Python слева умножения матрицы с инверсией разреженной матрицы - PullRequest
4 голосов
/ 14 октября 2011

Я пытаюсь вычислить выражение вида K = P * C.T * S ^ -1 (реализация фильтра Калмана)

Все задействованные матрицы разрежены, и я, конечно, хотел бы избежать вычисления фактического обратного значения.

Я пытался использовать

import scipy.sparse.linalg as spln

self.K = self.P.dot(spln.spsolve(S.T, C).T)

Проблема в том, что spsolve ожидает, что вторым аргументом будет вектор, а не матрица.

редактирование: Пояснение: проблема в Matlab может быть решена с помощью K = P * (C / S), поэтому я ищу метод, похожий на spsolve, но который может принять матрицу в качестве второго аргумента. Конечно, это можно сделать, разбив C на несколько векторов-столбцов c1..cn и решив задачу для каждого из них, а затем заново собрав их в матрицу, но я подозреваю, что это будет громоздким и неэффективным.

edit2 & 3: Размеры матриц обычно составляют около P ~ 10 Px10 ^ 6, S ~ 100x100, C = 100x10⁶. Диагональ P и S симметричны, а C будет иметь только один элемент в строке. Он будет использоваться для реализации фильтра Калмана с использованием разреженных матриц, см.

http://en.wikipedia.org/wiki/Kalman_filter#The_Kalman_filter

1 Ответ

2 голосов
/ 19 октября 2011

Как обходной путь может сделать

import numpy as np
from scipy.sparse.linalg import splu

def spsolve2(a, b):
    a_lu = splu(a)
    out = np.empty((A.shape[1], b.shape[1]))
    for j in xrange(b.shape[1]):
        out[:,j] = a_lu.solve(b[:,j])
    return out

self.K = self.P.dot(spsolve2(S.T, C).T)

Но да, это ошибка, что spsolve не принимает матрицы.

Однако, поскольку ваш S не очень большой,Вы также можете использовать плотное обратное.

...