38 template class BayesTree<ISAM2Clique>;
72 gttic(affectedKeysSet);
75 affectedKeysSet.insert(affectedKeys.begin(), affectedKeys.end());
76 gttoc(affectedKeysSet);
78 gttic(check_candidates_and_linearize);
84 if (affectedKeysSet.find(
key) == affectedKeysSet.end()) {
88 if (useCachedLinear && relinKeys.find(
key) != relinKeys.end())
89 useCachedLinear =
false;
92 if (useCachedLinear) {
93 #ifdef GTSAM_EXTRA_CONSISTENCY_CHECKS
102 #ifdef GTSAM_EXTRA_CONSISTENCY_CHECKS
110 gttoc(check_candidates_and_linearize);
121 if (!
result->markedKeys.empty() || !
result->observedKeys.empty()) {
130 &affectedBayesNet, &orphans);
149 for (
const auto& conditional : affectedBayesNet)
150 affectedKeys.insert(affectedKeys.end(), conditional->beginFrontals(),
151 conditional->endFrontals());
155 static const double kBatchThreshold = 0.65;
156 if (affectedKeys.size() >=
theta_.
size() * kBatchThreshold) {
161 &affectedKeysSet, &orphans,
result);
166 for (
const auto& root :
roots_)
167 for (
Key var : *root->conditional())
168 result->detail->variableStatus[var].inRootClique =
true;
185 affectedKeysSet->insert(
key);
191 result->unusedKeys.end());
194 affectedKeysSet->erase(
key);
207 for (
Key var :
result->observedKeys) constraintGroups[var] = 1;
232 bayesTree->roots().end());
234 nodes_.insert(bayesTree->nodes().begin(), bayesTree->nodes().end());
237 result->variablesReeliminated = affectedKeysSet->size();
243 result->detail->variableStatus[
key].isReeliminated =
true;
259 affectedAndNewKeys.insert(affectedAndNewKeys.end(), affectedKeys.begin(),
261 affectedAndNewKeys.insert(affectedAndNewKeys.end(),
262 result->observedKeys.begin(),
263 result->observedKeys.end());
268 factors.print(
"Relinearized factors: ");
269 std::cout <<
"Affected keys: ";
270 for (
const Key key : affectedKeys) {
271 std::cout <<
key <<
" ";
273 std::cout << std::endl;
278 for (
Key key : affectedAndNewKeys) {
279 result->detail->variableStatus[
key].isReeliminated =
true;
283 result->variablesReeliminated = affectedAndNewKeys.size();
290 if (
debug) cachedBoundary.
print(
"Boundary factors: ");
291 factors.push_back(cachedBoundary);
296 for (
const auto& orphan : *orphans)
304 gttic(reorder_and_eliminate);
310 affectedKeysSet->insert(
result->markedKeys.begin(),
result->markedKeys.end());
311 affectedKeysSet->insert(affectedKeys.begin(), affectedKeys.end());
316 gttic(ordering_constraints);
324 result->observedKeys.size() < affectedFactorsVarIndex.
size() ? 1 : 0;
326 constraintGroups.emplace(var, group);
331 iter != constraintGroups.end();
335 constraintGroups.erase(
iter++);
339 gttoc(ordering_constraints);
352 gttoc(reorder_and_eliminate);
356 bayesTree->roots().end());
357 nodes_.insert(bayesTree->nodes().begin(), bayesTree->nodes().end());
366 gttic(addNewVariables);
369 if (
ISDEBUG(
"ISAM2 AddVariables")) newTheta.
print(
"The new variables are: ");
378 detail->variableStatus[
key].isNew =
true;
388 for (
Key key : unusedKeys) {
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;
439 &
result.keysWithRemovedFactors);
453 result.variablesRelinearized = 0;
458 update.recordRelinearizeDetail(relinKeys,
result.details());
459 if (!relinKeys.empty()) {
466 result.variablesRelinearized =
result.markedKeys.size();
472 update.augmentVariableIndex(newFactors,
result.newFactorsIndices,
491 KeySet leafKeys(leafKeysList.begin(), leafKeysList.end());
496 map<Key, vector<GaussianFactor::shared_ptr> > marginalFactors;
505 auto trackingRemoveSubtree = [&](
const sharedClique& 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()) {
514 factorIndicesToRemove.insert(involved.begin(), involved.end());
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.");
525 return removedCliques;
529 for (
Key j : leafKeys) {
530 if (!leafKeysRemoved.
exists(
j)) {
535 while (
clique->parent_.use_count() != 0) {
539 if (leafKeys.exists(parent->conditional()->front()))
546 bool marginalizeEntireClique =
true;
547 for (
Key frontal :
clique->conditional()->frontals()) {
548 if (!leafKeys.exists(frontal)) {
549 marginalizeEntireClique =
false;
555 if (marginalizeEntireClique) {
565 marginalFactors[
clique->parent()->conditional()->front()].push_back(
570 trackingRemoveSubtree(
clique);
580 KeySet factorsInSubtreeRoot;
584 for (
Key parent : child->conditional()->parents()) {
585 if (leafKeys.exists(parent)) {
586 subtreesToRemove.push_back(child);
587 graph.push_back(child->cachedFactor());
594 const Cliques removed = trackingRemoveSubtree(subtree);
595 childrenRemoved.insert(childrenRemoved.end(), removed.begin(),
604 KeySet factorsFromMarginalizedInClique_step1;
605 for (
Key frontal :
clique->conditional()->frontals()) {
606 if (leafKeys.exists(frontal))
607 factorsFromMarginalizedInClique_step1.insert(
611 for (
const sharedClique& removedChild : childrenRemoved) {
612 for (
Key indexInClique : removedChild->conditional()->frontals()) {
614 factorsFromMarginalizedInClique_step1.erase(factorInvolving);
619 for (
const auto index : factorsFromMarginalizedInClique_step1) {
625 auto cg =
clique->conditional();
626 const KeySet cliqueFrontals(cg->beginFrontals(), cg->endFrontals());
628 std::set_intersection(cliqueFrontals.begin(), cliqueFrontals.end(),
629 leafKeys.begin(), leafKeys.end(),
630 std::back_inserter(cliqueFrontalsToEliminate));
635 if (eliminationResult1.second)
636 marginalFactors[cg->front()].push_back(eliminationResult1.second);
641 while (leafKeys.exists(cg->keys()[nToRemove])) ++nToRemove;
644 const DenseIndex dimToRemove = cg->matrixObject().offset(nToRemove);
645 cg->matrixObject().firstBlock() += nToRemove;
646 cg->matrixObject().rowStart() = dimToRemove;
650 originalKeys.swap(cg->keys());
651 cg->keys().assign(originalKeys.begin() + nToRemove, originalKeys.end());
652 cg->nrFrontals() -= nToRemove;
656 for (
Key frontal : cliqueFrontalsToEliminate) {
658 factorIndicesToRemove.insert(involved.begin(), involved.end());
662 leafKeysRemoved.insert(cliqueFrontalsToEliminate.begin(),
663 cliqueFrontalsToEliminate.end());
673 for (
const auto index : factorIndicesToRemove) {
681 factorIndicesToRemove.end(), removedFactors);
686 for (
const auto& key_factors : marginalFactors) {
687 for (
const auto& factor : key_factors.second) {
691 for (
Key factorKey : *factor) {
713 if (deletedFactorsIndices) {
714 deletedFactorsIndices->assign(factorIndicesToRemove.begin(),
715 factorIndicesToRemove.end());
717 if (marginalFactorsIndices){
718 *marginalFactorsIndices = std::move(newFactorIndices);
730 const double effectiveWildfireThreshold =
732 gttic(Wildfire_update);
734 effectiveWildfireThreshold, &
delta_);
736 gttoc(Wildfire_update);
742 const double effectiveWildfireThreshold =
746 gttic(Dogleg_Iterate);
749 gttic(Wildfire_update);
752 gttoc(Wildfire_update);
771 gttoc(Dogleg_Iterate);
780 throw std::runtime_error(
"iSAM2: unknown ISAM2Params type");
786 gttic(ISAM2_calculateEstimate);
829 for (
const auto& root : this->
roots()) root->addGradientAtZero(&
g);