Skip to content

Commit

Permalink
Deprecate manually vectorized mod methods in favor of compact broadca…
Browse files Browse the repository at this point in the history
…st syntax.
  • Loading branch information
Sacha0 committed Sep 20, 2016
1 parent a6a8946 commit dc663d9
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 36 deletions.
26 changes: 24 additions & 2 deletions base/arraymath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ promote_array_type{S<:Integer}(::typeof(./), ::Type{S}, ::Type{Bool}, T::Type) =
promote_array_type{S<:Integer}(::typeof(.\), ::Type{S}, ::Type{Bool}, T::Type) = T
promote_array_type{S<:Integer}(F, ::Type{S}, ::Type{Bool}, T::Type) = T

for f in (:+, :-, :div, :mod, :&, :|, :$)
broadcast(::typeof(mod), A::AbstractArray, B::AbstractArray) =
_elementwise(mod, promote_eltype_op(mod, A, B), A, B)
for f in (:+, :-, :div, :&, :|, :$)
@eval ($f)(A::AbstractArray, B::AbstractArray) =
_elementwise($f, promote_eltype_op($f, A, B), A, B)
end
Expand All @@ -68,7 +70,27 @@ function _elementwise{T}(op, ::Type{T}, A::AbstractArray, B::AbstractArray)
return F
end

for f in (:.+, :.-, :.*, :./, :.\, :.^, :, :.%, :.<<, :.>>, :div, :mod, :rem, :&, :|, :$)
function broadcast{T}(::typeof(mod), A::Number, B::AbstractArray{T})
R = promote_op(mod, typeof(A), T)
S = promote_array_type(mod, typeof(A), T, R)
S === Any && return [mod(A, b) for b in B]
F = similar(B, S)
for (iF, iB) in zip(eachindex(F), eachindex(B))
@inbounds F[iF] = mod(A, B[iB])
end
return F
end
function broadcast{T}(::typeof(mod), A::AbstractArray{T}, B::Number)
R = promote_op(mod, T, typeof(B))
S = promote_array_type(mod, typeof(B), T, R)
S === Any && return [mod(a, B) for a in A]
F = similar(A, S)
for (iF, iA) in zip(eachindex(F), eachindex(A))
@inbounds F[iF] = mod(A[iA], B)
end
return F
end
for f in (:.+, :.-, :.*, :./, :.\, :.^, :, :.%, :.<<, :.>>, :div, :rem, :&, :|, :$)
@eval begin
function ($f){T}(A::Number, B::AbstractArray{T})
R = promote_op($f, typeof(A), T)
Expand Down
30 changes: 15 additions & 15 deletions base/bitarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1148,27 +1148,27 @@ function div(x::Number, B::BitArray)
return fill(y, size(B))
end

function mod(A::BitArray, B::BitArray)
function broadcast(::typeof(mod), A::BitArray, B::BitArray)
shp = promote_shape(size(A), size(B))
all(B) || throw(DivideError())
return falses(shp)
end
mod(A::BitArray, B::Array{Bool}) = mod(A, BitArray(B))
mod(A::Array{Bool}, B::BitArray) = mod(BitArray(A), B)
function mod(B::BitArray, x::Bool)
return x ? falses(size(B)) : throw(DivideError())
end
function mod(x::Bool, B::BitArray)
all(B) || throw(DivideError())
return falses(size(B))
end
function mod(x::Number, B::BitArray)
all(B) || throw(DivideError())
y = mod(x, true)
return fill(y, size(B))
broadcast(::typeof(mod), A::BitArray, B::Array{Bool}) = mod.(A, BitArray(B))
broadcast(::typeof(mod), A::Array{Bool}, B::BitArray) = mod.(BitArray(A), B)
broadcast(::typeof(mod), B::BitArray, x::Bool) = x ? falses(size(B)) : throw(DivideError())
broadcast(::typeof(mod), x::Bool, B::BitArray) = all(B) ? falses(size(B)) : throw(DivideError())
broadcast(::typeof(mod), x::Number, B::BitArray) = all(B) ? fill(mod(x, true), size(B)) : throw(DivideError())
function broadcast(::typeof(mod), B::BitArray, x::Number)
T = promote_op(mod, Bool, typeof(x))
T === Any && return [mod(b, x) for b in B]
F = Array{T}(size(B))
for i = 1:length(F)
F[i] = mod(B[i], x)
end
return F
end

for f in (:div, :mod)
for f in (:div,)
@eval begin
function ($f)(B::BitArray, x::Number)
T = promote_op($f, Bool, typeof(x))
Expand Down
3 changes: 2 additions & 1 deletion base/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ module Broadcast
using Base.Cartesian
using Base: promote_eltype_op, @get!, _msk_end, unsafe_bitgetindex, linearindices, tail, OneTo, to_shape
import Base: .+, .-, .*, ./, .\, .//, .==, .<, .!=, .<=, , .%, .<<, .>>, .^
export broadcast, broadcast!, bitbroadcast, dotview
import Base: broadcast
export broadcast!, bitbroadcast, dotview
export broadcast_getindex, broadcast_setindex!

## Broadcasting utilities ##
Expand Down
7 changes: 7 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1000,4 +1000,11 @@ macro vectorize_2arg(S,f)
end
export @vectorize_1arg, @vectorize_2arg

# Deprecate manually vectorized mod methods in favor of compact broadcast syntax
@deprecate mod(B::BitArray, x::Bool) mod.(B, x)
@deprecate mod(x::Bool, B::BitArray) mod.(x, B)
@deprecate mod(A::AbstractArray, B::AbstractArray) mod.(A, B)
@deprecate mod{T}(x::Number, A::AbstractArray{T}) mod.(x, A)
@deprecate mod{T}(A::AbstractArray{T}, x::Number) mod.(A, x)

# End deprecations scheduled for 0.6
48 changes: 30 additions & 18 deletions test/bitarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,30 @@ tc(r1,r2) = false
bitcheck(b::BitArray) = length(b.chunks) == 0 || (b.chunks[end] == b.chunks[end] & Base._msk_end(b))
bitcheck(x) = true

function check_bitop(ret_type, func, args...)
function check_bitop_call(ret_type, func, args...)
r1 = func(args...)
r2 = func(map(x->(isa(x, BitArray) ? Array(x) : x), args)...)
check_bitop_tests(ret_type, r1, r2)
end
function check_bitop_dotcall(ret_type, func, args...)
r1 = func.(args...)
r2 = func.(map(x->(isa(x, BitArray) ? Array(x) : x), args)...)
check_bitop_tests(ret_type, r1, r2)
end
function check_bitop_tests(ret_type, r1, r2)
@test isa(r1, ret_type)
@test tc(r1, r2)
@test isequal(r1, convert(ret_type, r2))
@test bitcheck(r1)
end

macro check_bit_operation(ex, ret_type)
@assert Meta.isexpr(ex, :call)
Expr(:call, :check_bitop, esc(ret_type), map(esc,ex.args)...)
if Meta.isexpr(ex, :call)
Expr(:call, :check_bitop_call, esc(ret_type), map(esc, ex.args)...)
elseif Meta.isexpr(ex, :.)
Expr(:call, :check_bitop_dotcall, esc(ret_type), esc(ex.args[1]), map(esc, ex.args[2].args)...)
else
throw(ArgumentError("first argument to @check_bit_operation must be an expression with head either :call or :. !"))
end
end

let t0 = time()
Expand Down Expand Up @@ -612,11 +624,11 @@ b2 = bitrand(n1, n2)

b2 = trues(n1, n2)
@check_bit_operation div(b1, b2) BitMatrix
@check_bit_operation mod(b1, b2) BitMatrix
@check_bit_operation mod.(b1, b2) BitMatrix
@check_bit_operation div(b1,Array(b2)) BitMatrix
@check_bit_operation mod(b1,Array(b2)) BitMatrix
@check_bit_operation mod.(b1,Array(b2)) BitMatrix
@check_bit_operation div(Array(b1),b2) BitMatrix
@check_bit_operation mod(Array(b1),b2) BitMatrix
@check_bit_operation mod.(Array(b1),b2) BitMatrix

while true
global b1
Expand Down Expand Up @@ -650,7 +662,7 @@ i2 = rand(1:10, n1, n2)
@check_bit_operation (./)(b1, i2) Matrix{Float64}
@check_bit_operation (.^)(b1, i2) BitMatrix
@check_bit_operation div(b1, i2) Matrix{Int}
@check_bit_operation mod(b1, i2) Matrix{Int}
@check_bit_operation mod.(b1, i2) Matrix{Int}

# Matrix{Bool}/Matrix{Float64}
b1 = bitrand(n1, n2)
Expand All @@ -659,7 +671,7 @@ f2 = 1.0 .+ rand(n1, n2)
@check_bit_operation (./)(b1, f2) Matrix{Float64}
@check_bit_operation (.^)(b1, f2) Matrix{Float64}
@check_bit_operation div(b1, f2) Matrix{Float64}
@check_bit_operation mod(b1, f2) Matrix{Float64}
@check_bit_operation mod.(b1, f2) Matrix{Float64}

# Number/Matrix
b2 = bitrand(n1, n2)
Expand Down Expand Up @@ -696,22 +708,22 @@ end
b2 = trues(n1, n2)
@check_bit_operation (./)(true, b2) Matrix{Float64}
@check_bit_operation div(true, b2) BitMatrix
@check_bit_operation mod(true, b2) BitMatrix
@check_bit_operation mod.(true, b2) BitMatrix
@check_bit_operation (./)(false, b2) Matrix{Float64}
@check_bit_operation div(false, b2) BitMatrix
@check_bit_operation mod(false, b2) BitMatrix
@check_bit_operation mod.(false, b2) BitMatrix

@check_bit_operation (./)(i1, b2) Matrix{Float64}
@check_bit_operation div(i1, b2) Matrix{Int}
@check_bit_operation mod(i1, b2) Matrix{Int}
@check_bit_operation mod.(i1, b2) Matrix{Int}

@check_bit_operation (./)(u1, b2) Matrix{Float64}
@check_bit_operation div(u1, b2) Matrix{UInt8}
@check_bit_operation mod(u1, b2) Matrix{UInt8}
@check_bit_operation mod.(u1, b2) Matrix{UInt8}

@check_bit_operation (./)(f1, b2) Matrix{Float64}
@check_bit_operation div(f1, b2) Matrix{Float64}
@check_bit_operation mod(f1, b2) Matrix{Float64}
@check_bit_operation mod.(f1, b2) Matrix{Float64}

@check_bit_operation (./)(ci1, b2) Matrix{Complex128}
@check_bit_operation (./)(cu1, b2) Matrix{Complex128}
Expand Down Expand Up @@ -767,7 +779,7 @@ b2 = Array(bitrand(n1,n2))
@check_bit_operation (./)(b1, true) Matrix{Float64}
@check_bit_operation (./)(b1, false) Matrix{Float64}
@check_bit_operation div(b1, true) BitMatrix
@check_bit_operation mod(b1, true) BitMatrix
@check_bit_operation mod.(b1, true) BitMatrix

@check_bit_operation (&)(b1, b2) BitMatrix
@check_bit_operation (|)(b1, b2) BitMatrix
Expand All @@ -783,7 +795,7 @@ b2 = Array(bitrand(n1,n2))
@check_bit_operation (.*)(b1, i2) Matrix{Int}
@check_bit_operation (./)(b1, i2) Matrix{Float64}
@check_bit_operation div(b1, i2) Matrix{Int}
@check_bit_operation mod(b1, i2) Matrix{Int}
@check_bit_operation mod.(b1, i2) Matrix{Int}

@check_bit_operation (&)(b1, u2) Matrix{UInt8}
@check_bit_operation (|)(b1, u2) Matrix{UInt8}
Expand All @@ -793,14 +805,14 @@ b2 = Array(bitrand(n1,n2))
@check_bit_operation (.*)(b1, u2) Matrix{UInt8}
@check_bit_operation (./)(b1, u2) Matrix{Float64}
@check_bit_operation div(b1, u2) Matrix{UInt8}
@check_bit_operation mod(b1, u2) Matrix{UInt8}
@check_bit_operation mod.(b1, u2) Matrix{UInt8}

@check_bit_operation (.+)(b1, f2) Matrix{Float64}
@check_bit_operation (.-)(b1, f2) Matrix{Float64}
@check_bit_operation (.*)(b1, f2) Matrix{Float64}
@check_bit_operation (./)(b1, f2) Matrix{Float64}
@check_bit_operation div(b1, f2) Matrix{Float64}
@check_bit_operation mod(b1, f2) Matrix{Float64}
@check_bit_operation mod.(b1, f2) Matrix{Float64}

@check_bit_operation (.+)(b1, ci2) Matrix{Complex{Int}}
@check_bit_operation (.-)(b1, ci2) Matrix{Complex{Int}}
Expand Down

0 comments on commit dc663d9

Please sign in to comment.