Skip to content

Commit ad2d33e

Browse files
committed
include left matrix multiply and some fixes
1 parent 22b6fc9 commit ad2d33e

File tree

2 files changed

+56
-36
lines changed

2 files changed

+56
-36
lines changed

src/left.jl

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,35 @@
1111
import LinearAlgebra: AdjointAbsVec, TransposeAbsVec
1212

1313
# x = y'*A ⇐⇒ x' = (A'*y)
14-
Base.:(*)(y::AdjointAbsVec, A::LinearMap) = adjoint(*(A', y'))
14+
Base.:(*)(y::AdjointAbsVec, A::LinearMap) = adjoint(A' * y')
1515
Base.:(*)(y::TransposeAbsVec, A::LinearMap) = transpose(transpose(A) * transpose(y))
1616

17-
# mul!(x, y', A)
18-
Base.@propagate_inbounds function LinearAlgebra.mul!(x::AbstractMatrix, y::AdjointAbsVec, A::LinearMap)
19-
@boundscheck check_dim_mul(x, y, A)
20-
@inbounds mul!(adjoint(x), A', y')
21-
return adjoint(x)
22-
end
23-
24-
Base.@propagate_inbounds function LinearAlgebra.mul!(x::AbstractMatrix, y::AdjointAbsVec,
25-
A::LinearMap, α::Number, β::Number)
26-
@boundscheck check_dim_mul(x, y, A)
27-
@inbounds mul!(adjoint(x), A', y', α, β)
28-
return adjoint(x)
29-
end
17+
# multiplication with vector/matrix
18+
for Atype in (AdjointAbsVec, Adjoint{<:Any,<:AbstractMatrix})
19+
@eval Base.@propagate_inbounds function LinearAlgebra.mul!(x::AbstractMatrix, y::$Atype, A::LinearMap)
20+
@boundscheck check_dim_mul(x, y, A)
21+
@inbounds mul!(adjoint(x), A', y')
22+
return x
23+
end
3024

31-
Base.@propagate_inbounds function LinearAlgebra.mul!(x::AbstractMatrix, y::TransposeAbsVec, A::LinearMap)
32-
@boundscheck check_dim_mul(x, y, A)
33-
@inbounds mul!(transpose(x), transpose(A), transpose(y))
34-
return transpose(x)
25+
@eval Base.@propagate_inbounds function LinearAlgebra.mul!(x::AbstractMatrix, y::$Atype, A::LinearMap,
26+
α::Number, β::Number)
27+
@boundscheck check_dim_mul(x, y, A)
28+
@inbounds mul!(adjoint(x), A', y', conj(α), conj(β))
29+
return x
30+
end
3531
end
32+
for Atype in (TransposeAbsVec, Transpose{<:Any,<:AbstractMatrix})
33+
@eval Base.@propagate_inbounds function LinearAlgebra.mul!(x::AbstractMatrix, y::$Atype, A::LinearMap)
34+
@boundscheck check_dim_mul(x, y, A)
35+
@inbounds mul!(transpose(x), transpose(A), transpose(y))
36+
return x
37+
end
3638

37-
Base.@propagate_inbounds function LinearAlgebra.mul!(x::AbstractMatrix, y::TransposeAbsVec,
38-
A::LinearMap, α::Number, β::Number)
39-
@boundscheck check_dim_mul(x, y, A)
40-
@inbounds mul!(transpose(x), transpose(A), transpose(y), α, β)
41-
return transpose(x)
39+
@eval Base.@propagate_inbounds function LinearAlgebra.mul!(x::AbstractMatrix, y::$Atype, A::LinearMap,
40+
α::Number, β::Number)
41+
@boundscheck check_dim_mul(x, y, A)
42+
@inbounds mul!(transpose(x), transpose(A), transpose(y), α, β)
43+
return x
44+
end
4245
end

test/left.jl

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,51 @@ function left_tester(L::LinearMap{T}) where {T}
1717
@test transpose(y) * A transpose(y) * L
1818

1919
# mul!
20+
α = rand(T); β = rand(T)
2021
b1 = y' * A
2122
b2 = similar(b1)
22-
mul!(b2, y', L) # 3-arg
23-
@test b1 b2
24-
mul!(b2, y', L, true, false) # 5-arg
25-
@test b1 b2
23+
bt = copy(b1')'
24+
# bm = Matrix(bt) # TODO: this requires a generalization of the output to AbstractVecOrMat
25+
@test mul!(b2, y', L) mul!(bt, y', L)# ≈ mul!(bm, y', L)# 3-arg
26+
@test mul!(b2, y', L) === b2
27+
@test b1 b2 bt
28+
b3 = copy(b2)
29+
mul!(b3, y', L, α, β)
30+
@test b3 b2*β + b1*α
2631

2732
b1 = transpose(y) * A
2833
b2 = similar(b1)
29-
mul!(b2, transpose(y), L) # 3-arg
30-
@test b1 b2
31-
mul!(b2, transpose(y), L, true, false) # 5-arg
32-
@test b1 b2
34+
bt = transpose(copy(transpose(b1)))
35+
@test mul!(b2, transpose(y), L) mul!(bt, transpose(y), L)
36+
@test b1 b2 bt
37+
b3 = copy(b2)
38+
mul!(b3, transpose(y), L, α, β)
39+
@test b3 b2*β + b1*α
40+
41+
Y = rand(T, M, 3)
42+
X = similar(Y, 3, N)
43+
Xt = copy(X')'
44+
@test Y'L isa LinearMap
45+
@test Matrix(Y'L) Y'A
46+
@test mul!(X, Y', L) mul!(Xt, Y', L) Y'A
47+
@test mul!(Xt, Y', L) === Xt
48+
@test mul!(copy(X), Y', L, α, β) X*β + Y'A*α
49+
@test mul!(X, Y', L) === X
50+
@test mul!(X, Y', L, α, β) === X
3351

3452
true
3553
end
3654

37-
38-
@testset "left mul vec" begin
55+
@testset "left multiplication" begin
3956
T = ComplexF32
40-
M,N = 5,5
57+
N = 5
4158
L = LinearMap{T}(cumsum, reverse cumsum reverse, N)
4259

4360
@test left_tester(L) # FunctionMap
4461
@test left_tester(L'*L) # CompositeMap
4562
@test left_tester(2L) # ScaledMap
46-
@test left_tester(kron(L,L')) # KroneckerMap
47-
@test left_tester(2L+3L') # LinearCombination
63+
@test left_tester(kron(L, L')) # KroneckerMap
64+
@test left_tester(2L + 3L') # LinearCombination
4865
@test left_tester([L L]) # BlockMap
4966

5067
W = LinearMap(randn(T,5,4))

0 commit comments

Comments
 (0)