wolffd@0: function engine = enter_evidence(engine, evidence) wolffd@0: wolffd@0: doms = engine.fgraph.doms; wolffd@0: ndoms = length(doms); wolffd@0: ns = engine.fgraph.node_sizes; wolffd@0: obs = find(~isemptycell(evidence)); wolffd@0: cobs = myintersect(obs, engine.fgraph.cnodes); wolffd@0: dobs = myintersect(obs, engine.fgraph.dnodes); wolffd@0: ns(cobs) = 0; wolffd@0: ns(dobs) = 1; wolffd@0: wolffd@0: % recompute the weight of each domain now that we know what nodes are observed wolffd@0: for i=1:ndoms wolffd@0: engine.dom_weight(i) = prod(ns(engine.fgraph.doms{i})); wolffd@0: end wolffd@0: wolffd@0: % prime each local kernel with evidence (if any) wolffd@0: local_kernel = cell(1, ndoms); wolffd@0: for i=1:length(engine.fgraph.kernels_of_type) wolffd@0: u = engine.fgraph.kernels_of_type{i}; wolffd@0: local_kernel(u) = kernel_to_dpots(engine.fgraph.kernels{i}, evidence, engine.fgraph.domains_of_type{i}); wolffd@0: end wolffd@0: wolffd@0: % initialise all msgs to 1s wolffd@0: msg = cell(ndoms, ndoms); wolffd@0: for i=1:ndoms wolffd@0: nbrs = engine.fgraph.nbrs{i}; wolffd@0: for j=nbrs(:)' wolffd@0: dom = engine.fgraph.sepset{i,j}; wolffd@0: msg{i,j} = dpot(dom, ns(dom)); wolffd@0: end wolffd@0: end wolffd@0: 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 wolffd@0: for i=1:ndoms wolffd@0: prod_of_msg{i} = dpot(doms{i}, ns(doms{i})); wolffd@0: nbrs = engine.fgraph.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: end wolffd@0: wolffd@0: % each node computes its local belief wolffd@0: old_bel = bel; wolffd@0: for i=1:ndoms wolffd@0: bel{i} = normalize_pot(multiply_pots(prod_of_msg{i}, local_kernel{i})); 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: belT = get_params(bel{i}, 'table'); wolffd@0: old_belT = get_params(old_bel{i}, 'table'); wolffd@0: if ~approxeq(belT, old_belT, 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.fgraph.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: msg{i,j} = normalize_pot(marginalize_pot(temp, engine.fgraph.sepset{i,j})); wolffd@0: end wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: iter = iter + 1 wolffd@0: end wolffd@0: wolffd@0: engine.marginal_domains = bel; wolffd@0: %for i=1:ndoms wolffd@0: %engine.marginal_domains{i} = get_params(bel{i}, 'table'); wolffd@0: %end