主题:一些满足一定分布的随机数
//
// L'Ecuyer ran
// lanjingquan 2002.12.3
/////////////////////////////////////////////
#include<iostream.h>
#include<math.h>
#define PI 3.141592654
#define IM 2147483647
#define AM (1.0/IM)
#define IA 16807
#define IQ 127773
#define IR 2638
#define NTAB 32
#define NDIV (1+(IM-1)/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
float rand(long* idum)
{
int j;
long k;
static long iy=0;
static long iv[NTAB];
float temp;
if(*idum<=0||!iy)
{
if(-(*idum)<1)
*idum=1;
else
*idum=-(*idum);
for(j=NTAB+7;j>=0;j--)
{
k=(*idum)/IQ;
*idum=IA*(*idum-k*IQ)-k*IR;
if(*idum<0)
*idum+=IM;
if(j<NTAB)
iv[j]=*idum;
}
iy=iv[0];
}
k=(*idum)/IQ;
*idum=IA*(*idum-k*IQ)-k*IR;
if(*idum<0)
*idum+=IM;
j=iy/NDIV;
iy=iv[j];
iv[j]=*idum;
if((temp=float(AM*iy))>RNMX)
return float(RNMX);
else
return temp;
}
float expdev(long* idum)
{
float dum;
do
dum=rand(idum);
while(dum==0.0);
return float(-log(dum));
}
//Box-Muller
float gasdev(long* idum)
{
static int iset=0;
static float gset;
float fac,rsq,v1,v2;
if(iset==0)
{
do
{
v1=float(2.0*rand(idum)-1.0);
v2=float(2.0*rand(idum)-1.0);
rsq=v1*v1+v2*v2;
}while(rsq>=1.0||rsq==0.0);
fac=sqrt(-2.0*log(rsq)/rsq);
gset=v1*fac;
iset=1;
return v2*fac;
}
else
{
iset=0;
return gset;
}
}
float gamdev(int ia,long* idum)
{
int j;
float am,e,s,v1,v2,x,y;
if(ia<1)
cerr<<"error!"<<endl;
if(ia<6)
{
x=0.1;
for(j=1;j<ia;j++)
x*=rand(idum);
x=-log(x);
}
else
{
do
{
do
{
do
{
v1=float(2.0*rand(idum)-1.0);
v2=float(2.0*rand(idum)-1.0);
}while(v1*v1+v2*v2>1.0);
y=v2/v1;
am=ia-1;
s=sqrt(2.0*am+1.0);
x=s*y+am;
}while(x<=0.0);
e=(1.0+y*y)*exp(am*log(x/am)-s*y);
}while(rand(idum)>e);
}
return x;
}
float gammln(float xx)
{
double x,y,tmp,ser;
static double cof[6]=
{76.18009172947146,-86.50532032941677,24.01409824083091,
-1.231739572450155,0.1208650973866179e-2,-0.5395239384953e-5};
int j;
y=x=xx;
tmp=x+5.5;
tmp-=(x+0.5)*log(tmp);
ser=1.000000000190015;
for(j=0;j<=5;j++)
ser-=cof[j]/++y;
return -tmp+log(2.5066282746310005*ser/x);
}
float poidev(float xm,long* idum)
{
static float sq,alxm,g,oldm=-1.0;
float em,t,y;
if(xm<12.0)
{
if(xm!=oldm)
{
oldm=xm;
g=exp(-xm);
}
em=-1;
t=1.0;
do
{
em+=1.0;
t*=rand(idum);
}while(t<g);
}
else
{
if(xm!=oldm)
{
oldm=xm;
sq=sqrt(2.0*xm);
alxm=log(xm);
g=xm*alxm-gammln(xm+1.0);
}
do
{
do
{
y=tan(PI*rand(idum));
em=sq*y+xm;
}while(em<0.0);
em=floor(em);
t=0.9*(1.0+y*y)*exp(em*alxm-gammln(em+1.0)-g);
}while(rand(idum)>t);
}
return em;
}
void main()
{
long k=450;
for(int i=0;i<20;i++)
{
cout<<gamdev(325,&k)<<" ";
if((i+1)%5==0)
cout<<endl;
}
cout<<endl;
}
// L'Ecuyer ran
// lanjingquan 2002.12.3
/////////////////////////////////////////////
#include<iostream.h>
#include<math.h>
#define PI 3.141592654
#define IM 2147483647
#define AM (1.0/IM)
#define IA 16807
#define IQ 127773
#define IR 2638
#define NTAB 32
#define NDIV (1+(IM-1)/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
float rand(long* idum)
{
int j;
long k;
static long iy=0;
static long iv[NTAB];
float temp;
if(*idum<=0||!iy)
{
if(-(*idum)<1)
*idum=1;
else
*idum=-(*idum);
for(j=NTAB+7;j>=0;j--)
{
k=(*idum)/IQ;
*idum=IA*(*idum-k*IQ)-k*IR;
if(*idum<0)
*idum+=IM;
if(j<NTAB)
iv[j]=*idum;
}
iy=iv[0];
}
k=(*idum)/IQ;
*idum=IA*(*idum-k*IQ)-k*IR;
if(*idum<0)
*idum+=IM;
j=iy/NDIV;
iy=iv[j];
iv[j]=*idum;
if((temp=float(AM*iy))>RNMX)
return float(RNMX);
else
return temp;
}
float expdev(long* idum)
{
float dum;
do
dum=rand(idum);
while(dum==0.0);
return float(-log(dum));
}
//Box-Muller
float gasdev(long* idum)
{
static int iset=0;
static float gset;
float fac,rsq,v1,v2;
if(iset==0)
{
do
{
v1=float(2.0*rand(idum)-1.0);
v2=float(2.0*rand(idum)-1.0);
rsq=v1*v1+v2*v2;
}while(rsq>=1.0||rsq==0.0);
fac=sqrt(-2.0*log(rsq)/rsq);
gset=v1*fac;
iset=1;
return v2*fac;
}
else
{
iset=0;
return gset;
}
}
float gamdev(int ia,long* idum)
{
int j;
float am,e,s,v1,v2,x,y;
if(ia<1)
cerr<<"error!"<<endl;
if(ia<6)
{
x=0.1;
for(j=1;j<ia;j++)
x*=rand(idum);
x=-log(x);
}
else
{
do
{
do
{
do
{
v1=float(2.0*rand(idum)-1.0);
v2=float(2.0*rand(idum)-1.0);
}while(v1*v1+v2*v2>1.0);
y=v2/v1;
am=ia-1;
s=sqrt(2.0*am+1.0);
x=s*y+am;
}while(x<=0.0);
e=(1.0+y*y)*exp(am*log(x/am)-s*y);
}while(rand(idum)>e);
}
return x;
}
float gammln(float xx)
{
double x,y,tmp,ser;
static double cof[6]=
{76.18009172947146,-86.50532032941677,24.01409824083091,
-1.231739572450155,0.1208650973866179e-2,-0.5395239384953e-5};
int j;
y=x=xx;
tmp=x+5.5;
tmp-=(x+0.5)*log(tmp);
ser=1.000000000190015;
for(j=0;j<=5;j++)
ser-=cof[j]/++y;
return -tmp+log(2.5066282746310005*ser/x);
}
float poidev(float xm,long* idum)
{
static float sq,alxm,g,oldm=-1.0;
float em,t,y;
if(xm<12.0)
{
if(xm!=oldm)
{
oldm=xm;
g=exp(-xm);
}
em=-1;
t=1.0;
do
{
em+=1.0;
t*=rand(idum);
}while(t<g);
}
else
{
if(xm!=oldm)
{
oldm=xm;
sq=sqrt(2.0*xm);
alxm=log(xm);
g=xm*alxm-gammln(xm+1.0);
}
do
{
do
{
y=tan(PI*rand(idum));
em=sq*y+xm;
}while(em<0.0);
em=floor(em);
t=0.9*(1.0+y*y)*exp(em*alxm-gammln(em+1.0)-g);
}while(rand(idum)>t);
}
return em;
}
void main()
{
long k=450;
for(int i=0;i<20;i++)
{
cout<<gamdev(325,&k)<<" ";
if((i+1)%5==0)
cout<<endl;
}
cout<<endl;
}