From d866014b7455471250e738ea7c9f3d8e6ac14aca Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sat, 5 Apr 2025 23:13:42 +0530 Subject: [PATCH 1/5] istril/istriu for opposite triangularity --- src/triangular.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/triangular.jl b/src/triangular.jl index 199ff119..5cdc8282 100644 --- a/src/triangular.jl +++ b/src/triangular.jl @@ -376,6 +376,11 @@ istril(A::Transpose, k::Integer=0) = istriu(A.parent, -k) istriu(A::Adjoint, k::Integer=0) = istril(A.parent, -k) istriu(A::Transpose, k::Integer=0) = istril(A.parent, -k) +istril(U::UpperTriangular, k::Integer=0) = istril(parent(U), max(0, k)) +istril(U::UnitUpperTriangular, k::Integer=0) = k < 0 ? false : istril(parent(U), k) +istriu(U::LowerTriangular, k::Integer=0) = istriu(parent(U), min(0, k)) +istriu(U::UnitLowerTriangular, k::Integer=0) = k > 0 ? false : istriu(parent(U), k) + function tril!(A::UpperTriangular{T}, k::Integer=0) where {T} if k < 0 fill!(A.data, zero(T)) From 7fdfb3bc0ee7f95ac349c709ac80ce40d948ad8b Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sun, 6 Apr 2025 00:09:35 +0530 Subject: [PATCH 2/5] Add tests --- test/triangular.jl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/triangular.jl b/test/triangular.jl index 739c3ff3..d19b8094 100644 --- a/test/triangular.jl +++ b/test/triangular.jl @@ -196,6 +196,17 @@ end @test isdiag(LowerTriangular(diagm(0 => [1,2,3,4]))) @test !isdiag(UpperTriangular(rand(4, 4))) @test !isdiag(LowerTriangular(rand(4, 4))) + + for A in [rand(4,4), zeros(4,4)] + U = UpperTriangular(A) + UA = Array(U) + L = LowerTriangular(A) + LA = Array(L) + for k in -size(A,1):size(A,2) + @test istril(U, k) == istril(UA, k) + @test istriu(L, k) == istriu(LA, k) + end + end end # Test throwing in fallbacks for non BlasFloat/BlasComplex in A_rdiv_Bx! From 3e1aaace8730a37703acef1835de7662735d4647 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sun, 6 Apr 2025 00:15:59 +0530 Subject: [PATCH 3/5] Add banded tests --- test/triangular.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/triangular.jl b/test/triangular.jl index d19b8094..691e0412 100644 --- a/test/triangular.jl +++ b/test/triangular.jl @@ -197,7 +197,7 @@ end @test !isdiag(UpperTriangular(rand(4, 4))) @test !isdiag(LowerTriangular(rand(4, 4))) - for A in [rand(4,4), zeros(4,4)] + for A in [rand(4,4), zeros(4,4), diagm(1=>1:3), diagm(-2=>2:3)] U = UpperTriangular(A) UA = Array(U) L = LowerTriangular(A) From aeeed7df1936519c92c71059abd0358838d684ee Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sun, 6 Apr 2025 00:27:59 +0530 Subject: [PATCH 4/5] Add unit triangular tests --- test/triangular.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/triangular.jl b/test/triangular.jl index 691e0412..2f00183c 100644 --- a/test/triangular.jl +++ b/test/triangular.jl @@ -202,9 +202,25 @@ end UA = Array(U) L = LowerTriangular(A) LA = Array(L) + UU = UnitUpperTriangular(A) + UUA = Array(UU) + UL = UnitLowerTriangular(A) + ULA = Array(UL) for k in -size(A,1):size(A,2) @test istril(U, k) == istril(UA, k) @test istriu(L, k) == istriu(LA, k) + @test istril(UU, k) == istril(UUA, k) + @test istriu(UL, k) == istriu(ULA, k) + end + end + for (T, f) in ((UnitUpperTriangular, istril), (UnitLowerTriangular, istriu)) + A = Matrix{BigFloat}(undef, 2, 2) + isupper = T === UnitUpperTriangular + A[1+!isupper, 1+isupper] = 3 + UU = T(A) + UUA = Array(UU) + for k in -size(A,1):size(A,2) + @test f(UU, k) == f(UUA, k) end end end From 9675c3886937771ef644f35f6a31deab46ce8b9f Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sun, 6 Apr 2025 12:05:15 +0530 Subject: [PATCH 5/5] Fix minimum band for `UpperTriangular`/`Lowertriangular` --- src/triangular.jl | 4 ++-- test/triangular.jl | 45 ++++++++++++++++----------------------------- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/triangular.jl b/src/triangular.jl index 5cdc8282..a7037e7e 100644 --- a/src/triangular.jl +++ b/src/triangular.jl @@ -376,9 +376,9 @@ istril(A::Transpose, k::Integer=0) = istriu(A.parent, -k) istriu(A::Adjoint, k::Integer=0) = istril(A.parent, -k) istriu(A::Transpose, k::Integer=0) = istril(A.parent, -k) -istril(U::UpperTriangular, k::Integer=0) = istril(parent(U), max(0, k)) +istril(U::UpperTriangular, k::Integer=0) = istril(parent(U), max(-1, k)) istril(U::UnitUpperTriangular, k::Integer=0) = k < 0 ? false : istril(parent(U), k) -istriu(U::LowerTriangular, k::Integer=0) = istriu(parent(U), min(0, k)) +istriu(U::LowerTriangular, k::Integer=0) = istriu(parent(U), min(1, k)) istriu(U::UnitLowerTriangular, k::Integer=0) = k > 0 ? false : istriu(parent(U), k) function tril!(A::UpperTriangular{T}, k::Integer=0) where {T} diff --git a/test/triangular.jl b/test/triangular.jl index 2f00183c..02c58df7 100644 --- a/test/triangular.jl +++ b/test/triangular.jl @@ -196,33 +196,6 @@ end @test isdiag(LowerTriangular(diagm(0 => [1,2,3,4]))) @test !isdiag(UpperTriangular(rand(4, 4))) @test !isdiag(LowerTriangular(rand(4, 4))) - - for A in [rand(4,4), zeros(4,4), diagm(1=>1:3), diagm(-2=>2:3)] - U = UpperTriangular(A) - UA = Array(U) - L = LowerTriangular(A) - LA = Array(L) - UU = UnitUpperTriangular(A) - UUA = Array(UU) - UL = UnitLowerTriangular(A) - ULA = Array(UL) - for k in -size(A,1):size(A,2) - @test istril(U, k) == istril(UA, k) - @test istriu(L, k) == istriu(LA, k) - @test istril(UU, k) == istril(UUA, k) - @test istriu(UL, k) == istriu(ULA, k) - end - end - for (T, f) in ((UnitUpperTriangular, istril), (UnitLowerTriangular, istriu)) - A = Matrix{BigFloat}(undef, 2, 2) - isupper = T === UnitUpperTriangular - A[1+!isupper, 1+isupper] = 3 - UU = T(A) - UUA = Array(UU) - for k in -size(A,1):size(A,2) - @test f(UU, k) == f(UUA, k) - end - end end # Test throwing in fallbacks for non BlasFloat/BlasComplex in A_rdiv_Bx! @@ -761,15 +734,16 @@ end end @testset "istriu/istril forwards to parent" begin - @testset "$(nameof(typeof(M)))" for M in [Tridiagonal(rand(n-1), rand(n), rand(n-1)), + @testset "$(nameof(typeof(M)))" for M in Any[Tridiagonal(rand(n-1), rand(n), rand(n-1)), Tridiagonal(zeros(n-1), zeros(n), zeros(n-1)), Diagonal(randn(n)), Diagonal(zeros(n)), + rand(n,n), zeros(n,n), diagm(1=>1:n-1), diagm(-2=>1:n-2), ] @testset for TriT in (UpperTriangular, UnitUpperTriangular, LowerTriangular, UnitLowerTriangular) U = TriT(M) A = Array(U) - for k in -n:n + @testset for k in -n:n @test istriu(U, k) == istriu(A, k) @test istril(U, k) == istril(A, k) end @@ -787,6 +761,19 @@ end end end + @testset "partly initialized in unit triangular" begin + for (T, f) in ((UnitUpperTriangular, istril), (UnitLowerTriangular, istriu)) + A = Matrix{BigFloat}(undef, 2, 2) + isupper = T === UnitUpperTriangular + A[1+!isupper, 1+isupper] = 3 + UU = T(A) + UUA = Array(UU) + for k in -size(A,1):size(A,2) + @test f(UU, k) == f(UUA, k) + end + end + end + @testset "Union eltype" begin M = Matrix{Union{Int,Missing}}(missing,2,2) U = triu(M)