Scipy:在整个表面上加速集成?
Posted
技术标签:
【中文标题】Scipy:在整个表面上加速集成?【英文标题】:Scipy: speed up integration when doing it for the whole surface? 【发布时间】:2016-05-08 20:17:53 【问题描述】:我有一个概率密度函数 (pdf) f(x,y)
。而要在点 (x,y) 处获得其累积分布函数 (cdf)F(x,y)
,您需要整合 f(x,y)
,如下所示:
在Scipy
,我可以通过integrate.nquad
做到:
x, y=5, 4
F_at_x_y = integrate.nquad(f, [[-inf, x],[-inf, y]])
现在,我需要 x-y
面板中的整个 F(x,y)
,如下所示:
我该怎么做?
主要问题是,对于从(-30,-30)
到(30,30)
的每一点,我需要从头开始integrate.nquad
来获得F(x,y)
。这太慢了。
我想知道,由于结果是连续的(例如,您通过F(4,4)
的值得到F(5,6)
,并从这两个点之间的区域积分),是否可以加快进程?所以我们不需要在每一点都从头开始integrate
,因此可以加快处理速度。
可能有用的链接:
Multivariate Normal CDF in Python using scipy
http://cn.mathworks.com/help/stats/mvncdf.html
我正在考虑借用 斐波那契数列
How to write the Fibonacci Sequence in Python
【问题讨论】:
您真的需要多元法线(3 个链接中的 3 个),还是需要一些一般分布?你有没有尝试过简单的Ffun=lambda x,y:integrate.nquad(f, [[-inf, x],[-inf, y]]); Fvals=[Ffun(x,y) for x,y in zip(xarr,yarr)]
并按照你说的做,从x[i-1]
到x[i]
在一个双循环中集成,并比较两者?
@AndrasDeak,我需要它来进行一般分发。速度真的很慢,因为我的pdf
之一是kdf
(scikit-learn.org/stable/modules/generated/…),就是瓶颈。 multivariate normal
的 pdf 比这快得多。
【参考方案1】:
最后,这就是我所做的:
F 是 cdf,f 是 pdf
F(5,5) = F(5,4) + F(4,5) - 2 *F(4,4) + f(5,5)
并循环遍历整个表面,即可得到结果。
代码如下所示:
def cdf_from_pdf(pdf):
if not isinstance(pdf[0], np.ndarray):
original_dim = int(np.sqrt(len(pdf)))
pdf = pdf.reshape(original_dim,original_dim)
cdf = np.copy(pdf)
xdim, ydim = cdf.shape
for i in xrange(1,xdim):
cdf[i,0] = cdf[i-1,0] + cdf[i,0]
for i in xrange(1,ydim):
cdf[0,i] = cdf[0,i-1] + cdf[0,i]
for j in xrange(1,ydim):
for i in xrange(1,xdim):
cdf[i,j] = cdf[i-1,j] + cdf[i,j-1] - cdf[i-1,j-1] + pdf[i,j]
return cdf
这是一个非常粗略的近似值,您可以通过将 +/- 等式更改为积分来完善结果。
至于原始值和边距,cdf[0,:]
和cdf[:,0]
,也可以使用积分。就我而言,它非常小,所以我只使用 pdf 值。
您可以通过绘制cdf
来测试函数,或者检查cdf[n,n]
处的值
【讨论】:
以上是关于Scipy:在整个表面上加速集成?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Scipy 的 Kd-tree 函数来加速 K-Nearest Neighbors (KNN) [关闭]
从 scipy.spatial.Delauna 加速“find_simplex”