Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate broadcast_(get|set)index in favor of broadcasted (get|set)index #27075

Merged
merged 2 commits into from
May 14, 2018
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
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,9 @@ Deprecated or removed
using the broadcasted assignment syntax `A[I...] .= x` or `fill!(view(A, I...), x)`
([#26347]).

* `broadcast_getindex(A, I...)` and `broadcast_setindex!(A, v, I...)` are deprecated in
favor of `getindex.((A,), I...)` and `setindex!.((A,), v, I...)`, respectively ([#27075]).

* `LinAlg.fillslots!` has been renamed `LinAlg.fillstored!` ([#25030]).

* `fill!(A::Diagonal, x)` and `fill!(A::AbstractTriangular, x)` have been deprecated
Expand Down
121 changes: 1 addition & 120 deletions base/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ using .Base: Indices, OneTo, tail, to_shape, isoperator, promote_typejoin,
_msk_end, unsafe_bitgetindex, bitcache_chunks, bitcache_size, dumpbitcache, unalias
import .Base: copy, copyto!
export broadcast, broadcast!, BroadcastStyle, broadcast_axes, broadcast_similar, broadcastable,
broadcast_getindex, broadcast_setindex!, dotview, @__dot__
dotview, @__dot__

### Objects with customized broadcasting behavior should declare a BroadcastStyle

Expand Down Expand Up @@ -1018,125 +1018,6 @@ broadcasted(::DefaultArrayStyle{1}, ::typeof(big), r::StepRange) = big(r.start):
broadcasted(::DefaultArrayStyle{1}, ::typeof(big), r::StepRangeLen) = StepRangeLen(big(r.ref), big(r.step), length(r), r.offset)
broadcasted(::DefaultArrayStyle{1}, ::typeof(big), r::LinRange) = LinRange(big(r.start), big(r.stop), length(r))


"""
broadcast_getindex(A, inds...)
Equivalent to [`broadcast`](@ref)ing the `inds` arrays to a common size
and returning an array `[A[ks...] for ks in zip(indsb...)]` (where `indsb`
would be the broadcast `inds`). The shape of the output is equal to the shape of each
element of `indsb`.
# Examples
```jldoctest bc_getindex
julia> A = [11 12; 21 22]
2×2 Array{Int64,2}:
11 12
21 22
julia> A[1:2, 1:2]
2×2 Array{Int64,2}:
11 12
21 22
julia> broadcast_getindex(A, 1:2, 1:2)
2-element Array{Int64,1}:
11
22
julia> A[1:2, 2:-1:1]
2×2 Array{Int64,2}:
12 11
22 21
julia> broadcast_getindex(A, 1:2, 2:-1:1)
2-element Array{Int64,1}:
12
21
```
Because the indices are all vectors, these calls are like `[A[i[k], j[k]] for k = 1:2]`
where `i` and `j` are the two index vectors.
```jldoctest bc_getindex
julia> broadcast_getindex(A, 1:2, (1:2)')
2×2 Array{Int64,2}:
11 12
21 22
julia> broadcast_getindex(A, (1:2)', 1:2)
2×2 Array{Int64,2}:
11 21
12 22
julia> broadcast_getindex(A, [1 2 1; 1 2 2], [1, 2])
2×3 Array{Int64,2}:
11 21 11
12 22 22
```
"""
broadcast_getindex(src::AbstractArray, I::AbstractArray...) =
broadcast_getindex!(Base.similar(Array{eltype(src)}, combine_axes(I...)), src, I...)

@generated function broadcast_getindex!(dest::AbstractArray, src::AbstractArray, I::AbstractArray...)
N = length(I)
Isplat = Expr[:(I[$d]) for d = 1:N]
quote
@nexprs $N d->(I_d = I[d])
check_broadcast_axes(Base.axes(dest), $(Isplat...)) # unnecessary if this function is never called directly
checkbounds(src, $(Isplat...))
@nexprs $N d->(@nexprs $N k->(Ibcast_d_k = Base.axes(I_k, d) == OneTo(1)))
@nloops $N i dest d->(@nexprs $N k->(j_d_k = Ibcast_d_k ? 1 : i_d)) begin
@nexprs $N k->(@inbounds J_k = @nref $N I_k d->j_d_k)
@inbounds (@nref $N dest i) = (@nref $N src J)
end
dest
end
end

"""
broadcast_setindex!(A, X, inds...)
Efficient element-by-element setting of the values of `A` in a pattern established by `inds`.
Equivalent to broadcasting the `X` and `inds` arrays to a common size, and then executing
for (is, js) in zip(zip(indsb), eachindex(Xb))
A[is...] = Xb[js...]
end
where `Xb` and `indsb` are the broadcast `X` and `inds`.
See [`broadcast_getindex`](@ref) for examples of the treatment of `inds`.
"""
@generated function broadcast_setindex!(A::AbstractArray, x, I::AbstractArray...)
N = length(I)
Isplat = Expr[:(I[$d]) for d = 1:N]
quote
@nexprs $N d->(I_d = I[d])
checkbounds(A, $(Isplat...))
shape = combine_axes($(Isplat...))
@nextract $N shape d->(length(shape) < d ? OneTo(1) : shape[d])
@nexprs $N d->(@nexprs $N k->(Ibcast_d_k = Base.axes(I_k, d) == 1:1))
if !isa(x, AbstractArray)
xA = convert(eltype(A), x)
@nloops $N i d->shape_d d->(@nexprs $N k->(j_d_k = Ibcast_d_k ? 1 : i_d)) begin
@nexprs $N k->(@inbounds J_k = @nref $N I_k d->j_d_k)
@inbounds (@nref $N A J) = xA
end
else
X = x
@nexprs $N d->(shapelen_d = length(shape_d))
@ncall $N Base.setindex_shape_check X shapelen
Xstate = start(X)
@inbounds @nloops $N i d->shape_d d->(@nexprs $N k->(j_d_k = Ibcast_d_k ? 1 : i_d)) begin
@nexprs $N k->(J_k = @nref $N I_k d->j_d_k)
x_el, Xstate = next(X, Xstate)
(@nref $N A J) = x_el
end
end
A
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}
Expand Down
4 changes: 4 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1631,6 +1631,10 @@ end
@deprecate showcompact(io, x) show(IOContext(io, :compact => true), x)
@deprecate sprint(::typeof(showcompact), args...) sprint(show, args...; context=:compact => true)

# PR 27075
@deprecate broadcast_getindex(A, I...) getindex.((A,), I...)
@deprecate broadcast_setindex!(A, v, I...) setindex!.((A,), v, I...)

@deprecate isupper isuppercase
@deprecate islower islowercase
@deprecate ucfirst uppercasefirst
Expand Down
2 changes: 0 additions & 2 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,6 @@ export
axes,
broadcast!,
broadcast,
broadcast_getindex,
broadcast_setindex!,
cat,
checkbounds,
checkindex,
Expand Down
2 changes: 0 additions & 2 deletions doc/src/base/arrays.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ to operate on arrays, you should use `sin.(a)` to vectorize via `broadcast`.
Base.broadcast
Base.Broadcast.broadcast!
Base.@__dot__
Base.Broadcast.broadcast_getindex
Base.Broadcast.broadcast_setindex!
```

For specializing broadcast on custom types, see
Expand Down
3 changes: 1 addition & 2 deletions doc/src/manual/arrays.md
Original file line number Diff line number Diff line change
Expand Up @@ -654,8 +654,7 @@ julia> broadcast(+, a, b)
[Dotted operators](@ref man-dot-operators) such as `.+` and `.*` are equivalent
to `broadcast` calls (except that they fuse, as described below). There is also a
[`broadcast!`](@ref) function to specify an explicit destination (which can also
be accessed in a fusing fashion by `.=` assignment), and functions [`broadcast_getindex`](@ref)
and [`broadcast_setindex!`](@ref) that broadcast the indices before indexing. Moreover, `f.(args...)`
be accessed in a fusing fashion by `.=` assignment). Moreover, `f.(args...)`
is equivalent to `broadcast(f, args...)`, providing a convenient syntax to broadcast any function
([dot syntax](@ref man-vectorized)). Nested "dot calls" `f.(...)` (including calls to `.+` etcetera)
[automatically fuse](@ref man-dot-operators) into a single `broadcast` call.
Expand Down
18 changes: 9 additions & 9 deletions test/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,22 @@ for arr in (identity, as_sub)
@test arr(BitArray([true false])) .^ arr([0, 3]) == [true true; true false]

M = arr([11 12; 21 22])
@test broadcast_getindex(M, [2 1; 1 2], arr([1, 2])) == [21 11; 12 22]
@test_throws BoundsError broadcast_getindex(M, [2 1; 1 2], arr([1, -1]))
@test_throws BoundsError broadcast_getindex(M, [2 1; 1 2], arr([1, 2]), [2])
@test broadcast_getindex(M, [2 1; 1 2],arr([2, 1]), [1]) == [22 12; 11 21]
@test getindex.((M,), [2 1; 1 2], arr([1, 2])) == [21 11; 12 22]
@test_throws BoundsError getindex.((M,), [2 1; 1 2], arr([1, -1]))
@test_throws BoundsError getindex.((M,), [2 1; 1 2], arr([1, 2]), [2])
@test getindex.((M,), [2 1; 1 2],arr([2, 1]), [1]) == [22 12; 11 21]

A = arr(zeros(2,2))
broadcast_setindex!(A, arr([21 11; 12 22]), [2 1; 1 2], arr([1, 2]))
setindex!.((A,), arr([21 11; 12 22]), [2 1; 1 2], arr([1, 2]))
@test A == M
broadcast_setindex!(A, 5, [1,2], [2 2])
setindex!.((A,), 5, [1,2], [2 2])
@test A == [11 5; 21 5]
broadcast_setindex!(A, 7, [1,2], [1 2])
setindex!.((A,), 7, [1,2], [1 2])
@test A == fill(7, 2, 2)
A = arr(zeros(3,3))
broadcast_setindex!(A, 10:12, 1:3, 1:3)
setindex!.((A,), 10:12, 1:3, 1:3)
@test A == [10 0 0; 0 11 0; 0 0 12]
@test_throws BoundsError broadcast_setindex!(A, 7, [1,-1], [1 2])
@test_throws BoundsError setindex!.((A,), 7, [1,-1], [1 2])

for f in ((==), (<) , (!=), (<=))
bittest(f, arr([1 0; 0 1]), arr([1, 4]))
Expand Down