# Improving plot execution time

Let me first show what I'm trying to do, and then I will ask the question.

I defined three function

BumpFunction[x_] := Exp[-x^2/(1-x^2)]

IntegrateBumpFunction[x_] := NIntegrate[BumpFunction[t] , {t, 0, x}]

IntegrateBumpFunctionNormalized[x_] := NIntegrate[BumpFunction[t] , {t, 0, x}]/NIntegrate[BumpFunction[t] , {t, 0, 1}]



Then, I will use Timing to measure the time spend to plot the functions IntegrateBumpFunction and IntegrateBumpFunctionNormalized.

Timing[Plot[IntegrateBumpFunction[x], {x,-1,1}]]
Timing[Plot[IntegrateBumpFunctionNormalized[x], {x,-1,1}]]


You will see that there is a runtime difference. The cause of this discrepancy is in the denominator NIntegrate[BumpFunction[t] , {t, 0, 1}] in the function IntegrateBumpFunctionNormalized. In my opinion this happen because the Plot function calls the IntegrateBumpFunctionNormalized function several times during its execution and you always have to evaluate the integral NIntegrate[BumpFunction[t] , {t, 0, 1}]. This causes an increase in time to plot.bvd

My question is: Is it possible to avoid this problem by telling the plot function evaluate the term NIntegrate[BumpFunction[t] , {t, 0, 1}] only once?

Thanks.

• Any function that uses a numeric technique (e.g., NIntegrate) should have its argument(s) restricted to numeric values (NumericQ), e.g., IntegrateBumpFunction[x_?NumericQ] := ... Oct 24 at 18:08
• AbsoluteTiming is preferable to Timing in modern multi-threaded CPUs. Oct 24 at 19:39

Change definition of normalized function

nor = NIntegrate[BumpFunction[t], {t, 0, 1}];
IntegrateBumpFunctionNormalized[x_] :=
NIntegrate[BumpFunction[t], {t, 0, x}]/nor


Or, ultrafast, integrate with NDSolve , so you don't have to integrate as many times as you have plotPoints, but only once generate an interpolating fucntion.

BumpFunction[x_] = Exp[-x^2/(1 - x^2)];

bfsol = bf /.
First@NDSolve[{bf'[x] == BumpFunction[x], bf[0] == 0},
bf, {x, -1, 1}]

Timing[Plot[bfsol[x], {x, -1, 1}]]
Timing[Plot[bfsol[x]/bfsol[1], {x, -1, 1}]]

• Shorter, if plotting only: NDSolveValue[{bf'[x] == BumpFunction[x], bf[0] == 0}, bf, {x, -1, 1}] // ListLinePlot, though normalized is not quite as slick: NDSolveValue[{bf'[x] == BumpFunction[x], bf[0] == 0}, {Indexed[bf@"Coordinates", 1], bf@"ValuesOnGrid"/bf[1]}, {x, -1, 1}] // Transpose // ListLinePlot (+1) Oct 24 at 19:40
• Hi @Akku14. Your answer really works. However, I was trying to keep all the computation within a single function and not separate parts. Anyway, thanks for the reply. Oct 24 at 22:12
• Hi @jonjones, "trying to keep all the computation within a single function" is a new request, not something you specified in your original question. I think that moving the goalpost after receiving a good answer is not nice. Probably you can ask a new question with all the new requirements spelt out explicitly from the beginning. Oct 25 at 9:28
• @MichaelE2 , thanks for the tips from a real expert. Oct 25 at 10:25
• Hello @rhermans, . I think you are right. The answer was really good and I had no intention of belittling the answer gave by Michael E2. Oct 25 at 18:05