"After multiplying the integrand of NIntegrate
with -1
, the Precision
of the output will change." ← Sounds silly, huh? But this seems to be true at least for numerical integral internally using "ExtrapolatingOscillatory"
method. Just try the following example:
Precision /@
NIntegrate[{1, -1} BesselJ[0, x], {x, 0, ∞}, WorkingPrecision -> 32,
Method -> "ExtrapolatingOscillatory"]
{31.0265, 25.0279}
It's not necessary to set Method -> "ExtrapolatingOscillatory"
manually in this sample, I added the option just to emphasize.
Of course in the above example the difference of precision is small and isn't a big deal, but in some cases the difference can be drastic, for example the following I encountered in this problem:
f[p_, ξ_] = -(5 p Sqrt[(5 p^2)/6 + ξ^2] )/(
4 (-4 ξ^2 Sqrt[(5 p^2)/6 + ξ^2] Sqrt[(5 p^2)/2 + ξ^2] + ((5 p^2)/2 + 2 ξ^2)^2));
pmhankel[p_, sign_: 1, prec_: 32] :=
NIntegrate[sign ξ BesselJ[0, ξ] f[p, ξ], {ξ, 0, ∞},
WorkingPrecision -> prec, Method -> "ExtrapolatingOscillatory"]
preclst = Table[Precision@pmhankel[#, sign] & /@ Range@32, {sign, {1, -1}}]
ListLinePlot[preclst, PlotRange -> All]
It's not necessary to set Method -> "ExtrapolatingOscillatory"
manually in this sample, I added the option just to emphasize.
How to understand the behavior? Except for calculating every integral twice and choosing the better one, how to circumvent the problem?
"ExtrapolatingOscillatory"
to work without preliminary symbolic processing, how else can the zeroes where the integrand will be split at be determined? $\endgroup$"SymbolicProcessing->0"
the problem remains:pmhankelTest[p_, sign_: 1, prec_: 16] := NIntegrate[sign ξ BesselJ[0, ξ] f[p, ξ], {ξ, 0, ∞}, WorkingPrecision -> prec, Method -> {"ExtrapolatingOscillatory", "SymbolicProcessing" -> 0}];pmhankelTest[32, #, 32] & /@ {-1, 1}
(2) I triedIntegrationMonitor
mentioned in this answer, the{"Boundaries", "Dimension", "Error", "GetRule", "Integrand"}
etc. seems to be all the same, and the only difference between"Integral"
is the sign. $\endgroup$"ExtrapolatingOscillatory"
, and the problem doesn't show up in my (much slower) implementation:zero[i_] := Piecewise[{{BesselJZero[0, i], i > 0}}];separatepmhankel[p_?NumericQ, sign : 1 | -1, i_?NumericQ, prec_] := NIntegrate[sign ξ BesselJ[0, ξ] f[p, ξ], {ξ, zero@i, zero[i + 1]}, WorkingPrecision -> prec, MaxRecursion -> 40]; manualpmhankel[p_, sign_: 1, prec_: 16] := NSum[separatepmhankel[p, sign, i, prec], {i, 0, Infinity}, Method -> "AlternatingSigns", WorkingPrecision -> prec]; manualpmhankel[32, #, 32]&/@{1,-1} // AbsoluteTiming
$\endgroup$NIntegrate
internally switches to"LevinRule"
, and the output is indeed the same as that with option, Method -> "LevinRule"
. How about giving an answer? $\endgroup$