From e2ac5d244edcacc4c95474a732dd5ec7ce2acb0f Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Thu, 29 May 2008 22:33:07 +0000 Subject: [PATCH] Added ArrayBit to get the ability to manipulate a Matrix like a simple scalar. In particular this flag changes the behavior of operator* to a coeff wise product. --- Eigen/Core | 1 + Eigen/src/Core/ArrayBase.h | 45 +++++++++++++++++++++++ Eigen/src/Core/MatrixBase.h | 32 ++++++++++------ Eigen/src/Core/Product.h | 5 ++- Eigen/src/Core/util/Constants.h | 10 +++-- Eigen/src/Core/util/ForwardDeclarations.h | 1 + Eigen/src/Core/util/Meta.h | 4 +- 7 files changed, 78 insertions(+), 20 deletions(-) create mode 100644 Eigen/src/Core/ArrayBase.h diff --git a/Eigen/Core b/Eigen/Core index f3e6b1fcc..2c29f3602 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -27,6 +27,7 @@ namespace Eigen { #include "src/Core/Functors.h" #include "src/Core/MatrixBase.h" +#include "src/Core/ArrayBase.h" #include "src/Core/Coeffs.h" #include "src/Core/Assign.h" #include "src/Core/MatrixStorage.h" diff --git a/Eigen/src/Core/ArrayBase.h b/Eigen/src/Core/ArrayBase.h new file mode 100644 index 000000000..222c0256a --- /dev/null +++ b/Eigen/src/Core/ArrayBase.h @@ -0,0 +1,45 @@ +// 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-2008 Benoit Jacob +// +// 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 . + +#ifndef EIGEN_ARRAYBASE_H +#define EIGEN_ARRAYBASE_H + +template class ArrayBase {}; + +template class ArrayBase +{ + inline const Derived& derived() const { return *static_cast(this); } + inline Derived& derived() { return *static_cast(this); } + inline Derived& const_cast_derived() const + { return *static_cast(const_cast(this)); } +public: + template + const Product + matrixProduct(const MatrixBase &other) const + { + return Product(derived(), other.derived()); + } +}; + +#endif // EIGEN_ARRAYBASE_H \ No newline at end of file diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index e14ac5df2..c39b2d93e 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -49,7 +49,7 @@ * * \nosubgrouping */ -template class MatrixBase +template class MatrixBase : public ArrayBase { struct CommaInitializer; @@ -182,6 +182,24 @@ template class MatrixBase }; /** Represents a product scalar-matrix */ typedef CwiseUnaryOp, Derived> ScalarMultipleReturnType; + /** */ + template + struct ProductReturnType + { + typedef typename ei_meta_if< + (Derived::Flags & OtherDerived::Flags & ArrayBit), + CwiseBinaryOp::Scalar>, Derived, OtherDerived>, + Product + >::ret Type; + }; + /** the return type of MatrixBase::conjugate() */ + typedef typename ei_meta_if::IsComplex, + CwiseUnaryOp, Derived>, + Derived& + >::ret ConjugateReturnType; + /** the return type of MatrixBase::adjoint() */ + typedef Transpose::type> > + AdjointReturnType; //@} /// \name Copying and initialization @@ -281,7 +299,7 @@ template class MatrixBase */ //@{ template - const Product + const typename ProductReturnType::Type operator*(const MatrixBase &other) const; template @@ -303,16 +321,6 @@ template class MatrixBase Transpose transpose(); const Transpose transpose() const; - - /** the return type of MatrixBase::conjugate() */ - typedef typename ei_meta_if::IsComplex, - CwiseUnaryOp, Derived>, - Derived& - >::ret ConjugateReturnType; - /** the return type of MatrixBase::adjoint() */ - typedef Transpose< - NestByValue::type> - > AdjointReturnType; const AdjointReturnType adjoint() const; //@} diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 1b62e0750..fb0f732b5 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -320,10 +320,11 @@ template class Product : ei_no_assignm */ template template -inline const Product +inline const typename MatrixBase::template ProductReturnType::Type MatrixBase::operator*(const MatrixBase &other) const { - return Product(derived(), other.derived()); + assert( (Derived::Flags&ArrayBit) == (OtherDerived::Flags) ); + return typename ProductReturnType::Type(derived(), other.derived()); } /** replaces \c *this by \c *this * \a other. diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h index 1a84e64c6..909921f35 100644 --- a/Eigen/src/Core/util/Constants.h +++ b/Eigen/src/Core/util/Constants.h @@ -42,15 +42,17 @@ const unsigned int Like1DArrayBit = 0x20; ///< means the expression can be see const unsigned int ZeroDiagBit = 0x40; ///< means all diagonal coefficients are equal to 0 const unsigned int UnitDiagBit = 0x80; ///< means all diagonal coefficients are equal to 1 const unsigned int SelfAdjointBit = 0x100; ///< means the matrix is selfadjoint (M=M*). -const unsigned int UpperTriangularBit = 0x200; ///< means the strictly triangular lower part is 0 -const unsigned int LowerTriangularBit = 0x400; ///< means the strictly triangular upper part is 0 -const unsigned int DirectAccessBit = 0x800; ///< means the underlying matrix data can be direclty accessed +const unsigned int UpperTriangularBit = 0x200; ///< means the strictly triangular lower part is 0 +const unsigned int LowerTriangularBit = 0x400; ///< means the strictly triangular upper part is 0 +const unsigned int DirectAccessBit = 0x800; ///< means the underlying matrix data can be direclty accessed +const unsigned int ArrayBit = 0x1000; ///< means the underlying matrix data can be direclty accessed // list of flags that are inherited by default const unsigned int HereditaryBits = RowMajorBit | EvalBeforeNestingBit | EvalBeforeAssigningBit - | LargeBit; + | LargeBit + | ArrayBit; // Possible values for the Mode parameter of part() and of extract() const unsigned int Upper = UpperTriangularBit; diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index c229351aa..b9bc72efc 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -50,6 +50,7 @@ template class Map; template class PartialRedux; template class Part; template class Extract; +template::Flags) & ArrayBit> class ArrayBase; template struct ei_scalar_sum_op; diff --git a/Eigen/src/Core/util/Meta.h b/Eigen/src/Core/util/Meta.h index 792f65b33..f1939f59e 100644 --- a/Eigen/src/Core/util/Meta.h +++ b/Eigen/src/Core/util/Meta.h @@ -202,8 +202,8 @@ template struct ei_nested ei_must_nest_by_value::ret, T, typename ei_meta_if< - int(ei_traits::Flags) & EvalBeforeNestingBit - || (n+1) * int(NumTraits::Scalar>::ReadCost) < (n-1) * int(T::CoeffReadCost), + (int(ei_traits::Flags) & EvalBeforeNestingBit) + || ((n+1) * int(NumTraits::Scalar>::ReadCost) < (n-1) * int(T::CoeffReadCost)), typename ei_eval::type, const T& >::ret