Skip to content

Spaces

Creation of spaces

# quadratic_space — Method.

quadratic_space(K::NumField, n::Int; cached::Bool = true) -> QuadSpace

Create the quadratic space over K with dimension n and Gram matrix equals to the identity matrix.

source

# hermitian_space — Method.

hermitian_space(E::NumField, n::Int; cached::Bool = true) -> HermSpace

Create the hermitian space over E with dimension n and Gram matrix equals to the identity matrix. The number field E must be a quadratic extension, that is, must hold.

source

# quadratic_space — Method.

quadratic_space(K::NumField, G::MatElem; cached::Bool = true) -> QuadSpace

Create the quadratic space over K with Gram matrix G. The matrix G must be square and symmetric.

source

# hermitian_space — Method.

hermitian_space(E::NumField, gram::MatElem; cached::Bool = true) -> HermSpace

Create the hermitian space over E with Gram matrix equals to gram. The matrix gram must be square and hermitian with respect to the non-trivial automorphism of E. The number field E must be a quadratic extension, that is, must hold.

source

Examples

Here are easy examples to see how these constructors work. We will keep the two following spaces for the rest of this section:

julia> K, a = CyclotomicRealSubfield(7);


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


julia> E, b = number_field(t^2-a*t+1, "b");


julia> Q = quadratic_space(K, K[0 1; 1 0])
Quadratic space over
Maximal real subfield of cyclotomic field of order 7
with Gram matrix
[0 1; 1 0]

julia> H = hermitian_space(E, 3)
Hermitian space over
Relative number field with defining polynomial t^2 - (z_7 + 1/z_7)*t + 1
 over Maximal real subfield of cyclotomic field of order 7
with Gram matrix
[1 0 0; 0 1 0; 0 0 1]

Attributes

Let be a space over . We define its dimension to be its dimension as a vector space over its base ring and its rank to be the rank of its Gram matrix. If these two invariants agree, the space is said to be regular.

While dealing with lattices, one always works with regular ambient spaces.

The determinant of is defined to be the class of the determinant of its Gram matrix in (which is similar to in the quadratic case). The discriminant of is defined to be , where is the rank of .

# rank — Method.

rank(V::AbsSpace) -> Int

Return the rank of the space V.

source

# dim — Method.

dim(V::AbsSpace) -> Int

Return the dimension of the space V.

source

# gram_matrix — Method.

gram_matrix(V::AbsSpace) -> MatElem

Return the Gram matrix of the space V.

source

# involution — Method.

involution(V::AbsSpace) -> NumField

Return the involution of the space V.

source

# base_ring — Method.

base_ring(V::AbsSpace) -> NumField

Return the algebra over which the space V is defined.

source

# fixed_field — Method.

fixed_field(V::AbsSpace) -> NumField

Return the fixed field of the space V.

source

# det — Method.

det(V::AbsSpace) -> FieldElem

Return the determinant of the space V as an element of its fixed field.

source

# discriminant — Method.

discriminant(V::AbsSpace) -> FieldElem

Return the discriminant of the space V as an element of its fixed field.

source

Examples

So for instance, one could get the following information about the hermitian space :

julia> K, a = CyclotomicRealSubfield(7);


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


julia> E, b = number_field(t^2-a*t+1, "b");


julia> H = hermitian_space(E, 3);


julia> rank(H), dim(H)
(3, 3)

julia> gram_matrix(H)
[1   0   0]
[0   1   0]
[0   0   1]

julia> involution(H)
Map with following data
Domain:
=======
Relative number field with defining polynomial t^2 - (z_7 + 1/z_7)*t + 1
 over Maximal real subfield of cyclotomic field of order 7
Codomain:
=========
Relative number field with defining polynomial t^2 - (z_7 + 1/z_7)*t + 1
 over Maximal real subfield of cyclotomic field of order 7

julia> base_ring(H)
Relative number field with defining polynomial t^2 - (z_7 + 1/z_7)*t + 1
 over Maximal real subfield of cyclotomic field of order 7

julia> fixed_field(H)
Maximal real subfield of cyclotomic field of order 7

julia> det(H), discriminant(H)
(1, -1)

Predicates

Let be a hermitian space over (resp. quadratic space ). We say that is definite if is CM (resp. is totally real) and if there exists an orthogonal basis of for which the diagonal elements of the associated Gram matrix of are either all totally positive or all totally negative. In the former case, is said to be positive definite, while in the latter case it is negative definite. In all the other cases, we say that is indefinite.

# is_regular — Method.

is_regular(V::AbsSpace) -> Bool

Return whether the space V is regular, that is, if the Gram matrix has full rank.

source

# is_quadratic — Method.

is_quadratic(V::AbsSpace) -> Bool

Return whether the space V is quadratic.

source

# ishermitian — Method.

ishermitian(V::AbsSpace) -> Bool

Return whether the space V is hermitian.

source

# is_positive_definite — Method.

is_positive_definite(V::AbsSpace) -> Bool

Return whether the space V is positive definite.

source

# is_negative_definite — Method.

is_negative_definite(V::AbsSpace) -> Bool

Return whether the space V is negative definite.

source

# is_definite — Method.

is_definite(V::AbsSpace) -> Bool

Return whether the space V is definite.

source

Note that the ishermitian function tests whether the space is non-quadratic.

Examples

julia> K, a = CyclotomicRealSubfield(7);


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


julia> E, b = number_field(t^2-a*t+1, "b");


julia> Q = quadratic_space(K, K[0 1; 1 0]);


julia> H = hermitian_space(E, 3);


julia> is_regular(Q), is_regular(H)
(true, true)

julia> is_quadratic(Q), ishermitian(H)
(true, true)

julia> is_definite(Q), is_positive_definite(H)
(false, true)

Inner products and diagonalization

# gram_matrix — Method.

gram_matrix(V::AbsSpace, M::MatElem) -> MatElem

Return the Gram matrix of the rows of M with respect to the Gram matrix of the space V.

source

# gram_matrix — Method.

gram_matrix(V::AbsSpace, S::Vector{Vector}) -> MatElem

Return the Gram matrix of the sequence S with respect to the Gram matrix of the space V.

source

# inner_product — Method.

inner_product(V::AbsSpace, v::Vector, w::Vector) -> FieldElem

Return the inner product of v and w with respect to the bilinear form of the space V.

source

# orthogonal_basis — Method.

orthogonal_basis(V::AbsSpace) -> MatElem

Return a matrix M, such that the rows of M form an orthogonal basis of the space V.

source

# diagonal — Method.

diagonal(V::AbsSpace) -> Vector{FieldElem}

Return a vector of elements such that the space V is isometric to the diagonal space .

The elements are contained in the fixed field of V.

source

# restrict_scalars — Method.

restrict_scalars(V::AbsSpace, K::FlintRationalField,
                              alpha::FieldElem = one(base_ring(V)))
                                                      -> QuadSpace, SpaceRes

Given a space and a subfield K of the base algebra E of V, return the quadratic space W obtained by restricting the scalars of to K, together with the map f for extending the scalars back. The form on the restriction is given by where is the trace form. The rescaling factor is set to 1 by default.

Note that for now one can only restrict scalars to .

source

Examples

julia> K, a = CyclotomicRealSubfield(7);


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


julia> E, b = number_field(t^2-a*t+1, "b");


julia> Q = quadratic_space(K, K[0 1; 1 0]);


julia> H = hermitian_space(E, 3);


julia> gram_matrix(Q, K[1 1; 2 0])
[2   2]
[2   0]

julia> gram_matrix(H, E[1 0 0; 0 1 0; 0 0 1])
[1   0   0]
[0   1   0]
[0   0   1]

julia> inner_product(Q, [1, 1], [0, 2])
ERROR: MethodError: no method matching *(::Vector{Int64}, ::AbstractAlgebra.Generic.MatSpaceElem{nf_elem})
Closest candidates are:
  *(::Any, ::Any, !Matched::Any, !Matched::Any...) at operators.jl:591
  *(::StridedVecOrMat, !Matched::LinearAlgebra.Adjoint{<:Any, <:LinearAlgebra.LQPackedQ}) at /opt/hostedtoolcache/julia/1.8.5/x64/share/julia/stdlib/v1.8/LinearAlgebra/src/lq.jl:269
  *(::StridedVecOrMat, !Matched::LinearAlgebra.LQPackedQ) at /opt/hostedtoolcache/julia/1.8.5/x64/share/julia/stdlib/v1.8/LinearAlgebra/src/lq.jl:293
  ...

julia> orthogonal_basis(H)
[1   0   0]
[0   1   0]
[0   0   1]

julia> diagonal(Q), diagonal(H)
(nf_elem[1, -1], nf_elem[1, 1, 1])

Equivalence

Let and be spaces over the same extension . A homomorphism of spaces from to is a -linear mapping such that for all , one has

An automorphism of spaces is called an isometry and a monomorphism is called an embedding.

# hasse_invariant — Method.

hasse_invariant(V::QuadSpace, p::Union{InfPlc, NfOrdIdl}) -> Int

Returns the Hasse invariant of the quadratic space V at p. This is equal to the product of local Hilbert symbols , , where is isometric to . If V is degenerate return the hasse invariant of V/radical(V).

source

# witt_invariant — Method.

witt_invariant(V::QuadSpace, p::Union{InfPlc, NfOrdIdl}) -> Int

Returns the Witt invariant of the quadratic space V at p.

See [Definition 3.2.1, Kir16].

source

# is_isometric — Method.

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

Return whether the spaces L and M are isometric.

source

# is_isometric — Method.

is_isometric(L::AbsSpace, M::AbsSpace, p::Union{InfPlc, NfOrdIdl}) -> Bool

Return whether the spaces L and M are isometric over the completion at p.

source

# invariants — Method.

invariants(M::QuadSpace)
      -> FieldElem, Dict{NfOrdIdl, Int}, Vector{Tuple{InfPlc, Int}}

Returns a tuple (n, k, d, H, I) of invariants of M, which determine the isometry class completely. Here n is the dimension. The dimension of the kernel is k. The element d is the determinant of a Gram matrix of the non-degenerate part, H contains the non-trivial Hasse invariants and I contains for each real place the negative index of inertia.

Note that d is determined only modulo squares.

source

Examples

For instance, for the case of and the totally ramified prime of above , one can get:

julia> K, a = CyclotomicRealSubfield(7);


julia> Q = quadratic_space(K, K[0 1; 1 0]);


julia> OK = maximal_order(K);


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


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

julia> Q2 = quadratic_space(K, K[-1 0; 0 1]);


julia> is_isometric(Q, Q2, p)
true

julia> is_isometric(Q, Q2)
true

julia> invariants(Q2)
(2, 0, -1, Dict{NfOrdIdl, Int64}(), Tuple{InfPlc{AnticNumberField, Hecke.NumFieldEmbNfAbs}, Int64}[(Infinite place corresponding to (Embedding corresponding to ≈ -1.80), 1), (Infinite place corresponding to (Embedding corresponding to ≈ -0.45), 1), (Infinite place corresponding to (Embedding corresponding to ≈ 1.25), 1)])

Embeddings

Let and be two spaces over the same extension , and let be an -linear morphism. is called a representation of into if for all

In such a case, is said to be represented by and can be seen as an embedding of into . This representation property can be also tested locally with respect to the completions at some finite places. Note that in both quadratic and hermitian cases, completions are taken at finite places of the fixed field .

# is_locally_represented_by — Method.

is_locally_represented_by(U::T, V::T, p::NfOrdIdl) where T <: AbsSpace -> Bool

Given two spaces U and V over the same algebra E, and a prime ideal p in the maximal order of their fixed field K, return whether U is represented by V locally at p, i.e. whether embeds in .

source

# is_represented_by — Method.

is_represented_by(U::T, V::T) where T <: AbsSpace -> Bool

Given two spaces U and V over the same algebra E, return whether U is represented by V, i.e. whether U embeds in V.

source

Examples

Still using the spaces and , we can decide whether some other spaces embed respectively locally or globally into or :

julia> K, a = CyclotomicRealSubfield(7);


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


julia> E, b = number_field(t^2-a*t+1, "b");


julia> Q = quadratic_space(K, K[0 1; 1 0]);


julia> H = hermitian_space(E, 3);


julia> OK = maximal_order(K);


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


julia> Q2 = quadratic_space(K, K[-1 0; 0 1]);


julia> H2 = hermitian_space(E, E[-1 0 0; 0 1 0; 0 0 -1]);


julia> is_locally_represented_by(Q2, Q, p)
true

julia> is_represented_by(Q2, Q)
true

julia> is_locally_represented_by(H2, H, p)
true

julia> is_represented_by(H2, H)
false

Orthogonality operations

# orthogonal_complement — Method.

orthogonal_complement(V::AbsSpace, M::T) where T <: MatElem -> T

Given a space V and a subspace W with basis matrix M, return a basis matrix of the orthogonal complement of W inside V.

source

# orthogonal_projection — Method.

orthogonal_projection(V::AbsSpace, M::T) where T <: MatElem -> AbsSpaceMor

Given a space V and a non-degenerate subspace W with basis matrix M, return the endomorphism of V corresponding to the projection onto the complement of W in V.

source

# orthogonal_sum — Method.

orthogonal_sum(V::AbsSpace, W::AbsSpace) -> AbsSpace, AbsSpaceMor, AbsSpaceMor

Given two spaces V and W of the same kind (either both hermitian or both quadratic) and defined over the same algebra, return their orthogonal sum . It is given with the two natural embeddings and .

source

# direct_sum — Method.

direct_sum(x::Vararg{QuadSpace}) -> QuadSpace, Vector{AbsSpaceMor}, Vector{AbsSpaceMor}
direct_sum(x::Vector{QuadSpace}) -> QuadSpace, Vector{AbsSpaceMor}, Vector{AbsSpaceMor}

Given a collection of quadratic spaces , return their complete direct sum , together with the injections and the projections .

source

Example

julia> K, a = CyclotomicRealSubfield(7);


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


julia> E, b = number_field(t^2-a*t+1, "b");


julia> Q = quadratic_space(K, K[0 1; 1 0]);


julia> H = hermitian_space(E, 3);


julia> H2 = hermitian_space(E, E[-1 0 0; 0 1 0; 0 0 -1]);


julia> orthogonal_complement(Q, matrix(K, 1, 2, [1 0]))
[1   0]

julia> H3, map1, map2 = orthogonal_sum(H, H2);


julia> H3
Hermitian space over
Relative number field with defining polynomial t^2 - (z_7 + 1/z_7)*t + 1
 over Maximal real subfield of cyclotomic field of order 7
with Gram matrix
[1 0 0 0 0 0; 0 1 0 0 0 0; 0 0 1 0 0 0; 0 0 0 -1 0 0; 0 0 0 0 1 0; 0 0 0 0 0 -1]

julia> map1
Map with following data
Domain:
=======
Hermitian space over
Relative number field with defining polynomial t^2 - (z_7 + 1/z_7)*t + 1
 over Maximal real subfield of cyclotomic field of order 7
with Gram matrix
[1 0 0; 0 1 0; 0 0 1]
Codomain:
=========
Hermitian space over
Relative number field with defining polynomial t^2 - (z_7 + 1/z_7)*t + 1
 over Maximal real subfield of cyclotomic field of order 7
with Gram matrix
[1 0 0 0 0 0; 0 1 0 0 0 0; 0 0 1 0 0 0; 0 0 0 -1 0 0; 0 0 0 0 1 0; 0 0 0 0 0 -1]

julia> map2
Map with following data
Domain:
=======
Hermitian space over
Relative number field with defining polynomial t^2 - (z_7 + 1/z_7)*t + 1
 over Maximal real subfield of cyclotomic field of order 7
with Gram matrix
[-1 0 0; 0 1 0; 0 0 -1]
Codomain:
=========
Hermitian space over
Relative number field with defining polynomial t^2 - (z_7 + 1/z_7)*t + 1
 over Maximal real subfield of cyclotomic field of order 7
with Gram matrix
[1 0 0 0 0 0; 0 1 0 0 0 0; 0 0 1 0 0 0; 0 0 0 -1 0 0; 0 0 0 0 1 0; 0 0 0 0 0 -1]

Isotropic spaces

Let be a space over and let be a place in . is said to be isotropic locally at if there exists an element such that , where is the continuous extension of to .

# is_isotropic — Method.

is_isotropic(V::AbsSpace, p::Union{NfOrdIdl, InfPlc}) -> Bool

Given a space V and a place p in the fixed field K of V, return whether the completion of V at p is isotropic.

source

Example

julia> K, a = CyclotomicRealSubfield(7);


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


julia> E, b = number_field(t^2-a*t+1, "b");


julia> H = hermitian_space(E, 3);


julia> OK = maximal_order(K);


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


julia> is_isotropic(H, p)
true

Hyperbolic spaces

Let be a space over and let be a prime ideal of . is said to be hyperbolic locally at if the completion of can be decomposed as an orthogonal sum of dimension 2 spaces with Gram matrices of the form \right).

# is_locally_hyperbolic — Method.

is_locally_hyperbolic(V::Hermspace, p::NfOrdIdl) -> Bool

Return whether the completion of the hermitian space V over at the prime ideal p of is hyperbolic.

source

Example

julia> K, a = CyclotomicRealSubfield(7);


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


julia> E, b = number_field(t^2-a*t+1, "b");


julia> H = hermitian_space(E, 3);


julia> OK = maximal_order(K);


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


julia> is_locally_hyperbolic(H, p)
false