3

以下は、多変量正規分布から描画するための Cython コードです。密度が毎回異なるため、ループを使用しています。(conLSigma はコレスキー因子)

ループごとに逆分解とコレスキー分解を行っているため、これには多くの時間がかかります。純粋な 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)
4

2 に答える 2

5

コレスキー分解は、下三角行列を作成します。これは、 で実行される乗算の半分近くがnp.dot実行される必要がないことを意味します。ラインを変えると

betas_cand[con] = betas[con] + s * np.dot(conLSigma, np.random.standard_normal(size = nX))

の中へ

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]

ただし、変更する必要もあります

cdef np.ndarray betas_cand = np.zeros([ncons, nX], dtype = np.float64)

の中へ

cdef np.ndarray betas_cand = np.array(betas)

もちろん、乗算にスライスを使用することもできますが、提案した方法よりも高速になるかどうかはわかりません。とにかく、うまくいけば、あなたはアイデアを得るでしょう。これをスピードアップするために他にできることはあまりないと思います。

于 2010-11-21T06:36:11.620 に答える
0

最初にコレスキー分解を計算し、その後、逆置換によって下三角行列を反転するのはどうですか。これは linalg.cholesky(linalg.inv(S)) よりも高速です。

于 2014-06-09T15:03:23.737 に答える