diff toolboxes/FullBNT-1.0.7/bnt/inference/dynamic/@cbk_inf_engine/junk @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolboxes/FullBNT-1.0.7/bnt/inference/dynamic/@cbk_inf_engine/junk	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,176 @@
+function engine = cbk_inf_engine(bnet, varargin)
+% Just the same as bk_inf_engine, but you can specify overlapping clusters.
+
+ss = length(bnet.intra);
+% set default params
+clusters = 'exact';
+
+if nargin >= 2
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'clusters',  clusters = args{i+1};
+     otherwise, error(['unrecognized argument ' args{i}])
+    end
+  end
+end
+
+if strcmp(clusters, 'exact')
+  %clusters = { compute_interface_nodes(bnet.intra, bnet.inter) };
+  clusters = { 1:ss };
+elseif strcmp(clusters, 'ff')
+  clusters = num2cell(1:ss);
+end
+
+
+% We need to insert the prior on the clusters in slice 1,
+% and extract the posterior on the clusters in slice 2.
+% We don't need to care about the separators, b/c they're subsets of the clusters.
+C = length(clusters);
+clusters2 = cell(1,2*C);
+clusters2(1:C) = clusters;
+for c=1:C
+  clusters2{c+C} = clusters{c} + ss;
+end
+
+onodes = bnet.observed;
+obs_nodes = [onodes(:) onodes(:)+ss];
+engine.sub_engine = jtree_inf_engine(bnet, 'clusters', clusters2);
+
+%FH >>>
+%Compute separators. 
+ns = bnet.node_sizes(:,1);
+ns(onodes) = 1;
+[clusters, separators] = build_jt(clusters, 1:length(ns), ns);
+S = length(separators);
+engine.separators = separators;
+
+%Compute size of clusters.
+cl_sizes = zeros(1,C);
+for c=1:C
+    cl_sizes(c) = prod(ns(clusters{c}));
+end
+
+%Assign separators to the smallest cluster subsuming them.
+engine.cluster_ass_to_separator = zeros(S, 1);
+for s=1:S
+    subsuming_clusters = [];
+    %find smaunk
+    
+    for c=1:C
+        if mysubset(separators{s}, clusters{c}) 
+            subsuming_clusters(end+1) = c;
+        end
+    end
+    c = argmin(cl_sizes(subsuming_clusters));
+    engine.cluster_ass_to_separator(s) = subsuming_clusters(c);
+end
+
+%<<< FH
+
+engine.clq_ass_to_cluster = zeros(C, 2);
+for c=1:C
+  engine.clq_ass_to_cluster(c,1) = clq_containing_nodes(engine.sub_engine, clusters{c});
+  engine.clq_ass_to_cluster(c,2) = clq_containing_nodes(engine.sub_engine, clusters{c}+ss);
+end
+engine.clusters = clusters;
+
+engine.clq_ass_to_node = zeros(ss, 2);
+for i=1:ss
+  engine.clq_ass_to_node(i, 1) = clq_containing_nodes(engine.sub_engine, i);
+  engine.clq_ass_to_node(i, 2) = clq_containing_nodes(engine.sub_engine, i+ss);
+end
+
+
+
+% Also create an engine just for slice 1
+bnet1 = mk_bnet(bnet.intra1, bnet.node_sizes_slice, 'discrete', myintersect(bnet.dnodes, 1:ss), ...
+		'equiv_class', bnet.equiv_class(:,1), 'observed', onodes);
+for i=1:max(bnet1.equiv_class)
+  bnet1.CPD{i} = bnet.CPD{i};
+end
+
+engine.sub_engine1 = jtree_inf_engine(bnet1, 'clusters', clusters);
+
+engine.clq_ass_to_cluster1 = zeros(1,C);
+for c=1:C
+  engine.clq_ass_to_cluster1(c) = clq_containing_nodes(engine.sub_engine1, clusters{c});
+end
+
+engine.clq_ass_to_node1 = zeros(1, ss);
+for i=1:ss
+  engine.clq_ass_to_node1(i) = clq_containing_nodes(engine.sub_engine1, i);
+end
+
+engine.clpot = []; % this is where we store the results between enter_evidence and marginal_nodes
+engine.filter = [];
+engine.maximize = [];
+engine.T = [];
+
+engine.bel = [];
+engine.bel_clpot = [];
+engine.slice1 = [];
+%engine.pot_type = 'cg';
+% hack for online inference so we can cope with hidden Gaussians and discrete
+% it will not affect the pot type used in enter_evidence
+engine.pot_type = determine_pot_type(bnet, onodes);
+
+engine = class(engine, 'cbk_inf_engine', inf_engine(bnet));
+
+
+
+
+function [cliques, seps, jt_size] = build_jt(cliques, vars, ns)
+% BUILD_JT connects the cliques into a jtree, computes the respective 
+% separators and the size of the resulting jtree.
+%
+% [cliques, seps, jt_size] = build_jt(cliques, vars, ns)
+% ns(i) has to hold the size of vars(i)
+% vars has to be a superset of the union of cliques.
+
+%======== Compute the jtree with tool from BNT. This wants the vars to be 1:N.
+%==== Map from nodes to their indices.
+%disp('Computing jtree for cliques with vars and ns:');
+%cliques
+%vars
+%ns'
+
+inv_nodes = sparse(1,max(vars));
+N = length(vars);
+for i=1:N
+    inv_nodes(vars(i)) = i;
+end
+
+tmp_cliques = cell(1,length(cliques));
+%==== Temporarily map clique vars to their indices.
+for i=1:length(cliques)
+    tmp_cliques{i} = inv_nodes(cliques{i});
+end
+
+%=== Compute the jtree, using BNT.
+[jtree, root, B, w] = cliques_to_jtree(tmp_cliques, ns);
+
+
+%======== Now, compute the separators between connected cliques and their weights.
+seps = {};
+s_w = [];
+[is,js] = find(jtree > 0);
+for k=1:length(is)
+  i = is(k); j = js(k);
+  sep = vars(find(B(i,:) & B(j,:))); % intersect(cliques{i}, cliques{j});
+  if i>j | length(sep) == 0, continue; end;
+  seps{end+1} = sep;
+  s_w(end+1) = prod(ns(inv_nodes(seps{end})));
+end
+
+cl_w = sum(w);
+sep_w = sum(s_w);
+assert(cl_w > sep_w, 'Weight of cliques must be bigger than weight of separators');
+
+jt_size = cl_w + sep_w;
+% jt.cliques = cliques;
+% jt.seps = seps;
+% jt.size = jt_size;
+% jt.ns = ns';
+% jt;