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