Skip to content

Commit

Permalink
move code from Oscar.jl/experimental/GModule/Misc.jl here (#1675)
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasBreuer authored Apr 25, 2024
1 parent 1928f12 commit 86dba7a
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/Map.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ function domain end
function codomain end
function image_fn end

function coimage(h::Map)
return quo(domain(h), kernel(h)[1])
end

function check_composable(a::Map, b::Map)
codomain(a) !== domain(b) && error("Incompatible maps")
end
Expand Down
3 changes: 3 additions & 0 deletions src/Matrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,9 @@ end
Base.IteratorSize(::Type{<:MatrixElem}) = Base.HasShape{2}()
Base.IteratorEltype(::Type{<:MatrixElem}) = Base.HasEltype() # default

Base.pairs(M::MatElem) = Base.pairs(IndexCartesian(), M)
Base.pairs(::IndexCartesian, M::MatElem) = Base.Iterators.Pairs(M, CartesianIndices(axes(M)))

###############################################################################
#
# Block replacement
Expand Down
47 changes: 47 additions & 0 deletions src/Module.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#
###############################################################################

Base.eltype(M::FPModule{T}) where T <: FinFieldElem = elem_type(M)

function zero(M::FPModule{T}) where T <: RingElement
R = base_ring(M)
return M(zero_matrix(R, 1, ngens(M)))
Expand All @@ -27,6 +29,21 @@ function check_parent(M::FPModuleElem{T}, N::FPModuleElem{T}) where T <: RingEle
parent(M) !== parent(N) && error("Incompatible modules")
end

is_finite(M::FPModule{<:FinFieldElem}) = true

function is_sub_with_data(M::FPModule{T}, N::FPModule{T}) where T <: RingElement
fl = is_submodule(N, M)
if fl
return fl, hom(M, N, elem_type(N)[N(m) for m = gens(M)])
else
return fl, hom(M, N, elem_type(N)[zero(N) for m = gens(M)])
end
end

Base.issubset(M::FPModule{T}, N::FPModule{T}) where T <: RingElement = is_submodule(M, N)

order(M::FPModule{<:FinFieldElem}) = order(base_ring(M))^dim(M)

###############################################################################
#
# Unary operators
Expand Down Expand Up @@ -300,3 +317,33 @@ function rand(rng::AbstractRNG, M::FPModule{T}, vals...) where T <: RingElement
end

rand(M::FPModule, vals...) = rand(Random.GLOBAL_RNG, M, vals...)

###############################################################################
#
# Iteration
#
###############################################################################

Base.length(M::FPModule{T}) where T <: FinFieldElem = Int(order(M))

function Base.iterate(M::FPModule{T}) where T <: FinFieldElem
k = base_ring(M)
if dim(M) == 0
return zero(M), iterate([1])
end
p = Base.Iterators.ProductIterator(Tuple([k for i=1:dim(M)]))
f = iterate(p)
return M(elem_type(k)[f[1][i] for i=1:dim(M)]), (f[2], p)
end

function Base.iterate(M::FPModule{T}, st::Tuple{<:Tuple, <:Base.Iterators.ProductIterator}) where T <: FinFieldElem
n = iterate(st[2], st[1])
if n === nothing
return n
end
return M(elem_type(base_ring(M))[n[1][i] for i=1:dim(M)]), (n[2], st[2])
end

function Base.iterate(::FPModule{<:FinFieldElem}, ::Tuple{Int64, Int64})
return nothing
end
2 changes: 2 additions & 0 deletions src/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ export is_even
export is_exact_type
export is_finite
export is_finite_order
export is_free
export is_gen
export is_hermitian
export is_hessenberg
Expand Down Expand Up @@ -308,6 +309,7 @@ export is_square_with_sqrt
export is_squarefree
export is_submodule
export is_subset
export is_sub_with_data
export is_symmetric
export is_term
export is_term_recursive
Expand Down
7 changes: 7 additions & 0 deletions src/generic/DirectSum.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ base_ring(N::DirectSumModule{T}) where T <: RingElement = base_ring(N.m[1])

base_ring(v::DirectSumModuleElem{T}) where T <: RingElement = base_ring(v.parent)

dim(M::DirectSumModule{<:FieldElem}) = sum(dim(x) for x = M.m)

number_of_generators(N::DirectSumModule{T}) where T <: RingElement = sum(ngens(M) for M in N.m)

gens(N::DirectSumModule{T}) where T <: RingElement = [gen(N, i) for i = 1:ngens(N)]
Expand Down Expand Up @@ -248,6 +250,11 @@ function ModuleHomomorphism(D::DirectSumModule{T}, A::DirectSumModule{T}, m::Mat
return ModuleHomomorphism(D, A, transpose(hvcat(Tuple([length(SD) for i = 1:length(SA)]), map(x->transpose(x.matrix), m)...)))
end

function AbstractAlgebra.hom(M::DirectSumModule{T}, N::DirectSumModule{T}, mp::Vector{ModuleHomomorphism{T}}) where T
@assert length(M.m) == length(mp) == length(N.m)
return hom(M, N, cat(map(matrix, mp)..., dims = (1,2)))
end

function AbstractAlgebra.hom(A::AbstractAlgebra.Generic.DirectSumModule{T}, B::AbstractAlgebra.Generic.DirectSumModule{T}, M::Matrix{<:Map{<:AbstractAlgebra.FPModule{T}, <:AbstractAlgebra.FPModule{T}}}) where {T}
pro = canonical_projections(A)
im = canonical_injections(B)
Expand Down
2 changes: 2 additions & 0 deletions src/generic/FreeModule.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ function check_parent(m1::FreeModuleElem{T}, m2::FreeModuleElem{T}) where T <: U
parent(m1) !== parent(m2) && error("Incompatible free modules")
end

is_free(M::FreeModule) = true

@doc raw"""
rank(M::FreeModule{T}) where T <: Union{RingElement, NCRingElem}
Expand Down
2 changes: 2 additions & 0 deletions src/generic/Map.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ end

Base.inv(f::AbstractAlgebra.Map(AbstractAlgebra.IdentityMap)) = f

AbstractAlgebra.matrix(phi::IdentityMap{<:AbstractAlgebra.FPModule}) = identity_matrix(base_ring(domain(phi)), dim(domain(phi)))

################################################################################
#
# FunctionalMap
Expand Down
5 changes: 5 additions & 0 deletions src/generic/Misc/Poly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ function roots(R::Field, f::PolyRingElem)
return roots(f1)
end

function roots(a::FinFieldElem, i::Int)
_, x = polynomial_ring(parent(a), cached = false)
return roots(x^i-a)
end

function sturm_sequence(f::PolyRingElem{<:FieldElem})
g = f
h = derivative(g)
Expand Down
53 changes: 53 additions & 0 deletions src/generic/ModuleHomomorphism.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,44 @@ inverse_mat(f::Map(ModuleIsomorphism)) = f.inverse_matrix

inverse_image_fn(f::Map(ModuleIsomorphism)) = f.inverse_image_fn

###############################################################################
#
# Unary operators
#
###############################################################################

Base.:-(a::ModuleHomomorphism) = hom(domain(a), codomain(a), -matrix(a))

###############################################################################
#
# Binary operators
#
###############################################################################

Base.:*(a::T, b::ModuleHomomorphism{T}) where {T} = hom(domain(b), codomain(b), a * matrix(b))
Base.:*(a::T, b::ModuleIsomorphism{T}) where {T} = hom(domain(b), codomain(b), a * matrix(b))
Base.:+(a::ModuleHomomorphism, b::ModuleHomomorphism) = hom(domain(a), codomain(a), matrix(a) + matrix(b))
Base.:-(a::ModuleHomomorphism, b::ModuleHomomorphism) = hom(domain(a), codomain(a), matrix(a) - matrix(b))

###############################################################################
#
# Comparison
#
###############################################################################

function Base.:(==)(a::Union{ModuleHomomorphism, ModuleIsomorphism}, b::Union{ModuleHomomorphism, ModuleIsomorphism})
domain(a) === domain(b) || return false
codomain(a) === codomain(b) || return false
return matrix(a) == matrix(b)
end

function Base.hash(a::Union{ModuleHomomorphism, ModuleIsomorphism}, h::UInt)
h = hash(domain(a), h)
h = hash(codomain(a), h)
h = hash(matrix(a), h)
return h
end

###############################################################################
#
# String I/O
Expand Down Expand Up @@ -68,6 +106,10 @@ function Base.inv(f::Map(ModuleIsomorphism))
return ModuleIsomorphism{T}(codomain(f), domain(f), inverse_mat(f), matrix(f))
end

function Base.inv(f::ModuleHomomorphism)
return hom(codomain(f), domain(f), inv(matrix(f)))
end

###############################################################################
#
# Call overload
Expand Down Expand Up @@ -139,3 +181,14 @@ function ModuleIsomorphism(M1::AbstractAlgebra.FPModule{T},
end
return ModuleIsomorphism{T}(M1, M2, M, M_inv)
end

function hom(V::AbstractAlgebra.Module, W::AbstractAlgebra.Module, v::Vector{<:ModuleElem}; check::Bool = true)
if ngens(V) == 0
return ModuleHomomorphism(V, W, zero_matrix(base_ring(V), ngens(V), ngens(W)))
end
return ModuleHomomorphism(V, W, reduce(vcat, [x.v for x = v]))
end

function hom(V::AbstractAlgebra.Module, W::AbstractAlgebra.Module, v::MatElem; check::Bool = true)
return ModuleHomomorphism(V, W, v)
end
1 change: 1 addition & 0 deletions src/generic/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export inverse_mat
export invmod
export is_compatible
export is_divisible_by
export is_free
export is_homogeneous
export is_power
export is_rimhook
Expand Down

0 comments on commit 86dba7a

Please sign in to comment.