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 = [];