How to get rid of the error message when evaluating a highly oscillatory numerical integral?
The shortest and best way between two truths of the real domain often passes through the imaginary one.
— Jacques Hadamard
By taking a complex path, I get the answer without any complaints from Mathematica.
parabolic[a_, x_] = Simplify[InterpolatingPolynomial[{{-10, 0}, {0, a}, {10, 0}}, x]]
With[{a = 1},
Re[NIntegrate[With[{x = x + I parabolic[a, x]},
Exp[-x^2 + 100 I x]] (1 + I Derivative[0, 1][parabolic][a, x]),
{x, -10, 10}, WorkingPrecision -> 20]]]
5.1113608752199029964*10^-46
If you want further reading, see this or this.
You can try setting the AccuracyGoal
lower than WorkingPrecision
, which yields the correct result without a reported warning.
NIntegrate[Exp[-x^2] Cos[100 x], {x, -10, 10},
Method -> {"LevinRule"}, WorkingPrecision -> 50, AccuracyGoal -> 35]
5.1113608752199120138254477520179596033660767259737*10^-46
NIntegrate[Exp[-x^2] Cos[100 x], {x, -10, 10},
Method -> {"LevinRule"}, WorkingPrecision -> 100, AccuracyGoal -> 90]
5.11136087521990299641307044175882379310640009556142432636206474874790\ 3858004996545055056958734154112*10^-46
Reference.
When you give a setting for
WorkingPrecision
, this typically defines an upper limit on the precision of the results from a computation. But within this constraint you can tell the Wolfram Language how much precision and accuracy you want it to try to get.
In a highly oscillatory function, the last few digits of precision may not converge and/or take extended time.
When in doubt, use brute force.
-- Ken Thompson
AbsoluteTiming[
NIntegrate[Exp[-x^2] Cos[100 x], {x, -10, 10},
Method -> {"LocalAdaptive", "SymbolicProcessing" -> 0, "SingularityHandler" -> None},
MaxRecursion -> 100,
AccuracyGoal -> 90, WorkingPrecision -> 100]
]
(* {100.201,
5.111360875219902996413070441758823793106400095561424326362063281173449212599595171095728154857298543*10^-46} *)