163 lines
4.1 KiB
Julia
163 lines
4.1 KiB
Julia
module Groups
|
|
|
|
using AbstractAlgebra
|
|
import AbstractAlgebra: Group, GroupElem, Ring
|
|
import AbstractAlgebra: parent, parent_type, elem_type
|
|
import AbstractAlgebra: order, gens, matrix_repr
|
|
|
|
import Base: length, ==, hash, show, convert, eltype, iterate
|
|
import Base: inv, reduce, *, ^, power_by_squaring
|
|
import Base: findfirst, findnext, findlast, findprev, replace
|
|
import Base: deepcopy_internal
|
|
|
|
using LinearAlgebra
|
|
using ThreadsX
|
|
|
|
export gens, FreeGroup, Aut, SAut
|
|
|
|
include("types.jl")
|
|
|
|
include("FreeGroup.jl")
|
|
include("FPGroups.jl")
|
|
include("AutGroup.jl")
|
|
|
|
include("symbols.jl")
|
|
include("fallbacks.jl")
|
|
include("words.jl")
|
|
include("hashing.jl")
|
|
include("freereduce.jl")
|
|
include("arithmetic.jl")
|
|
include("findreplace.jl")
|
|
|
|
include("DirectPower.jl")
|
|
include("WreathProducts.jl")
|
|
|
|
###############################################################################
|
|
#
|
|
# String I/O
|
|
#
|
|
|
|
function Base.show(io::IO, W::GWord)
|
|
if length(W) == 0
|
|
print(io, "(id)")
|
|
else
|
|
join(io, (string(s) for s in syllables(W)), "*")
|
|
end
|
|
end
|
|
|
|
function Base.show(io::IO, s::T) where {T<:GSymbol}
|
|
if s.pow == 1
|
|
print(io, string(s.id))
|
|
else
|
|
print(io, "$(s.id)^$(s.pow)")
|
|
end
|
|
end
|
|
|
|
###############################################################################
|
|
#
|
|
# Misc
|
|
#
|
|
|
|
"""
|
|
gens(G::AbstractFPGroups)
|
|
Return vector of generators of `G`, as its elements.
|
|
"""
|
|
AbstractAlgebra.gens(G::AbstractFPGroup) = G.(G.gens)
|
|
|
|
"""
|
|
wlmetric_ball(S::AbstractVector{<:GroupElem}
|
|
[, center=one(first(S)); radius=2, op=*])
|
|
Compute metric ball as a list of elements of non-decreasing length, given the
|
|
word-length metric on the group generated by `S`. The ball is centered at `center`
|
|
(by default: the identity element). `radius` and `op` keywords specify the
|
|
radius and multiplication operation to be used.
|
|
"""
|
|
function wlmetric_ball_serial(
|
|
S::AbstractVector{T};
|
|
radius = 2,
|
|
op = *,
|
|
) where {T<:Union{GroupElem,NCRingElem}}
|
|
old = unique!([one(first(S)), S...])
|
|
sizes = [1, length(old)]
|
|
for i = 2:radius
|
|
new = collect(op(o, s) for o in @view(old[sizes[end-1]:end]) for s in S)
|
|
append!(old, new)
|
|
resize!(new, 0)
|
|
old = unique!(old)
|
|
push!(sizes, length(old))
|
|
end
|
|
return old, sizes[2:end]
|
|
end
|
|
|
|
function wlmetric_ball_thr(
|
|
S::AbstractVector{T};
|
|
radius = 2,
|
|
op = *,
|
|
) where {T<:Union{GroupElem,NCRingElem}}
|
|
old = unique!([one(first(S)), S...])
|
|
sizes = [1, length(old)]
|
|
for r = 2:radius
|
|
begin
|
|
new = ThreadsX.collect(
|
|
op(o, s) for o in @view(old[sizes[end-1]:end]) for s in S
|
|
)
|
|
ThreadsX.foreach(hash, new)
|
|
end
|
|
append!(old, new)
|
|
resize!(new, 0)
|
|
old = ThreadsX.unique(old)
|
|
push!(sizes, length(old))
|
|
end
|
|
return old, sizes[2:end]
|
|
end
|
|
|
|
function wlmetric_ball_serial(
|
|
S::AbstractVector{T},
|
|
center::T;
|
|
radius = 2,
|
|
op = *,
|
|
) where {T<:Union{GroupElem,NCRingElem}}
|
|
E, sizes = wlmetric_ball_serial(S, radius = radius, op = op)
|
|
isone(center) && return E, sizes
|
|
return c .* E, sizes
|
|
end
|
|
|
|
function wlmetric_ball_thr(
|
|
S::AbstractVector{T},
|
|
center::T;
|
|
radius = 2,
|
|
op = *,
|
|
) where {T<:Union{GroupElem,NCRingElem}}
|
|
E, sizes = wlmetric_ball_thr(S, radius = radius, op = op)
|
|
isone(center) && return E, sizes
|
|
return c .* E, sizes
|
|
end
|
|
|
|
function wlmetric_ball(
|
|
S::AbstractVector{T},
|
|
center::T = one(first(S));
|
|
radius = 2,
|
|
op = *,
|
|
threading = true,
|
|
) where {T<:Union{GroupElem,NCRingElem}}
|
|
threading && return wlmetric_ball_thr(S, center, radius = radius, op = op)
|
|
return return wlmetric_ball_serial(S, center, radius = radius, op = op)
|
|
end
|
|
|
|
"""
|
|
image(w::GWord, homomorphism; kwargs...)
|
|
Evaluate homomorphism `homomorphism` on a group word (element) `w`.
|
|
`homomorphism` needs to implement
|
|
> `hom(w; kwargs...)`,
|
|
where `hom(;kwargs...)` returns the value at the identity element.
|
|
"""
|
|
function image(w::GWord, hom; kwargs...)
|
|
return reduce(
|
|
*,
|
|
(hom(s; kwargs...) for s in syllables(w)),
|
|
init = hom(; kwargs...),
|
|
)
|
|
end
|
|
|
|
end # of module Groups
|