Unimodular lattices in dimension 29 and other lattices

Gaëtan Chenevier and Olivier Taïbi

This web page is a companion to the paper Unimodular lattices of rank 29 and related even genera of small determinant. Each genus considered in the paper gets a link in Tables 1 and 2 below, pointing to more information on the genus. This includes a complete list of representatives of isometry classes of lattices in the genus, with additional data (isomorphism class of root system, invariant characterizing the isometry class in the genus, cardinality and generators for reduced isometry groups). We give below a convenient method to download all (or a subset) of our lists and explain the formats precisely. We also provide PARI/GP code that allows one to check that our lists are correct and complete.

See here for the table of Weyl orbits of embeddings of root systems used in the main paper.

1. Genera

1.1. Odd unimodular lattices

Table 1: Number # of isometry classes of odd unimodular lattices of rank \(n\) having no norm 1 vector
n 12 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
# 1 1 1 1 1 4 3 12 12 28 49 156 368 1,901 14,493 357,003 38,966,352

1.2. Even lattices of (half-)determinant p

Table 2: Number of isometry classes of even lattices of rank \(n\) and (half-)determinant \(p\)
p\n 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
1 1         1 1 1           2 2 4           32 24 121      
3 1 1   1 1 1   2 1 2   3 2 5   10 6 27   64 31 290   2,827 678 285,825  
5   1 1 1   1 1 3   3 2 5   10 5 21   55 27 210   1,396 352 38,749   24,545,511 2,738,211
7 1 1   1 1 2   3 2 5   8 4 14   37 20 119   513 153 5,535   341,798 44,955 659,641,434  

2. Batch download and format

2.1. Batch download (lists of lattices)

They can be found in the directory lattices. For convenience we provide a script to download (and verify the checksum of) all these files. On a Unix-like system:

  • create a directory lattices and put the files ./lattices/SHA256 and ./lattices/dl_and_verify.sh in it,
  • make the script executable: chmod +x dl_and_verify.sh,
  • make sure that either wget or curl is installed,
  • make sure that sha256sum is installed,
  • from the directory lattices run ./dl_and_verify.sh SHA256 https://olitb.net/pro/uni29/lattices/.

This will download about 18GB of data. If one is only interested in a subset, one can delete lines from the SHA256 file.

2.2. Format

All lists are compressed (gzip format). If using PARI/GP they can simply be imported using readvec(), although the largest ones may not fit into memory.

  • The subdirectory odd_uni contains lists of odd unimodular lattices with no norm 1 vectors. In dimension n up to 28, each line of X[n]_no1.gz corresponds to an isometry class of lattices and has the form [gram,rs,roa,gens,inv] where:

    1. gram is a Gram matrix given in vector format (see the vec_to_gram() function in tools.gp in Code).
    2. rs is the root system given as a string of characters, e.g. "2A1 3E7" (see 2.3.2 below for details).
    3. roa is the cardinality of the reduced isometry group.
    4. gens is a list of generators of the reduced isometry group (matrices given in PARI/GP format, recalled in 2.3.1).
    5. inv is the BV invariant, i.e. fast_marked_HBV(vec_to_gram(gram), []) where the fast_marked_HBV function is defined in eqfminim.gp (see Code).

    To save space in dimension 29 the list is split in two sublists:

    • X29_no1_trivaut.gz contains the list of lattices having non-trivial reduced isometry group, in the same format as above,
    • X29_no1_nontrivaut.gz contains the list of lattices having trivial reduced isometry group (i.e. \(\{1,-w_0\}\) where \(w_0\) is the longest element of the Weyl group, which is never -1 for this genus) and thus each line simply has format [gram,rs,inv].

    In dimension 30 we have only enumerated the isometry classes of odd unimodular lattices with root system \(\emptyset\), \(\mathrm{A}_1\) or \(\mathrm{A}_2\):

    • X30_no1_empty_A1_A2_nontrivaut.gz contains the list of lattices having non-trivial reduced isometry group, each line being of the form [gram,rs,roa,gens,inv,v] where the first five terms are as above and v (a triple [d,x,t]) also realizes the isometry class as a d-neighbor of \(\mathrm{I}_n\) (see function nei(v) in 3 below),
    • X30_no1_empty_trivaut.gz, X30_no1_A1_trivaut.gz and X30_no1_A2_trivaut.gz contain the lists of lattices having trivial reduced isometry group, each line being of the form [d,x,t,inv] where as above v = [d,x,t] realizes a representative of the isometry class as a d-neighbor of \(\mathrm{I}_n\). To save space we do not give a Gram matrix in this case.
  • The subdirectory even_hdiscp contains lists of even lattices of (half-)determinant p where p is 1, 3, 5 or 7, i.e. lattices of determinant p (resp. 2p) in even (resp. odd) dimension. Each file p/X[n].gz has each line corresponding to an isometry class of lattices of (half-)determinant p and dimension n. The format is [gram,rs,roa,gens,inv] where inv is

    • 0 if p is 1 or if the (n,p)-entry in Table 7.3 or 7.4 is black, i.e. if isometry classes in this genus are distinguished by root systems alone,
    • the number of vectors of length 4 if p is 7 and n is 17 or 18,
    • BVhdiscp(gram,p,n) defined in invariants.gp (see 3), i.e. the invariant \(\mathrm{BV}_{n,p}\) defined just before Corollary 7.23, otherwise.

    As for odd lattices long lists are split into X[n]_nontrivaut.gz and X[n]_trivaut.gz (as above lines have format [gram,rs,inv], in all cases the reduced isometry group has a unique non-trivial element \(-w_0\)).

So in all cases isometry classes are distinguished by [rs,inv] (in fact inv alone is enough except for even_hdiscp/p/X[n].gz where p is 1 or [ p is 7 and n is 17 or 18 ]).

2.3. Format details

2.3.1. Matrices

Matrices with more than one line are written [a_{1,1},a_{1,2},...,a_{1,n};...;a_{m,1},...,a_{m,n}]. Unfortunately one by one matrices are denoted by Mat(x) in PARI/GP.

2.3.2. Isomorphism classes of root systems

An isomorphism class of (simply laced, i.e. type ADE) root systems is described by a string which is obtained by concatenating strings mXr corresponding to isotypic components, separated by a single space character. Here m is the multiplicity (omitted if equal to 1), X is the Dynkin type (A, D or E) and r is the rank. Isotypic components are ordered by type and rank, lexicographically.

2.3.3. Orders on root systems

To define the reduced isometry group of a lattice we need to choose an order on its root system. We use the lexicographic order, so that a root is positive if and only if its first non-zero coordinate is positive.

3. Code

Found here. To use the functions defined in the GP scripts it is necessary to compile the two C files (eqfminim.c and orbmod2.c) first. How to do this is platform-dependent: look for the line modules_build in the file pari.cfg provided with your distribution of PARI/GP, and run this command where %s is replaced by eqfminim or orbmod2. This generates two libraries which can then be loaded in GP (see the top of the files eqfminim.gp and orbmod2.gp for how this is done). Loading all.gp (e.g. by running gp all.gp) loads all our functions in an interpreter.

  • tools.gp defines general-purpose functions, in particular the functions gram_to_vec and vec_to_gram which translate between symmetric matrices and vectors (the vector associated to a symmetric matrix gram is composed of the diagonal coefficients gram[i,i], then the coefficients gram[i,i+1], etc). It also defines the function nei([d,x,t]) which computes a Gram matrix of the d-neighbor of \(\mathrm{I}_n\) associated to

    • an integer \(d \geq 2\)
    • an n by 1 matrix x = [x_1;...;x_n] where the coefficients \(x_i\) are non-decreasing and satisfy \(x_1=1\), \(x_n \leq d/2\) and \(x \cdot x \equiv 0 \pmod d\) (resp. \(x \cdot x \equiv 0 \pmod{2d}\)) if \(d\) is odd (resp. even),
    • t is an extra parameter equal to 0 or 1, only needed for d even.

    (For more details see Chenevier, Gaëtan, Unimodular hunting, Algebraic Geometry 12, No. 6, pp. 769–812)

  • rs.gp defines functions related to root systems, in particular root_system(gram) which computes the isomorphism class of the root system of a lattice with Gram matrix gram (a string as explained in 2.3.2) and order_weyl(rs) which computes the order of the Weyl group given such a string rs.
  • eqfminim.gp (relying on eqfminim.c) defines
    • An exact variant of the Fincke-Pohst algorithm, eqfminim(gram, M), where gram is a positive definite Gram matrix with integral coefficients and M is a bound (an integer). It returns [L_1,...,L_M] where L_i is a matrix whose columns are all vectors v of length i (i.e. qfeval(gram,v) is equal to i) whose first non-zero coefficient is positive.
    • A variant of the Plesken-Souvignier algorithm, qfautors(gram), computing the reduced isometry group of the Gram matrix gram, returning a vector whose first two components are its order and a vector of generators. (The other components give additional orbit information, or information useful for profiling.) For qfautors(gram) to be efficient, gram should be the Gram matrix in a basis of short vectors (see good_bases.gp below).
    • A (fast) implementation fast_marked_HBV(gram, mark) of the marked BV invariant (Definition 1.14)
  • invariants.gp uses this function fast_marked_HBV(gram, mark) to implement the invariant \(\mathrm{BV}_{n,p}\) (as defined just before Corollary 7.23 in the paper), as BVhdiscp(gram).
  • good_bases.gp (relying on eqfminim.c) defines
    • good_basis_rand(gram, B), which tries to find (randomly) a basis of vectors of norm (for gram) at most B, prioritizing vectors of length less than B (see Section 4 of Allombert, Bill; Chenevier, Gaëtan, Unimodular hunting. II, Forum Math. Sigma 13, Paper No. e136, 18 p. (2025)).
    • good_basis_hybrid(gram, B), which takes as input a Gram matrix gram which is already LLL-reduced and returns a basis of short vectors (of norm at most B) using a hybrid method (random and deterministic). If such a basis does not exist it will return a basis composed of n-1 vectors of norm at most B and another vector of norm as small as possible, or fall back to good_basis_rand() if such a basis is not found either. This method is generally faster than good_basis_rand().
  • orbmod2.gp (relying on orbmod2.c) defines functions computing orbits in \(\mathbb{F}_2^n\) for a subgroup of \(\operatorname{GL}_n(\mathbb{F}_2)\) (acting on column vectors) given by generators:
    • orbmod2(gens) takes as input a Vec of generators (more precisely, lifts with integral coefficients) and returns a Vec of Vecsmall([len, x]) where len is the cardinality of the orbit and x a representative, given in binary format (so int2binvec(x, n) recovers a Vec with coefficients 0 or 1).
    • fororbmod2(gens, V, block) evaluates block once for each orbit with V equal to (the Vec) [len, v] where len is the cardinality of the orbit and v is a representative (Vec with coefficients 0 or 1).
    • fororbmod2aff(gens, V, block) is a variant for subgroups of the affine group \(\mathbb{F}_2^n \rtimes \operatorname{GL}_n(\mathbb{F}_2)\): gens is now a Vec of pairs [g,t] where g is an n by n matrix with integral coefficients and t is a Vec (or Col) with integral coefficients, representing \(T_t \circ g\) where \(T_t\) is translation by \(t \in \mathbb{F}_2^n\).

The file check.gp contains functions allowing one to check that the lists are correct:

  • that each line is correct: gram represents a lattice in the genus and rs, roa and inv are correct,
  • and that each isomorphism class occurs exactly once (i.e. the invariants are distinct and the total mass is as predicted by the Smith-Minkowski-Siegel mass formula).

Assuming that the directories src and lattices are placed in the same directory, run gp check.gp from within src and the following commands (then wait a few days!):

  • check_all_odd_uni(1,1)
  • check_all_even(1,1)

to check all lists except for odd_uni/X29_no1_*.gz, even_hdiscp/5/X28_*.gz and even_hdiscp/5/X27_*.gz. For these lists the checks do not terminate in reasonable time (on a current computer), so to check them it is necessary to split the lists and run the checks in parallel (ideally, on many computers) using the functions check_rs_inv() and check_roa() defined in check.gp. How to do so is platform-dependent; to check the orders of automorphism groups we recommend mixing the lines during splitting as the lattices for which qfautors takes more time are not uniformly distributed in our lists.