@@ -1315,6 +1315,15 @@ function opnormestinv(A::AbstractSparseMatrixCSC{T}, t::Integer = min(2,maximum(
1315
1315
end
1316
1316
1317
1317
# # kron
1318
+ const _SparseArraysCSC{T} = Union{SparseVector{T}, AbstractSparseMatrixCSC{T}}
1319
+ const _SparseKronArrays = Union{_SpecialArrays, _SparseArrays, AdjOrTrans{<: Any ,<: _SparseArraysCSC }}
1320
+
1321
+ const _Symmetric_SparseKronArrays{T,A<: _SparseKronArrays } = Symmetric{T,A}
1322
+ const _Hermitian_SparseKronArrays{T,A<: _SparseKronArrays } = Hermitian{T,A}
1323
+ const _Triangular_SparseKronArrays{T,A<: _SparseKronArrays } = UpperOrLowerTriangular{T,A}
1324
+ const _Annotated_SparseKronArrays = Union{_Triangular_SparseKronArrays, _Symmetric_SparseKronArrays, _Hermitian_SparseKronArrays}
1325
+ const _SparseKronGroup = Union{_SparseKronArrays, _Annotated_SparseKronArrays}
1326
+
1318
1327
@inline function kron! (C:: SparseMatrixCSC , A:: AbstractSparseMatrixCSC , B:: AbstractSparseMatrixCSC )
1319
1328
mA, nA = size (A); mB, nB = size (B)
1320
1329
mC, nC = mA* mB, nA* nB
@@ -1353,19 +1362,10 @@ end
1353
1362
end
1354
1363
return C
1355
1364
end
1356
- @inline function kron! (C:: SparseMatrixCSC , A:: AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC} , B:: AbstractSparseMatrixCSC )
1357
- return kron! (C, copy (A), B)
1358
- end
1359
- @inline function kron! (C:: SparseMatrixCSC , A:: AbstractSparseMatrixCSC , B:: AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC} )
1360
- return kron! (C, A, copy (B))
1361
- end
1362
- @inline function kron! (C:: SparseMatrixCSC , A:: AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC} , B:: AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC} )
1363
- return kron! (C, copy (A), copy (B))
1364
- end
1365
1365
@inline function kron! (z:: SparseVector , x:: SparseVector , y:: SparseVector )
1366
1366
@boundscheck length (z) == length (x)* length (y) || throw (DimensionMismatch (" length of " *
1367
1367
" target vector needs to be $(length (x)* length (y)) , but has length $(length (z)) " ))
1368
- nnzx = nnz (x); nnzy = nnz (y);
1368
+ nnzx, nnzy = nnz (x), nnz (y)
1369
1369
nzind = nonzeroinds (z)
1370
1370
nzval = nonzeros (z)
1371
1371
@@ -1380,69 +1380,35 @@ end
1380
1380
end
1381
1381
return z
1382
1382
end
1383
+ # due to the sparse result type, there is no risk to override dense ⊗ dense here
1384
+ @inline function kron! (C:: SparseMatrixCSC , A:: Union{_SparseKronGroup,_DenseConcatGroup} , B:: Union{_SparseKronGroup,_DenseConcatGroup} )
1385
+ kron! (C, convert (SparseMatrixCSC, A), convert (SparseMatrixCSC, B))
1386
+ end
1387
+ kron! (C:: SparseMatrixCSC , A:: SparseVectorUnion , B:: AdjOrTransSparseVectorUnion ) = broadcast! (* , C, A, B)
1383
1388
1384
- # sparse matrix ⊗ sparse matrix
1385
- function kron (A :: AbstractSparseMatrixCSC{T1,S1} , B :: AbstractSparseMatrixCSC{T2,S2} ) where {T1,S1,T2,S2}
1386
- mA, nA = size (A); mB, nB = size (B)
1389
+ function kron (A :: AbstractSparseMatrixCSC , B :: AbstractSparseMatrixCSC )
1390
+ mA, nA = size (A)
1391
+ mB, nB = size (B)
1387
1392
mC, nC = mA* mB, nA* nB
1388
- Tv = typeof (one (T1) * one (T2 ))
1389
- Ti = promote_type (S1,S2 )
1393
+ Tv = typeof (oneunit ( eltype (A)) * oneunit ( eltype (B) ))
1394
+ Ti = promote_type (indtype (A), indtype (B) )
1390
1395
C = spzeros (Tv, Ti, mC, nC)
1391
1396
sizehint! (C, nnz (A)* nnz (B))
1392
1397
return @inbounds kron! (C, A, B)
1393
1398
end
1394
- kron (A:: AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC} , B:: AbstractSparseMatrixCSC ) = kron (copy (A), B)
1395
- kron (A:: AbstractSparseMatrixCSC , B:: AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC} ) = kron (A, copy (B))
1396
- function kron (A:: AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC} , B:: AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC} )
1397
- return kron (copy (A), copy (B))
1398
- end
1399
-
1400
- # sparse vector ⊗ sparse vector
1401
- function kron (x:: SparseVector{T1,S1} , y:: SparseVector{T2,S2} ) where {T1,S1,T2,S2}
1402
- nnzx = nnz (x); nnzy = nnz (y)
1399
+ function kron (x:: SparseVector , y:: SparseVector )
1400
+ nnzx, nnzy = nnz (x), nnz (y)
1403
1401
nnzz = nnzx* nnzy # number of nonzeros in new vector
1404
- nzind = Vector {promote_type(S1,S2 )} (undef, nnzz) # the indices of nonzeros
1405
- nzval = Vector {typeof(one(T1)*one(T2 ))} (undef, nnzz) # the values of nonzeros
1402
+ nzind = Vector {promote_type(indtype(x), indtype(y) )} (undef, nnzz) # the indices of nonzeros
1403
+ nzval = Vector {typeof(oneunit(eltype(x))*oneunit(eltype(y) ))} (undef, nnzz) # the values of nonzeros
1406
1404
z = SparseVector (length (x)* length (y), nzind, nzval)
1407
1405
return @inbounds kron! (z, x, y)
1408
1406
end
1409
-
1410
- # sparse matrix ⊗ sparse vector & vice versa
1411
- Base. @propagate_inbounds kron! (C:: SparseMatrixCSC , A:: AbstractSparseMatrixCSC , x:: SparseVector ) = kron! (C, A, SparseMatrixCSC (x))
1412
- Base. @propagate_inbounds kron! (C:: SparseMatrixCSC , x:: SparseVector , A:: AbstractSparseMatrixCSC ) = kron! (C, SparseMatrixCSC (x), A)
1413
-
1414
- kron (A:: AbstractSparseMatrixCSC , x:: SparseVector ) = kron (A, SparseMatrixCSC (x))
1415
- kron (A:: AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC} , x:: SparseVector ) =
1416
- kron (copy (A), x)
1417
- kron (x:: SparseVector , A:: AbstractSparseMatrixCSC ) = kron (SparseMatrixCSC (x), A)
1418
- kron (x:: SparseVector , A:: AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC} ) =
1419
- kron (x, copy (A))
1420
-
1421
- # sparse vec/mat ⊗ vec/mat and vice versa
1422
- Base. @propagate_inbounds kron! (C:: SparseMatrixCSC , A:: Union{SparseVector,AbstractSparseMatrixCSC} , B:: VecOrMat ) = kron! (C, A, sparse (B))
1423
- Base. @propagate_inbounds kron! (C:: SparseMatrixCSC , A:: VecOrMat , B:: Union{SparseVector,AbstractSparseMatrixCSC} ) = kron! (C, sparse (A), B)
1424
-
1425
- kron (A:: Union{SparseVector,AbstractSparseMatrixCSC,AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC}} , B:: VecOrMat ) =
1426
- kron (A, sparse (B))
1427
- kron (A:: VecOrMat , B:: Union{SparseVector,AbstractSparseMatrixCSC,AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC}} ) =
1428
- kron (sparse (A), B)
1429
-
1430
- # sparse vec/mat ⊗ Diagonal etc. and vice versa
1431
- const StructuredMatrix{T} = Union{Bidiagonal{T}, Diagonal{T}, SymTridiagonal{T}, Tridiagonal{T}}
1432
- Base. @propagate_inbounds kron! (C:: SparseMatrixCSC , A:: StructuredMatrix{T} , B:: Union{SparseVector{S}, AbstractSparseMatrixCSC{S}} ) where {T<: Number , S<: Number } =
1433
- kron! (C, sparse (A), B)
1434
- Base. @propagate_inbounds kron! (C:: SparseMatrixCSC , A:: Union{SparseVector{T}, AbstractSparseMatrixCSC{T}} , B:: StructuredMatrix{S} ) where {T<: Number , S<: Number } =
1435
- kron! (C, A, sparse (B))
1436
-
1437
- Base. @propagate_inbounds kron! (C:: SparseMatrixCSC , A:: Union{SparseVector{T}, AbstractSparseMatrixCSC{T}} , B:: Diagonal{S} ) where {T<: Number , S<: Number } = kron! (C, A, sparse (B))
1438
-
1439
- kron (A:: StructuredMatrix{T} , B:: Union{SparseVector{S}, AbstractSparseMatrixCSC{S}, AdjOrTrans{S,<:SparseVector}, AdjOrTrans{S,<:AbstractSparseMatrixCSC}} ) where {T<: Number , S<: Number } =
1440
- kron (sparse (A), B)
1441
- kron (A:: Union{SparseVector{T}, AbstractSparseMatrixCSC{T}, AdjOrTrans{S,<:SparseVector}, AdjOrTrans{S,<:AbstractSparseMatrixCSC}} , B:: StructuredMatrix{S} ) where {T<: Number , S<: Number } =
1442
- kron (A, sparse (B))
1443
-
1444
- # sparse outer product
1445
- kron! (C:: SparseMatrixCSC , A:: SparseVectorUnion , B:: AdjOrTransSparseVectorUnion ) = broadcast! (* , C, A, B)
1407
+ # extend to annotated sparse arrays, but leave out the (dense ⊗ dense)-case
1408
+ kron (A:: _SparseKronGroup , B:: _SparseKronGroup ) =
1409
+ kron (convert (SparseMatrixCSC, A), convert (SparseMatrixCSC, B))
1410
+ kron (A:: _SparseKronGroup , B:: _DenseConcatGroup ) = kron (A, sparse (B))
1411
+ kron (A:: _DenseConcatGroup , B:: _SparseKronGroup ) = kron (sparse (A), B)
1446
1412
kron (A:: SparseVectorUnion , B:: AdjOrTransSparseVectorUnion ) = A .* B
1447
1413
1448
1414
# # det, inv, cond
0 commit comments