diff options
| author | Bertrand <bertrand.horel@gmail.com> | 2016-01-31 22:03:37 +0000 |
|---|---|---|
| committer | Bertrand <bertrand.horel@gmail.com> | 2016-01-31 22:03:37 +0000 |
| commit | fd4237e52d643063f183564a9f5b0c6bdf0bc95a (patch) | |
| tree | c2327afa9cd742135b1461d0c2c9223cc9e2e1fb | |
| parent | a8423ae1e0321197960fe832a31d5aba76428a67 (diff) | |
| download | projet_C++-fd4237e52d643063f183564a9f5b0c6bdf0bc95a.tar.gz | |
premiers fichiers
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | mt19937.c | 229 | ||||
| -rw-r--r-- | mt19937.h | 23 | ||||
| -rw-r--r-- | var_alea.hpp | 111 |
4 files changed, 373 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6477798 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +CXX=g++ +CC=gcc +RM = rm +CXXFLAGS=-O3 + +test: test.o mt19937.o + $(CXX) $^ -o $@ + +clean: + -$(RM) -f *.o test diff --git a/mt19937.c b/mt19937.c new file mode 100644 index 0000000..94fccad --- /dev/null +++ b/mt19937.c @@ -0,0 +1,229 @@ +/* + A C-program for MT19937, with initialization improved 2002/2/10. + Coded by Takuji Nishimura and Makoto Matsumoto. + This is a faster version by taking Shawn Cokus's optimization, + Matthe Bellew's simplification, Isaku Wada's real version. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.keio.ac.jp/matumoto/emt.html + email: matumoto@math.keio.ac.jp +*/ + +#include "mt19937.h" + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UMASK 0x80000000UL /* most significant w-r bits */ +#define LMASK 0x7fffffffUL /* least significant r bits */ +#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) ) +#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL)) + +static unsigned long state[N]; /* the array for the state vector */ +static int left = 1; +static int initf = 0; +static unsigned long *next; + +/* initializes state[N] with a seed */ +void init_genrand(unsigned long s) +{ + int j; + state[0]= s & 0xffffffffUL; + for (j=1; j<N; j++) { + state[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array state[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + state[j] &= 0xffffffffUL; /* for >32 bit machines */ + } + left = 1; initf = 1; +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +void init_by_array(unsigned long init_key[], unsigned long key_length) +{ + unsigned int i, j, k; + init_genrand(19650218UL); + i=1; j=0; + k = (N>key_length ? N : key_length); + for (; k; k--) { + state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1664525UL)) + + init_key[j] + j; /* non linear */ + state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; j++; + if (i>=N) { state[0] = state[N-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=N-1; k; k--) { + state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL)) + - i; /* non linear */ + state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + if (i>=N) { state[0] = state[N-1]; i=1; } + } + + state[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ + left = 1; initf = 1; +} + +static void next_state(void) +{ + unsigned long *p=state; + int j; + + /* if init_genrand() has not been called, */ + /* a default initial seed is used */ + if (initf==0) init_genrand(5489UL); + + left = N; + next = state; + + for (j=N-M+1; --j; p++) + *p = p[M] ^ TWIST(p[0], p[1]); + + for (j=M; --j; p++) + *p = p[M-N] ^ TWIST(p[0], p[1]); + + *p = p[M-N] ^ TWIST(p[0], state[0]); +} + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void) +{ + unsigned long y; + + if (--left == 0) next_state(); + y = *next++; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +/* generates a random number on [0,0x7fffffff]-interval */ +long genrand_int31(void) +{ + unsigned long y; + + if (--left == 0) next_state(); + y = *next++; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return (long)(y>>1); +} + +/* generates a random number on [0,1]-real-interval */ +double genrand_real1(void) +{ + unsigned long y; + + if (--left == 0) next_state(); + y = *next++; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return (double)y * (1.0/4294967295.0); + /* divided by 2^32-1 */ +} + +/* generates a random number on [0,1)-real-interval */ +double genrand_real2(void) +{ + unsigned long y; + + if (--left == 0) next_state(); + y = *next++; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return (double)y * (1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on (0,1)-real-interval */ +double genrand_real3(void) +{ + unsigned long y; + + if (--left == 0) next_state(); + y = *next++; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return ((double)y + 0.5) * (1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on (0,1]-real-interval */ +double genrand_real4(void) +{ + return 1.-genrand_real2(); +} + +/* generates a random number on [0,1) with 53-bit resolution*/ +double genrand_res53(void) +{ + unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; + return(a*67108864.0+b)*(1.0/9007199254740992.0); +} +/* These real versions are due to Isaku Wada, 2002/01/09 added */ + diff --git a/mt19937.h b/mt19937.h new file mode 100644 index 0000000..6291cda --- /dev/null +++ b/mt19937.h @@ -0,0 +1,23 @@ +void init_genrand(unsigned long s); + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void); + +/* generates a random number on [0,0x7fffffff]-interval */ +long genrand_int31(void); + +/* generates a random number on [0,1]-real-interval */ +double genrand_real1(void); + +/* generates a random number on [0,1)-real-interval */ +double genrand_real2(void); + +/* generates a random number on (0,1)-real-interval */ +double genrand_real3(void); + +/* generates a random number on (0,1]-real-interval */ +double genrand_real4(void); + +/* generates a random number on [0,1) with 53-bit resolution*/ +double genrand_res53(void); + diff --git a/var_alea.hpp b/var_alea.hpp new file mode 100644 index 0000000..de37c1d --- /dev/null +++ b/var_alea.hpp @@ -0,0 +1,111 @@ +#ifndef VAR_ALEA_HPP +#define VAR_ALEA_HPP +#include <cmath> +#include "mt19937.h" + +void init_alea(unsigned seed = static_cast<unsigned>(std::time(0))) { + init_genrand(seed); +}; + +template <typename T> +struct var_alea { + typedef T result_type; + var_alea() : value(0) {}; + var_alea(T value) : value(value) {}; + virtual ~var_alea() {}; + virtual T operator()() = 0; + T current() const { return value; }; + protected: + T value; +}; + +struct uniform : public var_alea<double> +{ + uniform(double left = 0, double right = 1) + : left(left), size(right-left), genrand(genrand_real3) {}; + double operator()() { + return value = left + size * genrand(); + }; + private: + double left, size; + double (*genrand)(void); +}; + +struct expo : public var_alea<double> +{ + expo(double lambda) : inv_lambda(1./lambda), U(0,1) {}; + double operator()() { + return value = - inv_lambda * log(U()); + }; + private: + double inv_lambda; + uniform U; +}; + +struct gaussian : public var_alea<double> +{ + gaussian(double mean = 0, double std = 1) + : mean(mean), std(std), flag(true), unif(-1,1) {}; + double operator()() { + flag = !flag; + if (!flag) { + do { + U = unif(); V = unif(); + R2 = U*U + V*V; + } while (R2 > 1); + rac = sqrt(-2 * log(R2) / R2); + return value = mean + std * U * rac; + } else + return value = mean + std * V * rac; + }; + private: + double mean, std, U, V, R2, rac; + uniform unif; + bool flag; +}; + +struct chi_deux : public var_alea<double> +{ + chi_deux(int n) : n(n), G(0,1) {}; + double operator()() { + value = 0; + for (int j = 0; j < n; j++) value += G()*G.current(); + return value; + }; + private: + int n; + gaussian G; +}; + +struct inverse_gaussian : public var_alea<double> +{ + inverse_gaussian(double lambda, double mu) + : lambda(lambda), mu(mu), Y(1), U(0,1) {}; + double operator()() { + double Z = mu + 0.5*mu*mu/lambda*Y(); + double rac = sqrt(Z*Z - mu*mu); + return value = (U() < mu/(mu+Z+rac)) ? Z+rac : Z-rac; + }; + private: + double lambda, mu; + chi_deux Y; + uniform U; +}; + +struct normal_inverse_gaussian : public var_alea<double> +{ + normal_inverse_gaussian(double alpha, double beta, + double mu, double delta) + : alpha(alpha), beta(beta), mu(mu), delta(delta), G(0,1), + Y(delta/sqrt(alpha*alpha-beta*beta), delta*delta) {}; + double operator()() { + double y_ = Y(); + return value = mu + beta*y_ * sqrt(y_) * G(); + }; + private: + double alpha, beta, mu, delta; + gaussian G; + inverse_gaussian Y; +}; + +#endif |
