summaryrefslogtreecommitdiff
path: root/src/mt/random.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mt/random.cc')
-rw-r--r--src/mt/random.cc95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/mt/random.cc b/src/mt/random.cc
new file mode 100644
index 0000000..87a4c8c
--- /dev/null
+++ b/src/mt/random.cc
@@ -0,0 +1,95 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/random.h>
21#include <mt/mlock.h>
22#include <time.h>
23
24//////////////////////////////////////////////////////
25//
26// This file implements some routines from NumRec
27//
28
29const int NTAB=32; // NOTE: change in header if changing this
30
31const int IA=16807;
32const int IM=2147483647;
33const float AM=1/float(IM);
34const int IQ=127773;
35const int IR=2836;
36const int NDIV=1+(IM-1)/NTAB;
37const float EPS=1.2e-7;
38const float RNMX=1-EPS;
39
40static int idum,iy,iv[32],flag;
41static float extra;
42static int inited;
43static mutex_t mutex;
44
45unsigned long RandomInit(unsigned long seed)
46{
47 inited=1;
48 idum=seed?seed:1;
49 for(int j=NTAB+7;j>=0;j--) {
50 int k=idum/IQ;
51 idum=IA*(idum-k*IQ)-IR*k;
52 if(idum<0) idum+=IM;
53 if(j<NTAB) iv[j]=idum;
54 }
55 iy=iv[0];
56 return seed;
57}
58
59float Uniform()
60{
61 MLOCK(mutex);
62 if(!inited) RandomInit(time(0));
63 int k=idum/IQ;
64 idum=IA*(idum-k*IQ)-IR*k;
65 if(idum<0) idum+=IM;
66 int j=iy/NDIV;
67 iy=iv[j];
68 iv[j]=idum;
69 float temp=AM*iy; if(temp>RNMX) temp=RNMX;
70 return temp;
71}
72
73float Exponential()
74{
75 return -log(Uniform());
76}
77
78float Gaussian()
79{
80 MLOCK(mutex);
81 float v1,v2,rsq;
82 if(flag) {
83 flag=0;
84 return extra;
85 } else {
86 do {
87 v1=2*Uniform()-1;
88 v2=2*Uniform()-1;
89 rsq=v1*v1+v2*v2;
90 } while(rsq>=1||rsq<=0);
91 float fac=sqrt(-2*log(rsq)/rsq);
92 flag=1; extra=v1*fac;
93 return v2*fac;
94 }
95}