c-conc and p-val colour table output added
[physik/nlsop.git] / random.c
1 /*
2  * random functions
3  *
4  * author: hackbard@hackdaworld.dyndns.org
5  *
6  */
7
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <math.h>
14
15 #ifdef USE_LIBC_RAND
16 #include <time.h>
17 #endif
18
19 #include "random.h"
20
21 static int rand_fd;
22 static u32 *c_ptr,*b_ptr;
23
24 int rand_init(char *rf)
25 {
26  if(rf==NULL)
27  {
28 #ifndef USE_LIBC_RAND
29   if((rand_fd=open("/dev/urandom",O_RDONLY))<0)
30   {
31    puts("cannot open /dev/urandom");
32    return -1;
33   }
34 #endif
35  } else
36  {
37   if((rand_fd=open(rf,O_RDONLY))<0)
38   {
39    printf("cannot open %s\n",rf);
40    return -1;
41   }
42  }
43  if((b_ptr=(u32 *)(malloc(BUFSIZE*sizeof(u32))))==NULL)
44  {
45   puts("failed allocating random buffer");
46   return -1;
47  }
48  c_ptr=b_ptr+BUFSIZE;
49  
50  return 1;
51 }
52
53 int rand_close(void)
54 {
55 #ifndef USE_LIBC_RAND
56  close(rand_fd);
57 #endif
58  
59  return 1;
60 }
61
62 u32 get_rand(u32 max)
63 {
64  if(c_ptr>=b_ptr+BUFSIZE)
65  {
66 #ifdef MORE_PRINTF
67   printf("getting another %d bytes of random data ...\n",BUFSIZE);
68 #endif
69 #ifdef USE_LIBC_RAND
70   c_ptr=b_ptr;
71   srand((int)time(NULL));
72   while(c_ptr<b_ptr+BUFSIZE) *(c_ptr++)=(u32)rand();
73   c_ptr=b_ptr;
74 #else
75   if(read(rand_fd,b_ptr,BUFSIZE*sizeof(u32))<BUFSIZE*sizeof(u32))
76   {
77    /* -> assume random file, end reached */
78    puts("warning, will read random file from beginning ...");
79    lseek(rand_fd,0,SEEK_SET);
80    read(rand_fd,b_ptr,BUFSIZE*sizeof(u32));
81   }
82   c_ptr=b_ptr;
83 #endif
84 #ifdef MORE_PRINTF
85   printf("got it!\n");
86 #endif
87  }
88
89 #ifdef USE_LIBC_RAND
90  return((u32)(*(c_ptr++)*(max*1.0/((long long unsigned int)RAND_MAX+1))));
91 #else
92  return((u32)(*(c_ptr++)*(max*1.0/((long long unsigned int)URAND_MAX+1))));
93 #endif
94 }
95
96 u32 get_rand_lgp(u32 max,double a,double b)
97 {
98  return((u32)(1.0*max*(-1.0*b+sqrt(b*b+2*a*((b+a/2)*get_rand(URAND_MAX)/((long long unsigned int)URAND_MAX+1))))/a));
99 }
100
101 u32 get_rand_reject(u32 max_x,u32 max_y,u32 *graph)
102 {
103  u32 x,y;
104  unsigned char ok;
105
106  ok=0;
107  while(!ok)
108  {
109   x=get_rand(max_x);
110   y=get_rand(max_y);
111   if(y<=graph[x]) ok=1;
112  }
113
114  return x;
115 }