Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:56:17

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2008-2017 Gael Guennebaud <gael.guennebaud@inria.fr>
0005 // Copyright (C) 2014 yoco <peter.xiau@gmail.com>
0006 //
0007 // This Source Code Form is subject to the terms of the Mozilla
0008 // Public License v. 2.0. If a copy of the MPL was not distributed
0009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
0010 
0011 #ifndef EIGEN_RESHAPED_H
0012 #define EIGEN_RESHAPED_H
0013 
0014 namespace Eigen {
0015 
0016 /** \class Reshaped
0017   * \ingroup Core_Module
0018   *
0019   * \brief Expression of a fixed-size or dynamic-size reshape
0020   *
0021   * \tparam XprType the type of the expression in which we are taking a reshape
0022   * \tparam Rows the number of rows of the reshape we are taking at compile time (optional)
0023   * \tparam Cols the number of columns of the reshape we are taking at compile time (optional)
0024   * \tparam Order can be ColMajor or RowMajor, default is ColMajor.
0025   *
0026   * This class represents an expression of either a fixed-size or dynamic-size reshape.
0027   * It is the return type of DenseBase::reshaped(NRowsType,NColsType) and
0028   * most of the time this is the only way it is used.
0029   *
0030   * However, in C++98, if you want to directly maniputate reshaped expressions,
0031   * for instance if you want to write a function returning such an expression, you
0032   * will need to use this class. In C++11, it is advised to use the \em auto
0033   * keyword for such use cases.
0034   *
0035   * Here is an example illustrating the dynamic case:
0036   * \include class_Reshaped.cpp
0037   * Output: \verbinclude class_Reshaped.out
0038   *
0039   * Here is an example illustrating the fixed-size case:
0040   * \include class_FixedReshaped.cpp
0041   * Output: \verbinclude class_FixedReshaped.out
0042   *
0043   * \sa DenseBase::reshaped(NRowsType,NColsType)
0044   */
0045 
0046 namespace internal {
0047 
0048 template<typename XprType, int Rows, int Cols, int Order>
0049 struct traits<Reshaped<XprType, Rows, Cols, Order> > : traits<XprType>
0050 {
0051   typedef typename traits<XprType>::Scalar Scalar;
0052   typedef typename traits<XprType>::StorageKind StorageKind;
0053   typedef typename traits<XprType>::XprKind XprKind;
0054   enum{
0055     MatrixRows = traits<XprType>::RowsAtCompileTime,
0056     MatrixCols = traits<XprType>::ColsAtCompileTime,
0057     RowsAtCompileTime = Rows,
0058     ColsAtCompileTime = Cols,
0059     MaxRowsAtCompileTime = Rows,
0060     MaxColsAtCompileTime = Cols,
0061     XpxStorageOrder = ((int(traits<XprType>::Flags) & RowMajorBit) == RowMajorBit) ? RowMajor : ColMajor,
0062     ReshapedStorageOrder = (RowsAtCompileTime == 1 && ColsAtCompileTime != 1) ? RowMajor
0063                          : (ColsAtCompileTime == 1 && RowsAtCompileTime != 1) ? ColMajor
0064                          : XpxStorageOrder,
0065     HasSameStorageOrderAsXprType = (ReshapedStorageOrder == XpxStorageOrder),
0066     InnerSize = (ReshapedStorageOrder==int(RowMajor)) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
0067     InnerStrideAtCompileTime = HasSameStorageOrderAsXprType
0068                              ? int(inner_stride_at_compile_time<XprType>::ret)
0069                              : Dynamic,
0070     OuterStrideAtCompileTime = Dynamic,
0071 
0072     HasDirectAccess = internal::has_direct_access<XprType>::ret
0073                     && (Order==int(XpxStorageOrder))
0074                     && ((evaluator<XprType>::Flags&LinearAccessBit)==LinearAccessBit),
0075 
0076     MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0)
0077                        && (InnerStrideAtCompileTime == 1)
0078                         ? PacketAccessBit : 0,
0079     //MaskAlignedBit = ((OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0,
0080     FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
0081     FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
0082     FlagsRowMajorBit = (ReshapedStorageOrder==int(RowMajor)) ? RowMajorBit : 0,
0083     FlagsDirectAccessBit = HasDirectAccess ? DirectAccessBit : 0,
0084     Flags0 = traits<XprType>::Flags & ( (HereditaryBits & ~RowMajorBit) | MaskPacketAccessBit),
0085 
0086     Flags = (Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit | FlagsDirectAccessBit)
0087   };
0088 };
0089 
0090 template<typename XprType, int Rows, int Cols, int Order, bool HasDirectAccess> class ReshapedImpl_dense;
0091 
0092 } // end namespace internal
0093 
0094 template<typename XprType, int Rows, int Cols, int Order, typename StorageKind> class ReshapedImpl;
0095 
0096 template<typename XprType, int Rows, int Cols, int Order> class Reshaped
0097   : public ReshapedImpl<XprType, Rows, Cols, Order, typename internal::traits<XprType>::StorageKind>
0098 {
0099     typedef ReshapedImpl<XprType, Rows, Cols, Order, typename internal::traits<XprType>::StorageKind> Impl;
0100   public:
0101     //typedef typename Impl::Base Base;
0102     typedef Impl Base;
0103     EIGEN_GENERIC_PUBLIC_INTERFACE(Reshaped)
0104     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reshaped)
0105 
0106     /** Fixed-size constructor
0107       */
0108     EIGEN_DEVICE_FUNC
0109     inline Reshaped(XprType& xpr)
0110       : Impl(xpr)
0111     {
0112       EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
0113       eigen_assert(Rows * Cols == xpr.rows() * xpr.cols());
0114     }
0115 
0116     /** Dynamic-size constructor
0117       */
0118     EIGEN_DEVICE_FUNC
0119     inline Reshaped(XprType& xpr,
0120           Index reshapeRows, Index reshapeCols)
0121       : Impl(xpr, reshapeRows, reshapeCols)
0122     {
0123       eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==reshapeRows)
0124           && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==reshapeCols));
0125       eigen_assert(reshapeRows * reshapeCols == xpr.rows() * xpr.cols());
0126     }
0127 };
0128 
0129 // The generic default implementation for dense reshape simply forward to the internal::ReshapedImpl_dense
0130 // that must be specialized for direct and non-direct access...
0131 template<typename XprType, int Rows, int Cols, int Order>
0132 class ReshapedImpl<XprType, Rows, Cols, Order, Dense>
0133   : public internal::ReshapedImpl_dense<XprType, Rows, Cols, Order,internal::traits<Reshaped<XprType,Rows,Cols,Order> >::HasDirectAccess>
0134 {
0135     typedef internal::ReshapedImpl_dense<XprType, Rows, Cols, Order,internal::traits<Reshaped<XprType,Rows,Cols,Order> >::HasDirectAccess> Impl;
0136   public:
0137     typedef Impl Base;
0138     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl)
0139     EIGEN_DEVICE_FUNC inline ReshapedImpl(XprType& xpr) : Impl(xpr) {}
0140     EIGEN_DEVICE_FUNC inline ReshapedImpl(XprType& xpr, Index reshapeRows, Index reshapeCols)
0141       : Impl(xpr, reshapeRows, reshapeCols) {}
0142 };
0143 
0144 namespace internal {
0145 
0146 /** \internal Internal implementation of dense Reshaped in the general case. */
0147 template<typename XprType, int Rows, int Cols, int Order>
0148 class ReshapedImpl_dense<XprType,Rows,Cols,Order,false>
0149   : public internal::dense_xpr_base<Reshaped<XprType, Rows, Cols, Order> >::type
0150 {
0151     typedef Reshaped<XprType, Rows, Cols, Order> ReshapedType;
0152   public:
0153 
0154     typedef typename internal::dense_xpr_base<ReshapedType>::type Base;
0155     EIGEN_DENSE_PUBLIC_INTERFACE(ReshapedType)
0156     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl_dense)
0157 
0158     typedef typename internal::ref_selector<XprType>::non_const_type MatrixTypeNested;
0159     typedef typename internal::remove_all<XprType>::type NestedExpression;
0160 
0161     class InnerIterator;
0162 
0163     /** Fixed-size constructor
0164       */
0165     EIGEN_DEVICE_FUNC
0166     inline ReshapedImpl_dense(XprType& xpr)
0167       : m_xpr(xpr), m_rows(Rows), m_cols(Cols)
0168     {}
0169 
0170     /** Dynamic-size constructor
0171       */
0172     EIGEN_DEVICE_FUNC
0173     inline ReshapedImpl_dense(XprType& xpr, Index nRows, Index nCols)
0174       : m_xpr(xpr), m_rows(nRows), m_cols(nCols)
0175     {}
0176 
0177     EIGEN_DEVICE_FUNC Index rows() const { return m_rows; }
0178     EIGEN_DEVICE_FUNC Index cols() const { return m_cols; }
0179 
0180     #ifdef EIGEN_PARSED_BY_DOXYGEN
0181     /** \sa MapBase::data() */
0182     EIGEN_DEVICE_FUNC inline const Scalar* data() const;
0183     EIGEN_DEVICE_FUNC inline Index innerStride() const;
0184     EIGEN_DEVICE_FUNC inline Index outerStride() const;
0185     #endif
0186 
0187     /** \returns the nested expression */
0188     EIGEN_DEVICE_FUNC
0189     const typename internal::remove_all<XprType>::type&
0190     nestedExpression() const { return m_xpr; }
0191 
0192     /** \returns the nested expression */
0193     EIGEN_DEVICE_FUNC
0194     typename internal::remove_reference<XprType>::type&
0195     nestedExpression() { return m_xpr; }
0196 
0197   protected:
0198 
0199     MatrixTypeNested m_xpr;
0200     const internal::variable_if_dynamic<Index, Rows> m_rows;
0201     const internal::variable_if_dynamic<Index, Cols> m_cols;
0202 };
0203 
0204 
0205 /** \internal Internal implementation of dense Reshaped in the direct access case. */
0206 template<typename XprType, int Rows, int Cols, int Order>
0207 class ReshapedImpl_dense<XprType, Rows, Cols, Order, true>
0208   : public MapBase<Reshaped<XprType, Rows, Cols, Order> >
0209 {
0210     typedef Reshaped<XprType, Rows, Cols, Order> ReshapedType;
0211     typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
0212   public:
0213 
0214     typedef MapBase<ReshapedType> Base;
0215     EIGEN_DENSE_PUBLIC_INTERFACE(ReshapedType)
0216     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl_dense)
0217 
0218     /** Fixed-size constructor
0219       */
0220     EIGEN_DEVICE_FUNC
0221     inline ReshapedImpl_dense(XprType& xpr)
0222       : Base(xpr.data()), m_xpr(xpr)
0223     {}
0224 
0225     /** Dynamic-size constructor
0226       */
0227     EIGEN_DEVICE_FUNC
0228     inline ReshapedImpl_dense(XprType& xpr, Index nRows, Index nCols)
0229       : Base(xpr.data(), nRows, nCols),
0230         m_xpr(xpr)
0231     {}
0232 
0233     EIGEN_DEVICE_FUNC
0234     const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
0235     {
0236       return m_xpr;
0237     }
0238 
0239     EIGEN_DEVICE_FUNC
0240     XprType& nestedExpression() { return m_xpr; }
0241 
0242     /** \sa MapBase::innerStride() */
0243     EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0244     inline Index innerStride() const
0245     {
0246       return m_xpr.innerStride();
0247     }
0248 
0249     /** \sa MapBase::outerStride() */
0250     EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0251     inline Index outerStride() const
0252     {
0253       return ((Flags&RowMajorBit)==RowMajorBit) ? this->cols() : this->rows();
0254     }
0255 
0256   protected:
0257 
0258     XprTypeNested m_xpr;
0259 };
0260 
0261 // Evaluators
0262 template<typename ArgType, int Rows, int Cols, int Order, bool HasDirectAccess> struct reshaped_evaluator;
0263 
0264 template<typename ArgType, int Rows, int Cols, int Order>
0265 struct evaluator<Reshaped<ArgType, Rows, Cols, Order> >
0266   : reshaped_evaluator<ArgType, Rows, Cols, Order, traits<Reshaped<ArgType,Rows,Cols,Order> >::HasDirectAccess>
0267 {
0268   typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
0269   typedef typename XprType::Scalar Scalar;
0270   // TODO: should check for smaller packet types
0271   typedef typename packet_traits<Scalar>::type PacketScalar;
0272 
0273   enum {
0274     CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
0275     HasDirectAccess = traits<XprType>::HasDirectAccess,
0276 
0277 //     RowsAtCompileTime = traits<XprType>::RowsAtCompileTime,
0278 //     ColsAtCompileTime = traits<XprType>::ColsAtCompileTime,
0279 //     MaxRowsAtCompileTime = traits<XprType>::MaxRowsAtCompileTime,
0280 //     MaxColsAtCompileTime = traits<XprType>::MaxColsAtCompileTime,
0281 //
0282 //     InnerStrideAtCompileTime = traits<XprType>::HasSameStorageOrderAsXprType
0283 //                              ? int(inner_stride_at_compile_time<ArgType>::ret)
0284 //                              : Dynamic,
0285 //     OuterStrideAtCompileTime = Dynamic,
0286 
0287     FlagsLinearAccessBit = (traits<XprType>::RowsAtCompileTime == 1 || traits<XprType>::ColsAtCompileTime == 1 || HasDirectAccess) ? LinearAccessBit : 0,
0288     FlagsRowMajorBit = (traits<XprType>::ReshapedStorageOrder==int(RowMajor)) ? RowMajorBit : 0,
0289     FlagsDirectAccessBit =  HasDirectAccess ? DirectAccessBit : 0,
0290     Flags0 = evaluator<ArgType>::Flags & (HereditaryBits & ~RowMajorBit),
0291     Flags = Flags0 | FlagsLinearAccessBit | FlagsRowMajorBit | FlagsDirectAccessBit,
0292 
0293     PacketAlignment = unpacket_traits<PacketScalar>::alignment,
0294     Alignment = evaluator<ArgType>::Alignment
0295   };
0296   typedef reshaped_evaluator<ArgType, Rows, Cols, Order, HasDirectAccess> reshaped_evaluator_type;
0297   EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : reshaped_evaluator_type(xpr)
0298   {
0299     EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
0300   }
0301 };
0302 
0303 template<typename ArgType, int Rows, int Cols, int Order>
0304 struct reshaped_evaluator<ArgType, Rows, Cols, Order, /* HasDirectAccess */ false>
0305   : evaluator_base<Reshaped<ArgType, Rows, Cols, Order> >
0306 {
0307   typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
0308 
0309   enum {
0310     CoeffReadCost = evaluator<ArgType>::CoeffReadCost /* TODO + cost of index computations */,
0311 
0312     Flags = (evaluator<ArgType>::Flags & (HereditaryBits /*| LinearAccessBit | DirectAccessBit*/)),
0313 
0314     Alignment = 0
0315   };
0316 
0317   EIGEN_DEVICE_FUNC explicit reshaped_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_xpr(xpr)
0318   {
0319     EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
0320   }
0321 
0322   typedef typename XprType::Scalar Scalar;
0323   typedef typename XprType::CoeffReturnType CoeffReturnType;
0324 
0325   typedef std::pair<Index, Index> RowCol;
0326 
0327   inline RowCol index_remap(Index rowId, Index colId) const
0328   {
0329     if(Order==ColMajor)
0330     {
0331       const Index nth_elem_idx = colId * m_xpr.rows() + rowId;
0332       return RowCol(nth_elem_idx % m_xpr.nestedExpression().rows(),
0333                     nth_elem_idx / m_xpr.nestedExpression().rows());
0334     }
0335     else
0336     {
0337       const Index nth_elem_idx = colId + rowId * m_xpr.cols();
0338       return RowCol(nth_elem_idx / m_xpr.nestedExpression().cols(),
0339                     nth_elem_idx % m_xpr.nestedExpression().cols());
0340     }
0341   }
0342 
0343   EIGEN_DEVICE_FUNC
0344   inline Scalar& coeffRef(Index rowId, Index colId)
0345   {
0346     EIGEN_STATIC_ASSERT_LVALUE(XprType)
0347     const RowCol row_col = index_remap(rowId, colId);
0348     return m_argImpl.coeffRef(row_col.first, row_col.second);
0349   }
0350 
0351   EIGEN_DEVICE_FUNC
0352   inline const Scalar& coeffRef(Index rowId, Index colId) const
0353   {
0354     const RowCol row_col = index_remap(rowId, colId);
0355     return m_argImpl.coeffRef(row_col.first, row_col.second);
0356   }
0357 
0358   EIGEN_DEVICE_FUNC
0359   EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const
0360   {
0361     const RowCol row_col = index_remap(rowId, colId);
0362     return m_argImpl.coeff(row_col.first, row_col.second);
0363   }
0364 
0365   EIGEN_DEVICE_FUNC
0366   inline Scalar& coeffRef(Index index)
0367   {
0368     EIGEN_STATIC_ASSERT_LVALUE(XprType)
0369     const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
0370                                        Rows == 1 ? index : 0);
0371     return m_argImpl.coeffRef(row_col.first, row_col.second);
0372 
0373   }
0374 
0375   EIGEN_DEVICE_FUNC
0376   inline const Scalar& coeffRef(Index index) const
0377   {
0378     const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
0379                                        Rows == 1 ? index : 0);
0380     return m_argImpl.coeffRef(row_col.first, row_col.second);
0381   }
0382 
0383   EIGEN_DEVICE_FUNC
0384   inline const CoeffReturnType coeff(Index index) const
0385   {
0386     const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
0387                                        Rows == 1 ? index : 0);
0388     return m_argImpl.coeff(row_col.first, row_col.second);
0389   }
0390 #if 0
0391   EIGEN_DEVICE_FUNC
0392   template<int LoadMode>
0393   inline PacketScalar packet(Index rowId, Index colId) const
0394   {
0395     const RowCol row_col = index_remap(rowId, colId);
0396     return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second);
0397 
0398   }
0399 
0400   template<int LoadMode>
0401   EIGEN_DEVICE_FUNC
0402   inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
0403   {
0404     const RowCol row_col = index_remap(rowId, colId);
0405     m_argImpl.const_cast_derived().template writePacket<Unaligned>
0406             (row_col.first, row_col.second, val);
0407   }
0408 
0409   template<int LoadMode>
0410   EIGEN_DEVICE_FUNC
0411   inline PacketScalar packet(Index index) const
0412   {
0413     const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index,
0414                                         RowsAtCompileTime == 1 ? index : 0);
0415     return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second);
0416   }
0417 
0418   template<int LoadMode>
0419   EIGEN_DEVICE_FUNC
0420   inline void writePacket(Index index, const PacketScalar& val)
0421   {
0422     const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index,
0423                                         RowsAtCompileTime == 1 ? index : 0);
0424     return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second, val);
0425   }
0426 #endif
0427 protected:
0428 
0429   evaluator<ArgType> m_argImpl;
0430   const XprType& m_xpr;
0431 
0432 };
0433 
0434 template<typename ArgType, int Rows, int Cols, int Order>
0435 struct reshaped_evaluator<ArgType, Rows, Cols, Order, /* HasDirectAccess */ true>
0436 : mapbase_evaluator<Reshaped<ArgType, Rows, Cols, Order>,
0437                       typename Reshaped<ArgType, Rows, Cols, Order>::PlainObject>
0438 {
0439   typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
0440   typedef typename XprType::Scalar Scalar;
0441 
0442   EIGEN_DEVICE_FUNC explicit reshaped_evaluator(const XprType& xpr)
0443     : mapbase_evaluator<XprType, typename XprType::PlainObject>(xpr)
0444   {
0445     // 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
0446     eigen_assert(((internal::UIntPtr(xpr.data()) % EIGEN_PLAIN_ENUM_MAX(1,evaluator<XprType>::Alignment)) == 0) && "data is not aligned");
0447   }
0448 };
0449 
0450 } // end namespace internal
0451 
0452 } // end namespace Eigen
0453 
0454 #endif // EIGEN_RESHAPED_H