Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mathematica: Asynchronous incremental generation of dynamical graphics

What is the simplest way to asynchronously apply consecutive improvements to a Graphics object in a dynamic setting (and abort the evaluation of the unneeded results if input changes while they are being computed)?

As a simple example, consider this:

speed[r_] := Graphics@{Red, Circle[{0, 0}, r]}
qualityA[r_] := (Pause[1]; Graphics@{Red, Disk[{0, 0}, r]})
qualityB[r_] := (Pause[1]; Graphics@{Black, Circle[{0, 0}, r]})
Manipulate[Show[
  ControlActive[speed[r], {qualityA[r], qualityB[r]}],
  PlotRange -> {{-1, 1}, {-1, 1}}
  ], {{r, .5}, 0, 1}] 

Mathematica graphics

How can I evaluate qualityA and qualityB consecutively, and append their output to the display when it is ready?

Bonus points for Abort'ing the evaluation of unneeded results, and for allowing a part of the result to be calculated multiple times, so that after releasing the control I would see e.g. {qualityA[r]} then {qualityA[r],qualityB[r]}, and finally {qualityA2[r],qualityB[r]}.

like image 686
Janus Avatar asked Feb 23 '11 05:02

Janus


1 Answers

Really good question.

I may be overlooking a simpler way. There often is one when it comes to Dynamic... But here is my suggestion:

DynamicModule[{quality = 0, exprs = {}},
 Manipulate[
  Show[
   ControlActive[
    exprs = {}; quality = 0; Graphics@{Red, Circle[{0, 0}, r]},
    Switch[quality,
     0, Pause[1]; quality = 1; 
     AppendTo[exprs, Graphics@{Red, Disk[{0, 0}, r]}],
     1, Pause[1]; quality = 2; 
     AppendTo[exprs, Graphics@{Black, Circle[{0, 0}, r]}],
     _, r];
    exprs
    ],
   PlotRange -> {{-1, 1}, {-1, 1}}],
  {{r, .5}, 0, 1}
  ]
 ]

First we define some variables controlling increasingly high quality graphics: quality (ranging to 0 to the maximum quality, 2 in this case), and exprs (a list of expressions to Show, just as in your example).

Now note what happens in the two cases of ControlActive:

When ControlActive, the result is the same as yours, except we take the opportunity to reset quality and exprs relating to the "high quality" graphics.

When not ControlActive, the Dynamic expression evaluates to

code; exprs

This expression has the following key properties.

  1. It returns the list exprs every time.
  2. Each time code is evaluated, it improves the graphics by appending something to exprs.
  3. Each time code is evaluated, at least one of the variables lexically contained in code; exprs (such as quality) is changed. This means Dynamic will go ahead and evaluate our dynamic expression again, and again, and again, until ...
  4. Eventually code evaluates without any of the variables lexically contained in code; exprs changing. This means Dynamic will stop re-evaluating.
  5. The final evaluation lexically contains r. (Via the otherwise useless default case in the Switch, _, r.) This is important to make the slider still trigger updates.

Give it a try and let me know if that works for you.

Edit: What $Version of Mathematica are you using? I see some version dependence in the behavior of my code above.

Edit 2: I asked an expert on Dynamic and he found a better way, which I will describe in a separate answer.

like image 70
Andrew Moylan Avatar answered Nov 02 '22 07:11

Andrew Moylan