Plotting 2 functions & economizing on calc of intermediate result

  • Context: Mathematica 
  • Thread starter Thread starter Swamp Thing
  • Start date Start date
  • Tags Tags
    Functions Plotting
Join the discussion
Registration is free. Ask a follow-up in this thread, or start your own.
2 replies · 2K views
Swamp Thing
Insights Author
Messages
1,065
Reaction score
820
TL;DR
It's complicated :)
I am trying to plot two functions a(t) and b(t) that both use a common intermediate result K. In my actual code K would be a slow-ish calculation. To reuse the K across a and b, I am putting them into a single module that provides an array {a, b} to the Plot[] function. (BTW, the Evaluate[] is needed because without it, both plots come out the same color).

So far so good. But a(t) involves discretizing t to get N, and then summing over N terms, as in Total[Range[IntegerPart[t/20]]].

Now, although the plot comes out OK in this example, it displays a little error message : "Range specification in Range[IntegerPart[t/20]] does not have appropriate bounds". I am worried that this error will break my actual plot, which would be more complicated than this minimal demo, so it would be nice to get rid of the error.

And BTW, if I plot a and b separately and do a Show[Pa, Pb] then it works fine with no error -- at the cost of computing K twice as many times. Same if I Plot[{fn_a[t] , fn_ b[t],{t,0,10 }] in the usual way.

Thanks!

Code:
Plot[ Evaluate[
                       Module[{K,a,b},

                            (* "K" is an intermediate result needed for "a" and "b" *)
                            K=t; (* we don't want to calc this more than once per t *)

                            (* "a" is a sum over N terms; N depends on "t" *)
                            a= K * Total[Range[IntegerPart[t/20]]];

                             (* "b" is just a simple function of "t" *)
                                   b= K * t/10+5;

                              (* We want to plot a and b as a fn of t *)
                              {a,b}

                                   ]
                            ] ,

       {t,100,200},Exclusions->None
     ]
 
Last edited:
Physics news on Phys.org
If K is a function of x then you can make K into a function that remembers its values as follows:

K[x_]:=K[x]= (* some expression involving x *)

Every time you evaluate K it will remember the result and it will simply use that result instead of recalculating it.
 
  • Informative
Likes   Reactions: Swamp Thing
Brilliant!
Now the code is as simple as this:

Code:
fnA[x_]:=Total[Range[IntegerPart[x/20]]]
fnB[x_]:=.1*x

n=0 (*Evaluation counter for K *)
K[x_]:=K[x]= (n=n+1;0.2*x) (* value common to A, B *)

Plot[{ K[x]+fnA[x] , K[x]+fnB[x] } , {x,100,200}]

Style[Row[{"Evalutated 'K' ",n," times"}],20]

1609390845442.png

1609390952277.png


Thanks again!
 
  • Like
Likes   Reactions: Dale