Home | History | Annotate | Download | only in Core
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1 (at) gmail.com>
      5 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      6 //
      7 // This Source Code Form is subject to the terms of the Mozilla
      8 // Public License v. 2.0. If a copy of the MPL was not distributed
      9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     10 
     11 #ifndef EIGEN_EIGENBASE_H
     12 #define EIGEN_EIGENBASE_H
     13 
     14 namespace Eigen {
     15 
     16 /** Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
     17   *
     18   * In other words, an EigenBase object is an object that can be copied into a MatrixBase.
     19   *
     20   * Besides MatrixBase-derived classes, this also includes special matrix classes such as diagonal matrices, etc.
     21   *
     22   * Notice that this class is trivial, it is only used to disambiguate overloaded functions.
     23   *
     24   * \sa \ref TopicClassHierarchy
     25   */
     26 template<typename Derived> struct EigenBase
     27 {
     28 //   typedef typename internal::plain_matrix_type<Derived>::type PlainObject;
     29 
     30   typedef typename internal::traits<Derived>::StorageKind StorageKind;
     31   typedef typename internal::traits<Derived>::Index Index;
     32 
     33   /** \returns a reference to the derived object */
     34   Derived& derived() { return *static_cast<Derived*>(this); }
     35   /** \returns a const reference to the derived object */
     36   const Derived& derived() const { return *static_cast<const Derived*>(this); }
     37 
     38   inline Derived& const_cast_derived() const
     39   { return *static_cast<Derived*>(const_cast<EigenBase*>(this)); }
     40   inline const Derived& const_derived() const
     41   { return *static_cast<const Derived*>(this); }
     42 
     43   /** \returns the number of rows. \sa cols(), RowsAtCompileTime */
     44   inline Index rows() const { return derived().rows(); }
     45   /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
     46   inline Index cols() const { return derived().cols(); }
     47   /** \returns the number of coefficients, which is rows()*cols().
     48     * \sa rows(), cols(), SizeAtCompileTime. */
     49   inline Index size() const { return rows() * cols(); }
     50 
     51   /** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */
     52   template<typename Dest> inline void evalTo(Dest& dst) const
     53   { derived().evalTo(dst); }
     54 
     55   /** \internal Don't use it, but do the equivalent: \code dst += *this; \endcode */
     56   template<typename Dest> inline void addTo(Dest& dst) const
     57   {
     58     // This is the default implementation,
     59     // derived class can reimplement it in a more optimized way.
     60     typename Dest::PlainObject res(rows(),cols());
     61     evalTo(res);
     62     dst += res;
     63   }
     64 
     65   /** \internal Don't use it, but do the equivalent: \code dst -= *this; \endcode */
     66   template<typename Dest> inline void subTo(Dest& dst) const
     67   {
     68     // This is the default implementation,
     69     // derived class can reimplement it in a more optimized way.
     70     typename Dest::PlainObject res(rows(),cols());
     71     evalTo(res);
     72     dst -= res;
     73   }
     74 
     75   /** \internal Don't use it, but do the equivalent: \code dst.applyOnTheRight(*this); \endcode */
     76   template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const
     77   {
     78     // This is the default implementation,
     79     // derived class can reimplement it in a more optimized way.
     80     dst = dst * this->derived();
     81   }
     82 
     83   /** \internal Don't use it, but do the equivalent: \code dst.applyOnTheLeft(*this); \endcode */
     84   template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const
     85   {
     86     // This is the default implementation,
     87     // derived class can reimplement it in a more optimized way.
     88     dst = this->derived() * dst;
     89   }
     90 
     91 };
     92 
     93 /***************************************************************************
     94 * Implementation of matrix base methods
     95 ***************************************************************************/
     96 
     97 /** \brief Copies the generic expression \a other into *this.
     98   *
     99   * \details The expression must provide a (templated) evalTo(Derived& dst) const
    100   * function which does the actual job. In practice, this allows any user to write
    101   * its own special matrix without having to modify MatrixBase
    102   *
    103   * \returns a reference to *this.
    104   */
    105 template<typename Derived>
    106 template<typename OtherDerived>
    107 Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
    108 {
    109   other.derived().evalTo(derived());
    110   return derived();
    111 }
    112 
    113 template<typename Derived>
    114 template<typename OtherDerived>
    115 Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
    116 {
    117   other.derived().addTo(derived());
    118   return derived();
    119 }
    120 
    121 template<typename Derived>
    122 template<typename OtherDerived>
    123 Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other)
    124 {
    125   other.derived().subTo(derived());
    126   return derived();
    127 }
    128 
    129 /** replaces \c *this by \c *this * \a other.
    130   *
    131   * \returns a reference to \c *this
    132   */
    133 template<typename Derived>
    134 template<typename OtherDerived>
    135 inline Derived&
    136 MatrixBase<Derived>::operator*=(const EigenBase<OtherDerived> &other)
    137 {
    138   other.derived().applyThisOnTheRight(derived());
    139   return derived();
    140 }
    141 
    142 /** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=() */
    143 template<typename Derived>
    144 template<typename OtherDerived>
    145 inline void MatrixBase<Derived>::applyOnTheRight(const EigenBase<OtherDerived> &other)
    146 {
    147   other.derived().applyThisOnTheRight(derived());
    148 }
    149 
    150 /** replaces \c *this by \c *this * \a other. */
    151 template<typename Derived>
    152 template<typename OtherDerived>
    153 inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &other)
    154 {
    155   other.derived().applyThisOnTheLeft(derived());
    156 }
    157 
    158 } // end namespace Eigen
    159 
    160 #endif // EIGEN_EIGENBASE_H
    161