8
$\begingroup$

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?

$\endgroup$
4
  • 3
    $\begingroup$ Look at Symbol and Unique. Also consider indexed variables, e.g. x[1], x[2], etc. $\endgroup$
    – Mr.Wizard
    Commented Oct 16, 2012 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$ Commented Oct 16, 2012 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
    Commented Oct 16, 2012 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
    Commented Oct 17, 2012 at 12:28

2 Answers 2

12
$\begingroup$

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

ClearAll[x];
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

ClearAll[x];
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];
OwnValues[a]
(*
  {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}].

$\endgroup$
4
  • $\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
    Commented Oct 17, 2012 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
    Commented Oct 17, 2012 at 9:27
  • 1
    $\begingroup$ Mr.Wizard might prefer vars = Array[x, 10] :) $\endgroup$
    – sebhofer
    Commented Oct 17, 2012 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
    Commented Oct 17, 2012 at 13:12
2
$\begingroup$

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
$\endgroup$
2
  • $\begingroup$ Certainly not the best way to proceed most of the time, but a direct answer to the question. +1 $\endgroup$
    – Mr.Wizard
    Commented Oct 17, 2012 at 10:41
  • $\begingroup$ In place of SymbolName[Unevaluated[v]] I believe you can use MakeBoxes[v]. $\endgroup$
    – Mr.Wizard
    Commented Oct 17, 2012 at 10:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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