From cff5e3ce9c1e09553125bce464b9c80f8bc2eb76 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 31 Mar 2008 16:20:06 +0000 Subject: Make use of the LazyBit, introduce .lazy(), remove lazyProduct. --- Eigen/Core | 1 + Eigen/src/Core/Block.h | 2 +- Eigen/src/Core/DiagonalCoeffs.h | 2 +- Eigen/src/Core/Eval.h | 6 +++--- Eigen/src/Core/EvalOMP.h | 2 +- Eigen/src/Core/ForwardDeclarations.h | 16 +++++++++++++++- Eigen/src/Core/Map.h | 4 ++-- Eigen/src/Core/Matrix.h | 4 ++-- Eigen/src/Core/MatrixBase.h | 23 +++++++++++------------ Eigen/src/Core/Product.h | 31 +++++++------------------------ Eigen/src/Core/Random.h | 18 +++++++++--------- Eigen/src/Core/Redux.h | 2 +- Eigen/src/Core/Transpose.h | 2 +- Eigen/src/Core/Util.h | 8 ++++---- bench/basicbenchmark.h | 4 ++-- bench/benchmark_suite | 16 ++++++++-------- test/basicstuff.cpp | 6 +++--- test/main.h | 2 +- test/product.cpp | 9 +++++---- test/submatrices.cpp | 2 +- 20 files changed, 79 insertions(+), 81 deletions(-) diff --git a/Eigen/Core b/Eigen/Core index 6da789afe..c6185368d 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -21,6 +21,7 @@ namespace Eigen { #include "src/Core/MatrixStorage.h" #include "src/Core/Matrix.h" #include "src/Core/Eval.h" +#include "src/Core/Lazy.h" #include "src/Core/CwiseBinaryOp.h" #include "src/Core/CwiseUnaryOp.h" #include "src/Core/Product.h" diff --git a/Eigen/src/Core/Block.h b/Eigen/src/Core/Block.h index 751af9647..4c672e4f2 100644 --- a/Eigen/src/Core/Block.h +++ b/Eigen/src/Core/Block.h @@ -69,7 +69,7 @@ struct ei_traits > : (BlockCols==Dynamic ? MatrixType::MaxColsAtCompileTime : BlockCols), Flags = RowsAtCompileTime == Dynamic || ColsAtCompileTime == Dynamic ? (unsigned int)MatrixType::Flags - : (unsigned int)MatrixType::Flags &~ Large + : (unsigned int)MatrixType::Flags &~ LargeBit }; }; diff --git a/Eigen/src/Core/DiagonalCoeffs.h b/Eigen/src/Core/DiagonalCoeffs.h index 10cb7b8e4..417daa8ce 100644 --- a/Eigen/src/Core/DiagonalCoeffs.h +++ b/Eigen/src/Core/DiagonalCoeffs.h @@ -54,7 +54,7 @@ struct ei_traits > MaxColsAtCompileTime = 1, Flags = RowsAtCompileTime == Dynamic || ColsAtCompileTime == Dynamic ? (unsigned int)MatrixType::Flags - : (unsigned int)MatrixType::Flags &~ Large + : (unsigned int)MatrixType::Flags &~ LargeBit }; }; diff --git a/Eigen/src/Core/Eval.h b/Eigen/src/Core/Eval.h index 81de3026c..23e35a96a 100644 --- a/Eigen/src/Core/Eval.h +++ b/Eigen/src/Core/Eval.h @@ -53,7 +53,7 @@ struct ei_traits > ColsAtCompileTime = ExpressionType::ColsAtCompileTime, MaxRowsAtCompileTime = ExpressionType::MaxRowsAtCompileTime, MaxColsAtCompileTime = ExpressionType::MaxColsAtCompileTime, - Flags = ExpressionType::Flags & ~Lazy + Flags = ExpressionType::Flags & ~LazyBit }; }; @@ -101,9 +101,9 @@ template class Eval : ei_no_assignment_operator, * * \sa class Eval */ template -const Eval MatrixBase::eval() const +const typename ei_eval_unless_lazy::Type MatrixBase::eval() const { - return Eval(*static_cast(this)); + return typename ei_eval_unless_lazy::Type(derived()); } #endif // EIGEN_EVAL_H diff --git a/Eigen/src/Core/EvalOMP.h b/Eigen/src/Core/EvalOMP.h index d23f64007..32398b6be 100644 --- a/Eigen/src/Core/EvalOMP.h +++ b/Eigen/src/Core/EvalOMP.h @@ -48,7 +48,7 @@ struct ei_traits > ColsAtCompileTime = ExpressionType::ColsAtCompileTime, MaxRowsAtCompileTime = ExpressionType::MaxRowsAtCompileTime, MaxColsAtCompileTime = ExpressionType::MaxColsAtCompileTime, - Flags = ExpressionType::Flags & ~Lazy + Flags = ExpressionType::Flags & ~LazyBit }; }; diff --git a/Eigen/src/Core/ForwardDeclarations.h b/Eigen/src/Core/ForwardDeclarations.h index 9d5ec90ea..3c9d9db70 100644 --- a/Eigen/src/Core/ForwardDeclarations.h +++ b/Eigen/src/Core/ForwardDeclarations.h @@ -29,7 +29,7 @@ template struct ei_traits; template struct ei_product_eval_mode; template class Matrix; -template class MatrixRef; +template class Lazy; template class Minor; template class Block; template class Transpose; @@ -79,4 +79,18 @@ struct ei_xpr_copy > typedef const Matrix<_Scalar, _Rows, _Cols, _Flags, _MaxRows, _MaxCols> & Type; }; +template struct ei_conditional_eval +{ + typedef T Type; +}; + +template struct ei_conditional_eval +{ + typedef Eval Type; +}; + +template struct ei_eval_unless_lazy +{ + typedef typename ei_conditional_eval::Flags & LazyBit)>::Type Type; +}; #endif // EIGEN_FORWARDDECLARATIONS_H diff --git a/Eigen/src/Core/Map.h b/Eigen/src/Core/Map.h index e1abfad3f..4872b3f60 100644 --- a/Eigen/src/Core/Map.h +++ b/Eigen/src/Core/Map.h @@ -65,7 +65,7 @@ template class Map const Scalar& _coeff(int row, int col) const { - if(Flags & RowMajor) + if(Flags & RowMajorBit) return m_data[col + row * m_cols]; else // column-major return m_data[row + col * m_rows]; @@ -73,7 +73,7 @@ template class Map Scalar& _coeffRef(int row, int col) { - if(Flags & RowMajor) + if(Flags & RowMajorBit) return const_cast(m_data)[col + row * m_cols]; else // column-major return const_cast(m_data)[row + col * m_rows]; diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index f0192e6be..9ccad4e7e 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h @@ -104,7 +104,7 @@ class Matrix : public MatrixBase class MatrixBase Flags = ei_traits::Flags /**< This stores expression metadata which typically is inherited by new expressions * constructed from this one. The available flags are: - * \li \c RowMajor: if this bit is set, the preferred storage order for an evaluation + * \li \c RowMajorBit: if this bit is set, the preferred storage order for an evaluation * of this expression is row-major. Otherwise, it is column-major. - * \li \c Lazy: if this bit is set, the next evaluation of this expression will be canceled. + * \li \c LazyBit: if this bit is set, the next evaluation of this expression will be canceled. * This can be used, with care, to achieve lazy evaluation. - * \li \c Large: if this bit is set, optimization will be tuned for large matrices (typically, + * \li \c LargeBit: if this bit is set, optimization will be tuned for large matrices (typically, * at least 32x32). */ }; @@ -246,14 +246,11 @@ template class MatrixBase //@} /** \name Matrix product + * and, as a special case, matrix-vector product */ //@{ template - const Product - lazyProduct(const MatrixBase& other) const; - - template - const Eval > + const typename ei_eval_unless_lazy >::Type operator*(const MatrixBase &other) const; template @@ -313,9 +310,9 @@ template class MatrixBase /// \name Generating special matrices //@{ - static const Eval > random(int rows, int cols); - static const Eval > random(int size); - static const Eval > random(); + static const typename ei_eval_unless_lazy >::Type random(int rows, int cols); + static const typename ei_eval_unless_lazy >::Type random(int size); + static const typename ei_eval_unless_lazy >::Type random(); static const Zero zero(int rows, int cols); static const Zero zero(int size); static const Zero zero(); @@ -359,11 +356,13 @@ template class MatrixBase template const CwiseUnaryOp, Derived> cast() const; - const Eval eval() const EIGEN_ALWAYS_INLINE; + const typename ei_eval_unless_lazy::Type eval() const EIGEN_ALWAYS_INLINE; const EvalOMP evalOMP() const EIGEN_ALWAYS_INLINE; template void swap(const MatrixBase& other); + + const Lazy lazy() const; //@} /// \name Coefficient-wise operations diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index f8b173bcf..62e1b6317 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -69,8 +69,8 @@ struct ei_product_unroller * \param EvalMode internal use only * * This class represents an expression of the product of two matrices. - * It is the return type of MatrixBase::lazyProduct(), which is used internally by - * the operator* between matrices, and most of the time this is the only way it is used. + * It is the return type of the operator* between matrices, and most of the time + * this is the only way it is used. * * \sa class Sum, class Difference */ @@ -85,7 +85,7 @@ struct ei_traits > MaxColsAtCompileTime = Rhs::MaxColsAtCompileTime, Flags = (RowsAtCompileTime == Dynamic || ColsAtCompileTime == Dynamic) ? (unsigned int)(Lhs::Flags | Rhs::Flags) - : (unsigned int)(Lhs::Flags | Rhs::Flags) & ~Large + : (unsigned int)(Lhs::Flags | Rhs::Flags) & ~LargeBit }; }; @@ -148,36 +148,19 @@ template class Product : ei_no_assignm const typename Rhs::XprCopy m_rhs; }; -/** \returns an expression of the matrix product of \c this and \a other, in this order. - * - * This function is used internally by the operator* between matrices. The difference between - * lazyProduct() and that operator* is that lazyProduct() only constructs and returns an - * expression without actually computing the matrix product, while the operator* between - * matrices immediately evaluates the product and returns the resulting matrix. - * - * \sa class Product - */ -template -template -const Product -MatrixBase::lazyProduct(const MatrixBase &other) const -{ - return Product(derived(), other.derived()); -} - /** \returns the matrix product of \c *this and \a other. * * \note This function causes an immediate evaluation. If you want to perform a matrix product - * without immediate evaluation, use MatrixBase::lazyProduct() instead. + * without immediate evaluation, call .lazy() on one of the matrices before taking the product. * - * \sa lazyProduct(), operator*=(const MatrixBase&) + * \sa lazy(), operator*=(const MatrixBase&) */ template template -const Eval > +const typename ei_eval_unless_lazy >::Type MatrixBase::operator*(const MatrixBase &other) const { - return lazyProduct(other).eval(); + return Product(derived(), other.derived()).eval(); } /** replaces \c *this by \c *this * \a other. diff --git a/Eigen/src/Core/Random.h b/Eigen/src/Core/Random.h index 36b8c9ee5..03f08ef06 100644 --- a/Eigen/src/Core/Random.h +++ b/Eigen/src/Core/Random.h @@ -35,13 +35,13 @@ template struct ei_traits > { - typedef typename MatrixType::Scalar Scalar; + typedef typename ei_traits::Scalar Scalar; enum { - RowsAtCompileTime = MatrixType::RowsAtCompileTime, - ColsAtCompileTime = MatrixType::ColsAtCompileTime, - MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, - Flags = MatrixType::Flags + RowsAtCompileTime = ei_traits::RowsAtCompileTime, + ColsAtCompileTime = ei_traits::ColsAtCompileTime, + MaxRowsAtCompileTime = ei_traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = ei_traits::MaxColsAtCompileTime, + Flags = ei_traits::Flags }; }; @@ -92,7 +92,7 @@ template class Random : ei_no_assignment_operator, * \sa ei_random(), ei_random(int) */ template -const Eval > +const typename ei_eval_unless_lazy >::Type MatrixBase::random(int rows, int cols) { return Random(rows, cols).eval(); @@ -115,7 +115,7 @@ MatrixBase::random(int rows, int cols) * \sa ei_random(), ei_random(int,int) */ template -const Eval > +const typename ei_eval_unless_lazy >::Type MatrixBase::random(int size) { ei_assert(IsVectorAtCompileTime); @@ -135,7 +135,7 @@ MatrixBase::random(int size) * \sa ei_random(int), ei_random(int,int) */ template -const Eval > +const typename ei_eval_unless_lazy >::Type MatrixBase::random() { return Random(RowsAtCompileTime, ColsAtCompileTime).eval(); diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h index 9afb4e664..34eefca7c 100644 --- a/Eigen/src/Core/Redux.h +++ b/Eigen/src/Core/Redux.h @@ -95,7 +95,7 @@ struct ei_traits > MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, Flags = (RowsAtCompileTime == Dynamic || ColsAtCompileTime == Dynamic) ? (unsigned int)MatrixType::Flags - : (unsigned int)MatrixType::Flags & ~Large + : (unsigned int)MatrixType::Flags & ~LargeBit }; }; diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h index de481a31b..51799b33e 100644 --- a/Eigen/src/Core/Transpose.h +++ b/Eigen/src/Core/Transpose.h @@ -46,7 +46,7 @@ struct ei_traits > ColsAtCompileTime = MatrixType::RowsAtCompileTime, MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime, - Flags = MatrixType::Flags ^ RowMajor + Flags = MatrixType::Flags ^ RowMajorBit }; }; diff --git a/Eigen/src/Core/Util.h b/Eigen/src/Core/Util.h index 87808351c..ae9624aa1 100644 --- a/Eigen/src/Core/Util.h +++ b/Eigen/src/Core/Util.h @@ -37,7 +37,7 @@ #endif #ifdef EIGEN_DEFAULT_TO_ROW_MAJOR -#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER RowMajor +#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER RowMajorBit #else #define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER 0 #endif @@ -128,9 +128,9 @@ friend class Eigen::MatrixBase; const int Dynamic = -10; // matrix/expression flags -const unsigned int RowMajor = 0x1; -const unsigned int Lazy = 0x2; -const unsigned int Large = 0x4; +const unsigned int RowMajorBit = 0x1; +const unsigned int LazyBit = 0x2; +const unsigned int LargeBit = 0x4; enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight }; diff --git a/bench/basicbenchmark.h b/bench/basicbenchmark.h index c37d05ad4..3a6695e2f 100644 --- a/bench/basicbenchmark.h +++ b/bench/basicbenchmark.h @@ -13,13 +13,13 @@ void benchBasic_loop(const MatrixType& I, MatrixType& m, int iterations) { asm("#begin_bench_loop LazyEval"); if (MatrixType::SizeAtCompileTime!=Eigen::Dynamic) asm("#fixedsize"); - m = (I + 0.00005 * (m + m.lazyProduct(m))).eval(); + m = (I + 0.00005 * (m + m.lazy() * m)).eval(); } else if (Mode==OmpEval) { asm("#begin_bench_loop OmpEval"); if (MatrixType::SizeAtCompileTime!=Eigen::Dynamic) asm("#fixedsize"); - m = (I + 0.00005 * (m + m.lazyProduct(m))).evalOMP(); + m = (I + 0.00005 * (m + m.lazy() * m)).evalOMP(); } else { diff --git a/bench/benchmark_suite b/bench/benchmark_suite index 9ddfccbf6..a8fc6dced 100755 --- a/bench/benchmark_suite +++ b/bench/benchmark_suite @@ -1,17 +1,17 @@ #!/bin/bash -echo "Fixed size 3x3, ColumnMajor, -DNDEBUG" +echo "Fixed size 3x3, column-major, -DNDEBUG" $CXX -O3 -I .. -DNDEBUG benchmark.cpp -o benchmark && time ./benchmark >/dev/null -echo "Fixed size 3x3, ColumnMajor, with asserts" +echo "Fixed size 3x3, column-major, with asserts" $CXX -O3 -I .. benchmark.cpp -o benchmark && time ./benchmark >/dev/null -echo "Fixed size 3x3, RowMajor, -DNDEBUG" +echo "Fixed size 3x3, row-major, -DNDEBUG" $CXX -O3 -I .. -DEIGEN_DEFAULT_TO_ROW_MAJOR -DNDEBUG benchmark.cpp -o benchmark && time ./benchmark >/dev/null -echo "Fixed size 3x3, RowMajor, with asserts" +echo "Fixed size 3x3, row-major, with asserts" $CXX -O3 -I .. -DEIGEN_DEFAULT_TO_ROW_MAJOR benchmark.cpp -o benchmark && time ./benchmark >/dev/null -echo "Dynamic size 20x20, ColumnMajor, -DNDEBUG" +echo "Dynamic size 20x20, column-major, -DNDEBUG" $CXX -O3 -I .. -DNDEBUG benchmarkX.cpp -o benchmarkX && time ./benchmarkX >/dev/null -echo "Dynamic size 20x20, ColumnMajor, with asserts" +echo "Dynamic size 20x20, column-major, with asserts" $CXX -O3 -I .. benchmarkX.cpp -o benchmarkX && time ./benchmarkX >/dev/null -echo "Dynamic size 20x20, RowMajor, -DNDEBUG" +echo "Dynamic size 20x20, row-major, -DNDEBUG" $CXX -O3 -I .. -DEIGEN_DEFAULT_TO_ROW_MAJOR -DNDEBUG benchmarkX.cpp -o benchmarkX && time ./benchmarkX >/dev/null -echo "Dynamic size 20x20, RowMajor, with asserts" +echo "Dynamic size 20x20, row-major, with asserts" $CXX -O3 -I .. -DEIGEN_DEFAULT_TO_ROW_MAJOR benchmarkX.cpp -o benchmarkX && time ./benchmarkX >/dev/null diff --git a/test/basicstuff.cpp b/test/basicstuff.cpp index ac87738cc..052880321 100644 --- a/test/basicstuff.cpp +++ b/test/basicstuff.cpp @@ -110,7 +110,7 @@ void EigenTest::testBasicStuff() m3 = Matrix3d::random(); m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9; - VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); + VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); Vector3d vec[3]; vec[0] << 1, 4, 7; @@ -118,7 +118,7 @@ void EigenTest::testBasicStuff() vec[2] << 3, 6, 9; m3 = Matrix3d::random(); m3 << vec[0], vec[1], vec[2]; - VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); + VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); vec[0] << 1, 2, 3; vec[1] << 4, 5, 6; @@ -127,7 +127,7 @@ void EigenTest::testBasicStuff() m3 << vec[0].transpose(), 4, 5, 6, vec[2].transpose(); - VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); + VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); } } diff --git a/test/main.h b/test/main.h index c69a8f1ec..388a8973d 100644 --- a/test/main.h +++ b/test/main.h @@ -127,7 +127,7 @@ #endif // EIGEN_NO_ASSERTION_CHECKING -//#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER RowMajor +//#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER RowMajorBit #define EIGEN_INTERNAL_DEBUGGING #include diff --git a/test/product.cpp b/test/product.cpp index f09b5c33e..668c8ca56 100644 --- a/test/product.cpp +++ b/test/product.cpp @@ -63,7 +63,7 @@ template void product(const MatrixType& m) m3 = m1; m3 *= (m1.transpose() * m2); VERIFY_IS_APPROX(m3, m1*(m1.transpose()*m2)); - VERIFY_IS_APPROX(m3, m1.lazyProduct(m1.transpose()*m2)); + VERIFY_IS_APPROX(m3, m1.lazy() * (m1.transpose()*m2)); // continue testing Product.h: distributivity VERIFY_IS_APPROX(square*(m1 + m2), square*m1+square*m2); @@ -73,10 +73,11 @@ template void product(const MatrixType& m) 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); + // continue testing Product.h: lazy product + VERIFY_IS_APPROX(square.lazy() * m1, square*m1); + VERIFY_IS_APPROX(square * m1.lazy(), square*m1); // again, test operator() to check const-qualification - s1 += square.lazyProduct(m1)(r,c); + s1 += (square.lazy() * m1)(r,c); // test Product.h together with Identity.h VERIFY_IS_APPROX(m1, identity*m1); diff --git a/test/submatrices.cpp b/test/submatrices.cpp index 640a0fba6..34e3676f2 100644 --- a/test/submatrices.cpp +++ b/test/submatrices.cpp @@ -86,7 +86,7 @@ template void submatrices(const MatrixType& m) //check row() and col() VERIFY_IS_APPROX(m1.col(c1).transpose(), m1.transpose().row(c1)); - VERIFY_IS_APPROX(square.row(r1).dot(m1.col(c1)), square.lazyProduct(m1.conjugate())(r1,c1)); + VERIFY_IS_APPROX(square.row(r1).dot(m1.col(c1)), (square.lazy() * m1.conjugate())(r1,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); -- cgit v1.2.3