00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00028 #ifndef __COCONUT_RANDOM_H__
00029 #define __COCONUT_RANDOM_H__
00030
00031 #include <cmath>
00032 #include <cstdlib>
00033 #include <api_debug.h>
00034 #include <interval.h>
00035 #if defined(COCONUT_WINDOWS)
00036 #include <windows_utils.h>
00037 #endif
00038
00039 namespace coco {
00040
00045 #if defined(COCONUT_WINDOWS)
00046 #define coconut_random rand
00047 #else
00048 #define coconut_random random
00049 #endif
00050
00055 #if defined(COCONUT_WINDOWS)
00056 #define coconut_seed(A) srand(A)
00057 #else
00058 #define coconut_seed(A) srandom(A)
00059 #endif
00060
00063 #define COCONUT_RAND_MAX RAND_MAX
00064
00069 #define COCONUT_RRAND_MIN -1.e08
00070
00074 #define COCONUT_RRAND_MAX +1.e08
00075
00076 #if DEBUG_RANDOM
00077 #define INIT_SEED 1
00078 #else
00079 #define INIT_SEED coconut_random()
00080 #endif
00081
00085 #define coconut_init_random() coconut_seed(INIT_SEED)
00086
00090 typedef long int rand_t;
00091
00095 inline double d_random()
00096 {
00097 #if (DEBUG_RANDOM > 3)
00098 double help = (coconut_random()+0.)/(COCONUT_RAND_MAX+0.);
00099 std::cout << "Random generated: " << help << std::endl;
00100 return help;
00101 #else
00102 return (coconut_random()+0.)/(COCONUT_RAND_MAX+0.);
00103 #endif
00104 }
00105
00110 #define COCONUT_RRAND_MIN_BETA 0.01
00111
00115 #define COCONUT_RRAND_MIN_ALPHA 0.5
00116
00120 #define COCONUT_RRAND_MAX_ALPHA 0.99
00121
00122
00123 inline double r_random_h_eval(double t, double b, double a)
00124 {
00125 double ret;
00126 if (t>b)
00127 ret = (-a*b + t) / ((1./a-2.)*b + t);
00128 else if (t<-b)
00129 ret = (a*b + t) / ((1./a-2.)*b - t);
00130 else
00131 ret = a*t/b;
00132 return ret;
00133 }
00134
00135
00136 inline double r_random_hinv_eval(double x, double b, double a)
00137 {
00138 double ret;
00139 if (x>a)
00140 ret = b*(a + (1./a-2.)*x) / (1-x);
00141 else if (x<-a)
00142 ret = b*(-a + (1./a-2.)*x) / (1+x);
00143 else
00144 ret = b*x/a;
00145 return ret;
00146 }
00147
00168 inline double r_random(double l, double u, double beta = 10.0,
00169 double alpha = 0.9)
00170 {
00171 l = std::max(l,COCONUT_RRAND_MIN);
00172 u = std::min(u,COCONUT_RRAND_MAX);
00173 if(l == u) return l;
00174
00175
00176 alpha = std::max(alpha,COCONUT_RRAND_MIN_ALPHA);
00177 alpha = std::min(alpha,COCONUT_RRAND_MAX_ALPHA);
00178 beta = std::max(beta,COCONUT_RRAND_MIN_BETA);
00179
00180
00181 double hl = r_random_h_eval(l,beta,alpha);
00182 double hu = r_random_h_eval(u,beta,alpha);
00183
00184
00185 double r = d_random()*(hu-hl) + hl;
00186
00187
00188 double result = r_random_hinv_eval(r,beta,alpha);
00189
00190
00191 result = std::max(result,l);
00192 result = std::min(result,u);
00193
00194 #if (DEBUG_RANDOM > 3)
00195 std::cout << "r_random: " << l << ", " << u << ", " << rndnum << std::endl;
00196 std::cout << "r_random: result: " << result << std::endl;
00197 #endif
00198 return result;
00199 }
00200
00208 inline double r_random(const interval& _i, double beta = 10.0,
00209 double alpha = 0.9)
00210 {
00211 return r_random(_i.inf(), _i.sup(), beta, alpha);
00212 }
00213
00219 inline interval i_random(double l, double r, double beta = 10.0,
00220 double alpha = 0.9)
00221 {
00222 double d(r_random(l,r,beta,alpha)), e(r_random(l,r,beta,alpha));
00223 return interval(std::min(d,e),std::max(d,e));
00224 }
00225
00231 inline interval i_random(const interval& _i, double beta = 10.0,
00232 double alpha = 0.9)
00233 {
00234 return i_random(_i.inf(), _i.sup(), beta, alpha);
00235 }
00236
00240 inline interval i_random()
00241 {
00242 return i_random(0., 1., true);
00243 }
00244
00249 struct coconut_random_f
00250 {
00251 double beta;
00252 double alpha;
00253
00254 interval operator()(const interval& i) const
00255 { return i_random(i, beta, alpha); }
00256
00257 double operator()(double l, double u) const
00258 { return r_random(l, u, beta, alpha); }
00259
00260 double operator()(double u) const
00261 { return r_random(0., u, beta, alpha); }
00262
00263 double operator()() const
00264 { return d_random(); }
00265
00266 int operator()(int n) const
00267 { double r(d_random()); return (int) lrint(floor(r*n)); }
00268
00269 int operator()(long int n) const
00270 { double r(d_random()); return (int) lrint(floor(r*n)); }
00271
00272 size_t operator()(size_t n) const
00273 { double r(d_random()); return (size_t) lrint(floor(r*n)); }
00274
00275 coconut_random_f(double _b = 10.0, double _a = 0.9) : beta(_b), alpha(_a) {}
00276 };
00277
00278 }
00279
00280 #endif