""" 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( S::AbstractVector{T}, center::T = one(first(S)); radius = 2, op = *, ) where {T} ball = [center] sizes = [1] if radius ≤ 0 return ball, sizes[2:end] else ball = union!(ball, [center * s for s in S]) push!(sizes, length(ball)) if radius == 1 return ball, sizes[2:end] else for _ in 2:radius new = collect( op(o, s) for o in @view(ball[sizes[end-1]:end]) for s in S ) ball = union!(ball, new) push!(sizes, length(ball)) end end return ball, sizes[2:end] end # return wlmetric_ball_serial(S, center; radius = radius, op = op) end