0
$\begingroup$

I have variables in my code following the following notation :

theta12, theta13, theta14 etc..

I would check the values of all this variable so I could write an if condition for each theta but I wondered if it is possible to name the variables "dynamically", like if it was an array.

For example is it possible to write "thetakj" where k and j are integers on which I am looping on and mathematica understand this notation.

Am I forced to use an array to do it ?

$\endgroup$
7
  • $\begingroup$ Have a look at Map $\endgroup$
    – Sascha
    May 27, 2017 at 11:51
  • 2
    $\begingroup$ ToExpression["theta" <> ToString[k] <> ToString[j]]? $\endgroup$
    – Michael E2
    May 27, 2017 at 11:53
  • $\begingroup$ Or consider using SubValues, e.g. define theta[1,3], theta[1,4], ... $\endgroup$ May 27, 2017 at 11:53
  • 2
    $\begingroup$ @AlexeyBobrick These are still DownValues :) $\endgroup$
    – halirutan
    May 27, 2017 at 12:07
  • $\begingroup$ Thank you for all your answers, I will look at your functions ! $\endgroup$
    – StarBucK
    May 27, 2017 at 13:23

1 Answer 1

2
$\begingroup$

Here's something similar to what you need I suppose?

Clear@theta;

$PreRead = ReplaceAll[#, RowBox[{"theta", seq_}] :>
     Block[{},
      Module[{myHold}, SetAttributes[myHold, HoldAllComplete]; 
        With[{preproc = myHold[theta] @@ (ToExpression[#, TraditionalForm, myHold] & /@ Characters@seq)},
         With[{inject = Hold[preproc] //. myHold[cont_] :> cont}, 
          ToBoxes[inject][[1, 3]]]]] /; True]] &;

$PrePrint = 
 ReplaceAll[#, 
   theta[seq__] :> 
    With[{expr = MakeExpression[ RowBox[{"theta", StringJoin[ToString /@ {seq}]}], TraditionalForm]},
     ReleaseHold@Defer@expr]] &;

Usage

slightly different from what you wanted, but still very similar: just need a space between theta and those parameters:

e.g.

theta 12 = 3

theta 14 = 2;

theta 12 + theta 13

theta 12 + theta 14

(theta 12)*8

Table[theta ij,{i,4},{j,4}]

theta 12=.

Table[theta ij,{i,4},{j,4}]

Notes

(and basic idea as well)

Do not assign values to theta as what's doing in dark is replacing all theta ij expressions to theta[i,j] and turn it back when showing to you!

Use (theta ij) when you cannot deternmine whether theta ij along can create correct answer.

Acknoledge that theta 14 means theta[1,4], not theta[14]! thus theta (2*3+2) would return theta 14 which means theta[14] while evaluate it again will result in theta[1,4]!


Improvements

Clear@theta;

$PrePrint = 
  ReplaceAll[#, 
    theta[seq__] :> 
     With[{expr = 
        MakeExpression[
         RowBox[{"theta", Sequence @@ (ToString /@ {seq})}], 
         TraditionalForm]}, ReleaseHold@Defer@expr]] &;

$PreRead = ReplaceAll[#, RowBox[{"theta", seq__}] :>
     Block[{},
      Module[{myHold}, SetAttributes[myHold, HoldAllComplete]; 
        With[{preproc = 
           myHold[theta] @@ 
            ToExpression[{seq}, TraditionalForm, myHold]},
         With[{inject = Hold[preproc] //. myHold[cont_] :> cont}, 
          ToBoxes[inject][[1, 3]]]]] /; True]] &;

in this case, write theta i j k instead of theta ijk would be okay. It would cause less confusion with stuffs like theta 14.

A small note: in the output form, theta 1 2 1 or so will be displayed as theta 2 while the fullform keep honest. so just pay more attention to 1s, and everything would be okay.

$\endgroup$

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