gbasem.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
--
-- This code is distributed freely in the sence of
-- GPL(GNU General Public License).
--
-- reduced Groebner base for ideal in K[x,y,z,...]
-- K=Rational, Z/pZ, Complex, Float
-- Use as: glist:=GBase.getGBase([f1,f2,f3,...])
-- Use as: glist:=GBase.getGBaseZp(prime,[f1,f2,f3,...])
-- reduced minimal strong Groebner base for ideal in Z[x,y,z,...]
-- Use as: glist:=getGBaseI([f1,f2,f3,...])
--
-- getGBase(plist)
-- plist be Array of Polynomial
-- return Array of Polynomial of Reduced Grobner base
-- over field Rational, Complex, Float
-- getGBaseZp(plist,prime)
-- get Groebner basis on Zp.
--
-- K.Kodama 2001-01-26 Sather version
-- K.Kodama 2000-02-01 Ruby first version
--
class GBASE_RAT
class GBASE_RAT is
include GBASE{POLYM_RAT};
end;
class GBASE_FLTD
class GBASE_FLTD is
include GBASE{POLYM_FLTD};
end;
class GBASE_ZP
class GBASE_ZP is
include GBASE{POLYM_INTI};
include GBASE_ZP_ALG{POLYM_INTI};
-- Use as blist:=GBASE_ZP::getGBaseZp(prime, [f1,f2,f3,...]);
end;
class GBASE_INTI_L
class GBASE_INTI_L is
-- reduced minimal strong Groebner base for ideal in Z<x,y,z,...>
-- Grobner basis in Laulent polynomial ring Z<x,y,..>.
-- Use as: glist:=GBASE_INTI_L::getGBaseIL([f1,f2,f3,...])
-- K.Kodama 2001-12-17
getGBaseIL(fList:ARRAY{POLYM_INTI}):ARRAY{POLYM_INTI} is
gbase:ARRAY{POLYM_INTI}:=#;
loop fi::=fList.elt!.normalize;
if fi.is_zero.not then gbase:=gbase.append(|fi|); end;
end;
if gbase.size=0 then return (#); end;
fa::=POLYM_INTI::one;
loop fa:=fa+gbase.elt!.coeff_to_one; end;
vTbl::=fa.vars; vlTbl:ARRAY{STR}:=#;
loop
v::=vTbl.elt!; vl::="(1/"+v+")"; vlTbl:=vlTbl.append(|vl|);
gbase:=gbase.append(|#POLYM_INTI(v)*#POLYM_INTI(vl)-1|);
end;
-- set var order
VARNAME::setVarOrder(vlTbl.append(vTbl));
--#OUT+"var_order: "+VARNAME::getVarOrder.str+"\n";
to0:STR:=MONOMIAL{INTI}::getTermOrder;
MONOMIAL{INTI}::setTermOrder("lex");
gbase:=GBASE_INTI::getGBaseI(gbase);
MONOMIAL{INTI}::setTermOrder(to0);
return gbase;
end;
end;
class GBASE_INTI
class GBASE_INTI is
-- reduced minimal strong Groebner base for ideal in Z[x,y,z,...]
-- Grobner basis in Z[x,y,..].
-- Use as: glist:=GBASE_INTI::getGBaseI([f1,f2,f3,...])
-- K.Kodama 2000-02-04 Ruby first version
--
-- This module is distributed freely in the sence of
-- GPL(GNU General Public License).
include GBASE{POLYM_INTI};
include GBASE_INTI_ALG{POLYM_INTI,INTI};
end;
partial class GBASE_ZP_ALG{POLY}
partial class GBASE_ZP_ALG{POLY} is
makeGBaseZp(prime:INTI) is
-- make Grobner basis
GBase.sort; GBase:=GBase.reverse;
q:ARRAY{POLY};
s,h:POLY;
loop while!(S_list.size>0);
s:=S_list.pop.element;
s.divmod_Zp_lt(prime, GBase,out q, out h);
if ~h.is_zero then
loop S_list.insert(wrap.create(h.S_poly_Zp(prime,GBase.elt!)));
end;
-- GBase:=GBase.append(|h|); GBase.sort; GBase:=GBase.reverse;
GBase:=ARRAY_SORT{POLY}::sorted_rev_insert(GBase, h);
end;
end;
end;
makeMinimalLcGBaseZp(prime:INTI) is
-- make lc = 1
loop i::=GBase.ind!;
cr::=INTI_EXT::inv(prime, GBase[i].lc);
GBase[i]:=(GBase[i]*cr)%prime;
end;
end;
makeReducedGBaseZp(prime:INTI) is
GBase.sort; GBase:=GBase.reverse;
g,q:ARRAY{POLY}; p,r:POLY;
loop i::=GBase.ind!;
p:=GBase[i]; g:=ARRAY_EXT{POLY}::delete_at(i,GBase);
p.divmod_Zp(prime, g, out q, out r);
GBase[i]:=r;
end;
end;
getGBaseZp(prime:INTI, fList:ARRAY{POLY}):ARRAY{POLY} is
GBase:=#;
loop fi::=fList.elt!.normalize;
if fi.is_zero.not then GBase:=GBase.append(|fi|); end;
end;
if GBase.size=0 then return (#); end;
S_list:=#;
loop i::=0.upto!(GBase.size-2);
loop j::=(i+1).upto!(GBase.size-1);
S_list.insert(wrap.create(GBase[i].S_poly_Zp(prime,GBase[j])));
end;
end;
--#OUT+"gb="+GBase.str+"\n";
--#OUT+"makeGBaseZp\n";
makeGBaseZp(prime);
--#OUT+"gb="+GBase.str+"\n";
--#OUT+"makeMinimalLcGBaseZp\n";
makeMinimalLcGBaseZp(prime);
--#OUT+"gb="+GBase.str+"\n";
--#OUT+"makeMinimalGBase\n";
makeMinimalGBase;
--#OUT+"gb="+GBase.str+"\n";
--#OUT+"makeReducedGBaseZp\n";
makeReducedGBaseZp(prime);
--#OUT+"gb="+GBase.str+"\n";
GBase.sort; GBase:=GBase.reverse;
return GBase;
end;
end;
partial class GBASE_INTI_ALG{POLY,R}
partial class GBASE_INTI_ALG{POLY,R} is
absGB is
loop i::=0.upto!(GBase.size-1);
if GBase[i].lc.is_neg then GBase[i]:=-GBase[i]; end;
end;
end;
makeGBaseI is
-- make Grobner basis
GBase.sort; GBase:=GBase.reverse;
q:ARRAY{POLY};
s,h:POLY;
loop while!(S_list.is_empty.not);
s:=S_list.pop.element;
s.divmod_lt(GBase,out q, out h);
if ~h.is_zero then
loop S_list.insert( wrap.create(h.S_poly_PID(GBase.elt!))); end;
-- GBase:=GBase.append(|h|); GBase.sort; GBase:=GBase.reverse;
GBase:=ARRAY_SORT{POLY}::sorted_rev_insert(GBase, h);
end;
end;
end;
shared StrongGb:ARRAY{POLY};
searchSaturatedSubsetI(i:CARD, lcmP:POLY) is
lcmM::=lcmP.lp;
if i>=GBase.size then
sat:ARRAY{POLY}; -- set saturated subset
sat:=#;
-- lcmP: lcm of j[*].lp. for poly in GBase
loop poly::=GBase.elt!;
if lcmM.is_divisible(poly.lp) then sat:=sat.append(|poly|); end;
end;
if sat.size=0 then return; end;
cj:ARRAY{R}:=#(sat.size);
loop k::=sat.ind!; cj[k]:=sat[k].lc; end;
aj:ARRAY{R};
cJ:R;
cJ:=INTI_EXT::extended_gcd(cj,out aj);
fJ::=POLY::zero;
loop k::=sat.ind!; fJ:=fJ+#POLY(lcmM/sat[k].lp)*sat[k]*aj[k]; end;
StrongGb:=StrongGb.append(|fJ|);
else
lp::=GBase[i].lp;
searchSaturatedSubsetI(i+1,lcmP);
if ~lcmP.lp.is_divisible(lp) then
searchSaturatedSubsetI(i+1,#POLY(lcmP.lp.lcm(lp)));
end;
end;
end;
reductionSameLpI is
GBase.sort; GBase:=GBase.reverse;
-- Make GBase[] have different lp.
--#OUT+"reductionSameLpI\n";
f:POLY;
a0,a1:R;
i::=0;
loop while!(i<GBase.size-1);
j::=i+1;
loop while!(j<GBase.size);
if GBase[i].lp=GBase[j].lp then
gcd::=INTI_EXT::extended_gcd(GBase[i].lc,GBase[j].lc,out a0,out a1);
f:=GBase[i]*a0+GBase[j]*a1;
GBase[i]:=f;
GBase:=ARRAY_EXT{POLY}::delete_at(j,GBase);
else j:=j+1;
end;
end;
i:=i+1;
end;
end;
makeStrongGBI is
-- make strong Grobner basis
absGB;
reductionSameLpI;
-- for all saturated subset
GBase.sort; GBase:=GBase.reverse;
StrongGb:=#;
searchSaturatedSubsetI(0,POLY::one);
GBase:=StrongGb.copy;
reductionSameLpI;
GBase.sort; GBase:=GBase.reverse;
end;
makeMinimalStrongGBI is
g:ARRAY{POLY}:=#;
q:ARRAY{POLY};
p,r:POLY;
GBase.sort; GBase:=GBase.reverse;
i::=0;
loop while!(i<GBase.size);
p:=GBase[i]; g:=ARRAY_EXT{POLY}::delete_at(i,GBase);
p.divmod(g, out q, out r);
if r.is_zero then GBase:=ARRAY_EXT{POLY}::delete_at(i,GBase);
else GBase[i]:=r; i:=i+1;
end;
end;
GBase.sort; GBase:=GBase.reverse;
end;
getGBaseI(fList:ARRAY{POLY}):ARRAY{POLY} is
GBase:=#;
loop fi::=fList.elt!.normalize;
if fi.is_zero.not then GBase:=GBase.append(|fi|); end;
end;
if GBase.size=0 then return (#); end;
S_list:=#;
loop i::=0.upto!(GBase.size-2);
loop j::=(i+1).upto!(GBase.size-1);
S_list.insert( wrap.create(GBase[i].S_poly_PID(GBase[j])) );
end;
end;
-- #OUT+GBase.str+"\n";
-- #OUT+"makeGBaseI\n";
makeGBaseI;
-- #OUT+GBase.str+"\n";
-- #OUT+"makeStrongGBI\n";
makeStrongGBI;
--#OUT+GBase.str+"\n";
--#OUT+"makeMinimalStrongGBI\n";
makeMinimalStrongGBI;
--#OUT+GBase.str+"\n";
--#OUT+"sort\n";
GBase.sort; GBase:=GBase.reverse;
--#OUT+GBase.str+"\n";
return GBase;
end;
end; -- GBaseI
partial class GBASE{POLY}
partial class GBASE{POLY} is
shared S_list:A_PQ{PQMIN{POLY}}; -- queue of S-polynomial.
shared wrap:PQMIN{POLY};
shared GBase:ARRAY{POLY}; -- sorted decreasing order ">".
makeGBase is
-- make Grobner basis
GBase.sort; GBase:=GBase.reverse;
q:ARRAY{POLY};
s,h:POLY;
loop while!(S_list.size>0);
s:=S_list.pop.element;
s.divmod_lt(GBase,out q, out h);
if ~h.is_zero then
loop S_list.insert(wrap.create(h.S_poly(GBase.elt!))); end;
--GBase:=GBase.append(|h|); GBase.sort; GBase:=GBase.reverse;
GBase:=ARRAY_SORT{POLY}::sorted_rev_insert(GBase, h);
end;
end;
end;
makeMinimalGBase is
GBase.sort; GBase:=GBase.reverse;
i,j:CARD; change:BOOL;
i:=0;
loop while!(i<GBase.size);
j:=i+1; change:=false;
loop while!(j<GBase.size);
if GBase[i].lt.is_divisible(GBase[j].lt) then
change:=true; break!;
end;
j:=j+1;
end;
if change then
GBase:=ARRAY_EXT{POLY}::delete_at(i,GBase);
else i:=i+1; end;
end;
end;
makeMinimalLcGBase is
-- make lc = 1
loop i::=GBase.ind!;
GBase[i]:=GBase[i]/GBase[i].lc;
end;
end;
makeReducedGBase is
-- Reduced Grobner basis is canonical.
GBase.sort; GBase:=GBase.reverse;
g,q:ARRAY{POLY}; p,r:POLY;
loop i::=GBase.ind!;
p:=GBase[i]; g:=ARRAY_EXT{POLY}::delete_at(i,GBase);
p.divmod(g,out q, out r);
GBase[i]:=r;
end;
end;
getGBase(fList:ARRAY{POLY}):ARRAY{POLY} is
GBase:=#;
loop fi::=fList.elt!.normalize;
if fi.is_zero.not then GBase:=GBase.append(|fi|); end;
end;
if GBase.size=0 then return (#); end;
S_list:=#;
loop i::=0.upto!(GBase.size-2);
loop j::=(i+1).upto!(GBase.size-1);
S_list.insert( wrap.create(GBase[i].S_poly(GBase[j])) );
end;
end;
--#OUT+"gb="+GBase.str+"\n";
makeGBase;
--#OUT+"gb="+GBase.str+"\n";
--#OUT+"makeMinimalGBase\n";
makeMinimalGBase;
--#OUT+"gb="+GBase.str+"\n";
--#OUT+"makeMinimalLcGBase\n";
makeMinimalLcGBase;
--#OUT+"gb="+GBase.str+"\n";
--#OUT+"makeReducedGBase\n";
makeReducedGBase;
--#OUT+"gb="+GBase.str+"\n";
--#OUT+"sort\n";
GBase.sort; GBase:=GBase.reverse;
--#OUT+"gb="+GBase.str+"\n";
return GBase;
end;
end;