亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: 我實(shí)現(xiàn)一個(gè)隨機(jī)數(shù)生成器。 [打印本頁(yè)]

作者: emacsnw    時(shí)間: 2007-04-19 08:06
標(biāo)題: 我實(shí)現(xiàn)一個(gè)隨機(jī)數(shù)生成器。
我做機(jī)器學(xué)習(xí)方面的研究,因此非常需要高質(zhì)量的(偽)隨機(jī)數(shù)生成器,下面這個(gè)是我參考"Numerical Recipes in C (NRIC)"和一些其它資料實(shí)現(xiàn)的一個(gè)C++ Wrapper for random number generator. 當(dāng)然網(wǎng)上有很多類似的代碼,不過(guò)我覺(jué)得這個(gè)應(yīng)付常見(jiàn)的需求足夠了,至少基本滿足自己的需求。
它特點(diǎn)就是簡(jiǎn)單高效,但是隨機(jī)數(shù)質(zhì)量高,基于48位偽隨機(jī)數(shù)生成引擎,實(shí)現(xiàn)了比較常見(jiàn)的binomial, cauchy, exponential, gamma(erlang), gaussian, uniform integers, uniform, poisson, 還有一個(gè)數(shù)學(xué)函數(shù)log(Gamma(x))。
因?yàn)閰⒖剂艘恍┢渌Y料,我不知道該怎么發(fā)布這個(gè)東西,不過(guò)我有NRIC的正版授權(quán),因此自己用應(yīng)該是完全合法的。
使用的時(shí)候比較簡(jiǎn)單,比如需要生成200個(gè)正態(tài)分布的隨機(jī)數(shù):

  1. double x[200];
  2. Rand engine; // default to use current time as random seed
  3. for (int i = 0; i < 200; ++i)
  4.     x[i] = engine.gasdev();
復(fù)制代碼


// rand.h

  1. // -*- C++ -*-
  2. #ifndef RAND_H
  3. #define RAND_H

  4. #include <cmath>
  5. #include <cstdlib>

  6. class Rand {
  7.     static const double PI;
  8.     unsigned short xsubi[3];
  9.     void set_seed(long seed = 0);

  10. public:
  11.     Rand(long seed = 0) {set_seed(seed);}
  12.     static double log_gamma(double xx); // returns log(Gamma(xx))

  13.     // supported random deviates
  14.     double bnldev(double pp, int n); // binomial
  15.     double caudev();                 // cauchy
  16.     double caudev(double location, double scale);
  17.     double expdev();                 // exponential
  18.     double expdev(double intensity);
  19.     double gamdev(int shape);        // gamma(erlang)
  20.     double gamdev(int shape, double intensity);
  21.     double gasdev();                 // gaussian
  22.     double gasdev(double mean, double std);
  23.     int    intdev(int end_point);    // uniform integeters [0, end_point)
  24.     int    intdev(int start_point, int end_point);
  25.     double poidev(double mean);      // poisson
  26.     double unidev();                 // uniform [0, 1)
  27.     double unidev(double start_point, double end_point);
  28. };

  29. inline double Rand::caudev()
  30. {
  31.     return ::tan(PI * (unidev() - 0.5));
  32. }

  33. inline double Rand::caudev(double location, double scale)
  34. {
  35.     return location + scale * caudev();
  36. }

  37. inline double Rand::expdev(double intensity)
  38. {
  39.     return expdev() / intensity;
  40. }

  41. inline double Rand::gamdev(int shape, double intensity)
  42. {
  43.     return gamdev(shape) / intensity;
  44. }

  45. inline double Rand::gasdev(double mean, double std)
  46. {
  47.     return mean + std * gasdev();
  48. }

  49. inline int Rand::intdev(int end_point)
  50. {
  51.     return static_cast<int>(::floor(unidev() * end_point));
  52. }

  53. inline int Rand::intdev(int start_point, int end_point)
  54. {
  55.     return start_point + intdev(end_point - start_point);
  56. }

  57. inline double Rand::unidev()
  58. {
  59.     return ::erand48(xsubi);
  60. }

  61. inline double Rand::unidev(double start_point, double end_point)
  62. {
  63.     return start_point + (end_point - start_point) * unidev();
  64. }

  65. #endif
復(fù)制代碼


// rand.cc

  1. #include "rand.h"
  2. #include <ctime>

  3. const double Rand::PI = 3.14159265358979324;

  4. void Rand::set_seed(long seed)
  5. {
  6.     long rand_seed = seed;

  7.     if (seed == 0)
  8.         rand_seed = static_cast<long>(::time(0));
  9.     for (int i = 0; i < 3; ++i) {
  10.         xsubi[i] = rand_seed & 0xFFFF;
  11.         rand_seed >>= 16;
  12.     }
  13.     // the first few numbers are somewhat related with the seed
  14.     erand48(xsubi);
  15.     erand48(xsubi);
  16.     erand48(xsubi);
  17.     erand48(xsubi);
  18. }

  19. double Rand::log_gamma(double xx)
  20. {
  21.     double x, y, tmp, ser;
  22.     static double cof[6] = {76.18009172947146,
  23.                             -86.50532032941677,
  24.                             24.01409824083091,
  25.                             -1.231739572450155,
  26.                             0.1208650973866179e-2,
  27.                             -0.5395239384953e-5};
  28.     y = x = xx;
  29.     tmp = x + 5.5;
  30.     tmp -= (x + 0.5) * ::log(tmp);
  31.     ser = 1.000000000190015;
  32.     for (int j = 0; j <= 5; ++j)
  33.         ser += cof[j] / ++y;
  34.     return -tmp + ::log(2.5066282746310005 * ser / x);
  35. }

  36. double Rand::bnldev(double pp, int n)
  37. {
  38.     int j;
  39.     static int nold = -1;
  40.     double am, em, g, angle, p, bnl, sq, t, y;
  41.     static double pold = -1.0, pc, plog, pclog, en, oldg;

  42.     p = (pp <= 0.5 ? pp : 1.0 - pp);
  43.     am = n * p;
  44.     if (n < 25) {
  45.         bnl = 0.0;
  46.         for (j = 1; j <= n; ++j)
  47.             if (unidev() < p)
  48.                 ++bnl;
  49.     } else if (am < 1.0) {
  50.         g = ::exp(-am);
  51.         t = 1.0;
  52.         for (j = 0; j <= n; ++j) {
  53.             t *= unidev();
  54.             if (t < g)
  55.                 break;
  56.         }
  57.         bnl = (j <= n ? j : n);
  58.     } else {
  59.         if (n != nold) {
  60.             en = n;
  61.             oldg = log_gamma(en + 1.0);
  62.             nold = n;
  63.         } if (p != pold) {
  64.             pc = 1.0 - p;
  65.             plog = ::log(p);
  66.             pclog = ::log(pc);
  67.             pold = p;
  68.         }
  69.         sq = ::sqrt(2.0 * am * pc);
  70.         do {
  71.             do {
  72.                 angle = PI * unidev();
  73.                 y = ::tan(angle);
  74.                 em = sq * y + am;
  75.             } while (em < 0.0 || em >= (en + 1.0));
  76.             em = ::floor(em);
  77.             t = 1.2 * sq * (1.0 + y * y) *
  78.                 ::exp(oldg - log_gamma(em + 1.0) -
  79.                       log_gamma(en - em + 1.0) +
  80.                       em * plog + (en - em) * pclog);
  81.         } while (unidev() > t);
  82.         bnl = em;
  83.     }
  84.     if (p != pp)
  85.         bnl = n - bnl;
  86.     return bnl;
  87. }

  88. double Rand::expdev()
  89. {
  90.     double dum;

  91.     do {
  92.         dum = unidev();
  93.     } while (dum == 0.0);
  94.     return -::log(dum);
  95. }

  96. double Rand::gamdev(int shape)
  97. {
  98.     double am, e, s, v1, v2, x, y;

  99.     if (shape < 6) {
  100.         x = 1.0;
  101.         for (int j = 1; j <= shape; ++j)
  102.             x *= unidev();
  103.         x = -::log(x);
  104.     } else {
  105.         do {
  106.             do {
  107.                 do {
  108.                     v1 = unidev();
  109.                     v2 = 2.0 * unidev() - 1.0;
  110.                 } while (v1 * v1 + v2 * v2 > 1.0);
  111.                 y = v2 / v1;
  112.                 am = shape - 1;
  113.                 s = sqrt(2.0 * am + 1.0);
  114.                 x = s * y + am;
  115.             } while (x <= 0.0);
  116.             e = (1.0 + y * y) * ::exp(am * ::log(x / am) - s * y);
  117.         } while (unidev() > e);
  118.     }
  119.     return x;
  120. }

  121. double Rand::gasdev()
  122. {
  123.     static int iset = 0;
  124.     static double gset;
  125.     double fac, rsq, v1, v2;

  126.     if (iset == 0) {
  127.         do {
  128.             v1 = 2.0 * unidev() - 1.0;
  129.             v2 = 2.0 * unidev() - 1.0;
  130.             rsq = v1 * v1 + v2 * v2;
  131.         } while (rsq >= 1.0 || rsq == 0.0);
  132.         fac = sqrt(-2.0 * ::log(rsq) / rsq);
  133.         gset = v1 * fac;
  134.         iset = 1;
  135.         return v2 * fac;
  136.     }
  137.     iset = 0;
  138.     return gset;
  139. }

  140. double Rand::poidev(double mean)
  141. {
  142.     static double sq, alxm, g, oldm = -1.0;
  143.     double em, t, y;

  144.     if (mean < 12.0) {
  145.         if (mean != oldm) {
  146.             oldm = mean;
  147.             g = ::exp(-mean);
  148.         }
  149.         em = -1;
  150.         t = 1.0;
  151.         do {
  152.             ++em;
  153.             t *= unidev();
  154.         } while (t > g);
  155.     } else {
  156.         if (mean != oldm) {
  157.             oldm = mean;
  158.             sq = sqrt(2.0 * mean);
  159.             alxm = ::log(mean);
  160.             g = mean * alxm - log_gamma(mean + 1.0);
  161.         }
  162.         do {
  163.             do {
  164.                 y = ::tan(PI * unidev());
  165.                 em = sq * y + mean;
  166.             } while (em < 0.0);
  167.             em = ::floor(em);
  168.             t = 0.9 * (1.0 + y * y) *
  169.                 ::exp(em * alxm - log_gamma(em + 1.0) - g);
  170.         } while (unidev() > t);
  171.     }
  172.     return em;
  173. }
復(fù)制代碼





歡迎光臨 Chinaunix (http://www.72891.cn/) Powered by Discuz! X3.2