`eye(2)` 和 `[1, 0; 之间的区别0, 1]` 自动广播

Difference between `eye(2)` and `[1, 0; 0, 1]` in automatic broadcasting

我想从 Octave(版本 4.4.1)的单位矩阵的每一列中减去一个向量 v,例如v = [1; 1].

为什么自动广播对命令 eye 不起作用?

eye(2) - [1; 1]

error: operator -: nonconformant arguments (op1 is 2x2, op2 is 1x2)

bsxfun(@minus,eye(2),[1; 1])[1, 0; 0, 1] - [1; 1] 都产生

[0, -1; -1, 0]

Octave为什么要在自动播放上做这样的区分?为什么 eye(2) 不等于 [1, 0; 0, 1]


注意:在Matlab R2016a中,我没有自动广播,所以我只能使用bsxfun(@minus,eye(2),[1; 1]),这是一致的,因此不那么混乱。

对此(至少在八度内)的技术答案是 eye(2) 不会产生与 [1,0;0,1] 相同的类型;它产生一个内存效率高的对角矩阵,而 Octave 没有为对角矩阵类型实现可广播的负函数(还*)。

> typeinfo([1,0;0,1])
ans = matrix

> typeinfo(eye(2))
ans = diagonal matrix

> diag([1,1])- [1;1]
% error: operator -: nonconformant arguments (op1 is 2x2, op2 is 2x1)

> full( diag([1,1]) ) - [1;1]
% works

事实上,如果您尝试广播等效的稀疏矩阵,您会遇到同样的问题:

> sparse([1,0;0,1]) - [1;1]
%error: operator -: nonconformant arguments (op1 is 2x2, op2 is 2x1)

如果您想在不转换回完整矩阵的情况下执行广播(例如通过 full(eye(2)) - [1; 1]),您可以回退到 bsxfun,这是一个旨在明确执行广播的函数。

话虽如此,bsxfun 的输出是一个普通矩阵,这意味着如果先 'collected' 来自特殊类型的 full 矩阵,然后使用广播,你会得到相同的结果正如预期的那样,因此我怀疑在这种情况下使用 bsxfun 是否会提高效率。相反,bsxfun 在与 bsxfun( @(x,y) x-y, eye(2), [1;1] ) 等计算成本高昂的反模式(这很常见,但谢天谢地不是你所做的)一起使用时会导致性能下降。


* 话虽如此,如果这不是错误,那么它肯定是一个功能。值得在 Octave bugtracker 上开一张票(如果还没有的话!)。

在 R2016b Matlab 中更改了 隐式扩展 算法,请参阅此 blog-post from Loren - on the art of Matlab. There is another useful post here.

基本上,它使 Matlab 对于不喜欢编程的人来说更加用户友好,他们只是想把事情做好,他们大多是工程师(比如我)。因此,如果向量不适合一维矩阵(该维度将被扩展),Matlab 现在将扩展向量。这既好又坏。您的代码变得更短且更具可读性(因为您不需要使用 repmat 手动扩展它)但它也使您的代码容易出现代码中的缺陷,这些缺陷将被忽略并导致奇怪的错误管道。 在任何情况下,如果涉及到代码生成,您仍然需要使用 repmat.

显式扩展向量