Skip to content

Commit 5e53d12

Browse files
authored
Avoid accessing unset indices in symmetric copyto! (#1244)
Currently, copying `Symmetric`/`Hermitian` matrices with mismatched `uplo`s might access unset indices. In this PR, we fix this by ensuring that we always use `copytrito!`, and only access the triangular half of the parent that `uplo` corresponds to. On master, ```julia julia> using LinearAlgebra julia> M = Matrix{Complex{BigFloat}}(undef, 2, 2) 2×2 Matrix{Complex{BigFloat}}: #undef #undef #undef #undef julia> M[1,1] = M[2,2] = 3 3 julia> uplo1, uplo2 = :U, :L (:U, :L) julia> isupper = uplo1 == :U true julia> M[1+!isupper, 1+isupper] = 4+3im 4 + 3im julia> M 2×2 Matrix{Complex{BigFloat}}: 3.0+0.0im 4.0+3.0im #undef 3.0+0.0im julia> H1 = Hermitian(M, uplo1) 2×2 Hermitian{Complex{BigFloat}, Matrix{Complex{BigFloat}}}: 3.0+0.0im 4.0+3.0im 4.0-3.0im 3.0+0.0im julia> H2 = Hermitian(M', uplo2) 2×2 Hermitian{Complex{BigFloat}, Adjoint{Complex{BigFloat}, Matrix{Complex{BigFloat}}}}: 3.0+0.0im 4.0+3.0im 4.0-3.0im 3.0+0.0im julia> copyto!(H1, H2) ERROR: UndefRefError: access to undefined reference [...] ``` After this PR, ```julia julia> copyto!(H1, H2) 2×2 Hermitian{Complex{BigFloat}, Matrix{Complex{BigFloat}}}: 3.0+0.0im 4.0+3.0im 4.0-3.0im 3.0+0.0im ```
1 parent e64a3df commit 5e53d12

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

src/symmetric.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ function copyto!(dest::Symmetric, src::Symmetric)
352352
elseif src.uplo == dest.uplo
353353
copytrito!(dest.data, src.data, src.uplo)
354354
else
355-
transpose!(dest.data, Base.unalias(dest.data, src.data))
355+
copytrito!(dest.data, transpose(Base.unalias(dest.data, src.data)), dest.uplo)
356356
end
357357
return dest
358358
end
@@ -363,7 +363,7 @@ function copyto!(dest::Hermitian, src::Hermitian)
363363
elseif src.uplo == dest.uplo
364364
copytrito!(dest.data, src.data, src.uplo)
365365
else
366-
adjoint!(dest.data, Base.unalias(dest.data, src.data))
366+
copytrito!(dest.data, adjoint(Base.unalias(dest.data, src.data)), dest.uplo)
367367
end
368368
return dest
369369
end

test/symmetric.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,4 +1163,19 @@ end
11631163
end
11641164
end
11651165

1166+
@testset "copyto! with mismatched uplo" begin
1167+
for (S,tf) in ((Symmetric, transpose), (Hermitian, adjoint))
1168+
for (uplo1,uplo2) in [(:U,:L), (:L, :U)]
1169+
M = Matrix{Complex{BigFloat}}(undef, 2, 2)
1170+
M[1,1] = M[2,2] = 3
1171+
isupper = uplo1 == :U
1172+
M[1+!isupper, 1+isupper] = 4+3im
1173+
H1 = S(M, uplo1)
1174+
H2 = 2 * S(tf(M), uplo2)
1175+
copyto!(H2, H1)
1176+
@test H2 == H1
1177+
end
1178+
end
1179+
end
1180+
11661181
end # module TestSymmetric

0 commit comments

Comments
 (0)