|
| 1 | +# left.jl |
| 2 | +# "special cases" related left vector multiplication like x = y'*A |
| 3 | +# The subtlety is that y' is a AdjointAbsVec or a TransposeAbsVec |
| 4 | +# which is a subtype of AbstractMatrix but it is really "vector like" |
| 5 | +# so we want handle it like a vector (Issue#99) |
| 6 | +# So this is an exception to the left multiplication rule by a AbstractMatrix |
| 7 | +# that usually makes a WrappedMap. |
| 8 | +# The "transpose" versions may be of dubious use, but the adjoint versions |
| 9 | +# are useful for ensuring that (y'A)*x ≈ y'*(A*x) are both scalars. |
| 10 | + |
| 11 | +import LinearAlgebra: AdjointAbsVec, TransposeAbsVec |
| 12 | + |
| 13 | +# x = y'*A ⇐⇒ x' = (A'*y) |
| 14 | +Base.:(*)(y::AdjointAbsVec, A::LinearMap) = adjoint(A' * y') |
| 15 | +Base.:(*)(y::TransposeAbsVec, A::LinearMap) = transpose(transpose(A) * transpose(y)) |
| 16 | + |
| 17 | +# multiplication with vector/matrix |
| 18 | +for Atype in (AdjointAbsVec, Adjoint{<:Any,<:AbstractMatrix}) |
| 19 | + @eval begin |
| 20 | + Base.@propagate_inbounds function LinearAlgebra.mul!(x::AbstractMatrix, y::$Atype, A::LinearMap) |
| 21 | + @boundscheck check_dim_mul(x, y, A) |
| 22 | + @inbounds mul!(x', A', y') |
| 23 | + return x |
| 24 | + end |
| 25 | + |
| 26 | + Base.@propagate_inbounds function LinearAlgebra.mul!(x::AbstractMatrix, y::$Atype, A::LinearMap, |
| 27 | + α::Number, β::Number) |
| 28 | + @boundscheck check_dim_mul(x, y, A) |
| 29 | + @inbounds mul!(x', A', y', conj(α), conj(β)) |
| 30 | + return x |
| 31 | + end |
| 32 | + end |
| 33 | +end |
| 34 | +for Atype in (TransposeAbsVec, Transpose{<:Any,<:AbstractMatrix}) |
| 35 | + @eval begin |
| 36 | + Base.@propagate_inbounds function LinearAlgebra.mul!(x::AbstractMatrix, y::$Atype, A::LinearMap) |
| 37 | + @boundscheck check_dim_mul(x, y, A) |
| 38 | + @inbounds mul!(transpose(x), transpose(A), transpose(y)) |
| 39 | + return x |
| 40 | + end |
| 41 | + |
| 42 | + Base.@propagate_inbounds function LinearAlgebra.mul!(x::AbstractMatrix, y::$Atype, A::LinearMap, |
| 43 | + α::Number, β::Number) |
| 44 | + @boundscheck check_dim_mul(x, y, A) |
| 45 | + @inbounds mul!(transpose(x), transpose(A), transpose(y), α, β) |
| 46 | + return x |
| 47 | + end |
| 48 | + end |
| 49 | +end |
0 commit comments