PageRenderTime 72ms CodeModel.GetById 41ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Geometry_Eigen/Eigen/src/Core/Reverse.h

http://github.com/Akranar/daguerreo
C Header | 230 lines | 136 code | 34 blank | 60 comment | 20 complexity | d558fa0acdb9d059178b263a5b103ada MD5 | raw file
Possible License(s): AGPL-3.0, LGPL-2.1, LGPL-3.0, GPL-2.0
  1// This file is part of Eigen, a lightweight C++ template library
  2// for linear algebra.
  3//
  4// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
  5// Copyright (C) 2009 Ricard Marxer <email@ricardmarxer.com>
  6// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
  7//
  8// Eigen is free software; you can redistribute it and/or
  9// modify it under the terms of the GNU Lesser General Public
 10// License as published by the Free Software Foundation; either
 11// version 3 of the License, or (at your option) any later version.
 12//
 13// Alternatively, you can redistribute it and/or
 14// modify it under the terms of the GNU General Public License as
 15// published by the Free Software Foundation; either version 2 of
 16// the License, or (at your option) any later version.
 17//
 18// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
 19// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 20// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
 21// GNU General Public License for more details.
 22//
 23// You should have received a copy of the GNU Lesser General Public
 24// License and a copy of the GNU General Public License along with
 25// Eigen. If not, see <http://www.gnu.org/licenses/>.
 26
 27#ifndef EIGEN_REVERSE_H
 28#define EIGEN_REVERSE_H
 29
 30/** \class Reverse
 31  * \ingroup Core_Module
 32  *
 33  * \brief Expression of the reverse of a vector or matrix
 34  *
 35  * \param MatrixType the type of the object of which we are taking the reverse
 36  *
 37  * This class represents an expression of the reverse of a vector.
 38  * It is the return type of MatrixBase::reverse() and VectorwiseOp::reverse()
 39  * and most of the time this is the only way it is used.
 40  *
 41  * \sa MatrixBase::reverse(), VectorwiseOp::reverse()
 42  */
 43
 44namespace internal {
 45
 46template<typename MatrixType, int Direction>
 47struct traits<Reverse<MatrixType, Direction> >
 48 : traits<MatrixType>
 49{
 50  typedef typename MatrixType::Scalar Scalar;
 51  typedef typename traits<MatrixType>::StorageKind StorageKind;
 52  typedef typename traits<MatrixType>::XprKind XprKind;
 53  typedef typename nested<MatrixType>::type MatrixTypeNested;
 54  typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
 55  enum {
 56    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
 57    ColsAtCompileTime = MatrixType::ColsAtCompileTime,
 58    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
 59    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
 60
 61    // let's enable LinearAccess only with vectorization because of the product overhead
 62    LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) )
 63                 ? LinearAccessBit : 0,
 64
 65    Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | LvalueBit | PacketAccessBit | LinearAccess),
 66
 67    CoeffReadCost = _MatrixTypeNested::CoeffReadCost
 68  };
 69};
 70
 71template<typename PacketScalar, bool ReversePacket> struct reverse_packet_cond
 72{
 73  static inline PacketScalar run(const PacketScalar& x) { return preverse(x); }
 74};
 75
 76template<typename PacketScalar> struct reverse_packet_cond<PacketScalar,false>
 77{
 78  static inline PacketScalar run(const PacketScalar& x) { return x; }
 79};
 80
 81} // end namespace internal 
 82
 83template<typename MatrixType, int Direction> class Reverse
 84  : public internal::dense_xpr_base< Reverse<MatrixType, Direction> >::type
 85{
 86  public:
 87
 88    typedef typename internal::dense_xpr_base<Reverse>::type Base;
 89    EIGEN_DENSE_PUBLIC_INTERFACE(Reverse)
 90    using Base::IsRowMajor;
 91
 92    // next line is necessary because otherwise const version of operator()
 93    // is hidden by non-const version defined in this file
 94    using Base::operator(); 
 95
 96  protected:
 97    enum {
 98      PacketSize = internal::packet_traits<Scalar>::size,
 99      IsColMajor = !IsRowMajor,
100      ReverseRow = (Direction == Vertical)   || (Direction == BothDirections),
101      ReverseCol = (Direction == Horizontal) || (Direction == BothDirections),
102      OffsetRow  = ReverseRow && IsColMajor ? PacketSize : 1,
103      OffsetCol  = ReverseCol && IsRowMajor ? PacketSize : 1,
104      ReversePacket = (Direction == BothDirections)
105                    || ((Direction == Vertical)   && IsColMajor)
106                    || ((Direction == Horizontal) && IsRowMajor)
107    };
108    typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet;
109  public:
110
111    inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { }
112
113    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
114
115    inline Index rows() const { return m_matrix.rows(); }
116    inline Index cols() const { return m_matrix.cols(); }
117
118    inline Index innerStride() const
119    {
120      return -m_matrix.innerStride();
121    }
122
123    inline Scalar& operator()(Index row, Index col)
124    {
125      eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
126      return coeffRef(row, col);
127    }
128
129    inline Scalar& coeffRef(Index row, Index col)
130    {
131      return m_matrix.const_cast_derived().coeffRef(ReverseRow ? m_matrix.rows() - row - 1 : row,
132                                                    ReverseCol ? m_matrix.cols() - col - 1 : col);
133    }
134
135    inline CoeffReturnType coeff(Index row, Index col) const
136    {
137      return m_matrix.coeff(ReverseRow ? m_matrix.rows() - row - 1 : row,
138                            ReverseCol ? m_matrix.cols() - col - 1 : col);
139    }
140
141    inline CoeffReturnType coeff(Index index) const
142    {
143      return m_matrix.coeff(m_matrix.size() - index - 1);
144    }
145
146    inline Scalar& coeffRef(Index index)
147    {
148      return m_matrix.const_cast_derived().coeffRef(m_matrix.size() - index - 1);
149    }
150
151    inline Scalar& operator()(Index index)
152    {
153      eigen_assert(index >= 0 && index < m_matrix.size());
154      return coeffRef(index);
155    }
156
157    template<int LoadMode>
158    inline const PacketScalar packet(Index row, Index col) const
159    {
160      return reverse_packet::run(m_matrix.template packet<LoadMode>(
161                                    ReverseRow ? m_matrix.rows() - row - OffsetRow : row,
162                                    ReverseCol ? m_matrix.cols() - col - OffsetCol : col));
163    }
164
165    template<int LoadMode>
166    inline void writePacket(Index row, Index col, const PacketScalar& x)
167    {
168      m_matrix.const_cast_derived().template writePacket<LoadMode>(
169                                      ReverseRow ? m_matrix.rows() - row - OffsetRow : row,
170                                      ReverseCol ? m_matrix.cols() - col - OffsetCol : col,
171                                      reverse_packet::run(x));
172    }
173
174    template<int LoadMode>
175    inline const PacketScalar packet(Index index) const
176    {
177      return internal::preverse(m_matrix.template packet<LoadMode>( m_matrix.size() - index - PacketSize ));
178    }
179
180    template<int LoadMode>
181    inline void writePacket(Index index, const PacketScalar& x)
182    {
183      m_matrix.const_cast_derived().template writePacket<LoadMode>(m_matrix.size() - index - PacketSize, internal::preverse(x));
184    }
185
186  protected:
187    const typename MatrixType::Nested m_matrix;
188};
189
190/** \returns an expression of the reverse of *this.
191  *
192  * Example: \include MatrixBase_reverse.cpp
193  * Output: \verbinclude MatrixBase_reverse.out
194  *
195  */
196template<typename Derived>
197inline typename DenseBase<Derived>::ReverseReturnType
198DenseBase<Derived>::reverse()
199{
200  return derived();
201}
202
203/** This is the const version of reverse(). */
204template<typename Derived>
205inline const typename DenseBase<Derived>::ConstReverseReturnType
206DenseBase<Derived>::reverse() const
207{
208  return derived();
209}
210
211/** This is the "in place" version of reverse: it reverses \c *this.
212  *
213  * In most cases it is probably better to simply use the reversed expression
214  * of a matrix. However, when reversing the matrix data itself is really needed,
215  * then this "in-place" version is probably the right choice because it provides
216  * the following additional features:
217  *  - less error prone: doing the same operation with .reverse() requires special care:
218  *    \code m = m.reverse().eval(); \endcode
219  *  - this API allows to avoid creating a temporary (the current implementation creates a temporary, but that could be avoided using swap)
220  *  - it allows future optimizations (cache friendliness, etc.)
221  *
222  * \sa reverse() */
223template<typename Derived>
224inline void DenseBase<Derived>::reverseInPlace()
225{
226  derived() = derived().reverse().eval();
227}
228
229
230#endif // EIGEN_REVERSE_H