// This magma script is for enumerating subgroups GL_2(Z_2) // we'll start with those that contain -I. genbound := 1; // Each subgroup G is stored in a cartesian product. // Each entry in the catersian product has the form // (i) The index // (ii) The level 2^n // * WARNING! To trick Magma, into working, we declare that the level of // GL_2(Z_2) itself is equal to 2. // (iii) The image of that subgroup in GL_2(Z/2^n Z) // (iv) The maximal subgroups of G, given as pairs // where 2^n is the level of M. // (v) The genus of the corresponding modular curve // (vi) The image of the subgroup in a permutation group // (vii) The subgroup in the list that covers this subgroup with minimal degree. // We arrange the information here so that the group is actually a subgroup of that one. /* Pre-computations */ nbound := 8; // We start by pre-computing // GL(2,Z/2^n Z), permutations groups GL(2,Z/2^n Z)/{ +- 1 } // and maps phi between them // we also precompute kernels of the maps from GL(2,Z/2^m Z) -> // to GL(2,Z/2^n Z) for various m and n printf "Pre-computing!\n"; matgps := [ GL(2,Integers(2^n)) : n in [1..nbound]]; printf "Done!\n"; permgps := <>; mathoms := <>; for n in [1..nbound] do printf "Computing permutation representation %o.\n",n; G := matgps[n]; K := sub; phi, B := CosetAction(G,K); Append(~permgps,B); Append(~mathoms,phi); end for; sl2list := < mathoms[i](SL(2,Integers(2^i))) : i in [1..nbound] >; kerlist := <>; for n in [1..nbound] do tempkerlist := <>; for n2 in [n+1..nbound] do phi := hom< matgps[n2] -> matgps[n] | [ matgps[n]!matgps[n2].i : i in [1..#Generators(matgps[n2])]]>; printf "Storing kernel of GL(2,Z/%oZ) -> GL(2,Z/%oZ).\n",2^n2,2^n; printf "Storing in slot %o, %o.\n",n,#tempkerlist+1; K := Kernel(phi); Append(~tempkerlist,K); end for; Append(~kerlist,tempkerlist); end for; printf "Pre-computations done!\n"; /* HELPER FUNCTIONS */ // This function takes a subgroup of GL_2(Z/2^n Z) and lifts it // to a subgroup of GL_2(Z/2^m Z) for m > n. function liftsub(G,n,m) H2 := GL(2,Integers(2^m)); H3 := GL(2,Integers(2^n)); genlist := []; for g in Generators(G) do Append(~genlist,H2!g); end for; // Add generators for the kernel of GL_2(Z/2^m Z) -> GL_2(Z/2^n Z) return sub