So I'm the situation of needing analytical solutions to a family of equations of the form Ax=b, where A is an nxn matrix. I've written a function that does what I want, but I'm currently using a bit of a hack to generate arbitrary (dummy) variable names for the n-vector 'x' :

Map[Clear, Table["x" <> ToString[j], {j, n}]];
x = ToExpression[Table["x" <> ToString[j], {j, n}]];

Can anyone suggest a more elegant way of accomplishing this task?

  • 3
    $\begingroup$ Look at Symbol and Unique. Also consider indexed variables, e.g. x[1], x[2], etc. $\endgroup$ – Mr.Wizard Oct 16 '12 at 15:41
  • 1
    $\begingroup$ Consider also the use of the built-in C and K if you're going the "indexed variables" route. $\endgroup$ – J. M.'s ennui Oct 16 '12 at 16:31
  • $\begingroup$ @J.M. That was a very useful comment! I've never heard of NHoldAll before. Using K doesn't seem to have any advantages though, right? $\endgroup$ – sebhofer Oct 16 '12 at 22:20
  • $\begingroup$ Definately Array with some formal symbol or not formal if you are sure there's nothing defined on it. m~Array~{5, 5} . a~Array~5 // MatrixForm $\endgroup$ – Rojo Oct 17 '12 at 12:28

You have several possibilities for this. The probably two easiest methods are first to use Unique

x = Table[Unique["x"], {10}]
(* {x7, x8, x9, x10, x11, x12, x13, x14, x15, x16} *)

The good thing is, that when some of your variables xn are already defined, Unique will not return them. It always gives you fresh, unused symbols.

The other thing you should consider is, that x[1] can be used like a symbol too, although it isn't one. Therefore

vars = Table[x[i], {i, 10}]
(* Out[15]= {x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10]} *)

Can be used as valid variables too. In any case you should watch out that your variables are not assigned to values accidently. This is a common source of errors if you use them in combination with Solve or its friends.

Why did I use x= in the first example and vars= in the second one?

Let's take a very simple example

a = b[1];
  {HoldPattern[a] :> b[1]}

and now we assume that the b would be an a, than we would get an OwnValue-rule like

HoldPattern[a] :> a[1]

Therefore, the moment you use a an substitution process starts which is only stopped by the $RecursionLimit, because a is evaluated into a[1] which again contains an a in the front. This is repeatedly replaced.

Therefore, if you want to use the second approach, don't call it like x = Table[x[i], {i, 10}].

  • $\begingroup$ Evaluate x={x[1], x[2], x[3], x[4], x[5]}. In MMA 8.0.4 it exceeds the recursion limit. A bug? Whatever, it makes indexed variables a problem if used in the way the OP wants to use them. $\endgroup$ – m_goldberg Oct 17 '12 at 6:45
  • 1
    $\begingroup$ @m_goldberg No, no bug, it is the expected behavior. I added an explanation and made clear how to use it. Thank you for pointing it out. $\endgroup$ – halirutan Oct 17 '12 at 9:27
  • 1
    $\begingroup$ Mr.Wizard might prefer vars = Array[x, 10] :) $\endgroup$ – sebhofer Oct 17 '12 at 11:22
  • $\begingroup$ @halirutan. Thanks for the explanation. I understand what's going on with expressions like x = x[1] now. Another case of: don't think procedural; think rewrite. $\endgroup$ – m_goldberg Oct 17 '12 at 13:12

Here is a function that will do what you asked when it is passed a symbol and the length of the vector. The function returns the list of symbols it constructs; it assures that all the symbols in the list are clear of values.

SetAttributes[varVect, HoldFirst]

varVect[v_Symbol, n_Integer /; n > 0] := 
  Module[{vs = SymbolName[Unevaluated[v]], vars},
    vars = (vs <> ToString[#1]) & /@ Range[n];
    Clear @@ vars;
    Symbol /@ vars]

x = x2 = 1; x = varVect[x, 5]; x // FullForm => List[x1, x2, x3, x4, x5]
x[[2]] // FullForm => x2
  • $\begingroup$ Certainly not the best way to proceed most of the time, but a direct answer to the question. +1 $\endgroup$ – Mr.Wizard Oct 17 '12 at 10:41
  • $\begingroup$ In place of SymbolName[Unevaluated[v]] I believe you can use MakeBoxes[v]. $\endgroup$ – Mr.Wizard Oct 17 '12 at 10:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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