Reshaped.h
Go to the documentation of this file.
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 #include "./InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
47 namespace internal {
48 
49 template<typename XprType, int Rows, int Cols, int Order>
50 struct traits<Reshaped<XprType, Rows, Cols, Order> > : traits<XprType>
51 {
52  typedef typename traits<XprType>::Scalar Scalar;
53  typedef typename traits<XprType>::StorageKind StorageKind;
54  typedef typename traits<XprType>::XprKind XprKind;
55  enum{
56  MatrixRows = traits<XprType>::RowsAtCompileTime,
57  MatrixCols = traits<XprType>::ColsAtCompileTime,
58  RowsAtCompileTime = Rows,
59  ColsAtCompileTime = Cols,
60  MaxRowsAtCompileTime = Rows,
61  MaxColsAtCompileTime = Cols,
62  XpxStorageOrder = ((int(traits<XprType>::Flags) & RowMajorBit) == RowMajorBit) ? RowMajor : ColMajor,
63  ReshapedStorageOrder = (RowsAtCompileTime == 1 && ColsAtCompileTime != 1) ? RowMajor
64  : (ColsAtCompileTime == 1 && RowsAtCompileTime != 1) ? ColMajor
65  : XpxStorageOrder,
66  HasSameStorageOrderAsXprType = (ReshapedStorageOrder == XpxStorageOrder),
67  InnerSize = (ReshapedStorageOrder==int(RowMajor)) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
68  InnerStrideAtCompileTime = HasSameStorageOrderAsXprType
69  ? int(inner_stride_at_compile_time<XprType>::ret)
70  : Dynamic,
71  OuterStrideAtCompileTime = Dynamic,
72 
73  HasDirectAccess = internal::has_direct_access<XprType>::ret
74  && (Order==int(XpxStorageOrder))
75  && ((evaluator<XprType>::Flags&LinearAccessBit)==LinearAccessBit),
76 
77  MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0)
78  && (InnerStrideAtCompileTime == 1)
79  ? PacketAccessBit : 0,
80  //MaskAlignedBit = ((OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0,
81  FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
82  FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
83  FlagsRowMajorBit = (ReshapedStorageOrder==int(RowMajor)) ? RowMajorBit : 0,
84  FlagsDirectAccessBit = HasDirectAccess ? DirectAccessBit : 0,
85  Flags0 = traits<XprType>::Flags & ( (HereditaryBits & ~RowMajorBit) | MaskPacketAccessBit),
86 
87  Flags = (Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit | FlagsDirectAccessBit)
88  };
89 };
90 
91 template<typename XprType, int Rows, int Cols, int Order, bool HasDirectAccess> class ReshapedImpl_dense;
92 
93 } // end namespace internal
94 
95 template<typename XprType, int Rows, int Cols, int Order, typename StorageKind> class ReshapedImpl;
96 
97 template<typename XprType, int Rows, int Cols, int Order> class Reshaped
98  : public ReshapedImpl<XprType, Rows, Cols, Order, typename internal::traits<XprType>::StorageKind>
99 {
101  public:
102  //typedef typename Impl::Base Base;
103  typedef Impl Base;
106 
107 
110  inline Reshaped(XprType& xpr)
111  : Impl(xpr)
112  {
113  EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
114  eigen_assert(Rows * Cols == xpr.rows() * xpr.cols());
115  }
116 
120  inline Reshaped(XprType& xpr,
121  Index reshapeRows, Index reshapeCols)
122  : Impl(xpr, reshapeRows, reshapeCols)
123  {
124  eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==reshapeRows)
125  && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==reshapeCols));
126  eigen_assert(reshapeRows * reshapeCols == xpr.rows() * xpr.cols());
127  }
128 };
129 
130 // The generic default implementation for dense reshape simply forward to the internal::ReshapedImpl_dense
131 // that must be specialized for direct and non-direct access...
132 template<typename XprType, int Rows, int Cols, int Order>
133 class ReshapedImpl<XprType, Rows, Cols, Order, Dense>
134  : public internal::ReshapedImpl_dense<XprType, Rows, Cols, Order,internal::traits<Reshaped<XprType,Rows,Cols,Order> >::HasDirectAccess>
135 {
136  typedef internal::ReshapedImpl_dense<XprType, Rows, Cols, Order,internal::traits<Reshaped<XprType,Rows,Cols,Order> >::HasDirectAccess> Impl;
137  public:
138  typedef Impl Base;
140  EIGEN_DEVICE_FUNC inline ReshapedImpl(XprType& xpr) : Impl(xpr) {}
141  EIGEN_DEVICE_FUNC inline ReshapedImpl(XprType& xpr, Index reshapeRows, Index reshapeCols)
142  : Impl(xpr, reshapeRows, reshapeCols) {}
143 };
144 
145 namespace internal {
146 
148 template<typename XprType, int Rows, int Cols, int Order>
149 class ReshapedImpl_dense<XprType,Rows,Cols,Order,false>
150  : public internal::dense_xpr_base<Reshaped<XprType, Rows, Cols, Order> >::type
151 {
152  typedef Reshaped<XprType, Rows, Cols, Order> ReshapedType;
153  public:
154 
155  typedef typename internal::dense_xpr_base<ReshapedType>::type Base;
156  EIGEN_DENSE_PUBLIC_INTERFACE(ReshapedType)
157  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl_dense)
158 
159  typedef typename internal::ref_selector<XprType>::non_const_type MatrixTypeNested;
160  typedef internal::remove_all_t<XprType> NestedExpression;
161 
162  class InnerIterator;
163 
167  inline ReshapedImpl_dense(XprType& xpr)
168  : m_xpr(xpr), m_rows(Rows), m_cols(Cols)
169  {}
170 
174  inline ReshapedImpl_dense(XprType& xpr, Index nRows, Index nCols)
175  : m_xpr(xpr), m_rows(nRows), m_cols(nCols)
176  {}
177 
178  EIGEN_DEVICE_FUNC Index rows() const { return m_rows; }
179  EIGEN_DEVICE_FUNC Index cols() const { return m_cols; }
180 
181  #ifdef EIGEN_PARSED_BY_DOXYGEN
183  EIGEN_DEVICE_FUNC inline const Scalar* data() const;
184  EIGEN_DEVICE_FUNC inline Index innerStride() const;
185  EIGEN_DEVICE_FUNC inline Index outerStride() const;
186  #endif
187 
190  const internal::remove_all_t<XprType>&
191  nestedExpression() const { return m_xpr; }
192 
195  std::remove_reference_t<XprType>&
196  nestedExpression() { return m_xpr; }
197 
198  protected:
199 
200  MatrixTypeNested m_xpr;
201  const internal::variable_if_dynamic<Index, Rows> m_rows;
202  const internal::variable_if_dynamic<Index, Cols> m_cols;
203 };
204 
205 
207 template<typename XprType, int Rows, int Cols, int Order>
208 class ReshapedImpl_dense<XprType, Rows, Cols, Order, true>
209  : public MapBase<Reshaped<XprType, Rows, Cols, Order> >
210 {
211  typedef Reshaped<XprType, Rows, Cols, Order> ReshapedType;
212  typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
213  public:
214 
215  typedef MapBase<ReshapedType> Base;
216  EIGEN_DENSE_PUBLIC_INTERFACE(ReshapedType)
217  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl_dense)
218 
219 
222  inline ReshapedImpl_dense(XprType& xpr)
223  : Base(xpr.data()), m_xpr(xpr)
224  {}
225 
229  inline ReshapedImpl_dense(XprType& xpr, Index nRows, Index nCols)
230  : Base(xpr.data(), nRows, nCols),
231  m_xpr(xpr)
232  {}
233 
235  const internal::remove_all_t<XprTypeNested>& nestedExpression() const
236  {
237  return m_xpr;
238  }
239 
241  XprType& nestedExpression() { return m_xpr; }
242 
245  inline Index innerStride() const
246  {
247  return m_xpr.innerStride();
248  }
249 
252  inline Index outerStride() const
253  {
254  return (((Flags&RowMajorBit)==RowMajorBit) ? this->cols() : this->rows()) * m_xpr.innerStride();
255  }
256 
257  protected:
258 
259  XprTypeNested m_xpr;
260 };
261 
262 // Evaluators
263 template<typename ArgType, int Rows, int Cols, int Order, bool HasDirectAccess> struct reshaped_evaluator;
264 
265 template<typename ArgType, int Rows, int Cols, int Order>
266 struct evaluator<Reshaped<ArgType, Rows, Cols, Order> >
267  : reshaped_evaluator<ArgType, Rows, Cols, Order, traits<Reshaped<ArgType,Rows,Cols,Order> >::HasDirectAccess>
268 {
269  typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
270  typedef typename XprType::Scalar Scalar;
271  // TODO: should check for smaller packet types
272  typedef typename packet_traits<Scalar>::type PacketScalar;
273 
274  enum {
275  CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
276  HasDirectAccess = traits<XprType>::HasDirectAccess,
277 
278 // RowsAtCompileTime = traits<XprType>::RowsAtCompileTime,
279 // ColsAtCompileTime = traits<XprType>::ColsAtCompileTime,
280 // MaxRowsAtCompileTime = traits<XprType>::MaxRowsAtCompileTime,
281 // MaxColsAtCompileTime = traits<XprType>::MaxColsAtCompileTime,
282 //
283 // InnerStrideAtCompileTime = traits<XprType>::HasSameStorageOrderAsXprType
284 // ? int(inner_stride_at_compile_time<ArgType>::ret)
285 // : Dynamic,
286 // OuterStrideAtCompileTime = Dynamic,
287 
288  FlagsLinearAccessBit = (traits<XprType>::RowsAtCompileTime == 1 || traits<XprType>::ColsAtCompileTime == 1 || HasDirectAccess) ? LinearAccessBit : 0,
289  FlagsRowMajorBit = (traits<XprType>::ReshapedStorageOrder==int(RowMajor)) ? RowMajorBit : 0,
290  FlagsDirectAccessBit = HasDirectAccess ? DirectAccessBit : 0,
291  Flags0 = evaluator<ArgType>::Flags & (HereditaryBits & ~RowMajorBit),
292  Flags = Flags0 | FlagsLinearAccessBit | FlagsRowMajorBit | FlagsDirectAccessBit,
293 
294  PacketAlignment = unpacket_traits<PacketScalar>::alignment,
295  Alignment = evaluator<ArgType>::Alignment
296  };
297  typedef reshaped_evaluator<ArgType, Rows, Cols, Order, HasDirectAccess> reshaped_evaluator_type;
298  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : reshaped_evaluator_type(xpr)
299  {
300  EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
301  }
302 };
303 
304 template<typename ArgType, int Rows, int Cols, int Order>
305 struct reshaped_evaluator<ArgType, Rows, Cols, Order, /* HasDirectAccess */ false>
306  : evaluator_base<Reshaped<ArgType, Rows, Cols, Order> >
307 {
308  typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
309 
310  enum {
311  CoeffReadCost = evaluator<ArgType>::CoeffReadCost /* TODO + cost of index computations */,
312 
313  Flags = (evaluator<ArgType>::Flags & (HereditaryBits /*| LinearAccessBit | DirectAccessBit*/)),
314 
315  Alignment = 0
316  };
317 
318  EIGEN_DEVICE_FUNC explicit reshaped_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_xpr(xpr)
319  {
320  EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
321  }
322 
323  typedef typename XprType::Scalar Scalar;
324  typedef typename XprType::CoeffReturnType CoeffReturnType;
325 
326  typedef std::pair<Index, Index> RowCol;
327 
328  EIGEN_DEVICE_FUNC inline RowCol index_remap(Index rowId, Index colId) const
329  {
330  if(Order==ColMajor)
331  {
332  const Index nth_elem_idx = colId * m_xpr.rows() + rowId;
333  return RowCol(nth_elem_idx % m_xpr.nestedExpression().rows(),
334  nth_elem_idx / m_xpr.nestedExpression().rows());
335  }
336  else
337  {
338  const Index nth_elem_idx = colId + rowId * m_xpr.cols();
339  return RowCol(nth_elem_idx / m_xpr.nestedExpression().cols(),
340  nth_elem_idx % m_xpr.nestedExpression().cols());
341  }
342  }
343 
345  inline Scalar& coeffRef(Index rowId, Index colId)
346  {
348  const RowCol row_col = index_remap(rowId, colId);
349  return m_argImpl.coeffRef(row_col.first, row_col.second);
350  }
351 
353  inline const Scalar& coeffRef(Index rowId, Index colId) const
354  {
355  const RowCol row_col = index_remap(rowId, colId);
356  return m_argImpl.coeffRef(row_col.first, row_col.second);
357  }
358 
360  EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const
361  {
362  const RowCol row_col = index_remap(rowId, colId);
363  return m_argImpl.coeff(row_col.first, row_col.second);
364  }
365 
367  inline Scalar& coeffRef(Index index)
368  {
370  const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
371  Rows == 1 ? index : 0);
372  return m_argImpl.coeffRef(row_col.first, row_col.second);
373 
374  }
375 
377  inline const Scalar& coeffRef(Index index) const
378  {
379  const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
380  Rows == 1 ? index : 0);
381  return m_argImpl.coeffRef(row_col.first, row_col.second);
382  }
383 
385  inline const CoeffReturnType coeff(Index index) const
386  {
387  const RowCol row_col = index_remap(Rows == 1 ? 0 : index,
388  Rows == 1 ? index : 0);
389  return m_argImpl.coeff(row_col.first, row_col.second);
390  }
391 #if 0
393  template<int LoadMode>
394  inline PacketScalar packet(Index rowId, Index colId) const
395  {
396  const RowCol row_col = index_remap(rowId, colId);
397  return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second);
398 
399  }
400 
401  template<int LoadMode>
403  inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
404  {
405  const RowCol row_col = index_remap(rowId, colId);
406  m_argImpl.const_cast_derived().template writePacket<Unaligned>
407  (row_col.first, row_col.second, val);
408  }
409 
410  template<int LoadMode>
412  inline PacketScalar packet(Index index) const
413  {
414  const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index,
415  RowsAtCompileTime == 1 ? index : 0);
416  return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second);
417  }
418 
419  template<int LoadMode>
421  inline void writePacket(Index index, const PacketScalar& val)
422  {
423  const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index,
424  RowsAtCompileTime == 1 ? index : 0);
425  return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second, val);
426  }
427 #endif
428 protected:
429 
430  evaluator<ArgType> m_argImpl;
431  const XprType& m_xpr;
432 
433 };
434 
435 template<typename ArgType, int Rows, int Cols, int Order>
436 struct reshaped_evaluator<ArgType, Rows, Cols, Order, /* HasDirectAccess */ true>
437 : mapbase_evaluator<Reshaped<ArgType, Rows, Cols, Order>,
438  typename Reshaped<ArgType, Rows, Cols, Order>::PlainObject>
439 {
440  typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
441  typedef typename XprType::Scalar Scalar;
442 
443  EIGEN_DEVICE_FUNC explicit reshaped_evaluator(const XprType& xpr)
444  : mapbase_evaluator<XprType, typename XprType::PlainObject>(xpr)
445  {
446  // 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
447  eigen_assert(((std::uintptr_t(xpr.data()) % plain_enum_max(1, evaluator<XprType>::Alignment)) == 0) && "data is not aligned");
448  }
449 };
450 
451 } // end namespace internal
452 
453 } // end namespace Eigen
454 
455 #endif // EIGEN_RESHAPED_H
#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived)
Definition: Macros.h:1149
#define EIGEN_CONSTEXPR
Definition: Macros.h:747
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:883
#define EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
Definition: Macros.h:1168
#define eigen_assert(x)
Definition: Macros.h:902
#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived)
Definition: Macros.h:1122
int data[]
#define EIGEN_STATIC_ASSERT_LVALUE(Derived)
Definition: StaticAssert.h:96
#define EIGEN_STATIC_ASSERT(X, MSG)
Definition: StaticAssert.h:26
#define EIGEN_INTERNAL_CHECK_COST_VALUE(C)
Definition: StaticAssert.h:112
ReshapedImpl(XprType &xpr, Index reshapeRows, Index reshapeCols)
Definition: Reshaped.h:141
internal::ReshapedImpl_dense< XprType, Rows, Cols, Order, internal::traits< Reshaped< XprType, Rows, Cols, Order > >::HasDirectAccess > Impl
Definition: Reshaped.h:136
Expression of a fixed-size or dynamic-size reshape.
Definition: Reshaped.h:99
Reshaped(XprType &xpr, Index reshapeRows, Index reshapeCols)
Definition: Reshaped.h:120
ReshapedImpl< XprType, Rows, Cols, Order, typename internal::traits< XprType >::StorageKind > Impl
Definition: Reshaped.h:100
Reshaped(XprType &xpr)
Definition: Reshaped.h:110
@ ColMajor
Definition: Constants.h:321
@ RowMajor
Definition: Constants.h:323
const unsigned int PacketAccessBit
Definition: Constants.h:96
const unsigned int LinearAccessBit
Definition: Constants.h:132
const unsigned int DirectAccessBit
Definition: Constants.h:157
const unsigned int LvalueBit
Definition: Constants.h:146
const unsigned int RowMajorBit
Definition: Constants.h:68
constexpr int plain_enum_max(A a, B b)
Definition: Meta.h:524
: InteropHeaders
Definition: Core:139
const unsigned int HereditaryBits
Definition: Constants.h:197
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
const int Dynamic
Definition: Constants.h:24