aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/lu.cpp
diff options
context:
space:
mode:
authorGravatar Rasmus Munk Larsen <rmlarsen@google.com>2016-04-01 10:27:59 -0700
committerGravatar Rasmus Munk Larsen <rmlarsen@google.com>2016-04-01 10:27:59 -0700
commit1aa89fb85548dc425d54d2cbe7f28915c29db13a (patch)
treee2de38e397b0bd23f7f4ab8ee62236e6c91d8fa5 /test/lu.cpp
parent1b40abbf99d2022d1167063f7e52126cbe8d76bd (diff)
Add matrix condition estimator module that implements the Higham/Hager algorithm from http://www.maths.manchester.ac.uk/~higham/narep/narep135.pdf used in LPACK. Add rcond() methods to FullPivLU and PartialPivLU.
Diffstat (limited to 'test/lu.cpp')
-rw-r--r--test/lu.cpp22
1 files changed, 20 insertions, 2 deletions
diff --git a/test/lu.cpp b/test/lu.cpp
index f14435114..31991520d 100644
--- a/test/lu.cpp
+++ b/test/lu.cpp
@@ -11,6 +11,11 @@
#include <Eigen/LU>
using namespace std;
+template<typename MatrixType>
+typename MatrixType::RealScalar matrix_l1_norm(const MatrixType& m) {
+ return m.cwiseAbs().colwise().sum().maxCoeff();
+}
+
template<typename MatrixType> void lu_non_invertible()
{
typedef typename MatrixType::Index Index;
@@ -143,7 +148,13 @@ template<typename MatrixType> void lu_invertible()
m3 = MatrixType::Random(size,size);
m2 = lu.solve(m3);
VERIFY_IS_APPROX(m3, m1*m2);
- VERIFY_IS_APPROX(m2, lu.inverse()*m3);
+ MatrixType m1_inverse = lu.inverse();
+ VERIFY_IS_APPROX(m2, m1_inverse*m3);
+
+ // Test condition number estimation.
+ RealScalar rcond = RealScalar(1) / matrix_l1_norm(m1) / matrix_l1_norm(m1_inverse);
+ // Verify that the estimate is within a factor of 10 of the truth.
+ VERIFY(lu.rcond() > rcond / 10 && lu.rcond() < rcond * 10);
// test solve with transposed
lu.template _solve_impl_transposed<false>(m3, m2);
@@ -170,6 +181,7 @@ template<typename MatrixType> void lu_partial_piv()
PartialPivLU.h
*/
typedef typename MatrixType::Index Index;
+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
Index size = internal::random<Index>(1,4);
MatrixType m1(size, size), m2(size, size), m3(size, size);
@@ -181,7 +193,13 @@ template<typename MatrixType> void lu_partial_piv()
m3 = MatrixType::Random(size,size);
m2 = plu.solve(m3);
VERIFY_IS_APPROX(m3, m1*m2);
- VERIFY_IS_APPROX(m2, plu.inverse()*m3);
+ MatrixType m1_inverse = plu.inverse();
+ VERIFY_IS_APPROX(m2, m1_inverse*m3);
+
+ // Test condition number estimation.
+ RealScalar rcond = RealScalar(1) / matrix_l1_norm(m1) / matrix_l1_norm(m1_inverse);
+ // Verify that the estimate is within a factor of 10 of the truth.
+ VERIFY(plu.rcond() > rcond / 10 && plu.rcond() < rcond * 10);
// test solve with transposed
plu.template _solve_impl_transposed<false>(m3, m2);