4

フォームの評価をたくさん行う必要があります

X(:,i)' * A * X(:,i)   i = 1...n

ここで、X(:、i)はベクトルで、Aは対称行列です。表面上、私はこれをループで行うことができます

for i=1:n
    z(i) = X(:,i)' * A * X(:,i)
end

遅いか、次のようにベクトル化します

z = diag(X' * A * X)

これは、Xに多数の列がある場合、RAMを許容できないほど浪費します。現在、私は妥協しています

Y = A * X
for i=1:n
    z(i) = Y(:,i)' * X(:,i)
end

これは少し速く/軽いですが、それでも不十分なようです。

この結果をより効率的に達成するために、matlab / scilabのイディオムまたはトリックがあるのではないかと期待していましたか?

4

3 に答える 3

3

これを試して:

z = dot(X, A*X)

ここにテストするMatlabはありませんが、Octaveで動作するため、Matlabにも同様の dot()機能があると思います。

Octaveの助けから:

  -- Function File:  dot (X, Y, DIM)
     Computes the dot product of two vectors. If X and Y are matrices,
     calculate the dot-product along the first non-singleton dimension.
     If the optional argument DIM is given, calculate the dot-product
     along this dimension.
于 2010-04-02T20:23:57.940 に答える
3

これをMATLABで試してください。

z = sum(X.*(A*X));

これにより、関数DOTを使用したFedericoの提案と同等の結果が得られますが、実行速度はわずかに速くなります。これは、DOT関数が、 SUM関数を使用して上記で行ったのと同じ方法で結果を内部的に計算するためです。ただし、DOTには、複素数を処理する場合のための追加の入力引数チェックと追加の計算もあります。これは、おそらく不要または不要な余分なオーバーヘッドです。

計算効率に関する注記:

2つのメソッドの実行速度の時間差はわずかですが、操作を度も実行する場合は、合計が開始されます。相対速度をテストするために、ランダムな値の2つの100行100列のマトリックスを作成し、2つのメソッドの時間を多くの実行にわたって計時して、平均実行時間を取得しました。

    METHOD        AVERAGE EXECUTION TIME
--------------------------------------------
Z = sum(X.*Y);        0.0002595 sec
Z = dot(X,Y);         0.0003627 sec

したがって、 DOTの代わりにSUMを使用すると、約10,000要素の行列の場合にこの操作の実行時間が約28%短縮されます。行列が大きいほど、2つの方法の違いは無視できます。

要約すると、この計算がコードの実行速度に重大なボトルネックを示している場合は、 SUMを使用したソリューションを使用します。それ以外の場合は、どちらのソリューションでも問題ありません。

于 2010-04-02T20:24:23.403 に答える
1

完全を期すために、Scilabでのgnoviceの答えは次のようになります。

z = sum(X .* Y, 1)'
于 2010-04-02T22:52:25.100 に答える