Skip to content

Conversation

@simonbrandhorst
Copy link
Collaborator

@simonbrandhorst simonbrandhorst commented Nov 12, 2025

Release notes

  • #5545 Implements the decomposition approach for orthogonal group computation and isometry testing of integer lattices. This results in a vast speedup for lattices which are not generated by their shortest vectors.

@simonbrandhorst
Copy link
Collaborator Author

@ThomasBreuer @StevellM

@simonbrandhorst
Copy link
Collaborator Author

simonbrandhorst commented Nov 12, 2025

@ThomasBreuer as recommended I built a julia action function.
However, it allocates 4x as much when I wrap it as a homomorphism. Can you confirm?
The following code requires this PR.

julia> L1 = integer_lattice(gram=ZZ[2 1 -1 1 -1 -1 0 0 0 0 0 0 0 0 0 1; 1 2 -1 1 -1 0 0 0 0 0 0 0 0 0 0 1; -1 -1 2 0 1 0 0 0 0 0 0 0 0 0 0 -1; 1 1 0 2 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 1 -1 2 0 0 0 0 0 0 0 0 0 0 0; -1 0 0 0 0 2 0 0 0 0 0 0 0 0 0 -1; 0 0 0 0 0 0 2 1 -1 1 -1 -1 -2 -1 -2 -1; 0 0 0 0 0 0 1 2 -1 1 -1 -1 -2 -1 -2 -1; 0 0 0 0 0 0 -1 -1 2 0 0 0 2 0 2 1; 0 0 0 0 0 0 1 1 0 2 -1 -1 -1 -1 -1 0; 0 0 0 0 0 0 -1 -1 0 -1 2 1 1 1 2 1; 0 0 0 0 0 0 -1 -1 0 -1 1 2 1 1 1 1; 0 0 0 0 0 0 -2 -2 2 -1 1 1 4 1 3 2; 0 0 0 0 0 0 -1 -1 0 -1 1 1 1 2 0 0; 0 0 0 0 0 0 -2 -2 2 -1 2 1 3 0 6 3; 1 1 -1 0 0 -1 -1 -1 1 0 1 1 2 0 3 4]);

julia> G,sv = Oscar._isometry_group_via_decomposition(L1);
  0.014559 seconds (121.75 k allocations: 7.040 MiB)

julia> svZ = [matrix(ZZ,1,16,i) for i in sv];

julia> _short_vectors = svZ;

julia> sort!(_short_vectors, lt=Hecke._isless);

julia> w = similar(_short_vectors[1])
[0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]

julia> n = length(_short_vectors)
240

julia> Sn = symmetric_group(n)
Symmetric group of degree 240

julia> act_func(g) = perm(Sn, Oscar._as_perm(w, matrix(g), _short_vectors))
act_func (generic function with 1 method)

julia> fG = hom(G, Sn, act_func)
Group homomorphism
  from matrix group of degree 16 over ZZ
  to symmetric group of degree 240

julia> @b act_func(h)
138.059 μs (7 allocs: 4.594 KiB)

julia> @b fG(h)  # 4 times more allocations and a little slower
167.660 μs (283 allocs: 16.953 KiB)

@simonbrandhorst
Copy link
Collaborator Author

Requires thofma/Hecke.jl#2078

Copy link
Member

@StevellM StevellM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are some first comments after a quick look to the PR.

@simonbrandhorst
Copy link
Collaborator Author

simonbrandhorst commented Nov 13, 2025

julia> LL =   [integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -50]),
        integer_lattice(gram=ZZ[-2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; 0 -2 -1 1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1; 0 -1 -2 0 -1 -1 0 0 0 0 0 0 0 0 0 0 0; 0 1 0 -2 1 1 1 0 0 0 0 0 0 0 0 0 -1; 0 -1 -1 1 -2 -1 0 0 0 0 0 0 0 0 0 0 0; 0 -1 -1 1 -1 -2 0 0 0 0 0 0 0 0 0 0 0; 0 -1 0 1 0 0 -2 0 0 0 0 0 0 0 0 0 1; 0 0 0 0 0 0 0 -2 0 0 0 0 0 0 0 0 -1; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 1 0 -1 0 0 1 -1 0 0 0 0 0 0 0 0 -6]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -54]),
        integer_lattice(gram=ZZ[-2 1 -1 -1 1 1 1 0 0 0 0 0 0 0 1 -1 0; 1 -2 0 1 0 0 -1 0 0 0 0 0 0 0 -1 1 0; -1 0 -2 -1 1 1 1 0 0 0 0 0 0 0 1 -1 0; -1 1 -1 -2 1 0 1 0 0 0 0 0 0 0 1 -1 0; 1 0 1 1 -2 -1 -1 0 0 0 0 0 0 0 -1 1 0; 1 0 1 0 -1 -2 -1 0 0 0 0 0 0 0 -1 1 0; 1 -1 1 1 -1 -1 -2 0 0 0 0 0 0 0 -1 1 0; 0 0 0 0 0 0 0 -2 -1 -1 -1 1 -1 1 1 0 0; 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 1 0 0 0; 0 0 0 0 0 0 0 -1 -1 -2 -1 1 -1 1 1 0 0; 0 0 0 0 0 0 0 -1 0 -1 -2 1 0 0 1 0 0; 0 0 0 0 0 0 0 1 1 1 1 -2 1 -1 -1 0 0; 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 1 0 0; 0 0 0 0 0 0 0 1 1 1 0 -1 1 -2 -1 0 0; 1 -1 1 1 -1 -1 -1 1 0 1 1 -1 1 -1 -4 2 0; -1 1 -1 -1 1 1 1 0 0 0 0 0 0 0 2 -4 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -6]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 0 0 0 0 0; 0 0 0 0 0 0 0 0 -1 -2 -1 1 0 0 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 1 1 0 -2 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 -2 1 -1 1 1; 0 0 0 0 0 0 0 0 0 0 0 0 1 -2 0 -1 -1; 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 -2 0 1; 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 0 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 1 0 -4]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 1 1 -1 1 -1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 1 0 -1 1 0 0 0; 0 0 0 0 0 0 0 0 1 1 -2 -1 1 -1 0 0 0; 0 0 0 0 0 0 0 0 1 0 -1 -2 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 1 1 -2 1 0 0 0; 0 0 0 0 0 0 0 0 1 1 -1 -1 1 -2 0 0 0; 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 -2 -1 0; 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 -1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -14]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -56]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 1 -1 1 1 1 0 -1; 0 0 0 0 0 0 0 0 -1 -2 1 -1 1 0 0 0 -1; 0 0 0 0 0 0 0 0 1 1 -2 0 0 0 0 0 1; 0 0 0 0 0 0 0 0 -1 -1 0 -2 1 0 0 0 0; 0 0 0 0 0 0 0 0 1 1 0 1 -2 0 0 0 0; 0 0 0 0 0 0 0 0 1 0 0 0 0 -2 -1 0 1; 0 0 0 0 0 0 0 0 1 0 0 0 0 -1 -2 0 1; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 1; 0 0 0 0 0 0 0 0 -1 -1 1 0 0 1 1 1 -16]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -58]),
julia> LL =   [integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -50]),
        integer_lattice(gram=ZZ[-2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; 0 -2 -1 1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1; 0 -1 -2 0 -1 -1 0 0 0 0 0 0 0 0 0 0 0; 0 1 0 -2 1 1 1 0 0 0 0 0 0 0 0 0 -1; 0 -1 -1 1 -2 -1 0 0 0 0 0 0 0 0 0 0 0; 0 -1 -1 1 -1 -2 0 0 0 0 0 0 0 0 0 0 0; 0 -1 0 1 0 0 -2 0 0 0 0 0 0 0 0 0 1; 0 0 0 0 0 0 0 -2 0 0 0 0 0 0 0 0 -1; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 1 0 -1 0 0 1 -1 0 0 0 0 0 0 0 0 -6]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -54]),
        integer_lattice(gram=ZZ[-2 1 -1 -1 1 1 1 0 0 0 0 0 0 0 1 -1 0; 1 -2 0 1 0 0 -1 0 0 0 0 0 0 0 -1 1 0; -1 0 -2 -1 1 1 1 0 0 0 0 0 0 0 1 -1 0; -1 1 -1 -2 1 0 1 0 0 0 0 0 0 0 1 -1 0; 1 0 1 1 -2 -1 -1 0 0 0 0 0 0 0 -1 1 0; 1 0 1 0 -1 -2 -1 0 0 0 0 0 0 0 -1 1 0; 1 -1 1 1 -1 -1 -2 0 0 0 0 0 0 0 -1 1 0; 0 0 0 0 0 0 0 -2 -1 -1 -1 1 -1 1 1 0 0; 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 1 0 0 0; 0 0 0 0 0 0 0 -1 -1 -2 -1 1 -1 1 1 0 0; 0 0 0 0 0 0 0 -1 0 -1 -2 1 0 0 1 0 0; 0 0 0 0 0 0 0 1 1 1 1 -2 1 -1 -1 0 0; 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 1 0 0; 0 0 0 0 0 0 0 1 1 1 0 -1 1 -2 -1 0 0; 1 -1 1 1 -1 -1 -1 1 0 1 1 -1 1 -1 -4 2 0; -1 1 -1 -1 1 1 1 0 0 0 0 0 0 0 2 -4 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -6]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 0 0 0 0 0; 0 0 0 0 0 0 0 0 -1 -2 -1 1 0 0 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 1 1 0 -2 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 -2 1 -1 1 1; 0 0 0 0 0 0 0 0 0 0 0 0 1 -2 0 -1 -1; 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 -2 0 1; 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 0 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 1 0 -4]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 1 1 -1 1 -1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 1 0 -1 1 0 0 0; 0 0 0 0 0 0 0 0 1 1 -2 -1 1 -1 0 0 0; 0 0 0 0 0 0 0 0 1 0 -1 -2 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 1 1 -2 1 0 0 0; 0 0 0 0 0 0 0 0 1 1 -1 -1 1 -2 0 0 0; 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 -2 -1 0; 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 -1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -14]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -56]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 1 -1 1 1 1 0 -1; 0 0 0 0 0 0 0 0 -1 -2 1 -1 1 0 0 0 -1; 0 0 0 0 0 0 0 0 1 1 -2 0 0 0 0 0 1; 0 0 0 0 0 0 0 0 -1 -1 0 -2 1 0 0 0 0; 0 0 0 0 0 0 0 0 1 1 0 1 -2 0 0 0 0; 0 0 0 0 0 0 0 0 1 0 0 0 0 -2 -1 0 1; 0 0 0 0 0 0 0 0 1 0 0 0 0 -1 -2 0 1; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 1; 0 0 0 0 0 0 0 0 -1 -1 1 0 0 1 1 1 -16]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -58]),
julia> LL =   [integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -50]),
        integer_lattice(gram=ZZ[-2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; 0 -2 -1 1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1; 0 -1 -2 0 -1 -1 0 0 0 0 0 0 0 0 0 0 0; 0 1 0 -2 1 1 1 0 0 0 0 0 0 0 0 0 -1; 0 -1 -1 1 -2 -1 0 0 0 0 0 0 0 0 0 0 0; 0 -1 -1 1 -1 -2 0 0 0 0 0 0 0 0 0 0 0; 0 -1 0 1 0 0 -2 0 0 0 0 0 0 0 0 0 1; 0 0 0 0 0 0 0 -2 0 0 0 0 0 0 0 0 -1; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 1 0 -1 0 0 1 -1 0 0 0 0 0 0 0 0 -6]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -54]),
        integer_lattice(gram=ZZ[-2 1 -1 -1 1 1 1 0 0 0 0 0 0 0 1 -1 0; 1 -2 0 1 0 0 -1 0 0 0 0 0 0 0 -1 1 0; -1 0 -2 -1 1 1 1 0 0 0 0 0 0 0 1 -1 0; -1 1 -1 -2 1 0 1 0 0 0 0 0 0 0 1 -1 0; 1 0 1 1 -2 -1 -1 0 0 0 0 0 0 0 -1 1 0; 1 0 1 0 -1 -2 -1 0 0 0 0 0 0 0 -1 1 0; 1 -1 1 1 -1 -1 -2 0 0 0 0 0 0 0 -1 1 0; 0 0 0 0 0 0 0 -2 -1 -1 -1 1 -1 1 1 0 0; 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 1 0 0 0; 0 0 0 0 0 0 0 -1 -1 -2 -1 1 -1 1 1 0 0; 0 0 0 0 0 0 0 -1 0 -1 -2 1 0 0 1 0 0; 0 0 0 0 0 0 0 1 1 1 1 -2 1 -1 -1 0 0; 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 1 0 0; 0 0 0 0 0 0 0 1 1 1 0 -1 1 -2 -1 0 0; 1 -1 1 1 -1 -1 -1 1 0 1 1 -1 1 -1 -4 2 0; -1 1 -1 -1 1 1 1 0 0 0 0 0 0 0 2 -4 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -6]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 0 0 0 0 0; 0 0 0 0 0 0 0 0 -1 -2 -1 1 0 0 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 1 1 0 -2 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 -2 1 -1 1 1; 0 0 0 0 0 0 0 0 0 0 0 0 1 -2 0 -1 -1; 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 -2 0 1; 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 0 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 1 0 -4]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 1 1 -1 1 -1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 1 0 -1 1 0 0 0; 0 0 0 0 0 0 0 0 1 1 -2 -1 1 -1 0 0 0; 0 0 0 0 0 0 0 0 1 0 -1 -2 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 1 1 -2 1 0 0 0; 0 0 0 0 0 0 0 0 1 1 -1 -1 1 -2 0 0 0; 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 -2 -1 0; 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 -1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -14]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -56]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 1 -1 1 1 1 0 -1; 0 0 0 0 0 0 0 0 -1 -2 1 -1 1 0 0 0 -1; 0 0 0 0 0 0 0 0 1 1 -2 0 0 0 0 0 1; 0 0 0 0 0 0 0 0 -1 -1 0 -2 1 0 0 0 0; 0 0 0 0 0 0 0 0 1 1 0 1 -2 0 0 0 0; 0 0 0 0 0 0 0 0 1 0 0 0 0 -2 -1 0 1; 0 0 0 0 0 0 0 0 1 0 0 0 0 -1 -2 0 1; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 1; 0 0 0 0 0 0 0 0 -1 -1 1 0 0 1 1 1 -16]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -58]),
julia> LL =   [integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -50]),
        integer_lattice(gram=ZZ[-2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; 0 -2 -1 1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1; 0 -1 -2 0 -1 -1 0 0 0 0 0 0 0 0 0 0 0; 0 1 0 -2 1 1 1 0 0 0 0 0 0 0 0 0 -1; 0 -1 -1 1 -2 -1 0 0 0 0 0 0 0 0 0 0 0; 0 -1 -1 1 -1 -2 0 0 0 0 0 0 0 0 0 0 0; 0 -1 0 1 0 0 -2 0 0 0 0 0 0 0 0 0 1; 0 0 0 0 0 0 0 -2 0 0 0 0 0 0 0 0 -1; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 1 0 -1 0 0 1 -1 0 0 0 0 0 0 0 0 -6]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -54]),
        integer_lattice(gram=ZZ[-2 1 -1 -1 1 1 1 0 0 0 0 0 0 0 1 -1 0; 1 -2 0 1 0 0 -1 0 0 0 0 0 0 0 -1 1 0; -1 0 -2 -1 1 1 1 0 0 0 0 0 0 0 1 -1 0; -1 1 -1 -2 1 0 1 0 0 0 0 0 0 0 1 -1 0; 1 0 1 1 -2 -1 -1 0 0 0 0 0 0 0 -1 1 0; 1 0 1 0 -1 -2 -1 0 0 0 0 0 0 0 -1 1 0; 1 -1 1 1 -1 -1 -2 0 0 0 0 0 0 0 -1 1 0; 0 0 0 0 0 0 0 -2 -1 -1 -1 1 -1 1 1 0 0; 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 1 0 0 0; 0 0 0 0 0 0 0 -1 -1 -2 -1 1 -1 1 1 0 0; 0 0 0 0 0 0 0 -1 0 -1 -2 1 0 0 1 0 0; 0 0 0 0 0 0 0 1 1 1 1 -2 1 -1 -1 0 0; 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 1 0 0; 0 0 0 0 0 0 0 1 1 1 0 -1 1 -2 -1 0 0; 1 -1 1 1 -1 -1 -1 1 0 1 1 -1 1 -1 -4 2 0; -1 1 -1 -1 1 1 1 0 0 0 0 0 0 0 2 -4 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -6]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 0 0 0 0 0; 0 0 0 0 0 0 0 0 -1 -2 -1 1 0 0 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 1 1 0 -2 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 -2 1 -1 1 1; 0 0 0 0 0 0 0 0 0 0 0 0 1 -2 0 -1 -1; 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 -2 0 1; 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 0 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 1 0 -4]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 1 1 -1 1 -1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 1 0 -1 1 0 0 0; 0 0 0 0 0 0 0 0 1 1 -2 -1 1 -1 0 0 0; 0 0 0 0 0 0 0 0 1 0 -1 -2 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 1 1 -2 1 0 0 0; 0 0 0 0 0 0 0 0 1 1 -1 -1 1 -2 0 0 0; 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 -2 -1 0; 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 -1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -14]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -56]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 1 -1 1 1 1 0 -1; 0 0 0 0 0 0 0 0 -1 -2 1 -1 1 0 0 0 -1; 0 0 0 0 0 0 0 0 1 1 -2 0 0 0 0 0 1; 0 0 0 0 0 0 0 0 -1 -1 0 -2 1 0 0 0 0; 0 0 0 0 0 0 0 0 1 1 0 1 -2 0 0 0 0; 0 0 0 0 0 0 0 0 1 0 0 0 0 -2 -1 0 1; 0 0 0 0 0 0 0 0 1 0 0 0 0 -1 -2 0 1; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -2 1; 0 0 0 0 0 0 0 0 -1 -1 1 0 0 1 1 1 -16]),
        integer_lattice(gram=ZZ[-2 -1 -1 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; -1 -2 -1 0 1 -1 0 0 0 0 0 0 0 0 0 0 0; -1 -1 -2 1 1 -1 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -2 -1 0 -1 1 0 0 0 0 0 0 0 0 0; 1 1 1 -1 -2 1 -1 1 0 0 0 0 0 0 0 0 0; -1 -1 -1 0 1 -2 1 -1 0 0 0 0 0 0 0 0 0; 1 0 1 -1 -1 1 -2 1 0 0 0 0 0 0 0 0 0; -1 0 -1 1 1 -1 1 -2 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 -2 -1 -1 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 -1 -2 -1 0 1 -1 0 0 0; 0 0 0 0 0 0 0 0 -1 -1 -2 1 1 -1 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -2 -1 0 -1 1 0; 0 0 0 0 0 0 0 0 1 1 1 -1 -2 1 -1 1 0; 0 0 0 0 0 0 0 0 -1 -1 -1 0 1 -2 1 -1 0; 0 0 0 0 0 0 0 0 1 0 1 -1 -1 1 -2 1 0; 0 0 0 0 0 0 0 0 -1 0 -1 1 1 -1 1 -2 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -58]),

With this PR

julia> @time for L in LL
       @time orthogonal_group(L)
       end
  0.117977 seconds (1.02 M allocations: 65.744 MiB)
  0.101399 seconds (1.27 M allocations: 61.604 MiB)
  0.260657 seconds (1.01 M allocations: 64.580 MiB, 39.46% gc time)
  0.093477 seconds (1.33 M allocations: 51.566 MiB)
  0.086529 seconds (926.39 k allocations: 51.526 MiB)
  0.280857 seconds (1.06 M allocations: 61.636 MiB, 43.84% gc time)
  0.118825 seconds (1.03 M allocations: 65.695 MiB)
  0.097930 seconds (1.01 M allocations: 58.629 MiB)
  0.253046 seconds (1.01 M allocations: 64.901 MiB, 38.34% gc time)
  0.117678 seconds (1.02 M allocations: 65.371 MiB)
  0.314945 seconds (1.76 M allocations: 73.158 MiB, 42.95% gc time)
  0.090528 seconds (974.47 k allocations: 52.152 MiB)
  0.135374 seconds (1.22 M allocations: 74.306 MiB)
  0.282627 seconds (1.02 M allocations: 66.169 MiB, 41.12% gc time)
  0.088725 seconds (992.66 k allocations: 53.354 MiB)
  0.069676 seconds (891.04 k allocations: 40.757 MiB)
  0.054913 seconds (729.31 k allocations: 31.606 MiB)
  0.095627 seconds (1.43 M allocations: 54.230 MiB)
  0.288928 seconds (900.80 k allocations: 44.322 MiB, 50.25% gc time)
  0.088625 seconds (875.55 k allocations: 48.250 MiB)
  0.081170 seconds (1.19 M allocations: 47.754 MiB)
  0.101378 seconds (1.05 M allocations: 60.930 MiB)
  0.310542 seconds (1.31 M allocations: 59.394 MiB, 46.47% gc time)
  0.118717 seconds (1.02 M allocations: 65.378 MiB)
  3.651823 seconds (26.06 M allocations: 1.351 GiB, 23.66% gc time)  #total time

We also beat magma in many cases (Magma does not even terminate for most of these lattices).

for i in [4 .. 24] do
for> time Order(AutomorphismGroup(LL[i]));
for> end for;
67421129932800
Time: 3.570
192631799808000
Time: 0.140

14383174385664000
Time: 4492.240
Killed

Before this PR

julia> @time for L in LL
       @time orthogonal_group(L;algorithm=:decomposition)
       end
  79.253785 seconds (380.74 M allocations: 31.643 GiB, 11.87% gc time, 0.95% compilation time)
150.704756 seconds (722.25 M allocations: 52.659 GiB, 11.73% gc time, 0.05% compilation time)
129.229394 seconds (452.70 M allocations: 36.388 GiB, 11.43% gc time)
 60.312467 seconds (186.74 M allocations: 11.720 GiB, 7.96% gc time, 0.44% compilation time)
488.464346 seconds (2.30 G allocations: 188.982 GiB, 12.82% gc time)
335.924618 seconds (1.51 G allocations: 154.540 GiB, 13.08% gc time)
 99.195115 seconds (471.42 M allocations: 37.169 GiB, 11.52% gc time)
224.945539 seconds (1.07 G allocations: 82.144 GiB, 11.69% gc time)
 67.175203 seconds (303.71 M allocations: 23.834 GiB, 10.84% gc time)
# I lost patience here. Its obviously faster than before by a factor of 100>  in examples where decomposition applies

@simonbrandhorst simonbrandhorst added release notes: use body For PRs: the release notes string is included in the body text of the PR topic: number theory and removed needs hecke update labels Nov 13, 2025
@simonbrandhorst simonbrandhorst added the optimization Simpler/more performant code or more/better tests label Nov 14, 2025
@simonbrandhorst
Copy link
Collaborator Author

Good to go from my side. Further optimization can be done in another PR.

@simonbrandhorst simonbrandhorst enabled auto-merge (squash) November 14, 2025 09:50
@simonbrandhorst simonbrandhorst added the release notes: use title For PRs: the title of this PR is suitable for direct use in the release notes label Nov 14, 2025
@lgoettgens lgoettgens changed the title Isometry testing and groups via decomposition. Isometry testing and groups via decomposition Nov 14, 2025
@lgoettgens
Copy link
Member

This PR currently has two conflicting release note labels. Please remove one of them

@simonbrandhorst simonbrandhorst removed the release notes: use title For PRs: the title of this PR is suitable for direct use in the release notes label Nov 14, 2025
@simonbrandhorst
Copy link
Collaborator Author

Now the CI Enforce PR labels is failing. So that is buggy.

@simonbrandhorst
Copy link
Collaborator Author

I will add back the labels.

@simonbrandhorst simonbrandhorst added the release notes: use title For PRs: the title of this PR is suitable for direct use in the release notes label Nov 14, 2025
@lgoettgens
Copy link
Member

use body does not work right now

@simonbrandhorst simonbrandhorst merged commit 0a85a7e into master Nov 14, 2025
40 of 44 checks passed
@simonbrandhorst simonbrandhorst deleted the sb/decomposition branch November 14, 2025 11:09
@simonbrandhorst simonbrandhorst removed the release notes: use title For PRs: the title of this PR is suitable for direct use in the release notes label Nov 14, 2025
@lgoettgens
Copy link
Member

use body will only work once #5279 is merged, and will require a special syntax. If you just have something written in the PR body, please use to be added and mark the part in the body accordingly, so that someone can copypaste it later on

@simonbrandhorst simonbrandhorst added release notes: to be added PRs introducing changes that should be (but have not yet been) mentioned in the release notes and removed release notes: use body For PRs: the release notes string is included in the body text of the PR labels Nov 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

optimization Simpler/more performant code or more/better tests release notes: to be added PRs introducing changes that should be (but have not yet been) mentioned in the release notes topic: number theory

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants