diff --git a/src/_igraph/graphobject.c b/src/_igraph/graphobject.c index e5bef73b3..5887e751f 100644 --- a/src/_igraph/graphobject.c +++ b/src/_igraph/graphobject.c @@ -3563,24 +3563,22 @@ PyObject *igraphmodule_Graph_SBM(PyTypeObject * type, { igraphmodule_GraphObject *self; igraph_t g; - Py_ssize_t n; PyObject *block_sizes_o, *pref_matrix_o; PyObject *directed_o = Py_False; PyObject *loops_o = Py_False; + PyObject *multiple_o = Py_False; igraph_matrix_t pref_matrix; igraph_vector_int_t block_sizes; - static char *kwlist[] = { "n", "pref_matrix", "block_sizes", "directed", - "loops", NULL }; + static char *kwlist[] = { "pref_matrix", "block_sizes", "directed", + "loops", "multiple", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "nOO|OO", kwlist, - &n, &pref_matrix_o, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|OOO", kwlist, + &pref_matrix_o, &block_sizes_o, - &directed_o, &loops_o)) + &directed_o, &loops_o, &multiple_o)) return NULL; - CHECK_SSIZE_T_RANGE(n, "vertex count"); - if (igraphmodule_PyObject_to_matrix_t(pref_matrix_o, &pref_matrix, "pref_matrix")) { return NULL; } @@ -3590,7 +3588,7 @@ PyObject *igraphmodule_Graph_SBM(PyTypeObject * type, return NULL; } - if (igraph_sbm_game(&g, n, &pref_matrix, &block_sizes, PyObject_IsTrue(directed_o), PyObject_IsTrue(loops_o))) { + if (igraph_sbm_game(&g, &pref_matrix, &block_sizes, PyObject_IsTrue(directed_o), PyObject_IsTrue(loops_o), PyObject_IsTrue(multiple_o))) { igraphmodule_handle_igraph_error(); igraph_matrix_destroy(&pref_matrix); igraph_vector_int_destroy(&block_sizes); @@ -14754,19 +14752,19 @@ struct PyMethodDef igraphmodule_Graph_methods[] = { METH_VARARGS | METH_CLASS | METH_KEYWORDS, "SBM(n, pref_matrix, block_sizes, directed=False, loops=False)\n--\n\n" "Generates a graph based on a stochastic block model.\n\n" - "A given number of vertices are generated. Every vertex is assigned to a\n" - "vertex type according to the given block sizes. Vertices of the same\n" + "Every vertex is assigned to a vertex type according to the given block\n" + "sizes, which also determine the total vertex count. Vertices of the same\n" "type will be assigned consecutive vertex IDs. Finally, every\n" "vertex pair is evaluated and an edge is created between them with a\n" "probability depending on the types of the vertices involved. The\n" "probabilities are taken from the preference matrix.\n\n" - "@param n: the number of vertices in the graph\n" - "@param pref_matrix: matrix giving the connection probabilities for\n" - " different vertex types.\n" + "@param pref_matrix: matrix giving the connection probabilities (or expected\n" + " edge multiplicities for multigraphs) between different vertex types.\n" "@param block_sizes: list giving the number of vertices in each block; must\n" " sum up to I{n}.\n" "@param directed: whether to generate a directed graph.\n" - "@param loops: whether loop edges are allowed.\n"}, + "@param loops: whether loop edges are allowed.\n" + "@param multiple: whether multi-edges are allowed.\n"}, // interface to igraph_star {"Star", (PyCFunction) igraphmodule_Graph_Star, diff --git a/tests/test_generators.py b/tests/test_generators.py index bfb1c4e23..675de880a 100644 --- a/tests/test_generators.py +++ b/tests/test_generators.py @@ -429,9 +429,8 @@ def testLattice(self): def testSBM(self): pref_matrix = [[0.5, 0, 0], [0, 0, 0.5], [0, 0.5, 0]] - n = 60 types = [20, 20, 20] - g = Graph.SBM(n, pref_matrix, types) + g = Graph.SBM(pref_matrix, types) # Simple smoke tests for the expected structure of the graph self.assertTrue(g.is_simple()) @@ -441,21 +440,19 @@ def testSBM(self): self.assertTrue(not any(e.source // 20 == e.target // 20 for e in g2.es)) # Check loops argument - g = Graph.SBM(n, pref_matrix, types, loops=True) + g = Graph.SBM(pref_matrix, types, loops=True) self.assertFalse(g.is_simple()) self.assertTrue(sum(g.is_loop()) > 0) # Check directedness - g = Graph.SBM(n, pref_matrix, types, directed=True) + g = Graph.SBM(pref_matrix, types, directed=True) self.assertTrue(g.is_directed()) self.assertTrue(sum(g.is_mutual()) < g.ecount()) self.assertTrue(sum(g.is_loop()) == 0) # Check error conditions - self.assertRaises(ValueError, Graph.SBM, -1, pref_matrix, types) - self.assertRaises(InternalError, Graph.SBM, 61, pref_matrix, types) pref_matrix[0][1] = 0.7 - self.assertRaises(InternalError, Graph.SBM, 60, pref_matrix, types) + self.assertRaises(InternalError, Graph.SBM, pref_matrix, types) def testTriangularLattice(self): g = Graph.Triangular_Lattice([2, 2]) diff --git a/vendor/source/igraph b/vendor/source/igraph index be53d68e0..be8bc7d25 160000 --- a/vendor/source/igraph +++ b/vendor/source/igraph @@ -1 +1 @@ -Subproject commit be53d68e08548f3d299cc7bd6bfcfd7b2ea532b4 +Subproject commit be8bc7d25411da63414743ec16bf20022f4b7bab