MetisSupport.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) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 #ifndef METIS_SUPPORT_H
10 #define METIS_SUPPORT_H
11 
12 // IWYU pragma: private
13 #include "./InternalHeaderCheck.h"
14 
15 namespace Eigen {
24 template <typename StorageIndex>
26  public:
29 
30  template <typename MatrixType>
32  Index m = A.cols();
33  eigen_assert((A.rows() == A.cols()) && "ONLY FOR SQUARED MATRICES");
34  // Get the transpose of the input matrix
35  MatrixType At = A.transpose();
36  // Get the number of nonzeros elements in each row/col of At+A
37  Index TotNz = 0;
38  IndexVector visited(m);
39  visited.setConstant(-1);
40  for (StorageIndex j = 0; j < m; j++) {
41  // Compute the union structure of of A(j,:) and At(j,:)
42  visited(j) = j; // Do not include the diagonal element
43  // Get the nonzeros in row/column j of A
44  for (typename MatrixType::InnerIterator it(A, j); it; ++it) {
45  Index idx = it.index(); // Get the row index (for column major) or column index (for row major)
46  if (visited(idx) != j) {
47  visited(idx) = j;
48  ++TotNz;
49  }
50  }
51  // Get the nonzeros in row/column j of At
52  for (typename MatrixType::InnerIterator it(At, j); it; ++it) {
53  Index idx = it.index();
54  if (visited(idx) != j) {
55  visited(idx) = j;
56  ++TotNz;
57  }
58  }
59  }
60  // Reserve place for A + At
61  m_indexPtr.resize(m + 1);
62  m_innerIndices.resize(TotNz);
63 
64  // Now compute the real adjacency list of each column/row
65  visited.setConstant(-1);
66  StorageIndex CurNz = 0;
67  for (StorageIndex j = 0; j < m; j++) {
68  m_indexPtr(j) = CurNz;
69 
70  visited(j) = j; // Do not include the diagonal element
71  // Add the pattern of row/column j of A to A+At
72  for (typename MatrixType::InnerIterator it(A, j); it; ++it) {
73  StorageIndex idx = it.index(); // Get the row index (for column major) or column index (for row major)
74  if (visited(idx) != j) {
75  visited(idx) = j;
76  m_innerIndices(CurNz) = idx;
77  CurNz++;
78  }
79  }
80  // Add the pattern of row/column j of At to A+At
81  for (typename MatrixType::InnerIterator it(At, j); it; ++it) {
82  StorageIndex idx = it.index();
83  if (visited(idx) != j) {
84  visited(idx) = j;
85  m_innerIndices(CurNz) = idx;
86  ++CurNz;
87  }
88  }
89  }
90  m_indexPtr(m) = CurNz;
91  }
92 
93  template <typename MatrixType>
94  void operator()(const MatrixType& A, PermutationType& matperm) {
95  StorageIndex m = internal::convert_index<StorageIndex>(
96  A.cols()); // must be StorageIndex, because it is passed by address to METIS
97  IndexVector perm(m), iperm(m);
98  // First, symmetrize the matrix graph.
100  int output_error;
101 
102  // Call the fill-reducing routine from METIS
103  output_error = METIS_NodeND(&m, m_indexPtr.data(), m_innerIndices.data(), NULL, NULL, perm.data(), iperm.data());
104 
105  if (output_error != METIS_OK) {
106  // FIXME The ordering interface should define a class of possible errors
107  std::cerr << "ERROR WHILE CALLING THE METIS PACKAGE \n";
108  return;
109  }
110 
111  // Get the fill-reducing permutation
112  // NOTE: If Ap is the permuted matrix then perm and iperm vectors are defined as follows
113  // Row (column) i of Ap is the perm(i) row(column) of A, and row (column) i of A is the iperm(i) row(column) of Ap
114 
115  matperm.resize(m);
116  for (int j = 0; j < m; j++) matperm.indices()(iperm(j)) = j;
117  }
118 
119  protected:
120  IndexVector m_indexPtr; // Pointer to the adjacenccy list of each row/column
121  IndexVector m_innerIndices; // Adjacency list
122 };
123 
124 } // namespace Eigen
125 #endif
#define eigen_assert(x)
Definition: Macros.h:910
MatrixXf MatrixType
Definition: benchmark-blocking-sizes.cpp:52
Definition: MetisSupport.h:25
Matrix< StorageIndex, Dynamic, 1 > IndexVector
Definition: MetisSupport.h:28
void operator()(const MatrixType &A, PermutationType &matperm)
Definition: MetisSupport.h:94
IndexVector m_indexPtr
Definition: MetisSupport.h:120
void get_symmetrized_graph(const MatrixType &A)
Definition: MetisSupport.h:31
IndexVector m_innerIndices
Definition: MetisSupport.h:121
PermutationMatrix< Dynamic, Dynamic, StorageIndex > PermutationType
Definition: MetisSupport.h:27
void resize(Index newSize)
Definition: PermutationMatrix.h:119
const IndicesType & indices() const
Definition: PermutationMatrix.h:334
constexpr EIGEN_DEVICE_FUNC const Scalar * data() const
Definition: PlainObjectBase.h:273
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: PlainObjectBase.h:192
EIGEN_DEVICE_FUNC Derived & setConstant(Index size, const Scalar &val)
Definition: CwiseNullaryOp.h:365
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
Definition: PlainObjectBase.h:294
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: PlainObjectBase.h:191
int * m
Definition: level2_cplx_impl.h:294
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
void METIS_NodeND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *)
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2