% Small example of a Markov Random Field
%
% 1 - 2
% |   |
% 4 - 3

N = 4;
arity = 2;
ns = arity*ones(1,4);

T = cell(1,N);
for i=1:N
  dom = wrap([i i+1], N);
  T{i} = mk_table(dom, ns(dom));
  T{i}.T = rand(arity, arity);
end

% soft evidence
% phi(i) = Pr(X(i), ev(i)) = Pr(ev(i) | X(i)) Prior(X(i))
ev = cell(1,N);
for i=1:N
  ev{i} = mk_table(i, ns(i));
  ev{i}.T = normalise(ones(1,ns(i))); % uniform by default (acts like hidden)
end
ev{1}.T = [0.3 0.7]; % node 1 is observed 

T1234 = mk_table([1 2 3 4], ns);
for i=1:N
  T1234 = multiply_by_table(T1234, T{i});
  T1234 = multiply_by_table(T1234, ev{i});
end

T1234 = normalize_table(T1234);
m = marginalize_table(T1234, 2);
T1 = m.T(:)';



dag = zeros(N,N);
uedges = zeros(N,N);
uedges(1,2) = 1; uedges(2,3) = 1; uedges(3,4) = 1; uedges(4,1) = 1;
uedges = mk_symmetric(uedges);
dnodes = 1:N;
eclass = 1:N;
onodes = [];
cliques = { [1 2], [2 3], [3 4], [4 1] };
bnet = mk_bnet(dag, ns, dnodes, 'jtree', eclass, onodes, uedges, cliques);

for i=1:N
  bnet.bnodes{i} = mk_input_node(bnet, i);
  bnet.clpot{i} = T{i};
end
bnet = compile_params(bnet);

obs = [];
vals = [];
soft_obs = 1;
soft_vals = { ev{1}.T };
[bnet, ll] = enter_evidence(bnet, obs, vals, soft_vals, soft_obs);
m = marginal_nodes(bnet, 2);
T2 = m.T(:)';

assert(approxeq(T1, T2))
