# Optimization for plotting

I would like to know if there is any way to improve the speed of the following program:

f := 1 - (2 M)/r; M = 1;

Va := f ((l (l + 1))/r^2 + ((1 - S^2) \!$$\*SubscriptBox[\(\[PartialD]$$, $$r$$]f\))/r);(*Axial potential*)

rmin := r /. Last[FindMaximum[{V, r > M}, r]]

V1 := f \!$$\*SubscriptBox[\(\[PartialD]$$, $$r$$]V\);
V2 := f \!$$\*SubscriptBox[\(\[PartialD]$$, $$r$$]V1\);
V3 := f \!$$\*SubscriptBox[\(\[PartialD]$$, $$r$$]V2\);
V4 := f \!$$\*SubscriptBox[\(\[PartialD]$$, $$r$$]V3\);
V5 := f \!$$\*SubscriptBox[\(\[PartialD]$$, $$r$$]V4\);
V6 := f \!$$\*SubscriptBox[\(\[PartialD]$$, $$r$$]V5\);

\[CapitalGamma] :=
1/Sqrt[-2 V2] (1/8 (V4/V2) (1/4 + (n + 1/2)^2) -
1/288 (V3/V2)^2 (7 + 60 (n + 1/2)^2));
\[CapitalOmega] :=
1/(-2 V2) (5/6912 (V3 /V2)^4 (77 + 188 (n + 1/2)^2) -
1/384 (((V3)^2  V4)/(V2)^3) (51 + 100 (n + 1/2)^2) +
1/2304 (V4/V2)^2 (67 + 68 (n + 1/2)^2) +
1/288 ((V3 V5)/(V2)^2) (19 + 28 (n + 1/2)^2) -
1/288 (V6/V2) (5 + 4 (n + 1/2)^2));

\[Omega] := Sqrt[
V + \[CapitalGamma] Sqrt[(-2 V2)] -
I (n + 1/2) (1 + \[CapitalOmega]) Sqrt[(-2 V2)]];

(**********Plots**********)
V := Va;
S = 0;
Print[Style["Scalar perturbation", {Bold, Larger}], " Spin = ", S]

pp = 100;

l = 2; n = 0;
P1 = Plot[{Re[\[Omega]] /. r -> rmin, -Im[\[Omega]] /.
r -> rmin }, {M, 10^-3, 30}, AxesLabel -> {"M", "\[Omega]"},
PlotStyle -> {{Line, Blue}, {Dashed, Blue}},
PlotLegends -> Placed[{"\[ScriptL]=2"}, {0.7, 0.8}],
PlotRange -> {{0, 30}, {0, Automatic}}, MaxRecursion -> Infinity,
PlotPoints -> pp]; // AbsoluteTiming
l = 3; n = 0;
P2 = Plot[{Re[\[Omega]] /. r -> rmin, -Im[\[Omega]] /.
r -> rmin }, {M, 10^-3, 30}, AxesLabel -> {"M", "\[Omega]"},
PlotStyle -> {{Line, Red}, {Dashed, Red}},
PlotLegends -> Placed[{"\[ScriptL]=3"}, {0.7, 0.8}],
PlotRange -> {{0, 30}, {0, Automatic}}, MaxRecursion -> Infinity,
PlotPoints -> pp]; // AbsoluteTiming
l = 4; n = 0;
P3 = Plot[{Re[\[Omega]] /. r -> rmin, -Im[\[Omega]] /.
r -> rmin }, {M, 10^-3, 30}, AxesLabel -> {"M", "\[Omega]"},
PlotStyle -> {{Line, Black}, {Dashed, Black}},
PlotLegends -> Placed[{"\[ScriptL]=4"}, {0.7, 0.8}],
PlotRange -> {{0, 30}, {0, Automatic}}, MaxRecursion -> Infinity,
PlotPoints -> pp]; // AbsoluteTiming

Show[P1, P2, P3, Frame -> True, FrameLabel -> {"Mass", "Frequency"},
ImageSize -> Medium]


I have to make several analysis for even more complicated Vs, and several different plots. They are taking longer and longer and I have no idea how make this faster. Right now it is taking several minutes to run it.

• You use SetDelayed (:=) in loads of places you don't need it which is a drag on performance. Just use Set (=). Also don't use [PartialD] - just write D[V, r] for instance - as it becomes messy. After changing MaxRecursion to 15 (the max allowed) and making these other edits it takes 0.924229 seconds on my machine though the plot is just flat lines. – flinty Jul 3 at 16:56
• Removing MaxRecurson and PlotPoints makes no difference to me visually, and of course it's much, much faster. (I don't see flat lines like flinty. I see curves.) – C. E. Jul 3 at 17:00
• Also your rmin := r /. Last[FindMaximum[{V, r > M}, r]] comes before the definition of V, you should move V up. – flinty Jul 3 at 17:07
• @C.E. I added both MaxRecursion and PlotPoints hoping that it would be more precise. – Edison Santos Jul 3 at 17:55
• @flinty What is the difference between setting the definition before or after V? – Edison Santos Jul 3 at 17:55

It is quite tedious to modify your code so I will stick to some general hints:

• Your functions are all of relatively simple form it is best to just use their analytical form instead of SetDelay, aka :=, everything. So write

Va[r_] = ... (*yes, no colon here*)

Va := ...
• Then write f'[r] instead of your partial derivatives in the new function definitions because the other syntax does not work any more now (check this but I think they should all be reasonable algebraically compact)
• Try a Simplify for your expressions (might be unnecessary or useless but sometimes gives a speed up afterwards)
• Can you elaborate on why you would not use SetDelayed in your first general hint? I think it would bring more clarity to this answer! – CA Trevillian Aug 10 at 21:10