ADDRANS(3M)

名前
addrans - 加法的乱数の生成

形式

cc [ flag ... ] file ... -lsunmath -lm [ library ... ]

    flag にはフラグ、 file にはファイル名、 library にはライブラリ名を指定します。

#include <sunmath.h>

#define ADDRAN_SIZE 55

int i_addran_(void);

float r_addran_(void);

double d_addran_(void);

void i_addrans_(int *x, int *n, int *l, int *u);

void u_addrans_(unsigned *x, int *n, unsigned *l, unsigned *u);

void r_addrans_(float *x, int *n, float *l, float *u);

void d_addrans_(double *x, int *n, double *l, double *u);

void i_get_addrans_(int *x);

void r_get_addrans_(float *x);

void d_get_addrans_(double *x);

void i_set_addrans_(int *x);

void r_set_addrans_(float *x);

void d_set_addrans_(double *x);

void i_init_addrans_(void);

void r_init_addrans_(void);

void d_init_addrans_(void);

機能説明

これらの関数は、符号付き整数型、符号なし整数型、単精度浮動小数点型、 倍精度浮動小数点型の一様疑似乱数を生成します。

加法的乱数は、 次の式を用いた ..._addran_() により、1 度に 1 つずつ生成されます。
	addran_last = addran_table[i] - addran_table[(i-24) % ADDRAN_SIZE] ;
	addran_table[i] = addran_last;
	i = (i+1) % ADDRAN_SIZE ;
	return addran_last;
addran_table は、符号なし整数型、浮動小数点型、倍精度型の ADDRAN_SIZE 個の要素を含むテーブルです。 必要に応じて、 整数型および符号なし整数型の場合は 4294967296、 浮動小数点型および倍精度型の場合は 1.0 を加算することで、 乱数は以下の範囲に制限されます (下記のテーブルを参照)。

型 | 下位の境界 |  | 上位の境界
 | 名前 | 値 | 名前 | 値
符号なし | U_ADDRAN_LB | 0 | U_ADDRAN_UB | 4294967295
整数 | I_ADDRAN_LB | -2147483648 | I_ADDRAN_UB | 2147483647
浮動小数点 | R_ADDRAN_LB | 0 | R_ADDRAN_UB | 0.9999999403953552246
倍精度 | D_ADDRAN_LB | 0 | D_ADDRAN_UB | 0.9999999999999998890

このように、 32 ビットで表現可能な整数と符号なし整数は、どれも i_addran_() から同じ確率で得られます。 効率化のために「加法的方法」が減算によって実現されていることは、 気にすることではありません。

加法的乱数は、次の式を用いた ..._addrans_() により、一度に *n 個生成されます。
	addran_last = addran_table_[i] - addran_table_[(i-24) % ADDRAN_SIZE] ;
	addran_table[i] = addran_last;
	i = (i+1) % ADDRAN_SIZE ;
	return scale * (addran_last + offset)
ここで、 scale および offset は *l および *u から算出されるため、算出された乱数は間隔 [*l,*u] 内に一様に分布します。 u_addrans_() を使用すれば、 大きな符号なし整数の境界を指定できます。 u_addrans_() は、 i_addrans_() と同じ addran_table を使用します。

加法的乱数ジェネレータの状態 ( ADDRAN_SIZE の配列) は、 ...get_addrans_() で取得したり、 ...set_addrans_() で設定することができます。 また、 ...init_addrans_() によって初期の状態に戻すことができます。

使用例

  間隔 [0,1] 内で 1000 個の倍精度乱数を生成する

    double x[1000] ; int i, n = 1000 ; double lb = D_ADDRAN_LB, ub = D_ADDRAN_UB ;
    for (i=0;i<n;i++) x[i] = d_addran_(); /* または ... */
    d_addrans_(x, &n, &lb, &ub) ;	/* 同じ出力がより効果的に得られる */

  間隔 [-10,+10] 内で 1000 個の整数型乱数を生成する

    int x[1000] ; int n = 1000, lb = -10, ub = 10 ;

    i_addrans_(x, &n, &lb, &ub) ;

関連項目
drand48(3), lcrans(3M), mwcrans(3M), rand(3C), rand(3C), random(3), shufrans(3M).

Knuth 著, 『準数値算法』( The Art of Computer Programming Volume II ), 渋谷政昭、中川圭介訳, サイエンス社.

Park and Miller, Random Number Generators: Good Ones are Hard to Find, Communications of the ACM, October 1988.

注意事項

lcrans(3M) と addrans(3M) のどちらを使用すれば処理効率が向上するかは、プログラムが、 乱数生成関数を呼び出す回数によります。 通常の用途 (50 以上の呼び出しがある場合) では、 lcrans(3M)、 drand48(3)、 rand(3C)、 rand(3C)、 random(3) に含まれる関数よりも、 addrans(3M)、 に含まれる関数を ( shufrans(3M) とともに) 使用する方が処理効率が向上します。 また、50 以下の呼び出しの場合は、 addrans(3M) よりも lcrans(3M) を使用することをお勧めします。 addrans(3M) は最初の呼び出しで、ADDRAN_SIZE に定義されている 55 のエレメント テーブルを初期化するため、オーバーヘッドが生じることから、この場合は lcrans(3M) のほうが処理効率は向上します。