alexmat.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 
-- Copyright (C) 1983 2002 Kouji KODAMA
-- 2002/11 extended Alexander poly.
-- 2001/12 Grobner bases for Elementary ideals.
-- 2001/02 Sather version
-- 1998/1 LongInt
-- 1997/1
-- Theta curve
-- un-oriented surface in S^4
--
--1996/10
--LINUX version
--
--bug fix for 2-knot
--
--92/09/30 03:14:42
--1992/6  Alexander matrix and Alexander polynomial.
--1992/6/20:  10para99(parallel of k10c99. 40 crossing) 10sec.
--K. Kodama


class ALEXMAT

class ALEXMAT is apoly2conway(apoly:POLYS_INTI, out cpoly:POLYS_INTI) is a2c(apoly,out cpoly); a1:POLYS_INTI; c2a(cpoly,out a1); if (apoly/=a1)and(apoly/=-a1) then raise "Failed to convert between a.poly. and c.poly.\n"; end; end; conway2apoly(cpoly:POLYS_INTI, out apoly:POLYS_INTI) is c2a(cpoly, out apoly); c1:POLYS_INTI; a2c(apoly,out c1); if (cpoly/=c1)and(cpoly/=-c1) then raise "Failed to convert between a.poly. and c.poly.\n"; end; end; private a2c(apoly:POLYS_INTI, out cpoly:POLYS_INTI) is deg::=apoly.degree; CN:ARRAY{POLYS_INTI}:=POLY_COEFF::AllocCN(deg); cpoly:=#; x::=POLYS_INTI::x; loop z::=deg.downto!((deg+1)/2); cpoly:=cpoly+x^(z*2-deg)*apoly[z]; apoly:=apoly-CN[z*2-deg]*x^(deg-z)*apoly[z]; end; end; private c2a(cpoly:POLYS_INTI, out apoly:POLYS_INTI) is -- a=c.substitute(x-1/x) a:POLYS_INTI:=#; x::=POLYS_INTI::x; cn::=POLYS_INTI::one; cn1::=x^2-1; loop z::=0.upto!(cpoly.degree); a:=a*x+cn*cpoly[z]; cn:=cn*cn1; end; -- apoly=a.substitute(sqrt("t")) apoly:=#; loop i::=a.arr.ind!; j::=i/2; apoly[j]:=apoly[j]+a[i]; end; end; printConway(cpoly:POLYS_INTI) is LOGOUT::Title("Conway","Polynomial"); #LOGOUT+cpoly.str("tex","z",true)+"\n"; LOGOUT::flush; end; printApoly(apoly:POLYS_INTI) is LOGOUT::Title("Alexander","Polynomial"); ps::=""; loop i::=apoly.degree.downto!(0); if (apoly[i]>=0.inti) then #LOGOUT+ps; end; #LOGOUT+apoly[i]; ps:="+"; end; #LOGOUT+"\n"; LOGOUT::flush; end; shared AMat:MAT_POLYS_INTI; shared jPivot:ARRAY{INT}; shared trimN:INT; -- number of free generator shared trimC:INT; -- component of over bridge of deleted relation shared Relator:ARRAY{WORD}; shared g2c:ARRAY{INT}; shared compoN:INT; -- #of component WriteMatrix(p0:INT) is LOGOUT::Title("Alexander","matrix"); zFlg:BOOL; zFlg:=true; degR::=AMat.nr; degG::=AMat.nc; --if p0>degR then p0:=degR; end; --if p0>degG then p0:=degG; end; -- Alexander matrix is the form of -- \pmatrix{ -- diagonal & 0 \cr -- 0 & matrix \cr -- } if (degR=degG)and(p0=degR-1) then p0:=degR; end; -- Write diagonal part. d0:INT:=(p0).min(degR).min(degG);-- length of diagonel part loop i::=1.upto!(trimN); zFlg:=false; #LOGOUT+"diagonal part: 0\n"; end; loop i::=0.upto!(d0-1); j::=jPivot[i]; if (~AMat[i][j].is_one)and(~AMat[i][j].negate.is_one) then zFlg:=false; #LOGOUT+"diagonal part: "+AMat[i][j].str("tex","t",true)+"\n"; end; end; -- Write other part if (p0<degR)or(p0<degG) then sub1:ARRAY{INT}:=#(degR-p0); loop sub1[0.up!]:=p0.upto!(degR-1); end; sub2:ARRAY{INT}:=#(degG-p0); loop sub2[0.up!]:=jPivot[p0.upto!(degG-1)]; end; #LOGOUT+AMat.sub_matrix(sub1,sub2).str_pmatrix("t"); if (p0<degR)and(p0<degG) then zFlg:=false; end; end; if zFlg then #LOGOUT+"0\n"; end; LOGOUT::flush; end; splitMatrix(p0:INT, out diagonal_part:ARRAY{POLYS_INTI}, out SAMat:MAT_POLYS_INTI) is -- split Alexander matrix AMat to diagoanl part and other part. zFlg:BOOL; zFlg:=true; degR::=AMat.nr; degG::=AMat.nc; if (degR=degG)and(p0=degR-1) then p0:=degR; end; -- Get diagonal part. d0:INT:=(p0).min(degR).min(degG);-- length of diagonel part diagonal_part:=#; -- Number of 0-part is trimN. loop i::=0.upto!(d0-1); j::=jPivot[i]; if (AMat[i][j].is_one)or(AMat[i][j].negate.is_one) then ;--remove trivial elsif (AMat[i][j].is_zero) then trimN:=trimN+1; else diagonal_part:=diagonal_part.append(|AMat[i][j]|); end; end; -- Get other part SAMat:=#(degR-p0,degG-p0); if (p0<degR)or(p0<degG) then loop i::=(p0).upto!(degR-1); si::=0.up!; loop SAMat[si][0.up!]:=AMat[i][jPivot[(p0).upto!(degG-1)]]; end; end; end; end; MakeMatrix(TCode:TCODE) is -- RLength KNOT_GROUP::get_Relator(TCode, out Relator, out g2c); #OUT+"Rel:\n"; loop i::=Relator.ind!; #OUT+Relator[i].str+"\n"; end; trimN:=0; trimC:=0; compoN:=TCode[TCode.length].compo; g:INT:=g2c.size-1; r:INT:=Relator.size; jPivot:=#(g); loop i::=jPivot.ind!; jPivot[i]:=i; end; AMat:=#(r,g); AMat.clear; if (r=0)or(g=0) then return; end; loop i::=0.upto!(r-1); -- Make relation with Fox's free differential AMat[i][Relator[i][0]-1]:= AMat[i][Relator[i][0]-1]+(POLYS_INTI::one); AMat[i][Relator[i][1]-1]:= AMat[i][Relator[i][1]-1]+(#POLYS_INTI(1.inti,1)); if Relator[i].w.has_ind(2) then AMat[i][-Relator[i][2]-1]:= AMat[i][-Relator[i][2]-1]-(#POLYS_INTI(1.inti,1)); end; if Relator[i].w.has_ind(3) then AMat[i][-Relator[i][3]-1]:= AMat[i][-Relator[i][3]-1]-(POLYS_INTI::one) end; --#OUT+"AMat "+i.int+"-th relation:" -- +AMat[i][Relator[i][0]-1].str+", " -- +AMat[i][Relator[i][1]-1].str+", " -- +AMat[i][-Relator[i][2]-1].str+", " -- +AMat[i][-Relator[i][3]-1].str+"\n"; end; end; trimMat1(TCode:TCODE) is trimN:=0; -- Set # of "0" element. delR,delG:INT; pt:INT:=0; word:WORD; if TCode.has_band then -- 2-dim knot/link res::=KNOT_GROUP::getCrossR(TCode, inout pt, out word); if res and (pt<TCode.bandStart) then ; end; else -- 1-dim knot/link -- delete a crossing relation res::=KNOT_GROUP::getCrossR(TCode, inout pt, out word); if res and (pt<TCode.bandStart) then trimN:=1; delR:=1; delG:=word[1]; trimC:=g2c[delG]; AMat:=AMat.minor_matrix(delR-1,delG-1); jPivot:=#(AMat.nc); loop i::=jPivot.ind!; jPivot[i]:=i; end; end; end; end; ExtendedAlexanderPoly(ap:POLYS_INTI, ideg:INT) is ap:=ap.reverseDeg; -- The lowest term is strong. c.f. GBASES_INTI_L if (ap.lc.abs)=(1.inti) then ap:=POLYS_INTI::one; else loop f::=ap.factorize.elt!; if (f.lc.abs)=(1.inti) then ap:=ap/f; end; end; end; ap:=ap.reverseDeg; #LOGOUT+"Extended Alexnader Polynomial: "+"A"+ideg.str+" = "+ap.str("tex","t",true)+"\n"; LOGOUT::flush; end; AlexIdeal(trimN:INT,diagonal_part:ARRAY{POLYS_INTI},SAMat:MAT_POLYS_INTI,ideg:INT) is #LOGOUT+"Elementary_ideal_E( "+(ideg-1).str+" ):\n"; -- When free differential method, we must delete __one__ free meridian generator. ap:POLYS_INTI; if ideg<trimN then #LOGOUT+"[\n"+"0\n"+"]\n\n"; return; end; ideg:=ideg-trimN; ddeg::=diagonal_part.size; degr::=ddeg+SAMat.nr; -- number of relator degc::=ddeg+SAMat.nc; -- number of generator mdeg:INT:=degc-ideg; -- degree of minor. if mdeg<=0 then #LOGOUT+"[\n"+"1\n"+"]\n\n"; return; elsif degr<mdeg then #LOGOUT+"[\n"+"0\n"+"]\n\n"; return; end; -- separate "mdeg" to diagonal part "mdegd" and other part mdeg-mdegd. -- (1) 0<=mdegd<=ddeg , (2) 0<=mdeg-mdegd<= min(degr,degc)-ddeg -- (2) means mdegd<=mdeg and mdeg+ddeg-min(degr,degc)<=mdegd. gBases:ARRAY{POLYS_INTI}:=#; loop mdegd::=0.max(mdeg+ddeg-(degr.min(degc))).upto!(ddeg.min(mdeg)); combi3::=#COMBI_NR_STREAM(ddeg,mdegd); c3:ARRAY{INT}; loop while!(combi3.get(out c3)); f3::=POLYS_INTI::one; loop f3:=f3*diagonal_part[c3.elt!(1)-1]; end; if (mdeg-mdegd=0) then gBases:=gBases.append(|f3|); else combi1::=#COMBI_NR_STREAM(degr-ddeg,mdeg-mdegd); c1:ARRAY{INT}; loop while!(combi1.get(out c1)); sub1::=c1.create(c1.size-1); loop sub1[0.up!]:=c1.elt!(1)-1; end; combi2::=#COMBI_NR_STREAM(degc-ddeg,mdeg-mdegd); c2:ARRAY{INT}; loop while!(combi2.get(out c2)); sub2::=c2.create(c2.size-1); loop sub2[0.up!]:=c2.elt!(1)-1; end; gBases:=gBases.append(|SAMat.sub_matrix(sub1,sub2).det*f3|); end; end; end; end; end; --#OUT+"grobner bases:\n"+gBases.str+"\n\n"; gBases:=GBASES_INTI_L::getGBaseIL(gBases,out ap); -- get Grobner bases --#LOGOUT+gBases.str+"\n\n"; #LOGOUT+"[\n"; if gBases.size=0 then #LOGOUT+"0\n"; else loop b::=gBases.elt!; #LOGOUT+b.str("tex","t",true)+"\n"; end; end; #LOGOUT+"]\n"; LOGOUT::flush; ExtendedAlexanderPoly(ap, ideg) end; AlexanderIdeals(p0:INT) is diagonal_part:ARRAY{POLYS_INTI}; SAMat:MAT_POLYS_INTI; splitMatrix(p0,out diagonal_part,out SAMat); -- #OUT+"diagonal-0: "; loop trimN.times!; #OUT+"0,"; end; #OUT+"\n"; -- #OUT+"diagonal: "+diagonal_part+"\n"; -- #OUT+"matrix : "+SAMat.str+"\n"; -- diagonal is: trimN times 0 and diagonal_part loop ideg::=1.upto!(trimN+diagonal_part.size+SAMat.nc-1); --upto #_of_generator-1 AlexIdeal(trimN,diagonal_part,SAMat,ideg); end end; AlexPoly(p0:INT, out apoly:POLYS_INTI) is apoly:=POLYS_INTI::one; --- alex.poly if AMat.nr/=AMat.nc then #OUT+"Alexander matrix is not square.\n"; apoly:=POLYS_INTI::zero; return; end; pw:POLYS_INTI; -- work -- diagonal part countz::=0; -- count "0" loop i::=0.upto!(p0-1); pw:=AMat[i,jPivot[i]]; if pw.is_zero then countz:=countz+1; else apoly:=apoly*pw; end; end; -- non-diagonal part if countz+trimN<=1 then if p0<AMat.nr then mat::=AMat.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; apoly:=apoly*mat.det; end; else apoly:=POLYS_INTI::zero; end; if apoly.is_zero.not then apoly:=apoly.shift_deg(-(apoly.low_deg)); --if (trimN=1)and(compoN>1) then -- apoly:=apoly/(#POLYS_INTI(1.inti,1)-1.inti); --end; if apoly.substitute(1.inti)<0.inti then apoly:=-apoly; end; end; end; APolyOut(p0:INT, testSym:BOOL,use_conway:BOOL) is pa:POLYS_INTI; AlexPoly(p0,out pa); if use_conway then pc:POLYS_INTI; apoly2conway(pa, out pc); printConway(pc); else printApoly(pa); end; if testSym then -- Test symmetry using Murasugi's condition. SYMMET::TestSym(pa); end; end; AlexMat(TCode:TCODE, testSym:BOOL, testGb:BOOL) is AlexMat(TCode,testSym,testGb,false); end; AlexMat(TCode:TCODE, testSym:BOOL, testGb:BOOL, use_conway:BOOL) is rDeg:INT; if testSym then if TCode.has_band then #OUT+"[test cyclic] not support knotting surface.\n"; return; elsif TCode.number_compo/=1 then #OUT+"[test cyclic] not support links.\n"; return; end; end; POLYS_INTI::init; MakeMatrix(TCode); #LOGOUT+"\n"; if AMat.nr<1 or AMat.nc<1 then #LOGOUT+"The "; if TCode[TCode.length].compo=1 then #LOGOUT+"knot"; else #LOGOUT+"link"; end; if AMat.nc<1 then #LOGOUT+" is empty."; else #LOGOUT+" is Trivial."; end; else LOGOUT::LogTime; WriteMatrix(0); LOGOUT::flush; trimMat1(TCode); MAT_POLYS_INTI_REDUCTION::reduce(inout AMat,out jPivot,out rDeg); -- WriteMatrix(0); WriteMatrix(rDeg); LOGOUT::flush; if testGb then AlexanderIdeals(rDeg); end; LOGOUT::flush; if ~TCode.has_band then APolyOut(rDeg,testSym,use_conway); end; end; #LOGOUT+"\n"; LOGOUT::flush; AMat:=#(0,0); end; end;