function xi_t = combine_fwd_back(Bnet, alpha_t, beta_tp1, t, obs_nodes_t, vals_t, obs_nodes_tp1, vals_tp1)
% COMBINE_FWD_BACK Compute the posterior clique potentials for slices t and t+1 in a DBN.
% xi_t = combine_fwd_back(Bnet, alpha_t, beta_tp1, t, obs_nodes_t, vals_t, obs_nodes_tp1, vals_tp1)
%
% alpha_t{c} = scaled-alpha(c,t) for cluster c
% beta_tp1{c} = scaled-beta(c,t+1)
% xi_t{k} = potential on clique k in the jtree for slices t and t+1
%
% The method is a generalization of the following HMM equation:
% xi(i,j,t) = normalise( alpha(i,t) * transmat(i,j) * obsmat(j,t+1) * beta(j,t+1) )


% Add evidence to slices t and t+1
ss = Bnet.slice_size;
Bnet.observed_nodes = [obs_nodes_t(:)' obs_nodes_tp1(:)'+ss];
Bnet.values(obs_nodes_t) = vals_t;
Bnet.values(obs_nodes_tp1+ss) = vals_tp1;
Bnet = mk_ev_specific_pot(Bnet, Bnet.dbn.sl2_nodes_ass_to_cl);

% Add virtual evidence to slice t+1
num_clusters = length(Bnet.dbn.cluster);
for c=1:num_clusters
  cl = Bnet.dbn.cl_con_sl2_cluster(c);
  beta_tp1{c} = set_timeslice_belief(beta_tp1{c}, 2, Bnet);
  Bnet.jtree.clpot{cl} = multiply_by_potential(Bnet.jtree.clpot{cl}, beta_tp1{c});
end
% Add virtual evidence to slice t
for c=1:num_clusters
  cl = Bnet.dbn.cl_con_sl1_cluster(c);
  Bnet.jtree.clpot{cl} = multiply_by_potential(Bnet.jtree.clpot{cl}, alpha_t{c});
end

Bnet = collect_evidence(Bnet);
Bnet = distribute_evidence(Bnet);

num_cliques = length(Bnet.jtree.cliques);
xi_t = cell(1,num_cliques);
for c=1:num_cliques
  xi_t{c} = normalize_potential(Bnet.jtree.clpot{c});
  xi_t{c} = set_timeslice_belief(xi_t{c}, t, Bnet);
end

