Skip to content

Commit

Permalink
Trac #14631: Affine Polar Graphs
Browse files Browse the repository at this point in the history
Thank youuuuuuUUUUUUUUUuuuuuu Brouwer !!! `:-P`

Nathann

P.S. : This patch "does not really" depend on #14589, but here is what
happens when calling "is_strongly_regular" on a big graph. With the
patch :
{{{
sage: g
Affine Polar Graph VO^+(10,2): Graph on 1024 vertices
sage: %time g.is_strongly_regular(parameters = True)
CPU times: user 3.30 s, sys: 0.00 s, total: 3.30 s
Wall time: 3.31 s
(1024, 527, 270, 272)
}}}

Without the patch
{{{
sage: %time g.is_strongly_regular(parameters = True)
CPU times: user 316.33 s, sys: 0.08 s, total: 316.41 s
Wall time: 317.20 s
(1024, 527, 270, 272)
}}}

Annnnnd the doctests that this patch adds are a bit faster as a result
`:-P`

URL: http://trac.sagemath.org/14631
Reported by: ncohen
Ticket author(s): Nathann Cohen, Dima Pasechnik
Reviewer(s): Nathann Cohen, Dima Pasechnik
  • Loading branch information
Release Manager authored and vbraun committed May 19, 2014
2 parents 39d8e59 + 3ef564e commit 40f6530
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 1 deletion.
175 changes: 175 additions & 0 deletions src/sage/graphs/generators/families.py
Original file line number Diff line number Diff line change
Expand Up @@ -2173,3 +2173,178 @@ def SymplecticGraph(d,q):
G.relabel()
return G

def AffineOrthogonalPolarGraph(d,q,sign="+"):
r"""
Returns the affine polar graph `VO^+(d,q),VO^-(d,q)` or `VO(d,q)`.
Affine Polar graphs are built from a `d`-dimensional vector space over
`F_q`, and a quadratic form which is hyperbolic, elliptic or parabolic
according to the value of ``sign``.
Note that `VO^+(d,q),VO^-(d,q)` are strongly regular graphs, while `VO(d,q)`
is not.
For more information on Affine Polar graphs, see `Affine Polar
Graphs page of Andries Brouwer's website
<http://www.win.tue.nl/~aeb/graphs/VO.html>`_.
INPUT:
- ``d`` (integer) -- ``d`` must be even if ``sign != None``, and odd
otherwise.
- ``q`` (integer) -- a power of a prime number, as `F_q` must exist.
- ``sign`` -- must be qual to ``"+"``, ``"-"``, or ``None`` to compute
(respectively) `VO^+(d,q),VO^-(d,q)` or `VO(d,q)`. By default
``sign="+"``.
.. NOTE::
The graph `VO^\epsilon(d,q)` is the graph induced by the
non-neighbors of a vertex in an :meth:`Orthogonal Polar Graph
<OrthogonalPolarGraph>` `O^\epsilon(d+2,q)`.
EXAMPLES:
The :meth:`Brouwer-Haemers graph <BrouwerHaemersGraph>` is isomorphic to
`VO^-(4,3)`::
sage: g = graphs.AffineOrthogonalPolarGraph(4,3,"-")
sage: g.is_isomorphic(graphs.BrouwerHaemersGraph())
True
Some examples from `Brouwer's table or strongly regular graphs
<http://www.win.tue.nl/~aeb/graphs/srg/srgtab.html>`_::
sage: g = graphs.AffineOrthogonalPolarGraph(6,2,"-"); g
Affine Polar Graph VO^-(6,2): Graph on 64 vertices
sage: g.is_strongly_regular(parameters=True)
(64, 27, 10, 12)
sage: g = graphs.AffineOrthogonalPolarGraph(6,2,"+"); g
Affine Polar Graph VO^+(6,2): Graph on 64 vertices
sage: g.is_strongly_regular(parameters=True)
(64, 35, 18, 20)
When ``sign is None``::
sage: g = graphs.AffineOrthogonalPolarGraph(5,2,None); g
Affine Polar Graph VO^-(5,2): Graph on 32 vertices
sage: g.is_strongly_regular(parameters=True)
False
sage: g.is_regular()
True
sage: g.is_vertex_transitive()
True
"""
if sign in ["+","-"]:
s = 1 if sign == "+" else -1
if d%2 == 1:
raise ValueError("d must be even when sign!=None")
else:
if d%2 == 0:
raise ValueError("d must be odd when sign==None")
s = 0

from sage.interfaces.gap import gap
from sage.rings.finite_rings.constructor import FiniteField
from sage.modules.free_module import VectorSpace
from sage.matrix.constructor import Matrix
from sage.libs.gap.libgap import libgap
from itertools import combinations

M = Matrix(libgap.InvariantQuadraticForm(libgap.GeneralOrthogonalGroup(s,d,q))['matrix'])
F = libgap.GF(q).sage()
V = list(VectorSpace(F,d))

G = Graph()
G.add_vertices(map(tuple,V))
for x,y in combinations(V,2):
if not (x-y)*M*(x-y):
G.add_edge(tuple(x),tuple(y))

G.name("Affine Polar Graph VO^"+str('+' if s == 1 else '-')+"("+str(d)+","+str(q)+")")
G.relabel()
return G

def OrthogonalPolarGraph(m, q, sign="+"):
r"""
Returns the Orthogonal Polar Graph `O^{\epsilon}(m,q)`.
For more information on Orthogonal Polar graphs, see see the `page of
Andries Brouwer's website <http://www.win.tue.nl/~aeb/graphs/srghub.html>`_.
INPUT:
- ``m,q`` (integers) -- `q` must be a prime power.
- ``sign`` -- ``"+"`` or ``"-"`` if `m` is even, ``"+"`` (default)
otherwise.
EXAMPLES::
sage: G = graphs.OrthogonalPolarGraph(6,3,"+"); G
Orthogonal Polar Graph O^+(6, 3): Graph on 130 vertices
sage: G.is_strongly_regular(parameters=True)
(130, 48, 20, 16)
sage: G = graphs.OrthogonalPolarGraph(6,3,"-"); G
Orthogonal Polar Graph O^-(6, 3): Graph on 112 vertices
sage: G.is_strongly_regular(parameters=True)
(112, 30, 2, 10)
sage: G = graphs.OrthogonalPolarGraph(5,3); G
Orthogonal Polar Graph O(5, 3): Graph on 40 vertices
sage: G.is_strongly_regular(parameters=True)
(40, 12, 2, 4)
TESTS::
sage: G = graphs.OrthogonalPolarGraph(4,3,"")
Traceback (most recent call last):
...
ValueError: sign must be equal to either '-' or '+' when m is even
sage: G = graphs.OrthogonalPolarGraph(5,3,"-")
Traceback (most recent call last):
...
ValueError: sign must be equal to either '' or '+' when m is odd
"""
from sage.schemes.projective.projective_space import ProjectiveSpace
from sage.rings.finite_rings.constructor import FiniteField
from sage.modules.free_module_element import free_module_element as vector
from sage.matrix.constructor import Matrix
from sage.interfaces.gap import gap
from itertools import combinations

if m % 2 == 0:
if sign != "+" and sign != "-":
raise ValueError("sign must be equal to either '-' or '+' when "
"m is even")
else:
if sign != "" and sign != "+":
raise ValueError("sign must be equal to either '' or '+' when "
"m is odd")
sign = ""

Fq = FiniteField(q, prefix='x', conway=True)
e = {'+': 1,
'-': -1,
'' : 0}[sign]

M = gap("InvariantQuadraticForm(GO" + str((e, m, q)) + ").matrix")
M = [[Fq(x) for x in R] for R in M]
M = Matrix(M)
PG = ProjectiveSpace(m - 1, Fq)
m_over_two = m // 2

def F(x):
return x*M*x

def FF(x,y):
return F(vector([xx-yy for xx,yy in zip(x,y)]))

V = [x for x in PG if F(vector(x)) == 0]

G = Graph([V,lambda x,y:FF(x,y)==0],loops=False)

G.relabel()
G.name("Orthogonal Polar Graph O" + ("^" + sign if sign else "") + str((m, q)))
return G
6 changes: 5 additions & 1 deletion src/sage/graphs/graph_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ def __append_to_doc(methods):
"""

__append_to_doc(
["BalancedTree",
["AffineOrthogonalPolarGraph",
"BalancedTree",
"BarbellGraph",
"BubbleSortGraph",
"CirculantGraph",
Expand All @@ -201,6 +202,7 @@ def __append_to_doc(methods):
"NKStarGraph",
"NStarGraph",
"OddGraph",
"OrthogonalPolarGraph",
"PaleyGraph",
"petersen_family",
"RingedTree",
Expand Down Expand Up @@ -1345,6 +1347,7 @@ def fusenes(self, hexagon_count, benzenoids=False):
# Families
###########################################################################
import sage.graphs.generators.families
AffineOrthogonalPolarGraph = staticmethod(sage.graphs.generators.families.AffineOrthogonalPolarGraph)
BalancedTree = staticmethod(sage.graphs.generators.families.BalancedTree)
BarbellGraph = staticmethod(sage.graphs.generators.families.BarbellGraph)
BubbleSortGraph = staticmethod(sage.graphs.generators.families.BubbleSortGraph)
Expand All @@ -1368,6 +1371,7 @@ def fusenes(self, hexagon_count, benzenoids=False):
NKStarGraph = staticmethod(sage.graphs.generators.families.NKStarGraph)
NStarGraph = staticmethod(sage.graphs.generators.families.NStarGraph)
OddGraph = staticmethod(sage.graphs.generators.families.OddGraph)
OrthogonalPolarGraph = staticmethod(sage.graphs.generators.families.OrthogonalPolarGraph)
PaleyGraph = staticmethod(sage.graphs.generators.families.PaleyGraph)
petersen_family = staticmethod(sage.graphs.generators.families.petersen_family)
RingedTree = staticmethod(sage.graphs.generators.families.RingedTree)
Expand Down

0 comments on commit 40f6530

Please sign in to comment.