/* Erdos-Renyi : G(n,M) */ igraph_t *ggen_generate_erdos_gnm(gsl_rng *r, unsigned long n, unsigned long m) { igraph_matrix_t adj; igraph_t *g = NULL; int err; unsigned long i,j; unsigned long added_edges = 0; ggen_error_start_stack(); if(r == NULL) GGEN_SET_ERRNO(GGEN_EINVAL); if(m > (n*(n-1)/2)) GGEN_SET_ERRNO(GGEN_EINVAL); g = malloc(sizeof(igraph_t)); GGEN_CHECK_ALLOC(g); GGEN_FINALLY3(free,g,1); if(m == 0 || n <= 1) { GGEN_CHECK_IGRAPH(igraph_empty(g,n,1)); goto end; } if(m == (n*(n-1))/2) { GGEN_CHECK_IGRAPH(igraph_full_citation(g,n,1)); goto end; } GGEN_CHECK_IGRAPH(igraph_matrix_init(&adj,n,n)); GGEN_FINALLY(igraph_matrix_destroy,&adj); igraph_matrix_null(&adj); while(added_edges < m) { GGEN_CHECK_GSL_DO(i = gsl_rng_uniform_int(r,n)); GGEN_CHECK_GSL_DO(j = gsl_rng_uniform_int(r,n)); if(i < j && igraph_matrix_e(&adj,i,j) == 0) { igraph_matrix_set(&adj,i,j,1); added_edges++; } } GGEN_CHECK_IGRAPH(igraph_adjacency(g,&adj,IGRAPH_ADJ_DIRECTED)); end: ggen_error_clean(1); return g; ggen_error_label: return NULL; }
/*__________________________________________________________________________ MAIN CYCLE (FLTK CYCLE) ____*/ void mainidle_cb(void*){ //this routine updates the program. //thus, it computes the EVOLUTION double shooted; double dens, err; double totdens, toterr, totimerr; char s[100]; // ---- running controls AND PRINTING if( (amstepping==0 && runningcontrol==1 && graphisloaded==1 && ticks<=maxtime ) || (amstepping==1 && runningcontrol==1 && graphisloaded==1 && ticks<=maxtime && tickstep<=step-1) ) { Evolution(deltat); //PRINTS if((int)printdatabutton->value()==1){ //if have steady state if(usesteady==1){ igraph_matrix_t activation; igraph_matrix_init(&activation,nodesnumber,totrun); igraph_matrix_null(&activation); igraph_vector_t correlation; igraph_vector_init(&correlation,(nodesnumber*nodesnumber)); igraph_vector_null(&correlation); fprintf(output1,"%i ", ticks); fprintf(output2,"%i ", ticks); fprintf(output5,"%i ", ticks); fprintf(output6,"%i ", ticks); totdens=0; toterr=0; for(int i=0;i<nodesnumber;++i){ shooted=0; dens=0; err=0; for(int j=0; j<totrun; ++j){ dens=dens+MATRIX(density,i,j); err=err+((VECTOR(statstate)[i]-MATRIX(density,i,j))*(VECTOR(statstate)[i]-MATRIX(density,i,j))); shooted=shooted+MATRIX(loss,i,j); if(MATRIX(loss,i,j)!=0){++MATRIX(activation,i,j);} } dens=dens/totrun; err=sqrt(err)/totrun; shooted=shooted/totrun; totdens=totdens+dens; toterr=toterr+err; fprintf(output1,"%f ",dens); fprintf(output2,"%f ",err); fprintf(output5,"%f ",shooted); } totdens=totdens/nodesnumber; toterr=toterr/nodesnumber; fprintf(output1,"%f ",totdens); fprintf(output2,"%f ",toterr); // printf("\n\n ACTIVATION MATRIX \n \n"); print_matrix_ur(&activation,stdout); printf("\n\n"); // ---- CORRELATION --- igraph_vector_t meanactivation; igraph_vector_init(&meanactivation,nodesnumber); igraph_vector_null(&meanactivation); //calculate mean activation for (int j=0; j<totrun; ++j) { for (int i=0; i<nodesnumber; ++i) { VECTOR(meanactivation)[i]=VECTOR(meanactivation)[i]+MATRIX(activation,i,j); } } igraph_vector_scale(&meanactivation,1./totrun); //calculate actual correlation for (int x=0; x<nodesnumber ; ++x) { for(int y=0; y<nodesnumber; ++y){ double prod=0; for (int j=0; j<totrun; ++j) { prod=prod+ ( MATRIX(activation,x,j)*MATRIX(activation,y,j) ); } prod=prod/totrun; VECTOR(correlation)[(x*nodesnumber+y)] = prod - (VECTOR(meanactivation)[x]*VECTOR(meanactivation)[y]); } } igraph_vector_destroy(&meanactivation); for (int i=0; i<(nodesnumber*nodesnumber); ++i) { fprintf(output6,"%f ",VECTOR(correlation)[i]); } //calculate error on run igraph_matrix_t distl1; igraph_matrix_t distimel1; igraph_matrix_init(&distl1,nodesnumber,totrun); igraph_matrix_init(&distimel1,nodesnumber,totrun); igraph_matrix_null(&distl1); igraph_matrix_null(&distimel1); igraph_vector_t rundistl1; igraph_vector_t rundistimel1; igraph_vector_init(&rundistl1,totrun); igraph_vector_init(&rundistimel1,totrun); igraph_vector_null(&rundistl1); igraph_vector_null(&rundistimel1); toterr=0; totimerr=0; //for every run for(int j=0;j<totrun;++j){ //i evaluate the distance between the state and the stationary state (toterr) and the distance between old and new density (totimerr) for(int i=0; i<nodesnumber; ++i) { //L1 DISTANCE WRT STATSTATE & DENSITY MATRIX(distl1,i,j)=fabs(VECTOR(statstate)[i]-MATRIX(density,i,j)); //L1 DISTANCE WRT OLD DENSITY & DENSITY MATRIX(distimel1,i,j)=fabs(MATRIX(densityold,i,j)-MATRIX(density,i,j)); } } igraph_matrix_rowsum(&distl1,&rundistl1); igraph_matrix_rowsum(&distimel1,&rundistimel1); igraph_vector_scale(&rundistl1,(1./nodesnumber)); igraph_vector_scale(&rundistimel1,(1./nodesnumber)); toterr= (double)( igraph_vector_sum(&rundistl1) ) / (double)totrun ; totimerr= (double)( igraph_vector_sum(&rundistimel1)) / (double)totrun; igraph_vector_destroy(&rundistl1); igraph_vector_destroy(&rundistimel1); igraph_matrix_destroy(&distl1); igraph_matrix_destroy(&distimel1); fprintf(output2,"%f %f",toterr, totimerr); fprintf(output1,"\n"); fprintf(output2,"\n"); fprintf(output5,"\n"); fprintf(output6,"\n"); //if i have BRIDGES ("clustered" graph), I print the traffic on the BRIDGES, using "output3" file if(isclustered==1){ //for each bridge fprintf(output3,"%i ",ticks); for(int nbri=0; nbri<igraph_matrix_ncol(&bridgeslinks); ++nbri){ for(int i=0; i<igraph_matrix_nrow(&bridgeslinks);++i){ double tfl=0; for(int j=0; j<totrun; ++j){ int beid; beid=(int)MATRIX(bridgeslinks,i,nbri); tfl=tfl+MATRIX(flux,beid,j); } fprintf(output3,"%f ",tfl); } } fprintf(output3,"\n"); } igraph_matrix_destroy(&activation); igraph_vector_destroy(&correlation); } //if i HAVENT STEADY STATE else { fprintf(output1,"%i ", ticks); fprintf(output5,"%i ", ticks); for(int i=0;i<nodesnumber;++i){ shooted=0; dens=0; for(int j=0; j<totrun; ++j){ dens=dens+MATRIX(density,i,j); shooted=shooted+MATRIX(loss,i,j); } dens=dens/totrun; shooted=shooted/totrun; fprintf(output1,"%f " ,dens); fprintf(output5,"%f " ,shooted); } fprintf(output1,"\n"); fprintf(output5,"\n"); } } } if((ticks==maxtime || tickstep==step) && runningcontrol==1){ run(); } // ---- no graph loaded if(graphisloaded==0 && rewrite==1) { runbutton->deactivate(); sprintf(s,"No\nnetwork\nloaded"); databuff->text(s); } // ---- graph loaded else { runbutton->activate(); if(islattice==1 && rewrite==1){ if(istoro==1){ sprintf(s,"Nodes=%i\nToroidal\nLattice\n%iD Side=%i",nodesnumber, latticedim, latticeside); } else{ sprintf(s,"Nodes=%i\nLattice\n%iD Side=%i",nodesnumber, latticedim, latticeside); } databuff->text(s); } else if(rewrite==1){ sprintf(s,"Nodes=%i",nodesnumber); databuff->text(s); } } //have path if(havepath==1 && rewrite==1){pathbuff->text(path); } else if(havepath==0 && rewrite==1){pathbuff->text("No Path");} if(error==1 && rewrite==1){ sprintf(s,errorstring); databuff->text(s); } if (ticks<=maxtime){ scene->redraw(); datascene->redraw(); } rewrite=0; //Fl::repeat_timeout(1.0, mainidle_cb); }
/* Initializing elements */ void Matrix::null() noexcept { igraph_matrix_null(ptr()); }
int igraph_cocitation_real(const igraph_t *graph, igraph_matrix_t *res, igraph_vs_t vids, igraph_neimode_t mode, igraph_vector_t *weights) { long int no_of_nodes=igraph_vcount(graph); long int no_of_vids; long int from, i, j, k, l, u, v; igraph_vector_t neis=IGRAPH_VECTOR_NULL; igraph_vector_t vid_reverse_index; igraph_vit_t vit; IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); no_of_vids = IGRAPH_VIT_SIZE(vit); /* Create a mapping from vertex IDs to the row of the matrix where * the result for this vertex will appear */ IGRAPH_VECTOR_INIT_FINALLY(&vid_reverse_index, no_of_nodes); igraph_vector_fill(&vid_reverse_index, -1); for (IGRAPH_VIT_RESET(vit), i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { v = IGRAPH_VIT_GET(vit); if (v < 0 || v >= no_of_nodes) IGRAPH_ERROR("invalid vertex ID in vertex selector", IGRAPH_EINVAL); VECTOR(vid_reverse_index)[v] = i; } IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_matrix_resize(res, no_of_vids, no_of_nodes)); igraph_matrix_null(res); /* The result */ for (from=0; from<no_of_nodes; from++) { igraph_real_t weight = 1; IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) from, mode)); if (weights) weight = VECTOR(*weights)[from]; for (i=0; i < igraph_vector_size(&neis)-1; i++) { u = (long int) VECTOR(neis)[i]; k = (long int) VECTOR(vid_reverse_index)[u]; for (j=i+1; j<igraph_vector_size(&neis); j++) { v = (long int) VECTOR(neis)[j]; l = (long int) VECTOR(vid_reverse_index)[v]; if (k != -1) MATRIX(*res, k, v) += weight; if (l != -1) MATRIX(*res, l, u) += weight; } } } /* Clean up */ igraph_vector_destroy(&neis); igraph_vector_destroy(&vid_reverse_index); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(3); return 0; }
int igraph_dijkstra_shortest_paths(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t from, const igraph_vector_t *wghts, igraph_neimode_t mode) { long int no_of_nodes=igraph_vcount(graph); long int no_of_from; igraph_real_t *shortest; igraph_real_t min,alt; int i, j, uj, included; igraph_integer_t eid, u,v; igraph_vector_t q; igraph_vit_t fromvit; igraph_vector_t neis; IGRAPH_CHECK(igraph_vit_create(graph, from, &fromvit)); IGRAPH_FINALLY(igraph_vit_destroy, &fromvit); no_of_from=IGRAPH_VIT_SIZE(fromvit); if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE); } shortest=calloc(no_of_nodes, sizeof(igraph_real_t)); if (shortest==0) { IGRAPH_ERROR("shortest paths failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(free, shortest); IGRAPH_CHECK(igraph_matrix_resize(res, no_of_from, no_of_nodes)); igraph_matrix_null(res); for (IGRAPH_VIT_RESET(fromvit), i=0; !IGRAPH_VIT_END(fromvit); IGRAPH_VIT_NEXT(fromvit), i++) { //Start shortest and previous for(j=0;j<no_of_nodes;j++){ shortest[j] = INFINITY; //memset(previous,NAN, no_of_nodes); } shortest[(int)IGRAPH_VIT_GET(fromvit)] = 0; igraph_vector_init_seq(&q,0,no_of_nodes-1); while(igraph_vector_size(&q) != 0){ min = INFINITY; u = no_of_nodes; uj = igraph_vector_size(&q); for(j=0;j<igraph_vector_size(&q);j++){ v = VECTOR(q)[j]; if(shortest[(int)v] < min){ min = shortest[(int)v]; u = v; uj = j; } } if(min == INFINITY) break; igraph_vector_remove(&q,uj); igraph_vector_init(&neis,0); igraph_neighbors(graph,&neis,u,mode); for(j=0;j<igraph_vector_size(&neis);j++){ v = VECTOR(neis)[j]; //v must be in Q included = 0; for(j=0;j<igraph_vector_size(&q);j++){ if(v == VECTOR(q)[j]){ included = 1; break; } } if(!included) continue; igraph_get_eid(graph,&eid,u,v,1); alt = shortest[(int)u] + VECTOR(*wghts)[(int)eid]; if(alt < shortest[(int)v]){ shortest[(int)v] = alt; } } igraph_vector_destroy(&neis); } for(j=0;j<no_of_nodes;j++){ MATRIX(*res,i,j) = shortest[j]; } igraph_vector_destroy(&q); } /* Clean */ free(shortest); igraph_vit_destroy(&fromvit); IGRAPH_FINALLY_CLEAN(2); return 0; }
int igraph_revolver_mes_p_p(const igraph_t *graph, igraph_lazy_inclist_t *inclist, igraph_matrix_t *kernel, igraph_matrix_t *sd, igraph_matrix_t *norm, igraph_matrix_t *cites, const igraph_matrix_t *debug, igraph_vector_ptr_t *debugres, const igraph_vector_t *st, const igraph_vector_t *vtime, const igraph_vector_t *vtimeidx, const igraph_vector_t *etime, const igraph_vector_t *etimeidx, igraph_integer_t pno_of_events, const igraph_vector_t *authors, const igraph_vector_t *eventsizes, igraph_integer_t pmaxpapers) { long int no_of_nodes=igraph_vcount(graph); long int no_of_edges=igraph_ecount(graph); long int no_of_events=pno_of_events; long int maxpapers=pmaxpapers; igraph_vector_long_t papers; igraph_vector_char_t added; igraph_matrix_t v_normfact, *normfact, v_notnull, *notnull; igraph_matrix_t ch; igraph_vector_long_t ntk; igraph_matrix_t ntkk; igraph_vector_t *adjedges; long int timestep, i; long int nptr=0, eptr=0, aptr=0; long int nptr_save, eptr_save, eptr_new; IGRAPH_CHECK(igraph_vector_long_init(&papers, no_of_nodes)); IGRAPH_FINALLY(&igraph_vector_long_destroy, &papers); IGRAPH_CHECK(igraph_vector_char_init(&added, no_of_edges)); IGRAPH_FINALLY(igraph_vector_char_destroy, &added); IGRAPH_CHECK(igraph_vector_long_init(&ntk, maxpapers+1)); IGRAPH_FINALLY(igraph_vector_long_destroy, &ntk); IGRAPH_MATRIX_INIT_FINALLY(&ntkk, maxpapers+1, maxpapers+1); IGRAPH_MATRIX_INIT_FINALLY(&ch, maxpapers+1, maxpapers+1); if (norm) { normfact=norm; IGRAPH_CHECK(igraph_matrix_resize(normfact, maxpapers+1, maxpapers+1)); igraph_matrix_null(normfact); } else { normfact=&v_normfact; IGRAPH_MATRIX_INIT_FINALLY(normfact, maxpapers+1, maxpapers+1); } if (cites) { notnull=cites; IGRAPH_CHECK(igraph_matrix_resize(notnull, maxpapers+1, maxpapers+1)); igraph_matrix_null(notnull); } else { notnull=&v_notnull; IGRAPH_MATRIX_INIT_FINALLY(notnull, maxpapers+1, maxpapers+1); } IGRAPH_CHECK(igraph_matrix_resize(kernel, maxpapers+1, maxpapers+1)); igraph_matrix_null(kernel); if (sd) { IGRAPH_CHECK(igraph_matrix_resize(sd, maxpapers+1, maxpapers+1)); igraph_matrix_null(sd); } for (timestep=0; timestep<no_of_events; timestep++) { IGRAPH_ALLOW_INTERRUPTION(); nptr_save=nptr; while (nptr < no_of_nodes && VECTOR(*vtime)[(long int)VECTOR(*vtimeidx)[nptr]]==timestep) { nptr++; } /* If it is a new author then she has no papers yet */ VECTOR(ntk)[0] += (nptr-nptr_save); /* Update ch accordingly, could be done later as well */ if (VECTOR(ntk)[0] == nptr-nptr_save && nptr!=nptr_save) { if (nptr-nptr_save >= 2) { MATRIX(ch, 0, 0) = eptr; } for (i=1; i<maxpapers+1; i++) { if (NTKK(0,i) == (nptr-nptr_save)*VECTOR(ntk)[i]) { MATRIX(ch, 0, i) = MATRIX(ch, i, 0) = eptr; } } } /* print_ntkk(&ntkk, &ntk); */ /* Estimate Akk */ eptr_save=eptr; while (eptr < no_of_edges && VECTOR(*etime)[(long int)VECTOR(*etimeidx)[eptr] ] == timestep) { long int edge=(long int) VECTOR(*etimeidx)[eptr]; long int from=IGRAPH_FROM(graph, edge), to=IGRAPH_TO(graph, edge); long int xidx=VECTOR(papers)[from]; long int yidx=VECTOR(papers)[to]; double xk, oldakk; MATRIX(*notnull, xidx, yidx) += 1; MATRIX(*notnull, yidx, xidx) = MATRIX(*notnull, xidx, yidx); xk=VECTOR(*st)[timestep]/NTKK(xidx, yidx); oldakk=MATRIX(*kernel, xidx, yidx); MATRIX(*kernel, xidx, yidx) += (xk-oldakk)/MATRIX(*notnull, xidx, yidx); MATRIX(*kernel, yidx, xidx) = MATRIX(*kernel, xidx, yidx); if (sd) { MATRIX(*sd, xidx, yidx) += (xk-oldakk)*(xk-MATRIX(*kernel, xidx, yidx)); MATRIX(*sd, yidx, xidx) = MATRIX(*sd, xidx, yidx); } /* TODO: debug */ eptr++; } /* update ntkk, the new papers change the type of their authors */ eptr_new=eptr; for (i=aptr; i<aptr+VECTOR(*eventsizes)[timestep]; i++) { long int aut=(long int) VECTOR(*authors)[i]; long int pap=VECTOR(papers)[aut]; long int j, n; adjedges=igraph_lazy_inclist_get(inclist, (igraph_integer_t) aut); n=igraph_vector_size(adjedges); for (j=0; j<n; j++) { long int edge=(long int) VECTOR(*adjedges)[j]; if (VECTOR(added)[edge]) { long int otherv=IGRAPH_OTHER(graph, edge, aut); long int otherpap=VECTOR(papers)[otherv]; MATRIX(ntkk, pap, otherpap) -= 1; MATRIX(ntkk, otherpap, pap) = MATRIX(ntkk, pap, otherpap); if (NTKK(pap, otherpap)==1) { MATRIX(ch, pap, otherpap) = eptr_new; MATRIX(ch, otherpap, pap) = MATRIX(ch, pap, otherpap); } MATRIX(ntkk, pap+1, otherpap) += 1; MATRIX(ntkk, otherpap, pap+1) = MATRIX(ntkk, pap+1, otherpap); if (NTKK(pap+1, otherpap)==0) { MATRIX(*normfact, pap+1, otherpap) += eptr_new-MATRIX(ch, pap+1, otherpap); MATRIX(*normfact, otherpap, pap+1) = MATRIX(*normfact, pap+1, otherpap); } } } /* update ntk too */ for (j=0; j<maxpapers+1; j++) { long int before, after; before=(long int) NTKK(pap, j); VECTOR(ntk)[pap]-=1; after=(long int) NTKK(pap, j); VECTOR(ntk)[pap]+=1; if (before > 0 && after==0) { MATRIX(*normfact, pap, j) += eptr_new-MATRIX(ch, pap, j); MATRIX(*normfact, j, pap) = MATRIX(*normfact, pap, j); } } VECTOR(ntk)[pap]-=1; for (j=0; j<maxpapers+1; j++) { long int before, after; before=(long int) NTKK(pap+1, j); VECTOR(ntk)[pap+1] += 1; after=(long int) NTKK(pap+1, j); VECTOR(ntk)[pap+1] -= 1; if (before == 0 && after > 0) { MATRIX(ch, pap+1, j) = eptr_new; MATRIX(ch, j, pap+1) = MATRIX(ch, pap+1, j); } } VECTOR(ntk)[pap+1]+=1; VECTOR(papers)[aut] += 1; } aptr += VECTOR(*eventsizes)[timestep]; /* For every new edge, we lose one connection possibility, also add the edges*/ eptr=eptr_save; while (eptr < no_of_edges && VECTOR(*etime)[(long int) VECTOR(*etimeidx)[eptr] ] == timestep) { long int edge=(long int) VECTOR(*etimeidx)[eptr]; long int from=IGRAPH_FROM(graph, edge), to=IGRAPH_TO(graph, edge); long int xidx=VECTOR(papers)[from]; long int yidx=VECTOR(papers)[to]; MATRIX(ntkk, xidx, yidx) += 1; MATRIX(ntkk, yidx, xidx) = MATRIX(ntkk, xidx, yidx); if (NTKK(xidx, yidx)==0) { MATRIX(*normfact, xidx, yidx) += eptr_new-MATRIX(ch, xidx, yidx); MATRIX(*normfact, yidx, xidx) = MATRIX(*normfact, xidx, yidx); } VECTOR(added)[edge]=1; eptr++; } } for (i=0; i<maxpapers+1; i++) { igraph_real_t oldakk; long int j; for (j=0; j<=i; j++) { if (NTKK(i, j) != 0) { MATRIX(*normfact, i, j) += (eptr-MATRIX(ch, i, j)); MATRIX(*normfact, j, i) = MATRIX(*normfact, i, j); } if (MATRIX(*normfact, i, j)==0) { MATRIX(*kernel, i, j)=MATRIX(*kernel, j, i)=0; MATRIX(*normfact, i, j)=MATRIX(*normfact, j, i)=1; } oldakk=MATRIX(*kernel, i, j); MATRIX(*kernel, i, j) *= MATRIX(*notnull, i, j)/MATRIX(*normfact, i, j); MATRIX(*kernel, j, i) = MATRIX(*kernel, i, j); if (sd) { MATRIX(*sd, i, j) += oldakk * oldakk * MATRIX(*notnull, i, j) * (1-MATRIX(*notnull, i, j)/MATRIX(*normfact, i, j)); MATRIX(*sd, i, j) = sqrt(MATRIX(*sd, i, j)/(MATRIX(*normfact, i, j)-1)); MATRIX(*sd, j, i) = MATRIX(*sd, i, j); } } } if (!cites) { igraph_matrix_destroy(notnull); IGRAPH_FINALLY_CLEAN(1); } if (!norm) { igraph_matrix_destroy(normfact); IGRAPH_FINALLY_CLEAN(1); } igraph_matrix_destroy(&ch); igraph_matrix_destroy(&ntkk); igraph_vector_long_destroy(&ntk); igraph_vector_char_destroy(&added); igraph_vector_long_destroy(&papers); IGRAPH_FINALLY_CLEAN(5); return 0; }
/* Random Orders Method : */ igraph_t * ggen_generate_random_orders(gsl_rng *r, unsigned long n, unsigned int orders) { igraph_t *g = NULL; igraph_matrix_t m,edge_validity; int err = 0; long long i = 0,j,k; igraph_vector_ptr_t posets; igraph_vector_ptr_t indexes; igraph_vector_t *v,*w; ggen_error_start_stack(); if(r == NULL) GGEN_SET_ERRNO(GGEN_EINVAL); if(orders == 0) GGEN_SET_ERRNO(GGEN_EINVAL); // init structures g = malloc(sizeof(igraph_t)); GGEN_CHECK_ALLOC(g); GGEN_FINALLY3(free,g,1); GGEN_CHECK_IGRAPH(igraph_matrix_init(&m,n,n)); GGEN_FINALLY(igraph_matrix_destroy,&m); GGEN_CHECK_IGRAPH(igraph_matrix_init(&edge_validity,n,n)); GGEN_FINALLY(igraph_matrix_destroy,&edge_validity); GGEN_CHECK_IGRAPH(igraph_vector_ptr_init(&posets,orders)); IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(&posets,igraph_vector_destroy); GGEN_FINALLY(igraph_vector_ptr_destroy_all,&posets); GGEN_CHECK_IGRAPH(igraph_vector_ptr_init(&indexes,orders)); IGRAPH_VECTOR_PTR_SET_ITEM_DESTRUCTOR(&indexes,igraph_vector_destroy); GGEN_FINALLY(igraph_vector_ptr_destroy_all,&indexes); for(i = 0; i < orders; i++) { // posets is used for permutation computations // it should contain vertices VECTOR(posets)[i] = calloc(1,sizeof(igraph_vector_t)); GGEN_CHECK_ALLOC(VECTOR(posets)[i]); GGEN_CHECK_IGRAPH_VECTPTR(igraph_vector_init_seq(VECTOR(posets)[i],0,n-1),posets,i); VECTOR(indexes)[i] = calloc(1,sizeof(igraph_vector_t)); GGEN_CHECK_ALLOC(VECTOR(indexes)[i]); GGEN_CHECK_IGRAPH_VECTPTR(igraph_vector_init(VECTOR(indexes)[i],n),indexes,i); } // zero all structs igraph_matrix_null(&m); igraph_matrix_null(&edge_validity); // use gsl to shuffle each poset for( j = 0; j < orders; j++) { v = VECTOR(posets)[j]; GGEN_CHECK_GSL_DO(gsl_ran_shuffle(r,VECTOR(*v), n, sizeof(VECTOR(*v)[0]))); } // index saves the indices of each vertex in each permutation for( i = 0; i < orders; i++) for( j = 0; j < n; j++) { v = VECTOR(posets)[i]; w = VECTOR(indexes)[i]; k = VECTOR(*v)[j]; VECTOR(*w)[k] = j; } // edge_validity count if an edge is in all permutations for( i = 0; i < n; i++) for( j = 0; j < n; j++) for( k = 0; k < orders; k++) { v = VECTOR(indexes)[k]; if( VECTOR(*v)[i] < VECTOR(*v)[j]) igraph_matrix_set(&edge_validity,i,j, igraph_matrix_e(&edge_validity,i,j)+1); } // if an edge is present in all permutations then add it to the graph for( i = 0; i < n; i++) for( j = 0; j < n; j++) if(igraph_matrix_e(&edge_validity,i,j) == orders) igraph_matrix_set(&m,i,j,1); // translate the matrix to a graph GGEN_CHECK_IGRAPH(igraph_adjacency(g,&m,IGRAPH_ADJ_DIRECTED)); ggen_error_clean(1); return g; ggen_error_label: return NULL; }
int igraph_revolver_mes_d_d(const igraph_t *graph, igraph_lazy_inclist_t *inclist, igraph_matrix_t *kernel, igraph_matrix_t *sd, igraph_matrix_t *norm, igraph_matrix_t *cites, const igraph_matrix_t *debug, igraph_vector_ptr_t *debugres, const igraph_vector_t *st, const igraph_vector_t *vtime, const igraph_vector_t *vtimeidx, const igraph_vector_t *etime, const igraph_vector_t *etimeidx, igraph_integer_t pno_of_events, igraph_integer_t pmaxdegree) { long int no_of_nodes=igraph_vcount(graph); long int no_of_edges=igraph_ecount(graph); long int no_of_events=pno_of_events; long int maxdegree=pmaxdegree; igraph_vector_long_t degree; igraph_vector_char_t added; /* is this edge already in the network? */ igraph_matrix_t v_normfact, *normfact, v_notnull, *notnull; igraph_matrix_t ch; igraph_vector_long_t ntk; /* # of type x vertices */ igraph_matrix_t ntkk; /* # of connections between type x1, x2 vert. */ igraph_vector_t *adjedges; long int timestep, i; long int nptr=0, eptr=0; long int nptr_save, eptr_save, eptr_new; IGRAPH_CHECK(igraph_vector_long_init(°ree, no_of_nodes)); IGRAPH_FINALLY(&igraph_vector_long_destroy, °ree); IGRAPH_CHECK(igraph_vector_char_init(&added, no_of_edges)); IGRAPH_FINALLY(igraph_vector_char_destroy, &added); IGRAPH_CHECK(igraph_vector_long_init(&ntk, maxdegree+1)); IGRAPH_FINALLY(igraph_vector_long_destroy, &ntk); IGRAPH_MATRIX_INIT_FINALLY(&ntkk, maxdegree+1, maxdegree+1); IGRAPH_MATRIX_INIT_FINALLY(&ch, maxdegree+1, maxdegree+1); if (norm) { normfact=norm; IGRAPH_CHECK(igraph_matrix_resize(normfact, maxdegree+1, maxdegree+1)); igraph_matrix_null(normfact); } else { normfact=&v_normfact; IGRAPH_MATRIX_INIT_FINALLY(normfact, maxdegree+1, maxdegree+1); } if (cites) { notnull=cites; IGRAPH_CHECK(igraph_matrix_resize(notnull, maxdegree+1, maxdegree+1)); igraph_matrix_null(notnull); } else { notnull=&v_notnull; IGRAPH_MATRIX_INIT_FINALLY(notnull, maxdegree+1, maxdegree+1); } IGRAPH_CHECK(igraph_matrix_resize(kernel, maxdegree+1, maxdegree+1)); igraph_matrix_null(kernel); if (sd) { IGRAPH_CHECK(igraph_matrix_resize(sd, maxdegree+1, maxdegree+1)); igraph_matrix_null(sd); } for (timestep=0; timestep<no_of_events; timestep++) { IGRAPH_ALLOW_INTERRUPTION(); /* Add the vertices in the first */ nptr_save=nptr; while (nptr < no_of_nodes && VECTOR(*vtime)[(long int)VECTOR(*vtimeidx)[nptr]]==timestep) { nptr++; } VECTOR(ntk)[0] += (nptr-nptr_save); /* Update ch accordingly, could be done later as well */ if (VECTOR(ntk)[0] == nptr-nptr_save && nptr!=nptr_save) { if (nptr-nptr_save >= 2) { MATRIX(ch, 0, 0) = eptr; } for (i=1; i<maxdegree+1; i++) { if (NTKK(0,i) == (nptr-nptr_save)*VECTOR(ntk)[i]) { MATRIX(ch, 0, i) = MATRIX(ch, i, 0) = eptr; } } } /* Estimate Akk */ eptr_save=eptr; while (eptr < no_of_edges && VECTOR(*etime)[(long int)VECTOR(*etimeidx)[eptr] ] == timestep) { long int edge=(long int) VECTOR(*etimeidx)[eptr]; long int from=IGRAPH_FROM(graph, edge), to=IGRAPH_TO(graph, edge); long int xidx=VECTOR(degree)[from]; long int yidx=VECTOR(degree)[to]; double xk, oldakk; MATRIX(*notnull, xidx, yidx) += 1; MATRIX(*notnull, yidx, xidx) = MATRIX(*notnull, xidx, yidx); xk=VECTOR(*st)[timestep]/NTKK(xidx, yidx); oldakk=MATRIX(*kernel, xidx, yidx); MATRIX(*kernel, xidx, yidx) += (xk-oldakk)/MATRIX(*notnull, xidx, yidx); MATRIX(*kernel, yidx, xidx) = MATRIX(*kernel, xidx, yidx); if (sd) { MATRIX(*sd, xidx, yidx) += (xk-oldakk)*(xk-MATRIX(*kernel, xidx, yidx)); MATRIX(*sd, yidx, xidx) = MATRIX(*sd, xidx, yidx); } /* TODO: debug */ eptr++; } /* Update ntkk, ntk, ch, normfact, add the edges */ eptr_new=eptr; eptr=eptr_save; while (eptr < no_of_edges && VECTOR(*etime)[(long int) VECTOR(*etimeidx)[eptr] ] == timestep) { long int edge=(long int) VECTOR(*etimeidx)[eptr]; long int from=IGRAPH_FROM(graph, edge); long int to=IGRAPH_TO(graph, edge); long int xidx=VECTOR(degree)[from]; long int yidx=VECTOR(degree)[to]; long int n; adjedges=igraph_lazy_inclist_get(inclist, (igraph_integer_t) from); n=igraph_vector_size(adjedges); for (i=0; i<n; i++) { long int edge=(long int) VECTOR(*adjedges)[i]; if (VECTOR(added)[edge]) { long int otherv=IGRAPH_OTHER(graph, edge, from); /* other than from */ long int deg=VECTOR(degree)[otherv]; MATRIX(ntkk, xidx, deg) -= 1; MATRIX(ntkk, deg, xidx) = MATRIX(ntkk, xidx, deg); if (NTKK(xidx, deg)==1) { MATRIX(ch, deg, xidx) = eptr_new; MATRIX(ch, xidx, deg) = MATRIX(ch, deg, xidx); } MATRIX(ntkk, xidx+1, deg) += 1; MATRIX(ntkk, deg, xidx+1) = MATRIX(ntkk, xidx+1, deg); if (NTKK(xidx+1, deg)==0) { MATRIX(*normfact, xidx+1, deg) += eptr_new-MATRIX(ch, xidx+1, deg); MATRIX(*normfact, deg, xidx+1) = MATRIX(*normfact, xidx+1, deg); } } } adjedges=igraph_lazy_inclist_get(inclist, (igraph_integer_t) to); n=igraph_vector_size(adjedges); for (i=0; i<n; i++) { long int edge=(long int) VECTOR(*adjedges)[i]; if (VECTOR(added)[edge]) { long int otherv=IGRAPH_OTHER(graph, edge, to); /* other than to */ long int deg=VECTOR(degree)[otherv]; MATRIX(ntkk, yidx, deg) -= 1; MATRIX(ntkk, deg, yidx) = MATRIX(ntkk, yidx, deg); if (NTKK(yidx, deg)==1) { MATRIX(ch, deg, yidx) = eptr_new; MATRIX(ch, yidx, deg) = MATRIX(ch, deg, yidx); } MATRIX(ntkk, yidx+1, deg) += 1; MATRIX(ntkk, deg, yidx+1) = MATRIX(ntkk, yidx+1, deg); if (NTKK(yidx+1, deg)==0) { MATRIX(*normfact, yidx+1, deg) += eptr_new-MATRIX(ch, yidx+1, deg); MATRIX(*normfact, deg, yidx+1) = MATRIX(*normfact, yidx+1, deg); } } } VECTOR(added)[edge]=1; MATRIX(ntkk, xidx+1, yidx+1) += 1; MATRIX(ntkk, yidx+1, xidx+1) = MATRIX(ntkk, xidx+1, yidx+1); if (NTKK(xidx+1, yidx+1)==0) { MATRIX(*normfact, xidx+1, yidx+1) = eptr_new-MATRIX(ch, xidx+1, yidx+1); MATRIX(*normfact, yidx+1, xidx+1) = MATRIX(*normfact, xidx+1, yidx+1); } for (i=0; i<maxdegree+1; i++) { long int before, after; before=(long int) NTKK(xidx,i); VECTOR(ntk)[xidx] -= 1; after=(long int) NTKK(xidx,i); VECTOR(ntk)[xidx] += 1; if (before > 0 && after==0) { MATRIX(*normfact, xidx, i) += eptr_new-MATRIX(ch, xidx, i); MATRIX(*normfact, i, xidx) = MATRIX(*normfact, xidx, i); } } VECTOR(ntk)[xidx]--; for (i=0; i<maxdegree+1; i++) { long int before, after; before=(long int) NTKK(yidx, i); VECTOR(ntk)[yidx] -= 1; after=(long int) NTKK(yidx, i); VECTOR(ntk)[yidx] += 1; if (before > 0 && after==0) { MATRIX(*normfact, yidx, i) += eptr_new-MATRIX(ch, yidx, i); MATRIX(*normfact, i, yidx) = MATRIX(*normfact, yidx, i); } } VECTOR(ntk)[yidx]--; for (i=0; i<maxdegree+1; i++) { long int before, after; before=(long int) NTKK(xidx+1, i); VECTOR(ntk)[xidx+1] += 1; after=(long int) NTKK(xidx+1, i); VECTOR(ntk)[xidx+1] -= 1; if (before==0 && after > 0) { MATRIX(ch, xidx+1, i) = eptr_new; MATRIX(ch, i, xidx+1) = MATRIX(ch, xidx+1, i); } } VECTOR(ntk)[xidx+1]++; for (i=0; i<maxdegree+1; i++) { long int before, after; before=(long int) NTKK(yidx+1, i); VECTOR(ntk)[yidx+1] += 1; after=(long int) NTKK(yidx+1, i); VECTOR(ntk)[yidx+1] -= 1; if (before == 0 && after == 0) { MATRIX(ch, yidx+1, i) = eptr_new; MATRIX(ch, i, yidx+1) = MATRIX(ch, yidx+1, i); } } VECTOR(ntk)[yidx+1]++; VECTOR(degree)[from]++; VECTOR(degree)[to]++; eptr++; } } for (i=0; i<maxdegree+1; i++) { igraph_real_t oldakk; long int j; for (j=0; j<=i; j++) { if (NTKK(i, j) != 0) { MATRIX(*normfact, i, j) += (eptr-MATRIX(ch, i, j)); MATRIX(*normfact, j, i) = MATRIX(*normfact, i, j); } if (MATRIX(*normfact, i, j)==0) { MATRIX(*kernel, i, j)=MATRIX(*kernel, j, i)=0; MATRIX(*normfact, i, j)=MATRIX(*normfact, j, i)=1; } oldakk=MATRIX(*kernel, i, j); MATRIX(*kernel, i, j) *= MATRIX(*notnull, i, j)/MATRIX(*normfact, i, j); MATRIX(*kernel, j, i) = MATRIX(*kernel, i, j); if (sd) { MATRIX(*sd, i, j) += oldakk * oldakk * MATRIX(*notnull, i, j) * (1-MATRIX(*notnull, i, j)/MATRIX(*normfact, i, j)); MATRIX(*sd, i, j) = sqrt(MATRIX(*sd, i, j)/(MATRIX(*normfact, i, j)-1)); MATRIX(*sd, j, i) = MATRIX(*sd, i, j); } } } if (!cites) { igraph_matrix_destroy(notnull); IGRAPH_FINALLY_CLEAN(1); } if (!norm) { igraph_matrix_destroy(normfact); IGRAPH_FINALLY_CLEAN(1); } igraph_matrix_destroy(&ch); igraph_matrix_destroy(&ntkk); igraph_vector_long_destroy(&ntk); igraph_vector_char_destroy(&added); igraph_vector_long_destroy(°ree); IGRAPH_FINALLY_CLEAN(5); return 0; }
/** * \function igraph_community_fastgreedy * \brief Finding community structure by greedy optimization of modularity * * This function implements the fast greedy modularity optimization * algorithm for finding community structure, see * A Clauset, MEJ Newman, C Moore: Finding community structure in very * large networks, http://www.arxiv.org/abs/cond-mat/0408187 for the * details. * * </para><para> * Some improvements proposed in K Wakita, T Tsurumi: Finding community * structure in mega-scale social networks, * http://www.arxiv.org/abs/cs.CY/0702048v1 have also been implemented. * * \param graph The input graph. It must be a simple graph, i.e. a graph * without multiple and without loop edges. This is checked and an * error message is given for non-simple graphs. * \param weights Potentially a numeric vector containing edge * weights. Supply a null pointer here for unweighted graphs. The * weights are expected to be non-negative. * \param merges Pointer to an initialized matrix or NULL, the result of the * computation is stored here. The matrix has two columns and each * merge corresponds to one merge, the ids of the two merged * components are stored. The component ids are numbered from zero and * the first \c n components are the individual vertices, \c n is * the number of vertices in the graph. Component \c n is created * in the first merge, component \c n+1 in the second merge, etc. * The matrix will be resized as needed. If this argument is NULL * then it is ignored completely. * \param modularity Pointer to an initialized matrix or NULL pointer, * in the former case the modularity scores along the stages of the * computation are recorded here. The vector will be resized as * needed. * \return Error code. * * \sa \ref igraph_community_walktrap(), \ref * igraph_community_edge_betweenness() for other community detection * algorithms, \ref igraph_community_to_membership() to convert the * dendrogram to a membership vector. * * Time complexity: O(|E||V|log|V|) in the worst case, * O(|E|+|V|log^2|V|) typically, |V| is the number of vertices, |E| is * the number of edges. */ int igraph_community_fastgreedy(const igraph_t *graph, const igraph_vector_t *weights, igraph_matrix_t *merges, igraph_vector_t *modularity) { long int no_of_edges, no_of_nodes, no_of_joins, total_joins; long int i, j, k, n, m, from, to, dummy; igraph_integer_t ffrom, fto; igraph_eit_t edgeit; igraph_i_fastgreedy_commpair *pairs, *p1, *p2; igraph_i_fastgreedy_community_list communities; igraph_vector_t a; igraph_real_t q, maxq, *dq, weight_sum; igraph_bool_t simple; /*long int join_order[] = { 16,5, 5,6, 6,0, 4,0, 10,0, 26,29, 29,33, 23,33, 27,33, 25,24, 24,31, 12,3, 21,1, 30,8, 8,32, 9,2, 17,1, 11,0, 7,3, 3,2, 13,2, 1,2, 28,31, 31,33, 22,32, 18,32, 20,32, 32,33, 15,33, 14,33, 0,19, 19,2, -1,-1 };*/ /*long int join_order[] = { 43,42, 42,41, 44,41, 41,36, 35,36, 37,36, 36,29, 38,29, 34,29, 39,29, 33,29, 40,29, 32,29, 14,29, 30,29, 31,29, 6,18, 18,4, 23,4, 21,4, 19,4, 27,4, 20,4, 22,4, 26,4, 25,4, 24,4, 17,4, 0,13, 13,2, 1,2, 11,2, 8,2, 5,2, 3,2, 10,2, 9,2, 7,2, 2,28, 28,15, 12,15, 29,16, 4,15, -1,-1 };*/ no_of_nodes = igraph_vcount(graph); no_of_edges = igraph_ecount(graph); if (igraph_is_directed(graph)) { IGRAPH_ERROR("fast greedy community detection works for undirected graphs only", IGRAPH_UNIMPLEMENTED); } total_joins=no_of_nodes-1; if (weights != 0) { if (igraph_vector_size(weights) < igraph_ecount(graph)) IGRAPH_ERROR("fast greedy community detection: weight vector too short", IGRAPH_EINVAL); if (igraph_vector_any_smaller(weights, 0)) IGRAPH_ERROR("weights must be positive", IGRAPH_EINVAL); weight_sum = igraph_vector_sum(weights); } else weight_sum = no_of_edges; IGRAPH_CHECK(igraph_is_simple(graph, &simple)); if (!simple) { IGRAPH_ERROR("fast-greedy community finding works only on simple graphs", IGRAPH_EINVAL); } if (merges != 0) { IGRAPH_CHECK(igraph_matrix_resize(merges, total_joins, 2)); igraph_matrix_null(merges); } if (modularity != 0) { IGRAPH_CHECK(igraph_vector_resize(modularity, total_joins+1)); } /* Create degree vector */ IGRAPH_VECTOR_INIT_FINALLY(&a, no_of_nodes); if (weights) { debug("Calculating weighted degrees\n"); for (i=0; i < no_of_edges; i++) { VECTOR(a)[(long int)IGRAPH_FROM(graph, i)] += VECTOR(*weights)[i]; VECTOR(a)[(long int)IGRAPH_TO(graph, i)] += VECTOR(*weights)[i]; } } else { debug("Calculating degrees\n"); IGRAPH_CHECK(igraph_degree(graph, &a, igraph_vss_all(), IGRAPH_ALL, 0)); } /* Create list of communities */ debug("Creating community list\n"); communities.n = no_of_nodes; communities.no_of_communities = no_of_nodes; communities.e = (igraph_i_fastgreedy_community*)calloc(no_of_nodes, sizeof(igraph_i_fastgreedy_community)); if (communities.e == 0) { IGRAPH_ERROR("can't run fast greedy community detection", IGRAPH_ENOMEM); } IGRAPH_FINALLY(free, communities.e); communities.heap = (igraph_i_fastgreedy_community**)calloc(no_of_nodes, sizeof(igraph_i_fastgreedy_community*)); if (communities.heap == 0) { IGRAPH_ERROR("can't run fast greedy community detection", IGRAPH_ENOMEM); } IGRAPH_FINALLY(free, communities.heap); communities.heapindex = (igraph_integer_t*)calloc(no_of_nodes, sizeof(igraph_integer_t)); if (communities.heapindex == 0) { IGRAPH_ERROR("can't run fast greedy community detection", IGRAPH_ENOMEM); } IGRAPH_FINALLY_CLEAN(2); IGRAPH_FINALLY(igraph_i_fastgreedy_community_list_destroy, &communities); for (i=0; i<no_of_nodes; i++) { igraph_vector_ptr_init(&communities.e[i].neis, 0); communities.e[i].id = i; communities.e[i].size = 1; } /* Create list of community pairs from edges */ debug("Allocating dq vector\n"); dq = (igraph_real_t*)calloc(no_of_edges, sizeof(igraph_real_t)); if (dq == 0) { IGRAPH_ERROR("can't run fast greedy community detection", IGRAPH_ENOMEM); } IGRAPH_FINALLY(free, dq); debug("Creating community pair list\n"); IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(0), &edgeit)); IGRAPH_FINALLY(igraph_eit_destroy, &edgeit); pairs = (igraph_i_fastgreedy_commpair*)calloc(2*no_of_edges, sizeof(igraph_i_fastgreedy_commpair)); if (pairs == 0) { IGRAPH_ERROR("can't run fast greedy community detection", IGRAPH_ENOMEM); } IGRAPH_FINALLY(free, pairs); i=j=0; while (!IGRAPH_EIT_END(edgeit)) { long int eidx = IGRAPH_EIT_GET(edgeit); igraph_edge(graph, eidx, &ffrom, &fto); /* Create the pairs themselves */ from = (long int)ffrom; to = (long int)fto; if (from == to) { IGRAPH_ERROR("loop edge detected, simplify the graph before starting community detection", IGRAPH_EINVAL); } if (from>to) { dummy=from; from=to; to=dummy; } if (weights) { dq[j]=2*(VECTOR(*weights)[eidx]/(weight_sum*2.0) - VECTOR(a)[from]*VECTOR(a)[to]/(4.0*weight_sum*weight_sum)); } else { dq[j]=2*(1.0/(no_of_edges*2.0) - VECTOR(a)[from]*VECTOR(a)[to]/(4.0*no_of_edges*no_of_edges)); } pairs[i].first = from; pairs[i].second = to; pairs[i].dq = &dq[j]; pairs[i].opposite = &pairs[i+1]; pairs[i+1].first = to; pairs[i+1].second = from; pairs[i+1].dq = pairs[i].dq; pairs[i+1].opposite = &pairs[i]; /* Link the pair to the communities */ igraph_vector_ptr_push_back(&communities.e[from].neis, &pairs[i]); igraph_vector_ptr_push_back(&communities.e[to].neis, &pairs[i+1]); /* Update maximums */ if (communities.e[from].maxdq==0 || *communities.e[from].maxdq->dq < *pairs[i].dq) communities.e[from].maxdq = &pairs[i]; if (communities.e[to].maxdq==0 || *communities.e[to].maxdq->dq < *pairs[i+1].dq) communities.e[to].maxdq = &pairs[i+1]; /* Iterate */ i+=2; j++; IGRAPH_EIT_NEXT(edgeit); } igraph_eit_destroy(&edgeit); IGRAPH_FINALLY_CLEAN(1); /* Sorting community neighbor lists by community IDs */ debug("Sorting community neighbor lists\n"); for (i=0, j=0; i<no_of_nodes; i++) { igraph_vector_ptr_sort(&communities.e[i].neis, igraph_i_fastgreedy_commpair_cmp); /* Isolated vertices won't be stored in the heap (to avoid maxdq == 0) */ if (VECTOR(a)[i] > 0) { communities.heap[j] = &communities.e[i]; communities.heapindex[i] = j; j++; } else { communities.heapindex[i] = -1; } } communities.no_of_communities = j; /* Calculate proper vector a (see paper) and initial modularity */ q=0; igraph_vector_scale(&a, 1.0/(2.0 * (weights ? weight_sum : no_of_edges))); for (i=0; i<no_of_nodes; i++) q -= VECTOR(a)[i]*VECTOR(a)[i]; maxq=q; /* Initializing community heap */ debug("Initializing community heap\n"); igraph_i_fastgreedy_community_list_build_heap(&communities); debug("Initial modularity: %.4f\n", q); /* Let's rock ;) */ no_of_joins=0; while (no_of_joins<total_joins) { IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_PROGRESS("fast greedy community detection", no_of_joins*100.0/total_joins, 0); /* Store the modularity */ if (modularity) VECTOR(*modularity)[no_of_joins] = q; /* Some debug info if needed */ /* igraph_i_fastgreedy_community_list_check_heap(&communities); */ #ifdef DEBUG debug("===========================================\n"); for (i=0; i<communities.n; i++) { if (communities.e[i].maxdq == 0) { debug("Community #%ld: PASSIVE\n", i); continue; } debug("Community #%ld\n ", i); for (j=0; j<igraph_vector_ptr_size(&communities.e[i].neis); j++) { p1=(igraph_i_fastgreedy_commpair*)VECTOR(communities.e[i].neis)[j]; debug(" (%ld,%ld,%.4f)", p1->first, p1->second, *p1->dq); } p1=communities.e[i].maxdq; debug("\n Maxdq: (%ld,%ld,%.4f)\n", p1->first, p1->second, *p1->dq); } debug("Global maxdq is: (%ld,%ld,%.4f)\n", communities.heap[0]->maxdq->first, communities.heap[0]->maxdq->second, *communities.heap[0]->maxdq->dq); for (i=0; i<communities.no_of_communities; i++) debug("(%ld,%ld,%.4f) ", communities.heap[i]->maxdq->first, communities.heap[i]->maxdq->second, *communities.heap[0]->maxdq->dq); debug("\n"); #endif if (communities.heap[0] == 0) break; /* no more communities */ if (communities.heap[0]->maxdq == 0) break; /* there are only isolated comms */ to=communities.heap[0]->maxdq->second; from=communities.heap[0]->maxdq->first; debug("Q[%ld] = %.7f\tdQ = %.7f\t |H| = %ld\n", no_of_joins, q, *communities.heap[0]->maxdq->dq, no_of_nodes-no_of_joins-1); /* DEBUG */ /* from=join_order[no_of_joins*2]; to=join_order[no_of_joins*2+1]; if (to == -1) break; for (i=0; i<igraph_vector_ptr_size(&communities.e[to].neis); i++) { p1=(igraph_i_fastgreedy_commpair*)VECTOR(communities.e[to].neis)[i]; if (p1->second == from) communities.maxdq = p1; } */ n = igraph_vector_ptr_size(&communities.e[to].neis); m = igraph_vector_ptr_size(&communities.e[from].neis); /*if (n>m) { dummy=n; n=m; m=dummy; dummy=to; to=from; from=dummy; }*/ debug(" joining: %ld <- %ld\n", to, from); q += *communities.heap[0]->maxdq->dq; /* Merge the second community into the first */ i = j = 0; while (i<n && j<m) { p1 = (igraph_i_fastgreedy_commpair*)VECTOR(communities.e[to].neis)[i]; p2 = (igraph_i_fastgreedy_commpair*)VECTOR(communities.e[from].neis)[j]; debug("Pairs: %ld-%ld and %ld-%ld\n", p1->first, p1->second, p2->first, p2->second); if (p1->second < p2->second) { /* Considering p1 from now on */ debug(" Considering: %ld-%ld\n", p1->first, p1->second); if (p1->second == from) { debug(" WILL REMOVE: %ld-%ld\n", to, from); } else { /* chain, case 1 */ debug(" CHAIN(1): %ld-%ld %ld, now=%.7f, adding=%.7f, newdq(%ld,%ld)=%.7f\n", to, p1->second, from, *p1->dq, -2*VECTOR(a)[from]*VECTOR(a)[p1->second], p1->first, p1->second, *p1->dq-2*VECTOR(a)[from]*VECTOR(a)[p1->second]); igraph_i_fastgreedy_community_update_dq(&communities, p1, *p1->dq - 2*VECTOR(a)[from]*VECTOR(a)[p1->second]); } i++; } else if (p1->second == p2->second) { /* p1->first, p1->second and p2->first form a triangle */ debug(" Considering: %ld-%ld and %ld-%ld\n", p1->first, p1->second, p2->first, p2->second); /* Update dq value */ debug(" TRIANGLE: %ld-%ld-%ld, now=%.7f, adding=%.7f, newdq(%ld,%ld)=%.7f\n", to, p1->second, from, *p1->dq, *p2->dq, p1->first, p1->second, *p1->dq+*p2->dq); igraph_i_fastgreedy_community_update_dq(&communities, p1, *p1->dq + *p2->dq); igraph_i_fastgreedy_community_remove_nei(&communities, p1->second, from); i++; j++; } else { debug(" Considering: %ld-%ld\n", p2->first, p2->second); if (p2->second == to) { debug(" WILL REMOVE: %ld-%ld\n", p2->second, p2->first); } else { /* chain, case 2 */ debug(" CHAIN(2): %ld %ld-%ld, newdq(%ld,%ld)=%.7f\n", to, p2->second, from, to, p2->second, *p2->dq-2*VECTOR(a)[to]*VECTOR(a)[p2->second]); p2->opposite->second=to; /* need to re-sort community nei list `p2->second` */ /* TODO: quicksort is O(n*logn), although we could do a deletion and * insertion which can be done in O(logn) if deletion is O(1) */ debug(" Re-sorting community %ld\n", p2->second); igraph_vector_ptr_sort(&communities.e[p2->second].neis, igraph_i_fastgreedy_commpair_cmp); /* link from.neis[j] to the current place in to.neis if * from.neis[j] != to */ p2->first=to; IGRAPH_CHECK(igraph_vector_ptr_insert(&communities.e[to].neis,i,p2)); n++; i++; if (*p2->dq > *communities.e[to].maxdq->dq) { communities.e[to].maxdq = p2; k=igraph_i_fastgreedy_community_list_find_in_heap(&communities, to); igraph_i_fastgreedy_community_list_sift_up(&communities, k); } igraph_i_fastgreedy_community_update_dq(&communities, p2, *p2->dq - 2*VECTOR(a)[to]*VECTOR(a)[p2->second]); } j++; } } while (i<n) { p1 = (igraph_i_fastgreedy_commpair*)VECTOR(communities.e[to].neis)[i]; if (p1->second == from) { debug(" WILL REMOVE: %ld-%ld\n", p1->first, from); } else { /* chain, case 1 */ debug(" CHAIN(1): %ld-%ld %ld, now=%.7f, adding=%.7f, newdq(%ld,%ld)=%.7f\n", to, p1->second, from, *p1->dq, -2*VECTOR(a)[from]*VECTOR(a)[p1->second], p1->first, p1->second, *p1->dq-2*VECTOR(a)[from]*VECTOR(a)[p1->second]); igraph_i_fastgreedy_community_update_dq(&communities, p1, *p1->dq - 2*VECTOR(a)[from]*VECTOR(a)[p1->second]); } i++; } while (j<m) { p2 = (igraph_i_fastgreedy_commpair*)VECTOR(communities.e[from].neis)[j]; if (to == p2->second) { j++; continue; } /* chain, case 2 */ debug(" CHAIN(2): %ld %ld-%ld, newdq(%ld,%ld)=%.7f\n", to, p2->second, from, p1->first, p2->second, *p2->dq-2*VECTOR(a)[to]*VECTOR(a)[p2->second]); p2->opposite->second=to; /* need to re-sort community nei list `p2->second` */ /* TODO: quicksort is O(n*logn), although we could do a deletion and * insertion which can be done in O(logn) if deletion is O(1) */ debug(" Re-sorting community %ld\n", p2->second); igraph_vector_ptr_sort(&communities.e[p2->second].neis, igraph_i_fastgreedy_commpair_cmp); /* link from.neis[j] to the current place in to.neis if * from.neis[j] != to */ p2->first=to; IGRAPH_CHECK(igraph_vector_ptr_push_back(&communities.e[to].neis,p2)); if (*p2->dq > *communities.e[to].maxdq->dq) { communities.e[to].maxdq = p2; k=igraph_i_fastgreedy_community_list_find_in_heap(&communities, to); igraph_i_fastgreedy_community_list_sift_up(&communities, k); } igraph_i_fastgreedy_community_update_dq(&communities, p2, *p2->dq-2*VECTOR(a)[to]*VECTOR(a)[p2->second]); j++; } /* Now, remove community `from` from the neighbors of community `to` */ if (communities.no_of_communities > 2) { debug(" REMOVING: %ld-%ld\n", to, from); igraph_i_fastgreedy_community_remove_nei(&communities, to, from); i=igraph_i_fastgreedy_community_list_find_in_heap(&communities, from); igraph_i_fastgreedy_community_list_remove(&communities, i); } communities.e[from].maxdq=0; /* Update community sizes */ communities.e[to].size += communities.e[from].size; communities.e[from].size = 0; /* record what has been merged */ /* igraph_vector_ptr_clear is not enough here as it won't free * the memory consumed by communities.e[from].neis. Thanks * to Tom Gregorovic for pointing that out. */ igraph_vector_ptr_destroy(&communities.e[from].neis); if (merges) { MATRIX(*merges, no_of_joins, 0) = communities.e[to].id; MATRIX(*merges, no_of_joins, 1) = communities.e[from].id; communities.e[to].id = no_of_nodes+no_of_joins; } /* Update vector a */ VECTOR(a)[to] += VECTOR(a)[from]; VECTOR(a)[from] = 0.0; no_of_joins++; } /* TODO: continue merging when some isolated communities remained. Always * joining the communities with the least number of nodes results in the * smallest decrease in modularity every step. Now we're simply deleting * the excess rows from the merge matrix */ if (no_of_joins < total_joins) { long int *ivec; ivec=igraph_Calloc(igraph_matrix_nrow(merges), long int); if (ivec == 0) IGRAPH_ERROR("can't run fast greedy community detection", IGRAPH_ENOMEM); IGRAPH_FINALLY(free, ivec); for (i=0; i<no_of_joins; i++) ivec[i] = i+1; igraph_matrix_permdelete_rows(merges, ivec, total_joins-no_of_joins); free(ivec); IGRAPH_FINALLY_CLEAN(1); }
int main() { igraph_matrix_t m, m2; igraph_vector_t v; long int i, j, i2, j2; igraph_real_t r1, r2; igraph_matrix_init(&m, 4, 3); byrow(&m); /* igraph_matrix_e */ printf("igraph_matrix_e\n"); apply(m, printf("%i ", (int)igraph_matrix_e(&m, i, j)), printf("\n")); /* igraph_matrix_e_ptr */ printf("igraph_matrix_e_ptr\n"); apply(m, printf("%i ", (int)igraph_matrix_e_ptr(&m, i, j)[0]), printf("\n")); /* igraph_matrix_set */ printf("igraph_matrix_set\n"); apply(m, igraph_matrix_set(&m, i, j, i), (void) 0 ); print_matrix(&m); apply(m, igraph_matrix_set(&m, i, j, j), (void) 0 ); print_matrix(&m); /* igraph_matrix_fill */ printf("igraph_matrix_fill\n"); igraph_matrix_fill(&m, 42); print_matrix(&m); igraph_matrix_fill(&m, -42.1); print_matrix(&m); /* igraph_matrix_update */ printf("igraph_matrix_update\n"); igraph_matrix_init(&m2, 0, 0); byrow(&m); igraph_matrix_update(&m2, &m); print_matrix(&m2); /* igraph_matrix_rbind */ printf("igraph_matrix_rbind\n"); igraph_matrix_rbind(&m2, &m); print_matrix(&m2); printf("\n"); igraph_matrix_resize(&m, 0, igraph_matrix_ncol(&m2)); igraph_matrix_rbind(&m2, &m); print_matrix(&m2); printf("\n"); igraph_matrix_rbind(&m, &m2); print_matrix(&m); /* igraph_matrix_cbind */ printf("igraph_matrix_cbind\n"); igraph_matrix_resize(&m, 4, 3); igraph_matrix_resize(&m2, 4, 2); byrow(&m); byrow(&m2); igraph_matrix_cbind(&m, &m2); print_matrix(&m); /* igraph_matrix_swap */ printf("igraph_matrix_swap\n"); igraph_matrix_update(&m, &m2); igraph_matrix_null(&m); igraph_matrix_swap(&m, &m2); print_matrix(&m); print_matrix(&m2); /* igraph_matrix_get_row */ /* igraph_matrix_set_row */ printf("igraph_matrix_get_row\n"); printf("igraph_matrix_set_row\n"); igraph_vector_init(&v, 0); for (i=0; i<igraph_matrix_nrow(&m); i++) { igraph_matrix_get_row(&m, &v, i); igraph_matrix_set_row(&m2, &v, i); } print_matrix(&m2); /* igraph_matrix_set_col */ printf("igraph_matrix_set_col\n"); igraph_matrix_null(&m2); for (i=0; i<igraph_matrix_ncol(&m); i++) { igraph_matrix_get_col(&m, &v, i); igraph_matrix_set_col(&m2, &v, i); } print_matrix(&m2); /* igraph_matrix_swap_rows */ printf("igraph_matrix_swap_rows\n"); igraph_matrix_swap_rows(&m2, 0, 0); igraph_matrix_swap_rows(&m2, 0, 2); print_matrix(&m2); /* igraph_matrix_swap_cols */ printf("igraph_matrix_swap_cols\n"); igraph_matrix_swap_cols(&m2, 0, 0); igraph_matrix_swap_cols(&m2, 0, 1); print_matrix(&m2); /* igraph_matrix_add_constant */ printf("igraph_matrix_add_constant\n"); igraph_matrix_add_constant(&m2, 0); print_matrix(&m2); igraph_matrix_add_constant(&m2, -1); print_matrix(&m2); /* igraph_matrix_add */ printf("igraph_matrix_add\n"); byrow(&m2); byrow(&m); igraph_matrix_add(&m2, &m); print_matrix(&m2); /* igraph_matrix_sub */ printf("igraph_matrix_sub\n"); igraph_matrix_sub(&m2, &m); print_matrix(&m2); /* igraph_matrix_mul_elements */ printf("igraph_matrix_mul_elements\n"); igraph_matrix_mul_elements(&m2, &m); print_matrix(&m2); /* igraph_matrix_div_elements */ printf("igraph_matrix_div_elements\n"); igraph_matrix_fill(&m, 2); igraph_matrix_div_elements(&m2, &m); print_matrix(&m2); /* igraph_matrix_min */ printf("igraph_matrix_min\n"); if (igraph_matrix_min(&m2) != 0) { return 1; } if (igraph_matrix_min(&m) != 2) { return 1; } /* igraph_matrix_which_min */ printf("igraph_matrix_which_min\n"); igraph_matrix_which_min(&m2, &i, &j); if (i != 0 || j != 0) { return 2; } MATRIX(m2,0,1) = -1; igraph_matrix_which_min(&m2, &i, &j); if (i != 0 || j != 1) { return 2; } MATRIX(m2,3,1) = -2; igraph_matrix_which_min(&m2, &i, &j); if (i != 3 || j != 1) { return 2; } /* igraph_matrix_which_max */ printf("igraph_matrix_which_max\n"); MATRIX(m2,3,0) = 100; igraph_matrix_which_max(&m2, &i, &j); if (i != 3 || j != 0) { return 3; } /* igraph_matrix_minmax */ printf("igraph_matrix_minmax\n"); igraph_matrix_minmax(&m2, &r1, &r2); printf("%g %g\n", r1, r2); /* igraph_matrix_which_minmax */ printf("igraph_matrix_which_minmax\n"); igraph_matrix_which_minmax(&m2, &i, &j, &i2, &j2); if (i != 3 || j != 1 || i2 != 3 || j2 != 0) { return 4; } /* igraph_matrix_isnull */ printf("igraph_matrix_isnull\n"); if (igraph_matrix_isnull(&m2)) { return 5; } igraph_matrix_null(&m); if (!igraph_matrix_isnull(&m)) { return 5; } igraph_matrix_resize(&m2, 5, 0); if (!igraph_matrix_isnull(&m2)) { return 5; } /* igraph_matrix_empty */ printf("igraph_matrix_empty\n"); if (!igraph_matrix_empty(&m2)) { return 6; } igraph_matrix_resize(&m2, 5, 5); if (igraph_matrix_empty(&m2)) { return 6; } /* igraph_matrix_is_symmetric */ printf("igraph_matrix_is_symmetric\n"); byrow(&m2); if (igraph_matrix_is_symmetric(&m2)) { return 7; } igraph_matrix_update(&m, &m2); igraph_matrix_transpose(&m); igraph_matrix_add(&m, &m2); if (!igraph_matrix_is_symmetric(&m)) { return 7; } /* igraph_matrix_prod */ printf("igraph_matrix_prod\n"); igraph_matrix_resize(&m, 3,2); byrow(&m); igraph_matrix_add_constant(&m, 1); print_matrix(&m); printf("product: %g\n", igraph_matrix_prod(&m)); /* igraph_matrix_rowsum */ printf("igraph_matrix_rowsum\n"); igraph_matrix_rowsum(&m, &v); print_vector(&v); /* igraph_matrix_colsum */ printf("igraph_matrix_colsum\n"); igraph_matrix_colsum(&m, &v); print_vector(&v); /* igraph_matrix_contains */ printf("igraph_matrix_contains\n"); if (igraph_matrix_contains(&m, 0)) { return 8; } if (igraph_matrix_contains(&m, 6.0001)) { return 8; } if (igraph_matrix_contains(&m, 7)) { return 8; } if (!igraph_matrix_contains(&m, 1)) { return 8; } if (!igraph_matrix_contains(&m, 6)) { return 8; } /* igraph_matrix_search */ printf("igraph_matrix_search\n"); if (!igraph_matrix_search(&m, 0, 6.0, &i2, &i, &j)) { return 9; } if (i2 != 5 || i != 2 || j != 1) { return 9; } /* igraph_matrix_remove_row */ printf("igraph_matrix_remove_row\n"); igraph_matrix_remove_row(&m, 1); print_matrix(&m); igraph_matrix_resize(&m,5,4); byrow(&m); igraph_matrix_remove_row(&m, 4); print_matrix(&m); igraph_matrix_remove_row(&m, 0); print_matrix(&m); /* igraph_matrix_select_cols */ printf("igraph_matrix_select_cols\n"); igraph_matrix_resize(&m, 6, 5); apply(m, igraph_matrix_set(&m, i, j, j), (void) 0 ); igraph_vector_resize(&v, 3); VECTOR(v)[0]=0; VECTOR(v)[1]=4; VECTOR(v)[2]=2; igraph_matrix_select_cols(&m, &m2, &v); print_matrix(&m2); igraph_vector_resize(&v, 1); igraph_matrix_select_cols(&m, &m2, &v); print_matrix(&m2); igraph_vector_clear(&v); igraph_matrix_select_cols(&m, &m2, &v); if (!igraph_matrix_empty(&m2)) { return 9; } igraph_vector_destroy(&v); igraph_matrix_destroy(&m2); igraph_matrix_destroy(&m); if (IGRAPH_FINALLY_STACK_SIZE() != 0) return 10; return 0; }
int igraph_get_incidence(const igraph_t *graph, const igraph_vector_bool_t *types, igraph_matrix_t *res, igraph_vector_t *row_ids, igraph_vector_t *col_ids) { long int no_of_nodes=igraph_vcount(graph); long int no_of_edges=igraph_ecount(graph); long int n1=0, n2=0, i; igraph_vector_t perm; long int p1, p2; if (igraph_vector_bool_size(types) != no_of_nodes) { IGRAPH_ERROR("Invalid vertex type vector for bipartite graph", IGRAPH_EINVAL); } for (i=0; i<no_of_nodes; i++) { n1 += VECTOR(*types)[i] == 0 ? 1 : 0; } n2 = no_of_nodes-n1; IGRAPH_VECTOR_INIT_FINALLY(&perm, no_of_nodes); for (i=0, p1=0, p2=n1; i<no_of_nodes; i++) { VECTOR(perm)[i] = VECTOR(*types)[i] ? p2++ : p1++; } IGRAPH_CHECK(igraph_matrix_resize(res, n1, n2)); igraph_matrix_null(res); for (i=0; i<no_of_edges; i++) { long int from=IGRAPH_FROM(graph, i); long int to=IGRAPH_TO(graph, i); long int from2=(long int) VECTOR(perm)[from]; long int to2=(long int) VECTOR(perm)[to]; if (! VECTOR(*types)[from]) { MATRIX(*res, from2, to2-n1) += 1; } else { MATRIX(*res, to2, from2-n1) += 1; } } if (row_ids) { IGRAPH_CHECK(igraph_vector_resize(row_ids, n1)); } if (col_ids) { IGRAPH_CHECK(igraph_vector_resize(col_ids, n2)); } if (row_ids || col_ids) { for (i=0; i<no_of_nodes; i++) { if (! VECTOR(*types)[i]) { if (row_ids) { long int i2=(long int) VECTOR(perm)[i]; VECTOR(*row_ids)[i2] = i; } } else { if (col_ids) { long int i2=(long int) VECTOR(perm)[i]; VECTOR(*col_ids)[i2-n1] = i; } } } } igraph_vector_destroy(&perm); IGRAPH_FINALLY_CLEAN(1); return 0; }
int igraph_get_adjacency(const igraph_t *graph, igraph_matrix_t *res, igraph_get_adjacency_t type) { igraph_eit_t edgeit; long int no_of_nodes=igraph_vcount(graph); igraph_bool_t directed=igraph_is_directed(graph); int retval=0; long int from, to; igraph_integer_t ffrom, fto; IGRAPH_CHECK(igraph_matrix_resize(res, no_of_nodes, no_of_nodes)); igraph_matrix_null(res); IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(0), &edgeit)); IGRAPH_FINALLY(igraph_eit_destroy, &edgeit); if (directed) { while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &ffrom, &fto); from=ffrom; to=fto; MATRIX(*res, from, to) += 1; IGRAPH_EIT_NEXT(edgeit); } } else if (type==IGRAPH_GET_ADJACENCY_UPPER) { while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &ffrom, &fto); from=ffrom; to=fto; if (to < from) { MATRIX(*res, to, from) += 1; } else { MATRIX(*res, from, to) += 1; } IGRAPH_EIT_NEXT(edgeit); } } else if (type==IGRAPH_GET_ADJACENCY_LOWER) { while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &ffrom, &fto); from=ffrom; to=fto; if (to < from) { MATRIX(*res, from, to) += 1; } else { MATRIX(*res, to, from) += 1; } IGRAPH_EIT_NEXT(edgeit); } } else if (type==IGRAPH_GET_ADJACENCY_BOTH) { while (!IGRAPH_EIT_END(edgeit)) { igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &ffrom, &fto); from=ffrom; to=fto; MATRIX(*res, from, to) += 1; if (from != to) { MATRIX(*res, to, from) += 1; } IGRAPH_EIT_NEXT(edgeit); } } else { IGRAPH_ERROR("Invalid type argument", IGRAPH_EINVAL); } igraph_eit_destroy(&edgeit); IGRAPH_FINALLY_CLEAN(1); return retval; }