aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/eigensolver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/eigensolver.cpp')
-rw-r--r--test/eigensolver.cpp81
1 files changed, 71 insertions, 10 deletions
diff --git a/test/eigensolver.cpp b/test/eigensolver.cpp
index a1ab4a685..48ae50587 100644
--- a/test/eigensolver.cpp
+++ b/test/eigensolver.cpp
@@ -25,6 +25,10 @@
#include "main.h"
#include <Eigen/QR>
+#ifdef HAS_GSL
+#include "gsl_helper.h"
+#endif
+
template<typename MatrixType> void eigensolver(const MatrixType& m)
{
/* this test covers the following files:
@@ -33,19 +37,76 @@ template<typename MatrixType> void eigensolver(const MatrixType& m)
int rows = m.rows();
int cols = m.cols();
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
+ typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;
typedef typename std::complex<typename NumTraits<typename MatrixType::Scalar>::Real> Complex;
- MatrixType a = MatrixType::Random(rows,cols);
- MatrixType symmA = a.adjoint() * a;
+ RealScalar largerEps = 10*test_precision<RealScalar>();
+
+ MatrixType a = test_random_matrix<MatrixType>(rows,cols);
+ MatrixType a1 = test_random_matrix<MatrixType>(rows,cols);
+ MatrixType symmA = a.adjoint() * a + a1.adjoint() * a1;
+
+ MatrixType b = test_random_matrix<MatrixType>(rows,cols);
+ MatrixType b1 = test_random_matrix<MatrixType>(rows,cols);
+ MatrixType symmB = b.adjoint() * b + b1.adjoint() * b1;
SelfAdjointEigenSolver<MatrixType> eiSymm(symmA);
- VERIFY_IS_APPROX(symmA * eiSymm.eigenvectors(), (eiSymm.eigenvectors() * eiSymm.eigenvalues().asDiagonal().eval()));
+ // generalized eigen pb
+ SelfAdjointEigenSolver<MatrixType> eiSymmGen(symmA, symmB);
+
+ #ifdef HAS_GSL
+ if (ei_is_same_type<RealScalar,double>::ret)
+ {
+ typedef GslTraits<Scalar> Gsl;
+ typename Gsl::Matrix gEvec=0, gSymmA=0, gSymmB=0;
+ typename GslTraits<RealScalar>::Vector gEval=0;
+ RealVectorType _eval;
+ MatrixType _evec;
+ convert<MatrixType>(symmA, gSymmA);
+ convert<MatrixType>(symmB, gSymmB);
+ convert<MatrixType>(symmA, gEvec);
+ gEval = GslTraits<RealScalar>::createVector(rows);
+
+ Gsl::eigen_symm(gSymmA, gEval, gEvec);
+ convert(gEval, _eval);
+ convert(gEvec, _evec);
+
+ // test gsl itself !
+ VERIFY((symmA * _evec).isApprox(_evec * _eval.asDiagonal().eval(), largerEps));
+
+ // compare with eigen
+ VERIFY_IS_APPROX(_eval, eiSymm.eigenvalues());
+ VERIFY_IS_APPROX(_evec.cwise().abs(), eiSymm.eigenvectors().cwise().abs());
+
+ // generalized pb
+ Gsl::eigen_symm_gen(gSymmA, gSymmB, gEval, gEvec);
+ convert(gEval, _eval);
+ convert(gEvec, _evec);
+ // test GSL itself:
+ VERIFY((symmA * _evec).isApprox(symmB * (_evec * _eval.asDiagonal().eval()), largerEps));
+
+ // compare with eigen
+// std::cerr << _eval.transpose() << "\n" << eiSymmGen.eigenvalues().transpose() << "\n\n";
+// std::cerr << _evec.format(6) << "\n\n" << eiSymmGen.eigenvectors().format(6) << "\n\n\n";
+ VERIFY_IS_APPROX(_eval, eiSymmGen.eigenvalues());
+ VERIFY_IS_APPROX(_evec.cwise().abs(), eiSymmGen.eigenvectors().cwise().abs());
+
+ Gsl::free(gSymmA);
+ Gsl::free(gSymmB);
+ GslTraits<RealScalar>::free(gEval);
+ Gsl::free(gEvec);
+ }
+ #endif
+
+ VERIFY((symmA * eiSymm.eigenvectors()).isApprox(
+ eiSymm.eigenvectors() * eiSymm.eigenvalues().asDiagonal().eval(), largerEps));
// generalized eigen problem Ax = lBx
- MatrixType b = MatrixType::Random(rows,cols);
- MatrixType symmB = b.adjoint() * b;
- eiSymm.compute(symmA,symmB);
- VERIFY_IS_APPROX(symmA * eiSymm.eigenvectors(), symmB * (eiSymm.eigenvectors() * eiSymm.eigenvalues().asDiagonal().eval()));
+ VERIFY((symmA * eiSymmGen.eigenvectors()).isApprox(
+ symmB * (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal().eval()), largerEps));
// EigenSolver<MatrixType> eiNotSymmButSymm(covMat);
// VERIFY_IS_APPROX((covMat.template cast<Complex>()) * (eiNotSymmButSymm.eigenvectors().template cast<Complex>()),
@@ -59,12 +120,12 @@ template<typename MatrixType> void eigensolver(const MatrixType& m)
void test_eigensolver()
{
- for(int i = 0; i < 1; i++) {
+ for(int i = 0; i < g_repeat; i++) {
// very important to test a 3x3 matrix since we provide a special path for it
CALL_SUBTEST( eigensolver(Matrix3f()) );
CALL_SUBTEST( eigensolver(Matrix4d()) );
CALL_SUBTEST( eigensolver(MatrixXf(7,7)) );
- CALL_SUBTEST( eigensolver(MatrixXcd(6,6)) );
- CALL_SUBTEST( eigensolver(MatrixXcf(3,3)) );
+ CALL_SUBTEST( eigensolver(MatrixXcd(5,5)) );
+ CALL_SUBTEST( eigensolver(MatrixXd(19,19)) );
}
}