Skip to content

Commit f6d16c2

Browse files
committed
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 69fa500 commit f6d16c2

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
@@ -446,7 +446,8 @@ julia> triu(a,-3)
446446
1.0 1.0 1.0 1.0
447447
```
448448
"""
449-
function triu(M::AbstractMatrix, k::Integer = 0)
449+
triu(M::AbstractMatrix, k::Integer = 0) = _triu(M, Val(haszero(eltype(M))), k)
450+
function _triu(M::AbstractMatrix, ::Val{true}, k::Integer)
450451
d = similar(M)
451452
A = triu!(d,k)
452453
if iszero(k)
@@ -459,6 +460,14 @@ function triu(M::AbstractMatrix, k::Integer = 0)
459460
end
460461
return A
461462
end
463+
function _triu(M::AbstractMatrix, ::Val{false}, k::Integer)
464+
d = similar(M)
465+
# since the zero would need to be evaluated from the elements,
466+
# we copy the array to avoid undefined references in triu!
467+
copy!(d, M)
468+
A = triu!(d,k)
469+
return A
470+
end
462471

463472
"""
464473
tril(M, k::Integer = 0)
@@ -489,7 +498,8 @@ julia> tril(a,-3)
489498
1.0 0.0 0.0 0.0
490499
```
491500
"""
492-
function tril(M::AbstractMatrix,k::Integer=0)
501+
tril(M::AbstractMatrix,k::Integer=0) = _tril(M, Val(haszero(eltype(M))), k)
502+
function _tril(M::AbstractMatrix, ::Val{true}, k::Integer)
493503
d = similar(M)
494504
A = tril!(d,k)
495505
if iszero(k)
@@ -502,6 +512,14 @@ function tril(M::AbstractMatrix,k::Integer=0)
502512
end
503513
return A
504514
end
515+
function _tril(M::AbstractMatrix, ::Val{false}, k::Integer)
516+
d = similar(M)
517+
# since the zero would need to be evaluated from the elements,
518+
# we copy the array to avoid undefined references in tril!
519+
copy!(d, M)
520+
A = tril!(d,k)
521+
return A
522+
end
505523

506524
"""
507525
triu!(M)

test/dense.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,4 +1374,14 @@ end
13741374
@test !any(LinearAlgebra.getstructure(A))
13751375
end
13761376

1377+
@testset "triu/tril for block matrices" begin
1378+
O = ones(2,2)
1379+
Z = zero(O)
1380+
M = fill(O, 3, 3)
1381+
res = fill(Z, size(M))
1382+
res[1,2] = res[1,3] = res[2,3] = O
1383+
@test triu(GenericArray(M),1) == res
1384+
@test tril(GenericArray(M),-1) == res'
1385+
end
1386+
13771387
end # module TestDense

0 commit comments

Comments
 (0)