2
$\begingroup$

I have an interpolation through a list of points, which I need to integrate. The minimal working example looks as follows:

sin[t_] = Interpolation[Table[{x, Sin[x]}, {x, 0, \[Pi], \[Pi]/10}], Method -> "Hermite"][t];
Integrate[sin[x], x]

ClearSystemCache[]
Table[Integrate[sin[x], {x, 0, t}] // N, {t, 0, \[Pi], .01}]; // Timing
Table[NIntegrate[sin[x], {x, 0, t}], {t, 0, \[Pi], .01}]; // Timing

The output is as expected: The antiderivative is another InterpolatingFunction, and the Integrate version more than twice as fast as NIntegrate:

InterpolatingFunction[
    Domain: (0  \[Pi]) Output: scalar
]\[InvisibleApplication](x)

{0.18,Null}

{0.484,Null}

Now, let us change the interpolation method to "BSpline" in the first line. Then, I get the following output:

During evaluation of In[623]:= InterpolatingFunction::unsops: The operation is not supported for InterpolatingFunction[(0   \[Pi]),{5,39,0,{11},{4},0,0,0,0,Automatic,{},{},False},(0   \[Pi]/10    \[Pi]/5 (3 \[Pi])/10    (2 \[Pi])/5 \[Pi]/2 (3 \[Pi])/5 (7 \[Pi])/10    (4 \[Pi])/5 (9 \[Pi])/10    \[Pi]),{BSplineFunction[(0. 3.14159),<>],{}},{Automatic}] that was created with Method -> "Spline". >>

Out[625]= \[Integral]InterpolatingFunction[
    Domain: (0  \[Pi]) Output: scalar
]\[InvisibleApplication](x)\[DifferentialD]x

During evaluation of In[623]:= InterpolatingFunction::unsops: The operation is not supported for InterpolatingFunction[(0   \[Pi]),{5,39,0,{11},{4},0,0,0,0,Automatic,{},{},False},(0   \[Pi]/10    \[Pi]/5 (3 \[Pi])/10    (2 \[Pi])/5 \[Pi]/2 (3 \[Pi])/5 (7 \[Pi])/10    (4 \[Pi])/5 (9 \[Pi])/10    \[Pi]),{BSplineFunction[(0. 3.14159),<>],{}},{Automatic}] that was created with Method -> "Spline". >>

During evaluation of In[623]:= General::stop: Further output of InterpolatingFunction::unsops will be suppressed during this calculation. >>

Out[626]= {2.836,Null}

Out[627]= {1.104,Null}

So, the InterpolatingFunction can not longer be inspected before evaluation. This results in NIntegrate being 2.5 times faster, but six times slower than Integrate in the first example!

NB: The error messages go away if I define the function for numerical arguments only, sin[t_?NumericQ] = ... See Failure in integrating from an interpolating function!.

Question: Is there any feasible solution to improve the performance of the BSpline integration? For my data, the interpolation with Hermite gives really poor results and cannot be used.

$\endgroup$
  • 1
    $\begingroup$ Antidifferentiation is one of the advantages of Hermite interpolation. Would NDSolveValue[{y'[x] == sin[x], y[0] == 0}, y, {x, 0, Pi}] do what want? $\endgroup$ – Michael E2 Nov 26 '18 at 15:09
  • $\begingroup$ Related: (Ways to quicken numeric integral over interpolating spline?) $\endgroup$ – Carl Woll Nov 26 '18 at 17:41
  • $\begingroup$ @MichaelE2: Great suggestion, this is awesome! $\endgroup$ – Erwin411 Nov 27 '18 at 14:01
3
$\begingroup$

Following @MichaelE2's suggestion, I've converted the problem into an ODE:

In[1]:=
  sin[t_] = Interpolation[Table[{x, Sin[x]}, {x, 0, \[Pi], \[Pi]/10}], Method -> "Spline"][t];

  Block[{f},
    f = NDSolveValue[{y'[x] == sin[x], y[0] == 0}, y, {x, 0, \[Pi]}];
    Table[f[t], {t, 0, \[Pi], .01}];
    ] // AbsoluteTiming

Out[2]= {0.005696,Null}

It works equally well for Spline and Hermite and is orders of magnitude faster than Integrate or NIntegrate. (I've cleared the caches and even restarted the kernel.)

$\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.