0
$\begingroup$

My main question is how to assign values to symbolic arrays, in an efficient way. The code below is a simplified version of what I am trying to do and the output I get. Note that because I am using subscripts to generate my symbolic entries the output below is hard to follow, but in Mathematica it looks ok (so I also copy the output in LaTex for convenience)

I first generate a vector with generic symbolic entries:

ClearAll["Global`*"]
fMat = Array[Subscript[f, ##] &, {1, 2}]

{{Subscript[f, 1, 1], Subscript[f, 1, 2]}}

which actually looks like $\{\{f_{1,1}, f_{1,2}\}\}$

using LaTex. In my actual code I have a big matrix and that's why I am using subscripts. With this I can get symbolic results, like for instance

YMat = fMat.Transpose[fMat]

{{!(*SubsuperscriptBox[(f), (1, 1), (2)] + *SubsuperscriptBox[(f), (1, 2), (2)])}}

which looks like $\{\{f_{1,1}^2+f_{1,2}^2 \}\}$

All good so far. Now say I want to evaluate this for some specific values of my symbolic entries. So I try to assign values

Array[Subscript[f, ##] &, {1, 2}] = {2, 4}

will not work, giving a

`"Tag Array in Array[Subscript[f, ##1]&,{1,2}] is Protected."

message, while

{Subscript[f, 1, 1], Subscript[f, 1, 2]} = {2, 4}

works, in the sense that if I then type

YMat

{{20}}

However, I do not want to assign the values this way, because with a big matrix is a lot of code. I would like to do it in a compact way but I don't know how to do it. Also, as an aside, when I assign the values Mathematica will remember them the next time I evaluate the notebook, even with

ClearAll["Global`*"]

which is annoying because everything is numeric rather than symbolic. Any suggestion would be great!

$\endgroup$
2
$\begingroup$
ClearAll["Global`*"]

Generally, it is best to use indexed variables and avoid Subscript (or similar) except for display. Format handles this.

Format[f[m_, n_]] := Subscript[f, m, n]

fMat = Array[f, {1, 2}]

enter image description here

YMat = fMat.Transpose[fMat]

enter image description here

Attributes[Set]

{HoldFirst, Protected, SequenceHold}

Note that the Attributes for Set include the attribute HoldFirst, i.e., the LHS is not evaluated. To do what you want, you need to have the LHS evaluated.

Evaluate@fMat = {{2, 4}}

(*  {{2, 4}}  *)

fMat

(*  {{2, 4}}  *)

Or

{{f[1, 1], f[1, 2]}}

(*  {{2, 4}}  *)

YMat

(*  {{20}}  *)
$\endgroup$
  • $\begingroup$ Thanks! This works beautifully! $\endgroup$ – mariodrumblue Sep 7 '17 at 3:37
2
$\begingroup$

There are many ways you could do this. One way is to use replacement rules to substitute the values.

E.g.

YMat /. {Subscript[f, 1, 1]->2, Subscript[f, 1, 2]->4}

Would allow you to do the substitutions in your example.

Economical ways of doing this for larger arrays depend on how the values are available to you.

Suppose that the values that you want are all ready in some array fvalues. The following simple replacement rule using patterns could then be used to substitute the values in an expression.

YMat /. {Subscript[f,i_, j_] :> fvalues[[i,j]]}
$\endgroup$
  • $\begingroup$ Thanks! although I prefer the solution by Bob. This solution did not work well for me and also Mathematica was still remembering the values when I re-compiled the notebook. $\endgroup$ – mariodrumblue Sep 7 '17 at 3:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.