suanPan
sort_rcm.h
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (C) 2017-2022 Theodore Chang
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  ******************************************************************************/
40 #ifndef RCM_H
41 #define RCM_H
42 
44 
45 uvec sort_rcm(const std::vector<uvec>&, const uvec&);
46 
47 template<typename eT> uvec sort_rcm(const SpMat<eT>& MEAT) {
48 #ifdef SUANPAN_DEBUG
49  if(!MEAT.is_square()) throw logic_error("RCM() can only be applied to square matrix.\n");
51 
52  wall_clock TM;
53  TM.tic();
54 #endif
55 
57  auto S = MEAT.n_cols;
58 
60  uvec E(S, fill::none);
61  suanpan_for(0llu, S, [&](const uword I) { E(I) = MEAT.col(I).n_nonzero; });
62 
63  std::vector<uvec> A(S);
64  suanpan_for(0llu, S, [&](const uword K) {
65  unsigned J = 0;
66  uvec IDX(E(K));
67  for(auto L = MEAT.begin_col(K); L != MEAT.end_col(K); ++L) IDX(J++) = L.row();
68  A[K] = IDX(sort_index(E(IDX)));
69  });
70 
72  uvec G = sort_index(E);
73 
75  std::vector<bool> M(S, false);
77  uvec R(S, fill::zeros);
78 
83 
86  uword IDXA = 0, IDXB = S - 1, IDXC = S - 1;
87 
90 
96  while(IDXA < S) {
97  if(IDXB == IDXC) {
99  while(IDXA < S && M[G(IDXA)]) ++IDXA;
102  if(IDXA == S) break;
104  R(IDXC--) = G(IDXA);
106  M[G(IDXA++)] = true;
107  }
113  for(const auto& IDX : A[R(IDXB--)]) if(!M[IDX]) M[R(IDXC--) = IDX] = true;
114  }
115 
116 #ifdef SUANPAN_DEBUG
117  suanpan_debug("RCM algorithm takes %.5E seconds.\n", TM.toc());
118 #endif
119 
120  return R;
121 }
122 
123 template<typename eT> uvec sort_rcm(const Mat<eT>& MEAT) { return sort_rcm(SpMat<eT>(MEAT)); }
124 
125 template<typename dt, typename it> uvec sort_rcm(const triplet_form<dt, it>& triplet_mat) {
126  csc_form<dt, uword> csc_mat(triplet_mat);
127 
128  const uvec row_idx(csc_mat.row_idx, csc_mat.n_elem, false, false);
129  const uvec col_ptr(csc_mat.col_ptr, csc_mat.n_cols + 1, false, false);
130  const Col<dt> val_idx(csc_mat.val_idx, csc_mat.n_elem, false, false);
131 
132  return sort_rcm({row_idx, col_ptr, val_idx, csc_mat.n_rows, csc_mat.n_cols});
133 }
134 
135 #endif
136 
const index_t n_elem
Definition: csc_form.hpp:52
Definition: csc_form.hpp:25
uvec sort_rcm(const std::vector< uvec > &, const uvec &)
Definition: sort_rcm.cpp:20
Definition: triplet_form.hpp:62
const index_t n_rows
Definition: csc_form.hpp:50
void suanpan_for(const IT start, const IT end, F &&FN)
Definition: utility.h:24
const index_t n_cols
Definition: csc_form.hpp:51