%ERTS_SMOOTH1 Extended Rauch-Tung-Striebel smoother % % Syntax: % [M,P,D] = ERTS_SMOOTH1(M,P,A,Q,[a,W,param,same_p]) % % In: % M - NxK matrix of K mean estimates from Unscented Kalman filter % P - NxNxK matrix of K state covariances from Unscented Kalman Filter % A - Derivative of a() with respect to state as % matrix, inline function, function handle or % name of function in form A(x,param) (optional, default eye()) % Q - Process noise of discrete model (optional, default zero) % a - Mean prediction E[a(x[k-1],q=0)] as vector, % inline function, function handle or name % of function in form a(x,param) (optional, default A(x)*X) % W - Derivative of a() with respect to noise q % as matrix, inline function, function handle % or name of function in form W(x,param) (optional, default identity) % param - Parameters of a. Parameters should be a single cell array, vector or a matrix % containing the same parameters for each step or if different parameters % are used on each step they must be a cell array of the format % { param_1, param_2, ...}, where param_x contains the parameters for % step x as a cell array, a vector or a matrix. (optional, default empty) % same_p - 1 if the same parameters should be % used on every time step (optional, default 1) % % % % Out: % K - Smoothed state mean sequence % P - Smoothed state covariance sequence % D - Smoother gain sequence % % Description: % Extended Rauch-Tung-Striebel smoother algorithm. Calculate % "smoothed" sequence from given Kalman filter output sequence by % conditioning all steps to all measurements. % % Example: % % See also: % EKF_PREDICT1, EKF_UPDATE1 % History: % 04.05.2007 JH Added the possibility to pass different parameters for a and h % for each step. % 2006 SS Initial version. % % Copyright (C) 2006 Simo Särkkä % Copyright (C) 2007 Jouni Hartikainen % % $Id: erts_smooth1.m 111 2007-09-04 12:09:23Z ssarkka $ % % This software is distributed under the GNU General Public % Licence (version 2 or later); please refer to the file % Licence.txt, included with the software, for details. function [M,P,D] = erts_smooth1(M,P,A,Q,a,W,param,same_p) % % Check which arguments are there % if nargin < 3 A = []; end if nargin < 4 Q = []; end if nargin < 5 a = []; end if nargin < 6 W = []; end if nargin < 7 param = []; end if nargin < 8 same_p = []; end % % Apply defaults % if isempty(A) A = eye(size(M,1)); end if isempty(Q) Q = zeros(size(M,1)); end if isempty(W) W = eye(size(M,1),size(Q,2)); end if isempty(same_p) same_p = 1; end % % Extend Q if NxN matrix % if size(Q,3)==1 Q = repmat(Q,[1 1 size(M,2)]); end % % Run the smoother % D = zeros(size(M,1),size(M,1),size(M,2)); for k=(size(M,2)-1):-1:1 if isempty(param) params = []; elseif same_p params = param; else params = param{k}; end % % Perform prediction % if isempty(a) m_pred = A*M(:,k); elseif isnumeric(a) m_pred = a; elseif isstr(a) | strcmp(class(a),'function_handle') m_pred = feval(a,M(:,k),params); else m_pred = a(M(:,k),params); end if isnumeric(A) F = A; elseif isstr(A) | strcmp(class(A),'function_handle') F = feval(A,M(:,k),params); else F = A(M(:,k),params); end if isnumeric(W) B = W; elseif isstr(W) | strcmp(class(W),'function_handle') B = feval(W,M(:,k),params); else B = W(M(:,k),params); end P_pred = F * P(:,:,k) * F' + B * Q(:,:,k) * B'; C = P(:,:,k) * F'; D(:,:,k) = C / P_pred; M(:,k) = M(:,k) + D(:,:,k) * (M(:,k+1) - m_pred); P(:,:,k) = P(:,:,k) + D(:,:,k) * (P(:,:,k+1) - P_pred) * D(:,:,k)'; end