diff --git a/src/AbstractHyperrectangle.jl b/src/AbstractHyperrectangle.jl index 8e1881fb75..d9de15faa0 100644 --- a/src/AbstractHyperrectangle.jl +++ b/src/AbstractHyperrectangle.jl @@ -58,39 +58,36 @@ end # iterator that wraps the generator matrix struct HyperrectangleGeneratorIterator{AH<:AbstractHyperrectangle} H::AH - len::Int + nonflats::Vector{Int} # dimensions along which `H` is not flat + dim::Int # total number of dimensions of `H` (stored for efficiency) function HyperrectangleGeneratorIterator(H::AH) where {N<:Real, AH<:AbstractHyperrectangle{N}} - len = dim(H) - for i in 1:len - if radius_hyperrectangle(H, i) == zero(N) - len -= 1 + n = dim(H) + nonflats = Vector{Int}() + sizehint!(nonflats, n) + @inbounds for i in 1:n + if radius_hyperrectangle(H, i) != zero(N) + push(nonflats, i) end end - return new{AH}(H, len) + return new{AH}(H, nonflats, n) end end -Base.length(it::HyperrectangleGeneratorIterator) = it.len +Base.length(it::HyperrectangleGeneratorIterator) = length(it.nonflats) Base.eltype(::Type{<:HyperrectangleGeneratorIterator{<:AbstractHyperrectangle{N}}}) where {N} = Approximations.UnitVector{N} function Base.iterate(it::HyperrectangleGeneratorIterator{<:AH}, state::Int=1) where {N, AH<:AbstractHyperrectangle{N}} - local r - while true - if state > dim(it.H) - return nothing - end - r = radius_hyperrectangle(it.H, state) - if r != zero(N) - break - end - state += 1 + if state > length(it.nonflats) + return nothing end - g = Approximations.UnitVector(state, dim(it.H), r) + i = it.nonflats[state] + r = radius_hyperrectangle(it.H, i) + g = Approximations.UnitVector(i, it.dim, r) state += 1 return (g, state) end @@ -98,7 +95,7 @@ end """ generators(H::AbstractHyperrectangle) -Return an iterator over the (single) generator of a hyperrectangular set. +Return an iterator over the generators of a hyperrectangular set. ### Input