乱数生成プログラム



[ 簡単な説明 ]

一様乱数

一様乱数関数は、0〜1の間(0と1以外)の double 型数値を返します。引数はありません。
各関数は、使用する前にそれぞれ対応する初期設定関数を実行しなければなりません。
初期設定関数は、各関数名の前に "init_" を付けた名前です。
初期設定関数は、乱数の種として long 型数値を引数で与えます。

urnd( ) 乗算合同法
mrnd( ) M系列(周期 : 2521 - 1 ≒ 6.86×10156
rrnd( ) 乗算合同法(周期 : 約6.95×1012
ornd( ) Park and Miller 乗算合同法 (周期 : 231 - 2 = 2147483646)
brnd( ) Park and Miller 乗算合同法 + Bays-Durham 切り混ぜ法
ernd( ) L'Ecuyer 2種の乗算合同法組合せ(周期:約2.3×1018)
+ Bays-Durham 切り混ぜ法
krnd( ) Knuth 減算法
drnd( ) データ暗合化に基づく乱数列
qrnd( ) 線形合同法(高速生成法)
prnd0( )〜prnd33( ) ポータブルな乱数生成ルーチン(拙速生成法)


   注:ポータブルな乱数生成ルーチン(拙速生成法)
     乱数の生成法は線型合同法です。
     計算式は、ri+1 =(ri× p1 + p2)mod p3 です。

関数 パラメータ 周期   関数 パラメータ 周期
p1 p2 p3 p1 p2 p3
prnd0( ) 6075 106 1283 6075   prnd17( ) 86436 1093 18257 86436
prnd1( ) 7875 211 1663 7875   prnd18( ) 121500 1021 25673 121500
prnd2( ) 7875 421 1663 7875   prnd19( ) 259200 421 54773 259200
prnd3( ) 6075 1366 1283 6075   prnd20( ) 117128 1277 24749 117128
prnd4( ) 6655 936 1399 6655   prnd21( ) 121500 2041 25673 121500
prnd5( ) 11979 430 2531 11979   prnd22( ) 312500 741 66037 312500
prnd6( ) 14406 967 3041 14406   prnd23( ) 145800 3661 30809 145800
prnd7( ) 29282 419 6173 29282   prnd24( ) 175000 2661 36979 175000
prnd8( ) 53125 171 11213 53125   prnd25( ) 233280 1861 42297 233280
prnd9( ) 12960 1741 2731 12960   prnd26( ) 244944 1597 51749 244944
prnd10( ) 14000 1541 2957 14000   prnd27( ) 139968 3877 29573 139968
prnd11( ) 21870 1291 4621 21870   prnd28( ) 214326 3613 45289 214326
prnd12( ) 31104 625 6571 31104   prnd29( ) 714025 1366 150889 714025
prnd13( ) 139968 205 29573 139968   prnd30( ) 134456 8121 28411 134456
prnd14( ) 29282 1255 6173 29282   prnd31( ) 259200 7141 54773 259200
prnd15( ) 81000 421 17117 81000   prnd32( ) 233280 9301 49297 233280
prnd16( ) 134456 281 28411 134456   prnd33( ) 714025 4096 150889 714025


整数乱数

max から min の範囲の整数の乱数を発生します。内部で上記の一様乱数を使用しますので、初期設定関数 init_irnd( )に対して、一様乱数の初期設定関数名、乱数生成関数名、乱数の種を与えます。

irnd(max, min) max 〜 min の範囲の整数乱数


その他乱数

各関数は内部で上記の一様乱数を使用しますので、初期設定関数 init_irnd( )に対して、一様乱数の初期設定関数名、乱数生成関数名、乱数の種を与えます。

gaussd(av, sd) ボックス−マラー法による
正規分布乱数(高速・改良版)
av は平均値、sd は標準偏差
tri_rand( ) 三角分布乱数  
exp_rand( ) 指数分布乱数  
binornal(r, &x, &y) 2変量正規分布乱数 r は相関係数(-1 〜 1)
rnd_vector(&x, &y) ベクトル乱数  
rnd_vector3(&x, &y, &z) 3次元ベクトル乱数  

プログラム・ソース("random.c")           top (トップに戻る)
/*	random.c	擬似乱数(Pseudo-Random numbers)	*/
#include <stdio.h>
#include <stdlib.h>
#include "random.h"

/*#define		DEBUG		/* debug routine */

ulong _idum_u0, _idum_u1, _idum_u2;		/* urnd0()〜urnd6()の乱数核 */
ulong _idum_u3, _idum_u4, _idum_u5;		/*      〃        */
ulong _idum_u6;							/*      〃        */
ulong *_prx, *_prx_end;					/* mrnd()の乱数核ほか変数 */
ulong _rx[522];							/*      〃        */
unsigned int r_s1, r_s2, r_s3;			/* rrnd()の乱数核ほか変数 */
long _idum_o0, _idum_o1, _idum_o2;		/* ornd0()〜ornd2()の乱数核 */
long _idum_b, b_nd, b_iy;				/* brnd()の乱数核ほか変数 */
long b_iv[NTAB];						/*      〃        */
long _idum_e1, _idum_e2, e_nd, e_iy;	/* ernd()の乱数核ほか変数 */
long e_iv[NTAB];						/*      〃        */
long *k_ma_end, *pk1, *pk2;				/* krnd()の乱数核ほか変数 */
long k_ma[57];							/*      〃        */
ulong _idum_d;							/* drnd()の乱数核 */
ulong _idum_q;							/* qrnd()の乱数核 */
ulong _idum_p0, _idum_p1, _idum_p2;		/* prnd0()〜prnd33()の乱数核 */
ulong _idum_p3, _idum_p4, _idum_p5;		/*      〃        */
ulong _idum_p6, _idum_p7, _idum_p8;		/*      〃        */
ulong _idum_p9, _idum_p10, _idum_p11;	/*      〃        */
ulong _idum_p12, _idum_p13, _idum_p14;	/*      〃        */
ulong _idum_p15, _idum_p16, _idum_p17;	/*      〃        */
ulong _idum_p18, _idum_p19, _idum_p20;	/*      〃        */
ulong _idum_p21, _idum_p22, _idum_p23;	/*      〃        */
ulong _idum_p24, _idum_p25, _idum_p26;	/*      〃        */
ulong _idum_p27, _idum_p28, _idum_p29;	/*      〃        */
ulong _idum_p30, _idum_p31, _idum_p32;	/*      〃        */
ulong _idum_p33;						/*      〃        */
double (*_rand)(void);					/* 一様乱数以外の乱数で呼び出す一様分布乱数 */ 
double _tri;

void _error(char *s, int r)
{
	fprintf(stderr, "Error : %s\n", s);
	exit(r);
}

void init_urnd0(long seed)
{
	_idum_u0 = seed ^ MASK;
}

void init_urnd1(long seed)
{
	_idum_u1 = seed ^ MASK;
}

void init_urnd2(long seed)
{
	_idum_u2 = seed ^ MASK;
}

void init_urnd3(long seed)
{
	_idum_u3 = seed ^ MASK;
}

void init_urnd4(long seed)
{
	_idum_u4 = seed ^ MASK;
}

void init_urnd5(long seed)
{
	_idum_u5 = seed ^ MASK;
}

void init_urnd6(long seed)
{
	_idum_u6 = seed ^ MASK;
}

void init_mrnd(long seed)
{
	int i, j;
	ulong *p, *p1, *p2, *p3, s, u;

	_prx_end = &_rx[521];

	s = seed ^ MASK;
	u = 0;
	for(i = 0, _prx = _rx; i <= 16; i++)
	{
		for(j = 0; j < 32; j++)
		{
			s = s * 1566083941L + 1;
			u = (u >> 1) | (s & (1L << 31));
		}
		*_prx++ = u;
	}
	_prx--;
	*_prx = (0xffffffff & (*_prx << 23)) ^ (*_rx >> 9) ^ *(_rx + 15);
	p1 = _rx;
	p2 = &_rx[1];
	p3 = _prx++;
	while(_prx != _prx_end)
		*_prx++ = (0xffffffff & (*p1++ << 23)) ^ (*p2++ >> 9) ^ *p3++;
	rnd521();		/* wram up */
	rnd521();
	rnd521();
	_prx = &_rx[520];
}

void init_rrnd(long seed)
{
	r_s1 = (seed ^ MASK) & 0x7fff;
	r_s2 = ((r_s1 * r_s1) ^ MASK) & 0x7fff;
	r_s3 = ((r_s1 * r_s2) ^ MASK) & 0x7fff;
#ifdef DEBUG
printf("r_s1 = %d, r_s2 = %d, r_s3 = %d\n", r_s1, r_s2, r_s3);
#endif
}

void init_ornd0(long seed)
{
	_idum_o0 = seed ^ MASK;
}

void init_ornd1(long seed)
{
	_idum_o1 = seed ^ MASK;
}

void init_ornd2(long seed)
{
	_idum_o2 = seed ^ MASK;
}

long b_iy;

void init_brnd(long seed)
{
	int i;
	long *p;

	_idum_b = seed ^ MASK;
	for(i = 0; i < 8; i++)	bcal();
	for(i = NTAB - 1; i >= 0; i--)	b_iv[i] = bcal();
	b_nd = 1 + 2147483646L / NTAB;
	b_iy = b_iv[0];
} 

void init_ernd(long seed)
{
	int i;

	_idum_e1 = seed ^ MASK;
	_idum_e2 = (_idum_e1 * _idum_e1) ^ MASK;
	for(i = 0; i < 8; i++)	ecal1();
	for(i = NTAB - 1; i >= 0; i--)	e_iv[i] = ecal1();
	e_nd = 1 + 2147483562L / NTAB;
	e_iy = e_iv[0];
} 

void init_krnd(long seed)
{
	long mj, mk;
	int i, k;

	k_ma_end = &k_ma[56];
	mj = (MSEED - (seed ^ MASK)) % MBIG;
	k_ma[55] = mj;
	mk = 1L;
	for(i = 1; i <= 54; i++)
	{
		k = (21 * i) % 55;
		k_ma[k] = mk;
		mk = mj - mk;
		if(mk < 0)	mk += MBIG;
		mj = k_ma[k];
	}
	for(k = 1; k <= 4; k++)
	{
		for(i = 1; i <= 55; i++)
		{
			k_ma[i] -= k_ma[1 + (i + 30) % 55];
			if(k_ma[i] < 0)	k_ma[i] += MBIG;
		}
	}
	pk1 = &k_ma[0];
	pk2 = &k_ma[31];
}

void init_drnd(long seed)
{
	_idum_d = seed ^ MASK;
}

void init_qrnd(long seed)
{
	_idum_q = seed ^ MASK;
}

long init_prnd0(long seed)
{
	_idum_p0 = (seed ^ MASK) & 0x00000fff;
	return 6075;
}

long init_prnd1(long seed)
{
	_idum_p1 = (seed ^ MASK) & 0x00000fff;
	return 7875;
}

long init_prnd2(long seed)
{
	_idum_p2 = (seed ^ MASK) & 0x00000fff;
	return 7875;
}

long init_prnd3(long seed)
{
	_idum_p3 = (seed ^ MASK) & 0x00000fff;
	return 6075;
}

long init_prnd4(long seed)
{
	_idum_p4 = (seed ^ MASK) & 0x00000fff;
	return 6655;
}

long init_prnd5(long seed)
{
	_idum_p5 = (seed ^ MASK) & 0x00000fff;
	return 11979;
}

long init_prnd6(long seed)
{
	_idum_p6 = (seed ^ MASK) & 0x00000fff;
	return 14406;
}

long init_prnd7(long seed)
{
	_idum_p7 = (seed ^ MASK) & 0x00000fff;
	return 29282;
}

long init_prnd8(long seed)
{
	_idum_p8 = (seed ^ MASK) & 0x00000fff;
	return 53125;
}

long init_prnd9(long seed)
{
	_idum_p9 = (seed ^ MASK) & 0x00000fff;
	return 12960;
}

long init_prnd10(long seed)
{
	_idum_p10 = (seed ^ MASK) & 0x00000fff;
	return 14000;
}

long init_prnd11(long seed)
{
	_idum_p11 = (seed ^ MASK) & 0x00000fff;
	return 21870;
}

long init_prnd12(long seed)
{
	_idum_p12 = (seed ^ MASK) & 0x00000fff;
	return 31104;
}

long init_prnd13(long seed)
{
	_idum_p13 = (seed ^ MASK) & 0x00000fff;
	return 139968;
}

long init_prnd14(long seed)
{
	_idum_p14 = (seed ^ MASK) & 0x00000fff;
	return 29282;
}

long init_prnd15(long seed)
{
	_idum_p15 = (seed ^ MASK) & 0x00000fff;
	return 81000;
}

long init_prnd16(long seed)
{
	_idum_p16 = (seed ^ MASK) & 0x00000fff;
	return 134456;
}

long init_prnd17(long seed)
{
	_idum_p17 = (seed ^ MASK) & 0x00000fff;
	return 86436;
}

long init_prnd18(long seed)
{
	_idum_p18 = (seed ^ MASK) & 0x00000fff;
	return 121500;
}

long init_prnd19(long seed)
{
	_idum_p19 = (seed ^ MASK) & 0x00000fff;
	return 259200;
}

long init_prnd20(long seed)
{
	_idum_p20 = (seed ^ MASK) & 0x00000fff;
	return 117128;
}

long init_prnd21(long seed)
{
	_idum_p21 = (seed ^ MASK) & 0x00000fff;
	return 121500;
}

long init_prnd22(long seed)
{
	_idum_p22 = (seed ^ MASK) & 0x00000fff;
	return 312500;
}

long init_prnd23(long seed)
{
	_idum_p23 = (seed ^ MASK) & 0x00000fff;
	return 145800;
}

long init_prnd24(long seed)
{
	_idum_p24 = (seed ^ MASK) & 0x00000fff;
	return 175000;
}

long init_prnd25(long seed)
{
	_idum_p25 = (seed ^ MASK) & 0x00000fff;
	return 233280;
}

long init_prnd26(long seed)
{
	_idum_p26 = (seed ^ MASK) & 0x00000fff;
	return 244944;
}

long init_prnd27(long seed)
{
	_idum_p27 = (seed ^ MASK) & 0x00000fff;
	return 139968;
}

long init_prnd28(long seed)
{
	_idum_p28 = (seed ^ MASK) & 0x00000fff;
	return 214326;
}

long init_prnd29(long seed)
{
	_idum_p29 = (seed ^ MASK) & 0x00000fff;
	return 714025;
}

long init_prnd30(long seed)
{
	_idum_p30 = (seed ^ MASK) & 0x00000fff;
	return 134456;
}

long init_prnd31(long seed)
{
	_idum_p31 = (seed ^ MASK) & 0x00000fff;
	return 259200;
}

long init_prnd32(long seed)
{
	_idum_p32 = (seed ^ MASK) & 0x00000fff;
	return 233280;
}

long init_prnd33(long seed)
{
	_idum_p33 = (seed ^ MASK) & 0x00000fff;
	return 714025;
}

double urnd0(void)
{
	double d = 1. / 4294967296.;
	return (double)(_idum_u0 *= 69069L) * d;
}

double urnd1(void)
{
	double d = 1. / 4294967296.;
	return (double)(_idum_u1 *= 1664525L) * d;
}

double urnd2(void)
{
	double d = 1. / 4294967296.;
	return (double)(_idum_u2 *= 39894229L) * d;
}

double urnd3(void)
{
	double d = 1. / 4294967296.;
	return (double)(_idum_u3 *= 48828125L) * d;
}

double urnd4(void)
{
	double d = 1. / 4294967296.;
	return (double)(_idum_u4 *= 1566083941L) * d;
}

double urnd5(void)
{
	double d = 1. / 4294967296.;
	return (double)(_idum_u5 *= 1812433253L) * d;
}

double urnd6(void)
{
	double d = 1. / 4294967296.;
	return (double)(_idum_u6 *= 2110005341L) * d;
}

void rnd521(void)
{
	ulong *p, *p1, *p2;

	p1 = (_prx = p = p2 = _rx) + 489;
	while(p1 != _prx_end)	*p++ ^= *p1++;
	while(p  != _prx_end)	*p++ ^= *p2++;
}

double mrnd(void)
{
	double d = 1. / 4294967296.;
	if(++_prx == _prx_end)	rnd521();
	return (double)*_prx * d;
}

double rrnd(void)
{
	double d1 = 1. / 30269., d2 = 1. / 30307., d3 = 1. / 30323.;
	double r;

	if((r = (double)(r_s1 = (171 * r_s1) % 30269) * d1
		  + (double)(r_s2 = (172 * r_s2) % 30307) * d2
		  + (double)(r_s3 = (170 * r_s3) % 30323) * d3) < 1.)	return r;
	if(r < 2.)	return r - 1.;
	return r - 2.;
}

double ornd0(void)					/* Park and Miller の「最低基準」乱数 */
{
	long w;
	double d = 1. / 2147483647.;

	w = _idum_o0 / 127773L;
	if((_idum_o0 = (_idum_o0 - w * 127773L) * 16807 - w * 2836) <= 0)
		_idum_o0 += 2147483647L;
	return (double)_idum_o0 * d;
}

double ornd1(void)					/* Park and Miller の「最低基準」乱数 */
{
	long w;
	double d = 1. / 2147483647.;

	w = _idum_o1 / 44488L;
	if((_idum_o1 = (_idum_o1 - w * 44488L) * 48271L - w * 3399) <= 0)
		_idum_o1 += 2147483647L;
	return (double)_idum_o1 * d;
}

double ornd2(void)					/* Park and Miller の「最低基準」乱数 */
{
	long w;
	double d = 1. / 2147483647.;

	w = _idum_o2 / 30845;
	if((_idum_o2 = (_idum_o2 - w * 30845) * 69621L - w * 23902) <= 0)
		_idum_o2 += 2147483647L;
	return (double)_idum_o2 * d;
}

double brnd(void)
{
	double d = 1. / 2147483647.;
	int j;

	j = b_iy / b_nd;
	b_iy = b_iv[j];
	return (double)(b_iv[j] = bcal()) * d;
}

long bcal(void)
{
	long w;

	w = _idum_b / 127773L;
	if((_idum_b = (_idum_b - w * 127773L) * 16807 - w * 2836) <= 0)
		_idum_b += 2147483647L;
	return _idum_b;
}

double ernd(void)
{
	double d = 1. / 2147483563.;
	int j;

	j = e_iy / e_nd;
	if((e_iy = e_iv[j] - ecal2()) < 1)	e_iy += 2147483562L;
	return (double)(e_iv[j] = ecal1()) * d;
}

long ecal1(void)
{
	long w;

	w = _idum_e1 / 53668L;
	if((_idum_e1 = (_idum_e1 - w * 53668L) * 40014L - w * 12211L) <= 0)
		_idum_e1 += 2147483563L;
	return _idum_e1;
}

long ecal2(void)
{
	long w;

	w = _idum_e2 / 52774L;
	if((_idum_e2 = (_idum_e2 - w * 52774L) * 40692L - w * 3791) <= 0)
		_idum_e2 += 2147483399L;
	return _idum_e2;
}

double krnd(void)
{
	double d = 1. / (double)MBIG;
	long mj;

	if(++pk1 == k_ma_end)	pk1 = &k_ma[1];
	if(++pk2 == k_ma_end)	pk2 = &k_ma[1];
	if((mj = *pk1 - *pk2) < 0)	mj += MBIG;
	return (double)(*pk1 = mj) * d;
}

double drnd(void)
{
	double d = 1. / 4294967296.;
	ulong lw, rw, a, b, th, tl;

	a = _idum_d ^ 0xbaa96887L;
	b = (tl = a & 0xffff) * tl + ~((th = a >> 16) * th);
	a = (lw = ((((b >> 16)|(b << 16)) ^ 0x4b0f3b58L) + tl * th)) ^ 0x1e17d32cL;
	b = (tl = a & 0xffff) * tl + ~((th = a >> 16) * th);
	a = (rw = _idum_d++ ^ ((((b >> 16)|(b << 16)) ^ 0xe874f0c3L) + tl * th))
		^ 0x03bcdc3cL;
	b = (tl = a & 0xffff) * tl + ~((th = a >> 16) * th);
	a = lw ^ ((((b >> 16)|(b << 16)) ^ 0x6955c5a6L) + tl * th) ^ 0x0f33d1b2L;
	b = (tl = a & 0xffff) * tl + ~((th = a >> 16) * th);
	return (double)(rw ^ ((((b >> 16)|(b << 16)) ^ 0x55a7ca46L) + tl * th)) * d;
}

double qrnd(void)
{
	double d = 1. / 4294967296.;
	return (double)(_idum_q = _idum_q * 1664525L + 1013904223L) * d;
}

double prnd0(void)
{
	static double d = 1. / 6075.;
	return (double)(_idum_p0 = (_idum_p0 * 106 + 1283) % 6075) * d;
}

double prnd1(void)
{
	static double d = 1. / 7875.;
	return (double)(_idum_p1 = (_idum_p1 * 211 + 1663) % 7875) * d;
}

double prnd2(void)
{
	static double d = 1. / 7875.;
	return (double)(_idum_p2 = (_idum_p2 * 421 + 1663) % 7875) * d;
}

double prnd3(void)
{
	static double d = 1. / 6075.;
	return (double)(_idum_p3 = (_idum_p3 * 1366 + 1283) % 6075) * d;
}

double prnd4(void)
{
	static double d = 1. / 6655.;
	return (double)(_idum_p4 = (_idum_p4 * 936 + 1399) % 6655) * d;
}

double prnd5(void)
{
	static double d = 1. / 11979.;
	return (double)(_idum_p5 = (_idum_p5 * 430 + 2531) % 11979) * d;
}

double prnd6(void)
{
	static double d = 1. / 14406.;
	return (double)(_idum_p6 = (_idum_p6 * 967 + 3041) % 14406) * d;
}

double prnd7(void)
{
	static double d = 1. / 29282.;
	return (double)(_idum_p7 = (_idum_p7 * 419 + 6173) % 29282) * d;
}

double prnd8(void)
{
	static double d = 1. / 53125.;
	return (double)(_idum_p8 = (_idum_p8 * 171 + 11213) % 53125) * d;
}

double prnd9(void)
{
	static double d = 1. / 12960.;
	return (double)(_idum_p9 = (_idum_p9 * 1741 + 2731) % 12960) * d;
}

double prnd10(void)
{
	static double d = 1. / 14000.;
	return (double)(_idum_p10 = (_idum_p10 * 1541 + 2957) % 14000) * d;
}

double prnd11(void)
{
	static double d = 1. / 21870.;
	return (double)(_idum_p11 = (_idum_p11 * 1291 + 4621) % 21870) * d;
}

double prnd12(void)
{
	static double d = 1. / 31104.;
	return (double)(_idum_p12 = (_idum_p12 * 625 + 6571) % 31104) * d;
}

double prnd13(void)
{
	static double d = 1. / 139968.;
	return (double)(_idum_p13 = (_idum_p13 * 205 + 29573) % 139968) * d;
}

double prnd14(void)
{
	static double d = 1. / 29282.;
	return (double)(_idum_p14 = (_idum_p14 * 1255 + 6173) % 29282) * d;
}

double prnd15(void)
{
	static double d = 1. / 81000.;
	return (double)(_idum_p15 = (_idum_p15 * 421 + 17117) % 81000) * d;
}

double prnd16(void)
{
	static double d = 1. / 134456.;
	return (double)(_idum_p16 = (_idum_p16 * 281 + 28411) % 134456) * d;
}

double prnd17(void)
{
	static double d = 1. / 86436.;
	return (double)(_idum_p17 = (_idum_p17 * 1093 + 18257) % 86436) * d;
}

double prnd18(void)
{
	static double d = 1. / 121500.;
	return (double)(_idum_p18 = (_idum_p18 * 1021 + 25673) % 121500) * d;
}

double prnd19(void)
{
	static double d = 1. / 259200.;
	return (double)(_idum_p19 = (_idum_p19 * 421 + 54773) % 259200) * d;
}

double prnd20(void)
{
	static double d = 1. / 117128.;
	return (double)(_idum_p20 = (_idum_p20 * 1277 + 24749) % 117128) * d;
}

double prnd21(void)
{
	static double d = 1. / 121500.;
	return (double)(_idum_p21 = (_idum_p21 * 2041 + 25673) % 121500) * d;
}

double prnd22(void)
{
	static double d = 1. / 312500.;
	return (double)(_idum_p22 = (_idum_p22 * 741 + 66037) % 312500) * d;
}

double prnd23(void)
{
	static double d = 1. / 145800.;
	return (double)(_idum_p23 = (_idum_p23 * 3661 + 30809) % 145800) * d;
}

double prnd24(void)
{
	static double d = 1. / 175000.;
	return (double)(_idum_p24 = (_idum_p24 * 2661 + 36979) % 175000) * d;
}

double prnd25(void)
{
	static double d = 1. / 233280.;
	return (double)(_idum_p25 = (_idum_p25 * 1861 + 49297) % 233280) * d;
}

double prnd26(void)
{
	static double d = 1. / 244944.;
	return (double)(_idum_p26 = (_idum_p26 * 1597 + 51749) % 244944) * d;
}

double prnd27(void)
{
	static double d = 1. / 139968.;
	return (double)(_idum_p27 = (_idum_p27 * 3877 + 29573) % 139968) * d;
}

double prnd28(void)
{
	static double d = 1. / 214326.;
	return (double)(_idum_p28 = (_idum_p28 * 3613 + 45289) % 214326) * d;
}

double prnd29(void)
{
	static double d = 1. / 714025.;
	return (double)(_idum_p29 = (_idum_p29 * 1366 + 150889) % 714025) * d;
}

double prnd30(void)
{
	static double d = 1. / 134456.;
	return (double)(_idum_p30 = (_idum_p30 * 8121 + 28411) % 134456) * d;
}

double prnd31(void)
{
	static double d = 1. / 259200.;
	return (double)(_idum_p31 = (_idum_p31 * 7141 + 54773) % 259200) * d;
}

double prnd32(void)
{
	static double d = 1. / 233280.;
	return (double)(_idum_p32 = (_idum_p32 * 9301 + 49297) % 233280) * d;
}

double prnd33(void)
{
	static double d = 1. / 714025.;
	return (double)(_idum_p33 = (_idum_p33 * 4096 + 150889) % 714025) * d;
}

void init_irnd(void (*_init)(long s), double (*_rnd)(void), long seed)
{
	_init(seed);
	_rand = _rnd;
}

int irnd(int max, int min)
{
	return min + (int)(_rand() * (double)(max - min + 1));
}

void init_gaussd(void (*_init)(long s), double (*_rnd)(void), long seed)
{
	_init(seed);
	_rand = _rnd;
}

double gaussd(double av, double st)
{
	static double r1, r2, s;
	static int sw = 1;

	sw = 1 - sw;
	if(sw)	return av + st * r2 * s;
	do
	{
		r1 = 2. * _rand() - 1.;
		r2 = 2. * _rand() - 1.;
		s = r1 * r1 + r2 * r2;
	} while(s > 1.);
	s = sqrt(-2. * log(s) / s);
	return av + st * r1 * s;
}

void init_tri_rand(void (*_init)(long s), double (*_rnd)(void), long seed)
{
	_init(seed);
	_rand = _rnd;
	_tri = _rand();
}

double tri_rand(void)
{
	double d;

	d = _tri;
	return (_tri = _rand()) - d;
}

void init_exp_rand(void (*_init)(long s), double (*_rnd)(void), long seed)
{
	_init(seed);
	_rand = _rnd;
}

double exp_rand(void)
{
	return - log(_rand());
}

void init_binormal(void (*_init)(long s), double (*_rnd)(void), long seed)
{
	_init(seed);
	_rand = _rnd;
}

void binormal(double r, double *x, double *y)
{
	double r1, r2, s;

	do
	{
		r1 = 2. * _rand() - 1.;
		r2 = 2. * _rand() - 1.;
		s = r1 * r1 + r2 * r2;
	} while(s > 1.);
	s = - log(s) / s;
	r1 *= sqrt((1 + r) * s);
	r2 *= sqrt((1 - r) * s);
	*x = r1 + r2;
	*y = r1 - r2;
	return;
}

void init_rnd_vector(void (*_init)(long s), double (*_rnd)(void), long seed)
{
	_init(seed);
	_rand = _rnd;
}

void rnd_vector(double *x, double *y)
{
	double r;

	do
	{
		*x = 2. * _rand() - 1.;
		*y = 2. * _rand() - 1.;
		r = (*x * *x + *y * *y);
	} while(r > 1);
	r = sqrt(r);
	*x /= r;
	*y /= r;
	return;
}

void init_rnd_vector3(void (*_init)(long s), double (*_rnd)(void), long seed)
{
	_init(seed);
	_rand = _rnd;
}

void rnd_vector3(double *x, double *y, double *z)
{
	double t;

	do
	{
		*x = 2. * _rand() - 1.;
		*y = 2. * _rand() - 1.;
		*z = (*x * *x + *y * *y);
	} while(*z > 1);
	t = 2. * sqrt(1. - *z);
	*x *= t;
	*y *= t;
	*z = 2. * *z - 1.;
	return;
}