diff options
author | Mark Borgerding <mark@borgerding.net> | 2010-03-07 23:46:26 -0500 |
---|---|---|
committer | Mark Borgerding <mark@borgerding.net> | 2010-03-07 23:46:26 -0500 |
commit | 101cc03176d6705e27b8576a4ce6fbb86c8f3055 (patch) | |
tree | c9de0f65908ec6fc55d1b8a23a536f744a18bfdc /test | |
parent | e31929337e8732a32aca21b0343dae22fbced510 (diff) | |
parent | 9fe040ad29400f152b392fff9dc1493a6b9c14aa (diff) |
merge
Diffstat (limited to 'test')
-rw-r--r-- | test/CMakeLists.txt | 4 | ||||
-rw-r--r-- | test/block.cpp (renamed from test/submatrices.cpp) | 151 | ||||
-rw-r--r-- | test/cholesky.cpp | 7 | ||||
-rw-r--r-- | test/diagonal.cpp | 81 | ||||
-rw-r--r-- | test/geo_transformations.cpp | 11 | ||||
-rw-r--r-- | test/inverse.cpp | 2 | ||||
-rw-r--r-- | test/lu.cpp | 95 | ||||
-rw-r--r-- | test/main.h | 61 | ||||
-rw-r--r-- | test/map.cpp | 14 | ||||
-rw-r--r-- | test/mapstride.cpp | 139 | ||||
-rw-r--r-- | test/mixingtypes.cpp | 6 | ||||
-rw-r--r-- | test/packetmath.cpp | 5 | ||||
-rw-r--r-- | test/permutationmatrices.cpp | 23 | ||||
-rw-r--r-- | test/product_symm.cpp | 8 | ||||
-rw-r--r-- | test/product_syrk.cpp | 4 | ||||
-rw-r--r-- | test/product_trsolve.cpp | 11 | ||||
-rw-r--r-- | test/qr.cpp | 1 | ||||
-rw-r--r-- | test/qr_colpivoting.cpp | 4 | ||||
-rw-r--r-- | test/qr_fullpivoting.cpp | 2 | ||||
-rw-r--r-- | test/testsuite.cmake | 3 | ||||
-rw-r--r-- | test/unalignedassert.cpp | 6 | ||||
-rw-r--r-- | test/vectorization_logic.cpp | 18 |
22 files changed, 523 insertions, 133 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b0da2a1d8..072f63e1d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -104,16 +104,18 @@ ei_add_test(cwiseop) ei_add_test(unalignedcount) ei_add_test(redux) ei_add_test(visitor) +ei_add_test(block) ei_add_test(product_small) ei_add_test(product_large) ei_add_test(product_extra) ei_add_test(diagonalmatrices) ei_add_test(adjoint) -ei_add_test(submatrices) +ei_add_test(diagonal) ei_add_test(miscmatrices) ei_add_test(commainitializer) ei_add_test(smallvectors) ei_add_test(map) +ei_add_test(mapstride) ei_add_test(array) ei_add_test(array_for_matrix) ei_add_test(array_replicate) diff --git a/test/submatrices.cpp b/test/block.cpp index d53fd4b6f..c180afb75 100644 --- a/test/submatrices.cpp +++ b/test/block.cpp @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // // Eigen is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -51,16 +51,18 @@ template<typename Scalar> struct CheckMinor<Scalar,1,1> CheckMinor(MatrixType&, int, int) {} }; -template<typename MatrixType> void submatrices(const MatrixType& m) +template<typename MatrixType> void block(const MatrixType& m) { /* this test covers the following files: - Row.h Column.h Block.h Minor.h DiagonalCoeffs.h + Row.h Column.h Block.h Minor.h */ typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::RealScalar RealScalar; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType; typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType; - typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType; + typedef Matrix<Scalar, Dynamic, Dynamic> DynamicMatrixType; + typedef Matrix<Scalar, Dynamic, 1> DynamicVectorType; + int rows = m.rows(); int cols = m.cols(); @@ -69,8 +71,6 @@ template<typename MatrixType> void submatrices(const MatrixType& m) m3(rows, cols), mzero = MatrixType::Zero(rows, cols), ones = MatrixType::Ones(rows, cols); - SquareMatrixType identity = SquareMatrixType::Identity(rows, rows), - square = SquareMatrixType::Random(rows, rows); VectorType v1 = VectorType::Random(rows), v2 = VectorType::Random(rows), v3 = VectorType::Random(rows), @@ -84,20 +84,19 @@ template<typename MatrixType> void submatrices(const MatrixType& m) int c2 = ei_random<int>(c1,cols-1); //check row() and col() - VERIFY_IS_APPROX(m1.col(c1).transpose(), m1.transpose().row(c1)); - // FIXME perhaps we should re-enable that without the .eval() - VERIFY_IS_APPROX(m1.col(c1).dot(square.row(r1)), (square * m1.conjugate()).eval()(r1,c1)); + VERIFY_IS_EQUAL(m1.col(c1).transpose(), m1.transpose().row(c1)); //check operator(), both constant and non-constant, on row() and col() m1.row(r1) += s1 * m1.row(r2); m1.col(c1) += s1 * m1.col(c2); //check block() Matrix<Scalar,Dynamic,Dynamic> b1(1,1); b1(0,0) = m1(r1,c1); + RowVectorType br1(m1.block(r1,0,1,cols)); VectorType bc1(m1.block(0,c1,rows,1)); - VERIFY_IS_APPROX(b1, m1.block(r1,c1,1,1)); - VERIFY_IS_APPROX(m1.row(r1), br1); - VERIFY_IS_APPROX(m1.col(c1), bc1); + VERIFY_IS_EQUAL(b1, m1.block(r1,c1,1,1)); + VERIFY_IS_EQUAL(m1.row(r1), br1); + VERIFY_IS_EQUAL(m1.col(c1), bc1); //check operator(), both constant and non-constant, on block() m1.block(r1,c1,r2-r1+1,c2-c1+1) = s1 * m2.block(0, 0, r2-r1+1,c2-c1+1); m1.block(r1,c1,r2-r1+1,c2-c1+1)(r2-r1,c2-c1) = m2.block(0, 0, r2-r1+1,c2-c1+1)(0,0); @@ -105,11 +104,6 @@ template<typename MatrixType> void submatrices(const MatrixType& m) //check minor() CheckMinor<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime> checkminor(m1,r1,c1); - //check diagonal() - VERIFY_IS_APPROX(m1.diagonal(), m1.transpose().diagonal()); - m2.diagonal() = 2 * m1.diagonal(); - m2.diagonal()[0] *= 3; - const int BlockRows = EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime,2); const int BlockCols = EIGEN_ENUM_MIN(MatrixType::ColsAtCompileTime,5); if (rows>=5 && cols>=8) @@ -120,45 +114,23 @@ template<typename MatrixType> void submatrices(const MatrixType& m) m1.template block<BlockRows,BlockCols>(1,1)(0, 3) = m1.template block<2,5>(1,1)(1,2); // check that fixed block() and block() agree Matrix<Scalar,Dynamic,Dynamic> b = m1.template block<BlockRows,BlockCols>(3,3); - VERIFY_IS_APPROX(b, m1.block(3,3,BlockRows,BlockCols)); + VERIFY_IS_EQUAL(b, m1.block(3,3,BlockRows,BlockCols)); } if (rows>2) { // test sub vectors - VERIFY_IS_APPROX(v1.template head<2>(), v1.block(0,0,2,1)); - VERIFY_IS_APPROX(v1.template head<2>(), v1.head(2)); - VERIFY_IS_APPROX(v1.template head<2>(), v1.segment(0,2)); - VERIFY_IS_APPROX(v1.template head<2>(), v1.template segment<2>(0)); + VERIFY_IS_EQUAL(v1.template head<2>(), v1.block(0,0,2,1)); + VERIFY_IS_EQUAL(v1.template head<2>(), v1.head(2)); + VERIFY_IS_EQUAL(v1.template head<2>(), v1.segment(0,2)); + VERIFY_IS_EQUAL(v1.template head<2>(), v1.template segment<2>(0)); int i = rows-2; - VERIFY_IS_APPROX(v1.template tail<2>(), v1.block(i,0,2,1)); - VERIFY_IS_APPROX(v1.template tail<2>(), v1.tail(2)); - VERIFY_IS_APPROX(v1.template tail<2>(), v1.segment(i,2)); - VERIFY_IS_APPROX(v1.template tail<2>(), v1.template segment<2>(i)); + VERIFY_IS_EQUAL(v1.template tail<2>(), v1.block(i,0,2,1)); + VERIFY_IS_EQUAL(v1.template tail<2>(), v1.tail(2)); + VERIFY_IS_EQUAL(v1.template tail<2>(), v1.segment(i,2)); + VERIFY_IS_EQUAL(v1.template tail<2>(), v1.template segment<2>(i)); i = ei_random(0,rows-2); - VERIFY_IS_APPROX(v1.segment(i,2), v1.template segment<2>(i)); - - enum { - N1 = MatrixType::RowsAtCompileTime>1 ? 1 : 0, - N2 = MatrixType::RowsAtCompileTime>2 ? -2 : 0 - }; - - // check sub/super diagonal - m2.template diagonal<N1>() = 2 * m1.template diagonal<N1>(); - m2.template diagonal<N1>()[0] *= 3; - VERIFY_IS_APPROX(m2.template diagonal<N1>()[0], static_cast<Scalar>(6) * m1.template diagonal<N1>()[0]); - - m2.template diagonal<N2>() = 2 * m1.template diagonal<N2>(); - m2.template diagonal<N2>()[0] *= 3; - VERIFY_IS_APPROX(m2.template diagonal<N2>()[0], static_cast<Scalar>(6) * m1.template diagonal<N2>()[0]); - - m2.diagonal(N1) = 2 * m1.diagonal(N1); - m2.diagonal(N1)[0] *= 3; - VERIFY_IS_APPROX(m2.diagonal(N1)[0], static_cast<Scalar>(6) * m1.diagonal(N1)[0]); - - m2.diagonal(N2) = 2 * m1.diagonal(N2); - m2.diagonal(N2)[0] *= 3; - VERIFY_IS_APPROX(m2.diagonal(N2)[0], static_cast<Scalar>(6) * m1.diagonal(N2)[0]); + VERIFY_IS_EQUAL(v1.segment(i,2), v1.template segment<2>(i)); } // stress some basic stuffs with block matrices @@ -167,6 +139,49 @@ template<typename MatrixType> void submatrices(const MatrixType& m) VERIFY(ei_real(ones.col(c1).dot(ones.col(c2))) == RealScalar(rows)); VERIFY(ei_real(ones.row(r1).dot(ones.row(r2))) == RealScalar(cols)); + + // now test some block-inside-of-block. + + // expressions with direct access + VERIFY_IS_EQUAL( (m1.block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2)) , (m1.block(r2,c2,rows-r2,cols-c2)) ); + VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).row(0)) , (m1.row(r1).segment(c1,c2-c1+1)) ); + VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).col(0)) , (m1.col(c1).segment(r1,r2-r1+1)) ); + VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0)) , (m1.row(r1).segment(c1,c2-c1+1)) ); + VERIFY_IS_EQUAL( (m1.transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0)) , (m1.row(r1).segment(c1,c2-c1+1)) ); + + // expressions without direct access + VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2)) , ((m1+m2).block(r2,c2,rows-r2,cols-c2)) ); + VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).row(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)) ); + VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).col(0)) , ((m1+m2).col(c1).segment(r1,r2-r1+1)) ); + VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)) ); + VERIFY_IS_EQUAL( ((m1+m2).transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)) ); + + // evaluation into plain matrices from expressions with direct access (stress MapBase) + DynamicMatrixType dm; + DynamicVectorType dv; + dm.setZero(); + dm = m1.block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2); + VERIFY_IS_EQUAL(dm, (m1.block(r2,c2,rows-r2,cols-c2))); + dm.setZero(); + dv.setZero(); + dm = m1.block(r1,c1,r2-r1+1,c2-c1+1).row(0).transpose(); + dv = m1.row(r1).segment(c1,c2-c1+1); + VERIFY_IS_EQUAL(dv, dm); + dm.setZero(); + dv.setZero(); + dm = m1.col(c1).segment(r1,r2-r1+1); + dv = m1.block(r1,c1,r2-r1+1,c2-c1+1).col(0); + VERIFY_IS_EQUAL(dv, dm); + dm.setZero(); + dv.setZero(); + dm = m1.block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0); + dv = m1.row(r1).segment(c1,c2-c1+1); + VERIFY_IS_EQUAL(dv, dm); + dm.setZero(); + dv.setZero(); + dm = m1.row(r1).segment(c1,c2-c1+1).transpose(); + dv = m1.transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0); + VERIFY_IS_EQUAL(dv, dm); } @@ -176,18 +191,30 @@ void compare_using_data_and_stride(const MatrixType& m) int rows = m.rows(); int cols = m.cols(); int size = m.size(); - int stride = m.stride(); + int innerStride = m.innerStride(); + int outerStride = m.outerStride(); + int rowStride = m.rowStride(); + int colStride = m.colStride(); const typename MatrixType::Scalar* data = m.data(); for(int j=0;j<cols;++j) for(int i=0;i<rows;++i) - VERIFY_IS_APPROX(m.coeff(i,j), data[(MatrixType::Flags&RowMajorBit) ? i*stride+j : j*stride + i]); + VERIFY(m.coeff(i,j) == data[i*rowStride + j*colStride]); + + if(!MatrixType::IsVectorAtCompileTime) + { + for(int j=0;j<cols;++j) + for(int i=0;i<rows;++i) + VERIFY(m.coeff(i,j) == data[(MatrixType::Flags&RowMajorBit) + ? i*outerStride + j*innerStride + : j*outerStride + i*innerStride]); + } if(MatrixType::IsVectorAtCompileTime) { - VERIFY_IS_APPROX(stride, int((&m.coeff(1))-(&m.coeff(0)))); + VERIFY(innerStride == int((&m.coeff(1))-(&m.coeff(0)))); for (int i=0;i<size;++i) - VERIFY_IS_APPROX(m.coeff(i), data[i*stride]); + VERIFY(m.coeff(i) == data[i*innerStride]); } } @@ -211,19 +238,21 @@ void data_and_stride(const MatrixType& m) compare_using_data_and_stride(m1.col(c1).transpose()); } -void test_submatrices() +void test_block() { for(int i = 0; i < g_repeat; i++) { - CALL_SUBTEST_1( submatrices(Matrix<float, 1, 1>()) ); - CALL_SUBTEST_2( submatrices(Matrix4d()) ); - CALL_SUBTEST_3( submatrices(MatrixXcf(3, 3)) ); - CALL_SUBTEST_4( submatrices(MatrixXi(8, 12)) ); - CALL_SUBTEST_5( submatrices(MatrixXcd(20, 20)) ); - CALL_SUBTEST_6( submatrices(MatrixXf(20, 20)) ); + CALL_SUBTEST_1( block(Matrix<float, 1, 1>()) ); + CALL_SUBTEST_2( block(Matrix4d()) ); + CALL_SUBTEST_3( block(MatrixXcf(3, 3)) ); + CALL_SUBTEST_4( block(MatrixXi(8, 12)) ); + CALL_SUBTEST_5( block(MatrixXcd(20, 20)) ); + CALL_SUBTEST_6( block(MatrixXf(20, 20)) ); - CALL_SUBTEST_8( submatrices(Matrix<float,Dynamic,4>(3, 4)) ); + CALL_SUBTEST_8( block(Matrix<float,Dynamic,4>(3, 4)) ); +#ifndef EIGEN_DEFAULT_TO_ROW_MAJOR CALL_SUBTEST_6( data_and_stride(MatrixXf(ei_random(5,50), ei_random(5,50))) ); CALL_SUBTEST_7( data_and_stride(Matrix<int,Dynamic,Dynamic,RowMajor>(ei_random(5,50), ei_random(5,50))) ); +#endif } } diff --git a/test/cholesky.cpp b/test/cholesky.cpp index 1bb808d20..a446f5d73 100644 --- a/test/cholesky.cpp +++ b/test/cholesky.cpp @@ -95,7 +95,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m) { LLT<SquareMatrixType,Lower> chollo(symmLo); - VERIFY_IS_APPROX(symm, chollo.matrixL().toDenseMatrix() * chollo.matrixL().adjoint().toDenseMatrix()); + VERIFY_IS_APPROX(symm, chollo.reconstructedMatrix()); vecX = chollo.solve(vecB); VERIFY_IS_APPROX(symm * vecX, vecB); matX = chollo.solve(matB); @@ -103,7 +103,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m) // test the upper mode LLT<SquareMatrixType,Upper> cholup(symmUp); - VERIFY_IS_APPROX(symm, cholup.matrixL().toDenseMatrix() * cholup.matrixL().adjoint().toDenseMatrix()); + VERIFY_IS_APPROX(symm, cholup.reconstructedMatrix()); vecX = cholup.solve(vecB); VERIFY_IS_APPROX(symm * vecX, vecB); matX = cholup.solve(matB); @@ -119,8 +119,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m) { LDLT<SquareMatrixType> ldlt(symm); - // TODO(keir): This doesn't make sense now that LDLT pivots. - //VERIFY_IS_APPROX(symm, ldlt.matrixL() * ldlt.vectorD().asDiagonal() * ldlt.matrixL().adjoint()); + VERIFY_IS_APPROX(symm, ldlt.reconstructedMatrix()); vecX = ldlt.solve(vecB); VERIFY_IS_APPROX(symm * vecX, vecB); matX = ldlt.solve(matB); diff --git a/test/diagonal.cpp b/test/diagonal.cpp new file mode 100644 index 000000000..288d58c6e --- /dev/null +++ b/test/diagonal.cpp @@ -0,0 +1,81 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see <http://www.gnu.org/licenses/>. + +#include "main.h" + +template<typename MatrixType> void diagonal(const MatrixType& m) +{ + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType; + typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType; + int rows = m.rows(); + int cols = m.cols(); + + MatrixType m1 = MatrixType::Random(rows, cols), + m2 = MatrixType::Random(rows, cols); + + //check diagonal() + VERIFY_IS_APPROX(m1.diagonal(), m1.transpose().diagonal()); + m2.diagonal() = 2 * m1.diagonal(); + m2.diagonal()[0] *= 3; + + if (rows>2) + { + enum { + N1 = MatrixType::RowsAtCompileTime>1 ? 1 : 0, + N2 = MatrixType::RowsAtCompileTime>2 ? -2 : 0 + }; + + // check sub/super diagonal + m2.template diagonal<N1>() = 2 * m1.template diagonal<N1>(); + m2.template diagonal<N1>()[0] *= 3; + VERIFY_IS_APPROX(m2.template diagonal<N1>()[0], static_cast<Scalar>(6) * m1.template diagonal<N1>()[0]); + + m2.template diagonal<N2>() = 2 * m1.template diagonal<N2>(); + m2.template diagonal<N2>()[0] *= 3; + VERIFY_IS_APPROX(m2.template diagonal<N2>()[0], static_cast<Scalar>(6) * m1.template diagonal<N2>()[0]); + + m2.diagonal(N1) = 2 * m1.diagonal(N1); + m2.diagonal(N1)[0] *= 3; + VERIFY_IS_APPROX(m2.diagonal(N1)[0], static_cast<Scalar>(6) * m1.diagonal(N1)[0]); + + m2.diagonal(N2) = 2 * m1.diagonal(N2); + m2.diagonal(N2)[0] *= 3; + VERIFY_IS_APPROX(m2.diagonal(N2)[0], static_cast<Scalar>(6) * m1.diagonal(N2)[0]); + } +} + +void test_diagonal() +{ + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST_1( diagonal(Matrix<float, 1, 1>()) ); + CALL_SUBTEST_2( diagonal(Matrix4d()) ); + CALL_SUBTEST_2( diagonal(MatrixXcf(3, 3)) ); + CALL_SUBTEST_2( diagonal(MatrixXi(8, 12)) ); + CALL_SUBTEST_2( diagonal(MatrixXcd(20, 20)) ); + CALL_SUBTEST_1( diagonal(MatrixXf(21, 19)) ); + CALL_SUBTEST_1( diagonal(Matrix<float,Dynamic,4>(3, 4)) ); + } +} diff --git a/test/geo_transformations.cpp b/test/geo_transformations.cpp index 895fe0f08..b1a50f6b2 100644 --- a/test/geo_transformations.cpp +++ b/test/geo_transformations.cpp @@ -59,6 +59,7 @@ template<typename Scalar, int Mode> void transformations(void) Matrix3 matrot1, m; Scalar a = ei_random<Scalar>(-Scalar(M_PI), Scalar(M_PI)); + Scalar s0 = ei_random<Scalar>(); VERIFY_IS_APPROX(v0, AngleAxisx(a, v0.normalized()) * v0); VERIFY_IS_APPROX(-v0, AngleAxisx(Scalar(M_PI), v0.unitOrthogonal()) * v0); @@ -234,6 +235,16 @@ template<typename Scalar, int Mode> void transformations(void) t1 = Matrix3(q1) * (AlignedScaling3(v0) * Translation3(v0)); VERIFY_IS_APPROX(t0.matrix(), t1.matrix()); + + t0.setIdentity(); + t0.scale(s0).translate(v0); + t1 = Scaling(s0) * Translation3(v0); + VERIFY_IS_APPROX(t0.matrix(), t1.matrix()); + t0.prescale(s0); + t1 = Scaling(s0) * t1; + VERIFY_IS_APPROX(t0.matrix(), t1.matrix()); + + t0.setIdentity(); t0.prerotate(q1).prescale(v0).pretranslate(v0); // translation * aligned scaling and transformation * mat diff --git a/test/inverse.cpp b/test/inverse.cpp index 713caf4a6..1e567ad14 100644 --- a/test/inverse.cpp +++ b/test/inverse.cpp @@ -42,7 +42,7 @@ template<typename MatrixType> void inverse(const MatrixType& m) m2(rows, cols), mzero = MatrixType::Zero(rows, cols), identity = MatrixType::Identity(rows, rows); - createRandomMatrixOfRank(rows,rows,rows,m1); + createRandomPIMatrixOfRank(rows,rows,rows,m1); m2 = m1.inverse(); VERIFY_IS_APPROX(m1, m2.inverse() ); diff --git a/test/lu.cpp b/test/lu.cpp index 568db8230..37e2990d2 100644 --- a/test/lu.cpp +++ b/test/lu.cpp @@ -29,6 +29,7 @@ using namespace std; template<typename MatrixType> void lu_non_invertible() { typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; /* this test covers the following files: LU.h */ @@ -51,39 +52,46 @@ template<typename MatrixType> void lu_non_invertible() cols2 = cols = MatrixType::ColsAtCompileTime; } + enum { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime + }; typedef typename ei_kernel_retval_base<FullPivLU<MatrixType> >::ReturnType KernelMatrixType; typedef typename ei_image_retval_base<FullPivLU<MatrixType> >::ReturnType ImageMatrixType; - typedef Matrix<typename MatrixType::Scalar, Dynamic, Dynamic> DynamicMatrixType; - typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime> + typedef Matrix<typename MatrixType::Scalar, ColsAtCompileTime, ColsAtCompileTime> CMatrixType; + typedef Matrix<typename MatrixType::Scalar, RowsAtCompileTime, RowsAtCompileTime> + RMatrixType; int rank = ei_random<int>(1, std::min(rows, cols)-1); // The image of the zero matrix should consist of a single (zero) column vector VERIFY((MatrixType::Zero(rows,cols).fullPivLu().image(MatrixType::Zero(rows,cols)).cols() == 1)); - + MatrixType m1(rows, cols), m3(rows, cols2); CMatrixType m2(cols, cols2); - createRandomMatrixOfRank(rank, rows, cols, m1); - - FullPivLU<MatrixType> lu(m1); - // FIXME need better way to construct trapezoid matrices. extend triangularView to support rectangular. - DynamicMatrixType u(rows,cols); - for(int i = 0; i < rows; i++) - for(int j = 0; j < cols; j++) - u(i,j) = i>j ? Scalar(0) : lu.matrixLU()(i,j); - DynamicMatrixType l(rows,rows); - for(int i = 0; i < rows; i++) - for(int j = 0; j < rows; j++) - l(i,j) = (i<j || j>=cols) ? Scalar(0) - : i==j ? Scalar(1) - : lu.matrixLU()(i,j); - + createRandomPIMatrixOfRank(rank, rows, cols, m1); + + FullPivLU<MatrixType> lu; + + // The special value 0.01 below works well in tests. Keep in mind that we're only computing the rank + // of singular values are either 0 or 1. + // So it's not clear at all that the epsilon should play any role there. + lu.setThreshold(RealScalar(0.01)); + lu.compute(m1); + + MatrixType u(rows,cols); + u = lu.matrixLU().template triangularView<Upper>(); + RMatrixType l = RMatrixType::Identity(rows,rows); + l.block(0,0,rows,std::min(rows,cols)).template triangularView<StrictlyLower>() + = lu.matrixLU().block(0,0,rows,std::min(rows,cols)); + VERIFY_IS_APPROX(lu.permutationP() * m1 * lu.permutationQ(), l*u); - + KernelMatrixType m1kernel = lu.kernel(); ImageMatrixType m1image = lu.image(m1); + VERIFY_IS_APPROX(m1, lu.reconstructedMatrix()); VERIFY(rank == lu.rank()); VERIFY(cols - lu.rank() == lu.dimensionOfKernel()); VERIFY(!lu.isInjective()); @@ -91,9 +99,8 @@ template<typename MatrixType> void lu_non_invertible() VERIFY(!lu.isSurjective()); VERIFY((m1 * m1kernel).isMuchSmallerThan(m1)); VERIFY(m1image.fullPivLu().rank() == rank); - DynamicMatrixType sidebyside(m1.rows(), m1.cols() + m1image.cols()); - sidebyside << m1, m1image; - VERIFY(sidebyside.fullPivLu().rank() == rank); + VERIFY_IS_APPROX(m1 * m1.adjoint() * m1image, m1image); + m2 = CMatrixType::Random(cols,cols2); m3 = m1*m2; m2 = CMatrixType::Random(cols,cols2); @@ -107,20 +114,19 @@ template<typename MatrixType> void lu_invertible() /* this test covers the following files: LU.h */ + typedef typename MatrixType::Scalar Scalar; typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar; int size = ei_random<int>(1,200); MatrixType m1(size, size), m2(size, size), m3(size, size); - m1 = MatrixType::Random(size,size); - - if (ei_is_same_type<RealScalar,float>::ret) - { - // let's build a matrix more stable to inverse - MatrixType a = MatrixType::Random(size,size*2); - m1 += a * a.adjoint(); - } + FullPivLU<MatrixType> lu; + lu.setThreshold(0.01); + do { + m1 = MatrixType::Random(size,size); + lu.compute(m1); + } while(!lu.isInvertible()); - FullPivLU<MatrixType> lu(m1); + VERIFY_IS_APPROX(m1, lu.reconstructedMatrix()); VERIFY(0 == lu.dimensionOfKernel()); VERIFY(lu.kernel().cols() == 1); // the kernel() should consist of a single (zero) column vector VERIFY(size == lu.rank()); @@ -134,6 +140,23 @@ template<typename MatrixType> void lu_invertible() VERIFY_IS_APPROX(m2, lu.inverse()*m3); } +template<typename MatrixType> void lu_partial_piv() +{ + /* this test covers the following files: + PartialPivLU.h + */ + typedef typename MatrixType::Scalar Scalar; + typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar; + int rows = ei_random<int>(1,4); + int cols = rows; + + MatrixType m1(cols, rows); + m1.setRandom(); + PartialPivLU<MatrixType> plu(m1); + + VERIFY_IS_APPROX(m1, plu.reconstructedMatrix()); +} + template<typename MatrixType> void lu_verify_assert() { MatrixType tmp; @@ -169,21 +192,23 @@ void test_lu() CALL_SUBTEST_2( (lu_non_invertible<Matrix<double, 4, 6> >()) ); CALL_SUBTEST_2( (lu_verify_assert<Matrix<double, 4, 6> >()) ); - + CALL_SUBTEST_3( lu_non_invertible<MatrixXf>() ); CALL_SUBTEST_3( lu_invertible<MatrixXf>() ); CALL_SUBTEST_3( lu_verify_assert<MatrixXf>() ); - + CALL_SUBTEST_4( lu_non_invertible<MatrixXd>() ); CALL_SUBTEST_4( lu_invertible<MatrixXd>() ); + CALL_SUBTEST_4( lu_partial_piv<MatrixXd>() ); CALL_SUBTEST_4( lu_verify_assert<MatrixXd>() ); - + CALL_SUBTEST_5( lu_non_invertible<MatrixXcf>() ); CALL_SUBTEST_5( lu_invertible<MatrixXcf>() ); CALL_SUBTEST_5( lu_verify_assert<MatrixXcf>() ); - + CALL_SUBTEST_6( lu_non_invertible<MatrixXcd>() ); CALL_SUBTEST_6( lu_invertible<MatrixXcd>() ); + CALL_SUBTEST_6( lu_partial_piv<MatrixXcd>() ); CALL_SUBTEST_6( lu_verify_assert<MatrixXcd>() ); CALL_SUBTEST_7(( lu_non_invertible<Matrix<float,Dynamic,16> >() )); diff --git a/test/main.h b/test/main.h index 64f70b394..0a5e0746f 100644 --- a/test/main.h +++ b/test/main.h @@ -95,6 +95,7 @@ namespace Eigen #define ei_assert(a) \ if( (!(a)) && (!no_more_assert) ) \ { \ + std::cerr << #a << " " __FILE__ << "(" << __LINE__ << ")\n"; \ Eigen::no_more_assert = true; \ throw Eigen::ei_assert_exception(); \ } \ @@ -126,6 +127,7 @@ namespace Eigen if( (!(a)) && (!no_more_assert) ) \ { \ Eigen::no_more_assert = true; \ + std::cerr << #a << " " __FILE__ << "(" << __LINE__ << ")\n"; \ throw Eigen::ei_assert_exception(); \ } @@ -148,7 +150,7 @@ namespace Eigen #define EIGEN_INTERNAL_DEBUGGING #define EIGEN_NICE_RANDOM -#include <Eigen/QR> // required for createRandomMatrixOfRank +#include <Eigen/QR> // required for createRandomPIMatrixOfRank #define VERIFY(a) do { if (!(a)) { \ @@ -157,6 +159,7 @@ namespace Eigen exit(2); \ } } while (0) +#define VERIFY_IS_EQUAL(a, b) VERIFY(test_is_equal(a, b)) #define VERIFY_IS_APPROX(a, b) VERIFY(test_ei_isApprox(a, b)) #define VERIFY_IS_NOT_APPROX(a, b) VERIFY(!test_ei_isApprox(a, b)) #define VERIFY_IS_MUCH_SMALLER_THAN(a, b) VERIFY(test_ei_isMuchSmallerThan(a, b)) @@ -342,8 +345,59 @@ inline bool test_isUnitary(const MatrixBase<Derived>& m) return m.isUnitary(test_precision<typename ei_traits<Derived>::Scalar>()); } +template<typename Derived1, typename Derived2, + bool IsVector = bool(Derived1::IsVectorAtCompileTime) && bool(Derived2::IsVectorAtCompileTime) > +struct test_is_equal_impl +{ + static bool run(const Derived1& a1, const Derived2& a2) + { + if(a1.size() != a2.size()) return false; + // we evaluate a2 into a temporary of the shape of a1. this allows to let Assign.h handle the transposing if needed. + typename Derived1::PlainObject a2_evaluated(a2); + for(int i = 0; i < a1.size(); ++i) + if(a1.coeff(i) != a2_evaluated.coeff(i)) return false; + return true; + } +}; + +template<typename Derived1, typename Derived2> +struct test_is_equal_impl<Derived1, Derived2, false> +{ + static bool run(const Derived1& a1, const Derived2& a2) + { + if(a1.rows() != a2.rows()) return false; + if(a1.cols() != a2.cols()) return false; + for(int j = 0; j < a1.cols(); ++j) + for(int i = 0; i < a1.rows(); ++i) + if(a1.coeff(i,j) != a2.coeff(i,j)) return false; + return true; + } +}; + +template<typename Derived1, typename Derived2> +bool test_is_equal(const Derived1& a1, const Derived2& a2) +{ + return test_is_equal_impl<Derived1, Derived2>::run(a1, a2); +} + +bool test_is_equal(const int actual, const int expected) +{ + if (actual==expected) + return true; + // false: + std::cerr + << std::endl << " actual = " << actual + << std::endl << " expected = " << expected << std::endl << std::endl; + return false; +} + +/** Creates a random Partial Isometry matrix of given rank. + * + * A partial isometry is a matrix all of whose singular values are either 0 or 1. + * This is very useful to test rank-revealing algorithms. + */ template<typename MatrixType> -void createRandomMatrixOfRank(int desired_rank, int rows, int cols, MatrixType& m) +void createRandomPIMatrixOfRank(int desired_rank, int rows, int cols, MatrixType& m) { typedef typename ei_traits<MatrixType>::Scalar Scalar; enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime }; @@ -360,7 +414,8 @@ void createRandomMatrixOfRank(int desired_rank, int rows, int cols, MatrixType& if(desired_rank == 1) { - m = VectorType::Random(rows) * VectorType::Random(cols).transpose(); + // here we normalize the vectors to get a partial isometry + m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose(); return; } diff --git a/test/map.cpp b/test/map.cpp index 603b6159b..acaa8fecc 100644 --- a/test/map.cpp +++ b/test/map.cpp @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // // Eigen is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -42,8 +42,8 @@ template<typename VectorType> void map_class_vector(const VectorType& m) VectorType ma1 = Map<VectorType, Aligned>(array1, size); VectorType ma2 = Map<VectorType, Aligned>(array2, size); VectorType ma3 = Map<VectorType>(array3unaligned, size); - VERIFY_IS_APPROX(ma1, ma2); - VERIFY_IS_APPROX(ma1, ma3); + VERIFY_IS_EQUAL(ma1, ma2); + VERIFY_IS_EQUAL(ma1, ma3); VERIFY_RAISES_ASSERT((Map<VectorType,Aligned>(array3unaligned, size))); ei_aligned_delete(array1, size); @@ -70,9 +70,9 @@ template<typename MatrixType> void map_class_matrix(const MatrixType& m) Map<MatrixType>(array3unaligned, rows, cols) = Map<MatrixType>(array1, rows, cols); MatrixType ma1 = Map<MatrixType>(array1, rows, cols); MatrixType ma2 = Map<MatrixType, Aligned>(array2, rows, cols); - VERIFY_IS_APPROX(ma1, ma2); + VERIFY_IS_EQUAL(ma1, ma2); MatrixType ma3 = Map<MatrixType>(array3unaligned, rows, cols); - VERIFY_IS_APPROX(ma1, ma3); + VERIFY_IS_EQUAL(ma1, ma3); ei_aligned_delete(array1, size); ei_aligned_delete(array2, size); @@ -97,8 +97,8 @@ template<typename VectorType> void map_static_methods(const VectorType& m) VectorType ma1 = VectorType::Map(array1, size); VectorType ma2 = VectorType::MapAligned(array2, size); VectorType ma3 = VectorType::Map(array3unaligned, size); - VERIFY_IS_APPROX(ma1, ma2); - VERIFY_IS_APPROX(ma1, ma3); + VERIFY_IS_EQUAL(ma1, ma2); + VERIFY_IS_EQUAL(ma1, ma3); ei_aligned_delete(array1, size); ei_aligned_delete(array2, size); diff --git a/test/mapstride.cpp b/test/mapstride.cpp new file mode 100644 index 000000000..7a1605681 --- /dev/null +++ b/test/mapstride.cpp @@ -0,0 +1,139 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com> +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see <http://www.gnu.org/licenses/>. + +#include "main.h" + +template<typename VectorType> void map_class_vector(const VectorType& m) +{ + typedef typename VectorType::Scalar Scalar; + + int size = m.size(); + + VectorType v = VectorType::Random(size); + + int arraysize = 3*size; + + Scalar* array = ei_aligned_new<Scalar>(arraysize); + + { + Map<VectorType, Aligned, InnerStride<3> > map(array, size); + map = v; + for(int i = 0; i < size; ++i) + { + VERIFY(array[3*i] == v[i]); + VERIFY(map[i] == v[i]); + } + } + + { + Map<VectorType, Unaligned, InnerStride<Dynamic> > map(array, size, InnerStride<Dynamic>(2)); + map = v; + for(int i = 0; i < size; ++i) + { + VERIFY(array[2*i] == v[i]); + VERIFY(map[i] == v[i]); + } + } + + ei_aligned_delete(array, arraysize); +} + +template<typename MatrixType> void map_class_matrix(const MatrixType& _m) +{ + typedef typename MatrixType::Scalar Scalar; + + int rows = _m.rows(), cols = _m.cols(); + + MatrixType m = MatrixType::Random(rows,cols); + + int arraysize = 2*(rows+4)*(cols+4); + + Scalar* array = ei_aligned_new<Scalar>(arraysize); + + // test no inner stride and some dynamic outer stride + { + Map<MatrixType, Aligned, OuterStride<Dynamic> > map(array, rows, cols, OuterStride<Dynamic>(m.innerSize()+1)); + map = m; + VERIFY(map.outerStride() == map.innerSize()+1); + for(int i = 0; i < m.outerSize(); ++i) + for(int j = 0; j < m.innerSize(); ++j) + { + VERIFY(array[map.outerStride()*i+j] == m.coeffByOuterInner(i,j)); + VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j)); + } + } + + // test no inner stride and an outer stride of +4. This is quite important as for fixed-size matrices, + // this allows to hit the special case where it's vectorizable. + { + enum { + InnerSize = MatrixType::InnerSizeAtCompileTime, + OuterStrideAtCompileTime = InnerSize==Dynamic ? Dynamic : InnerSize+4 + }; + Map<MatrixType, Aligned, OuterStride<OuterStrideAtCompileTime> > + map(array, rows, cols, OuterStride<OuterStrideAtCompileTime>(m.innerSize()+4)); + map = m; + VERIFY(map.outerStride() == map.innerSize()+4); + for(int i = 0; i < m.outerSize(); ++i) + for(int j = 0; j < m.innerSize(); ++j) + { + VERIFY(array[map.outerStride()*i+j] == m.coeffByOuterInner(i,j)); + VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j)); + } + } + + // test both inner stride and outer stride + { + Map<MatrixType, Aligned, Stride<Dynamic,Dynamic> > map(array, rows, cols, Stride<Dynamic,Dynamic>(2*m.innerSize()+1, 2)); + map = m; + VERIFY(map.outerStride() == 2*map.innerSize()+1); + VERIFY(map.innerStride() == 2); + for(int i = 0; i < m.outerSize(); ++i) + for(int j = 0; j < m.innerSize(); ++j) + { + VERIFY(array[map.outerStride()*i+map.innerStride()*j] == m.coeffByOuterInner(i,j)); + VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j)); + } + } + + ei_aligned_delete(array, arraysize); +} + +void test_mapstride() +{ + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST_1( map_class_vector(Matrix<float, 1, 1>()) ); + CALL_SUBTEST_2( map_class_vector(Vector4d()) ); + CALL_SUBTEST_3( map_class_vector(RowVector4f()) ); + CALL_SUBTEST_4( map_class_vector(VectorXcf(8)) ); + CALL_SUBTEST_5( map_class_vector(VectorXi(12)) ); + + CALL_SUBTEST_1( map_class_matrix(Matrix<float, 1, 1>()) ); + CALL_SUBTEST_2( map_class_matrix(Matrix4d()) ); + CALL_SUBTEST_3( map_class_matrix(Matrix<float,3,5>()) ); + CALL_SUBTEST_3( map_class_matrix(Matrix<float,4,8>()) ); + CALL_SUBTEST_4( map_class_matrix(MatrixXcf(ei_random<int>(1,10),ei_random<int>(1,10))) ); + CALL_SUBTEST_5( map_class_matrix(MatrixXi(5,5)));//ei_random<int>(1,10),ei_random<int>(1,10))) ); + } +} diff --git a/test/mixingtypes.cpp b/test/mixingtypes.cpp index 71c2dcb18..c6cf00d28 100644 --- a/test/mixingtypes.cpp +++ b/test/mixingtypes.cpp @@ -78,7 +78,9 @@ template<int SizeAtCompileType> void mixingtypes(int size = SizeAtCompileType) // check dot product vf.dot(vf); +#if 0 // we get other compilation errors here than just static asserts VERIFY_RAISES_ASSERT(vd.dot(vf)); +#endif VERIFY_RAISES_ASSERT(vcf.dot(vf)); // yeah eventually we should allow this but i'm too lazy to make that change now in Dot.h // especially as that might be rewritten as cwise product .sum() which would make that automatic. @@ -125,8 +127,8 @@ void mixingtypes_large(int size) VERIFY_RAISES_ASSERT(mcd*md); VERIFY_RAISES_ASSERT(mf*vcf); VERIFY_RAISES_ASSERT(mcf*vf); - VERIFY_RAISES_ASSERT(mcf *= mf); - // VERIFY_RAISES_ASSERT(vcd = md*vcd); // does not even compile (cannot convert complex to double) +// VERIFY_RAISES_ASSERT(mcf *= mf); // does not even compile +// VERIFY_RAISES_ASSERT(vcd = md*vcd); // does not even compile (cannot convert complex to double) VERIFY_RAISES_ASSERT(vcf = mcf*vf); // VERIFY_RAISES_ASSERT(mf*md); // does not even compile diff --git a/test/packetmath.cpp b/test/packetmath.cpp index 7d863e616..e0cb61525 100644 --- a/test/packetmath.cpp +++ b/test/packetmath.cpp @@ -32,7 +32,10 @@ template<typename T> T ei_negate(const T& x) { return -x; } template<typename Scalar> bool areApprox(const Scalar* a, const Scalar* b, int size) { for (int i=0; i<size; ++i) - if (!ei_isApprox(a[i],b[i])) return false; + if (!ei_isApprox(a[i],b[i])) { + std::cout << "a[" << i << "]: " << a[i] << ", b[" << i << "]: " << b[i] << std::endl; + return false; + } return true; } diff --git a/test/permutationmatrices.cpp b/test/permutationmatrices.cpp index 0ef0a371a..89142d910 100644 --- a/test/permutationmatrices.cpp +++ b/test/permutationmatrices.cpp @@ -51,7 +51,7 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m) typedef Matrix<int, Rows, 1> LeftPermutationVectorType; typedef PermutationMatrix<Cols> RightPermutationType; typedef Matrix<int, Cols, 1> RightPermutationVectorType; - + int rows = m.rows(); int cols = m.cols(); @@ -72,7 +72,7 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m) Matrix<Scalar,Cols,Cols> rm(rp); VERIFY_IS_APPROX(m_permuted, lm*m_original*rm); - + VERIFY_IS_APPROX(lp.inverse()*m_permuted*rp.inverse(), m_original); VERIFY((lp*lp.inverse()).toDenseMatrix().isIdentity()); @@ -86,6 +86,23 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m) identityp.setIdentity(rows); VERIFY_IS_APPROX(m_original, identityp*m_original); + // check inplace permutations + m_permuted = m_original; + m_permuted = lp.inverse() * m_permuted; + VERIFY_IS_APPROX(m_permuted, lp.inverse()*m_original); + + m_permuted = m_original; + m_permuted = m_permuted * rp.inverse(); + VERIFY_IS_APPROX(m_permuted, m_original*rp.inverse()); + + m_permuted = m_original; + m_permuted = lp * m_permuted; + VERIFY_IS_APPROX(m_permuted, lp*m_original); + + m_permuted = m_original; + m_permuted = m_permuted * rp; + VERIFY_IS_APPROX(m_permuted, m_original*rp); + if(rows>1 && cols>1) { lp2 = lp; @@ -114,7 +131,7 @@ void test_permutationmatrices() CALL_SUBTEST_2( permutationmatrices(Matrix3f()) ); CALL_SUBTEST_3( permutationmatrices(Matrix<double,3,3,RowMajor>()) ); CALL_SUBTEST_4( permutationmatrices(Matrix4d()) ); - CALL_SUBTEST_5( permutationmatrices(Matrix<double,4,6>()) ); + CALL_SUBTEST_5( permutationmatrices(Matrix<double,40,60>()) ); CALL_SUBTEST_6( permutationmatrices(Matrix<double,Dynamic,Dynamic,RowMajor>(20, 30)) ); CALL_SUBTEST_7( permutationmatrices(MatrixXcf(15, 10)) ); } diff --git a/test/product_symm.cpp b/test/product_symm.cpp index a0d80080f..4ff1735d6 100644 --- a/test/product_symm.cpp +++ b/test/product_symm.cpp @@ -109,9 +109,11 @@ void test_product_symm() for(int i = 0; i < g_repeat ; i++) { CALL_SUBTEST_1(( symm<float,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) )); - CALL_SUBTEST_2(( symm<std::complex<double>,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) )); + CALL_SUBTEST_2(( symm<double,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) )); + CALL_SUBTEST_3(( symm<std::complex<double>,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) )); - CALL_SUBTEST_3(( symm<float,Dynamic,1>(ei_random<int>(10,320)) )); - CALL_SUBTEST_4(( symm<std::complex<double>,Dynamic,1>(ei_random<int>(10,320)) )); + CALL_SUBTEST_4(( symm<float,Dynamic,1>(ei_random<int>(10,320)) )); + CALL_SUBTEST_5(( symm<double,Dynamic,1>(ei_random<int>(10,320)) )); + CALL_SUBTEST_6(( symm<std::complex<double>,Dynamic,1>(ei_random<int>(10,320)) )); } } diff --git a/test/product_syrk.cpp b/test/product_syrk.cpp index e597ac88a..ec93056a9 100644 --- a/test/product_syrk.cpp +++ b/test/product_syrk.cpp @@ -77,6 +77,8 @@ void test_product_syrk() s = ei_random<int>(10,320); CALL_SUBTEST_1( syrk(MatrixXf(s, s)) ); s = ei_random<int>(10,320); - CALL_SUBTEST_2( syrk(MatrixXcd(s, s)) ); + CALL_SUBTEST_2( syrk(MatrixXd(s, s)) ); + s = ei_random<int>(10,320); + CALL_SUBTEST_3( syrk(MatrixXcd(s, s)) ); } } diff --git a/test/product_trsolve.cpp b/test/product_trsolve.cpp index 6e916230e..7a8068c35 100644 --- a/test/product_trsolve.cpp +++ b/test/product_trsolve.cpp @@ -79,12 +79,13 @@ void test_product_trsolve() { // matrices CALL_SUBTEST_1((trsolve<float,Dynamic,Dynamic>(ei_random<int>(1,320),ei_random<int>(1,320)))); - CALL_SUBTEST_2((trsolve<std::complex<double>,Dynamic,Dynamic>(ei_random<int>(1,320),ei_random<int>(1,320)))); + CALL_SUBTEST_2((trsolve<double,Dynamic,Dynamic>(ei_random<int>(1,320),ei_random<int>(1,320)))); + CALL_SUBTEST_3((trsolve<std::complex<double>,Dynamic,Dynamic>(ei_random<int>(1,320),ei_random<int>(1,320)))); // vectors - CALL_SUBTEST_3((trsolve<std::complex<double>,Dynamic,1>(ei_random<int>(1,320)))); - CALL_SUBTEST_4((trsolve<float,1,1>())); - CALL_SUBTEST_5((trsolve<float,1,2>())); - CALL_SUBTEST_6((trsolve<std::complex<float>,4,1>())); + CALL_SUBTEST_4((trsolve<std::complex<double>,Dynamic,1>(ei_random<int>(1,320)))); + CALL_SUBTEST_5((trsolve<float,1,1>())); + CALL_SUBTEST_6((trsolve<float,1,2>())); + CALL_SUBTEST_7((trsolve<std::complex<float>,4,1>())); } } diff --git a/test/qr.cpp b/test/qr.cpp index f2393c13b..1ce1f46e6 100644 --- a/test/qr.cpp +++ b/test/qr.cpp @@ -117,6 +117,7 @@ void test_qr() CALL_SUBTEST_3(( qr_fixedsize<Matrix<float,3,4>, 2 >() )); CALL_SUBTEST_4(( qr_fixedsize<Matrix<double,6,2>, 4 >() )); CALL_SUBTEST_5(( qr_fixedsize<Matrix<double,2,5>, 7 >() )); + CALL_SUBTEST_11( qr(Matrix<float,1,1>()) ); } for(int i = 0; i < g_repeat; i++) { diff --git a/test/qr_colpivoting.cpp b/test/qr_colpivoting.cpp index 16eb27c52..96cc66316 100644 --- a/test/qr_colpivoting.cpp +++ b/test/qr_colpivoting.cpp @@ -36,7 +36,7 @@ template<typename MatrixType> void qr() typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType; typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType; MatrixType m1; - createRandomMatrixOfRank(rank,rows,cols,m1); + createRandomPIMatrixOfRank(rank,rows,cols,m1); ColPivHouseholderQR<MatrixType> qr(m1); VERIFY_IS_APPROX(rank, qr.rank()); VERIFY(cols - qr.rank() == qr.dimensionOfKernel()); @@ -64,7 +64,7 @@ template<typename MatrixType, int Cols2> void qr_fixedsize() typedef typename MatrixType::Scalar Scalar; int rank = ei_random<int>(1, std::min(int(Rows), int(Cols))-1); Matrix<Scalar,Rows,Cols> m1; - createRandomMatrixOfRank(rank,Rows,Cols,m1); + createRandomPIMatrixOfRank(rank,Rows,Cols,m1); ColPivHouseholderQR<Matrix<Scalar,Rows,Cols> > qr(m1); VERIFY_IS_APPROX(rank, qr.rank()); VERIFY(Cols - qr.rank() == qr.dimensionOfKernel()); diff --git a/test/qr_fullpivoting.cpp b/test/qr_fullpivoting.cpp index c82ba4c7e..7ad3af1fe 100644 --- a/test/qr_fullpivoting.cpp +++ b/test/qr_fullpivoting.cpp @@ -35,7 +35,7 @@ template<typename MatrixType> void qr() typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType; typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType; MatrixType m1; - createRandomMatrixOfRank(rank,rows,cols,m1); + createRandomPIMatrixOfRank(rank,rows,cols,m1); FullPivHouseholderQR<MatrixType> qr(m1); VERIFY_IS_APPROX(rank, qr.rank()); VERIFY(cols - qr.rank() == qr.dimensionOfKernel()); diff --git a/test/testsuite.cmake b/test/testsuite.cmake index 90edf2853..b68a327a9 100644 --- a/test/testsuite.cmake +++ b/test/testsuite.cmake @@ -147,6 +147,9 @@ endif(NOT EIGEN_NO_UPDATE) # which ctest command to use for running the dashboard SET (CTEST_COMMAND "${EIGEN_CMAKE_DIR}ctest -D ${EIGEN_MODE}") +if($ENV{EIGEN_CTEST_ARGS}) +SET (CTEST_COMMAND "${CTEST_COMMAND} $ENV{EIGEN_CTEST_ARGS}") +endif($ENV{EIGEN_CTEST_ARGS}) # what cmake command to use for configuring this dashboard SET (CTEST_CMAKE_COMMAND "${EIGEN_CMAKE_DIR}cmake -DEIGEN_LEAVE_TEST_IN_ALL_TARGET=ON") diff --git a/test/unalignedassert.cpp b/test/unalignedassert.cpp index 85a83b7b5..5782ab20e 100644 --- a/test/unalignedassert.cpp +++ b/test/unalignedassert.cpp @@ -78,7 +78,7 @@ void check_unalignedassert_good() delete[] y; } -#if EIGEN_ALIGN +#if EIGEN_ALIGN_STATICALLY template<typename T> void construct_at_boundary(int boundary) { @@ -94,7 +94,7 @@ void construct_at_boundary(int boundary) void unalignedassert() { - #if EIGEN_ALIGN + #if EIGEN_ALIGN_STATICALLY construct_at_boundary<Vector2f>(4); construct_at_boundary<Vector3f>(4); construct_at_boundary<Vector4f>(16); @@ -124,7 +124,7 @@ void unalignedassert() check_unalignedassert_good<TestNew6>(); check_unalignedassert_good<Depends<true> >(); -#if EIGEN_ALIGN +#if EIGEN_ALIGN_STATICALLY VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4f>(8)); VERIFY_RAISES_ASSERT(construct_at_boundary<Matrix4f>(8)); VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2d>(8)); diff --git a/test/vectorization_logic.cpp b/test/vectorization_logic.cpp index 5d86df7b3..94a8a5c96 100644 --- a/test/vectorization_logic.cpp +++ b/test/vectorization_logic.cpp @@ -22,6 +22,7 @@ // License and a copy of the GNU General Public License along with // Eigen. If not, see <http://www.gnu.org/licenses/>. +#define EIGEN_DEBUG_ASSIGN #include "main.h" #include <typeinfo> @@ -33,6 +34,14 @@ bool test_assign(const Dst&, const Src&, int traversal, int unrolling) && ei_assign_traits<Dst,Src>::Unrolling==unrolling; } +template<typename Dst, typename Src> +bool test_assign(int traversal, int unrolling) +{ + ei_assign_traits<Dst,Src>::debug(); + return ei_assign_traits<Dst,Src>::Traversal==traversal + && ei_assign_traits<Dst,Src>::Unrolling==unrolling; +} + template<typename Xpr> bool test_redux(const Xpr&, int traversal, int unrolling) { @@ -86,6 +95,15 @@ void test_vectorization_logic() VERIFY(test_assign(MatrixXf(10,10),MatrixXf(20,20).block(10,10,2,3), SliceVectorizedTraversal,NoUnrolling)); + VERIFY((test_assign< + Map<Matrix<float,4,8>, Aligned, OuterStride<12> >, + Matrix<float,4,8> + >(InnerVectorizedTraversal,CompleteUnrolling))); + + VERIFY((test_assign< + Map<Matrix<float,4,8>, Aligned, InnerStride<12> >, + Matrix<float,4,8> + >(DefaultTraversal,CompleteUnrolling))); VERIFY(test_redux(VectorXf(10), LinearVectorizedTraversal,NoUnrolling)); |