1
votes

I have two arrays and an empty matrix, I need to perform a function such that the resulting matrix includes every combination of the two arrays.

Unfortunately I cannot run the arrays separately as they are both optional parameters for the function. I thought that the best way to do this was through nested loops but now I am unsure...

I've tried multiplying one of the matrices so that it includes the necessary duplicates, but I struggled with that as the real data is somewhat larger.

I've tried many versions of these nested loops.

a = [ 1 2 3 ]
b = [ 4 5 6 7 ]
ab = zeros(3,4)

for i = 1:length(a)
    for j = 1:length(b)
        ab[??] = function(x = a[??], y = b[??])
    end
end

ab = [1x4 1x5 1x6 1x7, 2x4 2x5 2x6 2x7, 3x4 3x5 3x6 3x7]

3

3 Answers

3
votes

Your problem can be solved by broadcasting:

julia> f(x, y) = (x,y)   # trivial example
f (generic function with 1 method)

julia> f.([1 2 3]', [4 5 6 7])
3×4 Array{Tuple{Int64,Int64},2}:
 (1, 4)  (1, 5)  (1, 6)  (1, 7)
 (2, 4)  (2, 5)  (2, 6)  (2, 7)
 (3, 4)  (3, 5)  (3, 6)  (3, 7)

The prime in a' transposes a to make the shapes work out correctly.

But note that a = [ 1 2 3 ] constructs a 1×3 Array{Int64,2}, which is a matrix. For a vector (what you probably call "array"), use commas: a = [ 1, 2, 3 ] etc. If you have your data in that form, you have to transpose the other way round:

julia> f.([1,2,3], [4,5,6,7]')
3×4 Array{Tuple{Int64,Int64},2}:
 (1, 4)  (1, 5)  (1, 6)  (1, 7)
 (2, 4)  (2, 5)  (2, 6)  (2, 7)
 (3, 4)  (3, 5)  (3, 6)  (3, 7)

BTW, this is called an "outer product" (for f = *), or a generalization of it. And if f is an operator , you can use dotted infix broadcasting: a' ∘. b.

2
votes

Isn't that just

a'.*b

?

Oh, now I have to write some more characters to get past the minimum acceptable answer length but I don't really have anything to add, I hope the code is self-explanatory.

1
votes

Also a list comprehension:

julia> a = [1,2,3];

julia> b = [4,5,6,7];

julia> ab = [(x,y) for x in a, y in b]
3×4 Array{Tuple{Int64,Int64},2}:
 (1, 4)  (1, 5)  (1, 6)  (1, 7)
 (2, 4)  (2, 5)  (2, 6)  (2, 7)
 (3, 4)  (3, 5)  (3, 6)  (3, 7)