@@ -66,23 +66,35 @@ LinearAlgebra.adjoint(A::LinearCombination) = LinearCombination{eltype(A)}(map
66
66
# map types that have an allocation-free 5-arg mul! implementation
67
67
const FreeMap = Union{MatrixMap,UniformScalingMap}
68
68
69
+ # with the mulstyle feature, this version distinction becomes obsolete
70
+ # the function for older versions would automatically call the ThreeArg method
71
+ # of _lincombmul!
69
72
if VERSION < v " 1.3.0-alpha.115"
70
73
71
74
Base. @propagate_inbounds function LinearAlgebra. mul! (y:: AbstractVector , A:: LinearCombination , x:: AbstractVector ,
72
75
α:: Number = true , β:: Number = false )
73
76
@boundscheck check_dim_mul (y, A, x)
74
- mul! (y, A. maps[1 ], x, α, β)
75
- @inbounds begin
76
- l = length (A. maps)
77
- if l> 1
78
- z = similar (y)
79
- for n in 2 : l
80
- mul! (z, A. maps[n], x, α, false )
81
- y .+ = z
77
+ if iszero (α)
78
+ iszero (β) && (fill! (y, zero (eltype (y))); return y)
79
+ isone (β) && return y
80
+ # β != 0, 1
81
+ rmul! (y, β)
82
+ return y
83
+ else
84
+ # TODO : reconsider the below code in light of the mulstyle trait
85
+ mul! (y, A. maps[1 ], x, α, β)
86
+ @inbounds begin
87
+ l = length (A. maps)
88
+ if l> 1
89
+ z = similar (y)
90
+ for n in 2 : l
91
+ mul! (z, A. maps[n], x, α, false )
92
+ y .+ = z
93
+ end
82
94
end
83
95
end
96
+ return y
84
97
end
85
- return y
86
98
end
87
99
88
100
else # 5-arg mul! is available for matrices
@@ -98,30 +110,58 @@ end # VERSION
98
110
# ###########
99
111
# multiplication helper functions
100
112
# ###########
101
-
113
+ # to be replaced by _lincombmul!(y, A::LinearCombination{<:Any,FiveArg}, x, α::Number, β::Number)
102
114
@inline function _lincombmul! (y, A:: LinearCombination{<:Any,<:Tuple{Vararg{FreeMap}}} , x,
103
115
α:: Number , β:: Number )
104
- mul! (y, A. maps[1 ], x, α, β)
105
- @inbounds for n in 2 : length (A. maps)
106
- mul! (y, A. maps[n], x, α, true )
116
+ if iszero (α)
117
+ iszero (β) && (fill! (y, zero (eltype (y))); return y)
118
+ isone (β) && return y
119
+ # β != 0, 1
120
+ rmul! (y, β)
121
+ return y
122
+ else
123
+ mul! (y, A. maps[1 ], x, α, β)
124
+ @inbounds for n in 2 : length (A. maps)
125
+ mul! (y, A. maps[n], x, α, true )
126
+ end
127
+ return y
107
128
end
108
- return y
109
129
end
110
130
131
+ # to be replaced by _lincombmul!(y, A::LinearCombination{<:Any,ThreeArg}, x, α::Number, β::Number)
111
132
@inline function _lincombmul! (y, A:: LinearCombination , x, α:: Number , β:: Number )
112
- mul! (y, first (A. maps), x, α, β)
113
- l = length (A. maps)
114
- if l> 1
133
+ if iszero (α)
134
+ iszero (β) && (fill! (y, zero (eltype (y))); return y)
135
+ isone (β) && return y
136
+ # β != 0, 1
137
+ rmul! (y, β)
138
+ return y
139
+ else
115
140
z = similar (y)
116
- for n in 2 : l
117
- @inbounds An = A. maps[n]
118
- if An isa FreeMap
119
- mul! (y, An, x, α, true )
141
+ A1 = A. maps[1 ]
142
+ if A1 isa FreeMap # to be replaced by mulstyle(A1) == FiveArg
143
+ mul! (y, A1, x, α, β)
144
+ else
145
+ if iszero (β)
146
+ mul! (y, A1, x)
147
+ ! isone (α) && rmul! (y, α)
120
148
else
121
- mul! (z, An, x, α, false )
122
- y .+ = z
149
+ ! isone (β) && rmul! (y, β)
150
+ mul! (z, A1, x)
151
+ y .+ = z .* α
152
+ end
153
+
154
+ l = length (A. maps)
155
+ if l> 1
156
+ @inbounds for An in Base. tail (A. maps)
157
+ if An isa FreeMap # to be replaced by mulstyle(An) == FiveArg
158
+ mul! (y, An, x, α, true )
159
+ else
160
+ mul! (z, An, x)
161
+ y .+ = z .* α
162
+ end
123
163
end
124
164
end
165
+ return y
125
166
end
126
- return y
127
167
end
0 commit comments