testDiscreteBayesNet.cpp
Go to the documentation of this file.
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  * testDiscreteBayesNet.cpp
14  *
15  * @date Feb 27, 2011
16  * @author Frank Dellaert
17  */
18 
20 #include <gtsam/base/Testable.h>
21 #include <gtsam/base/Vector.h>
22 #include <gtsam/base/debug.h>
26 
27 #include <iostream>
28 #include <string>
29 #include <vector>
30 
31 using namespace std;
32 using namespace gtsam;
33 
34 static const DiscreteKey Asia(0, 2), Smoking(4, 2), Tuberculosis(3, 2),
35  LungCancer(6, 2), Bronchitis(7, 2), Either(5, 2), XRay(2, 2), Dyspnea(1, 2);
36 
38 
39 /* ************************************************************************* */
42  DiscreteKey Parent(0, 2), Child(1, 2);
43 
44  auto prior = std::make_shared<DiscreteConditional>(Parent % "6/4");
45  CHECK(assert_equal(ADT({Parent}, "0.6 0.4"), (ADT)*prior));
47 
48  auto conditional =
49  std::make_shared<DiscreteConditional>(Child | Parent = "7/3 8/2");
50  EXPECT_LONGS_EQUAL(1, *(conditional->beginFrontals()));
51  ADT expected(Child & Parent, "0.7 0.8 0.3 0.2");
52  CHECK(assert_equal(expected, (ADT)*conditional));
53  bayesNet.push_back(conditional);
54 
56  LONGS_EQUAL(2, fg.back()->size());
57 
58  // Check the marginals
59  const double expectedMarginal[2]{0.4, 0.6 * 0.3 + 0.4 * 0.2};
61  for (size_t j = 0; j < 2; j++) {
62  Vector FT = marginals.marginalProbabilities(DiscreteKey(j, 2));
63  EXPECT_DOUBLES_EQUAL(expectedMarginal[j], FT[1], 1e-3);
64  EXPECT_DOUBLES_EQUAL(FT[0], 1.0 - FT[1], 1e-9);
65  }
66 }
67 
68 /* ************************************************************************* */
70  DiscreteBayesNet asia;
71 
72  asia.add(Asia, "99/1");
73  asia.add(Smoking % "50/50"); // Signature version
74 
75  asia.add(Tuberculosis | Asia = "99/1 95/5");
76  asia.add(LungCancer | Smoking = "99/1 90/10");
77  asia.add(Bronchitis | Smoking = "70/30 40/60");
78 
79  asia.add((Either | Tuberculosis, LungCancer) = "F T T T");
80 
81  asia.add(XRay | Either = "95/5 2/98");
82  asia.add((Dyspnea | Either, Bronchitis) = "9/1 2/8 3/7 1/9");
83 
84  // Convert to factor graph
85  DiscreteFactorGraph fg(asia);
86  LONGS_EQUAL(3, fg.back()->size());
87 
88  // Check the marginals we know (of the parent-less nodes)
90  Vector2 va(0.99, 0.01), vs(0.5, 0.5);
91  EXPECT(assert_equal(va, marginals.marginalProbabilities(Asia)));
92  EXPECT(assert_equal(vs, marginals.marginalProbabilities(Smoking)));
93 
94  // Create solver and eliminate
95  const Ordering ordering{0, 1, 2, 3, 4, 5, 6, 7};
97  DiscreteConditional expected2(Bronchitis % "11/9");
98  EXPECT(assert_equal(expected2, *chordal->back()));
99 
100  // Check evaluate and logProbability
101  auto result = fg.optimize();
103  std::log(asia.evaluate(result)), 1e-9);
104 
105  // add evidence, we were in Asia and we have dyspnea
106  fg.add(Asia, "0 1");
107  fg.add(Dyspnea, "0 1");
108 
109  // solve again, now with evidence
111  EXPECT(assert_equal(expected2, *chordal->back()));
112 
113  // now sample from it
114  DiscreteValues expectedSample{{Asia.first, 1}, {Dyspnea.first, 1},
115  {XRay.first, 1}, {Tuberculosis.first, 0},
116  {Smoking.first, 1}, {Either.first, 1},
117  {LungCancer.first, 1}, {Bronchitis.first, 0}};
118  SETDEBUG("DiscreteConditional::sample", false);
119  auto actualSample = chordal2->sample();
120  EXPECT(assert_equal(expectedSample, actualSample));
121 }
122 
123 /* ************************************************************************* */
125  DiscreteKey T(0, 2), L(1, 2), E(2, 2), C(8, 3), S(7, 2);
126 
127  DiscreteBayesNet bn;
128 
129  // try logic
130  bn.add((E | T, L) = "OR");
131  bn.add((E | T, L) = "AND");
132 
133  // try multivalued
134  bn.add(C % "1/1/2");
135  bn.add(C | S = "1/1/2 5/2/3");
136 }
137 
138 /* ************************************************************************* */
140  DiscreteBayesNet fragment;
141  fragment.add(Asia % "99/1");
142  fragment.add(Smoking % "50/50");
143 
144  fragment.add(Tuberculosis | Asia = "99/1 95/5");
145  fragment.add(LungCancer | Smoking = "99/1 90/10");
146  fragment.add((Either | Tuberculosis, LungCancer) = "F T T T");
147 
148  string actual = fragment.dot();
149  EXPECT(actual ==
150  "digraph {\n"
151  " size=\"5,5\";\n"
152  "\n"
153  " var0[label=\"0\"];\n"
154  " var3[label=\"3\"];\n"
155  " var4[label=\"4\"];\n"
156  " var5[label=\"5\"];\n"
157  " var6[label=\"6\"];\n"
158  "\n"
159  " var3->var5\n"
160  " var6->var5\n"
161  " var4->var6\n"
162  " var0->var3\n"
163  "}");
164 }
165 
166 /* ************************************************************************* */
167 // Check markdown representation looks as expected.
169  DiscreteBayesNet fragment;
170  fragment.add(Asia % "99/1");
171  fragment.add(Smoking | Asia = "8/2 7/3");
172 
173  string expected =
174  "`DiscreteBayesNet` of size 2\n"
175  "\n"
176  " *P(Asia):*\n\n"
177  "|Asia|value|\n"
178  "|:-:|:-:|\n"
179  "|0|0.99|\n"
180  "|1|0.01|\n"
181  "\n"
182  " *P(Smoking|Asia):*\n\n"
183  "|*Asia*|0|1|\n"
184  "|:-:|:-:|:-:|\n"
185  "|0|0.8|0.2|\n"
186  "|1|0.7|0.3|\n\n";
187  auto formatter = [](Key key) { return key == 0 ? "Asia" : "Smoking"; };
188  string actual = fragment.markdown(formatter);
189  EXPECT(actual == expected);
190 }
191 
192 /* ************************************************************************* */
193 int main() {
194  TestResult tr;
195  return TestRegistry::runAllTests(tr);
196 }
197 /* ************************************************************************* */
ADT
AlgebraicDecisionTree< Key > ADT
Definition: testDiscreteBayesNet.cpp:37
TestRegistry::runAllTests
static int runAllTests(TestResult &result)
Definition: TestRegistry.cpp:27
LungCancer
static const DiscreteKey LungCancer(6, 2)
gtsam::EliminateableFactorGraph::eliminateSequential
std::shared_ptr< BayesNetType > eliminateSequential(OptionalOrderingType orderingType={}, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex={}) const
Definition: EliminateableFactorGraph-inst.h:29
DiscreteBayesNet.h
gtsam::markdown
string markdown(const DiscreteValues &values, const KeyFormatter &keyFormatter, const DiscreteValues::Names &names)
Free version of markdown.
Definition: DiscreteValues.cpp:130
SETDEBUG
#define SETDEBUG(S, V)
Definition: debug.h:61
Tuberculosis
static const DiscreteKey Tuberculosis(3, 2)
gtsam::DiscreteFactorGraph
Definition: DiscreteFactorGraph.h:98
Vector.h
typedef and functions to augment Eigen's VectorXd
XRay
static const DiscreteKey XRay(2, 2)
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
EXPECT_LONGS_EQUAL
#define EXPECT_LONGS_EQUAL(expected, actual)
Definition: Test.h:154
Testable.h
Concept check for values that can be used in unit tests.
EXPECT
#define EXPECT(condition)
Definition: Test.h:150
TestHarness.h
DiscreteFactorGraph.h
gtsam::BayesNet::dot
void dot(std::ostream &os, const KeyFormatter &keyFormatter=DefaultKeyFormatter, const DotWriter &writer=DotWriter()) const
Output to graphviz format, stream version.
Definition: BayesNet-inst.h:45
formatter
const KeyFormatter & formatter
Definition: treeTraversal-inst.h:204
T
Eigen::Triplet< double > T
Definition: Tutorial_sparse_example.cpp:6
log
const EIGEN_DEVICE_FUNC LogReturnType log() const
Definition: ArrayCwiseUnaryOps.h:128
gtsam::Factor::back
Key back() const
Last key.
Definition: Factor.h:137
gtsam::Vector
Eigen::VectorXd Vector
Definition: Vector.h:38
result
Values result
Definition: OdometryOptimize.cpp:8
Bronchitis
static const DiscreteKey Bronchitis(7, 2)
gtsam::AlgebraicDecisionTree< Key >
different_sigmas::bayesNet
const HybridBayesNet bayesNet
Definition: testHybridBayesNet.cpp:242
gtsam::DiscreteBayesNet::logProbability
double logProbability(const DiscreteValues &values) const
Definition: DiscreteBayesNet.cpp:34
gtsam::DiscreteBayesNet
Definition: DiscreteBayesNet.h:38
j
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
Smoking
static const DiscreteKey Smoking(4, 2)
gtsam::DiscreteBayesNet::markdown
std::string markdown(const KeyFormatter &keyFormatter=DefaultKeyFormatter, const DiscreteFactor::Names &names={}) const
Render as markdown tables.
Definition: DiscreteBayesNet.cpp:72
gtsam::DiscreteBayesNet::evaluate
double evaluate(const DiscreteValues &values) const
Definition: DiscreteBayesNet.cpp:43
cholesky::expected
Matrix expected
Definition: testMatrix.cpp:971
gtsam::DiscreteMarginals
Definition: DiscreteMarginals.h:33
L
MatrixXd L
Definition: LLT_example.cpp:6
Vector2
Definition: test_operator_overloading.cpp:18
Eigen::Triplet< double >
Dyspnea
static const DiscreteKey Dyspnea(1, 2)
EXPECT_DOUBLES_EQUAL
#define EXPECT_DOUBLES_EQUAL(expected, actual, threshold)
Definition: Test.h:161
DiscreteMarginals.h
A class for computing marginals in a DiscreteFactorGraph.
ordering
static enum @1096 ordering
TestResult
Definition: TestResult.h:26
TEST
TEST(DiscreteBayesNet, bayesNet)
Definition: testDiscreteBayesNet.cpp:40
key
const gtsam::Symbol key('X', 0)
E
DiscreteKey E(5, 2)
gtsam::FactorGraph::back
sharedFactor back() const
Definition: FactorGraph.h:348
Either
static const DiscreteKey Either(5, 2)
gtsam::HybridBayesNet::push_back
void push_back(std::shared_ptr< HybridConditional > conditional)
Add a hybrid conditional using a shared_ptr.
Definition: HybridBayesNet.h:76
gtsam::DiscreteConditional
Definition: DiscreteConditional.h:37
gtsam::DiscreteBayesNet::add
void add(const DiscreteKey &key, const std::string &spec)
Definition: DiscreteBayesNet.h:85
C
Matrix< Scalar, Dynamic, Dynamic > C
Definition: bench_gemm.cpp:50
gtsam
traits
Definition: SFMdata.h:40
gtsam::DiscreteValues
Definition: DiscreteValues.h:34
CHECK
#define CHECK(condition)
Definition: Test.h:108
gtsam::DiscreteKey
std::pair< Key, size_t > DiscreteKey
Definition: DiscreteKey.h:38
std
Definition: BFloat16.h:88
gtsam::DiscreteFactorGraph::add
void add(Args &&... args)
Definition: DiscreteFactorGraph.h:138
gtsam::DiscreteBayesNet::shared_ptr
std::shared_ptr< This > shared_ptr
Definition: DiscreteBayesNet.h:43
gtsam::assert_equal
bool assert_equal(const Matrix &expected, const Matrix &actual, double tol)
Definition: Matrix.cpp:40
different_sigmas::prior
const auto prior
Definition: testHybridBayesNet.cpp:238
gtsam::DiscreteFactorGraph::optimize
DiscreteValues optimize(OptionalOrderingType orderingType={}) const
Find the maximum probable explanation (MPE) by doing max-product.
Definition: DiscreteFactorGraph.cpp:189
marginals
Marginals marginals(graph, result)
main
int main()
Definition: testDiscreteBayesNet.cpp:193
gtsam::Key
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:97
gtsam::Ordering
Definition: inference/Ordering.h:33
LONGS_EQUAL
#define LONGS_EQUAL(expected, actual)
Definition: Test.h:134
S
DiscreteKey S(1, 2)
debug.h
Global debugging flags.
Asia
static const DiscreteKey Asia(0, 2)


gtsam
Author(s):
autogenerated on Fri Nov 1 2024 03:39:49