最好的方式编写一Python功能的集成了一个高斯?
题
在尝试使用这的四方法纳入高斯(可以说有一个高斯的方法叫高斯),我具有的问题通过所需要的参数,高斯,离开四做的一体化过正确的变量。任何人都不会有一个很好的例子如何使用四w/多层面的功能吗?
但这带领我到一个更大问题的最佳方式纳入斯在一般。我没有找到一个高斯将在这(以我吃惊).我的计划是要编写一个简单的高斯功能,并通过它向四(或者现在一个固定的宽度积分).你会怎么做?
编辑:固定宽意义的东西喜欢trapz使用的一个固定dx来计算区域下一个曲线。
什么我来到这么远是一个方法使___高斯,返回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(gen_gauss, -inf, inf, (10,2,0))
的参数10,2,0并不一定相匹配N=10时,西格玛=2,mu=0,这促使更多的扩大定义。
Erf(z)在这.特别会要求我定义究竟是什么t是初步的,但它很高兴知道它是存在的。
解决方案
好吧,你似乎很困惑几件事情。让我们从头开始:你提到了“多维函数”,但随后继续讨论通常的单变量高斯曲线。这是的不的多维功能:当你整合它,你只整合一个变量(X)。这种区别是重要的是要的,因为是的怪物称为“多元高斯分布”,这是一个真正的多维函数,如果整合,需要整合两个或多个变量(使用昂贵的蒙特Carlo技术我之前提到的)。但你似乎只是在谈论常规one-变量高斯,这是很容易的工作,整合,以及所有。
在一变量高斯分布有两个参数,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
;有一对夫妇加法和乘法因素也正在随身携带。
如果Phi(z) = integral(N(x|0,1,1), -inf, z)
;也就是说,Phi(z)
是从负无穷大到z
标准正态分布的积分,然后将它通过
Phi(z) = 0.5 + 0.5 * erf(z / sqrt(2))
。
同样地,如果Phi(z | mu, sigma, n) = integral( N(x|sigma, mu, n), -inf, z)
;也就是说,Phi(z | mu, sigma, n)
是正态分布给定参数mu
,sigma
,和从负无穷大到n
z
的积分,然后将它由误差函数的定义是真的,
Phi(z | mu, sigma, n) = (n/2) * (1 + erf((x - mu) / (sigma * sqrt(2))))
。
看看对正常CDF维基百科文章,如果你想要更多的细节或证明这一事实。
好,这应该是足够的背景说明。回到你(编辑)的职位。你说“在scipy.special的ERF(Z)需要我来定义t是什么开始”。我不知道你这个是什么意思;哪里t
(时间?)进入到这个呢?希望上面的解释已经揭秘的误差函数的一点,它现在更清晰,为什么误差函数是这个职位的合适功能。
您的Python代码是确定的,但我宁愿在拉姆达闭包:
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
使用的闭合使得常量k
和s
的预计算,所以返回的函数WIL升需要在每次它叫时间(如果你正在整合它,这意味着它会被多次调用它可以是重要的)少做工作。另外,我避免使用任何幂运算符**
,这不仅仅是写出来平方慢,并且悬挂鸿沟从内循环,并用乘法代替它。我没有在他们的Python实现看着这一切,但是从我最后一次使用原始的x87汇编调整为纯粹的速度的内部循环,我似乎记得加,减,乘或把每4个CPU周期,分约36,至约200。那是几年前,因此采取与一粒盐这些数字幂;不过,这说明它们的相对复杂性。同时,计算exp(x)
蛮力方式是一个非常糟糕的主意;有写一个良好的执行exp(x)
的,使比一般a**b
风格幂它显著更快,更准确的时候可以采取的技巧。
我从未使用的常量pi和e的numpy的版本;我一直坚持使用普通的旧的数学模块的版本。我不知道为什么你可能更喜欢的任何一个。
我不知道你要什么用quad()
通话。 quad(gen_gauss, -inf, inf, (10,2,0))
应该整合从负无穷大到正无穷大重正化的高斯,并应始终吐出10(你的归一化因子),因为高斯在真正的线整合为1。远离10的任何答案(我不会期望的究竟的10,因为quad()
只是一个近似值,毕竟)意味着什么地方被搞砸了......很难说什么是搞砸了不知道实际的回报值和可能quad()
的内部工作。
希望已经揭秘了一些困惑,并解释了为什么误差函数是正确的答案,您的问题,以及如何,如果你好奇,自己做这一切。如果我的任何解释不清楚,我建议采取快速看一下维基百科第一;如果您还有疑问,请不要犹豫,问。
其他提示
SciPy的附带的 “错误函数”,又名高斯积分:
import scipy.special
help(scipy.special.erf)
我假设你正在处理的多元状态;如果是这样,这已经具有的功能你们寻找:这就是所谓MVNDIST("正常的多元分布)。在这文件是以往一样,太可怕了,所以我不能即使发现那里的功能是埋葬了,但是 它在那里的某个地方.该文件是很容易的最糟糕的部分内容很,并且已经沮丧的是我没有结束过去。
单变量的状态只是利用良好的旧错误的功能,其中许多实现。
作为攻击的问题,在一般的,是的,詹姆斯*汤普森提到,你只要写你自己的高斯分发功能和饲料到四().如果你可以避免的广义的一体化,虽然,这是一个很好的想法这样做--专业融合技术,用于一个特定功能(如MVNDIST使用)将远远快于一个标准的蒙特卡罗的多层面一体化,这可能是极其缓慢的高精确度。
高斯分布也称为正态分布。在SciPy的标准模块中的CDF功能你想要做什么。
from scipy.stats import norm
print norm.cdf(0.0)
>>>0.5
HTTP:// docs.scipy.org/doc/scipy/reference/generated/scipy.stats.norm.html#scipy.stats.norm
为什么不只是永远做你的积分从负无穷大到正无穷大,所以你总是知道答案吗? (开玩笑!)
我的猜测是,那有没有已经在SciPy的罐头高斯函数的唯一原因是,它是写一个简单的功能。您如何编写自己的功能,并将其传递到四,整合的建议听起来优秀。它采用了这样做的接受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 )
这是一个有点难看,因为高斯函数是有点长,但还是很琐碎写。