Skip to content

(*)(::SparseMatrixCSC, ::BitVector) no longer respects false as a strong zero on 1.13 #724

@waylonwh

Description

@waylonwh

On Julia 1.13 / SparseArrays 1.13.0, multiplying a sparse Float64 matrix that contains Inf (or NaN) by a BitVector returns NaN where earlier versions returned 0.0. The false entries of the BitVector no longer act as strong zeros.

Minimum working example

On Julia 1.12:

julia> VERSION
v"1.12.6"

julia> pkgversion(SparseArrays)
v"1.12.0"

julia> spdiagm([Inf]) * BitVector([false])
1-element Vector{Float64}:
 0.0

julia> Inf * false
0.0

On Julia 1.13:

julia> VERSION
v"1.13.0-rc1"

julia> pkgversion(SparseArrays)
v"1.13.0"

julia> spdiagm([Inf]) * BitVector([false])
1-element Vector{Float64}:
 NaN

julia> Inf * false
0.0

Cause

Possibly introduced by #666. The inner accumulation in _spmatmul! changed from += to muladd:

- C[rv[j], k] += nzv[j]*αxj
+ C[rvj, k] = muladd(nzv[j], αxj, C[rvj, k])

https://github.com/JuliaSparse/SparseArrays.jl/pull/666/changes#diff-c92a7388d7c72d7e5be3445ed18e898354d6c455b888839e303fe1e6d3a28e7aR172

With a Bool operand, αxj stays false::Bool, so the old code computed Inf * false == 0.0 (strong zero). muladd promotes the Bool to Float64 first, which loses the strong zero:

julia> muladd(Inf, false, 0.0)
NaN

julia> Inf * false + 0.0
0.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions