Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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.

share|improve this question
4  
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. –  J. M. Oct 12 '12 at 8:32
1  
@fpghost You can include the information you gave in the comment into your question. So it is seen by everyone on the first glance. –  halirutan Oct 12 '12 at 8:54
    
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. –  Andrew Moylan Oct 13 '12 at 19:47
    
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". –  Andrew Moylan Oct 13 '12 at 23:18
    
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 –  fpghost Oct 15 '12 at 7:22
add comment

1 Answer

up vote 3 down vote accepted

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.

share|improve this answer
    
why is it that if I put WorkingPrecision>40, AccuracyGoal->32 then one answer I get is -0.0736391861287610417303399059351591806809983958+0.1003354146233646690778729639‌​25606417744119066 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. –  fpghost Oct 13 '12 at 7:38
    
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). –  Andrew Moylan Oct 13 '12 at 17:30
    
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. –  Andrew Moylan Oct 13 '12 at 17:31
    
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 –  fpghost Oct 13 '12 at 20:52
2  
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. –  Andrew Moylan Oct 14 '12 at 15:00
show 6 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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