about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine
diff options
context:
space:
mode:
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));
+