Exemple #1
0
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;
}
Exemple #2
0
static SparseMatrix check_compatibility(SparseMatrix A, int ne, pedge *edges, int compatibility_method, real tol){
  /* go through the links and make sure edges are compatible */
  SparseMatrix B, C;
  int *ia, *ja, i, j, jj;
  real start;
  real dist;

  B = SparseMatrix_new(1, 1, 1, MATRIX_TYPE_REAL, FORMAT_COORD);
  ia = A->ia; ja = A->ja;
  //SparseMatrix_print("A",A);
  start = clock();
  for (i = 0; i < ne; i++){
    for (j = ia[i]; j < ia[i+1]; j++){
      jj = ja[j];
      if (i == jj) continue;
      if (compatibility_method == COMPATIBILITY_DIST){
	dist = edge_compatibility_full(edges[i], edges[jj]);
      } else if (compatibility_method == COMPATIBILITY_FULL){
	dist = edge_compatibility(edges[i], edges[jj]);
      } 
      /*
      fprintf(stderr,"edge %d = {",i);
      pedge_print("", edges[i]);
      fprintf(stderr,"edge %d = {",jj);
      pedge_print("", edges[jj]);
      fprintf(stderr,"compatibility=%f\n",dist);
      */

      if (ABS(dist) > tol){
	B = SparseMatrix_coordinate_form_add_entries(B, 1, &i, &jj, &dist);
	B = SparseMatrix_coordinate_form_add_entries(B, 1, &jj, &i, &dist);
      }
    }
  }
  C = SparseMatrix_from_coordinate_format(B);
  //SparseMatrix_print("C",C);
  SparseMatrix_delete(B);
  B = C;
  if (Verbose > 1)
    fprintf(stderr, "edge compatibilitu time = %f\n",((real) (clock() - start))/CLOCKS_PER_SEC);
  return B;
}
Exemple #3
0
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;

}
Exemple #4
0
static pedge* modularity_ink_bundling(int dim, int ne, SparseMatrix B, pedge* edges, real angle_param, real angle){
  int *assignment = NULL, flag, nclusters;
  real modularity;
  int *clusterp, *clusters;
  SparseMatrix D, C;
  point_t meet1, meet2;
  real ink0, ink1;
  pedge e;
  int i, j, jj;
  int use_value_for_clustering = TRUE;

  //int use_value_for_clustering = FALSE;

  SparseMatrix BB;

  /* B may contain negative entries */
  BB = SparseMatrix_copy(B);
  BB = SparseMatrix_apply_fun(BB, absfun);
  modularity_clustering(BB, TRUE, 0, use_value_for_clustering, &nclusters, &assignment, &modularity, &flag);
  SparseMatrix_delete(BB);

#ifdef OPENGL
  clusters_global = assignment;
#endif

  assert(!flag);
  if (Verbose > 1) fprintf(stderr, "there are %d clusters, modularity = %f\n",nclusters, modularity);
  
  C = SparseMatrix_new(1, 1, 1, MATRIX_TYPE_PATTERN, FORMAT_COORD);
  
  for (i = 0; i < ne; i++){
    jj = assignment[i];
    SparseMatrix_coordinate_form_add_entries(C, 1, &jj, &i, NULL);
  }
  
  D = SparseMatrix_from_coordinate_format(C);
  SparseMatrix_delete(C);
  clusterp = D->ia;
  clusters = D->ja;
  for (i = 0; i < nclusters; i++){
    ink1 = ink(edges, clusterp[i+1] - clusterp[i], &(clusters[clusterp[i]]), &ink0, &meet1, &meet2, angle_param, angle);
    if (Verbose > 1)
      fprintf(stderr,"nedges = %d ink0 = %f, ink1 = %f\n",clusterp[i+1] - clusterp[i], ink0, ink1);
    if (ink1 < ink0){
      for (j = clusterp[i]; j < clusterp[i+1]; j++){
	/* make this edge 5 points, insert two meeting points at 1 and 2, make 3 the last point */
	edges[clusters[j]] = pedge_double(edges[clusters[j]]);
	e = edges[clusters[j]] = pedge_double(edges[clusters[j]]);
	e->x[1*dim] = meet1.x;
	e->x[1*dim+1] = meet1.y;
	e->x[2*dim] = meet2.x;
	e->x[2*dim+1] = meet2.y;
	e->x[3*dim] = e->x[4*dim];
	e->x[3*dim+1] = e->x[4*dim+1];
	e->npoints = 4;
      }
#ifdef OPENGL
      edges_global = edges;
      drawScene();
#endif
    }
  }
  SparseMatrix_delete(D);
  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;
}
StressMajorizationSmoother SparseStressMajorizationSmoother_new(SparseMatrix A, int dim, real lambda0, real *x,
								int weighting_scheme, int scale_initial_coord){
  /* solve a stress model to achieve the ideal distance among a sparse set of edges recorded in A.
     A must be a real matrix.
   */
  StressMajorizationSmoother sm;
  int i, j, k, m = A->m, *ia, *ja, *iw, *jw, *id, *jd;
  int nz;
  real *d, *w, *lambda;
  real diag_d, diag_w, *a, dist, s = 0, stop = 0, sbot = 0;
  real xdot = 0;

  assert(SparseMatrix_is_symmetric(A, FALSE) && A->type == MATRIX_TYPE_REAL);

  /* if x is all zero, make it random */
  for (i = 0; i < m*dim; i++) xdot += x[i]*x[i];
  if (xdot == 0){
    for (i = 0; i < m*dim; i++) x[i] = 72*drand();
  }

  ia = A->ia;
  ja = A->ja;
  a = (real*) A->a;


  sm = MALLOC(sizeof(struct StressMajorizationSmoother_struct));
  sm->scaling = 1.;
  sm->data = NULL;
  sm->scheme = SM_SCHEME_NORMAL;
  sm->D = A;
  sm->tol_cg = 0.01;
  sm->maxit_cg = sqrt((double) A->m);

  lambda = sm->lambda = MALLOC(sizeof(real)*m);
  for (i = 0; i < m; i++) sm->lambda[i] = lambda0;

  nz = A->nz;

  sm->Lw = SparseMatrix_new(m, m, nz + m, MATRIX_TYPE_REAL, FORMAT_CSR);
  sm->Lwd = SparseMatrix_new(m, m, nz + m, MATRIX_TYPE_REAL, FORMAT_CSR);
  if (!(sm->Lw) || !(sm->Lwd)) {
    StressMajorizationSmoother_delete(sm);
    return NULL;
  }

  iw = sm->Lw->ia; jw = sm->Lw->ja;
  id = sm->Lwd->ia; jd = sm->Lwd->ja;
  w = (real*) sm->Lw->a; d = (real*) sm->Lwd->a;
  iw[0] = id[0] = 0;

  nz = 0;
  for (i = 0; i < m; i++){
    diag_d = diag_w = 0;
    for (j = ia[i]; j < ia[i+1]; j++){
      k = ja[j];
      if (k != i){

	jw[nz] = k;
	dist = a[j];
	switch (weighting_scheme){
	case WEIGHTING_SCHEME_SQR_DIST:
	  if (dist*dist == 0){
	    w[nz] = -100000;
	  } else {
	    w[nz] = -1/(dist*dist);
	  }
	  break;
	case WEIGHTING_SCHEME_INV_DIST:
	  if (dist*dist == 0){
	    w[nz] = -100000;
	  } else {
	    w[nz] = -1/(dist);
	  }
	  break;
	case WEIGHTING_SCHEME_NONE:
	  w[nz] = -1;
	  break;
	default:
	  assert(0);
	  return NULL;
	}
	diag_w += w[nz];
	jd[nz] = k;
	d[nz] = w[nz]*dist;

	stop += d[nz]*distance(x,dim,i,k);
	sbot += d[nz]*dist;
	diag_d += d[nz];

	nz++;
      }
    }

    jw[nz] = i;
    lambda[i] *= (-diag_w);/* alternatively don't do that then we have a constant penalty term scaled by lambda0 */
    w[nz] = -diag_w + lambda[i];

    jd[nz] = i;
    d[nz] = -diag_d;
    nz++;

    iw[i+1] = nz;
    id[i+1] = nz;
  }
  if (scale_initial_coord){
    s = stop/sbot;
  } else {
    s = 1.;
  }
  if (s == 0) {
    return NULL;
  }
  for (i = 0; i < nz; i++) d[i] *= s;


  sm->scaling = s;
  sm->Lw->nz = nz;
  sm->Lwd->nz = nz;

  return sm;
}
StressMajorizationSmoother StressMajorizationSmoother2_new(SparseMatrix A, int dim, real lambda0, real *x, 
							  int ideal_dist_scheme){
  /* use up to dist 2 neighbor */
  /* use up to dist 2 neighbor. This is used in overcoming pherical effect with ideal distance of
     2-neighbors equal graph distance etc.
   */
  StressMajorizationSmoother sm;
  int i, j, k, l, m = A->m, *ia = A->ia, *ja = A->ja, *iw, *jw, *id, *jd;
  int *mask, nz;
  real *d, *w, *lambda;
  real *avg_dist, diag_d, diag_w, dist, s = 0, stop = 0, sbot = 0;
  SparseMatrix ID;

  assert(SparseMatrix_is_symmetric(A, FALSE));

  ID = ideal_distance_matrix(A, dim, x);

  sm = GNEW(struct StressMajorizationSmoother_struct);
  sm->scaling = 1.;
  sm->data = NULL;
  sm->scheme = SM_SCHEME_NORMAL;
  sm->tol_cg = 0.01;
  sm->maxit_cg = sqrt((double) A->m);

  lambda = sm->lambda = N_GNEW(m,real);
  for (i = 0; i < m; i++) sm->lambda[i] = lambda0;
  mask = N_GNEW(m,int);

  avg_dist = N_GNEW(m,real);

  for (i = 0; i < m ;i++){
    avg_dist[i] = 0;
    nz = 0;
    for (j = ia[i]; j < ia[i+1]; j++){
      if (i == ja[j]) continue;
      avg_dist[i] += distance(x, dim, i, ja[j]);
      nz++;
    }
    assert(nz > 0);
    avg_dist[i] /= nz;
  }


  for (i = 0; i < m; i++) mask[i] = -1;

  nz = 0;
  for (i = 0; i < m; i++){
    mask[i] = i;
    for (j = ia[i]; j < ia[i+1]; j++){
      k = ja[j];
      if (mask[k] != i){
	mask[k] = i;
	nz++;
      }
    }
    for (j = ia[i]; j < ia[i+1]; j++){
      k = ja[j];
      for (l = ia[k]; l < ia[k+1]; l++){
	if (mask[ja[l]] != i){
	  mask[ja[l]] = i;
	  nz++;
	}
      }
    }
  }

  sm->Lw = SparseMatrix_new(m, m, nz + m, MATRIX_TYPE_REAL, FORMAT_CSR);
  sm->Lwd = SparseMatrix_new(m, m, nz + m, MATRIX_TYPE_REAL, FORMAT_CSR);
  if (!(sm->Lw) || !(sm->Lwd)) {
    StressMajorizationSmoother_delete(sm);
    return NULL;
  }

  iw = sm->Lw->ia; jw = sm->Lw->ja;

  w = (real*) sm->Lw->a; d = (real*) sm->Lwd->a;

  id = sm->Lwd->ia; jd = sm->Lwd->ja;
  iw[0] = id[0] = 0;

  nz = 0;
  for (i = 0; i < m; i++){
    mask[i] = i+m;
    diag_d = diag_w = 0;
    for (j = ia[i]; j < ia[i+1]; j++){
      k = ja[j];
      if (mask[k] != i+m){
	mask[k] = i+m;

	jw[nz] = k;
	if (ideal_dist_scheme == IDEAL_GRAPH_DIST){
	  dist = 1;
	} else if (ideal_dist_scheme == IDEAL_AVG_DIST){
	  dist = (avg_dist[i] + avg_dist[k])*0.5;
	} else if (ideal_dist_scheme == IDEAL_POWER_DIST){
	  dist = pow(distance_cropped(x,dim,i,k),.4);
	} else {
	  fprintf(stderr,"ideal_dist_scheme value wrong");
	  assert(0);
	  exit(1);
	}

	/*	
	  w[nz] = -1./(ia[i+1]-ia[i]+ia[ja[j]+1]-ia[ja[j]]);
	  w[nz] = -2./(avg_dist[i]+avg_dist[k]);*/
	/* w[nz] = -1.;*//* use unit weight for now, later can try 1/(deg(i)+deg(k)) */
	w[nz] = -1/(dist*dist);

	diag_w += w[nz];

	jd[nz] = k;
	/*
	  d[nz] = w[nz]*distance(x,dim,i,k);
	  d[nz] = w[nz]*dd[j];
	  d[nz] = w[nz]*(avg_dist[i] + avg_dist[k])*0.5;
	*/
	d[nz] = w[nz]*dist;
	stop += d[nz]*distance(x,dim,i,k);
	sbot += d[nz]*dist;
	diag_d += d[nz];

	nz++;
      }
    }

    /* distance 2 neighbors */
    for (j = ia[i]; j < ia[i+1]; j++){
      k = ja[j];
      for (l = ia[k]; l < ia[k+1]; l++){
	if (mask[ja[l]] != i+m){
	  mask[ja[l]] = i+m;

	  if (ideal_dist_scheme == IDEAL_GRAPH_DIST){
	    dist = 2;
	  } else if (ideal_dist_scheme == IDEAL_AVG_DIST){
	    dist = (avg_dist[i] + 2*avg_dist[k] + avg_dist[ja[l]])*0.5;
	  } else if (ideal_dist_scheme == IDEAL_POWER_DIST){
	    dist = pow(distance_cropped(x,dim,i,ja[l]),.4);
	  } else {
	    fprintf(stderr,"ideal_dist_scheme value wrong");
	    assert(0);
	    exit(1);
	  }

	  jw[nz] = ja[l];
	  /*
	    w[nz] = -1/(ia[i+1]-ia[i]+ia[ja[l]+1]-ia[ja[l]]);
	    w[nz] = -2/(avg_dist[i] + 2*avg_dist[k] + avg_dist[ja[l]]);*/
	  /* w[nz] = -1.;*//* use unit weight for now, later can try 1/(deg(i)+deg(k)) */

	  w[nz] = -1/(dist*dist);

	  diag_w += w[nz];

	  jd[nz] = ja[l];
	  /*
	    d[nz] = w[nz]*(distance(x,dim,i,k)+distance(x,dim,k,ja[l]));
	    d[nz] = w[nz]*(dd[j]+dd[l]);
	    d[nz] = w[nz]*(avg_dist[i] + 2*avg_dist[k] + avg_dist[ja[l]])*0.5;
	  */
	  d[nz] = w[nz]*dist;
	  stop += d[nz]*distance(x,dim,ja[l],k);
	  sbot += d[nz]*dist;
	  diag_d += d[nz];

	  nz++;
	}
      }
    }
    jw[nz] = i;
    lambda[i] *= (-diag_w);/* alternatively don't do that then we have a constant penalty term scaled by lambda0 */

    w[nz] = -diag_w + lambda[i];
    jd[nz] = i;
    d[nz] = -diag_d;
    nz++;

    iw[i+1] = nz;
    id[i+1] = nz;
  }
  s = stop/sbot;
  for (i = 0; i < nz; i++) d[i] *= s;

  sm->scaling = s;
  sm->Lw->nz = nz;
  sm->Lwd->nz = nz;

  FREE(mask);
  FREE(avg_dist);
  SparseMatrix_delete(ID);
  return sm;
}
/* ================================ spring and spring-electrical based smoother ================ */
SpringSmoother SpringSmoother_new(SparseMatrix A, int dim, spring_electrical_control ctrl, real *x){
  SpringSmoother sm;
  int i, j, k, l, m = A->m, *ia = A->ia, *ja = A->ja, *id, *jd;
  int *mask, nz;
  real *d, *dd;
  real *avg_dist;
  SparseMatrix ID = NULL;

  assert(SparseMatrix_is_symmetric(A, FALSE));

  ID = ideal_distance_matrix(A, dim, x);
  dd = (real*) ID->a;

  sm = N_GNEW(1,struct SpringSmoother_struct);
  mask = N_GNEW(m,int);

  avg_dist = N_GNEW(m,real);

  for (i = 0; i < m ;i++){
    avg_dist[i] = 0;
    nz = 0;
    for (j = ia[i]; j < ia[i+1]; j++){
      if (i == ja[j]) continue;
      avg_dist[i] += distance(x, dim, i, ja[j]);
      nz++;
    }
    assert(nz > 0);
    avg_dist[i] /= nz;
  }


  for (i = 0; i < m; i++) mask[i] = -1;

  nz = 0;
  for (i = 0; i < m; i++){
    mask[i] = i;
    for (j = ia[i]; j < ia[i+1]; j++){
      k = ja[j];
      if (mask[k] != i){
	mask[k] = i;
	nz++;
      }
    }
    for (j = ia[i]; j < ia[i+1]; j++){
      k = ja[j];
      for (l = ia[k]; l < ia[k+1]; l++){
	if (mask[ja[l]] != i){
	  mask[ja[l]] = i;
	  nz++;
	}
      }
    }
  }

  sm->D = SparseMatrix_new(m, m, nz, MATRIX_TYPE_REAL, FORMAT_CSR);
  if (!(sm->D)){
    SpringSmoother_delete(sm);
    return NULL;
  }

  id = sm->D->ia; jd = sm->D->ja;
  d = (real*) sm->D->a;
  id[0] = 0;

  nz = 0;
  for (i = 0; i < m; i++){
    mask[i] = i+m;
    for (j = ia[i]; j < ia[i+1]; j++){
      k = ja[j];
      if (mask[k] != i+m){
	mask[k] = i+m;
	jd[nz] = k;
	d[nz] = (avg_dist[i] + avg_dist[k])*0.5;
	d[nz] = dd[j];
	nz++;
      }
    }

    for (j = ia[i]; j < ia[i+1]; j++){
      k = ja[j];
      for (l = ia[k]; l < ia[k+1]; l++){
	if (mask[ja[l]] != i+m){
	  mask[ja[l]] = i+m;
	  jd[nz] = ja[l];
	  d[nz] = (avg_dist[i] + 2*avg_dist[k] + avg_dist[ja[l]])*0.5;
	  d[nz] = dd[j]+dd[l];
	  nz++;
	}
      }
    }
    id[i+1] = nz;
  }
  sm->D->nz = nz;
  sm->ctrl = spring_electrical_control_new();
  *(sm->ctrl) = *ctrl;
  sm->ctrl->random_start = FALSE;
  sm->ctrl->multilevels = 1;
  sm->ctrl->step /= 2;
  sm->ctrl->maxiter = 20;

  FREE(mask);
  FREE(avg_dist);
  SparseMatrix_delete(ID);

  return sm;
}
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);
}
Exemple #10
0
Multilevel_MQ_Clustering Multilevel_MQ_Clustering_establish(Multilevel_MQ_Clustering grid, int maxcluster) {
    int *matching = grid->matching;
    SparseMatrix A = grid->A;
    int n = grid->n, level = grid->level, nc = 0, nclusters = n;
    real mq = 0, mq_in = 0, mq_out = 0, mq_new, mq_in_new, mq_out_new, mq_max = 0, mq_in_max = 0, mq_out_max = 0;
    int *ia = A->ia, *ja = A->ja;
    real *a, amax = 0;
    real *deg_intra = grid->deg_intra, *wgt = grid->wgt;
    real *deg_intra_new, *wgt_new = NULL;
    int i, j, k, jj, jc, jmax;
    real *deg_inter, gain = 0, *dout = grid->dout, *dout_new, deg_in_i, deg_in_j, wgt_i, wgt_j, a_ij, dout_i, dout_j, dout_max = 0, wgt_jmax = 0;
    int *mask;
    real maxgain = 0;
    real total_gain = 0;
    SingleLinkedList *neighbors = NULL, lst;


    neighbors = MALLOC(sizeof(SingleLinkedList)*n);
    for (i = 0; i < n; i++) neighbors[i] = NULL;

    mq = grid->mq;
    mq_in = grid->mq_in;
    mq_out = grid->mq_out;

    deg_intra_new = MALLOC(sizeof(real)*n);
    wgt_new = MALLOC(sizeof(real)*n);
    deg_inter = MALLOC(sizeof(real)*n);
    mask = MALLOC(sizeof(int)*n);
    dout_new = MALLOC(sizeof(real)*n);
    for (i = 0; i < n; i++) mask[i] = -1;

    assert(n == A->n);
    for (i = 0; i < n; i++) matching[i] = UNMATCHED;

    /* gain in merging node A into cluster B is
       mq_in_new = mq_in - |E(A,A)|/(V(A))^2 - |E(B,B)|/(V(B))^2 + (|E(A,A)|+|E(B,B)|+|E(A,B)|)/(|V(A)|+|V(B)|)^2
       .         = mq_in - deg_intra(A)/|A|^2 - deg_intra(B)/|B|^2 + (deg_intra(A)+deg_intra(B)+a(A,B))/(|A|+|B|)^2

       mq_out_new = mq_out - |E(A,B)|/(|V(A)|*V(B)|)-\sum_{C and A connected, C!=B} |E(A,C)|/(|V(A)|*|V(C)|)-\sum_{C and B connected,C!=B} |E(B,C)|/(|V(B)|*|V(C)|)
       .                  + \sum_{C connected to A or B, C!=A, C!=B} (|E(A,C)|+|E(B,C)|)/(|V(C)|*(|V(A)|+|V(B)|)
       .          = mq_out + a(A,B)/(|A|*|B|)-\sum_{C and A connected} a(A,C)/(|A|*|C|)-\sum_{C and B connected} a(B,C)/(|B|*|C|)
       .                  + \sum_{C connected to A or B, C!=A, C!=B} (a(A,C)+a(B,C))/(|C|*(|A|+|B|))
       Denote:
       dout(i) = \sum_{j -- i} a(i,j)/|j|
       then

       mq_out_new = mq_out - |E(A,B)|/(|V(A)|*V(B)|)-\sum_{C and A connected, C!=B} |E(A,C)|/(|V(A)|*|V(C)|)-\sum_{C and B connected,C!=B} |E(B,C)|/(|V(B)|*|V(C)|)
       .                  + \sum_{C connected to A or B, C!=A, C!=B} (|E(A,C)|+|E(B,C)|)/(|V(C)|*(|V(A)|+|V(B)|)
       .          = mq_out + a(A,B)/(|A|*|B|)-dout(A)/|A| - dout(B)/|B|
       .                  + (dout(A)+dout(B))/(|A|+|B|) - (a(A,B)/|A|+a(A,B)/|B|)/(|A|+|B|)
       .          = mq_out -dout(A)/|A| - dout(B)/|B| + (dout(A)+dout(B))/(|A|+|B|)
       after merging A and B into cluster AB,
       dout(AB) = dout(A) + dout(B);
       dout(C) := dout(C) - a(A,C)/|A| - a(B,C)/|B| + a(A,C)/(|A|+|B|) + a(B, C)/(|A|+|B|)

       mq_new = mq_in_new/(k-1) - mq_out_new/((k-1)*(k-2))
       gain = mq_new - mq
    */
    a = (real*) A->a;
    for (i = 0; i < n; i++) {
        if (matching[i] != UNMATCHED) continue;
        /* accumulate connections between i and clusters */
        for (j = ia[i]; j < ia[i+1]; j++) {
            jj = ja[j];
            if (jj == i) continue;
            if ((jc=matching[jj]) != UNMATCHED) {
                if (mask[jc] != i) {
                    mask[jc] = i;
                    deg_inter[jc] = a[j];
                } else {
                    deg_inter[jc] += a[j];
                }
            }
        }
        deg_in_i = deg_intra[i];
        wgt_i = wgt[i];
        dout_i = dout[i];

        maxgain = 0;
        jmax = -1;
        for (j = ia[i]; j < ia[i+1]; j++) {
            jj = ja[j];
            if (jj == i) continue;
            jc = matching[jj];
            if (jc == UNMATCHED) {
                a_ij = a[j];
                wgt_j = wgt[jj];
                deg_in_j = deg_intra[jj];
                dout_j = dout[jj];
            } else if (deg_inter[jc] < 0) {
                continue;
            } else {
                a_ij = deg_inter[jc];
                wgt_j = wgt_new[jc];
                deg_inter[jc] = -1; /* so that we do not redo the calulation when we hit another neighbor in cluster jc */
                deg_in_j = deg_intra_new[jc];
                dout_j = dout_new[jc];
            }

            mq_in_new = mq_in - deg_in_i/pow(wgt_i, 2) - deg_in_j/pow(wgt_j,2)
                        + (deg_in_i + deg_in_j + a_ij)/pow(wgt_i + wgt_j,2);

            mq_out_new = mq_out - dout_i/wgt_i - dout_j/wgt_j + (dout_i + dout_j)/(wgt_i + wgt_j);

            if (nclusters > 2) {
                mq_new =  2*(mq_in_new/(nclusters - 1) - mq_out_new/((nclusters - 1)*(nclusters - 2)));
            } else {
                mq_new =  2*mq_in_new/(nclusters - 1);
            }

#ifdef DEBUG
            {   int ncluster;
                double mq2, mq_in2, mq_out2, *dout2;
                int *matching2, nc2 = nc;
                matching2 = MALLOC(sizeof(int)*A->m);
                matching2 = MEMCPY(matching2, matching, sizeof(real)*A->m);
                if (jc != UNMATCHED) {
                    matching2[i] = jc;
                } else {
                    matching2[i] = nc2;
                    matching2[jj] = nc2;
                    nc2++;
                }
                for (k = 0; k < n; k++) if (matching2[k] == UNMATCHED) matching2[k] =nc2++;
                mq2 = get_mq(A, matching2, &ncluster, &mq_in2, &mq_out2, &dout2);
                fprintf(stderr," {dout_i, dout_j}={%f,%f}, {predicted, calculated}: mq = {%f, %f}, mq_in ={%f,%f}, mq_out = {%f,%f}\n",dout_i, dout_j, mq_new, mq2, mq_in_new, mq_in2, mq_out_new, mq_out2);

                mq_new = mq2;

            }
#endif

            gain = mq_new - mq;
            if (Verbose) fprintf(stderr,"gain in merging node %d with node %d = %f-%f = %f\n", i, jj, mq, mq_new, gain);
            if (j == ia[i] || gain > maxgain) {
                maxgain = gain;
                jmax = jj;
                amax = a_ij;
                dout_max = dout_j;
                wgt_jmax = wgt_j;
                mq_max = mq_new;
                mq_in_max = mq_in_new;
                mq_out_max = mq_out_new;
            }

        }

        /* now merge i and jmax */
        if (maxgain > 0 || (nc >= 1 && nc > maxcluster)) {
            total_gain += maxgain;
            jc = matching[jmax];
            if (jc == UNMATCHED) {
                fprintf(stderr, "maxgain=%f, merge %d, %d\n",maxgain, i, jmax);
                neighbors[nc] = SingleLinkedList_new_int(jmax);
                neighbors[nc] = SingleLinkedList_prepend_int(neighbors[nc], i);
                dout_new[nc] = dout_i + dout_max;
                matching[i] = matching[jmax] = nc;
                wgt_new[nc] = wgt[i] + wgt[jmax];
                deg_intra_new[nc] = deg_intra[i] + deg_intra[jmax] + amax;
                nc++;
            } else {
                fprintf(stderr,"maxgain=%f, merge with existing cluster %d, %d\n",maxgain, i, jc);
                neighbors[jc] = SingleLinkedList_prepend_int(neighbors[jc], i);
                dout_new[jc] = dout_i + dout_max;
                wgt_new[jc] += wgt[i];
                matching[i] = jc;
                deg_intra_new[jc] += deg_intra[i] + amax;
            }
            mq = mq_max;
            mq_in = mq_in_max;
            mq_out = mq_out_max;
            nclusters--;
        } else {
            fprintf(stderr,"gain: %f -- no gain, skip merging node %d\n", maxgain, i);
            assert(maxgain <= 0);
            neighbors[nc] = SingleLinkedList_new_int(i);
            matching[i] = nc;
            deg_intra_new[nc] = deg_intra[i];
            wgt_new[nc] = wgt[i];
            nc++;
        }


        /* update scaled outdegree of neighbors of i and its merged node/cluster jmax */
        jc = matching[i];
        lst = neighbors[jc];
        do {
            mask[*((int*) SingleLinkedList_get_data(lst))] = n+i;
            lst = SingleLinkedList_get_next(lst);
        } while (lst);

        lst = neighbors[jc];

        do {
            k = *((int*) SingleLinkedList_get_data(lst));
            for (j = ia[k]; j < ia[k+1]; j++) {
                jj = ja[j];
                if (mask[jj] == n+i) continue;/* link to within cluster */
                if ((jc = matching[jj]) == UNMATCHED) {
                    if (k == i) {
                        dout[jj] += -a[j]/wgt_i + a[j]/(wgt_i + wgt_jmax);
                    } else {
                        dout[jj] += -a[j]/wgt_jmax + a[j]/(wgt_i + wgt_jmax);
                    }
                } else {
                    if (k == i) {
                        dout_new[jc] += -a[j]/wgt_i + a[j]/(wgt_i + wgt_jmax);
                    } else {
                        dout_new[jc] += -a[j]/wgt_jmax + a[j]/(wgt_i + wgt_jmax);
                    }
                }
            }
            lst = SingleLinkedList_get_next(lst);
        } while (lst);

    }

    fprintf(stderr,"verbose=%d\n",Verbose);
    if (Verbose) fprintf(stderr,"mq = %f new mq = %f level = %d, n = %d, nc = %d, gain = %g, mq_in = %f, mq_out = %f\n", mq, mq + total_gain,
                             level, n, nc, total_gain, mq_in, mq_out);

#ifdef DEBUG
    {   int ncluster;

        mq = get_mq(A, matching, &ncluster, &mq_in, &mq_out, &dout);
        fprintf(stderr," mq = %f\n",mq);

    }
#endif

    if (nc >= 1 && (total_gain > 0 || nc < n)) {
        /* now set up restriction and prolongation operator */
        SparseMatrix P, R, R0, B, cA;
        real one = 1.;
        Multilevel_MQ_Clustering cgrid;

        R0 = SparseMatrix_new(nc, n, 1, MATRIX_TYPE_REAL, FORMAT_COORD);
        for (i = 0; i < n; i++) {
            jj = matching[i];
            SparseMatrix_coordinate_form_add_entries(R0, 1, &jj, &i, &one);
        }
        R = SparseMatrix_from_coordinate_format(R0);
        SparseMatrix_delete(R0);
        P = SparseMatrix_transpose(R);
        B = SparseMatrix_multiply(R, A);
        if (!B) goto RETURN;
        cA = SparseMatrix_multiply(B, P);
        if (!cA) goto RETURN;
        SparseMatrix_delete(B);
        grid->P = P;
        grid->R = R;
        level++;
        cgrid = Multilevel_MQ_Clustering_init(cA, level);
        deg_intra_new = REALLOC(deg_intra_new, nc*sizeof(real));
        wgt_new = REALLOC(wgt_new, nc*sizeof(real));
        cgrid->deg_intra = deg_intra_new;
        cgrid->mq = grid->mq + total_gain;
        cgrid->wgt = wgt_new;
        dout_new =  REALLOC(dout_new, nc*sizeof(real));
        cgrid->dout = dout_new;

        cgrid = Multilevel_MQ_Clustering_establish(cgrid, maxcluster);

        grid->next = cgrid;
        cgrid->prev = grid;
    } else {
        /* no more improvement, stop and final clustering found */
        for (i = 0; i < n; i++) matching[i] = i;

        FREE(deg_intra_new);
        FREE(wgt_new);
        FREE(dout_new);
    }

RETURN:
    for (i = 0; i < n; i++) SingleLinkedList_delete(neighbors[i], free);
    FREE(neighbors);

    FREE(deg_inter);
    FREE(mask);
    return grid;
}
Exemple #11
0
static SparseMatrix get_overlap_graph(int dim, int n, real *x, real *width){
  scan_point *scanpointsx, *scanpointsy;
  int i, k, neighbor;
  SparseMatrix A = NULL, B = NULL;
  rb_red_blk_node *newNode, *newNode0;
  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 {
      assert(scanpointsx[i].node >= n);

      newNode = newNode0 = RBExactQuery(treey, &(scanpointsy[k + n]));

#ifdef DEBUG_RBTREE
      fprintf(stderr, "poping..%d....", scanpointsy[k + n].node);
      treey->PrintKey(newNode->key);
#endif

      assert(treey->nil != newNode);
      while ((newNode) && ((newNode = TreePredecessor(treey, newNode)) != treey->nil) && ((scan_point *)newNode->key)->node != k){
	neighbor = (((scan_point *)newNode->key)->node)%n;
	A = SparseMatrix_coordinate_form_add_entries(A, 1, &neighbor, &k, &one);
#ifdef DEBUG_RBTREE
	fprintf(stderr,"%d %d\n",k,neighbor);
#endif

      }

#ifdef DEBUG_RBTREE
      fprintf(stderr, "deleteing...");
      treey->PrintKey(newNode0->key);
#endif

      if (newNode0) RBDelete(treey,newNode0);
      if (newNode != treey->nil && newNode != newNode0) {

#ifdef DEBUG_RBTREE
	fprintf(stderr, "deleting2...");
	treey->PrintKey(newNode->key)
#endif

	if (newNode0) RBDelete(treey,newNode);
      }
    }
  }
UniformStressSmoother UniformStressSmoother_new(int dim, SparseMatrix A, real *x, real alpha, real M, int *flag){
  UniformStressSmoother sm;
  int i, j, k, m = A->m, *ia = A->ia, *ja = A->ja, *iw, *jw, *id, *jd;
  int nz;
  real *d, *w, *a = (real*) A->a;
  real diag_d, diag_w, dist, epsilon = 0.01;

  assert(SparseMatrix_is_symmetric(A, FALSE));

  sm = MALLOC(sizeof(struct StressMajorizationSmoother_struct));
  sm->data = NULL;
  sm->scheme = SM_SCHEME_UNIFORM_STRESS;
  sm->lambda = NULL;
  sm->data = MALLOC(sizeof(real)*2);
  ((real*) sm->data)[0] = alpha;
  ((real*) sm->data)[1] = M;
  sm->data_deallocator = FREE;

  /* Lw and Lwd have diagonals */
  sm->Lw = SparseMatrix_new(m, m, A->nz + m, MATRIX_TYPE_REAL, FORMAT_CSR);
  sm->Lwd = SparseMatrix_new(m, m, A->nz + m, MATRIX_TYPE_REAL, FORMAT_CSR);
  iw = sm->Lw->ia; jw = sm->Lw->ja;
  id = sm->Lwd->ia; jd = sm->Lwd->ja;
  w = (real*) sm->Lw->a; d = (real*) sm->Lwd->a;

  if (!(sm->Lw) || !(sm->Lwd)) {
    StressMajorizationSmoother_delete(sm);
    return NULL;
  }

  iw = sm->Lw->ia; jw = sm->Lw->ja;
  id = sm->Lwd->ia; jd = sm->Lwd->ja;
  w = (real*) sm->Lw->a; d = (real*) sm->Lwd->a;
  iw[0] = id[0] = 0;

  nz = 0;
  for (i = 0; i < m; i++){
    diag_d = diag_w = 0;
    for (j = ia[i]; j < ia[i+1]; j++){
      k = ja[j];
      if (k != i){
	dist = MAX(ABS(a[j]), epsilon);
	jd[nz] = jw[nz] = k;
	w[nz] = -1/(dist*dist);
	w[nz] = -1.;
	d[nz] = w[nz]*dist;
	diag_w += w[nz];
	diag_d += d[nz];
	nz++;
      }
    }
    jd[nz] = jw[nz] = i;
    w[nz] = -diag_w;
    d[nz] = -diag_d;
    nz++;

    iw[i+1] = nz;
    id[i+1] = nz;

  }

  sm->Lw->nz = nz;
  sm->Lwd->nz = nz;

  return sm;
}