Re: Using a variable set elsewhere within a function that has attribute
- To: mathgroup at smc.vnet.net
- Subject: [mg98074] Re: [mg98019] Using a variable set elsewhere within a function that has attribute
- From: "David Park" <djmpark at comcast.net>
- Date: Sun, 29 Mar 2009 02:47:16 -0500 (EST)
- References: <5226838.1238240354262.JavaMail.root@m02>
Daan, I usually don't use Manipulate because I find it easier to write up custom dynamic displays. At first is might seem like more work, but I think it's easier because I can calculate any kind of dependent dynamic variables that depend on the primary variables, and I can format the display in any manner I want. In the following: 1) calcAll is a routine that calculates dependent dynamic variables (diffeqn, odesol, plotfunc) from the primary dynamic variable r. 2) In the input controls use the second argument of Dynamic. Essentially we set r to the current setting of the Slider (or whatever control is being used) and then call calcAll to refresh all the dependent variables. One can even reset r within calcAll! This might be used to constrain r to a certain range of values or constrain a locator to a curve. 3) Format the dynamic display any way you wish using Rows, Columns or Grids. In this case I included a column of intermediate results just to aid in development of the routine. One might actually remove this and move some of the intermediate results to the calcAll Module. 4) You could also use a DynamicModule instead of Module. ode[r_] := x'[t] == r x[t] - x[t]^2 Module[ {r = 0.1, diffeqn, odesol, plotfunc, calcAll}, (* Routine to calculate solution from r *) calcAll[s_] := Module[{}, diffeqn = ode[s]; odesol = Part[NDSolve[{diffeqn, x[0] == 0.1}, x, {t, 0, 10}], 1, 1]; plotfunc = x[t] /. odesol]; (* Initialize *) calcAll[r]; (* Dynamic display *) Panel[ Column[ {Row[{"r: ", Slider[Dynamic[r, (r = #; calcAll[r]) &], {0, 1}, Appearance -> "Labeled"]}] (* Slider Row *), Dynamic@ Column[ {Column[{"Intermediate debugging results", diffeqn, odesol, plotfunc}](* Intermediate results *), Plot[Evaluate@plotfunc, {t, 0, 10}, PlotRange -> {0, 1}, ImageSize -> 400]}] }](* Display Column *), Style["Dynamic Solving of a Differential Equation", 16]](* Panel *) ] David Park djmpark at comcast.net http://home.comcast.net/~djmpark/ From: Daan Gerla [mailto:daan at gerla.nl] Hello Mathematica users, I am trying to use a variable defined elsewhere within Manipulate. I have assigned an expression to the variable that involves another variable. That second variable should not be assigned to anything outside of manipulate, however, within Manipulate, I want that second variable to change as I drag a slider and anything that uses the first variable to change accordingly. I am not quite sure I am saying this right, but this example should make clear what I mean: ode = x'[t] == r x[t] - x[t]^2; Manipulate[ ode, {r, 0.1, 1} ] I do not get any warnings or errors, but the result is not as you might expect: in the output the equation is displayed without a value for r and the slider does nothing. Manipulate[ Evaluate[ode], {r, 0.1, 1} ] does what you expect. The output contains a value for r which changes as the slider is dragged. Now I want to use ode for something else. Manipulate[ Plot[x[t] /. NDSolve[{Evaluate[ode], x[0] == 0.1}, x, {t, 0, 10}], {t, 0, 10}], {r, 0, 1} ] Here I get errors: NDSolve::dsvar: 0.0002042857142857143` cannot be used as a variable. >> ReplaceAll::reps: {NDSolve[{(x^\[Prime])[0.000204286]==r x[0.000204286]-x[<<1>>]^2,x[0]==0.1},x,<<1>>]} is neither a list of replacement rules nor a valid dispatch table, and so cannot be used for replacing. >> [...] It looks like it takes a number for t when it should not, and not a number for r when it should. What I want is of course a plot of x vs. t that changes as I change r by dragging the slider. I've tried many things, including changing the attributes of Manipulate, but no good results. I am not even sure what the problem exactly is... How do I solve this problem? What is the best way to do what I want to do? Regards, Daan