about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine
diff options
context:
space:
mode:
Diffstat (limited to 'sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine')
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Entries3
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_family.m59
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_nodes_SS.m52
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/enter_evidence.m28
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/jtree_limid_inf_engine.m52
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_family.m52
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_nodes.m17
12 files changed, 272 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Entries
new file mode 100644
index 00000000..932cb3b4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Entries
@@ -0,0 +1,5 @@
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/jtree_limid_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D/Old////
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Repository
new file mode 100644
index 00000000..e8bf097c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@jtree_limid_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Entries
new file mode 100644
index 00000000..0b350b99
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Entries
@@ -0,0 +1,3 @@
+/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes_SS.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Repository
new file mode 100644
index 00000000..59988183
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@jtree_limid_inf_engine/Old
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_family.m
new file mode 100644
index 00000000..cd660ae4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_family.m
@@ -0,0 +1,59 @@
+function [m, pot] = marginal_family(engine, query)
+% MARGINAL_NODES Compute the marginal on the family of the specified node (jtree_limid)
+% [m, pot] = marginal_family(engine, query)
+%
+% query should be a single decision node, or [] (to compute global max expected utility)
+
+bnet = bnet_from_engine(engine);
+if isempty(query)
+  compute_meu = 1;
+  d = bnet.decision_nodes(1); % pick an arbitrary root to collect to
+  fam = []; % marginalize root pot down to a point
+else
+  compute_meu = 0;
+  d = query;
+  assert(myismember(d, bnet.decision_nodes));
+  fam = family(bnet.dag, d);
+end
+
+clpot = init_clpot(bnet, engine.cliques, engine.clq_ass_to_node, engine.evidence, engine.exclude);
+
+% collect to root (clique containing d) 
+C = length(engine.cliques);
+seppot = cell(C, C);    % separators are implicitely initialized to 1s
+for n=engine.postorder{d}(1:end-1)
+  for p=parents(engine.rooted_jtree{d}, n)
+    %clpot{p} = divide_by_pot(clpot{n}, seppot{p,n}); % dividing by 1 is redundant
+    seppot{p,n} = marginalize_pot(clpot{n}, engine.separator{p,n});
+    clpot{p} = multiply_by_pot(clpot{p}, seppot{p,n});
+  end
+end
+
+root = engine.clq_ass_to_node(d);
+assert(root == engine.postorder{d}(end));
+pot = marginalize_pot(clpot{root}, fam);
+m = pot_to_marginal(pot);
+
+%%%%%%%%%%%
+
+
+function clpot = init_clpot(bnet, cliques, clq_ass_to_node, evidence, exclude)
+
+% Set the clique potentials to all 1s
+C = length(cliques);
+clpot = cell(1, C);
+ns = bnet.node_sizes;
+for i=1:C
+  clpot{i} = upot(cliques{i}, ns(cliques{i}));
+end
+
+N = length(bnet.dag);
+nodes = mysetdiff(1:N, exclude);
+
+for n=nodes(:)'
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n);
+  c = clq_ass_to_node(n);
+  pot = convert_to_pot(bnet.CPD{e}, 'u', ns, fam, evidence);
+  clpot{c} = multiply_by_pot(clpot{c}, pot);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_nodes_SS.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_nodes_SS.m
new file mode 100644
index 00000000..2b6ff642
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_nodes_SS.m
@@ -0,0 +1,52 @@
+function [pot, MEU] = marginal_nodes(engine, d)
+
+C = length(cliques);
+%clpot = init_clpot(limid, cliques, d, clq_ass_to_node);
+clpot = init_clpot(limid, cliques, [], clq_ass_to_node);
+
+% collect to root
+if 1
+  % HUGIN
+  seppot = cell(C, C);    % separators are implicitely initialized to 1s
+  for n=postorder{di}(1:end-1)
+    for p=parents(rooted_jtree{di}, n)
+      %clpot{p} = divide_by_pot(clpot{n}, seppot{p,n}); % dividing by 1 is redundant
+      seppot{p,n} = marginalize_pot(clpot{n}, separator{p,n});
+      clpot{p} = multiply_by_pot(clpot{p}, seppot{p,n});
+    end
+  end
+else
+  % Shafer-Shenoy
+  msg = cell(C,C);
+  for n=postorder{di}(1:end-1)
+    for c=children(rooted_jtree{di}, n)
+      clpot{n} = multiply_by_pot(clpot{n}, msg{c,n});
+    end
+    p = parents(rooted_jtree{di}, n);
+    %msg{n,p} = marginalize_pot(clpot{n}, cliques{p});
+    msg{n,p} = marginalize_pot(clpot{n}, separator{n,p});
+  end
+  root = clq_ass_to_node(d);
+  n=postorder{di}(end);
+  assert(n == root);
+  for c=children(rooted_jtree{di}, n)
+    clpot{n} = multiply_by_pot(clpot{n}, msg{c,n});
+  end
+end	
+
+fam = family(limid.dag, d);
+pot = marginalize_pot(clpot{root}, fam);
+
+%%%%%%%
+jpot = compute_joint_pot_limid(limid);
+pot2 = marginalize_pot(jpot, fam);
+assert(approxeq_pot(pot, pot2))
+%%%%%%
+
+[policy, score] = extract_policy(pot);
+
+e = limid.equiv_class(d);
+limid.CPD{e} = set_params(limid.CPD{e}, 'policy', policy);
+
+  
+    
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..5d874803
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/enter_evidence.m
@@ -0,0 +1,28 @@
+function engine = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (jtree_limid)
+% engine = enter_evidence(engine, evidence, ...)
+%
+% evidence{i} = [] if if X(i) is hidden, and otherwise contains its observed value.
+%
+% The list below gives optional arguments [default value in brackets].      
+%
+% exclude - list of nodes whose potential will not be included in the joint [ [] ]
+%
+% e.g., engine = enter_evidence(engine, ev, 'exclude', 3)
+
+exclude = [];
+
+if nargin >= 3
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'exclude', exclude = args{i+1};
+     otherwise,
+      error(['invalid argument name ' args{i}]);
+    end
+  end
+end
+  
+engine.exclude = exclude;
+engine.evidence = evidence;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/jtree_limid_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/jtree_limid_inf_engine.m
new file mode 100644
index 00000000..83dd89ef
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/jtree_limid_inf_engine.m
@@ -0,0 +1,52 @@
+function engine = jtree_limid_inf_engine(bnet)
+% JTREE_LIMID_INF_ENGINE Make a junction tree engine for use by solve_limid
+% engine = jtree_limid_inf_engine(bnet)
+%
+% This engine is designed to compute marginals on decision nodes
+
+
+MG = moralize(bnet.dag);
+% We do not remove the utility nodes, because that complicates the book-keeping.
+% Leaving them in will not introduce any un-necessary triangulation arcs, because they are always leaves.
+% Also, since utility nodes have size 1, they do not increase the size of the potentials.
+
+ns = bnet.node_sizes;
+elim_order = best_first_elim_order(MG, ns);
+[MTG, engine.cliques]  = triangulate(MG, elim_order);
+[engine.jtree, root, B, w] = cliques_to_jtree(engine.cliques, ns);
+
+% A node can be a member of many cliques, but is assigned to exactly one, to avoid
+% double-counting its CPD. We assign node i to clique c if c is the "lightest" clique that
+% contains i's family, so it can accomodate its CPD.
+N = length(bnet.dag);
+engine.clq_ass_to_node = zeros(1, N);
+for i=1:N
+  clqs_containing_family = find(all(B(:,family(bnet.dag, i)), 2)); % all selected columns must be 1
+  c = clqs_containing_family(argmin(w(clqs_containing_family)));  
+  engine.clq_ass_to_node(i) = c; 
+end
+
+
+% Compute the separators between connected cliques.
+[is,js] = find(engine.jtree > 0);
+num_cliques = length(engine.cliques);
+engine.separator = cell(num_cliques, num_cliques);
+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
+
+
+% create |D| different rooted jtree's
+engine.rooted_jtree = cell(1, N);
+engine.preorder = cell(1, N);
+engine.postorder = cell(1, N);
+for d=bnet.decision_nodes(:)'
+  root = engine.clq_ass_to_node(d);
+  [engine.rooted_jtree{d}, engine.preorder{d}, engine.postorder{d}] = mk_rooted_tree(engine.jtree, root);
+end
+
+engine.exclude = [];
+engine.evidence = [];
+
+engine = class(engine, 'jtree_limid_inf_engine', inf_engine(bnet));
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_family.m
new file mode 100644
index 00000000..dd3bf95e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_family.m
@@ -0,0 +1,52 @@
+function [m, pot] = marginal_family(engine, query)
+% MARGINAL_NODES Compute the marginal on the family of the specified node (jtree_limid)
+% [m, pot] = marginal_family(engine, query)
+%
+% query should be a single decision node
+
+bnet = bnet_from_engine(engine);
+d = query;
+assert(myismember(d, bnet.decision_nodes));
+fam = family(bnet.dag, d);
+
+clpot = init_clpot(bnet, engine.cliques, engine.clq_ass_to_node, engine.evidence, engine.exclude);
+
+% collect to root (clique containing d) 
+C = length(engine.cliques);
+seppot = cell(C, C);    % separators are implicitely initialized to 1s
+for n=engine.postorder{d}(1:end-1)
+  for p=parents(engine.rooted_jtree{d}, n)
+    %clpot{p} = divide_by_pot(clpot{n}, seppot{p,n}); % dividing by 1 is redundant
+    seppot{p,n} = marginalize_pot(clpot{n}, engine.separator{p,n});
+    clpot{p} = multiply_by_pot(clpot{p}, seppot{p,n});
+  end
+end
+
+root = engine.clq_ass_to_node(d);
+assert(root == engine.postorder{d}(end));
+pot = marginalize_pot(clpot{root}, fam);
+m = pot_to_marginal(pot);
+
+%%%%%%%%%%%
+
+
+function clpot = init_clpot(bnet, cliques, clq_ass_to_node, evidence, exclude)
+
+% Set the clique potentials to all 1s
+C = length(cliques);
+clpot = cell(1, C);
+ns = bnet.node_sizes;
+for i=1:C
+  clpot{i} = upot(cliques{i}, ns(cliques{i}));
+end
+
+N = length(bnet.dag);
+nodes = mysetdiff(1:N, exclude);
+
+for n=nodes(:)'
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n);
+  c = clq_ass_to_node(n);
+  pot = convert_to_pot(bnet.CPD{e}, 'u', fam(:), evidence);
+  clpot{c} = multiply_by_pot(clpot{c}, pot);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..d3700270
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_nodes.m
@@ -0,0 +1,17 @@
+function [m, pot] = marginal_nodes(engine, query)
+% MARGINAL_NODES Compute the marginal on the specified nodes (jtree_limid)
+% [m, pot] = marginal_nodes(engine, query)
+%
+% query should be a subset of a family of a decision node
+
+if isempty(query)
+  bnet = bnet_from_engine(engine);
+  d = bnet.decision_nodes(1); % pick an arbitrary decision node
+  [dummy, big_pot] = marginal_family(engine, d); 
+else
+  [dummy, big_pot] = marginal_family(engine, query);
+end
+pot = marginalize_pot(big_pot, query);
+m = pot_to_marginal(pot);
+
+