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};
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:INT, n:POLYS_FP) is
loop j:INT:=0.upto!(nc-1); m[i][j]:=m[i][j]%n; end;
end;
col_mod(j:INT, n:POLYS_FP) is
loop i:INT:=0.upto!(nr-1); m[i][j]:=m[i][j]%n; end;
end;
end;
partial class MAT_POLYS{ET}
partial class MAT_POLYS{ET} is
create(r,c:INT):SAME is
return create(r,c,ET::one);
end;
str_pmatrix(var_name:STR):STR is
-- TeX \pmatrix{ }. v:var name
s::="";
s:=s+"\\pmatrix{\n";
loop i::=0.upto!(nr-1);
loop j::=0.upto!(nc-1);
if j>0 then s:=s+" & "; end;
s:=s+m[i][j].str("tex",var_name,true);
end;
s:=s+" \\cr";
-- if i<nr-1 then s:=s+"\\\\"; end;
s:=s+"\n";
end;
s:=s+"}\n";
return s;
end;
str_array(var_name:STR):STR is
-- LaTeX array. v:var name
s::="";
s:=s+"\\left(\n";
s:=s+"\\begin{array}{"; loop nc.times!; s:=s+"c"; end; s:=s+"}\n";
loop i::=0.upto!(nr-1);
loop j::=0.upto!(nc-1);
if j>0 then s:=s+" & "; end;
s:=s+m[i][j].str("tex",var_name,true);
end;
--s:=s+"\\cr"
if i<nr-1 then s:=s+" \\\\"; end;
s:=s+"\n";
end;
s:=s+"\\end{array}\n";
s:=s+"\\right)\n";
return s;
end;
strTeX(var_name:STR):STR is
return str_pmatrix(var_name);
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;