# Re-using symbolic evaluation for numerical evaluation

I am creating a matrix of symbolic expressions "ResultSymbolic" , from a function which takes two symbolic Parameters: a scalar A, and an BxB Matrix M of symbolic expressions.

I have a second BxB Matrix of numerical values "Nums", which I am trying to plug into ResultSymbolic to get ResultNumerical:

 ResultNumerical = ResultSymbolic /. M -> Nums


If I do this, however, ResultNumerical looks exactly the same as ResultSymbolic.

ResultSymbolic takes a loooong time to compute, which is why I would love to be able to re-use it for ResultNumerical.

An example for "M" and "Nums" would be:

 M = {{M1,M2},{M3,M4}};
Nums = {{1,2},{3,4}};


I now want to replace every occurence of "Mi" in "ResultSymbolic" with the corresponding entry in "Nums", to get ResultNumeric.

• It's not clear from your question how the values in nums relate to the symbols in resultsymbolic. Is each entry in nums a value for a variable? Can you give a minimal example (ie, B == 2 or 3)? Also, I think you mean /., and not \.. – aardvark2012 Oct 27 '17 at 0:18
• I updated my post! – BigBadWolf Oct 27 '17 at 4:45

Assuming that the variables in M are the variables used in ResultSymbolic, this should work:

ResultNumerical = ResultSymbolic /. (Rule@@#&/@ Transpose[{Flatten[M],Flatten[Nums]}]);


Essentially, you just need to construct a list of rules where each symbol is substituted with the appropriate number. Flatten will preserve the order of each lists, assuming M and Nums will always have the same dimensions, and transposing brings each variable next to its numerical value. Then each pair has its head replaced with Rule to make it a list of rules.

This is really more of an addendum to @eyorble's perfectly good answer. I wanted to add a bit of an example to illustrate what's going on.

Suppose you have a matrix of variables and a corresponding matrix of values that they take:

vars = Partition[ToExpression[CharacterRange["α", "ι"]], 3]
nums = Partition[Range[9], 3]

(* {{α, β, γ},
{δ, ε, ζ},
{η, θ, ι}}

{{1, 2, 3},
{4, 5, 6},
{7, 8, 9}} *)


(OP called my vars matrix M in the question, but I've changed it to vars because single capital letters should be avoided in Mathematica, and it's nice to have meaningful variable names.)

Now suppose that your resultsymbolic is a matrix of some horrific functions of these variables:

resultssymbolic = Partition[f @@@ Table[RandomSample[Flatten[vars], 4], {4}], 2]

(* {{f[ι, ζ, ε, θ], f[ζ, γ, θ, α]},
{f[δ, θ, ζ, α], f[β, δ, η, α]}} *)


Then the numerical values can be substituted in with

resultssymbolic /. Flatten@MapThread[Rule, {vars, nums}, 2]

(* {{f[9, 6, 5, 8], f[6, 3, 8, 1]},
{f[4, 8, 6, 1], f[2, 4, 7, 1]}} *)


The key to making the substitution work is the list of replacement rules, which I constructed by MapThreading the Rule function over vars and nums (at level 2):

Flatten@MapThread[Rule, {vars, nums}, 2]

(* {α -> 1, β -> 2, γ -> 3, δ -> 4, ε -> 5, ζ -> 6, η -> 7, θ -> 8, ι -> 9} *)


Notice that without the Flatten we'd end up with a list of replacement lists:

(* {{α -> 1, β -> 2, γ -> 3},
{δ -> 4, ε -> 5, ζ -> 6},
{η -> 7, θ -> 8, ι -> 9}} *)


Trying to use this to replace the values will fail because ReplaceAll will interpret it as three separate replacement rules, and return three distinct matrices:

resultssymbolic /. MapThread[Rule, {vars, nums}, 2]

(* {{{f[ι, ζ, ε, θ], f[ζ, 3, θ, 1]},
{f[δ, θ, ζ, 1], f[2, δ, η, 1]}},

{{f[ι, 6, 5, θ], f[6, γ, θ, α]},
{f[4, θ, 6, α], f[β, 4, η, α]}},

{{f[9, ζ, ε, 8], f[ζ, γ, 8, α]},
{f[δ, 8, ζ, α], f[β, δ, 7, α]}}
} *)


which is clearly not what we're after.