joo*_*oon 3 python numpy cython
以下是我从多变量正态分布中绘制的Cython代码.我正在使用循环,因为每次我有不同的密度.(conLSigma是Cholesky因子)
这花费了很多时间,因为我正在对每个循环进行逆和Cholesky分解.它比纯python代码更快,但我想知道是否有任何方法可以提高速度.
from __future__ import division
import numpy as np
cimport numpy as np
ctypedef np.float64_t dtype_t
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
def drawMetro(np.ndarray[dtype_t, ndim = 2] beta,
np.ndarray[dtype_t, ndim = 3] H,
np.ndarray[dtype_t, ndim = 2] Sigma,
float s):
cdef int ncons = betas.shape[0]
cdef int nX = betas.shape[1]
cdef int con
cdef np.ndarray betas_cand = np.zeros([ncons, nX], dtype = np.float64)
cdef np.ndarray conLSigma = np.zeros([nX, nX], dtype = np.float64)
for con in xrange(ncons):
conLSigma = np.linalg.cholesky(np.linalg.inv(H[con] + Sigma))
betas_cand[con] = betas[con] + s * np.dot(conLSigma, np.random.standard_normal(size = nX))
return(betas_cand)
Run Code Online (Sandbox Code Playgroud)
Cholesky分解创建了一个下三角矩阵.这意味着np.dot不需要完成接近一半的乘法.如果你改变了这条线
betas_cand[con] = betas[con] + s * np.dot(conLSigma, np.random.standard_normal(size = nX))
Run Code Online (Sandbox Code Playgroud)
成
tmp = np.random.standard_normal(size = nX)
for i in xrange(nX):
for j in xrange(i+1):
betas_cand[con,i] += s * conLSigma[i,j] * tmp[j]
Run Code Online (Sandbox Code Playgroud)
但是,您还需要更改
cdef np.ndarray betas_cand = np.zeros([ncons, nX], dtype = np.float64)
Run Code Online (Sandbox Code Playgroud)
成
cdef np.ndarray betas_cand = np.array(betas)
Run Code Online (Sandbox Code Playgroud)
你当然可以使用切片进行乘法,但我不确定它是否会比我建议的方式更快.无论如何,希望你能得到这个想法.我认为你还有很多其他方法可以加快速度.
| 归档时间: |
|
| 查看次数: |
1495 次 |
| 最近记录: |