我想测试我写的一个简单的C++ Cholesky代码。所以我生成了一个随机下三角矩阵L,然后将其转置相乘以生成矩阵A。
A = L * Lt;
但是我的代码无法分解A。所以我在Matlab中尝试了这个:
N=200; L=tril(rand(N, N)); A=L*L'; [lc,p]=chol(A,'lower'); p
这会输出非零p,这意味着Matlab也无法因式分解A。我猜测随机性会生成秩亏矩阵。我的猜测正确吗?
更新:
我忘记提到以下Matlab代码似乎可以工作,如下所指出的Malife:
N=200; L=rand(N, N); A=L*L'; [lc,p]=chol(A,'lower'); p
区别在于第一个代码中的L是下三角矩阵,而第二个代码中则不是。这有什么关系吗?
我还尝试了以下使用scipy,参考了“生成正半定矩阵的简单算法”:https://dev59.com/XHRB5IYBdhLWcg3wc280
from scipy import random, linalg
A = random.rand(100, 100)
B = A*A.transpose()
linalg.cholesky(B)
但是它出现了错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/scipy/linalg/decomp_cholesky.py", line 66, in cholesky
c, lower = _cholesky(a, lower=lower, overwrite_a=overwrite_a, clean=True)
File "/usr/lib/python2.7/dist-packages/scipy/linalg/decomp_cholesky.py", line 24, in _cholesky
raise LinAlgError("%d-th leading minor not positive definite" % info)
numpy.linalg.linalg.LinAlgError: 2-th leading minor not positive definite
我不明白为什么scipy会出现这种情况。有什么想法吗?
谢谢, Nilesh。
*
代表的是逐个元素相乘,而不是代表代数乘法。如果要进行代数乘法计算,应该使用dot
函数。因此,你应该写成B = dot(A, A.transpose())
或者B = dot(A, A.T)
。 - Warren Weckesser