cart-elc

Source code for CART-ELC
git clone git://git.laack.co/cart-elc.git
Log | Files | Refs | README | LICENSE

Reshaped.h (17033B)


      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2008-2017 Gael Guennebaud <gael.guennebaud@inria.fr>
      5 // Copyright (C) 2014 yoco <peter.xiau@gmail.com>
      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_RESHAPED_H
     12 #define EIGEN_RESHAPED_H
     13 
     14 namespace Eigen {
     15 
     16 /** \class Reshaped
     17   * \ingroup Core_Module
     18   *
     19   * \brief Expression of a fixed-size or dynamic-size reshape
     20   *
     21   * \tparam XprType the type of the expression in which we are taking a reshape
     22   * \tparam Rows the number of rows of the reshape we are taking at compile time (optional)
     23   * \tparam Cols the number of columns of the reshape we are taking at compile time (optional)
     24   * \tparam Order can be ColMajor or RowMajor, default is ColMajor.
     25   *
     26   * This class represents an expression of either a fixed-size or dynamic-size reshape.
     27   * It is the return type of DenseBase::reshaped(NRowsType,NColsType) and
     28   * most of the time this is the only way it is used.
     29   *
     30   * However, in C++98, if you want to directly maniputate reshaped expressions,
     31   * for instance if you want to write a function returning such an expression, you
     32   * will need to use this class. In C++11, it is advised to use the \em auto
     33   * keyword for such use cases.
     34   *
     35   * Here is an example illustrating the dynamic case:
     36   * \include class_Reshaped.cpp
     37   * Output: \verbinclude class_Reshaped.out
     38   *
     39   * Here is an example illustrating the fixed-size case:
     40   * \include class_FixedReshaped.cpp
     41   * Output: \verbinclude class_FixedReshaped.out
     42   *
     43   * \sa DenseBase::reshaped(NRowsType,NColsType)
     44   */
     45 
     46 namespace internal {
     47 
     48 template<typename XprType, int Rows, int Cols, int Order>
     49 struct traits<Reshaped<XprType, Rows, Cols, Order> > : traits<XprType>
     50 {
     51   typedef typename traits<XprType>::Scalar Scalar;
     52   typedef typename traits<XprType>::StorageKind StorageKind;
     53   typedef typename traits<XprType>::XprKind XprKind;
     54   enum{
     55     MatrixRows = traits<XprType>::RowsAtCompileTime,
     56     MatrixCols = traits<XprType>::ColsAtCompileTime,
     57     RowsAtCompileTime = Rows,
     58     ColsAtCompileTime = Cols,
     59     MaxRowsAtCompileTime = Rows,
     60     MaxColsAtCompileTime = Cols,
     61     XpxStorageOrder = ((int(traits<XprType>::Flags) & RowMajorBit) == RowMajorBit) ? RowMajor : ColMajor,
     62     ReshapedStorageOrder = (RowsAtCompileTime == 1 && ColsAtCompileTime != 1) ? RowMajor
     63                          : (ColsAtCompileTime == 1 && RowsAtCompileTime != 1) ? ColMajor
     64                          : XpxStorageOrder,
     65     HasSameStorageOrderAsXprType = (ReshapedStorageOrder == XpxStorageOrder),
     66     InnerSize = (ReshapedStorageOrder==int(RowMajor)) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
     67     InnerStrideAtCompileTime = HasSameStorageOrderAsXprType
     68                              ? int(inner_stride_at_compile_time<XprType>::ret)
     69                              : Dynamic,
     70     OuterStrideAtCompileTime = Dynamic,
     71 
     72     HasDirectAccess = internal::has_direct_access<XprType>::ret
     73                     && (Order==int(XpxStorageOrder))
     74                     && ((evaluator<XprType>::Flags&LinearAccessBit)==LinearAccessBit),
     75 
     76     MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0)
     77                        && (InnerStrideAtCompileTime == 1)
     78                         ? PacketAccessBit : 0,
     79     //MaskAlignedBit = ((OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0,
     80     FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
     81     FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
     82     FlagsRowMajorBit = (ReshapedStorageOrder==int(RowMajor)) ? RowMajorBit : 0,
     83     FlagsDirectAccessBit = HasDirectAccess ? DirectAccessBit : 0,
     84     Flags0 = traits<XprType>::Flags & ( (HereditaryBits & ~RowMajorBit) | MaskPacketAccessBit),
     85 
     86     Flags = (Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit | FlagsDirectAccessBit)
     87   };
     88 };
     89 
     90 template<typename XprType, int Rows, int Cols, int Order, bool HasDirectAccess> class ReshapedImpl_dense;
     91 
     92 } // end namespace internal
     93 
     94 template<typename XprType, int Rows, int Cols, int Order, typename StorageKind> class ReshapedImpl;
     95 
     96 template<typename XprType, int Rows, int Cols, int Order> class Reshaped
     97   : public ReshapedImpl<XprType, Rows, Cols, Order, typename internal::traits<XprType>::StorageKind>
     98 {
     99     typedef ReshapedImpl<XprType, Rows, Cols, Order, typename internal::traits<XprType>::StorageKind> Impl;
    100   public:
    101     //typedef typename Impl::Base Base;
    102     typedef Impl Base;
    103     EIGEN_GENERIC_PUBLIC_INTERFACE(Reshaped)
    104     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reshaped)
    105 
    106     /** Fixed-size constructor
    107       */
    108     EIGEN_DEVICE_FUNC
    109     inline Reshaped(XprType& xpr)
    110       : Impl(xpr)
    111     {
    112       EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
    113       eigen_assert(Rows * Cols == xpr.rows() * xpr.cols());
    114     }
    115 
    116     /** Dynamic-size constructor
    117       */
    118     EIGEN_DEVICE_FUNC
    119     inline Reshaped(XprType& xpr,
    120           Index reshapeRows, Index reshapeCols)
    121       : Impl(xpr, reshapeRows, reshapeCols)
    122     {
    123       eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==reshapeRows)
    124           && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==reshapeCols));
    125       eigen_assert(reshapeRows * reshapeCols == xpr.rows() * xpr.cols());
    126     }
    127 };
    128 
    129 // The generic default implementation for dense reshape simply forward to the internal::ReshapedImpl_dense
    130 // that must be specialized for direct and non-direct access...
    131 template<typename XprType, int Rows, int Cols, int Order>
    132 class ReshapedImpl<XprType, Rows, Cols, Order, Dense>
    133   : public internal::ReshapedImpl_dense<XprType, Rows, Cols, Order,internal::traits<Reshaped<XprType,Rows,Cols,Order> >::HasDirectAccess>
    134 {
    135     typedef internal::ReshapedImpl_dense<XprType, Rows, Cols, Order,internal::traits<Reshaped<XprType,Rows,Cols,Order> >::HasDirectAccess> Impl;
    136   public:
    137     typedef Impl Base;
    138     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl)
    139     EIGEN_DEVICE_FUNC inline ReshapedImpl(XprType& xpr) : Impl(xpr) {}
    140     EIGEN_DEVICE_FUNC inline ReshapedImpl(XprType& xpr, Index reshapeRows, Index reshapeCols)
    141       : Impl(xpr, reshapeRows, reshapeCols) {}
    142 };
    143 
    144 namespace internal {
    145 
    146 /** \internal Internal implementation of dense Reshaped in the general case. */
    147 template<typename XprType, int Rows, int Cols, int Order>
    148 class ReshapedImpl_dense<XprType,Rows,Cols,Order,false>
    149   : public internal::dense_xpr_base<Reshaped<XprType, Rows, Cols, Order> >::type
    150 {
    151     typedef Reshaped<XprType, Rows, Cols, Order> ReshapedType;
    152   public:
    153 
    154     typedef typename internal::dense_xpr_base<ReshapedType>::type Base;
    155     EIGEN_DENSE_PUBLIC_INTERFACE(ReshapedType)
    156     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl_dense)
    157 
    158     typedef typename internal::ref_selector<XprType>::non_const_type MatrixTypeNested;
    159     typedef typename internal::remove_all<XprType>::type NestedExpression;
    160 
    161     class InnerIterator;
    162 
    163     /** Fixed-size constructor
    164       */
    165     EIGEN_DEVICE_FUNC
    166     inline ReshapedImpl_dense(XprType& xpr)
    167       : m_xpr(xpr), m_rows(Rows), m_cols(Cols)
    168     {}
    169 
    170     /** Dynamic-size constructor
    171       */
    172     EIGEN_DEVICE_FUNC
    173     inline ReshapedImpl_dense(XprType& xpr, Index nRows, Index nCols)
    174       : m_xpr(xpr), m_rows(nRows), m_cols(nCols)
    175     {}
    176 
    177     EIGEN_DEVICE_FUNC Index rows() const { return m_rows; }
    178     EIGEN_DEVICE_FUNC Index cols() const { return m_cols; }
    179 
    180     #ifdef EIGEN_PARSED_BY_DOXYGEN
    181     /** \sa MapBase::data() */
    182     EIGEN_DEVICE_FUNC inline const Scalar* data() const;
    183     EIGEN_DEVICE_FUNC inline Index innerStride() const;
    184     EIGEN_DEVICE_FUNC inline Index outerStride() const;
    185     #endif
    186 
    187     /** \returns the nested expression */
    188     EIGEN_DEVICE_FUNC
    189     const typename internal::remove_all<XprType>::type&
    190     nestedExpression() const { return m_xpr; }
    191 
    192     /** \returns the nested expression */
    193     EIGEN_DEVICE_FUNC
    194     typename internal::remove_reference<XprType>::type&
    195     nestedExpression() { return m_xpr; }
    196 
    197   protected:
    198 
    199     MatrixTypeNested m_xpr;
    200     const internal::variable_if_dynamic<Index, Rows> m_rows;
    201     const internal::variable_if_dynamic<Index, Cols> m_cols;
    202 };
    203 
    204 
    205 /** \internal Internal implementation of dense Reshaped in the direct access case. */
    206 template<typename XprType, int Rows, int Cols, int Order>
    207 class ReshapedImpl_dense<XprType, Rows, Cols, Order, true>
    208   : public MapBase<Reshaped<XprType, Rows, Cols, Order> >
    209 {
    210     typedef Reshaped<XprType, Rows, Cols, Order> ReshapedType;
    211     typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
    212   public:
    213 
    214     typedef MapBase<ReshapedType> Base;
    215     EIGEN_DENSE_PUBLIC_INTERFACE(ReshapedType)
    216     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl_dense)
    217 
    218     /** Fixed-size constructor
    219       */
    220     EIGEN_DEVICE_FUNC
    221     inline ReshapedImpl_dense(XprType& xpr)
    222       : Base(xpr.data()), m_xpr(xpr)
    223     {}
    224 
    225     /** Dynamic-size constructor
    226       */
    227     EIGEN_DEVICE_FUNC
    228     inline ReshapedImpl_dense(XprType& xpr, Index nRows, Index nCols)
    229       : Base(xpr.data(), nRows, nCols),
    230         m_xpr(xpr)
    231     {}
    232 
    233     EIGEN_DEVICE_FUNC
    234     const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
    235     {
    236       return m_xpr;
    237     }
    238 
    239     EIGEN_DEVICE_FUNC
    240     XprType& nestedExpression() { return m_xpr; }
    241 
    242     /** \sa MapBase::innerStride() */
    243     EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    244     inline Index innerStride() const
    245     {
    246       return m_xpr.innerStride();
    247     }
    248 
    249     /** \sa MapBase::outerStride() */
    250     EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
    251     inline Index outerStride() const
    252     {
    253       return ((Flags&RowMajorBit)==RowMajorBit) ? this->cols() : this->rows();
    254     }
    255 
    256   protected:
    257 
    258     XprTypeNested m_xpr;
    259 };
    260 
    261 // Evaluators
    262 template<typename ArgType, int Rows, int Cols, int Order, bool HasDirectAccess> struct reshaped_evaluator;
    263 
    264 template<typename ArgType, int Rows, int Cols, int Order>
    265 struct evaluator<Reshaped<ArgType, Rows, Cols, Order> >
    266   : reshaped_evaluator<ArgType, Rows, Cols, Order, traits<Reshaped<ArgType,Rows,Cols,Order> >::HasDirectAccess>
    267 {
    268   typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
    269   typedef typename XprType::Scalar Scalar;
    270   // TODO: should check for smaller packet types
    271   typedef typename packet_traits<Scalar>::type PacketScalar;
    272 
    273   enum {
    274     CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
    275     HasDirectAccess = traits<XprType>::HasDirectAccess,
    276 
    277 //     RowsAtCompileTime = traits<XprType>::RowsAtCompileTime,
    278 //     ColsAtCompileTime = traits<XprType>::ColsAtCompileTime,
    279 //     MaxRowsAtCompileTime = traits<XprType>::MaxRowsAtCompileTime,
    280 //     MaxColsAtCompileTime = traits<XprType>::MaxColsAtCompileTime,
    281 //
    282 //     InnerStrideAtCompileTime = traits<XprType>::HasSameStorageOrderAsXprType
    283 //                              ? int(inner_stride_at_compile_time<ArgType>::ret)
    284 //                              : Dynamic,
    285 //     OuterStrideAtCompileTime = Dynamic,
    286 
    287     FlagsLinearAccessBit = (traits<XprType>::RowsAtCompileTime == 1 || traits<XprType>::ColsAtCompileTime == 1 || HasDirectAccess) ? LinearAccessBit : 0,
    288     FlagsRowMajorBit = (traits<XprType>::ReshapedStorageOrder==int(RowMajor)) ? RowMajorBit : 0,
    289     FlagsDirectAccessBit =  HasDirectAccess ? DirectAccessBit : 0,
    290     Flags0 = evaluator<ArgType>::Flags & (HereditaryBits & ~RowMajorBit),
    291     Flags = Flags0 | FlagsLinearAccessBit | FlagsRowMajorBit | FlagsDirectAccessBit,
    292 
    293     PacketAlignment = unpacket_traits<PacketScalar>::alignment,
    294     Alignment = evaluator<ArgType>::Alignment
    295   };
    296   typedef reshaped_evaluator<ArgType, Rows, Cols, Order, HasDirectAccess> reshaped_evaluator_type;
    297   EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : reshaped_evaluator_type(xpr)
    298   {
    299     EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
    300   }
    301 };
    302 
    303 template<typename ArgType, int Rows, int Cols, int Order>
    304 struct reshaped_evaluator<ArgType, Rows, Cols, Order, /* HasDirectAccess */ false>
    305   : evaluator_base<Reshaped<ArgType, Rows, Cols, Order> >
    306 {
    307   typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
    308 
    309   enum {
    310     CoeffReadCost = evaluator<ArgType>::CoeffReadCost /* TODO + cost of index computations */,
    311 
    312     Flags = (evaluator<ArgType>::Flags & (HereditaryBits /*| LinearAccessBit | DirectAccessBit*/)),
    313 
    314     Alignment = 0
    315   };
    316 
    317   EIGEN_DEVICE_FUNC explicit reshaped_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_xpr(xpr)
    318   {
    319     EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
    320   }
    321 
    322   typedef typename XprType::Scalar Scalar;
    323   typedef typename XprType::CoeffReturnType CoeffReturnType;
    324 
    325   typedef std::pair<Index, Index> RowCol;
    326 
    327   inline RowCol index_remap(Index rowId, Index colId) const
    328   {
    329     if(Order==ColMajor)
    330     {
    331       const Index nth_elem_idx = colId * m_xpr.rows() + rowId;
    332       return RowCol(nth_elem_idx % m_xpr.nestedExpression().rows(),
    333                     nth_elem_idx / m_xpr.nestedExpression().rows());
    334     }
    335     else
    336     {
    337       const Index nth_elem_idx = colId + rowId * m_xpr.cols();
    338       return RowCol(nth_elem_idx / m_xpr.nestedExpression().cols(),
    339                     nth_elem_idx % m_xpr.nestedExpression().cols());
    340     }
    341   }
    342 
    343   EIGEN_DEVICE_FUNC
    344   inline Scalar& coeffRef(Index rowId, Index colId)
    345   {
    346     EIGEN_STATIC_ASSERT_LVALUE(XprType)
    347     const RowCol row_col = index_remap(rowId, colId);
    348     return m_argImpl.coeffRef(row_col.first, row_col.second);
    349   }
    350 
    351   EIGEN_DEVICE_FUNC
    352   inline const Scalar& coeffRef(Index rowId, Index colId) const
    353   {
    354     const RowCol row_col = index_remap(rowId, colId);
    355     return m_argImpl.coeffRef(row_col.first, row_col.second);
    356   }
    357 
    358   EIGEN_DEVICE_FUNC
    359   EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const
    360   {
    361     const RowCol row_col = index_remap(rowId, colId);
    362     return m_argImpl.coeff(row_col.first, row_col.second);
    363   }
    364 
    365   EIGEN_DEVICE_FUNC
    366   inline Scalar& coeffRef(Index index)
    367   {
    368     EIGEN_STATIC_ASSERT_LVALUE(XprType)
    369     const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
    370                                        Rows == 1 ? index : 0);
    371     return m_argImpl.coeffRef(row_col.first, row_col.second);
    372 
    373   }
    374 
    375   EIGEN_DEVICE_FUNC
    376   inline const Scalar& coeffRef(Index index) const
    377   {
    378     const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
    379                                        Rows == 1 ? index : 0);
    380     return m_argImpl.coeffRef(row_col.first, row_col.second);
    381   }
    382 
    383   EIGEN_DEVICE_FUNC
    384   inline const CoeffReturnType coeff(Index index) const
    385   {
    386     const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
    387                                        Rows == 1 ? index : 0);
    388     return m_argImpl.coeff(row_col.first, row_col.second);
    389   }
    390 #if 0
    391   EIGEN_DEVICE_FUNC
    392   template<int LoadMode>
    393   inline PacketScalar packet(Index rowId, Index colId) const
    394   {
    395     const RowCol row_col = index_remap(rowId, colId);
    396     return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second);
    397 
    398   }
    399 
    400   template<int LoadMode>
    401   EIGEN_DEVICE_FUNC
    402   inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
    403   {
    404     const RowCol row_col = index_remap(rowId, colId);
    405     m_argImpl.const_cast_derived().template writePacket<Unaligned>
    406             (row_col.first, row_col.second, val);
    407   }
    408 
    409   template<int LoadMode>
    410   EIGEN_DEVICE_FUNC
    411   inline PacketScalar packet(Index index) const
    412   {
    413     const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index,
    414                                         RowsAtCompileTime == 1 ? index : 0);
    415     return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second);
    416   }
    417 
    418   template<int LoadMode>
    419   EIGEN_DEVICE_FUNC
    420   inline void writePacket(Index index, const PacketScalar& val)
    421   {
    422     const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index,
    423                                         RowsAtCompileTime == 1 ? index : 0);
    424     return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second, val);
    425   }
    426 #endif
    427 protected:
    428 
    429   evaluator<ArgType> m_argImpl;
    430   const XprType& m_xpr;
    431 
    432 };
    433 
    434 template<typename ArgType, int Rows, int Cols, int Order>
    435 struct reshaped_evaluator<ArgType, Rows, Cols, Order, /* HasDirectAccess */ true>
    436 : mapbase_evaluator<Reshaped<ArgType, Rows, Cols, Order>,
    437                       typename Reshaped<ArgType, Rows, Cols, Order>::PlainObject>
    438 {
    439   typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
    440   typedef typename XprType::Scalar Scalar;
    441 
    442   EIGEN_DEVICE_FUNC explicit reshaped_evaluator(const XprType& xpr)
    443     : mapbase_evaluator<XprType, typename XprType::PlainObject>(xpr)
    444   {
    445     // TODO: for the 3.4 release, this should be turned to an internal assertion, but let's keep it as is for the beta lifetime
    446     eigen_assert(((internal::UIntPtr(xpr.data()) % EIGEN_PLAIN_ENUM_MAX(1,evaluator<XprType>::Alignment)) == 0) && "data is not aligned");
    447   }
    448 };
    449 
    450 } // end namespace internal
    451 
    452 } // end namespace Eigen
    453 
    454 #endif // EIGEN_RESHAPED_H