Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef EIGEN_REVERSE_H
00028 #define EIGEN_REVERSE_H
00029
00044 namespace internal {
00045
00046 template<typename MatrixType, int Direction>
00047 struct traits<Reverse<MatrixType, Direction> >
00048 : traits<MatrixType>
00049 {
00050 typedef typename MatrixType::Scalar Scalar;
00051 typedef typename traits<MatrixType>::StorageKind StorageKind;
00052 typedef typename traits<MatrixType>::XprKind XprKind;
00053 typedef typename nested<MatrixType>::type MatrixTypeNested;
00054 typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
00055 enum {
00056 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
00057 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
00058 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
00059 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
00060
00061
00062 LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) )
00063 ? LinearAccessBit : 0,
00064
00065 Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | LvalueBit | PacketAccessBit | LinearAccess),
00066
00067 CoeffReadCost = _MatrixTypeNested::CoeffReadCost
00068 };
00069 };
00070
00071 template<typename PacketScalar, bool ReversePacket> struct reverse_packet_cond
00072 {
00073 static inline PacketScalar run(const PacketScalar& x) { return preverse(x); }
00074 };
00075
00076 template<typename PacketScalar> struct reverse_packet_cond<PacketScalar,false>
00077 {
00078 static inline PacketScalar run(const PacketScalar& x) { return x; }
00079 };
00080
00081 }
00082
00083 template<typename MatrixType, int Direction> class Reverse
00084 : public internal::dense_xpr_base< Reverse<MatrixType, Direction> >::type
00085 {
00086 public:
00087
00088 typedef typename internal::dense_xpr_base<Reverse>::type Base;
00089 EIGEN_DENSE_PUBLIC_INTERFACE(Reverse)
00090 using Base::IsRowMajor;
00091
00092
00093
00094 using Base::operator();
00095
00096 protected:
00097 enum {
00098 PacketSize = internal::packet_traits<Scalar>::size,
00099 IsColMajor = !IsRowMajor,
00100 ReverseRow = (Direction == Vertical) || (Direction == BothDirections),
00101 ReverseCol = (Direction == Horizontal) || (Direction == BothDirections),
00102 OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1,
00103 OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1,
00104 ReversePacket = (Direction == BothDirections)
00105 || ((Direction == Vertical) && IsColMajor)
00106 || ((Direction == Horizontal) && IsRowMajor)
00107 };
00108 typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet;
00109 public:
00110
00111 inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { }
00112
00113 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
00114
00115 inline Index rows() const { return m_matrix.rows(); }
00116 inline Index cols() const { return m_matrix.cols(); }
00117
00118 inline Index innerStride() const
00119 {
00120 return -m_matrix.innerStride();
00121 }
00122
00123 inline Scalar& operator()(Index row, Index col)
00124 {
00125 eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
00126 return coeffRef(row, col);
00127 }
00128
00129 inline Scalar& coeffRef(Index row, Index col)
00130 {
00131 return m_matrix.const_cast_derived().coeffRef(ReverseRow ? m_matrix.rows() - row - 1 : row,
00132 ReverseCol ? m_matrix.cols() - col - 1 : col);
00133 }
00134
00135 inline CoeffReturnType coeff(Index row, Index col) const
00136 {
00137 return m_matrix.coeff(ReverseRow ? m_matrix.rows() - row - 1 : row,
00138 ReverseCol ? m_matrix.cols() - col - 1 : col);
00139 }
00140
00141 inline CoeffReturnType coeff(Index index) const
00142 {
00143 return m_matrix.coeff(m_matrix.size() - index - 1);
00144 }
00145
00146 inline Scalar& coeffRef(Index index)
00147 {
00148 return m_matrix.const_cast_derived().coeffRef(m_matrix.size() - index - 1);
00149 }
00150
00151 inline Scalar& operator()(Index index)
00152 {
00153 eigen_assert(index >= 0 && index < m_matrix.size());
00154 return coeffRef(index);
00155 }
00156
00157 template<int LoadMode>
00158 inline const PacketScalar packet(Index row, Index col) const
00159 {
00160 return reverse_packet::run(m_matrix.template packet<LoadMode>(
00161 ReverseRow ? m_matrix.rows() - row - OffsetRow : row,
00162 ReverseCol ? m_matrix.cols() - col - OffsetCol : col));
00163 }
00164
00165 template<int LoadMode>
00166 inline void writePacket(Index row, Index col, const PacketScalar& x)
00167 {
00168 m_matrix.const_cast_derived().template writePacket<LoadMode>(
00169 ReverseRow ? m_matrix.rows() - row - OffsetRow : row,
00170 ReverseCol ? m_matrix.cols() - col - OffsetCol : col,
00171 reverse_packet::run(x));
00172 }
00173
00174 template<int LoadMode>
00175 inline const PacketScalar packet(Index index) const
00176 {
00177 return internal::preverse(m_matrix.template packet<LoadMode>( m_matrix.size() - index - PacketSize ));
00178 }
00179
00180 template<int LoadMode>
00181 inline void writePacket(Index index, const PacketScalar& x)
00182 {
00183 m_matrix.const_cast_derived().template writePacket<LoadMode>(m_matrix.size() - index - PacketSize, internal::preverse(x));
00184 }
00185
00186 protected:
00187 const typename MatrixType::Nested m_matrix;
00188 };
00189
00196 template<typename Derived>
00197 inline typename DenseBase<Derived>::ReverseReturnType
00198 DenseBase<Derived>::reverse()
00199 {
00200 return derived();
00201 }
00202
00204 template<typename Derived>
00205 inline const typename DenseBase<Derived>::ConstReverseReturnType
00206 DenseBase<Derived>::reverse() const
00207 {
00208 return derived();
00209 }
00210
00223 template<typename Derived>
00224 inline void DenseBase<Derived>::reverseInPlace()
00225 {
00226 derived() = derived().reverse().eval();
00227 }
00228
00229
00230 #endif // EIGEN_REVERSE_H