Matlab中是否有类似于Numpy广播的功能?

24

我正在尝试在Matlab中将一个大小为3的向量从一个3*(一个很大的数字)矩阵的每一列中减去。当然,我可以使用循环,但我正在尝试寻找一些更有效的解决方案,有点像numpy广播。哦,我不能使用repmat,因为我没有足够的内存来使用它(因为它会创建另一个3*(一个很大的数字)的矩阵)...

这是否可能?


1
正如最近的一个回答所指出的那样,Matlab R2016b似乎已经将广播作为一项标准功能添加进去了。(https://nickhigham.wordpress.com/2016/09/20/implicit-expansion-matlab-r2016b/) - Charlie Parker
4个回答

19

其他答案有些过时了——Matlab R2016b似乎已经成为标准功能添加了广播。该博客文章中与问题匹配的示例:

>> A = ones(2) + [1 5]'
A =
     2     2
     6     6

3
2016b版本还有其他令人惊叹的新功能,比如一流的字符串(https://www.mathworks.com/help/matlab/matlab_prog/create-string-arrays.html),可以用“+”连接。哦,我只是在说反话 :-) - antony
注意:广播是很好的,但有时你得不到你想要的。我刚花了4个小时追踪我的代码中的错误:x=(1-A+K*C)^-1; % A是一个nxn矩阵。MATLAB不知道我想要单位矩阵!(分享给其他人的利益)。 - Bill

18
循环在MATLAB中不再是坏事,这要归功于编译器优化,例如即时加速(JITA)。大部分时间,我发现使用循环的解决方案在当前版本的MATLAB中比复杂的一行代码(尽管很酷:D)要快得多。

bsxfun可能会有所帮助但是根据我的经验,它也可能存在内存问题,但比repmat少。

因此,语法将是:

AA = bsxfun(@minus,A,b)其中b是向量,A是您的大矩阵

但我建议您对循环版本进行分析,然后再决定!由于内存限制,您可能没有选择 :)


你对 BSXFUN 的想法可能是正确的。它仍然会有内存问题,但我相信它通常比使用 REPMAT 做得稍微好一点。 - gnovice
3
我喜欢bsxfun的原因是在2010a和2010b版本中,它可以本地多线程运行您的代码,从而提高性能,而且不需要太多干预。 - JudoWill
@JudoWill:太好了!我一直在寻找反对repmat的明确案例——你有相关文档吗? - Jacob
2
也许你可以通过这个链接:http://www.mathworks.com/support/solutions/en/data/1-4PG4AN/?solution=1-4PG4AN 来了解,正如你所看到的,只有当矩阵足够大时,多线程才会启动。 - Amro
正如较新的答案之一所指出的那样,Matlab R2016b似乎已经将广播作为标准功能添加进去了。(https://nickhigham.wordpress.com/2016/09/20/implicit-expansion-matlab-r2016b/) - Charlie Parker

4

我不确定这样做是否会加快代码运行速度,但从向量中减去标量不会出现内存问题。由于您的矩阵大小非常不对称,在短维上使用for循环的开销可以忽略不计。

因此也许

matout = matin;
for j = 1:size(matin, 1) %3 in this case
     matout(j,:) = matin(j,:) - vec_to_subtract(j);
end

当然,您可以直接在原地进行操作,但我不知道您是否想保留原始矩阵。


实际上,for循环在大维度上(因为我正在从大小为3的向量中减去大小为3 *(很多)的数组的每一列),所以这就是我害怕for循环的原因。 - antony
这样想——将数组分成大小为1xN的3个向量。然后从每个向量中减去相应的标量。因此,for循环沿着短维度进行。 - Marc

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接