mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
merge my Dynamic -> -1 change
This commit is contained in:
@@ -129,7 +129,7 @@ template<typename ArrayType> void comparisons(const ArrayType& m)
|
||||
VERIFY(((m1.abs()+1)>RealScalar(0.1)).count() == rows*cols);
|
||||
|
||||
typedef Array<typename ArrayType::Index, Dynamic, 1> ArrayOfIndices;
|
||||
|
||||
|
||||
// TODO allows colwise/rowwise for array
|
||||
VERIFY_IS_APPROX(((m1.abs()+1)>RealScalar(0.1)).colwise().count(), ArrayOfIndices::Constant(cols,rows).transpose());
|
||||
VERIFY_IS_APPROX(((m1.abs()+1)>RealScalar(0.1)).rowwise().count(), ArrayOfIndices::Constant(rows, cols));
|
||||
@@ -151,10 +151,10 @@ template<typename ArrayType> void array_real(const ArrayType& m)
|
||||
VERIFY_IS_APPROX(m1.sin(), ei_sin(m1));
|
||||
VERIFY_IS_APPROX(m1.cos(), std::cos(m1));
|
||||
VERIFY_IS_APPROX(m1.cos(), ei_cos(m1));
|
||||
|
||||
|
||||
VERIFY_IS_APPROX(ei_cos(m1+RealScalar(3)*m2), ei_cos((m1+RealScalar(3)*m2).eval()));
|
||||
VERIFY_IS_APPROX(std::cos(m1+RealScalar(3)*m2), std::cos((m1+RealScalar(3)*m2).eval()));
|
||||
|
||||
|
||||
VERIFY_IS_APPROX(m1.abs().sqrt(), std::sqrt(std::abs(m1)));
|
||||
VERIFY_IS_APPROX(m1.abs().sqrt(), ei_sqrt(ei_abs(m1)));
|
||||
VERIFY_IS_APPROX(m1.abs(), ei_sqrt(ei_abs2(m1)));
|
||||
@@ -163,10 +163,10 @@ template<typename ArrayType> void array_real(const ArrayType& m)
|
||||
VERIFY_IS_APPROX(ei_abs2(std::real(m1)) + ei_abs2(std::imag(m1)), ei_abs2(m1));
|
||||
if(!NumTraits<Scalar>::IsComplex)
|
||||
VERIFY_IS_APPROX(ei_real(m1), m1);
|
||||
|
||||
|
||||
VERIFY_IS_APPROX(m1.abs().log(), std::log(std::abs(m1)));
|
||||
VERIFY_IS_APPROX(m1.abs().log(), ei_log(ei_abs(m1)));
|
||||
|
||||
|
||||
VERIFY_IS_APPROX(m1.exp(), std::exp(m1));
|
||||
VERIFY_IS_APPROX(m1.exp() * m2.exp(), std::exp(m1+m2));
|
||||
VERIFY_IS_APPROX(m1.exp(), ei_exp(m1));
|
||||
|
||||
@@ -37,10 +37,10 @@ template<typename MatrixType> void array_for_matrix(const MatrixType& m)
|
||||
MatrixType m1 = MatrixType::Random(rows, cols),
|
||||
m2 = MatrixType::Random(rows, cols),
|
||||
m3(rows, cols);
|
||||
|
||||
|
||||
ColVectorType cv1 = ColVectorType::Random(rows);
|
||||
RowVectorType rv1 = RowVectorType::Random(cols);
|
||||
|
||||
|
||||
Scalar s1 = ei_random<Scalar>(),
|
||||
s2 = ei_random<Scalar>();
|
||||
|
||||
|
||||
@@ -103,47 +103,6 @@ template<typename MatrixType> void reverse(const MatrixType& m)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
cout << "m1:" << endl << m1 << endl;
|
||||
cout << "m1c_reversed:" << endl << m1c_reversed << endl;
|
||||
|
||||
cout << "----------------" << endl;
|
||||
|
||||
for ( int i=0; i< rows*cols; i++){
|
||||
cout << m1c_reversed.coeff(i) << endl;
|
||||
}
|
||||
|
||||
cout << "----------------" << endl;
|
||||
|
||||
for ( int i=0; i< rows*cols; i++){
|
||||
cout << m1c_reversed.colwise().reverse().coeff(i) << endl;
|
||||
}
|
||||
|
||||
cout << "================" << endl;
|
||||
|
||||
cout << "m1.coeff( ind ): " << m1.coeff( ind ) << endl;
|
||||
cout << "m1c_reversed.colwise().reverse().coeff( ind ): " << m1c_reversed.colwise().reverse().coeff( ind ) << endl;
|
||||
*/
|
||||
|
||||
//MatrixType m1r_reversed = m1.rowwise().reverse();
|
||||
//VERIFY_IS_APPROX( m1r_reversed.rowwise().reverse().coeff( ind ), m1.coeff( ind ) );
|
||||
|
||||
/*
|
||||
cout << "m1" << endl << m1 << endl;
|
||||
cout << "m1 using coeff(int index)" << endl;
|
||||
for ( int i = 0; i < rows*cols; i++) {
|
||||
cout << m1.coeff(i) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
cout << "m1.transpose()" << endl << m1.transpose() << endl;
|
||||
cout << "m1.transpose() using coeff(int index)" << endl;
|
||||
for ( int i = 0; i < rows*cols; i++) {
|
||||
cout << m1.transpose().coeff(i) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
*/
|
||||
/*
|
||||
Scalar x = ei_random<Scalar>();
|
||||
|
||||
int r = ei_random<int>(0, rows-1),
|
||||
@@ -152,6 +111,7 @@ template<typename MatrixType> void reverse(const MatrixType& m)
|
||||
m1.reverse()(r, c) = x;
|
||||
VERIFY_IS_APPROX(x, m1(rows - 1 - r, cols - 1 - c));
|
||||
|
||||
/*
|
||||
m1.colwise().reverse()(r, c) = x;
|
||||
VERIFY_IS_APPROX(x, m1(rows - 1 - r, c));
|
||||
|
||||
|
||||
@@ -138,7 +138,8 @@ template<typename MatrixType> void basicStuffComplex(const MatrixType& m)
|
||||
VERIFY(ei_imag(s1)==ei_imag_ref(s1));
|
||||
ei_real_ref(s1) = ei_real(s2);
|
||||
ei_imag_ref(s1) = ei_imag(s2);
|
||||
VERIFY(s1==s2);
|
||||
VERIFY(ei_isApprox(s1, s2, NumTraits<RealScalar>::epsilon()));
|
||||
// extended precision in Intel FPUs means that s1 == s2 in the line above is not guaranteed.
|
||||
|
||||
RealMatrixType rm1 = RealMatrixType::Random(rows,cols),
|
||||
rm2 = RealMatrixType::Random(rows,cols);
|
||||
|
||||
@@ -26,10 +26,21 @@
|
||||
#define EIGEN_NO_ASSERTION_CHECKING
|
||||
#endif
|
||||
|
||||
static int nb_temporaries;
|
||||
|
||||
#define EIGEN_DEBUG_MATRIX_CTOR { if(size!=0) nb_temporaries++; }
|
||||
|
||||
#include "main.h"
|
||||
#include <Eigen/Cholesky>
|
||||
#include <Eigen/QR>
|
||||
|
||||
#define VERIFY_EVALUATION_COUNT(XPR,N) {\
|
||||
nb_temporaries = 0; \
|
||||
XPR; \
|
||||
if(nb_temporaries!=N) std::cerr << "nb_temporaries == " << nb_temporaries << "\n"; \
|
||||
VERIFY( (#XPR) && nb_temporaries==N ); \
|
||||
}
|
||||
|
||||
#ifdef HAS_GSL
|
||||
#include "gsl_helper.h"
|
||||
#endif
|
||||
@@ -110,20 +121,46 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
|
||||
VERIFY_IS_APPROX(symm * matX, matB);
|
||||
}
|
||||
|
||||
int sign = ei_random<int>()%2 ? 1 : -1;
|
||||
|
||||
if(sign == -1)
|
||||
// LDLT
|
||||
{
|
||||
symm = -symm; // test a negative matrix
|
||||
}
|
||||
int sign = ei_random<int>()%2 ? 1 : -1;
|
||||
|
||||
{
|
||||
LDLT<SquareMatrixType> ldlt(symm);
|
||||
VERIFY_IS_APPROX(symm, ldlt.reconstructedMatrix());
|
||||
vecX = ldlt.solve(vecB);
|
||||
if(sign == -1)
|
||||
{
|
||||
symm = -symm; // test a negative matrix
|
||||
}
|
||||
|
||||
SquareMatrixType symmUp = symm.template triangularView<Upper>();
|
||||
SquareMatrixType symmLo = symm.template triangularView<Lower>();
|
||||
|
||||
LDLT<SquareMatrixType,Lower> ldltlo(symmLo);
|
||||
VERIFY_IS_APPROX(symm, ldltlo.reconstructedMatrix());
|
||||
vecX = ldltlo.solve(vecB);
|
||||
VERIFY_IS_APPROX(symm * vecX, vecB);
|
||||
matX = ldlt.solve(matB);
|
||||
matX = ldltlo.solve(matB);
|
||||
VERIFY_IS_APPROX(symm * matX, matB);
|
||||
|
||||
LDLT<SquareMatrixType,Upper> ldltup(symmUp);
|
||||
VERIFY_IS_APPROX(symm, ldltup.reconstructedMatrix());
|
||||
vecX = ldltup.solve(vecB);
|
||||
VERIFY_IS_APPROX(symm * vecX, vecB);
|
||||
matX = ldltup.solve(matB);
|
||||
VERIFY_IS_APPROX(symm * matX, matB);
|
||||
|
||||
if(MatrixType::RowsAtCompileTime==Dynamic)
|
||||
{
|
||||
// note : each inplace permutation requires a small temporary vector (mask)
|
||||
|
||||
// check inplace solve
|
||||
matX = matB;
|
||||
VERIFY_EVALUATION_COUNT(matX = ldltlo.solve(matX), 0);
|
||||
VERIFY_IS_APPROX(matX, ldltlo.solve(matB).eval());
|
||||
|
||||
|
||||
matX = matB;
|
||||
VERIFY_EVALUATION_COUNT(matX = ldltup.solve(matX), 0);
|
||||
VERIFY_IS_APPROX(matX, ldltup.solve(matB).eval());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -134,6 +171,7 @@ template<typename MatrixType> void cholesky_verify_assert()
|
||||
|
||||
LLT<MatrixType> llt;
|
||||
VERIFY_RAISES_ASSERT(llt.matrixL())
|
||||
VERIFY_RAISES_ASSERT(llt.matrixU())
|
||||
VERIFY_RAISES_ASSERT(llt.solve(tmp))
|
||||
VERIFY_RAISES_ASSERT(llt.solveInPlace(&tmp))
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// for linear algebra. Eigen itself is part of the KDE project.
|
||||
//
|
||||
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
|
||||
// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
|
||||
//
|
||||
// Eigen is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,6 +24,7 @@
|
||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "main.h"
|
||||
#include <limits>
|
||||
#include <Eigen/Eigenvalues>
|
||||
#include <Eigen/LU>
|
||||
|
||||
@@ -31,12 +33,14 @@
|
||||
template<typename VectorType>
|
||||
void verify_is_approx_upto_permutation(const VectorType& vec1, const VectorType& vec2)
|
||||
{
|
||||
typedef typename NumTraits<typename VectorType::Scalar>::Real RealScalar;
|
||||
|
||||
VERIFY(vec1.cols() == 1);
|
||||
VERIFY(vec2.cols() == 1);
|
||||
VERIFY(vec1.rows() == vec2.rows());
|
||||
for (int k = 1; k <= vec1.rows(); ++k)
|
||||
{
|
||||
VERIFY_IS_APPROX(vec1.array().pow(k).sum(), vec2.array().pow(k).sum());
|
||||
VERIFY_IS_APPROX(vec1.array().pow(RealScalar(k)).sum(), vec2.array().pow(RealScalar(k)).sum());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,14 +63,20 @@ template<typename MatrixType> void eigensolver(const MatrixType& m)
|
||||
MatrixType symmA = a.adjoint() * a;
|
||||
|
||||
ComplexEigenSolver<MatrixType> ei0(symmA);
|
||||
VERIFY_IS_EQUAL(ei0.info(), Success);
|
||||
VERIFY_IS_APPROX(symmA * ei0.eigenvectors(), ei0.eigenvectors() * ei0.eigenvalues().asDiagonal());
|
||||
|
||||
ComplexEigenSolver<MatrixType> ei1(a);
|
||||
VERIFY_IS_EQUAL(ei1.info(), Success);
|
||||
VERIFY_IS_APPROX(a * ei1.eigenvectors(), ei1.eigenvectors() * ei1.eigenvalues().asDiagonal());
|
||||
// Note: If MatrixType is real then a.eigenvalues() uses EigenSolver and thus
|
||||
// another algorithm so results may differ slightly
|
||||
verify_is_approx_upto_permutation(a.eigenvalues(), ei1.eigenvalues());
|
||||
|
||||
|
||||
ComplexEigenSolver<MatrixType> eiNoEivecs(a, false);
|
||||
VERIFY_IS_EQUAL(eiNoEivecs.info(), Success);
|
||||
VERIFY_IS_APPROX(ei1.eigenvalues(), eiNoEivecs.eigenvalues());
|
||||
|
||||
// Regression test for issue #66
|
||||
MatrixType z = MatrixType::Zero(rows,cols);
|
||||
ComplexEigenSolver<MatrixType> eiz(z);
|
||||
@@ -74,6 +84,25 @@ template<typename MatrixType> void eigensolver(const MatrixType& m)
|
||||
|
||||
MatrixType id = MatrixType::Identity(rows, cols);
|
||||
VERIFY_IS_APPROX(id.operatorNorm(), RealScalar(1));
|
||||
|
||||
if (rows > 1)
|
||||
{
|
||||
// Test matrix with NaN
|
||||
a(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
|
||||
ComplexEigenSolver<MatrixType> eiNaN(a);
|
||||
VERIFY_IS_EQUAL(eiNaN.info(), NoConvergence);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename MatrixType> void eigensolver_verify_assert(const MatrixType& m)
|
||||
{
|
||||
ComplexEigenSolver<MatrixType> eig;
|
||||
VERIFY_RAISES_ASSERT(eig.eigenvectors());
|
||||
VERIFY_RAISES_ASSERT(eig.eigenvalues());
|
||||
|
||||
MatrixType a = MatrixType::Random(m.rows(),m.cols());
|
||||
eig.compute(a, false);
|
||||
VERIFY_RAISES_ASSERT(eig.eigenvectors());
|
||||
}
|
||||
|
||||
void test_eigensolver_complex()
|
||||
@@ -85,6 +114,11 @@ void test_eigensolver_complex()
|
||||
CALL_SUBTEST_4( eigensolver(Matrix3f()) );
|
||||
}
|
||||
|
||||
CALL_SUBTEST_1( eigensolver_verify_assert(Matrix4cf()) );
|
||||
CALL_SUBTEST_2( eigensolver_verify_assert(MatrixXcd(14,14)) );
|
||||
CALL_SUBTEST_3( eigensolver_verify_assert(Matrix<std::complex<float>, 1, 1>()) );
|
||||
CALL_SUBTEST_4( eigensolver_verify_assert(Matrix3f()) );
|
||||
|
||||
// Test problem size constructors
|
||||
CALL_SUBTEST_5(ComplexEigenSolver<MatrixXf>(10));
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
||||
// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
|
||||
//
|
||||
// Eigen is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,6 +24,7 @@
|
||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "main.h"
|
||||
#include <limits>
|
||||
#include <Eigen/Eigenvalues>
|
||||
|
||||
#ifdef HAS_GSL
|
||||
@@ -43,36 +45,52 @@ template<typename MatrixType> void eigensolver(const MatrixType& m)
|
||||
typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;
|
||||
typedef typename std::complex<typename NumTraits<typename MatrixType::Scalar>::Real> Complex;
|
||||
|
||||
// RealScalar largerEps = 10*test_precision<RealScalar>();
|
||||
|
||||
MatrixType a = MatrixType::Random(rows,cols);
|
||||
MatrixType a1 = MatrixType::Random(rows,cols);
|
||||
MatrixType symmA = a.adjoint() * a + a1.adjoint() * a1;
|
||||
|
||||
EigenSolver<MatrixType> ei0(symmA);
|
||||
VERIFY_IS_EQUAL(ei0.info(), Success);
|
||||
VERIFY_IS_APPROX(symmA * ei0.pseudoEigenvectors(), ei0.pseudoEigenvectors() * ei0.pseudoEigenvalueMatrix());
|
||||
VERIFY_IS_APPROX((symmA.template cast<Complex>()) * (ei0.pseudoEigenvectors().template cast<Complex>()),
|
||||
(ei0.pseudoEigenvectors().template cast<Complex>()) * (ei0.eigenvalues().asDiagonal()));
|
||||
|
||||
EigenSolver<MatrixType> ei1(a);
|
||||
VERIFY_IS_EQUAL(ei1.info(), Success);
|
||||
VERIFY_IS_APPROX(a * ei1.pseudoEigenvectors(), ei1.pseudoEigenvectors() * ei1.pseudoEigenvalueMatrix());
|
||||
VERIFY_IS_APPROX(a.template cast<Complex>() * ei1.eigenvectors(),
|
||||
ei1.eigenvectors() * ei1.eigenvalues().asDiagonal());
|
||||
VERIFY_IS_APPROX(a.eigenvalues(), ei1.eigenvalues());
|
||||
|
||||
EigenSolver<MatrixType> eiNoEivecs(a, false);
|
||||
VERIFY_IS_EQUAL(eiNoEivecs.info(), Success);
|
||||
VERIFY_IS_APPROX(ei1.eigenvalues(), eiNoEivecs.eigenvalues());
|
||||
VERIFY_IS_APPROX(ei1.pseudoEigenvalueMatrix(), eiNoEivecs.pseudoEigenvalueMatrix());
|
||||
|
||||
MatrixType id = MatrixType::Identity(rows, cols);
|
||||
VERIFY_IS_APPROX(id.operatorNorm(), RealScalar(1));
|
||||
|
||||
if (rows > 2)
|
||||
{
|
||||
// Test matrix with NaN
|
||||
a(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
|
||||
EigenSolver<MatrixType> eiNaN(a);
|
||||
VERIFY_IS_EQUAL(eiNaN.info(), NoConvergence);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename MatrixType> void eigensolver_verify_assert()
|
||||
template<typename MatrixType> void eigensolver_verify_assert(const MatrixType& m)
|
||||
{
|
||||
MatrixType tmp;
|
||||
|
||||
EigenSolver<MatrixType> eig;
|
||||
VERIFY_RAISES_ASSERT(eig.eigenvectors())
|
||||
VERIFY_RAISES_ASSERT(eig.pseudoEigenvectors())
|
||||
VERIFY_RAISES_ASSERT(eig.pseudoEigenvalueMatrix())
|
||||
VERIFY_RAISES_ASSERT(eig.eigenvalues())
|
||||
VERIFY_RAISES_ASSERT(eig.eigenvectors());
|
||||
VERIFY_RAISES_ASSERT(eig.pseudoEigenvectors());
|
||||
VERIFY_RAISES_ASSERT(eig.pseudoEigenvalueMatrix());
|
||||
VERIFY_RAISES_ASSERT(eig.eigenvalues());
|
||||
|
||||
MatrixType a = MatrixType::Random(m.rows(),m.cols());
|
||||
eig.compute(a, false);
|
||||
VERIFY_RAISES_ASSERT(eig.eigenvectors());
|
||||
VERIFY_RAISES_ASSERT(eig.pseudoEigenvectors());
|
||||
}
|
||||
|
||||
void test_eigensolver_generic()
|
||||
@@ -88,11 +106,11 @@ void test_eigensolver_generic()
|
||||
CALL_SUBTEST_4( eigensolver(Matrix2d()) );
|
||||
}
|
||||
|
||||
CALL_SUBTEST_1( eigensolver_verify_assert<Matrix4f>() );
|
||||
CALL_SUBTEST_2( eigensolver_verify_assert<MatrixXd>() );
|
||||
CALL_SUBTEST_4( eigensolver_verify_assert<Matrix2d>() );
|
||||
CALL_SUBTEST_5( eigensolver_verify_assert<MatrixXf>() );
|
||||
CALL_SUBTEST_1( eigensolver_verify_assert(Matrix4f()) );
|
||||
CALL_SUBTEST_2( eigensolver_verify_assert(MatrixXd(17,17)) );
|
||||
CALL_SUBTEST_3( eigensolver_verify_assert(Matrix<double,1,1>()) );
|
||||
CALL_SUBTEST_4( eigensolver_verify_assert(Matrix2d()) );
|
||||
|
||||
// Test problem size constructors
|
||||
CALL_SUBTEST_6(EigenSolver<MatrixXf>(10));
|
||||
CALL_SUBTEST_5(EigenSolver<MatrixXf>(10));
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
||||
// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
|
||||
//
|
||||
// Eigen is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,6 +24,7 @@
|
||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "main.h"
|
||||
#include <limits>
|
||||
#include <Eigen/Eigenvalues>
|
||||
|
||||
#ifdef HAS_GSL
|
||||
@@ -48,10 +50,12 @@ template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)
|
||||
MatrixType a = MatrixType::Random(rows,cols);
|
||||
MatrixType a1 = MatrixType::Random(rows,cols);
|
||||
MatrixType symmA = a.adjoint() * a + a1.adjoint() * a1;
|
||||
symmA.template triangularView<StrictlyUpper>().setZero();
|
||||
|
||||
MatrixType b = MatrixType::Random(rows,cols);
|
||||
MatrixType b1 = MatrixType::Random(rows,cols);
|
||||
MatrixType symmB = b.adjoint() * b + b1.adjoint() * b1;
|
||||
symmB.template triangularView<StrictlyUpper>().setZero();
|
||||
|
||||
SelfAdjointEigenSolver<MatrixType> eiSymm(symmA);
|
||||
// generalized eigen pb
|
||||
@@ -60,6 +64,9 @@ template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)
|
||||
#ifdef HAS_GSL
|
||||
if (ei_is_same_type<RealScalar,double>::ret)
|
||||
{
|
||||
// restore symmA and symmB.
|
||||
symmA = MatrixType(symmA.template selfadjointView<Lower>());
|
||||
symmB = MatrixType(symmB.template selfadjointView<Lower>());
|
||||
typedef GslTraits<Scalar> Gsl;
|
||||
typename Gsl::Matrix gEvec=0, gSymmA=0, gSymmB=0;
|
||||
typename GslTraits<RealScalar>::Vector gEval=0;
|
||||
@@ -89,10 +96,9 @@ template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)
|
||||
VERIFY((symmA * _evec).isApprox(symmB * (_evec * _eval.asDiagonal()), 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";
|
||||
MatrixType normalized_eivec = eiSymmGen.eigenvectors()*eiSymmGen.eigenvectors().colwise().norm().asDiagonal().inverse();
|
||||
VERIFY_IS_APPROX(_eval, eiSymmGen.eigenvalues());
|
||||
VERIFY_IS_APPROX(_evec.cwiseAbs(), eiSymmGen.eigenvectors().cwiseAbs());
|
||||
VERIFY_IS_APPROX(_evec.cwiseAbs(), normalized_eivec.cwiseAbs());
|
||||
|
||||
Gsl::free(gSymmA);
|
||||
Gsl::free(gSymmB);
|
||||
@@ -101,20 +107,46 @@ template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)
|
||||
}
|
||||
#endif
|
||||
|
||||
VERIFY((symmA * eiSymm.eigenvectors()).isApprox(
|
||||
VERIFY_IS_EQUAL(eiSymm.info(), Success);
|
||||
VERIFY((symmA.template selfadjointView<Lower>() * eiSymm.eigenvectors()).isApprox(
|
||||
eiSymm.eigenvectors() * eiSymm.eigenvalues().asDiagonal(), largerEps));
|
||||
VERIFY_IS_APPROX(symmA.template selfadjointView<Lower>().eigenvalues(), eiSymm.eigenvalues());
|
||||
|
||||
SelfAdjointEigenSolver<MatrixType> eiSymmNoEivecs(symmA, false);
|
||||
VERIFY_IS_EQUAL(eiSymmNoEivecs.info(), Success);
|
||||
VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmNoEivecs.eigenvalues());
|
||||
|
||||
// generalized eigen problem Ax = lBx
|
||||
VERIFY((symmA * eiSymmGen.eigenvectors()).isApprox(
|
||||
symmB * (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));
|
||||
VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
|
||||
VERIFY((symmA.template selfadjointView<Lower>() * eiSymmGen.eigenvectors()).isApprox(
|
||||
symmB.template selfadjointView<Lower>() * (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));
|
||||
|
||||
MatrixType sqrtSymmA = eiSymm.operatorSqrt();
|
||||
VERIFY_IS_APPROX(symmA, sqrtSymmA*sqrtSymmA);
|
||||
VERIFY_IS_APPROX(sqrtSymmA, symmA*eiSymm.operatorInverseSqrt());
|
||||
VERIFY_IS_APPROX(MatrixType(symmA.template selfadjointView<Lower>()), sqrtSymmA*sqrtSymmA);
|
||||
VERIFY_IS_APPROX(sqrtSymmA, symmA.template selfadjointView<Lower>()*eiSymm.operatorInverseSqrt());
|
||||
|
||||
MatrixType id = MatrixType::Identity(rows, cols);
|
||||
VERIFY_IS_APPROX(id.template selfadjointView<Lower>().operatorNorm(), RealScalar(1));
|
||||
|
||||
SelfAdjointEigenSolver<MatrixType> eiSymmUninitialized;
|
||||
VERIFY_RAISES_ASSERT(eiSymmUninitialized.info());
|
||||
VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvalues());
|
||||
VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
|
||||
VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
|
||||
VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());
|
||||
|
||||
eiSymmUninitialized.compute(symmA, false);
|
||||
VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
|
||||
VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
|
||||
VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());
|
||||
|
||||
if (rows > 1)
|
||||
{
|
||||
// Test matrix with NaN
|
||||
symmA(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
|
||||
SelfAdjointEigenSolver<MatrixType> eiSymmNaN(symmA);
|
||||
VERIFY_IS_EQUAL(eiSymmNaN.info(), NoConvergence);
|
||||
}
|
||||
}
|
||||
|
||||
void test_eigensolver_selfadjoint()
|
||||
|
||||
@@ -34,6 +34,8 @@ void test_first_aligned_helper(Scalar *array, int size)
|
||||
template<typename Scalar>
|
||||
void test_none_aligned_helper(Scalar *array, int size)
|
||||
{
|
||||
EIGEN_UNUSED_VARIABLE(array);
|
||||
EIGEN_UNUSED_VARIABLE(size);
|
||||
VERIFY(ei_packet_traits<Scalar>::size == 1 || ei_first_aligned(array, size) == size);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,13 @@ template<typename Scalar,int Size> void hessenberg(int size = Size)
|
||||
MatrixType cs2Q = cs2.matrixQ();
|
||||
VERIFY_IS_EQUAL(cs1Q, cs2Q);
|
||||
|
||||
// Test assertions for when used uninitialized
|
||||
HessenbergDecomposition<MatrixType> hessUninitialized;
|
||||
VERIFY_RAISES_ASSERT( hessUninitialized.matrixH() );
|
||||
VERIFY_RAISES_ASSERT( hessUninitialized.matrixQ() );
|
||||
VERIFY_RAISES_ASSERT( hessUninitialized.householderCoefficients() );
|
||||
VERIFY_RAISES_ASSERT( hessUninitialized.packedMatrix() );
|
||||
|
||||
// TODO: Add tests for packedMatrix() and householderCoefficients()
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,37 @@
|
||||
#undef VERIFY_IS_NOT_APPROX
|
||||
#define VERIFY_IS_NOT_APPROX(a, b) VERIFY((a)!=(b));
|
||||
|
||||
template<typename MatrixType> void integer_types(const MatrixType& m)
|
||||
template<typename MatrixType> void signed_integer_type_tests(const MatrixType& m)
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
|
||||
enum { is_signed = (Scalar(-1) > Scalar(0)) ? 0 : 1 };
|
||||
VERIFY(is_signed == 1);
|
||||
|
||||
int rows = m.rows();
|
||||
int cols = m.cols();
|
||||
|
||||
MatrixType m1(rows, cols),
|
||||
m2 = MatrixType::Random(rows, cols),
|
||||
mzero = MatrixType::Zero(rows, cols);
|
||||
|
||||
do {
|
||||
m1 = MatrixType::Random(rows, cols);
|
||||
} while(m1 == mzero || m1 == m2);
|
||||
|
||||
// check linear structure
|
||||
|
||||
Scalar s1;
|
||||
do {
|
||||
s1 = ei_random<Scalar>();
|
||||
} while(s1 == 0);
|
||||
|
||||
VERIFY_IS_EQUAL(-(-m1), m1);
|
||||
VERIFY_IS_EQUAL(-m2+m1+m2, m1);
|
||||
VERIFY_IS_EQUAL((-m1+m2)*s1, -s1*m1+s1*m2);
|
||||
}
|
||||
|
||||
template<typename MatrixType> void integer_type_tests(const MatrixType& m)
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
|
||||
@@ -97,13 +127,10 @@ template<typename MatrixType> void integer_types(const MatrixType& m)
|
||||
s1 = ei_random<Scalar>();
|
||||
} while(s1 == 0);
|
||||
|
||||
VERIFY_IS_EQUAL(-(-m1), m1);
|
||||
VERIFY_IS_EQUAL(m1+m1, 2*m1);
|
||||
VERIFY_IS_EQUAL(m1+m2-m1, m2);
|
||||
VERIFY_IS_EQUAL(-m2+m1+m2, m1);
|
||||
VERIFY_IS_EQUAL(m1*s1, s1*m1);
|
||||
VERIFY_IS_EQUAL((m1+m2)*s1, s1*m1+s1*m2);
|
||||
VERIFY_IS_EQUAL((-m1+m2)*s1, -s1*m1+s1*m2);
|
||||
m3 = m2; m3 += m1;
|
||||
VERIFY_IS_EQUAL(m3, m1+m2);
|
||||
m3 = m2; m3 -= m1;
|
||||
@@ -122,18 +149,26 @@ template<typename MatrixType> void integer_types(const MatrixType& m)
|
||||
void test_integer_types()
|
||||
{
|
||||
for(int i = 0; i < g_repeat; i++) {
|
||||
CALL_SUBTEST_1( integer_types(Matrix<unsigned int, 1, 1>()) );
|
||||
CALL_SUBTEST_1( integer_types(Matrix<unsigned long, 3, 4>()) );
|
||||
CALL_SUBTEST_2( integer_types(Matrix<long, 2, 2>()) );
|
||||
CALL_SUBTEST_1( integer_type_tests(Matrix<unsigned int, 1, 1>()) );
|
||||
CALL_SUBTEST_1( integer_type_tests(Matrix<unsigned long, 3, 4>()) );
|
||||
|
||||
CALL_SUBTEST_3( integer_types(Matrix<char, 2, Dynamic>(2, 10)) );
|
||||
CALL_SUBTEST_4( integer_types(Matrix<unsigned char, 3, 3>()) );
|
||||
CALL_SUBTEST_4( integer_types(Matrix<unsigned char, Dynamic, Dynamic>(20, 20)) );
|
||||
CALL_SUBTEST_2( integer_type_tests(Matrix<long, 2, 2>()) );
|
||||
CALL_SUBTEST_2( signed_integer_type_tests(Matrix<long, 2, 2>()) );
|
||||
|
||||
CALL_SUBTEST_5( integer_types(Matrix<short, Dynamic, 4>(7, 4)) );
|
||||
CALL_SUBTEST_6( integer_types(Matrix<unsigned short, 4, 4>()) );
|
||||
CALL_SUBTEST_3( integer_type_tests(Matrix<char, 2, Dynamic>(2, 10)) );
|
||||
CALL_SUBTEST_3( signed_integer_type_tests(Matrix<char, 2, Dynamic>(2, 10)) );
|
||||
|
||||
CALL_SUBTEST_7( integer_types(Matrix<long long, 11, 13>()) );
|
||||
CALL_SUBTEST_8( integer_types(Matrix<unsigned long long, Dynamic, 5>(1, 5)) );
|
||||
CALL_SUBTEST_4( integer_type_tests(Matrix<unsigned char, 3, 3>()) );
|
||||
CALL_SUBTEST_4( integer_type_tests(Matrix<unsigned char, Dynamic, Dynamic>(20, 20)) );
|
||||
|
||||
CALL_SUBTEST_5( integer_type_tests(Matrix<short, Dynamic, 4>(7, 4)) );
|
||||
CALL_SUBTEST_5( signed_integer_type_tests(Matrix<short, Dynamic, 4>(7, 4)) );
|
||||
|
||||
CALL_SUBTEST_6( integer_type_tests(Matrix<unsigned short, 4, 4>()) );
|
||||
|
||||
CALL_SUBTEST_7( integer_type_tests(Matrix<long long, 11, 13>()) );
|
||||
CALL_SUBTEST_7( signed_integer_type_tests(Matrix<long long, 11, 13>()) );
|
||||
|
||||
CALL_SUBTEST_8( integer_type_tests(Matrix<unsigned long long, Dynamic, 5>(1, 5)) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,10 +78,23 @@ template<typename MatrixType> void inverse(const MatrixType& m)
|
||||
MatrixType m3 = v3*v3.transpose(), m4(rows,cols);
|
||||
m3.computeInverseAndDetWithCheck(m4, det, invertible);
|
||||
VERIFY( rows==1 ? invertible : !invertible );
|
||||
VERIFY_IS_APPROX(det, m3.determinant());
|
||||
VERIFY_IS_MUCH_SMALLER_THAN(ei_abs(det-m3.determinant()), RealScalar(1));
|
||||
m3.computeInverseWithCheck(m4, invertible);
|
||||
VERIFY( rows==1 ? invertible : !invertible );
|
||||
#endif
|
||||
|
||||
// check in-place inversion
|
||||
if(MatrixType::RowsAtCompileTime>=2 && MatrixType::RowsAtCompileTime<=4)
|
||||
{
|
||||
// in-place is forbidden
|
||||
VERIFY_RAISES_ASSERT(m1 = m1.inverse());
|
||||
}
|
||||
else
|
||||
{
|
||||
m2 = m1.inverse();
|
||||
m1 = m1.inverse();
|
||||
VERIFY_IS_APPROX(m1,m2);
|
||||
}
|
||||
}
|
||||
|
||||
void test_inverse()
|
||||
|
||||
@@ -120,7 +120,7 @@ template<typename MatrixType> void lu_invertible()
|
||||
|
||||
MatrixType m1(size, size), m2(size, size), m3(size, size);
|
||||
FullPivLU<MatrixType> lu;
|
||||
lu.setThreshold(0.01);
|
||||
lu.setThreshold(RealScalar(0.01));
|
||||
do {
|
||||
m1 = MatrixType::Random(size,size);
|
||||
lu.compute(m1);
|
||||
|
||||
@@ -368,7 +368,7 @@ inline bool test_isUnitary(const MatrixBase<Derived>& m)
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
bool test_is_equal(T actual, U expected)
|
||||
bool test_is_equal(const T& actual, const U& expected)
|
||||
{
|
||||
if (actual==expected)
|
||||
return true;
|
||||
|
||||
@@ -51,8 +51,8 @@ void testVectorType(const VectorType& base)
|
||||
{
|
||||
typedef typename ei_traits<VectorType>::Scalar Scalar;
|
||||
Scalar low = ei_random<Scalar>(-500,500);
|
||||
Scalar high = ei_random<Scalar>(-500,500);
|
||||
if (low>high) std::swap(low,high);
|
||||
Scalar high = ei_random<Scalar>(-500,500);
|
||||
if (low>high) std::swap(low,high);
|
||||
const int size = base.size();
|
||||
const Scalar step = (high-low)/(size-1);
|
||||
|
||||
@@ -91,7 +91,7 @@ void testVectorType(const VectorType& base)
|
||||
|
||||
Matrix<Scalar,Dynamic,1> size_changer(size+50);
|
||||
size_changer.setLinSpaced(low,high,size);
|
||||
VERIFY( size_changer.size() == size );
|
||||
VERIFY( size_changer.size() == size );
|
||||
}
|
||||
|
||||
template<typename MatrixType>
|
||||
|
||||
@@ -64,9 +64,7 @@ template<typename MatrixType> void inverse_general_4x4(int repeat)
|
||||
double error_avg = error_sum / repeat;
|
||||
EIGEN_DEBUG_VAR(error_avg);
|
||||
EIGEN_DEBUG_VAR(error_max);
|
||||
// FIXME that 1.3 used to be a 1.0 until the NumTraits changes on 28 April 2010, and then a 1.2 until the ReturnByValue/Inverse changes
|
||||
// on 30 May 2010, what's going wrong (if anything) ??
|
||||
VERIFY(error_avg < (NumTraits<Scalar>::IsComplex ? 8.0 : 1.3));
|
||||
VERIFY(error_avg < (NumTraits<Scalar>::IsComplex ? 8.0 : 1.2)); // FIXME that 1.2 used to be a 1.0 until the NumTraits changes on 28 April 2010, what's going wrong??
|
||||
VERIFY(error_max < (NumTraits<Scalar>::IsComplex ? 64.0 : 20.0));
|
||||
}
|
||||
|
||||
|
||||
@@ -71,8 +71,9 @@ template<typename MatrixType> void product(const MatrixType& m)
|
||||
|
||||
Scalar s1 = ei_random<Scalar>();
|
||||
|
||||
int r = ei_random<int>(0, rows-1),
|
||||
c = ei_random<int>(0, cols-1);
|
||||
int r = ei_random<int>(0, rows-1),
|
||||
c = ei_random<int>(0, cols-1),
|
||||
c2 = ei_random<int>(0, cols-1);
|
||||
|
||||
// begin testing Product.h: only associativity for now
|
||||
// (we use Transpose.h but this doesn't count as a test for it)
|
||||
@@ -150,4 +151,8 @@ template<typename MatrixType> void product(const MatrixType& m)
|
||||
{
|
||||
VERIFY(areNotApprox(res2,square2 + m2.transpose() * m1));
|
||||
}
|
||||
|
||||
// inner product
|
||||
Scalar x = square2.row(c) * square2.col(c2);
|
||||
VERIFY_IS_APPROX(x, square2.row(c).transpose().cwiseProduct(square2.col(c2)).sum());
|
||||
}
|
||||
|
||||
@@ -49,5 +49,22 @@ void test_product_large()
|
||||
MatrixXf a = MatrixXf::Random(10,4), b = MatrixXf::Random(4,10), c = a;
|
||||
VERIFY_IS_APPROX((a = a * b), (c * b).eval());
|
||||
}
|
||||
|
||||
{
|
||||
// check the functions to setup blocking sizes compile and do not segfault
|
||||
// FIXME check they do what they are supposed to do !!
|
||||
std::ptrdiff_t l1 = ei_random<int>(10000,20000);
|
||||
std::ptrdiff_t l2 = ei_random<int>(1000000,2000000);
|
||||
setCpuCacheSizes(l1,l2);
|
||||
VERIFY(l1==l1CacheSize());
|
||||
VERIFY(l2==l2CacheSize());
|
||||
std::ptrdiff_t k1 = ei_random<int>(10,100)*16;
|
||||
std::ptrdiff_t m1 = ei_random<int>(10,100)*16;
|
||||
std::ptrdiff_t n1 = ei_random<int>(10,100)*16;
|
||||
setBlockingSizes<float>(k1,m1,n1);
|
||||
std::ptrdiff_t k, m, n;
|
||||
getBlockingSizes<float>(k,m,n);
|
||||
VERIFY(k==k1 && m==m1 && n==n1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "main.h"
|
||||
#include <limits>
|
||||
#include <Eigen/Eigenvalues>
|
||||
|
||||
template<typename MatrixType> void schur(int size = MatrixType::ColsAtCompileTime)
|
||||
@@ -34,6 +35,7 @@ template<typename MatrixType> void schur(int size = MatrixType::ColsAtCompileTim
|
||||
for(int counter = 0; counter < g_repeat; ++counter) {
|
||||
MatrixType A = MatrixType::Random(size, size);
|
||||
ComplexSchur<MatrixType> schurOfA(A);
|
||||
VERIFY_IS_EQUAL(schurOfA.info(), Success);
|
||||
ComplexMatrixType U = schurOfA.matrixU();
|
||||
ComplexMatrixType T = schurOfA.matrixT();
|
||||
for(int row = 1; row < size; ++row) {
|
||||
@@ -48,14 +50,31 @@ template<typename MatrixType> void schur(int size = MatrixType::ColsAtCompileTim
|
||||
ComplexSchur<MatrixType> csUninitialized;
|
||||
VERIFY_RAISES_ASSERT(csUninitialized.matrixT());
|
||||
VERIFY_RAISES_ASSERT(csUninitialized.matrixU());
|
||||
VERIFY_RAISES_ASSERT(csUninitialized.info());
|
||||
|
||||
// Test whether compute() and constructor returns same result
|
||||
MatrixType A = MatrixType::Random(size, size);
|
||||
ComplexSchur<MatrixType> cs1;
|
||||
cs1.compute(A);
|
||||
ComplexSchur<MatrixType> cs2(A);
|
||||
VERIFY_IS_EQUAL(cs1.info(), Success);
|
||||
VERIFY_IS_EQUAL(cs2.info(), Success);
|
||||
VERIFY_IS_EQUAL(cs1.matrixT(), cs2.matrixT());
|
||||
VERIFY_IS_EQUAL(cs1.matrixU(), cs2.matrixU());
|
||||
|
||||
// Test computation of only T, not U
|
||||
ComplexSchur<MatrixType> csOnlyT(A, false);
|
||||
VERIFY_IS_EQUAL(csOnlyT.info(), Success);
|
||||
VERIFY_IS_EQUAL(cs1.matrixT(), csOnlyT.matrixT());
|
||||
VERIFY_RAISES_ASSERT(csOnlyT.matrixU());
|
||||
|
||||
if (size > 1)
|
||||
{
|
||||
// Test matrix with NaN
|
||||
A(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
|
||||
ComplexSchur<MatrixType> csNaN(A);
|
||||
VERIFY_IS_EQUAL(csNaN.info(), NoConvergence);
|
||||
}
|
||||
}
|
||||
|
||||
void test_schur_complex()
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "main.h"
|
||||
#include <limits>
|
||||
#include <Eigen/Eigenvalues>
|
||||
|
||||
template<typename MatrixType> void verifyIsQuasiTriangular(const MatrixType& T)
|
||||
@@ -55,6 +56,7 @@ template<typename MatrixType> void schur(int size = MatrixType::ColsAtCompileTim
|
||||
for(int counter = 0; counter < g_repeat; ++counter) {
|
||||
MatrixType A = MatrixType::Random(size, size);
|
||||
RealSchur<MatrixType> schurOfA(A);
|
||||
VERIFY_IS_EQUAL(schurOfA.info(), Success);
|
||||
MatrixType U = schurOfA.matrixU();
|
||||
MatrixType T = schurOfA.matrixT();
|
||||
verifyIsQuasiTriangular(T);
|
||||
@@ -65,14 +67,31 @@ template<typename MatrixType> void schur(int size = MatrixType::ColsAtCompileTim
|
||||
RealSchur<MatrixType> rsUninitialized;
|
||||
VERIFY_RAISES_ASSERT(rsUninitialized.matrixT());
|
||||
VERIFY_RAISES_ASSERT(rsUninitialized.matrixU());
|
||||
VERIFY_RAISES_ASSERT(rsUninitialized.info());
|
||||
|
||||
// Test whether compute() and constructor returns same result
|
||||
MatrixType A = MatrixType::Random(size, size);
|
||||
RealSchur<MatrixType> rs1;
|
||||
rs1.compute(A);
|
||||
RealSchur<MatrixType> rs2(A);
|
||||
VERIFY_IS_EQUAL(rs1.info(), Success);
|
||||
VERIFY_IS_EQUAL(rs2.info(), Success);
|
||||
VERIFY_IS_EQUAL(rs1.matrixT(), rs2.matrixT());
|
||||
VERIFY_IS_EQUAL(rs1.matrixU(), rs2.matrixU());
|
||||
|
||||
// Test computation of only T, not U
|
||||
RealSchur<MatrixType> rsOnlyT(A, false);
|
||||
VERIFY_IS_EQUAL(rsOnlyT.info(), Success);
|
||||
VERIFY_IS_EQUAL(rs1.matrixT(), rsOnlyT.matrixT());
|
||||
VERIFY_RAISES_ASSERT(rsOnlyT.matrixU());
|
||||
|
||||
if (size > 1)
|
||||
{
|
||||
// Test matrix with NaN
|
||||
A(0,0) = std::numeric_limits<typename MatrixType::Scalar>::quiet_NaN();
|
||||
RealSchur<MatrixType> rsNaN(A);
|
||||
VERIFY_IS_EQUAL(rsNaN.info(), NoConvergence);
|
||||
}
|
||||
}
|
||||
|
||||
void test_schur_real()
|
||||
|
||||
@@ -55,7 +55,7 @@ void test_selfadjoint()
|
||||
{
|
||||
for(int i = 0; i < g_repeat ; i++)
|
||||
{
|
||||
EIGEN_UNUSED int s = ei_random<int>(1,20);
|
||||
int s = ei_random<int>(1,20); EIGEN_UNUSED_VARIABLE(s);
|
||||
|
||||
CALL_SUBTEST_1( selfadjoint(Matrix<float, 1, 1>()) );
|
||||
CALL_SUBTEST_2( selfadjoint(Matrix<float, 2, 2>()) );
|
||||
|
||||
@@ -81,13 +81,13 @@ initSparse(double density,
|
||||
v = Scalar(0);
|
||||
else if ((flags & MakeUpperTriangular) && j<i)
|
||||
v = Scalar(0);
|
||||
|
||||
|
||||
if ((flags&ForceRealDiag) && (i==j))
|
||||
v = ei_real(v);
|
||||
|
||||
|
||||
if (v!=Scalar(0))
|
||||
{
|
||||
sparseMat.insertBack(j,i) = v;
|
||||
sparseMat.insertBackByOuterInner(j,i) = v;
|
||||
if (nonzeroCoords)
|
||||
nonzeroCoords->push_back(Vector2i(i,j));
|
||||
}
|
||||
@@ -126,13 +126,13 @@ initSparse(double density,
|
||||
v = Scalar(0);
|
||||
else if ((flags & MakeUpperTriangular) && j<i)
|
||||
v = Scalar(0);
|
||||
|
||||
|
||||
if ((flags&ForceRealDiag) && (i==j))
|
||||
v = ei_real(v);
|
||||
|
||||
|
||||
if (v!=Scalar(0))
|
||||
{
|
||||
sparseMat.insertBack(j,i) = v;
|
||||
sparseMat.insertBackByOuterInner(j,i) = v;
|
||||
if (nonzeroCoords)
|
||||
nonzeroCoords->push_back(Vector2i(i,j));
|
||||
}
|
||||
|
||||
@@ -323,12 +323,12 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
|
||||
else if (x<0.5)
|
||||
{
|
||||
countFalseNonZero++;
|
||||
m2.insertBack(j,i) = Scalar(0);
|
||||
m2.insertBackByOuterInner(j,i) = Scalar(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
countTrueNonZero++;
|
||||
m2.insertBack(j,i) = refM2(i,j) = Scalar(1);
|
||||
m2.insertBackByOuterInner(j,i) = refM2(i,j) = Scalar(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,26 +149,27 @@ template<typename Scalar> void sparse_solvers(int rows, int cols)
|
||||
}
|
||||
|
||||
// test LDLT
|
||||
if (!NumTraits<Scalar>::IsComplex)
|
||||
{
|
||||
// TODO fix the issue with complex (see SparseLDLT::solveInPlace)
|
||||
SparseMatrix<Scalar> m2(rows, cols);
|
||||
DenseMatrix refMat2(rows, cols);
|
||||
|
||||
DenseVector b = DenseVector::Random(cols);
|
||||
DenseVector refX(cols), x(cols);
|
||||
|
||||
// initSPD(density, refMat2, m2);
|
||||
initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular, 0, 0);
|
||||
refMat2 += (refMat2.adjoint()).eval();
|
||||
refMat2.diagonal() *= 0.5;
|
||||
for(int i=0; i<rows; ++i)
|
||||
m2.coeffRef(i,i) = refMat2(i,i) = ei_abs(ei_real(refMat2(i,i)));
|
||||
|
||||
refX = refMat2.llt().solve(b); // FIXME use LLT to compute the reference because LDLT seems to fail with large matrices
|
||||
refX = refMat2.template selfadjointView<Upper>().llt().solve(b);
|
||||
// FIXME use LLT to compute the reference because LDLT seems to fail with large matrices
|
||||
typedef SparseMatrix<Scalar,Upper|SelfAdjoint> SparseSelfAdjointMatrix;
|
||||
x = b;
|
||||
SparseLDLT<SparseSelfAdjointMatrix> ldlt(m2);
|
||||
if (ldlt.succeeded())
|
||||
ldlt.solveInPlace(x);
|
||||
else
|
||||
std::cerr << "warning LDLT failed\n";
|
||||
|
||||
VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LDLT: default");
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,11 @@
|
||||
|
||||
#include "main.h"
|
||||
|
||||
template<typename T> bool isFinite(const T& x)
|
||||
{
|
||||
return x==x && x>=NumTraits<T>::lowest() && x<=NumTraits<T>::highest();
|
||||
}
|
||||
|
||||
template<typename MatrixType> void stable_norm(const MatrixType& m)
|
||||
{
|
||||
/* this test covers the following files:
|
||||
@@ -50,7 +55,7 @@ template<typename MatrixType> void stable_norm(const MatrixType& m)
|
||||
int rows = m.rows();
|
||||
int cols = m.cols();
|
||||
|
||||
Scalar big = ei_abs(ei_random<Scalar>()) * (std::numeric_limits<RealScalar>::max() * RealScalar(1e-4));
|
||||
Scalar big = ei_random<Scalar>() * (std::numeric_limits<RealScalar>::max() * RealScalar(1e-4));
|
||||
Scalar small = static_cast<RealScalar>(1)/big;
|
||||
|
||||
MatrixType vzero = MatrixType::Zero(rows, cols),
|
||||
@@ -68,22 +73,35 @@ template<typename MatrixType> void stable_norm(const MatrixType& m)
|
||||
|
||||
RealScalar size = static_cast<RealScalar>(m.size());
|
||||
|
||||
// test overflow
|
||||
/* VERIFY_IS_NOT_APPROX(static_cast<Scalar>(vbig.norm()), ei_sqrt(size)*big); // here the default norm must fail
|
||||
Does not succeed on gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1, Intel Core 2 Duo T7300 with no SSE optimizations
|
||||
*/
|
||||
// test isFinite
|
||||
VERIFY(!isFinite( std::numeric_limits<RealScalar>::infinity()));
|
||||
VERIFY(!isFinite(ei_sqrt(-ei_abs(big))));
|
||||
|
||||
VERIFY_IS_APPROX(static_cast<Scalar>(vbig.stableNorm()), ei_sqrt(size)*big);
|
||||
VERIFY_IS_APPROX(static_cast<Scalar>(vbig.blueNorm()), ei_sqrt(size)*big);
|
||||
VERIFY_IS_APPROX(static_cast<Scalar>(vbig.hypotNorm()), ei_sqrt(size)*big);
|
||||
// test overflow
|
||||
VERIFY(isFinite(ei_sqrt(size)*ei_abs(big)));
|
||||
#ifdef EIGEN_VECTORIZE_SSE
|
||||
// since x87 FPU uses 80bits of precision overflow is not detected
|
||||
if(ei_packet_traits<Scalar>::size>1)
|
||||
{
|
||||
VERIFY_IS_NOT_APPROX(static_cast<Scalar>(vbig.norm()), ei_sqrt(size)*big); // here the default norm must fail
|
||||
}
|
||||
#endif
|
||||
VERIFY_IS_APPROX(vbig.stableNorm(), ei_sqrt(size)*ei_abs(big));
|
||||
VERIFY_IS_APPROX(vbig.blueNorm(), ei_sqrt(size)*ei_abs(big));
|
||||
VERIFY_IS_APPROX(vbig.hypotNorm(), ei_sqrt(size)*ei_abs(big));
|
||||
|
||||
// test underflow
|
||||
/* VERIFY_IS_NOT_APPROX(static_cast<Scalar>(vsmall.norm()), ei_sqrt(size)*small); // here the default norm must fail
|
||||
Does not succeed on gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1, Intel Core 2 Duo T7300 with no SSE optimizations
|
||||
*/
|
||||
VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.stableNorm()), ei_sqrt(size)*small);
|
||||
VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.blueNorm()), ei_sqrt(size)*small);
|
||||
VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.hypotNorm()), ei_sqrt(size)*small);
|
||||
VERIFY(isFinite(ei_sqrt(size)*ei_abs(small)));
|
||||
#ifdef EIGEN_VECTORIZE_SSE
|
||||
// since x87 FPU uses 80bits of precision underflow is not detected
|
||||
if(ei_packet_traits<Scalar>::size>1)
|
||||
{
|
||||
VERIFY_IS_NOT_APPROX(static_cast<Scalar>(vsmall.norm()), ei_sqrt(size)*small); // here the default norm must fail
|
||||
}
|
||||
#endif
|
||||
VERIFY_IS_APPROX(vsmall.stableNorm(), ei_sqrt(size)*ei_abs(small));
|
||||
VERIFY_IS_APPROX(vsmall.blueNorm(), ei_sqrt(size)*ei_abs(small));
|
||||
VERIFY_IS_APPROX(vsmall.hypotNorm(), ei_sqrt(size)*ei_abs(small));
|
||||
|
||||
// Test compilation of cwise() version
|
||||
VERIFY_IS_APPROX(vrand.colwise().stableNorm(), vrand.colwise().norm());
|
||||
|
||||
@@ -48,8 +48,13 @@ void check_stdlist_matrix(const MatrixType& m)
|
||||
++wi;
|
||||
}
|
||||
|
||||
v.resize(21);
|
||||
v.resize(21);
|
||||
v.back() = x;
|
||||
if (!test_ei_isApprox(v.back(),x))
|
||||
{
|
||||
std::cout << x << std::endl;
|
||||
std::cout << v.back() << std::endl;
|
||||
}
|
||||
VERIFY_IS_APPROX(v.back(), x);
|
||||
v.resize(22,y);
|
||||
VERIFY_IS_APPROX(v.back(), y);
|
||||
@@ -112,6 +117,11 @@ void check_stdlist_quaternion(const QuaternionType&)
|
||||
v.resize(22,y);
|
||||
VERIFY_IS_APPROX(v.back(), y);
|
||||
v.push_back(x);
|
||||
if (!test_ei_isApprox(v.back(),x))
|
||||
{
|
||||
std::cout << x << std::endl;
|
||||
std::cout << v.back() << std::endl;
|
||||
}
|
||||
VERIFY_IS_APPROX(v.back(), x);
|
||||
}
|
||||
|
||||
|
||||
@@ -235,8 +235,8 @@ void test_triangular()
|
||||
{
|
||||
for(int i = 0; i < g_repeat ; i++)
|
||||
{
|
||||
EIGEN_UNUSED int r = ei_random<int>(2,20);
|
||||
EIGEN_UNUSED int c = ei_random<int>(2,20);
|
||||
int r = ei_random<int>(2,20); EIGEN_UNUSED_VARIABLE(r);
|
||||
int c = ei_random<int>(2,20); EIGEN_UNUSED_VARIABLE(c);
|
||||
|
||||
CALL_SUBTEST_1( triangular_square(Matrix<float, 1, 1>()) );
|
||||
CALL_SUBTEST_2( triangular_square(Matrix<float, 2, 2>()) );
|
||||
|
||||
@@ -52,5 +52,8 @@ void test_unalignedcount()
|
||||
VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0,40) -= b.segment(0,40), 10, 10, 10, 0);
|
||||
VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0,40) *= 3.5, 10, 0, 10, 0);
|
||||
VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0,40) /= 3.5, 10, 0, 10, 0);
|
||||
#else
|
||||
// The following line is to eliminate "variable not used" warnings
|
||||
nb_load = nb_loadu = nb_store = nb_storeu = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user