Skip to content

Commit 6bd5cc7

Browse files
committed
fix: moved voronoi implementation
1 parent 239fe5b commit 6bd5cc7

1 file changed

Lines changed: 143 additions & 147 deletions

File tree

src/_igraph/graphobject.c

Lines changed: 143 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -13748,6 +13748,149 @@ PyObject *igraphmodule_Graph_community_leiden(igraphmodule_GraphObject *self,
1374813748
return error ? NULL : Py_BuildValue("Nd", res, (double) quality);
1374913749
}
1375013750

13751+
/**
13752+
* Voronoi clustering
13753+
*/
13754+
PyObject *igraphmodule_Graph_community_voronoi(igraphmodule_GraphObject *self,
13755+
PyObject *args, PyObject *kwds) {
13756+
static char *kwlist[] = {"modularity", "lengths", "weights", "mode", "radius", NULL};
13757+
PyObject *lengths_o = Py_None, *weights_o = Py_None;
13758+
PyObject *mode_o = Py_None;
13759+
PyObject *radius_o = Py_None;
13760+
PyObject *modularity_o = Py_None;
13761+
igraph_vector_t *lengths_v = NULL;
13762+
igraph_vector_t *weights_v = NULL;
13763+
igraph_vector_int_t membership_v, generators_v;
13764+
igraph_neimode_t mode = IGRAPH_ALL;
13765+
igraph_real_t radius = -1.0; /* negative means auto-optimize */
13766+
igraph_real_t modularity = IGRAPH_NAN;
13767+
PyObject *membership_o, *generators_o, *result_o;
13768+
igraph_bool_t return_modularity = false;
13769+
13770+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOO", kwlist,
13771+
&modularity_o, &lengths_o, &weights_o, &mode_o, &radius_o))
13772+
return NULL;
13773+
13774+
if (modularity_o != Py_None){
13775+
modularity = (igraph_real_t)PyFloat_AsDouble(modularity_o);
13776+
}
13777+
else {
13778+
return_modularity = true;
13779+
}
13780+
13781+
/* Handle mode parameter */
13782+
if (mode_o != Py_None) {
13783+
if (igraphmodule_PyObject_to_neimode_t(mode_o, &mode))
13784+
return NULL;
13785+
}
13786+
13787+
/* Handle radius parameter */
13788+
if (radius_o != Py_None) {
13789+
if (PyFloat_Check(radius_o)) {
13790+
radius = PyFloat_AsDouble(radius_o);
13791+
} else if (PyLong_Check(radius_o)) {
13792+
radius = PyLong_AsDouble(radius_o);
13793+
} else {
13794+
PyErr_SetString(PyExc_TypeError, "radius must be a number or None");
13795+
return NULL;
13796+
}
13797+
if (PyErr_Occurred()) return NULL;
13798+
}
13799+
13800+
/* Handle lengths parameter */
13801+
if (lengths_o != Py_None) {
13802+
if (igraphmodule_attrib_to_vector_t(lengths_o, self, &lengths_v, ATTRIBUTE_TYPE_EDGE)) {
13803+
return NULL;
13804+
}
13805+
}
13806+
13807+
/* Handle weights parameter */
13808+
if (weights_o != Py_None) {
13809+
if (igraphmodule_attrib_to_vector_t(weights_o, self, &weights_v, ATTRIBUTE_TYPE_EDGE)) {
13810+
if (lengths_v != 0) {
13811+
igraph_vector_destroy(lengths_v); free(lengths_v);
13812+
}
13813+
return NULL;
13814+
}
13815+
}
13816+
13817+
/* Initialize result vectors */
13818+
if (igraph_vector_int_init(&membership_v, 0)) {
13819+
if (lengths_v != 0) {
13820+
igraph_vector_destroy(lengths_v); free(lengths_v);
13821+
}
13822+
if (weights_v != 0) {
13823+
igraph_vector_destroy(weights_v); free(weights_v);
13824+
}
13825+
igraphmodule_handle_igraph_error();
13826+
return NULL;
13827+
}
13828+
13829+
if (igraph_vector_int_init(&generators_v, 0)) {
13830+
if (lengths_v != 0) {
13831+
igraph_vector_destroy(lengths_v); free(lengths_v);
13832+
}
13833+
if (weights_v != 0) {
13834+
igraph_vector_destroy(weights_v); free(weights_v);
13835+
}
13836+
igraph_vector_int_destroy(&membership_v);
13837+
igraphmodule_handle_igraph_error();
13838+
return NULL;
13839+
}
13840+
13841+
/* Call the C function - pass NULL for None parameters */
13842+
if (igraph_community_voronoi(&self->g, &membership_v, &generators_v,
13843+
return_modularity ? &modularity : NULL,
13844+
lengths_v,
13845+
weights_v,
13846+
mode, radius)) {
13847+
13848+
if (lengths_v != 0) {
13849+
igraph_vector_destroy(lengths_v); free(lengths_v);
13850+
}
13851+
if (weights_v != 0) {
13852+
igraph_vector_destroy(weights_v); free(weights_v);
13853+
}
13854+
igraph_vector_int_destroy(&membership_v);
13855+
igraph_vector_int_destroy(&generators_v);
13856+
igraphmodule_handle_igraph_error();
13857+
return NULL;
13858+
}
13859+
13860+
/* Clean up input vectors */
13861+
13862+
if (lengths_v != 0) {
13863+
igraph_vector_destroy(lengths_v); free(lengths_v);
13864+
}
13865+
if (weights_v != 0) {
13866+
igraph_vector_destroy(weights_v); free(weights_v);
13867+
}
13868+
13869+
/* Convert results to Python objects */
13870+
membership_o = igraphmodule_vector_int_t_to_PyList(&membership_v);
13871+
igraph_vector_int_destroy(&membership_v);
13872+
if (!membership_o) {
13873+
igraph_vector_int_destroy(&generators_v);
13874+
return NULL;
13875+
}
13876+
13877+
generators_o = igraphmodule_vector_int_t_to_PyList(&generators_v);
13878+
igraph_vector_int_destroy(&generators_v);
13879+
if (!generators_o) {
13880+
Py_DECREF(membership_o);
13881+
return NULL;
13882+
}
13883+
13884+
/* Return tuple with membership, generators, and modularity */
13885+
if (return_modularity) {
13886+
result_o = Py_BuildValue("(NNd)", membership_o, generators_o, modularity);
13887+
} else {
13888+
result_o = Py_BuildValue("(NN)", membership_o, generators_o);
13889+
}
13890+
13891+
return result_o;
13892+
}
13893+
1375113894
/**********************************************************************
1375213895
* Random walks *
1375313896
**********************************************************************/
@@ -13896,153 +14039,6 @@ PyObject *igraphmodule_Graph_random_walk(igraphmodule_GraphObject * self,
1389614039
}
1389714040

1389814041

13899-
/**********************************************************************
13900-
* Other methods *
13901-
**********************************************************************/
13902-
13903-
/**
13904-
* Voronoi clustering
13905-
*/
13906-
PyObject *igraphmodule_Graph_community_voronoi(igraphmodule_GraphObject *self,
13907-
PyObject *args, PyObject *kwds) {
13908-
static char *kwlist[] = {"modularity", "lengths", "weights", "mode", "radius", NULL};
13909-
PyObject *lengths_o = Py_None, *weights_o = Py_None;
13910-
PyObject *mode_o = Py_None;
13911-
PyObject *radius_o = Py_None;
13912-
PyObject *modularity_o = Py_None;
13913-
igraph_vector_t *lengths_v = NULL;
13914-
igraph_vector_t *weights_v = NULL;
13915-
igraph_vector_int_t membership_v, generators_v;
13916-
igraph_neimode_t mode = IGRAPH_ALL;
13917-
igraph_real_t radius = -1.0; /* negative means auto-optimize */
13918-
igraph_real_t modularity = IGRAPH_NAN;
13919-
PyObject *membership_o, *generators_o, *result_o;
13920-
igraph_bool_t return_modularity = false;
13921-
13922-
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOO", kwlist,
13923-
&modularity_o, &lengths_o, &weights_o, &mode_o, &radius_o))
13924-
return NULL;
13925-
13926-
if (modularity_o != Py_None){
13927-
modularity = (igraph_real_t)PyFloat_AsDouble(modularity_o);
13928-
}
13929-
else {
13930-
return_modularity = true;
13931-
}
13932-
13933-
/* Handle mode parameter */
13934-
if (mode_o != Py_None) {
13935-
if (igraphmodule_PyObject_to_neimode_t(mode_o, &mode))
13936-
return NULL;
13937-
}
13938-
13939-
/* Handle radius parameter */
13940-
if (radius_o != Py_None) {
13941-
if (PyFloat_Check(radius_o)) {
13942-
radius = PyFloat_AsDouble(radius_o);
13943-
} else if (PyLong_Check(radius_o)) {
13944-
radius = PyLong_AsDouble(radius_o);
13945-
} else {
13946-
PyErr_SetString(PyExc_TypeError, "radius must be a number or None");
13947-
return NULL;
13948-
}
13949-
if (PyErr_Occurred()) return NULL;
13950-
}
13951-
13952-
/* Handle lengths parameter */
13953-
if (lengths_o != Py_None) {
13954-
if (igraphmodule_attrib_to_vector_t(lengths_o, self, &lengths_v, ATTRIBUTE_TYPE_EDGE)) {
13955-
return NULL;
13956-
}
13957-
}
13958-
13959-
/* Handle weights parameter */
13960-
if (weights_o != Py_None) {
13961-
if (igraphmodule_attrib_to_vector_t(weights_o, self, &weights_v, ATTRIBUTE_TYPE_EDGE)) {
13962-
if (lengths_v != 0) {
13963-
igraph_vector_destroy(lengths_v); free(lengths_v);
13964-
}
13965-
return NULL;
13966-
}
13967-
}
13968-
13969-
/* Initialize result vectors */
13970-
if (igraph_vector_int_init(&membership_v, 0)) {
13971-
if (lengths_v != 0) {
13972-
igraph_vector_destroy(lengths_v); free(lengths_v);
13973-
}
13974-
if (weights_v != 0) {
13975-
igraph_vector_destroy(weights_v); free(weights_v);
13976-
}
13977-
igraphmodule_handle_igraph_error();
13978-
return NULL;
13979-
}
13980-
13981-
if (igraph_vector_int_init(&generators_v, 0)) {
13982-
if (lengths_v != 0) {
13983-
igraph_vector_destroy(lengths_v); free(lengths_v);
13984-
}
13985-
if (weights_v != 0) {
13986-
igraph_vector_destroy(weights_v); free(weights_v);
13987-
}
13988-
igraph_vector_int_destroy(&membership_v);
13989-
igraphmodule_handle_igraph_error();
13990-
return NULL;
13991-
}
13992-
13993-
/* Call the C function - pass NULL for None parameters */
13994-
if (igraph_community_voronoi(&self->g, &membership_v, &generators_v,
13995-
return_modularity ? &modularity : NULL,
13996-
lengths_v,
13997-
weights_v,
13998-
mode, radius)) {
13999-
14000-
if (lengths_v != 0) {
14001-
igraph_vector_destroy(lengths_v); free(lengths_v);
14002-
}
14003-
if (weights_v != 0) {
14004-
igraph_vector_destroy(weights_v); free(weights_v);
14005-
}
14006-
igraph_vector_int_destroy(&membership_v);
14007-
igraph_vector_int_destroy(&generators_v);
14008-
igraphmodule_handle_igraph_error();
14009-
return NULL;
14010-
}
14011-
14012-
/* Clean up input vectors */
14013-
14014-
if (lengths_v != 0) {
14015-
igraph_vector_destroy(lengths_v); free(lengths_v);
14016-
}
14017-
if (weights_v != 0) {
14018-
igraph_vector_destroy(weights_v); free(weights_v);
14019-
}
14020-
14021-
/* Convert results to Python objects */
14022-
membership_o = igraphmodule_vector_int_t_to_PyList(&membership_v);
14023-
igraph_vector_int_destroy(&membership_v);
14024-
if (!membership_o) {
14025-
igraph_vector_int_destroy(&generators_v);
14026-
return NULL;
14027-
}
14028-
14029-
generators_o = igraphmodule_vector_int_t_to_PyList(&generators_v);
14030-
igraph_vector_int_destroy(&generators_v);
14031-
if (!generators_o) {
14032-
Py_DECREF(membership_o);
14033-
return NULL;
14034-
}
14035-
14036-
/* Return tuple with membership, generators, and modularity */
14037-
if (return_modularity) {
14038-
result_o = Py_BuildValue("(NNd)", membership_o, generators_o, modularity);
14039-
} else {
14040-
result_o = Py_BuildValue("(NN)", membership_o, generators_o);
14041-
}
14042-
14043-
return result_o;
14044-
}
14045-
1404614042
/**********************************************************************
1404714043
* Special internal methods that you won't need to mess around with *
1404814044
**********************************************************************/

0 commit comments

Comments
 (0)