void fdp_init_node_edge(graph_t * g) { attrsym_t *E_len; node_t *n; edge_t *e; int nn = agnnodes(g); int i; ndata* alg = N_NEW(nn, ndata); processClusterEdges(g); GD_neato_nlist(g) = N_NEW(nn + 1, node_t *); for (i = 0, n = agfstnode(g); n; n = agnxtnode(g, n)) { neato_init_node (n); ND_alg(n) = alg + i; GD_neato_nlist(g)[i] = n; ND_id(n) = i++; } E_len = agfindattr(g->proto->e, "len"); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { for (e = agfstout(g, n); e; e = agnxtout(g, e)) { init_edge(e, E_len); } } initialPositions(g); }
node_t *UF_union(node_t * u, node_t * v) { if (u == v) return u; if (ND_UF_parent(u) == NULL) { ND_UF_parent(u) = u; ND_UF_size(u) = 1; } else u = UF_find(u); if (ND_UF_parent(v) == NULL) { ND_UF_parent(v) = v; ND_UF_size(v) = 1; } else v = UF_find(v); if (ND_id(u) > ND_id(v)) { ND_UF_parent(u) = v; ND_UF_size(v) += ND_UF_size(u); } else { ND_UF_parent(v) = u; ND_UF_size(u) += ND_UF_size(v); v = u; } return v; }
/* scan_graph_mode: * Prepare the graph and data structures depending on the layout mode. * If Reduce is true, eliminate singletons and trees. Since G may be a * subgraph, we remove the nodes from the root graph. * Return the number of nodes in the reduced graph. */ int scan_graph_mode(graph_t * G, int mode) { int i, lenx, nV, nE, deg; char *str; node_t *np, *xp, *other; double total_len = 0.0; if (Verbose) fprintf(stderr, "Scanning graph %s, %d nodes\n", G->name, agnnodes(G)); /* Eliminate singletons and trees */ if (Reduce) { for (np = agfstnode(G); np; np = xp) { xp = agnxtnode(G, np); deg = degreeKind(G, np, &other); if (deg == 0) { /* singleton node */ agdelete(G->root, np); } else if (deg == 1) { agdelete(G->root, np); xp = prune(G, other, xp); } } } nV = agnnodes(G); nE = agnedges(G); lenx = agindex(G->root->proto->e, "len"); if (mode == MODE_KK) { Epsilon = .0001 * nV; getdouble(G, "epsilon", &Epsilon); if ((str = agget(G->root, "Damping"))) Damping = atof(str); else Damping = .99; GD_neato_nlist(G) = N_NEW(nV + 1, node_t *); for (i = 0, np = agfstnode(G); np; np = agnxtnode(G, np)) { GD_neato_nlist(G)[i] = np; ND_id(np) = i++; ND_heapindex(np) = -1; total_len += setEdgeLen(G, np, lenx); } } else {
/* getPos: */ static real *getPos(Agraph_t * g, spring_electrical_control ctrl) { Agnode_t *n; real *pos = N_NEW(Ndim * agnnodes(g), real); int ix, i; if (agfindnodeattr(g, "pos") == NULL) return pos; for (n = agfstnode(g); n; n = agnxtnode(g, n)) { i = ND_id(n); if (hasPos(n)) { for (ix = 0; ix < Ndim; ix++) { pos[i * Ndim + ix] = ND_pos(n)[ix]; } } } return pos; }
static void sfdpLayout(graph_t * g, spring_electrical_control ctrl, int hops, pointf pad) { real *sizes; real *pos; Agnode_t *n; int flag, i; int n_edge_label_nodes = 0, *edge_label_nodes = NULL; SparseMatrix D = NULL; SparseMatrix A; if (ctrl->method == METHOD_SPRING_MAXENT) /* maxent can work with distance matrix */ A = makeMatrix(g, Ndim, &D); else A = makeMatrix(g, Ndim, NULL); if (ctrl->overlap >= 0) { if (ctrl->edge_labeling_scheme > 0) sizes = getSizes(g, pad, &n_edge_label_nodes, &edge_label_nodes); else sizes = getSizes(g, pad, NULL, NULL); } else sizes = NULL; pos = getPos(g, ctrl); switch (ctrl->method) { case METHOD_SPRING_ELECTRICAL: case METHOD_SPRING_MAXENT: multilevel_spring_electrical_embedding(Ndim, A, D, ctrl, NULL, sizes, pos, n_edge_label_nodes, edge_label_nodes, &flag); break; case METHOD_UNIFORM_STRESS: uniform_stress(Ndim, A, pos, &flag); break; case METHOD_STRESS:{ int maxit = 200; real tol = 0.001; int weighted = TRUE; if (!D){ D = SparseMatrix_get_real_adjacency_matrix_symmetrized(A);/* all distance 1 */ weighted = FALSE; } else { D = SparseMatrix_symmetrize_nodiag(D, FALSE); weighted = TRUE; } if (hops > 0){ SparseMatrix DD; DD = SparseMatrix_distance_matrix_khops(hops, D, weighted); if (Verbose){ fprintf(stderr,"extracted a %d-neighborhood graph of %d edges from a graph of %d edges\n", hops, (DD->nz)/2, (D->nz/2)); } SparseMatrix_delete(D); D = DD; } stress_model(Ndim, A, D, &pos, TRUE, maxit, tol, &flag); } break; } for (n = agfstnode(g); n; n = agnxtnode(g, n)) { real *npos = pos + (Ndim * ND_id(n)); for (i = 0; i < Ndim; i++) { ND_pos(n)[i] = npos[i]; } } free(sizes); free(pos); SparseMatrix_delete (A); if (D) SparseMatrix_delete (D); if (edge_label_nodes) FREE(edge_label_nodes); }