我生成了一个随机的5 * 5矩阵x
,如下所示:
>>> x = np.random.randn(5,5)
然后使用
scipy.linalg.ldl
分解将其分解,如下所示:>>> l, d, p = la.ldl(x)
我想使用
l
,d
和p
返回x。我以为我可以做到以下几点:>>> l[p,:] @ d @ l[p,:].transpose() - x
但这并没有给我零期望。谁能解释我要去哪里错了?
我的目标是获得较低的对角矩阵
L
,使x = LDL^T
不需要行置换矩阵p
,但是对于输出输出的内容,我感到很困惑。 最佳答案
LDL分解算法仅适用于Hermitian /对称矩阵。您将矩阵传递给它的是随机值,该值不太可能是对称的。此外,应在不将置换矩阵应用于下三角矩阵的情况下执行矩阵乘法。
当将非对称矩阵传递给scipy.linalg.ldl
时,仅引用矩阵的下部或上部三角形部分,具体取决于lower
关键字参数的值(默认为True
)。我们可以通过np.isclose()
看到其效果:
>>> x = np.random.randn(5,5)
>>> l, d, p = la.ldl(x)
>>> np.isclose(l.dot(d).dot(l.T) - x, 0)
[[ True False False False False]
[ True True False False False]
[ True True True False False]
[ True True True True False]
[ True True True True True]]
在这里,我们看到矩阵的上三角部分被假定为对称的,因此该算法返回的值在这种情况下将是正确的。
下面,我们传递
la.ldl
一个实际的对称矩阵,并获得预期的结果。>>> x = np.array([[1, 2, 3],
[2, 4, 5],
[3, 5, 6]])
>>> l, d, p = la.ldl(x)
>>> print(np.isclose(l.dot(d).dot(l.T) - x, 0))
[[ True True True]
[ True True True]
[ True True True]]
如果您通常希望在不进行置换的情况下分解为LDL ^ T,则可以进一步减小矩阵的范围。您的矩阵也必须为positive definite。
这是一个带有这样一个矩阵的示例:
>>> x = np.array([[2, -1, 0],
[-1, 3, -1],
[0, -1, 4]])
>>> l, d, p = la.ldl(x)
>>> l
array([[ 1. , 0. , 0. ],
[-0.5, 1. , 0. ],
[ 0. , -0.4, 1. ]])
>>> d
array([[2. , 0. , 0. ],
[0. , 2.5, 0. ],
[0. , 0. , 3.6]])
>>> p
array([0, 1, 2], dtype=int64)
如您所见,排列
p
只是[0, 1, 2]
,而l
已经是较低的三角形。关于python - Scipy LDL分解返回意外结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60172680/