亚洲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ù):
double x[200];
Rand engine; // default to use current time as random seed
for (int i = 0; i < 200; ++i)
x[i] = engine.gasdev();
復(fù)制代碼
// rand.h
// -*- C++ -*-
#ifndef RAND_H
#define RAND_H
#include <cmath>
#include <cstdlib>
class Rand {
static const double PI;
unsigned short xsubi[3];
void set_seed(long seed = 0);
public:
Rand(long seed = 0) {set_seed(seed);}
static double log_gamma(double xx); // returns log(Gamma(xx))
// supported random deviates
double bnldev(double pp, int n); // binomial
double caudev(); // cauchy
double caudev(double location, double scale);
double expdev(); // exponential
double expdev(double intensity);
double gamdev(int shape); // gamma(erlang)
double gamdev(int shape, double intensity);
double gasdev(); // gaussian
double gasdev(double mean, double std);
int intdev(int end_point); // uniform integeters [0, end_point)
int intdev(int start_point, int end_point);
double poidev(double mean); // poisson
double unidev(); // uniform [0, 1)
double unidev(double start_point, double end_point);
};
inline double Rand::caudev()
{
return ::tan(PI * (unidev() - 0.5));
}
inline double Rand::caudev(double location, double scale)
{
return location + scale * caudev();
}
inline double Rand::expdev(double intensity)
{
return expdev() / intensity;
}
inline double Rand::gamdev(int shape, double intensity)
{
return gamdev(shape) / intensity;
}
inline double Rand::gasdev(double mean, double std)
{
return mean + std * gasdev();
}
inline int Rand::intdev(int end_point)
{
return static_cast<int>(::floor(unidev() * end_point));
}
inline int Rand::intdev(int start_point, int end_point)
{
return start_point + intdev(end_point - start_point);
}
inline double Rand::unidev()
{
return ::erand48(xsubi);
}
inline double Rand::unidev(double start_point, double end_point)
{
return start_point + (end_point - start_point) * unidev();
}
#endif
復(fù)制代碼
// rand.cc
#include "rand.h"
#include <ctime>
const double Rand::PI = 3.14159265358979324;
void Rand::set_seed(long seed)
{
long rand_seed = seed;
if (seed == 0)
rand_seed = static_cast<long>(::time(0));
for (int i = 0; i < 3; ++i) {
xsubi[i] = rand_seed & 0xFFFF;
rand_seed >>= 16;
}
// the first few numbers are somewhat related with the seed
erand48(xsubi);
erand48(xsubi);
erand48(xsubi);
erand48(xsubi);
}
double Rand::log_gamma(double xx)
{
double x, y, tmp, ser;
static double cof[6] = {76.18009172947146,
-86.50532032941677,
24.01409824083091,
-1.231739572450155,
0.1208650973866179e-2,
-0.5395239384953e-5};
y = x = xx;
tmp = x + 5.5;
tmp -= (x + 0.5) * ::log(tmp);
ser = 1.000000000190015;
for (int j = 0; j <= 5; ++j)
ser += cof[j] / ++y;
return -tmp + ::log(2.5066282746310005 * ser / x);
}
double Rand::bnldev(double pp, int n)
{
int j;
static int nold = -1;
double am, em, g, angle, p, bnl, sq, t, y;
static double pold = -1.0, pc, plog, pclog, en, oldg;
p = (pp <= 0.5 ? pp : 1.0 - pp);
am = n * p;
if (n < 25) {
bnl = 0.0;
for (j = 1; j <= n; ++j)
if (unidev() < p)
++bnl;
} else if (am < 1.0) {
g = ::exp(-am);
t = 1.0;
for (j = 0; j <= n; ++j) {
t *= unidev();
if (t < g)
break;
}
bnl = (j <= n ? j : n);
} else {
if (n != nold) {
en = n;
oldg = log_gamma(en + 1.0);
nold = n;
} if (p != pold) {
pc = 1.0 - p;
plog = ::log(p);
pclog = ::log(pc);
pold = p;
}
sq = ::sqrt(2.0 * am * pc);
do {
do {
angle = PI * unidev();
y = ::tan(angle);
em = sq * y + am;
} while (em < 0.0 || em >= (en + 1.0));
em = ::floor(em);
t = 1.2 * sq * (1.0 + y * y) *
::exp(oldg - log_gamma(em + 1.0) -
log_gamma(en - em + 1.0) +
em * plog + (en - em) * pclog);
} while (unidev() > t);
bnl = em;
}
if (p != pp)
bnl = n - bnl;
return bnl;
}
double Rand::expdev()
{
double dum;
do {
dum = unidev();
} while (dum == 0.0);
return -::log(dum);
}
double Rand::gamdev(int shape)
{
double am, e, s, v1, v2, x, y;
if (shape < 6) {
x = 1.0;
for (int j = 1; j <= shape; ++j)
x *= unidev();
x = -::log(x);
} else {
do {
do {
do {
v1 = unidev();
v2 = 2.0 * unidev() - 1.0;
} while (v1 * v1 + v2 * v2 > 1.0);
y = v2 / v1;
am = shape - 1;
s = sqrt(2.0 * am + 1.0);
x = s * y + am;
} while (x <= 0.0);
e = (1.0 + y * y) * ::exp(am * ::log(x / am) - s * y);
} while (unidev() > e);
}
return x;
}
double Rand::gasdev()
{
static int iset = 0;
static double gset;
double fac, rsq, v1, v2;
if (iset == 0) {
do {
v1 = 2.0 * unidev() - 1.0;
v2 = 2.0 * unidev() - 1.0;
rsq = v1 * v1 + v2 * v2;
} while (rsq >= 1.0 || rsq == 0.0);
fac = sqrt(-2.0 * ::log(rsq) / rsq);
gset = v1 * fac;
iset = 1;
return v2 * fac;
}
iset = 0;
return gset;
}
double Rand::poidev(double mean)
{
static double sq, alxm, g, oldm = -1.0;
double em, t, y;
if (mean < 12.0) {
if (mean != oldm) {
oldm = mean;
g = ::exp(-mean);
}
em = -1;
t = 1.0;
do {
++em;
t *= unidev();
} while (t > g);
} else {
if (mean != oldm) {
oldm = mean;
sq = sqrt(2.0 * mean);
alxm = ::log(mean);
g = mean * alxm - log_gamma(mean + 1.0);
}
do {
do {
y = ::tan(PI * unidev());
em = sq * y + mean;
} while (em < 0.0);
em = ::floor(em);
t = 0.9 * (1.0 + y * y) *
::exp(em * alxm - log_gamma(em + 1.0) - g);
} while (unidev() > t);
}
return em;
}
復(fù)制代碼
歡迎光臨 Chinaunix (http://www.72891.cn/)
Powered by Discuz! X3.2