STK++ 0.9.13
STK_RandBase.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright (C) 2004-2016 Serge Iovleff, Université Lille 1, Inria
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this program; if not, write to the
16 Free Software Foundation, Inc.,
17 59 Temple Place,
18 Suite 330,
19 Boston, MA 02111-1307
20 USA
21
22 Contact : S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
23*/
24
25/* Project: stkpp::STatistiK
26 * Purpose: Main pseudo-random uniform, Gaussian and exponential generators.
27 * Author: Serge Iovleff, S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
28 **/
29
36#ifndef STK_RANDBASE_H
37#define STK_RANDBASE_H
38
39#ifdef IS_RTKPP_LIB /* is rtkpp lib */
40
41#include <R_ext/Random.h>
42#include <Rmath.h>
43#include <Rcpp/sugar/undoRmath.h>
44
45#include <STKernel.h>
46
47namespace STK
48{
52class RandBase
53{
54 public:
56 inline RandBase(){}
58 inline ~RandBase(){}
65 inline Real randUnif()
66 { GetRNGstate();
67 Real s = Rf_runif(0, 1);
68 PutRNGstate();
69 return s;
70 }
72 inline Real operator()() { return randUnif(); }
80 inline Real randGauss( Real const& mu = 0, Real const& sigma = 1)
81 { GetRNGstate();
82 Real s = Rf_rnorm(mu, sigma);
83 PutRNGstate();
84 return s;
85 }
87 inline Real rand( Real const& n )
88 { GetRNGstate();
89 Real s = Rf_runif(0, n);
90 PutRNGstate();
91 return s;
92 }
94 inline Real randDblExc( Real const& n ) { return rand(n);}
95};
96} // namespace STK
97
98
99
100#else
101
102// MersenneTwister header.
103#include "MersenneTwister.h"
104
105namespace STK
106{
107
131class RandBase: protected MTRand
132{
133 public:
140 RandBase( Real const& glimit = 3.442619855899
141 , Real const& gvol = 9.91256303526217e-3
142 , int gsize = 128
143 );
150 RandBase( int oneSeed
151 , Real const& glimit = 3.442619855899
152 , Real const& gvol = 9.91256303526217e-3
153 , int gsize = 128
154 );
155
162 template< class TContainer1D>
163 RandBase( TContainer1D const& bigSeed
164 , Real const& glimit = 3.442619855899
165 , Real const& gvol = 9.91256303526217e-3
166 , int gsize = 128
167 )
169 {
170 // dimension
171 int first = bigSeed.begin(), size = bigSeed.size();
172 uint32* arraySeed = new uint32[size];
173 // cast int in uint32
174 for (int i=first; i<bigSeed.end(); i++)
175 { arraySeed[i-first] = uint32(bigSeed[i]);}
176 // Re-seeding functions with same behavior as initializers
177 seed(arraySeed, size);
178 delete[] arraySeed;
179 // initialize zigourat method for gaussian random generator
180 gaussInit();
181 }
183 ~RandBase();
192 inline int randDiscreteUnif() { return int(Real(randInt()));}
201 inline Real randUnif() { return Real(randDblExc());}
202
204 inline Real operator()() { return (Real)MTRand::operator()(); }
206 inline Real rand() { return (Real)MTRand::rand(); }
208 inline Real rand( Real const& n ) { return (Real)MTRand::rand((double)n); }
210 inline Real randExc() { return (Real)MTRand::randExc(); }
212 inline Real randExc( Real const& n ) { return (Real)MTRand::randExc((double)n); }
214 inline Real randDblExc() { return (Real)MTRand::randDblExc(); }
216 inline Real randDblExc( Real const& n ) { return (Real)MTRand::randDblExc((double)n); }
217
226 Real randGauss(Real const& mu = 0, Real const& sigma = 1);
234 Real randExp();
235
236 private:
237 /* Gauss parameters. */
241 const int gsize_;
245 Real const gvol_;
250 Real *kn, *wn, *fn;
252 void gaussInit();
253};
254
255
256/* Initialize with a simple int seed. */
257inline RandBase::RandBase( int oneSeed, Real const& glimit, Real const& gvol, int gsize)
258 : MTRand( (uint32)oneSeed ), gsize_(gsize), glimit_(glimit), gvol_(gvol)
259{ gaussInit();}
260
261/* auto-initialize with /dev/urandom or time() and clock() */
262inline RandBase::RandBase( Real const& glimit, Real const& gvol, int gsize)
263 : MTRand(), gsize_(gsize), glimit_(glimit), gvol_(gvol)
264{ gaussInit();}
265
266/* destructor. */
268{
269 delete [] kn;
270 delete [] wn;
271 delete [] fn;
272}
273
274/* Pseudo-random gaussian generator.
275 * \f[ f(x) = \frac{1}{\sqrt{2\pi}}
276 * \exp\left\{-\frac{x^2}{2}\right\}
277 * \f]
278 * Return a real number from a normal (Gaussian) normalized
279 * distribution.
280**/
281inline Real RandBase::randGauss(Real const& mu, Real const& sigma)
282{
283 while(1)
284 {
285 // uniforms number
286 Real u = 2.0 * randUnif() - 1.0;
287 // random box
288 uint32 i = randInt() & 0x7F; //
289 // squeeze step : try the rectangular boxes
290 if (std::abs(u) < wn[i]) return mu + sigma * u * kn[i];
291 // bottom box: we have to sample from the tail
292 if (i == 0)
293 {
294 Real x;
295 // loop
296 do { x = randExp() / glimit_;}
297 while ( 2.0 * randExp() < x * x);
298 // result sign(u) * (x+dr)
299 return mu + sigma * sign(u, x+glimit_);
300 }
301 else // other box
302 { // x : result, f1 : intermediary result
303 Real x = u * kn[i], f1 = fn[i+1];
304 // reject step : is this a sample from the wedges ?
305 if ( f1 + randUnif()*( fn[i]*exp(x*x/2.)-f1) < 1.0)
306 { return mu + sigma * x;}
307 }
308 }
309 // avoid warning at compilation
310 return 0.;
311}
312
313/* Pseudo-random exponential generator.
314 * \f[
315 * f(x) = \exp\left\{ -x \right\}
316 * \f]
317 * Return a real number from an exponential normalized
318 * distribution.
319**/
321{ return -Real(std::log(randUnif()));}
322
323/* Initialization (Zigourrat method). */
325{
326 kn = new Real[gsize_+1];
327 wn = new Real[gsize_];
328 fn = new Real[gsize_+1];
329
330 Real f = exp(-0.5 * glimit_ * glimit_);
331 kn[0] = gvol_ / f; // [0] is bottom block: gvol/f(gbound)
332
333 kn[gsize_] = 0;
334 fn[gsize_] = 1;
335
336 kn[1] = glimit_;
337 fn[1] = f;
338
339 for (int i = 2; i < gsize_; ++i)
340 {
341 kn[i] = sqrt(-2 * log(gvol_ / kn[i-1] + f));
342 fn[i] = (f = exp(-0.5 * kn[i] * kn[i]));
343 }
344 for (int i = 0; i < gsize_; ++i)
345 wn[i] = kn[i + 1] / kn[i];
346}
347
348} // namespace STK
349
350#endif
351
352#endif //STK_RANDBASE_H
353
This file include all the header files of the project STKernel.
Generate unsigner 32 bits random number using the Merdsenne Twister Algorithm.
unsigned long uint32
unsigned integer type, at least 32 bits
double randDblExc()
real number in (0,1)
double rand()
real number in [0,1]
uint32 randInt()
integer in [0,2^32-1]
double operator()()
same as rand().
void seed()
Re-seeding functions with same behavior as initializers.
double randExc()
real number in [0,1)
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
class for the Base random generator.
RandBase(TContainer1D const &bigSeed, Real const &glimit=3.442619855899, Real const &gvol=9.91256303526217e-3, int gsize=128)
Initialize with a seed Array.
Real randGauss(Real const &mu=0, Real const &sigma=1)
Pseudo-random gaussian generator of the gaussian probability law:
int randDiscreteUnif()
Pseudo-random int uniform generator.
Real * kn
kn holds coordinates, such that each rectangle has same area.
Real randExc()
real number in [0,1)
Real randExp()
Pseudo-random exponential generator.
Real randUnif()
pseudo-random uniform generator.
Real rand(Real const &n)
real number in [0,n]
Real rand()
real number in [0,1]
Real randExc(Real const &n)
real number in [0,n)
Real const glimit_
limit of the bottom box.
const int gsize_
Number of box for the gaussian ziggourat method.
Real const gvol_
volume of each box and of the remaining tail.
Real randDblExc(Real const &n)
real number in (0,n)
RandBase(Real const &glimit=3.442619855899, Real const &gvol=9.91256303526217e-3, int gsize=128)
Default constructor.
void gaussInit()
Initialization of the Zigourrat method.
~RandBase()
destructor.
Real randDblExc()
real number in (0,1)
Type sign(Type const &x, Type const &y=Type(1))
template sign value sign(x) * y: Type should be an integral type
Definition STK_Misc.h:53
double Real
STK fundamental type of Real values.
The namespace STK is the main domain space of the Statistical ToolKit project.