矢量喷溅

Cam*_*nek 3 julia

我希望能够以向量化的方式将一个元组数组喷射到一个函数中。例如,如果我具有以下功能,

function foo(x, y)
    x + y
end
Run Code Online (Sandbox Code Playgroud)

和以下元组数组,

args_array = [(1, 2), (3, 4), (5, 6)]
Run Code Online (Sandbox Code Playgroud)

然后我可以使用列表推导来获得所需的结果:

julia> [foo(args...) for args in args_array]
3-element Array{Int64,1}:
  3
  7
 11
Run Code Online (Sandbox Code Playgroud)

但是,我希望能够对此操作使用点矢量化表示法:

julia> foo.(args_array...)
ERROR: MethodError: no method matching foo(::Int64, ::Int64, ::Int64)
Run Code Online (Sandbox Code Playgroud)

但是如您所见,该特定语法不起作用。有矢量化的方法可以做到这一点吗?

Mat*_* B. 8

foo.(args_array...) 不起作用,因为它正在执行以下操作:

foo.((1, 2), (3, 4), (5, 6))
# which is roughly equivalent to
[foo(1,3,5), foo(2,4,6)]
Run Code Online (Sandbox Code Playgroud)

换句话说,它将每个元素args_array作为一个单独的参数,然后广播foo这些参数。您要foo直接广播元素。问题是运行:

foo.(args_array)
# is roughly equivalent to:
[foo((1,2)), foo((3,4)), foo((5,6))]
Run Code Online (Sandbox Code Playgroud)

换句话说,广播语法只是将每个元组作为单个参数传递给foo。我们可以用一个简单的中间函数来解决这个问题:

julia> bar(args) = foo(args...);

julia> bar.(args_array)
3-element Array{Int64,1}:
  3
  7
 11
Run Code Online (Sandbox Code Playgroud)

现在,这就是您想要的!如果不想的话,甚至不需要构造第二个参数。这是完全等效的:

julia> (args->foo(args...)).(args_array)
3-element Array{Int64,1}:
  3
  7
 11
Run Code Online (Sandbox Code Playgroud)

实际上,您可以很容易地对此进行概括:

julia> splat(f) = args -> f(args...);

julia> (splat(foo)).(args_array)
3-element Array{Int64,1}:
  3
  7
 11
Run Code Online (Sandbox Code Playgroud)