The Math Forum



Search All of the Math Forum:

Views expressed in these public forums are not endorsed by NCTM or The Math Forum.


Math Forum » Discussions » Inactive » comp.soft-sys.math.mathematica

Topic: Fixed Typo in Code---> Re: updating a simulation within Manipulate.
Replies: 5   Last Post: Mar 9, 2013 5:25 AM

Advanced Search

Back to Topic List Back to Topic List Jump to Tree View Jump to Tree View   Messages: [ Previous | Next ]
Nasser Abbasi

Posts: 6,675
Registered: 2/7/05
Re: Fixed Typo in Code---> Re: updating a simulation within Manipulate.
Posted: Mar 9, 2013 5:25 AM
  Click to see the message monospaced in plain text Plain Text   Click to reply to this topic Reply

On 3/7/2013 9:47 PM, W Craig Carter wrote:
> On previous message, there is a typo in the example code, please use this instead:
>
> randomStep[bias_, stepList_] :=
> Module[{angle = RandomVariate[NormalDistribution[bias, 1]]},
> Join[stepList, {Last[stepList] + {Cos[angle], Sin[angle]}}]]
>
> walkerGraphic[stepList_, range_] :=
> Graphics[GraphicsComplex[stepList, Disk /@ Range[Length[stepList]]],
> PlotRange -> range {{-1, 1}, {-1, 1}}]
>
> DynamicModule[{walkerPath = {{0, 0}}},
> Manipulate[
> If[keepWalking,(*kludge warning---testing for If[ True...] seems inefficient*)
> walkerPath = randomStep[bias, walkerPath]];
> If[reset, reset = False; keepWalking = False;
> walkerPath = {{0, 0}}];
> walkerGraphic[walkerPath,
> range], {{keepWalking, False}, {True, False}}, {{reset,
> False}, {True, False}}, Delimiter, {{range, 20}, 0, 100},
> {{bias, 0}, -Pi, Pi,
> AngularGauge[##, ImageSize -> 160,
> ScaleOrigin -> {{-4 Pi, 4 Pi}, 1}] &}]]
>
>
>
> W Craig Carter
> Professor of Materials Science, MIT


The best way that I found after to do all these things
in Mathematica is to use a finite state machine type setup
to control the overall state of simulation. There will be a
"running" state, "pause" state, "reset" state and so on.

Then the whole simulation will be controlled by one ticklish
dynamic, called `tick` which acts like the heart beat of the
simulation.

Only one TrackedSymbol in the whole simulation.

Next, we will use the second argument of Dynamic to act as
the callback. Each time a control is changed, in the callback
we adjust the state of simulation as needed, then tickle the
heart beat so that the main display is refreshed.

When the main display does not need to refresh, then the heart beat
is not updated in the callback. Other house keeping logic can
be there if needed.

So, this is the whole idea. This works now as traditional simulation
loops work and as traditional GUI callbacks work, but with the
advntage of having Dynamics as well.

No need now to worry about where to do what, and have the logic spread
in many different locations in the code. The logic of the simulation
now is more organized and it is possible to make the simulation as
complex as needed without losing track of things.

In the callback (i.e. second argument of Dynamic), only work
relating to this control is done.

In the main display area, is where the main logic of the
state machine is, which updates the display, and if needed
tickle the heart beat again, so that the loop continue again
and again. No trigers are needed, no clocks, etc... Just one
tickle when needed, and the use of the second argument of
Dynamics and adding TrackedSymbols on the tick.

I wrote a note on this method sometime ago here

http://12000.org/my_notes/event_driven_GUI_with_Manipulate/event_driven_manipulate.htm

Using this method of doing simulation, here is your simulation now.
I put the notebook here also in case the paste does not work:

http://12000.org/tmp/030813/

----------------------------------------------
DynamicModule[{walkerPath = {{0, 0}}, state = "running", tick = 0,
result, del = $MachineEpsilon, range = 40, bias = 0, btnControls,
rangeControl, biasControl, stepSizeControl, stepSize = 0.21},

stepSizeControl =
Row[{Text@"step size", Spacer[5],
Manipulator[Dynamic[stepSize, {stepSize = #} &], {0.01, 1, 0.01},
ImageSize -> Tiny, ContinuousAction -> True], Spacer[5],
Dynamic[AccountingForm[stepSize, {3, 2}, NumberSigns -> {"", ""},
NumberPadding -> {"0", "0"}]]}];

btnControls = Grid[{{
Button[Text[Style["run", 12]],
If[state == "running", walkerPath = {{0, 0}}];
state = "running"; tick += del, ImageSize -> {50, 35}],
Button[Text[Style["pause", 12]], state = "paused"; tick += del,
ImageSize -> {50, 35}],
Button[Text[Style["step", 12]], state = "step"; tick += del,
ImageSize -> {50, 35}],
Button[Text[Style["reset", 12]], state = "reset";
walkerPath = {{0, 0}};
result = walkerGraphic[walkerPath, range]; tick = 0,
ImageSize -> {50, 35}]
}}, Spacings -> {0.2, .1}
];

rangeControl =
Row[{Text@"range", Spacer[5],
Manipulator[Dynamic[range, {range = #} &], {0, 100, 1},
ImageSize -> Tiny, ContinuousAction -> True], Spacer[5],
Dynamic[range]}];

biasControl =
AngularGauge[Dynamic[bias, {bias = #; tick += del} &], {-Pi, Pi},
ImageSize -> {260, 100}, ScaleOrigin -> {{-4 Pi, 4 Pi}, 1}];

Labeled[Grid[{

{Grid[{{btnControls},
{stepSizeControl},
{rangeControl},
{biasControl}
}],

Dynamic[
tick;
Which[state == "running" || state == "step",
walkerPath = randomStep[bias, walkerPath, stepSize];
result = walkerGraphic[walkerPath, range];
If[state == "running", tick += del]
];
result,
TrackedSymbols :> {tick}
]
}
}, Frame -> All]
, Text[Style["version 3/8/2013", 10]]]
,
Initialization :>
{
randomStep[bias_, stepList_, stepSize_] :=
Module[{angle = RandomVariate[NormalDistribution[bias, 1]]},
Join[stepList, {Last[stepList] +
stepSize {Cos[angle], Sin[angle]}}]
];

walkerGraphic[stepList_, range_] :=
Graphics[{Gray, PointSize[.04], Point@Most@stepList, Blue,
Point@Last@stepList}, PlotRange -> range {{-1, 1}, {-1, 1}},
ImageSize -> 200];
}
]
--------------------------------------------------

--Nasser









Point your RSS reader here for a feed of the latest messages in this topic.

[Privacy Policy] [Terms of Use]

© The Math Forum at NCTM 1994-2017. All Rights Reserved.