diff --git a/NEWS.md b/NEWS.md index 67fc1343e9cbc..b072cbf94f0e1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -697,6 +697,18 @@ Deprecated or removed `Matrix{Int}(undef, (2, 4))`, and `Array{Float32,3}(11, 13, 17)` is now `Array{Float32,3}(undef, 11, 13, 17)` ([#24781]). + * Previously `setindex!(A, x, I...)` (and the syntax `A[I...] = x`) supported two + different modes of operation when supplied with a set of non-scalar indices `I` + (e.g., at least one index is an `AbstractArray`) depending upon the value of `x` + on the right hand side. If `x` is an `AbstractArray`, its _contents_ are copied + elementwise into the locations in `A` selected by `I` and it must have the same + number of elements as `I` selects locations. Otherwise, if `x` is not an + `AbstractArray`, then its _value_ is implicitly broadcast to all locations to + all locations in `A` selected by `I`. This latter behavior—implicitly broadcasting + "scalar"-like values across many locations—is now deprecated in favor of explicitly + using the broadcasted assignment syntax `A[I...] .= x` or `fill!(view(A, I...), x)` + ([#26347]). + * `LinAlg.fillslots!` has been renamed `LinAlg.fillstored!` ([#25030]). * `fill!(A::Diagonal, x)` and `fill!(A::AbstractTriangular, x)` have been deprecated diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 5755ed8e7d999..ec65d728c2a54 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -1181,8 +1181,8 @@ function get!(X::AbstractArray{T}, A::AbstractArray, I::Union{AbstractRange,Abst # Linear indexing ind = findall(in(1:length(A)), I) X[ind] = A[I[ind]] - X[1:first(ind)-1] = default - X[last(ind)+1:length(X)] = default + fill!(view(X, 1:first(ind)-1), default) + fill!(view(X, last(ind)+1:length(X)), default) X end @@ -1380,7 +1380,11 @@ function _cat(A, shape::NTuple{N}, catdims, X...) where N end end I::NTuple{N, UnitRange{Int}} = (inds...,) - A[I...] = x + if x isa AbstractArray + A[I...] = x + else + fill!(view(A, I...), x) + end end return A end @@ -1930,10 +1934,10 @@ function mapslices(f, A::AbstractArray, dims::AbstractVector) ridx[d] = axes(R,d) end - R[ridx...] = r1 + concatenate_setindex!(R, r1, ridx...) nidx = length(otherdims) - indices = Iterators.drop(CartesianIndices(itershape), 1) + indices = Iterators.drop(CartesianIndices(itershape), 1) # skip the first element, we already handled it inner_mapslices!(safe_for_reuse, indices, nidx, idx, otherdims, ridx, Aslice, A, f, R) end @@ -1941,16 +1945,16 @@ end if safe_for_reuse # when f returns an array, R[ridx...] = f(Aslice) line copies elements, # so we can reuse Aslice - for I in indices # skip the first element, we already handled it + for I in indices replace_tuples!(nidx, idx, ridx, otherdims, I) _unsafe_getindex!(Aslice, A, idx...) - R[ridx...] = f(Aslice) + concatenate_setindex!(R, f(Aslice), ridx...) end else # we can't guarantee safety (#18524), so allocate new storage for each slice for I in indices replace_tuples!(nidx, idx, ridx, otherdims, I) - R[ridx...] = f(A[idx...]) + concatenate_setindex!(R, f(A[idx...]), ridx...) end end @@ -1963,6 +1967,8 @@ function replace_tuples!(nidx, idx, ridx, otherdims, I) end end +concatenate_setindex!(R, v, I...) = (R[I...] .= (v,); R) +concatenate_setindex!(R, X::AbstractArray, I...) = (R[I...] = X) ## 1 argument diff --git a/base/abstractarraymath.jl b/base/abstractarraymath.jl index cd723ffd449e7..df3f1caddbe92 100644 --- a/base/abstractarraymath.jl +++ b/base/abstractarraymath.jl @@ -363,10 +363,6 @@ _rshps(shp, shp_i, sz, i, ::Tuple{}) = _reperr(s, n, N) = throw(ArgumentError("number of " * s * " repetitions " * "($n) cannot be less than number of dimensions of input ($N)")) -# We need special handling when repeating arrays of arrays -cat_fill!(R, X, inds) = (R[inds...] = X) -cat_fill!(R, X::AbstractArray, inds) = fill!(view(R, inds...), X) - @noinline function _repeat(A::AbstractArray, inner, outer) shape, inner_shape = rep_shapes(A, inner, outer) @@ -385,7 +381,7 @@ cat_fill!(R, X::AbstractArray, inds) = fill!(view(R, inds...), X) n = inner[i] inner_indices[i] = (1:n) .+ ((c[i] - 1) * n) end - cat_fill!(R, A[c], inner_indices) + fill!(view(R, inner_indices...), A[c]) end end diff --git a/base/array.jl b/base/array.jl index 2f6956960a6fb..30dd5edc8b5d8 100644 --- a/base/array.jl +++ b/base/array.jl @@ -706,29 +706,6 @@ function setindex! end @eval setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T} = (@_inline_meta; arrayset($(Expr(:boundscheck)), A, convert(T,x)::T, i1, i2, I...)) -# These are redundant with the abstract fallbacks but needed for bootstrap -function setindex!(A::Array, x, I::AbstractVector{Int}) - @_propagate_inbounds_meta - I′ = unalias(A, I) - for i in I′ - A[i] = x - end - return A -end -function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int}) - @_propagate_inbounds_meta - @boundscheck setindex_shape_check(X, length(I)) - X′ = unalias(A, X) - I′ = unalias(A, I) - count = 1 - for i in I′ - @inbounds x = X′[count] - A[i] = x - count += 1 - end - return A -end - # Faster contiguous setindex! with copyto! function setindex!(A::Array{T}, X::Array{T}, I::UnitRange{Int}) where T @_inline_meta @@ -750,9 +727,6 @@ function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T return A end -setindex!(A::Array, x::Number, ::Colon) = fill!(A, x) -setindex!(A::Array{T, N}, x::Number, ::Vararg{Colon, N}) where {T, N} = fill!(A, x) - # efficiently grow an array _growbeg!(a::Vector, delta::Integer) = diff --git a/base/bitarray.jl b/base/bitarray.jl index be4600713110b..fd826ef13cd1d 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -584,7 +584,7 @@ function gen_bitarray_from_itr(itr, st) end end if ind > 1 - @inbounds C[ind:bitcache_size] = false + @inbounds C[ind:bitcache_size] .= false resize!(B, length(B) + ind - 1) dumpbitcache(Bc, cind, C) end @@ -608,7 +608,7 @@ function fill_bitarray_from_itr!(B::BitArray, itr, st) end end if ind > 1 - @inbounds C[ind:bitcache_size] = false + @inbounds C[ind:bitcache_size] .= false dumpbitcache(Bc, cind, C) end return B @@ -653,44 +653,10 @@ end indexoffset(i) = first(i)-1 indexoffset(::Colon) = 0 -@inline function setindex!(B::BitArray, x, J0::Union{Colon,UnitRange{Int}}) - I0 = to_indices(B, (J0,))[1] - @boundscheck checkbounds(B, I0) - y = Bool(x) - l0 = length(I0) - l0 == 0 && return B - f0 = indexoffset(I0)+1 - fill_chunks!(B.chunks, y, f0, l0) - return B -end @propagate_inbounds function setindex!(B::BitArray, X::AbstractArray, J0::Union{Colon,UnitRange{Int}}) _setindex!(IndexStyle(B), B, X, to_indices(B, (J0,))[1]) end -# logical indexing - -# When indexing with a BitArray, we can operate whole chunks at a time for a ~100x gain -@inline function setindex!(B::BitArray, x, I::BitArray) - @boundscheck checkbounds(B, I) - _unsafe_setindex!(B, x, I) -end -function _unsafe_setindex!(B::BitArray, x, I::BitArray) - y = convert(Bool, x) - Bc = B.chunks - Ic = I.chunks - length(Bc) == length(Ic) || throw_boundserror(B, I) - @inbounds if y - for i = 1:length(Bc) - Bc[i] |= Ic[i] - end - else - for i = 1:length(Bc) - Bc[i] &= ~Ic[i] - end - end - return B -end - # Assigning an array of bools is more complicated, but we can still do some # work on chunks by combining X and I 64 bits at a time to improve perf by ~40% @inline function setindex!(B::BitArray, X::AbstractArray, I::BitArray) diff --git a/base/bitset.jl b/base/bitset.jl index 330b11e77430f..395a61505b85b 100644 --- a/base/bitset.jl +++ b/base/bitset.jl @@ -114,12 +114,16 @@ end @inline function _growend0!(b::Bits, nchunks::Int) len = length(b) _growend!(b, nchunks) - @inbounds b[len+1:end] = CHK0 # resize! gives dirty memory + for i in len+1:length(b) + @inbounds b[i] = CHK0 # resize! gives dirty memory + end end @inline function _growbeg0!(b::Bits, nchunks::Int) _growbeg!(b, nchunks) - @inbounds b[1:nchunks] = CHK0 + for i in 1:nchunks + @inbounds b[i] = CHK0 + end end function _matched_map!(f, s1::BitSet, s2::BitSet) diff --git a/base/broadcast.jl b/base/broadcast.jl index ffca52e64de07..1e09f39411aa4 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -830,7 +830,7 @@ end end end if ind > 1 - @inbounds tmp[ind:bitcache_size] = false + @inbounds tmp[ind:bitcache_size] .= false dumpbitcache(destc, cind, tmp) end return dest @@ -1106,6 +1106,39 @@ See [`broadcast_getindex`](@ref) for examples of the treatment of `inds`. end end +## In specific instances, we can broadcast masked BitArrays whole chunks at a time +# Very intentionally do not support much functionality here: scalar indexing would be O(n) +struct BitMaskedBitArray{N,M} + parent::BitArray{N} + mask::BitArray{M} + BitMaskedBitArray{N,M}(parent, mask) where {N,M} = new(parent, mask) +end +@inline function BitMaskedBitArray(parent::BitArray{N}, mask::BitArray{M}) where {N,M} + @boundscheck checkbounds(parent, mask) + BitMaskedBitArray{N,M}(parent, mask) +end +Base.@propagate_inbounds dotview(B::BitArray, i::BitArray) = BitMaskedBitArray(B, i) +Base.show(io::IO, B::BitMaskedBitArray) = foreach(arg->show(io, arg), (typeof(B), (B.parent, B.mask))) +# Override materialize! to prevent the BitMaskedBitArray from escaping to an overrideable method +@inline materialize!(B::BitMaskedBitArray, bc::Broadcasted{<:Any,<:Any,typeof(identity),Tuple{Bool}}) = fill!(B, bc.args[1]) +@inline materialize!(B::BitMaskedBitArray, bc::Broadcasted{<:Any}) = materialize!(SubArray(B.parent, to_indices(B.parent, (B.mask,))), bc) +function Base.fill!(B::BitMaskedBitArray, b::Bool) + Bc = B.parent.chunks + Ic = B.mask.chunks + @inbounds if b + for i = 1:length(Bc) + Bc[i] |= Ic[i] + end + else + for i = 1:length(Bc) + Bc[i] &= ~Ic[i] + end + end + return B +end + + + ############################################################ # x[...] .= f.(y...) ---> broadcast!(f, dotview(x, ...), y...). diff --git a/base/char.jl b/base/char.jl index 768919d493c24..97e74d2d0758a 100644 --- a/base/char.jl +++ b/base/char.jl @@ -215,7 +215,10 @@ widen(::Type{T}) where {T<:AbstractChar} = T print(io::IO, c::Char) = (write(io, c); nothing) print(io::IO, c::AbstractChar) = print(io, Char(c)) # fallback: convert to output UTF-8 -const hex_chars = UInt8['0':'9';'a':'z'] +const hex_chars = UInt8['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', + 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', + 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] function show_invalid(io::IO, c::Char) write(io, 0x27) diff --git a/base/compiler/ssair/ir.jl b/base/compiler/ssair/ir.jl index f5e5a55682e7c..7d12ad1312c0b 100644 --- a/base/compiler/ssair/ir.jl +++ b/base/compiler/ssair/ir.jl @@ -578,7 +578,9 @@ function resize!(compact::IncrementalCompact, nnewnodes) resize!(compact.result_lines, nnewnodes) resize!(compact.result_flags, nnewnodes) resize!(compact.used_ssas, nnewnodes) - compact.used_ssas[(old_length+1):nnewnodes] = 0 + for i in (old_length+1):nnewnodes + compact.used_ssas[i] = 0 + end nothing end diff --git a/base/compiler/ssair/slot2ssa.jl b/base/compiler/ssair/slot2ssa.jl index 72cb54b13647e..7183bf741774c 100644 --- a/base/compiler/ssair/slot2ssa.jl +++ b/base/compiler/ssair/slot2ssa.jl @@ -377,8 +377,8 @@ function domsort_ssa!(ir::IRCode, domtree::DomTree) end old_inst_range = ir.cfg.blocks[bb].stmts inst_range = (bb_start_off+1):(bb_start_off+length(old_inst_range)) - inst_rename[old_inst_range] = Any[SSAValue(x) for x in inst_range] for (nidx, idx) in zip(inst_range, old_inst_range) + inst_rename[idx] = SSAValue(nidx) stmt = ir.stmts[idx] if isa(stmt, PhiNode) result_stmts[nidx] = rename_phinode_edges(stmt, bb, result_order, bb_rename) diff --git a/base/deprecated.jl b/base/deprecated.jl index 8efe89cbe319c..743d9d1f186f9 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -1491,6 +1491,27 @@ function slicedim(A::AbstractVector, d::Integer, i::Number) end end +# PR #26347: Deprecate implicit scalar broadcasting in setindex! +_axes(::Ref) = () +_axes(x) = axes(x) +function deprecate_scalar_setindex_broadcast_message(v, I...) + value = (_axes(Base.Broadcast.broadcastable(v)) == () ? "x" : "(x,)") + "using `A[I...] = x` to implicitly broadcast `x` across many locations is deprecated. Use `A[I...] .= $value` instead." +end +deprecate_scalar_setindex_broadcast_message(v, ::Colon, ::Vararg{Colon}) = + "using `A[:] = x` to implicitly broadcast `x` across many locations is deprecated. Use `fill!(A, x)` instead." + +function _iterable(v, I...) + depwarn(deprecate_scalar_setindex_broadcast_message(v, I...), :setindex!) + Iterators.repeated(v) +end +function setindex!(B::BitArray, x, I0::Union{Colon,UnitRange{Int}}, I::Union{Int,UnitRange{Int},Colon}...) + depwarn(deprecate_scalar_setindex_broadcast_message(x, I0, I...), :setindex!) + B[I0, I...] .= (x,) + B +end + + # PR #26283 @deprecate contains(haystack, needle) occursin(needle, haystack) @deprecate contains(s::AbstractString, r::Regex, offset::Integer) occursin(r, s, offset=offset) diff --git a/base/iobuffer.jl b/base/iobuffer.jl index 88ce78dc77aec..c42093b9d2c59 100644 --- a/base/iobuffer.jl +++ b/base/iobuffer.jl @@ -117,7 +117,7 @@ function IOBuffer(; append=flags.append, truncate=flags.truncate, maxsize=maxsize) - buf.data[:] = 0 + fill!(buf.data, 0) return buf end @@ -246,7 +246,7 @@ function truncate(io::GenericIOBuffer, n::Integer) if n > length(io.data) resize!(io.data, n) end - io.data[io.size+1:n] = 0 + io.data[io.size+1:n] .= 0 io.size = n io.ptr = min(io.ptr, n+1) ismarked(io) && io.mark > n && unmark(io) diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 7e157ccc9a21f..6b864dfcf2be8 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -662,12 +662,11 @@ function _setindex!(l::IndexStyle, A::AbstractArray, x, I::Union{Real, AbstractA A end -_iterable(v::AbstractArray) = v -_iterable(v) = Iterators.repeated(v) +_iterable(X::AbstractArray, I...) = X @generated function _unsafe_setindex!(::IndexStyle, A::AbstractArray, x, I::Union{Real,AbstractArray}...) N = length(I) quote - x′ = _iterable(unalias(A, x)) + x′ = unalias(A, _iterable(x, I...)) @nexprs $N d->(I_d = unalias(A, I[d])) idxlens = @ncall $N index_lengths I @ncall $N setindex_shape_check x′ (d->idxlens[d]) @@ -1204,19 +1203,26 @@ end end end -@inline function setindex!(B::BitArray, x, - I0::Union{Colon,UnitRange{Int}}, I::Union{Int,UnitRange{Int},Colon}...) - J = to_indices(B, (I0, I...)) - @boundscheck checkbounds(B, J...) - _unsafe_setindex!(B, x, J...) -end @propagate_inbounds function setindex!(B::BitArray, X::AbstractArray, I0::Union{Colon,UnitRange{Int}}, I::Union{Int,UnitRange{Int},Colon}...) _setindex!(IndexStyle(B), B, X, to_indices(B, (I0, I...))...) end -@generated function _unsafe_setindex!(B::BitArray, x, - I0::Union{Slice,UnitRange{Int}}, I::Union{Int,UnitRange{Int},Slice}...) +## fill! contiguous views of BitArrays with a single value +function fill!(V::SubArray{Bool, <:Any, <:BitArray, Tuple{AbstractUnitRange{Int}}}, x) + B = V.parent + I0 = V.indices[1] + l0 = length(I0) + l0 == 0 && return V + fill_chunks!(B.chunks, Bool(x), first(I0), l0) + return V +end + +fill!(V::SubArray{Bool, <:Any, <:BitArray, Tuple{AbstractUnitRange{Int}, Vararg{Union{Int,AbstractUnitRange{Int}}}}}, x) = + _unsafe_fill_indices!(V.parent, x, V.indices...) + +@generated function _unsafe_fill_indices!(B::BitArray, x, + I0::AbstractUnitRange{Int}, I::Union{Int,AbstractUnitRange{Int}}...) N = length(I) quote y = Bool(x) @@ -1469,7 +1475,9 @@ julia> extrema(A, (1,2)) """ function extrema(A::AbstractArray, dims) sz = [size(A)...] - sz[[dims...]] = 1 + for d in dims + sz[d] = 1 + end B = Array{Tuple{eltype(A),eltype(A)}}(undef, sz...) return extrema!(B, A) end diff --git a/stdlib/FileWatching/src/FileWatching.jl b/stdlib/FileWatching/src/FileWatching.jl index d2a9c4edd3724..e2759f7fa29f7 100644 --- a/stdlib/FileWatching/src/FileWatching.jl +++ b/stdlib/FileWatching/src/FileWatching.jl @@ -158,7 +158,7 @@ mutable struct _FDWatcher if fdnum > length(FDWatchers) old_len = length(FDWatchers) resize!(FDWatchers, fdnum) - FDWatchers[(old_len + 1):fdnum] = nothing + FDWatchers[(old_len + 1):fdnum] .= nothing elseif FDWatchers[fdnum] !== nothing this = FDWatchers[fdnum]::_FDWatcher this.refcount = (this.refcount[1] + Int(readable), this.refcount[2] + Int(writable)) diff --git a/stdlib/LinearAlgebra/src/dense.jl b/stdlib/LinearAlgebra/src/dense.jl index a83cf1d7b55ac..9e1bfa4ab0454 100644 --- a/stdlib/LinearAlgebra/src/dense.jl +++ b/stdlib/LinearAlgebra/src/dense.jl @@ -1297,7 +1297,7 @@ function pinv(A::StridedMatrix{T}, tol::Real) where T Sinv = zeros(Stype, length(SVD.S)) index = SVD.S .> tol*maximum(SVD.S) Sinv[index] = one(Stype) ./ SVD.S[index] - Sinv[findall(.!isfinite.(Sinv))] = zero(Stype) + Sinv[findall(.!isfinite.(Sinv))] .= zero(Stype) return SVD.Vt' * (Diagonal(Sinv) * SVD.U') end function pinv(A::StridedMatrix{T}) where T diff --git a/stdlib/LinearAlgebra/src/qr.jl b/stdlib/LinearAlgebra/src/qr.jl index 1408ffc04d85d..2e7f0eb437402 100644 --- a/stdlib/LinearAlgebra/src/qr.jl +++ b/stdlib/LinearAlgebra/src/qr.jl @@ -774,7 +774,7 @@ function ldiv!(A::QRPivoted{T}, B::StridedMatrix{T}, rcond::Real) where T<:BlasF end ar = abs(A.factors[1]) if ar == 0 - B[1:nA, :] = 0 + B[1:nA, :] .= 0 return B, 0 end rnk = 1 @@ -795,7 +795,7 @@ function ldiv!(A::QRPivoted{T}, B::StridedMatrix{T}, rcond::Real) where T<:BlasF end C, τ = LAPACK.tzrzf!(A.factors[1:rnk,:]) ldiv!(UpperTriangular(C[1:rnk,1:rnk]),view(lmul!(adjoint(A.Q), view(B, 1:mA, 1:nrhs)), 1:rnk, 1:nrhs)) - B[rnk+1:end,:] = zero(T) + B[rnk+1:end,:] .= zero(T) LAPACK.ormrz!('L', eltype(B)<:Complex ? 'C' : 'T', C, τ, view(B,1:nA,1:nrhs)) B[1:nA,:] = view(B, 1:nA, :)[invperm(A.p),:] return B, rnk @@ -832,7 +832,7 @@ function ldiv!(A::QR{T}, B::StridedMatrix{T}) where T end LinearAlgebra.ldiv!(UpperTriangular(view(R, :, 1:minmn)), view(B, 1:minmn, :)) if n > m # Apply elementary transformation to solution - B[m + 1:mB,1:nB] = zero(T) + B[m + 1:mB,1:nB] .= zero(T) for j = 1:nB for k = 1:m vBj = B[k,j] diff --git a/stdlib/LinearAlgebra/src/uniformscaling.jl b/stdlib/LinearAlgebra/src/uniformscaling.jl index 6c04450da0b07..9cfed3941c575 100644 --- a/stdlib/LinearAlgebra/src/uniformscaling.jl +++ b/stdlib/LinearAlgebra/src/uniformscaling.jl @@ -378,7 +378,14 @@ chol(J::UniformScaling, args...) = ((C, info) = _chol!(J, nothing); @assertposde ## Matrix construction from UniformScaling -Matrix{T}(s::UniformScaling, dims::Dims{2}) where {T} = setindex!(Base.zeros(T, dims), T(s.λ), diagind(dims...)) +function Matrix{T}(s::UniformScaling, dims::Dims{2}) where {T} + A = zeros(T, dims) + v = T(s.λ) + for i in diagind(dims...) + @inbounds A[i] = v + end + return A +end Matrix{T}(s::UniformScaling, m::Integer, n::Integer) where {T} = Matrix{T}(s, Dims((m, n))) Matrix(s::UniformScaling, m::Integer, n::Integer) = Matrix(s, Dims((m, n))) Matrix(s::UniformScaling, dims::Dims{2}) = Matrix{eltype(s)}(s, dims) diff --git a/stdlib/LinearAlgebra/test/dense.jl b/stdlib/LinearAlgebra/test/dense.jl index b9e094d2801f0..9bbd914047462 100644 --- a/stdlib/LinearAlgebra/test/dense.jl +++ b/stdlib/LinearAlgebra/test/dense.jl @@ -340,7 +340,7 @@ end dim=2 S=zeros(Complex,dim,dim) T=zeros(Complex,dim,dim) - T[:] = 1 + fill!(T, 1) z = 2.5 + 1.5im S[1] = z @test S*T == [z z; 0 0] diff --git a/stdlib/Pkg3/src/GraphType.jl b/stdlib/Pkg3/src/GraphType.jl index c207f0cad1935..35bb07f8eecdc 100644 --- a/stdlib/Pkg3/src/GraphType.jl +++ b/stdlib/Pkg3/src/GraphType.jl @@ -1266,7 +1266,7 @@ function build_eq_classes_soft1!(graph::Graph, p0::Int) # disable the other versions by introducing additional constraints fill!(gconstr0, false) - gconstr0[repr_vers] = true + gconstr0[repr_vers] .= true return end diff --git a/stdlib/SHA/src/sha3.jl b/stdlib/SHA/src/sha3.jl index 89e15e7403c2f..38bc547f7208e 100644 --- a/stdlib/SHA/src/sha3.jl +++ b/stdlib/SHA/src/sha3.jl @@ -61,7 +61,7 @@ function digest!(context::T) where {T<:SHA3_CTX} # Begin padding with a 0x06 context.buffer[usedspace+1] = 0x06 # Fill with zeros up until the last byte - context.buffer[usedspace+2:end-1] = 0x00 + context.buffer[usedspace+2:end-1] .= 0x00 # Finish it off with a 0x80 context.buffer[end] = 0x80 else diff --git a/stdlib/SharedArrays/test/runtests.jl b/stdlib/SharedArrays/test/runtests.jl index f71494f7945ed..d26e84bdfbcbc 100644 --- a/stdlib/SharedArrays/test/runtests.jl +++ b/stdlib/SharedArrays/test/runtests.jl @@ -34,7 +34,7 @@ function check_pids_all(S::SharedArray) parentindices(D.loc_subarr_1d)[1] end @test all(sdata(S)[idxes_in_p] .== p) - pidtested[idxes_in_p] = true + pidtested[idxes_in_p] .= true end @test all(pidtested) end @@ -124,7 +124,7 @@ finalize(S) # Creating a new file fn2 = tempname() -S = SharedArray{Int,2}(fn2, sz, init=D->D[localindices(D)] = myid()) +S = SharedArray{Int,2}(fn2, sz, init=D->(for i in localindices(D); D[i] = myid(); end)) @test S == filedata filedata2 = similar(Atrue) read!(fn2, filedata2) @@ -134,7 +134,7 @@ finalize(S) # Appending to a file fn3 = tempname() write(fn3, fill(0x1, 4)) -S = SharedArray{UInt8}(fn3, sz, 4, mode="a+", init=D->D[localindices(D)]=0x02) +S = SharedArray{UInt8}(fn3, sz, 4, mode="a+", init=D->(for i in localindices(D); D[i] = 0x02; end)) len = prod(sz)+4 @test filesize(fn3) == len filedata = Vector{UInt8}(undef, len) @@ -190,25 +190,25 @@ s = copy(sdata(d)) ds = deepcopy(d) @test ds == d pids_d = procs(d) -remotecall_fetch(setindex!, pids_d[findfirst(id->(id != myid()), pids_d)::Int], d, 1.0, 1:10) +@everywhere bcast_setindex!(S, v, I) = (for i in I; S[i] = v; end; S) +remotecall_fetch(bcast_setindex!, pids_d[findfirst(id->(id != myid()), pids_d)::Int], d, 1.0, 1:10) @test ds != d @test s != d copyto!(d, s) -@everywhere setid!(A) = A[localindices(A)] = myid() +@everywhere setid!(A) = (for i in localindices(A); A[i] = myid(); end; A) @everywhere procs(ds) setid!($ds) @test d == s @test ds != s @test first(ds) == first(procs(ds)) @test last(ds) == last(procs(ds)) - # SharedArray as an array # Since the data in d will depend on the nprocs, just test that these operations work a = d[1:5] @test_throws BoundsError d[-1:5] a = d[1,1,1:3:end] -d[2:4] = 7 -d[5,1:2:4,8] = 19 +d[2:4] .= 7 +d[5,1:2:4,8] .= 19 AA = rand(4,2) A = @inferred(convert(SharedArray, AA)) diff --git a/stdlib/SparseArrays/src/deprecated.jl b/stdlib/SparseArrays/src/deprecated.jl index 7c1aab2046e6f..8f372098d86b0 100644 --- a/stdlib/SparseArrays/src/deprecated.jl +++ b/stdlib/SparseArrays/src/deprecated.jl @@ -222,6 +222,15 @@ end import Base: asyncmap @deprecate asyncmap(f, s::AbstractSparseArray...; kwargs...) sparse(asyncmap(f, map(Array, s)...; kwargs...)) +# PR 26347: implicit scalar broadcasting within setindex! +@deprecate setindex!(A::SparseMatrixCSC, x::Number, i::Integer, J::AbstractVector{<:Integer}) (A[i, J] .= x; A) +@deprecate setindex!(A::SparseMatrixCSC, x::Number, I::AbstractVector{<:Integer}, j::Integer) (A[I, j] .= x; A) +@deprecate setindex!(A::SparseMatrixCSC, x, ::Colon) fill!(A, x) +@deprecate setindex!(A::SparseMatrixCSC, x, ::Colon, ::Colon) fill!(A, x) +@deprecate setindex!(A::SparseMatrixCSC, x, ::Colon, j::Union{Integer, AbstractVector}) (A[:, j] .= x; A) +@deprecate setindex!(A::SparseMatrixCSC, x, i::Union{Integer, AbstractVector}, ::Colon) (A[i, :] .= x; A) +@deprecate setindex!(A::SparseMatrixCSC, x::Number, I::AbstractVector{<:Integer}, J::AbstractVector{<:Integer}) (A[I, J] .= x; A) + #25395 keywords unlocked @deprecate dropzeros(x, trim) dropzeros(x, trim = trim) @deprecate dropzeros!(x, trim) dropzeros!(x, trim = trim) diff --git a/stdlib/SparseArrays/src/higherorderfns.jl b/stdlib/SparseArrays/src/higherorderfns.jl index 3ee447c8a2c54..a6509299d86e1 100644 --- a/stdlib/SparseArrays/src/higherorderfns.jl +++ b/stdlib/SparseArrays/src/higherorderfns.jl @@ -522,11 +522,16 @@ function _broadcast_notzeropres!(f::Tf, fillvalue, C::SparseVecOrMat, A::SparseV end # Cases with vertical expansion else # numrows(A) != numrows(C) (=> numrows(A) == 1) + svA, svC = storedvals(A), storedvals(C) @inbounds for (j, jo) in zip(columns(C), _densecoloffsets(C)) Ak, stopAk = numcols(A) == 1 ? (colstartind(A, 1), colboundind(A, 1)) : (colstartind(A, j), colboundind(A, j)) - Ax = Ak < stopAk ? storedvals(A)[Ak] : zero(eltype(A)) + Ax = Ak < stopAk ? svA[Ak] : zero(eltype(A)) fofAx = f(Ax) - fofAx != fillvalue && (storedvals(C)[(jo + 1):(jo + numrows(C))] = fofAx) + if fofAx != fillvalue + for i in (jo + 1):(jo + numrows(C)) + svC[i] = fofAx + end + end end end return C diff --git a/stdlib/SparseArrays/src/linalg.jl b/stdlib/SparseArrays/src/linalg.jl index 052a777445696..c304d3c3821fa 100644 --- a/stdlib/SparseArrays/src/linalg.jl +++ b/stdlib/SparseArrays/src/linalg.jl @@ -618,7 +618,7 @@ function normestinv(A::SparseMatrixCSC{T}, t::Integer = min(2,maximum(size(A)))) # Generate the block matrix X = Matrix{Ti}(undef, n, t) - X[1:n,1] = 1 + X[1:n,1] .= 1 for j = 2:t while true _rand_pm1!(view(X,1:n,j)) diff --git a/stdlib/SparseArrays/src/sparsematrix.jl b/stdlib/SparseArrays/src/sparsematrix.jl index 134897631050c..441c26bb6a20a 100644 --- a/stdlib/SparseArrays/src/sparsematrix.jl +++ b/stdlib/SparseArrays/src/sparsematrix.jl @@ -969,7 +969,7 @@ end function _ispermutationvalid_permute!(perm::AbstractVector{<:Integer}, checkspace::Vector{<:Integer}) n = length(perm) - checkspace[1:n] = 0 + checkspace[1:n] .= 0 for k in perm (0 < k ≤ n) && ((checkspace[k] ⊻= 1) == 1) || return false end @@ -2326,10 +2326,10 @@ getindex(A::SparseMatrixCSC, I::AbstractVector{<:Integer}, J::AbstractVector{Boo getindex(A::SparseMatrixCSC, I::AbstractVector{Bool}, J::AbstractVector{<:Integer}) = A[findall(I),J] ## setindex! -function setindex!(A::SparseMatrixCSC{Tv,Ti}, v, i::Integer, j::Integer) where Tv where Ti - setindex!(A, convert(Tv, v), convert(Ti, i), convert(Ti, j)) -end -function setindex!(A::SparseMatrixCSC{Tv,Ti}, v::Tv, i::Ti, j::Ti) where Tv where Ti<:Integer +function setindex!(A::SparseMatrixCSC{Tv,Ti}, _v, _i::Integer, _j::Integer) where Tv where Ti + v = convert(Tv, _v) + i = convert(Ti, _i) + j = convert(Ti, _j) if !((1 <= i <= A.m) & (1 <= j <= A.n)) throw(BoundsError(A, (i,j))) end @@ -2353,20 +2353,14 @@ function setindex!(A::SparseMatrixCSC{Tv,Ti}, v::Tv, i::Ti, j::Ti) where Tv wher return A end -setindex!(A::SparseMatrixCSC, v::AbstractMatrix, i::Integer, J::AbstractVector{<:Integer}) = setindex!(A, v, [i], J) -setindex!(A::SparseMatrixCSC, v::AbstractMatrix, I::AbstractVector{<:Integer}, j::Integer) = setindex!(A, v, I, [j]) - -setindex!(A::SparseMatrixCSC, x::Number, i::Integer, J::AbstractVector{<:Integer}) = setindex!(A, x, [i], J) -setindex!(A::SparseMatrixCSC, x::Number, I::AbstractVector{<:Integer}, j::Integer) = setindex!(A, x, I, [j]) +setindex!(A::SparseMatrixCSC, x::AbstractArray, ::Colon) = setindex!(A, x, 1:length(A)) +setindex!(A::SparseMatrixCSC, x::AbstractArray, ::Colon, ::Colon) = setindex!(A, x, 1:size(A, 1), 1:size(A,2)) +setindex!(A::SparseMatrixCSC, x::AbstractArray, ::Colon, j::Union{Integer, AbstractVector}) = setindex!(A, x, 1:size(A, 1), j) +setindex!(A::SparseMatrixCSC, x::AbstractArray, i::Union{Integer, AbstractVector}, ::Colon) = setindex!(A, x, i, 1:size(A, 2)) -# Colon translation -setindex!(A::SparseMatrixCSC, x, ::Colon) = setindex!(A, x, 1:length(A)) -setindex!(A::SparseMatrixCSC, x, ::Colon, ::Colon) = setindex!(A, x, 1:size(A, 1), 1:size(A,2)) -setindex!(A::SparseMatrixCSC, x, ::Colon, j::Union{Integer, AbstractVector}) = setindex!(A, x, 1:size(A, 1), j) -setindex!(A::SparseMatrixCSC, x, i::Union{Integer, AbstractVector}, ::Colon) = setindex!(A, x, i, 1:size(A, 2)) - -function setindex!(A::SparseMatrixCSC{Tv}, x::Number, - I::AbstractVector{<:Integer}, J::AbstractVector{<:Integer}) where Tv +function Base.fill!(V::SubArray{Tv, <:Any, <:SparseMatrixCSC, Tuple{Vararg{Union{Integer, AbstractVector{<:Integer}},2}}}, x) where Tv + A = V.parent + I, J = V.indices if isempty(I) || isempty(J); return A; end # lt=≤ to check for strict sorting if !issorted(I, lt=≤); I = sort!(unique(I)); end @@ -2385,7 +2379,7 @@ Helper method for immediately preceding setindex! method. For all (i,j) such tha j in J, assigns zero to A[i,j] if A[i,j] is a presently-stored entry, and otherwise does nothing. """ function _spsetz_setindex!(A::SparseMatrixCSC, - I::AbstractVector{<:Integer}, J::AbstractVector{<:Integer}) + I::Union{Integer, AbstractVector{<:Integer}}, J::Union{Integer, AbstractVector{<:Integer}}) lengthI = length(I) for j in J coljAfirstk = A.colptr[j] @@ -2421,7 +2415,7 @@ and j in J, assigns x to A[i,j] if A[i,j] is a presently-stored entry, and alloc assigns x to A[i,j] if A[i,j] is not presently stored. """ function _spsetnz_setindex!(A::SparseMatrixCSC{Tv}, x::Tv, - I::AbstractVector{<:Integer}, J::AbstractVector{<:Integer}) where Tv + I::Union{Integer, AbstractVector{<:Integer}}, J::Union{Integer, AbstractVector{<:Integer}}) where Tv m, n = size(A) lenI = length(I) @@ -2526,16 +2520,18 @@ function _spsetnz_setindex!(A::SparseMatrixCSC{Tv}, x::Tv, return A end -setindex!(A::SparseMatrixCSC{Tv,Ti}, S::Matrix, I::AbstractVector{T}, J::AbstractVector{T}) where {Tv,Ti,T<:Integer} = - setindex!(A, convert(SparseMatrixCSC{Tv,Ti}, S), I, J) +setindex!(A::SparseMatrixCSC{Tv,Ti}, S::Matrix, I::Integer, J::Integer) where {Tv,Ti} = setindex!(A, convert(Tv, S), I, J) +setindex!(A::SparseMatrixCSC{Tv,Ti}, S::Matrix, I::Union{Integer, AbstractVector{<:Integer}}, J::Union{Integer, AbstractVector{<:Integer}}) where {Tv,Ti} = + setindex!(A, convert(SparseMatrixCSC{Tv,Ti}, S), I, J) -setindex!(A::SparseMatrixCSC, v::AbstractVector, I::AbstractVector{<:Integer}, j::Integer) = setindex!(A, v, I, [j]) -setindex!(A::SparseMatrixCSC, v::AbstractVector, i::Integer, J::AbstractVector{<:Integer}) = setindex!(A, v, [i], J) -setindex!(A::SparseMatrixCSC, v::AbstractVector, I::AbstractVector{T}, J::AbstractVector{T}) where {T<:Integer} = - setindex!(A, reshape(v, length(I), length(J)), I, J) +setindex!(A::SparseMatrixCSC, v::AbstractVector, I::Integer, J::Integer) = setindex!(A, convert(Tv, v), I, J) +setindex!(A::SparseMatrixCSC, v::AbstractVector, I::Union{Integer, AbstractVector{<:Integer}}, J::Union{Integer, AbstractVector{<:Integer}}) = + setindex!(A, reshape(v, length(I), length(J)), I, J) -# A[I,J] = B -function setindex!(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}, I::AbstractVector{T}, J::AbstractVector{T}) where {Tv,Ti,T<:Integer} +# Nonscalar A[I,J] = B +setindex!(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}, I::Integer, J::Integer) where {Tv,Ti} = + setindex!(A, convert(Tv, I, J), I, J) +function setindex!(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}, I::Union{Integer, AbstractVector{<:Integer}}, J::Union{Integer, AbstractVector{<:Integer}}) where {Tv,Ti} if size(B,1) != length(I) || size(B,2) != length(J) throw(DimensionMismatch("")) end @@ -2585,7 +2581,7 @@ function setindex!(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}, I::Abst asgn_col = J[colB] I_asgn = falses(m) - I_asgn[I] = true + I_asgn[I] .= true ptrS = 1 @@ -2674,8 +2670,8 @@ setindex!(A::Matrix, x::SparseMatrixCSC, I::AbstractVector{Bool}, J::AbstractVec setindex!(A::Matrix, x::SparseMatrixCSC, I::AbstractVector{<:Integer}, J::AbstractVector{Bool}) = setindex!(A, Array(x), I, findall(J)) setindex!(A::Matrix, x::SparseMatrixCSC, I::AbstractVector{Bool}, J::AbstractVector{<:Integer}) = setindex!(A, Array(x), findall(I), J) -setindex!(A::SparseMatrixCSC, x, I::AbstractVector{Bool}) = throw(BoundsError()) -function setindex!(A::SparseMatrixCSC, x, I::AbstractMatrix{Bool}) +setindex!(A::SparseMatrixCSC, x::AbstractArray, I::AbstractVector{Bool}) = setindex!(A, x, findall(I)) +function setindex!(A::SparseMatrixCSC, x::AbstractArray, I::AbstractMatrix{Bool}) checkbounds(A, I) n = sum(I) (n == 0) && (return A) @@ -2692,7 +2688,7 @@ function setindex!(A::SparseMatrixCSC, x, I::AbstractMatrix{Bool}) for row in 1:A.m if I[row, col] - v = isa(x, AbstractArray) ? x[xidx] : x + v = x[xidx] xidx += 1 if r1 <= r2 @@ -2775,7 +2771,7 @@ function setindex!(A::SparseMatrixCSC, x, I::AbstractMatrix{Bool}) A end -function setindex!(A::SparseMatrixCSC, x, I::AbstractVector{<:Real}) +function setindex!(A::SparseMatrixCSC, x::AbstractArray, I::AbstractVector{<:Real}) n = length(I) (n == 0) && (return A) @@ -2800,7 +2796,7 @@ function setindex!(A::SparseMatrixCSC, x, I::AbstractVector{<:Real}) (sxidx < n) && (I[sxidx] == I[sxidx+1]) && continue row,col = Base._ind2sub(szA, I[sxidx]) - v = isa(x, AbstractArray) ? x[sxidx] : x + v = x[sxidx] if col > lastcol r1 = Int(colptrA[col]) diff --git a/stdlib/SparseArrays/src/sparsevector.jl b/stdlib/SparseArrays/src/sparsevector.jl index a1d2973d533ed..cb51a09e9725c 100644 --- a/stdlib/SparseArrays/src/sparsevector.jl +++ b/stdlib/SparseArrays/src/sparsevector.jl @@ -1799,7 +1799,7 @@ function _densifyfirstnztoend!(x::SparseVector) nzi = x.nzind[oldpos] nzv = x.nzval[oldpos] newpos = nzi - x.nzind[1] + 1 - newpos < nextpos && (x.nzval[newpos+1:nextpos] = 0) + newpos < nextpos && (x.nzval[newpos+1:nextpos] .= 0) newpos == oldpos && break x.nzval[newpos] = nzv nextpos = newpos - 1 @@ -1821,12 +1821,12 @@ function _densifystarttolastnz!(x::SparseVector) @inbounds for oldpos in oldnnz:-1:1 nzi = x.nzind[oldpos] nzv = x.nzval[oldpos] - nzi < nextpos && (x.nzval[nzi+1:nextpos] = 0) + nzi < nextpos && (x.nzval[nzi+1:nextpos] .= 0) nzi == oldpos && (nextpos = 0; break) x.nzval[nzi] = nzv nextpos = nzi - 1 end - nextpos > 0 && (x.nzval[1:nextpos] = 0) + nextpos > 0 && (x.nzval[1:nextpos] .= 0) # finally update lengthened nzinds x.nzind[1:newnnz] = 1:newnnz x diff --git a/stdlib/SparseArrays/test/sparse.jl b/stdlib/SparseArrays/test/sparse.jl index ba896ff3a705c..09d24e711fed8 100644 --- a/stdlib/SparseArrays/test/sparse.jl +++ b/stdlib/SparseArrays/test/sparse.jl @@ -16,7 +16,12 @@ end @testset "iszero specialization for SparseMatrixCSC" begin @test !iszero(sparse(I, 3, 3)) # test failure @test iszero(spzeros(3, 3)) # test success with no stored entries - @test iszero(setindex!(sparse(I, 3, 3), 0, :)) # test success with stored zeros + S = sparse(I, 3, 3) + S[:] .= 0 + @test iszero(S) # test success with stored zeros via broadcasting + S = sparse(I, 3, 3) + fill!(S, 0) + @test iszero(S) # test success with stored zeros via fill! @test iszero(SparseMatrixCSC(2, 2, [1,2,3], [1,2], [0,0,1])) # test success with nonzeros beyond data range end @testset "isone specialization for SparseMatrixCSC" begin @@ -148,8 +153,8 @@ let @testset "sparse assignment" begin p = [4, 1, 3] - a116[p, p] = -1 - s116[p, p] = -1 + a116[p, p] .= -1 + s116[p, p] .= -1 @test a116 == s116 p = [2, 1, 4] @@ -747,10 +752,10 @@ end @testset "setindex" begin a = spzeros(Int, 10, 10) @test count(!iszero, a) == 0 - a[1,:] = 1 + a[1,:] .= 1 @test count(!iszero, a) == 10 @test a[1,:] == sparse(fill(1,10)) - a[:,2] = 2 + a[:,2] .= 2 @test count(!iszero, a) == 19 @test a[:,2] == sparse(fill(2,10)) b = copy(a) @@ -764,20 +769,20 @@ end @test count(!iszero, a) == 18 # Zero-assignment behavior of setindex!(A, v, I, J) - a[1,:] = 0 + a[1,:] .= 0 @test nnz(a) == 19 @test count(!iszero, a) == 9 - a[2,:] = 0 + a[2,:] .= 0 @test nnz(a) == 19 @test count(!iszero, a) == 8 - a[:,1] = 0 + a[:,1] .= 0 @test nnz(a) == 19 @test count(!iszero, a) == 8 - a[:,2] = 0 + a[:,2] .= 0 @test nnz(a) == 19 @test count(!iszero, a) == 0 a = copy(b) - a[:,:] = 0 + a[:,:] .= 0 @test nnz(a) == 19 @test count(!iszero, a) == 0 @@ -806,13 +811,13 @@ end @test a[1,:] == sparse([1; 1; 3:10]) a[1:0,2] = [] @test a[:,2] == sparse([1:10;]) - a[1,1:0] = 0 + a[1,1:0] .= 0 @test a[1,:] == sparse([1; 1; 3:10]) - a[1:0,2] = 0 + a[1:0,2] .= 0 @test a[:,2] == sparse([1:10;]) - a[1,1:0] = 1 + a[1,1:0] .= 1 @test a[1,:] == sparse([1; 1; 3:10]) - a[1:0,2] = 1 + a[1:0,2] .= 1 @test a[:,2] == sparse([1:10;]) @test_throws BoundsError a[:,11] = spzeros(10,1) @@ -820,16 +825,16 @@ end @test_throws BoundsError a[:,-1] = spzeros(10,1) @test_throws BoundsError a[-1,:] = spzeros(1,10) @test_throws BoundsError a[0:9] = spzeros(1,10) - @test_throws BoundsError a[:,11] = 0 - @test_throws BoundsError a[11,:] = 0 - @test_throws BoundsError a[:,-1] = 0 - @test_throws BoundsError a[-1,:] = 0 - @test_throws BoundsError a[0:9] = 0 - @test_throws BoundsError a[:,11] = 1 - @test_throws BoundsError a[11,:] = 1 - @test_throws BoundsError a[:,-1] = 1 - @test_throws BoundsError a[-1,:] = 1 - @test_throws BoundsError a[0:9] = 1 + @test_throws BoundsError (a[:,11] .= 0; a) + @test_throws BoundsError (a[11,:] .= 0; a) + @test_throws BoundsError (a[:,-1] .= 0; a) + @test_throws BoundsError (a[-1,:] .= 0; a) + @test_throws BoundsError (a[0:9] .= 0; a) + @test_throws BoundsError (a[:,11] .= 1; a) + @test_throws BoundsError (a[11,:] .= 1; a) + @test_throws BoundsError (a[:,-1] .= 1; a) + @test_throws BoundsError (a[-1,:] .= 1; a) + @test_throws BoundsError (a[0:9] .= 1; a) @test_throws DimensionMismatch a[1:2,1:2] = 1:3 @test_throws DimensionMismatch a[1:2,1] = 1:3 @@ -837,16 +842,16 @@ end @test_throws DimensionMismatch a[1:2] = 1:3 A = spzeros(Int, 10, 20) - A[1:5,1:10] = 10 - A[1:5,1:10] = 10 + A[1:5,1:10] .= 10 + A[1:5,1:10] .= 10 @test count(!iszero, A) == 50 @test A[1:5,1:10] == fill(10, 5, 10) - A[6:10,11:20] = 0 + A[6:10,11:20] .= 0 @test count(!iszero, A) == 50 - A[6:10,11:20] = 20 + A[6:10,11:20] .= 20 @test count(!iszero, A) == 100 @test A[6:10,11:20] == fill(20, 5, 10) - A[4:8,8:16] = 15 + A[4:8,8:16] .= 15 @test count(!iszero, A) == 121 @test A[4:8,8:16] == fill(15, 5, 9) @@ -857,13 +862,13 @@ end nA = count(!iszero, A) x = A[1:TSZ, 1:(2*TSZ)] nx = count(!iszero, x) - A[1:TSZ, 1:(2*TSZ)] = 0 + A[1:TSZ, 1:(2*TSZ)] .= 0 nB = count(!iszero, A) @test nB == (nA - nx) A[1:TSZ, 1:(2*TSZ)] = x @test count(!iszero, A) == nA @test A == B - A[1:TSZ, 1:(2*TSZ)] = 10 + A[1:TSZ, 1:(2*TSZ)] .= 10 @test count(!iszero, A) == nB + 2*TSZ*TSZ A[1:TSZ, 1:(2*TSZ)] = x @test count(!iszero, A) == nA @@ -902,22 +907,22 @@ end sumS1 = sum(S) sumFI = sum(S[FI]) nnzS1 = nnz(S) - S[FI] = 0 + S[FI] .= 0 sumS2 = sum(S) cnzS2 = count(!iszero, S) @test sum(S[FI]) == 0 @test nnz(S) == nnzS1 @test (sum(S) + sumFI) == sumS1 - S[FI] = 10 + S[FI] .= 10 nnzS3 = nnz(S) @test sum(S) == sumS2 + 10*sum(FI) - S[FI] = 0 + S[FI] .= 0 @test sum(S) == sumS2 @test nnz(S) == nnzS3 @test count(!iszero, S) == cnzS2 - S[FI] = [1:sum(FI);] + S[FI] .= [1:sum(FI);] @test sum(S) == sumS2 + sum(1:sum(FI)) S = sprand(50, 30, 0.5, x -> round.(Int, rand(x) * 100)) @@ -926,9 +931,9 @@ end J = randperm(N) sumS1 = sum(S) sumS2 = sum(S[I]) - S[I] = 0 + S[I] .= 0 @test sum(S) == (sumS1 - sumS2) - S[I] = J + S[I] .= J @test sum(S) == (sumS1 - sumS2 + sum(J)) end end @@ -936,8 +941,8 @@ end @testset "dropstored!" begin A = spzeros(Int, 10, 10) # Introduce nonzeros in row and column two - A[1,:] = 1 - A[:,2] = 2 + A[1,:] .= 1 + A[:,2] .= 2 @test nnz(A) == 19 # Test argument bounds checking for dropstored!(A, i, j) @@ -968,8 +973,8 @@ end SparseArrays.dropstored!(A, :, 2) @test nnz(A) == 0 # --> Introduce nonzeros in rows one and two and columns two and three - A[1:2,:] = 1 - A[:,2:3] = 2 + A[1:2,:] .= 1 + A[:,2:3] .= 2 @test nnz(A) == 36 # --> Test dropping multiple rows containing stored and nonstored entries SparseArrays.dropstored!(A, 1:3, :) @@ -978,7 +983,7 @@ end SparseArrays.dropstored!(A, :, 2:4) @test nnz(A) == 0 # --> Introduce nonzeros in every other row - A[1:2:9, :] = 1 + A[1:2:9, :] .= 1 @test nnz(A) == 50 # --> Test dropping a block of the matrix towards the upper left SparseArrays.dropstored!(A, 2:5, 2:5) @@ -1419,9 +1424,12 @@ end struczerosA = findall(x -> x == 0, A) poszerosinds = unique(rand(struczerosA, targetnumposzeros)) negzerosinds = unique(rand(struczerosA, targetnumnegzeros)) - Aposzeros = setindex!(copy(A), 2, poszerosinds) - Anegzeros = setindex!(copy(A), -2, negzerosinds) - Abothsigns = setindex!(copy(Aposzeros), -2, negzerosinds) + Aposzeros = copy(A) + Aposzeros[poszerosinds] .= 2 + Anegzeros = copy(A) + Anegzeros[negzerosinds] .= -2 + Abothsigns = copy(Aposzeros) + Abothsigns[negzerosinds] .= -2 map!(x -> x == 2 ? 0.0 : x, Aposzeros.nzval, Aposzeros.nzval) map!(x -> x == -2 ? -0.0 : x, Anegzeros.nzval, Anegzeros.nzval) map!(x -> x == 2 ? 0.0 : x == -2 ? -0.0 : x, Abothsigns.nzval, Abothsigns.nzval) @@ -1598,21 +1606,21 @@ end @test A1!=A2 nonzeros(A1)[end]=1 @test A1==A2 - A1[1:4,end] = 1 + A1[1:4,end] .= 1 @test A1!=A2 - nonzeros(A1)[end-4:end-1]=0 + nonzeros(A1)[end-4:end-1].=0 @test A1==A2 - A2[1:4,end-1] = 1 + A2[1:4,end-1] .= 1 @test A1!=A2 - nonzeros(A2)[end-5:end-2]=0 + nonzeros(A2)[end-5:end-2].=0 @test A1==A2 - A2[2:3,1] = 1 + A2[2:3,1] .= 1 @test A1!=A2 - nonzeros(A2)[2:3]=0 + nonzeros(A2)[2:3].=0 @test A1==A2 - A1[2:5,1] = 1 + A1[2:5,1] .= 1 @test A1!=A2 - nonzeros(A1)[2:5]=0 + nonzeros(A1)[2:5].=0 @test A1==A2 @test sparse([1,1,0])!=sparse([0,1,1]) end @@ -1946,11 +1954,11 @@ end @testset "setindex issue #20657" begin local A = spzeros(3, 3) I = [1, 1, 1]; J = [1, 1, 1] - A[I, 1] = 1 + A[I, 1] .= 1 @test nnz(A) == 1 - A[1, J] = 1 + A[1, J] .= 1 @test nnz(A) == 1 - A[I, J] = 1 + A[I, J] .= 1 @test nnz(A) == 1 end diff --git a/stdlib/SparseArrays/test/sparsevector.jl b/stdlib/SparseArrays/test/sparsevector.jl index 45f82ae14427f..8ad9273fe6f96 100644 --- a/stdlib/SparseArrays/test/sparsevector.jl +++ b/stdlib/SparseArrays/test/sparsevector.jl @@ -208,7 +208,7 @@ end let x = sprand(10, 10, 0.5) I = rand(1:size(x, 2), 10) bI = falses(size(x, 2)) - bI[I] = true + bI[I] .= true r = x[1,bI] @test isa(r, SparseVector{Float64,Int}) @test all(!iszero, nonzeros(r)) @@ -218,7 +218,7 @@ end let x = sprand(10, 0.5) I = rand(1:length(x), 5) bI = falses(length(x)) - bI[I] = true + bI[I] .= true r = x[bI] @test isa(r, SparseVector{Float64,Int}) @test all(!iszero, nonzeros(r)) @@ -1045,9 +1045,12 @@ end struczerosv = findall(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) + vposzeros = copy(v) + vposzeros[poszerosinds] .= 2 + vnegzeros = copy(v) + vnegzeros[negzerosinds] .= -2 + vbothsigns = copy(vposzeros) + vbothsigns[negzerosinds] .= -2 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) @@ -1067,7 +1070,7 @@ end end # original dropzeros! test xdrop = sparsevec(1:7, [3., 2., -1., 1., -2., -3., 3.], 7) - xdrop.nzval[[2, 4, 6]] = 0.0 + xdrop.nzval[[2, 4, 6]] .= 0.0 SparseArrays.dropzeros!(xdrop) @test exact_equal(xdrop, SparseVector(7, [1, 3, 5, 7], [3, -1., -2., 3.])) end diff --git a/stdlib/SuiteSparse/src/spqr.jl b/stdlib/SuiteSparse/src/spqr.jl index edb22812ec643..05467cdc4bef0 100644 --- a/stdlib/SuiteSparse/src/spqr.jl +++ b/stdlib/SuiteSparse/src/spqr.jl @@ -381,7 +381,7 @@ function _ldiv_basic(F::QRSparse, B::StridedVecOrMat) LinearAlgebra.lmul!(adjoint(F.Q), X0) # Zero out to get basic solution - X[rnk + 1:end, :] = 0 + X[rnk + 1:end, :] .= 0 # Solve R*X = B LinearAlgebra.ldiv!(UpperTriangular(view(F.R, Base.OneTo(rnk), Base.OneTo(rnk))), diff --git a/test/arrayops.jl b/test/arrayops.jl index bd20fe6cd35be..2061d100712a7 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -54,13 +54,13 @@ using Random, LinearAlgebra b = copy(a') @test a[1,1] == 1. && a[1,2] == 2. && a[2,1] == 3. && a[2,2] == 4. @test b[1,1] == 1. && b[2,1] == 2. && b[1,2] == 3. && b[2,2] == 4. - a[[1 2 3 4]] = 0 + a[[1 2 3 4]] .= 0 @test a == zeros(2,2) - a[[1 2], [1 2]] = 1 + a[[1 2], [1 2]] .= 1 @test a == fill(1.,2,2) - a[[1 2], 1] = 0 + a[[1 2], 1] .= 0 @test a[1,1] == 0. && a[1,2] == 1. && a[2,1] == 0. && a[2,2] == 1. - a[:, [1 2]] = 2 + a[:, [1 2]] .= 2 @test a == fill(2.,2,2) a = Array{Float64}(undef, 2, 2, 2, 2, 2) @@ -301,7 +301,7 @@ end @test B == [0 0 1 0 0; 11 12 13 14 15; 0 0 3 0 0; 0 0 4 0 0] B[[3,1],[2,4]] = [21 22; 23 24] @test B == [0 23 1 24 0; 11 12 13 14 15; 0 21 3 22 0; 0 0 4 0 0] - B[4,[2,3]] = 7 + B[4,[2,3]] .= 7 @test B == [0 23 1 24 0; 11 12 13 14 15; 0 21 3 22 0; 0 7 7 0 0] @test isequal(reshape(reshape(1:27, 3, 3, 3), Val(2))[1,:], [1, 4, 7, 10, 13, 16, 19, 22, 25]) @@ -916,7 +916,7 @@ end @test_throws BoundsError [1:5;][[true,false,true,false]] @test_throws BoundsError [1:5;][[true,false,true,false,true,false]] a = [1:5;] - a[[true,false,true,false,true]] = 6 + a[[true,false,true,false,true]] .= 6 @test a == [6,2,6,4,6] a[[true,false,true,false,true]] = [7,8,9] @test a == [7,2,8,4,9] @@ -933,7 +933,7 @@ end @test A == [1 1 1 1 1; 2 1 3 4 1; 1 1 1 1 1] @test_throws DimensionMismatch A[[true,false,true], 5] = [19] @test_throws DimensionMismatch A[[true,false,true], 5] = 19:21 - A[[true,false,true], 5] = 7 + A[[true,false,true], 5] .= 7 @test A == [1 1 1 1 7; 2 1 3 4 1; 1 1 1 1 7] B = cat(3, 1, 2, 3) @@ -1050,7 +1050,7 @@ end end a = [1,3,5] b = [1 3] - a[b] = 8 + a[b] .= 8 @test a == [8,3,8] end @@ -1642,7 +1642,7 @@ end @test a[1,CartesianIndex{2}(3,4)] == -2 a[CartesianIndex{1}(2),3,CartesianIndex{1}(3)] = -3 @test a[CartesianIndex{1}(2),3,CartesianIndex{1}(3)] == -3 - a[[CartesianIndex(1,3),CartesianIndex(2,4)],3:3] = -4 + a[[CartesianIndex(1,3),CartesianIndex(2,4)],3:3] .= -4 @test a[1,3,3] == -4 @test a[2,4,3] == -4 end @@ -1983,7 +1983,7 @@ copyto!(S, A) # issue #13250 x13250 = zeros(3) -x13250[UInt(1):UInt(2)] = 1.0 +x13250[UInt(1):UInt(2)] .= 1.0 @test x13250[1] == 1.0 @test x13250[2] == 1.0 @test x13250[3] == 0.0 @@ -2323,7 +2323,7 @@ Float64(x::F21666) = Float64(x.x) # test that cumsum uses more stable algorithm # for types with unknown/rounding arithmetic # we make v pretty large, because stable algorithm may have a large base case - v = zeros(300); v[1] = 2; v[200:end] = eps(Float32) + v = zeros(300); v[1] = 2; v[200:end] .= eps(Float32) f_rounds = Float64.(cumsum(F21666{Base.ArithmeticRounds}.(v))) f_unknown = Float64.(cumsum(F21666{Base.ArithmeticUnknown}.(v))) diff --git a/test/bitarray.jl b/test/bitarray.jl index f88a5d8a02913..6c3ee50c7561b 100644 --- a/test/bitarray.jl +++ b/test/bitarray.jl @@ -12,6 +12,7 @@ tc(r1,r2) = false bitcheck(b::BitArray) = Test._check_bitarray_consistency(b) bitcheck(x) = true +bcast_setindex!(b, x, I...) = (b[I...] .= x; b) function check_bitop_call(ret_type, func, args...; kwargs...) r1 = func(args...; kwargs...) @@ -156,7 +157,7 @@ timesofar("conversions") b1 = bitrand(v1) @test_throws BoundsError resize!(b1, -1) @check_bit_operation resize!(b1, v1 ÷ 2) BitVector - gr(b) = (resize!(b, v1)[(v1÷2):end] = 1; b) + gr(b) = (resize!(b, v1)[(v1÷2):end] .= 1; b) @check_bit_operation gr(b1) BitVector end @@ -251,39 +252,41 @@ timesofar("constructors") for j in [1, 63, 64, 65, 127, 128, 129, 191, 192, 193, l-1] x = rand(Bool) - @check_bit_operation setindex!(b1, x, 1:j) T + @check_bit_operation fill!(b1, x) T + rand!(b1) + @check_bit_operation bcast_setindex!(b1, x, 1:j) b2 = bitrand(j) for bb in (b2, view(b2, 1:j), view(Array{Any}(b2), :)) @check_bit_operation setindex!(b1, bb, 1:j) T end x = rand(Bool) - @check_bit_operation setindex!(b1, x, j+1:l) T + @check_bit_operation bcast_setindex!(b1, x, j+1:l) T b2 = bitrand(l-j) @check_bit_operation setindex!(b1, b2, j+1:l) T end for j in [1, 63, 64, 65, 127, 128, 129, div(l,2)] m1 = j:(l-j) x = rand(Bool) - @check_bit_operation setindex!(b1, x, m1) T + @check_bit_operation bcast_setindex!(b1, x, m1) T b2 = bitrand(length(m1)) @check_bit_operation setindex!(b1, b2, m1) T end x = rand(Bool) - @check_bit_operation setindex!(b1, x, 1:100) T + @check_bit_operation bcast_setindex!(b1, x, 1:100) T b2 = bitrand(100) @check_bit_operation setindex!(b1, b2, 1:100) T y = rand(0.0:1.0) - @check_bit_operation setindex!(b1, y, 1:100) T + @check_bit_operation bcast_setindex!(b1, y, 1:100) T t1 = findall(bitrand(l)) x = rand(Bool) - @check_bit_operation setindex!(b1, x, t1) T + @check_bit_operation bcast_setindex!(b1, x, t1) T b2 = bitrand(length(t1)) @check_bit_operation setindex!(b1, b2, t1) T y = rand(0.0:1.0) - @check_bit_operation setindex!(b1, y, t1) T + @check_bit_operation bcast_setindex!(b1, y, t1) T end @testset "multidimensional" begin @@ -405,8 +408,16 @@ timesofar("constructors") for (b2, k1, k2) in Channel(gen_setindex_data) # println(typeof(b2), " ", typeof(k1), " ", typeof(k2)) # uncomment to debug - for bb in ((b2 isa AbstractArray) ? (b2, view(b2, :), view(Array{Any}(b2), :)) : (b2,)) - @check_bit_operation setindex!(b1, bb, k1, k2) BitMatrix + if b2 isa AbstractArray + for bb in (b2, view(b2, :), view(Array{Any}(b2), :)) + @check_bit_operation setindex!(b1, bb, k1, k2) BitMatrix + end + else + if k1 isa Integer && k2 isa Integer + @check_bit_operation setindex!(b1, b2, k1, k2) BitMatrix + else + @check_bit_operation bcast_setindex!(b1, b2, k1, k2) BitMatrix + end end end @@ -415,7 +426,7 @@ timesofar("constructors") @check_bit_operation setindex!(b1, b2, m1, 1:m2) BitMatrix x = rand(Bool) b2 = bitrand(1, m2, 1) - @check_bit_operation setindex!(b1, x, m1, 1:m2, 1) BitMatrix + @check_bit_operation bcast_setindex!(b1, x, m1, 1:m2, 1) BitMatrix @check_bit_operation setindex!(b1, b2, m1, 1:m2, 1) BitMatrix b1 = bitrand(s1, s2, s3, s4) @@ -461,7 +472,11 @@ timesofar("constructors") for (b2, k1, k2, k3, k4) in Channel(gen_setindex_data4) # println(typeof(b2), " ", typeof(k1), " ", typeof(k2), " ", typeof(k3), " ", typeof(k4)) # uncomment to debug - @check_bit_operation setindex!(b1, b2, k1, k2, k3, k4) BitArray{4} + if b2 isa Bool + @check_bit_operation bcast_setindex!(b1, b2, k1, k2, k3, k4) BitArray{4} + else + @check_bit_operation setindex!(b1, b2, k1, k2, k3, k4) BitArray{4} + end end for p1 = [rand(1:v1) 1 63 64 65 191 192 193] @@ -489,7 +504,7 @@ timesofar("constructors") b1 = bitrand(n1, n2) t1 = bitrand(n1, n2) - @check_bit_operation setindex!(b1, true, t1) BitMatrix + @check_bit_operation bcast_setindex!(b1, true, t1) BitMatrix t1 = bitrand(n1, n2) b2 = bitrand(count(t1)) diff --git a/test/copy.jl b/test/copy.jl index fd0128c2a661a..80a83ed7b2cab 100644 --- a/test/copy.jl +++ b/test/copy.jl @@ -61,7 +61,7 @@ end RA = CartesianIndices(axes(A)) copyto!(B, CartesianIndices((5:7,2:3)), A, RA) @test B[5:7,2:3] == A - B[5:7,2:3] = 0 + B[5:7,2:3] .= 0 @test all(x->x==0, B) end end diff --git a/test/subarray.jl b/test/subarray.jl index 2b5ab06fc36ff..12aa0464ace42 100644 --- a/test/subarray.jl +++ b/test/subarray.jl @@ -354,7 +354,7 @@ sA = view(A, 2:2, 1:5, :) @test size(sA) == (1, 5, 8) @test axes(sA) === (Base.OneTo(1), Base.OneTo(5), Base.OneTo(8)) @test sA[1, 2, 1:8][:] == [5:15:120;] -sA[2:5:end] = -1 +sA[2:5:end] .= -1 @test all(sA[2:5:end] .== -1) @test all(A[5:15:120] .== -1) @test @inferred(strides(sA)) == (1,3,15) @@ -363,10 +363,12 @@ sA[2:5:end] = -1 test_bounds(sA) sA = view(A, 1:3, 1:5, 5) @test Base.parentdims(sA) == [1:2;] -sA[1:3,1:5] = -2 +sA[1:3,1:5] .= -2 @test all(A[:,:,5] .== -2) -sA[:] = -3 +fill!(sA, -3) @test all(A[:,:,5] .== -3) +sA[:] .= 4 +@test all(A[:,:,5] .== 4) @test @inferred(strides(sA)) == (1,3) test_bounds(sA) sA = view(A, 1:3, 3:3, 2:5) @@ -413,7 +415,7 @@ sA = view(A, 2, :, 1:8) @test sA[2, 1:8][:] == [5:15:120;] @test sA[:,1] == [2:3:14;] @test sA[2:5:end] == [5:15:110;] -sA[2:5:end] = -1 +sA[2:5:end] .= -1 @test all(sA[2:5:end] .== -1) @test all(A[5:15:120] .== -1) test_bounds(sA) @@ -441,7 +443,7 @@ A = rand(2, 2, 3) msk = fill(true, 2, 2) msk[2,1] = false sA = view(A, :, :, 1) -sA[msk] = 1.0 +sA[msk] .= 1.0 @test sA[msk] == fill(1, count(msk)) # bounds checking upon construction; see #4044, #10296 @@ -531,7 +533,7 @@ end @test x[1:3] isa SubArray @test x[2] === 11 @test Dict((1:3) => 4)[1:3] === 4 - x[1:2] = 0 + x[1:2] .= 0 @test x == [0,0,19,4] x[1:2] .= 5:6 @test x == [5,6,19,4]