diff options
author | dos-reis <gdr@axiomatics.org> | 2007-08-14 05:14:52 +0000 |
---|---|---|
committer | dos-reis <gdr@axiomatics.org> | 2007-08-14 05:14:52 +0000 |
commit | ab8cc85adde879fb963c94d15675783f2cf4b183 (patch) | |
tree | c202482327f474583b750b2c45dedfc4e4312b1d /src/algebra/gpgcd.spad.pamphlet | |
download | open-axiom-ab8cc85adde879fb963c94d15675783f2cf4b183.tar.gz |
Initial population.
Diffstat (limited to 'src/algebra/gpgcd.spad.pamphlet')
-rw-r--r-- | src/algebra/gpgcd.spad.pamphlet | 691 |
1 files changed, 691 insertions, 0 deletions
diff --git a/src/algebra/gpgcd.spad.pamphlet b/src/algebra/gpgcd.spad.pamphlet new file mode 100644 index 00000000..bf758915 --- /dev/null +++ b/src/algebra/gpgcd.spad.pamphlet @@ -0,0 +1,691 @@ +\documentclass{article} +\usepackage{axiom} +\begin{document} +\title{\$SPAD/src/algebra gpgcd.spad} +\author{The Axiom Team} +\maketitle +\begin{abstract} +\end{abstract} +\eject +\tableofcontents +\eject +\section{package GENPGCD GeneralPolynomialGcdPackage} +<<package GENPGCD GeneralPolynomialGcdPackage>>= +)abbrev package GENPGCD GeneralPolynomialGcdPackage +++ Description: +++ This package provides operations for GCD computations +++ on polynomials +GeneralPolynomialGcdPackage(E,OV,R,P):C == T where + R : PolynomialFactorizationExplicit + P : PolynomialCategory(R,E,OV) + OV : OrderedSet + E : OrderedAbelianMonoidSup + + SUPP ==> SparseUnivariatePolynomial P +--JHD ContPrim ==> Record(cont:P,prim:P) + + C == with + gcdPolynomial : (SUPP,SUPP) -> SUPP + ++ gcdPolynomial(p,q) returns the GCD of p and q + randomR : () ->R + ++ randomR() should be local but conditional +--JHD gcd : (P,P) -> P +--JHD gcd : List P -> P +--JHD gcdprim : (P,P) -> P +--JHD gcdprim : List P -> P + +--JHD gcdcofact : List P -> List P +--JHD gcdcofactprim : List P -> List P + +--JHD primitate : (P,OV) -> P +--JHD primitate : SUPP -> SUPP + +--JHD content : P -> P +--JHD content : List P -> List P +--JHD contprim : List P -> List ContPrim + +--JHD monomContent : (P,OV) -> P +--JHD monomContent : SUPP -> SUPP + + + T == add + + SUPR ==> SparseUnivariatePolynomial R +--JHD SUPLGcd ==> Record(locgcd:SUPP,goodint:List R) +--JHD LGcd ==> Record(locgcd:P,goodint:List R) +--JHD UTerm ==> Record(lpol:List SUPR,lint:List R,mpol:P) +--JHD--JHD pmod:R := (prevPrime(2**26)$IntegerPrimesPackage(Integer))::R + +--JHD import MultivariateLifting(E,OV,R,P,pmod) + import UnivariatePolynomialCategoryFunctions2(R,SUPR,P,SUPP) + import UnivariatePolynomialCategoryFunctions2(P,SUPP,R,SUPR) + -------- Local Functions -------- + +--JHD abs : P -> P + better : (P,P) -> Boolean +--JHD failtest : (P,P,P) -> Boolean +--JHD gcdMonom : (P,P,OV) -> P +--JHD gcdTermList : (P,P) -> P +--JHD gcdPrim : (P,P,OV) -> P +--JHD gcdSameMainvar : (P,P,OV) -> P +--JHD internal : (P,P,OV) -> P +--JHD good : (P,List OV) -> Record(upol:SUPR,inval:List R) +--JHD gcdPrs : (P,P,NNI,OV) -> Union(P,"failed") +--JHD +--JHD chooseVal : (P,P,List OV) -> UTerm +--JHD localgcd : (P,P,List OV) -> LGcd +--JHD notCoprime : (P,P, List NNI,List OV) -> P +--JHD imposelc : (List SUPR,List OV,List R,List P) -> List SUPR + +--JHD lift? :(P,P,UTerm,List NNI,List OV) -> Union("failed",P) +-- lift :(P,SUPR,SUPR,P,List OV,List NNI,List R) -> P + lift : (SUPR,SUPP,SUPR,List OV,List R) -> Union(SUPP,"failed") + -- lifts first and third arguments as factors of the second + -- fourth is number of variables. +--JHD monomContent : (P,OV) -> P + monomContentSup : SUPP -> SUPP +-- +--JHD gcdcofact : List P -> List P + + gcdTrivial : (SUPP,SUPP) -> SUPP + gcdSameVariables: (SUPP,SUPP,List OV) -> SUPP + recursivelyGCDCoefficients: (SUPP,List OV,SUPP,List OV) -> SUPP + flatten : (SUPP,List OV) -> SUPP + -- evaluates out all variables in the second + -- argument, leaving a polynomial of the same + -- degree +-- eval : (SUPP,List OV,List R) -> SUPP + variables : SUPP -> List OV + ---- JHD's exported functions --- + gcdPolynomial(p1:SUPP,p2:SUPP) == + zero? p1 => p2 + zero? p2 => p1 + 0=degree p1 => gcdTrivial(p1,p2) + 0=degree p2 => gcdTrivial(p2,p1) + if degree p1 < degree p2 then (p1,p2):=(p2,p1) + p1 exquo p2 case SUPP => (unitNormal p2).canonical + c1:= monomContentSup(p1) + c2:= monomContentSup(p2) + p1:= (p1 exquo c1)::SUPP + p2:= (p2 exquo c2)::SUPP + (p1 exquo p2) case SUPP => (unitNormal p2).canonical * gcd(c1,c2) + vp1:=variables p1 + vp2:=variables p2 + v1:=setDifference(vp1,vp2) + v2:=setDifference(vp2,vp1) + #v1 = 0 and #v2 = 0 => gcdSameVariables(p1,p2,vp1)*gcd(c1,c2) + -- all variables are in common + v:=setDifference(vp1,v1) + pp1:=flatten(p1,v1) + pp2:=flatten(p2,v2) + g:=gcdSameVariables(pp1,pp2,v) +-- one? g => gcd(c1,c2)::SUPP + (g = 1) => gcd(c1,c2)::SUPP + (#v1 = 0 or not (p1 exquo g) case "failed") and + -- if #vi = 0 then pp1 = p1, so we know g divides + (#v2 = 0 or not (p2 exquo g) case "failed") + => g*gcd(c1,c2) -- divdes them both, so is the gcd + -- OK, so it's not the gcd: try again + v:=variables g -- there can be at most these variables in answer + v1:=setDifference(vp1,v) + v2:=setDifference(vp2,v) + if (#v1 = 0) then g:= gcdSameVariables(g,flatten(p2,v2),v) + else if (#v2=0) then g:=gcdSameVariables(g,flatten(p1,v1),v) + else g:=gcdSameVariables(g,flatten(p1,v1)-flatten(p2,v2),v) +-- one? g => gcd(c1,c2)::SUPP + (g = 1) => gcd(c1,c2)::SUPP + (#v1 = 0 or not (p1 exquo g) case "failed") and + (#v2 = 0 or not (p2 exquo g) case "failed") + => g*gcd(c1,c2)::SUPP -- divdes them both, so is the gcd + v:=variables g -- there can be at most these variables in answer + v1:=setDifference(vp1,v) + if #v1 ^= 0 then + g:=recursivelyGCDCoefficients(g,v,p1,v1) +-- one? g => return gcd(c1,c2)::SUPP + (g = 1) => return gcd(c1,c2)::SUPP + v:=variables g -- there can be at most these variables in answer + v2:=setDifference(vp2,v) + recursivelyGCDCoefficients(g,v,p2,v2)*gcd(c1,c2) + if R has StepThrough then + randomCount:R := init() + randomR() == + (v:=nextItem(randomCount)) case R => + randomCount:=v + v + SAY("Taking next stepthrough range in GeneralPolynomialGcdPackage")$Lisp + randomCount:=init() + randomCount + else + randomR() == (random$Integer() rem 100)::R + ---- JHD's local functions --- + gcdSameVariables(p1:SUPP,p2:SUPP,lv:List OV) == + -- two non-trivial primitive (or, at least, we don't care + -- about content) + -- polynomials with precisely the same degree + #lv = 0 => map(#1::P,gcdPolynomial(map(ground,p1), + map(ground,p2))) + degree p2 = 1 => + p1 exquo p2 case SUPP => p2 + 1 + gcdLC:=gcd(leadingCoefficient p1,leadingCoefficient p2) + lr:=[randomR() for vv in lv] + count:NonNegativeInteger:=0 + while count<10 repeat + while zero? eval(gcdLC,lv,lr) and count<10 repeat + lr:=[randomR() for vv in lv] + count:=count+1 + count = 10 => error "too many evaluations in GCD code" + up1:SUPR:=map(ground eval(#1,lv,lr),p1) + up2:SUPR:=map(ground eval(#1,lv,lr),p2) + u:=gcdPolynomial(up1,up2) + degree u = 0 => return 1 + -- let's pick a second one, just to check + lrr:=[randomR() for vv in lv] + while zero? eval(gcdLC,lv,lrr) and count<10 repeat + lrr:=[randomR() for vv in lv] + count:=count+1 + count = 10 => error "too many evaluations in GCD code" + vp1:SUPR:=map(ground eval(#1,lv,lrr),p1) + vp2:SUPR:=map(ground eval(#1,lv,lrr),p2) + v:=gcdPolynomial(vp1,vp2) + degree v = 0 => return 1 + if degree v < degree u then + u:=v + up1:=vp1 + up2:=vp2 + lr:=lrr + up1:=(up1 exquo u)::SUPR + degree gcd(u,up1) = 0 => + ans:=lift(u,p1,up1,lv,lr) + ans case SUPP => return ans + "next" + up2:=(up2 exquo u)::SUPR + degree gcd(u,up2) = 0 => + ans:=lift(u,p2,up2,lv,lr) + ans case SUPP => return ans + "next" + -- so neither cofactor is relatively prime + count:=0 + while count < 10 repeat + r:=randomR() + uu:=up1+r*up2 + degree gcd(u,uu)=0 => + ans:= lift(u,p1+r::P *p2,uu,lv,lr) + ans case SUPP => return ans + "next" + error "too many evaluations in GCD code" + count >= 10 => error "too many evaluations in GCD code" + lift(gR:SUPR,p:SUPP,cfR:SUPR,lv:List OV,lr:List R) == + -- lift the coprime factorisation gR*cfR = (univariate of p) + -- where the variables lv have been evaluated at lr + lcp:=leadingCoefficient p + g:=monomial(lcp,degree gR)+map(#1::P,reductum gR) + cf:=monomial(lcp,degree cfR)+map(#1::P,reductum cfR) + p:=lcp*p -- impose leaidng coefficient of p on each factor + while lv ^= [] repeat + v:=first lv + r:=first lr + lv:=rest lv + lr:=rest lr + thisp:=map(eval(#1,lv,lr),p) + d:="max"/[degree(c,v) for c in coefficients p] + prime:=v::P - r::P + pn:=prime + origFactors:=[g,cf]::List SUPP + for n in 1..d repeat + Ecart:=(thisp- g*cf) exquo pn + Ecart case "failed" => + error "failed lifting in hensel in Complex Polynomial GCD" + zero? Ecart => leave + step:=solveLinearPolynomialEquation(origFactors, + map(eval(#1,v,r),Ecart::SUPP)) + step case "failed" => return "failed" + g:=g+pn*first step + cf:=cf+pn*second step + pn:=pn*prime + thisp ^= g*cf => return "failed" + g + recursivelyGCDCoefficients(g:SUPP,v:List OV,p:SUPP,pv:List OV) == + mv:=first pv -- take each coefficient w.r.t. mv + pv:=rest pv -- and recurse on pv as necessary + d:="max"/[degree(u,mv) for u in coefficients p] + for i in 0..d repeat + p1:=map(coefficient(#1,mv,i),p) + oldg:=g + if pv = [] then g:=gcdSameVariables(g,p1,v) + else g:=recursivelyGCDCoefficients(p,v,p1,pv) +-- one? g => return 1 + (g = 1) => return 1 + g^=oldg => + oldv:=v + v:=variables g + pv:=setUnion(pv,setDifference(v,oldv)) + g + flatten(p1:SUPP,lv:List OV) == + #lv = 0 => p1 + lr:=[ randomR() for vv in lv] + dg:=degree p1 + while dg ^= degree (ans:= map(eval(#1,lv,lr),p1)) repeat + lr:=[ randomR() for vv in lv] + ans +-- eval(p1:SUPP,lv:List OV,lr:List R) == map(eval(#1,lv,lr),p1) + variables(p1:SUPP) == + removeDuplicates ("concat"/[variables u for u in coefficients p1]) + gcdTrivial(p1:SUPP,p2:SUPP) == + -- p1 is non-zero, but has degree zero + -- p2 is non-zero + cp1:=leadingCoefficient p1 +-- one? cp1 => 1 + (cp1 = 1) => 1 + degree p2 = 0 => gcd(cp1,leadingCoefficient p2)::SUPP + un?:=unit? cp1 + while not zero? p2 and not un? repeat + cp1:=gcd(leadingCoefficient p2,cp1) + un?:=unit? cp1 + p2:=reductum p2 + un? => 1 + cp1::SUPP + + ---- Local functions ---- +--JHD -- test if something wrong happened in the gcd +--JHD failtest(f:P,p1:P,p2:P) : Boolean == +--JHD (p1 exquo f) case "failed" or (p2 exquo f) case "failed" +--JHD +--JHD -- Choose the integers +--JHD chooseVal(p1:P,p2:P,lvar:List OV):UTerm == +--JHD x:OV:=lvar.first +--JHD lvr:=lvar.rest +--JHD d1:=degree(p1,x) +--JHD d2:=degree(p2,x) +--JHD dd:NNI:=0$NNI +--JHD nvr:NNI:=#lvr +--JHD lval:List R :=[] +--JHD range:I:=8 +--JHD for i in 1.. repeat +--JHD range:=2*range +--JHD lval:=[(random()$I rem (2*range) - range)::R for i in 1..nvr] +--JHD uf1:SUPR:=univariate eval(p1,lvr,lval) +--JHD degree uf1 ^= d1 => "new point" +--JHD uf2:SUPR:=univariate eval(p2,lvr,lval) +--JHD degree uf2 ^= d2 => "new point" +--JHD u:=gcd(uf1,uf2) +--JHD du:=degree u +--JHD --the univariate gcd is 1 +--JHD if du=0 then return [[1$SUPR],lval,0$P]$UTerm +--JHD +--JHD ugcd:List SUPR:=[u,(uf1 exquo u)::SUPR,(uf2 exquo u)::SUPR] +--JHD uterm:=[ugcd,lval,0$P]$UTerm +--JHD dd=0 => dd:=du +--JHD +--JHD --the degree is not changed +--JHD du=dd => +--JHD +--JHD --test if one of the polynomials is the gcd +--JHD dd=d1 => +--JHD if ^((f:=p2 exquo p1) case "failed") then +--JHD return [[u],lval,p1]$UTerm +--JHD if dd^=d2 then dd:=(dd-1)::NNI +--JHD +--JHD dd=d2 => +--JHD if ^((f:=p1 exquo p2) case "failed") then +--JHD return [[u],lval,p2]$UTerm +--JHD dd:=(dd-1)::NNI +--JHD return uterm +--JHD +--JHD --the new gcd has degree less +--JHD du<dd => dd:=du +--JHD +--JHD good(f:P,lvr:List OV):Record(upol:SUPR,inval:List R) == +--JHD nvr:NNI:=#lvr +--JHD range:I:=1 +--JHD ltry:List List R:=[] +--JHD while true repeat +--JHD range:=2*range +--JHD lval:=[(random()$I rem (2*range) -range)::R for i in 1..nvr] +--JHD member?(lval,ltry) => "new point" +--JHD ltry:=cons(lval,ltry) +--JHD uf:=univariate eval(f,lvr,lval) +--JHD if degree gcd(uf,differentiate uf)=0 then return [uf,lval] +--JHD +--JHD -- impose the right lc +--JHD imposelc(lipol:List SUPR, +--JHD lvar:List OV,lval:List R,leadc:List P):List SUPR == +--JHD result:List SUPR :=[] +--JHD lvar:=lvar.rest +--JHD for pol in lipol for leadpol in leadc repeat +--JHD p1:= univariate eval(leadpol,lvar,lval) * pol +--JHD result:= cons((p1 exquo leadingCoefficient pol)::SUPR,result) +--JHD reverse result +--JHD +--JHD --Compute the gcd between not coprime polynomials +--JHD notCoprime(g:P,p2:P,ldeg:List NNI,lvar:List OV) : P == +--JHD x:OV:=lvar.first +--JHD lvar1:List OV:=lvar.rest +--JHD lg1:=gcdcofact([g,differentiate(g,x)]) +--JHD g1:=lg1.1 +--JHD lg:LGcd:=localgcd(g1,p2,lvar) +--JHD (l,lval):=(lg.locgcd,lg.goodint) +--JHD p2:=(p2 exquo l)::P +--JHD (gd1,gd2):=(l,l) +--JHD ul:=univariate(eval(l,lvar1,lval)) +--JHD dl:=degree ul +--JHD if degree gcd(ul,differentiate ul) ^=0 then +--JHD newchoice:=good(l,lvar.rest) +--JHD ul:=newchoice.upol +--JHD lval:=newchoice.inval +--JHD ug1:=univariate(eval(g1,lvar1,lval)) +--JHD ulist:=[ug1,univariate eval(p2,lvar1,lval)] +--JHD lcpol:=[leadingCoefficient univariate(g1,x), +--JHD leadingCoefficient univariate(p2,x)] +--JHD while true repeat +--JHD d:SUPR:=gcd(cons(ul,ulist)) +--JHD if degree d =0 then return gd1 +--JHD lquo:=(ul exquo d)::SUPR +--JHD if degree lquo ^=0 then +--JHD lgcd:=gcd(cons(leadingCoefficient univariate(l,x),lcpol)) +--JHD gd2:=lift(l,d,lquo,lgcd,lvar,ldeg,lval) +--JHD l:=gd2 +--JHD ul:=univariate(eval(l,lvar1,lval)) +--JHD dl:=degree ul +--JHD gd1:=gd1*gd2 +--JHD ulist:=[(uf exquo d)::SUPR for uf in ulist] +--JHD +--JHD -- we suppose that the poly have the same mainvar, deg p1<deg p2 and the +--JHD -- polys primitive +--JHD internal(p1:P,p2:P,x:OV) : P == +--JHD lvar:List OV:=sort(#1>#2,setUnion(variables p1,variables p2)) +--JHD d1:=degree(p1,x) +--JHD d2:=degree(p2,x) +--JHD result: P:=localgcd(p1,p2,lvar).locgcd +--JHD -- special cases +--JHD result=1 => 1$P +--JHD (dr:=degree(result,x))=d1 or dr=d2 => result +--JHD while failtest(result,p1,p2) repeat +--JHD SAY$Lisp "retrying gcd" +--JHD result:=localgcd(p1,p2,lvar).locgcd +--JHD result +--JHD +--JHD --local function for the gcd : it returns the evaluation point too +--JHD localgcd(p1:P,p2:P,lvar:List(OV)) : LGcd == +--JHD x:OV:=lvar.first +--JHD uterm:=chooseVal(p1,p2,lvar) +--JHD listpol:= uterm.lpol +--JHD ud:=listpol.first +--JHD dd:= degree ud +--JHD +--JHD --the univariate gcd is 1 +--JHD dd=0 => [1$P,uterm.lint]$LGcd +--JHD +--JHD --one of the polynomials is the gcd +--JHD dd=degree(p1,x) or dd=degree(p2,x) => +--JHD [uterm.mpol,uterm.lint]$LGcd +--JHD ldeg:List NNI:=map(min,degree(p1,lvar),degree(p2,lvar)) +--JHD +--JHD -- if there is a polynomial g s.t. g/gcd and gcd are coprime ... +--JHD -- I can lift +--JHD (h:=lift?(p1,p2,uterm,ldeg,lvar)) case "failed" => +--JHD [notCoprime(p1,p2,ldeg,lvar),uterm.lint]$LGcd +--JHD [h::P,uterm.lint]$LGcd +--JHD +--JHD +--JHD -- content, internal functions return the poly if it is a monomial +--JHD monomContent(p:P,var:OV):P == +--JHD ground? p => 1$P +--JHD md:= minimumDegree(p,var) +--JHD ((var::P)**md)*(gcd sort(better,coefficients univariate(p,var))) + + monomContentSup(u:SUPP):SUPP == + degree(u) = 0$NonNegativeInteger => 1$SUPP + md:= minimumDegree u + gcd(sort(better,coefficients u)) * monomial(1$P,md)$SUPP + +--JHD -- change the polynomials to have positive lc +--JHD abs(p:P): P == unitNormal(p).canonical + + -- Ordering for gcd purposes + better(p1:P,p2:P):Boolean == + ground? p1 => true + ground? p2 => false + degree(p1,mainVariable(p1)::OV) < degree(p2,mainVariable(p2)::OV) + + -- PRS algorithm + -- gcdPrs(p1:P,p2:P,d:NNI,var:OV):Union(P,"failed") == + -- u1:= univariate(p1,var) + -- u2:= univariate(p2,var) + -- finished:Boolean:= false + -- until finished repeat + -- dd:NNI:=(degree u1 - degree u2)::NNI + -- lc1:SUPP:=leadingCoefficient u2 * reductum u1 + -- lc2:SUPP:=leadingCoefficient u1 * reductum u2 + -- u3:SUPP:= primitate((lc1-lc2)*monomial(1$P,dd))$% + -- (d3:=degree(u3)) <= d => finished:= true + -- u1:= u2 + -- u2:= u3 + -- if d3 > degree(u1) then (u1,u2):= (u2,u1) + -- g:= (u2 exquo u3) + -- g case SUPP => abs multivariate(u3,var) + -- "failed" + + -- Gcd between polynomial p1 and p2 with + -- mainVariable p1 < x=mainVariable p2 +--JHD gcdTermList(p1:P,p2:P) : P == +--JHD termList:=sort(better, +--JHD cons(p1,coefficients univariate(p2,(mainVariable p2)::OV))) +--JHD q:P:=termList.first +--JHD for term in termList.rest until q = 1$P repeat q:= gcd(q,term) +--JHD q +--JHD +--JHD -- Gcd between polynomials with the same mainVariable +--JHD gcdSameMainvar(p1:P,p2:P,mvar:OV): P == +--JHD if degree(p1,mvar) < degree(p2,mvar) then (p1,p2):= (p2,p1) +--JHD (p1 exquo p2) case P => abs p2 +--JHD c1:= monomContent(p1,mvar)$% +--JHD c1 = p1 => gcdMonom(p1,p2,mvar) +--JHD c2:= monomContent(p2,mvar)$% +--JHD c2 = p2 => gcdMonom(p2,p1,mvar) +--JHD p1:= (p1 exquo c1)::P +--JHD p2:= (p2 exquo c2)::P +--JHD if degree(p1,mvar) < degree(p2,mvar) then (p1,p2):= (p2,p1) +--JHD (p1 exquo p2) case P => abs(p2) * gcd(c1,c2) +--JHD abs(gcdPrim(p1,p2,mvar)) * gcd(c1,c2) +--JHD +--JHD -- make the polynomial primitive with respect to var +--JHD primitate(p:P,var:OV):P == (p exquo monomContent(p,var))::P +--JHD +--JHD primitate(u:SUPP):SUPP == (u exquo monomContentSup u)::SUPP +--JHD +--JHD -- gcd between primitive polynomials with the same mainVariable +--JHD gcdPrim(p1:P,p2:P,mvar:OV):P == +--JHD vars:= removeDuplicates append(variables p1,variables p2) +--JHD #vars=1 => multivariate(gcd(univariate p1,univariate p2),mvar) +--JHD vars:=delete(vars,position(mvar,vars)) +--JHD --d:= degModGcd(p1,p2,mvar,vars) +--JHD --d case "failed" => internal(p2,p1,mvar) +--JHD --deg:= d:NNI +--JHD --deg = 0$NNI => 1$P +--JHD --deg = degree(p1,mvar) => +--JHD -- (p2 exquo p1) case P => abs(p1) -- already know that +--JHD -- ^(p1 exquo p2) +--JHD -- internal(p2,p1,mvar) +--JHD --cheapPrs?(p1,p2,deg,mvar) => +--JHD -- g:= gcdPrs(p1,p2,deg,mvar) +--JHD -- g case P => g::P +--JHD -- internal(p2,p1,mvar) +--JHD internal(p2,p1,mvar) +--JHD +--JHD -- gcd between a monomial and a polynomial +--JHD gcdMonom(m:P,p:P,var:OV):P == +--JHD ((var::P) ** min(minimumDegree(m,var),minimumDegree(p,var))) * +--JHD gcdTermList(leadingCoefficient(univariate(m,var)),p) +--JHD +--JHD --If there is a pol s.t. pol/gcd and gcd are coprime I can lift +--JHD lift?(p1:P,p2:P,uterm:UTerm,ldeg:List NNI, +--JHD lvar:List OV) : Union("failed",P) == +--JHD x:OV:=lvar.first +--JHD leadpol:Boolean:=false +--JHD (listpol,lval):=(uterm.lpol,uterm.lint) +--JHD d:=listpol.first +--JHD listpol:=listpol.rest +--JHD nolift:Boolean:=true +--JHD for uf in listpol repeat +--JHD --note uf and d not necessarily primitive +--JHD degree gcd(uf,d) =0 => nolift:=false +--JHD nolift => "failed" +--JHD f:P:=([p1,p2]$List(P)).(position(uf,listpol)) +--JHD lgcd:=gcd(leadingCoefficient univariate(p1,x), +--JHD leadingCoefficient univariate(p2,x)) +--JHD lift(f,d,uf,lgcd,lvar,ldeg,lval) +--JHD +--JHD -- interface with the general "lifting" function +--JHD lift(f:P,d:SUPR,uf:SUPR,lgcd:P,lvar:List OV, +--JHD ldeg:List NNI,lval:List R):P == +--JHD x:OV:=lvar.first +--JHD leadpol:Boolean:=false +--JHD lcf:P +--JHD lcf:=leadingCoefficient univariate(f,x) +--JHD df:=degree(f,x) +--JHD leadlist:List(P):=[] +--JHD +--JHD if lgcd^=1$P then +--JHD leadpol:=true +--JHD f:=lgcd*f +--JHD ldeg:=[n0+n1 for n0 in ldeg for n1 in degree(lgcd,lvar)] +--JHD lcd:R:=leadingCoefficient d +--JHD if ground? lgcd then d:=((retract lgcd) *d exquo lcd)::SUPR +--JHD else d:=(retract(eval(lgcd,lvar.rest,lval)) * d exquo lcd)::SUPR +--JHD uf:=lcd*uf +--JHD leadlist:=[lgcd,lcf] +--JHD lg:=imposelc([d,uf],lvar,lval,leadlist) +--JHD plist:=lifting(univariate(f,x),lvar,lg,lval,leadlist,ldeg)::List P +--JHD (p0:P,p1:P):=(plist.first,plist.2) +--JHD if univariate eval(p0,rest lvar,lval) ^= lg.first then +--JHD (p0,p1):=(p1,p0) +--JHD ^leadpol => p0 +--JHD cprim:=contprim([p0]) +--JHD cprim.first.prim +--JHD +--JHD -- Gcd for two multivariate polynomials +--JHD gcd(p1:P,p2:P) : P == +--JHD (p1:= abs(p1)) = (p2:= abs(p2)) => p1 +--JHD ground? p1 => +--JHD p1 = 1$P => p1 +--JHD p1 = 0$P => p2 +--JHD ground? p2 => gcd((retract p1)@R,(retract p2)@R)::P +--JHD gcdTermList(p1,p2) +--JHD ground? p2 => +--JHD p2 = 1$P => p2 +--JHD p2 = 0$P => p1 +--JHD gcdTermList(p2,p1) +--JHD mv1:= mainVariable(p1)::OV +--JHD mv2:= mainVariable(p2)::OV +--JHD mv1 = mv2 => gcdSameMainvar(p1,p2,mv1) +--JHD mv1 < mv2 => gcdTermList(p1,p2) +--JHD gcdTermList(p2,p1) +--JHD +--JHD -- Gcd for a list of multivariate polynomials +--JHD gcd(listp:List P) : P == +--JHD lf:=sort(better,listp) +--JHD f:=lf.first +--JHD for g in lf.rest repeat +--JHD f:=gcd(f,g) +--JHD if f=1$P then return f +--JHD f +--JHD -- Gcd and cofactors for a list of polynomials +--JHD gcdcofact(listp : List P) : List P == +--JHD h:=gcd listp +--JHD cons(h,[(f exquo h) :: P for f in listp]) +--JHD +--JHD -- Gcd for primitive polynomials +--JHD gcdprim(p1:P,p2:P):P == +--JHD (p1:= abs(p1)) = (p2:= abs(p2)) => p1 +--JHD ground? p1 => +--JHD ground? p2 => gcd((retract p1)@R,(retract p2)@R)::P +--JHD p1 = 0$P => p2 +--JHD 1$P +--JHD ground? p2 => +--JHD p2 = 0$P => p1 +--JHD 1$P +--JHD mv1:= mainVariable(p1)::OV +--JHD mv2:= mainVariable(p2)::OV +--JHD mv1 = mv2 => +--JHD md:=min(minimumDegree(p1,mv1),minimumDegree(p2,mv1)) +--JHD mp:=1$P +--JHD if md>1 then +--JHD mp:=(mv1::P)**md +--JHD p1:=(p1 exquo mp)::P +--JHD p2:=(p2 exquo mp)::P +--JHD mp*gcdPrim(p1,p2,mv1) +--JHD 1$P +--JHD +--JHD -- Gcd for a list of primitive multivariate polynomials +--JHD gcdprim(listp:List P) : P == +--JHD lf:=sort(better,listp) +--JHD f:=lf.first +--JHD for g in lf.rest repeat +--JHD f:=gcdprim(f,g) +--JHD if f=1$P then return f +--JHD f +--JHD -- Gcd and cofactors for a list of primitive polynomials +--JHD gcdcofactprim(listp : List P) : List P == +--JHD h:=gcdprim listp +--JHD cons(h,[(f exquo h) :: P for f in listp]) +--JHD +--JHD -- content of a polynomial (with respect to its main var) +--JHD content(f:P):P == +--JHD ground? f => f +--JHD x:OV:=(mainVariable f)::OV +--JHD gcd sort(better,coefficients univariate(f,x)) +--JHD +--JHD -- contents of a list of polynomials +--JHD content(listf:List P) : List P == [content f for f in listf] +--JHD +--JHD -- contents and primitive parts of a list of polynomials +--JHD contprim(listf:List P) : List ContPrim == +--JHD prelim :List P := content listf +--JHD [[q,(f exquo q)::P]$ContPrim for q in prelim for f in listf] +--JHD + +@ +\section{License} +<<license>>= +--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +--All rights reserved. +-- +--Redistribution and use in source and binary forms, with or without +--modification, are permitted provided that the following conditions are +--met: +-- +-- - Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- - Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in +-- the documentation and/or other materials provided with the +-- distribution. +-- +-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the +-- names of its contributors may be used to endorse or promote products +-- derived from this software without specific prior written permission. +-- +--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +@ +<<*>>= +<<license>> + +<<package GENPGCD GeneralPolynomialGcdPackage>> +@ +\eject +\begin{thebibliography}{99} +\bibitem{1} nothing +\end{thebibliography} +\end{document} |