RE: RE: plot several functions
- To: mathgroup at smc.vnet.net
- Subject: [mg35950] RE: [mg35900] RE: plot several functions
- From: "DrBob" <majort at cox-internet.com>
- Date: Fri, 9 Aug 2002 05:17:58 -0400 (EDT)
- Reply-to: <drbob at bigfoot.com>
- Sender: owner-wri-mathgroup at wolfram.com
I really like the Interpolation idea in Mihajlo's problem, because the expression his large block evaluates to is very long and involved. not just the preliminaries leading up to it. Whether all this maneuvering is worthwhile depends on how often he'll use these functions together, though. If he's just plotting it once in a while, he can wait six seconds while it works. Bobby -----Original Message----- From: Wolf, Hartmut [mailto:Hartmut.Wolf at t-systems.com] To: mathgroup at smc.vnet.net Subject: [mg35950] RE: [mg35900] RE: plot several functions >-----Original Message----- >From: DrBob [mailto:majort at cox-internet.com] To: mathgroup at smc.vnet.net >Sent: Wednesday, August 07, 2002 11:59 AM >Subject: [mg35950] [mg35900] RE: plot several functions > > >You can redefine the functions to take advantage of their commonality, >something like this: > >(I'm using Sin[x] as the LARGE BLOCK) > >helper[x_] := Sin[x] >fun1[large_, x_] := Cos[x]large >fun2[large_, x_] := Exp[x]large >fun3[large_, x_] := x large > >Plot[Evaluate@{h = helper[t]; fun1[h, t], fun2[h, t], fun3[h, t]}, {t, >0, Pi}] > >or > >helper[x_] := Sin[x] >fun1[large_, x_] := Cos[x]large >fun2[large_, x_] := Exp[x]large >fun3[large_, x_] := x large >vector[x_] := (h = helper[t]; {fun1[h, t], fun2[h, t], fun3[h, t]}) > >Plot[Evaluate@vector@t, {t, 0, Pi}] > >For other purposes, you can still define > >fun1[arg_]:=fun1[helper@arg,arg] > >et cetera. > >In case you haven't seen this before, f@x is the same as f[x]. > >Bobby > >-----Original Message----- >From: Mihajlo Vanevic [mailto:mvane at eunet.yu] To: mathgroup at smc.vnet.net >Subject: [mg35950] [mg35900] plot several functions > >I have the following problem: > >I have to plot several functions at once, like > >Plot[{fun1[t], fun2[t], fun3[t]},{t,0,1}] > > >where fun1,2,3 consists of the same (large!!) block, >something like: > >fun1[arg_]:=Module[... LARGE BLOCK; result1]; >fun2[arg_]:=Module[... LARGE BLOCK(same as above); result2]; >fun3[arg_]:=Module[... LARGE BLOCK(same as above); result3]; > >When I do the plot, this block is evaluated three times for every t, >and the plot takes very long time... >Is there any way to make my plot faster, by evaluating >LARGE BLOCK (in Plot) only once, for every t?? > > > > > > > Mihajlo, Bob's suggestion gives you a way to modularalize the code for LARGE BLOCK using a function abstraction. Another way would be to use With: In[14]:= With[{LARGE = 1/2 - Cos[(2*# + \[Pi])/4]^2 &}, fun1[arg_] = Cos[arg]*LARGE[arg]; fun2[arg_] = Exp[arg]*LARGE[arg]; fun3[arg_] = arg*LARGE[arg];] In[15]:= Plot[{fun1[t], fun2[t], fun3[t]}, {t, 0, Pi}, PlotStyle -> Hue /@ ({0, 1, 2}/3)] As your functions depend only on one argument so does LARGE, also it is assumed that you factored out the block of lengthy calculation such that it delivers one value (to be used within the definitions of the funs). If that is not possible you might try using several LARGE1, LARGE2,... but the following will be of no value unless the number of desired output functions is substantially greater than the number of values transferred to them from LARGE BLOCK. So far all this doesn't help you very much, as in the Plot above (as well as in Bob's suggestion) LARGE will be evaluated separately (and again) when the function plotpoints are evaluated successively for fun1, fun2, fun3. A simple way out would be to tabulate the values for LARGE, taking for long time, then tabulate all the funs for short using those values of LARGE. And finally MulipleListPlot the funs'es values. If LARGE as well as each fun are only slowly varying, this might be quite satisfactory, but else you are loosing the advantages of Plot to keep the bending angle of successive polygon sections below MaxBend. The difficulty for tabulating LARGE now comes from the fact that sampling of plotpoints is done independently for fun1, fun2, etc.; so you cannot reuse the LARGE values calculated in plotting fun1 for fun2 or fun3. A way out would be to make an InterpolatingFunction from the tabulated values for LARGE, and then use this InterpolatingFunction for plotting the funs. Equidistant sampling for LARGE again might be satisfactory. But I think there is a better way, now exploiting the advantages of Plot's adaptive sampling algorithm: the bending angle is controlled independently of scaling in the local context of each successive triple of sampling points. So using the sampling of Plot for LARGE would make up a more robust InterpolatingFunction. Let's use Bob's approach for abstraction of LARGE: In[16]:= LARGE = 1/2 - Cos[(2*# + \[Pi])/4]^2 &; fun1[arg_] := Cos[arg]*LARGE[arg]; fun2[arg_] := Exp[arg]*LARGE[arg]; fun3[arg_] := arg*LARGE[arg] do the sampling... In[20]:= ppoints = {}; Module[{p}, Plot[(AppendTo[ppoints, {t, p = LARGE[t]}]; p), {t, 0, Pi}]] ...taking some time, and now reuse this calculation... In[23]:= Block[{LARGE=Interpolation[Union[ppoints]]}, Plot[{fun1[t],fun2[t],fun3[t]},{t,0,Pi}, PlotStyle -> Hue/@({0,1,2}/3)]] ...taking much less time. If you like to inspect the sampling points for LARGE: In[21]:= ListPlot[ppoints, PlotStyle -> PointSize[.02]] BTW, I had to use Union because the first two sampling Points came out too close, giving problems to Interpoaltion. Or you may compare the result of Out[23] with original LARGE In[35]:= Plot[{fun1[t], fun2[t], fun3[t]}, {t, 0, Pi}, PlotStyle -> Hue /@ ({0, 1, 2}/3)] Since this check will take your time again, if neccessary, you may restrict the test of comparison to a smaller interval of rapid variation (but lowering PlotPoints accordingly! with same MaxBend) and perhaps to only one function. -- Hartmut