Skip to content

Commit

Permalink
Merge pull request #467 from JuliaIntervals/lb/mince
Browse files Browse the repository at this point in the history
Improve mince and add method for non-uniform partition of IntervalBox
  • Loading branch information
Kolaru committed Jun 3, 2021
2 parents c7602f4 + 430ed81 commit a3dc27f
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 17 deletions.
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

0 comments on commit a3dc27f

Please sign in to comment.