aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorGravatar Deanna Hood <deanna.m.hood@gmail.com>2015-04-20 14:01:35 -0400
committerGravatar Deanna Hood <deanna.m.hood@gmail.com>2015-04-20 14:01:35 -0400
commit0250f4a9f2f7bb54ed760cec045939a1bbe58170 (patch)
tree5e0372ddef57f51f7adb56bb9569037e6e9556ad /test
parent0339502a4feb6340f1e9f6f6ca8b3ef4d263f366 (diff)
parent0eb220c00d9773c29c7d169ad0e20745b0ef21bb (diff)
Merged default into unary-array-cwise-functors
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt7
-rw-r--r--test/array_reverse.cpp30
-rw-r--r--test/diagonalmatrices.cpp20
-rw-r--r--test/main.h8
-rw-r--r--test/product_extra.cpp68
-rw-r--r--test/rand.cpp88
-rw-r--r--test/real_qz.cpp16
-rw-r--r--test/sparse_basic.cpp160
-rw-r--r--test/sparse_block.cpp254
-rw-r--r--test/sparse_product.cpp5
-rw-r--r--test/svd_common.h64
-rw-r--r--test/swap.cpp6
-rw-r--r--test/unalignedassert.cpp36
-rw-r--r--test/vectorization_logic.cpp2
14 files changed, 577 insertions, 187 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 1712b8718..54ce7fb30 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -139,6 +139,7 @@ endif(TEST_LIB)
set_property(GLOBAL PROPERTY EIGEN_CURRENT_SUBPROJECT "Official")
add_custom_target(BuildOfficial)
+ei_add_test(rand)
ei_add_test(meta)
ei_add_test(sizeof)
ei_add_test(dynalloc)
@@ -226,6 +227,7 @@ ei_add_test(stdvector_overload)
ei_add_test(stdlist)
ei_add_test(stddeque)
ei_add_test(sparse_basic)
+ei_add_test(sparse_block)
ei_add_test(sparse_vector)
ei_add_test(sparse_product)
ei_add_test(sparse_ref)
@@ -330,3 +332,8 @@ endif(EIGEN_TEST_NVCC)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/failtests)
add_test(NAME failtests WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/failtests COMMAND ${CMAKE_COMMAND} ${Eigen_SOURCE_DIR} -G "${CMAKE_GENERATOR}" -DEIGEN_FAILTEST=ON)
+
+option(EIGEN_TEST_BUILD_DOCUMENTATION "Test building the doxygen documentation" OFF)
+IF(EIGEN_TEST_BUILD_DOCUMENTATION)
+ add_dependencies(buildtests doc)
+ENDIF()
diff --git a/test/array_reverse.cpp b/test/array_reverse.cpp
index fbe7a9901..a5c0d37f9 100644
--- a/test/array_reverse.cpp
+++ b/test/array_reverse.cpp
@@ -24,7 +24,7 @@ template<typename MatrixType> void reverse(const MatrixType& m)
// this test relies a lot on Random.h, and there's not much more that we can do
// to test it, hence I consider that we will have tested Random.h
- MatrixType m1 = MatrixType::Random(rows, cols);
+ MatrixType m1 = MatrixType::Random(rows, cols), m2;
VectorType v1 = VectorType::Random(rows);
MatrixType m1_r = m1.reverse();
@@ -96,6 +96,26 @@ template<typename MatrixType> void reverse(const MatrixType& m)
m1.reverse()(r, c) = x;
VERIFY_IS_APPROX(x, m1(rows - 1 - r, cols - 1 - c));
+
+ m2 = m1;
+ m2.reverseInPlace();
+ VERIFY_IS_APPROX(m2,m1.reverse().eval());
+
+ m2 = m1;
+ m2.col(0).reverseInPlace();
+ VERIFY_IS_APPROX(m2.col(0),m1.col(0).reverse().eval());
+
+ m2 = m1;
+ m2.row(0).reverseInPlace();
+ VERIFY_IS_APPROX(m2.row(0),m1.row(0).reverse().eval());
+
+ m2 = m1;
+ m2.rowwise().reverseInPlace();
+ VERIFY_IS_APPROX(m2,m1.rowwise().reverse().eval());
+
+ m2 = m1;
+ m2.colwise().reverseInPlace();
+ VERIFY_IS_APPROX(m2,m1.colwise().reverse().eval());
/*
m1.colwise().reverse()(r, c) = x;
@@ -113,11 +133,11 @@ void test_array_reverse()
CALL_SUBTEST_2( reverse(Matrix2f()) );
CALL_SUBTEST_3( reverse(Matrix4f()) );
CALL_SUBTEST_4( reverse(Matrix4d()) );
- CALL_SUBTEST_5( reverse(MatrixXcf(3, 3)) );
- CALL_SUBTEST_6( reverse(MatrixXi(6, 3)) );
- CALL_SUBTEST_7( reverse(MatrixXcd(20, 20)) );
+ CALL_SUBTEST_5( reverse(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
+ CALL_SUBTEST_6( reverse(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
+ CALL_SUBTEST_7( reverse(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
CALL_SUBTEST_8( reverse(Matrix<float, 100, 100>()) );
- CALL_SUBTEST_9( reverse(Matrix<float,Dynamic,Dynamic,RowMajor>(6,3)) );
+ CALL_SUBTEST_9( reverse(Matrix<float,Dynamic,Dynamic,RowMajor>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
}
#ifdef EIGEN_TEST_PART_3
Vector4f x; x << 1, 2, 3, 4;
diff --git a/test/diagonalmatrices.cpp b/test/diagonalmatrices.cpp
index 0227ba577..cd6dc8cf0 100644
--- a/test/diagonalmatrices.cpp
+++ b/test/diagonalmatrices.cpp
@@ -17,6 +17,7 @@ template<typename MatrixType> void diagonalmatrices(const MatrixType& m)
typedef Matrix<Scalar, Rows, 1> VectorType;
typedef Matrix<Scalar, 1, Cols> RowVectorType;
typedef Matrix<Scalar, Rows, Rows> SquareMatrixType;
+ typedef Matrix<Scalar, Dynamic, Dynamic> DynMatrixType;
typedef DiagonalMatrix<Scalar, Rows> LeftDiagonalMatrix;
typedef DiagonalMatrix<Scalar, Cols> RightDiagonalMatrix;
typedef Matrix<Scalar, Rows==Dynamic?Dynamic:2*Rows, Cols==Dynamic?Dynamic:2*Cols> BigMatrix;
@@ -64,6 +65,13 @@ template<typename MatrixType> void diagonalmatrices(const MatrixType& m)
VERIFY_IS_APPROX( (((v1+v2).asDiagonal() * (m1+m2))(i,j)) , (v1+v2)(i) * (m1+m2)(i,j) );
VERIFY_IS_APPROX( ((m1 * (rv1+rv2).asDiagonal())(i,j)) , (rv1+rv2)(j) * m1(i,j) );
VERIFY_IS_APPROX( (((m1+m2) * (rv1+rv2).asDiagonal())(i,j)) , (rv1+rv2)(j) * (m1+m2)(i,j) );
+
+ if(rows>1)
+ {
+ DynMatrixType tmp = m1.topRows(rows/2), res;
+ VERIFY_IS_APPROX( (res = m1.topRows(rows/2) * rv1.asDiagonal()), tmp * rv1.asDiagonal() );
+ VERIFY_IS_APPROX( (res = v1.head(rows/2).asDiagonal()*m1.topRows(rows/2)), v1.head(rows/2).asDiagonal()*tmp );
+ }
BigMatrix big;
big.setZero(2*rows, 2*cols);
@@ -93,6 +101,17 @@ template<typename MatrixType> void diagonalmatrices(const MatrixType& m)
VERIFY_IS_APPROX( (sq_m1 = (s1*v1).asDiagonal()), (s1*v1).asDiagonal().toDenseMatrix() );
}
+template<int>
+void bug987()
+{
+ Matrix3Xd points = Matrix3Xd::Random(3, 3);
+ Vector2d diag = Vector2d::Random();
+ Matrix2Xd tmp1 = points.topRows<2>(), res1, res2;
+ VERIFY_IS_APPROX( res1 = diag.asDiagonal() * points.topRows<2>(), res2 = diag.asDiagonal() * tmp1 );
+ Matrix2d tmp2 = points.topLeftCorner<2,2>();
+ VERIFY_IS_APPROX(( res1 = points.topLeftCorner<2,2>()*diag.asDiagonal()) , res2 = tmp2*diag.asDiagonal() );
+}
+
void test_diagonalmatrices()
{
for(int i = 0; i < g_repeat; i++) {
@@ -106,4 +125,5 @@ void test_diagonalmatrices()
CALL_SUBTEST_8( diagonalmatrices(Matrix<double,Dynamic,Dynamic,RowMajor>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
CALL_SUBTEST_9( diagonalmatrices(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
}
+ CALL_SUBTEST_10( bug987<0>() );
}
diff --git a/test/main.h b/test/main.h
index 5849cedd9..d336d4d9b 100644
--- a/test/main.h
+++ b/test/main.h
@@ -95,6 +95,9 @@
namespace Eigen
{
static std::vector<std::string> g_test_stack;
+ // level == 0 <=> abort if test fail
+ // level >= 1 <=> warning message to std::cerr if test fail
+ static int g_test_level = 0;
static int g_repeat;
static unsigned int g_seed;
static bool g_has_set_repeat, g_has_set_seed;
@@ -229,6 +232,8 @@ inline void verify_impl(bool condition, const char *testname, const char *file,
{
if (!condition)
{
+ if(Eigen::g_test_level>0)
+ std::cerr << "WARNING: ";
std::cerr << "Test " << testname << " failed in " << file << " (" << line << ")"
<< std::endl << " " << condition_as_string << std::endl;
std::cerr << "Stack:\n";
@@ -236,7 +241,8 @@ inline void verify_impl(bool condition, const char *testname, const char *file,
for(int i=test_stack_size-1; i>=0; --i)
std::cerr << " - " << Eigen::g_test_stack[i] << "\n";
std::cerr << "\n";
- abort();
+ if(Eigen::g_test_level==0)
+ abort();
}
}
diff --git a/test/product_extra.cpp b/test/product_extra.cpp
index 1b4c6c33c..7c54b6977 100644
--- a/test/product_extra.cpp
+++ b/test/product_extra.cpp
@@ -113,6 +113,9 @@ void mat_mat_scalar_scalar_product()
template <typename MatrixType>
void zero_sized_objects(const MatrixType& m)
{
+ typedef typename MatrixType::Scalar Scalar;
+ const int PacketSize = internal::packet_traits<Scalar>::size;
+ const int PacketSize1 = PacketSize>1 ? PacketSize-1 : 1;
Index rows = m.rows();
Index cols = m.cols();
@@ -132,9 +135,41 @@ void zero_sized_objects(const MatrixType& m)
res = b*a;
VERIFY(res.rows()==0 && res.cols()==cols);
}
+
+ {
+ Matrix<Scalar,PacketSize,0> a;
+ Matrix<Scalar,0,1> b;
+ Matrix<Scalar,PacketSize,1> res;
+ VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize,1) );
+ VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize,1) );
+ }
+
+ {
+ Matrix<Scalar,PacketSize1,0> a;
+ Matrix<Scalar,0,1> b;
+ Matrix<Scalar,PacketSize1,1> res;
+ VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize1,1) );
+ VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize1,1) );
+ }
+
+ {
+ Matrix<Scalar,PacketSize,Dynamic> a(PacketSize,0);
+ Matrix<Scalar,Dynamic,1> b(0,1);
+ Matrix<Scalar,PacketSize,1> res;
+ VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize,1) );
+ VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize,1) );
+ }
+
+ {
+ Matrix<Scalar,PacketSize1,Dynamic> a(PacketSize1,0);
+ Matrix<Scalar,Dynamic,1> b(0,1);
+ Matrix<Scalar,PacketSize1,1> res;
+ VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize1,1) );
+ VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize1,1) );
+ }
}
-
+template<int>
void bug_127()
{
// Bug 127
@@ -159,6 +194,7 @@ void bug_127()
a*b;
}
+template<int>
void unaligned_objects()
{
// Regression test for the bug reported here:
@@ -188,6 +224,29 @@ void unaligned_objects()
}
}
+template<typename T>
+EIGEN_DONT_INLINE
+Index test_compute_block_size(Index m, Index n, Index k)
+{
+ Index mc(m), nc(n), kc(k);
+ internal::computeProductBlockingSizes<T,T>(kc, mc, nc);
+ return kc+mc+nc;
+}
+
+template<typename T>
+Index compute_block_size()
+{
+ Index ret = 0;
+ ret += test_compute_block_size<T>(0,1,1);
+ ret += test_compute_block_size<T>(1,0,1);
+ ret += test_compute_block_size<T>(1,1,0);
+ ret += test_compute_block_size<T>(0,0,1);
+ ret += test_compute_block_size<T>(0,1,0);
+ ret += test_compute_block_size<T>(1,0,0);
+ ret += test_compute_block_size<T>(0,0,0);
+ return ret;
+}
+
void test_product_extra()
{
for(int i = 0; i < g_repeat; i++) {
@@ -198,6 +257,9 @@ void test_product_extra()
CALL_SUBTEST_4( product_extra(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );
CALL_SUBTEST_1( zero_sized_objects(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
}
- CALL_SUBTEST_5( bug_127() );
- CALL_SUBTEST_6( unaligned_objects() );
+ CALL_SUBTEST_5( bug_127<0>() );
+ CALL_SUBTEST_6( unaligned_objects<0>() );
+ CALL_SUBTEST_7( compute_block_size<float>() );
+ CALL_SUBTEST_7( compute_block_size<double>() );
+ CALL_SUBTEST_7( compute_block_size<std::complex<double> >() );
}
diff --git a/test/rand.cpp b/test/rand.cpp
new file mode 100644
index 000000000..7c8068a3b
--- /dev/null
+++ b/test/rand.cpp
@@ -0,0 +1,88 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2015 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/.
+
+#include "main.h"
+
+template<typename Scalar> Scalar check_in_range(Scalar x, Scalar y)
+{
+ Scalar r = internal::random<Scalar>(x,y);
+ VERIFY(r>=x);
+ if(y>=x)
+ {
+ VERIFY(r<=y);
+ }
+ return r;
+}
+
+template<typename Scalar> void check_all_in_range(Scalar x, Scalar y)
+{
+ Array<int,1,Dynamic> mask(y-x+1);
+ mask.fill(0);
+ long n = (y-x+1)*32;
+ for(long k=0; k<n; ++k)
+ {
+ mask( check_in_range(x,y)-x )++;
+ }
+ VERIFY( (mask>0).all() );
+}
+
+void test_rand()
+{
+ long long_ref = NumTraits<long>::highest()/10;
+ char char_offset = (std::min)(g_repeat,64);
+ char short_offset = (std::min)(g_repeat,16000);
+
+ for(int i = 0; i < g_repeat*10; i++) {
+ CALL_SUBTEST(check_in_range<float>(10,11));
+ CALL_SUBTEST(check_in_range<float>(1.24234523,1.24234523));
+ CALL_SUBTEST(check_in_range<float>(-1,1));
+ CALL_SUBTEST(check_in_range<float>(-1432.2352,-1432.2352));
+
+ CALL_SUBTEST(check_in_range<double>(10,11));
+ CALL_SUBTEST(check_in_range<double>(1.24234523,1.24234523));
+ CALL_SUBTEST(check_in_range<double>(-1,1));
+ CALL_SUBTEST(check_in_range<double>(-1432.2352,-1432.2352));
+
+ CALL_SUBTEST(check_in_range<int>(0,-1));
+ CALL_SUBTEST(check_in_range<short>(0,-1));
+ CALL_SUBTEST(check_in_range<long>(0,-1));
+ CALL_SUBTEST(check_in_range<int>(-673456,673456));
+ CALL_SUBTEST(check_in_range<short>(-24345,24345));
+ CALL_SUBTEST(check_in_range<long>(-long_ref,long_ref));
+ }
+
+ CALL_SUBTEST(check_all_in_range<char>(11,11));
+ CALL_SUBTEST(check_all_in_range<char>(11,11+char_offset));
+ CALL_SUBTEST(check_all_in_range<char>(-5,5));
+ CALL_SUBTEST(check_all_in_range<char>(-11-char_offset,-11));
+ CALL_SUBTEST(check_all_in_range<char>(-126,-126+char_offset));
+ CALL_SUBTEST(check_all_in_range<char>(126-char_offset,126));
+ CALL_SUBTEST(check_all_in_range<char>(-126,126));
+
+ CALL_SUBTEST(check_all_in_range<short>(11,11));
+ CALL_SUBTEST(check_all_in_range<short>(11,11+short_offset));
+ CALL_SUBTEST(check_all_in_range<short>(-5,5));
+ CALL_SUBTEST(check_all_in_range<short>(-11-short_offset,-11));
+ CALL_SUBTEST(check_all_in_range<short>(-24345,-24345+short_offset));
+ CALL_SUBTEST(check_all_in_range<short>(24345,24345+short_offset));
+
+ CALL_SUBTEST(check_all_in_range<int>(11,11));
+ CALL_SUBTEST(check_all_in_range<int>(11,11+g_repeat));
+ CALL_SUBTEST(check_all_in_range<int>(-5,5));
+ CALL_SUBTEST(check_all_in_range<int>(-11-g_repeat,-11));
+ CALL_SUBTEST(check_all_in_range<int>(-673456,-673456+g_repeat));
+ CALL_SUBTEST(check_all_in_range<int>(673456,673456+g_repeat));
+
+ CALL_SUBTEST(check_all_in_range<long>(11,11));
+ CALL_SUBTEST(check_all_in_range<long>(11,11+g_repeat));
+ CALL_SUBTEST(check_all_in_range<long>(-5,5));
+ CALL_SUBTEST(check_all_in_range<long>(-11-g_repeat,-11));
+ CALL_SUBTEST(check_all_in_range<long>(-long_ref,-long_ref+g_repeat));
+ CALL_SUBTEST(check_all_in_range<long>( long_ref, long_ref+g_repeat));
+}
diff --git a/test/real_qz.cpp b/test/real_qz.cpp
index 7d743a734..a1766c6d9 100644
--- a/test/real_qz.cpp
+++ b/test/real_qz.cpp
@@ -25,6 +25,22 @@ template<typename MatrixType> void real_qz(const MatrixType& m)
MatrixType A = MatrixType::Random(dim,dim),
B = MatrixType::Random(dim,dim);
+
+ // Regression test for bug 985: Randomly set rows or columns to zero
+ Index k=internal::random<Index>(0, dim-1);
+ switch(internal::random<int>(0,10)) {
+ case 0:
+ A.row(k).setZero(); break;
+ case 1:
+ A.col(k).setZero(); break;
+ case 2:
+ B.row(k).setZero(); break;
+ case 3:
+ B.col(k).setZero(); break;
+ default:
+ break;
+ }
+
RealQZ<MatrixType> qz(A,B);
VERIFY_IS_EQUAL(qz.info(), Success);
diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp
index e243964f4..75f29a2b4 100644
--- a/test/sparse_basic.cpp
+++ b/test/sparse_basic.cpp
@@ -58,48 +58,6 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
VERIFY_IS_APPROX(m, refMat);
- // test InnerIterators and Block expressions
- for (Index t=0; t<10; ++t)
- {
- Index j = internal::random<Index>(0,cols-1);
- Index i = internal::random<Index>(0,rows-1);
- Index w = internal::random<Index>(1,cols-j-1);
- Index h = internal::random<Index>(1,rows-i-1);
-
- VERIFY_IS_APPROX(m.block(i,j,h,w), refMat.block(i,j,h,w));
- for(Index c=0; c<w; c++)
- {
- VERIFY_IS_APPROX(m.block(i,j,h,w).col(c), refMat.block(i,j,h,w).col(c));
- for(Index r=0; r<h; r++)
- {
- // FIXME col().coeff() not implemented yet
-// VERIFY_IS_APPROX(m.block(i,j,h,w).col(c).coeff(r), refMat.block(i,j,h,w).col(c).coeff(r));
- }
- }
- for(Index r=0; r<h; r++)
- {
- VERIFY_IS_APPROX(m.block(i,j,h,w).row(r), refMat.block(i,j,h,w).row(r));
- for(Index c=0; c<w; c++)
- {
- // FIXME row().coeff() not implemented yet
-// VERIFY_IS_APPROX(m.block(i,j,h,w).row(r).coeff(c), refMat.block(i,j,h,w).row(r).coeff(c));
- }
- }
- }
-
- for(Index c=0; c<cols; c++)
- {
- VERIFY_IS_APPROX(m.col(c) + m.col(c), (m + m).col(c));
- VERIFY_IS_APPROX(m.col(c) + m.col(c), refMat.col(c) + refMat.col(c));
- }
-
- for(Index r=0; r<rows; r++)
- {
- VERIFY_IS_APPROX(m.row(r) + m.row(r), (m + m).row(r));
- VERIFY_IS_APPROX(m.row(r) + m.row(r), refMat.row(r) + refMat.row(r));
- }
-
-
// test assertion
VERIFY_RAISES_ASSERT( m.coeffRef(-1,1) = 0 );
VERIFY_RAISES_ASSERT( m.coeffRef(0,m.cols()) = 0 );
@@ -184,82 +142,6 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
VERIFY_IS_APPROX(m2,m1);
}
- // test innerVector()
- {
- DenseMatrix refMat2 = DenseMatrix::Zero(rows, cols);
- SparseMatrixType m2(rows, cols);
- initSparse<Scalar>(density, refMat2, m2);
- Index j0 = internal::random<Index>(0,outer-1);
- Index j1 = internal::random<Index>(0,outer-1);
- if(SparseMatrixType::IsRowMajor)
- VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.row(j0));
- else
- VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.col(j0));
-
- if(SparseMatrixType::IsRowMajor)
- VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.row(j0)+refMat2.row(j1));
- else
- VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.col(j0)+refMat2.col(j1));
-
- SparseMatrixType m3(rows,cols);
- m3.reserve(VectorXi::Constant(outer,int(inner/2)));
- for(Index j=0; j<outer; ++j)
- for(Index k=0; k<(std::min)(j,inner); ++k)
- m3.insertByOuterInner(j,k) = k+1;
- for(Index j=0; j<(std::min)(outer, inner); ++j)
- {
- VERIFY(j==numext::real(m3.innerVector(j).nonZeros()));
- if(j>0)
- VERIFY(j==numext::real(m3.innerVector(j).lastCoeff()));
- }
- m3.makeCompressed();
- for(Index j=0; j<(std::min)(outer, inner); ++j)
- {
- VERIFY(j==numext::real(m3.innerVector(j).nonZeros()));
- if(j>0)
- VERIFY(j==numext::real(m3.innerVector(j).lastCoeff()));
- }
-
- VERIFY(m3.innerVector(j0).nonZeros() == m3.transpose().innerVector(j0).nonZeros());
-
-// m2.innerVector(j0) = 2*m2.innerVector(j1);
-// refMat2.col(j0) = 2*refMat2.col(j1);
-// VERIFY_IS_APPROX(m2, refMat2);
- }
-
- // test innerVectors()
- {
- DenseMatrix refMat2 = DenseMatrix::Zero(rows, cols);
- SparseMatrixType m2(rows, cols);
- initSparse<Scalar>(density, refMat2, m2);
- if(internal::random<float>(0,1)>0.5) m2.makeCompressed();
- Index j0 = internal::random<Index>(0,outer-2);
- Index j1 = internal::random<Index>(0,outer-2);
- Index n0 = internal::random<Index>(1,outer-(std::max)(j0,j1));
- if(SparseMatrixType::IsRowMajor)
- VERIFY_IS_APPROX(m2.innerVectors(j0,n0), refMat2.block(j0,0,n0,cols));
- else
- VERIFY_IS_APPROX(m2.innerVectors(j0,n0), refMat2.block(0,j0,rows,n0));
- if(SparseMatrixType::IsRowMajor)
- VERIFY_IS_APPROX(m2.innerVectors(j0,n0)+m2.innerVectors(j1,n0),
- refMat2.middleRows(j0,n0)+refMat2.middleRows(j1,n0));
- else
- VERIFY_IS_APPROX(m2.innerVectors(j0,n0)+m2.innerVectors(j1,n0),
- refMat2.block(0,j0,rows,n0)+refMat2.block(0,j1,rows,n0));
-
- VERIFY_IS_APPROX(m2, refMat2);
-
- VERIFY(m2.innerVectors(j0,n0).nonZeros() == m2.transpose().innerVectors(j0,n0).nonZeros());
-
- m2.innerVectors(j0,n0) = m2.innerVectors(j0,n0) + m2.innerVectors(j1,n0);
- if(SparseMatrixType::IsRowMajor)
- refMat2.middleRows(j0,n0) = (refMat2.middleRows(j0,n0) + refMat2.middleRows(j1,n0)).eval();
- else
- refMat2.middleCols(j0,n0) = (refMat2.middleCols(j0,n0) + refMat2.middleCols(j1,n0)).eval();
-
- VERIFY_IS_APPROX(m2, refMat2);
- }
-
// test basic computations
{
DenseMatrix refM1 = DenseMatrix::Zero(rows, cols);
@@ -330,40 +212,6 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
VERIFY(m2.isApprox(m3));
}
-
-
- // test generic blocks
- {
- DenseMatrix refMat2 = DenseMatrix::Zero(rows, cols);
- SparseMatrixType m2(rows, cols);
- initSparse<Scalar>(density, refMat2, m2);
- Index j0 = internal::random<Index>(0,outer-2);
- Index j1 = internal::random<Index>(0,outer-2);
- Index n0 = internal::random<Index>(1,outer-(std::max)(j0,j1));
- if(SparseMatrixType::IsRowMajor)
- VERIFY_IS_APPROX(m2.block(j0,0,n0,cols), refMat2.block(j0,0,n0,cols));
- else
- VERIFY_IS_APPROX(m2.block(0,j0,rows,n0), refMat2.block(0,j0,rows,n0));
-
- if(SparseMatrixType::IsRowMajor)
- VERIFY_IS_APPROX(m2.block(j0,0,n0,cols)+m2.block(j1,0,n0,cols),
- refMat2.block(j0,0,n0,cols)+refMat2.block(j1,0,n0,cols));
- else
- VERIFY_IS_APPROX(m2.block(0,j0,rows,n0)+m2.block(0,j1,rows,n0),
- refMat2.block(0,j0,rows,n0)+refMat2.block(0,j1,rows,n0));
-
- Index i = internal::random<Index>(0,m2.outerSize()-1);
- if(SparseMatrixType::IsRowMajor) {
- m2.innerVector(i) = m2.innerVector(i) * s1;
- refMat2.row(i) = refMat2.row(i) * s1;
- VERIFY_IS_APPROX(m2,refMat2);
- } else {
- m2.innerVector(i) = m2.innerVector(i) * s1;
- refMat2.col(i) = refMat2.col(i) * s1;
- VERIFY_IS_APPROX(m2,refMat2);
- }
- }
-
// test prune
{
SparseMatrixType m2(rows, cols);
@@ -602,8 +450,8 @@ void test_sparse_basic()
CALL_SUBTEST_2(( sparse_basic(SparseMatrix<std::complex<double>, ColMajor>(r, c)) ));
CALL_SUBTEST_2(( sparse_basic(SparseMatrix<std::complex<double>, RowMajor>(r, c)) ));
CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double>(r, c)) ));
- CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double,ColMajor,long int>(r, c)) ));
- CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double,RowMajor,long int>(r, c)) ));
+ CALL_SUBTEST_5(( sparse_basic(SparseMatrix<double,ColMajor,long int>(r, c)) ));
+ CALL_SUBTEST_5(( sparse_basic(SparseMatrix<double,RowMajor,long int>(r, c)) ));
r = Eigen::internal::random<int>(1,100);
c = Eigen::internal::random<int>(1,100);
@@ -611,8 +459,8 @@ void test_sparse_basic()
r = c; // check square matrices in 25% of tries
}
- CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double,ColMajor,short int>(short(r), short(c))) ));
- CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double,RowMajor,short int>(short(r), short(c))) ));
+ CALL_SUBTEST_6(( sparse_basic(SparseMatrix<double,ColMajor,short int>(short(r), short(c))) ));
+ CALL_SUBTEST_6(( sparse_basic(SparseMatrix<double,RowMajor,short int>(short(r), short(c))) ));
}
// Regression test for bug 900: (manually insert higher values here, if you have enough RAM):
diff --git a/test/sparse_block.cpp b/test/sparse_block.cpp
new file mode 100644
index 000000000..8a6e0687c
--- /dev/null
+++ b/test/sparse_block.cpp
@@ -0,0 +1,254 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008-2015 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/.
+
+#include "sparse.h"
+
+template<typename SparseMatrixType> void sparse_block(const SparseMatrixType& ref)
+{
+ const Index rows = ref.rows();
+ const Index cols = ref.cols();
+ const Index inner = ref.innerSize();
+ const Index outer = ref.outerSize();
+
+ typedef typename SparseMatrixType::Scalar Scalar;
+
+ double density = (std::max)(8./(rows*cols), 0.01);
+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
+ typedef Matrix<Scalar,Dynamic,1> DenseVector;
+ typedef Matrix<Scalar,1,Dynamic> RowDenseVector;
+
+ Scalar s1 = internal::random<Scalar>();
+ {
+ SparseMatrixType m(rows, cols);
+ DenseMatrix refMat = DenseMatrix::Zero(rows, cols);
+ initSparse<Scalar>(density, refMat, m);
+
+ VERIFY_IS_APPROX(m, refMat);
+
+ // test InnerIterators and Block expressions
+ for (int t=0; t<10; ++t)
+ {
+ Index j = internal::random<Index>(0,cols-2);
+ Index i = internal::random<Index>(0,rows-2);
+ Index w = internal::random<Index>(1,cols-j);
+ Index h = internal::random<Index>(1,rows-i);
+
+ VERIFY_IS_APPROX(m.block(i,j,h,w), refMat.block(i,j,h,w));
+ for(Index c=0; c<w; c++)
+ {
+ VERIFY_IS_APPROX(m.block(i,j,h,w).col(c), refMat.block(i,j,h,w).col(c));
+ for(Index r=0; r<h; r++)
+ {
+ VERIFY_IS_APPROX(m.block(i,j,h,w).col(c).coeff(r), refMat.block(i,j,h,w).col(c).coeff(r));
+ VERIFY_IS_APPROX(m.block(i,j,h,w).coeff(r,c), refMat.block(i,j,h,w).coeff(r,c));
+ }
+ }
+ for(Index r=0; r<h; r++)
+ {
+ VERIFY_IS_APPROX(m.block(i,j,h,w).row(r), refMat.block(i,j,h,w).row(r));
+ for(Index c=0; c<w; c++)
+ {
+ VERIFY_IS_APPROX(m.block(i,j,h,w).row(r).coeff(c), refMat.block(i,j,h,w).row(r).coeff(c));
+ VERIFY_IS_APPROX(m.block(i,j,h,w).coeff(r,c), refMat.block(i,j,h,w).coeff(r,c));
+ }
+ }
+
+ VERIFY_IS_APPROX(m.middleCols(j,w), refMat.middleCols(j,w));
+ VERIFY_IS_APPROX(m.middleRows(i,h), refMat.middleRows(i,h));
+ for(Index r=0; r<h; r++)
+ {
+ VERIFY_IS_APPROX(m.middleCols(j,w).row(r), refMat.middleCols(j,w).row(r));
+ VERIFY_IS_APPROX(m.middleRows(i,h).row(r), refMat.middleRows(i,h).row(r));
+ for(Index c=0; c<w; c++)
+ {
+ VERIFY_IS_APPROX(m.col(c).coeff(r), refMat.col(c).coeff(r));
+ VERIFY_IS_APPROX(m.row(r).coeff(c), refMat.row(r).coeff(c));
+
+ VERIFY_IS_APPROX(m.middleCols(j,w).coeff(r,c), refMat.middleCols(j,w).coeff(r,c));
+ VERIFY_IS_APPROX(m.middleRows(i,h).coeff(r,c), refMat.middleRows(i,h).coeff(r,c));
+ if(m.middleCols(j,w).coeff(r,c) != Scalar(0))
+ {
+ VERIFY_IS_APPROX(m.middleCols(j,w).coeffRef(r,c), refMat.middleCols(j,w).coeff(r,c));
+ }
+ if(m.middleRows(i,h).coeff(r,c) != Scalar(0))
+ {
+ VERIFY_IS_APPROX(m.middleRows(i,h).coeff(r,c), refMat.middleRows(i,h).coeff(r,c));
+ }
+ }
+ }
+ for(Index c=0; c<w; c++)
+ {
+ VERIFY_IS_APPROX(m.middleCols(j,w).col(c), refMat.middleCols(j,w).col(c));
+ VERIFY_IS_APPROX(m.middleRows(i,h).col(c), refMat.middleRows(i,h).col(c));
+ }
+ }
+
+ for(Index c=0; c<cols; c++)
+ {
+ VERIFY_IS_APPROX(m.col(c) + m.col(c), (m + m).col(c));
+ VERIFY_IS_APPROX(m.col(c) + m.col(c), refMat.col(c) + refMat.col(c));
+ }
+
+ for(Index r=0; r<rows; r++)
+ {
+ VERIFY_IS_APPROX(m.row(r) + m.row(r), (m + m).row(r));
+ VERIFY_IS_APPROX(m.row(r) + m.row(r), refMat.row(r) + refMat.row(r));
+ }
+ }
+
+ // test innerVector()
+ {
+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, cols);
+ SparseMatrixType m2(rows, cols);
+ initSparse<Scalar>(density, refMat2, m2);
+ Index j0 = internal::random<Index>(0,outer-1);
+ Index j1 = internal::random<Index>(0,outer-1);
+ if(SparseMatrixType::IsRowMajor)
+ VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.row(j0));
+ else
+ VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.col(j0));
+
+ if(SparseMatrixType::IsRowMajor)
+ VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.row(j0)+refMat2.row(j1));
+ else
+ VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.col(j0)+refMat2.col(j1));
+
+ SparseMatrixType m3(rows,cols);
+ m3.reserve(VectorXi::Constant(outer,int(inner/2)));
+ for(Index j=0; j<outer; ++j)
+ for(Index k=0; k<(std::min)(j,inner); ++k)
+ m3.insertByOuterInner(j,k) = k+1;
+ for(Index j=0; j<(std::min)(outer, inner); ++j)
+ {
+ VERIFY(j==numext::real(m3.innerVector(j).nonZeros()));
+ if(j>0)
+ VERIFY(j==numext::real(m3.innerVector(j).lastCoeff()));
+ }
+ m3.makeCompressed();
+ for(Index j=0; j<(std::min)(outer, inner); ++j)
+ {
+ VERIFY(j==numext::real(m3.innerVector(j).nonZeros()));
+ if(j>0)
+ VERIFY(j==numext::real(m3.innerVector(j).lastCoeff()));
+ }
+
+ VERIFY(m3.innerVector(j0).nonZeros() == m3.transpose().innerVector(j0).nonZeros());
+
+// m2.innerVector(j0) = 2*m2.innerVector(j1);
+// refMat2.col(j0) = 2*refMat2.col(j1);
+// VERIFY_IS_APPROX(m2, refMat2);
+ }
+
+ // test innerVectors()
+ {
+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, cols);
+ SparseMatrixType m2(rows, cols);
+ initSparse<Scalar>(density, refMat2, m2);
+ if(internal::random<float>(0,1)>0.5) m2.makeCompressed();
+ Index j0 = internal::random<Index>(0,outer-2);
+ Index j1 = internal::random<Index>(0,outer-2);
+ Index n0 = internal::random<Index>(1,outer-(std::max)(j0,j1));
+ if(SparseMatrixType::IsRowMajor)
+ VERIFY_IS_APPROX(m2.innerVectors(j0,n0), refMat2.block(j0,0,n0,cols));
+ else
+ VERIFY_IS_APPROX(m2.innerVectors(j0,n0), refMat2.block(0,j0,rows,n0));
+ if(SparseMatrixType::IsRowMajor)
+ VERIFY_IS_APPROX(m2.innerVectors(j0,n0)+m2.innerVectors(j1,n0),
+ refMat2.middleRows(j0,n0)+refMat2.middleRows(j1,n0));
+ else
+ VERIFY_IS_APPROX(m2.innerVectors(j0,n0)+m2.innerVectors(j1,n0),
+ refMat2.block(0,j0,rows,n0)+refMat2.block(0,j1,rows,n0));
+
+ VERIFY_IS_APPROX(m2, refMat2);
+
+ VERIFY(m2.innerVectors(j0,n0).nonZeros() == m2.transpose().innerVectors(j0,n0).nonZeros());
+
+ m2.innerVectors(j0,n0) = m2.innerVectors(j0,n0) + m2.innerVectors(j1,n0);
+ if(SparseMatrixType::IsRowMajor)
+ refMat2.middleRows(j0,n0) = (refMat2.middleRows(j0,n0) + refMat2.middleRows(j1,n0)).eval();
+ else
+ refMat2.middleCols(j0,n0) = (refMat2.middleCols(j0,n0) + refMat2.middleCols(j1,n0)).eval();
+
+ VERIFY_IS_APPROX(m2, refMat2);
+ }
+
+ // test generic blocks
+ {
+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, cols);
+ SparseMatrixType m2(rows, cols);
+ initSparse<Scalar>(density, refMat2, m2);
+ Index j0 = internal::random<Index>(0,outer-2);
+ Index j1 = internal::random<Index>(0,outer-2);
+ Index n0 = internal::random<Index>(1,outer-(std::max)(j0,j1));
+ if(SparseMatrixType::IsRowMajor)
+ VERIFY_IS_APPROX(m2.block(j0,0,n0,cols), refMat2.block(j0,0,n0,cols));
+ else
+ VERIFY_IS_APPROX(m2.block(0,j0,rows,n0), refMat2.block(0,j0,rows,n0));
+
+ if(SparseMatrixType::IsRowMajor)
+ VERIFY_IS_APPROX(m2.block(j0,0,n0,cols)+m2.block(j1,0,n0,cols),
+ refMat2.block(j0,0,n0,cols)+refMat2.block(j1,0,n0,cols));
+ else
+ VERIFY_IS_APPROX(m2.block(0,j0,rows,n0)+m2.block(0,j1,rows,n0),
+ refMat2.block(0,j0,rows,n0)+refMat2.block(0,j1,rows,n0));
+
+ Index i = internal::random<Index>(0,m2.outerSize()-1);
+ if(SparseMatrixType::IsRowMajor) {
+ m2.innerVector(i) = m2.innerVector(i) * s1;
+ refMat2.row(i) = refMat2.row(i) * s1;
+ VERIFY_IS_APPROX(m2,refMat2);
+ } else {
+ m2.innerVector(i) = m2.innerVector(i) * s1;
+ refMat2.col(i) = refMat2.col(i) * s1;
+ VERIFY_IS_APPROX(m2,refMat2);
+ }
+
+ Index r0 = internal::random<Index>(0,rows-2);
+ Index c0 = internal::random<Index>(0,cols-2);
+ Index r1 = internal::random<Index>(1,rows-r0);
+ Index c1 = internal::random<Index>(1,cols-c0);
+
+ VERIFY_IS_APPROX(DenseVector(m2.col(c0)), refMat2.col(c0));
+ VERIFY_IS_APPROX(m2.col(c0), refMat2.col(c0));
+
+ VERIFY_IS_APPROX(RowDenseVector(m2.row(r0)), refMat2.row(r0));
+ VERIFY_IS_APPROX(m2.row(r0), refMat2.row(r0));
+
+ VERIFY_IS_APPROX(m2.block(r0,c0,r1,c1), refMat2.block(r0,c0,r1,c1));
+ VERIFY_IS_APPROX((2*m2).block(r0,c0,r1,c1), (2*refMat2).block(r0,c0,r1,c1));
+ }
+}
+
+void test_sparse_block()
+{
+ for(int i = 0; i < g_repeat; i++) {
+ int r = Eigen::internal::random<int>(1,200), c = Eigen::internal::random<int>(1,200);
+ if(Eigen::internal::random<int>(0,4) == 0) {
+ r = c; // check square matrices in 25% of tries
+ }
+ EIGEN_UNUSED_VARIABLE(r+c);
+ CALL_SUBTEST_1(( sparse_block(SparseMatrix<double>(1, 1)) ));
+ CALL_SUBTEST_1(( sparse_block(SparseMatrix<double>(8, 8)) ));
+ CALL_SUBTEST_1(( sparse_block(SparseMatrix<double>(r, c)) ));
+ CALL_SUBTEST_2(( sparse_block(SparseMatrix<std::complex<double>, ColMajor>(r, c)) ));
+ CALL_SUBTEST_2(( sparse_block(SparseMatrix<std::complex<double>, RowMajor>(r, c)) ));
+
+ CALL_SUBTEST_3(( sparse_block(SparseMatrix<double,ColMajor,long int>(r, c)) ));
+ CALL_SUBTEST_3(( sparse_block(SparseMatrix<double,RowMajor,long int>(r, c)) ));
+
+ r = Eigen::internal::random<int>(1,100);
+ c = Eigen::internal::random<int>(1,100);
+ if(Eigen::internal::random<int>(0,4) == 0) {
+ r = c; // check square matrices in 25% of tries
+ }
+
+ CALL_SUBTEST_4(( sparse_block(SparseMatrix<double,ColMajor,short int>(short(r), short(c))) ));
+ CALL_SUBTEST_4(( sparse_block(SparseMatrix<double,RowMajor,short int>(short(r), short(c))) ));
+ }
+}
diff --git a/test/sparse_product.cpp b/test/sparse_product.cpp
index 480a660fc..3bad3def7 100644
--- a/test/sparse_product.cpp
+++ b/test/sparse_product.cpp
@@ -67,6 +67,9 @@ template<typename SparseMatrixType> void sparse_product()
VERIFY_IS_APPROX(m4 = m2*m3/s1, refMat4 = refMat2*refMat3/s1);
VERIFY_IS_APPROX(m4 = m2*m3*s1, refMat4 = refMat2*refMat3*s1);
VERIFY_IS_APPROX(m4 = s2*m2*m3*s1, refMat4 = s2*refMat2*refMat3*s1);
+ VERIFY_IS_APPROX(m4 = (m2+m2)*m3, refMat4 = (refMat2+refMat2)*refMat3);
+ VERIFY_IS_APPROX(m4 = m2*m3.leftCols(cols/2), refMat4 = refMat2*refMat3.leftCols(cols/2));
+ VERIFY_IS_APPROX(m4 = m2*(m3+m3).leftCols(cols/2), refMat4 = refMat2*(refMat3+refMat3).leftCols(cols/2));
VERIFY_IS_APPROX(m4=(m2*m3).pruned(0), refMat4=refMat2*refMat3);
VERIFY_IS_APPROX(m4=(m2t.transpose()*m3).pruned(0), refMat4=refMat2t.transpose()*refMat3);
@@ -194,7 +197,7 @@ template<typename SparseMatrixType> void sparse_product()
VERIFY_IS_APPROX(d3=d1*m2.transpose(), refM3=d1*refM2.transpose());
}
- // test self-adjoint and traingular-view products
+ // test self-adjoint and triangular-view products
{
DenseMatrix b = DenseMatrix::Random(rows, rows);
DenseMatrix x = DenseMatrix::Random(rows, rows);
diff --git a/test/svd_common.h b/test/svd_common.h
index 4c172cf9d..b44b79124 100644
--- a/test/svd_common.h
+++ b/test/svd_common.h
@@ -49,18 +49,39 @@ void svd_compare_to_full(const MatrixType& m,
unsigned int computationOptions,
const SvdType& referenceSvd)
{
- typedef typename MatrixType::Index Index;
+ typedef typename MatrixType::RealScalar RealScalar;
Index rows = m.rows();
Index cols = m.cols();
Index diagSize = (std::min)(rows, cols);
+ RealScalar prec = test_precision<RealScalar>();
SvdType svd(m, computationOptions);
VERIFY_IS_APPROX(svd.singularValues(), referenceSvd.singularValues());
+
+ if(computationOptions & (ComputeFullV|ComputeThinV))
+ {
+ VERIFY( (svd.matrixV().adjoint()*svd.matrixV()).isIdentity(prec) );
+ VERIFY_IS_APPROX( svd.matrixV().leftCols(diagSize) * svd.singularValues().asDiagonal() * svd.matrixV().leftCols(diagSize).adjoint(),
+ referenceSvd.matrixV().leftCols(diagSize) * referenceSvd.singularValues().asDiagonal() * referenceSvd.matrixV().leftCols(diagSize).adjoint());
+ }
+
+ if(computationOptions & (ComputeFullU|ComputeThinU))
+ {
+ VERIFY( (svd.matrixU().adjoint()*svd.matrixU()).isIdentity(prec) );
+ VERIFY_IS_APPROX( svd.matrixU().leftCols(diagSize) * svd.singularValues().cwiseAbs2().asDiagonal() * svd.matrixU().leftCols(diagSize).adjoint(),
+ referenceSvd.matrixU().leftCols(diagSize) * referenceSvd.singularValues().cwiseAbs2().asDiagonal() * referenceSvd.matrixU().leftCols(diagSize).adjoint());
+ }
+
+ // The following checks are not critical.
+ // For instance, with Dived&Conquer SVD, if only the factor 'V' is computedt then different matrix-matrix product implementation will be used
+ // and the resulting 'V' factor might be significantly different when the SVD decomposition is not unique, especially with single precision float.
+ ++g_test_level;
if(computationOptions & ComputeFullU) VERIFY_IS_APPROX(svd.matrixU(), referenceSvd.matrixU());
if(computationOptions & ComputeThinU) VERIFY_IS_APPROX(svd.matrixU(), referenceSvd.matrixU().leftCols(diagSize));
- if(computationOptions & ComputeFullV) VERIFY_IS_APPROX(svd.matrixV(), referenceSvd.matrixV());
+ if(computationOptions & ComputeFullV) VERIFY_IS_APPROX(svd.matrixV().cwiseAbs(), referenceSvd.matrixV().cwiseAbs());
if(computationOptions & ComputeThinV) VERIFY_IS_APPROX(svd.matrixV(), referenceSvd.matrixV().leftCols(diagSize));
+ --g_test_level;
}
//
@@ -85,33 +106,48 @@ void svd_least_square(const MatrixType& m, unsigned int computationOptions)
SvdType 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);
-
+ else if(internal::is_same<RealScalar,float>::value) svd.setThreshold(2e-4);
+
SolutionType x = svd.solve(rhs);
-
- // evaluate normal equation which works also for least-squares solutions
- if(internal::is_same<RealScalar,double>::value || svd.rank()==m.diagonal().size())
- {
- // 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);
- }
-
+
RealScalar residual = (m*x-rhs).norm();
- // Check that there is no significantly better solution in the neighborhood of x
+ RealScalar rhs_norm = rhs.norm();
if(!test_isMuchSmallerThan(residual,rhs.norm()))
{
// ^^^ If the residual is very small, then we have an exact solution, so we are already good.
+
+ // evaluate normal equation which works also for least-squares solutions
+ if(internal::is_same<RealScalar,double>::value || svd.rank()==m.diagonal().size())
+ {
+ using std::sqrt;
+ // This test is not stable with single precision.
+ // This is probably because squaring m signicantly affects the precision.
+ if(internal::is_same<RealScalar,float>::value) ++g_test_level;
+
+ VERIFY_IS_APPROX(m.adjoint()*(m*x),m.adjoint()*rhs);
+
+ if(internal::is_same<RealScalar,float>::value) --g_test_level;
+ }
+
+ // Check that there is no significantly better solution in the neighborhood of x
for(Index k=0;k<x.rows();++k)
{
+ using std::abs;
+
SolutionType y(x);
y.row(k) = (1.+2*NumTraits<RealScalar>::epsilon())*x.row(k);
RealScalar residual_y = (m*y-rhs).norm();
+ VERIFY( test_isMuchSmallerThan(abs(residual_y-residual), rhs_norm) || residual < residual_y );
+ if(internal::is_same<RealScalar,float>::value) ++g_test_level;
VERIFY( test_isApprox(residual_y,residual) || residual < residual_y );
+ if(internal::is_same<RealScalar,float>::value) --g_test_level;
y.row(k) = (1.-2*NumTraits<RealScalar>::epsilon())*x.row(k);
residual_y = (m*y-rhs).norm();
+ VERIFY( test_isMuchSmallerThan(abs(residual_y-residual), rhs_norm) || residual < residual_y );
+ if(internal::is_same<RealScalar,float>::value) ++g_test_level;
VERIFY( test_isApprox(residual_y,residual) || residual < residual_y );
+ if(internal::is_same<RealScalar,float>::value) --g_test_level;
}
}
}
diff --git a/test/swap.cpp b/test/swap.cpp
index dc3610085..5d6f0e6af 100644
--- a/test/swap.cpp
+++ b/test/swap.cpp
@@ -82,8 +82,10 @@ template<typename MatrixType> void swap(const MatrixType& m)
void test_swap()
{
+ int s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
CALL_SUBTEST_1( swap(Matrix3f()) ); // fixed size, no vectorization
CALL_SUBTEST_2( swap(Matrix4d()) ); // fixed size, possible vectorization
- CALL_SUBTEST_3( swap(MatrixXd(3,3)) ); // dyn size, no vectorization
- CALL_SUBTEST_4( swap(MatrixXf(30,30)) ); // dyn size, possible vectorization
+ CALL_SUBTEST_3( swap(MatrixXd(s,s)) ); // dyn size, no vectorization
+ CALL_SUBTEST_4( swap(MatrixXf(s,s)) ); // dyn size, possible vectorization
+ TEST_SET_BUT_UNUSED_VARIABLE(s)
}
diff --git a/test/unalignedassert.cpp b/test/unalignedassert.cpp
index d8815263a..9c6f0bc8f 100644
--- a/test/unalignedassert.cpp
+++ b/test/unalignedassert.cpp
@@ -9,7 +9,17 @@
#include "main.h"
-typedef Matrix<float,8,1> Vector8f;
+typedef Matrix<float, 6,1> Vector6f;
+typedef Matrix<float, 8,1> Vector8f;
+typedef Matrix<float, 12,1> Vector12f;
+
+typedef Matrix<double, 5,1> Vector5d;
+typedef Matrix<double, 6,1> Vector6d;
+typedef Matrix<double, 7,1> Vector7d;
+typedef Matrix<double, 8,1> Vector8d;
+typedef Matrix<double, 9,1> Vector9d;
+typedef Matrix<double,10,1> Vector10d;
+typedef Matrix<double,12,1> Vector12d;
struct TestNew1
{
@@ -81,10 +91,13 @@ void construct_at_boundary(int boundary)
void unalignedassert()
{
- #if EIGEN_ALIGN_STATICALLY
+#if EIGEN_ALIGN_STATICALLY
construct_at_boundary<Vector2f>(4);
construct_at_boundary<Vector3f>(4);
construct_at_boundary<Vector4f>(16);
+ construct_at_boundary<Vector6f>(4);
+ construct_at_boundary<Vector8f>(EIGEN_ALIGN_BYTES);
+ construct_at_boundary<Vector12f>(16);
construct_at_boundary<Matrix2f>(16);
construct_at_boundary<Matrix3f>(4);
construct_at_boundary<Matrix4f>(EIGEN_ALIGN_BYTES);
@@ -92,6 +105,13 @@ void unalignedassert()
construct_at_boundary<Vector2d>(16);
construct_at_boundary<Vector3d>(4);
construct_at_boundary<Vector4d>(EIGEN_ALIGN_BYTES);
+ construct_at_boundary<Vector5d>(4);
+ construct_at_boundary<Vector6d>(16);
+ construct_at_boundary<Vector7d>(4);
+ construct_at_boundary<Vector8d>(EIGEN_ALIGN_BYTES);
+ construct_at_boundary<Vector9d>(4);
+ construct_at_boundary<Vector10d>(16);
+ construct_at_boundary<Vector12d>(EIGEN_ALIGN_BYTES);
construct_at_boundary<Matrix2d>(EIGEN_ALIGN_BYTES);
construct_at_boundary<Matrix3d>(4);
construct_at_boundary<Matrix4d>(EIGEN_ALIGN_BYTES);
@@ -100,7 +120,7 @@ void unalignedassert()
construct_at_boundary<Vector3cf>(4);
construct_at_boundary<Vector2cd>(EIGEN_ALIGN_BYTES);
construct_at_boundary<Vector3cd>(16);
- #endif
+#endif
check_unalignedassert_good<TestNew1>();
check_unalignedassert_good<TestNew2>();
@@ -112,11 +132,19 @@ void unalignedassert()
check_unalignedassert_good<Depends<true> >();
#if EIGEN_ALIGN_STATICALLY
- if(EIGEN_ALIGN_BYTES==16)
+ if(EIGEN_ALIGN_BYTES>=16)
{
VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4f>(8));
+ VERIFY_RAISES_ASSERT(construct_at_boundary<Vector8f>(8));
+ VERIFY_RAISES_ASSERT(construct_at_boundary<Vector12f>(8));
VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2d>(8));
+ VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4d>(8));
+ VERIFY_RAISES_ASSERT(construct_at_boundary<Vector6d>(8));
+ VERIFY_RAISES_ASSERT(construct_at_boundary<Vector8d>(8));
+ VERIFY_RAISES_ASSERT(construct_at_boundary<Vector10d>(8));
+ VERIFY_RAISES_ASSERT(construct_at_boundary<Vector12d>(8));
VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2cf>(8));
+ VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4i>(8));
}
for(int b=8; b<EIGEN_ALIGN_BYTES; b+=8)
{
diff --git a/test/vectorization_logic.cpp b/test/vectorization_logic.cpp
index 2f839cf51..97477072a 100644
--- a/test/vectorization_logic.cpp
+++ b/test/vectorization_logic.cpp
@@ -214,7 +214,7 @@ template<typename Scalar, bool Enable = internal::packet_traits<Scalar>::Vectori
>(DefaultTraversal,CompleteUnrolling)));
VERIFY((test_assign(Matrix11(), Matrix<Scalar,PacketSize,EIGEN_PLAIN_ENUM_MIN(2,PacketSize)>()*Matrix<Scalar,EIGEN_PLAIN_ENUM_MIN(2,PacketSize),PacketSize>(),
- PacketSize>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD?DefaultTraversal:InnerVectorizedTraversal, CompleteUnrolling)));
+ InnerVectorizedTraversal, CompleteUnrolling)));
#endif
VERIFY(test_assign(MatrixXX(10,10),MatrixXX(20,20).block(10,10,2,3),