Re: Re: Dynamic changing of variables
- To: mathgroup at smc.vnet.net
- Subject: [mg96508] Re: [mg96365] Re: [mg96314] Dynamic changing of variables
- From: Patrick Scheibe <pscheibe at trm.uni-leipzig.de>
- Date: Sun, 15 Feb 2009 03:20:28 -0500 (EST)
- References: <200902121137.GAA08437@smc.vnet.net>
Hi, I just want to say thanks to all for the answers. As I said, I had already a way to do it, but I was trying to find out how Dynamic(Module) is intended to be used. Special thanks goes to John who took the time to write a very clear explanation which gave (hopefully not only for me) insights from another than the "how to fix it" viewpoint. Since John was asking, I'll attach my small sample where I was wondering how to do it the right way. Cheers Patrick DynamicModule[{lz, ly, beta = 0.5, z0 = 0.5, y0 = 0.5, sol, doCalc}, sol[beta_, z0_, y0_] := Block[{parms = {v0 -> 1, k -> 10, kf -> 1, v1 -> 7.3, VM2 -> 65, VM3 -> 500, K2 -> 1, KR -> 2, KA -> 0.9, m -> 2, n -> 2, p -> 4, \[Beta] -> beta}, v2, v3, pde}, v2 = VM2*(Z[t]^n/(K2^n + Z[t]^n)); v3 = VM3*(Y[t]^m/(KR^m + Y[t]^m))*(Z[t]^p/(KA^p + Z[t]^p)); pde = {Derivative[1][Z][t] == v0 + v1*\[Beta] - v2 + v3 + kf*Y[t] - k*Z[t], Derivative[1][Y][t] == v2 - v3 - kf*Y[t], Z[0] == z0, Y[0] == y0}; {Z, Y} /. Flatten[NDSolve[pde /. parms, {Z, Y}, {t, 0, 3}]]]; doCalc[] := {lz, ly} = sol[beta, z0, y0]; Column[{Dynamic[ Plot[{lz[t], ly[t]}, {t, 0, 3}, PlotRange -> {{0, 3}, {0, 2}}, ImageSize -> 400]], Dynamic[ ParametricPlot[{lz[t], ly[t]}, {t, 0, 3}, PlotRange -> {{0, 2}, {0, 2}}, ImageSize -> {300, 300}]], Row[{"\[Beta]", Slider[Dynamic[beta, (beta = #1; doCalc[]) & ], {0, 1}], Dynamic[beta]}], Row[{"\!\(\*SubscriptBox[\(Z\), \(0\)]\)", Slider[Dynamic[z0, (z0 = #1; doCalc[]) & ], {0, 1}], Dynamic[z0]}], Row[{"\!\(\*SubscriptBox[\(Y\), \(0\)]\)", Slider[Dynamic[y0, (y0 = #1; doCalc[]) & ], {0, 1}], Dynamic[y0]}]}]] On Thu, 2009-02-12 at 06:37 -0500, John Fultz wrote: > A note to anybody who makes non-trivial Dynamic interfaces. Read the question and my response and understand it thoroughly. This is a really important > question and understanding the answer will help you to create very sophisticated and powerful Dynamic interfaces with no need for guesses or trial and error. > > The error here is in the statement... > > > In order to update "a" with the actual value of Sin[b] I need > > Dynamic around it. Unfortunately, now the variable "a" is invisibly > > or, more specifically, what the definition of "it" is (take the oblique > reference to a U.S. presidential quote as you will). Yes, you do need to > introduce a Dynamic to get a=Sin[b] to evaluate, but putting it on the > right-hand side of the assignment is wrong in this context. The key is to > remember that Dynamic does not control anything about evaluation directly. What it does is to create a spot on the screen which has evaluation properties. > > If, for example, you were to evaluate the following in a fresh Mathematica > session... > > b=5; > Dynamic[a=b]; > b=6; > Print[a]; > > ...then what will be printed? Instead of evaluating it immediately, think about > it before you try it. Hint...it's a trick question, but understanding the trick > will open your mind to exactly what Dynamic is doing. > > The answer, which I will not reveal here (because you should really try it for > yourself!) can be explained by the fact that the Dynamic never did anything > because it never showed up onscreen. The semicolon inhibited the onscreen > appearance of Dynamic, and without appearing onscreen, the evaluation of Dynamic > accomplishes nothing. > > More subtly, if you remove all of the semicolons, the Print[] statement (at > least on my machine) *still* remains unchanged, but now for a completely > different reason. That's because the onscreen placement of a Dynamic guarantees > that its contents will be evaluated, but not *when* they'll be evaluated. My > example sets up a race condition which, at least on my machine in v7, the > Shift+Enter evaluation wins. > > > If I understand the intent of your example correctly, the place to begin is > here... > > DynamicModule[{a, b = 0}, Dynamic[a = Sin[b]; > Column[{Dynamic[a], Slider[Dynamic[b], {0, 2*Pi}]}]]] > > I.e., wrap the Dynamic around the entire CompoundExpression including the > assignment and the Column. > > You say this is a toy example that represents a real-world one. I believe > that...I've written things that look like your toy example many times. It's a > shame I'm not seeing your real example, though, because there are some further > simplifications and improved efficiencies which I might be able to comment on. > For example, in this case it's a bit wasteful that the Column[] is inside of a > Dynamic[]. It could be a static element which contains individual Dynamic > elements. Something like... > > DynamicModule[{a, b = 0}, > Column[{Dynamic[a = Sin[b]; a], Slider[Dynamic[b], {0, 2*Pi}]}]] > > which is obviously silly in this example, but may point to something interesting > in your real-world code. Perhaps a generalization I could remark on is the > notion of an onscreen Dynamic which has no visual appearance. Something like > this... > > DynamicModule[{a, b = 0}, Row[{Dynamic[a = Sin[b]; Spacer[0]], > Column[{Dynamic[a], Slider[Dynamic[b], {0, 2*Pi}]}]}]] > > This is a more sophisticated technique in which Row[] is used to show a Dynamic > which takes essentially no onscreen space, and yet has an onscreen presence. In > this version, the Row[] and Column[] are static elements which are never > regenerated by Dynamic. And we can now more tightly confine the evaluation > behaviors of the elements of the Column so that they are regenerated on an > as-needed basis, rather than every time any variable in the whole interface > changes. > > I recommend re-reading the Advanced Dynamic Functionality tutorial (or reading > it if you haven't already) in light of some of the things I've said here. > Especially the subsections "Automatic Updates of Dynamic Objects" and "Nesting > Dynamic". You can find it by typing tutorial/AdvancedDynamicFunctionality in > your help window. > > Sincerely, > > John Fultz > jfultz at wolfram.com > User Interface Group > Wolfram Research, Inc. > > > > > On Wed, 11 Feb 2009 05:22:24 -0500 (EST), Patrick Scheibe wrote: > > Hi, > > > > assume the following code lines: > > > > DynamicModule[{a, b 0}, > > a = Dynamic[Sin[b]]; > > Column[{ > > Dynamic[a], > > Slider[Dynamic[b], {0, 2*Pi}] > > }] > > ] > > > > In order to update "a" with the actual value of Sin[b] I need > > Dynamic around it. Unfortunately, now the variable "a" is invisibly > > wrapped and completely useless for further calculations. I'm not able to > > calculate even a+1 inside the DynamicModule. > > > > DynamicModule[{a, b = 0}, > > a = Dynamic[Sin[b]]; > > Column[{ > > Dynamic[a+1], > > Slider[Dynamic[b], {0, 2*Pi}] > > }] > > ] > > > > If I'm not just too stupid and this behaviour is intended, then I'm > > wondering whether this doesn't lead to problems when you have more > > complex constructs with several dynamic variables. > > > > Cheers > > Patrick > > > > PS: I was just pointed by another person on this and I found a way > > around it. So cannot provide a real problem I'm having. Nevertheless, I > > would be glad to know what you think since I couldn't really find the > > point in the documentation where this is explained. > > > >
- References:
- Re: Dynamic changing of variables
- From: John Fultz <jfultz@wolfram.com>
- Re: Dynamic changing of variables