5
$\begingroup$

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

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

Out[256]= 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[273]:= NIntegrate[Exp[-x^2] Cos[100 x], {x, -10, 10}, 
  Method -> {"LevinRule"}, WorkingPrecision -> 50]

Out[273]= 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[273]:= 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[273]:= NIntegrate::ncvb: NIntegrate failed to converge to
prescribed accuracy after 9 recursive bisections in x near
{x} = {0.06347548783822353791148881980667872878998059126103862089665838701205185579592695769871303841009927124}.
NIntegrate obtained 5.111360875219905604641986398088384278637257832232254321100441868877978318265582017097113446297596528`100.*^-46
and 2.115650450746176575259758050321352748848126918694539847444939975975907083592875723586821709970659407`100.*^-59
for the integral and error estimates. >>

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

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

4 Answers 4

6
$\begingroup$

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.

$\endgroup$
8
  • $\begingroup$ 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?)... $\endgroup$ Jul 13, 2016 at 3:37
  • $\begingroup$ 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 $\endgroup$ Jul 13, 2016 at 3:52
  • $\begingroup$ I didn't find it explicitly says only true for NDSolve $\endgroup$ Jul 13, 2016 at 3:55
  • $\begingroup$ We are not talking about the same link... You are right, maybe the default value in NIntegrate is the WorkingPrecision. $\endgroup$ Jul 13, 2016 at 4:01
  • $\begingroup$ The link in your first sentence...Click on details, it doesn't says this is true only for NDSolve.. $\endgroup$ Jul 13, 2016 at 4:08
12
$\begingroup$

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.

$\endgroup$
3
4
$\begingroup$

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} *)
$\endgroup$
2
$\begingroup$

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}  *)
$\endgroup$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.