我生成了一个随机的5 * 5矩阵x,如下所示:

>>> x = np.random.randn(5,5)


然后使用scipy.linalg.ldl分解将其分解,如下所示:

>>> l, d, p = la.ldl(x)


我想使用ldp返回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/

10-11 18:05