Eigen  3.3.3
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 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
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends