polym_mat.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 

class MAT_POLYM_INTI

class MAT_POLYM_INTI is include MAT_RING{POLYM_INTI}; include DET_PRIMITIVE_ALG{POLYM_INTI}; create(r,c:CARD):SAME is return create(r,c,POLYM_INTI::one); end; end;

class MAT_POLYM_INTI_REDUCTION

class MAT_POLYM_INTI_REDUCTION is ------------------- matrix reduction ----------- shared Pivot_lc:INTI; -- coefficient of highest term shared ip,jp:CARD; shared cv0:ARRAY{POLYM_INTI}; shared Mat:MAT_POLYM_INTI; shared jPivot:ARRAY{CARD}; -- [1..ALEXMATmaxC] shared p0:CARD; shared polydeg,polydegM:MONOMIAL{INTI}; CheckZeroI(p0:CARD):BOOL is loop j::=(p0+1).upto!(Mat.nc-1); if Mat[p0][jPivot[j]].is_zero.not then return false; end; end; return true; end; CheckZeroJ(p0:CARD):BOOL is j0::=jPivot[p0]; loop i::=(p0+1).upto!(Mat.nr-1); if Mat[i][j0].is_zero.not then return false; end; end; return true; end; CheckZero(p0:CARD):BOOL is res::=CheckZeroI(p0) and CheckZeroJ(p0); return res; end; maxDeg(p0:CARD):MONOMIAL{INTI} is -- maximal degree in [p0..iDeg][p0..jDeg] d:MONOMIAL{INTI}:=#; loop i::=p0.upto!(Mat.nr-1); loop j::=p0.upto!(Mat.nc-1); d:=d.lcm(Mat[i][jPivot[j]].lp); end; end; return d; end; shared unit:BOOL; -- true if pivot be a unit. shared deg:MONOMIAL{INTI}; Sp(i,j:CARD) is ip:=i; jp:=j; cv0:=Mat[ip]; deg:=cv0[jPivot[j]].lp; Pivot_lc:=cv0[jPivot[j]].lc; end; SetPivotSearch(p0:CARD) is APivot,wPivot:INTI; j1::=p0; count::=0; Sp(p0,p0); cv0:=Mat[ip]; cv1::=cv0; -- search arleady reduced loop i::=p0.upto!(Mat.nr-1); cv1:=Mat[i]; count:=0; loop j::=p0.upto!(Mat.nc-1); if cv1[jPivot[j]].is_zero.not then count:=count+1; jp:=j; end; end; if count=1 then j1:=jPivot[jp]; count:=0; loop i1::=p0.upto!(Mat.nr-1); if Mat[i1][j1].is_zero.not then count:=count+1; end; end; if count=1 then Sp(i,jp); return; end; end; end; -- Search unit wPivot:=0.inti; unit:=false; deg:=#; loop i::=p0.upto!(Mat.nr-1); cv1:=Mat[i]; loop j::=p0.upto!(Mat.nc-1); j1:=jPivot[j]; if cv1[j1].is_zero.not then wPivot:=cv1[j1].lc.abs; if ((wPivot=1.inti)and(cv1[j1]=#POLYM_INTI(cv1[j1].lt)) and ((~unit)or(cv1[j1].lp<deg)) ) then Sp(i,j); unit:=true; if (deg=#MONOMIAL{INTI}) then return; end; end; end; end; end; if unit then return; end; -- Search a polynomial with least coefficient of degree "polydeg" APivot:=(-1).inti; wPivot:=0.inti; deg:=polydeg; loop i::=p0.upto!(Mat.nr-1); cv1:=Mat[i]; loop j::=p0.upto!(Mat.nc-1); j1:=jPivot[j]; wPivot:=cv1[j1].lc.abs; if (cv1[j1].is_zero.not)and(APivot<0.inti) then Sp(i,j); APivot:=Pivot_lc.abs; end; if (cv1[j1].is_zero.not)and((i/=p0)or(j/=p0))and(APivot>wPivot) then if (deg>cv1[j1].lp)or(APivot>wPivot) then Sp(i,j); APivot:=Pivot_lc.abs; end; end; end; end; return; end; -- SetPivotSearch SetPivot(p0:CARD, inout polydeg:MONOMIAL{INTI}):BOOL is -- Set Pivot_lc,jPivot: ip:=p0,jp:=jPivot[p0],cv0:=Mat[ip]; SetPivotSearch(p0); -- ip,jp,Pivot_lc cv0:=Mat[ip]; Mat[ip]:=Mat[p0]; Mat[p0]:=cv0; ip:=p0; tmp::=jPivot[jp]; jPivot[jp]:=jPivot[p0]; jPivot[p0]:=tmp; jp:=tmp; if Pivot_lc/=0.inti then polydeg:=deg; end; return Pivot_lc/=0.inti; end; shiftC(i:CARD) is -- shift degree of i-th row to standard position d:MONOMIAL{INTI}; cv1::=Mat[i]; loop j::=p0.upto!(Mat.nc-1); j1::=jPivot[j]; -- set degree if (cv1[j1].is_zero.not) then if void(d) then d:=cv1[j1].gcd_term; else d:=d.gcd(cv1[j1].gcd_term); end; end; end; if void(d) then d:=#; end; d.coeff:=POLYM_INTI::r_1; if (~void(d))and(d>#MONOMIAL{INTI}) then --shift degree loop j::=p0.upto!(Mat.nc-1); j1::=jPivot[j]; if (cv1[j1].is_zero.not) then cv1[j1]:=cv1[j1]/#POLYM_INTI(d); end; end; end; end; shiftL(j:CARD) is -- shift degree to standard position d:MONOMIAL{INTI}; j1::=jPivot[j]; -- set degree loop i::=p0.upto!(Mat.nr-1); if (Mat[i][j1].is_zero.not) then if void(d) then d:=Mat[i][j1].gcd_term; else d:=d.gcd(Mat[i][j1].gcd_term); end; end; end; if void(d) then d:=#; end; d.coeff:=POLYM_INTI::r_1; if d>#MONOMIAL{INTI} then --shift loop i::=p0.upto!(Mat.nr-1); if (Mat[i][j1].is_zero.not) then Mat[i][j1]:=Mat[i][j1]/#POLYM_INTI(d); end; end; end; end; SubC(i:CARD, inout polydegM:MONOMIAL{INTI}):BOOL is j1 :CARD; s:INTI:=0.inti; spoly, wpoly:POLYM_INTI; d,mw:MONOMIAL{INTI}; cv1::=Mat[i]; flg:BOOL:=false; -- #OUT+"subC"+"\n"; if unit then flg:=true; loop -- if cv0[jp].degree/=0 then #OUT+"!"; end; --#OUT+"subC:1"+"\n"; -- check equivalence with Alexander poly. -- #LOGOUT+WriteMatrix(Mat,Mat.nr-1,Mat.nc-1,1); -- APolyOut(p0,maxR,false); -- #LOGOUT+"\n"; if (cv1[jp].is_zero) then break!; end; mw:=cv1[jp].lp.lcm(cv0[jp].lp); d:=mw/cv1[jp].lp; d.coeff:=POLYM_INTI::r_1; wpoly:=#POLYM_INTI(d); --d:=mw/cv0[jp].lp; d.coeff:=cv1[jp].lc/Pivot_lc; --spoly:=#POLYM_INTI(d); spoly:=cv1[jp]*wpoly/cv0[jp]; loop j::=p0.upto!(Mat.nc-1); j1:=jPivot[j]; if cv0[j1].is_zero.not then cv1[j1]:=cv1[j1]*wpoly-cv0[j1]*spoly; end; end; -- #LOGOUT+WriteMatrix(Mat,Mat.nr-1,Mat.nc-1,1); -- APolyOut(p0,maxR,false); -- #LOGOUT+"\n"; end; else loop --#OUT+"subC:2"+"\n"; if (cv1[jp].is_zero)or(cv1[jp].lt<cv0[jp].lt) then break!; end; if cv1[jp].lp.is_divisible(cv0[jp].lp,false,false).not then break!; end; s:=cv1[jp].lc/Pivot_lc; if s=0.inti then break!; end; flg:=true; mw:=cv1[jp].lp.lcm(cv0[jp].lp); d:=mw/cv1[jp].lp; d.coeff:=POLYM_INTI::r_1; wpoly:=#POLYM_INTI(d); --d:=mw/cv0[jp].lp; d.coeff:=s; --spoly:=#POLYM_INTI(d); spoly:=cv1[jp]*wpoly/cv0[jp]; loop j::=p0.upto!(Mat.nc-1); j1:=jPivot[j]; if cv0[j1].is_zero.not then cv1[j1]:=cv1[j1]*wpoly-cv0[j1]*spoly; end; end; end; end; --#OUT+"subC:2"+"\n"; if ~ flg then return false; end; loop j::=p0.upto!(Mat.nc-1); shiftL(j); end; shiftC(i); -- set polydegM --#OUT+"subC:4"+"\n"; loop j::=p0.upto!(Mat.nc-1); j1:=jPivot[j]; if (cv1[j1].is_zero.not)and(polydegM<cv1[j1].lp) then polydegM:=cv1[j1].lp; end; end; return true; end; SubL(j:CARD, inout polydegM:MONOMIAL{INTI}):BOOL is s:INTI:=0.inti; spoly, wpoly:POLYM_INTI; j1::=jPivot[j]; flg:BOOL:=false; cv1:ARRAY{POLYM_INTI}; d,dw:MONOMIAL{INTI}; --#OUT+"subL"+"\n"; loop --#OUT+"subL:1"+"\n"; if (cv0[j1].is_zero)or(cv0[j1].lp<cv0[jp].lp) then break!; end; if cv0[j1].lp.is_divisible(cv0[jp].lp,false,false).not then break!; end; s:=(cv0[j1].lc/Pivot_lc); if s=0.inti then break!; end; dw:=cv0[j1].lp.lcm(cv0[jp].lp); d:=dw/cv0[j1].lp; d.coeff:=POLYM_INTI::r_1; wpoly:=#POLYM_INTI(d); --d:=mw/cv0[jp].lp; d.coeff:=s; --spoly:=#POLYM_INTI(d); spoly:=cv0[j1]*wpoly/cv0[jp]; flg:=true; loop i::=p0.upto!(Mat.nr-1); cv1:=Mat[i]; if cv1[jp].is_zero.not then cv1[j1]:=cv1[j1]*wpoly-spoly*cv1[jp]; end; end; end; --#OUT+"subL:2"+"\n"; if ~ flg then return false; end; loop i::=p0.upto!(Mat.nr-1); shiftC(i); end; shiftL(j); -- set polydegM --#OUT+"subL:3"+"\n"; loop i::=p0.upto!(Mat.nr-1); cv1:=Mat[i]; if (cv1[j1].is_zero.not)and(polydegM<cv1[j1].lp) then polydegM:=cv1[j1].lp; end; end; return true; end; reduce(inout mat:MAT_POLYM_INTI,out jpivot:ARRAY{CARD},out rDeg:CARD) is --#OUT+"reduce\n"; i1:CARD; subFlg:BOOL; count:CARD; Mat:=mat; jPivot:=#(mat.nc); loop i::=jPivot.ind!; jPivot[i]:=i; end; jpivot:=jPivot; dim:CARD:=(Mat.nr).min(Mat.nc); if dim<=0 then rDeg:=0;mat:=Mat; jpivot:=jPivot; return; end; --#OUT+"reduce1\n"; loop p0:=0.upto!(dim-1); --#OUT+"reduce2: p0="+p0.str+"\n"; if (p0+1=dim)and(Mat.nr=Mat.nc) then rDeg:=p0+1; mat:=Mat; jpivot:=jPivot; return; end; rDeg:=p0; polydegM:=maxDeg(p0); subFlg:=true; count:=0; loop count:=count+1; --#OUT+"reduce3: count="+count.str+"\n"; -- I don't know how to check the matrix is minimal. -- (dim-p0+1) if count>(dim-p0).square then mat:=Mat; jpivot:=jPivot; return; end; --if ~ subFlg then polydegM:=polydegM-1; --else -- polydegMax:=polydegM; polydegM:=maxDeg(p0); -- polydegMax:=maxDeg(p0,iDeg0,jDeg0); --end; subFlg:=false; polydeg:=polydegM; --#OUT+"reduce4: setpivot"+"\n"; if SetPivot(p0,inout polydeg) then end; --if polydeg<0 then -- minimal? -- mat:=Mat; jpivot:=jPivot; return; --end; if CheckZero(p0) then break!; end; polydegM:=polydeg; -- #OUT+"set pivot:\n"; WriteMatrix(Mat,p0); --#OUT+"reduce5: subC"+"\n"; loop i::=(p0+1).upto!(Mat.nr-1) ; if Mat[i][jp].is_zero.not then subFlg:=SubC(i,inout polydegM) or subFlg; -- if (Pivot_lc.abs/=1)or(polydeg>0) then -- WriteMatrix(p0); --end; end; end; if unit then cv0[jp]:=POLYM_INTI::one; polydeg:=#MONOMIAL{INTI}; loop j::=(p0+1).upto!(Mat.nc-1) ; cv0[jPivot[j]]:=POLYM_INTI::zero; end; break!; elsif CheckZero(p0) then break!; end; --#OUT+"reduce6: subL"+"\n"; loop j::=(p0+1).upto!(Mat.nc-1); if cv0[jPivot[j]].is_zero.not then subFlg:=SubL(j,inout polydegM) or subFlg; -- if (Pivot_lc.abs/=1)or(polydeg>0) then --WriteMatrix(AlexMat,p0); --end; end; end; if CheckZero(p0) then break!; end; end; end; --if Mat.nr-1=Mat.nc-1 then rDeg:=dim+1; end; --PrintRelation; mat:=Mat; jpivot:=jPivot; end; end;