Skip to content

Commit 19e766a

Browse files
committed
carry out (c)transpose in trivial cases for Ax_mul_Bx methods for Hermitian and Symmetric
- Symmetric and Hermitian{<:Real} are invariant to transpose so it is a no-op - Hermitian and Symmetric{<:Real} are invariant to ctranspose so it is a no-op
1 parent 724bbaf commit 19e766a

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

base/linalg/diagonal.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ A_mul_B!(out::AbstractMatrix, A::Diagonal, in::AbstractMatrix) = out .= A.diag .
234234
Ac_mul_B!(out::AbstractMatrix, A::Diagonal, in::AbstractMatrix) = out .= ctranspose.(A.diag) .* in
235235
At_mul_B!(out::AbstractMatrix, A::Diagonal, in::AbstractMatrix) = out .= transpose.(A.diag) .* in
236236

237+
# ambiguities with Symmetric/Hermitian
238+
A_mul_Bt(A::Diagonal, B::RealHermSymComplexSym) = A*B
239+
At_mul_B(A::RealHermSymComplexSym, D::Diagonal) = A*B
240+
A_mul_Bc(A::Diagonal, B::RealHermSymComplexHerm) = A*B
241+
Ac_mul_B(A::RealHermSymComplexHerm, D::Diagonal) = A*B
237242

238243
(/)(Da::Diagonal, Db::Diagonal) = Diagonal(Da.diag ./ Db.diag)
239244
function A_ldiv_B!(D::Diagonal{T}, v::AbstractVector{T}) where {T}

base/linalg/symmetric.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ end
107107

108108
const HermOrSym{T,S} = Union{Hermitian{T,S}, Symmetric{T,S}}
109109
const RealHermSymComplexHerm{T<:Real,S} = Union{Hermitian{T,S}, Symmetric{T,S}, Hermitian{Complex{T},S}}
110+
const RealHermSymComplexSym{T<:Real,S} = Union{Hermitian{T,S}, Symmetric{T,S}, Symmetric{Complex{T},S}}
110111

111112
size(A::HermOrSym, d) = size(A.data, d)
112113
size(A::HermOrSym) = size(A.data)
@@ -301,6 +302,25 @@ A_mul_B!(C::StridedMatrix{T}, A::StridedMatrix{T}, B::Hermitian{T,<:StridedMatri
301302

302303
*(A::HermOrSym, B::HermOrSym) = A*full(B)
303304

305+
# Fallbacks to avoid generic_matvecmul!/generic_matmatmul!
306+
## Symmetric and Hermitian{<:Real} are invariant to transpose; peel of the t
307+
At_mul_B(A::RealHermSymComplexSym, B::AbstractVector) = A*B
308+
At_mul_B(A::RealHermSymComplexSym, B::AbstractMatrix) = A*B
309+
A_mul_Bt(A::AbstractMatrix, B::RealHermSymComplexSym) = A*B
310+
## Hermitian and Symmetric{<:Real} are invariant to ctranspose; peel of the c
311+
Ac_mul_B(A::RealHermSymComplexHerm, B::AbstractVector) = A*B
312+
Ac_mul_B(A::RealHermSymComplexHerm, B::AbstractMatrix) = A*B
313+
A_mul_Bc(A::AbstractMatrix, B::RealHermSymComplexHerm) = A*B
314+
315+
# ambiguities with RowVector
316+
A_mul_Bt(A::RowVector, B::RealHermSymComplexSym) = A*B
317+
A_mul_Bc(A::RowVector, B::RealHermSymComplexHerm) = A*B
318+
# ambiguities with UpperTriangular
319+
At_mul_B(A::RealHermSymComplexSym, B::AbstractTriangular) = A*B
320+
A_mul_Bt(A::AbstractTriangular, B::RealHermSymComplexSym) = A*B
321+
Ac_mul_B(A::RealHermSymComplexHerm, B::AbstractTriangular) = A*B
322+
A_mul_Bc(A::AbstractTriangular, B::RealHermSymComplexHerm) = A*B
323+
304324
for T in (:Symmetric, :Hermitian), op in (:+, :-, :*, :/)
305325
# Deal with an ambiguous case
306326
@eval ($op)(A::$T, x::Bool) = ($T)(($op)(A.data, x), Symbol(A.uplo))

0 commit comments

Comments
 (0)