Say I have the following function
function foo(p :: Int, x :: Real)
return p*x
end
And I want to call it for the following arrays:
P = [1, 2, 3]
X = [5.0, 6.0, 7.0, 8.0]
If I want to call foo
and store the value in a single array of size (length(P), length(X))
I could just double loop X
and P
as:
R = zeros(length(P), length(X))
for i in 1:length(P), j in 1:length(X)
R[i, j] = foo(P[i], X[j])
end
However, is there another way to do this while explicitly avoiding the double loop? Maybe something like?
R = foo.(collect(zip(P, X)))
Of course, the above does not work as foo
cannot handle ::Tuple{Int64, Float64}
, but I have not found a way to broadcast over different sized arrays for the moment. Any tips would be appreciated, thanks!
CodePudding user response:
If you want to use broadcasting you can do it like this:
julia> foo.(P, permutedims(X))
3×4 Matrix{Float64}:
5.0 6.0 7.0 8.0
10.0 12.0 14.0 16.0
15.0 18.0 21.0 24.0
or
julia> foo.(P, reshape(X, 1, :))
3×4 Matrix{Float64}:
5.0 6.0 7.0 8.0
10.0 12.0 14.0 16.0
15.0 18.0 21.0 24.0
or
julia> (((x, y),) -> foo(x, y)).(Iterators.product(P, X))
3×4 Matrix{Float64}:
5.0 6.0 7.0 8.0
10.0 12.0 14.0 16.0
15.0 18.0 21.0 24.0
or
julia> Base.splat(foo).(Iterators.product(P, X))
3×4 Matrix{Float64}:
5.0 6.0 7.0 8.0
10.0 12.0 14.0 16.0
15.0 18.0 21.0 24.0