2012-12-11 74 views
4

比方说,我有一个功能,如:呼叫功能

function [result] = Square(x) 
    result = x * x; 
end 

和我有类似如下的数组,

x = 0:0.1:1; 

我想有一个y阵列,它使用我的Square函数存储x的正方形。当然,一个办法是下面

y = zeros(1,10); 

for i = 1:10 
    y(i) = Square(x(i)); 
end 

不过,我想应该有这样做的更优雅的方式。我尝试了一些我的见解并进行了一些搜索,但找不到任何解决方案。有什么建议么?

回答

10

对于你给的例子:

其中
y = x.^2; % or 
y = x.*x; 

.*.^*^逐元素的版本。这是最简单,最快捷的方式。

更普遍的:

y = arrayfun(@Square, x); 

可以是优雅的,但相对于

y = zeros(size(x)); 
for ii = 1:numel(x) 
    y(ii) = Square(x(ii)); end 

其实我建议要远离arrayfun远离它通常很慢,直到分析已经表明,它是比简单的循环更快。这将很少,如果有的话。

在新的Matlab版本(R2008及更高版本)中,JIT加速循环的效率非常高,以至于像arrayfun这样的内容在未来版本中可能会消失。

另外:请注意,我用ii而不是i作为循环变量。在Matlab中,ij是虚构单元的内置名称。如果您将其用作变量名称,则由于必需的名称解析而导致性能下降。使用除ij以外的任何内容都会妨碍这一点。

+0

你是绝对正确的'arrayfun'比元素内置函数慢 - 除非你使用'gpuArray's,其中'arrayfun'是要走的路。 – Edric

+0

@Edric:一个该死的,我真的希望我有一个GPU来玩这个东西......我不知道它!感谢您的高举。不会*总是*更快我会想象(由于相关的内存问题),但仍然可以想象,它通常会更快。 –

+0

@Edic:顺便说一下 - *真* *?为什么'x。^ 2'(''''''''gpuArray')*不会*分布在GPU上? –

2

你想要arrayfun

arrayfun(@Square, x) 

help arrayfun

(仅在GNU八度测试,我没有MATLAB)

2

我打算假设你不会做像平方操作那样简单的事情,而你正在尝试做的事情还没有在MATLAB中进行矢量化。

最好调用一次函数,并在函数中做循环。随着元素数量的增加,您会注意到操作时间的显着增加。

让我们的职能是:

function result = getSquare(x) 
    result = x*x; % I did not use .* on purpose 
end 

function result = getSquareVec(x) 
result = zeros(1,numel(x)); 
    for idx = 1:numel(x) 
     result(:,idx) = x(idx)*x(idx); 
    end 
end 

而且,我们称他们从脚本:

y = 1:10000; 
tic; 
for idx = 1:numel(y) 
    res = getSquare(y(idx)); 
end 
toc 

tic; 
    res = getSquareVec(y); 
toc 

我跑了代码几次,原来调用该函数只有一次是至少快两倍。

Elapsed time is 0.020524 seconds. 
Elapsed time is 0.008560 seconds. 

Elapsed time is 0.019019 seconds. 
Elapsed time is 0.007661 seconds. 

Elapsed time is 0.022532 seconds. 
Elapsed time is 0.006731 seconds. 

Elapsed time is 0.023051 seconds. 
Elapsed time is 0.005951 seconds.