Skip to content

Commit 814a3fb

Browse files
authored
avoid allocation for length-1 linear combinations (#34)
* avoid allocation for length-1 linear combinations * add allocation tests * major revision and addition of tests
1 parent b425454 commit 814a3fb

File tree

2 files changed

+325
-193
lines changed

2 files changed

+325
-193
lines changed

src/linearcombination.jl

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ struct LinearCombination{T, As<:Tuple{Vararg{LinearMap}}, Ts<:Tuple} <: LinearMa
33
coeffs::Ts
44
function LinearCombination{T, As, Ts}(maps::As, coeffs::Ts) where {T, As, Ts}
55
N = length(maps)
6-
N == length(coeffs) || error("Number of coefficients doesn't match number of terms")
6+
N == length(coeffs) || error("number of coefficients doesn't match number of linear maps")
77
sz = size(maps[1])
88
for n = 1:N
99
size(maps[n]) == sz || throw(DimensionMismatch("LinearCombination"))
@@ -97,32 +97,41 @@ function A_mul_B!(y::AbstractVector, A::LinearCombination, x::AbstractVector)
9797
# no size checking, will be done by individual maps
9898
A_mul_B!(y, A.maps[1], x)
9999
A.coeffs[1] == 1 || lmul!(A.coeffs[1], y)
100-
z = similar(y)
101-
for n=2:length(A.maps)
102-
A_mul_B!(z, A.maps[n], x)
103-
axpy!(A.coeffs[n], z, y)
100+
l = length(A.maps)
101+
if l>1
102+
z = similar(y)
103+
for n=2:l
104+
A_mul_B!(z, A.maps[n], x)
105+
axpy!(A.coeffs[n], z, y)
106+
end
104107
end
105108
return y
106109
end
107110
function At_mul_B!(y::AbstractVector, A::LinearCombination, x::AbstractVector)
108111
# no size checking, will be done by individual maps
109112
At_mul_B!(y, A.maps[1], x)
110113
A.coeffs[1] == 1 || lmul!(A.coeffs[1], y)
111-
z = similar(y)
112-
for n = 2:length(A.maps)
113-
At_mul_B!(z, A.maps[n], x)
114-
axpy!(A.coeffs[n], z, y)
114+
l = length(A.maps)
115+
if l>1
116+
z = similar(y)
117+
for n = 2:l
118+
At_mul_B!(z, A.maps[n], x)
119+
axpy!(A.coeffs[n], z, y)
120+
end
115121
end
116122
return y
117123
end
118124
function Ac_mul_B!(y::AbstractVector, A::LinearCombination, x::AbstractVector)
119125
# no size checking, will be done by individual maps
120126
Ac_mul_B!(y, A.maps[1], x)
121127
A.coeffs[1] == 1 || lmul!(conj(A.coeffs[1]), y)
122-
z = similar(y)
123-
for n=2:length(A.maps)
124-
Ac_mul_B!(z, A.maps[n], x)
125-
axpy!(conj(A.coeffs[n]), z, y)
128+
l = length(A.maps)
129+
if l>1
130+
z = similar(y)
131+
for n=2:l
132+
Ac_mul_B!(z, A.maps[n], x)
133+
axpy!(conj(A.coeffs[n]), z, y)
134+
end
126135
end
127136
return y
128137
end

0 commit comments

Comments
 (0)