Mercurial > hg > camir-aes2014
comparison toolboxes/FullBNT-1.0.7/bnt/inference/static/@jtree_inf_engine/jtree_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 = jtree_inf_engine(bnet, varargin) | |
2 % JTREE_INF_ENGINE Junction tree inference engine | |
3 % engine = jtree_inf_engine(bnet, ...) | |
4 % | |
5 % The following optional arguments can be specified in the form of name/value pairs: | |
6 % [default value in brackets] | |
7 % | |
8 % clusters - a cell array of sets of nodes we want to ensure are in the same clique (in addition to families) [ {} ] | |
9 % root - the root of the junction tree will be a clique that contains this set of nodes [N] | |
10 % stages - stages{t} is a set of nodes we want to eliminate before stages{t+1}, ... [ {1:N} ] | |
11 % | |
12 % e.g., engine = jtree_inf_engine(bnet, 'maximize', 1); | |
13 % | |
14 % For more details on the junction tree algorithm, see | |
15 % - "Probabilistic networks and expert systems", Cowell, Dawid, Lauritzen and Spiegelhalter, Springer, 1999 | |
16 % - "Inference in Belief Networks: A procedural guide", C. Huang and A. Darwiche, | |
17 % Intl. J. Approximate Reasoning, 15(3):225-263, 1996. | |
18 | |
19 | |
20 % set default params | |
21 N = length(bnet.dag); | |
22 clusters = {}; | |
23 root = N; | |
24 stages = { 1:N }; | |
25 maximize = 0; | |
26 | |
27 if nargin >= 2 | |
28 args = varargin; | |
29 nargs = length(args); | |
30 if ~isstr(args{1}) | |
31 error('the interface to jtree has changed; now, onodes is not allowed and all optional params must be passed by name') | |
32 end | |
33 for i=1:2:nargs | |
34 switch args{i}, | |
35 case 'clusters', clusters = args{i+1}; | |
36 case 'root', root = args{i+1}; | |
37 case 'stages', stages = args{i+1}; | |
38 case 'maximize', maximize = args{i+1}; | |
39 otherwise, | |
40 error(['invalid argument name ' args{i}]); | |
41 end | |
42 end | |
43 end | |
44 | |
45 engine = init_fields; | |
46 engine = class(engine, 'jtree_inf_engine', inf_engine(bnet)); | |
47 | |
48 engine.maximize = maximize; | |
49 | |
50 onodes = bnet.observed; | |
51 | |
52 %[engine.jtree, dummy, engine.cliques, B, w, elim_order, moral_edges, fill_in_edges, strong] = ... | |
53 % dag_to_jtree(bnet, onodes, stages, clusters); | |
54 | |
55 porder = determine_elim_constraints(bnet, onodes); | |
56 strong = ~isempty(porder); | |
57 ns = bnet.node_sizes(:); | |
58 ns(onodes) = 1; % observed nodes have only 1 possible value | |
59 [engine.jtree, root2, engine.cliques, B, w] = ... | |
60 graph_to_jtree(moralize(bnet.dag), ns, porder, stages, clusters); | |
61 | |
62 | |
63 engine.cliques_bitv = B; | |
64 engine.clique_weight = w; | |
65 C = length(engine.cliques); | |
66 engine.clpot = cell(1,C); | |
67 | |
68 % Compute the separators between connected cliques. | |
69 [is,js] = find(engine.jtree > 0); | |
70 engine.separator = cell(C,C); | |
71 for k=1:length(is) | |
72 i = is(k); j = js(k); | |
73 engine.separator{i,j} = find(B(i,:) & B(j,:)); % intersect(cliques{i}, cliques{j}); | |
74 end | |
75 | |
76 % A node can be a member of many cliques, but is assigned to exactly one, to avoid | |
77 % double-counting its CPD. We assign node i to clique c if c is the "lightest" clique that | |
78 % contains i's family, so it can accomodate its CPD. | |
79 | |
80 engine.clq_ass_to_node = zeros(1, N); | |
81 for i=1:N | |
82 %c = clq_containing_nodes(engine, family(bnet.dag, i)); | |
83 clqs_containing_family = find(all(B(:,family(bnet.dag, i)), 2)); % all selected columns must be 1 | |
84 c = clqs_containing_family(argmin(w(clqs_containing_family))); | |
85 engine.clq_ass_to_node(i) = c; | |
86 end | |
87 | |
88 % Make the jtree rooted, so there is a fixed message passing order. | |
89 if strong | |
90 % the last clique is guaranteed to be a strong root | |
91 % engine.root_clq = length(engine.cliques); | |
92 | |
93 % --- 4/17/2010, by Wei Sun (George Mason University): | |
94 % It has been proved that the last clique is not necessary to be the | |
95 % strong root, instead, a clique called interface clique, that contains | |
96 % all discrete parents and at least one continuous node from a connected | |
97 % continuous component in a CLG, is guaranteed to be a strong root. | |
98 engine.root_clq = findroot(bnet, engine.cliques) ; | |
99 else | |
100 % jtree_dbn_inf_engine requires the root to contain the interface. | |
101 % This may conflict with the strong root requirement! *********** BUG ************* | |
102 engine.root_clq = clq_containing_nodes(engine, root); | |
103 if engine.root_clq <= 0 | |
104 error(['no clique contains ' num2str(root)]); | |
105 end | |
106 end | |
107 | |
108 [engine.jtree, engine.preorder, engine.postorder] = mk_rooted_tree(engine.jtree, engine.root_clq); | |
109 | |
110 % collect | |
111 engine.postorder_parents = cell(1,length(engine.postorder)); | |
112 for n=engine.postorder(:)' | |
113 engine.postorder_parents{n} = parents(engine.jtree, n); | |
114 end | |
115 % distribute | |
116 engine.preorder_children = cell(1,length(engine.preorder)); | |
117 for n=engine.preorder(:)' | |
118 engine.preorder_children{n} = children(engine.jtree, n); | |
119 end | |
120 | |
121 | |
122 | |
123 %%%%%%%% | |
124 | |
125 function engine = init_fields() | |
126 | |
127 engine.jtree = []; | |
128 engine.cliques = []; | |
129 engine.separator = []; | |
130 engine.cliques_bitv = []; | |
131 engine.clique_weight = []; | |
132 engine.clpot = []; | |
133 engine.clq_ass_to_node = []; | |
134 engine.root_clq = []; | |
135 engine.preorder = []; | |
136 engine.postorder = []; | |
137 engine.preorder_children = []; | |
138 engine.postorder_parents = []; | |
139 engine.maximize = []; | |
140 engine.evidence = []; | |
141 |