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 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      5 //
      6 // This Source Code Form is subject to the terms of the Mozilla
      7 // Public License v. 2.0. If a copy of the MPL was not distributed
      8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9 
     10 #ifndef EIGEN_ARRAYBASE_H
     11 #define EIGEN_ARRAYBASE_H
     12 
     13 namespace Eigen {
     14 
     15 template<typename ExpressionType> class MatrixWrapper;
     16 
     17 /** \class ArrayBase
     18   * \ingroup Core_Module
     19   *
     20   * \brief Base class for all 1D and 2D array, and related expressions
     21   *
     22   * An array is similar to a dense vector or matrix. While matrices are mathematical
     23   * objects with well defined linear algebra operators, an array is just a collection
     24   * of scalar values arranged in a one or two dimensionnal fashion. As the main consequence,
     25   * all operations applied to an array are performed coefficient wise. Furthermore,
     26   * arrays support scalar math functions of the c++ standard library (e.g., std::sin(x)), and convenient
     27   * constructors allowing to easily write generic code working for both scalar values
     28   * and arrays.
     29   *
     30   * This class is the base that is inherited by all array expression types.
     31   *
     32   * \tparam Derived is the derived type, e.g., an array or an expression type.
     33   *
     34   * This class can be extended with the help of the plugin mechanism described on the page
     35   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAYBASE_PLUGIN.
     36   *
     37   * \sa class MatrixBase, \ref TopicClassHierarchy
     38   */
     39 template<typename Derived> class ArrayBase
     40   : public DenseBase<Derived>
     41 {
     42   public:
     43 #ifndef EIGEN_PARSED_BY_DOXYGEN
     44     /** The base class for a given storage type. */
     45     typedef ArrayBase StorageBaseType;
     46 
     47     typedef ArrayBase Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl;
     48 
     49     using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
     50                 typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*;
     51 
     52     typedef typename internal::traits<Derived>::StorageKind StorageKind;
     53     typedef typename internal::traits<Derived>::Index Index;
     54     typedef typename internal::traits<Derived>::Scalar Scalar;
     55     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
     56     typedef typename NumTraits<Scalar>::Real RealScalar;
     57 
     58     typedef DenseBase<Derived> Base;
     59     using Base::RowsAtCompileTime;
     60     using Base::ColsAtCompileTime;
     61     using Base::SizeAtCompileTime;
     62     using Base::MaxRowsAtCompileTime;
     63     using Base::MaxColsAtCompileTime;
     64     using Base::MaxSizeAtCompileTime;
     65     using Base::IsVectorAtCompileTime;
     66     using Base::Flags;
     67     using Base::CoeffReadCost;
     68 
     69     using Base::derived;
     70     using Base::const_cast_derived;
     71     using Base::rows;
     72     using Base::cols;
     73     using Base::size;
     74     using Base::coeff;
     75     using Base::coeffRef;
     76     using Base::lazyAssign;
     77     using Base::operator=;
     78     using Base::operator+=;
     79     using Base::operator-=;
     80     using Base::operator*=;
     81     using Base::operator/=;
     82 
     83     typedef typename Base::CoeffReturnType CoeffReturnType;
     84 
     85 #endif // not EIGEN_PARSED_BY_DOXYGEN
     86 
     87 #ifndef EIGEN_PARSED_BY_DOXYGEN
     88     /** \internal the plain matrix type corresponding to this expression. Note that is not necessarily
     89       * exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const
     90       * reference to a matrix, not a matrix! It is however guaranteed that the return type of eval() is either
     91       * PlainObject or const PlainObject&.
     92       */
     93     typedef Array<typename internal::traits<Derived>::Scalar,
     94                 internal::traits<Derived>::RowsAtCompileTime,
     95                 internal::traits<Derived>::ColsAtCompileTime,
     96                 AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
     97                 internal::traits<Derived>::MaxRowsAtCompileTime,
     98                 internal::traits<Derived>::MaxColsAtCompileTime
     99           > PlainObject;
    100 
    101 
    102     /** \internal Represents a matrix with all coefficients equal to one another*/
    103     typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Derived> ConstantReturnType;
    104 #endif // not EIGEN_PARSED_BY_DOXYGEN
    105 
    106 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase
    107 #   include "../plugins/CommonCwiseUnaryOps.h"
    108 #   include "../plugins/MatrixCwiseUnaryOps.h"
    109 #   include "../plugins/ArrayCwiseUnaryOps.h"
    110 #   include "../plugins/CommonCwiseBinaryOps.h"
    111 #   include "../plugins/MatrixCwiseBinaryOps.h"
    112 #   include "../plugins/ArrayCwiseBinaryOps.h"
    113 #   ifdef EIGEN_ARRAYBASE_PLUGIN
    114 #     include EIGEN_ARRAYBASE_PLUGIN
    115 #   endif
    116 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
    117 
    118     /** Special case of the template operator=, in order to prevent the compiler
    119       * from generating a default operator= (issue hit with g++ 4.1)
    120       */
    121     Derived& operator=(const ArrayBase& other)
    122     {
    123       return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
    124     }
    125 
    126     Derived& operator+=(const Scalar& scalar)
    127     { return *this = derived() + scalar; }
    128     Derived& operator-=(const Scalar& scalar)
    129     { return *this = derived() - scalar; }
    130 
    131     template<typename OtherDerived>
    132     Derived& operator+=(const ArrayBase<OtherDerived>& other);
    133     template<typename OtherDerived>
    134     Derived& operator-=(const ArrayBase<OtherDerived>& other);
    135 
    136     template<typename OtherDerived>
    137     Derived& operator*=(const ArrayBase<OtherDerived>& other);
    138 
    139     template<typename OtherDerived>
    140     Derived& operator/=(const ArrayBase<OtherDerived>& other);
    141 
    142   public:
    143     ArrayBase<Derived>& array() { return *this; }
    144     const ArrayBase<Derived>& array() const { return *this; }
    145 
    146     /** \returns an \link Eigen::MatrixBase Matrix \endlink expression of this array
    147       * \sa MatrixBase::array() */
    148     MatrixWrapper<Derived> matrix() { return derived(); }
    149     const MatrixWrapper<const Derived> matrix() const { return derived(); }
    150 
    151 //     template<typename Dest>
    152 //     inline void evalTo(Dest& dst) const { dst = matrix(); }
    153 
    154   protected:
    155     ArrayBase() : Base() {}
    156 
    157   private:
    158     explicit ArrayBase(Index);
    159     ArrayBase(Index,Index);
    160     template<typename OtherDerived> explicit ArrayBase(const ArrayBase<OtherDerived>&);
    161   protected:
    162     // mixing arrays and matrices is not legal
    163     template<typename OtherDerived> Derived& operator+=(const MatrixBase<OtherDerived>& )
    164     {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
    165     // mixing arrays and matrices is not legal
    166     template<typename OtherDerived> Derived& operator-=(const MatrixBase<OtherDerived>& )
    167     {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
    168 };
    169 
    170 /** replaces \c *this by \c *this - \a other.
    171   *
    172   * \returns a reference to \c *this
    173   */
    174 template<typename Derived>
    175 template<typename OtherDerived>
    176 EIGEN_STRONG_INLINE Derived &
    177 ArrayBase<Derived>::operator-=(const ArrayBase<OtherDerived> &other)
    178 {
    179   SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, OtherDerived> tmp(derived());
    180   tmp = other.derived();
    181   return derived();
    182 }
    183 
    184 /** replaces \c *this by \c *this + \a other.
    185   *
    186   * \returns a reference to \c *this
    187   */
    188 template<typename Derived>
    189 template<typename OtherDerived>
    190 EIGEN_STRONG_INLINE Derived &
    191 ArrayBase<Derived>::operator+=(const ArrayBase<OtherDerived>& other)
    192 {
    193   SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived());
    194   tmp = other.derived();
    195   return derived();
    196 }
    197 
    198 /** replaces \c *this by \c *this * \a other coefficient wise.
    199   *
    200   * \returns a reference to \c *this
    201   */
    202 template<typename Derived>
    203 template<typename OtherDerived>
    204 EIGEN_STRONG_INLINE Derived &
    205 ArrayBase<Derived>::operator*=(const ArrayBase<OtherDerived>& other)
    206 {
    207   SelfCwiseBinaryOp<internal::scalar_product_op<Scalar>, Derived, OtherDerived> tmp(derived());
    208   tmp = other.derived();
    209   return derived();
    210 }
    211 
    212 /** replaces \c *this by \c *this / \a other coefficient wise.
    213   *
    214   * \returns a reference to \c *this
    215   */
    216 template<typename Derived>
    217 template<typename OtherDerived>
    218 EIGEN_STRONG_INLINE Derived &
    219 ArrayBase<Derived>::operator/=(const ArrayBase<OtherDerived>& other)
    220 {
    221   SelfCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, Derived, OtherDerived> tmp(derived());
    222   tmp = other.derived();
    223   return derived();
    224 }
    225 
    226 } // end namespace Eigen
    227 
    228 #endif // EIGEN_ARRAYBASE_H
    229