允许i = [1 2]
和j = [3 5]
。现在是八度:
arrayfun(@(x,y) x+y,i,j)
我们得到[4 7]
。但我想在i
与j
的组合上应用该函数来获取[i(1)+j(1) i(1)+j(2) i(2)+j(1) i(2)+j(2)]=[4 6 5 7]
。
我如何做到这一点?我知道我可以使用for-loopsl但我想要矢量化代码,因为它更快。
答案 0 :(得分:1)
首先,你的第一个例子并不是最好的,因为用arrayfun
完成你所做的事情最有效的方法就是矢量化:
a = [1 2];
b = [3 5];
out = a+b
其次,至少在Matlab中,arrayfun
不一定比简单的for
循环更快。 arrayfun
主要是一种便利(特别是对于它更高级的选项)。请亲自尝试这个简单的计时示例:
a = 1:1e5;
b = a+1;
y = arrayfun(@(x,y)x+y,a,b); % Warm up
tic
y = arrayfun(@(x,y)x+y,a,b);
toc
y = zeros(1,numel(a));
for k = 1:numel(a)
y(k) = a(k)+b(k); % Warm up
end
tic
y = zeros(1,numel(a));
for k = 1:numel(a)
y(k) = a(k)+b(k);
end
toc
在Matlab R2015a中,for
循环方法从命令窗口运行速度快70倍,从M文件函数运行速度快260多倍。八度可能不同,但你应该试验。
最后,您可以使用meshgrid
完成所需内容:
a = [1 2];
b = [3 5];
[x,y] = meshgrid(a,b);
out = x(:).'+y(:).'
会在您的问题中返回[4 6 5 7]
。您还可以使用ndgrid
以不同的顺序获取输出。
答案 1 :(得分:1)
在Octave中,为了找到两个向量之间的求和,您可以使用真正的向量化方法broadcasting
,如此 -
out = reshape(ii(:).' + jj(:),[],1)
这是ideone
对每个大小为1 x 100
的输入向量的运行时测试 -
-------------------- With FOR-LOOP
Elapsed time is 0.148444 seconds.
-------------------- With BROADCASTING
Elapsed time is 0.00038299 seconds.
如果你想保持它的通用性以适应除了汇总之外的操作,你可以使用像这样的匿名函数 -
func1 = @(I,J) I+J;
out = reshape(func1(ii,jj.'),1,[])
在MATLAB中,您可以使用下面列出的两个bsxfun
替代方案来完成相同的操作。
予。带有匿名函数的bsxfun
-
func1 = @(I,J) I+J;
out = reshape(bsxfun(func1,ii(:).',jj(:)),1,[]);
II。 bsxfun
内置@plus -
out = reshape(bsxfun(@plus,ii(:).',jj(:)),1,[]);
对于每个大小为1 x 10000
的输入向量,我的运行时间为 -
-------------------- With FOR-LOOP
Elapsed time is 1.193941 seconds.
-------------------- With BSXFUN ANONYMOUS
Elapsed time is 0.252825 seconds.
-------------------- With BSXFUN BUILTIN
Elapsed time is 0.215066 seconds.