int igraph_vector_complex_create(igraph_vector_complex_t *v, const igraph_vector_t *real, const igraph_vector_t *imag) { int i, n=igraph_vector_size(real); if (n != igraph_vector_size(imag)) { IGRAPH_ERROR("Real and imag vector sizes don't match", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_vector_complex_init(v, n)); /* FINALLY not needed */ for (i=0; i<n; i++) { VECTOR(*v)[i] = igraph_complex(VECTOR(*real)[i], VECTOR(*imag)[i]); } return 0; }
int igraph_i_eigen_matrix_lapack_reorder(const igraph_vector_t *real, const igraph_vector_t *imag, const igraph_matrix_t *compressed, const igraph_eigen_which_t *which, igraph_vector_complex_t *values, igraph_matrix_complex_t *vectors) { igraph_vector_int_t idx; igraph_vector_t mag; igraph_bool_t hasmag=0; int nev=(int) igraph_vector_size(real); int howmany=0, start=0; int i; igraph_i_eigen_matrix_lapack_cmp_t cmpfunc=0; igraph_i_eml_cmp_t vextra = { &mag, real, imag }; void *extra=&vextra; IGRAPH_CHECK(igraph_vector_int_init(&idx, nev)); IGRAPH_FINALLY(igraph_vector_int_destroy, &idx); switch (which->pos) { case IGRAPH_EIGEN_LM: INITMAG(); cmpfunc=igraph_i_eigen_matrix_lapack_cmp_lm; howmany=which->howmany; break; case IGRAPH_EIGEN_ALL: INITMAG(); cmpfunc=igraph_i_eigen_matrix_lapack_cmp_sm; howmany=nev; break; case IGRAPH_EIGEN_SM: INITMAG(); cmpfunc=igraph_i_eigen_matrix_lapack_cmp_sm; howmany=which->howmany; break; case IGRAPH_EIGEN_LR: cmpfunc=igraph_i_eigen_matrix_lapack_cmp_lr; howmany=which->howmany; break; case IGRAPH_EIGEN_SR: cmpfunc=igraph_i_eigen_matrix_lapack_cmp_sr; howmany=which->howmany; break; case IGRAPH_EIGEN_SELECT: INITMAG(); cmpfunc=igraph_i_eigen_matrix_lapack_cmp_sm; start=which->il-1; howmany=which->iu - which->il + 1; break; case IGRAPH_EIGEN_LI: cmpfunc=igraph_i_eigen_matrix_lapack_cmp_li; howmany=which->howmany; break; case IGRAPH_EIGEN_SI: cmpfunc=igraph_i_eigen_matrix_lapack_cmp_si; howmany=which->howmany; break; case IGRAPH_EIGEN_INTERVAL: case IGRAPH_EIGEN_BE: default: IGRAPH_ERROR("Unimplemented eigenvalue ordering", IGRAPH_UNIMPLEMENTED); break; } for (i=0; i<nev; i++) { VECTOR(idx)[i] = i; } igraph_qsort_r(VECTOR(idx), (size_t) nev, sizeof(VECTOR(idx)[0]), extra, cmpfunc); if (hasmag) { igraph_vector_destroy(&mag); IGRAPH_FINALLY_CLEAN(1); } if (values) { IGRAPH_CHECK(igraph_vector_complex_resize(values, howmany)); for (i=0; i<howmany; i++) { int x=VECTOR(idx)[start+i]; VECTOR(*values)[i] = igraph_complex(VECTOR(*real)[x], VECTOR(*imag)[x]); } } if (vectors) { int n=(int) igraph_matrix_nrow(compressed); IGRAPH_CHECK(igraph_matrix_complex_resize(vectors, n, howmany)); for (i=0; i<howmany; i++) { int j, x=VECTOR(idx)[start+i]; if (VECTOR(*imag)[x] == 0) { /* real eigenvalue */ for (j=0; j<n; j++) { MATRIX(*vectors, j, i) = igraph_complex(MATRIX(*compressed, j, x), 0.0); } } else { /* complex eigenvalue */ int neg=1, co=0; if (VECTOR(*imag)[x] < 0) { neg=-1; co=1; } for (j=0; j<n; j++) { MATRIX(*vectors, j, i) = igraph_complex(MATRIX(*compressed, j, x-co), neg * MATRIX(*compressed, j, x+1-co)); } } } } igraph_vector_int_destroy(&idx); IGRAPH_FINALLY_CLEAN(1); return 0; }