-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathSample04-HMM-chain.cpp
135 lines (117 loc) · 4.52 KB
/
Sample04-HMM-chain.cpp
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
/**
* Author: Andrea Casalino
* Created: 03.01.2020
*
* report any bug to [email protected].
**/
// what is required from the EFG core library
#include <EasyFactorGraph/Error.h>
#include <EasyFactorGraph/factor/FactorExponential.h>
#include <EasyFactorGraph/io/json/Exporter.h>
#include <EasyFactorGraph/io/xml/Exporter.h>
#include <EasyFactorGraph/model/Graph.h>
#include <EasyFactorGraph/structure/SpecialFactors.h>
using namespace EFG::model;
using namespace EFG::io;
using namespace EFG::factor;
using namespace EFG::categoric;
using namespace EFG::strct;
// just a bunch of utilities needed by the sample
#include <Printing.h>
#include <SampleSection.h>
#include <iostream>
using namespace std;
Graph make_graph_chain(const std::size_t &chain_size,
const std::size_t &var_size, const float &weight_XY,
const float &weight_YY);
int main() {
SAMPLE_SECTION(
"Chain like structure. After running the sample, check the content of "
"the generated Graph_XY.xml, Graph_YY.xml, Graph_XY.json and "
"Graph_YY.json ",
"4.4", [] {
size_t chain_size = 10; // you can change it
size_t var_dom_size = 2; // you can change it
vector<size_t> Y_MAP;
Y_MAP.reserve(chain_size);
{
// create a chain with a strong weight on the potentials XY.
auto G_XY = make_graph_chain(chain_size, var_dom_size, 2.f, 0.5f);
// compute MAP on hidden variables and display it
for (size_t k = 0; k < chain_size; ++k) {
Y_MAP.push_back(G_XY.getMAP("Y_" + to_string(k)));
}
cout << "Strong correlation with evidences, MAP on Y0,1,.. "
<< Y_MAP << endl;
// export into an xml (just as an exporting example)
xml::Exporter::exportToFile(
G_XY, xml::ExportInfo{"Graph_XY.xml", "Graph_XY"});
// export into a json (just as an exporting example)
json::Exporter::exportToFile(G_XY, "Graph_XY.json");
}
{
// create a chain with a strong weight on the potentials YY.
auto G_YY = make_graph_chain(chain_size, var_dom_size, 0.5f, 2.f);
// compute MAP on hidden variables and display it
Y_MAP.clear();
for (size_t k = 0; k < chain_size; ++k) {
Y_MAP.push_back(G_YY.getMAP("Y_" + to_string(k)));
}
cout << "Strong correlation among hidden variables, MAP on Y0,1,.. "
" "
<< Y_MAP << endl;
// export into an xml (just as an exporting example)
xml::Exporter::exportToFile(
G_YY, xml::ExportInfo{"Graph_YY.xml", "Graph_YY"});
// export into a json (just as an exporting example)
json::Exporter::exportToFile(G_YY, "Graph_YY.json");
}
});
return EXIT_SUCCESS;
}
Graph make_graph_chain(const std::size_t &chain_size,
const std::size_t &var_size, const float &weight_XY,
const float &weight_YY) {
if (chain_size < 2)
throw EFG::Error("invalid chain size");
if (var_size < 2)
throw EFG::Error("invalid variable size");
Graph G;
auto X = make_variable(var_size, "X_placeholder");
auto Y = make_variable(var_size, "Y_placeholder");
auto Ybis = make_variable(var_size, "Y_placeholder_bis");
FactorExponential P_YY(
Factor{VariablesSoup{Y, Ybis}, Factor::SimplyCorrelatedTag{}}, weight_YY);
FactorExponential P_XY(
Factor{VariablesSoup{Y, X}, Factor::SimplyCorrelatedTag{}}, weight_XY);
// build the chain and set the value of the evidences equal to:
// X_0 = 0, X_1=var_size-1, X_2= 0, X_3 = var_size-1, etc..
VariablesSoup Y_vars, X_vars;
for (size_t k = 0; k < chain_size; k++) {
Y_vars.push_back(make_variable(var_size, "Y_" + to_string(k)));
X_vars.push_back(make_variable(var_size, "X_" + to_string(k)));
auto temp_XY = std::make_shared<FactorExponential>(P_XY);
temp_XY->replaceVariables(VariablesSoup{X_vars[k], Y_vars[k]});
G.addConstFactor(temp_XY);
}
for (size_t k = 0; k < chain_size; k++) {
ImmutablePtr factor;
if (0 == k) {
factor = std::make_shared<Indicator>(Y_vars[0], 0);
} else {
auto temp_YY = std::make_shared<FactorExponential>(P_YY);
temp_YY->replaceVariables(VariablesSoup{Y_vars[k], Y_vars[k - 1]});
factor = temp_YY;
}
G.addConstFactor(factor);
}
size_t o = 0;
for (size_t k = 0; k < chain_size; k++) {
G.setEvidence(X_vars[k], o);
if (o == 0)
o = 1;
else
o = 0;
}
return G;
}