The issue is that by default, whenever a symbol in the Manipulate
change value, the Manipulate
expression is reevaluated. This means that when data
, dollarWon
etc. are changed in a given evaluation, their changes trigger another reevaluation and you get an infinite loop.
The way around this is to control the tracked symbols with the TrackedSymbols
option.
Manipulate[data = RandomWalk[nrTournaments, roi, bi, rake];
dollarWon = biWon bi; biWon = Last[data];
Dynamic@ListPlot[data, Joined -> True],
{{nrTournaments, 10000, "tournaments"}, 0, 100000, 100},
{{roi, 0.015, "ROI"}, 0, 20, 0.001},
{{bi, 60, "BI ($)"}, 0, 10000, 1},
{{rake, 1.26, "rake ($)"}, 0, 500, 0.01},
Panel[Grid[{{Dynamic[
Row[{"BI won: ", ToString[biWon], " (",
Style["$" <> ToString[dollarWon],
If[dollarWon >= 0, Darker[Green], Red]], ")"}]]}},
Alignment -> Left]],
SaveDefinitions -> True, TrackedSymbols :> True]
Setting the option to True
means only the control variables are tracked. It is equivalent in this case to the setting TrackedSymbols :> {nrTournaments, roi, bi, rake}
.
With only the TrackedSymbols
option, the Manipulate
is initially evaluated twice, and once there after for every change of inputs. To fix this, put the ListPlot
inside a Dynamic
.
To run more trials on the same input, one way is to track a dummy variable. (I haven't discovered a better way. Update
does not seem applicable. I can't figure out how to force updating without an actual change.)
trial = 0;
Manipulate[trial;
data = RandomWalk[nrTournaments, roi, bi, rake];
dollarWon = biWon bi; biWon = Last[data];
Dynamic@ListPlot[data, Joined -> True],
{{nrTournaments, 10000, "tournaments"}, 0, 100000, 100},
{{roi, 0.015, "ROI"}, 0, 20, 0.001},
{{bi, 60, "BI ($)"}, 0, 10000, 1},
{{rake, 1.26, "rake ($)"}, 0, 500, 0.01},
Panel[Grid[{{Dynamic[
Row[{"BI won: ", ToString[biWon], " (",
Style["$" <> ToString[dollarWon],
If[dollarWon >= 0, Darker[Green], Red]], ")"}]]}},
Alignment -> Left]],
Button["Run again", trial++],
SaveDefinitions -> True,
TrackedSymbols :> {nrTournaments, roi, bi, rake, trial}]
You can also make trial
a Manipulate
variable with a slider. Add the following to the variable declarations:
{trial, 1, 10^6, 1}
If trial
at the beginning of the Manipulate
expression is replaced by SeedRandom[trial]
. then trials with the same inputs will be reproducible.