add DirectPowerIter struct to iterate over DirectProduct

This commit is contained in:
kalmarek 2018-08-08 14:12:55 +02:00
parent 60c04f0dbd
commit e6d67ca3f7
2 changed files with 37 additions and 9 deletions

View File

@ -277,18 +277,45 @@ end
#
###############################################################################
import Base: size, length, start, next, done, eltype
struct DirectPowerIter{Gr<:AbstractAlgebra.Group, GrEl<:AbstractAlgebra.GroupElem}
G::Gr
N::Int
elts::Vector{GrEl}
totalorder::Int
orderG::Int
end
function DirectPowerIter(G::Gr, N::Integer) where {Gr<:AbstractAlgebra.Group}
return DirectPowerIter{Gr, elem_type(G)}(
G,
N,
vec(collect(elements(G))),
Int(order(G))^N,
Int(order(G))
)
end
Base.size(DPIter::DirectPowerIter) = ntuple(i -> DPIter.orderG, DPIter.N)
Base.length(DPIter::DirectPowerIter) = DPIter.totalorder
Base.start(::DirectPowerIter) = 0
function Base.next(DPIter::DirectPowerIter, state)
idx = ind2sub(size(DPIter), state+1)
return DirectProductGroupElem([DPIter.elts[i] for i in idx]), state+1
end
Base.done(DPIter::DirectPowerIter, state) = DPIter.totalorder <= state
Base.eltype(::Type{DirectPowerIter{Gr, GrEl}}) where {Gr, GrEl} = DirectProductGroupElem{GrEl}
doc"""
elements(G::DirectProductGroup)
> Returns `generator` that produces all elements of group `G` (provided that
> `G.group` implements the `elements` method).
"""
# TODO: can Base.product handle generators?
# now it returns nothing's so we have to collect ellements...
function elements(G::DirectProductGroup)
elts = collect(elements(G.group))
cartesian_prod = Base.product([elts for _ in 1:G.n]...)
return (DirectProductGroupElem([elt...]) for elt in cartesian_prod)
end
elements(G::DirectProductGroup) = DirectPowerIter(G.group, G.n)
doc"""
order(G::DirectProductGroup)

View File

@ -201,8 +201,9 @@ end
matrix_repr(g::WreathProductElem) = Any[matrix_repr(g.p) g.n]
function elements(G::WreathProduct)
iter = Base.product(collect(elements(G.N)), collect(elements(G.P)))
return (WreathProductElem(n, p, false) for (n,p) in iter)
Nelts = collect(elements(G.N))
Pelts = collect(elements(G.P))
return (WreathProductElem(n, p, false) for n in Nelts, p in Pelts)
end
order(G::WreathProduct) = order(G.P)*order(G.N)