1
$\begingroup$

I am trying to numerically evaluate an integral whose integrand depends on two parameters, say $(a,b)$ and when $b\gg 1$ I suspect (although it's not guaranteed) that the integrand is very small. Thus when $b\gg 1$ and I try to evaluate the integral Mathematica throws up NIntegrate::slwcon errors suggesting it's either zero, rapidly oscillating or I need to increase precision. How can I get around this error to produce an actual result, even if it's $\approx 10^{-6}$?

Some info on integrand
The integrand looks like $\exp(-ix)\,W(x)$, where $x$ is the integration variable. $W(x)$ is a function that I only know numerically. I compute it by using NDSolve to solve a second order ODE (specifically the radial part of the Klein-Gordon equation in Schwarzschild as given by eq (4) of this paper) to get modes $u_i$ (which are oscillatory waves), then I roughly hit them with their cc $u_i u_i^*$ and sum them up to get $W$.

I did some plots of the integrand and it is indeed oscillatory. Especially at large $b$ where it is super oscillatory.

$\endgroup$
5
  • 4
    $\begingroup$ It's hard to give advice you can use if you won't mention the particular integral you're having trouble with. A strategy that would work for, say, principal value integrals won't apply to finite oscillatory integrals. $\endgroup$ Commented Oct 12, 2012 at 8:32
  • 1
    $\begingroup$ @fpghost You can include the information you gave in the comment into your question. So it is seen by everyone on the first glance. $\endgroup$
    – halirutan
    Commented Oct 12, 2012 at 8:54
  • $\begingroup$ You mentioned that you use NDSolve to compute part of the integrand. Make sure the relative or absolute precision of the NDSolve result is several digits higher than the relative or absolute precision you'll try to get from NIntegrate. $\endgroup$ Commented Oct 13, 2012 at 19:47
  • $\begingroup$ Since your integrand has oscillatory form f(x)*exp(g(x)), it's possible that special methods for oscillatory integrals are being selected. You can try disabling them: Method -> "GaussKronrodRule". Or you can try explicitly using some of them: Method -> "LevinRule". $\endgroup$ Commented Oct 13, 2012 at 23:18
  • $\begingroup$ Not sure I follow the logic of why it would be a good idea to disable methods for oscillatory integrands if that's what mine is? are there any others like "LevinRule" that are particularly good for rapidly oscillatory integrands? thanks $\endgroup$
    – fpghost
    Commented Oct 15, 2012 at 7:22

1 Answer 1

6
$\begingroup$

It sounds like you would be happy with an answer within an absolute precision of 10^-6, so the first thing to try is to add AccuracyGoal -> 6:

In[1]:= f[a_, x_] /; NumberQ[x] := Sin[a x]

In[2]:= NIntegrate[f[10^5, x], {x, 0, Pi}]

During evaluation of In[2]:= 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[2]:= NIntegrate::ncvb: NIntegrate failed to converge to prescribed accuracy after 9 recursive bisections in x near {x} = {2.19661}. NIntegrate obtained 0.004548856283494872` and 0.0017787902702028312` for the integral and error estimates. >>

Out[2]= 0.00454886

In[3]:= NIntegrate[f[10^5, x], {x, 0, Pi}, AccuracyGoal -> 6]

Out[3]= -1.31929*10^-11

(By default NIntegrate seeks relative precision 10^-6, and is never satisified with any specific absolute precision.)

Without seeing your integrand it's hard to say more.

$\endgroup$
11
  • 1
    $\begingroup$ why is it that if I put WorkingPrecision>40, AccuracyGoal->32 then one answer I get is -0.0736391861287610417303399059351591806809983958+0.100335414623364669077872963925606417744119066 I, but if I put WorkingPrecision>20, AccuracyGoal->12 then I get 0.073639030286222496511+0.10033572855937423011 I.I thought AccuralGoal->12 would still mean 12 digits accurate? whereas these disagree on 6th dp. $\endgroup$
    – fpghost
    Commented Oct 13, 2012 at 7:38
  • 1
    $\begingroup$ This may be because you still have the default PrecisionGoal. Use an explicit setting for PrecisionGoal. You can use PrecisionGoal -> Infinity to specify that no relative precision is enough to trigger convergence (i.e., to only use AcccuracyGoal). $\endgroup$ Commented Oct 13, 2012 at 17:30
  • $\begingroup$ Again, it is hard to debug without your original function. But another common problem that can arise is that your integrand stops looking continuous on very small scales. This can happen when you are using some numerical procedure of your own to calculate it. $\endgroup$ Commented Oct 13, 2012 at 17:31
  • $\begingroup$ Isn't the default PrecisionGoal set to the half the Working Precision though? It seems a very difficult thing to estimate what PrecisionGoal, AccuracyGoal, and WorkingPrecision one needs if one wants an answer with a certain error. I know with Precision p and Accuracy a, the error is supposed to be less than err=10^-a+|x|10^-p , giving x-err/2<x<x+err/2, but NDSolve never really seems to achieve this goal in the final result. As you say true digits seem to be far less than one would expect if these goals were really fulfilled, so it seems almost a guessing game to know how to pick these goals $\endgroup$
    – fpghost
    Commented Oct 13, 2012 at 20:52
  • 3
    $\begingroup$ For PrecisionGoal and AccuracyGoal, you should choose values corresponding to the precision/accuracy required in your application ... For WorkingPrecision, there is no really surefire way to choose, but I'll suggest starting by adding 10 to the larger of PrecisionGoal and AccuracyGoal. Make sure the precision of your integrand (i.e. it's PrecisionGoal) is at least as large as the WorkingPrecision of your NIntegrate. $\endgroup$ Commented Oct 14, 2012 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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