主要内容

このページの翻訳は最新ではありません。ここをクリックして,英語の最新版を参照してください。

乱数発生器の制御

この例では,乱数発生器を制御する関数rngを使用する方法を示します。

MATLABの(疑似)乱数は,関数兰德兰迪,およびrandnで生成されます。他の多くの関数がこの3つの関数を呼び出しますが,これらは基本ブロックです。3つの関数はすべて,rngを使って制御できる1つの共有乱数発生器に依存します。

MATLABの“乱数”は予測不可能ですが,決定性アルゴリズムによって生成されるということを理解しておいてください。このアルゴリズムは,アルゴリズムを知らなければその出力が独立した乱数列に”見える”ように十分に複雑になるように設計されていて,ランダム性のさまざまな統計検定にも合格できます。ここで紹介する関数を使用すると,次の項目を実行するために確定性を利用できます。

  • 乱数に関連する計算を反復して同じ結果を取得する。

  • 反復計算で異なる乱数が使用されることを保証する。

また,見かけのランダム性を利用して個々の計算結果の組み合わせが正しいことを証明します。

“やり直し”

新しいMATLABセッションで兰德兰迪,またはrandnの出力を確認すると,MATLABを再起動するたびに同じ数列が返されることに気付きます。これは,実際にMATLABを再起動しなくても乱数発生器を起動時の状態にリセットできるので多くの場面で役立ちます。たとえば,乱数を含む計算を反復して同じ結果を得る必要がある場合などです。

rngを使用すると,乱数発生器を既定の設定に簡単に戻すことができます。

rng默认的兰德%返回与启动时相同的值
ans = 0.8147

MATLABの起動時の”既定の“乱数設定はどのような内容で,rng违约にはどのような機能があるのでしょう。入力なしでrngを呼び出すと,シードが0のメルセンヌ・ツイスター発生器アルゴリズムであることがわかります。

rng
ans =结构体字段:类型:'twister' Seed: 0状态:[625x1 uint32]

状态フィールドなどの上記の出力を使用してMATLABが乱数を生成する方法を制御および変更する方法の詳細については,以下を参照してください。ここでは,発生器兰德兰迪,およびrandnが現在使用しているものを確認するために使用されています。

非反復性

兰德兰迪,またはrandnは呼び出されるたびに共有乱数発生器から新しい値を取り出し,連続した値は統計的に独立した値として処理されます。しかし前述のように,MATLABを再起動するたびにこれらの関数はリセットされて同じ数列を返します。“同一の乱数”を使用する計算が統計的に独立しているとは考えられないことは明らかです。そのため,複数のMATLABセッションで実行される計算が統計的に“独立しているように”その計算を組み合わせる必要がある場合,既定の発生器の設定は使用できません。

新しいMATLABセッションで同じ乱数が繰り返されないようにするには,乱数発生器に異なるシードを選択する方法が簡単です。rngを使うと,現在時刻に基づいたシードを作成することによって同じ乱数の発生を簡単に回避できます。

rng洗牌兰德
ans = 0.1579

“洗牌”は,使用されるたびに異なるシードで発生器を再シードします。入力なしでrngを呼び出すと,実際に使用されるシードの内容を確認できます。

rng
ans =结构体字段:类型:'twister' Seed: 686196167 State: [625x1 uint32]
rng洗牌%每次创建一个不同的种子rng
ans =结构体字段:类型:'twister' Seed: 686196175 State: [625x1 uint32]
兰德
ans = 0.7367

“洗牌”を使用すると,非常に簡単に乱数発生器を再シードできます。MATLABで "本来の" ランダム性を確保するには shuffle の使用が便利な場合も必要な場合もあります。ただし、多くの場合、“洗牌”を”使用する必要はまったくありません”。現在時刻に基づいてシードを選択すると,兰德兰迪,およびrandnから得られる値の統計的な特性は向上せず,本当の意味で”ランダム性を高める”ことはできません。MATLABの起動時や乱数を含む大規模な計算を実行する前に発生器を再シードしてもよいですが、乱数の統計的な特性に影響を及ぼす可能性があるため、実際には 1 つのセッションで何回も発生器の再シードを行うのはお勧めできません。

“洗牌”を使用すると同一の値の系列の繰り返しを回避できますが,これが重要な場合もあれば,”便利”であるにすぎない場合もあり,さほど重要でない場合がほとんどです。“洗牌”を使用する場合は,後で計算を繰り返せるようにrngが作成したシードを保存することを忘れないでください。以下にその方法を示します。

反復性と非反復性の強力な制御

これまでのところ,乱数発生器を既定の設定にリセットする方法と,現在時刻から作成されるシードを使用して発生器を再シードする方法を確認してきました。また,rngを使用すると特定のシードを使って発生器を再シードできることも説明しました。

同じシードを何回も使用して同じ計算を繰り返すことができます。たとえば,次のコードを2回実行します。

rng (1)%种子是任何< 2^32的非负整数x = randn(1、5)
x =1×5-0.6490 1.1812 -0.7585 -1.1096 -0.8456
Rng (1) x = Rng (1,5)
x =1×5-0.6490 1.1812 -0.7585 -1.1096 -0.8456

...まったく同じ結果が得られます。これを実行するのは,特定の値を使用してxに依存するその後の計算内容を繰り返すことができるように,消去後にxを再び作成する場合などです。

一方で,同じ計算を繰り返さないように,”“異なるシードを選択する場合があります。たとえば1つのMATLABセッションで次のコードを実行します。

Rng (2) x2 = sum(randn(50,1000),1);% 1000次随机漫步试验

別のセッションでは次のコードを実行します。

Rng (3) x3 = sum(randn(50,1000),1); / /计算结果

...2つの結果を組み合わせると,単に2回繰り返されて同じ結果になったのではないことがわかります。

X = [x2 x3];

“洗牌”と同様に,MATLABの乱数発生器を再シードする際は注意してください。兰德兰迪,およびrandnのその後のすべての出力に影響するためです。反復性または一意性が必要ない場合,一般的には発生器を再シードしないで単に乱数を生成することをお勧めします。発生器を再シードする必要がある場合は,コマンドラインで行うか,コード内の見落としにくい場所で行ってください。

発生器のタイプの選択

前述のように乱数発生器を再シードできるだけでなく,使用する乱数発生器のタイプを選択することもできます。発生器のタイプが異なると発生する乱数列も異なります。たとえば統計的な特性に基づいて特定のタイプを選択する場合もあります。また,MATLABの古いバージョンで使われていた別の既定の発生器タイプの結果を再作成する場合もあります。

他に発生器のタイプを選択する理由として,“ランダムな”入力データを生成する検証試験を記述して,その検定で常にまったく同じ予測どおりの結果が得られることを保証する場合があります。入力データを作成する前にシードでrngを呼び出すと,乱数発生器が再シードされます。しかし,何らかの理由で発生器のタイプが変更されていると,兰德兰迪,およびrandnの出力はそのシードから予測される出力とは異なる内容になります。したがって,反復性を確実にするには、発生器のタイプも指定します。

たとえば,次のコマンドを実行します。

rng (0,“旋风”

これにより,兰德兰迪,およびrandnはメルセンヌ・ツイスター発生器アルゴリズムを0でシードしてから使用します。

次のように“combRecursive”を使用するとします。

rng (0,“combRecursive”

これにより,結合多重再帰発生器アルゴリズムが選択されます。このアルゴリズムは,メルセンヌ・ツイスターではサポートされないいくつかの並列機能をサポートします。

次のコマンドを実行するとします。

rng (0,v4的

これにより,MATLAB 4.0の既定の設定だった発生器アルゴリズムが選択されます。

次のコマンドは乱数発生器を既定の設定に戻します。

rng默认的

ただし,乱数発生器の既定の設定はMATLABリリース間で変更されている場合があることから,“默认”による予測結果については長期的な保証はありません。“默认”は乱数発生器をリセットするには便利ですが,より高い予想精度を求める場合は,発生器のタイプとシードを指定してください。

一方,対話的に操作して反復性が必要な場合は,シードを指定してrngを呼び出す方法が簡単であり,通常はこの方法で十分です。

乱数発生器の設定内容の保存と復元

入力なしでrngを呼び出すと,前述の2つの情報である,発生器のタイプと発生器を前回再シードしたときの整数値を含むフィールドをもつスカラー構造体が返されます。

s = rng
s =结构体字段:类型:'twister' Seed: 0状态:[625x1 uint32]

3番目のフィールド状态には,発生器の現在の状態ベクトルのコピーが含まれています。この状態ベクトルは,発生器が乱数列の次の値を生成するために内部で保持する情報です。兰德兰迪,またはrandnが呼び出されるたびに,これらが共有する発生器は内部状態を更新します。したがって,rngによって返される設定構造体の状態ベクトルには,その状態がキャプチャされた点から始まる数列を繰り返すために必要な情報が含まれています。

この出力を確認することも有益ですが,rng“入力”として設定構造体も受け入れるため,状態ベクトルなどの設定内容を保存し,それを復元して後で計算を繰り返すことができます。設定には発生器のタイプも含まれるため,出力の内容を正確に把握できます。また,上述の "後で" は、同じ MATLAB セッションの数秒後から、いくつもの MATLAB リリースを経た数年後まで含まれます。発生器の設定を保存した乱数列の点から結果を繰り返すことができます。例を次に示します。

x1 = randn (10,10);%在随机数序列中向前移动s =提高;%此时保存设置x2 = randn(1、5)
x2 =1×50.8404 -0.8880 0.1001 -0.5445 0.3035
x3 = randn (5,5);%在随机数序列中向前移动rng(年代);%将发电机返回保存状态x2 = randn(1、5)重复相同的数字
x2 =1×50.8404 -0.8880 0.1001 -0.5445 0.3035

再シードでは大まかな再初期化が行われるだけですが,設定構造体を使用して発生器の状態を保存および復元すると,乱数列の“どの部分“でも繰り返すことができます。

設定構造体の一般的な使用方法は,発生器の状態の復元です。ただし,構造体には状態だけでなく発生器のタイプとシードも含まれているため,発生器のタイプを一時的に切り替えるときにも便利です。たとえば,MATLAB 5.0の従来の発生器のいずれかを使用して値を作成する場合は,古い発生器を使用するために切り替えるのと同時に現在の設定を保存できます。

previousSettings = rng (0,“v5uniform”
previousSettings =结构体字段:类型:'twister' Seed: 0状态:[625x1 uint32]

...さらに,後で元の設定を復元できます。

rng (previousSettings)

設定構造体のフィールドの内容を変更する必要はありません。具体的には,独自の状態ベクトルを構成する必要がなく,発生器の状態の形式にも影響されません。

簡潔で柔軟性の高いコードの記述

rngを使用すると,次のいずれかを実行できます。

  • 乱数発生器の再シード

  • 乱数発生器の設定の保存と復元

発生器のタイプを把握する必要はありません。また,乱数発生器の設定内容を知らなくても、既定の設定に戻すことができます。発生器のタイプを指定する "必要がある" 場合でも、rngを使用すると指定する”必要がなくなります”。

発生器のタイプを指定する必要がなくなれば,使用する発生器が異なる場合にもコードが自動的に適合して,新しい既定の乱数発生器のタイプがもつ改良された特性を自動的に活用することができます。

rngRandStream

一般的な必要性に応じてMATLABで乱数発生器を制御するには,rngが最も便利です。ただし,複数の乱数ストリームや並列乱数生成を含む複雑な状況では,より複雑なツールが必要です。RandStreamクラスがそのツールで,乱数発生を最も強力に制御できます。この2つのツールは相補的な関係にあり,rngではRandStreamの柔軟性に基づいて構築される単純で簡潔な構文を作成できます。