102 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C++
		
	
	
| /* ----------------------------------------------------------------------------
 | |
| 
 | |
|  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
 | |
|  * Atlanta, Georgia 30332-0415
 | |
|  * All Rights Reserved
 | |
|  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
 | |
| 
 | |
|  * See LICENSE for the license information
 | |
| 
 | |
|  * -------------------------------------------------------------------------- */
 | |
| 
 | |
| /**
 | |
|  * @file    RegularHessianFactor.h
 | |
|  * @brief   HessianFactor class with constant sized blcoks
 | |
|  * @author  Richard Roberts
 | |
|  * @date    Dec 8, 2010
 | |
|  */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <gtsam/linear/HessianFactor.h>
 | |
| #include <boost/foreach.hpp>
 | |
| #include <vector>
 | |
| 
 | |
| namespace gtsam {
 | |
| 
 | |
| template<size_t D>
 | |
| class RegularHessianFactor: public HessianFactor {
 | |
| 
 | |
| private:
 | |
| 
 | |
|   typedef Eigen::Matrix<double, D, D> MatrixDD; // camera hessian block
 | |
|   typedef Eigen::Matrix<double, D, 1> VectorD;
 | |
| 
 | |
| public:
 | |
| 
 | |
|   /** Construct an n-way factor.  Gs contains the upper-triangle blocks of the
 | |
|    * quadratic term (the Hessian matrix) provided in row-order, gs the pieces
 | |
|    * of the linear vector term, and f the constant term.
 | |
|    */
 | |
|   RegularHessianFactor(const std::vector<Key>& js,
 | |
|       const std::vector<Matrix>& Gs, const std::vector<Vector>& gs, double f) :
 | |
|       HessianFactor(js, Gs, gs, f) {
 | |
|   }
 | |
| 
 | |
|   /** Constructor with an arbitrary number of keys and with the augmented information matrix
 | |
|    *   specified as a block matrix. */
 | |
|   template<typename KEYS>
 | |
|   RegularHessianFactor(const KEYS& keys,
 | |
|       const SymmetricBlockMatrix& augmentedInformation) :
 | |
|       HessianFactor(keys, augmentedInformation) {
 | |
|   }
 | |
| 
 | |
|   /** y += alpha * A'*A*x */
 | |
|   void multiplyHessianAdd(double alpha, const VectorValues& x,
 | |
|       VectorValues& y) const {
 | |
|     HessianFactor::multiplyHessianAdd(alpha, x, y);
 | |
|   }
 | |
| 
 | |
|   // Scratch space for multiplyHessianAdd
 | |
|   typedef Eigen::Matrix<double, D, 1> DVector;
 | |
|   mutable std::vector<DVector> y;
 | |
| 
 | |
|   void multiplyHessianAdd(double alpha, const double* x,
 | |
|       double* yvalues) const {
 | |
|     // Create a vector of temporary y values, corresponding to rows i
 | |
|     y.resize(size());
 | |
|     BOOST_FOREACH(DVector & yi, y)
 | |
|       yi.setZero();
 | |
| 
 | |
|     typedef Eigen::Map<DVector> DMap;
 | |
|     typedef Eigen::Map<const DVector> ConstDMap;
 | |
| 
 | |
|     // Accessing the VectorValues one by one is expensive
 | |
|     // So we will loop over columns to access x only once per column
 | |
|     // And fill the above temporary y values, to be added into yvalues after
 | |
|     DVector xj(D);
 | |
|     for (DenseIndex j = 0; j < (DenseIndex) size(); ++j) {
 | |
|       Key key = keys_[j];
 | |
|       const double* xj = x + key * D;
 | |
|       DenseIndex i = 0;
 | |
|       for (; i < j; ++i)
 | |
|         y[i] += info_(i, j).knownOffDiagonal() * ConstDMap(xj);
 | |
|       // blocks on the diagonal are only half
 | |
|       y[i] += info_(j, j).selfadjointView() * ConstDMap(xj);
 | |
|       // for below diagonal, we take transpose block from upper triangular part
 | |
|       for (i = j + 1; i < (DenseIndex) size(); ++i)
 | |
|         y[i] += info_(i, j).knownOffDiagonal() * ConstDMap(xj);
 | |
|     }
 | |
| 
 | |
|     // copy to yvalues
 | |
|     for (DenseIndex i = 0; i < (DenseIndex) size(); ++i) {
 | |
|       Key key = keys_[i];
 | |
|       DMap(yvalues + key * D) += alpha * y[i];
 | |
|     }
 | |
|   }
 | |
| 
 | |
| };
 | |
| 
 | |
| }
 | |
| 
 |