symmet.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
class SYMMET
class SYMMET is
-- check if knot has symmetries in Murasugi's method.
--
-- c.f. Murasugi, K.,"On periodic knots."
-- Comment.Math.Helv.,46(1971),162-174.
--
-- $K$ be a knot,
-- $K'$ a knot obtain from $K$ dividing by knot symmetry of period $p$.
-- $p$:prime.
--
-- $A$ :Alexander polynomial of K.
-- $Ad$ :Alexander polynomials of K'.
--
-- Then:
-- (a) $ A = Ad^{p} * Ri^{p-1} $ in $ Z_p<t>$ and
-- (b) $Ad | A$ in $Z<t>$.
-- where $R_i = 1 + t + t^2 + t^3 +....+ t^(i-1)$ , $gcd(i,p)=1$ .
--
-- Search pair p and polynomial Ad which admit (a),(b).
-- So knot K can have period p.
--
-- (1)
-- If A=1 then p:=every prime, Ad:=1.
-- So display "p=0".
--
-- Let p:prime. (Set p from prime table and check followings.)
-- (2) Let $A_p$ be $A$ in $Z_p<t>$.
-- $A_p$ be $A (mod) Z_p$.
-- If $A_p$=1 then let $Ad_p=1$ (on $Z_p$),
-- ($Ad_p is $Ad (mod) Z_p$
--
-- (3) search $R_i$ s.t. $R_i^{p-1} | Ap$ (in $Z_p<t>$).
-- Let $Aq := Ap/Ri^(p-1)$. (in $Z_p<t>$ )
-- $Aq$ is $Ad^{p}$ in (a).
--
-- (Aftre here compute in the form of Conway polynomial in this program)
-- (4) Search $Ad_p$ s.t. $Ad_p^p = Aq$ (in $Z_p<t>$ ).
-- ( Now, $Ad_p$ satisfy (a).)
--
-- Make $Ad$ satisfy (b), and $Ad_p = Ad (mod) Z_p$
-- (5) Check if $Ad | A$ in Z<t> .
-- 1996/10 LINUX version
-- 1989,10 K.Kodama
shared prime:INTI;
shared RPoly:POLYS_INTI; -- - 1 1 1 1 1 ....1
shared DegR:INT;
shared cyclic:BOOL;
shared ApolyP:POLYS_INTI; -- Alexander mod prime
shared Cpoly:POLYS_INTI; -- Conway
shared Cdp1:POLYS_INTI; -- degree of Deg0, DegDP. copy of CpS0, Cdp.
shared PolyD:POLYS_INTI; -- poly. of K' on Z
shared DegM:INT;
shared TblS:POLYS_INTI; -- work table TblS,---DegM
shared bottom:INTI;
Alex2Conway(a:POLYS_INTI,out p:POLYS_INTI) is
-- Convert from Alexander poly. to compressed Conway poly.
-- On knot, Deg is even.On Conway poly. s be z^2 , and set p[s],
w:POLYS_INTI;
ALEXMAT::apoly2conway(a,out w);
w.normalize; p:=#;
loop s:INT:=0.up!.int; until!(s*2>w.degree); p[s.card]:=w[(s+s).card]; end;
end;
Conway2Alex(c:POLYS_INTI, out a:POLYS_INTI) is
-- convert from compressed Conway poly. to Alexander poly.
-- On knot, Deg is even.On Conway poly. s be z^2 , and set p[s],
w:POLYS_INTI:=c.substitute(#POLYS_INTI(1.inti,2));
ALEXMAT::conway2apoly(w,out a);
end;
Restore_SetPolyD:BOOL is
-- true if Set
--set polynomial Cd=PolyD[] from TblS[]
--Cdp1(x) : Conway poly. of K' mod Z_p
--x=i+bottom.
--Reconstruct PolyD Conway poly.
-- for K' using TblS[x]=(Cd(x)-Cdp1)DIV prime.
dv,at:INTI;
--#OUT+"TblS="+TblS.str+"\n";
Tbl0::=TblS.copy;
-- Set from high order to lower order
-- with Tbl2(differential of TblS[])
PolyD:=POLYS_INTI::one;
loop deg::=DegM.downto!(1.int);
Tbl2::=Tbl0.copy; dv:=deg.inti.factorial;
loop diff::=deg.downto!(1.int);
loop i::=0.upto!(diff.card-1); Tbl2[i]:=Tbl2[i+1]-Tbl2[i]; end;
end;
at:=Tbl2[0]/dv;
if Tbl2[0]/=(at*dv) then return false; end;
PolyD[deg.card]:=Cdp1[deg.card]+at*prime;
loop i::=0.upto!(deg.card-1);
Tbl0[i]:=Tbl0[i]-at*((bottom+i.inti)^deg);
end;
end;
if (Tbl0[0].is_non_zero) then return false; end;
return true;
end;
Restore_CheckDiv is
-- Check if Ad | Aq ( PolyD | Cpoly) and display.
q,r:POLYS_INTI;
Cpoly.divmod(PolyD,out q,out r);
if ~r.is_zero then return; end; -- not a divisor.
Conway2Alex(PolyD,out q);
cyclic:=true;
#LOGOUT+"period"+prime.str+"?,"+" R(t)="+RPoly.str+" ;"
+" Alexander poly of K'="+q.str+"\n";
return;
end;
Restore_SetVal(ite:INT) is
-- change x= ite+bottom.
-- And compute Cpoly(x), Cdp1(x).
-- Make Cd(x) and TblS[ite]=(Cd(x)-Cdp1(x)) DIV prime.
x::=ite.inti+bottom;
if x.is_zero then
TblS[ite.card]:=x;
if (ite>=DegM) then
if Restore_SetPolyD then Restore_CheckDiv; end;
else Restore_SetVal(ite+1);
end;
return;
end;
V0:INTI:=Cpoly.substitute(x);
V1p:INTI:=Cdp1.substitute(x);
if V0.is_zero then -- Now z2= +1 or -1. so Cpoly=(x-z2)^k*(poly.)
if (V1p.mod(prime)).is_zero then
TblS[ite.card]:=-(V1p/prime);
if (ite>=DegM) then
if Restore_SetPolyD then Restore_CheckDiv; end;
else Restore_SetVal(ite+1);
end;
end;
cp1::=Cpoly.copy;
dp1::=POLYS_INTI::gen_func(|-x, 1.inti|);
loop while!(V0.is_zero); -- delete factor (t-x)
cp1:=cp1/dp1; V0:=cp1.substitute(x);
end;
end;
-- Now V0/=0
V0:=V0.abs; -- V0=Cpoly(x). V1p=Cdp1(x). V1=Cd(x).
-- make V1|V0 and V1=V1p(mod p)
x:=x.abs; V1::=(V1p-((V0+V1p)/prime)*prime);
loop while!(V1<=V0);
if V1.is_zero.not and V0.mod(V1.abs).is_zero and
(V1-1.inti).abs.mod(x).is_zero then
if (V1-V1p).mod(prime).is_zero.not then
#OUT+"failed to set V1.\n";
end;
TblS[ite.card]:=(V1-V1p)/prime;
if (ite>=DegM) then
if Restore_SetPolyD then Restore_CheckDiv; end;
else Restore_SetVal(ite+1);
end;
end;
V1:=V1+prime;
end;
end;
Restore(Cdp:POLYS_INTI) is
-- When Cdp( Conway polynomial for K') is known in Zp[t].
-- Re-construct Conway polynomial in Z[t].
-- Note that Cdp|Cpoly in Z[t].
Cdp1:=Cdp.copy; if Cdp1[0]=(-1).inti then Cdp1:=-Cdp1; end;
if prime.evenly_divides(Cpoly.lc) then DegM:=Cpoly.degree;
else DegM:=Cdp.degree;
end;
bottom:=-(DegM/2).inti;
TblS:=#;
Restore_SetVal(0.int);
end;
Find is
#LOGOUT+"?period "+prime.str+"\n";
end;
----------------following PROCEDUREs work in Zp<t>-------------
divide_Zp(Poly0,PolyDv:POLYS_INTI, out PolyQ:POLYS_INTI):BOOL is
-- true if PolyDv | Poly0. PolyQ:=Poly0/PolyDv
r:POLYS_INTI;
Poly0.divmod_Zp(prime, PolyDv,out PolyQ,out r);
return r.is_zero;
end;
shared CpolyDP,CpolyQ:POLYS_INTI;
shared DegCDP:INT;
Filter_SetPoly(d:INT) is
-- Recursive call --
--We compute as Conway poly.
-- So, must convert Alexander polynomial to Conway poly.
polyQ2:POLYS_INTI;
if d>=DegCDP then
loop i::=(1.inti).upto!(prime-1.inti);
CpolyDP[d.card]:=i;
if divide_Zp(CpolyQ,CpolyDP^(prime.int),out polyQ2)
and (polyQ2.degree.is_zero) and
prime.evenly_divides(polyQ2[0]-1.inti) then
Restore(CpolyDP);
end;
end;
return;
elsif d.is_pos then
loop i::=(0.inti).upto!(prime-1.inti);
CpolyDP[d.card]:=i; Filter_SetPoly(d+1);
end;
return;
else -- d=0
CpolyDP[d.card]:=1.inti; Filter_SetPoly(d+1); return;
end;
end;
Filter is
if ApolyP.degree.is_zero then
RPoly:=#(1.inti); CpolyDP:=#(1.inti); Restore(CpolyDP); return;
end;
Dp:INT;
ApolyQ:POLYS_INTI;
RPoly:=#;
loop DegR:=0.int.upto!(ApolyP.degree.int/(prime.int-1));
RPoly[DegR.card]:=1.inti; -- R(t)
Dp:=ApolyP.degree-DegR*(prime.int-1);
if prime.int.evenly_divides(DegR+1).not and
(prime.int*2).evenly_divides(Dp) and
divide_Zp(ApolyP,RPoly^(prime.int-1),out ApolyQ) then
-- ApolyP = ApolyQ * Ri^{p-1} -- check K~
DegCDP:=Dp/prime.int;
if DegCDP.is_zero then
CpolyDP:=#(1.inti); Restore(CpolyDP);
else
DegCDP:=DegCDP/2; -- degree of Conway-poly of K'
Alex2Conway(ApolyQ, out CpolyQ);
CpolyDP:=#;
Filter_SetPoly(0.int); -- Set CpolyDP[] and Restore to Z<t>
end;
end;
end;
end;
TestSym(apoly:POLYS_INTI) is
-- Main function.
-- Test if apoly has Murasugi's condition on prime.
POLYS_INTI::init;
cyclic:=false;
#LOGOUT+"Now, testing cyclic period of the Knot\n";
-- normalize
apoly:=apoly.shift_deg(-apoly.low_deg).normalize;
-- ap:POLYS_INTI:=#;
-- loop j::=0.upto!(apoly.degree/2); ap[j]:=apoly[j+j]; end;
-- apoly:=ap.normalize;
if apoly.substitute(1.inti)=(-1).inti then apoly:=-apoly; end;
if apoly.degree.is_zero then prime:=0.inti; Find; return; end;
Alex2Conway(apoly,out Cpoly);
if Cpoly[0]=(-1).inti then Cpoly:=-Cpoly; end;
--#OUT+"apoly:\n"; ALEXMAT::printApoly(apoly);
--#OUT+"cpoly:\n"; ALEXMAT::printConway(Cpoly);
loop pn:INTI:=(2.inti).upto!((apoly.degree+1).inti.max(apoly[0].abs));
if ((pn<=(apoly.degree+1).inti)or((apoly[0]%pn).is_zero))
and INTI_EXT::is_prime(pn) then
prime:=pn;
ApolyP:=apoly.mod(prime);
ApolyP:=ApolyP.shift_deg(-ApolyP.low_deg).normalize;
Filter;
end;
end;
if ~cyclic then #LOGOUT+"This knot has no cyclic period.\n"; end;
end;
end;