Eigen  3.2.10
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 namespace Eigen {
16 
31 namespace internal {
32 
33 template<typename MatrixType, int Direction>
34 struct traits<Reverse<MatrixType, Direction> >
35  : traits<MatrixType>
36 {
37  typedef typename MatrixType::Scalar Scalar;
38  typedef typename traits<MatrixType>::StorageKind StorageKind;
39  typedef typename traits<MatrixType>::XprKind XprKind;
40  typedef typename nested<MatrixType>::type MatrixTypeNested;
41  typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
42  enum {
43  RowsAtCompileTime = MatrixType::RowsAtCompileTime,
44  ColsAtCompileTime = MatrixType::ColsAtCompileTime,
45  MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
46  MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
47 
48  // let's enable LinearAccess only with vectorization because of the product overhead
49  LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) )
50  ? LinearAccessBit : 0,
51 
52  Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | LvalueBit | PacketAccessBit | LinearAccess),
53 
54  CoeffReadCost = _MatrixTypeNested::CoeffReadCost
55  };
56 };
57 
58 template<typename PacketScalar, bool ReversePacket> struct reverse_packet_cond
59 {
60  static inline PacketScalar run(const PacketScalar& x) { return preverse(x); }
61 };
62 
63 template<typename PacketScalar> struct reverse_packet_cond<PacketScalar,false>
64 {
65  static inline PacketScalar run(const PacketScalar& x) { return x; }
66 };
67 
68 } // end namespace internal
69 
70 template<typename MatrixType, int Direction> class Reverse
71  : public internal::dense_xpr_base< Reverse<MatrixType, Direction> >::type
72 {
73  public:
74 
75  typedef typename internal::dense_xpr_base<Reverse>::type Base;
76  EIGEN_DENSE_PUBLIC_INTERFACE(Reverse)
77  using Base::IsRowMajor;
78 
79  // The following two operators are provided to worarkound
80  // a MSVC 2013 issue. In theory, we could simply do:
81  // using Base::operator();
82  // to make const version of operator() visible.
83  // Otheriwse, they would be hidden by the non-const versions defined in this file
84 
85  inline CoeffReturnType operator()(Index row, Index col) const
86  {
87  eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
88  return coeff(row, col);
89  }
90 
91  inline CoeffReturnType operator()(Index index) const
92  {
93  eigen_assert(index >= 0 && index < m_matrix.size());
94  return coeff(index);
95  }
96 
97  protected:
98  enum {
99  PacketSize = internal::packet_traits<Scalar>::size,
100  IsColMajor = !IsRowMajor,
101  ReverseRow = (Direction == Vertical) || (Direction == BothDirections),
102  ReverseCol = (Direction == Horizontal) || (Direction == BothDirections),
103  OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1,
104  OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1,
105  ReversePacket = (Direction == BothDirections)
106  || ((Direction == Vertical) && IsColMajor)
107  || ((Direction == Horizontal) && IsRowMajor)
108  };
109  typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet;
110  public:
111 
112  inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { }
113 
114  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
115 
116  inline Index rows() const { return m_matrix.rows(); }
117  inline Index cols() const { return m_matrix.cols(); }
118 
119  inline Index innerStride() const
120  {
121  return -m_matrix.innerStride();
122  }
123 
124  inline Scalar& operator()(Index row, Index col)
125  {
126  eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
127  return coeffRef(row, col);
128  }
129 
130  inline Scalar& coeffRef(Index row, Index col)
131  {
132  return m_matrix.const_cast_derived().coeffRef(ReverseRow ? m_matrix.rows() - row - 1 : row,
133  ReverseCol ? m_matrix.cols() - col - 1 : col);
134  }
135 
136  inline CoeffReturnType coeff(Index row, Index col) const
137  {
138  return m_matrix.coeff(ReverseRow ? m_matrix.rows() - row - 1 : row,
139  ReverseCol ? m_matrix.cols() - col - 1 : col);
140  }
141 
142  inline CoeffReturnType coeff(Index index) const
143  {
144  return m_matrix.coeff(m_matrix.size() - index - 1);
145  }
146 
147  inline Scalar& coeffRef(Index index)
148  {
149  return m_matrix.const_cast_derived().coeffRef(m_matrix.size() - index - 1);
150  }
151 
152  inline Scalar& operator()(Index index)
153  {
154  eigen_assert(index >= 0 && index < m_matrix.size());
155  return coeffRef(index);
156  }
157 
158  template<int LoadMode>
159  inline const PacketScalar packet(Index row, Index col) const
160  {
161  return reverse_packet::run(m_matrix.template packet<LoadMode>(
162  ReverseRow ? m_matrix.rows() - row - OffsetRow : row,
163  ReverseCol ? m_matrix.cols() - col - OffsetCol : col));
164  }
165 
166  template<int LoadMode>
167  inline void writePacket(Index row, Index col, const PacketScalar& x)
168  {
169  m_matrix.const_cast_derived().template writePacket<LoadMode>(
170  ReverseRow ? m_matrix.rows() - row - OffsetRow : row,
171  ReverseCol ? m_matrix.cols() - col - OffsetCol : col,
172  reverse_packet::run(x));
173  }
174 
175  template<int LoadMode>
176  inline const PacketScalar packet(Index index) const
177  {
178  return internal::preverse(m_matrix.template packet<LoadMode>( m_matrix.size() - index - PacketSize ));
179  }
180 
181  template<int LoadMode>
182  inline void writePacket(Index index, const PacketScalar& x)
183  {
184  m_matrix.const_cast_derived().template writePacket<LoadMode>(m_matrix.size() - index - PacketSize, internal::preverse(x));
185  }
186 
187  const typename internal::remove_all<typename MatrixType::Nested>::type&
188  nestedExpression() const
189  {
190  return m_matrix;
191  }
192 
193  protected:
194  typename MatrixType::Nested m_matrix;
195 };
196 
203 template<typename Derived>
206 {
207  return derived();
208 }
209 
211 template<typename Derived>
212 inline const typename DenseBase<Derived>::ConstReverseReturnType
214 {
215  return derived();
216 }
217 
230 template<typename Derived>
232 {
233  derived() = derived().reverse().eval();
234 }
235 
236 } // end namespace Eigen
237 
238 #endif // EIGEN_REVERSE_H
ReverseReturnType reverse()
Definition: Reverse.h:205
Definition: LDLT.h:16
const unsigned int PacketAccessBit
Definition: Constants.h:81
Definition: Constants.h:212
void reverseInPlace()
Definition: Reverse.h:231
const unsigned int LinearAccessBit
Definition: Constants.h:117
const unsigned int LvalueBit
Definition: Constants.h:131
Definition: Constants.h:209
Definition: Eigen_Colamd.h:50
Definition: Constants.h:215
Expression of the reverse of a vector or matrix.
Definition: Reverse.h:70