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_ARRAY_H
     11 #define EIGEN_ARRAY_H
     12 
     13 namespace Eigen {
     14 
     15 /** \class Array
     16   * \ingroup Core_Module
     17   *
     18   * \brief General-purpose arrays with easy API for coefficient-wise operations
     19   *
     20   * The %Array class is very similar to the Matrix class. It provides
     21   * general-purpose one- and two-dimensional arrays. The difference between the
     22   * %Array and the %Matrix class is primarily in the API: the API for the
     23   * %Array class provides easy access to coefficient-wise operations, while the
     24   * API for the %Matrix class provides easy access to linear-algebra
     25   * operations.
     26   *
     27   * This class can be extended with the help of the plugin mechanism described on the page
     28   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAY_PLUGIN.
     29   *
     30   * \sa \ref TutorialArrayClass, \ref TopicClassHierarchy
     31   */
     32 namespace internal {
     33 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
     34 struct traits<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > : traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
     35 {
     36   typedef ArrayXpr XprKind;
     37   typedef ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > XprBase;
     38 };
     39 }
     40 
     41 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
     42 class Array
     43   : public PlainObjectBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
     44 {
     45   public:
     46 
     47     typedef PlainObjectBase<Array> Base;
     48     EIGEN_DENSE_PUBLIC_INTERFACE(Array)
     49 
     50     enum { Options = _Options };
     51     typedef typename Base::PlainObject PlainObject;
     52 
     53   protected:
     54     template <typename Derived, typename OtherDerived, bool IsVector>
     55     friend struct internal::conservative_resize_like_impl;
     56 
     57     using Base::m_storage;
     58 
     59   public:
     60 
     61     using Base::base;
     62     using Base::coeff;
     63     using Base::coeffRef;
     64 
     65     /**
     66       * The usage of
     67       *   using Base::operator=;
     68       * fails on MSVC. Since the code below is working with GCC and MSVC, we skipped
     69       * the usage of 'using'. This should be done only for operator=.
     70       */
     71     template<typename OtherDerived>
     72     EIGEN_STRONG_INLINE Array& operator=(const EigenBase<OtherDerived> &other)
     73     {
     74       return Base::operator=(other);
     75     }
     76 
     77     /** Copies the value of the expression \a other into \c *this with automatic resizing.
     78       *
     79       * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
     80       * it will be initialized.
     81       *
     82       * Note that copying a row-vector into a vector (and conversely) is allowed.
     83       * The resizing, if any, is then done in the appropriate way so that row-vectors
     84       * remain row-vectors and vectors remain vectors.
     85       */
     86     template<typename OtherDerived>
     87     EIGEN_STRONG_INLINE Array& operator=(const ArrayBase<OtherDerived>& other)
     88     {
     89       return Base::_set(other);
     90     }
     91 
     92     /** This is a special case of the templated operator=. Its purpose is to
     93       * prevent a default operator= from hiding the templated operator=.
     94       */
     95     EIGEN_STRONG_INLINE Array& operator=(const Array& other)
     96     {
     97       return Base::_set(other);
     98     }
     99 
    100     /** Default constructor.
    101       *
    102       * For fixed-size matrices, does nothing.
    103       *
    104       * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix
    105       * is called a null matrix. This constructor is the unique way to create null matrices: resizing
    106       * a matrix to 0 is not supported.
    107       *
    108       * \sa resize(Index,Index)
    109       */
    110     EIGEN_STRONG_INLINE explicit Array() : Base()
    111     {
    112       Base::_check_template_params();
    113       EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
    114     }
    115 
    116 #ifndef EIGEN_PARSED_BY_DOXYGEN
    117     // FIXME is it still needed ??
    118     /** \internal */
    119     Array(internal::constructor_without_unaligned_array_assert)
    120       : Base(internal::constructor_without_unaligned_array_assert())
    121     {
    122       Base::_check_template_params();
    123       EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
    124     }
    125 #endif
    126 
    127     /** Constructs a vector or row-vector with given dimension. \only_for_vectors
    128       *
    129       * Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
    130       * it is redundant to pass the dimension here, so it makes more sense to use the default
    131       * constructor Matrix() instead.
    132       */
    133     EIGEN_STRONG_INLINE explicit Array(Index dim)
    134       : Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim)
    135     {
    136       Base::_check_template_params();
    137       EIGEN_STATIC_ASSERT_VECTOR_ONLY(Array)
    138       eigen_assert(dim >= 0);
    139       eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim);
    140       EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
    141     }
    142 
    143     #ifndef EIGEN_PARSED_BY_DOXYGEN
    144     template<typename T0, typename T1>
    145     EIGEN_STRONG_INLINE Array(const T0& x, const T1& y)
    146     {
    147       Base::_check_template_params();
    148       this->template _init2<T0,T1>(x, y);
    149     }
    150     #else
    151     /** constructs an uninitialized matrix with \a rows rows and \a cols columns.
    152       *
    153       * This is useful for dynamic-size matrices. For fixed-size matrices,
    154       * it is redundant to pass these parameters, so one should use the default constructor
    155       * Matrix() instead. */
    156     Array(Index rows, Index cols);
    157     /** constructs an initialized 2D vector with given coefficients */
    158     Array(const Scalar& x, const Scalar& y);
    159     #endif
    160 
    161     /** constructs an initialized 3D vector with given coefficients */
    162     EIGEN_STRONG_INLINE Array(const Scalar& x, const Scalar& y, const Scalar& z)
    163     {
    164       Base::_check_template_params();
    165       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3)
    166       m_storage.data()[0] = x;
    167       m_storage.data()[1] = y;
    168       m_storage.data()[2] = z;
    169     }
    170     /** constructs an initialized 4D vector with given coefficients */
    171     EIGEN_STRONG_INLINE Array(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
    172     {
    173       Base::_check_template_params();
    174       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4)
    175       m_storage.data()[0] = x;
    176       m_storage.data()[1] = y;
    177       m_storage.data()[2] = z;
    178       m_storage.data()[3] = w;
    179     }
    180 
    181     explicit Array(const Scalar *data);
    182 
    183     /** Constructor copying the value of the expression \a other */
    184     template<typename OtherDerived>
    185     EIGEN_STRONG_INLINE Array(const ArrayBase<OtherDerived>& other)
    186              : Base(other.rows() * other.cols(), other.rows(), other.cols())
    187     {
    188       Base::_check_template_params();
    189       Base::_set_noalias(other);
    190     }
    191     /** Copy constructor */
    192     EIGEN_STRONG_INLINE Array(const Array& other)
    193             : Base(other.rows() * other.cols(), other.rows(), other.cols())
    194     {
    195       Base::_check_template_params();
    196       Base::_set_noalias(other);
    197     }
    198     /** Copy constructor with in-place evaluation */
    199     template<typename OtherDerived>
    200     EIGEN_STRONG_INLINE Array(const ReturnByValue<OtherDerived>& other)
    201     {
    202       Base::_check_template_params();
    203       Base::resize(other.rows(), other.cols());
    204       other.evalTo(*this);
    205     }
    206 
    207     /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
    208     template<typename OtherDerived>
    209     EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other)
    210       : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
    211     {
    212       Base::_check_template_params();
    213       Base::resize(other.rows(), other.cols());
    214       *this = other;
    215     }
    216 
    217     /** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the
    218       * data pointers.
    219       */
    220     template<typename OtherDerived>
    221     void swap(ArrayBase<OtherDerived> const & other)
    222     { this->_swap(other.derived()); }
    223 
    224     inline Index innerStride() const { return 1; }
    225     inline Index outerStride() const { return this->innerSize(); }
    226 
    227     #ifdef EIGEN_ARRAY_PLUGIN
    228     #include EIGEN_ARRAY_PLUGIN
    229     #endif
    230 
    231   private:
    232 
    233     template<typename MatrixType, typename OtherDerived, bool SwapPointers>
    234     friend struct internal::matrix_swap_impl;
    235 };
    236 
    237 /** \defgroup arraytypedefs Global array typedefs
    238   * \ingroup Core_Module
    239   *
    240   * Eigen defines several typedef shortcuts for most common 1D and 2D array types.
    241   *
    242   * The general patterns are the following:
    243   *
    244   * \c ArrayRowsColsType where \c Rows and \c Cols can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size,
    245   * and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd
    246   * for complex double.
    247   *
    248   * For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of floats.
    249   *
    250   * There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is
    251   * a fixed-size 1D array of 4 complex floats.
    252   *
    253   * \sa class Array
    254   */
    255 
    256 #define EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix)   \
    257 /** \ingroup arraytypedefs */                                    \
    258 typedef Array<Type, Size, Size> Array##SizeSuffix##SizeSuffix##TypeSuffix;  \
    259 /** \ingroup arraytypedefs */                                    \
    260 typedef Array<Type, Size, 1>    Array##SizeSuffix##TypeSuffix;
    261 
    262 #define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, Size)         \
    263 /** \ingroup arraytypedefs */                                    \
    264 typedef Array<Type, Size, Dynamic> Array##Size##X##TypeSuffix;  \
    265 /** \ingroup arraytypedefs */                                    \
    266 typedef Array<Type, Dynamic, Size> Array##X##Size##TypeSuffix;
    267 
    268 #define EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \
    269 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 2, 2) \
    270 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 3, 3) \
    271 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 4, 4) \
    272 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \
    273 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \
    274 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \
    275 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 4)
    276 
    277 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(int,                  i)
    278 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(float,                f)
    279 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(double,               d)
    280 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<float>,  cf)
    281 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<double>, cd)
    282 
    283 #undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES
    284 #undef EIGEN_MAKE_ARRAY_TYPEDEFS
    285 
    286 #undef EIGEN_MAKE_ARRAY_TYPEDEFS_LARGE
    287 
    288 #define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \
    289 using Eigen::Matrix##SizeSuffix##TypeSuffix; \
    290 using Eigen::Vector##SizeSuffix##TypeSuffix; \
    291 using Eigen::RowVector##SizeSuffix##TypeSuffix;
    292 
    293 #define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(TypeSuffix) \
    294 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \
    295 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \
    296 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \
    297 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \
    298 
    299 #define EIGEN_USING_ARRAY_TYPEDEFS \
    300 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i) \
    301 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(f) \
    302 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d) \
    303 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \
    304 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd)
    305 
    306 } // end namespace Eigen
    307 
    308 #endif // EIGEN_ARRAY_H
    309