Skip to content

Commit 3cf63de

Browse files
author
Clément Fauchereau
committed
fast extrema computation on sparse arrays
1 parent bf886b5 commit 3cf63de

File tree

5 files changed

+59
-1
lines changed

5 files changed

+59
-1
lines changed

stdlib/SparseArrays/src/SparseArrays.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import LinearAlgebra: mul!, ldiv!, rdiv!, cholesky, adjoint!, diag, eigen, dot,
1818
import Base: acos, acosd, acot, acotd, acsch, asech, asin, asind, asinh,
1919
atan, atand, atanh, broadcast!, conj!, cos, cosc, cosd, cosh, cospi, cot,
2020
cotd, coth, count, csc, cscd, csch,
21-
exp10, exp2, findprev, findnext, floor, hash, argmin, inv,
21+
exp10, exp2, extrema, findprev, findnext, floor, hash, argmin, inv,
2222
log10, log2, sec, secd, sech, show,
2323
sin, sinc, sind, sinh, sinpi, dropdims, sum, summary, tan,
2424
tand, tanh, trunc, abs, abs2,

stdlib/SparseArrays/src/sparsematrix.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3742,3 +3742,20 @@ end
37423742

37433743
circshift!(O::AbstractSparseMatrixCSC, X::AbstractSparseMatrixCSC, (r,)::Base.DimsInteger{1}) = circshift!(O, X, (r,0))
37443744
circshift!(O::AbstractSparseMatrixCSC, X::AbstractSparseMatrixCSC, r::Real) = circshift!(O, X, (Integer(r),0))
3745+
3746+
function extrema(f, A::AbstractSparseMatrixCSC)
3747+
if iszero(length(A))
3748+
throw(ArgumentError("Sparse matrix must have at least one element."))
3749+
end
3750+
N = nnz(A)
3751+
iszero(N) && return f(zero(eltype(A))), f(zero(eltype(A)))
3752+
vmin, vmax = extrema(f, nonzeros(A))
3753+
if N != length(A)
3754+
f0 = f(zero(eltype(A)))
3755+
vmin = min(f0, vmin)
3756+
vmax = max(f0, vmax)
3757+
end
3758+
vmin, vmax
3759+
end
3760+
3761+
extrema(A::AbstractSparseMatrixCSC) = extrema(identity, A)

stdlib/SparseArrays/src/sparsevector.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,3 +2122,20 @@ end
21222122

21232123

21242124
circshift!(O::SparseVector, X::SparseVector, r::Real,) = circshift!(O, X, (Integer(r),))
2125+
2126+
function extrema(f, A::AbstractSparseVector)
2127+
if length(A) == 0
2128+
throw(ArgumentError("Sparse vector must have at least one element."))
2129+
end
2130+
N = nnz(A)
2131+
iszero(N) && return f(zero(eltype(A))), f(zero(eltype(A)))
2132+
vmin, vmax = extrema(f, nonzeros(A))
2133+
if N != length(A)
2134+
f0 = f(zero(eltype(A)))
2135+
vmin = min(f0, vmin)
2136+
vmax = max(f0, vmax)
2137+
end
2138+
vmin, vmax
2139+
end
2140+
2141+
extrema(A::AbstractSparseVector) = extrema(identity, A)

stdlib/SparseArrays/test/sparse.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3082,4 +3082,16 @@ end
30823082
@test nonzeros(d) == V[1:4]
30833083
end
30843084

3085+
@testset "extrema" begin
3086+
n = 10
3087+
A = sprand(n, n, 0.2)
3088+
B = Array(A)
3089+
f(x) = x^3
3090+
@test extrema(A) == extrema(B)
3091+
@test extrema(f, A) == extrema(f, B)
3092+
@test extrema(spzeros(n, n)) == (0.0, 0.0)
3093+
@test_throws ArgumentError extrema(spzeros(0, 0))
3094+
@test extrema(sparse(ones(n, n))) == (1.0, 1.0)
3095+
end
3096+
30853097
end # module

stdlib/SparseArrays/test/sparsevector.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,4 +1457,16 @@ end
14571457
end
14581458
end
14591459

1460+
@testset "extrema" begin
1461+
n = 10
1462+
A = sprand(n, 0.2)
1463+
B = Array(A)
1464+
f(x) = x^3
1465+
@test extrema(A) == extrema(B)
1466+
@test extrema(f, A) == extrema(f, B)
1467+
@test extrema(spzeros(n)) == (0.0, 0.0)
1468+
@test_throws ArgumentError extrema(spzeros(0))
1469+
@test extrema(sparse(ones(n))) == (1.0, 1.0)
1470+
end
1471+
14601472
end # module

0 commit comments

Comments
 (0)