6.2 GAP

(The first version of this chapter was written by David Joyner.)

Wrapping a GAP function in Sage is a matter of writing a program in Python which uses the pexpect interface to pipe various commands to GAP and read back the input into Sage. This can range from easy to hard.

For example, suppose we want to make a wrapper for computation of the Cartan matrix of a simple Lie algebra. The Cartan matrix of $ G_2$ is available in GAP using the commands

gap> L:= SimpleLieAlgebra( "G", 2, Rationals ); 
<Lie algebra of dimension 14 over Rationals>
gap> R:= RootSystem( L );
<root system of rank 2>
gap> CartanMatrix( R );
(Incidentally, most of the GAP Lie algebra implementation was written by Thomas Breuer, Willem de Graaf and Craig Struble.)

In Sage, one can simply type

sage: L = gap.SimpleLieAlgebra('"G"', 2, 'Rationals'); L
Algebra( Rationals, [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9, v.10, 
  v.11, v.12, v.13, v.14 ] )
sage: R = L.RootSystem(); R
<root system of rank 2>
sage: R.CartanMatrix()
[ [ 2, -1 ], [ -3, 2 ] ]
Note the '"G"' which is evaluated in Gap as the string "G".

Using this example, the purpose of this section is to show how one might write a Pyhon/Sage program who's input is, say, ('G',2) and who's output is the matrix above (but as a Sage Matrix - see matrix.py in sage/matrix/matrix.py).

First, the input must be converted into strings consisting of legal GAP commands. Then the GAP output, which is also a string, must be parsed and converted if possible to a corresponding Sage/Python class object.

def cartan_matrix(type, rank):
    """
    Return the Cartain matrix of given Chevalley type and rank.

    INPUT:
        type -- a Chevalley letter name, as a string, for
                a family type of simple Lie algebras
        rank -- an integer (legal for that type).

    EXAMPLES:
        sage: cartan_matrix("A",5)
        [ 2 -1  0  0  0]
        [-1  2 -1  0  0]
        [ 0 -1  2 -1  0]
        [ 0  0 -1  2 -1]
        [ 0  0  0 -1  2]
        sage: cartan_matrix("G",2)
        [ 2 -1]
        [-3  2]
    """

    L = gap.SimpleLieAlgebra('"%s"'%type, rank, 'Rationals')
    R = L.RootSystem()
    sM  = R.CartanMatrix()
    ans = eval(str(sM))
    MS  = MatrixSpace(ZZ, rank)
    return MS(ans)
The output ans is a Python list. The last two lines convert that list to a Sage class object Matrix instance.

Alternatively, one could code the body of the above function in a more pythonic way as follows:

    L = gap.new(SimpleLieAlgebra("%s", %s, Rationals);'%(type, rank))
    R = L.RootSystem()
    sM = R.CartanMatrix()
    ans = eval(str(sM))
    MS  = MatrixSpace(QQ, rank)
    return MS(ans)

Defining ``easy'' and ``hard'' is subjective, but here is one definition: an example is ``easy'' if there is already a corresponding class object in Python or Sage for the output data type of the GAP function you are trying to wrap. For example, wrapping any GUAVA (GAP's error-correcting codes package) function is ``easy'' since error-correcting codes are vector spaces over finite fields and GUAVA functions return one of the following data types:

(a)
vectors over finite fields,

(b)
polynomials over finite fields,

(c)
matrices over finite fields,

(d)
permutation groups or their elements,

(e)
integers.
Sage already has a class object for each of these.

A ``hard'' example is left as an exercise! Here are a few ideas.

See About this document... for information on suggesting changes.