16
$\begingroup$

I have a function that is a bit too slow for Manipulate[]. Right now I plan to cache outputs outside the manipulation and just have the manipulator select among cached outputs, but I am wondering if some better version of that trick exists.

Basically, I am creating a CDF presentation in which I intend to show the effect of different values for a correlation parameter $\rho$ in Monte Carlo simulations to the audience using Manipulate[] to show the resulting sample histograms. The simulation process is too slow to make for a good user experience as a live function, so one way or another I will have to cache some things.

It seems that if I am clever about writing a Module as an argument to Manipulate I should be able to make it cache, say, 199 different output sets corresponding to the various % correlations between -0.99 and +0.99.

$\endgroup$
4
  • 4
    $\begingroup$ How many parameters do you adjust with Manipulate? If it's only one, the minimal effort solution might be just precomputing a number of frames to show and using ListAnimate. $\endgroup$
    – Szabolcs
    Mar 12, 2012 at 18:35
  • $\begingroup$ Also, with Manipulate it's possible not to update the output before releasing the slider, or updating the output only with "low quality" (actually custom output can be used) while dragging the slider. This lets you give instant feedback when dragging the slider and a precise result will appear a second or two after you release the slider. If the simulation is even slower than 1-2 seconds then you really need to cache something. How the caching is best implemented depends on the details of the problem. The most general solution (e.g. ListAnimate) is not necessarily the best. $\endgroup$
    – Szabolcs
    Mar 12, 2012 at 18:39
  • 2
    $\begingroup$ Risking one more comment, one typical way of caching in Mathematica is memoization, in case you didn't know about it. There lots of variations on the technique. E.g. the number of values remembered can be limited. However, it seems to me that precomputing values is more appropriate for your case than caching them. $\endgroup$
    – Szabolcs
    Mar 12, 2012 at 18:48
  • $\begingroup$ I am planning on only one parameter. I did indeed use the ControlActive to get low-res behavior (as recommended in the "Advanced Tutorial") but as you anticipate it was too slow. ListAnimate is an interesting idea but I rather like having variable values on the scrubber. $\endgroup$
    – Brian B
    Mar 12, 2012 at 20:30

1 Answer 1

13
$\begingroup$

The following code demonstrates a bit of caching. The initialization code is run only once, because the variable cached which is saved in the Manipulate remembers the cached state. So when you copy the Manipulate into an empty notebook and open this in a fresh session, the cached plots stored in the saved variable plot (stored because of the SaveDefinitions option) won't be calculated again.

Remove the cached = True line and insert a Print["Init"] before the Plot command to see that plot is recalculated when the notebook containing the Manipulate is opened and viewed in a fresh session (without explicitly executing any code).

DynamicModule[{cached, plot},
 Manipulate[
  plot[[kx, ky]],
  {kx, 1, 10, 1},
  {ky, 1, 10, 1},
  Initialization :> {
    If[\[Not] TrueQ[cached],
     plot = 
      Table[Plot3D[
        Sin[kx x] Cos[ky y], {x, 0, \[Pi]}, {y, 0, \[Pi]}], {kx, 10}, {ky, 10}];
     cached = True
     ]},
  SaveDefinitions -> True,
  SynchronousInitialization -> False
  ]
 ]

Mathematica graphics

$\endgroup$
5
  • $\begingroup$ Exactly the sort of idea I was looking for, thank you. I'll be interested to see if the saving works in CDF, which I plan to test today. $\endgroup$
    – Brian B
    Mar 13, 2012 at 15:24
  • $\begingroup$ As an aside, this works in CDF player (after clicking past a warning) but not in embedded web pages. I presume this is due to the security restrictions on general functions like DynamicModule. $\endgroup$
    – Brian B
    Mar 14, 2012 at 13:37
  • 1
    $\begingroup$ @BrianB Good to hear that. Perhaps you could try to work without DynamicModule it isn't really essential here. I used it to restrict the effects of SaveDefinition to localized names, but if you are careful doing without shouldn't cause problems. $\endgroup$ Mar 14, 2012 at 14:39
  • $\begingroup$ Just wondering.. Whats done here is a kinda brute force (elegant) approach (which works). Is there an inbuilt feature to do this? (I am expecting that such "inbuilt" feature could be advantageous over this approach) $\endgroup$ Aug 12, 2013 at 14:11
  • $\begingroup$ @myaccount_ram If I had known of such a method I would have provided it, of course. $\endgroup$ Aug 12, 2013 at 15:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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