diff --git a/src/intervals/arithmetic.jl b/src/intervals/arithmetic.jl index ed8360e53..1209fbc92 100644 --- a/src/intervals/arithmetic.jl +++ b/src/intervals/arithmetic.jl @@ -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 diff --git a/src/multidim/intervalbox.jl b/src/multidim/intervalbox.jl index 897ce72fc..d154f7f8a 100644 --- a/src/multidim/intervalbox.jl +++ b/src/multidim/intervalbox.jl @@ -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...) diff --git a/test/multidim_tests/multidim.jl b/test/multidim_tests/multidim.jl index 407d6debf..dfe9ce775 100644 --- a/test/multidim_tests/multidim.jl +++ b/test/multidim_tests/multidim.jl @@ -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