Eigne Matrix Class Library
Dependents: Eigen_test Odometry_test AttitudeEstimation_usingTicker MPU9250_Quaternion_Binary_Serial ... more
PermutationMatrix.h
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> 00005 // Copyright (C) 2009-2011 Gael Guennebaud <gael.guennebaud@inria.fr> 00006 // 00007 // This Source Code Form is subject to the terms of the Mozilla 00008 // Public License v. 2.0. If a copy of the MPL was not distributed 00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00010 00011 #ifndef EIGEN_PERMUTATIONMATRIX_H 00012 #define EIGEN_PERMUTATIONMATRIX_H 00013 00014 namespace Eigen { 00015 00016 template<int RowCol,typename IndicesType,typename MatrixType, typename StorageKind> class PermutedImpl; 00017 00018 /** \class PermutationBase 00019 * \ingroup Core_Module 00020 * 00021 * \brief Base class for permutations 00022 * 00023 * \param Derived the derived class 00024 * 00025 * This class is the base class for all expressions representing a permutation matrix, 00026 * internally stored as a vector of integers. 00027 * The convention followed here is that if \f$ \sigma \f$ is a permutation, the corresponding permutation matrix 00028 * \f$ P_\sigma \f$ is such that if \f$ (e_1,\ldots,e_p) \f$ is the canonical basis, we have: 00029 * \f[ P_\sigma(e_i) = e_{\sigma(i)}. \f] 00030 * This convention ensures that for any two permutations \f$ \sigma, \tau \f$, we have: 00031 * \f[ P_{\sigma\circ\tau} = P_\sigma P_\tau. \f] 00032 * 00033 * Permutation matrices are square and invertible. 00034 * 00035 * Notice that in addition to the member functions and operators listed here, there also are non-member 00036 * operator* to multiply any kind of permutation object with any kind of matrix expression (MatrixBase) 00037 * on either side. 00038 * 00039 * \sa class PermutationMatrix, class PermutationWrapper 00040 */ 00041 00042 namespace internal { 00043 00044 template<typename PermutationType, typename MatrixType, int Side, bool Transposed=false> 00045 struct permut_matrix_product_retval; 00046 template<typename PermutationType, typename MatrixType, int Side, bool Transposed=false> 00047 struct permut_sparsematrix_product_retval; 00048 enum PermPermProduct_t {PermPermProduct}; 00049 00050 } // end namespace internal 00051 00052 template<typename Derived> 00053 class PermutationBase : public EigenBase<Derived> 00054 { 00055 typedef internal::traits<Derived> Traits; 00056 typedef EigenBase<Derived> Base; 00057 public: 00058 00059 #ifndef EIGEN_PARSED_BY_DOXYGEN 00060 typedef typename Traits::IndicesType IndicesType; 00061 enum { 00062 Flags = Traits::Flags, 00063 CoeffReadCost = Traits::CoeffReadCost, 00064 RowsAtCompileTime = Traits::RowsAtCompileTime, 00065 ColsAtCompileTime = Traits::ColsAtCompileTime, 00066 MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime, 00067 MaxColsAtCompileTime = Traits::MaxColsAtCompileTime 00068 }; 00069 typedef typename Traits::Scalar Scalar; 00070 typedef typename Traits::Index Index; 00071 typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime,0,MaxRowsAtCompileTime,MaxColsAtCompileTime> 00072 DenseMatrixType; 00073 typedef PermutationMatrix<IndicesType::SizeAtCompileTime,IndicesType::MaxSizeAtCompileTime,Index> 00074 PlainPermutationType; 00075 using Base::derived ; 00076 #endif 00077 00078 /** Copies the other permutation into *this */ 00079 template<typename OtherDerived> 00080 Derived& operator=(const PermutationBase<OtherDerived>& other) 00081 { 00082 indices() = other.indices(); 00083 return derived (); 00084 } 00085 00086 /** Assignment from the Transpositions \a tr */ 00087 template<typename OtherDerived> 00088 Derived& operator=(const TranspositionsBase<OtherDerived>& tr) 00089 { 00090 setIdentity(tr.size()); 00091 for(Index k=size ()-1; k>=0; --k) 00092 applyTranspositionOnTheRight(k,tr.coeff(k)); 00093 return derived (); 00094 } 00095 00096 #ifndef EIGEN_PARSED_BY_DOXYGEN 00097 /** This is a special case of the templated operator=. Its purpose is to 00098 * prevent a default operator= from hiding the templated operator=. 00099 */ 00100 Derived& operator=(const PermutationBase& other) 00101 { 00102 indices() = other.indices(); 00103 return derived (); 00104 } 00105 #endif 00106 00107 /** \returns the number of rows */ 00108 inline Index rows () const { return Index(indices().size ()); } 00109 00110 /** \returns the number of columns */ 00111 inline Index cols () const { return Index(indices().size ()); } 00112 00113 /** \returns the size of a side of the respective square matrix, i.e., the number of indices */ 00114 inline Index size () const { return Index(indices().size ()); } 00115 00116 #ifndef EIGEN_PARSED_BY_DOXYGEN 00117 template<typename DenseDerived> 00118 void evalTo(MatrixBase<DenseDerived>& other) const 00119 { 00120 other.setZero(); 00121 for (int i=0; i<rows ();++i) 00122 other.coeffRef(indices().coeff(i),i) = typename DenseDerived::Scalar(1); 00123 } 00124 #endif 00125 00126 /** \returns a Matrix object initialized from this permutation matrix. Notice that it 00127 * is inefficient to return this Matrix object by value. For efficiency, favor using 00128 * the Matrix constructor taking EigenBase objects. 00129 */ 00130 DenseMatrixType toDenseMatrix () const 00131 { 00132 return derived (); 00133 } 00134 00135 /** const version of indices(). */ 00136 const IndicesType& indices() const { return derived ().indices(); } 00137 /** \returns a reference to the stored array representing the permutation. */ 00138 IndicesType& indices () { return derived ().indices(); } 00139 00140 /** Resizes to given size. 00141 */ 00142 inline void resize(Index newSize) 00143 { 00144 indices().resize(newSize); 00145 } 00146 00147 /** Sets *this to be the identity permutation matrix */ 00148 void setIdentity() 00149 { 00150 for(Index i = 0; i < size (); ++i) 00151 indices().coeffRef(i) = i; 00152 } 00153 00154 /** Sets *this to be the identity permutation matrix of given size. 00155 */ 00156 void setIdentity(Index newSize) 00157 { 00158 resize(newSize); 00159 setIdentity(); 00160 } 00161 00162 /** Multiplies *this by the transposition \f$(ij)\f$ on the left. 00163 * 00164 * \returns a reference to *this. 00165 * 00166 * \warning This is much slower than applyTranspositionOnTheRight(int,int): 00167 * this has linear complexity and requires a lot of branching. 00168 * 00169 * \sa applyTranspositionOnTheRight(int,int) 00170 */ 00171 Derived& applyTranspositionOnTheLeft(Index i, Index j) 00172 { 00173 eigen_assert(i>=0 && j>=0 && i<size () && j<size ()); 00174 for(Index k = 0; k < size (); ++k) 00175 { 00176 if(indices().coeff(k) == i) indices().coeffRef(k) = j; 00177 else if(indices().coeff(k) == j) indices().coeffRef(k) = i; 00178 } 00179 return derived (); 00180 } 00181 00182 /** Multiplies *this by the transposition \f$(ij)\f$ on the right. 00183 * 00184 * \returns a reference to *this. 00185 * 00186 * This is a fast operation, it only consists in swapping two indices. 00187 * 00188 * \sa applyTranspositionOnTheLeft(int,int) 00189 */ 00190 Derived& applyTranspositionOnTheRight(Index i, Index j) 00191 { 00192 eigen_assert(i>=0 && j>=0 && i<size () && j<size ()); 00193 std::swap(indices().coeffRef(i), indices().coeffRef(j)); 00194 return derived (); 00195 } 00196 00197 /** \returns the inverse permutation matrix. 00198 * 00199 * \note \note_try_to_help_rvo 00200 */ 00201 inline Transpose<PermutationBase> inverse () const 00202 { return derived (); } 00203 /** \returns the tranpose permutation matrix. 00204 * 00205 * \note \note_try_to_help_rvo 00206 */ 00207 inline Transpose<PermutationBase> transpose () const 00208 { return derived (); } 00209 00210 /**** multiplication helpers to hopefully get RVO ****/ 00211 00212 00213 #ifndef EIGEN_PARSED_BY_DOXYGEN 00214 protected: 00215 template<typename OtherDerived> 00216 void assignTranspose(const PermutationBase<OtherDerived>& other) 00217 { 00218 for (int i=0; i<rows ();++i) indices().coeffRef(other.indices().coeff(i)) = i; 00219 } 00220 template<typename Lhs,typename Rhs> 00221 void assignProduct(const Lhs& lhs, const Rhs& rhs) 00222 { 00223 eigen_assert(lhs.cols() == rhs.rows()); 00224 for (int i=0; i<rows ();++i) indices().coeffRef(i) = lhs.indices().coeff(rhs.indices().coeff(i)); 00225 } 00226 #endif 00227 00228 public: 00229 00230 /** \returns the product permutation matrix. 00231 * 00232 * \note \note_try_to_help_rvo 00233 */ 00234 template<typename Other> 00235 inline PlainPermutationType operator* (const PermutationBase<Other>& other) const 00236 { return PlainPermutationType(internal::PermPermProduct, derived (), other.derived ()); } 00237 00238 /** \returns the product of a permutation with another inverse permutation. 00239 * 00240 * \note \note_try_to_help_rvo 00241 */ 00242 template<typename Other> 00243 inline PlainPermutationType operator* (const Transpose<PermutationBase<Other> >& other) const 00244 { return PlainPermutationType(internal::PermPermProduct, *this, other.eval()); } 00245 00246 /** \returns the product of an inverse permutation with another permutation. 00247 * 00248 * \note \note_try_to_help_rvo 00249 */ 00250 template<typename Other> friend 00251 inline PlainPermutationType operator* (const Transpose<PermutationBase<Other> >& other, const PermutationBase& perm) 00252 { return PlainPermutationType(internal::PermPermProduct, other.eval(), perm); } 00253 00254 /** \returns the determinant of the permutation matrix, which is either 1 or -1 depending on the parity of the permutation. 00255 * 00256 * This function is O(\c n) procedure allocating a buffer of \c n booleans. 00257 */ 00258 Index determinant () const 00259 { 00260 Index res = 1; 00261 Index n = size (); 00262 Matrix<bool,RowsAtCompileTime,1,0,MaxRowsAtCompileTime> mask(n); 00263 mask.fill(false); 00264 Index r = 0; 00265 while(r < n) 00266 { 00267 // search for the next seed 00268 while(r<n && mask[r]) r++; 00269 if(r>=n) 00270 break; 00271 // we got one, let's follow it until we are back to the seed 00272 Index k0 = r++; 00273 mask.coeffRef(k0) = true; 00274 for(Index k=indices().coeff(k0); k!=k0; k=indices().coeff(k)) 00275 { 00276 mask.coeffRef(k) = true; 00277 res = -res; 00278 } 00279 } 00280 return res; 00281 } 00282 00283 protected: 00284 00285 }; 00286 00287 /** \class PermutationMatrix 00288 * \ingroup Core_Module 00289 * 00290 * \brief Permutation matrix 00291 * 00292 * \param SizeAtCompileTime the number of rows/cols, or Dynamic 00293 * \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. 00294 * \param IndexType the interger type of the indices 00295 * 00296 * This class represents a permutation matrix, internally stored as a vector of integers. 00297 * 00298 * \sa class PermutationBase, class PermutationWrapper, class DiagonalMatrix 00299 */ 00300 00301 namespace internal { 00302 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType> 00303 struct traits<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType> > 00304 : traits<Matrix<IndexType,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> > 00305 { 00306 typedef IndexType Index; 00307 typedef Matrix<IndexType, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType; 00308 }; 00309 } 00310 00311 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType> 00312 class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType> > 00313 { 00314 typedef PermutationBase<PermutationMatrix> Base; 00315 typedef internal::traits<PermutationMatrix> Traits; 00316 public: 00317 00318 #ifndef EIGEN_PARSED_BY_DOXYGEN 00319 typedef typename Traits::IndicesType IndicesType; 00320 #endif 00321 00322 inline PermutationMatrix() 00323 {} 00324 00325 /** Constructs an uninitialized permutation matrix of given size. 00326 */ 00327 inline PermutationMatrix(int size ) : m_indices(size) 00328 {} 00329 00330 /** Copy constructor. */ 00331 template<typename OtherDerived> 00332 inline PermutationMatrix(const PermutationBase<OtherDerived>& other) 00333 : m_indices(other.indices()) {} 00334 00335 #ifndef EIGEN_PARSED_BY_DOXYGEN 00336 /** Standard copy constructor. Defined only to prevent a default copy constructor 00337 * from hiding the other templated constructor */ 00338 inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {} 00339 #endif 00340 00341 /** Generic constructor from expression of the indices. The indices 00342 * array has the meaning that the permutations sends each integer i to indices[i]. 00343 * 00344 * \warning It is your responsibility to check that the indices array that you passes actually 00345 * describes a permutation, i.e., each value between 0 and n-1 occurs exactly once, where n is the 00346 * array's size. 00347 */ 00348 template<typename Other> 00349 explicit inline PermutationMatrix(const MatrixBase<Other>& a_indices) : m_indices(a_indices) 00350 {} 00351 00352 /** Convert the Transpositions \a tr to a permutation matrix */ 00353 template<typename Other> 00354 explicit PermutationMatrix(const TranspositionsBase<Other>& tr) 00355 : m_indices(tr.size ()) 00356 { 00357 *this = tr; 00358 } 00359 00360 /** Copies the other permutation into *this */ 00361 template<typename Other> 00362 PermutationMatrix& operator=(const PermutationBase<Other>& other) 00363 { 00364 m_indices = other.indices(); 00365 return *this; 00366 } 00367 00368 /** Assignment from the Transpositions \a tr */ 00369 template<typename Other> 00370 PermutationMatrix& operator=(const TranspositionsBase<Other>& tr) 00371 { 00372 return Base::operator=(tr.derived()); 00373 } 00374 00375 #ifndef EIGEN_PARSED_BY_DOXYGEN 00376 /** This is a special case of the templated operator=. Its purpose is to 00377 * prevent a default operator= from hiding the templated operator=. 00378 */ 00379 PermutationMatrix& operator=(const PermutationMatrix& other) 00380 { 00381 m_indices = other.m_indices; 00382 return *this; 00383 } 00384 #endif 00385 00386 /** const version of indices(). */ 00387 const IndicesType& indices() const { return m_indices; } 00388 /** \returns a reference to the stored array representing the permutation. */ 00389 IndicesType& indices () { return m_indices; } 00390 00391 00392 /**** multiplication helpers to hopefully get RVO ****/ 00393 00394 #ifndef EIGEN_PARSED_BY_DOXYGEN 00395 template<typename Other> 00396 PermutationMatrix(const Transpose<PermutationBase<Other> >& other) 00397 : m_indices(other.nestedPermutation().size ()) 00398 { 00399 for (int i=0; i<m_indices.size();++i) m_indices.coeffRef(other.nestedPermutation().indices().coeff(i)) = i; 00400 } 00401 template<typename Lhs,typename Rhs> 00402 PermutationMatrix(internal::PermPermProduct_t, const Lhs& lhs, const Rhs& rhs) 00403 : m_indices(lhs.indices().size ()) 00404 { 00405 Base::assignProduct(lhs,rhs); 00406 } 00407 #endif 00408 00409 protected: 00410 00411 IndicesType m_indices; 00412 }; 00413 00414 00415 namespace internal { 00416 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess> 00417 struct traits<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess> > 00418 : traits<Matrix<IndexType,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> > 00419 { 00420 typedef IndexType Index; 00421 typedef Map<const Matrix<IndexType, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1>, _PacketAccess> IndicesType; 00422 }; 00423 } 00424 00425 template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess> 00426 class Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess> 00427 : public PermutationBase<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess> > 00428 { 00429 typedef PermutationBase<Map> Base; 00430 typedef internal::traits<Map> Traits; 00431 public: 00432 00433 #ifndef EIGEN_PARSED_BY_DOXYGEN 00434 typedef typename Traits::IndicesType IndicesType; 00435 typedef typename IndicesType::Scalar Index; 00436 #endif 00437 00438 inline Map(const Index* indicesPtr) 00439 : m_indices(indicesPtr) 00440 {} 00441 00442 inline Map(const Index* indicesPtr, Index size) 00443 : m_indices(indicesPtr,size) 00444 {} 00445 00446 /** Copies the other permutation into *this */ 00447 template<typename Other> 00448 Map& operator=(const PermutationBase<Other>& other) 00449 { return Base::operator=(other.derived()); } 00450 00451 /** Assignment from the Transpositions \a tr */ 00452 template<typename Other> 00453 Map& operator=(const TranspositionsBase<Other>& tr) 00454 { return Base::operator=(tr.derived()); } 00455 00456 #ifndef EIGEN_PARSED_BY_DOXYGEN 00457 /** This is a special case of the templated operator=. Its purpose is to 00458 * prevent a default operator= from hiding the templated operator=. 00459 */ 00460 Map& operator=(const Map& other) 00461 { 00462 m_indices = other.m_indices; 00463 return *this; 00464 } 00465 #endif 00466 00467 /** const version of indices(). */ 00468 const IndicesType& indices() const { return m_indices; } 00469 /** \returns a reference to the stored array representing the permutation. */ 00470 IndicesType& indices() { return m_indices; } 00471 00472 protected: 00473 00474 IndicesType m_indices; 00475 }; 00476 00477 /** \class PermutationWrapper 00478 * \ingroup Core_Module 00479 * 00480 * \brief Class to view a vector of integers as a permutation matrix 00481 * 00482 * \param _IndicesType the type of the vector of integer (can be any compatible expression) 00483 * 00484 * This class allows to view any vector expression of integers as a permutation matrix. 00485 * 00486 * \sa class PermutationBase, class PermutationMatrix 00487 */ 00488 00489 struct PermutationStorage {}; 00490 00491 template<typename _IndicesType> class TranspositionsWrapper; 00492 namespace internal { 00493 template<typename _IndicesType> 00494 struct traits<PermutationWrapper<_IndicesType> > 00495 { 00496 typedef PermutationStorage StorageKind; 00497 typedef typename _IndicesType::Scalar Scalar; 00498 typedef typename _IndicesType::Scalar Index; 00499 typedef _IndicesType IndicesType; 00500 enum { 00501 RowsAtCompileTime = _IndicesType::SizeAtCompileTime, 00502 ColsAtCompileTime = _IndicesType::SizeAtCompileTime, 00503 MaxRowsAtCompileTime = IndicesType::MaxRowsAtCompileTime, 00504 MaxColsAtCompileTime = IndicesType::MaxColsAtCompileTime, 00505 Flags = 0, 00506 CoeffReadCost = _IndicesType::CoeffReadCost 00507 }; 00508 }; 00509 } 00510 00511 template<typename _IndicesType> 00512 class PermutationWrapper : public PermutationBase<PermutationWrapper<_IndicesType> > 00513 { 00514 typedef PermutationBase<PermutationWrapper> Base; 00515 typedef internal::traits<PermutationWrapper> Traits; 00516 public: 00517 00518 #ifndef EIGEN_PARSED_BY_DOXYGEN 00519 typedef typename Traits::IndicesType IndicesType; 00520 #endif 00521 00522 inline PermutationWrapper(const IndicesType& a_indices) 00523 : m_indices(a_indices) 00524 {} 00525 00526 /** const version of indices(). */ 00527 const typename internal::remove_all<typename IndicesType::Nested>::type& 00528 indices() const { return m_indices; } 00529 00530 protected: 00531 00532 typename IndicesType::Nested m_indices; 00533 }; 00534 00535 /** \returns the matrix with the permutation applied to the columns. 00536 */ 00537 template<typename Derived, typename PermutationDerived> 00538 inline const internal::permut_matrix_product_retval<PermutationDerived, Derived, OnTheRight> 00539 operator* (const MatrixBase<Derived>& matrix, 00540 const PermutationBase<PermutationDerived> &permutation) 00541 { 00542 return internal::permut_matrix_product_retval 00543 <PermutationDerived, Derived, OnTheRight> 00544 (permutation.derived (), matrix.derived()); 00545 } 00546 00547 /** \returns the matrix with the permutation applied to the rows. 00548 */ 00549 template<typename Derived, typename PermutationDerived> 00550 inline const internal::permut_matrix_product_retval 00551 <PermutationDerived, Derived, OnTheLeft> 00552 operator* (const PermutationBase<PermutationDerived> &permutation, 00553 const MatrixBase<Derived>& matrix) 00554 { 00555 return internal::permut_matrix_product_retval 00556 <PermutationDerived, Derived, OnTheLeft> 00557 (permutation.derived (), matrix.derived()); 00558 } 00559 00560 namespace internal { 00561 00562 template<typename PermutationType, typename MatrixType, int Side, bool Transposed> 00563 struct traits<permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> > 00564 { 00565 typedef typename MatrixType::PlainObject ReturnType; 00566 }; 00567 00568 template<typename PermutationType, typename MatrixType, int Side, bool Transposed> 00569 struct permut_matrix_product_retval 00570 : public ReturnByValue<permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> > 00571 { 00572 typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned; 00573 typedef typename MatrixType::Index Index; 00574 00575 permut_matrix_product_retval(const PermutationType& perm, const MatrixType& matrix) 00576 : m_permutation(perm), m_matrix(matrix) 00577 {} 00578 00579 inline Index rows() const { return m_matrix.rows(); } 00580 inline Index cols() const { return m_matrix.cols(); } 00581 00582 template<typename Dest> inline void evalTo(Dest& dst) const 00583 { 00584 const Index n = Side==OnTheLeft ? rows() : cols(); 00585 // FIXME we need an is_same for expression that is not sensitive to constness. For instance 00586 // is_same_xpr<Block<const Matrix>, Block<Matrix> >::value should be true. 00587 if( is_same<MatrixTypeNestedCleaned,Dest>::value 00588 && blas_traits<MatrixTypeNestedCleaned>::HasUsableDirectAccess 00589 && blas_traits<Dest>::HasUsableDirectAccess 00590 && extract_data(dst) == extract_data(m_matrix)) 00591 { 00592 // apply the permutation inplace 00593 Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(m_permutation.size()); 00594 mask.fill(false); 00595 Index r = 0; 00596 while(r < m_permutation.size()) 00597 { 00598 // search for the next seed 00599 while(r<m_permutation.size() && mask[r]) r++; 00600 if(r>=m_permutation.size()) 00601 break; 00602 // we got one, let's follow it until we are back to the seed 00603 Index k0 = r++; 00604 Index kPrev = k0; 00605 mask.coeffRef(k0) = true; 00606 for(Index k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k)) 00607 { 00608 Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>(dst, k) 00609 .swap(Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime> 00610 (dst,((Side==OnTheLeft) ^ Transposed) ? k0 : kPrev)); 00611 00612 mask.coeffRef(k) = true; 00613 kPrev = k; 00614 } 00615 } 00616 } 00617 else 00618 { 00619 for(int i = 0; i < n; ++i) 00620 { 00621 Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime> 00622 (dst, ((Side==OnTheLeft) ^ Transposed) ? m_permutation.indices().coeff(i) : i) 00623 00624 = 00625 00626 Block<const MatrixTypeNestedCleaned,Side==OnTheLeft ? 1 : MatrixType::RowsAtCompileTime,Side==OnTheRight ? 1 : MatrixType::ColsAtCompileTime> 00627 (m_matrix, ((Side==OnTheRight) ^ Transposed) ? m_permutation.indices().coeff(i) : i); 00628 } 00629 } 00630 } 00631 00632 protected: 00633 const PermutationType& m_permutation; 00634 typename MatrixType::Nested m_matrix; 00635 }; 00636 00637 /* Template partial specialization for transposed/inverse permutations */ 00638 00639 template<typename Derived> 00640 struct traits<Transpose<PermutationBase<Derived> > > 00641 : traits<Derived> 00642 {}; 00643 00644 } // end namespace internal 00645 00646 template<typename Derived> 00647 class Transpose<PermutationBase<Derived> > 00648 : public EigenBase<Transpose<PermutationBase<Derived> > > 00649 { 00650 typedef Derived PermutationType; 00651 typedef typename PermutationType::IndicesType IndicesType; 00652 typedef typename PermutationType::PlainPermutationType PlainPermutationType; 00653 public: 00654 00655 #ifndef EIGEN_PARSED_BY_DOXYGEN 00656 typedef internal::traits<PermutationType> Traits; 00657 typedef typename Derived::DenseMatrixType DenseMatrixType; 00658 enum { 00659 Flags = Traits::Flags, 00660 CoeffReadCost = Traits::CoeffReadCost, 00661 RowsAtCompileTime = Traits::RowsAtCompileTime, 00662 ColsAtCompileTime = Traits::ColsAtCompileTime, 00663 MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime, 00664 MaxColsAtCompileTime = Traits::MaxColsAtCompileTime 00665 }; 00666 typedef typename Traits::Scalar Scalar; 00667 #endif 00668 00669 Transpose(const PermutationType& p) : m_permutation(p) {} 00670 00671 inline int rows() const { return m_permutation.rows(); } 00672 inline int cols() const { return m_permutation.cols(); } 00673 00674 #ifndef EIGEN_PARSED_BY_DOXYGEN 00675 template<typename DenseDerived> 00676 void evalTo(MatrixBase<DenseDerived>& other) const 00677 { 00678 other.setZero(); 00679 for (int i=0; i<rows();++i) 00680 other.coeffRef(i, m_permutation.indices().coeff(i)) = typename DenseDerived::Scalar(1); 00681 } 00682 #endif 00683 00684 /** \return the equivalent permutation matrix */ 00685 PlainPermutationType eval() const { return *this; } 00686 00687 DenseMatrixType toDenseMatrix() const { return *this; } 00688 00689 /** \returns the matrix with the inverse permutation applied to the columns. 00690 */ 00691 template<typename OtherDerived> friend 00692 inline const internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheRight, true> 00693 operator* (const MatrixBase<OtherDerived>& matrix, const Transpose& trPerm) 00694 { 00695 return internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheRight, true>(trPerm.m_permutation, matrix.derived()); 00696 } 00697 00698 /** \returns the matrix with the inverse permutation applied to the rows. 00699 */ 00700 template<typename OtherDerived> 00701 inline const internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheLeft, true> 00702 operator* (const MatrixBase<OtherDerived>& matrix) const 00703 { 00704 return internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheLeft, true>(m_permutation, matrix.derived()); 00705 } 00706 00707 const PermutationType& nestedPermutation() const { return m_permutation; } 00708 00709 protected: 00710 const PermutationType& m_permutation; 00711 }; 00712 00713 template<typename Derived> 00714 const PermutationWrapper<const Derived> MatrixBase<Derived>::asPermutation() const 00715 { 00716 return derived(); 00717 } 00718 00719 } // end namespace Eigen 00720 00721 #endif // EIGEN_PERMUTATIONMATRIX_H
Generated on Tue Jul 12 2022 17:46:58 by 1.7.2