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) {
65 if(random->b_ptr==random->buffer+RAND_BUFSIZE) {
66 if(random->status&RAND_STAT_VERBOSE)
67 dprintf(random->logfd,
68 "[random] getting new random numbers\n");
69 random->b_ptr=random->buffer;
70 if(!(random->status&RAND_STAT_UDEV)) {
71 lseek(random->fd,0,SEEK_SET);
72 dprintf(random->logfd,
73 "[random] warning, rereading random file\n");
75 read(random->fd,random->b_ptr,
76 RAND_BUFSIZE*sizeof(unsigned int));
77 if(random->status&RAND_STAT_VERBOSE)
78 dprintf(random->logfd,
79 "[random] got new random numbers\n");
82 return(*(random->b_ptr++));
85 double rand_get_double(t_random *random) {
87 return(1.0*rand_get(random)/(double)(URAND_MAX+1));
90 double rand_get_double_linear(t_random *random,double a,double b) {
92 return((-b+sqrt(b*b+2*a*(b+a/2)*rand_get_double(random)))/a);
95 double rand_get_gauss(t_random *random) {
99 if(random->status&RAND_STAT_GAUSS) {
100 random->status&=~RAND_STAT_GAUSS;
101 return random->gauss;
105 while((w>=1.0)||(w==0.0)) {
106 a=-2.0*rand_get_double(random)+1.0;
107 b=-2.0*rand_get_double(random)+1.0;
111 w=sqrt(-2.0*log(w)/w);
114 random->status|=RAND_STAT_GAUSS;
119 unsigned int rand_get_int_linear(t_random *random,unsigned int max,
122 return((int)(rand_get_double_linear(random,a,b)*max));
125 unsigned int rand_get_reject(t_random *random,unsigned int max_x,
126 unsigned int max_y,unsigned int *graph) {
133 x=(max_x*rand_get_double(random));
134 y=(max_y*rand_get_double(random));
135 if(y<=graph[x]) ok=1;