Lattices
Creation of lattices
Inside a given ambient space
lattice Method
lattice(V::AbstractSpace) -> AbstractLat
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.
lattice Method
lattice(V::AbstractSpace, B::PMat ; check::Bool = true) -> AbstractLat
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.
lattice Method
lattice(V::AbstractSpace, basis::MatElem ; check::Bool = true) -> AbstractLat
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.
lattice Method
lattice(V::AbstractSpace, gens::Vector) -> AbstractLat
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
.
Quadratic lattice over a number field
quadratic_lattice Method
quadratic_lattice(K::Field ; gram::MatElem) -> Union{ZZLat, QuadLat}
Given a matrix gram
and a field K
, return the free quadratic lattice inside the quadratic space over K
with Gram matrix gram
.
If ZZLat
, seen as a lattice over the ring
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.
quadratic_lattice Method
quadratic_lattice(K::Field, basis::MatElem ; gram = nothing,
check::Bool = true)
-> Union{ZZLat, 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.
If ZZLat
, seen as a lattice over the ring
quadratic_lattice Method
quadratic_lattice(K::Field, gens::Vector ; gram = nothing) -> Union{ZZLat, 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
.
If ZZLat
, seen as a lattice over the ring
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
.
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.
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.
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
.
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 = number_field(g, "b");
julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);
julia> gens = Vector{AbsSimpleNumFieldElem}[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 of degree 1 over QQ
with basis AbsSimpleNumFieldElem[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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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 of Relative number field of degree 2 over number field
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 = number_field(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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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 = polynomial_ring(QQ, :x)
f = x - 1
K, a = number_field(f, :a, cached = false)
Kt, t = polynomial_ring(K, :t)
g = t^2 + 7
E, b = number_field(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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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 of degree 1 over QQ
with basis AbsSimpleNumFieldElem[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 of Relative number field of degree 2 over number field
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::AbstractLat) -> AbstractSpace
Return the ambient space of the lattice L
. If the ambient space is not known, an error is raised.
rational_span Method
rational_span(L::AbstractLat) -> AbstractSpace
Return the rational span of the lattice L
.
basis_matrix_of_rational_span Method
basis_matrix_of_rational_span(L::AbstractLat) -> MatElem
Return a basis matrix of the rational span of the lattice L
.
gram_matrix_of_rational_span Method
gram_matrix_of_rational_span(L::AbstractLat) -> MatElem
Return the Gram matrix of the rational span of the lattice L
.
diagonal_of_rational_span Method
diagonal_of_rational_span(L::AbstractLat) -> Vector
Return the diagonal of the rational span of the lattice L
.
Examples
julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(g, "b");
julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);
julia> gens = Vector{AbsSimpleNumFieldElem}[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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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 of dimension 4
over relative number field with defining polynomial t^2 + 7
over number field with defining polynomial x - 1
over rational field
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 of dimension 3
over number field of degree 1 over QQ
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{AbsSimpleNumFieldElem}:
2
2
2
Rational equivalence
hasse_invariant Method
hasse_invariant(L::AbstractLat, p::Union{InfPlc, AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Int
Return the Hasse invariant of the rational span of the lattice L
at the place p
. The lattice must be quadratic.
witt_invariant Method
witt_invariant(L::AbstractLat, p::Union{InfPlc, AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}) -> Int
Return the Witt invariant of the rational span of the lattice L
at the place p
. The lattice must be quadratic.
is_rationally_isometric Method
is_rationally_isometric(L::AbstractLat, M::AbstractLat, p::Union{InfPlc, AbsNumFieldOrderIdeal})
-> Bool
Return whether the rational spans of the lattices L
and M
are isometric over the completion at the place p
.
is_rationally_isometric Method
is_rationally_isometric(L::AbstractLat, M::AbstractLat) -> Bool
Return whether the rational spans of the lattices L
and M
are isometric.
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{AbsSimpleNumFieldElem}[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{AbsSimpleNumFieldElem}[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 of degree 1 over QQ
with basis AbsSimpleNumFieldElem[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
Note that a pseudo-basis is not unique. Given a pseudo-basis
rank Method
rank(L::AbstractLat) -> Int
Return the rank of the underlying module of the lattice L
.
degree Method
degree(L::AbstractLat) -> Int
Return the dimension of the ambient space of the lattice L
.
discriminant Method
discriminant(L::AbstractLat) -> AbsSimpleNumFieldOrderFractionalIdeal
Return the discriminant of the lattice L
, that is, the generalized index ideal
base_field Method
base_field(L::AbstractLat) -> Field
Return the algebra over which the rational span of the lattice L
is defined.
base_ring Method
base_ring(L::AbstractLat) -> Ring
Return the order over which the lattice L
is defined.
fixed_field Method
fixed_field(L::AbstractLat) -> Field
Returns the fixed field of the involution of the lattice L
.
fixed_ring Method
fixed_ring(L::AbstractLat) -> Ring
Return the maximal order in the fixed field of the lattice L
.
involution Method
involution(L::AbstractLat) -> Map
Return the involution of the rational span of the lattice L
.
pseudo_matrix Method
pseudo_matrix(L::AbstractLat) -> PMat
Return a basis pseudo-matrix of the lattice L
.
pseudo_basis Method
pseudo_basis(L::AbstractLat) -> Vector{Tuple{Vector, Ideal}}
Return a pseudo-basis of the lattice L
.
coefficient_ideals Method
coefficient_ideals(L::AbstractLat) -> Vector{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}}
Return the coefficient ideals of a pseudo-basis of the lattice L
.
absolute_basis_matrix Method
absolute_basis_matrix(L::AbstractLat) -> MatElem
Return a L
.
generators Method
generators(L::AbstractLat; 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.
gram_matrix_of_generators Method
gram_matrix_of_generators(L::AbstractLat; 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.
Examples
julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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 with defining polynomial x - 1
over rational field
julia> base_ring(Lherm)
Relative maximal order of Relative number field of degree 2 over number field
with pseudo-basis
(1, 1//1 * <1, 1>)
(b + 1, 1//2 * <1, 1>)
julia> fixed_field(Lherm)
Number field with defining polynomial x - 1
over rational field
julia> fixed_ring(Lherm)
Maximal order of Number field of degree 1 over QQ
with basis AbsSimpleNumFieldElem[1]
julia> involution(Lherm)
Map
from relative number field of degree 2 over number field
to relative number field of degree 2 over number field
julia> pseudo_matrix(Lherm)
Pseudo-matrix over Relative maximal order of Relative number field of degree 2 over number field
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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}, Hecke.RelNumFieldOrderFractionalIdeal{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal, Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}}:
([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.RelNumFieldOrderFractionalIdeal{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal, Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}:
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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}:
[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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}:
[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
For any fractional (left) ideal
+ Method
+(L::AbstractLat, M::AbstractLat) -> AbstractLat
Return the sum of the lattices L
and M
.
The lattices L
and M
must have the same ambient space.
* Method
*(a::NumFieldElem, L::AbstractLat) -> AbstractLat
Return the lattice L
.
* Method
*(a::NumFieldOrderIdeal, L::AbstractLat) -> AbstractLat
Return the lattice L
.
* Method
*(a::NumFieldOrderFractionalIdeal, L::AbstractLat) -> AbstractLat
Return the lattice L
.
rescale Method
rescale(L::AbstractLat, a::NumFieldElem) -> AbstractLat
Return the rescaled lattice L
.
intersect Method
intersect(L::AbstractLat, M::AbstractLat) -> AbstractLat
Return the intersection of the lattices L
and M
.
The lattices L
and M
must have the same ambient space.
primitive_closure Method
primitive_closure(M::AbstractLat, N::AbstractLat) -> AbstractLat
Given two lattices M
and N
defined over a number field E
, with N
in M
.
One can also use the alias saturate(L, M)
.
orthogonal_submodule Method
orthogonal_submodule(L::AbstractLat, M::AbstractLat) -> AbstractLat
Return the largest submodule of L
orthogonal to M
.
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{AbsSimpleNumFieldElem}[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{AbsSimpleNumFieldElem}[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 of degree 1 over QQ
with basis AbsSimpleNumFieldElem[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 of degree 1 over QQ
with basis AbsSimpleNumFieldElem[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 of degree 1 over QQ
with basis AbsSimpleNumFieldElem[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 of dimension 3
over number field of degree 1 over QQ
with gram matrix
[6 0 0]
[0 6 0]
[0 0 6]
julia> pseudo_matrix(Lquad)
Pseudo-matrix over Maximal order of Number field of degree 1 over QQ
with basis AbsSimpleNumFieldElem[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]
Categorical constructions
Given finite collections of lattices, one can construct their direct sums, which are also direct products in this context. They are also sometimes called biproducts. Depending on the user usage, it is possible to call one of the following functions.
direct_sum Method
direct_sum(x::Vararg{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}
direct_sum(x::Vector{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}
Given a collection of quadratic or hermitian lattices
For objects of type AbstractLat
, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L
as a direct product with the projections direct_product(x)
. If one wants to obtain L
as a biproduct with the injections biproduct(x)
.
direct_sum(g1::QuadSpaceCls, g2::QuadSpaceCls) -> QuadSpaceCls
Return the isometry class of the direct sum of two representatives.
direct_product Method
direct_product(algebras::StructureConstantAlgebra...; task::Symbol = :sum)
-> StructureConstantAlgebra, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}
direct_product(algebras::Vector{StructureConstantAlgebra}; task::Symbol = :sum)
-> StructureConstantAlgebra, Vector{AbsAlgAssMor}, Vector{AbsAlgAssMor}
Returns the algebra task
can be ":sum", ":prod", ":both" or ":none" and determines which canonical maps are computed as well: ":sum" for the injections, ":prod" for the projections.
direct_product(x::Vararg{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}
direct_product(x::Vector{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}
Given a collection of quadratic or hermitian lattices
For objects of type AbstractLat
, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L
as a direct sum with the injections direct_sum(x)
. If one wants to obtain L
as a biproduct with the injections biproduct(x)
.
biproduct Method
biproduct(x::Vararg{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}
biproduct(x::Vector{T}) where T <: AbstractLat -> T, Vector{AbstractSpaceMor}, Vector{AbstractSpaceMor}
Given a collection of quadratic or hermitian lattices
For objects of type AbstractLat
, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain L
as a direct sum with the injections direct_sum(x)
. If one wants to obtain L
as a direct product with the projections direct_product(x)
.
Invariants
Let
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
norm Method
norm(L::AbstractLat) -> AbsNumFieldOrderFractionalIdeal
Return the norm of the lattice L
. This is a fractional ideal of the fixed field of L
.
scale Method
scale(L::AbstractLat) -> AbsSimpleNumFieldOrderFractionalIdeal
Return the scale of the lattice L
.
volume Method
volume(L::AbstractLat) -> AbsSimpleNumFieldOrderFractionalIdeal
Return the volume of the lattice L
.
Examples
julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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
is_modular Method
is_modular(L::AbstractLat) -> Bool, AbsSimpleNumFieldOrderFractionalIdeal
Return whether the lattice L
is modular. In this case, the second returned value is a fractional ideal L
such that L
.
is_modular Method
is_modular(L::AbstractLat, p) -> Bool, Int
Return whether the completion L
at the prime ideal or integer p
is modular. If it is the case the second returned value is an integer v
such that
is_positive_definite Method
is_positive_definite(L::AbstractLat) -> Bool
Return whether the rational span of the lattice L
is positive definite.
is_negative_definite Method
is_negative_definite(L::AbstractLat) -> Bool
Return whether the rational span of the lattice L
is negative definite.
is_definite Method
is_definite(L::AbstractLat) -> Bool
Return whether the rational span of the lattice L
is definite.
can_scale_totally_positive Method
can_scale_totally_positive(L::AbstractLat) -> Bool, NumFieldElem
Return whether there is a totally positive rescaled lattice of the lattice L
. If so, the second returned value is an element
Examples
julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}; type = :any) -> MatElem
Given a prime ideal p
and a lattice L
, return a basis matrix of a lattice M
such that 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 latticeM
will be a sublattice ofL
.If
type == :supermodule
, the latticeM
will be a superlattice ofL
.If
type == :any
, there may not be any containment relation betweenM
andL
.
jordan_decomposition Method
jordan_decomposition(L::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem})
-> 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
is_isotropic Method
is_isotropic(L::AbstractLat, p::Union{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, InfPlc}) -> Bool
Return whether the completion of the lattice L
at the place p
is isotropic.
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{AbsSimpleNumFieldElem}[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{AbsSimpleNumFieldElem}[[1 0 0; 0 1 0; 0 0 1]], AbstractAlgebra.Generic.MatSpaceElem{AbsSimpleNumFieldElem}[[2 0 0; 0 2 0; 0 0 2]], [0])
julia> is_isotropic(Lquad, p)
true
Automorphisms for definite lattices
Let
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
automorphism_group_order Method
automorphism_group_order(L::AbstractLat; depth::Int = -1, bacher_depth::Int = 0) -> Int
Given a definite lattice L
, return the order of the automorphism group of L
.
Setting the parameters depth
and bacher_depth
to a positive value may improve performance. If set to -1
(default), the used value of depth
is chosen heuristically depending on the rank of L
. By default, bacher_depth
is set to 0
.
automorphism_group_generators Method
automorphism_group_generators(L::AbstractLat; ambient_representation::Bool = true,
depth::Int = -1, bacher_depth::Int = 0)
-> 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
.
Setting the parameters depth
and bacher_depth
to a positive value may improve performance. If set to -1
(default), the used value of depth
is chosen heuristically depending on the rank of L
. By default, bacher_depth
is set to 0
.
Examples
julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(g, "b");
julia> D = matrix(K, 3, 3, [2, 0, 0, 0, 2, 0, 0, 0, 2]);
julia> gens = Vector{AbsSimpleNumFieldElem}[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{AbsSimpleNumFieldElem}}:
[-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::AbstractLat, M::AbstractLat; depth::Int = -1, bacher_depth::Int = 0) -> Bool
Return whether the lattices L
and M
are isometric.
Setting the parameters depth
and bacher_depth
to a positive value may improve performance. If set to -1
(default), the used value of depth
is chosen heuristically depending on the rank of L
. By default, bacher_depth
is set to 0
.
is_isometric_with_isometry Method
is_isometric_with_isometry(L::AbstractLat, M::AbstractLat; ambient_representation::Bool = true
depth::Int = -1, bacher_depth::Int = 0)
-> (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, 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, L
and M
respectively.
Setting the parameters depth
and bacher_depth
to a positive value may improve performance. If set to -1
(default), the used value of depth
is chosen heuristically depending on the rank of L
. By default, bacher_depth
is set to 0
.
is_locally_isometric Method
is_locally_isometric(L::AbstractLat, M::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Bool
Return whether the completions of the lattices L
and M
at the prime ideal p
are isometric.
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{AbsSimpleNumFieldElem}[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{AbsSimpleNumFieldElem}[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::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Bool, AbstractLat
Given a lattice L
and a prime ideal p
of the fixed ring L
, return whether the completion of L
at p
has integral norm and that L
has no proper overlattice satisfying this property.
If the norm of L
is not integral at p
, the second output is L
by default. Otherwise, either L
is maximal at p
and the second output is L
, or the second output is a lattice M
in the ambient space of L
whose completion at p
is a minimal overlattice of
is_maximal_integral Method
is_maximal_integral(L::AbstractLat) -> Bool, AbstractLat
Given a lattice L
, return whether L
has integral norm and has no proper overlattice satisfying this property.
If the norm of L
is not integral, the second output is L
by default. Otherwise, either L
is maximal and the second output is L
, or the second output is a minimal overlattice M
of L
with integral norm.
is_maximal Method
is_maximal(L::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> Bool, AbstractLat
Given a lattice L
and a prime ideal p
in the fixed ring L
such that the norm of L
is maximal integral at p
.
If L
is locally maximal at p
, the second output is L
, otherwise it is a lattice M
in the same ambient space of L
whose completion at p
has integral norm and is a proper overlattice of
maximal_integral_lattice Method
maximal_integral_lattice(L::AbstractLat, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> AbstractLat
Given a lattice L
and a prime ideal p
of the fixed ring L
such that the norm of 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
.
maximal_integral_lattice Method
maximal_integral_lattice(L::AbstractLat) -> AbstractLat
Given a lattice L
with integral norm, return a maximal integral overlattice M
of L
.
maximal_integral_lattice Method
maximal_integral_lattice(V::AbstractSpace) -> AbstractLat
Given a space V
, return a lattice in V
with integral norm and which is maximal in V
satisfying this property.
Examples
julia> K, a = rationals_as_number_field();
julia> Kt, t = K["t"];
julia> g = t^2 + 7;
julia> E, b = number_field(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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}[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)
julia> is_maximal_integral(Lherm)
(false, Hermitian lattice of rank 4 and degree 4)
julia> is_maximal(Lherm, p)
(false, Hermitian lattice of rank 4 and degree 4)
julia> pseudo_basis(maximal_integral_lattice(Lherm, p))
4-element Vector{Tuple{Vector{Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}, Hecke.RelNumFieldOrderFractionalIdeal{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal, Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}}:
([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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}, Hecke.RelNumFieldOrderFractionalIdeal{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal, Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}}:
([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.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}, Hecke.RelNumFieldOrderFractionalIdeal{AbsSimpleNumFieldElem, AbsSimpleNumFieldOrderFractionalIdeal, Hecke.RelSimpleNumFieldElem{AbsSimpleNumFieldElem}}}}:
([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])
([4, 2, 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])
([2, 3, 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])