⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unsflt.cpp

📁 良好的代码实现
💻 CPP
字号:
/* * Bayes++ the Bayesian Filtering Library * Copyright (c) 2002 Michael Stevens * See accompanying Bayes++.htm for terms and conditions of use. * * $Header: /cvsroot/bayesclasses/Bayes++/BayesFilter/unsFlt.cpp,v 1.29.2.4 2005/01/15 11:24:32 mistevens Exp $ * $NoKeywords: $ *//* * Unscented Filter. */#include "unsFlt.hpp"#include "matSup.hpp"#include "models.hpp"#include <cmath>/* Filter namespace */namespace Bayesian_filter{	using namespace Bayesian_filter_matrix;Unscented_scheme::Unscented_scheme (std::size_t x_size, std::size_t z_initialsize) :		Kalman_state_filter(x_size), Functional_filter(),		XX(x_size, 2*x_size+1),		s(Empty), S(Empty), SI(Empty),		fXX(x_size, 2*x_size+1)/* * Initialise filter and set the size of things we know about */{	Unscented_scheme::x_size = x_size;	Unscented_scheme::XX_size = 2*x_size+1;	last_z_size = 0;	// Leave z_size dependants Empty if z_initialsize==0	observe_size (z_initialsize);}Unscented_scheme& Unscented_scheme::operator= (const Unscented_scheme& a)/* Optimise copy assignment to only copy filter state * Precond: matrix size conformance */{	Kalman_state_filter::operator=(a);	XX = a.XX;	return *this;}void Unscented_scheme::unscented (FM::ColMatrix& XX, const FM::Vec& x, const FM::SymMatrix& X, Float scale)/* * Generate the unscented point representing a distribution * Fails if scale is negative */{	UTriMatrix Sigma(x_size,x_size);						// Get a upper Cholesky factoriation	Float rcond = UCfactor(Sigma, X);	rclimit.check_PSD(rcond, "X not PSD");	Sigma *= std::sqrt(scale);						// Generate XX with the same sample Mean and Covar as before	column(XX,0) = x;	for (std::size_t c = 0; c < x_size; ++c) {		UTriMatrix::Column SigmaCol = column(Sigma,c);		column(XX,c+1) .assign (x  + SigmaCol);		column(XX,x_size+c+1) .assign (x - SigmaCol);	}}Unscented_scheme::Float Unscented_scheme::predict_Kappa (std::size_t size) const// Default Kappa for predict: state augmented with predict noise{	// Use the rule to minimise mean squared error of 4 order term	return Float(3-signed(size));}Unscented_scheme::Float Unscented_scheme::observe_Kappa (std::size_t size) const// Default Kappa for observation: state on its own{	// Use the rule to minimise mean squared error of 4 order term	return Float(3-signed(size));}void Unscented_scheme::init ()/* * Initialise state *  Pre : x,X *  Post: x,X is PSD */{						// Postconditions	if (!isPSD (X))		error (Numeric_exception("Initial X not PSD"));}void Unscented_scheme::init_XX ()/* * Initialise from unscented state *  Pre : XX, kappa *  Post: x,X is PSD */{	Float x_kappa = Float(x_size) + kappa;						// Mean of predicted distribution: x	noalias(x) = column(fXX,0) * kappa;	for (std::size_t i = 1; i < XX_size; ++i) {		noalias(x) += column(fXX,i) / Float(2); // ISSUE uBlas may not be able to promote integer 2	}	x /= x_kappa;						// Covariance of distribution: X							// Subtract mean from each point in fXX	for (std::size_t i = 0; i < XX_size; ++i) {		column(fXX,i).minus_assign (x);	}							// Center point, premult here by 2 for efficency    {		ColMatrix::Column fXX0 = column(fXX,0);		noalias(X) = FM::outer_prod(fXX0, fXX0);		X *= 2*kappa;	}							// Remaining unscented points	for (std::size_t i = 1; i < XX_size; ++i) {		ColMatrix::Column fXXi = column(fXX,i);		noalias(X) += FM::outer_prod(fXXi, fXXi);	}	X /= 2*x_kappa;}void Unscented_scheme::update ()/* * Update state *  Pre : x,X *  Post: x,X */{}void Unscented_scheme::update_XX (Float kappa)/* * Update unscented state *  Pre : x,X *  Post: x,X, XX, kappa */{	Unscented_scheme::kappa = kappa;	Float x_kappa = Float(x_size) + kappa;	unscented (XX, x, X, x_kappa);}// ISSUE GCC2.95 cannot link if these are localy defined in member function// Move them back into member functions for standard compilersnamespace {	class Adapted_zero_model : public Unscented_predict_model	{	public:		Adapted_zero_model(Functional_predict_model& fm) :			Unscented_predict_model(0),			fmodel(fm), zeroQ(0,0)		{}		const Vec& f(const Vec& x) const		{			return fmodel.fx(x);		}		const SymMatrix& Q(const FM::Vec& /*x*/) const		{			return zeroQ;		}	private:		Functional_predict_model& fmodel;		SymMatrix zeroQ;	};	class Adapted_model : public Unscented_predict_model	{	public:		Adapted_model(Addative_predict_model& am) :			Unscented_predict_model(am.G.size1()),			amodel(am), QGqG(am.G.size1(),am.G.size1())		// Q gets size from GqG'		{			RowMatrix temp (am.G.size1(), am.G.size1());			noalias(QGqG) = prod_SPD(am.G, am.q, temp);		}		const Vec& f(const Vec& x) const		{			return amodel.f(x);		}		const SymMatrix& Q(const FM::Vec& /*x*/) const		{			return QGqG;		}	private:		Addative_predict_model& amodel;		mutable SymMatrix QGqG;	};}//namespacevoid Unscented_scheme::predict (Functional_predict_model& f)/* * Adapt model by creating an Unscented predict with zero noise * ISSUE: A simple specialisation is possible, rather then this adapted implemenation */{	Adapted_zero_model adaptedmodel(f);	predict (adaptedmodel);}void Unscented_scheme::predict (Addative_predict_model& f)/* * Adapt model by creating an Unscented predict with addative noise *  Computes noise covariance Q = GqG' */{	Adapted_model adaptedmodel(f);	predict (adaptedmodel);}void Unscented_scheme::predict (Unscented_predict_model& f)/* * Predict forward *  Pre : x,X *  Post: x,X is PSD * Implementation uses specific model for fast unscented computation */{	const std::size_t XX_size = XX.size2();						// Create unscented distribution	kappa = predict_Kappa(x_size);	Float x_kappa = Float(x_size) + kappa;	unscented (XX, x, X, x_kappa);						// Predict points of XX using supplied predict model							// State covariance	for (std::size_t i = 0; i < XX_size; ++i) {		column(fXX,i).assign (f.f( column(XX,i) ));	}	init_XX ();						// Addative Noise Prediction, computed about center point	noalias(X) += f.Q( column(fXX,0) );}void Unscented_scheme::observe_size (std::size_t z_size)/* * Optimised dynamic observation sizing */{	if (z_size != last_z_size) {		last_z_size = z_size;		s.resize(z_size, false);		S.resize(z_size,z_size, false);		SI.resize(z_size,z_size, false);	}}Bayes_base::Float Unscented_scheme::observe (Uncorrelated_addative_observe_model& h, const FM::Vec& z)/* * Observation fusion *  Pre : x,X *  Post: x,X is PSD * * Uncorrelated noise * ISSUE: Simplified implemenation using uncorrelated noise equations */{	Adapted_Correlated_addative_observe_model hh(h);	return observe (hh, z);}Bayes_base::Float Unscented_scheme::observe (Correlated_addative_observe_model& h, const FM::Vec& z)/* * Observation fusion *  Pre : x,X *  Post: x,X is PSD */{	std::size_t z_size = z.size();	ColMatrix zXX (z_size, 2*x_size+1);	Vec zp(z_size);	SymMatrix Xzz(z_size,z_size);	Matrix Xxz(x_size,z_size);	Matrix W(x_size,z_size);	observe_size (z.size());	// Dynamic sizing						// Create unscented distribution	kappa = observe_Kappa(x_size);	Float x_kappa = Float(x_size) + kappa;	unscented (XX, x, X, x_kappa);						// Predict points of XX using supplied observation model	{		Vec zXXi(z_size), zXX0(z_size);		zXX0 = h.h( column(XX,0) );		column(zXX,0) = zXX0;		for (std::size_t i = 1; i < XX.size2(); ++i) {			zXXi = h.h( column(XX,i) );						// Normalise relative to zXX0			h.normalise (zXXi, zXX0);			column(zXX,i) = zXXi;		}	}						// Mean of predicted distribution: zp	noalias(zp) = column(zXX,0) * kappa;	for (std::size_t i = 1; i < zXX.size2(); ++i) {		noalias(zp) += column(zXX,i) / Float(2); // ISSUE uBlas may not be able to promote integer 2	}	zp /= x_kappa;						// Covariance of observation predict: Xzz							// Subtract mean from each point in zXX	for (std::size_t i = 0; i < XX_size; ++i) {		column(zXX,i).minus_assign (zp);	}							// Center point, premult here by 2 for efficency	{		ColMatrix::Column zXX0 = column(zXX,0);		noalias(Xzz) = FM::outer_prod(zXX0, zXX0);		Xzz *= 2*kappa;	}							// Remaining unscented points	for (std::size_t i = 1; i < zXX.size2(); ++i) {		ColMatrix::Column zXXi = column(zXX,i);		noalias(Xzz) += FM::outer_prod(zXXi, zXXi);	}	Xzz /= 2*x_kappa;						// Correlation of state with observation: Xxz							// Center point, premult here by 2 for efficency	{		noalias(Xxz) = FM::outer_prod(column(XX,0) - x, column(zXX,0));		Xxz *= 2*kappa;	}							// Remaining unscented points	for (std::size_t i = 1; i < zXX.size2(); ++i) {		noalias(Xxz) += FM::outer_prod(column(XX,i) - x, column(zXX,i));	}	Xxz /= 2* (Float(x_size) + kappa);						// Innovation covariance	S = Xzz;	noalias(S) += h.Z;						// Inverse innovation covariance	Float rcond = UdUinversePD (SI, S);	rclimit.check_PD(rcond, "S not PD in observe");						// Kalman gain	noalias(W) = prod(Xxz,SI);						// Normalised innovation	h.normalise(s = z, zp);	noalias(s) -= zp;						// Filter update	noalias(x) += prod(W,s);	RowMatrix WStemp(W.size1(), S.size2());	noalias(X) -= prod_SPD(W,S, WStemp);	return rcond;}}//namespace

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -