Разложение липкого ЛНП, возвращающее неожиданный результат - PullRequest
1 голос
/ 11 февраля 2020

Я сгенерировал случайную матрицу 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, но я очень смущен, поскольку на то, что Сципи дает в качестве вывода.

1 Ответ

2 голосов
/ 11 февраля 2020

Алгоритм разложения ЛПНП применяется только для эрмитовых / симметричных c матриц. Вы передаете ему матрицу со случайными значениями, которые вряд ли будут симметричны c. Кроме того, умножение матриц должно выполняться без применения матрицы перестановок к нижним матрицам tri angular.

Когда несимметричная матрица c передается в scipy.linalg.ldl, только нижняя или верхняя Ссылка на три angular части матрицы зависит от значения аргумента ключевого слова 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]]

Здесь мы видим, что верхняя три angular часть матрицы была принята как симметричная c, и поэтому алгоритм имеет возвращаемые значения, которые были бы правильными, если бы это было так.

Ниже мы передаем la.ldl фактическую матрицу симметрии c и получаем ожидаемый результат.

>>> 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 в целом, без перестановок , это еще больше уменьшает поле матриц. Ваша матрица также должна быть положительно определенной .

Вот пример с одной такой матрицей:

>>> 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 уже ниже три angular.

...