poly_mat.sa


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

class MAT_POLYS_INTI

class MAT_POLYS_INTI is include MAT_RING{POLYS_INTI}; include DET_PRIMITIVE_ALG{POLYS_INTI}; create(r,c:INT):SAME is return create(r,c,POLYS_INTI::one); end; end;

class MAT_POLYS_INTI_REDUCTION

class MAT_POLYS_INTI_REDUCTION is ------------------- matrix reduction ----------- shared Pivot_lc:INTI; -- coefficient of highest term shared ip,jp:INT; shared cv0:ARRAY{POLYS_INTI}; shared Mat:MAT_POLYS_INTI; shared jPivot:ARRAY{INT}; -- [1..ALEXMATmaxC] shared p0:INT; shared polydeg,polydegM:INT; CheckZeroI(p0:INT):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:INT):BOOL is j0:INT:=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:INT):BOOL is res::=CheckZeroI(p0) and CheckZeroJ(p0); return res; end; maxDeg(p0:INT):INT is -- maximal degree in [p0..iDeg][p0..jDeg] d:INT:=0; loop i::=p0.upto!(Mat.nr-1); loop j::=p0.upto!(Mat.nc-1); d:=d.max(Mat[i][jPivot[j]].degree); end; end; return d; end; shared unit:BOOL; -- true if pivot be a unit. shared deg:INT; Sp(i,j:INT) is ip:=i; jp:=j; cv0:=Mat[ip]; deg:=cv0[jPivot[j]].degree; Pivot_lc:=cv0[jPivot[j]].lc; end; SetPivotSearch(p0:INT) is APivot,wPivot:INTI; j1:INT; count:INT:=0; Sp(p0,p0); cv0:=Mat[ip]; cv1:ARRAY{POLYS_INTI}:=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:=0; 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]=cv1[j1].lt) and ((~unit)or(cv1[j1].degree<deg)) ) then Sp(i,j); unit:=true; if (deg=0) 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].degree)or(APivot>wPivot) then Sp(i,j); APivot:=Pivot_lc.abs; end; end; end; end; return; end; -- SetPivotSearch SetPivot(p0:INT, inout polydeg:INT):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:INT) is -- shift degree of i-th row to standard position j1:INT; -- set degree d:INT:=-1; cv1::=Mat[i]; loop j::=p0.upto!(Mat.nc-1); j1:=jPivot[j]; if (cv1[j1].is_zero.not) then if d>=0 then d:=d.min(cv1[j1].low_deg); else d:=cv1[j1].low_deg; end; end; end; if d>0 then --shift loop j::=p0.upto!(Mat.nc-1); j1:=jPivot[j]; if (cv1[j1].is_zero.not) then cv1[j1]:=cv1[j1].shift_deg(-d); end; end; end; end; shiftL(j:INT) is -- shift degree to standard position d:INT:=-1; j1:INT:=jPivot[j]; -- set degree loop i::=p0.upto!(Mat.nr-1); if (Mat[i][j1].is_zero.not) then if d>=0 then d:=d.min(Mat[i][j1].low_deg); else d:=Mat[i][j1].low_deg; end; end; end; if d>0 then --shift loop i::=p0.upto!(Mat.nr-1); if (Mat[i][j1].is_zero.not) then Mat[i][j1]:=Mat[i][j1].shift_deg(-d); end; end; end; end; SubC(i:INT, inout polydegM:INT):BOOL is j1,d :INT; s:INTI:=0.inti; spoly:POLYS_INTI; cv1::=Mat[i]; flg:BOOL:=false; if unit then flg:=true; loop -- if cv0[jp].degree/=0 then #OUT+"!"; end; ------- test ------ -- #LOGOUT+"SubC loop:\n"; -- #LOGOUT+WriteMatrix(Mat,Mat.nr-1,Mat.nc-1,1); -- APolyOut(p0,maxR,false); -- #LOGOUT+"\n"; if (cv1[jp].is_zero) then break!; end; d:=cv1[jp].degree-cv0[jp].degree; if d<0 then loop j::=p0.upto!(Mat.nc-1); cv1[jPivot[j]]:=cv1[jPivot[j]].shift_deg(-d); end; d:=0; end; s:=cv1[jp].lc/Pivot_lc; spoly:=#POLYS_INTI(s,d); loop j::=p0.upto!(Mat.nc-1); j1:=jPivot[j]; if cv0[j1].is_zero.not then cv1[j1]:=cv1[j1]-(spoly*cv0[j1]); end; end; -- #LOGOUT+WriteMatrix(Mat,Mat.nr-1,Mat.nc-1,1); -- APolyOut(p0,maxR,false); -- #LOGOUT+"\n"; end; else loop if (cv1[jp].is_zero)or(cv1[jp].degree<cv0[jp].degree) then break!; end; s:=cv1[jp].lc/Pivot_lc; if s=0.inti then break!; end; flg:=true; d:=cv1[jp].degree-cv0[jp].degree; spoly:=#POLYS_INTI(s,d); loop j::=p0.upto!(Mat.nc-1); j1:=jPivot[j]; if cv0[j1].is_zero.not then cv1[j1]:=cv1[j1]-(spoly*cv0[j1]); end; end; end; end; if ~ flg then return false; end; loop j::=p0.upto!(Mat.nc-1); shiftL(j); end; shiftC(i); -- set polydegM loop j::=p0.upto!(Mat.nc-1); j1:=jPivot[j]; if (cv1[j1].is_zero.not)and(polydegM<cv1[j1].degree) then polydegM:=cv1[j1].degree; end; end; return true; end; SubL(j:INT, inout polydegM:INT):BOOL is d:INT; s:INTI:=0.inti; spoly:POLYS_INTI; j1:INT:=jPivot[j]; flg:BOOL:=false; cv1:ARRAY{POLYS_INTI}; loop --#OUT+"subL:1"+"\n"; if (cv0[j1].is_zero)or(cv0[j1].degree<cv0[jp].degree) then break!; end; s:=(cv0[j1].lc/Pivot_lc); if s=0.inti then break!; end; d:=cv0[j1].degree-cv0[jp].degree; spoly:=#POLYS_INTI(s,d); flg:=true; loop i::=p0.upto!(Mat.nr-1); cv1:=Mat[i]; if cv1[jp].is_zero.not then cv1[j1]:=cv1[j1]-(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].degree) then polydegM:=cv1[j1].degree; end; end; return true; end; reduce(inout mat:MAT_POLYS_INTI,out jpivot:ARRAY{INT},out rDeg:INT) is --#OUT+"reduce\n"; i1:INT; subFlg:BOOL; count:INT; Mat:=mat; jPivot:=#(mat.nc); loop i::=jPivot.ind!; jPivot[i]:=i; end; jpivot:=jPivot; dim:INT:=(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"; loop while!((polydeg>=0) and (~ SetPivot(p0,inout polydeg)) ); polydeg:=polydeg-1; 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]:=POLYS_INTI::one; polydeg:=0; loop j::=(p0+1).upto!(Mat.nc-1) ; cv0[jPivot[j]]:=POLYS_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;