testSymbolicBayesTree.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  * @file testSymbolicBayesTree.cpp
14  * @date sept 15, 2012
15  * @author Frank Dellaert
16  * @author Michael Kaess
17  * @author Viorela Ila
18  */
19 
22 #include <gtsam/inference/Symbol.h>
24 
25 #include <boost/assign/list_of.hpp>
26 #include <boost/assign/std/vector.hpp>
27 #include <boost/assign/std/list.hpp>
28 #include <boost/range/adaptor/indirected.hpp>
29 using namespace boost::assign;
30 using boost::adaptors::indirected;
31 
34 
35 using namespace std;
36 using namespace gtsam;
37 using namespace gtsam::symbol_shorthand;
38 
39 static bool debug = false;
40 
41 namespace {
42 
43  /* ************************************************************************* */
44  // Helper functions for below
45  template<typename KEYS>
46  SymbolicBayesTreeClique::shared_ptr MakeClique(const KEYS& keys, DenseIndex nrFrontals)
47  {
48  return boost::make_shared<SymbolicBayesTreeClique>(
49  boost::make_shared<SymbolicConditional>(
50  SymbolicConditional::FromKeys(keys, nrFrontals)));
51  }
52 
53  template<typename KEYS, typename CHILDREN>
55  const KEYS& keys, DenseIndex nrFrontals, const CHILDREN& children)
56  {
58  boost::make_shared<SymbolicBayesTreeClique>(
59  boost::make_shared<SymbolicConditional>(
60  SymbolicConditional::FromKeys(keys, nrFrontals)));
61  clique->children.assign(children.begin(), children.end());
62  for(typename CHILDREN::const_iterator child = children.begin(); child != children.end(); ++child)
63  (*child)->parent_ = clique;
64  return clique;
65  }
66 
67 }
68 
69 /* ************************************************************************* */
71 {
72  SymbolicBayesTree bayesTree = asiaBayesTree;
73  bayesTree.clear();
74 
76 
77  // Check whether cleared BayesTree is equal to a new BayesTree
78  CHECK(assert_equal(expected, bayesTree));
79 }
80 
81 /* ************************************************************************* */
82 TEST(SymbolicBayesTree, clique_structure)
83 {
84  // l1 l2
85  // / | / |
86  // x1 --- x2 --- x3 --- x4 --- x5
87  // \ |
88  // l3
90  graph += SymbolicFactor(X(1), L(1));
91  graph += SymbolicFactor(X(1), X(2));
92  graph += SymbolicFactor(X(2), L(1));
93  graph += SymbolicFactor(X(2), X(3));
94  graph += SymbolicFactor(X(3), X(4));
95  graph += SymbolicFactor(X(4), L(2));
96  graph += SymbolicFactor(X(4), X(5));
97  graph += SymbolicFactor(L(2), X(5));
98  graph += SymbolicFactor(X(4), L(3));
99  graph += SymbolicFactor(X(5), L(3));
100 
102  expected.insertRoot(
103  MakeClique(list_of(X(2)) (X(3)), 2, list_of
104  (MakeClique(list_of(X(4)) (X(3)), 1, list_of
105  (MakeClique(list_of(X(5)) (L(2)) (X(4)), 2, list_of
106  (MakeClique(list_of(L(3)) (X(4)) (X(5)), 1))))))
107  (MakeClique(list_of(X(1)) (L(1)) (X(2)), 2))));
108 
109  Ordering order = list_of(X(1)) (L(3)) (L(1)) (X(5)) (X(2)) (L(2)) (X(4)) (X(3));
110 
111  SymbolicBayesTree actual = *graph.eliminateMultifrontal(order);
112 
113  EXPECT(assert_equal(expected, actual));
114 }
115 
116 /* ************************************************************************* *
117 Bayes Tree for testing conversion to a forest of orphans needed for incremental.
118  A,B
119  C|A E|B
120  D|C F|E
121  */
122 /* ************************************************************************* */
123 TEST( BayesTree, removePath )
124 {
125  const Key _A_=A(0), _B_=B(0), _C_=C(0), _D_=D(0), _E_=E(0), _F_=F(0);
126 
127  SymbolicBayesTree bayesTreeOrig;
128  bayesTreeOrig.insertRoot(
129  MakeClique(list_of(_A_)(_B_), 2, list_of
130  (MakeClique(list_of(_C_)(_A_), 1, list_of
131  (MakeClique(list_of(_D_)(_C_), 1))))
132  (MakeClique(list_of(_E_)(_B_), 1, list_of
133  (MakeClique(list_of(_F_)(_E_), 1))))));
134 
135  SymbolicBayesTree bayesTree = bayesTreeOrig;
136 
137  // remove C, expected outcome: factor graph with ABC,
138  // Bayes Tree now contains two orphan trees: D|C and E|B,F|E
140  expected += SymbolicFactor(_A_,_B_);
141  expected += SymbolicFactor(_C_,_A_);
142  SymbolicBayesTree::Cliques expectedOrphans;
143  expectedOrphans += bayesTree[_D_], bayesTree[_E_];
144 
145  SymbolicBayesNet bn;
146  SymbolicBayesTree::Cliques orphans;
147  bayesTree.removePath(bayesTree[_C_], &bn, &orphans);
149  CHECK(assert_equal(expected, factors));
150  CHECK(assert_container_equal(expectedOrphans|indirected, orphans|indirected));
151 
152  bayesTree = bayesTreeOrig;
153 
154  // remove E: factor graph with EB; E|B removed from second orphan tree
155  SymbolicFactorGraph expected2;
156  expected2 += SymbolicFactor(_A_,_B_);
157  expected2 += SymbolicFactor(_E_,_B_);
158  SymbolicBayesTree::Cliques expectedOrphans2;
159  expectedOrphans2 += bayesTree[_F_];
160  expectedOrphans2 += bayesTree[_C_];
161 
162  SymbolicBayesNet bn2;
163  SymbolicBayesTree::Cliques orphans2;
164  bayesTree.removePath(bayesTree[_E_], &bn2, &orphans2);
165  SymbolicFactorGraph factors2(bn2);
166  CHECK(assert_equal(expected2, factors2));
167  CHECK(assert_container_equal(expectedOrphans2|indirected, orphans2|indirected));
168 }
169 
170 /* ************************************************************************* */
171 TEST( BayesTree, removePath2 )
172 {
173  SymbolicBayesTree bayesTree = asiaBayesTree;
174 
175  // Call remove-path with clique B
176  SymbolicBayesNet bn;
177  SymbolicBayesTree::Cliques orphans;
178  bayesTree.removePath(bayesTree[_B_], &bn, &orphans);
180 
181  // Check expected outcome
183  expected += SymbolicFactor(_E_,_L_,_B_);
184  CHECK(assert_equal(expected, factors));
185  SymbolicBayesTree::Cliques expectedOrphans;
186  expectedOrphans += bayesTree[_S_], bayesTree[_T_], bayesTree[_X_];
187  CHECK(assert_container_equal(expectedOrphans|indirected, orphans|indirected));
188 }
189 
190 /* ************************************************************************* */
191 TEST(BayesTree, removePath3)
192 {
193  SymbolicBayesTree bayesTree = asiaBayesTree;
194 
195  // Call remove-path with clique T
196  SymbolicBayesNet bn;
197  SymbolicBayesTree::Cliques orphans;
198  bayesTree.removePath(bayesTree[_T_], &bn, &orphans);
200 
201  // Check expected outcome
203  expected += SymbolicFactor(_E_, _L_, _B_);
204  expected += SymbolicFactor(_T_, _E_, _L_);
205  CHECK(assert_equal(expected, factors));
206  SymbolicBayesTree::Cliques expectedOrphans;
207  expectedOrphans += bayesTree[_S_], bayesTree[_X_];
208  CHECK(assert_container_equal(expectedOrphans|indirected, orphans|indirected));
209 }
210 
211 void getAllCliques(const SymbolicBayesTree::sharedClique& subtree, SymbolicBayesTree::Cliques& cliques) {
212  // Check if subtree exists
213  if (subtree) {
214  cliques.push_back(subtree);
215  // Recursive call over all child cliques
216  for(SymbolicBayesTree::sharedClique& childClique: subtree->children) {
217  getAllCliques(childClique,cliques);
218  }
219  }
220 }
221 
222 /* ************************************************************************* */
223 TEST( BayesTree, shortcutCheck )
224 {
225  const Key _A_=6, _B_=5, _C_=4, _D_=3, _E_=2, _F_=1, _G_=0;
226  SymbolicFactorGraph chain = list_of
227  (SymbolicFactor(_A_))
228  (SymbolicFactor(_B_, _A_))
229  (SymbolicFactor(_C_, _A_))
231  (SymbolicFactor(_E_, _B_))
232  (SymbolicFactor(_F_, _E_))
233  (SymbolicFactor(_G_, _F_));
234  Ordering ordering(list_of(_G_)(_F_)(_E_)(_D_)(_C_)(_B_)(_A_));
235  SymbolicBayesTree bayesTree = *chain.eliminateMultifrontal(ordering);
236 
237  //bayesTree.saveGraph("BT1.dot");
238 
239  SymbolicBayesTree::sharedClique rootClique = bayesTree.roots().front();
240  //rootClique->printTree();
241  SymbolicBayesTree::Cliques allCliques;
242  getAllCliques(rootClique,allCliques);
243 
244  for(SymbolicBayesTree::sharedClique& clique: allCliques) {
245  //clique->print("Clique#");
246  SymbolicBayesNet bn = clique->shortcut(rootClique);
247  //bn.print("Shortcut:\n");
248  //cout << endl;
249  }
250 
251  // Check if all the cached shortcuts are cleared
252  rootClique->deleteCachedShortcuts();
253  for(SymbolicBayesTree::sharedClique& clique: allCliques) {
254  bool notCleared = clique->cachedSeparatorMarginal().is_initialized();
255  CHECK( notCleared == false);
256  }
257  EXPECT_LONGS_EQUAL(0, (long)rootClique->numCachedSeparatorMarginals());
258 
259 // for(SymbolicBayesTree::sharedClique& clique: allCliques) {
260 // clique->print("Clique#");
261 // if(clique->cachedShortcut()){
262 // bn = clique->cachedShortcut().get();
263 // bn.print("Shortcut:\n");
264 // }
265 // else
266 // cout << "Not Initialized" << endl;
267 // cout << endl;
268 // }
269 }
270 
271 /* ************************************************************************* */
272 TEST( BayesTree, removeTop )
273 {
274  SymbolicBayesTree bayesTree = asiaBayesTree;
275 
276  // create a new factor to be inserted
277  //boost::shared_ptr<IndexFactor> newFactor(new IndexFactor(_S_,_B_));
278 
279  // Remove the contaminated part of the Bayes tree
280  SymbolicBayesNet bn;
281  SymbolicBayesTree::Cliques orphans;
282  bayesTree.removeTop(list_of(_B_)(_S_), &bn, &orphans);
283 
284  // Check expected outcome
286  expected += SymbolicConditional::FromKeys(list_of(_E_)(_L_)(_B_), 3);
287  expected += SymbolicConditional::FromKeys(list_of(_S_)(_B_)(_L_), 1);
288  CHECK(assert_equal(expected, bn));
289 
290  SymbolicBayesTree::Cliques expectedOrphans;
291  expectedOrphans += bayesTree[_T_], bayesTree[_X_];
292  CHECK(assert_container_equal(expectedOrphans|indirected, orphans|indirected));
293 
294  // Try removeTop again with a factor that should not change a thing
295  //boost::shared_ptr<IndexFactor> newFactor2(new IndexFactor(_B_));
296  SymbolicBayesNet bn2;
297  SymbolicBayesTree::Cliques orphans2;
298  bayesTree.removeTop(list_of(_B_), &bn2, &orphans2);
299  SymbolicFactorGraph factors2(bn2);
300  SymbolicFactorGraph expected2;
301  CHECK(assert_equal(expected2, factors2));
302  SymbolicBayesTree::Cliques expectedOrphans2;
303  CHECK(assert_container_equal(expectedOrphans2|indirected, orphans2|indirected));
304 }
305 
306 /* ************************************************************************* */
307 TEST( BayesTree, removeTop2 )
308 {
309  SymbolicBayesTree bayesTree = asiaBayesTree;
310 
311  // create two factors to be inserted
312  //SymbolicFactorGraph newFactors;
313  //newFactors.push_factor(_B_);
314  //newFactors.push_factor(_S_);
315 
316  // Remove the contaminated part of the Bayes tree
317  SymbolicBayesNet bn;
318  SymbolicBayesTree::Cliques orphans;
319  bayesTree.removeTop(list_of(_T_), &bn, &orphans);
320 
321  // Check expected outcome
322  SymbolicBayesNet expected = list_of
323  (SymbolicConditional::FromKeys(list_of(_E_)(_L_)(_B_), 3))
324  (SymbolicConditional::FromKeys(list_of(_T_)(_E_)(_L_), 1));
325  CHECK(assert_equal(expected, bn));
326 
327  SymbolicBayesTree::Cliques expectedOrphans;
328  expectedOrphans += bayesTree[_S_], bayesTree[_X_];
329  CHECK(assert_container_equal(expectedOrphans|indirected, orphans|indirected));
330 }
331 
332 /* ************************************************************************* */
333 TEST( BayesTree, removeTop3 )
334 {
335  SymbolicFactorGraph graph = list_of
336  (SymbolicFactor(L(5)))
337  (SymbolicFactor(X(4), L(5)))
338  (SymbolicFactor(X(2), X(4)))
339  (SymbolicFactor(X(3), X(2)));
340  Ordering ordering(list_of (X(3)) (X(2)) (X(4)) (L(5)) );
341  SymbolicBayesTree bayesTree = *graph.eliminateMultifrontal(ordering);
342 
343  // remove all
344  SymbolicBayesNet bn;
345  SymbolicBayesTree::Cliques orphans;
346  bayesTree.removeTop(list_of(L(5))(X(4))(X(2))(X(3)), &bn, &orphans);
347 
348  SymbolicBayesNet expectedBn = list_of
349  (SymbolicConditional::FromKeys(list_of(X(4))(L(5)), 2))
350  (SymbolicConditional(X(2), X(4)))
351  (SymbolicConditional(X(3), X(2)));
352  EXPECT(assert_equal(expectedBn, bn));
353  EXPECT(orphans.empty());
354 }
355 
356 /* ************************************************************************* */
357 TEST( BayesTree, removeTop4 )
358 {
359  SymbolicFactorGraph graph = list_of
360  (SymbolicFactor(L(5)))
361  (SymbolicFactor(X(4), L(5)))
362  (SymbolicFactor(X(2), X(4)))
363  (SymbolicFactor(X(3), X(2)));
364  Ordering ordering(list_of (X(3)) (X(2)) (X(4)) (L(5)) );
365  SymbolicBayesTree bayesTree = *graph.eliminateMultifrontal(ordering);
366 
367  // remove all
368  SymbolicBayesNet bn;
369  SymbolicBayesTree::Cliques orphans;
370  bayesTree.removeTop(list_of(X(2))(L(5))(X(4))(X(3)), &bn, &orphans);
371 
372  SymbolicBayesNet expectedBn = list_of
373  (SymbolicConditional::FromKeys(list_of(X(4))(L(5)), 2))
374  (SymbolicConditional(X(2), X(4)))
375  (SymbolicConditional(X(3), X(2)));
376  EXPECT(assert_equal(expectedBn, bn));
377  EXPECT(orphans.empty());
378 }
379 
380 /* ************************************************************************* */
381 TEST( BayesTree, removeTop5 )
382 {
383  // Remove top called with variables that are not in the Bayes tree
384  SymbolicFactorGraph graph = list_of
385  (SymbolicFactor(L(5)))
386  (SymbolicFactor(X(4), L(5)))
387  (SymbolicFactor(X(2), X(4)))
388  (SymbolicFactor(X(3), X(2)));
389  Ordering ordering(list_of (X(3)) (X(2)) (X(4)) (L(5)) );
390  SymbolicBayesTree bayesTree = *graph.eliminateMultifrontal(ordering);
391 
392  // Remove nonexistant
393  SymbolicBayesNet bn;
394  SymbolicBayesTree::Cliques orphans;
395  bayesTree.removeTop(list_of(X(10)), &bn, &orphans);
396 
397  SymbolicBayesNet expectedBn;
398  EXPECT(assert_equal(expectedBn, bn));
399  EXPECT(orphans.empty());
400 }
401 
402 /* ************************************************************************* */
403 TEST( SymbolicBayesTree, thinTree ) {
404 
405  // create a thin-tree Bayesnet, a la Jean-Guillaume
406  SymbolicBayesNet bayesNet;
407  bayesNet.push_back(boost::make_shared<SymbolicConditional>(14));
408 
409  bayesNet.push_back(boost::make_shared<SymbolicConditional>(13, 14));
410  bayesNet.push_back(boost::make_shared<SymbolicConditional>(12, 14));
411 
412  bayesNet.push_back(boost::make_shared<SymbolicConditional>(11, 13, 14));
413  bayesNet.push_back(boost::make_shared<SymbolicConditional>(10, 13, 14));
414  bayesNet.push_back(boost::make_shared<SymbolicConditional>(9, 12, 14));
415  bayesNet.push_back(boost::make_shared<SymbolicConditional>(8, 12, 14));
416 
417  bayesNet.push_back(boost::make_shared<SymbolicConditional>(7, 11, 13));
418  bayesNet.push_back(boost::make_shared<SymbolicConditional>(6, 11, 13));
419  bayesNet.push_back(boost::make_shared<SymbolicConditional>(5, 10, 13));
420  bayesNet.push_back(boost::make_shared<SymbolicConditional>(4, 10, 13));
421 
422  bayesNet.push_back(boost::make_shared<SymbolicConditional>(3, 9, 12));
423  bayesNet.push_back(boost::make_shared<SymbolicConditional>(2, 9, 12));
424  bayesNet.push_back(boost::make_shared<SymbolicConditional>(1, 8, 12));
425  bayesNet.push_back(boost::make_shared<SymbolicConditional>(0, 8, 12));
426 
427  if (debug) {
428  GTSAM_PRINT(bayesNet);
429  bayesNet.saveGraph("/tmp/symbolicBayesNet.dot");
430  }
431 
432  // create a BayesTree out of a Bayes net
434  if (debug) {
435  GTSAM_PRINT(bayesTree);
436  bayesTree.saveGraph("/tmp/SymbolicBayesTree.dot");
437  }
438 
439  SymbolicBayesTree::Clique::shared_ptr R = bayesTree.roots().front();
440 
441  {
442  // check shortcut P(S9||R) to root
444  SymbolicBayesNet shortcut = c->shortcut(R);
445  SymbolicBayesNet expected = list_of(SymbolicConditional(14, 11, 13));
446  EXPECT(assert_equal(expected, shortcut));
447  }
448 
449  {
450  // check shortcut P(S8||R) to root
452  SymbolicBayesNet shortcut = c->shortcut(R);
453  SymbolicBayesNet expected = list_of
454  (SymbolicConditional(12, 14))
455  (SymbolicConditional(14, 11, 13));
456  EXPECT(assert_equal(expected, shortcut));
457  }
458 
459  {
460  // check shortcut P(S4||R) to root
462  SymbolicBayesNet shortcut = c->shortcut(R);
463  SymbolicBayesNet expected = list_of(SymbolicConditional(10, 11, 13));
464  EXPECT(assert_equal(expected, shortcut));
465  }
466 
467  {
468  // check shortcut P(S2||R) to root
470  SymbolicBayesNet shortcut = c->shortcut(R);
471  SymbolicBayesNet expected = list_of(SymbolicConditional(9, 11, 12, 13))
472  (SymbolicConditional(12, 11, 13));
473  EXPECT(assert_equal(expected, shortcut));
474  }
475 
476  {
477  // check shortcut P(S0||R) to root
479  SymbolicBayesNet shortcut = c->shortcut(R);
480  SymbolicBayesNet expected = list_of(SymbolicConditional(8, 11, 12, 13))
481  (SymbolicConditional(12, 11, 13));
482  EXPECT(assert_equal(expected, shortcut));
483  }
484 
485  SymbolicBayesNet::shared_ptr actualJoint;
486 
487  // Check joint P(8,2)
488  if (false) { // TODO, not disjoint
489  actualJoint = bayesTree.jointBayesNet(8, 2);
491  expected.push_back(boost::make_shared<SymbolicConditional>(8));
492  expected.push_back(boost::make_shared<SymbolicConditional>(2, 8));
493  EXPECT(assert_equal(expected, *actualJoint));
494  }
495 
496  // Check joint P(1,2)
497  if (false) { // TODO, not disjoint
498  actualJoint = bayesTree.jointBayesNet(1, 2);
500  expected.push_back(boost::make_shared<SymbolicConditional>(2));
501  expected.push_back(boost::make_shared<SymbolicConditional>(1, 2));
502  EXPECT(assert_equal(expected, *actualJoint));
503  }
504 
505  // Check joint P(2,6)
506  if (true) {
507  actualJoint = bayesTree.jointBayesNet(2, 6);
509  expected.push_back(boost::make_shared<SymbolicConditional>(2, 6));
510  expected.push_back(boost::make_shared<SymbolicConditional>(6));
511  EXPECT(assert_equal(expected, *actualJoint));
512  }
513 
514  // Check joint P(4,6)
515  if (false) { // TODO, not disjoint
516  actualJoint = bayesTree.jointBayesNet(4, 6);
518  expected.push_back(boost::make_shared<SymbolicConditional>(6));
519  expected.push_back(boost::make_shared<SymbolicConditional>(4, 6));
520  EXPECT(assert_equal(expected, *actualJoint));
521  }
522 }
523 
524 /* ************************************************************************* */
525 TEST(SymbolicBayesTree, forest_joint)
526 {
527  // Create forest
528  SymbolicBayesTreeClique::shared_ptr root1 = MakeClique(list_of(1), 1);
529  SymbolicBayesTreeClique::shared_ptr root2 = MakeClique(list_of(2), 1);
530  SymbolicBayesTree bayesTree;
531  bayesTree.insertRoot(root1);
532  bayesTree.insertRoot(root2);
533 
534  // Check joint
535  SymbolicBayesNet expected = list_of
537  (SymbolicConditional(2));
538  SymbolicBayesNet actual = *bayesTree.jointBayesNet(1, 2);
539 
540  EXPECT(assert_equal(expected, actual));
541 }
542 
543 /* ************************************************************************* *
544  Bayes tree for smoother with "natural" ordering:
545  C1 5 6
546  C2 4 : 5
547  C3 3 : 4
548  C4 2 : 3
549  C5 1 : 2
550  C6 0 : 1
551  **************************************************************************** */
552 
553 TEST( SymbolicBayesTree, linear_smoother_shortcuts ) {
554  // Create smoother with 7 nodes
555  SymbolicFactorGraph smoother;
556  smoother.push_factor(0);
557  smoother.push_factor(0, 1);
558  smoother.push_factor(1, 2);
559  smoother.push_factor(2, 3);
560  smoother.push_factor(3, 4);
561  smoother.push_factor(4, 5);
562  smoother.push_factor(5, 6);
563 
564  // Eliminate in numerical order 0..6
565  Ordering ordering(smoother.keys());
566  SymbolicBayesNet bayesNet = *smoother.eliminateSequential(ordering);
567 
568  if (debug) {
569  GTSAM_PRINT(bayesNet);
570  bayesNet.saveGraph("/tmp/symbolicBayesNet.dot");
571  }
572 
573  // create a BayesTree
574  SymbolicBayesTree bayesTree = *smoother.eliminateMultifrontal(ordering);
575  if (debug) {
576  GTSAM_PRINT(bayesTree);
577  bayesTree.saveGraph("/tmp/SymbolicBayesTree.dot");
578  }
579 
580  SymbolicBayesTree::Clique::shared_ptr R = bayesTree.roots().front();
581 
582  {
583  // check shortcut P(S2||R) to root
584  SymbolicBayesTree::Clique::shared_ptr c = bayesTree[4]; // 4 is frontal in C2
585  SymbolicBayesNet shortcut = c->shortcut(R);
587  EXPECT(assert_equal(expected, shortcut));
588  }
589 
590  {
591  // check shortcut P(S3||R) to root
592  SymbolicBayesTree::Clique::shared_ptr c = bayesTree[3]; // 3 is frontal in C3
593  SymbolicBayesNet shortcut = c->shortcut(R);
595  EXPECT(assert_equal(expected, shortcut));
596  }
597 
598  {
599  // check shortcut P(S4||R) to root
600  SymbolicBayesTree::Clique::shared_ptr c = bayesTree[2]; // 2 is frontal in C4
601  SymbolicBayesNet shortcut = c->shortcut(R);
603  EXPECT(assert_equal(expected, shortcut));
604  }
605 }
606 
607 /* ************************************************************************* */
608 // from testSymbolicJunctionTree, which failed at one point
609 TEST(SymbolicBayesTree, complicatedMarginal)
610 {
611  // Create the conditionals to go in the BayesTree
613  SymbolicBayesTreeClique::shared_ptr root = MakeClique(list_of(11)(12), 2);
614  cur = root;
615 
616  root->children += MakeClique(list_of(9)(10)(11)(12), 2);
617  root->children.back()->parent_ = root;
618 
619  root->children += MakeClique(list_of(7)(8)(11), 2);
620  root->children.back()->parent_ = root;
621  cur = root->children.back();
622 
623  cur->children += MakeClique(list_of(5)(6)(7)(8), 2);
624  cur->children.back()->parent_ = cur;
625  cur = cur->children.back();
626 
627  cur->children += MakeClique(list_of(3)(4)(6), 2);
628  cur->children.back()->parent_ = cur;
629 
630  cur->children += MakeClique(list_of(1)(2)(5), 2);
631  cur->children.back()->parent_ = cur;
632 
633  // Create Bayes Tree
635  bt.insertRoot(root);
636  if (debug) {
637  GTSAM_PRINT(bt);
638  bt.saveGraph("/tmp/SymbolicBayesTree.dot");
639  }
640 
641  // Shortcut on 9
642  {
644  SymbolicBayesNet shortcut = c->shortcut(root);
645  EXPECT(assert_equal(SymbolicBayesNet(), shortcut));
646  }
647 
648  // Shortcut on 7
649  {
651  SymbolicBayesNet shortcut = c->shortcut(root);
652  EXPECT(assert_equal(SymbolicBayesNet(), shortcut));
653  }
654 
655  // Shortcut on 5
656  {
658  SymbolicBayesNet shortcut = c->shortcut(root);
659  SymbolicBayesNet expected = list_of
660  (SymbolicConditional(7, 8, 11))
661  (SymbolicConditional(8, 11));
662  EXPECT(assert_equal(expected, shortcut));
663  }
664 
665  // Shortcut on 3
666  {
668  SymbolicBayesNet shortcut = c->shortcut(root);
670  EXPECT(assert_equal(expected, shortcut));
671  }
672 
673  // Shortcut on 1
674  {
676  SymbolicBayesNet shortcut = c->shortcut(root);
678  EXPECT(assert_equal(expected, shortcut));
679  }
680 
681  // Marginal on 5
682  {
684  EXPECT(assert_equal(SymbolicFactor(5), *actual, 1e-1));
685  }
686 
687  // Shortcut on 6
688  {
690  EXPECT(assert_equal(SymbolicFactor(6), *actual, 1e-1));
691  }
692 
693 }
694 
695 /* ************************************************************************* */
696 TEST(SymbolicBayesTree, COLAMDvsMETIS) {
697 
698  // create circular graph
700  sfg.push_factor(0, 1);
701  sfg.push_factor(1, 2);
702  sfg.push_factor(2, 3);
703  sfg.push_factor(3, 4);
704  sfg.push_factor(4, 5);
705  sfg.push_factor(0, 5);
706 
707  // COLAMD
708  {
709  Ordering ordering = Ordering::Create(Ordering::COLAMD, sfg);
710  EXPECT(assert_equal(Ordering(list_of(0)(5)(1)(4)(2)(3)), ordering));
711 
712  // - P( 4 2 3)
713  // | - P( 1 | 2 4)
714  // | | - P( 5 | 1 4)
715  // | | | - P( 0 | 1 5)
717  expected.insertRoot(
718  MakeClique(list_of(4)(2)(3), 3,
719  list_of(
720  MakeClique(list_of(1)(2)(4), 1,
721  list_of(
722  MakeClique(list_of(5)(1)(4), 1,
723  list_of(MakeClique(list_of(0)(1)(5), 1))))))));
724 
725  SymbolicBayesTree actual = *sfg.eliminateMultifrontal(ordering);
726  EXPECT(assert_equal(expected, actual));
727  }
728 
729 #ifdef GTSAM_SUPPORT_NESTED_DISSECTION
730  // METIS
731  {
732  Ordering ordering = Ordering::Create(Ordering::METIS, sfg);
733 // Linux and Mac split differently when using mettis
734 #if !defined(__APPLE__)
735  EXPECT(assert_equal(Ordering(list_of(3)(2)(5)(0)(4)(1)), ordering));
736 #else
737  EXPECT(assert_equal(Ordering(list_of(5)(4)(2)(1)(0)(3)), ordering));
738 #endif
739 
740  // - P( 1 0 3)
741  // | - P( 4 | 0 3)
742  // | | - P( 5 | 0 4)
743  // | - P( 2 | 1 3)
745 #if !defined(__APPLE__)
746  expected.insertRoot(
747  MakeClique(list_of(2)(4)(1), 3,
748  list_of(
749  MakeClique(list_of(0)(1)(4), 1,
750  list_of(MakeClique(list_of(5)(0)(4), 1))))(
751  MakeClique(list_of(3)(2)(4), 1))));
752 #else
753  expected.insertRoot(
754  MakeClique(list_of(1)(0)(3), 3,
755  list_of(
756  MakeClique(list_of(4)(0)(3), 1,
757  list_of(MakeClique(list_of(5)(0)(4), 1))))(
758  MakeClique(list_of(2)(1)(3), 1))));
759 #endif
760  SymbolicBayesTree actual = *sfg.eliminateMultifrontal(ordering);
761  EXPECT(assert_equal(expected, actual));
762  }
763 #endif
764 }
765 
766 /* ************************************************************************* */
767 int main() {
768  TestResult tr;
769  return TestRegistry::runAllTests(tr);
770 }
771 /* ************************************************************************* */
772 
void removePath(sharedClique clique, BayesNetType *bn, Cliques *orphans)
Provides additional testing facilities for common data structures.
int main()
#define CHECK(condition)
Definition: Test.h:109
boost::shared_ptr< This > shared_ptr
GTSAM_EXPORT void saveGraph(const std::string &s, const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
void removeTop(const KeyVector &keys, BayesNetType *bn, Cliques *orphans)
Key E(std::uint64_t j)
static const Key _C_
static int runAllTests(TestResult &result)
boost::shared_ptr< This > shared_ptr
static enum @843 ordering
Matrix expected
Definition: testMatrix.cpp:974
boost::shared_ptr< BayesTreeType > eliminateMultifrontal(OptionalOrderingType orderingType=boost::none, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex=boost::none) const
KeySet keys() const
static bool debug
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
Rot2 R(Rot2::fromAngle(0.1))
MatrixXd L
Definition: LLT_example.cpp:6
Definition: Half.h:150
GaussianFactorGraph factors(list_of(factor1)(factor2)(factor3))
static const Key _L_
IsDerived< DERIVEDFACTOR > push_back(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:166
const mpreal root(const mpreal &x, unsigned long int k, mp_rnd_t r=mpreal::get_default_rnd())
Definition: mpreal.h:2194
NonlinearFactorGraph graph
Matrix< SCALARB, Dynamic, Dynamic > B
Definition: bench_gemm.cpp:36
ptrdiff_t DenseIndex
The index type for Eigen objects.
Definition: types.h:67
void insertRoot(const sharedClique &subtree)
sharedConditional marginalFactor(Key j, const Eliminate &function=EliminationTraitsType::DefaultEliminate) const
Signature::Row F
Definition: Signature.cpp:53
sharedBayesNet jointBayesNet(Key j1, Key j2, const Eliminate &function=EliminationTraitsType::DefaultEliminate) const
#define EXPECT(condition)
Definition: Test.h:151
void saveGraph(const std::string &s, const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
static const Key _D_
boost::shared_ptr< This > shared_ptr
Array< double, 1, 3 > e(1./3., 0.5, 2.)
bool assert_container_equal(const std::map< V1, V2 > &expected, const std::map< V1, V2 > &actual, double tol=1e-9)
Matrix< Scalar, Dynamic, Dynamic > C
Definition: bench_gemm.cpp:37
static const Key _B_
traits
Definition: chartTesting.h:28
bool assert_equal(const Matrix &expected, const Matrix &actual, double tol)
Definition: Matrix.cpp:42
#define GTSAM_PRINT(x)
Definition: Testable.h:41
#define EXPECT_LONGS_EQUAL(expected, actual)
Definition: Test.h:155
void getAllCliques(const SymbolicBayesTree::sharedClique &subtree, SymbolicBayesTree::Cliques &cliques)
boost::shared_ptr< BayesNetType > eliminateSequential(OptionalOrderingType orderingType=boost::none, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex=boost::none) const
TEST(SymbolicBayesTree, clear)
const KeyVector keys
static const Key _A_
#define X
Definition: icosphere.cpp:20
const Roots & roots() const
Definition: BayesTree.h:147
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:61


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:49:57