2
$\begingroup$

I have defined a function $\phi(x,p_z)$ as the integral of another function via NIntegrate:

$$\phi(x,p_z)=\int_{-\infty}^{\infty}f_{\text{int,1}}(x,p_z;k_p)\,dk_p$$

My function is supposed to evaluate numerically, but instead it's evaluating symbolically, which naturally means I have made a mistake somewhere. I have made sure to include ?NumericQ in the arguments of the integrand definition, and have cleared all previous function definitions. Every minimal working example I try to construct ends up evaluating numerically like it's supposed to.

What's going on here? Is there something wrong going on with my function names?


ClearAll[M02, c, RZeros, kplus, kminus, kbplus, kbminus];
M02 = 0.1;
c = 1.2;
RZeros = y /. NSolve[y (1 - c y)^2 == M02, y, Reals];

kplus[x_, pz_, kp_, i_] := -x*pz + Sqrt[RZeros[[i]] + kp + (x*pz)^2];
kminus[x_, pz_, kp_, i_] := -x*pz - 
   Sqrt[RZeros[[i]] + kp + (x*pz)^2];
kbplus[x_, pz_, kp_, i_] := (1. - x)*pz + 
   Sqrt[RZeros[[i]] + kp + ((1. - x)*pz)^2];
kbminus[x_, pz_, kp_, i_] := (1. - x)*pz - 
   Sqrt[RZeros[[i]] + kp + ((1. - x)*pz)^2];

ClearAll[ybar1, BranchModifier1, N11, N12, D11, D12, D13, fint1];

ybar1[x_, pz_, kp_, i_] := RZeros[[i]] - 2.*pz*kplus[x, pz, kp, i];
BranchModifier1 = {-1, -1, I};
N11[x_, pz_, kp_, i_] := 
  BranchModifier1[[i]]*
   Sqrt[Abs[(1. - c*RZeros[[i]])*(1. - c*ybar1[x, pz, kp, i])]];
N12[x_, pz_, kp_, i_] := 
  1. - c*((1. - x)*ybar1[x, pz, kp, i] + x*RZeros[[i]]);
D11[x_, pz_, kp_, i_] := 
  Product[If[j != i, kplus[x, pz, kp, i] - kplus[x, pz, kp, j], 
    1.], {j, 1, Length[RZeros]}];
D12[x_, pz_, kp_, i_] := 
  Product[kplus[x, pz, kp, i] - kminus[x, pz, kp, j], {j, 1, 
    Length[RZeros]}];
D13[x_, pz_, kp_, i_] := 
  ybar1[x, pz, kp, i]*(1. - c*ybar1[x, pz, kp, i])^2 - M02;
fint1[x_?NumericQ, pz_?NumericQ, kp_?NumericQ] := 
  Sum[(N11[x, pz, kp, i] N12[x, pz, kp, i])/(
   D11[x, pz, kp, i] D12[x, pz, kp, i] D13[x, pz, kp, i]), {i, 1, 
    Length[RZeros]}];

ClearAll[phi];

phi[x_, pz_] := 
  NIntegrate[fint1[x, pz, kp], {kp, 0, \[Infinity]}, 
   MaxRecursion -> 40];

phi[0.6, 5]  (* should evaluate numerically! *)
NIntegrate[fint1[0.60000000000000000000, 5, kp], {kp, 0, \[Infinity]},
  MaxRecursion -> 40]

[Edit: Partially Solved]

I just solved my problem, but don't understand why what I did solved my problem.

My integral was to be defined over the range $(-\infty,+\infty)$, but I accidentally defined it in MMA as being over $(0,+\infty)$. Changing this allowed my integral to be evaluated numerically.

Similarly, changing the bounds of integration to $(a,b)$, where $a$ and $b$ are finite numbers, also allows my integral to be evaluated numerically.

Why is it that $(0,+\infty)$ does not evaluate numerically?


[Edit 2: Take Back my Previous "Solution"]

I take back the supposed "solution" in my previous edit. The integral is supposed to be from $0$ to $+\infty$ only.

$\endgroup$
  • $\begingroup$ BranchModifier is not defined. You probably meant to use BranchModifier1. $\endgroup$ – Anton Antonov Jul 4 '18 at 19:56
  • $\begingroup$ @AntonAntonov Ah, woops, I had actually defined BranchModifier identically in another notebook so fixing that doesn't change anything. See my most recent edit (bottom) $\endgroup$ – Arturo don Juan Jul 4 '18 at 20:07
5
$\begingroup$

Why is it that (0,+∞) does not evaluate numerically?

Let us redefine phi to take options as:

ClearAll[phi];
phi[x_, pz_, opts : OptionsPattern[]] := 
  NIntegrate[fint1[x, pz, kp], {kp, 0, Infinity}, opts, MaxRecursion -> 40];

Calling phi with no options (as in the question) produces "NIntegrate::inumri":

phi[0.6, 5]  (*should evaluate numerically!*)

During evaluation of In[52]:= NIntegrate::inumri: The integrand fint1[0.6,5,kp] has evaluated to Overflow, Indeterminate, or Infinity for all sampling points in the region with boundaries {{0.,3.67005*10^28}}.

(* NIntegrate[fint1[0.6, 5, kp], {kp, 0, \[Infinity]}, MaxRecursion -> 40] *)

Since the integral is calculated to infinity this message prompts that the singularity handler is responsible. So, we can do a few things like:

  • compute the integral without singularity handling and with smaller precision goal, or

  • use a different singularity handler.

Here are some example calls:

phi[0.6, 5, 
 Method -> {"GlobalAdaptive", "SingularityHandler" -> None}, 
 PrecisionGoal -> 4]

(* 0.200486 - 0.0614598 I *)

phi[0.6, 5, 
 Method -> {"GlobalAdaptive", 
   "SingularityHandler" -> "DoubleExponential"}, PrecisionGoal -> 7]

(* 0.200478 - 0.0614822 I *)
$\endgroup$
  • $\begingroup$ Thanks for the response. This is really odd though because (a) the integrand is very well behaved for $k_p>0$ and (b) the answer in the end is finite. Would you have any guesses for why MMA isn't automatically handling whatever errors it's having with the integral? I ask this because your first example call seems to not really be changing much, and yet it does. $\endgroup$ – Arturo don Juan Jul 4 '18 at 20:47
  • $\begingroup$ Well it can be shown following the code for the IMT variable transformation in the reference documentation I linked in my answer that the IMT transformations together with the [0,1) -> [0,Infinity] transformation produce infinite values for the integrant. In the code I suggested I just prevented the application of IMT. $\endgroup$ – Anton Antonov Jul 5 '18 at 12:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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