Examples

Example LatNF_simple-nflat-example (H32E4)

Some basic functionality with number field lattices will be demonstrated. The standard lattice over (Q)(Sqrt(37)) is created and a sublattice of it is selected.
> K<s37> := QuadraticField(37);
> L := NumberFieldLattice(K,3);
> r := (1+s37)/2;
> vecs:=[L.2+r*L.3, L.2-r*L.3, L.1+r*L.2];
> SUB := sub<L|vecs>;

The same sublattice may be obtained in another way, by directly giving its generating vectors as elements of the ambient space. Further, let S be the sublattice generated by one of the basis vectors of SUB. Then the lattice sum of S and its orthogonal complement O provide another sublattice.

> S2 := NumberFieldLattice([Vector(v) : v in vecs]);
> assert SUB eq S2; // both methods give the same
> S := sub<SUB|[vecs[1]]>; // 1-dimensional sublattice
> O := OrthogonalComplement(SUB, vecs[1]);
> InnerProduct(SUB!O.1, SUB!vecs[1]);
0
> InnerProduct(SUB!O.2, SUB!vecs[1]);
0
> assert IsSublattice(S+O, SUB);
> Norm(Determinant(S+O)/Determinant(SUB));
10201
> assert 101*SUB.2 in (S+O); // the index has norm 101^2
> assert 101*SUB.3 in (S+O);

Example LatNF_nf-second-ex (H32E5)

The next example concerns non-trivial Gram matrices and transformations.
> K<s37> := QuadraticField(37);
> L := NumberFieldLattice(K,3); // standard lattice
> r := (1+s37)/2;
> v1 := Vector([1,2+3*r,-1+4*r]);
> v2 := Vector([1/2,1/3-3*r/2,1+r]);
> LAT := NumberFieldLattice([v1,v2]);
> Norm(Determinant(L+LAT));
1/1296

This lattice is 2-dimensional and has a denominator of 6. Next, while keeping the same basis vectors, the inner product matrix is changed. The resulting lattice is then modified by applying a random transformation matrix (not necessarily of unit determinant).

> IP := DiagonalMatrix([(s37-1)/2,1,1]);
> LATG := NumberFieldLattice([v1,v2] : InnerProduct:=IP);
> R := Matrix(2,2, [s37,1, -1,(1+s37)/2]);
> NEW := R*LATG;
> BasisMatrix(NEW);
[     1/2*(2*s37 + 1)  1/12*(33*s37 + 661)    1/2*(3*s37 + 151)]
[       1/4*(s37 - 3) 1/12*(-25*s37 - 211)             -s37 + 9]
> InnerProductMatrix(NEW);
[1/2*(s37 - 1)             0             0]
[            0             1             0]
[            0             0             1]
> Determinant(R)^2*Determinant(LATG) eq Determinant(R*LATG);
true

If an integral transformation has determinant 1, then the resulting lattices are equal.

> Y := Matrix(3,3,[1,0,0, (1+s37)/2,1,0, -s37,-1,1]);
> Z := Matrix(3,3,[1,0,0, (-1+s37)/2,1,0, 2,s37,1]);
> TYZ := Y*Transpose(Z); // TYZ has determinant 1
> L eq TYZ*L;
true
> LYZ := NumberFieldLattice(K,3 : Gram:=TYZ*Transpose(TYZ));
> IsIsometric(TYZ*L,LYZ); // these have the same pseudoGram matrix
true
[1 0 0]
[0 1 0]
[0 0 1]
> assert PseudoGramMatrix(TYZ*L) eq PseudoGramMatrix(LYZ);
> C := Matrix(3,3,[1,s37,s37^2/2, 0,1,1+s37, 0,0,1]);
> D := Matrix(3,3,[1,(1+s37)/3,-1, 0,1,2+3*s37/4, 0,0,1]);
> TCD := C*Transpose(D);
> IsIsometric(L,TCD*L); // TCD has determinant 1, but is not integral
false
> assert Determinant(TCD) eq 1;
> [Denominator(x) : x in Eltseq(TCD)];
[ 6, 8, 2, 3, 4, 1, 1, 4, 1 ]

The next statement shows that the call to IsIsometric can be expensive in some cases.

> time IsIsometric(LAT,sub<LAT|[v1+v2,2*v1+v2]>); // nontrivial enum
Time: 27.960
true
[1 1]
[2 1]

Example LatNF_nf-lat-sqrt5 (H32E6)

Here we work with lattices over (Q)(√5) that are related to the icosahedron and dodecahedron.
> K<s5> := QuadraticField(5);
> L := NumberFieldLattice(K,3); // standard lattice
> phi := (1-s5)/2; // negative golden ratio
> vecs := [L.2+phi*L.3, L.2-phi*L.3, -L.1-phi*L.2];
> SUB := sub<L|vecs>;
> LAT := NumberFieldLattice([Vector(v) : v in vecs]);
> LAT eq SUB; // either way gives the same lattice
true
> Determinant(LAT); // (1-s5)^2
-2*s5 + 6

The given vectors are all of norm (5 - √5)/2, and their orbit under the automorphism group forms the vertices of a dodecahedron. The automorphism group of this sublattice is a central 2-extension of (Alt)(5), while that of the standard lattice is a central 2-extension of (Sym)(4).

> [Norm(v) : v in vecs];
[ 1/2*(-s5 + 5), 1/2*(-s5 + 5), 1/2*(-s5 + 5) ]
> A := AutomorphismGroup(LAT);
> IsIsomorphic(A/Center(A),AlternatingGroup(5));
true
> B := AutomorphismGroup(L);
> IsIsomorphic(B/Center(B),SymmetricGroup(4));
true

Carefully note that acting on vecs[1] as a member of L by a matrix is different to acting on vecs[1] as a member of LAT by the same matrix, as the action is on the coordinate vectors.

> vecs[1]^(A.1);
(1/2*(-s5 + 1) 1/2*(-s5 + 5)  1/2*(s5 - 3))
> Norm($1); // not the same
1/2*(-9*s5 + 25)
> (LAT!vecs[1])^(A.1);
(1/2*(s5 - 1)            0            1)
> Norm($1); // as desired
1/2*(-s5 + 5)

There are twelve vectors of norm (5 - √5)/2 in the smaller lattice, while there are 24 in the standard lattice.

> #Sphere(L,1); // 6 vectors of norm 1
6
> #Sphere(L,(5-s5)/2); // 24 vectors of this norm
24
> #Sphere(L,3); // 32 of norm 3
32
> assert Set(vecs) subset Set(Sphere(L,(5-s5)/2));
> #Sphere(LAT,1); // no vectors of norm 1
0
> #Sphere(LAT,(5-s5)/2); // 12 vectors of this norm
12
> #Sphere(LAT,3); // 20 of norm 3
20
> Lvecs := ChangeUniverse(vecs, LAT);
> assert Set(Lvecs) subset Set(Sphere(LAT,(5-s5)/2));

The orbit of the 12 vectors of norm (5 - √5)/2 in LAT is complete under the automorphism group. By taking a 3-sided face of the icosahedron, or a 5-sided face of the dodecahedron (vectors of norm 3), its action under the group automorphisms will give all such faces.

> Set(Sphere(LAT,(5-s5)/2)) eq Orbit(A,Lvecs[1]);
true
> FACE3 := {LAT.1,LAT.2,LAT.3}; // vertices of a face
> #(FACE3^A); // all 20 faces, each vertex appears 5 times
20
> Multiplicities(Multiset(&cat[SetToSequence(x) : x in FACE3^A]));
[ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 ]
> assert &and[Norm(InnerProduct(a,b)) eq -1 : a,b in FACE3 | a ne b];
> // now the dodecahedron
> S3 := Sphere(LAT,3);
> w1 := LAT ! [(1+s5)/2,0,-(1-s5)/2];
> w2 := LAT ! [1,-1,-1];
> w3 := LAT ! [1,-1,1];
> w4 := LAT ! [(1+s5)/2,0,(1-s5)/2];
> w5 := LAT ! [-(1-s5)/2,-(1+s5)/2,0];
> FACE5 := {w1,w2,w3,w4,w5}; // vertices of a face
> #(FACE5^A); // all 12 faces, each vertex appears thrice
12
> Multiplicities(Multiset(&cat[SetToSequence(x) : x in FACE5^A]));
[ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 ]
> O1 := OrthogonalComplement(LAT,w1);
> O2 := OrthogonalComplement(LAT,w2);
> IsIsometric(O1,O2);
true
[      -s5 + 3   1/2*(s5 + 1)]
[  1/2*(s5 + 3) 1/2*(3*s5 + 7)]

Example LatNF_nflat-notsimple (H32E7)

Here are some more examples with nontrivial coefficient ideals.

> K<u> := QuadraticField(257); // class number 3
> O := Integers(K);
> v1 := Vector([K|1,0,0]);
> v2 := Vector([K|0,u,0]);
> p2 := Factorization(2*O)[1][1]; // nonprincipal
> Js := [(2*O)/p2,2*O];
> L := NumberFieldLattice([v1,v2] : Ideals:=Js);
> IsFree(L);
false
> DS := DirectSum([L,L,L]); // Steinitz class is principal
> S := SimpleLattice(DS);
> DS eq S;
true

The automorphism group in the presence of nontrivial coefficient ideals need not have integral transforms on the pseudobasis.

> K<u> := QuadraticField(5);
> O := Integers(K);
> Vs := [Vector([K|2,0,1]),Vector([K|0,1,2])];
> Js := [1*O,2*O];
> G := DiagonalMatrix([K|4,1]);
> L := NumberFieldLattice(Vs : Gram:=G,Ideals:=Js);
> AutomorphismGroup(L);
MatrixGroup(2, K) of order 2^3
Generators:
    [ 1  0]    [-1  0]    [ 0   -2]
    [ 0 -1]    [ 0 -1]    [-1/2  0]
> A := AutomorphismGroup(L : NaturalAction);
> L*(&*Generators(A)) eq L;
true

The enumeration code with Sphere is also consistent with coefficient ideals, and the vectors are always returned in the ambient.

> Sphere(L,4);
{ (2 0 1), (-2  0 -1), (0 2 4), ( 0 -2 -4) }
> Sphere(L,8);
{ ( 2 -2 -3), (-2  2  3), (2 2 5), (-2 -2 -5) }
> Sphere(L,20 : Negatives:=false);
{ (2*u 0 u), ( 4 -2 -2), ( 2 -4 -7), (2 4 9), (4 2 6), (0 2*u 4*u) }
> [Coordinates(v) : v in $1]; // coordinates
[ (-u 0), ( 2 -2), ( 1 -4), (1 4), (2 2), (0 -2*u) ]

The IsIsometric functionality also works with coefficient ideals. This is demonstrated by first intrinsically transforming a lattice L by a unimodular transform matrix T to get a lattice N, and then finding the isometry between L and N on the ambient space.

> K<u> := QuadraticField(257);
> O := Integers(K);
> v1 := Vector([K|1,0,0]);
> v2 := Vector([K|0,u,0]);
> I := [1*O,2*O];
> G := Matrix(2,2,[K|1,0,0,2]);
> L := NumberFieldLattice([v1,v2] : Gram:=G,Ideals:=I);
> T := Matrix(2,2,[u-1,5,51,u+1]);
> PB :=PseudoBasis(L);
> M := NumberFieldLattice(PB : Gram:=T*G*Transpose(T),Ideals:=I);
> b,U := IsIsometric(T*L,M : NaturalAction); assert b;
> T*L*U^(-1) eq L;
true

Example LatNF_nflat-maass (H32E8)

Maass showed [Maa41] that there is exactly one even 4-dimensional unimodular lattice on (Z)[φ] where φ=(1 + √5)/2 is the golden ratio. The size of its automorphism group is 14400. There are 120 vectors of norm 2.

> K<u> := QuadraticField(5);
> e := (1+u)/2;
> M := Matrix(4,[2,-1,0,1-e, -1,2,-1,e-1, 0,-1,2,-e, 1-e,e-1,-e,2]);
> Determinant(M);
1
> L := NumberFieldLattice(K,4 : Gram:=M);
> Dual(L) eq L; // self-dual, since unimodular
true
> Norm(L); // L is even
Principal Ideal, Generator: 2
> AutomorphismGroup(L);
MatrixGroup(4, K) of order 2^6 * 3^2 * 5^2
> #Sphere(L,2);
120

It was shown by Costello and Hsia [CH87] that there is a unique rootless even 12-dimensional unimodular lattice on (Z)[φ], with automorphism group of size 72576000. This is associated to a (Z)[φ]-structure on the Leech lattice.

To construct this lattice, it is first convenient to transform to coordinates where the hyperbolic decomposition over the prime ideal (2) is more perspicacious, so that the norms are multiples of 4, and the inner products are even except for the first/third and second/fourth vector pairs (this can be done by selecting some vectors of norm 4 that generate the lattice, and then performing suitable transformations). Moving then to the triple sum of the resulting lattice, an index 64 sublattice corresponding to the hyperbolic decomposition is found. Rescaling the inner product yields the desired unimodular lattice.

> H := Matrix(K,4, [     20,   -20*u+8,   u-6,       0,
>                   -20*u+8, -16*u+104, 6*u-8, (1-u)/2,
>                       u-6,     6*u-8,     4,       0,
>                         0,   (1-u)/2,     0,       4]);
> LL := NumberFieldLattice(K,4 : Gram:=H); // det(H) is e^4
> assert IsIsometric(L,LL);
> D := DirectSum([LL,LL,LL]);
> DIAG := [D.1+D.5+D.9, D.2+D.6+D.10];
> ORTHO := [D.3-D.7, D.3-D.11, D.4-D.8, D.4-D.12];
> assert &and[InnerProduct(a,b) eq 0 : a in DIAG, b in ORTHO];
> SUB := (2*D) + sub<D | DIAG cat ORTHO>;
> I6 := IdentityMatrix(K,6);
> T := DiagonalJoin(I6/e,I6); // make determinant be 1
> N := T*InnerProductScaling(SUB,1/2);
> Determinant(N);
1
> Dual(N) eq N; // again self-dual
true
> Norm(N); // and even
Principal Ideal, Generator: 2
> time #AutomorphismGroup(N);
72576000
Time: 1.150
> #Sphere(N,2); // rootless
0
> time #Sphere(N,4 : Negatives:=false);
18900
Time: 6.370
V2.28, 13 July 2023