This chapter contains an introduction into vector spaces and algebras in GAP.
A vector space \(V\) over a field \(F\) is an (abelian) additive group that is closed under scalar multiplication by elements in \(F\), such that
\(1v=v\),
\(a(bv)=(ab)v\),
\(a(v+w)=av+aw\), and
\((a+b)v=av+bv\),
for all \(a,b \in F\) and all \(v,w \in V\). In GAP, only those domains that are constructed as vector spaces are regarded as vector spaces. In particular, an additive group that does not know about an acting domain of scalars is not regarded as a vector space in GAP.
Probably the most common \(F\)-vector spaces in GAP are so-called row spaces. They consist of row vectors, that is, lists whose elements lie in \(F\). In the following example we compute the vector space spanned by the row vectors [ 1, 1, 1 ]
and [ 1, 0, 2 ]
over the rationals.
gap> F:= Rationals;; gap> V:= VectorSpace( F, [ [ 1, 1, 1 ], [ 1, 0, 2 ] ] ); <vector space over Rationals, with 2 generators> gap> [ 2, 1, 3 ] in V; true
The full row space \(F^n\) is created by commands like:
gap> F:= GF( 7 );; gap> V:= F^3; # The full row space over F of dimension 3. ( GF(7)^3 ) gap> [ 1, 2, 3 ] * One( F ) in V; true
In the same way we can also create matrix spaces. Here the short notation field^[dim1,dim2]
can be used:
gap> m1:= [ [ 1, 2 ], [ 3, 4 ] ];; m2:= [ [ 0, 1 ], [ 1, 0 ] ];; gap> V:= VectorSpace( Rationals, [ m1, m2 ] ); <vector space over Rationals, with 2 generators> gap> m1+m2 in V; true gap> W:= Rationals^[3,2]; ( Rationals^[ 3, 2 ] ) gap> [ [ 1, 1 ], [ 2, 2 ], [ 3, 3 ] ] in W; true
A field is naturally a vector space over itself.
gap> IsVectorSpace( Rationals ); true
If \(\Phi\) is an algebraic extension of \(F\), then \(\Phi\) is also a vector space over \(F\) (and indeed over any subfield of \(\Phi\) that contains \(F\)). This field \(F\) is stored in the attribute LeftActingDomain
(Reference: LeftActingDomain). In GAP, the default is to view fields as vector spaces over their prime fields. By the function AsVectorSpace
(Reference: AsVectorSpace), we can view fields as vector spaces over fields other than the prime field.
gap> F:= GF( 16 );; gap> LeftActingDomain( F ); GF(2) gap> G:= AsVectorSpace( GF( 4 ), F ); AsField( GF(2^2), GF(2^4) ) gap> F = G; true gap> LeftActingDomain( G ); GF(2^2)
A vector space has three important attributes: its field of definition, its dimension and a basis. We already encountered the function LeftActingDomain
(Reference: LeftActingDomain) in the example above. It extracts the field of definition of a vector space. The function Dimension
(Reference: Dimension) provides the dimension of the vector space.
gap> F:= GF( 9 );; gap> m:= [ [ Z(3)^0, 0*Z(3), 0*Z(3) ], [ 0*Z(3), Z(3)^0, Z(3)^0 ] ];; gap> V:= VectorSpace( F, m ); <vector space over GF(3^2), with 2 generators> gap> Dimension( V ); 2 gap> W:= AsVectorSpace( GF( 3 ), V ); <vector space over GF(3), with 4 generators> gap> V = W; true gap> Dimension( W ); 4 gap> LeftActingDomain( W ); GF(3)
One of the most important attributes is a basis. For a given basis \(B\) of \(V\), every vector \(v\) in \(V\) can be expressed uniquely as \(v = \sum_{b \in B} c_b b\), with coefficients \(c_b \in F\).
In GAP, bases are special lists of vectors. They are used mainly for the computation of coefficients and linear combinations.
Given a vector space \(V\), a basis of \(V\) is obtained by simply applying the function Basis
(Reference: Basis) to \(V\). The vectors that form the basis are extracted from the basis by BasisVectors
(Reference: BasisVectors).
gap> m1:= [ [ 1, 2 ], [ 3, 4 ] ];; m2:= [ [ 1, 1 ], [ 1, 0 ] ];; gap> V:= VectorSpace( Rationals, [ m1, m2 ] ); <vector space over Rationals, with 2 generators> gap> B:= Basis( V ); SemiEchelonBasis( <vector space over Rationals, with 2 generators>, ... ) gap> BasisVectors( Basis( V ) ); [ [ [ 1, 2 ], [ 3, 4 ] ], [ [ 0, 1 ], [ 2, 4 ] ] ]
The coefficients of a vector relative to a given basis are found by the function Coefficients
(Reference: Coefficients). Furthermore, linear combinations of the basis vectors are constructed using LinearCombination
(Reference: LinearCombination).
gap> V:= VectorSpace( Rationals, [ [ 1, 2 ], [ 3, 4 ] ] ); <vector space over Rationals, with 2 generators> gap> B:= Basis( V ); SemiEchelonBasis( <vector space over Rationals, with 2 generators>, ... ) gap> BasisVectors( Basis( V ) ); [ [ 1, 2 ], [ 0, 1 ] ] gap> Coefficients( B, [ 1, 0 ] ); [ 1, -2 ] gap> LinearCombination( B, [ 1, -2 ] ); [ 1, 0 ]
In the above examples we have seen that GAP often chooses the basis it wants to work with. It is also possible to construct bases with prescribed basis vectors by giving a list of these vectors as second argument to Basis
(Reference: Basis).
gap> V:= VectorSpace( Rationals, [ [ 1, 2 ], [ 3, 4 ] ] );; gap> B:= Basis( V, [ [ 1, 0 ], [ 0, 1 ] ] ); SemiEchelonBasis( <vector space over Rationals, with 2 generators>, [ [ 1, 0 ], [ 0, 1 ] ] ) gap> Coefficients( B, [ 1, 2 ] ); [ 1, 2 ]
We can construct subspaces and quotient spaces of vector spaces. The natural projection map (constructed by NaturalHomomorphismBySubspace
(Reference: NaturalHomomorphismBySubspace)), connects a vector space with its quotient space.
gap> V:= Rationals^4; ( Rationals^4 ) gap> W:= Subspace( V, [ [ 1, 2, 3, 4 ], [ 0, 9, 8, 7 ] ] ); <vector space over Rationals, with 2 generators> gap> VmodW:= V/W; ( Rationals^2 ) gap> h:= NaturalHomomorphismBySubspace( V, W ); <linear mapping by matrix, ( Rationals^4 ) -> ( Rationals^2 )> gap> Image( h, [ 1, 2, 3, 4 ] ); [ 0, 0 ] gap> PreImagesRepresentative( h, [ 1, 0 ] ); [ 1, 0, 0, 0 ]
If a bilinear multiplication is defined for the elements of a vector space, and if the vector space is closed under this multiplication then it is called an algebra. For example, every field is an algebra:
gap> f:= GF(8); IsAlgebra( f ); GF(2^3) true
One of the most important classes of algebras are sub-algebras of matrix algebras. On the set of all \(n \times n\) matrices over a field \(F\) it is possible to define a multiplication in many ways. The most frequent are the ordinary matrix multiplication and the Lie multiplication.
Each matrix constructed as \([ \textit{row1}, \textit{row2}, \ldots ]\) is regarded by GAP as an ordinary matrix, its multiplication is the ordinary associative matrix multiplication. The sum and product of two ordinary matrices are again ordinary matrices.
The full matrix associative algebra can be created as follows:
gap> F:= GF( 9 );; gap> A:= F^[3,3]; ( GF(3^2)^[ 3, 3 ] )
An algebra can be constructed from generators using the function Algebra
(Reference: Algebra). It takes as arguments the field of coefficients and a list of generators. Of course the coefficient field and the generators must fit together; if we want to construct an algebra of ordinary matrices, we may take the field generated by the entries of the generating matrices, or a subfield or extension field.
gap> m1:= [ [ 1, 1 ], [ 0, 0 ] ];; m2:= [ [ 0, 0 ], [ 0, 1 ] ];; gap> A:= Algebra( Rationals, [ m1, m2 ] ); <algebra over Rationals, with 2 generators>
An interesting class of algebras for which many special algorithms are implemented is the class of Lie algebras. They arise for example as algebras of matrices whose product is defined by the Lie bracket \([ A, B ] = A * B - B * A\), where \(*\) denotes the ordinary matrix product.
Since the multiplication of objects in GAP is always assumed to be the operation *
(resp. the infix operator *
), and since there is already the ordinary
matrix product defined for ordinary matrices, as mentioned above, we must use a different construction for matrices that occur as elements of Lie algebras. Such Lie matrices can be constructed by LieObject
(Reference: LieObject) from ordinary matrices, the sum and product of Lie matrices are again Lie matrices.
gap> m:= LieObject( [ [ 1, 1 ], [ 1, 1 ] ] ); LieObject( [ [ 1, 1 ], [ 1, 1 ] ] ) gap> m*m; LieObject( [ [ 0, 0 ], [ 0, 0 ] ] ) gap> IsOrdinaryMatrix( m1 ); IsOrdinaryMatrix( m ); true false gap> IsLieMatrix( m1 ); IsLieMatrix( m ); false true
Given a field F
and a list mats
of Lie objects over F
, we can construct the Lie algebra generated by mats
using the function Algebra
(Reference: Algebra). Alternatively, if we do not want to be bothered with the function LieObject
(Reference: LieObject), we can use the function LieAlgebra
(Reference: LieAlgebra for an associative algebra) that takes a field and a list of ordinary matrices, and constructs the Lie algebra generated by the corresponding Lie matrices. Note that this means that the ordinary matrices used in the call of LieAlgebra
(Reference: LieAlgebra for an associative algebra) are not contained in the returned Lie algebra.
gap> m1:= [ [ 0, 1 ], [ 0, 0 ] ];; gap> m2:= [ [ 0, 0 ], [ 1, 0 ] ];; gap> L:= LieAlgebra( Rationals, [ m1, m2 ] ); <Lie algebra over Rationals, with 2 generators> gap> m1 in L; false
A second way of creating an algebra is by specifying a multiplication table. Let \(A\) be a finite dimensional algebra with basis \((x_1, x_2, \ldots, x_n)\), then for \(1 \leq i, j \leq n\) the product \(x_i x_j\) is a linear combination of basis elements, i.e., there are \(c_{ij}^k\) in the ground field such that \(x_i x_j = \sum_{k=1}^n c_{ij}^k x_k.\) It is not difficult to show that the constants \(c_{ij}^k\) determine the multiplication completely. Therefore, the \(c_{ij}^k\) are called structure constants. In GAP we can create a finite dimensional algebra by specifying an array of structure constants.
In GAP such a table of structure constants is represented using lists. The obvious way to do this would be to construct a three-dimensional
list T
such that T[i][j][k]
equals \(c_{ij}^k\). But it often happens that many of these constants vanish. Therefore a more complicated structure is used in order to be able to omit the zeros. A multiplication table of an \(n\)-dimensional algebra is an \(n \times n\) array T
such that T[i][j]
describes the product of the i
-th and the j
-th basis element. This product is encoded in the following way. The entry T[i][j]
is a list of two elements. The first of these is a list of indices \(k\) such that \(c_{ij}^k\) is nonzero. The second list contains the corresponding constants \(c_{ij}^k\). Suppose, for example, that S
is the table of an algebra with basis \((x_1, x_2, \ldots, x_8)\) and that S[3][7]
equals [ [ 2, 4, 6 ], [ 1/2, 2, 2/3 ] ]
. Then in the algebra we have the relation \(x_3 x_7 = (1/2) x_2 + 2 x_4 + (2/3) x_6.\) Furthermore, if S[6][1] = [ [ ], [ ] ]
then the product of the sixth and first basis elements is zero.
Finally two numbers are added to the table. The first number can be 1, -1, or 0. If it is 1, then the table is known to be symmetric, i.e., \(c_{ij}^k = c_{ji}^k\). If this number is -1, then the table is known to be antisymmetric (this happens for instance when the algebra is a Lie algebra). The remaining case, 0, occurs in all other cases. The second number that is added is the zero element of the field over which the algebra is defined.
Empty structure constants tables are created by the function EmptySCTable
(Reference: EmptySCTable), which takes a dimension \(d\), a zero element \(z\), and optionally one of the strings "symmetric"
, "antisymmetric"
, and returns an empty structure constants table \(T\) corresponding to a \(d\)-dimensional algebra over a field with zero element \(z\). Structure constants can be entered into the table \(T\) using the function SetEntrySCTable
(Reference: SetEntrySCTable). It takes four arguments, namely \(T\), two indices \(i\) and \(j\), and a list of the form \([ c_{ij}^{{k_1}}, k_1, c_{ij}^{{k_2}}, k_2, \ldots ]\). In this call to SetEntrySCTable
, the product of the \(i\)-th and the \(j\)-th basis vector in any algebra described by \(T\) is set to \(\sum_l c_{ij}^{{k_l}} x_{{k_l}}\). (Note that in the empty table, this product was zero.) If \(T\) knows that it is (anti)symmetric, then at the same time also the product of the \(j\)-th and the \(i\)-th basis vector is set appropriately.
gap> T:= EmptySCTable( 2, 0, "symmetric" ); [ [ [ [ ], [ ] ], [ [ ], [ ] ] ], [ [ [ ], [ ] ], [ [ ], [ ] ] ], 1, 0 ] gap> SetEntrySCTable( T, 1, 2, [1/2,1,1/3,2] ); T; [ [ [ [ ], [ ] ], [ [ 1, 2 ], [ 1/2, 1/3 ] ] ], [ [ [ 1, 2 ], [ 1/2, 1/3 ] ], [ [ ], [ ] ] ], 1, 0 ]
If we have defined a structure constants table, then we can construct the corresponding algebra by AlgebraByStructureConstants
(Reference: AlgebraByStructureConstants).
gap> A:= AlgebraByStructureConstants( Rationals, T ); <algebra of dimension 2 over Rationals>
If we know that a structure constants table defines a Lie algebra, then we can construct the corresponding Lie algebra by LieAlgebraByStructureConstants
(Reference: LieAlgebraByStructureConstants); the algebra returned by this function knows that it is a Lie algebra, so GAP need not check the Jacobi identity.
gap> T:= EmptySCTable( 2, 0, "antisymmetric" );; gap> SetEntrySCTable( T, 1, 2, [2/3,1] ); gap> L:= LieAlgebraByStructureConstants( Rationals, T ); <Lie algebra of dimension 2 over Rationals>
In GAP an algebra is naturally a vector space. Hence all the functionality for vector spaces is also available for algebras.
gap> F:= GF(2);; gap> z:= Zero( F );; o:= One( F );; gap> T:= EmptySCTable( 3, z, "antisymmetric" );; gap> SetEntrySCTable( T, 1, 2, [ o, 1, o, 3 ] ); gap> SetEntrySCTable( T, 1, 3, [ o, 1 ] ); gap> SetEntrySCTable( T, 2, 3, [ o, 3 ] ); gap> A:= AlgebraByStructureConstants( F, T ); <algebra of dimension 3 over GF(2)> gap> Dimension( A ); 3 gap> LeftActingDomain( A ); GF(2) gap> Basis( A ); CanonicalBasis( <algebra of dimension 3 over GF(2)> )
Subalgebras and ideals of an algebra can be constructed by specifying a set of generators for the subalgebra or ideal. The quotient space of an algebra by an ideal is naturally an algebra itself.
gap> m:= [ [ 1, 2, 3 ], [ 0, 1, 6 ], [ 0, 0, 1 ] ];; gap> A:= Algebra( Rationals, [ m ] );; gap> subA:= Subalgebra( A, [ m-m^2 ] ); <algebra over Rationals, with 1 generator> gap> Dimension( subA ); 2 gap> idA:= Ideal( A, [ m-m^3 ] ); <two-sided ideal in <algebra of dimension 3 over Rationals>, (1 generator)> gap> Dimension( idA ); 2 gap> B:= A/idA; <algebra of dimension 1 over Rationals>
The call B:= A/idA
creates a new algebra that does not know
about its connection with A
. If we want to connect an algebra with its factor via a homomorphism, then we first have to create the homomorphism (NaturalHomomorphismByIdeal
(Reference: NaturalHomomorphismByIdeal)). After this we create the factor algebra from the homomorphism by the function ImagesSource
(Reference: ImagesSource). In the next example we divide an algebra A
by its radical and lift the central idempotents of the factor to the original algebra A
.
gap> m1:=[[1,0,0],[0,2,0],[0,0,3]];; gap> m2:=[[0,1,0],[0,0,2],[0,0,0]];; gap> A:= Algebra( Rationals, [ m1, m2 ] );; gap> Dimension( A ); 6 gap> R:= RadicalOfAlgebra( A ); <algebra of dimension 3 over Rationals> gap> h:= NaturalHomomorphismByIdeal( A, R ); <linear mapping by matrix, <algebra of dimension 6 over Rationals> -> <algebra of dimension 3 over Rationals>> gap> AmodR:= ImagesSource( h ); <algebra of dimension 3 over Rationals> gap> id:= CentralIdempotentsOfAlgebra( AmodR ); [ v.3, v.2+(-3)*v.3, v.1+(-2)*v.2+(3)*v.3 ] gap> PreImagesRepresentative( h, id[1] ); [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 1 ] ] gap> PreImagesRepresentative( h, id[2] ); [ [ 0, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 0 ] ] gap> PreImagesRepresentative( h, id[3] ); [ [ 1, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ]
Structure constants tables for the simple Lie algebras are present in GAP. They can be constructed using the function SimpleLieAlgebra
(Reference: SimpleLieAlgebra). The Lie algebras constructed by this function come with a root system attached.
gap> L:= SimpleLieAlgebra( "G", 2, Rationals ); <Lie algebra of dimension 14 over Rationals> gap> R:= RootSystem( L ); <root system of rank 2> gap> PositiveRoots( R ); [ [ 2, -1 ], [ -3, 2 ], [ -1, 1 ], [ 1, 0 ], [ 3, -1 ], [ 0, 1 ] ] gap> CartanMatrix( R ); [ [ 2, -1 ], [ -3, 2 ] ]
Another example of algebras is provided by quaternion algebras. We define a quaternion algebra over an extension field of the rationals, namely the field generated by \(\sqrt{{5}}\). (The number EB(5)
is equal to \(1/2 (-1+\sqrt{{5}})\). The field is printed as NF(5,[ 1, 4 ])
.)
gap> b5:= EB(5); E(5)+E(5)^4 gap> q:= QuaternionAlgebra( FieldByGenerators( [ b5 ] ) ); <algebra-with-one of dimension 4 over NF(5,[ 1, 4 ])> gap> gens:= GeneratorsOfAlgebra( q ); [ e, i, j, k ] gap> e:= gens[1];; i:= gens[2];; j:= gens[3];; k:= gens[4];; gap> IsAssociative( q ); true gap> IsCommutative( q ); false gap> i*j; j*i; k (-1)*k gap> One( q ); e
If the coefficient field is a real subfield of the complex numbers then the quaternion algebra is in fact a division ring.
gap> IsDivisionRing( q ); true gap> Inverse( e+i+j ); (1/3)*e+(-1/3)*i+(-1/3)*j
So GAP knows about this fact. As in any ring, we can look at groups of units. (The function StarCyc
(Reference: StarCyc) used below computes the unique algebraic conjugate of an element in a quadratic subfield of a cyclotomic field.)
gap> c5:= StarCyc( b5 ); E(5)^2+E(5)^3 gap> g1:= 1/2*( b5*e + i - c5*j ); (1/2*E(5)+1/2*E(5)^4)*e+(1/2)*i+(-1/2*E(5)^2-1/2*E(5)^3)*j gap> Order( g1 ); 5 gap> g2:= 1/2*( -c5*e + i + b5*k ); (-1/2*E(5)^2-1/2*E(5)^3)*e+(1/2)*i+(1/2*E(5)+1/2*E(5)^4)*k gap> Order( g2 ); 10 gap> g:=Group( g1, g2 );; #I default `IsGeneratorsOfMagmaWithInverses' method returns `true' for [ (1/2*E(5)+1/2*E(5)^4)*e+(1/2)*i+(-1/2*E(5)^2-1/2*E(5)^3)*j, (-1/2*E(5)^2-1/2*E(5)^3)*e+(1/2)*i+(1/2*E(5)+1/2*E(5)^4)*k ] gap> Size( g ); 120 gap> IsPerfect( g ); true
Since there is only one perfect group of order 120, up to isomorphism, we see that the group g
is isomorphic to \(SL_2(5)\). As usual, a permutation representation of the group can be constructed using a suitable action of the group.
gap> cos:= RightCosets( g, Subgroup( g, [ g1 ] ) );; gap> Length( cos ); 24 gap> hom:= ActionHomomorphism( g, cos, OnRight );; gap> im:= Image( hom ); Group([ (2,3,5,9,15)(4,7,12,8,14)(10,17,23,20,24)(11,19,22,16,13), (1,2,4,8,3,6,11,20,17,19)(5,10,18,7,13,22,12,21,24,15)(9,16)(14,23) ]) gap> Size( im ); 120
To get a matrix representation of g
or of the whole algebra q
, we must specify a basis of the vector space on which the algebra acts, and compute the linear action of elements w.r.t. this basis.
gap> bas:= CanonicalBasis( q );; gap> BasisVectors( bas ); [ e, i, j, k ] gap> op:= OperationAlgebraHomomorphism( q, bas, OnRight ); <op. hom. AlgebraWithOne( NF(5,[ 1, 4 ]), [ e, i, j, k ] ) -> matrices of dim. 4> gap> ImagesRepresentative( op, e ); [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ] gap> ImagesRepresentative( op, i ); [ [ 0, 1, 0, 0 ], [ -1, 0, 0, 0 ], [ 0, 0, 0, -1 ], [ 0, 0, 1, 0 ] ] gap> ImagesRepresentative( op, g1 ); [ [ 1/2*E(5)+1/2*E(5)^4, 1/2, -1/2*E(5)^2-1/2*E(5)^3, 0 ], [ -1/2, 1/2*E(5)+1/2*E(5)^4, 0, -1/2*E(5)^2-1/2*E(5)^3 ], [ 1/2*E(5)^2+1/2*E(5)^3, 0, 1/2*E(5)+1/2*E(5)^4, -1/2 ], [ 0, 1/2*E(5)^2+1/2*E(5)^3, 1/2, 1/2*E(5)+1/2*E(5)^4 ] ]
More information about vector spaces can be found in ChapterĀ Reference: Vector Spaces. ChapterĀ Reference: Algebras deals with the functionality for general algebras. Furthermore, concerning special functions for Lie algebras, there is ChapterĀ Reference: Lie Algebras.
generated by GAPDoc2HTML