3
$\begingroup$

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?

$\endgroup$
1

3 Answers 3

5
$\begingroup$

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.}
$\endgroup$
4
$\begingroup$

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.}
$\endgroup$
0
$\begingroup$

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}}
$\endgroup$
2
  • $\begingroup$ Thanks for this extra detail, very helpful as I do have values stored in the parameters $\endgroup$
    – Matthew
    Commented Dec 12, 2013 at 12:18
  • $\begingroup$ @Matthew You're welcome. Consider possibly Accepting this answer instead, if it is the solution you will use? $\endgroup$
    – Mr.Wizard
    Commented Dec 12, 2013 at 20:41

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.