0
$\begingroup$

I've noted that the numerical integration time of an interpolated function depends on the size of its domain. If I create two lists from the same function with the same step size, but one having a larger domain than the other, then the integration of the interpolated function of those lists, will take longer for the larger domain.

Let me use some calculations I've been doing as an example. Define the following functions and parameters:

c=6.642;
d=0.549;
p0=1/(4π Integrate[r^2/(1+E^((r-c)/d)),{r,0,∞}]);
p[r_?NumericQ]:=p0/(1+E^((r-c)/d));
F[q_?NumericQ]:=4π NIntegrate[If[q==0||r==0,r^2 p[r],Sin[(q r)/0.19733]/((q r)/0.19733) r^2 p[r]],{r,0,∞}];

Create 3 lists for the function $F[q]$, interpolate them all, and finally integrate them between $q=0$ and $q=1$.

The first one will have points between $q=0$ and $1=2000$ in steps of $1/200$ (this list took me almost 4h to create, but it has other purposes for me than just this example):

F02000200= Table[{q, F[q]}, {q, 0, 2000, 1/200}];

The second and third list will have values for $q$ between $0$ and $1$, and in steps of $1/200$ and $1/1000$ respectively:

F01200 = Table[{q, F[q]}, {q, 0, 1, 1/200}];
F011000 = Table[{q, F[q]}, {q, 0, 1, 1/1000}];

After creating these lists, interpolate them:

F02000200I = Interpolation[F02000200];
F01200I = Interpolation[F01200];
F011000I = Interpolation[F011000];

Now integrate these interpolated functions between $q=0$ to $q=1$, first without any method, then using "InterpolationPointsSubdivision" and defining "MaxSubregions" option.

Integration without options:

NIntegrate[F02000200I[q], {q, 0, 1}] // AbsoluteTiming
{23.7545, 0.0670531}

NIntegrate[F01200I[q], {q, 0, 1}] // AbsoluteTiming
{0.00335623, 0.0670531}

NIntegrate[F011000I[q], {q, 0, 1}] // AbsoluteTiming
{1.05108, 0.0670531}

This example shows that, integrating between $0$ and $1$, using $F02000200I[q]$ takes 7000x more time than $F01200I[q]$ even though they both have the same number of subdivisions in that range of integration. Also, it can be seen that integrating $F011000I[q]$ takes 300x more time than $F01200I[q]$. It's expected to take longer, but not 300x for only 5x the number of subdivisions.

Now, using "InterpolationPointsSubdivision" and "MaxSubregions:

NIntegrate[F02000200L[q],{q,0,1},Method->{"InterpolationPointsSubdivision","MaxSubregions"-> 202,"SymbolicProcessing"-> 0}]//AbsoluteTiming
{23.8689, 0.0670531}

NIntegrate[F01200L[q],{q,0,1},Method->{"InterpolationPointsSubdivision","MaxSubregions"->202}]//AbsoluteTiming
{0.00181735, 0.0670531}

NIntegrate[F011000L[q],{q,0,1},Method->{"InterpolationPointsSubdivision","MaxSubregions"-> 1002}]//AbsoluteTiming
{0.00640001, 0.0670531}

As we can see, better results are obtained for $F01200L[q]$ (even without MaxSubregions" because it's default value is 1000) and $F011000L[q]$ (I had to manually find the number of subdivision which at first thought should be 1001). The last one is only 3x slower for 5x more points, a great result! For $F02000200L[q]$, however, even with the same MaxSubregions number of $F01200L[q]$, which should be the same because their defining list uses the same step size, no enhancement of the time integration can be seen.

Messing around with the number of subregions and choose to be 400002 for $F02000200L[q]$ a 100x speed improvement can be obtained:

NIntegrate[F02000200L[q],{q,0,1},Method->{"InterpolationPointsSubdivision","MaxSubregions"-> 400002,"SymbolicProcessing"-> 0}]//AbsoluteTiming
{0.222328, 0.0670531}

Two main questions arise:

1) Why MaxSubregions should be 400002 for $F02000200L[q]$ and 202 for $F01200L[q]$?

2) Why it takes 100x more time to integrate $F02000200L[q]$ between $0$ and $1$ than $F01200L[q]$?

All of this is interesting because I need analyze functions which are defined as integrals of one or more parameters of other functions. The latter functions, are also defined as integrals of more elementary functions. Because of this, I decided to create lists the inner integrals so Mathematica doesn't need to compute them each time it computes the other ones. All of this gives rise to a third question:

3) How to choose the step size in order to get the optimum precision/time integration ratio.

Thanks

$\endgroup$
  • $\begingroup$ Sorry, but with a clear kernel, I cannot reproduce your results :((... My result for NIntegrate[F02000200I[q], {q, 0, 1}] // AbsoluteTiming is {0.004136, 87.8502}. I am using MMA ver 11.2 and macOS 10.13.3 $\endgroup$ – José Antonio Díaz Navas Jan 30 '18 at 18:04
  • $\begingroup$ @JoséAntonioDíazNavas You are right! For simplification purposes I changed a normalization constant $p0$ to 1... I'll edit the question. Thanks! $\endgroup$ – Pierre Jan 30 '18 at 18:31
  • $\begingroup$ @JoséAntonioDíazNavas And I'm using Mma 11.0... $\endgroup$ – Pierre Jan 30 '18 at 18:41
  • $\begingroup$ not following all of this but you can use analytic Integrate on an interpolation function. I expect it will be much faster. $\endgroup$ – george2079 Jan 30 '18 at 18:41
  • $\begingroup$ @george2079 Just tested your suggestion and it really does work! However I get the exact same results as with NIntegrate, "InterpolationPointsSubdivision" and "MaxSubregions" (taking ~0.23s for $F02000200L[q]$). The second and third questions are still pertinent. The first one is still interesting. $\endgroup$ – Pierre Jan 30 '18 at 18:50

Your Answer

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

Browse other questions tagged or ask your own question.