Skip to content

Commit

Permalink
Use map() in @vectorize operators to generalize to N-d. Close #172.
Browse files Browse the repository at this point in the history
  • Loading branch information
ViralBShah committed Aug 20, 2011
1 parent f2dba4a commit dfb887f
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 42 deletions.
64 changes: 48 additions & 16 deletions j/abstractarray.j
Original file line number Diff line number Diff line change
Expand Up @@ -843,46 +843,78 @@ isempty(a::AbstractArray) = (numel(a) == 0)
#map(f, M::AbstractMatrix) = [ f(M[i,j]) | i=1:size(M,1), j=1:size(M,2) ]

## TODO: How to generalize map to n input args?

## 1-d
function map_to(dest::AbstractArray, f, A::AbstractArray)
for i=1:numel(A)
dest[i] = f(A[i])
end
return dest
end

function map(f, A::AbstractArray)
if isempty(A); return A; end
first = f(A[1])
dest = similar(A, typeof(first))
return map_to(dest, f, A)
end

## 2-d
function map_to(dest::AbstractArray, f, A::AbstractArray, B::AbstractArray)
for i=1:numel(A)
dest[i] = f(A[i], B[i])
end
return dest
end

function map(f, A::AbstractArray)
function map(f, A::AbstractArray, B::AbstractArray)
if size(A) != size(B); error("Input size and shape should be same"); end
if isempty(A); return A; end
first = f(A[1])
first = f(A[1], B[1])
dest = similar(A, typeof(first))
return map_to(dest, f, A)
return map_to(dest, f, A, B)
end

function map(f, A::AbstractArray, B::AbstractArray)
if size(A) != size(B); error("Input size and shape should be same"); end
function map_to(dest::AbstractArray, f, A::AbstractArray, B::Number)
for i=1:numel(A)
dest[i] = f(A[i], B)
end
return dest
end

function map(f, A::AbstractArray, B::Number)
if isempty(A); return A; end
first = f(A[1], B[1])
first = f(A[1], B)
dest = similar(A, typeof(first))
return map_to(dest, f, A, B)
end

function map_to(dest::AbstractArray, f, A::Number, B::AbstractArray)
for i=1:numel(B)
dest[i] = f(A, B[i])
end
return dest
end

function map(f, A::Number, B::AbstractArray)
if isempty(A); return A; end
first = f(A, B[1])
dest = similar(B, typeof(first))
return map_to(dest, f, A, B)
end

## Obsolete - Mainly here for reference purposes, use gen_cartesian_map
# function cartesian_map(body, t::Tuple, it...)
# idx = length(t)-length(it)
# if idx == 0
# body(it)
# else
# for i = t[idx]
# cartesian_map(body, t, i, it...)
# end
# end
# end
## Still used in show()
function cartesian_map(body, t::Tuple, it...)
idx = length(t)-length(it)
if idx == 0
body(it)
else
for i = t[idx]
cartesian_map(body, t, i, it...)
end
end
end

## Transpose, Permute ##

Expand Down
35 changes: 9 additions & 26 deletions j/operators.j
Original file line number Diff line number Diff line change
Expand Up @@ -101,40 +101,23 @@ one(::Type{Function}) = identity

macro vectorize_1arg(S,f)
quote
function ($f){T<:$S}(x::AbstractArray{T,1})
[ ($f)(x[i]) | i=1:length(x) ]
end
function ($f){T<:$S}(x::AbstractArray{T,2})
[ ($f)(x[i,j]) | i=1:size(x,1), j=1:size(x,2) ]
function ($f){T<:$S}(x::AbstractArray{T})
return map(($f), x)
end
end
end

macro vectorize_2arg(S,f)
quote
function ($f){T<:$S}(x::T, y::AbstractArray{T,1})
[ ($f)(x,y[i]) | i=1:length(y) ]
end
function ($f){T<:$S}(x::AbstractArray{T,1}, y::T)
[ ($f)(x[i],y) | i=1:length(x) ]
end
function ($f){T<:$S}(x::T, y::AbstractArray{T,2})
[ ($f)(x,y[i,j]) | i=1:size(y,1), j=1:size(y,2) ]
function ($f){T1<:$S, T2<:$S}(x::T1, y::AbstractArray{T2})
return map(($f), x, y)
end
function ($f){T<:$S}(x::AbstractArray{T,2}, y::T)
[ ($f)(x[i,j],y) | i=1:size(x,1), j=1:size(x,2) ]
function ($f){T1<:$S, T2<:$S}(x::AbstractArray{T1}, y::T2)
return map(($f), x, y)
end
function ($f){T<:$S}(x::AbstractArray{T,1}, y::AbstractArray{T,1})
if size(x) != size(y)
error("vector length mismatch")
end
[ ($f)(x[i],y[i]) | i=1:length(x) ]
end
function ($f){T<:$S}(x::AbstractArray{T,2}, y::AbstractArray{T,2})
if size(x) != size(y)
error("matrix dimension mismatch")
end
[ ($f)(x[i,j],y[i,j]) | i=1:size(x,1), j=1:size(x,2) ]
function ($f){T1<:$S, T2<:$S}(x::AbstractArray{T1}, y::AbstractArray{T2})
if size(x) != size(y); error("Input sizes and shapes should match"); end
return map(($f), x, y)
end
end
end

0 comments on commit dfb887f

Please sign in to comment.