Skip to content

Commit

Permalink
Fix multiplying Symmetric and Hermitian matrices (#261)
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Feb 14, 2024
1 parent 3a1ca9b commit 2a7b7ca
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 12 deletions.
25 changes: 13 additions & 12 deletions src/dispatch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -474,26 +474,27 @@ Base.:*(A::AbstractArray, α::AbstractMutable) = A .* α

# Needed for Julia v1.0, otherwise, `broadcast(*, α, A)` gives a `Array` and
# not a `Symmetric`.

_mult_upper(α, A) = parent* LinearAlgebra.UpperTriangular(parent(A)))
_mult_lower(α, A) = parent* LinearAlgebra.LowerTriangular(parent(A)))

function Base.:*::Number, A::LinearAlgebra.Symmetric{<:AbstractMutable})
return LinearAlgebra.Symmetric(
α * parent(A),
LinearAlgebra.sym_uplo(A.uplo),
)
c = LinearAlgebra.sym_uplo(A.uplo)
B = c == :U ? _mult_upper(α, A) : _mult_lower(α, A)
return LinearAlgebra.Symmetric(B, c)
end

function Base.:*::Number, A::LinearAlgebra.Hermitian{<:AbstractMutable})
return LinearAlgebra.Hermitian(
α * parent(A),
LinearAlgebra.sym_uplo(A.uplo),
)
c = LinearAlgebra.sym_uplo(A.uplo)
B = c == :U ? _mult_upper(α, A) : _mult_lower(α, A)
return LinearAlgebra.Hermitian(B, c)
end

# Fix ambiguity identified by Aqua.jl.
function Base.:*::Real, A::LinearAlgebra.Hermitian{<:AbstractMutable})
return LinearAlgebra.Hermitian(
α * parent(A),
LinearAlgebra.sym_uplo(A.uplo),
)
c = LinearAlgebra.sym_uplo(A.uplo)
B = c == :U ? _mult_upper(α, A) : _mult_lower(α, A)
return LinearAlgebra.Hermitian(B, c)
end

# These three have specific methods that just redirect to `Matrix{T}` which
Expand Down
12 changes: 12 additions & 0 deletions test/dispatch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,15 @@ end
@test MA.operate(LinearAlgebra.dot, z, z) == LinearAlgebra.dot(z, z)
end
end

@testset "*(::Real, ::Union{Hermitian,Symmetric})" begin
A = DummyBigInt[1 2; 2 3]
B = DummyBigInt[2 4; 4 6]
@test MA.isequal_canonical(2 * A, B)
C = LinearAlgebra.Symmetric(B)
@test MA.isequal_canonical(2 * LinearAlgebra.Symmetric(A, :U), C)
@test MA.isequal_canonical(2 * LinearAlgebra.Symmetric(A, :L), C)
D = LinearAlgebra.Hermitian(B)
@test all(MA.isequal_canonical.(2 * LinearAlgebra.Hermitian(A, :L), D))
@test all(MA.isequal_canonical.(2 * LinearAlgebra.Hermitian(A, :U), D))
end

0 comments on commit 2a7b7ca

Please sign in to comment.