Mercurial > hg > camir-aes2014
comparison toolboxes/FullBNT-1.0.7/bnt/inference/static/@stab_cond_gauss_inf_engine/stab_cond_gauss_inf_engine.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
1 function engine = stab_cond_gauss_inf_engine(bnet) | |
2 % STAB_COND_GAUSS_INF_ENGINE Junction tree using stable CG potentials | |
3 % engine = cond_gauss_inf_engine(bnet) | |
4 % | |
5 % This class was written by Shan Huang (shan.huang@intel.com) 2001 | |
6 % and fixed by Rainer Deventer deventer@informatik.uni-erlangen.de March 2003 | |
7 N = length(bnet.dag); | |
8 clusters = {}; | |
9 root = N; | |
10 stages = { 1:N }; | |
11 onodes = []; | |
12 engine = init_fields; | |
13 engine.evidence = []; | |
14 engine = class(engine, 'stab_cond_gauss_inf_engine', inf_engine(bnet)); | |
15 | |
16 ns = bnet.node_sizes(:); | |
17 ns(onodes) = 1; % observed nodes have only 1 possible value | |
18 | |
19 %[engine.jtree, dummy, engine.cliques, B, w, elim_order, moral_edges, fill_in_edges, strong] = ... | |
20 % dag_to_jtree(bnet, onodes, stages, clusters); | |
21 | |
22 | |
23 partial_order = determine_elim_constraints(bnet, onodes); | |
24 strong = ~isempty(partial_order); | |
25 stages = {}; | |
26 clusters = {}; | |
27 [engine.jtree, dummy_root, engine.cliques, B, w, elim_order] = | |
28 graph_to_jtree(moralize(bnet.dag), ns, partial_order, stages, clusters); | |
29 | |
30 | |
31 engine.cliques_bitv = B; | |
32 engine.clique_weight = w; | |
33 C = length(engine.cliques); | |
34 engine.clpot = cell(1,C); | |
35 | |
36 % A node can be a member of many cliques, but is assigned to exactly one, to avoid | |
37 % double-counting its CPD. We assign node i to clique c if c is the "lightest" clique that | |
38 % contains i's family, so it can accomodate its CPD. | |
39 | |
40 engine.clq_ass_to_node = zeros(1, N); | |
41 num_cliques = length(engine.cliques); | |
42 for i=1:N | |
43 clqs_containing_family = find(all(B(:,family(bnet.dag, i)), 2)); % all selected columns must be 1 | |
44 c = clqs_containing_family(argmin(w(clqs_containing_family))); | |
45 engine.clq_ass_to_node(i) = c; | |
46 end | |
47 | |
48 % Compute the separators between connected cliques. | |
49 [is,js] = find(engine.jtree > 0); | |
50 engine.separator = cell(num_cliques, num_cliques); | |
51 for k=1:length(is) | |
52 i = is(k); j = js(k); | |
53 engine.separator{i,j} = find(B(i,:) & B(j,:)); % intersect(cliques{i}, cliques{j}); | |
54 end | |
55 %keyboard; | |
56 engine.seppot = cell(C,C); | |
57 | |
58 pot_type = 'scg'; | |
59 check_for_cd_arcs([], bnet.cnodes, bnet.dag); | |
60 | |
61 % Make the jtree rooted, so there is a fixed message passing order. | |
62 if strong | |
63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
64 % Start the search for the strong root at the clique with the % | |
65 % highest number. % | |
66 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
67 root = length(engine.cliques); | |
68 root_found = 0; | |
69 | |
70 while ((~root_found) & (root >= 1)) | |
71 root_found = test_strong_root(engine.jtree,engine.cliques,bnet.dnodes,root); | |
72 if ~root_found | |
73 root = root - 1; | |
74 end | |
75 end | |
76 assert(root > 0) | |
77 engine.root = root; | |
78 % the last clique is guaranteed to be a strong root | |
79 %engine.root = length(engine.cliques); | |
80 else | |
81 % jtree_dbn_inf_engine requires the root to contain the interface. | |
82 % This may conflict with the strong root requirement! *********** BUG ************* | |
83 engine.root = clq_containing_nodes(engine, root); | |
84 if engine.root <= 0 | |
85 error(['no clique contains ' num2str(root)]); | |
86 end | |
87 end | |
88 | |
89 [engine.jtree, engine.preorder, engine.postorder] = mk_rooted_tree(engine.jtree, engine.root); | |
90 | |
91 % Evaluate CPDs with evidence, and convert to potentials | |
92 pot = cell(1, N); | |
93 inited = zeros(1, C); | |
94 clpot = cell(1, C); | |
95 evidence = cell(1, N); | |
96 for n=1:N | |
97 fam = family(bnet.dag, n); | |
98 e = bnet.equiv_class(n); | |
99 %pot{n} = CPD_to_scgpot(bnet.CPD{e}, fam, ns, bnet.cnodes, evidence); | |
100 pot{n} = convert_to_pot(bnet.CPD{e}, pot_type, fam(:), evidence); | |
101 cindex = engine.clq_ass_to_node(n); | |
102 if inited(cindex) | |
103 clpot{cindex} = direct_combine_pots(pot{n}, clpot{cindex}); | |
104 else | |
105 clpot{cindex} = pot{n}; | |
106 inited(cindex) = 1; | |
107 end | |
108 end | |
109 | |
110 for i=1:C | |
111 if inited(i) == 0 | |
112 clpot{i} = scgpot([], [], [], []); | |
113 end | |
114 end | |
115 | |
116 seppot = cell(C, C); | |
117 % separators are is not need to initialize | |
118 | |
119 % collect to root (node to parents) | |
120 % Unlike the HUGIN architecture the complements are stored in the cliques during COLLECT | |
121 % and the separators are not playing a specific role during this process | |
122 for n=engine.postorder(1:end-1) | |
123 for p=parents(engine.jtree, n) | |
124 if ~isempty(engine.separator{p,n}) | |
125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
126 % The empty case might happen for unlinked nodes, i.e. the DAG is not % | |
127 % a single tree, but a forest % | |
128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
129 [margpot, comppot] = complement_pot(clpot{n}, engine.separator{p,n}); | |
130 clpot{n} = comppot; | |
131 clpot{p} = combine_pots(clpot{p}, margpot); | |
132 end | |
133 end | |
134 end | |
135 | |
136 % distribute message from root | |
137 % We have not to store the weak clique marginals and keep the original complement potentials. | |
138 % This is a minor variation of HUGIN architecture. | |
139 temppot = clpot; | |
140 for n=engine.preorder | |
141 for c=children(engine.jtree, n) | |
142 seppot{n,c} = marginalize_pot(temppot{n}, engine.separator{n,c}); | |
143 temppot{c} = direct_combine_pots(temppot{c}, seppot{n,c}); | |
144 end | |
145 end | |
146 | |
147 engine.clpot = clpot; | |
148 engine.seppot = seppot; | |
149 | |
150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
151 % init_fields() % | |
152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
153 function engine = init_fields() | |
154 | |
155 engine.evidence = []; | |
156 engine.jtree = []; | |
157 engine.cliques = []; | |
158 engine.cliques_bitv = []; | |
159 engine.clique_weight = []; | |
160 engine.preorder = []; | |
161 engine.postorder = []; | |
162 engine.root = []; | |
163 engine.clq_ass_to_node = []; | |
164 engine.separator = []; | |
165 engine.clpot =[]; | |
166 engine.seppot = []; | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | |
178 |