$darkmode
Eigen  5.0.1-dev
Reverse.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
5 // Copyright (C) 2009 Ricard Marxer <email@ricardmarxer.com>
6 // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
7 //
8 // This Source Code Form is subject to the terms of the Mozilla
9 // Public License v. 2.0. If a copy of the MPL was not distributed
10 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 
12 #ifndef EIGEN_REVERSE_H
13 #define EIGEN_REVERSE_H
14 
15 // IWYU pragma: private
16 #include "./InternalHeaderCheck.h"
17 
18 namespace Eigen {
19 
20 namespace internal {
21 
22 template <typename MatrixType, int Direction>
23 struct traits<Reverse<MatrixType, Direction> > : traits<MatrixType> {
24  typedef typename MatrixType::Scalar Scalar;
25  typedef typename traits<MatrixType>::StorageKind StorageKind;
26  typedef typename traits<MatrixType>::XprKind XprKind;
27  typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
28  typedef std::remove_reference_t<MatrixTypeNested> MatrixTypeNested_;
29  enum {
30  RowsAtCompileTime = MatrixType::RowsAtCompileTime,
31  ColsAtCompileTime = MatrixType::ColsAtCompileTime,
32  MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
33  MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
34  Flags = MatrixTypeNested_::Flags & (RowMajorBit | LvalueBit)
35  };
36 };
37 
38 template <typename PacketType, bool ReversePacket>
39 struct reverse_packet_cond {
40  static inline PacketType run(const PacketType& x) { return preverse(x); }
41 };
42 
43 template <typename PacketType>
44 struct reverse_packet_cond<PacketType, false> {
45  static inline PacketType run(const PacketType& x) { return x; }
46 };
47 
48 } // end namespace internal
49 
64 template <typename MatrixType, int Direction>
65 class Reverse : public internal::dense_xpr_base<Reverse<MatrixType, Direction> >::type {
66  public:
67  typedef typename internal::dense_xpr_base<Reverse>::type Base;
68  EIGEN_DENSE_PUBLIC_INTERFACE(Reverse)
69  typedef internal::remove_all_t<MatrixType> NestedExpression;
70  using Base::IsRowMajor;
71 
72  protected:
73  enum {
74  PacketSize = internal::packet_traits<Scalar>::size,
75  IsColMajor = !IsRowMajor,
76  ReverseRow = (Direction == Vertical) || (Direction == BothDirections),
77  ReverseCol = (Direction == Horizontal) || (Direction == BothDirections),
78  OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1,
79  OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1,
80  ReversePacket = (Direction == BothDirections) || ((Direction == Vertical) && IsColMajor) ||
81  ((Direction == Horizontal) && IsRowMajor)
82  };
83  typedef internal::reverse_packet_cond<PacketScalar, ReversePacket> reverse_packet;
84 
85  public:
86  EIGEN_DEVICE_FUNC explicit inline Reverse(const MatrixType& matrix) : m_matrix(matrix) {}
87 
88  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
89 
90  EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return m_matrix.rows(); }
91  EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return m_matrix.cols(); }
92 
93  EIGEN_DEVICE_FUNC inline Index innerStride() const { return -m_matrix.innerStride(); }
94 
95  EIGEN_DEVICE_FUNC const internal::remove_all_t<typename MatrixType::Nested>& nestedExpression() const {
96  return m_matrix;
97  }
98 
99  protected:
100  typename MatrixType::Nested m_matrix;
101 };
102 
109 template <typename Derived>
111  return ReverseReturnType(derived());
112 }
113 
114 // reverse const overload moved DenseBase.h due to a CUDA compiler bug
115 
128 template <typename Derived>
129 EIGEN_DEVICE_FUNC inline void DenseBase<Derived>::reverseInPlace() {
130  constexpr int HalfRowsAtCompileTime = RowsAtCompileTime == Dynamic ? Dynamic : RowsAtCompileTime / 2;
131  constexpr int HalfColsAtCompileTime = ColsAtCompileTime == Dynamic ? Dynamic : ColsAtCompileTime / 2;
132  if (cols() > rows()) {
133  Index half = cols() / 2;
134  this->template leftCols<HalfColsAtCompileTime>(half).swap(
135  this->template rightCols<HalfColsAtCompileTime>(half).reverse());
136  if ((cols() % 2) == 1) {
137  Index half2 = rows() / 2;
138  col(half).template head<HalfRowsAtCompileTime>(half2).swap(
139  col(half).template tail<HalfRowsAtCompileTime>(half2).reverse());
140  }
141  } else {
142  Index half = rows() / 2;
143  this->template topRows<HalfRowsAtCompileTime>(half).swap(
144  this->template bottomRows<HalfRowsAtCompileTime>(half).reverse());
145  if ((rows() % 2) == 1) {
146  Index half2 = cols() / 2;
147  row(half).template head<HalfColsAtCompileTime>(half2).swap(
148  row(half).template tail<HalfColsAtCompileTime>(half2).reverse());
149  }
150  }
151 }
152 
153 namespace internal {
154 
155 template <int Direction>
156 struct vectorwise_reverse_inplace_impl;
157 
158 template <>
159 struct vectorwise_reverse_inplace_impl<Vertical> {
160  template <typename ExpressionType>
161  static void run(ExpressionType& xpr) {
162  constexpr Index HalfAtCompileTime =
163  ExpressionType::RowsAtCompileTime == Dynamic ? Dynamic : ExpressionType::RowsAtCompileTime / 2;
164  Index half = xpr.rows() / 2;
165  xpr.template topRows<HalfAtCompileTime>(half).swap(
166  xpr.template bottomRows<HalfAtCompileTime>(half).colwise().reverse());
167  }
168 };
169 
170 template <>
171 struct vectorwise_reverse_inplace_impl<Horizontal> {
172  template <typename ExpressionType>
173  static void run(ExpressionType& xpr) {
174  constexpr Index HalfAtCompileTime =
175  ExpressionType::ColsAtCompileTime == Dynamic ? Dynamic : ExpressionType::ColsAtCompileTime / 2;
176  Index half = xpr.cols() / 2;
177  xpr.template leftCols<HalfAtCompileTime>(half).swap(
178  xpr.template rightCols<HalfAtCompileTime>(half).rowwise().reverse());
179  }
180 };
181 
182 } // end namespace internal
183 
195 template <typename ExpressionType, int Direction>
197  internal::vectorwise_reverse_inplace_impl<Direction>::run(m_matrix);
198 }
199 
200 } // end namespace Eigen
201 
202 #endif // EIGEN_REVERSE_H
Definition: Constants.h:266
void reverseInPlace()
Definition: Reverse.h:196
const unsigned int LvalueBit
Definition: Constants.h:148
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:43
const unsigned int RowMajorBit
Definition: Constants.h:70
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
std::enable_if_t< std::is_base_of< DenseBase< std::decay_t< DerivedA > >, std::decay_t< DerivedA > >::value &&std::is_base_of< DenseBase< std::decay_t< DerivedB > >, std::decay_t< DerivedB > >::value, void > swap(DerivedA &&a, DerivedB &&b)
Definition: DenseBase.h:667
ReverseReturnType reverse()
Definition: Reverse.h:110
Definition: Constants.h:269
Definition: Constants.h:272
void reverseInPlace()
Definition: Reverse.h:129
const int Dynamic
Definition: Constants.h:25
Expression of the reverse of a vector or matrix.
Definition: Reverse.h:65