4.4 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 is sometimes easy, sometimes hard.

For example, suppose we want to make a wrapper for the 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 access these commands by typing

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".

The purpose of this section is to use this example to show how one might write a Python/Sage program whose input is, say, ('G',2) and whose output is the matrix above (but as a Sage Matrix -- see the code in the directory SAGE_ROOT/devel/sage/sage/matrix/ and the corresponding parts of the Sage reference manual).

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(QQ, rank)
    return MS(ans)
The output ans is a Python list. The last two lines convert that list to an instance of the Sage class Matrix.

Alternatively, one could replace the first line of the above function with this:

    L = gap.new(SimpleLieAlgebra("%s", %s, Rationals);'%(type, rank))

Defining ``easy'' and ``hard'' is subjective, but here is one definition: wrapping a GAP function is ``easy'' if there is already a corresponding class 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 classes 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.