Skip to content

Lattices

Creation of lattices

Inside a given ambient space

# lattice — Method.

lattice(V::AbsSpace) -> AbsLat

Given an ambient space V, return the lattice with the standard basis matrix. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.

source

# lattice — Method.

lattice(V::AbsSpace, B::PMat ; check::Bool = true) -> AbsLat

Given an ambient space V and a pseudo-matrix B, return the lattice spanned by the pseudo-matrix B inside V. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.

By default, B is checked to be of full rank. This test can be disabled by setting check to false.

source

# lattice — Method.

lattice(V::AbsSpace, basis::MatElem ; check::Bool = true) -> AbsLat

Given an ambient space V and a matrix basis, return the lattice spanned by the rows of basis inside V. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.

By default, basis is checked to be of full rank. This test can be disabled by setting check to false.

source

# lattice — Method.

lattice(V::AbsSpace, gens::Vector) -> AbsLat

Given an ambient space V and a list of generators gens, return the lattice spanned by gens in V. If V is hermitian (resp. quadratic) then the output is a hermitian (resp. quadratic) lattice.

If gens is empty, the function returns the zero lattice in V.

source

Quadratic lattice over a number field

# quadratic_lattice — Method.

quadratic_lattice(K::Field ; gram::MatElem) -> QuadLat

Given a matrix gram and a field K, return the free quadratic lattice inside the quadratic space over K with Gram matrix gram.

source

# quadratic_lattice — Method.

quadratic_lattice(K::Field, B::PMat ; gram = nothing,
                                      check:::Bool = true) -> QuadLat

Given a pseudo-matrix B with entries in a field K return the quadratic lattice spanned by the pseudo-matrix B inside the quadratic space over K with Gram matrix gram.

If gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over K of size the number of columns of B.

By default, B is checked to be of full rank. This test can be disabled by setting check to false.

source

# quadratic_lattice — Method.

quadratic_lattice(K::Field, basis::MatElem ; gram = nothing,
                                             check::Bool = true) -> QuadLat

Given a matrix basis and a field K, return the quadratic lattice spanned by the rows of basis inside the quadratic space over K with Gram matrix gram.

If gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over K of size the number of columns of basis.

By default, basis is checked to be of full rank. This test can be disabled by setting check to false.

source

# quadratic_lattice — Method.

quadratic_lattice(K::Field, gens::Vector ; gram = nothing) -> QuadLat

Given a list of vectors gens and a field K, return the quadratic lattice spanned by the elements of gens inside the quadratic space over K with Gram matrix gram.

If gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over K of size the length of the elements of gens.

If gens is empty, gram must be supplied and the function returns the zero lattice in the quadratic space over K with gram matrix gram.

source

Hermitian lattice over a degree 2 extension

# hermitian_lattice — Method.

hermitian_lattice(E::NumField; gram::MatElem) -> HermLat

Given a matrix gram and a number field E of degree 2, return the free hermitian lattice inside the hermitian space over E with Gram matrix gram.

source

# hermitian_lattice — Method.

hermitian_lattice(E::NumField, B::PMat; gram = nothing,
			             check::Bool = true) -> HermLat

Given a pseudo-matrix B with entries in a number field E of degree 2, return the hermitian lattice spanned by the pseudo-matrix B inside the hermitian space over E with Gram matrix gram.

If gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over E of size the number of columns of B.

By default, B is checked to be of full rank. This test can be disabled by setting check to false.

source

# hermitian_lattice — Method.

hermitian_lattice(E::NumField, basis::MatElem; gram = nothing,
			                    check::Bool = true) -> HermLat

Given a matrix basis and a number field E of degree 2, return the hermitian lattice spanned by the rows of basis inside the hermitian space over E with Gram matrix gram.

If gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over E of size the number of columns of basis.

By default, basis is checked to be of full rank. This test can be disabled by setting check to false.

source

# hermitian_lattice — Method.

hermitian_lattice(E::NumField, gens::Vector ; gram = nothing) -> HermLat

Given a list of vectors gens and a number field E of degree 2, return the hermitian lattice spanned by the elements of gens inside the hermitian space over E with Gram matrix gram.

If gram is not supplied, the Gram matrix of the ambient space will be the identity matrix over E of size the length of the elements of gens.

If gens is empty, gram must be supplied and the function returns the zero lattice in the hermitan space over E with Gram matrix gram.

source

Examples

The two following examples will be used all along this section:

julia> K, a = rationals_as_number_field();


julia> Kt, t = K["t"];


julia> g = t^2 + 7;


julia> E, b = NumberField(g, "b");


julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);


julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];


julia> Lquad = quadratic_lattice(K, gens, gram = D)
Quadratic lattice of rank 3 and degree 3
over
Maximal order of Number field over Rational Field with defining polynomial x - 1
with basis nf_elem[1]

julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);


julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];


julia> Lherm = hermitian_lattice(E, gens, gram = D)
Hermitian lattice of rank 4 and degree 4
over
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>

Note that the format used here is the one given by the internal function Hecke.to_hecke() which prints REPL commands to get back the input lattice.

julia> K, a = rationals_as_number_field();


julia> Kt, t = K["t"];


julia> g = t^2 + 7;


julia> E, b = NumberField(g, "b");


julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);


julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];


julia> Lherm = hermitian_lattice(E, gens, gram = D);


julia> Hecke.to_hecke(Lherm)
Qx, x = PolynomialRing(FlintQQ, "x")
f = x - 1
K, a = NumberField(f, "a", cached = false)
Kt, t = PolynomialRing(K, "t")
g = t^2 + 7
E, b = NumberField(g, "b", cached = false)
D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])]
L = hermitian_lattice(E, gens, gram = D)

Finally, one can access some databases in which are stored several quadratic and hermitian lattices. Up to now, these are not automatically available while running Hecke. It can nonethelss be used in the following way:

julia> qld = Hecke.quadratic_lattice_database()
Quadratic lattices of rank >= 3 with class number 1 or 2
Author: Markus Kirschmer
Source: http://www.math.rwth-aachen.de/~Markus.Kirschmer/forms/
Version: 0.0.1
Number of lattices: 30250

julia> lattice(qld, 1)
Quadratic lattice of rank 3 and degree 3
over
Maximal order of Number field over Rational Field with defining polynomial x - 1
with basis nf_elem[1]

julia> hlb = Hecke.hermitian_lattice_database()
Hermitian lattices of rank >= 3 with class number 1 or 2
Author: Markus Kirschmer
Source: http://www.math.rwth-aachen.de/~Markus.Kirschmer/forms/
Version: 0.0.1
Number of lattices: 570

julia> lattice(hlb, 426)
Hermitian lattice of rank 4 and degree 4
over
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>

Ambient space and rational span

# ambient_space — Method.

ambient_space(L::AbsLat) -> AbsSpace

Return the ambient space of the lattice L. If the ambient space is not known, an error is raised.

source

# rational_span — Method.

rational_span(L::AbsLat) -> AbsSpace

Return the rational span of the lattice L.

source

# basis_matrix_of_rational_span — Method.

basis_matrix_of_rational_span(L::AbsLat) -> MatElem

Return a basis matrix of the rational span of the lattice L.

source

# gram_matrix_of_rational_span — Method.

gram_matrix_of_rational_span(L::AbsLat) -> MatElem

Return the Gram matrix of the rational span of the lattice L.

source

# diagonal_of_rational_span — Method.

diagonal_of_rational_span(L::AbsLat) -> Vector

Return the diagonal of the rational span of the lattice L.

source

Examples

julia> K, a = rationals_as_number_field();


julia> Kt, t = K["t"];


julia> g = t^2 + 7;


julia> E, b = NumberField(g, "b");


julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);


julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];


julia> Lquad = quadratic_lattice(K, gens, gram = D);


julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);


julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];


julia> Lherm = hermitian_lattice(E, gens, gram = D);


julia> ambient_space(Lherm)
Hermitian space over
Relative number field with defining polynomial t^2 + 7
 over Number field over Rational Field with defining polynomial x - 1
with Gram matrix
[1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 1]

julia> rational_span(Lquad)
Quadratic space over
Number field over Rational Field with defining polynomial x - 1
with Gram matrix
[2 2 2; 2 4 2; 2 2 4]

julia> basis_matrix_of_rational_span(Lherm)
[1   0   0   0]
[5   1   0   0]
[3   0   1   0]
[0   0   0   1]

julia> gram_matrix_of_rational_span(Lherm)
[1    5    3   0]
[5   26   15   0]
[3   15   10   0]
[0    0    0   1]

julia> diagonal_of_rational_span(Lquad)
3-element Vector{nf_elem}:
 2
 2
 2

Rational equivalence

# hasse_invariant — Method.

hasse_invariant(L::AbsLat, p::Union{InfPlc, NfOrdIdl}) -> Int

Return the Hasse invariant of the rational span of the lattice L at the place p. The lattice must be quadratic.

source

# witt_invariant — Method.

witt_invariant(L::AbsLat, p::Union{InfPlc, NfOrdIdl}) -> Int

Return the Witt invariant of the rational span of the lattice L at the place p. The lattice must be quadratic.

source

# is_rationally_isometric — Method.

is_rationally_isometric(L::AbsLat, M::AbsLat, p::Union{InfPlc, NfAbsOrdIdl})
                                                                     -> Bool

Return whether the rational spans of the lattices L and M are isometric over the completion at the place p.

source

# is_rationally_isometric — Method.

is_rationally_isometric(L::AbsLat, M::AbsLat) -> Bool

Return whether the rational spans of the lattices L and M are isometric.

source

Examples

For now and for the rest of this section, the examples will include the new lattice Lquad2 which is quadratic. Moreover, all the completions are going to be done at the prime ideal .

julia> K, a = rationals_as_number_field();


julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);


julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];


julia> Lquad = quadratic_lattice(K, gens, gram = D);


julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);


julia> gens = Vector{nf_elem}[map(K, [-35, 25, 0]), map(K, [30, 40, -20]), map(K, [5, 10, -5])];


julia> Lquad2 = quadratic_lattice(K, gens, gram = D)
Quadratic lattice of rank 3 and degree 3
over
Maximal order of Number field over Rational Field with defining polynomial x - 1
with basis nf_elem[1]

julia> OK = maximal_order(K);


julia> p = prime_decomposition(OK, 7)[1][1]
<7, 7>
Norm: 7
Minimum: 7
principal generator 7
two normal wrt: 7

julia> hasse_invariant(Lquad, p), witt_invariant(Lquad, p)
(1, 1)

julia> is_rationally_isometric(Lquad, Lquad2, p)
true

julia> is_rationally_isometric(Lquad, Lquad2)
true

Attributes

Let be a lattice over . We call a pseudo-basis of any sequence of pairs where the 's are fractional (left) ideals of and is a basis of the rational span of , and such that

Note that a pseudo-basis is not unique. Given a pseudo-basis of , we define the corresponding pseudo-matrix of to be the datum consisting of a list of coefficient ideals corresponding to the ideals 's and a matrix whose rows are the coordinates of the 's in the canonical basis of the ambient space of (conversely, given any such pseudo-matrix, one can define the corresponding pseudo-basis).

# rank — Method.

rank(L::AbsLat) -> Int

Return the rank of the underlying module of the lattice L.

source

# degree — Method.

degree(L::AbsLat) -> Int

Return the dimension of the ambient space of the lattice L.

source

# discriminant — Method.

discriminant(L::AbsLat) -> NfOrdFracIdl

Return the discriminant of the lattice L, that is, the generalized index ideal .

source

# base_field — Method.

base_field(L::AbsLat) -> Field

Return the algebra over which the rational span of the lattice L is defined.

source

# base_ring — Method.

base_ring(L::AbsLat) -> Ring

Return the order over which the lattice L is defined.

source

# fixed_field — Method.

fixed_field(L::AbsLat) -> Field

Returns the fixed field of the involution of the lattice L.

source

# fixed_ring — Method.

fixed_ring(L::AbsLat) -> Ring

Return the maximal order in the fixed field of the lattice L.

source

# involution — Method.

involution(L::AbsLat) -> Map

Return the involution of the rational span of the lattice L.

source

# pseudo_matrix — Method.

pseudo_matrix(L::AbsLat) -> PMat

Return a basis pseudo-matrix of the lattice L.

source

# pseudo_basis — Method.

pseudo_basis(L::AbsLat) -> Vector{Tuple{Vector, Ideal}}

Return a pseudo-basis of the lattice L.

source

# coefficient_ideals — Method.

coefficient_ideals(L::AbsLat) -> Vector{NfOrdIdl}

Return the coefficient ideals of a pseudo-basis of the lattice L.

source

# absolute_basis_matrix — Method.

absolute_basis_matrix(L::AbsLat) -> MatElem

Return a -basis matrix of the lattice L.

source

# absolute_basis — Method.

absolute_basis(L::AbsLat) -> Vector

Return a -basis of the lattice L.

source

# generators — Method.

generators(L::AbsLat; minimal = false) -> Vector{Vector}

Return a set of generators of the lattice L over the base ring of L.

If minimal == true, the number of generators is minimal. Note that computing minimal generators is expensive.

source

# gram_matrix_of_generators — Method.

gram_matrix_of_generators(L::AbsLat; minimal::Bool = false) -> MatElem

Return the Gram matrix of a generating set of the lattice L.

If minimal == true, then a minimal generating set is used. Note that computing minimal generators is expensive.

source

Examples

julia> K, a = rationals_as_number_field();


julia> Kt, t = K["t"];


julia> g = t^2 + 7;


julia> E, b = NumberField(g, "b");


julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);


julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];


julia> Lherm = hermitian_lattice(E, gens, gram = D);


julia> rank(Lherm), degree(Lherm)
(4, 4)

julia> discriminant(Lherm)
Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <7, 7>) * [1 0]
(1//2 * <7, 7>) * [0 1]

julia> base_field(Lherm)
Relative number field with defining polynomial t^2 + 7
 over Number field over Rational Field with defining polynomial x - 1

julia> base_ring(Lherm)
Relative maximal order of Relative number field with defining polynomial t^2 + 7
 over Number field over Rational Field with defining polynomial x - 1
with pseudo-basis
(1, 1//1 * <1, 1>)
(b + 1, 1//2 * <1, 1>)

julia> fixed_field(Lherm)
Number field over Rational Field with defining polynomial x - 1

julia> fixed_ring(Lherm)
Maximal order of Number field over Rational Field with defining polynomial x - 1
with basis nf_elem[1]

julia> involution(Lherm)
Map with following data
Domain:
=======
Relative number field with defining polynomial t^2 + 7
 over Number field over Rational Field with defining polynomial x - 1
Codomain:
=========
Relative number field with defining polynomial t^2 + 7
 over Number field over Rational Field with defining polynomial x - 1

julia> pseudo_matrix(Lherm)
Pseudo-matrix over Relative maximal order of Relative number field with defining polynomial t^2 + 7
 over Number field over Rational Field with defining polynomial x - 1
with pseudo-basis
(1, 1//1 * <1, 1>)
(b + 1, 1//2 * <1, 1>)
Fractional ideal with row [1 0 0 0]
Fractional ideal with row [5 1 0 0]
Fractional ideal with row [3 0 1 0]
Fractional ideal with row [0 0 0 1]

julia> pseudo_basis(Lherm)
4-element Vector{Tuple{Vector{Hecke.NfRelElem{nf_elem}}, Hecke.NfRelOrdFracIdl{nf_elem, Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}, Hecke.NfRelElem{nf_elem}}}}:
 ([1, 0, 0, 0], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <7, 28>) * [1 0]
(1//2 * <1, 1>) * [6 1])
 ([5, 1, 0, 0], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//2 * <1, 1>) * [0 1])
 ([3, 0, 1, 0], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//2 * <1, 1>) * [0 1])
 ([0, 0, 0, 1], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//2 * <1, 1>) * [0 1])

julia> coefficient_ideals(Lherm)
4-element Vector{Hecke.NfRelOrdFracIdl{nf_elem, Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}, Hecke.NfRelElem{nf_elem}}}:
 Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <7, 28>) * [1 0]
(1//2 * <1, 1>) * [6 1]
 Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//2 * <1, 1>) * [0 1]
 Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//2 * <1, 1>) * [0 1]
 Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//2 * <1, 1>) * [0 1]

julia> absolute_basis_matrix(Lherm)
[            7               0               0               0]
[1//2*b + 7//2               0               0               0]
[            5               1               0               0]
[5//2*b + 5//2   1//2*b + 1//2               0               0]
[            3               0               1               0]
[3//2*b + 3//2               0   1//2*b + 1//2               0]
[            0               0               0               1]
[            0               0               0   1//2*b + 1//2]

julia> absolute_basis(Lherm)
8-element Vector{Vector{Hecke.NfRelElem{nf_elem}}}:
 [7, 0, 0, 0]
 [1//2*b + 7//2, 0, 0, 0]
 [5, 1, 0, 0]
 [5//2*b + 5//2, 1//2*b + 1//2, 0, 0]
 [3, 0, 1, 0]
 [3//2*b + 3//2, 0, 1//2*b + 1//2, 0]
 [0, 0, 0, 1]
 [0, 0, 0, 1//2*b + 1//2]

julia> generators(Lherm)
4-element Vector{Vector{Hecke.NfRelElem{nf_elem}}}:
 [2, -1, 0, 0]
 [-3, 0, -1, 0]
 [0, 0, 0, -1]
 [b, 0, 0, 0]

julia> gram_matrix_of_generators(Lherm)
[  5     -6   0   -2*b]
[ -6     10   0    3*b]
[  0      0   1      0]
[2*b   -3*b   0      7]

Module operations

Let be a lattice over inside the space . The dual lattice of is defined to be the following lattice over in :

For any fractional (left) ideal of , one can define the lattice to be the lattice over , in the same space , obtained by rescaling the coefficient ideals of a pseudo-basis of by . In another flavour, for any non-zero element , one defines the rescaled lattice to be the lattice over with the same underlying module as (i.e. the same pseudo-bases) but in space .

# + — Method.

+(L::AbsLat, M::AbsLat) -> AbsLat

Return the sum of the lattices L and M.

The lattices L and M must have the same ambient space.

source

# * — Method.

*(a::NumFieldElem, L::AbsLat) -> AbsLat

Return the lattice inside the ambient space of the lattice L.

source

# * — Method.

*(a::NumFieldOrdIdl, L::AbsLat) -> AbsLat

Return the lattice inside the ambient space of the lattice L.

source

# * — Method.

*(a::NumFieldOrdFracIdl, L::AbsLat) -> AbsLat

Return the lattice inside the ambient space of the lattice L.

source

# rescale — Method.

rescale(L::AbsLat, a::NumFieldElem) -> AbsLat

Return the rescaled lattice . Note that this has a different ambient space than the lattice L.

source

# dual — Method.

dual(L::AbsLat) -> AbsLat

Return the dual lattice of the lattice L.

source

# intersect — Method.

intersect(L::AbsLat, M::AbsLat) -> AbsLat

Return the intersection of the lattices L and M.

The lattices L and M must have the same ambient space.

source

# primitive_closure — Method.

primitive_closure(M::AbsLat, N::AbsLat) -> AbsLat

Given two lattices M and N defined over a number field E, with , return the primitive closure of N in M.

One can also use the alias saturate(L, M).

source

# orthogonal_submodule — Method.

orthogonal_submodule(L::AbsLat, M::AbsLat) -> AbsLat

Return the largest submodule of L orthogonal to M.

source

Examples

julia> K, a = rationals_as_number_field();


julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);


julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];


julia> Lquad = quadratic_lattice(K, gens, gram = D);


julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);


julia> gens = Vector{nf_elem}[map(K, [-35, 25, 0]), map(K, [30, 40, -20]), map(K, [5, 10, -5])];


julia> Lquad2 = quadratic_lattice(K, gens, gram = D);


julia> OK = maximal_order(K);


julia> p = prime_decomposition(OK, 7)[1][1];


julia> pseudo_matrix(Lquad + Lquad2)
Pseudo-matrix over Maximal order of Number field over Rational Field with defining polynomial x - 1
with basis nf_elem[1]
1//1 * <2, 2> with row [1 0 0]
1//1 * <1, 1> with row [1 1 0]
1//1 * <1, 1> with row [1 0 1]

julia> pseudo_matrix(intersect(Lquad, Lquad2))
Pseudo-matrix over Maximal order of Number field over Rational Field with defining polynomial x - 1
with basis nf_elem[1]
1//1 * <10, 10> with row [1 0 0]
1//1 * <25, 25> with row [1//5 1 0]
1//1 * <5, 5> with row [0 3 1]

julia> pseudo_matrix(p*Lquad)
Pseudo-matrix over Maximal order of Number field over Rational Field with defining polynomial x - 1
with basis nf_elem[1]
1//1 * <14, 126> with row [1 0 0]
1//1 * <7, 7> with row [1 1 0]
1//1 * <7, 7> with row [1 0 1]

julia> ambient_space(rescale(Lquad,3*a))
Quadratic space over
Number field over Rational Field with defining polynomial x - 1
with Gram matrix
[6 0 0; 0 6 0; 0 0 6]

julia> pseudo_matrix(Lquad)
Pseudo-matrix over Maximal order of Number field over Rational Field with defining polynomial x - 1
with basis nf_elem[1]
1//1 * <2, 2> with row [1 0 0]
1//1 * <1, 1> with row [1 1 0]
1//1 * <1, 1> with row [1 0 1]

Invariants

Let be a lattice over , in the space . We define:

  • the norm of to be the ideal of generated by the squares ;
  • the scale of to be the set ;
  • the volume of to be the index ideal

Note that these are fractional ideals of .

# norm — Method.

norm(L::AbsLat) -> NfOrdFracIdl

Return the norm of the lattice L. This is a fractional ideal of the fixed field of L.

source

# scale — Method.

scale(L::AbsLat) -> NfOrdFracIdl

Return the scale of the lattice L.

source

# volume — Method.

volume(L::AbsLat) -> NfOrdFracIdl

Return the volume of the lattice L.

source

Examples

julia> K, a = rationals_as_number_field();


julia> Kt, t = K["t"];


julia> g = t^2 + 7;


julia> E, b = NumberField(g, "b");


julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);


julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];


julia> Lherm = hermitian_lattice(E, gens, gram = D);


julia> norm(Lherm)
1//1 * <1, 1>
Norm: 1
Minimum: 1
principal generator 1
basis_matrix
[1]
two normal wrt: 2

julia> scale(Lherm)
Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//2 * <1, 1>) * [0 1]

julia> volume(Lherm)
Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <7, 7>) * [1 0]
(1//2 * <7, 7>) * [0 1]

Predicates

Let be a lattice over . It is said to be integral if its scale is an integral ideal, i.e. it is contained in . Moreover, if is a prime ideal in , then is said to be modular (resp. locally modular at ) if there exists a fractional ideal of (resp. an integer ) such that (resp. ).

# is_integral — Method.

is_integral(L::AbsLat) -> Bool

Return whether the lattice L is integral.

source

# is_modular — Method.

is_modular(L::AbsLat) -> Bool, NfOrdFracIdl

Return whether the lattice L is modular. In this case, the second returned value is a fractional ideal of the base algebra of L such that , where is the dual of L.

source

# is_modular — Method.

is_modular(L::AbsLat, p::NfOrdIdl) -> Bool, Int

Return whether the completion of the lattice L at the prime ideal p is modular. If it is the case the second returned value is an integer v such that is -modular.

source

# is_positive_definite — Method.

is_positive_definite(L::AbsLat) -> Bool

Return whether the rational span of the lattice L is positive definite.

source

# is_negative_definite — Method.

is_negative_definite(L::AbsLat) -> Bool

Return whether the rational span of the lattice L is negative definite.

source

# is_definite — Method.

is_definite(L::AbsLat) -> Bool

Return whether the rational span of the lattice L is definite.

source

# can_scale_totally_positive — Method.

can_scale_totally_positive(L::AbsLat) -> Bool, NumFieldElem

Return whether there is a totally positive rescaled lattice of the lattice L. If so, the second returned value is an element such that is totally positive.

source

Examples

julia> K, a = rationals_as_number_field();


julia> Kt, t = K["t"];


julia> g = t^2 + 7;


julia> E, b = NumberField(g, "b");


julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);


julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];


julia> Lherm = hermitian_lattice(E, gens, gram = D);


julia> OK = maximal_order(K);


julia> is_integral(Lherm)
true

julia> is_modular(Lherm)[1]
false

julia> p = prime_decomposition(OK, 7)[1][1];


julia> is_modular(Lherm, p)
(false, 0)

julia> is_positive_definite(Lherm)
true

julia> can_scale_totally_positive(Lherm)
(true, 1)

Local properties

# local_basis_matrix — Method.

local_basis_matrix(L::AbsLat, p::NfOrdIdl; type = :any) -> MatElem

Given a prime ideal p and a lattice L, return a basis matrix of a lattice M such that . Note that if p is an ideal in the base ring of L, the completions are taken at the minimum of p (which is an ideal in the base ring of the order of p).

  • If type == :submodule, the lattice L will be a sublattice of M.
  • If type == :supermodule, the lattice L will be a superlattice of M.
  • If type == :any, there may not be any containment relation between M and L.

source

# jordan_decomposition — Method.

jordan_decomposition(L::AbsLat, p::NfOrdIdl)
                            -> Vector{MatElem}, Vector{MatElem}, Vector{Int}

Return a Jordan decomposition of the completion of the lattice L at a prime ideal p.

The returned value consists of three lists , and of the same length . The completions of the row spans of the matrices yield a Jordan decomposition of into modular sublattices with Gram matrices and scale of -adic valuation .

source

# is_isotropic — Method.

is_isotropic(L::AbsLat, p::Union{NfOrdIdl, InfPlc}) -> Bool

Return whether the completion of the lattice L at the place p is isotropic.

source

Examples

julia> K, a = rationals_as_number_field();


julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);


julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];


julia> Lquad = quadratic_lattice(K, gens, gram = D);


julia> OK = maximal_order(K);


julia> p = prime_decomposition(OK, 7)[1][1];


julia> local_basis_matrix(Lquad, p)
[1   0   0]
[1   1   0]
[1   0   1]

julia> jordan_decomposition(Lquad, p)
(AbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[1 0 0; 0 1 0; 0 0 1]], AbstractAlgebra.Generic.MatSpaceElem{nf_elem}[[2 0 0; 0 2 0; 0 0 2]], [0])

julia> is_isotropic(Lquad, p)
true

Automorphisms for definite lattices

Let and be two lattices over the same extension , inside their respective ambient spaces and . Similarly to homomorphisms of spaces, we define a homomorphism of lattices from to to be an -module homomorphism such that for all , one has

Again, any automorphism of lattices is called an isometry and any monomorphism is called an embedding. We refer to the set of isometries from a lattice to itself as the automorphism group of .

# automorphism_group_order — Method.

automorphism_group_order(L::AbsLat) -> Int

Given a definite lattice L, return the order of the automorphism group of L.

source

# automorphism_group_generators — Method.

automorphism_group_generators(L::AbsLat; ambient_representation::Bool = true)
                                                      -> Vector{MatElem}

Given a definite lattice L, return generators for the automorphism group of L. If ambient_representation == true (the default), the transformations are represented with respect to the ambient space of L. Otherwise, the transformations are represented with respect to the (pseudo-)basis of L.

source

Examples

julia> K, a = rationals_as_number_field();


julia> Kt, t = K["t"];


julia> g = t^2 + 7;


julia> E, b = NumberField(g, "b");


julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);


julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];


julia> Lquad = quadratic_lattice(K, gens, gram = D);


julia> is_definite(Lquad)
true

julia> automorphism_group_order(Lquad)
48

julia> automorphism_group_generators(Lquad)
6-element Vector{AbstractAlgebra.Generic.MatSpaceElem{nf_elem}}:
 [-1 0 0; 0 -1 0; 0 0 -1]
 [1 0 0; 0 -1 0; 0 0 -1]
 [1 0 0; 0 0 -1; 0 -1 0]
 [0 -1 0; 0 0 -1; 1 0 0]
 [1 0 0; 0 1 0; 0 0 -1]
 [0 1 0; 1 0 0; 0 0 1]

Isometry

# is_isometric — Method.

is_isometric(L::AbsLat, M::AbsLat) -> Bool

Return whether the lattices L and M are isometric.

source

# is_isometric_with_isometry — Method.

is_isometric_with_isometry(L::AbsLat, M::AbsLat; ambient_representation::Bool = true)
                                                          -> (Bool, MatElem)

Return whether the lattices L and M are isometric. If this is the case, the second returned value is an isometry T from L to M.

By default, that isometry is represented with respect to the bases of the ambient spaces, that is, where and are the Gram matrices of the ambient spaces of L and M respectively. If ambient_representation == false, then the isometry is represented with respect to the (pseudo-)bases of L and M, that is, where and are the Gram matrices of the (pseudo-)bases of L and M respectively.

source

# is_locally_isometric — Method.

is_locally_isometric(L::AbsLat, M::AbsLat, p::NfOrdIdl) -> Bool

Return whether the completions of the lattices L and M at the prime ideal p are isometric.

source

Examples

julia> K, a = rationals_as_number_field();


julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);


julia> gens = Vector{nf_elem}[map(K, [1, 1, 0]), map(K, [1, 0, 1]), map(K, [2, 0, 0])];


julia> Lquad = quadratic_lattice(K, gens, gram = D);


julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);


julia> gens = Vector{nf_elem}[map(K, [-35, 25, 0]), map(K, [30, 40, -20]), map(K, [5, 10, -5])];


julia> Lquad2 = quadratic_lattice(K, gens, gram = D);


julia> OK = maximal_order(K);


julia> p = prime_decomposition(OK, 7)[1][1];


julia> is_isometric(Lquad, Lquad2)
false

julia> is_locally_isometric(Lquad, Lquad2, p)
true

Maximal integral lattices

# is_maximal_integral — Method.

is_maximal_integral(L::AbsLat, p::NfOrdIdl) -> Bool, AbsLat

Given a lattice L and a prime ideal p of the fixed ring of L, return whether the completion of L at p is maximal integral. If it is not the case, the second returned value is a lattice in the ambient space of L whose completion at p is a minimal overlattice of .

source

# is_maximal_integral — Method.

is_maximal_integral(L::AbsLat) -> Bool, AbsLat

Given a lattice L, return whether L is maximal integral. If it is not, the second returned value is a minimal overlattice of L with integral norm.

source

# is_maximal — Method.

is_maximal(L::AbsLat, p::NfOrdIdl) -> Bool, AbsLat

Given a lattice L and a prime ideal p in the fixed ring of L, check whether the norm of is integral and return whether L is maximal at p. If it is locally integral but not locally maximal, the second returned value is a lattice in the same ambient space of L whose completion at p has integral norm and is a proper overlattice of .

source

# maximal_integral_lattice — Method.

maximal_integral_lattice(L::AbsLat, p::NfOrdIdl) -> AbsLat

Given a lattice L and a prime ideal p of the fixed ring of L, return a lattice M in the ambient space of L which is maximal integral at p and which agrees with L locally at all the places different from p.

source

# maximal_integral_lattice — Method.

maximal_integral_lattice(L::AbsLat) -> AbsLat

Given a lattice L, return a lattice M in the ambient space of L which is maximal integral and which contains L.

source

# maximal_integral_lattice — Method.

maximal_integral_lattice(V::AbsSpace) -> AbsLat

Given a space V, return a lattice in V with integral norm and which is maximal in V satisfying this property.

source

Examples

julia> K, a = rationals_as_number_field();


julia> Kt, t = K["t"];


julia> g = t^2 + 7;


julia> E, b = NumberField(g, "b");


julia> D = matrix(E, 4, 4, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);


julia> gens = Vector{Hecke.NfRelElem{nf_elem}}[map(E, [2, -1, 0, 0]), map(E, [-3, 0, -1, 0]), map(E, [0, 0, 0, -1]), map(E, [b, 0, 0, 0])];


julia> Lherm = hermitian_lattice(E, gens, gram = D);


julia> OK = maximal_order(K);


julia> p = prime_decomposition(OK, 7)[1][1];


julia> is_maximal_integral(Lherm, p)
(false, Hermitian lattice of rank 4 and degree 4
over
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>)

julia> is_maximal_integral(Lherm)
(false, Hermitian lattice of rank 4 and degree 4
over
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>)

julia> is_maximal(Lherm, p)
(false, Hermitian lattice of rank 4 and degree 4
over
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>)

julia> pseudo_basis(maximal_integral_lattice(Lherm, p))
4-element Vector{Tuple{Vector{Hecke.NfRelElem{nf_elem}}, Hecke.NfRelOrdFracIdl{nf_elem, Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}, Hecke.NfRelElem{nf_elem}}}}:
 ([1, 0, 0, 0], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//2 * <1, 1>) * [0 1])
 ([0, 1, 0, 0], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//2 * <1, 1>) * [0 1])
 ([2, 4, 1, 0], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//14 * <1, 1>) * [6 1])
 ([3, 2, 0, 1], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//14 * <1, 1>) * [6 1])

julia> pseudo_basis(maximal_integral_lattice(Lherm))
4-element Vector{Tuple{Vector{Hecke.NfRelElem{nf_elem}}, Hecke.NfRelOrdFracIdl{nf_elem, Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}, Hecke.NfRelElem{nf_elem}}}}:
 ([1, 0, 0, 0], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//2 * <1, 1>) * [0 1])
 ([0, 1, 0, 0], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//2 * <1, 1>) * [0 1])
 ([2, 4, 1, 0], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//14 * <1, 1>) * [6 1])
 ([4, 5, 0, 1], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//14 * <1, 1>) * [6 1])

julia> pseudo_basis(maximal_integral_lattice(ambient_space(Lherm)))
4-element Vector{Tuple{Vector{Hecke.NfRelElem{nf_elem}}, Hecke.NfRelOrdFracIdl{nf_elem, Hecke.NfAbsOrdFracIdl{AnticNumberField, nf_elem}, Hecke.NfRelElem{nf_elem}}}}:
 ([1, 0, 0, 0], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//2 * <1, 1>) * [0 1])
 ([0, 1, 0, 0], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//2 * <1, 1>) * [0 1])
 ([2, 4, 1, 0], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//14 * <1, 1>) * [6 1])
 ([4, 5, 0, 1], Fractional ideal of
Relative maximal order with pseudo-basis (1) * 1//1 * <1, 1>, (b + 1) * 1//2 * <1, 1>
with basis pseudo-matrix
(1//1 * <1, 1>) * [1 0]
(1//14 * <1, 1>) * [6 1])