-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmodels.hpp
145 lines (120 loc) · 5.26 KB
/
models.hpp
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#ifndef INCLUDE_MODELS_HPP_
#define INCLUDE_MODELS_HPP_
#include <array> // for array
#include <cmath> // for sqrt
#include <cstddef> // for size_t
#include <vector> // for vector
#include <boost/math/distributions/normal.hpp> // for normal_distr...
#include <boost/random/discrete_distribution.hpp> // for discrete_dis...
#include <boost/random/normal_distribution.hpp> // for normal_distr...
#include <boost/random/uniform_real_distribution.hpp> // for uniform_real...
#include <boost/random/uniform_smallint.hpp> // for uniform_smal...
#include "cpprob/cpprob.hpp" // for sample, predict
#include "cpprob/distributions/multivariate_normal.hpp" // for multivariate...
#include "cpprob/ndarray.hpp" // for NDArray
namespace models {
template<class RealType = double>
void gaussian_unknown_mean(const RealType y1, const RealType y2)
{
using boost::random::normal_distribution;
normal_distribution<RealType> prior {1, std::sqrt(5)};
const RealType mu = cpprob::sample(prior, true);
const RealType var = std::sqrt(2);
normal_distribution<RealType> likelihood {mu, var};
cpprob::observe(likelihood, y1);
cpprob::observe(likelihood, y2);
cpprob::predict(mu, "Mu");
}
template<class RealType=double>
void gaussian_2d_unk_mean(const std::vector<RealType> y1)
{
using boost::random::normal_distribution;
cpprob::multivariate_normal_distribution<> prior{{1,2}, {std::sqrt(5),std::sqrt(3)}};
const auto mu = cpprob::sample(prior, true);
const RealType var = std::sqrt(2);
cpprob::multivariate_normal_distribution<RealType> likelihood {mu.begin(), mu.end(), var};
cpprob::observe(likelihood, y1);
cpprob::predict(mu, "Mu");
}
template<class RealType = double>
struct Gauss {
void operator()(const RealType y1, const RealType y2) const
{
using boost::random::normal_distribution;
normal_distribution<RealType> prior {1, std::sqrt(5)};
const RealType mu = cpprob::sample(prior, true);
const RealType var = std::sqrt(2);
normal_distribution<RealType> likelihood {mu, var};
cpprob::observe(likelihood, y1);
cpprob::observe(likelihood, y2);
cpprob::predict(mu, "Mu");
}
};
template<std::size_t N>
void linear_gaussian_1d (const std::array<double, N> & observations)
{
using boost::random::normal_distribution;
double state = 0;
for (const auto obs : observations) {
normal_distribution<> transition_distr {state, 1};
state = cpprob::sample(transition_distr, true);
normal_distribution<> likelihood {state, 1};
cpprob::observe(likelihood, obs);
cpprob::predict(state, "State");
}
}
template<class RealType=double>
void normal_rejection_sampling(const RealType y1, const RealType y2)
{
using boost::random::normal_distribution;
using boost::random::uniform_real_distribution;
const RealType mu_prior = 1;
const RealType sigma_prior = std::sqrt(5);
const RealType sigma = std::sqrt(2);
// Simulate N(mu_prior, sigma_prior) using just its pdf
auto pdf_prior = boost::math::normal_distribution<RealType>(mu_prior, sigma_prior);
// Sample from Normal Distr
const auto maxval = boost::math::pdf(pdf_prior, mu_prior);
uniform_real_distribution<RealType> proposal{mu_prior - 20*sigma_prior,
mu_prior + 20*sigma_prior};
uniform_real_distribution<RealType> accept {0, maxval};
RealType mu;
{cpprob::rejection_sampling rej{};
do {
mu = cpprob::sample(proposal, true);
} while (cpprob::sample(accept, true) > boost::math::pdf(pdf_prior, mu));
}
normal_distribution<RealType> likelihood {mu, sigma};
cpprob::observe(likelihood, y1);
cpprob::observe(likelihood, y2);
cpprob::predict(mu, "Mu");
}
template<std::size_t N>
void hmm(const std::array<double, N> & observed_states)
{
using boost::random::normal_distribution;
using boost::random::discrete_distribution;
using boost::random::uniform_smallint;
constexpr int k = 3;
static const std::array<double, k> state_mean {{-1, 0, 1}};
static const std::array<std::array<double, k>, k> T {{{{ 0.1, 0.5, 0.4 }},
{{ 0.2, 0.2, 0.6 }},
{{ 0.15, 0.15, 0.7 }}}};
uniform_smallint<std::size_t> prior {0, 2};
auto state = cpprob::sample(prior, true);
cpprob::predict(state, "State");
auto obs_it = observed_states.begin();
normal_distribution<> likelihood {state_mean[state], 1};
cpprob::observe(likelihood, *obs_it);
++obs_it;
for (; obs_it != observed_states.end(); ++obs_it) {
discrete_distribution<std::size_t> transition_distr {T[state].begin(), T[state].end()};
state = cpprob::sample(transition_distr, true);
cpprob::predict(state, "State");
likelihood = normal_distribution<>{state_mean[state], 1};
cpprob::observe(likelihood, *obs_it);
}
}
void all_distr(int, int);
} // end namespace models
#endif // INCLUDE_MODELS_HPP_