Skip to content

Commit 702f4bb

Browse files
committed
Working version (!) with VecOut = AbstractVecOrMat
1 parent 0775fa3 commit 702f4bb

File tree

3 files changed

+23
-33
lines changed

3 files changed

+23
-33
lines changed

src/LinearMaps.jl

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ export LinearMap
44
export , kronsum,
55

66
using LinearAlgebra
7-
import LinearAlgebra: AdjointAbsVec, TransposeAbsVec
87
using SparseArrays
98

109
if VERSION < v"1.2-"
@@ -20,8 +19,7 @@ const MapOrMatrix{T} = Union{LinearMap{T},AbstractMatrix{T}}
2019
const RealOrComplex = Union{Real,Complex}
2120

2221
# valid types for left vector multiplication:
23-
const VecIn = Union{AdjointAbsVec, TransposeAbsVec}
24-
const VecOut = Union{AbstractVector, AdjointAbsVec, TransposeAbsVec}
22+
const VecOut = AbstractVecOrMat # todo - temporary
2523

2624
Base.eltype(::LinearMap{T}) where {T} = T
2725

@@ -52,24 +50,20 @@ Base.ndims(::LinearMap) = 2
5250
Base.size(A::LinearMap, n) = (n==1 || n==2 ? size(A)[n] : error("LinearMap objects have only 2 dimensions"))
5351
Base.length(A::LinearMap) = size(A)[1] * size(A)[2]
5452

55-
# check dimension consistency for y = A*x and Y = A*X
56-
function check_dim_mul(y::VecOut, A::LinearMap, x::AbstractVector)
53+
# check dimension consistency for right multiply: y = A*x and Y = A*X
54+
function check_dim_mul(Y::AbstractVecOrMat, A::LinearMap, X::AbstractVecOrMat)
5755
# @info "checked vector dimensions" # uncomment for testing
5856
m, n = size(A)
59-
(m == length(y) && n == length(x)) || throw(DimensionMismatch("mul!"))
60-
return nothing
61-
end
62-
function check_dim_mul(Y::AbstractMatrix, A::LinearMap, X::AbstractMatrix)
63-
# @info "checked matrix dimensions" # uncomment for testing
64-
m, n = size(A)
65-
(m == size(Y, 1) && n == size(X, 1) && size(Y, 2) == size(X, 2)) || throw(DimensionMismatch("mul!"))
57+
(m == size(Y, 1) && n == size(X, 1) && size(Y, 2) == size(X, 2)) ||
58+
throw(DimensionMismatch("mul! $(size(X)) $(size(Y)) $(size(A))"))
6659
return nothing
6760
end
6861

69-
# check dimension consistency for left multiplication x = y'*A
70-
function check_dim_mul(x::V, y::V, A::LinearMap) where {V <: VecIn}
62+
# check dimension consistency for left multiply: X = Y*A (e.g., Y=y')
63+
function check_dim_mul(X::AbstractVecOrMat, Y::AbstractVecOrMat, A::LinearMap)
7164
m, n = size(A)
72-
((1,m) == size(y) && (1,n) == size(x)) || throw(DimensionMismatch("left mul!"))
65+
(n == size(X, 2) && m == size(Y, 2) && size(Y, 1) == size(X, 1)) ||
66+
throw(DimensionMismatch("left mul!"))
7367
return nothing
7468
end
7569

src/left.jl

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,29 @@
1010

1111
import LinearAlgebra: AdjointAbsVec, TransposeAbsVec
1212

13+
# x = y'*A ⇐⇒ x' = (A'*y)
1314
Base.:(*)(y::AdjointAbsVec, A::LinearMap) = adjoint(*(A', y'))
1415
Base.:(*)(y::TransposeAbsVec, A::LinearMap) = transpose(transpose(A) * transpose(y))
1516

1617
# mul!(x, y', A)
1718
LinearAlgebra.mul!(x::AdjointAbsVec, y::AdjointAbsVec, A::LinearMap) =
1819
mul!(x, y, A, true, false)
1920

20-
# not sure if we need bounds checks and propagate inbounds stuff here
21+
# todo: not sure if we need bounds checks and propagate inbounds stuff here
2122

2223
# mul!(x, y', A, α, β)
23-
function LinearAlgebra.mul!(x::AdjointAbsVec, y::AdjointAbsVec, A::LinearMap,
24-
α::Number, β::Number)
24+
# the key here is that "adjoint" and "transpose" are lazy "views"
25+
function LinearAlgebra.mul!(x::AdjointAbsVec, y::AdjointAbsVec,
26+
A::LinearMap, α::Number, β::Number)
2527
check_dim_mul(x, y, A)
26-
mul!(x, A', y', α, β)
27-
return conj!(x)
28+
mul!(adjoint(x), A', y', α, β)
29+
return adjoint(x)
2830
end
2931

3032
# mul!(x, transpose(y), A, α, β)
31-
function LinearAlgebra.mul!(x::TransposeAbsVec, y::TransposeAbsVec, A::LinearMap,
32-
α::Number, β::Number)
33+
function LinearAlgebra.mul!(x::TransposeAbsVec, y::TransposeAbsVec,
34+
A::LinearMap, α::Number, β::Number)
3335
check_dim_mul(x, y, A)
34-
return mul!(x, transpose(A), transpose(y), α, β)
36+
mul!(transpose(x), transpose(A), transpose(y), α, β)
37+
return transpose(x)
3538
end

test/left.jl

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,11 @@ end
4545
@test left_tester(L'*L) # CompositeMap
4646
@test left_tester(2L) # ScaledMap
4747
@test left_tester(kron(L,L')) # KroneckerMap
48+
@test left_tester(2L+3L') # LinearCombination
49+
@test left_tester([L L]) # BlockMap
4850

49-
#=
50-
todo: fails with DimensionMismatch
51-
W = LinearMap(randn(T,5,4)) #
51+
W = LinearMap(randn(T,5,4))
5252
@test left_tester(W) # WrappedMap
53-
=#
54-
55-
#=
56-
todo: fails with stack overflow
57-
@test left_tester([L L]) # BlockMap
58-
@test left_tester(2L+3L') # LinearCombination
59-
=#
6053
end
6154

6255
end # version

0 commit comments

Comments
 (0)