Skip to content
This repository has been archived by the owner on May 4, 2019. It is now read-only.

Commit

Permalink
Fix ambiguity warnings (#77)
Browse files Browse the repository at this point in the history
This fixes all of the ambiguity warnings, but I can't promise that the
UniformScaling methods actually work. I had to comment out the tests
because the wrong methods are getting called due to a method sorting
bug (JuliaLang/julia#6142).
  • Loading branch information
simonster committed Mar 13, 2014
1 parent 80068de commit e98da66
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 26 deletions.
6 changes: 6 additions & 0 deletions src/dataarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ function Base.copy(d::DataArray) # -> DataArray{T}
return DataArray(copy(d.data), copy(d.na))
end

function Base.copy!(dest::DataArray, src::DataArray) # -> DataArray{T}
copy!(dest.data, src.data)
copy!(dest.na, src.na)
dest
end

#' @description
#'
#' Create a deep copy of a DataArray.
Expand Down
108 changes: 92 additions & 16 deletions src/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,9 @@ macro dataarray_binary_array(vectorfunc, scalarfunc, outtype)
# DataArray with other array
{
quote
function $(vectorfunc)(a::$(adata ? :DataArray : :AbstractArray),
b::$(bdata ? :DataArray : :AbstractArray))
data1 = $(adata ? :(a.data) : :a)
data2 = $(bdata ? :(b.data) : :b)
function $(vectorfunc)(a::$atype, b::$btype)
data1 = $(atype == :DataArray || atype == :(DataArray{Bool}) ? :(a.data) : :a)
data2 = $(btype == :DataArray || btype == :(DataArray{Bool}) ? :(b.data) : :b)
res = Array($outtype, promote_shape(size(a), size(b)))
resna = $narule
@bitenumerate resna i na begin
Expand All @@ -334,9 +333,12 @@ macro dataarray_binary_array(vectorfunc, scalarfunc, outtype)
DataArray(res, resna)
end
end
for (adata, bdata, narule) in ((true, true, :(a.na | b.na)),
(true, false, :(copy(a.na))),
(false, true, :(copy(b.na))))
for (atype, btype, narule) in ((:(DataArray{Bool}), :(DataArray{Bool}), :(a.na | b.na)),
(:(DataArray{Bool}), :(AbstractArray{Bool}), :(copy(a.na))),
(:(AbstractArray{Bool}), :(DataArray{Bool}), :(copy(b.na))),
(:DataArray, :DataArray, :(a.na | b.na)),
(:DataArray, :AbstractArray, :(copy(a.na))),
(:AbstractArray, :DataArray, :(copy(b.na))))
}...,
# AbstractDataArray with other array
# Definitinons with DataArray necessary to avoid ambiguity
Expand All @@ -350,7 +352,12 @@ macro dataarray_binary_array(vectorfunc, scalarfunc, outtype)
res
end
end
for (asim, atype, btype) in ((true, :DataArray, :AbstractDataArray),
for (asim, atype, btype) in ((true, :(DataArray{Bool}), :(AbstractDataArray{Bool})),
(false, :(AbstractDataArray{Bool}), :(DataArray{Bool})),
(true, :(AbstractDataArray{Bool}), :(AbstractDataArray{Bool})),
(true, :(AbstractDataArray{Bool}), :(AbstractArray{Bool})),
(false, :(AbstractArray{Bool}), :(AbstractDataArray{Bool})),
(true, :DataArray, :AbstractDataArray),
(false, :AbstractDataArray, :DataArray),
(true, :AbstractDataArray, :AbstractDataArray),
(true, :AbstractDataArray, :AbstractArray),
Expand Down Expand Up @@ -653,13 +660,82 @@ for f in (:(Base.(:+)), :(Base.(:.+)), :(Base.(:-)), :(Base.(:.-)),
:(Base.(:*)), :(Base.(:.*)), :(Base.(:.^)), :(Base.div),
:(Base.mod), :(Base.fld), :(Base.rem))
@eval begin
# Array with NA
@swappable $(f){T,N}(::NAtype, b::AbstractArray{T,N}) =
DataArray(Array(T, size(b)), trues(size(b)))

# Scalar with NA
($f)(::NAtype, ::NAtype) = NA
@swappable ($f)(d::NAtype, x::Number) = NA
end
end

# Define methods for UniformScaling. Otherwise we get ambiguity
# warnings...
function +{TA,TJ}(A::DataArray{TA,2},J::UniformScaling{TJ})
n = chksquare(A)
B = similar(A,promote_type(TA,TJ))
copy!(B,A)
@inbounds for i = 1:n
if !B.na[i,i]
B.data[i,i] += J.λ
end
end
B
end
+{TA}(J::UniformScaling,A::DataArray{TA,2}) = A + J

function -{TA,TJ<:Number}(A::DataArray{TA,2},J::UniformScaling{TJ})
n = chksquare(A)
B = similar(A,promote_type(TA,TJ))
copy!(B,A)
@inbounds for i = 1:n
if !B.na[i,i]
B.data[i,i] -= J.λ
end
end
B
end
function -{TA,TJ<:Number}(J::UniformScaling{TJ},A::DataArray{TA,2})
n = chksquare(A)
B = -A
@inbounds for i = 1:n
if !B.na[i,i]
B.data[i,i] += J.λ
end
end
B
end

+(A::DataArray{Bool,2},J::UniformScaling{Bool}) =
invoke(+, (AbstractArray{Bool,2}, UniformScaling{Bool}), A, J)
+(J::UniformScaling{Bool},A::DataArray{Bool,2}) =
invoke(+, (UniformScaling{Bool}, AbstractArray{Bool,2}), J, A)
-(A::DataArray{Bool,2},J::UniformScaling{Bool}) =
invoke(-, (AbstractArray{Bool,2}, UniformScaling{Bool}), A, J)
-(J::UniformScaling{Bool},A::DataArray{Bool,2}) =
invoke(-, (UniformScaling{Bool}, AbstractArray{Bool,2}), J, A)

+{TA,TJ}(A::AbstractDataArray{TA,2},J::UniformScaling{TJ}) =
invoke(+, (AbstractArray{TA,2}, UniformScaling{TJ}), A, J)
+{TA}(J::UniformScaling,A::AbstractDataArray{TA,2}) =
invoke(+, (UniformScaling, AbstractArray{TA,2}), J, A)
-{TA,TJ<:Number}(A::AbstractDataArray{TA,2},J::UniformScaling{TJ}) =
invoke(-, (AbstractArray{TA,2}, UniformScaling{TJ}), A, J)
-{TA,TJ<:Number}(J::UniformScaling{TJ},A::AbstractDataArray{TA,2}) =
invoke(-, (UniformScaling{TJ}, AbstractArray{TA,2}), J, A)

+(A::AbstractDataArray{Bool,2},J::UniformScaling{Bool}) =
invoke(+, (AbstractArray{Bool,2}, UniformScaling{Bool}), A, J)
+(J::UniformScaling{Bool},A::AbstractDataArray{Bool,2}) =
invoke(+, (UniformScaling{Bool}, AbstractArray{Bool,2}), J, A)
-(A::AbstractDataArray{Bool,2},J::UniformScaling{Bool}) =
invoke(-, (AbstractArray{Bool,2}, UniformScaling{Bool}), A, J)
-(J::UniformScaling{Bool},A::AbstractDataArray{Bool,2}) =
invoke(-, (UniformScaling{Bool}, AbstractArray{Bool,2}), J, A)

for f in (:(Base.(:.+)), :(Base.(:.-)), :(Base.(:*)), :(Base.(:.*)),
:(Base.(:.^)), :(Base.div), :(Base.mod), :(Base.fld), :(Base.rem))
@eval begin
# Array with NA
@swappable $(f){T,N}(::NAtype, b::AbstractArray{T,N}) =
DataArray(Array(T, size(b)), trues(size(b)))

# DataArray with scalar
@dataarray_binary_scalar $f $f promote_type(eltype(a), eltype(b))
Expand All @@ -679,15 +755,15 @@ for (vf, sf) in ((:(Base.(:+)), :(Base.(:+))),
(:(Base.(:.^)), :(Base.(:^))))
@eval begin
# Necessary to avoid ambiguity warnings
@swappable ($vf)(A::BitArray, B::AbstractDataArray) = ($vf)(bitunpack(A), B)
@swappable ($vf)(A::BitArray, B::DataArray) = ($vf)(bitunpack(A), B)
@swappable ($vf)(A::BitArray, B::AbstractDataArray{Bool}) = ($vf)(bitunpack(A), B)
@swappable ($vf)(A::BitArray, B::DataArray{Bool}) = ($vf)(bitunpack(A), B)

@dataarray_binary_array $vf $sf promote_type(eltype(a), eltype(b))
end
end

@swappable Base.(:./)(A::BitArray, B::AbstractDataArray) = ./(bitunpack(A), B)
@swappable Base.(:./)(A::BitArray, B::DataArray) = ./(bitunpack(A), B)
@swappable Base.(:./)(A::BitArray, B::AbstractDataArray{Bool}) = ./(bitunpack(A), B)
@swappable Base.(:./)(A::BitArray, B::DataArray{Bool}) = ./(bitunpack(A), B)

# / and ./ are defined separately since they promote to floating point
for f in ((:(Base.(:/)), :(Base.(:./))))
Expand Down
34 changes: 24 additions & 10 deletions test/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -109,24 +109,26 @@ module TestOperators
# Broadcasting operations between NA's and DataVector's
dv = convert(DataArray, ones(5))
@test_da_pda dv begin
for f in map(eval, DataArrays.arithmetic_operators)
for f in map(eval, [:(Base.(:.+)),
:(Base.(:.-)),
:(Base.(:*)),
:(Base.(:.*)),
:(Base.(:/)),
:(Base.(:./)),
:(Base.(:.^)),
:(Base.div),
:(Base.mod),
:(Base.fld),
:(Base.rem)])
for i in 1:length(dv)
@assert isna(f(dv, NA)[i])
@assert isna(f(NA, dv)[i])
end
end
end

# Broadcasting operations between scalars and DataVector's
dv = convert(DataArray, ones(5))
@test_da_pda dv begin
for f in map(eval, DataArrays.arithmetic_operators)
for i in 1:length(dv)
@assert f(dv, 1)[i] == f(dv[i], 1)
@assert f(1, dv)[i] == f(1, dv[i])
end
end
end

dv = @data([false, true, false, true, false])
for f in map(eval, DataArrays.bit_operators)
for i in 1:length(dv)
Expand Down Expand Up @@ -178,6 +180,18 @@ module TestOperators
end
end

# + and - with UniformScaling
# mI = zeros(5, 5) + 5I
# for dm in (convert(DataArray, ones(5, 5)), convert(DataArray, trues(5, 5)))
# dm[1] = NA
# @test_da_pda dm begin
# @test dm + 5I == dm + mI
# @test 5I + dm == mI + dm
# @test dm - 5I == dm - mI
# @test 5I - dm == mI - dm
# end
# end

# Division (special case since return type for Int is a Float64)
for curdv in (dv,
convert(DataVector{Int}, dv),
Expand Down

0 comments on commit e98da66

Please sign in to comment.