function [bnet, loglik] = propagate_hmm(bnet, vals)
% PROPOGATE_HMM Call the HMM code to do inference.
% bnet = propogate_hmm(bnet, vals)
%
% We compute the posterior distribution on the hidden variables in each slice and each pair of
% slices, and store in bnet.hmm.one_slice_marginal{t}.T and bnet.hmm.two_slice_marginal{t}.T respectively.
% If bnet.filter_only = 1, we only run the forwards algorithm.

T = size(vals, 2);

O = length(bnet.observed_slice); % num. observables per slice
if O==1
  data = vals;
else
  % collapse the observables into a single value per slice
  data = zeros(1,T);
  obs = reshape(vals, [O T]);
  os = bnet.node_sizes_slice(bnet.observed_slice);
  for t=1:T
    data(t) = subv2ind(os, obs(:,t));
  end
end

B = mk_dhmm_obs_mat(data, bnet.hmm.obsmat, bnet.hmm.obsmat1);
if bnet.filter_only
  [bnet.hmm.alpha, bnet.hmm.xi, loglik] = forwards(bnet.hmm.prior, bnet.hmm.transmat, B);
  gamma = bnet.hmm.alpha;
else
  [bnet.hmm.alpha, bnet.hmm.beta, bnet.hmm.gamma, bnet.hmm.xi, loglik] = ...
      forwards_backwards(bnet.hmm.prior, bnet.hmm.transmat, B);
  gamma = bnet.hmm.gamma;
end
xi = bnet.hmm.xi;
  
% Decompose the matrices into factored form, and store in potential form.
hs = bnet.node_sizes_slice(bnet.hidden_slice);
if length(bnet.hmm.one_slice_marginal) ~= T
  bnet = mk_space_for_hmm_marginals(bnet, 1);
end
for t=1:T
  bnet.hmm.one_slice_marginal{t}.T = reshape(gamma(:,t), [hs]);
end
for t=1:T-1
  bnet.hmm.two_slice_marginal{t}.T = reshape(xi(:,:,t), [hs hs]);
end




