X-Git-Url: https://hackdaworld.org/gitweb/?a=blobdiff_plain;f=random%2Frandom.c;fp=random%2Frandom.c;h=c06b98ad11de103e73f466d2f7b7e6241f1a3e38;hb=3ffe2a08e25fc091b6241885055450009267e2d8;hp=0000000000000000000000000000000000000000;hpb=b040d775deb32173e6536464a3e2ad95a6a5bd55;p=physik%2Fposic.git diff --git a/random/random.c b/random/random.c new file mode 100644 index 0000000..c06b98a --- /dev/null +++ b/random/random.c @@ -0,0 +1,140 @@ +/* + * random.c - basic random deviates + * + * author: Frank Zirkelbach + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#include "random.h" + +int rand_init(t_random *random,char *randomfile,int logfd) { + + random->status=0; + + if(logfd) random->logfd=logfd; + + if(randomfile==NULL) { + random->fd=open("/dev/urandom",O_RDONLY); + if(random->fd<0) { + perror("open urandom"); + return -1; + } + random->status|=RAND_STAT_UDEV; + } else { + random->fd=open(randomfile,O_RDONLY); + if(random->fd<0) { + perror("open randomfile"); + return -1; + } + } + random->buffer=malloc(RAND_BUFSIZE*sizeof(unsigned int)); + if(random->buffer==NULL) { + perror("malloc random buffer"); + return -1; + } + random->b_ptr=random->buffer+RAND_BUFSIZE; + + dprintf(random->logfd,"[random] init successfull\n"); + + return 0; +} + + +int rand_close(t_random *random) { + + dprintf(random->logfd,"[random] shutdown\n"); + + if(random->buffer) free(random->buffer); + if(random->fd) close(random->fd); + if(random->logfd) close(random->logfd); + + return 0; +} + +unsigned int rand_get(t_random *random) { + + if(random->b_ptr==random->buffer+RAND_BUFSIZE) { + if(random->status&RAND_STAT_VERBOSE) + dprintf(random->logfd, + "[random] getting new random numbers\n"); + random->b_ptr=random->buffer; + if(!(random->status&RAND_STAT_UDEV)) { + lseek(random->fd,0,SEEK_SET); + dprintf(random->logfd, + "[random] warning, rereading random file\n"); + } + read(random->fd,random->b_ptr, + RAND_BUFSIZE*sizeof(unsigned int)); + if(random->status&RAND_STAT_VERBOSE) + dprintf(random->logfd, + "[random] got new random numbers\n"); + } + + return(*(random->b_ptr++)); +} + +double rand_get_double(t_random *random) { + + return(1.0*rand_get(random)/(double)(URAND_MAX+1)); +} + +double rand_get_double_linear(t_random *random,double a,double b) { + + return((-b+sqrt(b*b+2*a*(b+a/2)*rand_get_double(random)))/a); +} + +double rand_get_gauss(t_random *random) { + + double a,b,w; + + if(random->status&RAND_STAT_GAUSS) { + random->status&=~RAND_STAT_GAUSS; + return random->gauss; + } + + w=0; + while((w>=1.0)||(w==0.0)) { + a=-2.0*rand_get_double(random)+1.0; + b=-2.0*rand_get_double(random)+1.0; + w=a*a+b*b; + } + + w=sqrt(-2.0*log(w)/w); + + random->gauss=b*w; + random->status|=RAND_STAT_GAUSS; + + return(a*w); +} + +unsigned int rand_get_int_linear(t_random *random,unsigned int max, + double a,double b) { + + return((int)(rand_get_double_linear(random,a,b)*max)); +} + +unsigned int rand_get_reject(t_random *random,unsigned int max_x, + unsigned int max_y,unsigned int *graph) { + + unsigned int x,y; + unsigned char ok; + + ok=0; + while(!ok) { + x=(max_x*rand_get_double(random)); + y=(max_y*rand_get_double(random)); + if(y<=graph[x]) ok=1; + } + + return x; +} +