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}; include MAT_POLYS{POLYS_INTI}; det_mod_unit:POLYS_INTI is return MAT_POLYS_DET::det_mod_unit(self); end; end;

class MAT_POLYS_FP

class MAT_POLYS_FP is include MAT_RING{POLYS_FP}; include DET_PRIMITIVE_ALG{POLYS_FP} det->det_prm; include MAT_PID{POLYS_FP}; include MAT_PID_DET{POLYS_FP} det->det_pid; include MAT_POLYS{POLYS_FP}; det:POLYS_FP is return det_pid; end; row_mod(i:CARD, n:POLYS_FP) is -- (i-th row) mod n if nc>0 then loop j:CARD:=0.upto!(nc-1); m[i][j]:=m[i][j]%n; end; end; end; col_mod(j:CARD, n:POLYS_FP) is -- (j-th col) mod n if nr>0 then loop i:CARD:=0.upto!(nr-1); m[i][j]:=m[i][j]%n; end; end; end; end;

partial class MAT_POLYS{ET}

partial class MAT_POLYS{ET} is create(r,c:CARD):SAME is return create(r,c,ET::one); end; str_pmatrix(var_name:STR):STR is -- TeX \pmatrix{ }. v:var name if nc=0 or nr=0 then return "()"; end; s:STR:="\\pmatrix{\n"; newln:STR:=""; loop i::=0.upto!(nr-1); s:=s+newln; newln:="\\cr\n"; sep:STR:=""; loop j::=0.upto!(nc-1); s:=s+sep+m[i][j].str("tex",var_name,true); sep:=" & "; end; end; s:=s+"\\cr\n}\n"; return s; end; str_array(var_name:STR):STR is -- LaTeX array. v:var name if nc=0 or nr=0 then return "()"; end; s:STR:="\\left( \\begin{array}{"+("c".repeat(nc))+"}\n"; newln:STR:=""; loop i::=0.upto!(nr-1); s:=s+newln; newln:="\\\\\n"; sep:STR:=""; loop j::=0.upto!(nc-1); s:=s+sep+m[i][j].str("tex",var_name,true); sep:=" & "; end; end; s:=s+"\n\\end{array} \\right)\n"; return s; end; strTeX(var_name:STR):STR is return str_pmatrix(var_name); end; end;

class MAT_POLYS_DET

class MAT_POLYS_DET is det_mod_unit(M:MAT_POLYS_INTI):POLYS_INTI is if M.nr/=M.nc then return POLYS_INTI::zero; end; Mw::=M.copy; jPivot:ARRAY{CARD}; p0:CARD; MAT_POLYS_INTI_REDUCTION::reduce(inout Mw,out jPivot,out p0); poly::=POLYS_INTI::one; pw:POLYS_INTI; -- work -- diagonal part if p0>0 then loop i::=0.upto!(p0-1); pw:=Mw[i,jPivot[i]]; if pw.is_zero then return pw; else poly:=poly*pw; end; end; end; -- non-diagonal part if p0<Mw.nr then mat::=Mw.copy; jPivotm::=jPivot.copy; loop i::=0.upto!(p0-1); mat:=mat.minor_matrix(0,jPivotm[i]); loop j::=i.upto!(jPivotm.size-1); if jPivotm[j]>jPivotm[i] then jPivotm[j]:=jPivotm[j]-1; end; end; end; poly:=poly*mat.det; end; return poly; 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:CARD; shared cv0:ARRAY{POLYS_INTI}; shared Mat:MAT_POLYS_INTI; shared jPivot:ARRAY{CARD}; -- [1..ALEXMATmaxC] shared p0:CARD; shared polydegM:CARD; 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):CARD is -- maximal degree in [p0..iDeg][p0..jDeg] d:CARD:=0; loop i::=p0.upto!(Mat.nr-1); loop j::=p0.upto!(Mat.nc-1); d:=d.max(Mat[i][jPivot[j]].degree.card); end; end; return d; end; Sp(i,j:CARD, out deg:CARD,out Pivot_lc:INTI) is ip:=i; jp:=j; cv0:=Mat[ip]; deg:=cv0[jPivot[j]].degree.card; Pivot_lc:=cv0[jPivot[j]].lc; end; SetPivotSearch(p0:CARD, polydeg:CARD, out deg:CARD, out Pivot_is_unit:BOOL) is APivot,wPivot:INTI; j1:CARD; count:CARD:=0; Sp(p0,p0, out deg,out Pivot_lc); Pivot_is_unit:=false; 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, out deg,out Pivot_lc); return; end; end; end; -- Search unit wPivot:=0.inti; Pivot_is_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 ((~Pivot_is_unit)or(cv1[j1].degree<deg.int)) ) then Sp(i,j,out deg,out Pivot_lc); Pivot_is_unit:=true; if (deg=0) then return; end; end; end; end; end; if Pivot_is_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,out deg,out Pivot_lc); APivot:=Pivot_lc.abs; end; if (cv1[j1].is_zero.not) and((i/=p0)or(j/=p0)) and (APivot>wPivot) then if (deg.int>cv1[j1].degree)or(APivot>wPivot) then Sp(i,j,out deg,out Pivot_lc); APivot:=Pivot_lc.abs; end; end; end; end; return; end; -- SetPivotSearch SetPivot(p0:CARD, inout polydeg:CARD, out piv_is_unit:BOOL):BOOL is -- Set Pivot_lc,jPivot: ip:=p0,jp:=jPivot[p0],cv0:=Mat[ip]; deg:CARD; SetPivotSearch(p0,polydeg,out deg, out piv_is_unit); -- 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 j1:CARD; -- 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.is_non_neg then d:=d.min(cv1[j1].low_deg); else d:=cv1[j1].low_deg; end; end; end; if d.is_pos 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:CARD) is -- shift degree to standard position d:INT:=-1; j1:CARD:=jPivot[j]; -- set degree loop i::=p0.upto!(Mat.nr-1); if (Mat[i][j1].is_zero.not) then if d.is_non_neg then d:=d.min(Mat[i][j1].low_deg); else d:=Mat[i][j1].low_deg; end; end; end; if d.is_pos 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:CARD, inout polydegM:CARD, piv_is_unit:BOOL):BOOL is j1:CARD; d:INT; s:INTI:=0.inti; spoly:POLYS_INTI; cv1::=Mat[i]; flg:BOOL:=false; if piv_is_unit then flg:=true; loop -- if cv0[jp].degree/=0 then #OUT+"!"; end; if (cv1[jp].is_zero) then break!; end; d:=cv1[jp].degree-cv0[jp].degree; if d.is_neg 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.card); 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; 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.card); 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.int<cv1[j1].degree) then polydegM:=cv1[j1].degree.card; end; end; return true; end; SubL(j:CARD, inout polydegM:CARD):BOOL is s:INTI:=0.inti; spoly:POLYS_INTI; j1:CARD:=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:CARD:=(cv0[j1].degree-cv0[jp].degree).card; 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.card) then polydegM:=cv1[j1].degree.card; end; end; return true; end; reduce(inout mat:MAT_POLYS_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; piv_is_unit:BOOL; 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_tmp::=polydegM; --#OUT+"reduce4: setpivot"+"\n"; loop while!((polydeg_tmp>=0) and (~ SetPivot(p0,inout polydeg_tmp, out piv_is_unit)) ); if polydeg_tmp=0 then -- minimal? mat:=Mat; jpivot:=jPivot; return; end; polydeg_tmp:=polydeg_tmp-1; end; if CheckZero(p0) then break!; end; polydegM:=polydeg_tmp; -- #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,piv_is_unit) or subFlg; -- if (Pivot_lc.abs/=1)or(polydeg_tmp>0) then -- WriteMatrix(p0); --end; end; end; if piv_is_unit then cv0[jp]:=POLYS_INTI::one; polydeg_tmp:=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_tmp>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;