-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Closed
Labels
sparseSparse arraysSparse arrays
Description
In v1.2.0 and v1.5.0 it is easy to create a corrupted sparse object unintentionally:
julia> B = sparse([1 1;0 0]);
julia> A = SparseMatrixCSC{Float64,Int}(B);
julia> A[2,1] = 1
julia> A
2×2 SparseMatrixCSC{Float64,Int64} with 3 stored entries:
[1, 1] = 1.0
[2, 1] = 1.0
[1, 2] = 1.0
julia> B
2×2 SparseMatrixCSC{Int64,Int64} with 3 stored entries:
[1, 1] = 1
[2, 1] = 1
[1, 2] = #undef
julia> b = sparse([1;0]);
julia> a = SparseVector{Float64,Int}(b);
julia> a[2] = 1;
julia> a
2-element SparseVector{Float64,Int64} with 2 stored entries:
[1] = 1.0
[2] = 1.0
julia> b
2-element SparseVector{Int64,Int64} with 1 stored entry:
[1] = 1
[2] = #undef
Reason seems to be that the constructors SparseMatrixCSC{Tv,Ti}(S::SparseMatrixCSC) and SparseVector{Tv,Ti}(s:SparseVector)
may produce objects, which share some but not all of their fields with the source objects.
That is for example the case, if Ti == eltype(S.rowval) and Tv != eltype(S.nzval). That results in inconsistent objects when one of them is modified. For example:
julia> dump(b)
SparseVector{Int64,Int64}
n: Int64 2
nzind: Array{Int64}((2,)) [1, 2]
nzval: Array{Int64}((1,)) [1]
where the sizes of the component vectors of b diverge.
IMO the constructors should be changed to not use convert, but make copies.
The issue surfaced in v1.5 (but not in v1.2) when doing a calculation like follows, where the
corruption of B was rather unexpected:
julia> B = Symmetric(sparse([1 1;0 0]));
julia> B \ ones(2);
ERROR: MethodError: no method matching lu! ...
julia> B
2×2 Symmetric{Int64,SparseMatrixCSC{Int64,Int64}}:
1 #undef
#undef 0
Metadata
Metadata
Assignees
Labels
sparseSparse arraysSparse arrays