passagemath-graphs 10.5.43__cp311-cp311-macosx_14_0_arm64.whl → 10.6.1rc2__cp311-cp311-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.
Files changed (132) hide show
  1. {passagemath_graphs-10.5.43.dist-info → passagemath_graphs-10.6.1rc2.dist-info}/METADATA +5 -6
  2. {passagemath_graphs-10.5.43.dist-info → passagemath_graphs-10.6.1rc2.dist-info}/RECORD +132 -130
  3. sage/combinat/abstract_tree.py +188 -17
  4. sage/combinat/cluster_algebra_quiver/interact.py +1 -2
  5. sage/combinat/cluster_algebra_quiver/mutation_type.py +518 -519
  6. sage/combinat/cluster_algebra_quiver/quiver.py +233 -205
  7. sage/combinat/designs/covering_design.py +2 -6
  8. sage/combinat/designs/database.py +11 -10
  9. sage/combinat/designs/designs_pyx.cpython-311-darwin.so +0 -0
  10. sage/combinat/designs/designs_pyx.pyx +2 -2
  11. sage/combinat/designs/evenly_distributed_sets.cpython-311-darwin.so +0 -0
  12. sage/combinat/designs/evenly_distributed_sets.pyx +4 -4
  13. sage/combinat/designs/gen_quadrangles_with_spread.cpython-311-darwin.so +0 -0
  14. sage/combinat/designs/latin_squares.py +53 -20
  15. sage/combinat/designs/orthogonal_arrays.py +2 -1
  16. sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-311-darwin.so +0 -0
  17. sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +22 -21
  18. sage/combinat/designs/resolvable_bibd.py +191 -157
  19. sage/combinat/designs/subhypergraph_search.cpython-311-darwin.so +0 -0
  20. sage/combinat/designs/subhypergraph_search.pyx +4 -4
  21. sage/combinat/designs/twographs.py +2 -2
  22. sage/combinat/finite_state_machine.py +6 -6
  23. sage/combinat/posets/bubble_shuffle.py +247 -0
  24. sage/combinat/posets/d_complete.py +3 -3
  25. sage/combinat/posets/elements.py +3 -3
  26. sage/combinat/posets/hasse_cython.cpython-311-darwin.so +0 -0
  27. sage/combinat/posets/hasse_cython.pyx +1 -1
  28. sage/combinat/posets/hasse_diagram.py +16 -22
  29. sage/combinat/posets/hochschild_lattice.py +158 -0
  30. sage/combinat/posets/incidence_algebras.py +14 -16
  31. sage/combinat/posets/lattices.py +51 -53
  32. sage/combinat/posets/linear_extension_iterator.cpython-311-darwin.so +0 -0
  33. sage/combinat/posets/linear_extensions.py +10 -12
  34. sage/combinat/posets/moebius_algebra.py +4 -4
  35. sage/combinat/posets/poset_examples.py +70 -23
  36. sage/combinat/posets/posets.py +294 -103
  37. sage/databases/knotinfo_db.py +2 -1
  38. sage/graphs/asteroidal_triples.cpython-311-darwin.so +0 -0
  39. sage/graphs/asteroidal_triples.pyx +24 -3
  40. sage/graphs/base/boost_graph.cpython-311-darwin.so +0 -0
  41. sage/graphs/base/boost_graph.pxd +3 -3
  42. sage/graphs/base/c_graph.cpython-311-darwin.so +0 -0
  43. sage/graphs/base/c_graph.pyx +1 -1
  44. sage/graphs/base/dense_graph.cpython-311-darwin.so +0 -0
  45. sage/graphs/base/dense_graph.pxd +5 -3
  46. sage/graphs/base/dense_graph.pyx +44 -0
  47. sage/graphs/base/graph_backends.cpython-311-darwin.so +0 -0
  48. sage/graphs/base/sparse_graph.cpython-311-darwin.so +0 -0
  49. sage/graphs/base/static_dense_graph.cpython-311-darwin.so +0 -0
  50. sage/graphs/base/static_sparse_backend.cpython-311-darwin.so +0 -0
  51. sage/graphs/base/static_sparse_backend.pyx +8 -5
  52. sage/graphs/base/static_sparse_graph.cpython-311-darwin.so +0 -0
  53. sage/graphs/base/static_sparse_graph.pyx +86 -15
  54. sage/graphs/bipartite_graph.py +59 -36
  55. sage/graphs/centrality.cpython-311-darwin.so +0 -0
  56. sage/graphs/centrality.pyx +82 -9
  57. sage/graphs/cographs.py +1 -1
  58. sage/graphs/comparability.cpython-311-darwin.so +0 -0
  59. sage/graphs/comparability.pyx +64 -26
  60. sage/graphs/connectivity.cpython-311-darwin.so +0 -0
  61. sage/graphs/convexity_properties.cpython-311-darwin.so +0 -0
  62. sage/graphs/convexity_properties.pyx +52 -9
  63. sage/graphs/digraph.py +439 -95
  64. sage/graphs/digraph_generators.py +174 -102
  65. sage/graphs/distances_all_pairs.cpython-311-darwin.so +0 -0
  66. sage/graphs/dot2tex_utils.py +1 -1
  67. sage/graphs/edge_connectivity.cpython-311-darwin.so +0 -0
  68. sage/graphs/generators/basic.py +1 -1
  69. sage/graphs/generators/distance_regular.cpython-311-darwin.so +0 -0
  70. sage/graphs/generators/distance_regular.pyx +1 -1
  71. sage/graphs/generators/families.py +37 -27
  72. sage/graphs/generators/random.py +2 -2
  73. sage/graphs/generators/smallgraphs.py +3 -3
  74. sage/graphs/generic_graph.py +558 -86
  75. sage/graphs/generic_graph_pyx.cpython-311-darwin.so +0 -0
  76. sage/graphs/generic_graph_pyx.pyx +58 -11
  77. sage/graphs/genus.cpython-311-darwin.so +0 -0
  78. sage/graphs/genus.pyx +3 -4
  79. sage/graphs/graph.py +291 -8
  80. sage/graphs/graph_coloring.cpython-311-darwin.so +0 -0
  81. sage/graphs/graph_database.py +67 -12
  82. sage/graphs/graph_decompositions/bandwidth.cpython-311-darwin.so +0 -0
  83. sage/graphs/graph_decompositions/clique_separators.cpython-311-darwin.so +0 -0
  84. sage/graphs/graph_decompositions/clique_separators.pyx +24 -3
  85. sage/graphs/graph_decompositions/cutwidth.cpython-311-darwin.so +0 -0
  86. sage/graphs/graph_decompositions/fast_digraph.cpython-311-darwin.so +0 -0
  87. sage/graphs/graph_decompositions/fast_digraph.pyx +1 -1
  88. sage/graphs/graph_decompositions/graph_products.cpython-311-darwin.so +0 -0
  89. sage/graphs/graph_decompositions/graph_products.pyx +67 -21
  90. sage/graphs/graph_decompositions/modular_decomposition.cpython-311-darwin.so +0 -0
  91. sage/graphs/graph_decompositions/slice_decomposition.cpython-311-darwin.so +0 -0
  92. sage/graphs/graph_decompositions/slice_decomposition.pyx +34 -8
  93. sage/graphs/graph_decompositions/tree_decomposition.cpython-311-darwin.so +0 -0
  94. sage/graphs/graph_decompositions/vertex_separation.cpython-311-darwin.so +0 -0
  95. sage/graphs/graph_generators.py +45 -32
  96. sage/graphs/graph_generators_pyx.cpython-311-darwin.so +0 -0
  97. sage/graphs/graph_generators_pyx.pyx +15 -15
  98. sage/graphs/graph_latex.py +1 -1
  99. sage/graphs/graph_list.py +52 -9
  100. sage/graphs/graph_plot.py +7 -0
  101. sage/graphs/hyperbolicity.cpython-311-darwin.so +0 -0
  102. sage/graphs/hyperbolicity.pyx +2 -0
  103. sage/graphs/independent_sets.cpython-311-darwin.so +0 -0
  104. sage/graphs/isoperimetric_inequalities.cpython-311-darwin.so +0 -0
  105. sage/graphs/isoperimetric_inequalities.pyx +42 -6
  106. sage/graphs/line_graph.cpython-311-darwin.so +0 -0
  107. sage/graphs/line_graph.pyx +153 -37
  108. sage/graphs/matching_covered_graph.py +84 -60
  109. sage/graphs/orientations.py +3 -18
  110. sage/graphs/path_enumeration.cpython-311-darwin.so +0 -0
  111. sage/graphs/path_enumeration.pyx +2 -2
  112. sage/graphs/spanning_tree.cpython-311-darwin.so +0 -0
  113. sage/graphs/strongly_regular_db.cpython-311-darwin.so +0 -0
  114. sage/graphs/strongly_regular_db.pyx +15 -15
  115. sage/graphs/traversals.cpython-311-darwin.so +0 -0
  116. sage/graphs/traversals.pyx +13 -12
  117. sage/graphs/trees.cpython-311-darwin.so +0 -0
  118. sage/graphs/tutte_polynomial.py +1 -1
  119. sage/graphs/views.cpython-311-darwin.so +0 -0
  120. sage/graphs/weakly_chordal.cpython-311-darwin.so +0 -0
  121. sage/graphs/weakly_chordal.pyx +50 -8
  122. sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-311-darwin.so +0 -0
  123. sage/knots/free_knotinfo_monoid.py +3 -3
  124. sage/knots/knotinfo.py +102 -82
  125. sage/knots/link.py +72 -39
  126. sage/topology/cubical_complex.py +4 -5
  127. sage/topology/delta_complex.py +4 -4
  128. sage/topology/simplicial_complex.py +0 -1
  129. sage/topology/simplicial_complex_catalog.py +6 -0
  130. sage/topology/simplicial_complex_examples.py +4 -16
  131. {passagemath_graphs-10.5.43.dist-info → passagemath_graphs-10.6.1rc2.dist-info}/WHEEL +0 -0
  132. {passagemath_graphs-10.5.43.dist-info → passagemath_graphs-10.6.1rc2.dist-info}/top_level.txt +0 -0
@@ -28,7 +28,10 @@ AUTHORS:
28
28
  - Gregg Musiker
29
29
  - Christian Stump
30
30
 
31
- .. SEEALSO:: For mutation types of combinatorial quivers, see :meth:`~sage.combinat.cluster_algebra_quiver.quiver_mutation_type.QuiverMutationType`. Cluster seeds are closely related to :meth:`~sage.combinat.cluster_algebra_quiver.cluster_seed.ClusterSeed`.
31
+ .. SEEALSO::
32
+
33
+ For mutation types of combinatorial quivers, see :meth:`~sage.combinat.cluster_algebra_quiver.quiver_mutation_type.QuiverMutationType`.
34
+ Cluster seeds are closely related to :meth:`~sage.combinat.cluster_algebra_quiver.cluster_seed.ClusterSeed`.
32
35
  """
33
36
  # ****************************************************************************
34
37
  # Copyright (C) 2011 Gregg Musiker <musiker@math.mit.edu>
@@ -40,22 +43,21 @@ AUTHORS:
40
43
  from copy import copy
41
44
  from itertools import product
42
45
 
43
- from sage.structure.sage_object import SageObject
44
- from sage.rings.integer_ring import ZZ
45
- from sage.rings.infinity import infinity
46
- from sage.graphs.digraph import DiGraph
47
- from sage.graphs.graph import Graph
48
- from sage.graphs.views import EdgesView
49
46
  from sage.arith.misc import gcd
50
- from sage.misc.misc_c import prod
51
- from sage.misc.lazy_import import lazy_import
52
- from sage.rings.rational_field import QQ
53
- from sage.rings.polynomial.polynomial_ring import polygen
54
47
  from sage.combinat.cluster_algebra_quiver.quiver_mutation_type import QuiverMutationType, QuiverMutationType_Irreducible, QuiverMutationType_Reducible, _edge_list_to_matrix
55
48
  from sage.combinat.cluster_algebra_quiver.mutation_class import _principal_part, _digraph_mutate, _matrix_to_digraph, _dg_canonical_form, _mutation_class_iter, _digraph_to_dig6, _dig6_to_matrix
56
49
  from sage.combinat.cluster_algebra_quiver.mutation_type import _connected_mutation_type, _mutation_type_from_data, is_mutation_finite
57
-
58
50
  from sage.combinat.cluster_algebra_quiver.interact import cluster_interact
51
+ from sage.graphs.digraph import DiGraph
52
+ from sage.graphs.graph import Graph
53
+ from sage.graphs.views import EdgesView
54
+ from sage.misc.lazy_import import lazy_import
55
+ from sage.misc.misc_c import prod
56
+ from sage.rings.infinity import infinity
57
+ from sage.rings.integer_ring import ZZ
58
+ from sage.rings.polynomial.polynomial_ring import polygen
59
+ from sage.rings.rational_field import QQ
60
+ from sage.structure.sage_object import SageObject
59
61
 
60
62
  lazy_import('sage.modules.free_module_element', 'vector')
61
63
  lazy_import('sage.matrix.constructor', 'matrix')
@@ -69,12 +71,18 @@ class ClusterQuiver(SageObject):
69
71
 
70
72
  - ``data`` -- can be any of the following::
71
73
 
72
- * :class:`QuiverMutationType`
73
- * :class:`str` -- string representing a :class:`QuiverMutationType` or a common quiver type (see Examples)
74
- * :class:`ClusterQuiver`
75
- * :class:`Matrix` -- a skew-symmetrizable matrix
76
- * :class:`DiGraph` -- must be the input data for a quiver
77
- * List of edges -- must be the edge list of a digraph for a quiver
74
+ - :class:`QuiverMutationType`
75
+
76
+ - :class:`str` -- string representing a :class:`QuiverMutationType`
77
+ or a common quiver type (see Examples)
78
+
79
+ - :class:`ClusterQuiver`
80
+
81
+ - :class:`Matrix` -- a skew-symmetrizable matrix
82
+
83
+ - :class:`DiGraph` -- must be the input data for a quiver
84
+
85
+ - List of edges -- must be the edge list of a digraph for a quiver
78
86
 
79
87
  - ``frozen`` -- (default: ``None``) sets the list of frozen variables
80
88
  if the input type is a :class:`DiGraph`, it is ignored otherwise
@@ -148,30 +156,30 @@ class ClusterQuiver(SageObject):
148
156
 
149
157
  sage: Q = ClusterQuiver(['A',[2,5],1]); Q
150
158
  Quiver on 7 vertices of type ['A', [2, 5], 1]
151
- sage: T = ClusterQuiver( Q ); T
159
+ sage: T = ClusterQuiver(Q); T
152
160
  Quiver on 7 vertices of type ['A', [2, 5], 1]
153
161
 
154
162
  From a Matrix::
155
163
 
156
164
  sage: Q = ClusterQuiver(['A',[2,5],1]); Q
157
165
  Quiver on 7 vertices of type ['A', [2, 5], 1]
158
- sage: T = ClusterQuiver( Q._M ); T
166
+ sage: T = ClusterQuiver(Q._M); T
159
167
  Quiver on 7 vertices
160
168
 
161
- sage: Q = ClusterQuiver( matrix([[0,1,-1],[-1,0,1],[1,-1,0],[1,2,3]]) ); Q
169
+ sage: Q = ClusterQuiver(matrix([[0,1,-1],[-1,0,1],[1,-1,0],[1,2,3]])); Q
162
170
  Quiver on 4 vertices with 1 frozen vertex
163
171
 
164
- sage: Q = ClusterQuiver( matrix([]) ); Q
172
+ sage: Q = ClusterQuiver(matrix([])); Q
165
173
  Quiver without vertices
166
174
 
167
175
  From a DiGraph::
168
176
 
169
177
  sage: Q = ClusterQuiver(['A',[2,5],1]); Q
170
178
  Quiver on 7 vertices of type ['A', [2, 5], 1]
171
- sage: T = ClusterQuiver( Q._digraph ); T
179
+ sage: T = ClusterQuiver(Q._digraph); T
172
180
  Quiver on 7 vertices
173
181
 
174
- sage: Q = ClusterQuiver( DiGraph([[1,2],[2,3],[3,4],[4,1]]) ); Q
182
+ sage: Q = ClusterQuiver(DiGraph([[1,2],[2,3],[3,4],[4,1]])); Q
175
183
  Quiver on 4 vertices
176
184
 
177
185
  sage: Q = ClusterQuiver(DiGraph([['a', 'b'], ['b', 'c'], ['c', 'd'], ['d', 'e']]),
@@ -180,13 +188,14 @@ class ClusterQuiver(SageObject):
180
188
  sage: Q.mutation_type()
181
189
  [ ['A', 2], ['A', 2] ]
182
190
  sage: Q
183
- Quiver on 5 vertices of type [ ['A', 2], ['A', 2] ] with 1 frozen vertex
191
+ Quiver on 5 vertices of type [ ['A', 2], ['A', 2] ]
192
+ with 1 frozen vertex
184
193
 
185
194
  From a List of edges::
186
195
 
187
196
  sage: Q = ClusterQuiver(['A',[2,5],1]); Q
188
197
  Quiver on 7 vertices of type ['A', [2, 5], 1]
189
- sage: T = ClusterQuiver( Q._digraph.edges(sort=True) ); T
198
+ sage: T = ClusterQuiver(Q._digraph.edges(sort=True)); T
190
199
  Quiver on 7 vertices
191
200
 
192
201
  sage: Q = ClusterQuiver([[1, 2], [2, 3], [3, 4], [4, 1]]); Q
@@ -215,7 +224,7 @@ class ClusterQuiver(SageObject):
215
224
  ValueError: the input data was not recognized
216
225
  """
217
226
 
218
- def __init__(self, data, frozen=None, user_labels=None):
227
+ def __init__(self, data, frozen=None, user_labels=None) -> None:
219
228
  """
220
229
  TESTS::
221
230
 
@@ -226,11 +235,12 @@ class ClusterQuiver(SageObject):
226
235
  from sage.structure.element import Matrix
227
236
 
228
237
  if isinstance(user_labels, list):
229
- user_labels = [tuple(x) if isinstance(x, list) else x for x in user_labels]
238
+ user_labels = [tuple(x) if isinstance(x, list) else x
239
+ for x in user_labels]
230
240
  elif isinstance(user_labels, dict):
231
- values = [tuple(user_labels[x]) if isinstance(user_labels[x], list) else user_labels[x] for x in user_labels]
232
- user_labels = dict(zip(user_labels.keys(),
233
- values))
241
+ user_labels = {x: tuple(label) if isinstance(label, list)
242
+ else label
243
+ for x, label in user_labels.items()}
234
244
 
235
245
  # constructs a quiver from a mutation type
236
246
  if isinstance(data, (QuiverMutationType_Irreducible,
@@ -241,7 +251,7 @@ class ClusterQuiver(SageObject):
241
251
  ' Use set_frozen to freeze vertices.')
242
252
 
243
253
  mutation_type = data
244
- self.__init__( mutation_type.standard_quiver() )
254
+ self.__init__(mutation_type.standard_quiver())
245
255
  if user_labels:
246
256
  self.relabel(user_labels)
247
257
  self._nlist = list(user_labels)
@@ -251,9 +261,10 @@ class ClusterQuiver(SageObject):
251
261
  # NOTE: for now, any string representing a *reducible type* is
252
262
  # coerced into the standard quiver, but there is now more flexibility
253
263
  # in how to input a connected (irreducible) quiver.
254
- elif (isinstance(data, (list,tuple))
255
- and (isinstance(data[0], str) or all(isinstance(comp, (list,tuple))
256
- and isinstance(comp[0], str) for comp in data))):
264
+ elif (isinstance(data, (list, tuple))
265
+ and (isinstance(data[0], str) or
266
+ all(isinstance(comp, (list, tuple))
267
+ and isinstance(comp[0], str) for comp in data))):
257
268
  if frozen is not None:
258
269
  print('The input specifies a mutation type, so the additional'
259
270
  ' parameter frozen is ignored. Use set_frozen to freeze vertices.')
@@ -265,50 +276,54 @@ class ClusterQuiver(SageObject):
265
276
  # format the input appropriately. Thus we handle several
266
277
  # special cases this way.
267
278
  if len(data) == 2 and isinstance(data[0], str):
268
- if data[0] == 'TR' or data[0] == 'GR' or (data[0] == 'C' and data[1] == 2):
269
- if data[1] in ZZ:
270
- quiv = ClusterQuiver( QuiverMutationType_Irreducible( data[0], data[1] )._digraph )
279
+ d0, d1 = data
280
+ if d0 == 'TR' or d0 == 'GR' or (d0 == 'C' and d1 == 2):
281
+ if d1 in ZZ:
282
+ quiv = ClusterQuiver(QuiverMutationType_Irreducible(d0, d1)._digraph)
271
283
  quiv._mutation_type = mutation_type
272
- self.__init__( quiv )
273
- elif isinstance(data[1], list):
274
- quiv = ClusterQuiver( QuiverMutationType_Irreducible( data[0], tuple(data[1]) )._digraph )
284
+ self.__init__(quiv)
285
+ elif isinstance(d1, list):
286
+ quiv = ClusterQuiver(QuiverMutationType_Irreducible(d0, tuple(d1))._digraph)
275
287
  quiv._mutation_type = mutation_type
276
- self.__init__( quiv )
288
+ self.__init__(quiv)
277
289
  else:
278
- self.__init__( mutation_type.standard_quiver() )
290
+ self.__init__(mutation_type.standard_quiver())
279
291
  elif len(data) == 3 and isinstance(data[0], str):
280
- if (data[0] == 'F' and data[1] == 4 and data[2] == [2,1]) or (data[0] == 'G' and data[1] == 2 and data[2] == [3,1]):
281
- quiv = ClusterQuiver( QuiverMutationType_Irreducible( data[0], data[1], tuple(data[2]) )._digraph )
292
+ d0, d1, d2 = data
293
+ if ((d0 == 'F' and d1 == 4 and d2 == [2, 1]) or
294
+ (d0 == 'G' and d1 == 2 and d2 == [3, 1])):
295
+ quiv = ClusterQuiver(QuiverMutationType_Irreducible(d0, d1, tuple(d2))._digraph)
282
296
  quiv._mutation_type = mutation_type
283
- self.__init__( quiv )
284
- elif (data[0] == 'F' and data[1] == 4 and data[2] == (2,1) ) or (data[0] == 'G' and data[1] == 2 and data[2] == (3,1) ):
285
- quiv = ClusterQuiver( QuiverMutationType_Irreducible( data[0], data[1], data[2] )._digraph )
297
+ self.__init__(quiv)
298
+ elif ((d0 == 'F' and d1 == 4 and d2 == (2, 1)) or
299
+ (d0 == 'G' and d1 == 2 and d2 == (3, 1))):
300
+ quiv = ClusterQuiver(QuiverMutationType_Irreducible(d0, d1, d2)._digraph)
286
301
  quiv._mutation_type = mutation_type
287
- self.__init__( quiv )
288
- elif data[0] == 'A' and isinstance(data[1], list) and data[2] == 1:
289
- if len(data[1]) == 2 and min(data[1]) == 0:
290
- quiv = ClusterQuiver( QuiverMutationType_Irreducible( data[0], tuple(data[1]), data[2] )._digraph )
302
+ self.__init__(quiv)
303
+ elif d0 == 'A' and isinstance(d1, list) and d2 == 1:
304
+ if len(d1) == 2 and min(d1) == 0:
305
+ quiv = ClusterQuiver(QuiverMutationType_Irreducible(d0, tuple(d1), d2)._digraph)
291
306
  quiv._mutation_type = mutation_type
292
- self.__init__( quiv )
307
+ self.__init__(quiv)
293
308
  else:
294
- self.__init__( mutation_type.standard_quiver() )
309
+ self.__init__(mutation_type.standard_quiver())
295
310
 
296
- elif data[0] == 'A' and isinstance(data[1], tuple) and data[2] == 1:
297
- if len(data[1]) == 2 and min(data[1]) == 0:
298
- quiv = ClusterQuiver( QuiverMutationType_Irreducible( data[0], data[1], data[2] )._digraph )
311
+ elif d0 == 'A' and isinstance(d1, tuple) and d2 == 1:
312
+ if len(d1) == 2 and min(d1) == 0:
313
+ quiv = ClusterQuiver(QuiverMutationType_Irreducible(d0, d1, d2)._digraph)
299
314
  quiv._mutation_type = mutation_type
300
- self.__init__( quiv )
315
+ self.__init__(quiv)
301
316
  else:
302
- self.__init__( mutation_type.standard_quiver() )
317
+ self.__init__(mutation_type.standard_quiver())
303
318
 
304
319
  else:
305
- self.__init__( mutation_type.standard_quiver() )
320
+ self.__init__(mutation_type.standard_quiver())
306
321
  else:
307
- self.__init__( mutation_type.standard_quiver() )
322
+ self.__init__(mutation_type.standard_quiver())
308
323
 
309
324
  if user_labels:
310
325
  if isinstance(user_labels, dict):
311
- self._nlist = list(user_labels.keys())
326
+ self._nlist = list(user_labels)
312
327
  else:
313
328
  self._nlist = user_labels
314
329
 
@@ -316,7 +331,7 @@ class ClusterQuiver(SageObject):
316
331
 
317
332
  # constructs a quiver from a cluster seed
318
333
  elif isinstance(data, ClusterSeed):
319
- self.__init__( data.quiver() )
334
+ self.__init__(data.quiver())
320
335
 
321
336
  # constructs a quiver from a quiver
322
337
  elif isinstance(data, ClusterQuiver):
@@ -330,14 +345,14 @@ class ClusterQuiver(SageObject):
330
345
  self._m = data._m
331
346
  self._mlist = list(data._mlist)
332
347
  self._nlist = list(data._nlist)
333
- self._digraph = copy( data._digraph )
348
+ self._digraph = copy(data._digraph)
334
349
  self._vertex_dictionary = data._vertex_dictionary
335
350
  self._mutation_type = data._mutation_type
336
351
  self._description = data._description
337
352
 
338
353
  # constructs a quiver from a matrix
339
354
  elif isinstance(data, Matrix):
340
- if not _principal_part(data).is_skew_symmetrizable( positive=True ):
355
+ if not _principal_part(data).is_skew_symmetrizable(positive=True):
341
356
  raise ValueError('The principal part of the matrix data must be skew-symmetrizable.')
342
357
 
343
358
  if frozen is not None:
@@ -347,20 +362,20 @@ class ClusterQuiver(SageObject):
347
362
  self._M.set_immutable()
348
363
  self._n = n = self._M.ncols()
349
364
  self._m = m = self._M.nrows() - self._n
350
- self._digraph = _matrix_to_digraph( self._M )
365
+ self._digraph = _matrix_to_digraph(self._M)
351
366
  self._vertex_dictionary = {}
352
367
  self._mutation_type = None
353
368
 
354
369
  if user_labels:
355
370
  if isinstance(user_labels, dict):
356
- self._nlist = list(user_labels.keys())[0:n]
357
- self._mlist = list(user_labels.keys())[n:n+m]
371
+ self._nlist = list(user_labels)[0:n]
372
+ self._mlist = list(user_labels)[n:n+m]
358
373
  elif isinstance(user_labels, list):
359
374
  self._nlist = user_labels[0:n]
360
375
  self._mlist = user_labels[n:n+m]
361
376
  self._digraph.relabel(self._nlist + self._mlist)
362
377
  else:
363
- self._mlist = list(range(n,n+m))
378
+ self._mlist = list(range(n, n+m))
364
379
  self._nlist = list(range(n))
365
380
  if n+m == 0:
366
381
  self._description = 'Quiver without vertices'
@@ -417,34 +432,34 @@ class ClusterQuiver(SageObject):
417
432
  else:
418
433
  multi_edges[(v1, v2)] = label
419
434
  dg.delete_edge(v1, v2)
420
- dg.add_edges([(v1, v2, multi_edges[(v1,v2)])
435
+ dg.add_edges([(v1, v2, multi_edges[(v1, v2)])
421
436
  for v1, v2 in multi_edges])
422
437
 
423
- for edge in dg.edge_iterator():
424
- if edge[0] >= n and edge[1] >= n:
438
+ for e0, e1, lab in dg.edge_iterator():
439
+ if e0 >= n and e1 >= n:
425
440
  raise ValueError("the input digraph contains edges"
426
441
  " within the frozen vertices")
427
- if edge[2] is None:
428
- dg.set_edge_label( edge[0], edge[1], (1,-1) )
429
- edge = (edge[0],edge[1],(1,-1))
430
- elif edge[2] in ZZ:
431
- dg.set_edge_label( edge[0], edge[1], (edge[2],-edge[2]) )
432
- edge = (edge[0],edge[1],(edge[2],-edge[2]))
433
- elif isinstance(edge[2], list) and len(edge[2]) != 2:
442
+ if lab is None:
443
+ lab = (1, -1)
444
+ dg.set_edge_label(e0, e1, lab)
445
+ elif lab in ZZ:
446
+ lab = (lab, -lab)
447
+ dg.set_edge_label(e0, e1, lab)
448
+ elif isinstance(lab, list) and len(lab) != 2:
434
449
  raise ValueError("the input digraph contains an edge with"
435
450
  " the wrong type of list as a label")
436
- elif isinstance(edge[2], list) and len(edge[2]) == 2:
437
- dg.set_edge_label( edge[0], edge[1], (edge[2][0], edge[2][1]))
438
- edge = (edge[0],edge[1],(edge[2][0],edge[2][1]))
439
- elif ( edge[0] >= n or edge[1] >= n ) and not edge[2][0] == - edge[2][1]:
451
+ elif isinstance(lab, list) and len(lab) == 2:
452
+ lab = tuple(lab)
453
+ dg.set_edge_label(e0, e1, lab)
454
+ elif (e0 >= n or e1 >= n) and not lab[0] == -lab[1]:
440
455
  raise ValueError("the input digraph contains an edge to or"
441
456
  " from a frozen vertex which is not skew-symmetric")
442
- if edge[2][0] < 0:
443
- raise ValueError("the input digraph contains an edge of the"
444
- " form (a,-b) with negative a")
457
+ if lab[0] < 0:
458
+ raise ValueError("the input digraph contains an edge of "
459
+ "the form (a,-b) with negative a")
445
460
 
446
- M = _edge_list_to_matrix( dg.edge_iterator(), list(range(n)),
447
- list(range(n, n + m)) )
461
+ M = _edge_list_to_matrix(dg.edge_iterator(), list(range(n)),
462
+ list(range(n, n + m)))
448
463
  if not _principal_part(M).is_skew_symmetrizable(positive=True):
449
464
  raise ValueError("the input digraph must be skew-symmetrizable")
450
465
 
@@ -465,7 +480,8 @@ class ClusterQuiver(SageObject):
465
480
 
466
481
  # if data is a list of edges, the appropriate digraph is constructed.
467
482
 
468
- elif isinstance(data, (list, EdgesView)) and all(isinstance(x, (list,tuple)) for x in data):
483
+ elif (isinstance(data, (list, EdgesView))
484
+ and all(isinstance(x, (list, tuple)) for x in data)):
469
485
  dg = DiGraph(data)
470
486
  self.__init__(data=dg, frozen=frozen)
471
487
 
@@ -485,16 +501,16 @@ class ClusterQuiver(SageObject):
485
501
  EXAMPLES::
486
502
 
487
503
  sage: Q = ClusterQuiver(['A',5])
488
- sage: T = Q.mutate( 2, inplace=False )
489
- sage: Q.__eq__( T )
504
+ sage: T = Q.mutate(2, inplace=False)
505
+ sage: Q.__eq__(T)
490
506
  False
491
- sage: T.mutate( 2 )
492
- sage: Q.__eq__( T )
507
+ sage: T.mutate(2)
508
+ sage: Q.__eq__(T)
493
509
  True
494
510
  """
495
511
  return isinstance(other, ClusterQuiver) and self._M == other._M
496
512
 
497
- def __hash__(self):
513
+ def __hash__(self) -> int:
498
514
  """
499
515
  Return a hash of ``self``.
500
516
 
@@ -507,7 +523,7 @@ class ClusterQuiver(SageObject):
507
523
  """
508
524
  return hash(self._M)
509
525
 
510
- def _repr_(self):
526
+ def _repr_(self) -> str:
511
527
  """
512
528
  Return the description of ``self``.
513
529
 
@@ -572,7 +588,7 @@ class ClusterQuiver(SageObject):
572
588
  g2 = graphs.CycleGraph(m).get_pos()
573
589
  for i in g2:
574
590
  z = CC(g2[i])*e**(-pi*I/(2*m))
575
- g2[i] = (z.real_part(),z.imag_part())
591
+ g2[i] = (z.real_part(), z.imag_part())
576
592
  for i in range(m):
577
593
  g1[n+i] = [2*g2[i][0], 2*g2[i][1]]
578
594
  return g1
@@ -582,28 +598,30 @@ class ClusterQuiver(SageObject):
582
598
  nlist = copy(self._nlist)
583
599
  mlist = copy(self._mlist)
584
600
  colors = rainbow(11)
585
- color_dict = { colors[0]:[], colors[1]:[], colors[6]:[], colors[5]:[] }
601
+ color_dict = {colors[0]: [], colors[1]: [],
602
+ colors[6]: [], colors[5]: []}
586
603
 
587
- # Set up our graph. If it's directed we have a digraph, else just a normal graph
604
+ # Set up our graph. If it's directed we have a digraph, else
605
+ # just a normal graph
588
606
  if directed:
589
- dg = DiGraph( self._digraph )
607
+ dg = self._digraph.copy(immutable=False)
590
608
  else:
591
- dg = Graph( self._digraph )
609
+ dg = Graph(self._digraph)
592
610
 
593
611
  # For each edge in our graph we assign a color
594
- for edge in dg.edges(sort=True):
595
- v1,v2,(a,b) = edge
612
+ for v1, v2, ab in dg.edges(sort=True):
596
613
 
597
614
  if v1 in nlist and v2 in nlist:
598
- if (a,b) == (1,-1):
599
- color_dict[ colors[0] ].append((v1,v2))
615
+ if ab == (1, -1):
616
+ color_dict[colors[0]].append((v1, v2))
600
617
  else:
601
- color_dict[ colors[6] ].append((v1,v2))
618
+ color_dict[colors[6]].append((v1, v2))
602
619
  else:
603
- if (a,b) == (1,-1):
604
- color_dict[ colors[1] ].append((v1,v2))
620
+ if ab == (1, -1):
621
+ color_dict[colors[1]].append((v1, v2))
605
622
  else:
606
- color_dict[ colors[5] ].append((v1,v2))
623
+ color_dict[colors[5]].append((v1, v2))
624
+ a, b = ab
607
625
  if a == -b:
608
626
  if a == 1:
609
627
  dg.set_edge_label(v1, v2, '')
@@ -621,7 +639,7 @@ class ClusterQuiver(SageObject):
621
639
  mlist.remove(mark)
622
640
  partition = (nlist, mlist, [mark])
623
641
  else:
624
- raise ValueError("The given mark is not a vertex of self.")
642
+ raise ValueError("the given mark is not a vertex of self")
625
643
  else:
626
644
 
627
645
  # Partition out the green vertices
@@ -644,7 +662,7 @@ class ClusterQuiver(SageObject):
644
662
  'vertex_labels': True,
645
663
  }
646
664
  if circular:
647
- pp = _graphs_concentric_circles( n, m )
665
+ pp = _graphs_concentric_circles(n, m)
648
666
  options['pos'] = {}
649
667
  for v in pp:
650
668
  # If we're using vertex dictionary set that as key
@@ -652,9 +670,10 @@ class ClusterQuiver(SageObject):
652
670
  vkey = self._vertex_dictionary[v]
653
671
  else:
654
672
  vkey = v
655
- options['pos'][vkey] = (pp[v][0] + center[0], pp[v][1] + center[1])
673
+ options['pos'][vkey] = (pp[v][0] + center[0],
674
+ pp[v][1] + center[1])
656
675
 
657
- return dg.plot( **options )
676
+ return dg.plot(**options)
658
677
 
659
678
  def show(self, fig_size=1, circular=False, directed=True, mark=None, save_pos=False, greens=[]):
660
679
  """
@@ -681,11 +700,12 @@ class ClusterQuiver(SageObject):
681
700
  sage: Q.show() # long time
682
701
  """
683
702
  n, m = self._n, self._m
684
- plot = self.plot( circular=circular, directed=directed, mark=mark, save_pos=save_pos, greens=greens)
703
+ plot = self.plot(circular=circular, directed=directed,
704
+ mark=mark, save_pos=save_pos, greens=greens)
685
705
  if circular:
686
- plot.show( figsize=[fig_size*3*(n+m)/4+1,fig_size*3*(n+m)/4+1] )
706
+ plot.show(figsize=[fig_size*3*(n+m)/4+1, fig_size*3*(n+m)/4+1])
687
707
  else:
688
- plot.show( figsize=[fig_size*n+1,fig_size*n+1] )
708
+ plot.show(figsize=[fig_size*n+1, fig_size*n+1])
689
709
 
690
710
  def interact(self, fig_size=1, circular=True):
691
711
  r"""
@@ -764,7 +784,7 @@ class ClusterQuiver(SageObject):
764
784
  if self.m():
765
785
  from sage.matrix.constructor import matrix
766
786
  from sage.matrix.constructor import block_matrix
767
- M1 = M.matrix_from_rows(list(range(self.n())))
787
+ M1 = M.matrix_from_rows(range(self.n()))
768
788
  M2 = M.matrix_from_rows(list(range(self.n(), self.n() + self.m())))
769
789
  M3 = matrix(self.m(), self.m())
770
790
  M = block_matrix([[M1, -M2.transpose()], [M2, M3]])
@@ -877,7 +897,7 @@ class ClusterQuiver(SageObject):
877
897
  sage: ClusterQuiver(['C', 4], user_labels = ['x', 'y', 'z', 'w']).digraph().edges(sort=True)
878
898
  [('x', 'y', (1, -1)), ('z', 'w', (2, -1)), ('z', 'y', (1, -1))]
879
899
  """
880
- return copy(self._digraph)
900
+ return self._digraph.copy()
881
901
 
882
902
  def mutation_type(self):
883
903
  """
@@ -952,15 +972,15 @@ class ClusterQuiver(SageObject):
952
972
  examples from page 8 of [Ke2008]_::
953
973
 
954
974
  sage: dg = DiGraph(); dg.add_edges([(9,0),(9,4),(4,6),(6,7),(7,8),(8,3),(3,5),(5,6),(8,1),(2,3)])
955
- sage: ClusterQuiver( dg ).mutation_type() # long time
975
+ sage: ClusterQuiver(dg).mutation_type() # long time
956
976
  ['E', 8, [1, 1]]
957
977
 
958
- sage: dg = DiGraph( { 0:[3], 1:[0,4], 2:[0,6], 3:[1,2,7], 4:[3,8], 5:[2], 6:[3,5], 7:[4,6], 8:[7] } )
959
- sage: ClusterQuiver( dg ).mutation_type() # long time
978
+ sage: dg = DiGraph({ 0:[3], 1:[0,4], 2:[0,6], 3:[1,2,7], 4:[3,8], 5:[2], 6:[3,5], 7:[4,6], 8:[7] })
979
+ sage: ClusterQuiver(dg).mutation_type() # long time
960
980
  ['E', 8, 1]
961
981
 
962
- sage: dg = DiGraph( { 0:[3,9], 1:[0,4], 2:[0,6], 3:[1,2,7], 4:[3,8], 5:[2], 6:[3,5], 7:[4,6], 8:[7], 9:[1] } )
963
- sage: ClusterQuiver( dg ).mutation_type() # long time
982
+ sage: dg = DiGraph({ 0:[3,9], 1:[0,4], 2:[0,6], 3:[1,2,7], 4:[3,8], 5:[2], 6:[3,5], 7:[4,6], 8:[7], 9:[1] })
983
+ sage: ClusterQuiver(dg).mutation_type() # long time
964
984
  ['E', 8, [1, 1]]
965
985
 
966
986
  infinite types::
@@ -1013,7 +1033,7 @@ class ClusterQuiver(SageObject):
1013
1033
  connected_components = sorted(dg.connected_components(sort=False))
1014
1034
  for component in connected_components:
1015
1035
  # constructing the digraph for this component
1016
- dg_component = dg.subgraph( component )
1036
+ dg_component = dg.subgraph(component)
1017
1037
  dg_component.relabel()
1018
1038
  # turning dg_component into a canonical form
1019
1039
  _dg_canonical_form(dg_component)
@@ -1028,7 +1048,7 @@ class ClusterQuiver(SageObject):
1028
1048
  mut_type_part = 'undetermined infinite mutation type'
1029
1049
  else:
1030
1050
  # checking if this quiver is in the database
1031
- mut_type_part = _mutation_type_from_data( dg_component.order(), dig6, compute_if_necessary=False )
1051
+ mut_type_part = _mutation_type_from_data(dg_component.order(), dig6, compute_if_necessary=False)
1032
1052
  # checking if the algorithm can determine the mutation type
1033
1053
  if mut_type_part == 'unknown':
1034
1054
  mut_type_part = _connected_mutation_type(dg_component)
@@ -1037,7 +1057,7 @@ class ClusterQuiver(SageObject):
1037
1057
  mut_type_part = _mutation_type_from_data(dg_component.order(), dig6, compute_if_necessary=True)
1038
1058
  if mut_type_part == 'unknown':
1039
1059
  mut_type_part = 'undetermined finite mutation type'
1040
- mutation_type.append( mut_type_part )
1060
+ mutation_type.append(mut_type_part)
1041
1061
 
1042
1062
  # the empty quiver case
1043
1063
  if len(mutation_type) == 0:
@@ -1046,12 +1066,9 @@ class ClusterQuiver(SageObject):
1046
1066
  elif len(mutation_type) == 1:
1047
1067
  mutation_type = mutation_type[0]
1048
1068
  # the reducible quiver case
1049
- elif len(mutation_type) > 1:
1050
- if any(isinstance(mut_type_part, str)
1051
- for mut_type_part in mutation_type):
1052
- pass
1053
- else:
1054
- mutation_type = QuiverMutationType(mutation_type)
1069
+ elif not any(isinstance(mut_type_part, str)
1070
+ for mut_type_part in mutation_type):
1071
+ mutation_type = QuiverMutationType(mutation_type)
1055
1072
  self._mutation_type = mutation_type
1056
1073
  return self._mutation_type
1057
1074
 
@@ -1090,7 +1107,7 @@ class ClusterQuiver(SageObject):
1090
1107
  """
1091
1108
  return self._m
1092
1109
 
1093
- def free_vertices(self):
1110
+ def free_vertices(self) -> list:
1094
1111
  """
1095
1112
  Return the list of free vertices of ``self``.
1096
1113
 
@@ -1103,7 +1120,7 @@ class ClusterQuiver(SageObject):
1103
1120
  """
1104
1121
  return self._nlist
1105
1122
 
1106
- def frozen_vertices(self):
1123
+ def frozen_vertices(self) -> list:
1107
1124
  """
1108
1125
  Return the list of frozen vertices of ``self``.
1109
1126
 
@@ -1151,7 +1168,7 @@ class ClusterQuiver(SageObject):
1151
1168
  (Quiver on 3 vertices of type [ ['A', 1], ['B', 2] ], {0: 1, 1: 2, 2: 0})
1152
1169
  """
1153
1170
  # computing the canonical form respecting the frozen variables
1154
- dg = copy(self._digraph)
1171
+ dg = self._digraph.copy()
1155
1172
  iso, _ = _dg_canonical_form(dg, frozen=self._mlist)
1156
1173
  frozen = [iso[i] for i in self._mlist]
1157
1174
  Q = ClusterQuiver(dg, frozen=frozen)
@@ -1164,16 +1181,15 @@ class ClusterQuiver(SageObject):
1164
1181
  CC_new = sorted(zip([sorted(iso[i] for i in L) for L in CC],
1165
1182
  range(len(CC))))
1166
1183
  comp_iso = [L[1] for L in CC_new]
1167
- Q._mutation_type = []
1168
- for i in range( len( CC_new ) ):
1169
- Q._mutation_type.append( copy( self._mutation_type.irreducible_components()[ comp_iso[i] ] ) )
1170
- Q._mutation_type = QuiverMutationType( Q._mutation_type )
1184
+ Q._mutation_type = [copy(self._mutation_type.irreducible_components()[comp_i])
1185
+ for comp_i in comp_iso]
1186
+ Q._mutation_type = QuiverMutationType(Q._mutation_type)
1171
1187
  if certificate:
1172
1188
  return Q, iso
1173
1189
  else:
1174
1190
  return Q
1175
1191
 
1176
- def is_acyclic(self):
1192
+ def is_acyclic(self) -> bool:
1177
1193
  """
1178
1194
  Return true if ``self`` is acyclic.
1179
1195
 
@@ -1202,8 +1218,8 @@ class ClusterQuiver(SageObject):
1202
1218
  sage: ClusterQuiver(['A',[4,3],1]).is_bipartite()
1203
1219
  False
1204
1220
  """
1205
- dg = copy(self._digraph)
1206
- dg.delete_vertices(list(range(self._n, self._n + self._m)))
1221
+ dg = self._digraph.copy(immutable=False)
1222
+ dg.delete_vertices(range(self._n, self._n + self._m))
1207
1223
  if any(dg.in_degree(i) and dg.out_degree(i) for i in dg):
1208
1224
  return False
1209
1225
  if not return_bipartition:
@@ -1229,15 +1245,19 @@ class ClusterQuiver(SageObject):
1229
1245
  sage: Q2.exchangeable_part() == Q3.exchangeable_part()
1230
1246
  True
1231
1247
  """
1232
- dg = DiGraph( self._digraph )
1233
- dg.delete_vertices(list(range(self._n, self._n + self._m)))
1234
- Q = ClusterQuiver( dg )
1248
+ dg = self._digraph.copy(immutable=False)
1249
+ dg.delete_vertices(range(self._n, self._n + self._m))
1250
+ Q = ClusterQuiver(dg)
1235
1251
  Q._mutation_type = self._mutation_type
1236
1252
  return Q
1237
1253
 
1238
1254
  def principal_extension(self, inplace=False):
1239
1255
  """
1240
- Return the principal extension of ``self``, adding n frozen vertices to any previously frozen vertices. I.e., the quiver obtained by adding an outgoing edge to every mutable vertex of ``self``.
1256
+ Return the principal extension of ``self``, adding n frozen vertices
1257
+ to any previously frozen vertices.
1258
+
1259
+ This is the quiver obtained by adding an outgoing edge to
1260
+ every mutable vertex of ``self``.
1241
1261
 
1242
1262
  EXAMPLES::
1243
1263
 
@@ -1252,11 +1272,13 @@ class ClusterQuiver(SageObject):
1252
1272
  sage: T.digraph().edges(sort=True)
1253
1273
  [(0, 1, (1, -1)), (2, 0, (1, -1)), (3, 1, (1, -1))]
1254
1274
  sage: T2.digraph().edges(sort=True)
1255
- [(0, 1, (1, -1)), (2, 0, (1, -1)), (3, 1, (1, -1)), (4, 0, (1, -1)), (5, 1, (1, -1))]
1275
+ [(0, 1, (1, -1)), (2, 0, (1, -1)), (3, 1, (1, -1)),
1276
+ (4, 0, (1, -1)), (5, 1, (1, -1))]
1256
1277
  """
1257
- dg = DiGraph(self._digraph)
1258
- dg.add_edges( [(self._n+self._m+i,i) for i in range(self._n)] )
1259
- Q = ClusterQuiver( dg, frozen=list(range(self._n, self._n+self._m+self._n)) )
1278
+ dg = self._digraph.copy(immutable=False)
1279
+ dg.add_edges([(self._n + self._m + i, i) for i in range(self._n)])
1280
+ Q = ClusterQuiver(dg, frozen=list(range(self._n,
1281
+ 2 * self._n + self._m)))
1260
1282
  Q._mutation_type = self._mutation_type
1261
1283
  if inplace:
1262
1284
  self.__init__(Q)
@@ -1280,7 +1302,7 @@ class ClusterQuiver(SageObject):
1280
1302
  return sinks[0]
1281
1303
  return None
1282
1304
 
1283
- def sinks(self):
1305
+ def sinks(self) -> list:
1284
1306
  r"""
1285
1307
  Return all vertices of ``self`` that are sinks.
1286
1308
 
@@ -1315,7 +1337,7 @@ class ClusterQuiver(SageObject):
1315
1337
  return sources[0]
1316
1338
  return None
1317
1339
 
1318
- def sources(self):
1340
+ def sources(self) -> list:
1319
1341
  r"""
1320
1342
  Return all vertices of ``self`` that are sources.
1321
1343
 
@@ -1335,15 +1357,15 @@ class ClusterQuiver(SageObject):
1335
1357
 
1336
1358
  def mutate(self, data, inplace=True):
1337
1359
  """
1338
- Mutates ``self`` at a sequence of vertices.
1360
+ Mutate ``self`` at a sequence of vertices.
1339
1361
 
1340
1362
  INPUT:
1341
1363
 
1342
1364
  - ``sequence`` -- a vertex of ``self``, an iterator of vertices of
1343
1365
  ``self``, a function which takes in the ClusterQuiver and returns a
1344
1366
  vertex or an iterator of vertices, or a string of the parameter
1345
- wanting to be called on ClusterQuiver that will return a vertex or
1346
- an iterator of vertices
1367
+ wanting to be called on ``ClusterQuiver`` that will return a vertex
1368
+ or an iterator of vertices
1347
1369
  - ``inplace`` -- boolean (default: ``True``); if ``False``, the result
1348
1370
  is returned, otherwise ``self`` is modified
1349
1371
 
@@ -1455,7 +1477,7 @@ class ClusterQuiver(SageObject):
1455
1477
  else:
1456
1478
  seq = data
1457
1479
  if isinstance(seq, tuple):
1458
- seq = list( seq )
1480
+ seq = list(seq)
1459
1481
  if not isinstance(seq, list):
1460
1482
  raise ValueError('The quiver can only be mutated at a vertex or at a sequence of vertices')
1461
1483
  if not isinstance(inplace, bool):
@@ -1476,7 +1498,7 @@ class ClusterQuiver(SageObject):
1476
1498
  Q._mutation_type = self._mutation_type
1477
1499
  return Q
1478
1500
 
1479
- def mutation_sequence(self, sequence, show_sequence=False, fig_size=1.2 ):
1501
+ def mutation_sequence(self, sequence, show_sequence=False, fig_size=1.2):
1480
1502
  """
1481
1503
  Return a list containing the sequence of quivers obtained from ``self``
1482
1504
  by a sequence of mutations on vertices.
@@ -1512,44 +1534,46 @@ class ClusterQuiver(SageObject):
1512
1534
  else:
1513
1535
  width_factor = 6
1514
1536
  fig_size = fig_size*4*n/3
1515
- V = list(range(n))
1537
+ V = range(n)
1516
1538
 
1517
1539
  if isinstance(sequence, tuple):
1518
- sequence = list( sequence )
1540
+ sequence = list(sequence)
1519
1541
  if not isinstance(sequence, list):
1520
- raise ValueError('The quiver can only be mutated at a vertex or at a sequence of vertices')
1542
+ raise ValueError('the quiver can only be mutated at a vertex'
1543
+ ' or at a sequence of vertices')
1521
1544
  if any(v not in V for v in sequence):
1522
1545
  v = next(v for v in sequence if v not in V)
1523
- raise ValueError('The quiver can only be mutated at the vertex %s' % v )
1546
+ raise ValueError(f'the quiver can only be mutated at the vertex {v}')
1524
1547
 
1525
- quiver = copy( self )
1548
+ quiver = copy(self)
1526
1549
  quiver_sequence = []
1527
- quiver_sequence.append( copy( quiver ) )
1550
+ quiver_sequence.append(copy(quiver))
1528
1551
 
1529
1552
  for v in sequence:
1530
- quiver.mutate( v )
1531
- quiver_sequence.append( copy( quiver ) )
1553
+ quiver.mutate(v)
1554
+ quiver_sequence.append(copy(quiver))
1532
1555
 
1533
1556
  if show_sequence:
1534
1557
  from sage.plot.plot import Graphics
1535
1558
  from sage.plot.text import text
1536
1559
 
1537
- def _plot_arrow( v, k, center=(0, 0) ):
1538
- return text(r"$\longleftrightarrow$",(center[0],center[1]), fontsize=25) + text(r"$\mu_"+str(v)+"$",(center[0],center[1]+0.15), fontsize=15) \
1539
- + text("$"+str(k)+"$",(center[0],center[1]-0.2), fontsize=15)
1560
+ def _plot_arrow(v, k, center=(0, 0)):
1561
+ return text(r"$\longleftrightarrow$", (center[0], center[1]), fontsize=25) + text(r"$\mu_"+str(v)+"$", (center[0], center[1]+0.15), fontsize=15) \
1562
+ + text("$"+str(k)+"$", (center[0], center[1]-0.2), fontsize=15)
1540
1563
 
1541
- plot_sequence = [ quiver_sequence[i].plot( circular=True, center=(i*width_factor,0) ) for i in range(len(quiver_sequence)) ]
1542
- arrow_sequence = [ _plot_arrow( sequence[i],i+1,center=((i+0.5)*width_factor,0) ) for i in range(len(sequence)) ]
1564
+ plot_sequence = [quiver_sequence[i].plot(circular=True, center=(i*width_factor, 0)) for i in range(len(quiver_sequence))]
1565
+ arrow_sequence = [_plot_arrow(sequence[i], i+1, center=((i+0.5)*width_factor, 0)) for i in range(len(sequence))]
1543
1566
  sequence = []
1544
- for i in range( len( plot_sequence ) ):
1545
- if i < len( arrow_sequence ):
1546
- sequence.append( plot_sequence[i] + arrow_sequence[i] )
1567
+ for i in range(len(plot_sequence)):
1568
+ if i < len(arrow_sequence):
1569
+ sequence.append(plot_sequence[i] + arrow_sequence[i])
1547
1570
  else:
1548
- sequence.append( plot_sequence[i] )
1571
+ sequence.append(plot_sequence[i])
1549
1572
  plot_obj = Graphics()
1550
1573
  for elem in sequence:
1551
1574
  plot_obj += elem
1552
- plot_obj.show(axes=False, figsize=[fig_size*len(quiver_sequence),fig_size])
1575
+ plot_obj.show(axes=False, figsize=[fig_size*len(quiver_sequence),
1576
+ fig_size])
1553
1577
  return quiver_sequence
1554
1578
 
1555
1579
  def reorient(self, data):
@@ -1623,13 +1647,15 @@ class ClusterQuiver(SageObject):
1623
1647
  self._M.set_immutable()
1624
1648
  self._mutation_type = None
1625
1649
  else:
1626
- raise ValueError('not a total order on the vertices of the quiver or a list of edges to be oriented')
1650
+ raise ValueError('not a total order on the vertices of the quiver'
1651
+ ' or a list of edges to be oriented')
1627
1652
 
1628
1653
  def mutation_class_iter(self, depth=infinity, show_depth=False,
1629
1654
  return_paths=False, data_type='quiver',
1630
1655
  up_to_equivalence=True, sink_source=False):
1631
1656
  """
1632
- Return an iterator for the mutation class of ``self`` together with certain constraints.
1657
+ Return an iterator for the mutation class of ``self``
1658
+ together with certain constraints.
1633
1659
 
1634
1660
  INPUT:
1635
1661
 
@@ -1699,7 +1725,8 @@ class ClusterQuiver(SageObject):
1699
1725
  Quiver on 3 vertices of type ['A', 3]
1700
1726
  Quiver on 3 vertices of type ['A', 3]
1701
1727
 
1702
- sage: it = Q.mutation_class_iter(return_paths=True,up_to_equivalence=False)
1728
+ sage: it = Q.mutation_class_iter(return_paths=True,
1729
+ ....: up_to_equivalence=False)
1703
1730
  sage: mutation_class = list(it)
1704
1731
  sage: len(mutation_class)
1705
1732
  14
@@ -1715,7 +1742,8 @@ class ClusterQuiver(SageObject):
1715
1742
  [0, 1]
1716
1743
 
1717
1744
  sage: Q = ClusterQuiver(['A',3])
1718
- sage: it = Q.mutation_class_iter(return_paths=True,data_type='matrix')
1745
+ sage: it = Q.mutation_class_iter(return_paths=True,
1746
+ ....: data_type='matrix')
1719
1747
  sage: next(it)
1720
1748
  (
1721
1749
  [ 0 0 1]
@@ -1723,7 +1751,8 @@ class ClusterQuiver(SageObject):
1723
1751
  [-1 -1 0], []
1724
1752
  )
1725
1753
 
1726
- sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format='list_of_edges')
1754
+ sage: dg = DiGraph([['a', 'b'], ['b', 'c']],
1755
+ ....: format='list_of_edges')
1727
1756
  sage: S = ClusterQuiver(dg, frozen=['b'])
1728
1757
  sage: S.mutation_class()
1729
1758
  [Quiver on 3 vertices with 1 frozen vertex,
@@ -1778,8 +1807,8 @@ class ClusterQuiver(SageObject):
1778
1807
  - ``show_depth`` -- boolean (default: ``False``); if ``True``, the
1779
1808
  actual depth of the mutation is shown
1780
1809
  - ``return_paths`` -- boolean (default: ``False``); if ``True``, a
1781
- shortest path of mutation sequences from ``self`` to the given quiver is
1782
- returned as well
1810
+ shortest path of mutation sequences from ``self`` to the given
1811
+ quiver is returned as well
1783
1812
  - ``data_type`` -- (default: ``'quiver'``) can be one of
1784
1813
  the following:
1785
1814
 
@@ -1875,7 +1904,7 @@ class ClusterQuiver(SageObject):
1875
1904
  up_to_equivalence=up_to_equivalence,
1876
1905
  sink_source=sink_source))
1877
1906
 
1878
- def is_finite(self):
1907
+ def is_finite(self) -> bool:
1879
1908
  """
1880
1909
  Return ``True`` if ``self`` is of finite type.
1881
1910
 
@@ -1918,10 +1947,12 @@ class ClusterQuiver(SageObject):
1918
1947
  return (type(mt) in [QuiverMutationType_Irreducible,
1919
1948
  QuiverMutationType_Reducible] and mt.is_finite())
1920
1949
 
1921
- def is_mutation_finite( self, nr_of_checks=None, return_path=False ):
1950
+ def is_mutation_finite(self, nr_of_checks=None, return_path=False) -> bool:
1922
1951
  """
1923
- Uses a non-deterministic method by random mutations in various
1924
- directions. Can result in a wrong answer.
1952
+ Return whether ``self`` is mutation-finite.
1953
+
1954
+ This uses a non-deterministic method by random mutations in various
1955
+ directions. This can result in a wrong answer.
1925
1956
 
1926
1957
  INPUT:
1927
1958
 
@@ -1933,7 +1964,8 @@ class ClusterQuiver(SageObject):
1933
1964
 
1934
1965
  ALGORITHM:
1935
1966
 
1936
- A quiver is mutation infinite if and only if every edge label (a,-b) satisfy a*b > 4.
1967
+ A quiver is mutation infinite if and only if every
1968
+ edge label (a,-b) satisfy a*b > 4.
1937
1969
  Thus, we apply random mutations in random directions
1938
1970
 
1939
1971
  EXAMPLES::
@@ -1943,7 +1975,8 @@ class ClusterQuiver(SageObject):
1943
1975
  sage: Q.is_mutation_finite()
1944
1976
  True
1945
1977
 
1946
- sage: Q = ClusterQuiver([(0,1),(1,2),(2,3),(3,4),(4,5),(5,6),(6,7),(7,8),(2,9)])
1978
+ sage: Q = ClusterQuiver([(0,1),(1,2),(2,3),(3,4),
1979
+ ....: (4,5),(5,6),(6,7),(7,8),(2,9)])
1947
1980
  sage: Q.is_mutation_finite()
1948
1981
  False
1949
1982
  """
@@ -1969,17 +2002,17 @@ class ClusterQuiver(SageObject):
1969
2002
  M = _dig6_to_matrix(dig6)
1970
2003
 
1971
2004
  is_finite, path = is_mutation_finite(M, nr_of_checks=nr_of_checks)
1972
- if return_path:
1973
- return is_finite, path
1974
- else:
1975
- return is_finite
2005
+ return (is_finite, path) if return_path else is_finite
1976
2006
 
1977
2007
  def number_of_edges(self):
1978
2008
  r"""
1979
2009
  Return the total number of edges on the quiver.
1980
2010
 
1981
- Note: This only works with non-valued quivers. If used on a
1982
- non-valued quiver then the positive value is taken to be the number of edges added
2011
+ .. NOTE::
2012
+
2013
+ This only works with non-valued quivers. If used on a
2014
+ non-valued quiver then the positive value is taken to be
2015
+ the number of edges added.
1983
2016
 
1984
2017
  OUTPUT: integer of the number of edges
1985
2018
 
@@ -1991,13 +2024,7 @@ class ClusterQuiver(SageObject):
1991
2024
  sage: S = ClusterQuiver(['B',4]); S.number_of_edges()
1992
2025
  3
1993
2026
  """
1994
- digraph_edges = self.digraph().edges(sort=True)
1995
-
1996
- total_edges = 0
1997
- for edge in digraph_edges:
1998
- total_edges += edge[2][0]
1999
-
2000
- return total_edges
2027
+ return sum(label[0] for label in self.digraph().edge_labels())
2001
2028
 
2002
2029
  def relabel(self, relabelling, inplace=True):
2003
2030
  r"""
@@ -2026,11 +2053,11 @@ class ClusterQuiver(SageObject):
2026
2053
  dict_labels = {}
2027
2054
 
2028
2055
  # Organize labels noting that for:
2029
- # _digraph: { old_vertex: new_vertex}
2056
+ # _digraph: {old_vertex: new_vertex}
2030
2057
  # _vertex_dictionary: {num: new_vertex}
2031
2058
  if isinstance(relabelling, list):
2032
- digraph_labels = {old_vertices[i]: relabelling[i] for i in range(len(relabelling))}
2033
- dict_labels = {range(len(relabelling))[i]: relabelling[i] for i in range(len(relabelling))}
2059
+ digraph_labels = dict(zip(old_vertices, relabelling))
2060
+ dict_labels = dict(enumerate(relabelling))
2034
2061
  elif isinstance(relabelling, dict):
2035
2062
  # need to make sure we map correctly
2036
2063
  for key in relabelling:
@@ -2198,11 +2225,12 @@ class ClusterQuiver(SageObject):
2198
2225
  ...
2199
2226
  ValueError: only makes sense for quivers of finite type
2200
2227
  """
2228
+ from sage.geometry.fan import Fan
2229
+
2201
2230
  if not self.is_finite():
2202
2231
  raise ValueError('only makes sense for quivers of finite type')
2203
2232
 
2204
2233
  from .cluster_seed import ClusterSeed
2205
- from sage.geometry.fan import Fan
2206
2234
  from sage.geometry.cone import Cone
2207
2235
 
2208
2236
  seed = ClusterSeed(self)
@@ -2252,8 +2280,8 @@ class ClusterQuiver(SageObject):
2252
2280
  ValueError: only supported for quivers of finite type
2253
2281
  """
2254
2282
  from .cluster_seed import ClusterSeed
2255
- from sage.geometry.fan import Fan
2256
2283
  from sage.geometry.cone import Cone
2284
+ from sage.geometry.fan import Fan
2257
2285
 
2258
2286
  if not (self.is_finite()):
2259
2287
  raise ValueError('only supported for quivers of finite type')