PermutationMatrix.h
Go to the documentation of this file.
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-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #ifndef EIGEN_PERMUTATIONMATRIX_H
12 #define EIGEN_PERMUTATIONMATRIX_H
13 
14 // IWYU pragma: private
15 #include "./InternalHeaderCheck.h"
16 
17 namespace Eigen {
18 
19 namespace internal {
20 
22 
23 } // end namespace internal
24 
48 template <typename Derived>
49 class PermutationBase : public EigenBase<Derived> {
52 
53  public:
54 #ifndef EIGEN_PARSED_BY_DOXYGEN
55  typedef typename Traits::IndicesType IndicesType;
56  enum {
57  Flags = Traits::Flags,
58  RowsAtCompileTime = Traits::RowsAtCompileTime,
59  ColsAtCompileTime = Traits::ColsAtCompileTime,
60  MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime,
61  MaxColsAtCompileTime = Traits::MaxColsAtCompileTime
62  };
63  typedef typename Traits::StorageIndex StorageIndex;
69  using Base::derived;
71  typedef void Scalar;
72 #endif
73 
75  template <typename OtherDerived>
76  Derived& operator=(const PermutationBase<OtherDerived>& other) {
77  indices() = other.indices();
78  return derived();
79  }
80 
82  template <typename OtherDerived>
84  setIdentity(tr.size());
85  for (Index k = size() - 1; k >= 0; --k) applyTranspositionOnTheRight(k, tr.coeff(k));
86  return derived();
87  }
88 
90  inline EIGEN_DEVICE_FUNC Index rows() const { return Index(indices().size()); }
91 
93  inline EIGEN_DEVICE_FUNC Index cols() const { return Index(indices().size()); }
94 
96  inline EIGEN_DEVICE_FUNC Index size() const { return Index(indices().size()); }
97 
98 #ifndef EIGEN_PARSED_BY_DOXYGEN
99  template <typename DenseDerived>
100  void evalTo(MatrixBase<DenseDerived>& other) const {
101  other.setZero();
102  for (Index i = 0; i < rows(); ++i) other.coeffRef(indices().coeff(i), i) = typename DenseDerived::Scalar(1);
103  }
104 #endif
105 
110  DenseMatrixType toDenseMatrix() const { return derived(); }
111 
113  const IndicesType& indices() const { return derived().indices(); }
115  IndicesType& indices() { return derived().indices(); }
116 
119  inline void resize(Index newSize) { indices().resize(newSize); }
120 
122  void setIdentity() {
124  for (StorageIndex i = 0; i < n; ++i) indices().coeffRef(i) = i;
125  }
126 
129  void setIdentity(Index newSize) {
130  resize(newSize);
131  setIdentity();
132  }
133 
144  eigen_assert(i >= 0 && j >= 0 && i < size() && j < size());
145  for (Index k = 0; k < size(); ++k) {
146  if (indices().coeff(k) == i)
147  indices().coeffRef(k) = StorageIndex(j);
148  else if (indices().coeff(k) == j)
149  indices().coeffRef(k) = StorageIndex(i);
150  }
151  return derived();
152  }
153 
163  eigen_assert(i >= 0 && j >= 0 && i < size() && j < size());
164  std::swap(indices().coeffRef(i), indices().coeffRef(j));
165  return derived();
166  }
167 
172  inline InverseReturnType inverse() const { return InverseReturnType(derived()); }
177  inline InverseReturnType transpose() const { return InverseReturnType(derived()); }
178 
179  /**** multiplication helpers to hopefully get RVO ****/
180 
181 #ifndef EIGEN_PARSED_BY_DOXYGEN
182  protected:
183  template <typename OtherDerived>
185  for (Index i = 0; i < rows(); ++i) indices().coeffRef(other.indices().coeff(i)) = i;
186  }
187  template <typename Lhs, typename Rhs>
188  void assignProduct(const Lhs& lhs, const Rhs& rhs) {
189  eigen_assert(lhs.cols() == rhs.rows());
190  for (Index i = 0; i < rows(); ++i) indices().coeffRef(i) = lhs.indices().coeff(rhs.indices().coeff(i));
191  }
192 #endif
193 
194  public:
199  template <typename Other>
202  }
203 
208  template <typename Other>
210  return PlainPermutationType(internal::PermPermProduct, *this, other.eval());
211  }
212 
217  template <typename Other>
219  const PermutationBase& perm) {
220  return PlainPermutationType(internal::PermPermProduct, other.eval(), perm);
221  }
222 
228  Index determinant() const {
229  Index res = 1;
230  Index n = size();
232  mask.fill(false);
233  Index r = 0;
234  while (r < n) {
235  // search for the next seed
236  while (r < n && mask[r]) r++;
237  if (r >= n) break;
238  // we got one, let's follow it until we are back to the seed
239  Index k0 = r++;
240  mask.coeffRef(k0) = true;
241  for (Index k = indices().coeff(k0); k != k0; k = indices().coeff(k)) {
242  mask.coeffRef(k) = true;
243  res = -res;
244  }
245  }
246  return res;
247  }
248 
249  protected:
250 };
251 
252 namespace internal {
253 template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_>
254 struct traits<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_> >
255  : traits<
256  Matrix<StorageIndex_, SizeAtCompileTime, SizeAtCompileTime, 0, MaxSizeAtCompileTime, MaxSizeAtCompileTime> > {
259  typedef StorageIndex_ StorageIndex;
260  typedef void Scalar;
261 };
262 } // namespace internal
263 
278 template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_>
280  : public PermutationBase<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_> > {
283 
284  public:
285  typedef const PermutationMatrix& Nested;
286 
287 #ifndef EIGEN_PARSED_BY_DOXYGEN
288  typedef typename Traits::IndicesType IndicesType;
289  typedef typename Traits::StorageIndex StorageIndex;
290 #endif
291 
292  inline PermutationMatrix() {}
293 
296  explicit inline PermutationMatrix(Index size) : m_indices(size) {
298  }
299 
301  template <typename OtherDerived>
303 
311  template <typename Other>
313 
315  template <typename Other>
317  *this = tr;
318  }
319 
321  template <typename Other>
323  m_indices = other.indices();
324  return *this;
325  }
326 
328  template <typename Other>
330  return Base::operator=(tr.derived());
331  }
332 
334  const IndicesType& indices() const { return m_indices; }
337 
338  /**** multiplication helpers to hopefully get RVO ****/
339 
340 #ifndef EIGEN_PARSED_BY_DOXYGEN
341  template <typename Other>
343  : m_indices(other.derived().nestedExpression().size()) {
346  for (StorageIndex i = 0; i < end; ++i)
347  m_indices.coeffRef(other.derived().nestedExpression().indices().coeff(i)) = i;
348  }
349  template <typename Lhs, typename Rhs>
351  Base::assignProduct(lhs, rhs);
352  }
353 #endif
354 
355  protected:
357 };
358 
359 namespace internal {
360 template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_, int PacketAccess_>
361 struct traits<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_>, PacketAccess_> >
362  : traits<
363  Matrix<StorageIndex_, SizeAtCompileTime, SizeAtCompileTime, 0, MaxSizeAtCompileTime, MaxSizeAtCompileTime> > {
366  typedef StorageIndex_ StorageIndex;
367  typedef void Scalar;
368 };
369 } // namespace internal
370 
371 template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_, int PacketAccess_>
372 class Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_>, PacketAccess_>
373  : public PermutationBase<
374  Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_>, PacketAccess_> > {
377 
378  public:
379 #ifndef EIGEN_PARSED_BY_DOXYGEN
380  typedef typename Traits::IndicesType IndicesType;
382 #endif
383 
384  inline Map(const StorageIndex* indicesPtr) : m_indices(indicesPtr) {}
385 
386  inline Map(const StorageIndex* indicesPtr, Index size) : m_indices(indicesPtr, size) {}
387 
389  template <typename Other>
391  return Base::operator=(other.derived());
392  }
393 
395  template <typename Other>
397  return Base::operator=(tr.derived());
398  }
399 
400 #ifndef EIGEN_PARSED_BY_DOXYGEN
404  Map& operator=(const Map& other) {
405  m_indices = other.m_indices;
406  return *this;
407  }
408 #endif
409 
411  const IndicesType& indices() const { return m_indices; }
413  IndicesType& indices() { return m_indices; }
414 
415  protected:
417 };
418 
419 template <typename IndicesType_>
421 namespace internal {
422 template <typename IndicesType_>
423 struct traits<PermutationWrapper<IndicesType_> > {
425  typedef void Scalar;
427  typedef IndicesType_ IndicesType;
428  enum {
429  RowsAtCompileTime = IndicesType_::SizeAtCompileTime,
430  ColsAtCompileTime = IndicesType_::SizeAtCompileTime,
431  MaxRowsAtCompileTime = IndicesType::MaxSizeAtCompileTime,
432  MaxColsAtCompileTime = IndicesType::MaxSizeAtCompileTime,
433  Flags = 0
434  };
435 };
436 } // namespace internal
437 
449 template <typename IndicesType_>
450 class PermutationWrapper : public PermutationBase<PermutationWrapper<IndicesType_> > {
453 
454  public:
455 #ifndef EIGEN_PARSED_BY_DOXYGEN
456  typedef typename Traits::IndicesType IndicesType;
457 #endif
458 
460 
463 
464  protected:
465  typename IndicesType::Nested m_indices;
466 };
467 
470 template <typename MatrixDerived, typename PermutationDerived>
474 }
475 
478 template <typename PermutationDerived, typename MatrixDerived>
482 }
483 
484 template <typename PermutationType>
485 class InverseImpl<PermutationType, PermutationStorage> : public EigenBase<Inverse<PermutationType> > {
486  typedef typename PermutationType::PlainPermutationType PlainPermutationType;
488 
489  protected:
491 
492  public:
494  using EigenBase<Inverse<PermutationType> >::derived;
495 
496 #ifndef EIGEN_PARSED_BY_DOXYGEN
497  typedef typename PermutationType::DenseMatrixType DenseMatrixType;
498  enum {
499  RowsAtCompileTime = PermTraits::RowsAtCompileTime,
500  ColsAtCompileTime = PermTraits::ColsAtCompileTime,
501  MaxRowsAtCompileTime = PermTraits::MaxRowsAtCompileTime,
502  MaxColsAtCompileTime = PermTraits::MaxColsAtCompileTime
503  };
504 #endif
505 
506 #ifndef EIGEN_PARSED_BY_DOXYGEN
507  template <typename DenseDerived>
508  void evalTo(MatrixBase<DenseDerived>& other) const {
509  other.setZero();
510  for (Index i = 0; i < derived().rows(); ++i)
511  other.coeffRef(i, derived().nestedExpression().indices().coeff(i)) = typename DenseDerived::Scalar(1);
512  }
513 #endif
514 
516  PlainPermutationType eval() const { return derived(); }
517 
518  DenseMatrixType toDenseMatrix() const { return derived(); }
519 
522  template <typename OtherDerived>
524  const InverseType& trPerm) {
525  return Product<OtherDerived, InverseType, AliasFreeProduct>(matrix.derived(), trPerm.derived());
526  }
527 
530  template <typename OtherDerived>
533  }
534 };
535 
536 template <typename Derived>
538  return derived();
539 }
540 
541 namespace internal {
542 
543 template <>
546 };
547 
548 } // end namespace internal
549 
550 } // end namespace Eigen
551 
552 #endif // EIGEN_PERMUTATIONMATRIX_H
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
#define eigen_internal_assert(x)
Definition: Macros.h:916
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:892
#define eigen_assert(x)
Definition: Macros.h:910
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
SCALAR Scalar
Definition: bench_gemm.cpp:45
EIGEN_DEVICE_FUNC Derived & setZero()
Definition: CwiseNullaryOp.h:554
void evalTo(MatrixBase< DenseDerived > &other) const
Definition: PermutationMatrix.h:508
DenseMatrixType toDenseMatrix() const
Definition: PermutationMatrix.h:518
friend const Product< OtherDerived, InverseType, AliasFreeProduct > operator*(const MatrixBase< OtherDerived > &matrix, const InverseType &trPerm)
Definition: PermutationMatrix.h:523
InverseImpl()
Definition: PermutationMatrix.h:490
PermutationType::DenseMatrixType DenseMatrixType
Definition: PermutationMatrix.h:497
PlainPermutationType eval() const
Definition: PermutationMatrix.h:516
Inverse< PermutationType > InverseType
Definition: PermutationMatrix.h:493
internal::traits< PermutationType > PermTraits
Definition: PermutationMatrix.h:487
const Product< InverseType, OtherDerived, AliasFreeProduct > operator*(const MatrixBase< OtherDerived > &matrix) const
Definition: PermutationMatrix.h:531
PermutationType::PlainPermutationType PlainPermutationType
Definition: PermutationMatrix.h:486
Definition: Inverse.h:65
Scalar coeff(Index row, Index col) const
Expression of the inverse of another expression.
Definition: Inverse.h:43
Map(const StorageIndex *indicesPtr, Index size)
Definition: PermutationMatrix.h:386
Map & operator=(const PermutationBase< Other > &other)
Definition: PermutationMatrix.h:390
Map & operator=(const TranspositionsBase< Other > &tr)
Definition: PermutationMatrix.h:396
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:96
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:52
const PermutationWrapper< const Derived > asPermutation() const
Definition: PermutationMatrix.h:537
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Scalar & coeffRef(Index rowId, Index colId)
Definition: PlainObjectBase.h:217
Base class for permutations.
Definition: PermutationMatrix.h:49
InverseReturnType transpose() const
Definition: PermutationMatrix.h:177
void assignProduct(const Lhs &lhs, const Rhs &rhs)
Definition: PermutationMatrix.h:188
void resize(Index newSize)
Definition: PermutationMatrix.h:119
Traits::IndicesType IndicesType
Definition: PermutationMatrix.h:55
EIGEN_DEVICE_FUNC Index rows() const
Definition: PermutationMatrix.h:90
Traits::StorageIndex StorageIndex
Definition: PermutationMatrix.h:63
IndicesType & indices()
Definition: PermutationMatrix.h:115
PlainPermutationType PlainObject
Definition: PermutationMatrix.h:68
constexpr EIGEN_DEVICE_FUNC Derived & derived()
Definition: EigenBase.h:49
EIGEN_DEVICE_FUNC Index cols() const
Definition: PermutationMatrix.h:93
Index determinant() const
Definition: PermutationMatrix.h:228
PermutationMatrix< IndicesType::SizeAtCompileTime, IndicesType::MaxSizeAtCompileTime, StorageIndex > PlainPermutationType
Definition: PermutationMatrix.h:67
Inverse< Derived > InverseReturnType
Definition: PermutationMatrix.h:70
EIGEN_DEVICE_FUNC Index size() const
Definition: PermutationMatrix.h:96
Matrix< StorageIndex, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime > DenseMatrixType
Definition: PermutationMatrix.h:65
friend PlainPermutationType operator*(const InverseImpl< Other, PermutationStorage > &other, const PermutationBase &perm)
Definition: PermutationMatrix.h:218
Derived & applyTranspositionOnTheLeft(Index i, Index j)
Definition: PermutationMatrix.h:143
Derived & applyTranspositionOnTheRight(Index i, Index j)
Definition: PermutationMatrix.h:162
void setIdentity()
Definition: PermutationMatrix.h:122
@ MaxRowsAtCompileTime
Definition: PermutationMatrix.h:60
@ RowsAtCompileTime
Definition: PermutationMatrix.h:58
@ MaxColsAtCompileTime
Definition: PermutationMatrix.h:61
@ ColsAtCompileTime
Definition: PermutationMatrix.h:59
void evalTo(MatrixBase< DenseDerived > &other) const
Definition: PermutationMatrix.h:100
void Scalar
Definition: PermutationMatrix.h:71
void setIdentity(Index newSize)
Definition: PermutationMatrix.h:129
PlainPermutationType operator*(const InverseImpl< Other, PermutationStorage > &other) const
Definition: PermutationMatrix.h:209
Derived & operator=(const PermutationBase< OtherDerived > &other)
Definition: PermutationMatrix.h:76
EigenBase< Derived > Base
Definition: PermutationMatrix.h:51
internal::traits< Derived > Traits
Definition: PermutationMatrix.h:50
Derived & operator=(const TranspositionsBase< OtherDerived > &tr)
Definition: PermutationMatrix.h:83
InverseReturnType inverse() const
Definition: PermutationMatrix.h:172
DenseMatrixType toDenseMatrix() const
Definition: PermutationMatrix.h:110
const IndicesType & indices() const
Definition: PermutationMatrix.h:113
PlainPermutationType operator*(const PermutationBase< Other > &other) const
Definition: PermutationMatrix.h:200
void assignTranspose(const PermutationBase< OtherDerived > &other)
Definition: PermutationMatrix.h:184
Permutation matrix.
Definition: PermutationMatrix.h:280
Traits::IndicesType IndicesType
Definition: PermutationMatrix.h:288
PermutationMatrix & operator=(const TranspositionsBase< Other > &tr)
Definition: PermutationMatrix.h:329
PermutationMatrix(const PermutationBase< OtherDerived > &other)
Definition: PermutationMatrix.h:302
PermutationMatrix(const TranspositionsBase< Other > &tr)
Definition: PermutationMatrix.h:316
PermutationMatrix(const InverseImpl< Other, PermutationStorage > &other)
Definition: PermutationMatrix.h:342
internal::traits< PermutationMatrix > Traits
Definition: PermutationMatrix.h:282
const IndicesType & indices() const
Definition: PermutationMatrix.h:334
IndicesType & indices()
Definition: PermutationMatrix.h:336
PermutationMatrix()
Definition: PermutationMatrix.h:292
IndicesType m_indices
Definition: PermutationMatrix.h:356
PermutationMatrix(const MatrixBase< Other > &indices)
Definition: PermutationMatrix.h:312
const PermutationMatrix & Nested
Definition: PermutationMatrix.h:285
PermutationMatrix(Index size)
Definition: PermutationMatrix.h:296
PermutationMatrix(internal::PermPermProduct_t, const Lhs &lhs, const Rhs &rhs)
Definition: PermutationMatrix.h:350
Traits::StorageIndex StorageIndex
Definition: PermutationMatrix.h:289
PermutationMatrix & operator=(const PermutationBase< Other > &other)
Definition: PermutationMatrix.h:322
PermutationBase< PermutationMatrix > Base
Definition: PermutationMatrix.h:281
Class to view a vector of integers as a permutation matrix.
Definition: PermutationMatrix.h:450
PermutationWrapper(const IndicesType &indices)
Definition: PermutationMatrix.h:459
Traits::IndicesType IndicesType
Definition: PermutationMatrix.h:456
PermutationBase< PermutationWrapper > Base
Definition: PermutationMatrix.h:451
const internal::remove_all_t< typename IndicesType::Nested > & indices() const
Definition: PermutationMatrix.h:462
IndicesType::Nested m_indices
Definition: PermutationMatrix.h:465
internal::traits< PermutationWrapper > Traits
Definition: PermutationMatrix.h:452
Expression of the product of two arbitrary matrices or vectors.
Definition: Product.h:202
Definition: Transpositions.h:19
EIGEN_DEVICE_FUNC const StorageIndex & coeff(Index i) const
Definition: Transpositions.h:45
EIGEN_DEVICE_FUNC Index size() const
Definition: Transpositions.h:38
EIGEN_DEVICE_FUNC Derived & derived()
Definition: Transpositions.h:27
Definition: Transpositions.h:237
Eigen::Map< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor >, 0, Eigen::OuterStride<> > matrix(T *data, int rows, int cols, int stride)
Definition: common.h:85
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
EIGEN_BLAS_FUNC() swap(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:117
char char char int int * k
Definition: level2_impl.h:374
@ Lhs
Definition: TensorContractionMapper.h:20
@ Rhs
Definition: TensorContractionMapper.h:20
PermPermProduct_t
Definition: PermutationMatrix.h:21
@ PermPermProduct
Definition: PermutationMatrix.h:21
typename remove_all< T >::type remove_all_t
Definition: Meta.h:142
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
EIGEN_DEVICE_FUNC const Product< MatrixDerived, PermutationDerived, AliasFreeProduct > operator*(const MatrixBase< MatrixDerived > &matrix, const PermutationBase< PermutationDerived > &permutation)
Definition: PermutationMatrix.h:471
Extend namespace for flags.
Definition: fsi_chan_precond_driver.cc:56
r
Definition: UniformPSDSelfTest.py:20
Definition: Eigen_Colamd.h:49
Definition: Constants.h:540
Definition: EigenBase.h:33
constexpr EIGEN_DEVICE_FUNC Derived & derived()
Definition: EigenBase.h:49
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:43
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217
Definition: Constants.h:564
Definition: Constants.h:528
EigenBase2EigenBase Kind
Definition: PermutationMatrix.h:545
Definition: AssignEvaluator.h:760
Definition: AssignEvaluator.h:757
Map< const Matrix< StorageIndex_, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1 >, PacketAccess_ > IndicesType
Definition: PermutationMatrix.h:365
Matrix< StorageIndex_, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1 > IndicesType
Definition: PermutationMatrix.h:258
IndicesType_::Scalar StorageIndex
Definition: PermutationMatrix.h:426
void Scalar
Definition: PermutationMatrix.h:425
PermutationStorage StorageKind
Definition: PermutationMatrix.h:424
IndicesType_ IndicesType
Definition: PermutationMatrix.h:427
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2