www.pudn.com > ConstrainedEM.zip > inf_engine_from_mnet.m
function engine = inf_engine_from_mnet(mnet,k,tree_flag) %, param ,maximize)
% original is jtree_inf_engine of BNT
% set default params
if nargin<3
tree_flag=0;
end
N = length(mnet);
engine = init_fields;
engine.mnet=mnet;
clusters = {};
root = N;
stages = { 1:N };
[engine.jtree, dummy, engine.cliques, B, w, elim_order ] = net_to_jtree(mnet ,k,tree_flag);
engine.cliques_bitv = B;
engine.clique_weight = w;
C = length(engine.cliques);
engine.clpot = cell(1,C);
engine.elim_order=elim_order;
% Compute the separators between connected cliques.
[is,js] = find(engine.jtree > 0);
engine.separator = cell(C,C);
for k=1:length(is)
i = is(k); j = js(k);
engine.separator{i,j} = find(B(i,:) & B(j,:)); % intersect(cliques{i}, cliques{j});
end
% A constraint is a factor of 2 variables and can be a member of many cliques, but
% is assigned to exactly one, to avoid double-counting its CPD. We assign constraint
% i to clique c if c is the "lightest" clique that contains i's variables.
% here i only assign the constraint factors, not the gaussian cpds.
[is js ]=find( triu(mnet)==1);
for k=1:length(is)
i=is(k);
j=js(k);
if mnet(i,j)==1
clqs_containing_const = find(all(B(:,[i j ]), 2)); % all selected columns must be 1
c = clqs_containing_const(argmin(w(clqs_containing_const)));
engine.clq_ass_to_const(i,j) = c;
end
end
% assign the simple cpd (1-d) of every node to a certain clique
engine.clq_ass_to_node = zeros(1, N);
for i=1:N
%c = clq_containing_nodes(engine, family(bnet.dag, i));
clqs_containing_i = find(B(:,i)==1);
c = clqs_containing_i(argmin(w(clqs_containing_i)));
engine.clq_ass_to_node(i) = c;
end
% make the jtree rooted, so there is a fixed message passing order.
engine.root_clq = my_clq_containing_nodes(engine, root);
if engine.root_clq <= 0
error(['no clique contains ' num2str(root)]);
end
[engine.jtree, engine.preorder, engine.postorder] = mk_rooted_tree(engine.jtree, engine.root_clq);
% collect
engine.postorder_parents = cell(1,length(engine.postorder));
for n=engine.postorder(:)'
engine.postorder_parents{n} = parents(engine.jtree, n);
end
% distribute
engine.preorder_children = cell(1,length(engine.preorder));
for n=engine.preorder(:)'
engine.preorder_children{n} = children(engine.jtree, n);
end
%%%%%%%%
function engine = init_fields()
engine.jtree = [];
engine.cliques = [];
engine.separator = [];
engine.cliques_bitv = [];
engine.clique_weight = [];
engine.clpot = [];
engine.clq_ass_to_node = [];
engine.root_clq = [];
engine.preorder = [];
engine.postorder = [];
engine.preorder_children = [];
engine.postorder_parents = [];
engine.maximize = [];
engine.evidence = [];