From 5988555206a53e2e226e487b541f571858d5e8f9 Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Tue, 13 Oct 2026 03:07:26 +0000 Subject: [PATCH 1/2] Rank `missing` in `findmin` and `findmax` of a sparse matrix as dense does Co-Authored-By: Claude Opus 5.5 --- src/reductions.jl | 6 ++++-- test/reductions.jl | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/reductions.jl b/src/reductions.jl index 3930d243..b5cf4f16 100644 --- a/src/reductions.jl +++ b/src/reductions.jl @@ -724,8 +724,10 @@ function _findr(op, A::AbstractSparseMatrixCSC{Tv}, region) where {Tv} end end -_isless_fm(a, b) = b == b && ( a != a || isless(a, b) ) -_isgreater_fm(a, b) = b == b && ( a != a || isless(b, a) ) +# whether `a` replaces the best value so far `b`, by the test of Base's dense `findmin` and +# `findmax`, so that the result agrees with dense on `NaN`, `missing` and signed zeros +_isless_fm(a, b) = Base.isgreater(b, a) +_isgreater_fm(a, b) = isless(b, a) findmin(A::AbstractSparseMatrixCSC{Tv}, region::Union{Integer,Tuple{Integer},NTuple{2,Integer}}) where {Tv} = _findr(_isless_fm, A, region) diff --git a/test/reductions.jl b/test/reductions.jl index 24f310da..c006395b 100644 --- a/test/reductions.jl +++ b/test/reductions.jl @@ -221,6 +221,13 @@ end @test isequal(m(Z, dims=region), m(Array(Z), dims=region)) end end + # `missing`, which dense ranks above `NaN` + for D in (Union{Missing,Float64}[1.0 missing; 0.0 2.0], Union{Missing,Float64}[NaN missing; 0.0 2.0]), + m in (findmax, findmin) + Z = sparse(D) + @test isequal(m(Z), m(D)) + @test isequal(m(Z, dims=1), m(D, dims=1)) && isequal(m(Z, dims=2), m(D, dims=2)) + end end for m in [findmax, findmin] @test_throws ArgumentError m(S, (4, 3)) From eecc87a5e459c010f4fdef95a40f0991d6d447c3 Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Tue, 13 Oct 2026 03:18:06 +0000 Subject: [PATCH 2/2] Trim the `missing` test to one case per helper Co-Authored-By: Claude Opus 5.5 --- test/reductions.jl | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test/reductions.jl b/test/reductions.jl index c006395b..dd7ae101 100644 --- a/test/reductions.jl +++ b/test/reductions.jl @@ -222,12 +222,9 @@ end end end # `missing`, which dense ranks above `NaN` - for D in (Union{Missing,Float64}[1.0 missing; 0.0 2.0], Union{Missing,Float64}[NaN missing; 0.0 2.0]), - m in (findmax, findmin) - Z = sparse(D) - @test isequal(m(Z), m(D)) - @test isequal(m(Z, dims=1), m(D, dims=1)) && isequal(m(Z, dims=2), m(D, dims=2)) - end + D = Union{Missing,Float64}[NaN missing; 0.0 2.0] + @test isequal(findmin(sparse(D)), findmin(D)) + @test isequal(findmax(sparse(D), dims=1), findmax(D, dims=1)) end for m in [findmax, findmin] @test_throws ArgumentError m(S, (4, 3))