Skip to content

Commit 2ef3842

Browse files
jishnubKristofferC
authored andcommitted
Inplace transpose for unit Triangular may skip diagonal (#53101)
Since the diagonal elements of a `UnitUpperTriangular` are given by `onelement`, these should be unchanged under `transpose/adjoint`, and we don't need to access these elements in the parent array when performing in-place operations. Fixes ```julia julia> using LinearAlgebra julia> M = Matrix{BigFloat}(undef, 2, 2); julia> M[1,2] = 3; julia> U = UnitUpperTriangular(M) 2×2 UnitUpperTriangular{BigFloat, Matrix{BigFloat}}: 1.0 3.0 ⋅ 1.0 julia> transpose!(U) ERROR: UndefRefError: access to undefined reference Stacktrace: [1] getindex @ ./essentials.jl:882 [inlined] [2] getindex @ ./array.jl:915 [inlined] [3] copytri! @ ~/packages/julias/julia-latest/share/julia/stdlib/v1.11/LinearAlgebra/src/matmul.jl:414 [inlined] [4] transpose!(A::UnitUpperTriangular{BigFloat, Matrix{BigFloat}}) @ LinearAlgebra ~/packages/julias/julia-latest/share/julia/stdlib/v1.11/LinearAlgebra/src/triangular.jl:470 [5] top-level scope @ REPL[5]:1 ``` After this PR: ```julia julia> transpose!(U) 2×2 UnitLowerTriangular{BigFloat, Matrix{BigFloat}}: 1.0 ⋅ 3.0 1.0 ``` (cherry picked from commit cc74d24)
1 parent a1ad1ba commit 2ef3842

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

stdlib/LinearAlgebra/src/triangular.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -406,13 +406,13 @@ transpose(A::UnitLowerTriangular) = UnitUpperTriangular(transpose(A.data))
406406
transpose(A::UnitUpperTriangular) = UnitLowerTriangular(transpose(A.data))
407407

408408
transpose!(A::LowerTriangular) = UpperTriangular(copytri!(A.data, 'L', false, true))
409-
transpose!(A::UnitLowerTriangular) = UnitUpperTriangular(copytri!(A.data, 'L', false, true))
409+
transpose!(A::UnitLowerTriangular) = UnitUpperTriangular(copytri!(A.data, 'L', false, false))
410410
transpose!(A::UpperTriangular) = LowerTriangular(copytri!(A.data, 'U', false, true))
411-
transpose!(A::UnitUpperTriangular) = UnitLowerTriangular(copytri!(A.data, 'U', false, true))
411+
transpose!(A::UnitUpperTriangular) = UnitLowerTriangular(copytri!(A.data, 'U', false, false))
412412
adjoint!(A::LowerTriangular) = UpperTriangular(copytri!(A.data, 'L' , true, true))
413-
adjoint!(A::UnitLowerTriangular) = UnitUpperTriangular(copytri!(A.data, 'L' , true, true))
413+
adjoint!(A::UnitLowerTriangular) = UnitUpperTriangular(copytri!(A.data, 'L' , true, false))
414414
adjoint!(A::UpperTriangular) = LowerTriangular(copytri!(A.data, 'U' , true, true))
415-
adjoint!(A::UnitUpperTriangular) = UnitLowerTriangular(copytri!(A.data, 'U' , true, true))
415+
adjoint!(A::UnitUpperTriangular) = UnitLowerTriangular(copytri!(A.data, 'U' , true, false))
416416

417417
diag(A::LowerTriangular) = diag(A.data)
418418
diag(A::UnitLowerTriangular) = fill(oneunit(eltype(A)), size(A,1))

stdlib/LinearAlgebra/test/triangular.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ debug && println("Test basic type functionality")
1818
@test LowerTriangular(randn(3, 3)) |> t -> [size(t, i) for i = 1:3] == [size(Matrix(t), i) for i = 1:3]
1919

2020
# The following test block tries to call all methods in base/linalg/triangular.jl in order for a combination of input element types. Keep the ordering when adding code.
21-
for elty1 in (Float32, Float64, BigFloat, ComplexF32, ComplexF64, Complex{BigFloat}, Int)
21+
@testset for elty1 in (Float32, Float64, BigFloat, ComplexF32, ComplexF64, Complex{BigFloat}, Int)
2222
# Begin loop for first Triangular matrix
2323
for (t1, uplo1) in ((UpperTriangular, :U),
2424
(UnitUpperTriangular, :U),
@@ -871,4 +871,12 @@ end
871871
end
872872
end
873873

874+
@testset "transpose triangular diagonal" begin
875+
M = Matrix{BigFloat}(undef, 2, 2);
876+
M[1,2] = 3;
877+
U = UnitUpperTriangular(M)
878+
Ut = transpose(U)
879+
@test transpose!(U) == Ut
880+
end
881+
874882
end # module TestTriangular

0 commit comments

Comments
 (0)