int test_node( int argc, char *argv[] ) { Node *n = node_new( 1.1, 2.5 ); g_return_val_if_fail( NODE_POSITION(n)->x == 1.1, 1 ); g_return_val_if_fail( NODE_POSITION(n)->y == 2.5, 1 ); g_return_val_if_fail( node_is_isolated( n ), 1 ); g_return_val_if_fail( node_is_at_boundary( n ) == NULL, 1 ); g_return_val_if_fail( node_degree( n ) == 0, 1 ); node_free( n ); Mesh *mesh = mesh_new(); Node *n1 = mesh_add_node( mesh, 0.0, 0.0 ); Node *n2 = mesh_add_node( mesh, 1.0, 0.0 ); Node *n3 = mesh_add_node( mesh, 1.0, 1.0 ); Node *n4 = mesh_add_node( mesh, 0.0, 1.0 ); Node *n5 = mesh_add_node( mesh, 0.5, 0.5 ); Edge *e1 = mesh_add_edge( mesh, n1, n2 ); Edge *e2 = mesh_add_edge( mesh, n2, n3 ); Edge *e3 = mesh_add_edge( mesh, n3, n4 ); Edge *e4 = mesh_add_edge( mesh, n4, n1 ); Edge *e5 = mesh_add_edge( mesh, n5, n1 ); Edge *e6 = mesh_add_edge( mesh, n5, n2 ); Edge *e7 = mesh_add_edge( mesh, n5, n3 ); Edge *e8 = mesh_add_edge( mesh, n5, n4 ); mesh_add_element( mesh, &e1->he[0], &e6->he[1], &e5->he[0] ); mesh_add_element( mesh, &e2->he[0], &e7->he[1], &e6->he[0] ); mesh_add_element( mesh, &e3->he[0], &e8->he[1], &e7->he[0] ); mesh_add_element( mesh, &e4->he[0], &e5->he[1], &e8->he[0] ); g_return_val_if_fail( ! node_is_isolated( n1 ), 1 ); g_return_val_if_fail( node_is_at_boundary( n1 ) == &e4->he[1], 1 ); g_return_val_if_fail( node_degree( n1 ) == 3, 1 ); g_return_val_if_fail( ! node_is_isolated( n2 ), 1 ); g_return_val_if_fail( node_is_at_boundary( n2 ) == &e1->he[1], 1 ); g_return_val_if_fail( node_degree( n2 ) == 3, 1 ); g_return_val_if_fail( ! node_is_isolated( n3 ), 1 ); g_return_val_if_fail( node_is_at_boundary( n3 ) == &e2->he[1], 1 ); g_return_val_if_fail( node_degree( n3 ) == 3, 1 ); g_return_val_if_fail( ! node_is_isolated( n4 ), 1 ); g_return_val_if_fail( node_is_at_boundary( n4 ) == &e3->he[1], 1 ); g_return_val_if_fail( node_degree( n4 ) == 3, 1 ); g_return_val_if_fail( ! node_is_isolated( n5 ), 1 ); g_return_val_if_fail( node_is_at_boundary( n5 ) == NULL, 1 ); g_return_val_if_fail( node_degree( n5 ) == 4, 1 ); mesh_free( mesh ); return 0; }
static void maximal_independent_edge_set_heavest_edge_pernode_leaves_first(SparseMatrix A, int randomize, int **cluster, int **clusterp, int *ncluster){ int i, ii, j, *ia, *ja, m, n, *p = NULL, q; real *a, amax = 0; int first = TRUE, jamax = 0; int *matched, nz, ncmax = 0, nz0, nzz,k ; enum {UNMATCHED = -2, MATCHED = -1}; assert(A); assert(SparseMatrix_known_strucural_symmetric(A)); ia = A->ia; ja = A->ja; m = A->m; n = A->n; assert(n == m); *cluster = N_GNEW(m,int); *clusterp = N_GNEW((m+1),int); matched = N_GNEW(m,int); for (i = 0; i < m; i++) matched[i] = i; assert(SparseMatrix_is_symmetric(A, FALSE)); assert(A->type == MATRIX_TYPE_REAL); *ncluster = 0; (*clusterp)[0] = 0; nz = 0; a = (real*) A->a; if (!randomize){ for (i = 0; i < m; i++){ if (matched[i] == MATCHED || node_degree(i) != 1) continue; q = ja[ia[i]]; assert(matched[q] != MATCHED); matched[q] = MATCHED; (*cluster)[nz++] = q; for (j = ia[q]; j < ia[q+1]; j++){ if (q == ja[j]) continue; if (node_degree(ja[j]) == 1){ matched[ja[j]] = MATCHED; (*cluster)[nz++] = ja[j]; } } ncmax = MAX(ncmax, nz - (*clusterp)[*ncluster]); nz0 = (*clusterp)[*ncluster]; if (nz - nz0 <= MAX_CLUSTER_SIZE){ (*clusterp)[++(*ncluster)] = nz; } else { (*clusterp)[++(*ncluster)] = ++nz0; nzz = nz0; for (k = nz0; k < nz && nzz < nz; k++){ nzz += MAX_CLUSTER_SIZE - 1; nzz = MIN(nz, nzz); (*clusterp)[++(*ncluster)] = nzz; } } } #ifdef DEBUG_print if (Verbose) fprintf(stderr, "%d leaves and parents for %d clusters, largest cluster = %d\n",nz, *ncluster, ncmax); #endif for (i = 0; i < m; i++){ first = TRUE; if (matched[i] == MATCHED) continue; for (j = ia[i]; j < ia[i+1]; j++){ if (i == ja[j]) continue; if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){ if (first) { amax = a[j]; jamax = ja[j]; first = FALSE; } else { if (a[j] > amax){ amax = a[j]; jamax = ja[j]; } } } } if (!first){ matched[jamax] = MATCHED; matched[i] = MATCHED; (*cluster)[nz++] = i; (*cluster)[nz++] = jamax; (*clusterp)[++(*ncluster)] = nz; } } /* dan yi dian, wu ban */ for (i = 0; i < m; i++){ if (matched[i] == i){ (*cluster)[nz++] = i; (*clusterp)[++(*ncluster)] = nz; } } assert(nz == n); } else { p = random_permutation(m); for (ii = 0; ii < m; ii++){ i = p[ii]; if (matched[i] == MATCHED || node_degree(i) != 1) continue; q = ja[ia[i]]; assert(matched[q] != MATCHED); matched[q] = MATCHED; (*cluster)[nz++] = q; for (j = ia[q]; j < ia[q+1]; j++){ if (q == ja[j]) continue; if (node_degree(ja[j]) == 1){ matched[ja[j]] = MATCHED; (*cluster)[nz++] = ja[j]; } } ncmax = MAX(ncmax, nz - (*clusterp)[*ncluster]); nz0 = (*clusterp)[*ncluster]; if (nz - nz0 <= MAX_CLUSTER_SIZE){ (*clusterp)[++(*ncluster)] = nz; } else { (*clusterp)[++(*ncluster)] = ++nz0; nzz = nz0; for (k = nz0; k < nz && nzz < nz; k++){ nzz += MAX_CLUSTER_SIZE - 1; nzz = MIN(nz, nzz); (*clusterp)[++(*ncluster)] = nzz; } } } #ifdef DEBUG_print if (Verbose) fprintf(stderr, "%d leaves and parents for %d clusters, largest cluster = %d\n",nz, *ncluster, ncmax); #endif for (ii = 0; ii < m; ii++){ i = p[ii]; first = TRUE; if (matched[i] == MATCHED) continue; for (j = ia[i]; j < ia[i+1]; j++){ if (i == ja[j]) continue; if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){ if (first) { amax = a[j]; jamax = ja[j]; first = FALSE; } else { if (a[j] > amax){ amax = a[j]; jamax = ja[j]; } } } } if (!first){ matched[jamax] = MATCHED; matched[i] = MATCHED; (*cluster)[nz++] = i; (*cluster)[nz++] = jamax; (*clusterp)[++(*ncluster)] = nz; } } /* dan yi dian, wu ban */ for (i = 0; i < m; i++){ if (matched[i] == i){ (*cluster)[nz++] = i; (*clusterp)[++(*ncluster)] = nz; } } FREE(p); } FREE(matched); }
static void maximal_independent_edge_set_heavest_cluster_pernode_leaves_first(SparseMatrix A, int csize, int randomize, int **cluster, int **clusterp, int *ncluster){ int i, ii, j, *ia, *ja, m, n, *p = NULL, q, iv; real *a; int *matched, nz, nz0, nzz,k, nv; enum {UNMATCHED = -2, MATCHED = -1}; real *vlist; assert(A); assert(SparseMatrix_known_strucural_symmetric(A)); ia = A->ia; ja = A->ja; m = A->m; n = A->n; assert(n == m); *cluster = N_GNEW(m,int); *clusterp = N_GNEW((m+1),int); matched = N_GNEW(m,int); vlist = N_GNEW(2*m,real); for (i = 0; i < m; i++) matched[i] = i; assert(SparseMatrix_is_symmetric(A, FALSE)); assert(A->type == MATRIX_TYPE_REAL); *ncluster = 0; (*clusterp)[0] = 0; nz = 0; a = (real*) A->a; p = random_permutation(m); for (ii = 0; ii < m; ii++){ i = p[ii]; if (matched[i] == MATCHED || node_degree(i) != 1) continue; q = ja[ia[i]]; assert(matched[q] != MATCHED); matched[q] = MATCHED; (*cluster)[nz++] = q; for (j = ia[q]; j < ia[q+1]; j++){ if (q == ja[j]) continue; if (node_degree(ja[j]) == 1){ matched[ja[j]] = MATCHED; (*cluster)[nz++] = ja[j]; } } nz0 = (*clusterp)[*ncluster]; if (nz - nz0 <= MAX_CLUSTER_SIZE){ (*clusterp)[++(*ncluster)] = nz; } else { (*clusterp)[++(*ncluster)] = ++nz0; nzz = nz0; for (k = nz0; k < nz && nzz < nz; k++){ nzz += MAX_CLUSTER_SIZE - 1; nzz = MIN(nz, nzz); (*clusterp)[++(*ncluster)] = nzz; } } } for (ii = 0; ii < m; ii++){ i = p[ii]; if (matched[i] == MATCHED) continue; nv = 0; for (j = ia[i]; j < ia[i+1]; j++){ if (i == ja[j]) continue; if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){ vlist[2*nv] = ja[j]; vlist[2*nv+1] = a[j]; nv++; } } if (nv > 0){ qsort(vlist, nv, sizeof(real)*2, scomp); for (j = 0; j < MIN(csize - 1, nv); j++){ iv = (int) vlist[2*j]; matched[iv] = MATCHED; (*cluster)[nz++] = iv; } matched[i] = MATCHED; (*cluster)[nz++] = i; (*clusterp)[++(*ncluster)] = nz; } } /* dan yi dian, wu ban */ for (i = 0; i < m; i++){ if (matched[i] == i){ (*cluster)[nz++] = i; (*clusterp)[++(*ncluster)] = nz; } } FREE(p); FREE(matched); }
SparseMatrix ideal_distance_matrix(SparseMatrix A, int dim, real *x){ /* find the ideal distance between edges, either 1, or |N[i] \Union N[j]| - |N[i] \Intersection N[j]| */ SparseMatrix D; int *ia, *ja, i, j, k, l, nz; real *d; int *mask = NULL; real len, di, sum, sumd; assert(SparseMatrix_is_symmetric(A, FALSE)); D = SparseMatrix_copy(A); ia = D->ia; ja = D->ja; if (D->type != MATRIX_TYPE_REAL){ FREE(D->a); D->type = MATRIX_TYPE_REAL; D->a = N_GNEW(D->nz,real); } d = (real*) D->a; mask = N_GNEW(D->m,int); for (i = 0; i < D->m; i++) mask[i] = -1; for (i = 0; i < D->m; i++){ di = node_degree(i); mask[i] = i; for (j = ia[i]; j < ia[i+1]; j++){ if (i == ja[j]) continue; mask[ja[j]] = i; } for (j = ia[i]; j < ia[i+1]; j++){ k = ja[j]; if (i == k) continue; len = di + node_degree(k); for (l = ia[k]; l < ia[k+1]; l++){ if (mask[ja[l]] == i) len--; } d[j] = len; assert(len > 0); } } sum = 0; sumd = 0; nz = 0; for (i = 0; i < D->m; i++){ for (j = ia[i]; j < ia[i+1]; j++){ if (i == ja[j]) continue; nz++; sum += distance(x, dim, i, ja[j]); sumd += d[j]; } } sum /= nz; sumd /= nz; sum = sum/sumd; for (i = 0; i < D->m; i++){ for (j = ia[i]; j < ia[i+1]; j++){ if (i == ja[j]) continue; d[j] = sum*d[j]; } } return D; }