2012-04-06 11 views
2

私は、parforループにスクランブルされた準モンテカルロ数を生成する問題があります。Parforループでスクランブルされた準モンテカルロ数を生成する問題

問題は、私がparforループ内でこれらの数字の複数のセットを生成すると、各セットの数字が同じになることです。私は以下の非常に簡単な例を含めています。

>>numbers{1}(1:3,:) 
ans = 
      0.76   0.05   0.77 
      0.33   0.96   0.23 
      0.60   0.72   0.52 

>> numbers{2}(1:3,:) 
ans = 
      0.76   0.05   0.77 
      0.33   0.96   0.23 
      0.60   0.72   0.52 

:問題を実証するために

D = 3; 
M = 1000; 
numbers = cell(1,4); 

mystream = qrandstream(scramble(sobolset(D),'MatousekAffineOwen')); 
myfun = @(x) qrand(mystream,x); 

parfor i = 1:4 
    numbers{i} = myfun(M); 
end 

は、このコードを実行した後、番号の数字は、{1}、番号は{2}、数字{3}と番号は{4}と同一であります私は誰もがこの問題の修正を考えることができるかどうか疑問に思っています。私は、通常の乱数列を使用するときに問題が発生しないので、私ができることがなければならないと考えています。

Quasi-Random Numberストリームの 'Skip'や 'Leap'のようなものを悪用することはできません。その理由は、上記のコードスニペットを、私が並列に実行する大規模なMATLABプログラムで使用しているからです...

答えて

4

各並列作業者を別々に呼び出す必要があります。これは、のようにのparforループ内qrandstream関連文を移動させることにより行うことができる。

D = 3; 
M = 1000; 
numbers = cell(1,4); 

parfor i = 1:4 
    mystream = qrandstream(scramble(sobolset(D),'MatousekAffineOwen')); 
    myfun = @(x) qrand(mystream,x); 

    numbers{i} = myfun(M); 
end 

理由:MatousekAffineOwenがランダムスクランブリング順序を持っているが、MATLABは、巨大な予め定義されたアレイとして擬似ランダム系列を扱い とサンプルデータは、新しいサンプルが必要となるたびにオンザフライで計算されます。スクランブリングはこの順序を変更しますが、qrandstreamオブジェクトは、スクランブルが呼び出されるとすぐに、一度起こったかのように動作します。その後、qrandstreamは確定的な数値のストリームになります。非並列コード(または、最初にmatlabpoolを有効にせずにparforを使用する場合)では、このセットアップは単一のqrandstream b/cでうまく動作します。MATLABはqrandを呼び出すたびに(仮想)リストを処理し続けます。

しかし、parforでは、必要な変数や関数などのすべてのコピーが各ワーカーに渡されます。結果として、各作業者は、疑似乱数の重複した予め定められたストリームを取得し、結果として、各作業者に同一のサンプルストリームが得られる。ちなみに、これはすべての数字{i}が同じ値を持つことを意味するものではありません。並列ワーカー(マシンコア)の数より多いパーフループ範囲の場合、同じワーカーで複数のループ反復が発生し、同じで非反復qrandstreamを共有します。私の2つのコアマシンでは、あなたの4反復のサンプルコードはnumbers{1}==numbers{4}numbers{2}==numbers{3}

関連する問題