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;
|