Home | History | Annotate | Download | only in Core
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1 (at) gmail.com>
      5 // Copyright (C) 2009-2011 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      6 //
      7 // This Source Code Form is subject to the terms of the Mozilla
      8 // Public License v. 2.0. If a copy of the MPL was not distributed
      9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     10 
     11 #ifndef EIGEN_PERMUTATIONMATRIX_H
     12 #define EIGEN_PERMUTATIONMATRIX_H
     13 
     14 namespace Eigen {
     15 
     16 template<int RowCol,typename IndicesType,typename MatrixType, typename StorageKind> class PermutedImpl;
     17 
     18 /** \class PermutationBase
     19   * \ingroup Core_Module
     20   *
     21   * \brief Base class for permutations
     22   *
     23   * \param Derived the derived class
     24   *
     25   * This class is the base class for all expressions representing a permutation matrix,
     26   * internally stored as a vector of integers.
     27   * The convention followed here is that if \f$ \sigma \f$ is a permutation, the corresponding permutation matrix
     28   * \f$ P_\sigma \f$ is such that if \f$ (e_1,\ldots,e_p) \f$ is the canonical basis, we have:
     29   *  \f[ P_\sigma(e_i) = e_{\sigma(i)}. \f]
     30   * This convention ensures that for any two permutations \f$ \sigma, \tau \f$, we have:
     31   *  \f[ P_{\sigma\circ\tau} = P_\sigma P_\tau. \f]
     32   *
     33   * Permutation matrices are square and invertible.
     34   *
     35   * Notice that in addition to the member functions and operators listed here, there also are non-member
     36   * operator* to multiply any kind of permutation object with any kind of matrix expression (MatrixBase)
     37   * on either side.
     38   *
     39   * \sa class PermutationMatrix, class PermutationWrapper
     40   */
     41 
     42 namespace internal {
     43 
     44 template<typename PermutationType, typename MatrixType, int Side, bool Transposed=false>
     45 struct permut_matrix_product_retval;
     46 template<typename PermutationType, typename MatrixType, int Side, bool Transposed=false>
     47 struct permut_sparsematrix_product_retval;
     48 enum PermPermProduct_t {PermPermProduct};
     49 
     50 } // end namespace internal
     51 
     52 template<typename Derived>
     53 class PermutationBase : public EigenBase<Derived>
     54 {
     55     typedef internal::traits<Derived> Traits;
     56     typedef EigenBase<Derived> Base;
     57   public:
     58 
     59     #ifndef EIGEN_PARSED_BY_DOXYGEN
     60     typedef typename Traits::IndicesType IndicesType;
     61     enum {
     62       Flags = Traits::Flags,
     63       CoeffReadCost = Traits::CoeffReadCost,
     64       RowsAtCompileTime = Traits::RowsAtCompileTime,
     65       ColsAtCompileTime = Traits::ColsAtCompileTime,
     66       MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime,
     67       MaxColsAtCompileTime = Traits::MaxColsAtCompileTime
     68     };
     69     typedef typename Traits::Scalar Scalar;
     70     typedef typename Traits::Index Index;
     71     typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime,0,MaxRowsAtCompileTime,MaxColsAtCompileTime>
     72             DenseMatrixType;
     73     typedef PermutationMatrix<IndicesType::SizeAtCompileTime,IndicesType::MaxSizeAtCompileTime,Index>
     74             PlainPermutationType;
     75     using Base::derived;
     76     #endif
     77 
     78     /** Copies the other permutation into *this */
     79     template<typename OtherDerived>
     80     Derived& operator=(const PermutationBase<OtherDerived>& other)
     81     {
     82       indices() = other.indices();
     83       return derived();
     84     }
     85 
     86     /** Assignment from the Transpositions \a tr */
     87     template<typename OtherDerived>
     88     Derived& operator=(const TranspositionsBase<OtherDerived>& tr)
     89     {
     90       setIdentity(tr.size());
     91       for(Index k=size()-1; k>=0; --k)
     92         applyTranspositionOnTheRight(k,tr.coeff(k));
     93       return derived();
     94     }
     95 
     96     #ifndef EIGEN_PARSED_BY_DOXYGEN
     97     /** This is a special case of the templated operator=. Its purpose is to
     98       * prevent a default operator= from hiding the templated operator=.
     99       */
    100     Derived& operator=(const PermutationBase& other)
    101     {
    102       indices() = other.indices();
    103       return derived();
    104     }
    105     #endif
    106 
    107     /** \returns the number of rows */
    108     inline Index rows() const { return Index(indices().size()); }
    109 
    110     /** \returns the number of columns */
    111     inline Index cols() const { return Index(indices().size()); }
    112 
    113     /** \returns the size of a side of the respective square matrix, i.e., the number of indices */
    114     inline Index size() const { return Index(indices().size()); }
    115 
    116     #ifndef EIGEN_PARSED_BY_DOXYGEN
    117     template<typename DenseDerived>
    118     void evalTo(MatrixBase<DenseDerived>& other) const
    119     {
    120       other.setZero();
    121       for (int i=0; i<rows();++i)
    122         other.coeffRef(indices().coeff(i),i) = typename DenseDerived::Scalar(1);
    123     }
    124     #endif
    125 
    126     /** \returns a Matrix object initialized from this permutation matrix. Notice that it
    127       * is inefficient to return this Matrix object by value. For efficiency, favor using
    128       * the Matrix constructor taking EigenBase objects.
    129       */
    130     DenseMatrixType toDenseMatrix() const
    131     {
    132       return derived();
    133     }
    134 
    135     /** const version of indices(). */
    136     const IndicesType& indices() const { return derived().indices(); }
    137     /** \returns a reference to the stored array representing the permutation. */
    138     IndicesType& indices() { return derived().indices(); }
    139 
    140     /** Resizes to given size.
    141       */
    142     inline void resize(Index newSize)
    143     {
    144       indices().resize(newSize);
    145     }
    146 
    147     /** Sets *this to be the identity permutation matrix */
    148     void setIdentity()
    149     {
    150       for(Index i = 0; i < size(); ++i)
    151         indices().coeffRef(i) = i;
    152     }
    153 
    154     /** Sets *this to be the identity permutation matrix of given size.
    155       */
    156     void setIdentity(Index newSize)
    157     {
    158       resize(newSize);
    159       setIdentity();
    160     }
    161 
    162     /** Multiplies *this by the transposition \f$(ij)\f$ on the left.
    163       *
    164       * \returns a reference to *this.
    165       *
    166       * \warning This is much slower than applyTranspositionOnTheRight(int,int):
    167       * this has linear complexity and requires a lot of branching.
    168       *
    169       * \sa applyTranspositionOnTheRight(int,int)
    170       */
    171     Derived& applyTranspositionOnTheLeft(Index i, Index j)
    172     {
    173       eigen_assert(i>=0 && j>=0 && i<size() && j<size());
    174       for(Index k = 0; k < size(); ++k)
    175       {
    176         if(indices().coeff(k) == i) indices().coeffRef(k) = j;
    177         else if(indices().coeff(k) == j) indices().coeffRef(k) = i;
    178       }
    179       return derived();
    180     }
    181 
    182     /** Multiplies *this by the transposition \f$(ij)\f$ on the right.
    183       *
    184       * \returns a reference to *this.
    185       *
    186       * This is a fast operation, it only consists in swapping two indices.
    187       *
    188       * \sa applyTranspositionOnTheLeft(int,int)
    189       */
    190     Derived& applyTranspositionOnTheRight(Index i, Index j)
    191     {
    192       eigen_assert(i>=0 && j>=0 && i<size() && j<size());
    193       std::swap(indices().coeffRef(i), indices().coeffRef(j));
    194       return derived();
    195     }
    196 
    197     /** \returns the inverse permutation matrix.
    198       *
    199       * \note \note_try_to_help_rvo
    200       */
    201     inline Transpose<PermutationBase> inverse() const
    202     { return derived(); }
    203     /** \returns the tranpose permutation matrix.
    204       *
    205       * \note \note_try_to_help_rvo
    206       */
    207     inline Transpose<PermutationBase> transpose() const
    208     { return derived(); }
    209 
    210     /**** multiplication helpers to hopefully get RVO ****/
    211 
    212 
    213 #ifndef EIGEN_PARSED_BY_DOXYGEN
    214   protected:
    215     template<typename OtherDerived>
    216     void assignTranspose(const PermutationBase<OtherDerived>& other)
    217     {
    218       for (int i=0; i<rows();++i) indices().coeffRef(other.indices().coeff(i)) = i;
    219     }
    220     template<typename Lhs,typename Rhs>
    221     void assignProduct(const Lhs& lhs, const Rhs& rhs)
    222     {
    223       eigen_assert(lhs.cols() == rhs.rows());
    224       for (int i=0; i<rows();++i) indices().coeffRef(i) = lhs.indices().coeff(rhs.indices().coeff(i));
    225     }
    226 #endif
    227 
    228   public:
    229 
    230     /** \returns the product permutation matrix.
    231       *
    232       * \note \note_try_to_help_rvo
    233       */
    234     template<typename Other>
    235     inline PlainPermutationType operator*(const PermutationBase<Other>& other) const
    236     { return PlainPermutationType(internal::PermPermProduct, derived(), other.derived()); }
    237 
    238     /** \returns the product of a permutation with another inverse permutation.
    239       *
    240       * \note \note_try_to_help_rvo
    241       */
    242     template<typename Other>
    243     inline PlainPermutationType operator*(const Transpose<PermutationBase<Other> >& other) const
    244     { return PlainPermutationType(internal::PermPermProduct, *this, other.eval()); }
    245 
    246     /** \returns the product of an inverse permutation with another permutation.
    247       *
    248       * \note \note_try_to_help_rvo
    249       */
    250     template<typename Other> friend
    251     inline PlainPermutationType operator*(const Transpose<PermutationBase<Other> >& other, const PermutationBase& perm)
    252     { return PlainPermutationType(internal::PermPermProduct, other.eval(), perm); }
    253 
    254     /** \returns the determinant of the permutation matrix, which is either 1 or -1 depending on the parity of the permutation.
    255       *
    256       * This function is O(\c n) procedure allocating a buffer of \c n booleans.
    257       */
    258     Index determinant() const
    259     {
    260       Index res = 1;
    261       Index n = size();
    262       Matrix<bool,RowsAtCompileTime,1,0,MaxRowsAtCompileTime> mask(n);
    263       mask.fill(false);
    264       Index r = 0;
    265       while(r < n)
    266       {
    267         // search for the next seed
    268         while(r<n && mask[r]) r++;
    269         if(r>=n)
    270           break;
    271         // we got one, let's follow it until we are back to the seed
    272         Index k0 = r++;
    273         mask.coeffRef(k0) = true;
    274         for(Index k=indices().coeff(k0); k!=k0; k=indices().coeff(k))
    275         {
    276           mask.coeffRef(k) = true;
    277           res = -res;
    278         }
    279       }
    280       return res;
    281     }
    282 
    283   protected:
    284 
    285 };
    286 
    287 /** \class PermutationMatrix
    288   * \ingroup Core_Module
    289   *
    290   * \brief Permutation matrix
    291   *
    292   * \param SizeAtCompileTime the number of rows/cols, or Dynamic
    293   * \param MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it.
    294   * \param IndexType the interger type of the indices
    295   *
    296   * This class represents a permutation matrix, internally stored as a vector of integers.
    297   *
    298   * \sa class PermutationBase, class PermutationWrapper, class DiagonalMatrix
    299   */
    300 
    301 namespace internal {
    302 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType>
    303 struct traits<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType> >
    304  : traits<Matrix<IndexType,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
    305 {
    306   typedef IndexType Index;
    307   typedef Matrix<IndexType, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
    308 };
    309 }
    310 
    311 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType>
    312 class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType> >
    313 {
    314     typedef PermutationBase<PermutationMatrix> Base;
    315     typedef internal::traits<PermutationMatrix> Traits;
    316   public:
    317 
    318     #ifndef EIGEN_PARSED_BY_DOXYGEN
    319     typedef typename Traits::IndicesType IndicesType;
    320     #endif
    321 
    322     inline PermutationMatrix()
    323     {}
    324 
    325     /** Constructs an uninitialized permutation matrix of given size.
    326       */
    327     inline PermutationMatrix(int size) : m_indices(size)
    328     {}
    329 
    330     /** Copy constructor. */
    331     template<typename OtherDerived>
    332     inline PermutationMatrix(const PermutationBase<OtherDerived>& other)
    333       : m_indices(other.indices()) {}
    334 
    335     #ifndef EIGEN_PARSED_BY_DOXYGEN
    336     /** Standard copy constructor. Defined only to prevent a default copy constructor
    337       * from hiding the other templated constructor */
    338     inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {}
    339     #endif
    340 
    341     /** Generic constructor from expression of the indices. The indices
    342       * array has the meaning that the permutations sends each integer i to indices[i].
    343       *
    344       * \warning It is your responsibility to check that the indices array that you passes actually
    345       * describes a permutation, i.e., each value between 0 and n-1 occurs exactly once, where n is the
    346       * array's size.
    347       */
    348     template<typename Other>
    349     explicit inline PermutationMatrix(const MatrixBase<Other>& a_indices) : m_indices(a_indices)
    350     {}
    351 
    352     /** Convert the Transpositions \a tr to a permutation matrix */
    353     template<typename Other>
    354     explicit PermutationMatrix(const TranspositionsBase<Other>& tr)
    355       : m_indices(tr.size())
    356     {
    357       *this = tr;
    358     }
    359 
    360     /** Copies the other permutation into *this */
    361     template<typename Other>
    362     PermutationMatrix& operator=(const PermutationBase<Other>& other)
    363     {
    364       m_indices = other.indices();
    365       return *this;
    366     }
    367 
    368     /** Assignment from the Transpositions \a tr */
    369     template<typename Other>
    370     PermutationMatrix& operator=(const TranspositionsBase<Other>& tr)
    371     {
    372       return Base::operator=(tr.derived());
    373     }
    374 
    375     #ifndef EIGEN_PARSED_BY_DOXYGEN
    376     /** This is a special case of the templated operator=. Its purpose is to
    377       * prevent a default operator= from hiding the templated operator=.
    378       */
    379     PermutationMatrix& operator=(const PermutationMatrix& other)
    380     {
    381       m_indices = other.m_indices;
    382       return *this;
    383     }
    384     #endif
    385 
    386     /** const version of indices(). */
    387     const IndicesType& indices() const { return m_indices; }
    388     /** \returns a reference to the stored array representing the permutation. */
    389     IndicesType& indices() { return m_indices; }
    390 
    391 
    392     /**** multiplication helpers to hopefully get RVO ****/
    393 
    394 #ifndef EIGEN_PARSED_BY_DOXYGEN
    395     template<typename Other>
    396     PermutationMatrix(const Transpose<PermutationBase<Other> >& other)
    397       : m_indices(other.nestedPermutation().size())
    398     {
    399       for (int i=0; i<m_indices.size();++i) m_indices.coeffRef(other.nestedPermutation().indices().coeff(i)) = i;
    400     }
    401     template<typename Lhs,typename Rhs>
    402     PermutationMatrix(internal::PermPermProduct_t, const Lhs& lhs, const Rhs& rhs)
    403       : m_indices(lhs.indices().size())
    404     {
    405       Base::assignProduct(lhs,rhs);
    406     }
    407 #endif
    408 
    409   protected:
    410 
    411     IndicesType m_indices;
    412 };
    413 
    414 
    415 namespace internal {
    416 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess>
    417 struct traits<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess> >
    418  : traits<Matrix<IndexType,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
    419 {
    420   typedef IndexType Index;
    421   typedef Map<const Matrix<IndexType, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1>, _PacketAccess> IndicesType;
    422 };
    423 }
    424 
    425 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess>
    426 class Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess>
    427   : public PermutationBase<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess> >
    428 {
    429     typedef PermutationBase<Map> Base;
    430     typedef internal::traits<Map> Traits;
    431   public:
    432 
    433     #ifndef EIGEN_PARSED_BY_DOXYGEN
    434     typedef typename Traits::IndicesType IndicesType;
    435     typedef typename IndicesType::Scalar Index;
    436     #endif
    437 
    438     inline Map(const Index* indicesPtr)
    439       : m_indices(indicesPtr)
    440     {}
    441 
    442     inline Map(const Index* indicesPtr, Index size)
    443       : m_indices(indicesPtr,size)
    444     {}
    445 
    446     /** Copies the other permutation into *this */
    447     template<typename Other>
    448     Map& operator=(const PermutationBase<Other>& other)
    449     { return Base::operator=(other.derived()); }
    450 
    451     /** Assignment from the Transpositions \a tr */
    452     template<typename Other>
    453     Map& operator=(const TranspositionsBase<Other>& tr)
    454     { return Base::operator=(tr.derived()); }
    455 
    456     #ifndef EIGEN_PARSED_BY_DOXYGEN
    457     /** This is a special case of the templated operator=. Its purpose is to
    458       * prevent a default operator= from hiding the templated operator=.
    459       */
    460     Map& operator=(const Map& other)
    461     {
    462       m_indices = other.m_indices;
    463       return *this;
    464     }
    465     #endif
    466 
    467     /** const version of indices(). */
    468     const IndicesType& indices() const { return m_indices; }
    469     /** \returns a reference to the stored array representing the permutation. */
    470     IndicesType& indices() { return m_indices; }
    471 
    472   protected:
    473 
    474     IndicesType m_indices;
    475 };
    476 
    477 /** \class PermutationWrapper
    478   * \ingroup Core_Module
    479   *
    480   * \brief Class to view a vector of integers as a permutation matrix
    481   *
    482   * \param _IndicesType the type of the vector of integer (can be any compatible expression)
    483   *
    484   * This class allows to view any vector expression of integers as a permutation matrix.
    485   *
    486   * \sa class PermutationBase, class PermutationMatrix
    487   */
    488 
    489 struct PermutationStorage {};
    490 
    491 template<typename _IndicesType> class TranspositionsWrapper;
    492 namespace internal {
    493 template<typename _IndicesType>
    494 struct traits<PermutationWrapper<_IndicesType> >
    495 {
    496   typedef PermutationStorage StorageKind;
    497   typedef typename _IndicesType::Scalar Scalar;
    498   typedef typename _IndicesType::Scalar Index;
    499   typedef _IndicesType IndicesType;
    500   enum {
    501     RowsAtCompileTime = _IndicesType::SizeAtCompileTime,
    502     ColsAtCompileTime = _IndicesType::SizeAtCompileTime,
    503     MaxRowsAtCompileTime = IndicesType::MaxRowsAtCompileTime,
    504     MaxColsAtCompileTime = IndicesType::MaxColsAtCompileTime,
    505     Flags = 0,
    506     CoeffReadCost = _IndicesType::CoeffReadCost
    507   };
    508 };
    509 }
    510 
    511 template<typename _IndicesType>
    512 class PermutationWrapper : public PermutationBase<PermutationWrapper<_IndicesType> >
    513 {
    514     typedef PermutationBase<PermutationWrapper> Base;
    515     typedef internal::traits<PermutationWrapper> Traits;
    516   public:
    517 
    518     #ifndef EIGEN_PARSED_BY_DOXYGEN
    519     typedef typename Traits::IndicesType IndicesType;
    520     #endif
    521 
    522     inline PermutationWrapper(const IndicesType& a_indices)
    523       : m_indices(a_indices)
    524     {}
    525 
    526     /** const version of indices(). */
    527     const typename internal::remove_all<typename IndicesType::Nested>::type&
    528     indices() const { return m_indices; }
    529 
    530   protected:
    531 
    532     typename IndicesType::Nested m_indices;
    533 };
    534 
    535 /** \returns the matrix with the permutation applied to the columns.
    536   */
    537 template<typename Derived, typename PermutationDerived>
    538 inline const internal::permut_matrix_product_retval<PermutationDerived, Derived, OnTheRight>
    539 operator*(const MatrixBase<Derived>& matrix,
    540           const PermutationBase<PermutationDerived> &permutation)
    541 {
    542   return internal::permut_matrix_product_retval
    543            <PermutationDerived, Derived, OnTheRight>
    544            (permutation.derived(), matrix.derived());
    545 }
    546 
    547 /** \returns the matrix with the permutation applied to the rows.
    548   */
    549 template<typename Derived, typename PermutationDerived>
    550 inline const internal::permut_matrix_product_retval
    551                <PermutationDerived, Derived, OnTheLeft>
    552 operator*(const PermutationBase<PermutationDerived> &permutation,
    553           const MatrixBase<Derived>& matrix)
    554 {
    555   return internal::permut_matrix_product_retval
    556            <PermutationDerived, Derived, OnTheLeft>
    557            (permutation.derived(), matrix.derived());
    558 }
    559 
    560 namespace internal {
    561 
    562 template<typename PermutationType, typename MatrixType, int Side, bool Transposed>
    563 struct traits<permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> >
    564 {
    565   typedef typename MatrixType::PlainObject ReturnType;
    566 };
    567 
    568 template<typename PermutationType, typename MatrixType, int Side, bool Transposed>
    569 struct permut_matrix_product_retval
    570  : public ReturnByValue<permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> >
    571 {
    572     typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned;
    573     typedef typename MatrixType::Index Index;
    574 
    575     permut_matrix_product_retval(const PermutationType& perm, const MatrixType& matrix)
    576       : m_permutation(perm), m_matrix(matrix)
    577     {}
    578 
    579     inline Index rows() const { return m_matrix.rows(); }
    580     inline Index cols() const { return m_matrix.cols(); }
    581 
    582     template<typename Dest> inline void evalTo(Dest& dst) const
    583     {
    584       const Index n = Side==OnTheLeft ? rows() : cols();
    585       // FIXME we need an is_same for expression that is not sensitive to constness. For instance
    586       // is_same_xpr<Block<const Matrix>, Block<Matrix> >::value should be true.
    587       if(    is_same<MatrixTypeNestedCleaned,Dest>::value
    588           && blas_traits<MatrixTypeNestedCleaned>::HasUsableDirectAccess
    589           && blas_traits<Dest>::HasUsableDirectAccess
    590           && extract_data(dst) == extract_data(m_matrix))
    591       {
    592         // apply the permutation inplace
    593         Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(m_permutation.size());
    594         mask.fill(false);
    595         Index r = 0;
    596         while(r < m_permutation.size())
    597         {
    598           // search for the next seed
    599           while(r<m_permutation.size() && mask[r]) r++;
    600           if(r>=m_permutation.size())
    601             break;
    602           // we got one, let's follow it until we are back to the seed
    603           Index k0 = r++;
    604           Index kPrev = k0;
    605           mask.coeffRef(k0) = true;
    606           for(Index k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k))
    607           {
    608                   Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>(dst, k)
    609             .swap(Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
    610                        (dst,((Side==OnTheLeft) ^ Transposed) ? k0 : kPrev));
    611 
    612             mask.coeffRef(k) = true;
    613             kPrev = k;
    614           }
    615         }
    616       }
    617       else
    618       {
    619         for(int i = 0; i < n; ++i)
    620         {
    621           Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
    622                (dst, ((Side==OnTheLeft) ^ Transposed) ? m_permutation.indices().coeff(i) : i)
    623 
    624           =
    625 
    626           Block<const MatrixTypeNestedCleaned,Side==OnTheLeft ? 1 : MatrixType::RowsAtCompileTime,Side==OnTheRight ? 1 : MatrixType::ColsAtCompileTime>
    627                (m_matrix, ((Side==OnTheRight) ^ Transposed) ? m_permutation.indices().coeff(i) : i);
    628         }
    629       }
    630     }
    631 
    632   protected:
    633     const PermutationType& m_permutation;
    634     typename MatrixType::Nested m_matrix;
    635 };
    636 
    637 /* Template partial specialization for transposed/inverse permutations */
    638 
    639 template<typename Derived>
    640 struct traits<Transpose<PermutationBase<Derived> > >
    641  : traits<Derived>
    642 {};
    643 
    644 } // end namespace internal
    645 
    646 template<typename Derived>
    647 class Transpose<PermutationBase<Derived> >
    648   : public EigenBase<Transpose<PermutationBase<Derived> > >
    649 {
    650     typedef Derived PermutationType;
    651     typedef typename PermutationType::IndicesType IndicesType;
    652     typedef typename PermutationType::PlainPermutationType PlainPermutationType;
    653   public:
    654 
    655     #ifndef EIGEN_PARSED_BY_DOXYGEN
    656     typedef internal::traits<PermutationType> Traits;
    657     typedef typename Derived::DenseMatrixType DenseMatrixType;
    658     enum {
    659       Flags = Traits::Flags,
    660       CoeffReadCost = Traits::CoeffReadCost,
    661       RowsAtCompileTime = Traits::RowsAtCompileTime,
    662       ColsAtCompileTime = Traits::ColsAtCompileTime,
    663       MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime,
    664       MaxColsAtCompileTime = Traits::MaxColsAtCompileTime
    665     };
    666     typedef typename Traits::Scalar Scalar;
    667     #endif
    668 
    669     Transpose(const PermutationType& p) : m_permutation(p) {}
    670 
    671     inline int rows() const { return m_permutation.rows(); }
    672     inline int cols() const { return m_permutation.cols(); }
    673 
    674     #ifndef EIGEN_PARSED_BY_DOXYGEN
    675     template<typename DenseDerived>
    676     void evalTo(MatrixBase<DenseDerived>& other) const
    677     {
    678       other.setZero();
    679       for (int i=0; i<rows();++i)
    680         other.coeffRef(i, m_permutation.indices().coeff(i)) = typename DenseDerived::Scalar(1);
    681     }
    682     #endif
    683 
    684     /** \return the equivalent permutation matrix */
    685     PlainPermutationType eval() const { return *this; }
    686 
    687     DenseMatrixType toDenseMatrix() const { return *this; }
    688 
    689     /** \returns the matrix with the inverse permutation applied to the columns.
    690       */
    691     template<typename OtherDerived> friend
    692     inline const internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheRight, true>
    693     operator*(const MatrixBase<OtherDerived>& matrix, const Transpose& trPerm)
    694     {
    695       return internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheRight, true>(trPerm.m_permutation, matrix.derived());
    696     }
    697 
    698     /** \returns the matrix with the inverse permutation applied to the rows.
    699       */
    700     template<typename OtherDerived>
    701     inline const internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheLeft, true>
    702     operator*(const MatrixBase<OtherDerived>& matrix) const
    703     {
    704       return internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheLeft, true>(m_permutation, matrix.derived());
    705     }
    706 
    707     const PermutationType& nestedPermutation() const { return m_permutation; }
    708 
    709   protected:
    710     const PermutationType& m_permutation;
    711 };
    712 
    713 template<typename Derived>
    714 const PermutationWrapper<const Derived> MatrixBase<Derived>::asPermutation() const
    715 {
    716   return derived();
    717 }
    718 
    719 } // end namespace Eigen
    720 
    721 #endif // EIGEN_PERMUTATIONMATRIX_H
    722