3
$\begingroup$

I would like to optimize evaluation of the function defined as an integral:

f[x_]:= NIntegrate[g[s],{s,0,x}]

the function g[x] can be an Interpolating function. The problem is that when I want to generate a Table of points

Table[f[x],{x,0.,200.,10.}]

function f[x] need to reintegrate the previous domain which is a waste of time because I calculated this value previously. I am thinking of a function definition that stores limits of integration and the value of the NIntegrate and when I call it for different argument it just integrates the missing part and adds it to the stored variable. For example:

f[2.] = NIntegrate[g[s],{s,0.,2.}]
f[4.] = NIntegrate[g[s],{s,2.,4.}] + f[2.]
f[3.] = f[4.] - NIntegrate[g[s],{s,3.,4.}] 

With this function definition creating a list of values would be much faster. Is something like this possible in Mathematica 11.0?

$\endgroup$
  • $\begingroup$ If g is an InterpolatingFunction (as opposed to merely "can be"), then use Integrate[g[s], s], which yields a G[s] where G is the integral (an InterpolatingFunction) of g such that G[a] == 0, where {a, b} is the domain of g. $\endgroup$ – Michael E2 Sep 23 '16 at 12:36
  • $\begingroup$ Another approach could be to use NDSolve instead of NIntegrate. $\endgroup$ – Chip Hurst Sep 25 '16 at 18:30
  • $\begingroup$ An excelent answer can be found here: mathematica.stackexchange.com/a/130617/23248 $\endgroup$ – ivbc Nov 8 '16 at 18:10
2
$\begingroup$

The behavior you seek of remembering subcalculations is called memoization (Wolfram Tutorial) and could be implemented like this:

delta = 10.;
f2[x_]:= f2[x] = f2[x - delta] + NIntegrate[g[s],{s,x - delta,x}];
f2[0.] = 0;
ans3 = Table[f2[x], {x, 0., 200., delta}]

As a demo, I will use g = FunctionInterpolation[Exp[x/200], {x, 0, 200}] here.

However this does actually not run any faster than your original proposition (at least for the g I chose here), because NIntegrate is still called as many times as before. Just because the intervals you integrate over are smaller, does not mean NIntegrate will necessarily run much faster, because it uses adaptive algorithms to subdivide the interval it's given in every case.


When g is an InterpolatingFunction then Integrate[g[s], s] should be possible for symbolic s. So you can just do

int = Integrate[g[s], s];
a = int /. s -> 0;
ans1 = Table[int - a /. s -> x, {x, 0., 200., 10.}]

With g = FunctionInterpolation[Exp[x/200], {x, 0, 200}] the code

f[x_]:= NIntegrate[g[s],{s,0,x}];
ans2 = Table[f[x],{x,0.,200.,10.}]

takes 0.03 second to complete, while my suggestion takes 0.0006 seconds. Note however that ans1 - ans2 have some terms of order $10^{-6}$, which you may or may not need to think about.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.