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$
3
  • $\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
    Commented Sep 23, 2016 at 12:36
  • $\begingroup$ Another approach could be to use NDSolve instead of NIntegrate. $\endgroup$
    – Greg Hurst
    Commented Sep 25, 2016 at 18:30
  • $\begingroup$ An excelent answer can be found here: mathematica.stackexchange.com/a/130617/23248 $\endgroup$
    – ivbc
    Commented Nov 8, 2016 at 18:10

1 Answer 1

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 and acknowledge you have read our privacy policy.

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