ISAM2 refactoring and documentation
parent
660127489d
commit
936ee6d9fd
|
|
@ -14,8 +14,34 @@ namespace gtsam {
|
|||
|
||||
template<class CONDITIONAL, class VALUES>
|
||||
struct ISAM2<CONDITIONAL, VALUES>::Impl {
|
||||
static void AddVariables(const VALUES& newTheta, VALUES& theta, Permuted<VectorValues>& delta, Ordering& ordering, typename Base::Nodes& nodes);
|
||||
static FastSet<Index> IndicesFromFactors(const Ordering& ordering, const NonlinearFactorGraph<VALUES>& factors);
|
||||
/**
|
||||
* Add new variables to the ISAM2 system.
|
||||
* @param newTheta Initial values for new variables
|
||||
* @param theta Current solution to be augmented with new initialization
|
||||
* @param delta Current linear delta to be augmented with zeros
|
||||
* @param ordering Current ordering to be augmented with new variables
|
||||
* @param nodes Current BayesTree::Nodes index to be augmented with slots for new variables
|
||||
*/
|
||||
static void AddVariables(const VALUES& newTheta, VALUES& theta, Permuted<VectorValues>& delta, Ordering& ordering, typename Base::Nodes& nodes);
|
||||
|
||||
/**
|
||||
* Extract the set of variable indices from a NonlinearFactorGraph. For each Symbol
|
||||
* in each NonlinearFactor, obtains the index by calling ordering[symbol].
|
||||
* @param ordering The current ordering from which to obtain the variable indices
|
||||
* @param factors The factors from which to extract the variables
|
||||
* @return The set of variables indices from the factors
|
||||
*/
|
||||
static FastSet<Index> IndicesFromFactors(const Ordering& ordering, const NonlinearFactorGraph<VALUES>& factors);
|
||||
|
||||
/**
|
||||
* Find the set of variables to be relinearized according to relinearizeThreshold.
|
||||
* Any variables in the VectorValues delta whose vector magnitude is greater than
|
||||
* or equal to relinearizeThreshold are returned.
|
||||
* @param delta The linear delta to check against the threshold
|
||||
* @return The set of variable indices in delta whose magnitude is greater than or
|
||||
* equal to relinearizeThreshold
|
||||
*/
|
||||
static FastSet<Index> CheckRelinearization(Permuted<VectorValues>& delta, double relinearizeThreshold);
|
||||
};
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
@ -70,4 +96,16 @@ FastSet<Index> ISAM2<CONDITIONAL,VALUES>::Impl::IndicesFromFactors(const Orderin
|
|||
return indices;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
template<class CONDITIONAL, class VALUES>
|
||||
FastSet<Index> ISAM2<CONDITIONAL,VALUES>::Impl::CheckRelinearization(Permuted<VectorValues>& delta, double relinearizeThreshold) {
|
||||
FastSet<Index> relinKeys;
|
||||
for(Index var=0; var<delta.size(); ++var) {
|
||||
double maxDelta = delta[var].lpNorm<Eigen::Infinity>();
|
||||
if(maxDelta >= relinearizeThreshold) {
|
||||
relinKeys.insert(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -716,21 +716,19 @@ void ISAM2<Conditional, Values>::update(
|
|||
if(structuralLast) structuralKeys = markedKeys; // If we're using structural-last ordering, make another copy
|
||||
toc(3,"gather involved keys");
|
||||
|
||||
vector<bool> markedRelinMask(ordering_.nVars(), false);
|
||||
bool relinAny = false;
|
||||
// Check relinearization if we're at a 10th step, or we are using a looser loop relin threshold
|
||||
if (force_relinearize || (params_.enableRelinearization && count % params_.relinearizeSkip == 0)) { // todo: every n steps
|
||||
tic(4,"gather relinearize keys");
|
||||
vector<bool> markedRelinMask(ordering_.nVars(), false);
|
||||
bool relinAny = false;
|
||||
// 4. Mark keys in \Delta above threshold \beta: J=\{\Delta_{j}\in\Delta|\Delta_{j}\geq\beta\}.
|
||||
for(Index var=0; var<delta_.size(); ++var) {
|
||||
//cout << var << ": " << delta_[var].transpose() << endl;
|
||||
double maxDelta = delta_[var].lpNorm<Eigen::Infinity>();
|
||||
if(maxDelta >= params_.relinearizeThreshold || disableReordering) {
|
||||
markedRelinMask[var] = true;
|
||||
markedKeys.insert(var);
|
||||
if(!relinAny) relinAny = true;
|
||||
}
|
||||
}
|
||||
FastSet<Index> relinKeys = Impl::CheckRelinearization(delta_, params_.relinearizeThreshold);
|
||||
if(disableReordering) relinKeys = Impl::CheckRelinearization(delta_, 0.0); // This is used for debugging
|
||||
|
||||
BOOST_FOREACH(const Index j, relinKeys) { markedRelinMask[j] = true; }
|
||||
markedKeys.insert(relinKeys.begin(), relinKeys.end());
|
||||
if(!relinKeys.empty())
|
||||
relinAny = true;
|
||||
toc(4,"gather relinearize keys");
|
||||
|
||||
tic(5,"fluid find_all");
|
||||
|
|
@ -739,37 +737,29 @@ void ISAM2<Conditional, Values>::update(
|
|||
// mark all cliques that involve marked variables
|
||||
if(this->root())
|
||||
find_all(this->root(), markedKeys, markedRelinMask); // add other cliques that have the marked ones in the separator
|
||||
// richard commented these out since now using an array to mark keys
|
||||
//affectedKeys.sort(); // remove duplicates
|
||||
//affectedKeys.unique();
|
||||
// merge with markedKeys
|
||||
}
|
||||
// richard commented these out since now using an array to mark keys
|
||||
//markedKeys.splice(markedKeys.begin(), affectedKeys, affectedKeys.begin(), affectedKeys.end());
|
||||
//markedKeys.sort(); // remove duplicates
|
||||
//markedKeys.unique();
|
||||
// BOOST_FOREACH(const Index var, affectedKeys) {
|
||||
// markedKeys.push_back(var);
|
||||
// }
|
||||
toc(5,"fluid find_all");
|
||||
}
|
||||
|
||||
tic(6,"expmap");
|
||||
// 6. Update linearization point for marked variables: \Theta_{J}:=\Theta_{J}+\Delta_{J}.
|
||||
if (relinAny) {
|
||||
tic(6,"expmap");
|
||||
// 6. Update linearization point for marked variables: \Theta_{J}:=\Theta_{J}+\Delta_{J}.
|
||||
if (relinAny) {
|
||||
#ifndef NDEBUG
|
||||
_SelectiveExpmapAndClear selectiveExpmap(delta_, ordering_, markedRelinMask);
|
||||
_SelectiveExpmapAndClear selectiveExpmap(delta_, ordering_, markedRelinMask);
|
||||
#else
|
||||
_SelectiveExpmap selectiveExpmap(delta_, ordering_, markedRelinMask);
|
||||
_SelectiveExpmap selectiveExpmap(delta_, ordering_, markedRelinMask);
|
||||
#endif
|
||||
theta_.apply(selectiveExpmap);
|
||||
// theta_ = theta_.expmap(deltaMarked);
|
||||
}
|
||||
toc(6,"expmap");
|
||||
theta_.apply(selectiveExpmap);
|
||||
}
|
||||
toc(6,"expmap");
|
||||
|
||||
#ifndef NDEBUG
|
||||
lastRelinVariables_ = markedRelinMask;
|
||||
lastRelinVariables_ = markedRelinMask;
|
||||
#endif
|
||||
} else {
|
||||
#ifndef NDEBUG
|
||||
lastRelinVariables_ = vector<bool>(ordering_.nVars(), false);
|
||||
#endif
|
||||
}
|
||||
|
||||
tic(7,"linearize new");
|
||||
tic(1,"linearize");
|
||||
|
|
@ -800,19 +790,6 @@ void ISAM2<Conditional, Values>::update(
|
|||
delta_.permutation() = Permutation::Identity(delta_.size());
|
||||
delta_.container() = newDelta;
|
||||
lastBacksubVariableCount = theta_.size();
|
||||
|
||||
//#ifndef NDEBUG
|
||||
// FactorGraph<JacobianFactor> linearfullJ = *nonlinearFactors_.linearize(theta_, ordering_);
|
||||
// VectorValues deltafullJ = optimize(*GenericSequentialSolver<JacobianFactor>(linearfullJ).eliminate());
|
||||
// FactorGraph<HessianFactor> linearfullH =
|
||||
// *nonlinearFactors_.linearize(theta_, ordering_)->template convertCastFactors<FactorGraph<HessianFactor> >();
|
||||
// VectorValues deltafullH = optimize(*GenericSequentialSolver<HessianFactor>(linearfullH).eliminate());
|
||||
// if(!assert_equal(deltafullJ, newDelta, 1e-2))
|
||||
// throw runtime_error("iSAM2 does not agree with full Jacobian solver");
|
||||
// if(!assert_equal(deltafullH, newDelta, 1e-2))
|
||||
// throw runtime_error("iSAM2 does not agree with full Hessian solver");
|
||||
//#endif
|
||||
|
||||
} else {
|
||||
vector<bool> replacedKeysMask(variableIndex_.size(), false);
|
||||
if(replacedKeys) {
|
||||
|
|
|
|||
|
|
@ -92,6 +92,59 @@ TEST(ISAM2, AddVariables) {
|
|||
EXPECT(assert_equal(orderingExpected, ordering));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
//TEST(ISAM2, IndicesFromFactors) {
|
||||
//
|
||||
// using namespace gtsam::planarSLAM;
|
||||
// typedef GaussianISAM2<planarSLAM::Values>::Impl Impl;
|
||||
//
|
||||
// Ordering ordering; ordering += PointKey(0), PoseKey(0), PoseKey(1);
|
||||
// planarSLAM::Graph graph;
|
||||
// graph.addPrior(PoseKey(0), Pose2(), sharedUnit(Pose2::dimension));
|
||||
// graph.addRange(PoseKey(0), PointKey(0), 1.0, sharedUnit(1));
|
||||
//
|
||||
// FastSet<Index> expected;
|
||||
// expected.insert(0);
|
||||
// expected.insert(1);
|
||||
//
|
||||
// FastSet<Index> actual = Impl::IndicesFromFactors(ordering, graph);
|
||||
//
|
||||
// EXPECT(assert_equal(expected, actual));
|
||||
//}
|
||||
|
||||
/* ************************************************************************* */
|
||||
//TEST(ISAM2, CheckRelinearization) {
|
||||
//
|
||||
// typedef GaussianISAM2<planarSLAM::Values>::Impl Impl;
|
||||
//
|
||||
// // Create values where indices 1 and 3 are above the threshold of 0.1
|
||||
// VectorValues values;
|
||||
// values.reserve(4, 10);
|
||||
// values.push_back_preallocated(Vector_(2, 0.09, 0.09));
|
||||
// values.push_back_preallocated(Vector_(3, 0.11, 0.11, 0.09));
|
||||
// values.push_back_preallocated(Vector_(3, 0.09, 0.09, 0.09));
|
||||
// values.push_back_preallocated(Vector_(2, 0.11, 0.11));
|
||||
//
|
||||
// // Create a permutation
|
||||
// Permutation permutation(4);
|
||||
// permutation[0] = 2;
|
||||
// permutation[1] = 0;
|
||||
// permutation[2] = 1;
|
||||
// permutation[3] = 3;
|
||||
//
|
||||
// Permuted<VectorValues> permuted(permutation, values);
|
||||
//
|
||||
// // After permutation, the indices above the threshold are 2 and 2
|
||||
// FastSet<Index> expected;
|
||||
// expected.insert(2);
|
||||
// expected.insert(3);
|
||||
//
|
||||
// // Indices checked by CheckRelinearization
|
||||
// FastSet<Index> actual = Impl::CheckRelinearization(permuted, 0.1);
|
||||
//
|
||||
// EXPECT(assert_equal(expected, actual));
|
||||
//}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST(ISAM2, optimize2) {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue