362 |
04 Aug 05 |
jari |
// $Id$ |
362 |
04 Aug 05 |
jari |
2 |
|
561 |
15 Mar 06 |
jari |
3 |
/* |
2119 |
12 Dec 09 |
peter |
Copyright (C) 2005, 2006, 2007, 2008 Jari Häkkinen, Peter Johansson |
4359 |
23 Aug 23 |
peter |
Copyright (C) 2009, 2011, 2012, 2013, 2015, 2016, 2017, 2018, 2020, 2022, 2023 Peter Johansson |
561 |
15 Mar 06 |
jari |
6 |
|
1437 |
25 Aug 08 |
peter |
This file is part of the yat library, http://dev.thep.lu.se/yat |
561 |
15 Mar 06 |
jari |
8 |
|
675 |
10 Oct 06 |
jari |
The yat library is free software; you can redistribute it and/or |
675 |
10 Oct 06 |
jari |
modify it under the terms of the GNU General Public License as |
1486 |
09 Sep 08 |
jari |
published by the Free Software Foundation; either version 3 of the |
675 |
10 Oct 06 |
jari |
License, or (at your option) any later version. |
561 |
15 Mar 06 |
jari |
13 |
|
675 |
10 Oct 06 |
jari |
The yat library is distributed in the hope that it will be useful, |
675 |
10 Oct 06 |
jari |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
675 |
10 Oct 06 |
jari |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
561 |
15 Mar 06 |
jari |
General Public License for more details. |
561 |
15 Mar 06 |
jari |
18 |
|
561 |
15 Mar 06 |
jari |
You should have received a copy of the GNU General Public License |
1487 |
10 Sep 08 |
jari |
along with yat. If not, see <http://www.gnu.org/licenses/>. |
561 |
15 Mar 06 |
jari |
21 |
*/ |
561 |
15 Mar 06 |
jari |
22 |
|
2881 |
18 Nov 12 |
peter |
23 |
#include <config.h> |
2881 |
18 Nov 12 |
peter |
24 |
|
680 |
11 Oct 06 |
jari |
25 |
#include "random.h" |
675 |
10 Oct 06 |
jari |
26 |
#include "yat/statistics/Histogram.h" |
738 |
07 Jan 07 |
jari |
27 |
#include "yat/utility/Exception.h" |
3902 |
05 May 20 |
peter |
28 |
#include "yat/utility/utility.h" |
371 |
05 Aug 05 |
peter |
29 |
|
1614 |
05 Nov 08 |
peter |
30 |
#include <cassert> |
3591 |
20 Jan 17 |
peter |
31 |
#include <cstddef> |
2588 |
25 Oct 11 |
peter |
32 |
#include <cstring> |
374 |
05 Aug 05 |
jari |
33 |
#include <fstream> |
3959 |
30 Jul 20 |
peter |
34 |
#include <mutex> |
738 |
07 Jan 07 |
jari |
35 |
#include <sstream> |
371 |
05 Aug 05 |
peter |
36 |
|
362 |
04 Aug 05 |
jari |
37 |
namespace theplu { |
680 |
11 Oct 06 |
jari |
38 |
namespace yat { |
365 |
05 Aug 05 |
peter |
39 |
namespace random { |
362 |
04 Aug 05 |
jari |
40 |
|
3591 |
20 Jan 17 |
peter |
41 |
std::atomic<RNG*> RNG::instance_ { nullptr }; |
3959 |
30 Jul 20 |
peter |
42 |
std::mutex RNG::init_mutex_; |
3959 |
30 Jul 20 |
peter |
43 |
thread_local std::unique_ptr<gsl_rng, void(*)(gsl_rng*)> RNG::rng_ |
3959 |
30 Jul 20 |
peter |
44 |
{ nullptr, gsl_rng_free}; |
362 |
04 Aug 05 |
jari |
45 |
|
425 |
07 Dec 05 |
jari |
46 |
RNG::RNG(void) |
362 |
04 Aug 05 |
jari |
47 |
{ |
738 |
07 Jan 07 |
jari |
// support rng/seed changes through environment vars |
738 |
07 Jan 07 |
jari |
49 |
if (!gsl_rng_env_setup()) |
750 |
17 Feb 07 |
jari |
50 |
throw utility::GSL_error("RNG::RNG unknown generator"); |
2800 |
28 Jul 12 |
peter |
51 |
seed_ = gsl_rng_default_seed; |
2802 |
29 Jul 12 |
peter |
// let's allocate already here, just to behave as yat 0.8 |
2802 |
29 Jul 12 |
peter |
53 |
rng_alloc(); |
362 |
04 Aug 05 |
jari |
54 |
} |
362 |
04 Aug 05 |
jari |
55 |
|
362 |
04 Aug 05 |
jari |
56 |
|
362 |
04 Aug 05 |
jari |
57 |
RNG::~RNG(void) |
362 |
04 Aug 05 |
jari |
58 |
{ |
362 |
04 Aug 05 |
jari |
59 |
} |
362 |
04 Aug 05 |
jari |
60 |
|
2768 |
11 Jul 12 |
peter |
61 |
|
752 |
17 Feb 07 |
jari |
62 |
RNG* RNG::instance(void) |
752 |
17 Feb 07 |
jari |
63 |
{ |
3579 |
16 Jan 17 |
peter |
64 |
if (instance_==NULL) { |
3959 |
30 Jul 20 |
peter |
65 |
std::unique_lock<std::mutex> lock(init_mutex_); |
3579 |
16 Jan 17 |
peter |
66 |
if (instance_==NULL) |
3579 |
16 Jan 17 |
peter |
67 |
instance_ = new RNG; |
3579 |
16 Jan 17 |
peter |
68 |
} |
2770 |
11 Jul 12 |
peter |
69 |
return instance_; |
752 |
17 Feb 07 |
jari |
70 |
} |
752 |
17 Feb 07 |
jari |
71 |
|
752 |
17 Feb 07 |
jari |
72 |
|
1271 |
09 Apr 08 |
peter |
73 |
unsigned long RNG::max(void) const |
718 |
26 Dec 06 |
jari |
74 |
{ |
2770 |
11 Jul 12 |
peter |
75 |
return gsl_rng_max(rng()); |
718 |
26 Dec 06 |
jari |
76 |
} |
718 |
26 Dec 06 |
jari |
77 |
|
718 |
26 Dec 06 |
jari |
78 |
|
1271 |
09 Apr 08 |
peter |
79 |
unsigned long RNG::min(void) const |
718 |
26 Dec 06 |
jari |
80 |
{ |
2770 |
11 Jul 12 |
peter |
81 |
return gsl_rng_min(rng()); |
718 |
26 Dec 06 |
jari |
82 |
} |
718 |
26 Dec 06 |
jari |
83 |
|
718 |
26 Dec 06 |
jari |
84 |
|
718 |
26 Dec 06 |
jari |
85 |
std::string RNG::name(void) const |
718 |
26 Dec 06 |
jari |
86 |
{ |
2770 |
11 Jul 12 |
peter |
87 |
return gsl_rng_name(rng()); |
718 |
26 Dec 06 |
jari |
88 |
} |
718 |
26 Dec 06 |
jari |
89 |
|
718 |
26 Dec 06 |
jari |
90 |
|
718 |
26 Dec 06 |
jari |
91 |
const gsl_rng* RNG::rng(void) const |
718 |
26 Dec 06 |
jari |
92 |
{ |
2770 |
11 Jul 12 |
peter |
93 |
if (rng_.get()==NULL) |
2770 |
11 Jul 12 |
peter |
94 |
rng_alloc(); |
2770 |
11 Jul 12 |
peter |
95 |
return rng_.get(); |
718 |
26 Dec 06 |
jari |
96 |
} |
718 |
26 Dec 06 |
jari |
97 |
|
718 |
26 Dec 06 |
jari |
98 |
|
2770 |
11 Jul 12 |
peter |
99 |
void RNG::rng_alloc(void) const |
2770 |
11 Jul 12 |
peter |
100 |
{ |
2770 |
11 Jul 12 |
peter |
101 |
assert(rng_.get()==NULL); |
2770 |
11 Jul 12 |
peter |
102 |
gsl_rng* rng = gsl_rng_alloc(gsl_rng_default); |
2770 |
11 Jul 12 |
peter |
103 |
if (!rng) |
2770 |
11 Jul 12 |
peter |
104 |
throw utility::GSL_error("RNG failed to allocate memory"); |
3959 |
30 Jul 20 |
peter |
105 |
std::unique_lock<std::mutex> lock(mutex_); |
2802 |
29 Jul 12 |
peter |
106 |
gsl_rng_set(rng, seed_); |
2802 |
29 Jul 12 |
peter |
// bump seed to avoid subsequent gsl_rng to be identical |
2802 |
29 Jul 12 |
peter |
108 |
++seed_; |
2789 |
25 Jul 12 |
peter |
// rng_ owns rng and takes care of deallocation |
2770 |
11 Jul 12 |
peter |
110 |
rng_.reset(rng); |
2838 |
16 Sep 12 |
peter |
111 |
} // lock is released here |
2770 |
11 Jul 12 |
peter |
112 |
|
2770 |
11 Jul 12 |
peter |
113 |
|
1271 |
09 Apr 08 |
peter |
114 |
void RNG::seed(unsigned long s) const |
718 |
26 Dec 06 |
jari |
115 |
{ |
3959 |
30 Jul 20 |
peter |
116 |
std::unique_lock<std::mutex> lock(mutex_); |
2770 |
11 Jul 12 |
peter |
117 |
gsl_rng_set(rng(),s); |
2802 |
29 Jul 12 |
peter |
118 |
seed_ = s+1; |
2838 |
16 Sep 12 |
peter |
119 |
} // lock is released here |
718 |
26 Dec 06 |
jari |
120 |
|
718 |
26 Dec 06 |
jari |
121 |
|
1271 |
09 Apr 08 |
peter |
122 |
unsigned long RNG::seed_from_devurandom(void) |
374 |
05 Aug 05 |
jari |
123 |
{ |
2590 |
25 Oct 11 |
peter |
124 |
std::ifstream is("/dev/urandom", std::ios::binary); |
3902 |
05 May 20 |
peter |
125 |
unsigned long s=0; |
3902 |
05 May 20 |
peter |
126 |
utility::binary_read(is, s); |
374 |
05 Aug 05 |
jari |
127 |
is.close(); |
374 |
05 Aug 05 |
jari |
128 |
seed(s); |
374 |
05 Aug 05 |
jari |
129 |
return s; |
374 |
05 Aug 05 |
jari |
130 |
} |
374 |
05 Aug 05 |
jari |
131 |
|
374 |
05 Aug 05 |
jari |
132 |
|
674 |
10 Oct 06 |
peter |
133 |
int RNG::set_state(const RNG_state& state) |
674 |
10 Oct 06 |
peter |
134 |
{ |
2770 |
11 Jul 12 |
peter |
135 |
if (rng_.get()==NULL) |
2770 |
11 Jul 12 |
peter |
136 |
rng_alloc(); |
2804 |
31 Jul 12 |
peter |
137 |
if (gsl_rng_memcpy(rng_.get(), state.rng())) |
2804 |
31 Jul 12 |
peter |
138 |
throw utility::GSL_error("yat::random::RNG::set_state failed"); |
2804 |
31 Jul 12 |
peter |
139 |
return 0; |
674 |
10 Oct 06 |
peter |
140 |
} |
674 |
10 Oct 06 |
peter |
141 |
|
718 |
26 Dec 06 |
jari |
// --------------------- RNG_state ---------------------------------- |
674 |
10 Oct 06 |
peter |
143 |
|
674 |
10 Oct 06 |
peter |
144 |
RNG_state::RNG_state(const RNG* rng) |
674 |
10 Oct 06 |
peter |
145 |
{ |
1614 |
05 Nov 08 |
peter |
146 |
clone(*rng->rng()); |
674 |
10 Oct 06 |
peter |
147 |
} |
674 |
10 Oct 06 |
peter |
148 |
|
2770 |
11 Jul 12 |
peter |
149 |
|
1614 |
05 Nov 08 |
peter |
150 |
RNG_state::RNG_state(const RNG_state& state) |
1614 |
05 Nov 08 |
peter |
151 |
{ |
1614 |
05 Nov 08 |
peter |
152 |
clone(*state.rng()); |
1614 |
05 Nov 08 |
peter |
153 |
} |
1614 |
05 Nov 08 |
peter |
154 |
|
2770 |
11 Jul 12 |
peter |
155 |
|
674 |
10 Oct 06 |
peter |
156 |
RNG_state::~RNG_state(void) |
674 |
10 Oct 06 |
peter |
157 |
{ |
674 |
10 Oct 06 |
peter |
158 |
gsl_rng_free(rng_); |
674 |
10 Oct 06 |
peter |
159 |
rng_=NULL; |
674 |
10 Oct 06 |
peter |
160 |
} |
674 |
10 Oct 06 |
peter |
161 |
|
718 |
26 Dec 06 |
jari |
162 |
const gsl_rng* RNG_state::rng(void) const |
718 |
26 Dec 06 |
jari |
163 |
{ |
718 |
26 Dec 06 |
jari |
164 |
return rng_; |
718 |
26 Dec 06 |
jari |
165 |
} |
718 |
26 Dec 06 |
jari |
166 |
|
1614 |
05 Nov 08 |
peter |
167 |
|
1614 |
05 Nov 08 |
peter |
168 |
void RNG_state::clone(const gsl_rng& rng) |
1614 |
05 Nov 08 |
peter |
169 |
{ |
1614 |
05 Nov 08 |
peter |
170 |
assert(rng_!=&rng); |
1614 |
05 Nov 08 |
peter |
171 |
if (!(rng_ = gsl_rng_clone(&rng))) |
2804 |
31 Jul 12 |
peter |
172 |
throw utility::GSL_error("RNG_state::clone failed to allocate memory"); |
1614 |
05 Nov 08 |
peter |
173 |
} |
1614 |
05 Nov 08 |
peter |
174 |
|
1614 |
05 Nov 08 |
peter |
175 |
RNG_state& RNG_state::operator=(const RNG_state& rhs) |
1614 |
05 Nov 08 |
peter |
176 |
{ |
1614 |
05 Nov 08 |
peter |
177 |
if (this != &rhs) { |
1614 |
05 Nov 08 |
peter |
178 |
gsl_rng_free(rng_); |
1614 |
05 Nov 08 |
peter |
179 |
clone(*rhs.rng()); |
1614 |
05 Nov 08 |
peter |
180 |
} |
1614 |
05 Nov 08 |
peter |
181 |
return *this; |
1614 |
05 Nov 08 |
peter |
182 |
} |
1614 |
05 Nov 08 |
peter |
183 |
|
706 |
19 Dec 06 |
jari |
// --------------------- Discrete distribtuions --------------------- |
674 |
10 Oct 06 |
peter |
185 |
|
706 |
19 Dec 06 |
jari |
186 |
Discrete::Discrete(void) |
706 |
19 Dec 06 |
jari |
187 |
: rng_(RNG::instance()) |
706 |
19 Dec 06 |
jari |
188 |
{ |
706 |
19 Dec 06 |
jari |
189 |
} |
706 |
19 Dec 06 |
jari |
190 |
|
2804 |
31 Jul 12 |
peter |
191 |
|
706 |
19 Dec 06 |
jari |
192 |
Discrete::~Discrete(void) |
706 |
19 Dec 06 |
jari |
193 |
{ |
706 |
19 Dec 06 |
jari |
194 |
} |
706 |
19 Dec 06 |
jari |
195 |
|
706 |
19 Dec 06 |
jari |
196 |
|
1271 |
09 Apr 08 |
peter |
197 |
void Discrete::seed(unsigned long s) const |
718 |
26 Dec 06 |
jari |
198 |
{ |
718 |
26 Dec 06 |
jari |
199 |
rng_->seed(s); |
718 |
26 Dec 06 |
jari |
200 |
} |
718 |
26 Dec 06 |
jari |
201 |
|
718 |
26 Dec 06 |
jari |
202 |
|
2804 |
31 Jul 12 |
peter |
203 |
unsigned long Discrete::seed_from_devurandom(void) |
2804 |
31 Jul 12 |
peter |
204 |
{ |
2804 |
31 Jul 12 |
peter |
205 |
return rng_->seed_from_devurandom(); |
1271 |
09 Apr 08 |
peter |
206 |
} |
1271 |
09 Apr 08 |
peter |
207 |
|
1271 |
09 Apr 08 |
peter |
208 |
|
2889 |
07 Dec 12 |
peter |
209 |
Binomial::Binomial(double p, unsigned int n) |
2890 |
07 Dec 12 |
peter |
210 |
: Discrete(), p_(p), n_(n) |
2889 |
07 Dec 12 |
peter |
211 |
{ |
2889 |
07 Dec 12 |
peter |
212 |
} |
2889 |
07 Dec 12 |
peter |
213 |
|
2889 |
07 Dec 12 |
peter |
214 |
|
2889 |
07 Dec 12 |
peter |
215 |
unsigned long Binomial::operator()(void) const |
2889 |
07 Dec 12 |
peter |
216 |
{ |
2889 |
07 Dec 12 |
peter |
217 |
return gsl_ran_binomial(rng_->rng(), p_, n_); |
2889 |
07 Dec 12 |
peter |
218 |
} |
2889 |
07 Dec 12 |
peter |
219 |
|
2889 |
07 Dec 12 |
peter |
220 |
|
4009 |
19 Oct 20 |
peter |
221 |
DiscreteGeneral::DiscreteGeneral(void) |
4009 |
19 Oct 20 |
peter |
222 |
: gen_(nullptr) |
4009 |
19 Oct 20 |
peter |
223 |
{} |
4009 |
19 Oct 20 |
peter |
224 |
|
4009 |
19 Oct 20 |
peter |
225 |
|
371 |
05 Aug 05 |
peter |
226 |
DiscreteGeneral::DiscreteGeneral(const statistics::Histogram& hist) |
1616 |
05 Nov 08 |
peter |
227 |
: gen_(NULL) |
371 |
05 Aug 05 |
peter |
228 |
{ |
1616 |
05 Nov 08 |
peter |
229 |
p_.reserve(hist.nof_bins()); |
2804 |
31 Jul 12 |
peter |
230 |
for (size_t i=0; i<hist.nof_bins(); i++) |
1616 |
05 Nov 08 |
peter |
231 |
p_.push_back(hist[i]); |
1616 |
05 Nov 08 |
peter |
232 |
preproc(); |
371 |
05 Aug 05 |
peter |
233 |
} |
371 |
05 Aug 05 |
peter |
234 |
|
374 |
05 Aug 05 |
jari |
235 |
|
1616 |
05 Nov 08 |
peter |
236 |
DiscreteGeneral::DiscreteGeneral(const DiscreteGeneral& other) |
2090 |
21 Oct 09 |
peter |
237 |
: Discrete(other), gen_(NULL), p_(other.p_) |
1616 |
05 Nov 08 |
peter |
238 |
{ |
1616 |
05 Nov 08 |
peter |
239 |
preproc(); |
1616 |
05 Nov 08 |
peter |
240 |
} |
1616 |
05 Nov 08 |
peter |
241 |
|
1616 |
05 Nov 08 |
peter |
242 |
|
4010 |
19 Oct 20 |
peter |
243 |
DiscreteGeneral::DiscreteGeneral(DiscreteGeneral&& other) |
4382 |
13 Oct 23 |
peter |
244 |
: Discrete(std::move(other)), gen_(other.gen_), p_(std::move(other.p_)) |
4010 |
19 Oct 20 |
peter |
245 |
{ |
4382 |
13 Oct 23 |
peter |
246 |
other.gen_ = nullptr; |
4010 |
19 Oct 20 |
peter |
247 |
} |
4010 |
19 Oct 20 |
peter |
248 |
|
4010 |
19 Oct 20 |
peter |
249 |
|
371 |
05 Aug 05 |
peter |
250 |
DiscreteGeneral::~DiscreteGeneral(void) |
371 |
05 Aug 05 |
peter |
251 |
{ |
1616 |
05 Nov 08 |
peter |
252 |
free(); |
1616 |
05 Nov 08 |
peter |
253 |
} |
1616 |
05 Nov 08 |
peter |
254 |
|
1616 |
05 Nov 08 |
peter |
255 |
|
1616 |
05 Nov 08 |
peter |
256 |
void DiscreteGeneral::free(void) |
1616 |
05 Nov 08 |
peter |
257 |
{ |
374 |
05 Aug 05 |
jari |
258 |
if (gen_) |
371 |
05 Aug 05 |
peter |
259 |
gsl_ran_discrete_free( gen_ ); |
371 |
05 Aug 05 |
peter |
260 |
gen_ = NULL; |
371 |
05 Aug 05 |
peter |
261 |
} |
371 |
05 Aug 05 |
peter |
262 |
|
706 |
19 Dec 06 |
jari |
263 |
|
1616 |
05 Nov 08 |
peter |
264 |
void DiscreteGeneral::preproc(void) |
1616 |
05 Nov 08 |
peter |
265 |
{ |
1616 |
05 Nov 08 |
peter |
266 |
assert(!gen_); |
1616 |
05 Nov 08 |
peter |
267 |
assert(p_.size()); |
1616 |
05 Nov 08 |
peter |
268 |
gen_ = gsl_ran_discrete_preproc( p_.size(), &p_.front() ); |
1616 |
05 Nov 08 |
peter |
269 |
if (!gen_) |
1616 |
05 Nov 08 |
peter |
270 |
throw utility::GSL_error("DiscreteGeneral failed to setup generator."); |
1616 |
05 Nov 08 |
peter |
271 |
} |
1616 |
05 Nov 08 |
peter |
272 |
|
1616 |
05 Nov 08 |
peter |
273 |
|
1616 |
05 Nov 08 |
peter |
274 |
DiscreteGeneral& DiscreteGeneral::operator=(const DiscreteGeneral& rhs) |
1616 |
05 Nov 08 |
peter |
275 |
{ |
4010 |
19 Oct 20 |
peter |
276 |
DiscreteGeneral tmp(rhs); |
4010 |
19 Oct 20 |
peter |
277 |
swap(*this, tmp); |
1616 |
05 Nov 08 |
peter |
278 |
return *this; |
1616 |
05 Nov 08 |
peter |
279 |
} |
1616 |
05 Nov 08 |
peter |
280 |
|
1616 |
05 Nov 08 |
peter |
281 |
|
4010 |
19 Oct 20 |
peter |
282 |
DiscreteGeneral& DiscreteGeneral::operator=(DiscreteGeneral&& rhs) |
4010 |
19 Oct 20 |
peter |
283 |
{ |
4010 |
19 Oct 20 |
peter |
284 |
DiscreteGeneral tmp(std::move(rhs)); |
4010 |
19 Oct 20 |
peter |
285 |
swap(*this, tmp); |
4010 |
19 Oct 20 |
peter |
286 |
return *this; |
4010 |
19 Oct 20 |
peter |
287 |
} |
4010 |
19 Oct 20 |
peter |
288 |
|
4010 |
19 Oct 20 |
peter |
289 |
|
1271 |
09 Apr 08 |
peter |
290 |
unsigned long DiscreteGeneral::operator()(void) const |
718 |
26 Dec 06 |
jari |
291 |
{ |
718 |
26 Dec 06 |
jari |
292 |
return gsl_ran_discrete(rng_->rng(), gen_); |
718 |
26 Dec 06 |
jari |
293 |
} |
718 |
26 Dec 06 |
jari |
294 |
|
718 |
26 Dec 06 |
jari |
295 |
|
4010 |
19 Oct 20 |
peter |
296 |
void swap(DiscreteGeneral& lhs, DiscreteGeneral& rhs) |
4010 |
19 Oct 20 |
peter |
297 |
{ |
4010 |
19 Oct 20 |
peter |
298 |
std::swap(lhs.gen_, rhs.gen_); |
4010 |
19 Oct 20 |
peter |
299 |
std::swap(lhs.p_, rhs.p_); |
4010 |
19 Oct 20 |
peter |
300 |
} |
4010 |
19 Oct 20 |
peter |
301 |
|
4010 |
19 Oct 20 |
peter |
302 |
|
1271 |
09 Apr 08 |
peter |
303 |
DiscreteUniform::DiscreteUniform(unsigned long n) |
718 |
26 Dec 06 |
jari |
304 |
: range_(n) |
718 |
26 Dec 06 |
jari |
305 |
{ |
738 |
07 Jan 07 |
jari |
306 |
if (range_>rng_->max()) { |
3074 |
03 Sep 13 |
peter |
307 |
std::ostringstream ss; |
3074 |
03 Sep 13 |
peter |
308 |
ss << "DiscreteUniform::DiscreteUniform: "; |
738 |
07 Jan 07 |
jari |
309 |
ss << n << " is too large for RNG " << rng_->name(); |
3074 |
03 Sep 13 |
peter |
310 |
ss << "; maximal argument is " << rng_->max(); |
738 |
07 Jan 07 |
jari |
311 |
throw utility::GSL_error(ss.str()); |
738 |
07 Jan 07 |
jari |
312 |
} |
718 |
26 Dec 06 |
jari |
313 |
} |
718 |
26 Dec 06 |
jari |
314 |
|
718 |
26 Dec 06 |
jari |
315 |
|
1271 |
09 Apr 08 |
peter |
316 |
unsigned long DiscreteUniform::operator()(void) const |
718 |
26 Dec 06 |
jari |
317 |
{ |
738 |
07 Jan 07 |
jari |
318 |
return (range_ ? |
2804 |
31 Jul 12 |
peter |
319 |
gsl_rng_uniform_int(rng_->rng(),range_) : gsl_rng_get(rng_->rng())); |
718 |
26 Dec 06 |
jari |
320 |
} |
718 |
26 Dec 06 |
jari |
321 |
|
718 |
26 Dec 06 |
jari |
322 |
|
1271 |
09 Apr 08 |
peter |
323 |
unsigned long DiscreteUniform::operator()(unsigned long n) const |
718 |
26 Dec 06 |
jari |
324 |
{ |
738 |
07 Jan 07 |
jari |
// making sure that n is not larger than the range of the |
738 |
07 Jan 07 |
jari |
// underlying RNG |
738 |
07 Jan 07 |
jari |
327 |
if (n>rng_->max()) { |
3074 |
03 Sep 13 |
peter |
328 |
std::ostringstream ss; |
3074 |
03 Sep 13 |
peter |
329 |
ss << "DiscreteUniform::operator(unsigned long): "; |
738 |
07 Jan 07 |
jari |
330 |
ss << n << " is too large for RNG " << rng_->name(); |
3074 |
03 Sep 13 |
peter |
331 |
ss << "; maximal argument is " << rng_->max(); |
738 |
07 Jan 07 |
jari |
332 |
throw utility::GSL_error(ss.str()); |
738 |
07 Jan 07 |
jari |
333 |
} |
738 |
07 Jan 07 |
jari |
334 |
return gsl_rng_uniform_int(rng_->rng(),n); |
718 |
26 Dec 06 |
jari |
335 |
} |
718 |
26 Dec 06 |
jari |
336 |
|
718 |
26 Dec 06 |
jari |
337 |
|
3894 |
27 Mar 20 |
peter |
338 |
unsigned long int DiscreteUniform::min(void) const |
3894 |
27 Mar 20 |
peter |
339 |
{ |
3894 |
27 Mar 20 |
peter |
340 |
return range_ ? 0 : rng_->min(); |
3894 |
27 Mar 20 |
peter |
341 |
} |
3894 |
27 Mar 20 |
peter |
342 |
|
3894 |
27 Mar 20 |
peter |
343 |
|
3894 |
27 Mar 20 |
peter |
344 |
unsigned long int DiscreteUniform::max(void) const |
3894 |
27 Mar 20 |
peter |
345 |
{ |
3894 |
27 Mar 20 |
peter |
346 |
return range_ ? (range_-1) : rng_->max(); |
3894 |
27 Mar 20 |
peter |
347 |
} |
3894 |
27 Mar 20 |
peter |
348 |
|
3894 |
27 Mar 20 |
peter |
349 |
|
3446 |
02 Dec 15 |
peter |
350 |
Geometric::Geometric(double p) |
3446 |
02 Dec 15 |
peter |
351 |
: p_(p) |
3446 |
02 Dec 15 |
peter |
352 |
{} |
3446 |
02 Dec 15 |
peter |
353 |
|
3446 |
02 Dec 15 |
peter |
354 |
|
3446 |
02 Dec 15 |
peter |
355 |
unsigned long int Geometric::operator()(void) const |
3446 |
02 Dec 15 |
peter |
356 |
{ |
4200 |
19 Aug 22 |
peter |
357 |
return gsl_ran_geometric (rng_->rng(), p_); |
3446 |
02 Dec 15 |
peter |
358 |
} |
3446 |
02 Dec 15 |
peter |
359 |
|
3446 |
02 Dec 15 |
peter |
360 |
|
3446 |
02 Dec 15 |
peter |
361 |
unsigned long int Geometric::operator()(double p) const |
3446 |
02 Dec 15 |
peter |
362 |
{ |
3446 |
02 Dec 15 |
peter |
363 |
return gsl_ran_geometric (rng_->rng(), p); |
3446 |
02 Dec 15 |
peter |
364 |
} |
3446 |
02 Dec 15 |
peter |
365 |
|
3446 |
02 Dec 15 |
peter |
366 |
|
3465 |
10 Feb 16 |
peter |
367 |
HyperGeometric::HyperGeometric(void) |
3465 |
10 Feb 16 |
peter |
368 |
{} |
3465 |
10 Feb 16 |
peter |
369 |
|
3465 |
10 Feb 16 |
peter |
370 |
|
3465 |
10 Feb 16 |
peter |
371 |
HyperGeometric::HyperGeometric(unsigned int n1, unsigned int n2, |
3465 |
10 Feb 16 |
peter |
372 |
unsigned int t) |
3465 |
10 Feb 16 |
peter |
373 |
: n1_(n1), n2_(n2), t_(t) |
3465 |
10 Feb 16 |
peter |
374 |
{} |
3465 |
10 Feb 16 |
peter |
375 |
|
3465 |
10 Feb 16 |
peter |
376 |
|
3465 |
10 Feb 16 |
peter |
377 |
unsigned long int HyperGeometric::operator()(void) const |
3465 |
10 Feb 16 |
peter |
378 |
{ |
3465 |
10 Feb 16 |
peter |
379 |
return (*this)(n1_, n2_, t_); |
3465 |
10 Feb 16 |
peter |
380 |
} |
3465 |
10 Feb 16 |
peter |
381 |
|
3465 |
10 Feb 16 |
peter |
382 |
|
3465 |
10 Feb 16 |
peter |
383 |
unsigned long int HyperGeometric::operator()(unsigned int n1, |
3465 |
10 Feb 16 |
peter |
384 |
unsigned int n2, |
3465 |
10 Feb 16 |
peter |
385 |
unsigned int t) const |
3465 |
10 Feb 16 |
peter |
386 |
{ |
3465 |
10 Feb 16 |
peter |
387 |
return gsl_ran_hypergeometric(rng_->rng(), n1, n2, t); |
3465 |
10 Feb 16 |
peter |
388 |
} |
3465 |
10 Feb 16 |
peter |
389 |
|
3465 |
10 Feb 16 |
peter |
390 |
|
3469 |
29 Feb 16 |
peter |
391 |
NegativeHyperGeometric::NegativeHyperGeometric(void) |
3469 |
29 Feb 16 |
peter |
392 |
{} |
3469 |
29 Feb 16 |
peter |
393 |
|
3469 |
29 Feb 16 |
peter |
394 |
|
3469 |
29 Feb 16 |
peter |
395 |
NegativeHyperGeometric::NegativeHyperGeometric(unsigned int n1, |
3469 |
29 Feb 16 |
peter |
396 |
unsigned int n2, unsigned int t) |
3469 |
29 Feb 16 |
peter |
397 |
: n1_(n1), n2_(n2), t_(t) |
3469 |
29 Feb 16 |
peter |
398 |
{} |
3469 |
29 Feb 16 |
peter |
399 |
|
3469 |
29 Feb 16 |
peter |
400 |
|
3469 |
29 Feb 16 |
peter |
401 |
unsigned long int NegativeHyperGeometric::operator()(void) const |
3469 |
29 Feb 16 |
peter |
402 |
{ |
3469 |
29 Feb 16 |
peter |
403 |
return (*this)(n1_, n2_, t_); |
3469 |
29 Feb 16 |
peter |
404 |
} |
3469 |
29 Feb 16 |
peter |
405 |
|
3469 |
29 Feb 16 |
peter |
406 |
|
3469 |
29 Feb 16 |
peter |
407 |
unsigned long int NegativeHyperGeometric::operator()(unsigned int n1, |
3469 |
29 Feb 16 |
peter |
408 |
unsigned int n2, |
3469 |
29 Feb 16 |
peter |
409 |
unsigned int t) const |
3469 |
29 Feb 16 |
peter |
410 |
{ |
3469 |
29 Feb 16 |
peter |
411 |
assert(t <= n2); |
3469 |
29 Feb 16 |
peter |
412 |
|
3469 |
29 Feb 16 |
peter |
// NHG can be described as an array with n1 true and n2 false, and |
3469 |
29 Feb 16 |
peter |
// NHG(n1, n2, t) is the number of true left of the t:th false. By |
3469 |
29 Feb 16 |
peter |
// symmetry number of true right of the t:th false is NHG(n1, n2, |
3469 |
29 Feb 16 |
peter |
// n2-t+1) since t:th false counting from left is the (n2-t+1):th |
3469 |
29 Feb 16 |
peter |
// false counting from right. |
3469 |
29 Feb 16 |
peter |
418 |
|
3469 |
29 Feb 16 |
peter |
// When t is larger than midpoint (2*t > n2+1) we use this |
3469 |
29 Feb 16 |
peter |
// symmetry to speed things up. |
3469 |
29 Feb 16 |
peter |
421 |
if (t > (n2+1)/2) |
3469 |
29 Feb 16 |
peter |
422 |
return n1 - (*this)(n1, n2, n2-t+1); |
3469 |
29 Feb 16 |
peter |
423 |
|
3469 |
29 Feb 16 |
peter |
424 |
ContinuousUniform uniform; |
3469 |
29 Feb 16 |
peter |
425 |
unsigned long int k = 0; |
3469 |
29 Feb 16 |
peter |
426 |
while (t) { |
3469 |
29 Feb 16 |
peter |
427 |
assert(n1 + n2); |
3469 |
29 Feb 16 |
peter |
428 |
double x = uniform(); |
3469 |
29 Feb 16 |
peter |
429 |
if (x * (n1+n2) < n1) { |
3469 |
29 Feb 16 |
peter |
430 |
--n1; |
3469 |
29 Feb 16 |
peter |
431 |
++k; |
3469 |
29 Feb 16 |
peter |
432 |
if (!n1) |
3469 |
29 Feb 16 |
peter |
433 |
return k; |
3469 |
29 Feb 16 |
peter |
434 |
} |
3469 |
29 Feb 16 |
peter |
435 |
else { |
3469 |
29 Feb 16 |
peter |
436 |
--t; |
3469 |
29 Feb 16 |
peter |
437 |
--n2; |
3469 |
29 Feb 16 |
peter |
438 |
} |
3469 |
29 Feb 16 |
peter |
439 |
} |
3469 |
29 Feb 16 |
peter |
440 |
return k; |
3469 |
29 Feb 16 |
peter |
441 |
} |
3469 |
29 Feb 16 |
peter |
442 |
|
3469 |
29 Feb 16 |
peter |
443 |
|
706 |
19 Dec 06 |
jari |
444 |
Poisson::Poisson(const double m) |
706 |
19 Dec 06 |
jari |
445 |
: m_(m) |
706 |
19 Dec 06 |
jari |
446 |
{ |
706 |
19 Dec 06 |
jari |
447 |
} |
706 |
19 Dec 06 |
jari |
448 |
|
1271 |
09 Apr 08 |
peter |
449 |
unsigned long Poisson::operator()(void) const |
718 |
26 Dec 06 |
jari |
450 |
{ |
718 |
26 Dec 06 |
jari |
451 |
return gsl_ran_poisson(rng_->rng(), m_); |
718 |
26 Dec 06 |
jari |
452 |
} |
718 |
26 Dec 06 |
jari |
453 |
|
718 |
26 Dec 06 |
jari |
454 |
|
1271 |
09 Apr 08 |
peter |
455 |
unsigned long Poisson::operator()(const double m) const |
718 |
26 Dec 06 |
jari |
456 |
{ |
718 |
26 Dec 06 |
jari |
457 |
return gsl_ran_poisson(rng_->rng(), m); |
718 |
26 Dec 06 |
jari |
458 |
} |
718 |
26 Dec 06 |
jari |
459 |
|
4147 |
28 Feb 22 |
peter |
460 |
|
4147 |
28 Feb 22 |
peter |
461 |
NegativeBinomial::NegativeBinomial(double p, double r) |
4147 |
28 Feb 22 |
peter |
462 |
: p_(p), r_(r) |
4147 |
28 Feb 22 |
peter |
463 |
{ |
4147 |
28 Feb 22 |
peter |
464 |
} |
4147 |
28 Feb 22 |
peter |
465 |
|
4147 |
28 Feb 22 |
peter |
466 |
unsigned long NegativeBinomial::operator()(void) const |
4147 |
28 Feb 22 |
peter |
467 |
{ |
4147 |
28 Feb 22 |
peter |
468 |
return gsl_ran_negative_binomial(rng_->rng(), p_, r_); |
4147 |
28 Feb 22 |
peter |
469 |
} |
4147 |
28 Feb 22 |
peter |
470 |
|
4147 |
28 Feb 22 |
peter |
471 |
|
4147 |
28 Feb 22 |
peter |
472 |
unsigned long NegativeBinomial::operator()(double p, double r) const |
4147 |
28 Feb 22 |
peter |
473 |
{ |
4147 |
28 Feb 22 |
peter |
474 |
return gsl_ran_negative_binomial(rng_->rng(), p, r); |
4147 |
28 Feb 22 |
peter |
475 |
} |
4147 |
28 Feb 22 |
peter |
476 |
|
706 |
19 Dec 06 |
jari |
// --------------------- Continuous distribtuions --------------------- |
706 |
19 Dec 06 |
jari |
478 |
|
706 |
19 Dec 06 |
jari |
479 |
Continuous::Continuous(void) |
706 |
19 Dec 06 |
jari |
480 |
: rng_(RNG::instance()) |
706 |
19 Dec 06 |
jari |
481 |
{ |
706 |
19 Dec 06 |
jari |
482 |
} |
706 |
19 Dec 06 |
jari |
483 |
|
706 |
19 Dec 06 |
jari |
484 |
|
706 |
19 Dec 06 |
jari |
485 |
Continuous::~Continuous(void) |
706 |
19 Dec 06 |
jari |
486 |
{ |
706 |
19 Dec 06 |
jari |
487 |
} |
706 |
19 Dec 06 |
jari |
488 |
|
706 |
19 Dec 06 |
jari |
489 |
|
1271 |
09 Apr 08 |
peter |
490 |
void Continuous::seed(unsigned long s) const |
718 |
26 Dec 06 |
jari |
491 |
{ |
718 |
26 Dec 06 |
jari |
492 |
rng_->seed(s); |
718 |
26 Dec 06 |
jari |
493 |
} |
718 |
26 Dec 06 |
jari |
494 |
|
718 |
26 Dec 06 |
jari |
495 |
|
2578 |
04 Oct 11 |
peter |
496 |
unsigned long Continuous::seed_from_devurandom(void) |
2578 |
04 Oct 11 |
peter |
497 |
{ |
2578 |
04 Oct 11 |
peter |
498 |
return rng_->seed_from_devurandom(); |
2578 |
04 Oct 11 |
peter |
499 |
} |
2578 |
04 Oct 11 |
peter |
500 |
|
2578 |
04 Oct 11 |
peter |
501 |
|
706 |
19 Dec 06 |
jari |
502 |
ContinuousGeneral::ContinuousGeneral(const statistics::Histogram& hist) |
706 |
19 Dec 06 |
jari |
503 |
: discrete_(DiscreteGeneral(hist)), hist_(hist) |
706 |
19 Dec 06 |
jari |
504 |
{ |
706 |
19 Dec 06 |
jari |
505 |
} |
706 |
19 Dec 06 |
jari |
506 |
|
706 |
19 Dec 06 |
jari |
507 |
|
718 |
26 Dec 06 |
jari |
508 |
double ContinuousGeneral::operator()(void) const |
718 |
26 Dec 06 |
jari |
509 |
{ |
718 |
26 Dec 06 |
jari |
510 |
return hist_.observation_value(discrete_())+(u_()-0.5)*hist_.spacing(); |
718 |
26 Dec 06 |
jari |
511 |
} |
718 |
26 Dec 06 |
jari |
512 |
|
718 |
26 Dec 06 |
jari |
513 |
double ContinuousUniform::operator()(void) const |
718 |
26 Dec 06 |
jari |
514 |
{ |
718 |
26 Dec 06 |
jari |
515 |
return gsl_rng_uniform(rng_->rng()); |
718 |
26 Dec 06 |
jari |
516 |
} |
718 |
26 Dec 06 |
jari |
517 |
|
718 |
26 Dec 06 |
jari |
518 |
|
706 |
19 Dec 06 |
jari |
519 |
Exponential::Exponential(const double m) |
706 |
19 Dec 06 |
jari |
520 |
: m_(m) |
706 |
19 Dec 06 |
jari |
521 |
{ |
706 |
19 Dec 06 |
jari |
522 |
} |
706 |
19 Dec 06 |
jari |
523 |
|
706 |
19 Dec 06 |
jari |
524 |
|
718 |
26 Dec 06 |
jari |
525 |
double Exponential::operator()(void) const |
718 |
26 Dec 06 |
jari |
526 |
{ |
718 |
26 Dec 06 |
jari |
527 |
return gsl_ran_exponential(rng_->rng(), m_); |
718 |
26 Dec 06 |
jari |
528 |
} |
718 |
26 Dec 06 |
jari |
529 |
|
718 |
26 Dec 06 |
jari |
530 |
|
718 |
26 Dec 06 |
jari |
531 |
double Exponential::operator()(const double m) const |
718 |
26 Dec 06 |
jari |
532 |
{ |
718 |
26 Dec 06 |
jari |
533 |
return gsl_ran_exponential(rng_->rng(), m); |
718 |
26 Dec 06 |
jari |
534 |
} |
718 |
26 Dec 06 |
jari |
535 |
|
718 |
26 Dec 06 |
jari |
536 |
|
706 |
19 Dec 06 |
jari |
537 |
Gaussian::Gaussian(const double s, const double m) |
706 |
19 Dec 06 |
jari |
538 |
: m_(m), s_(s) |
706 |
19 Dec 06 |
jari |
539 |
{ |
706 |
19 Dec 06 |
jari |
540 |
} |
706 |
19 Dec 06 |
jari |
541 |
|
718 |
26 Dec 06 |
jari |
542 |
|
718 |
26 Dec 06 |
jari |
543 |
double Gaussian::operator()(void) const |
718 |
26 Dec 06 |
jari |
544 |
{ |
718 |
26 Dec 06 |
jari |
545 |
return gsl_ran_gaussian(rng_->rng(), s_)+m_; |
718 |
26 Dec 06 |
jari |
546 |
} |
718 |
26 Dec 06 |
jari |
547 |
|
718 |
26 Dec 06 |
jari |
548 |
|
718 |
26 Dec 06 |
jari |
549 |
double Gaussian::operator()(const double s) const |
718 |
26 Dec 06 |
jari |
550 |
{ |
718 |
26 Dec 06 |
jari |
551 |
return gsl_ran_gaussian(rng_->rng(), s); |
718 |
26 Dec 06 |
jari |
552 |
} |
718 |
26 Dec 06 |
jari |
553 |
|
718 |
26 Dec 06 |
jari |
554 |
|
718 |
26 Dec 06 |
jari |
555 |
double Gaussian::operator()(const double s, const double m) const |
718 |
26 Dec 06 |
jari |
556 |
{ |
718 |
26 Dec 06 |
jari |
557 |
return gsl_ran_gaussian(rng_->rng(), s)+m; |
718 |
26 Dec 06 |
jari |
558 |
} |
718 |
26 Dec 06 |
jari |
559 |
|
4281 |
29 Jan 23 |
peter |
560 |
|
4281 |
29 Jan 23 |
peter |
561 |
MultivariateGaussian::MultivariateGaussian(const utility::VectorBase& m, |
4281 |
29 Jan 23 |
peter |
562 |
const utility::CholeskyDecomposer& C) |
4281 |
29 Jan 23 |
peter |
563 |
: mean_(m), cholesky_decomposer_(C) |
4281 |
29 Jan 23 |
peter |
564 |
{} |
4281 |
29 Jan 23 |
peter |
565 |
|
4281 |
29 Jan 23 |
peter |
566 |
|
4281 |
29 Jan 23 |
peter |
567 |
MultivariateGaussian::MultivariateGaussian(const utility::VectorBase& m, |
4281 |
29 Jan 23 |
peter |
568 |
utility::CholeskyDecomposer&& C) |
4281 |
29 Jan 23 |
peter |
569 |
: mean_(m), cholesky_decomposer_(std::move(C)) |
4281 |
29 Jan 23 |
peter |
570 |
{} |
4281 |
29 Jan 23 |
peter |
571 |
|
4281 |
29 Jan 23 |
peter |
572 |
|
4281 |
29 Jan 23 |
peter |
573 |
void MultivariateGaussian::operator()(utility::VectorMutable& x) |
4281 |
29 Jan 23 |
peter |
574 |
{ |
4281 |
29 Jan 23 |
peter |
575 |
(*this)(mean_, cholesky_decomposer_, x); |
4281 |
29 Jan 23 |
peter |
576 |
} |
4281 |
29 Jan 23 |
peter |
577 |
|
4281 |
29 Jan 23 |
peter |
578 |
|
4281 |
29 Jan 23 |
peter |
579 |
void MultivariateGaussian::operator()(const utility::VectorBase& m, |
4281 |
29 Jan 23 |
peter |
580 |
const utility::CholeskyDecomposer& C, |
4281 |
29 Jan 23 |
peter |
581 |
utility::VectorMutable& x) |
4281 |
29 Jan 23 |
peter |
582 |
{ |
4281 |
29 Jan 23 |
peter |
// should perhaps be stored as a member variable (in a base class) |
4281 |
29 Jan 23 |
peter |
584 |
RNG* rng = RNG::instance(); |
4281 |
29 Jan 23 |
peter |
585 |
if (int status = gsl_ran_multivariate_gaussian(rng->rng(), |
4281 |
29 Jan 23 |
peter |
586 |
m.gsl_vector_p(), |
4281 |
29 Jan 23 |
peter |
587 |
C.L().gsl_matrix_p(), |
4281 |
29 Jan 23 |
peter |
588 |
x.gsl_vector_p())) |
4281 |
29 Jan 23 |
peter |
589 |
throw utility::GSL_error("MultivariateGaussian failed", status); |
4281 |
29 Jan 23 |
peter |
590 |
} |
4281 |
29 Jan 23 |
peter |
591 |
|
680 |
11 Oct 06 |
jari |
592 |
}}} // of namespace random, yat, and theplu |