# Scoping inside of Module and Manipulate

This is driving me nuts: I'm trying to control the parameters for a relatively large system of ODEs using Manipulate.

With[{todo =
Module[
{sol, ode, timedur = 40},
ode = Evaluate[odes /. removeboundaries /. moieties];
sol = NDSolve[Join[ode, init], vars, {t, 0, timedur}];
Plot[Evaluate[c[1][t] /. parms] /. sol, {t, 0, timedur}]
],
controls =
Sequence @@
Table[{{parms[[i]][[1]], parms[[i]][[2]]},
0, (3*parms[[i]][[2]])}, {i, 1, Length[parms]}]},
Manipulate[todo, controls, ContinuousAction -> False,
ControlPlacement -> Bottom]]


The solve step, in which sol is created, performs successfully. When trying to make a Plot from this however, I get all kinds of errors like

NDSolve::ndnum: Encountered non-numerical value for a derivative at t == 0.


Although NDSolve runs fine when Plot is commented out! Note that this code relies on global variables defined elsewhere in the script. I should also add that the code inside the Module[] works when copied to a fresh cell.

Could someone help me out?

Thanks!!

-
it seems to be fairly common sense, but it happens to be not so common ... Could you please post a self contained and running (or minimal not-running) example? –  belisarius May 16 '12 at 2:39

Even without a minimual example, it is clear that you have a problem related to your use of With as the outer scoping construct. Please see the answers to this question, particularly mine.

• Use With for local constants that you don't have to change subsequently.
• Use Module for local variables that are local to that piece of code.
• Use Block for local variables that are local to that sequence of evaluation.

You are defining todo to be a constant, and then trying to Manipulate it.

In addition, the Module outputs the graphic from the Plot as its output. It will be a Graphics[] object, which is not amenable to the kinds of parameter adjustment you seem to want.

My suggestion would be something along the lines of:

Module[{sol, ode, timedur = 40, controls},
ode = Evaluate[odes /. removeboundaries /. moieties];
sol = NDSolve[Join[ode, init], vars, {t, 0, timedur}];
controls =  Sequence @@
Table[{{parms[[i]][[1]], parms[[i]][[2]]},
0, (3*parms[[i]][[2]])}, {i, 1, Length[parms], 1}];
Manipulate[Plot[Evaluate[c[1][t] /. parms] /. sol, {t, 0, timedur}] ,
controls, ContinuousAction -> False,  ControlPlacement -> Bottom]]

-
The "use With for local constants" is a recommendation, but not a description of how With works. For example, the following code works just fine, setting b to 10: With[{a=b},a=10]. And so does With[{a=b^2},Manipulate[a,{b,0,1}]]. What With does is to replace the symbol with the expression before evaluating that, with some fine points for nested scoping constructs. Note that due to how With works, the Manipulate does not try to manipulate todo in @Maarten's code (or a in my example above), but whatever todo is replaced with. And that seems indeed to be intended. –  celtschk May 16 '12 at 12:51
Thanks! My plan was to write a generic ODE solver with sliders for the parameters. I still haven't succeeded so I might be posting more questions on this. –  Maarten May 19 '12 at 8:33

Your problem probably is that the right hand side of the {todo = ...} is evaluated before inserting into the Manipulate. Use {todo := ...} instead to disable premature evaluation. However if calculation of ode and sol does not involve params in any way (as your code suggests), you probably want to pre-evaluate that part, and only put the actual Plot command inside the Manipulate.

-
Thanks a lot! I now understand that With[] defines constants, not variables. To compute sol`, the parms have to be inserted into the odes by the Manipulate wrapper. I defined the odes as a constant - erroneously - and so couldn't manipulate them. I will try the := operator! –  Maarten May 19 '12 at 8:39