Я использую Eigen в программе C++ для решения линейного уравнения для очень маленького квадрата. матрица (4X4).
Мой тестовый код похож на
template<template <typename MatrixType> typename EigenSolver>
Vertor3d solve(){
//Solve Ax = b and A is a real symmetric matrix and positive semidefinite
... // Construct 4X4 square matrix A and 4X1 vector b
EigenSolver<Matrix4d> solver(A);
auto x = solver.solve(b);
... // Compute relative error for validating
}
Я тестирую некоторые EigenSolver, которые включают:
- FullPixLU
- PartialPivLU
- ДомохозяинQR
- ColPivHouseholderQR
- ColPivHouseholderQR
- Полная ортогональная декомпозиция
- LDLT
- Прямой обратный
Прямая инверсия это:
template<typename MatrixType>
struct InverseSolve
{
private:
MatrixType inv;
public:
InverseSolve(const MatrixType &matrix) :inv(matrix.inverse()) {
}
template<typename VectorType>
auto solve(const VectorType & b) {
return inv * b;
}
};
Я обнаружил, что быстрый метод - это DirectInverse. Даже если я связал Eigen с MKL, результат не изменился.
Это результат теста
- FullPixLU: 477 мс
- PartialPivLU: 468 мс
- HouseholderQR: 849 мс
- ColPivHouseholderQR: 766 мс
- ColPivHouseholderQR: 857 мс
- CompleteOrthogonalDecomposition: 832 мс
- LDLT : 477 мс
- Прямая инверсия: 88 мс
все они используют 1000000 матриц со случайным удвоением из равномерного распределения [0,100]. Сначала я строю верхний треугольник, а затем копирую в нижний треугольник.
Единственная проблема DirectInverse заключается в том, что его относительная ошибка немного больше, чем у других решателей, но приемлема.
Есть ли более быстрое или изящное решение для моей программы? Является ли DirectInverse быстрым решением для моей программы?
DirectInverse не использует симметричную информацию, так почему же DirectInverse намного быстрее, чем LDLT?
selfadjointView<Eigen::Upper>
также хорошо работает дляinv
. Я протестирую решение и сравню его с решением, настроенным вручную. Еще раз спасибо за вашу помощь. 19.06.2018inv.selfadjointView<Eigen::Upper>() * b
конечно работает, но скорее всего будет работать медленнее. Использование симметрии для матричных векторных произведений в основном имеет смысл, если это экономит место в кэше. 19.06.2018