Skip to content

Commit aff4c78

Browse files
committed
Deprecate manually vectorized mod methods in favor of compact broadcast syntax.
1 parent a6a8946 commit aff4c78

File tree

5 files changed

+82
-36
lines changed

5 files changed

+82
-36
lines changed

base/arraymath.jl

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ promote_array_type{S<:Integer}(::typeof(./), ::Type{S}, ::Type{Bool}, T::Type) =
5252
promote_array_type{S<:Integer}(::typeof(.\), ::Type{S}, ::Type{Bool}, T::Type) = T
5353
promote_array_type{S<:Integer}(F, ::Type{S}, ::Type{Bool}, T::Type) = T
5454

55-
for f in (:+, :-, :div, :mod, :&, :|, :$)
55+
# broadcast(::typeof(mod), A::AbstractArray, B::AbstractArray) =
56+
# _elementwise(mod, promote_eltype_op(mod, A, B), A, B)
57+
# The preceding definition should not be necessary?
58+
# Instead use general broadcast machinery, which the code below in part replicates?
59+
for f in (:+, :-, :div, :&, :|, :$)
5660
@eval ($f)(A::AbstractArray, B::AbstractArray) =
5761
_elementwise($f, promote_eltype_op($f, A, B), A, B)
5862
end
@@ -68,7 +72,29 @@ function _elementwise{T}(op, ::Type{T}, A::AbstractArray, B::AbstractArray)
6872
return F
6973
end
7074

71-
for f in (:.+, :.-, :.*, :./, :.\, :.^, :, :.%, :.<<, :.>>, :div, :mod, :rem, :&, :|, :$)
75+
# function broadcast{T}(::typeof(mod), A::Number, B::AbstractArray{T})
76+
# R = promote_op(mod, typeof(A), T)
77+
# S = promote_array_type(mod, typeof(A), T, R)
78+
# S === Any && return [mod(A, b) for b in B]
79+
# F = similar(B, S)
80+
# for (iF, iB) in zip(eachindex(F), eachindex(B))
81+
# @inbounds F[iF] = mod(A, B[iB])
82+
# end
83+
# return F
84+
# end
85+
# function broadcast{T}(::typeof(mod), A::AbstractArray{T}, B::Number)
86+
# R = promote_op(mod, T, typeof(B))
87+
# S = promote_array_type(mod, typeof(B), T, R)
88+
# S === Any && return [mod(a, B) for a in A]
89+
# F = similar(A, S)
90+
# for (iF, iA) in zip(eachindex(F), eachindex(A))
91+
# @inbounds F[iF] = mod(A[iA], B)
92+
# end
93+
# return F
94+
# end
95+
# The preceding definitions should not be necessary?
96+
# Instead use general broadcast machinery, which the code below in part replicates?
97+
for f in (:.+, :.-, :.*, :./, :.\, :.^, :, :.%, :.<<, :.>>, :div, :rem, :&, :|, :$)
7298
@eval begin
7399
function ($f){T}(A::Number, B::AbstractArray{T})
74100
R = promote_op($f, typeof(A), T)

base/bitarray.jl

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,27 +1148,27 @@ function div(x::Number, B::BitArray)
11481148
return fill(y, size(B))
11491149
end
11501150

1151-
function mod(A::BitArray, B::BitArray)
1151+
function broadcast(::typeof(mod), A::BitArray, B::BitArray)
11521152
shp = promote_shape(size(A), size(B))
11531153
all(B) || throw(DivideError())
11541154
return falses(shp)
11551155
end
1156-
mod(A::BitArray, B::Array{Bool}) = mod(A, BitArray(B))
1157-
mod(A::Array{Bool}, B::BitArray) = mod(BitArray(A), B)
1158-
function mod(B::BitArray, x::Bool)
1159-
return x ? falses(size(B)) : throw(DivideError())
1160-
end
1161-
function mod(x::Bool, B::BitArray)
1162-
all(B) || throw(DivideError())
1163-
return falses(size(B))
1164-
end
1165-
function mod(x::Number, B::BitArray)
1166-
all(B) || throw(DivideError())
1167-
y = mod(x, true)
1168-
return fill(y, size(B))
1156+
broadcast(::typeof(mod), A::BitArray, B::Array{Bool}) = mod.(A, BitArray(B))
1157+
broadcast(::typeof(mod), A::Array{Bool}, B::BitArray) = mod.(BitArray(A), B)
1158+
broadcast(::typeof(mod), B::BitArray, x::Bool) = x ? falses(size(B)) : throw(DivideError())
1159+
broadcast(::typeof(mod), x::Bool, B::BitArray) = all(B) ? falses(size(B)) : throw(DivideError())
1160+
broadcast(::typeof(mod), x::Number, B::BitArray) = all(B) ? fill(mod(x, true), size(B)) : throw(DivideError())
1161+
function broadcast(::typeof(mod), B::BitArray, x::Number)
1162+
T = promote_op(mod, Bool, typeof(x))
1163+
T === Any && return [mod(b, x) for b in B]
1164+
F = Array{T}(size(B))
1165+
for i = 1:length(F)
1166+
F[i] = mod(B[i], x)
1167+
end
1168+
return F
11691169
end
11701170

1171-
for f in (:div, :mod)
1171+
for f in (:div,)
11721172
@eval begin
11731173
function ($f)(B::BitArray, x::Number)
11741174
T = promote_op($f, Bool, typeof(x))

base/broadcast.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ module Broadcast
55
using Base.Cartesian
66
using Base: promote_eltype_op, @get!, _msk_end, unsafe_bitgetindex, linearindices, tail, OneTo, to_shape
77
import Base: .+, .-, .*, ./, .\, .//, .==, .<, .!=, .<=, , .%, .<<, .>>, .^
8-
export broadcast, broadcast!, bitbroadcast, dotview
8+
import Base: broadcast
9+
export broadcast!, bitbroadcast, dotview
910
export broadcast_getindex, broadcast_setindex!
1011

1112
## Broadcasting utilities ##

base/deprecated.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,4 +1000,11 @@ macro vectorize_2arg(S,f)
10001000
end
10011001
export @vectorize_1arg, @vectorize_2arg
10021002

1003+
# Deprecate manually vectorized mod methods in favor of compact broadcast syntax
1004+
@deprecate mod(B::BitArray, x::Bool) mod.(B, x)
1005+
@deprecate mod(x::Bool, B::BitArray) mod.(x, B)
1006+
@deprecate mod(A::AbstractArray, B::AbstractArray) mod.(A, B)
1007+
@deprecate mod{T}(x::Number, A::AbstractArray{T}) mod.(x, A)
1008+
@deprecate mod{T}(A::AbstractArray{T}, x::Number) mod.(A, x)
1009+
10031010
# End deprecations scheduled for 0.6

test/bitarray.jl

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,30 @@ tc(r1,r2) = false
1010
bitcheck(b::BitArray) = length(b.chunks) == 0 || (b.chunks[end] == b.chunks[end] & Base._msk_end(b))
1111
bitcheck(x) = true
1212

13-
function check_bitop(ret_type, func, args...)
13+
function check_bitop_call(ret_type, func, args...)
1414
r1 = func(args...)
1515
r2 = func(map(x->(isa(x, BitArray) ? Array(x) : x), args)...)
16+
check_bitop_tests(ret_type, r1, r2)
17+
end
18+
function check_bitop_dotcall(ret_type, func, args...)
19+
r1 = func.(args...)
20+
r2 = func.(map(x->(isa(x, BitArray) ? Array(x) : x), args)...)
21+
check_bitop_tests(ret_type, r1, r2)
22+
end
23+
function check_bitop_tests(ret_type, r1, r2)
1624
@test isa(r1, ret_type)
1725
@test tc(r1, r2)
1826
@test isequal(r1, convert(ret_type, r2))
1927
@test bitcheck(r1)
2028
end
21-
2229
macro check_bit_operation(ex, ret_type)
23-
@assert Meta.isexpr(ex, :call)
24-
Expr(:call, :check_bitop, esc(ret_type), map(esc,ex.args)...)
30+
if Meta.isexpr(ex, :call)
31+
Expr(:call, :check_bitop_call, esc(ret_type), map(esc, ex.args)...)
32+
elseif Meta.isexpr(ex, :.)
33+
Expr(:call, :check_bitop_dotcall, esc(ret_type), esc(ex.args[1]), map(esc, ex.args[2].args)...)
34+
else
35+
throw(ArgumentError("first argument to @check_bit_operation must be an expression with head either :call or :. !"))
36+
end
2537
end
2638

2739
let t0 = time()
@@ -612,11 +624,11 @@ b2 = bitrand(n1, n2)
612624

613625
b2 = trues(n1, n2)
614626
@check_bit_operation div(b1, b2) BitMatrix
615-
@check_bit_operation mod(b1, b2) BitMatrix
627+
@check_bit_operation mod.(b1, b2) BitMatrix
616628
@check_bit_operation div(b1,Array(b2)) BitMatrix
617-
@check_bit_operation mod(b1,Array(b2)) BitMatrix
629+
@check_bit_operation mod.(b1,Array(b2)) BitMatrix
618630
@check_bit_operation div(Array(b1),b2) BitMatrix
619-
@check_bit_operation mod(Array(b1),b2) BitMatrix
631+
@check_bit_operation mod.(Array(b1),b2) BitMatrix
620632

621633
while true
622634
global b1
@@ -650,7 +662,7 @@ i2 = rand(1:10, n1, n2)
650662
@check_bit_operation (./)(b1, i2) Matrix{Float64}
651663
@check_bit_operation (.^)(b1, i2) BitMatrix
652664
@check_bit_operation div(b1, i2) Matrix{Int}
653-
@check_bit_operation mod(b1, i2) Matrix{Int}
665+
@check_bit_operation mod.(b1, i2) Matrix{Int}
654666

655667
# Matrix{Bool}/Matrix{Float64}
656668
b1 = bitrand(n1, n2)
@@ -659,7 +671,7 @@ f2 = 1.0 .+ rand(n1, n2)
659671
@check_bit_operation (./)(b1, f2) Matrix{Float64}
660672
@check_bit_operation (.^)(b1, f2) Matrix{Float64}
661673
@check_bit_operation div(b1, f2) Matrix{Float64}
662-
@check_bit_operation mod(b1, f2) Matrix{Float64}
674+
@check_bit_operation mod.(b1, f2) Matrix{Float64}
663675

664676
# Number/Matrix
665677
b2 = bitrand(n1, n2)
@@ -696,22 +708,22 @@ end
696708
b2 = trues(n1, n2)
697709
@check_bit_operation (./)(true, b2) Matrix{Float64}
698710
@check_bit_operation div(true, b2) BitMatrix
699-
@check_bit_operation mod(true, b2) BitMatrix
711+
@check_bit_operation mod.(true, b2) BitMatrix
700712
@check_bit_operation (./)(false, b2) Matrix{Float64}
701713
@check_bit_operation div(false, b2) BitMatrix
702-
@check_bit_operation mod(false, b2) BitMatrix
714+
@check_bit_operation mod.(false, b2) BitMatrix
703715

704716
@check_bit_operation (./)(i1, b2) Matrix{Float64}
705717
@check_bit_operation div(i1, b2) Matrix{Int}
706-
@check_bit_operation mod(i1, b2) Matrix{Int}
718+
@check_bit_operation mod.(i1, b2) Matrix{Int}
707719

708720
@check_bit_operation (./)(u1, b2) Matrix{Float64}
709721
@check_bit_operation div(u1, b2) Matrix{UInt8}
710-
@check_bit_operation mod(u1, b2) Matrix{UInt8}
722+
@check_bit_operation mod.(u1, b2) Matrix{UInt8}
711723

712724
@check_bit_operation (./)(f1, b2) Matrix{Float64}
713725
@check_bit_operation div(f1, b2) Matrix{Float64}
714-
@check_bit_operation mod(f1, b2) Matrix{Float64}
726+
@check_bit_operation mod.(f1, b2) Matrix{Float64}
715727

716728
@check_bit_operation (./)(ci1, b2) Matrix{Complex128}
717729
@check_bit_operation (./)(cu1, b2) Matrix{Complex128}
@@ -767,7 +779,7 @@ b2 = Array(bitrand(n1,n2))
767779
@check_bit_operation (./)(b1, true) Matrix{Float64}
768780
@check_bit_operation (./)(b1, false) Matrix{Float64}
769781
@check_bit_operation div(b1, true) BitMatrix
770-
@check_bit_operation mod(b1, true) BitMatrix
782+
@check_bit_operation mod.(b1, true) BitMatrix
771783

772784
@check_bit_operation (&)(b1, b2) BitMatrix
773785
@check_bit_operation (|)(b1, b2) BitMatrix
@@ -783,7 +795,7 @@ b2 = Array(bitrand(n1,n2))
783795
@check_bit_operation (.*)(b1, i2) Matrix{Int}
784796
@check_bit_operation (./)(b1, i2) Matrix{Float64}
785797
@check_bit_operation div(b1, i2) Matrix{Int}
786-
@check_bit_operation mod(b1, i2) Matrix{Int}
798+
@check_bit_operation mod.(b1, i2) Matrix{Int}
787799

788800
@check_bit_operation (&)(b1, u2) Matrix{UInt8}
789801
@check_bit_operation (|)(b1, u2) Matrix{UInt8}
@@ -793,14 +805,14 @@ b2 = Array(bitrand(n1,n2))
793805
@check_bit_operation (.*)(b1, u2) Matrix{UInt8}
794806
@check_bit_operation (./)(b1, u2) Matrix{Float64}
795807
@check_bit_operation div(b1, u2) Matrix{UInt8}
796-
@check_bit_operation mod(b1, u2) Matrix{UInt8}
808+
@check_bit_operation mod.(b1, u2) Matrix{UInt8}
797809

798810
@check_bit_operation (.+)(b1, f2) Matrix{Float64}
799811
@check_bit_operation (.-)(b1, f2) Matrix{Float64}
800812
@check_bit_operation (.*)(b1, f2) Matrix{Float64}
801813
@check_bit_operation (./)(b1, f2) Matrix{Float64}
802814
@check_bit_operation div(b1, f2) Matrix{Float64}
803-
@check_bit_operation mod(b1, f2) Matrix{Float64}
815+
@check_bit_operation mod.(b1, f2) Matrix{Float64}
804816

805817
@check_bit_operation (.+)(b1, ci2) Matrix{Complex{Int}}
806818
@check_bit_operation (.-)(b1, ci2) Matrix{Complex{Int}}

0 commit comments

Comments
 (0)