1
0
mirror of https://github.com/kalmarek/Groups.jl.git synced 2025-01-12 22:22:32 +01:00

refactor wlmetric_ball

This commit is contained in:
Marek Kaluba 2021-07-17 20:23:41 +02:00
parent 27e768639d
commit bcce338754
No known key found for this signature in database
GPG Key ID: 8BF1A3855328FC15

View File

@ -6,50 +6,34 @@ word-length metric on the group generated by `S`. The ball is centered at `cente
(by default: the identity element). `radius` and `op` keywords specify the (by default: the identity element). `radius` and `op` keywords specify the
radius and multiplication operation to be used. radius and multiplication operation to be used.
""" """
function wlmetric_ball_serial(S::AbstractVector{T}; radius = 2, op = *) where {T} function wlmetric_ball_serial(S::AbstractVector{T}, center::T=one(first(S)); radius = 2, op = *) where {T}
@assert radius > 0 @assert radius >= 1
old = unique!([one(first(S)), S...]) old = unique!([center, [center*s for s in S]...])
sizes = [1, length(old)] return _wlmetric_ball(S, old, radius, op, collect, unique!)
for i in 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 end
function wlmetric_ball_thr(S::AbstractVector{T}; radius = 2, op = *) where {T} function wlmetric_ball_thr(S::AbstractVector{T}, center::T=one(first(S)); radius = 2, op = *) where {T}
@assert radius > 0 @assert radius >= 1
old = unique!([one(first(S)), S...]) old = unique!([center, [center*s for s in S]...])
return _wlmetric_ball(S, old, radius, op, ThreadsX.collect, ThreadsX.unique)
end
function _wlmetric_ball(S, old, radius, op, collect, unique)
sizes = [1, length(old)] sizes = [1, length(old)]
for r in 2:radius for r in 2:radius
begin old = let old = old, S = S,
new = new = collect(
ThreadsX.collect(op(o, s) for o in @view(old[sizes[end-1]:end]) for s in S) (g = op(o, s); hash(g); g)
ThreadsX.foreach(hash, new) for o in @view(old[sizes[end-1]:end]) for s in S
)
append!(old, new)
unique(old)
end end
append!(old, new)
resize!(new, 0)
old = ThreadsX.unique(old)
push!(sizes, length(old)) push!(sizes, length(old))
end end
return old, sizes[2:end] return old, sizes[2:end]
end end
function wlmetric_ball_serial(S::AbstractVector{T}, center::T; radius = 2, op = *) where {T}
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}
E, sizes = wlmetric_ball_thr(S, radius = radius, op = op)
isone(center) && return E, sizes
return c .* E, sizes
end
function wlmetric_ball( function wlmetric_ball(
S::AbstractVector{T}, S::AbstractVector{T},
center::T = one(first(S)); center::T = one(first(S));