Solution using NIntegrate of Mathematica 6+ (9.0.1)
One can achieve for integrating InterpolatingFunction by NIntegrate the same precision as with Integrate by specifying explicit set of Exclusions and MaxRecursion->0 (although the timings are disappointing):
integrand[ww_, k_] := k/ww
dataF = {#1, integrand[#1, #2]} & @@@ data;
int = Interpolation[dataF, InterpolationOrder -> 1];
ni1 = NIntegrate[int[ww], {ww, dataF[[1, 1]], dataF[[-1, 1]]},
MaxRecursion -> 0, PrecisionGoal -> 16,
Exclusions -> dataF[[2 ;; -2, 1]]]; // AbsoluteTiming
ni2 = NIntegrate[int[ww], Evaluate@Prepend[dataF[[All, 1]], ww],
MaxRecursion -> 0, PrecisionGoal -> 16]; // AbsoluteTiming
i1 = Integrate[int[ww], {ww, dataF[[1, 1]], dataF[[-1, 1]]}]; // AbsoluteTiming
exactSum =
MovingAverage[dataF[[All, 2]], 2].Differences[
dataF[[All, 1]]]; // AbsoluteTiming
{ni1, ni2} - i1
{ni1, ni2, i1} - exactSum
{ni1, ni2, i1, exactSum} // InputForm
During evaluation of In[1]:= NIntegrate::ncvb: NIntegrate failed to converge to prescribed accuracy after 0 recursive bisections in ww near {ww} = {1034.51}. NIntegrate obtained 0.00003537589327712014` and 5.3740022820734247`*^-20 for the integral and error estimates. >>
Out[5]= {171.515625, Null}
During evaluation of In[1]:= NIntegrate::ncvb: NIntegrate failed to converge to prescribed accuracy after 0 recursive bisections in ww near {ww} = {575.35}. NIntegrate obtained 0.000035375893282044965` and 3.621199488108469`*^-12 for the integral and error estimates. >>
Out[6]= {150.656250, Null}
Out[7]= {0.250000, Null}
Out[8]= {0.031250, Null}
Out[9]= {1.76183*10^-19, 4.925*10^-15}
Out[10]= {-9.28912*10^-13, -9.23987*10^-13, -9.28912*10^-13}
Out[11]//InputForm=
{0.00003537589327712014, 0.000035375893282044965, 0.00003537589327711996,
0.00003537589420603182}
Using the "LocalAdaptive" strategy and non-zero MaxRecursion in the same manner one can increase precision of integration of smooth function of InterpolatingFunction:
int2 = Interpolation[data, InterpolationOrder -> 1];
ni3 = NIntegrate[int2[ww]/ww, {ww, data[[1, 1]], data[[-1, 1]]},
MaxRecursion -> 12, PrecisionGoal -> 16, Exclusions -> data[[2 ;; -2, 1]],
Method -> "LocalAdaptive"]; // AbsoluteTiming
ni4 = NIntegrate[int2[ww]/ww, Evaluate@Prepend[dataF[[All, 1]], ww],
MaxRecursion -> 12, PrecisionGoal -> 16,
Method -> "LocalAdaptive"]; // AbsoluteTiming
area[{w1_, k1_}, {w2_, k2_}] =
Integrate[(a + b ww)/ww, {ww, w1, w2}, PrincipalValue -> True] /.
First@Solve[a + b w1 == k1 && a + b w2 == k2, {a, b}] // Simplify;
exactSum2 = Total[area @@@ Partition[data, 2, 1]]; // AbsoluteTiming
{ni1, ni2} - exactSum
{ni1, ni2, exactSum} // InputForm
Out[13]= {197.421875, Null}
Out[14]= {169.859375, Null}
Out[16]= {1.015625, Null}
Out[17]= {-9.28912*10^-13, -9.23987*10^-13}
Out[18]//InputForm=
{0.00003537589327712014, 0.000035375893282044965, 0.00003537589420603182}
NIntegrate of Mathematica 5.2
I should also point out that in Mathematica 5.2 one can get the same precision using only MaxRecursion and PrecisionGoal options and much faster, addition of exclusions makes it even faster:
In[4]:= << Statistics`DataSmoothing`
data = << data.m;
integrand[ww_, k_] := k/ww
dataF = {#1, integrand[#1, #2]} & @@@ data;
int = Interpolation[dataF, InterpolationOrder -> 1];
ni1 = NIntegrate[int[ww], {ww, dataF[[1, 1]], dataF[[-1, 1]]},
MaxRecursion -> 25, PrecisionGoal -> 16]; // AbsoluteTiming
ni2 = NIntegrate[int[ww], Evaluate@Prepend[dataF[[All, 1]], ww],
MaxRecursion -> 0, PrecisionGoal -> 16,
SingularityDepth -> 0]; // AbsoluteTiming
i = Integrate[int[ww], {ww, dataF[[1, 1]], dataF[[-1, 1]]}]; // AbsoluteTiming
exactSum =
MovingAverage[dataF[[All, 2]],
2].(Rest@dataF[[All, 1]] - Most@dataF[[All, 1]]); // AbsoluteTiming
{ni1, ni2} - i
{ni1, ni2, i} - exactSum
{ni1, ni2, i, exactSum} // InputForm
From In[4]:= NIntegrate::slwcon: Numerical integration converging too slowly; suspect one of the following: singularity, value of the integration being 0, oscillatory integrand, or insufficient WorkingPrecision. If your integrand is oscillatory try using the option Method->Oscillatory in NIntegrate. More\[Ellipsis]
From In[4]:= NIntegrate::ncvb: NIntegrate failed to converge to prescribed accuracy after 26 recursive bisections in ww near ww = 1033.9707945203033`. More\[Ellipsis]
Out[9]= {79.5937500 Second, Null}
From In[4]:= NIntegrate::ncvb: NIntegrate failed to converge to prescribed accuracy after 2 recursive bisections in ww near ww = 575.2930004161132`. More\[Ellipsis]
Out[10]= {37.2656250 Second, Null}
Out[11]= {0.2656250 Second, Null}
Out[12]= {0.0468750 Second, Null}
Out[13]= {-5.34626*10^-14, 6.48336*10^-13}
Out[14]= {-9.82374*10^-13, -2.80576*10^-13, -9.28912*10^-13}
Out[15]//InputForm=
{0.000035375893223657405, 0.00003537589392545566, 0.00003537589327711996,
0.000035375894206031784}
In[16]:= int2 = Interpolation[data, InterpolationOrder -> 1];
ni3 = NIntegrate[int2[ww]/ww, {ww, data[[1, 1]], data[[-1, 1]]},
MaxRecursion -> 25, PrecisionGoal -> 16]; // AbsoluteTiming
ni4 = NIntegrate[int2[ww]/ww, Evaluate@Prepend[data[[All, 1]], ww],
MaxRecursion -> 12, PrecisionGoal -> 16]; // AbsoluteTiming
area[{w1_, k1_}, {w2_, k2_}] =
Integrate[(a + b ww)/ww, {ww, w1, w2}, PrincipalValue -> True] /.
First@Solve[a + b w1 == k1 && a + b w2 == k2, {a, b}] // Simplify;
exactSum2 = Total[area @@@ Partition[data, 2, 1]]; // AbsoluteTiming
{ni3, ni4} - exactSum2
{ni3, ni4, exactSum2} // InputForm
From In[16]:= NIntegrate::slwcon: Numerical integration converging too slowly; suspect one of the following: singularity, value of the integration being 0, oscillatory integrand, or insufficient WorkingPrecision. If your integrand is oscillatory try using the option Method->Oscillatory in NIntegrate. More\[Ellipsis]
From In[16]:= NIntegrate::ncvb: NIntegrate failed to converge to prescribed accuracy after 26 recursive bisections in ww near ww = 1033.9707945203033`. More\[Ellipsis]
Out[17]= {84.7031250 Second, Null}
From In[16]:= NIntegrate::slwcon: Numerical integration converging too slowly; suspect one of the following: singularity, value of the integration being 0, oscillatory integrand, or insufficient WorkingPrecision. If your integrand is oscillatory try using the option Method->Oscillatory in NIntegrate. More\[Ellipsis]
From In[16]:= NIntegrate::tmap: NIntegrate is unable to achieve the tolerances specified by the PrecisionGoal and AccuracyGoal options because the working precision is insufficient. Try increasing the setting of the WorkingPrecision option.
Out[18]= {39.8593750 Second, Null}
Out[20]= {1.8281250 Second, Null}
Out[21]= {-9.83531*10^-13, -9.3084*10^-13}
Out[22]//InputForm=
{0.00003537589321637961, 0.000035375893269070094, 0.00003537589419991056}
All the above timings I have got on the same machine.
First@Import....is a header and the table is not formatted properly. It seems that the first 38 elements are headers and so is the last. Can you useImport[...,"Table"]and select only numbersSelect[#, NumberQ]/@then see if you can reproduce it? – gpap Feb 1 at 13:33Plot[Derivative[-1][int][ww], {ww, dataF[[1, 1]], dataF[[-1, 1]]}, Evaluated -> True]looks okay? – Oleksandr R. Feb 1 at 13:57ListLogPlot[data, PlotRange -> All, Joined -> True]gives me this. – Alexey Popkov Feb 1 at 14:30Importcode will not work since support of thejdx(JCAMP-DX) format is added in version 9. I'll try to find a workaround. – Alexey Popkov Feb 1 at 14:41