Skip to content

Commit 239fe5b

Browse files
committed
add: modularity as param and conversion if needed
1 parent 2540511 commit 239fe5b

File tree

2 files changed

+55
-40
lines changed

2 files changed

+55
-40
lines changed

src/_igraph/graphobject.c

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13905,23 +13905,31 @@ PyObject *igraphmodule_Graph_random_walk(igraphmodule_GraphObject * self,
1390513905
*/
1390613906
PyObject *igraphmodule_Graph_community_voronoi(igraphmodule_GraphObject *self,
1390713907
PyObject *args, PyObject *kwds) {
13908-
static char *kwlist[] = {"lengths", "weights", "mode", "radius", NULL};
13908+
static char *kwlist[] = {"modularity", "lengths", "weights", "mode", "radius", NULL};
1390913909
PyObject *lengths_o = Py_None, *weights_o = Py_None;
1391013910
PyObject *mode_o = Py_None;
1391113911
PyObject *radius_o = Py_None;
13912+
PyObject *modularity_o = Py_None;
1391213913
igraph_vector_t *lengths_v = NULL;
1391313914
igraph_vector_t *weights_v = NULL;
1391413915
igraph_vector_int_t membership_v, generators_v;
1391513916
igraph_neimode_t mode = IGRAPH_ALL;
1391613917
igraph_real_t radius = -1.0; /* negative means auto-optimize */
1391713918
igraph_real_t modularity = IGRAPH_NAN;
1391813919
PyObject *membership_o, *generators_o, *result_o;
13919-
igraph_bool_t return_modularity = 1;
13920+
igraph_bool_t return_modularity = false;
1392013921

13921-
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO", kwlist,
13922-
&lengths_o, &weights_o, &mode_o, &radius_o))
13922+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOO", kwlist,
13923+
&modularity_o, &lengths_o, &weights_o, &mode_o, &radius_o))
1392313924
return NULL;
1392413925

13926+
if (modularity_o != Py_None){
13927+
modularity = (igraph_real_t)PyFloat_AsDouble(modularity_o);
13928+
}
13929+
else {
13930+
return_modularity = true;
13931+
}
13932+
1392513933
/* Handle mode parameter */
1392613934
if (mode_o != Py_None) {
1392713935
if (igraphmodule_PyObject_to_neimode_t(mode_o, &mode))
@@ -18739,40 +18747,44 @@ struct PyMethodDef igraphmodule_Graph_methods[] = {
1873918747
"@return: the community membership vector.\n"
1874018748
},
1874118749
{"community_voronoi",
18742-
(PyCFunction) igraphmodule_Graph_community_voronoi,
18750+
(PyCFunction) igraphmodule_Graph_community_voronoi,
1874318751
METH_VARARGS | METH_KEYWORDS,
18744-
"community_voronoi(lengths=None, weights=None, mode=\"all\", radius=None)\n\n"
18745-
"Finds communities using Voronoi partitioning.\n\n"
18746-
"This function finds communities using a Voronoi partitioning of vertices based\n"
18747-
"on the given edge lengths divided by the edge clustering coefficient.\n"
18748-
"The generator vertices are chosen to be those with the largest local relative\n"
18749-
"density within a radius, with the local relative density of a vertex defined as\n"
18750-
"s * m / (m + k), where s is the strength of the vertex, m is the number of\n"
18751-
"edges within the vertex's first order neighborhood, while k is the number of\n"
18752-
"edges with only one endpoint within this neighborhood.\n\n"
18753-
"@param lengths: edge lengths, or C{None} to consider all edges as having\n"
18754-
" unit length. Voronoi partitioning will use edge lengths equal to\n"
18755-
" lengths / ECC where ECC is the edge clustering coefficient.\n"
18756-
"@param weights: edge weights, or C{None} to consider all edges as having\n"
18757-
" unit weight. Weights are used when selecting generator points, as well\n"
18758-
" as for computing modularity.\n"
18759-
"@param mode: if C{\"out\"}, distances from generator points to all other\n"
18760-
" nodes are considered. If C{\"in\"}, the reverse distances are used.\n"
18761-
" If C{\"all\"}, edge directions are ignored. This parameter is ignored\n"
18762-
" for undirected graphs.\n"
18763-
"@param radius: the radius/resolution to use when selecting generator points.\n"
18764-
" The larger this value, the fewer partitions there will be. Pass C{None}\n"
18765-
" to automatically select the radius that maximizes modularity.\n"
18766-
"@return: a tuple containing the membership vector, generator vertices,\n"
18767-
" and modularity score.\n"
18768-
"@rtype: tuple\n\n"
18769-
"@newfield ref: Reference\n"
18770-
"@ref: Deritei et al., Community detection by graph Voronoi diagrams,\n"
18771-
" New Journal of Physics 16, 063007 (2014)\n"
18772-
" U{https://doi.org/10.1088/1367-2630/16/6/063007}\n"
18773-
"@ref: Molnár et al., Community Detection in Directed Weighted Networks\n"
18774-
" using Voronoi Partitioning, Scientific Reports 14, 8124 (2024)\n"
18775-
" U{https://doi.org/10.1038/s41598-024-58624-4}\n"
18752+
"community_voronoi(lengths=None, weights=None, mode=\"all\", radius=None, modularity=None)\n\n"
18753+
"Finds communities using Voronoi partitioning.\n\n"
18754+
"This function finds communities using a Voronoi partitioning of vertices based\n"
18755+
"on the given edge lengths divided by the edge clustering coefficient.\n"
18756+
"The generator vertices are chosen to be those with the largest local relative\n"
18757+
"density within a radius, with the local relative density of a vertex defined as\n"
18758+
"s * m / (m + k), where s is the strength of the vertex, m is the number of\n"
18759+
"edges within the vertex's first order neighborhood, while k is the number of\n"
18760+
"edges with only one endpoint within this neighborhood.\n\n"
18761+
"@param lengths: edge lengths, or C{None} to consider all edges as having\n"
18762+
" unit length. Voronoi partitioning will use edge lengths equal to\n"
18763+
" lengths / ECC where ECC is the edge clustering coefficient.\n"
18764+
"@param weights: edge weights, or C{None} to consider all edges as having\n"
18765+
" unit weight. Weights are used when selecting generator points, as well\n"
18766+
" as for computing modularity.\n"
18767+
"@param mode: if C{\"out\"}, distances from generator points to all other\n"
18768+
" nodes are considered. If C{\"in\"}, the reverse distances are used.\n"
18769+
" If C{\"all\"}, edge directions are ignored. This parameter is ignored\n"
18770+
" for undirected graphs.\n"
18771+
"@param radius: the radius/resolution to use when selecting generator points.\n"
18772+
" The larger this value, the fewer partitions there will be. Pass C{None}\n"
18773+
" to automatically select the radius that maximizes modularity.\n"
18774+
"@param modularity: if not C{None}, the modularity score will be calculated\n"
18775+
" and returned as part of the result tuple.\n"
18776+
"@return: a tuple containing the membership vector and generator vertices.\n"
18777+
" When modularity calculation is requested, also includes the modularity score\n"
18778+
" as a third element: (membership, generators, modularity).\n"
18779+
" Otherwise: (membership, generators).\n"
18780+
"@rtype: tuple\n\n"
18781+
"B{References}\n\n"
18782+
" - Deritei et al., Community detection by graph Voronoi diagrams,\n"
18783+
" New Journal of Physics 16, 063007 (2014)\n"
18784+
" https://doi.org/10.1088/1367-2630/16/6/063007\n"
18785+
" - Molnár et al., Community Detection in Directed Weighted Networks\n"
18786+
" using Voronoi Partitioning, Scientific Reports 14, 8124 (2024)\n"
18787+
" https://doi.org/10.1038/s41598-024-58624-4\n"
1877618788
},
1877718789
{"community_leiden",
1877818790
(PyCFunction) igraphmodule_Graph_community_leiden,

src/igraph/community.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def _community_spinglass(graph, *args, **kwds):
320320
return VertexClustering(graph, membership, modularity_params=modularity_params)
321321

322322

323-
def _community_voronoi(graph, lengths=None, weights=None, mode="all", radius=None):
323+
def _community_voronoi(graph, modularity=None, lengths=None, weights=None, mode="all", radius=None):
324324
"""Finds communities using Voronoi partitioning.
325325
326326
This function finds communities using a Voronoi partitioning of vertices based
@@ -364,8 +364,11 @@ def _community_voronoi(graph, lengths=None, weights=None, mode="all", radius=Non
364364
mode = mode_map[mode.lower()]
365365
else:
366366
raise ValueError(f"Invalid mode '{mode}'. Must be one of: out, in, all")
367-
368-
membership, generators, modularity = GraphBase.community_voronoi(graph, lengths, weights, mode, radius)
367+
368+
if modularity is None:
369+
membership, generators, modularity = GraphBase.community_voronoi(graph, modularity, lengths, weights, mode, radius)
370+
else:
371+
membership, generators = GraphBase.community_voronoi(graph, modularity, lengths, weights, mode, radius)
369372

370373
params = {"generators": generators}
371374
modularity_params = {}

0 commit comments

Comments
 (0)