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.
This commit is contained in:
Gael Guennebaud 2008-05-29 22:33:07 +00:00
parent b501e08d81
commit e2ac5d244e
7 changed files with 78 additions and 20 deletions

View File

@ -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"

View File

@ -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 <jacob@math.jussieu.fr>
//
// 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/>.
#ifndef EIGEN_ARRAYBASE_H
#define EIGEN_ARRAYBASE_H
template<typename Derived> class ArrayBase<Derived,false> {};
template<typename Derived> class ArrayBase<Derived,true>
{
inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
inline Derived& derived() { return *static_cast<Derived*>(this); }
inline Derived& const_cast_derived() const
{ return *static_cast<Derived*>(const_cast<ArrayBase*>(this)); }
public:
template<typename OtherDerived>
const Product<Derived,OtherDerived>
matrixProduct(const MatrixBase<OtherDerived> &other) const
{
return Product<Derived,OtherDerived>(derived(), other.derived());
}
};
#endif // EIGEN_ARRAYBASE_H

View File

@ -49,7 +49,7 @@
*
* \nosubgrouping
*/
template<typename Derived> class MatrixBase
template<typename Derived> class MatrixBase : public ArrayBase<Derived>
{
struct CommaInitializer;
@ -182,6 +182,24 @@ template<typename Derived> class MatrixBase
};
/** Represents a product scalar-matrix */
typedef CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived> ScalarMultipleReturnType;
/** */
template<typename OtherDerived>
struct ProductReturnType
{
typedef typename ei_meta_if<
(Derived::Flags & OtherDerived::Flags & ArrayBit),
CwiseBinaryOp<ei_scalar_product_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>,
Product<Derived,OtherDerived>
>::ret Type;
};
/** the return type of MatrixBase::conjugate() */
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>,
Derived&
>::ret ConjugateReturnType;
/** the return type of MatrixBase::adjoint() */
typedef Transpose<NestByValue<typename ei_unref<ConjugateReturnType>::type> >
AdjointReturnType;
//@}
/// \name Copying and initialization
@ -281,7 +299,7 @@ template<typename Derived> class MatrixBase
*/
//@{
template<typename OtherDerived>
const Product<Derived,OtherDerived>
const typename ProductReturnType<OtherDerived>::Type
operator*(const MatrixBase<OtherDerived> &other) const;
template<typename OtherDerived>
@ -303,16 +321,6 @@ template<typename Derived> class MatrixBase
Transpose<Derived> transpose();
const Transpose<Derived> transpose() const;
/** the return type of MatrixBase::conjugate() */
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>,
Derived&
>::ret ConjugateReturnType;
/** the return type of MatrixBase::adjoint() */
typedef Transpose<
NestByValue<typename ei_unref<ConjugateReturnType>::type>
> AdjointReturnType;
const AdjointReturnType adjoint() const;
//@}

View File

@ -320,10 +320,11 @@ template<typename Lhs, typename Rhs, int EvalMode> class Product : ei_no_assignm
*/
template<typename Derived>
template<typename OtherDerived>
inline const Product<Derived,OtherDerived>
inline const typename MatrixBase<Derived>::template ProductReturnType<OtherDerived>::Type
MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
{
return Product<Derived,OtherDerived>(derived(), other.derived());
assert( (Derived::Flags&ArrayBit) == (OtherDerived::Flags) );
return typename ProductReturnType<OtherDerived>::Type(derived(), other.derived());
}
/** replaces \c *this by \c *this * \a other.

View File

@ -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;

View File

@ -50,6 +50,7 @@ template<typename MatrixType> class Map;
template<int Direction, typename UnaryOp, typename MatrixType> class PartialRedux;
template<typename MatrixType, unsigned int Mode> class Part;
template<typename MatrixType, unsigned int Mode> class Extract;
template<typename Derived, bool HasArrayFlag = int(ei_traits<Derived>::Flags) & ArrayBit> class ArrayBase;
template<typename Scalar> struct ei_scalar_sum_op;

View File

@ -202,8 +202,8 @@ template<typename T, int n=1> struct ei_nested
ei_must_nest_by_value<T>::ret,
T,
typename ei_meta_if<
int(ei_traits<T>::Flags) & EvalBeforeNestingBit
|| (n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost) < (n-1) * int(T::CoeffReadCost),
(int(ei_traits<T>::Flags) & EvalBeforeNestingBit)
|| ((n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost) < (n-1) * int(T::CoeffReadCost)),
typename ei_eval<T>::type,
const T&
>::ret