# How to get rid of the error message when evaluating a highly oscillatory numerical integral?

I have a simple numerical integral with a highly oscillatory integrand:

In:= Integrate[Exp[-x^2] Cos[100 x], {x, -10, 10}] // N

Out= 5.11136*10^-46 + 0. I


Using numerical integration, I used the method "LevinRule" and increased the WorkingPrecision to 50. I got the right result, but it came with an error message:

In:= NIntegrate[Exp[-x^2] Cos[100 x], {x, -10, 10},
Method -> {"LevinRule"}, WorkingPrecision -> 50]

Out= 5.1113608752199056046419863980883842786372578322323*10^-46


The error message says that the integral failed to converge, which makes me worry if I don't know the exact answer in advance.

During evaluation of In:= NIntegrate::slwcon: Numerical integration converging too
slowly; suspect one of the following: singularity, value of the integration is 0,
highly oscillatory integrand, or WorkingPrecision too small. >>

During evaluation of In:= NIntegrate::ncvb: NIntegrate failed to converge to
prescribed accuracy after 9 recursive bisections in x near
{x} = {0.06347548783822353791148881980667872878998059126103862089665838701205185579592695769871303841009927124}.
NIntegrate obtained 5.111360875219905604641986398088384278637257832232254321100441868877978318265582017097113446297596528100.*^-46
and 2.115650450746176575259758050321352748848126918694539847444939975975907083592875723586821709970659407100.*^-59
for the integral and error estimates. >>


How do I get rid of this error message, without suppressing it?

• Have you ever heard about Quiet?
– mmal
Jul 13, 2016 at 2:28
• @mmal What f I don't know the exact answer? I suppose suppress the error message is dangeous. Jul 13, 2016 at 2:30

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

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.

• Can you explain why this works and why the previous code report an error? The error says failed to converge to prescribed accuracy I assume this means that the AccuracyGoal set by default is very very high(even higher than 35 and 90?)... Jul 13, 2016 at 3:37
• The links says AccuracyGoal->Automatic normally yields an accuracy goal equal to half the setting for WorkingPrecision. . I suppose when I unspecify the AccuracyGoal, it is set to 25, but why it can't converge but can when it set explicitly to 35 Jul 13, 2016 at 3:52
• I didn't find it explicitly says only true for NDSolve Jul 13, 2016 at 3:55
• We are not talking about the same link... You are right, maybe the default value in NIntegrate is the WorkingPrecision. Jul 13, 2016 at 4:01
• The link in your first sentence...Click on details, it doesn't says this is true only for NDSolve.. Jul 13, 2016 at 4:08

The shortest and best way between two truths of the real domain often passes through the imaginary one.

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.

• This is a very smart way! Jul 13, 2016 at 8:49
• Pfft! Using brute force is better! May 24, 2020 at 0:43
• @Anton, sometimes ;D May 24, 2020 at 0:46

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} *)


Another brute-force approach, but quick:

NIntegrate[Exp[-x^2] Cos[100 x],
Evaluate@Flatten@{x, Range[-10., 10, 2 Pi/100], 10.},
Method -> {"GaussKronrodRule", "Points" -> 31}, MaxRecursion -> 0,
PrecisionGoal -> 25, WorkingPrecision -> 100] //
N[#, 50] & // AbsoluteTiming

(*  {0.231645, 5.1113608752199029964130704417588237931064000955614*10^-46}  *)