Mercurial > hg > camir-aes2014
diff toolboxes/FullBNT-1.0.7/HMM/fixed_lag_smoother.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/FullBNT-1.0.7/HMM/fixed_lag_smoother.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,65 @@ +function [alpha, obslik, gamma, xi] = fixed_lag_smoother(d, alpha, obslik, obsvec, transmat, act) +% FIXED_LAG_SMOOTHER Computed smoothed posterior estimates within a window given previous filtered window. +% [alpha, obslik, gamma, xi] = fixed_lag_smoother(d, alpha, obslik, obsvec, transmat, act) +% +% d >= 2 is the desired window width. +% Actually, we use d=min(d, t0), where t0 is the current time. +% +% alpha(:, t0-d:t0-1) - length d window, excluding t0 (Columns indexed 1..d) +% obslik(:, t0-d:t0-1) - length d window +% obsvec - likelihood vector for current observation +% transmat - transition matrix +% If we specify the optional 'act' argument, transmat{a} should be a cell array, and +% act(t0-d:t0) - length d window, last column = current action +% +% Output: +% alpha(:, t0-d+1:t0) - last column = new filtered estimate +% obslik(:, t0-d+1:t0) - last column = obsvec +% xi(:, :, t0-d+1:t0-1) - 2 slice smoothed window +% gamma(:, t0-d+1:t0) - smoothed window +% +% As usual, we define (using T=d) +% alpha(i,t) = Pr(Q(t)=i | Y(1:t)) +% gamma(i,t) = Pr(Q(t)=i | Y(1:T)) +% xi(i,j,t) = Pr(Q(t)=i, Q(t+1)=j | Y(1:T)) +% +% obslik(i,t) = Pr(Y(t) | Q(t)=i) +% transmat{a}(i,j) = Pr(Q(t)=j | Q(t-1)=i, A(t)=a) + +[S n] = size(alpha); +d = min(d, n+1); +if d < 2 + error('must keep a window of length at least 2'); +end + +if ~exist('act') + act = ones(1, n+1); + transmat = { transmat }; +end + +% pluck out last d-1 components from the history +alpha = alpha(:, n-d+2:n); +obslik = obslik(:, n-d+2:n); + +% Extend window by 1 +t = d; +obslik(:,t) = obsvec; +xi = zeros(S, S, d-1); +xi(:,:,t-1) = normalise((alpha(:,t-1) * obslik(:,t)') .* transmat{act(t)}); +alpha(:,t) = sum(xi(:,:,t-1), 1)'; + +% Now smooth backwards inside the window +beta = ones(S, d); +T = d; +%fprintf('smooth from %d to 1, i.e., %d to %d\n', d, t0, t0-d+1); +gamma(:,T) = alpha(:,T); +for t=T-1:-1:1 + b = beta(:,t+1) .* obslik(:,t+1); + beta(:,t) = normalise(transmat{act(t)} * b); + gamma(:,t) = normalise(alpha(:,t) .* beta(:,t)); + xi(:,:,t) = normalise((transmat{act(t)} .* (alpha(:,t) * b'))); +end + + + +