Eigen  3.4.90 (git rev 5a9f66fb35d03a4da9ef8976e67a61b30aa16dcf)
 
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 <[email protected]>
5// Copyright (C) 2009-2015 Gael Guennebaud <[email protected]>
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;
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 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() {
123 StorageIndex n = StorageIndex(size());
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>
184 void assignTranspose(const PermutationBase<OtherDerived>& other) {
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>
200 inline PlainPermutationType operator*(const PermutationBase<Other>& other) const {
201 return PlainPermutationType(internal::PermPermProduct, derived(), other.derived());
202 }
203
208 template <typename Other>
209 inline PlainPermutationType operator*(const InverseImpl<Other, PermutationStorage>& other) const {
210 return PlainPermutationType(internal::PermPermProduct, *this, other.eval());
211 }
212
217 template <typename Other>
218 friend inline PlainPermutationType operator*(const InverseImpl<Other, PermutationStorage>& other,
219 const PermutationBase& perm) {
220 return PlainPermutationType(internal::PermPermProduct, other.eval(), perm);
221 }
222
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
252namespace internal {
253template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_>
254struct traits<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_> >
255 : traits<
256 Matrix<StorageIndex_, SizeAtCompileTime, SizeAtCompileTime, 0, MaxSizeAtCompileTime, MaxSizeAtCompileTime> > {
257 typedef PermutationStorage StorageKind;
258 typedef Matrix<StorageIndex_, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
259 typedef StorageIndex_ StorageIndex;
260 typedef void Scalar;
261};
262} // namespace internal
263
278template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_>
280 : public PermutationBase<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_> > {
282 typedef internal::traits<PermutationMatrix> Traits;
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) {
297 eigen_internal_assert(size <= NumTraits<StorageIndex>::highest());
298 }
299
301 template <typename OtherDerived>
302 inline PermutationMatrix(const PermutationBase<OtherDerived>& other) : m_indices(other.indices()) {}
303
311 template <typename Other>
312 explicit inline PermutationMatrix(const MatrixBase<Other>& indices) : m_indices(indices) {}
313
315 template <typename Other>
316 explicit PermutationMatrix(const TranspositionsBase<Other>& tr) : m_indices(tr.size()) {
317 *this = tr;
318 }
319
321 template <typename Other>
323 m_indices = other.indices();
324 return *this;
325 }
326
328 template <typename Other>
329 PermutationMatrix& operator=(const TranspositionsBase<Other>& tr) {
330 return Base::operator=(tr.derived());
331 }
332
334 const IndicesType& indices() const { return m_indices; }
336 IndicesType& indices() { return m_indices; }
337
338 /**** multiplication helpers to hopefully get RVO ****/
339
340#ifndef EIGEN_PARSED_BY_DOXYGEN
341 template <typename Other>
342 PermutationMatrix(const InverseImpl<Other, PermutationStorage>& other)
343 : m_indices(other.derived().nestedExpression().size()) {
344 eigen_internal_assert(m_indices.size() <= NumTraits<StorageIndex>::highest());
345 StorageIndex end = StorageIndex(m_indices.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>
350 PermutationMatrix(internal::PermPermProduct_t, const Lhs& lhs, const Rhs& rhs) : m_indices(lhs.indices().size()) {
351 Base::assignProduct(lhs, rhs);
352 }
353#endif
354
355 protected:
356 IndicesType m_indices;
357};
358
359namespace internal {
360template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_, int PacketAccess_>
361struct traits<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_>, PacketAccess_> >
362 : traits<
363 Matrix<StorageIndex_, SizeAtCompileTime, SizeAtCompileTime, 0, MaxSizeAtCompileTime, MaxSizeAtCompileTime> > {
364 typedef PermutationStorage StorageKind;
365 typedef Map<const Matrix<StorageIndex_, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1>, PacketAccess_> IndicesType;
366 typedef StorageIndex_ StorageIndex;
367 typedef void Scalar;
368};
369} // namespace internal
370
371template <int SizeAtCompileTime, int MaxSizeAtCompileTime, typename StorageIndex_, int PacketAccess_>
372class Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_>, PacketAccess_>
373 : public PermutationBase<
374 Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, StorageIndex_>, PacketAccess_> > {
375 typedef PermutationBase<Map> Base;
376 typedef internal::traits<Map> Traits;
377
378 public:
379#ifndef EIGEN_PARSED_BY_DOXYGEN
380 typedef typename Traits::IndicesType IndicesType;
381 typedef typename IndicesType::Scalar StorageIndex;
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>
390 Map& operator=(const PermutationBase<Other>& other) {
391 return Base::operator=(other.derived());
392 }
393
395 template <typename Other>
396 Map& operator=(const TranspositionsBase<Other>& tr) {
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:
416 IndicesType m_indices;
417};
418
419template <typename IndicesType_>
420class TranspositionsWrapper;
421namespace internal {
422template <typename IndicesType_>
423struct traits<PermutationWrapper<IndicesType_> > {
424 typedef PermutationStorage StorageKind;
425 typedef void Scalar;
426 typedef typename IndicesType_::Scalar StorageIndex;
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
449template <typename IndicesType_>
450class PermutationWrapper : public PermutationBase<PermutationWrapper<IndicesType_> > {
452 typedef internal::traits<PermutationWrapper> Traits;
453
454 public:
455#ifndef EIGEN_PARSED_BY_DOXYGEN
456 typedef typename Traits::IndicesType IndicesType;
457#endif
458
459 inline PermutationWrapper(const IndicesType& indices) : m_indices(indices) {}
460
462 const internal::remove_all_t<typename IndicesType::Nested>& indices() const { return m_indices; }
463
464 protected:
465 typename IndicesType::Nested m_indices;
466};
467
470template <typename MatrixDerived, typename PermutationDerived>
475
478template <typename PermutationDerived, typename MatrixDerived>
483
484template <typename PermutationType>
485class InverseImpl<PermutationType, PermutationStorage> : public EigenBase<Inverse<PermutationType> > {
486 typedef typename PermutationType::PlainPermutationType PlainPermutationType;
487 typedef internal::traits<PermutationType> PermTraits;
488
489 protected:
490 InverseImpl() {}
491
492 public:
493 typedef Inverse<PermutationType> InverseType;
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>
523 friend const Product<OtherDerived, InverseType, AliasFreeProduct> operator*(const MatrixBase<OtherDerived>& matrix,
524 const InverseType& trPerm) {
525 return Product<OtherDerived, InverseType, AliasFreeProduct>(matrix.derived(), trPerm.derived());
526 }
527
530 template <typename OtherDerived>
531 const Product<InverseType, OtherDerived, AliasFreeProduct> operator*(const MatrixBase<OtherDerived>& matrix) const {
532 return Product<InverseType, OtherDerived, AliasFreeProduct>(derived(), matrix.derived());
533 }
534};
535
536template <typename Derived>
537const PermutationWrapper<const Derived> MatrixBase<Derived>::asPermutation() const {
538 return derived();
539}
540
541namespace internal {
542
543template <>
544struct AssignmentKind<DenseShape, PermutationShape> {
545 typedef EigenBase2EigenBase Kind;
546};
547
548} // end namespace internal
549
550} // end namespace Eigen
551
552#endif // EIGEN_PERMUTATIONMATRIX_H
void fill(const Scalar &value)
Definition CwiseNullaryOp.h:335
Derived & setZero()
Definition CwiseNullaryOp.h:549
Derived & derived()
Definition EigenBase.h:49
Scalar & coeffRef(Index row, Index col)
Definition DenseCoeffsBase.h:301
Expression of the inverse of another expression.
Definition Inverse.h:43
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:217
Base class for permutations.
Definition PermutationMatrix.h:49
InverseReturnType transpose() const
Definition PermutationMatrix.h:177
Derived & applyTranspositionOnTheLeft(Index i, Index j)
Definition PermutationMatrix.h:143
void resize(Index newSize)
Definition PermutationMatrix.h:119
Index determinant() const
Definition PermutationMatrix.h:228
Index size() const
Definition PermutationMatrix.h:96
Index cols() const
Definition PermutationMatrix.h:93
Derived & applyTranspositionOnTheRight(Index i, Index j)
Definition PermutationMatrix.h:162
friend PlainPermutationType operator*(const InverseImpl< Other, PermutationStorage > &other, const PermutationBase &perm)
Definition PermutationMatrix.h:218
void setIdentity()
Definition PermutationMatrix.h:122
Derived & operator=(const PermutationBase< OtherDerived > &other)
Definition PermutationMatrix.h:76
IndicesType & indices()
Definition PermutationMatrix.h:115
void setIdentity(Index newSize)
Definition PermutationMatrix.h:129
PlainPermutationType operator*(const InverseImpl< Other, PermutationStorage > &other) const
Definition PermutationMatrix.h:209
const IndicesType & indices() const
Definition PermutationMatrix.h:113
Index rows() const
Definition PermutationMatrix.h:90
InverseReturnType inverse() const
Definition PermutationMatrix.h:172
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:200
Permutation matrix.
Definition PermutationMatrix.h:280
PermutationMatrix(const PermutationBase< OtherDerived > &other)
Definition PermutationMatrix.h:302
PermutationMatrix(const TranspositionsBase< Other > &tr)
Definition PermutationMatrix.h:316
PermutationMatrix & operator=(const PermutationBase< Other > &other)
Definition PermutationMatrix.h:322
PermutationMatrix(const MatrixBase< Other > &indices)
Definition PermutationMatrix.h:312
PermutationMatrix(Index size)
Definition PermutationMatrix.h:296
const IndicesType & indices() const
Definition PermutationMatrix.h:334
IndicesType & indices()
Definition PermutationMatrix.h:336
PermutationMatrix & operator=(const TranspositionsBase< Other > &tr)
Definition PermutationMatrix.h:329
Class to view a vector of integers as a permutation matrix.
Definition PermutationMatrix.h:450
const internal::remove_all_t< typename IndicesType::Nested > & indices() const
Definition PermutationMatrix.h:462
Expression of the product of two arbitrary matrices or vectors.
Definition Product.h:202
Namespace containing all symbols from the Eigen library.
Definition Core:137
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:83
const Product< MatrixDerived, PermutationDerived, AliasFreeProduct > operator*(const MatrixBase< MatrixDerived > &matrix, const PermutationBase< PermutationDerived > &permutation)
Definition PermutationMatrix.h:471
Definition EigenBase.h:33
Eigen::Index Index
The interface type of indices.
Definition EigenBase.h:43
Derived & derived()
Definition EigenBase.h:49
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition Meta.h:523