Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve documentation for the "Matrix groups" section #4556

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 125 additions & 8 deletions docs/src/Groups/matgroup.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,92 @@ DocTestSetup = Oscar.doctestsetup()

# 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{RE}) where RE <: RingElem`](@ref)).

Matrix groups in Oscar have the type
[`MatrixGroup{RE<:RingElem, T<:MatElem{RE}}`](@ref),
their elements have the type
[`MatrixGroupElem{RE<:RingElem, T<:MatElem{RE}}`](@ref).

## Basic Creation

In order to *create* a matrix group,
one first creates matrices that generate the group,
and then calls `matrix_group` with these generators.

```jldoctest matgroupxpl
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"
```

Alternatively,
one can start with [a classical matrix group](@ref "Classical groups").

```jldoctest matgroupxpl
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> h = change_base_ring(F, g)
Matrix group of degree 3
over finite field of degree 2 and characteristic 2

julia> flag, mp = is_subgroup(h, G)
(true, Hom: h -> G)

julia> mp(gen(h, 1)) in G
true
```

## Functions for matrix groups

```@docs
matrix_group(R::Ring, m::Int, V::AbstractVector{T}; check::Bool=true) where T<:Union{MatElem,MatrixGroupElem}
MatrixGroup{RE<:RingElem, T<:MatElem{RE}}
MatrixGroupElem{RE<:RingElem, T<:MatElem{RE}}
base_ring(G::MatrixGroup{RE}) where RE <: RingElem
degree(G::MatrixGroup)
centralizer(G::MatrixGroup{T}, x::MatrixGroupElem{T}) where T <: FinFieldElem
Expand All @@ -17,6 +99,9 @@ map_entries(f, G::MatrixGroup)

## Elements of matrix groups

The following functions delegate to the underlying matrix
of the given matrix group element.

```@docs
matrix(x::MatrixGroupElem)
base_ring(x::MatrixGroupElem)
Expand All @@ -30,17 +115,33 @@ is_unipotent(x::MatrixGroupElem{T}) where T <: FinFieldElem

## Sesquilinear forms

Sesquilinear forms are alternating and symmetric bilinear forms,
hermitian forms, and quadratic forms.

Sesquilinear forms in Oscar have the type
[`SesquilinearForm{T<:RingElem}`](@ref).

A sesquilinear form can be created
[from its Gram matrix](@ref "Create sesquilinear forms from Gram matrices")
or [as an invariant form of a matrix group](@ref "Invariant forms").

## Create sesquilinear forms from Gram matrices

```@docs
SesquilinearForm{T<:RingElem}
is_alternating(f::SesquilinearForm)
is_hermitian(f::SesquilinearForm)
is_quadratic(f::SesquilinearForm)
is_symmetric(f::SesquilinearForm)
alternating_form(B::MatElem{T}) where T <: FieldElem
symmetric_form(B::MatElem{T}) where T <: FieldElem
hermitian_form(B::MatElem{T}) where T <: FieldElem
quadratic_form(B::MatElem{T}) where T <: FieldElem
quadratic_form(f::MPolyRingElem{T}) where T <: FieldElem
```

## Functions for sesquilinear forms

```@docs
is_alternating(f::SesquilinearForm)
is_hermitian(f::SesquilinearForm)
is_quadratic(f::SesquilinearForm)
is_symmetric(f::SesquilinearForm)
corresponding_bilinear_form(B::SesquilinearForm)
corresponding_quadratic_form(B::SesquilinearForm)
gram_matrix(f::SesquilinearForm)
Expand All @@ -50,10 +151,14 @@ witt_index(f::SesquilinearForm{T}) where T
is_degenerate(f::SesquilinearForm{T}) where T
is_singular(f::SesquilinearForm{T}) where T
is_congruent(f::SesquilinearForm{T}, g::SesquilinearForm{T}) where T <: RingElem
isometry_group(f::SesquilinearForm{T}) where T
```

## Invariant forms

The following functions compute (Gram matrices of) sesquilinear forms
that are invariant under the given matrix group.

```@docs
invariant_bilinear_forms(G::MatrixGroup{S,T}) where {S,T}
invariant_sesquilinear_forms(G::MatrixGroup{S,T}) where {S,T}
Expand All @@ -66,12 +171,14 @@ invariant_sesquilinear_form(G::MatrixGroup)
invariant_quadratic_form(G::MatrixGroup)
preserved_quadratic_forms(G::MatrixGroup{S,T}) where {S,T}
preserved_sesquilinear_forms(G::MatrixGroup{S,T}) where {S,T}
isometry_group(f::SesquilinearForm{T}) where T
orthogonal_sign(G::MatrixGroup)
```

## Utilities for matrices

(The inputs/outputs of the functions described in this section
are matrices not matrix group elements.)

```@docs
pol_elementary_divisors(A::MatElem{T}) where T
generalized_jordan_block(f::T, n::Int) where T<:PolyRingElem
Expand All @@ -98,3 +205,13 @@ omega_group(e::Int, n::Int, F::Ring)
unitary_group(n::Int, q::Int)
special_unitary_group(n::Int, q::Int)
```

## Technicalities

```@docs
MatrixGroup{RE<:RingElem, T<:MatElem{RE}}
MatrixGroupElem{RE<:RingElem, T<:MatElem{RE}}
ring_elem_type(::Type{MatrixGroup{S,T}}) where {S,T}
mat_elem_type(::Type{MatrixGroup{S,T}}) where {S,T}
SesquilinearForm{T<:RingElem}
```
104 changes: 101 additions & 3 deletions src/Groups/matrices/MatGrp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,42 @@ MatrixGroupElem(G::MatrixGroup{RE,T}, x::T, x_gap::GapObj) where {RE,T} = Matrix
MatrixGroupElem(G::MatrixGroup{RE,T}, x::T) where {RE, T} = MatrixGroupElem{RE,T}(G,x)
MatrixGroupElem(G::MatrixGroup{RE,T}, x_gap::GapObj) where {RE, T} = MatrixGroupElem{RE,T}(G,x_gap)

"""
ring_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
```jldoctest
julia> g = GL(2, 3);

julia> ring_elem_type(typeof(g)) == elem_type(typeof(base_ring(g)))
true
```
"""
ring_elem_type(::Type{MatrixGroup{S,T}}) where {S,T} = S
ring_elem_type(::MatrixGroup{S,T}) where {S,T} = S

"""
mat_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
```jldoctest
julia> g = GL(2, 3);

julia> mat_elem_type(typeof(g)) == typeof(matrix(one(g)))
true
```
"""
mat_elem_type(::Type{MatrixGroup{S,T}}) where {S,T} = T
mat_elem_type(::MatrixGroup{S,T}) where {S,T} = T

_gap_filter(::Type{<:MatrixGroup}) = GAP.Globals.IsMatrixGroup

elem_type(::Type{MatrixGroup{S,T}}) where {S,T} = MatrixGroupElem{S,T}
Expand Down Expand Up @@ -419,7 +453,23 @@ det(x::MatrixGroupElem) = det(matrix(x))
"""
base_ring(x::MatrixGroupElem)

Return the base ring of the underlying matrix of `x`.
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
```jldoctest
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))
true
```
"""
base_ring(x::MatrixGroupElem) = base_ring(parent(x))

Expand All @@ -431,6 +481,25 @@ parent(x::MatrixGroupElem) = x.parent
matrix(x::MatrixGroupElem)

Return the underlying matrix of `x`.

# Examples
```jldoctest
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)
true
```
"""
function matrix(x::MatrixGroupElem)
if !isdefined(x, :elm)
Expand Down Expand Up @@ -463,6 +532,21 @@ size(x::MatrixGroupElem) = size(matrix(x))
tr(x::MatrixGroupElem)

Return the trace of the underlying matrix of `x`.

# Examples
```jldoctest
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
true
```
"""
tr(x::MatrixGroupElem) = tr(matrix(x))

Expand All @@ -484,6 +568,14 @@ transpose(x::MatrixGroupElem) = MatrixGroupElem(parent(x), transpose(matrix(x)))
base_ring(G::MatrixGroup)

Return the base ring of the matrix group `G`.

# Examples
```jldoctest
julia> F = GF(4); g = general_linear_group(2, F);

julia> base_ring(g) == F
true
```
"""
base_ring(G::MatrixGroup{RE}) where RE <: RingElem = G.ring::parent_type(RE)

Expand All @@ -492,7 +584,13 @@ base_ring_type(::Type{<:MatrixGroup{RE}}) where {RE} = parent_type(RE)
"""
degree(G::MatrixGroup)

Return the degree of the matrix group `G`, i.e. the number of rows of its matrices.
Return the degree of `G`, i.e., the number of rows of its matrices.

# Examples
```jldoctest
julia> degree(GL(4, 2))
4
```
"""
degree(G::MatrixGroup) = G.deg

Expand Down Expand Up @@ -543,7 +641,7 @@ function compute_order(G::MatrixGroup{T}) where {T <: Union{AbsSimpleNumFieldEle
return ZZRingElem(GAPWrap.Size(GapObj(G)))
else
n = order(isomorphic_group_over_finite_field(G)[1])
GAP.Globals.SetSize(GapObj(G), GAP.Obj(n))
set_order(G, n)
return n
end
end
Expand Down
Loading
Loading