about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine
diff options
context:
space:
mode:
Diffstat (limited to 'sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine')
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/initialize_engine.m65
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/README12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/clq_containing_nodes.m24
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/enter_evidence.m260
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_difclq_nodes.m55
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_nodes.m77
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_singleclq_nodes.m30
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/problems.txt76
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push.m38
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push_pot_toclique.m7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/stab_cond_gauss_inf_engine.m178
18 files changed, 840 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries
new file mode 100644
index 00000000..055aa4df
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries
@@ -0,0 +1,11 @@
+/README/1.1.1.1/Sun May 11 15:39:50 2003//
+/clq_containing_nodes.m/1.1.1.1/Wed May 29 11:59:46 2002//
+/enter_evidence.m/1.1.1.1/Wed Mar 12 10:38:00 2003//
+/marginal_difclq_nodes.m/1.1.1.1/Fri Feb 21 11:20:32 2003//
+/marginal_nodes.m/1.1.1.1/Fri Feb 21 11:13:10 2003//
+/marginal_singleclq_nodes.m/1.1.1.1/Wed Jan 29 11:23:58 2003//
+/problems.txt/1.1.1.1/Wed May 29 11:59:46 2002//
+/push.m/1.1.1.1/Mon Feb 10 15:38:04 2003//
+/push_pot_toclique.m/1.1.1.1/Wed May 29 11:59:46 2002//
+/stab_cond_gauss_inf_engine.m/1.1.1.1/Fri Mar 28 17:12:42 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Repository
new file mode 100644
index 00000000..849daef7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@stab_cond_gauss_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Entries
new file mode 100644
index 00000000..ce0c4813
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Entries
@@ -0,0 +1,2 @@
+/initialize_engine.m/1.1.1.1/Wed May 29 11:59:46 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Repository
new file mode 100644
index 00000000..eb292815
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@stab_cond_gauss_inf_engine/Old
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_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/@stab_cond_gauss_inf_engine/Old/initialize_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/initialize_engine.m
new file mode 100644
index 00000000..6fb51c2e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/initialize_engine.m
@@ -0,0 +1,65 @@
+function [engine, loglik] = initialize_engine(engine)
+%initialize
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes(:);
+N = length(bnet.dag);
+
+pot_type = 'scg'
+check_for_cd_arcs([], bnet.cnodes, bnet.dag);
+
+% Evaluate CPDs with evidence, and convert to potentials  
+pot = cell(1, N);
+C = length(engine.cliques);
+inited = zeros(1, C);
+clpot = cell(1, C);
+evidence = cell(1, N);
+for n=1:N
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n);
+  pot{n} = CPD_to_scgpot(bnet.CPD{e}, fam, ns, bnet.cnodes, evidence);
+  cindex = engine.clq_ass_to_node(n);
+  if inited(cindex)
+      %clpot{cindex} = direct_combine_pots(clpot{cindex}, pot{n});
+      clpot{cindex} = direct_combine_pots(pot{n}, clpot{cindex});
+  else
+      clpot{cindex} = pot{n};
+      inited(cindex) = 1;
+  end
+end
+
+for i=1:C
+    if inited(i) == 0
+        clpot{i} = scgpot([], [], [], []);
+    end
+end
+
+seppot = cell(C, C);
+% separators are is not need to initialize
+
+% collect to root (node to parents)
+for n=engine.postorder(1:end-1)
+  for p=parents(engine.jtree, n)
+      [margpot, comppot] = complement_pot(clpot{n}, engine.separator{p,n});
+      margpot = marginalize_pot(clpot{n}, engine.separator{p,n});
+      clpot{n} = comppot;
+      %seppot{p, n} = margpot;
+      clpot{p} = combine_pots(clpot{p}, margpot);
+      %clpot{p} = combine_pots(margpot, clpot{p});
+  end
+end
+
+temppot = clpot;
+%temppot = clpot{engine.root};
+for n=engine.preorder
+  for c=children(engine.jtree, n)
+    seppot{n,c} = marginalize_pot(temppot{n}, engine.separator{n,c});
+    %seppot{n,c} = marginalize_pot(clpot{n}, engine.separator{n,c});
+    %clpot{c} = direct_combine_pots(clpot{c}, seppot{n,c});
+    temppot{c} = direct_combine_pots(temppot{c}, seppot{n,c});
+  end
+end
+
+engine.clpot = clpot;
+engine.seppot = seppot;
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/README b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/README
new file mode 100644
index 00000000..e905e28c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/README
@@ -0,0 +1,12 @@
+% Stable conditional Gaussian inference
+% Originally written by Huang, Shan <shan.huang@intel.com> 2001
+% Fixed by Rainer Deventer 2003
+
+
+@techreport{Lauritzen99,
+  author = "S. Lauritzen and F. Jensen",
+  title = "Stable Local Computation with Conditional {G}aussian Distributions",
+  year = 1999,
+  number = "R-99-2014",
+  institution = "Dept. Math. Sciences, Aalborg Univ."
+}
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/clq_containing_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/clq_containing_nodes.m
new file mode 100644
index 00000000..c64d2bff
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/clq_containing_nodes.m
@@ -0,0 +1,24 @@
+function c = clq_containing_nodes(engine, nodes, fam)
+% CLQ_CONTAINING_NODES Find the lightest clique (if any) that contains the set of nodes
+% c = clq_containing_nodes(engine, nodes, family)
+%
+% If the optional 'family' argument is specified, it means nodes = family(nodes(end)).
+% (This is useful since clq_ass_to_node is not accessible to outsiders.)
+% Returns c=-1 if there is no such clique.
+
+if nargin < 3, fam = 0; else fam = 1; end
+
+if length(nodes)==1
+  c = engine.clq_ass_to_node(nodes(1));
+elseif fam
+  c = engine.clq_ass_to_node(nodes(end));
+else
+  B = engine.cliques_bitv;
+  w = engine.clique_weight;
+  clqs = find(all(B(:,nodes), 2)); % all selected columns must be 1
+  if isempty(clqs)
+    c = -1;
+  else
+    c = clqs(argmin(w(clqs)));     
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..4b02fc8f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/enter_evidence.m
@@ -0,0 +1,260 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE enter evidence to engine including discrete and continuous evidence
+% [engine, ll] = enter_evidence(engine, evidence)
+%
+% ll is always 0, which is wrong.
+
+if ~isempty(engine.evidence)
+    bnet = bnet_from_engine(engine);
+    engine = stab_cond_gauss_inf_engine(bnet);
+    engine.evidence = evidence;
+else
+    engine.evidence = evidence;
+    bnet = bnet_from_engine(engine);
+end
+
+engine.evidence = evidence;
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes(:);
+observed = ~isemptycell(evidence);
+onodes = find(observed);
+hnodes = find(isemptycell(evidence));
+cobs = myintersect(bnet.cnodes, onodes);
+dobs = myintersect(bnet.dnodes, onodes);
+
+engine = incorporate_dis_evidence(engine, dobs, evidence);
+l = length(cobs);
+for i = 1:l
+    node = cobs(i);
+    engine = incorporate_singleconts_evidence(engine, node, evidence);
+end
+clpot = engine.clpot;
+
+clq_num = length(engine.cliques);
+for n=engine.postorder(1:end-1)
+  for p=parents(engine.jtree, n)
+      [margpot, comppot] = complement_pot(clpot{n}, engine.separator{p,n});
+      clpot{n} = comppot;
+      clpot{p} = combine_pots(clpot{p}, margpot);
+  end
+end
+
+temppot = clpot;
+for n=engine.preorder
+  for c=children(engine.jtree, n)
+    seppot{n,c} = marginalize_pot(temppot{n}, engine.separator{n,c});
+    temppot{c} = direct_combine_pots(temppot{c}, seppot{n,c});
+  end
+end
+engine.clpot = clpot;
+engine.seppot = seppot;
+
+[pot,loglik]=normalize_pot(clpot{engine.root});
+
+%%%%%%%%%%%%%%%%%%
+function engine = incorporate_dis_evidence(engine, donodes, evidence)
+l = length(donodes);
+for i=donodes(:)'
+    node = i;
+    clqid = engine.clq_ass_to_node(node);
+    pot = struct(engine.clpot{clqid});
+    ns = zeros(1, max(pot.domain));
+    ns(pot.ddom) = pot.dsizes;
+    ns(pot.cheaddom) = pot.cheadsizes;
+    ns(pot.ctaildom) = pot.ctailsizes;
+    ddom = pot.ddom;
+    
+    potcarray = cell(1, pot.dsize);
+    for j =1:pot.dsize
+        tpotc = struct(pot.scgpotc{j});
+        potcarray{j} = scgcpot(tpotc.cheadsize, tpotc.ctailsize, 0, tpotc.A, tpotc.B, tpotc.C);
+    end
+    
+    if length(ns(ddom)) == 1
+        matrix = pot.scgpotc;
+    else
+        matrix = reshape(pot.scgpotc,ns(ddom)); 
+        potcarray = reshape(potcarray, ns(ddom));
+    end
+    
+    map = find_equiv_posns(node, ddom);
+    vals = cat(1, evidence{node});
+    index = mk_multi_index(length(ddom), map, vals);
+    potcarray(index{:}) = matrix(index{:});
+    potcarray = potcarray(:);
+    %keyboard;
+    engine.clpot{clqid} = scgpot(pot.ddom, pot.cheaddom, pot.ctaildom, ns, potcarray);
+end
+
+%%%%%%%%%%%%%%%%%%
+function engine = incorporate_singleconts_evidence(engine, node, evidence)
+%incorporate_singleconts_evidence incorporate evidence of 1 continuous node
+B = engine.cliques_bitv;
+clqs_containnode = find(all(B(:,node), 2)); % all selected columns must be 1
+% Every continuous node necessarily apears as head in exactly one clique,
+% which is the clique where it appears closest to the strong root. In all other
+% clique potentials where it appears, it must be a tail node.
+clq_ev_as_head = [];
+for i = clqs_containnode(:)'
+    pot = struct(engine.clpot{i});
+    if myismember(node, pot.cheaddom)
+        clq_ev_as_head = [clq_ev_as_head i];
+        break;
+    end
+end
+	       
+% If we will incorporate the evidence node which is head of a potential we must rearrange
+% the juntion tree by push operation until the tail of the include potential is empty
+if ~isempty(clq_ev_as_head)
+    assert(1 == length(clq_ev_as_head));
+    i = clq_ev_as_head;
+    pot = struct(engine.clpot{i});
+    while ~isempty(pot.ctaildom)
+        [engine, clqtoroot] = push(engine, i, node);
+        i = clqtoroot;
+        pot = struct(engine.clpot{i});
+    end
+    B = engine.cliques_bitv;
+    clqs_containnode = find(all(B(:,node), 2));
+end
+
+for i = clqs_containnode(:)'
+    pot = struct(engine.clpot{i});
+    if myismember(node, pot.cheaddom)
+        engine.clpot{i} = incoporate_evidence_headnode(engine.clpot{i}, node, evidence);
+    else
+        %assert(myismember(node, pot.ctaildom));
+        engine.clpot{i} = incoporate_evidence_tailnode(engine.clpot{i}, node, evidence);
+    end
+end
+
+%%%%%%%%%%%%%%%%%%
+function newscgpot = incoporate_evidence_tailnode(pot, node, evidence)
+%ENTER_EVIDENCE_TAILNODE enter the evidence of 1 tailnode of the scgpot
+newscgpot = pot;
+pot = struct(pot);
+%if isempty(pot.ctaildom)
+if ~myismember(node, pot.ctaildom)
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % In this case there is no real dependency of the head nodes %
+    % on the tail. The potential should be returned unchanged    %
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    return;
+end
+%newscgpot = scgpot([], [], [], []);
+assert(myismember(node, pot.ctaildom));
+ni = block(find_equiv_posns(node, pot.ctaildom), pot.ctailsizes);
+
+ctaildom = mysetdiff(pot.ctaildom, node);
+cheaddom = pot.cheaddom;
+ddom = pot.ddom;
+domain = mysetdiff(pot.domain, node);
+dsize = pot.dsize;
+ns = zeros(1, max(pot.domain));
+ns(pot.ddom) = pot.dsizes;
+ns(pot.cheaddom) = pot.cheadsizes;
+ns(pot.ctaildom) = pot.ctailsizes;
+cheadsizes = pot.cheadsizes;
+cheadsize = pot.cheadsize;
+ctailsizes = ns(ctaildom);
+ctailsize = sum(ns(ctaildom));
+
+potarray = cell(1, dsize);
+for i=1:dsize
+    potc = struct(pot.scgpotc{i});
+    B = potc.B;
+    A = potc.A + B(:, ni)*evidence{node};
+    B(:, ni) = [];
+    potarray{i} = scgcpot(cheadsize, ctailsize, potc.p, A, B, potc.C);
+end
+
+newscgpot = scgpot(ddom, cheaddom, ctaildom, ns, potarray);
+
+%%%%%%%%%%%%%%%%
+function newscgpot = incoporate_evidence_headnode(pot, node, evidence)
+%ENTER_EVIDENCE_HEADNODE 
+pot = struct(pot);
+y2 = evidence{node};
+assert(myismember(node, pot.cheaddom));
+assert(isempty(pot.ctaildom));
+ddom = pot.ddom;
+cheaddom = mysetdiff(pot.cheaddom, node);
+ctaildom = pot.ctaildom;
+dsize = pot.dsize;
+domain = mysetdiff(pot.domain, node);
+
+ns = zeros(1, max(pot.domain));
+ns(pot.ddom) = pot.dsizes;
+ns(pot.cheaddom) = pot.cheadsizes;
+ns(pot.ctaildom) = pot.ctailsizes;
+ctailsizes = ns(ctaildom);
+ctailsize = sum(ctailsizes);
+cheadsizes = ns(cheaddom);
+cheadsize = sum(cheadsizes);
+onodesize = ns(node);
+
+p = zeros(1,dsize);
+A1 = zeros(cheadsize, dsize);
+A2 = zeros(onodesize, dsize);
+C11 = zeros(cheadsize, cheadsize, dsize);
+C12 = zeros(cheadsize, onodesize, dsize);
+C21 = zeros(onodesize, cheadsize, dsize);
+C22 = zeros(onodesize, onodesize, dsize);
+ZM = zeros(onodesize, onodesize);
+
+n1i = block(find_equiv_posns(cheaddom, pot.cheaddom), pot.cheadsizes);
+n2i = block(find_equiv_posns(node, pot.cheaddom), pot.cheadsizes);
+
+indic = 0;
+for i=1:dsize
+    potc = struct(pot.scgpotc{i});
+    p(i) = potc.p;
+    if ~isempty(n1i)
+        A1(:,i) = potc.A(n1i);
+    end 
+    if ~isempty(n2i)
+        A2(:,i) = potc.A(n2i);
+    end
+    C11(:,:,i) = potc.C(n1i, n1i);
+    C12(:,:,i) = potc.C(n1i, n2i);
+    C21(:,:,i) = potc.C(n2i, n1i);
+    C22(:,:,i) = potc.C(n2i, n2i);
+    if isequal(0, C22(:,:,i)) & isequal(evidence{node}, A2(:, i))
+        indic = i;
+    end
+end
+
+np = zeros(1,dsize);
+nA = zeros(cheadsize, dsize);
+nC = zeros(cheadsize, cheadsize, dsize);
+
+if indic
+    np(:) = 0;
+    np(indic) = p(indic);
+    nA = A1;
+    nC = C11;
+else
+    for i=1:dsize
+        if isequal(0, C22(:,:,i))
+            p(i) = 0;
+            nA(:, i) = A1(:, i);
+            nC(:,:,i) = C11(:,:,i);
+        else
+            sq = (y2 - A2(:,i))' * inv(C22(:,:,i)) * (y2 - A2(:,i));
+            ex = exp(-0.5*sq);
+            %np(i) = p(i) * ex / ( (2 * pi)^(-onodesize/2) * sqrt(det(C22(:,:,i))) );
+            np(i) = p(i) * ex / ( (2 * pi)^(onodesize/2) * sqrt(det(C22(:,:,i))) );
+            nA(:,i) = A1(:,i) + C12(:,:,i) * inv(C22(:,:,i)) * (y2 - A2(:,i));
+            tmp1 = C12(:,:,i) * inv(C22(:,:,i)) * C21(:,:,i);
+            nC(:,:,i) = C11(:,:,i) - tmp1;
+        end
+    end
+end 
+
+scpot = cell(1, dsize);
+W = zeros(cheadsize,ctailsize);
+for i=1:dsize
+    scpot{i} = scgcpot(cheadsize, ctailsize, np(i), nA(:,i), W, nC(:,:,i));
+end
+ns(node) = 0;
+newscgpot = scgpot(ddom, cheaddom, ctaildom, ns, scpot);
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_difclq_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_difclq_nodes.m
new file mode 100644
index 00000000..e1cad6c7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_difclq_nodes.m
@@ -0,0 +1,55 @@
+function marginal = marginal_difclq_nodes(engine, query_nodes)
+% MARGINAL_DIFCLQ_NODES get the marginal distribution of nodes which is not in a single clique
+% marginal = marginal_difclq_nodes(engine, query_nodes)
+
+keyboard
+num_clique = length(engine.cliques);
+B = engine.cliques_bitv;
+clqs_containnodes = [];
+for i=1:length(query_nodes)
+    node = query_nodes(i);
+    tnodes = find(all(B(:, node), 2));
+    clqs_containnodes = myunion(clqs_containnodes, tnodes);
+end
+% get all cliques contains query nodes
+
+% get the minimal sub tree in junction which contains these cliques and the node closest to the root of jtree
+[subtree, nroot_node] = min_subtree_conti_nodes(engine.jtree, engine.root, clqs_containnodes);
+if ~mysubset(query_nodes, engine.cliques{nroot_node});
+    % if query nodes is not all memers of the clique closest to the root clique performe push operation
+    engine = push_tree(engine, subtree, query_nodes, nroot_node);
+end
+
+if ~(nroot_node == engine.root)
+    % if the clique closest to the root clique is not the root clique we must direct combine the 
+    % potential with the potential stored in separator toward to root
+    p = parents(engine.jtree, nroot_node);
+    tpot = direct_combine_pots(engine.clpot{nroot_node}, engine.seppot{p, nroot_node});
+else
+    tpot = engine.clpot{nroot_node};
+end
+
+pot = marginalize_pot(tpot, query_nodes);
+marginal = pot_to_marginal(pot);
+marginal.T = normalise(marginal.T);
+
+
+
+function engine = push_tree(engine, tree, query_nodes, inode)
+% PUSH_TREE recursive perform push opeartion on tree
+% engine = push_tree(engine, tree, query_nodes, inode)
+
+cs = children(tree, inode);
+for i = 1:length(cs)
+    node = cs(i);
+    push_tree(engine, tree, query_nodes, node);
+    push_dom = myintersect(engine.cliques{node}, query_nodes);
+    [engine, clqtoroot] = push(engine, node, push_dom);
+end
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..063c2439
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_nodes.m
@@ -0,0 +1,77 @@
+function marginal = marginal_nodes(engine, query, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (stab_cond_gauss)
+% marginal = marginal_nodes(engine, query, add_ev)
+%
+% 'query' must be a singleton set.
+% add_ev is an optional argument; if 1, we will "inflate" the marginal of observed nodes
+% to their original size, adding 0s to the positions which contradict the evidence
+
+if nargin < 3, add_ev = 0; end
+if isempty(engine.evidence)
+    hquery = query;  
+else   
+    hquery = [];
+    for i = query
+        if isempty(engine.evidence{i})
+        hquery = [hquery i];
+        end
+    end
+end
+
+bnet = bnet_from_engine(engine);
+
+nclq = length(engine.cliques);
+clique = 0;
+for i = 1:nclq
+  if mysubset(hquery, engine.cliques{i})
+    pot = struct(engine.clpot{i});
+    %if mysubset(hquery, pot.cheaddom) | mysubset(hquery, pot.ddom)
+    if mysubset(hquery, pot.domain)
+     clique = i;
+      break;
+    end
+  end
+end
+
+if isempty(hquery)
+     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+     % If all requested variables are observed, no query is necessary %
+     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+     marginal.mu = [];
+     marginal.Sigma = [];
+     marginal.T = 1.0;
+     marginal.domain = query;
+else
+    if clique == 0
+        marginal = marginal_difclq_nodes(engine, hquery);
+    else 
+        marginal = marginal_singleclq_nodes(engine, clique, hquery);
+    end
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % Change the format of output, so that it is identical to the %
+    % format obtained by the same request for the junction-tree   %
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    marginal.domain = query;
+    bnet = bnet_from_engine(engine);
+    dquery = myintersect(bnet.dnodes,hquery);
+    ns = bnet.node_sizes(dquery);
+    if length(ns) == 0
+    marginal.T = 1;
+    else
+        if length(ns) == 1
+            ns = [1 ns];
+        end
+        marginal.T = reshape(marginal.T,ns);
+    end
+end
+if add_ev
+  bnet = bnet_from_engine(engine);
+  %marginal = add_ev_to_dmarginal(marginal, engine.evidence, bnet.node_sizes);
+  marginal = add_evidence_to_gmarginal(marginal, engine.evidence, bnet.node_sizes, bnet.cnodes);
+end
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_singleclq_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_singleclq_nodes.m
new file mode 100644
index 00000000..d755617f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_singleclq_nodes.m
@@ -0,0 +1,30 @@
+function marginal = marginal_singleclq_nodes(engine, i, query)
+% MARGINAL_SINGLECLQ_NODES get the marginal distribution of nodes which is in a single clique
+% marginal = marginal_singleclq_nodes(engine, i, query)
+
+pot = struct(engine.clpot{i});
+if isempty(pot.ctaildom)
+    if i ~= engine.root
+        p = parents(engine.jtree, i);
+        tpot = direct_combine_pots(engine.clpot{i}, engine.seppot{p, i});
+    else
+        tpot = engine.clpot{i};
+    end
+    pot = marginalize_pot(tpot, query);
+    
+    marginal = pot_to_marginal(pot);
+    marginal.T = normalise(marginal.T);
+else
+    [engine, clqtoroot] = push(engine, i, query);
+    if clqtoroot == engine.root
+        tpot = engine.clpot{clqtoroot};
+    else
+        p = parents(engine.jtree, clqtoroot);
+        tpot = direct_combine_pots(engine.clpot{clqtoroot}, engine.seppot{p, clqtoroot});
+    end
+    pot = marginalize_pot(tpot, query);
+    
+    marginal = pot_to_marginal(pot);
+    marginal.T = normalise(marginal.T);
+end
+                
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/problems.txt b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/problems.txt
new file mode 100644
index 00000000..fa7c6be8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/problems.txt
@@ -0,0 +1,76 @@
+PROBLEMS WITH STAB_COND_GAUSS_INF_ENGINE
+
+
+- enter_evidence always returns ll=0
+  (I set ll=0 since it is not computed)
+
+- fails on scg_3node, probably because the engine needs to be
+re-initialized every time before enter_evidence is called, not just
+when the engine is constructed.
+
+??? Error using ==> assert
+assertion violated: 
+
+K>> dbstack
+dbstack
+> In /home/eecs/murphyk/matlab/BNT/HMM/assert.m at line 9
+  In /home/eecs/murphyk/matlab/BNT/examples/static/SCG/scg_3node.m at line 45
+
+
+
+- crashes on scg3
+
+Error in ==> /home/eecs/murphyk/matlab/BNT/inference/static/@stab_cond_gauss_inf_engine/stab_cond_gauss_inf_engine.m
+On line 77  ==>       clpot{cindex} = direct_combine_pots(pot{n}, clpot{cindex});
+
+K>> dbstack
+dbstack
+> In /home/eecs/murphyk/matlab/BNT/inference/static/@stab_cond_gauss_inf_engine/stab_cond_gauss_inf_engine.m at line 77
+  In /home/eecs/murphyk/matlab/BNT/examples/static/SCG/scg3.m at line 41
+K>> 
+
+
+
+
+
+- fails on scg1 and scg2
+
+Warning: One or more output arguments not assigned during call to 'min_subtree_conti_nodes (nearsest_node2)'.
+Warning in ==> /home/eecs/murphyk/matlab/BNT/graph/min_subtree_conti_nodes.m (nearsest_node2)
+On line 60  ==>     nea_node = nearsest_node2(tree, nodes, n);
+
+K>> dbstack
+dbstack
+> In /home/eecs/murphyk/matlab/BNT/graph/min_subtree_conti_nodes.m (nearsest_node2) at line 60
+  In /home/eecs/murphyk/matlab/BNT/graph/min_subtree_conti_nodes.m (nearest_node) at line 50
+  In /home/eecs/murphyk/matlab/BNT/graph/min_subtree_conti_nodes.m at line 11
+  In /home/eecs/murphyk/matlab/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_difclq_nodes.m at line 17
+  In /home/eecs/murphyk/matlab/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_nodes.m at line 23
+  In /home/eecs/murphyk/matlab/BNT/examples/static/SCG/scg1.m at line 42
+
+
+
+
+
+- This code fragment, from BNT/graph/min_subtree_conti_nodes, is clearly redundant
+
+function nea_node = nearest_node(tree, root, nodes)
+%get the nearest node to the root in the tree
+nea_node = nearsest_node2(tree, nodes, root);
+
+function nea_node = nearsest_node2(tree, nodes, inode)
+if myismember(inode, nodes)
+    nea_node = inode;
+    return;
+end
+cs = children(tree, inode);
+for i = 1:length(cs)
+    n = cs(i);
+    nea_node = nearsest_node2(tree, nodes, n);
+end
+    
+
+- Some names are badly chosen. 'nearsest' is a mis-spelling. 'min_subtree_conti_nodes' should be
+'min_subtree_containing_nodes' or 'min_subtree_con_nodes'.
+
+- In general, the code needs some heavy polishing.
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push.m
new file mode 100644
index 00000000..193bf722
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push.m
@@ -0,0 +1,38 @@
+function [engine, clqtoroot] = push(engine, clq, pushdom)
+%PUSH_POT push the variables in putshdom which is subset of clq to the clique toword the root and get new engine
+%pushdom is pushed variables set
+%clq is the index of the clique that pushdom belongs to
+
+clqdom = engine.cliques{clq};
+assert( mysubset(pushdom, clqdom));
+clqtoroot = parents(engine.jtree, clq);
+%sepdom = engine.separator{clq, clqtoroot};
+sepdom = engine.separator{clqtoroot, clq};
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Calculate the strong marginal of the union of pushdom and and the separatordomain and  %
+% the corresponding complement                                                           %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%[margpot, comppot] = complement_pot(engine.clpot{clq}, pushdom);
+newsepdom = myunion(pushdom,sepdom);
+[margpot,comppot] = complement_pot(engine.clpot{clq}, newsepdom);
+engine.clpot{clqtoroot} = direct_combine_pots(engine.clpot{clqtoroot}, margpot);
+engine.clpot{clq} = comppot;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Calculation of the new separator and separatorpotential of the junction tree %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+engine.seppot{clqtoroot, clq} = direct_combine_pots(engine.seppot{clqtoroot, clq}, margpot);
+engine.separator{clqtoroot, clq} = myunion(engine.separator{clqtoroot, clq}, pushdom);
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Add pushdomain to the clique towards the root %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
+engine.cliques{clqtoroot} = myunion(engine.cliques{clqtoroot}, pushdom);
+
+num_cliques = length(engine.cliques);
+B = sparse(num_cliques, 1);
+for i=1:num_cliques
+  B(i, engine.cliques{i}) = 1;
+end
+engine.cliques_bitv = B;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push_pot_toclique.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push_pot_toclique.m
new file mode 100644
index 00000000..4bcd0ed0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push_pot_toclique.m
@@ -0,0 +1,7 @@
+function engine = push_pot_toclique(engine, clqtarget, clq, nodes)
+% PUSH_POT push the variables in putshdom which is subset of clq to the target clique toword the root and get new engine
+% engine = push_pot_toclique(engine, clqtarget, clq, nodes)
+[engine, clqtoroot] = push_pot(engine, clq, nodes)
+while clqtoroot ~= clqtarget
+    [engine, clqtoroot] = push_pot(engine, clqtoroot, nodes)
+end
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/stab_cond_gauss_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/stab_cond_gauss_inf_engine.m
new file mode 100644
index 00000000..42c47c6a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/stab_cond_gauss_inf_engine.m
@@ -0,0 +1,178 @@
+function engine = stab_cond_gauss_inf_engine(bnet)
+% STAB_COND_GAUSS_INF_ENGINE Junction tree using stable CG potentials
+% engine = cond_gauss_inf_engine(bnet)
+% 
+% This class was written by Shan Huang (shan.huang@intel.com) 2001
+% and fixed by Rainer Deventer deventer@informatik.uni-erlangen.de March 2003
+N = length(bnet.dag);
+clusters = {};
+root = N;
+stages = { 1:N };
+onodes = [];
+engine = init_fields;
+engine.evidence = [];
+engine = class(engine, 'stab_cond_gauss_inf_engine', inf_engine(bnet));
+
+ns = bnet.node_sizes(:);
+ns(onodes) = 1; % observed nodes have only 1 possible value
+
+%[engine.jtree, dummy, engine.cliques, B, w, elim_order, moral_edges, fill_in_edges, strong] = ...
+%    dag_to_jtree(bnet, onodes, stages, clusters);
+
+
+partial_order = determine_elim_constraints(bnet, onodes);
+strong = ~isempty(partial_order);
+stages = {};
+clusters = {};
+[engine.jtree, dummy_root, engine.cliques, B, w, elim_order] = 
+    graph_to_jtree(moralize(bnet.dag), ns, partial_order, stages, clusters);
+
+    
+engine.cliques_bitv = B;
+engine.clique_weight = w;
+C = length(engine.cliques);
+engine.clpot = cell(1,C);
+
+% 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.
+
+engine.clq_ass_to_node = zeros(1, N);
+num_cliques = length(engine.cliques);
+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);
+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
+%keyboard;
+engine.seppot = cell(C,C);
+
+pot_type = 'scg';
+check_for_cd_arcs([], bnet.cnodes, bnet.dag);
+
+% Make the jtree rooted, so there is a fixed message passing order.
+if strong
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  % Start the search for the strong root at the clique with the  %
+  % highest number.                                              %
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  root = length(engine.cliques);
+  root_found = 0;
+  
+  while ((~root_found) & (root >= 1))
+      root_found = test_strong_root(engine.jtree,engine.cliques,bnet.dnodes,root);
+      if ~root_found
+          root = root - 1;
+      end
+  end
+  assert(root > 0)
+  engine.root = root;
+  % the last clique is guaranteed to be a strong root
+  %engine.root = length(engine.cliques);
+else
+  % jtree_dbn_inf_engine requires the root to contain the interface.
+  % This may conflict with the strong root requirement! *********** BUG *************
+  engine.root = clq_containing_nodes(engine, root);
+  if engine.root <= 0
+    error(['no clique contains ' num2str(root)]);
+  end
+end  
+
+[engine.jtree, engine.preorder, engine.postorder] = mk_rooted_tree(engine.jtree, engine.root);
+
+% Evaluate CPDs with evidence, and convert to potentials  
+pot = cell(1, N);
+inited = zeros(1, C);
+clpot = cell(1, C);
+evidence = cell(1, N);
+for n=1:N
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n);
+  %pot{n} = CPD_to_scgpot(bnet.CPD{e}, fam, ns, bnet.cnodes, evidence);
+  pot{n} = convert_to_pot(bnet.CPD{e}, pot_type, fam(:), evidence);
+  cindex = engine.clq_ass_to_node(n);
+  if inited(cindex)
+      clpot{cindex} = direct_combine_pots(pot{n}, clpot{cindex});
+  else
+      clpot{cindex} = pot{n};
+      inited(cindex) = 1;
+  end
+end
+
+for i=1:C
+    if inited(i) == 0
+        clpot{i} = scgpot([], [], [], []);
+    end
+end
+
+seppot = cell(C, C);
+% separators are is not need to initialize
+
+% collect to root (node to parents)
+% Unlike the HUGIN architecture the complements are stored in the cliques during COLLECT 
+% and the separators are not playing a specific role during this process
+for n=engine.postorder(1:end-1)
+  for p=parents(engine.jtree, n)
+    if ~isempty(engine.separator{p,n})
+      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+      % The empty case might happen for unlinked nodes, i.e. the DAG is not %
+      % a single tree, but a forest                                           %
+      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+      [margpot, comppot] = complement_pot(clpot{n}, engine.separator{p,n});
+      clpot{n} = comppot;
+      clpot{p} = combine_pots(clpot{p}, margpot);
+    end
+  end
+end
+
+% distribute message from root
+% We have not to store the weak clique marginals and keep the original complement potentials. 
+% This is a minor variation of HUGIN architecture.
+temppot = clpot;
+for n=engine.preorder
+  for c=children(engine.jtree, n)
+    seppot{n,c} = marginalize_pot(temppot{n}, engine.separator{n,c});
+    temppot{c} = direct_combine_pots(temppot{c}, seppot{n,c});
+  end
+end
+
+engine.clpot = clpot;
+engine.seppot = seppot;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% init_fields()                  %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+function engine = init_fields()
+
+engine.evidence = [];
+engine.jtree = [];
+engine.cliques = [];
+engine.cliques_bitv = [];
+engine.clique_weight = [];
+engine.preorder = [];
+engine.postorder = [];
+engine.root = []; 
+engine.clq_ass_to_node = [];
+engine.separator = [];
+engine.clpot =[];
+engine.seppot = [];
+
+
+
+
+
+
+
+
+
+
+
+