3

I have an estimation routine I have coded up, I want now to do some tests on it where I pick a particular parameter and run the estimation for differing values of that parameter. What I want is to be able to specify the parameter name I am interested in changing at the top of the file and from then on just run a loop substituting different values into the chosen parameter.

So for example I want something to the effect of

paramToVary = a;
paramValues = Range[0, 1, 1/20];

Do[MyEstimation[a, b], {paramToVary, paramValues}]

except this wont work as written, paramToVary takes the values of paramValues whereas I want these to be going into a instead. Any ideas on how to do this or alternative solutions?

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
Matthew
  • 33
  • 2

3 Answers3

5

Since Do (and Table) has attribute HoldAll, paramToVary won't be evaluated at the right time. Use Evaluate on the iterator specification to force the replacement of paramToVary -> a.

ClearAll[a];
paramToVary = a;
paramValues = Range[0, 1, .2];

Table[a, Evaluate@{paramToVary, paramValues}]
{0., 0.2, 0.4, 0.6, 0.8, 1.}
István Zachar
  • 47,032
  • 20
  • 143
  • 291
4

Using With might do the trick too:

ClearAll[a];
With[{paramToVary = a, paramValues = Range[0, 1, .2]},
 Table[a, {paramToVary, paramValues}]
]
{0., 0.2, 0.4, 0.6, 0.8, 1.}
FJRA
  • 3,972
  • 22
  • 31
0

As described by István this is an issue of evaluation order. There are several methods, Evaluate and With already illustrated. I often use a Function for this purpose as it is concise:

paramToVary = a;
paramValues = Range[0, 1, 1/5];

Table[{a, b}, {#, paramValues}] & @ paramToVary
{{0, b}, {1/5, b}, {2/5, b}, {3/5, b}, {4/5, b}, {1, b}}

There are potential complications with your approach that I wish to caution you about. If the Symbol a has an assigned value this operation will fail because paramToVary will evaluate to that value rather than the Symbol a:

a = 999;
Table[{a, b}, {#, paramValues}] & @ paramToVary

During evaluation of In[42]:= Table::itraw: Raw object 999 cannot be used as an iterator. >>

You can guard against this by keeping the Symbol in a Hold expression, and by using some method to insert the unevaluated Symbol into the Table (or Do) expression. My favorite method for the latter is what I have come to call the "injector pattern". Please also see How to set Block local variables by code? for a related question.

a = 999;

paramToVary = Hold[a]

paramToVary /. _[x_] :> Table[{a, b}, {x, paramValues}]
{{0, b}, {1/5, b}, {2/5, b}, {3/5, b}, {4/5, b}, {1, b}}

Note that a had a value before paramToVary was defined without breaking the code.

Alternatively you can use my step function which simplifies definition retrieval, and use SetDelayed rather than Hold:

a = 999;

paramToVary := a;

step[paramToVary] /. _[x_] :> Table[{a, b}, {x, paramValues}]
{{0, b}, {1/5, b}, {2/5, b}, {3/5, b}, {4/5, b}, {1, b}}
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371