Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

In working on a simple simulation I came across the following Manipulate quirk (bug?) and I want to know how to get around it. Here is the first pass code, which acts as expected (but is incorrect):

simpleBrownianSimulation[] := Module[{vels, nPts},
    Manipulate[
        vels = Table[RandomReal[{-1, 1}, 2], {Length[pts]}];
        nPts = Table[pts[[i]] + t*vels[[i]], {i, Length[pts]}];
        Graphics[{Blue, PointSize[0.02], Point[nPts]}, 
        PlotRange -> {{-5, 5}, {-5, 5}}],
        {{pts, {{0, 0}}}, Locator, LocatorAutoCreate -> True, Appearance -> None},
        {t, 0, 10, 0.05}
]];
simpleBrownianSimulation[]

The idea is to use the slider to trigger updates to the particles (stored in pts) position. This code correctly updates only if the slider is moved, but contains an error, since the position is computed always from the initial position of the particle, and the current time value. So to fix this, I changed it to:

simpleBrownianSimulation[] := Module[{vels, nPts, isSet = False},
    Manipulate[
    If[!isSet, nPts = pts; isSet = True];
    vels = Table[RandomReal[{-1, 1}, 2], {Length[pts]}];
    nPts = Table[nPts[[i]] + vels[[i]], {i, Length[pts]}];
    Graphics[{Blue, PointSize[0.02], Point[nPts]}, PlotRange -> {{-5, 5}, {-5, 5}}],
    {{pts, {{0, 0}}}, Locator, LocatorAutoCreate -> True, Appearance -> None},
    {t, 0, 10, 0.05}
]];
simpleBrownianSimulation[]

This code is correct, but it ANIMATES! It updates on its own regardless of whether the slider is being moved or not. I know that here the value of the slider is not used, that is fine. I just want to use it as an update trigger, and NOT have maniuplate update otherwise. Why is manipulate doing this and how can I fix it? Note that this is Mathematica 9, but this occurs both on the Windows and Mac versions.

share|improve this question
1  
Do not have to look at this now, but an advice: do not put Manipulate inside a Module. Put Module inside Manipulate. –  Nasser Feb 25 at 23:21
add comment

1 Answer 1

up vote 2 down vote accepted

Your code constantly updates because nPts is local to a module enclosing the Manipulate. If the Manipulate enclosed the module, your code wouldn't work as you would like, but it wouldn't be constantly updating.

Here is a much simpler example showing the same behavior.

Module[{n = 1}, Manipulate[Row[{"n = ", n++}], {t, 0, 5}]]

constantly updates, but

Manipulate[Module[{n = 1}, Row[{"n = ", n++}]], {t, 0, 5}]

doesn't.

I would take a different approach. I wouldn't use locators to add more particles to the simulation; rather I would use a ClickPane. Nor would I use a slider to generate update events; rather I would use a Button

Manipulate[
  If[update, 
     update = False; pts = Plus @@@ Transpose[{pts, RandomReal[{-1, 1}, {Length@pts, 2}]}]];
  ClickPane[
    Framed@Graphics[{Blue, PointSize[0.02], Point[pts]}, PlotRange -> {{-5, 5}, {-5, 5}}], 
    AppendTo[pts, #] &],
  {{update, False}, ControlType -> None},
  {{pts, {{0, 0}}}, ControlType -> None},
  Button["Update", update = True]]

manipulate

This is much simpler than your code, but still performs the simulation you are trying to implement. Give it a try and see if it satisfies your needs.

share|improve this answer
    
Cool, thanks. I guess the problem here is that for someone who normally programs Objective-C and Java/Swing, it seems like what manipulate does is update only if a control fires an event. However, for some reason, if inside the manipulate the value of a variable is changed which is not local to the manipulate, this somehow (magically?) triggers an update of the manipulates code. I see no reason why this is good, and this seems to be really non-obvious behavior. I do agree about button vs. slider. Goal was just to give a quick&dirty way to trigger updates. –  jcb Feb 28 at 4:14
    
By non-obvious I mean that the event handling which must be in the background firing an update off to the manipulate shouldn't know anything about variable assignments, and manipulate shouldn't be updating without some sort of event, otherwise it is doing lots of unnecessary processing. –  jcb Feb 28 at 4:15
    
@jcb. There is quite a bit of magic in Manipulate. It is designed to let people implement some fairly fancy GUIs without getting down and dirty with Mathematica's GUI primitives. If you want to work at a level closer to what you are used to, the lower level GUI elements are available. You might find DynamicModule more to your liking than Manipulate. Personally, I like Manipulate a lot. Compare my implementation of your simulation to what it would take in Java/Swing. I did it with less than 10 line of code. In Java it would take many, many more lines. –  m_goldberg Feb 28 at 4:38
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.