Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/SparseArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ julia> collect(SparseArrays.iternz(x))
"""
function iternz end

widelength(x::AbstractSparseArray) = prod(widen, size(x))
widelength(x::AbstractSparseArray) = *(map(widen, size(x))...)
# Linear indexing compares an index with `length(A)`, which wraps for 2^63 entries or more
_checklinearindexing(A::AbstractSparseMatrixCSC) = widelength(A) <= typemax(Int) ||
throw(OverflowError(string("a ", size(A, 1), "×", size(A, 2), " sparse matrix has more ",
Expand Down
28 changes: 4 additions & 24 deletions src/constructors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -714,43 +714,23 @@ julia> sprand(Float64, 3, 0.75)
"""
function sprand(r::AbstractRNG, m::Integer, n::Integer, density::AbstractFloat, rfn::Function, ::Type{T}) where T
m, n = Int(m), Int(n)
if _sprandoverflows(m, n, density)
colptr, rowval, V = _sprand_bycolumn(r, m, n, density, rfn)
return SparseMatrixCSC(m, n, colptr, rowval, convert(Vector{T}, V))
end
I, V = _sprandvalues(r, m, n, density, rfn)
return sparse_sortedlinearindices!(I, convert(Vector{T}, V), m, n)
end
function sprand(r::AbstractRNG, m::Integer, n::Integer, density::AbstractFloat, rfn::Function)
m, n = Int(m), Int(n)
if _sprandoverflows(m, n, density)
colptr, rowval, V = _sprand_bycolumn(r, m, n, density, rfn)
return SparseMatrixCSC(m, n, colptr, rowval, convert(Vector{eltype(V)}, V))
end
I, V = _sprandvalues(r, m, n, density, rfn)
return sparse_sortedlinearindices!(I, convert(Vector{eltype(V)}, V), m, n)
end
# the arguments are checked first, since negative dimensions can overflow too
function _sprandoverflows(m::Int, n::Int, density::AbstractFloat)
function _sprandvalues(r::AbstractRNG, m::Int, n::Int, density::AbstractFloat, rfn::F) where {F}
(m < 0 || n < 0) && throw(ArgumentError("invalid Array dimensions"))
0 <= density <= 1 || throw(ArgumentError("$density not in [0,1]"))
return Base.mul_with_overflow(m, n)[2]
end
function _sprandvalues(r::AbstractRNG, m::Int, n::Int, density::AbstractFloat, rfn::F) where {F}
# the entries are drawn as linear indices, which wrap for 2^63 entries or more
Base.mul_with_overflow(m, n)[2] && throw(OverflowError(string("a ", m, "×", n,
" sparse matrix has more entries than `sprand` can draw from")))
I = randsubseq(r, 1:(m*n), density)
return I, rfn(r, length(I))
end
# an `Int` cannot index the `m*n` entries, so the stored rows are drawn column by column
function _sprand_bycolumn(r::AbstractRNG, m::Int, n::Int, density::AbstractFloat, rfn::F) where {F}
colptr = Vector{Int}(undef, n + 1)
colptr[1] = 1
rowval, rows = Int[], Int[]
for col in 1:n
append!(rowval, randsubseq!(r, rows, 1:m, density))
colptr[col + 1] = length(rowval) + 1
end
return colptr, rowval, rfn(r, length(rowval))
end

sprand(m::Integer, n::Integer, density::AbstractFloat, rfn::Function) =
sprand(default_rng(), m, n, density, (r, i) -> rfn(i))
Expand Down
4 changes: 2 additions & 2 deletions src/sparsematrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ function _storedinds(S::SparseMatrixCSCColumnSubset)
end
return inds
end
widelength(S::SparseMatrixCSCColumnSubset) = prod(widen, size(S))
widelength(S::SparseMatrixCSCColumnSubset) = *(map(widen, size(S))...)
widelength(x::Union{SparseColumnView,SparseVectorView}) = length(x)
# `A` itself where it exposes compressed storage through `nzrange`, `rowvals` and `nonzeros`,
# otherwise its sparse copy
Expand Down Expand Up @@ -984,7 +984,7 @@ similar(S::AbstractSparseMatrixCSC, ::Type{TvNew}, ::Type{TiNew}, m::Integer, n:
_sparsesimilar(S, TvNew, TiNew, (m, n))

function Base.sizehint!(S::SparseMatrixCSC, n::Integer)
nhint = min(n, widelength(S))
nhint = Int(min(n, widelength(S)))
sizehint!(getrowval(S), nhint)
sizehint!(getnzval(S), nhint)
return S
Expand Down
2 changes: 1 addition & 1 deletion test/issues.jl
Original file line number Diff line number Diff line change
Expand Up @@ -979,7 +979,7 @@ end
@test_throws OverflowError B[[1]] = [1.0]
@test_throws OverflowError B[1] = 1.0
@test nnz(B) == 0
@test nnz(sprand(Xoshiro(1), 2^62, 4, 1e-17)) > 0
@test_throws OverflowError sprand(Xoshiro(1), 2^62, 4, 1e-17)
end

if isdefined(Docs, :undocumented_names) # new in Julia 1.11
Expand Down
Loading