diff --git a/src/diagonal.jl b/src/diagonal.jl index 90572d7b..b5642800 100644 --- a/src/diagonal.jl +++ b/src/diagonal.jl @@ -360,6 +360,13 @@ function rmul!(A::AbstractMatrix, D::Diagonal) end return A end +# A' = A' * D => A = D' * A +# This uses the fact that D' is a Diagonal +function rmul!(A::AdjOrTransAbsMat, D::Diagonal) + f = wrapperop(A) + lmul!(f(D), f(A)) + A +end # T .= T * D function rmul!(T::Tridiagonal, D::Diagonal) matmul_size_check(size(T), size(D)) @@ -395,6 +402,13 @@ function lmul!(D::Diagonal, T::Tridiagonal) end return T end +# A' = D * A' => A = A * D' +# This uses the fact that D' is a Diagonal +function lmul!(D::Diagonal, A::AdjOrTransAbsMat) + f = wrapperop(A) + rmul!(f(A), f(D)) + A +end @inline function __muldiag_nonzeroalpha!(out, D::Diagonal, B, alpha::Number, beta::Number) @inbounds for j in axes(B, 2) diff --git a/test/diagonal.jl b/test/diagonal.jl index 3dd334aa..4675e6f2 100644 --- a/test/diagonal.jl +++ b/test/diagonal.jl @@ -1257,6 +1257,22 @@ end end end +@testset "rmul!/lmul! for adj/trans" begin + for T in (Float64, ComplexF64) + A = rand(T,5,4); B = similar(A) + for f in (adjoint, transpose) + D = Diagonal(rand(T, size(A,1))) + B .= A + rmul!(f(B), D) + @test f(B) == f(A) * D + D = Diagonal(rand(T, size(A,2))) + B .= A + lmul!(D, f(B)) + @test f(B) == D * f(A) + end + end +end + struct SMatrix1{T} <: AbstractArray{T,2} elt::T end