/* Steven Andrews, 5/12/95, modified 11/98 */ /* Several random number generators */ /* See documentation called random doc */ /* Copyright 2003 by Steven Andrews. Permission is granted for non-commercial use of and modifications to the code. */ #include #include "random.h" #include "math2.h" unsigned int randomize() { unsigned int seed; seed=(unsigned int) time(NULL); srand(seed); return seed; } float binomrand(int n,float m,float s) { float x=0; int i; for(i=1;i<=n;i++) x+=(float)rand()/RAND_MAX; x=(x-0.5*n)/sqrt(n/12.0); return(x*s+m); } int intrandp(int n,float *p) { float r; int jl,ju,jm; r=(float)rand()/(RAND_MAX+1.0); jl=-1; ju=n-1; while(ju-jl>1) { jm=(ju+jl)>>1; if(p[jm]<=r) jl=jm; else ju=jm; } return ju; } int poisrand(float xm) { static float sq,alxm,g,oldm=-1.0; float em,t,y; if(xm<=0) return 0; else if(xm<12) { if(xm!=oldm) { oldm=xm; g=exp(-xm); } em=0; for(t=(float)rand()/RAND_MAX;t>g;t*=(float)rand()/RAND_MAX) { em+=1.0; }} else { if(xm!=oldm) { oldm=xm; sq=sqrt(2.0*xm); alxm=log(xm); g=xm*alxm-gammaln(xm+1.0); } do { do { y=tan(PI*rand()/RAND_MAX); em=sq*y+xm; } while(em<0); em=floor(em); t=0.9*(1.0+y*y)*exp(em*alxm-gammaln(em+1.0)-g); } while((float)rand()/RAND_MAX>t); } return (int) em; } int poisrandD(double xm) { static double sq,alxm,g,oldm=-1.0; float em,t,y; if(xm<=0) return 0; else if(xm<12) { if(xm!=oldm) { oldm=xm; g=exp(-xm); } em=0; for(t=(double)rand()/RAND_MAX;t>g;t*=(double)rand()/RAND_MAX) { em+=1.0; }} else { if(xm!=oldm) { oldm=xm; sq=sqrt(2.0*xm); alxm=log(xm); g=xm*alxm-gammaln(xm+1.0); } do { do { y=tan(PI*rand()/RAND_MAX); em=sq*y+xm; } while(em<0); em=floor(em); t=0.9*(1.0+y*y)*exp(em*alxm-gammaln(em+1.0)-g); } while((double)rand()/RAND_MAX>t); } return (int) em; } float binomialrand(float p,int n) { int swap,j; float am,bnl,pscale,g,t,sq,angle,y,em; static float nold=-1,pold=-1; static float en,oldg,pc,plog,pclog; if(n<1) return 0; if(p>1) return n; if(p<0) return 0; swap=0; if(p>0.5) { swap=1; p=1.0-p; } am=n*p; if(n<25) { pscale=p*RAND_MAX; bnl=0; for(j=0;j=(en+1.0)); em=floor(em); t=1.2*sq*(1.0+y*y)*exp(oldg-gammaln(em+1.0)-gammaln(en-em+1.0)+em*plog+(en-em)*pclog); } while((float)rand()/RAND_MAX>t); bnl=em; } if(swap) bnl=n-bnl; return bnl; } float gaussrand() { static int iset=0; static float gset; float fac,r,v1,v2; if(!iset) { do { v1=2.0*rand()/(RAND_MAX+1.0)-1.0; v2=2.0*rand()/(RAND_MAX+1.0)-1.0; r=v1*v1+v2*v2; } while(r>=1||r==0); fac=sqrt(-2.0*log(r)/r); gset=v1*fac; iset=1; return v2*fac; } else { iset=0; return gset; }} void sphererand(float *x,float rad1,float rad2) { float th,phi; th=thetarand(); phi=unirand(0,2.0*PI); if(rad1==rad2) ; else if(rad1==0) rad1=radrand2(rad2); else rad1=pow((float)rand()/RAND_MAX*(rad2*rad2*rad2-rad1*rad1*rad1)+rad1*rad1*rad1,0.333333333333); x[0]=rad1*sin(th)*cos(phi); x[1]=rad1*sin(th)*sin(phi); x[2]=rad1*cos(th); return; } void sphererandd(double *x,double rad1,double rad2) { double th,phi; th=thetarand(); phi=unirand(0,2*PI); if(rad1==rad2) ; else if(rad1==0) rad1=radrand2(rad2); else rad1=pow((double)rand()/RAND_MAX*(rad2*rad2*rad2-rad1*rad1*rad1)+rad1*rad1*rad1,0.333333333333); x[0]=rad1*sin(th)*cos(phi); x[1]=rad1*sin(th)*sin(phi); x[2]=rad1*cos(th); return; } void randtable(float *a,int n,int eq) { int i; if(eq==1) { for(i=0;i=100) bin=99; for(b=0;b=bin) oflow++; else a[b]++; sum+=x; sum2+=x*x; } printf("<%0.2f\t:",low-(high-low)/(bin-1)/2); for(i=1;i<=uflow;i++) printf("x"); for(b=0;b%0.2f\t:",high+(high-low)/(bin-1)/2); for(i=1;i<=oflow;i++) printf("x"); printf("\n"); printf("mean: %f\tstandard deviation: %f\n",sum/n,sqrt(sum2/n-sum/n*sum/n)); return; }