4

次のような関数があるとしましょう。

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

そして、私は次のような配列を持っています、

x = 0:0.1:1;

関数を使用してのy2乗を格納する配列が必要です。確かに、1つの方法は次のようになります、xSquare

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代わりにを使用したことに注意してください。iMatlab ではij虚数単位の組み込み名です。変数名として使用すると、必要な名前解決が必要になるため、パフォーマンスが低下します。iまたは以外のものを使用すると、それjが防止されます。

于 2012-12-11T09:13:44.347 に答える
2

あなたがしたいarrayfun

arrayfun(@Square, x)

見るhelp arrayfun

(GNU Octave でのみテストされています。MATLAB は持っていません)

于 2012-12-11T09:07:20.590 に答える
2

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

コードを数回実行したところ、関数を 1 回呼び出すだけで少なくとも 2 倍高速であることがわかりました。

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 に答える
2

要素ごとの演算子を検討しました.*か?

算術演算子のドキュメントを参照してください。

于 2012-12-11T09:09:42.823 に答える