Pointwise function application to nested arrays


#1

I cannot find a convenient way to map a function over arrays of arrays.

For a simple array I can use the syntax f.(x):

x=[1,2]
exp.(x)

For nested arrays though,

x=[[1,2],[3,4]]
exp.(x)

I end up with the deprecation warning

WARNING: exp(x::AbstractArray{T}) where T <: Number is deprecated, use exp.(x) instead.

I could use map(x->(exp.(x)), x), but this is rather cumbersome and becomes even more difficult for higher levels of nesting.

What is the recommended way to deal with the pointwise application of a function to nested arrays?


#2

I think that’s the main way to do it at this point (note that I removed an unnecessary set of extra parens); there are also variants like [exp.(x) for x in x]. It’s not that bad — you’re just spoiled by the dot notation. :wink:

In a future version of Julia you may be able to do map(exp.(_), x) or (exp.(_)).(x).

If you have higher levels of nesting, you may want to re-think your data structures.


#3

Assuming the functions you would like to apply are for non-vectors,

magic(obj::Any, func::Function) = func(obj)
magic(obj::AbstractVector, func::Function) = magic.(obj, func)

then you could do,

objA = collect(1:2)
objB = [[1,2], [3,4]]
magic(objA, exp)
magic(objB, exp)

#4

It’s not a general solution like the dot call syntax, but if you need some specific function to work recursively into nested arrays you can define it to do so.

julia> Base.exp(x::Array) = exp.(x)

julia> a=[[[0,1],[[[2,3]]]]]
1-element Array{Array{Array{Any,1},1},1}:
 Array{Any,1}[Any[0, 1], Any[Array{Int64,1}[[2, 3]]]]

julia> exp(a)
1-element Array{Array{Array{T,1} where T,1},1}:
 Array{T,1} where T[[1.0, 2.71828], Array{Array{Float64,1},1}[Array{Float64,1}[[7.38906, 20.0855]]]]