gbases.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).
--
class GBASES_INTI
class GBASES_INTI is
-- reduced minimal strong Grobner base for ideal in Z[x]
-- Use as: glist=getGBaseI([f1,f2,f3,...])
--
-- 2001-02-03 Sather version
-- K.Kodama 2000-02-04 Ruby first version
--
include GBASES_INTI_ALG{POLYS_INTI,INTI};
end;
class GBASES_INTI_L
class GBASES_INTI_L is
-- reduced minimal strong Grobner base for ideal
-- in Laurent polynomial Z<x>.
--
-- Use as: glist=getGBaseIL([f1,f2,f3,...])
-- 2001-02-03 Sather version
-- K.Kodama 2000-02-17 Ruby first version
include GBASES_INTI_ALG{POLYS_INTI,INTI};
include GBASES_INTI_L_ALG{POLYS_INTI,INTI};
end;
partial class GBASES_INTI_L_ALG{POLY,R}
partial class GBASES_INTI_L_ALG{POLY,R} is
shared GPoly:POLY;
makeGBaseI1L is
-- make Grobner basis
GBase.sort; GBase:=GBase.reverse;
absGB;
q:ARRAY{POLY};
s,h:POLY;
lcH:INTI;
loop while!(S_list.is_empty.not);
s:=S_list.pop.element;
h:=s.mod_lt(GBase);
if ~h.is_zero then
h:=h.shift0;
if h.lc.is_neg then h:=-h; end;
loop S_list.insert( wrap.create(h.S_poly_PID(GBase.elt!))); end;
S_list.insert( wrap.create(h.S_poly_PID_L2(GPoly)));
S_list.insert( wrap.create(h.S_poly_PID_L3(GPoly)));
-- GBase:=GBase.append(|h|); GBase.sort; GBase:=GBase.reverse;
GBase:=ARRAY_SORT{POLY}::sorted_rev_insert(GBase, h);
end;
end;
end;
shift0GBase:BOOL is
sFlg::=false;
loop i::=GBase.ind!;
if GBase[i][0].is_zero then sFlg:=true;
GBase[i]:=GBase[i].shift0;
end;
end;
return sFlg;
end;
getGBaseIL(fList:ARRAY{POLY}):ARRAY{POLY} is
kf:POLY; return getGBaseIL(fList,out kf);
end;
getGBaseIL(fList:ARRAY{POLY},out kf:POLY):ARRAY{POLY} is
GBase:=#; kf:=POLY::zero;
loop fi::=fList.elt!.normalize;
if fi.is_zero.not then GBase:=GBase.append(|fi|); end;
end;
if GBase.size=0 then return (#); end;
loop while!(shift0GBase);
GBase:=GBASES_INTI::getGBaseI(GBase);
end;
listr:ARRAY{POLY}:=#(GBase.size);
loop i::=GBase.ind!; listr[i]:=GBase[i].reverseDeg; end;
gf:POLY:=POLY::one*2;
loop f::=listr.elt!;
if ( (f.lc.abs=POLY::r_1)and
((gf.lc.abs/=POLY::r_1)or(f.degree<gf.degree))) then
gf:=f.copy;
end;
end;
if gf.lc.abs /= POLY::r_1 then
listr:=GBASES_INTI::getGBaseI(listr); gf:=listr[0].copy;
end;
if gf.lc.is_neg then gf:=-gf; end;
GPoly:=gf.reverseDeg;
S_list:=#;
loop i::=GBase.ind!;
S_list.insert(wrap.create(GBase[i].S_poly_PID_L2(GPoly)));
S_list.insert(wrap.create(GBase[i].S_poly_PID_L3(GPoly)));
end;
makeGBaseI1L;
makeStrongGBI;
makeMinimalStrongGBI;
GBase.sort; GBase:=GBase.reverse;
kf:=GPoly.shift_deg(-1).mod(GBase).shift_deg(1.int)+GPoly[0];
if kf.lc.is_neg then kf:=-kf; end;
return GBase;
end;
end;
partial class GBASES_INTI_ALG{POLY,R}
partial class GBASES_INTI_ALG{POLY,R} is
shared S_list:A_PQ{PQMIN{POLY}}; -- queue of S-polynomial.
shared wrap:PQMIN{POLY};
shared GBase:ARRAY{POLY};
absGB is
loop i::=GBase.ind!;
if GBase[i].lc.is_neg then GBase[i]:=-GBase[i]; end;
end;
end;
makeGBaseI is
-- make Grobner basis
GBase.sort; GBase:=GBase.reverse;
absGB;
q:ARRAY{POLY};
s,h:POLY;
lcH:INTI;
loop while!(S_list.is_empty.not);
s:=S_list.pop.element;
h:=s.mod_lt(GBase);
if ~h.is_zero then
if h.lc.is_neg then h:=-h; end;
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:INT, lcmD:INT) is
-- lcmM::=lcmP.lp;
-- lcmD:INT:=lcmP.degree; (c.f gbasem.sa)
if i>=GBase.size.int then
sat:ARRAY{POLY}:=#; -- set saturated subset
-- lcmP: lcm of j[*].lp. for poly in GBase
loop poly::=GBase.elt!;
if lcmD>=poly.degree 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+(sat[k]*aj[k]).shift_deg(lcmD-sat[k].degree); end;
StrongGb:=StrongGb.append(|fJ|);
else
d::=GBase[i.card].degree;
searchSaturatedSubsetI(i+1,lcmD);
if lcmD<d then
--if ~lcmP.lp.is_divisible(lp) then
searchSaturatedSubsetI(i+1,d);
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].degree=GBase[j].degree 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.int,0.int);
GBase:=StrongGb.copy;
absGB;
reductionSameLpI;
GBase.sort; GBase:=GBase.reverse;
end;
makeMinimalStrongGBI is
g: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);
r:=p.mod(g);
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 (#);
elsif GBase.size=1 then return GBase;
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;
class TEST_GBASEI
class TEST_GBASEI is
include TEST;
main is
POLYS_INTI::init;
test_gb_s_i;
test_gb_s_i_l;
end;
test_gb_s_i is
class_name("GBASES_INTI");
#OUT+" Grobner basis for Z[x]\n";
f1,f2,f3:POLYS_INTI;
gb:ARRAY{POLYS_INTI};
sa:ARRAY{STR};
s:STR;
x::=POLYS_INTI::x;
f1:=x^(4)*2-x^(2)*2+x*8+10;-- "2x^(4)-2x^(2)+8x+10"
f2:=x^(4)*3+x*12+15; -- "3x^(4)+12x+15"
f3:=x^(5)*2+x^(4)*12-x^(3)*2+x^(2)*10+x*58+62; --"2x^(5)+12x^(4)-2x^(3)+10x^(2)+58x+62")
gb:=GBASES_INTI::getGBaseI(|f1,f2,f3|);
sa:=|"x^{4}+1", "2" |; s:=sa.str;
test("sample1", gb.str, s);
finish;
end;
test_gb_s_i_l is
class_name("GBASES_INTI_L");
#OUT+" Grobner basis for Z[x,1/x]\n";
f1,f2,f3,f4,f5,f6,f7,f8,f9:POLYS_INTI;
gb:ARRAY{POLYS_INTI};
sa:ARRAY{STR};
s:STR;
x::=POLYS_INTI::x;
f1:=x^(4)*2-x^(2)*2+x*8+10;-- "2x^(4)-2x^(2)+8x+10"
f2:=x^(4)*3+x*12+15; -- "3x^(4)+12x+15"
f3:=x^(5)*2+x^(4)*12-x^(3)*2+x^(2)*10+x*58+62; --"2x^(5)+12x^(4)-2x^(3)+10x^(2)+58x+62")
gb:=GBASES_INTI_L::getGBaseIL(|f1,f2,f3|);
sa:=|"x^{4}+1", "2" |; s:=sa.str;
test("sample1", gb.str, s);
f1:=x^(8)-x^(7)*4+x^(6)*9-x^(5)*15+x^(4)*17-x^(3)*15+x^(2)*9-x*4+1;
f2:=-x^(8)+x^(7)*4-x^(6)*9+x^(5)*15-x^(4)*17+x^(3)*15-x^(2)*9+x*4-1;
f3:=POLYS_INTI::zero;
f4:=-x^(8)+x^(7)*4-x^(6)*9+x^(5)*15-x^(4)*17+x^(3)*15-x^(2)*9+x*4-1;
f5:=x^(8)-x^(7)*4+x^(6)*9-x^(5)*15+x^(4)*17-x^(3)*15+x^(2)*9-x*4+1;
f6:=POLYS_INTI::zero;
f7:=POLYS_INTI::zero;
f8:=POLYS_INTI::zero;
f9:=POLYS_INTI::zero;
gb:=GBASES_INTI_L::getGBaseIL(|f1,f2,f3,f4,f5,f6,f7,f8,f9|);
s:="{x^{8}-4*x^{7}+9*x^{6}-15*x^{5}+17*x^{4}-15*x^{3}+9*x^{2}-4*x+1}";
test("sample2", gb.str, s);
finish;
end;
end;