Eigen  5.0.1-dev+60122df6
 
Loading...
Searching...
No Matches
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
17namespace Eigen {
18
19namespace internal {
20
21enum PermPermProduct_t { PermPermProduct };
22
23} // end namespace internal
24
48template <typename Derived>
49class 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>
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
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
255namespace internal {
256template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_>
257struct 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
281template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_>
282class PermutationMatrix
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>
325 PermutationMatrix& operator=(const PermutationBase<Other>& 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
362namespace internal {
363template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_, int PacketAccess_>
364struct 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
374template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_, int PacketAccess_>
375class 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
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
422template <typename IndicesType_>
423class TranspositionsWrapper;
424namespace internal {
425template <typename IndicesType_>
426struct 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
452template <typename IndicesType_>
453class 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
473template <typename MatrixDerived, typename PermutationDerived>
478
481template <typename PermutationDerived, typename MatrixDerived>
486
487template <typename PermutationType>
488class 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
539template <typename Derived>
540const PermutationWrapper<const Derived> MatrixBase<Derived>::asPermutation() const {
541 return derived();
542}
543
544namespace internal {
545
546template <>
547struct AssignmentKind<DenseShape, PermutationShape> {
548 typedef EigenBase2EigenBase Kind;
549};
550
551} // end namespace internal
552
553} // end namespace Eigen
554
555#endif // EIGEN_PERMUTATIONMATRIX_H
Derived & setZero()
Definition CwiseNullaryOp.h:552
Expression of the inverse of another expression.
Definition Inverse.h:43
A matrix or vector expression mapping an existing array of data.
Definition Map.h:96
Map(PointerArgType dataPtr, const StrideType &stride=StrideType())
Definition Map.h:123
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:52
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:186
constexpr Scalar & coeffRef(Index rowId, Index colId)
Definition PlainObjectBase.h:191
Base class for permutations.
Definition PermutationMatrix.h:49
InverseReturnType transpose() const
Definition PermutationMatrix.h:180
Derived & applyTranspositionOnTheLeft(Index i, Index j)
Definition PermutationMatrix.h:146
void resize(Index newSize)
Definition PermutationMatrix.h:122
Index determinant() const
Definition PermutationMatrix.h:231
Index size() const
Definition PermutationMatrix.h:96
Index cols() const
Definition PermutationMatrix.h:93
DenseMatrixType eval() const
Definition PermutationMatrix.h:113
Derived & applyTranspositionOnTheRight(Index i, Index j)
Definition PermutationMatrix.h:165
friend PlainPermutationType operator*(const InverseImpl< Other, PermutationStorage > &other, const PermutationBase &perm)
Definition PermutationMatrix.h:221
void setIdentity()
Definition PermutationMatrix.h:125
Derived & operator=(const PermutationBase< OtherDerived > &other)
Definition PermutationMatrix.h:76
IndicesType & indices()
Definition PermutationMatrix.h:118
void setIdentity(Index newSize)
Definition PermutationMatrix.h:132
PlainPermutationType operator*(const InverseImpl< Other, PermutationStorage > &other) const
Definition PermutationMatrix.h:212
const IndicesType & indices() const
Definition PermutationMatrix.h:116
Index rows() const
Definition PermutationMatrix.h:90
InverseReturnType inverse() const
Definition PermutationMatrix.h:175
DenseMatrixType toDenseMatrix() const
Definition PermutationMatrix.h:110
Derived & operator=(const TranspositionsBase< OtherDerived > &tr)
Definition PermutationMatrix.h:83
PlainPermutationType operator*(const PermutationBase< Other > &other) const
Definition PermutationMatrix.h:203
Permutation matrix.
Definition PermutationMatrix.h:283
PermutationMatrix(const PermutationBase< OtherDerived > &other)
Definition PermutationMatrix.h:305
PermutationMatrix(const TranspositionsBase< Other > &tr)
Definition PermutationMatrix.h:319
PermutationMatrix & operator=(const PermutationBase< Other > &other)
Definition PermutationMatrix.h:325
PermutationMatrix(const MatrixBase< Other > &indices)
Definition PermutationMatrix.h:315
PermutationMatrix(Index size)
Definition PermutationMatrix.h:299
const IndicesType & indices() const
Definition PermutationMatrix.h:337
IndicesType & indices()
Definition PermutationMatrix.h:339
PermutationMatrix & operator=(const TranspositionsBase< Other > &tr)
Definition PermutationMatrix.h:332
Class to view a vector of integers as a permutation matrix.
Definition PermutationMatrix.h:453
const internal::remove_all_t< typename IndicesType::Nested > & indices() const
Definition PermutationMatrix.h:465
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
const Product< MatrixDerived, PermutationDerived, DefaultProduct > operator*(const MatrixBase< MatrixDerived > &matrix, const PermutationBase< PermutationDerived > &permutation)
Definition PermutationMatrix.h:474
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82
Definition EigenBase.h:33
constexpr Derived & derived()
Definition EigenBase.h:49
Eigen::Index Index
The interface type of indices.
Definition EigenBase.h:43