Eigen  5.0.1
 
Loading...
Searching...
No Matches
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// SPDX-License-Identifier: MPL-2.0
12
13#ifndef EIGEN_REVERSE_H
14#define EIGEN_REVERSE_H
15
16// IWYU pragma: private
17#include "./InternalHeaderCheck.h"
18
19namespace Eigen {
20
21namespace internal {
22
23template <typename MatrixType, int Direction>
24struct traits<Reverse<MatrixType, Direction> > : traits<MatrixType> {
25 using Scalar = typename MatrixType::Scalar;
26 using StorageKind = typename traits<MatrixType>::StorageKind;
27 using XprKind = typename traits<MatrixType>::XprKind;
28 using MatrixTypeNested = typename ref_selector<MatrixType>::type;
29 using MatrixTypeNested_ = std::remove_reference_t<MatrixTypeNested>;
30 enum {
31 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
32 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
33 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
34 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
35 Flags = MatrixTypeNested_::Flags & (RowMajorBit | LvalueBit)
36 };
37};
38
39template <typename PacketType, bool ReversePacket>
40struct reverse_packet_cond {
41 static inline PacketType run(const PacketType& x) { return preverse(x); }
42};
43
44template <typename PacketType>
45struct reverse_packet_cond<PacketType, false> {
46 static inline PacketType run(const PacketType& x) { return x; }
47};
48
49} // end namespace internal
50
65template <typename MatrixType, int Direction>
66class Reverse : public internal::dense_xpr_base<Reverse<MatrixType, Direction> >::type {
67 public:
68 using Base = typename internal::dense_xpr_base<Reverse>::type;
69 EIGEN_DENSE_PUBLIC_INTERFACE(Reverse)
70 using NestedExpression = internal::remove_all_t<MatrixType>;
71 using Base::IsRowMajor;
72
73 protected:
74 enum {
75 PacketSize = internal::packet_traits<Scalar>::size,
76 IsColMajor = !IsRowMajor,
77 ReverseRow = (Direction == Vertical) || (Direction == BothDirections),
78 ReverseCol = (Direction == Horizontal) || (Direction == BothDirections),
79 OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1,
80 OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1,
81 ReversePacket = (Direction == BothDirections) || ((Direction == Vertical) && IsColMajor) ||
82 ((Direction == Horizontal) && IsRowMajor)
83 };
84 using reverse_packet = internal::reverse_packet_cond<PacketScalar, ReversePacket>;
85
86 public:
87 EIGEN_DEVICE_FUNC constexpr explicit inline Reverse(const MatrixType& matrix) : m_matrix(matrix) {}
88
89 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
90
91 EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return m_matrix.rows(); }
92 EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return m_matrix.cols(); }
93
94 EIGEN_DEVICE_FUNC inline Index innerStride() const { return -m_matrix.innerStride(); }
95
96 EIGEN_DEVICE_FUNC constexpr const internal::remove_all_t<typename MatrixType::Nested>& nestedExpression() const {
97 return m_matrix;
98 }
99
100 protected:
101 typename MatrixType::Nested m_matrix;
102};
103
110template <typename Derived>
111EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::ReverseReturnType DenseBase<Derived>::reverse() {
112 return ReverseReturnType(derived());
113}
114
115// reverse const overload moved to DenseBase.h due to a CUDA compiler bug
116
129template <typename Derived>
130EIGEN_DEVICE_FUNC inline void DenseBase<Derived>::reverseInPlace() {
131 constexpr int HalfRowsAtCompileTime = RowsAtCompileTime == Dynamic ? Dynamic : RowsAtCompileTime / 2;
132 constexpr int HalfColsAtCompileTime = ColsAtCompileTime == Dynamic ? Dynamic : ColsAtCompileTime / 2;
133 if (cols() > rows()) {
134 Index half = cols() / 2;
135 this->template leftCols<HalfColsAtCompileTime>(half).swap(
136 this->template rightCols<HalfColsAtCompileTime>(half).reverse());
137 if ((cols() % 2) == 1) {
138 Index half2 = rows() / 2;
139 col(half).template head<HalfRowsAtCompileTime>(half2).swap(
140 col(half).template tail<HalfRowsAtCompileTime>(half2).reverse());
141 }
142 } else {
143 Index half = rows() / 2;
144 this->template topRows<HalfRowsAtCompileTime>(half).swap(
145 this->template bottomRows<HalfRowsAtCompileTime>(half).reverse());
146 if ((rows() % 2) == 1) {
147 Index half2 = cols() / 2;
148 row(half).template head<HalfColsAtCompileTime>(half2).swap(
149 row(half).template tail<HalfColsAtCompileTime>(half2).reverse());
150 }
151 }
152}
153
154namespace internal {
155
156template <int Direction>
157struct vectorwise_reverse_inplace_impl;
158
159template <>
160struct vectorwise_reverse_inplace_impl<Vertical> {
161 template <typename ExpressionType>
162 static void run(ExpressionType& xpr) {
163 constexpr Index HalfAtCompileTime =
164 ExpressionType::RowsAtCompileTime == Dynamic ? Dynamic : ExpressionType::RowsAtCompileTime / 2;
165 Index half = xpr.rows() / 2;
166 xpr.template topRows<HalfAtCompileTime>(half).swap(
167 xpr.template bottomRows<HalfAtCompileTime>(half).colwise().reverse());
168 }
169};
170
171template <>
172struct vectorwise_reverse_inplace_impl<Horizontal> {
173 template <typename ExpressionType>
174 static void run(ExpressionType& xpr) {
175 constexpr Index HalfAtCompileTime =
176 ExpressionType::ColsAtCompileTime == Dynamic ? Dynamic : ExpressionType::ColsAtCompileTime / 2;
177 Index half = xpr.cols() / 2;
178 xpr.template leftCols<HalfAtCompileTime>(half).swap(
179 xpr.template rightCols<HalfAtCompileTime>(half).rowwise().reverse());
180 }
181};
182
183} // end namespace internal
184
196template <typename ExpressionType, int Direction>
198 internal::vectorwise_reverse_inplace_impl<Direction>::run(m_matrix);
199}
200
201} // end namespace Eigen
202
203#endif // EIGEN_REVERSE_H
constexpr FixedSegmentReturnType<... >::Type head(NType n)
Definition DenseBase.h:1174
constexpr ColXpr col(Index i)
Definition DenseBase.h:1081
ReverseReturnType reverse()
Definition Reverse.h:111
constexpr NRowsBlockXpr<... >::Type bottomRows(NRowsType n)
Definition DenseBase.h:670
constexpr NColsBlockXpr<... >::Type rightCols(NColsType n)
Definition DenseBase.h:875
constexpr FixedSegmentReturnType<... >::Type tail(NType n)
Definition DenseBase.h:1221
constexpr NColsBlockXpr<... >::Type leftCols(NColsType n)
Definition DenseBase.h:808
constexpr RowXpr row(Index i)
Definition DenseBase.h:1094
@ ColsAtCompileTime
Definition DenseBase.h:103
@ RowsAtCompileTime
Definition DenseBase.h:97
void reverseInPlace()
Definition Reverse.h:130
constexpr NRowsBlockXpr<... >::Type topRows(NRowsType n)
Definition DenseBase.h:603
void reverseInPlace()
Definition Reverse.h:197
@ BothDirections
Definition Constants.h:273
@ Horizontal
Definition Constants.h:270
@ Vertical
Definition Constants.h:267
constexpr unsigned int LvalueBit
Definition Constants.h:149
constexpr unsigned int RowMajorBit
Definition Constants.h:71