Main Content

複数のストリーム

複数の独立したストリームの使用

MATLAB® ソフトウェアには、複数の独立した乱数ストリームを生成できる発生器アルゴリズムが含まれています。たとえば、複数の独立したストリームをサポートする発生器には、結合多重再帰 ('mrg32k3a')、乗法ラグ フィボナッチ ('mlfg6331_64')、Philox 4x32 ('philox4x32_10')、および Threefry 4x64 ('threefry4x64_20') という 4 つの発生器タイプがあります。オーバーラップが発生しないことが保証され、かつストリーム間の値の (疑似的な) 独立性を実証するテストが実行されている、複数の独立したストリームを作成することができます。複数のストリームをサポートする発生器アルゴリズムの詳細については、乱数ストリームの作成と管理の発生器アルゴリズムの表を参照してください。

関数RandStream.createを使用すると、同じ発生器アルゴリズムとシード値をもつ、統計的に独立したストリームを作成できます。

[s1,s2,s3] = RandStream.create('mlfg6331_64','NumStreams',3)
s1 = 
mlfg6331_64 random stream
      StreamIndex: 1
       NumStreams: 3
             Seed: 0
  NormalTransform: Ziggurat

s2 = 
mlfg6331_64 random stream
      StreamIndex: 2
       NumStreams: 3
             Seed: 0
  NormalTransform: Ziggurat

s3 = 
mlfg6331_64 random stream
      StreamIndex: 3
       NumStreams: 3
             Seed: 0
  NormalTransform: Ziggurat

独立性を示すものとして、この 3 つのストリームは概して無相関であることがわかります。

r1 = rand(s1,100000,1);
r2 = rand(s2,100000,1); 
r3 = rand(s3,100000,1);
corrcoef([r1,r2,r3])
ans = 3×3

    1.0000    0.0007    0.0052
    0.0007    1.0000    0.0000
    0.0052    0.0000    1.0000

用途に応じて、シミュレートする必要がある特定のイベントによっては、独立した一連のストリームの中から一部のストリームのみを作成すると便利なことがあります。一連の複数のストリームから一部のストリームのみを作成するには、StreamIndices パラメーターを指定します。StreamIndex プロパティは作成する各ストリームのインデックスを返します。

streamNum = 256;
streamId = 4;
s4 = RandStream.create('mlfg6331_64','NumStreams',streamNum,'StreamIndices',streamId)
s4 = 
mlfg6331_64 random stream
      StreamIndex: 4
       NumStreams: 256
             Seed: 0
  NormalTransform: Ziggurat

複数のストリームは統計的に独立しているため、シミュレーション精度の検証に使用できます。たとえば一連の独立したストリームは、異なる MATLAB セッションや異なるプロセッサで複数回のモンテ カルロ シミュレーションの繰り返しに使用でき、結果の分散の決定に使用できます。このように、複数のストリームは大規模な並列計算に使用できます。

シードの使用による異なる結果の取得

独立したストリームを明確にはサポートしていない発生器に、異なるシードを入力すると複数のストリームが作成されます。別のシードを使うと、他のストリームから独立して動作するストリームを作成し、異なる値を返すことができます。しかし、複数の独立したストリームを作成できるように特別に設計された発生器を使用する方が、ストリーム全体の統計的特性が慎重に検証されているため、より望ましいオプションとなります。

メルセンヌ・ツイスター発生器を使用して、異なるシードで 2 つのストリームを作成します。

s1 = RandStream('mt19937ar','Seed',1)
s1 = 
mt19937ar random stream
             Seed: 1
  NormalTransform: Ziggurat

s2 = RandStream('mt19937ar','Seed',2)
s2 = 
mt19937ar random stream
             Seed: 2
  NormalTransform: Ziggurat

最初のストリームを 1 つの MATLAB セッションで使用して、乱数を生成します。

r1 = rand(s1,100000,1);

2 番目のストリームをもう 1 つの MATLAB セッションで使用して、乱数を生成します。

r2 = rand(s2,100000,1);

シードが異なると、通常ストリームは無相関の値を返します。

corrcoef([r1,r2])
ans = 2×2

    1.0000    0.0030
    0.0030    1.0000

メルセンヌ・ツイスターの状態空間はシードとなり得る値の数 (232) よりもはるかに大きい (219937 個の要素) ため、異なるシードを使用した 2 つのストリームは無相関であるように見えるかもしれません。異なるシードを大量に使用しない限り、異なるシミュレーションの実行でオーバーラップが生ずる確率は非常に低くなります。間隔の広いシードを使用しても、ランダム性のレベルは上がりません。実際に、この手法を突き詰めて各呼び出しの前に発生器の再シードを行っても、結果は統計的に独立同分布していない一連の値となり得ます。

ストリームのシード指定は、MATLAB の起動時などの初期化ステップや、シミュレーションの実行前に行った場合に最も有効です。

サブストリームの使用による異なる結果の取得

1 つのストリームから異なる結果を取得するためのもう 1 つの方法は、サブストリームを使用することです。乱数列での位置が正確には把握されないシードとは異なり、サブストリーム間の間隔は把握されているため、オーバーラップの可能性をなくすことができます。独立した並列ストリームと同様、サブストリームについても統計的に独立していることを実証する研究が行われています。つまり、従来はシードを使用して行われていた多くのことを、サブストリームを使用すれば、より制御された方法で実行できます。また、サブストリームは並列ストリームよりも軽量なソリューションです。

サブストリームは、すばやく簡単に、異なるタイミングで同じコードから異なる結果を確実に取得する方法となります。たとえば、ループ内でいくつかの乱数を生成します。

defaultStream = RandStream('mlfg6331_64');
RandStream.setGlobalStream(defaultStream)
for i = 1:5
    defaultStream.Substream = i;
    z = rand(1,i)
end
z = 0.6986
z = 1×2

    0.9230    0.2489

z = 1×3

    0.0261    0.2530    0.0737

z = 1×4

    0.3220    0.7405    0.1983    0.1052

z = 1×5

    0.2067    0.2417    0.9777    0.5970    0.4187

別のループ内で、反復 5 回の最初のセットとは独立した乱数を生成できます。

for i = 6:10
    defaultStream.Substream = i;
    z = rand(1,11-i)
end
z = 1×5

    0.2650    0.8229    0.2479    0.0247    0.4581

z = 1×4

    0.3963    0.7445    0.7734    0.9113

z = 1×3

    0.2758    0.3662    0.7979

z = 1×2

    0.6814    0.5150

z = 0.5247

各サブストリームはループで反復した処理を再生成できます。たとえば、ループ内の 6 番目のサブストリームに戻ることができます。

defaultStream.Substream = 6;
z = rand(1,5)
z = 1×5

    0.2650    0.8229    0.2479    0.0247    0.4581

参考

|

関連するトピック