##################################################################################### # # fpla.gi Serena Cicalo' and Willem de Graaf # # # The package LieRing is free software; you can redistribute it and/or modify it under the # terms of the GNU General Public License as published by the Free Software Foundation; # either version 2 of the License, or (at your option) any later version.
local o, mninds, b, i, mat, cc, bas, mns, n, t, s;
o:= fam!.ordering;
mninds:= [ ]; for b in BB do for i in [1,3..Length(b)-1] do if not b[i].no in mninds then Add( mninds, b[i].no ); fi;
od;
od;
Sort( mninds, function( a, b ) return o[a] > o[b]; end );
mat:= [ ]; for b in BB do
cc:= List( mninds, x -> 0 ); for i in [1,3..Length(b)-1] do
cc[ Position( mninds, b[i].no ) ]:= b[i+1];
od;
Add( mat, cc );
od;
TriangulizeMat( mat );
bas:= [ ];
mns:= fam!.monomials;
n:= Length( mninds ); for cc in mat do if cc <> 0*cc then
b:= [ ]; for i in [n,n-1..1] do if cc[i] <> 0then
Add( b, mns[ o[mninds[i]] ] );
Add( b, cc[i] ); fi;
od;
Add( bas, b ); fi;
# Here we do assume G to be monic, but not that lms is sorted, # so a bit different from reduce.
local lms0, ef, len, r, m, cf, a, g, mns, side, lg, i;
if f=[] then return f; fi; if G = [ ] then return f; fi;
lms0:= List( lms, x -> x.no );
ef:= ShallowCopy( f );
len:= Length(ef);
r:= [ ];
while len >0do
m:= ef[ len-1 ]; cf:= ef[len];
ef:= ef{[1..len-2]};
len:= len-2;
# look for a factor...
a:= LRPrivateFunctions.search_factor0( m, lms0 );
if a[1] then
g:= ShallowCopy(G[a[2]]);
lg:= Length(g);
mns:= a[3];
side:= a[4];
g:= g{[1..lg-2]};
for i in [1..Length(mns)] do if side[i] = 0then
g:= LRPrivateFunctions.dir_mult( fam, [mns[i],1], g ); else
g:= LRPrivateFunctions.dir_mult( fam, g, [mns[i],1] ); fi;
od;
# compute -cf*g: for i in [2,4..Length(g)] do
g[i]:= -cf*g[i];
od;
ef:= LRPrivateFunctions.direct_sum( fam, ef, g );
len:= Length( ef );
# Here we do assume G to be monic, and that lms is sorted
local lms0, ef, len, r, m, cf, a, g, mns, side, lg, i;
if f=[] then return f; fi; if G = [ ] then return f; fi;
lms0:= List( lms, x -> x.no );
ef:= ShallowCopy( f );
len:= Length(ef);
r:= [ ];
while len > 0do
m:= ef[ len-1 ]; cf:= ef[len];
ef:= ef{[1..len-2]};
len:= len-2;
# look for a factor...
a:= LRPrivateFunctions.search_factor( m, lms0 );
if a[1] then
g:= ShallowCopy(G[a[2]]);
lg:= Length(g);
mns:= a[3];
side:= a[4];
g:= g{[1..lg-2]};
for i in [1..Length(mns)] do if side[i] = 0then
g:= LRPrivateFunctions.dir_mult( fam, [mns[i],1], g ); else
g:= LRPrivateFunctions.dir_mult( fam, g, [mns[i],1] ); fi;
od;
# compute -cf*g: for i in [2,4..Length(g)] do
g[i]:= -cf*g[i];
od;
ef:= LRPrivateFunctions.direct_sum( fam, ef, g );
len:= Length( ef );
if h <> [] then # we add it, but first we remove all elements of which the # leading monomial reduces mod h from G:
n:= [ h[ Length(h)-1 ] ];
Gh:= [ h ]; for i in [1..Length(G)] do
g:= LRPrivateFunctions.reduce_sorted( fam, G[i], Gh, n ); if g <> [] and g[Length(g)-1].no <> lms[i].no then
Add( newelms, g ); len:= len+1;
Unbind( G[i] ); Unbind( lms[i] ); elif g=[ ] then
Unbind( G[i] ); Unbind( lms[i] ); else
G[i]:= g; fi;
od;
G:= Filtered( G, x -> IsBound(x) );
LRPrivateFunctions.is_interred:= function( Fam, G )
local i, j, h;
for i in [1..Length(G)] do for j in [1..Length(G)] do if i <> j then
h:= LRPrivateFunctions.reduce_sorted( Fam, G[i], [ G[j] ], [ G[j][Length(G[j])-1] ] ); if h <> G[i] then
Print(i," ",j,"\n");
return false; fi; fi;
od;
od;
return true;
end;
LRPrivateFunctions.interreduce_field:= function( fam, U )
local G, lms, i, r, f, k, cf, lf;
for i in [1..Length(U)] do if U[i] = [ ] then
Unbind( U[i] ); fi;
od;
U:= Filtered( U, x -> IsBound(x) );
if U = [] then return U; fi;
Sort( U, function(u,v) return u[Length(u)-1].deg < v[Length(v)-1].deg; end );
for i in [1..Length(U)] do
f:= ShallowCopy(U[i]); lf:= Length(f);
cf:= f[lf]; if not IsOne( cf ) then for k in [2,4..lf] do f[k]:= f[k]/cf; od;
U[i]:= f; fi;
od;
G:= [ U[1] ];
lms:= [ U[1][ Length(U[1])-1 ] ]; for i in [2..Length(U)] do
r:= LRPrivateFunctions.addElm_RedSet_field( fam, U[i], G, lms );
G:= r[1]; lms:= r[2];
od;
return G;
end;
InstallMethod( FpLieAlgebra, "for free Lie algebra and list of its elements",
true, [ IsFreeNAAlgebra, IsList ], 0, function( A, RR )
# compute A/I, where I is the ideal gen by R along with Jacobi s
# i.e., if the degrees of the generators are different, then we # loop until the bound, and we do not care about homogeneous components # that are zero.
# determine whether the relations are homogeneous.
is_hom:= true; for r in RR do
eg:= r![1];
dg:= eg[1].deg; for k in [3,5..Length(eg)-1] do if eg[k].deg <> dg then
is_hom:= false; break; fi;
od; if not is_hom and is_nilquot then bound:= 2*bound; break; fi;
od;
while deg <= bound do
rels:= [ ];
if is_nilquot and deg = nilquot+1then# ONLY in nonhom case!!! # we have to add all monomials of degree deg to the relations for i in [1..Length(Bd)] do for j in [i..Length(Bd)] do if i+j = deg then for m1 in Bd[i] do for m2 in Bd[j] do if o[m1[1].no] < o[m2[1].no] then
Add( rels, LRPrivateFunctions.dir_monmult( Fam, m1, m2 ) ); fi;
od;
od; fi;
od;
od;
# we add all monomials in the deg-th term of the lower central series # of the algebra that we got so far...
B:= [ ]; for i in [1..Length(Bd)] do Append( B, Bd[i] ); od;
d:= 1; while d < deg do
B0:= [ ]; for m in Bd[1] do for f in B do
Add( B0, get_rid_of_hdeg( LRPrivateFunctions.reduce_field( Fam,
LRPrivateFunctions.dir_mult( Fam, m, f ), G, lms ), nilquot ));
od;
od;
B0:= Filtered( B0, x -> not x = [ ] );
B:= LRPrivateFunctions.make_basis_field( Fam, B0 );
d:= d+1;
od;
Append( rels, B );
fi;
for r in R do if Degree(r) = deg then if is_nilquot then
f:= get_rid_of_hdeg( r![1], nilquot ); else
f:= r![1]; fi;
Add( rels, f ); fi;
od;
for i in [1..Length(rels)] do
f:= ShallowCopy( LRPrivateFunctions.reduce_field( Fam, rels[i], G, lms ) ); if f <> [ ] then
c:= f[Length(f)]; if not IsOne(c) thenfor j in [2,4..Length(f)] do f[j]:= f[j]/c; od; fi;
rels[i]:= f; else
Unbind( rels[i] ); fi;
od;
rels:= Filtered( rels, x -> IsBound(x) );
lowdeg:= not ForAll( rels, x -> x[ Length(x)-1 ].deg = deg );
lmsr:= LRPrivateFunctions.leading_mns( rels );
lmsposr:= [ ]; for i in [1..Length(lmsr)] do
lmsposr[ lmsr[i].no ]:= i; if lmsr[i].deg < deg then lowdeg:= true; fi;
od;
nonleadingr:= [ ]; for r in rels do for k in [1,3..Length(r)-3] do
AddSet( nonleadingr, r[k].no );
od;
od;
if deg >= 3then
a1:= Length(g);
a2:= Length(Bd);
for i in [1..a1] do
m1:= g[i]![1]; for u in [1..a2] do
v:= deg-m1[1].deg-u; if v > 0 and v <= a2 then
a3:= Length( Bd[u] );
a4:= Length( Bd[v] ); for j in [1..a3] do
m2:= Bd[u][j]; if o[m1[1].no] < o[m2[1].no] then for k in [1..a4] do
m3:= Bd[v][k]; if o[m2[1].no] < o[m3[1].no] then
if f <> [] then
lf:= Length(f);
c:= f[ lf ]; if not IsOne(c) thenfor i in [2,4..lf] do f[i]:= f[i]/c; od; fi;
if f[ Length(f)-1 ].no in nonleadingr then
rels:= LRPrivateFunctions.linalg_reduce_allbyone( Fam, f, rels ); fi;
Add( rels, f ); for r in [1,3..lf-3] do
AddSet( nonleadingr, f[r].no );
od;
m:= f[ lf -1 ];
lmsposr[ m.no ]:= Length( rels ); if m.deg < deg then lowdeg:= true; fi; fi; fi;
od; fi;
od; fi;
od;
od;
fi;
if is_hom then
Append( G, rels ); else if lowdeg then
SortParallel( lms, G, function( u,v) return u.no < v.no; end ); for i in [1..Length(rels)] do
r:= LRPrivateFunctions.addElm_RedSet_field( Fam, rels[i], G, lms );
G:= r[1]; lms:= r[2];
od; else
Append( G, rels ); fi; fi;
for i in [1..Length(G)] do
c:= G[i][ Length( G[i] ) ]; if not IsOne(c) then for j in [2,4..Length(G[i])] do G[i][j]:= G[i][j]/c; od; fi;
od;
lms:= LRPrivateFunctions.leading_mns( G );
lmspos:= [ ]; for i in [1..Length(lms)] do
lmspos[ lms[i].no ]:= i;
od;
newB:= [ ]; for f in g do
m:= f![1]; if m[1].deg = deg then if not IsBound( lmspos[m[1].no] ) then
Add( newB, m ); fi; fi;
od;
if deg > 1then
for u in [1..Length(Bd)] do
v:= deg-u; if v>=1 and v<=Length(Bd) then for i in [1..Length(Bd[u])] do
m1:= Bd[u][i]; for k in [1..Length( Bd[v] )] do
m2:= Bd[v][k]; if o[m1[1].no] < o[m2[1].no] then
m:= LRPrivateFunctions.dir_monmult( Fam, m1, m2 ); if not IsBound( lmspos[m[1].no] ) then
Add( newB, m ); fi; fi;
od;
od; fi;
od;
fi;
Add( Bd, newB );
# maybe throw away some old basis elements (only in non-hom case!) if not is_hom and lowdeg then for i in [1..Length(Bd)] do for j in [1..Length(Bd[i])] do
m:= Bd[i][j][1]; for k in [1..Length(lms)] do if LRPrivateFunctions.IsFactor_yn( lms[k], m ) then
Unbind( Bd[i][j] ); break; fi;
od;
od;
Bd[i]:= Filtered( Bd[i], x -> IsBound(x) );
od; fi;
Bk:= Bd[ Length( Bd ) ];
if Bk = [ ] and not diff_degree then
c:= 1; while Bd[c] <> [ ] do c:= c+1; od;
bound:= 2*c-1;
bound:= Maximum(bound,Maximum( List( R, x -> Degree(x) ) ) ); fi;
if is_hom and deg = nilquot then # we are done...
deg:= bound+1; else
deg:= deg+1; fi;
od;
B:= []; for i in [1..Length(Bd)] do Append( B, Bd[i] ); od;
basinds:= [ ]; for i in [1..Length(B)] do
basinds[ B[i][1].no ]:= i;
od;
for i in [1..Length(B)] do for j in [i+1..Length(B)] do if not( is_nilquot and B[i][1].deg + B[j][1].deg > nilquot ) then
eg:= LRPrivateFunctions.linalg_reduce_onemon( Fam,
LRPrivateFunctions.dir_monmult( Fam, B[i], B[j] ), G, lmspos );
cc:= [ ]; for k in [1,3..Length(eg)-1] do
Add( cc, eg[k+1] );
Add( cc, basinds[eg[k].no] );
od;
SetEntrySCTable( T, i, j, cc ); fi;
od;
od;
K:= LieAlgebraByStructureConstants( LeftActingDomain(A), T );
g:= [ ]; for i in GeneratorsOfAlgebra(A) do
eg:= LRPrivateFunctions.linalg_reduce_onemon( Fam, i![1], G, lmspos );
cf:= List( [1..Dimension(K)], x -> Zero( LeftActingDomain(K) ) ); for k in [1,3..Length(eg)-1] do
cf[basinds[eg[k].no]]:= eg[k+1];
od;
Add( g, cf*Basis(K) );
od;
SetGeneratorsImages( K, g );
hom:= function( elm )
local eval, e, len, res, i;
eval:= function( expr )
local a,b; if IsBound(expr.var) then
return g[ expr.var ]; else
a:= eval( expr.left );
b:= eval( expr.right );
return a*b; fi; end;
e:= elm![1];
len:= Length( e );
res:= Zero( K ); for i in [ 1, 3 .. len - 1 ] do
res:= res + e[i+1]*eval( e[i] );
od;
return res;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.