![]() |
Eigen
3.3.3
|
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 namespace internal { 00018 00019 template<typename MatrixType, int Direction> 00020 struct traits<Reverse<MatrixType, Direction> > 00021 : traits<MatrixType> 00022 { 00023 typedef typename MatrixType::Scalar Scalar; 00024 typedef typename traits<MatrixType>::StorageKind StorageKind; 00025 typedef typename traits<MatrixType>::XprKind XprKind; 00026 typedef typename ref_selector<MatrixType>::type MatrixTypeNested; 00027 typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested; 00028 enum { 00029 RowsAtCompileTime = MatrixType::RowsAtCompileTime, 00030 ColsAtCompileTime = MatrixType::ColsAtCompileTime, 00031 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, 00032 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, 00033 Flags = _MatrixTypeNested::Flags & (RowMajorBit | LvalueBit) 00034 }; 00035 }; 00036 00037 template<typename PacketType, bool ReversePacket> struct reverse_packet_cond 00038 { 00039 static inline PacketType run(const PacketType& x) { return preverse(x); } 00040 }; 00041 00042 template<typename PacketType> struct reverse_packet_cond<PacketType,false> 00043 { 00044 static inline PacketType run(const PacketType& x) { return x; } 00045 }; 00046 00047 } // end namespace internal 00048 00063 template<typename MatrixType, int Direction> class Reverse 00064 : public internal::dense_xpr_base< Reverse<MatrixType, Direction> >::type 00065 { 00066 public: 00067 00068 typedef typename internal::dense_xpr_base<Reverse>::type Base; 00069 EIGEN_DENSE_PUBLIC_INTERFACE(Reverse) 00070 typedef typename internal::remove_all<MatrixType>::type NestedExpression; 00071 using Base::IsRowMajor; 00072 00073 protected: 00074 enum { 00075 PacketSize = internal::packet_traits<Scalar>::size, 00076 IsColMajor = !IsRowMajor, 00077 ReverseRow = (Direction == Vertical) || (Direction == BothDirections), 00078 ReverseCol = (Direction == Horizontal) || (Direction == BothDirections), 00079 OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1, 00080 OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1, 00081 ReversePacket = (Direction == BothDirections) 00082 || ((Direction == Vertical) && IsColMajor) 00083 || ((Direction == Horizontal) && IsRowMajor) 00084 }; 00085 typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet; 00086 public: 00087 00088 EIGEN_DEVICE_FUNC explicit inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { } 00089 00090 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse) 00091 00092 EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.rows(); } 00093 EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.cols(); } 00094 00095 EIGEN_DEVICE_FUNC inline Index innerStride() const 00096 { 00097 return -m_matrix.innerStride(); 00098 } 00099 00100 EIGEN_DEVICE_FUNC const typename internal::remove_all<typename MatrixType::Nested>::type& 00101 nestedExpression() const 00102 { 00103 return m_matrix; 00104 } 00105 00106 protected: 00107 typename MatrixType::Nested m_matrix; 00108 }; 00109 00116 template<typename Derived> 00117 inline typename DenseBase<Derived>::ReverseReturnType 00118 DenseBase<Derived>::reverse() 00119 { 00120 return ReverseReturnType(derived()); 00121 } 00122 00123 00124 //reverse const overload moved DenseBase.h due to a CUDA compiler bug 00125 00138 template<typename Derived> 00139 inline void DenseBase<Derived>::reverseInPlace() 00140 { 00141 if(cols()>rows()) 00142 { 00143 Index half = cols()/2; 00144 leftCols(half).swap(rightCols(half).reverse()); 00145 if((cols()%2)==1) 00146 { 00147 Index half2 = rows()/2; 00148 col(half).head(half2).swap(col(half).tail(half2).reverse()); 00149 } 00150 } 00151 else 00152 { 00153 Index half = rows()/2; 00154 topRows(half).swap(bottomRows(half).reverse()); 00155 if((rows()%2)==1) 00156 { 00157 Index half2 = cols()/2; 00158 row(half).head(half2).swap(row(half).tail(half2).reverse()); 00159 } 00160 } 00161 } 00162 00163 namespace internal { 00164 00165 template<int Direction> 00166 struct vectorwise_reverse_inplace_impl; 00167 00168 template<> 00169 struct vectorwise_reverse_inplace_impl<Vertical> 00170 { 00171 template<typename ExpressionType> 00172 static void run(ExpressionType &xpr) 00173 { 00174 Index half = xpr.rows()/2; 00175 xpr.topRows(half).swap(xpr.bottomRows(half).colwise().reverse()); 00176 } 00177 }; 00178 00179 template<> 00180 struct vectorwise_reverse_inplace_impl<Horizontal> 00181 { 00182 template<typename ExpressionType> 00183 static void run(ExpressionType &xpr) 00184 { 00185 Index half = xpr.cols()/2; 00186 xpr.leftCols(half).swap(xpr.rightCols(half).rowwise().reverse()); 00187 } 00188 }; 00189 00190 } // end namespace internal 00191 00203 template<typename ExpressionType, int Direction> 00204 void VectorwiseOp<ExpressionType,Direction>::reverseInPlace() 00205 { 00206 internal::vectorwise_reverse_inplace_impl<Direction>::run(_expression().const_cast_derived()); 00207 } 00208 00209 } // end namespace Eigen 00210 00211 #endif // EIGEN_REVERSE_H