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