2016-03-22 2 views
1

対応する乗算:temp10万* 3マトリクスあるインデックス外マトリクスの列ベクトルを、次のように私は重い計算を有するマトリックス

L = ones(100000,200000); 
for i = 1:10000 
    temp = f(i,...); 
    L = L .* temp(:, index); 
end 

(値はf(i,...)から計算され、私はここに引数を省略)とは、1 * 200,000整数ベクトル(1〜3)です。

私は自分のアルゴリズムで何度も何度もやらなければなりません。私はMatlabが反復でtemp(:, index)から100000 * 200000を作成する時間を無駄にすると感じます。しかし、それは必要ではないかもしれません。つまり、対応する列を抽出してから、対応する列のLに掛けることができます。しかし、私は効率的にそれを行う方法を見つけることができません...

誰もがこれについて助言を与えることができます。ありがとう!

私は小さなおよび仮想的な例を与える:

function test 
x = rand(5,3); 
t = rand(10,1); % could be very long 
point = 3; 
index = [1 2 1 3 2 3 1 2;... 
     2 3 2 1 2 3 1 1;... 
     1 1 1 2 2 3 1 1;... 
     3 3 2 3 2 2 2 1;... 
     2 3 2 1 2 1 3 1]; % could be very long 
L = ones(10,8); 
for i = 1:5 
    temp = myfun(x(i,:),t,point); 
    L = L .* temp(:, index(i,:)); 
end 
    function prob = myfun(x,t,point) 
    prob = ones(size(t,1),point); 
    for k = 2:point 
     prob(:,k) = exp(((k-1).*x(1).*(t) + x(k))); 
    end 
    de = sum(prob,2); 
    for k = 1:point 
     prob(:,k) = prob(:,k)./de; 
    end 
    end 
end 
+1

質問を明確にしてください。作業コードを使って簡単な例を作ると、nxmの行列を10x20程度に変更できます。そうすれば、私はあなたを助けることができるでしょう。 – JCKaz

+2

'temp'変数を避けたい場合は、' f(i、...) 'の行全体を指定する必要があります。私は手で計算された数字で小さな説明的な例を追加することをお勧めします。 – Dan

+2

データにゼロが多い場合は、[疎行列](http://ch.mathworks.com/help/matlab/ref/sparse.html)を使用することを検討してください。 –

答えて

1

私は、おそらくそれはしかし、あなたの大きな行列の違いは、各反復の間にはいくつかのマイナーな計算を節約するために管理。私がしたのは、ある行をprob(:,k) = exp(((k-1).*x(i,1).*(t) + x(i,k)));に変更することでした。 xの要素に注目してください。これにより、不要な計算がいくつか節約されます。私はこれが何であるか見当がつかないように、これを最適化することがやや困難であるが、ここに私のコードは次のとおりです。

x = rand(5,3); 
t = rand(10,1); 
point = 3; 
index = [1 2 1 3 2 3 1 2;... 
     2 3 2 1 2 3 1 1;... 
     1 1 1 2 2 3 1 1;... 
     3 3 2 3 2 2 2 1;... 
     2 3 2 1 2 1 3 1]; 
L = ones(10,8); 
for i = 1:5 
    prob = ones(size(t,1),point); 
    for k = 2:point 
     prob(:,k) = exp(((k-1).*x(i,1).*(t) + x(i,k))); 
    end 
    de = sum(prob,2); 
    for k = 1:point 
     prob(:,k) = prob(:,k)./de; 
    end 
    L = L .* prob(:, index(i,:)); 
end 

私は気づいた、いくつかの危険な操作がありますが、例えばde = sum(prob,2);prob(:,k) = prob(:,k)./de;prob(:,k) = prob(:,k)./sum(prob,2);に変更すると、結果が異なることに注意してください。おそらくあなたはこれをすでに認識していますが、それは言及する価値があるかもしれません。私が手伝ってくれるものがあれば教えてください。

+1

ありがとう、@ JCKaz。実際、 'myfun'はアルゴリズム外で指定されています。上記の例では、デモンストレーションのためにネストされた関数として記述します。 'profile on'の後に、' L = L。* temp(:、index(i、:));という行が重い計算の重要な部分であることがわかりました。 matlabに、 'temp(:、index(i、:))の行列を実際に(内部的に)作成せずに' L 'と 'temp(i、:)の間の対応する列を掛けるようにすればいいと思います。 ) '。それは時間を節約するはずです。しかし、MatlabにはC++やFortranのような参照関数やポインタがないようです。 –

+0

私は参照してください。しかし、あなたは 'prob(:、k)= exp((k-1)。* x(i、1)。*(t)+ x(i、k)))最初にxベクトル、行列全体を解析し、それをベクトルに変換してから1つの要素を抽出する必要はありません。今すぐ要素をただちに取得します。 – JCKaz

+0

これを指摘してくれてありがとう、私はそれを見た。それは確かに時間を節約します:) 'L = L。* temp(:、index(i、:));'には考えがありますか?それは私が克服しなければならない重要な部分です。 –

関連する問題