28 assert(
A->m == (
size_t)
A->n);
37 grid->delete_top_level_A =
false;
44 if (
grid->level == 0) {
45 if (
grid->delete_top_level_A) {
65 int nsuper, *super =
NULL, *superp =
NULL;
68 assert(
A->is_pattern_symmetric);
71 const size_t m =
A->m;
73 assert((
size_t)n == m);
75 *clusterp =
gv_calloc(m + 1,
sizeof(
int));
76 size_t *
const matched =
gv_calloc(m,
sizeof(
size_t));
78 for (
size_t i = 0; i < m; i++) matched[i] = i;
90 for (
int i = 0; i < nsuper; i++){
91 if (superp[i+1] - superp[i] <= 1)
continue;
92 nz0 = (*clusterp)[*ncluster];
93 for (j = superp[i]; j < superp[i+1]; j++){
94 matched[super[j]] = MATCHED;
95 (*cluster)[nz++] = super[j];
97 (*clusterp)[++(*ncluster)] = nz;
101 if (nz > nz0) (*clusterp)[++(*ncluster)] = nz;
105 for (
size_t ii = 0; ii < m; ii++){
106 const size_t i = p[ii];
108 if (matched[i] == MATCHED)
continue;
109 for (j = ia[i]; j < ia[i+1]; j++){
110 if ((
int)i == ja[j])
continue;
111 if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){
125 matched[jamax] = MATCHED;
126 matched[i] = MATCHED;
127 (*cluster)[nz++] = (int)i;
128 (*cluster)[nz++] = jamax;
129 (*clusterp)[++(*ncluster)] = nz;
133 for (
size_t i = 0; i < m; i++){
134 if (matched[i] == i) {
135 (*cluster)[nz++] = (int)i;
136 (*clusterp)[++(*ncluster)] = nz;
154 int *cluster=
NULL, *clusterp=
NULL, ncluster;
156 assert(
A->m == (
size_t)
A->n);
160 const size_t n =
A->m;
163 assert(ncluster <= (
int)n);
165 if (nc == (
int)n || nc <
minsize) {
176 for (i = 0; i < ncluster; i++){
177 for (j = clusterp[i]; j < clusterp[i+1]; j++){
178 assert(clusterp[i+1] > clusterp[i]);
179 irn[nzc] = cluster[j];
193 (*cA)->is_symmetric =
true;
194 (*cA)->is_pattern_symmetric =
true;
220 if (
Verbose) fprintf(stderr,
"nc=%d n = %d\n",nc,n);
247 for (i = 0; i < n; i++) fputs (
" ", stderr);
258 fprintf(stderr,
"level -- %d, n = %d, nz = %d nz/n = %f\n",
grid->level,
grid->n,
grid->A->nz,
grid->A->nz/(
double)
grid->n);
266 fprintf(stderr,
" maxlevel reached, coarsening stops\n");
277 cgrid->
n = (int)cA->
m;
295 if (
A != A0)
grid->delete_top_level_A =
true;
void print_padding(int n)
static const double min_coarsen_factor
Multilevel Multilevel_get_coarsest(Multilevel grid)
static void Multilevel_establish(Multilevel grid, const Multilevel_control ctrl)
static void maximal_independent_edge_set_heavest_edge_pernode_supernodes_first(SparseMatrix A, int **cluster, int **clusterp, int *ncluster)
void Multilevel_delete(Multilevel grid)
static void Multilevel_coarsen(SparseMatrix A, SparseMatrix *cA, SparseMatrix *P, SparseMatrix *R)
static Multilevel Multilevel_init(SparseMatrix A)
Multilevel Multilevel_new(SparseMatrix A0, const Multilevel_control ctrl)
static void Multilevel_coarsen_internal(SparseMatrix A, SparseMatrix *cA, SparseMatrix *P, SparseMatrix *R)
void SparseMatrix_decompose_to_supervariables(SparseMatrix A, int *ncluster, int **cluster, int **clusterp)
SparseMatrix SparseMatrix_transpose(SparseMatrix A)
bool SparseMatrix_is_symmetric(SparseMatrix A, bool test_pattern_symmetry_only)
SparseMatrix SparseMatrix_from_coordinate_arrays(size_t nz, size_t m, int n, int *irn, int *jcn, const void *val, int type, size_t sz)
SparseMatrix SparseMatrix_multiply(SparseMatrix A, SparseMatrix B)
SparseMatrix SparseMatrix_divide_row_by_degree(SparseMatrix A)
void SparseMatrix_delete(SparseMatrix A)
SparseMatrix SparseMatrix_get_real_adjacency_matrix_symmetrized(SparseMatrix A)
SparseMatrix SparseMatrix_multiply3(SparseMatrix A, SparseMatrix B, SparseMatrix C)
SparseMatrix SparseMatrix_remove_diagonal(SparseMatrix A)
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
static void * gv_alloc(size_t size)
size_t * gv_permutation(size_t bound)