@@ -34,10 +34,10 @@ function mul!(C::StridedVecOrMat, A::AbstractSparseMatrixCSC, B::Union{StridedVe
34
34
if β != 1
35
35
β != 0 ? rmul! (C, β) : fill! (C, zero (eltype (C)))
36
36
end
37
- for k = 1 : size (C, 2 )
38
- @inbounds for col = 1 : size (A, 2 )
37
+ for k in 1 : size (C, 2 )
38
+ @inbounds for col in 1 : size (A, 2 )
39
39
αxj = B[col,k] * α
40
- for j = getcolptr (A)[col] : ( getcolptr (A)[col + 1 ] - 1 )
40
+ for j in nzrange (A, col )
41
41
C[rv[j], k] += nzv[j]* αxj
42
42
end
43
43
end
49
49
* (A:: SparseMatrixCSCUnion{TA} , B:: AdjOrTransStridedOrTriangularMatrix{Tx} ) where {TA,Tx} =
50
50
(T = promote_op (matprod, TA, Tx); mul! (similar (B, T, (size (A, 1 ), size (B, 2 ))), A, B, true , false ))
51
51
52
- function mul! (C:: StridedVecOrMat , adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} , B:: Union{StridedVector,AdjOrTransStridedOrTriangularMatrix} , α:: Number , β:: Number )
53
- A = adjA. parent
54
- size (A, 2 ) == size (C, 1 ) || throw (DimensionMismatch ())
55
- size (A, 1 ) == size (B, 1 ) || throw (DimensionMismatch ())
56
- size (B, 2 ) == size (C, 2 ) || throw (DimensionMismatch ())
57
- nzv = nonzeros (A)
58
- rv = rowvals (A)
59
- if β != 1
60
- β != 0 ? rmul! (C, β) : fill! (C, zero (eltype (C)))
61
- end
62
- for k = 1 : size (C, 2 )
63
- @inbounds for col = 1 : size (A, 2 )
64
- tmp = zero (eltype (C))
65
- for j = getcolptr (A)[col]: (getcolptr (A)[col + 1 ] - 1 )
66
- tmp += adjoint (nzv[j])* B[rv[j],k]
52
+ for (T, t) in ((Adjoint, adjoint), (Transpose, transpose))
53
+ @eval function mul! (C:: StridedVecOrMat , xA:: $T{<:Any,<:AbstractSparseMatrixCSC} , B:: Union{StridedVector,AdjOrTransStridedOrTriangularMatrix} , α:: Number , β:: Number )
54
+ A = xA. parent
55
+ size (A, 2 ) == size (C, 1 ) || throw (DimensionMismatch ())
56
+ size (A, 1 ) == size (B, 1 ) || throw (DimensionMismatch ())
57
+ size (B, 2 ) == size (C, 2 ) || throw (DimensionMismatch ())
58
+ nzv = nonzeros (A)
59
+ rv = rowvals (A)
60
+ if β != 1
61
+ β != 0 ? rmul! (C, β) : fill! (C, zero (eltype (C)))
62
+ end
63
+ for k in 1 : size (C, 2 )
64
+ @inbounds for col in 1 : size (A, 2 )
65
+ tmp = zero (eltype (C))
66
+ for j in nzrange (A, col)
67
+ tmp += $ t (nzv[j])* B[rv[j],k]
68
+ end
69
+ C[col,k] += tmp * α
67
70
end
68
- C[col,k] += tmp * α
69
71
end
72
+ C
70
73
end
71
- C
72
74
end
73
75
* (adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} , x:: StridedVector{Tx} ) where {Tx} =
74
76
(T = promote_op (matprod, eltype (adjA), Tx); mul! (similar (x, T, size (adjA, 1 )), adjA, x, true , false ))
75
77
* (adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} , B:: AdjOrTransStridedOrTriangularMatrix ) =
76
78
(T = promote_op (matprod, eltype (adjA), eltype (B)); mul! (similar (B, T, (size (adjA, 1 ), size (B, 2 ))), adjA, B, true , false ))
77
-
78
- function mul! (C:: StridedVecOrMat , transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC} , B:: Union{StridedVector,AdjOrTransStridedOrTriangularMatrix} , α:: Number , β:: Number )
79
- A = transA. parent
80
- size (A, 2 ) == size (C, 1 ) || throw (DimensionMismatch ())
81
- size (A, 1 ) == size (B, 1 ) || throw (DimensionMismatch ())
82
- size (B, 2 ) == size (C, 2 ) || throw (DimensionMismatch ())
83
- nzv = nonzeros (A)
84
- rv = rowvals (A)
85
- if β != 1
86
- β != 0 ? rmul! (C, β) : fill! (C, zero (eltype (C)))
87
- end
88
- for k = 1 : size (C, 2 )
89
- @inbounds for col = 1 : size (A, 2 )
90
- tmp = zero (eltype (C))
91
- for j = getcolptr (A)[col]: (getcolptr (A)[col + 1 ] - 1 )
92
- tmp += transpose (nzv[j])* B[rv[j],k]
93
- end
94
- C[col,k] += tmp * α
95
- end
96
- end
97
- C
98
- end
99
79
* (transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC} , x:: StridedVector{Tx} ) where {Tx} =
100
80
(T = promote_op (matprod, eltype (transA), Tx); mul! (similar (x, T, size (transA, 1 )), transA, x, true , false ))
101
81
* (transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC} , B:: AdjOrTransStridedOrTriangularMatrix ) =
102
82
(T = promote_op (matprod, eltype (transA), eltype (B)); mul! (similar (B, T, (size (transA, 1 ), size (B, 2 ))), transA, B, true , false ))
103
83
104
- # For compatibility with dense multiplication API. Should be deleted when dense multiplication
105
- # API is updated to follow BLAS API.
106
- mul! (C:: StridedVecOrMat , A:: AbstractSparseMatrixCSC , B:: Union{StridedVector,AdjOrTransStridedOrTriangularMatrix} ) =
107
- mul! (C, A, B, true , false )
108
- mul! (C:: StridedVecOrMat , adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} , B:: Union{StridedVector,AdjOrTransStridedOrTriangularMatrix} ) =
109
- mul! (C, adjA, B, true , false )
110
- mul! (C:: StridedVecOrMat , transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC} , B:: Union{StridedVector,AdjOrTransStridedOrTriangularMatrix} ) =
111
- mul! (C, transA, B, true , false )
112
-
113
84
function mul! (C:: StridedVecOrMat , X:: AdjOrTransStridedOrTriangularMatrix , A:: AbstractSparseMatrixCSC , α:: Number , β:: Number )
114
85
mX, nX = size (X)
115
86
nX == size (A, 1 ) || throw (DimensionMismatch ())
@@ -120,49 +91,50 @@ function mul!(C::StridedVecOrMat, X::AdjOrTransStridedOrTriangularMatrix, A::Abs
120
91
if β != 1
121
92
β != 0 ? rmul! (C, β) : fill! (C, zero (eltype (C)))
122
93
end
123
- @inbounds for multivec_row= 1 : mX, col = 1 : size (A, 2 ), k= getcolptr (A)[col]: (getcolptr (A)[col+ 1 ]- 1 )
124
- C[multivec_row, col] += α * X[multivec_row, rv[k]] * nzv[k] # perhaps suboptimal position of α?
94
+ if X isa StridedOrTriangularMatrix
95
+ @inbounds for col in 1 : size (A, 2 ), k in nzrange (A, col)
96
+ Aiα = nzv[k] * α
97
+ rvk = rv[k]
98
+ @simd for multivec_row in 1 : mX
99
+ C[multivec_row, col] += X[multivec_row, rvk] * Aiα
100
+ end
101
+ end
102
+ else # X isa Adjoint or Transpose
103
+ for multivec_row in 1 : mX, col in 1 : size (A, 2 )
104
+ @inbounds for k in nzrange (A, col)
105
+ C[multivec_row, col] += X[multivec_row, rv[k]] * nzv[k] * α
106
+ end
107
+ end
125
108
end
126
109
C
127
110
end
128
111
* (X:: AdjOrTransStridedOrTriangularMatrix , A:: SparseMatrixCSCUnion{TvA} ) where {TvA} =
129
112
(T = promote_op (matprod, eltype (X), TvA); mul! (similar (X, T, (size (X, 1 ), size (A, 2 ))), X, A, true , false ))
130
113
131
- function mul! (C:: StridedVecOrMat , X:: AdjOrTransStridedOrTriangularMatrix , adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} , α:: Number , β:: Number )
132
- A = adjA. parent
133
- mX, nX = size (X)
134
- nX == size (A, 2 ) || throw (DimensionMismatch ())
135
- mX == size (C, 1 ) || throw (DimensionMismatch ())
136
- size (A, 1 ) == size (C, 2 ) || throw (DimensionMismatch ())
137
- rv = rowvals (A)
138
- nzv = nonzeros (A)
139
- if β != 1
140
- β != 0 ? rmul! (C, β) : fill! (C, zero (eltype (C)))
141
- end
142
- @inbounds for col = 1 : size (A, 2 ), k= getcolptr (A)[col]: (getcolptr (A)[col+ 1 ]- 1 ), multivec_col= 1 : mX
143
- C[multivec_col, rv[k]] += α * X[multivec_col, col] * adjoint (nzv[k]) # perhaps suboptimal position of α?
114
+ for (T, t) in ((Adjoint, adjoint), (Transpose, transpose))
115
+ @eval function mul! (C:: StridedVecOrMat , X:: AdjOrTransStridedOrTriangularMatrix , xA:: $T{<:Any,<:AbstractSparseMatrixCSC} , α:: Number , β:: Number )
116
+ A = xA. parent
117
+ mX, nX = size (X)
118
+ nX == size (A, 2 ) || throw (DimensionMismatch ())
119
+ mX == size (C, 1 ) || throw (DimensionMismatch ())
120
+ size (A, 1 ) == size (C, 2 ) || throw (DimensionMismatch ())
121
+ rv = rowvals (A)
122
+ nzv = nonzeros (A)
123
+ if β != 1
124
+ β != 0 ? rmul! (C, β) : fill! (C, zero (eltype (C)))
125
+ end
126
+ @inbounds for col in 1 : size (A, 2 ), k in nzrange (A, col)
127
+ Aiα = $ t (nzv[k]) * α
128
+ rvk = rv[k]
129
+ @simd for multivec_col in 1 : mX
130
+ C[multivec_col, rvk] += X[multivec_col, col] * Aiα
131
+ end
132
+ end
133
+ C
144
134
end
145
- C
146
135
end
147
136
* (X:: AdjOrTransStridedOrTriangularMatrix , adjA:: Adjoint{<:Any,<:AbstractSparseMatrixCSC} ) =
148
137
(T = promote_op (matprod, eltype (X), eltype (adjA)); mul! (similar (X, T, (size (X, 1 ), size (adjA, 2 ))), X, adjA, true , false ))
149
-
150
- function mul! (C:: StridedVecOrMat , X:: AdjOrTransStridedOrTriangularMatrix , transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC} , α:: Number , β:: Number )
151
- A = transA. parent
152
- mX, nX = size (X)
153
- nX == size (A, 2 ) || throw (DimensionMismatch ())
154
- mX == size (C, 1 ) || throw (DimensionMismatch ())
155
- size (A, 1 ) == size (C, 2 ) || throw (DimensionMismatch ())
156
- rv = rowvals (A)
157
- nzv = nonzeros (A)
158
- if β != 1
159
- β != 0 ? rmul! (C, β) : fill! (C, zero (eltype (C)))
160
- end
161
- @inbounds for col = 1 : size (A, 2 ), k= getcolptr (A)[col]: (getcolptr (A)[col+ 1 ]- 1 ), multivec_col= 1 : mX
162
- C[multivec_col, rv[k]] += α * X[multivec_col, col] * transpose (nzv[k]) # perhaps suboptimal position of α?
163
- end
164
- C
165
- end
166
138
* (X:: AdjOrTransStridedOrTriangularMatrix , transA:: Transpose{<:Any,<:AbstractSparseMatrixCSC} ) =
167
139
(T = promote_op (matprod, eltype (X), eltype (transA)); mul! (similar (X, T, (size (X, 1 ), size (transA, 2 ))), X, transA, true , false ))
168
140
@@ -896,7 +868,7 @@ function ldiv!(D::Diagonal{T}, A::AbstractSparseMatrixCSC{T}) where {T}
896
868
for i= 1 : length (b)
897
869
iszero (b[i]) && throw (SingularException (i))
898
870
end
899
- @inbounds for col = 1 : size (A, 2 ), p = getcolptr (A)[col] : ( getcolptr (A)[col + 1 ] - 1 )
871
+ @inbounds for col in 1 : size (A, 2 ), p in nzrange (A, col )
900
872
nonz[p] = b[Arowval[p]] \ nonz[p]
901
873
end
902
874
A
@@ -916,7 +888,7 @@ function triu(S::AbstractSparseMatrixCSC{Tv,Ti}, k::Integer=0) where {Tv,Ti}
916
888
colptr[col] = 1
917
889
end
918
890
for col = max (k+ 1 ,1 ) : n
919
- for c1 = getcolptr (S)[col] : getcolptr (S)[ col+ 1 ] - 1
891
+ for c1 in nzrange (S, col)
920
892
rowvals (S)[c1] > col - k && break
921
893
nnz += 1
922
894
end
@@ -927,7 +899,7 @@ function triu(S::AbstractSparseMatrixCSC{Tv,Ti}, k::Integer=0) where {Tv,Ti}
927
899
A = SparseMatrixCSC (m, n, colptr, rowval, nzval)
928
900
for col = max (k+ 1 ,1 ) : n
929
901
c1 = getcolptr (S)[col]
930
- for c2 = getcolptr (A)[col] : getcolptr (A)[ col+ 1 ] - 1
902
+ for c2 in nzrange (A, col)
931
903
rowvals (A)[c2] = rowvals (S)[c1]
932
904
nonzeros (A)[c2] = nonzeros (S)[c1]
933
905
c1 += 1
@@ -981,7 +953,7 @@ function sparse_diff1(S::AbstractSparseMatrixCSC{Tv,Ti}) where {Tv,Ti}
981
953
for col = 1 : n
982
954
last_row = 0
983
955
last_val = 0
984
- for k = getcolptr (S)[col] : getcolptr (S)[ col+ 1 ] - 1
956
+ for k in nzrange (S, col)
985
957
row = rowvals (S)[k]
986
958
val = nonzeros (S)[k]
987
959
if row > 1
@@ -1124,7 +1096,7 @@ function opnorm(A::AbstractSparseMatrixCSC, p::Real=2)
1124
1096
nA:: Tsum = 0
1125
1097
for j= 1 : n
1126
1098
colSum:: Tsum = 0
1127
- for i = getcolptr (A)[j] : getcolptr (A)[j + 1 ] - 1
1099
+ for i in nzrange (A, j)
1128
1100
colSum += abs (nonzeros (A)[i])
1129
1101
end
1130
1102
nA = max (nA, colSum)
@@ -1469,7 +1441,7 @@ function mul!(C::AbstractSparseMatrixCSC, A::AbstractSparseMatrixCSC, D::Diagona
1469
1441
Cnzval = nonzeros (C)
1470
1442
Anzval = nonzeros (A)
1471
1443
resize! (Cnzval, length (Anzval))
1472
- for col = 1 : n, p = getcolptr (A)[ col] : ( getcolptr (A)[col + 1 ] - 1 )
1444
+ for col in 1 : n, p in nzrange (A, col)
1473
1445
@inbounds Cnzval[p] = Anzval[p] * b[col]
1474
1446
end
1475
1447
C
@@ -1484,7 +1456,7 @@ function mul!(C::AbstractSparseMatrixCSC, D::Diagonal, A::AbstractSparseMatrixCS
1484
1456
Anzval = nonzeros (A)
1485
1457
Arowval = rowvals (A)
1486
1458
resize! (Cnzval, length (Anzval))
1487
- for col = 1 : n, p = getcolptr (A)[ col] : ( getcolptr (A)[col + 1 ] - 1 )
1459
+ for col in 1 : n, p in nzrange (A, col)
1488
1460
@inbounds Cnzval[p] = b[Arowval[p]] * Anzval[p]
1489
1461
end
1490
1462
C
@@ -1520,7 +1492,7 @@ function rmul!(A::AbstractSparseMatrixCSC, D::Diagonal)
1520
1492
m, n = size (A)
1521
1493
(n == size (D, 1 )) || throw (DimensionMismatch ())
1522
1494
Anzval = nonzeros (A)
1523
- @inbounds for col = 1 : n, p = getcolptr (A)[col] : ( getcolptr (A)[col + 1 ] - 1 )
1495
+ @inbounds for col in 1 : n, p in nzrange (A, col )
1524
1496
Anzval[p] = Anzval[p] * D. diag[col]
1525
1497
end
1526
1498
return A
@@ -1531,7 +1503,7 @@ function lmul!(D::Diagonal, A::AbstractSparseMatrixCSC)
1531
1503
(m == size (D, 2 )) || throw (DimensionMismatch ())
1532
1504
Anzval = nonzeros (A)
1533
1505
Arowval = rowvals (A)
1534
- @inbounds for col = 1 : n, p = getcolptr (A)[col] : ( getcolptr (A)[col + 1 ] - 1 )
1506
+ @inbounds for col in 1 : n, p in nzrange (A, col )
1535
1507
Anzval[p] = D. diag[Arowval[p]] * Anzval[p]
1536
1508
end
1537
1509
return A
0 commit comments