Example #1
0
VALUE cIGraph_modularity(VALUE self, VALUE groups){

  igraph_t *graph;
  igraph_real_t value;
  igraph_vector_t membership;

  VALUE group;

  int i,j;

  Data_Get_Struct(self, igraph_t, graph);

  igraph_vector_init(&membership,igraph_vcount(graph));

  for(i=0;i<RARRAY_LEN(groups);i++){
    group = RARRAY_PTR(groups)[i];
    for(j=0;j<RARRAY_LEN(group);j++){
      igraph_vector_set(&membership,
			cIGraph_get_vertex_id(self,RARRAY_PTR(group)[j]),i);
    }
  }

  igraph_modularity(graph,&membership,&value,NULL);
  
  igraph_vector_destroy(&membership);

  return rb_float_new(value);

}
Example #2
0
int igraph_community_multilevel(const igraph_t *graph,
  const igraph_vector_t *weights, igraph_vector_t *membership,
  igraph_matrix_t *memberships, igraph_vector_t *modularity) {
 
  igraph_t g;
  igraph_vector_t w, m, level_membership;
  igraph_real_t prev_q = -1, q = -1;
  int i, level = 1;
  long int vcount = igraph_vcount(graph);

  /* Make a copy of the original graph, we will do the merges on the copy */
  IGRAPH_CHECK(igraph_copy(&g, graph));
  IGRAPH_FINALLY(igraph_destroy, &g);

  if (weights) {
    IGRAPH_CHECK(igraph_vector_copy(&w, weights));   
    IGRAPH_FINALLY(igraph_vector_destroy, &w);  
  } else {
    IGRAPH_VECTOR_INIT_FINALLY(&w, igraph_ecount(&g));
    igraph_vector_fill(&w, 1);
  }

  IGRAPH_VECTOR_INIT_FINALLY(&m, vcount);
  IGRAPH_VECTOR_INIT_FINALLY(&level_membership, vcount);

  if (memberships || membership) {
    /* Put each vertex in its own community */
    for (i = 0; i < vcount; i++) {
      VECTOR(level_membership)[i] = i;
    }
  }
  if (memberships) {
    /* Resize the membership matrix to have vcount columns and no rows */
    IGRAPH_CHECK(igraph_matrix_resize(memberships, 0, vcount));
  }
  if (modularity) {
    /* Clear the modularity vector */
    igraph_vector_clear(modularity);
  }
  
  while (1) {
    /* Remember the previous modularity and vertex count, do a single step */
    igraph_integer_t step_vcount = igraph_vcount(&g);

    prev_q = q;
    IGRAPH_CHECK(igraph_i_community_multilevel_step(&g, &w, &m, &q));
 
    /* Were there any merges? If not, we have to stop the process */
    if (igraph_vcount(&g) == step_vcount || q < prev_q)
      break;

    if (memberships || membership) {
      for (i = 0; i < vcount; i++) {
        /* Readjust the membership vector */
        VECTOR(level_membership)[i] = VECTOR(m)[(long int) VECTOR(level_membership)[i]];
      }
        
    }

    if (modularity) {
      /* If we have to return the modularity scores, add it to the modularity vector */
      IGRAPH_CHECK(igraph_vector_push_back(modularity, q));
    }

    if (memberships) {
      /* If we have to return the membership vectors at each level, store the new
       * membership vector */
      IGRAPH_CHECK(igraph_matrix_add_rows(memberships, 1));
      IGRAPH_CHECK(igraph_matrix_set_row(memberships, &level_membership, level - 1));
    }

    /* debug("Level: %d Communities: %ld Modularity: %f\n", level, (long int) igraph_vcount(&g),
      (double) q); */

    /* Increase the level counter */
    level++;
  }

  /* It might happen that there are no merges, so every vertex is in its 
     own community. We still might want the modularity score for that. */
  if (modularity && igraph_vector_size(modularity) == 0) {
    igraph_vector_t tmp;
    igraph_real_t mod;
    int i;
    IGRAPH_VECTOR_INIT_FINALLY(&tmp, vcount);
    for (i=0; i<vcount; i++) { VECTOR(tmp)[i]=i; }
    IGRAPH_CHECK(igraph_modularity(graph, &tmp, &mod, weights));
    igraph_vector_destroy(&tmp);
    IGRAPH_FINALLY_CLEAN(1);
    IGRAPH_CHECK(igraph_vector_resize(modularity, 1));
    VECTOR(*modularity)[0]=mod;
  }

  /* If we need the final membership vector, copy it to the output */
  if (membership) {
    IGRAPH_CHECK(igraph_vector_resize(membership, vcount));   
    for (i = 0; i < vcount; i++) {
      VECTOR(*membership)[i] = VECTOR(level_membership)[i];
    }
  }

  /* Destroy the copy of the graph */
  igraph_destroy(&g);

  /* Destroy the temporary vectors */
  igraph_vector_destroy(&m);
  igraph_vector_destroy(&w);
  igraph_vector_destroy(&level_membership);
  IGRAPH_FINALLY_CLEAN(4);

  return 0;
}