# Optimize function defined with Nintegrate

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?

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

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.