# How to deal with highly oscillatory integrand when using "NIntegrate" and have a precise result

FTw][n_][w_]:=NIntegrate[ax[n][t]/.sol2]Exp[i w1 t],{t,0,600}]
Plot[Abs[FTw[w1]],{w,1,3}]


Here I'd like to calculate the Fourier transform of a complicated function. I tried to plot it to see its behavior. It can work out the result (although very slow). But there is warning during calculation, saying that

"NIntegrate converges too slowly;suspect one of the following:singularity,value of the integration is 0, highly oscillatory integrand, or WorkingPrecision too small".

After calculation is done, it says

The global error of the strategy GlobalAdaptive has increased more than 400 times. The global error is expected to decrease monotonically after a number of integrand evaluations. Suspect one of the following: the working precision is insufficient for the specified precision goal; the integrand is highly oscillatory or it is not a (piecewise) smooth function; or the true value of the integral is 0. Increasing the value of the GlobalAdaptive option MaxErrorIncreases might lead to a convergent numerical integration.

Here the original functionax[n][t]/.sol2 is a group of numerical solutions of some complicated ODEs solved by "NDSolve" function. (n=1,2,3...)

I also plot the integrand (ax[t]/.sol2 Exp[i w1 t]) choosing w1=0.4\Pi. It can be seen that it is really very oscillatory(I plot it again using different w1,and the general behavior of the curve is the same: highly oscillatroy).

So how can I deal with the problem to get a more precise result and get rid of the warning. I know it is a problem of working precision, but I am quite unfamiliar with Mathematica so I really don't know how to set the precision to have a satisfactory result.

If anyone can help, I'd appreciate it very much. And I can provide more information if you want.

(P.S. My original ODEs are really really long(it contains more than 100 equations),so I don't show it here. I think judging from the behavior of the curve someone can have a solution)

• Aug 10 '17 at 19:25
• "InterpolationPointsSubdivision" might help, too. Aug 10 '17 at 19:29
• Thank you Micheal, I am dealing with the Fourier transform of a interpolating function, but I encountered a different problem as that guy did.
– Fred
Aug 10 '17 at 19:33
• My problem is the integrand oscillates too fast so that I need to set precision goal manually(I guess) but I don't know how to do it.
– Fred
Aug 10 '17 at 19:35
• If you scrape-n-paste your code from the screen above into Mathematica it will show you mismatched brackets, ax isn't defined, sol2 isn't defined, all of which makes it difficult or impossible for anyone to reproduce your problem and test possible fixes. If you look in reference.wolfram.com/language/ref/NIntegrate.html and you click on the orange "Options" and then the orange "WorkingPrecision" or "PrecisionGoal" or "AccuracyGoal" it will show how to use those. If you are going to increase those then you need to avoid any numbers with decimal points that will limit your precision.
– Bill
Aug 10 '17 at 19:50

This has similar oscillatory characteristics as the OP's and can be integrated (after a couple of minutes) with "InterpolationPointsSubdivision":

ifn = NDSolveValue[
{y'[x] + (1/2 + 2 Sin[10 x]) y[x] == Exp[-Sin[x/100]^2], y == 10},
y, {x, 0, 500}]

ListLinePlot@ifn Length[ifn@"Grid"]
(*  34655  *)

NIntegrate[ifn[x] Exp[10 I x], {x, 0, 500},
Method -> {"InterpolationPointsSubdivision",
"MaxSubregions" -> Length[ifn@"Grid"]}]
(*  65.1942 - 2.30904 I  *)


As far as can be inferred from the current statement of the problem, I don't see why this wouldn't work.

The method referred to in my first comment, and also it turns out found in this earlier Q&A, works on this example. This gives the same answer as above:

NIntegrate[ifn[x] Exp[10 I x], {x, 0, 500}, Method -> "LevinRule"]


Actually, it's must faster and might be preferred for that reason.

• Aug 10 '17 at 23:25