2009-08-22 06:23:24 +08:00
|
|
|
/**
|
2009-11-13 00:16:32 +08:00
|
|
|
* @file GaussianFactor.h
|
2009-08-22 06:23:24 +08:00
|
|
|
* @brief Linear Factor....A Gaussian
|
|
|
|
|
* @brief linearFactor
|
|
|
|
|
* @author Christian Potthast
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// \callgraph
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <boost/shared_ptr.hpp>
|
2009-11-06 13:43:03 +08:00
|
|
|
#include <boost/tuple/tuple.hpp>
|
2010-08-27 23:31:20 +08:00
|
|
|
//#include <boost/serialization/map.hpp>
|
2010-02-25 16:16:33 +08:00
|
|
|
#include <boost/foreach.hpp>
|
2010-10-09 06:04:47 +08:00
|
|
|
#include <boost/lambda/lambda.hpp>
|
|
|
|
|
#include <boost/bind.hpp>
|
|
|
|
|
#include <boost/numeric/ublas/matrix_proxy.hpp>
|
|
|
|
|
#include <boost/pool/pool_alloc.hpp>
|
2010-01-18 03:34:57 +08:00
|
|
|
#include <list>
|
2010-01-22 12:41:40 +08:00
|
|
|
#include <set>
|
2010-10-09 06:04:47 +08:00
|
|
|
#include <vector>
|
|
|
|
|
#include <map>
|
|
|
|
|
#include <deque>
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
#include <gtsam/base/types.h>
|
2010-08-20 01:23:19 +08:00
|
|
|
#include <gtsam/base/Matrix.h>
|
2010-10-09 06:04:47 +08:00
|
|
|
#include <gtsam/base/blockMatrices.h>
|
|
|
|
|
#include <gtsam/inference/Factor-inl.h>
|
|
|
|
|
#include <gtsam/inference/inference.h>
|
|
|
|
|
#include <gtsam/inference/VariableSlots.h>
|
2010-10-09 11:09:58 +08:00
|
|
|
#include <gtsam/linear/VectorValues.h>
|
2010-08-20 01:23:19 +08:00
|
|
|
#include <gtsam/linear/SharedDiagonal.h>
|
|
|
|
|
#include <gtsam/linear/GaussianConditional.h>
|
|
|
|
|
#include <gtsam/linear/GaussianBayesNet.h>
|
2009-08-22 06:23:24 +08:00
|
|
|
|
|
|
|
|
namespace gtsam {
|
|
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
class GaussianFactorGraph;
|
|
|
|
|
template<class VariableIndexStorage=VariableIndexStorage_vector> class GaussianVariableIndex;
|
2009-11-02 11:50:30 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
/** A map from key to dimension, useful in various contexts */
|
2010-10-12 05:14:35 +08:00
|
|
|
typedef std::map<Index, size_t> Dimensions;
|
2010-07-13 12:07:05 +08:00
|
|
|
|
2009-08-22 06:23:24 +08:00
|
|
|
/**
|
|
|
|
|
* Base Class for a linear factor.
|
2009-11-13 00:16:32 +08:00
|
|
|
* GaussianFactor is non-mutable (all methods const!).
|
2009-08-22 06:23:24 +08:00
|
|
|
* The factor value is exp(-0.5*||Ax-b||^2)
|
|
|
|
|
*/
|
2010-10-09 06:04:47 +08:00
|
|
|
class GaussianFactor: public Factor {
|
|
|
|
|
|
2009-08-22 06:23:24 +08:00
|
|
|
public:
|
|
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
typedef GaussianConditional Conditional;
|
2009-11-13 00:16:32 +08:00
|
|
|
typedef boost::shared_ptr<GaussianFactor> shared_ptr;
|
2010-10-09 06:04:47 +08:00
|
|
|
typedef boost::numeric::ublas::matrix<double, boost::numeric::ublas::column_major> matrix_type;
|
|
|
|
|
typedef VerticalBlockView<matrix_type> ab_type;
|
2009-08-22 06:23:24 +08:00
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
2010-01-23 01:36:57 +08:00
|
|
|
SharedDiagonal model_; // Gaussian noise model with diagonal covariance matrix
|
2010-10-09 06:04:47 +08:00
|
|
|
std::vector<size_t> firstNonzeroBlocks_;
|
|
|
|
|
matrix_type matrix_;
|
|
|
|
|
ab_type Ab_;
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2009-10-23 01:23:24 +08:00
|
|
|
public:
|
|
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
/** Copy constructor */
|
|
|
|
|
GaussianFactor(const GaussianFactor& gf);
|
|
|
|
|
|
|
|
|
|
/** default constructor for I/O */
|
|
|
|
|
GaussianFactor();
|
2009-08-22 06:23:24 +08:00
|
|
|
|
|
|
|
|
/** Construct Null factor */
|
2010-02-26 11:20:15 +08:00
|
|
|
GaussianFactor(const Vector& b_in);
|
2009-08-22 06:23:24 +08:00
|
|
|
|
|
|
|
|
/** Construct unary factor */
|
2010-10-12 05:14:35 +08:00
|
|
|
GaussianFactor(Index i1, const Matrix& A1,
|
2010-02-26 11:20:15 +08:00
|
|
|
const Vector& b, const SharedDiagonal& model);
|
2009-12-11 12:59:05 +08:00
|
|
|
|
2009-08-22 06:23:24 +08:00
|
|
|
/** Construct binary factor */
|
2010-10-12 05:14:35 +08:00
|
|
|
GaussianFactor(Index i1, const Matrix& A1,
|
|
|
|
|
Index i2, const Matrix& A2,
|
2010-02-26 11:20:15 +08:00
|
|
|
const Vector& b, const SharedDiagonal& model);
|
2010-01-20 08:26:49 +08:00
|
|
|
|
2009-08-22 06:23:24 +08:00
|
|
|
/** Construct ternary factor */
|
2010-10-12 05:14:35 +08:00
|
|
|
GaussianFactor(Index i1, const Matrix& A1, Index i2,
|
|
|
|
|
const Matrix& A2, Index i3, const Matrix& A3,
|
2010-02-26 11:20:15 +08:00
|
|
|
const Vector& b, const SharedDiagonal& model);
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2009-10-22 22:27:03 +08:00
|
|
|
/** Construct an n-ary factor */
|
2010-10-12 05:14:35 +08:00
|
|
|
GaussianFactor(const std::vector<std::pair<Index, Matrix> > &terms,
|
2010-02-26 11:20:15 +08:00
|
|
|
const Vector &b, const SharedDiagonal& model);
|
2009-10-22 22:27:03 +08:00
|
|
|
|
2010-10-12 05:14:35 +08:00
|
|
|
GaussianFactor(const std::list<std::pair<Index, Matrix> > &terms,
|
2010-02-26 11:20:15 +08:00
|
|
|
const Vector &b, const SharedDiagonal& model);
|
2010-02-25 16:16:33 +08:00
|
|
|
|
2009-08-22 06:23:24 +08:00
|
|
|
/** Construct from Conditional Gaussian */
|
2010-10-09 06:04:47 +08:00
|
|
|
GaussianFactor(const GaussianConditional& cg);
|
2009-10-23 01:23:24 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
// /** Constructor that combines a set of factors */
|
|
|
|
|
// GaussianFactor(const std::vector<shared_ptr> & factors);
|
2009-10-23 01:23:24 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
// Implementing Testable interface
|
2009-10-23 01:23:24 +08:00
|
|
|
void print(const std::string& s = "") const;
|
2010-10-09 06:04:47 +08:00
|
|
|
bool equals(const GaussianFactor& lf, double tol = 1e-9) const;
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2010-10-09 11:09:58 +08:00
|
|
|
Vector unweighted_error(const VectorValues& c) const; /** (A*x-b) */
|
|
|
|
|
Vector error_vector(const VectorValues& c) const; /** (A*x-b)/sigma */
|
|
|
|
|
double error(const VectorValues& c) const; /** 0.5*(A*x-b)'*D*(A*x-b) */
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
/** Check if the factor contains no information, i.e. zero rows. This does
|
|
|
|
|
* not necessarily mean that the factor involves no variables (to check for
|
|
|
|
|
* involving no variables use keys().empty()).
|
|
|
|
|
*/
|
|
|
|
|
bool empty() const { return Ab_.size1() == 0;}
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
/** Get a view of the r.h.s. vector b */
|
|
|
|
|
ab_type::const_column_type getb() const { return Ab_.column(size(), 0); }
|
|
|
|
|
ab_type::column_type getb() { return Ab_.column(size(), 0); }
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
/** Get a view of the A matrix for the variable pointed to be the given key iterator */
|
|
|
|
|
ab_type::const_block_type getA(const_iterator variable) const { return Ab_(variable - keys_.begin()); }
|
|
|
|
|
ab_type::block_type getA(iterator variable) { return Ab_(variable - keys_.begin()); }
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
/** Return the dimension of the variable pointed to by the given key iterator
|
|
|
|
|
* todo: Remove this in favor of keeping track of dimensions with variables?
|
|
|
|
|
*/
|
|
|
|
|
size_t getDim(const_iterator variable) const { return Ab_(variable - keys_.begin()).size2(); }
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Permutes the GaussianFactor, but for efficiency requires the permutation
|
|
|
|
|
* to already be inverted. This acts just as a change-of-name for each
|
|
|
|
|
* variable. The order of the variables within the factor is not changed.
|
|
|
|
|
*/
|
|
|
|
|
void permuteWithInverse(const Permutation& inversePermutation);
|
|
|
|
|
|
|
|
|
|
/** Named constructor for combining a set of factors with pre-computed set of
|
|
|
|
|
* variables. */
|
|
|
|
|
template<class Storage>
|
|
|
|
|
static shared_ptr Combine(const GaussianFactorGraph& factorGraph,
|
|
|
|
|
const GaussianVariableIndex<Storage>& variableIndex, const std::vector<size_t>& factors,
|
2010-10-12 05:14:35 +08:00
|
|
|
const std::vector<Index>& variables, const std::vector<std::vector<size_t> >& variablePositions);
|
2010-10-09 06:04:47 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Named constructor for combining a set of factors with pre-computed set of
|
|
|
|
|
* variables.
|
|
|
|
|
*/
|
|
|
|
|
static shared_ptr Combine(const GaussianFactorGraph& factors, const VariableSlots& variableSlots);
|
2009-11-05 04:59:16 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
protected:
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
/** Protected mutable accessor for the r.h.s. b. */
|
2010-01-19 13:45:25 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
/** Internal debug check to make sure variables are sorted */
|
|
|
|
|
void checkSorted() const;
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
public:
|
2010-03-05 07:39:36 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
/** get a copy of sigmas */
|
|
|
|
|
const Vector& get_sigmas() const { return model_->sigmas(); }
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
/** get a copy of model */
|
|
|
|
|
const SharedDiagonal& get_model() const { return model_; }
|
2009-08-22 06:23:24 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* return the number of rows from the b vector
|
|
|
|
|
* @return a integer with the number of rows from the b vector
|
|
|
|
|
*/
|
2010-10-09 06:04:47 +08:00
|
|
|
size_t numberOfRows() const { return Ab_.size1(); }
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2010-01-31 11:33:53 +08:00
|
|
|
/** Return A*x */
|
2010-10-09 11:09:58 +08:00
|
|
|
Vector operator*(const VectorValues& x) const;
|
2009-12-27 20:13:31 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
// /** Return A'*e */
|
2010-10-09 11:09:58 +08:00
|
|
|
// VectorValues operator^(const Vector& e) const;
|
2009-12-27 20:13:31 +08:00
|
|
|
|
2010-01-31 11:33:53 +08:00
|
|
|
/** x += A'*e */
|
2010-10-09 11:09:58 +08:00
|
|
|
void transposeMultiplyAdd(double alpha, const Vector& e, VectorValues& x) const;
|
2010-01-31 11:33:53 +08:00
|
|
|
|
2009-08-22 06:23:24 +08:00
|
|
|
/**
|
|
|
|
|
* Return (dense) matrix associated with factor
|
|
|
|
|
* @param ordering of variables needed for matrix column order
|
2009-11-11 22:42:09 +08:00
|
|
|
* @param set weight to true to bake in the weights
|
2009-08-22 06:23:24 +08:00
|
|
|
*/
|
2010-10-09 06:04:47 +08:00
|
|
|
std::pair<Matrix, Vector> matrix(bool weight = true) const;
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2009-11-05 23:08:58 +08:00
|
|
|
/**
|
|
|
|
|
* Return (dense) matrix associated with factor
|
|
|
|
|
* The returned system is an augmented matrix: [A b]
|
|
|
|
|
* @param ordering of variables needed for matrix column order
|
2010-01-20 00:52:01 +08:00
|
|
|
* @param set weight to use whitening to bake in weights
|
2009-11-05 23:08:58 +08:00
|
|
|
*/
|
2010-10-09 06:04:47 +08:00
|
|
|
Matrix matrix_augmented(bool weight = true) const;
|
2009-11-05 23:08:58 +08:00
|
|
|
|
2009-11-06 13:43:03 +08:00
|
|
|
/**
|
|
|
|
|
* Return vectors i, j, and s to generate an m-by-n sparse matrix
|
|
|
|
|
* such that S(i(k),j(k)) = s(k), which can be given to MATLAB's sparse.
|
|
|
|
|
* As above, the standard deviations are baked into A and b
|
2009-12-12 14:18:29 +08:00
|
|
|
* @param first column index for each variable
|
2009-11-06 13:43:03 +08:00
|
|
|
*/
|
|
|
|
|
boost::tuple<std::list<int>, std::list<int>, std::list<double> >
|
2009-12-12 14:18:29 +08:00
|
|
|
sparse(const Dimensions& columnIndices) const;
|
2009-11-06 13:43:03 +08:00
|
|
|
|
2009-10-23 01:23:24 +08:00
|
|
|
/* ************************************************************************* */
|
|
|
|
|
// MUTABLE functions. FD:on the path to being eradicated
|
|
|
|
|
/* ************************************************************************* */
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
GaussianConditional::shared_ptr eliminateFirst();
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2010-10-12 08:14:50 +08:00
|
|
|
GaussianBayesNet::shared_ptr eliminate(size_t nrFrontals = 1);
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2010-10-09 06:04:47 +08:00
|
|
|
friend class GaussianFactorGraph;
|
|
|
|
|
friend class Inference;
|
2009-12-11 04:19:15 +08:00
|
|
|
|
2009-11-13 00:16:32 +08:00
|
|
|
}; // GaussianFactor
|
2009-10-23 01:23:24 +08:00
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
2009-08-22 06:23:24 +08:00
|
|
|
|
2009-10-27 21:33:44 +08:00
|
|
|
/**
|
|
|
|
|
* creates a C++ string a la "x3", "m768"
|
|
|
|
|
* @param c the base character
|
|
|
|
|
* @param index the integer to be added
|
|
|
|
|
* @return a C++ string
|
|
|
|
|
*/
|
|
|
|
|
std::string symbol(char c, int index);
|
|
|
|
|
|
2009-08-22 06:23:24 +08:00
|
|
|
} // namespace gtsam
|