I am trying to calculate some integrals that use very high power exponents. An example equation is:
(-exp(-(x+sqrt(p)).^2)+exp(-(x-sqrt(p)).^2)).^2 ...
./( exp(-(x+sqrt(p)).^2)+exp(-(x-sqrt(p)).^2)) ...
/ (2*sqrt(pi))
where p
is constant (1000 being a typical value), and I need the integral for x=[-inf,inf]. If I use the integral
function for numeric integration I get NaN
as a result. I can avoid that if I set the limits of the integration to something like [-20,20] and a low p
(<100), but ideally I need the full range.
I have also tried setting syms x
and using int
and vpa
, but in this case vpa
returns:
1.0 - 1.0*numeric::int((1125899906842624*(exp(-(x - 10*10^(1/2))^2) - exp(-(x + 10*10^(1/2))^2))^2)/(3991211251234741*(exp(-(x - 10*10^(1/2))^2) + exp(-(x + 10*10^(1/2))^2)))
without calculating a value. Again, if I set the limits of the integration to lower values I do get a result (also for low p
), but I know that the result that I get is wrong – e.g., if x=[-100,100] and p=1000, the result is >1, which should be wrong as the equation should be asymptotic to 1 (or alternatively the codomain should be [0,1) ).
Am I doing something wrong with vpa
or is there another way to calculate high precision values for my integrals?
First, you're doing something that makes solving symbolic problems more difficult and less accurate. The variable
pi
is a floating-point value, not an exact symbolic representation of the fundamental constant. In Matlab symbolic math code, you should always usesym('pi')
. You should do the same for any other special numeric values, e.g.,sqrt(sym('2'))
andexp(sym('1'))
, you use or they will get converted to an approximate rational fraction by default (the source of strange large number you see in the code in your question). For further details, I recommend that you read through the documentation for thesym
function.Applying the above, here's a runnable example:
Now
vpa(int(f,x,-100,100))
andvpa(int(f,x,-1e3,1e3))
return exactly1.0
(to 32 digits of precision, see below).Unfortunately,
vpa(int(f,x,-Inf,Inf))
, does not return an answer, but a call to the underlying MuPAD functionnumeric::int
. As I explain in this answer, this is what can happen whenint
cannot obtain a result. Normally, it should try to evaluate the the integral numerically, but your function appears to be ill-defined at ±∞, resulting in divide by zero issues that the variable precision quadrature methods can't handle well. You can evaluate the integral at wider bounds by increasing the variable precision using thedigits
function (just remember to setdigits
back to the default of 32 when done). Settingdigits(128)
allowed me to evaluatevpa(int(f,x,-1e4,1e4))
. You can also more efficiently evaluate your integral over a wider range via2*vpa(int(f,x,0,1e4))
at lower effective digits settings.If your goal is to see exactly how much less than one
p = 1000
corresponds to, you can use something likevpa(1-2*int(f,x,0,1e4))
. Atdigits(128)
, this returnsApplying
double
to this shows that it is approximately8.6e-89
.