Exemple #1
0
/* 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;
}
Exemple #2
0
/*__________________________________________________________________________ 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);
    
}
Exemple #3
0
/* Initializing elements */
void Matrix::null() noexcept { igraph_matrix_null(ptr()); }
Exemple #4
0
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;
}
Exemple #5
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;
}
Exemple #7
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(&degree, no_of_nodes));
    IGRAPH_FINALLY(&igraph_vector_long_destroy, &degree);

    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(&degree);
    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);
  }
Exemple #10
0
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;
}
Exemple #11
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;
}