Eigne Matrix Class Library
Dependents: Eigen_test Odometry_test AttitudeEstimation_usingTicker MPU9250_Quaternion_Binary_Serial ... more
Reverse.h
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> 00005 // Copyright (C) 2009 Ricard Marxer <email@ricardmarxer.com> 00006 // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> 00007 // 00008 // This Source Code Form is subject to the terms of the Mozilla 00009 // Public License v. 2.0. If a copy of the MPL was not distributed 00010 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00011 00012 #ifndef EIGEN_REVERSE_H 00013 #define EIGEN_REVERSE_H 00014 00015 namespace Eigen { 00016 00017 /** \class Reverse 00018 * \ingroup Core_Module 00019 * 00020 * \brief Expression of the reverse of a vector or matrix 00021 * 00022 * \param MatrixType the type of the object of which we are taking the reverse 00023 * 00024 * This class represents an expression of the reverse of a vector. 00025 * It is the return type of MatrixBase::reverse() and VectorwiseOp::reverse() 00026 * and most of the time this is the only way it is used. 00027 * 00028 * \sa MatrixBase::reverse(), VectorwiseOp::reverse() 00029 */ 00030 00031 namespace internal { 00032 00033 template<typename MatrixType, int Direction> 00034 struct traits<Reverse<MatrixType, Direction> > 00035 : traits<MatrixType> 00036 { 00037 typedef typename MatrixType::Scalar Scalar; 00038 typedef typename traits<MatrixType>::StorageKind StorageKind; 00039 typedef typename traits<MatrixType>::XprKind XprKind; 00040 typedef typename nested<MatrixType>::type MatrixTypeNested; 00041 typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested; 00042 enum { 00043 RowsAtCompileTime = MatrixType::RowsAtCompileTime, 00044 ColsAtCompileTime = MatrixType::ColsAtCompileTime, 00045 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, 00046 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, 00047 00048 // let's enable LinearAccess only with vectorization because of the product overhead 00049 LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) ) 00050 ? LinearAccessBit : 0, 00051 00052 Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | LvalueBit | PacketAccessBit | LinearAccess), 00053 00054 CoeffReadCost = _MatrixTypeNested::CoeffReadCost 00055 }; 00056 }; 00057 00058 template<typename PacketScalar, bool ReversePacket> struct reverse_packet_cond 00059 { 00060 static inline PacketScalar run(const PacketScalar& x) { return preverse(x); } 00061 }; 00062 00063 template<typename PacketScalar> struct reverse_packet_cond<PacketScalar,false> 00064 { 00065 static inline PacketScalar run(const PacketScalar& x) { return x; } 00066 }; 00067 00068 } // end namespace internal 00069 00070 template<typename MatrixType, int Direction> class Reverse 00071 : public internal::dense_xpr_base< Reverse<MatrixType, Direction> >::type 00072 { 00073 public: 00074 00075 typedef typename internal::dense_xpr_base<Reverse>::type Base; 00076 EIGEN_DENSE_PUBLIC_INTERFACE(Reverse) 00077 using Base::IsRowMajor; 00078 00079 // next line is necessary because otherwise const version of operator() 00080 // is hidden by non-const version defined in this file 00081 using Base::operator(); 00082 00083 protected: 00084 enum { 00085 PacketSize = internal::packet_traits<Scalar>::size, 00086 IsColMajor = !IsRowMajor, 00087 ReverseRow = (Direction == Vertical) || (Direction == BothDirections), 00088 ReverseCol = (Direction == Horizontal) || (Direction == BothDirections), 00089 OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1, 00090 OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1, 00091 ReversePacket = (Direction == BothDirections) 00092 || ((Direction == Vertical) && IsColMajor) 00093 || ((Direction == Horizontal) && IsRowMajor) 00094 }; 00095 typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet; 00096 public: 00097 00098 inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { } 00099 00100 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse) 00101 00102 inline Index rows() const { return m_matrix.rows(); } 00103 inline Index cols() const { return m_matrix.cols(); } 00104 00105 inline Index innerStride() const 00106 { 00107 return -m_matrix.innerStride(); 00108 } 00109 00110 inline Scalar& operator()(Index row, Index col) 00111 { 00112 eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); 00113 return coeffRef(row, col); 00114 } 00115 00116 inline Scalar& coeffRef(Index row, Index col) 00117 { 00118 return m_matrix.const_cast_derived().coeffRef(ReverseRow ? m_matrix.rows() - row - 1 : row, 00119 ReverseCol ? m_matrix.cols() - col - 1 : col); 00120 } 00121 00122 inline CoeffReturnType coeff(Index row, Index col) const 00123 { 00124 return m_matrix.coeff(ReverseRow ? m_matrix.rows() - row - 1 : row, 00125 ReverseCol ? m_matrix.cols() - col - 1 : col); 00126 } 00127 00128 inline CoeffReturnType coeff(Index index) const 00129 { 00130 return m_matrix.coeff(m_matrix.size() - index - 1); 00131 } 00132 00133 inline Scalar& coeffRef(Index index) 00134 { 00135 return m_matrix.const_cast_derived().coeffRef(m_matrix.size() - index - 1); 00136 } 00137 00138 inline Scalar& operator()(Index index) 00139 { 00140 eigen_assert(index >= 0 && index < m_matrix.size()); 00141 return coeffRef(index); 00142 } 00143 00144 template<int LoadMode> 00145 inline const PacketScalar packet(Index row, Index col) const 00146 { 00147 return reverse_packet::run(m_matrix.template packet<LoadMode>( 00148 ReverseRow ? m_matrix.rows() - row - OffsetRow : row, 00149 ReverseCol ? m_matrix.cols() - col - OffsetCol : col)); 00150 } 00151 00152 template<int LoadMode> 00153 inline void writePacket(Index row, Index col, const PacketScalar& x) 00154 { 00155 m_matrix.const_cast_derived().template writePacket<LoadMode>( 00156 ReverseRow ? m_matrix.rows() - row - OffsetRow : row, 00157 ReverseCol ? m_matrix.cols() - col - OffsetCol : col, 00158 reverse_packet::run(x)); 00159 } 00160 00161 template<int LoadMode> 00162 inline const PacketScalar packet(Index index) const 00163 { 00164 return internal::preverse(m_matrix.template packet<LoadMode>( m_matrix.size() - index - PacketSize )); 00165 } 00166 00167 template<int LoadMode> 00168 inline void writePacket(Index index, const PacketScalar& x) 00169 { 00170 m_matrix.const_cast_derived().template writePacket<LoadMode>(m_matrix.size() - index - PacketSize, internal::preverse(x)); 00171 } 00172 00173 const typename internal::remove_all<typename MatrixType::Nested>::type& 00174 nestedExpression() const 00175 { 00176 return m_matrix; 00177 } 00178 00179 protected: 00180 typename MatrixType::Nested m_matrix; 00181 }; 00182 00183 /** \returns an expression of the reverse of *this. 00184 * 00185 * Example: \include MatrixBase_reverse.cpp 00186 * Output: \verbinclude MatrixBase_reverse.out 00187 * 00188 */ 00189 template<typename Derived> 00190 inline typename DenseBase<Derived>::ReverseReturnType 00191 DenseBase<Derived>::reverse() 00192 { 00193 return derived(); 00194 } 00195 00196 /** This is the const version of reverse(). */ 00197 template<typename Derived> 00198 inline const typename DenseBase<Derived>::ConstReverseReturnType 00199 DenseBase<Derived>::reverse() const 00200 { 00201 return derived(); 00202 } 00203 00204 /** This is the "in place" version of reverse: it reverses \c *this. 00205 * 00206 * In most cases it is probably better to simply use the reversed expression 00207 * of a matrix. However, when reversing the matrix data itself is really needed, 00208 * then this "in-place" version is probably the right choice because it provides 00209 * the following additional features: 00210 * - less error prone: doing the same operation with .reverse() requires special care: 00211 * \code m = m.reverse().eval(); \endcode 00212 * - this API allows to avoid creating a temporary (the current implementation creates a temporary, but that could be avoided using swap) 00213 * - it allows future optimizations (cache friendliness, etc.) 00214 * 00215 * \sa reverse() */ 00216 template<typename Derived> 00217 inline void DenseBase<Derived>::reverseInPlace() 00218 { 00219 derived() = derived().reverse().eval(); 00220 } 00221 00222 } // end namespace Eigen 00223 00224 #endif // EIGEN_REVERSE_H
Generated on Tue Jul 12 2022 17:46:59 by 1.7.2