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