about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/BNT/inference/online/@hmm_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/@hmm_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/@hmm_2TBN_inf_engine')
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries9
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/back.m21
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/backT.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd.m17
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd1.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/hmm_2TBN_inf_engine.m86
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_family.m35
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_nodes.m27
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/mk_hmm_obs_lik_vec.m53
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/update_engine.m8
16 files changed, 285 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries
new file mode 100644
index 00000000..9d562fd8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries
@@ -0,0 +1,9 @@
+/back.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//
+/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//
+/hmm_2TBN_inf_engine.m/1.1.1.1/Thu Nov 14 20:03:50 2002//
+/marginal_family.m/1.1.1.1/Thu Nov 14 20:05:36 2002//
+/marginal_nodes.m/1.1.1.1/Thu Nov 14 20:02:46 2002//
+/update_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries.Log
new file mode 100644
index 00000000..b2cd71e0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/private////
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Repository
new file mode 100644
index 00000000..858ed017
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/online/@hmm_2TBN_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_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/@hmm_2TBN_inf_engine/back.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/back.m
new file mode 100644
index 00000000..8ad416f7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/back.m
@@ -0,0 +1,21 @@
+function b = back(engine, bfuture, f, t)
+
+if f.t ~= t
+  error('mixed up time stamps')
+end
+
+b.t = t;
+b.obslik = f.obslik;
+bb_future = bfuture.beta .* bfuture.obslik;
+if engine.maximize
+  B = repmat(bb_future(:)', length(bfuture.beta), 1);
+  b.beta = normalise(max(engine.transprob .* B, [], 2));
+else
+  b.beta = normalise((engine.transprob * bb_future));
+end
+b.gamma = normalise(f.alpha .* b.beta);
+if t > 1
+  bb_t = b.beta .* b.obslik;
+  b.xi = normalise((engine.transprob .* (f.past_alpha * bb_t'))); % t-1,t
+end
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/backT.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/backT.m
new file mode 100644
index 00000000..ffeb6628
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/backT.m
@@ -0,0 +1,11 @@
+function b = backT(engine, f, t)
+
+b.t = t;
+b.obslik = f.obslik;
+Q = length(f.alpha);
+b.beta = ones(Q,1);
+b.gamma = f.alpha;
+if t > 1
+  bb_t = b.obslik;
+  b.xi = normalise((engine.transprob .* (f.past_alpha * bb_t'))); % T-1,T
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd.m
new file mode 100644
index 00000000..3afdf714
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd.m
@@ -0,0 +1,17 @@
+function [f, logscale] = fwd(engine, fpast, ev, t)
+% Forwards pass.
+
+f.obslik = mk_hmm_obs_lik_vec(engine, ev);
+transmat = engine.transprob;
+f.past_alpha = fpast.alpha;
+if engine.maximize
+  Q = length(fpast.alpha);
+  A = repmat(fpast.alpha, [1 Q]);
+  m = max(transmat .* A, [], 1);
+  [f.alpha, scale] = normalise(m(:) .* f.obslik);
+else
+  [f.alpha, scale] = normalise((transmat' * fpast.alpha) .* f.obslik);
+end
+logscale = log(scale);
+%f.xi = normalise((fpast.alpha * obslik') .* transmat); % t-1,t
+f.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd1.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd1.m
new file mode 100644
index 00000000..ec16db4b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd1.m
@@ -0,0 +1,11 @@
+function [f, logscale] = fwd1(engine, ev, t)
+% Forwards pass for slice 1.
+
+if t ~= 1
+  error('mixed up time stamps')
+end
+prior = engine.startprob(:);
+f.obslik = mk_hmm_obs_lik_vec(engine, ev);
+[f.alpha, lik] = normalise(prior .* f.obslik);
+logscale = log(lik);
+f.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/hmm_2TBN_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/hmm_2TBN_inf_engine.m
new file mode 100644
index 00000000..8504124b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/hmm_2TBN_inf_engine.m
@@ -0,0 +1,86 @@
+function engine = hmm_2TBN_inf_engine(bnet, varargin)
+% HMM_2TBN_INF_ENGINE Inference engine for DBNs which uses the forwards-backwards algorithm.
+% engine = hmm_2TBN_inf_engine(bnet, ...)
+%
+% The DBN is converted to an HMM with a single meganode, but the observed nodes remain factored.
+% This can be faster than jtree if the num. hidden nodes is low, because of lower constant factors.
+%
+% All hidden nodes must be discrete.
+% All observed nodes are assumed to be leaves.
+% The parents of each observed leaf are assumed to be a subset of the hidden nodes within the same slice.
+% The only exception is if bnet is an AR-HMM, where the parents are assumed to be self in the
+% previous slice (continuous), plus all the discrete nodes in the current slice.
+
+
+%% Optional arguments
+%% ndx_type - 'B', 'D', or 'SD', used in marginal_family [ 'SD' ]
+
+ndx_type = 'SD';
+ss = bnet.nnodes_per_slice;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     %case 'ndx_type', ndx_type = args{i+1};
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+% Stuff to do with speeding up marginal_family
+%engine.ndx_type = ndx_type;
+
+[int, engine.persist, engine.transient] = compute_interface_nodes(bnet.intra, bnet.inter);
+engine.persist_bitv = zeros(1, ss);
+engine.persist_bitv(engine.persist) = 1;
+
+
+ns = bnet.node_sizes(:);
+ns(bnet.observed) = 1;
+ns(bnet.observed+ss) = 1;
+engine.eff_node_sizes = ns;
+
+% for n=1:ss
+%   dom = 1:(2*ss); % domain of xi(:,:,1)
+%   fam = family(bnet.dag, n+ss);
+%   engine.marg_fam2_ndx_id(n) = add_ndx(dom, fam, ns, ndx_type);
+ 
+%   dom = 1:ss; % domain of gamma(:,:,1)
+%   fam = family(bnet.dag, n);
+%   engine.marg_fam1_ndx_id(n) = add_ndx(dom, fam, ns, ndx_type);
+
+%   engine.marg_singleton_ndx_id(n) = add_ndx(dom, n, ns, ndx_type);
+% end
+
+for o=bnet.observed(:)'
+  %if bnet.equiv_class(o,1) ~= bnet.equiv_class(o,2)
+  %  error(['observed node ' num2str(o) ' is not tied'])
+  %end
+  cs = children(bnet.dag, o);
+  if ~isempty(cs)
+    error(['observed node ' num2str(o) ' is not allowed children'])
+  end
+end
+
+[engine.startprob, engine.transprob, engine.obsprob] = dbn_to_hmm(bnet);
+
+% This is where we will store the results between enter_evidence and marginal_nodes
+engine.one_slice_marginal = [];
+engine.two_slice_marginal = [];
+
+ss = length(bnet.intra);
+engine.maximize = [];
+engine.evidence = [];
+engine.node_sizes = [];
+
+% avoid the need to do bnet_from_engine, which is slow
+engine.slice_size = ss;
+engine.parents = bnet.parents;
+
+engine.bel = [];
+engine = class(engine, 'hmm_2TBN_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_family.m
new file mode 100644
index 00000000..cd8a6997
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_family.m
@@ -0,0 +1,35 @@
+function marginal = marginal_family(engine, b, i, t, add_ev)
+% MARGINAL_FAMILY Compute the marginal on the specified family (hmm_2TBN)
+% marginal = marginal_family(engine, b, i, t, add_ev)
+
+ns = engine.eff_node_sizes(:);
+ss = engine.slice_size;
+
+if t==1 % | ~engine.persist_bitv(i)
+  bigT = b.gamma;
+  ps = engine.parents{i};
+  dom = [ps i];
+  %id = engine.marg_fam1_ndx_id(i);
+  bigdom = 1:ss;
+  bigsz = ns(bigdom);
+  bigdom = bigdom + (t-1)*ss;
+else % some parents are in previous slice
+  bigT = b.xi; % (t-1,t)
+  ps = engine.parents{i+ss};
+  dom = [ps i+ss] + (t-2)*ss;
+  %id = engine.marg_fam2_ndx_id(i);
+  bigdom = 1:(2*ss); % domain of xi(:,:,t)
+  bigsz = ns(bigdom);
+  bigdom = bigdom + (t-2)*ss;
+end
+marginal.domain = dom;
+
+%ndx = get_ndx(id, engine.ndx_type);
+%marginal.T = marg_table_ndx(bigT, engine.maximize, ndx, engine.ndx_type);
+%global SD_NDX
+%ndx = SD_NDX{id};
+%marginal.T = marg_table_ndxSD(bigT, engine.maximize, ndx);
+marginal.T = marg_table(bigT, bigdom, bigsz, dom, engine.maximize); 
+
+assert(~add_ev);
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..6fa6c2b3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_nodes.m
@@ -0,0 +1,27 @@
+function marginal = marginal_nodes(engine, b, nodes, t, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified nodes (hmm_2TBN)
+% marginal = marginal_nodes(engine, b, nodes, t, add_ev)
+%
+% nodes must be a singleton set 
+
+assert(length(nodes)==1)
+ss = engine.slice_size;
+
+i = nodes(1);
+bigT = b.gamma;
+dom = i + (t-1)*ss;
+
+%id = engine.marg_singleton_ndx_id(i);
+%global SD_NDX
+%ndx = SD_NDX{id};
+%marginal.T = marg_table_ndxSD(bigT, engine.maximize, ndx);
+
+ns = engine.eff_node_sizes(:);
+bigdom = 1:ss;
+marginal.T = marg_table(bigT, bigdom + (t-1)*ss, ns(bigdom), dom, engine.maximize);
+
+marginal.domain = dom;
+assert(~add_ev);
+%if add_ev
+%  marginal = add_ev_to_dmarginal(marginal, engine.evidence, engine.node_sizes);
+%end    
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Entries
new file mode 100644
index 00000000..c37a30a9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Entries
@@ -0,0 +1,2 @@
+/mk_hmm_obs_lik_vec.m/1.1.1.1/Sun May  4 21:47:44 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Repository
new file mode 100644
index 00000000..81419e91
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/online/@hmm_2TBN_inf_engine/private
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/mk_hmm_obs_lik_vec.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/mk_hmm_obs_lik_vec.m
new file mode 100644
index 00000000..915a2f39
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/mk_hmm_obs_lik_vec.m
@@ -0,0 +1,53 @@
+function obslik = mk_hmm_obs_lik_vec(engine, evidence)
+
+% P(o1,o2| h) = P(o1|h) * P(o2|h) where h = Q1,Q2,...
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+onodes = bnet.observed;
+hnodes = mysetdiff(1:ss, onodes);
+ns = bnet.node_sizes(:);
+ns(onodes) = 1;
+
+Q = length(engine.startprob);
+obslik = ones(Q, 1);
+
+for i=1:length(onodes)
+  o = onodes(i);
+  %data = cell2num(evidence(o,1));
+  data = evidence{o,1};
+  if myismember(o, bnet.dnodes)
+    %obslik_i = eval_pdf_cond_multinomial(data, engine.obsprob{i}.CPT);
+    obslik_i = multinomial_prob(data, engine.obsprob{i}.CPT);
+  else
+    if bnet.auto_regressive(o)
+      error('can''t handle AR nodes')
+    end
+    %% calling mk_ghmm_obs_lik, which calls gaussian_prob, is slow, so we inline it
+    %% and use the pre-computed  inverse matrix
+    %obslik_i = mk_ghmm_obs_lik(data, engine.obsprob{i}.mu, engine.obsprob{i}.Sigma);
+    x = data(:);
+    m = engine.obsprob{i}.mu;
+    Qi = size(m, 2);
+    obslik_i = size(Qi, 1);
+    invC = engine.obsprob{i}.inv_Sigma;
+    denom = engine.obsprob{i}.denom;
+    for j=1:Qi
+      numer = exp(-0.5 * (x-m(:,j))' * invC(:,:,j) * (x-m(:,j)));
+      obslik_i(j) = numer / denom(j);
+    end
+  end
+  % convert P(o|ps) into P(o|h) by multiplying onto a (h,o) potential of all 1s
+  ps = bnet.parents{o};
+  dom = [ps o];
+  obspot_i = dpot(dom, ns(dom), obslik_i);
+  dom = [hnodes o];
+  obspot = dpot(dom, ns(dom));
+  obspot = multiply_by_pot(obspot, obspot_i);
+  % compute p(oi|h) * p(oj|h)
+  S = struct(obspot);
+  obslik = obslik .* S.T(:);
+end
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/update_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/update_engine.m
new file mode 100644
index 00000000..e6cd1f79
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/update_engine.m
@@ -0,0 +1,8 @@
+function engine = update_engine(engine, newCPDs)
+% UPDATE_ENGINE Update the engine to take into account the new parameters (hmm)
+% engine = update_engine(engine, newCPDs)
+
+%engine.inf_engine.bnet.CPD = newCPDs;
+engine.inf_engine = update_engine(engine.inf_engine, newCPDs);
+[engine.startprob, engine.transprob, engine.obsprob] = dbn_to_hmm(bnet_from_engine(engine));
+