CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

Views: 418425
#Decompose a element in SL(2,Z[1/p*n]) into product of elements in SL(2,Z[1/n]) and its conjugation by P=[[1,0],[0,p]]
InstallGlobalFunction(SL2ZmElementsDecomposition,
function(g,p)
local 
  i,j,q,k,d,
  S,T,Y,Spr,Tpr,A,B,C,
  l,t,r,m,H,h,K,
  PrimeFactorization,TriangleMatrixDecomposition,InverseOfMatricesList;
S:=[[0,1],[-1,0]];
T:=[[1,0],[1,1]];
Y:=[[0,-1],[1,1]];
l:=[[1,0],[0,1]];
t:=[];
r:=[];
H:=Group(S);
K:=Group(Y);
##########################################
PrimeFactorization:=function(n,p)    #find the power of p in the prime factorization of n
local r,k;
r:=-1;
k:=n;
while IsInt(k) do
  r:=r+1;
  k:=k/p;
od; 
return r;
end;
###########################################
TriangleMatrixDecomposition:=function(g,p) #Decomposition for a upper triangle matrix
				   # with p-factor appears in the numerator of (1,1)-entry
local
      S,T,Spr,r,
      l,q,d,x,id;
S:=[[0,1],[-1,0]];
T:=[[1,0],[1,1]];
Spr:=[[0,p^-1],[-p,0]];
l:=[[1,0],[0,1]];
d:=[];
id:=[[1,0],[0,1]];
while g[1][2]<>0 do
	if g[1][2]*g[2][2]<0 and IsInt(g[2][2]/g[1][2])=false then 
		  q:=Int(g[2][2]/g[1][2])-1;
	else q:=Int(g[2][2]/g[1][2]);
	fi;
	l:=T^(-q)*l;
	g:=T^(-q)*g;
	if AbsoluteValue(g[1][2])>AbsoluteValue(g[2][2]) and g[1][2] <> 0 then
	l:=S*l;
	g:=S*g;
	fi;
od;
l:=l^-1;
x:=PrimeFactorization(NumeratorRat(g[1][1]),p);
r:=[[g[1][1]*p^-x,0],[g[2][1]*p^x,g[2][2]*p^x]];
while x>0 do
  Append(d,[S^3,Spr]);
  x:=x-1;
od;
d[1]:=l*d[1];
if r=-id then d[1]:=S^2*d[1];
else
    if not r=id then Add(d,r);fi;
fi;
return d;
end;
###############################################
InverseOfMatricesList:=function(list)    #input a list of matrices [A,B,C] 
					 #output a list of matrices [C^-1,B^-1,A^-1]
local i,n,d;
n:=Length(list);
d:=[];
for i in [1..n] do
    Add(d,list[n-i+1]^-1);
od;
return d;
end;
###########################################
if p=0 then                #In case of decompose SL(2,Z) into product of elements in C4 and C6
if g=[[1,0],[0,1]] then return [g];fi;
while g[1][2]<>0 do
	if g[1][1]*g[1][2]<0 and IsInt(g[1][1]/g[1][2])=false then 
		  q:=Int(g[1][1]/g[1][2])-1;
	else q:=Int(g[1][1]/g[1][2]);
	fi;
	g:=g*T^(-q);
	q:=-q;
	if q>0 then
	    while q>0 do
		Append(t,[S^3,Y^-1]);
		q:=q-1;
	    od;
	fi;
	if q<0 then
	    while q<0 do
		Append(t,[Y,S^-3]);
		q:=q+1;
	    od;
	fi;
	if AbsoluteValue(g[1][1])<AbsoluteValue(g[1][2]) then
	Add(t,S);
	g:=g*S;
	fi;
od;
#Print("t=",t,"\n");
#Print("g=",g,"\n");
t:=InverseOfMatricesList(t);
if g[1][1]>0 then 
	q:=g[2][1];
	if q>0 then
	    while q>0 do
		Append(r,[S^3,Y^-1]);
		q:=q-1;
	    od;
	fi;
	if q<0 then
	    while q<0 do
		Append(r,[Y,S^-3]);
		q:=q+1;
	    od;
	fi;
else
	Add(r,S^2);
	q:=-g[2][1];
	if q>0 then
	    while q>0 do
		Append(r,[S^3,Y^-1]);
		q:=q-1;
	    od;
	fi;
	if q<0 then
	    while q<0 do
		Append(r,[Y,S^-3]);
		q:=q+1;
	    od;
	fi;
fi;
Append(r,t);
m:=[];
Add(m,r[1]);
for i in [2..Length(r)] do
    if r[i]*r[i-1] in H or r[i]*r[i-1] in K then
	m[Length(m)]:=m[Length(m)]*r[i];
    else
	Add(m,r[i]);
    fi;
od;
r:=[];
Add(r,m[1]);
for i in [2..Length(m)] do
    if m[i]*m[i-1] in H or m[i]*m[i-1] in K then
	r[Length(r)]:=r[Length(r)]*m[i];
    else
	Add(r,m[i]);
    fi;
od;
return r;
else          
# in case of decompose SL(2,Z[1/p*n]) into product of elements in SL(2,Z[1/n]) and its conjugation by P=[[1,0],[0,p]]
if PrimeFactorization(DenominatorRat(g[1][1]),p)+PrimeFactorization(DenominatorRat(g[1][2]),p)+PrimeFactorization(DenominatorRat(g[2][1]),p)+PrimeFactorization(DenominatorRat(g[2][2]),p)=0 then
return [g];
fi;
Spr:=[[0,p^-1],[-p,0]];
Tpr:=[[1,0],[p,1]];
while g[1][1]<>0 do
	if g[1][1]*g[2][1]<0 and IsInt(g[2][1]/g[1][1])=false then 
		  q:=Int(g[2][1]/g[1][1])-1;
	else q:=Int(g[2][1]/g[1][1]);
	fi;
	l:=T^(-q)*l;
	g:=T^(-q)*g;
	if AbsoluteValue(g[1][1])>AbsoluteValue(g[2][1]) then
	l:=S*l;
	g:=S*g;
	fi;
od;
l:=S*l;
g:=S*g;
l:=l^-1;
#Print("l=",l,"\n");
#Print("g=",g,"\n");
k:=PrimeFactorization(NumeratorRat(g[1][1]),p);
if k>0 then 
  d:=TriangleMatrixDecomposition(g,p);
  d[1]:=l*d[1];
else 
  d:=TriangleMatrixDecomposition(g^-1,p);
  #Print("d=",d,"\n");
  if d[Length(d)] in SL2Z(p) and not d[Length(d)] in CongruenceSubgroupGamma0(p) then
      Add(d,l^-1);
      d:=InverseOfMatricesList(d);
   else
      d:=InverseOfMatricesList(d);
      d[1]:=l*d[1];
   fi;
fi;
r:=[d[1]];
for i in [2..Length(d)] do
    if d[i]*d[i-1] in H or d[i]*d[i-1] in K then
	r[Length(r)]:=r[Length(r)]*d[i];
    else
	Add(r,d[i]);
    fi;
od;
return r;
fi;
end);
#T:=[[1,0],[1,1]];S:=[[0,1],[-1,0]];Up1:=[[2,0],[0,2^-1]];Up2:=[[3,0],[0,3^-1]];Y:=[[0,-1],[1,1]];Up3:=[[5,0],[0,5^-1]];