From 2a4f28a68b0e64a123281b82b5bdfdd1367967f0 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 26 Aug 2025 14:18:29 -0400 Subject: [PATCH 1/3] src/sage/graphs/generators: add Golay code graph pytests The algorithm to construct the Shortened 000 111 extended binary Golay code graph takes a long time, and we plan to cache its vertices and edges. To ensure that the cached data continue to agree with the construction, we add a new pytest file that checks the two for isomorphism. --- src/sage/graphs/generators/generators_test.py | 34 +++++++++++++++++++ src/sage/graphs/generators/meson.build | 1 + 2 files changed, 35 insertions(+) create mode 100644 src/sage/graphs/generators/generators_test.py diff --git a/src/sage/graphs/generators/generators_test.py b/src/sage/graphs/generators/generators_test.py new file mode 100644 index 00000000000..5b57f1cd459 --- /dev/null +++ b/src/sage/graphs/generators/generators_test.py @@ -0,0 +1,34 @@ +import pytest + + +def test_shortened_000_111_extended_binary_Golay_code_graph(): + r""" + Test that Sage produces a graph equal to the one that we get + from this construction. + + The construction itself takes a long time. + """ + from sage.coding import codes_catalog + from sage.coding.linear_code import LinearCode + from sage.graphs.generators.distance_regular import ( + shortened_000_111_extended_binary_Golay_code_graph + ) + from sage.matrix.constructor import matrix + from sage.rings.finite_rings.finite_field_constructor import FiniteField + + code = codes_catalog.GolayCode(FiniteField(2)) + C_basis = code.basis() + + # now special shortening + v = C_basis[0] + C_basis[1] + C_basis[2] # v has 111 at the start + C_basis = C_basis[3:] + C_basis.append(v) + C_basis = list(map(lambda x: x[3:], C_basis)) + + code = LinearCode(matrix(FiniteField(2), C_basis)) + G = code.cosetGraph() + G.name("Shortened 000 111 extended binary Golay code") + assert G.is_distance_regular() + + H = shortened_000_111_extended_binary_Golay_code_graph() + assert G == H diff --git a/src/sage/graphs/generators/meson.build b/src/sage/graphs/generators/meson.build index f6634fe7d8d..74955841af9 100644 --- a/src/sage/graphs/generators/meson.build +++ b/src/sage/graphs/generators/meson.build @@ -6,6 +6,7 @@ py.install_sources( 'classical_geometries.py', 'degree_sequence.py', 'families.py', + 'generators_test.py', 'intersection.py', 'platonic_solids.py', 'random.py', From 27eaeb667076ecf5c315a830ad129381646c5a62 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 26 Aug 2025 14:21:10 -0400 Subject: [PATCH 2/3] src/sage/graphs/generators: add pickled Golay code graph data Add a pickled/xz'd list of vertices and edges for the Shortened 000 111 extended binary Golay code graph. It's much faster to construct this graph from cached data than it is to do it on-the-fly. --- src/sage/graphs/generators/meson.build | 1 + ...1_extended_binary_Golay_code_graph.pickle.xz | Bin 0 -> 45604 bytes 2 files changed, 1 insertion(+) create mode 100644 src/sage/graphs/generators/shortened_000_111_extended_binary_Golay_code_graph.pickle.xz diff --git a/src/sage/graphs/generators/meson.build b/src/sage/graphs/generators/meson.build index 74955841af9..ef1ca93250e 100644 --- a/src/sage/graphs/generators/meson.build +++ b/src/sage/graphs/generators/meson.build @@ -10,6 +10,7 @@ py.install_sources( 'intersection.py', 'platonic_solids.py', 'random.py', + 'shortened_000_111_extended_binary_Golay_code_graph.pickle.xz', 'smallgraphs.py', 'trees.pxd', 'world_map.py', diff --git a/src/sage/graphs/generators/shortened_000_111_extended_binary_Golay_code_graph.pickle.xz b/src/sage/graphs/generators/shortened_000_111_extended_binary_Golay_code_graph.pickle.xz new file mode 100644 index 0000000000000000000000000000000000000000..e46e00615d706d1a482635425de7252b73d28ee8 GIT binary patch literal 45604 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¯Ntdb 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 U80P^X1hK?t`vL#}000D8TE4q*`2YX_ literal 0 HcmV?d00001 From 8260d63e3af21300aa6c628c94cc138cd5491aa0 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 26 Aug 2025 14:22:33 -0400 Subject: [PATCH 3/3] src/sage/graphs/generators: speed up Golay code graph construction Reimplement shortened_000_111_extended_binary_Golay_code_graph() to load its vertices and edges from compressed, pickled data. This speeds up the construction significantly, and eliminates a persistent CI warning about the corresponding test being slow. --- .../graphs/generators/distance_regular.pyx | 62 +++++++++++++------ 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/src/sage/graphs/generators/distance_regular.pyx b/src/sage/graphs/generators/distance_regular.pyx index 570012ac3fc..4b5c8ac7657 100644 --- a/src/sage/graphs/generators/distance_regular.pyx +++ b/src/sage/graphs/generators/distance_regular.pyx @@ -488,34 +488,58 @@ def shortened_000_111_extended_binary_Golay_code_graph(): EXAMPLES:: sage: # long time, needs sage.modules sage.rings.finite_rings - sage: G = graphs.shortened_000_111_extended_binary_Golay_code_graph() # 25 s + sage: G = graphs.shortened_000_111_extended_binary_Golay_code_graph() sage: G.is_distance_regular(True) ([21, 20, 16, 9, 2, 1, None], [None, 1, 2, 3, 16, 20, 21]) ALGORITHM: - Compute the extended binary Golay code. Compute its subcode whose codewords - start with 000 or 111. Remove the first 3 entries from all the codewords - from the new linear code and compute its coset graph. + The vertices and edges of this graph have been precomputed and + pickled, so truthfully, we just unpickle them and pass them to the + Graph constructor. But the algorithm used to compute those + vertices and edges in the first place is, - REFERENCES: - - Description and construction of this graph can be found in [BCN1989]_ p. 365. - """ - from sage.coding.linear_code import LinearCode - - code = codes.GolayCode(GF(2)) - C_basis = code.basis() + #. Compute the extended binary Golay code. + #. Compute its subcode whose codewords start with 000 or 111. + #. Remove the first 3 entries from all the codewords from the + new linear code and compute its coset graph. - # now special shortening - v = C_basis[0] + C_basis[1] + C_basis[2] # v has 111 at the start - C_basis = C_basis[3:] - C_basis.append(v) - C_basis = list(map(lambda x: x[3:], C_basis)) + This construction is tested in ``generators_test.py``, where the + result is compared with the result from this method. - code = LinearCode(Matrix(GF(2), C_basis)) + REFERENCES: - G = code.cosetGraph() + The description and construction of this graph can be found in + [BCN1989]_, page 365. + """ + import lzma + from importlib.resources import as_file, files + from pickle import load + + # Path to the pickled-and-xz'd list of (vertices, edges) + ppath = files('sage.graphs.generators').joinpath( + "shortened_000_111_extended_binary_Golay_code_graph.pickle.xz" + ) + + with as_file(ppath) as p: + with lzma.open(p) as f: + vs_and_es = load(f, fix_imports=False) + + # Vertices/edges are pickled as tuples of ints, but should be + # vectors with entries in GF(2). + V = VectorSpace(GF(2), 21) + for i in range(2048): + # vertex i + vs_and_es[0][i] = V(vs_and_es[0][i]) + vs_and_es[0][i].set_immutable() + for i in range(21504): + # edge i = (v1, v2, l) + vs_and_es[1][i][0] = V(vs_and_es[1][i][0]) # v1 + vs_and_es[1][i][0].set_immutable() + vs_and_es[1][i][1] = V(vs_and_es[1][i][1]) # v2 + vs_and_es[1][i][1].set_immutable() + + G = Graph(vs_and_es, format='vertices_and_edges') G.name("Shortened 000 111 extended binary Golay code") return G