File indexing completed on 2025-01-18 09:56:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef EIGEN_RESHAPED_H
0012 #define EIGEN_RESHAPED_H
0013
0014 namespace Eigen {
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
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
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 }
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
0102 typedef Impl Base;
0103 EIGEN_GENERIC_PUBLIC_INTERFACE(Reshaped)
0104 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reshaped)
0105
0106
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
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
0130
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
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
0164
0165 EIGEN_DEVICE_FUNC
0166 inline ReshapedImpl_dense(XprType& xpr)
0167 : m_xpr(xpr), m_rows(Rows), m_cols(Cols)
0168 {}
0169
0170
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
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
0188 EIGEN_DEVICE_FUNC
0189 const typename internal::remove_all<XprType>::type&
0190 nestedExpression() const { return m_xpr; }
0191
0192
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
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
0219
0220 EIGEN_DEVICE_FUNC
0221 inline ReshapedImpl_dense(XprType& xpr)
0222 : Base(xpr.data()), m_xpr(xpr)
0223 {}
0224
0225
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
0243 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0244 inline Index innerStride() const
0245 {
0246 return m_xpr.innerStride();
0247 }
0248
0249
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
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
0271 typedef typename packet_traits<Scalar>::type PacketScalar;
0272
0273 enum {
0274 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
0275 HasDirectAccess = traits<XprType>::HasDirectAccess,
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
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, 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 ,
0311
0312 Flags = (evaluator<ArgType>::Flags & (HereditaryBits )),
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, 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
0446 eigen_assert(((internal::UIntPtr(xpr.data()) % EIGEN_PLAIN_ENUM_MAX(1,evaluator<XprType>::Alignment)) == 0) && "data is not aligned");
0447 }
0448 };
0449
0450 }
0451
0452 }
0453
0454 #endif