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 DiscreteBayesNetExample.cpp
14 * @brief Discrete Bayes Net example with famous Asia Bayes Network
15 * @author Frank Dellaert
16 * @date JULY 10, 2020
17 */
18
19#include <gtsam/discrete/DiscreteFactorGraph.h>
20#include <gtsam/discrete/DiscreteMarginals.h>
21#include <gtsam/inference/BayesNet.h>
22
23#include <iomanip>
24
25using namespace std;
26using namespace gtsam;
27
28int main(int argc, char **argv) {
29 DiscreteBayesNet asia;
30 DiscreteKey Asia(0, 2), Smoking(4, 2), Tuberculosis(3, 2), LungCancer(6, 2),
31 Bronchitis(7, 2), Either(5, 2), XRay(2, 2), Dyspnea(1, 2);
32 asia.add(args: Asia % "99/1");
33 asia.add(args: Smoking % "50/50");
34
35 asia.add(args&: Tuberculosis | Asia = "99/1 95/5");
36 asia.add(args&: LungCancer | Smoking = "99/1 90/10");
37 asia.add(args&: Bronchitis | Smoking = "70/30 40/60");
38
39 asia.add(args&: (Either | Tuberculosis, LungCancer) = "F T T T");
40
41 asia.add(args&: XRay | Either = "95/5 2/98");
42 asia.add(args&: (Dyspnea | Either, Bronchitis) = "9/1 2/8 3/7 1/9");
43
44 // print
45 vector<string> pretty = {"Asia", "Dyspnea", "XRay", "Tuberculosis",
46 "Smoking", "Either", "LungCancer", "Bronchitis"};
47 auto formatter = [pretty](Key key) { return pretty[key]; };
48 asia.print(s: "Asia", formatter);
49
50 // Convert to factor graph
51 DiscreteFactorGraph fg(asia);
52
53 // Create solver and eliminate
54 const Ordering ordering{0, 1, 2, 3, 4, 5, 6, 7};
55
56 // solve
57 auto mpe = fg.optimize();
58 GTSAM_PRINT(mpe);
59
60 // We can also build a Bayes tree (directed junction tree).
61 // The elimination order above will do fine:
62 auto bayesTree = fg.eliminateMultifrontal(ordering);
63 bayesTree->print(s: "bayesTree", keyFormatter: formatter);
64
65 // add evidence, we were in Asia and we have dyspnea
66 fg.add(args&: Asia, args: "0 1");
67 fg.add(args&: Dyspnea, args: "0 1");
68
69 // solve again, now with evidence
70 auto mpe2 = fg.optimize();
71 GTSAM_PRINT(mpe2);
72
73 // We can also sample from it
74 DiscreteBayesNet::shared_ptr chordal = fg.eliminateSequential(ordering);
75 cout << "\n10 samples:" << endl;
76 for (size_t i = 0; i < 10; i++) {
77 auto sample = chordal->sample();
78 GTSAM_PRINT(sample);
79 }
80 return 0;
81}
82