int igraph_i_eigen_matrix_symmetric_arpack(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) { /* For ARPACK we need a matrix multiplication operation. This can be done in any format, so everything is fine, we don't have to convert. */ igraph_i_eigen_matrix_sym_arpack_data_t myextra = { A, sA }; if (!options) { IGRAPH_ERROR("`options' must be given for ARPACK algorithm", IGRAPH_EINVAL); } if (which->pos == IGRAPH_EIGEN_BE) { return igraph_i_eigen_matrix_symmetric_arpack_be(A, sA, fun, n, extra, which, options, storage, values, vectors); } else { switch (which->pos) { case IGRAPH_EIGEN_LM: options->which[0]='L'; options->which[1]='M'; options->nev=which->howmany; break; case IGRAPH_EIGEN_SM: options->which[0]='S'; options->which[1]='M'; options->nev=which->howmany; break; case IGRAPH_EIGEN_LA: options->which[0]='L'; options->which[1]='A'; options->nev=which->howmany; break; case IGRAPH_EIGEN_SA: options->which[0]='S'; options->which[1]='A'; options->nev=which->howmany; break; case IGRAPH_EIGEN_ALL: options->which[0]='L'; options->which[1]='M'; options->nev=n; break; case IGRAPH_EIGEN_INTERVAL: IGRAPH_ERROR("Interval of eigenvectors with ARPACK", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_SELECT: IGRAPH_ERROR("Selected eigenvalues with ARPACK", IGRAPH_UNIMPLEMENTED); /* TODO */ break; default: /* This cannot happen */ break; } options->n=n; options->ncv= 2*options->nev < n ? 2*options->nev : n; if (!fun) { fun=igraph_i_eigen_matrix_sym_arpack_cb; extra=(void*) &myextra; } IGRAPH_CHECK(igraph_arpack_rssolve(fun, extra, options, storage, values, vectors)); 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_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_i_eigen_adjacency_arpack(const igraph_t *graph, 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_complex_t *cmplxvalues, igraph_matrix_complex_t *cmplxvectors){ igraph_adjlist_t adjlist; void *extra=(void*) &adjlist; int n=igraph_vcount(graph); if (!options) { IGRAPH_ERROR("`options' must be given for ARPACK algorithm", IGRAPH_EINVAL); } if (igraph_is_directed(graph)) { IGRAPH_ERROR("ARPACK adjacency eigensolver not implemented for " "directed graphs", IGRAPH_UNIMPLEMENTED); } if (which->pos == IGRAPH_EIGEN_INTERVAL) { IGRAPH_ERROR("ARPACK adjacency eigensolver does not implement " "`INTERNAL' eigenvalues", IGRAPH_UNIMPLEMENTED); } if (which->pos == IGRAPH_EIGEN_SELECT) { IGRAPH_ERROR("ARPACK adjacency eigensolver does not implement " "`SELECT' eigenvalues", IGRAPH_UNIMPLEMENTED); } if (which->pos == IGRAPH_EIGEN_ALL) { IGRAPH_ERROR("ARPACK adjacency eigensolver does not implement " "`ALL' eigenvalues", IGRAPH_UNIMPLEMENTED); } switch (which->pos) { case IGRAPH_EIGEN_LM: options->which[0]='L'; options->which[1]='M'; options->nev=which->howmany; break; case IGRAPH_EIGEN_SM: options->which[0]='S'; options->which[1]='M'; options->nev=which->howmany; break; case IGRAPH_EIGEN_LA: options->which[0]='L'; options->which[1]='A'; options->nev=which->howmany; break; case IGRAPH_EIGEN_SA: options->which[0]='S'; options->which[1]='A'; options->nev=which->howmany; break; case IGRAPH_EIGEN_ALL: options->which[0]='L'; options->which[1]='M'; options->nev=n; break; case IGRAPH_EIGEN_BE: IGRAPH_ERROR("Eigenvectors from both ends with ARPACK", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_INTERVAL: IGRAPH_ERROR("Interval of eigenvectors with ARPACK", IGRAPH_UNIMPLEMENTED); /* TODO */ break; case IGRAPH_EIGEN_SELECT: IGRAPH_ERROR("Selected eigenvalues with ARPACK", IGRAPH_UNIMPLEMENTED); /* TODO */ break; default: /* This cannot happen */ break; } options->n=n; options->ncv= 2*options->nev < n ? 2*options->nev : n; IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_IN)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_eigen_adjacency_arpack_sym_cb, extra, options, storage, values, vectors)); igraph_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(1); 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; }