From 1978c7dc47f29c35622d0dd90eddd4937da371e6 Mon Sep 17 00:00:00 2001 From: Ivo Maffei Date: Tue, 28 Jul 2020 16:43:02 +0200 Subject: [PATCH 1/8] added a few sporadic distance regular graphs --- src/sage/graphs/distance_regular.pyx | 212 +++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 src/sage/graphs/distance_regular.pyx diff --git a/src/sage/graphs/distance_regular.pyx b/src/sage/graphs/distance_regular.pyx new file mode 100644 index 00000000000..436a86d6ec4 --- /dev/null +++ b/src/sage/graphs/distance_regular.pyx @@ -0,0 +1,212 @@ +r""" +Dabase of distance regular graphs + +In this module we construct several distance regular graphs +and group them in a function that maps intersection arrays +to graphs. + +For a survey on distance-regular graph see [BCN1989]_ or [VDKT2016]_. + +EXAMPLES:: + + sage: G = graphs.cocliques_HoffmannSingleton() + sage: G.is_distance_regular() + True + +AUTHORS: + +- Ivo Maffei (2020-07-28): initial version + +""" + +# **************************************************************************** +# Copyright (C) 2020 Ivo Maffei +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.graphs.graph import Graph +from sage.libs.gap.libgap import libgap +from sage.modules.free_module import VectorSpace +from sage.modules.free_module_element import vector +from sage.rings.finite_rings.finite_field_constructor import GF + +def cocliques_HoffmannSingleton(): + r""" + Return the graph obtained from the cocliques of the Hoffmann-Singleton graph. + + This is a distance-regular graph with intersecion array + `[15, 14, 10, 3; 1, 5, 12, 15]`. + + EXAMPLES:: + + sage: G = graphs.cocliques_HoffmannSingleton() + sage: G.is_distance_regular(True) + ([15, 14, 10, 3, None], [None, 1, 5, 12, 15]) + + REFERENCES: + + The construction of this graph can be found in [BCN1989]_ p. 392. + """ + from sage.graphs.graph_generators import GraphGenerators + D = GraphGenerators.HoffmanSingletonGraph() + DC = D.complement() + + cocliques = DC.cliques_maximum() # 100 of this + + edges = [] + for i in range(100): + sC = frozenset(cocliques[i]) + for j in range(i+1,100): + if len(sC.intersection(cocliques[j])) == 8: + sC2 = frozenset(cocliques[j]) + edges.append( (sC,sC2) ) + + G = Graph(edges,format="list_of_edges") + return G + + +def locally_GQ42_graph(): + r""" + Return the unique amply regular graph which is locally a generalised + quadrangle. + + This graph is distance-regular with intersection array + `[45, 32, 12, 1; 1, 6, 32, 45]`. + + This graph is also distance-transitive. + + EXAMPLES:: + + sage: G = graphs.locally_GQ42_graph() + sage: G.is_distance_regular(True) + ([45, 32, 12, 1, None], [None, 1, 6, 32, 45]) + + .. NOTE:: + + This function needs the GAP's package AtlasRep [WPNBBAtl]_. + Install it via ``sage -i gap_packages``. + """ + H = libgap.AtlasGroup("3^2.U4(3).D8",libgap.NrMovedPoints,756) + Ns = H.NormalSubgroups() + for N in Ns: + if len(N.GeneratorsSmallest()) == 7: # there is only one + break + + G = Graph(libgap.Orbit(N,[1,9],libgap.OnSets), format='list_of_edges') + G.name("locally GQ(4,2) graph") + return G + + +def ConwaySmith_for_3S7(): + r""" + Return the Conway-Smith graph related to `3 Sym(7)`. + + This is a distance-regular graph with intersection array + `[10, 6, 4, 1; 1, 2, 6, 10]`. + + EXAMPLES:: + + sage: G = graphs.ConwaySmith_for_3S7() + sage: G.is_distance_regular(True) + ([10, 6, 4, 1, None], [None, 1, 2, 6, 10]) + """ + from sage.rings.number_field.number_field import CyclotomicField + + F = CyclotomicField(3) + w = F.gen() + + V= VectorSpace(GF(4), 6) + z2 = GF(4)('z2') # GF(4) = {0,1,z2, z2+1} + + W = V.span([(0,0,1,1,1,1), (0,1,0,1,z2,z2+1), (1,0,0,1,z2+1,z2)]) + # we only need the 45 vectors with 2 zero entries + # we also embed everything into CC + + K = [] + for v in W: + #check zero entries + zeros = 0 + for x in v: + if x == 0: + zeros += 1 + + if zeros == 2: + # send to F and in K + # z2 -> w + # z2+1 -> w^2 + vv = [] # new vector + for x in v: + if x == z2: + vv.append(w) + elif x == z2+1: + vv.append(w**2) + else: + vv.append(int(x)) # this is weirdly needed for some reason + + # now vv is the new vector in F + vv = vector(F, vv) + K.append(vv) + + # we need to add other vectors + for i in range(6): + #create e_i + ei = [0]*6 + ei[i] = 1 + ei = vector(F, ei) + + K.append(2 * ei) + K.append(2 * w * ei) + K.append(2 * w**2 * ei) + # now K is all the 63 vertices + + def has_edge(u,v): + com = 0 + for i in range(6): + com += u[i].conjugate() * v[i] + + if com == 2: + return True + return False + + G = Graph() + length = len(K) + for i in range(length): + K[i].set_immutable() + for j in range(i+1, length): + if has_edge(K[i], K[j]): + K[j].set_immutable() + G.add_edge((K[i], K[j])) + + G.name("Conway-Smith graph for 3S7") + return G + +def graph_3O73(): + r""" + Return the graph related to the group `3 O(7,3)`. + + This graph is distance-regular with intersection array + `[117, 80, 24, 1; 1, 12, 80, 117]`. + + The graph is also distance transitive with "3.O(7,3)" as automorphism + group + + EXAMPLES:: + + sage: G = graphs.graph_3O73() + sage: G.is_distance_regular(True) + ([117, 80, 24, 1, None], [None, 1, 12, 80, 117]) + + .. NOTE:: + + This function needs the GAP's package AtlasRep [WPNBBAtl]_. + Install it via ``sage -i gap_packages``. + """ + group = libgap.AtlasGroup("3.O7(3)",libgap.NrMovedPoints,1134) + G = Graph(group.Orbit([1,3], libgap.OnSets), format='list_of_edges') + G.name("Distance transitive graph with automorphism group 3.O_7(3)") + return G From 384fb27a89b10c3abd3fd9706e56a3d6cf2ed0c3 Mon Sep 17 00:00:00 2001 From: Ivo Maffei Date: Wed, 29 Jul 2020 21:03:06 +0200 Subject: [PATCH 2/8] moved file to generators; fixed tests --- src/sage/graphs/distance_regular.pyx | 212 ------------------ .../graphs/generators/distance_regular.pyx | 111 +++++++++ 2 files changed, 111 insertions(+), 212 deletions(-) delete mode 100644 src/sage/graphs/distance_regular.pyx diff --git a/src/sage/graphs/distance_regular.pyx b/src/sage/graphs/distance_regular.pyx deleted file mode 100644 index 436a86d6ec4..00000000000 --- a/src/sage/graphs/distance_regular.pyx +++ /dev/null @@ -1,212 +0,0 @@ -r""" -Dabase of distance regular graphs - -In this module we construct several distance regular graphs -and group them in a function that maps intersection arrays -to graphs. - -For a survey on distance-regular graph see [BCN1989]_ or [VDKT2016]_. - -EXAMPLES:: - - sage: G = graphs.cocliques_HoffmannSingleton() - sage: G.is_distance_regular() - True - -AUTHORS: - -- Ivo Maffei (2020-07-28): initial version - -""" - -# **************************************************************************** -# Copyright (C) 2020 Ivo Maffei -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# https://www.gnu.org/licenses/ -# **************************************************************************** - -from sage.graphs.graph import Graph -from sage.libs.gap.libgap import libgap -from sage.modules.free_module import VectorSpace -from sage.modules.free_module_element import vector -from sage.rings.finite_rings.finite_field_constructor import GF - -def cocliques_HoffmannSingleton(): - r""" - Return the graph obtained from the cocliques of the Hoffmann-Singleton graph. - - This is a distance-regular graph with intersecion array - `[15, 14, 10, 3; 1, 5, 12, 15]`. - - EXAMPLES:: - - sage: G = graphs.cocliques_HoffmannSingleton() - sage: G.is_distance_regular(True) - ([15, 14, 10, 3, None], [None, 1, 5, 12, 15]) - - REFERENCES: - - The construction of this graph can be found in [BCN1989]_ p. 392. - """ - from sage.graphs.graph_generators import GraphGenerators - D = GraphGenerators.HoffmanSingletonGraph() - DC = D.complement() - - cocliques = DC.cliques_maximum() # 100 of this - - edges = [] - for i in range(100): - sC = frozenset(cocliques[i]) - for j in range(i+1,100): - if len(sC.intersection(cocliques[j])) == 8: - sC2 = frozenset(cocliques[j]) - edges.append( (sC,sC2) ) - - G = Graph(edges,format="list_of_edges") - return G - - -def locally_GQ42_graph(): - r""" - Return the unique amply regular graph which is locally a generalised - quadrangle. - - This graph is distance-regular with intersection array - `[45, 32, 12, 1; 1, 6, 32, 45]`. - - This graph is also distance-transitive. - - EXAMPLES:: - - sage: G = graphs.locally_GQ42_graph() - sage: G.is_distance_regular(True) - ([45, 32, 12, 1, None], [None, 1, 6, 32, 45]) - - .. NOTE:: - - This function needs the GAP's package AtlasRep [WPNBBAtl]_. - Install it via ``sage -i gap_packages``. - """ - H = libgap.AtlasGroup("3^2.U4(3).D8",libgap.NrMovedPoints,756) - Ns = H.NormalSubgroups() - for N in Ns: - if len(N.GeneratorsSmallest()) == 7: # there is only one - break - - G = Graph(libgap.Orbit(N,[1,9],libgap.OnSets), format='list_of_edges') - G.name("locally GQ(4,2) graph") - return G - - -def ConwaySmith_for_3S7(): - r""" - Return the Conway-Smith graph related to `3 Sym(7)`. - - This is a distance-regular graph with intersection array - `[10, 6, 4, 1; 1, 2, 6, 10]`. - - EXAMPLES:: - - sage: G = graphs.ConwaySmith_for_3S7() - sage: G.is_distance_regular(True) - ([10, 6, 4, 1, None], [None, 1, 2, 6, 10]) - """ - from sage.rings.number_field.number_field import CyclotomicField - - F = CyclotomicField(3) - w = F.gen() - - V= VectorSpace(GF(4), 6) - z2 = GF(4)('z2') # GF(4) = {0,1,z2, z2+1} - - W = V.span([(0,0,1,1,1,1), (0,1,0,1,z2,z2+1), (1,0,0,1,z2+1,z2)]) - # we only need the 45 vectors with 2 zero entries - # we also embed everything into CC - - K = [] - for v in W: - #check zero entries - zeros = 0 - for x in v: - if x == 0: - zeros += 1 - - if zeros == 2: - # send to F and in K - # z2 -> w - # z2+1 -> w^2 - vv = [] # new vector - for x in v: - if x == z2: - vv.append(w) - elif x == z2+1: - vv.append(w**2) - else: - vv.append(int(x)) # this is weirdly needed for some reason - - # now vv is the new vector in F - vv = vector(F, vv) - K.append(vv) - - # we need to add other vectors - for i in range(6): - #create e_i - ei = [0]*6 - ei[i] = 1 - ei = vector(F, ei) - - K.append(2 * ei) - K.append(2 * w * ei) - K.append(2 * w**2 * ei) - # now K is all the 63 vertices - - def has_edge(u,v): - com = 0 - for i in range(6): - com += u[i].conjugate() * v[i] - - if com == 2: - return True - return False - - G = Graph() - length = len(K) - for i in range(length): - K[i].set_immutable() - for j in range(i+1, length): - if has_edge(K[i], K[j]): - K[j].set_immutable() - G.add_edge((K[i], K[j])) - - G.name("Conway-Smith graph for 3S7") - return G - -def graph_3O73(): - r""" - Return the graph related to the group `3 O(7,3)`. - - This graph is distance-regular with intersection array - `[117, 80, 24, 1; 1, 12, 80, 117]`. - - The graph is also distance transitive with "3.O(7,3)" as automorphism - group - - EXAMPLES:: - - sage: G = graphs.graph_3O73() - sage: G.is_distance_regular(True) - ([117, 80, 24, 1, None], [None, 1, 12, 80, 117]) - - .. NOTE:: - - This function needs the GAP's package AtlasRep [WPNBBAtl]_. - Install it via ``sage -i gap_packages``. - """ - group = libgap.AtlasGroup("3.O7(3)",libgap.NrMovedPoints,1134) - G = Graph(group.Orbit([1,3], libgap.OnSets), format='list_of_edges') - G.name("Distance transitive graph with automorphism group 3.O_7(3)") - return G diff --git a/src/sage/graphs/generators/distance_regular.pyx b/src/sage/graphs/generators/distance_regular.pyx index dcf979914aa..d5c0a5e343f 100644 --- a/src/sage/graphs/generators/distance_regular.pyx +++ b/src/sage/graphs/generators/distance_regular.pyx @@ -1,5 +1,9 @@ r""" +<<<<<<< HEAD Database of distance regular graphs +======= +Dabase of distance regular graphs +>>>>>>> moved file to generators; fixed tests In this module we construct several distance regular graphs and group them in a function that maps intersection arrays @@ -39,7 +43,11 @@ def cocliques_HoffmannSingleton(): r""" Return the graph obtained from the cocliques of the Hoffmann-Singleton graph. +<<<<<<< HEAD This is a distance-regular graph with intersection array +======= + This is a distance-regular graph with intersecion array +>>>>>>> moved file to generators; fixed tests `[15, 14, 10, 3; 1, 5, 12, 15]`. EXAMPLES:: @@ -53,6 +61,7 @@ def cocliques_HoffmannSingleton(): The construction of this graph can be found in [BCN1989]_ p. 392. """ from sage.graphs.graph_generators import GraphGenerators +<<<<<<< HEAD import itertools D = GraphGenerators.HoffmanSingletonGraph() @@ -72,6 +81,29 @@ def locally_GQ42_distance_transitive_graph(): r""" Return the unique amply regular graph with `\mu = 6` which is locally a generalised quadrangle. +======= + D = GraphGenerators.HoffmanSingletonGraph() + DC = D.complement() + + cocliques = DC.cliques_maximum() # 100 of this + + edges = [] + for i in range(100): + sC = frozenset(cocliques[i]) + for j in range(i+1,100): + if len(sC.intersection(cocliques[j])) == 8: + sC2 = frozenset(cocliques[j]) + edges.append( (sC,sC2) ) + + G = Graph(edges,format="list_of_edges") + return G + + +def locally_GQ42_graph(): + r""" + Return the unique amply regular graph which is locally a generalised + quadrangle. +>>>>>>> moved file to generators; fixed tests This graph is distance-regular with intersection array `[45, 32, 12, 1; 1, 6, 32, 45]`. @@ -80,6 +112,7 @@ def locally_GQ42_distance_transitive_graph(): EXAMPLES:: +<<<<<<< HEAD sage: G = graphs.locally_GQ42_distance_transitive_graph() # optional - internet sage: G.is_distance_regular(True) # optional - internet ([45, 32, 12, 1, None], [None, 1, 6, 32, 45]) @@ -90,13 +123,30 @@ def locally_GQ42_distance_transitive_graph(): This construction is due to Dima Pasechnik. """ H = libgap.AtlasGroup("3^2.U4(3).D8", libgap.NrMovedPoints, 756) +======= + sage: G = graphs.locally_GQ42_graph() # optional - gap_packages + sage: G.is_distance_regular(True) # optional - gap_packages + ([45, 32, 12, 1, None], [None, 1, 6, 32, 45]) + + .. NOTE:: + + This function needs the GAP's package AtlasRep [WPNBBAtl]_. + Install it via ``sage -i gap_packages``. + """ + H = libgap.AtlasGroup("3^2.U4(3).D8",libgap.NrMovedPoints,756) +>>>>>>> moved file to generators; fixed tests Ns = H.NormalSubgroups() for N in Ns: if len(N.GeneratorsSmallest()) == 7: # there is only one break +<<<<<<< HEAD G = Graph(libgap.Orbit(N, [1, 9], libgap.OnSets), format='list_of_edges') G.name("locally GQ(4,2) distance transitive graph") +======= + G = Graph(libgap.Orbit(N,[1,9],libgap.OnSets), format='list_of_edges') + G.name("locally GQ(4,2) graph") +>>>>>>> moved file to generators; fixed tests return G @@ -112,6 +162,7 @@ def ConwaySmith_for_3S7(): sage: G = graphs.ConwaySmith_for_3S7() sage: G.is_distance_regular(True) ([10, 6, 4, 1, None], [None, 1, 2, 6, 10]) +<<<<<<< HEAD REFERENCES: @@ -120,12 +171,20 @@ def ConwaySmith_for_3S7(): """ from sage.rings.number_field.number_field import CyclotomicField import itertools +======= + """ + from sage.rings.number_field.number_field import CyclotomicField +>>>>>>> moved file to generators; fixed tests F = CyclotomicField(3) w = F.gen() V= VectorSpace(GF(4), 6) +<<<<<<< HEAD z2 = GF(4)('z2') # GF(4) = {0, 1, z2, z2+1} +======= + z2 = GF(4)('z2') # GF(4) = {0,1,z2, z2+1} +>>>>>>> moved file to generators; fixed tests W = V.span([(0,0,1,1,1,1), (0,1,0,1,z2,z2+1), (1,0,0,1,z2+1,z2)]) # we only need the 45 vectors with 2 zero entries @@ -133,10 +192,17 @@ def ConwaySmith_for_3S7(): K = [] for v in W: +<<<<<<< HEAD # check zero entries zeros = 0 for x in v: if x.is_zero(): +======= + #check zero entries + zeros = 0 + for x in v: + if x == 0: +>>>>>>> moved file to generators; fixed tests zeros += 1 if zeros == 2: @@ -147,10 +213,17 @@ def ConwaySmith_for_3S7(): for x in v: if x == z2: vv.append(w) +<<<<<<< HEAD elif x == z2 + 1: vv.append(w**2) else: vv.append(int(x)) +======= + elif x == z2+1: + vv.append(w**2) + else: + vv.append(int(x)) # this is weirdly needed for some reason +>>>>>>> moved file to generators; fixed tests # now vv is the new vector in F vv = vector(F, vv) @@ -158,8 +231,13 @@ def ConwaySmith_for_3S7(): # we need to add other vectors for i in range(6): +<<<<<<< HEAD # create e_i ei = [0, 0, 0, 0, 0, 0] +======= + #create e_i + ei = [0]*6 +>>>>>>> moved file to generators; fixed tests ei[i] = 1 ei = vector(F, ei) @@ -168,6 +246,7 @@ def ConwaySmith_for_3S7(): K.append(2 * w**2 * ei) # now K is all the 63 vertices +<<<<<<< HEAD for v in K: v.set_immutable() @@ -178,6 +257,25 @@ def ConwaySmith_for_3S7(): for Ki, Kj in itertools.combinations(K, 2): if has_edge(Ki, Kj): G.add_edge((Ki, Kj)) +======= + def has_edge(u,v): + com = 0 + for i in range(6): + com += u[i].conjugate() * v[i] + + if com == 2: + return True + return False + + G = Graph() + length = len(K) + for i in range(length): + K[i].set_immutable() + for j in range(i+1, length): + if has_edge(K[i], K[j]): + K[j].set_immutable() + G.add_edge((K[i], K[j])) +>>>>>>> moved file to generators; fixed tests G.name("Conway-Smith graph for 3S7") return G @@ -194,6 +292,7 @@ def graph_3O73(): EXAMPLES:: +<<<<<<< HEAD sage: G = graphs.graph_3O73() # optional - internet sage: G.is_distance_regular(True) # optional - internet ([117, 80, 24, 1, None], [None, 1, 12, 80, 117]) @@ -204,6 +303,18 @@ def graph_3O73(): [BCN1989]_ p. 400. """ group = libgap.AtlasGroup("3.O7(3)", libgap.NrMovedPoints, 1134) +======= + sage: G = graphs.graph_3O73() # optional - gap_packages + sage: G.is_distance_regular(True) # optional - gap_packages + ([117, 80, 24, 1, None], [None, 1, 12, 80, 117]) + + .. NOTE:: + + This function needs the GAP's package AtlasRep [WPNBBAtl]_. + Install it via ``sage -i gap_packages``. + """ + group = libgap.AtlasGroup("3.O7(3)",libgap.NrMovedPoints,1134) +>>>>>>> moved file to generators; fixed tests G = Graph(libgap.Orbit(group, [1, 3], libgap.OnSets), format='list_of_edges') G.name("Distance transitive graph with automorphism group 3.O_7(3)") return G From 85b4d555702fdbb1fac743b580f489bdc68036ed Mon Sep 17 00:00:00 2001 From: Ivo Maffei Date: Fri, 31 Jul 2020 11:34:21 +0200 Subject: [PATCH 3/8] added 4 more sporadic drg --- .../graphs/generators/distance_regular.pyx | 101 ++++++++++++++++++ src/sage/graphs/graph_generators.py | 8 ++ 2 files changed, 109 insertions(+) diff --git a/src/sage/graphs/generators/distance_regular.pyx b/src/sage/graphs/generators/distance_regular.pyx index d5c0a5e343f..71f641defe4 100644 --- a/src/sage/graphs/generators/distance_regular.pyx +++ b/src/sage/graphs/generators/distance_regular.pyx @@ -318,3 +318,104 @@ def graph_3O73(): G = Graph(libgap.Orbit(group, [1, 3], libgap.OnSets), format='list_of_edges') G.name("Distance transitive graph with automorphism group 3.O_7(3)") return G + +def FosterGraph3S6(): + r""" + Return the Foster graph for `3.Sym(6)`. + + This graph is distance-regular with intersection array + `[6, 4, 2, 1; 1, 1, 4, 6]`. + + The graph is also distance transitive. + + EXAMPLES:: + + sage: G = graphs.FosterGraph3S6() + sage: G.is_distance_regular(True) + ([6, 4, 2, 1, None], [None, 1, 1, 4, 6]) + """ + + a = libgap.eval(("(2,6)(3,5)(4,11)(7,17)(8,16)(9,14)(13,22)(15,25)" + "(18,29)(19,28)(20,21)(24,30)(26,35)(27,33)(31,39)" + "(34,38)(36,43)(37,40)(42,44)")) + b = libgap.eval(("(1,2,7,12,4)(3,8,18,20,10)(5,9,19,21,11)(6,13,17,26,15)" + "(14,23,28,31,24)(16,22,29,36,27)(25,32,35,42,34)" + "(30,37,39,44,38)(33,40,43,45,41)")) + + group = libgap.Group(a,b) + + G = Graph(group.Orbit([1, 7], libgap.OnSets), format='list_of_edges') + G.name("Foster graph for 3.Sym(6) graph") + return G + +def J2Graph(): + r""" + Return the distance-transitive graph with automorphism group `J_2`. + + EXAMPLES:: + + sage: G = graphs.J2Graph() # optional - gap_packages + sage: G.is_distance_regular(True) # optional - gap_packages + ([10, 8, 8, 2, None], [None, 1, 1, 4, 5]) + + .. NOTE:: + + This function needs the GAP's package AtlasRep [WPNBBAtl]_. + Install it via ``sage -i gap_packages``. + """ + group = libgap.AtlasGroup("J2", libgap.NrMovedPoints, 315) + G = Graph(group.Orbit([1, 9], libgap.OnSets), format='list_of_edges') + G.name("J_2 graph") + return G + +def IvanovIvanovFaradjevGraph(): + r""" + Return the IvanovIvanovFaradjev graph. + + The graph is distance-transitive with automorphism group `3.M_{22}`. + + EXAMPLES:: + + sage: G = graphs.IvanovIvanovFaradjevGraph() + sage: G.is_distance_regular(True) + ([7, 6, 4, 4, 4, 1, 1, 1, None], [None, 1, 1, 1, 2, 4, 4, 6, 7]) + + .. NOTE:: + + This function needs the GAP's package AtlasRep [WPNBBAtl]_. + Install it via ``sage -i gap_packages``. + """ + + group = libgap.AtlasGroup("3.M22", libgap.NrMovedPoints, 990) + graph = Graph(group.Orbit([1, 22], libgap.OnSets), format='list_of_edges') + + graph.name("Ivanov-Ivanov-Faradjev Graph") + return graph + +def LargeWittGraph(): + r""" + Return the large Witt graph. + + The construction is taken from + http://mathworld.wolfram.com/LargeWittGraph.html + + EXAMPLES: + + sage: g = graphs.LargeWittGraph() + sage: g.is_distance_regular(True) + ([30, 28, 24, None], [None, 1, 3, 15]) + """ + from sage.coding import codes_catalog as codes + import itertools + + C = codes.GolayCode(GF(2), extended=True) + vertices = [c for c in C if c.hamming_weight() == 8] + + edges = [] + for v, w in itertools.combinations(vertices, 2): + if not set(v.support()).intersection(w.support()): + edges.append((v, w)) + + W = Graph(edges, format='list_of_edges') + W.name("Large Witt graph") + return W diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index edccdcb6cd7..119d5d8f535 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -119,6 +119,7 @@ def __append_to_doc(methods): "FlowerSnark", "FolkmanGraph", "FosterGraph", + "FosterGraph3S6", "FranklinGraph", "FruchtGraph", "GoldnerHararyGraph", @@ -139,12 +140,15 @@ def __append_to_doc(methods): "HoltGraph", "HortonGraph", "IoninKharaghani765Graph", + "IvanovIvanovFaradjevGraph", + "J2Graph", "JankoKharaghaniGraph", "JankoKharaghaniTonchevGraph", "KittellGraph", "KrackhardtKiteGraph", "Klein3RegularGraph", "Klein7RegularGraph", + "LargeWittGraph", "locally_GQ42_distance_transitive_graph", "LocalMcLaughlinGraph", "LjubljanaGraph", @@ -1942,6 +1946,7 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None FlowerSnark = staticmethod(smallgraphs.FlowerSnark) FolkmanGraph = staticmethod(smallgraphs.FolkmanGraph) FosterGraph = staticmethod(smallgraphs.FosterGraph) + FosterGraph3S6 = staticmethod(distance_regular.FosterGraph3S6) FranklinGraph = staticmethod(smallgraphs.FranklinGraph) FruchtGraph = staticmethod(smallgraphs.FruchtGraph) GoldnerHararyGraph = staticmethod(smallgraphs.GoldnerHararyGraph) @@ -1963,12 +1968,15 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None HoltGraph = staticmethod(smallgraphs.HoltGraph) HortonGraph = staticmethod(smallgraphs.HortonGraph) IoninKharaghani765Graph = staticmethod(smallgraphs.IoninKharaghani765Graph) + IvanovIvanovFaradjevGraph = staticmethod(distance_regular.IvanovIvanovFaradjevGraph) + J2Graph = staticmethod(distance_regular.J2Graph) JankoKharaghaniGraph = staticmethod(smallgraphs.JankoKharaghaniGraph) JankoKharaghaniTonchevGraph = staticmethod(smallgraphs.JankoKharaghaniTonchevGraph) KittellGraph = staticmethod(smallgraphs.KittellGraph) KrackhardtKiteGraph = staticmethod(smallgraphs.KrackhardtKiteGraph) Klein3RegularGraph = staticmethod(smallgraphs.Klein3RegularGraph) Klein7RegularGraph = staticmethod(smallgraphs.Klein7RegularGraph) + LargeWittGraph = staticmethod(distance_regular.LargeWittGraph) locally_GQ42_distance_transitive_graph = staticmethod(distance_regular.locally_GQ42_distance_transitive_graph) LocalMcLaughlinGraph = staticmethod(smallgraphs.LocalMcLaughlinGraph) LjubljanaGraph = staticmethod(smallgraphs.LjubljanaGraph) From 4c4f69bc43f273f7733ac19bdba45fb7c3c97be4 Mon Sep 17 00:00:00 2001 From: Ivo Maffei Date: Fri, 31 Jul 2020 11:59:06 +0200 Subject: [PATCH 4/8] added remaining Witt graphs --- .../graphs/generators/distance_regular.pyx | 52 ++++++++++++++++++- src/sage/graphs/graph_generators.py | 6 ++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/generators/distance_regular.pyx b/src/sage/graphs/generators/distance_regular.pyx index 71f641defe4..7cc53a9be04 100644 --- a/src/sage/graphs/generators/distance_regular.pyx +++ b/src/sage/graphs/generators/distance_regular.pyx @@ -399,7 +399,10 @@ def LargeWittGraph(): The construction is taken from http://mathworld.wolfram.com/LargeWittGraph.html - EXAMPLES: + This is a distance-regular graph with intersection array + `[30,28,24;1,3,15]`. + + EXAMPLES:: sage: g = graphs.LargeWittGraph() sage: g.is_distance_regular(True) @@ -419,3 +422,50 @@ def LargeWittGraph(): W = Graph(edges, format='list_of_edges') W.name("Large Witt graph") return W + +def TruncatedWittGraph(): + r""" + Return the truncated Witt graph. + + This builds the large Witt graph, then removes + all vertices whose codeword start with a 1. + + The graph is distance-regular with intersection array + `[15,14,12;1,1,9]`. + + EXAMPLES:: + + sage: G = graphs.TruncatedWittGraph() + sage: G.is_distance_regular(True) + ([15, 14, 12, None], [None, 1, 1, 9]) + + """ + # get large witt graph and remove all vertices which start with a 1 + G = LargeWittGraph() + G.delete_vertices(filter(lambda x : x[0] == 1, G.vertices())) + + G.name("Truncated Witt graph") + return G + +def DoublyTruncatedWittGraph(): + r""" + Return the doubly truncated Witt graph. + + This builds the truncated Witt graph, then removes + all vertices whose codeword start with a 1. + + The graph is distance-regular with intersection array + `[7,6,4,4;1,1,1,6]`. + + EXAMPLES:: + + sage: G = graphs.DoublyTruncatedWittGraph() + sage: G.is_distance_regular(True) + ([7, 6, 4, 4, None], [None, 1, 1, 1, 6]) + """ + + G = TruncatedWittGraph() + G.delete_vertices(filter(lambda x : x[1] == 1, G.vertices())) + + G.name("Doubly Truncated Witt graph") + return G diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index 119d5d8f535..44152f1e773 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -110,6 +110,7 @@ def __append_to_doc(methods): "DesarguesGraph", "DejterGraph", "DoubleStarSnark", + "DoublyTruncatedWittGraph", "DurerGraph", "DyckGraph", "EllinghamHorton54Graph", @@ -177,6 +178,7 @@ def __append_to_doc(methods): "TietzeGraph", "TruncatedIcosidodecahedralGraph", "TruncatedTetrahedralGraph", + "TruncatedWittGraph", "Tutte12Cage", "TutteCoxeterGraph", "TutteGraph", @@ -1937,6 +1939,7 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None DejterGraph = staticmethod(smallgraphs.DejterGraph) DesarguesGraph = staticmethod(smallgraphs.DesarguesGraph) DoubleStarSnark = staticmethod(smallgraphs.DoubleStarSnark) + DoublyTruncatedWittGraph = staticmethod(distance_regular.DoublyTruncatedWittGraph) DurerGraph = staticmethod(smallgraphs.DurerGraph) DyckGraph = staticmethod(smallgraphs.DyckGraph) EllinghamHorton54Graph = staticmethod(smallgraphs.EllinghamHorton54Graph) @@ -2005,7 +2008,8 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None TietzeGraph = staticmethod(smallgraphs.TietzeGraph) Tutte12Cage = staticmethod(smallgraphs.Tutte12Cage) TruncatedIcosidodecahedralGraph = staticmethod(smallgraphs.TruncatedIcosidodecahedralGraph) - TruncatedTetrahedralGraph= staticmethod(smallgraphs.TruncatedTetrahedralGraph) + TruncatedTetrahedralGraph = staticmethod(smallgraphs.TruncatedTetrahedralGraph) + TruncatedWittGraph = staticmethod(distance_regular.TruncatedWittGraph) TutteCoxeterGraph = staticmethod(smallgraphs.TutteCoxeterGraph) TutteGraph = staticmethod(smallgraphs.TutteGraph) U42Graph216 = staticmethod(smallgraphs.U42Graph216) From 9c813294ca1acd60a0c991b768507994781ca299 Mon Sep 17 00:00:00 2001 From: Ivo Maffei Date: Sat, 1 Aug 2020 10:15:15 +0200 Subject: [PATCH 5/8] renamed locally GQ function and added references --- .../graphs/generators/distance_regular.pyx | 111 ------------------ 1 file changed, 111 deletions(-) diff --git a/src/sage/graphs/generators/distance_regular.pyx b/src/sage/graphs/generators/distance_regular.pyx index 7cc53a9be04..819e5093095 100644 --- a/src/sage/graphs/generators/distance_regular.pyx +++ b/src/sage/graphs/generators/distance_regular.pyx @@ -1,9 +1,5 @@ r""" -<<<<<<< HEAD Database of distance regular graphs -======= -Dabase of distance regular graphs ->>>>>>> moved file to generators; fixed tests In this module we construct several distance regular graphs and group them in a function that maps intersection arrays @@ -43,11 +39,7 @@ def cocliques_HoffmannSingleton(): r""" Return the graph obtained from the cocliques of the Hoffmann-Singleton graph. -<<<<<<< HEAD This is a distance-regular graph with intersection array -======= - This is a distance-regular graph with intersecion array ->>>>>>> moved file to generators; fixed tests `[15, 14, 10, 3; 1, 5, 12, 15]`. EXAMPLES:: @@ -61,7 +53,6 @@ def cocliques_HoffmannSingleton(): The construction of this graph can be found in [BCN1989]_ p. 392. """ from sage.graphs.graph_generators import GraphGenerators -<<<<<<< HEAD import itertools D = GraphGenerators.HoffmanSingletonGraph() @@ -81,29 +72,6 @@ def locally_GQ42_distance_transitive_graph(): r""" Return the unique amply regular graph with `\mu = 6` which is locally a generalised quadrangle. -======= - D = GraphGenerators.HoffmanSingletonGraph() - DC = D.complement() - - cocliques = DC.cliques_maximum() # 100 of this - - edges = [] - for i in range(100): - sC = frozenset(cocliques[i]) - for j in range(i+1,100): - if len(sC.intersection(cocliques[j])) == 8: - sC2 = frozenset(cocliques[j]) - edges.append( (sC,sC2) ) - - G = Graph(edges,format="list_of_edges") - return G - - -def locally_GQ42_graph(): - r""" - Return the unique amply regular graph which is locally a generalised - quadrangle. ->>>>>>> moved file to generators; fixed tests This graph is distance-regular with intersection array `[45, 32, 12, 1; 1, 6, 32, 45]`. @@ -112,7 +80,6 @@ def locally_GQ42_graph(): EXAMPLES:: -<<<<<<< HEAD sage: G = graphs.locally_GQ42_distance_transitive_graph() # optional - internet sage: G.is_distance_regular(True) # optional - internet ([45, 32, 12, 1, None], [None, 1, 6, 32, 45]) @@ -122,31 +89,14 @@ def locally_GQ42_graph(): A description of this graph can be found in [BCN1989]_ p.399. This construction is due to Dima Pasechnik. """ - H = libgap.AtlasGroup("3^2.U4(3).D8", libgap.NrMovedPoints, 756) -======= - sage: G = graphs.locally_GQ42_graph() # optional - gap_packages - sage: G.is_distance_regular(True) # optional - gap_packages - ([45, 32, 12, 1, None], [None, 1, 6, 32, 45]) - - .. NOTE:: - - This function needs the GAP's package AtlasRep [WPNBBAtl]_. - Install it via ``sage -i gap_packages``. - """ H = libgap.AtlasGroup("3^2.U4(3).D8",libgap.NrMovedPoints,756) ->>>>>>> moved file to generators; fixed tests Ns = H.NormalSubgroups() for N in Ns: if len(N.GeneratorsSmallest()) == 7: # there is only one break -<<<<<<< HEAD G = Graph(libgap.Orbit(N, [1, 9], libgap.OnSets), format='list_of_edges') G.name("locally GQ(4,2) distance transitive graph") -======= - G = Graph(libgap.Orbit(N,[1,9],libgap.OnSets), format='list_of_edges') - G.name("locally GQ(4,2) graph") ->>>>>>> moved file to generators; fixed tests return G @@ -162,7 +112,6 @@ def ConwaySmith_for_3S7(): sage: G = graphs.ConwaySmith_for_3S7() sage: G.is_distance_regular(True) ([10, 6, 4, 1, None], [None, 1, 2, 6, 10]) -<<<<<<< HEAD REFERENCES: @@ -171,20 +120,12 @@ def ConwaySmith_for_3S7(): """ from sage.rings.number_field.number_field import CyclotomicField import itertools -======= - """ - from sage.rings.number_field.number_field import CyclotomicField ->>>>>>> moved file to generators; fixed tests F = CyclotomicField(3) w = F.gen() V= VectorSpace(GF(4), 6) -<<<<<<< HEAD z2 = GF(4)('z2') # GF(4) = {0, 1, z2, z2+1} -======= - z2 = GF(4)('z2') # GF(4) = {0,1,z2, z2+1} ->>>>>>> moved file to generators; fixed tests W = V.span([(0,0,1,1,1,1), (0,1,0,1,z2,z2+1), (1,0,0,1,z2+1,z2)]) # we only need the 45 vectors with 2 zero entries @@ -192,17 +133,10 @@ def ConwaySmith_for_3S7(): K = [] for v in W: -<<<<<<< HEAD # check zero entries zeros = 0 for x in v: if x.is_zero(): -======= - #check zero entries - zeros = 0 - for x in v: - if x == 0: ->>>>>>> moved file to generators; fixed tests zeros += 1 if zeros == 2: @@ -213,17 +147,10 @@ def ConwaySmith_for_3S7(): for x in v: if x == z2: vv.append(w) -<<<<<<< HEAD elif x == z2 + 1: vv.append(w**2) else: vv.append(int(x)) -======= - elif x == z2+1: - vv.append(w**2) - else: - vv.append(int(x)) # this is weirdly needed for some reason ->>>>>>> moved file to generators; fixed tests # now vv is the new vector in F vv = vector(F, vv) @@ -231,13 +158,8 @@ def ConwaySmith_for_3S7(): # we need to add other vectors for i in range(6): -<<<<<<< HEAD # create e_i ei = [0, 0, 0, 0, 0, 0] -======= - #create e_i - ei = [0]*6 ->>>>>>> moved file to generators; fixed tests ei[i] = 1 ei = vector(F, ei) @@ -246,7 +168,6 @@ def ConwaySmith_for_3S7(): K.append(2 * w**2 * ei) # now K is all the 63 vertices -<<<<<<< HEAD for v in K: v.set_immutable() @@ -257,25 +178,6 @@ def ConwaySmith_for_3S7(): for Ki, Kj in itertools.combinations(K, 2): if has_edge(Ki, Kj): G.add_edge((Ki, Kj)) -======= - def has_edge(u,v): - com = 0 - for i in range(6): - com += u[i].conjugate() * v[i] - - if com == 2: - return True - return False - - G = Graph() - length = len(K) - for i in range(length): - K[i].set_immutable() - for j in range(i+1, length): - if has_edge(K[i], K[j]): - K[j].set_immutable() - G.add_edge((K[i], K[j])) ->>>>>>> moved file to generators; fixed tests G.name("Conway-Smith graph for 3S7") return G @@ -292,7 +194,6 @@ def graph_3O73(): EXAMPLES:: -<<<<<<< HEAD sage: G = graphs.graph_3O73() # optional - internet sage: G.is_distance_regular(True) # optional - internet ([117, 80, 24, 1, None], [None, 1, 12, 80, 117]) @@ -303,18 +204,6 @@ def graph_3O73(): [BCN1989]_ p. 400. """ group = libgap.AtlasGroup("3.O7(3)", libgap.NrMovedPoints, 1134) -======= - sage: G = graphs.graph_3O73() # optional - gap_packages - sage: G.is_distance_regular(True) # optional - gap_packages - ([117, 80, 24, 1, None], [None, 1, 12, 80, 117]) - - .. NOTE:: - - This function needs the GAP's package AtlasRep [WPNBBAtl]_. - Install it via ``sage -i gap_packages``. - """ - group = libgap.AtlasGroup("3.O7(3)",libgap.NrMovedPoints,1134) ->>>>>>> moved file to generators; fixed tests G = Graph(libgap.Orbit(group, [1, 3], libgap.OnSets), format='list_of_edges') G.name("Distance transitive graph with automorphism group 3.O_7(3)") return G From b88df6bb072a9945370b6b94941ab037168af2c4 Mon Sep 17 00:00:00 2001 From: Ivo Maffei Date: Sun, 2 Aug 2020 11:37:53 +0200 Subject: [PATCH 6/8] added reference blocks --- .../graphs/generators/distance_regular.pyx | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/sage/graphs/generators/distance_regular.pyx b/src/sage/graphs/generators/distance_regular.pyx index 819e5093095..0bca59b2b05 100644 --- a/src/sage/graphs/generators/distance_regular.pyx +++ b/src/sage/graphs/generators/distance_regular.pyx @@ -222,6 +222,11 @@ def FosterGraph3S6(): sage: G = graphs.FosterGraph3S6() sage: G.is_distance_regular(True) ([6, 4, 2, 1, None], [None, 1, 1, 4, 6]) + + REFERENCES: + + A description and construction of this graph can be found in + [BCN1989]_ p. 397. """ a = libgap.eval(("(2,6)(3,5)(4,11)(7,17)(8,16)(9,14)(13,22)(15,25)" @@ -243,14 +248,14 @@ def J2Graph(): EXAMPLES:: - sage: G = graphs.J2Graph() # optional - gap_packages - sage: G.is_distance_regular(True) # optional - gap_packages + sage: G = graphs.J2Graph() # optional - internet + sage: G.is_distance_regular(True) # optional - internet ([10, 8, 8, 2, None], [None, 1, 1, 4, 5]) - .. NOTE:: + REFERENCES: - This function needs the GAP's package AtlasRep [WPNBBAtl]_. - Install it via ``sage -i gap_packages``. + A description and construction of this graph can be found in + [BCN1989]_ p. 408. """ group = libgap.AtlasGroup("J2", libgap.NrMovedPoints, 315) G = Graph(group.Orbit([1, 9], libgap.OnSets), format='list_of_edges') @@ -265,14 +270,14 @@ def IvanovIvanovFaradjevGraph(): EXAMPLES:: - sage: G = graphs.IvanovIvanovFaradjevGraph() - sage: G.is_distance_regular(True) + sage: G = graphs.IvanovIvanovFaradjevGraph() # optional - internet + sage: G.is_distance_regular(True) # optional - internet ([7, 6, 4, 4, 4, 1, 1, 1, None], [None, 1, 1, 1, 2, 4, 4, 6, 7]) - .. NOTE:: + REFERENCES: - This function needs the GAP's package AtlasRep [WPNBBAtl]_. - Install it via ``sage -i gap_packages``. + A description and construction of this graph can be found in + [BCN1989]_ p. 369. """ group = libgap.AtlasGroup("3.M22", libgap.NrMovedPoints, 990) @@ -285,9 +290,6 @@ def LargeWittGraph(): r""" Return the large Witt graph. - The construction is taken from - http://mathworld.wolfram.com/LargeWittGraph.html - This is a distance-regular graph with intersection array `[30,28,24;1,3,15]`. @@ -296,6 +298,13 @@ def LargeWittGraph(): sage: g = graphs.LargeWittGraph() sage: g.is_distance_regular(True) ([30, 28, 24, None], [None, 1, 3, 15]) + + REFERENCES: + + A description of this graph can be found in + [BCN1989]_ p. 366. + This construction is taken from + http://mathworld.wolfram.com/LargeWittGraph.html """ from sage.coding import codes_catalog as codes import itertools @@ -328,6 +337,10 @@ def TruncatedWittGraph(): sage: G.is_distance_regular(True) ([15, 14, 12, None], [None, 1, 1, 9]) + REFERENCES: + + A description and construction of this graph can be found in + [BCN1989]_ p. 367. """ # get large witt graph and remove all vertices which start with a 1 G = LargeWittGraph() @@ -351,6 +364,11 @@ def DoublyTruncatedWittGraph(): sage: G = graphs.DoublyTruncatedWittGraph() sage: G.is_distance_regular(True) ([7, 6, 4, 4, None], [None, 1, 1, 1, 6]) + + REFERENCES: + + A description and construction of this graph can be found in + [BCN1989]_ p. 368. """ G = TruncatedWittGraph() From ecde7ca82b40acb53a6a5a380e64340f791cf4f7 Mon Sep 17 00:00:00 2001 From: Ivo Maffei Date: Tue, 4 Aug 2020 10:58:16 +0200 Subject: [PATCH 7/8] fix wrong rebase merge conflict resolution --- src/sage/graphs/generators/distance_regular.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/generators/distance_regular.pyx b/src/sage/graphs/generators/distance_regular.pyx index 0bca59b2b05..24dc98173e9 100644 --- a/src/sage/graphs/generators/distance_regular.pyx +++ b/src/sage/graphs/generators/distance_regular.pyx @@ -89,7 +89,7 @@ def locally_GQ42_distance_transitive_graph(): A description of this graph can be found in [BCN1989]_ p.399. This construction is due to Dima Pasechnik. """ - H = libgap.AtlasGroup("3^2.U4(3).D8",libgap.NrMovedPoints,756) + H = libgap.AtlasGroup("3^2.U4(3).D8", libgap.NrMovedPoints, 756) Ns = H.NormalSubgroups() for N in Ns: if len(N.GeneratorsSmallest()) == 7: # there is only one From a87fad1a74954c825c13ba6065dc275d1417cb42 Mon Sep 17 00:00:00 2001 From: Ivo Maffei Date: Wed, 5 Aug 2020 10:47:16 +0200 Subject: [PATCH 8/8] added gap_packages flag to atlasrep --- src/sage/graphs/generators/distance_regular.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/generators/distance_regular.pyx b/src/sage/graphs/generators/distance_regular.pyx index 3d3a5cf5c03..e98082bf635 100644 --- a/src/sage/graphs/generators/distance_regular.pyx +++ b/src/sage/graphs/generators/distance_regular.pyx @@ -248,8 +248,8 @@ def J2Graph(): EXAMPLES:: - sage: G = graphs.J2Graph() # optional - internet - sage: G.is_distance_regular(True) # optional - internet + sage: G = graphs.J2Graph() # optional - internet gap_packages + sage: G.is_distance_regular(True) # optional - internet gap_packages ([10, 8, 8, 2, None], [None, 1, 1, 4, 5]) REFERENCES: @@ -270,8 +270,8 @@ def IvanovIvanovFaradjevGraph(): EXAMPLES:: - sage: G = graphs.IvanovIvanovFaradjevGraph() # optional - internet - sage: G.is_distance_regular(True) # optional - internet + sage: G = graphs.IvanovIvanovFaradjevGraph() # optional - internet gap_packages + sage: G.is_distance_regular(True) # optional - internet gap_packages ([7, 6, 4, 4, 4, 1, 1, 1, None], [None, 1, 1, 1, 2, 4, 4, 6, 7]) REFERENCES: