mollusk 0e4acfb8f2 fix incorrect folder name for julia-0.6.x
Former-commit-id: ef2c7401e0876f22d2f7762d182cfbcd5a7d9c70
2018-06-11 03:28:36 -07:00

1156 lines
36 KiB
Julia
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# This file is a part of Julia. License is MIT: https://julialang.org/license
### Data
spv_x1 = SparseVector(8, [2, 5, 6], [1.25, -0.75, 3.5])
@test isa(spv_x1, SparseVector{Float64,Int})
x1_full = zeros(length(spv_x1))
x1_full[SparseArrays.nonzeroinds(spv_x1)] = nonzeros(spv_x1)
### Basic Properties
let x = spv_x1
@test eltype(x) == Float64
@test ndims(x) == 1
@test length(x) == 8
@test size(x) == (8,)
@test size(x,1) == 8
@test size(x,2) == 1
@test !isempty(x)
@test countnz(x) == 3
@test nnz(x) == 3
@test SparseArrays.nonzeroinds(x) == [2, 5, 6]
@test nonzeros(x) == [1.25, -0.75, 3.5]
end
@test count(SparseVector(8, [2, 5, 6], [true,false,true])) == 2
# full
for (x, xf) in [(spv_x1, x1_full)]
@test isa(Array(x), Vector{Float64})
@test Array(x) == xf
end
### Show
@test contains(string(spv_x1), "1.25")
@test contains(string(spv_x1), "-0.75")
@test contains(string(spv_x1), "3.5")
### Other Constructors
### Comparison helper to ensure exact equality with internal structure
function exact_equal(x::AbstractSparseVector, y::AbstractSparseVector)
eltype(x) == eltype(y) &&
eltype(SparseArrays.nonzeroinds(x)) == eltype(SparseArrays.nonzeroinds(y)) &&
length(x) == length(y) &&
SparseArrays.nonzeroinds(x) == SparseArrays.nonzeroinds(y) &&
nonzeros(x) == nonzeros(y)
end
# construct empty sparse vector
@test exact_equal(spzeros(Float64, 8), SparseVector(8, Int[], Float64[]))
# from list of indices and values
@test exact_equal(
sparsevec(Int[], Float64[], 8),
SparseVector(8, Int[], Float64[]))
@test exact_equal(
sparsevec(Int[], Float64[]),
SparseVector(0, Int[], Float64[]))
@test exact_equal(
sparsevec([3, 3], [5.0, -5.0], 8),
SparseVector(8, [3], [0.0]))
@test exact_equal(
sparsevec([2, 3, 6], [12.0, 18.0, 25.0]),
SparseVector(6, [2, 3, 6], [12.0, 18.0, 25.0]))
let x0 = SparseVector(8, [2, 3, 6], [12.0, 18.0, 25.0])
@test exact_equal(
sparsevec([2, 3, 6], [12.0, 18.0, 25.0], 8), x0)
@test exact_equal(
sparsevec([3, 6, 2], [18.0, 25.0, 12.0], 8), x0)
@test exact_equal(
sparsevec([2, 3, 4, 4, 6], [12.0, 18.0, 5.0, -5.0, 25.0], 8),
SparseVector(8, [2, 3, 4, 6], [12.0, 18.0, 0.0, 25.0]))
@test exact_equal(
sparsevec([1, 1, 1, 2, 3, 3, 6], [2.0, 3.0, -5.0, 12.0, 10.0, 8.0, 25.0], 8),
SparseVector(8, [1, 2, 3, 6], [0.0, 12.0, 18.0, 25.0]))
@test exact_equal(
sparsevec([2, 3, 6, 7, 7], [12.0, 18.0, 25.0, 5.0, -5.0], 8),
SparseVector(8, [2, 3, 6, 7], [12.0, 18.0, 25.0, 0.0]))
end
@test exact_equal(
sparsevec(Any[1, 3], [1, 1]),
sparsevec([1, 3], [1, 1]))
@test exact_equal(
sparsevec(Any[1, 3], [1, 1], 5),
sparsevec([1, 3], [1, 1], 5))
# from dictionary
function my_intmap(x)
a = Dict{Int,eltype(x)}()
for i in SparseArrays.nonzeroinds(x)
a[i] = x[i]
end
return a
end
let x = spv_x1
a = my_intmap(x)
xc = sparsevec(a, 8)
@test exact_equal(x, xc)
xc = sparsevec(a)
@test exact_equal(xc, SparseVector(6, [2, 5, 6], [1.25, -0.75, 3.5]))
d = Dict{Int, Float64}((1 => 0.0, 2 => 1.0, 3 => 2.0))
@test exact_equal(sparsevec(d), SparseVector(3, [1, 2, 3], [0.0, 1.0, 2.0]))
end
# spones - copies structure, but replaces nzvals with ones
let x = SparseVector(8, [2, 3, 6], [12.0, 18.0, 25.0])
y = spones(x)
@test (x .!= 0) == (y .!= 0)
@test y == SparseVector(8, [2, 3, 6], [1.0, 1.0, 1.0])
end
# sprand & sprandn
let xr = sprand(1000, 0.9)
@test isa(xr, SparseVector{Float64,Int})
@test length(xr) == 1000
@test all(nonzeros(xr) .>= 0.0)
end
let xr = sprand(Float32, 1000, 0.9)
@test isa(xr, SparseVector{Float32,Int})
@test length(xr) == 1000
@test all(nonzeros(xr) .>= 0.0)
end
let xr = sprandn(1000, 0.9)
@test isa(xr, SparseVector{Float64,Int})
@test length(xr) == 1000
if !isempty(nonzeros(xr))
@test any(nonzeros(xr) .> 0.0) && any(nonzeros(xr) .< 0.0)
end
end
let xr = sprand(Bool, 1000, 0.9)
@test isa(xr, SparseVector{Bool,Int})
@test length(xr) == 1000
@test all(nonzeros(xr))
end
let r1 = MersenneTwister(0), r2 = MersenneTwister(0)
@test sprand(r1, 100, .9) == sprand(r2, 100, .9)
@test sprandn(r1, 100, .9) == sprandn(r2, 100, .9)
@test sprand(r1, Bool, 100, .9) == sprand(r2, Bool, 100, .9)
end
### Element access
# getindex
# single integer index
for (x, xf) in [(spv_x1, x1_full)]
for i = 1:length(x)
@test x[i] == xf[i]
end
end
# generic array index
let x = sprand(100, 0.5)
I = rand(1:length(x), 20)
r = x[I]
@test isa(r, SparseVector{Float64,Int})
@test all(nonzeros(r) .!= 0.0)
@test Array(r) == Array(x)[I]
end
# boolean array index
let x = sprand(10, 10, 0.5)
I = rand(1:size(x, 2), 10)
bI = falses(size(x, 2))
bI[I] = true
r = x[1,bI]
@test isa(r, SparseVector{Float64,Int})
@test all(nonzeros(r) .!= 0.0)
@test Array(r) == Array(x)[1,bI]
end
let x = sprand(10, 0.5)
I = rand(1:length(x), 5)
bI = falses(length(x))
bI[I] = true
r = x[bI]
@test isa(r, SparseVector{Float64,Int})
@test all(nonzeros(r) .!= 0.0)
@test Array(r) == Array(x)[bI]
end
# setindex
let xc = spzeros(Float64, 8)
xc[3] = 2.0
@test exact_equal(xc, SparseVector(8, [3], [2.0]))
end
let xc = copy(spv_x1)
xc[5] = 2.0
@test exact_equal(xc, SparseVector(8, [2, 5, 6], [1.25, 2.0, 3.5]))
end
let xc = copy(spv_x1)
xc[3] = 4.0
@test exact_equal(xc, SparseVector(8, [2, 3, 5, 6], [1.25, 4.0, -0.75, 3.5]))
xc[1] = 6.0
@test exact_equal(xc, SparseVector(8, [1, 2, 3, 5, 6], [6.0, 1.25, 4.0, -0.75, 3.5]))
xc[8] = -1.5
@test exact_equal(xc, SparseVector(8, [1, 2, 3, 5, 6, 8], [6.0, 1.25, 4.0, -0.75, 3.5, -1.5]))
end
let xc = copy(spv_x1)
xc[5] = 0.0
@test exact_equal(xc, SparseVector(8, [2, 5, 6], [1.25, 0.0, 3.5]))
xc[6] = 0.0
@test exact_equal(xc, SparseVector(8, [2, 5, 6], [1.25, 0.0, 0.0]))
xc[2] = 0.0
@test exact_equal(xc, SparseVector(8, [2, 5, 6], [0.0, 0.0, 0.0]))
xc[1] = 0.0
@test exact_equal(xc, SparseVector(8, [2, 5, 6], [0.0, 0.0, 0.0]))
end
## dropstored! tests
let x = SparseVector(10, [2, 7, 9], [2.0, 7.0, 9.0])
# Test argument bounds checking for dropstored!(x, i)
@test_throws BoundsError Base.SparseArrays.dropstored!(x, 0)
@test_throws BoundsError Base.SparseArrays.dropstored!(x, 11)
# Test behavior of dropstored!(x, i)
# --> Test dropping a single stored entry
@test Base.SparseArrays.dropstored!(x, 2) == SparseVector(10, [7, 9], [7.0, 9.0])
# --> Test dropping a single nonstored entry
@test Base.SparseArrays.dropstored!(x, 5) == SparseVector(10, [7, 9], [7.0, 9.0])
end
# find and findnz tests
@test find(spv_x1) == find(x1_full)
@test findnz(spv_x1) == (find(x1_full), filter(x->x!=0, x1_full))
let xc = SparseVector(8, [2, 3, 5], [1.25, 0, -0.75]), fc = Array(xc)
@test find(xc) == find(fc)
@test findnz(xc) == ([2, 5], [1.25, -0.75])
end
### Array manipulation
# copy
let x = spv_x1
xc = copy(x)
@test isa(xc, SparseVector{Float64,Int})
@test x.nzind !== xc.nzval
@test x.nzval !== xc.nzval
@test exact_equal(x, xc)
end
let a = SparseVector(8, [2, 5, 6], Int32[12, 35, 72])
# vec
@test vec(a) == a
# reinterpret
au = reinterpret(UInt32, a)
@test isa(au, SparseVector{UInt32,Int})
@test exact_equal(au, SparseVector(8, [2, 5, 6], UInt32[12, 35, 72]))
# float
af = float(a)
@test float(af) == af
@test isa(af, SparseVector{Float64,Int})
@test exact_equal(af, SparseVector(8, [2, 5, 6], [12., 35., 72.]))
@test sparsevec(transpose(transpose(af))) == af
# complex
acp = complex(af)
@test complex(acp) == acp
@test isa(acp, SparseVector{Complex128,Int})
@test exact_equal(acp, SparseVector(8, [2, 5, 6], complex([12., 35., 72.])))
@test sparsevec(ctranspose(ctranspose(acp))) == acp
end
let x1 = SparseVector(8, [2, 5, 6], [12.2, 1.4, 5.0])
x2 = SparseVector(8, [3, 4], [1.2, 3.4])
copy!(x2, x1)
@test x2 == x1
x2 = SparseVector(8, [2, 4, 8], [10.3, 7.4, 3.1])
copy!(x2, x1)
@test x2 == x1
x2 = SparseVector(8, [1, 3, 4, 7], [0.3, 1.2, 3.4, 0.1])
copy!(x2, x1)
@test x2 == x1
x2 = SparseVector(10, [3, 4], [1.2, 3.4])
copy!(x2, x1)
@test x2[1:8] == x1
@test x2[9:10] == spzeros(2)
x2 = SparseVector(10, [3, 4, 9], [1.2, 3.4, 17.8])
copy!(x2, x1)
@test x2[1:8] == x1
@test x2[9] == 17.8
@test x2[10] == 0
x2 = SparseVector(10, [3, 4, 5, 6, 9], [8.3, 7.2, 1.2, 3.4, 17.8])
copy!(x2, x1)
@test x2[1:8] == x1
@test x2[9] == 17.8
@test x2[10] == 0
x2 = SparseVector(6, [3, 4], [1.2, 3.4])
@test_throws BoundsError copy!(x2, x1)
end
let x1 = sparse([2, 1, 2], [1, 3, 3], [12.2, 1.4, 5.0], 2, 4)
x2 = SparseVector(8, [3, 4], [1.2, 3.4])
copy!(x2, x1)
@test x2[:] == x1[:]
x2 = SparseVector(8, [2, 4, 8], [10.3, 7.4, 3.1])
copy!(x2, x1)
@test x2[:] == x1[:]
x2 = SparseVector(8, [1, 3, 4, 7], [0.3, 1.2, 3.4, 0.1])
copy!(x2, x1)
@test x2[:] == x1[:]
x2 = SparseVector(10, [3, 4], [1.2, 3.4])
copy!(x2, x1)
@test x2[1:8] == x1[:]
@test x2[9:10] == spzeros(2)
x2 = SparseVector(10, [3, 4, 9], [1.2, 3.4, 17.8])
copy!(x2, x1)
@test x2[1:8] == x1[:]
@test x2[9] == 17.8
@test x2[10] == 0
x2 = SparseVector(10, [3, 4, 5, 6, 9], [8.3, 7.2, 1.2, 3.4, 17.8])
copy!(x2, x1)
@test x2[1:8] == x1[:]
@test x2[9] == 17.8
@test x2[10] == 0
x2 = SparseVector(6, [3, 4], [1.2, 3.4])
@test_throws BoundsError copy!(x2, x1)
end
let x1 = SparseVector(8, [2, 5, 6], [12.2, 1.4, 5.0])
x2 = sparse([1, 2], [2, 2], [1.2, 3.4], 2, 4)
copy!(x2, x1)
@test x2[:] == x1[:]
x2 = sparse([2, 2, 2], [1, 3, 4], [10.3, 7.4, 3.1], 2, 4)
copy!(x2, x1)
@test x2[:] == x1[:]
x2 = sparse([1, 1, 2, 1], [1, 2, 2, 4], [0.3, 1.2, 3.4, 0.1], 2, 4)
copy!(x2, x1)
@test x2[:] == x1[:]
x2 = sparse([1, 2], [2, 2], [1.2, 3.4], 2, 5)
copy!(x2, x1)
@test x2[1:8] == x1
@test x2[9:10] == spzeros(2)
x2 = sparse([1, 2, 1], [2, 2, 5], [1.2, 3.4, 17.8], 2, 5)
copy!(x2, x1)
@test x2[1:8] == x1
@test x2[9] == 17.8
@test x2[10] == 0
x2 = sparse([1, 2, 1, 2, 1], [2, 2, 3, 3, 5], [8.3, 7.2, 1.2, 3.4, 17.8], 2, 5)
copy!(x2, x1)
@test x2[1:8] == x1
@test x2[9] == 17.8
@test x2[10] == 0
x2 = sparse([1, 2], [2, 2], [1.2, 3.4], 2, 3)
@test_throws BoundsError copy!(x2, x1)
end
### Type conversion
let x = convert(SparseVector, sparse([2, 5, 6], [1, 1, 1], [1.25, -0.75, 3.5], 8, 1))
@test isa(x, SparseVector{Float64,Int})
@test exact_equal(x, spv_x1)
end
let x = spv_x1, xf = x1_full
xc = convert(SparseVector, xf)
@test isa(xc, SparseVector{Float64,Int})
@test exact_equal(xc, x)
xc = convert(SparseVector{Float32,Int}, x)
xf32 = SparseVector(8, [2, 5, 6], [1.25f0, -0.75f0, 3.5f0])
@test isa(xc, SparseVector{Float32,Int})
@test exact_equal(xc, xf32)
xc = convert(SparseVector{Float32}, x)
@test isa(xc, SparseVector{Float32,Int})
@test exact_equal(xc, xf32)
xm = convert(SparseMatrixCSC, x)
@test isa(xm, SparseMatrixCSC{Float64,Int})
@test Array(xm) == reshape(xf, 8, 1)
xm = convert(SparseMatrixCSC{Float32}, x)
@test isa(xm, SparseMatrixCSC{Float32,Int})
@test Array(xm) == reshape(convert(Vector{Float32}, xf), 8, 1)
end
### Concatenation
let m = 80, n = 100
A = Array{SparseVector{Float64,Int}}(n)
tnnz = 0
for i = 1:length(A)
A[i] = sprand(m, 0.3)
tnnz += nnz(A[i])
end
H = hcat(A...)
@test isa(H, SparseMatrixCSC{Float64,Int})
@test size(H) == (m, n)
@test nnz(H) == tnnz
Hr = zeros(m, n)
for j = 1:n
Hr[:,j] = Array(A[j])
end
@test Array(H) == Hr
V = vcat(A...)
@test isa(V, SparseVector{Float64,Int})
@test length(V) == m * n
Vr = vec(Hr)
@test Array(V) == Vr
end
# Test that concatenations of combinations of sparse vectors with various other
# matrix/vector types yield sparse arrays
let N = 4
spvec = spzeros(N)
spmat = spzeros(N, 1)
densevec = ones(N)
densemat = ones(N, 1)
diagmat = Diagonal(ones(4))
# Test that concatenations of pairwise combinations of sparse vectors with dense
# vectors/matrices, sparse matrices, or special matrices yield sparse arrays
for othervecormat in (densevec, densemat, spmat)
@test issparse(vcat(spvec, othervecormat))
@test issparse(vcat(othervecormat, spvec))
end
for othervecormat in (densevec, densemat, spmat, diagmat)
@test issparse(hcat(spvec, othervecormat))
@test issparse(hcat(othervecormat, spvec))
@test issparse(hvcat((2,), spvec, othervecormat))
@test issparse(hvcat((2,), othervecormat, spvec))
@test issparse(cat((1,2), spvec, othervecormat))
@test issparse(cat((1,2), othervecormat, spvec))
end
# The preceding tests should cover multi-way combinations of those types, but for good
# measure test a few multi-way combinations involving those types
@test issparse(vcat(spvec, densevec, spmat, densemat))
@test issparse(vcat(densevec, spvec, densemat, spmat))
@test issparse(hcat(spvec, densemat, spmat, densevec, diagmat))
@test issparse(hcat(densemat, spmat, spvec, densevec, diagmat))
@test issparse(hvcat((5,), diagmat, densevec, spvec, densemat, spmat))
@test issparse(hvcat((5,), spvec, densemat, diagmat, densevec, spmat))
@test issparse(cat((1,2), densemat, diagmat, spmat, densevec, spvec))
@test issparse(cat((1,2), spvec, diagmat, densevec, spmat, densemat))
end
@testset "vertical concatenation of SparseVectors with different el- and ind-type (#22225)" begin
spv6464 = SparseVector(0, Int64[], Int64[])
@test isa(vcat(spv6464, SparseVector(0, Int64[], Int32[])), SparseVector{Int64,Int64})
@test isa(vcat(spv6464, SparseVector(0, Int32[], Int64[])), SparseVector{Int64,Int64})
@test isa(vcat(spv6464, SparseVector(0, Int32[], Int32[])), SparseVector{Int64,Int64})
end
## sparsemat: combinations with sparse matrix
let S = sprand(4, 8, 0.5)
Sf = Array(S)
@assert isa(Sf, Matrix{Float64})
# get a single column
for j = 1:size(S,2)
col = S[:, j]
@test isa(col, SparseVector{Float64,Int})
@test length(col) == size(S,1)
@test Array(col) == Sf[:,j]
end
# Get a reshaped vector
v = S[:]
@test isa(v, SparseVector{Float64,Int})
@test length(v) == length(S)
@test Array(v) == Sf[:]
# Get a linear subset
for i=0:length(S)
v = S[1:i]
@test isa(v, SparseVector{Float64,Int})
@test length(v) == i
@test Array(v) == Sf[1:i]
end
for i=1:length(S)+1
v = S[i:end]
@test isa(v, SparseVector{Float64,Int})
@test length(v) == length(S) - i + 1
@test Array(v) == Sf[i:end]
end
for i=0:div(length(S),2)
v = S[1+i:end-i]
@test isa(v, SparseVector{Float64,Int})
@test length(v) == length(S) - 2i
@test Array(v) == Sf[1+i:end-i]
end
end
let r = [1,10], S = sparse(r, r, r)
Sf = Array(S)
@assert isa(Sf, Matrix{Int})
inds = [1,1,1,1,1,1]
v = S[inds]
@test isa(v, SparseVector{Int,Int})
@test length(v) == length(inds)
@test Array(v) == Sf[inds]
inds = [2,2,2,2,2,2]
v = S[inds]
@test isa(v, SparseVector{Int,Int})
@test length(v) == length(inds)
@test Array(v) == Sf[inds]
# get a single column
for j = 1:size(S,2)
col = S[:, j]
@test isa(col, SparseVector{Int,Int})
@test length(col) == size(S,1)
@test Array(col) == Sf[:,j]
end
# Get a reshaped vector
v = S[:]
@test isa(v, SparseVector{Int,Int})
@test length(v) == length(S)
@test Array(v) == Sf[:]
# Get a linear subset
for i=0:length(S)
v = S[1:i]
@test isa(v, SparseVector{Int,Int})
@test length(v) == i
@test Array(v) == Sf[1:i]
end
for i=1:length(S)+1
v = S[i:end]
@test isa(v, SparseVector{Int,Int})
@test length(v) == length(S) - i + 1
@test Array(v) == Sf[i:end]
end
for i=0:div(length(S),2)
v = S[1+i:end-i]
@test isa(v, SparseVector{Int,Int})
@test length(v) == length(S) - 2i
@test Array(v) == Sf[1+i:end-i]
end
end
## math
### Data
rnd_x0 = sprand(50, 0.6)
rnd_x0f = Array(rnd_x0)
rnd_x1 = sprand(50, 0.7) * 4.0
rnd_x1f = Array(rnd_x1)
spv_x1 = SparseVector(8, [2, 5, 6], [1.25, -0.75, 3.5])
spv_x2 = SparseVector(8, [1, 2, 6, 7], [3.25, 4.0, -5.5, -6.0])
### Arithmetic operations
let x = spv_x1, x2 = spv_x2
# negate
@test exact_equal(-x, SparseVector(8, [2, 5, 6], [-1.25, 0.75, -3.5]))
# abs and abs2
@test exact_equal(abs.(x), SparseVector(8, [2, 5, 6], abs.([1.25, -0.75, 3.5])))
@test exact_equal(abs2.(x), SparseVector(8, [2, 5, 6], abs2.([1.25, -0.75, 3.5])))
# plus and minus
xa = SparseVector(8, [1,2,5,6,7], [3.25,5.25,-0.75,-2.0,-6.0])
@test exact_equal(x + x, x * 2)
@test exact_equal(x + x2, xa)
@test exact_equal(x2 + x, xa)
xb = SparseVector(8, [1,2,5,6,7], [-3.25,-2.75,-0.75,9.0,6.0])
@test exact_equal(x - x, SparseVector(8, Int[], Float64[]))
@test exact_equal(x - x2, xb)
@test exact_equal(x2 - x, -xb)
@test Array(x) + x2 == Array(xa)
@test Array(x) - x2 == Array(xb)
@test x + Array(x2) == Array(xa)
@test x - Array(x2) == Array(xb)
# multiplies
xm = SparseVector(8, [2, 6], [5.0, -19.25])
@test exact_equal(x .* x, abs2.(x))
@test exact_equal(x .* x2, xm)
@test exact_equal(x2 .* x, xm)
@test Array(x) .* x2 == Array(xm)
@test x .* Array(x2) == Array(xm)
# max & min
@test exact_equal(max.(x, x), x)
@test exact_equal(min.(x, x), x)
@test exact_equal(max.(x, x2),
SparseVector(8, Int[1, 2, 6], Float64[3.25, 4.0, 3.5]))
@test exact_equal(min.(x, x2),
SparseVector(8, Int[2, 5, 6, 7], Float64[1.25, -0.75, -5.5, -6.0]))
end
### Complex
let x = spv_x1, x2 = spv_x2
# complex
@test exact_equal(complex.(x, x),
SparseVector(8, [2,5,6], [1.25+1.25im, -0.75-0.75im, 3.5+3.5im]))
@test exact_equal(complex.(x, x2),
SparseVector(8, [1,2,5,6,7], [3.25im, 1.25+4.0im, -0.75+0.0im, 3.5-5.5im, -6.0im]))
@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 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
function check_nz2z_z2z{T}(f::Function, x::SparseVector{T}, xf::Vector{T})
R = typeof(f(zero(T)))
r = f(x)
isa(r, AbstractSparseVector) || error("$f(x) is not a sparse vector.")
eltype(r) == R || error("$f(x) results in eltype = $(eltype(r)), expect $R")
all(r.nzval .!= 0) || error("$f(x) contains zeros in nzval.")
Array(r) == f.(xf) || error("Incorrect results found in $f(x).")
end
for f in [floor, ceil, trunc, round]
check_nz2z_z2z(f, rnd_x1, rnd_x1f)
end
for f in [log1p, expm1,
sin, tan, sinpi, sind, tand,
asin, atan, asind, atand,
sinh, tanh, asinh, atanh]
check_nz2z_z2z(f, rnd_x0, rnd_x0f)
end
### Non-zero-preserving math functions: sparse -> dense
function check_z2nz{T}(f::Function, x::SparseVector{T}, xf::Vector{T})
R = typeof(f(zero(T)))
r = f(x)
isa(r, Vector) || error("$f(x) is not a dense vector.")
eltype(r) == R || error("$f(x) results in eltype = $(eltype(r)), expect $R")
r == f.(xf) || error("Incorrect results found in $f(x).")
end
for f in [exp, exp2, exp10, log, log2, log10,
cos, csc, cot, sec, cospi,
cosd, cscd, cotd, secd,
acos, acot, acosd, acotd,
cosh, csch, coth, sech, acsch, asech]
check_z2nz(f, rnd_x0, rnd_x0f)
end
### Reduction
# sum, vecnorm
let x = spv_x1
@test sum(x) == 4.0
@test sum(abs, x) == 5.5
@test sum(abs2, x) == 14.375
@test vecnorm(x) == sqrt(14.375)
@test vecnorm(x, 1) == 5.5
@test vecnorm(x, 2) == sqrt(14.375)
@test vecnorm(x, Inf) == 3.5
end
# maximum, minimum
let x = spv_x1
@test maximum(x) == 3.5
@test minimum(x) == -0.75
@test maximum(abs, x) == 3.5
@test minimum(abs, x) == 0.0
end
let x = abs.(spv_x1)
@test maximum(x) == 3.5
@test minimum(x) == 0.0
end
let x = -abs.(spv_x1)
@test maximum(x) == 0.0
@test minimum(x) == -3.5
end
let x = SparseVector(3, [1, 2, 3], [-4.5, 2.5, 3.5])
@test maximum(x) == 3.5
@test minimum(x) == -4.5
@test maximum(abs, x) == 4.5
@test minimum(abs, x) == 2.5
end
let x = spzeros(Float64, 8)
@test maximum(x) == 0.0
@test minimum(x) == 0.0
@test maximum(abs, x) == 0.0
@test minimum(abs, x) == 0.0
end
### linalg
### BLAS Level-1
let x = sprand(16, 0.5), x2 = sprand(16, 0.4)
xf = Array(x)
xf2 = Array(x2)
# axpy!
for c in [1.0, -1.0, 2.0, -2.0]
y = Array(x)
@test Base.axpy!(c, x2, y) === y
@test y == Array(x2 * c + x)
end
# scale
let α = 2.5, sx = SparseVector(x.n, x.nzind, x.nzval * α)
@test exact_equal(x * α, sx)
@test exact_equal(x * (α + 0.0*im), complex(sx))
@test exact_equal(α * x, sx)
@test exact_equal((α + 0.0*im) * x, complex(sx))
@test exact_equal(x * α, sx)
@test exact_equal(α * x, sx)
@test exact_equal(x .* α, sx)
@test exact_equal(α .* x, sx)
@test exact_equal(x / α, SparseVector(x.n, x.nzind, x.nzval / α))
xc = copy(x)
@test scale!(xc, α) === xc
@test exact_equal(xc, sx)
xc = copy(x)
@test scale!(α, xc) === xc
@test exact_equal(xc, sx)
xc = copy(x)
@test scale!(xc, complex(α, 0.0)) === xc
@test exact_equal(xc, sx)
xc = copy(x)
@test scale!(complex(α, 0.0), xc) === xc
@test exact_equal(xc, sx)
end
# dot
let dv = dot(xf, xf2)
@test dot(x, x) == sum(abs2, x)
@test dot(x2, x2) == sum(abs2, x2)
@test dot(x, x2) dv
@test dot(x2, x) dv
@test dot(Array(x), x2) dv
@test dot(x, Array(x2)) dv
end
end
let x = complex.(sprand(32, 0.6), sprand(32, 0.6)),
y = complex.(sprand(32, 0.6), sprand(32, 0.6))
xf = Array(x)::Vector{Complex128}
yf = Array(y)::Vector{Complex128}
@test dot(x, x) dot(xf, xf)
@test dot(x, y) dot(xf, yf)
end
### BLAS Level-2:
## dense A * sparse x -> dense y
let A = randn(9, 16), x = sprand(16, 0.7)
xf = Array(x)
for α in [0.0, 1.0, 2.0], β in [0.0, 0.5, 1.0]
y = rand(9)
rr = α*A*xf + β*y
@test A_mul_B!(α, A, x, β, y) === y
@test y rr
end
y = A*x
@test isa(y, Vector{Float64})
@test A*x A*xf
end
let A = randn(16, 9), x = sprand(16, 0.7)
xf = Array(x)
for α in [0.0, 1.0, 2.0], β in [0.0, 0.5, 1.0]
y = rand(9)
rr = α*A'xf + β*y
@test At_mul_B!(α, A, x, β, y) === y
@test y rr
end
y = At_mul_B(A, x)
@test isa(y, Vector{Float64})
@test y At_mul_B(A, xf)
end
## sparse A * sparse x -> dense y
let A = sprandn(9, 16, 0.5), x = sprand(16, 0.7)
Af = Array(A)
xf = Array(x)
for α in [0.0, 1.0, 2.0], β in [0.0, 0.5, 1.0]
y = rand(9)
rr = α*Af*xf + β*y
@test A_mul_B!(α, A, x, β, y) === y
@test y rr
end
y = SparseArrays.densemv(A, x)
@test isa(y, Vector{Float64})
@test y Af*xf
end
let A = sprandn(16, 9, 0.5), x = sprand(16, 0.7)
Af = Array(A)
xf = Array(x)
for α in [0.0, 1.0, 2.0], β in [0.0, 0.5, 1.0]
y = rand(9)
rr = α*Af'xf + β*y
@test At_mul_B!(α, A, x, β, y) === y
@test y rr
end
y = SparseArrays.densemv(A, x; trans='T')
@test isa(y, Vector{Float64})
@test y At_mul_B(Af, xf)
end
let A = complex.(sprandn(7, 8, 0.5), sprandn(7, 8, 0.5)),
x = complex.(sprandn(8, 0.6), sprandn(8, 0.6)),
x2 = complex.(sprandn(7, 0.75), sprandn(7, 0.75))
Af = Array(A)
xf = Array(x)
x2f = Array(x2)
@test SparseArrays.densemv(A, x; trans='N') Af * xf
@test SparseArrays.densemv(A, x2; trans='T') Af.' * x2f
@test SparseArrays.densemv(A, x2; trans='C') Af'x2f
@test_throws ArgumentError SparseArrays.densemv(A, x; trans='D')
end
## sparse A * sparse x -> sparse y
let A = sprandn(9, 16, 0.5), x = sprand(16, 0.7), x2 = sprand(9, 0.7)
Af = Array(A)
xf = Array(x)
x2f = Array(x2)
y = A*x
@test isa(y, SparseVector{Float64,Int})
@test all(nonzeros(y) .!= 0.0)
@test Array(y) Af * xf
y = At_mul_B(A, x2)
@test isa(y, SparseVector{Float64,Int})
@test all(nonzeros(y) .!= 0.0)
@test Array(y) Af'x2f
end
let A = complex.(sprandn(7, 8, 0.5), sprandn(7, 8, 0.5)),
x = complex.(sprandn(8, 0.6), sprandn(8, 0.6)),
x2 = complex.(sprandn(7, 0.75), sprandn(7, 0.75))
Af = Array(A)
xf = Array(x)
x2f = Array(x2)
y = A*x
@test isa(y, SparseVector{Complex128,Int})
@test Array(y) Af * xf
y = At_mul_B(A, x2)
@test isa(y, SparseVector{Complex128,Int})
@test Array(y) Af.' * x2f
y = Ac_mul_B(A, x2)
@test isa(y, SparseVector{Complex128,Int})
@test Array(y) Af'x2f
end
# left-division operations involving triangular matrices and sparse vectors (#14005)
let m = 10
sparsefloatvecs = SparseVector[sprand(m, 0.4) for k in 1:3]
sparseintvecs = SparseVector[SparseVector(m, sprvec.nzind, round.(Int, sprvec.nzval*10)) for sprvec in sparsefloatvecs]
sparsecomplexvecs = SparseVector[SparseVector(m, sprvec.nzind, complex.(sprvec.nzval, sprvec.nzval)) for sprvec in sparsefloatvecs]
sprmat = sprand(m, m, 0.2)
sparsefloatmat = speye(m) + sprmat/(2m)
sparsecomplexmat = speye(m) + SparseMatrixCSC(m, m, sprmat.colptr, sprmat.rowval, complex.(sprmat.nzval, sprmat.nzval)/(4m))
sparseintmat = speye(Int, m)*10m + SparseMatrixCSC(m, m, sprmat.colptr, sprmat.rowval, round.(Int, sprmat.nzval*10))
denseintmat = eye(Int, m)*10m + rand(1:m, m, m)
densefloatmat = eye(m) + randn(m, m)/(2m)
densecomplexmat = eye(m) + complex.(randn(m, m), randn(m, m))/(4m)
inttypes = (Int32, Int64, BigInt)
floattypes = (Float32, Float64, BigFloat)
complextypes = (Complex{Float32}, Complex{Float64})
eltypes = (inttypes..., floattypes..., complextypes...)
for eltypemat in eltypes
(densemat, sparsemat) = eltypemat in inttypes ? (denseintmat, sparseintmat) :
eltypemat in floattypes ? (densefloatmat, sparsefloatmat) :
eltypemat in complextypes && (densecomplexmat, sparsecomplexmat)
densemat = convert(Matrix{eltypemat}, densemat)
sparsemat = convert(SparseMatrixCSC{eltypemat}, sparsemat)
trimats = (LowerTriangular(densemat), UpperTriangular(densemat),
LowerTriangular(sparsemat), UpperTriangular(sparsemat) )
unittrimats = (Base.LinAlg.UnitLowerTriangular(densemat), Base.LinAlg.UnitUpperTriangular(densemat),
Base.LinAlg.UnitLowerTriangular(sparsemat), Base.LinAlg.UnitUpperTriangular(sparsemat) )
for eltypevec in eltypes
spvecs = eltypevec in inttypes ? sparseintvecs :
eltypevec in floattypes ? sparsefloatvecs :
eltypevec in complextypes && sparsecomplexvecs
spvecs = SparseVector[SparseVector(m, spvec.nzind, convert(Vector{eltypevec}, spvec.nzval)) for spvec in spvecs]
for spvec in spvecs
fspvec = convert(Array, spvec)
# test out-of-place left-division methods
for mat in (trimats..., unittrimats...), func in (\, At_ldiv_B, Ac_ldiv_B)
@test func(mat, spvec) func(mat, fspvec)
end
# test in-place left-division methods not involving quotients
if eltypevec == typeof(zero(eltypemat)*zero(eltypevec) + zero(eltypemat)*zero(eltypevec))
for mat in unittrimats, func in (A_ldiv_B!, Base.LinAlg.At_ldiv_B!, Base.LinAlg.Ac_ldiv_B!)
@test func(mat, copy(spvec)) func(mat, copy(fspvec))
end
end
# test in-place left-division methods involving quotients
if eltypevec == typeof((zero(eltypemat)*zero(eltypevec) + zero(eltypemat)*zero(eltypevec))/one(eltypemat))
for mat in trimats, func in (A_ldiv_B!, Base.LinAlg.At_ldiv_B!, Base.LinAlg.Ac_ldiv_B!)
@test func(mat, copy(spvec)) func(mat, copy(fspvec))
end
end
end
end
end
end
# The preceding tests miss the edge case where the sparse vector is empty (#16716)
let origmat = [-1.5 -0.7; 0.0 1.0]
transmat = transpose(origmat)
utmat = UpperTriangular(origmat)
ltmat = LowerTriangular(transmat)
uutmat = Base.LinAlg.UnitUpperTriangular(origmat)
ultmat = Base.LinAlg.UnitLowerTriangular(transmat)
zerospvec = spzeros(Float64, 2)
zerodvec = zeros(Float64, 2)
for mat in (utmat, ltmat, uutmat, ultmat)
for func in (\, At_ldiv_B, Ac_ldiv_B)
@test isequal((func)(mat, zerospvec), zerodvec)
end
for ipfunc in (A_ldiv_B!, Base.LinAlg.At_ldiv_B!, Base.LinAlg.Ac_ldiv_B!)
@test isequal((ipfunc)(mat, copy(zerospvec)), zerospvec)
end
end
end
# fkeep!
let x = sparsevec(1:7, [3., 2., -1., 1., -2., -3., 3.], 7)
# droptol
xdrop = Base.droptol!(copy(x), 1.5)
@test exact_equal(xdrop, SparseVector(7, [1, 2, 5, 6, 7], [3., 2., -2., -3., 3.]))
Base.droptol!(xdrop, 2.5)
@test exact_equal(xdrop, SparseVector(7, [1, 6, 7], [3., -3., 3.]))
Base.droptol!(xdrop, 3.)
@test exact_equal(xdrop, SparseVector(7, Int[], Float64[]))
xdrop = copy(x)
# This will keep index 1, 3, 4, 7 in xdrop
f_drop(i, x) = (abs(x) == 1.) || (i in [1, 7])
Base.SparseArrays.fkeep!(xdrop, f_drop)
@test exact_equal(xdrop, SparseVector(7, [1, 3, 4, 7], [3., -1., 1., 3.]))
end
# dropzeros[!]
let testdims = (10, 20, 30), nzprob = 0.4, targetnumposzeros = 5, targetnumnegzeros = 5
for m in testdims
v = sprand(m, nzprob)
struczerosv = find(x -> x == 0, v)
poszerosinds = unique(rand(struczerosv, targetnumposzeros))
negzerosinds = unique(rand(struczerosv, targetnumnegzeros))
vposzeros = setindex!(copy(v), 2, poszerosinds)
vnegzeros = setindex!(copy(v), -2, negzerosinds)
vbothsigns = setindex!(copy(vposzeros), -2, negzerosinds)
map!(x -> x == 2 ? 0.0 : x, vposzeros.nzval, vposzeros.nzval)
map!(x -> x == -2 ? -0.0 : x, vnegzeros.nzval, vnegzeros.nzval)
map!(x -> x == 2 ? 0.0 : x == -2 ? -0.0 : x, vbothsigns.nzval, vbothsigns.nzval)
for vwithzeros in (vposzeros, vnegzeros, vbothsigns)
# Basic functionality / dropzeros!
@test dropzeros!(copy(vwithzeros)) == v
@test dropzeros!(copy(vwithzeros), false) == v
# Basic functionality / dropzeros
@test dropzeros(vwithzeros) == v
@test dropzeros(vwithzeros, false) == v
# Check trimming works as expected
@test length(dropzeros!(copy(vwithzeros)).nzval) == length(v.nzval)
@test length(dropzeros!(copy(vwithzeros)).nzind) == length(v.nzind)
@test length(dropzeros!(copy(vwithzeros), false).nzval) == length(vwithzeros.nzval)
@test length(dropzeros!(copy(vwithzeros), false).nzind) == length(vwithzeros.nzind)
end
end
# original dropzeros! test
xdrop = sparsevec(1:7, [3., 2., -1., 1., -2., -3., 3.], 7)
xdrop.nzval[[2, 4, 6]] = 0.0
Base.SparseArrays.dropzeros!(xdrop)
@test exact_equal(xdrop, SparseVector(7, [1, 3, 5, 7], [3, -1., -2., 3.]))
end
# It's tempting to share data between a SparseVector and a SparseMatrix,
# but if that's done, then modifications to one or the other will cause
# an inconsistent state:
sv = sparse(1:10)
sm = convert(SparseMatrixCSC, sv)
sv[1] = 0
@test Array(sm)[2:end] == collect(2:10)
# Ensure that sparsevec with all-zero values returns an array of zeros
@test sparsevec([1,2,3],[0,0,0]) == [0,0,0]
# Compare stored zero semantics between SparseVector and SparseMatrixCSC
let S = SparseMatrixCSC(10,1,[1,6],[1,3,5,6,7],[0,1,2,0,3]), x = SparseVector(10,[1,3,5,6,7],[0,1,2,0,3])
@test nnz(S) == nnz(x) == 5
for I = (:, 1:10, collect(1:10))
@test S[I,1] == S[I] == x[I] == x
@test nnz(S[I,1]) == nnz(S[I]) == nnz(x[I]) == nnz(x)
end
for I = (2:9, 1:2, 9:10, [3,6,1], [10,9,8], [])
@test S[I,1] == S[I] == x[I]
@test nnz(S[I,1]) == nnz(S[I]) == nnz(x[I])
end
@test S[[1 3 5; 2 4 6]] == x[[1 3 5; 2 4 6]]
@test nnz(S[[1 3 5; 2 4 6]]) == nnz(x[[1 3 5; 2 4 6]])
end
# Issue 14013
s14013 = sparse([10.0 0.0 30.0; 0.0 1.0 0.0])
a14013 = [10.0 0.0 30.0; 0.0 1.0 0.0]
@test s14013 == a14013
@test vec(s14013) == s14013[:] == a14013[:]
@test Array(s14013)[1,:] == s14013[1,:] == a14013[1,:] == [10.0, 0.0, 30.0]
@test Array(s14013)[2,:] == s14013[2,:] == a14013[2,:] == [0.0, 1.0, 0.0]
# Issue 14046
s14046 = sprand(5, 1.0)
@test spzeros(5) + s14046 == s14046
@test 2*s14046 == s14046 + s14046
# Issue 14589
# test vectors with no zero elements
x = sparsevec(1:7, [3., 2., -1., 1., -2., -3., 3.], 7)
@test collect(sort(x)) == sort(collect(x))
# test vectors with all zero elements
x = sparsevec(Int64[], Float64[], 7)
@test collect(sort(x)) == sort(collect(x))
# test vector with sparsity approx 1/2
x = sparsevec(1:7, [3., 2., -1., 1., -2., -3., 3.], 15)
@test collect(sort(x)) == sort(collect(x))
# apply three distinct tranformations where zeros sort into start/middle/end
@test collect(sort(x, by=abs)) == sort(collect(x), by=abs)
@test collect(sort(x, by=sign)) == sort(collect(x), by=sign)
@test collect(sort(x, by=inv)) == sort(collect(x), by=inv)
# fill!
for Tv in [Float32, Float64, Int64, Int32, Complex128]
for Ti in [Int16, Int32, Int64, BigInt]
sptypes = (SparseMatrixCSC{Tv, Ti}, SparseVector{Tv, Ti})
sizes = [(3, 4), (3,)]
for (siz, Sp) in zip(sizes, sptypes)
arr = rand(Tv, siz...)
sparr = Sp(arr)
fillval = rand(Tv)
fill!(sparr, fillval)
@test Array(sparr) == fillval * ones(arr)
fill!(sparr, 0)
@test Array(sparr) == zeros(arr)
end
end
end
# ref 13130 and 16661
@test issparse([sprand(10,10,.1) sprand(10,.1)])
@test issparse([sprand(10,1,.1); sprand(10,.1)])
@test issparse([sprand(10,10,.1) rand(10)])
@test issparse([sprand(10,1,.1) rand(10)])
@test issparse([sprand(10,2,.1) sprand(10,1,.1) rand(10)])
@test issparse([sprand(10,1,.1); rand(10)])
@test issparse([sprand(10,.1) rand(10)])
@test issparse([sprand(10,.1); rand(10)])
mutable struct t20488 end
@testset "similar" begin
x = sparsevec(rand(3) .+ 0.1)
@test length(similar(x, t20488).nzval) == 3
@test typeof(similar(x, Float32, Int32)) == SparseVector{Float32, Int32}
@test typeof(similar(x, Float32)) == SparseVector{Float32, Int}
end
@testset "show" begin
io = IOBuffer()
show(io, MIME"text/plain"(), sparsevec(Int64[1], [1.0]))
@test String(take!(io)) == "1-element SparseVector{Float64,Int64} with 1 stored entry:\n [1] = 1.0"
show(io, MIME"text/plain"(), spzeros(Float64, Int64, 2))
@test String(take!(io)) == "2-element SparseVector{Float64,Int64} with 0 stored entries"
show(io, similar(sparsevec(rand(3) .+ 0.1), t20488))
@test String(take!(io)) == " [1] = #undef\n [2] = #undef\n [3] = #undef"
end
@testset "spzeros with index type" begin
@test typeof(spzeros(Float32, Int16, 3)) == SparseVector{Float32,Int16}
end