wolffd@0
|
1 function [bel, niter] = parallel_protocol(engine, evidence, pot_type, local_kernel, msg)
|
wolffd@0
|
2
|
wolffd@0
|
3 bnet = bnet_from_engine(engine);
|
wolffd@0
|
4 ns = bnet.node_sizes;
|
wolffd@0
|
5 onodes = find(~isemptycell(evidence));
|
wolffd@0
|
6
|
wolffd@0
|
7 ndoms = length(engine.gdl.doms);
|
wolffd@0
|
8 prod_of_msg = cell(1, ndoms);
|
wolffd@0
|
9 bel = cell(1, ndoms);
|
wolffd@0
|
10 old_bel = cell(1, ndoms);
|
wolffd@0
|
11
|
wolffd@0
|
12 converged = 0;
|
wolffd@0
|
13 iter = 1;
|
wolffd@0
|
14 while ~converged & (iter <= engine.max_iter)
|
wolffd@0
|
15
|
wolffd@0
|
16 % each node multiplies all its incoming msgs and computes its local belief
|
wolffd@0
|
17 old_bel = bel;
|
wolffd@0
|
18 for i=1:ndoms
|
wolffd@0
|
19 prod_of_msg{i} = mk_initial_pot(pot_type, engine.gdl.doms{i}, ns, bnet.cnodes, onodes);
|
wolffd@0
|
20 nbrs = engine.gdl.nbrs{i};
|
wolffd@0
|
21 for j=nbrs(:)'
|
wolffd@0
|
22 prod_of_msg{i} = multiply_by_pot(prod_of_msg{i}, msg{j,i});
|
wolffd@0
|
23 end
|
wolffd@0
|
24 bel{i} = normalize_pot(multiply_by_pot(local_kernel{i}, prod_of_msg{i}));
|
wolffd@0
|
25 end
|
wolffd@0
|
26
|
wolffd@0
|
27 if ~isempty(engine.fid)
|
wolffd@0
|
28 for i=1:ndoms
|
wolffd@0
|
29 tmp = pot_to_marginal(bel{i});
|
wolffd@0
|
30 %fprintf(engine.fid, '%9.7f ', tmp.T(1));
|
wolffd@0
|
31 fprintf(engine.fid, '%9.7f ', tmp.U(1));
|
wolffd@0
|
32 end
|
wolffd@0
|
33 %fprintf(engine.fid, ' U ');
|
wolffd@0
|
34 %for i=1:ndoms
|
wolffd@0
|
35 % tmp = pot_to_marginal(bel{i});
|
wolffd@0
|
36 % fprintf(engine.fid, '%9.7f ', tmp.U(1));
|
wolffd@0
|
37 %end
|
wolffd@0
|
38 fprintf(engine.fid, '\n');
|
wolffd@0
|
39 end
|
wolffd@0
|
40
|
wolffd@0
|
41 % converged?
|
wolffd@0
|
42 if iter==1
|
wolffd@0
|
43 converged = 0;
|
wolffd@0
|
44 else
|
wolffd@0
|
45 converged = 1;
|
wolffd@0
|
46 for i=1:ndoms
|
wolffd@0
|
47 if ~approxeq_pot(bel{i}, old_bel{i}, engine.tol)
|
wolffd@0
|
48 converged = 0;
|
wolffd@0
|
49 break;
|
wolffd@0
|
50 end
|
wolffd@0
|
51 end
|
wolffd@0
|
52 end
|
wolffd@0
|
53
|
wolffd@0
|
54 if ~converged
|
wolffd@0
|
55 old_msg = msg;
|
wolffd@0
|
56 % each node sends a msg to each of its neighbors
|
wolffd@0
|
57 for i=1:ndoms
|
wolffd@0
|
58 nbrs = engine.gdl.nbrs{i};
|
wolffd@0
|
59 for j=nbrs(:)'
|
wolffd@0
|
60 % multiply all incoming msgs except from j
|
wolffd@0
|
61 temp = prod_of_msg{i};
|
wolffd@0
|
62 temp = divide_by_pot(temp, old_msg{j,i});
|
wolffd@0
|
63 % send msg from i to j
|
wolffd@0
|
64 temp = multiply_by_pot(temp, local_kernel{i});
|
wolffd@0
|
65 temp2 = marginalize_pot(temp, engine.gdl.sepset{i,j}, engine.maximize);
|
wolffd@0
|
66 msg{i,j} = normalize_pot(temp2);
|
wolffd@0
|
67 end
|
wolffd@0
|
68 end
|
wolffd@0
|
69 end
|
wolffd@0
|
70
|
wolffd@0
|
71 iter = iter + 1;
|
wolffd@0
|
72 end
|
wolffd@0
|
73
|
wolffd@0
|
74
|
wolffd@0
|
75 niter = iter-1;
|
wolffd@0
|
76
|
wolffd@0
|
77 if 0
|
wolffd@0
|
78 for i=1:ndoms
|
wolffd@0
|
79 prod_of_msg{i} = mk_initial_pot(pot_type, engine.gdl.doms{i}, ns, bnet.cnodes, onodes);
|
wolffd@0
|
80 nbrs = engine.gdl.nbrs{i};
|
wolffd@0
|
81 for j=nbrs(:)'
|
wolffd@0
|
82 prod_of_msg{i} = multiply_by_pot(prod_of_msg{i}, msg{j,i});
|
wolffd@0
|
83 end
|
wolffd@0
|
84 bel{i} = normalize_pot(multiply_by_pot(local_kernel{i}, prod_of_msg{i}));
|
wolffd@0
|
85 end
|
wolffd@0
|
86 end
|