Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve mince and add method for non-uniform partition of IntervalBox #467

Merged
merged 6 commits into from
Jun 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/intervals/arithmetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ convert(::Type{Integer}, a::Interval) = isinteger(a) ?
Splits `x` in `n` intervals of the same diameter, which are returned
as a vector.
"""
function mince(x::Interval, n)
@inline function mince(x::Interval, n)
nodes = range(x.lo, x.hi, length = n+1)
return [Interval(nodes[i], nodes[i+1]) for i in 1:length(nodes)-1]
return Interval.(nodes[1:n], nodes[2:n+1])
end
34 changes: 19 additions & 15 deletions src/multidim/intervalbox.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,29 +115,33 @@ Base.:(==)(x::IntervalBox, y::IntervalBox) = x.v == y.v


"""
mince(x::IntervalBox, n)
mince(x::IntervalBox, n::Int)

Splits `x` in `n` intervals in each dimension of the same diameter. These
intervals are combined in all possible `IntervalBox`-es, which are returned
as a vector.
"""
@generated function mince(x::IntervalBox{N,T}, n) where {N,T}
quote
nodes_matrix = Array{Interval{T},2}(undef, n, N)
for i in 1:N
nodes_matrix[1:n,i] .= mince(x[i], n)
end

nodes = IntervalBox{$N,T}[]
Base.Cartesian.@nloops $N i _->(1:n) begin
Base.Cartesian.@nextract $N ival d->nodes_matrix[i_d, d]
ibox = Base.Cartesian.@ncall $N IntervalBox ival
push!(nodes, ibox)
end
nodes
@inline mince(x::IntervalBox{N,T}, n::Int) where {N,T} =
mince(x, ntuple(_ -> n, N))

"""
mince(x::IntervalBox, ncuts::::NTuple{N,Int})

Splits `x[i]` in `ncuts[i]` intervals . These intervals are
combined in all possible `IntervalBox`-es, which are returned
as a vector.
"""
@inline function mince(x::IntervalBox{N,T}, ncuts::NTuple{N,Int}) where {N,T}
minced_intervals = [mince(x[i], ncuts[i]) for i in 1:N]
minced_boxes = Vector{IntervalBox{N,T}}(undef, prod(ncuts))

for (k, cut_indices) in enumerate(CartesianIndices(ncuts))
minced_boxes[k] = IntervalBox([minced_intervals[i][cut_indices[i]] for i in 1:N])
end
return minced_boxes
end


hull(a::IntervalBox{N,T}, b::IntervalBox{N,T}) where {N,T} = IntervalBox(hull.(a[:], b[:]))
hull(a::Vector{IntervalBox{N,T}}) where {N,T} = hull(a...)

Expand Down
10 changes: 10 additions & 0 deletions test/multidim_tests/multidim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -306,18 +306,28 @@ end
@test vb2 == vv
@test hull(vb2...) == ib2
@test hull(vb2) == ib2
@test mince(ib2, (4,4)) == vb2
@test mince(ib2, (1,4)) == [ (-1 .. 1)×(-1 .. -0.5), (-1 .. 1)×(-0.5 .. 0),
(-1 .. 1)×(0 .. 0.5), (-1 .. 1)×(0.5 .. 1)]
@test hull(mince(ib2, (1,4))) == ib2

ib3 = IntervalBox(-1..1, 3)
vb3 = mince(ib3, 4)
@test length(vb3) == 4^3
@test hull(vb3...) == ib3
@test hull(vb3) == ib3
@test mince(ib3, (4,4,4)) == vb3
@test mince(ib3, (2,1,1)) == [(-1 .. 0)×(-1 .. 1)×(-1 .. 1),
(0 .. 1)×(-1 .. 1)×(-1 .. 1)]
@test hull(mince(ib3, (2,1,1))) == ib3

ib4 = IntervalBox(-1..1, 4)
vb4 = mince(ib4, 4)
@test length(vb4) == 4^4
@test hull(vb4...) == ib4
@test hull(vb4) == ib4
@test mince(ib4,(4,4,4,4)) == vb4
@test mince(ib4,(1,1,1,1)) == [ib4]
end

@testset "Special box constructors" begin
Expand Down