19.2广播

广播是指当Octave二进制运算符和函数的矩阵或数组操作数或自变量大小不同时,它们的行为方式。自3.6.0版本以来,Octave现在在使用元素二进制运算符和函数时自动广播向量、矩阵和数组。从广义上讲,较小的数组在较大的数组中“广播”,直到它们具有兼容的形状。规则是,相应的雷维度必须

  1. 相等,或
  2. 其中一个必须是1。

在所有维度相等的情况下,不发生广播,并通过元素算术进行排序。对于较高维度的数组,如果维度的数量不相同,则丢失的尾部维度将被视为1。当其中一个维度为1时,具有该单例维度的数组将沿着该维度进行复制,直到它与另一个数组的维度匹配。例如,考虑

x=[1 2 3;4 5 6;7 8 9];y=[10 20 30];x+y

在没有广播的情况下,x+y这将是一个错误,因为尺寸不一致。然而,在广播中,似乎执行了以下操作:

x=[1 2 3 4 5 6 7 8 9];y=[10 20 30 10 20 30 10 10 20 30];x+y⇒    11   22   33      14   25   36      17   28   39

也就是说,较小的数组大小[1 3]沿ngleton维度(行数)复制,直到[3 3]。然而,没有实际的复制发生。内部实现沿着必要的维度重用元素,以便在不复制内存的情况下实现所需的效果。

两个数组都可以在彼此之间广播,例如,向量的元素与其自身的所有成对差异:

y-y'⇒    0   10   20    -10    0   10    -20  -10    0

这里是大小的向量[1 3][3 1]两者都获取广播到大小的矩阵中[3 3]在普通的矩阵分解发生之前。

可能熟悉的广播的一个特殊情况是,当正在广播的数组的所有维度都是1时,即,数组是向量。因此,例如,像这样的操作x-42最大值(x,2)是广播的基本例子。

对于更高维的示例,假设img是大小的RGB图像[m n 3]我们希望将每种颜色乘以一个不同的标量。以下代码通过广播来实现这一点,

img.*=置换([0.8,0.9,1.2],[1,3,2]);

请注意使用permute来匹配的尺寸[0.8, 0.9, 1.2]向量带有img.

对于没有用广播语义编写的函数,bsxfun可以用于强制他们进行广播。

 
: C = bsxfun (f, A, B)

应用二进制函数f按元素到两个数组参数AB,根据需要扩展任一输入参数中的单例维度。

f是一个函数句柄、内联函数或字符串,其中包含要计算的函数的名称。函数f必须能够接受两个相等长度的列向量参数,或者一个标量列向量参数。

的尺寸AB必须相等或为singleton。数组的单个维度将扩展到与其他数组相同的维度。

详见: 元胞数组, cellfun.

只有当两个广播条件中的任何一个成立时,才应用广播。然而,与往常一样,当两个维度不同且都不是1:

x=[1 2 3 4 5 6];y=[10 20 30 40];x+y

这将返回关于不一致参数的错误。

除了常见的算术运算外,两个自变量的几个函数也会广播。广播的函数和运算符的完整列表

加+减-倍。*参考。/ldivide。\权力lt<le<=eq==gt>ge>=ne!=~=和&或|atan2海波最大最小模rem xor+=-=.*=./=.\=.^=&=|=

这是广播力量的一个真实例子。Floyd-Warshall算法用于计算图中每对顶点之间的最短路径长度。序图邻接矩阵的一个简单实现n可能看起来是这样的:

对于k=1:n对于i=1:n对于j=1:nist(i,j)=min(dist(i,j),dist(i,k)+dist(k,j));endforendforendfor

对最里面的循环进行向量化后,它可能看起来像这样:

对于k=1:n对于i=1:n dist(i,:)=min(dist(ⅰ,:),dist(ⅱ,k)+dist(k,:));endforendfor

使用双向广播,看起来是这样的:

对于k=1:n dist=min(dist,dist(:,k)+dist(k,:));外循环

对于具有100个顶点的给定图,这三种技术的相对时间性能对于初始代码为7.3秒,对于向量化代码为87毫秒,对于完全广播代码为1.3毫秒。对于一个有1000个顶点的图,向量化需要11.7秒,而广播只需要1.15秒。因此,一般来说,编写具有广播语义的代码以提高性能是值得的。

然而,如果一个更简单的操作就足够了,请注意不要求助于广播。对于矩阵ab,请考虑以下内容:

c=总和(置换(a,[1,3,2]).*permute(b, [3, 2, 1]), 3);

该操作在按元素相乘期间广播具有排列维度的两个矩阵,以获得更大的三维数组,然后沿第三维度对该数组求和。只要想一想,就会证明这个运算就是最简单的普通矩阵乘法,c= a*b;.

术语注释:“广播”是Numpy数值环境在Python编程语言中推广的术语。在其他编程语言和环境中,广播也可能是已知的二进制单例展开(BSX,在MATLAB,以及的名称的起源bsxfun作用回收(R编程语言),单指令多数据(SIMD),或复制.

19.2.1广播和遗留代码

新的广播语义几乎从不影响Octave以前版本中的代码。因此,从继承的所有代码MATLAB在之前版本的Octave中有效的应该仍然有效,而不会更改Octave。唯一的例外是以下代码

尝试c=a.*b;catch c=a.*a;end_try_catch

这可能依赖于返回误差的不同大小的矩阵。因为这样的操作现在是有效的Octave语法,所以这不会再导致错误。相反,应使用以下代码:

如果(isequal(大小(a),大小(b)))c=a.*b;否则c=a.*a;endif

版权所有 © 2024 Octave中文网

ICP备案/许可证号:黑ICP备2024030411号