about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/HMM
diff options
context:
space:
mode:
Diffstat (limited to 'sourcecodes/bnt-master/HMM')
-rw-r--r--sourcecodes/bnt-master/HMM/CVS/Entries29
-rw-r--r--sourcecodes/bnt-master/HMM/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/HMM/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/HMM/README.txt23
-rw-r--r--sourcecodes/bnt-master/HMM/dhmm_em.m124
-rw-r--r--sourcecodes/bnt-master/HMM/dhmm_em_demo.m25
-rw-r--r--sourcecodes/bnt-master/HMM/dhmm_em_online.m80
-rw-r--r--sourcecodes/bnt-master/HMM/dhmm_em_online_demo.m93
-rw-r--r--sourcecodes/bnt-master/HMM/dhmm_logprob.m22
-rw-r--r--sourcecodes/bnt-master/HMM/dhmm_logprob_brute_force.m21
-rw-r--r--sourcecodes/bnt-master/HMM/dhmm_logprob_path.m15
-rw-r--r--sourcecodes/bnt-master/HMM/dhmm_sample.m10
-rw-r--r--sourcecodes/bnt-master/HMM/dhmm_sample_endstate.m19
-rw-r--r--sourcecodes/bnt-master/HMM/fixed_lag_smoother.m65
-rw-r--r--sourcecodes/bnt-master/HMM/fixed_lag_smoother_demo.m38
-rw-r--r--sourcecodes/bnt-master/HMM/fwdback.m197
-rw-r--r--sourcecodes/bnt-master/HMM/gausshmm_train_observed.m44
-rw-r--r--sourcecodes/bnt-master/HMM/mc_sample.m17
-rw-r--r--sourcecodes/bnt-master/HMM/mc_sample_endstate.m27
-rw-r--r--sourcecodes/bnt-master/HMM/mdp_sample.m18
-rw-r--r--sourcecodes/bnt-master/HMM/mhmmParzen_train_observed.m37
-rw-r--r--sourcecodes/bnt-master/HMM/mhmm_em.m173
-rw-r--r--sourcecodes/bnt-master/HMM/mhmm_em_demo.m40
-rw-r--r--sourcecodes/bnt-master/HMM/mhmm_logprob.m30
-rw-r--r--sourcecodes/bnt-master/HMM/mhmm_sample.m31
-rw-r--r--sourcecodes/bnt-master/HMM/mk_leftright_transmat.m6
-rw-r--r--sourcecodes/bnt-master/HMM/mk_rightleft_transmat.m6
-rw-r--r--sourcecodes/bnt-master/HMM/pomdp_sample.m20
-rw-r--r--sourcecodes/bnt-master/HMM/testHMM.m5
-rw-r--r--sourcecodes/bnt-master/HMM/transmat_train_observed.m39
-rw-r--r--sourcecodes/bnt-master/HMM/viterbi_path.m62
31 files changed, 1318 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/HMM/CVS/Entries b/sourcecodes/bnt-master/HMM/CVS/Entries
new file mode 100644
index 00000000..b9105b50
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/CVS/Entries
@@ -0,0 +1,29 @@
+/README.txt/1.1.1.1/Thu Jun  9 01:22:48 2005//
+/dhmm_em.m/1.1.1.1/Thu Jun  9 01:25:04 2005//
+/dhmm_em_demo.m/1.1.1.1/Sun May  4 22:01:12 2003//
+/dhmm_em_online.m/1.1.1.1/Sun May  4 22:02:58 2003//
+/dhmm_em_online_demo.m/1.1.1.1/Sun May  4 22:04:10 2003//
+/dhmm_logprob.m/1.1.1.1/Sun May  4 22:01:34 2003//
+/dhmm_logprob_brute_force.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/dhmm_logprob_path.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/dhmm_sample.m/1.1.1.1/Mon May 31 22:19:50 2004//
+/dhmm_sample_endstate.m/1.1.1.1/Sun May  4 22:00:34 2003//
+/fixed_lag_smoother.m/1.1.1.1/Wed Jan 22 17:56:04 2003//
+/fixed_lag_smoother_demo.m/1.1.1.1/Thu Jun  9 01:27:20 2005//
+/fwdback.m/1.1.1.1/Thu Jun  9 01:17:50 2005//
+/gausshmm_train_observed.m/1.1.1.1/Thu Feb 12 23:08:22 2004//
+/mc_sample.m/1.1.1.1/Mon May 24 22:26:34 2004//
+/mc_sample_endstate.m/1.1.1.1/Wed Jan 22 20:32:28 2003//
+/mdp_sample.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/mhmmParzen_train_observed.m/1.1.1.1/Sat Feb 14 02:06:30 2004//
+/mhmm_em.m/1.1.1.1/Sun Feb  8 04:52:42 2004//
+/mhmm_em_demo.m/1.1.1.1/Tue May 13 16:11:22 2003//
+/mhmm_logprob.m/1.1.1.1/Sun May  4 22:11:54 2003//
+/mhmm_sample.m/1.1.1.1/Wed May 26 00:32:28 2004//
+/mk_leftright_transmat.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/mk_rightleft_transmat.m/1.1.1.1/Fri Nov 22 21:45:52 2002//
+/pomdp_sample.m/1.1.1.1/Sun May  4 21:58:20 2003//
+/testHMM.m/1.1.1.1/Thu Jun  9 01:25:50 2005//
+/transmat_train_observed.m/1.1.1.1/Sun Aug 29 12:41:52 2004//
+/viterbi_path.m/1.1.1.1/Sat Oct 23 01:18:22 2004//
+D
diff --git a/sourcecodes/bnt-master/HMM/CVS/Repository b/sourcecodes/bnt-master/HMM/CVS/Repository
new file mode 100644
index 00000000..5f13f5c3
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/HMM
diff --git a/sourcecodes/bnt-master/HMM/CVS/Root b/sourcecodes/bnt-master/HMM/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/HMM/README.txt b/sourcecodes/bnt-master/HMM/README.txt
new file mode 100644
index 00000000..2e6ab78f
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/README.txt
@@ -0,0 +1,23 @@
+Hidden Markov Model (HMM) Toolbox written by Kevin Murphy (1998).
+See http://www.ai.mit.edu/~murphyk/Software/hmm.html for details.
+
+Models
+------
+
+dhmm = HMM with discrete output
+mhmm = HMM with mixture of Gaussians output;
+ Use mhmm with M=1 components to simulate an HMM with a single Gaussian output.
+
+Demos
+-----
+
+mhmm_em_demo
+dhmm_em_demo
+dhmm_em_online_demo
+fixed_lag_smoother_demo
+
+References
+-----------
+
+See "A tutorial on Hidden Markov Models and selected applications in speech recognition",
+ L. Rabiner, 1989, Proc. IEEE 77(2):257--286.
diff --git a/sourcecodes/bnt-master/HMM/dhmm_em.m b/sourcecodes/bnt-master/HMM/dhmm_em.m
new file mode 100644
index 00000000..34ac1c6d
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/dhmm_em.m
@@ -0,0 +1,124 @@
+function [LL, prior, transmat, obsmat, nrIterations] = ...
+   dhmm_em(data, prior, transmat, obsmat, varargin)
+% LEARN_DHMM Find the ML/MAP parameters of an HMM with discrete outputs using EM.
+% [ll_trace, prior, transmat, obsmat, iterNr] = learn_dhmm(data, prior0, transmat0, obsmat0, ...)
+%
+% Notation: Q(t) = hidden state, Y(t) = observation
+%
+% INPUTS:
+% data{ex} or data(ex,:) if all sequences have the same length
+% prior(i)
+% transmat(i,j)
+% obsmat(i,o)
+%
+% Optional parameters may be passed as 'param_name', param_value pairs.
+% Parameter names are shown below; default values in [] - if none, argument is mandatory.
+%
+% 'max_iter' - max number of EM iterations [10]
+% 'thresh' - convergence threshold [1e-4]
+% 'verbose' - if 1, print out loglik at every iteration [1]
+% 'obs_prior_weight' - weight to apply to uniform dirichlet prior on observation matrix [0]
+%
+% To clamp some of the parameters, so learning does not change them:
+% 'adj_prior' - if 0, do not change prior [1]
+% 'adj_trans' - if 0, do not change transmat [1]
+% 'adj_obs' - if 0, do not change obsmat [1]
+%
+% Modified by Herbert Jaeger so xi are not computed individually
+% but only their sum (over time) as xi_summed; this is the only way how they are used
+% and it saves a lot of memory.
+
+[max_iter, thresh, verbose, obs_prior_weight, adj_prior, adj_trans, adj_obs] = ...
+   process_options(varargin, 'max_iter', 10, 'thresh', 1e-4, 'verbose', 1, ...
+                   'obs_prior_weight', 0, 'adj_prior', 1, 'adj_trans', 1, 'adj_obs', 1);
+
+previous_loglik = -inf;
+loglik = 0;
+converged = 0;
+num_iter = 1;
+LL = [];
+
+if ~iscell(data)
+ data = num2cell(data, 2); % each row gets its own cell
+end
+
+while (num_iter <= max_iter) & ~converged
+ % E step
+ [loglik, exp_num_trans, exp_num_visits1, exp_num_emit] = ...
+     compute_ess_dhmm(prior, transmat, obsmat, data, obs_prior_weight);
+
+ % M step
+ if adj_prior
+   prior = normalise(exp_num_visits1);
+ end
+ if adj_trans & ~isempty(exp_num_trans)
+   transmat = mk_stochastic(exp_num_trans);
+ end
+ if adj_obs
+   obsmat = mk_stochastic(exp_num_emit);
+ end
+
+ if verbose, fprintf(1, 'iteration %d, loglik = %f\n', num_iter, loglik); end
+ num_iter =  num_iter + 1;
+ converged = em_converged(loglik, previous_loglik, thresh);
+ previous_loglik = loglik;
+ LL = [LL loglik];
+end
+nrIterations = num_iter - 1;
+
+%%%%%%%%%%%%%%%%%%%%%%%
+
+function [loglik, exp_num_trans, exp_num_visits1, exp_num_emit, exp_num_visitsT] = ...
+   compute_ess_dhmm(startprob, transmat, obsmat, data, dirichlet)
+% COMPUTE_ESS_DHMM Compute the Expected Sufficient Statistics for an HMM with discrete outputs
+% function [loglik, exp_num_trans, exp_num_visits1, exp_num_emit, exp_num_visitsT] = ...
+%    compute_ess_dhmm(startprob, transmat, obsmat, data, dirichlet)
+%
+% INPUTS:
+% startprob(i)
+% transmat(i,j)
+% obsmat(i,o)
+% data{seq}(t)
+% dirichlet - weighting term for uniform dirichlet prior on expected emissions
+%
+% OUTPUTS:
+% exp_num_trans(i,j) = sum_l sum_{t=2}^T Pr(X(t-1) = i, X(t) = j| Obs(l))
+% exp_num_visits1(i) = sum_l Pr(X(1)=i | Obs(l))
+% exp_num_visitsT(i) = sum_l Pr(X(T)=i | Obs(l))
+% exp_num_emit(i,o) = sum_l sum_{t=1}^T Pr(X(t) = i, O(t)=o| Obs(l))
+% where Obs(l) = O_1 .. O_T for sequence l.
+
+numex = length(data);
+[S O] = size(obsmat);
+exp_num_trans = zeros(S,S);
+exp_num_visits1 = zeros(S,1);
+exp_num_visitsT = zeros(S,1);
+exp_num_emit = dirichlet*ones(S,O);
+loglik = 0;
+
+for ex=1:numex
+ obs = data{ex};
+ T = length(obs);
+ %obslik = eval_pdf_cond_multinomial(obs, obsmat);
+ obslik = multinomial_prob(obs, obsmat);
+ [alpha, beta, gamma, current_ll, xi_summed] = fwdback(startprob, transmat, obslik);
+
+ loglik = loglik +  current_ll;
+ exp_num_trans = exp_num_trans + xi_summed;
+ exp_num_visits1 = exp_num_visits1 + gamma(:,1);
+ exp_num_visitsT = exp_num_visitsT + gamma(:,T);
+ % loop over whichever is shorter
+ if T < O
+   for t=1:T
+     o = obs(t);
+     exp_num_emit(:,o) = exp_num_emit(:,o) + gamma(:,t);
+   end
+ else
+   for o=1:O
+     ndx = find(obs==o);
+     if ~isempty(ndx)
+       exp_num_emit(:,o) = exp_num_emit(:,o) + sum(gamma(:, ndx), 2);
+     end
+   end
+ end
+end
diff --git a/sourcecodes/bnt-master/HMM/dhmm_em_demo.m b/sourcecodes/bnt-master/HMM/dhmm_em_demo.m
new file mode 100644
index 00000000..c6ffa1dd
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/dhmm_em_demo.m
@@ -0,0 +1,25 @@
+O = 3;
+Q = 2;
+
+% "true" parameters
+prior0 = normalise(rand(Q,1));
+transmat0 = mk_stochastic(rand(Q,Q));
+obsmat0 = mk_stochastic(rand(Q,O));
+
+% training data
+T = 5;
+nex = 10;
+data = dhmm_sample(prior0, transmat0, obsmat0, T, nex);
+
+% initial guess of parameters
+prior1 = normalise(rand(Q,1));
+transmat1 = mk_stochastic(rand(Q,Q));
+obsmat1 = mk_stochastic(rand(Q,O));
+
+% improve guess of parameters using EM
+[LL, prior2, transmat2, obsmat2] = dhmm_em(data, prior1, transmat1, obsmat1, 'max_iter', 5);
+LL
+
+% use model to compute log likelihood
+loglik = dhmm_logprob(data, prior2, transmat2, obsmat2)
+% log lik is slightly different than LL(end), since it is computed after the final M step
diff --git a/sourcecodes/bnt-master/HMM/dhmm_em_online.m b/sourcecodes/bnt-master/HMM/dhmm_em_online.m
new file mode 100644
index 00000000..605a1f5b
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/dhmm_em_online.m
@@ -0,0 +1,80 @@
+function [transmat, obsmat, exp_num_trans, exp_num_emit, gamma, ll] = dhmm_em_online(...
+    prior, transmat, obsmat, exp_num_trans, exp_num_emit, decay, data, ...
+    act, adj_trans, adj_obs, dirichlet, filter_only)
+% ONLINE_EM Adjust the parameters using a weighted combination of the old and new expected statistics
+%
+% [transmat, obsmat, exp_num_trans, exp_num_emit, gamma, ll] = online_em(...
+%    prior, transmat, obsmat, exp_num_trans, exp_num_emit, decay, data, act, ...
+%    adj_trans, adj_obs, dirichlet, filter_only)
+% 
+% 0 < decay < 1, with smaller values meaning the past is forgotten more quickly.
+% (We need to decay the old ess, since they were based on out-of-date parameters.)
+% The other params are as in learn_hmm.
+% We do a single forwards-backwards pass on the provided data, initializing with the specified prior.
+% (If filter_only = 1, we only do a forwards pass.)
+
+if ~exist('act'), act = []; end
+if ~exist('adj_trans'), adj_trans = 1; end
+if ~exist('adj_obs'), adj_obs = 1; end
+if ~exist('dirichlet'), dirichlet = 0; end
+if ~exist('filter_only'), filter_only = 0; end
+
+% E step
+olikseq = multinomial_prob(data, obsmat);
+if isempty(act)
+  [alpha, beta, gamma, ll, xi] = fwdback(prior, transmat, olikseq, 'fwd_only', filter_only);
+else
+  [alpha, beta, gamma, ll, xi] = fwdback(prior, transmat, olikseq, 'fwd_only', filter_only, ...
+					 'act', act);
+end
+
+% Increment ESS
+[S O] = size(obsmat);
+if adj_obs
+  exp_num_emit = decay*exp_num_emit + dirichlet*ones(S,O);
+  T = length(data);
+  if T < O
+    for t=1:T
+      o = data(t);
+      exp_num_emit(:,o) = exp_num_emit(:,o) + gamma(:,t);
+    end
+  else
+    for o=1:O
+      ndx = find(data==o);
+      if ~isempty(ndx)
+	exp_num_emit(:,o) = exp_num_emit(:,o) + sum(gamma(:, ndx), 2);
+      end
+    end
+  end
+end
+
+if adj_trans & (T > 1)
+  if isempty(act)
+    exp_num_trans = decay*exp_num_trans + sum(xi,3);
+  else
+    % act(2) determines Q(2), xi(:,:,1) holds P(Q(1), Q(2))
+    A = length(transmat);
+    for a=1:A
+      ndx = find(act(2:end)==a);
+      if ~isempty(ndx)
+	exp_num_trans{a} = decay*exp_num_trans{a} + sum(xi(:,:,ndx), 3);
+      end
+    end
+  end
+end
+
+
+% M step
+
+if adj_obs
+  obsmat = mk_stochastic(exp_num_emit);
+end
+if adj_trans & (T>1)
+  if isempty(act)
+    transmat = mk_stochastic(exp_num_trans);
+  else
+    for a=1:A
+      transmat{a} = mk_stochastic(exp_num_trans{a});
+    end
+  end
+end
diff --git a/sourcecodes/bnt-master/HMM/dhmm_em_online_demo.m b/sourcecodes/bnt-master/HMM/dhmm_em_online_demo.m
new file mode 100644
index 00000000..579d89d5
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/dhmm_em_online_demo.m
@@ -0,0 +1,93 @@
+% Example of online EM applied to a simple POMDP with fixed action seq
+
+clear all
+
+% Create a really easy model to learn
+rand('state', 1);
+O = 2;
+S = 2;
+A = 2;
+prior0 = [1 0]';
+transmat0 = cell(1,A);
+transmat0{1} = [0.9 0.1; 0.1 0.9]; % long runs of 1s and 2s
+transmat0{2} = [0.1 0.9; 0.9 0.1]; % short runs
+obsmat0 = eye(2);
+	   
+%prior0 = normalise(rand(S,1));
+%transmat0 = mk_stochastic(rand(S,S));
+%obsmat0 = mk_stochastic(rand(S,O));
+
+T = 10;
+act = [1*ones(1,25) 2*ones(1,25) 1*ones(1,25) 2*ones(1,25)];
+data = pomdp_sample(prior0, transmat0, obsmat0, act);
+%data = sample_dhmm(prior0, transmat0, obsmat0, T, 1);
+
+% Initial guess of params
+rand('state', 2); % different seed!
+transmat1 = cell(1,A);
+for a=1:A
+  transmat1{a} = mk_stochastic(rand(S,S));
+end
+obsmat1 = mk_stochastic(rand(S,O));
+prior1 = prior0; % so it labels states the same way
+
+% Uniformative Dirichlet prior (expected sufficient statistics / pseudo counts)
+e = 0.001;
+ess_trans = cell(1,A);
+for a=1:A
+  ess_trans{a} = repmat(e, S, S);
+end
+ess_emit = repmat(e, S, O);
+
+% Params
+w = 2;
+decay_sched = [0.1:0.1:0.9];
+
+% Initialize
+LL1 = zeros(1,T);
+t = 1;
+y = data(t);
+data_win = y;
+act_win = [1]; % arbitrary initial value
+[prior1, LL1(1)] = normalise(prior1 .* obsmat1(:,y));
+
+% Iterate
+for t=2:T
+  y = data(t);
+  a = act(t);
+  if t <= w
+    data_win = [data_win y];
+    act_win = [act_win a];
+  else
+    data_win = [data_win(2:end) y];
+    act_win = [act_win(2:end) a];
+    prior1 = gamma(:, 2);
+  end
+  d = decay_sched(min(t, length(decay_sched)));
+  [transmat1, obsmat1, ess_trans, ess_emit, gamma, ll] = dhmm_em_online(...
+      prior1, transmat1, obsmat1, ess_trans, ess_emit, d, data_win, act_win);
+  bel = gamma(:, end);
+  LL1(t) = ll/length(data_win);
+  %fprintf('t=%d, ll=%f\n', t, ll);
+end
+
+LL1(1) = LL1(2); % since initial likelihood is for 1 slice
+plot(1:T, LL1, 'rx-');
+
+
+% compare with offline learning
+
+if 0
+rand('state', 2); % same seed as online learner
+transmat2 = cell(1,A);
+for a=1:A
+  transmat2{a} = mk_stochastic(rand(S,S));
+end
+obsmat2 = mk_stochastic(rand(S,O));
+prior2 = prior0;
+[LL2, prior2, transmat2, obsmat2] = dhmm_em(data, prior2, transmat2, obsmat2, ....
+					       'max_iter', 10, 'thresh', 1e-3, 'verbose', 1, 'act', act);
+
+LL2 = LL2 / T
+
+end
diff --git a/sourcecodes/bnt-master/HMM/dhmm_logprob.m b/sourcecodes/bnt-master/HMM/dhmm_logprob.m
new file mode 100644
index 00000000..f8afe835
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/dhmm_logprob.m
@@ -0,0 +1,22 @@
+function [loglik, errors] = dhmm_logprob(data, prior, transmat, obsmat)
+% LOG_LIK_DHMM Compute the log-likelihood of a dataset using a discrete HMM
+% [loglik, errors] = log_lik_dhmm(data, prior, transmat, obsmat)
+%
+% data{m} or data(m,:) is the m'th sequence
+% errors  is a list of the cases which received a loglik of -infinity
+
+if ~iscell(data)
+  data = num2cell(data, 2);
+end
+ncases = length(data);
+
+loglik = 0;
+errors = [];
+for m=1:ncases
+  obslik = multinomial_prob(data{m}, obsmat);
+  [alpha, beta, gamma, ll] = fwdback(prior, transmat, obslik, 'fwd_only', 1);
+  if ll==-inf
+    errors = [errors m];
+  end
+  loglik = loglik + ll;
+end
diff --git a/sourcecodes/bnt-master/HMM/dhmm_logprob_brute_force.m b/sourcecodes/bnt-master/HMM/dhmm_logprob_brute_force.m
new file mode 100644
index 00000000..abffd0c9
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/dhmm_logprob_brute_force.m
@@ -0,0 +1,21 @@
+function logp = enumerate_HMM_loglik(prior, transmat, obsmat)
+% ENUMERATE_HMM_LOGLIK Compute the log likelihood of a sequence by exhaustive (O(Q^T)) enumeration.
+% logp = enumerate_HMM_loglik(prior, transmat, obsmat)
+%
+% Inputs:
+% prior(i) = Pr(Q(1) = i)
+% transmat(i,j) = Pr(Q(t+1)=j | Q(t)=i)
+% obsmat(i,t) = Pr(y(t) | Q(t)=i)
+
+Q = length(prior);
+T = size(obsmat, 2);
+sizes = repmat(Q, 1, T);
+
+psum = 0;
+for i=1:Q^T
+  qs = ind2subv(sizes, i); % make the state sequence 
+  psum = psum + prob_path(prior, transmat, obsmat, qs);
+end
+logp = log(psum)
+
+ 
diff --git a/sourcecodes/bnt-master/HMM/dhmm_logprob_path.m b/sourcecodes/bnt-master/HMM/dhmm_logprob_path.m
new file mode 100644
index 00000000..11a1e3af
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/dhmm_logprob_path.m
@@ -0,0 +1,15 @@
+function [ll, p] = prob_path(prior, transmat, obsmat, qs)
+% PROB_PATH Compute the prob. of a specific path (state sequence) through an HMM.
+% [ll, p] = prob_path(prior, transmat, obsmat, states)
+%
+% ll = log prob path
+% p(t) = Pr(O(t)) * Pr(Q(t) -> Q(t+1)) for 1<=t<T, p(T) = Pr(O(T))
+
+T = size(obsmat, 2);
+p = zeros(1,T);
+p(1) = prior(qs(1)) * obsmat(qs(1),1);
+for t=2:T
+  p(t) = transmat(qs(t-1), qs(t)) * obsmat(qs(t),t);
+end
+
+ll = sum(log(p));
diff --git a/sourcecodes/bnt-master/HMM/dhmm_sample.m b/sourcecodes/bnt-master/HMM/dhmm_sample.m
new file mode 100644
index 00000000..5122c81b
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/dhmm_sample.m
@@ -0,0 +1,10 @@
+function [obs, hidden] = dhmm_sample(initial_prob, transmat, obsmat, numex, len)
+% SAMPLE_DHMM Generate random sequences from a Hidden Markov Model with discrete outputs.
+%
+% [obs, hidden] = sample_dhmm(initial_prob, transmat, obsmat, numex, len)
+% Each row of obs is an observation sequence of length len.
+
+hidden = mc_sample(initial_prob, transmat, len, numex);
+obs = multinomial_sample(hidden, obsmat);
+
+
diff --git a/sourcecodes/bnt-master/HMM/dhmm_sample_endstate.m b/sourcecodes/bnt-master/HMM/dhmm_sample_endstate.m
new file mode 100644
index 00000000..1972ebd2
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/dhmm_sample_endstate.m
@@ -0,0 +1,19 @@
+function [obs, hidden] = dhmm_sample_endstate(startprob, transmat, obsmat, endprob, numex)
+% SAMPLE_DHMM Generate random sequences from an HMM with discrete outputs.
+% function [obs, hidden] = sample_dhmm_endstate(startprob, transmat, obsmat, endprob, numex)
+%
+% We sample until we have have entered the end state
+% obs{m} and hidden{m} are the m'th sequence
+
+hidden = cell(1,numex);
+obs = cell(1,numex);
+
+for m=1:numex
+  hidden{m} = mc_sample_endstate(startprob, transmat, endprob);
+  T = length(hidden{m});
+  obs{m} = zeros(1,T);
+  for t=1:T
+    h = hidden{m}(t);
+    obs{m}(t) = sample_discrete(obsmat(h,:));
+  end
+end
diff --git a/sourcecodes/bnt-master/HMM/fixed_lag_smoother.m b/sourcecodes/bnt-master/HMM/fixed_lag_smoother.m
new file mode 100644
index 00000000..9e19df98
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/fixed_lag_smoother.m
@@ -0,0 +1,65 @@
+function [alpha, obslik, gamma, xi] = fixed_lag_smoother(d, alpha, obslik, obsvec, transmat, act)
+% FIXED_LAG_SMOOTHER Computed smoothed posterior estimates within a window given previous filtered window.
+% [alpha, obslik, gamma, xi] = fixed_lag_smoother(d, alpha, obslik, obsvec, transmat, act)
+%
+% d >= 2 is the desired window width.
+% Actually, we use d=min(d, t0), where t0 is the current time.
+%
+% alpha(:, t0-d:t0-1) - length d window, excluding t0 (Columns indexed 1..d)
+% obslik(:, t0-d:t0-1) - length d window
+% obsvec              - likelihood vector for current observation
+% transmat            - transition matrix
+% If we specify the optional 'act' argument, transmat{a} should be a cell array, and
+% act(t0-d:t0)          - length d window, last column = current action
+%
+% Output:
+% alpha(:, t0-d+1:t0)     - last column = new filtered estimate
+% obslik(:, t0-d+1:t0)    - last column = obsvec
+% xi(:, :, t0-d+1:t0-1)   - 2 slice smoothed window
+% gamma(:, t0-d+1:t0)     - smoothed window
+%
+% As usual, we define (using T=d)
+% alpha(i,t) = Pr(Q(t)=i | Y(1:t))
+% gamma(i,t) = Pr(Q(t)=i | Y(1:T))
+% xi(i,j,t) = Pr(Q(t)=i, Q(t+1)=j | Y(1:T))
+%
+% obslik(i,t) = Pr(Y(t) | Q(t)=i) 
+% transmat{a}(i,j) = Pr(Q(t)=j | Q(t-1)=i, A(t)=a)
+
+[S n] = size(alpha); 
+d = min(d, n+1); 
+if d < 2
+  error('must keep a window of length at least 2');
+end
+
+if ~exist('act')
+  act = ones(1, n+1);
+  transmat = { transmat };
+end
+
+% pluck out last d-1 components from the history
+alpha = alpha(:, n-d+2:n); 
+obslik = obslik(:, n-d+2:n); 
+
+% Extend window by 1
+t = d;
+obslik(:,t) = obsvec;
+xi = zeros(S, S, d-1);
+xi(:,:,t-1) = normalise((alpha(:,t-1) * obslik(:,t)') .* transmat{act(t)});
+alpha(:,t) = sum(xi(:,:,t-1), 1)';
+
+% Now smooth backwards inside the window
+beta = ones(S, d);
+T = d;
+%fprintf('smooth from %d to 1, i.e., %d to %d\n', d, t0, t0-d+1);
+gamma(:,T) = alpha(:,T);
+for t=T-1:-1:1
+  b = beta(:,t+1) .* obslik(:,t+1); 
+  beta(:,t) = normalise(transmat{act(t)} * b);
+  gamma(:,t) = normalise(alpha(:,t) .* beta(:,t));
+  xi(:,:,t) = normalise((transmat{act(t)} .* (alpha(:,t) * b')));
+end
+
+
+
+
diff --git a/sourcecodes/bnt-master/HMM/fixed_lag_smoother_demo.m b/sourcecodes/bnt-master/HMM/fixed_lag_smoother_demo.m
new file mode 100644
index 00000000..9cf19f90
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/fixed_lag_smoother_demo.m
@@ -0,0 +1,38 @@
+% Example of fixed lag smoothing
+
+rand('state', 1);
+S = 2;
+O = 2;
+T = 7;
+data = sample_discrete([0.5 0.5], 1, T);
+transmat = mk_stochastic(rand(S,S));
+obsmat = mk_stochastic(rand(S,O));
+obslik = multinomial_prob(data, obsmat);
+prior = [0.5 0.5]';
+
+
+[alpha0, beta0, gamma0, ll0, xi0] = fwdback(prior, transmat, obslik);
+
+w = 3;
+alpha1 = zeros(S, T);
+gamma1 = zeros(S, T);
+xi1 = zeros(S, S, T-1);
+t = 1;
+b = obsmat(:, data(t));
+olik_win = b; % window of conditional observation likelihoods
+alpha_win = normalise(prior .* b);
+alpha1(:,t) = alpha_win;
+for t=2:T
+  [alpha_win, olik_win, gamma_win, xi_win] = ...
+      fixed_lag_smoother(w, alpha_win, olik_win, obsmat(:, data(t)), transmat);
+  alpha1(:,max(1,t-w+1):t) = alpha_win;
+  gamma1(:,max(1,t-w+1):t) = gamma_win;
+  xi1(:,:,max(1,t-w+1):t-1) = xi_win;
+end
+
+e = 1e-1;
+%assert(approxeq(alpha0, alpha1, e));
+assert(approxeq(gamma0(:, T-w+1:end), gamma1(:, T-w+1:end), e));
+%assert(approxeq(xi0(:,:,T-w+1:end), xi1(:,:,T-w+1:end), e));
+
+
diff --git a/sourcecodes/bnt-master/HMM/fwdback.m b/sourcecodes/bnt-master/HMM/fwdback.m
new file mode 100644
index 00000000..d74d5490
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/fwdback.m
@@ -0,0 +1,197 @@
+function [alpha, beta, gamma, loglik, xi_summed, gamma2] = fwdback(init_state_distrib, ...
+   transmat, obslik, varargin)
+% FWDBACK Compute the posterior probs. in an HMM using the forwards backwards algo.
+%
+% [alpha, beta, gamma, loglik, xi, gamma2] = fwdback(init_state_distrib, transmat, obslik, ...)
+%
+% Notation:
+% Y(t) = observation, Q(t) = hidden state, M(t) = mixture variable (for MOG outputs)
+% A(t) = discrete input (action) (for POMDP models)
+%
+% INPUT:
+% init_state_distrib(i) = Pr(Q(1) = i)
+% transmat(i,j) = Pr(Q(t) = j | Q(t-1)=i)
+%  or transmat{a}(i,j) = Pr(Q(t) = j | Q(t-1)=i, A(t-1)=a) if there are discrete inputs
+% obslik(i,t) = Pr(Y(t)| Q(t)=i)
+%   (Compute obslik using eval_pdf_xxx on your data sequence first.)
+%
+% Optional parameters may be passed as 'param_name', param_value pairs.
+% Parameter names are shown below; default values in [] - if none, argument is mandatory.
+%
+% For HMMs with MOG outputs: if you want to compute gamma2, you must specify
+% 'obslik2' - obslik(i,j,t) = Pr(Y(t)| Q(t)=i,M(t)=j)  []
+% 'mixmat' - mixmat(i,j) = Pr(M(t) = j | Q(t)=i)  []
+%
+% For HMMs with discrete inputs:
+% 'act' - act(t) = action performed at step t
+%
+% Optional arguments:
+% 'fwd_only' - if 1, only do a forwards pass and set beta=[], gamma2=[]  [0]
+% 'scaled' - if 1,  normalize alphas and betas to prevent underflow [1]
+% 'maximize' - if 1, use max-product instead of sum-product [0]
+%
+% OUTPUTS:
+% alpha(i,t) = p(Q(t)=i | y(1:t)) (or p(Q(t)=i, y(1:t)) if scaled=0)
+% beta(i,t) = p(y(t+1:T) | Q(t)=i)*p(y(t+1:T)|y(1:t)) (or p(y(t+1:T) | Q(t)=i) if scaled=0)
+% gamma(i,t) = p(Q(t)=i | y(1:T))
+% loglik = log p(y(1:T))
+% xi(i,j,t-1)  = p(Q(t-1)=i, Q(t)=j | y(1:T))  - NO LONGER COMPUTED
+% xi_summed(i,j) = sum_{t=}^{T-1} xi(i,j,t)  - changed made by Herbert Jaeger
+% gamma2(j,k,t) = p(Q(t)=j, M(t)=k | y(1:T)) (only for MOG  outputs)
+%
+% If fwd_only = 1, these become
+% alpha(i,t) = p(Q(t)=i | y(1:t))
+% beta = []
+% gamma(i,t) = p(Q(t)=i | y(1:t))
+% xi(i,j,t-1)  = p(Q(t-1)=i, Q(t)=j | y(1:t))
+% gamma2 = []
+%
+% Note: we only compute xi if it is requested as a return argument, since it can be very large.
+% Similarly, we only compute gamma2 on request (and if using MOG outputs).
+%
+% Examples:
+%
+% [alpha, beta, gamma, loglik] = fwdback(pi, A, multinomial_prob(sequence, B));
+%
+% [B, B2] = mixgauss_prob(data, mu, Sigma, mixmat);
+% [alpha, beta, gamma, loglik, xi, gamma2] = fwdback(pi, A, B, 'obslik2', B2, 'mixmat', mixmat);
+
+if nargout >= 5, compute_xi = 1; else compute_xi = 0; end
+if nargout >= 6, compute_gamma2 = 1; else compute_gamma2 = 0; end
+
+[obslik2, mixmat, fwd_only, scaled, act, maximize, compute_xi, compute_gamma2] = ...
+   process_options(varargin, ...
+       'obslik2', [], 'mixmat', [], ...
+       'fwd_only', 0, 'scaled', 1, 'act', [], 'maximize', 0, ...
+                   'compute_xi', compute_xi, 'compute_gamma2', compute_gamma2);
+
+[Q T] = size(obslik);
+
+if isempty(obslik2)
+ compute_gamma2 = 0;
+end
+
+if isempty(act)
+ act = ones(1,T);
+ transmat = { transmat } ;
+end
+
+scale = ones(1,T);
+
+% scale(t) = Pr(O(t) | O(1:t-1)) = 1/c(t) as defined by Rabiner (1989).
+% Hence prod_t scale(t) = Pr(O(1)) Pr(O(2)|O(1)) Pr(O(3) | O(1:2)) ... = Pr(O(1), ... ,O(T))
+% or log P = sum_t log scale(t).
+% Rabiner suggests multiplying beta(t) by scale(t), but we can instead
+% normalise beta(t) - the constants will cancel when we compute gamma.
+
+loglik = 0;
+
+alpha = zeros(Q,T);
+gamma = zeros(Q,T);
+if compute_xi
+ xi_summed = zeros(Q,Q);
+else
+ xi_summed = [];
+end
+
+%%%%%%%%% Forwards %%%%%%%%%%
+
+t = 1;
+alpha(:,1) = init_state_distrib(:) .* obslik(:,t);
+if scaled
+ %[alpha(:,t), scale(t)] = normaliseC(alpha(:,t));
+ [alpha(:,t), scale(t)] = normalise(alpha(:,t));
+end
+assert(approxeq(sum(alpha(:,t)),1))
+for t=2:T
+ %trans = transmat(:,:,act(t-1))';
+ trans = transmat{act(t-1)};
+ if maximize
+   m = max_mult(trans', alpha(:,t-1));
+   %A = repmat(alpha(:,t-1), [1 Q]);
+   %m = max(trans .* A, [], 1);
+ else
+   m = trans' * alpha(:,t-1);
+ end
+ alpha(:,t) = m(:) .* obslik(:,t);
+ if scaled
+   %[alpha(:,t), scale(t)] = normaliseC(alpha(:,t));
+   [alpha(:,t), scale(t)] = normalise(alpha(:,t));
+ end
+ if compute_xi & fwd_only  % useful for online EM
+   %xi(:,:,t-1) = normaliseC((alpha(:,t-1) * obslik(:,t)') .* trans);
+   xi_summed = xi_summed + normalise((alpha(:,t-1) * obslik(:,t)') .* trans);
+ end
+ assert(approxeq(sum(alpha(:,t)),1))
+end
+if scaled
+ if any(scale==0)
+   loglik = -inf;
+ else
+   loglik = sum(log(scale));
+ end
+else
+ loglik = log(sum(alpha(:,T)));
+end
+
+if fwd_only
+ gamma = alpha;
+ beta = [];
+ gamma2 = [];
+ return;
+end
+
+%%%%%%%%% Backwards %%%%%%%%%%
+
+beta = zeros(Q,T);
+if compute_gamma2
+ M = size(mixmat, 2);
+ gamma2 = zeros(Q,M,T);
+else
+ gamma2 = [];
+end
+
+beta(:,T) = ones(Q,1);
+%gamma(:,T) = normaliseC(alpha(:,T) .* beta(:,T));
+gamma(:,T) = normalise(alpha(:,T) .* beta(:,T));
+t=T;
+if compute_gamma2
+ denom = obslik(:,t) + (obslik(:,t)==0); % replace 0s with 1s before dividing
+ gamma2(:,:,t) = obslik2(:,:,t) .* mixmat .* repmat(gamma(:,t), [1 M]) ./ repmat(denom, [1 M]);
+ %gamma2(:,:,t) = normaliseC(obslik2(:,:,t) .* mixmat .* repmat(gamma(:,t), [1 M])); % wrong!
+end
+for t=T-1:-1:1
+ b = beta(:,t+1) .* obslik(:,t+1);
+ %trans = transmat(:,:,act(t));
+ trans = transmat{act(t)};
+ if maximize
+   B = repmat(b(:)', Q, 1);
+   beta(:,t) = max(trans .* B, [], 2);
+ else
+   beta(:,t) = trans * b;
+ end
+ if scaled
+   %beta(:,t) = normaliseC(beta(:,t));
+   beta(:,t) = normalise(beta(:,t));
+ end
+ %gamma(:,t) = normaliseC(alpha(:,t) .* beta(:,t));
+ gamma(:,t) = normalise(alpha(:,t) .* beta(:,t));
+ if compute_xi
+   %xi(:,:,t) = normaliseC((trans .* (alpha(:,t) * b')));
+   xi_summed = xi_summed + normalise((trans .* (alpha(:,t) * b')));
+ end
+ if compute_gamma2
+   denom = obslik(:,t) + (obslik(:,t)==0); % replace 0s with 1s before dividing
+   gamma2(:,:,t) = obslik2(:,:,t) .* mixmat .* repmat(gamma(:,t), [1 M]) ./ repmat(denom, [1 M]);
+   %gamma2(:,:,t) = normaliseC(obslik2(:,:,t) .* mixmat .* repmat(gamma(:,t), [1 M]));
+ end
+end
+
+% We now explain the equation for gamma2
+% Let zt=y(1:t-1,t+1:T) be all observations except y(t)
+% gamma2(Q,M,t) = P(Qt,Mt|yt,zt) = P(yt|Qt,Mt,zt) P(Qt,Mt|zt) / P(yt|zt)
+%                = P(yt|Qt,Mt) P(Mt|Qt) P(Qt|zt) / P(yt|zt)
+% Now gamma(Q,t) = P(Qt|yt,zt) = P(yt|Qt) P(Qt|zt) / P(yt|zt)
+% hence
+% P(Qt,Mt|yt,zt) = P(yt|Qt,Mt) P(Mt|Qt) [P(Qt|yt,zt) P(yt|zt) / P(yt|Qt)] / P(yt|zt)
+%                = P(yt|Qt,Mt) P(Mt|Qt) P(Qt|yt,zt) / P(yt|Qt)
diff --git a/sourcecodes/bnt-master/HMM/gausshmm_train_observed.m b/sourcecodes/bnt-master/HMM/gausshmm_train_observed.m
new file mode 100644
index 00000000..0e96b365
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/gausshmm_train_observed.m
@@ -0,0 +1,44 @@
+function [initState, transmat, mu, Sigma] = gausshmm_train_observed(obsData, hiddenData, ...
+						  nstates, varargin)
+% GAUSSHMM_TRAIN_OBSERVED  Estimate params of HMM with Gaussian output from fully observed sequences
+% [initState, transmat, mu, Sigma] = gausshmm_train_observed(obsData, hiddenData, nstates,...)
+%
+% INPUT
+% If all sequences have the same length
+% obsData(:,t,ex) 
+% hiddenData(ex,t)  - must be ROW vector if only one sequence
+% If sequences have different lengths, we use cell arrays
+% obsData{ex}(:,t) 
+% hiddenData{ex}(t)
+%
+% Optional argumnets
+% dirichletPriorWeight - for smoothing transition matrix counts
+%
+% Optional parameters from mixgauss_Mstep:
+% 'cov_type' - 'full', 'diag' or 'spherical' ['full']
+% 'tied_cov' - 1 (Sigma) or 0 (Sigma_i) [0]
+% 'clamped_cov' - pass in clamped value, or [] if unclamped [ [] ]
+% 'clamped_mean' - pass in clamped value, or [] if unclamped [ [] ]
+% 'cov_prior' - Lambda_i, added to YY(:,:,i) [0.01*eye(d,d,Q)]
+%
+% Output
+% mu(:,q)
+% Sigma(:,:,q) 
+
+[dirichletPriorWeight, other] = process_options(...
+    varargin, 'dirichletPriorWeight', 0);
+
+[transmat, initState] = transmat_train_observed(hiddenData, nstates, ...
+						'dirichletPriorWeight', dirichletPriorWeight);
+
+% convert to obsData(:,t*nex)
+if ~iscell(obsData)
+  [D T Nex] = size(obsData);
+  obsData = reshape(obsData, D, T*Nex);
+else
+  obsData = cat(2, obsData{:});
+  hiddenData = cat(2,hiddenData{:});
+end
+[mu, Sigma] = condgaussTrainObserved(obsData, hiddenData(:), nstates, varargin{:});
+
+ 
diff --git a/sourcecodes/bnt-master/HMM/mc_sample.m b/sourcecodes/bnt-master/HMM/mc_sample.m
new file mode 100644
index 00000000..87488f44
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/mc_sample.m
@@ -0,0 +1,17 @@
+function S = mc_sample(prior, trans, len, numex)
+% SAMPLE_MC Generate random sequences from a Markov chain.
+% STATE = SAMPLE_MC(PRIOR, TRANS, LEN) generates a sequence of length LEN.
+%
+% STATE = SAMPLE_MC(PRIOR, TRANS, LEN, N) generates N rows each of length LEN.
+
+if nargin==3
+  numex = 1;
+end
+
+S = zeros(numex,len);
+for i=1:numex
+  S(i, 1) = sample_discrete(prior);
+  for t=2:len
+    S(i, t) = sample_discrete(trans(S(i,t-1),:));
+  end
+end
diff --git a/sourcecodes/bnt-master/HMM/mc_sample_endstate.m b/sourcecodes/bnt-master/HMM/mc_sample_endstate.m
new file mode 100644
index 00000000..8dc9e0ba
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/mc_sample_endstate.m
@@ -0,0 +1,27 @@
+function S = sample_mc_endstate(startprob, trans, endprob)
+% SAMPLE_MC_ENDSTATE Generate a random sequence from a Markov chain until enter the endstate.
+% seq = sample_mc(startprob, trans, endprob)
+
+% add an end state
+Q = size(trans,1);
+transprob = zeros(Q,Q+1);
+end_state = Q+1;
+for i=1:Q
+  for j=1:Q
+    transprob(i,j) = (1-endprob(i)) * trans(i,j);
+  end
+  transprob(i,end_state) = endprob(i);
+  %assert(approxeq(sum(transprob(i,:)), 1))
+end                  
+
+S = [];
+S(1) = sample_discrete(startprob);
+t = 1;
+p = endprob(S(t));
+stop = (S(1) == end_state);
+while ~stop
+  S(t+1) = sample_discrete(transprob(S(t),:));
+  stop = (S(t+1) == end_state);
+  t = t + 1;
+end
+S = S(1:end-1); % don't include end state
diff --git a/sourcecodes/bnt-master/HMM/mdp_sample.m b/sourcecodes/bnt-master/HMM/mdp_sample.m
new file mode 100644
index 00000000..63923c9c
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/mdp_sample.m
@@ -0,0 +1,18 @@
+function state = sample_mdp(prior, trans, act)
+% SAMPLE_MDP Sample a sequence of states from a Markov Decision Process.
+% state = sample_mdp(prior, trans, act)
+%
+% Inputs:
+% prior(i) = Pr(Q(1)=i)
+% trans{a}(i,j) = Pr(Q(t)=j | Q(t-1)=i, A(t)=a)
+% act(a) = A(t), so act(1) is ignored
+%
+% Output:
+% state is a vector of length T=length(act)
+
+len = length(act);
+state = zeros(1,len);
+state(1) = sample_discrete(prior);
+for t=2:len
+  state(t) = sample_discrete(trans{act(t)}(state(t-1),:));
+end
diff --git a/sourcecodes/bnt-master/HMM/mhmmParzen_train_observed.m b/sourcecodes/bnt-master/HMM/mhmmParzen_train_observed.m
new file mode 100644
index 00000000..1786e9a2
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/mhmmParzen_train_observed.m
@@ -0,0 +1,37 @@
+function [initState, transmat, mu, Nproto, pick] = mhmmParzen_train_observed(obsData, hiddenData, ...
+						  nstates, maxNproto, varargin)
+% mhmmParzentrain_observed  with mixture of Gaussian outputs from fully observed sequences
+% function [initState, transmat, mu, Nproto] = mhmm_train_observed_parzen(obsData, hiddenData, ...
+%						  nstates, maxNproto)
+%
+%
+% INPUT
+% If all sequences have the same length
+% obsData(:,t,ex) 
+% hiddenData(ex,t)  - must be ROW vector if only one sequence
+% If sequences have different lengths, we use cell arrays
+% obsData{ex}(:,t) 
+% hiddenData{ex}(t)
+%
+% Optional argumnets
+% dirichletPriorWeight - for smoothing transition matrix counts
+% mkSymmetric
+%
+% Output
+% mu(:,q)
+% Nproto(q) is the number of prototypes (mixture components) chosen for state q
+
+[transmat, initState] = transmat_train_observed(...
+    hiddenData, nstates, varargin{:});
+
+% convert to obsData(:,t*nex)
+if ~iscell(obsData)
+  [D T Nex] = size(obsData);
+  obsData = reshape(obsData, D, T*Nex);
+else
+  obsData = cat(2, obsData{:});
+  hiddenData = cat(2, hiddenData{:});
+end
+[mu, Nproto, pick] = parzen_fit_select_unif(obsData, hiddenData(:), maxNproto);
+
+ 
diff --git a/sourcecodes/bnt-master/HMM/mhmm_em.m b/sourcecodes/bnt-master/HMM/mhmm_em.m
new file mode 100644
index 00000000..036c5222
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/mhmm_em.m
@@ -0,0 +1,173 @@
+function [LL, prior, transmat, mu, Sigma, mixmat] = ...
+     mhmm_em(data, prior, transmat, mu, Sigma, mixmat, varargin);
+% LEARN_MHMM Compute the ML parameters of an HMM with (mixtures of) Gaussians output using EM.
+% [ll_trace, prior, transmat, mu, sigma, mixmat] = learn_mhmm(data, ...
+%   prior0, transmat0, mu0, sigma0, mixmat0, ...) 
+%
+% Notation: Q(t) = hidden state, Y(t) = observation, M(t) = mixture variable
+%
+% INPUTS:
+% data{ex}(:,t) or data(:,t,ex) if all sequences have the same length
+% prior(i) = Pr(Q(1) = i), 
+% transmat(i,j) = Pr(Q(t+1)=j | Q(t)=i)
+% mu(:,j,k) = E[Y(t) | Q(t)=j, M(t)=k ]
+% Sigma(:,:,j,k) = Cov[Y(t) | Q(t)=j, M(t)=k]
+% mixmat(j,k) = Pr(M(t)=k | Q(t)=j) : set to [] or ones(Q,1) if only one mixture component
+%
+% Optional parameters may be passed as 'param_name', param_value pairs.
+% Parameter names are shown below; default values in [] - if none, argument is mandatory.
+%
+% 'max_iter' - max number of EM iterations [10]
+% 'thresh' - convergence threshold [1e-4]
+% 'verbose' - if 1, print out loglik at every iteration [1]
+% 'cov_type' - 'full', 'diag' or 'spherical' ['full']
+%
+% To clamp some of the parameters, so learning does not change them:
+% 'adj_prior' - if 0, do not change prior [1]
+% 'adj_trans' - if 0, do not change transmat [1]
+% 'adj_mix' - if 0, do not change mixmat [1]
+% 'adj_mu' - if 0, do not change mu [1]
+% 'adj_Sigma' - if 0, do not change Sigma [1]
+%
+% If the number of mixture components differs depending on Q, just set  the trailing
+% entries of mixmat to 0, e.g., 2 components if Q=1, 3 components if Q=2,
+% then set mixmat(1,3)=0. In this case, B2(1,3,:)=1.0.
+
+if ~isstr(varargin{1}) % catch old syntax
+  error('optional arguments should be passed as string/value pairs')
+end
+
+[max_iter, thresh, verbose, cov_type,  adj_prior, adj_trans, adj_mix, adj_mu, adj_Sigma] = ...
+    process_options(varargin, 'max_iter', 10, 'thresh', 1e-4, 'verbose', 1, ...
+		    'cov_type', 'full', 'adj_prior', 1, 'adj_trans', 1, 'adj_mix', 1, ...
+		    'adj_mu', 1, 'adj_Sigma', 1);
+  
+previous_loglik = -inf;
+loglik = 0;
+converged = 0;
+num_iter = 1;
+LL = [];
+
+if ~iscell(data)
+  data = num2cell(data, [1 2]); % each elt of the 3rd dim gets its own cell
+end
+numex = length(data);
+
+
+O = size(data{1},1);
+Q = length(prior);
+if isempty(mixmat)
+  mixmat = ones(Q,1);
+end
+M = size(mixmat,2);
+if M == 1
+  adj_mix = 0;
+end
+
+while (num_iter <= max_iter) & ~converged
+  % E step
+  [loglik, exp_num_trans, exp_num_visits1, postmix, m, ip, op] = ...
+      ess_mhmm(prior, transmat, mixmat, mu, Sigma, data);
+  
+  
+  % M step
+  if adj_prior
+    prior = normalise(exp_num_visits1);
+  end
+  if adj_trans 
+    transmat = mk_stochastic(exp_num_trans);
+  end
+  if adj_mix
+    mixmat = mk_stochastic(postmix);
+  end
+  if adj_mu | adj_Sigma
+    [mu2, Sigma2] = mixgauss_Mstep(postmix, m, op, ip, 'cov_type', cov_type);
+    if adj_mu
+      mu = reshape(mu2, [O Q M]);
+    end
+    if adj_Sigma
+      Sigma = reshape(Sigma2, [O O Q M]);
+    end
+  end
+  
+  if verbose, fprintf(1, 'iteration %d, loglik = %f\n', num_iter, loglik); end
+  num_iter =  num_iter + 1;
+  converged = em_converged(loglik, previous_loglik, thresh);
+  previous_loglik = loglik;
+  LL = [LL loglik];
+end
+
+
+%%%%%%%%%
+
+function [loglik, exp_num_trans, exp_num_visits1, postmix, m, ip, op] = ...
+    ess_mhmm(prior, transmat, mixmat, mu, Sigma, data)
+% ESS_MHMM Compute the Expected Sufficient Statistics for a MOG Hidden Markov Model.
+%
+% Outputs:
+% exp_num_trans(i,j)   = sum_l sum_{t=2}^T Pr(Q(t-1) = i, Q(t) = j| Obs(l))
+% exp_num_visits1(i)   = sum_l Pr(Q(1)=i | Obs(l))
+%
+% Let w(i,k,t,l) = P(Q(t)=i, M(t)=k | Obs(l))
+% where Obs(l) = Obs(:,:,l) = O_1 .. O_T for sequence l
+% Then 
+% postmix(i,k) = sum_l sum_t w(i,k,t,l) (posterior mixing weights/ responsibilities)
+% m(:,i,k)   = sum_l sum_t w(i,k,t,l) * Obs(:,t,l)
+% ip(i,k) = sum_l sum_t w(i,k,t,l) * Obs(:,t,l)' * Obs(:,t,l)
+% op(:,:,i,k) = sum_l sum_t w(i,k,t,l) * Obs(:,t,l) * Obs(:,t,l)'
+
+
+verbose = 0;
+
+%[O T numex] = size(data);
+numex = length(data);
+O = size(data{1},1);
+Q = length(prior);
+M = size(mixmat,2);
+exp_num_trans = zeros(Q,Q);
+exp_num_visits1 = zeros(Q,1);
+postmix = zeros(Q,M);
+m = zeros(O,Q,M);
+op = zeros(O,O,Q,M);
+ip = zeros(Q,M);
+
+mix = (M>1);
+
+loglik = 0;
+if verbose, fprintf(1, 'forwards-backwards example # '); end
+for ex=1:numex
+  if verbose, fprintf(1, '%d ', ex); end
+  %obs = data(:,:,ex);
+  obs = data{ex};
+  T = size(obs,2);
+  if mix
+    [B, B2] = mixgauss_prob(obs, mu, Sigma, mixmat);
+    [alpha, beta, gamma,  current_loglik, xi, gamma2] = ...
+	fwdback(prior, transmat, B, 'obslik2', B2, 'mixmat', mixmat);
+  else
+    B = mixgauss_prob(obs, mu, Sigma);
+    [alpha, beta, gamma,  current_loglik, xi] = fwdback(prior, transmat, B);
+  end    
+  loglik = loglik +  current_loglik; 
+  if verbose, fprintf(1, 'll at ex %d = %f\n', ex, loglik); end
+
+  exp_num_trans = exp_num_trans + sum(xi,3);
+  exp_num_visits1 = exp_num_visits1 + gamma(:,1);
+  
+  if mix
+    postmix = postmix + sum(gamma2,3);
+  else
+    postmix = postmix + sum(gamma,2); 
+    gamma2 = reshape(gamma, [Q 1 T]); % gamma2(i,m,t) = gamma(i,t)
+  end
+  for i=1:Q
+    for k=1:M
+      w = reshape(gamma2(i,k,:), [1 T]); % w(t) = w(i,k,t,l)
+      wobs = obs .* repmat(w, [O 1]); % wobs(:,t) = w(t) * obs(:,t)
+      m(:,i,k) = m(:,i,k) + sum(wobs, 2); % m(:) = sum_t w(t) obs(:,t)
+      op(:,:,i,k) = op(:,:,i,k) + wobs * obs'; % op(:,:) = sum_t w(t) * obs(:,t) * obs(:,t)'
+      ip(i,k) = ip(i,k) + sum(sum(wobs .* obs, 2)); % ip = sum_t w(t) * obs(:,t)' * obs(:,t)
+    end
+  end
+end
+if verbose, fprintf(1, '\n'); end
diff --git a/sourcecodes/bnt-master/HMM/mhmm_em_demo.m b/sourcecodes/bnt-master/HMM/mhmm_em_demo.m
new file mode 100644
index 00000000..3e361545
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/mhmm_em_demo.m
@@ -0,0 +1,40 @@
+if 1
+  O = 4;
+  T = 10;
+  nex = 50;
+  M = 2;
+  Q = 3;
+else
+  O = 8;          %Number of coefficients in a vector 
+  T = 420;         %Number of vectors in a sequence 
+  nex = 1;        %Number of sequences 
+  M = 1;          %Number of mixtures 
+  Q = 6;          %Number of states 
+end
+cov_type = 'full';
+
+data = randn(O,T,nex);
+
+% initial guess of parameters
+prior0 = normalise(rand(Q,1));
+transmat0 = mk_stochastic(rand(Q,Q));
+
+if 0
+  Sigma0 = repmat(eye(O), [1 1 Q M]);
+  % Initialize each mean to a random data point
+  indices = randperm(T*nex);
+  mu0 = reshape(data(:,indices(1:(Q*M))), [O Q M]);
+  mixmat0 = mk_stochastic(rand(Q,M));
+else
+  [mu0, Sigma0] = mixgauss_init(Q*M, data, cov_type);
+  mu0 = reshape(mu0, [O Q M]);
+  Sigma0 = reshape(Sigma0, [O O Q M]);
+  mixmat0 = mk_stochastic(rand(Q,M));
+end
+
+[LL, prior1, transmat1, mu1, Sigma1, mixmat1] = ...
+    mhmm_em(data, prior0, transmat0, mu0, Sigma0, mixmat0, 'max_iter', 5);
+
+
+loglik = mhmm_logprob(data, prior1, transmat1, mu1, Sigma1, mixmat1);
+
diff --git a/sourcecodes/bnt-master/HMM/mhmm_logprob.m b/sourcecodes/bnt-master/HMM/mhmm_logprob.m
new file mode 100644
index 00000000..e27a4eb9
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/mhmm_logprob.m
@@ -0,0 +1,30 @@
+function [loglik, errors] = mhmm_logprob(data, prior, transmat, mu, Sigma, mixmat)
+% LOG_LIK_MHMM Compute the log-likelihood of a dataset using a (mixture of) Gaussians HMM
+% [loglik, errors] = log_lik_mhmm(data, prior, transmat, mu, sigma, mixmat)
+%
+% data{m}(:,t) or data(:,t,m) if all cases have same length
+% errors  is a list of the cases which received a loglik of -infinity
+%
+% Set mixmat to ones(Q,1) or omit it if there is only 1 mixture component
+
+Q = length(prior);
+if size(mixmat,1) ~= Q % trap old syntax
+  error('mixmat should be QxM')
+end
+if nargin < 6, mixmat = ones(Q,1); end
+
+if ~iscell(data)
+  data = num2cell(data, [1 2]); % each elt of the 3rd dim gets its own cell
+end
+ncases = length(data);
+
+loglik = 0;
+errors = [];
+for m=1:ncases
+  obslik = mixgauss_prob(data{m}, mu, Sigma, mixmat);
+  [alpha, beta, gamma, ll] = fwdback(prior, transmat, obslik, 'fwd_only', 1);
+  if ll==-inf
+    errors = [errors m];
+  end
+  loglik = loglik + ll;
+end
diff --git a/sourcecodes/bnt-master/HMM/mhmm_sample.m b/sourcecodes/bnt-master/HMM/mhmm_sample.m
new file mode 100644
index 00000000..83034cd4
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/mhmm_sample.m
@@ -0,0 +1,31 @@
+function [obs, hidden] = mhmm_sample(T, numex, initial_prob, transmat, mu, Sigma, mixmat)
+% SAMPLE_MHMM Generate random sequences from an HMM with (mixtures of) Gaussian output.
+% [obs, hidden] = sample_mhmm(T, numex, initial_prob, transmat, mu, Sigma, mixmat)
+%
+% INPUTS:
+% T - length of each sequence
+% numex - num. sequences
+% init_state_prob(i) = Pr(Q(1) = i)
+% transmat(i,j) = Pr(Q(t+1)=j | Q(t)=i)
+% mu(:,j,k) = mean of Y(t) given Q(t)=j, M(t)=k
+% Sigma(:,:,j,k) = cov. of Y(t) given Q(t)=j, M(t)=k
+% mixmat(j,k) = Pr(M(t)=k | Q(t)=j) : set to ones(Q,1) or omit if single mixture
+%
+% OUTPUT:
+% obs(:,t,l) = observation vector at time t for sequence l
+% hidden(t,l) = the hidden state at time t for sequence l
+
+Q = length(initial_prob);
+if nargin < 7, mixmat = ones(Q,1); end
+O = size(mu,1);
+hidden = zeros(T, numex);
+obs = zeros(O, T, numex);
+
+hidden = mc_sample(initial_prob, transmat, T, numex)';
+for i=1:numex
+  for t=1:T
+    q = hidden(t,i);
+    m = sample_discrete(mixmat(q,:), 1, 1);
+    obs(:,t,i) =  gaussian_sample(mu(:,q,m), Sigma(:,:,q,m), 1);
+  end
+end
diff --git a/sourcecodes/bnt-master/HMM/mk_leftright_transmat.m b/sourcecodes/bnt-master/HMM/mk_leftright_transmat.m
new file mode 100644
index 00000000..8a36e1a6
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/mk_leftright_transmat.m
@@ -0,0 +1,6 @@
+function transmat = mk_leftright_transmat(Q, p)
+% MK_LEFTRIGHT_TRANSMAT Q = num states, p = prob on (i,i), 1-p on (i,i+1)
+% function transmat = mk_leftright_transmat(Q, p)
+
+transmat = p*diag(ones(Q,1)) + (1-p)*diag(ones(Q-1,1),1);
+transmat(Q,Q)=1;
diff --git a/sourcecodes/bnt-master/HMM/mk_rightleft_transmat.m b/sourcecodes/bnt-master/HMM/mk_rightleft_transmat.m
new file mode 100644
index 00000000..ce7cf62b
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/mk_rightleft_transmat.m
@@ -0,0 +1,6 @@
+function transmat = mk_rightleft_transmat(Q, p)
+% MK_RIGHTLEFT_TRANSMAT Q = num states, p = prob on (i,i), 1-p on (i,i+1)
+% function transmat = mk_rightleft_transmat(Q, p)
+
+transmat = p*diag(ones(Q,1)) + (1-p)*diag(ones(Q-1,1),-1);
+transmat(1,1)=1;
diff --git a/sourcecodes/bnt-master/HMM/pomdp_sample.m b/sourcecodes/bnt-master/HMM/pomdp_sample.m
new file mode 100644
index 00000000..836ce39f
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/pomdp_sample.m
@@ -0,0 +1,20 @@
+function [obs, hidden] = pomdp_sample(initial_prob, transmat, obsmat, act)
+% SAMPLE_POMDP Generate a random sequence from a Partially Observed Markov Decision Process.
+% [obs, hidden] = sample_pomdp(prior, transmat, obsmat, act)
+%
+% Inputs:
+% prior(i) = Pr(Q(1)=i)
+% transmat{a}(i,j) = Pr(Q(t)=j | Q(t-1)=i, A(t)=a)
+% obsmat(i,k) = Pr(Y(t)=k | Q(t)=i)
+% act(a) = A(t), so act(1) is ignored
+%
+% Output:
+% obs and hidden are vectors of length T=length(act)
+
+
+len = length(act);
+hidden = mdp_sample(initial_prob, transmat, act);
+obs = zeros(1, len);
+for t=1:len
+  obs(t) = sample_discrete(obsmat(hidden(t),:));
+end
diff --git a/sourcecodes/bnt-master/HMM/testHMM.m b/sourcecodes/bnt-master/HMM/testHMM.m
new file mode 100644
index 00000000..b3ced724
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/testHMM.m
@@ -0,0 +1,5 @@
+% Run all the demos, to check everything is "syntactically correct"
+mhmm_em_demo
+dhmm_em_demo
+dhmm_em_online_demo
+fixed_lag_smoother_demo
diff --git a/sourcecodes/bnt-master/HMM/transmat_train_observed.m b/sourcecodes/bnt-master/HMM/transmat_train_observed.m
new file mode 100644
index 00000000..06918429
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/transmat_train_observed.m
@@ -0,0 +1,39 @@
+function [transmat, initState] = transmat_train_observed(labels,  nstates, varargin)
+% transmat_train_observed ML estimation from fully observed data
+% function [transmat, initState] = transmat_train_observed(labels,  nstates, varargin)
+%
+% If all sequences have the same length
+% labels(ex,t)
+% If sequences have different lengths, we use cell arrays
+% labels{ex}(t)
+
+[dirichletPriorWeight, mkSymmetric, other] = process_options(...
+    varargin, 'dirichletPriorWeight', 0, 'mkSymmetric', 0);
+
+if ~iscell(labels)
+  [numex T] = size(labels);
+  if T==1
+    labels = labels';
+  end
+  %fprintf('T=%d, numex=%d\n', T, numex);
+  labels = num2cell(labels,2); % each row gets its own cell
+end
+numex = length(labels);
+
+counts = zeros(nstates, nstates);
+counts1 = zeros(nstates,1);
+for s=1:numex
+  labs = labels{s}; labs = labs(:)';
+  dat = [labs(1:end-1); labs(2:end)];
+  counts = counts + compute_counts(dat, [nstates nstates]);
+  q = labs(1);
+  counts1(q) = counts1(q) + 1;
+end
+pseudo_counts = dirichletPriorWeight*ones(nstates, nstates);
+if mkSymmetric
+  counts = counts + counts';
+end
+transmat = mk_stochastic(counts + pseudo_counts);
+initState = normalize(counts1 + dirichletPriorWeight*ones(nstates,1));
+
+  
diff --git a/sourcecodes/bnt-master/HMM/viterbi_path.m b/sourcecodes/bnt-master/HMM/viterbi_path.m
new file mode 100644
index 00000000..88010277
--- /dev/null
+++ b/sourcecodes/bnt-master/HMM/viterbi_path.m
@@ -0,0 +1,62 @@
+function path = viterbi_path(prior, transmat, obslik)
+% VITERBI Find the most-probable (Viterbi) path through the HMM state trellis.
+% path = viterbi(prior, transmat, obslik)
+%
+% Inputs:
+% prior(i) = Pr(Q(1) = i)
+% transmat(i,j) = Pr(Q(t+1)=j | Q(t)=i)
+% obslik(i,t) = Pr(y(t) | Q(t)=i)
+%
+% Outputs:
+% path(t) = q(t), where q1 ... qT is the argmax of the above expression.
+
+
+% delta(j,t) = prob. of the best sequence of length t-1 and then going to state j, and O(1:t)
+% psi(j,t) = the best predecessor state, given that we ended up in state j at t
+
+scaled = 1;
+
+T = size(obslik, 2);
+prior = prior(:);
+Q = length(prior);
+
+delta = zeros(Q,T);
+psi = zeros(Q,T);
+path = zeros(1,T);
+scale = ones(1,T);
+
+
+t=1;
+delta(:,t) = prior .* obslik(:,t);
+if scaled
+  [delta(:,t), n] = normalise(delta(:,t));
+  scale(t) = 1/n;
+end
+psi(:,t) = 0; % arbitrary value, since there is no predecessor to t=1
+for t=2:T
+  for j=1:Q
+    [delta(j,t), psi(j,t)] = max(delta(:,t-1) .* transmat(:,j));
+    delta(j,t) = delta(j,t) * obslik(j,t);
+  end
+  if scaled
+    [delta(:,t), n] = normalise(delta(:,t));
+    scale(t) = 1/n;
+  end
+end
+[p, path(T)] = max(delta(:,T));
+for t=T-1:-1:1
+  path(t) = psi(path(t+1),t+1);
+end
+
+% If scaled==0, p = prob_path(best_path)
+% If scaled==1, p = Pr(replace sum with max and proceed as in the scaled forwards algo)
+% Both are different from p(data) as computed using the sum-product (forwards) algorithm
+
+if 0
+if scaled
+  loglik = -sum(log(scale));
+  %loglik = prob_path(prior, transmat, obslik, path);
+else
+  loglik = log(p);
+end
+end