Skip to content

Commit ce8e7c5

Browse files
committed
Relaxed type requirements on maps storage for LinearCombination and BlockMap
1 parent 8e3b35b commit ce8e7c5

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

src/blockmap.jl

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
struct BlockMap{T,As<:Tuple{Vararg{LinearMap}},Rs<:Tuple{Vararg{Int}},Rranges<:Tuple{Vararg{UnitRange{Int}}},Cranges<:Tuple{Vararg{UnitRange{Int}}}} <: LinearMap{T}
1+
struct BlockMap{T,As,Rs<:Tuple{Vararg{Int}},Rranges<:Tuple{Vararg{UnitRange{Int}}},Cranges<:Tuple{Vararg{UnitRange{Int}}}} <: LinearMap{T}
22
maps::As
33
rows::Rs
44
rowranges::Rranges
@@ -39,6 +39,9 @@ function BlockMap{T}(M::Int, N::Int, (m,n), maps, is, js) where T
3939
sum(m) == M && sum(n) == N ||
4040
throw(DimensionMismatch("Cumulative block dimensions $(sum(m))×$(sum(n)) do not agree with overall size $(M)×$(N)"))
4141

42+
length(maps) == length(is) == length(js) ||
43+
throw(ArgumentError("Must provide block coordinates for $(length(maps)) blocks"))
44+
4245
allunique(zip(is, js)) ||
4346
throw(ArgumentError("Not all block indices unique"))
4447

@@ -50,9 +53,6 @@ function BlockMap{T}(M::Int, N::Int, (m,n), maps, is, js) where T
5053
throw(DimensionMismatch("Block of size $(size(A)) does not match size at $((i,j)): $((m[i],n[j]))"))
5154
end
5255

53-
# It would be nice to do just maps = map(LinearMap, maps)
54-
maps = (map(A -> A isa LinearMap ? A : LinearMap(A), maps)...,)
55-
5656
rows = zeros(Int, length(m))
5757
colranges = ()
5858
colstarts = 1 .+ vcat(0,cumsum(n))
@@ -71,6 +71,8 @@ function BlockMap{T}(M::Int, N::Int, (m,n), maps, is, js) where T
7171
rowranges = (rowranges...,iprev:i-1)
7272
end
7373

74+
maps = map(convert_to_lmaps_, maps)
75+
7476
BlockMap{T}(maps, rows, rowranges, colranges, M, N)
7577
end
7678

src/linearcombination.jl

+47-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
struct LinearCombination{T, As<:Tuple{Vararg{LinearMap}}} <: LinearMap{T}
1+
struct LinearCombination{T, As} <: LinearMap{T}
22
maps::As
33
function LinearCombination{T, As}(maps::As) where {T, As}
44
N = length(maps)
@@ -13,6 +13,33 @@ end
1313

1414
LinearCombination{T}(maps::As) where {T, As} = LinearCombination{T, As}(maps)
1515

16+
function Base.show(io::IO, A::LinearCombination)
17+
write(io, "LinearMaps.LinearCombination(")
18+
n = length(A.maps)
19+
if get(io, :limit, true) && n > 10
20+
s = 1:5
21+
e = n-5:n
22+
if e[1]-s[end] > 1
23+
write(io, "(")
24+
for i in s
25+
show(io, A.maps[i])
26+
write(io, ", ")
27+
end
28+
write(io, "")
29+
for i in e
30+
write(io, ", ")
31+
show(io, A.maps[i])
32+
end
33+
write(io, ")")
34+
else
35+
show(io, A.maps)
36+
end
37+
else
38+
show(io, A.maps)
39+
end
40+
write(io, ")")
41+
end
42+
1643
MulStyle(A::LinearCombination) = MulStyle(A.maps...)
1744

1845
# basic methods
@@ -81,6 +108,9 @@ for Atype in (AbstractVector, AbstractMatrix)
81108
end
82109
end
83110

111+
# For tuple-like storage of the maps (default), we recurse on the tail
112+
# of the tuple.
113+
84114
@inline _mul!(::FiveArg, y, A::LinearCombination, x, α::Number) =
85115
__mul!(y, Base.tail(A.maps), x, α, nothing)
86116
@inline function _mul!(::ThreeArg, y, A::LinearCombination, x, α::Number)
@@ -93,6 +123,22 @@ end
93123
@inline __mul!(y, A::Tuple{LinearMap}, x, α, z) = __mul!(y, first(A), x, α, z)
94124
@inline __mul!(y, A::LinearMap, x, α, z) = muladd!(MulStyle(A), y, A, x, α, z)
95125

126+
# For vector-like storage of the maps, we simply loop over the maps.
127+
128+
@inline function _mul!(::FiveArg, y, A::LinearCombination{<:Any,<:AbstractVector}, x, α::Number)
129+
for i = 2:length(A.maps)
130+
mul!(y, A.maps[i], x, α, true)
131+
end
132+
y
133+
end
134+
@inline function _mul!(mulstyle::ThreeArg, y, A::LinearCombination{<:Any,<:AbstractVector}, x, α::Number)
135+
z = similar(y)
136+
for i = 2:length(A.maps)
137+
muladd!(mulstyle, y, A.maps[i], x, α, z)
138+
end
139+
y
140+
end
141+
96142
@inline muladd!(::FiveArg, y, A, x, α, _) = mul!(y, A, x, α, true)
97143
@inline function muladd!(::ThreeArg, y, A, x, α, z)
98144
mul!(z, A, x)

0 commit comments

Comments
 (0)