wolffd@0: % Check that adding soft evidence to a hidden node is equivalent to evaluating its leaf CPD. wolffd@0: wolffd@0: % Make an HMM wolffd@0: T = 3; Q = 2; O = 2; cts_obs = 0; param_tying = 0; wolffd@0: bnet = mk_hmm_bnet(T, Q, O, cts_obs, param_tying); wolffd@0: N = 2*T; wolffd@0: onodes = bnet.observed; wolffd@0: hnodes = mysetdiff(1:N, onodes); wolffd@0: for i=1:N wolffd@0: bnet.CPD{i} = tabular_CPD(bnet, i); wolffd@0: end wolffd@0: wolffd@0: ev = sample_bnet(bnet); wolffd@0: evidence = cell(1,N); wolffd@0: evidence(onodes) = ev(onodes); wolffd@0: wolffd@0: engine = jtree_inf_engine(bnet); wolffd@0: wolffd@0: [engine, ll] = enter_evidence(engine, evidence); wolffd@0: query = 1; wolffd@0: m = marginal_nodes(engine, query); wolffd@0: wolffd@0: wolffd@0: % Make a Markov chain with the same backbone wolffd@0: bnet2 = mk_markov_chain_bnet(T, Q); wolffd@0: for i=1:T wolffd@0: S = struct(bnet.CPD{hnodes(i)}); % violate object privacy wolffd@0: bnet2.CPD{i} = tabular_CPD(bnet2, i, S.CPT); wolffd@0: end wolffd@0: wolffd@0: % Evaluate the observed leaves of the HMM wolffd@0: soft_ev = cell(1,T); wolffd@0: for i=1:T wolffd@0: S = struct(bnet.CPD{onodes(i)}); % violate object privacy wolffd@0: dist = S.CPT(:, evidence{onodes(i)}); wolffd@0: soft_ev{i} = dist; wolffd@0: end wolffd@0: wolffd@0: % Use the leaf potentials as soft evidence wolffd@0: engine2 = jtree_inf_engine(bnet2); wolffd@0: [engine2, ll2] = enter_evidence(engine2, cell(1,T), 'soft', soft_ev); wolffd@0: m2 = marginal_nodes(engine2, query); wolffd@0: wolffd@0: assert(approxeq(m2.T, m.T)) wolffd@0: assert(approxeq(ll2, ll)) wolffd@0: wolffd@0: wolffd@0: wolffd@0: % marginal on node 1 without evidence wolffd@0: [engine2, ll2] = enter_evidence(engine2, cell(1,T)); wolffd@0: m2 = marginal_nodes(engine2, 1); wolffd@0: wolffd@0: % add soft evidence wolffd@0: soft_ev=cell(1,T); wolffd@0: soft_ev{1}=[0.7 0.3]; wolffd@0: [engine2, ll2] = enter_evidence(engine2, cell(1,T), 'soft', soft_ev); wolffd@0: m3 = marginal_nodes(engine2, 1); wolffd@0: wolffd@0: assert(approxeq(normalise(m2.T .* [0.7 0.3]'), m3.T)) wolffd@0: