0

第一期

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

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

第 2 期

我有一个问题,一个整行和一列(例如第一行中的所有元素和第一列中的所有元素)都为零,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]])
4

2 回答 2

1

你可以只使用numpy.linalg.cholesky. 此外,如果一列或一行的所有内容都为零,则矩阵将是奇异的,至少有一个特征值为零,因此不是正定的。由于 Cholesky 仅针对“Hermitian(实值对称)和正定矩阵定义,因此不适用于它。

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

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

于 2014-04-16T18:28:21.920 回答
1

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

于 2014-07-28T16:51:45.247 回答