广播是指当Octave二进制运算符和函数的矩阵或数组操作数或自变量大小不同时,它们的行为方式。自3.6.0版本以来,Octave现在在使用元素二进制运算符和函数时自动广播向量、矩阵和数组。从广义上讲,较小的数组在较大的数组中“广播”,直到它们具有兼容的形状。规则是,相应的雷维度必须
在所有维度相等的情况下,不发生广播,并通过元素算术进行排序。对于较高维度的数组,如果维度的数量不相同,则丢失的尾部维度将被视为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按元素到两个数组参数A和B,根据需要扩展任一输入参数中的单例维度。
f是一个函数句柄、内联函数或字符串,其中包含要计算的函数的名称。函数f必须能够接受两个相等长度的列向量参数,或者一个标量列向量参数。
的尺寸A和B必须相等或为singleton。数组的单个维度将扩展到与其他数组相同的维度。
只有当两个广播条件中的任何一个成立时,才应用广播。然而,与往常一样,当两个维度不同且都不是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秒。因此,一般来说,编写具有广播语义的代码以提高性能是值得的。
然而,如果一个更简单的操作就足够了,请注意不要求助于广播。对于矩阵a和b,请考虑以下内容:
c=总和(置换(a,[1,3,2]).*permute(b, [3, 2, 1]), 3);
该操作在按元素相乘期间广播具有排列维度的两个矩阵,以获得更大的三维数组,然后沿第三维度对该数组求和。只要想一想,就会证明这个运算就是最简单的普通矩阵乘法,c= a*b;
.
术语注释:“广播”是Numpy数值环境在Python编程语言中推广的术语。在其他编程语言和环境中,广播也可能是已知的二进制单例展开(BSX,在MATLAB,以及的名称的起源bsxfun
作用回收(R编程语言),单指令多数据(SIMD),或复制.
新的广播语义几乎从不影响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号