int igraph_lapack_dsyevr(const igraph_matrix_t *A, igraph_lapack_dsyev_which_t which, igraph_real_t vl, igraph_real_t vu, int vestimate, int il, int iu, igraph_real_t abstol, igraph_vector_t *values, igraph_matrix_t *vectors, igraph_vector_int_t *support) { igraph_matrix_t Acopy; char jobz = vectors ? 'V' : 'N', range, uplo='U'; int n=(int) igraph_matrix_nrow(A), lda=n, ldz=n; int m, info; igraph_vector_t *myvalues=values, vvalues; igraph_vector_int_t *mysupport=support, vsupport; igraph_vector_t work; igraph_vector_int_t iwork; int lwork=-1, liwork=-1; if (n != igraph_matrix_ncol(A)) { IGRAPH_ERROR("Cannot find eigenvalues/vectors", IGRAPH_NONSQUARE); } if (which==IGRAPH_LAPACK_DSYEV_INTERVAL && (vestimate < 1 || vestimate > n)) { IGRAPH_ERROR("Estimated (upper bound) number of eigenvalues must be " "between 1 and n", IGRAPH_EINVAL); } if (which==IGRAPH_LAPACK_DSYEV_SELECT && iu-il < 0) { IGRAPH_ERROR("Invalid 'il' and/or 'iu' values", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_matrix_copy(&Acopy, A)); IGRAPH_FINALLY(igraph_matrix_destroy, &Acopy); IGRAPH_VECTOR_INIT_FINALLY(&work, 1); IGRAPH_CHECK(igraph_vector_int_init(&iwork, 1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &iwork); if (!values) { IGRAPH_VECTOR_INIT_FINALLY(&vvalues, 0); myvalues=&vvalues; } if (!support) { IGRAPH_CHECK(igraph_vector_int_init(&vsupport, 0)); IGRAPH_FINALLY(igraph_vector_int_destroy, &vsupport); mysupport=&vsupport; } switch (which) { case IGRAPH_LAPACK_DSYEV_ALL: range = 'A'; IGRAPH_CHECK(igraph_vector_resize(myvalues, n)); IGRAPH_CHECK(igraph_vector_int_resize(mysupport, 2*n)); if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, n)); } break; case IGRAPH_LAPACK_DSYEV_INTERVAL: range = 'V'; IGRAPH_CHECK(igraph_vector_resize(myvalues, vestimate)); IGRAPH_CHECK(igraph_vector_int_resize(mysupport, 2*vestimate)); if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors,n, vestimate)); } break; case IGRAPH_LAPACK_DSYEV_SELECT: range = 'I'; IGRAPH_CHECK(igraph_vector_resize(myvalues, iu-il+1)); IGRAPH_CHECK(igraph_vector_int_resize(mysupport, 2*(iu-il+1))); if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, iu-il+1)); } break; } igraphdsyevr_(&jobz, &range, &uplo, &n, &MATRIX(Acopy,0,0), &lda, &vl, &vu, &il, &iu, &abstol, &m, VECTOR(*myvalues), vectors ? &MATRIX(*vectors,0,0) : 0, &ldz, VECTOR(*mysupport), VECTOR(work), &lwork, VECTOR(iwork), &liwork, &info); lwork=(int) VECTOR(work)[0]; liwork=VECTOR(iwork)[0]; IGRAPH_CHECK(igraph_vector_resize(&work, lwork)); IGRAPH_CHECK(igraph_vector_int_resize(&iwork, liwork)); igraphdsyevr_(&jobz, &range, &uplo, &n, &MATRIX(Acopy,0,0), &lda, &vl, &vu, &il, &iu, &abstol, &m, VECTOR(*myvalues), vectors ? &MATRIX(*vectors,0,0) : 0, &ldz, VECTOR(*mysupport), VECTOR(work), &lwork, VECTOR(iwork), &liwork, &info); if (values) { IGRAPH_CHECK(igraph_vector_resize(values, m)); } if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, m)); } if (support) { IGRAPH_CHECK(igraph_vector_int_resize(support, m)); } if (!support) { igraph_vector_int_destroy(&vsupport); IGRAPH_FINALLY_CLEAN(1); } if (!values) { igraph_vector_destroy(&vvalues); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_int_destroy(&iwork); igraph_vector_destroy(&work); igraph_matrix_destroy(&Acopy); IGRAPH_FINALLY_CLEAN(3); return 0; }
int igraph_i_vertex_coloring_greedy_cn(const igraph_t *graph, igraph_vector_int_t *colors) { long i, vertex, maxdeg; long vc = igraph_vcount(graph); igraph_2wheap_t cn; /* indexed heap storing number of already coloured neighbours */ igraph_vector_int_t neigh_colors; igraph_adjlist_t adjlist; IGRAPH_CHECK(igraph_vector_int_resize(colors, vc)); igraph_vector_int_fill(colors, 0); /* Nothing to do for 0 or 1 vertices. * Remember that colours are integers starting from 0, * and the 'colors' vector is already 0-initialized above. */ if (vc <= 1) return IGRAPH_SUCCESS; IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); /* find maximum degree and a corresponding vertex */ { igraph_vector_t degree; IGRAPH_CHECK(igraph_vector_init(°ree, 0)); IGRAPH_FINALLY(igraph_vector_destroy, °ree); IGRAPH_CHECK(igraph_degree(graph, °ree, igraph_vss_all(), IGRAPH_ALL, 0)); vertex = igraph_vector_which_max(°ree); maxdeg = VECTOR(degree)[vertex]; igraph_vector_destroy(°ree); IGRAPH_FINALLY_CLEAN(1); } IGRAPH_CHECK(igraph_vector_int_init(&neigh_colors, 0)); IGRAPH_CHECK(igraph_vector_int_reserve(&neigh_colors, maxdeg)); IGRAPH_FINALLY(igraph_vector_int_destroy, &neigh_colors); IGRAPH_CHECK(igraph_2wheap_init(&cn, vc)); IGRAPH_FINALLY(igraph_2wheap_destroy, &cn); for (i=0; i < vc; ++i) if (i != vertex) igraph_2wheap_push_with_index(&cn, i, 0); /* should not fail since memory was already reserved */ while (1) { igraph_vector_int_t *neighbors = igraph_adjlist_get(&adjlist, vertex); long neigh_count = igraph_vector_int_size(neighbors); /* colour current vertex */ { igraph_integer_t col; IGRAPH_CHECK(igraph_vector_int_resize(&neigh_colors, neigh_count)); for (i=0; i < neigh_count; ++i) VECTOR(neigh_colors)[i] = VECTOR(*colors)[ VECTOR(*neighbors)[i] ]; igraph_vector_int_sort(&neigh_colors); i=0; col = 0; do { while (i < neigh_count && VECTOR(neigh_colors)[i] == col) i++; col++; } while (i < neigh_count && VECTOR(neigh_colors)[i] == col); VECTOR(*colors)[vertex] = col; } /* increment number of coloured neighbours for each neighbour of vertex */ for (i=0; i < neigh_count; ++i) { long idx = VECTOR(*neighbors)[i]; if (igraph_2wheap_has_elem(&cn, idx)) igraph_2wheap_modify(&cn, idx, igraph_2wheap_get(&cn, idx) + 1); } /* stop if no more vertices left to colour */ if (igraph_2wheap_empty(&cn)) break; igraph_2wheap_delete_max_index(&cn, &vertex); IGRAPH_ALLOW_INTERRUPTION(); } /* subtract 1 from each colour value, so that colours start at 0 */ igraph_vector_int_add_constant(colors, -1); /* free data structures */ igraph_vector_int_destroy(&neigh_colors); igraph_adjlist_destroy(&adjlist); igraph_2wheap_destroy(&cn); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; }