4

假设我有一个功能,例如:

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

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

4

4 回答 4

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是虚数单位的内置名称。如果您将其用作变量名,由于需要进行必要的名称解析,您将失去一些性能。使用除ior以外的任何东西j都会阻止这种情况。

于 2012-12-11T09:13:44.347 回答
2

你想要arrayfun

arrayfun(@Square, x)

help arrayfun

(仅在 GNU Octave 中测试,我没有 MATLAB)

于 2012-12-11T09:07:20.590 回答
2

您是否考虑过逐个元素的运算符.*

请参阅算术运算符的文档。

于 2012-12-11T09:09:42.823 回答
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.
于 2012-12-11T09:41:46.657 回答