Skip to content

Commit 2f95f42

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 3ef68f4 commit 2f95f42

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

base/linalg/diagonal.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,12 @@ 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+
# RealHermSymComplex[Sym]/[Herm] only include Number; invariant to [c]transpose
239+
A_mul_Bt(A::Diagonal, B::RealHermSymComplexSym) = A*B
240+
At_mul_B(A::RealHermSymComplexSym, B::Diagonal) = A*B
241+
A_mul_Bc(A::Diagonal, B::RealHermSymComplexHerm) = A*B
242+
Ac_mul_B(A::RealHermSymComplexHerm, B::Diagonal) = A*B
237243

238244
(/)(Da::Diagonal, Db::Diagonal) = Diagonal(Da.diag ./ Db.diag)
239245
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
@@ -109,6 +109,7 @@ end
109109

110110
const HermOrSym{T,S} = Union{Hermitian{T,S}, Symmetric{T,S}}
111111
const RealHermSymComplexHerm{T<:Real,S} = Union{Hermitian{T,S}, Symmetric{T,S}, Hermitian{Complex{T},S}}
112+
const RealHermSymComplexSym{T<:Real,S} = Union{Hermitian{T,S}, Symmetric{T,S}, Symmetric{Complex{T},S}}
112113

113114
size(A::HermOrSym, d) = size(A.data, d)
114115
size(A::HermOrSym) = size(A.data)
@@ -303,6 +304,25 @@ A_mul_B!(C::StridedMatrix{T}, A::StridedMatrix{T}, B::Hermitian{T,<:StridedMatri
303304

304305
*(A::HermOrSym, B::HermOrSym) = A*full(B)
305306

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

0 commit comments

Comments
 (0)