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