diff --git a/doc/ref/algfld.xml b/doc/ref/algfld.xml index 3df63aec9e..69c5ca6693 100644 --- a/doc/ref/algfld.xml +++ b/doc/ref/algfld.xml @@ -95,6 +95,15 @@ gap> m^2; <#Include Label="IsAlgebraicElement"> + + + + +
+Finding Subfields + +<#Include Label="IdealDecompositionsOfPolynomial"> +
diff --git a/doc/ref/groups.xml b/doc/ref/groups.xml index 648d59ef5c..61106f32fb 100644 --- a/doc/ref/groups.xml +++ b/doc/ref/groups.xml @@ -587,7 +587,6 @@ see . -
Tests for the Availability of Methods @@ -601,6 +600,14 @@ see . <#Include Label="CanComputeIsSubset"> <#Include Label="KnowsHowToDecompose"> +
+ + +
+Specific functions for Normalizer calculation + +<#Include Label="NormalizerViaRadical"> +
diff --git a/lib/algfld.gd b/lib/algfld.gd index 7c50c7facb..366843adf5 100644 --- a/lib/algfld.gd +++ b/lib/algfld.gd @@ -188,3 +188,45 @@ DeclareGlobalFunction("AlgExtEmbeddedPol"); DeclareGlobalFunction("AlgExtSquareHensel"); +############################################################################# +## +#F IdealDecompositionsOfPolynomial( [:"onlyone"] ) finds ideal decompositions of rational f +## +## <#GAPDoc Label="IdealDecompositionsOfPolynomial"> +## +## +## +## +## Let f be a univariate, rational, irreducible, polynomial. A +## pair g,h of polynomials of degree strictly +## smaller than that of f, such that f(x)|g(h(x)) is +## called an ideal decomposition. In the context of field +## extensions, if \alpha is a root of f in a suitable extension +## and Q the field of rational numbers. Such decompositions correspond +## to (proper) subfields Q\lt Q(\beta)\lt Q(\alpha), where g is the +## minimal polynomial of \beta. +## This function determines such decompositions up to equality of the subfields +## Q(\beta), thus determining subfields of a given algebraic extension. +## It returns a list of pairs [g,h] (and an empty list if no such +## decomposition exists). If the option onlyone is given it returns at +## most one such decomposition (and performs faster). +## x:=X(Rationals,"x");;pol:=x^8-24*x^6+144*x^4-288*x^2+144;; +## gap> l:=IdealDecompositionsOfPolynomial(pol); +## [ [ x^2+72*x+144, x^6-20*x^4+60*x^2-36 ], +## [ x^2-48*x+144, x^6-21*x^4+84*x^2-48 ], +## [ x^2+288*x+17280, x^6-24*x^4+132*x^2-288 ], +## [ x^4-24*x^3+144*x^2-288*x+144, x^2 ] ] +## gap> List(l,x->Value(x[1],x[2])/pol); +## [ x^4-16*x^2-8, x^4-18*x^2+33, x^4-24*x^2+120, 1 ] +## gap> IdealDecompositionsOfPolynomial(pol:onlyone); +## [ [ x^2+72*x+144, x^6-20*x^4+60*x^2-36 ] ] +## ]]> +## In this example the given polynomial is regular with Galois group +## Q_8, as expected we get four proper subfields. +## +## +## <#/GAPDoc> +## +DeclareGlobalFunction("IdealDecompositionsOfPolynomial"); +DeclareSynonym("DecomPoly",IdealDecompositionsOfPolynomial); diff --git a/lib/algfld.gi b/lib/algfld.gi index 9cf4f5a8bc..25a398c86e 100644 --- a/lib/algfld.gi +++ b/lib/algfld.gi @@ -172,7 +172,8 @@ if Length(extra)>0 and IsString(extra[1]) then SetCharacteristic(fam,Characteristic(f)); fam!.indeterminateName:=nam; colf:=CollectionsFamily(fam); - e:=Objectify(NewType(colf,IsAlgebraicExtensionDefaultRep), + e:=Objectify(NewType(colf, + IsAlgebraicExtensionDefaultRep and IsAlgebraicExtension), rec()); fam!.wholeField:=e; @@ -2193,13 +2194,14 @@ end); ############################################################################# ## -#F DecomPoly( [,"all"] ) finds (all) ideal decompositions of rational f +#F IdealDecompositionsOfPolynomial( [,"onlyone"] ) finds ideal decompositions of rational f ## This is equivalent to finding subfields of K(alpha). ## -DecomPoly := function(arg) -local f,n,e,ff,p,ffp,ffd,roots,allroots,nowroots,fm,fft,comb,combi,k,h,i,j, - gut,avoid,blocks,g,m,decom,z,R,scale,allowed,hp,hpc,a,kfam; - f:=arg[1]; +InstallGlobalFunction(IdealDecompositionsOfPolynomial,function(f) +local n,e,ff,p,ffp,ffd,roots,allroots,nowroots,fm,fft,comb,combi,k,h,i,j, + gut,avoid,blocks,g,m,decom,z,R,scale,allowed,hp,hpc,a,kfam,only; + + only:=ValueOption("onlyone")=true; n:=DegreeOfUnivariateLaurentPolynomial(f); if IsPrime(n) then return []; @@ -2255,9 +2257,9 @@ local f,n,e,ff,p,ffp,ffd,roots,allroots,nowroots,fm,fft,comb,combi,k,h,i,j, fft:=ff{combi}; ffp:=List(fft,i->AlgebraicPolynomialModP(kfam,i,fm[1],p)); roots:=Filtered(fm,i->ForAny(ffp,j->Value(j,i)=Zero(k))); - if Length(roots)<>Sum(ffd{combi}) then - Error("serious error"); - fi; + if Length(roots)<>Sum(ffd{combi}) then + Error("serious error"); + fi; allroots:=Union(roots,[fm[1]]); gut:=true; j:=1; @@ -2270,9 +2272,7 @@ local f,n,e,ff,p,ffp,ffd,roots,allroots,nowroots,fm,fft,comb,combi,k,h,i,j, if gut then Info(InfoPoly,2,"block found"); Add(blocks,combi); - if Length(arg)>1 then - gut:=false; - fi; + if only<>true then gut:=false; fi; fi; h:=h+1; od; @@ -2328,15 +2328,12 @@ local f,n,e,ff,p,ffp,ffd,roots,allroots,nowroots,fm,fft,comb,combi,k,h,i,j, #h:=Value(h,X(Rationals)*z); Add(decom,[g,h]); od; - if Length(arg)=1 then - decom:=decom[1]; - fi; return decom; else Info(InfoPoly,2,"primitive"); return []; fi; -end; +end); ############################################################################# ## diff --git a/lib/grp.gd b/lib/grp.gd index 602778f3f2..d54a47c0fb 100644 --- a/lib/grp.gd +++ b/lib/grp.gd @@ -4528,6 +4528,38 @@ DeclareGlobalFunction("GroupEnumeratorByClosure"); DeclareOperation( "LowIndexSubgroups", [ IsGroup, IsPosInt ] ); +############################################################################# +## +#F NormalizerViaRadical(,) +## +## <#GAPDoc Label="NormalizerViaRadical"> +## +## +## +## +## This function implements a particular approach, following the +## SolvableRadical paradigm, for calculating the +## normalizer of a subgroup S in G. It is at the moment +## provided only as a separate function, and not as method for the operation +## Normalizer, as it can often be slower than other built-in routines. +## In certain hard cases (non-solvable groups with nontrivial radical), however +## its performance is substantially superior. +## The function thus is provided as a +## non-automated tool for advanced users. +## g:=TransitiveGroup(30,2030);; +## gap> s:=SylowSubgroup(g,5);; +## gap> Size(NormalizerViaRadical(g,s)); +## 28800 +## ]]> +## Note that this example only demonstrates usage, but that in this case +## in fact the ordinary Normalizer routine performs faster. +## +## +## <#/GAPDoc> +## +DeclareGlobalFunction("NormalizerViaRadical"); + ############################################################################# ## #E diff --git a/lib/norad.gi b/lib/norad.gi index 4181ed421a..e7acb6b247 100644 --- a/lib/norad.gi +++ b/lib/norad.gi @@ -378,7 +378,7 @@ local expandvec,bassrc,basimg,transl,getbasimg,gettransl,myact2; end); # main normalizer routine -BindGlobal("NormalizerViaRadical",function(G,U) +InstallGlobalFunction(NormalizerViaRadical,function(G,U) local sus,ser,len,factorhom,uf,n,d,up,mran,nran,mpcgs,pcgs,pcisom,nf,ng,np,sub, central,f,ngm,npm,no2pcgs,part,stb,mods,famo,part0,nopcgs,uff,ufg,prev, famo2,ufr,dims,vecs,ovecs,vecsz,l,prop,properties,clusters,clusterspaces,