Eigen  3.4.90 (git rev 5a9f66fb35d03a4da9ef8976e67a61b30aa16dcf)
 
Loading...
Searching...
No Matches
Reshaped.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008-2017 Gael Guennebaud <[email protected]>
5// Copyright (C) 2014 yoco <[email protected]>
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// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18
48namespace internal {
49
50template <typename XprType, int Rows, int Cols, int Order>
51struct traits<Reshaped<XprType, Rows, Cols, Order> > : traits<XprType> {
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 ? int(inner_stride_at_compile_time<XprType>::ret) : Dynamic,
69 OuterStrideAtCompileTime = Dynamic,
70
71 HasDirectAccess = internal::has_direct_access<XprType>::ret && (Order == int(XpxStorageOrder)) &&
72 ((evaluator<XprType>::Flags & LinearAccessBit) == LinearAccessBit),
73
74 MaskPacketAccessBit =
75 (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0) && (InnerStrideAtCompileTime == 1)
77 : 0,
78 // MaskAlignedBit = ((OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16)
79 // == 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
90template <typename XprType, int Rows, int Cols, int Order, bool HasDirectAccess>
91class ReshapedImpl_dense;
92
93} // end namespace internal
94
95template <typename XprType, int Rows, int Cols, int Order, typename StorageKind>
96class ReshapedImpl;
97
98template <typename XprType, int Rows, int Cols, int Order>
99class Reshaped : public ReshapedImpl<XprType, Rows, Cols, Order, typename internal::traits<XprType>::StorageKind> {
100 typedef ReshapedImpl<XprType, Rows, Cols, Order, typename internal::traits<XprType>::StorageKind> Impl;
101
102 public:
103 // typedef typename Impl::Base Base;
104 typedef Impl Base;
105 EIGEN_GENERIC_PUBLIC_INTERFACE(Reshaped)
106 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reshaped)
107
108
110 EIGEN_DEVICE_FUNC inline Reshaped(XprType& xpr) : Impl(xpr) {
111 EIGEN_STATIC_ASSERT(RowsAtCompileTime != Dynamic && ColsAtCompileTime != Dynamic,
112 THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
113 eigen_assert(Rows * Cols == xpr.rows() * xpr.cols());
114 }
115
118 EIGEN_DEVICE_FUNC inline Reshaped(XprType& xpr, Index reshapeRows, Index reshapeCols)
119 : Impl(xpr, reshapeRows, reshapeCols) {
120 eigen_assert((RowsAtCompileTime == Dynamic || RowsAtCompileTime == reshapeRows) &&
121 (ColsAtCompileTime == Dynamic || ColsAtCompileTime == reshapeCols));
122 eigen_assert(reshapeRows * reshapeCols == xpr.rows() * xpr.cols());
123 }
124};
125
126// The generic default implementation for dense reshape simply forward to the internal::ReshapedImpl_dense
127// that must be specialized for direct and non-direct access...
128template <typename XprType, int Rows, int Cols, int Order>
129class ReshapedImpl<XprType, Rows, Cols, Order, Dense>
130 : public internal::ReshapedImpl_dense<XprType, Rows, Cols, Order,
131 internal::traits<Reshaped<XprType, Rows, Cols, Order> >::HasDirectAccess> {
132 typedef internal::ReshapedImpl_dense<XprType, Rows, Cols, Order,
133 internal::traits<Reshaped<XprType, Rows, Cols, Order> >::HasDirectAccess>
134 Impl;
135
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
144namespace internal {
145
147template <typename XprType, int Rows, int Cols, int Order>
148class ReshapedImpl_dense<XprType, Rows, Cols, Order, false>
149 : public internal::dense_xpr_base<Reshaped<XprType, Rows, Cols, Order> >::type {
150 typedef Reshaped<XprType, Rows, Cols, Order> ReshapedType;
151
152 public:
153 typedef typename internal::dense_xpr_base<ReshapedType>::type Base;
154 EIGEN_DENSE_PUBLIC_INTERFACE(ReshapedType)
155 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl_dense)
156
157 typedef typename internal::ref_selector<XprType>::non_const_type MatrixTypeNested;
158 typedef internal::remove_all_t<XprType> NestedExpression;
159
160 class InnerIterator;
161
164 EIGEN_DEVICE_FUNC inline ReshapedImpl_dense(XprType& xpr) : m_xpr(xpr), m_rows(Rows), m_cols(Cols) {}
165
168 EIGEN_DEVICE_FUNC inline ReshapedImpl_dense(XprType& xpr, Index nRows, Index nCols)
169 : m_xpr(xpr), m_rows(nRows), m_cols(nCols) {}
170
171 EIGEN_DEVICE_FUNC Index rows() const { return m_rows; }
172 EIGEN_DEVICE_FUNC Index cols() const { return m_cols; }
173
174#ifdef EIGEN_PARSED_BY_DOXYGEN
176 EIGEN_DEVICE_FUNC inline const Scalar* data() const;
177 EIGEN_DEVICE_FUNC inline Index innerStride() const;
178 EIGEN_DEVICE_FUNC inline Index outerStride() const;
179#endif
180
182 EIGEN_DEVICE_FUNC const internal::remove_all_t<XprType>& nestedExpression() const { return m_xpr; }
183
185 EIGEN_DEVICE_FUNC std::remove_reference_t<XprType>& nestedExpression() { return m_xpr; }
186
187 protected:
188 MatrixTypeNested m_xpr;
189 const internal::variable_if_dynamic<Index, Rows> m_rows;
190 const internal::variable_if_dynamic<Index, Cols> m_cols;
191};
192
194template <typename XprType, int Rows, int Cols, int Order>
195class ReshapedImpl_dense<XprType, Rows, Cols, Order, true> : public MapBase<Reshaped<XprType, Rows, Cols, Order> > {
196 typedef Reshaped<XprType, Rows, Cols, Order> ReshapedType;
197 typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
198
199 public:
200 typedef MapBase<ReshapedType> Base;
201 EIGEN_DENSE_PUBLIC_INTERFACE(ReshapedType)
202 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ReshapedImpl_dense)
203
204
206 EIGEN_DEVICE_FUNC inline ReshapedImpl_dense(XprType& xpr) : Base(xpr.data()), m_xpr(xpr) {}
207
210 EIGEN_DEVICE_FUNC inline ReshapedImpl_dense(XprType& xpr, Index nRows, Index nCols)
211 : Base(xpr.data(), nRows, nCols), m_xpr(xpr) {}
212
213 EIGEN_DEVICE_FUNC const internal::remove_all_t<XprTypeNested>& nestedExpression() const { return m_xpr; }
214
215 EIGEN_DEVICE_FUNC XprType& nestedExpression() { return m_xpr; }
216
218 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index innerStride() const { return m_xpr.innerStride(); }
219
221 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index outerStride() const {
222 return (((Flags & RowMajorBit) == RowMajorBit) ? this->cols() : this->rows()) * m_xpr.innerStride();
223 }
224
225 protected:
226 XprTypeNested m_xpr;
227};
228
229// Evaluators
230template <typename ArgType, int Rows, int Cols, int Order, bool HasDirectAccess>
231struct reshaped_evaluator;
232
233template <typename ArgType, int Rows, int Cols, int Order>
234struct evaluator<Reshaped<ArgType, Rows, Cols, Order> >
235 : reshaped_evaluator<ArgType, Rows, Cols, Order, traits<Reshaped<ArgType, Rows, Cols, Order> >::HasDirectAccess> {
236 typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
237 typedef typename XprType::Scalar Scalar;
238 // TODO: should check for smaller packet types
239 typedef typename packet_traits<Scalar>::type PacketScalar;
240
241 enum {
242 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
243 HasDirectAccess = traits<XprType>::HasDirectAccess,
244
245 // RowsAtCompileTime = traits<XprType>::RowsAtCompileTime,
246 // ColsAtCompileTime = traits<XprType>::ColsAtCompileTime,
247 // MaxRowsAtCompileTime = traits<XprType>::MaxRowsAtCompileTime,
248 // MaxColsAtCompileTime = traits<XprType>::MaxColsAtCompileTime,
249 //
250 // InnerStrideAtCompileTime = traits<XprType>::HasSameStorageOrderAsXprType
251 // ? int(inner_stride_at_compile_time<ArgType>::ret)
252 // : Dynamic,
253 // OuterStrideAtCompileTime = Dynamic,
254
255 FlagsLinearAccessBit =
256 (traits<XprType>::RowsAtCompileTime == 1 || traits<XprType>::ColsAtCompileTime == 1 || HasDirectAccess)
257 ? LinearAccessBit
258 : 0,
259 FlagsRowMajorBit = (traits<XprType>::ReshapedStorageOrder == int(RowMajor)) ? RowMajorBit : 0,
260 FlagsDirectAccessBit = HasDirectAccess ? DirectAccessBit : 0,
261 Flags0 = evaluator<ArgType>::Flags & (HereditaryBits & ~RowMajorBit),
262 Flags = Flags0 | FlagsLinearAccessBit | FlagsRowMajorBit | FlagsDirectAccessBit,
263
264 PacketAlignment = unpacket_traits<PacketScalar>::alignment,
265 Alignment = evaluator<ArgType>::Alignment
266 };
267 typedef reshaped_evaluator<ArgType, Rows, Cols, Order, HasDirectAccess> reshaped_evaluator_type;
268 EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : reshaped_evaluator_type(xpr) {
269 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
270 }
271};
272
273template <typename ArgType, int Rows, int Cols, int Order>
274struct reshaped_evaluator<ArgType, Rows, Cols, Order, /* HasDirectAccess */ false>
275 : evaluator_base<Reshaped<ArgType, Rows, Cols, Order> > {
276 typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
277
278 enum {
279 CoeffReadCost = evaluator<ArgType>::CoeffReadCost /* TODO + cost of index computations */,
280
281 Flags = (evaluator<ArgType>::Flags & (HereditaryBits /*| LinearAccessBit | DirectAccessBit*/)),
282
283 Alignment = 0
284 };
285
286 EIGEN_DEVICE_FUNC explicit reshaped_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_xpr(xpr) {
287 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
288 }
289
290 typedef typename XprType::Scalar Scalar;
291 typedef typename XprType::CoeffReturnType CoeffReturnType;
292
293 typedef std::pair<Index, Index> RowCol;
294
295 EIGEN_DEVICE_FUNC inline RowCol index_remap(Index rowId, Index colId) const {
296 if (Order == ColMajor) {
297 const Index nth_elem_idx = colId * m_xpr.rows() + rowId;
298 return RowCol(nth_elem_idx % m_xpr.nestedExpression().rows(), nth_elem_idx / m_xpr.nestedExpression().rows());
299 } else {
300 const Index nth_elem_idx = colId + rowId * m_xpr.cols();
301 return RowCol(nth_elem_idx / m_xpr.nestedExpression().cols(), nth_elem_idx % m_xpr.nestedExpression().cols());
302 }
303 }
304
305 EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index rowId, Index colId) {
306 EIGEN_STATIC_ASSERT_LVALUE(XprType)
307 const RowCol row_col = index_remap(rowId, colId);
308 return m_argImpl.coeffRef(row_col.first, row_col.second);
309 }
310
311 EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index rowId, Index colId) const {
312 const RowCol row_col = index_remap(rowId, colId);
313 return m_argImpl.coeffRef(row_col.first, row_col.second);
314 }
315
316 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const {
317 const RowCol row_col = index_remap(rowId, colId);
318 return m_argImpl.coeff(row_col.first, row_col.second);
319 }
320
321 EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index index) {
322 EIGEN_STATIC_ASSERT_LVALUE(XprType)
323 const RowCol row_col = index_remap(Rows == 1 ? 0 : index, Rows == 1 ? index : 0);
324 return m_argImpl.coeffRef(row_col.first, row_col.second);
325 }
326
327 EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index index) const {
328 const RowCol row_col = index_remap(Rows == 1 ? 0 : index, Rows == 1 ? index : 0);
329 return m_argImpl.coeffRef(row_col.first, row_col.second);
330 }
331
332 EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index index) const {
333 const RowCol row_col = index_remap(Rows == 1 ? 0 : index, Rows == 1 ? index : 0);
334 return m_argImpl.coeff(row_col.first, row_col.second);
335 }
336#if 0
337 EIGEN_DEVICE_FUNC
338 template<int LoadMode>
339 inline PacketScalar packet(Index rowId, Index colId) const
340 {
341 const RowCol row_col = index_remap(rowId, colId);
342 return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second);
343
344 }
345
346 template<int LoadMode>
347 EIGEN_DEVICE_FUNC
348 inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
349 {
350 const RowCol row_col = index_remap(rowId, colId);
351 m_argImpl.const_cast_derived().template writePacket<Unaligned>
352 (row_col.first, row_col.second, val);
353 }
354
355 template<int LoadMode>
356 EIGEN_DEVICE_FUNC
357 inline PacketScalar packet(Index index) const
358 {
359 const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index,
360 RowsAtCompileTime == 1 ? index : 0);
361 return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second);
362 }
363
364 template<int LoadMode>
365 EIGEN_DEVICE_FUNC
366 inline void writePacket(Index index, const PacketScalar& val)
367 {
368 const RowCol row_col = index_remap(RowsAtCompileTime == 1 ? 0 : index,
369 RowsAtCompileTime == 1 ? index : 0);
370 return m_argImpl.template packet<Unaligned>(row_col.first, row_col.second, val);
371 }
372#endif
373 protected:
374 evaluator<ArgType> m_argImpl;
375 const XprType& m_xpr;
376};
377
378template <typename ArgType, int Rows, int Cols, int Order>
379struct reshaped_evaluator<ArgType, Rows, Cols, Order, /* HasDirectAccess */ true>
380 : mapbase_evaluator<Reshaped<ArgType, Rows, Cols, Order>,
381 typename Reshaped<ArgType, Rows, Cols, Order>::PlainObject> {
382 typedef Reshaped<ArgType, Rows, Cols, Order> XprType;
383 typedef typename XprType::Scalar Scalar;
384
385 EIGEN_DEVICE_FUNC explicit reshaped_evaluator(const XprType& xpr)
386 : mapbase_evaluator<XprType, typename XprType::PlainObject>(xpr) {
387 // TODO: for the 3.4 release, this should be turned to an internal assertion, but let's keep it as is for the beta
388 // lifetime
389 eigen_assert(((std::uintptr_t(xpr.data()) % plain_enum_max(1, evaluator<XprType>::Alignment)) == 0) &&
390 "data is not aligned");
391 }
392};
393
394} // end namespace internal
395
396} // end namespace Eigen
397
398#endif // EIGEN_RESHAPED_H
Expression of a fixed-size or dynamic-size reshape.
Definition Reshaped.h:99
Reshaped(XprType &xpr, Index reshapeRows, Index reshapeCols)
Definition Reshaped.h:118
@ ColMajor
Definition Constants.h:318
@ RowMajor
Definition Constants.h:320
const unsigned int PacketAccessBit
Definition Constants.h:97
const unsigned int LinearAccessBit
Definition Constants.h:133
const unsigned int DirectAccessBit
Definition Constants.h:159
const unsigned int LvalueBit
Definition Constants.h:148
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition Core:137
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:83
const int Dynamic
Definition Constants.h:25