2016-05-15 5 views
0

parforを使用して結果行列を書き込むにはどうすればよいですか?行列をparforで書くことができない

コードサンプル:

xCount = 10; 
yCount = 20; 
area = xCount*yCount; 
PP = nan(area,3); 

parfor x = 1:10 
    for y = 1:20 
     id = y + (x-1)*yCount; % global PP line id. 
     z = x^2+y*10; % my stuff to get Z. 
     PP(id,:) = [x y z]; % write to PP line 
    end 
end 

のparforループが原因変数 'PP' が使用されているように実行することができません。

答えて

3

実際には、「有効なインデックスはPARFORループ内で制限されています」と言います。その理由は、MATLABはparforループを連続して反復します。つまり、1 2 3 4 5ではなく、5 2 4 1 3のような半無作為な順序で反復を実行できます。これは、PPのMATLABが結果を格納しなければならない場所を知るために、並列環境に入る前に、異なる反復によって行が呼び出されないことを知り、結果をワーカーから返す際の競合を避けることを望みます。

解決策は、インデックスがどこにストアされているかが事前に分かっているような方法で構造PPになります。 2次元配列を作成することにより、中のものを保存するためにループの前に使用する:

xCount = 10; 
yCount = 20; 
area = xCount*yCount; 
PP(xCount,yCount) = 0; 
y=1:yCount; 

parfor x = 1:xCount 
    z = x^2+y.*10; % my stuff to get Z. 
    PP(x,:) = z; % write to PP line 
end 
%// Go to the [x y z] format 
PP = [repmat((1:yCount).',xCount,1),repmat((1:xCount).',yCount,1), PP(:)]; 

それは内ながら各役立ち値の3倍(z)を、保存するので、私は個人的に、この場合の最後の行をしないだろうループから出てくる2Dマトリックスは1つのdoubleを格納するだけで、単にPP(x,y)を読み込むことで索引付けすることができます。したがって、同じ量の有用なデータを格納するために3倍のメモリが必要になります。

+0

インデックスの配列を生成する代わりに、 'i = 1:area'をparループし、' ind2sub([xCount、yCount]、i) 'を使って対応するx、yの値を見つけることができます。そうすれば、 'PP(i) 'への代入はMatlabによって完全にスプライス可能になります。 –

+0

ありがとう!しかし、私はMatlabのチームには本当に同意しません。 C#で私はそれを行うことができます。 Matlabの人は、私が思うには、ほんの少しの保護層を追加しました!私のIDの計算は正しい、すべてのIDは一意になります。本当に、これは悪臭を放つ! – Pedro77

+0

@ Pedro77 MATLABの内部エンジンには強くありませんが、同じ要素に同時にアクセスしようとする2人の作業者がいるとき、下腹部の何かがうんざりするので、すべてのインデックスが一意であることを事前に知りたい* 。なぜそれがC#、単純な、MATLAB〜= C#のように動作しません。 – Adriaan

関連する問題