I have a complex algorithm that depends on:
- A wavelet basis
- A number of sampling points out of a distribution
- A thresholding value
I want to be able to play with different scenarios using Manipulate, but I am hitting a wall trying to ensure that when one updates the threshold, it does not resample the data. I have noticed that Manipulate is kind of smart enough to pick up dependencies and recalculate only what's needed, but still puzzles me quite a bit.
So, I have prepared a simple example that illustrates my ignorance...
The following code generates only one sample, but it triggers the call to take an snapshot of the sample every time one changes the threshold (th
in code) although the threshold is not involved in the computation of data
.
Module[{dist, dataAll},
dist = MixtureDistribution[{8, 2},
{NormalDistribution[0.5, 0.05], NormalDistribution[0.7, 0.01]}];
dataAll = (Print["New data"]; RandomVariate[dist, 2000]);
Manipulate[
Module[{data},
data = (Print["New sample"]; Take[dataAll, nn]);
ColumnForm[{
{{Min[dataAll], Max[dataAll]}, {Min[data], Max[data]}} //
MatrixForm,
th}]
]
],
{wave, {HaarWavelet[], DaubechiesWavelet[2], DaubechiesWavelet[3],
DaubechiesWavelet[4], SymletWavelet[4]}},
{nn, {80, 100, 200, 300, 500, 800, 1300, 2000}},
{th, 0., 1., 0.05}
]
]
Changing the wave
variable does not trigger any calculation; apparently because it is not being used at all.
If I change the expression inside Manipulate to something without th
, then it does not print the message, i.e. it does not trigger... but this is not useful.
My algorithm is more complex than above. I need guidance on how to setup a Manipulate where certain steps of the process depend on certain manipulate parameters, but I don't want the whole expression (whole algorithm) to be calculated from top to bottom. I started trying also Manipulate
inside Manipulate
, but it gets very ugly.
So, in abstract, if one has an algorithm like
- step 1
- step 2, depends on param A
- step 3
- step 4, depends on param B
- step 5
- step 6, depends on param C
- step 7 -> final expression/plot/etc
where one wants to manipulate params A, B and C. How does one replay the algorithm from the steps that are actually required? For example, if one changes B then only steps from 4 to 7 (final expression) need to be calculated. The issue being that those steps setup a number of auxiliary variables, etc, so splitting that into functions will get messy fairly quickly, I believe. And still I am unsure that doing that will solve the problem. I'd prefer an approach whereby those things are packed in modules inside modules, but would that help?
As a concrete question: how would you change the code above so the resulting expression ColumnForm[...]
still refers to th
, but the data
is not recalculated when changing th
?
Any pointers would be appreciated.
TrackedSymbols
option? $\endgroup${u, f}
where thef
function that creates the UI element has that callback in the generatedDynamic
? $\endgroup$