MathGroup Archive 2002

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

Search the Archive

RE: RE: plot several functions

  • To: mathgroup at smc.vnet.net
  • Subject: [mg35938] RE: [mg35900] RE: plot several functions
  • From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>
  • Date: Thu, 8 Aug 2002 06:06:29 -0400 (EDT)
  • Sender: owner-wri-mathgroup at wolfram.com

>-----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: [mg35938] [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: [mg35938] [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



  • Prev by Date: Need Help! Mathlink C++ problems
  • Next by Date: RE: Fw: Recursive Function
  • Previous by thread: RE: plot several functions
  • Next by thread: RE: RE: plot several functions