Reputation: 1
I'm trying to perform the following triple integral:
f(v) is a 3 variable Gaussian probability density function.
The magnitude of the resultant velocity, V, must be less than some Vmax (so Vx, Vy, and Vz can each range from 0 or -Vmax to +Vmax, but if Vx = Vmax then Vy and Vz must be zero, for example).
For now we can take sigma = 1. I will ignore the division by v inside the integral for now as well, so I'm just integrating f(v).
I've been trying to use the scipy.integrate tplquad function but keep getting an answer that's of the order of magnitude ~1e-7 and provided Vmax is big enough (I'm using Vmax = 500) the integral should approach 1 since the probability over all (velocity) space is 1.
Here is my code:
from scipy.integrate import tplquad
from numpy import pi, exp, sqrt
def func(Vz,Vy,Vx):
return sqrt( (1/(sigma*2*pi)**(3/2)) ) * exp( - ( ((Vx**2)/2) + ((Vy**2)/2) + ((Vz**2)/2) ) )
def Vymax(Vx):
return sqrt(Vmax**2 - Vx**2)
def Vzmax(Vx,Vy):
return sqrt(Vmax**2 - Vx**2 - Vy**2)
Vmax = 500
sigma = 1
integral = tplquad(func,0,Vmax,lambda a: 0, Vymax,lambda a, y: 0, Vzmax)
print(8*integral[0])
Output:
>>> (executing cell "Triple integral a..." (line 15 of "Integral4.py"))
1.4644282619462532e-07
>>>
The Vymax and Vzmax functions are to keep Vy and Vz values within ranges so that the resultant velocity doesn't exceed Vmax. I've used lambda functions in tplquad for 0 because tplquad requires a function as input for the 4th parameters onwards.
I can't see where I've gone wrong but I'm sure I must be missing something simple or being completely stupid.
If tplquad isn't the right function for this problem, is there an alternative? I'm even happy to write my own function but am unsure what the best method would be - I tried a Monte Carlo method but couldn't quite figure it out. I can't just separate out the components because eventually I need to have an offset Vx + Voffset so it'll no longer be centred on the origin. I've searched on here as much as I could and came across this but it doesn't describe properly how to do a multivariate Gaussian, since the question was (meant to be) about a single variable Gaussian.
Any help much appreciated.
Upvotes: 0
Views: 2944
Reputation: 114811
Your formula for the multivariate normal distribution is not correct. You have both the sqrt
call, and the factor of 1/2 in the power in the coefficient of the exponential. You are also missing the factor of 1/sigma**2 in the exponent.
Here's a modified version, using sigma
in a way that matches the formula shown in the question:
def func(Vz,Vy,Vx):
return (1.0/(sigma**2*2*pi)**(3./2)) * exp( - ( ((Vx**2)/2) + ((Vy**2)/2) + ((Vz**2)/2) )/sigma**2 )
After adding a print statement to print the value of sigma
, I get:
In [28]: run tplquad_question.py
sigma = 1
8*integral[0] = 1.00000000196
Edit the script and run again:
In [29]: run tplquad_question.py
sigma = 2.5
8*integral[0] = 1.00000000927
Here's the complete tplquad_question.py
:
from __future__ import print_function, division
from scipy.integrate import tplquad
from numpy import pi, exp, sqrt
def func(Vz,Vy,Vx):
return (1.0/(sigma**2*2*pi)**(3./2)) * exp( - ( ((Vx**2)/2) + ((Vy**2)/2) + ((Vz**2)/2) )/sigma**2 )
def Vymax(Vx):
return sqrt(Vmax**2 - Vx**2)
def Vzmax(Vx,Vy):
return sqrt(Vmax**2 - Vx**2 - Vy**2)
Vmax = 500
sigma = 1
integral = tplquad(func,0,Vmax,lambda a: 0, Vymax,lambda a, y: 0, Vzmax)
print("sigma =", sigma)
print("8*integral[0] =", 8*integral[0])
Upvotes: 2