Lapack:Cholesky矩阵分解问题

时间:2014-04-16 16:32:03

标签: python matrix lapack cvxopt

第1期

有人可以推荐一种在python中进行Cholesky分解的不太尴尬的方法吗?特别是最后一行让我烦恼。

SigmaSqrt = matrix(Sigma)
cvxopt.lapack.potrf(SigmaSqrt)
SigmaSqrt = matrix(np.tril(SigmaSqrt))

第2期

我有问题,那一条整线和一条线。 column(例如,第一行中的所有元素和第一列中的所有元素)都为零,lapack失败,并且矩阵不是正定的错误。解决这个问题的最佳方法是什么?

目前我这样做:(看起来很尴尬......)

try:
    SigmaSqrt = matrix(Sigma)
    cvxopt.lapack.potrf(SigmaSqrt)
    SigmaSqrt = matrix(np.tril(SigmaSqrt))
except ArithmeticError:
    SigmaSqrt = matrix(Sigma.ix[1:,1:])
    cvxopt.lapack.potrf(SigmaSqrt)
    SigmaSqrt = matrix(np.tril(SigmaSqrt))
    SigmaSqrt = sparse([[v0],[v0[1:].T, SigmaSqrt]])

2 个答案:

答案 0 :(得分:1)

您可以使用numpy.linalg.cholesky。此外,如果一行中的所有一列或全部都是零,则矩阵将是单数的,至少在特征值上将为零,因此不是正定的。由于Cholesky仅定义为“Hermitian(对称,如果是实值)和正定”,它不适用于它。

编辑:来“处理”您的问题取决于您的需求。你做的任何事情都会使一个cholesky成为原始矩阵的Cholesky。如果你正在进行一个迭代过程并且它可以稍微有点软,如果它已经是对称的,那么使用numpy.linalg.eigvalsh来找到矩阵的特征值。设d是最负的特征值。然后设置A += (abs(d) + 1e-4) * np.indentity(len(A))。这将使其肯定。

编辑:这是Levenberg-Marquardt算法中使用的技巧。这链接到关于Newton's Method的维基百科文章提到它,因为关于Levenberg-Marquard的文章没有涉及到这一点。另外,here也是一篇论文。基本上,这会将所有特征值移动(abs(d) + 1e-4),从而使它们全部为正,这是矩阵为正定的充分条件。

答案 1 :(得分:1)

另一种选择是chompack模块:chompack homepage chompack.cholesky 我自己和cvxopt模块一起使用它。它与cvxopt的(稀疏)矩阵完美配合。