Skip to content

Commit

Permalink
Merge pull request jump-dev#2179 from JuliaOpt/bl/empty_sparse
Browse files Browse the repository at this point in the history
Fix construction of empty SparseAxisArray
  • Loading branch information
blegat authored Mar 5, 2020
2 parents 3af8a2c + b31935a commit 1df1e06
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 3 deletions.
13 changes: 12 additions & 1 deletion src/Containers/container.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,22 @@ function container(f::Function, indices::VectorizedProductIterator,
return DenseAxisArray(map(I -> f(I...), indices), indices.prod.iterators...)
end
default_container(::NestedIterator) = SparseAxisArray
# Returns the element type. If it is unknown but it is known to be `N`-tuples,
# returns `NTuple{N, Any}`.
_eltype_or_any(indices::Array) = eltype(indices)
function container(f::Function, indices,
::Type{SparseAxisArray})
# Same as `map` but does not allocate the resulting vector.
mappings = Base.Generator(I -> I => f(I...), indices)
# Same as `Dict(mapping)` but it will error if two indices are the same.
data = NoDuplicateDict(mappings)
return SparseAxisArray(data.dict)
dict = data.dict
if isempty(dict)
# If `dict` is empty, it was not able to determine the type
# of the key hence the type of `dict` is `Dict{Any, Any}`.
# This is an issue since `SparseAxisArray` needs the key
# type to be a tuple.
dict = Dict{_eltype_or_any(indices), Any}()
end
return SparseAxisArray(dict)
end
4 changes: 2 additions & 2 deletions src/Containers/macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,9 @@ function container_code(idxvars, indices, code, requested_container)
return :(error($error_message))
end
if requested_container == :DenseAxisArray
requested_container = :(JuMP.Containers.DenseAxisArray)
requested_container = :(Containers.DenseAxisArray)
elseif requested_container == :SparseAxisArray
requested_container = :(JuMP.Containers.SparseAxisArray)
requested_container = :(Containers.SparseAxisArray)
end
esc_idxvars = esc.(idxvars)
func = :(($(esc_idxvars...),) -> $code)
Expand Down
1 change: 1 addition & 0 deletions src/Containers/nested_iterator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,4 @@ function tail_iterate(iterators, condition, elems, states, prev_states)
end
Base.iterate(it::NestedIterator) = first_iterate(it.iterators, it.condition, tuple(), tuple())
Base.iterate(it::NestedIterator, states) = tail_iterate(it.iterators, it.condition, tuple(), states, tuple())
_eltype_or_any(::NestedIterator{<:Tuple{Vararg{Any,N}}}) where N = NTuple{N, Any}
1 change: 1 addition & 0 deletions src/Containers/vectorized_product_iterator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,4 @@ _prod_indices(t::Tuple) = (Base.OneTo(length(t[1])), _prod_indices(Base.tail(t))
Base.ndims(it::VectorizedProductIterator) = length(axes(it))
Base.length(it::VectorizedProductIterator) = prod(size(it))
Base.iterate(it::VectorizedProductIterator, args...) = iterate(it.prod, args...)
_eltype_or_any(it::VectorizedProductIterator) = eltype(it.prod)
8 changes: 8 additions & 0 deletions test/Containers/macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,13 @@ using JuMP.Containers
@test x isa Containers.SparseAxisArray{Int, 2}
Containers.@container(x[i=1:10; iseven(i)], i)
@test x isa Containers.SparseAxisArray{Int, 1}
Containers.@container(x[i=1:0, j=i:0], i)
@test x isa SparseAxisArray{Any,2,Tuple{Any,Any}}
Containers.@container(x[i=1:2, j=1:2; false], i)
@test x isa SparseAxisArray{Any,2,Tuple{Any,Any}}
Containers.@container(x[i=1:0, j=2:1], i, container = SparseAxisArray)
@test x isa SparseAxisArray{Any,2,Tuple{Int,Int}}
Containers.@container(x[i=1:0, j=1:0], i, container = SparseAxisArray)
@test x isa SparseAxisArray{Any,2,Tuple{Int,Int}}
end
end

0 comments on commit 1df1e06

Please sign in to comment.