diff --git a/lib/clashom.gi b/lib/clashom.gi index 8c7da2f28c..7015e26e3d 100644 --- a/lib/clashom.gi +++ b/lib/clashom.gi @@ -2938,7 +2938,10 @@ local r, #radical select:=[1..Length(reps)]; while Length(select)>0 do pos:=select[1]; - sel:=Filtered(select,x->reps[x][3]=reps[pos][3]); + # same reps, same gens + sel:=Filtered(select,x->reps[x][3]=reps[pos][3] and + reps[x][5]=reps[pos][5] and reps[x][6]=reps[pos][6]); + if ValueOption("conjugacytest")=true and Length(sel)<>2 then return fail; fi; @@ -3085,3 +3088,113 @@ function(G) if IsPermGroup(G) or IsPcGroup(G) then TryNextMethod();fi; return ConjugacyClassesViaRadical(G); end); + + +############################################################################# +## +#F TFClassMatrixColumn(,,,) . calculate the t-th column +#F of the r-th class matrix and store it in the appropriate column of M +## +BindGlobal("TFClassMatrixColumn",function(D,M,r,t) + local c,gt,s,z,i,T,w,e,j,p,orb,collect,found,id; + if t=1 then + M[D.inversemap[r],t]:=D.classiz[r]; + else + orb:=DxGaloisOrbits(D,r); + z:=D.classreps[t]; + c:=orb.orbits[t][1]; + if c<>t then + p:=RepresentativeAction(Stabilizer(orb.group,r),c,t); + if p<>fail then + # was the first column of the galois class active? + if ForAny([1..NrRows(M)],i->M[i,c]>0) then + for i in D.classrange do + M[i^p,t]:=M[i,c]; + od; + Info(InfoCharacterTable,2,"Computing column ",t, + " : by GaloisImage"); + return; + fi; + fi; + fi; + + T:=DoubleCentralizerOrbit(D,r,t); + Info(InfoCharacterTable,2,"Computing column ",t," :", + Length(T[1])," instead of ",D.classiz[r]); + + if IsDxLargeGroup(D.group) then + # if r and t are unique,the conjugation test can be weak (i.e. up to + # galois automorphisms) + w:=Length(orb.orbits[t])=1 and Length(orb.orbits[r])=1; + collect:=[]; + for i in [1..Length(T[1])] do + e:=T[1][i]*z; + Unbind(T[1][i]); + found:=false; + if w then + c:=D.rationalidentification(D,e); + if c in orb.uniqueIdentifications then + s:=orb.orbits[ + First([1..D.klanz],j->D.rids[j]=c)][1]; + M[s,t]:=M[s,t]+T[2][i]; + found:=true; + fi; + fi; + if not found then + id:=D.cheapIdentification(D,e); + s:=Filtered([1..D.klanz],i->D.chids[i]=id); + if Length(s)=1 then + s:=s[1]; + M[s,t]:=M[s,t]+T[2][i]; + else + # only strong test possible + Add(collect,[e,First(D.faclaimg,y->y[1]=id)[2],T[2][i]]); + #s:=D.ClassElement(D,e); + #M[s,t]:=M[s,t]+T[2][i]; + fi; + fi; + od; + #Print(Length(collect)," collected\n"); + if Length(collect)=1 then + s:=D.ClassElement(D,collect[1][1]); + M[s,t]:=M[s,t]+collect[1][3]; + else + for id in Set(List(collect,x->x[2])) do + found:=Filtered(collect,x->x[2]=id); + s:=TFCanonicalClassRepresentative(D.group, + List(found,x->x[1]):candidatenums:=id); + s:=List(s,x->x[2]); + s:=List(s,x->First(id,y->D.canreps[y]=x)); + for i in [1..Length(s)] do + M[s[i],t]:=M[s[i],t]+found[i][3]; + od; + + od; + fi; + + if w then # weak discrimination possible ? + gt:=Set(Filtered(orb.orbits,i->Length(i)>1)); + for i in gt do + if i[1] in orb.identifees then + # were these classes detected weakly ? + e:=M[i[1],t]; + if e>0 then + Info(InfoCharacterTable,3,"GaloisIdentification ",i,": ",e); + fi; + for j in i do + M[j,t]:=e/Length(i); + od; + fi; + od; + fi; + else # Small Group + for i in [1..Length(T[1])] do + s:=D.ClassElement(D,T[1][i] * z); + Unbind(T[1][i]); + M[s,t]:=M[s,t]+T[2][i]; + od; + fi; + fi; +end); + + diff --git a/lib/ctblgrp.gd b/lib/ctblgrp.gd index 8d62353a3b..c57c226fb4 100644 --- a/lib/ctblgrp.gd +++ b/lib/ctblgrp.gd @@ -103,6 +103,8 @@ DeclareGlobalFunction( "IsDxLargeGroup" ); DeclareGlobalFunction("DxModularValuePol"); DeclareGlobalFunction("DxDegreeCandidates"); +DeclareGlobalFunction("DxGaloisOrbits"); +DeclareGlobalFunction("DoubleCentralizerOrbit"); ############################################################################# ## diff --git a/lib/ctblgrp.gi b/lib/ctblgrp.gi index 8c34c23413..a12a77c085 100644 --- a/lib/ctblgrp.gi +++ b/lib/ctblgrp.gi @@ -1266,7 +1266,7 @@ end ); ## #F DxGaloisOrbits(,) . orbits of Stab_Gal(f) when acting on the classes ## -BindGlobal( "DxGaloisOrbits", function(D,f) +InstallGlobalFunction(DxGaloisOrbits,function(D,f) local i,k,l,u,ga,galOp,p; k:=D.klanz; if not IsBound(D.galOp[f]) then @@ -1298,8 +1298,7 @@ local i,k,l,u,ga,galOp,p; fi; fi; return D.galOp[f]; -end ); - +end); ############################################################################# ## @@ -1692,7 +1691,7 @@ end ); ## whenever they might become bigger using double cosets of the ## centralizers. ## -BindGlobal("DoubleCentralizerOrbit",function(D,c1,c2) +InstallGlobalFunction(DoubleCentralizerOrbit,function(D,c1,c2) local often,trans,e,neu,i,inv,cent,l,s,s1,x,dom; inv:=D.inversemap[c1]; s1:=D.classiz[c1]; diff --git a/lib/ctblperm.gi b/lib/ctblperm.gi index 75bf18d921..7f9e6594d7 100644 --- a/lib/ctblperm.gi +++ b/lib/ctblperm.gi @@ -38,7 +38,7 @@ end ); ## The class invariant consists of the cycle structure and - if computation ## might improve results - of the Fingerprint of the permutation ## -BindGlobal( "IdentificationPermGroup", function(D,el) +BindGlobal("CheapIdentificationPermGroup",function(D,el) local s,t,i,l; # guter Programmier s t i l ! s:=CycleStructurePerm(el); s:=ShallowCopy(s); @@ -58,13 +58,19 @@ BindGlobal( "IdentificationPermGroup", function(D,el) Add(s,-FingerprintPerm(D,el,D.p1,D.p2,D.fingerprintOrbitStabilizer, D.fingerprintRepresentatives)); fi; + return s; +end); + +BindGlobal("IdentificationPermGroup",function(D,el) +local s,l; + s:=CheapIdentificationPermGroup(D,el); if IsBound(D.usefitfree) and not s in D.nocanonize then l:=First(D.faclaimg,x->x[1]=s); l:=TFCanonicalClassRepresentative(D.group,[el]:candidatenums:=l[2]); Add(s,l[1][2]); fi; return s; -end ); +end); ############################################################################# @@ -93,6 +99,7 @@ local k,structures,ambiguousStructures,i,j,p,cem,ces,z,t,cen,a, c,s,f,fc,fs,fos,fr,enum; D.identification:=IdentificationPermGroup; + D.cheapIdentification:=CheapIdentificationPermGroup; D.rationalidentification:=RationalIdentificationPermGroup; D.ClassMatrixColumn:=StandardClassMatrixColumn; @@ -213,16 +220,22 @@ local k,structures,ambiguousStructures,i,j,p,cem,ces,z,t,cen,a, fi; D.ids:=[]; + D.chids:=[]; D.rids:=[]; + D.canreps:=[]; for i in [1..D.klanz] do D.ids[i]:=D.identification(D,D.classreps[i]); + D.chids[i]:=D.cheapIdentification(D,D.classreps[i]); D.rids[i]:= - D.rationalidentification(D,D.classreps[i]); + D.rationalidentification(D,D.classreps[i]); + D.canreps[i]:= + TFCanonicalClassRepresentative(D.group,[D.classreps[i]])[1][2]; od; # use canonical reps? if Size(SolvableRadical(D.group))>1 then D.usefitfree:=true; + D.ClassMatrixColumn:=TFClassMatrixColumn; D.nocanonize:=[]; D.faclaimg:=[]; fs:=List(D.ids,ShallowCopy); @@ -232,8 +245,7 @@ local k,structures,ambiguousStructures,i,j,p,cem,ces,z,t,cen,a, Add(D.nocanonize,fs[i]); else Add(D.faclaimg,[fs[i],f]); # store which classes images could be - f:=TFCanonicalClassRepresentative(D.group,[D.classreps[i]]); - Add(D.ids[i],f[1][2]); + Add(D.ids[i],D.canreps[i]); fi; od; fi; diff --git a/lib/fitfree.gi b/lib/fitfree.gi index 7b6ce7b7ea..23e96fb7cb 100644 --- a/lib/fitfree.gi +++ b/lib/fitfree.gi @@ -1558,4 +1558,3 @@ local ff,i,j,c,q,a,b,prev,sub,m,k; return c; end); -