编写集成高斯函数的Python函数的最佳方法是什么?

编写集成高斯函数的Python函数的最佳方法是什么?,python,scipy,gaussian,integral,Python,Scipy,Gaussian,Integral,在尝试使用scipy的quad方法对高斯进行积分时(假设有一种高斯方法,名为gauss),我遇到了将所需参数传递给gauss并让quad对正确的变量进行积分的问题。有没有人有一个很好的例子来说明如何使用多维函数 但这让我想到了一个更重要的问题,关于积分高斯函数的最佳方法。我没有在scipy中找到高斯积分(令我惊讶)。我的计划是编写一个简单的高斯函数并将其传递给quad(或者现在是一个固定宽度的积分器)。你会怎么做 编辑:固定宽度意味着类似trapz的东西,它使用固定的dx来计算曲线下的面积 到目

在尝试使用scipy的quad方法对高斯进行积分时(假设有一种高斯方法,名为gauss),我遇到了将所需参数传递给gauss并让quad对正确的变量进行积分的问题。有没有人有一个很好的例子来说明如何使用多维函数

但这让我想到了一个更重要的问题,关于积分高斯函数的最佳方法。我没有在scipy中找到高斯积分(令我惊讶)。我的计划是编写一个简单的高斯函数并将其传递给quad(或者现在是一个固定宽度的积分器)。你会怎么做

编辑:固定宽度意味着类似trapz的东西,它使用固定的dx来计算曲线下的面积

到目前为止,我得到的是一个方法make__________________________gauss,它返回一个lambda函数,然后可以进入四元函数。通过这种方式,我可以在积分之前,用我需要的平均值和方差生成一个正态函数

def make_gauss(N, sigma, mu):
    return (lambda x: N/(sigma * (2*numpy.pi)**.5) *
            numpy.e ** (-(x-mu)**2/(2 * sigma**2)))

quad(make_gauss(N=10, sigma=2, mu=0), -inf, inf)
当我尝试传递一个通用的高斯函数(需要用x、N、mu和sigma调用)并使用类quad填充一些值时

quad(gen_gauss, -inf, inf, (10,2,0))
参数10、2和0不一定与N=10、sigma=2、mu=0匹配,这促使定义更加扩展


scipy.special中的erf(z)要求我精确定义t最初是什么,但知道它在那里很好。

为什么不总是从-infinity到+infinity进行积分,以便总是知道答案?(开玩笑!)

我的猜测是,SciPy中还没有屏蔽高斯函数的唯一原因是它是一个很容易编写的函数。您关于编写自己的函数并将其传递给quad以集成的建议听起来很棒。它使用公认的SciPy工具来实现这一点,对您来说代码工作量很小,而且对于其他人来说非常可读,即使他们从未见过SciPy

你所说的固定宽度积分器到底是什么意思?你的意思是使用与QUADPACK不同的算法吗

编辑:为了完整性,这里有一些类似于我尝试的高斯分布,平均值为0,标准偏差为1,从0到+无穷大:

from scipy.integrate import quad
from math import pi, exp
mean = 0
sd   = 1
quad(lambda x: 1 / ( sd * ( 2 * pi ) ** 0.5 ) * exp( x ** 2 / (-2 * sd ** 2) ), 0, inf )

这有点难看,因为高斯函数有点长,但写起来仍然很简单

我假设你在处理多元高斯函数;如果是这样的话,SciPy已经有了你想要的功能:它被称为MVNDIST(“多元正态分布”)。SciPy文档和以往一样糟糕,所以我甚至找不到函数的埋藏位置,但是。文档很容易是SciPy最糟糕的部分,过去让我失望不已

单变量高斯函数只是使用了旧的错误函数,其中有许多实现

至于一般地解决这个问题,是的,正如James Thompson所提到的,您只需要编写您自己的高斯分布函数并将其提供给quad()。但是,如果您可以避免广义积分,那么这样做是一个好主意——针对特定函数的专门积分技术(如MVNDIST使用)将比标准的蒙特卡罗多维积分要快得多,而标准的蒙特卡罗多维积分对于高精度来说可能非常缓慢。

scipy附带了“误差函数”,即高斯积分:

import scipy.special
help(scipy.special.erf)

好吧,你似乎对一些事情很困惑。让我们从一开始开始:你提到了一个“多维函数”,但接着讨论了通常的单变量高斯曲线。这不是一个多维函数:当你积分它时,你只积分一个变量(x)这种区别很重要,因为有一种叫做“多元高斯分布”的怪物,它是一种真正的多维函数,如果进行积分,需要对两个或多个变量进行积分(使用我前面提到的昂贵的蒙特卡罗技术).但你似乎只是在谈论规则的单变量高斯分布,它更容易处理,更容易积分,等等

单变量高斯分布有两个参数,
sigma
mu
,是单个变量的函数,我们将表示
x
。您似乎还携带了一个归一化参数
n
(这在一些应用中很有用)。标准化参数通常不包括在计算中,因为您可以在最后将其重新固定(请记住,积分是一个线性运算符:
int(n*f(x),x)=n*int(f(x),x)
)。但如果您愿意,我们可以随身携带;我喜欢的正态分布表示法是

N(x-mu,sigma,N):=(N/(sigma*sqrt(2*pi))*exp(((x-mu)^2)/(2*sigma^2))

(将其理解为“给定的
x
的正态分布
sigma
mu
,以及
n
由…)到目前为止,一切正常;这与您得到的函数相匹配。请注意,这里唯一的真实变量是
x
:其他三个参数对于任何特定的高斯函数都是固定的

现在来看一个数学事实:所有高斯曲线的形状都是相同的,这是可以证明的,它们只是稍微移动了一点。因此我们可以使用称为“标准正态分布”的
N(x | 0,1,1)
,然后将我们的结果转换回一般的高斯曲线。如果你有
N(x | 0,1,1)的积分
,你可以简单地计算任意高斯函数的积分。这个积分出现得如此频繁,以至于它有一个特殊的名字:误差函数
erf
。由于一些旧的约定,它不完全是
erf
;还有一些加法和乘法因子

如果φ(z)=积分(N(x | 0,1,1),-inf,z);也就是说,
φ(z)
是从负无穷大到
z
的标准正态分布的积分,那么根据误差f的定义,它是真的
def make_gauss(N, sigma, mu):
    k = N / (sigma * math.sqrt(2*math.pi))
    s = -1.0 / (2 * sigma * sigma)
    def f(x):
        return k * math.exp(s * (x - mu)*(x - mu))
    return f
from scipy.stats import norm
print norm.cdf(0.0)
>>>0.5