231 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			231 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
| /*
 | |
|  * NoiseModel.h
 | |
|  *
 | |
|  *  Created on: Jan 13, 2010
 | |
|  *      Author: Richard Roberts
 | |
|  *      Author: Frank Dellaert
 | |
|  */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <boost/shared_ptr.hpp>
 | |
| //#include "Testable.h" TODO
 | |
| #include "Vector.h"
 | |
| #include "Matrix.h"
 | |
| 
 | |
| namespace gtsam {
 | |
| 
 | |
|   /**
 | |
|    * NoiseModel is the abstract base class for all noise models.
 | |
|    *
 | |
|    * It must implement a 'whiten' function to normalize an error vector, and an
 | |
|    * 'unwhiten' function to unnormalize an error vector.
 | |
|    */
 | |
|   class NoiseModel /* TODO : public Testable<NoiseModel> */ {
 | |
| 
 | |
|   protected:
 | |
| 
 | |
|   	size_t dim_;
 | |
| 
 | |
|   public:
 | |
| 
 | |
|   	NoiseModel(size_t dim):dim_(dim) {}
 | |
|   	virtual ~NoiseModel() {}
 | |
| 
 | |
|     /**
 | |
|      * Whiten an error vector.
 | |
|      */
 | |
|     virtual Vector whiten(const Vector& v) const = 0;
 | |
| 
 | |
|     /**
 | |
|      * Unwhiten an error vector.
 | |
|      */
 | |
|     virtual Vector unwhiten(const Vector& v) const = 0;
 | |
|   };
 | |
| 
 | |
|   /**
 | |
| 	 * GaussianNoiseModel implements the mathematical model
 | |
| 	 *  |R*x|^2 = |y|^2 with R'*R=inv(Sigma)
 | |
| 	 * where
 | |
| 	 *   y = whiten(x) = R*x
 | |
| 	 *   x = unwhiten(x) = inv(R)*y
 | |
| 	 * as indeed
 | |
| 	 *   |y|^2 = y'*y = x'*R'*R*x
 | |
| 	 * Various derived classes are available that are more efficient.
 | |
| 	 */
 | |
| 	struct GaussianNoiseModel: public NoiseModel {
 | |
| 
 | |
| 	protected:
 | |
| 
 | |
| 		// TODO: store as boost upper-triangular or whatever is passed from above
 | |
| 		/* Matrix square root of information matrix (R) */
 | |
| 		Matrix sqrt_information_;
 | |
| 
 | |
| 		/** protected constructor takes square root information matrix */
 | |
| 		GaussianNoiseModel(const Matrix& sqrt_information) :
 | |
| 			NoiseModel(sqrt_information.size1()), sqrt_information_(sqrt_information) {
 | |
| 		}
 | |
| 
 | |
| 	public:
 | |
| 
 | |
| 		typedef boost::shared_ptr<GaussianNoiseModel> shared_ptr;
 | |
| 
 | |
|     /**
 | |
|      * A Gaussian noise model created by specifying a square root information matrix.
 | |
|      */
 | |
|     static shared_ptr SqrtInformation(const Matrix& R) {
 | |
|     	return shared_ptr(new GaussianNoiseModel(R));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * A Gaussian noise model created by specifying a covariance matrix.
 | |
|      */
 | |
|     static shared_ptr Covariance(const Matrix& Sigma) {
 | |
|     	return shared_ptr(new GaussianNoiseModel(inverse_square_root(Sigma)));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * A Gaussian noise model created by specifying an information matrix.
 | |
|      */
 | |
|     static shared_ptr Information(const Matrix& Q)  {
 | |
|     	return shared_ptr(new GaussianNoiseModel(square_root_positive(Q)));
 | |
|     }
 | |
| 
 | |
|     virtual Vector whiten(const Vector& v) const;
 | |
| 		virtual Vector unwhiten(const Vector& v) const;
 | |
| 
 | |
| 		/**
 | |
| 		 * Multiply a derivative with R (derivative of whiten)
 | |
| 		 * Equivalent to whitening each column of the input matrix.
 | |
| 		 */
 | |
| 		virtual Matrix Whiten(const Matrix& H) const;
 | |
| 
 | |
| 		/**
 | |
| 		 * In-place version
 | |
| 		 */
 | |
| 		virtual void WhitenInPlace(Matrix& H) const;
 | |
| 
 | |
| 		/**
 | |
| 		 * Return R itself, but note that Whiten(H) is cheaper than R*H
 | |
| 		 */
 | |
| 		const Matrix& R() const {
 | |
| 			return sqrt_information_;
 | |
| 		}
 | |
| 
 | |
| 	}; // GaussianNoiseModel
 | |
| 
 | |
| 	// FD: does not work, ambiguous overload :-(
 | |
|   // inline Vector operator*(const GaussianNoiseModel& R, const Vector& v) {return R.whiten(v);}
 | |
| 
 | |
|   /**
 | |
|    * A diagonal noise model implements a diagonal covariance matrix, with the
 | |
|    * elements of the diagonal specified in a Vector.  This class has no public
 | |
|    * constructors, instead, use the static constructor functions Sigmas etc...
 | |
|    */
 | |
|   class Diagonal : public GaussianNoiseModel {
 | |
|   protected:
 | |
| 
 | |
|   	/** sigmas and reciprocal */
 | |
|     Vector sigmas_, invsigmas_;
 | |
| 
 | |
|     /** protected constructor takes sigmas */
 | |
|     Diagonal(const Vector& sigmas);
 | |
| 
 | |
|   public:
 | |
| 
 | |
| 		typedef boost::shared_ptr<Diagonal> shared_ptr;
 | |
| 
 | |
|     /**
 | |
|      * A diagonal noise model created by specifying a Vector of sigmas, i.e.
 | |
|      * standard devations, the diagonal of the square root covariance matrix.
 | |
|      */
 | |
|     static shared_ptr Sigmas(const Vector& sigmas) {
 | |
|     	return shared_ptr(new Diagonal(sigmas));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * A diagonal noise model created by specifying a Vector of variances, i.e.
 | |
|      * i.e. the diagonal of the covariance matrix.
 | |
|      */
 | |
|     static shared_ptr Variances(const Vector& variances) {
 | |
|     	return shared_ptr(new Diagonal(esqrt(variances)));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * A diagonal noise model created by specifying a Vector of precisions, i.e.
 | |
|      * i.e. the diagonal of the information matrix, i.e., weights
 | |
|      */
 | |
|     static shared_ptr Precisions(const Vector& precisions) {
 | |
|     	return Variances(reciprocal(precisions));
 | |
|     }
 | |
| 
 | |
|     virtual Vector whiten(const Vector& v) const;
 | |
|     virtual Vector unwhiten(const Vector& v) const;
 | |
|   };
 | |
| 
 | |
|   /**
 | |
|    * An isotropic noise model corresponds to a scaled diagonal covariance
 | |
|    * To construct, use one of the static methods
 | |
|    */
 | |
|   class Isotropic : public Diagonal {
 | |
|   protected:
 | |
|     double sigma_, invsigma_;
 | |
| 
 | |
|     /** protected constructor takes sigma */
 | |
|     Isotropic(size_t dim, double sigma) :
 | |
| 			Diagonal(repeat(dim, sigma)),sigma_(sigma),invsigma_(1.0/sigma) {}
 | |
| 
 | |
|   public:
 | |
| 
 | |
| 		typedef boost::shared_ptr<Isotropic> shared_ptr;
 | |
| 
 | |
|     /**
 | |
|      * An isotropic noise model created by specifying a standard devation sigma
 | |
|      */
 | |
|     static shared_ptr Sigma(size_t dim, double sigma) {
 | |
|     	return shared_ptr(new Isotropic(dim, sigma));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * An isotropic noise model created by specifying a variance = sigma^2.
 | |
|      */
 | |
|     static shared_ptr Variance(size_t dim, double variance)  {
 | |
|     	return shared_ptr(new Isotropic(dim, sqrt(variance)));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * An isotropic noise model created by specifying a precision
 | |
|      */
 | |
|     static shared_ptr Precision(size_t dim, double precision)  {
 | |
|     	return Variance(dim, 1.0/precision);
 | |
|     }
 | |
| 
 | |
|     virtual Vector whiten(const Vector& v) const;
 | |
|     virtual Vector unwhiten(const Vector& v) const;
 | |
|   };
 | |
| 
 | |
|   /**
 | |
|    * UnitCovariance: i.i.d. unit-variance noise on all m dimensions.
 | |
|    */
 | |
|   class UnitCovariance : public Isotropic {
 | |
|   protected:
 | |
| 
 | |
|     UnitCovariance(size_t dim): Isotropic(dim,1.0) {}
 | |
| 
 | |
|   public:
 | |
| 
 | |
|     typedef boost::shared_ptr<UnitCovariance> shared_ptr;
 | |
| 
 | |
|     /**
 | |
|      * An isotropic noise model created by specifying a standard devation sigma
 | |
|      */
 | |
|     static shared_ptr Create(size_t dim);
 | |
| 
 | |
|     virtual Vector whiten(const Vector& v) const { return v; }
 | |
|     virtual Vector unwhiten(const Vector& v) const { return v; }
 | |
|     virtual Matrix Whiten(const Matrix& H) const { return H; }
 | |
| 	  virtual void WhitenInPlace(Matrix& H) const {}
 | |
|   };
 | |
| 
 | |
| }
 |