loops/gap/extensions.gi

80 lines
3.6 KiB
Plaintext

#############################################################################
##
#W extensions.gi Extensions [loops]
##
#H @(#)$Id: extensions.gi, v 3.0.0 2015/06/15 gap Exp $
##
#Y Copyright (C) 2004, G. P. Nagy (University of Szeged, Hungary),
#Y P. Vojtechovsky (University of Denver, USA)
##
#############################################################################
##
#O LoopByExtension( K, F, phi, theta )
##
## Let K be an abelian group, F a loop, phi: F --> Aut( K ) a homomorphism,
## and theta: F x F --> K a map (cocycle) satisfying theta(1,x) = theta(x,1)
## = 1. Then the function returns the extension K x F with multiplication *
## defined by (a,x)*(b,y) = (a phi(x)(b) theta(x,y), xy).
##
## Note about arguments:
## phi is a list of length |F| of permutations of [1, ..., K ],
## theta is am |F| by |F| matrix of numbers from [1, ..., K].
InstallMethod( LoopByExtension, "for a commutative associative loop and a loop",
[ IsLoop, IsLoop, IsList, IsMatrix ],
function( K, F, phi, theta )
local nK, nF, ctK, ctF, ct, a, b, x, y, c, z;
# only some properties of the arguments are checked
if not IsAssociative( K ) then Error("LOOPS: <1> must be an associative loop."); fi;
if not IsCommutative( K ) then Error("LOOPS: <1> must be a commutative loop."); fi;
# sizes
nK := Size( K );
nF := Size( F );
# making sure all is canonical
ctK := CanonicalCayleyTable( CayleyTable( K ) );
ctF := CanonicalCayleyTable( CayleyTable( F ) );
# future Cayley table
ct := List([1..nK*nF], i -> 0 * [1..nK*nF] );
# constructing the Cayley table
for a in [1..nK] do for b in [1..nK] do for x in [1..nF] do for y in [1..nF] do
c := ctK[ a ][ b^phi[x] ];
c := ctK[ c ][ theta[ x ][ y ] ];
z := ctF[ x ][ y ];
ct[ nK*(x-1) + a ][ nK*(y-1) + b ] := nK*(z-1) + c;
od; od; od; od;
return LoopByCayleyTable( ct );
end);
#############################################################################
##
#O NuclearExtension( Q, K )
##
## Let Q be a loop and K an abelian normal subloop of Q contained in the
## nucleus of Q. Then Q is an extension of K by Q/K = F via a map
## phi: F --> Aut( K ) and a cocycle theta: F x F --> K, as above.
## This function returns the for ingredients [ K, F, phi, theta ],
## all in a canonical form.
InstallMethod( NuclearExtension, "for a loop and a normal nuclear subloop",
[ IsLoop, IsLoop ],
function( Q, K )
local F, t, phi, theta, i, j, elmK;
# checking arguments
if not IsNormal( Q, K ) then Error("LOOPS: <2> must be a normal subloop of <1>."); fi;
if not IsCommutative( K ) then Error("LOOPS: <2> must be a commutative loop."); fi;
if not ForAll( K, k -> k in Nuc( Q ) ) then Error("LOOPS: <2> must be contained in the nucleus of <1>."); fi;
# partitioning Q nicely into cosets of K (not needed but it aids in visualization)
Q := IsomorphicCopyByNormalSubloop( Q, K );
K := Subloop( Q, [1..Size(K)] );
F := FactorLoop( Q, K );
t := List( [1..Size(F)], i -> Elements(Q)[(i-1)*Size(K) + 1] ); #transversal
phi := List( t, x -> RestrictedPerm( MiddleInnerMapping( Q, x ), [1..Size(K)] ) ); #action
theta := List( [1..Size(F)], i -> [1..Size(F)] ); #cocycle
for i in [1..Size(F)] do for j in [1..Size(F)] do
elmK := RightDivision( t[i]*t[j], t[ CayleyTable( F )[ i ][ j ] ] );
theta[ i ][ j ] := Position( Elements( K ), elmK );
od; od;
return [ K, F, phi, theta ];
end);