Пример #1
0
/* #include "igraph_visitor.h"
#include "igraph_memory.h"
#include "igraph_adjlist.h"
#include "igraph_interface.h"
#include "igraph_dqueue.h"
#include "igraph_stack.h"
#include "config.h"*/
int igraph_bfsr(const igraph_t *graph, 
	       igraph_integer_t root,igraph_vector_t *roots,
	       igraph_neimode_t mode, igraph_bool_t unreachable,
	       const igraph_vector_t *restricted,
	       igraph_vector_t *order, igraph_vector_t *rank,
	       igraph_vector_t *father,
	       igraph_vector_t *pred, igraph_vector_t *succ,
	       igraph_vector_t *dist, igraph_bfshandler_t *callback,
	       void *extra) {
  
  igraph_dqueue_t Q;
  long int no_of_nodes=igraph_vcount(graph);
  long int actroot=0;
  igraph_vector_char_t added;

  igraph_lazy_adjlist_t adjlist;
  
  long int act_rank=0;
  long int pred_vec=-1;
  
  long int rootpos=0;
  long int noroots= roots ? igraph_vector_size(roots) : 1;

  if (!roots && (root < 0 || root >= no_of_nodes)) {
    IGRAPH_ERROR("Invalid root vertex in BFS", IGRAPH_EINVAL);
  }
  
  if (roots) {
    igraph_real_t min, max;
    igraph_vector_minmax(roots, &min, &max);
    if (min < 0 || max >= no_of_nodes) {
      IGRAPH_ERROR("Invalid root vertex in BFS", IGRAPH_EINVAL);
    }
  }

  if (restricted) {
    igraph_real_t min, max;
    igraph_vector_minmax(restricted, &min, &max);
    if (min < 0 || max >= no_of_nodes) {
      IGRAPH_ERROR("Invalid vertex id in restricted set", IGRAPH_EINVAL);
    }
  }

  if (mode != IGRAPH_OUT && mode != IGRAPH_IN && 
      mode != IGRAPH_ALL) {
    IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE);
  }
  
  if (!igraph_is_directed(graph)) { mode=IGRAPH_ALL; }

  IGRAPH_CHECK(igraph_vector_char_init(&added, no_of_nodes));
  IGRAPH_FINALLY(igraph_vector_char_destroy, &added);
  IGRAPH_CHECK(igraph_dqueue_init(&Q, 100));
  IGRAPH_FINALLY(igraph_dqueue_destroy, &Q);

  IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, mode, /*simplify=*/ 0));
  IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist);

  /* Mark the vertices that are not in the restricted set, as already
     found. Special care must be taken for vertices that are not in
     the restricted set, but are to be used as 'root' vertices. */
  if (restricted) {
    long int i, n=igraph_vector_size(restricted);
    igraph_vector_char_fill(&added, 1);
    for (i=0; i<n; i++) {
      long int v=(long int) VECTOR(*restricted)[i];
      VECTOR(added)[v]=0;
    }
  }

  /* Resize result vectors, and fill them with IGRAPH_NAN */

# define VINIT(v) if (v) {                      \
  igraph_vector_resize((v), no_of_nodes);	\
  igraph_vector_fill((v), IGRAPH_NAN); }

  VINIT(order);
  VINIT(rank);
  VINIT(father);
  VINIT(pred);
  VINIT(succ);
  VINIT(dist);
# undef VINIT
        
  while (1) { 

    /* Get the next root vertex, if any */

    if (roots && rootpos < noroots) {
      /* We are still going through the 'roots' vector */
      actroot=(long int) VECTOR(*roots)[rootpos++];
    } else if (!roots && rootpos==0) {
      /* We have a single root vertex given, and start now */
      actroot=root;
      rootpos++;
    } else if (rootpos==noroots && unreachable) {
      /* We finished the given root(s), but other vertices are also
	 tried as root */
      actroot=0;
      rootpos++;
    } else if (unreachable && actroot+1 < no_of_nodes) {
      /* We are already doing the other vertices, take the next one */
      actroot++;
    } else {
      /* No more root nodes to do */
      break;
    }

    /* OK, we have a new root, start BFS */
    if (VECTOR(added)[actroot]) { continue; }
    IGRAPH_CHECK(igraph_dqueue_push(&Q, actroot));
    IGRAPH_CHECK(igraph_dqueue_push(&Q, 0));
    VECTOR(added)[actroot] = 1;
    if (father) { VECTOR(*father)[actroot] = -1; }
      
    pred_vec=-1;

    while (!igraph_dqueue_empty(&Q)) {
      long int actvect=(long int) igraph_dqueue_pop(&Q);
      long int actdist=(long int) igraph_dqueue_pop(&Q);
      long int succ_vec;
      igraph_vector_t *neis=igraph_lazy_adjlist_get(&adjlist, 
						    (igraph_integer_t) actvect);
      long int i, n=igraph_vector_size(neis);    
      
      if (pred) { VECTOR(*pred)[actvect] = pred_vec; }
      if (rank) { VECTOR(*rank) [actvect] = act_rank; }
      if (order) { VECTOR(*order)[act_rank++] = actvect; }
      if (dist) { VECTOR(*dist)[actvect] = actdist; }      
      igraph_vector_shuffle(neis);
      for (i=0; i<n; i++) {
	long int nei=(long int) VECTOR(*neis)[i];
	if (! VECTOR(added)[nei]) {
	  VECTOR(added)[nei] = 1;
	  IGRAPH_CHECK(igraph_dqueue_push(&Q, nei));
	  IGRAPH_CHECK(igraph_dqueue_push(&Q, actdist+1));
	  if (father) { VECTOR(*father)[nei] = actvect; }
	}
      }

      succ_vec = igraph_dqueue_empty(&Q) ? -1L : 
	(long int) igraph_dqueue_head(&Q);
      if (callback) {
	igraph_bool_t terminate=
	  callback(graph, (igraph_integer_t) actvect, (igraph_integer_t) 
		   pred_vec, (igraph_integer_t) succ_vec, 
		   (igraph_integer_t) act_rank-1, (igraph_integer_t) actdist, 
		   extra);
	if (terminate) {
	  igraph_lazy_adjlist_destroy(&adjlist);
	  igraph_dqueue_destroy(&Q);
	  igraph_vector_char_destroy(&added);
	  IGRAPH_FINALLY_CLEAN(3);
	  return 0;
	}
      }

      if (succ) { VECTOR(*succ)[actvect] = succ_vec; }
      pred_vec=actvect;

    } /* while Q !empty */

  } /* for actroot < no_of_nodes */

  igraph_lazy_adjlist_destroy(&adjlist);
  igraph_dqueue_destroy(&Q);
  igraph_vector_char_destroy(&added);
  IGRAPH_FINALLY_CLEAN(3);
  
  return 0;
}
Пример #2
0
int dfs_d(const igraph_t *graph, igraph_integer_t root,
	       igraph_neimode_t mode, igraph_bool_t unreachable, 
	       igraph_vector_t *order,
	       igraph_vector_t *order_out, igraph_vector_t *father,
	       igraph_vector_t *dist, igraph_dfshandler_t *in_callback,
	       igraph_dfshandler_t *out_callback,
	       void *extra) {
  
  long int no_of_nodes=igraph_vcount(graph);
  igraph_lazy_adjlist_t adjlist;
  igraph_stack_t stack;
  igraph_vector_char_t added;
  igraph_vector_long_t nptr;
  long int actroot;
  long int act_rank=0;
  long int rank_out=0;
  long int act_dist=0;

  if (root < 0 || root >= no_of_nodes) { 
    IGRAPH_ERROR("Invalid root vertex for DFS", IGRAPH_EINVAL);
  }

  if (mode != IGRAPH_OUT && mode != IGRAPH_IN && 
      mode != IGRAPH_ALL) {
    IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE);
  }
  
  if (!igraph_is_directed(graph)) { mode=IGRAPH_ALL; }

  IGRAPH_CHECK(igraph_vector_char_init(&added, no_of_nodes));
  IGRAPH_FINALLY(igraph_vector_char_destroy, &added);
  IGRAPH_CHECK(igraph_stack_init(&stack, 100));
  IGRAPH_FINALLY(igraph_stack_destroy, &stack);
  IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, mode, /*simplify=*/ 0));  
  IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist);
  IGRAPH_CHECK(igraph_vector_long_init(&nptr, no_of_nodes));
  IGRAPH_FINALLY(igraph_vector_long_destroy, &nptr);

# define FREE_ALL() do { 			\
  igraph_vector_long_destroy(&nptr);            \
  igraph_lazy_adjlist_destroy(&adjlist);        \
  igraph_stack_destroy(&stack);                 \
  igraph_vector_char_destroy(&added);           \
  IGRAPH_FINALLY_CLEAN(4); } while (0)

  /* Resize result vectors and fill them with IGRAPH_NAN */
  
# define VINIT(v) if (v) {                      \
    igraph_vector_resize(v, no_of_nodes);       \
    igraph_vector_fill(v, IGRAPH_NAN); }
  
  VINIT(order);
  VINIT(order_out);
  VINIT(father);
  VINIT(dist);

# undef VINIT

  IGRAPH_CHECK(igraph_stack_push(&stack, root));
  VECTOR(added)[(long int)root] = 1;
  if (father) { VECTOR(*father)[(long int)root] = -1; }
  if (order) { VECTOR(*order)[act_rank++] = root; }
  if (dist) { VECTOR(*dist)[(long int)root] = 0; }
  if (in_callback) {
    igraph_bool_t terminate=in_callback(graph, root, 0, extra);
    if (terminate) { FREE_ALL(); return 0; }
  }

  for (actroot=0; actroot<no_of_nodes; actroot++) {

    /* 'root' first, then all other vertices */
    if (igraph_stack_empty(&stack)) {
      if (!unreachable) { break; }
      if (VECTOR(added)[actroot]) { continue; }
      IGRAPH_CHECK(igraph_stack_push(&stack, actroot));
      VECTOR(added)[actroot] = 1;
      if (father) { VECTOR(*father)[actroot] = -1; }
      if (order) { VECTOR(*order)[act_rank++] = actroot; }
      if (dist) { VECTOR(*dist)[actroot] = 0; }

      if (in_callback) {
	igraph_bool_t terminate=in_callback(graph, (igraph_integer_t) actroot,
					    0, extra);
	if (terminate) { FREE_ALL(); return 0; }
      }
    }
    
    while (!igraph_stack_empty(&stack)) {
      long int actvect=(long int) igraph_stack_top(&stack);
      igraph_vector_t *neis=igraph_lazy_adjlist_get(&adjlist, 
						    (igraph_integer_t) actvect);
      long int n=igraph_vector_size(neis);
      long int *ptr=igraph_vector_long_e_ptr(&nptr, actvect);

      igraph_vector_shuffle(neis);
      igraph_vector_print(neis);
      /* Search for a neighbor that was not yet visited */
      igraph_bool_t any=0;
      long int nei;
      while (!any && (*ptr) <n) {
	nei=(long int) VECTOR(*neis)[(*ptr)];
	any=!VECTOR(added)[nei];
	(*ptr) ++;
      }
      if (any) {
	/* There is such a neighbor, add it */
	IGRAPH_CHECK(igraph_stack_push(&stack, nei));
	VECTOR(added)[nei] = 1;
	if (father) { VECTOR(*father)[ nei ] = actvect; }
	if (order) { VECTOR(*order)[act_rank++] = nei; }
	act_dist++;
	if (dist) { VECTOR(*dist)[nei] = act_dist; }

	if (in_callback) {
	  igraph_bool_t terminate=in_callback(graph, (igraph_integer_t) nei,
					      (igraph_integer_t) act_dist, 
					      extra);
	  if (terminate) { FREE_ALL(); return 0; }
	}

      } else {
	/* There is no such neighbor, finished with the subtree */
	igraph_stack_pop(&stack);
	if (order_out) { VECTOR(*order_out)[rank_out++] = actvect; }
	act_dist--;

	if (out_callback) {
	  igraph_bool_t terminate=out_callback(graph, (igraph_integer_t) 
					       actvect, (igraph_integer_t) 
					       act_dist, extra);
	  if (terminate) { FREE_ALL(); return 0; }
	}
      }
    }      
  }

  FREE_ALL();
# undef FREE_ALL

  return 0;
}
Пример #3
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;
}
Пример #4
0
int igraph_revolver_st_d_d(const igraph_t *graph,
                           igraph_lazy_inclist_t *inclist,
                           igraph_vector_t *st,
                           const igraph_matrix_t *kernel,
                           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) {

    long int no_of_events=pno_of_events;
    long int maxdegree=igraph_matrix_nrow(kernel)-1;
    long int no_of_nodes=igraph_vcount(graph);
    long int no_of_edges=igraph_ecount(graph);
    long int timestep=0;

    igraph_vector_long_t degree;
    igraph_vector_long_t ntk;
    igraph_vector_char_t added;

    igraph_vector_t *adjedges;

    long int i;
    long int nptr=0, eptr=0;

    IGRAPH_CHECK(igraph_vector_long_init(&ntk, maxdegree+1));
    IGRAPH_FINALLY(igraph_vector_long_destroy, &ntk);
    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_resize(st, no_of_events));
    VECTOR(*st)[0]=0;

    for (timestep=0; timestep<no_of_events-1; timestep++) {

        IGRAPH_ALLOW_INTERRUPTION();

        /* add the new nodes */
        while (nptr < no_of_nodes &&
                VECTOR(*vtime)[ (long int) VECTOR(*vtimeidx)[nptr] ] == timestep) {
            for (i=0; i<maxdegree+1; i++) {
                VECTOR(*st)[timestep] += VECTOR(ntk)[i]*MATRIX(*kernel, i, 0);
            }
            VECTOR(ntk)[0]++;
            nptr++;
        }

        /* add the new edges as well, but this is for the next timestep
           already */
        VECTOR(*st)[timestep+1] = VECTOR(*st)[timestep];
        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];
            igraph_real_t inc=0;
            long int n;

            inc -= MATRIX(*kernel, xidx, yidx);

            for (i=0; i<maxdegree+1; i++) {
                inc += VECTOR(ntk)[i] * (MATRIX(*kernel, i, xidx+1) -
                                         MATRIX(*kernel, i, xidx)   +
                                         MATRIX(*kernel, i, yidx+1) -
                                         MATRIX(*kernel, i, yidx));
            }
            inc -= MATRIX(*kernel, xidx+1, xidx+1);
            inc -= MATRIX(*kernel, yidx+1, yidx+1);
            inc += MATRIX(*kernel, xidx, xidx);
            inc += MATRIX(*kernel, yidx, yidx);

            VECTOR(ntk)[xidx]--;
            VECTOR(ntk)[yidx]--;
            VECTOR(ntk)[xidx+1]++;
            VECTOR(ntk)[yidx+1]++;

            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);
                    long int deg=VECTOR(degree)[otherv];
                    inc += MATRIX(*kernel, xidx, deg);
                    inc -= MATRIX(*kernel, 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);
                    long int deg=VECTOR(degree)[otherv];
                    inc += MATRIX(*kernel, yidx, deg);
                    inc -= MATRIX(*kernel, yidx+1, deg);
                }
            }

            VECTOR(degree)[from] += 1;
            VECTOR(degree)[to] += 1;
            VECTOR(added)[edge]=1;

            VECTOR(*st)[timestep+1] += inc;

            eptr++;
        }
    }

    igraph_vector_char_destroy(&added);
    igraph_vector_long_destroy(&degree);
    igraph_vector_long_destroy(&ntk);
    IGRAPH_FINALLY_CLEAN(3);

    return 0;
}
Пример #5
0
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;
}
Пример #6
0
int igraph_revolver_st_p_p(const igraph_t *graph,
                           igraph_lazy_inclist_t *inclist,
                           igraph_vector_t *st,
                           const igraph_matrix_t *kernel,
                           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_events=pno_of_events;
    long int maxpapers=igraph_matrix_nrow(kernel)-1;
    long int no_of_nodes=igraph_vcount(graph);
    long int no_of_edges=igraph_ecount(graph);
    long int timestep=0;

    igraph_vector_long_t papers;
    igraph_vector_long_t ntk;
    igraph_vector_char_t added;

    igraph_vector_t *adjedges;

    long int i;
    long int nptr=0, eptr=0, aptr=0, nptr_save;

    IGRAPH_CHECK(igraph_vector_long_init(&ntk, maxpapers+1));
    IGRAPH_FINALLY(igraph_vector_long_destroy, &ntk);
    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_resize(st, no_of_events));
    VECTOR(*st)[0]=0;

    for (timestep=0; timestep<no_of_events-1; timestep++) {

        IGRAPH_ALLOW_INTERRUPTION();

        /* add the new nodes */
        nptr_save=nptr;
        while (nptr < no_of_nodes &&
                VECTOR(*vtime)[ (long int) VECTOR(*vtimeidx)[nptr] ] == timestep) {
            nptr++;
        }
        nptr_save=nptr-nptr_save;
        if (nptr_save != 0) {
            for (i=0; i<maxpapers+1; i++) {
                VECTOR(*st)[timestep] += VECTOR(ntk)[i]*MATRIX(*kernel, i, 0)*nptr_save;
            }
            VECTOR(*st)[timestep] += nptr_save*(nptr_save-1)/2 * MATRIX(*kernel, 0, 0);
            VECTOR(ntk)[0]+=nptr_save;
        }

        VECTOR(*st)[timestep+1] = VECTOR(*st)[timestep];

        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;

            for (j=0; j<maxpapers+1; j++) {
                VECTOR(*st)[timestep+1] += VECTOR(ntk)[j] * (MATRIX(*kernel, j, pap+1)-
                                           MATRIX(*kernel, j, pap));
            }

            VECTOR(*st)[timestep+1] += MATRIX(*kernel, pap, pap);
            VECTOR(*st)[timestep+1] -= MATRIX(*kernel, pap+1, pap+1);

            VECTOR(ntk)[pap]--;
            VECTOR(ntk)[pap+1]++;

            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];
                    VECTOR(*st)[timestep+1] += MATRIX(*kernel, pap, otherpap);
                    VECTOR(*st)[timestep+1] -= MATRIX(*kernel, pap+1, otherpap);
                }
            }

            VECTOR(papers)[aut] += 1;
        }
        aptr += VECTOR(*eventsizes)[timestep];

        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(papers)[from];
            long int yidx=VECTOR(papers)[to];
            VECTOR(*st)[timestep+1] -= MATRIX(*kernel, xidx, yidx);
            VECTOR(added)[edge]=1;
            eptr++;
        }

    }

    igraph_vector_char_destroy(&added);
    igraph_vector_long_destroy(&papers);
    igraph_vector_long_destroy(&ntk);
    IGRAPH_FINALLY_CLEAN(3);

    return 0;
}
Пример #7
0
int igraph_is_bipartite(const igraph_t *graph,
			igraph_bool_t *res,
			igraph_vector_bool_t *type) {
  
  /* We basically do a breadth first search and label the
     vertices along the way. We stop as soon as we can find a
     contradiction. 
  
     In the 'seen' vector 0 means 'not seen yet', 1 means type 1, 
     2 means type 2.
  */

  long int no_of_nodes=igraph_vcount(graph);
  igraph_vector_char_t seen;
  igraph_dqueue_t Q;
  igraph_vector_t neis;
  igraph_bool_t bi=1;
  long int i;
  
  IGRAPH_CHECK(igraph_vector_char_init(&seen, no_of_nodes));
  IGRAPH_FINALLY(igraph_vector_char_destroy, &seen);
  IGRAPH_DQUEUE_INIT_FINALLY(&Q, 100);
  IGRAPH_VECTOR_INIT_FINALLY(&neis, 0);

  for (i=0; bi && i<no_of_nodes; i++) {
    
    if (VECTOR(seen)[i]) { continue; }
    
    IGRAPH_CHECK(igraph_dqueue_push(&Q, i));
    VECTOR(seen)[i]=1;
    
    while (bi && !igraph_dqueue_empty(&Q)) {
      long int n, j;
      igraph_integer_t actnode=(igraph_integer_t) igraph_dqueue_pop(&Q);
      char acttype=VECTOR(seen)[actnode];
      
      IGRAPH_CHECK(igraph_neighbors(graph, &neis, actnode, IGRAPH_ALL));
      n=igraph_vector_size(&neis);
      for (j=0; j<n; j++) {
	long int nei=(long int) VECTOR(neis)[j];
	if (VECTOR(seen)[nei]) {
	  long int neitype=VECTOR(seen)[nei];
	  if (neitype == acttype) { 
	    bi=0; 
	    break;
	  }
	} else {
	  VECTOR(seen)[nei] = 3 - acttype;
	  IGRAPH_CHECK(igraph_dqueue_push(&Q, nei));
	}
      }
    }
  }

  igraph_vector_destroy(&neis);
  igraph_dqueue_destroy(&Q);
  IGRAPH_FINALLY_CLEAN(2);

  if (res) { *res=bi; }
  
  if (type && bi) { 
    IGRAPH_CHECK(igraph_vector_bool_resize(type, no_of_nodes));
    for (i=0; i<no_of_nodes; i++) {
      VECTOR(*type)[i] = VECTOR(seen)[i] - 1;
    }
  }

  igraph_vector_char_destroy(&seen);
  IGRAPH_FINALLY_CLEAN(1);
    
  return 0;
}