Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 Thu Nov 17 2022 22:01:30 by
1.7.2