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 several variables in my DynamicModule and some parts of my computation depend only on subset of them. I am trying to use Refresh to "cache" values but can't make it work.

Example of the problem:

verySlowFunction[x_] := Module[{}, Print["SLOW"]; x * x];

DynamicModule[
 {a = 1, b = 1},
 Dynamic[
  Module[
   { x = Refresh[verySlowFunction[a], TrackedSymbols :> {a}] },
   Column[{
     Slider[Dynamic[a]],
     Slider[Dynamic[b]],
     {a, b , x + x + b} 
     }]]]]

I expect "SLOW" to be printed only when I drag "a" slider, but it is printed when I'm dragging "b" slider as well.

I know that Dynamic clones whole expression tree on its evaluation, that's why x is always different, but this one doesn't work as well:

Module[
 {x},
 DynamicModule[
  {a = 1, b = 1},
  Dynamic[
    x = Refresh[verySlowFunction[a], TrackedSymbols :> {a}] ;
   Column[{
     Slider[Dynamic[a]],
     Slider[Dynamic[b]],
     {a, b , x + x + b} 
     }]]]]
share|improve this question
1  
This is so useful: 12000.org/my_notes/event_driven_GUI_with_Manipulate/… –  Gustavo Delfino Sep 14 '13 at 0:10
    
Do you know if this approach is actually used by anybody? I imagine there could be a library of helper functions to make it look simpler. –  mikea Sep 14 '13 at 0:39
    
Besides the author, I am using it. I don't know who else, but it works beautifully. –  Gustavo Delfino Sep 14 '13 at 13:58
add comment

2 Answers 2

up vote 2 down vote accepted

Try this one

DynamicModule[{a = 1, b = 1, x = 1}, 
 Column@{Slider@Dynamic[a, (a = #; x = verySlowFunction[a]) &], 
   Slider@Dynamic[b], Dynamic@{a, b, x + x + b}}]

The second argument in Dynamic is evaluated when the corresponding variable changes.

Or this one

DynamicModule[{a = 1, b = 1}, 
 Column@{Slider@Dynamic[a], Slider@Dynamic[b], Dynamic@{a, b}, 
   Dynamic[x = verySlowFunction[a]]}]

You can manually insert Refresh with TrackedSymbols in the last Dynamic.

share|improve this answer
1  
Thanks, this will work. However in my actual case verySlowFunction depends on more than one argument, and there are several temporary calculations to perform. This would require me to duplicate re-evaluation into lots of controls, right? –  mikea Sep 14 '13 at 0:43
    
@mikea There are more elegant approach if you have several arguments. See update. –  ybeltukov Sep 14 '13 at 0:53
    
The second version has some serious omission: it does not include calculations based on x. That's what causes me troubles. –  mikea Sep 14 '13 at 5:50
add comment

That's tricky question, I have to admit I do not have general solution but I usually do what is good for particular case. Here I'd use DynamicWrapper:

verySlowFunction[x_] := Module[{}, Print["SLOW"]; x*x];

DynamicModule[{a = 1, b = 1},
              DynamicWrapper[
                     Column@{
                             Slider@Dynamic[a],
                             Slider@Dynamic[b],
                             Dynamic@{a, b, x + x + b}},
                     x = verySlowFunction[a];]]

This is not the answer to the question how to use Refresh for your purposes but I think it is not bad approach :). I'm looking forward for more answers how one can deal with this.

About link provided by @Gustavo, imo there is to much acrobatics in there which is not necessary in case of DynamicModule. DynamicModule != Manipulate because the body of DM is not automatically updated when variables are.

I appreciate any comments if I'm mistaken somewhere.

share|improve this answer
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.