From bb138fa8d89b1636254098b81f53b51b2cd58128 Mon Sep 17 00:00:00 2001 From: John Lapeyre Date: Wed, 25 Oct 2023 03:08:58 -0400 Subject: [PATCH] Improve efficiency of minimum/maximum(::Diagonal) (#30236) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` julia> DM = Diagonal(rand(100)); julia> @btime minimum($DM); # before 27.987 μs (0 allocations: 0 bytes) julia> @btime minimum($DM); # after 246.091 ns (0 allocations: 0 bytes) ``` --- stdlib/LinearAlgebra/src/diagonal.jl | 12 ++++++++++++ stdlib/LinearAlgebra/test/diagonal.jl | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index c58f2f8d3b665..ebc0d1cd0e59b 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -161,6 +161,18 @@ end r end +function Base.minimum(D::Diagonal{T}) where T <: Number + mindiag = minimum(D.diag) + size(D, 1) > 1 && return (min(zero(T), mindiag)) + return mindiag +end + +function Base.maximum(D::Diagonal{T}) where T <: Number + maxdiag = Base.maximum(D.diag) + size(D, 1) > 1 && return (max(zero(T), maxdiag)) + return maxdiag +end + @inline function getindex(D::Diagonal, i::Int, j::Int) @boundscheck checkbounds(D, i, j) if i == j diff --git a/stdlib/LinearAlgebra/test/diagonal.jl b/stdlib/LinearAlgebra/test/diagonal.jl index 1b1aa37af2d31..caefc7889a8d6 100644 --- a/stdlib/LinearAlgebra/test/diagonal.jl +++ b/stdlib/LinearAlgebra/test/diagonal.jl @@ -108,6 +108,12 @@ Random.seed!(1) for func in (det, tr) @test func(D) ≈ func(DM) atol=n^2*eps(relty)*(1+(elty<:Complex)) end + + if eltype(D) <: Real + @test minimum(D) ≈ minimum(DM) + @test maximum(D) ≈ maximum(DM) + end + if relty <: BlasFloat for func in (exp, cis, sinh, cosh, tanh, sech, csch, coth) @test func(D) ≈ func(DM) atol=n^3*eps(relty)