ISAM2.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 
20 #include <gtsam/nonlinear/ISAM2.h>
22 
23 #include <gtsam/base/debug.h>
24 #include <gtsam/base/timing.h>
27 
28 #include <algorithm>
29 #include <map>
30 #include <utility>
31 #include <variant>
32 
33 using namespace std;
34 
35 namespace gtsam {
36 
37 // Instantiate base class
38 template class BayesTree<ISAM2Clique>;
39 
40 /* ************************************************************************* */
41 ISAM2::ISAM2(const ISAM2Params& params) : params_(params), update_count_(0) {
42  if (std::holds_alternative<ISAM2DoglegParams>(params_.optimizationParams)) {
43  doglegDelta_ =
44  std::get<ISAM2DoglegParams>(params_.optimizationParams).initialDelta;
45  }
46 }
47 
48 /* ************************************************************************* */
49 ISAM2::ISAM2() : update_count_(0) {
50  if (std::holds_alternative<ISAM2DoglegParams>(params_.optimizationParams)) {
51  doglegDelta_ =
52  std::get<ISAM2DoglegParams>(params_.optimizationParams).initialDelta;
53  }
54 }
55 
56 /* ************************************************************************* */
57 bool ISAM2::equals(const ISAM2& other, double tol) const {
58  return Base::equals(other, tol) && theta_.equals(other.theta_, tol) &&
59  variableIndex_.equals(other.variableIndex_, tol) &&
60  nonlinearFactors_.equals(other.nonlinearFactors_, tol) &&
61  fixedVariables_ == other.fixedVariables_;
62 }
63 
64 /* ************************************************************************* */
66  const ISAM2UpdateParams& updateParams, const FastList<Key>& affectedKeys,
67  const KeySet& relinKeys) {
69  FactorIndexSet candidates =
71 
72  gttic(affectedKeysSet);
73  // for fast lookup below
74  KeySet affectedKeysSet;
75  affectedKeysSet.insert(affectedKeys.begin(), affectedKeys.end());
76  gttoc(affectedKeysSet);
77 
78  gttic(check_candidates_and_linearize);
79  GaussianFactorGraph linearized;
80  for (const FactorIndex idx : candidates) {
81  bool inside = true;
82  bool useCachedLinear = params_.cacheLinearizedFactors;
83  for (Key key : nonlinearFactors_[idx]->keys()) {
84  if (affectedKeysSet.find(key) == affectedKeysSet.end()) {
85  inside = false;
86  break;
87  }
88  if (useCachedLinear && relinKeys.find(key) != relinKeys.end())
89  useCachedLinear = false;
90  }
91  if (inside) {
92  if (useCachedLinear) {
93 #ifdef GTSAM_EXTRA_CONSISTENCY_CHECKS
94  assert(linearFactors_[idx]);
95  assert(linearFactors_[idx]->keys() == nonlinearFactors_[idx]->keys());
96 #endif
97  linearized.push_back(linearFactors_[idx]);
98  } else {
99  auto linearFactor = nonlinearFactors_[idx]->linearize(theta_);
100  linearized.push_back(linearFactor);
102 #ifdef GTSAM_EXTRA_CONSISTENCY_CHECKS
103  assert(linearFactors_[idx]->keys() == linearFactor->keys());
104 #endif
105  linearFactors_[idx] = linearFactor;
106  }
107  }
108  }
109  }
110  gttoc(check_candidates_and_linearize);
111 
112  return linearized;
113 }
114 
115 /* ************************************************************************* */
116 void ISAM2::recalculate(const ISAM2UpdateParams& updateParams,
117  const KeySet& relinKeys, ISAM2Result* result) {
120 
121  if (!result->markedKeys.empty() || !result->observedKeys.empty()) {
122  // Remove top of Bayes tree and convert to a factor graph:
123  // (a) For each affected variable, remove the corresponding clique and all
124  // parents up to the root. (b) Store orphaned sub-trees \BayesTree_{O} of
125  // removed cliques.
126  GaussianBayesNet affectedBayesNet;
127  Cliques orphans;
128  this->removeTop(
129  KeyVector(result->markedKeys.begin(), result->markedKeys.end()),
130  &affectedBayesNet, &orphans);
131 
132  // FactorGraph<GaussianFactor> factors(affectedBayesNet);
133  // bug was here: we cannot reuse the original factors, because then the
134  // cached factors get messed up [all the necessary data is actually
135  // contained in the affectedBayesNet, including what was passed in from the
136  // boundaries, so this would be correct; however, in the process we also
137  // generate new cached_ entries that will be wrong (ie. they don't contain
138  // what would be passed up at a certain point if batch elimination was done,
139  // but that's what we need); we could choose not to update cached_ from
140  // here, but then the new information (and potentially different variable
141  // ordering) is not reflected in the cached_ values which again will be
142  // wrong] so instead we have to retrieve the original linearized factors AND
143  // add the cached factors from the boundary
144 
145  // ordering provides all keys in conditionals, there cannot be others
146  // because path to root included
147  gttic(affectedKeys);
148  FastList<Key> affectedKeys;
149  for (const auto& conditional : affectedBayesNet)
150  affectedKeys.insert(affectedKeys.end(), conditional->beginFrontals(),
151  conditional->endFrontals());
152  gttoc(affectedKeys);
153 
154  KeySet affectedKeysSet;
155  static const double kBatchThreshold = 0.65;
156  if (affectedKeys.size() >= theta_.size() * kBatchThreshold) {
157  // Do a batch step - reorder and relinearize all variables
158  recalculateBatch(updateParams, &affectedKeysSet, result);
159  } else {
160  recalculateIncremental(updateParams, relinKeys, affectedKeys,
161  &affectedKeysSet, &orphans, result);
162  }
163 
164  // Root clique variables for detailed results
165  if (result->detail && params_.enableDetailedResults) {
166  for (const auto& root : roots_)
167  for (Key var : *root->conditional())
168  result->detail->variableStatus[var].inRootClique = true;
169  }
170 
171  // Update replaced keys mask (accumulates until back-substitution happens)
172  deltaReplacedMask_.insert(affectedKeysSet.begin(), affectedKeysSet.end());
173  }
174 }
175 
176 /* ************************************************************************* */
178  KeySet* affectedKeysSet, ISAM2Result* result) {
180 
181  gttic(add_keys);
182 
183  // copy the keys from the variableIndex_ to the affectedKeysSet
184  for (const auto& [key, _] : variableIndex_) {
185  affectedKeysSet->insert(key);
186  }
187  // Removed unused keys:
188  VariableIndex affectedFactorsVarIndex = variableIndex_;
189 
190  affectedFactorsVarIndex.removeUnusedVariables(result->unusedKeys.begin(),
191  result->unusedKeys.end());
192 
193  for (const Key key : result->unusedKeys) {
194  affectedKeysSet->erase(key);
195  }
196  gttoc(add_keys);
197 
198  gttic(ordering);
199  Ordering order;
200  if (updateParams.constrainedKeys) {
201  order = Ordering::ColamdConstrained(affectedFactorsVarIndex,
202  *updateParams.constrainedKeys);
203  } else {
204  if (theta_.size() > result->observedKeys.size()) {
205  // Only if some variables are unconstrained
206  FastMap<Key, int> constraintGroups;
207  for (Key var : result->observedKeys) constraintGroups[var] = 1;
208  order = Ordering::ColamdConstrained(affectedFactorsVarIndex,
209  constraintGroups);
210  } else {
211  order = Ordering::Colamd(affectedFactorsVarIndex);
212  }
213  }
214  gttoc(ordering);
215 
216  gttic(linearize);
217  auto linearized = nonlinearFactors_.linearize(theta_);
218  if (params_.cacheLinearizedFactors) linearFactors_ = *linearized;
219  gttoc(linearize);
220 
221  gttic(eliminate);
222  ISAM2BayesTree::shared_ptr bayesTree =
224  GaussianEliminationTree(*linearized, affectedFactorsVarIndex, order))
226  .first;
227  gttoc(eliminate);
228 
229  gttic(insert);
230  roots_.clear();
231  roots_.insert(roots_.end(), bayesTree->roots().begin(),
232  bayesTree->roots().end());
233  nodes_.clear();
234  nodes_.insert(bayesTree->nodes().begin(), bayesTree->nodes().end());
235  gttoc(insert);
236 
237  result->variablesReeliminated = affectedKeysSet->size();
238  result->factorsRecalculated = nonlinearFactors_.size();
239 
240  // Reeliminated keys for detailed results
242  for (Key key : theta_.keys()) {
243  result->detail->variableStatus[key].isReeliminated = true;
244  }
245  }
246 }
247 
248 /* ************************************************************************* */
250  const KeySet& relinKeys,
251  const FastList<Key>& affectedKeys,
252  KeySet* affectedKeysSet, Cliques* orphans,
253  ISAM2Result* result) {
255  const bool debug = ISDEBUG("ISAM2 recalculate");
256 
257  // 2. Add the new factors \Factors' into the resulting factor graph
258  FastList<Key> affectedAndNewKeys;
259  affectedAndNewKeys.insert(affectedAndNewKeys.end(), affectedKeys.begin(),
260  affectedKeys.end());
261  affectedAndNewKeys.insert(affectedAndNewKeys.end(),
262  result->observedKeys.begin(),
263  result->observedKeys.end());
265  relinearizeAffectedFactors(updateParams, affectedAndNewKeys, relinKeys);
266 
267  if (debug) {
268  factors.print("Relinearized factors: ");
269  std::cout << "Affected keys: ";
270  for (const Key key : affectedKeys) {
271  std::cout << key << " ";
272  }
273  std::cout << std::endl;
274  }
275 
276  // Reeliminated keys for detailed results
278  for (Key key : affectedAndNewKeys) {
279  result->detail->variableStatus[key].isReeliminated = true;
280  }
281  }
282 
283  result->variablesReeliminated = affectedAndNewKeys.size();
284  result->factorsRecalculated = factors.size();
285 
286  gttic(cached);
287  // Add the cached intermediate results from the boundary of the orphans...
288  GaussianFactorGraph cachedBoundary =
290  if (debug) cachedBoundary.print("Boundary factors: ");
291  factors.push_back(cachedBoundary);
292  gttoc(cached);
293 
294  gttic(orphans);
295  // Add the orphaned subtrees
296  for (const auto& orphan : *orphans)
297  factors.emplace_shared<BayesTreeOrphanWrapper<ISAM2::Clique> >(orphan);
298  gttoc(orphans);
299 
300  // 3. Re-order and eliminate the factor graph into a Bayes net (Algorithm
301  // [alg:eliminate]), and re-assemble into a new Bayes tree (Algorithm
302  // [alg:BayesTree])
303 
304  gttic(reorder_and_eliminate);
305 
306  gttic(list_to_set);
307  // create a partial reordering for the new and contaminated factors
308  // result->markedKeys are passed in: those variables will be forced to the
309  // end in the ordering
310  affectedKeysSet->insert(result->markedKeys.begin(), result->markedKeys.end());
311  affectedKeysSet->insert(affectedKeys.begin(), affectedKeys.end());
312  gttoc(list_to_set);
313 
314  VariableIndex affectedFactorsVarIndex(factors);
315 
316  gttic(ordering_constraints);
317  // Create ordering constraints
318  FastMap<Key, int> constraintGroups;
319  if (updateParams.constrainedKeys) {
320  constraintGroups = *updateParams.constrainedKeys;
321  } else {
322  constraintGroups = FastMap<Key, int>();
323  const int group =
324  result->observedKeys.size() < affectedFactorsVarIndex.size() ? 1 : 0;
325  for (Key var : result->observedKeys)
326  constraintGroups.emplace(var, group);
327  }
328 
329  // Remove unaffected keys from the constraints
330  for (FastMap<Key, int>::iterator iter = constraintGroups.begin();
331  iter != constraintGroups.end();
332  /*Incremented in loop ++iter*/) {
333  if (result->unusedKeys.exists(iter->first) ||
334  !affectedKeysSet->exists(iter->first))
335  constraintGroups.erase(iter++);
336  else
337  ++iter;
338  }
339  gttoc(ordering_constraints);
340 
341  // Generate ordering
342  gttic(Ordering);
343  const Ordering ordering =
344  Ordering::ColamdConstrained(affectedFactorsVarIndex, constraintGroups);
345  gttoc(Ordering);
346 
347  // Do elimination
348  GaussianEliminationTree etree(factors, affectedFactorsVarIndex, ordering);
349  auto bayesTree = ISAM2JunctionTree(etree)
351  .first;
352  gttoc(reorder_and_eliminate);
353 
354  gttic(reassemble);
355  roots_.insert(roots_.end(), bayesTree->roots().begin(),
356  bayesTree->roots().end());
357  nodes_.insert(bayesTree->nodes().begin(), bayesTree->nodes().end());
358  gttoc(reassemble);
359 
360  // 4. The orphans have already been inserted during elimination
361 }
362 
363 /* ************************************************************************* */
364 void ISAM2::addVariables(const Values& newTheta,
366  gttic(addNewVariables);
367 
368  theta_.insert(newTheta);
369  if (ISDEBUG("ISAM2 AddVariables")) newTheta.print("The new variables are: ");
370  // Add zeros into the VectorValues
371  delta_.insert(newTheta.zeroVectors());
372  deltaNewton_.insert(newTheta.zeroVectors());
373  RgProd_.insert(newTheta.zeroVectors());
374 
375  // New keys for detailed results
377  for (Key key : newTheta.keys()) {
378  detail->variableStatus[key].isNew = true;
379  }
380  }
381 }
382 
383 /* ************************************************************************* */
384 void ISAM2::removeVariables(const KeySet& unusedKeys) {
386 
387  variableIndex_.removeUnusedVariables(unusedKeys.begin(), unusedKeys.end());
388  for (Key key : unusedKeys) {
389  delta_.erase(key);
391  RgProd_.erase(key);
392  deltaReplacedMask_.erase(key);
394  theta_.erase(key);
395  fixedVariables_.erase(key);
396  }
397 }
398 
399 /* ************************************************************************* */
401  const NonlinearFactorGraph& newFactors, const Values& newTheta,
402  const FactorIndices& removeFactorIndices,
403  const std::optional<FastMap<Key, int> >& constrainedKeys,
404  const std::optional<FastList<Key> >& noRelinKeys,
405  const std::optional<FastList<Key> >& extraReelimKeys,
406  bool force_relinearize) {
408  params.constrainedKeys = constrainedKeys;
409  params.extraReelimKeys = extraReelimKeys;
410  params.force_relinearize = force_relinearize;
411  params.noRelinKeys = noRelinKeys;
412  params.removeFactorIndices = removeFactorIndices;
413 
414  return update(newFactors, newTheta, params);
415 }
416 
417 /* ************************************************************************* */
419  const Values& newTheta,
420  const ISAM2UpdateParams& updateParams) {
421  gttic(ISAM2_update);
422  this->update_count_ += 1;
423  UpdateImpl::LogStartingUpdate(newFactors, *this);
425  UpdateImpl update(params_, updateParams);
426 
427  // Update delta if we need it to check relinearization later
428  if (update.relinarizationNeeded(update_count_))
429  updateDelta(updateParams.forceFullSolve);
430 
431  // 1. Add any new factors \Factors:=\Factors\cup\Factors'.
432  update.pushBackFactors(newFactors, &nonlinearFactors_, &linearFactors_,
433  &variableIndex_, &result.newFactorsIndices,
434  &result.keysWithRemovedFactors);
435  update.computeUnusedKeys(newFactors, variableIndex_,
436  result.keysWithRemovedFactors, &result.unusedKeys);
437 
438  // 2. Initialize any new variables \Theta_{new} and add
439  // \Theta:=\Theta\cup\Theta_{new}.
440  addVariables(newTheta, result.details());
442  update.error(nonlinearFactors_, calculateEstimate(), &result.errorBefore);
443 
444  // 3. Mark linear update
445  update.gatherInvolvedKeys(newFactors, nonlinearFactors_,
446  result.keysWithRemovedFactors, &result.markedKeys);
447  update.updateKeys(result.markedKeys, &result);
448 
449  KeySet relinKeys;
450  result.variablesRelinearized = 0;
451  if (update.relinarizationNeeded(update_count_)) {
452  // 4. Mark keys in \Delta above threshold \beta:
453  relinKeys = update.gatherRelinearizeKeys(roots_, delta_, fixedVariables_,
454  &result.markedKeys);
455  update.recordRelinearizeDetail(relinKeys, result.details());
456  if (!relinKeys.empty()) {
457  // 5. Mark cliques that involve marked variables \Theta_{J} and ancestors.
458  update.findFluid(roots_, relinKeys, &result.markedKeys, result.details());
459  // 6. Update linearization point for marked variables:
460  // \Theta_{J}:=\Theta_{J}+\Delta_{J}.
461  theta_.retractMasked(delta_, relinKeys);
462  }
463  result.variablesRelinearized = result.markedKeys.size();
464  }
465 
466  // 7. Linearize new factors
467  update.linearizeNewFactors(newFactors, theta_, nonlinearFactors_.size(),
468  result.newFactorsIndices, &linearFactors_);
469  update.augmentVariableIndex(newFactors, result.newFactorsIndices,
470  &variableIndex_);
471 
472  // 8. Redo top of Bayes tree and update data structures
473  recalculate(updateParams, relinKeys, &result);
474  if (!result.unusedKeys.empty()) removeVariables(result.unusedKeys);
475  result.cliques = this->nodes().size();
476 
478  update.error(nonlinearFactors_, calculateEstimate(), &result.errorAfter);
479  return result;
480 }
481 
482 /* ************************************************************************* */
484  const FastList<Key>& leafKeysList,
485  FactorIndices* marginalFactorsIndices,
486  FactorIndices* deletedFactorsIndices) {
487  // Convert to ordered set
488  KeySet leafKeys(leafKeysList.begin(), leafKeysList.end());
489 
490  // Keep track of marginal factors - map from clique to the marginal factors
491  // that should be incorporated into it, passed up from it's children.
492  // multimap<sharedClique, GaussianFactor::shared_ptr> marginalFactors;
493  map<Key, vector<GaussianFactor::shared_ptr> > marginalFactors;
494 
495  // Keep track of variables removed in subtrees
496  KeySet leafKeysRemoved;
497 
498  // Keep track of factors that get summarized by removing cliques
499  FactorIndexSet factorIndicesToRemove;
500 
501  // Remove the subtree and throw away the cliques
502  auto trackingRemoveSubtree = [&](const sharedClique& subtreeRoot) {
503  const Cliques removedCliques = this->removeSubtree(subtreeRoot);
504  for (const sharedClique& removedClique : removedCliques) {
505  auto cg = removedClique->conditional();
506  marginalFactors.erase(cg->front());
507  leafKeysRemoved.insert(cg->beginFrontals(), cg->endFrontals());
508  for (Key frontal : cg->frontals()) {
509  // Add to factors to remove
510  const auto& involved = variableIndex_[frontal];
511  factorIndicesToRemove.insert(involved.begin(), involved.end());
512 #if !defined(NDEBUG)
513  // Check for non-leaf keys
514  if (!leafKeys.exists(frontal))
515  throw std::runtime_error(
516  "Requesting to marginalize variables that are not leaves, "
517  "the ISAM2 object is now in an inconsistent state so should "
518  "no longer be used.");
519 #endif
520  }
521  }
522  return removedCliques;
523  };
524 
525  // Remove each variable and its subtrees
526  for (Key j : leafKeys) {
527  if (!leafKeysRemoved.exists(j)) { // If the index was not already removed
528  // by removing another subtree
529 
530  // Traverse up the tree to find the root of the marginalized subtree
532  while (clique->parent_.use_count() != 0) {
533  // Check if parent contains a marginalized leaf variable. Only need to
534  // check the first variable because it is the closest to the leaves.
535  sharedClique parent = clique->parent();
536  if (leafKeys.exists(parent->conditional()->front()))
537  clique = parent;
538  else
539  break;
540  }
541 
542  // See if we should remove the whole clique
543  bool marginalizeEntireClique = true;
544  for (Key frontal : clique->conditional()->frontals()) {
545  if (!leafKeys.exists(frontal)) {
546  marginalizeEntireClique = false;
547  break;
548  }
549  }
550 
551  // Remove either the whole clique or part of it
552  if (marginalizeEntireClique) {
553  // Remove the whole clique and its subtree, and keep the marginal
554  // factor.
555  auto marginalFactor = clique->cachedFactor();
556  // We do not need the marginal factors associated with this clique
557  // because their information is already incorporated in the new
558  // marginal factor. So, now associate this marginal factor with the
559  // parent of this clique. If the clique is a root and has no parent, then
560  // we can discard it without keeping track of the marginal factor.
561  if (clique->parent()) {
562  marginalFactors[clique->parent()->conditional()->front()].push_back(
564  }
565  // Now remove this clique and its subtree - all of its marginal
566  // information has been stored in marginalFactors.
567  trackingRemoveSubtree(clique);
568  } else {
569  // Reeliminate the current clique and the marginals from its children,
570  // then keep only the marginal on the non-marginalized variables. We
571  // get the childrens' marginals from any existing children, plus
572  // the marginals from the marginalFactors multimap, which come from any
573  // subtrees already marginalized out.
574 
575  // Add child marginals and remove marginalized subtrees
577  KeySet factorsInSubtreeRoot;
578  Cliques subtreesToRemove;
579  for (const sharedClique& child : clique->children) {
580  // Remove subtree if child depends on any marginalized keys
581  for (Key parent : child->conditional()->parents()) {
582  if (leafKeys.exists(parent)) {
583  subtreesToRemove.push_back(child);
584  graph.push_back(child->cachedFactor()); // Add child marginal
585  break;
586  }
587  }
588  }
589  Cliques childrenRemoved;
590  for (const sharedClique& subtree : subtreesToRemove) {
591  const Cliques removed = trackingRemoveSubtree(subtree);
592  childrenRemoved.insert(childrenRemoved.end(), removed.begin(),
593  removed.end());
594  }
595 
596  // Add the factors that are pulled into the current clique by the
597  // marginalized variables. These are the factors that involve
598  // *marginalized* frontal variables in this clique but do not involve
599  // frontal variables of any of its children.
600  // TODO(dellaert): reuse cached linear factors
601  KeySet factorsFromMarginalizedInClique_step1;
602  for (Key frontal : clique->conditional()->frontals()) {
603  if (leafKeys.exists(frontal))
604  factorsFromMarginalizedInClique_step1.insert(
605  variableIndex_[frontal].begin(), variableIndex_[frontal].end());
606  }
607  // Remove any factors in subtrees that we're removing at this step
608  for (const sharedClique& removedChild : childrenRemoved) {
609  for (Key indexInClique : removedChild->conditional()->frontals()) {
610  for (Key factorInvolving : variableIndex_[indexInClique]) {
611  factorsFromMarginalizedInClique_step1.erase(factorInvolving);
612  }
613  }
614  }
615  // Create factor graph from factor indices
616  for (const auto index : factorsFromMarginalizedInClique_step1) {
617  graph.push_back(nonlinearFactors_[index]->linearize(theta_));
618  }
619 
620  // Reeliminate the linear graph to get the marginal and discard the
621  // conditional
622  auto cg = clique->conditional();
623  const KeySet cliqueFrontals(cg->beginFrontals(), cg->endFrontals());
624  KeyVector cliqueFrontalsToEliminate;
625  std::set_intersection(cliqueFrontals.begin(), cliqueFrontals.end(),
626  leafKeys.begin(), leafKeys.end(),
627  std::back_inserter(cliqueFrontalsToEliminate));
628  auto eliminationResult1 = params_.getEliminationFunction()(
629  graph, Ordering(cliqueFrontalsToEliminate));
630 
631  // Add the resulting marginal
632  if (eliminationResult1.second)
633  marginalFactors[cg->front()].push_back(eliminationResult1.second);
634 
635  // Split the current clique
636  // Find the position of the last leaf key in this clique
637  DenseIndex nToRemove = 0;
638  while (leafKeys.exists(cg->keys()[nToRemove])) ++nToRemove;
639 
640  // Make the clique's matrix appear as a subset
641  const DenseIndex dimToRemove = cg->matrixObject().offset(nToRemove);
642  cg->matrixObject().firstBlock() += nToRemove;
643  cg->matrixObject().rowStart() = dimToRemove;
644 
645  // Change the keys in the clique
646  KeyVector originalKeys;
647  originalKeys.swap(cg->keys());
648  cg->keys().assign(originalKeys.begin() + nToRemove, originalKeys.end());
649  cg->nrFrontals() -= nToRemove;
650 
651  // Add to factorIndicesToRemove any factors involved in frontals of
652  // current clique
653  for (Key frontal : cliqueFrontalsToEliminate) {
654  const auto& involved = variableIndex_[frontal];
655  factorIndicesToRemove.insert(involved.begin(), involved.end());
656  }
657 
658  // Add removed keys
659  leafKeysRemoved.insert(cliqueFrontalsToEliminate.begin(),
660  cliqueFrontalsToEliminate.end());
661  }
662  }
663  }
664 
665  // At this point we have updated the BayesTree, now update the remaining iSAM2
666  // data structures
667 
668  // Remove the factors to remove that will be summarized in marginal factors
669  NonlinearFactorGraph removedFactors;
670  for (const auto index : factorIndicesToRemove) {
671  removedFactors.push_back(nonlinearFactors_[index]);
672  nonlinearFactors_.remove(index);
674  linearFactors_.remove(index);
675  }
676  }
677  variableIndex_.remove(factorIndicesToRemove.begin(),
678  factorIndicesToRemove.end(), removedFactors);
679 
680  // Gather factors to add - the new marginal factors
681  GaussianFactorGraph factorsToAdd{};
682  NonlinearFactorGraph nonlinearFactorsToAdd{};
683  for (const auto& key_factors : marginalFactors) {
684  for (const auto& factor : key_factors.second) {
685  if (factor) {
686  factorsToAdd.push_back(factor);
687  nonlinearFactorsToAdd.emplace_shared<LinearContainerFactor>(factor);
688  for (Key factorKey : *factor) {
689  fixedVariables_.insert(factorKey);
690  }
691  }
692  }
693  }
694  // Add the nonlinear factors and keep track of the new factor indices
695  auto newFactorIndices = nonlinearFactors_.add_factors(nonlinearFactorsToAdd,
697  // Add cached linear factors.
700  for (std::size_t i = 0; i < nonlinearFactorsToAdd.size(); ++i){
701  linearFactors_[newFactorIndices[i]] = factorsToAdd[i];
702  }
703  }
704  // Augment the variable index
705  variableIndex_.augment(factorsToAdd, newFactorIndices);
706 
707  // Remove the marginalized variables
708  removeVariables(KeySet(leafKeys.begin(), leafKeys.end()));
709 
710  if (deletedFactorsIndices) {
711  deletedFactorsIndices->assign(factorIndicesToRemove.begin(),
712  factorIndicesToRemove.end());
713  }
714  if (marginalFactorsIndices){
715  *marginalFactorsIndices = std::move(newFactorIndices);
716  }
717 }
718 
719 /* ************************************************************************* */
720 // Marked const but actually changes mutable delta
721 void ISAM2::updateDelta(bool forceFullSolve) const {
723  if (std::holds_alternative<ISAM2GaussNewtonParams>(params_.optimizationParams)) {
724  // If using Gauss-Newton, update with wildfireThreshold
725  const ISAM2GaussNewtonParams& gaussNewtonParams =
726  std::get<ISAM2GaussNewtonParams>(params_.optimizationParams);
727  const double effectiveWildfireThreshold =
728  forceFullSolve ? 0.0 : gaussNewtonParams.wildfireThreshold;
729  gttic(Wildfire_update);
731  effectiveWildfireThreshold, &delta_);
732  deltaReplacedMask_.clear();
733  gttoc(Wildfire_update);
734  } else if (std::holds_alternative<ISAM2DoglegParams>(params_.optimizationParams)) {
735  // If using Dogleg, do a Dogleg step
736  const ISAM2DoglegParams& doglegParams =
737  std::get<ISAM2DoglegParams>(params_.optimizationParams);
738  const double effectiveWildfireThreshold =
739  forceFullSolve ? 0.0 : doglegParams.wildfireThreshold;
740 
741  // Do one Dogleg iteration
742  gttic(Dogleg_Iterate);
743 
744  // Compute Newton's method step
745  gttic(Wildfire_update);
747  roots_, deltaReplacedMask_, effectiveWildfireThreshold, &deltaNewton_);
748  gttoc(Wildfire_update);
749 
750  // Compute steepest descent step
751  const VectorValues gradAtZero = this->gradientAtZero(); // Compute gradient
753  &RgProd_); // Update RgProd
755  gradAtZero, RgProd_); // Compute gradient search point
756 
757  // Clear replaced keys mask because now we've updated deltaNewton_ and
758  // RgProd_
759  deltaReplacedMask_.clear();
760 
761  // Compute dogleg point
764  *doglegDelta_, doglegParams.adaptationMode, dx_u, deltaNewton_,
766  doglegParams.verbose));
767  gttoc(Dogleg_Iterate);
768 
769  gttic(Copy_dx_d);
770  // Update Delta and linear step
771  doglegDelta_ = doglegResult.delta;
772  delta_ =
773  doglegResult
774  .dx_d; // Copy the VectorValues containing with the linear solution
775  gttoc(Copy_dx_d);
776  } else {
777  throw std::runtime_error("iSAM2: unknown ISAM2Params type");
778  }
779 }
780 
781 /* ************************************************************************* */
783  gttic(ISAM2_calculateEstimate);
784  const VectorValues& delta(getDelta());
785  gttic(Expmap);
786  return theta_.retract(delta);
787  gttoc(Expmap);
788 }
789 
790 /* ************************************************************************* */
792  const Vector& delta = getDelta()[key];
793  return *theta_.at(key).retract_(delta);
794 }
795 
796 /* ************************************************************************* */
798  updateDelta(true); // Force full solve when updating delta_
799  return theta_.retract(delta_);
800 }
801 
802 /* ************************************************************************* */
805  ->information()
806  .inverse();
807 }
808 
809 /* ************************************************************************* */
811  if (!deltaReplacedMask_.empty()) updateDelta();
812  return delta_;
813 }
814 
815 /* ************************************************************************* */
816 double ISAM2::error(const VectorValues& x) const {
817  return GaussianFactorGraph(*this).error(x);
818 }
819 
820 /* ************************************************************************* */
822  // Create result
823  VectorValues g;
824 
825  // Sum up contributions for each clique
826  for (const auto& root : this->roots()) root->addGradientAtZero(&g);
827 
828  return g;
829 }
830 
831 } // namespace gtsam
gtsam::DeltaImpl::UpdateGaussNewtonDelta
static size_t UpdateGaussNewtonDelta(const ISAM2::Roots &roots, const KeySet &replacedKeys, double wildfireThreshold, VectorValues *delta)
Definition: ISAM2-impl.cpp:47
gttoc
#define gttoc(label)
Definition: timing.h:296
timing.h
Timing utilities.
gtsam::FactorGraph::add_factors
FactorIndices add_factors(const CONTAINER &factors, bool useEmptySlots=false)
Definition: FactorGraph-inst.h:109
gtsam::BayesTreeOrphanWrapper
Definition: BayesTree.h:281
gtsam::DeltaImpl::ComputeGradientSearch
static VectorValues ComputeGradientSearch(const VectorValues &gradAtZero, const VectorValues &RgProd)
Definition: ISAM2-impl.cpp:145
gtsam::ISAM2Params
Definition: ISAM2Params.h:136
gtsam::NonlinearFactorGraph::equals
bool equals(const NonlinearFactorGraph &other, double tol=1e-9) const
Definition: NonlinearFactorGraph.cpp:97
gtsam::ISAM2::addVariables
void addVariables(const Values &newTheta, ISAM2Result::DetailedResults *detail=0)
Definition: ISAM2.cpp:364
gtsam::UpdateImpl
Definition: ISAM2-impl.h:108
gtsam::ISAM2
Definition: ISAM2.h:45
gtsam::Values::keys
KeyVector keys() const
Definition: Values.cpp:218
gtsam::ISAM2::marginalizeLeaves
void marginalizeLeaves(const FastList< Key > &leafKeys, FactorIndices *marginalFactorsIndices=nullptr, FactorIndices *deletedFactorsIndices=nullptr)
Definition: ISAM2.cpp:483
gtsam::DeltaImpl::UpdateRgProd
static size_t UpdateRgProd(const ISAM2::Roots &roots, const KeySet &replacedKeys, const VectorValues &gradAtZero, VectorValues *RgProd)
Definition: ISAM2-impl.cpp:130
gtsam::ISAM2::calculateBestEstimate
Values calculateBestEstimate() const
Definition: ISAM2.cpp:797
gtsam::Values::size
size_t size() const
Definition: Values.h:178
gtsam::DoglegOptimizerImpl::Iterate
static IterationResult Iterate(double delta, TrustRegionAdaptationMode mode, const VectorValues &dx_u, const VectorValues &dx_n, const M &Rd, const F &f, const VALUES &x0, const double f_error, const bool verbose=false)
Definition: DoglegOptimizerImpl.h:138
LinearContainerFactor.h
Wrap Jacobian and Hessian linear factors to allow simple injection into a nonlinear graph.
gtsam::ISAM2::deltaNewton_
VectorValues deltaNewton_
Definition: ISAM2.h:63
gtsam::VariableIndex::augment
void augment(const FG &factors, const FactorIndices *newFactorIndices=nullptr)
Definition: VariableIndex-inl.h:27
keys
const KeyVector keys
Definition: testRegularImplicitSchurFactor.cpp:40
gtsam::VectorValues::insert
iterator insert(const std::pair< Key, Vector > &key_value)
Definition: VectorValues.cpp:88
gtsam::ISAM2::params_
ISAM2Params params_
Definition: ISAM2.h:87
gtsam::FastSet::exists
bool exists(const VALUE &e) const
Definition: FastSet.h:98
gtsam::ISAM2::linearFactors_
GaussianFactorGraph linearFactors_
Definition: ISAM2.h:84
gtsam::ISAM2Params::enableDetailedResults
bool enableDetailedResults
Definition: ISAM2Params.h:207
gtsam::BayesTree< ISAM2Clique >::roots_
Roots roots_
Definition: BayesTree.h:103
gtsam::FactorGraph::print
virtual void print(const std::string &s="FactorGraph", const KeyFormatter &formatter=DefaultKeyFormatter) const
Print out graph to std::cout, with optional key formatter.
Definition: FactorGraph-inst.h:37
gtsam::ISAM2::update_count_
int update_count_
Definition: ISAM2.h:96
gtsam::Values::retractMasked
void retractMasked(const VectorValues &delta, const KeySet &mask)
Definition: Values.cpp:103
simple_graph::factors
const GaussianFactorGraph factors
Definition: testJacobianFactor.cpp:213
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::ISAM2::theta_
Values theta_
Definition: ISAM2.h:48
ISAM2-impl.h
Incremental update functionality (ISAM2) for BayesTree, with fluid relinearization.
gtsam::FastMap
Definition: FastMap.h:39
gtsam::ISAM2::fixedVariables_
KeySet fixedVariables_
Definition: ISAM2.h:94
gtsam::Matrix
Eigen::MatrixXd Matrix
Definition: base/Matrix.h:39
gtsam::ISAM2::delta_
VectorValues delta_
Definition: ISAM2.h:61
gtsam::BayesTree< ISAM2Clique >::nodes
const Nodes & nodes() const
Definition: BayesTree.h:146
detail
Definition: testSerializationNonlinear.cpp:70
gtsam::NonlinearFactorGraph::linearize
std::shared_ptr< GaussianFactorGraph > linearize(const Values &linearizationPoint) const
Linearize a nonlinear factor graph.
Definition: NonlinearFactorGraph.cpp:239
gtsam::BayesTree< ISAM2Clique >::marginalFactor
sharedConditional marginalFactor(Key j, const Eliminate &function=EliminationTraitsType::DefaultEliminate) const
Definition: BayesTree-inst.h:309
gtsam::FastSet< Key >
gtsam::ISAM2::recalculateBatch
void recalculateBatch(const ISAM2UpdateParams &updateParams, KeySet *affectedKeysSet, ISAM2Result *result)
Definition: ISAM2.cpp:177
gtsam::ISAM2::sharedClique
Base::sharedClique sharedClique
Shared pointer to a clique.
Definition: ISAM2.h:103
vanilla::params
static const SmartProjectionParams params
Definition: smartFactorScenarios.h:69
gtsam::Vector
Eigen::VectorXd Vector
Definition: Vector.h:38
gtsam::ISAM2Result::markedKeys
KeySet markedKeys
Definition: ISAM2Result.h:109
gtsam::KeyVector
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition: Key.h:92
result
Values result
Definition: OdometryOptimize.cpp:8
gtsam::BayesTree< ISAM2Clique >::removeTop
void removeTop(const KeyVector &keys, BayesNetType *bn, Cliques *orphans)
Definition: BayesTree-inst.h:516
gtsam::ISAM2Params::getEliminationFunction
GaussianFactorGraph::Eliminate getEliminationFunction() const
Definition: ISAM2Params.h:323
gtsam::VariableIndex::remove
void remove(ITERATOR firstFactor, ITERATOR lastFactor, const FG &factors)
Definition: VariableIndex-inl.h:53
gtsam::UpdateImpl::error
void error(const NonlinearFactorGraph &nonlinearFactors, const Values &estimate, std::optional< double > *result) const
Definition: ISAM2-impl.h:191
gtsam::ISAM2::equals
virtual bool equals(const ISAM2 &other, double tol=1e-9) const
Definition: ISAM2.cpp:57
gtsam::ISAM2Params::optimizationParams
OptimizationParams optimizationParams
Definition: ISAM2Params.h:151
gtsam::DoglegOptimizerImpl::IterationResult::delta
double delta
Definition: DoglegOptimizerImpl.h:35
gtsam::DoglegOptimizerImpl::IterationResult::dx_d
VectorValues dx_d
Definition: DoglegOptimizerImpl.h:36
gtsam::ISAM2DoglegParams
Definition: ISAM2Params.h:68
gtsam::ISAM2::ISAM2
ISAM2()
Definition: ISAM2.cpp:49
gtsam::ISAM2GaussNewtonParams::wildfireThreshold
double wildfireThreshold
Definition: ISAM2Params.h:38
gtsam::ISAM2UpdateParams::constrainedKeys
std::optional< FastMap< Key, int > > constrainedKeys
Definition: ISAM2UpdateParams.h:40
gtsam::ISAM2DoglegParams::wildfireThreshold
double wildfireThreshold
Definition: ISAM2Params.h:71
gtsam::BayesTree< ISAM2Clique >::nodes_
Nodes nodes_
Definition: BayesTree.h:100
gtsam::ISAM2::error
double error(const VectorValues &x) const
Definition: ISAM2.cpp:816
gtsam::GaussianFactorGraph
Definition: GaussianFactorGraph.h:73
gtsam::BayesTree< ISAM2Clique >::removeSubtree
Cliques removeSubtree(const sharedClique &subtree)
Definition: BayesTree-inst.h:537
gtsam::NonlinearFactorGraph::error
double error(const Values &values) const
Definition: NonlinearFactorGraph.cpp:170
Expmap
Pose2_ Expmap(const Vector3_ &xi)
Definition: InverseKinematicsExampleExpressions.cpp:47
gtsam::Values::at
const ValueType at(Key j) const
Definition: Values-inl.h:261
ISDEBUG
#define ISDEBUG(S)
Definition: debug.h:60
gtsam::Values::retract
Values retract(const VectorValues &delta) const
Definition: Values.cpp:98
gtsam::FactorGraph::resize
virtual void resize(size_t size)
Definition: FactorGraph.h:367
gtsam::BayesTree< ISAM2Clique >::roots
const Roots & roots() const
Definition: BayesTree.h:152
gtsam.examples.PlanarManipulatorExample.delta
def delta(g0, g1)
Definition: PlanarManipulatorExample.py:45
gtsam::KeySet
FastSet< Key > KeySet
Definition: Key.h:96
gtsam::VectorValues
Definition: VectorValues.h:74
j
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
ISAM2Result.h
Class that stores detailed iSAM2 result.
gtsam::ISAM2::recalculateIncremental
void recalculateIncremental(const ISAM2UpdateParams &updateParams, const KeySet &relinKeys, const FastList< Key > &affectedKeys, KeySet *affectedKeysSet, Cliques *orphans, ISAM2Result *result)
Perform an incremental update of the factor graph to return a new Bayes Tree with affected keys.
Definition: ISAM2.cpp:249
gtsam::Ordering::Colamd
static Ordering Colamd(const FACTOR_GRAPH &graph)
Definition: inference/Ordering.h:93
gtsam::BayesTree< ISAM2Clique >::clique
const sharedClique & clique(Key j) const
Definition: BayesTree.h:155
gtsam::FactorIndex
std::uint64_t FactorIndex
Integer nonlinear factor index type.
Definition: types.h:100
gtsam::ISAM2::nonlinearFactors_
NonlinearFactorGraph nonlinearFactors_
Definition: ISAM2.h:81
gtsam::NonlinearFactorGraph
Definition: NonlinearFactorGraph.h:55
debug
static constexpr bool debug
Definition: testDiscreteBayesTree.cpp:31
gtsam::ISAM2Result::DetailedResults
Definition: ISAM2Result.h:115
gtsam::Value
Definition: Value.h:39
gtsam::ISAM2::deltaReplacedMask_
KeySet deltaReplacedMask_
Definition: ISAM2.h:76
gtsam::ISAM2::variableIndex_
VariableIndex variableIndex_
Definition: ISAM2.h:52
gtsam::UpdateImpl::GetAffectedFactors
static FactorIndexSet GetAffectedFactors(const KeyList &keys, const VariableIndex &variableIndex)
Definition: ISAM2-impl.h:487
gtsam::VariableIndex::removeUnusedVariables
void removeUnusedVariables(ITERATOR firstKey, ITERATOR lastKey)
Remove unused empty variables (in debug mode verifies they are empty).
Definition: VariableIndex-inl.h:84
gtsam::Values::equals
bool equals(const Values &other, double tol=1e-9) const
Definition: Values.cpp:77
gtsam::ISAM2GaussNewtonParams
Definition: ISAM2Params.h:36
gtsam::Ordering::ColamdConstrained
static Ordering ColamdConstrained(const FACTOR_GRAPH &graph, const FastMap< Key, int > &groups)
Definition: inference/Ordering.h:168
gtsam::ConcurrentMap::unsafe_erase
void unsafe_erase(typename Base::iterator position)
Definition: ConcurrentMap.h:94
gtsam::ISAM2::removeVariables
void removeVariables(const KeySet &unusedKeys)
Definition: ISAM2.cpp:384
gtsam::FastList
Definition: FastList.h:43
size_t
std::size_t size_t
Definition: wrap/pybind11/include/pybind11/detail/common.h:476
gtsam::VariableIndex
Definition: VariableIndex.h:41
g
void g(const string &key, int i)
Definition: testBTree.cpp:41
ordering
static enum @1096 ordering
gtsam::ISAM2::updateDelta
void updateDelta(bool forceFullSolve=false) const
Definition: ISAM2.cpp:721
key
const gtsam::Symbol key('X', 0)
gtsam::FactorGraph::remove
void remove(size_t i)
Definition: FactorGraph.h:371
gtsam::ISAM2::calculateEstimate
Values calculateEstimate() const
Definition: ISAM2.cpp:782
gtsam::FactorGraph::size
size_t size() const
Definition: FactorGraph.h:297
ISAM2.h
Incremental update functionality (ISAM2) for BayesTree, with fluid relinearization.
gtsam::Values::zeroVectors
VectorValues zeroVectors() const
Definition: Values.cpp:260
gtsam::ISAM2::relinearizeAffectedFactors
GaussianFactorGraph relinearizeAffectedFactors(const ISAM2UpdateParams &updateParams, const FastList< Key > &affectedKeys, const KeySet &relinKeys)
Definition: ISAM2.cpp:65
gtsam::ISAM2::getDelta
const VectorValues & getDelta() const
Definition: ISAM2.cpp:810
gtsam::UpdateImpl::GetCachedBoundaryFactors
static GaussianFactorGraph GetCachedBoundaryFactors(const ISAM2::Cliques &orphans)
Definition: ISAM2-impl.h:500
gtsam::ISAM2::RgProd_
VectorValues RgProd_
Definition: ISAM2.h:65
gtsam::ISAM2BayesTree::shared_ptr
std::shared_ptr< This > shared_ptr
Definition: ISAM2-impl.h:46
gtsam::Values::print
void print(const std::string &str="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
Definition: Values.cpp:66
gtsam
traits
Definition: chartTesting.h:28
gtsam::ISAM2::update
virtual ISAM2Result update(const NonlinearFactorGraph &newFactors=NonlinearFactorGraph(), const Values &newTheta=Values(), const FactorIndices &removeFactorIndices=FactorIndices(), const std::optional< FastMap< Key, int > > &constrainedKeys={}, const std::optional< FastList< Key > > &noRelinKeys={}, const std::optional< FastList< Key > > &extraReelimKeys={}, bool force_relinearize=false)
Definition: ISAM2.cpp:400
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::ISAM2::marginalCovariance
Matrix marginalCovariance(Key key) const
Definition: ISAM2.cpp:803
gtsam::GaussianFactorGraph::error
double error(const VectorValues &x) const
Definition: GaussianFactorGraph.cpp:71
iter
iterator iter(handle obj)
Definition: pytypes.h:2428
gtsam::DenseIndex
ptrdiff_t DenseIndex
The index type for Eigen objects.
Definition: types.h:103
gtsam::ISAM2Params::findUnusedFactorSlots
bool findUnusedFactorSlots
Definition: ISAM2Params.h:225
gtsam::ISAM2UpdateParams
Definition: ISAM2UpdateParams.h:32
std
Definition: BFloat16.h:88
gtsam::DoglegOptimizerImpl::IterationResult
Definition: DoglegOptimizerImpl.h:34
gtsam::VariableIndex::size
size_t size() const
The number of variable entries. This is equal to the number of unique variable Keys.
Definition: VariableIndex.h:78
gtsam::Values::insert
void insert(Key j, const Value &val)
Definition: Values.cpp:155
gtsam::UpdateImpl::LogRecalculateKeys
static void LogRecalculateKeys(const ISAM2Result &result)
Definition: ISAM2-impl.h:470
gtsam::GaussianEliminationTree
Definition: GaussianEliminationTree.h:27
gtsam::ISAM2JunctionTree
Definition: ISAM2-impl.h:54
gtsam::ISAM2::gradientAtZero
VectorValues gradientAtZero() const
Definition: ISAM2.cpp:821
gtsam::tol
const G double tol
Definition: Group.h:79
gtsam::EliminatableClusterTree::eliminate
std::pair< std::shared_ptr< BayesTreeType >, std::shared_ptr< FactorGraphType > > eliminate(const Eliminate &function) const
Definition: ClusterTree-inst.h:285
gtsam::Values::erase
void erase(Key j)
Definition: Values.cpp:210
gtsam::ISAM2::recalculate
void recalculate(const ISAM2UpdateParams &updateParams, const KeySet &relinKeys, ISAM2Result *result)
Remove marked top and either recalculate in batch or incrementally.
Definition: ISAM2.cpp:116
gtsam::ISAM2Result
Definition: ISAM2Result.h:39
gtsam::ISAM2DoglegParams::adaptationMode
DoglegOptimizerImpl::TrustRegionAdaptationMode adaptationMode
Definition: ISAM2Params.h:74
gtsam::BayesTree< ISAM2Clique >::equals
bool equals(const This &other, double tol=1e-9) const
Definition: BayesTree-inst.h:269
gtsam::LinearContainerFactor
Definition: LinearContainerFactor.h:29
gtsam::ISAM2::doglegDelta_
std::optional< double > doglegDelta_
Definition: ISAM2.h:90
gtsam::ISAM2UpdateParams::forceFullSolve
bool forceFullSolve
Definition: ISAM2UpdateParams.h:71
gtsam::VariableIndex::equals
bool equals(const VariableIndex &other, double tol=0.0) const
Test for equality (for unit tests and debug assertions).
Definition: VariableIndex.cpp:27
gtsam::VectorValues::erase
void erase(Key var)
Definition: VectorValues.h:229
gtsam::ISAM2DoglegParams::verbose
bool verbose
Whether Dogleg prints iteration and convergence information.
Definition: ISAM2Params.h:77
Eigen::placeholders::end
static const EIGEN_DEPRECATED end_t end
Definition: IndexedViewHelper.h:181
graph
NonlinearFactorGraph graph
Definition: doc/Code/OdometryExample.cpp:2
BayesTree-inst.h
Bayes Tree is a tree of cliques of a Bayes Chain.
gtsam::Key
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:97
_
constexpr descr< N - 1 > _(char const (&text)[N])
Definition: descr.h:109
insert
A insert(1, 2)=0
gtsam::Ordering
Definition: inference/Ordering.h:33
gtsam::ISAM2Params::cacheLinearizedFactors
bool cacheLinearizedFactors
Definition: ISAM2Params.h:201
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
pybind_wrapper_test_script.other
other
Definition: pybind_wrapper_test_script.py:42
gtsam::ISAM2Params::evaluateNonlinearError
bool evaluateNonlinearError
Definition: ISAM2Params.h:178
gtsam::UpdateImpl::LogStartingUpdate
static void LogStartingUpdate(const NonlinearFactorGraph &newFactors, const ISAM2 &isam2)
Definition: ISAM2-impl.h:115
gtsam::GaussianBayesNet
Definition: GaussianBayesNet.h:35
gttic
#define gttic(label)
Definition: timing.h:295
debug.h
Global debugging flags.
gtsam::FactorIndices
FastVector< FactorIndex > FactorIndices
Define collection types:
Definition: Factor.h:36
gtsam::ISAM2::params
const ISAM2Params & params() const
Definition: ISAM2.h:279


gtsam
Author(s):
autogenerated on Thu Jun 13 2024 03:02:44