// This magma script is for enumerating subgroups GL_2(Z_2) // Now we're working on those that don't contain -I. // Each group G is stored as a list with five pieces of information: // i) The number of the group , ii) The index of G, iii) the level of G // iv) The group G itself, and v) The name of X_G. /* Pre-computations */ nbound := 7; // 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