2011-12-26 2 views
6

Может ли кто-нибудь указать мне на библиотеку/код, позволяющий выполнять низкоуровневые обновления в декомпозиции Cholesky в python (numpy)? Matlab предлагает эту функцию как функцию cholupdate. LINPACK также имеет эту функциональность, но он (насколько мне известно) еще не был перенесен на LAPACK и, следовательно, недоступен, например. SciPy.Обновление Dense Cholesky в Python

Я выяснил, что scikits.sparse предлагает аналогичную функцию, основанную на CHOLMOD, но мои матрицы плотные.

Есть ли код для python с функциональностью cholupdate, совместимой с numpy?

Спасибо!

ответ

3

Вот пакет Python, который делает ранг 1 обновление и downdates на Холецких факторах с использованием Cython: https://github.com/jcrudy/choldate

Пример:

from choldate import cholupdate, choldowndate 
import numpy 

#Create a random positive definite matrix, V 
numpy.random.seed(1) 
X = numpy.random.normal(size=(100,10)) 
V = numpy.dot(X.transpose(),X) 

#Calculate the upper Cholesky factor, R 
R = numpy.linalg.cholesky(V).transpose() 

#Create a random update vector, u 
u = numpy.random.normal(size=R.shape[0]) 

#Calculate the updated positive definite matrix, V1, and its Cholesky factor, R1 
V1 = V + numpy.outer(u,u) 
R1 = numpy.linalg.cholesky(V1).transpose() 

#The following is equivalent to the above 
R1_ = R.copy() 
cholupdate(R1_,u.copy()) 
assert(numpy.all((R1 - R1_)**2 < 1e-16)) 

#And downdating is the inverse of updating 
R_ = R1.copy() 
choldowndate(R_,u.copy()) 
assert(numpy.all((R - R_)**2 < 1e-16)) 
1

Это должно сделать ранг-1 обновление или downdate на Numpy массивов R и x со знаком «+» или «-», соответствующим обновлению или сокращению. (Портировано из MATLAB cholupdate в Википедии: http://en.wikipedia.org/wiki/Cholesky_decomposition):

def cholupdate(R,x,sign): 
    import numpy as np 
     p = np.size(x) 
     x = x.T 
     for k in range(p): 
     if sign == '+': 
      r = np.sqrt(R[k,k]**2 + x[k]**2) 
     elif sign == '-': 
      r = np.sqrt(R[k,k]**2 - x[k]**2) 
     c = r/R[k,k] 
     s = x[k]/R[k,k] 
     R[k,k] = r 
     if sign == '+': 
      R[k,k+1:p] = (R[k,k+1:p] + s*x[k+1:p])/c 
     elif sign == '-': 
      R[k,k+1:p] = (R[k,k+1:p] - s*x[k+1:p])/c 
     x[k+1:p]= c*x[k+1:p] - s*R[k, k+1:p] 
     return R 
Смежные вопросы