passagemath-graphs 10.6.1rc1__cp310-cp310-musllinux_1_2_aarch64.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.6.1rc1.dist-info/METADATA +292 -0
- passagemath_graphs-10.6.1rc1.dist-info/RECORD +260 -0
- passagemath_graphs-10.6.1rc1.dist-info/WHEEL +5 -0
- passagemath_graphs-10.6.1rc1.dist-info/top_level.txt +2 -0
- passagemath_graphs.libs/libgcc_s-69c45f16.so.1 +0 -0
- passagemath_graphs.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
- passagemath_graphs.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
- sage/all__sagemath_graphs.py +39 -0
- sage/combinat/abstract_tree.py +2723 -0
- sage/combinat/all__sagemath_graphs.py +34 -0
- sage/combinat/binary_tree.py +5306 -0
- sage/combinat/cluster_algebra_quiver/all.py +22 -0
- sage/combinat/cluster_algebra_quiver/cluster_seed.py +5208 -0
- sage/combinat/cluster_algebra_quiver/interact.py +124 -0
- sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
- sage/combinat/cluster_algebra_quiver/mutation_type.py +1555 -0
- sage/combinat/cluster_algebra_quiver/quiver.py +2290 -0
- sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +2468 -0
- sage/combinat/designs/MOLS_handbook_data.py +570 -0
- sage/combinat/designs/all.py +58 -0
- sage/combinat/designs/bibd.py +1655 -0
- sage/combinat/designs/block_design.py +1071 -0
- sage/combinat/designs/covering_array.py +269 -0
- sage/combinat/designs/covering_design.py +530 -0
- sage/combinat/designs/database.py +5615 -0
- sage/combinat/designs/design_catalog.py +122 -0
- sage/combinat/designs/designs_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/designs_pyx.pxd +21 -0
- sage/combinat/designs/designs_pyx.pyx +993 -0
- sage/combinat/designs/difference_family.py +3951 -0
- sage/combinat/designs/difference_matrices.py +279 -0
- sage/combinat/designs/evenly_distributed_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/evenly_distributed_sets.pyx +661 -0
- sage/combinat/designs/ext_rep.py +1064 -0
- sage/combinat/designs/gen_quadrangles_with_spread.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/gen_quadrangles_with_spread.pyx +339 -0
- sage/combinat/designs/group_divisible_designs.py +361 -0
- sage/combinat/designs/incidence_structures.py +2357 -0
- sage/combinat/designs/latin_squares.py +581 -0
- sage/combinat/designs/orthogonal_arrays.py +2244 -0
- sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +967 -0
- sage/combinat/designs/resolvable_bibd.py +815 -0
- sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
- sage/combinat/designs/subhypergraph_search.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/subhypergraph_search.pyx +530 -0
- sage/combinat/designs/twographs.py +306 -0
- sage/combinat/finite_state_machine.py +14874 -0
- sage/combinat/finite_state_machine_generators.py +2006 -0
- sage/combinat/graph_path.py +448 -0
- sage/combinat/interval_posets.py +3908 -0
- sage/combinat/nu_tamari_lattice.py +269 -0
- sage/combinat/ordered_tree.py +1446 -0
- sage/combinat/posets/all.py +46 -0
- sage/combinat/posets/bubble_shuffle.py +247 -0
- sage/combinat/posets/cartesian_product.py +493 -0
- sage/combinat/posets/d_complete.py +182 -0
- sage/combinat/posets/elements.py +273 -0
- sage/combinat/posets/forest.py +30 -0
- sage/combinat/posets/hasse_cython.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/hasse_cython.pyx +174 -0
- sage/combinat/posets/hasse_diagram.py +3672 -0
- sage/combinat/posets/hochschild_lattice.py +158 -0
- sage/combinat/posets/incidence_algebras.py +794 -0
- sage/combinat/posets/lattices.py +5117 -0
- sage/combinat/posets/linear_extension_iterator.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/linear_extension_iterator.pyx +292 -0
- sage/combinat/posets/linear_extensions.py +1037 -0
- sage/combinat/posets/mobile.py +275 -0
- sage/combinat/posets/moebius_algebra.py +776 -0
- sage/combinat/posets/poset_examples.py +2178 -0
- sage/combinat/posets/posets.py +9360 -0
- sage/combinat/rooted_tree.py +1070 -0
- sage/combinat/shard_order.py +239 -0
- sage/combinat/tamari_lattices.py +384 -0
- sage/combinat/yang_baxter_graph.py +923 -0
- sage/databases/all__sagemath_graphs.py +1 -0
- sage/databases/knotinfo_db.py +1231 -0
- sage/ext_data/all__sagemath_graphs.py +1 -0
- sage/ext_data/graphs/graph_plot_js.html +330 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/graphs/all.py +42 -0
- sage/graphs/asteroidal_triples.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/asteroidal_triples.pyx +320 -0
- sage/graphs/base/all.py +1 -0
- sage/graphs/base/boost_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/boost_graph.pxd +106 -0
- sage/graphs/base/boost_graph.pyx +3045 -0
- sage/graphs/base/c_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/c_graph.pxd +106 -0
- sage/graphs/base/c_graph.pyx +5096 -0
- sage/graphs/base/dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/dense_graph.pxd +28 -0
- sage/graphs/base/dense_graph.pyx +801 -0
- sage/graphs/base/graph_backends.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/graph_backends.pxd +5 -0
- sage/graphs/base/graph_backends.pyx +797 -0
- sage/graphs/base/overview.py +85 -0
- sage/graphs/base/sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/sparse_graph.pxd +90 -0
- sage/graphs/base/sparse_graph.pyx +1653 -0
- sage/graphs/base/static_dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_dense_graph.pxd +5 -0
- sage/graphs/base/static_dense_graph.pyx +1032 -0
- sage/graphs/base/static_sparse_backend.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_backend.pxd +27 -0
- sage/graphs/base/static_sparse_backend.pyx +1583 -0
- sage/graphs/base/static_sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_graph.pxd +37 -0
- sage/graphs/base/static_sparse_graph.pyx +1375 -0
- sage/graphs/bipartite_graph.py +2732 -0
- sage/graphs/centrality.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/centrality.pyx +1038 -0
- sage/graphs/cographs.py +519 -0
- sage/graphs/comparability.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/comparability.pyx +851 -0
- sage/graphs/connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/connectivity.pxd +157 -0
- sage/graphs/connectivity.pyx +4813 -0
- sage/graphs/convexity_properties.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/convexity_properties.pxd +16 -0
- sage/graphs/convexity_properties.pyx +870 -0
- sage/graphs/digraph.py +4754 -0
- sage/graphs/digraph_generators.py +1993 -0
- sage/graphs/distances_all_pairs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/distances_all_pairs.pxd +12 -0
- sage/graphs/distances_all_pairs.pyx +2938 -0
- sage/graphs/domination.py +1363 -0
- sage/graphs/dot2tex_utils.py +100 -0
- sage/graphs/edge_connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/edge_connectivity.pyx +1215 -0
- sage/graphs/generators/all.py +1 -0
- sage/graphs/generators/basic.py +1769 -0
- sage/graphs/generators/chessboard.py +538 -0
- sage/graphs/generators/classical_geometries.py +1611 -0
- sage/graphs/generators/degree_sequence.py +235 -0
- sage/graphs/generators/distance_regular.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generators/distance_regular.pyx +2846 -0
- sage/graphs/generators/families.py +4759 -0
- sage/graphs/generators/intersection.py +565 -0
- sage/graphs/generators/platonic_solids.py +262 -0
- sage/graphs/generators/random.py +2623 -0
- sage/graphs/generators/smallgraphs.py +5741 -0
- sage/graphs/generators/world_map.py +724 -0
- sage/graphs/generic_graph.py +26867 -0
- sage/graphs/generic_graph_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generic_graph_pyx.pxd +34 -0
- sage/graphs/generic_graph_pyx.pyx +1673 -0
- sage/graphs/genus.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/genus.pyx +622 -0
- sage/graphs/graph.py +9645 -0
- sage/graphs/graph_coloring.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_coloring.pyx +2284 -0
- sage/graphs/graph_database.py +1177 -0
- sage/graphs/graph_decompositions/all.py +1 -0
- sage/graphs/graph_decompositions/bandwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
- sage/graphs/graph_decompositions/clique_separators.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.pyx +616 -0
- sage/graphs/graph_decompositions/cutwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
- sage/graphs/graph_decompositions/fast_digraph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
- sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
- sage/graphs/graph_decompositions/graph_products.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/graph_products.pyx +508 -0
- sage/graphs/graph_decompositions/modular_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
- sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
- sage/graphs/graph_decompositions/slice_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
- sage/graphs/graph_decompositions/slice_decomposition.pyx +1106 -0
- sage/graphs/graph_decompositions/tree_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
- sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
- sage/graphs/graph_decompositions/vertex_separation.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
- sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
- sage/graphs/graph_editor.py +82 -0
- sage/graphs/graph_generators.py +3314 -0
- sage/graphs/graph_generators_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_generators_pyx.pyx +95 -0
- sage/graphs/graph_input.py +812 -0
- sage/graphs/graph_latex.py +2064 -0
- sage/graphs/graph_list.py +410 -0
- sage/graphs/graph_plot.py +1756 -0
- sage/graphs/graph_plot_js.py +338 -0
- sage/graphs/hyperbolicity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/hyperbolicity.pyx +1704 -0
- sage/graphs/hypergraph_generators.py +364 -0
- sage/graphs/independent_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/independent_sets.pxd +13 -0
- sage/graphs/independent_sets.pyx +402 -0
- sage/graphs/isgci.py +1033 -0
- sage/graphs/isoperimetric_inequalities.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/isoperimetric_inequalities.pyx +489 -0
- sage/graphs/line_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/line_graph.pyx +743 -0
- sage/graphs/lovasz_theta.py +77 -0
- sage/graphs/matching.py +1633 -0
- sage/graphs/matching_covered_graph.py +3590 -0
- sage/graphs/orientations.py +1489 -0
- sage/graphs/partial_cube.py +459 -0
- sage/graphs/path_enumeration.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/path_enumeration.pyx +2040 -0
- sage/graphs/pq_trees.py +1129 -0
- sage/graphs/print_graphs.py +201 -0
- sage/graphs/schnyder.py +865 -0
- sage/graphs/spanning_tree.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/spanning_tree.pyx +1457 -0
- sage/graphs/strongly_regular_db.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/strongly_regular_db.pyx +3340 -0
- sage/graphs/traversals.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/traversals.pxd +9 -0
- sage/graphs/traversals.pyx +1872 -0
- sage/graphs/trees.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/trees.pxd +15 -0
- sage/graphs/trees.pyx +310 -0
- sage/graphs/tutte_polynomial.py +713 -0
- sage/graphs/views.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/views.pyx +794 -0
- sage/graphs/weakly_chordal.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/weakly_chordal.pyx +604 -0
- sage/groups/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
- sage/knots/all.py +6 -0
- sage/knots/free_knotinfo_monoid.py +507 -0
- sage/knots/gauss_code.py +291 -0
- sage/knots/knot.py +682 -0
- sage/knots/knot_table.py +284 -0
- sage/knots/knotinfo.py +2900 -0
- sage/knots/link.py +4715 -0
- sage/sandpiles/all.py +13 -0
- sage/sandpiles/examples.py +225 -0
- sage/sandpiles/sandpile.py +6365 -0
- sage/topology/all.py +22 -0
- sage/topology/cell_complex.py +1214 -0
- sage/topology/cubical_complex.py +1976 -0
- sage/topology/delta_complex.py +1806 -0
- sage/topology/filtered_simplicial_complex.py +744 -0
- sage/topology/moment_angle_complex.py +823 -0
- sage/topology/simplicial_complex.py +5160 -0
- sage/topology/simplicial_complex_catalog.py +92 -0
- sage/topology/simplicial_complex_examples.py +1680 -0
- sage/topology/simplicial_complex_homset.py +205 -0
- sage/topology/simplicial_complex_morphism.py +836 -0
- sage/topology/simplicial_set.py +4102 -0
- sage/topology/simplicial_set_catalog.py +55 -0
- sage/topology/simplicial_set_constructions.py +2954 -0
- sage/topology/simplicial_set_examples.py +865 -0
- sage/topology/simplicial_set_morphism.py +1464 -0
sage/knots/gauss_code.py
ADDED
@@ -0,0 +1,291 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
# sage.doctest: needs sage.graphs
|
3
|
+
"""
|
4
|
+
Helper functions related to Gauss codes of knots
|
5
|
+
|
6
|
+
This contains in particular a function that takes a signed Gauss code
|
7
|
+
and builds the list of local orientations at every crossing. This involves
|
8
|
+
making choices, but allows to build a knot from just a signed Gauss code.
|
9
|
+
|
10
|
+
The following convention is used for signed Gauss codes: a negative
|
11
|
+
number corresponds to an over-crossing.
|
12
|
+
|
13
|
+
REFERENCES:
|
14
|
+
|
15
|
+
- https://math.stackexchange.com/questions/1233249/recovering-knot-crossing-orientations-from-a-gauss-code-or-dowker-notation
|
16
|
+
|
17
|
+
.. [Kauf1999] Louis H. Kauffman, *Virtual Knot Theory*, Europ. J. Combinatorics
|
18
|
+
(1999) 20, 663-691 ; http://homepages.math.uic.edu/~kauffman/VKT.pdf
|
19
|
+
"""
|
20
|
+
# ****************************************************************************
|
21
|
+
# Copyright (C) 2019 Frédéric Chapoton <fchapoton2@gmail.com>
|
22
|
+
#
|
23
|
+
# This program is free software: you can redistribute it and/or modify
|
24
|
+
# it under the terms of the GNU General Public License as published by
|
25
|
+
# the Free Software Foundation, either version 2 of the License, or
|
26
|
+
# (at your option) any later version.
|
27
|
+
# https://www.gnu.org/licenses/
|
28
|
+
# ****************************************************************************
|
29
|
+
from sage.graphs.graph import Graph
|
30
|
+
|
31
|
+
|
32
|
+
def dowker_to_gauss(code):
|
33
|
+
"""
|
34
|
+
Convert from Dowker-Thistlethwaite code to signed Gauss code.
|
35
|
+
|
36
|
+
EXAMPLES::
|
37
|
+
|
38
|
+
sage: from sage.knots.gauss_code import dowker_to_gauss
|
39
|
+
sage: dowker_to_gauss([6,-12,2,8,-4,-10])
|
40
|
+
[-3, 1, 6, -2, -1, 3, -4, 4, 2, -5, 5, -6]
|
41
|
+
sage: dowker_to_gauss([-4,-6,-2])
|
42
|
+
[2, -1, 3, -2, 1, -3]
|
43
|
+
|
44
|
+
TESTS::
|
45
|
+
|
46
|
+
sage: dowker_to_gauss([])
|
47
|
+
[]
|
48
|
+
"""
|
49
|
+
n = len(code)
|
50
|
+
# vertices are numbered by half of their even label
|
51
|
+
signes = {abs(j): (1 if j > 0 else -1) for j in code}
|
52
|
+
gauss = []
|
53
|
+
for i in range(1, 2 * n + 1):
|
54
|
+
if i % 2:
|
55
|
+
letter = code[(i - 1) // 2] // 2
|
56
|
+
gauss.append(-letter)
|
57
|
+
else:
|
58
|
+
gauss.append(signes[abs(i)] * i // 2)
|
59
|
+
return gauss
|
60
|
+
|
61
|
+
|
62
|
+
def recover_orientations(gauss):
|
63
|
+
"""
|
64
|
+
Create diagrammatic information from signed Gauss code.
|
65
|
+
|
66
|
+
This method is an auxiliary method, used for two different
|
67
|
+
goals. The first goal is to create a knot from the signed Gauss
|
68
|
+
code. This requires choosing at every crossing a local
|
69
|
+
orientation, in a compatible way. The second goal is to picture
|
70
|
+
the knot diagram using unicode. This goes through the creation of
|
71
|
+
a noncrossing matching diagram.
|
72
|
+
|
73
|
+
INPUT:
|
74
|
+
|
75
|
+
- signed Gauss code
|
76
|
+
|
77
|
+
OUTPUT:
|
78
|
+
|
79
|
+
- word, a permutation of the (unsigned) Gauss code
|
80
|
+
- list of positive (upwards) couplings in this word
|
81
|
+
- list of negative (downwards) couplings in this word
|
82
|
+
- list of signs, local orientations at each crossing
|
83
|
+
|
84
|
+
ALGORITHM:
|
85
|
+
|
86
|
+
The algorithm comes from Section 3 of [Kauf1999]_.
|
87
|
+
|
88
|
+
EXAMPLES::
|
89
|
+
|
90
|
+
sage: from sage.knots.gauss_code import recover_orientations
|
91
|
+
sage: G = [4,1,5,2,1,3,6,4,2,5,3,6]
|
92
|
+
sage: recover_orientations(G)
|
93
|
+
([4, 2, 1, 4, 6, 3, 1, 5, 2, 5, 3, 6],
|
94
|
+
[(1, 8), (2, 6)],
|
95
|
+
[(0, 3), (4, 11), (5, 10), (7, 9)],
|
96
|
+
[1, -1, 1, 1, -1, 1])
|
97
|
+
|
98
|
+
sage: G = [1,2,3,1,2,3]
|
99
|
+
sage: recover_orientations(G)
|
100
|
+
([1, 3, 2, 1, 2, 3], [(0, 3)], [(1, 5), (2, 4)], [1, 1, 1])
|
101
|
+
|
102
|
+
sage: G = [1, 2, 4, 5, 8, 1, 3, 4, 6, 7, 2, 3, 5, 6, 7, 8]
|
103
|
+
sage: recover_orientations(G)
|
104
|
+
([1, 8, 7, 6, 5, 4, 6, 7, 2, 4, 3, 2, 1, 3, 5, 8],
|
105
|
+
[(0, 12), (2, 7), (3, 6), (8, 11)],
|
106
|
+
[(1, 15), (4, 14), (5, 9), (10, 13)],
|
107
|
+
[1, -1, 1, -1, 1, -1, -1, 1])
|
108
|
+
|
109
|
+
TESTS::
|
110
|
+
|
111
|
+
sage: recover_orientations([])
|
112
|
+
([], [], [], [])
|
113
|
+
"""
|
114
|
+
signs_overunder = [1 if letter > 0 else -1 for letter in gauss]
|
115
|
+
gauss = [abs(x) for x in gauss]
|
116
|
+
n = len(gauss) // 2
|
117
|
+
|
118
|
+
# first step, perform subword reversals
|
119
|
+
changed = list(gauss)
|
120
|
+
for i in range(1, n + 1):
|
121
|
+
id0 = changed.index(i)
|
122
|
+
start = changed[:id0 + 1]
|
123
|
+
after0 = changed[id0 + 1:]
|
124
|
+
id1 = after0.index(i)
|
125
|
+
middle = list(reversed(after0[:id1]))
|
126
|
+
end = after0[id1:]
|
127
|
+
changed = start + middle + end
|
128
|
+
|
129
|
+
# second step, build the noncrossing planar diagram
|
130
|
+
pairings = [[] for _ in range(n)]
|
131
|
+
for pos, letter in enumerate(changed):
|
132
|
+
pairings[letter - 1].append(pos)
|
133
|
+
pairings = [tuple(ab) for ab in pairings]
|
134
|
+
|
135
|
+
def cross(ab, cd):
|
136
|
+
a, b = ab
|
137
|
+
c, d = cd
|
138
|
+
if c < a:
|
139
|
+
a, b, c, d = c, d, a, b
|
140
|
+
return a < c < b < d
|
141
|
+
|
142
|
+
colors = Graph([pairings, cross]).coloring()
|
143
|
+
if colors is None: # empty graph
|
144
|
+
positive = []
|
145
|
+
negative = []
|
146
|
+
elif len(colors) == 1:
|
147
|
+
positive = colors[0]
|
148
|
+
negative = []
|
149
|
+
else:
|
150
|
+
positive, negative = sorted(colors)
|
151
|
+
positive.sort()
|
152
|
+
negative.sort()
|
153
|
+
|
154
|
+
# third step, determine the local orientations
|
155
|
+
# this is done by following the knot
|
156
|
+
|
157
|
+
signs_local = {d: 1 for d in range(1, n + 1)}
|
158
|
+
for x, _ in negative:
|
159
|
+
signs_local[changed[x]] *= -1
|
160
|
+
|
161
|
+
jump_from = {}
|
162
|
+
for x, y in positive + negative:
|
163
|
+
jump_from[x] = y
|
164
|
+
jump_from[y] = x
|
165
|
+
|
166
|
+
direction = 1
|
167
|
+
position = 0
|
168
|
+
for k in range(2 * n):
|
169
|
+
letter = changed[position]
|
170
|
+
new_position = jump_from[position]
|
171
|
+
signe = signs_local[letter]
|
172
|
+
if new_position < position:
|
173
|
+
signe = -signe
|
174
|
+
if direction == 1:
|
175
|
+
signe *= signs_overunder[k]
|
176
|
+
signs_local[letter] = signe
|
177
|
+
direction = -direction
|
178
|
+
position = new_position + direction
|
179
|
+
|
180
|
+
signs_final = [signs_local[d] for d in range(1, n + 1)]
|
181
|
+
return changed, positive, negative, signs_final
|
182
|
+
|
183
|
+
|
184
|
+
def rectangular_diagram(gauss):
|
185
|
+
"""
|
186
|
+
Return a rectangular diagram and crossing coordinates.
|
187
|
+
|
188
|
+
INPUT:
|
189
|
+
|
190
|
+
- signed Gauss code
|
191
|
+
|
192
|
+
OUTPUT:
|
193
|
+
|
194
|
+
- graph whose vertices are the corners of the knot diagram
|
195
|
+
|
196
|
+
- positions of the horizontal and vertical crossings
|
197
|
+
|
198
|
+
EXAMPLES::
|
199
|
+
|
200
|
+
sage: from sage.knots.gauss_code import rectangular_diagram
|
201
|
+
sage: G = [4,1,5,2,1,3,6,4,2,5,3,6]
|
202
|
+
sage: rectangular_diagram(G)
|
203
|
+
(Graph on 18 vertices, ([(1, 3), (3, 7), (4, 6), (6, 2)],
|
204
|
+
[(4, 3), (6, 5)]))
|
205
|
+
|
206
|
+
sage: G = [1,2,3,1,2,3]
|
207
|
+
sage: rectangular_diagram(G)
|
208
|
+
(Graph on 10 vertices, ([(1, 3), (2, 2)], [(2, 1)]))
|
209
|
+
|
210
|
+
TESTS::
|
211
|
+
|
212
|
+
sage: rectangular_diagram([])
|
213
|
+
(Graph on 4 vertices, ([], []))
|
214
|
+
"""
|
215
|
+
if not gauss:
|
216
|
+
G = Graph()
|
217
|
+
verts = [(0, 0), (1, 0), (1, 1), (0, 1)]
|
218
|
+
for i in range(4):
|
219
|
+
G.add_edge(verts[i], verts[(i + 1) % 4])
|
220
|
+
G.set_pos({v: v for v in verts})
|
221
|
+
return G, ([], [])
|
222
|
+
|
223
|
+
changed, positive, negative, ori = recover_orientations(gauss)
|
224
|
+
|
225
|
+
n = len(changed)
|
226
|
+
G = Graph()
|
227
|
+
horizontal = []
|
228
|
+
vertical = []
|
229
|
+
for a, b in positive:
|
230
|
+
G.add_edge((a, a), (b, a))
|
231
|
+
G.add_edge((b, a), (b, b))
|
232
|
+
G.add_edge((a + 1, a + 1), (b + 1, a + 1))
|
233
|
+
G.add_edge((b + 1, a + 1), (b + 1, b + 1))
|
234
|
+
letter = changed[a]
|
235
|
+
if b != a + 1:
|
236
|
+
if ori[letter - 1] == -1:
|
237
|
+
horizontal.append((b, a + 1))
|
238
|
+
else:
|
239
|
+
vertical.append((b, a + 1))
|
240
|
+
for a, b in negative:
|
241
|
+
G.add_edge((a, a), (a, b))
|
242
|
+
G.add_edge((a, b), (b, b))
|
243
|
+
G.add_edge((a + 1, a + 1), (a + 1, b + 1))
|
244
|
+
G.add_edge((a + 1, b + 1), (b + 1, b + 1))
|
245
|
+
letter = changed[a]
|
246
|
+
if a + 1 != b:
|
247
|
+
if ori[letter - 1] == 1:
|
248
|
+
horizontal.append((a + 1, b))
|
249
|
+
else:
|
250
|
+
vertical.append((a + 1, b))
|
251
|
+
|
252
|
+
# closing the loop on either side
|
253
|
+
total = positive + negative
|
254
|
+
debut = next(iter(b for a, b in total if a == 0))
|
255
|
+
fin = next(iter(n - 1 - a for a, b in total if b == n - 1))
|
256
|
+
if debut > fin:
|
257
|
+
G.add_edge((0, 0), (0, n))
|
258
|
+
G.add_edge((0, n), (n, n))
|
259
|
+
else:
|
260
|
+
G.add_edge((0, 0), (n, 0))
|
261
|
+
G.add_edge((n, 0), (n, n))
|
262
|
+
|
263
|
+
# remove useless vertices and double edges
|
264
|
+
for a, b in list(G):
|
265
|
+
(x, y), (xx, yy) = sorted(G.neighbors((a, b)))
|
266
|
+
if x == xx == a:
|
267
|
+
G.delete_vertex((a, b))
|
268
|
+
G.add_edge((a, y), (a, yy))
|
269
|
+
elif y == yy == b:
|
270
|
+
G.delete_vertex((a, b))
|
271
|
+
G.add_edge((x, b), (xx, b))
|
272
|
+
|
273
|
+
# renumber lines and columns to remove empty ones
|
274
|
+
lignes = sorted(set(a for a, _ in G))
|
275
|
+
colonnes = sorted(set(b for _, b in G))
|
276
|
+
d_lig = {a: i for i, a in enumerate(lignes)}
|
277
|
+
d_col = {b: i for i, b in enumerate(colonnes)}
|
278
|
+
|
279
|
+
horizontal = sorted((d_lig[a], d_col[b]) for a, b in horizontal)
|
280
|
+
vertical = sorted((d_lig[a], d_col[b]) for a, b in vertical)
|
281
|
+
|
282
|
+
def standard(ab):
|
283
|
+
a, b = ab
|
284
|
+
return (d_lig[a], d_col[b])
|
285
|
+
|
286
|
+
G.relabel(standard)
|
287
|
+
|
288
|
+
# setting the positions
|
289
|
+
positions = {ab: ab for ab in G}
|
290
|
+
G.set_pos(positions)
|
291
|
+
return G, (horizontal, vertical)
|