Evaluate function of several variables on cartesian product?


#1

The title is not very good but what I want to is the following:

H(x->f(x),x) #returns a vector 
H((x,y)->f(x,y),x,y) #returns a matrix of dimension (length(x),length(y))
H((x,y,z)->f(x,y,z),x,y,z) #returns a 3D matrix of dimension (length(x),length(y),length(z))
etc...

Is there a generic function H(f,vars....) to do that ? x,y,z being vectors.


#2

You can use broadcasting: f.(x) to get a vector, f.(x, y.') to get a matrix, f.(x, y.', reshape(z, 1, 1, length(z)) to get a 3d array, and so on. Or a comprehension: [f(x,y,z) for x in x, y in y, z in z] will return a 3d array, for example.


#3

Ok thanks, I’ll try to write my own then.


#4

You can use the function product defined in Iterators packet. It returns an array of tuples which represents the cartesian products of input iterators.

You can write a function like this:

    function myproduct(f, c...)
        pro = Iterators.product(c...)
        reshape(map(x->f(x...), pro), map(length, pro.xss))
    end

Example:

julia> a = 1:3;

julia> b = 1:3;

julia> myproduct(-,a,b)
3×3 Array{Int64,2}:
 0  -1  -2
 1   0  -1
 2   1   0

#5

That’s elegant, but a bit slow (about 100x slower than the optimal), at least on 0.50.