2013-03-22 10 views
7

matlabのparforを使ってこの単純なコードで何が起こっているのか誰かが知っていますか? おかげで、Matlab parforループインデックス

は、私は4つの配列に行列をスライスし、各配列の要素を更新する独立

をここで簡単なバージョンです:

a = zeros(4,4); 
parfor i = 1:4 
    j = 2;  
    a(j,i) = 3; 
end 

エラー:「」制限されているの有効な指標parforループで;

a = zeros(4,4); 
parfor i = 1:4 
    a(2,i) = 3; 
end 

同じエラーを持つ別のシンプルな非稼働バージョン:私のアプリケーションで

a = zeros(4,4); 
parfor i = 1:4 
    a(i,i) = 3; 
end 

は、インデックスjがいくつかをアレイごとに独立して生成されたこの作品

しかし

、アルゴリズム

+1

ループ内に他のインデックス変数を設定できないようです。参照してください:http://www.mathworks.com/matlabcentral/newsreader/view_thread/162203 – cyang

+0

どのバージョンのmatlabを使用していますか? – alrikai

+0

MATLABの私のバージョンでは持っていませんが、私は 'parpool'を見てみる価値があると思います - http://www.mathworks.it/it/help/distcomp/parpool.html –

答えて

1

達成しようとしていること可能ではない。

は、MATLABドキュメントによると:

When you use other variables along with the loop variable to index an array, you cannot set these variables inside the loop. In effect, such variables are constant over the execution of the entire parfor statement. You cannot combine the loop variable with itself to form an index expression.

MATLAB Documentation Source

ですから、インデックスを使用するすべての変数は、ループ変数以外のあなたの配列は、ループ全体のために一定である必要があります。

+0

です。私は、2D配列を索引付けするために、parfor内にforループをネストすることが可能であることを知りました。 "for"ループ変数、例えば:for j = 1:4 {a(i、j)= ..}は、forforループ内で変更できます。for i = 1:4 {}。 jがすべての繰り返しに対して同じであれば、それは安全です。実際には、あなたが参照している文書でこれを見つけました。「固定インデックスリスト - 第1レベルのかっこ内のインデックスのリストは、指定された変数(スライスされた変数)のすべての出現で同じです。 –

2

ちょうど私の2セント:@ mmumbosはすでに説明したように、達成しようとしていることはこのようにはできませんが、一定の回避策が適用されます。

のは、あなたが(行列Aの線形変換の順列である)は、次のようなものを実装する必要があると仮定しましょう:

n=10; 
A=rand(n,n); 
B=zeros(n,n); 
parfor i=1:n, 
    j=(i<=5)*(2*(i-1)+1)+(i>5)*(2*(i-5)); 
    B(j,i) = my_function(A(i,:)); 
end 

は、代わりに次のことを試してみてください。

parfor i=1:n, 
    B_temp(i,:) = my_function(A(i,:)); 
end 

次に、あなたを行列Bを実際に構築する必要はありません。あなたは、次のように簡単に構成された「」インデックステーブル「」を使用してB_tempを使用してアクセスすることができます

J=zeros(n,1); 
parfor i=1:n, 
    J(i) = (i<=5)*(2*(i-1)+1)+(i>5)*(2*(i-5)); 
end 

その後B(i)B_temp(J(i))を介してアクセスされます。あなたの最後の(カウンタ)の例を再考

は、あなたがそれを周りに働くことができる方法を見てみましょう:

その後
n=4; 
diag_A = zeros(n,1); 
parfor i=1:n, 
    diag_A(i)=3; % or any function of i 
end 

、あなたは「」i「は」にアクセスする必要があるとき - Aの番目の対角要素、あなたのアクセスを代わりにdiag_A(i)。このような場合のために、次の行に沿って関数を作成すると便利です:

function a = access_matrix(A, diag_A, i, j) 
    if (i!=j), 
    a = A(i,j); 
    else 
    a = diag_A(i); 
    end 
end 

MATLABはparforの実装を改善するまでは、そのような回避策は(残念ながら)例ロットで必要になります。

+0

'B_temp'を構築するために使用されるコードの2番目のセクションは、Matlab(R2016a)でエラーを引き起こします。 –

+0

@エリクMありがとうございました - あなたは実際にタイプミスを発見しました。左辺は 'B_temp(i、i)'ではなく 'B_temp(i、:)'でなければなりません。 –

0

まだ言及されていないので、これらのタイプの問題の診断に本当に役立つリンクがあります:Classification of Variables in Parfor。これらの問題は、MATLABが変数をそのページで概要を示す厳密な定義に分類できない場合に発生します。

ここでは、ループの前にスライス変数Aをスライスする方法がわかりません。あなた自身で並列実装をプログラミングすることを考えてください。あなたがしたいことは、他のプロセッサが触れることができないことを知っている偶数個の部分にカットアップAを入れてから、それらを独立して行動するために異なるCPUに渡すことです。 MATLABはループを調べ、プログラムを実行するまで何がjかわからないため、これを行う方法がわかりません。これはMATLABの限界です。 A(i * j、:)のような複雑な係数を使うと同じことが起こる別のケースです。もう一度それを分割する方法は分かりません。

関連する問題