使用scipy积分tplquad来评估多元高斯的三重积分

时间:2013-11-21 04:29:04

标签: python scipy gaussian integrate

我正在尝试执行以下三重积分:

3d gaussian equation

f(v)是3变量高斯概率密度函数。

合成速度V的大小必须小于某个Vmax(因此Vx,Vy和Vz各自的范围可以从0或-Vmax到+ Vmax,但如果Vx = Vmax则Vy和Vz必须为零,例如)。

现在我们可以使用sigma = 1.我现在也会忽略积分内的除法,所以我只是整合了f(v)。

我一直在尝试使用scipy.integrate tplquad函数,但仍然得到一个数量级为1e-7的答案,并且提供的Vmax足够大(我使用Vmax = 500)积分应接近因为所有(速度)空间的概率都是1。

这是我的代码:

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])

输出:

>>> (executing cell "Triple integral a..." (line 15 of "Integral4.py"))
1.4644282619462532e-07
>>>

Vymax和Vzmax功能是将Vy和Vz值保持在范围内,以使合成速度不超过Vmax。我在tplquad中使用lambda函数为0,因为tplquad需要一个函数作为第4个参数的输入。

我无法看到我出错的地方,但我确信我一定会错过一些简单或完全愚蠢的事情。

如果tplquad不是这个问题的正确功能,还有替代方案吗?我甚至乐于编写自己的函数,但我不确定最好的方法是什么 - 我尝试了蒙特卡罗方法,但无法弄明白。我不能单独分离组件,因为最终我需要一个偏移Vx + Voffset,因此它不再以原点为中心。我尽可能多地在这里搜索并遇到this,但它没有正确描述如何进行多变量高斯,因为问题是(意味着)关于单变量高斯。

任何帮助都非常感激。

感谢。

1 个答案:

答案 0 :(得分:2)

multivariate normal distribution的公式不正确。在指数系数的幂中,sqrt调用,的因子为1/2。您在指数中也缺少1 / sigma ** 2因子。

以下是修改后的版本,使用sigma的方式与问题中显示的公式相符:

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 )

添加print语句以打印sigma的值后,我得到:

In [28]: run tplquad_question.py
sigma = 1
8*integral[0] = 1.00000000196

编辑脚本并再次运行:

In [29]: run tplquad_question.py
sigma = 2.5
8*integral[0] = 1.00000000927

以下是完整的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])