Skip to content

Commit c33045c

Browse files
authored
Copy matrices in triu/tril if no zero exists for the eltype (#1320)
This fixes a regression in the `triu`/`tril` implementation on v1.12 and nightly. After this, the following works again: ```julia julia> M = fill(ones(2,2), 3, 3) 3×3 Matrix{Matrix{Float64}}: [1.0 1.0; 1.0 1.0] [1.0 1.0; 1.0 1.0] [1.0 1.0; 1.0 1.0] [1.0 1.0; 1.0 1.0] [1.0 1.0; 1.0 1.0] [1.0 1.0; 1.0 1.0] [1.0 1.0; 1.0 1.0] [1.0 1.0; 1.0 1.0] [1.0 1.0; 1.0 1.0] julia> using Test: GenericArray julia> triu(GenericArray(M),1) 3×3 GenericArray{Matrix{Float64}, 2}: [0.0 0.0; 0.0 0.0] [1.0 1.0; 1.0 1.0] [1.0 1.0; 1.0 1.0] [0.0 0.0; 0.0 0.0] [0.0 0.0; 0.0 0.0] [1.0 1.0; 1.0 1.0] [0.0 0.0; 0.0 0.0] [0.0 0.0; 0.0 0.0] [0.0 0.0; 0.0 0.0] ```
1 parent 3396f0b commit c33045c

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

src/generic.jl

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,8 @@ julia> triu(a,-3)
464464
1.0 1.0 1.0 1.0
465465
```
466466
"""
467-
function triu(M::AbstractMatrix, k::Integer = 0)
467+
triu(M::AbstractMatrix, k::Integer = 0) = _triu(M, Val(haszero(eltype(M))), k)
468+
function _triu(M::AbstractMatrix, ::Val{true}, k::Integer)
468469
d = similar(M)
469470
A = triu!(d,k)
470471
if iszero(k)
@@ -477,6 +478,14 @@ function triu(M::AbstractMatrix, k::Integer = 0)
477478
end
478479
return A
479480
end
481+
function _triu(M::AbstractMatrix, ::Val{false}, k::Integer)
482+
d = similar(M)
483+
# since the zero would need to be evaluated from the elements,
484+
# we copy the array to avoid undefined references in triu!
485+
copy!(d, M)
486+
A = triu!(d,k)
487+
return A
488+
end
480489

481490
"""
482491
tril(M, k::Integer = 0)
@@ -507,7 +516,8 @@ julia> tril(a,-3)
507516
1.0 0.0 0.0 0.0
508517
```
509518
"""
510-
function tril(M::AbstractMatrix,k::Integer=0)
519+
tril(M::AbstractMatrix,k::Integer=0) = _tril(M, Val(haszero(eltype(M))), k)
520+
function _tril(M::AbstractMatrix, ::Val{true}, k::Integer)
511521
d = similar(M)
512522
A = tril!(d,k)
513523
if iszero(k)
@@ -520,6 +530,14 @@ function tril(M::AbstractMatrix,k::Integer=0)
520530
end
521531
return A
522532
end
533+
function _tril(M::AbstractMatrix, ::Val{false}, k::Integer)
534+
d = similar(M)
535+
# since the zero would need to be evaluated from the elements,
536+
# we copy the array to avoid undefined references in tril!
537+
copy!(d, M)
538+
A = tril!(d,k)
539+
return A
540+
end
523541

524542
"""
525543
triu!(M)

test/dense.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,4 +1408,14 @@ end
14081408
@test 2^A == 2^Matrix(A)
14091409
end
14101410

1411+
@testset "triu/tril for block matrices" begin
1412+
O = ones(2,2)
1413+
Z = zero(O)
1414+
M = fill(O, 3, 3)
1415+
res = fill(Z, size(M))
1416+
res[1,2] = res[1,3] = res[2,3] = O
1417+
@test triu(GenericArray(M),1) == res
1418+
@test tril(GenericArray(M),-1) == res'
1419+
end
1420+
14111421
end # module TestDense

0 commit comments

Comments
 (0)