-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Don't access uninitialized indices in tril!
/triu!
for numeric arrays
#52528
Conversation
tril!
/triu!
for numeric arrays
It seems like the current implementation is insufficiently general. I expect it to fail sometimes on matrices with julia> x = fill!(Matrix{Union{Float64,ComplexF64}}(undef,3,3), 0.0)
3×3 Matrix{Union{Float64, ComplexF64}}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
julia> x isa AbstractMatrix{<:Number}
true
julia> x[1,1] = zero(eltype(x))
ERROR: MethodError: no method matching Union{Float64, ComplexF64}(::Int64) The above matrix would fit the signature of the provided specialization but would then throw an error because Would it work to assign each entry by checking whether Not sure what the best resolution is. |
Interesting observation! This seems to also impact other structured matrix types: julia> Diagonal(Union{Float64,ComplexF64}[1,2])
ERROR: MethodError: no method matching Union{Float64, ComplexF64}(::Int64) where the off-diagonal zeros are not defined. In that case, there isn't a parent to probe, either. Still, this PR appears to break this case, as the following used to work until now: julia> UpperTriangular(Matrix{Union{Float64,ComplexF64}}(undef, 2, 2))
2×2 UpperTriangular{Union{Float64, ComplexF64}, Matrix{Union{Float64, ComplexF64}}}:
0.0+0.0im 0.0+0.0im
⋅ 0.0+0.0im |
The julia> Diagonal(Union{Float64,ComplexF64}[1.0,2.0])
2×2 Diagonal{Union{Float64, ComplexF64}, Vector{Union{Float64, ComplexF64}}}:
Error showing value of type Diagonal{Union{Float64, ComplexF64}, Vector{Union{Float64, ComplexF64}}}:
ERROR: MethodError: no method matching Union{Float64, ComplexF64}(::Int64)
julia> Diagonal([1.0,2.0]) # why did it even need to know what `zero(eltype(...))` is? it's not shown
2×2 Diagonal{Float64, Vector{Float64}}:
1.0 ⋅
⋅ 2.0 Of course, a matrix with structural zeros requires a valid From the stacktrace, it appears that |
Perhaps we should use |
Gentle bump |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if the haszero
trait should be declared public
, so that other packages such as StaticArrays could indicate their types as suitable. But we could think about that later, I guess.
Otherwise LGTM.
@mikmoore I wonder if you foresee any issues with the current implementation? |
Looks good to me. The last "arguably useful" holdout I foresee is union types. One might attempt One could go further and remove I could see the |
This specializes the generic
triu!
andtril!
methods for arrays of numbers, where a zero is known to exist. In such cases, we don't need to read the possibly uninitialized values of the elements at the indices that are to be assigned to. After this, the following would be possible: