2009-12-29 13:57:05 +08:00
/**
* @ file ISAM2 - inl . h
2009-12-30 12:27:14 +08:00
* @ brief Incremental update functionality ( ISAM2 ) for BayesTree , with fluid relinearization .
2009-12-29 13:57:05 +08:00
* @ author Michael Kaess
*/
# include <boost/foreach.hpp>
# include <boost/assign/std/list.hpp> // for operator +=
using namespace boost : : assign ;
2010-01-03 12:57:35 +08:00
# include <set>
2010-01-16 09:16:59 +08:00
# include "NonlinearFactorGraph-inl.h"
2009-12-29 13:57:05 +08:00
# include "GaussianFactor.h"
# include "VectorConfig.h"
# include "Conditional.h"
# include "BayesTree-inl.h"
# include "ISAM2.h"
namespace gtsam {
using namespace std ;
2010-01-17 14:06:20 +08:00
// from inference-inl.h - need to additionally return the newly created factor for caching
2010-01-18 16:05:33 +08:00
boost : : shared_ptr < GaussianConditional > _eliminateOne ( FactorGraph < GaussianFactor > & graph , CachedFactors & cached , const Symbol & key ) {
2010-01-17 14:06:20 +08:00
// combine the factors of all nodes connected to the variable to be eliminated
// if no factors are connected to key, returns an empty factor
boost : : shared_ptr < GaussianFactor > joint_factor = removeAndCombineFactors ( graph , key ) ;
// eliminate that joint factor
boost : : shared_ptr < GaussianFactor > factor ;
boost : : shared_ptr < GaussianConditional > conditional ;
boost : : tie ( conditional , factor ) = joint_factor - > eliminate ( key ) ;
2010-01-20 09:24:32 +08:00
// ADDED: remember the intermediate result to be able to later restart computation in the middle
2010-01-17 14:06:20 +08:00
cached [ key ] = factor ;
// add new factor on separator back into the graph
if ( ! factor - > empty ( ) ) graph . push_back ( factor ) ;
// return the conditional Gaussian
return conditional ;
}
// from GaussianFactorGraph.cpp, see _eliminateOne above
2010-01-18 16:05:33 +08:00
GaussianBayesNet _eliminate ( FactorGraph < GaussianFactor > & graph , CachedFactors & cached , const Ordering & ordering ) {
2010-01-17 14:06:20 +08:00
GaussianBayesNet chordalBayesNet ; // empty
2010-01-18 12:53:17 +08:00
BOOST_FOREACH ( const Symbol & key , ordering ) {
2010-01-17 14:06:20 +08:00
GaussianConditional : : shared_ptr cg = _eliminateOne ( graph , cached , key ) ;
chordalBayesNet . push_back ( cg ) ;
}
return chordalBayesNet ;
}
2010-01-18 16:05:33 +08:00
GaussianBayesNet _eliminate_const ( const FactorGraph < GaussianFactor > & graph , CachedFactors & cached , const Ordering & ordering ) {
2010-01-17 14:06:20 +08:00
// make a copy that can be modified locally
FactorGraph < GaussianFactor > graph_ignored = graph ;
return _eliminate ( graph_ignored , cached , ordering ) ;
}
2009-12-29 13:57:05 +08:00
/** Create an empty Bayes Tree */
template < class Conditional , class Config >
ISAM2 < Conditional , Config > : : ISAM2 ( ) : BayesTree < Conditional > ( ) { }
2009-12-30 12:27:14 +08:00
/** Create a Bayes Tree from a nonlinear factor graph */
2009-12-29 13:57:05 +08:00
template < class Conditional , class Config >
2009-12-31 13:35:08 +08:00
ISAM2 < Conditional , Config > : : ISAM2 ( const NonlinearFactorGraph < Config > & nlfg , const Ordering & ordering , const Config & config )
2010-02-22 05:17:47 +08:00
: BayesTree < Conditional > ( nlfg . linearize ( config ) - > eliminate ( ordering ) ) , theta_ ( config ) , thetaFuture_ ( config ) , nonlinearFactors_ ( nlfg ) {
2010-01-17 14:06:20 +08:00
// todo: repeats calculation above, just to set "cached"
2010-02-22 05:17:47 +08:00
// De-referencing shared pointer can be quite expensive because creates temporary
_eliminate_const ( * nlfg . linearize ( config ) , cached_ , ordering ) ;
2010-01-17 14:06:20 +08:00
}
2009-12-29 13:57:05 +08:00
2010-01-20 14:49:19 +08:00
/* ************************************************************************* */
template < class Conditional , class Config >
2010-07-11 06:59:50 +08:00
list < size_t > ISAM2 < Conditional , Config > : : getAffectedFactors ( const list < Symbol > & keys ) const {
2010-01-22 14:28:12 +08:00
FactorGraph < NonlinearFactor < Config > > allAffected ;
2010-07-11 06:59:50 +08:00
list < size_t > indices ;
2010-01-20 14:49:19 +08:00
BOOST_FOREACH ( const Symbol & key , keys ) {
2010-07-11 06:59:50 +08:00
const list < size_t > l = nonlinearFactors_ . factors ( key ) ;
2010-01-20 14:49:19 +08:00
indices . insert ( indices . begin ( ) , l . begin ( ) , l . end ( ) ) ;
}
indices . sort ( ) ;
indices . unique ( ) ;
2010-01-23 02:29:27 +08:00
return indices ;
2010-01-20 14:49:19 +08:00
}
2009-12-29 13:57:05 +08:00
/* ************************************************************************* */
2010-01-18 12:32:45 +08:00
// retrieve all factors that ONLY contain the affected variables
// (note that the remaining stuff is summarized in the cached factors)
2009-12-29 13:57:05 +08:00
template < class Conditional , class Config >
2010-02-22 05:17:47 +08:00
boost : : shared_ptr < GaussianFactorGraph > ISAM2 < Conditional , Config > : : relinearizeAffectedFactors
( const set < Symbol > & affectedKeys ) const {
2010-01-20 14:49:19 +08:00
2010-01-22 14:28:12 +08:00
list < Symbol > affectedKeysList ; // todo: shouldn't have to convert back to list...
affectedKeysList . insert ( affectedKeysList . begin ( ) , affectedKeys . begin ( ) , affectedKeys . end ( ) ) ;
2010-07-11 06:59:50 +08:00
list < size_t > candidates = getAffectedFactors ( affectedKeysList ) ;
2010-01-18 12:53:17 +08:00
2010-01-17 14:06:20 +08:00
NonlinearFactorGraph < Config > nonlinearAffectedFactors ;
2010-01-18 12:53:17 +08:00
2010-07-11 06:59:50 +08:00
BOOST_FOREACH ( size_t idx , candidates ) {
2010-01-17 14:06:20 +08:00
bool inside = true ;
2010-01-23 02:29:27 +08:00
BOOST_FOREACH ( const Symbol & key , nonlinearFactors_ [ idx ] - > keys ( ) ) {
2010-01-22 14:28:12 +08:00
if ( affectedKeys . find ( key ) = = affectedKeys . end ( ) ) {
2010-01-17 14:06:20 +08:00
inside = false ;
2010-01-20 14:49:19 +08:00
break ;
}
2010-01-17 14:06:20 +08:00
}
if ( inside )
2010-01-23 02:29:27 +08:00
nonlinearAffectedFactors . push_back ( nonlinearFactors_ [ idx ] ) ;
2010-01-17 14:06:20 +08:00
}
2010-01-18 12:53:17 +08:00
2010-02-22 05:17:47 +08:00
// TODO: temporary might be expensive, return shared pointer ?
2010-01-22 04:15:52 +08:00
return nonlinearAffectedFactors . linearize ( theta_ ) ;
2010-01-18 12:32:45 +08:00
}
2010-01-17 14:06:20 +08:00
2010-01-18 12:32:45 +08:00
/* ************************************************************************* */
2010-01-18 12:53:17 +08:00
// find intermediate (linearized) factors from cache that are passed into the affected area
2010-01-18 12:32:45 +08:00
template < class Conditional , class Config >
FactorGraph < GaussianFactor > ISAM2 < Conditional , Config > : : getCachedBoundaryFactors ( Cliques & orphans ) {
2010-01-17 14:06:20 +08:00
FactorGraph < GaussianFactor > cachedBoundary ;
2010-01-18 12:53:17 +08:00
2010-01-17 14:06:20 +08:00
BOOST_FOREACH ( sharedClique orphan , orphans ) {
2010-01-20 14:49:19 +08:00
// find the last variable that was eliminated
const Symbol & key = orphan - > ordering ( ) . back ( ) ;
2010-01-17 14:06:20 +08:00
// retrieve the cached factor and add to boundary
2010-01-18 16:05:33 +08:00
cachedBoundary . push_back ( cached_ [ key ] ) ;
2010-01-17 14:06:20 +08:00
}
2010-01-18 12:53:17 +08:00
2010-01-21 15:38:37 +08:00
return cachedBoundary ;
2010-01-18 12:32:45 +08:00
}
2010-01-17 14:06:20 +08:00
2010-01-18 12:32:45 +08:00
/* ************************************************************************* */
2010-07-10 07:18:10 +08:00
// todo: will be obsolete soon
2010-01-18 12:32:45 +08:00
template < class Conditional , class Config >
void ISAM2 < Conditional , Config > : : update_internal ( const NonlinearFactorGraph < Config > & newFactors ,
2010-01-23 08:21:34 +08:00
const Config & newTheta , Cliques & orphans , double wildfire_threshold , double relinearize_threshold , bool relinearize ) {
2010-01-22 00:09:57 +08:00
2010-01-22 14:28:12 +08:00
// marked_ = nonlinearFactors_.keys(); // debug only ////////////
2010-01-22 00:09:57 +08:00
2010-01-23 08:21:34 +08:00
// only relinearize if requested in previous step AND necessary (ie. at least one variable changes)
relinearize = true ; // todo - switched off
bool relinFromLast = true ; //marked_.size() > 0;
2010-01-22 14:28:12 +08:00
//// 1 - relinearize selected variables
2010-01-23 08:21:34 +08:00
if ( relinFromLast ) {
theta_ = expmap ( theta_ , deltaMarked_ ) ;
}
2010-01-22 14:28:12 +08:00
//// 2 - Add new factors (for later relinearization)
2010-01-22 00:09:57 +08:00
2010-01-21 15:38:37 +08:00
nonlinearFactors_ . push_back ( newFactors ) ;
2010-01-17 14:06:20 +08:00
2010-01-22 14:28:12 +08:00
//// 3 - Initialize new variables
theta_ . insert ( newTheta ) ;
thetaFuture_ . insert ( newTheta ) ;
//// 4 - Mark affected variables as invalid
2010-01-22 01:41:54 +08:00
2010-01-22 04:15:52 +08:00
// todo - not in lyx yet: relin requires more than just removing the cliques corresponding to the variables!!!
// It's about factors!!!
2010-01-22 01:41:54 +08:00
2010-01-23 08:21:34 +08:00
if ( relinFromLast ) {
// mark variables that have to be removed as invalid (removeFATtop)
// basically calculate all the keys contained in the factors that contain any of the keys...
// the goal is to relinearize all variables directly affected by new factors
2010-07-11 06:59:50 +08:00
list < size_t > allAffected = getAffectedFactors ( marked_ ) ;
2010-01-23 08:21:34 +08:00
set < Symbol > accumulate ;
BOOST_FOREACH ( int idx , allAffected ) {
list < Symbol > tmp = nonlinearFactors_ [ idx ] - > keys ( ) ;
accumulate . insert ( tmp . begin ( ) , tmp . end ( ) ) ;
}
marked_ . clear ( ) ;
marked_ . insert ( marked_ . begin ( ) , accumulate . begin ( ) , accumulate . end ( ) ) ;
} // else: marked_ is empty anyways
2010-01-22 01:41:54 +08:00
2010-01-23 08:21:34 +08:00
// also mark variables that are affected by new factors as invalid
2010-01-21 15:38:37 +08:00
const list < Symbol > newKeys = newFactors . keys ( ) ;
marked_ . insert ( marked_ . begin ( ) , newKeys . begin ( ) , newKeys . end ( ) ) ;
// eliminate duplicates
marked_ . sort ( ) ;
marked_ . unique ( ) ;
2010-01-19 09:18:28 +08:00
2010-01-22 14:28:12 +08:00
//// 5 - removeTop invalidate all cliques involving marked variables
2010-01-17 14:06:20 +08:00
2010-01-19 09:18:28 +08:00
// remove affected factors
2010-01-21 08:38:22 +08:00
BayesNet < GaussianConditional > affectedBayesNet ;
2010-01-21 15:38:37 +08:00
this - > removeTop ( marked_ , affectedBayesNet , orphans ) ;
2010-01-18 12:32:45 +08:00
2010-01-22 14:28:12 +08:00
//// 6 - find factors connected to affected variables
//// 7 - linearize
2010-01-21 15:38:37 +08:00
2010-02-22 05:17:47 +08:00
boost : : shared_ptr < GaussianFactorGraph > factors ;
2010-01-21 15:38:37 +08:00
2010-01-23 08:21:34 +08:00
if ( relinFromLast ) {
// ordering provides all keys in conditionals, there cannot be others because path to root included
set < Symbol > affectedKeys ;
list < Symbol > tmp = affectedBayesNet . ordering ( ) ;
affectedKeys . insert ( tmp . begin ( ) , tmp . end ( ) ) ;
2010-01-19 08:15:46 +08:00
2010-01-23 08:21:34 +08:00
// todo - remerge in keys of new factors
affectedKeys . insert ( newKeys . begin ( ) , newKeys . end ( ) ) ;
2010-01-20 09:24:32 +08:00
2010-01-23 09:53:04 +08:00
// Save number of affected variables
lastAffectedVariableCount = affectedKeys . size ( ) ;
2010-01-23 08:21:34 +08:00
factors = relinearizeAffectedFactors ( affectedKeys ) ;
2010-01-23 09:53:04 +08:00
// Save number of affected factors
2010-02-22 05:17:47 +08:00
lastAffectedFactorCount = factors - > size ( ) ;
2010-01-23 09:53:04 +08:00
2010-01-23 08:21:34 +08:00
// add the cached intermediate results from the boundary of the orphans ...
FactorGraph < GaussianFactor > cachedBoundary = getCachedBoundaryFactors ( orphans ) ;
2010-02-22 05:17:47 +08:00
factors - > push_back ( cachedBoundary ) ;
2010-01-23 08:21:34 +08:00
} else {
// reuse the old factors
FactorGraph < GaussianFactor > tmp ( affectedBayesNet ) ;
2010-02-22 05:17:47 +08:00
factors . reset ( new GaussianFactorGraph ) ;
factors - > push_back ( tmp ) ;
factors - > push_back ( * newFactors . linearize ( theta_ ) ) ; // avoid temporary ?
2010-01-23 08:21:34 +08:00
}
2010-01-18 12:32:45 +08:00
2010-01-22 14:28:12 +08:00
//// 8 - eliminate and add orphans back in
2010-01-03 12:57:35 +08:00
2009-12-29 13:57:05 +08:00
// create an ordering for the new and contaminated factors
2010-07-09 13:23:17 +08:00
// newKeys are passed in: those variables will be forced to the end in the ordering
set < Symbol > newKeysSet ;
newKeysSet . insert ( newKeys . begin ( ) , newKeys . end ( ) ) ;
Ordering ordering = factors - > getConstrainedOrdering ( newKeysSet ) ;
2009-12-29 13:57:05 +08:00
// eliminate into a Bayes net
2010-02-22 05:17:47 +08:00
BayesNet < Conditional > bayesNet = _eliminate ( * factors , cached_ , ordering ) ;
2010-01-03 12:57:35 +08:00
2010-01-22 10:27:26 +08:00
// Create Index from ordering
IndexTable < Symbol > index ( ordering ) ;
2009-12-29 13:57:05 +08:00
// insert conditionals back in, straight into the topless bayesTree
typename BayesNet < Conditional > : : const_reverse_iterator rit ;
2010-01-22 10:27:26 +08:00
for ( rit = bayesNet . rbegin ( ) ; rit ! = bayesNet . rend ( ) ; + + rit )
this - > insert ( * rit , index ) ;
2010-01-20 09:24:32 +08:00
2010-01-23 09:53:04 +08:00
// Save number of affectedCliques
lastAffectedCliqueCount = this - > size ( ) ;
2009-12-29 13:57:05 +08:00
// add orphans to the bottom of the new tree
BOOST_FOREACH ( sharedClique orphan , orphans ) {
2010-01-22 10:27:26 +08:00
Symbol parentRepresentative = findParentClique ( orphan - > separator_ , index ) ;
sharedClique parent = ( * this ) [ parentRepresentative ] ;
2009-12-29 13:57:05 +08:00
parent - > children_ + = orphan ;
orphan - > parent_ = parent ; // set new parent!
}
2010-01-18 12:32:45 +08:00
2010-01-22 14:28:12 +08:00
//// 9 - update solution
2010-01-21 15:38:37 +08:00
2010-01-22 14:28:12 +08:00
delta_ = optimize2 ( * this , wildfire_threshold ) ;
2010-01-21 15:38:37 +08:00
2010-01-22 14:28:12 +08:00
//// 10 - mark variables, if significant change
2010-01-21 15:38:37 +08:00
marked_ . clear ( ) ;
2010-01-22 14:28:12 +08:00
deltaMarked_ = VectorConfig ( ) ; // clear
2010-01-23 08:21:34 +08:00
if ( relinearize ) { // decides about next step!!!
for ( VectorConfig : : const_iterator it = delta_ . begin ( ) ; it ! = delta_ . end ( ) ; it + + ) {
Symbol key = it - > first ;
Vector v = it - > second ;
if ( max ( abs ( v ) ) > = relinearize_threshold ) {
marked_ . push_back ( key ) ;
deltaMarked_ . insert ( key , v ) ;
}
2010-01-21 15:38:37 +08:00
}
2010-01-23 08:21:34 +08:00
// not part of the formal algorithm, but needed to allow initialization of new variables outside by the user
thetaFuture_ = expmap ( thetaFuture_ , deltaMarked_ ) ;
}
2010-01-21 15:38:37 +08:00
2009-12-29 13:57:05 +08:00
}
2010-07-10 07:18:10 +08:00
template < class Conditional , class Config >
void ISAM2 < Conditional , Config > : : linear_update ( const FactorGraph < GaussianFactor > & newFactors ) {
// Input: BayesTree(this), newFactors
// 1. Remove top of Bayes tree and convert to a factor graph:
// (a) For each affected variable, remove the corresponding clique and all parents up to the root.
// (b) Store orphaned sub-trees \BayesTree_{O} of removed cliques.
const list < Symbol > newKeys = newFactors . keys ( ) ;
2010-07-16 17:06:09 +08:00
Cliques orphans ;
2010-07-10 07:18:10 +08:00
BayesNet < GaussianConditional > affectedBayesNet ;
this - > removeTop ( newKeys , affectedBayesNet , orphans ) ;
FactorGraph < GaussianFactor > factors ( affectedBayesNet ) ;
// 2. Add the new factors \Factors' into the resulting factor graph
factors . push_back ( newFactors ) ;
// 3. Re-order and eliminate the factor graph into a Bayes net (Algorithm [alg:eliminate]), and re-assemble into a new Bayes tree (Algorithm [alg:BayesTree])
// create an ordering for the new and contaminated factors
// newKeys are passed in: those variables will be forced to the end in the ordering
set < Symbol > newKeysSet ;
newKeysSet . insert ( newKeys . begin ( ) , newKeys . end ( ) ) ;
Ordering ordering = factors . getConstrainedOrdering ( newKeysSet ) ;
// eliminate into a Bayes net
BayesNet < Conditional > bayesNet = _eliminate ( factors , cached_ , ordering ) ;
// Create Index from ordering
IndexTable < Symbol > index ( ordering ) ;
// insert conditionals back in, straight into the topless bayesTree
typename BayesNet < Conditional > : : const_reverse_iterator rit ;
for ( rit = bayesNet . rbegin ( ) ; rit ! = bayesNet . rend ( ) ; + + rit )
this - > insert ( * rit , index ) ;
// Save number of affectedCliques
lastAffectedCliqueCount = this - > size ( ) ;
// 4. Insert the orphans back into the new Bayes tree.
// add orphans to the bottom of the new tree
BOOST_FOREACH ( sharedClique orphan , orphans ) {
Symbol parentRepresentative = findParentClique ( orphan - > separator_ , index ) ;
sharedClique parent = ( * this ) [ parentRepresentative ] ;
parent - > children_ + = orphan ;
orphan - > parent_ = parent ; // set new parent!
}
// Output: BayesTree(this)
}
2010-07-16 17:06:09 +08:00
template < class Conditional , class Config >
void ISAM2 < Conditional , Config > : : find_all ( sharedClique clique , list < Symbol > & keys , const list < Symbol > & marked ) {
// does the separator contain any of the variables?
bool found = false ;
BOOST_FOREACH ( const Symbol & key , clique - > separator_ ) {
if ( find ( marked . begin ( ) , marked . end ( ) , key ) ! = marked . end ( ) )
found = true ;
}
if ( found ) {
// then add this clique
keys . push_back ( clique - > keys ( ) . front ( ) ) ;
}
BOOST_FOREACH ( const sharedClique & child , clique - > children_ ) {
find_all ( child , keys , marked ) ;
}
}
2010-07-10 07:18:10 +08:00
template < class Conditional , class Config >
void ISAM2 < Conditional , Config > : : fluid_relinearization ( double relinearize_threshold ) {
// Input: nonlinear factors factors_, linearization point theta_, Bayes tree (this), delta_
// 1. Mark variables in \Delta above threshold \beta: J=\{\Delta_{j}\in\Delta|\Delta_{j}\geq\beta\}.
2010-07-16 17:06:09 +08:00
list < Symbol > marked ;
2010-07-10 07:18:10 +08:00
VectorConfig deltaMarked ;
for ( VectorConfig : : const_iterator it = delta_ . begin ( ) ; it ! = delta_ . end ( ) ; it + + ) {
Symbol key = it - > first ;
Vector v = it - > second ;
if ( max ( abs ( v ) ) > = relinearize_threshold ) {
marked . push_back ( key ) ;
deltaMarked . insert ( key , v ) ;
}
}
// 2. Update linearization point for marked variables: \Theta_{J}:=\Theta_{J}+\Delta_{J}.
theta_ = expmap ( theta_ , deltaMarked ) ;
// 3. Mark all cliques that involve marked variables \Theta_{J} and all their ancestors.
2010-07-16 17:06:09 +08:00
// mark all cliques that involve marked variables
list < Symbol > affectedSymbols ( marked ) ; // add all marked
find_all ( this - > root ( ) , affectedSymbols , marked ) ; // add other cliques that have the marked ones in the separator
2010-07-10 07:18:10 +08:00
// 4. From the leaves to the top, if a clique is marked:
// re-linearize the original factors in \Factors associated with the clique,
// add the cached marginal factors from its children, and re-eliminate.
2010-07-16 17:06:09 +08:00
// todo: for simplicity, currently simply remove the top and recreate it using the original ordering
Cliques orphans ;
BayesNet < GaussianConditional > affectedBayesNet ;
this - > removeTop ( affectedSymbols , affectedBayesNet , orphans ) ;
// remember original ordering
// Ordering original_ordering = affectedBayesNet.ordering();
boost : : shared_ptr < GaussianFactorGraph > factors ;
// ordering provides all keys in conditionals, there cannot be others because path to root included
set < Symbol > affectedKeys ;
list < Symbol > tmp = affectedBayesNet . ordering ( ) ;
affectedKeys . insert ( tmp . begin ( ) , tmp . end ( ) ) ;
factors = relinearizeAffectedFactors ( affectedKeys ) ;
Ordering original_ordering = factors - > getOrdering ( ) ; // todo - hack
// add the cached intermediate results from the boundary of the orphans ...
FactorGraph < GaussianFactor > cachedBoundary = getCachedBoundaryFactors ( orphans ) ;
factors - > push_back ( cachedBoundary ) ;
// eliminate into a Bayes net
BayesNet < Conditional > bayesNet = _eliminate ( * factors , cached_ , original_ordering ) ;
// Create Index from ordering
IndexTable < Symbol > index ( original_ordering ) ;
// insert conditionals back in, straight into the topless bayesTree
typename BayesNet < Conditional > : : const_reverse_iterator rit ;
for ( rit = bayesNet . rbegin ( ) ; rit ! = bayesNet . rend ( ) ; + + rit )
this - > insert ( * rit , index ) ;
// add orphans to the bottom of the new tree
BOOST_FOREACH ( sharedClique orphan , orphans ) {
Symbol parentRepresentative = findParentClique ( orphan - > separator_ , index ) ;
sharedClique parent = ( * this ) [ parentRepresentative ] ;
parent - > children_ + = orphan ;
orphan - > parent_ = parent ; // set new parent!
}
2010-07-10 07:18:10 +08:00
// Output: updated Bayes tree (this), updated linearization point theta_
}
2009-12-29 13:57:05 +08:00
template < class Conditional , class Config >
2010-01-21 15:38:37 +08:00
void ISAM2 < Conditional , Config > : : update (
2010-01-22 14:28:12 +08:00
const NonlinearFactorGraph < Config > & newFactors , const Config & newTheta ,
2010-01-23 08:21:34 +08:00
double wildfire_threshold , double relinearize_threshold , bool relinearize ) {
2010-01-17 14:06:20 +08:00
2010-07-10 07:18:10 +08:00
# if 1
// old algorithm:
2009-12-29 13:57:05 +08:00
Cliques orphans ;
2010-01-23 08:21:34 +08:00
this - > update_internal ( newFactors , newTheta , orphans , wildfire_threshold , relinearize_threshold , relinearize ) ;
2010-07-16 17:06:09 +08:00
delta_ . print ( ) ;
this - > print ( ) ;
2010-07-10 07:18:10 +08:00
# else
2010-07-16 17:06:09 +08:00
printf ( " **1 \n " ) ; fflush ( stdout ) ;
2010-07-10 07:18:10 +08:00
// 1. Add any new factors \Factors:=\Factors\cup\Factors'.
nonlinearFactors_ . push_back ( newFactors ) ;
2010-07-16 17:06:09 +08:00
printf ( " **2 \n " ) ; fflush ( stdout ) ;
2010-07-10 07:18:10 +08:00
// 2. Initialize any new variables \Theta_{new} and add \Theta:=\Theta\cup\Theta_{new}.
theta_ . insert ( newTheta ) ;
2010-07-16 17:06:09 +08:00
printf ( " **3 \n " ) ; fflush ( stdout ) ;
2010-07-10 07:18:10 +08:00
// 3. Linearize new factor
2010-07-16 17:06:09 +08:00
boost : : shared_ptr < GaussianFactorGraph > linearFactors = newFactors . linearize ( theta_ ) ;
printf ( " **4 \n " ) ; fflush ( stdout ) ;
2010-01-21 15:38:37 +08:00
2010-07-10 07:18:10 +08:00
// 4. Linear iSAM step (alg 3)
2010-07-16 17:06:09 +08:00
linear_update ( * linearFactors ) ; // in: this
2010-07-10 07:18:10 +08:00
2010-07-16 17:06:09 +08:00
printf ( " **5 \n " ) ; fflush ( stdout ) ;
2010-07-10 07:18:10 +08:00
// 5. Calculate Delta (alg 0)
delta_ = optimize2 ( * this , wildfire_threshold ) ;
2010-07-16 17:06:09 +08:00
printf ( " **6 \n " ) ; fflush ( stdout ) ;
2010-07-10 07:18:10 +08:00
// 6. Iterate Algorithm 4 until no more re-linearizations occur
2010-07-16 17:06:09 +08:00
// if (relinearize)
// fluid_relinearization(relinearize_threshold); // in: delta_, theta_, nonlinearFactors_, this
printf ( " **7 \n " ) ; fflush ( stdout ) ;
2010-07-10 07:18:10 +08:00
// todo: linearization point and delta_ do not fit... have to update delta again
delta_ = optimize2 ( * this , wildfire_threshold ) ;
2010-07-16 17:06:09 +08:00
printf ( " **8 \n " ) ; fflush ( stdout ) ;
delta_ . print ( ) ;
this - > print ( ) ;
printf ( " **9 \n " ) ; fflush ( stdout ) ;
2010-07-10 07:18:10 +08:00
# endif
2009-12-29 13:57:05 +08:00
}
/* ************************************************************************* */
}
/// namespace gtsam