The function in this section computes the genus of a lattice.
Genus(L) : Lat -> [ Lat ]
Depth: RngIntElt Default:
Given an integral lattice L, enumerate the genus of L by successively constructing p-neighbours and checking on isometry. This is done using the smallest prime p not dividing the determinant of L. In the case that L is odd with odd determinant and has an even neighbour L', the genus of L is obtained from the edges of the neighbouring graph of L'.Note that neighbours with respect to two vectors v_1, v_2 whose images in L/pL lie in the same orbit of ( Aut)(L) on L/pL are isometric. Therefore only orbit representatives of the action of ( Aut)(L) on L/pL are used. The computation of these orbits restricts the range of application of this function to cases where p^(( Rank)(L)) < 10^7.
By default, the system chooses the value for the Depth parameter for the calls to AutomorphismGroup and IsIsometric (see the section on automorphism group and isometry testing) which depends on the rank of L (( Min)( Floor((( Rank)(L) - 5)/2), 4 )). This can be overruled by setting Depth := d.
We use a combination of the automorphism group, isometry and neighbouring functions. The idea is that the neighbouring graph spans the full genus which therefore can be computed by successively generating neighbours and checking them for isometry with already known ones. The automorphism group comes into play, since neighbours with respect to vectors in the same orbit under the automorphism group are isometric.
> L := CoordinateLattice(Lattice("Kappa", 12)); > G := AutomorphismGroup(L); > G2 := ChangeRing(G, GF(2)); > O := Orbits(G2); > [ Norm(L!Rep(o)) : o in O ]; [ 0, 4, 8, 10 ]Hence only the second and third orbit give rise to a neighbour. To obtain an even neighbour, the second vector has to be adjusted by an element of 2 * L such that it has norm divisible by 8.
> v1 := L ! Rep(O[2]); > v1 +:= 2 * Rep({ b : b in Basis(L) | (v1,b) mod 2 eq 1 }); > v2 := L ! Rep(O[3]); > Norm(v1), Norm(v2); 16 8 > L1 := Neighbour(L, v1, 2); > L2 := Neighbour(L, v2, 2); > bool := IsIsometric(L, L1); bool; true > bool := IsIsometric(L, L2); bool; falseSo we obtain only one non-isometric even neighbour of L. To obtain the full genus we can now proceed with L2 in the same way, and do this with the following function EvenGenus. Note that this function is simply one part of the intrinsic function Genus.
> function EvenGenus(L) > // Start with the lattice L > Lambda := [ CoordinateLattice(LLL(L)) ]; > cand := 1; > while cand le #Lambda do > L := Lambda[cand]; > G := ChangeRing( AutomorphismGroup(L), GF(2) ); > // Get the orbits on L/2L > O := Orbits(G); > for o in O do > v := L ! Rep(o); > if not IsZero(v) and Norm(v) mod 4 eq 0 then > // Adjust the vector such that its norm is divisible by 8 > if not Norm(v) mod 8 eq 0 then > v +:= 2 * Rep({ b : b in Basis(L) | (v,b) mod 2 eq 1 }); > end if; > N := LLL(Neighbour(L, v, 2)); > new := true; > for i in [1..#Lambda] do > if IsIsometric(Lambda[i], N) then > new := false; > break i; > end if; > end for; > if new then > Append( Lambda, CoordinateLattice(N)); > end if; > end if; > end for; > cand +:= 1; > end while; > return Lambda; > end function; > > time Lambda := EvenGenus(L); Time: 14.359 > #Lambda; 10 > [ Minimum(L) : L in Lambda ]; [ 4, 2, 2, 2, 2, 2, 2, 2, 2, 2 ] > &+[ 1/#AutomorphismGroup(L) : L in Lambda ]; 4649359/4213820620800We see that the genus consists of 10 classes of lattices where only the Coxeter-Todd lattice has minimum 4 and get the mass of the genus as 4649359/4213820620800.