testHybridEstimation.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 
19 #include <gtsam/geometry/Pose2.h>
20 #include <gtsam/geometry/Pose3.h>
27 #include <gtsam/inference/Symbol.h>
36 
37 // Include for test suite
39 
40 #include <bitset>
41 
42 #include "Switching.h"
43 
44 using namespace std;
45 using namespace gtsam;
46 
49 
50 TEST(HybridEstimation, Full) {
51  size_t K = 6;
52  std::vector<double> measurements = {0, 1, 2, 2, 2, 3};
53  // Ground truth discrete seq
54  std::vector<size_t> discrete_seq = {1, 1, 0, 0, 1};
55  // Switching example of robot moving in 1D
56  // with given measurements and equal mode priors.
57  Switching switching(K, 1.0, 0.1, measurements, "1/1 1/1");
59 
60  Ordering hybridOrdering;
61  for (size_t k = 0; k < K; k++) {
62  hybridOrdering.push_back(X(k));
63  }
64  for (size_t k = 0; k < K - 1; k++) {
65  hybridOrdering.push_back(M(k));
66  }
67 
68  HybridBayesNet::shared_ptr bayesNet = graph.eliminateSequential();
69 
70  EXPECT_LONGS_EQUAL(2 * K - 1, bayesNet->size());
71 
73 
74  Values initial = switching.linearizationPoint;
75  Values result = initial.retract(delta.continuous());
76 
77  DiscreteValues expected_discrete;
78  for (size_t k = 0; k < K - 1; k++) {
79  expected_discrete[M(k)] = discrete_seq[k];
80  }
81  EXPECT(assert_equal(expected_discrete, delta.discrete()));
82 
83  Values expected_continuous;
84  for (size_t k = 0; k < K; k++) {
85  expected_continuous.insert(X(k), measurements[k]);
86  }
87  EXPECT(assert_equal(expected_continuous, result));
88 }
89 
90 /****************************************************************************/
91 // Test approximate inference with an additional pruning step.
92 TEST(HybridEstimation, IncrementalSmoother) {
93  size_t K = 15;
94  std::vector<double> measurements = {0, 1, 2, 2, 2, 2, 3, 4, 5, 6, 6,
95  7, 8, 9, 9, 9, 10, 11, 11, 11, 11};
96  // Ground truth discrete seq
97  std::vector<size_t> discrete_seq = {1, 1, 0, 0, 0, 1, 1, 1, 1, 0,
98  1, 1, 1, 0, 0, 1, 1, 0, 0, 0};
99  // Switching example of robot moving in 1D
100  // with given measurements and equal mode priors.
101  Switching switching(K, 1.0, 0.1, measurements, "1/1 1/1");
102  HybridSmoother smoother;
104  Values initial;
105 
106  // Add the X(0) prior
107  graph.push_back(switching.nonlinearFactorGraph.at(0));
108  initial.insert(X(0), switching.linearizationPoint.at<double>(X(0)));
109 
110  HybridGaussianFactorGraph linearized;
111 
112  for (size_t k = 1; k < K; k++) {
113  // Motion Model
114  graph.push_back(switching.nonlinearFactorGraph.at(k));
115  // Measurement
116  graph.push_back(switching.nonlinearFactorGraph.at(k + K - 1));
117 
118  initial.insert(X(k), switching.linearizationPoint.at<double>(X(k)));
119 
120  linearized = *graph.linearize(initial);
121  Ordering ordering = smoother.getOrdering(linearized);
122 
123  smoother.update(linearized, 3, ordering);
124  graph.resize(0);
125  }
126 
127  HybridValues delta = smoother.hybridBayesNet().optimize();
128 
129  Values result = initial.retract(delta.continuous());
130 
131  DiscreteValues expected_discrete;
132  for (size_t k = 0; k < K - 1; k++) {
133  expected_discrete[M(k)] = discrete_seq[k];
134  }
135  EXPECT(assert_equal(expected_discrete, delta.discrete()));
136 
137  Values expected_continuous;
138  for (size_t k = 0; k < K; k++) {
139  expected_continuous.insert(X(k), measurements[k]);
140  }
141  EXPECT(assert_equal(expected_continuous, result));
142 }
143 
144 /****************************************************************************/
145 // Test approximate inference with an additional pruning step.
146 TEST(HybridEstimation, ISAM) {
147  size_t K = 15;
148  std::vector<double> measurements = {0, 1, 2, 2, 2, 2, 3, 4, 5, 6, 6,
149  7, 8, 9, 9, 9, 10, 11, 11, 11, 11};
150  // Ground truth discrete seq
151  std::vector<size_t> discrete_seq = {1, 1, 0, 0, 0, 1, 1, 1, 1, 0,
152  1, 1, 1, 0, 0, 1, 1, 0, 0, 0};
153  // Switching example of robot moving in 1D
154  // with given measurements and equal mode priors.
155  Switching switching(K, 1.0, 0.1, measurements, "1/1 1/1");
158  Values initial;
159 
160  // gttic_(Estimation);
161 
162  // Add the X(0) prior
163  graph.push_back(switching.nonlinearFactorGraph.at(0));
164  initial.insert(X(0), switching.linearizationPoint.at<double>(X(0)));
165 
166  HybridGaussianFactorGraph linearized;
167 
168  for (size_t k = 1; k < K; k++) {
169  // Motion Model
170  graph.push_back(switching.nonlinearFactorGraph.at(k));
171  // Measurement
172  graph.push_back(switching.nonlinearFactorGraph.at(k + K - 1));
173 
174  initial.insert(X(k), switching.linearizationPoint.at<double>(X(k)));
175 
176  isam.update(graph, initial, 3);
177  // isam.bayesTree().print("\n\n");
178 
179  graph.resize(0);
180  initial.clear();
181  }
182 
184  DiscreteValues assignment = isam.assignment();
185 
186  DiscreteValues expected_discrete;
187  for (size_t k = 0; k < K - 1; k++) {
188  expected_discrete[M(k)] = discrete_seq[k];
189  }
190  EXPECT(assert_equal(expected_discrete, assignment));
191 
192  Values expected_continuous;
193  for (size_t k = 0; k < K; k++) {
194  expected_continuous.insert(X(k), measurements[k]);
195  }
196  EXPECT(assert_equal(expected_continuous, result));
197 }
198 
212  size_t K, const std::vector<double>& measurements,
213  const std::vector<size_t>& discrete_seq, double measurement_sigma = 0.1,
214  double between_sigma = 1.0) {
216  Values linearizationPoint;
217 
218  // Add measurement factors
219  auto measurement_noise = noiseModel::Isotropic::Sigma(1, measurement_sigma);
220  for (size_t k = 0; k < K; k++) {
221  graph.emplace_shared<PriorFactor<double>>(X(k), measurements.at(k),
222  measurement_noise);
223  linearizationPoint.insert<double>(X(k), static_cast<double>(k + 1));
224  }
225 
227 
228  // Add "motion models".
229  auto motion_noise_model = noiseModel::Isotropic::Sigma(1, between_sigma);
230  for (size_t k = 0; k < K - 1; k++) {
231  auto motion_model = std::make_shared<MotionModel>(
232  X(k), X(k + 1), discrete_seq.at(k), motion_noise_model);
233  graph.push_back(motion_model);
234  }
235  GaussianFactorGraph::shared_ptr linear_graph =
236  graph.linearize(linearizationPoint);
237  return linear_graph;
238 }
239 
247 template <size_t K>
248 std::vector<size_t> getDiscreteSequence(size_t x) {
249  std::bitset<K - 1> seq = x;
250  std::vector<size_t> discrete_seq(K - 1);
251  for (size_t i = 0; i < K - 1; i++) {
252  // Save to discrete vector in reverse order
253  discrete_seq[K - 2 - i] = seq[i];
254  }
255  return discrete_seq;
256 }
257 
270  Ordering continuous(graph.continuousKeySet());
271  const auto [bayesNet, remainingGraph] =
272  graph.eliminatePartialSequential(continuous);
273 
274  auto last_conditional = bayesNet->at(bayesNet->size() - 1);
275  DiscreteKeys discrete_keys = last_conditional->discreteKeys();
276 
277  const std::vector<DiscreteValues> assignments =
278  DiscreteValues::CartesianProduct(discrete_keys);
279 
280  std::reverse(discrete_keys.begin(), discrete_keys.end());
281 
282  vector<VectorValues::shared_ptr> vector_values;
283  for (const DiscreteValues& assignment : assignments) {
284  VectorValues values = bayesNet->optimize(assignment);
285  vector_values.push_back(std::make_shared<VectorValues>(values));
286  }
287  DecisionTree<Key, VectorValues::shared_ptr> delta_tree(discrete_keys,
288  vector_values);
289 
290  // Get the probPrime tree with the correct leaf probabilities
291  std::vector<double> probPrimes;
292  for (const DiscreteValues& assignment : assignments) {
293  VectorValues delta = *delta_tree(assignment);
294 
295  // If VectorValues is empty, it means this is a pruned branch.
296  // Set the probPrime to 0.0.
297  if (delta.size() == 0) {
298  probPrimes.push_back(0.0);
299  continue;
300  }
301 
302  double error = graph.error({delta, assignment});
303  probPrimes.push_back(exp(-error));
304  }
305  AlgebraicDecisionTree<Key> probPrimeTree(discrete_keys, probPrimes);
306  return probPrimeTree;
307 }
308 
309 /*********************************************************************************
310  * Test for correctness of different branches of the P'(Continuous | Discrete).
311  * The values should match those of P'(Continuous) for each discrete mode.
312  ********************************************************************************/
313 TEST(HybridEstimation, Probability) {
314  constexpr size_t K = 4;
315  std::vector<double> measurements = {0, 1, 2, 2};
316  double between_sigma = 1.0, measurement_sigma = 0.1;
317 
318  // Switching example of robot moving in 1D with
319  // given measurements and equal mode priors.
320  Switching switching(K, between_sigma, measurement_sigma, measurements,
321  "1/1 1/1");
322  auto graph = switching.linearizedFactorGraph;
323 
324  // Continuous elimination
325  Ordering continuous_ordering(graph.continuousKeySet());
326  auto [bayesNet, discreteGraph] =
327  graph.eliminatePartialSequential(continuous_ordering);
328 
329  // Discrete elimination
330  Ordering discrete_ordering(graph.discreteKeySet());
331  auto discreteBayesNet = discreteGraph->eliminateSequential(discrete_ordering);
332 
333  // Add the discrete conditionals to make it a full bayes net.
334  for (auto discrete_conditional : *discreteBayesNet) {
335  bayesNet->add(discrete_conditional);
336  }
337 
338  HybridValues hybrid_values = bayesNet->optimize();
339 
340  // This is the correct sequence as designed
341  DiscreteValues discrete_seq;
342  discrete_seq[M(0)] = 1;
343  discrete_seq[M(1)] = 1;
344  discrete_seq[M(2)] = 0;
345 
346  EXPECT(assert_equal(discrete_seq, hybrid_values.discrete()));
347 }
348 
349 /****************************************************************************/
355 TEST(HybridEstimation, ProbabilityMultifrontal) {
356  constexpr size_t K = 4;
357  std::vector<double> measurements = {0, 1, 2, 2};
358 
359  double between_sigma = 1.0, measurement_sigma = 0.1;
360 
361  // Switching example of robot moving in 1D with given measurements and equal
362  // mode priors.
363  Switching switching(K, between_sigma, measurement_sigma, measurements,
364  "1/1 1/1");
365  auto graph = switching.linearizedFactorGraph;
366 
367  // Get the tree of unnormalized probabilities for each mode sequence.
368  AlgebraicDecisionTree<Key> expected_probPrimeTree = getProbPrimeTree(graph);
369 
370  // Eliminate continuous
371  Ordering continuous_ordering(graph.continuousKeySet());
372  const auto [bayesTree, discreteGraph] =
373  graph.eliminatePartialMultifrontal(continuous_ordering);
374 
375  // Get the last continuous conditional which will have all the discrete keys
376  Key last_continuous_key =
377  continuous_ordering.at(continuous_ordering.size() - 1);
378  auto last_conditional = (*bayesTree)[last_continuous_key]->conditional();
379  DiscreteKeys discrete_keys = last_conditional->discreteKeys();
380 
381  Ordering discrete(graph.discreteKeySet());
382  auto discreteBayesTree = discreteGraph->eliminateMultifrontal(discrete);
383 
384  EXPECT_LONGS_EQUAL(1, discreteBayesTree->size());
385  // DiscreteBayesTree should have only 1 clique
386  auto discrete_clique = (*discreteBayesTree)[discrete.at(0)];
387 
388  std::set<HybridBayesTreeClique::shared_ptr> clique_set;
389  for (auto node : bayesTree->nodes()) {
390  clique_set.insert(node.second);
391  }
392 
393  // Set the root of the bayes tree as the discrete clique
394  for (auto clique : clique_set) {
395  if (clique->conditional()->parents() ==
396  discrete_clique->conditional()->frontals()) {
397  discreteBayesTree->addClique(clique, discrete_clique);
398 
399  } else {
400  // Remove the clique from the children of the parents since
401  // it will get added again in addClique.
402  auto clique_it = std::find(clique->parent()->children.begin(),
403  clique->parent()->children.end(), clique);
404  clique->parent()->children.erase(clique_it);
405  discreteBayesTree->addClique(clique, clique->parent());
406  }
407  }
408 
409  HybridValues hybrid_values = discreteBayesTree->optimize();
410 
411  // This is the correct sequence as designed
412  DiscreteValues discrete_seq;
413  discrete_seq[M(0)] = 1;
414  discrete_seq[M(1)] = 1;
415  discrete_seq[M(2)] = 0;
416 
417  EXPECT(assert_equal(discrete_seq, hybrid_values.discrete()));
418 }
419 
420 /*********************************************************************************
421  // Create a hybrid nonlinear factor graph f(x0, x1, m0; z0, z1)
422  ********************************************************************************/
425 
426  constexpr double sigma = 0.5; // measurement noise
427  const auto noise_model = noiseModel::Isotropic::Sigma(1, sigma);
428 
429  // Add "measurement" factors:
432 
433  // Add hybrid nonlinear factor:
434  DiscreteKey m(M(0), 2);
435  const auto zero_motion =
436  std::make_shared<BetweenFactor<double>>(X(0), X(1), 0, noise_model);
437  const auto one_motion =
438  std::make_shared<BetweenFactor<double>>(X(0), X(1), 1, noise_model);
439  std::vector<NoiseModelFactor::shared_ptr> components = {zero_motion,
440  one_motion};
442 
443  return nfg;
444 }
445 
446 /*********************************************************************************
447  // Create a hybrid linear factor graph f(x0, x1, m0; z0, z1)
448  ********************************************************************************/
451 
452  Values initial;
453  double z0 = 0.0, z1 = 1.0;
454  initial.insert<double>(X(0), z0);
455  initial.insert<double>(X(1), z1);
456  return nfg.linearize(initial);
457 }
458 
459 /*********************************************************************************
460  * Do hybrid elimination and do regression test on discrete conditional.
461  ********************************************************************************/
462 TEST(HybridEstimation, eliminateSequentialRegression) {
463  // Create the factor graph from the nonlinear factor graph.
465 
466  // Create expected discrete conditional on m0.
467  DiscreteKey m(M(0), 2);
468  DiscreteConditional expected(m % "0.51341712/1"); // regression
469 
470  // Eliminate into BN using one ordering
471  const Ordering ordering1{X(0), X(1), M(0)};
472  HybridBayesNet::shared_ptr bn1 = fg->eliminateSequential(ordering1);
473 
474  // Check that the discrete conditional matches the expected.
475  auto dc1 = bn1->back()->asDiscrete();
476  EXPECT(assert_equal(expected, *dc1, 1e-9));
477 
478  // Eliminate into BN using a different ordering
479  const Ordering ordering2{X(0), X(1), M(0)};
480  HybridBayesNet::shared_ptr bn2 = fg->eliminateSequential(ordering2);
481 
482  // Check that the discrete conditional matches the expected.
483  auto dc2 = bn2->back()->asDiscrete();
484  EXPECT(assert_equal(expected, *dc2, 1e-9));
485 }
486 
487 /*********************************************************************************
488  * Test for correctness via sampling.
489  *
490  * Compute the conditional P(x0, m0, x1| z0, z1)
491  * with measurements z0, z1. To do so, we:
492  * 1. Start with the corresponding Factor Graph `FG`.
493  * 2. Eliminate the factor graph into a Bayes Net `BN`.
494  * 3. Sample from the Bayes Net.
495  * 4. Check that the ratio `BN(x)/FG(x) = constant` for all samples `x`.
496  ********************************************************************************/
497 TEST(HybridEstimation, CorrectnessViaSampling) {
498  // 1. Create the factor graph from the nonlinear factor graph.
499  const auto fg = createHybridGaussianFactorGraph();
500 
501  // 2. Eliminate into BN
502  const HybridBayesNet::shared_ptr bn = fg->eliminateSequential();
503 
504  // Set up sampling
505  std::mt19937_64 rng(11);
506 
507  // Compute the log-ratio between the Bayes net and the factor graph.
508  auto compute_ratio = [&](const HybridValues& sample) -> double {
509  return bn->evaluate(sample) / fg->probPrime(sample);
510  };
511 
512  // The error evaluated by the factor graph and the Bayes net should differ by
513  // the normalizing term computed via the Bayes net determinant.
514  const HybridValues sample = bn->sample(&rng);
515  double expected_ratio = compute_ratio(sample);
516  // regression
517  EXPECT_DOUBLES_EQUAL(0.728588, expected_ratio, 1e-6);
518 
519  // 3. Do sampling
520  constexpr int num_samples = 10;
521  for (size_t i = 0; i < num_samples; i++) {
522  // Sample from the bayes net
523  const HybridValues sample = bn->sample(&rng);
524 
525  // 4. Check that the ratio is constant.
526  EXPECT_DOUBLES_EQUAL(expected_ratio, compute_ratio(sample), 1e-6);
527  }
528 }
529 
530 /****************************************************************************/
531 TEST(HybridEstimation, ModeSelection) {
533  Values initial;
534 
535  auto measurement_model = noiseModel::Isotropic::Sigma(1, 0.1);
536  auto motion_model = noiseModel::Isotropic::Sigma(1, 1.0);
537 
538  graph.emplace_shared<PriorFactor<double>>(X(0), 0.0, measurement_model);
539  graph.emplace_shared<PriorFactor<double>>(X(1), 0.0, measurement_model);
540 
541  // The size of the noise model
542  size_t d = 1;
543  double noise_tight = 0.5, noise_loose = 5.0;
544 
545  auto model0 = std::make_shared<MotionModel>(
546  X(0), X(1), 0.0, noiseModel::Isotropic::Sigma(d, noise_loose)),
547  model1 = std::make_shared<MotionModel>(
548  X(0), X(1), 0.0, noiseModel::Isotropic::Sigma(d, noise_tight));
549  std::vector<NoiseModelFactor::shared_ptr> components = {model0, model1};
550 
552 
553  initial.insert(X(0), 0.0);
554  initial.insert(X(1), 0.0);
555 
556  auto gmf = mf.linearize(initial);
557  graph.add(gmf);
558 
559  auto gfg = graph.linearize(initial);
560 
561  HybridBayesNet::shared_ptr bayesNet = gfg->eliminateSequential();
562 
564  EXPECT_LONGS_EQUAL(1, delta.discrete().at(M(0)));
565 
566  /**************************************************************/
567  HybridBayesNet bn;
568  const DiscreteKey mode(M(0), 2);
569 
570  bn.push_back(
571  GaussianConditional::sharedMeanAndStddev(Z(0), -I_1x1, X(0), Z_1x1, 0.1));
572  bn.push_back(
573  GaussianConditional::sharedMeanAndStddev(Z(0), -I_1x1, X(1), Z_1x1, 0.1));
574 
575  std::vector<std::pair<Vector, double>> parameters{{Z_1x1, noise_loose},
576  {Z_1x1, noise_tight}};
577  bn.emplace_shared<HybridGaussianConditional>(mode, Z(0), I_1x1, X(0), -I_1x1,
578  X(1), parameters);
579 
581  vv.insert(Z(0), Z_1x1);
582 
583  auto fg = bn.toFactorGraph(vv);
584  auto expected_posterior = fg.eliminateSequential();
585 
586  EXPECT(assert_equal(*expected_posterior, *bayesNet, 1e-6));
587 }
588 
589 /****************************************************************************/
590 TEST(HybridEstimation, ModeSelection2) {
591  using symbol_shorthand::Z;
592 
593  // The size of the noise model
594  size_t d = 3;
595  double noise_tight = 0.5, noise_loose = 5.0;
596 
597  HybridBayesNet bn;
598  const DiscreteKey mode(M(0), 2);
599 
600  bn.push_back(
601  GaussianConditional::sharedMeanAndStddev(Z(0), -I_3x3, X(0), Z_3x1, 0.1));
602  bn.push_back(
603  GaussianConditional::sharedMeanAndStddev(Z(0), -I_3x3, X(1), Z_3x1, 0.1));
604 
605  std::vector<std::pair<Vector, double>> parameters{{Z_3x1, noise_loose},
606  {Z_3x1, noise_tight}};
607  bn.emplace_shared<HybridGaussianConditional>(mode, Z(0), I_3x3, X(0), -I_3x3,
608  X(1), parameters);
609 
611  vv.insert(Z(0), Z_3x1);
612 
613  auto fg = bn.toFactorGraph(vv);
614 
615  auto expected_posterior = fg.eliminateSequential();
616 
617  // =====================================
618 
620  Values initial;
621 
622  auto measurement_model = noiseModel::Isotropic::Sigma(d, 0.1);
623  auto motion_model = noiseModel::Isotropic::Sigma(d, 1.0);
624 
625  graph.emplace_shared<PriorFactor<Vector3>>(X(0), Z_3x1, measurement_model);
626  graph.emplace_shared<PriorFactor<Vector3>>(X(1), Z_3x1, measurement_model);
627 
628  auto model0 = std::make_shared<BetweenFactor<Vector3>>(
629  X(0), X(1), Z_3x1, noiseModel::Isotropic::Sigma(d, noise_loose)),
631  X(0), X(1), Z_3x1, noiseModel::Isotropic::Sigma(d, noise_tight));
632  std::vector<NoiseModelFactor::shared_ptr> components = {model0, model1};
633 
635 
636  initial.insert<Vector3>(X(0), Z_3x1);
637  initial.insert<Vector3>(X(1), Z_3x1);
638 
639  auto gmf = mf.linearize(initial);
640  graph.add(gmf);
641 
642  auto gfg = graph.linearize(initial);
643 
644  HybridBayesNet::shared_ptr bayesNet = gfg->eliminateSequential();
645 
646  EXPECT(assert_equal(*expected_posterior, *bayesNet, 1e-6));
647 }
648 
649 /* ************************************************************************* */
650 int main() {
651  TestResult tr;
652  return TestRegistry::runAllTests(tr);
653 }
654 /* ************************************************************************* */
TestRegistry::runAllTests
static int runAllTests(TestResult &result)
Definition: TestRegistry.cpp:27
gtsam::HybridSmoother::hybridBayesNet
const HybridBayesNet & hybridBayesNet() const
Return the Bayes Net posterior.
Definition: HybridSmoother.cpp:147
gtsam::HybridGaussianFactorGraph::shared_ptr
std::shared_ptr< This > shared_ptr
shared_ptr to This
Definition: HybridGaussianFactorGraph.h:118
gtsam::HybridSmoother::update
void update(HybridGaussianFactorGraph graph, std::optional< size_t > maxNrLeaves={}, const std::optional< Ordering > given_ordering={})
Definition: HybridSmoother.cpp:59
gtsam::EliminateableFactorGraph::eliminateSequential
std::shared_ptr< BayesNetType > eliminateSequential(OptionalOrderingType orderingType={}, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex={}) const
Definition: EliminateableFactorGraph-inst.h:29
Pose2.h
2D Pose
DiscreteBayesNet.h
GaussianFactorGraph.h
Linear Factor Graph where all factors are Gaussians.
gtsam::HybridValues
Definition: HybridValues.h:37
gtsam::GaussianFactorGraph::shared_ptr
std::shared_ptr< This > shared_ptr
shared_ptr to this class
Definition: GaussianFactorGraph.h:82
rng
static std::mt19937 rng
Definition: timeFactorOverhead.cpp:31
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
d
static const double d[K][N]
Definition: igam.h:11
EXPECT_LONGS_EQUAL
#define EXPECT_LONGS_EQUAL(expected, actual)
Definition: Test.h:154
EXPECT
#define EXPECT(condition)
Definition: Test.h:150
gtsam::Z_3x1
static const Eigen::MatrixBase< Vector3 >::ConstantReturnType Z_3x1
Definition: Vector.h:46
HybridNonlinearFactorGraph.h
Nonlinear hybrid factor graph that uses type erasure.
main
int main()
Definition: testHybridEstimation.cpp:650
TestHarness.h
gtsam::HybridBayesNet
Definition: HybridBayesNet.h:36
gtsam::HybridNonlinearFactorGraph
Definition: HybridNonlinearFactorGraph.h:33
gtsam::VectorValues::insert
iterator insert(const std::pair< Key, Vector > &key_value)
Definition: VectorValues.cpp:88
z1
Point2 z1
Definition: testTriangulationFactor.cpp:45
initial
Values initial
Definition: OdometryOptimize.cpp:2
Switching.h
x
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
Definition: gnuplot_common_settings.hh:12
gtsam::PriorFactor
Definition: nonlinear/PriorFactor.h:30
HybridBayesNet.h
A Bayes net of Gaussian Conditionals indexed by discrete keys.
createHybridNonlinearFactorGraph
static HybridNonlinearFactorGraph createHybridNonlinearFactorGraph()
Definition: testHybridEstimation.cpp:423
different_sigmas::values
HybridValues values
Definition: testHybridBayesNet.cpp:195
gtsam::NonlinearFactorGraph::linearize
std::shared_ptr< GaussianFactorGraph > linearize(const Values &linearizationPoint) const
Linearize a nonlinear factor graph.
Definition: NonlinearFactorGraph.cpp:239
X
#define X
Definition: icosphere.cpp:20
gtsam::DiscreteKeys
DiscreteKeys is a set of keys that can be assembled using the & operator.
Definition: DiscreteKey.h:41
GaussianBayesNet.h
Chordal Bayes Net, the result of eliminating a factor graph.
vv
static const VectorValues vv
Definition: testHybridGaussianConditional.cpp:41
gtsam::Vector3
Eigen::Vector3d Vector3
Definition: Vector.h:43
exp
const EIGEN_DEVICE_FUNC ExpReturnType exp() const
Definition: ArrayCwiseUnaryOps.h:97
result
Values result
Definition: OdometryOptimize.cpp:8
HybridGaussianFactor.h
A set of GaussianFactors, indexed by a set of discrete keys.
test_motion::noise_model
auto noise_model
Definition: testHybridNonlinearFactorGraph.cpp:119
HybridSmoother.h
An incremental smoother for hybrid factor graphs.
gtsam::NonlinearISAM::update
void update(const NonlinearFactorGraph &newFactors, const Values &initialValues)
Definition: NonlinearISAM.cpp:35
sampling::sigma
static const double sigma
Definition: testGaussianBayesNet.cpp:170
specificModesFactorGraph
GaussianFactorGraph::shared_ptr specificModesFactorGraph(size_t K, const std::vector< double > &measurements, const std::vector< size_t > &discrete_seq, double measurement_sigma=0.1, double between_sigma=1.0)
A function to get a specific 1D robot motion problem as a linearized factor graph....
Definition: testHybridEstimation.cpp:211
gtsam::AlgebraicDecisionTree< Key >
gtsam::Switching
ϕ(X(0)) .. ϕ(X(k),X(k+1)) .. ϕ(X(k);z_k) .. ϕ(M(0)) .. ϕ(M(k),M(k+1))
Definition: Switching.h:122
gtsam::FactorGraph::at
const sharedFactor at(size_t i) const
Definition: FactorGraph.h:306
gtsam::HybridBayesNet::optimize
HybridValues optimize() const
Solve the HybridBayesNet by first computing the MPE of all the discrete variables and then optimizing...
Definition: HybridBayesNet.cpp:223
gtsam::NonlinearFactorGraph::error
double error(const Values &values) const
Definition: NonlinearFactorGraph.cpp:170
gtsam::Values::at
const ValueType at(Key j) const
Definition: Values-inl.h:261
PriorFactor.h
gtsam::FactorGraph::resize
virtual void resize(size_t size)
Definition: FactorGraph.h:367
different_sigmas::bayesNet
const HybridBayesNet bayesNet
Definition: testHybridBayesNet.cpp:192
gtsam.examples.PlanarManipulatorExample.delta
def delta(g0, g1)
Definition: PlanarManipulatorExample.py:45
gtsam::VectorValues
Definition: VectorValues.h:74
BetweenFactor.h
mode
static const DiscreteKey mode(modeKey, 2)
parameters
static ConjugateGradientParameters parameters
Definition: testIterative.cpp:33
isam
NonlinearISAM isam(relinearizeInterval)
gtsam::NonlinearFactorGraph
Definition: NonlinearFactorGraph.h:55
gtsam::make_shared
gtsam::enable_if_t< needs_eigen_aligned_allocator< T >::value, std::shared_ptr< T > > make_shared(Args &&... args)
Definition: make_shared.h:56
cholesky::expected
Matrix expected
Definition: testMatrix.cpp:971
gtsam::HybridGaussianConditional
A conditional of gaussian conditionals indexed by discrete variables, as part of a Bayes Network....
Definition: HybridGaussianConditional.h:53
gtsam::HybridGaussianFactorGraph
Definition: HybridGaussianFactorGraph.h:104
mf
Matrix2f mf
Definition: MatrixBase_cast.cpp:2
gtsam::HybridNonlinearISAM
Definition: HybridNonlinearISAM.h:29
gtsam::NonlinearISAM::estimate
Values estimate() const
Definition: NonlinearISAM.cpp:80
Symbol.h
TEST
TEST(HybridEstimation, Full)
Definition: testHybridEstimation.cpp:50
m
Matrix3f m
Definition: AngleAxis_mimic_euler.cpp:1
gtsam::HybridSmoother::getOrdering
Ordering getOrdering(const HybridGaussianFactorGraph &newFactors)
Definition: HybridSmoother.cpp:27
EXPECT_DOUBLES_EQUAL
#define EXPECT_DOUBLES_EQUAL(expected, actual, threshold)
Definition: Test.h:161
ordering
static enum @1096 ordering
TestResult
Definition: TestResult.h:26
JacobianFactor.h
gtsam::FactorGraph::size
size_t size() const
Definition: FactorGraph.h:297
gtsam::DecisionTree
a decision tree is a function from assignments to values.
Definition: DecisionTree.h:63
gtsam::HybridSmoother
Definition: HybridSmoother.h:27
HybridNonlinearFactor.h
A set of nonlinear factors indexed by a set of discrete keys.
gtsam::HybridBayesNet::push_back
void push_back(std::shared_ptr< HybridConditional > conditional)
Add a hybrid conditional using a shared_ptr.
Definition: HybridBayesNet.h:75
gtsam::DiscreteConditional
Definition: DiscreteConditional.h:37
gtsam
traits
Definition: chartTesting.h:28
error
static double error
Definition: testRot3.cpp:37
NoiseModel.h
K
#define K
Definition: igam.h:8
NonlinearFactorGraph.h
Factor Graph consisting of non-linear factors.
gtsam::DiscreteValues
Definition: DiscreteValues.h:34
gtsam::FactorGraph::push_back
IsDerived< DERIVEDFACTOR > push_back(std::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:147
gtsam::Values
Definition: Values.h:65
gtsam::DiscreteKey
std::pair< Key, size_t > DiscreteKey
Definition: DiscreteKey.h:38
std
Definition: BFloat16.h:88
gtsam::Switching::linearizationPoint
Values linearizationPoint
Definition: Switching.h:127
gtsam::HybridValues::discrete
const DiscreteValues & discrete() const
Return the discrete values.
Definition: HybridValues.cpp:57
getDiscreteSequence
std::vector< size_t > getDiscreteSequence(size_t x)
Get the discrete sequence from the integer x.
Definition: testHybridEstimation.cpp:248
gtsam::Values::insert
void insert(Key j, const Value &val)
Definition: Values.cpp:155
gtsam::HybridNonlinearFactorGraph::linearize
std::shared_ptr< HybridGaussianFactorGraph > linearize(const Values &continuousValues) const
Linearize all the continuous factors in the HybridNonlinearFactorGraph.
Definition: HybridNonlinearFactorGraph.cpp:139
GaussianBayesTree.h
Gaussian Bayes Tree, the result of eliminating a GaussianJunctionTree.
gtsam::assert_equal
bool assert_equal(const Matrix &expected, const Matrix &actual, double tol)
Definition: Matrix.cpp:40
HybridNonlinearISAM.h
gtsam::Switching::linearizedFactorGraph
HybridGaussianFactorGraph linearizedFactorGraph
Definition: Switching.h:126
initial
Definition: testScenarioRunner.cpp:148
gtsam::ISAM
Definition: ISAM.h:31
reverse
void reverse(const MatrixType &m)
Definition: array_reverse.cpp:16
test_motion::components
std::vector< NoiseModelFactor::shared_ptr > components
Definition: testHybridNonlinearFactorGraph.cpp:120
gtsam::HybridBayesNet::shared_ptr
std::shared_ptr< HybridBayesNet > shared_ptr
Definition: HybridBayesNet.h:41
getProbPrimeTree
AlgebraicDecisionTree< Key > getProbPrimeTree(const HybridGaussianFactorGraph &graph)
Helper method to get the tree of unnormalized probabilities as per the elimination scheme.
Definition: testHybridEstimation.cpp:268
gtsam::HybridBayesNet::toFactorGraph
HybridGaussianFactorGraph toFactorGraph(const VectorValues &measurements) const
Definition: HybridBayesNet.cpp:362
gtsam::FactorGraph::add
IsDerived< DERIVEDFACTOR > add(std::shared_ptr< DERIVEDFACTOR > factor)
add is a synonym for push_back.
Definition: FactorGraph.h:171
graph
NonlinearFactorGraph graph
Definition: doc/Code/OdometryExample.cpp:2
createHybridGaussianFactorGraph
static HybridGaussianFactorGraph::shared_ptr createHybridGaussianFactorGraph()
Definition: testHybridEstimation.cpp:449
model1
noiseModel::Isotropic::shared_ptr model1
Definition: testEssentialMatrixFactor.cpp:26
gtsam::Key
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:97
Z
#define Z
Definition: icosphere.cpp:21
gtsam::Ordering
Definition: inference/Ordering.h:33
Eigen::seq
internal::enable_if<!(symbolic::is_symbolic< FirstType >::value||symbolic::is_symbolic< LastType >::value), ArithmeticSequence< typename internal::cleanup_index_type< FirstType >::type, Index > >::type seq(FirstType f, LastType l)
Definition: ArithmeticSequence.h:234
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
gtsam::HybridNonlinearFactor
Implementation of a discrete-conditioned hybrid factor.
Definition: HybridNonlinearFactor.h:58
Pose3.h
3D Pose
gtsam::Switching::nonlinearFactorGraph
HybridNonlinearFactorGraph nonlinearFactorGraph
Definition: Switching.h:125
gtsam::FactorGraph::emplace_shared
IsDerived< DERIVEDFACTOR > emplace_shared(Args &&... args)
Emplace a shared pointer to factor of given type.
Definition: FactorGraph.h:153
gtsam::HybridBayesNet::emplace_shared
void emplace_shared(Args &&...args)
Definition: HybridBayesNet.h:120
gtsam::BetweenFactor
Definition: BetweenFactor.h:40
M
Matrix< RealScalar, Dynamic, Dynamic > M
Definition: bench_gemm.cpp:51


gtsam
Author(s):
autogenerated on Fri Oct 4 2024 03:08:41