(Псевдо) -обратная от N к N матрица с нулевым определителем

Я хотел бы взять обратную матрицу nxn для использования в моем GraphSlam.

Проблемы, с которыми я столкнулся:

  • .inverse() Собственная библиотека (3.1.2) не допускает нулевые значения, возвращает NaN
  • Библиотека LAPACK (3.4.2) не позволяет использовать нулевой определитель, но допускает нулевые значения (использовался пример кода из Вычисление обратной матрицы с использованием Lapack в C)
  • Библиотека Seldon (5.1.2) по какой-то причине не компилируется

Кто-нибудь успешно реализовал N Икс N матричный инверсионный код, который допускает отрицательные, нулевые значения и определитель нуля? Любые хорошие рекомендации библиотеки (C ++)?

Я пытаюсь рассчитать омега в следующем для GraphSlam:
http://www.acastano.com/others/udacity/cs_373_autonomous_car.html


Простой пример:

[ 1 -1  0 0 ]
[ -1 2 -1 0 ]
[ 0 -1  1 0 ]
[ 0  0  0 0 ]

Реальный пример будет 170×170 и содержит 0, отрицательные значения, большие положительные значения.
Данный простой пример используется для отладки кода.


Я могу рассчитать это в Matlab (псевдообратная Мура-Пенроуза), но по какой-то причине я не могу запрограммировать это на C ++.

A = [1 -1 0 0; -1 2 -1 0; 0 -1 1 0; 0 0 0 0]
B = pinv(A)
B=
[0.56   -0.12  -0.44  0]
[-0.12  0.22   -0.11  0]
[-0.44  -0.11   0.56  0]
[0  0  0   0]

Для моего приложения я могу (временно) удалить измерение с нулями.
Поэтому я собираюсь удалить 4-й столбец и 4-й ряд.
Я также могу сделать это для моей матрицы 170×170, 4×4 был просто примером.

A:

[ 1 -1  0 ]
[ -1 2 -1 ]
[ 0 -1  1 ]

Таким образом, удаление 4-го столбца и 4-го ряда не приведет к нулевому определителю.
Но у меня все еще может быть нулевой определитель, если моя матрица такая же, как указано выше.
Это когда сумма каждой строки или каждого столбца равна нулю. (Который у меня будет все время в GraphSlam)

Решение LAPACK (основанное на инверсии Мура-Пенроуза) работало, если определитель не был равен нулю (использовался пример кода из Вычисление обратной матрицы с использованием Lapack в C).
Но потерпел неудачу как «псевдообратный» с определителем нуля.


РЕШЕНИЕ: (все кредиты Фрэнку Рейнингхаусу), используя SVD (разложение по единственному значению)
http://sourceware.org/ml/gsl-discuss/2008-q2/msg00013.html

Работает с:

  • Нулевые значения (даже полные 0 строк и полные 0 столбцов)
  • Отрицательные значения
  • Определитель нуля

A ^ -1:

[0.56   -0.12  -0.44]
[-0.12  0.22   -0.11]
[-0.44  -0.11   0.56]

5

Решение

Если все, что вам нужно, это решить задачу вида Ax = B (или эквивалентно вычислить произведения вида A ^ -1 * b), то я рекомендую вам не вычислять обратное или псевдообратное значение A, а непосредственно решать для Ax = b с использованием подходящего решателя, раскрывающего рейтинг. Например, используя Eigen:

x = A.colPivHouseholderQr().solve(b);
x = A.jacobiSvd(ComputeThinU|ComputeThinV).solve(b);
7

Другие решения

Ваша команда Matlab не вычисляет обратное значение в вашем случае, потому что матрица имеет определенный ноль. pinv Command рассчитывает Псевдообратный Мур-Пенроуз. pinv(A) имеет некоторые, но не все, свойства inv(A),

Так что вы не делаете то же самое в C ++ и в Matlab!

предыдущий

Как в моем комментарии. Теперь как ответ. Вы должны убедиться, что вы инвертируете обратимые матрицы. Это означает

det A != 0

В вашем примере матрицы определитель равен нулю. Это не обратимая матрица. Я надеюсь, что вы не примеряете это!

Например, данная матрица имеет нулевой определитель, если имеется полная строка или столбец с нулевыми записями.

4

Вы уверены, что это из-за нулевых / отрицательных значений, а не потому, что ваша матрица необратима?

Обратная матрица имеет место только в том случае, если ее определитель ненулевой (ссылка на mathworld), а пример матрицы вы выложили в вопросе имеет нулевой определитель и поэтому он не имеет обратного.

Это должно объяснить, почему эти библиотеки не позволяют использовать обратную матрицу, но я не могу сказать, имеет ли место то же самое рассуждение для вашей полноразмерной матрицы 170×170.

2

Если ваши матрицы являются своего рода ковариационными или весовыми матрицами, вы можете использовать «обобщенную инверсию Холецкого» вместо SVD. Результаты будут более приемлемыми для практического использования

-1
По вопросам рекламы [email protected]