NDSolve
has an interface for repeatedly solving an equation with different initial conditions without having to analyze the equation and set up the solving algorithm each time. This can improve performance dramatically. For example,
nd = First@NDSolve`ProcessEquations[{y'[t] == -y[t], y[0] == 1}, {y}, t]
(* NDSolve`StateData[<0.>] *)
solve[y0_] := Module[{}, nd = First@NDSolve`Reinitialize[nd, y[0] == y0];
NDSolve`Iterate[nd, 1]; NDSolve`ProcessSolutions[nd]]
Timing[NDSolve[{y'[t] == -y[t], y[0] == #}, y, {t, 0, 1}]&/@Range[0.001, 1, 0.001]]//First
(* 0.527396 *)
Timing[solve /@ Range[0.001, 1, 0.001]] // First
(* 0.250309 *)
Is there an analogous interface to NIntegrate
that would allow me to process the integral once, then do integrations using the same integration method (as chosen by NIntegrate
) repeatedly using different constants in the integrand and/or different limits of integration?
Answer
NIntegrate
performs a certain symbolic processing of the integrand to detect discontinuities, singularities, to determine the method to choose and so on.
If you know the integrand pretty well, the way to reduce the overhead is to set the method explicitly, set its SymbolicProcessing
suboption to 0 (to allow to time spent on the preprocessing), and to add points of discontinuities to the path explicitly.
This can make a significant difference in timing:
In[66]:= Do[
NIntegrate[Piecewise[{{x^2, x <= 1}}, 1/1 + x], {x, 0, 1, 2},
Method -> {"GaussKronrodRule",
"SymbolicProcessing" -> 0}], {10^3}] // AbsoluteTiming
Out[66]= {1.542154, Null}
In[67]:= Do[
NIntegrate[
Piecewise[{{x^2, x <= 1}}, 1/1 + x], {x, 0,
2}], {10^3}] // AbsoluteTiming
Out[67]= {15.063506, Null}
Comments
Post a Comment