Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Dynamic changing of variables

4 views
Skip to first unread message

Patrick Scheibe

unread,
Feb 11, 2009, 5:21:41 AM2/11/09
to
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.


Albert Retey

unread,
Feb 12, 2009, 6:34:00 AM2/12/09
to
Hi,

> 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.

You need to understand that Dynamic is something that only starts its
magic when it is shown within the FrontEnd. So this:

a = Dynamic[Sin[b]];

is assigning the Dynamic (actually a DynamicBox) to a, something that
only makes sense for the FrontEnd, not the Kernel. What you really want
is not to assign a to Dynamic[Sin[b]] but you want to assign Sin[b] to a
dynamically, which could be done with:

Dynamic[a=Sin[b]]

but again, this would only work if it appears visible within the
FronEnd, if you put a ; after it, it will not appear in the output, so
it will not do anything. I think this is more close to what you want:

DynamicModule[{a,b = 0},
Column[{
Dynamic[a = Sin[b]],
Dynamic[a + 1],


Slider[Dynamic[b], {0, 2*Pi}]
}]
]

If you don't want the 'intermediate' result to be shown in the FrontEnd,
you can wrap everything and suppress output:

DynamicModule[{a,b = 0},
Column[{
Dynamic[
a = Sin[b];
a + 1


],
Slider[Dynamic[b], {0, 2*Pi}]
}]
]

Another very useful mechanism to assign a value to a whenever b changes
is to use the second argument in Dynamic, like this:

DynamicModule[{a,b = 0},
Column[{
Dynamic[a + 1],
Slider[Dynamic[b, (b = #; a = Sin[b]; #) &], {0, 2*Pi}]
}]
]

hth,

albert

David Park

unread,
Feb 12, 2009, 6:37:14 AM2/12/09
to
A dynamic display will have primary dynamic variables that are set by
controls (Sliders, InputFields, etc.) and dependent variables that are
calculated from the primary dynamic variables.

The trick to handling this is to use the second argument of Dynamic. This
allows us to call a calculation routine that will calculate all of the
dependent variables. The calculation can even do more; it can apply a
constraint to the primary dynamic variable.

Here is a modification of your example that illustrates these things.

DynamicModule[
{(* Primary dynamic variables *)
b = 3,
(* Dependent dynamic variables *)
a, c,
(* Routine to calculate dependent variables *)
calcAll},

calcAll[bvar_] :=
((* Constrain the b variable to 1 <= b <= 5 *)
b = Max[1, Min[5, bvar]];
(* Calcuate the dependent dynamic variables *)
a = Sin[b];
c = a + 1);

(* Initialze *)
calcAll[b];

Column[
{Dynamic@{b, a, c},
Slider[Dynamic[b, (b = #; calcAll[b]) &], {0, 2*Pi}]}]
]

This simple form is easily generalize to create very complex custom
displays. You have complete control of how you place controls and how you
display information and you can dynamically calculate very complicated
objects from the primary dynamic variables.

Throw Manipulate into the ashcan. You will never need it again.

David Park
djm...@comcast.net
http://home.comcast.net/~djmpark/

From: Patrick Scheibe [mailto:psch...@trm.uni-leipzig.de]


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

John Fultz

unread,
Feb 12, 2009, 6:37:46 AM2/12/09
to
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
jfu...@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},

Sjoerd C. de Vries

unread,
Feb 12, 2009, 6:38:40 AM2/12/09
to
The problem of updating a lies with its invisible dependence on b. If
you make it explicitely dependent on b you can drop the first dynamic
and a is not wrapped and can be used for calculations.

DynamicModule[{a, b = 0},

a[b_] = Sin[b];
Column[{Dynamic[a[b]], Slider[Dynamic[b], {0, 2*Pi}]}]]

Alternatively, you could have wrapped the whole assignment with
Dynamic:

DynamicModule[{a, b = 0},

Column[{Dynamic[a = Sin[b]], Dynamic[a + 1],


Slider[Dynamic[b], {0, 2*Pi}]}]]

Cheers -- Sjoerd

On Feb 11, 12:21 pm, Patrick Scheibe <psche...@trm.uni-leipzig.de>
wrote:

Jens-Peer Kuska

unread,
Feb 12, 2009, 6:32:23 AM2/12/09
to
Hi,

DynamicModule[{a = 0, b = 0},
Column[{Dynamic[a + 1],
Slider[Dynamic[b, (a = Sin[#]; b = #) &], {0, 2*Pi}]}]]

??

Regards
Jens

Patrick Scheibe

unread,
Feb 15, 2009, 3:20:23 AM2/15/09
to
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
>

> 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
> jfu...@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},

0 new messages