EMAN2
randnum.cpp
Go to the documentation of this file.
1/*
2* Author: Grant Tang, 03/10/2008 (gtang@bcm.edu)
3* Copyright (c) 2000-2006 Baylor College of Medicine
4*
5* This software is issued under a joint BSD/GNU license. You may use the
6* source code in this file under either license. However, note that the
7* complete EMAN2 and SPARX software packages have some GPL dependencies,
8* so you are responsible for compliance with the licenses of these packages
9* if you opt to use BSD licensing. The warranty disclaimer below holds
10* in either instance.
11*
12* This complete copyright notice must be included in any revised version of the
13* source code. Additional authorship citations may be added, but existing
14* author citations must be preserved.
15*
16* This program is free software; you can redistribute it and/or modify
17* it under the terms of the GNU General Public License as published by
18* the Free Software Foundation; either version 2 of the License, or
19* (at your option) any later version.
20*
21* This program is distributed in the hope that it will be useful,
22* but WITHOUT ANY WARRANTY; without even the implied warranty of
23* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24* GNU General Public License for more details.
25*
26* You should have received a copy of the GNU General Public License
27* along with this program; if not, write to the Free Software
28* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29*
30* */
31
32#include <cmath>
33#include <ctime>
34#include <cstdio>
35#ifndef _WIN32
36 #include <sys/time.h>
37#else
38 #include <Windows.h>
39 #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
40 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
41 #else
42 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
43 #endif
44#endif
45#include "randnum.h"
46
47using namespace EMAN;
48
49namespace {
50#ifndef _WIN32
54 unsigned long long random_seed()
55 {
56 unsigned int seed;
57 struct timeval tv;
58 FILE *devrandom;
59
60 if ((devrandom = fopen("/dev/urandom","r")) == NULL) {
61 gettimeofday(&tv,0);
62 seed = tv.tv_sec + tv.tv_usec;
63 //printf("Got seed %u from gettimeofday()\n",seed);
64 }
65 else {
66 fread(&seed,sizeof(seed),1,devrandom);
67 //printf("Got seed %u from /dev/random\n",seed);
68 fclose(devrandom);
69 }
70
71 return seed;
72 }
73#else
74 /* this function works on Windows */
75 unsigned long long random_seed()
76 {
77 FILETIME ft;
78 unsigned __int64 tmpres = 0;
79 static int tzflag;
80 struct timeval tv;
81
82 GetSystemTimeAsFileTime(&ft);
83 tmpres |= ft.dwHighDateTime;
84 tmpres <<= 32;
85 tmpres |= ft.dwLowDateTime;
86
87 /*converting file time to unix epoch*/
88 tmpres /= 10; /*convert into microseconds*/
89 tmpres -= DELTA_EPOCH_IN_MICROSECS;
90 tv.tv_sec = (long long)(tmpres / 1000000UL);
91 tv.tv_usec = (long long)(tmpres % 1000000UL);
92
93 unsigned long long seed = tv.tv_sec + tv.tv_usec;
94 return seed;
95 }
96#endif
97}
98
99Randnum * Randnum::_instance = 0;
100const gsl_rng_type * Randnum::T = gsl_rng_default;
101gsl_rng * Randnum::r = 0;
102unsigned long long Randnum::_seed = random_seed();
103
104Randnum * Randnum::Instance() {
105 if(_instance == 0) {
106 _instance = new Randnum();
107 }
108
109 return _instance;
110}
111
112Randnum * Randnum::Instance(const gsl_rng_type * _t) {
113 if(_instance == 0) {
114 _instance = new Randnum(_t);
115 }
116 else if(_t != _instance->T) {
117 gsl_rng_free (_instance->r);
118 _instance->r = gsl_rng_alloc (_t);
119 gsl_rng_set(_instance->r, _seed );
120 }
121
122 return _instance;
123}
124
126{
127 r = gsl_rng_alloc (T);
128 gsl_rng_set(r, _seed );
129}
130
131Randnum::Randnum(const gsl_rng_type * _t)
132{
133 r = gsl_rng_alloc (_t);
134 gsl_rng_set(r, _seed );
135}
136
138{
139 gsl_rng_free (r);
140}
141
142void Randnum::set_seed(unsigned long long seed)
143{
144 _seed = seed;
145 gsl_rng_set(r, _seed);
146}
147
148unsigned long long Randnum::get_seed()
149{
150 return _seed;
151}
152
153long long Randnum::get_irand(long long lo, long long hi) const
154{
155 return gsl_rng_uniform_int(r, hi-lo+1)+lo;
156}
157
158float Randnum::get_frand(double lo, double hi) const
159{
160 return static_cast<float>(gsl_rng_uniform(r) * (hi -lo) + lo);
161}
162
163float Randnum::get_frand_pos(double lo, double hi) const
164{
165 return static_cast<float>(gsl_rng_uniform_pos(r) * (hi -lo) + lo);
166}
167
168float Randnum::get_gauss_rand(float mean, float sigma) const
169{
170 float x = 0.0f;
171 float y = 0.0f;
172 float r = 0.0f;
173 bool valid = true;
174
175 while (valid) {
176 x = get_frand_pos(-1.0, 1.0);
177 y = get_frand_pos(-1.0, 1.0);
178 r = x * x + y * y;
179
180 if (r <= 1.0 && r > 0) {
181 valid = false;
182 }
183 }
184
185 float f = std::sqrt(-2.0f * std::log(r) / r);
186 float result = x * f * sigma + mean;
187 return result;
188}
189
191{
192 const gsl_rng_type **t, **t0;
193
194 t0 = gsl_rng_types_setup ();
195
196 printf ("Available generators:\n");
197
198 for (t = t0; *t != 0; t++) {
199 printf ("%s\n", (*t)->name);
200 }
201}
The wrapper class for gsl's random number generater.
Definition: randnum.h:86
static unsigned long long _seed
Definition: randnum.h:167
void print_generator_type() const
print out all possible random number generator type in gsl
Definition: randnum.cpp:190
void set_seed(unsigned long long seed)
Set the seed for the random number generator.
Definition: randnum.cpp:142
static const gsl_rng_type * T
Definition: randnum.h:165
static Randnum * Instance()
Definition: randnum.cpp:104
static Randnum * _instance
Definition: randnum.h:169
Randnum()
The default constructor will use the gsl default random number generator gal_rng_mt19937.
Definition: randnum.cpp:125
long long get_irand(long long lo, long long hi) const
This function returns a random integer from lo to hi inclusive.
Definition: randnum.cpp:153
unsigned long long get_seed()
Get the current random number seed.
Definition: randnum.cpp:148
float get_gauss_rand(float mean, float sigma) const
Return a Gaussian random number.
Definition: randnum.cpp:168
float get_frand(double lo=0.0, double hi=1.0) const
This function returns a random float from lo inclusive to hi.
Definition: randnum.cpp:158
float get_frand_pos(double lo=0.0, double hi=1.0) const
This function returns a random float from lo to hi.
Definition: randnum.cpp:163
static gsl_rng * r
Definition: randnum.h:166
EMData * log() const
return natural logarithm image for a image
EMData * sqrt() const
return square root of current image
E2Exception class.
Definition: aligner.h:40
#define y(i, j)
Definition: projector.cpp:1516
#define x(i)
Definition: projector.cpp:1517