シミュレーションをしよう(0):乱数

なにかしら"シミュレーション"と呼べそうなものをしてみたいのだが、 その前にシミュレーションに使う「乱数」について。 乱数というのは次々と作為に選んだ数のことだが、 コンピュータには「無作為」という概念はないので、なんらかのプログラムに よって「無作為っぽい」数列を作り出す。それを「疑似乱数」とよぶ。 疑似乱数の発生法やプログラムにはいろいろなものがあり、目的に応じて 使えばよい。単にLINUXでシミュレーションするだけなら、C言語に初めから 用意された乱数でもいいのだが、 ここではスーパーコンピュータを使用することを前提として、 特別の乱数発生関数を使うことにする

プログラム

プログラムの中身を理解する必要はないので、以下の二つをコピーして 使えばよし。ファイル名は変えないほうがいいと思う。

使い方

 この乱数を使う場合は、プログラムの最初にヘッダーファイルを使うことを宣言する。 ↓こんな感じ。
#include<stdio.h>
#include "rnd.h"


 乱数の”種”となる数を格納するためにプログラム中に以下の整数配列を宣言する。RND_Pというのはヘッダーファイルで定義されているので、このままにしておく
 int rseed[RND_P];


 乱数を使う前に一度だけ「初期化」関数を呼ぶ
 ranset(raninit,rseed);
rseedは上で宣言した配列。raninitは乱数の「初期値」。 これは適当な整数ならなんでもよく、この値を変えるごとに違う乱数列が得られる。 初期値が同じなら同じ乱数列が得られる。 プログラム中で何回乱数を使おうと、初期化は一度でよい。

 整数値の乱数が必要なときは、関数rndを使う。
 rnd(r,n,rseed);
nは乱数の個数で、n個の乱数が一度に生成され、整数配列rに収納される。したがって、rはnより大きいサイズを持つ整数配列として宣言されている必要がある(nより大きければよく、ちょうどnである必要はない)。乱数の値は0から2147483647(2の31乗-1)までである

 実数値の乱数が必要なときは、関数drndを使う。
 drnd(r,n,rseed);
nは乱数の個数で、n個の乱数が一度に生成され、実数配列rに収納される。したがって、ここではrはnより大きいサイズを持つ実数配列として宣言されている必要がある。 乱数の値は0から1までである。

整数乱数のテストプログラム

#include<stdio.h>
#include "rnd.h"
#define NMAX 20000
main()
{
 int rseed[RND_P];
 int i,j;
 int raninit,n;
 int r[NMAX];

 scanf("%d%d", &n,&raninit);

 ranset(raninit,rseed);
 rnd(r,n,rseed);
 for(i=0; i<n; ++i){
  printf("%d\n",r[i]);}
}
ここで新しく出てきた構文は3行目のdefineである。
#define NMAX 20000
これはプログラム中のNMAXという文字をすべて20000という文字で置き換えよという命令で、コンパイラはあたかもすべてのNMAXが20000と書かれているかのように解釈してコンパイルする。

 このプログラムは端末から乱数の個数と初期値を入力すると、個数分の整数乱数を出力する。これを実行して実際に数万個の乱数を出力し、gnuplot等でグラフを描いてみよう。

実数乱数のテストプログラム

#include<stdio.h>
#include "rnd.h"
#define NMAX 20000
main()
{
 int rseed[RND_P];
 int i,j;
 int raninit,n;
 double r[NMAX];

 scanf("%d%d", &n,&raninit);

 ranset(raninit,rseed);
 drnd(r,n,rseed);
 for(i=0; i<n; ++i){
  printf("%f\n",r[i]);}
}
これを実行して実際に数万個の乱数を出力し、gnuplot等でグラフを描いてみよう。
次へ