What's a good pattern to turn expression+replacement rules into a function which automatically applies these replacement rules?
IE, I'm finding a common pattern in my code, have some programmatically constructed formula with indexed symbols, and then evaluate it using replacement rules
n = 2;
amat = Array[a, {n, n}];
amat0 = RandomReal[{0, 1}, {n, n}];
expr = a[1, 1] + a[1, 2] + a[2, 1] + a[2, 2];
expr /. Flatten[Thread /@ Thread[amat -> amat0]]
It would be convenient to have a utility to turn expr into function, so instead of cumbersome replacement syntax I could do
func[amat0]
What's a good pattern to achieve this?
I've made an attempt below discovering following blockers:
- Function wants a flat list of parameters, I can't give it a matrix
- Function does not allow indexed symbols as parameters
A = {{1, 2}, {3, 4}, {5, 6}};
{m, n} = Dimensions@A;
wvec = Array[w, n];
norm2[vec_] := Total[vec*vec];
w0 = ConstantArray[0, n];
yhat = {1, 2, 3};
(turns w[1],w[2] into www1,www2)
removeIndices[
l_] := (MapIndexed[Symbol["www" <> ToString[First@#2]] &, l]);
(turns expression in terms of wvec into function)
functify[expr_] :=
With[{params = removeIndices[wvec]},
Function @@ {params, expr /. Thread[wvec -> params]}]
F = functify[1/m 1/2 norm2[A . wvec - yhat]^2]
F @@ w0
F @@ w0) the result you want, or is this illustrating the blockers? – lericr Feb 25 '23 at 18:50MapThread[Rule, {amat, amat0}, 2]. – lericr Feb 25 '23 at 18:53ClearAll[makeFunc]; makeFunc[expr_] := vals |-> ReplaceAll[Head[First@Variables[expr]] -> (vals[[##]] &)][expr]; makeFunc[expr]@amat0? – kglr Feb 25 '23 at 19:21