wolffd@0: function [bel, niter] = parallel_protocol(engine, evidence, pot_type, local_kernel, msg) wolffd@0: wolffd@0: bnet = bnet_from_engine(engine); wolffd@0: ns = bnet.node_sizes; wolffd@0: onodes = find(~isemptycell(evidence)); wolffd@0: wolffd@0: ndoms = length(engine.gdl.doms); wolffd@0: prod_of_msg = cell(1, ndoms); wolffd@0: bel = cell(1, ndoms); wolffd@0: old_bel = cell(1, ndoms); wolffd@0: wolffd@0: converged = 0; wolffd@0: iter = 1; wolffd@0: while ~converged & (iter <= engine.max_iter) wolffd@0: wolffd@0: % each node multiplies all its incoming msgs and computes its local belief wolffd@0: old_bel = bel; wolffd@0: for i=1:ndoms wolffd@0: prod_of_msg{i} = mk_initial_pot(pot_type, engine.gdl.doms{i}, ns, bnet.cnodes, onodes); wolffd@0: nbrs = engine.gdl.nbrs{i}; wolffd@0: for j=nbrs(:)' wolffd@0: prod_of_msg{i} = multiply_by_pot(prod_of_msg{i}, msg{j,i}); wolffd@0: end wolffd@0: bel{i} = normalize_pot(multiply_by_pot(local_kernel{i}, prod_of_msg{i})); wolffd@0: end wolffd@0: wolffd@0: if ~isempty(engine.fid) wolffd@0: for i=1:ndoms wolffd@0: tmp = pot_to_marginal(bel{i}); wolffd@0: %fprintf(engine.fid, '%9.7f ', tmp.T(1)); wolffd@0: fprintf(engine.fid, '%9.7f ', tmp.U(1)); wolffd@0: end wolffd@0: %fprintf(engine.fid, ' U '); wolffd@0: %for i=1:ndoms wolffd@0: % tmp = pot_to_marginal(bel{i}); wolffd@0: % fprintf(engine.fid, '%9.7f ', tmp.U(1)); wolffd@0: %end wolffd@0: fprintf(engine.fid, '\n'); wolffd@0: end wolffd@0: wolffd@0: % converged? wolffd@0: if iter==1 wolffd@0: converged = 0; wolffd@0: else wolffd@0: converged = 1; wolffd@0: for i=1:ndoms wolffd@0: if ~approxeq_pot(bel{i}, old_bel{i}, engine.tol) wolffd@0: converged = 0; wolffd@0: break; wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: if ~converged wolffd@0: old_msg = msg; wolffd@0: % each node sends a msg to each of its neighbors wolffd@0: for i=1:ndoms wolffd@0: nbrs = engine.gdl.nbrs{i}; wolffd@0: for j=nbrs(:)' wolffd@0: % multiply all incoming msgs except from j wolffd@0: temp = prod_of_msg{i}; wolffd@0: temp = divide_by_pot(temp, old_msg{j,i}); wolffd@0: % send msg from i to j wolffd@0: temp = multiply_by_pot(temp, local_kernel{i}); wolffd@0: temp2 = marginalize_pot(temp, engine.gdl.sepset{i,j}, engine.maximize); wolffd@0: msg{i,j} = normalize_pot(temp2); wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: iter = iter + 1; wolffd@0: end wolffd@0: wolffd@0: wolffd@0: niter = iter-1; wolffd@0: wolffd@0: if 0 wolffd@0: for i=1:ndoms wolffd@0: prod_of_msg{i} = mk_initial_pot(pot_type, engine.gdl.doms{i}, ns, bnet.cnodes, onodes); wolffd@0: nbrs = engine.gdl.nbrs{i}; wolffd@0: for j=nbrs(:)' wolffd@0: prod_of_msg{i} = multiply_by_pot(prod_of_msg{i}, msg{j,i}); wolffd@0: end wolffd@0: bel{i} = normalize_pot(multiply_by_pot(local_kernel{i}, prod_of_msg{i})); wolffd@0: end wolffd@0: end