@@ -6,10 +6,17 @@ vec(a::AbstractFill) = fillsimilar(a, length(a))
66# cannot do this for vectors since that would destroy scalar dot product
77
88
9- transpose (a:: Union{AbstractOnesMatrix, AbstractZerosMatrix} ) = fillsimilar (a, reverse (axes (a)))
10- adjoint (a:: Union{AbstractOnesMatrix, AbstractZerosMatrix} ) = fillsimilar (a, reverse (axes (a)))
11- transpose (a:: FillMatrix{T} ) where T = Fill {T} (transpose (a. value), reverse (a. axes))
12- adjoint (a:: FillMatrix{T} ) where T = Fill {T} (adjoint (a. value), reverse (a. axes))
9+ for OP in (:transpose , :adjoint )
10+ @eval begin
11+ function $OP (a:: AbstractZerosMatrix )
12+ v = getindex_value (a)
13+ T = typeof ($ OP (v))
14+ Zeros {T} (reverse (axes (a)))
15+ end
16+ $ OP (a:: AbstractOnesMatrix ) = fillsimilar (a, reverse (axes (a)))
17+ $ OP (a:: FillMatrix ) = Fill ($ OP (a. value), reverse (a. axes))
18+ end
19+ end
1320
1421permutedims (a:: AbstractFillMatrix ) = fillsimilar (a, reverse (a. axes))
1522
@@ -91,9 +98,18 @@ mult_ones(a, b) = mult_ones(a, b, mult_axes(a, b))
9198* (a:: AbstractFillMatrix , b:: AbstractZerosMatrix ) = mult_zeros (a, b)
9299* (a:: AbstractFillMatrix , b:: AbstractZerosVector ) = mult_zeros (a, b)
93100
94- * (a:: AbstractZerosMatrix , b:: AbstractMatrix ) = mult_zeros (a, b)
95- * (a:: AbstractMatrix , b:: AbstractZerosVector ) = mult_zeros (a, b)
96- * (a:: AbstractMatrix , b:: AbstractZerosMatrix ) = mult_zeros (a, b)
101+ for MT in (:AbstractMatrix , :AbstractTriangular )
102+ @eval * (a:: AbstractZerosMatrix , b:: $MT ) = mult_zeros (a, b)
103+ @eval * (a:: $MT , b:: AbstractZerosMatrix ) = mult_zeros (a, b)
104+ end
105+ # Odd way to deal with the type-parameters to avoid ambiguities
106+ for MT in (:(AbstractMatrix{T}), :(Transpose{<: Any , <: AbstractMatrix{T} }), :(Adjoint{<: Any , <: AbstractMatrix{T} }),
107+ :(AbstractTriangular{T}))
108+ @eval * (a:: $MT , b:: AbstractZerosVector ) where {T} = mult_zeros (a, b)
109+ end
110+ for MT in (:(Transpose{<: Any , <: AbstractVector }), :(Adjoint{<: Any , <: AbstractVector }))
111+ @eval * (a:: $MT , b:: AbstractZerosMatrix ) = mult_zeros (a, b)
112+ end
97113* (a:: AbstractZerosMatrix , b:: AbstractVector ) = mult_zeros (a, b)
98114
99115function lmul_diag (a:: Diagonal , b)
@@ -139,60 +155,56 @@ end
139155function mul! (y:: AbstractVector , A:: AbstractFillMatrix , b:: AbstractFillVector , alpha:: Number , beta:: Number )
140156 check_matmul_sizes (y, A, b)
141157
142- αAb = alpha * getindex_value (A) * getindex_value (b) * length (b)
158+ Abα = Ref ( getindex_value (A) * getindex_value (b) * alpha * length (b) )
143159
144160 if iszero (beta)
145- y .= αAb
161+ y .= Abα
146162 else
147- y .= αAb .+ beta .* y
163+ y .= Abα .+ y .* beta
148164 end
149165 y
150166end
151167
152168function mul! (y:: StridedVector , A:: StridedMatrix , b:: AbstractFillVector , alpha:: Number , beta:: Number )
153169 check_matmul_sizes (y, A, b)
154170
155- αb = alpha * getindex_value (b)
171+ bα = Ref ( getindex_value (b) * alpha )
156172
157173 if iszero (beta)
158- y .= zero (eltype (y))
159- for col in eachcol (A)
160- y .+ = αb .* col
161- end
174+ y .= Ref (zero (eltype (y)))
162175 else
163- lmul! (beta, y )
164- for col in eachcol (A)
165- y .+ = αb .* col
166- end
176+ rmul! (y, beta )
177+ end
178+ for Acol in eachcol (A)
179+ @. y += Acol * bα
167180 end
168181 y
169182end
170183
171184function mul! (y:: StridedVector , A:: AbstractFillMatrix , b:: StridedVector , alpha:: Number , beta:: Number )
172185 check_matmul_sizes (y, A, b)
173186
174- αA = alpha * getindex_value (A )
187+ Abα = Ref ( getindex_value (A) * sum (b) * alpha )
175188
176189 if iszero (beta)
177- y .= αA .* sum (b)
190+ y .= Abα
178191 else
179- y .= αA .* sum (b) .+ beta .* y
192+ y .= Abα .+ y .* beta
180193 end
181194 y
182195end
183196
184- function _mul_adjtrans! (y:: AbstractVector , A:: AbstractMatrix , b:: AbstractVector , alpha, beta, f)
185- α = alpha * getindex_value (b)
186-
197+ function _mul_adjtrans! (y:: AbstractVector , A:: AbstractMatrix , b:: AbstractFillVector , alpha, beta, f)
198+ bα = getindex_value (b) * alpha
187199 At = f (A)
188200
189201 if iszero (beta)
190- for (ind, col ) in zip (eachindex (y), eachcol (At))
191- y[ind] = α .* f (sum (col))
202+ for (ind, Atcol ) in zip (eachindex (y), eachcol (At))
203+ y[ind] = f (sum (Atcol)) * bα
192204 end
193205 else
194- for (ind, col ) in zip (eachindex (y), eachcol (At))
195- y[ind] = α .* f (sum (col )) .+ beta .* y[ind]
206+ for (ind, Atcol ) in zip (eachindex (y), eachcol (At))
207+ y[ind] = f (sum (Atcol )) * bα .+ y[ind] .* beta
196208 end
197209 end
198210 y
@@ -207,11 +219,11 @@ end
207219
208220function mul! (C:: AbstractMatrix , A:: AbstractFillMatrix , B:: AbstractFillMatrix , alpha:: Number , beta:: Number )
209221 check_matmul_sizes (C, A, B)
210- αAB = alpha * getindex_value (A) * getindex_value (B) * size (B,1 )
222+ ABα = getindex_value (A) * getindex_value (B) * alpha * size (B,1 )
211223 if iszero (beta)
212- C .= αAB
224+ C .= ABα
213225 else
214- C .= αAB .+ beta .* C
226+ C .= ABα .+ C .* beta
215227 end
216228 C
217229end
@@ -237,7 +249,7 @@ _firstcol(C::Union{Adjoint, Transpose}) = view(parent(C), 1, :)
237249function _mulfill! (C, A, B:: AbstractFillMatrix , alpha, beta)
238250 check_matmul_sizes (C, A, B)
239251 if iszero (size (B,2 ))
240- return lmul! (beta, C )
252+ return rmul! (C, beta )
241253 end
242254 mul! (_firstcol (C), A, view (B, :, 1 ), alpha, beta)
243255 copyfirstcol! (C)
@@ -288,13 +300,25 @@ function _adjvec_mul_zeros(a, b)
288300 return a1 * b[1 ]
289301end
290302
291- * (a:: AdjointAbsVec{<:Any,<:AbstractZerosVector} , b:: AbstractMatrix ) = (b' * a' )'
303+ for MT in (:AbstractMatrix , :AbstractTriangular , :(Adjoint{<: Any ,<: TransposeAbsVec }))
304+ @eval * (a:: AdjointAbsVec{<:Any,<:AbstractZerosVector} , b:: $MT ) = (b' * a' )'
305+ end
306+ # ambiguity
307+ function * (a:: AdjointAbsVec{<:Any,<:AbstractZerosVector} , b:: TransposeAbsVec{<:Any,<:AdjointAbsVec} )
308+ # change from Transpose ∘ Adjoint to Adjoint ∘ Transpose
309+ b2 = adjoint (transpose (adjoint (transpose (b))))
310+ a * b2
311+ end
292312* (a:: AdjointAbsVec{<:Any,<:AbstractZerosVector} , b:: AbstractZerosMatrix ) = (b' * a' )'
293- * (a:: TransposeAbsVec{<:Any,<:AbstractZerosVector} , b:: AbstractMatrix ) = transpose (transpose (b) * transpose (a))
313+ for MT in (:AbstractMatrix , :AbstractTriangular , :(Transpose{<: Any ,<: AdjointAbsVec }))
314+ @eval * (a:: TransposeAbsVec{<:Any,<:AbstractZerosVector} , b:: $MT ) = transpose (transpose (b) * transpose (a))
315+ end
294316* (a:: TransposeAbsVec{<:Any,<:AbstractZerosVector} , b:: AbstractZerosMatrix ) = transpose (transpose (b) * transpose (a))
295317
296318* (a:: AbstractVector , b:: AdjOrTransAbsVec{<:Any,<:AbstractZerosVector} ) = a * permutedims (parent (b))
297- * (a:: AbstractMatrix , b:: AdjOrTransAbsVec{<:Any,<:AbstractZerosVector} ) = a * permutedims (parent (b))
319+ for MT in (:AbstractMatrix , :AbstractTriangular )
320+ @eval * (a:: $MT , b:: AdjOrTransAbsVec{<:Any,<:AbstractZerosVector} ) = a * permutedims (parent (b))
321+ end
298322* (a:: AbstractZerosVector , b:: AdjOrTransAbsVec{<:Any,<:AbstractZerosVector} ) = a * permutedims (parent (b))
299323* (a:: AbstractZerosMatrix , b:: AdjOrTransAbsVec{<:Any,<:AbstractZerosVector} ) = a * permutedims (parent (b))
300324
305329
306330* (a:: Adjoint{T, <:AbstractMatrix{T}} where T, b:: AbstractZeros{<:Any, 1} ) = mult_zeros (a, b)
307331
308- * (D:: Diagonal , a:: AdjointAbsVec{<:Any,<:AbstractZerosVector} ) = (a' * D' )'
332+ * (D:: Diagonal , a:: Adjoint{<:Any,<:AbstractZerosVector} ) = (a' * D' )'
333+ * (D:: Diagonal , a:: Transpose{<:Any,<:AbstractZerosVector} ) = transpose (transpose (a) * transpose (D))
309334* (a:: AdjointAbsVec{<:Any,<:AbstractZerosVector} , D:: Diagonal ) = (D' * a' )'
310335* (a:: TransposeAbsVec{<:Any,<:AbstractZerosVector} , D:: Diagonal ) = transpose (D* transpose (a))
311336function _triple_zeromul (x, D:: Diagonal , y)
323348* (x:: TransposeAbsVec{<:Any,<:AbstractZerosVector} , D:: Diagonal , y:: AbstractZerosVector ) = _triple_zeromul (x, D, y)
324349
325350
326- function * (a:: Transpose{T, <:AbstractVector{T} } , b:: AbstractZerosVector{T} ) where T<: Real
351+ function * (a:: Transpose{T, <:AbstractVector} , b:: AbstractZerosVector{T} ) where T<: Real
327352 la, lb = length (a), length (b)
328353 if la ≠ lb
329354 throw (DimensionMismatch (" dot product arguments have lengths $la and $lb " ))
@@ -496,3 +521,11 @@ function kron(f::AbstractFillVecOrMat, g::AbstractFillVecOrMat)
496521 sz = _kronsize (f, g)
497522 return _kron (f, g, sz)
498523end
524+
525+ # bandedness
526+ function LinearAlgebra. istriu (A:: AbstractFillMatrix , k:: Integer = 0 )
527+ iszero (A) || k <= - (size (A,1 )- 1 )
528+ end
529+ function LinearAlgebra. istril (A:: AbstractFillMatrix , k:: Integer = 0 )
530+ iszero (A) || k >= size (A,2 )- 1
531+ end
0 commit comments