Significant change: Made FactorGraph templated on Factor only, and moved error and probPrime to derived classes
Moved find_and_remove_factors to base class Added and tested symbolic factor graph constructor and conversion from any factor graph typerelease/4.3a0
							parent
							
								
									1f792a53ea
								
							
						
					
					
						commit
						b6cee73571
					
				| 
						 | 
				
			
			@ -332,7 +332,7 @@
 | 
			
		|||
<buildArguments>-f local.mk</buildArguments>
 | 
			
		||||
<buildTarget>testCal3_S2.run</buildTarget>
 | 
			
		||||
<stopOnError>true</stopOnError>
 | 
			
		||||
<useDefaultCommand>false</useDefaultCommand>
 | 
			
		||||
<useDefaultCommand>true</useDefaultCommand>
 | 
			
		||||
<runAllBuilders>true</runAllBuilders>
 | 
			
		||||
</target>
 | 
			
		||||
<target name="testVSLAMFactor.run" path="cpp" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ ConstrainedConditionalGaussian::shared_ptr ConstrainedLinearFactorGraph::elimina
 | 
			
		|||
	ConstrainedConditionalGaussian::shared_ptr ccg = constraint->eliminate(key);
 | 
			
		||||
 | 
			
		||||
	// perform a change of variables on the linear factors in the separator
 | 
			
		||||
	LinearFactorSet separator = find_factors_and_remove(key);
 | 
			
		||||
	vector<LinearFactor::shared_ptr> separator = find_factors_and_remove(key);
 | 
			
		||||
	BOOST_FOREACH(LinearFactor::shared_ptr factor, separator) {
 | 
			
		||||
		// store the block matrices
 | 
			
		||||
		map<string, Matrix> blocks;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@ namespace gtsam {
 | 
			
		|||
 * To fix it, we need to think more deeply about this.
 | 
			
		||||
 */
 | 
			
		||||
template<class Factor, class Config>
 | 
			
		||||
class ConstrainedNonlinearFactorGraph: public FactorGraph<Factor, Config> {
 | 
			
		||||
class ConstrainedNonlinearFactorGraph: public FactorGraph<Factor> {
 | 
			
		||||
protected:
 | 
			
		||||
	/** collection of equality factors */
 | 
			
		||||
	std::vector<LinearConstraint::shared_ptr> eq_factors;
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +44,7 @@ public:
 | 
			
		|||
	 * Copy constructor from regular NLFGs
 | 
			
		||||
	 */
 | 
			
		||||
	ConstrainedNonlinearFactorGraph(const NonlinearFactorGraph<Config>& nfg) :
 | 
			
		||||
		FactorGraph<Factor, Config> (nfg) {
 | 
			
		||||
		FactorGraph<Factor> (nfg) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	typedef typename boost::shared_ptr<Factor> shared_factor;
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +78,7 @@ public:
 | 
			
		|||
	 * Insert a factor into the graph
 | 
			
		||||
	 */
 | 
			
		||||
	void push_back(const shared_factor& f) {
 | 
			
		||||
		FactorGraph<Factor,Config>::push_back(f);
 | 
			
		||||
		FactorGraph<Factor>::push_back(f);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,12 +59,6 @@ namespace gtsam {
 | 
			
		|||
     */
 | 
			
		||||
    virtual double error(const Config& c) const = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * equality up to tolerance
 | 
			
		||||
     * tricky to implement, see NonLinearFactor1 for an example
 | 
			
		||||
    virtual bool equals(const Factor& f, double tol=1e-9) const = 0;
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    virtual std::string dump() const = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,8 +23,8 @@ using namespace std;
 | 
			
		|||
namespace gtsam {
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
template<class Factor, class Config>
 | 
			
		||||
void FactorGraph<Factor, Config>::print(const string& s) const {
 | 
			
		||||
template<class Factor>
 | 
			
		||||
void FactorGraph<Factor>::print(const string& s) const {
 | 
			
		||||
	cout << s << endl;
 | 
			
		||||
	printf("size: %d\n", (int) size());
 | 
			
		||||
	for (int i = 0; i < factors_.size(); i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -35,9 +35,9 @@ void FactorGraph<Factor, Config>::print(const string& s) const {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
template<class Factor, class Config>
 | 
			
		||||
bool FactorGraph<Factor, Config>::equals
 | 
			
		||||
	(const FactorGraph<Factor, Config>& fg, double tol) const {
 | 
			
		||||
template<class Factor>
 | 
			
		||||
bool FactorGraph<Factor>::equals
 | 
			
		||||
	(const FactorGraph<Factor>& fg, double tol) const {
 | 
			
		||||
	/** check whether the two factor graphs have the same number of factors_ */
 | 
			
		||||
	if (factors_.size() != fg.size()) return false;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,26 +53,36 @@ bool FactorGraph<Factor, Config>::equals
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
template<class Factor, class Config>
 | 
			
		||||
void FactorGraph<Factor,Config>::push_back(shared_factor factor) {
 | 
			
		||||
	factors_.push_back(factor);  // add the actual factor
 | 
			
		||||
	int i = factors_.size() - 1; // index of factor
 | 
			
		||||
	list<string> keys = factor->keys(); // get keys for factor
 | 
			
		||||
	BOOST_FOREACH(string key, keys){    // for each key push i onto list
 | 
			
		||||
template<class Factor>
 | 
			
		||||
size_t FactorGraph<Factor>::nrFactors() const {
 | 
			
		||||
	int size_ = 0;
 | 
			
		||||
	for (const_iterator factor = factors_.begin(); factor != factors_.end(); factor++)
 | 
			
		||||
		if (*factor != NULL) size_++;
 | 
			
		||||
	return size_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
template<class Factor>
 | 
			
		||||
void FactorGraph<Factor>::push_back(shared_factor factor) {
 | 
			
		||||
 | 
			
		||||
	factors_.push_back(factor);                  // add the actual factor
 | 
			
		||||
 | 
			
		||||
	int i = factors_.size() - 1;                 // index of factor
 | 
			
		||||
	list<string> 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, so make one
 | 
			
		||||
			list<int> indices(1, i);
 | 
			
		||||
			indices_.insert(pair<string, list<int> >(key, indices));  // insert new indices into factorMap
 | 
			
		||||
		if (it==indices_.end()){                   // there's no list yet
 | 
			
		||||
			list<int> indices(1,i);                  // so make one
 | 
			
		||||
			indices_.insert(make_pair(key,indices)); // insert new indices into factorMap
 | 
			
		||||
		}
 | 
			
		||||
		else{
 | 
			
		||||
			list<int> *indices_ptr;
 | 
			
		||||
			indices_ptr = &(it->second);
 | 
			
		||||
			indices_ptr->push_back(i);
 | 
			
		||||
		else {
 | 
			
		||||
			list<int> *indices_ptr = &(it->second);  // get the list
 | 
			
		||||
			indices_ptr->push_back(i);               // add the index i to it
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
/**
 | 
			
		||||
 * Call colamd given a column-major symbolic matrix A
 | 
			
		||||
| 
						 | 
				
			
			@ -122,12 +132,12 @@ Ordering colamd(int n_col, int n_row, int nrNonZeros, const map<Key, vector<int>
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
template<class Factor, class Config>
 | 
			
		||||
Ordering FactorGraph<Factor,Config>::getOrdering() const {
 | 
			
		||||
template<class Factor>
 | 
			
		||||
Ordering FactorGraph<Factor>::getOrdering() const {
 | 
			
		||||
 | 
			
		||||
	// A factor graph is really laid out in row-major format, each factor a row
 | 
			
		||||
	// Below, we compute a symbolic matrix stored in sparse columns.
 | 
			
		||||
	typedef string Key;                  // default case  with string keys
 | 
			
		||||
	typedef string Key;             // default case  with string keys
 | 
			
		||||
	map<Key, vector<int> > columns; // map from keys to a sparse column of non-zero row indices
 | 
			
		||||
	int nrNonZeros = 0;             // number of non-zero entries
 | 
			
		||||
	int n_row = factors_.size();    /* colamd arg 1: number of rows in A */
 | 
			
		||||
| 
						 | 
				
			
			@ -147,5 +157,29 @@ Ordering FactorGraph<Factor,Config>::getOrdering() const {
 | 
			
		|||
		return colamd(n_col, n_row, nrNonZeros, columns);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
/** find all non-NULL factors for a variable, then set factors to NULL       */
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
template<class Factor>
 | 
			
		||||
vector<boost::shared_ptr<Factor> >
 | 
			
		||||
FactorGraph<Factor>::find_factors_and_remove(const string& key) {
 | 
			
		||||
	vector<boost::shared_ptr<Factor> > found;
 | 
			
		||||
 | 
			
		||||
	Indices::iterator it = indices_.find(key);
 | 
			
		||||
	if (it == indices_.end())
 | 
			
		||||
		throw(std::invalid_argument
 | 
			
		||||
				("FactorGraph::find_factors_and_remove invalid key: " + key));
 | 
			
		||||
 | 
			
		||||
	list<int> *indices_ptr; // pointer to indices list in indices_ map
 | 
			
		||||
	indices_ptr = &(it->second);
 | 
			
		||||
 | 
			
		||||
	BOOST_FOREACH(int i, *indices_ptr) {
 | 
			
		||||
		if(factors_[i] == NULL) continue; // skip NULL factors
 | 
			
		||||
		found.push_back(factors_[i]);     // add to found
 | 
			
		||||
		factors_[i].reset();              // set factor to NULL.
 | 
			
		||||
	}
 | 
			
		||||
	return found;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,7 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/serialization/map.hpp>
 | 
			
		||||
#include <boost/serialization/vector.hpp>
 | 
			
		||||
#include <boost/serialization/shared_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -18,10 +19,6 @@
 | 
			
		|||
namespace gtsam {
 | 
			
		||||
 | 
			
		||||
	class Ordering;
 | 
			
		||||
	class VectorConfig;
 | 
			
		||||
	class LinearFactor;
 | 
			
		||||
	class LinearFactorGraph;
 | 
			
		||||
	class Ordering;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * A factor graph is a bipartite graph with factor nodes connected to variable nodes.
 | 
			
		||||
| 
						 | 
				
			
			@ -29,9 +26,7 @@ namespace gtsam {
 | 
			
		|||
	 * 
 | 
			
		||||
	 * Templated on the type of factors and configuration.
 | 
			
		||||
	 */
 | 
			
		||||
	template<class Factor, class Config> class FactorGraph
 | 
			
		||||
		: public Testable<FactorGraph<Factor,Config> >
 | 
			
		||||
	{
 | 
			
		||||
	template<class Factor> class FactorGraph: public Testable<FactorGraph<Factor> > {
 | 
			
		||||
	public:
 | 
			
		||||
		typedef typename boost::shared_ptr<Factor> shared_factor;
 | 
			
		||||
		typedef typename std::vector<shared_factor>::iterator iterator;
 | 
			
		||||
| 
						 | 
				
			
			@ -73,38 +68,27 @@ namespace gtsam {
 | 
			
		|||
			return factors_[i];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/** return the numbers of the factors_ in the factor graph */
 | 
			
		||||
		inline size_t size() const {
 | 
			
		||||
			int size_=0;
 | 
			
		||||
			for (const_iterator factor = factors_.begin(); factor != factors_.end(); factor++)
 | 
			
		||||
			  if(*factor != NULL)
 | 
			
		||||
				  size_++;
 | 
			
		||||
			return size_;
 | 
			
		||||
		}
 | 
			
		||||
		/** return the number of factors and NULLS */
 | 
			
		||||
	  inline size_t size() const { return factors_.size();}
 | 
			
		||||
 | 
			
		||||
		/** return the number valid factors */
 | 
			
		||||
	  size_t nrFactors() const;
 | 
			
		||||
 | 
			
		||||
		/** Add a factor */
 | 
			
		||||
		void push_back(shared_factor factor);
 | 
			
		||||
 | 
			
		||||
		/** unnormalized error */
 | 
			
		||||
		double error(const Config& c) const {
 | 
			
		||||
			double total_error = 0.;
 | 
			
		||||
			/** iterate over all the factors_ to accumulate the log probabilities */
 | 
			
		||||
			for (const_iterator factor = factors_.begin(); factor != factors_.end(); factor++)
 | 
			
		||||
				total_error += (*factor)->error(c);
 | 
			
		||||
 | 
			
		||||
			return total_error;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/** Unnormalized probability. O(n) */
 | 
			
		||||
		double probPrime(const Config& c) const {
 | 
			
		||||
			return exp(-0.5 * error(c));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Compute colamd ordering
 | 
			
		||||
		 */
 | 
			
		||||
		Ordering getOrdering() const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * find all the factors that involve the given node and remove them
 | 
			
		||||
     * from the factor graph
 | 
			
		||||
     * @param key the key for the given node
 | 
			
		||||
     */
 | 
			
		||||
		std::vector<shared_factor> find_factors_and_remove(const std::string& key);
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
 | 
			
		||||
		/** Serialization function */
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +96,7 @@ namespace gtsam {
 | 
			
		|||
		template<class Archive>
 | 
			
		||||
		void serialize(Archive & ar, const unsigned int version) {
 | 
			
		||||
			ar & BOOST_SERIALIZATION_NVP(factors_);
 | 
			
		||||
			ar & BOOST_SERIALIZATION_NVP(indices_);
 | 
			
		||||
		}
 | 
			
		||||
	}; // FactorGraph
 | 
			
		||||
} // namespace gtsam
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,34 +55,13 @@ list<int> LinearFactorGraph::factors(const string& key) const {
 | 
			
		|||
	return it->second;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
/** find all non-NULL factors for a variable, then set factors to NULL       */
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
LinearFactorSet LinearFactorGraph::find_factors_and_remove(const string& key) {
 | 
			
		||||
	LinearFactorSet found;
 | 
			
		||||
 | 
			
		||||
	Indices::iterator it = indices_.find(key);
 | 
			
		||||
	list<int> *indices_ptr; // pointer to indices list in indices_ map
 | 
			
		||||
	indices_ptr = &(it->second);
 | 
			
		||||
 | 
			
		||||
	for (list<int>::iterator it = indices_ptr->begin(); it != indices_ptr->end(); it++) {
 | 
			
		||||
		if(factors_[*it] == NULL){  // skip NULL factors
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		found.push_back(factors_[*it]);
 | 
			
		||||
		factors_[*it].reset(); // set factor to NULL.
 | 
			
		||||
	}
 | 
			
		||||
	return found;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
/* find factors and remove them from the factor graph: O(n)                  */
 | 
			
		||||
/* ************************************************************************* */ 
 | 
			
		||||
boost::shared_ptr<LinearFactor>
 | 
			
		||||
LinearFactorGraph::combine_factors(const string& key)
 | 
			
		||||
{
 | 
			
		||||
	LinearFactorSet found = find_factors_and_remove(key);
 | 
			
		||||
	vector<LinearFactor::shared_ptr> found = find_factors_and_remove(key);
 | 
			
		||||
	boost::shared_ptr<LinearFactor> lf(new LinearFactor(found));
 | 
			
		||||
	return lf;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ namespace gtsam {
 | 
			
		|||
   *   VectorConfig = A configuration of vectors
 | 
			
		||||
   * Most of the time, linear factor graphs arise by linearizing a non-linear factor graph.
 | 
			
		||||
   */
 | 
			
		||||
  class LinearFactorGraph : public FactorGraph<LinearFactor, VectorConfig> {
 | 
			
		||||
  class LinearFactorGraph : public FactorGraph<LinearFactor> {
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +40,21 @@ namespace gtsam {
 | 
			
		|||
     */
 | 
			
		||||
    LinearFactorGraph(const ChordalBayesNet& CBN);
 | 
			
		||||
 | 
			
		||||
		/** unnormalized error */
 | 
			
		||||
		double error(const VectorConfig& c) const {
 | 
			
		||||
			double total_error = 0.;
 | 
			
		||||
			// iterate over all the factors_ to accumulate the log probabilities
 | 
			
		||||
			for (const_iterator factor = factors_.begin(); factor != factors_.end(); factor++)
 | 
			
		||||
				total_error += (*factor)->error(c);
 | 
			
		||||
 | 
			
		||||
			return total_error;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/** Unnormalized probability. O(n) */
 | 
			
		||||
		double probPrime(const VectorConfig& c) const {
 | 
			
		||||
			return exp(-0.5 * error(c));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * given a chordal bayes net, sets the linear factor graph identical to that CBN
 | 
			
		||||
     * FD: imperative !!
 | 
			
		||||
| 
						 | 
				
			
			@ -58,13 +73,6 @@ namespace gtsam {
 | 
			
		|||
     */
 | 
			
		||||
    std::list<int> factors(const std::string& key) const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * find all the factors that involve the given node and remove them
 | 
			
		||||
     * from the factor graph
 | 
			
		||||
     * @param key the key for the given node
 | 
			
		||||
     */
 | 
			
		||||
    LinearFactorSet find_factors_and_remove(const std::string& key);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * extract and combine all the factors that involve a given node
 | 
			
		||||
     * NOTE: the combined factor will be depends on a system-dependent
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,12 +82,12 @@ timeLinearFactor: LDFLAGS += -L.libs -lgtsam
 | 
			
		|||
 | 
			
		||||
# graphs 
 | 
			
		||||
sources += LinearFactorGraph.cpp 
 | 
			
		||||
#sources += BayesChain.cpp SymbolicBayesChain.cpp 
 | 
			
		||||
sources += SymbolicBayesChain.cpp 
 | 
			
		||||
sources += ChordalBayesNet.cpp 
 | 
			
		||||
sources += ConstrainedNonlinearFactorGraph.cpp ConstrainedLinearFactorGraph.cpp 
 | 
			
		||||
check_PROGRAMS += testFactorgraph testLinearFactorGraph testNonlinearFactorGraph 
 | 
			
		||||
check_PROGRAMS += testChordalBayesNet testNonlinearOptimizer
 | 
			
		||||
#check_PROGRAMS += testSymbolicBayesChain testBayesTree  
 | 
			
		||||
check_PROGRAMS += testSymbolicBayesChain testBayesTree  
 | 
			
		||||
check_PROGRAMS += testConstrainedNonlinearFactorGraph testConstrainedLinearFactorGraph
 | 
			
		||||
testFactorgraph_SOURCES          = testFactorgraph.cpp
 | 
			
		||||
testLinearFactorGraph_SOURCES    = $(example) testLinearFactorGraph.cpp
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,27 +13,42 @@
 | 
			
		|||
 | 
			
		||||
namespace gtsam {
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
template<class Config>
 | 
			
		||||
LinearFactorGraph NonlinearFactorGraph<Config>::linearize(const Config& config) const {
 | 
			
		||||
	// TODO speed up the function either by returning a pointer or by
 | 
			
		||||
	// returning the linearisation as a second argument and returning
 | 
			
		||||
	// the reference
 | 
			
		||||
	/* ************************************************************************* */
 | 
			
		||||
	template<class Config>
 | 
			
		||||
	double NonlinearFactorGraph<Config>::error(const Config& c) const {
 | 
			
		||||
		double total_error = 0.;
 | 
			
		||||
		// iterate over all the factors_ to accumulate the log probabilities
 | 
			
		||||
		typedef typename FactorGraph<NonlinearFactor<Config> >::const_iterator
 | 
			
		||||
				const_iterator;
 | 
			
		||||
		for (const_iterator factor = this->factors_.begin(); factor
 | 
			
		||||
				!= this->factors_.end(); factor++)
 | 
			
		||||
			total_error += (*factor)->error(c);
 | 
			
		||||
 | 
			
		||||
	// create an empty linear FG
 | 
			
		||||
	LinearFactorGraph linearFG;
 | 
			
		||||
		return total_error;
 | 
			
		||||
	}
 | 
			
		||||
	/* ************************************************************************* */
 | 
			
		||||
	template<class Config>
 | 
			
		||||
	LinearFactorGraph NonlinearFactorGraph<Config>::linearize(
 | 
			
		||||
			const Config& config) const {
 | 
			
		||||
		// TODO speed up the function either by returning a pointer or by
 | 
			
		||||
		// returning the linearisation as a second argument and returning
 | 
			
		||||
		// the reference
 | 
			
		||||
 | 
			
		||||
	typedef typename FactorGraph<NonlinearFactor<Config> ,Config>:: const_iterator const_iterator;
 | 
			
		||||
	// linearize all factors
 | 
			
		||||
	for (const_iterator factor = this->factors_.begin(); factor
 | 
			
		||||
			< this->factors_.end(); factor++) {
 | 
			
		||||
		boost::shared_ptr<LinearFactor> lf = (*factor)->linearize(config);
 | 
			
		||||
		linearFG.push_back(lf);
 | 
			
		||||
		// create an empty linear FG
 | 
			
		||||
		LinearFactorGraph linearFG;
 | 
			
		||||
 | 
			
		||||
		typedef typename FactorGraph<NonlinearFactor<Config> >::const_iterator
 | 
			
		||||
				const_iterator;
 | 
			
		||||
		// linearize all factors
 | 
			
		||||
		for (const_iterator factor = this->factors_.begin(); factor
 | 
			
		||||
				< this->factors_.end(); factor++) {
 | 
			
		||||
			boost::shared_ptr<LinearFactor> lf = (*factor)->linearize(config);
 | 
			
		||||
			linearFG.push_back(lf);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return linearFG;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return linearFG;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,7 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "NonlinearFactor.h"
 | 
			
		||||
#include "FactorGraph.h"
 | 
			
		||||
#include "LinearFactorGraph.h"
 | 
			
		||||
 | 
			
		||||
namespace gtsam {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -22,12 +22,20 @@ namespace gtsam {
 | 
			
		|||
	 * Linearizing the non-linear factor graph creates a linear factor graph on the 
 | 
			
		||||
	 * tangent vector space at the linearization point. Because the tangent space is a true
 | 
			
		||||
	 * vector space, the config type will be an VectorConfig in that linearized
 | 
			
		||||
 	 */
 | 
			
		||||
	 */
 | 
			
		||||
	template<class Config>
 | 
			
		||||
	class NonlinearFactorGraph: public FactorGraph<NonlinearFactor<Config> ,Config> {
 | 
			
		||||
	class NonlinearFactorGraph: public FactorGraph<NonlinearFactor<Config> > {
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
 | 
			
		||||
		/** unnormalized error */
 | 
			
		||||
		double error(const Config& c) const;
 | 
			
		||||
 | 
			
		||||
		/** Unnormalized probability. O(n) */
 | 
			
		||||
		double probPrime(const Config& c) const {
 | 
			
		||||
			return exp(-0.5 * error(c));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * linearize a nonlinear factor graph
 | 
			
		||||
		 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,9 +14,9 @@ using namespace std;
 | 
			
		|||
namespace gtsam {
 | 
			
		||||
 | 
			
		||||
	/* ************************************************************************* */
 | 
			
		||||
	template<class Factor, class Config>
 | 
			
		||||
	template<class Factor>
 | 
			
		||||
	SymbolicBayesChain::SymbolicBayesChain(
 | 
			
		||||
			const FactorGraph<Factor, Config>& factorGraph, const Ordering& ordering) {
 | 
			
		||||
			const FactorGraph<Factor>& factorGraph, const Ordering& ordering) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,7 @@
 | 
			
		|||
// trick from some reading group
 | 
			
		||||
#define FOREACH_PAIR( KEY, VAL, COL) BOOST_FOREACH (boost::tie(KEY,VAL),COL)
 | 
			
		||||
 | 
			
		||||
#include "BayesChain-inl.h"
 | 
			
		||||
#include "SymbolicBayesChain.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,8 +36,8 @@ namespace gtsam {
 | 
			
		|||
		/**
 | 
			
		||||
		 *  Construct from any factor graph
 | 
			
		||||
		 */
 | 
			
		||||
		template<class Factor, class Config>
 | 
			
		||||
		SymbolicBayesChain(const FactorGraph<Factor, Config>& factorGraph,
 | 
			
		||||
		template<class Factor>
 | 
			
		||||
		SymbolicBayesChain(const FactorGraph<Factor>& factorGraph,
 | 
			
		||||
				const Ordering& ordering);
 | 
			
		||||
 | 
			
		||||
		/** Destructor */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@
 | 
			
		|||
#include <iostream>
 | 
			
		||||
#include <CppUnitLite/TestHarness.h>
 | 
			
		||||
#include "ConstrainedLinearFactorGraph.h"
 | 
			
		||||
#include "FactorGraph-inl.h"
 | 
			
		||||
#include "LinearFactorGraph.h"
 | 
			
		||||
#include "smallExample.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -237,12 +238,12 @@ TEST( ConstrainedLinearFactorGraph, eliminate_multi_constraint )
 | 
			
		|||
	// eliminate the constraint
 | 
			
		||||
	ConstrainedConditionalGaussian::shared_ptr cg1 = fg.eliminate_constraint("x");
 | 
			
		||||
	CHECK(cg1->size() == 1);
 | 
			
		||||
	CHECK(fg.size() == 2);
 | 
			
		||||
	CHECK(fg.nrFactors() == 1);
 | 
			
		||||
 | 
			
		||||
	// eliminate the induced constraint
 | 
			
		||||
	ConstrainedConditionalGaussian::shared_ptr cg2 = fg.eliminate_constraint("y");
 | 
			
		||||
	CHECK(fg.size() == 1);
 | 
			
		||||
	CHECK(cg2->size() == 1);
 | 
			
		||||
	CHECK(fg.nrFactors() == 0);
 | 
			
		||||
 | 
			
		||||
	// eliminate the linear factor
 | 
			
		||||
	ConditionalGaussian::shared_ptr cg3 = fg.eliminate_one("z");
 | 
			
		||||
| 
						 | 
				
			
			@ -259,7 +260,6 @@ TEST( ConstrainedLinearFactorGraph, eliminate_multi_constraint )
 | 
			
		|||
	CHECK(assert_equal(act_y, Vector_(2, -0.1, 0.4), 1e-4));
 | 
			
		||||
	Vector act_x = cg1->solve(actual);
 | 
			
		||||
	CHECK(assert_equal(act_x, Vector_(2, -2.0, 2.0), 1e-4));
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -487,7 +487,7 @@ TEST( LinearFactorGraph, find_factors_and_remove )
 | 
			
		|||
  LinearFactor::shared_ptr f2 = fg[2];
 | 
			
		||||
 | 
			
		||||
  // call the function
 | 
			
		||||
  LinearFactorSet factors = fg.find_factors_and_remove("x1");
 | 
			
		||||
  vector<LinearFactor::shared_ptr> factors = fg.find_factors_and_remove("x1");
 | 
			
		||||
 | 
			
		||||
  // Check the factors
 | 
			
		||||
  CHECK(f0==factors[0]);
 | 
			
		||||
| 
						 | 
				
			
			@ -495,7 +495,7 @@ TEST( LinearFactorGraph, find_factors_and_remove )
 | 
			
		|||
  CHECK(f2==factors[2]);
 | 
			
		||||
 | 
			
		||||
  // CHECK if the factors are deleted from the factor graph
 | 
			
		||||
  LONGS_EQUAL(1,fg.size());
 | 
			
		||||
  LONGS_EQUAL(1,fg.nrFactors());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
| 
						 | 
				
			
			@ -510,7 +510,7 @@ TEST( LinearFactorGraph, find_factors_and_remove__twice )
 | 
			
		|||
  LinearFactor::shared_ptr f2 = fg[2];
 | 
			
		||||
 | 
			
		||||
  // call the function
 | 
			
		||||
  LinearFactorSet factors = fg.find_factors_and_remove("x1");
 | 
			
		||||
  vector<LinearFactor::shared_ptr> factors = fg.find_factors_and_remove("x1");
 | 
			
		||||
 | 
			
		||||
  // Check the factors
 | 
			
		||||
  CHECK(f0==factors[0]);
 | 
			
		||||
| 
						 | 
				
			
			@ -521,7 +521,7 @@ TEST( LinearFactorGraph, find_factors_and_remove__twice )
 | 
			
		|||
  CHECK(factors.size() == 0);
 | 
			
		||||
 | 
			
		||||
  // CHECK if the factors are deleted from the factor graph
 | 
			
		||||
  LONGS_EQUAL(1,fg.size());
 | 
			
		||||
  LONGS_EQUAL(1,fg.nrFactors());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,32 +7,121 @@
 | 
			
		|||
#include <CppUnitLite/TestHarness.h>
 | 
			
		||||
 | 
			
		||||
#include "smallExample.h"
 | 
			
		||||
#include "FactorGraph-inl.h"
 | 
			
		||||
#include "BayesChain-inl.h"
 | 
			
		||||
#include "SymbolicBayesChain-inl.h"
 | 
			
		||||
 | 
			
		||||
namespace gtsam {
 | 
			
		||||
 | 
			
		||||
	/** Symbolic Factor */
 | 
			
		||||
	class SymbolicFactor: public Testable<SymbolicFactor> {
 | 
			
		||||
	private:
 | 
			
		||||
 | 
			
		||||
		std::list<std::string> keys_;
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
 | 
			
		||||
		SymbolicFactor(std::list<std::string> keys) :
 | 
			
		||||
			keys_(keys) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		typedef boost::shared_ptr<SymbolicFactor> shared_ptr;
 | 
			
		||||
 | 
			
		||||
		/** print */
 | 
			
		||||
		void print(const std::string& s = "SymbolicFactor") const {
 | 
			
		||||
			cout << s << " ";
 | 
			
		||||
			BOOST_FOREACH(string key, keys_) cout << key << " ";
 | 
			
		||||
			cout << endl;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/** check equality */
 | 
			
		||||
		bool equals(const SymbolicFactor& other, double tol = 1e-9) const {
 | 
			
		||||
			return keys_ == other.keys_;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Find all variables
 | 
			
		||||
		 * @return The set of all variable keys
 | 
			
		||||
		 */
 | 
			
		||||
		std::list<std::string> keys() const {
 | 
			
		||||
			return keys_;
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/** Symbolic Factor Graph */
 | 
			
		||||
	class SymbolicFactorGraph: public FactorGraph<SymbolicFactor> {
 | 
			
		||||
	public:
 | 
			
		||||
 | 
			
		||||
		SymbolicFactorGraph() {}
 | 
			
		||||
 | 
			
		||||
		template<class Factor>
 | 
			
		||||
		SymbolicFactorGraph(const FactorGraph<Factor>& fg) {
 | 
			
		||||
			for (size_t i = 0; i < fg.size(); i++) {
 | 
			
		||||
				boost::shared_ptr<Factor> f = fg[i];
 | 
			
		||||
				std::list<std::string> keys = f->keys();
 | 
			
		||||
				SymbolicFactor::shared_ptr factor(new SymbolicFactor(keys));
 | 
			
		||||
				push_back(factor);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace gtsam;
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
TEST( SymbolicBayesChain, symbolicFactorGraph )
 | 
			
		||||
{
 | 
			
		||||
	// construct expected symbolic graph
 | 
			
		||||
	SymbolicFactorGraph expected;
 | 
			
		||||
 | 
			
		||||
	list<string> f1_keys; f1_keys.push_back("x1");
 | 
			
		||||
	SymbolicFactor::shared_ptr f1(new SymbolicFactor(f1_keys));
 | 
			
		||||
	expected.push_back(f1);
 | 
			
		||||
 | 
			
		||||
	list<string> f2_keys; f2_keys.push_back("x1"); f2_keys.push_back("x2");
 | 
			
		||||
	SymbolicFactor::shared_ptr f2(new SymbolicFactor(f2_keys));
 | 
			
		||||
	expected.push_back(f2);
 | 
			
		||||
 | 
			
		||||
	list<string> f3_keys; f3_keys.push_back("l1"); f3_keys.push_back("x1");
 | 
			
		||||
	SymbolicFactor::shared_ptr f3(new SymbolicFactor(f3_keys));
 | 
			
		||||
	expected.push_back(f3);
 | 
			
		||||
 | 
			
		||||
	list<string> f4_keys; f4_keys.push_back("l1"); f4_keys.push_back("x2");
 | 
			
		||||
	SymbolicFactor::shared_ptr f4(new SymbolicFactor(f4_keys));
 | 
			
		||||
	expected.push_back(f4);
 | 
			
		||||
 | 
			
		||||
	// construct it from the factor graph graph
 | 
			
		||||
	LinearFactorGraph factorGraph = createLinearFactorGraph();
 | 
			
		||||
	SymbolicFactorGraph actual(factorGraph);
 | 
			
		||||
 | 
			
		||||
	CHECK(assert_equal(expected, actual));
 | 
			
		||||
 | 
			
		||||
	//symbolicGraph.find_factors_and_remove("x");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
TEST( SymbolicBayesChain, constructor )
 | 
			
		||||
{
 | 
			
		||||
	// Create manually
 | 
			
		||||
	SymbolicConditional::shared_ptr x2(new SymbolicConditional("x1","l1"));
 | 
			
		||||
	SymbolicConditional::shared_ptr x2(new SymbolicConditional("x1", "l1"));
 | 
			
		||||
	SymbolicConditional::shared_ptr l1(new SymbolicConditional("x1"));
 | 
			
		||||
	SymbolicConditional::shared_ptr x1(new SymbolicConditional());
 | 
			
		||||
	map<string, SymbolicConditional::shared_ptr> nodes;
 | 
			
		||||
	nodes.insert(make_pair("x2",x2));
 | 
			
		||||
	nodes.insert(make_pair("l1",l1));
 | 
			
		||||
	nodes.insert(make_pair("x1",x1));
 | 
			
		||||
	nodes.insert(make_pair("x2", x2));
 | 
			
		||||
	nodes.insert(make_pair("l1", l1));
 | 
			
		||||
	nodes.insert(make_pair("x1", x1));
 | 
			
		||||
	SymbolicBayesChain expected(nodes);
 | 
			
		||||
 | 
			
		||||
	// Create from a factor graph
 | 
			
		||||
  Ordering ordering;
 | 
			
		||||
  ordering.push_back("x2");
 | 
			
		||||
  ordering.push_back("l1");
 | 
			
		||||
  ordering.push_back("x1");
 | 
			
		||||
	Ordering ordering;
 | 
			
		||||
	ordering.push_back("x2");
 | 
			
		||||
	ordering.push_back("l1");
 | 
			
		||||
	ordering.push_back("x1");
 | 
			
		||||
	LinearFactorGraph factorGraph = createLinearFactorGraph();
 | 
			
		||||
	SymbolicBayesChain actual(factorGraph,ordering);
 | 
			
		||||
 | 
			
		||||
	SymbolicBayesChain actual(factorGraph, ordering);
 | 
			
		||||
	//CHECK(assert_equal(expected, actual));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue