Skip to content

Commit

Permalink
undeprecate real and imag for sparse matrices (#22090)
Browse files Browse the repository at this point in the history
make sure aliasing is the same as for AbstracArrays for SparseArray{<:Real}
add tests for this
add shortcut for conj(SparseArray{<:Complex} which is faster than broadcasting
(cherry picked from commit 6b0d54e)
  • Loading branch information
fredrikekre authored and tkelman committed Jun 3, 2017
1 parent 50d53bb commit 40ac20b
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 13 deletions.
2 changes: 1 addition & 1 deletion base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ end
# Deprecate vectorized unary functions over sparse matrices in favor of compact broadcast syntax (#17265).
for f in (:sin, :sinh, :sind, :asin, :asinh, :asind,
:tan, :tanh, :tand, :atan, :atanh, :atand,
:sinpi, :cosc, :ceil, :floor, :trunc, :round, :real, :imag,
:sinpi, :cosc, :ceil, :floor, :trunc, :round,
:log1p, :expm1, :abs, :abs2,
:log, :log2, :log10, :exp, :exp2, :exp10, :sinc, :cospi,
:cos, :cosh, :cosd, :acos, :acosd,
Expand Down
4 changes: 4 additions & 0 deletions base/sparse/sparsematrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1444,6 +1444,10 @@ sparse(S::UniformScaling, m::Integer, n::Integer=m) = speye_scaled(S.λ, m, n)
conj!(A::SparseMatrixCSC) = (@inbounds broadcast!(conj, A.nzval, A.nzval); A)
(-)(A::SparseMatrixCSC) = SparseMatrixCSC(A.m, A.n, copy(A.colptr), copy(A.rowval), map(-, A.nzval))

# the rest of real, conj, imag are handled correctly via AbstractArray methods
conj(A::SparseMatrixCSC{<:Complex}) =
SparseMatrixCSC(A.m, A.n, copy(A.colptr), copy(A.rowval), conj(A.nzval))
imag(A::SparseMatrixCSC{Tv,Ti}) where {Tv<:Real,Ti} = spzeros(Tv, Ti, A.m, A.n)

## Binary arithmetic and boolean operators
(+)(A::SparseMatrixCSC, B::SparseMatrixCSC) = map(+, A, B)
Expand Down
5 changes: 2 additions & 3 deletions base/sparse/sparsevector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -985,7 +985,6 @@ hvcat(rows::Tuple{Vararg{Int}}, xs::_TypedDenseConcatGroup{T}...) where {T} = Ba
### Unary Map

# zero-preserving functions (z->z, nz->nz)
conj(x::SparseVector) = SparseVector(length(x), copy(nonzeroinds(x)), conj(nonzeros(x)))
-(x::SparseVector) = SparseVector(length(x), copy(nonzeroinds(x)), -(nonzeros(x)))

# functions f, such that
Expand Down Expand Up @@ -1019,9 +1018,9 @@ macro unarymap_nz2z_z2z(op, TF)
end)
end

real(x::AbstractSparseVector{<:Real}) = x
# the rest of real, conj, imag are handled correctly via AbstractArray methods
@unarymap_nz2z_z2z real Complex

conj(x::SparseVector{<:Complex}) = SparseVector(length(x), copy(nonzeroinds(x)), conj(nonzeros(x)))
imag(x::AbstractSparseVector{Tv,Ti}) where {Tv<:Real,Ti<:Integer} = SparseVector(length(x), Ti[], Tv[])
@unarymap_nz2z_z2z imag Complex

Expand Down
25 changes: 17 additions & 8 deletions test/sparse/sparse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -533,10 +533,12 @@ end
@test tan.(Afull) == Array(tan.(A)) # should be redundant with sin test
@test ceil.(Afull) == Array(ceil.(A))
@test floor.(Afull) == Array(floor.(A)) # should be redundant with ceil test
@test real.(Afull) == Array(real.(A))
@test imag.(Afull) == Array(imag.(A))
@test real.(Cfull) == Array(real.(C))
@test imag.(Cfull) == Array(imag.(C))
@test real.(Afull) == Array(real.(A)) == Array(real(A))
@test imag.(Afull) == Array(imag.(A)) == Array(imag(A))
@test conj.(Afull) == Array(conj.(A)) == Array(conj(A))
@test real.(Cfull) == Array(real.(C)) == Array(real(C))
@test imag.(Cfull) == Array(imag.(C)) == Array(imag(C))
@test conj.(Cfull) == Array(conj.(C)) == Array(conj(C))
# Test representatives of [unary functions that map zeros to zeros and nonzeros to nonzeros]
@test expm1.(Afull) == Array(expm1.(A))
@test abs.(Afull) == Array(abs.(A))
Expand All @@ -554,12 +556,19 @@ end
I = rand(T[1:100;], 2, 2)
D = R + I*im
S = sparse(D)
@test R == real.(S)
@test I == imag.(S)
@test real.(sparse(R)) == R
@test nnz(imag.(sparse(R))) == 0
spR = sparse(R)

@test R == real.(S) == real(S)
@test I == imag.(S) == imag(S)
@test conj(full(S)) == conj.(S) == conj(S)
@test real.(spR) == R
@test nnz(imag.(spR)) == nnz(imag(spR)) == 0
@test abs.(S) == abs.(D)
@test abs2.(S) == abs2.(D)

# test aliasing of real and conj of real valued matrix
@test real(spR) === spR
@test conj(spR) === spR
end
end

Expand Down
4 changes: 3 additions & 1 deletion test/sparse/sparsevector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -637,14 +637,16 @@ let x = spv_x1, x2 = spv_x2
@test exact_equal(complex.(x2, x),
SparseVector(8, [1,2,5,6,7], [3.25+0.0im, 4.0+1.25im, -0.75im, -5.5+3.5im, -6.0+0.0im]))

# real & imag
# real, imag and conj

@test real(x) === x
@test exact_equal(imag(x), spzeros(Float64, length(x)))
@test conj(x) === x

xcp = complex.(x, x2)
@test exact_equal(real(xcp), x)
@test exact_equal(imag(xcp), x2)
@test exact_equal(conj(xcp), complex.(x, -x2))
end

### Zero-preserving math functions: sparse -> sparse
Expand Down

0 comments on commit 40ac20b

Please sign in to comment.