コード生成に対応した、かつ、繰り返しのない乱数列を生成する Simulinki モデルを作成するにはどうすればよいですか?
11 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
MathWorks Support Team
il 24 Ott 2022
Risposto: MathWorks Support Team
il 24 Ott 2022
Simulink で乱数を作成しようとしています。実際には MATLAB Function ブロックの 'rand' と 'normrnd' 関数を使用しています。
しかしシミュレーションを実行すると毎回同じ乱数列が出力されます。Function ブロックの中で 'coder.extrinsic('rand')' を使う方法がある様子ですが、どうすればいいのでしょうか?
ただし coder.extrinsic('rand')'はシミュレーションでは使用できますが、コード生成にはサポートされていません。
Simulink で毎回異なる乱数列を作成し、かつ、コード生成をサポートするにはどうしたらよいですか?
Risposta accettata
MathWorks Support Team
il 24 Ott 2022
以下の 3 通りの方法があります。
1) rand 関数を呼び出す前に rng('shuffle') コマンドを使用します。rng('shuffle') は、R2018b以降のリリースでスタンドアロンコード生成に使用可能です。
2) アプリケーションを実行するたびに乱数発生器の状態がシステムクロックに基づいて初期化され、毎回一意の値が出力されるようなロジックを実装します。以下の MATLAB Answers をご参考ください。
https://www.mathworks.com/matlabcentral/answers/104306-why-does-my-compiled-rand-function-give-the-same-values-every-time-i-run-my-matlab-generated-standal
MATLABの "clock "コマンドはコード生成後は使用できないため、C 標準ライブラリの time 関数を使用します。これは以下のように "coder.cinclude" と "coder.ceval"を使用してユニークシードを設定するために呼び出すことができます。
function out = Func_Name (in1, in2)
coder.cinclude('"time.h"')
sd=0;
sd=coder.ceval('time',[]);
rng(sd,'twister');
out = zeros(1,1);
out = normrnd(in1, in2);
これらのコマンドは CodeGen でのビルドは問題なく行われます。しかしモデルをシミュレートしたり、実行ファイルを実行すると、"Func_Name "ブロックの出力値が毎秒同じ値を返し続けます。
これは、C 言語の関数 time が時間を秒単位で返すため、シミュレーション中に同じ値を秒単位で返し続けていることが原因です(出力は1秒に1回変化することがわかります)。これは、rand コマンドを使う前に、毎回この「一定」のシード値で乱数発生器をリセットしていることになります。これにより乱数発生器はリセットされ、1秒間に同じ定数値が出力されます。
生成されたコードは、高い頻度で乱数を生成している場合、ハードウェア上で失敗する可能性があります。これはコードが新しいインスタンスとして実行されるたびに、乱数生成器に一度だけシードを入れることで回避できます。
解決策としては以下の 2 つが考えられます。
2a) Clock ブロックを使って、シミュレーション時間を MATLAB のFunction ブロックに供給します。この時間を元に、ifループを使って乱数生成器に一度だけ seed を使用することができます。また、シミュレーション時間の代わりにグローバル変数をカウンタとして使用し、乱数生成器に一度だけシードを与えることも可能です。
function out = Func_Name (in1, in2)
coder.cinclude('"time.h"')
if simTime < 0.001
sd=0;
sd=coder.ceval('time',[]);
rng(sd,'twister');
end
out = zeros(1,1);
out = normrnd(in1, in2);
2b) Stateflow Chart を使用する。
よりシンプルな方法として Stateflow Chart を使用する方法があります。Stateflow Chart では rng(seed,'twister') コマンドを実行開始時に一度だけ実行することができます。また、モデルに Clock ブロックを追加する必要もありません。
3) S-functionを使用する。
外部 C コードで動作確認済みのコードがあれば、S-function を作成することができます。S-function は TLC ファイルが必要ですが、コード生成に対応しています。
0 Commenti
Più risposte (0)
Vedere anche
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!