Generating a vector of dummy variables

8

4

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?

voxelite

Posted 2012-10-16T15:32:30.643

Reputation: 83

3Look at Symbol and Unique. Also consider indexed variables, e.g. x[1], x[2], etc. – Mr.Wizard – 2012-10-16T15:41:41.730

1Consider also the use of the built-in C and K if you're going the "indexed variables" route. – J. M.'s ennui – 2012-10-16T16:31:29.000

@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? – sebhofer – 2012-10-16T22:20:11.140

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 – Rojo – 2012-10-17T12:28:25.400

Answers

11

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}].

halirutan

Posted 2012-10-16T15:32:30.643

Reputation: 109 574

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. – m_goldberg – 2012-10-17T06:45:16.237

1@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. – halirutan – 2012-10-17T09:27:38.920

1Mr.Wizard might prefer vars = Array[x, 10] :) – sebhofer – 2012-10-17T11:22:44.100

@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. – m_goldberg – 2012-10-17T13:12:54.247

2

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

m_goldberg

Posted 2012-10-16T15:32:30.643

Reputation: 104 223

Certainly not the best way to proceed most of the time, but a direct answer to the question. +1 – Mr.Wizard – 2012-10-17T10:41:33.447

In place of SymbolName[Unevaluated[v]] I believe you can use MakeBoxes[v]. – Mr.Wizard – 2012-10-17T10:43:12.400