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.

I have a Manipulate that uses RandomVariate and Random that I would like to have redraw and recompute random values selectively, depending on what Manipulate parameters have been changed.

For example, I would like to be able to control redraws and recomputations so that

  • new data and honestMeans are only computed if n has changed;
  • new punishMeans are computed only when n or punish have changed;
  • a redraw is triggered when zoom changes, but without triggering an update to data, honestMeans or punishMeans;
  • a redraw triggered when any of data, honestMeans or punishMeans or zoom changes (without triggering a recomputation of data, honestMeans or punishMeans);
  • everything updates if an explicit update is requested (somehow)

as indicated in the comments below:

scale = 5;
dist = HypergeometricDistribution[scale, Round[0.7*2*scale], 2*scale];
genVotes[punish_, n_] := Module[{},
   votes = {data[[1]]};
   For[i = 2, i <= n, i++,
    If[Random[] < punish,
     If[votes[[i - 1]] > data[[i]], vote = 0, vote = scale],
     vote = data[[i]]
     ];
    AppendTo[votes, Mean[Append[data[[1 ;; i - 1]], vote]]];
    AppendTo[votes, Mean[Append[data[[1 ;; i - 1]], data[[i]]]]];
    ]; Return[votes];
   ];

Manipulate[
  data = RandomVariate[dist, n];(* Should only change when n changes *)
  punishMeans = genVotes[punish, n]; (* Should change when punish or n change *)
  honestMeans = genVotes[0, n]; (* Should only change when n changes *)
  GraphicsColumn[{ (* Should redraw when any of the above change, or if zoom changes, without triggering recompilation of data, punishMeans or honestMeans *)
   Show[
    ListPlot[punishMeans,
     Joined -> False, PlotStyle -> Gray, PlotMarkers -> Automatic, 
     PlotRange -> {{0, n}, {(1 - zoom)*#, (1 + zoom)*#} &[Mean[data]]},
     Frame -> True, Axes -> None,
     Epilog -> {Blue, Line[{{0, Mean[data]}, {n, Mean[data]}}]}],
    ListPlot[honestMeans,
     Joined -> True, PlotStyle -> Black, PlotMarkers -> None]
    ],
   Show[
    Histogram[data, scale, PlotRange -> {{0, scale + 1}, All}, 
     Frame -> True,
     FrameTicks -> {{Automatic, 
        Automatic}, {{# + .5, #, 0} & /@ Range[0, scale], None}}, 
     Axes -> None],
    DiscretePlot[n*PDF[dist, x], {x, 0, scale + 1}, Joined -> True, 
     PlotMarkers -> None, Filling -> None]
    ]
   }],
 {{n, 100}, 10, 5000},
 {{punish, 0.5}, 0, 1},
 Delimiter,
 {{zoom, 0.2}, .1, .5},
 TrackedSymbols :> {n, punish, zoom}]

Is there a way to do this kind of selective update of elements of a Manipulate?

share|improve this question
2  
Please don't post your full-blown code/problem here but just a minimal example for other users to work with. –  belisarius Feb 23 at 21:45
    
@belisarius: That's my MWE. (All interdependencies matter, as near as I can tell.) Don't hesitate to simplify the example if you spot an opportunity to do so. –  raxacoricofallapatorius Feb 23 at 21:48
    
fyi, your code above does not run, it has errors in it, on V 9.01 , here is screen shot !Mathematica graphics may be if you fix these first it will help. –  Nasser Feb 23 at 23:14
    
@Nasser: Thanks. Fixed (I think). –  raxacoricofallapatorius Feb 23 at 23:29

1 Answer 1

up vote 2 down vote accepted

This uses the second argument of dynamics, which acts like an event call back. In there, you do the specific action needed when that dynamic changes. This localizes the logic with its own control variable. Makes it easier to manage. If you like more information about this method, see this question

But you really need to fix/improve the way the function genVotes works. It is very inefficient and slow (that is why I made ContinuousAction -> False below for now), and it also uses global data which is not a good way to implement it. I'll leave this for you to fix.

scale = 5;
dist = HypergeometricDistribution[scale, Round[0.7*2*scale], 2*scale];

genVotes[punish_, n_] := Module[{},
   votes = {data[[1]]};
   For[i = 2, i <= n, i++,
    If[Random[] < punish,
     If[votes[[i - 1]] > data[[i]],
      vote = 0,
      vote = scale
      ],
     vote = data[[i]]
     ];
    AppendTo[votes, Mean[Append[data[[1 ;; i - 1]], vote]]];
    AppendTo[votes, Mean[Append[data[[1 ;; i - 1]], data[[i]]]]]
    ];
   votes
   ];

Manipulate[tick;

 GraphicsColumn[{

   Show[ListPlot[punishMeans, Joined -> False, 
     PlotStyle -> Gray, PlotMarkers -> Automatic, 
     PlotRange -> {{0, n}, {(1 - zoom)*#, (1 + zoom)*#} &[Mean[data]]}, 
     Frame -> True, Axes -> None, 
     Epilog -> {Blue, Line[{{0, Mean[data]}, {n, Mean[data]}}]}], 
    ListPlot[honestMeans, Joined -> True, PlotStyle -> Black, PlotMarkers -> None]
    ],

   Histogram[data, scale, PlotRange -> {{0, scale + 1}, All}, Frame -> True, 
    FrameTicks -> {{Automatic, Automatic}, 
      {{# + .5, #, 0} & /@ Range[0, scale], None}}, Axes -> None], 
   DiscretePlot[n*PDF[dist, x], {x, 0, scale + 1}, Joined -> True, 
      PlotMarkers -> None, Filling -> None]
   }],

 Grid[{
   {"n",
    Manipulator[Dynamic[
      n, {n = #; data = RandomVariate[dist, n]; punishMeans = genVotes[punish, n]; 
        honestMeans = genVotes[0, n]; 
        tick = Not[tick]} &], {10, 200, 1}, ImageSize -> Tiny], Dynamic[n]
    },
   {"punish",
    Manipulator[Dynamic[punish, {punish = #; punishMeans = genVotes[punish, n]; 
     tick = Not[tick]} &], {0, 1, 0.1}, ImageSize -> Tiny], Dynamic[punish]
    },
   {"zoom",
    Manipulator[Dynamic[zoom, {zoom = #; tick = Not[tick]} &], {.1, .5, 0.1}, 
      ImageSize -> Tiny, ContinuousAction -> True], Dynamic[zoom]
    }
   }
  ],

 {{zoom, .2}, None},
 {{n, 100}, None},
 {{punish, .5}, None},
 {{tick, False}, None},
 SynchronousUpdating -> False,
 SynchronousInitialization -> False,
 ContinuousAction -> False,
 TrackedSymbols :> {tick}
 ]

enter image description here

share|improve this answer
    
Yeah, sorry: genVotes and the use of data are pretty terrible. I'll fix that. –  raxacoricofallapatorius Feb 24 at 1:05

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.