1/* ----------------------------------------------------------------------------
2
3 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4 * Atlanta, Georgia 30332-0415
5 * All Rights Reserved
6 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7
8 * See LICENSE for the license information
9
10 * -------------------------------------------------------------------------- */
11
12/**
13 * @file UGM_chain.cpp
14 * @brief UGM (undirected graphical model) examples: chain
15 * @author Frank Dellaert
16 * @author Abhijit Kundu
17 *
18 * See http://www.di.ens.fr/~mschmidt/Software/UGM/chain.html
19 * for more explanation. This code demos the same example using GTSAM.
20 */
21
22#include <gtsam/base/timing.h>
23#include <gtsam/discrete/DiscreteFactorGraph.h>
24#include <gtsam/discrete/DiscreteMarginals.h>
25
26#include <iomanip>
27
28using namespace std;
29using namespace gtsam;
30
31int main(int argc, char** argv) {
32 // Set Number of Nodes in the Graph
33 const int nrNodes = 60;
34
35 // Each node takes 1 of 7 possible states denoted by 0-6 in following order:
36 // ["VideoGames" "Industry" "GradSchool" "VideoGames(with PhD)"
37 // "Industry(with PhD)" "Academia" "Deceased"]
38 const size_t nrStates = 7;
39
40 // define variables
41 vector<DiscreteKey> nodes;
42 for (int i = 0; i < nrNodes; i++) {
43 DiscreteKey dk(i, nrStates);
44 nodes.push_back(x: dk);
45 }
46
47 // create graph
48 DiscreteFactorGraph graph;
49
50 // add node potentials
51 graph.add(args&: nodes[0], args: ".3 .6 .1 0 0 0 0");
52 for (int i = 1; i < nrNodes; i++) graph.add(args&: nodes[i], args: "1 1 1 1 1 1 1");
53
54 const std::string edgePotential =
55 ".08 .9 .01 0 0 0 .01 "
56 ".03 .95 .01 0 0 0 .01 "
57 ".06 .06 .75 .05 .05 .02 .01 "
58 "0 0 0 .3 .6 .09 .01 "
59 "0 0 0 .02 .95 .02 .01 "
60 "0 0 0 .01 .01 .97 .01 "
61 "0 0 0 0 0 0 1";
62
63 // add edge potentials
64 for (int i = 0; i < nrNodes - 1; i++)
65 graph.add(args: nodes[i] & nodes[i + 1], args: edgePotential);
66
67 cout << "Created Factor Graph with " << nrNodes << " variable nodes and "
68 << graph.size() << " factors (Unary+Edge).";
69
70 // "Decoding", i.e., configuration with largest value
71 // Uses max-product.
72 auto optimalDecoding = graph.optimize();
73 optimalDecoding.print(s: "\nMost Probable Explanation (optimalDecoding)\n");
74
75 // "Inference" Computing marginals for each node
76 // Here we'll make use of DiscreteMarginals class, which makes use of
77 // bayes-tree based shortcut evaluation of marginals
78 DiscreteMarginals marginals(graph);
79
80 cout << "\nComputing Node Marginals ..(BayesTree based)" << endl;
81 gttic_(Multifrontal);
82 for (vector<DiscreteKey>::iterator it = nodes.begin(); it != nodes.end();
83 ++it) {
84 // Compute the marginal
85 Vector margProbs = marginals.marginalProbabilities(key: *it);
86
87 // Print the marginals
88 cout << "Node#" << setw(4) << it->first << " : ";
89 print(v: margProbs);
90 }
91 gttoc_(Multifrontal);
92
93 tictoc_print_();
94 return 0;
95}
96