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
00030 namespace Eigen {
00031
00046 namespace internal {
00047
00048 template<typename MatrixType, int Direction>
00049 struct traits<Reverse<MatrixType, Direction> >
00050 : traits<MatrixType>
00051 {
00052 typedef typename MatrixType::Scalar Scalar;
00053 typedef typename traits<MatrixType>::StorageKind StorageKind;
00054 typedef typename traits<MatrixType>::XprKind XprKind;
00055 typedef typename nested<MatrixType>::type MatrixTypeNested;
00056 typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
00057 enum {
00058 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
00059 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
00060 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
00061 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
00062
00063
00064 LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) )
00065 ? LinearAccessBit : 0,
00066
00067 Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | LvalueBit | PacketAccessBit | LinearAccess),
00068
00069 CoeffReadCost = _MatrixTypeNested::CoeffReadCost
00070 };
00071 };
00072
00073 template<typename PacketScalar, bool ReversePacket> struct reverse_packet_cond
00074 {
00075 static inline PacketScalar run(const PacketScalar& x) { return preverse(x); }
00076 };
00077
00078 template<typename PacketScalar> struct reverse_packet_cond<PacketScalar,false>
00079 {
00080 static inline PacketScalar run(const PacketScalar& x) { return x; }
00081 };
00082
00083 }
00084
00085 template<typename MatrixType, int Direction> class Reverse
00086 : public internal::dense_xpr_base< Reverse<MatrixType, Direction> >::type
00087 {
00088 public:
00089
00090 typedef typename internal::dense_xpr_base<Reverse>::type Base;
00091 EIGEN_DENSE_PUBLIC_INTERFACE(Reverse)
00092 using Base::IsRowMajor;
00093
00094
00095
00096 using Base::operator();
00097
00098 protected:
00099 enum {
00100 PacketSize = internal::packet_traits<Scalar>::size,
00101 IsColMajor = !IsRowMajor,
00102 ReverseRow = (Direction == Vertical) || (Direction == BothDirections),
00103 ReverseCol = (Direction == Horizontal) || (Direction == BothDirections),
00104 OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1,
00105 OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1,
00106 ReversePacket = (Direction == BothDirections)
00107 || ((Direction == Vertical) && IsColMajor)
00108 || ((Direction == Horizontal) && IsRowMajor)
00109 };
00110 typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet;
00111 public:
00112
00113 inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { }
00114
00115 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
00116
00117 inline Index rows() const { return m_matrix.rows(); }
00118 inline Index cols() const { return m_matrix.cols(); }
00119
00120 inline Index innerStride() const
00121 {
00122 return -m_matrix.innerStride();
00123 }
00124
00125 inline Scalar& operator()(Index row, Index col)
00126 {
00127 eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
00128 return coeffRef(row, col);
00129 }
00130
00131 inline Scalar& coeffRef(Index row, Index col)
00132 {
00133 return m_matrix.const_cast_derived().coeffRef(ReverseRow ? m_matrix.rows() - row - 1 : row,
00134 ReverseCol ? m_matrix.cols() - col - 1 : col);
00135 }
00136
00137 inline CoeffReturnType coeff(Index row, Index col) const
00138 {
00139 return m_matrix.coeff(ReverseRow ? m_matrix.rows() - row - 1 : row,
00140 ReverseCol ? m_matrix.cols() - col - 1 : col);
00141 }
00142
00143 inline CoeffReturnType coeff(Index index) const
00144 {
00145 return m_matrix.coeff(m_matrix.size() - index - 1);
00146 }
00147
00148 inline Scalar& coeffRef(Index index)
00149 {
00150 return m_matrix.const_cast_derived().coeffRef(m_matrix.size() - index - 1);
00151 }
00152
00153 inline Scalar& operator()(Index index)
00154 {
00155 eigen_assert(index >= 0 && index < m_matrix.size());
00156 return coeffRef(index);
00157 }
00158
00159 template<int LoadMode>
00160 inline const PacketScalar packet(Index row, Index col) const
00161 {
00162 return reverse_packet::run(m_matrix.template packet<LoadMode>(
00163 ReverseRow ? m_matrix.rows() - row - OffsetRow : row,
00164 ReverseCol ? m_matrix.cols() - col - OffsetCol : col));
00165 }
00166
00167 template<int LoadMode>
00168 inline void writePacket(Index row, Index col, const PacketScalar& x)
00169 {
00170 m_matrix.const_cast_derived().template writePacket<LoadMode>(
00171 ReverseRow ? m_matrix.rows() - row - OffsetRow : row,
00172 ReverseCol ? m_matrix.cols() - col - OffsetCol : col,
00173 reverse_packet::run(x));
00174 }
00175
00176 template<int LoadMode>
00177 inline const PacketScalar packet(Index index) const
00178 {
00179 return internal::preverse(m_matrix.template packet<LoadMode>( m_matrix.size() - index - PacketSize ));
00180 }
00181
00182 template<int LoadMode>
00183 inline void writePacket(Index index, const PacketScalar& x)
00184 {
00185 m_matrix.const_cast_derived().template writePacket<LoadMode>(m_matrix.size() - index - PacketSize, internal::preverse(x));
00186 }
00187
00188 const typename internal::remove_all<typename MatrixType::Nested>::type&
00189 nestedExpression() const
00190 {
00191 return m_matrix;
00192 }
00193
00194 protected:
00195 typename MatrixType::Nested m_matrix;
00196 };
00197
00204 template<typename Derived>
00205 inline typename DenseBase<Derived>::ReverseReturnType
00206 DenseBase<Derived>::reverse()
00207 {
00208 return derived();
00209 }
00210
00212 template<typename Derived>
00213 inline const typename DenseBase<Derived>::ConstReverseReturnType
00214 DenseBase<Derived>::reverse() const
00215 {
00216 return derived();
00217 }
00218
00231 template<typename Derived>
00232 inline void DenseBase<Derived>::reverseInPlace()
00233 {
00234 derived() = derived().reverse().eval();
00235 }
00236
00237 }
00238
00239 #endif // EIGEN_REVERSE_H