📜  在 Julia 中跨数组广播(1)

📅  最后修改于: 2023-12-03 15:23:11.587000             🧑  作者: Mango

在 Julia 中跨数组广播

在 Julia 中,数组广播是一种非常方便且高效的方法,可以让你对一个数组的每个元素执行相同的操作,而不需要显式循环。 在这个教程中,我们将介绍一些跨数组广播的基础知识。

什么是数组广播

数组广播是一种将函数应用于一个数组的每个元素的方法,而不需要显式循环。 假设有两个数组 a=[1,2,3]b=[4,5,6],在不使用广播的情况下,如果我们想将它们的元素相加,我们可以使用循环来完成:

c = similar(a)
for i in eachindex(a)
    c[i] = a[i] + b[i]
end

使用数组广播,我们可以更简洁地实现:

c = a .+ b

注意,我们在数组 a 和 b 中的加号前面添加了一个点号( . )。 这个点号告诉 Julia 对数组进行广播运算。

广播的规则

当数组不具有相同的形状时,Julia 会根据一定的规则自动扩展数组,以便它们可以进行广播运算。 这些规则如下:

  1. 如果两个数组的形状相同,则它们可以互相广播。

  2. 如果两个数组的形状不同,但至少一个数组的形状是1,则可以通过复制该维来进行广播。

  3. 如果两个数组的形状不同,且没有任何一个数组的形状是1,则无法广播,程序将会抛出一个错误。

让我们看一下这些规则如何适用于一些例子。

形状相同的数组广播

让我们先定义两个相同形状的数组:

a = [1 2 3; 4 5 6]
b = [7 8 9; 10 11 12]

现在,我们可以直接将它们相加,无需循环。

c = a .+ b

这里,数组 a 和数组 b 的形状相同,因此它们可以通过广播运算互相加和。

至少一个数组的形状为1

让我们定义一个数组 a=[1,2,3] 和一个形状为 3×3 的数组 b

a = [1,2,3]
b = [4 5 6; 7 8 9; 10 11 12]

如果我们尝试执行以下操作:

c = a .+ b

我们会得到一个错误:

DimensionMismatch("arrays could not be broadcast to a common size")

这是因为数组 a 和数组 b 的形状不同,因此它们无法直接相加。 不过,如果我们将数组 a 转换为行向量,则可以对其进行广播:

c = a' .+ b

这将把数组 a 均匀复制3次,使其与数组 b 具有相同的形状。

形状不同的数组无法广播

如果我们有两个形状不同的数组,例如 a=[1,2,3]b=[4,5],则无法使用广播机制来执行操作 a .+ b。 这将导致以下错误:

DimensionMismatch("arrays could not be broadcast to a common size")

这个错误发生是因为,这两个数组的形状既没有一个相同的部分,也没有一列或一行可以在两个数组之间共享。 在这种情况下,最好使用循环来执行此操作。

设置数组广播的维数

我们可以使用符号 ... 来指定广播的维数。 当我们对一个具有多个维度的数组进行广播时,可以选择广播的维数。 例如:

a = [1 2 3]
b = [4,5,6]
c = a .+ b  # 该语句等价于 a .+ b'

在这个例子中,我们使用了 a .+ b' 来强制把数组 b 成为一个行向量,这里的 ' 表示转置。 但是,我们也可以使用 ... 来指定广播的维度:

c = a .+ b'...

这将产生与 a .+ b' 等效的结果。

广播的效率

使用数组广播是非常高效的,因为它使用了优化的底层代码,可以有效地利用 CPU 中的矢量化指令和多核处理器。 在许多情况下,使用数组广播比使用循环更快。

总结

在 Julia 中,使用数组广播可以轻松对数组进行相同的操作,而不需要显式循环。 Julia 自动地应用广播的规则,以确定哪些数组可以广播,以及如何对它们进行广播。 在许多情况下,使用广播可以更加清晰和高效地编写代码。