Пример #1
0
uint8_t _update_avg_graph(
  graph_t      *gin,
  graph_t      *gavg,
  array_t      *nodemap,
  edge_weight_t edgeweight,
  uint16_t      ninputs) {

  uint64_t  i;
  uint64_t  j;
  uint32_t  ginnodes;
  uint32_t *nbrs;
  uint32_t  nnbrs;
  uint32_t  outi;
  uint32_t  outj;
  float     inwt;
  float     outwt;

  ginnodes = graph_num_nodes(gin);

  for (i = 0; i < ginnodes; i++) {

    outi  = *(uint32_t *)array_getd(nodemap, i);
    nnbrs = graph_num_neighbours(gin, i);
    nbrs  = graph_get_neighbours(gin, i);

    for (j = 0; j < nnbrs; j++) {

      if (i >= nbrs[j]) continue;

      outj = *(uint32_t *)array_getd(nodemap, nbrs[j]);

      /*will have no effect if edge already exists*/
      graph_add_edge(gavg, outi, outj, 0.0);

      inwt  = graph_get_weight(gin,  i,    nbrs[j]);
      outwt = graph_get_weight(gavg, outi, outj);

      switch (edgeweight) {

        case SUM_WEIGHTS: outwt = outwt + inwt;           break;
        case COUNT_EDGES: outwt = outwt + 1;              break;
        case AVG_WEIGHTS: outwt = outwt + (inwt/ninputs); break;
        default:          goto fail;
      }

      if (graph_set_weight(gavg, outi, outj, outwt))
         goto fail;
    }
  }

  return 0;

fail:
  return 1;
}
Пример #2
0
static int path_decimate(gstack_t** path, double* Dmin)
{
  size_t n = gstack_size(*path);
  double xmin = pow(*Dmin, 2);
  corner_t cns[n];

  /*
    empty the stack into a corners array - we do this
    in reverse order so the gstack_push below gives us
    a gstack_t in the same order (needed due to an
    assumed orientation of the boundaries)
  */

  for (int i = 0 ; i < n ; i++)
    {
      if (gstack_pop(*path, (void*)(cns+(n-1-i))) != 0)
	return -1;
    }

  /* cache metric tensor and ellipse centres */

  vector_t e[n];
  m2_t mt[n];

  for (int i = 0 ; i < n ; i++)
    {
      ellipse_t E;

      arrow_ellipse(&(cns[i].A), &E);

      mt[i] = ellipse_mt(E);
      e[i] = E.centre;
    }

  /* create ellipse intersection graph */

  graph_t G;

  if (graph_init(n,&G) != 0)
    return -1;

  size_t err = 0;

  for (int i = 0 ; i < n-1 ; i++)
    {
      for (int j = i+1 ; j < n ; j++)
	{
	  double x = contact_mt(vsub(e[j], e[i]), mt[i], mt[j]);

	  /*
	    failed contact() results in edge not being
	    included in the graph so possible intesection
	    survives - save the number for a warning (below)
	  */

	  if (x<0)
	    {
	      err++;
	      continue;
	    }

	  /*
	    weight of each node is the maximum of the
	    contact-distances of the incoming edges
	  */

	  if (x < xmin)
	    {
	      double
		w1 = graph_get_weight(G, i),
		w2 = graph_get_weight(G, j);

	      graph_set_weight(G, i, MAX(w1, x));
	      graph_set_weight(G, j, MAX(w2, x));

	      if (graph_add_edge(G, i, j) != 0)
		return -1;
	    }
	}
    }

  if (err)
    fprintf(stderr,"failed contact distance for %i pairs\n", (int)err);

  /* greedy node deletion to obtain non-intersecting subset */

  size_t maxi;

  while (graph_maxedge(G, &maxi) > 0)
    if (graph_del_node(G, maxi) != 0)
      return -1;

  /* dump back into gstack */

  for (int i = 0 ; i < n ; i++)
    if ( !graph_node_flag(G, i, NODE_STALE) )
      gstack_push(*path, (void*)(cns+i));

  graph_clean(&G);

  return 1;
}