Some refactoring, new static method "combine"
							parent
							
								
									374140abb8
								
							
						
					
					
						commit
						ae17f8a82f
					
				|  | @ -17,6 +17,8 @@ | |||
|  * @brief Internals for Expression.h, not for general consumption | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <gtsam/nonlinear/Values.h> | ||||
| #include <boost/foreach.hpp> | ||||
| 
 | ||||
|  | @ -34,10 +36,16 @@ class Expression; | |||
|  */ | ||||
| template<class T> | ||||
| class ExpressionNode { | ||||
| 
 | ||||
| protected: | ||||
|   ExpressionNode() { | ||||
|   } | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
|   typedef std::map<Key, Matrix> JacobianMap; | ||||
| 
 | ||||
|   /// Destructor
 | ||||
|   virtual ~ExpressionNode() { | ||||
|   } | ||||
| 
 | ||||
|  | @ -46,7 +54,7 @@ public: | |||
| 
 | ||||
|   /// Return value and optional derivatives
 | ||||
|   virtual T value(const Values& values, | ||||
|       boost::optional<std::map<Key, Matrix>&> = boost::none) const = 0; | ||||
|       boost::optional<JacobianMap&> = boost::none) const = 0; | ||||
| }; | ||||
| 
 | ||||
| /// Constant Expression
 | ||||
|  | @ -64,6 +72,9 @@ class ConstantExpression: public ExpressionNode<T> { | |||
| 
 | ||||
| public: | ||||
| 
 | ||||
|   typedef std::map<Key, Matrix> JacobianMap; | ||||
| 
 | ||||
|   /// Destructor
 | ||||
|   virtual ~ConstantExpression() { | ||||
|   } | ||||
| 
 | ||||
|  | @ -75,7 +86,7 @@ public: | |||
| 
 | ||||
|   /// Return value and optional derivatives
 | ||||
|   virtual T value(const Values& values, | ||||
|       boost::optional<std::map<Key, Matrix>&> jacobians = boost::none) const { | ||||
|       boost::optional<JacobianMap&> jacobians = boost::none) const { | ||||
|     return value_; | ||||
|   } | ||||
| }; | ||||
|  | @ -96,6 +107,9 @@ class LeafExpression: public ExpressionNode<T> { | |||
| 
 | ||||
| public: | ||||
| 
 | ||||
|   typedef std::map<Key, Matrix> JacobianMap; | ||||
| 
 | ||||
|   /// Destructor
 | ||||
|   virtual ~LeafExpression() { | ||||
|   } | ||||
| 
 | ||||
|  | @ -108,10 +122,10 @@ public: | |||
| 
 | ||||
|   /// Return value and optional derivatives
 | ||||
|   virtual T value(const Values& values, | ||||
|       boost::optional<std::map<Key, Matrix>&> jacobians = boost::none) const { | ||||
|       boost::optional<JacobianMap&> jacobians = boost::none) const { | ||||
|     const T& value = values.at<T>(key_); | ||||
|     if (jacobians) { | ||||
|       std::map<Key, Matrix>::iterator it = jacobians->find(key_); | ||||
|       JacobianMap::iterator it = jacobians->find(key_); | ||||
|       if (it != jacobians->end()) { | ||||
|         it->second += Eigen::MatrixXd::Identity(value.dim(), value.dim()); | ||||
|       } else { | ||||
|  | @ -147,6 +161,9 @@ private: | |||
| 
 | ||||
| public: | ||||
| 
 | ||||
|   typedef std::map<Key, Matrix> JacobianMap; | ||||
| 
 | ||||
|   /// Destructor
 | ||||
|   virtual ~UnaryExpression() { | ||||
|   } | ||||
| 
 | ||||
|  | @ -157,13 +174,13 @@ public: | |||
| 
 | ||||
|   /// Return value and optional derivatives
 | ||||
|   virtual T value(const Values& values, | ||||
|       boost::optional<std::map<Key, Matrix>&> jacobians = boost::none) const { | ||||
|       boost::optional<JacobianMap&> jacobians = boost::none) const { | ||||
| 
 | ||||
|     T value; | ||||
|     if (jacobians) { | ||||
|       Eigen::MatrixXd H; | ||||
|       value = f_(expression_->value(values, jacobians), H); | ||||
|       std::map<Key, Matrix>::iterator it = jacobians->begin(); | ||||
|       JacobianMap::iterator it = jacobians->begin(); | ||||
|       for (; it != jacobians->end(); ++it) { | ||||
|         it->second = H * it->second; | ||||
|       } | ||||
|  | @ -183,6 +200,8 @@ class BinaryExpression: public ExpressionNode<T> { | |||
| 
 | ||||
| public: | ||||
| 
 | ||||
|   typedef std::map<Key, Matrix> JacobianMap; | ||||
| 
 | ||||
|   typedef boost::function< | ||||
|       T(const E1&, const E2&, boost::optional<Matrix&>, | ||||
|           boost::optional<Matrix&>)> function; | ||||
|  | @ -200,8 +219,34 @@ private: | |||
| 
 | ||||
|   friend class Expression<T> ; | ||||
| 
 | ||||
|   /// Combine Jacobians
 | ||||
|   static void combine(const Matrix& H1, const Matrix& H2, | ||||
|       const JacobianMap& terms1, const JacobianMap& terms2, | ||||
|       JacobianMap& jacobians) { | ||||
|     // TODO: both Jacobians and terms are sorted. There must be a simple
 | ||||
|     //       but fast algorithm that does this.
 | ||||
|     typedef std::pair<Key, Matrix> Pair; | ||||
|     BOOST_FOREACH(const Pair& term, terms1) { | ||||
|       JacobianMap::iterator it = jacobians.find(term.first); | ||||
|       if (it != jacobians.end()) { | ||||
|         it->second += H1 * term.second; | ||||
|       } else { | ||||
|         jacobians[term.first] = H1 * term.second; | ||||
|       } | ||||
|     } | ||||
|     BOOST_FOREACH(const Pair& term, terms2) { | ||||
|       JacobianMap::iterator it = jacobians.find(term.first); | ||||
|       if (it != jacobians.end()) { | ||||
|         it->second += H2 * term.second; | ||||
|       } else { | ||||
|         jacobians[term.first] = H2 * term.second; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
|   /// Destructor
 | ||||
|   virtual ~BinaryExpression() { | ||||
|   } | ||||
| 
 | ||||
|  | @ -215,33 +260,14 @@ public: | |||
| 
 | ||||
|   /// Return value and optional derivatives
 | ||||
|   virtual T value(const Values& values, | ||||
|       boost::optional<std::map<Key, Matrix>&> jacobians = boost::none) const { | ||||
|       boost::optional<JacobianMap&> jacobians = boost::none) const { | ||||
|     T val; | ||||
|     if (jacobians) { | ||||
|       std::map<Key, Matrix> terms1; | ||||
|       std::map<Key, Matrix> terms2; | ||||
|       JacobianMap terms1, terms2; | ||||
|       Matrix H1, H2; | ||||
|       val = f_(expression1_->value(values, terms1), | ||||
|           expression2_->value(values, terms2), H1, H2); | ||||
|       // TODO: both Jacobians and terms are sorted. There must be a simple
 | ||||
|       //       but fast algorithm that does this.
 | ||||
|       typedef std::pair<Key, Matrix> Pair; | ||||
|       BOOST_FOREACH(const Pair& term, terms1) { | ||||
|         std::map<Key, Matrix>::iterator it = jacobians->find(term.first); | ||||
|         if (it != jacobians->end()) { | ||||
|           it->second += H1 * term.second; | ||||
|         } else { | ||||
|           (*jacobians)[term.first] = H1 * term.second; | ||||
|         } | ||||
|       } | ||||
|       BOOST_FOREACH(const Pair& term, terms2) { | ||||
|         std::map<Key, Matrix>::iterator it = jacobians->find(term.first); | ||||
|         if (it != jacobians->end()) { | ||||
|           it->second += H2 * term.second; | ||||
|         } else { | ||||
|           (*jacobians)[term.first] = H2 * term.second; | ||||
|         } | ||||
|       } | ||||
|       combine(H1, H2, terms1, terms2, *jacobians); | ||||
|     } else { | ||||
|       val = f_(expression1_->value(values), expression2_->value(values), | ||||
|           boost::none, boost::none); | ||||
|  |  | |||
|  | @ -17,8 +17,9 @@ | |||
|  * @brief Expressions for Block Automatic Differentiation | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "Expression-inl.h" | ||||
| #include <gtsam/inference/Key.h> | ||||
| #include <boost/bind.hpp> | ||||
| 
 | ||||
| namespace gtsam { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue