From bb18d4637756a06dc2ac918c3d2ce56690eec928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giulia=20Orr=C3=B9?= Date: Fri, 20 Feb 2026 16:08:57 +0000 Subject: [PATCH 1/3] Add ProjectiveSpace as attribute of the congruence subgroup --- lib/CongruenceGroups/congGroups.gd | 6 ++++++ lib/CongruenceGroups/congGroups.gi | 1 + lib/CongruenceGroups/sl2methods.gi | 15 +++++++++++++++ lib/Orru/sl2methodsExtra.gi | 15 ++++++++------- lib/Orru/sl3methods.gi | 22 +++++++++++++++++++--- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/lib/CongruenceGroups/congGroups.gd b/lib/CongruenceGroups/congGroups.gd index f92b97a9..c159c964 100644 --- a/lib/CongruenceGroups/congGroups.gd +++ b/lib/CongruenceGroups/congGroups.gd @@ -113,6 +113,12 @@ DeclareAttribute( "IndexInAmbientGroup", IsHAPCongruenceSubgroup ); ## is the cubic tree. DeclareAttribute( "StabilizerSubgroup", IsHAPCongruenceSubgroup ); +############################################################################ +## +## ProjectiveSpave( ) +## +DeclareAttribute( "ProjectiveSpace", IsHAPCongruenceSubgroup ); + ############################################################################ ## ## AmbientTransversal( ) diff --git a/lib/CongruenceGroups/congGroups.gi b/lib/CongruenceGroups/congGroups.gi index b82075e3..86d1c2e0 100644 --- a/lib/CongruenceGroups/congGroups.gi +++ b/lib/CongruenceGroups/congGroups.gi @@ -101,6 +101,7 @@ InstallMethod( CongruenceSubgroupGamma0, "for integer matrix group and positive ################################################## ## ## Remaining components to be computed in other functions. + ProjectiveSpace(G); AmbientTransversal(G); CosetPosFunction(G); #A generic method will be used to construct the CosetRepFunction(G); #these two functions except for cases with a diff --git a/lib/CongruenceGroups/sl2methods.gi b/lib/CongruenceGroups/sl2methods.gi index 3dad221f..1acd3f8b 100644 --- a/lib/CongruenceGroups/sl2methods.gi +++ b/lib/CongruenceGroups/sl2methods.gi @@ -23,6 +23,21 @@ return ind; end); +########################################################################## +## +## ProjectiveSpace( ) +InstallMethod(ProjectiveSpace, + "Projective space", + [ IsIntegerMatrixGroup and IsHAPCongruenceSubgroupGamma0 ], + function(G) + local n; + if DimensionOfMatrixGroup(G)>2 then TryNextMethod(); fi; + + n := LevelOfCongruenceSubgroup(G); + + return FiniteProjectiveLine(n); + end); + ########################################################################## ## ## AmbientTransversal( ) diff --git a/lib/Orru/sl2methodsExtra.gi b/lib/Orru/sl2methodsExtra.gi index 0d614da3..4c896761 100644 --- a/lib/Orru/sl2methodsExtra.gi +++ b/lib/Orru/sl2methodsExtra.gi @@ -2,7 +2,7 @@ InstallMethod(CosetPosFunction, "Returns cosetPos(g) function for the congruence subgroup G", [ IsIntegerMatrixGroup and IsHAPCongruenceSubgroupGamma0 ], function(G) - local cosetPos, canonicalRep, n, ProjLine; + local cosetPos, canonicalRep, n, ProjLine, U; if DimensionOfMatrixGroup(G) <> 2 then TryNextMethod(); @@ -14,16 +14,17 @@ InstallMethod(CosetPosFunction, TryNextMethod(); fi; - ProjLine := FiniteProjectiveLine(n); + ProjLine := ProjectiveSpace(G); + + U := Filtered([0..n],i -> Gcd(i,n) = 1); canonicalRep := function(g) - local v, vv, U, d, dd, x, y; + local v, vv, d, dd, x, y; v := [g[1][1], g[2][1]]; vv := List(v, x -> x mod n); - U := Units(Integers mod n); if vv[1] mod n = 0 then return [0,1]; - elif ZmodnZObj(vv[1],n) in U then + elif (vv[1] mod n) in U then return [1,(Inverse(vv[1]) mod n)*vv[2] mod n]; else d := Gcd(vv[1],n); @@ -62,7 +63,7 @@ InstallMethod(CosetRepFunction, TryNextMethod(); fi; - ProjLine := FiniteProjectiveLine(n); + ProjLine := ProjectiveSpace(G); cosetOfInt := function(i) local a, c, b, d, gg; @@ -106,7 +107,7 @@ InstallMethod(CosetRepFunction, TryNextMethod(); fi; - ProjLine := FiniteProjectiveLine(n); + ProjLine := ProjectiveSpace(G); GG:=AmbientGroupOfCongruenceSubgroup(G); diff --git a/lib/Orru/sl3methods.gi b/lib/Orru/sl3methods.gi index a1d34500..20616ae6 100644 --- a/lib/Orru/sl3methods.gi +++ b/lib/Orru/sl3methods.gi @@ -2,6 +2,22 @@ ## ## Methods for 3x3 congruence subgroups of SL3 +########################################################################## +## +## ProjectiveSpace( ) +## + +InstallMethod(ProjectiveSpace, + "Projective space", + [ IsIntegerMatrixGroup and IsHAPCongruenceSubgroupGamma0 ], + function(G) + local n; + if DimensionOfMatrixGroup(G)<>3 then TryNextMethod(); fi; + + n := LevelOfCongruenceSubgroup(G); + + return FiniteProjectivePlane(n); + end); ########################################################################## ## ## CosetPosFunction( ) @@ -19,7 +35,7 @@ InstallMethod(CosetPosFunction, n := LevelOfCongruenceSubgroup(G); - ProjPlane := FiniteProjectivePlane(n); + ProjPlane := ProjectiveSpace(G); cosetPos := function(g) local v, vv, U, u, w; @@ -59,7 +75,7 @@ InstallMethod(CosetRepFunction, return Inverse(Herm!.rowtrans); end; - ProjPlane := FiniteProjectivePlane(n); + ProjPlane := ProjectiveSpace(G); cosetOfInt:=function(i) local x,y,z; @@ -94,7 +110,7 @@ function(G) fi; n := LevelOfCongruenceSubgroup(G); - ProjPlane := FiniteProjectivePlane(n); + ProjPlane := ProjectiveSpace(G); GG:=AmbientGroupOfCongruenceSubgroup(G); cosetPos:=CosetPosFunction(G); From 6b0381a3854ddf10175db455d6f61f1863cbf329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giulia=20Orr=C3=B9?= Date: Fri, 20 Feb 2026 16:21:22 +0000 Subject: [PATCH 2/3] Add CosetPosFunctions for power of primes --- lib/Orru/sl2methodsExtra.gi | 83 +++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/lib/Orru/sl2methodsExtra.gi b/lib/Orru/sl2methodsExtra.gi index 4c896761..918b9608 100644 --- a/lib/Orru/sl2methodsExtra.gi +++ b/lib/Orru/sl2methodsExtra.gi @@ -1,3 +1,82 @@ +# methods for power of primes + +InstallMethod(CosetPosFunction, + "Returns cosetPos(g) function for the congruence subgroup G", + [ IsIntegerMatrixGroup and IsHAPCongruenceSubgroupGamma0 ], + function(G) + local cosetPos, canonicalRep, n, countRep; + + if DimensionOfMatrixGroup(G) <> 2 then + TryNextMethod(); + fi; + + n := LevelOfCongruenceSubgroup(G); + + if not IsPrimePowerInt(n) then + TryNextMethod(); + fi; + + if IsPrime(n) then + TryNextMethod(); + fi; + + canonicalRep := function(g) + local v, vv, U, d, dd, x, y; + v := [g[1][1], g[2][1]]; + vv := List(v, x -> x mod n); + U := Filtered([0..n],i->Gcd(i,n)=1); + if vv[1] mod n = 0 then + return [0,1]; + elif vv[1] mod n in U then + return [1,(Inverse(vv[1]) mod n)*vv[2] mod n]; + else + d := Gcd(vv[1],n); + dd := n/d; + x := vv[1]/d; + y := vv[2]/x mod dd; + while not Gcd(d,y) = 1 do + y := y + dd; + od; + return [d, y]; + fi; + end; + + countRep := function(m) + local p, e, i, countp; + + p := Set(Factors(m))[1]; + e := Length(Factors(m)); + + countp := [1,m]; + + for i in [2..e] do + Add(countp, p^(e-i)*(p-1)); + od; + + return countp; + end; + + cosetPos := function(g) + local w, count, e, U; + w := canonicalRep(g); + + count := countRep(n); + + if w[1] = 0 then + return 1; + elif w[1] = 1 then + U := Filtered([0..n],i -> Gcd(i,n) = 1); + return 2 + Position(U,w[2]); + else + e := Length(Factors(w[1])); + U := Filtered([0..n/w[1]], i-> Gcd(i,n/w[1]) = 1); + return Sum(count{[1..1 + e]}) + Position(U, w[2]); + fi; + end; + + return cosetPos; + end); + InstallMethod(CosetPosFunction, "Returns cosetPos(g) function for the congruence subgroup G", [ IsIntegerMatrixGroup and IsHAPCongruenceSubgroupGamma0 ], @@ -14,6 +93,10 @@ InstallMethod(CosetPosFunction, TryNextMethod(); fi; + if IsPrimePowerInt(n) then + TryNextMethod(); + fi; + ProjLine := ProjectiveSpace(G); U := Filtered([0..n],i -> Gcd(i,n) = 1); From ddc46a412f30bc7e6c8c8cdcaa0bafc209ad841a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giulia=20Orr=C3=B9?= Date: Fri, 20 Feb 2026 16:59:32 +0000 Subject: [PATCH 3/3] Fix case where the first entry of the representative equals 1 --- lib/Orru/sl2methodsExtra.gi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Orru/sl2methodsExtra.gi b/lib/Orru/sl2methodsExtra.gi index 918b9608..7358be85 100644 --- a/lib/Orru/sl2methodsExtra.gi +++ b/lib/Orru/sl2methodsExtra.gi @@ -65,8 +65,8 @@ InstallMethod(CosetPosFunction, if w[1] = 0 then return 1; elif w[1] = 1 then - U := Filtered([0..n],i -> Gcd(i,n) = 1); - return 2 + Position(U,w[2]); + U := [0..n-1]; + return 1 + Position(U,w[2]); else e := Length(Factors(w[1])); U := Filtered([0..n/w[1]], i-> Gcd(i,n/w[1]) = 1);