forked from wuyangf7/OPERA
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstat.cpp
More file actions
78 lines (67 loc) · 1.94 KB
/
stat.cpp
File metadata and controls
78 lines (67 loc) · 1.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//
// stat.cpp
// gctb
//
// Created by Jian Zeng on 14/06/2016.
// Copyright © 2016 Jian Zeng. All rights reserved.
//
#include "stat.hpp"
void Stat::seedEngine(const int seed){
if (seed) {
srand(seed);
engine.seed(seed);
} else {
srand((int)time(NULL));
engine.seed((int)time(NULL));
}
}
float Stat::Normal::sample(const float mean, const float variance){
return mean + snorm()*sqrtf(variance);
}
float Stat::InvChiSq::sample(const float df, const float scale){
//inverse_chi_squared_distribution invchisq(df, scale);
//return boost::math::quantile(invchisq, ranf()); // don't know why this is not correct
gamma_generator sgamma(engine, gamma_distribution(0.5f*df, 1));
return scale/(2.0f*sgamma());
}
double Stat::Gamma::sample(const float shape, const float scale){
gamma_generator sgamma(engine, gamma_distribution(shape, scale));
return sgamma();
}
float Stat::Beta::sample(const float a, const float b){
beta_distribution beta(a,b);
return boost::math::quantile(beta,ranf());
}
unsigned Stat::Bernoulli::sample(const float p){
if (std::isnan(p)) return ranf() < 0.5 ? 1:0;
else return ranf() < p ? 1:0;
}
unsigned Stat::Bernoulli::sample(const VectorXf &p){
float cum = 0;
float rnd = ranf();
long size = p.size();
unsigned ret = 0;
for (unsigned i=0; i<size; ++i) {
if (!std::isnan(p[i])) cum += p[i];
if (rnd < cum) {
ret = i;
break;
}
}
return ret;
}
float Stat::NormalZeroMixture::sample(const float mean, const float variance, const float p){
return bernoulli.sample(p) ? normal.sample(mean, variance) : 0;
}
// Sample Dirichlet
VectorXd Stat::Dirichlet::sample(const int n, const VectorXd &irx){
VectorXd ps(n);
double sx = 0.0;
for (int i = 0; i < n; i++)
{
ps[i] = gamma.sample(irx(i), 1.0);
sx += ps[i];
}
ps = ps / sx;
return ps;
}