I am using Eigen on a C++ program for solving linear equation for very small square matrix(4X4).
My test code is like
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
}
I test some EigenSolver which include:
- FullPixLU
- PartialPivLU
- HouseholderQR
- ColPivHouseholderQR
- ColPivHouseholderQR
- CompleteOrthogonalDecomposition
- LDLT
- Direct Inverse
Direct Inverse is:
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;
}
};
I found that the fast method is DirectInverse,Even If I linked Eigen with MKL , the result was not change.
This is the test result
- FullPixLU : 477 ms
- PartialPivLU : 468 ms
- HouseholderQR : 849 ms
- ColPivHouseholderQR : 766 ms
- ColPivHouseholderQR : 857 ms
- CompleteOrthogonalDecomposition : 832 ms
- LDLT : 477 ms
- Direct Inverse : 88 ms
which all use 1000000 matrices with random double from uniform distribution [0,100].I fristly construct upper-triangle and then copy to lower-triangle.
The only problem of DirectInverse is that its relative error slightly larger than other solver but acceptble.
Is there any faster or more felegant solution for my program?Is DirectInverse the fast solution for my program?
DirectInverse does not use the symmetric infomation so why is DirectInverse far faster than LDLT?
solve
per matrix or just one? Please include your benchmark-result as text into the question, not as image-link. For fixed sized matrices up to 4x4,inverse()
is computed directly using co-factors, which is very fast and requires only on division, but is expected to be slightly less accurate, in general. Thesolve
as you implemented it, will only require a very fast Matrix-Vector product. You can increase the accuracy by doing a refinement-step:x=inv*b; x+=inv*(b-A*x);
. MKL will generally not help for small fixed-sized inputs. – Ezraezriinverse()
does not use it.Should I reimplement ainverse()
for my program? – PallatenVector4d x = solver.solve(b);
instead ofauto x = ...
. Otherwise, you might havex
evaluated multiple times. – Ezraezri