annotate toolboxes/FullBNT-1.0.7/bnt/inference/static/@belprop_inf_engine/Old/enter_evidence.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
rev   line source
wolffd@0 1 function engine = enter_evidence(engine, evidence)
wolffd@0 2
wolffd@0 3 doms = engine.fg.doms;
wolffd@0 4 ndoms = length(doms);
wolffd@0 5 ns = engine.fg.node_sizes;
wolffd@0 6 obs = find(~isemptycell(evidence));
wolffd@0 7 cobs = myintersect(obs, engine.fg.cnodes);
wolffd@0 8 dobs = myintersect(obs, engine.fg.dnodes);
wolffd@0 9 ns(cobs) = 0;
wolffd@0 10 ns(dobs) = 1;
wolffd@0 11
wolffd@0 12 % prime each local kernel with evidence (if any)
wolffd@0 13 local_kernel = cell(1, ndoms);
wolffd@0 14 for i=1:length(engine.fg.kernels_of_type)
wolffd@0 15 u = engine.fg.kernels_of_type{i};
wolffd@0 16 local_kernel(u) = kernel_to_dpots(engine.fg.kernels{i}, evidence, engine.fg.domains_of_type{i});
wolffd@0 17 end
wolffd@0 18
wolffd@0 19 % initialise all msgs to 1s
wolffd@0 20 nedges = engine.fg.nedges;
wolffd@0 21 msg = cell(1, nedges);
wolffd@0 22 for i=1:nedges
wolffd@0 23 msg{i} = dpot(engine.fg.sepset{i}, ns(engine.fg.sepset{i}));
wolffd@0 24 end
wolffd@0 25
wolffd@0 26 prod_of_msg = cell(1, ndoms);
wolffd@0 27 bel = cell(1, ndoms);
wolffd@0 28 old_bel = cell(1, ndoms);
wolffd@0 29
wolffd@0 30 converged = 0;
wolffd@0 31 iter = 1;
wolffd@0 32 while ~converged & (iter <= engine.max_iter)
wolffd@0 33
wolffd@0 34 % each node multiplies all its incoming msgs
wolffd@0 35 for i=1:ndoms
wolffd@0 36 prod_of_msg{i} = dpot(doms{i}, ns(doms{i}));
wolffd@0 37 nbrs = engine.fg.nbrs{i};
wolffd@0 38 for j=1:length(nbrs)
wolffd@0 39 ndx = engine.fg.edge_ndx(j,i);
wolffd@0 40 prod_of_msg{i} = multiply_by_pot(prod_of_msg{i}, msg{ndx});
wolffd@0 41 end
wolffd@0 42 end
wolffd@0 43 old_msg = msg;
wolffd@0 44
wolffd@0 45 % each node computes its local belief
wolffd@0 46 for i=1:ndoms
wolffd@0 47 bel{i} = normalize_pot(multiply_pots(prod_of_msg{i}, local_kernel{i}));
wolffd@0 48 end
wolffd@0 49
wolffd@0 50 % converged?
wolffd@0 51 converged = 1;
wolffd@0 52 for i=1:ndoms
wolffd@0 53 if ~approxeq(bel{i}, old_bel{i}, engine.tol)
wolffd@0 54 converged = 0;
wolffd@0 55 break;
wolffd@0 56 end
wolffd@0 57 end
wolffd@0 58
wolffd@0 59 if ~converged
wolffd@0 60 % each node sends a msg to each of its neighbors
wolffd@0 61 for i=1:ndoms
wolffd@0 62 nbrs = engine.fg.nbrs{i};
wolffd@0 63 for j=1:length(nbrs)
wolffd@0 64 % multiply all incoming msgs except from j
wolffd@0 65 temp = prod_of_msg{i};
wolffd@0 66 ndx = engine.fg.edge_ndx(j,i);
wolffd@0 67 temp = divide_by_pot(temp, old_msg{ndx});
wolffd@0 68 % send msg from i to j
wolffd@0 69 temp = multiply_by_pot(temp, local_kernel{i});
wolffd@0 70 ndx = engine.fg.edge_ndx(i,j);
wolffd@0 71 msg{ndx} = normalize_pot(marginalize_pot(temp, engine.fg.sepset{ndx}));
wolffd@0 72 end
wolffd@0 73 end
wolffd@0 74 end
wolffd@0 75
wolffd@0 76 iter = iter + 1;
wolffd@0 77 end
wolffd@0 78
wolffd@0 79
wolffd@0 80 engine.marginal = bel;