Caching linearized factors in iSAM2, improves speed when linearization is expensive
Merge remote-tracking branch 'svn/branches/iSAM2_cache_linearized' into trunk Conflicts: .cprojectrelease/4.3a0
parent
2c62712be6
commit
91e7dc5882
|
@ -96,7 +96,7 @@ namespace gtsam {
|
||||||
* to already be inverted. This acts just as a change-of-name for each
|
* to already be inverted. This acts just as a change-of-name for each
|
||||||
* variable. The order of the variables within the factor is not changed.
|
* variable. The order of the variables within the factor is not changed.
|
||||||
*/
|
*/
|
||||||
virtual void permuteWithInverse(const Permutation& inversePermutation) = 0;
|
virtual void permuteWithInverse(const Permutation& inversePermutation) { IndexFactor::permuteWithInverse(inversePermutation); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** Serialization function */
|
/** Serialization function */
|
||||||
|
|
|
@ -51,7 +51,8 @@ namespace gtsam {
|
||||||
void GaussianFactorGraph::permuteWithInverse(
|
void GaussianFactorGraph::permuteWithInverse(
|
||||||
const Permutation& inversePermutation) {
|
const Permutation& inversePermutation) {
|
||||||
BOOST_FOREACH(const sharedFactor& factor, factors_) {
|
BOOST_FOREACH(const sharedFactor& factor, factors_) {
|
||||||
factor->permuteWithInverse(inversePermutation);
|
if(factor)
|
||||||
|
factor->permuteWithInverse(inversePermutation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -270,14 +270,6 @@ namespace gtsam {
|
||||||
* @return The linear term \f$ g \f$ */
|
* @return The linear term \f$ g \f$ */
|
||||||
constColumn linearTerm() const;
|
constColumn linearTerm() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Permutes the GaussianFactor, but for efficiency requires the permutation
|
|
||||||
* to already be inverted. This acts just as a change-of-name for each
|
|
||||||
* variable. The order of the variables within the factor is not changed.
|
|
||||||
*/
|
|
||||||
virtual void permuteWithInverse(const Permutation& inversePermutation) {
|
|
||||||
IndexFactor::permuteWithInverse(inversePermutation); }
|
|
||||||
|
|
||||||
// Friend unit test classes
|
// Friend unit test classes
|
||||||
friend class ::ConversionConstructorHessianFactorTest;
|
friend class ::ConversionConstructorHessianFactorTest;
|
||||||
friend class ::Constructor1HessianFactorTest;
|
friend class ::Constructor1HessianFactorTest;
|
||||||
|
|
|
@ -250,43 +250,6 @@ namespace gtsam {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
|
||||||
void JacobianFactor::permuteWithInverse(const Permutation& inversePermutation) {
|
|
||||||
|
|
||||||
// Build a map from the new variable indices to the old slot positions.
|
|
||||||
typedef FastMap<size_t, size_t> SourceSlots;
|
|
||||||
SourceSlots sourceSlots;
|
|
||||||
for(size_t j=0; j<size(); ++j)
|
|
||||||
sourceSlots.insert(make_pair(inversePermutation[keys_[j]], j));
|
|
||||||
|
|
||||||
// Build a vector of variable dimensions in the new order
|
|
||||||
vector<size_t> dimensions(size() + 1);
|
|
||||||
size_t j = 0;
|
|
||||||
BOOST_FOREACH(const SourceSlots::value_type& sourceSlot, sourceSlots) {
|
|
||||||
dimensions[j++] = Ab_(sourceSlot.second).cols();
|
|
||||||
}
|
|
||||||
assert(j == size());
|
|
||||||
dimensions.back() = 1;
|
|
||||||
|
|
||||||
// Copy the variables and matrix into the new order
|
|
||||||
vector<Index> oldKeys(size());
|
|
||||||
keys_.swap(oldKeys);
|
|
||||||
AbMatrix oldMatrix;
|
|
||||||
BlockAb oldAb(oldMatrix, dimensions.begin(), dimensions.end(), Ab_.rows());
|
|
||||||
Ab_.swap(oldAb);
|
|
||||||
j = 0;
|
|
||||||
BOOST_FOREACH(const SourceSlots::value_type& sourceSlot, sourceSlots) {
|
|
||||||
keys_[j] = sourceSlot.first;
|
|
||||||
Ab_(j++).noalias() = oldAb(sourceSlot.second);
|
|
||||||
}
|
|
||||||
Ab_(j).noalias() = oldAb(j);
|
|
||||||
|
|
||||||
// Since we're permuting the variables, ensure that entire rows from this
|
|
||||||
// factor are copied when Combine is called
|
|
||||||
BOOST_FOREACH(size_t& varpos, firstNonzeroBlocks_) { varpos = 0; }
|
|
||||||
assertInvariants();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
Vector JacobianFactor::unweighted_error(const VectorValues& c) const {
|
Vector JacobianFactor::unweighted_error(const VectorValues& c) const {
|
||||||
Vector e = -getb();
|
Vector e = -getb();
|
||||||
|
|
|
@ -169,13 +169,6 @@ namespace gtsam {
|
||||||
*/
|
*/
|
||||||
virtual size_t getDim(const_iterator variable) const { return Ab_(variable - begin()).cols(); }
|
virtual size_t getDim(const_iterator variable) const { return Ab_(variable - begin()).cols(); }
|
||||||
|
|
||||||
/**
|
|
||||||
* Permutes the GaussianFactor, but for efficiency requires the permutation
|
|
||||||
* to already be inverted. This acts just as a change-of-name for each
|
|
||||||
* variable. The order of the variables within the factor is not changed.
|
|
||||||
*/
|
|
||||||
virtual void permuteWithInverse(const Permutation& inversePermutation);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return the number of rows in the corresponding linear system
|
* return the number of rows in the corresponding linear system
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -552,7 +552,7 @@ TEST(GaussianFactor, permuteWithInverse)
|
||||||
actual.permuteWithInverse(inversePermutation);
|
actual.permuteWithInverse(inversePermutation);
|
||||||
// actualIndex.permute(*inversePermutation.inverse());
|
// actualIndex.permute(*inversePermutation.inverse());
|
||||||
|
|
||||||
JacobianFactor expected(0, A3, 2, A2, 4, A1, b, sharedSigma(2, 1.0));
|
JacobianFactor expected(4, A1, 2, A2, 0, A3, b, sharedSigma(2, 1.0));
|
||||||
GaussianFactorGraph expectedFG; expectedFG.push_back(JacobianFactor::shared_ptr(new JacobianFactor(expected)));
|
GaussianFactorGraph expectedFG; expectedFG.push_back(JacobianFactor::shared_ptr(new JacobianFactor(expected)));
|
||||||
// GaussianVariableIndex expectedIndex(expectedFG);
|
// GaussianVariableIndex expectedIndex(expectedFG);
|
||||||
|
|
||||||
|
|
|
@ -257,6 +257,9 @@ ISAM2::Impl::PartialSolve(GaussianFactorGraph& factors,
|
||||||
cout << "Full var-ordered eliminated BT:\n";
|
cout << "Full var-ordered eliminated BT:\n";
|
||||||
result.bayesTree->printTree("");
|
result.bayesTree->printTree("");
|
||||||
}
|
}
|
||||||
|
// Undo permutation on our subset of cached factors, we must later permute *all* of the cached factors
|
||||||
|
factors.permuteWithInverse(*affectedColamd);
|
||||||
|
factors.permuteWithInverse(affectedKeysSelector);
|
||||||
toc(8,"permute eliminated");
|
toc(8,"permute eliminated");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -78,6 +78,12 @@ ISAM2& ISAM2::operator=(const ISAM2& rhs) {
|
||||||
deltaUptodate_ = rhs.deltaUptodate_;
|
deltaUptodate_ = rhs.deltaUptodate_;
|
||||||
deltaReplacedMask_ = rhs.deltaReplacedMask_;
|
deltaReplacedMask_ = rhs.deltaReplacedMask_;
|
||||||
nonlinearFactors_ = rhs.nonlinearFactors_;
|
nonlinearFactors_ = rhs.nonlinearFactors_;
|
||||||
|
|
||||||
|
linearFactors_ = GaussianFactorGraph();
|
||||||
|
linearFactors_.reserve(rhs.linearFactors_.size());
|
||||||
|
BOOST_FOREACH(const GaussianFactor::shared_ptr& linearFactor, rhs.linearFactors_) {
|
||||||
|
linearFactors_.push_back(linearFactor->clone()); }
|
||||||
|
|
||||||
ordering_ = rhs.ordering_;
|
ordering_ = rhs.ordering_;
|
||||||
params_ = rhs.params_;
|
params_ = rhs.params_;
|
||||||
doglegDelta_ = rhs.doglegDelta_;
|
doglegDelta_ = rhs.doglegDelta_;
|
||||||
|
@ -125,7 +131,7 @@ FastList<size_t> ISAM2::getAffectedFactors(const FastList<Index>& keys) const {
|
||||||
// retrieve all factors that ONLY contain the affected variables
|
// retrieve all factors that ONLY contain the affected variables
|
||||||
// (note that the remaining stuff is summarized in the cached factors)
|
// (note that the remaining stuff is summarized in the cached factors)
|
||||||
FactorGraph<GaussianFactor>::shared_ptr
|
FactorGraph<GaussianFactor>::shared_ptr
|
||||||
ISAM2::relinearizeAffectedFactors(const FastList<Index>& affectedKeys) const {
|
ISAM2::relinearizeAffectedFactors(const FastList<Index>& affectedKeys, const FastSet<Index>& relinKeys) const {
|
||||||
|
|
||||||
tic(1,"getAffectedFactors");
|
tic(1,"getAffectedFactors");
|
||||||
FastList<size_t> candidates = getAffectedFactors(affectedKeys);
|
FastList<size_t> candidates = getAffectedFactors(affectedKeys);
|
||||||
|
@ -139,24 +145,37 @@ ISAM2::relinearizeAffectedFactors(const FastList<Index>& affectedKeys) const {
|
||||||
affectedKeysSet.insert(affectedKeys.begin(), affectedKeys.end());
|
affectedKeysSet.insert(affectedKeys.begin(), affectedKeys.end());
|
||||||
toc(2,"affectedKeysSet");
|
toc(2,"affectedKeysSet");
|
||||||
|
|
||||||
tic(3,"check candidates");
|
tic(3,"check candidates and linearize");
|
||||||
|
FactorGraph<GaussianFactor>::shared_ptr linearized = boost::make_shared<FactorGraph<GaussianFactor> >();
|
||||||
BOOST_FOREACH(size_t idx, candidates) {
|
BOOST_FOREACH(size_t idx, candidates) {
|
||||||
bool inside = true;
|
bool inside = true;
|
||||||
|
bool useCachedLinear = params_.cacheLinearizedFactors;
|
||||||
BOOST_FOREACH(Key key, nonlinearFactors_[idx]->keys()) {
|
BOOST_FOREACH(Key key, nonlinearFactors_[idx]->keys()) {
|
||||||
Index var = ordering_[key];
|
Index var = ordering_[key];
|
||||||
if (affectedKeysSet.find(var) == affectedKeysSet.end()) {
|
if(affectedKeysSet.find(var) == affectedKeysSet.end()) {
|
||||||
inside = false;
|
inside = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(useCachedLinear && relinKeys.find(var) != relinKeys.end())
|
||||||
|
useCachedLinear = false;
|
||||||
|
}
|
||||||
|
if(inside) {
|
||||||
|
if(useCachedLinear) {
|
||||||
|
assert(linearFactors_[idx]);
|
||||||
|
linearized->push_back(linearFactors_[idx]);
|
||||||
|
assert(linearFactors_[idx]->keys() == nonlinearFactors_[idx]->symbolic(ordering_)->keys());
|
||||||
|
} else {
|
||||||
|
GaussianFactor::shared_ptr linearFactor = nonlinearFactors_[idx]->linearize(theta_, ordering_);
|
||||||
|
linearized->push_back(linearFactor);
|
||||||
|
if(params_.cacheLinearizedFactors) {
|
||||||
|
assert(linearFactors_[idx]->keys() == linearFactor->keys());
|
||||||
|
linearFactors_[idx] = linearFactor;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (inside)
|
|
||||||
nonlinearAffectedFactors.push_back(nonlinearFactors_[idx]);
|
|
||||||
}
|
}
|
||||||
toc(3,"check candidates");
|
toc(3,"check candidates and linearize");
|
||||||
|
|
||||||
tic(4,"linearize");
|
|
||||||
FactorGraph<GaussianFactor>::shared_ptr linearized(nonlinearAffectedFactors.linearize(theta_, ordering_));
|
|
||||||
toc(4,"linearize");
|
|
||||||
return linearized;
|
return linearized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +206,7 @@ GaussianFactorGraph ISAM2::getCachedBoundaryFactors(Cliques& orphans) {
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<FastSet<Index> > ISAM2::recalculate(
|
boost::shared_ptr<FastSet<Index> > ISAM2::recalculate(
|
||||||
const FastSet<Index>& markedKeys, const FastVector<Index>& newKeys, const FactorGraph<GaussianFactor>::shared_ptr newFactors,
|
const FastSet<Index>& markedKeys, const FastSet<Index>& relinKeys, const FastVector<Index>& newKeys,
|
||||||
const boost::optional<FastMap<Index,int> >& constrainKeys, ISAM2Result& result) {
|
const boost::optional<FastMap<Index,int> >& constrainKeys, ISAM2Result& result) {
|
||||||
|
|
||||||
// TODO: new factors are linearized twice, the newFactors passed in are not used.
|
// TODO: new factors are linearized twice, the newFactors passed in are not used.
|
||||||
|
@ -300,11 +319,11 @@ boost::shared_ptr<FastSet<Index> > ISAM2::recalculate(
|
||||||
toc(1,"reorder");
|
toc(1,"reorder");
|
||||||
|
|
||||||
tic(2,"linearize");
|
tic(2,"linearize");
|
||||||
GaussianFactorGraph factors(*nonlinearFactors_.linearize(theta_, ordering_));
|
linearFactors_ = *nonlinearFactors_.linearize(theta_, ordering_);
|
||||||
toc(2,"linearize");
|
toc(2,"linearize");
|
||||||
|
|
||||||
tic(5,"eliminate");
|
tic(5,"eliminate");
|
||||||
JunctionTree<GaussianFactorGraph, Base::Clique> jt(factors, variableIndex_);
|
JunctionTree<GaussianFactorGraph, Base::Clique> jt(linearFactors_, variableIndex_);
|
||||||
sharedClique newRoot;
|
sharedClique newRoot;
|
||||||
if(params_.factorization == ISAM2Params::LDL)
|
if(params_.factorization == ISAM2Params::LDL)
|
||||||
newRoot = jt.eliminate(EliminatePreferLDL);
|
newRoot = jt.eliminate(EliminatePreferLDL);
|
||||||
|
@ -325,7 +344,7 @@ boost::shared_ptr<FastSet<Index> > ISAM2::recalculate(
|
||||||
|
|
||||||
lastAffectedMarkedCount = markedKeys.size();
|
lastAffectedMarkedCount = markedKeys.size();
|
||||||
lastAffectedVariableCount = affectedKeysSet->size();
|
lastAffectedVariableCount = affectedKeysSet->size();
|
||||||
lastAffectedFactorCount = factors.size();
|
lastAffectedFactorCount = linearFactors_.size();
|
||||||
|
|
||||||
return affectedKeysSet;
|
return affectedKeysSet;
|
||||||
|
|
||||||
|
@ -338,7 +357,7 @@ boost::shared_ptr<FastSet<Index> > ISAM2::recalculate(
|
||||||
affectedAndNewKeys.insert(affectedAndNewKeys.end(), affectedKeys.begin(), affectedKeys.end());
|
affectedAndNewKeys.insert(affectedAndNewKeys.end(), affectedKeys.begin(), affectedKeys.end());
|
||||||
affectedAndNewKeys.insert(affectedAndNewKeys.end(), newKeys.begin(), newKeys.end());
|
affectedAndNewKeys.insert(affectedAndNewKeys.end(), newKeys.begin(), newKeys.end());
|
||||||
tic(1,"relinearizeAffected");
|
tic(1,"relinearizeAffected");
|
||||||
GaussianFactorGraph factors(*relinearizeAffectedFactors(affectedAndNewKeys));
|
GaussianFactorGraph factors(*relinearizeAffectedFactors(affectedAndNewKeys, relinKeys));
|
||||||
if(debug) factors.print("Relinearized factors: ");
|
if(debug) factors.print("Relinearized factors: ");
|
||||||
toc(1,"relinearizeAffected");
|
toc(1,"relinearizeAffected");
|
||||||
|
|
||||||
|
@ -360,11 +379,7 @@ boost::shared_ptr<FastSet<Index> > ISAM2::recalculate(
|
||||||
// add the cached intermediate results from the boundary of the orphans ...
|
// add the cached intermediate results from the boundary of the orphans ...
|
||||||
GaussianFactorGraph cachedBoundary = getCachedBoundaryFactors(orphans);
|
GaussianFactorGraph cachedBoundary = getCachedBoundaryFactors(orphans);
|
||||||
if(debug) cachedBoundary.print("Boundary factors: ");
|
if(debug) cachedBoundary.print("Boundary factors: ");
|
||||||
factors.reserve(factors.size() + cachedBoundary.size());
|
factors.push_back(cachedBoundary);
|
||||||
// Copy so that we can later permute factors
|
|
||||||
BOOST_FOREACH(const GaussianFactor::shared_ptr& cached, cachedBoundary) {
|
|
||||||
factors.push_back(cached->clone());
|
|
||||||
}
|
|
||||||
toc(2,"cached");
|
toc(2,"cached");
|
||||||
|
|
||||||
// END OF COPIED CODE
|
// END OF COPIED CODE
|
||||||
|
@ -410,6 +425,15 @@ boost::shared_ptr<FastSet<Index> > ISAM2::recalculate(
|
||||||
tic(5,"permute ordering");
|
tic(5,"permute ordering");
|
||||||
ordering_.permuteWithInverse(partialSolveResult.fullReorderingInverse);
|
ordering_.permuteWithInverse(partialSolveResult.fullReorderingInverse);
|
||||||
toc(5,"permute ordering");
|
toc(5,"permute ordering");
|
||||||
|
if(params_.cacheLinearizedFactors) {
|
||||||
|
tic(6,"permute cached linear");
|
||||||
|
//linearFactors_.permuteWithInverse(partialSolveResult.fullReorderingInverse);
|
||||||
|
FastList<size_t> permuteLinearIndices = getAffectedFactors(affectedAndNewKeys);
|
||||||
|
BOOST_FOREACH(size_t idx, permuteLinearIndices) {
|
||||||
|
linearFactors_[idx]->permuteWithInverse(partialSolveResult.fullReorderingInverse);
|
||||||
|
}
|
||||||
|
toc(6,"permute cached linear");
|
||||||
|
}
|
||||||
|
|
||||||
toc(4,"reorder and eliminate");
|
toc(4,"reorder and eliminate");
|
||||||
|
|
||||||
|
@ -526,11 +550,12 @@ ISAM2Result ISAM2::update(
|
||||||
toc(4,"gather involved keys");
|
toc(4,"gather involved keys");
|
||||||
|
|
||||||
// Check relinearization if we're at the nth step, or we are using a looser loop relin threshold
|
// Check relinearization if we're at the nth step, or we are using a looser loop relin threshold
|
||||||
|
FastSet<Index> relinKeys;
|
||||||
if (relinearizeThisStep) {
|
if (relinearizeThisStep) {
|
||||||
tic(5,"gather relinearize keys");
|
tic(5,"gather relinearize keys");
|
||||||
vector<bool> markedRelinMask(ordering_.nVars(), false);
|
vector<bool> markedRelinMask(ordering_.nVars(), false);
|
||||||
// 4. Mark keys in \Delta above threshold \beta: J=\{\Delta_{j}\in\Delta|\Delta_{j}\geq\beta\}.
|
// 4. Mark keys in \Delta above threshold \beta: J=\{\Delta_{j}\in\Delta|\Delta_{j}\geq\beta\}.
|
||||||
FastSet<Index> relinKeys = Impl::CheckRelinearization(delta_, ordering_, params_.relinearizeThreshold);
|
relinKeys = Impl::CheckRelinearization(delta_, ordering_, params_.relinearizeThreshold);
|
||||||
if(disableReordering) relinKeys = Impl::CheckRelinearization(delta_, ordering_, 0.0); // This is used for debugging
|
if(disableReordering) relinKeys = Impl::CheckRelinearization(delta_, ordering_, 0.0); // This is used for debugging
|
||||||
|
|
||||||
// Add the variables being relinearized to the marked keys
|
// Add the variables being relinearized to the marked keys
|
||||||
|
@ -563,15 +588,21 @@ ISAM2Result ISAM2::update(
|
||||||
}
|
}
|
||||||
|
|
||||||
tic(8,"linearize new");
|
tic(8,"linearize new");
|
||||||
tic(1,"linearize");
|
|
||||||
// 7. Linearize new factors
|
// 7. Linearize new factors
|
||||||
FactorGraph<GaussianFactor>::shared_ptr linearFactors = newFactors.linearize(theta_, ordering_);
|
if(params_.cacheLinearizedFactors) {
|
||||||
toc(1,"linearize");
|
tic(1,"linearize");
|
||||||
|
FactorGraph<GaussianFactor>::shared_ptr linearFactors = newFactors.linearize(theta_, ordering_);
|
||||||
|
linearFactors_.push_back(*linearFactors);
|
||||||
|
assert(nonlinearFactors_.size() == linearFactors_.size());
|
||||||
|
toc(1,"linearize");
|
||||||
|
|
||||||
tic(2,"augment VI");
|
tic(2,"augment VI");
|
||||||
// Augment the variable index with the new factors
|
// Augment the variable index with the new factors
|
||||||
variableIndex_.augment(*linearFactors);
|
variableIndex_.augment(*linearFactors);
|
||||||
toc(2,"augment VI");
|
toc(2,"augment VI");
|
||||||
|
} else {
|
||||||
|
variableIndex_.augment(*newFactors.symbolic(ordering_));
|
||||||
|
}
|
||||||
toc(8,"linearize new");
|
toc(8,"linearize new");
|
||||||
|
|
||||||
tic(9,"recalculate");
|
tic(9,"recalculate");
|
||||||
|
@ -587,7 +618,7 @@ ISAM2Result ISAM2::update(
|
||||||
}
|
}
|
||||||
boost::shared_ptr<FastSet<Index> > replacedKeys;
|
boost::shared_ptr<FastSet<Index> > replacedKeys;
|
||||||
if(!markedKeys.empty() || !newKeys.empty())
|
if(!markedKeys.empty() || !newKeys.empty())
|
||||||
replacedKeys = recalculate(markedKeys, newKeys, linearFactors, constrainedIndices, result);
|
replacedKeys = recalculate(markedKeys, relinKeys, newKeys, constrainedIndices, result);
|
||||||
|
|
||||||
// Update replaced keys mask (accumulates until back-substitution takes place)
|
// Update replaced keys mask (accumulates until back-substitution takes place)
|
||||||
if(replacedKeys) {
|
if(replacedKeys) {
|
||||||
|
|
|
@ -118,6 +118,13 @@ struct ISAM2Params {
|
||||||
*/
|
*/
|
||||||
Factorization factorization;
|
Factorization factorization;
|
||||||
|
|
||||||
|
/** Whether to cache linear factors (default: true).
|
||||||
|
* This can improve performance if linearization is expensive, but can hurt
|
||||||
|
* performance if linearization is very cleap due to computation to look up
|
||||||
|
* additional keys.
|
||||||
|
*/
|
||||||
|
bool cacheLinearizedFactors;
|
||||||
|
|
||||||
KeyFormatter keyFormatter; ///< A KeyFormatter for when keys are printed during debugging (default: DefaultKeyFormatter)
|
KeyFormatter keyFormatter; ///< A KeyFormatter for when keys are printed during debugging (default: DefaultKeyFormatter)
|
||||||
|
|
||||||
/** Specify parameters as constructor arguments */
|
/** Specify parameters as constructor arguments */
|
||||||
|
@ -128,11 +135,12 @@ struct ISAM2Params {
|
||||||
bool _enableRelinearization = true, ///< see ISAM2Params::enableRelinearization
|
bool _enableRelinearization = true, ///< see ISAM2Params::enableRelinearization
|
||||||
bool _evaluateNonlinearError = false, ///< see ISAM2Params::evaluateNonlinearError
|
bool _evaluateNonlinearError = false, ///< see ISAM2Params::evaluateNonlinearError
|
||||||
Factorization _factorization = ISAM2Params::LDL, ///< see ISAM2Params::factorization
|
Factorization _factorization = ISAM2Params::LDL, ///< see ISAM2Params::factorization
|
||||||
|
bool _cacheLinearizedFactors = true, ///< see ISAM2Params::cacheLinearizedFactors
|
||||||
const KeyFormatter& _keyFormatter = DefaultKeyFormatter ///< see ISAM2::Params::keyFormatter
|
const KeyFormatter& _keyFormatter = DefaultKeyFormatter ///< see ISAM2::Params::keyFormatter
|
||||||
) : optimizationParams(_optimizationParams), relinearizeThreshold(_relinearizeThreshold),
|
) : optimizationParams(_optimizationParams), relinearizeThreshold(_relinearizeThreshold),
|
||||||
relinearizeSkip(_relinearizeSkip), enableRelinearization(_enableRelinearization),
|
relinearizeSkip(_relinearizeSkip), enableRelinearization(_enableRelinearization),
|
||||||
evaluateNonlinearError(_evaluateNonlinearError), factorization(_factorization),
|
evaluateNonlinearError(_evaluateNonlinearError), factorization(_factorization),
|
||||||
keyFormatter(_keyFormatter) {}
|
cacheLinearizedFactors(_cacheLinearizedFactors), keyFormatter(_keyFormatter) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -341,6 +349,9 @@ protected:
|
||||||
/** All original nonlinear factors are stored here to use during relinearization */
|
/** All original nonlinear factors are stored here to use during relinearization */
|
||||||
NonlinearFactorGraph nonlinearFactors_;
|
NonlinearFactorGraph nonlinearFactors_;
|
||||||
|
|
||||||
|
/** The current linear factors, which are only updated as needed */
|
||||||
|
mutable GaussianFactorGraph linearFactors_;
|
||||||
|
|
||||||
/** The current elimination ordering Symbols to Index (integer) keys.
|
/** The current elimination ordering Symbols to Index (integer) keys.
|
||||||
*
|
*
|
||||||
* We keep it up to date as we add and reorder variables.
|
* We keep it up to date as we add and reorder variables.
|
||||||
|
@ -453,11 +464,11 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
FastList<size_t> getAffectedFactors(const FastList<Index>& keys) const;
|
FastList<size_t> getAffectedFactors(const FastList<Index>& keys) const;
|
||||||
FactorGraph<GaussianFactor>::shared_ptr relinearizeAffectedFactors(const FastList<Index>& affectedKeys) const;
|
FactorGraph<GaussianFactor>::shared_ptr relinearizeAffectedFactors(const FastList<Index>& affectedKeys, const FastSet<Index>& relinKeys) const;
|
||||||
GaussianFactorGraph getCachedBoundaryFactors(Cliques& orphans);
|
GaussianFactorGraph getCachedBoundaryFactors(Cliques& orphans);
|
||||||
|
|
||||||
boost::shared_ptr<FastSet<Index> > recalculate(const FastSet<Index>& markedKeys,
|
boost::shared_ptr<FastSet<Index> > recalculate(const FastSet<Index>& markedKeys, const FastSet<Index>& relinKeys,
|
||||||
const FastVector<Index>& newKeys, const FactorGraph<GaussianFactor>::shared_ptr newFactors,
|
const FastVector<Index>& newKeys,
|
||||||
const boost::optional<FastMap<Index,int> >& constrainKeys, ISAM2Result& result);
|
const boost::optional<FastMap<Index,int> >& constrainKeys, ISAM2Result& result);
|
||||||
// void linear_update(const GaussianFactorGraph& newFactors);
|
// void linear_update(const GaussianFactorGraph& newFactors);
|
||||||
void updateDelta(bool forceFullSolve = false) const;
|
void updateDelta(bool forceFullSolve = false) const;
|
||||||
|
|
Loading…
Reference in New Issue