Matrix groups
Introduction
A matrix group is a group that consists of invertible square matrices over a common ring, the base ring of the group (see base_ring(G::MatrixGroup)).
We distinguish between matrices and elements of matrix groups, that is, matrix group elements are not regarded as matrices. This distinction is necessary because we want that each element of a matrix group has this group as its parent. An advantage of this setup is that we know more about a matrix group element than about a matrix, for example that it is square and invertible.
Apply matrix to the matrix group element $g$ in order to create the corresponding matrix $m$. Call $G(m)$ in order to create the group element corresponding to $m$.
julia> G = general_linear_group(3, 2)
GL(3,2)
julia> x, y = gens(G)
2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
[1 1 0; 0 1 0; 0 0 1]
[0 0 1; 1 0 0; 0 1 0]
julia> x
[1 1 0]
[0 1 0]
[0 0 1]
julia> m = matrix(x)
[1 1 0]
[0 1 0]
[0 0 1]
julia> m == x
false
julia> G(m) == x
true
julia> parent(x)
GL(3,2)
julia> parent(m)
Matrix space of 3 rows and 3 columns
over prime field of characteristic 2For convenience, functions for matrices such as det and tr are defined also for matrix group elements, see the section on functions for elements of matrix groups.
julia> det(x)
1
julia> tr(x)
1Matrix groups in OSCAR have the type MatrixGroup{RE<:RingElem, T<:MatElem{RE}}, their elements have the type MatrixGroupElem{RE<:RingElem, T<:MatElem{RE}}.
Creation of matrix groups
The typical ways to create a matrix group are
to create matrices that generate the group, and then to call
matrix_groupwith these generators, orto start with a classical matrix group, and to create subgroups of it.
matrix_group — Methodmatrix_group([R::Ring, m::Int, ]V::T...) where T<:Union{MatElem,MatrixGroupElem}
matrix_group([R::Ring, m::Int, ]V::AbstractVector{T}) where T<:Union{MatElem,MatrixGroupElem}Return the matrix group generated by matrices in V. If V is empty then the base ring R and the degree m must be given.
Examples
julia> mats = [[0 -1; 1 -1], [0 1; 1 0]]
2-element Vector{Matrix{Int64}}:
[0 -1; 1 -1]
[0 1; 1 0]
julia> matelms = map(m -> matrix(ZZ, m), mats)
2-element Vector{ZZMatrix}:
[0 -1; 1 -1]
[0 1; 1 0]
julia> g = matrix_group(matelms)
Matrix group of degree 2
over integer ring
julia> describe(g)
"S3"
julia> t = matrix_group(ZZ, 2, typeof(matelms[1])[])
Matrix group of degree 2
over integer ring
julia> t == trivial_subgroup(g)[1]
true
julia> F = GF(3); matelms = map(m -> matrix(F, m), mats)
2-element Vector{FqMatrix}:
[0 2; 1 2]
[0 1; 1 0]
julia> g = matrix_group(matelms)
Matrix group of degree 2
over prime field of characteristic 3
julia> describe(g)
"S3"Here are examples for the creation of matrix groups as subgroups of classical groups.
julia> g = GL(3, GF(2))
GL(3,2)
julia> F = GF(4)
Finite field of degree 2 and characteristic 2
julia> G = GL(3, F)
GL(3,4)
julia> is_subset(g, G)
false
julia> base_ring(g)
Prime field of characteristic 2
julia> base_ring(G)
Finite field of degree 2 and characteristic 2
julia> h = change_base_ring(F, g)
Matrix group of degree 3
over finite field of degree 2 and characteristic 2
julia> is_subset(h, G)
true
julia> flag, mp = is_subgroup(h, G)
(true, Hom: h -> G)
julia> x = gen(h, 1);
julia> parent(x) == h
true
julia> parent(mp(x))
GL(3,4)Classical groups
general_linear_group — Methodgeneral_linear_group(n::Int, q::Int)
general_linear_group(n::Int, R::Ring)
GL = general_linear_groupReturn the general linear group of dimension n over the ring R respectively the field GF(q).
Currently R must be either a finite field or a residue ring or ZZ.
Examples
julia> F = GF(7)
Prime field of characteristic 7
julia> H = general_linear_group(2, F)
GL(2,7)
julia> gens(H)
2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
[3 0; 0 1]
[6 1; 6 0]
julia> order(general_linear_group(2, residue_ring(ZZ, 6)[1]))
288special_linear_group — Methodspecial_linear_group(n::Int, q::Int)
special_linear_group(n::Int, R::Ring)
SL = special_linear_groupReturn the special linear group of dimension n over the ring R respectively the field GF(q).
Currently R must be either a finite field or a residue ring or ZZ.
Examples
julia> F = GF(7)
Prime field of characteristic 7
julia> H = special_linear_group(2, F)
SL(2,7)
julia> gens(H)
2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
[3 0; 0 5]
[6 1; 6 0]
julia> order(special_linear_group(2, residue_ring(ZZ, 6)[1]))
144symplectic_group — Methodsymplectic_group(n::Int, q::Int)
symplectic_group(n::Int, R::Ring)
Sp = symplectic_groupReturn the symplectic group of dimension n over the ring R respectively the field GF(q). The dimension n must be even.
Currently R must be either a finite field or a residue ring of prime power order.
Examples
julia> F = GF(7)
Prime field of characteristic 7
julia> H = symplectic_group(2, F)
Sp(2,7)
julia> gens(H)
2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
[3 0; 0 5]
[6 1; 6 0]
julia> order(symplectic_group(2, residue_ring(ZZ, 4)[1]))
48orthogonal_group — Methodorthogonal_group(e::Int, n::Int, R::Ring)
orthogonal_group(e::Int, n::Int, q::Int)
GO = orthogonal_groupReturn the orthogonal group of dimension n over the ring R respectively the field GF(q), and of type e, where e in {+1,-1} for n even and e=0 for n odd. If n is odd, e can be omitted.
Currently R must be either a finite field or a residue ring of odd prime power order.
Examples
julia> F = GF(7)
Prime field of characteristic 7
julia> H = orthogonal_group(1, 2, F)
GO+(2,7)
julia> gens(H)
2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
[3 0; 0 5]
[0 1; 1 0]
julia> order(orthogonal_group(-1, 2, residue_ring(ZZ, 9)[1]))
24special_orthogonal_group — Methodspecial_orthogonal_group(e::Int, n::Int, R::Ring)
special_orthogonal_group(e::Int, n::Int, q::Int)
SO = special_orthogonal_groupReturn the special orthogonal group of dimension n over the ring R respectively the field GF(q), and of type e, where e in {+1,-1} for n even and e=0 for n odd. If n is odd, e can be omitted.
Currently R must be either a finite field or a residue ring of odd prime power order.
Examples
julia> F = GF(7)
Prime field of characteristic 7
julia> H = special_orthogonal_group(1, 2, F)
SO+(2,7)
julia> gens(H)
3-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
[3 0; 0 5]
[5 0; 0 3]
[1 0; 0 1]
julia> order(special_orthogonal_group(-1, 2, residue_ring(ZZ, 9)[1]))
12omega_group — Methodomega_group(e::Int, n::Int, R::Ring)
omega_group(e::Int, n::Int, q::Int)Return the Omega group of dimension n over the ring R respectively the field GF(q), and of type e, where e in {+1,-1} for n even and e=0 for n odd. If n is odd, e can be omitted.
Currently R must be either a finite field or a residue ring of odd prime power order.
Examples
julia> F = GF(7)
Prime field of characteristic 7
julia> H = omega_group(1, 2, F)
Omega+(2,7)
julia> gens(H)
1-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
[2 0; 0 4]
julia> order(omega_group(0, 3, residue_ring(ZZ, 9)[1]))
324unitary_group — Methodunitary_group(n::Int, q::Int)
GU = unitary_groupReturn the unitary group of dimension n over the field GF(q^2).
Examples
julia> H = unitary_group(2,3)
GU(2,3)
julia> gens(H)
2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
[o 0; 0 2*o]
[2 2*o+2; 2*o+2 0]special_unitary_group — Methodspecial_unitary_group(n::Int, q::Int)
SU = special_unitary_groupReturn the special unitary group of dimension n over the field with q^2 elements.
Examples
julia> H = special_unitary_group(2,3)
SU(2,3)
julia> gens(H)
2-element Vector{MatrixGroupElem{FqFieldElem, FqMatrix}}:
[1 2*o+2; 0 1]
[0 2*o+2; 2*o+2 0]Functions for matrix groups
Defining data of a matrix group are its base_ring and its degree.
base_ring — Methodbase_ring(G::MatrixGroup)Return the base ring of the matrix group G.
Examples
julia> F = GF(4); g = general_linear_group(2, F);
julia> base_ring(g) == F
truedegree — Methoddegree(G::MatrixGroup)Return the degree of G, i.e., the number of rows of its matrices.
Examples
julia> degree(GL(4, 2))
4map_entries — Methodmap_entries(f, G::MatrixGroup)Return the matrix group obtained by applying f element-wise to each generator of G.
f can be a ring or a field, a suitable map, or a Julia function.
Examples
julia> mat = matrix(ZZ, 2, 2, [1, 1, 0, 1]);
julia> G = matrix_group(mat);
julia> G2 = map_entries(x -> -x, G)
Matrix group of degree 2
over integer ring
julia> is_finite(G2)
false
julia> order(map_entries(GF(3), G))
3Functions for elements of matrix groups
The following functions delegate to the underlying matrix of the given matrix group element.
matrix — Methodmatrix(x::MatrixGroupElem)Return the underlying matrix of x.
Examples
julia> F = GF(4); g = general_linear_group(2, F);
julia> x = gen(g, 1)
[o 0]
[0 1]
julia> m = matrix(x)
[o 0]
[0 1]
julia> x == m
false
julia> x == g(m)
truebase_ring — Methodbase_ring(x::MatrixGroupElem)Return the base ring of the matrix group to which x belongs. This is also the base ring of the underlying matrix of x.
Examples
julia> F = GF(4); g = general_linear_group(2, F);
julia> x = gen(g, 1)
[o 0]
[0 1]
julia> base_ring(x) == F
true
julia> base_ring(x) == base_ring(matrix(x))
truenrows — Methodnumber_of_rows(x::MatrixGroupElem)Return the number of rows of the underlying matrix of x.
det — Methoddet(x::MatrixGroupElem)Return the determinant of the underlying matrix of x.
Examples
julia> F = GF(4); g = general_linear_group(2, F);
julia> x = gen(g, 1)
[o 0]
[0 1]
julia> d = det(x)
o
julia> d in F
truetr — Methodtr(x::MatrixGroupElem)Return the trace of the underlying matrix of x.
Examples
julia> F = GF(4); g = general_linear_group(2, F);
julia> x = gen(g, 1)
[o 0]
[0 1]
julia> t = tr(x)
o + 1
julia> t in F
truemultiplicative_jordan_decomposition — Methodmultiplicative_jordan_decomposition(M::MatrixGroupElem{T}) where T <: FinFieldElemReturn S and U in the group parent(M) such that S is semisimple, U is unipotent and M = SU = US.
multiplicative_jordan_decomposition can be called also with a matrix, but the decomposition S, U is in general not compatible with A, B = multiplicative_jordan_decomposition(matrix(M)), in the sense that S and U are guaranteed to commute, whereas A and B may not commute, see the example below.
Examples
julia> m = matrix(GF(2), [0 0 1 1 0; 1 1 0 1 1; 1 0 1 0 0; 1 1 0 1 0; 0 1 1 0 0]);
julia> M = GL(5, 2)(m);
julia> S, U = multiplicative_jordan_decomposition(M)
([1 1 1 1 0; 0 0 0 1 1; 0 1 0 0 1; 1 1 0 1 0; 1 0 0 0 1], [1 0 1 0 1; 0 1 1 0 1; 1 1 1 0 0; 0 0 0 1 0; 1 1 0 0 1])
julia> S * U == U * S == M
true
julia> is_semisimple(S) && is_unipotent(U)
true
julia> A, B = multiplicative_jordan_decomposition(m)
([0 0 1 1 0; 1 1 0 1 1; 0 1 1 0 0; 1 1 0 1 0; 1 0 1 0 0], [0 1 0 0 0; 1 0 0 0 0; 0 0 1 0 0; 0 0 0 1 0; 0 0 0 0 1])
julia> A * B == m
true
julia> B * A == m
falseis_semisimple — Methodis_semisimple(x::MatrixGroupElem{T}) where T <: FinFieldElemReturn whether x is semisimple, i.e. has order coprime with the characteristic of its base ring.
Examples
julia> g = GO(3, 3);
julia> is_semisimple(gen(g,1))
true
julia> is_semisimple(gen(g,2))
falseis_unipotent — Methodis_unipotent(x::MatrixGroupElem{T}) where T <: FinFieldElemReturn whether x is unipotent, i.e. its order is a power of the characteristic of its base ring.
Examples
julia> g = SU(3,5)
SU(3,5)
julia> is_unipotent(gen(g,2))
false
julia> is_unipotent(gen(g,2)^3)
trueSesquilinear and quadratic forms
Sesquilinear forms are alternating and symmetric bilinear forms, and hermitian forms.
Sesquilinear forms in OSCAR have the type SesquilinearForm{T<:RingElem}. Quadratic forms in OSCAR have the type QuadraticForm{T<:RingElem}.
A sesquilinear or quadratic form can be created from its Gram matrix or as an invariant form of a matrix group.
Create sesquilinear and quadratic forms from Gram matrices
alternating_form — Methodalternating_form(B::MatElem{T})Return the alternating form with Gram matrix B. An exception is thrown if B is not square or does not have zeros on the diagonal or does not satisfy B = -transpose(B).
Examples
julia> f = alternating_form(matrix(GF(3), 2, 2, [0, 1, -1, 0]))
alternating form with Gram matrix
[0 1]
[2 0]
julia> describe(isometry_group(f))
"SL(2,3)"symmetric_form — Methodsymmetric_form(B::MatElem{T})Return the symmetric form with Gram matrix B. An exception is thrown if B is not square or not symmetric.
Examples
julia> f = symmetric_form(matrix(GF(3), 2, 2, [0, 1, 1, 0]))
symmetric form with Gram matrix
[0 1]
[1 0]
julia> describe(isometry_group(f))
"C2 x C2"hermitian_form — Methodhermitian_form(B::MatElem{T})Return the hermitian form with Gram matrix B. An exception is thrown if B is not square or does not satisfy B = conjugate_transpose(B), see conjugate_transpose.
Examples
julia> F = GF(4); z = gen(F);
julia> f = hermitian_form(matrix(F, 2, 2, [0, z, z^2, 0]))
hermitian form with Gram matrix
[ 0 o]
[o + 1 0]
julia> describe(isometry_group(f))
"C3 x S3"quadratic_form — Methodquadratic_form(B::MatElem{T})Return the quadratic form with Gram matrix B.
Examples
julia> f = quadratic_form(matrix(GF(3), 2, 2, [2, 2, 0, 1]))
quadratic form with Gram matrix
[2 2]
[0 1]
julia> describe(isometry_group(f))
"D8"quadratic_form — Methodquadratic_form(f::MPolyRingElem{T}; check=true)Return the quadratic form described by the polynomial f. Here, f must be a homogeneous polynomial of degree 2. If check is set to false, it is not checked whether f is homogeneous of degree 2. To define quadratic forms of dimension 1, f can also have type PolyRingElem{T}.
Examples
julia> _, (x1, x2) = polynomial_ring(GF(3), [:x1, :x2]);
julia> f = quadratic_form(2*x1^2 + 2*x1*x2 + x2^2)
quadratic form with Gram matrix
[2 2]
[0 1]
julia> describe(isometry_group(f))
"D8"Invariant forms
The following functions compute (Gram matrices of) sesquilinear and quadratic forms that are invariant under the given matrix group.
invariant_bilinear_forms — Methodinvariant_bilinear_forms(G::MatrixGroup)Return a generating set for the vector space of bilinear forms preserved by G.
Examples
julia> G = sylow_subgroup(GL(3, 2), 2)[1];
julia> length(invariant_bilinear_forms(G))
2invariant_sesquilinear_forms — Methodinvariant_sesquilinear_forms(G::MatrixGroup)Return a generating set for the vector space of sesquilinear forms preserved by the group G.
An exception is thrown if base_ring(G) is not a finite field with even degree over its prime subfield.
Examples
julia> G = sylow_subgroup(GL(3, 4), 2)[1];
julia> length(invariant_sesquilinear_forms(G))
1invariant_quadratic_forms — Methodinvariant_quadratic_forms(G::MatrixGroup)Return a generating set for the vector space of quadratic forms preserved by the group G.
Examples
julia> G = sylow_subgroup(GL(3, 2), 2)[1];
julia> length(invariant_quadratic_forms(G))
2invariant_symmetric_forms — Methodinvariant_symmetric_forms(G::MatrixGroup)Return a generating set for the vector space of symmetric forms preserved by the group G.
Work properly only in odd characteristic. In even characteristic, only alternating forms are found.
Examples
julia> G = sylow_subgroup(GL(3, 3), 2)[1];
julia> length(invariant_symmetric_forms(G))
1invariant_alternating_forms — Methodinvariant_alternating_forms(G::MatrixGroup)Return a generating set for the vector space of alternating forms preserved by the group G.
Examples
julia> G = sylow_subgroup(GL(3, 4), 2)[1];
julia> length(invariant_alternating_forms(G))
1invariant_hermitian_forms — Methodinvariant_hermitian_forms(G::MatrixGroup)Return a generating set for the vector space of hermitian forms preserved by the group G. An exception is thrown if base_ring(G) is not a finite field with even degree over its prime subfield.
Examples
julia> G = sylow_subgroup(GL(3, 4), 2)[1];
julia> length(invariant_hermitian_forms(G))
1invariant_bilinear_form — Methodinvariant_bilinear_form(G::MatrixGroup{T}) where T <: FinFieldElemReturn the Gram matrix of an invariant bilinear form for G. An exception is thrown if the module induced by the action of G is not absolutely irreducible.
Examples
julia> invariant_bilinear_form(Sp(4, 2))
[0 0 0 1]
[0 0 1 0]
[0 1 0 0]
[1 0 0 0]invariant_sesquilinear_form — Methodinvariant_sesquilinear_form(G::MatrixGroup{T}) where T <: FinFieldElemReturn the Gram matrix of an invariant sesquilinear (non bilinear) form for G.
An exception is thrown if the module induced by the action of G is not absolutely irreducible or if G is defined over a finite field of odd degree over the prime field.
Examples
julia> invariant_sesquilinear_form(GU(4, 2))
[0 0 0 1]
[0 0 1 0]
[0 1 0 0]
[1 0 0 0]invariant_quadratic_form — Methodinvariant_quadratic_form(G::MatrixGroup{T}) where T <: FinFieldElemReturn the Gram matrix of an invariant quadratic form for G. An exception is thrown if the module induced by the action of G is not absolutely irreducible.
Examples
julia> invariant_quadratic_form(GO(1, 4, 2))
[0 1 0 0]
[0 0 0 0]
[0 0 0 1]
[0 0 0 0]preserved_quadratic_forms — Methodpreserved_quadratic_forms(G::MatrixGroup{T}) where T <: FinFieldElemUses random methods to find all of the quadratic forms preserved by G up to a scalar (i.e. such that G is a group of similarities for the forms). Since the procedure relies on a pseudo-random generator, the user may need to execute the operation more than once to find all invariant quadratic forms.
preserved_sesquilinear_forms — Methodpreserved_sesquilinear_forms(G::MatrixGroup{T}) where T <: FinFieldElemUses random methods to find all of the sesquilinear forms preserved by G up to a scalar (i.e. such that G is a group of similarities for the forms). Since the procedure relies on a pseudo-random generator, the user may need to execute the operation more than once to find all invariant sesquilinear forms.
orthogonal_sign — Methodorthogonal_sign(G::MatrixGroup{T}) where T <: FinFieldElemFor absolutely irreducible G of degree n, return
nothingifGdoes not preserve a nonzero quadratic form,0ifnis odd andGpreserves a nonzero quadratic form,1ifnis even andGpreserves a nonzero quadratic form of+type,-1ifnis even andGpreserves a nonzero quadratic form of-type.
Examples
julia> orthogonal_sign(GO(1, 4, 2))
1
julia> orthogonal_sign(GO(-1, 4, 2))
-1Functions for sesquilinear and quadratic forms
is_alternating — Methodis_alternating(f::SesquilinearForm)Return whether f has been created as an alternating form.
The Gram matrix M of an alternating form satisfies M = -transpose(M) and M has zeros on the diagonal, see is_alternating(M::MatrixElem).
Examples
julia> M = matrix(GF(2), [0 1; 1 0])
[0 1]
[1 0]
julia> is_alternating(alternating_form(M))
true
julia> is_alternating(symmetric_form(M))
falseis_hermitian — Methodis_hermitian(f::SesquilinearForm)Return whether f has been created as a hermitian form.
The Gram matrix M of a hermitian form satisfies M = conjugate_transpose(M), see is_hermitian(B::MatElem{T}) where T <: FinFieldElem.
Examples
julia> F, z = finite_field(2, 2); M = matrix(F, [0 z; z+1 0])
[ 0 o]
[o + 1 0]
julia> is_hermitian(hermitian_form(M))
trueis_symmetric — Methodis_symmetric(f::SesquilinearForm)Return whether f has been created as a symmetric form. The Gram matrix M of a symmetric form satisfies M = transpose(M), see is_symmetric(M::MatrixElem).
Examples
julia> M = matrix(GF(2), [0 1; 1 0])
[0 1]
[1 0]
julia> is_symmetric(symmetric_form(M))
true
julia> is_symmetric(alternating_form(M))
falsecorresponding_bilinear_form — Methodcorresponding_bilinear_form(Q::QuadraticForm)Return the symmetric form B defined by B(u,v) = Q(u+v)-Q(u)-Q(v).
Examples
julia> Q = quadratic_form(invariant_quadratic_form(GO(3,3)))
quadratic form with Gram matrix
[0 1 0]
[0 0 0]
[0 0 1]
julia> corresponding_bilinear_form(Q)
symmetric form with Gram matrix
[0 1 0]
[1 0 0]
[0 0 2]corresponding_quadratic_form — Methodcorresponding_quadratic_form(f::SesquilinearForm)Given a symmetric form f, return the quadratic form Q defined by Q(v) = f(v,v)/2. It is defined only in odd characteristic.
Examples
julia> f = symmetric_form(invariant_bilinear_form(GO(3, 3)))
symmetric form with Gram matrix
[0 2 0]
[2 0 0]
[0 0 1]
julia> corresponding_quadratic_form(f)
quadratic form with Gram matrix
[0 2 0]
[0 0 0]
[0 0 2]gram_matrix — Methodgram_matrix(f::SesquilinearForm)
gram_matrix(f::QuadraticForm)Return the Gram matrix that defines f.
Examples
julia> M = invariant_bilinear_forms(GO(3, 5))[1];
julia> M == gram_matrix(symmetric_form(M))
true
julia> M = invariant_quadratic_forms(GO(3, 5))[1];
julia> M == gram_matrix(quadratic_form(M))
truedefining_polynomial — Methoddefining_polynomial(f::QuadraticForm)Return the polynomial that defines f.
Examples
julia> g = GO(5, 2);
julia> f = quadratic_form(invariant_quadratic_forms(g)[1]);
julia> defining_polynomial(f)
x1^2 + x2*x4 + x3*x5radical — Methodradical(f::SesquilinearForm{T})
radical(f::QuadraticForm{T})Return (U, emb) where U is the radical of f and emb is the embedding of U into the full vector space on which f is defined.
For a quadratic form f, the radical is defined as the set of vectors v such that f(v) = 0 and v lies in the radical of the corresponding bilinear form.
Otherwise the radical of f is defined as the subspace of all v such that f(u, v) = 0 for all u.
Examples
julia> g = GO(7, 2);
julia> f = symmetric_form(invariant_symmetric_forms(g)[1]);
julia> U, emb = radical(f);
julia> vector_space_dim(U)
1witt_index — Methodwitt_index(f::SesquilinearForm)
witt_index(f::QuadraticForm)Return the Witt index of the form induced by f on V/Rad(f). The Witt index is the dimension of a maximal totally isotropic (singular for quadratic forms) subspace.
Examples
julia> g = GO(1, 6, 2);
julia> witt_index(quadratic_form(invariant_quadratic_forms(g)[1]))
3
julia> g = GO(-1, 6, 2);
julia> witt_index(quadratic_form(invariant_quadratic_forms(g)[1]))
2is_degenerate — Methodis_degenerate(f::SesquilinearForm)
is_degenerate(f::QuadraticForm)Return whether f is degenerate, i.e. f has nonzero radical. A quadratic form is degenerate if the corresponding bilinear form is.
Examples
julia> g = GO(5, 2);
julia> f = symmetric_form(invariant_symmetric_forms(g)[1]);
julia> is_degenerate(f)
trueis_singular — Methodis_singular(Q::QuadraticForm)Return whether Q is singular, i.e. Q has nonzero radical.
Examples
julia> G = GO(5, 2);
julia> f = quadratic_form(invariant_quadratic_forms(G)[1]);
julia> is_singular(f)
falseis_congruent — Methodis_congruent(f::SesquilinearForm{T}, g::SesquilinearForm{T}) where T <: RingElem
is_congruent(f::QuadraticForm{T}, g::QuadraticForm{T}) where T <: RingElemIf f and g are quadratic forms, return (true, C) if there exists a matrix C such that f^C = ag for some scalar a. If such C does not exist, then return (false, nothing).
Otherwise return (true, C) if there exists a matrix C such that f^C = g, or equivalently, CBC* = A, where A and B are the Gram matrices of f and g respectively, and C* is the transpose-conjugate matrix of C. If such C does not exist, then return (false, nothing).
Examples
julia> m1 = symmetric_form(matrix(GF(5), [1 0 2; 0 1 0; 2 0 1]))
symmetric form with Gram matrix
[1 0 2]
[0 1 0]
[2 0 1]
julia> m2 = symmetric_form(matrix(GF(5), [1 4 2; 4 2 0; 2 0 0]))
symmetric form with Gram matrix
[1 4 2]
[4 2 0]
[2 0 0]
julia> is_congruent( m1, m2 )
(true, [1 0 0; 1 1 0; 3 3 1])isometry_group — Methodisometry_group(f::SesquilinearForm{T}) where T
isometry_group(f::QuadraticForm{T}) where TReturn the group of isometries for f.
Examples
julia> G = symplectic_group(4, 2);
julia> f = alternating_form(invariant_alternating_forms(G)[1]);
julia> isometry_group(f) == G
trueisometry_group(L::AbstractLat; depth::Int = -1, bacher_depth::Int = 0) -> MatrixGroupReturn the group of isometries of the lattice L.
The transformations are represented with respect to the ambient space 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.
Utilities for matrices
The inputs/outputs of the functions described in this section are matrices not matrix group elements.
pol_elementary_divisors — Methodpol_elementary_divisors(x::MatElem)
pol_elementary_divisors(x::MatrixGroupElem)Return a list of pairs (f_i,m_i), for irreducible polynomials f_i and positive integers m_i, where the f_i^m_i are the elementary divisors of x.
generalized_jordan_block — Methodgeneralized_jordan_block(f::T, n::Int) where T<:PolyRingElemReturn the Jordan block of dimension n corresponding to the polynomial f.
generalized_jordan_form — Methodgeneralized_jordan_form(A::MatElem{T}; with_pol::Bool=false) where TReturn (J,Z), where Z^-1*J*Z = A and J is a diagonal join of Jordan blocks (corresponding to irreducible polynomials).
Examples
julia> M = permutation_matrix(GF(2), [2, 3, 4, 1]);
julia> A, B = generalized_jordan_form(matrix(M));
julia> A
[1 1 0 0]
[0 1 1 0]
[0 0 1 1]
[0 0 0 1]
julia> B
[1 0 0 0]
[1 1 0 0]
[1 0 1 0]
[1 1 1 1]matrix — Methodmatrix(A::Vector{AbstractAlgebra.Generic.FreeModuleElem})Return the matrix whose rows are the vectors in A. All vectors in A must have the same length and the same base ring.
Examples
julia> V = vector_space(GF(2), 2); matrix(gens(V))
[1 0]
[0 1]conjugate_transpose — Methodconjugate_transpose(x::MatElem{T}) where T <: FinFieldElemIf the base ring of x is GF(q^2), return the matrix transpose( map ( y -> y^q, x) ). An exception is thrown if the base ring does not have even degree.
Examples
julia> F, z = finite_field(2, 2); M = matrix(F, [0 z; 0 0])
[0 o]
[0 0]
julia> conjugate_transpose(M)
[ 0 0]
[o + 1 0]complement — Methodcomplement(V::AbstractAlgebra.Generic.FreeModule{T}, W::AbstractAlgebra.Generic.Submodule{T}) where T <: FieldElemReturn a complement for W in V, i.e. a subspace U of V such that V is the direct sum of U and W.
Examples
julia> V = vector_space(GF(2), 2);
julia> U = sub(V,[V[1] + V[2]])[1];
julia> C, emb = complement(V,U);
julia> map(emb, gens(C))[1]
(0, 1)permutation_matrix — Methodpermutation_matrix(R::NCRing, Q::AbstractVector{T}) where T <: Int
permutation_matrix(R::NCRing, p::PermGroupElem)Return the permutation matrix over the ring R corresponding to the sequence Q or to the permutation p. If Q is a sequence, then Q must contain exactly once every integer from 1 to some n.
Examples
julia> s = perm([3, 1, 2])
(1,3,2)
julia> permutation_matrix(QQ, s)
[0 0 1]
[1 0 0]
[0 1 0]is_alternating — Methodis_alternating(M::MatrixElem)Return whether the form corresponding to the matrix M is alternating, i.e. M = -transpose(M) and M has zeros on the diagonal. Return false if M is not a square matrix.
is_hermitian — Methodis_hermitian(B::MatElem{T}) where T <: FinFieldElemReturn whether the matrix B is hermitian, i.e. B = conjugate_transpose(B). Return false if B is not a square matrix, or the field has not even degree.
Examples
julia> F, z = finite_field(2, 2); x = matrix(F, [1 z; 0 1]);
julia> is_hermitian(x)
false
julia> is_hermitian(x + conjugate_transpose(x))
trueTechnicalities
MatrixGroup — TypeMatrixGroup{RE<:RingElem, T<:MatElem{RE}} <: GAPGroupType of groups G of n x n matrices over the ring R, where n = degree(G) and R = base_ring(G).
MatrixGroupElem — TypeMatrixGroupElem{RE<:RingElem, T<:MatElem{RE}} <: AbstractMatrixGroupElemType of elements of a group of type MatrixGroup{RE, T}.
ring_elem_type — Methodring_elem_type(G::MatrixGroup{S,T}) where {S,T}
ring_elem_type(::Type{MatrixGroup{S,T}}) where {S,T}Return the type S of the entries of the elements of G. One can enter the type of G instead of G.
Examples
julia> g = GL(2, 3);
julia> ring_elem_type(typeof(g)) == elem_type(typeof(base_ring(g)))
truemat_elem_type — Methodmat_elem_type(G::MatrixGroup{S,T}) where {S,T}
mat_elem_type(::Type{MatrixGroup{S,T}}) where {S,T}Return the type T of matrix(x), for elements x of G. One can enter the type of G instead of G.
Examples
julia> g = GL(2, 3);
julia> mat_elem_type(typeof(g)) == typeof(matrix(one(g)))
trueSesquilinearForm — TypeSesquilinearForm{T<:RingElem}Type of alternating and symmetric bilinear forms, hermitian forms, defined by a Gram matrix.
QuadraticForm — TypeQuadraticForm{T<:RingElem}Type of quadratic forms, defined by a Gram matrix or by a polynomial.