MathGroup Archive 2009

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Compute once question

  • To: mathgroup at smc.vnet.net
  • Subject: [mg105706] Re: Compute once question
  • From: David Bailey <dave at removedbailey.co.uk>
  • Date: Wed, 16 Dec 2009 06:17:51 -0500 (EST)
  • References: <hg00d9$j98$1@smc.vnet.net> <200912131038.FAA21060@smc.vnet.net> <hg7v80$en5$1@smc.vnet.net>

Michael Greene wrote:
> Thanks David. I think I'm 'zeroing' all the variables before I use them. Got
> some nasty displays early on that I've cleaned out so I think I know what
> you're referring to.
> 
> Here's the code- I've tried to clean it up somewhat so it's clearer what's
> going on.
> 
> I expect the transition from step 8 to step 9 to be immediate as I've
> already computed what I need to display. Yet the delay for the 9th step
> message to appear is as long as the delay for the 8th step graphic. It's as
> if Mathematica isn't evaluating the code in the If statement as much as it's
> treating the code as a function definition that will be evaluated when it's
> referred to in the Graphic[] call.
> 
> Manipulate[
>  (*Do some initial work *)
>  msg = {{"A circle has a circumference of 2\[Pi]r..."}, {"...so \
> halfway around a circle is \[Pi]r"}, {"We can re-arrange the slices \
> without changing the area..."}, {"...or the distance halfway around \
> the circle."}, {"Slice the circle into more pieces & the right shape \
> morphs..."}, {"...into a rectangle"}, {"The rectangle is r units high \
> and 2\[Pi]r units wide..."}};
>  Slices = {4, 8, 16, 100};
> 
>  (* Figure out which message and what pieces we're going to show next based
> on which step \
> we're on*)
>  If[Step == 1, {n = 1; ms = 1; showSlice = 0; showSlice2 = 0;
>    showPerim = 0;
>    showPerim2 = 0;}, If[Step == 2, showPerim = 1; ms = 2;];
>   If[Step == 3, showSlice = 1; showSlice2 = 1; ms = 3;];
>   If[Step == 4, showPerim2 = 1; ms = 4; showSlice = .5];
>   If[Step == 5, ms = 5; n = 2;];
>   If[Step > 5 && Step < 9, n = Part[Slices, Step - 4];];
>   If[n == 100, ms = 6];];
>  If[Step == 9, ms = 7];
>  nm = Text[Style[Take[msg, {ms, ms}], Bold, 24], {3.25, 2.7}];
> 
>  (*Computation begins here. Slice a circle, rotate the slices and \
> translate them
>   Only do this up through step 8, reuse results after step 8*)
>  If[Step <= 8, \[Theta] = Pi/(n + 1); bottom = Red; top = Gray;
>    ef = If[n < 15, White, If[n < 30, LightBlue, None]];
>    cn = Table[
>      Circle[{1, 1}, 1, {s \[Theta], s \[Theta] + \[Theta]}], {s, 0,
>       n}];
>    ct = Table[
>      Rotate[Take[cn, {s1}],
>       Pi/2 - (s1 - 1) \[Theta] - \[Theta]/2, {1, 1}], {s1, 1,
>       n + 1}];
>    ctt = Table[
>      Translate[
>       Take[ct, {s2}], {2 (s2 - 1) Sin[\[Theta]/2] +
>         2, -Cos[\[Theta]/2]/2}], {s2, 1, n + 1}];
>    p = {3, 1 - Cos[\[Theta]/2]/2};
>    p2 = p + {Cos[Pi/2 + \[Theta]/2], Sin[Pi/2 + \[Theta]/2]};
>    ra = Line[{{1, 1}, {0, 1}}];
>    ra2 = Line[{p, p2}];
>    ral = Text[Style["r", Bold, 36], {.5, 1.1}];
>    ral2 = Translate[ral, {1.3 + Cos[\[Theta]/2], -.10}];
>    cir = Text[Style["\[Pi]r", Bold, 36], {1, 2.2}];
>    cir2 = Translate[cir, {2 + Cos[\[Theta]/2], -.5}];
>    dn = Table[
>      Disk[{1, 1}, 1, {s \[Theta], s \[Theta] + \[Theta]}], {s, 0,
>       n}];
>    dt = Table[
>      Rotate[Take[dn, {s1}],
>       Pi/2 - (s1 - 1) \[Theta] - \[Theta]/2, {1, 1}], {s1, 1,
>       n + 1}];
>    dtt = Table[
>      Translate[
>       Take[dt, {s2}], {2 (s2 - 1) Sin[\[Theta]/2] +
>         2, -Cos[\[Theta]/2]/2}], {s2, 1, n + 1}];
>    dnn = Table[
>      Disk[{1, 1},
>       1, {s \[Theta] + Pi, Pi + s \[Theta] + \[Theta]}], {s, 0, n}];
>    dtn = Table[
>      Rotate[Take[dnn, {s1}],
>       3 Pi/2 - (s1 - 1) \[Theta] - \[Theta]/2 + Pi, {1, 1}], {s1, 1,
>       n + 1}];
>    dttn =
>     Table[Translate[
>       Take[dtn, {s2}], {2 (s2 - 1) Sin[\[Theta]/2] +
>         2*Sin[\[Theta]/2]/2 + 2, Cos[\[Theta]/2]/2}], {s2, 1,
>       n + 1}];
>    ](* Computation should end here and not repeat at step 9 *)
> 
>   (* Display computation results *)
>   Graphics[{EdgeForm[ef],
>     nm, {FaceForm[top], dn}, {FaceForm[bottom], dnn}, {FaceForm[top],
>      Opacity[showSlice], dtt}, {FaceForm[bottom], Opacity[showSlice2],
>       dttn, {Thick,
>       Blue, {{Opacity[showPerim], cn, ra, cir,
>         ral}, {Opacity[showPerim2], ctt, cir2, ra2, ral2}}}}},
>    PlotRange -> {{-.50, 6.5}, {0, 3}}, Axes -> True,
>    ImageSize -> {800, 470}],
>  {Step, Table[ii, {ii, 9}], ControlType -> SetterBar}]
> 
> 
> Thanks again,
> Michael
> 
> 
> On Sun, Dec 13, 2009 at 2:38 AM, David Bailey <dave at removedbailey.co.uk>wrote:
> 
>> Michael Greene wrote:
>>> I'm having trouble getting Mathematica not to repeatedly compute values
>> in a
>>> Manipulate Window. I'm not sure if it's a bug in my code or if it's a
>>> fundamental disconnect between what I think is going on and what
>> Mathematica
>>> is actually doing.
>>>
>>> What my code is doing is slicing a circle into segments, rotating the
>> slices
>>> and then translating them. When  the process first starts out, I'm
>> dealing
>>> with a small number of slices so the response is immediate. The process
>>> eventually works up to around 20 slices and the user begins to see a
>> slight
>>> delay between manipulating the controller and seeing the result. At 100
>>> slices, we're talking about a 3 or 4 second lag which isn't OK.
>>>
>>> When I first started the process, I was allowing the user to directly
>>> manipulate the slice count. When I saw the lags starting to kick in, I
>>> thought I'd just let the user control a step counter instead and based on
>>> which step the user was on, compute the graphic, store the graphic and
>> reuse
>>> the stored graphic as we moved further into the process. That is:
>>>
>>> If[Step<=8, <do intensive computation and store graphic in G>];
>>> Graphics[G];
>>>
>>> So when Step gets to 9, I expect G to pop up on the screen right away but
>> it
>>> doesn't. The program still takes several seconds as if it's recomputing
>> G.
>>> Am I wrong to expect Mathematica to only compute G when Step is less than
>> 9?
>>> I'd post the actual code but it's rather hoary. Hopefully my question
>> still
>>> makes sense sans code.
>>>
>>>  What I'd really like to be able to do is timeslice G's computation in
>> the
>>> earlier steps when the user is spending time assimilating the earlier
>>> information so by the time he/she gets to the computationally expensive
>>> step, the work is done and G just pops onto the screen as if it's no big
>>> deal. But first things first...
>>>
>>> Thanks,
>>> Michael
>>>
>>>
>> It is awfully hard to comment in detail without some actual code, but it
>> may be worth adding counters to your code, such as
>>
>> Global`couter1++;
>>
>> If you zeroise all the counters before use (otherwise you will get nasty
>> recursion errors) and move the Manipulate controls, you will be able to
>> inspect the counters to determine how many times things got executed. I
>> specified the Global` context just in case your code was nested in
>> another context for one reason or another.
>>
>> David Bailey
>> http://www.dbaileyconsultancy.co.uk
>>
>>
> 
> 
One problem with your code is that the If that starts If[Step <= 8 
.......... has a missing semicolon at its end, which means it is 
'multiplied' by the subsequent graphics!

I extracted the graphics that had been created, by inserting Global`ggg= 
before the actual Graphics construction. This meant that I could display 
the graphics object outside Manipulate. As you will see if you try this, 
it is quite slow to render. Furthermore, by printing in InputForm

ggg//InputForm

you can see that all the Rotate and Translate operations are being 
performed in the FE. It might be worth trying to perform these 
operations explicitly in the kernel.

Finally, I don't really like your approach of not recalculating if 
step>8, because you get the wrong answer if you jump from step 3 to step 
8 (say). You really need to test if the previous step was 8 and the 
current step exceeds 8 - but hopefully if you simplify the graphic in 
the kernel, that will not be necessary. More generally, you might want 
to store all 9 graphics constructions in an array and only compute them 
once - but of course that will not speed up the actual rendering process.

I hope this helps,

David Bailey
http://www.dbaileyconsultancy.co.uk


  • Prev by Date: Re: ParallelTable slows down computation
  • Next by Date: Re: Compute once question
  • Previous by thread: Re: Re: Compute once question
  • Next by thread: Re: Compute once question