Function: intnumosc
Section: sums
C-Name: intnumosc0
Prototype: V=GEGD0,L,DGp
Help: intnumosc(x=a,expr,H,{flag=0},{tab}): numerical integration from a
 to oo of oscillating quasi-periodic function expr of half-period H.
 tab is either omitted (and will be recomputed) or precomputed with
 intnumgaussinit; flag is either 0 (Sidi extrapolation, safe mode), 1 (Sidi
 extrapolation, unsafe mode), 2 (sumalt), 3 (sumnumlagrange), 4 (sumpos).
Doc: numerical integration from $a$ to $\infty$ of oscillating
 quasi-periodic function \var{expr} of half-period $H$, meaning that we
 at least expect the distance between the function's consecutive zeros to be
 close to $H$: the sine or cosine functions ($H = \pi$) are paradigmatic
 examples, but the Bessel $J_{\nu}$ or $Y_{\nu}$ functions ($H = \pi/2$) can
 also be handled. The integral from $a$ to $\infty$ is computed
 by summing the integral between two consecutive multiples of $H$;
 \fl determines the summation algorithm used: either $0$ (Sidi extrapolation,
 safe mode), 1 (Sidi extrapolation, unsafe mode), 2 (\kbd{sumalt}),
 3 (\kbd{sumnumlagrange}) or 4 (\kbd{sumpos}). For the last two modes
 (Lagrange and Sumpos), one should input the period $2H$ instead of the
 half-period $H$.

 The default is $\fl = 0$; Sidi summation should be the most
 robust algorithm; you can try it in unsafe mode when the integrals between
 two consecutive multiples of $H$ form an alternating series, this should be
 about twice faster than the default and not lose accuracy. Sumpos should be
 by far the slowest method, but also very robust and may be able to handle
 integrals where Sidi fails. Sumalt should be fast but often wrong,
 especially when the integrals between two consecutive multiples of $H$
 do not form an alternating series), and Lagrange should be as fast as Sumalt
 but more often wrong.

 When one of the Sidi modes runs into difficulties, it will return the result
 to the accuracy believed to be correct (the other modes do not perform
 extrapolation and do not have this property) :
 \bprog
 ? f(x)=besselj(0,x)^4*log(x+1);
 ? \pb384
 ? intnumosc(x = 0, f(x), Pi)
 %1 = 0.4549032054850867417 \\ fewer digits than expected !
 ? bitprecision(%)
 %2 = 64
 ? \g1 \\ increase debug level to see diagnostics
 ? intnumosc(x = 0, f(x), Pi)
 sumsidi: reached accuracy of 23 bits.
 %2 = 0.4549032054850867417
 @eprog\noindent The algorithm could extrapolate the series to 23 bits of
 accuracy, then diverged. So only the absolute error is likely to be
 around $2^{-23}$ instead of the possible $2^{-64}$ (or the requested
 $2^{-384}$). We'll come back to this example at the end.

 In case of difficulties, you may try to replace the half-(quasi)-period $H$
 by a multiple, such as the quasi-period $2H$: since we do not expect
 alternating behaviour, \kbd{sumalt} mode will almost surely be broken, but
 others may improve, in particular Lagrange or Sumpos.

 \kbd{tab} is either omitted or precomputed with \kbd{intnumgaussinit};
 if using Sidi summation in safe mode ($\fl = 0$) \emph{and} precompute
 \kbd{tab}, you should use a precision roughly 50\% larger than the target
 (this is not necessary for any of the other summations).

 First an alternating example:
 \bprog
 ? \pb384
 \\ Sidi, safe mode
 ? exponent(intnumosc(x=0,sinc(x),Pi) - Pi/2)
 time = 183 ms.
 %1 = -383
 ? exponent(intnumosc(x=0,sinc(x),2*Pi) - Pi/2)
 time = 224 ms.
 %2 = -383 \\ also works with 2H, a little slower

 \\ Sidi, unsafe mode
 ? exponent(intnumosc(x=0,sinc(x),Pi,1) - Pi/2)
 time = 79 ms.
 %3 = -383  \\ alternating: unsafe mode is fine and almost twice faster
 ? exponent(intnumosc(x=0,sinc(x),2*Pi,1) - Pi/2)
 time = 86 ms.
 %4 = -285 \\ but this time 2H loses accuracy

 \\ Sumalt
 ? exponent(intnumosc(x=0,sinc(x),Pi,2) - Pi/2)
 time = 115 ms. \\ sumalt is just as accurate and fast
 %5 = -383
 ? exponent(intnumosc(x=0,sinc(x),2*Pi,2) - Pi/2)
 time = 115 ms.
 %6 = -10 \\ ...but breaks completely with 2H

 \\ Lagrange
 ? exponent(intnumosc(x=0,sinc(x),Pi,2) - Pi/2)
 time = 100 ms. \\ junk
 %7 = 224
 ? exponent(intnumosc(x=0,sinc(x),2*Pi,2) - Pi/2)
 time = 100 ms.
 %8 = -238 \\ ...a little better with 2H

 \\ Sumpos
 ? exponent(intnumosc(x=0,sinc(x),Pi,4) - Pi/2)
 time = 17,961 ms.
 %9 = 7 \\ junk; slow
 ? exponent(intnumosc(x=0,sinc(x),2*Pi,4) - Pi/2)
 time = 19,105 ms.
 %10 = -4 \\ still junk
 @eprog

 Now a non-alternating one:
 \bprog
 ? exponent(intnumosc(x=0,sinc(x)^2,Pi) - Pi/2)
 time = 277 ms.
 %1 = -383 \\ safe mode is still perfect
 ? exponent(intnumosc(x=0,sinc(x)^2,Pi,1) - Pi/2)
 time = 97 ms.
 %2 = -284 \\ non-alternating; this time, Sidi's unsafe mode loses accuracy
 ? exponent(intnumosc(x=0,sinc(x)^2,Pi,2) - Pi/2)
 time = 113 ms.
 %3 = -10 \\ this time sumalt fails completely
 ? exponent(intnumosc(x=0,sinc(x)^2,Pi,3) - Pi/2)
 time = 103 ms.
 %4 = -237 \\ Lagrange loses accuracy (same with 2H = 2*Pi)
 ? exponent(intnumosc(x=0,sinc(x)^2,Pi,4) - Pi/2)
 time = 17,681 ms.
 %4 = -381 \\ and Sumpos is good but slow (perfect with 2H)
 @eprog

 Exemples of a different flavour:
 \bprog
 ? exponent(intnumosc(x = 0, besselj(0,x)*sin(3*x), Pi) - 1/sqrt(8))
 time = 4,615 ms.
 %1 = -385 \\ more expensive but correct
 ? exponent(intnumosc(x = 0, besselj(0,x)*sin(3*x), Pi, 1) - 1/sqrt(8))
 time = 1,424 ms.
 %2 = -279 \\ unsafe mode loses some accuracy (other modes return junk)

 ? S = log(2*Pi)- Euler - 1;
 ? exponent(intnumosc(t=1, (frac(t)/t)^2, 1/2) - S)
 time = 21 ms.
 %4 = -6 \\ junk
 ? exponent(intnumosc(t=1, (frac(t)/t)^2, 1) - S)
 time = 66ms.
 %5 = -384 \\ perfect with 2H
 ? exponent(intnumosc(t=1, (frac(t)/t)^2, 1, 1) - S)
 time = 20 ms.
 %6 = -286 \\ unsafe mode loses accuracy
 ? exponent(intnumosc(t=1, (frac(t)/t)^2, 1, 3) - S)
 time = 30 ms.
 %7 = -236  \\ and so does Lagrange (Sumalt fails)
 ? exponent(intnumosc(t=1, (frac(t)/t)^2, 1, 4) - S)
 time = 2,315 ms.
 %8 = -382 \\ Sumpos is perfect but slow
 @eprog\noindent Again, Sidi extrapolation behaves well, especially in safe
 mode, but $2H$ is required here.

 If the integrand has singularities close to the interval of integration,
 it is advisable to split the integral in two: use the more robust \kbd{intnum}
 to handle the singularities, then \kbd{intnumosc} for the remainder:
 \bprog
 ? \p38
 ? f(x) = besselj(0,x)^3 * log(x); \\ mild singularity at 0
 ? g() = intnumosc(x = 0, f(x), Pi); \\ direct
 ? h() = intnum(x = 0, Pi, f(x)) + intnumosc(x = Pi, f(x), Pi); \\ split at Pi
 ? G = g();
 time = 293 ms.
 ? H = h();
 time = 320 ms. \\ about as fast
 ? exponent(G-H)
 %6 = -12 \\ at least one of them is junk
 ? \p77 \\ increase accuracy
 ? G2=g(); H2=h();
 ? exponent(G - G2)
 %8 = -13  \\ g() is not consistent
 ? exponent(H - H2)
 %9 = -128  \\ not a proof, but h() looks good
 @eprog\noindent Finally, here is an exemple where all methods fail, even
 when splitting the integral, except Sumpos:
 \bprog
 ? \p38
 ? f(x)=besselj(0,x)^4*log(x+1);
 ? F = intnumosc(x=0,f(x), Pi, 4)
 time = 2,437 ms.
 %2 = 0.45489838778971732178155161172638343214
 ? \p76 \\ double accuracy to check
 ? exponent(F - intnumosc(x = 0,f(x), Pi, 4))
 time = 18,817 ms.
 %3 = -122 \\ F was almost perfect
 @eprog
