У меня есть следующий фрагмент кода, где я вычисляю матрицу L заданной квадратной матрицы с помощью команды scipy.linalg.lu(), а затем делаю то же самое снова, кроме того, применяя ее к разреженной форме данной матрицы, используя scipy. sparse.linalg.splu(). Это код:
import numpy as np
from scipy.sparse.linalg import splu
from scipy.sparse import csc_matrix
import scipy.linalg
A1 = csc_matrix([[1., 0, 0.], [5., 0, 2], [0, -1., 0]])
A2 = np.array([[1., 0, 0.], [5., 0, 2], [0, -1., 0]])
B = splu(A1)
P,L,U = scipy.linalg.lu(A2)
print(L);print(csr_matrix.todense(B.L))
Что возвращает следующее:
[[ 1. 0. 0. ]
[ 0. 1. 0. ]
[ 0.2 -0. 1. ]]
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
Как мы видим, эти матрицы не совпадают. Я не понимаю, что делают обе команды или что-то еще не так? Любая помощь приветствуется. Спасибо!
Я думаю, что ответ здесь заключается в том, что декомпозиция "SuperLU" разреженной матрицы требует перестановок как строк, так и столбцов (см. Документы):
Pr * A * Pc = L * U
Это обеспечивается отображением индексов в perm_r
и perm_c
. Так,
Pr = csc_matrix((3,3))
Pr[B.perm_r, np.arange(3)] = 1
Pc = csc_matrix((3,3))
Pc[np.arange(3), B.perm_c] = 1
(Pr.T @ B.U @ B.L @ Pc.T).A
дает, при необходимости:
array([[ 1., 0., 0.],
[ 5., 0., 2.],
[ 0., -1., 0.]])
То же самое, что и нерезкий результат, который требует только перестановки L-матрицы, P @L @U