Spracherkennung für: .g vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
#############################################################################
#
# Code for the realization of the Mal'cev correspondence via the
# matrix embedding.
# Further this file contains code for the multiplications in nilpotent
# by abelian groups.
#
#############################################################################
#
# IN: x ..... upper or lower trinagular matrix with one's on the diagonal
#
# OUT: log(x)
#
MAT_Logarithm := function( x )
local n,mat,matPow,log,i;
n := Length( x[1] );
mat := x - x^0;
matPow := mat;
log := mat;
for i in [2..n-1] do
matPow := matPow*mat;
log := log + (-1)^(i-1)*(i)^-1*matPow;
od;
return log;
end;
#############################################################################
#
# IN: v ..... upper or lower trinagular matrix with 0s on the diagonal
#
# OUT: exp(x)
#
MAT_Exponential := function( v )
local n,exp, vPow, fac, i;
n := Length( v[1] );
exp := IdentityMat(n) + v;
vPow := v;
fac := 1;
for i in [2..n-1] do
vPow := vPow*v;
fac := fac*i;
exp := exp + (fac^-1)*vPow;
od;
return exp;
end;
#############################################################################
#
# IN: g.......... element of parent group GG
#
#MAT_LieAutMatrix := function( g, liealg )
# local N,mats,AutMat,exps,n,i,coeff,mat,log;
#
# N := liealg.N;
# mats := liealg.mats;
# AutMat := [];
# exps := LinearActionOnPcp( [g], liealg.pcp )[1];
# n := Length( exps );
# for i in [1..n] do
# # compute matrix corresponding to n_i^g
# mat := MappedVector( exps[i], mats );
# # compute coefficients with respect to the log n_i 's
# log := MAT_Logarithm( mat );
# coeff := Coefficients( liealg.basis, log );
# Add( AutMat, coeff );
# od;
# return AutMat;
#end;
#############################################################################
#
# IN: g ........ element of parent group GG (new presentation of G )
# NN ....... new presentation of T-group N
# liealg ... liealgebra record of N
# OUT: Automorphism of L(NN) corresponding to the conjugation action
# of g
#
MAT_LieAutMatrix := function( g, NN, liealg )
local AutMat,pcp,mats,exps,n,i,log,coeff,mat;
AutMat := [];
pcp := Pcp( NN );
# get matrices of cpcs of N
mats := liealg.cpcs.pcs.matrices;
exps := LinearActionOnPcp( [g], pcp )[1];
n := Length( exps );
for i in [1..n] do
# compute matrix corresponding to n_i^g
mat := MappedVector( exps[i], mats );
# compute coefficients with respect to the log n_i 's
log := MAT_Logarithm( mat );
coeff := Coefficients( liealg.basis, log );
Add( AutMat, coeff );
od;
return AutMat;
end;
#############################################################################
#
# IN: mats..... list of matrices in lower triangular form
# gens..... shadow list of generators
MAT_Cpcs_LowerTringularMatGroup := function( mats, gens )
local n,conj,matsU,level,pcs;
# bring mats in upper triangular form
n := Length( mats[1] );
conj := IdentityMat( n );
conj := Reversed( conj );
matsU := List( mats, x-> conj*x*conj );
# compute constructive ps-sequence
level := MAT_SiftUpperUnitriMatGroup( matsU, gens );
# pc-sequence of matrix group
pcs := MAT_PolycyclicGenerators( level );
return rec( gens_old := mats,
level := level,
pcs := pcs,
conj := conj );
end;
#############################################################################
#
# IN: mats..... list of matrices which generated an unipotent group
# gens..... shadow list of generators
MAT_Cpcs_UnipotentMatGroup := function( mats, gens )
local conj,matsU,level,pcs,t;
# determine the conjugator to bring mats in upper triangular form
t := Runtime();
Print( "Computing conjugator \c" );
conj := POL_DetermineRealConjugator( mats );
Print( "(", Runtime()-t, " msec)\n" );
# compute constructive ps-sequence
t := Runtime();
Print( "Computing rest of cpcs \c" );
matsU := List( mats, x-> x^conj );
level := MAT_SiftUpperUnitriMatGroup( matsU, gens );
# pc-sequence of matrix group
pcs := MAT_PolycyclicGenerators( level );
Print( "(", Runtime()-t, " msec)\n" );
return rec( gens_old := mats,
level := level,
pcs := pcs,
conj := conj );
end;
#############################################################################
#
# IN: mats..... list of matrices which generated an unipotent group
# There are generated by the algorithm of Nickel,
# using Deep Thought Polynomials.
# These are matrices in lower triangular form,
# but not necessarily with integer entries.
# gens..... shadow list of generators
#
# TODO: This does not work with current implementation
# "Build dual representation", but Werner promises
# in his paper that his alg. can give a lower triangular
# matrix group.
MAT_Cpcs_NickelUnipotentMatGroup := function( mats, gens )
local conj,mats_upper,mats_upper_integral,level,pcs,n,conj1,conj2;
# bring mats in upper triangular integral form
n := Length( mats[1] );
conj1 := IdentityMat( n );
conj1 := Reversed( conj1 );
mats_upper := List( mats, x-> x^conj1 );
conj2 := POL_DetermineConjugatorIntegral( mats_upper );
conj := conj1* conj2;
mats_upper_integral := List( mats_upper, x-> x^conj2 );
# test if it is in uppertriangular and integer form
Assert( 2, POL_UpperTriangIntTest( mats_upper_integral ) );
# compute constructive ps-sequence
level := MAT_SiftUpperUnitriMatGroup( mats_upper_integral, gens );
# pc-sequence of matrix group
pcs := MAT_PolycyclicGenerators( level );
return rec( gens_old := mats,
level := level,
pcs := pcs,
conj := conj );
end;
#############################################################################
#
# IN: ll......... generators exponent list
# n := number of generators of pcs
# OUT exp ....... exponent vector corresponding to ll
MAT_ExpByGenList := function( ll, n )
local exp,m,i;
exp := List( [1..n], x->0 );
m := Length( ll );
i := 1;
while i<m do
exp[ll[i]] := ll[i+1];
i := i+2;
od;
return exp;
end;
#############################################################################
#
# exponent vector for lower triangular matrix group
#
MAT_ExpVector_Cpcs_LTMG := function( cpcs, mat )
local exp1, exp2,n;
exp1 := DecomposeUpperUnitriMat( cpcs.level, mat^cpcs.conj );
exp2 := WordPolycyclicGens( cpcs.pcs, exp1 );
n := Length( cpcs.pcs.gens );
return MAT_ExpByGenList( exp2, n );
end;
#############################################################################
#
# exponent vector for upper triangular matrix group
#
MAT_ExpVector_Cpcs_UTMG := function( cpcs, mat )
local exp1, exp2,n;
exp1 := DecomposeUpperUnitriMat( cpcs.level, mat );
exp2 := WordPolycyclicGens( cpcs.pcs, exp1 );
n := Length( cpcs.pcs.gens );
return MAT_ExpByGenList( exp2, n );
end;
#############################################################################
#
# IN: n .... element of NN
# FCR... fact mult. record of N
#
# OUT: log(n) in L(NN)
#
MAT_Pcp2LieAlg := function( n, FCR )
local exp,mat,log,liealg;
liealg := FCR.liealg;
exp := ExponentsByPcp( FCR.pcpNN, n );
mat := MappedVector( exp, liealg.cpcs.pcs.matrices );
log := MAT_Logarithm( mat );
return Coefficients( liealg.basis, log );
end;
#############################################################################
#
# IN: exp ...exponent vector of.element of NN
# FCR... fact mult. record of N
#
# OUT: log(n) in L(NN)
#
MAT_PcpExp2LieAlg := function( exp, FCR )
local mat,log,liealg;
liealg := FCR.liealg;
mat := MappedVector( exp, liealg.cpcs.pcs.matrices );
log := MAT_Logarithm( mat );
return Coefficients( liealg.basis, log );
end;
MAT_LieAlg2Pcp := function( l, FCR )
local mat,mat2,exp,g;
mat := LinearCombination( FCR.liealg.basis, l );
mat2 := MAT_Exponential( mat );
exp := MAT_ExpVector_Cpcs_UTMG( FCR.liealg.cpcs, mat2 );
#g := MappedVector( exp, FCR.pcpNN );
return exp;
end;
# this version is only needed for timing tests.
MAT_PcpExp2LieAlg_TestVersion := function( args )
local mat,log,exp, liealg;
exp := args[1];
liealg := args[2];
mat := MappedVector( exp, liealg.cpcs.pcs.matrices );
log := MAT_Logarithm( mat );
return Coefficients( liealg.basis, log );
end;
MAT_LieAlg2Pcp_TestVersion := function( args )
local mat,mat2,exp,g,l,liealg;
l := args[1];
liealg := args[2];
mat := LinearCombination( liealg.basis, l );
mat2 := MAT_Exponential( mat );
exp := MAT_ExpVector_Cpcs_UTMG( liealg.cpcs, mat2 );
#g := MappedVector( exp, FCR.pcpNN );
return exp;
end;
#############################################################################
#
# IN: nilpotent N;
# method ... method which is used to compute the representation
# this is either deGraaf_Nickel or Nickel
#
# OUT: record containing
# N ........ input N
# mats...... (old) generators of N represented as matrices
# basis..... basis for the lie algebra Q\log N
# pcp ...... Pcp of N
# cpcs ..... constructive polycyclic sequence for <mats>
#
MAT_LieAlgebra := function( args)
local N2,phi,mats,logs,V,basis,iso,pcp,cpcs,N,method,t;
N := args[1];
if Length( args ) = 1 then
method := "deGraaf_Nickel";
else
method := args[2];
fi;
if method = "deGraaf_Nickel" then
Print( "Compute matrix represetation ...\c" );
pcp := Pcp( N );
N2 := PcpGroupByPcp( pcp );
IsNilpotent( N2 );
phi := UnitriangularMatrixRepresentation( N2 );
mats := GeneratorsOfGroup( Image( phi ) );
Print( "Compute cpcs for representation...\n" );
cpcs := MAT_Cpcs_LowerTringularMatGroup( mats, pcp );
elif method = "Nickel" then
Print( "Compute matrix represetation ...\n" );
pcp := Pcp( N );
N2 := PcpGroupByPcp( pcp );
mats := BuildDualRepresentation( N2 )[2];
Print( "Compute cpcs for representation...\n" );
cpcs := MAT_Cpcs_UnipotentMatGroup( mats, pcp );
else
Error( "wrong method indicated" );
fi;
t := Runtime();
Print( "Computing Lie algebra ...\c" );
logs := List( cpcs.pcs.matrices, MAT_Logarithm );
V := VectorSpace( Rationals, logs );
basis := Basis( V, logs );
Print( "(", Runtime()-t, " msec)\n" );
return rec( N := N, mats := mats, basis := basis, pcp := pcp,
cpcs := cpcs, V := V );
end;
#############################################################################
#
# IN: N...... f.g. torsion-free nilpotent group
# cpcs... constructive pc-seq. of N computed by
# OUT: a pc-presented groups with underlying pc-seq. coming from the
# gens of N
MAT_ChangePcpPresent := function( N, cpcs )
local n, coll,mats, matsInv,i,j,con,exp,genList;
# get number of gens of N = hirsch length of N
n := HirschLength( N );
# define collector
coll := FromTheLeftCollector( n );
# get mats which of cpcs
mats := cpcs.pcs.matrices;
matsInv := List( mats, x -> x^-1 );
# define conjugation relations within N, g_i^g_j
for i in [2..n] do
for j in [1..(i-1)] do
# compute g_i^g_j
con := matsInv[j]*mats[i]*mats[j];
exp := MAT_ExpVector_Cpcs_UTMG( cpcs, con );
genList:=POL_Exp2GenList(exp);
SetConjugate( coll, i, j, genList);
# compute g_i^(g_j^-1)
con := mats[j]*mats[i]*matsInv[j];
exp := MAT_ExpVector_Cpcs_UTMG( cpcs, con );
genList:=POL_Exp2GenList(exp);
SetConjugate( coll, i, -j, genList);
od;
od;
UpdatePolycyclicCollector( coll);
return PcpGroupByCollector( coll );
end;
#############################################################################
#
# IN: g.......... Element of parent group of the T-group N
# liealg .... Liealgebra data structure computed by MAT_LieAlgebra
#
# OUT description of the action of g on N with respect to new pcs of N
# which comes from the matrix cpcs of N
#
MAT_ActionOnNewPcs := function( g, liealg )
local gens_s,n,action,i,h,exp,exp2,mat;
# get new gens in terms of the old ones
gens_s := liealg.cpcs.pcs.gens_s;
n := Length( gens_s );
action := [];
for i in [1..n] do
# compute action of g on gens_s[i] in terms of gens_s
h := gens_s[i]^g;
exp := ExponentsByPcp( liealg.pcp , h );
mat := MappedVector( exp, liealg.mats );
exp2 := MAT_ExpVector_Cpcs_LTMG( liealg.cpcs, mat );
Add( action, exp2 );
od;
return action;
end;
MAT_OldExpN2NewExpN := function( liealg, exp )
local mat;
mat := MappedVector( exp, liealg.mats );
return MAT_ExpVector_Cpcs_LTMG( liealg.cpcs, mat );
end;
#############################################################################
#
# IN: G.......... pc group
# liealg.N.......... torsion-free nilpotent normal subgroup of G
# liealg.cpcs...... constructive pc-seq. for N
#
MAT_NewUnderlyingCollectorParentGrp := function( G, liealg )
local N,cpcs,phi,GN,pcpGN,m,n,l,coll,mats,matsInv,exp1,exp2,exp3,i,j,k,
exp,genList,action,actionInv,g,h,g_I,preImgs,preImgsInv,con,rels;
N := liealg.N;
cpcs := liealg.cpcs;
#get collector
phi := NaturalHomomorphism( G, N );
GN := Image( phi );
pcpGN := Pcp( GN );
m := Length( pcpGN );
n := HirschLength( N );
l := m+n;
coll := FromTheLeftCollector( l );
# define relations wihtin N
# get mats which of cpcs
mats := cpcs.pcs.matrices;
matsInv := List( mats, x -> x^-1 );
# define conjugation relations within N, g_i^g_j
exp1 := List( [1..m], x-> 0 );
for i in [2..n] do
for j in [1..(i-1)] do
# compute g_i^g_j
con := matsInv[j]*mats[i]*mats[j];
exp2 := MAT_ExpVector_Cpcs_UTMG( cpcs, con );
exp := Concatenation( exp1, exp2 );
genList:=POL_Exp2GenList(exp);
SetConjugate( coll, i+m, j+m, genList);
# compute g_i^(g_j^-1)
con := mats[j]*mats[i]*matsInv[j];
exp2 := MAT_ExpVector_Cpcs_UTMG( cpcs, con );
exp := Concatenation( exp1, exp2 );
genList:=POL_Exp2GenList(exp);
SetConjugate( coll, i+m, -(j+m), genList);
od;
od;
#define relations coming from the action of G on N
preImgs := List( pcpGN, x -> PreImagesRepresentative( phi, x ) );
preImgsInv := List( preImgs, x->x^-1 );
for j in [1..m] do
action := MAT_ActionOnNewPcs( preImgs[j], liealg );
actionInv := MAT_ActionOnNewPcs( preImgs[j]^-1, liealg );
for i in [1..n] do
#action of g_j on g_{i+m}
exp2 := action[i];
exp := Concatenation( exp1, exp2 );
genList:=POL_Exp2GenList(exp);
SetConjugate( coll, i+m, j, genList);
#action of g_j^-1 onf g_{i+m}
exp2 := actionInv[i];
exp := Concatenation( exp1, exp2 );
genList:=POL_Exp2GenList(exp);
SetConjugate( coll, i+m, -j, genList);
od;
od;
#define relations coming from relations within the gens of G/N
#conjugation relation
for i in [2..m] do
for j in [1..(i-1)] do
# relation coming from g_i^g_j
g := preImgsInv[j]*preImgs[i]*preImgs[j];
# compute part of exponent in G/N
g_I := Image( phi, g );
exp1 := ExponentsByPcp( pcpGN, g_I );
# divide off
h := MappedVector( exp1, preImgs );
n := h^-1*g;
# compute part of exponent in N
exp2 := ExponentsByPcp( Pcp(N), n );
exp3 := MAT_OldExpN2NewExpN( liealg, exp2 );
exp := Concatenation( exp1, exp3 );
genList:=POL_Exp2GenList(exp);
SetConjugate( coll, i, j, genList);
# relation coming from g_i^(g_j^-1)
g := preImgs[j]*preImgs[i]*preImgsInv[j];
# compute part of exponent in G/N
g_I := Image( phi, g );
exp1 := ExponentsByPcp( pcpGN, g_I );
# divide off
h := MappedVector( exp1, preImgs );
n := h^-1*g;
# compute part of exponent in N
exp2 := ExponentsByPcp( Pcp(N), n );
exp3 := MAT_OldExpN2NewExpN( liealg, exp2 );
exp := Concatenation( exp1, exp3 );
genList:=POL_Exp2GenList(exp);
SetConjugate( coll, i, -j, genList);
od;
od;
#power relation
rels := RelativeOrdersOfPcp( pcpGN );
k := Length( rels );
for i in [1..k] do
if rels[i] <> 0 then
g := preImgs[i]^rels[i];
# compute part of exponent in G/N
g_I := Image( phi, g );
exp1 := ExponentsByPcp( pcpGN, g_I );
# divide off
h := MappedVector( exp1, preImgs );
n := h^-1*g;
# compute part of exponent in N
exp2 := ExponentsByPcp( Pcp(N), n );
exp3 := MAT_OldExpN2NewExpN( liealg, exp2 );
exp := Concatenation( exp1, exp3 );
genList:=POL_Exp2GenList(exp);
SetRelativeOrder( coll, i, rels[i] );
SetPower( coll, i, genList );
fi;
od;
UpdatePolycyclicCollector( coll);
return PcpGroupByCollector( coll );
end;
# IN: g..... Element of parent group of the T-group N
# pcp... Pcp of N
MAT_ActionOfConjugator2List := function( g, pcp )
local autList;
autList := List( pcp, x -> ExponentsByPcp( pcp, x^g ));
return autList;
end;
#############################################################################
#
# IN: G ..... pc-group
# N ..... T-group which is normal in G
#
# OUT: record containing
# a new presentation GG of G with pc-seque. which goes through
# G > N > 1 and which generators corresponding to the constructive
# pc-sequence of N
# and all datastructures which are needed to do fast
# conjugation.
#
MAT_FastConjugationRec := function( G, N )
local liealg,GG,pcpGG,n,l,m,NN,factorGens, lieAuts;
liealg := MAT_LieAlgebra( [N, "deGraaf_Nickel"] );
GG := MAT_NewUnderlyingCollectorParentGrp( G, liealg );
pcpGG := Pcp( GG );
n := HirschLength( N );
l := Length( pcpGG );
m := l-n;
NN := Subgroup( GG, pcpGG{[m+1..l]} );
factorGens := pcpGG{[1..m]};
# compute corresponding autom. of L(NN)
lieAuts := List( pcpGG, x -> MAT_LieAutMatrix( x, NN, liealg ));
return rec( GG := GG,
NN := NN,
pcpNN := Pcp( NN ),
G := G,
liealg := liealg,
factorGens := factorGens,
lieAuts := lieAuts,
info := "mat" );
end;
#############################################################################
#
# IN: FCR ....... fast multiplication record
# n ......... element of T-group N
# c ......... element of parent group of N
# c = w( factorGens )
# OUT: n^c computed via the matrix lie algebra
#
MAT_FastConjugation := function( FCR, n, c )
local lieAut,log,l,g;
exp := Exponents( c );
# map n to L(NN)
log := MAT_Pcp2LieAlg( n, FCR );
#get corresponding automorphism of L(N)
lieAut := MappedVector( exp, FCR.lieAuts );
#apply autom. to log(n)
l := log*lieAut;
#map it back to NN
g := MAT_LieAlg2Pcp( l, FCR );
return g;
end;
#############################################################################
#
# IN: FCR ....... fast multiplication record of a group which is
# the semidiret product of an abelian and a T-Group
# so G = A semi N, for group elements g = a(g)n(g)
#
# Attention: we assume just power relations of the form
# g_i^r_i = 1
#
# g1,g2 ..... random element of G
#
# c = w( factorGens )
# OUT: n^c computed via the matrix lie algebra
#
MAT_FastMultiplicationAbelianSemiTGroup := function( FCR, g1, g2 )
local l,hl,exp1,exp2,exp1_n,exp2_n,exp2_a,rels,i,log,logMat,mat1,mat2,
mat, exp_n,exp,exp_a;
# get length of abelian part and Hirsch length of N
l := Length( FCR.factorGens );
hl := HirschLength( FCR.NN );
# get exponent vectors
exp1 := Exponents( g1 );
exp2 := Exponents( g2 );
exp1_n := exp1{[l+1..l+hl]};
exp2_n := exp2{[l+1..l+hl]};
exp2_a := exp2{[1..l]};
# the computation now follows the scheme:
# g1g2 = a(g1)n(g1) a(g2)n(g2)
# = a(g1)a(g2) n(g1)^a(g2) n(g2)
# exponent vector of a(g1*g2) and reduce mod relative orders
exp_a := exp1{[1..l]} + exp2{[1..l]};
rels := RelativeOrdersOfPcp( Pcp( FCR.GG ) );
for i in [1..l] do
if rels[i] <> 0 then
exp_a[i] := exp_a[i] mod rels[i];
fi;
od;
# map n(g1) to lie algebra
log := MAT_PcpExp2LieAlg( exp1_n, FCR );
# apply a(g2) to it
for i in [1..l] do
log := log*FCR.lieAuts[i]^exp2_a[i];
od;
# get matrix of n(g1)^a(g2) in matrix respresentation of N
logMat := LinearCombination( FCR.liealg.basis, log );
mat1 := MAT_Exponential( logMat );
# get matrix of n(g2) in matrix respresentation of N
mat2 := MappedVector( exp2_n, FCR.liealg.cpcs.pcs.matrices );
# multiply them
mat := mat1*mat2;
# get exponent vector of the result
exp_n := MAT_ExpVector_Cpcs_UTMG( FCR.liealg.cpcs, mat );
exp := Concatenation( exp_a, exp_n );
return exp;
end;
MAT_FastMultiplicationAbelianSemiTGroup_RuntimeVersion := function( args )
local FCR,g1,g2,exp;
FCR := args[1];
g1 := args[2];
g2 := args[3];
exp := MAT_FastMultiplicationAbelianSemiTGroup( FCR, g1, g2 );
return exp;
end;
#
# Test functions
MAT_Test_FCR := function( FCR )
local n,k,i,g,e,c,exp1,exp2;
for i in [1..10] do
n := Random( FCR.NN );
k := Length( FCR.factorGens );
i := RandomList( [1..k] );
g := FCR.factorGens[i];
e := RandomList( [-5..5] ); Print( e, " " );
c := g^e;
exp1 := MAT_FastConjugation( FCR, n, c );
exp2 := ExponentsByPcp( FCR.pcpNN, n^c );
if not exp1 = exp2 then
Error( "Mist\n" );
fi;
od;
end;
# IN: autList ... Let phi be an automorm. of the T-group N with
# pcs g_1,...,g_n. Then autList ist
# [ exp( g_1^phi ), ... , exp( g_n^phi ) ]
# where exp is with respect g_1,...,g_n
# liealg .... Liealgebra data structure computed by MAT_LieAlgebra
#
# OUT autListNew ... Let n_1, ..., n_n be the pcs of N give by the
# matrix cpcs. Then autListNew is
# [ exp( n_1^phi ), ... , exp( n_n^phi ) ]
# where exp is with respect to n_1,...,n_n
#
#MAT_ConvertAutList := fuction( autList, liealg )
# local;
#
#end;
MAT_Test := function()
local T,G,N,FCR,n,g,c;
T := SC_Exams( 4 );
G := T.G;
N := T.N;
FCR := MAT_FastConjugationRec( G, N );
n := Random( FCR.NN );
g := FCR.factorGens[2];
#g := Random( FCR.GG );
c := g;
#c := g^100;
ExponentsByPcp( FCR.pcpNN, n^c );
MAT_FastConjugation( FCR, n, c );
end;