about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine
diff options
context:
space:
mode:
authorziejd22017-09-28 15:04:40 -0500
committerziejd22017-09-28 15:04:40 -0500
commit8070dc963753142bb86c4ed698d91fd623ed28e7 (patch)
treed0f6dd8fc46a49b819aa55c1a90faa14d8448883 /sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine
parent7cc31810d53176e805532b2789955f4eedbce6bb (diff)
downloadBNW-8070dc963753142bb86c4ed698d91fd623ed28e7.tar.gz
BNW using Octave instead of Matlab.
This version of BNW should perform the same as the original version. The only difference is that it uses Octave instead of Matlab when running BayesNet Toolbox during parameter learning.

I am calling this BNW_1.02. It can be accessed at:
compbio.uthsc.edu/BNW_1.02
Diffstat (limited to 'sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine')
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Entries10
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back.m27
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back1.m21
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/backT.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/enter_evidence.m22
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd.m47
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd1.m32
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/jtree_sparse_2TBN_inf_engine.m95
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_family.m12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_nodes.m32
12 files changed, 311 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Entries
new file mode 100644
index 00000000..14219dd2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Entries
@@ -0,0 +1,10 @@
+/back.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/back1.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/backT.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/fwd.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/fwd1.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/jtree_sparse_2TBN_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
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Repository
new file mode 100644
index 00000000..2c445be3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/online/@jtree_sparse_2TBN_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back.m
new file mode 100644
index 00000000..7f686d55
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back.m
@@ -0,0 +1,27 @@
+function b = back(engine, bfuture, f, t)
+
+if f.t ~= t
+  error('mixed up time stamps')
+end
+if t==1
+  b = back1(engine, bfuture, f, t);
+  return;
+end
+
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+int = engine.interface;
+D = engine.in_clq;
+C = engine.out_clq;
+phiD = marginalize_pot(bfuture.clpot{D}, int, engine.maximize);
+phiD = set_domain_pot(phiD, int+ss); % shift to slice 2
+phiC = marginalize_pot(f.clpot{C}, int+ss, engine.maximize);
+ratio = divide_by_pot(phiD, phiC);
+f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio);
+
+[b.clpot, seppot] = distribute_evidence(engine.jtree_engine, f.clpot, f.seppot);
+for c=1:length(b.clpot)
+  [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c});
+end
+b.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back1.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back1.m
new file mode 100644
index 00000000..a8587a72
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back1.m
@@ -0,0 +1,21 @@
+function b = back1(engine, bfuture, f, t)
+
+if t ~= 1
+  error('mixed up time stamps')
+end
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+int = engine.interface;
+D = engine.in_clq; % from J2
+C = engine.int_clq1; % from J1
+phiD = marginalize_pot(bfuture.clpot{D}, int, engine.maximize);
+phiC = marginalize_pot(f.clpot{C}, int, engine.maximize);
+ratio = divide_by_pot(phiD, phiC);
+f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio);
+
+[b.clpot, seppot] = distribute_evidence(engine.jtree_engine1, f.clpot, f.seppot);
+for c=1:length(b.clpot)
+  [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c});
+end
+b.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/backT.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/backT.m
new file mode 100644
index 00000000..7f7a1b42
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/backT.m
@@ -0,0 +1,11 @@
+function b = backT(engine, f, t)
+
+if t==1
+  [b.clpot, seppot] = distribute_evidence(engine.jtree_engine1, f.clpot, f.seppot);
+else
+  [b.clpot, seppot] = distribute_evidence(engine.jtree_engine, f.clpot, f.seppot);
+end
+for c=1:length(b.clpot)
+  [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c});
+end
+b.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..048d9064
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/enter_evidence.m
@@ -0,0 +1,22 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (jtree_online)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product instead of sum-product [0]
+%
+
+engine.maximize = 0;
+args = varargin;
+for i=1:2:length(args)
+  switch args{i}
+   case 'maximize', engine.maximize = args{i+1};
+   otherwise, error(['unrecognized argument ' args{i}])
+  end
+end
+
+[engine, loglik] = offline_smoother(engine, evidence);
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd.m
new file mode 100644
index 00000000..948d8bc8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd.m
@@ -0,0 +1,47 @@
+function [f, logscale] = fwd(engine, fpast, ev, t)
+% Forwards pass.
+
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+ev2 = cell(ss, 2);
+ev2(:,1) = fpast.evidence;
+ev2(:,2) = ev;
+CPDpot = cell(1,ss);
+for n=1:ss
+  fam = family(bnet.dag, n, 2);
+  e = bnet.equiv_class(n, 2);
+  CPDpot{n} = convert_to_pot(bnet.CPD{e}, engine.pot_type, fam(:), ev2);
+end       
+f.evidence = ev;
+f.t = t;
+
+% get prior
+int = engine.interface;
+if fpast.t==1
+  prior = marginalize_pot(fpast.clpot{engine.int_clq1}, int, engine.maximize);
+else
+  prior = marginalize_pot(fpast.clpot{engine.out_clq}, int+ss, engine.maximize);
+  prior = set_domain_pot(prior, int); % shift back to slice 1
+end
+
+pots = [ {prior} CPDpot ];
+slice1 = 1:ss;
+slice2 = slice1 + ss; 
+CPDclqs = engine.clq_ass_to_node(slice2);
+D = engine.in_clq;
+clqs = [D CPDclqs];
+
+[f.clpot, f.seppot] =  init_pot(engine.jtree_engine, clqs, pots, engine.pot_type, engine.observed);
+[f.clpot, f.seppot] = collect_evidence(engine.jtree_engine, f.clpot, f.seppot);
+for c=1:length(f.clpot)
+  if isa(f.clpot{c}, 'struct')
+     domain = f.clpot{c}.domain;
+     sizes = f.clpot{c}.sizes;
+     T = f.clpot{c}.T;
+     f.clpot{c} = dpot(domain, sizes, T);
+  end
+  [f.clpot{c}, ll(c)] = normalize_pot(f.clpot{c});
+end
+logscale = ll(engine.root);
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd1.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd1.m
new file mode 100644
index 00000000..45d28c3f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd1.m
@@ -0,0 +1,32 @@
+function [f, logscale] = fwd1(engine, ev, t)
+% Forwards pass for slice 1.
+
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+CPDpot = cell(1,ss);
+for n=1:ss
+  fam = family(bnet.dag, n, 1);
+  e = bnet.equiv_class(n, 1);
+  CPDpot{n} = convert_to_pot(bnet.CPD{e}, engine.pot_type, fam(:), ev);
+end       
+f.evidence = ev;
+f.t = t;
+
+pots = CPDpot;
+slice1 = 1:ss;
+CPDclqs = engine.clq_ass_to_node1(slice1);
+
+[f.clpot, f.seppot] =  init_pot(engine.jtree_engine1, CPDclqs, CPDpot, engine.pot_type, engine.observed1);
+[f.clpot, f.seppot] = collect_evidence(engine.jtree_engine1, f.clpot, f.seppot);
+for c=1:length(f.clpot)
+  if isa(f.clpot{c}, 'struct')
+     domain = f.clpot{c}.domain;
+     sizes = f.clpot{c}.sizes;
+     T = f.clpot{c}.T;
+     f.clpot{c} = dpot(domain, sizes, T);
+  end
+  [f.clpot{c}, ll(c)] = normalize_pot(f.clpot{c});
+end
+logscale = ll(engine.root1);
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/jtree_sparse_2TBN_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/jtree_sparse_2TBN_inf_engine.m
new file mode 100644
index 00000000..4897e8fd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/jtree_sparse_2TBN_inf_engine.m
@@ -0,0 +1,95 @@
+function engine = jtree_sparse_2TBN_inf_engine(bnet, varargin)
+% JTREE_ONLINE_INF_ENGINE Online Junction tree inference algorithm for DBNs.
+% engine = jtree_online_inf_engine(bnet, ...)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% clusters - specifies variables that must be grouped in the 1.5 slice DBN
+% maximize - 1 means do max-product, 0 means sum-product [0]
+%
+% The same nodes must be observed in every slice.
+
+ss = length(bnet.intra);
+clusters = {};
+engine.maximize = 0;
+
+args = varargin;
+nargs = length(args);
+for i=1:2:length(args)
+  switch args{i},
+   case 'clusters', clusters = args{i+1};
+   case 'maximize', engine.maximize = args{i+1};
+   otherwise, error(['unrecognized argument ' args{i}])
+  end
+end
+
+engine.evidence = [];
+engine.node_sizes = [];
+
+int = [];
+% include nodes with any outgoing arcs
+for u=1:ss
+  if any(bnet.inter(u,:))
+    int = [int u];
+  end
+end
+
+engine.interface = int;
+engine.nonint = mysetdiff(1:ss, int);
+
+onodes = bnet.observed;
+
+% Create a "1.5 slice" jtree, containing the interface nodes of slice 1
+% and all the nodes of slice 2
+% To keep the node numbering the same, we simply disconnect the non-interface nodes
+% from slice 1, and set their size to 1.
+% We do this to speed things up, and so that the likelihood is computed correctly - we do not need to do
+% this if we just want to compute marginals (i.e., we can include nodes whose potentials will
+% be left as all 1s).
+intra15 = bnet.intra;
+for i=engine.nonint(:)'
+  intra15(:,i) = 0;
+  intra15(i,:) = 0;
+  assert(~any(bnet.inter(i,:)))
+end
+dag15 = [intra15      bnet.inter;
+	 zeros(ss)    bnet.intra];
+ns = bnet.node_sizes(:);
+ns(engine.nonint) = 1; % disconnected nodes get size 1
+obs_nodes = [onodes(:) onodes(:)+ss];
+bnet15 = mk_bnet(dag15, ns, 'discrete', bnet.dnodes, 'equiv_class', bnet.equiv_class(:), ...
+		 'observed', obs_nodes(:));
+
+% use unconstrained elimination,
+% but force there to be a clique containing both interfaces
+clusters(end+1:end+2) = {int, int+ss};
+%engine.jtree_engine = jtree_inf_engine(bnet15, 'clusters', clusters, 'root', int+ss);
+engine.jtree_engine = jtree_sparse_inf_engine(bnet15, 'clusters', clusters, 'root', int+ss);
+jtree_engine = struct(engine.jtree_engine); % violate object privacy
+
+engine.in_clq = clq_containing_nodes(engine.jtree_engine, int);
+engine.out_clq = clq_containing_nodes(engine.jtree_engine, int+ss);
+engine.clq_ass_to_node = jtree_engine.clq_ass_to_node;
+engine.root = jtree_engine.root_clq;
+
+% 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.jtree_engine1 = jtree_inf_engine(bnet1, 'clusters', {int}, 'root', int);
+engine.jtree_engine1 = jtree_sparse_inf_engine(bnet1, 'clusters', {int}, 'root', int);
+jtree_engine1 = struct(engine.jtree_engine1); % violate object privacy
+engine.int_clq1 = clq_containing_nodes(engine.jtree_engine1, int);
+engine.clq_ass_to_node1 = jtree_engine1.clq_ass_to_node;
+engine.root1 = jtree_engine1.root_clq;
+
+engine.observed = [onodes onodes+ss];
+engine.observed1 = onodes;
+engine.pot_type = determine_pot_type(bnet, onodes);
+engine.slice_size = bnet.nnodes_per_slice;
+
+engine = class(engine, 'jtree_sparse_2TBN_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_family.m
new file mode 100644
index 00000000..0b6e6186
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_family.m
@@ -0,0 +1,12 @@
+function m = marginal_family(engine, b, i, t, add_ev)
+% MARGINAL_FAMILY Compute the marginal on the specified family (jtree_2TBN)
+% marginal = marginal_family(engine, b, i, t, add_ev)
+
+bnet = bnet_from_engine(engine);
+if t==1
+  m = marginal_nodes(engine, b, family(bnet.dag, i), t, add_ev, 1);
+else
+  ss = length(bnet.intra);
+  fam = family(bnet.dag, i+ss);
+  m = marginal_nodes(engine, b, fam, t, add_ev, 1);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..e7ee2ae9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_nodes.m
@@ -0,0 +1,32 @@
+function marginal = marginal_nodes(engine, b, nodes, t, add_ev, is_fam)
+% function marginal = marginal_nodes(engine, b, nodes, t, add_ev, is_fam) (jtree_2TBN)
+
+if nargin < 6, is_fam = 0; end
+ss = engine.slice_size;
+
+if ~is_fam & (t > 1) & all(nodes<=ss)
+  nodes = nodes + ss;
+end
+
+if t==1
+  c = clq_containing_nodes(engine.jtree_engine1, nodes, is_fam);
+else
+  c = clq_containing_nodes(engine.jtree_engine, nodes, is_fam);
+end
+if c == -1
+  error(['no clique contains ' nodes])
+end
+bigpot = b.clpot{c};
+pot = marginalize_pot(bigpot, nodes, engine.maximize);
+marginal = pot_to_marginal(pot);
+
+% we convert the domain to the unrolled numbering system
+% so that add_ev_to_dmarginal (maybe called in update_ess) extracts the right evidence.
+if t > 1
+  marginal.domain = nodes+(t-2)*engine.slice_size;
+end
+assert(~add_ev);
+
+
+
+