NIntegrate
can spend a distressing amount of time trying to simplify the integrand symbolically if you allow it. In some cases, like this one, it is significantly faster to simply force it to treat it as a black-box numeric function by defining the function to only take numeric arguments. For direct comparison, here is the original definition of the function with AbsoluteTiming
stuck on the end:
Clear[Cef2];
Cef2[b1_, b2_, x_, y_, r_] =
E^(-r - E^-r Cosh[
r (x^2 + y^2)]) ((E^(x y E^(-2 r)) Sin[(y b1 + x b2)] +
E^(x y) Cos[(y b1 - x b2)]));
NIntegrate[
Cef2[0.1243, 1.1321, x, y, 2.51], {x, 0, Infinity}, {y, 0,
Infinity}] // AbsoluteTiming
{121.665, 0.103711}
This takes 122 seconds and finds the result to be 0.103711 (though it does throw a few warnings out that the integral is converging slowly).
Redefining the function to use ?NumericQ
(and :=
instead of =
, as that can cause some unexpected issues):
Clear[Cef2];
Cef2[b1_?NumericQ, b2_?NumericQ, x_?NumericQ, y_?NumericQ,
r_?NumericQ] :=
E^(-r - E^-r Cosh[
r (x^2 + y^2)]) ((E^(x y E^(-2 r)) Sin[(y b1 + x b2)] +
E^(x y) Cos[(y b1 - x b2)]));
NIntegrate[
Cef2[0.1243, 1.1321, x, y, 2.51], {x, 0, Infinity}, {y, 0,
Infinity}] // AbsoluteTiming
{0.0916949, 0.103711}
This takes less than a tenth of a second to achieve the same result, though it still complains about the convergence rate being slow.
For the final result I care to have a precision of at most 10^-5, can this be useful to make it even faster?
Yes, you can use this piece of information to make this integral even faster. Just add PrecisionGoal -> 4
to the NIntegrate
. This tells NIntegrate
that you only need 4 digits of precision (covering $10^{-1}$ through $10^{-4}$ and then the $10^{-5}$ digit is a matter of luck).
This provides another roughly 50% speedup (0.0532 seconds compared to the above 0.092), though the evaluation times are small enough already that this isn't going to be a reliable or consistent measure of that.