$darkmode
Eigen  5.0.1-dev
PermutationMatrix.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
5 // Copyright (C) 2009-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 
21 enum PermPermProduct_t { PermPermProduct };
22 
23 } // end namespace internal
24 
48 template <typename Derived>
49 class PermutationBase : public EigenBase<Derived> {
50  typedef internal::traits<Derived> Traits;
51  typedef EigenBase<Derived> Base;
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;
65  DenseMatrixType;
67  PlainPermutationType;
68  typedef PlainPermutationType PlainObject;
69  using Base::derived;
70  typedef Inverse<Derived> InverseReturnType;
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>
83  Derived& operator=(const TranspositionsBase<OtherDerived>& tr) {
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  DenseMatrixType eval() const { return toDenseMatrix(); }
114 
116  const IndicesType& indices() const { return derived().indices(); }
118  IndicesType& indices() { return derived().indices(); }
119 
122  inline void resize(Index newSize) { indices().resize(newSize); }
123 
125  void setIdentity() {
126  StorageIndex n = StorageIndex(size());
127  for (StorageIndex i = 0; i < n; ++i) indices().coeffRef(i) = i;
128  }
129 
132  void setIdentity(Index newSize) {
133  resize(newSize);
134  setIdentity();
135  }
136 
147  eigen_assert(i >= 0 && j >= 0 && i < size() && j < size());
148  for (Index k = 0; k < size(); ++k) {
149  if (indices().coeff(k) == i)
150  indices().coeffRef(k) = StorageIndex(j);
151  else if (indices().coeff(k) == j)
152  indices().coeffRef(k) = StorageIndex(i);
153  }
154  return derived();
155  }
156 
166  eigen_assert(i >= 0 && j >= 0 && i < size() && j < size());
167  std::swap(indices().coeffRef(i), indices().coeffRef(j));
168  return derived();
169  }
170 
175  inline InverseReturnType inverse() const { return InverseReturnType(derived()); }
180  inline InverseReturnType transpose() const { return InverseReturnType(derived()); }
181 
182  /**** multiplication helpers to hopefully get RVO ****/
183 
184 #ifndef EIGEN_PARSED_BY_DOXYGEN
185  protected:
186  template <typename OtherDerived>
187  void assignTranspose(const PermutationBase<OtherDerived>& other) {
188  for (Index i = 0; i < rows(); ++i) indices().coeffRef(other.indices().coeff(i)) = i;
189  }
190  template <typename Lhs, typename Rhs>
191  void assignProduct(const Lhs& lhs, const Rhs& rhs) {
192  eigen_assert(lhs.cols() == rhs.rows());
193  for (Index i = 0; i < rows(); ++i) indices().coeffRef(i) = lhs.indices().coeff(rhs.indices().coeff(i));
194  }
195 #endif
196 
197  public:
202  template <typename Other>
203  inline PlainPermutationType operator*(const PermutationBase<Other>& other) const {
204  return PlainPermutationType(internal::PermPermProduct, derived(), other.derived());
205  }
206 
211  template <typename Other>
212  inline PlainPermutationType operator*(const InverseImpl<Other, PermutationStorage>& other) const {
213  return PlainPermutationType(internal::PermPermProduct, *this, other.eval());
214  }
215 
220  template <typename Other>
221  friend inline PlainPermutationType operator*(const InverseImpl<Other, PermutationStorage>& other,
222  const PermutationBase& perm) {
223  return PlainPermutationType(internal::PermPermProduct, other.eval(), perm);
224  }
225 
231  Index determinant() const {
232  Index res = 1;
233  Index n = size();
235  mask.fill(false);
236  Index r = 0;
237  while (r < n) {
238  // search for the next seed
239  while (r < n && mask[r]) r++;
240  if (r >= n) break;
241  // we got one, let's follow it until we are back to the seed
242  Index k0 = r++;
243  mask.coeffRef(k0) = true;
244  for (Index k = indices().coeff(k0); k != k0; k = indices().coeff(k)) {
245  mask.coeffRef(k) = true;
246  res = -res;
247  }
248  }
249  return res;
250  }
251 
252  protected:
253 };
254 
255 namespace internal {
256 template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_>
257 struct traits<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_> >
258  : traits<
259  Matrix<StorageIndex_, SizeAtCompileTime, SizeAtCompileTime, 0, MaxSizeAtCompileTime, MaxSizeAtCompileTime> > {
260  typedef PermutationStorage StorageKind;
261  typedef Matrix<StorageIndex_, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
262  typedef StorageIndex_ StorageIndex;
263  typedef void Scalar;
264 };
265 } // namespace internal
266 
281 template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_>
283  : public PermutationBase<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_> > {
285  typedef internal::traits<PermutationMatrix> Traits;
286 
287  public:
288  typedef const PermutationMatrix& Nested;
289 
290 #ifndef EIGEN_PARSED_BY_DOXYGEN
291  typedef typename Traits::IndicesType IndicesType;
292  typedef typename Traits::StorageIndex StorageIndex;
293 #endif
294 
295  inline PermutationMatrix() {}
296 
299  explicit inline PermutationMatrix(Index size) : m_indices(size) {
300  eigen_internal_assert(size <= NumTraits<StorageIndex>::highest());
301  }
302 
304  template <typename OtherDerived>
305  inline PermutationMatrix(const PermutationBase<OtherDerived>& other) : m_indices(other.indices()) {}
306 
314  template <typename Other>
315  explicit inline PermutationMatrix(const MatrixBase<Other>& indices) : m_indices(indices) {}
316 
318  template <typename Other>
319  explicit PermutationMatrix(const TranspositionsBase<Other>& tr) : m_indices(tr.size()) {
320  *this = tr;
321  }
322 
324  template <typename Other>
326  m_indices = other.indices();
327  return *this;
328  }
329 
331  template <typename Other>
332  PermutationMatrix& operator=(const TranspositionsBase<Other>& tr) {
333  return Base::operator=(tr.derived());
334  }
335 
337  const IndicesType& indices() const { return m_indices; }
339  IndicesType& indices() { return m_indices; }
340 
341  /**** multiplication helpers to hopefully get RVO ****/
342 
343 #ifndef EIGEN_PARSED_BY_DOXYGEN
344  template <typename Other>
345  PermutationMatrix(const InverseImpl<Other, PermutationStorage>& other)
346  : m_indices(other.derived().nestedExpression().size()) {
347  eigen_internal_assert(m_indices.size() <= NumTraits<StorageIndex>::highest());
348  StorageIndex end = StorageIndex(m_indices.size());
349  for (StorageIndex i = 0; i < end; ++i)
350  m_indices.coeffRef(other.derived().nestedExpression().indices().coeff(i)) = i;
351  }
352  template <typename Lhs, typename Rhs>
353  PermutationMatrix(internal::PermPermProduct_t, const Lhs& lhs, const Rhs& rhs) : m_indices(lhs.indices().size()) {
354  Base::assignProduct(lhs, rhs);
355  }
356 #endif
357 
358  protected:
359  IndicesType m_indices;
360 };
361 
362 namespace internal {
363 template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_, int PacketAccess_>
364 struct traits<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_>, PacketAccess_> >
365  : traits<
366  Matrix<StorageIndex_, SizeAtCompileTime, SizeAtCompileTime, 0, MaxSizeAtCompileTime, MaxSizeAtCompileTime> > {
367  typedef PermutationStorage StorageKind;
368  typedef Map<const Matrix<StorageIndex_, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1>, PacketAccess_> IndicesType;
369  typedef StorageIndex_ StorageIndex;
370  typedef void Scalar;
371 };
372 } // namespace internal
373 
374 template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_, int PacketAccess_>
375 class Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_>, PacketAccess_>
376  : public PermutationBase<
377  Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_>, PacketAccess_> > {
378  typedef PermutationBase<Map> Base;
379  typedef internal::traits<Map> Traits;
380 
381  public:
382 #ifndef EIGEN_PARSED_BY_DOXYGEN
383  typedef typename Traits::IndicesType IndicesType;
384  typedef typename IndicesType::Scalar StorageIndex;
385 #endif
386 
387  inline Map(const StorageIndex* indicesPtr) : m_indices(indicesPtr) {}
388 
389  inline Map(const StorageIndex* indicesPtr, Index size) : m_indices(indicesPtr, size) {}
390 
392  template <typename Other>
393  Map& operator=(const PermutationBase<Other>& other) {
394  return Base::operator=(other.derived());
395  }
396 
398  template <typename Other>
399  Map& operator=(const TranspositionsBase<Other>& tr) {
400  return Base::operator=(tr.derived());
401  }
402 
403 #ifndef EIGEN_PARSED_BY_DOXYGEN
404 
407  Map& operator=(const Map& other) {
408  m_indices = other.m_indices;
409  return *this;
410  }
411 #endif
412 
414  const IndicesType& indices() const { return m_indices; }
416  IndicesType& indices() { return m_indices; }
417 
418  protected:
419  IndicesType m_indices;
420 };
421 
422 template <typename IndicesType_>
423 class TranspositionsWrapper;
424 namespace internal {
425 template <typename IndicesType_>
426 struct traits<PermutationWrapper<IndicesType_> > {
427  typedef PermutationStorage StorageKind;
428  typedef void Scalar;
429  typedef typename IndicesType_::Scalar StorageIndex;
430  typedef IndicesType_ IndicesType;
431  enum {
432  RowsAtCompileTime = IndicesType_::SizeAtCompileTime,
433  ColsAtCompileTime = IndicesType_::SizeAtCompileTime,
434  MaxRowsAtCompileTime = IndicesType::MaxSizeAtCompileTime,
435  MaxColsAtCompileTime = IndicesType::MaxSizeAtCompileTime,
436  Flags = 0
437  };
438 };
439 } // namespace internal
440 
452 template <typename IndicesType_>
453 class PermutationWrapper : public PermutationBase<PermutationWrapper<IndicesType_> > {
455  typedef internal::traits<PermutationWrapper> Traits;
456 
457  public:
458 #ifndef EIGEN_PARSED_BY_DOXYGEN
459  typedef typename Traits::IndicesType IndicesType;
460 #endif
461 
462  inline PermutationWrapper(const IndicesType& indices) : m_indices(indices) {}
463 
465  const internal::remove_all_t<typename IndicesType::Nested>& indices() const { return m_indices; }
466 
467  protected:
468  typename IndicesType::Nested m_indices;
469 };
470 
473 template <typename MatrixDerived, typename PermutationDerived>
475  const MatrixBase<MatrixDerived>& matrix, const PermutationBase<PermutationDerived>& permutation) {
477 }
478 
481 template <typename PermutationDerived, typename MatrixDerived>
483  const PermutationBase<PermutationDerived>& permutation, const MatrixBase<MatrixDerived>& matrix) {
485 }
486 
487 template <typename PermutationType>
488 class InverseImpl<PermutationType, PermutationStorage> : public EigenBase<Inverse<PermutationType> > {
489  typedef typename PermutationType::PlainPermutationType PlainPermutationType;
490  typedef internal::traits<PermutationType> PermTraits;
491 
492  protected:
493  InverseImpl() {}
494 
495  public:
496  typedef Inverse<PermutationType> InverseType;
497  using EigenBase<Inverse<PermutationType> >::derived;
498 
499 #ifndef EIGEN_PARSED_BY_DOXYGEN
500  typedef typename PermutationType::DenseMatrixType DenseMatrixType;
501  enum {
502  RowsAtCompileTime = PermTraits::RowsAtCompileTime,
503  ColsAtCompileTime = PermTraits::ColsAtCompileTime,
504  MaxRowsAtCompileTime = PermTraits::MaxRowsAtCompileTime,
505  MaxColsAtCompileTime = PermTraits::MaxColsAtCompileTime
506  };
507 #endif
508 
509 #ifndef EIGEN_PARSED_BY_DOXYGEN
510  template <typename DenseDerived>
511  void evalTo(MatrixBase<DenseDerived>& other) const {
512  other.setZero();
513  for (Index i = 0; i < derived().rows(); ++i)
514  other.coeffRef(i, derived().nestedExpression().indices().coeff(i)) = typename DenseDerived::Scalar(1);
515  }
516 #endif
517 
519  PlainPermutationType eval() const { return derived(); }
520 
521  DenseMatrixType toDenseMatrix() const { return derived(); }
522 
525  template <typename OtherDerived>
526  friend const Product<OtherDerived, InverseType, DefaultProduct> operator*(const MatrixBase<OtherDerived>& matrix,
527  const InverseType& trPerm) {
528  return Product<OtherDerived, InverseType, DefaultProduct>(matrix.derived(), trPerm.derived());
529  }
530 
533  template <typename OtherDerived>
534  const Product<InverseType, OtherDerived, DefaultProduct> operator*(const MatrixBase<OtherDerived>& matrix) const {
535  return Product<InverseType, OtherDerived, DefaultProduct>(derived(), matrix.derived());
536  }
537 };
538 
539 template <typename Derived>
540 const PermutationWrapper<const Derived> MatrixBase<Derived>::asPermutation() const {
541  return derived();
542 }
543 
544 namespace internal {
545 
546 template <>
547 struct AssignmentKind<DenseShape, PermutationShape> {
548  typedef EigenBase2EigenBase Kind;
549 };
550 
551 } // end namespace internal
552 
553 } // end namespace Eigen
554 
555 #endif // EIGEN_PERMUTATIONMATRIX_H
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
const Product< MatrixDerived, PermutationDerived, DefaultProduct > operator*(const MatrixBase< MatrixDerived > &matrix, const PermutationBase< PermutationDerived > &permutation)
Definition: PermutationMatrix.h:474
constexpr Derived & derived()
Definition: EigenBase.h:49
Expression of the product of two arbitrary matrices or vectors.
Definition: Product.h:198
PlainPermutationType operator*(const PermutationBase< Other > &other) const
Definition: PermutationMatrix.h:203
friend PlainPermutationType operator*(const InverseImpl< Other, PermutationStorage > &other, const PermutationBase &perm)
Definition: PermutationMatrix.h:221
InverseReturnType inverse() const
Definition: PermutationMatrix.h:175
PermutationMatrix & operator=(const TranspositionsBase< Other > &tr)
Definition: PermutationMatrix.h:332
PlainPermutationType operator*(const InverseImpl< Other, PermutationStorage > &other) const
Definition: PermutationMatrix.h:212
const IndicesType & indices() const
Definition: PermutationMatrix.h:337
DenseMatrixType toDenseMatrix() const
Definition: PermutationMatrix.h:110
Derived & applyTranspositionOnTheRight(Index i, Index j)
Definition: PermutationMatrix.h:165
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:232
PermutationMatrix(Index size)
Definition: PermutationMatrix.h:299
IndicesType & indices()
Definition: PermutationMatrix.h:339
Derived & operator=(const PermutationBase< OtherDerived > &other)
Definition: PermutationMatrix.h:76
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:43
Map(PointerArgType dataPtr, const StrideType &stride=StrideType())
Definition: Map.h:123
Base class for permutations.
Definition: PermutationMatrix.h:49
Definition: EigenBase.h:33
const internal::remove_all_t< typename IndicesType::Nested > & indices() const
Definition: PermutationMatrix.h:465
Expression of the inverse of another expression.
Definition: Inverse.h:43
Permutation matrix.
Definition: PermutationMatrix.h:282
Index size() const
Definition: PermutationMatrix.h:96
IndicesType & indices()
Definition: PermutationMatrix.h:118
Index cols() const
Definition: PermutationMatrix.h:93
PermutationMatrix(const TranspositionsBase< Other > &tr)
Definition: PermutationMatrix.h:319
Derived & operator=(const TranspositionsBase< OtherDerived > &tr)
Definition: PermutationMatrix.h:83
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
constexpr Scalar & coeffRef(Index row, Index col)
Definition: DenseCoeffsBase.h:306
Class to view a vector of integers as a permutation matrix.
Definition: PermutationMatrix.h:453
void setIdentity()
Definition: PermutationMatrix.h:125
const IndicesType & indices() const
Definition: PermutationMatrix.h:116
constexpr Derived & derived()
Definition: EigenBase.h:49
PermutationMatrix(const PermutationBase< OtherDerived > &other)
Definition: PermutationMatrix.h:305
Derived & setZero()
Definition: CwiseNullaryOp.h:552
Derived & applyTranspositionOnTheLeft(Index i, Index j)
Definition: PermutationMatrix.h:146
DenseMatrixType eval() const
Definition: PermutationMatrix.h:113
InverseReturnType transpose() const
Definition: PermutationMatrix.h:180
constexpr Scalar & coeffRef(Index rowId, Index colId)
Definition: PlainObjectBase.h:191
void setIdentity(Index newSize)
Definition: PermutationMatrix.h:132
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:186
void resize(Index newSize)
Definition: PermutationMatrix.h:122
Index determinant() const
Definition: PermutationMatrix.h:231
PermutationMatrix(const MatrixBase< Other > &indices)
Definition: PermutationMatrix.h:315
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:52
PermutationMatrix & operator=(const PermutationBase< Other > &other)
Definition: PermutationMatrix.h:325
Index rows() const
Definition: PermutationMatrix.h:90