From c1542151c4333386295541b8c53fde7457ea3669 Mon Sep 17 00:00:00 2001 From: Alfredo Braunstein Date: Wed, 2 Jan 2019 11:42:50 +0100 Subject: [PATCH] implements copy!(dst::SparseVector, src) (fixes #30443) (#30531) * implements copy!(dst::SparseVector, src) (fixes #30443) * Adjust error message * more efficient copy! * fix typo * fix return value * add an assert and an explicit return --- stdlib/SparseArrays/src/sparsevector.jl | 31 ++++++++++++++++++------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/stdlib/SparseArrays/src/sparsevector.jl b/stdlib/SparseArrays/src/sparsevector.jl index ecf3c53830b30..ea46ebd213c2d 100644 --- a/stdlib/SparseArrays/src/sparsevector.jl +++ b/stdlib/SparseArrays/src/sparsevector.jl @@ -2,7 +2,7 @@ ### Common definitions -import Base: sort, findall +import Base: sort, findall, copy! import LinearAlgebra: promote_to_array_type, promote_to_arrays_ ### The SparseVector @@ -378,13 +378,11 @@ sparsevec(a::AbstractSparseArray) = vec(a) sparsevec(a::AbstractSparseVector) = vec(a) sparse(a::AbstractVector) = sparsevec(a) -function _dense2sparsevec(s::AbstractArray{Tv}, initcap::Ti) where {Tv,Ti} +function _dense2indval!(nzind::Vector{Ti}, nzval::Vector{Tv}, s::AbstractArray{Tv}) where {Tv,Ti} @assert !has_offset_axes(s) - # pre-condition: initcap > 0; the initcap determines the index type + cap = length(nzind); + @assert cap == length(nzval) n = length(s) - cap = initcap - nzind = Vector{Ti}(undef, cap) - nzval = Vector{Tv}(undef, cap) c = 0 @inbounds for i = 1:n v = s[i] @@ -403,7 +401,12 @@ function _dense2sparsevec(s::AbstractArray{Tv}, initcap::Ti) where {Tv,Ti} resize!(nzind, c) resize!(nzval, c) end - SparseVector(n, nzind, nzval) + return (nzind, nzval) +end + +function _dense2sparsevec(s::AbstractArray{Tv}, initcap::Ti) where {Tv,Ti} + nzind, nzval = _dense2indval!(Vector{Ti}(undef, initcap), Vector{Tv}(undef, initcap), s) + SparseVector(length(s), nzind, nzval) end SparseVector{Tv,Ti}(s::AbstractVector{Tv}) where {Tv,Ti} = @@ -1935,6 +1938,18 @@ julia> dropzeros(A) """ dropzeros(x::SparseVector; trim::Bool = true) = dropzeros!(copy(x), trim = trim) +function copy!(dst::SparseVector, src::SparseVector) + dst.n == src.n || throw(ArgumentError("Sparse vectors should have the same length for copy!")) + copy!(dst.nzval, src.nzval) + copy!(dst.nzind, src.nzind) + return dst +end + +function copy!(dst::SparseVector, src::AbstractVector) + dst.n == length(src) || throw(ArgumentError("Sparse vector should have the same length as source for copy!")) + _dense2indval!(dst.nzind, dst.nzval, src) + return dst +end function _fillnonzero!(arr::SparseMatrixCSC{Tv, Ti}, val) where {Tv,Ti} m, n = size(arr) @@ -2007,7 +2022,7 @@ end function circshift!(O::SparseVector, X::SparseVector, (r,)::Base.DimsInteger{1}) - O .= X + copy!(O, X) subvector_shifter!(O.nzind, O.nzval, 1, length(O.nzind), O.n, mod(r, X.n)) return O end