void mq_clustering(SparseMatrix A, int inplace, int maxcluster, int use_value, int *nclusters, int **assignment, real *mq, int *flag) { /* find a clustering of vertices by maximize mq A: symmetric square matrix n x n. If real value, value will be used as edges weights, otherwise edge weights are considered as 1. inplace: whether A can e modified. If true, A will be modified by removing diagonal. maxcluster: used to specify the maximum number of cluster desired, e.g., maxcluster=10 means that a maximum of 10 clusters . is desired. this may not always be realized, and mq may be low when this is specified. Default: maxcluster = 0 nclusters: on output the number of clusters assignment: dimension n. Node i is assigned to cluster "assignment[i]". 0 <= assignment < nclusters */ SparseMatrix B; *flag = 0; assert(A->m == A->n); B = SparseMatrix_symmetrize(A, FALSE); if (!inplace && B == A) { B = SparseMatrix_copy(A); } B = SparseMatrix_remove_diagonal(B); if (B->type != MATRIX_TYPE_REAL || !use_value) B = SparseMatrix_set_entries_to_real_one(B); hierachical_mq_clustering(B, maxcluster, nclusters, assignment, mq, flag); if (B != A) SparseMatrix_delete(B); }
void stress_model_core(int dim, SparseMatrix B, real **x, int edge_len_weighted, int maxit_sm, real tol, int *flag){ int m; SparseStressMajorizationSmoother sm; real lambda = 0; /*int maxit_sm = 1000, i; tol = 0.001*/ int i; SparseMatrix A = B; if (!SparseMatrix_is_symmetric(A, FALSE) || A->type != MATRIX_TYPE_REAL){ if (A->type == MATRIX_TYPE_REAL){ A = SparseMatrix_symmetrize(A, FALSE); A = SparseMatrix_remove_diagonal(A); } else { A = SparseMatrix_get_real_adjacency_matrix_symmetrized(A); } } A = SparseMatrix_remove_diagonal(A); *flag = 0; m = A->m; if (!x) { *x = MALLOC(sizeof(real)*m*dim); srand(123); for (i = 0; i < dim*m; i++) (*x)[i] = drand(); } if (edge_len_weighted){ sm = SparseStressMajorizationSmoother_new(A, dim, lambda, *x, WEIGHTING_SCHEME_SQR_DIST, TRUE);/* do not under weight the long distances */ //sm = SparseStressMajorizationSmoother_new(A, dim, lambda, *x, WEIGHTING_SCHEME_INV_DIST, TRUE);/* do not under weight the long distances */ } else { sm = SparseStressMajorizationSmoother_new(A, dim, lambda, *x, WEIGHTING_SCHEME_NONE, TRUE);/* weight the long distances */ } if (!sm) { *flag = -1; goto RETURN; } sm->tol_cg = 0.1; /* we found that there is no need to solve the Laplacian accurately */ sm->scheme = SM_SCHEME_STRESS; SparseStressMajorizationSmoother_smooth(sm, dim, *x, maxit_sm, tol); for (i = 0; i < dim*m; i++) { (*x)[i] /= sm->scaling; } SparseStressMajorizationSmoother_delete(sm); RETURN: if (A != B) SparseMatrix_delete(A); }
static void get_neighborhood_precision_recall(char *outfile, SparseMatrix A0, real *ideal_dist_matrix, real *dist_matrix){ SparseMatrix A = A0; int i, j, k, n = A->m; // int *ia, *ja; int *g_order = NULL, *p_order = NULL;/* ordering using graph/physical distance */ real *gdist, *pdist, radius; int np_neighbors; int ng_neighbors; /*number of (graph theoretical) neighbors */ real node_dist;/* distance of a node to the center node */ real true_positive; real recall; FILE *fp; fp = fopen(outfile,"w"); if (!SparseMatrix_is_symmetric(A, FALSE)){ A = SparseMatrix_symmetrize(A, FALSE); } // ia = A->ia; // ja = A->ja; for (k = 5; k <= 50; k+= 5){ recall = 0; for (i = 0; i < n; i++){ gdist = &(ideal_dist_matrix[i*n]); vector_ordering(n, gdist, &g_order, TRUE); pdist = &(dist_matrix[i*n]); vector_ordering(n, pdist, &p_order, TRUE); ng_neighbors = MIN(n-1, k); /* set the number of closest neighbor in the graph space to consider, excluding the node itself */ np_neighbors = ng_neighbors;/* set the number of closest neighbor in the embedding to consider, excluding the node itself */ radius = pdist[p_order[np_neighbors]]; true_positive = 0; for (j = 1; j <= ng_neighbors; j++){ node_dist = pdist[g_order[j]];/* the phisical distance for j-th closest node (in graph space) */ if (node_dist <= radius) true_positive++; } recall += true_positive/np_neighbors; } recall /= n; fprintf(fp,"%d %f\n", k, recall); } fprintf(stderr,"wrote precision/recall in file %s\n", outfile); fclose(fp); if (A != A0) SparseMatrix_delete(A); FREE(g_order); FREE(p_order); }
SparseMatrix get_distance_matrix(SparseMatrix A, real scaling){ /* get a distance matrix from a graph, at the moment we just symmetrize the matrix. At the moment if the matrix is not real, we just assume distance of 1 among edges. Then we apply scaling to the entire matrix */ SparseMatrix B; real *val; int i; if (A->type == MATRIX_TYPE_REAL){ B = SparseMatrix_symmetrize(A, FALSE); } else { B = SparseMatrix_get_real_adjacency_matrix_symmetrized(A); } val = (real*) B->a; if (scaling != 1) for (i = 0; i < B->nz; i++) val[i] *= scaling; return B; }
SparseMatrix call_tri(int n, int dim, real * x) { real one = 1; int i, ii, jj; SparseMatrix A; SparseMatrix B; int* edgelist = NULL; real* xv = N_GNEW(n, real); real* yv = N_GNEW(n, real); int numberofedges; for (i = 0; i < n; i++) { xv[i] = x[i * 2]; yv[i] = x[i * 2 + 1]; } if (n > 2) { edgelist = delaunay_tri (xv, yv, n, &numberofedges); } else { numberofedges = 0; } A = SparseMatrix_new(n, n, 1, MATRIX_TYPE_REAL, FORMAT_COORD); for (i = 0; i < numberofedges; i++) { ii = edgelist[i * 2]; jj = edgelist[i * 2 + 1]; SparseMatrix_coordinate_form_add_entries(A, 1, &(ii), &(jj), &one); } if (n == 2) { /* if two points, add edge i->j */ ii = 0; jj = 1; SparseMatrix_coordinate_form_add_entries(A, 1, &(ii), &(jj), &one); } for (i = 0; i < n; i++) { SparseMatrix_coordinate_form_add_entries(A, 1, &i, &i, &one); } B = SparseMatrix_from_coordinate_format(A); SparseMatrix_delete(A); A = SparseMatrix_symmetrize(B, FALSE); SparseMatrix_delete(B); B = A; free (edgelist); free (xv); free (yv); return B; }
void stress_model(int dim, SparseMatrix B, real **x, int maxit_sm, real tol, int *flag){ int m; SparseStressMajorizationSmoother sm; real lambda = 0; /*int maxit_sm = 1000, i; tol = 0.001*/ int i; SparseMatrix A = B; if (!SparseMatrix_is_symmetric(A, FALSE) || A->type != MATRIX_TYPE_REAL){ if (A->type == MATRIX_TYPE_REAL){ A = SparseMatrix_symmetrize(A, FALSE); A = SparseMatrix_remove_diagonal(A); } else { A = SparseMatrix_get_real_adjacency_matrix_symmetrized(A); } } A = SparseMatrix_remove_diagonal(A); *flag = 0; m = A->m; if (!x) { *x = MALLOC(sizeof(real)*m*dim); srand(123); for (i = 0; i < dim*m; i++) (*x)[i] = drand(); } sm = SparseStressMajorizationSmoother_new(A, dim, lambda, *x, WEIGHTING_SCHEME_NONE);/* do not under weight the long distances */ if (!sm) { *flag = -1; goto RETURN; } SparseStressMajorizationSmoother_smooth(sm, dim, *x, maxit_sm, 0.001); for (i = 0; i < dim*m; i++) { (*x)[i] /= sm->scaling; } SparseStressMajorizationSmoother_delete(sm); RETURN: if (A != B) SparseMatrix_delete(A); }
SparseMatrix call_tri2(int n, int dim, real * xx) { real *x, *y; v_data *delaunay; int i, j; SparseMatrix A; SparseMatrix B; real one = 1; x = N_GNEW(n, real); y = N_GNEW(n, real); for (i = 0; i < n; i++) { x[i] = xx[dim * i]; y[i] = xx[dim * i + 1]; } delaunay = UG_graph(x, y, n, 0); A = SparseMatrix_new(n, n, 1, MATRIX_TYPE_REAL, FORMAT_COORD); for (i = 0; i < n; i++) { for (j = 1; j < delaunay[i].nedges; j++) { SparseMatrix_coordinate_form_add_entries(A, 1, &i, &(delaunay[i]. edges[j]), &one); } } for (i = 0; i < n; i++) { SparseMatrix_coordinate_form_add_entries(A, 1, &i, &i, &one); } B = SparseMatrix_from_coordinate_format(A); B = SparseMatrix_symmetrize(B, FALSE); SparseMatrix_delete(A); free (x); free (y); freeGraph (delaunay); return B; }
pedge* edge_bundling(SparseMatrix A0, int dim, real *x, int maxit_outer, real K, int method, int nneighbor, int compatibility_method, int max_recursion, real angle_param, real angle, int open_gl){ /* bundle edges. A: edge graph x: edge i is at {p,q}, . where p = x[2*dim*i : 2*dim*i+dim-1] . and q = x[2*dim*i+dim : 2*dim*i+2*dim-1] maxit_outer: max outer iteration for force directed bundling. Every outer iter subdivide each edge segment into 2. K: norminal edge length in force directed bundling method: which method to use. nneighbor: number of neighbors to be used in forming nearest neighbor graph. Used only in agglomerative method compatibility_method: which method to use to calculate compatibility. Used only in force directed. max_recursion: used only in agglomerative method. Specify how many level of recursion to do to bundle bundled edges again open_gl: whether to plot in X. */ int ne = A0->m; pedge *edges; SparseMatrix A = A0, B = NULL; int i; real tol = 0.001; int k; real step0 = 0.1, start = 0.0; int maxit = 10; int flag; assert(A->n == ne); edges = MALLOC(sizeof(pedge)*ne); for (i = 0; i < ne; i++){ edges[i] = pedge_new(2, dim, &(x[dim*2*i])); } A = SparseMatrix_symmetrize(A0, TRUE); if (Verbose) start = clock(); if (method == METHOD_INK){ /* go through the links and make sure edges are compatible */ B = check_compatibility(A, ne, edges, compatibility_method, tol); edges = modularity_ink_bundling(dim, ne, B, edges, angle_param, angle); } else if (method == METHOD_INK_AGGLOMERATE){ #ifdef HAVE_ANN /* plan: merge a node with its neighbors if doing so improve. Form coarsening graph, repeat until no more ink saving */ edges = agglomerative_ink_bundling(dim, A, edges, nneighbor, max_recursion, angle_param, angle, open_gl, &flag); assert(!flag); #else agerr (AGERR, "Graphviz built without approximate nearest neighbor library ANN; agglomerative inking not available\n"); edges = edges; #endif } else if (method == METHOD_FD){/* FD method */ /* go through the links and make sure edges are compatible */ B = check_compatibility(A, ne, edges, compatibility_method, tol); for (k = 0; k < maxit_outer; k++){ for (i = 0; i < ne; i++){ edges[i] = pedge_double(edges[i]); } step0 = step0/2; edges = force_directed_edge_bundling(B, edges, maxit, step0, K, open_gl); } } else if (method == METHOD_NONE){ edges = edges; } else { assert(0); } if (Verbose) fprintf(stderr, "total edge bundling cpu = %f\n",((real) (clock() - start))/CLOCKS_PER_SEC); if (B != A) SparseMatrix_delete(B); if (A != A0) SparseMatrix_delete(A); return edges; }
static SparseMatrix get_overlap_graph(int dim, int n, real *x, real *width, int check_overlap_only){ /* if check_overlap_only = TRUE, we only check whether there is one overlap */ scan_point *scanpointsx, *scanpointsy; int i, k, neighbor; SparseMatrix A = NULL, B = NULL; rb_red_blk_node *newNode, *newNode0, *newNode2 = NULL; rb_red_blk_tree* treey; real one = 1; A = SparseMatrix_new(n, n, 1, MATRIX_TYPE_REAL, FORMAT_COORD); scanpointsx = N_GNEW(2*n,scan_point); for (i = 0; i < n; i++){ scanpointsx[2*i].node = i; scanpointsx[2*i].x = x[i*dim] - width[i*dim]; scanpointsx[2*i].status = INTV_OPEN; scanpointsx[2*i+1].node = i+n; scanpointsx[2*i+1].x = x[i*dim] + width[i*dim]; scanpointsx[2*i+1].status = INTV_CLOSE; } qsort(scanpointsx, 2*n, sizeof(scan_point), comp_scan_points); scanpointsy = N_GNEW(2*n,scan_point); for (i = 0; i < n; i++){ scanpointsy[i].node = i; scanpointsy[i].x = x[i*dim+1] - width[i*dim+1]; scanpointsy[i].status = INTV_OPEN; scanpointsy[i+n].node = i; scanpointsy[i+n].x = x[i*dim+1] + width[i*dim+1]; scanpointsy[i+n].status = INTV_CLOSE; } treey = RBTreeCreate(NodeComp,NodeDest,InfoDest,NodePrint,InfoPrint); for (i = 0; i < 2*n; i++){ #ifdef DEBUG_RBTREE fprintf(stderr," k = %d node = %d x====%f\n",(scanpointsx[i].node)%n, (scanpointsx[i].node), (scanpointsx[i].x)); #endif k = (scanpointsx[i].node)%n; if (scanpointsx[i].status == INTV_OPEN){ #ifdef DEBUG_RBTREE fprintf(stderr, "inserting..."); treey->PrintKey(&(scanpointsy[k])); #endif RBTreeInsert(treey, &(scanpointsy[k]), NULL); /* add both open and close int for y */ #ifdef DEBUG_RBTREE fprintf(stderr, "inserting2..."); treey->PrintKey(&(scanpointsy[k+n])); #endif RBTreeInsert(treey, &(scanpointsy[k+n]), NULL); } else { real bsta, bbsta, bsto, bbsto; int ii; assert(scanpointsx[i].node >= n); newNode = newNode0 = RBExactQuery(treey, &(scanpointsy[k + n])); ii = ((scan_point *)newNode->key)->node; assert(ii < n); bsta = scanpointsy[ii].x; bsto = scanpointsy[ii+n].x; #ifdef DEBUG_RBTREE fprintf(stderr, "poping..%d....yinterval={%f,%f}\n", scanpointsy[k + n].node, bsta, bsto); treey->PrintKey(newNode->key); #endif assert(treey->nil != newNode); while ((newNode) && ((newNode = TreePredecessor(treey, newNode)) != treey->nil)){ neighbor = (((scan_point *)newNode->key)->node)%n; bbsta = scanpointsy[neighbor].x; bbsto = scanpointsy[neighbor+n].x;/* the y-interval of the node that has one end of the interval lower than the top of the leaving interval (bsto) */ #ifdef DEBUG_RBTREE fprintf(stderr," predecessor is node %d y = %f\n", ((scan_point *)newNode->key)->node, ((scan_point *)newNode->key)->x); #endif if (neighbor != k){ if (ABS(0.5*(bsta+bsto) - 0.5*(bbsta+bbsto)) < 0.5*(bsto-bsta) + 0.5*(bbsto-bbsta)){/* if the distance of the centers of the interval is less than sum of width, we have overlap */ A = SparseMatrix_coordinate_form_add_entries(A, 1, &neighbor, &k, &one); #ifdef DEBUG_RBTREE fprintf(stderr,"====================================== %d %d\n",k,neighbor); #endif if (check_overlap_only) goto check_overlap_RETURN; } } else { newNode2 = newNode; } } #ifdef DEBUG_RBTREE fprintf(stderr, "deleteing..."); treey->PrintKey(newNode0->key); #endif if (newNode0) RBDelete(treey,newNode0); if (newNode2 && newNode2 != treey->nil && newNode2 != newNode0) { #ifdef DEBUG_RBTREE fprintf(stderr, "deleteing2..."); treey->PrintKey(newNode2->key); #endif if (newNode0) RBDelete(treey,newNode2); } } } check_overlap_RETURN: FREE(scanpointsx); FREE(scanpointsy); RBTreeDestroy(treey); B = SparseMatrix_from_coordinate_format(A); SparseMatrix_delete(A); A = SparseMatrix_symmetrize(B, FALSE); SparseMatrix_delete(B); if (Verbose) fprintf(stderr, "found %d clashes\n", A->nz); return A; }
void country_graph_coloring(int seed, SparseMatrix A, int **p, real *norm_1){ int n = A->m, i, j, jj; SparseMatrix L, A2; int *ia = A->ia, *ja = A->ja; int a = -1.; real nrow; real *v = NULL; real norm1[2], norm2[2], norm11[2], norm22[2], norm = n; real pi, pj; int improved = TRUE; assert(A->m == A->n); A2 = SparseMatrix_symmetrize(A, TRUE); ia = A2->ia; ja = A2->ja; /* Laplacian */ L = SparseMatrix_new(n, n, 1, MATRIX_TYPE_REAL, FORMAT_COORD); for (i = 0; i < n; i++){ nrow = 0.; for (j = ia[i]; j < ia[i+1]; j++){ jj = ja[j]; if (jj != i){ nrow ++; L = SparseMatrix_coordinate_form_add_entries(L, 1, &i, &jj, &a); } } L = SparseMatrix_coordinate_form_add_entries(L, 1, &i, &i, &nrow); } L = SparseMatrix_from_coordinate_format(L); /* largest eigen vector */ { int maxit = 100; real tol = 0.00001; power_method(L, seed, maxit, tol, &v); } vector_ordering(n, v, p, TRUE); /* swapping */ while (improved){ improved = FALSE; norm = n; for (i = 0; i < n; i++){ get_local_12_norm(n, i, ia, ja, *p, norm1); for (j = 0; j < n; j++){ if (j == i) continue; get_local_12_norm(n, j, ia, ja, *p, norm2); norm = MIN(norm, norm2[0]); pi = (*p)[i]; pj = (*p)[j]; (*p)[i] = pj; (*p)[j] = pi; get_local_12_norm(n, i, ia, ja, *p, norm11); get_local_12_norm(n, j, ia, ja, *p, norm22); if (MIN(norm11[0],norm22[0]) > MIN(norm1[0],norm2[0])){ // || //(MIN(norm11[0],norm22[0]) == MIN(norm1[0],norm2[0]) && norm11[1]+norm22[1] > norm1[1]+norm2[1])) { improved = TRUE; norm1[0] = norm11[0]; norm1[1] = norm11[1]; continue; } (*p)[i] = pi; (*p)[j] = pj; } } if (Verbose) { get_12_norm(n, ia, ja, *p, norm1); fprintf(stderr, "norm = %f", norm); fprintf(stderr, "norm1 = %f, norm2 = %f\n", norm1[0], norm1[1]); } } get_12_norm(n, ia, ja, *p, norm1); *norm_1 = norm1[0]; if (A2 != A) SparseMatrix_delete(A2); SparseMatrix_delete(L); }
fprintf(stderr, "deleting2..."); treey->PrintKey(newNode->key) #endif if (newNode0) RBDelete(treey,newNode); } } } FREE(scanpointsx); FREE(scanpointsy); RBTreeDestroy(treey); B = SparseMatrix_from_coordinate_format(A); SparseMatrix_delete(A); A = SparseMatrix_symmetrize(B, FALSE); SparseMatrix_delete(B); if (Verbose) fprintf(stderr, "found %d clashes\n", A->nz); return A; } /* ============================== label overlap smoother ==================*/ static void relative_position_constraints_delete(void *d){ relative_position_constraints data; if (!d) return; data = (relative_position_constraints) d; if (data->irn) FREE(data->irn);