FillArrays.jl
FillArrays.jl copied to clipboard
`real(::Fill)` gives an array of arrays?
This is surprising:
julia> real(Fill(1+im)) isa Array{<:AbstractArray{Int}}
true
julia> real(fill(1+im)) isa Array{Int,0}
true
(jl_AeiBcQ) pkg> st
Status `/private/var/folders/yq/4p2zwd614y59gszh7y9ypyhh0000gn/T/jl_AeiBcQ/Project.toml`
[1a297f60] FillArrays v0.11.7
I guess it comes from this difference, via broadcast_preserving_zero_d:
julia> Fill(1) .+ Fill(2)
0-dimensional Fill{Int64}, with entry equal to 3
julia> fill(1) .+ fill(2)
3
This actually looks like a bug in Julia, why would 0-dimensional arrays have a different broadcasting behaviour:
julia> x + x
0-dimensional Array{Int64, 0}:
2
julia> x .+ x
2
I do think it's the intended behaviour, although I don't see it mentioned in the manual. Maybe broadcast never produces a 0-array, e.g. sqrt.(fill(pi)) isa Float64.
I think it’s more “unintended consequence of design: it follows because 0-dimensional arrays are treated like constants in broadcasting with vectors/matrices, but the special case where everything is 0-dimensional was probably not thought through.
I don’t think it’s going to change in Julia v1.x so yes I agree we should make Fill match. But I’ll open an issue so that perhaps this could be changed in Julia v2
https://github.com/JuliaLang/julia/issues/28866 is the issue, it seems.
Ah, I encountered the same issue: https://github.com/JuliaLang/julia/issues/28866#issuecomment-1143946830
Can I maybe add that this still exists, and also is not consistent? It works for -(), but not for conj, real, imag.
julia> A = Fill(1im)
0-dimensional Fill{Complex{Int64}}, with entry equal to 0 + 1im
julia> conj(A), real(A), imag(A), -A
(fill(Fill(0 - 1im)), fill(Fill(0)), fill(Fill(1)), Fill(0 - 1im))
julia> B = fill(1im)
0-dimensional Array{Complex{Int64}, 0}:
0 + 1im
julia> conj(B), real(B), imag(B), -B
(fill(0 - 1im), fill(0), fill(1), fill(0 - 1im))
Would you be ok with a PR that just manually fixes this by implementing the broadcast_preserving_zero_d, at least for the case with a single argument?
# makes 0-dimensional arrays behave like Julia Base
@inline function Base.broadcast_preserving_zero_d(f, As::AbstractFill...)
bc = broadcasted(f, As...)
return Base.materialize(bc)
end
If we'd agree on this, I can add some tests as well.
[edit] Alternatively, I could also just add special-case versions for the zero-dimensional versions.