wolffd@0
|
1 function engine = enter_evidence(engine, evidence)
|
wolffd@0
|
2
|
wolffd@0
|
3 doms = engine.fgraph.doms;
|
wolffd@0
|
4 ndoms = length(doms);
|
wolffd@0
|
5 ns = engine.fgraph.node_sizes;
|
wolffd@0
|
6 obs = find(~isemptycell(evidence));
|
wolffd@0
|
7 cobs = myintersect(obs, engine.fgraph.cnodes);
|
wolffd@0
|
8 dobs = myintersect(obs, engine.fgraph.dnodes);
|
wolffd@0
|
9 ns(cobs) = 0;
|
wolffd@0
|
10 ns(dobs) = 1;
|
wolffd@0
|
11
|
wolffd@0
|
12 % recompute the weight of each domain now that we know what nodes are observed
|
wolffd@0
|
13 for i=1:ndoms
|
wolffd@0
|
14 engine.dom_weight(i) = prod(ns(engine.fgraph.doms{i}));
|
wolffd@0
|
15 end
|
wolffd@0
|
16
|
wolffd@0
|
17 % prime each local kernel with evidence (if any)
|
wolffd@0
|
18 local_kernel = cell(1, ndoms);
|
wolffd@0
|
19 for i=1:length(engine.fgraph.kernels_of_type)
|
wolffd@0
|
20 u = engine.fgraph.kernels_of_type{i};
|
wolffd@0
|
21 local_kernel(u) = kernel_to_dpots(engine.fgraph.kernels{i}, evidence, engine.fgraph.domains_of_type{i});
|
wolffd@0
|
22 end
|
wolffd@0
|
23
|
wolffd@0
|
24 % initialise all msgs to 1s
|
wolffd@0
|
25 msg = cell(ndoms, ndoms);
|
wolffd@0
|
26 for i=1:ndoms
|
wolffd@0
|
27 nbrs = engine.fgraph.nbrs{i};
|
wolffd@0
|
28 for j=nbrs(:)'
|
wolffd@0
|
29 dom = engine.fgraph.sepset{i,j};
|
wolffd@0
|
30 msg{i,j} = dpot(dom, ns(dom));
|
wolffd@0
|
31 end
|
wolffd@0
|
32 end
|
wolffd@0
|
33
|
wolffd@0
|
34 prod_of_msg = cell(1, ndoms);
|
wolffd@0
|
35 bel = cell(1, ndoms);
|
wolffd@0
|
36 old_bel = cell(1, ndoms);
|
wolffd@0
|
37
|
wolffd@0
|
38 converged = 0;
|
wolffd@0
|
39 iter = 1;
|
wolffd@0
|
40 while ~converged & (iter <= engine.max_iter)
|
wolffd@0
|
41
|
wolffd@0
|
42 % each node multiplies all its incoming msgs
|
wolffd@0
|
43 for i=1:ndoms
|
wolffd@0
|
44 prod_of_msg{i} = dpot(doms{i}, ns(doms{i}));
|
wolffd@0
|
45 nbrs = engine.fgraph.nbrs{i};
|
wolffd@0
|
46 for j=nbrs(:)'
|
wolffd@0
|
47 prod_of_msg{i} = multiply_by_pot(prod_of_msg{i}, msg{j,i});
|
wolffd@0
|
48 end
|
wolffd@0
|
49 end
|
wolffd@0
|
50
|
wolffd@0
|
51 % each node computes its local belief
|
wolffd@0
|
52 old_bel = bel;
|
wolffd@0
|
53 for i=1:ndoms
|
wolffd@0
|
54 bel{i} = normalize_pot(multiply_pots(prod_of_msg{i}, local_kernel{i}));
|
wolffd@0
|
55 end
|
wolffd@0
|
56
|
wolffd@0
|
57 % converged?
|
wolffd@0
|
58 if iter==1
|
wolffd@0
|
59 converged = 0;
|
wolffd@0
|
60 else
|
wolffd@0
|
61 converged = 1;
|
wolffd@0
|
62 for i=1:ndoms
|
wolffd@0
|
63 belT = get_params(bel{i}, 'table');
|
wolffd@0
|
64 old_belT = get_params(old_bel{i}, 'table');
|
wolffd@0
|
65 if ~approxeq(belT, old_belT, engine.tol)
|
wolffd@0
|
66 converged = 0;
|
wolffd@0
|
67 break;
|
wolffd@0
|
68 end
|
wolffd@0
|
69 end
|
wolffd@0
|
70 end
|
wolffd@0
|
71
|
wolffd@0
|
72 if ~converged
|
wolffd@0
|
73 old_msg = msg;
|
wolffd@0
|
74 % each node sends a msg to each of its neighbors
|
wolffd@0
|
75 for i=1:ndoms
|
wolffd@0
|
76 nbrs = engine.fgraph.nbrs{i};
|
wolffd@0
|
77 for j=nbrs(:)'
|
wolffd@0
|
78 % multiply all incoming msgs except from j
|
wolffd@0
|
79 temp = prod_of_msg{i};
|
wolffd@0
|
80 temp = divide_by_pot(temp, old_msg{j,i});
|
wolffd@0
|
81 % send msg from i to j
|
wolffd@0
|
82 temp = multiply_by_pot(temp, local_kernel{i});
|
wolffd@0
|
83 msg{i,j} = normalize_pot(marginalize_pot(temp, engine.fgraph.sepset{i,j}));
|
wolffd@0
|
84 end
|
wolffd@0
|
85 end
|
wolffd@0
|
86 end
|
wolffd@0
|
87
|
wolffd@0
|
88 iter = iter + 1
|
wolffd@0
|
89 end
|
wolffd@0
|
90
|
wolffd@0
|
91 engine.marginal_domains = bel;
|
wolffd@0
|
92 %for i=1:ndoms
|
wolffd@0
|
93 %engine.marginal_domains{i} = get_params(bel{i}, 'table');
|
wolffd@0
|
94 %end
|