210 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			210 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C++
		
	
	
| /**
 | |
|  * @file    VectorConfig.cpp
 | |
|  * @brief   Factor Graph Configuration
 | |
|  * @brief   VectorConfig
 | |
|  * @author  Carlos Nieto
 | |
|  * @author  Christian Potthast
 | |
|  */
 | |
| 
 | |
| #include <boost/foreach.hpp>
 | |
| #include <boost/tuple/tuple.hpp>
 | |
| #include "VectorConfig.h"
 | |
| 
 | |
| // trick from some reading group
 | |
| #define FOREACH_PAIR( KEY, VAL, COL) BOOST_FOREACH (boost::tie(KEY,VAL),COL) 
 | |
| 
 | |
| using namespace std;
 | |
| 
 | |
| namespace gtsam {
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| void check_size(const Symbol& key, const Vector & vj, const Vector & dj) {
 | |
|   if (dj.size()!=vj.size()) {
 | |
|     cout << "For key \"" << (string)key << "\"" << endl;
 | |
|     cout << "vj.size = " << vj.size() << endl;
 | |
|     cout << "dj.size = " << dj.size() << endl;
 | |
|     throw(std::invalid_argument("VectorConfig::+ mismatched dimensions"));
 | |
|   }
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| std::vector<Symbol> VectorConfig::get_names() const {
 | |
|   std::vector<Symbol> names;
 | |
|   for(const_iterator it=values.begin(); it!=values.end(); it++)
 | |
|     names.push_back(it->first);
 | |
|   return names;
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| void VectorConfig::insert(const VectorConfig& config) {
 | |
| 	for (const_iterator it = config.begin(); it!=config.end(); it++) {
 | |
| 		insert(it->first, it->second);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| void VectorConfig::add(const Symbol& j, const Vector& a) {
 | |
| 	Vector& vj = values[j];
 | |
| 	if (vj.size()==0) vj = a; else vj += a;
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| size_t VectorConfig::dim() const {
 | |
| 	size_t result=0;
 | |
| 	Symbol key; Vector v; // rtodo: copying vector?
 | |
| 	FOREACH_PAIR(key, v, values) result += v.size();
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| VectorConfig VectorConfig::scale(double s) const {
 | |
| 	VectorConfig scaled;
 | |
| 	Symbol key; Vector val; // rtodo: copying vector?
 | |
| 	FOREACH_PAIR(key, val, values)
 | |
| 		scaled.insert(key, s*val);
 | |
| 	return scaled;
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| VectorConfig VectorConfig::operator*(double s) const {
 | |
| 	return scale(s);
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| VectorConfig VectorConfig::operator-() const {
 | |
| 	VectorConfig result;
 | |
| 	Symbol j; Vector v; // rtodo: copying vector?
 | |
| 	FOREACH_PAIR(j, v, values)
 | |
| 		result.insert(j, -v);
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| void VectorConfig::operator+=(const VectorConfig& b) {
 | |
|   Symbol j; Vector b_j; // rtodo: copying vector?
 | |
| 	FOREACH_PAIR(j, b_j, b.values) {
 | |
| 		iterator it = values.find(j);
 | |
| 		if (it==values.end())
 | |
| 			insert(j, b_j);
 | |
| 		else
 | |
| 			it->second += b_j;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| VectorConfig VectorConfig::operator+(const VectorConfig& b) const {
 | |
| 	VectorConfig result = *this;
 | |
| 	result += b;
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| VectorConfig VectorConfig::operator-(const VectorConfig& b) const {
 | |
| 	VectorConfig result;
 | |
| 	Symbol j; Vector v; // rtodo: copying vector?
 | |
| 	FOREACH_PAIR(j, v, values)
 | |
| 		result.insert(j, v - b.get(j));
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| VectorConfig expmap(const VectorConfig& original, const VectorConfig& delta)
 | |
| {
 | |
| 	VectorConfig newConfig;
 | |
| 	Symbol j; Vector vj; // rtodo: copying vector?
 | |
| 	FOREACH_PAIR(j, vj, original.values) {
 | |
| 		if (delta.contains(j)) {
 | |
| 			const Vector& dj = delta[j];
 | |
| 			check_size(j,vj,dj);
 | |
| 			newConfig.insert(j, vj + dj);
 | |
| 		} else {
 | |
| 			newConfig.insert(j, vj);
 | |
| 		}
 | |
| 	}
 | |
| 	return newConfig;
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| VectorConfig expmap(const VectorConfig& original, const Vector& delta)
 | |
| {
 | |
| 	VectorConfig newConfig;
 | |
| 	size_t i = 0;
 | |
| 	Symbol j; Vector vj; // rtodo: copying vector?
 | |
| 	FOREACH_PAIR(j, vj, original.values) {
 | |
| 		size_t mj = vj.size();
 | |
| 		Vector dj = sub(delta, i, i+mj);
 | |
| 		newConfig.insert(j, vj + dj);
 | |
| 		i += mj;
 | |
| 	}
 | |
| 	return newConfig;
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| const Vector& VectorConfig::get(const Symbol& name) const {
 | |
|   return values.at(name);
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| Vector& VectorConfig::getReference(const Symbol& name) {
 | |
|   return values.at(name);
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| void VectorConfig::print(const string& name) const {
 | |
|   odprintf("VectorConfig %s\n", name.c_str());
 | |
|   odprintf("size: %d\n", values.size());
 | |
|   Symbol j; Vector v; // rtodo: copying vector
 | |
|   FOREACH_PAIR(j, v, values) {
 | |
|     odprintf("%s:", ((string)j).c_str());
 | |
|     gtsam::print(v);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| bool VectorConfig::equals(const VectorConfig& expected, double tol) const {
 | |
|   Symbol j; Vector vActual; // rtodo: copying vector
 | |
|   if( values.size() != expected.size() ) return false;
 | |
| 
 | |
|   // iterate over all nodes
 | |
|   FOREACH_PAIR(j, vActual, values) {
 | |
|     Vector vExpected = expected[j];
 | |
|     if(!equal_with_abs_tol(vExpected,vActual,tol)) 
 | |
|     	return false;
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| double VectorConfig::dot(const VectorConfig& b) const {
 | |
|   Symbol j; Vector v; double result = 0.0; // rtodo: copying vector
 | |
| 	FOREACH_PAIR(j, v, values) result += gtsam::dot(v,b.get(j));
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| double dot(const VectorConfig& a, const VectorConfig& b) {
 | |
| 	return a.dot(b);
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| void scal(double alpha, VectorConfig& x) {
 | |
| 	for (VectorConfig::iterator xj = x.begin(); xj != x.end(); xj++)
 | |
| 		scal(alpha, xj->second);
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| void axpy(double alpha, const VectorConfig& x, VectorConfig& y) {
 | |
| 	VectorConfig::const_iterator xj = x.begin();
 | |
| 	for (VectorConfig::iterator yj = y.begin(); yj != y.end(); yj++, xj++)
 | |
| 		axpy(alpha, xj->second, yj->second);
 | |
| }
 | |
| 
 | |
| /* ************************************************************************* */
 | |
| 
 | |
| void print(const VectorConfig& v, const std::string& s){
 | |
| 	v.print(s);
 | |
| }
 | |
| /* ************************************************************************* */
 | |
| 
 | |
| } // gtsam
 |