passagemath-graphs 10.5.43__cp312-cp312-macosx_14_0_arm64.whl → 10.6.1rc2__cp312-cp312-macosx_14_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {passagemath_graphs-10.5.43.dist-info → passagemath_graphs-10.6.1rc2.dist-info}/METADATA +5 -6
- {passagemath_graphs-10.5.43.dist-info → passagemath_graphs-10.6.1rc2.dist-info}/RECORD +132 -130
- sage/combinat/abstract_tree.py +188 -17
- sage/combinat/cluster_algebra_quiver/interact.py +1 -2
- sage/combinat/cluster_algebra_quiver/mutation_type.py +518 -519
- sage/combinat/cluster_algebra_quiver/quiver.py +233 -205
- sage/combinat/designs/covering_design.py +2 -6
- sage/combinat/designs/database.py +11 -10
- sage/combinat/designs/designs_pyx.cpython-312-darwin.so +0 -0
- sage/combinat/designs/designs_pyx.pyx +2 -2
- sage/combinat/designs/evenly_distributed_sets.cpython-312-darwin.so +0 -0
- sage/combinat/designs/evenly_distributed_sets.pyx +4 -4
- sage/combinat/designs/gen_quadrangles_with_spread.cpython-312-darwin.so +0 -0
- sage/combinat/designs/latin_squares.py +53 -20
- sage/combinat/designs/orthogonal_arrays.py +2 -1
- sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-312-darwin.so +0 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +22 -21
- sage/combinat/designs/resolvable_bibd.py +191 -157
- sage/combinat/designs/subhypergraph_search.cpython-312-darwin.so +0 -0
- sage/combinat/designs/subhypergraph_search.pyx +4 -4
- sage/combinat/designs/twographs.py +2 -2
- sage/combinat/finite_state_machine.py +6 -6
- sage/combinat/posets/bubble_shuffle.py +247 -0
- sage/combinat/posets/d_complete.py +3 -3
- sage/combinat/posets/elements.py +3 -3
- sage/combinat/posets/hasse_cython.cpython-312-darwin.so +0 -0
- sage/combinat/posets/hasse_cython.pyx +1 -1
- sage/combinat/posets/hasse_diagram.py +16 -22
- sage/combinat/posets/hochschild_lattice.py +158 -0
- sage/combinat/posets/incidence_algebras.py +14 -16
- sage/combinat/posets/lattices.py +51 -53
- sage/combinat/posets/linear_extension_iterator.cpython-312-darwin.so +0 -0
- sage/combinat/posets/linear_extensions.py +10 -12
- sage/combinat/posets/moebius_algebra.py +4 -4
- sage/combinat/posets/poset_examples.py +70 -23
- sage/combinat/posets/posets.py +294 -103
- sage/databases/knotinfo_db.py +2 -1
- sage/graphs/asteroidal_triples.cpython-312-darwin.so +0 -0
- sage/graphs/asteroidal_triples.pyx +24 -3
- sage/graphs/base/boost_graph.cpython-312-darwin.so +0 -0
- sage/graphs/base/boost_graph.pxd +3 -3
- sage/graphs/base/c_graph.cpython-312-darwin.so +0 -0
- sage/graphs/base/c_graph.pyx +1 -1
- sage/graphs/base/dense_graph.cpython-312-darwin.so +0 -0
- sage/graphs/base/dense_graph.pxd +5 -3
- sage/graphs/base/dense_graph.pyx +44 -0
- sage/graphs/base/graph_backends.cpython-312-darwin.so +0 -0
- sage/graphs/base/sparse_graph.cpython-312-darwin.so +0 -0
- sage/graphs/base/static_dense_graph.cpython-312-darwin.so +0 -0
- sage/graphs/base/static_sparse_backend.cpython-312-darwin.so +0 -0
- sage/graphs/base/static_sparse_backend.pyx +8 -5
- sage/graphs/base/static_sparse_graph.cpython-312-darwin.so +0 -0
- sage/graphs/base/static_sparse_graph.pyx +86 -15
- sage/graphs/bipartite_graph.py +59 -36
- sage/graphs/centrality.cpython-312-darwin.so +0 -0
- sage/graphs/centrality.pyx +82 -9
- sage/graphs/cographs.py +1 -1
- sage/graphs/comparability.cpython-312-darwin.so +0 -0
- sage/graphs/comparability.pyx +64 -26
- sage/graphs/connectivity.cpython-312-darwin.so +0 -0
- sage/graphs/convexity_properties.cpython-312-darwin.so +0 -0
- sage/graphs/convexity_properties.pyx +52 -9
- sage/graphs/digraph.py +439 -95
- sage/graphs/digraph_generators.py +174 -102
- sage/graphs/distances_all_pairs.cpython-312-darwin.so +0 -0
- sage/graphs/dot2tex_utils.py +1 -1
- sage/graphs/edge_connectivity.cpython-312-darwin.so +0 -0
- sage/graphs/generators/basic.py +1 -1
- sage/graphs/generators/distance_regular.cpython-312-darwin.so +0 -0
- sage/graphs/generators/distance_regular.pyx +1 -1
- sage/graphs/generators/families.py +37 -27
- sage/graphs/generators/random.py +2 -2
- sage/graphs/generators/smallgraphs.py +3 -3
- sage/graphs/generic_graph.py +558 -86
- sage/graphs/generic_graph_pyx.cpython-312-darwin.so +0 -0
- sage/graphs/generic_graph_pyx.pyx +58 -11
- sage/graphs/genus.cpython-312-darwin.so +0 -0
- sage/graphs/genus.pyx +3 -4
- sage/graphs/graph.py +291 -8
- sage/graphs/graph_coloring.cpython-312-darwin.so +0 -0
- sage/graphs/graph_database.py +67 -12
- sage/graphs/graph_decompositions/bandwidth.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.pyx +24 -3
- sage/graphs/graph_decompositions/cutwidth.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.pyx +1 -1
- sage/graphs/graph_decompositions/graph_products.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/graph_products.pyx +67 -21
- sage/graphs/graph_decompositions/modular_decomposition.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.pyx +34 -8
- sage/graphs/graph_decompositions/tree_decomposition.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/vertex_separation.cpython-312-darwin.so +0 -0
- sage/graphs/graph_generators.py +45 -32
- sage/graphs/graph_generators_pyx.cpython-312-darwin.so +0 -0
- sage/graphs/graph_generators_pyx.pyx +15 -15
- sage/graphs/graph_latex.py +1 -1
- sage/graphs/graph_list.py +52 -9
- sage/graphs/graph_plot.py +7 -0
- sage/graphs/hyperbolicity.cpython-312-darwin.so +0 -0
- sage/graphs/hyperbolicity.pyx +2 -0
- sage/graphs/independent_sets.cpython-312-darwin.so +0 -0
- sage/graphs/isoperimetric_inequalities.cpython-312-darwin.so +0 -0
- sage/graphs/isoperimetric_inequalities.pyx +42 -6
- sage/graphs/line_graph.cpython-312-darwin.so +0 -0
- sage/graphs/line_graph.pyx +153 -37
- sage/graphs/matching_covered_graph.py +84 -60
- sage/graphs/orientations.py +3 -18
- sage/graphs/path_enumeration.cpython-312-darwin.so +0 -0
- sage/graphs/path_enumeration.pyx +2 -2
- sage/graphs/spanning_tree.cpython-312-darwin.so +0 -0
- sage/graphs/strongly_regular_db.cpython-312-darwin.so +0 -0
- sage/graphs/strongly_regular_db.pyx +15 -15
- sage/graphs/traversals.cpython-312-darwin.so +0 -0
- sage/graphs/traversals.pyx +13 -12
- sage/graphs/trees.cpython-312-darwin.so +0 -0
- sage/graphs/tutte_polynomial.py +1 -1
- sage/graphs/views.cpython-312-darwin.so +0 -0
- sage/graphs/weakly_chordal.cpython-312-darwin.so +0 -0
- sage/graphs/weakly_chordal.pyx +50 -8
- sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-312-darwin.so +0 -0
- sage/knots/free_knotinfo_monoid.py +3 -3
- sage/knots/knotinfo.py +102 -82
- sage/knots/link.py +72 -39
- sage/topology/cubical_complex.py +4 -5
- sage/topology/delta_complex.py +4 -4
- sage/topology/simplicial_complex.py +0 -1
- sage/topology/simplicial_complex_catalog.py +6 -0
- sage/topology/simplicial_complex_examples.py +4 -16
- {passagemath_graphs-10.5.43.dist-info → passagemath_graphs-10.6.1rc2.dist-info}/WHEEL +0 -0
- {passagemath_graphs-10.5.43.dist-info → passagemath_graphs-10.6.1rc2.dist-info}/top_level.txt +0 -0
@@ -1144,27 +1144,23 @@ class MatchingCoveredGraph(Graph):
|
|
1144
1144
|
raise ValueError('loops are not allowed in '
|
1145
1145
|
'matching covered graphs')
|
1146
1146
|
|
1147
|
-
#
|
1148
|
-
|
1147
|
+
# If (u, v, label) is a multiple edge/ an existing edge
|
1148
|
+
if self.has_edge(u, v):
|
1149
|
+
self._backend.add_edge(u, v, label, self._directed)
|
1150
|
+
return
|
1149
1151
|
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
self.__init__(data=G, matching=self.get_matching())
|
1152
|
+
# Check if there exists an M-alternating odd uv path starting and
|
1153
|
+
# ending with edges in self._matching
|
1154
|
+
from sage.graphs.matching import M_alternating_even_mark
|
1155
|
+
w = next((b if a == u else a) for a, b, *_ in self.get_matching() if u in (a, b))
|
1155
1156
|
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1157
|
+
if v in M_alternating_even_mark(self, w, self.get_matching()):
|
1158
|
+
# There exists a perfect matching containing the edge (u, v, label)
|
1159
|
+
self._backend.add_edge(u, v, label, self._directed)
|
1160
|
+
return
|
1160
1161
|
|
1161
|
-
|
1162
|
-
|
1163
|
-
# Thus, the resulting graph is either disconnected
|
1164
|
-
# or has an odd order, hence not matching covered
|
1165
|
-
raise ValueError('the graph obtained after the addition of edge '
|
1166
|
-
'(%s) is not matching covered'
|
1167
|
-
% str((u, v, label)))
|
1162
|
+
raise ValueError('the graph obtained after the addition of edge '
|
1163
|
+
'(%s) is not matching covered' % str((u, v, label)))
|
1168
1164
|
|
1169
1165
|
@doc_index('Overwritten methods')
|
1170
1166
|
def add_edges(self, edges, loops=False):
|
@@ -1180,7 +1176,8 @@ class MatchingCoveredGraph(Graph):
|
|
1180
1176
|
INPUT:
|
1181
1177
|
|
1182
1178
|
- ``edges`` -- an iterable of edges, given either as ``(u, v)``
|
1183
|
-
or ``(u, v, 'label')
|
1179
|
+
or ``(u, v, 'label')``. If an edge is provided in the format
|
1180
|
+
``(u, v)``, the label is set to ``None``.
|
1184
1181
|
|
1185
1182
|
- ``loops`` -- boolean (default: ``False``); note that this shall
|
1186
1183
|
always be set to either ``False`` or ``None`` (since matching covered
|
@@ -1188,6 +1185,9 @@ class MatchingCoveredGraph(Graph):
|
|
1188
1185
|
``(v, v, 'label')`` are removed from the iterator. If ``loops`` is
|
1189
1186
|
set to ``True``, a :exc:`ValueError` is thrown.
|
1190
1187
|
|
1188
|
+
- Please note that all the loops present in the iterator are ignored,
|
1189
|
+
provided that ``loops`` is set to ``False`` or ``None``.
|
1190
|
+
|
1191
1191
|
OUTPUT:
|
1192
1192
|
|
1193
1193
|
- If ``loops`` is set to ``True``, a :exc:`ValueError` is returned.
|
@@ -1219,7 +1219,7 @@ class MatchingCoveredGraph(Graph):
|
|
1219
1219
|
sage: G = MatchingCoveredGraph(S)
|
1220
1220
|
sage: F = [(0, 4), (2, 4), (4, 6), (4, 7)]
|
1221
1221
|
sage: G.add_edges(F)
|
1222
|
-
sage: G.edges(sort=True)
|
1222
|
+
sage: G.edges(sort=True, sort_vertices=True)
|
1223
1223
|
[(0, 1, None), (0, 3, None), (0, 4, None), (0, 6, None),
|
1224
1224
|
(1, 2, None), (1, 4, None), (2, 4, None), (2, 5, None),
|
1225
1225
|
(2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None),
|
@@ -1234,7 +1234,7 @@ class MatchingCoveredGraph(Graph):
|
|
1234
1234
|
sage: F = [(0, 9), (1, 8), (2, 9), (3, 8),
|
1235
1235
|
....: (4, 9), (5, 8), (6, 9), (7, 8)]
|
1236
1236
|
sage: G.add_edges(F)
|
1237
|
-
sage: G.edges(sort=True)
|
1237
|
+
sage: G.edges(sort=True, sort_vertices=True)
|
1238
1238
|
[(0, 1, None), (0, 7, None), (0, 9, None), (1, 2, None),
|
1239
1239
|
(1, 8, None), (2, 3, None), (2, 9, None), (3, 4, None),
|
1240
1240
|
(3, 8, None), (4, 5, None), (4, 9, None), (5, 6, None),
|
@@ -1249,7 +1249,7 @@ class MatchingCoveredGraph(Graph):
|
|
1249
1249
|
sage: F = {(0, 8, None), (1, 10), (4, 11, 'label'),
|
1250
1250
|
....: (5, 9), (8, 9), (10, 11)}
|
1251
1251
|
sage: G.add_edges(F)
|
1252
|
-
sage: G.edges(sort=True)
|
1252
|
+
sage: G.edges(sort=True, sort_vertices=True)
|
1253
1253
|
[(0, 1, None), (0, 3, None), (0, 4, None), (0, 8, None),
|
1254
1254
|
(1, 2, None), (1, 5, None), (1, 10, None), (2, 3, None),
|
1255
1255
|
(2, 6, None), (3, 7, None), (4, 5, None), (4, 7, None),
|
@@ -1295,7 +1295,7 @@ class MatchingCoveredGraph(Graph):
|
|
1295
1295
|
sage: G = MatchingCoveredGraph(W)
|
1296
1296
|
sage: F = [(0, 0), (1, 3), (2, 4)]
|
1297
1297
|
sage: G.add_edges(edges=F, loops=False)
|
1298
|
-
sage: G.edges(sort=True)
|
1298
|
+
sage: G.edges(sort=True, sort_vertices=True)
|
1299
1299
|
[(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None),
|
1300
1300
|
(0, 5, None), (1, 2, None), (1, 3, None), (1, 5, None),
|
1301
1301
|
(2, 3, None), (2, 4, None), (3, 4, None), (4, 5, None)]
|
@@ -1304,7 +1304,7 @@ class MatchingCoveredGraph(Graph):
|
|
1304
1304
|
Traceback (most recent call last):
|
1305
1305
|
...
|
1306
1306
|
ValueError: loops are not allowed in matching covered graphs
|
1307
|
-
sage: G.edges(sort=True)
|
1307
|
+
sage: G.edges(sort=True, sort_vertices=True)
|
1308
1308
|
[(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None),
|
1309
1309
|
(0, 5, None), (1, 2, None), (1, 3, None), (1, 5, None),
|
1310
1310
|
(2, 3, None), (2, 4, None), (3, 4, None), (4, 5, None)]
|
@@ -1331,9 +1331,23 @@ class MatchingCoveredGraph(Graph):
|
|
1331
1331
|
(0, 6, None), (1, 2, None), (1, 2, None), (1, 4, None),
|
1332
1332
|
(2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None),
|
1333
1333
|
(4, 5, None), (5, 7, None), (6, 7, None)]
|
1334
|
+
sage: H = [(0, 1)] * 4
|
1335
|
+
sage: G.add_edges(H)
|
1336
|
+
sage: G.edge_label(0, 1)
|
1337
|
+
[None, None, None, None, None, 'label']
|
1334
1338
|
|
1335
1339
|
TESTS:
|
1336
1340
|
|
1341
|
+
Providing with a non-iterable of edges::
|
1342
|
+
|
1343
|
+
sage: K2 = graphs.CompleteGraph(2)
|
1344
|
+
sage: G = MatchingCoveredGraph(K2)
|
1345
|
+
sage: G.add_edges(1234)
|
1346
|
+
Traceback (most recent call last):
|
1347
|
+
...
|
1348
|
+
ValueError: expected an iterable of edges,
|
1349
|
+
but got a non-iterable object
|
1350
|
+
|
1337
1351
|
Providing with an edge in ``edges`` that has 0 values to unpack::
|
1338
1352
|
|
1339
1353
|
sage: W = graphs.WagnerGraph()
|
@@ -1341,7 +1355,7 @@ class MatchingCoveredGraph(Graph):
|
|
1341
1355
|
sage: G.add_edges([()])
|
1342
1356
|
Traceback (most recent call last):
|
1343
1357
|
...
|
1344
|
-
ValueError: need more than
|
1358
|
+
ValueError: need more than 1 value to unpack for edge: ()
|
1345
1359
|
|
1346
1360
|
Providing with an edge in ``edges`` that has precisely one value to unpack::
|
1347
1361
|
|
@@ -1350,7 +1364,7 @@ class MatchingCoveredGraph(Graph):
|
|
1350
1364
|
sage: G.add_edges([(0, )])
|
1351
1365
|
Traceback (most recent call last):
|
1352
1366
|
...
|
1353
|
-
ValueError: need more than 1 value to unpack
|
1367
|
+
ValueError: need more than 1 value to unpack for edge: (0,)
|
1354
1368
|
|
1355
1369
|
Providing with an edge in ``edges`` that has more than 3 values to unpack::
|
1356
1370
|
|
@@ -1359,17 +1373,17 @@ class MatchingCoveredGraph(Graph):
|
|
1359
1373
|
sage: G.add_edges([(0, 1, 2, 3, 4)])
|
1360
1374
|
Traceback (most recent call last):
|
1361
1375
|
...
|
1362
|
-
ValueError: too many values to unpack (expected 2)
|
1376
|
+
ValueError: too many values to unpack (expected 2) for edge: (0, 1, 2, 3, 4)
|
1363
1377
|
|
1364
1378
|
Providing with an edge of unknown data type::
|
1365
1379
|
|
1366
1380
|
sage: M = graphs.MurtyGraph()
|
1367
1381
|
sage: G = MatchingCoveredGraph(M)
|
1368
|
-
sage: F = [
|
1382
|
+
sage: F = [None, 'edge', None]
|
1369
1383
|
sage: G.add_edges(F)
|
1370
1384
|
Traceback (most recent call last):
|
1371
1385
|
...
|
1372
|
-
TypeError: input
|
1386
|
+
TypeError: input edge None is of unknown type
|
1373
1387
|
"""
|
1374
1388
|
if loops:
|
1375
1389
|
raise ValueError('loops are not allowed in '
|
@@ -1378,34 +1392,44 @@ class MatchingCoveredGraph(Graph):
|
|
1378
1392
|
if not edges: # do nothing
|
1379
1393
|
return
|
1380
1394
|
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1395
|
+
from collections.abc import Iterable
|
1396
|
+
if not isinstance(edges, Iterable):
|
1397
|
+
raise ValueError('expected an iterable of edges, '
|
1398
|
+
'but got a non-iterable object')
|
1385
1399
|
|
1386
|
-
|
1387
|
-
|
1400
|
+
links = [] # to extract the nonloop input edges
|
1401
|
+
for edge in edges:
|
1402
|
+
if hasattr(edge, '__len__'):
|
1403
|
+
if len(edge) <= 1:
|
1404
|
+
raise ValueError('need more than 1 value to unpack '
|
1405
|
+
f'for edge: {edge}')
|
1388
1406
|
|
1389
1407
|
elif len(edge) > 3:
|
1390
|
-
raise ValueError('too many values to unpack (expected 2)'
|
1408
|
+
raise ValueError('too many values to unpack (expected 2) '
|
1409
|
+
f'for edge: {edge}')
|
1391
1410
|
|
1392
1411
|
else:
|
1393
|
-
raise TypeError('input
|
1412
|
+
raise TypeError(f'input edge {edge} is of unknown type')
|
1394
1413
|
|
1395
|
-
|
1396
|
-
edges = list(set(edges))
|
1414
|
+
u, v, l = None, None, None
|
1397
1415
|
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1416
|
+
if len(edge) == 2:
|
1417
|
+
u, v = edge
|
1418
|
+
else:
|
1419
|
+
u, v, l = edge
|
1402
1420
|
|
1403
|
-
|
1404
|
-
|
1421
|
+
if u != v:
|
1422
|
+
links.append((u, v, l))
|
1405
1423
|
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1424
|
+
# If each of the input edges is existent
|
1425
|
+
if (self.allows_multiple_edges()
|
1426
|
+
and all(self.has_edge(*edge) for edge in links)):
|
1427
|
+
self._backend.add_edges(links, self._directed)
|
1428
|
+
return
|
1429
|
+
|
1430
|
+
# Check if all the incident vertices of the input edges are existent
|
1431
|
+
new_vertices = {x for u, v, _ in links for x in (u, v)
|
1432
|
+
if x not in self}
|
1409
1433
|
|
1410
1434
|
# Throw error if the no. of new vertices is odd
|
1411
1435
|
if len(new_vertices) % 2:
|
@@ -1414,7 +1438,7 @@ class MatchingCoveredGraph(Graph):
|
|
1414
1438
|
|
1415
1439
|
try:
|
1416
1440
|
G = Graph(self, multiedges=self.allows_multiple_edges())
|
1417
|
-
G.add_edges(edges=
|
1441
|
+
G.add_edges(edges=links, loops=loops)
|
1418
1442
|
|
1419
1443
|
# Check if G has a vertex with at most 1 neighbor
|
1420
1444
|
if any(len(G.neighbors(v)) <= 1 for v in G):
|
@@ -1429,14 +1453,14 @@ class MatchingCoveredGraph(Graph):
|
|
1429
1453
|
else:
|
1430
1454
|
# Check if the existing perfect matching may be extended to a
|
1431
1455
|
# perfect matching of the new graph
|
1432
|
-
|
1456
|
+
links_with_two_new_vertices = []
|
1433
1457
|
|
1434
|
-
for edge in
|
1458
|
+
for edge in links:
|
1435
1459
|
if edge[0] in new_vertices and edge[1] in new_vertices:
|
1436
|
-
|
1460
|
+
links_with_two_new_vertices.append(edge)
|
1437
1461
|
|
1438
|
-
|
1439
|
-
M
|
1462
|
+
M = Graph(data=links_with_two_new_vertices, format='list_of_edges')
|
1463
|
+
M.add_edges(self.get_matching())
|
1440
1464
|
|
1441
1465
|
# Check if M is a perfect matching of the resulting graph
|
1442
1466
|
if (G.order() != 2*M.size()):
|
@@ -1706,7 +1730,7 @@ class MatchingCoveredGraph(Graph):
|
|
1706
1730
|
[{0}, {1}, {2, 3, 4}, {5}, {6}, {7}]
|
1707
1731
|
|
1708
1732
|
For a bicritical graph (for instance, the Petersen graph), the
|
1709
|
-
canonical
|
1733
|
+
canonical partition constitutes of only singleton sets each containing
|
1710
1734
|
an individual vertex::
|
1711
1735
|
|
1712
1736
|
sage: P = graphs.PetersenGraph()
|
@@ -1979,7 +2003,7 @@ class MatchingCoveredGraph(Graph):
|
|
1979
2003
|
EXAMPLES:
|
1980
2004
|
|
1981
2005
|
If one specifies a perfect matching while initializing the object, the
|
1982
|
-
value of ``self._matching`` is
|
2006
|
+
value of ``self._matching`` is the same matching::
|
1983
2007
|
|
1984
2008
|
sage: P = graphs.PetersenGraph()
|
1985
2009
|
sage: M = [(0, 1), (2, 3), (4, 9), (5, 7), (6, 8)]
|
@@ -1989,8 +2013,8 @@ class MatchingCoveredGraph(Graph):
|
|
1989
2013
|
sage: M == sorted(G.get_matching())
|
1990
2014
|
True
|
1991
2015
|
|
1992
|
-
If no matching is specified while
|
1993
|
-
a perfect is computed
|
2016
|
+
If no matching is specified while initializing a matching
|
2017
|
+
covered graph, a perfect matching is computed
|
1994
2018
|
:meth:`~sage.graphs.graph.Graph.matching` and that is captured as
|
1995
2019
|
``self._matching``::
|
1996
2020
|
|
@@ -2192,7 +2216,7 @@ class MatchingCoveredGraph(Graph):
|
|
2192
2216
|
return B
|
2193
2217
|
|
2194
2218
|
@doc_index('Overwritten methods')
|
2195
|
-
def has_loops(self):
|
2219
|
+
def has_loops(self) -> bool:
|
2196
2220
|
r"""
|
2197
2221
|
Check whether there are loops in the (matching covered) graph.
|
2198
2222
|
|
@@ -2842,7 +2866,7 @@ class MatchingCoveredGraph(Graph):
|
|
2842
2866
|
sage: G.is_brick()
|
2843
2867
|
True
|
2844
2868
|
|
2845
|
-
The triangular
|
2869
|
+
The triangular circular ladder (a graph on six vertices), aka
|
2846
2870
|
`\overline{C_6}` is a brick::
|
2847
2871
|
|
2848
2872
|
sage: C6Bar = graphs.CircularLadderGraph(3)
|
sage/graphs/orientations.py
CHANGED
@@ -188,22 +188,9 @@ def _initialize_digraph(G, edges, name=None, weighted=None, sparse=None,
|
|
188
188
|
name=name,
|
189
189
|
hash_labels=hash_labels)
|
190
190
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
for attr in attributes_to_copy:
|
195
|
-
if hasattr(G, attr):
|
196
|
-
copy_attr = {}
|
197
|
-
old_attr = getattr(G, attr)
|
198
|
-
if isinstance(old_attr, dict):
|
199
|
-
for v, value in old_attr.items():
|
200
|
-
try:
|
201
|
-
copy_attr[v] = value.copy()
|
202
|
-
except AttributeError:
|
203
|
-
copy_attr[v] = copy(value)
|
204
|
-
setattr(D, attr, copy_attr)
|
205
|
-
else:
|
206
|
-
setattr(D, attr, copy(old_attr))
|
191
|
+
# Copy attributes '_assoc' and '_embedding' if set
|
192
|
+
D._copy_attribute_from(G, '_assoc')
|
193
|
+
D._copy_attribute_from(G, '_embedding')
|
207
194
|
|
208
195
|
return D
|
209
196
|
|
@@ -559,13 +546,11 @@ def acyclic_orientations(G):
|
|
559
546
|
# A graph without edge cannot be oriented
|
560
547
|
return
|
561
548
|
|
562
|
-
from sage.rings.infinity import Infinity
|
563
549
|
from sage.combinat.subset import Subsets
|
564
550
|
|
565
551
|
def reorder_vertices(G):
|
566
552
|
n = G.order()
|
567
553
|
ko = n
|
568
|
-
k = n
|
569
554
|
G_copy = G.copy()
|
570
555
|
vertex_labels = {v: None for v in G_copy.vertices()}
|
571
556
|
|
Binary file
|
sage/graphs/path_enumeration.pyx
CHANGED
@@ -1856,7 +1856,7 @@ def all_paths_iterator(self, starting_vertices=None, ending_vertices=None,
|
|
1856
1856
|
idx_to_path[idx] = path
|
1857
1857
|
pq.push((-len(path), idx))
|
1858
1858
|
idx = idx + 1
|
1859
|
-
except
|
1859
|
+
except StopIteration:
|
1860
1860
|
pass
|
1861
1861
|
# Since we always extract a shortest path, using a heap
|
1862
1862
|
# can speed up the algorithm
|
@@ -1876,7 +1876,7 @@ def all_paths_iterator(self, starting_vertices=None, ending_vertices=None,
|
|
1876
1876
|
idx_to_path[idx] = path
|
1877
1877
|
pq.push((-len(path), idx))
|
1878
1878
|
idx = idx + 1
|
1879
|
-
except
|
1879
|
+
except StopIteration:
|
1880
1880
|
pass
|
1881
1881
|
|
1882
1882
|
|
Binary file
|
Binary file
|
@@ -958,7 +958,7 @@ def is_complete_multipartite(int v, int k, int l, int mu):
|
|
958
958
|
|
959
959
|
sage: from sage.graphs.strongly_regular_db import is_complete_multipartite
|
960
960
|
sage: t = is_complete_multipartite(12,8,4,8); t
|
961
|
-
(
|
961
|
+
(<...CompleteMultipartiteSRG...>,
|
962
962
|
3,
|
963
963
|
4)
|
964
964
|
sage: g = t[0](*t[1:]); g
|
@@ -1493,7 +1493,7 @@ def is_twograph_descendant_of_srg(int v, int k0, int l, int mu):
|
|
1493
1493
|
|
1494
1494
|
sage: from sage.graphs.strongly_regular_db import is_twograph_descendant_of_srg
|
1495
1495
|
sage: t = is_twograph_descendant_of_srg(27, 10, 1, 5); t # needs database_graphs sage.rings.finite_rings
|
1496
|
-
(
|
1496
|
+
(<...is_twograph_descendant_of_srg...>, (8,))
|
1497
1497
|
sage: g = t[0](*t[1:]); g # needs database_graphs sage.rings.finite_rings
|
1498
1498
|
descendant of complement(Johnson graph with parameters 8,2) at {0, 1}: Graph on 27 vertices
|
1499
1499
|
sage: g.is_strongly_regular(parameters=True) # needs database_graphs sage.rings.finite_rings
|
@@ -1663,9 +1663,9 @@ def is_switch_OA_srg(int v, int k, int l, int mu):
|
|
1663
1663
|
sage: t[0](*t[1:]).is_strongly_regular(parameters=True) # needs sage.schemes
|
1664
1664
|
(290, 136, 63, 64)
|
1665
1665
|
sage: is_switch_OA_srg(626, 300, 143, 144) # needs sage.schemes
|
1666
|
-
(
|
1666
|
+
(<...switch_OA_srg..., 12, 25)
|
1667
1667
|
sage: is_switch_OA_srg(842, 406, 195, 196) # needs sage.schemes
|
1668
|
-
(
|
1668
|
+
(<...switch_OA_srg..., 14, 29)
|
1669
1669
|
"""
|
1670
1670
|
cdef int n_2_p_1 = v
|
1671
1671
|
cdef int n = <int> floor(sqrt(n_2_p_1 - 1))
|
@@ -2618,8 +2618,8 @@ def SRG_630_85_20_10():
|
|
2618
2618
|
hs = HoffmanSingletonGraph()
|
2619
2619
|
P = list(range(5)) + list(range(30, 35)) # a Petersen in hs
|
2620
2620
|
mc = [0, 1, 5, 6, 12, 13, 16, 17, 22, 23, 29, 33, 39, 42, 47]
|
2621
|
-
assert
|
2622
|
-
assert
|
2621
|
+
assert hs.subgraph(mc).is_regular(k=0) # a maximum coclique
|
2622
|
+
assert hs.subgraph(P).is_regular(k=3)
|
2623
2623
|
h = hs.automorphism_group().stabilizer(mc, action='OnSets')
|
2624
2624
|
l = h.orbit(tuple((x[0], x[1]) for x in hs.subgraph(P).matching()),
|
2625
2625
|
"OnSetsSets")
|
@@ -2785,7 +2785,7 @@ def strongly_regular_graph(int v, int k, int l, int mu=-1, bint existence=False,
|
|
2785
2785
|
- ``v``, ``k``, ``l``, ``mu`` -- ``integers`` -- note that ``mu``, if unspecified, is
|
2786
2786
|
automatically determined from ``v``, ``k``, ``l``
|
2787
2787
|
|
2788
|
-
- ``existence`` -- boolean
|
2788
|
+
- ``existence`` -- boolean (default: ``False``); instead of building the graph,
|
2789
2789
|
return:
|
2790
2790
|
|
2791
2791
|
- ``True`` -- meaning that a `(v,k,\lambda,\mu)`-strongly regular graph
|
@@ -2923,21 +2923,21 @@ def strongly_regular_graph_lazy(int v, int k, int l, int mu=-1, bint existence=F
|
|
2923
2923
|
sage: # needs database_graphs
|
2924
2924
|
sage: from sage.graphs.strongly_regular_db import strongly_regular_graph_lazy
|
2925
2925
|
sage: g,p=strongly_regular_graph_lazy(10,6,3); g,p
|
2926
|
-
(
|
2926
|
+
(<...is_johnson...>, 5)
|
2927
2927
|
sage: g(p)
|
2928
2928
|
Johnson graph with parameters 5,2: Graph on 10 vertices
|
2929
2929
|
sage: g,p=strongly_regular_graph_lazy(10,3,0,1); g,p
|
2930
|
-
(
|
2930
|
+
(<...strongly_regular_graph_lazy...>,
|
2931
2931
|
(5,))
|
2932
2932
|
sage: g(p)
|
2933
2933
|
complement(Johnson graph with parameters 5,2): Graph on 10 vertices
|
2934
2934
|
sage: g,p=strongly_regular_graph_lazy(12,3,2); g,p
|
2935
|
-
(
|
2935
|
+
(<...strongly_regular_graph_lazy...>,
|
2936
2936
|
(3, 4))
|
2937
2937
|
sage: g(p)
|
2938
2938
|
complement(Multipartite Graph with set sizes [4, 4, 4]): Graph on 12 vertices
|
2939
2939
|
sage: g = strongly_regular_graph_lazy(539,250,105); g # needs sage.combinat sage.modules
|
2940
|
-
(
|
2940
|
+
(<...is_twograph_descendant_of_srg...>,
|
2941
2941
|
5,
|
2942
2942
|
11)
|
2943
2943
|
sage: g[0](*g[1:]) # needs sage.combinat sage.modules
|
@@ -3299,11 +3299,11 @@ def _check_database():
|
|
3299
3299
|
if _brouwer_database[params]['status'] != "impossible":
|
3300
3300
|
raise RuntimeError("Brouwer's db does not seem to know that {} in unfeasible".format(params))
|
3301
3301
|
comment = _brouwer_database[params]['comments']
|
3302
|
-
if ('Krein'
|
3302
|
+
if ('Krein' in comment or
|
3303
3303
|
'Absolute' in comment or
|
3304
|
-
'Conf'
|
3305
|
-
'mu=1'
|
3306
|
-
'μ=2'
|
3304
|
+
'Conf' in comment or
|
3305
|
+
'mu=1' in comment or
|
3306
|
+
'μ=2' in comment):
|
3307
3307
|
continue
|
3308
3308
|
raise RuntimeError("We detected that {} was unfeasible, but maybe we should not have".format(params))
|
3309
3309
|
|
Binary file
|
sage/graphs/traversals.pyx
CHANGED
@@ -63,7 +63,6 @@ Methods
|
|
63
63
|
|
64
64
|
from collections import deque
|
65
65
|
|
66
|
-
from libc.string cimport memset
|
67
66
|
from libc.stdint cimport uint32_t
|
68
67
|
from libcpp.vector cimport vector
|
69
68
|
from cysignals.signals cimport sig_on, sig_off
|
@@ -75,7 +74,6 @@ from sage.graphs.base.static_sparse_backend cimport StaticSparseCGraph
|
|
75
74
|
from sage.graphs.base.static_sparse_backend cimport StaticSparseBackend
|
76
75
|
from sage.graphs.base.static_sparse_graph cimport init_short_digraph
|
77
76
|
from sage.graphs.base.static_sparse_graph cimport free_short_digraph
|
78
|
-
from sage.graphs.base.static_sparse_graph cimport out_degree
|
79
77
|
from sage.graphs.graph_decompositions.slice_decomposition cimport \
|
80
78
|
extended_lex_BFS
|
81
79
|
|
@@ -465,6 +463,14 @@ def lex_BFS(G, reverse=False, tree=False, initial_vertex=None, algorithm="fast")
|
|
465
463
|
Traceback (most recent call last):
|
466
464
|
...
|
467
465
|
ValueError: 'foo' is not a graph vertex
|
466
|
+
|
467
|
+
Check that :issue:`39934` is fixed::
|
468
|
+
|
469
|
+
sage: G = Graph(1, immutable=True)
|
470
|
+
sage: G.lex_BFS(algorithm='slow')
|
471
|
+
[0]
|
472
|
+
sage: G.lex_BFS(algorithm='fast')
|
473
|
+
[0]
|
468
474
|
"""
|
469
475
|
if initial_vertex is not None and initial_vertex not in G:
|
470
476
|
raise ValueError(f"'{initial_vertex}' is not a graph vertex")
|
@@ -475,22 +481,15 @@ def lex_BFS(G, reverse=False, tree=False, initial_vertex=None, algorithm="fast")
|
|
475
481
|
if algorithm != "fast":
|
476
482
|
raise ValueError(f"unknown algorithm '{algorithm}'")
|
477
483
|
|
478
|
-
cdef size_t n = G.order()
|
479
|
-
|
480
484
|
# For algorithm "fast" we need to convert G to an undirected graph
|
481
485
|
if G.is_directed():
|
482
486
|
G = G.to_undirected()
|
483
487
|
|
484
|
-
# Initialize variables needed by the fast
|
488
|
+
# Initialize variables needed by the fast algorithm
|
485
489
|
cdef CGraphBackend Gbackend = <CGraphBackend> G._backend
|
486
490
|
cdef CGraph cg = Gbackend.cg()
|
487
|
-
cdef list sigma = []
|
488
|
-
cdef dict predecessor = {}
|
489
|
-
# Initialize variables needed by the fast algorithm
|
490
491
|
cdef vector[int] sigma_int
|
491
492
|
cdef vector[int] pred
|
492
|
-
# Initialize variables needed by the slow algorithm
|
493
|
-
cdef dict lexicographic_label
|
494
493
|
# Temporary variables
|
495
494
|
cdef int vi, i, initial_v_int
|
496
495
|
|
@@ -500,9 +499,11 @@ def lex_BFS(G, reverse=False, tree=False, initial_vertex=None, algorithm="fast")
|
|
500
499
|
initial_v_int = Gbackend.get_vertex(initial_vertex)
|
501
500
|
else:
|
502
501
|
initial_v_int = -1
|
502
|
+
sig_on()
|
503
503
|
extended_lex_BFS(cg, sigma_int, NULL, initial_v_int, &pred, NULL, NULL)
|
504
|
-
|
505
|
-
|
504
|
+
sig_off()
|
505
|
+
cdef list sigma = [Gbackend.vertex_label(vi) for vi in sigma_int]
|
506
|
+
cdef dict predecessor = {u: sigma[i] for u, i in zip(sigma, pred) if i != -1}
|
506
507
|
|
507
508
|
if reverse:
|
508
509
|
sigma.reverse()
|
Binary file
|
sage/graphs/tutte_polynomial.py
CHANGED
@@ -663,7 +663,7 @@ def _tutte_polynomial_internal(G, x, y, edge_selector, cache=None):
|
|
663
663
|
##################################
|
664
664
|
|
665
665
|
# Theorem 4: from Haggard, Pearce, and Royle Note that the formula
|
666
|
-
# at http://homepages.ecs.vuw.ac.nz/~djp/files/TOMS10.pdf is
|
666
|
+
# at https://web.archive.org/web/20110401195911/http://homepages.ecs.vuw.ac.nz/~djp/files/TOMS10.pdf is
|
667
667
|
# slightly incorrect. The initial sum should only go to n-2
|
668
668
|
# instead of n (allowing for the last part of the recursion).
|
669
669
|
# Additionally, the first operand of the final product should be
|
Binary file
|
Binary file
|