We have a 5-dimensional integral arising as a solution to a physics problem, where two dimensions of the integration space cover the spherical and azimuthal angle, and three dimensions are needed to account for Gaussians in three Cartesian directions.
We are using Mathematica's NIntegrate with "GlobalAdaptive", which seems the only way to get any sensible values. The Boolean constraint below is mandatory (we have also tried Heaviside), and we have stripped the physical constants from the expressions below to focus on the problem. Numerically speaking, the problem is that the integrand has a complicated functional dependence (determined by the physics), and the volume of the integration space is very large.
With the settings below, by stepwise increasing the integration limits for the Gaussians, we are able to (probably) reach convergence, but the calculation throws warnings and completely fails for i = 5 (corresponding to five standard deviations from the mean) – before crashing, Mathematica uses 75 GB of memory on a very powerful desktop workstation.
Are there any ways to improve convergence and computational efficiency of the integral below? We need reliable integral values for MANY input parameters, and in the real physical situation the integration is even significantly slower than in this simplified example.
Many thanks!
beta[u_] := Sqrt[1 - 1/(u + 1)^2];
(*integrand*)
sigma[theta_, u_] := (1 - beta[u]^2) /
beta[u]^4*(Csc[theta/2])^4*(1 - beta[u]^2*Sin[theta/2]^2 +
beta[u]*Sin[theta/2] (1 - Sin[theta/2]));
(*gaussian distributions*)
gauss[v_, sig_] := 1/(sig*Sqrt[2*Pi])*Exp[-v^2/(2*sig)];
(*function for the boole*)
Tmax[vx_, vy_, vz_, U_, phi_,
theta_] := (1/2)*(vx^2 + vy^2 + vz^2) + (1 -
Cos[theta])*(Sqrt[U*(U + 2)] + vz)*Sqrt[U*(U + 2)] -
Sqrt[U*(U + 2)]*Sin[theta]*(vx*Cos[phi] + vy*Sin[phi])
(*integral*)
fivedim[u_, i_] :=
AbsoluteTiming[
NIntegrate[
Boole[Tmax[cx, cy, cz, u, phi, theta] >= 15]*sigma[theta, u]*
Sin[theta]*gauss[cx, 1]*gauss[cy, 1]*gauss[cz, 1], {theta, 0,
Pi}, {phi, 0, 2 Pi}, {cx, -i, i}, {cy, -i, i}, {cz, -i, i},
Method -> {"GlobalAdaptive"}]]
(*calculate integral to estimate convergence limit*)
limit = {1, 2, 3, 4};
values = {};
For[i = 1, i <= Length[limit], i++,
values = Append[values, fivedim[100000, i]]]
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.
NIntegrate::eincr: The global error of the strategy GlobalAdaptive has increased more than 2000 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. NIntegrate obtained 0.5581961194518056` and 0.009589824655407775` for the integral and error estimates.
General::stop: Further output of NIntegrate::eincr will be suppressed during this calculation.
We can see from the results that the value of the integral does not fully converge (see {time [s], integral value} values below).
In[97]:= values
Out[97]= {{8.81786, 0.558196}, {32.2968, 1.64615}, {7.84894,
2.00055}, {10.6271, 2.02892}}
```
Append
is inefficient, you can just useArray
orTable
, also you repeatedly calculate the same expressions, you could useWith
to speed this up. Even so it still has the same issues. See my suggestions here pastebin.com/xFuTpp9f esp.With
, but I don't think there's much you can do. $\endgroup$fivedim[u_, i_] := AbsoluteTiming[ NIntegrate[ Boole[Tmax[cx, cy, cz, u, phi, theta] >= 15]*sigma[theta, u]* Sin[theta]*gauss[cx, 1]*gauss[cy, 1]*gauss[cz, 1], {theta, 0, Pi}, {phi, 0, 2 Pi}, {cx, -i, i}, {cy, -i, i}, {cz, -i, i}, Method -> {"LocalAdaptive"}, AccuracyGoal -> 6, PrecisionGoal -> 6]]; Table[fivedim[100000, i], {i, 1, 5}]
, I obtain{{5.06368, 1.60554*10^-6}, {5.0857, 0.0000155633}, {6.33888, 0.000208747}, {7.89441, 0.000525671}, {5.09002, 1.58715*10^-6}}
. ` $\endgroup$fivedim[u_, i_] := AbsoluteTiming[ NIntegrate[ Boole[Tmax[cx, cy, cz, u, phi, theta] >= 15]*sigma[theta, u]* Sin[theta]*gauss[cx, 1]*gauss[cy, 1]*gauss[cz, 1], {theta, 0, Pi}, {phi, 0, 2 Pi}, {cx, -i, i}, {cy, -i, i}, {cz, -i, i}, Method -> {"MonteCarlo"}, AccuracyGoal -> 3, PrecisionGoal -> 3]];Table[fivedim[100000, i], {i, 1, 5}]
, I obtain{{0.0068733, 5.8473*10^-6}, {0.008582, 0.0000275885}, {0.0063151, 0.0000463867}, {0.0068139, 6.62425*10^-7}, {0.0099911, 1.76042*10^-7}}
. I thinkMethod->"GlobalAdaptive"
is not a proper method here. $\endgroup$Expand[]
over your whole expression to be integrated, then you end up with 20 sumed-terms. If you integrate withi<5
you'll see, that most of them are insignificant, and there are often pairwise effectively canceling terms. Only one single term does actually contribute to the first 3-4 significant digits. So one could concentrate on just using this single term. However, thats an empirical result. $\endgroup$