wolffd@0
|
1 function [engine, ll, niter] = enter_evidence(engine, evidence, varargin)
|
wolffd@0
|
2 % ENTER_EVIDENCE Propagate evidence using belief propagation
|
wolffd@0
|
3 % [engine, ll, niter] = enter_evidence(engine, evidence, ...)
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % The log-likelihood is not computed; ll = 0.
|
wolffd@0
|
6 % niter contains the number of iterations used (if engine.protocol = 'parallel')
|
wolffd@0
|
7 %
|
wolffd@0
|
8 % The following optional arguments can be specified in the form of name/value pairs:
|
wolffd@0
|
9 % [default value in brackets]
|
wolffd@0
|
10 %
|
wolffd@0
|
11 % maximize - 1 means use max-product, 0 means use sum-product [0]
|
wolffd@0
|
12 % exclude - list of nodes whose potential will not be included in the joint [ [] ]
|
wolffd@0
|
13 %
|
wolffd@0
|
14 % e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
|
wolffd@0
|
15
|
wolffd@0
|
16 ll = 0;
|
wolffd@0
|
17 exclude = [];
|
wolffd@0
|
18 maximize = 0;
|
wolffd@0
|
19
|
wolffd@0
|
20 if nargin >= 3
|
wolffd@0
|
21 args = varargin;
|
wolffd@0
|
22 nargs = length(args);
|
wolffd@0
|
23 for i=1:2:nargs
|
wolffd@0
|
24 switch args{i},
|
wolffd@0
|
25 case 'exclude', exclude = args{i+1};
|
wolffd@0
|
26 case 'maximize', maximize = args{i+1};
|
wolffd@0
|
27 otherwise,
|
wolffd@0
|
28 error(['invalid argument name ' args{i}]);
|
wolffd@0
|
29 end
|
wolffd@0
|
30 end
|
wolffd@0
|
31 end
|
wolffd@0
|
32
|
wolffd@0
|
33 engine.maximize = maximize;
|
wolffd@0
|
34
|
wolffd@0
|
35 if ~isempty(engine.filename)
|
wolffd@0
|
36 engine.fid = fopen(engine.filename, 'w');
|
wolffd@0
|
37 if engine.fid == 0
|
wolffd@0
|
38 error(['can''t open ' engine.filename]);
|
wolffd@0
|
39 end
|
wolffd@0
|
40 else
|
wolffd@0
|
41 engine.fid = [];
|
wolffd@0
|
42 end
|
wolffd@0
|
43
|
wolffd@0
|
44 gdl = engine.gdl;
|
wolffd@0
|
45 bnet = bnet_from_engine(engine);
|
wolffd@0
|
46
|
wolffd@0
|
47 ndoms = length(gdl.doms);
|
wolffd@0
|
48 ns = bnet.node_sizes;
|
wolffd@0
|
49 onodes = find(~isemptycell(evidence));
|
wolffd@0
|
50 pot_type = determine_pot_type(bnet, onodes);
|
wolffd@0
|
51
|
wolffd@0
|
52 % prime each local kernel with evidence (if any)
|
wolffd@0
|
53 local_kernel = cell(1, ndoms);
|
wolffd@0
|
54 for i=1:ndoms
|
wolffd@0
|
55 if myismember(i, exclude)
|
wolffd@0
|
56 local_kernel{i} = mk_initial_pot(pot_type, gdl.doms{i}, ns, bnet.cnodes, onodes);
|
wolffd@0
|
57 else
|
wolffd@0
|
58 e = bnet.equiv_class(i);
|
wolffd@0
|
59 local_kernel{i} = convert_to_pot(bnet.CPD{e}, pot_type, gdl.doms{i}(:), evidence);
|
wolffd@0
|
60 end
|
wolffd@0
|
61 end
|
wolffd@0
|
62
|
wolffd@0
|
63 % initialise all msgs to 1s
|
wolffd@0
|
64 msg = cell(ndoms, ndoms);
|
wolffd@0
|
65 for i=1:ndoms
|
wolffd@0
|
66 nbrs = gdl.nbrs{i};
|
wolffd@0
|
67 for j=nbrs(:)'
|
wolffd@0
|
68 dom = gdl.sepset{i,j};
|
wolffd@0
|
69 msg{i,j} = mk_initial_pot(pot_type, dom, ns, bnet.cnodes, onodes);
|
wolffd@0
|
70 end
|
wolffd@0
|
71 end
|
wolffd@0
|
72
|
wolffd@0
|
73 switch engine.protocol
|
wolffd@0
|
74 case 'parallel',
|
wolffd@0
|
75 [engine.marginal_domains, niter] = parallel_protocol(engine, evidence, pot_type, local_kernel, msg);
|
wolffd@0
|
76 case 'tree',
|
wolffd@0
|
77 engine.marginal_domains = serial_protocol(engine, evidence, pot_type, local_kernel, msg);
|
wolffd@0
|
78 niter = 1;
|
wolffd@0
|
79 end
|
wolffd@0
|
80 engine.niter = niter;
|
wolffd@0
|
81
|
wolffd@0
|
82 %fprintf('just finished %d iterations of belprop\n', niter);
|
wolffd@0
|
83
|
wolffd@0
|
84 if ~isempty(engine.filename)
|
wolffd@0
|
85 fclose(engine.fid);
|
wolffd@0
|
86 end
|