aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2014-09-14 17:34:54 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2014-09-14 17:34:54 +0200
commit749b56f6af4f712ccc4235a4faf7c13e09b9f3a3 (patch)
treebf77d6d609fee4e8dcf3b354582906502a4b1b90 /test
parentaf9c9f7706bb7701a7224827e981ecc2f3bd9ac7 (diff)
parent9452eb38f812194a676edc1b9eb9d08b7bc0f297 (diff)
merge with default branch
Diffstat (limited to 'test')
-rw-r--r--test/jacobisvd.cpp52
-rw-r--r--test/linearstructure.cpp26
-rw-r--r--test/product.h8
-rw-r--r--test/stable_norm.cpp69
-rw-r--r--test/upperbidiagonalization.cpp2
5 files changed, 148 insertions, 9 deletions
diff --git a/test/jacobisvd.cpp b/test/jacobisvd.cpp
index 36721b496..cd04db5be 100644
--- a/test/jacobisvd.cpp
+++ b/test/jacobisvd.cpp
@@ -315,16 +315,30 @@ void jacobisvd_inf_nan()
VERIFY(sub(some_inf, some_inf) != sub(some_inf, some_inf));
svd.compute(MatrixType::Constant(10,10,some_inf), ComputeFullU | ComputeFullV);
- Scalar some_nan = zero<Scalar>() / zero<Scalar>();
- VERIFY(some_nan != some_nan);
- svd.compute(MatrixType::Constant(10,10,some_nan), ComputeFullU | ComputeFullV);
+ Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
+ VERIFY(nan != nan);
+ svd.compute(MatrixType::Constant(10,10,nan), ComputeFullU | ComputeFullV);
MatrixType m = MatrixType::Zero(10,10);
m(internal::random<int>(0,9), internal::random<int>(0,9)) = some_inf;
svd.compute(m, ComputeFullU | ComputeFullV);
m = MatrixType::Zero(10,10);
- m(internal::random<int>(0,9), internal::random<int>(0,9)) = some_nan;
+ m(internal::random<int>(0,9), internal::random<int>(0,9)) = nan;
+ svd.compute(m, ComputeFullU | ComputeFullV);
+
+ // regression test for bug 791
+ m.resize(3,3);
+ m << 0, 2*NumTraits<Scalar>::epsilon(), 0.5,
+ 0, -0.5, 0,
+ nan, 0, 0;
+ svd.compute(m, ComputeFullU | ComputeFullV);
+
+ m.resize(4,4);
+ m << 1, 0, 0, 0,
+ 0, 3, 1, 2e-308,
+ 1, 0, 1, nan,
+ 0, nan, nan, 0;
svd.compute(m, ComputeFullU | ComputeFullV);
}
@@ -340,11 +354,33 @@ void jacobisvd_underoverflow()
Matrix2d M;
M << -7.90884e-313, -4.94e-324,
0, 5.60844e-313;
+ JacobiSVD<Matrix2d> svd;
+ svd.compute(M,ComputeFullU|ComputeFullV);
+ jacobisvd_check_full(M,svd);
+
+ VectorXd value_set(9);
+ value_set << 0, 1, -1, 5.60844e-313, -5.60844e-313, 4.94e-324, -4.94e-324, -4.94e-223, 4.94e-223;
+ Array4i id(0,0,0,0);
+ int k = 0;
+ do
+ {
+ M << value_set(id(0)), value_set(id(1)), value_set(id(2)), value_set(id(3));
+ svd.compute(M,ComputeFullU|ComputeFullV);
+ jacobisvd_check_full(M,svd);
+
+ id(k)++;
+ if(id(k)>=value_set.size())
+ {
+ while(k<3 && id(k)>=value_set.size()) id(++k)++;
+ id.head(k).setZero();
+ k=0;
+ }
+
+ } while((id<int(value_set.size())).all());
+
#if defined __INTEL_COMPILER
#pragma warning pop
#endif
- JacobiSVD<Matrix2d> svd;
- svd.compute(M); // just check we don't loop indefinitely
// Check for overflow:
Matrix3d M3;
@@ -353,7 +389,8 @@ void jacobisvd_underoverflow()
-8.7190887618028355e+307, -7.3453213709232193e+307, -2.4367363684472105e+307;
JacobiSVD<Matrix3d> svd3;
- svd3.compute(M3); // just check we don't loop indefinitely
+ svd3.compute(M3,ComputeFullU|ComputeFullV); // just check we don't loop indefinitely
+ jacobisvd_check_full(M3,svd3);
}
void jacobisvd_preallocate()
@@ -437,6 +474,7 @@ void test_jacobisvd()
// Test on inf/nan matrix
CALL_SUBTEST_7( jacobisvd_inf_nan<MatrixXf>() );
+ CALL_SUBTEST_10( jacobisvd_inf_nan<MatrixXd>() );
}
CALL_SUBTEST_7(( jacobisvd<MatrixXf>(MatrixXf(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));
diff --git a/test/linearstructure.cpp b/test/linearstructure.cpp
index 618984d5c..b627915ce 100644
--- a/test/linearstructure.cpp
+++ b/test/linearstructure.cpp
@@ -2,11 +2,16 @@
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+// Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+static bool g_called;
+
+#define EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN { g_called = true; }
+
#include "main.h"
template<typename MatrixType> void linearStructure(const MatrixType& m)
@@ -68,6 +73,24 @@ template<typename MatrixType> void linearStructure(const MatrixType& m)
VERIFY_IS_APPROX(m1.block(0,0,rows,cols) * s1, m1 * s1);
}
+// Make sure that complex * real and real * complex are properly optimized
+template<typename MatrixType> void real_complex(DenseIndex rows = MatrixType::RowsAtCompileTime, DenseIndex cols = MatrixType::ColsAtCompileTime)
+{
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+
+ RealScalar s = internal::random<RealScalar>();
+ MatrixType m1 = MatrixType::Random(rows, cols);
+
+ g_called = false;
+ VERIFY_IS_APPROX(s*m1, Scalar(s)*m1);
+ VERIFY(g_called && "real * matrix<complex> not properly optimized");
+
+ g_called = false;
+ VERIFY_IS_APPROX(m1*s, m1*Scalar(s));
+ VERIFY(g_called && "matrix<complex> * real not properly optimized");
+}
+
void test_linearstructure()
{
for(int i = 0; i < g_repeat; i++) {
@@ -80,5 +103,8 @@ void test_linearstructure()
CALL_SUBTEST_7( linearStructure(MatrixXi (internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
CALL_SUBTEST_8( linearStructure(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
CALL_SUBTEST_9( linearStructure(ArrayXXf (internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
+
+ CALL_SUBTEST_10( real_complex<Matrix4cd>() );
+ CALL_SUBTEST_10( real_complex<MatrixXcf>(10,10) );
}
}
diff --git a/test/product.h b/test/product.h
index 856b234ac..0b3abe402 100644
--- a/test/product.h
+++ b/test/product.h
@@ -139,4 +139,12 @@ template<typename MatrixType> void product(const MatrixType& m)
// inner product
Scalar x = square2.row(c) * square2.col(c2);
VERIFY_IS_APPROX(x, square2.row(c).transpose().cwiseProduct(square2.col(c2)).sum());
+
+ // outer product
+ VERIFY_IS_APPROX(m1.col(c) * m1.row(r), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));
+ VERIFY_IS_APPROX(m1.row(r).transpose() * m1.col(c).transpose(), m1.block(r,0,1,cols).transpose() * m1.block(0,c,rows,1).transpose());
+ VERIFY_IS_APPROX(m1.block(0,c,rows,1) * m1.row(r), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));
+ VERIFY_IS_APPROX(m1.col(c) * m1.block(r,0,1,cols), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));
+ VERIFY_IS_APPROX(m1.leftCols(1) * m1.row(r), m1.block(0,0,rows,1) * m1.block(r,0,1,cols));
+ VERIFY_IS_APPROX(m1.col(c) * m1.topRows(1), m1.block(0,c,rows,1) * m1.block(0,0,1,cols));
}
diff --git a/test/stable_norm.cpp b/test/stable_norm.cpp
index 549f91fbf..f76919af4 100644
--- a/test/stable_norm.cpp
+++ b/test/stable_norm.cpp
@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2009-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -14,6 +14,21 @@ template<typename T> bool isNotNaN(const T& x)
return x==x;
}
+template<typename T> bool isNaN(const T& x)
+{
+ return x!=x;
+}
+
+template<typename T> bool isInf(const T& x)
+{
+ return x > NumTraits<T>::highest();
+}
+
+template<typename T> bool isMinusInf(const T& x)
+{
+ return x < NumTraits<T>::lowest();
+}
+
// workaround aggressive optimization in ICC
template<typename T> EIGEN_DONT_INLINE T sub(T a, T b) { return a - b; }
@@ -106,6 +121,58 @@ template<typename MatrixType> void stable_norm(const MatrixType& m)
VERIFY_IS_APPROX(vrand.rowwise().stableNorm(), vrand.rowwise().norm());
VERIFY_IS_APPROX(vrand.rowwise().blueNorm(), vrand.rowwise().norm());
VERIFY_IS_APPROX(vrand.rowwise().hypotNorm(), vrand.rowwise().norm());
+
+ // test NaN, +inf, -inf
+ MatrixType v;
+ Index i = internal::random<Index>(0,rows-1);
+ Index j = internal::random<Index>(0,cols-1);
+
+ // NaN
+ {
+ v = vrand;
+ v(i,j) = RealScalar(0)/RealScalar(0);
+ VERIFY(!isFinite(v.squaredNorm())); VERIFY(isNaN(v.squaredNorm()));
+ VERIFY(!isFinite(v.norm())); VERIFY(isNaN(v.norm()));
+ VERIFY(!isFinite(v.stableNorm())); VERIFY(isNaN(v.stableNorm()));
+ VERIFY(!isFinite(v.blueNorm())); VERIFY(isNaN(v.blueNorm()));
+ VERIFY(!isFinite(v.hypotNorm())); VERIFY(isNaN(v.hypotNorm()));
+ }
+
+ // +inf
+ {
+ v = vrand;
+ v(i,j) = RealScalar(1)/RealScalar(0);
+ VERIFY(!isFinite(v.squaredNorm())); VERIFY(isInf(v.squaredNorm()));
+ VERIFY(!isFinite(v.norm())); VERIFY(isInf(v.norm()));
+ VERIFY(!isFinite(v.stableNorm())); VERIFY(isInf(v.stableNorm()));
+ VERIFY(!isFinite(v.blueNorm())); VERIFY(isInf(v.blueNorm()));
+ VERIFY(!isFinite(v.hypotNorm())); VERIFY(isInf(v.hypotNorm()));
+ }
+
+ // -inf
+ {
+ v = vrand;
+ v(i,j) = RealScalar(-1)/RealScalar(0);
+ VERIFY(!isFinite(v.squaredNorm())); VERIFY(isInf(v.squaredNorm()));
+ VERIFY(!isFinite(v.norm())); VERIFY(isInf(v.norm()));
+ VERIFY(!isFinite(v.stableNorm())); VERIFY(isInf(v.stableNorm()));
+ VERIFY(!isFinite(v.blueNorm())); VERIFY(isInf(v.blueNorm()));
+ VERIFY(!isFinite(v.hypotNorm())); VERIFY(isInf(v.hypotNorm()));
+ }
+
+ // mix
+ {
+ Index i2 = internal::random<Index>(0,rows-1);
+ Index j2 = internal::random<Index>(0,cols-1);
+ v = vrand;
+ v(i,j) = RealScalar(-1)/RealScalar(0);
+ v(i2,j2) = RealScalar(0)/RealScalar(0);
+ VERIFY(!isFinite(v.squaredNorm())); VERIFY(isNaN(v.squaredNorm()));
+ VERIFY(!isFinite(v.norm())); VERIFY(isNaN(v.norm()));
+ VERIFY(!isFinite(v.stableNorm())); VERIFY(isNaN(v.stableNorm()));
+ VERIFY(!isFinite(v.blueNorm())); VERIFY(isNaN(v.blueNorm()));
+ VERIFY(!isFinite(v.hypotNorm())); VERIFY(isNaN(v.hypotNorm()));
+ }
}
void test_stable_norm()
diff --git a/test/upperbidiagonalization.cpp b/test/upperbidiagonalization.cpp
index d15bf588b..847b34b55 100644
--- a/test/upperbidiagonalization.cpp
+++ b/test/upperbidiagonalization.cpp
@@ -35,7 +35,7 @@ void test_upperbidiagonalization()
CALL_SUBTEST_1( upperbidiag(MatrixXf(3,3)) );
CALL_SUBTEST_2( upperbidiag(MatrixXd(17,12)) );
CALL_SUBTEST_3( upperbidiag(MatrixXcf(20,20)) );
- CALL_SUBTEST_4( upperbidiag(MatrixXcd(16,15)) );
+ CALL_SUBTEST_4( upperbidiag(Matrix<std::complex<double>,Dynamic,Dynamic,RowMajor>(16,15)) );
CALL_SUBTEST_5( upperbidiag(Matrix<float,6,4>()) );
CALL_SUBTEST_6( upperbidiag(Matrix<float,5,5>()) );
CALL_SUBTEST_7( upperbidiag(Matrix<double,4,3>()) );