33import LinearAlgebra: checksquare
44using Random: rand!
55
6- # # sparse matrix multiplication
7-
8- * (A:: AbstractSparseMatrixCSC{TvA,TiA} , B:: AbstractSparseMatrixCSC{TvB,TiB} ) where {TvA,TiA,TvB,TiB} =
9- * (sppromote (A, B)... )
10- * (A:: AbstractSparseMatrixCSC{TvA,TiA} , transB:: Transpose{<:Any,<:AbstractSparseMatrixCSC{TvB,TiB}} ) where {TvA,TiA,TvB,TiB} =
11- (B = transB. parent; (pA, pB) = sppromote (A, B); * (pA, transpose (pB)))
12- * (A:: AbstractSparseMatrixCSC{TvA,TiA} , adjB:: Adjoint{<:Any,<:AbstractSparseMatrixCSC{TvB,TiB}} ) where {TvA,TiA,TvB,TiB} =
13- (B = adjB. parent; (pA, pB) = sppromote (A, B); * (pA, adjoint (pB)))
14- * (transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC{TvA,TiA}} , B:: AbstractSparseMatrixCSC{TvB,TiB} ) where {TvA,TiA,TvB,TiB} =
15- (A = transA. parent; (pA, pB) = sppromote (A, B); * (transpose (pA), pB))
16- * (adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC{TvA,TiA}} , B:: AbstractSparseMatrixCSC{TvB,TiB} ) where {TvA,TiA,TvB,TiB} =
17- (A = adjA. parent; (pA, pB) = sppromote (A, B); * (adjoint (pA), pB))
18- * (transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC{TvA,TiA}} , transB:: Transpose{<:Any,<:AbstractSparseMatrixCSC{TvB,TiB}} ) where {TvA,TiA,TvB,TiB} =
19- (A = transA. parent; B = transB. parent; (pA, pB) = sppromote (A, B); * (transpose (pA), transpose (pB)))
20- * (adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC{TvA,TiA}} , adjB:: Adjoint{<:Any,<:AbstractSparseMatrixCSC{TvB,TiB}} ) where {TvA,TiA,TvB,TiB} =
21- (A = adjA. parent; B = adjB. parent; (pA, pB) = sppromote (A, B); * (adjoint (pA), adjoint (pB)))
22-
23- function sppromote (A:: AbstractSparseMatrixCSC{TvA,TiA} , B:: AbstractSparseMatrixCSC{TvB,TiB} ) where {TvA,TiA,TvB,TiB}
24- Tv = promote_type (TvA, TvB)
25- Ti = promote_type (TiA, TiB)
26- A = convert (SparseMatrixCSC{Tv,Ti}, A)
27- B = convert (SparseMatrixCSC{Tv,Ti}, B)
28- A, B
29- end
30-
316# In matrix-vector multiplication, the correct orientation of the vector is assumed.
327const AdjOrTransStridedMatrix{T} = Union{StridedMatrix{T},Adjoint{<: Any ,<: StridedMatrix{T} },Transpose{<: Any ,<: StridedMatrix{T} }}
338
@@ -50,10 +25,10 @@ function mul!(C::StridedVecOrMat, A::AbstractSparseMatrixCSC, B::Union{StridedVe
5025 end
5126 C
5227end
53- * (A:: AbstractSparseMatrixCSC{TA,S } , x:: StridedVector{Tx} ) where {TA,S ,Tx} =
54- (T = promote_op (matprod, TA, Tx); mul! (similar (x, T, size (A, 1 )), A, x, one (T), zero (T) ))
55- * (A:: AbstractSparseMatrixCSC{TA,S } , B:: StridedMatrix{Tx} ) where {TA,S ,Tx} =
56- (T = promote_op (matprod, TA, Tx); mul! (similar (B, T, (size (A, 1 ), size (B, 2 ))), A, B, one (T), zero (T) ))
28+ * (A:: AbstractSparseMatrixCSC{TA} , x:: StridedVector{Tx} ) where {TA,Tx} =
29+ (T = promote_op (matprod, TA, Tx); mul! (similar (x, T, size (A, 1 )), A, x, true , false ))
30+ * (A:: AbstractSparseMatrixCSC{TA} , B:: StridedMatrix{Tx} ) where {TA,Tx} =
31+ (T = promote_op (matprod, TA, Tx); mul! (similar (B, T, (size (A, 1 ), size (B, 2 ))), A, B, true , false ))
5732
5833function mul! (C:: StridedVecOrMat , adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} , B:: Union{StridedVector,AdjOrTransStridedMatrix} , α:: Number , β:: Number )
5934 A = adjA. parent
@@ -76,10 +51,10 @@ function mul!(C::StridedVecOrMat, adjA::Adjoint{<:Any,<:AbstractSparseMatrixCSC}
7651 end
7752 C
7853end
79- * (adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC{TA,S}} , x:: StridedVector{Tx} ) where {TA,S, Tx} =
80- (T = promote_op (matprod, TA , Tx); mul! (similar (x, T, size (adjA, 1 )), adjA, x, one (T), zero (T) ))
81- * (adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC{TA,S}} , B:: AdjOrTransStridedMatrix{Tx} ) where {TA,S,Tx} =
82- (T = promote_op (matprod, TA, Tx) ; mul! (similar (B, T, (size (adjA, 1 ), size (B, 2 ))), adjA, B, one (T), zero (T) ))
54+ * (adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} , x:: StridedVector{Tx} ) where {Tx} =
55+ (T = promote_op (matprod, eltype (adjA) , Tx); mul! (similar (x, T, size (adjA, 1 )), adjA, x, true , false ))
56+ * (adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} , B:: AdjOrTransStridedMatrix ) =
57+ (T = promote_op (matprod, eltype (adjA), eltype (B)) ; mul! (similar (B, T, (size (adjA, 1 ), size (B, 2 ))), adjA, B, true , false ))
8358
8459function mul! (C:: StridedVecOrMat , transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC} , B:: Union{StridedVector,AdjOrTransStridedMatrix} , α:: Number , β:: Number )
8560 A = transA. parent
@@ -102,19 +77,19 @@ function mul!(C::StridedVecOrMat, transA::Transpose{<:Any,<:AbstractSparseMatrix
10277 end
10378 C
10479end
105- * (transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC{TA,S}} , x:: StridedVector{Tx} ) where {TA,S, Tx} =
106- (T = promote_op (matprod, TA , Tx); mul! (similar (x, T, size (transA, 1 )), transA, x, one (T), zero (T) ))
107- * (transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC{TA,S}} , B:: AdjOrTransStridedMatrix{Tx} ) where {TA,S,Tx} =
108- (T = promote_op (matprod, TA, Tx) ; mul! (similar (B, T, (size (transA, 1 ), size (B, 2 ))), transA, B, one (T), zero (T) ))
80+ * (transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC} , x:: StridedVector{Tx} ) where {Tx} =
81+ (T = promote_op (matprod, eltype (transA) , Tx); mul! (similar (x, T, size (transA, 1 )), transA, x, true , false ))
82+ * (transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC} , B:: AdjOrTransStridedMatrix ) =
83+ (T = promote_op (matprod, eltype (transA), eltype (B)) ; mul! (similar (B, T, (size (transA, 1 ), size (B, 2 ))), transA, B, true , false ))
10984
11085# For compatibility with dense multiplication API. Should be deleted when dense multiplication
11186# API is updated to follow BLAS API.
11287mul! (C:: StridedVecOrMat , A:: AbstractSparseMatrixCSC , B:: Union{StridedVector,AdjOrTransStridedMatrix} ) =
113- mul! (C, A, B, one ( eltype (B)), zero ( eltype (C)) )
88+ mul! (C, A, B, true , false )
11489mul! (C:: StridedVecOrMat , adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} , B:: Union{StridedVector,AdjOrTransStridedMatrix} ) =
115- mul! (C, adjA, B, one ( eltype (B)), zero ( eltype (C)) )
90+ mul! (C, adjA, B, true , false )
11691mul! (C:: StridedVecOrMat , transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC} , B:: Union{StridedVector,AdjOrTransStridedMatrix} ) =
117- mul! (C, transA, B, one ( eltype (B)), zero ( eltype (C)) )
92+ mul! (C, transA, B, true , false )
11893
11994function mul! (C:: StridedVecOrMat , X:: AdjOrTransStridedMatrix , A:: AbstractSparseMatrixCSC , α:: Number , β:: Number )
12095 mX, nX = size (X)
@@ -131,8 +106,8 @@ function mul!(C::StridedVecOrMat, X::AdjOrTransStridedMatrix, A::AbstractSparseM
131106 end
132107 C
133108end
134- * (X:: AdjOrTransStridedMatrix{TX} , A:: AbstractSparseMatrixCSC{TvA,TiA } ) where {TX, TvA,TiA } =
135- (T = promote_op (matprod, TX , TvA); mul! (similar (X, T, (size (X, 1 ), size (A, 2 ))), X, A, one (T), zero (T) ))
109+ * (X:: AdjOrTransStridedMatrix , A:: AbstractSparseMatrixCSC{TvA} ) where {TvA} =
110+ (T = promote_op (matprod, eltype (X) , TvA); mul! (similar (X, T, (size (X, 1 ), size (A, 2 ))), X, A, true , false ))
136111
137112function mul! (C:: StridedVecOrMat , X:: AdjOrTransStridedMatrix , adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} , α:: Number , β:: Number )
138113 A = adjA. parent
@@ -150,8 +125,8 @@ function mul!(C::StridedVecOrMat, X::AdjOrTransStridedMatrix, adjA::Adjoint{<:An
150125 end
151126 C
152127end
153- * (X:: AdjOrTransStridedMatrix{TX} , adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC{TvA,TiA}} ) where {TX,TvA,TiA} =
154- (T = promote_op (matprod, TX, TvA) ; mul! (similar (X, T, (size (X, 1 ), size (adjA, 2 ))), X, adjA, one (T), zero (T) ))
128+ * (X:: AdjOrTransStridedMatrix , adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} ) =
129+ (T = promote_op (matprod, eltype (X), eltype (adjA)) ; mul! (similar (X, T, (size (X, 1 ), size (adjA, 2 ))), X, adjA, true , false ))
155130
156131function mul! (C:: StridedVecOrMat , X:: AdjOrTransStridedMatrix , transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC} , α:: Number , β:: Number )
157132 A = transA. parent
@@ -169,8 +144,8 @@ function mul!(C::StridedVecOrMat, X::AdjOrTransStridedMatrix, transA::Transpose{
169144 end
170145 C
171146end
172- * (X:: AdjOrTransStridedMatrix{TX} , transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC{TvA,TiA}} ) where {TX,TvA,TiA} =
173- (T = promote_op (matprod, TX, TvA) ; mul! (similar (X, T, (size (X, 1 ), size (transA, 2 ))), X, transA, one (T), zero (T) ))
147+ * (X:: AdjOrTransStridedMatrix , transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC} ) =
148+ (T = promote_op (matprod, eltype (X), eltype (transA)) ; mul! (similar (X, T, (size (X, 1 ), size (transA, 2 ))), X, transA, true , false ))
174149
175150function (* )(D:: Diagonal , A:: AbstractSparseMatrixCSC )
176151 T = Base. promote_op (* , eltype (D), eltype (A))
@@ -184,13 +159,13 @@ end
184159# Sparse matrix multiplication as described in [Gustavson, 1978]:
185160# http://dl.acm.org/citation.cfm?id=355796
186161
187- * (A:: AbstractSparseMatrixCSC{Tv,Ti} , B:: AbstractSparseMatrixCSC{Tv,Ti} ) where {Tv,Ti} = spmatmul (A,B)
188- * (A:: AbstractSparseMatrixCSC{Tv,Ti} , B:: Adjoint{<:Any,<:AbstractSparseMatrixCSC{Tv,Ti}} ) where {Tv,Ti} = spmatmul (A, copy (B))
189- * (A:: AbstractSparseMatrixCSC{Tv,Ti} , B:: Transpose{<:Any,<:AbstractSparseMatrixCSC{Tv,Ti}} ) where {Tv,Ti} = spmatmul (A, copy (B))
190- * (A:: Transpose{<:Any,<:AbstractSparseMatrixCSC{Tv,Ti}} , B:: AbstractSparseMatrixCSC{Tv,Ti} ) where {Tv,Ti} = spmatmul (copy (A), B)
191- * (A:: Adjoint{<:Any,<:AbstractSparseMatrixCSC{Tv,Ti}} , B:: AbstractSparseMatrixCSC{Tv,Ti} ) where {Tv,Ti} = spmatmul (copy (A), B)
192- * (A:: Adjoint{<:Any,<:AbstractSparseMatrixCSC{Tv,Ti}} , B:: Adjoint{<:Any,<:AbstractSparseMatrixCSC{Tv,Ti}} ) where {Tv,Ti} = spmatmul (copy (A), copy (B))
193- * (A:: Transpose{<:Any,<:AbstractSparseMatrixCSC{Tv,Ti}} , B:: Transpose{<:Any,<:AbstractSparseMatrixCSC{Tv,Ti}} ) where {Tv,Ti} = spmatmul (copy (A), copy (B))
162+ * (A:: AbstractSparseMatrixCSC , B:: AbstractSparseMatrixCSC ) = spmatmul (A,B)
163+ * (A:: AbstractSparseMatrixCSC , B:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} ) = spmatmul (A, copy (B))
164+ * (A:: AbstractSparseMatrixCSC , B:: Transpose{<:Any,<:AbstractSparseMatrixCSC} ) = spmatmul (A, copy (B))
165+ * (A:: Transpose{<:Any,<:AbstractSparseMatrixCSC} , B:: AbstractSparseMatrixCSC ) = spmatmul (copy (A), B)
166+ * (A:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} , B:: AbstractSparseMatrixCSC ) = spmatmul (copy (A), B)
167+ * (A:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} , B:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} ) = spmatmul (copy (A), copy (B))
168+ * (A:: Transpose{<:Any,<:AbstractSparseMatrixCSC} , B:: Transpose{<:Any,<:AbstractSparseMatrixCSC} ) = spmatmul (copy (A), copy (B))
194169
195170# Gustavsen's matrix multiplication algorithm revisited.
196171# The result rowval vector is already sorted by construction.
200175# done by a quicksort of the row indices or by a full scan of the dense result vector.
201176# The last is faster, if more than ≈ 1/32 of the result column is nonzero.
202177# TODO : extend to SparseMatrixCSCUnion to allow for SubArrays (view(X, :, r)).
203- function spmatmul (A:: AbstractSparseMatrixCSC{Tv,Ti} , B:: AbstractSparseMatrixCSC{Tv,Ti} ) where {Tv,Ti}
178+ function spmatmul (A:: AbstractSparseMatrixCSC{TvA,TiA} , B:: AbstractSparseMatrixCSC{TvB,TiB} ) where {TvA,TiA,TvB,TiB}
179+ Tv = promote_op (matprod, TvA, TvB)
180+ Ti = promote_type (TiA, TiB)
204181 mA, nA = size (A)
205182 nB = size (B, 2 )
206183 nA == size (B, 1 ) || throw (DimensionMismatch ())
371348
372349# # triangular sparse handling
373350
374- possible_adjoint (adj:: Bool , a:: Real ) = a
375- possible_adjoint (adj:: Bool , a ) = adj ? adjoint (a) : a
351+ possible_adjoint (adj:: Bool , a:: Real ) = a
352+ possible_adjoint (adj:: Bool , a) = adj ? adjoint (a) : a
376353
377354const UnitDiagonalTriangular = Union{UnitUpperTriangular,UnitLowerTriangular}
378355
@@ -776,7 +753,6 @@ mul!(y::StridedVecOrMat, A::SparseMatrixCSCSymmHerm, x::StridedVecOrMat) = mul!(
776753# C .= α * A * B + β * C
777754function mul! (C:: StridedVecOrMat{T} , sA:: SparseMatrixCSCSymmHerm , B:: StridedVecOrMat ,
778755 α:: Number , β:: Number ) where T
779-
780756 fuplo = sA. uplo == ' U' ? nzrangeup : nzrangelo
781757 _mul! (fuplo, C, sA, B, T (α), T (β))
782758end
0 commit comments