Evaluate function of several variables on cartesian product?


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))

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


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.


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


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))


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


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