Skip to main content

How to speed up integration of interpolation function?


I have a list of data, and I interpolate it to a function. Then I need to do an integration with the interpolating function. But I found that the speed is unacceptably slow.


My data is here (a little long, but don't go away :) ):


data = {-0.00799443, -0.00581522, -0.00557107, -0.00543862, -0.00528042, \

-0.00508618, -0.00486091, -0.00461279, -0.00435009, -0.00408028, \
-0.0038098, -0.00354416, -0.00328805, -0.00304535, -0.00281906, \
-0.0026108, -0.00242045, -0.00224588, -0.00208332, -0.00192845, \
-0.00177801, -0.00163133, -0.00149092, -0.00136145, -0.0012474, \
-0.00115024, -0.00106716, -0.000992246, -0.000919878, -0.000848073, \
-0.000779184, -0.000717175, -0.000663667, -0.000616407, -0.00057173, \
-0.000528424, -0.000488614, -0.000454547, -0.000425288, -0.000397686, \
-0.000370268, -0.00034446, -0.000321488, -0.00030009, -0.000278782, \
-0.000258483, -0.000240725, -0.000224931, -0.000209972, -0.000196452, \
-0.000184918, -0.000174195, -0.000163592, -0.000153752, -0.000144418, \

-0.000134884, -0.000125771, -0.000117444, -0.000109436, -0.000102175, \
-0.0000959463, -0.0000902133, -0.000085125, -0.0000806452, \
-0.0000762082, -0.0000719591, -0.0000677566, -0.000063368, \
-0.0000591507, -0.0000549953, -0.0000510613, -0.0000475951, \
-0.0000444333, -0.0000417897, -0.0000394736, -0.0000373836, \
-0.0000354749, -0.0000334705, -0.0000314543, -0.0000292503, \
-0.0000269879, -0.0000247026, -0.0000224853, -0.0000204942, \
-0.0000187118, -0.0000172668, -0.0000160166, -0.0000149913, \
-0.0000139883, -0.0000129844, -0.000011827, -0.0000105289, \
-9.06132*10^-6, -7.50783*10^-6, -5.94092*10^-6, -4.46213*10^-6, \

-3.15097*10^-6, -2.0399*10^-6, -1.13236*10^-6, -3.57489*10^-7,
3.57489*10^-7, 1.13236*10^-6, 2.0399*10^-6, 3.15097*10^-6,
4.46213*10^-6, 5.94092*10^-6, 7.50783*10^-6,
9.06132*10^-6, 0.0000105289, 0.000011827, 0.0000129844, \
0.0000139883, 0.0000149913, 0.0000160166, 0.0000172668, 0.0000187118, \
0.0000204942, 0.0000224853, 0.0000247026, 0.0000269879, 0.0000292503, \
0.0000314543, 0.0000334705, 0.0000354749, 0.0000373836, 0.0000394736, \
0.0000417897, 0.0000444333, 0.0000475951, 0.0000510613, 0.0000549953, \
0.0000591507, 0.000063368, 0.0000677566, 0.0000719591, 0.0000762082, \
0.0000806452, 0.000085125, 0.0000902133, 0.0000959463, 0.000102175, \

0.000109436, 0.000117444, 0.000125771, 0.000134884, 0.000144418, \
0.000153752, 0.000163592, 0.000174195, 0.000184918, 0.000196452, \
0.000209972, 0.000224931, 0.000240725, 0.000258483, 0.000278782, \
0.00030009, 0.000321488, 0.00034446, 0.000370268, 0.000397686, \
0.000425288, 0.000454547, 0.000488614, 0.000528424, 0.00057173, \
0.000616407, 0.000663667, 0.000717175, 0.000779184, 0.000848073, \
0.000919878, 0.000992246, 0.00106716, 0.00115024, 0.0012474, \
0.00136145, 0.00149092, 0.00163133, 0.00177801, 0.00192845, \
0.00208332, 0.00224588, 0.00242045, 0.0026108, 0.00281906, \
0.00304535, 0.00328805, 0.00354416, 0.0038098, 0.00408028, \

0.00435009, 0.00461279, 0.00486091, 0.00508618, 0.00528042, \
0.00543862, 0.00557107, 0.00581522, 0.00799443}

Interpolate it:


f = Interpolation[data];
Plot[f[x], {x, 1, 200}, PlotRange -> All]

It looks like:


interpolating function plot


Now I define a function:



Clear[b];
b[x_, y_] := NIntegrate[
Cross[{0, f[s], 0}, {x - s, 0, y}][[{1, 3}]]/((x - s)^2 + y^2),
{s, 1, 200}
];

The integration is so slow!!


b[1., 2.] // AbsoluteTiming

(*{1.17772, {-0.00827965, -0.0104805}}*)


What I want to do is a vector plot:


VectorPlot[b[x, y], {x, -10, 210}, {y, -3, 3}]

But with this kind of slow integration, this is painful. Are there better ways to speed up the integration?



Answer



The way to deal with this is to use the special setting Method -> "InterpolationPointsSubdivision" of NIntegrate[], which will automagically split the integrand so that an integration rule (by default, "GlobalAdaptive") is only applied within each piecewise polynomial interval of the InterpolatingFunction[] involved. This is akin to the functionality of the old package NumericalMath`NIntegrateInterpolatingFunct`​.


As a demonstration:


With[{x = 5, y = 5}, 
NIntegrate[Cross[{0, f[s], 0}, {x - s, 0, y}][[{1, 3}]]/((x - s)^2 + y^2),

{s, 1, 200}]] // AbsoluteTiming
{0.619479, {-0.00929476, -0.00291246}}

With[{x = 5, y = 5},
NIntegrate[Cross[{0, f[s], 0}, {x - s, 0, y}][[{1, 3}]]/((x - s)^2 + y^2),
{s, 1, 200}, Method -> "InterpolationPointsSubdivision"]] // AbsoluteTiming
{0.0798281, {-0.00929476, -0.00291246}}

Options[NIntegrate`InterpolationPointsSubdivision] displays the suboptions that can be fed to this method.


Comments