After defining a bivariate function f(x::Int, y::Int)
, how can I get a matrix A = ( f(a[i], b[j]) )
using two vector a
and b
.
For example, let a = [1, 2]
, b = [1, 2, 3]
and f(x, y) = x + y
, the desirble result should be
A = [2 3 4
5 6 7]
Julia’s list comprehension seems to not work. Is there any simple way to realize it?
Hi!
I’m not sure which comprehension syntax you tried, but this one seems to work:
julia> f(x, y) = x + y
f (generic function with 1 method)
julia> a = [1, 2];
julia> b = [1, 2, 3];
julia> A = [f(a[i], b[j]) for i = 1:2, j = 1:3]
2×3 Matrix{Int64}:
2 3 4
3 4 5
Notice the subtle difference with that one:
julia> A = [f(a[i], b[j]) for i = 1:2 for j = 1:3]
6-element Vector{Int64}:
2
3
4
3
4
5
9 Likes
[m for m in Iterators.map(Base.splat(f), Iterators.product(a,b))]
Using StatsBase
pairwise(f,a,b)
That could possibly be written as broadcasting:
Base.splat(f).(Iterators.product(a,b))
Not directly related, but do you know why these two give different results?
julia> @btime broadcast(Base.splat(f), Iterators.product($a, $b))
86.526 ns (2 allocations: 272 bytes)
3×2 Matrix{Int64}:
2 3
3 4
4 5
julia> @btime map(Base.splat(f), Iterators.product($a, $b))
46.457 ns (1 allocation: 112 bytes)
3×2 Matrix{Int64}:
2 3
3 4
4 5
1 Like
I don’t know the answer. But, testing these two, to broadcast a function on an array of arrays, the speed difference leans towards broadcast:
f(x,y) = x + y
z = [rand(0:9,2) for _ in 1:1_000]
Base.splat(f).(z) # 36.9 μs (1 allocation: 7.94 KiB)
map(Base.splat(f),z) # 43.1 μs (1 allocation: 7.94 KiB)
1 Like