Example #1
0
    def __init__(self, homset, imgs, check=True):
        r"""
        Constructor method.

        TESTS:

        The following input does not define a valid group homomorphism::

            sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
            sage: A = AbelianGroupGap([2])
            sage: G = MatrixGroup([Matrix(ZZ, 2, [0,1,-1,0])])
            sage: A.hom([G.gen(0)])
            Traceback (most recent call last):
            ...
            ValueError: images do not define a group homomorphism
        """
        from sage.libs.gap.libgap import libgap
        Morphism.__init__(self, homset)
        dom = homset.domain()
        codom = homset.codomain()
        gens = [x.gap() for x in dom.gens()]
        imgs = [codom(x).gap() for x in imgs]
        if check:
            if not len(gens) == len(imgs):
                raise ValueError("provide an image for each generator")
            self._phi = libgap.GroupHomomorphismByImages(
                dom.gap(), codom.gap(), gens, imgs)
            # if it is not a group homomorphism, then
            # self._phi is the gap boolean fail
            if self._phi.is_bool():  # check we did not fail
                raise ValueError("images do not define a group homomorphism")
        else:
            ByImagesNC = libgap.function_factory("GroupHomomorphismByImagesNC")
            self._phi = ByImagesNC(dom.gap(), codom.gap(), gens, imgs)
def orbits_lines_mod_p(self, p):
    r"""
    Let `(L, q)` be a lattice. This returns representatives of the
    orbits of lines in `L/pL` under the orthogonal group of `q`.

    INPUT:

    - ``p`` -- a prime number

    OUTPUT:

    - a list of vectors over ``GF(p)``

    EXAMPLES::

        sage: from sage.quadratic_forms.quadratic_form__neighbors import orbits_lines_mod_p
        sage: Q = QuadraticForm(ZZ, 3, [1, 0, 0, 2, 1, 3])
        sage: Q.orbits_lines_mod_p(2)
        [(0, 0, 1),
        (0, 1, 0),
        (0, 1, 1),
        (1, 0, 0),
        (1, 0, 1),
        (1, 1, 0),
        (1, 1, 1)]
    """
    from sage.libs.gap.libgap import libgap
    # careful the self.automorphism_group() acts from the left
    # but in gap we act from the right!! --> transpose
    gens = self.automorphism_group().gens()
    gens = [g.matrix().transpose().change_ring(GF(p)) for g in gens]
    orbs = libgap.function_factory(
    """function(gens, p)
        local one, G, reps, V, n, orb;
        one:= One(GF(p));
        G:=Group(List(gens, g -> g*one));
        n:= Size(gens[1]);
        V:= GF(p)^n;
        orb:= OrbitsDomain(G, V, OnLines);
        reps:= List(orb, g->g[1]);
        return reps;
        end;""")
    # run this at startup if you need more memory...
    #from sage.interfaces.gap import get_gap_memory_pool_size, set_gap_memory_pool_size
    #memory_gap = get_gap_memory_pool_size()
    #set_gap_memory_pool_size(1028*memory_gap)
    orbs_reps = orbs(gens, p)
    #set_gap_memory_pool_size(memory_gap)
    M = GF(p)**self.dim()
    return [M(m.sage()) for m in orbs_reps if not m.IsZero()]
Example #3
0
    def cardinality(self):
        """
        Return the size of combinations(mset, k).

        IMPLEMENTATION: Wraps GAP's NrCombinations.

        EXAMPLES::

            sage: mset = [1,1,2,3,4,4,5]
            sage: Combinations(mset,2).cardinality()
            12
        """
        from sage.libs.gap.libgap import libgap
        items = [self.mset.index(_) for _ in self.mset]
        nc = libgap.function_factory('NrCombinations')
        return ZZ(nc(items, ZZ(self.k)))
Example #4
0
    def module_composition_factors(self, algorithm=None):
        r"""
        Return a list of triples consisting of [base field, dimension,
        irreducibility], for each of the Meataxe composition factors
        modules. The ``algorithm="verbose"`` option returns more information,
        but in Meataxe notation.

        EXAMPLES::

            sage: F = GF(3); MS = MatrixSpace(F,4,4)
            sage: M = MS(0)
            sage: M[0,1]=1;M[1,2]=1;M[2,3]=1;M[3,0]=1
            sage: G = MatrixGroup([M])
            sage: G.module_composition_factors()
            [(Finite Field of size 3, 1, True),
             (Finite Field of size 3, 1, True),
             (Finite Field of size 3, 2, True)]
            sage: F = GF(7); MS = MatrixSpace(F,2,2)
            sage: gens = [MS([[0,1],[-1,0]]),MS([[1,1],[2,3]])]
            sage: G = MatrixGroup(gens)
            sage: G.module_composition_factors()
            [(Finite Field of size 7, 2, True)]

        Type ``G.module_composition_factors(algorithm='verbose')`` to get a
        more verbose version.

        For more on MeatAxe notation, see
        https://www.gap-system.org/Manuals/doc/ref/chap69.html
        """
        from sage.libs.gap.libgap import libgap
        F = self.base_ring()
        if not F.is_finite():
            raise NotImplementedError("Base ring must be finite.")
        n = self.degree()
        MS = MatrixSpace(F, n, n)
        mats = [MS(g.matrix()) for g in self.gens()]
        # initializing list of mats by which the gens act on self
        mats_gap = libgap(mats)
        M = mats_gap.GModuleByMats(F)
        compo = libgap.function_factory('MTX.CompositionFactors')
        MCFs = compo(M)
        if algorithm == "verbose":
            print(str(MCFs) + "\n")
        return sorted((MCF['field'].sage(),
                       MCF['dimension'].sage(),
                       MCF['IsIrreducible'].sage()) for MCF in MCFs)
Example #5
0
    def _element_constructor_(self, x, check=True, **options):
        r"""
        Handle conversions and coercions.

        EXAMPLES::

            sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
            sage: A = AbelianGroupGap([2,4])
            sage: H = A.Hom(A)
            sage: H([g^2 for g in A.gens()])
            Group endomorphism of Abelian group with gap, generator orders (2, 4)
            sage: H(2)
            Traceback (most recent call last):
            ...
            TypeError: unable to convert 2 to an element of ...

        A group homomorphism between a finitely presented group and a subgroup of a permutation group::

            sage: PG = PGU(6,2)
            sage: g, h = PG.gens()
            sage: p1 = h^-3*(h^-1*g^-1)^2*h*g*h^2*g^-1*h^2*g*h^-5*g^-1
            sage: p2 = g*(g*h)^2*g*h^-4*(g*h)^2*(h^2*g*h^-2*g)^2*h^-2*g*h^-2*g^-1*h^-1*g*h*g*h^-1*g
            sage: p3 = h^-3*g^-1*h*g*h^4*g^-1*h^-1*g*h*(h^2*g^-1)^2*h^-4*g*h^2*g^-1*h^-7*g^-2*h^-2*g*h^-2*g^-1*h^-1*(g*h)^2*h^3
            sage: p4 = h*(h^3*g)^2*h*g*h^-1*g*h^2*g^-1*h^-2*g*h^4*g^-1*h^3*g*h^-2*g*h^-1*g^-1*h^2*g*h*g^-1*h^-2*g*h*g^-1*h^2*g*h^2*g^-1
            sage: p5 = h^2*g*h^2*g^-1*h*g*h^-1*g*h*g^-1*h^2*g*h^-2*g*h^2*g*h^-2*(h^-1*g)^2*h^4*(g*h^-1)^2*g^-1
            sage: UPG = PG.subgroup([p1, p2, p3, p4, p5], canonicalize=False)
            sage: B6 = BraidGroup(6)
            sage: reprB6 = B6.hom(UPG.gens())
            sage: b1, b2, b3, b4, b5 = B6.gens()
            sage: reprB6(b1*b2*b3*b4*b5) == p1*p2*p3*p4*p5
            True

        TESTS:

        The following input does not define a valid group homomorphism::

            sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
            sage: A = AbelianGroupGap([2])
            sage: G = MatrixGroup([Matrix(ZZ, 2, [0,1,-1,0])])
            sage: A.hom([G.gen(0)])
            Traceback (most recent call last):
            ...
            ValueError: images do not define a group homomorphism
        """
        if isinstance(x, (tuple, list)):
            # there should be a better way
            from sage.libs.gap.libgap import libgap
            dom = self.domain()
            codom = self.codomain()
            gens = dom.gap().GeneratorsOfGroup()
            imgs = [codom(g).gap() for g in x]
            if check:
                if not len(gens) == len(imgs):
                    raise ValueError("provide an image for each generator")
                phi = libgap.GroupHomomorphismByImages(dom.gap(), codom.gap(), gens, imgs)
                # if it is not a group homomorphism, then
                # self._phi is the gap boolean fail
                if phi.is_bool():     # check we did not fail
                    raise ValueError("images do not define a group homomorphism")
            else:
                ByImagesNC = libgap.function_factory("GroupHomomorphismByImagesNC")
                phi = ByImagesNC(dom.gap(), codom.gap(), gens, imgs)
            return self.element_class(self, phi, check=check, **options)
        if isinstance(x, GapElement):
            try:
                return self.element_class(self, x, check=True, **options)
            except ValueError:
                pass
        return super(GroupHomset_libgap, self)._element_constructor_(x, check=check, **options)
Example #6
0
def CossidentePenttilaGraph(q):
    r"""
    Cossidente-Penttila `((q^3+1)(q+1)/2,(q^2+1)(q-1)/2,(q-3)/2,(q-1)^2/2)`-strongly regular graph

    For each odd prime power `q`, one can partition the points of the `O_6^-(q)`-generalized
    quadrange `GQ(q,q^2)` into two parts, so that on any of them the induced subgraph of
    the point graph of the GQ has parameters as above [CP05]_.

    Directly follwing the construction in [CP05]_ is not efficient,
    as one then needs to construct the dual `GQ(q^2,q)`. Thus we
    describe here a more efficient approach that we came up with, following a suggestion by
    T.Penttila. Namely, this partition is invariant
    under the subgroup `H=\Omega_3(q^2)<O_6^-(q)`. We build the appropriate `H`, which
    leaves the form `B(X,Y,Z)=XY+Z^2` invariant, and
    pick up two orbits of `H` on the `F_q`-points. One them is `B`-isotropic, and we
    take the representative `(1:0:0)`. The other one corresponds to the points of
    `PG(2,q^2)` that have all the lines on them either missing the conic specified by `B`, or
    intersecting the conic in two points. We take `(1:1:e)` as the representative. It suffices
    to pick `e` so that `e^2+1` is not a square in `F_{q^2}`. Indeed,
    The conic can be viewed as the union of `\{(0:1:0)\}` and `\{(1:-t^2:t) | t \in F_{q^2}\}`.
    The coefficients of a generic line on `(1:1:e)` are `[1:-1-eb:b]`, for `-1\neq eb`.
    Thus, to make sure the intersection with the conic is always even, we need that the
    discriminant of `1+(1+eb)t^2+tb=0` never vanishes, and this is if and only if
    `e^2+1` is not a square. Further, we need to adjust `B`, by multiplying it by appropriately
    chosen `\nu`, so that `(1:1:e)` becomes isotropic under the relative trace norm
    `\nu B(X,Y,Z)+(\nu B(X,Y,Z))^q`. The latter is used then to define the graph.

    INPUT:

    - ``q`` -- an odd prime power.

    EXAMPLES:

    For `q=3` one gets Sims-Gewirtz graph. ::

        sage: G=graphs.CossidentePenttilaGraph(3)    # optional - gap_packages (grape)
        sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape)
        (56, 10, 0, 2)

    For `q>3` one gets new graphs. ::

        sage: G=graphs.CossidentePenttilaGraph(5)    # optional - gap_packages (grape)
        sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape)
        (378, 52, 1, 8)

    TESTS::

        sage: G=graphs.CossidentePenttilaGraph(7)    # optional - gap_packages (grape) # long time
        sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) # long time
        (1376, 150, 2, 18)
        sage: graphs.CossidentePenttilaGraph(2)
        Traceback (most recent call last):
        ...
        ValueError: q(=2) must be an odd prime power

    REFERENCES:

    .. [CP05] \A.Cossidente and T.Penttila
       Hemisystems on the Hermitian surface
       Journal of London Math. Soc. 72(2005), 731-741
    """
    p, k = is_prime_power(q,get_data=True)
    if k==0 or p==2:
        raise ValueError('q(={}) must be an odd prime power'.format(q))

    from sage.libs.gap.libgap import libgap
    from sage.misc.package import is_package_installed, PackageNotFoundError

    if not is_package_installed('gap_packages'):
        raise PackageNotFoundError('gap_packages')

    adj_list=libgap.function_factory("""function(q)
        local z, e, so, G, nu, G1, G0, B, T, s, O1, O2, x;
        LoadPackage("grape");
        G0:=SO(3,q^2);
        so:=GeneratorsOfGroup(G0);
        G1:=Group(Comm(so[1],so[2]),Comm(so[1],so[3]),Comm(so[2],so[3]));
        B:=InvariantBilinearForm(G0).matrix;
        z:=Z(q^2); e:=z; sqo:=(q^2-1)/2;
        if IsInt(sqo/Order(e^2+z^0)) then
            e:=z^First([2..q^2-2], x-> not IsInt(sqo/Order(z^(2*x)+z^0)));
        fi;
        nu:=z^First([0..q^2-2], x->z^x*(e^2+z^0)+(z^x*(e^2+z^0))^q=0*z);
        T:=function(x)
            local r;
            r:=nu*x*B*x;
            return r+r^q;
        end;
        s:=Group([Z(q)*IdentityMat(3,GF(q))]);
        O1:=Orbit(G1, Set(Orbit(s,z^0*[1,0,0])), OnSets);
        O2:=Orbit(G1, Set(Orbit(s,z^0*[1,1,e])), OnSets);
        G:=Graph(G1,Concatenation(O1,O2),OnSets,
            function(x,y) return x<>y and 0*z=T(x[1]+y[1]); end);
        return List([1..OrderGraph(G)],x->Adjacency(G,x));
        end;""")

    adj = adj_list(q) # for each vertex, we get the list of vertices it is adjacent to
    G = Graph(((i,int(j-1))
               for i,ni in enumerate(adj) for j in ni),
               format='list_of_edges', multiedges=False)
    G.name('CossidentePenttila('+str(q)+')')
    return G
Example #7
0
Operations for LibGAP Elements

GAP functions for which several methods can be available are called
operations, so GAP ``Size`` is an example of an operation. This module
is for inspecting GAP operations from Python. In particular, it can
list the operations that take a particular LibGAP element as first
argument. This is used in tab completion, where Python ``x.[TAB]``
lists all GAP operations for which ``Operation(x, ...)`` is defined.
"""

import re
import string
from sage.structure.sage_object import SageObject
from sage.libs.gap.libgap import libgap

Length = libgap.function_factory('Length')
FlagsType = libgap.function_factory('FlagsType')
TypeObj = libgap.function_factory('TypeObj')
IS_SUBSET_FLAGS = libgap.function_factory('IS_SUBSET_FLAGS')
OPERATIONS = libgap.get_global('OPERATIONS')
NameFunction = libgap.function_factory('NameFunction')

NAME_RE = re.compile(r'(Setter|Getter|Tester)\((.*)\)')


class OperationInspector(SageObject):
    def __init__(self, libgap_element):
        """
        Information about operations that can act on a given LibGAP element

        INPUT:
Example #8
0
"""

###############################################################################
#       Copyright (C) 2016, Volker Braun <*****@*****.**>
#
#   Distributed under the terms of the GNU General Public License (GPL)
#   as published by the Free Software Foundation; either version 2 of
#   the License, or (at your option) any later version.
#                   http://www.gnu.org/licenses/
###############################################################################

from six.moves import cPickle
from sage.libs.gap.libgap import libgap
from sage.libs.gap.saved_workspace import workspace

NamesGVars = libgap.function_factory('NamesGVars')
Filtered = libgap.function_factory('Filtered')
ValueGlobal = libgap.function_factory('ValueGlobal')
IsBoundGlobal = libgap.function_factory('IsBoundGlobal')
IsFunction = libgap.function_factory('IsFunction')
IsDocumentedWord = libgap.function_factory('IsDocumentedWord')


def load_or_compute(name, function):
    """
    Helper to load a cached value or compute it

    INPUT:

    - ``name`` -- string. Part of the cache filename
Example #9
0
#       Copyright (C) 2016, Volker Braun <*****@*****.**>
#
#   Distributed under the terms of the GNU General Public License (GPL)
#   as published by the Free Software Foundation; either version 2 of
#   the License, or (at your option) any later version.
#                   http://www.gnu.org/licenses/
###############################################################################


import cPickle
import string
from sage.libs.gap.libgap import libgap
from sage.libs.gap.saved_workspace import workspace


NamesGVars = libgap.function_factory('NamesGVars')
Filtered =libgap.function_factory('Filtered')
ValueGlobal = libgap.function_factory('ValueGlobal')
IsBoundGlobal = libgap.function_factory('IsBoundGlobal')
IsFunction = libgap.function_factory('IsFunction')
IsDocumentedWord = libgap.function_factory('IsDocumentedWord')


def load_or_compute(name, function):
    """
    Helper to load a cached value or compute it

    INPUT:

    - ``name`` -- string. Part of the cache filename
Example #10
0
GAP functions for which several methods can be available are called
operations, so GAP ``Size`` is an example of an operation. This module
is for inspecting GAP operations from Python. In particular, it can
list the operations that take a particular LibGAP element as first
argument. This is used in tab completion, where Python ``x.[TAB]``
lists all GAP operations for which ``Operation(x, ...)`` is defined.
"""

import re
import string
from sage.structure.sage_object import SageObject
from sage.misc.cachefunc import cached_method
from sage.libs.gap.libgap import libgap

Length = libgap.function_factory('Length')
FlagsType = libgap.function_factory('FlagsType')
TypeObj = libgap.function_factory('TypeObj')
IS_SUBSET_FLAGS = libgap.function_factory('IS_SUBSET_FLAGS')
OPERATIONS = libgap.get_global('OPERATIONS')
NameFunction = libgap.function_factory('NameFunction')


NAME_RE = re.compile('(Setter|Getter|Tester)\((.*)\)')


class OperationInspector(SageObject):

    def __init__(self, libgap_element):
        """
        Information about operations that can act on a given LibGAP element
"""
All Documented GAP Functions

This Python module contains all documented GAP functions, they can be
thought of as the official API of GAP.

EXAMPLES::

    sage: from sage.libs.gap.all_documented_functions import *
    sage: DihedralGroup(8)
    <pc group of size 8 with 3 generators>
    sage: GeneratorsOfGroup(_)
    [ f1, f2, f3 ]
    sage: List(_, Order)
    [ 2, 4, 2 ]
"""

from sage.libs.gap.libgap import libgap
from sage.libs.gap.assigned_names import FUNCTIONS as _FUNCTIONS



for _f in _FUNCTIONS:
    globals()[_f] = libgap.function_factory(_f)
Example #12
0
def CossidentePenttilaGraph(q):
    r"""
    Cossidente-Penttila `((q^3+1)(q+1)/2,(q^2+1)(q-1)/2,(q-3)/2,(q-1)^2/2)`-strongly regular graph

    For each odd prime power `q`, one can partition the points of the `O_6^-(q)`-generalized
    quadrange `GQ(q,q^2)` into two parts, so that on any of them the induced subgraph of
    the point graph of the GQ has parameters as above [CP05]_.

    Directly follwing the construction in [CP05]_ is not efficient,
    as one then needs to construct the dual `GQ(q^2,q)`. Thus we
    describe here a more efficient approach that we came up with, following a suggestion by
    T.Penttila. Namely, this partition is invariant
    under the subgroup `H=\Omega_3(q^2)<O_6^-(q)`. We build the appropriate `H`, which
    leaves the form `B(X,Y,Z)=XY+Z^2` invariant, and
    pick up two orbits of `H` on the `F_q`-points. One them is `B`-isotropic, and we
    take the representative `(1:0:0)`. The other one corresponds to the points of
    `PG(2,q^2)` that have all the lines on them either missing the conic specified by `B`, or
    intersecting the conic in two points. We take `(1:1:e)` as the representative. It suffices
    to pick `e` so that `e^2+1` is not a square in `F_{q^2}`. Indeed,
    The conic can be viewed as the union of `\{(0:1:0)\}` and `\{(1:-t^2:t) | t \in F_{q^2}\}`.
    The coefficients of a generic line on `(1:1:e)` are `[1:-1-eb:b]`, for `-1\neq eb`.
    Thus, to make sure the intersection with the conic is always even, we need that the
    discriminant of `1+(1+eb)t^2+tb=0` never vanishes, and this is if and only if
    `e^2+1` is not a square. Further, we need to adjust `B`, by multiplying it by appropriately
    chosen `\nu`, so that `(1:1:e)` becomes isotropic under the relative trace norm
    `\nu B(X,Y,Z)+(\nu B(X,Y,Z))^q`. The latter is used then to define the graph.

    INPUT:

    - ``q`` -- an odd prime power.

    EXAMPLES:

    For `q=3` one gets Sims-Gewirtz graph. ::

        sage: G=graphs.CossidentePenttilaGraph(3)    # optional - gap_packages (grape)
        sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape)
        (56, 10, 0, 2)

    For `q>3` one gets new graphs. ::

        sage: G=graphs.CossidentePenttilaGraph(5)    # optional - gap_packages (grape)
        sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape)
        (378, 52, 1, 8)

    TESTS::

        sage: G=graphs.CossidentePenttilaGraph(7)    # optional - gap_packages (grape) # long time
        sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) # long time
        (1376, 150, 2, 18)
        sage: graphs.CossidentePenttilaGraph(2)
        Traceback (most recent call last):
        ...
        ValueError: q(=2) must be an odd prime power

    REFERENCES:

    .. [CP05] A.Cossidente and T.Penttila
       Hemisystems on the Hermitian surface
       Journal of London Math. Soc. 72(2005), 731-741
    """
    p, k = is_prime_power(q,get_data=True)
    if k==0 or p==2:
        raise ValueError('q(={}) must be an odd prime power'.format(q))

    from sage.libs.gap.libgap import libgap
    from sage.misc.package import is_package_installed, PackageNotFoundError

    if not is_package_installed('gap_packages'):
        raise PackageNotFoundError('gap_packages')

    adj_list=libgap.function_factory("""function(q)
        local z, e, so, G, nu, G1, G0, B, T, s, O1, O2, x;
        LoadPackage("grape");
        G0:=SO(3,q^2);
        so:=GeneratorsOfGroup(G0);
        G1:=Group(Comm(so[1],so[2]),Comm(so[1],so[3]),Comm(so[2],so[3]));
        B:=InvariantBilinearForm(G0).matrix;
        z:=Z(q^2); e:=z; sqo:=(q^2-1)/2;
        if IsInt(sqo/Order(e^2+z^0)) then
            e:=z^First([2..q^2-2], x-> not IsInt(sqo/Order(z^(2*x)+z^0)));
        fi;
        nu:=z^First([0..q^2-2], x->z^x*(e^2+z^0)+(z^x*(e^2+z^0))^q=0*z);
        T:=function(x)
            local r;
            r:=nu*x*B*x;
            return r+r^q;
        end;
        s:=Group([Z(q)*IdentityMat(3,GF(q))]);
        O1:=Orbit(G1, Set(Orbit(s,z^0*[1,0,0])), OnSets);
        O2:=Orbit(G1, Set(Orbit(s,z^0*[1,1,e])), OnSets);
        G:=Graph(G1,Concatenation(O1,O2),OnSets,
            function(x,y) return x<>y and 0*z=T(x[1]+y[1]); end);
        return List([1..OrderGraph(G)],x->Adjacency(G,x));
        end;""")

    adj = adj_list(q) # for each vertex, we get the list of vertices it is adjacent to
    G = Graph(((i,int(j-1))
               for i,ni in enumerate(adj) for j in ni),
               format='list_of_edges', multiedges=False)
    G.name('CossidentePenttila('+str(q)+')')
    return G