Я хотел бы взять обратную матрицу nxn для использования в моем GraphSlam.
Проблемы, с которыми я столкнулся:
.inverse()
Собственная библиотека (3.1.2) не допускает нулевых значений, возвращаетNaN
- Библиотека LAPACK (3.4.2) не позволяет использовать нулевой определитель, но допускает нулевые значения (используется код примера из Вычисление обратной матрицы с помощью lapack в C)
- Библиотека Seldon (5.1.2) по какой-то причине не компилировалась
Кто-нибудь успешно реализовал код инверсии матрицы n x n, который допускает отрицательные значения, нулевые значения и определитель нуля? Любые рекомендации по хорошей библиотеке (С++)?
Я пытаюсь рассчитать омегу для 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 ]
Реальный пример будет 170x170 и будет содержать 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-ю строку.
Я также могу сделать это для моей матрицы 170x170, 4x4 был просто примером.
A:
[ 1 -1 0 ]
[ -1 2 -1 ]
[ 0 -1 1 ]
Таким образом, удаление 4-го столбца и 4-й строки не приведет к нулевому определителю. Но у меня все еще может быть нулевой определитель, если моя матрица такая же, как указано выше. Это когда сумма каждой строки или каждого столбца равна нулю. (Который у меня будет постоянно на GraphSlam)
Решение LAPACK (на основе Moore-Penrose Inverse) работало, если детерминант не был равен нулю (использовался код примера из Вычисление обратной матрицы с использованием 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]