diff --git a/src/generic.jl b/src/generic.jl index 21bcd4cb..afbd7b9f 100644 --- a/src/generic.jl +++ b/src/generic.jl @@ -464,7 +464,8 @@ julia> triu(a,-3) 1.0 1.0 1.0 1.0 ``` """ -function triu(M::AbstractMatrix, k::Integer = 0) +triu(M::AbstractMatrix, k::Integer = 0) = _triu(M, Val(haszero(eltype(M))), k) +function _triu(M::AbstractMatrix, ::Val{true}, k::Integer) d = similar(M) A = triu!(d,k) if iszero(k) @@ -477,6 +478,14 @@ function triu(M::AbstractMatrix, k::Integer = 0) end return A end +function _triu(M::AbstractMatrix, ::Val{false}, k::Integer) + d = similar(M) + # since the zero would need to be evaluated from the elements, + # we copy the array to avoid undefined references in triu! + copy!(d, M) + A = triu!(d,k) + return A +end """ tril(M, k::Integer = 0) @@ -507,7 +516,8 @@ julia> tril(a,-3) 1.0 0.0 0.0 0.0 ``` """ -function tril(M::AbstractMatrix,k::Integer=0) +tril(M::AbstractMatrix,k::Integer=0) = _tril(M, Val(haszero(eltype(M))), k) +function _tril(M::AbstractMatrix, ::Val{true}, k::Integer) d = similar(M) A = tril!(d,k) if iszero(k) @@ -520,6 +530,14 @@ function tril(M::AbstractMatrix,k::Integer=0) end return A end +function _tril(M::AbstractMatrix, ::Val{false}, k::Integer) + d = similar(M) + # since the zero would need to be evaluated from the elements, + # we copy the array to avoid undefined references in tril! + copy!(d, M) + A = tril!(d,k) + return A +end """ triu!(M) diff --git a/test/dense.jl b/test/dense.jl index ee659748..99e0b429 100644 --- a/test/dense.jl +++ b/test/dense.jl @@ -1408,4 +1408,14 @@ end @test 2^A == 2^Matrix(A) end +@testset "triu/tril for block matrices" begin + O = ones(2,2) + Z = zero(O) + M = fill(O, 3, 3) + res = fill(Z, size(M)) + res[1,2] = res[1,3] = res[2,3] = O + @test triu(GenericArray(M),1) == res + @test tril(GenericArray(M),-1) == res' +end + end # module TestDense