Eigen  5.0.1
 
Loading...
Searching...
No Matches
Ordering.h
1// SPDX-License-Identifier: MPL-2.0
2
3// This file is part of Eigen, a lightweight C++ template library
4// for linear algebra.
5//
6// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
7//
8// This Source Code Form is subject to the terms of the Mozilla
9// Public License v. 2.0. If a copy of the MPL was not distributed
10// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
11
12#ifndef EIGEN_ORDERING_H
13#define EIGEN_ORDERING_H
14
15// IWYU pragma: private
16#include "./InternalHeaderCheck.h"
17#include "Eigen_Colamd.h"
18
19namespace Eigen {
20
30template <typename StorageIndex>
32 public:
34
39 template <typename MatrixType>
40 void operator()(const MatrixType& mat, PermutationType& perm) const {
41 // AMD only reads the sparsity pattern. Build a column-major view of mat,
42 // then materialize \c pattern(mat + mat^T) directly into a
43 // SparseMatrix<signed char> (1-byte placeholder values), bypassing
44 // Eigen's generic transpose + sparse-sum evaluators.
47 internal::SparsityPatternRef<StorageIndex> pat = internal::make_col_major_pattern_ref(mat, outer_buf, inner_buf);
49 internal::materialize_at_plus_a_pattern(pat, symm);
50 internal::minimum_degree_ordering(symm, perm);
51 }
52
56 template <typename SrcType, unsigned int SrcUpLo>
57 void operator()(const SparseSelfAdjointView<SrcType, SrcUpLo>& mat, PermutationType& perm) const {
58 // Build a column-major pattern view of the underlying matrix and expand
59 // its UpLo triangle to the full symmetric pattern in one pass, bypassing
60 // Eigen's generic selfadjointView assignment evaluator.
63 internal::SparsityPatternRef<StorageIndex> pat =
64 internal::make_col_major_pattern_ref(mat.matrix(), outer_buf, inner_buf);
66 internal::materialize_selfadjoint_pattern<SrcUpLo>(pat, symm);
67 internal::minimum_degree_ordering(symm, perm);
68 }
69};
70
79template <typename StorageIndex>
81 public:
83
85 template <typename MatrixType>
86 void operator()(const MatrixType& /*mat*/, PermutationType& perm) const {
87 perm.resize(0);
88 }
89};
90
99template <typename StorageIndex>
101 public:
103 using IndexVector = Matrix<StorageIndex, Dynamic, 1>;
104
106 template <typename MatrixType>
107 void operator()(const MatrixType& mat, PermutationType& perm) const {
108 using MatrixStorageIndex = typename MatrixType::StorageIndex;
109 Matrix<MatrixStorageIndex, Dynamic, 1> outer_buf, inner_buf;
110 internal::SparsityPatternRef<MatrixStorageIndex> pat =
111 internal::make_col_major_pattern_ref(mat, outer_buf, inner_buf);
112 const StorageIndex m = internal::convert_index<StorageIndex>(pat.innerSize);
113 const StorageIndex n = internal::convert_index<StorageIndex>(pat.outerSize);
114 // Accumulate in Index — Eigen's contract is that any valid nnz fits there
115 // (mat.nonZeros() returns Index), so the sum can't overflow. One
116 // bounds-checked narrow to StorageIndex at the end catches the only real
117 // overflow case (total > StorageIndex range).
118 Index total_nnz = 0;
119 for (Index j = 0; j < pat.outerSize; ++j) total_nnz += pat.nonZeros(j);
120 const StorageIndex nnz = internal::convert_index<StorageIndex>(total_nnz);
121
122 StorageIndex Alen = internal::Colamd::recommended(nnz, m, n);
123 double knobs[internal::Colamd::NKnobs];
124 StorageIndex stats[internal::Colamd::NStats];
125 internal::Colamd::set_defaults(knobs);
126
127 // Colamd writes into A[] in place and needs a contiguous CSC layout, so
128 // always compact per column — handles both compressed and uncompressed
129 // sources uniformly via SparsityPatternRef::nonZeros(j).
130 IndexVector p(n + 1), A(Alen);
131 p(0) = 0;
132 for (StorageIndex j = 0; j < n; ++j) {
133 const Index nz = pat.nonZeros(j);
134 const MatrixStorageIndex* src = pat.inner + pat.outer[j];
135 copy_colamd_indices(src, nz, A.data() + p(j), std::is_same<MatrixStorageIndex, StorageIndex>());
136 p(j + 1) = p(j) + static_cast<StorageIndex>(nz);
137 }
138
139 StorageIndex info = internal::Colamd::compute_ordering(m, n, Alen, A.data(), p.data(), knobs, stats);
140 EIGEN_UNUSED_VARIABLE(info);
141 eigen_assert(info && "COLAMD failed");
142
143 perm.resize(n);
144 for (StorageIndex i = 0; i < n; i++) perm.indices()(p(i)) = i;
145 }
146
147 private:
148 template <typename SrcStorageIndex>
149 static void copy_colamd_indices(const SrcStorageIndex* src, Index nz, StorageIndex* dst, std::true_type) {
150 std::copy_n(src, nz, dst);
151 }
152
153 template <typename SrcStorageIndex>
154 static void copy_colamd_indices(const SrcStorageIndex* src, Index nz, StorageIndex* dst, std::false_type) {
155 for (Index k = 0; k < nz; ++k) dst[k] = internal::convert_index<StorageIndex>(src[k]);
156 }
157};
158
159} // end namespace Eigen
160
161#endif
Definition Ordering.h:31
void operator()(const SparseSelfAdjointView< SrcType, SrcUpLo > &mat, PermutationType &perm) const
Definition Ordering.h:57
void operator()(const MatrixType &mat, PermutationType &perm) const
Definition Ordering.h:40
Definition Ordering.h:100
void operator()(const MatrixType &mat, PermutationType &perm) const
Definition Ordering.h:107
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:188
Definition Ordering.h:80
void operator()(const MatrixType &, PermutationType &perm) const
Definition Ordering.h:86
void resize(Index newSize)
Definition PermutationMatrix.h:165
Permutation matrix.
Definition PermutationMatrix.h:346
constexpr const IndicesType & indices() const
Definition PermutationMatrix.h:400
constexpr const Scalar * data() const
Definition PlainObjectBase.h:261
A versatile sparse matrix representation.
Definition SparseMatrix.h:122
Pseudo expression to manipulate a triangular sparse matrix as a selfadjoint matrix.
Definition SparseSelfAdjointView.h:53