From 6dcb5ba4fe584234624212dacfe0ed9c940970fb Mon Sep 17 00:00:00 2001 From: BeaMarton13 Date: Tue, 17 Jun 2025 14:13:00 +0300 Subject: [PATCH 1/8] add: expose fluid communities to python --- src/_igraph/graphobject.c | 65 +++++++++++++++++++++++++++++++++++++ src/igraph/__init__.py | 3 ++ src/igraph/community.py | 25 ++++++++++++++ tests/test_decomposition.py | 55 +++++++++++++++++++++++++++++++ 4 files changed, 148 insertions(+) diff --git a/src/_igraph/graphobject.c b/src/_igraph/graphobject.c index 8c82bf79f..060ec8183 100644 --- a/src/_igraph/graphobject.c +++ b/src/_igraph/graphobject.c @@ -13895,6 +13895,46 @@ PyObject *igraphmodule_Graph_random_walk(igraphmodule_GraphObject * self, } } +/********************************************************************** + * Other methods * + **********************************************************************/ + + /** + * Fluid communities + */ +PyObject *igraphmodule_Graph_community_fluid_communities(igraphmodule_GraphObject *self, + PyObject *args, PyObject *kwds) { + static char *kwlist[] = {"no_of_communities", NULL}; + long no_of_communities_long; + igraph_integer_t no_of_communities; + igraph_vector_int_t membership; + PyObject *result; + + // Parse the Python integer argument + if (!PyArg_ParseTupleAndKeywords(args, kwds, "l", kwlist, &no_of_communities_long)) { + return NULL; + } + + // Convert to igraph_integer_t + no_of_communities = (igraph_integer_t) no_of_communities_long; + + if (igraph_vector_int_init(&membership, 0)) { + igraphmodule_handle_igraph_error(); + return NULL; + } + + if (igraph_community_fluid_communities(&self->g, no_of_communities, &membership)) { + igraphmodule_handle_igraph_error(); + igraph_vector_int_destroy(&membership); + return NULL; + } + + result = igraphmodule_vector_int_t_to_PyList(&membership); + igraph_vector_int_destroy(&membership); + + return result; +} + /********************************************************************** * Special internal methods that you won't need to mess around with * **********************************************************************/ @@ -18694,6 +18734,31 @@ struct PyMethodDef igraphmodule_Graph_methods[] = { " the given length (shorter if the random walk got stuck).\n" }, + + /**********************/ + /* OTHER METHODS */ + /**********************/ + {"community_fluid_communities", (PyCFunction) igraphmodule_Graph_community_fluid_communities, + METH_VARARGS | METH_KEYWORDS, + "community_fluid_communities(no_of_communities)\n--\n\n" + "Community detection based on fluids interacting on the graph.\n\n" + "The algorithm is based on the simple idea of several fluids interacting\n" + "in a non-homogeneous environment (the graph topology), expanding and\n" + "contracting based on their interaction and density. Weighted graphs are\n" + "not supported.\n\n" + "This function implements the community detection method described in:\n" + "Parés F, Gasulla DG, et. al. (2018) Fluid Communities: A Competitive,\n" + "Scalable and Diverse Community Detection Algorithm. In: Complex Networks\n" + "& Their Applications VI: Proceedings of Complex Networks 2017 (The Sixth\n" + "International Conference on Complex Networks and Their Applications),\n" + "Springer, vol 689, p 229. https://doi.org/10.1007/978-3-319-72150-7_19\n\n" + "@param no_of_communities: The number of communities to be found. Must be\n" + " greater than 0 and fewer than number of vertices in the graph.\n" + "@return: a list with the community membership of each vertex.\n" + "@note: The graph must be simple and connected. Edge directions will be\n" + " ignored if the graph is directed.\n" + "@note: Time complexity: O(|E|)\n"}, + /**********************/ /* INTERNAL FUNCTIONS */ /**********************/ diff --git a/src/igraph/__init__.py b/src/igraph/__init__.py index b7f920cac..a1e87d13e 100644 --- a/src/igraph/__init__.py +++ b/src/igraph/__init__.py @@ -109,6 +109,7 @@ _community_multilevel, _community_optimal_modularity, _community_edge_betweenness, + _community_fluid_communities, _community_spinglass, _community_walktrap, _k_core, @@ -658,6 +659,7 @@ def es(self): community_multilevel = _community_multilevel community_optimal_modularity = _community_optimal_modularity community_edge_betweenness = _community_edge_betweenness + community_fluid_communities = _community_fluid_communities community_spinglass = _community_spinglass community_walktrap = _community_walktrap k_core = _k_core @@ -1100,6 +1102,7 @@ def write(graph, filename, *args, **kwds): _community_multilevel, _community_optimal_modularity, _community_edge_betweenness, + _community_fluid_communities, _community_spinglass, _community_walktrap, _k_core, diff --git a/src/igraph/community.py b/src/igraph/community.py index 0fdcdf154..d7abaa6d3 100644 --- a/src/igraph/community.py +++ b/src/igraph/community.py @@ -461,6 +461,31 @@ def _community_leiden( ) + +def _community_fluid_communities(graph, no_of_communities): + """Community detection based on fluids interacting on the graph. + + The algorithm is based on the simple idea of several fluids interacting + in a non-homogeneous environment (the graph topology), expanding and + contracting based on their interaction and density. Weighted graphs are + not supported. + + This function implements the community detection method described in: + Parés F, Gasulla DG, et. al. (2018) Fluid Communities: A Competitive, + Scalable and Diverse Community Detection Algorithm. + + @param no_of_communities: The number of communities to be found. Must be + greater than 0 and fewer than number of vertices in the graph. + @return: an appropriate L{VertexClustering} object. + """ + if graph.is_directed(): + # The C implementation will show a warning, but we can handle it here + pass + + membership = GraphBase.community_fluid_communities(graph, no_of_communities) + return VertexClustering(graph, membership) + + def _modularity(self, membership, weights=None, resolution=1, directed=True): """Calculates the modularity score of the graph with respect to a given clustering. diff --git a/tests/test_decomposition.py b/tests/test_decomposition.py index 0bfdd1b6a..41ab588c8 100644 --- a/tests/test_decomposition.py +++ b/tests/test_decomposition.py @@ -280,6 +280,61 @@ def testEigenvector(self): cl = g.community_leading_eigenvector(2) self.assertMembershipsEqual(cl, [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]) self.assertAlmostEqual(cl.q, 0.4523, places=3) + + def testFluidCommunities(self): + # Test with a simple graph: two cliques connected by a single edge + g = Graph.Full(5) + Graph.Full(5) + g.add_edges([(0, 5)]) + + # Test basic functionality - should find 2 communities + cl = g.community_fluid_communities(2) + self.assertEqual(len(set(cl.membership)), 2) + self.assertMembershipsEqual(cl, [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]) + + # Test with 3 cliques + g = Graph.Full(4) + Graph.Full(4) + Graph.Full(4) + g += [(0, 4), (4, 8)] # Connect the cliques + cl = g.community_fluid_communities(3) + self.assertEqual(len(set(cl.membership)), 3) + self.assertMembershipsEqual(cl, [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]) + + # Test error conditions + # Number of communities must be positive + with self.assertRaises(Exception): + g.community_fluid_communities(0) + + # Number of communities cannot exceed number of vertices + with self.assertRaises(Exception): + g.community_fluid_communities(g.vcount() + 1) + + # Test with disconnected graph (should raise error) + g_disconnected = Graph.Full(3) + Graph.Full(3) # No connecting edge + with self.assertRaises(Exception): + g_disconnected.community_fluid_communities(2) + + # Test with single vertex (edge case) + g_single = Graph(1) + cl = g_single.community_fluid_communities(1) + self.assertEqual(cl.membership, [0]) + + # Test with small connected graph + g_small = Graph([(0, 1), (1, 2), (2, 0)]) # Triangle + cl = g_small.community_fluid_communities(1) + self.assertEqual(len(set(cl.membership)), 1) + self.assertEqual(cl.membership, [0, 0, 0]) + + # Test deterministic behavior on simple structure + # Note: Fluid communities can be non-deterministic due to randomization, + # but on very simple structures it should be consistent + g_path = Graph([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]) + cl = g_path.community_fluid_communities(2) + self.assertEqual(len(set(cl.membership)), 2) + + # Test that it returns a VertexClustering object + g = Graph.Full(6) + cl = g.community_fluid_communities(2) + self.assertIsInstance(cl, VertexClustering) + self.assertEqual(len(cl.membership), g.vcount()) def testInfomap(self): g = Graph.Famous("zachary") From 721b75c25e92cffe868697b83f3f166c6685260d Mon Sep 17 00:00:00 2001 From: BeaMarton13 Date: Tue, 17 Jun 2025 14:29:27 +0300 Subject: [PATCH 2/8] updated community --- src/igraph/community.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/igraph/community.py b/src/igraph/community.py index d7abaa6d3..47ed14c39 100644 --- a/src/igraph/community.py +++ b/src/igraph/community.py @@ -478,9 +478,26 @@ def _community_fluid_communities(graph, no_of_communities): greater than 0 and fewer than number of vertices in the graph. @return: an appropriate L{VertexClustering} object. """ + # Validate input parameters + if no_of_communities <= 0: + raise ValueError("no_of_communities must be greater than 0") + + if no_of_communities >= graph.vcount(): + raise ValueError("no_of_communities must be fewer than the number of vertices") + + # Check if graph is weighted (not supported) + if graph.is_weighted(): + raise ValueError("Weighted graphs are not supported by the fluid communities algorithm") + + # Handle directed graphs - the algorithm works on undirected graphs + # but can accept directed graphs (they are treated as undirected) if graph.is_directed(): - # The C implementation will show a warning, but we can handle it here - pass + import warnings + warnings.warn( + "Directed graphs are treated as undirected in the fluid communities algorithm", + UserWarning, + stacklevel=2 + ) membership = GraphBase.community_fluid_communities(graph, no_of_communities) return VertexClustering(graph, membership) From 63fba4f5e4bce6507fd530d02ab206a14fdde4cc Mon Sep 17 00:00:00 2001 From: BeaMarton13 Date: Tue, 17 Jun 2025 14:45:36 +0300 Subject: [PATCH 3/8] fix: error in community --- src/igraph/community.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/igraph/community.py b/src/igraph/community.py index 47ed14c39..2b9e158d3 100644 --- a/src/igraph/community.py +++ b/src/igraph/community.py @@ -461,7 +461,6 @@ def _community_leiden( ) - def _community_fluid_communities(graph, no_of_communities): """Community detection based on fluids interacting on the graph. @@ -475,15 +474,15 @@ def _community_fluid_communities(graph, no_of_communities): Scalable and Diverse Community Detection Algorithm. @param no_of_communities: The number of communities to be found. Must be - greater than 0 and fewer than number of vertices in the graph. + greater than 0 and fewer than or equal to the number of vertices in the graph. @return: an appropriate L{VertexClustering} object. """ # Validate input parameters if no_of_communities <= 0: raise ValueError("no_of_communities must be greater than 0") - if no_of_communities >= graph.vcount(): - raise ValueError("no_of_communities must be fewer than the number of vertices") + if no_of_communities > graph.vcount(): + raise ValueError("no_of_communities must be fewer than or equal to the number of vertices") # Check if graph is weighted (not supported) if graph.is_weighted(): From b6917f06bc458377ebaea4498ed450dadf806c37 Mon Sep 17 00:00:00 2001 From: BeaMarton13 Date: Wed, 18 Jun 2025 10:21:09 +0300 Subject: [PATCH 4/8] add: fluid communities decs to communities and decomposition section --- src/_igraph/graphobject.c | 47 ++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/_igraph/graphobject.c b/src/_igraph/graphobject.c index 060ec8183..e459f1e34 100644 --- a/src/_igraph/graphobject.c +++ b/src/_igraph/graphobject.c @@ -18439,6 +18439,28 @@ struct PyMethodDef igraphmodule_Graph_methods[] = { "\n" "@see: modularity()\n" }, + {"community_fluid_communities", + (PyCFunction) igraphmodule_Graph_community_fluid_communities, + METH_VARARGS | METH_KEYWORDS, + "community_fluid_communities(no_of_communities)\n--\n\n" + "Community detection based on fluids interacting on the graph.\n\n" + "The algorithm is based on the simple idea of several fluids interacting\n" + "in a non-homogeneous environment (the graph topology), expanding and\n" + "contracting based on their interaction and density. Weighted graphs are\n" + "not supported.\n\n" + "This function implements the community detection method described in:\n" + "Parés F, Gasulla DG, et. al. (2018) Fluid Communities: A Competitive,\n" + "Scalable and Diverse Community Detection Algorithm. In: Complex Networks\n" + "& Their Applications VI: Proceedings of Complex Networks 2017 (The Sixth\n" + "International Conference on Complex Networks and Their Applications),\n" + "Springer, vol 689, p 229. https://doi.org/10.1007/978-3-319-72150-7_19\n\n" + "@param no_of_communities: The number of communities to be found. Must be\n" + " greater than 0 and fewer than number of vertices in the graph.\n" + "@return: a list with the community membership of each vertex.\n" + "@note: The graph must be simple and connected. Edge directions will be\n" + " ignored if the graph is directed.\n" + "@note: Time complexity: O(|E|)\n" + }, {"community_infomap", (PyCFunction) igraphmodule_Graph_community_infomap, METH_VARARGS | METH_KEYWORDS, @@ -18734,31 +18756,6 @@ struct PyMethodDef igraphmodule_Graph_methods[] = { " the given length (shorter if the random walk got stuck).\n" }, - - /**********************/ - /* OTHER METHODS */ - /**********************/ - {"community_fluid_communities", (PyCFunction) igraphmodule_Graph_community_fluid_communities, - METH_VARARGS | METH_KEYWORDS, - "community_fluid_communities(no_of_communities)\n--\n\n" - "Community detection based on fluids interacting on the graph.\n\n" - "The algorithm is based on the simple idea of several fluids interacting\n" - "in a non-homogeneous environment (the graph topology), expanding and\n" - "contracting based on their interaction and density. Weighted graphs are\n" - "not supported.\n\n" - "This function implements the community detection method described in:\n" - "Parés F, Gasulla DG, et. al. (2018) Fluid Communities: A Competitive,\n" - "Scalable and Diverse Community Detection Algorithm. In: Complex Networks\n" - "& Their Applications VI: Proceedings of Complex Networks 2017 (The Sixth\n" - "International Conference on Complex Networks and Their Applications),\n" - "Springer, vol 689, p 229. https://doi.org/10.1007/978-3-319-72150-7_19\n\n" - "@param no_of_communities: The number of communities to be found. Must be\n" - " greater than 0 and fewer than number of vertices in the graph.\n" - "@return: a list with the community membership of each vertex.\n" - "@note: The graph must be simple and connected. Edge directions will be\n" - " ignored if the graph is directed.\n" - "@note: Time complexity: O(|E|)\n"}, - /**********************/ /* INTERNAL FUNCTIONS */ /**********************/ From 98b4dab8e762f87ee5bbaba5da4a0fdb4fbc186e Mon Sep 17 00:00:00 2001 From: BeaMarton13 Date: Wed, 18 Jun 2025 13:45:17 +0300 Subject: [PATCH 5/8] fix: removed long type --- src/_igraph/graphobject.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/_igraph/graphobject.c b/src/_igraph/graphobject.c index e459f1e34..b4fdf257f 100644 --- a/src/_igraph/graphobject.c +++ b/src/_igraph/graphobject.c @@ -13905,18 +13905,14 @@ PyObject *igraphmodule_Graph_random_walk(igraphmodule_GraphObject * self, PyObject *igraphmodule_Graph_community_fluid_communities(igraphmodule_GraphObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"no_of_communities", NULL}; - long no_of_communities_long; - igraph_integer_t no_of_communities; + Py_ssize_t no_of_communities; igraph_vector_int_t membership; PyObject *result; // Parse the Python integer argument - if (!PyArg_ParseTupleAndKeywords(args, kwds, "l", kwlist, &no_of_communities_long)) { + if (!PyArg_ParseTupleAndKeywords(args, kwds, "n", kwlist, &no_of_communities)) { return NULL; } - - // Convert to igraph_integer_t - no_of_communities = (igraph_integer_t) no_of_communities_long; if (igraph_vector_int_init(&membership, 0)) { igraphmodule_handle_igraph_error(); From 5dd8a5b727d251929774fe586bb7f17bf5155d86 Mon Sep 17 00:00:00 2001 From: BeaMarton13 Date: Thu, 19 Jun 2025 11:13:53 +0300 Subject: [PATCH 6/8] fix: based on PR comments and reference updated --- src/_igraph/graphobject.c | 111 ++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/src/_igraph/graphobject.c b/src/_igraph/graphobject.c index b4fdf257f..63fde128f 100644 --- a/src/_igraph/graphobject.c +++ b/src/_igraph/graphobject.c @@ -13748,6 +13748,38 @@ PyObject *igraphmodule_Graph_community_leiden(igraphmodule_GraphObject *self, return error ? NULL : Py_BuildValue("Nd", res, (double) quality); } + /** + * Fluid communities + */ +PyObject *igraphmodule_Graph_community_fluid_communities(igraphmodule_GraphObject *self, + PyObject *args, PyObject *kwds) { + static char *kwlist[] = {"no_of_communities", NULL}; + Py_ssize_t no_of_communities; + igraph_vector_int_t membership; + PyObject *result; + + // Parse the Python integer argument + if (!PyArg_ParseTupleAndKeywords(args, kwds, "n", kwlist, &no_of_communities)) { + return NULL; + } + + if (igraph_vector_int_init(&membership, 0)) { + igraphmodule_handle_igraph_error(); + return NULL; + } + + if (igraph_community_fluid_communities(&self->g, no_of_communities, &membership)) { + igraphmodule_handle_igraph_error(); + igraph_vector_int_destroy(&membership); + return NULL; + } + + result = igraphmodule_vector_int_t_to_PyList(&membership); + igraph_vector_int_destroy(&membership); + + return result; +} + /********************************************************************** * Random walks * **********************************************************************/ @@ -13895,42 +13927,6 @@ PyObject *igraphmodule_Graph_random_walk(igraphmodule_GraphObject * self, } } -/********************************************************************** - * Other methods * - **********************************************************************/ - - /** - * Fluid communities - */ -PyObject *igraphmodule_Graph_community_fluid_communities(igraphmodule_GraphObject *self, - PyObject *args, PyObject *kwds) { - static char *kwlist[] = {"no_of_communities", NULL}; - Py_ssize_t no_of_communities; - igraph_vector_int_t membership; - PyObject *result; - - // Parse the Python integer argument - if (!PyArg_ParseTupleAndKeywords(args, kwds, "n", kwlist, &no_of_communities)) { - return NULL; - } - - if (igraph_vector_int_init(&membership, 0)) { - igraphmodule_handle_igraph_error(); - return NULL; - } - - if (igraph_community_fluid_communities(&self->g, no_of_communities, &membership)) { - igraphmodule_handle_igraph_error(); - igraph_vector_int_destroy(&membership); - return NULL; - } - - result = igraphmodule_vector_int_t_to_PyList(&membership); - igraph_vector_int_destroy(&membership); - - return result; -} - /********************************************************************** * Special internal methods that you won't need to mess around with * **********************************************************************/ @@ -18435,28 +18431,25 @@ struct PyMethodDef igraphmodule_Graph_methods[] = { "\n" "@see: modularity()\n" }, - {"community_fluid_communities", - (PyCFunction) igraphmodule_Graph_community_fluid_communities, - METH_VARARGS | METH_KEYWORDS, - "community_fluid_communities(no_of_communities)\n--\n\n" - "Community detection based on fluids interacting on the graph.\n\n" - "The algorithm is based on the simple idea of several fluids interacting\n" - "in a non-homogeneous environment (the graph topology), expanding and\n" - "contracting based on their interaction and density. Weighted graphs are\n" - "not supported.\n\n" - "This function implements the community detection method described in:\n" - "Parés F, Gasulla DG, et. al. (2018) Fluid Communities: A Competitive,\n" - "Scalable and Diverse Community Detection Algorithm. In: Complex Networks\n" - "& Their Applications VI: Proceedings of Complex Networks 2017 (The Sixth\n" - "International Conference on Complex Networks and Their Applications),\n" - "Springer, vol 689, p 229. https://doi.org/10.1007/978-3-319-72150-7_19\n\n" - "@param no_of_communities: The number of communities to be found. Must be\n" - " greater than 0 and fewer than number of vertices in the graph.\n" - "@return: a list with the community membership of each vertex.\n" - "@note: The graph must be simple and connected. Edge directions will be\n" - " ignored if the graph is directed.\n" - "@note: Time complexity: O(|E|)\n" - }, + {"community_fluid_communities",(PyCFunction) igraphmodule_Graph_community_fluid_communities,METH_VARARGS | METH_KEYWORDS, + "community_fluid_communities(no_of_communities)\n--\n\n" + "Community detection based on fluids interacting on the graph.\n\n" + "The algorithm is based on the simple idea of several fluids interacting\n" + "in a non-homogeneous environment (the graph topology), expanding and\n" + "contracting based on their interaction and density. Weighted graphs are\n" + "not supported.\n\n" + "B{Reference}\n\n" + " - Parés F, Gasulla DG, et. al. (2018) Fluid Communities: A Competitive,\n" + " Scalable and Diverse Community Detection Algorithm. In: Complex Networks\n" + " & Their Applications VI: Proceedings of Complex Networks 2017 (The Sixth\n" + " International Conference on Complex Networks and Their Applications),\n" + " Springer, vol 689, p 229. https://doi.org/10.1007/978-3-319-72150-7_19\n\n" + "@param no_of_communities: The number of communities to be found. Must be\n" + " greater than 0 and fewer than number of vertices in the graph.\n" + "@return: a list with the community membership of each vertex.\n" + "@note: The graph must be simple and connected. Edge directions will be\n" + " ignored if the graph is directed.\n" + "@note: Time complexity: O(|E|)\n", {"community_infomap", (PyCFunction) igraphmodule_Graph_community_infomap, METH_VARARGS | METH_KEYWORDS, @@ -18465,7 +18458,7 @@ struct PyMethodDef igraphmodule_Graph_methods[] = { "method of Martin Rosvall and Carl T. Bergstrom.\n\n" "See U{https://www.mapequation.org} for a visualization of the algorithm\n" "or one of the references provided below.\n" - "B{References}\n" + "B{Reference}: " " - M. Rosvall and C. T. Bergstrom: I{Maps of information flow reveal\n" " community structure in complex networks}. PNAS 105, 1118 (2008).\n" " U{https://arxiv.org/abs/0707.0609}\n" From f3a2cad70d862b17894a2dbeccfe41632fba1a91 Mon Sep 17 00:00:00 2001 From: BeaMarton13 Date: Thu, 19 Jun 2025 11:21:33 +0300 Subject: [PATCH 7/8] fix: errors fixed --- src/_igraph/graphobject.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/_igraph/graphobject.c b/src/_igraph/graphobject.c index 63fde128f..478b1b9d5 100644 --- a/src/_igraph/graphobject.c +++ b/src/_igraph/graphobject.c @@ -18450,6 +18450,7 @@ struct PyMethodDef igraphmodule_Graph_methods[] = { "@note: The graph must be simple and connected. Edge directions will be\n" " ignored if the graph is directed.\n" "@note: Time complexity: O(|E|)\n", + }, {"community_infomap", (PyCFunction) igraphmodule_Graph_community_infomap, METH_VARARGS | METH_KEYWORDS, From d72a35472f8254d309572d788e3d793e6f895648 Mon Sep 17 00:00:00 2001 From: BeaMarton13 Date: Thu, 19 Jun 2025 11:35:53 +0300 Subject: [PATCH 8/8] fix: format changes --- src/_igraph/graphobject.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/_igraph/graphobject.c b/src/_igraph/graphobject.c index 478b1b9d5..9f65a60d2 100644 --- a/src/_igraph/graphobject.c +++ b/src/_igraph/graphobject.c @@ -18431,7 +18431,9 @@ struct PyMethodDef igraphmodule_Graph_methods[] = { "\n" "@see: modularity()\n" }, - {"community_fluid_communities",(PyCFunction) igraphmodule_Graph_community_fluid_communities,METH_VARARGS | METH_KEYWORDS, + {"community_fluid_communities", + (PyCFunction) igraphmodule_Graph_community_fluid_communities, + METH_VARARGS | METH_KEYWORDS, "community_fluid_communities(no_of_communities)\n--\n\n" "Community detection based on fluids interacting on the graph.\n\n" "The algorithm is based on the simple idea of several fluids interacting\n"