@@ -1401,52 +1401,65 @@ sparse(S::UniformScaling, m::Integer, n::Integer=m) = speye_scaled(S.λ, m, n)
1401
1401
# # map/map! and broadcast/broadcast! over sparse matrices
1402
1402
1403
1403
# map/map! entry points
1404
- function map! {Tf ,N} (f:: Tf , C:: SparseMatrixCSC , A:: SparseMatrixCSC , Bs:: Vararg{SparseMatrixCSC,N} )
1404
+ function map! {F ,N} (f:: F , C:: SparseMatrixCSC , A:: SparseMatrixCSC , Bs:: Vararg{SparseMatrixCSC,N} )
1405
1405
_checksameshape (C, A, Bs... )
1406
+ return _map! (f, C, A, Bs... )
1407
+ end
1408
+ @inline function _map! (f, C, A, Bs:: Vararg )
1406
1409
fofzeros = f (_zeros_eltypes (A, Bs... )... )
1407
1410
fpreszeros = fofzeros == zero (fofzeros)
1408
1411
return fpreszeros ? _map_zeropres! (f, C, A, Bs... ) :
1409
1412
_map_notzeropres! (f, fofzeros, C, A, Bs... )
1410
1413
end
1411
- function map {Tf ,N} (f:: Tf , A:: SparseMatrixCSC , Bs:: Vararg{SparseMatrixCSC,N} )
1414
+ function map {F ,N} (f:: F , A:: SparseMatrixCSC , Bs:: Vararg{SparseMatrixCSC,N} )
1412
1415
_checksameshape (A, Bs... )
1413
- fofzeros = f ( _zeros_eltypes ( A, Bs... ) ... )
1414
- fpreszeros = fofzeros == zero (fofzeros)
1415
- maxnnzC = fpreszeros ? min ( length (A), _sumnnzs ( A, Bs... )) : length (A )
1416
+ return _map (f, A, Bs... )
1417
+ end
1418
+ @inline function _map (f, A, Bs:: Vararg )
1416
1419
entrytypeC = _broadcast_type (f, A, Bs... )
1417
- indextypeC = _promote_indtype (A, Bs... )
1418
- Ccolptr = Vector {indextypeC} (A. n + 1 )
1419
- Crowval = Vector {indextypeC} (maxnnzC)
1420
- Cnzval = Vector {entrytypeC} (maxnnzC)
1421
- C = SparseMatrixCSC (A. m, A. n, Ccolptr, Crowval, Cnzval)
1422
- return fpreszeros ? _map_zeropres! (f, C, A, Bs... ) :
1423
- _map_notzeropres! (f, fofzeros, C, A, Bs... )
1420
+ if isleaftype (entrytypeC)
1421
+ indextypeC = _promote_indtype (A, Bs... )
1422
+ fofzeros = f (_zeros_eltypes (A, Bs... )... )
1423
+ fpreszeros = fofzeros == zero (fofzeros)
1424
+ maxnnzC = fpreszeros ? min (length (A), _sumnnzs (A, Bs... )) : length (A)
1425
+ Ccolptr = Vector {indextypeC} (A. n + 1 )
1426
+ Crowval = Vector {indextypeC} (maxnnzC)
1427
+ Cnzval = Vector {entrytypeC} (maxnnzC)
1428
+ C = SparseMatrixCSC (A. m, A. n, Ccolptr, Crowval, Cnzval)
1429
+ return fpreszeros ? _map_zeropres! (f, C, A, Bs... ) :
1430
+ _map_notzeropres! (f, fofzeros, C, A, Bs... )
1431
+ end
1432
+ return sparse (collect (Base. Generator (f, A, Bs... )))
1424
1433
end
1425
1434
# broadcast/broadcast! entry points
1426
- broadcast {Tf } (f:: Tf , A:: SparseMatrixCSC ) = map (f, A)
1427
- broadcast! {Tf } (f:: Tf , C:: SparseMatrixCSC , A:: SparseMatrixCSC ) = map! (f, C, A)
1428
- function broadcast! {Tf ,N} (f:: Tf , C:: SparseMatrixCSC , A:: SparseMatrixCSC , Bs:: Vararg{SparseMatrixCSC,N} )
1429
- _aresameshape (C, A, Bs... ) && return map ! (f, C, A, Bs... ) # could avoid a second dims check in map
1435
+ broadcast {F } (f:: F , A:: SparseMatrixCSC ) = map (f, A)
1436
+ broadcast! {F } (f:: F , C:: SparseMatrixCSC , A:: SparseMatrixCSC ) = map! (f, C, A)
1437
+ function broadcast! {F ,N} (f:: F , C:: SparseMatrixCSC , A:: SparseMatrixCSC , Bs:: Vararg{SparseMatrixCSC,N} )
1438
+ _aresameshape (C, A, Bs... ) && return _map ! (f, C, A, Bs... )
1430
1439
Base. Broadcast. check_broadcast_indices (indices (C), A, Bs... )
1431
1440
fofzeros = f (_zeros_eltypes (A, Bs... )... )
1432
1441
fpreszeros = fofzeros == zero (fofzeros)
1433
1442
return fpreszeros ? _broadcast_zeropres! (f, C, A, Bs... ) :
1434
1443
_broadcast_notzeropres! (f, fofzeros, C, A, Bs... )
1435
1444
end
1436
- function broadcast {Tf,N} (f:: Tf , A:: SparseMatrixCSC , Bs:: Vararg{SparseMatrixCSC,N} )
1437
- _aresameshape (A, Bs... ) && return map (f, A, Bs... ) # could avoid a second dims check in map
1438
- fofzeros = f (_zeros_eltypes (A, Bs... )... )
1439
- fpreszeros = fofzeros == zero (fofzeros)
1440
- indextypeC = _promote_indtype (A, Bs... )
1445
+ function broadcast {F,N} (f:: F , A:: SparseMatrixCSC , Bs:: Vararg{SparseMatrixCSC,N} )
1446
+ _aresameshape (A, Bs... ) && return _map (f, A, Bs... )
1441
1447
entrytypeC = _broadcast_type (f, A, Bs... )
1442
- Cm, Cn = Base. to_shape (Base. Broadcast. broadcast_indices (A, Bs... ))
1443
- maxnnzC = fpreszeros ? _checked_maxnnzbcres (Cm, Cn, A, Bs... ) : (Cm * Cn)
1444
- Ccolptr = Vector {indextypeC} (Cn + 1 )
1445
- Crowval = Vector {indextypeC} (maxnnzC)
1446
- Cnzval = Vector {entrytypeC} (maxnnzC)
1447
- C = SparseMatrixCSC (Cm, Cn, Ccolptr, Crowval, Cnzval)
1448
- return fpreszeros ? _broadcast_zeropres! (f, C, A, Bs... ) :
1449
- _broadcast_notzeropres! (f, fofzeros, C, A, Bs... )
1448
+ shape = Base. Broadcast. broadcast_indices (A, Bs... )
1449
+ if isleaftype (entrytypeC)
1450
+ indextypeC = _promote_indtype (A, Bs... )
1451
+ fofzeros = f (_zeros_eltypes (A, Bs... )... )
1452
+ fpreszeros = fofzeros == zero (fofzeros)
1453
+ Cm, Cn = Base. to_shape (shape)
1454
+ maxnnzC = fpreszeros ? _checked_maxnnzbcres (Cm, Cn, A, Bs... ) : (Cm * Cn)
1455
+ Ccolptr = Vector {indextypeC} (Cn + 1 )
1456
+ Crowval = Vector {indextypeC} (maxnnzC)
1457
+ Cnzval = Vector {entrytypeC} (maxnnzC)
1458
+ C = SparseMatrixCSC (Cm, Cn, Ccolptr, Crowval, Cnzval)
1459
+ return fpreszeros ? _broadcast_zeropres! (f, C, A, Bs... ) :
1460
+ _broadcast_notzeropres! (f, fofzeros, C, A, Bs... )
1461
+ end
1462
+ return sparse (Base. Broadcast. broadcast_t (f, Any, shape, CartesianRange (shape), A, Bs... ))
1450
1463
end
1451
1464
# map/map! and broadcast/broadcast! entry point helper functions
1452
1465
@inline _sumnnzs (A) = nnz (A)
@@ -1468,7 +1481,7 @@ _broadcast_type(f, As...) = Base._promote_op(f, Base.Broadcast.typestuple(As...)
1468
1481
1469
1482
# _map_zeropres!/_map_notzeropres! specialized for a single sparse matrix
1470
1483
" Stores only the nonzero entries of `map(f, Matrix(A))` in `C`."
1471
- function _map_zeropres! {Tf} (f :: Tf , C:: SparseMatrixCSC , A:: SparseMatrixCSC )
1484
+ function _map_zeropres! (f , C:: SparseMatrixCSC , A:: SparseMatrixCSC )
1472
1485
spaceC = min (length (C. rowval), length (C. nzval))
1473
1486
Ck = 1
1474
1487
@inbounds for j in 1 : C. n
@@ -1491,7 +1504,7 @@ end
1491
1504
Densifies `C`, storing `fillvalue` in place of each unstored entry in `A` and
1492
1505
`f(A[i,j])` in place of each stored entry `A[i,j]` in `A`.
1493
1506
"""
1494
- function _map_notzeropres! {Tf} (f :: Tf , fillvalue, C:: SparseMatrixCSC , A:: SparseMatrixCSC )
1507
+ function _map_notzeropres! (f , fillvalue, C:: SparseMatrixCSC , A:: SparseMatrixCSC )
1495
1508
# Build dense matrix structure in C, expanding storage if necessary
1496
1509
_densestructure! (C)
1497
1510
# Populate values
@@ -2281,14 +2294,13 @@ round{To}(::Type{To}, A::SparseMatrixCSC) = round.(To, A)
2281
2294
# TODO : These seven functions should probably be reimplemented in terms of sparse map
2282
2295
# when a better sparse map exists. (And vectorized min, max, &, |, and xor should be
2283
2296
# deprecated in favor of compact-broadcast syntax.)
2284
- _checksameshape (A, B) = size (A) == size (B) || throw (DimensionMismatch (" size(A) must match size(B)" ))
2285
- (+ )(A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = (_checksameshape (A, B); broadcast (+ , A, B))
2286
- (- )(A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = (_checksameshape (A, B); broadcast (- , A, B))
2287
- min (A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = (_checksameshape (A, B); broadcast (min, A, B))
2288
- max (A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = (_checksameshape (A, B); broadcast (max, A, B))
2289
- (& )(A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = (_checksameshape (A, B); broadcast (& , A, B))
2290
- (| )(A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = (_checksameshape (A, B); broadcast (| , A, B))
2291
- xor (A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = (_checksameshape (A, B); broadcast (xor, A, B))
2297
+ (+ )(A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = broadcast (+ , A, B)
2298
+ (- )(A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = broadcast (- , A, B)
2299
+ min (A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = broadcast (min, A, B)
2300
+ max (A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = broadcast (max, A, B)
2301
+ (& )(A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = broadcast (& , A, B)
2302
+ (| )(A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = broadcast (| , A, B)
2303
+ xor (A:: SparseMatrixCSC , B:: SparseMatrixCSC ) = broadcast (xor, A, B)
2292
2304
2293
2305
(.+ )(A:: SparseMatrixCSC , B:: Number ) = Array (A) .+ B
2294
2306
( + )(A:: SparseMatrixCSC , B:: Array ) = Array (A) + B
0 commit comments