Skip to content

Commit

Permalink
Use broadcast for some operations in arraymath (#19746)
Browse files Browse the repository at this point in the history
* Use broadcast for unary operations in arraymath

* Use broadcast for some binary array operations
  • Loading branch information
andreasnoack authored Dec 30, 2016
1 parent 6ad62c4 commit d44977c
Showing 1 changed file with 7 additions and 61 deletions.
68 changes: 7 additions & 61 deletions base/arraymath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,13 @@ Transform an array to its complex conjugate in-place.
See also [`conj`](@ref).
"""
function conj!{T<:Number}(A::AbstractArray{T})
for i in eachindex(A)
A[i] = conj(A[i])
end
return A
end
conj!{T<:Number}(A::AbstractArray{T}) = broadcast!(conj, A, A)

for f in (:-, :~, :conj, :sign)
@eval begin
function ($f)(A::AbstractArray)
F = similar(A)
RF, RA = eachindex(F), eachindex(A)
if RF == RA
for i in RA
F[i] = ($f)(A[i])
end
else
for (iF, iA) in zip(RF, RA)
F[iF] = ($f)(A[iA])
end
end
return F
end
end
for f in (:-, :~, :conj, :sign, :real, :imag)
@eval ($f)(A::AbstractArray) = broadcast($f, A)
end

(-)(A::AbstractArray{Bool}) = reshape([ -A[i] for i in eachindex(A) ], size(A))

real(A::AbstractArray) = reshape([ real(x) for x in A ], size(A))
imag(A::AbstractArray) = reshape([ imag(x) for x in A ], size(A))

function !(A::AbstractArray{Bool})
F = similar(A)
RF, RA = eachindex(F), eachindex(A)
if RF == RA
for i in RA
F[i] = !A[i]
end
else
for (iF, iA) in zip(RF, RA)
F[iF] = !A[iA]
end
end
return F
end
!(A::AbstractArray{Bool}) = broadcast(!, A)

## Binary arithmetic operators ##

Expand All @@ -67,26 +29,10 @@ promote_array_type{S<:Integer}(::typeof(\), ::Type{S}, ::Type{Bool}, T::Type) =
promote_array_type{S<:Integer}(F, ::Type{S}, ::Type{Bool}, T::Type) = T

for f in (:+, :-, :div, :mod, :&, :|)
@eval ($f)(A::AbstractArray, B::AbstractArray) =
_elementwise($f, promote_eltype_op($f, A, B), A, B)
end
function _elementwise(op, ::Type{Any}, A::AbstractArray, B::AbstractArray)
promote_shape(A, B) # check size compatibility
return broadcast(op, A, B)
end
function _elementwise{T}(op, ::Type{T}, A::AbstractArray, B::AbstractArray)
F = similar(A, T, promote_shape(A, B))
RF, RA, RB = eachindex(F), eachindex(A), eachindex(B)
if RF == RA == RB
for i in RA
@inbounds F[i] = op(A[i], B[i])
end
else
for (iF, iA, iB) in zip(RF, RA, RB)
@inbounds F[iF] = op(A[iA], B[iB])
end
@eval function ($f)(A::AbstractArray, B::AbstractArray)
promote_shape(A, B) # check size compatibility
broadcast($f, A, B)
end
return F
end

for f in (:div, :mod, :rem, :&, :|, :/, :\, :*, :+, :-)
Expand Down

0 comments on commit d44977c

Please sign in to comment.