File indexing completed on 2025-01-18 09:56:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef EIGEN_REVERSE_H
0013 #define EIGEN_REVERSE_H
0014
0015 namespace Eigen {
0016
0017 namespace internal {
0018
0019 template<typename MatrixType, int Direction>
0020 struct traits<Reverse<MatrixType, Direction> >
0021 : traits<MatrixType>
0022 {
0023 typedef typename MatrixType::Scalar Scalar;
0024 typedef typename traits<MatrixType>::StorageKind StorageKind;
0025 typedef typename traits<MatrixType>::XprKind XprKind;
0026 typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
0027 typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
0028 enum {
0029 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
0030 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
0031 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
0032 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
0033 Flags = _MatrixTypeNested::Flags & (RowMajorBit | LvalueBit)
0034 };
0035 };
0036
0037 template<typename PacketType, bool ReversePacket> struct reverse_packet_cond
0038 {
0039 static inline PacketType run(const PacketType& x) { return preverse(x); }
0040 };
0041
0042 template<typename PacketType> struct reverse_packet_cond<PacketType,false>
0043 {
0044 static inline PacketType run(const PacketType& x) { return x; }
0045 };
0046
0047 }
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 template<typename MatrixType, int Direction> class Reverse
0064 : public internal::dense_xpr_base< Reverse<MatrixType, Direction> >::type
0065 {
0066 public:
0067
0068 typedef typename internal::dense_xpr_base<Reverse>::type Base;
0069 EIGEN_DENSE_PUBLIC_INTERFACE(Reverse)
0070 typedef typename internal::remove_all<MatrixType>::type NestedExpression;
0071 using Base::IsRowMajor;
0072
0073 protected:
0074 enum {
0075 PacketSize = internal::packet_traits<Scalar>::size,
0076 IsColMajor = !IsRowMajor,
0077 ReverseRow = (Direction == Vertical) || (Direction == BothDirections),
0078 ReverseCol = (Direction == Horizontal) || (Direction == BothDirections),
0079 OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1,
0080 OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1,
0081 ReversePacket = (Direction == BothDirections)
0082 || ((Direction == Vertical) && IsColMajor)
0083 || ((Direction == Horizontal) && IsRowMajor)
0084 };
0085 typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet;
0086 public:
0087
0088 EIGEN_DEVICE_FUNC explicit inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { }
0089
0090 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
0091
0092 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0093 inline Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
0094 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0095 inline Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
0096
0097 EIGEN_DEVICE_FUNC inline Index innerStride() const
0098 {
0099 return -m_matrix.innerStride();
0100 }
0101
0102 EIGEN_DEVICE_FUNC const typename internal::remove_all<typename MatrixType::Nested>::type&
0103 nestedExpression() const
0104 {
0105 return m_matrix;
0106 }
0107
0108 protected:
0109 typename MatrixType::Nested m_matrix;
0110 };
0111
0112
0113
0114
0115
0116
0117
0118 template<typename Derived>
0119 EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::ReverseReturnType
0120 DenseBase<Derived>::reverse()
0121 {
0122 return ReverseReturnType(derived());
0123 }
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140 template<typename Derived>
0141 EIGEN_DEVICE_FUNC inline void DenseBase<Derived>::reverseInPlace()
0142 {
0143 if(cols()>rows())
0144 {
0145 Index half = cols()/2;
0146 leftCols(half).swap(rightCols(half).reverse());
0147 if((cols()%2)==1)
0148 {
0149 Index half2 = rows()/2;
0150 col(half).head(half2).swap(col(half).tail(half2).reverse());
0151 }
0152 }
0153 else
0154 {
0155 Index half = rows()/2;
0156 topRows(half).swap(bottomRows(half).reverse());
0157 if((rows()%2)==1)
0158 {
0159 Index half2 = cols()/2;
0160 row(half).head(half2).swap(row(half).tail(half2).reverse());
0161 }
0162 }
0163 }
0164
0165 namespace internal {
0166
0167 template<int Direction>
0168 struct vectorwise_reverse_inplace_impl;
0169
0170 template<>
0171 struct vectorwise_reverse_inplace_impl<Vertical>
0172 {
0173 template<typename ExpressionType>
0174 static void run(ExpressionType &xpr)
0175 {
0176 const int HalfAtCompileTime = ExpressionType::RowsAtCompileTime==Dynamic?Dynamic:ExpressionType::RowsAtCompileTime/2;
0177 Index half = xpr.rows()/2;
0178 xpr.topRows(fix<HalfAtCompileTime>(half))
0179 .swap(xpr.bottomRows(fix<HalfAtCompileTime>(half)).colwise().reverse());
0180 }
0181 };
0182
0183 template<>
0184 struct vectorwise_reverse_inplace_impl<Horizontal>
0185 {
0186 template<typename ExpressionType>
0187 static void run(ExpressionType &xpr)
0188 {
0189 const int HalfAtCompileTime = ExpressionType::ColsAtCompileTime==Dynamic?Dynamic:ExpressionType::ColsAtCompileTime/2;
0190 Index half = xpr.cols()/2;
0191 xpr.leftCols(fix<HalfAtCompileTime>(half))
0192 .swap(xpr.rightCols(fix<HalfAtCompileTime>(half)).rowwise().reverse());
0193 }
0194 };
0195
0196 }
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209 template<typename ExpressionType, int Direction>
0210 EIGEN_DEVICE_FUNC void VectorwiseOp<ExpressionType,Direction>::reverseInPlace()
0211 {
0212 internal::vectorwise_reverse_inplace_impl<Direction>::run(m_matrix);
0213 }
0214
0215 }
0216
0217 #endif