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  // Initialize any new variables \Theta_{new} and add
428  // \Theta:=\Theta\cup\Theta_{new}.
429  // Needed before delta update if using Dogleg optimizer.
430  addVariables(newTheta, result.details());
431 
432  // Update delta if we need it to check relinearization later
433  if (update.relinarizationNeeded(update_count_))
434  updateDelta(updateParams.forceFullSolve);
435 
436  // 1. Add any new factors \Factors:=\Factors\cup\Factors'.
437  update.pushBackFactors(newFactors, &nonlinearFactors_, &linearFactors_,
438  &variableIndex_, &result.newFactorsIndices,
439  &result.keysWithRemovedFactors);
440  update.computeUnusedKeys(newFactors, variableIndex_,
441  result.keysWithRemovedFactors, &result.unusedKeys);
442 
443  // 2. Compute new error to check for relinearization
445  update.error(nonlinearFactors_, calculateEstimate(), &result.errorBefore);
446 
447  // 3. Mark linear update
448  update.gatherInvolvedKeys(newFactors, nonlinearFactors_,
449  result.keysWithRemovedFactors, &result.markedKeys);
450  update.updateKeys(result.markedKeys, &result);
451 
452  KeySet relinKeys;
453  result.variablesRelinearized = 0;
454  if (update.relinarizationNeeded(update_count_)) {
455  // 4. Mark keys in \Delta above threshold \beta:
456  relinKeys = update.gatherRelinearizeKeys(roots_, delta_, fixedVariables_,
457  &result.markedKeys);
458  update.recordRelinearizeDetail(relinKeys, result.details());
459  if (!relinKeys.empty()) {
460  // 5. Mark cliques that involve marked variables \Theta_{J} and ancestors.
461  update.findFluid(roots_, relinKeys, &result.markedKeys, result.details());
462  // 6. Update linearization point for marked variables:
463  // \Theta_{J}:=\Theta_{J}+\Delta_{J}.
464  theta_.retractMasked(delta_, relinKeys);
465  }
466  result.variablesRelinearized = result.markedKeys.size();
467  }
468 
469  // 7. Linearize new factors
470  update.linearizeNewFactors(newFactors, theta_, nonlinearFactors_.size(),
471  result.newFactorsIndices, &linearFactors_);
472  update.augmentVariableIndex(newFactors, result.newFactorsIndices,
473  &variableIndex_);
474 
475  // 8. Redo top of Bayes tree and update data structures
476  recalculate(updateParams, relinKeys, &result);
477  if (!result.unusedKeys.empty()) removeVariables(result.unusedKeys);
478  result.cliques = this->nodes().size();
479 
481  update.error(nonlinearFactors_, calculateEstimate(), &result.errorAfter);
482  return result;
483 }
484 
485 /* ************************************************************************* */
487  const FastList<Key>& leafKeysList,
488  FactorIndices* marginalFactorsIndices,
489  FactorIndices* deletedFactorsIndices) {
490  // Convert to ordered set
491  KeySet leafKeys(leafKeysList.begin(), leafKeysList.end());
492 
493  // Keep track of marginal factors - map from clique to the marginal factors
494  // that should be incorporated into it, passed up from it's children.
495  // multimap<sharedClique, GaussianFactor::shared_ptr> marginalFactors;
496  map<Key, vector<GaussianFactor::shared_ptr> > marginalFactors;
497 
498  // Keep track of variables removed in subtrees
499  KeySet leafKeysRemoved;
500 
501  // Keep track of factors that get summarized by removing cliques
502  FactorIndexSet factorIndicesToRemove;
503 
504  // Remove the subtree and throw away the cliques
505  auto trackingRemoveSubtree = [&](const sharedClique& subtreeRoot) {
506  const Cliques removedCliques = this->removeSubtree(subtreeRoot);
507  for (const sharedClique& removedClique : removedCliques) {
508  auto cg = removedClique->conditional();
509  marginalFactors.erase(cg->front());
510  leafKeysRemoved.insert(cg->beginFrontals(), cg->endFrontals());
511  for (Key frontal : cg->frontals()) {
512  // Add to factors to remove
513  const auto& involved = variableIndex_[frontal];
514  factorIndicesToRemove.insert(involved.begin(), involved.end());
515 #if !defined(NDEBUG)
516  // Check for non-leaf keys
517  if (!leafKeys.exists(frontal))
518  throw std::runtime_error(
519  "Requesting to marginalize variables that are not leaves, "
520  "the ISAM2 object is now in an inconsistent state so should "
521  "no longer be used.");
522 #endif
523  }
524  }
525  return removedCliques;
526  };
527 
528  // Remove each variable and its subtrees
529  for (Key j : leafKeys) {
530  if (!leafKeysRemoved.exists(j)) { // If the index was not already removed
531  // by removing another subtree
532 
533  // Traverse up the tree to find the root of the marginalized subtree
535  while (clique->parent_.use_count() != 0) {
536  // Check if parent contains a marginalized leaf variable. Only need to
537  // check the first variable because it is the closest to the leaves.
538  sharedClique parent = clique->parent();
539  if (leafKeys.exists(parent->conditional()->front()))
540  clique = parent;
541  else
542  break;
543  }
544 
545  // See if we should remove the whole clique
546  bool marginalizeEntireClique = true;
547  for (Key frontal : clique->conditional()->frontals()) {
548  if (!leafKeys.exists(frontal)) {
549  marginalizeEntireClique = false;
550  break;
551  }
552  }
553 
554  // Remove either the whole clique or part of it
555  if (marginalizeEntireClique) {
556  // Remove the whole clique and its subtree, and keep the marginal
557  // factor.
558  auto marginalFactor = clique->cachedFactor();
559  // We do not need the marginal factors associated with this clique
560  // because their information is already incorporated in the new
561  // marginal factor. So, now associate this marginal factor with the
562  // parent of this clique. If the clique is a root and has no parent, then
563  // we can discard it without keeping track of the marginal factor.
564  if (clique->parent()) {
565  marginalFactors[clique->parent()->conditional()->front()].push_back(
567  }
568  // Now remove this clique and its subtree - all of its marginal
569  // information has been stored in marginalFactors.
570  trackingRemoveSubtree(clique);
571  } else {
572  // Reeliminate the current clique and the marginals from its children,
573  // then keep only the marginal on the non-marginalized variables. We
574  // get the childrens' marginals from any existing children, plus
575  // the marginals from the marginalFactors multimap, which come from any
576  // subtrees already marginalized out.
577 
578  // Add child marginals and remove marginalized subtrees
580  KeySet factorsInSubtreeRoot;
581  Cliques subtreesToRemove;
582  for (const sharedClique& child : clique->children) {
583  // Remove subtree if child depends on any marginalized keys
584  for (Key parent : child->conditional()->parents()) {
585  if (leafKeys.exists(parent)) {
586  subtreesToRemove.push_back(child);
587  graph.push_back(child->cachedFactor()); // Add child marginal
588  break;
589  }
590  }
591  }
592  Cliques childrenRemoved;
593  for (const sharedClique& subtree : subtreesToRemove) {
594  const Cliques removed = trackingRemoveSubtree(subtree);
595  childrenRemoved.insert(childrenRemoved.end(), removed.begin(),
596  removed.end());
597  }
598 
599  // Add the factors that are pulled into the current clique by the
600  // marginalized variables. These are the factors that involve
601  // *marginalized* frontal variables in this clique but do not involve
602  // frontal variables of any of its children.
603  // TODO(dellaert): reuse cached linear factors
604  KeySet factorsFromMarginalizedInClique_step1;
605  for (Key frontal : clique->conditional()->frontals()) {
606  if (leafKeys.exists(frontal))
607  factorsFromMarginalizedInClique_step1.insert(
608  variableIndex_[frontal].begin(), variableIndex_[frontal].end());
609  }
610  // Remove any factors in subtrees that we're removing at this step
611  for (const sharedClique& removedChild : childrenRemoved) {
612  for (Key indexInClique : removedChild->conditional()->frontals()) {
613  for (Key factorInvolving : variableIndex_[indexInClique]) {
614  factorsFromMarginalizedInClique_step1.erase(factorInvolving);
615  }
616  }
617  }
618  // Create factor graph from factor indices
619  for (const auto index : factorsFromMarginalizedInClique_step1) {
620  graph.push_back(nonlinearFactors_[index]->linearize(theta_));
621  }
622 
623  // Reeliminate the linear graph to get the marginal and discard the
624  // conditional
625  auto cg = clique->conditional();
626  const KeySet cliqueFrontals(cg->beginFrontals(), cg->endFrontals());
627  KeyVector cliqueFrontalsToEliminate;
628  std::set_intersection(cliqueFrontals.begin(), cliqueFrontals.end(),
629  leafKeys.begin(), leafKeys.end(),
630  std::back_inserter(cliqueFrontalsToEliminate));
631  auto eliminationResult1 = params_.getEliminationFunction()(
632  graph, Ordering(cliqueFrontalsToEliminate));
633 
634  // Add the resulting marginal
635  if (eliminationResult1.second)
636  marginalFactors[cg->front()].push_back(eliminationResult1.second);
637 
638  // Split the current clique
639  // Find the position of the last leaf key in this clique
640  DenseIndex nToRemove = 0;
641  while (leafKeys.exists(cg->keys()[nToRemove])) ++nToRemove;
642 
643  // Make the clique's matrix appear as a subset
644  const DenseIndex dimToRemove = cg->matrixObject().offset(nToRemove);
645  cg->matrixObject().firstBlock() += nToRemove;
646  cg->matrixObject().rowStart() = dimToRemove;
647 
648  // Change the keys in the clique
649  KeyVector originalKeys;
650  originalKeys.swap(cg->keys());
651  cg->keys().assign(originalKeys.begin() + nToRemove, originalKeys.end());
652  cg->nrFrontals() -= nToRemove;
653 
654  // Add to factorIndicesToRemove any factors involved in frontals of
655  // current clique
656  for (Key frontal : cliqueFrontalsToEliminate) {
657  const auto& involved = variableIndex_[frontal];
658  factorIndicesToRemove.insert(involved.begin(), involved.end());
659  }
660 
661  // Add removed keys
662  leafKeysRemoved.insert(cliqueFrontalsToEliminate.begin(),
663  cliqueFrontalsToEliminate.end());
664  }
665  }
666  }
667 
668  // At this point we have updated the BayesTree, now update the remaining iSAM2
669  // data structures
670 
671  // Remove the factors to remove that will be summarized in marginal factors
672  NonlinearFactorGraph removedFactors;
673  for (const auto index : factorIndicesToRemove) {
674  removedFactors.push_back(nonlinearFactors_[index]);
675  nonlinearFactors_.remove(index);
677  linearFactors_.remove(index);
678  }
679  }
680  variableIndex_.remove(factorIndicesToRemove.begin(),
681  factorIndicesToRemove.end(), removedFactors);
682 
683  // Gather factors to add - the new marginal factors
684  GaussianFactorGraph factorsToAdd{};
685  NonlinearFactorGraph nonlinearFactorsToAdd{};
686  for (const auto& key_factors : marginalFactors) {
687  for (const auto& factor : key_factors.second) {
688  if (factor) {
689  factorsToAdd.push_back(factor);
690  nonlinearFactorsToAdd.emplace_shared<LinearContainerFactor>(factor);
691  for (Key factorKey : *factor) {
692  fixedVariables_.insert(factorKey);
693  }
694  }
695  }
696  }
697  // Add the nonlinear factors and keep track of the new factor indices
698  auto newFactorIndices = nonlinearFactors_.add_factors(nonlinearFactorsToAdd,
700  // Add cached linear factors.
703  for (std::size_t i = 0; i < nonlinearFactorsToAdd.size(); ++i){
704  linearFactors_[newFactorIndices[i]] = factorsToAdd[i];
705  }
706  }
707  // Augment the variable index
708  variableIndex_.augment(factorsToAdd, newFactorIndices);
709 
710  // Remove the marginalized variables
711  removeVariables(KeySet(leafKeys.begin(), leafKeys.end()));
712 
713  if (deletedFactorsIndices) {
714  deletedFactorsIndices->assign(factorIndicesToRemove.begin(),
715  factorIndicesToRemove.end());
716  }
717  if (marginalFactorsIndices){
718  *marginalFactorsIndices = std::move(newFactorIndices);
719  }
720 }
721 
722 /* ************************************************************************* */
723 // Marked const but actually changes mutable delta
724 void ISAM2::updateDelta(bool forceFullSolve) const {
726  if (std::holds_alternative<ISAM2GaussNewtonParams>(params_.optimizationParams)) {
727  // If using Gauss-Newton, update with wildfireThreshold
728  const ISAM2GaussNewtonParams& gaussNewtonParams =
729  std::get<ISAM2GaussNewtonParams>(params_.optimizationParams);
730  const double effectiveWildfireThreshold =
731  forceFullSolve ? 0.0 : gaussNewtonParams.wildfireThreshold;
732  gttic(Wildfire_update);
734  effectiveWildfireThreshold, &delta_);
735  deltaReplacedMask_.clear();
736  gttoc(Wildfire_update);
737 
738  } else if (std::holds_alternative<ISAM2DoglegParams>(params_.optimizationParams)) {
739  // If using Dogleg, do a Dogleg step
740  const ISAM2DoglegParams& doglegParams =
741  std::get<ISAM2DoglegParams>(params_.optimizationParams);
742  const double effectiveWildfireThreshold =
743  forceFullSolve ? 0.0 : doglegParams.wildfireThreshold;
744 
745  // Do one Dogleg iteration
746  gttic(Dogleg_Iterate);
747 
748  // Compute Newton's method step
749  gttic(Wildfire_update);
751  roots_, deltaReplacedMask_, effectiveWildfireThreshold, &deltaNewton_);
752  gttoc(Wildfire_update);
753 
754  // Compute steepest descent step
755  const VectorValues gradAtZero = this->gradientAtZero(); // Compute gradient
757  &RgProd_); // Update RgProd
759  gradAtZero, RgProd_); // Compute gradient search point
760 
761  // Clear replaced keys mask because now we've updated deltaNewton_ and
762  // RgProd_
763  deltaReplacedMask_.clear();
764 
765  // Compute dogleg point
768  *doglegDelta_, doglegParams.adaptationMode, dx_u, deltaNewton_,
770  doglegParams.verbose));
771  gttoc(Dogleg_Iterate);
772 
773  gttic(Copy_dx_d);
774  // Update Delta and linear step
775  doglegDelta_ = doglegResult.delta;
776  // Copy the VectorValues containing with the linear solution
777  delta_ = doglegResult.dx_d;
778  gttoc(Copy_dx_d);
779  } else {
780  throw std::runtime_error("iSAM2: unknown ISAM2Params type");
781  }
782 }
783 
784 /* ************************************************************************* */
786  gttic(ISAM2_calculateEstimate);
787  const VectorValues& delta(getDelta());
788  gttic(Expmap);
789  return theta_.retract(delta);
790  gttoc(Expmap);
791 }
792 
793 /* ************************************************************************* */
795  const Vector& delta = getDelta()[key];
796  return *theta_.at(key).retract_(delta);
797 }
798 
799 /* ************************************************************************* */
801  updateDelta(true); // Force full solve when updating delta_
802  return theta_.retract(delta_);
803 }
804 
805 /* ************************************************************************* */
808  ->information()
809  .inverse();
810 }
811 
812 /* ************************************************************************* */
814  if (!deltaReplacedMask_.empty()) updateDelta();
815  return delta_;
816 }
817 
818 /* ************************************************************************* */
819 double ISAM2::error(const VectorValues& x) const {
820  return GaussianFactorGraph(*this).error(x);
821 }
822 
823 /* ************************************************************************* */
825  // Create result
826  VectorValues g;
827 
828  // Sum up contributions for each clique
829  for (const auto& root : this->roots()) root->addGradientAtZero(&g);
830 
831  return g;
832 }
833 
834 } // 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:486
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:800
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:90
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:819
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:490
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:724
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:785
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:813
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: SFMdata.h:40
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:806
gtsam::GaussianFactorGraph::error
double error(const VectorValues &x) const
Definition: GaussianFactorGraph.cpp:71
iter
iterator iter(handle obj)
Definition: pytypes.h:2475
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:824
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:37
gtsam::ISAM2::params
const ISAM2Params & params() const
Definition: ISAM2.h:279


gtsam
Author(s):
autogenerated on Sat Nov 16 2024 04:02:32