假设我有一个功能,例如:
function [result] = Square( x )
result = x * x;
end
我有一个类似下面的数组,
x = 0:0.1:1;
我希望有一个y
数组,使用我的x
函数存储Square
的方块。当然,一种方法是以下,
y = zeros(1,10);
for i = 1:10
y(i) = Square(x(i));
end
但是,我想应该有一种更优雅的方式。我尝试了一些我的见解并进行了一些搜索,但无法找到任何解决方案。有什么建议吗?
答案 0 :(得分: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中,i
和j
是虚构单元的内置名称。如果将其用作变量名称,则由于需要必要的名称解析,您将失去一些性能。使用i
或j
以外的任何内容都可以防止这种情况发生。
答案 1 :(得分:2)
您想要arrayfun
。
arrayfun(@Square, x)
请参阅help arrayfun
(仅在GNU Octave测试,我没有MATLAB)
答案 2 :(得分:2)
您是否考虑了逐个元素的运算符.*
?
请参阅arithmetic operators的文档。
答案 3 :(得分: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.