int igraph_i_eigen_matrix_lapack_common(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors) { igraph_vector_t valuesreal, valuesimag; igraph_matrix_t vectorsright, *myvectors= vectors ? &vectorsright : 0; int n=(int) igraph_matrix_nrow(A); int info=1; IGRAPH_VECTOR_INIT_FINALLY(&valuesreal, n); IGRAPH_VECTOR_INIT_FINALLY(&valuesimag, n); if (vectors) { IGRAPH_MATRIX_INIT_FINALLY(&vectorsright, n, n); } IGRAPH_CHECK(igraph_lapack_dgeev(A, &valuesreal, &valuesimag, /*vectorsleft=*/ 0, myvectors, &info)); IGRAPH_CHECK(igraph_i_eigen_matrix_lapack_reorder(&valuesreal, &valuesimag, myvectors, which, values, vectors)); if (vectors) { igraph_matrix_destroy(&vectorsright); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&valuesimag); igraph_vector_destroy(&valuesreal); IGRAPH_FINALLY_CLEAN(2); return 0; }
int igraph_i_eigen_matrix_symmetric_arpack_be(const igraph_matrix_t *A, const igraph_sparsemat_t *sA, igraph_arpack_function_t *fun, int n, void *extra, const igraph_eigen_which_t *which, igraph_arpack_options_t *options, igraph_arpack_storage_t *storage, igraph_vector_t *values, igraph_matrix_t *vectors) { igraph_vector_t tmpvalues, tmpvalues2; igraph_matrix_t tmpvectors, tmpvectors2; igraph_i_eigen_matrix_sym_arpack_data_t myextra = { A, sA }; int low=(int) floor(which->howmany/2.0), high=(int) ceil(which->howmany/2.0); int l1, l2, w; if (low + high >= n) { IGRAPH_ERROR("Requested too many eigenvalues/vectors", IGRAPH_EINVAL); } if (!fun) { fun=igraph_i_eigen_matrix_sym_arpack_cb; extra=(void*) &myextra; } IGRAPH_VECTOR_INIT_FINALLY(&tmpvalues, high); IGRAPH_MATRIX_INIT_FINALLY(&tmpvectors, n, high); IGRAPH_VECTOR_INIT_FINALLY(&tmpvalues2, low); IGRAPH_MATRIX_INIT_FINALLY(&tmpvectors2, n, low); options->n=n; options->nev=high; options->ncv= 2*options->nev < n ? 2*options->nev : n; options->which[0]='L'; options->which[1]='A'; IGRAPH_CHECK(igraph_arpack_rssolve(fun, extra, options, storage, &tmpvalues, &tmpvectors)); options->nev=low; options->ncv= 2*options->nev < n ? 2*options->nev : n; options->which[0]='S'; options->which[1]='A'; IGRAPH_CHECK(igraph_arpack_rssolve(fun, extra, options, storage, &tmpvalues2, &tmpvectors2)); IGRAPH_CHECK(igraph_vector_resize(values, low+high)); IGRAPH_CHECK(igraph_matrix_resize(vectors, n, low+high)); l1=0; l2=0; w=0; while (w < which->howmany) { VECTOR(*values)[w] = VECTOR(tmpvalues)[l1]; memcpy(&MATRIX(*vectors, 0, w), &MATRIX(tmpvectors, 0, l1), (size_t) n * sizeof(igraph_real_t)); w++; l1++; if (w < which->howmany) { VECTOR(*values)[w] = VECTOR(tmpvalues2)[l2]; memcpy(&MATRIX(*vectors, 0, w), &MATRIX(tmpvectors2, 0, l2), (size_t) n * sizeof(igraph_real_t)); w++; l2++; } } igraph_matrix_destroy(&tmpvectors2); igraph_vector_destroy(&tmpvalues2); igraph_matrix_destroy(&tmpvectors); igraph_vector_destroy(&tmpvalues); IGRAPH_FINALLY_CLEAN(4); return 0; }
int igraph_i_community_spinglass_negative(const igraph_t *graph, const igraph_vector_t *weights, igraph_real_t *modularity, igraph_real_t *temperature, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t spins, igraph_bool_t parupdate, igraph_real_t starttemp, igraph_real_t stoptemp, igraph_real_t coolfact, igraph_spincomm_update_t update_rule, igraph_real_t gamma, /* igraph_matrix_t *adhesion, */ /* igraph_matrix_t *normalised_adhesion, */ /* igraph_real_t *polarization, */ igraph_real_t gamma_minus) { unsigned long changes, runs; igraph_bool_t use_weights=0; bool zeroT; double kT, acc; ClusterList<NNode*> *cl_cur; network *net; PottsModelN *pm; igraph_real_t d_n; igraph_real_t d_p; /* Check arguments */ if (parupdate) { IGRAPH_ERROR("Parallel spin update not implemented with " "negative gamma", IGRAPH_UNIMPLEMENTED); } if (spins < 2 || spins > 500) { IGRAPH_ERROR("Invalid number of spins", IGRAPH_EINVAL); } if (update_rule != IGRAPH_SPINCOMM_UPDATE_SIMPLE && update_rule != IGRAPH_SPINCOMM_UPDATE_CONFIG) { IGRAPH_ERROR("Invalid update rule", IGRAPH_EINVAL); } if (weights) { if (igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } use_weights=1; } if (coolfact < 0 || coolfact>=1.0) { IGRAPH_ERROR("Invalid cooling factor", IGRAPH_EINVAL); } if (gamma < 0.0) { IGRAPH_ERROR("Invalid gamma value", IGRAPH_EINVAL); } if (starttemp/stoptemp<1.0) { IGRAPH_ERROR("starttemp should be larger in absolute value than stoptemp", IGRAPH_EINVAL); } /* Check whether we have a single component */ igraph_bool_t conn; IGRAPH_CHECK(igraph_is_connected(graph, &conn, IGRAPH_WEAK)); if (!conn) { IGRAPH_ERROR("Cannot work with unconnected graph", IGRAPH_EINVAL); } igraph_vector_minmax(weights, &d_n, &d_p); if (d_n > 0) { d_n=0; } if (d_p < 0) { d_p=0; } d_n = -d_n; net = new network; net->node_list =new DL_Indexed_List<NNode*>(); net->link_list =new DL_Indexed_List<NLink*>(); net->cluster_list=new DL_Indexed_List<ClusterList<NNode*>*>(); /* Transform the igraph_t */ IGRAPH_CHECK(igraph_i_read_network(graph, weights, net, use_weights, 0)); bool directed = igraph_is_directed(graph); pm=new PottsModelN(net,(unsigned int)spins, directed); /* initialize the random number generator */ RNG_BEGIN(); if ((stoptemp==0.0) && (starttemp==0.0)) zeroT=true; else zeroT=false; //Begin at a high enough temperature kT=pm->FindStartTemp(gamma, gamma_minus, starttemp); /* assign random initial configuration */ pm->assign_initial_conf(true); runs=0; changes=1; acc = 0; while (changes>0 && (kT/stoptemp>1.0 || (zeroT && runs<150))) { IGRAPH_ALLOW_INTERRUPTION(); /* This is not clean.... */ runs++; kT = kT*coolfact; acc=pm->HeatBathLookup(gamma, gamma_minus, kT, 50); if (acc<(1.0-1.0/double(spins))*0.001) changes=0; else changes=1; } /* while loop */ /* These are needed, otherwise 'modularity' is not calculated */ igraph_matrix_t adhesion, normalized_adhesion; igraph_real_t polarization; IGRAPH_MATRIX_INIT_FINALLY(&adhesion, 0, 0); IGRAPH_MATRIX_INIT_FINALLY(&normalized_adhesion, 0, 0); pm->WriteClusters(modularity, temperature, csize, membership, &adhesion, &normalized_adhesion, &polarization, kT, d_p, d_n, gamma, gamma_minus); igraph_matrix_destroy(&normalized_adhesion); igraph_matrix_destroy(&adhesion); IGRAPH_FINALLY_CLEAN(2); while (net->link_list->Size()) delete net->link_list->Pop(); while (net->node_list->Size()) delete net->node_list->Pop(); while (net->cluster_list->Size()) { cl_cur=net->cluster_list->Pop(); while (cl_cur->Size()) cl_cur->Pop(); delete cl_cur; } RNG_END(); return 0; }
int igraph_i_eigen_matrix_symmetric_lapack_sm(const igraph_matrix_t *A, const igraph_eigen_which_t *which, igraph_vector_t *values, igraph_matrix_t *vectors) { igraph_vector_t val; igraph_matrix_t vec; int i, w=0, n=(int) igraph_matrix_nrow(A); igraph_real_t small; int p1, p2, pr=0; IGRAPH_VECTOR_INIT_FINALLY(&val, 0); if (vectors) { IGRAPH_MATRIX_INIT_FINALLY(&vec, 0, 0); } IGRAPH_CHECK(igraph_lapack_dsyevr(A, IGRAPH_LAPACK_DSYEV_ALL, /*vl=*/ 0, /*vu=*/ 0, /*vestimate=*/ 0, /*il=*/ 0, /*iu=*/ 0, /*abstol=*/ 1e-14, &val, vectors ? &vec : 0, /*support=*/ 0)); /* Look for smallest value */ small=fabs(VECTOR(val)[0]); for (i=1; i<n; i++) { igraph_real_t v=fabs(VECTOR(val)[i]); if (v < small) { small=v; w=i; } } p1=w-1; p2=w; if (values) { IGRAPH_CHECK(igraph_vector_resize(values, which->howmany)); } if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, which->howmany)); } while (pr < which->howmany) { if (p2 == n-1 || fabs(VECTOR(val)[p1]) < fabs(VECTOR(val)[p2])) { if (values) { VECTOR(*values)[pr]=VECTOR(val)[p1]; } if (vectors) { memcpy(&MATRIX(*vectors,0,pr), &MATRIX(vec,0,p1), sizeof(igraph_real_t) * (size_t) n); } p1--; pr++; } else { if (values) { VECTOR(*values)[pr]=VECTOR(val)[p2]; } if (vectors) { memcpy(&MATRIX(*vectors,0,pr), &MATRIX(vec,0,p2), sizeof(igraph_real_t) * (size_t) n); } p2++; pr++; } } if (vectors) { igraph_matrix_destroy(&vec); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&val); IGRAPH_FINALLY_CLEAN(1); return 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(°ree, no_of_nodes)); IGRAPH_FINALLY(&igraph_vector_long_destroy, °ree); IGRAPH_CHECK(igraph_vector_char_init(&added, no_of_edges)); IGRAPH_FINALLY(igraph_vector_char_destroy, &added); IGRAPH_CHECK(igraph_vector_long_init(&ntk, maxdegree+1)); IGRAPH_FINALLY(igraph_vector_long_destroy, &ntk); IGRAPH_MATRIX_INIT_FINALLY(&ntkk, maxdegree+1, maxdegree+1); IGRAPH_MATRIX_INIT_FINALLY(&ch, maxdegree+1, maxdegree+1); if (norm) { normfact=norm; IGRAPH_CHECK(igraph_matrix_resize(normfact, maxdegree+1, maxdegree+1)); igraph_matrix_null(normfact); } else { normfact=&v_normfact; IGRAPH_MATRIX_INIT_FINALLY(normfact, maxdegree+1, maxdegree+1); } if (cites) { notnull=cites; IGRAPH_CHECK(igraph_matrix_resize(notnull, maxdegree+1, maxdegree+1)); igraph_matrix_null(notnull); } else { notnull=&v_notnull; IGRAPH_MATRIX_INIT_FINALLY(notnull, maxdegree+1, maxdegree+1); } IGRAPH_CHECK(igraph_matrix_resize(kernel, maxdegree+1, maxdegree+1)); igraph_matrix_null(kernel); if (sd) { IGRAPH_CHECK(igraph_matrix_resize(sd, maxdegree+1, maxdegree+1)); igraph_matrix_null(sd); } for (timestep=0; timestep<no_of_events; timestep++) { IGRAPH_ALLOW_INTERRUPTION(); /* Add the vertices in the first */ nptr_save=nptr; while (nptr < no_of_nodes && VECTOR(*vtime)[(long int)VECTOR(*vtimeidx)[nptr]]==timestep) { nptr++; } VECTOR(ntk)[0] += (nptr-nptr_save); /* Update ch accordingly, could be done later as well */ if (VECTOR(ntk)[0] == nptr-nptr_save && nptr!=nptr_save) { if (nptr-nptr_save >= 2) { MATRIX(ch, 0, 0) = eptr; } for (i=1; i<maxdegree+1; i++) { if (NTKK(0,i) == (nptr-nptr_save)*VECTOR(ntk)[i]) { MATRIX(ch, 0, i) = MATRIX(ch, i, 0) = eptr; } } } /* Estimate Akk */ eptr_save=eptr; while (eptr < no_of_edges && VECTOR(*etime)[(long int)VECTOR(*etimeidx)[eptr] ] == timestep) { long int edge=(long int) VECTOR(*etimeidx)[eptr]; long int from=IGRAPH_FROM(graph, edge), to=IGRAPH_TO(graph, edge); long int xidx=VECTOR(degree)[from]; long int yidx=VECTOR(degree)[to]; double xk, oldakk; MATRIX(*notnull, xidx, yidx) += 1; MATRIX(*notnull, yidx, xidx) = MATRIX(*notnull, xidx, yidx); xk=VECTOR(*st)[timestep]/NTKK(xidx, yidx); oldakk=MATRIX(*kernel, xidx, yidx); MATRIX(*kernel, xidx, yidx) += (xk-oldakk)/MATRIX(*notnull, xidx, yidx); MATRIX(*kernel, yidx, xidx) = MATRIX(*kernel, xidx, yidx); if (sd) { MATRIX(*sd, xidx, yidx) += (xk-oldakk)*(xk-MATRIX(*kernel, xidx, yidx)); MATRIX(*sd, yidx, xidx) = MATRIX(*sd, xidx, yidx); } /* TODO: debug */ eptr++; } /* Update ntkk, ntk, ch, normfact, add the edges */ eptr_new=eptr; eptr=eptr_save; while (eptr < no_of_edges && VECTOR(*etime)[(long int) VECTOR(*etimeidx)[eptr] ] == timestep) { long int edge=(long int) VECTOR(*etimeidx)[eptr]; long int from=IGRAPH_FROM(graph, edge); long int to=IGRAPH_TO(graph, edge); long int xidx=VECTOR(degree)[from]; long int yidx=VECTOR(degree)[to]; long int n; adjedges=igraph_lazy_inclist_get(inclist, (igraph_integer_t) from); n=igraph_vector_size(adjedges); for (i=0; i<n; i++) { long int edge=(long int) VECTOR(*adjedges)[i]; if (VECTOR(added)[edge]) { long int otherv=IGRAPH_OTHER(graph, edge, from); /* other than from */ long int deg=VECTOR(degree)[otherv]; MATRIX(ntkk, xidx, deg) -= 1; MATRIX(ntkk, deg, xidx) = MATRIX(ntkk, xidx, deg); if (NTKK(xidx, deg)==1) { MATRIX(ch, deg, xidx) = eptr_new; MATRIX(ch, xidx, deg) = MATRIX(ch, deg, xidx); } MATRIX(ntkk, xidx+1, deg) += 1; MATRIX(ntkk, deg, xidx+1) = MATRIX(ntkk, xidx+1, deg); if (NTKK(xidx+1, deg)==0) { MATRIX(*normfact, xidx+1, deg) += eptr_new-MATRIX(ch, xidx+1, deg); MATRIX(*normfact, deg, xidx+1) = MATRIX(*normfact, xidx+1, deg); } } } adjedges=igraph_lazy_inclist_get(inclist, (igraph_integer_t) to); n=igraph_vector_size(adjedges); for (i=0; i<n; i++) { long int edge=(long int) VECTOR(*adjedges)[i]; if (VECTOR(added)[edge]) { long int otherv=IGRAPH_OTHER(graph, edge, to); /* other than to */ long int deg=VECTOR(degree)[otherv]; MATRIX(ntkk, yidx, deg) -= 1; MATRIX(ntkk, deg, yidx) = MATRIX(ntkk, yidx, deg); if (NTKK(yidx, deg)==1) { MATRIX(ch, deg, yidx) = eptr_new; MATRIX(ch, yidx, deg) = MATRIX(ch, deg, yidx); } MATRIX(ntkk, yidx+1, deg) += 1; MATRIX(ntkk, deg, yidx+1) = MATRIX(ntkk, yidx+1, deg); if (NTKK(yidx+1, deg)==0) { MATRIX(*normfact, yidx+1, deg) += eptr_new-MATRIX(ch, yidx+1, deg); MATRIX(*normfact, deg, yidx+1) = MATRIX(*normfact, yidx+1, deg); } } } VECTOR(added)[edge]=1; MATRIX(ntkk, xidx+1, yidx+1) += 1; MATRIX(ntkk, yidx+1, xidx+1) = MATRIX(ntkk, xidx+1, yidx+1); if (NTKK(xidx+1, yidx+1)==0) { MATRIX(*normfact, xidx+1, yidx+1) = eptr_new-MATRIX(ch, xidx+1, yidx+1); MATRIX(*normfact, yidx+1, xidx+1) = MATRIX(*normfact, xidx+1, yidx+1); } for (i=0; i<maxdegree+1; i++) { long int before, after; before=(long int) NTKK(xidx,i); VECTOR(ntk)[xidx] -= 1; after=(long int) NTKK(xidx,i); VECTOR(ntk)[xidx] += 1; if (before > 0 && after==0) { MATRIX(*normfact, xidx, i) += eptr_new-MATRIX(ch, xidx, i); MATRIX(*normfact, i, xidx) = MATRIX(*normfact, xidx, i); } } VECTOR(ntk)[xidx]--; for (i=0; i<maxdegree+1; i++) { long int before, after; before=(long int) NTKK(yidx, i); VECTOR(ntk)[yidx] -= 1; after=(long int) NTKK(yidx, i); VECTOR(ntk)[yidx] += 1; if (before > 0 && after==0) { MATRIX(*normfact, yidx, i) += eptr_new-MATRIX(ch, yidx, i); MATRIX(*normfact, i, yidx) = MATRIX(*normfact, yidx, i); } } VECTOR(ntk)[yidx]--; for (i=0; i<maxdegree+1; i++) { long int before, after; before=(long int) NTKK(xidx+1, i); VECTOR(ntk)[xidx+1] += 1; after=(long int) NTKK(xidx+1, i); VECTOR(ntk)[xidx+1] -= 1; if (before==0 && after > 0) { MATRIX(ch, xidx+1, i) = eptr_new; MATRIX(ch, i, xidx+1) = MATRIX(ch, xidx+1, i); } } VECTOR(ntk)[xidx+1]++; for (i=0; i<maxdegree+1; i++) { long int before, after; before=(long int) NTKK(yidx+1, i); VECTOR(ntk)[yidx+1] += 1; after=(long int) NTKK(yidx+1, i); VECTOR(ntk)[yidx+1] -= 1; if (before == 0 && after == 0) { MATRIX(ch, yidx+1, i) = eptr_new; MATRIX(ch, i, yidx+1) = MATRIX(ch, yidx+1, i); } } VECTOR(ntk)[yidx+1]++; VECTOR(degree)[from]++; VECTOR(degree)[to]++; eptr++; } } for (i=0; i<maxdegree+1; i++) { igraph_real_t oldakk; long int j; for (j=0; j<=i; j++) { if (NTKK(i, j) != 0) { MATRIX(*normfact, i, j) += (eptr-MATRIX(ch, i, j)); MATRIX(*normfact, j, i) = MATRIX(*normfact, i, j); } if (MATRIX(*normfact, i, j)==0) { MATRIX(*kernel, i, j)=MATRIX(*kernel, j, i)=0; MATRIX(*normfact, i, j)=MATRIX(*normfact, j, i)=1; } oldakk=MATRIX(*kernel, i, j); MATRIX(*kernel, i, j) *= MATRIX(*notnull, i, j)/MATRIX(*normfact, i, j); MATRIX(*kernel, j, i) = MATRIX(*kernel, i, j); if (sd) { MATRIX(*sd, i, j) += oldakk * oldakk * MATRIX(*notnull, i, j) * (1-MATRIX(*notnull, i, j)/MATRIX(*normfact, i, j)); MATRIX(*sd, i, j) = sqrt(MATRIX(*sd, i, j)/(MATRIX(*normfact, i, j)-1)); MATRIX(*sd, j, i) = MATRIX(*sd, i, j); } } } if (!cites) { igraph_matrix_destroy(notnull); IGRAPH_FINALLY_CLEAN(1); } if (!norm) { igraph_matrix_destroy(normfact); IGRAPH_FINALLY_CLEAN(1); } igraph_matrix_destroy(&ch); igraph_matrix_destroy(&ntkk); igraph_vector_long_destroy(&ntk); igraph_vector_char_destroy(&added); igraph_vector_long_destroy(°ree); IGRAPH_FINALLY_CLEAN(5); return 0; }
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; }
int igraph_layout_kamada_kawai(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_real_t epsilon, igraph_real_t kkconst, const igraph_vector_t *weights, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy) { igraph_integer_t no_nodes=igraph_vcount(graph); igraph_integer_t no_edges=igraph_ecount(graph); igraph_real_t L, L0=sqrt(no_nodes); igraph_matrix_t dij, lij, kij; igraph_real_t max_dij; igraph_vector_t D1, D2; igraph_integer_t i, j, m; if (maxiter < 0) { IGRAPH_ERROR("Number of iterations must be non-negatice in " "Kamada-Kawai layout", IGRAPH_EINVAL); } if (kkconst <= 0) { IGRAPH_ERROR("`K' constant must be positive in Kamada-Kawai layout", IGRAPH_EINVAL); } if (use_seed && (igraph_matrix_nrow(res) != no_nodes || igraph_matrix_ncol(res) != 2)) { IGRAPH_ERROR("Invalid start position matrix size in " "Kamada-Kawai layout", IGRAPH_EINVAL); } if (weights && igraph_vector_size(weights) != no_edges) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } if (minx && igraph_vector_size(minx) != no_nodes) { IGRAPH_ERROR("Invalid minx vector length", IGRAPH_EINVAL); } if (maxx && igraph_vector_size(maxx) != no_nodes) { IGRAPH_ERROR("Invalid maxx vector length", IGRAPH_EINVAL); } if (minx && maxx && !igraph_vector_all_le(minx, maxx)) { IGRAPH_ERROR("minx must not be greater than maxx", IGRAPH_EINVAL); } if (miny && igraph_vector_size(miny) != no_nodes) { IGRAPH_ERROR("Invalid miny vector length", IGRAPH_EINVAL); } if (maxy && igraph_vector_size(maxy) != no_nodes) { IGRAPH_ERROR("Invalid maxy vector length", IGRAPH_EINVAL); } if (miny && maxy && !igraph_vector_all_le(miny, maxy)) { IGRAPH_ERROR("miny must not be greater than maxy", IGRAPH_EINVAL); } if (!use_seed) { if (minx || maxx || miny || maxy) { const igraph_real_t width=sqrt(no_nodes), height=width; IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 2)); RNG_BEGIN(); for (i=0; i<no_nodes; i++) { igraph_real_t x1=minx ? VECTOR(*minx)[i] : -width/2; igraph_real_t x2=maxx ? VECTOR(*maxx)[i] : width/2; igraph_real_t y1=miny ? VECTOR(*miny)[i] : -height/2; igraph_real_t y2=maxy ? VECTOR(*maxy)[i] : height/2; if (!igraph_finite(x1)) { x1 = -width/2; } if (!igraph_finite(x2)) { x2 = width/2; } if (!igraph_finite(y1)) { y1 = -height/2; } if (!igraph_finite(y2)) { y2 = height/2; } MATRIX(*res, i, 0) = RNG_UNIF(x1, x2); MATRIX(*res, i, 1) = RNG_UNIF(y1, y2); } RNG_END(); } else { igraph_layout_circle(graph, res, /* order= */ igraph_vss_all()); } } if (no_nodes <= 1) { return 0; } IGRAPH_MATRIX_INIT_FINALLY(&dij, no_nodes, no_nodes); IGRAPH_MATRIX_INIT_FINALLY(&kij, no_nodes, no_nodes); IGRAPH_MATRIX_INIT_FINALLY(&lij, no_nodes, no_nodes); IGRAPH_CHECK(igraph_shortest_paths_dijkstra(graph, &dij, igraph_vss_all(), igraph_vss_all(), weights, IGRAPH_ALL)); max_dij = 0.0; for (i=0; i<no_nodes; i++) { for (j=i+1; j<no_nodes; j++) { if (!igraph_finite(MATRIX(dij, i, j))) { continue; } if (MATRIX(dij, i, j) > max_dij) { max_dij = MATRIX(dij, i, j); } } } for (i=0; i<no_nodes; i++) { for (j=0; j<no_nodes; j++) { if (MATRIX(dij, i, j) > max_dij) { MATRIX(dij, i, j) = max_dij; } } } L = L0 / max_dij; for (i=0; i<no_nodes; i++) { for (j=0; j<no_nodes; j++) { igraph_real_t tmp=MATRIX(dij, i, j) * MATRIX(dij, i, j); if (i==j) { continue; } MATRIX(kij, i, j) = kkconst / tmp; MATRIX(lij, i, j) = L * MATRIX(dij, i, j); } } /* Initialize delta */ IGRAPH_VECTOR_INIT_FINALLY(&D1, no_nodes); IGRAPH_VECTOR_INIT_FINALLY(&D2, no_nodes); for (m=0; m<no_nodes; m++) { igraph_real_t myD1=0.0, myD2=0.0; for (i=0; i<no_nodes; i++) { if (i==m) { continue; } igraph_real_t dx=MATRIX(*res, m, 0) - MATRIX(*res, i, 0); igraph_real_t dy=MATRIX(*res, m, 1) - MATRIX(*res, i, 1); igraph_real_t mi_dist=sqrt(dx * dx + dy * dy); myD1 += MATRIX(kij, m, i) * (dx - MATRIX(lij, m, i) * dx / mi_dist); myD2 += MATRIX(kij, m, i) * (dy - MATRIX(lij, m, i) * dy / mi_dist); } VECTOR(D1)[m] = myD1; VECTOR(D2)[m] = myD2; } for (j=0; j<maxiter; j++) { igraph_real_t myD1=0.0, myD2=0.0, A=0.0, B=0.0, C=0.0; igraph_real_t max_delta, delta_x, delta_y; igraph_real_t old_x, old_y, new_x, new_y; /* Select maximal delta */ m=0; max_delta=-1; for (i=0; i<no_nodes; i++) { igraph_real_t delta=(VECTOR(D1)[i] * VECTOR(D1)[i] + VECTOR(D2)[i] * VECTOR(D2)[i]); if (delta > max_delta) { m=i; max_delta=delta; } } if (max_delta < epsilon) { break; } old_x=MATRIX(*res, m, 0); old_y=MATRIX(*res, m, 1); /* Calculate D1 and D2, A, B, C */ for (i=0; i<no_nodes; i++) { if (i==m) { continue; } igraph_real_t dx=old_x - MATRIX(*res, i, 0); igraph_real_t dy=old_y - MATRIX(*res, i, 1); igraph_real_t dist=sqrt(dx * dx + dy * dy); igraph_real_t den=dist * (dx * dx + dy * dy); A += MATRIX(kij, m, i) * (1 - MATRIX(lij, m, i) * dy * dy / den); B += MATRIX(kij, m, i) * MATRIX(lij, m, i) * dx * dy / den; C += MATRIX(kij, m, i) * (1 - MATRIX(lij, m, i) * dx * dx / den); } myD1 = VECTOR(D1)[m]; myD2 = VECTOR(D2)[m]; /* Need to solve some linear equations */ delta_y = (B * myD1 - myD2 * A) / (C * A - B * B); delta_x = - (myD1 + B * delta_y) / A; new_x = old_x + delta_x; new_y = old_y + delta_y; /* Limits, if given */ if (minx && new_x < VECTOR(*minx)[m]) { new_x = VECTOR(*minx)[m]; } if (maxx && new_x > VECTOR(*maxx)[m]) { new_x = VECTOR(*maxx)[m]; } if (miny && new_y < VECTOR(*miny)[m]) { new_y = VECTOR(*miny)[m]; } if (maxy && new_y > VECTOR(*maxy)[m]) { new_y = VECTOR(*maxy)[m]; } /* Update delta, only with/for the affected node */ VECTOR(D1)[m] = VECTOR(D2)[m] = 0.0; for (i=0; i<no_nodes; i++) { if (i==m) { continue; } igraph_real_t old_dx=old_x - MATRIX(*res, i, 0); igraph_real_t old_dy=old_y - MATRIX(*res, i, 1); igraph_real_t old_mi_dist=sqrt(old_dx * old_dx + old_dy * old_dy); igraph_real_t new_dx=new_x - MATRIX(*res, i, 0); igraph_real_t new_dy=new_y - MATRIX(*res, i, 1); igraph_real_t new_mi_dist=sqrt(new_dx * new_dx + new_dy * new_dy); VECTOR(D1)[i] -= MATRIX(kij, m, i) * (-old_dx + MATRIX(lij, m, i) * old_dx / old_mi_dist); VECTOR(D2)[i] -= MATRIX(kij, m, i) * (-old_dy + MATRIX(lij, m, i) * old_dy / old_mi_dist); VECTOR(D1)[i] += MATRIX(kij, m, i) * (-new_dx + MATRIX(lij, m, i) * new_dx / new_mi_dist); VECTOR(D2)[i] += MATRIX(kij, m, i) * (-new_dy + MATRIX(lij, m, i) * new_dy / new_mi_dist); VECTOR(D1)[m] += MATRIX(kij, m, i) * (new_dx - MATRIX(lij, m, i) * new_dx / new_mi_dist); VECTOR(D2)[m] += MATRIX(kij, m, i) * (new_dy - MATRIX(lij, m, i) * new_dy / new_mi_dist); } /* Update coordinates*/ MATRIX(*res, m, 0) = new_x; MATRIX(*res, m, 1) = new_y; } igraph_vector_destroy(&D2); igraph_vector_destroy(&D1); igraph_matrix_destroy(&lij); igraph_matrix_destroy(&kij); igraph_matrix_destroy(&dij); IGRAPH_FINALLY_CLEAN(5); return 0; }
int igraph_layout_kamada_kawai_3d(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_real_t epsilon, igraph_real_t kkconst, const igraph_vector_t *weights, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy, const igraph_vector_t *minz, const igraph_vector_t *maxz) { igraph_integer_t no_nodes=igraph_vcount(graph); igraph_integer_t no_edges=igraph_ecount(graph); igraph_real_t L, L0=sqrt(no_nodes); igraph_matrix_t dij, lij, kij; igraph_real_t max_dij; igraph_vector_t D1, D2, D3; igraph_integer_t i, j, m; if (maxiter < 0) { IGRAPH_ERROR("Number of iterations must be non-negatice in " "Kamada-Kawai layout", IGRAPH_EINVAL); } if (kkconst <= 0) { IGRAPH_ERROR("`K' constant must be positive in Kamada-Kawai layout", IGRAPH_EINVAL); } if (use_seed && (igraph_matrix_nrow(res) != no_nodes || igraph_matrix_ncol(res) != 3)) { IGRAPH_ERROR("Invalid start position matrix size in " "3d Kamada-Kawai layout", IGRAPH_EINVAL); } if (weights && igraph_vector_size(weights) != no_edges) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } if (minx && igraph_vector_size(minx) != no_nodes) { IGRAPH_ERROR("Invalid minx vector length", IGRAPH_EINVAL); } if (maxx && igraph_vector_size(maxx) != no_nodes) { IGRAPH_ERROR("Invalid maxx vector length", IGRAPH_EINVAL); } if (minx && maxx && !igraph_vector_all_le(minx, maxx)) { IGRAPH_ERROR("minx must not be greater than maxx", IGRAPH_EINVAL); } if (miny && igraph_vector_size(miny) != no_nodes) { IGRAPH_ERROR("Invalid miny vector length", IGRAPH_EINVAL); } if (maxy && igraph_vector_size(maxy) != no_nodes) { IGRAPH_ERROR("Invalid maxy vector length", IGRAPH_EINVAL); } if (miny && maxy && !igraph_vector_all_le(miny, maxy)) { IGRAPH_ERROR("miny must not be greater than maxy", IGRAPH_EINVAL); } if (minz && igraph_vector_size(minz) != no_nodes) { IGRAPH_ERROR("Invalid minz vector length", IGRAPH_EINVAL); } if (maxz && igraph_vector_size(maxz) != no_nodes) { IGRAPH_ERROR("Invalid maxz vector length", IGRAPH_EINVAL); } if (minz && maxz && !igraph_vector_all_le(minz, maxz)) { IGRAPH_ERROR("minz must not be greater than maxz", IGRAPH_EINVAL); } if (!use_seed) { if (minx || maxx || miny || maxy || minz || maxz) { const igraph_real_t width=sqrt(no_nodes), height=width, depth=width; IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 3)); RNG_BEGIN(); for (i=0; i<no_nodes; i++) { igraph_real_t x1=minx ? VECTOR(*minx)[i] : -width/2; igraph_real_t x2=maxx ? VECTOR(*maxx)[i] : width/2; igraph_real_t y1=miny ? VECTOR(*miny)[i] : -height/2; igraph_real_t y2=maxy ? VECTOR(*maxy)[i] : height/2; igraph_real_t z1=minz ? VECTOR(*minz)[i] : -depth/2; igraph_real_t z2=maxz ? VECTOR(*maxz)[i] : depth/2; if (!igraph_finite(x1)) { x1 = -width/2; } if (!igraph_finite(x2)) { x2 = width/2; } if (!igraph_finite(y1)) { y1 = -height/2; } if (!igraph_finite(y2)) { y2 = height/2; } if (!igraph_finite(z1)) { z1 = -depth/2; } if (!igraph_finite(z2)) { z2 = depth/2; } MATRIX(*res, i, 0) = RNG_UNIF(x1, x2); MATRIX(*res, i, 1) = RNG_UNIF(y1, y2); MATRIX(*res, i, 2) = RNG_UNIF(z1, z2); } RNG_END(); } else { igraph_layout_sphere(graph, res); } } if (no_nodes <= 1) { return 0; } IGRAPH_MATRIX_INIT_FINALLY(&dij, no_nodes, no_nodes); IGRAPH_MATRIX_INIT_FINALLY(&kij, no_nodes, no_nodes); IGRAPH_MATRIX_INIT_FINALLY(&lij, no_nodes, no_nodes); IGRAPH_CHECK(igraph_shortest_paths_dijkstra(graph, &dij, igraph_vss_all(), igraph_vss_all(), weights, IGRAPH_ALL)); max_dij = 0.0; for (i=0; i<no_nodes; i++) { for (j=i+1; j<no_nodes; j++) { if (!igraph_finite(MATRIX(dij, i, j))) { continue; } if (MATRIX(dij, i, j) > max_dij) { max_dij = MATRIX(dij, i, j); } } } for (i=0; i<no_nodes; i++) { for (j=0; j<no_nodes; j++) { if (MATRIX(dij, i, j) > max_dij) { MATRIX(dij, i, j) = max_dij; } } } L = L0 / max_dij; for (i=0; i<no_nodes; i++) { for (j=0; j<no_nodes; j++) { igraph_real_t tmp=MATRIX(dij, i, j) * MATRIX(dij, i, j); if (i==j) { continue; } MATRIX(kij, i, j) = kkconst / tmp; MATRIX(lij, i, j) = L * MATRIX(dij, i, j); } } /* Initialize delta */ IGRAPH_VECTOR_INIT_FINALLY(&D1, no_nodes); IGRAPH_VECTOR_INIT_FINALLY(&D2, no_nodes); IGRAPH_VECTOR_INIT_FINALLY(&D3, no_nodes); for (m=0; m<no_nodes; m++) { igraph_real_t myD1=0.0, myD2=0.0, myD3=0.0; for (i=0; i<no_nodes; i++) { if (i==m) { continue; } igraph_real_t dx=MATRIX(*res, m, 0) - MATRIX(*res, i, 0); igraph_real_t dy=MATRIX(*res, m, 1) - MATRIX(*res, i, 1); igraph_real_t dz=MATRIX(*res, m, 2) - MATRIX(*res, i, 2); igraph_real_t mi_dist=sqrt(dx * dx + dy * dy + dz * dz); myD1 += MATRIX(kij, m, i) * (dx - MATRIX(lij, m, i) * dx / mi_dist); myD2 += MATRIX(kij, m, i) * (dy - MATRIX(lij, m, i) * dy / mi_dist); myD3 += MATRIX(kij, m, i) * (dz - MATRIX(lij, m, i) * dz / mi_dist); } VECTOR(D1)[m] = myD1; VECTOR(D2)[m] = myD2; VECTOR(D3)[m] = myD3; } for (j=0; j<maxiter; j++) { igraph_real_t Ax=0.0, Ay=0.0, Az=0.0; igraph_real_t Axx=0.0, Axy=0.0, Axz=0.0, Ayy=0.0, Ayz=0.0, Azz=0.0; igraph_real_t max_delta, delta_x, delta_y, delta_z; igraph_real_t old_x, old_y, old_z, new_x, new_y, new_z; igraph_real_t detnum; /* Select maximal delta */ m=0; max_delta=-1; for (i=0; i<no_nodes; i++) { igraph_real_t delta=(VECTOR(D1)[i] * VECTOR(D1)[i] + VECTOR(D2)[i] * VECTOR(D2)[i] + VECTOR(D3)[i] * VECTOR(D3)[i]); if (delta > max_delta) { m=i; max_delta=delta; } } if (max_delta < epsilon) { break; } old_x=MATRIX(*res, m, 0); old_y=MATRIX(*res, m, 1); old_z=MATRIX(*res, m, 2); /* Calculate D1, D2 and D3, and other coefficients */ for (i=0; i<no_nodes; i++) { if (i==m) { continue; } igraph_real_t dx=old_x - MATRIX(*res, i, 0); igraph_real_t dy=old_y - MATRIX(*res, i, 1); igraph_real_t dz=old_z - MATRIX(*res, i, 2); igraph_real_t dist=sqrt(dx * dx + dy * dy + dz *dz); igraph_real_t den=dist * (dx * dx + dy * dy + dz * dz); igraph_real_t k_mi=MATRIX(kij, m, i); igraph_real_t l_mi=MATRIX(lij, m, i); Axx += k_mi * (1 - l_mi * (dy*dy + dz*dz) / den); Ayy += k_mi * (1 - l_mi * (dx*dx + dz*dz) / den); Azz += k_mi * (1 - l_mi * (dx*dx + dy*dy) / den); Axy += k_mi * l_mi * dx * dy / den; Axz += k_mi * l_mi * dx * dz / den; Ayz += k_mi * l_mi * dy * dz / den; } Ax = -VECTOR(D1)[m]; Ay = -VECTOR(D2)[m]; Az = -VECTOR(D3)[m]; /* Need to solve some linear equations, we just use Cramer's rule */ #define DET(a,b,c,d,e,f,g,h,i) ((a*e*i+b*f*g+c*d*h)-(c*e*g+b*d*i+a*f*h)) detnum = DET(Axx,Axy,Axz, Axy,Ayy,Ayz, Axz,Ayz,Azz); delta_x = DET(Ax ,Ay ,Az , Axy,Ayy,Ayz, Axz,Ayz,Azz) / detnum; delta_y = DET(Axx,Axy,Axz, Ax ,Ay ,Az , Axz,Ayz,Azz) / detnum; delta_z = DET(Axx,Axy,Axz, Axy,Ayy,Ayz, Ax ,Ay ,Az ) / detnum; new_x = old_x + delta_x; new_y = old_y + delta_y; new_z = old_z + delta_z; /* Limits, if given */ if (minx && new_x < VECTOR(*minx)[m]) { new_x = VECTOR(*minx)[m]; } if (maxx && new_x > VECTOR(*maxx)[m]) { new_x = VECTOR(*maxx)[m]; } if (miny && new_y < VECTOR(*miny)[m]) { new_y = VECTOR(*miny)[m]; } if (maxy && new_y > VECTOR(*maxy)[m]) { new_y = VECTOR(*maxy)[m]; } if (minz && new_z < VECTOR(*minz)[m]) { new_z = VECTOR(*minz)[m]; } if (maxz && new_z > VECTOR(*maxz)[m]) { new_z = VECTOR(*maxz)[m]; } /* Update delta, only with/for the affected node */ VECTOR(D1)[m] = VECTOR(D2)[m] = VECTOR(D3)[m] = 0.0; for (i=0; i<no_nodes; i++) { if (i==m) { continue; } igraph_real_t old_dx=old_x - MATRIX(*res, i, 0); igraph_real_t old_dy=old_y - MATRIX(*res, i, 1); igraph_real_t old_dz=old_z - MATRIX(*res, i, 2); igraph_real_t old_mi_dist=sqrt(old_dx * old_dx + old_dy * old_dy + old_dz * old_dz); igraph_real_t new_dx=new_x - MATRIX(*res, i, 0); igraph_real_t new_dy=new_y - MATRIX(*res, i, 1); igraph_real_t new_dz=new_z - MATRIX(*res, i, 2); igraph_real_t new_mi_dist=sqrt(new_dx * new_dx + new_dy * new_dy + new_dz * new_dz); VECTOR(D1)[i] -= MATRIX(kij, m, i) * (-old_dx + MATRIX(lij, m, i) * old_dx / old_mi_dist); VECTOR(D2)[i] -= MATRIX(kij, m, i) * (-old_dy + MATRIX(lij, m, i) * old_dy / old_mi_dist); VECTOR(D3)[i] -= MATRIX(kij, m, i) * (-old_dz + MATRIX(lij, m, i) * old_dz / old_mi_dist); VECTOR(D1)[i] += MATRIX(kij, m, i) * (-new_dx + MATRIX(lij, m, i) * new_dx / new_mi_dist); VECTOR(D2)[i] += MATRIX(kij, m, i) * (-new_dy + MATRIX(lij, m, i) * new_dy / new_mi_dist); VECTOR(D3)[i] += MATRIX(kij, m, i) * (-new_dz + MATRIX(lij, m, i) * new_dz / new_mi_dist); VECTOR(D1)[m] += MATRIX(kij, m, i) * (new_dx - MATRIX(lij, m, i) * new_dx / new_mi_dist); VECTOR(D2)[m] += MATRIX(kij, m, i) * (new_dy - MATRIX(lij, m, i) * new_dy / new_mi_dist); VECTOR(D3)[m] += MATRIX(kij, m, i) * (new_dz - MATRIX(lij, m, i) * new_dz / new_mi_dist); } /* Update coordinates*/ MATRIX(*res, m, 0) = new_x; MATRIX(*res, m, 1) = new_y; MATRIX(*res, m, 2) = new_z; } igraph_vector_destroy(&D3); igraph_vector_destroy(&D2); igraph_vector_destroy(&D1); igraph_matrix_destroy(&lij); igraph_matrix_destroy(&kij); igraph_matrix_destroy(&dij); IGRAPH_FINALLY_CLEAN(6); return 0; }
int igraph_pagerank(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t damping, const igraph_vector_t *weights, igraph_arpack_options_t *options) { igraph_matrix_t values; igraph_matrix_t vectors; igraph_integer_t dirmode; igraph_vector_t outdegree; igraph_vector_t tmp; long int i; long int no_of_nodes=igraph_vcount(graph); long int no_of_edges=igraph_ecount(graph); options->n = igraph_vcount(graph); options->nev = 1; options->ncv = 3; options->which[0]='L'; options->which[1]='M'; options->start=1; /* no random start vector */ directed = directed && igraph_is_directed(graph); if (weights && igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid length of weights vector when calculating " "PageRank scores", IGRAPH_EINVAL); } IGRAPH_MATRIX_INIT_FINALLY(&values, 0, 0); IGRAPH_MATRIX_INIT_FINALLY(&vectors, options->n, 1); if (directed) { dirmode=IGRAPH_IN; } else { dirmode=IGRAPH_ALL; } IGRAPH_VECTOR_INIT_FINALLY(&outdegree, options->n); IGRAPH_VECTOR_INIT_FINALLY(&tmp, options->n); RNG_BEGIN(); if (!weights) { igraph_adjlist_t adjlist; igraph_i_pagerank_data_t data = { graph, &adjlist, damping, &outdegree, &tmp }; IGRAPH_CHECK(igraph_degree(graph, &outdegree, igraph_vss_all(), directed ? IGRAPH_OUT : IGRAPH_ALL, /*loops=*/ 0)); /* Avoid division by zero */ for (i=0; i<options->n; i++) { if (VECTOR(outdegree)[i]==0) { VECTOR(outdegree)[i]=1; } MATRIX(vectors, i, 0) = VECTOR(outdegree)[i]; } IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, dirmode)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_arpack_rnsolve(igraph_i_pagerank, &data, options, 0, &values, &vectors)); igraph_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(1); } else { igraph_adjedgelist_t adjedgelist; igraph_i_pagerank_data2_t data = { graph, &adjedgelist, weights, damping, &outdegree, &tmp }; IGRAPH_CHECK(igraph_adjedgelist_init(graph, &adjedgelist, dirmode)); IGRAPH_FINALLY(igraph_adjedgelist_destroy, &adjedgelist); /* Weighted degree */ for (i=0; i<no_of_edges; i++) { long int from=IGRAPH_FROM(graph, i); long int to=IGRAPH_TO(graph, i); igraph_real_t weight=VECTOR(*weights)[i]; VECTOR(outdegree)[from] += weight; if (!directed) { VECTOR(outdegree)[to] += weight; } } /* Avoid division by zero */ for (i=0; i<options->n; i++) { if (VECTOR(outdegree)[i]==0) { VECTOR(outdegree)[i]=1; } MATRIX(vectors, i, 0) = VECTOR(outdegree)[i]; } IGRAPH_CHECK(igraph_arpack_rnsolve(igraph_i_pagerank2, &data, options, 0, &values, &vectors)); igraph_adjedgelist_destroy(&adjedgelist); IGRAPH_FINALLY_CLEAN(1); } RNG_END(); igraph_vector_destroy(&tmp); igraph_vector_destroy(&outdegree); IGRAPH_FINALLY_CLEAN(2); if (value) { *value=MATRIX(values, 0, 0); } if (vector) { long int i; igraph_vit_t vit; long int nodes_to_calc; igraph_real_t sum=0; for (i=0; i<no_of_nodes; i++) { sum += MATRIX(vectors, i, 0); } IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); nodes_to_calc=IGRAPH_VIT_SIZE(vit); IGRAPH_CHECK(igraph_vector_resize(vector, nodes_to_calc)); for (IGRAPH_VIT_RESET(vit), i=0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { VECTOR(*vector)[i] = MATRIX(vectors, (long int)IGRAPH_VIT_GET(vit), 0); VECTOR(*vector)[i] /= sum; } igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); } if (options->info) { IGRAPH_WARNING("Non-zero return code from ARPACK routine!"); } igraph_matrix_destroy(&vectors); igraph_matrix_destroy(&values); IGRAPH_FINALLY_CLEAN(2); return 0; }
int igraph_i_kleinberg(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, igraph_bool_t scale, igraph_arpack_options_t *options, int inout) { igraph_adjlist_t myinadjlist, myoutadjlist; igraph_adjlist_t *inadjlist, *outadjlist; igraph_vector_t tmp; igraph_vector_t values; igraph_matrix_t vectors; igraph_i_kleinberg_data_t extra; long int i; options->n=igraph_vcount(graph); options->start=1; IGRAPH_VECTOR_INIT_FINALLY(&values, 0); IGRAPH_MATRIX_INIT_FINALLY(&vectors, options->n, 1); IGRAPH_VECTOR_INIT_FINALLY(&tmp, options->n); if (inout==0) { inadjlist=&myinadjlist; outadjlist=&myoutadjlist; } else if (inout==1) { inadjlist=&myoutadjlist; outadjlist=&myinadjlist; } else { /* This should not happen */ IGRAPH_ERROR("Invalid 'inout' argument, plese do not call " "this funtion directly", IGRAPH_FAILURE); } IGRAPH_CHECK(igraph_adjlist_init(graph, &myinadjlist, IGRAPH_IN)); IGRAPH_FINALLY(igraph_adjlist_destroy, &myinadjlist); IGRAPH_CHECK(igraph_adjlist_init(graph, &myoutadjlist, IGRAPH_OUT)); IGRAPH_FINALLY(igraph_adjlist_destroy, &myoutadjlist); IGRAPH_CHECK(igraph_degree(graph, &tmp, igraph_vss_all(), IGRAPH_ALL, 0)); for (i=0; i<options->n; i++) { if (VECTOR(tmp)[i] != 0) { MATRIX(vectors, i, 0) = VECTOR(tmp)[i]; } else { MATRIX(vectors, i, 0) = 1.0; } } extra.in=inadjlist; extra.out=outadjlist; extra.tmp=&tmp; options->n = igraph_vcount(graph); options->nev = 1; options->ncv = 3; options->which[0]='L'; options->which[1]='M'; options->start=1; /* no random start vector */ IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_kleinberg2, &extra, options, 0, &values, &vectors)); igraph_adjlist_destroy(&myoutadjlist); igraph_adjlist_destroy(&myinadjlist); igraph_vector_destroy(&tmp); IGRAPH_FINALLY_CLEAN(3); if (value) { *value = VECTOR(values)[0]; } if (vector) { igraph_real_t amax=0; long int which=0; long int i; IGRAPH_CHECK(igraph_vector_resize(vector, options->n)); for (i=0; i<options->n; i++) { igraph_real_t tmp; VECTOR(*vector)[i] = MATRIX(vectors, i, 0); tmp=fabs(VECTOR(*vector)[i]); if (tmp>amax) { amax=tmp; which=i; } } if (scale && amax!=0) { igraph_vector_scale(vector, 1/VECTOR(*vector)[which]); } } if (options->info) { IGRAPH_WARNING("Non-zero return code from ARPACK routine!"); } igraph_matrix_destroy(&vectors); igraph_vector_destroy(&values); IGRAPH_FINALLY_CLEAN(2); return 0; }
int igraph_eigenvector_centrality(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, igraph_bool_t scale, const igraph_vector_t *weights, igraph_arpack_options_t *options) { igraph_vector_t values; igraph_matrix_t vectors; igraph_vector_t degree; long int i; options->n=igraph_vcount(graph); options->start=1; /* no random start vector */ if (weights && igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid length of weights vector when calculating " "eigenvector centrality", IGRAPH_EINVAL); } if (weights && igraph_is_directed(graph)) { IGRAPH_WARNING("Weighted directed graph in eigenvector centrality"); } IGRAPH_VECTOR_INIT_FINALLY(&values, 0); IGRAPH_MATRIX_INIT_FINALLY(&vectors, options->n, 1); IGRAPH_VECTOR_INIT_FINALLY(°ree, options->n); IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_ALL, /*loops=*/ 0)); for (i=0; i<options->n; i++) { if (VECTOR(degree)[i]) { MATRIX(vectors, i, 0) = VECTOR(degree)[i]; } else { MATRIX(vectors, i, 0) = 1.0; } } igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(1); options->n = igraph_vcount(graph); options->nev = 1; options->ncv = 3; options->which[0]='L'; options->which[1]='A'; options->start=1; /* no random start vector */ if (!weights) { igraph_adjlist_t adjlist; IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_eigenvector_centrality, &adjlist, options, 0, &values, &vectors)); igraph_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(1); } else { igraph_adjedgelist_t adjedgelist; igraph_i_eigenvector_centrality_t data = { graph, &adjedgelist, weights }; IGRAPH_CHECK(igraph_adjedgelist_init(graph, &adjedgelist, IGRAPH_ALL)); IGRAPH_FINALLY(igraph_adjedgelist_destroy, &adjedgelist); IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_eigenvector_centrality2, &data, options, 0, &values, &vectors)); igraph_adjedgelist_destroy(&adjedgelist); IGRAPH_FINALLY_CLEAN(1); } if (value) { *value=VECTOR(values)[0]; } if (vector) { igraph_real_t amax=0; long int which=0; long int i; IGRAPH_CHECK(igraph_vector_resize(vector, options->n)); for (i=0; i<options->n; i++) { igraph_real_t tmp; VECTOR(*vector)[i] = MATRIX(vectors, i, 0); tmp=fabs(VECTOR(*vector)[i]); if (tmp>amax) { amax=tmp; which=i; } } if (scale && amax!=0) { igraph_vector_scale(vector, 1/VECTOR(*vector)[which]); } } if (options->info) { IGRAPH_WARNING("Non-zero return code from ARPACK routine!"); } igraph_matrix_destroy(&vectors); igraph_vector_destroy(&values); IGRAPH_FINALLY_CLEAN(2); return 0; }