Skip to content

Commit 15afb1e

Browse files
committed
Special case sparse matrix copy! for equal lengths.
If length(A) == length(B) in copy!(A, B), all elements in A are replaced, even if size(A) != size(B). This can be done much more efficiently than falling back on copy! for AbstractMatrix, reusing functionality from reshape instead.
1 parent 43c597b commit 15afb1e

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

base/sparse/sparsematrix.jl

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,14 +195,19 @@ copy(S::SparseMatrixCSC) =
195195

196196
function copy!{TvA, TiA, TvB, TiB}(A::SparseMatrixCSC{TvA,TiA},
197197
B::SparseMatrixCSC{TvB,TiB})
198-
# If the two matrices have the same size then all the
199-
# elements in A will be overwritten and we can simply copy the
200-
# internal fields of B to A.
201-
if size(A) == size(B)
202-
copy!(A.colptr, B.colptr)
198+
# If the two matrices have the same length then all the
199+
# elements in A will be overwritten.
200+
if length(A) == length(B)
203201
resize!(A.nzval, length(B.nzval))
204202
resize!(A.rowval, length(B.rowval))
205-
copy!(A.rowval, B.rowval)
203+
if size(A) == size(B)
204+
# Simple case: we can simply copy the internal fields of B to A.
205+
copy!(A.colptr, B.colptr)
206+
copy!(A.rowval, B.rowval)
207+
else
208+
# This is like a "reshape B into A".
209+
sparse_compute_reshaped_colptr_and_rowval(A.colptr, A.rowval, A.m, A.n, B.colptr, B.rowval, B.m, B.n)
210+
end
206211
copy!(A.nzval, B.nzval)
207212
else
208213
invoke(Base.copy!, Tuple{AbstractMatrix{TvA}, AbstractMatrix{TvB}}, A, B)

test/sparsedir/sparse.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ let
253253
@test pointer(A.nzval) != pointer(B.nzval)
254254
@test pointer(A.rowval) != pointer(B.rowval)
255255
@test pointer(A.colptr) != pointer(B.colptr)
256+
# Test size(A) != size(B), but length(A) == length(B)
257+
B = sprand(25, 1, 0.2)
258+
copy!(A, B)
259+
@test A[:] == B[:]
256260
# Test size(A) != size(B)
257261
B = sprand(3, 3, 0.2)
258262
copy!(A, B)

0 commit comments

Comments
 (0)