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@gmail.com>
5 // Copyright (C) 2009-2011 Gael Guennebaud <gael.guennebaud@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 */
rows()108     inline Index rows() const { return Index(indices().size()); }
109 
110     /** \returns the number of columns */
cols()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 */
size()114     inline Index size() const { return Index(indices().size()); }
115 
116     #ifndef EIGEN_PARSED_BY_DOXYGEN
117     template<typename DenseDerived>
evalTo(MatrixBase<DenseDerived> & other)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       */
toDenseMatrix()130     DenseMatrixType toDenseMatrix() const
131     {
132       return derived();
133     }
134 
135     /** const version of indices(). */
indices()136     const IndicesType& indices() const { return derived().indices(); }
137     /** \returns a reference to the stored array representing the permutation. */
indices()138     IndicesType& indices() { return derived().indices(); }
139 
140     /** Resizes to given size.
141       */
resize(Index newSize)142     inline void resize(Index newSize)
143     {
144       indices().resize(newSize);
145     }
146 
147     /** Sets *this to be the identity permutation matrix */
setIdentity()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       */
setIdentity(Index newSize)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       */
applyTranspositionOnTheLeft(Index i,Index j)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       */
applyTranspositionOnTheRight(Index i,Index j)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       */
inverse()201     inline Transpose<PermutationBase> inverse() const
202     { return derived(); }
203     /** \returns the tranpose permutation matrix.
204       *
205       * \note \note_try_to_help_rvo
206       */
transpose()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>
assignTranspose(const PermutationBase<OtherDerived> & other)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>
assignProduct(const Lhs & lhs,const Rhs & 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   protected:
255 
256 };
257 
258 /** \class PermutationMatrix
259   * \ingroup Core_Module
260   *
261   * \brief Permutation matrix
262   *
263   * \param SizeAtCompileTime the number of rows/cols, or Dynamic
264   * \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.
265   * \param IndexType the interger type of the indices
266   *
267   * This class represents a permutation matrix, internally stored as a vector of integers.
268   *
269   * \sa class PermutationBase, class PermutationWrapper, class DiagonalMatrix
270   */
271 
272 namespace internal {
273 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType>
274 struct traits<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType> >
275  : traits<Matrix<IndexType,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
276 {
277   typedef IndexType Index;
278   typedef Matrix<IndexType, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
279 };
280 }
281 
282 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType>
283 class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType> >
284 {
285     typedef PermutationBase<PermutationMatrix> Base;
286     typedef internal::traits<PermutationMatrix> Traits;
287   public:
288 
289     #ifndef EIGEN_PARSED_BY_DOXYGEN
290     typedef typename Traits::IndicesType IndicesType;
291     #endif
292 
293     inline PermutationMatrix()
294     {}
295 
296     /** Constructs an uninitialized permutation matrix of given size.
297       */
298     inline PermutationMatrix(int size) : m_indices(size)
299     {}
300 
301     /** Copy constructor. */
302     template<typename OtherDerived>
303     inline PermutationMatrix(const PermutationBase<OtherDerived>& other)
304       : m_indices(other.indices()) {}
305 
306     #ifndef EIGEN_PARSED_BY_DOXYGEN
307     /** Standard copy constructor. Defined only to prevent a default copy constructor
308       * from hiding the other templated constructor */
309     inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {}
310     #endif
311 
312     /** Generic constructor from expression of the indices. The indices
313       * array has the meaning that the permutations sends each integer i to indices[i].
314       *
315       * \warning It is your responsibility to check that the indices array that you passes actually
316       * describes a permutation, i.e., each value between 0 and n-1 occurs exactly once, where n is the
317       * array's size.
318       */
319     template<typename Other>
320     explicit inline PermutationMatrix(const MatrixBase<Other>& a_indices) : m_indices(a_indices)
321     {}
322 
323     /** Convert the Transpositions \a tr to a permutation matrix */
324     template<typename Other>
325     explicit PermutationMatrix(const TranspositionsBase<Other>& tr)
326       : m_indices(tr.size())
327     {
328       *this = tr;
329     }
330 
331     /** Copies the other permutation into *this */
332     template<typename Other>
333     PermutationMatrix& operator=(const PermutationBase<Other>& other)
334     {
335       m_indices = other.indices();
336       return *this;
337     }
338 
339     /** Assignment from the Transpositions \a tr */
340     template<typename Other>
341     PermutationMatrix& operator=(const TranspositionsBase<Other>& tr)
342     {
343       return Base::operator=(tr.derived());
344     }
345 
346     #ifndef EIGEN_PARSED_BY_DOXYGEN
347     /** This is a special case of the templated operator=. Its purpose is to
348       * prevent a default operator= from hiding the templated operator=.
349       */
350     PermutationMatrix& operator=(const PermutationMatrix& other)
351     {
352       m_indices = other.m_indices;
353       return *this;
354     }
355     #endif
356 
357     /** const version of indices(). */
358     const IndicesType& indices() const { return m_indices; }
359     /** \returns a reference to the stored array representing the permutation. */
360     IndicesType& indices() { return m_indices; }
361 
362 
363     /**** multiplication helpers to hopefully get RVO ****/
364 
365 #ifndef EIGEN_PARSED_BY_DOXYGEN
366     template<typename Other>
367     PermutationMatrix(const Transpose<PermutationBase<Other> >& other)
368       : m_indices(other.nestedPermutation().size())
369     {
370       for (int i=0; i<m_indices.size();++i) m_indices.coeffRef(other.nestedPermutation().indices().coeff(i)) = i;
371     }
372     template<typename Lhs,typename Rhs>
373     PermutationMatrix(internal::PermPermProduct_t, const Lhs& lhs, const Rhs& rhs)
374       : m_indices(lhs.indices().size())
375     {
376       Base::assignProduct(lhs,rhs);
377     }
378 #endif
379 
380   protected:
381 
382     IndicesType m_indices;
383 };
384 
385 
386 namespace internal {
387 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess>
388 struct traits<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess> >
389  : traits<Matrix<IndexType,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
390 {
391   typedef IndexType Index;
392   typedef Map<const Matrix<IndexType, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1>, _PacketAccess> IndicesType;
393 };
394 }
395 
396 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess>
397 class Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess>
398   : public PermutationBase<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess> >
399 {
400     typedef PermutationBase<Map> Base;
401     typedef internal::traits<Map> Traits;
402   public:
403 
404     #ifndef EIGEN_PARSED_BY_DOXYGEN
405     typedef typename Traits::IndicesType IndicesType;
406     typedef typename IndicesType::Scalar Index;
407     #endif
408 
409     inline Map(const Index* indicesPtr)
410       : m_indices(indicesPtr)
411     {}
412 
413     inline Map(const Index* indicesPtr, Index size)
414       : m_indices(indicesPtr,size)
415     {}
416 
417     /** Copies the other permutation into *this */
418     template<typename Other>
419     Map& operator=(const PermutationBase<Other>& other)
420     { return Base::operator=(other.derived()); }
421 
422     /** Assignment from the Transpositions \a tr */
423     template<typename Other>
424     Map& operator=(const TranspositionsBase<Other>& tr)
425     { return Base::operator=(tr.derived()); }
426 
427     #ifndef EIGEN_PARSED_BY_DOXYGEN
428     /** This is a special case of the templated operator=. Its purpose is to
429       * prevent a default operator= from hiding the templated operator=.
430       */
431     Map& operator=(const Map& other)
432     {
433       m_indices = other.m_indices;
434       return *this;
435     }
436     #endif
437 
438     /** const version of indices(). */
439     const IndicesType& indices() const { return m_indices; }
440     /** \returns a reference to the stored array representing the permutation. */
441     IndicesType& indices() { return m_indices; }
442 
443   protected:
444 
445     IndicesType m_indices;
446 };
447 
448 /** \class PermutationWrapper
449   * \ingroup Core_Module
450   *
451   * \brief Class to view a vector of integers as a permutation matrix
452   *
453   * \param _IndicesType the type of the vector of integer (can be any compatible expression)
454   *
455   * This class allows to view any vector expression of integers as a permutation matrix.
456   *
457   * \sa class PermutationBase, class PermutationMatrix
458   */
459 
460 struct PermutationStorage {};
461 
462 template<typename _IndicesType> class TranspositionsWrapper;
463 namespace internal {
464 template<typename _IndicesType>
465 struct traits<PermutationWrapper<_IndicesType> >
466 {
467   typedef PermutationStorage StorageKind;
468   typedef typename _IndicesType::Scalar Scalar;
469   typedef typename _IndicesType::Scalar Index;
470   typedef _IndicesType IndicesType;
471   enum {
472     RowsAtCompileTime = _IndicesType::SizeAtCompileTime,
473     ColsAtCompileTime = _IndicesType::SizeAtCompileTime,
474     MaxRowsAtCompileTime = IndicesType::MaxRowsAtCompileTime,
475     MaxColsAtCompileTime = IndicesType::MaxColsAtCompileTime,
476     Flags = 0,
477     CoeffReadCost = _IndicesType::CoeffReadCost
478   };
479 };
480 }
481 
482 template<typename _IndicesType>
483 class PermutationWrapper : public PermutationBase<PermutationWrapper<_IndicesType> >
484 {
485     typedef PermutationBase<PermutationWrapper> Base;
486     typedef internal::traits<PermutationWrapper> Traits;
487   public:
488 
489     #ifndef EIGEN_PARSED_BY_DOXYGEN
490     typedef typename Traits::IndicesType IndicesType;
491     #endif
492 
493     inline PermutationWrapper(const IndicesType& a_indices)
494       : m_indices(a_indices)
495     {}
496 
497     /** const version of indices(). */
498     const typename internal::remove_all<typename IndicesType::Nested>::type&
499     indices() const { return m_indices; }
500 
501   protected:
502 
503     typename IndicesType::Nested m_indices;
504 };
505 
506 /** \returns the matrix with the permutation applied to the columns.
507   */
508 template<typename Derived, typename PermutationDerived>
509 inline const internal::permut_matrix_product_retval<PermutationDerived, Derived, OnTheRight>
510 operator*(const MatrixBase<Derived>& matrix,
511           const PermutationBase<PermutationDerived> &permutation)
512 {
513   return internal::permut_matrix_product_retval
514            <PermutationDerived, Derived, OnTheRight>
515            (permutation.derived(), matrix.derived());
516 }
517 
518 /** \returns the matrix with the permutation applied to the rows.
519   */
520 template<typename Derived, typename PermutationDerived>
521 inline const internal::permut_matrix_product_retval
522                <PermutationDerived, Derived, OnTheLeft>
523 operator*(const PermutationBase<PermutationDerived> &permutation,
524           const MatrixBase<Derived>& matrix)
525 {
526   return internal::permut_matrix_product_retval
527            <PermutationDerived, Derived, OnTheLeft>
528            (permutation.derived(), matrix.derived());
529 }
530 
531 namespace internal {
532 
533 template<typename PermutationType, typename MatrixType, int Side, bool Transposed>
534 struct traits<permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> >
535 {
536   typedef typename MatrixType::PlainObject ReturnType;
537 };
538 
539 template<typename PermutationType, typename MatrixType, int Side, bool Transposed>
540 struct permut_matrix_product_retval
541  : public ReturnByValue<permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> >
542 {
543     typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned;
544     typedef typename MatrixType::Index Index;
545 
546     permut_matrix_product_retval(const PermutationType& perm, const MatrixType& matrix)
547       : m_permutation(perm), m_matrix(matrix)
548     {}
549 
550     inline Index rows() const { return m_matrix.rows(); }
551     inline Index cols() const { return m_matrix.cols(); }
552 
553     template<typename Dest> inline void evalTo(Dest& dst) const
554     {
555       const Index n = Side==OnTheLeft ? rows() : cols();
556       // FIXME we need an is_same for expression that is not sensitive to constness. For instance
557       // is_same_xpr<Block<const Matrix>, Block<Matrix> >::value should be true.
558       if(    is_same<MatrixTypeNestedCleaned,Dest>::value
559           && blas_traits<MatrixTypeNestedCleaned>::HasUsableDirectAccess
560           && blas_traits<Dest>::HasUsableDirectAccess
561           && extract_data(dst) == extract_data(m_matrix))
562       {
563         // apply the permutation inplace
564         Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(m_permutation.size());
565         mask.fill(false);
566         Index r = 0;
567         while(r < m_permutation.size())
568         {
569           // search for the next seed
570           while(r<m_permutation.size() && mask[r]) r++;
571           if(r>=m_permutation.size())
572             break;
573           // we got one, let's follow it until we are back to the seed
574           Index k0 = r++;
575           Index kPrev = k0;
576           mask.coeffRef(k0) = true;
577           for(Index k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k))
578           {
579                   Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>(dst, k)
580             .swap(Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
581                        (dst,((Side==OnTheLeft) ^ Transposed) ? k0 : kPrev));
582 
583             mask.coeffRef(k) = true;
584             kPrev = k;
585           }
586         }
587       }
588       else
589       {
590         for(int i = 0; i < n; ++i)
591         {
592           Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
593                (dst, ((Side==OnTheLeft) ^ Transposed) ? m_permutation.indices().coeff(i) : i)
594 
595           =
596 
597           Block<const MatrixTypeNestedCleaned,Side==OnTheLeft ? 1 : MatrixType::RowsAtCompileTime,Side==OnTheRight ? 1 : MatrixType::ColsAtCompileTime>
598                (m_matrix, ((Side==OnTheRight) ^ Transposed) ? m_permutation.indices().coeff(i) : i);
599         }
600       }
601     }
602 
603   protected:
604     const PermutationType& m_permutation;
605     typename MatrixType::Nested m_matrix;
606 };
607 
608 /* Template partial specialization for transposed/inverse permutations */
609 
610 template<typename Derived>
611 struct traits<Transpose<PermutationBase<Derived> > >
612  : traits<Derived>
613 {};
614 
615 } // end namespace internal
616 
617 template<typename Derived>
618 class Transpose<PermutationBase<Derived> >
619   : public EigenBase<Transpose<PermutationBase<Derived> > >
620 {
621     typedef Derived PermutationType;
622     typedef typename PermutationType::IndicesType IndicesType;
623     typedef typename PermutationType::PlainPermutationType PlainPermutationType;
624   public:
625 
626     #ifndef EIGEN_PARSED_BY_DOXYGEN
627     typedef internal::traits<PermutationType> Traits;
628     typedef typename Derived::DenseMatrixType DenseMatrixType;
629     enum {
630       Flags = Traits::Flags,
631       CoeffReadCost = Traits::CoeffReadCost,
632       RowsAtCompileTime = Traits::RowsAtCompileTime,
633       ColsAtCompileTime = Traits::ColsAtCompileTime,
634       MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime,
635       MaxColsAtCompileTime = Traits::MaxColsAtCompileTime
636     };
637     typedef typename Traits::Scalar Scalar;
638     #endif
639 
640     Transpose(const PermutationType& p) : m_permutation(p) {}
641 
642     inline int rows() const { return m_permutation.rows(); }
643     inline int cols() const { return m_permutation.cols(); }
644 
645     #ifndef EIGEN_PARSED_BY_DOXYGEN
646     template<typename DenseDerived>
647     void evalTo(MatrixBase<DenseDerived>& other) const
648     {
649       other.setZero();
650       for (int i=0; i<rows();++i)
651         other.coeffRef(i, m_permutation.indices().coeff(i)) = typename DenseDerived::Scalar(1);
652     }
653     #endif
654 
655     /** \return the equivalent permutation matrix */
656     PlainPermutationType eval() const { return *this; }
657 
658     DenseMatrixType toDenseMatrix() const { return *this; }
659 
660     /** \returns the matrix with the inverse permutation applied to the columns.
661       */
662     template<typename OtherDerived> friend
663     inline const internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheRight, true>
664     operator*(const MatrixBase<OtherDerived>& matrix, const Transpose& trPerm)
665     {
666       return internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheRight, true>(trPerm.m_permutation, matrix.derived());
667     }
668 
669     /** \returns the matrix with the inverse permutation applied to the rows.
670       */
671     template<typename OtherDerived>
672     inline const internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheLeft, true>
673     operator*(const MatrixBase<OtherDerived>& matrix) const
674     {
675       return internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheLeft, true>(m_permutation, matrix.derived());
676     }
677 
678     const PermutationType& nestedPermutation() const { return m_permutation; }
679 
680   protected:
681     const PermutationType& m_permutation;
682 };
683 
684 template<typename Derived>
685 const PermutationWrapper<const Derived> MatrixBase<Derived>::asPermutation() const
686 {
687   return derived();
688 }
689 
690 } // end namespace Eigen
691 
692 #endif // EIGEN_PERMUTATIONMATRIX_H
693