}
static SparseMatrix DistanceMatrix_restrict_cluster(int ncluster, int *clusterp, int *cluster, SparseMatrix P, SparseMatrix R, SparseMatrix D){
-#if 0
- /* this construct a distance matrix of a coarse graph, for a coarsen give by merging all nodes in each cluster */
- SparseMatrix cD = NULL;
- int i, j, nzc;
- int **irn, **jcn;
- real **val;
- int n = D->m;
- int *assignment = NULL;
- int nz;
- int *id = D->ia, jd = D->ja;
- int *mask = NULL;
- int *nnodes, *mask;
- real *d = NULL;
-
-
- assert(D->m == D->n);
- if (!D) return NULL;
- if (D->a && D->type == MATRIX_TYPE_REAL) d = (real*) D->val;
-
- irn = N_GNEW(ncluster,int*);
- jcn = N_GNEW(ncluster,int*);
- val = N_GNEW(ncluster,real*);
- assignment = N_GNEW(n,int);
- nz = N_GNEW(ncluster,int);
- mask = N_GNEW(n,int);
- nnodes = N_GNEW(ncluster,int);
-
-
- /* find ncluster-subgrahs induced by the ncluster -clusters, find the diameter of each,
- then use the radius as the distance from the supernode to the rest of the "world"
- */
- for (i = 0; i < ncluster; i++) nz[i] = 0;
- for (i = 0; i < ncluster; i++){
- for (j = clusterp[i]; j < clusterp[i+1]; j++){
- assert(clusterp[i+1] > clusterp[i]);
- assignment[cluster[j]] = i;
- }
- }
-
- for (i = 0; i < n; i++){/* figure out how many entries per submatrix */
- ic = asignment[i];
- for (j = id[i]; j < id[i+1]; j++){
- if (i != jd[j] && ic == assignment[jd[j]]) {
- nz[ic]++;
- }
- }
- }
- for (i = 0; i < ncluster; i++) {
- irn[i] = N_GNEW(nz[i],int);
- jcn[i] = N_GNEW(nz[i],int);
- val[i] = N_GNEW(nz[i],int);
- val[i] = NULL;
- }
-
-
- for (i = 0; i < ncluster; i++) nz[i] = 0;/* get subgraphs */
- for (i = 0; i < n; i++) mask[i] = -1;
- for (i = 0; i < ncluster; i++) nnodes[i] = -1;
- for (i = 0; i < n; i++){
- ic = asignment[i];
- ii = mask[i];
- if (ii < 0){
- mask[i] = ii = nnodes[ic];
- nnodes[ic]++;
- }
- for (j = id[i]; j < id[i+1]; j++){
- jc = assignment[jd[j]];
- if (i != jd[j] && ic == jc) {
- jj = mask[jd[j]];
- if (jj < 0){
- mask[jd[j]] = jj = nnodes[jc];
- nnodes[jc]++;
- }
- irn[ic][nz[ic]] = ii;
- jcn[ic][nz[ic]] = jj;
- if (d) val[ic][nz[ic]] = d[j];
- }
- }
- }
-
- for (i = 0; i < ncluster; i++){/* form subgraphs */
- SparseMatrix A;
- A = SparseMatrix_from_coordinate_arrays(nz[nz[i]], nnodes[i], nnodes[i], irn[i], jcn[i], (void*) val[i], MATRIX_TYPE_REAL);
-
- SparseMatrix_delete(A);
- }
-
-
- for (i = 0; i < ncluster; i++){
- for (j = clusterp[i]; j < clusterp[i+1]; j++){
- assert(clusterp[i+1] > clusterp[i]);
- irn[nzc] = cluster[j];
- jcn[nzc] = i;
- val[nzc++] = 1.;
- }
- }
- assert(nzc == n);
- cD = SparseMatrix_multiply3(R, D, P);
-
- SparseMatrix_set_symmetric(cD);
- SparseMatrix_set_pattern_symmetric(cD);
- cD = SparseMatrix_remove_diagonal(cD);
-
- FREE(nz);
- FREE(assignment);
- for (i = 0; i < ncluster; i++){
- FREE(irn[i]);
- FREE(jcn[i]);
- FREE(val[i]);
- }
- FREE(irn); FREE(jcn); FREE(val);
- FREE(mask);
- FREE(nnodes);
-
- return cD;
-#endif
return NULL;
}
#define node_degree(i) (ia[(i)+1] - ia[(i)])
-#ifdef UNUSED
-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);
-}
-
-
-
-void dump_distance_edge_length(char *outfile, SparseMatrix A, int dim, real *x){
- int weighted = TRUE;
- int n, i, j, nzz;
- real *dist_matrix = NULL;
- int flag;
- real *dij, *xij, wij, top = 0, bot = 0, t;
-
- int *p = NULL;
- real dmin, dmax, xmax, xmin, bsta, bwidth, *xbin, x25, x75, median;
- int nbins = 30, nsta, nz = 0;
- FILE *fp;
-
- fp = fopen(outfile,"w");
-
- flag = SparseMatrix_distance_matrix(A, weighted, &dist_matrix);
- assert(!flag);
-
- n = A->m;
- dij = MALLOC(sizeof(real)*(n*(n-1)/2));
- xij = MALLOC(sizeof(real)*(n*(n-1)/2));
- for (i = 0; i < n; i++){
- for (j = i+1; j < n; j++){
- dij[nz] = dist_matrix[i*n+j];
- xij[nz] = distance(x, dim, i, j);
- if (dij[nz] > 0){
- wij = 1/(dij[nz]*dij[nz]);
- } else {
- wij = 1;
- }
- top += wij * dij[nz] * xij[nz];
- bot += wij*xij[nz]*xij[nz];
- nz++;
- }
- }
- if (bot > 0){
- t = top/bot;
- } else {
- t = 1;
- }
- fprintf(stderr,"scaling factor = %f\n", t);
-
- for (i = 0; i < nz; i++) xij[i] *= t;
-
- vector_ordering(nz, dij, &p, TRUE);
- dmin = dij[p[0]];
- dmax = dij[p[nz-1]];
- nbins = MIN(nbins, dmax/MAX(1,dmin));/* scale by dmin since edge length of 1 is treated as 72 points in stress/maxent/full_stress */
- bwidth = (dmax - dmin)/nbins;
-
- nsta = 0; bsta = dmin;
- xbin = MALLOC(sizeof(real)*nz);
- nzz = nz;
-
- for (i = 0; i < nbins; i++){
- /* the bin is [dmin + i*(dmax-dmin)/nbins, dmin + (i+1)*(dmax-dmin)/nbins] */
- nz = 0; xmin = xmax = xij[p[nsta]];
- while (nsta < nzz && dij[p[nsta]] >= bsta && dij[p[nsta]] <= bsta + bwidth){
- xbin[nz++] = xij[p[nsta]];
- xmin = MIN(xmin, xij[p[nsta]]);
- xmax = MAX(xmax, xij[p[nsta]]);
- nsta++;
- }
- /* find the median, and 25/75% */
- if (nz > 0){
- median = vector_median(nz, xbin);
- x25 = vector_percentile(nz, xbin, 0.25);
- x75 = vector_percentile(nz, xbin, 0.75);
- fprintf(fp, "%d %f %f %f %f %f %f %f\n", nz, bsta, bsta + bwidth, xmin, x25, median, x75, xmax);
- } else {
- xmin = xmax = median = x25 = x75 = (bsta + 0.5*bwidth);
- }
- bsta += bwidth;
- }
-
- FREE(dij); FREE(xij); FREE(xbin); FREE(p);
- FREE(dist_matrix);
-
-}
-
-real get_full_stress(SparseMatrix A, int dim, real *x, int weighting_scheme){
- /* get the full weighted stress, \sum_ij w_ij (t ||x_i-x_j||^2-d_ij)^2, where t
- is the optimal scaling factor t = \sum w_ij ||x_i-x_j||^2/(\sum w_ij d_ij ||x_i - x_j||),
-
- Matrix A is assume to be sparse and a full distance matrix will be generated.
- We assume undirected graph and only check an undirected edge i--j, not i->j and j->i.
- */
- int weighted = TRUE;
- int n, i, j;
- real *ideal_dist_matrix = NULL, *dist_matrix;
- int flag;
- real t, top = 0, bot = 0, lstress, stress = 0, dij, wij, xij;
- real sne_disimilarity = 0;
-
- flag = SparseMatrix_distance_matrix(A, weighted, &ideal_dist_matrix);
- assert(!flag);
-
- n = A->m;
- dist_matrix = MALLOC(sizeof(real)*n*n);
-
- for (i = 0; i < n; i++){
- for (j = i+1; j < n; j++){
- dij = ideal_dist_matrix[i*n+j];
- assert(dij >= 0);
- xij = distance(x, dim, i, j);
- if (dij > 0){
- switch (weighting_scheme){
- case WEIGHTING_SCHEME_SQR_DIST:
- wij = 1/(dij*dij);
- break;
- case WEIGHTING_SCHEME_INV_DIST:
- wij = 1/(dij);
- break;
- break;
- case WEIGHTING_SCHEME_NONE:
- wij = 1;
- default:
- assert(0);
- }
- } else {
- wij = 1;
- }
- top += wij * dij * xij;
- bot += wij*xij*xij;
- }
- }
- if (bot > 0){
- t = top/bot;
- } else {
- t = 1;
- }
-
- for (i = 0; i < n; i++){
- dist_matrix[i*n+i] = 0.;
- for (j = i+1; j < n; j++){
- dij = ideal_dist_matrix[i*n+j];
- assert(dij >= 0);
- xij = distance(x, dim, i, j);
- dist_matrix[i*n+j] = xij*t;
- dist_matrix[j*n+i] = xij*t;
- if (dij > 0){
- wij = 1/(dij*dij);
- } else {
- wij = 1;
- }
- lstress = (xij*t - dij);
- stress += wij*lstress*lstress;
- }
- }
-
- {int K = 20;
- sne_disimilarity = get_sne_disimilarity(n, ideal_dist_matrix, dist_matrix, K);
- }
-
- get_neighborhood_precision_recall("/tmp/recall.txt", A, ideal_dist_matrix, dist_matrix);
- get_neighborhood_precision_recall("/tmp/precision.txt", A, dist_matrix, ideal_dist_matrix);
-
- fprintf(stderr,"sne_disimilarity = %f\n",sne_disimilarity);
- if (n > 0) fprintf(stderr,"sstress per edge = %f\n",stress/n/(n-1)*2);
-
- FREE(dist_matrix);
- FREE(ideal_dist_matrix);
- return stress;
-}
-#endif
-
-
static 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]|
*/
}
dist = distance(x, dim, i, jd[j]);
- //if (d[j] >= -0.0001*dist){
- // /* sometimes d[j] = 0 and ||x_i-x_j||=0*/
- // dd[j] = d[j]/MAX(0.0001, dist);
if (d[j] == 0){
dd[j] = 0;
} else {
}
dd[j] = d[j]/dist;
-#if 0
- /* if two points are at the same place, we do not want a huge entry,
- as this cause problem with CG./ In any case,
- at thw limit d[j] == ||x[i] - x[jd[j]]||,
- or close. */
- if (dist < -d[j]*0.0000001){
- dd[j] = -10000.;
- } else {
- dd[j] = d[j]/dist;
- }
-#endif
-
}
diag += dd[j];
}
uniform_stress_augment_rhs(m, dim, x, y, alpha, M);
break;
}
-#if UNIMPEMENTED
- case SM_SCHEME_MAXENT:{
-#ifdef GVIEWER
- if (Gviewer){
- char lab[100];
- snprintf(lab, sizeof(lab), "maxent. alpha=%10.2g, iter=%d",
- stress_maxent_data_get_alpha(sm->data), iter);
- gviewer_set_label(lab);
- }
-#endif
- stress_maxent_augment_rhs_fast(sm, dim, x, y, &flag);
- if (flag) goto RETURN;
- break;
- }
- case SM_SCHEME_STRESS_APPROX:{
- stress_approx_augment_rhs(sm, dim, x, y, &flag);
- if (flag) goto RETURN;
- break;
- }
- case SM_SCHEME_STRESS:{
-#ifdef GVIEWER
- if (Gviewer){
- char lab[100];
- snprintf(lab, sizeof(lab), "pmds(k), iter=%d", iter);
- gviewer_set_label(lab);
- }
-#endif
- }
-#endif /* UNIMPEMENTED */
default:
break;
}
{
node_t *n;
edge_t *e;
-#if 0
- int nnodes = agnnodes(g);
- attrsym_t *N_pos = agfindnodeattr(g, "pos");
-#endif
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
neato_init_node(n);
-#if 0
- FIX so that user positions works with multiscale
- user_pos(N_pos, NULL, n, nnodes);
-#endif
}
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
for (e = agfstout(g, n); e; e = agnxtout(g, e))
if (edge_label_nodes) FREE(edge_label_nodes);
}
-#if UNUSED
-static int
-late_mode (graph_t* g, Agsym_t* sym, int dflt)
-{
- char* s;
- int v;
- int rv;
-
- if (!sym) return dflt;
- s = agxget (g, sym);
- if (isdigit(*s)) {
- if ((v = atoi (s)) <= METHOD_UNIFORM_STRESS)
- rv = v;
- else
- rv = dflt;
- }
- else if (isalpha(*s)) {
- if (!strcasecmp(s, "spring"))
- rv = METHOD_SPRING_ELECTRICAL;
- else if (!strcasecmp(s, "maxent"))
- rv = METHOD_SPRING_MAXENT;
- else if (!strcasecmp(s, "stress"))
- rv = METHOD_STRESS;
- else if (!strcasecmp(s, "uniform"))
- rv = METHOD_UNIFORM_STRESS;
- else {
- agerr (AGWARN, "Unknown value \"%s\" for mode attribute\n", s);
- rv = dflt;
- }
- }
- else
- rv = dflt;
- return rv;
-}
-#endif
-
static int
late_smooth (graph_t* g, Agsym_t* sym, int dflt)
{
ctrl->multilevels = late_int(g, agfindgraphattr(g, "levels"), INT_MAX, 0);
ctrl->smoothing = late_smooth(g, agfindgraphattr(g, "smoothing"), SMOOTHING_NONE);
ctrl->tscheme = late_quadtree_scheme(g, agfindgraphattr(g, "quadtree"), QUAD_TREE_NORMAL);
- /* ctrl->method = late_mode(g, agfindgraphattr(g, "mode"), METHOD_SPRING_ELECTRICAL); */
ctrl->method = METHOD_SPRING_ELECTRICAL;
ctrl->beautify_leaves = mapBool (agget(g, "beautify"), FALSE);
ctrl->do_shrinking = mapBool (agget(g, "overlap_shrink"), TRUE);