aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBertrand <bertrand.horel@gmail.com>2016-01-31 22:03:37 +0000
committerBertrand <bertrand.horel@gmail.com>2016-01-31 22:03:37 +0000
commitfd4237e52d643063f183564a9f5b0c6bdf0bc95a (patch)
treec2327afa9cd742135b1461d0c2c9223cc9e2e1fb
parenta8423ae1e0321197960fe832a31d5aba76428a67 (diff)
downloadprojet_C++-fd4237e52d643063f183564a9f5b0c6bdf0bc95a.tar.gz
premiers fichiers
-rw-r--r--Makefile10
-rw-r--r--mt19937.c229
-rw-r--r--mt19937.h23
-rw-r--r--var_alea.hpp111
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