diff --git a/cpp/FactorGraph-inl.h b/cpp/FactorGraph-inl.h index 5c217d6c1..0e7afdcd6 100644 --- a/cpp/FactorGraph-inl.h +++ b/cpp/FactorGraph-inl.h @@ -17,6 +17,7 @@ #include #include +#include #include #include "Ordering.h" #include "FactorGraph.h" @@ -86,19 +87,7 @@ void FactorGraph::push_back(sharedFactor factor) { if (factor==NULL) return; int i = factors_.size() - 1; // index of factor - list keys = factor->keys(); // get keys for factor - - BOOST_FOREACH(string key, keys){ // for each key push i onto list - Indices::iterator it = indices_.find(key); // old list for that key (if exists) - if (it==indices_.end()){ // there's no list yet - list indices(1,i); // so make one - indices_.insert(make_pair(key,indices)); // insert new indices into factorMap - } - else { - list *indices_ptr = &(it->second); // get the list - indices_ptr->push_back(i); // add the index i to it - } - } + associateFactor(i, factor); } /* ************************************************************************* */ @@ -109,6 +98,36 @@ void FactorGraph::push_back(const FactorGraph& factors) { push_back(*factor); } +/* ************************************************************************* */ +template +void FactorGraph::replace(int index, sharedFactor factor) { + if(index >= factors_.size()) + throw invalid_argument(boost::str(boost::format( + "Factor graph does not contain a factor with index %d.") % index)); + //if(factors_[index] == NULL) + // throw invalid_argument(boost::str(boost::format( + // "Factor with index %d is NULL." % index))); + + if(factors_[index] != NULL) { + // Remove this factor from its variables' index lists + list keys(factor->keys()); + BOOST_FOREACH(string key, keys) { + Indices::iterator indices = indices_.find(key); + if(indices != indices_.end()) { + indices->second.remove(index); + } else { + throw invalid_argument(boost::str(boost::format( + "Factor graph inconsistency! Factor %d involves variable %s but " + "is missing from its factor index list.") % index % key)); + } + } + } + + // Replace the factor + factors_[index] = factor; + associateFactor(index, factor); +} + /* ************************************************************************* */ template Ordering FactorGraph::keys() const { @@ -231,6 +250,24 @@ FactorGraph::findAndRemoveFactors(const string& key) { return found; } +/* ************************************************************************* */ +template +void FactorGraph::associateFactor(int index, sharedFactor factor) { + list keys = factor->keys(); // get keys for factor + + BOOST_FOREACH(string key, keys){ // for each key push i onto list + Indices::iterator it = indices_.find(key); // old list for that key (if exists) + if (it==indices_.end()){ // there's no list yet + list indices(1,index); // so make one + indices_.insert(make_pair(key,indices)); // insert new indices into factorMap + } + else { + list *indices_ptr = &(it->second); // get the list + indices_ptr->push_back(index); // add the index i to it + } + } +} + /* ************************************************************************* */ /* find factors and remove them from the factor graph: O(n) */ /* ************************************************************************* */ @@ -253,6 +290,4 @@ FactorGraph combine(const FactorGraph& fg1, const FactorGraph& factors); + /** replace a factor by index */ + void replace(int index, sharedFactor factor); + /** return keys in some random order */ Ordering keys() const; @@ -111,6 +114,8 @@ namespace gtsam { std::vector findAndRemoveFactors(const std::string& key); private: + /** Associate factor index with the variables connected to the factor */ + void associateFactor(int index, sharedFactor factor); /** Serialization function */ friend class boost::serialization::access;