diff --git a/lib/Orru/decsOrru.gd b/lib/Orru/decsOrru.gd index 94b5361c..319fd938 100644 --- a/lib/Orru/decsOrru.gd +++ b/lib/Orru/decsOrru.gd @@ -3,6 +3,7 @@ IsHapRightTransversalSL3ZSubgroup:=NewFilter("IsHapRightTransversalSL3ZSubgroup" DeclareGlobalFunction("HAP_GenericCongruenceSubgroup"); DeclareOperation("FiniteProjectiveLine",[IsInt]); DeclareOperation("FiniteProjectivePlane",[IsInt]); +DeclareOperation("FiniteProjectiveLine_alt",[IsInt]); DeclareGlobalFunction("HAP_FiniteProjectiveLineIntegers"); DeclareGlobalFunction("HAP_FiniteProjectiveLineIntegers_alt"); DeclareGlobalFunction("HAP_FiniteProjectivePlaneIntegers"); diff --git a/lib/Orru/finiteProjectiveSpaces.gi b/lib/Orru/finiteProjectiveSpaces.gi index ffe3b436..27bc7aaf 100644 --- a/lib/Orru/finiteProjectiveSpaces.gi +++ b/lib/Orru/finiteProjectiveSpaces.gi @@ -20,6 +20,12 @@ return HAP_FiniteProjectivePlaneIntegers(n); end); ######################################################## ######################################################## +InstallMethod(FiniteProjectiveLine_alt, +"Finite projective line for the ring Z/nZ", +[IsInt], +function(n) +return HAP_FiniteProjectiveLineIntegers_alt(n); +end); diff --git a/lib/Orru/initOrru.gi b/lib/Orru/initOrru.gi index 4e1b824e..0402f3cd 100644 --- a/lib/Orru/initOrru.gi +++ b/lib/Orru/initOrru.gi @@ -2,3 +2,5 @@ ReadPackageHap( "lib/Orru/subgroups.gi"); ReadPackageHap( "lib/Orru/finiteProjectiveSpaces.gi"); ReadPackageHap( "lib/Orru/HAP_SL3ZSubgroupTree_fast.gi"); ReadPackageHap( "lib/Orru/SL3ZTopHomology.gi"); +ReadPackageHap( "lib/Orru/sl2methodsExtra.gi"); +ReadPackageHap( "lib/Orru/sl3methods.gi"); diff --git a/lib/Orru/sl2methodsExtra.gi b/lib/Orru/sl2methodsExtra.gi new file mode 100644 index 00000000..f4004a1c --- /dev/null +++ b/lib/Orru/sl2methodsExtra.gi @@ -0,0 +1,79 @@ +InstallMethod(CosetPosFunction, + "Returns cosetPos(g) function for the congruence subgroup G", + [ IsIntegerMatrixGroup and IsHAPCongruenceSubgroupGamma0 ], + function(G) + local cosetPos, canonicalRep, n, ProjLine; + + if DimensionOfMatrixGroup(G) <> 2 then + TryNextMethod(); + fi; + + n := LevelOfCongruenceSubgroup(G); + + ProjLine := FiniteProjectiveLine(n); + + 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 := Units(Integers mod n); + if vv[1] mod n = 0 then + return [0,1]; + elif ZmodnZObj(vv[1],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; + + cosetPos := function(g) + local w; + w := canonicalRep(g); + return Position(ProjLine,w); + end; + + return cosetPos; + end); + +InstallMethod(CosetRepFunction, + "Returns cosetPos(g) function for the congruence subgroup G", + [ IsIntegerMatrixGroup and IsHAPCongruenceSubgroupGamma0 ], + function(G) + local cosetOfInt, cosetRep, n, ProjLine, cosetPos; + + if DimensionOfMatrixGroup(G) <> 2 then + TryNextMethod(); + fi; + + n := LevelOfCongruenceSubgroup(G); + + ProjLine := FiniteProjectiveLine(n); + + cosetOfInt := function(i) + local a, c, b, d, gg; + a := ProjLine[i][1]; + c := ProjLine[i][2]; + if a = 0 then + return [[0,-1],[1,0]]; + fi; + gg := Gcdex(a,c); + b := -gg.coeff2; + d := gg.coeff1; + return [[a,b],[c,d]]; + end; + + cosetPos := CosetPosFunction(G); + + cosetRep:=function(g); + return cosetOfInt(cosetPos(g)); + end; + + return cosetRep; + end); \ No newline at end of file diff --git a/lib/Orru/sl3methods.gi b/lib/Orru/sl3methods.gi new file mode 100644 index 00000000..c79fbae5 --- /dev/null +++ b/lib/Orru/sl3methods.gi @@ -0,0 +1,80 @@ +########################################################################## +## +## Methods for 3x3 congruence subgroups of SL3 + +########################################################################## +## +## CosetPosFunction( ) +## +## Returns a function cosetPos(g) giving the position of the coset gG in +## the ambient group. +InstallMethod(CosetPosFunction, +"Returns cosetPos(g) function for the congruence subgroup G", +[ IsIntegerMatrixGroup and IsHAPCongruenceSubgroupGamma0 ], + function(G) + local cosetPos, n, ProjPlane; + if DimensionOfMatrixGroup(G) <> 3 then + TryNextMethod(); + fi; + + n := LevelOfCongruenceSubgroup(G); + + ProjPlane := FiniteProjectivePlane(n); + + cosetPos := function(g) + local v, vv, U, u, w; + v := [g[1][1], g[2][1], g[3][1]]; + vv := List(v, x -> x mod n); + U := Units(Integers mod n); + for u in U do + w := List(vv, x -> (Int(u)*x) mod n); + if w in ProjPlane.Reps then + return Position(ProjPlane.Reps,w); + fi; + od; + end; + + return cosetPos; + end); +########################################################################## +## +## CosetRepFunction( ) +## +## Returns a function cosetPos(g) giving a canonical rpresentative of the +## coset gG in the ambient group. +InstallMethod(CosetRepFunction, +"Returns cosetRep(g) function for the congruence subgroup G", +[ IsIntegerMatrixGroup and IsHAPCongruenceSubgroupGamma0 ], + function(G) + local MatrixInSL3_Hermite, cosetOfInt, cosetRep, n, ProjPlane, cosetPos; + if DimensionOfMatrixGroup(G) <> 3 then + TryNextMethod(); + fi; + + n := LevelOfCongruenceSubgroup(G); + + MatrixInSL3_Hermite := function(v) + local Herm; + Herm := HermiteNormalFormIntegerMatTransform([[v[1]],[v[2]],[v[3]]]); + return Inverse(Herm!.rowtrans); + end; + + ProjPlane := FiniteProjectivePlane(n); + + cosetOfInt:=function(i) + local x,y,z; + x := ProjPlane.Reps[i][1]; + y := ProjPlane.Reps[i][2]; + z := ProjPlane.Reps[i][3]; + + return MatrixInSL3_Hermite([x,y,z]); + end; + + cosetPos := CosetPosFunction(G); + + cosetRep:=function(g); + return cosetOfInt(cosetPos(g)); + end; + + return cosetRep; + end); \ No newline at end of file diff --git a/lib/Orru/subgroups.gi b/lib/Orru/subgroups.gi index a1cdc3fa..b7d2af17 100644 --- a/lib/Orru/subgroups.gi +++ b/lib/Orru/subgroups.gi @@ -124,7 +124,7 @@ function(n,m) G!.index := m*Product(List(SSortedList(Factors(m)), p->1+1/p)); fi; - ProjLine := FiniteProjectiveLine(m); + ProjLine := FiniteProjectiveLine_alt(m); CosetPos := function(g) local v, vv, U, u, w; v := [g[1][1], g[2][1]]; @@ -225,7 +225,7 @@ function(n,m) ProjLine := FiniteProjectiveLine(m); CanonicalRep := function(g) - local v, vv, U, d, dd; + local v, vv, U, d, dd, x, y; v := [g[1][1], g[2][1]]; vv := List(v, x -> x mod m); U := Units(Integers mod m); @@ -236,7 +236,12 @@ function(n,m) else d := Gcd(vv[1],m); dd := m/d; - return [vv[1], vv[2] mod dd]; + 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; @@ -306,7 +311,7 @@ function(G,H) TryNextMethod(); fi; - HAPCongruenceSubgroupTree(H); + #HAPCongruenceSubgroupTree(H); return HAP_TransversalCongruenceSubgroupInAmbientGroup(G,H); end);