GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#############################################################################
##
#W autoops.gi AutPGrp package Bettina Eick
##
#############################################################################
##
#F PGAutomorphism( <G>, <gens>, <imgs> )
##
InstallMethod( PGAutomorphism,
"for p-groups", true, [IsPGroup, IsList, IsList ], 0,
function( G, gens, imgs )
local filter, type, r, p, pcgs, base, pcgsimgs, baseimgs, def, d;
# cache the default type in the group
if not IsBound( G!.PGAutomType ) then
filter := IsPGAutomorphism and IsBijective;
type := TypeOfDefaultGeneralMapping( G, G, filter );
G!.PGAutomType := type;
else
type := G!.PGAutomType;
fi;
# get images correct
r := RankPGroup( G );
p := PrimePGroup( G );
pcgs := Pcgs( G );
base := pcgs{[1..r]};
if gens = pcgs then
pcgsimgs := imgs;
baseimgs := imgs{[1..r]};
elif gens = base then
baseimgs := ShallowCopy( imgs );
pcgsimgs := ShallowCopy( imgs );
for d in G!.definitions do
if not IsNegRat( d ) then
Add( pcgsimgs, SubstituteDef( d, pcgsimgs, p ) );
fi;
od;
else
Print("# W computing pcgs in PGAutomorphism \n");
pcgsimgs := CanonicalPcgsByGeneratorsWithImages( pcgs, gens, imgs );
baseimgs := pcgsimgs{[1..r]};
fi;
# create homomorphism
return Objectify( type, rec( pcgs := pcgs, pcgsimgs := pcgsimgs,
base := base, baseimgs := baseimgs ) );
end);
#############################################################################
##
#F IdentityPGAutomorphism( <G> )
##
InstallGlobalFunction( IdentityPGAutomorphism, function( G )
return PGAutomorphism( G, Pcgs(G), AsList(Pcgs(G)) );
end );
#############################################################################
##
#F PrintObj(auto)
##
InstallMethod( PrintObj,
"for group automorphisms",
true,
[IsPGAutomorphism],
SUM_FLAGS,
function( auto )
if IsBound( auto!.mat ) then
Print("Aut + Mat: ",auto!.pcgsimgs);
else
Print("Aut: ",auto!.pcgsimgs);
fi;
end);
#############################################################################
##
#F ViewObj(auto)
##
InstallMethod( ViewObj,
"for group automorphisms",
true,
[IsPGAutomorphism],
SUM_FLAGS,
function( auto )
if IsBound( auto!.mat ) then
Print("Aut + Mat: ",auto!.pcgsimgs);
else
Print("Aut: ",auto!.pcgsimgs);
fi;
end);
#############################################################################
##
#F \=
##
InstallMethod( \=,
"for group automorphisms",
IsIdenticalObj,
[IsPGAutomorphism, IsPGAutomorphism],
0,
function( auto1, auto2 )
return auto1!.base = auto2!.base and auto1!.baseimgs = auto2!.baseimgs;
end);
#############################################################################
##
#F ImagesRepresentative( auto, g )
##
InstallMethod( ImagesRepresentative,
"for group automorphisms",
true,
[IsPGAutomorphism, IsObject],
0,
function( auto, g )
return MappedPcElement( g, auto!.pcgs, auto!.pcgsimgs );
end );
#############################################################################
##
#F PGMult( auto1, auto2 )
##
InstallMethod( PGMult, true, [IsPGAutomorphism, IsPGAutomorphism], 0,
function( auto1, auto2 )
local new, aut;
# 1. version
new := List( auto1!.pcgsimgs, x -> ImagesRepresentative( auto2, x ) );
if IsBound( auto1!.mat ) and IsBound( auto2!.mat ) then
aut := PGAutomorphism( Source(auto1), auto1!.pcgs, new );
aut!.mat := auto1!.mat * auto2!.mat;
else
aut := PGAutomorphism( Source(auto1), auto1!.pcgs, new );
fi;
return aut;
# 2. version
new := List( auto2!.baseimgs, x -> ImagesRepresentative( auto1, x ) );
return PGAutomorphism( Source(auto2), auto2!.base, new );
end );
#############################################################################
##
#F CompositionMapping2( auto1, auto2 )
##
InstallMethod( CompositionMapping2,
"for group automorphisms",
true,
[IsPGAutomorphism, IsPGAutomorphism],
0,
function( auto2, auto1 )
return PGMult( auto1, auto2 );
end );
#############################################################################
##
#F PGMultList( autl )
##
InstallMethod( PGMultList, true, [IsList], 0,
function( autl )
local l, r, new;
if Length( autl ) = 1 then return autl[1]; fi;
if Length( autl ) = 2 then return PGMult(autl[1],autl[2]); fi;
l := Length( autl );
r := QuoInt( l, 2 );
new := List( [1..r], x -> PGMult( autl[2*x-1], autl[2*x] ));
if not IsInt( l/2 ) then Add( new, autl[l] ); fi;
return PGMultList( new );
end );
#############################################################################
##
#F PGPower( n, aut )
##
InstallMethod( PGPower, true, [IsInt, IsPGAutomorphism], 0,
function( n, aut )
local c, l, i, j, new;
if n <= 0 then return fail; fi;
if n = 1 then return aut; fi;
c := CoefficientsQadic( n, 2 );
# create power list, if necessary
if not IsBound( aut!.power ) then aut!.power := []; fi;
# add powers, if necessary
l := Length( aut!.power );
if l = 0 then
new := aut;
else
new := aut!.power[l];
fi;
for i in [l+1..Length(c)-1] do
new := PGMult( new, new );
Add( aut!.power, new );
od;
# multiply powers together
if c[1] = 1 then
new := [aut];
else
new := [];
fi;
for i in [2..Length(c)] do
if c[i] = 1 then
Add( new, aut!.power[i-1] );
fi;
od;
return PGMultList( new );
end );
#############################################################################
##
#F PGInverse( aut )
##
InstallMethod( PGInverse, true, [IsPGAutomorphism], 0,
function( aut )
local new, inv;
if not IsBound( aut!.inv ) then
new := CanonicalPcgsByGeneratorsWithImages(
aut!.pcgs, aut!.pcgsimgs, aut!.pcgs);
inv := PGAutomorphism( Source( aut ), aut!.pcgs, new[2] );
else
inv := aut!.inv;
fi;
if IsBound( aut!.mat ) and not IsBound( inv!.mat) then
inv!.mat := aut!.mat^-1;
fi;
aut!.inv := inv;
return aut!.inv;
end );
#############################################################################
##
#F InverseGeneralMapping(auto)
##
InstallOtherMethod( InverseGeneralMapping,
"for group automorphism",
true,
[IsPGAutomorphism],
SUM_FLAGS,
function( auto ) return PGInverse( auto ); end );