diff options
author | Benoit Jacob <jacob.benoit.1@gmail.com> | 2007-12-25 17:20:58 +0000 |
---|---|---|
committer | Benoit Jacob <jacob.benoit.1@gmail.com> | 2007-12-25 17:20:58 +0000 |
commit | dad245af56b4597f27d7c219e5f5f0b38cd62d24 (patch) | |
tree | 64d24b37b4be26bddd842f359ff42bc30abfa723 /test | |
parent | 3cd2a125b2712d6b7c620bef0671c6a05839d6e5 (diff) |
- eigen2 now fully enforces constness! found a way to achieve that
with minimal code duplication. There now are only two (2)
const_cast remaining in the whole source code.
- eigen2 now fully allows copying a row-vector into a column-vector.
added a unit-test for that.
- split unit tests, improve docs, various improvements.
Diffstat (limited to 'test')
-rw-r--r-- | test/CMakeLists.txt | 3 | ||||
-rw-r--r-- | test/basicstuff.cpp | 96 | ||||
-rw-r--r-- | test/linearstructure.cpp | 106 | ||||
-rw-r--r-- | test/main.h | 3 | ||||
-rw-r--r-- | test/map.cpp | 60 | ||||
-rw-r--r-- | test/product.cpp | 100 |
6 files changed, 280 insertions, 88 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 72a9f8fb7..6fff26b43 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,10 +7,13 @@ INCLUDE_DIRECTORIES( ${QT_INCLUDE_DIR} ) SET(test_SRCS main.cpp basicstuff.cpp + linearstructure.cpp + product.cpp adjoint.cpp submatrices.cpp miscmatrices.cpp smallvectors.cpp + map.cpp ) QT4_AUTOMOC(${test_SRCS}) diff --git a/test/basicstuff.cpp b/test/basicstuff.cpp index 04fefc25e..dcc909b4f 100644 --- a/test/basicstuff.cpp +++ b/test/basicstuff.cpp @@ -29,18 +29,9 @@ namespace Eigen { template<typename MatrixType> void basicStuff(const MatrixType& m) { - /* this test covers the following files: - 1) Explicitly (see comments below): - Random.h Zero.h Identity.h Fuzzy.h Sum.h Difference.h - Opposite.h Product.h ScalarMultiple.h Map.h - - 2) Implicitly (the core stuff): - MatrixBase.h Matrix.h MatrixStorage.h CopyHelper.h MatrixRef.h - NumTraits.h Util.h MathFunctions.h OperatorEquals.h Coeffs.h - */ - typedef typename MatrixType::Scalar Scalar; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType; + int rows = m.rows(); int cols = m.cols(); @@ -58,13 +49,9 @@ template<typename MatrixType> void basicStuff(const MatrixType& m) v2 = VectorType::random(rows), vzero = VectorType::zero(rows); - Scalar s1 = random<Scalar>(), - s2 = random<Scalar>(); - int r = random<int>(0, rows-1), c = random<int>(0, cols-1); - // test Fuzzy.h and Zero.h. VERIFY_IS_APPROX( v1, v1); VERIFY_IS_NOT_APPROX( v1, 2*v1); VERIFY_IS_MUCH_SMALLER_THAN( vzero, v1); @@ -86,80 +73,13 @@ template<typename MatrixType> void basicStuff(const MatrixType& m) // operator() that gets called, which in turn calls _read(). VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::zero(rows,cols)(r,c), static_cast<Scalar>(1)); - // test the linear structure, i.e. the following files: - // Sum.h Difference.h Opposite.h ScalarMultiple.h - VERIFY_IS_APPROX(-(-m1), m1); - VERIFY_IS_APPROX(m1+m1, 2*m1); - VERIFY_IS_APPROX(m1+m2-m1, m2); - VERIFY_IS_APPROX(-m2+m1+m2, m1); - VERIFY_IS_APPROX(m1*s1, s1*m1); - VERIFY_IS_APPROX((m1+m2)*s1, s1*m1+s1*m2); - VERIFY_IS_APPROX((s1+s2)*m1, m1*s1+m1*s2); - VERIFY_IS_APPROX((m1-m2)*s1, s1*m1-s1*m2); - VERIFY_IS_APPROX((s1-s2)*m1, m1*s1-m1*s2); - VERIFY_IS_APPROX((-m1+m2)*s1, -s1*m1+s1*m2); - VERIFY_IS_APPROX((-s1+s2)*m1, -m1*s1+m1*s2); - m3 = m2; m3 += m1; - VERIFY_IS_APPROX(m3, m1+m2); - m3 = m2; m3 -= m1; - VERIFY_IS_APPROX(m3, m2-m1); - m3 = m2; m3 *= s1; - VERIFY_IS_APPROX(m3, s1*m2); - if(NumTraits<Scalar>::HasFloatingPoint) - { - m3 = m2; m3 /= s1; - VERIFY_IS_APPROX(m3, m2/s1); - } - - // again, test operator() to check const-qualification - VERIFY_IS_APPROX((-m1)(r,c), -(m1(r,c))); - VERIFY_IS_APPROX((m1-m2)(r,c), (m1(r,c))-(m2(r,c))); - VERIFY_IS_APPROX((m1+m2)(r,c), (m1(r,c))+(m2(r,c))); - VERIFY_IS_APPROX((s1*m1)(r,c), s1*(m1(r,c))); - VERIFY_IS_APPROX((m1*s1)(r,c), (m1(r,c))*s1); - if(NumTraits<Scalar>::HasFloatingPoint) - VERIFY_IS_APPROX((m1/s1)(r,c), (m1(r,c))/s1); - - // begin testing Product.h: only associativity for now - // (we use Transpose.h but this doesn't count as a test for it) - VERIFY_IS_APPROX((m1*m1.transpose())*m2, m1*(m1.transpose()*m2)); - m3 = m1; - m3 *= (m1.transpose() * m2); - VERIFY_IS_APPROX(m3, m1*(m1.transpose()*m2)); - VERIFY_IS_APPROX(m3, m1.lazyProduct(m1.transpose()*m2)); - - // continue testing Product.h: distributivity - VERIFY_IS_APPROX(square*(m1 + m2), square*m1+square*m2); - VERIFY_IS_APPROX(square*(m1 - m2), square*m1-square*m2); - - // continue testing Product.h: compatibility with ScalarMultiple.h - VERIFY_IS_APPROX(s1*(square*m1), (s1*square)*m1); - VERIFY_IS_APPROX(s1*(square*m1), square*(m1*s1)); - - // continue testing Product.h: lazyProduct - VERIFY_IS_APPROX(square.lazyProduct(m1), square*m1); - // again, test operator() to check const-qualification - s1 += square.lazyProduct(m1)(r,c); - - // test Product.h together with Identity.h - VERIFY_IS_APPROX(m1, identity*m1); - VERIFY_IS_APPROX(v1, identity*v1); - // again, test operator() to check const-qualification - VERIFY_IS_APPROX(MatrixType::identity(std::max(rows,cols))(r,c), static_cast<Scalar>(r==c)); - - // test Map.h - Scalar* array1 = new Scalar[rows]; - Scalar* array2 = new Scalar[rows]; - typedef Matrix<Scalar, Dynamic, 1> VectorX; - VectorX::map(array1, rows) = VectorX::random(rows); - VectorX::map(array2, rows) = VectorX::map(array1, rows); - VectorX ma1 = VectorX::map(array1, rows); - VectorX ma2 = VectorX::map(array2, rows); - VERIFY_IS_APPROX(ma1, ma2); - VERIFY_IS_APPROX(ma1, VectorX(array2, rows)); - - delete[] array1; - delete[] array2; + // now test copying a row-vector into a (column-)vector and conversely. + square.col(r) = square.row(r).eval(); + Matrix<Scalar, 1, MatrixType::RowsAtCompileTime> rv(rows); + Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> cv(rows); + rv = square.col(r); + cv = square.row(r); + VERIFY_IS_APPROX(rv, cv.transpose()); } void EigenTest::testBasicStuff() diff --git a/test/linearstructure.cpp b/test/linearstructure.cpp new file mode 100644 index 000000000..2bb7a1d81 --- /dev/null +++ b/test/linearstructure.cpp @@ -0,0 +1,106 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2006-2007 Benoit Jacob <jacob@math.jussieu.fr> +// +// Eigen is free software; 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 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 General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along +// with Eigen; if not, write to the Free Software Foundation, Inc., 51 +// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. This exception does not invalidate any other reasons why a work +// based on this file might be covered by the GNU General Public License. + +#include "main.h" + +namespace Eigen { + +template<typename MatrixType> void linearStructure(const MatrixType& m) +{ + /* this test covers the following files: + Sum.h Difference.h Opposite.h ScalarMultiple.h + */ + + typedef typename MatrixType::Scalar Scalar; + typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType; + + int rows = m.rows(); + int cols = m.cols(); + + // 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), + m2 = MatrixType::random(rows, cols), + m3(rows, cols), + mzero = MatrixType::zero(rows, cols), + identity = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> + ::identity(rows), + square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> + ::random(rows, rows); + VectorType v1 = VectorType::random(rows), + v2 = VectorType::random(rows), + vzero = VectorType::zero(rows); + + Scalar s1 = random<Scalar>(), + s2 = random<Scalar>(); + + int r = random<int>(0, rows-1), + c = random<int>(0, cols-1); + + VERIFY_IS_APPROX(-(-m1), m1); + VERIFY_IS_APPROX(m1+m1, 2*m1); + VERIFY_IS_APPROX(m1+m2-m1, m2); + VERIFY_IS_APPROX(-m2+m1+m2, m1); + VERIFY_IS_APPROX(m1*s1, s1*m1); + VERIFY_IS_APPROX((m1+m2)*s1, s1*m1+s1*m2); + VERIFY_IS_APPROX((s1+s2)*m1, m1*s1+m1*s2); + VERIFY_IS_APPROX((m1-m2)*s1, s1*m1-s1*m2); + VERIFY_IS_APPROX((s1-s2)*m1, m1*s1-m1*s2); + VERIFY_IS_APPROX((-m1+m2)*s1, -s1*m1+s1*m2); + VERIFY_IS_APPROX((-s1+s2)*m1, -m1*s1+m1*s2); + m3 = m2; m3 += m1; + VERIFY_IS_APPROX(m3, m1+m2); + m3 = m2; m3 -= m1; + VERIFY_IS_APPROX(m3, m2-m1); + m3 = m2; m3 *= s1; + VERIFY_IS_APPROX(m3, s1*m2); + if(NumTraits<Scalar>::HasFloatingPoint) + { + m3 = m2; m3 /= s1; + VERIFY_IS_APPROX(m3, m2/s1); + } + + // again, test operator() to check const-qualification + VERIFY_IS_APPROX((-m1)(r,c), -(m1(r,c))); + VERIFY_IS_APPROX((m1-m2)(r,c), (m1(r,c))-(m2(r,c))); + VERIFY_IS_APPROX((m1+m2)(r,c), (m1(r,c))+(m2(r,c))); + VERIFY_IS_APPROX((s1*m1)(r,c), s1*(m1(r,c))); + VERIFY_IS_APPROX((m1*s1)(r,c), (m1(r,c))*s1); + if(NumTraits<Scalar>::HasFloatingPoint) + VERIFY_IS_APPROX((m1/s1)(r,c), (m1(r,c))/s1); +} + +void EigenTest::testLinearStructure() +{ + for(int i = 0; i < m_repeat; i++) { + linearStructure(Matrix<float, 1, 1>()); + linearStructure(Matrix4d()); + linearStructure(MatrixXcf(3, 3)); + linearStructure(MatrixXi(8, 12)); + linearStructure(MatrixXcd(20, 20)); + } +} + +} // namespace Eigen diff --git a/test/main.h b/test/main.h index 8cab47331..59c6b2de7 100644 --- a/test/main.h +++ b/test/main.h @@ -114,10 +114,13 @@ class EigenTest : public QObject private slots: void testBasicStuff(); + void testLinearStructure(); + void testProduct(); void testAdjoint(); void testSubmatrices(); void testMiscMatrices(); void testSmallVectors(); + void testMap(); protected: int m_repeat; }; diff --git a/test/map.cpp b/test/map.cpp new file mode 100644 index 000000000..fece15853 --- /dev/null +++ b/test/map.cpp @@ -0,0 +1,60 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2006-2007 Benoit Jacob <jacob@math.jussieu.fr> +// +// Eigen is free software; 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 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 General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along +// with Eigen; if not, write to the Free Software Foundation, Inc., 51 +// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. This exception does not invalidate any other reasons why a work +// based on this file might be covered by the GNU General Public License. + +#include "main.h" + +namespace Eigen { + +template<typename VectorType> void tmap(const VectorType& m) +{ + typedef typename VectorType::Scalar Scalar; + + int size = m.size(); + + // test Map.h + Scalar* array1 = new Scalar[size]; + Scalar* array2 = new Scalar[size]; + VectorType::map(array1, size) = VectorType::random(size); + VectorType::map(array2, size) = VectorType::map(array1, size); + VectorType ma1 = VectorType::map(array1, size); + VectorType ma2 = VectorType::map(array2, size); + VERIFY_IS_APPROX(ma1, ma2); + VERIFY_IS_APPROX(ma1, VectorType(array2, size)); + delete[] array1; + delete[] array2; +} + +void EigenTest::testMap() +{ + for(int i = 0; i < m_repeat; i++) { + tmap(Matrix<float, 1, 1>()); + tmap(Vector4d()); + tmap(RowVector4f()); + tmap(VectorXcf(8)); + tmap(VectorXi(12)); + } +} + +} // namespace Eigen diff --git a/test/product.cpp b/test/product.cpp new file mode 100644 index 000000000..81610d64c --- /dev/null +++ b/test/product.cpp @@ -0,0 +1,100 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2006-2007 Benoit Jacob <jacob@math.jussieu.fr> +// +// Eigen is free software; 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 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 General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along +// with Eigen; if not, write to the Free Software Foundation, Inc., 51 +// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. This exception does not invalidate any other reasons why a work +// based on this file might be covered by the GNU General Public License. + +#include "main.h" + +namespace Eigen { + +template<typename MatrixType> void product(const MatrixType& m) +{ + /* this test covers the following files: + Identity.h Product.h + */ + + typedef typename MatrixType::Scalar Scalar; + typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType; + + int rows = m.rows(); + int cols = m.cols(); + + // 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), + m2 = MatrixType::random(rows, cols), + m3(rows, cols), + mzero = MatrixType::zero(rows, cols), + identity = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> + ::identity(rows), + square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> + ::random(rows, rows); + VectorType v1 = VectorType::random(rows), + v2 = VectorType::random(rows), + vzero = VectorType::zero(rows); + + Scalar s1 = random<Scalar>(); + + int r = random<int>(0, rows-1), + c = random<int>(0, cols-1); + + // begin testing Product.h: only associativity for now + // (we use Transpose.h but this doesn't count as a test for it) + VERIFY_IS_APPROX((m1*m1.transpose())*m2, m1*(m1.transpose()*m2)); + m3 = m1; + m3 *= (m1.transpose() * m2); + VERIFY_IS_APPROX(m3, m1*(m1.transpose()*m2)); + VERIFY_IS_APPROX(m3, m1.lazyProduct(m1.transpose()*m2)); + + // continue testing Product.h: distributivity + VERIFY_IS_APPROX(square*(m1 + m2), square*m1+square*m2); + VERIFY_IS_APPROX(square*(m1 - m2), square*m1-square*m2); + + // continue testing Product.h: compatibility with ScalarMultiple.h + VERIFY_IS_APPROX(s1*(square*m1), (s1*square)*m1); + VERIFY_IS_APPROX(s1*(square*m1), square*(m1*s1)); + + // continue testing Product.h: lazyProduct + VERIFY_IS_APPROX(square.lazyProduct(m1), square*m1); + // again, test operator() to check const-qualification + s1 += square.lazyProduct(m1)(r,c); + + // test Product.h together with Identity.h + VERIFY_IS_APPROX(m1, identity*m1); + VERIFY_IS_APPROX(v1, identity*v1); + // again, test operator() to check const-qualification + VERIFY_IS_APPROX(MatrixType::identity(std::max(rows,cols))(r,c), static_cast<Scalar>(r==c)); +} + +void EigenTest::testProduct() +{ + for(int i = 0; i < m_repeat; i++) { + product(Matrix<float, 1, 1>()); + product(Matrix4d()); + product(MatrixXcf(3, 3)); + product(MatrixXi(8, 12)); + product(MatrixXcd(20, 20)); + } +} + +} // namespace Eigen |