aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2014-07-18 11:02:22 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2014-07-18 11:02:22 +0200
commita325d1cb1e607c36d602b1cad9a57b05c60050fa (patch)
tree0c4576947946af90cb8587a4ccbf7030c5b8f772 /test
parent2bdb3b1afdbc07d54fec43edff92138f82492941 (diff)
parentda62eb22e497d864ccaed93907818a384bad8e2a (diff)
merge with default branch
Diffstat (limited to 'test')
-rw-r--r--test/jacobisvd.cpp88
-rw-r--r--test/meta.cpp24
-rw-r--r--test/product_large.cpp9
-rw-r--r--test/product_trsolve.cpp18
-rw-r--r--test/sparse_product.cpp43
5 files changed, 140 insertions, 42 deletions
diff --git a/test/jacobisvd.cpp b/test/jacobisvd.cpp
index d441a6eca..36721b496 100644
--- a/test/jacobisvd.cpp
+++ b/test/jacobisvd.cpp
@@ -67,6 +67,7 @@ template<typename MatrixType, int QRPreconditioner>
void jacobisvd_solve(const MatrixType& m, unsigned int computationOptions)
{
typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
typedef typename MatrixType::Index Index;
Index rows = m.rows();
Index cols = m.cols();
@@ -81,9 +82,37 @@ void jacobisvd_solve(const MatrixType& m, unsigned int computationOptions)
RhsType rhs = RhsType::Random(rows, internal::random<Index>(1, cols));
JacobiSVD<MatrixType, QRPreconditioner> svd(m, computationOptions);
+
+ if(internal::is_same<RealScalar,double>::value) svd.setThreshold(1e-8);
+ else if(internal::is_same<RealScalar,float>::value) svd.setThreshold(1e-4);
+
SolutionType x = svd.solve(rhs);
+
+ RealScalar residual = (m*x-rhs).norm();
+ // Check that there is no significantly better solution in the neighborhood of x
+ if(!test_isMuchSmallerThan(residual,rhs.norm()))
+ {
+ // If the residual is very small, then we have an exact solution, so we are already good.
+ for(int k=0;k<x.rows();++k)
+ {
+ SolutionType y(x);
+ y.row(k).array() += 2*NumTraits<RealScalar>::epsilon();
+ RealScalar residual_y = (m*y-rhs).norm();
+ VERIFY( test_isApprox(residual_y,residual) || residual < residual_y );
+
+ y.row(k) = x.row(k).array() - 2*NumTraits<RealScalar>::epsilon();
+ residual_y = (m*y-rhs).norm();
+ VERIFY( test_isApprox(residual_y,residual) || residual < residual_y );
+ }
+ }
+
// evaluate normal equation which works also for least-squares solutions
- VERIFY_IS_APPROX(m.adjoint()*m*x,m.adjoint()*rhs);
+ if(internal::is_same<RealScalar,double>::value)
+ {
+ // This test is not stable with single precision.
+ // This is probably because squaring m signicantly affects the precision.
+ VERIFY_IS_APPROX(m.adjoint()*m*x,m.adjoint()*rhs);
+ }
// check minimal norm solutions
{
@@ -139,10 +168,9 @@ void jacobisvd_test_all_computation_options(const MatrixType& m)
if (QRPreconditioner == NoQRPreconditioner && m.rows() != m.cols())
return;
JacobiSVD<MatrixType, QRPreconditioner> fullSvd(m, ComputeFullU|ComputeFullV);
-
- jacobisvd_check_full(m, fullSvd);
- jacobisvd_solve<MatrixType, QRPreconditioner>(m, ComputeFullU | ComputeFullV);
-
+ CALL_SUBTEST(( jacobisvd_check_full(m, fullSvd) ));
+ CALL_SUBTEST(( jacobisvd_solve<MatrixType, QRPreconditioner>(m, ComputeFullU | ComputeFullV) ));
+
#if defined __INTEL_COMPILER
// remark #111: statement is unreachable
#pragma warning disable 111
@@ -150,20 +178,20 @@ void jacobisvd_test_all_computation_options(const MatrixType& m)
if(QRPreconditioner == FullPivHouseholderQRPreconditioner)
return;
- jacobisvd_compare_to_full(m, ComputeFullU, fullSvd);
- jacobisvd_compare_to_full(m, ComputeFullV, fullSvd);
- jacobisvd_compare_to_full(m, 0, fullSvd);
+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeFullU, fullSvd) ));
+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeFullV, fullSvd) ));
+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, 0, fullSvd) ));
if (MatrixType::ColsAtCompileTime == Dynamic) {
// thin U/V are only available with dynamic number of columns
- jacobisvd_compare_to_full(m, ComputeFullU|ComputeThinV, fullSvd);
- jacobisvd_compare_to_full(m, ComputeThinV, fullSvd);
- jacobisvd_compare_to_full(m, ComputeThinU|ComputeFullV, fullSvd);
- jacobisvd_compare_to_full(m, ComputeThinU , fullSvd);
- jacobisvd_compare_to_full(m, ComputeThinU|ComputeThinV, fullSvd);
- jacobisvd_solve<MatrixType, QRPreconditioner>(m, ComputeFullU | ComputeThinV);
- jacobisvd_solve<MatrixType, QRPreconditioner>(m, ComputeThinU | ComputeFullV);
- jacobisvd_solve<MatrixType, QRPreconditioner>(m, ComputeThinU | ComputeThinV);
+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeFullU|ComputeThinV, fullSvd) ));
+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeThinV, fullSvd) ));
+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeThinU|ComputeFullV, fullSvd) ));
+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeThinU , fullSvd) ));
+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeThinU|ComputeThinV, fullSvd) ));
+ CALL_SUBTEST(( jacobisvd_solve<MatrixType, QRPreconditioner>(m, ComputeFullU | ComputeThinV) ));
+ CALL_SUBTEST(( jacobisvd_solve<MatrixType, QRPreconditioner>(m, ComputeThinU | ComputeFullV) ));
+ CALL_SUBTEST(( jacobisvd_solve<MatrixType, QRPreconditioner>(m, ComputeThinU | ComputeThinV) ));
// test reconstruction
typedef typename MatrixType::Index Index;
@@ -176,12 +204,29 @@ void jacobisvd_test_all_computation_options(const MatrixType& m)
template<typename MatrixType>
void jacobisvd(const MatrixType& a = MatrixType(), bool pickrandom = true)
{
- MatrixType m = pickrandom ? MatrixType::Random(a.rows(), a.cols()) : a;
+ MatrixType m = a;
+ if(pickrandom)
+ {
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+ typedef typename MatrixType::Index Index;
+ Index diagSize = (std::min)(a.rows(), a.cols());
+ RealScalar s = std::numeric_limits<RealScalar>::max_exponent10/4;
+ s = internal::random<RealScalar>(1,s);
+ Matrix<RealScalar,Dynamic,1> d = Matrix<RealScalar,Dynamic,1>::Random(diagSize);
+ for(Index k=0; k<diagSize; ++k)
+ d(k) = d(k)*std::pow(RealScalar(10),internal::random<RealScalar>(-s,s));
+ m = Matrix<Scalar,Dynamic,Dynamic>::Random(a.rows(),diagSize) * d.asDiagonal() * Matrix<Scalar,Dynamic,Dynamic>::Random(diagSize,a.cols());
+ // cancel some coeffs
+ Index n = internal::random<Index>(0,m.size()-1);
+ for(Index i=0; i<n; ++i)
+ m(internal::random<Index>(0,m.rows()-1), internal::random<Index>(0,m.cols()-1)) = Scalar(0);
+ }
- jacobisvd_test_all_computation_options<MatrixType, FullPivHouseholderQRPreconditioner>(m);
- jacobisvd_test_all_computation_options<MatrixType, ColPivHouseholderQRPreconditioner>(m);
- jacobisvd_test_all_computation_options<MatrixType, HouseholderQRPreconditioner>(m);
- jacobisvd_test_all_computation_options<MatrixType, NoQRPreconditioner>(m);
+ CALL_SUBTEST(( jacobisvd_test_all_computation_options<MatrixType, FullPivHouseholderQRPreconditioner>(m) ));
+ CALL_SUBTEST(( jacobisvd_test_all_computation_options<MatrixType, ColPivHouseholderQRPreconditioner>(m) ));
+ CALL_SUBTEST(( jacobisvd_test_all_computation_options<MatrixType, HouseholderQRPreconditioner>(m) ));
+ CALL_SUBTEST(( jacobisvd_test_all_computation_options<MatrixType, NoQRPreconditioner>(m) ));
}
template<typename MatrixType> void jacobisvd_verify_assert(const MatrixType& m)
@@ -384,6 +429,7 @@ void test_jacobisvd()
TEST_SET_BUT_UNUSED_VARIABLE(r)
TEST_SET_BUT_UNUSED_VARIABLE(c)
+ CALL_SUBTEST_10(( jacobisvd<MatrixXd>(MatrixXd(r,c)) ));
CALL_SUBTEST_7(( jacobisvd<MatrixXf>(MatrixXf(r,c)) ));
CALL_SUBTEST_8(( jacobisvd<MatrixXcd>(MatrixXcd(r,c)) ));
(void) r;
diff --git a/test/meta.cpp b/test/meta.cpp
index 3302c5887..b8dea68e8 100644
--- a/test/meta.cpp
+++ b/test/meta.cpp
@@ -9,6 +9,12 @@
#include "main.h"
+template<typename From, typename To>
+bool check_is_convertible(const From&, const To&)
+{
+ return internal::is_convertible<From,To>::value;
+}
+
void test_meta()
{
VERIFY((internal::conditional<(3<4),internal::true_type, internal::false_type>::type::value));
@@ -52,6 +58,24 @@ void test_meta()
VERIFY(( internal::is_same<const float,internal::remove_pointer<const float*>::type >::value));
VERIFY(( internal::is_same<float,internal::remove_pointer<float* const >::type >::value));
+ VERIFY(( internal::is_convertible<float,double>::value ));
+ VERIFY(( internal::is_convertible<int,double>::value ));
+ VERIFY(( internal::is_convertible<double,int>::value ));
+ VERIFY((!internal::is_convertible<std::complex<double>,double>::value ));
+ VERIFY(( internal::is_convertible<Array33f,Matrix3f>::value ));
+// VERIFY((!internal::is_convertible<Matrix3f,Matrix3d>::value )); //does not work because the conversion is prevented by a static assertion
+ VERIFY((!internal::is_convertible<Array33f,int>::value ));
+ VERIFY((!internal::is_convertible<MatrixXf,float>::value ));
+ {
+ float f;
+ MatrixXf A, B;
+ VectorXf a, b;
+ VERIFY(( check_is_convertible(a.dot(b), f) ));
+ VERIFY(( check_is_convertible(a.transpose()*b, f) ));
+ VERIFY((!check_is_convertible(A*B, f) ));
+ VERIFY(( check_is_convertible(A*B, A) ));
+ }
+
VERIFY(internal::meta_sqrt<1>::ret == 1);
#define VERIFY_META_SQRT(X) VERIFY(internal::meta_sqrt<X>::ret == int(std::sqrt(double(X))))
VERIFY_META_SQRT(2);
diff --git a/test/product_large.cpp b/test/product_large.cpp
index 03d7bd8ed..11531aa1d 100644
--- a/test/product_large.cpp
+++ b/test/product_large.cpp
@@ -61,4 +61,13 @@ void test_product_large()
VERIFY_IS_APPROX(r2, (mat1.row(2)*mat2).eval());
}
#endif
+
+ // Regression test for bug 714:
+#ifdef EIGEN_HAS_OPENMP
+ std::cout << "Testing omp_set_dynamic(1)\n";
+ omp_set_dynamic(1);
+ for(int i = 0; i < g_repeat; i++) {
+ CALL_SUBTEST_6( product(Matrix<float,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
+ }
+#endif
}
diff --git a/test/product_trsolve.cpp b/test/product_trsolve.cpp
index 69892b3a8..4b97fa9d6 100644
--- a/test/product_trsolve.cpp
+++ b/test/product_trsolve.cpp
@@ -84,10 +84,18 @@ void test_product_trsolve()
CALL_SUBTEST_4((trsolve<std::complex<double>,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2),internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))));
// vectors
- CALL_SUBTEST_1((trsolve<float,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
- CALL_SUBTEST_5((trsolve<std::complex<double>,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
- CALL_SUBTEST_6((trsolve<float,1,1>()));
- CALL_SUBTEST_7((trsolve<float,1,2>()));
- CALL_SUBTEST_8((trsolve<std::complex<float>,4,1>()));
+ CALL_SUBTEST_5((trsolve<float,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
+ CALL_SUBTEST_6((trsolve<double,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
+ CALL_SUBTEST_7((trsolve<std::complex<float>,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
+ CALL_SUBTEST_8((trsolve<std::complex<double>,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
+
+ // meta-unrollers
+ CALL_SUBTEST_9((trsolve<float,4,1>()));
+ CALL_SUBTEST_10((trsolve<double,4,1>()));
+ CALL_SUBTEST_11((trsolve<std::complex<float>,4,1>()));
+ CALL_SUBTEST_12((trsolve<float,1,1>()));
+ CALL_SUBTEST_13((trsolve<float,1,2>()));
+ CALL_SUBTEST_14((trsolve<float,3,1>()));
+
}
}
diff --git a/test/sparse_product.cpp b/test/sparse_product.cpp
index 6d32132bc..27bc548f8 100644
--- a/test/sparse_product.cpp
+++ b/test/sparse_product.cpp
@@ -108,28 +108,39 @@ template<typename SparseMatrixType> void sparse_product()
Index r = internal::random<Index>(0,rows-1);
Index c1 = internal::random<Index>(0,cols-1);
Index r1 = internal::random<Index>(0,depth-1);
+ DenseMatrix dm5 = DenseMatrix::Random(depth, cols);
- VERIFY_IS_APPROX( m4=m2.col(c)*refMat3.col(c1).transpose(), refMat4=refMat2.col(c)*refMat3.col(c1).transpose());
- VERIFY_IS_APPROX( m4=m2.middleCols(c,1)*refMat3.col(c1).transpose(), refMat4=refMat2.col(c)*refMat3.col(c1).transpose());
- VERIFY_IS_APPROX(dm4=m2.col(c)*refMat3.col(c1).transpose(), refMat4=refMat2.col(c)*refMat3.col(c1).transpose());
+ VERIFY_IS_APPROX( m4=m2.col(c)*dm5.col(c1).transpose(), refMat4=refMat2.col(c)*dm5.col(c1).transpose());
+ VERIFY_IS_EQUAL(m4.nonZeros(), (refMat4.array()!=0).count());
+ VERIFY_IS_APPROX( m4=m2.middleCols(c,1)*dm5.col(c1).transpose(), refMat4=refMat2.col(c)*dm5.col(c1).transpose());
+ VERIFY_IS_EQUAL(m4.nonZeros(), (refMat4.array()!=0).count());
+ VERIFY_IS_APPROX(dm4=m2.col(c)*dm5.col(c1).transpose(), refMat4=refMat2.col(c)*dm5.col(c1).transpose());
- VERIFY_IS_APPROX(m4=refMat3.col(c1)*m2.col(c).transpose(), refMat4=refMat3.col(c1)*refMat2.col(c).transpose());
- VERIFY_IS_APPROX(m4=refMat3.col(c1)*m2.middleCols(c,1).transpose(), refMat4=refMat3.col(c1)*refMat2.col(c).transpose());
- VERIFY_IS_APPROX(dm4=refMat3.col(c1)*m2.col(c).transpose(), refMat4=refMat3.col(c1)*refMat2.col(c).transpose());
+ VERIFY_IS_APPROX(m4=dm5.col(c1)*m2.col(c).transpose(), refMat4=dm5.col(c1)*refMat2.col(c).transpose());
+ VERIFY_IS_EQUAL(m4.nonZeros(), (refMat4.array()!=0).count());
+ VERIFY_IS_APPROX(m4=dm5.col(c1)*m2.middleCols(c,1).transpose(), refMat4=dm5.col(c1)*refMat2.col(c).transpose());
+ VERIFY_IS_EQUAL(m4.nonZeros(), (refMat4.array()!=0).count());
+ VERIFY_IS_APPROX(dm4=dm5.col(c1)*m2.col(c).transpose(), refMat4=dm5.col(c1)*refMat2.col(c).transpose());
- VERIFY_IS_APPROX( m4=refMat3.row(r1).transpose()*m2.col(c).transpose(), refMat4=refMat3.row(r1).transpose()*refMat2.col(c).transpose());
- VERIFY_IS_APPROX(dm4=refMat3.row(r1).transpose()*m2.col(c).transpose(), refMat4=refMat3.row(r1).transpose()*refMat2.col(c).transpose());
+ VERIFY_IS_APPROX( m4=dm5.row(r1).transpose()*m2.col(c).transpose(), refMat4=dm5.row(r1).transpose()*refMat2.col(c).transpose());
+ VERIFY_IS_EQUAL(m4.nonZeros(), (refMat4.array()!=0).count());
+ VERIFY_IS_APPROX(dm4=dm5.row(r1).transpose()*m2.col(c).transpose(), refMat4=dm5.row(r1).transpose()*refMat2.col(c).transpose());
- VERIFY_IS_APPROX( m4=m2.row(r).transpose()*refMat3.col(c1).transpose(), refMat4=refMat2.row(r).transpose()*refMat3.col(c1).transpose());
- VERIFY_IS_APPROX( m4=m2.middleRows(r,1).transpose()*refMat3.col(c1).transpose(), refMat4=refMat2.row(r).transpose()*refMat3.col(c1).transpose());
- VERIFY_IS_APPROX(dm4=m2.row(r).transpose()*refMat3.col(c1).transpose(), refMat4=refMat2.row(r).transpose()*refMat3.col(c1).transpose());
+ VERIFY_IS_APPROX( m4=m2.row(r).transpose()*dm5.col(c1).transpose(), refMat4=refMat2.row(r).transpose()*dm5.col(c1).transpose());
+ VERIFY_IS_EQUAL(m4.nonZeros(), (refMat4.array()!=0).count());
+ VERIFY_IS_APPROX( m4=m2.middleRows(r,1).transpose()*dm5.col(c1).transpose(), refMat4=refMat2.row(r).transpose()*dm5.col(c1).transpose());
+ VERIFY_IS_EQUAL(m4.nonZeros(), (refMat4.array()!=0).count());
+ VERIFY_IS_APPROX(dm4=m2.row(r).transpose()*dm5.col(c1).transpose(), refMat4=refMat2.row(r).transpose()*dm5.col(c1).transpose());
- VERIFY_IS_APPROX( m4=refMat3.col(c1)*m2.row(r), refMat4=refMat3.col(c1)*refMat2.row(r));
- VERIFY_IS_APPROX( m4=refMat3.col(c1)*m2.middleRows(r,1), refMat4=refMat3.col(c1)*refMat2.row(r));
- VERIFY_IS_APPROX(dm4=refMat3.col(c1)*m2.row(r), refMat4=refMat3.col(c1)*refMat2.row(r));
+ VERIFY_IS_APPROX( m4=dm5.col(c1)*m2.row(r), refMat4=dm5.col(c1)*refMat2.row(r));
+ VERIFY_IS_EQUAL(m4.nonZeros(), (refMat4.array()!=0).count());
+ VERIFY_IS_APPROX( m4=dm5.col(c1)*m2.middleRows(r,1), refMat4=dm5.col(c1)*refMat2.row(r));
+ VERIFY_IS_EQUAL(m4.nonZeros(), (refMat4.array()!=0).count());
+ VERIFY_IS_APPROX(dm4=dm5.col(c1)*m2.row(r), refMat4=dm5.col(c1)*refMat2.row(r));
- VERIFY_IS_APPROX( m4=refMat3.row(r1).transpose()*m2.row(r), refMat4=refMat3.row(r1).transpose()*refMat2.row(r));
- VERIFY_IS_APPROX(dm4=refMat3.row(r1).transpose()*m2.row(r), refMat4=refMat3.row(r1).transpose()*refMat2.row(r));
+ VERIFY_IS_APPROX( m4=dm5.row(r1).transpose()*m2.row(r), refMat4=dm5.row(r1).transpose()*refMat2.row(r));
+ VERIFY_IS_EQUAL(m4.nonZeros(), (refMat4.array()!=0).count());
+ VERIFY_IS_APPROX(dm4=dm5.row(r1).transpose()*m2.row(r), refMat4=dm5.row(r1).transpose()*refMat2.row(r));
}
VERIFY_IS_APPROX(m6=m6*m6, refMat6=refMat6*refMat6);