Skip to content

Commit 57ea2f9

Browse files
committed
Transition vectorized unary functions over SparseMatrixCSCs to compact broadcast syntax, accordingly revise and expand the associated tests, and add deprecations for the vectorized syntax.
1 parent aad8624 commit 57ea2f9

File tree

3 files changed

+64
-38
lines changed

3 files changed

+64
-38
lines changed

base/deprecated.jl

+13
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,19 @@ function symperm{Tv,Ti}(A::SparseMatrixCSC{Tv,Ti}, pinv::Vector{Ti})
788788
"Pkg.add(\"SuiteSparse\") to install SuiteSparse on Julia v0.5."))
789789
end
790790

791+
# Deprecate vectorized unary functions over sparse matrices in favor of compact broadcast syntax
792+
for f in (:sin, :sinh, :sind, :asin, :asinh, :asind,
793+
:tan, :tanh, :tand, :atan, :atanh, :atand,
794+
:sinpi, :cosc, :ceil, :floor, :trunc, :round, :real, :imag,
795+
:log1p, :expm1, :abs, :abs2, :conj,
796+
:log, :log2, :log10, :exp, :exp2, :exp10, :sinc, :cospi,
797+
:cos, :cosh, :cosd, :acos, :acosd,
798+
:cot, :coth, :cotd, :acot, :acotd,
799+
:sec, :sech, :secd, :asech,
800+
:csc, :csch, :cscd, :acsch)
801+
@eval @deprecate $f(A::SparseMatrixCSC) $f.(A)
802+
end
803+
791804
# During the 0.5 development cycle, do not add any deprecations below this line
792805
# To be deprecated in 0.6
793806

base/sparse/sparsematrix.jl

+11-11
Original file line numberDiff line numberDiff line change
@@ -1036,12 +1036,12 @@ end
10361036
"""
10371037
Helper macro for the unary broadcast definitions below. Takes parent method `fp` and a set
10381038
of desired child methods `fcs`, and builds an expression defining each of the child methods
1039-
such that `fc(A::SparseMatrixCSC) = fp(fc, A)`.
1039+
such that `broadcast(::typeof(fc), A::SparseMatrixCSC) = fp(fc, A)`.
10401040
"""
10411041
macro _enumerate_childmethods(fp, fcs...)
10421042
fcexps = Expr(:block)
10431043
for fc in fcs
1044-
push!(fcexps.args, :( $(esc(fc))(A::SparseMatrixCSC) = $(esc(fp))($(esc(fc)), A) ) )
1044+
push!(fcexps.args, :( broadcast(::typeof($(esc(fc))), A::SparseMatrixCSC) = $(esc(fp))($(esc(fc)), A) ) )
10451045
end
10461046
return fcexps
10471047
end
@@ -1080,10 +1080,10 @@ end
10801080
sin, sinh, sind, asin, asinh, asind,
10811081
tan, tanh, tand, atan, atanh, atand,
10821082
sinpi, cosc, ceil, floor, trunc, round)
1083-
real(A::SparseMatrixCSC) = copy(A)
1084-
imag{Tv,Ti}(A::SparseMatrixCSC{Tv,Ti}) = spzeros(Tv, Ti, A.m, A.n)
1085-
real{TTv}(A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2z_z2z_T(real, A, TTv)
1086-
imag{TTv}(A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2z_z2z_T(imag, A, TTv)
1083+
broadcast(::typeof(real), A::SparseMatrixCSC) = copy(A)
1084+
broadcast{Tv,Ti}(::typeof(imag), A::SparseMatrixCSC{Tv,Ti}) = spzeros(Tv, Ti, A.m, A.n)
1085+
broadcast{TTv}(::typeof(real), A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2z_z2z_T(real, A, TTv)
1086+
broadcast{TTv}(::typeof(imag), A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2z_z2z_T(imag, A, TTv)
10871087
ceil{To}(::Type{To}, A::SparseMatrixCSC) = _broadcast_unary_nz2z_z2z_T(ceil, A, To)
10881088
floor{To}(::Type{To}, A::SparseMatrixCSC) = _broadcast_unary_nz2z_z2z_T(floor, A, To)
10891089
trunc{To}(::Type{To}, A::SparseMatrixCSC) = _broadcast_unary_nz2z_z2z_T(trunc, A, To)
@@ -1110,10 +1110,10 @@ function _broadcast_unary_nz2nz_z2z{Tv}(f::Function, A::SparseMatrixCSC{Tv})
11101110
end
11111111
@_enumerate_childmethods(_broadcast_unary_nz2nz_z2z,
11121112
log1p, expm1, abs, abs2, conj)
1113-
abs2{TTv}(A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2nz_z2z_T(abs2, A, TTv)
1114-
abs{TTv}(A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2nz_z2z_T(abs, A, TTv)
1115-
abs{TTv<:Integer}(A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2nz_z2z_T(abs, A, Float64)
1116-
abs{TTv<:BigInt}(A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2nz_z2z_T(abs, A, BigFloat)
1113+
broadcast{TTv}(::typeof(abs2), A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2nz_z2z_T(abs2, A, TTv)
1114+
broadcast{TTv}(::typeof(abs), A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2nz_z2z_T(abs, A, TTv)
1115+
broadcast{TTv<:Integer}(::typeof(abs), A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2nz_z2z_T(abs, A, Float64)
1116+
broadcast{TTv<:BigInt}(::typeof(abs), A::SparseMatrixCSC{Complex{TTv}}) = _broadcast_unary_nz2nz_z2z_T(abs, A, BigFloat)
11171117
function conj!(A::SparseMatrixCSC)
11181118
@inbounds @simd for k in 1:nnz(A)
11191119
A.nzval[k] = conj(A.nzval[k])
@@ -1450,7 +1450,7 @@ end # macro
14501450
(.^)(A::SparseMatrixCSC, B::Number) =
14511451
B==0 ? sparse(ones(typeof(one(eltype(A)).^B), A.m, A.n)) :
14521452
SparseMatrixCSC(A.m, A.n, copy(A.colptr), copy(A.rowval), A.nzval .^ B)
1453-
(.^)(::Irrational{:e}, B::SparseMatrixCSC) = exp(B)
1453+
(.^)(::Irrational{:e}, B::SparseMatrixCSC) = exp.(B)
14541454
(.^)(A::Number, B::SparseMatrixCSC) = (.^)(A, full(B))
14551455
(.^)(A::SparseMatrixCSC, B::Array) = (.^)(full(A), B)
14561456
(.^)(A::Array, B::SparseMatrixCSC) = (.^)(A, full(B))

test/sparsedir/sparse.jl

+40-27
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ end
286286

287287
# conj
288288
cA = sprandn(5,5,0.2) + im*sprandn(5,5,0.2)
289-
@test full(conj(cA)) == conj(full(cA))
289+
@test full(conj.(cA)) == conj(full(cA))
290290

291291
# transpose of SubArrays
292292
A = view(sprandn(10, 10, 0.3), 1:4, 1:4)
@@ -402,22 +402,47 @@ end
402402
@test maximum(sparse(-ones(3,3))) == -1
403403
@test minimum(sparse(ones(3,3))) == 1
404404

405-
# Unary functions
406-
a = sprand(5,15, 0.5)
407-
afull = full(a)
408-
for op in (:sin, :cos, :tan, :ceil, :floor, :abs, :abs2)
409-
@eval begin
410-
@test ($op)(afull) == full($(op)(a))
411-
end
412-
end
413-
414-
for op in (:ceil, :floor)
415-
@eval begin
416-
@test ($op)(Int,afull) == full($(op)(Int,a))
405+
# Test unary functions with specialized broadcast over SparseMatrixCSCs
406+
let
407+
A = sprand(5, 15, 0.5)
408+
C = A + im*A
409+
Afull = full(A)
410+
Cfull = full(C)
411+
# Test representatives of [unary functions that map zeros to zeros and may map nonzeros to zeros]
412+
@test sin.(Afull) == full(sin.(A))
413+
@test tan.(Afull) == full(tan.(A)) # should be redundant with sin test
414+
@test ceil.(Afull) == full(ceil.(A))
415+
@test floor.(Afull) == full(floor.(A)) # should be redundant with ceil test
416+
@test real.(Afull) == full(real.(A))
417+
@test imag.(Afull) == full(imag.(A))
418+
@test real.(Cfull) == full(real.(C))
419+
@test imag.(Cfull) == full(imag.(C))
420+
# Test representatives of [unary functions that map zeros to zeros and nonzeros to nonzeros]
421+
@test expm1.(Afull) == full(expm1.(A))
422+
@test abs.(Afull) == full(abs.(A))
423+
@test abs2.(Afull) == full(abs2.(A))
424+
@test abs.(Cfull) == full(abs.(C))
425+
@test abs2.(Cfull) == full(abs2.(C))
426+
# Test representatives of [unary functions that map both zeros and nonzeros to nonzeros]
427+
@test cos.(Afull) == full(cos.(A))
428+
# Test representatives of remaining vectorized-nonbroadcast unary functions
429+
@test ceil(Int, Afull) == full(ceil(Int, A))
430+
@test floor(Int, Afull) == full(floor(Int, A))
431+
# Tests of real, imag, abs, and abs2 for SparseMatrixCSC{Int,X}s previously elsewhere
432+
for T in (Int, Float16, Float32, Float64, BigInt, BigFloat)
433+
R = rand(T[1:100;], 2, 2)
434+
I = rand(T[1:100;], 2, 2)
435+
D = R + I*im
436+
S = sparse(D)
437+
@test R == real.(S)
438+
@test I == imag.(S)
439+
@test real.(sparse(R)) == R
440+
@test nnz(imag.(sparse(R))) == 0
441+
@test abs.(S) == abs(D)
442+
@test abs2.(S) == abs2(D)
417443
end
418444
end
419445

420-
421446
# getindex tests
422447
ni = 23
423448
nj = 32
@@ -696,7 +721,7 @@ end
696721
@test_throws ArgumentError sparsevec(Dict(-1=>1,1=>2))
697722

698723
# issue #8976
699-
@test conj(sparse([1im])) == sparse(conj([1im]))
724+
@test conj.(sparse([1im])) == sparse(conj([1im]))
700725
@test conj!(sparse([1im])) == sparse(conj!([1im]))
701726

702727
# issue #9525
@@ -862,18 +887,6 @@ end
862887
x = speye(100)
863888
@test_throws BoundsError x[-10:10]
864889

865-
for T in (Int, Float16, Float32, Float64, BigInt, BigFloat)
866-
let R=rand(T[1:100;],2,2), I=rand(T[1:100;],2,2)
867-
D = R + I*im
868-
S = sparse(D)
869-
@test R == real(S)
870-
@test I == imag(S)
871-
@test real(sparse(R)) == R
872-
@test nnz(imag(sparse(R))) == 0
873-
@test abs(S) == abs(D)
874-
@test abs2(S) == abs2(D)
875-
end
876-
end
877890

878891
# issue #10407
879892
@test maximum(spzeros(5, 5)) == 0.0

0 commit comments

Comments
 (0)