2 * random.c - basic random deviates
4 * author: Frank Zirkelbach <frank.zirkelbach@physik.uni-augsburg.de>
10 #include <sys/types.h>
19 int rand_init(t_random *random,char *randomfile,int logfd) {
23 if(logfd) random->logfd=logfd;
25 if(randomfile==NULL) {
26 random->fd=open("/dev/urandom",O_RDONLY);
28 perror("open urandom");
31 random->status|=RAND_STAT_UDEV;
33 random->fd=open(randomfile,O_RDONLY);
35 perror("open randomfile");
39 random->buffer=malloc(RAND_BUFSIZE*sizeof(unsigned int));
40 if(random->buffer==NULL) {
41 perror("malloc random buffer");
44 random->b_ptr=random->buffer+RAND_BUFSIZE;
46 dprintf(random->logfd,"[random] init successfull\n");
52 int rand_close(t_random *random) {
54 dprintf(random->logfd,"[random] shutdown\n");
56 if(random->buffer) free(random->buffer);
57 if(random->fd) close(random->fd);
58 if(random->logfd) close(random->logfd);
63 unsigned int rand_get(t_random *random) {
67 if(random->b_ptr==random->buffer+RAND_BUFSIZE) {
68 if(random->status&RAND_STAT_VERBOSE)
69 dprintf(random->logfd,
70 "[random] getting new random numbers\n");
71 if(!(random->status&RAND_STAT_UDEV)) {
72 lseek(random->fd,0,SEEK_SET);
73 dprintf(random->logfd,
74 "[random] warning, rereading random file\n");
76 left=RAND_BUFSIZE*sizeof(unsigned int);
78 left-=read(random->fd,
80 RAND_BUFSIZE*sizeof(unsigned int)-left,
83 if(random->status&RAND_STAT_VERBOSE)
84 dprintf(random->logfd,
85 "[random] got new random numbers\n");
86 random->b_ptr=random->buffer;
89 return(*(random->b_ptr++));
92 double rand_get_double(t_random *random) {
94 return(1.0*rand_get(random)/((long long unsigned int)URAND_MAX+1));
97 double rand_get_double_linear(t_random *random,double a,double b) {
99 return((-b+sqrt(b*b+2*a*(b+a/2)*rand_get_double(random)))/a);
102 double rand_get_gauss(t_random *random) {
106 if(random->status&RAND_STAT_GAUSS) {
107 random->status&=~RAND_STAT_GAUSS;
108 return random->gauss;
112 while((w>=1.0)||(w==0.0)) {
113 a=-2.0*rand_get_double(random)+1.0;
114 b=-2.0*rand_get_double(random)+1.0;
118 w=sqrt(-2.0*log(w)/w);
121 random->status|=RAND_STAT_GAUSS;
126 unsigned int rand_get_int_linear(t_random *random,unsigned int max,
129 return((int)(rand_get_double_linear(random,a,b)*max));
132 unsigned int rand_get_reject(t_random *random,unsigned int max_x,
133 unsigned int max_y,unsigned int *graph) {
140 x=(max_x*rand_get_double(random));
141 y=(max_y*rand_get_double(random));
142 if(y<=graph[x]) ok=1;