From 8070dc963753142bb86c4ed698d91fd623ed28e7 Mon Sep 17 00:00:00 2001 From: ziejd2 Date: Thu, 28 Sep 2017 15:04:40 -0500 Subject: 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 --- sourcecodes/bnt-master/HMM/CVS/Entries | 29 +++ sourcecodes/bnt-master/HMM/CVS/Repository | 1 + sourcecodes/bnt-master/HMM/CVS/Root | 1 + sourcecodes/bnt-master/HMM/README.txt | 23 +++ sourcecodes/bnt-master/HMM/dhmm_em.m | 124 +++++++++++++ sourcecodes/bnt-master/HMM/dhmm_em_demo.m | 25 +++ sourcecodes/bnt-master/HMM/dhmm_em_online.m | 80 +++++++++ sourcecodes/bnt-master/HMM/dhmm_em_online_demo.m | 93 ++++++++++ sourcecodes/bnt-master/HMM/dhmm_logprob.m | 22 +++ .../bnt-master/HMM/dhmm_logprob_brute_force.m | 21 +++ sourcecodes/bnt-master/HMM/dhmm_logprob_path.m | 15 ++ sourcecodes/bnt-master/HMM/dhmm_sample.m | 10 ++ sourcecodes/bnt-master/HMM/dhmm_sample_endstate.m | 19 ++ sourcecodes/bnt-master/HMM/fixed_lag_smoother.m | 65 +++++++ .../bnt-master/HMM/fixed_lag_smoother_demo.m | 38 ++++ sourcecodes/bnt-master/HMM/fwdback.m | 197 +++++++++++++++++++++ .../bnt-master/HMM/gausshmm_train_observed.m | 44 +++++ sourcecodes/bnt-master/HMM/mc_sample.m | 17 ++ sourcecodes/bnt-master/HMM/mc_sample_endstate.m | 27 +++ sourcecodes/bnt-master/HMM/mdp_sample.m | 18 ++ .../bnt-master/HMM/mhmmParzen_train_observed.m | 37 ++++ sourcecodes/bnt-master/HMM/mhmm_em.m | 173 ++++++++++++++++++ sourcecodes/bnt-master/HMM/mhmm_em_demo.m | 40 +++++ sourcecodes/bnt-master/HMM/mhmm_logprob.m | 30 ++++ sourcecodes/bnt-master/HMM/mhmm_sample.m | 31 ++++ sourcecodes/bnt-master/HMM/mk_leftright_transmat.m | 6 + sourcecodes/bnt-master/HMM/mk_rightleft_transmat.m | 6 + sourcecodes/bnt-master/HMM/pomdp_sample.m | 20 +++ sourcecodes/bnt-master/HMM/testHMM.m | 5 + .../bnt-master/HMM/transmat_train_observed.m | 39 ++++ sourcecodes/bnt-master/HMM/viterbi_path.m | 62 +++++++ 31 files changed, 1318 insertions(+) create mode 100644 sourcecodes/bnt-master/HMM/CVS/Entries create mode 100644 sourcecodes/bnt-master/HMM/CVS/Repository create mode 100644 sourcecodes/bnt-master/HMM/CVS/Root create mode 100644 sourcecodes/bnt-master/HMM/README.txt create mode 100644 sourcecodes/bnt-master/HMM/dhmm_em.m create mode 100644 sourcecodes/bnt-master/HMM/dhmm_em_demo.m create mode 100644 sourcecodes/bnt-master/HMM/dhmm_em_online.m create mode 100644 sourcecodes/bnt-master/HMM/dhmm_em_online_demo.m create mode 100644 sourcecodes/bnt-master/HMM/dhmm_logprob.m create mode 100644 sourcecodes/bnt-master/HMM/dhmm_logprob_brute_force.m create mode 100644 sourcecodes/bnt-master/HMM/dhmm_logprob_path.m create mode 100644 sourcecodes/bnt-master/HMM/dhmm_sample.m create mode 100644 sourcecodes/bnt-master/HMM/dhmm_sample_endstate.m create mode 100644 sourcecodes/bnt-master/HMM/fixed_lag_smoother.m create mode 100644 sourcecodes/bnt-master/HMM/fixed_lag_smoother_demo.m create mode 100644 sourcecodes/bnt-master/HMM/fwdback.m create mode 100644 sourcecodes/bnt-master/HMM/gausshmm_train_observed.m create mode 100644 sourcecodes/bnt-master/HMM/mc_sample.m create mode 100644 sourcecodes/bnt-master/HMM/mc_sample_endstate.m create mode 100644 sourcecodes/bnt-master/HMM/mdp_sample.m create mode 100644 sourcecodes/bnt-master/HMM/mhmmParzen_train_observed.m create mode 100644 sourcecodes/bnt-master/HMM/mhmm_em.m create mode 100644 sourcecodes/bnt-master/HMM/mhmm_em_demo.m create mode 100644 sourcecodes/bnt-master/HMM/mhmm_logprob.m create mode 100644 sourcecodes/bnt-master/HMM/mhmm_sample.m create mode 100644 sourcecodes/bnt-master/HMM/mk_leftright_transmat.m create mode 100644 sourcecodes/bnt-master/HMM/mk_rightleft_transmat.m create mode 100644 sourcecodes/bnt-master/HMM/pomdp_sample.m create mode 100644 sourcecodes/bnt-master/HMM/testHMM.m create mode 100644 sourcecodes/bnt-master/HMM/transmat_train_observed.m create mode 100644 sourcecodes/bnt-master/HMM/viterbi_path.m (limited to 'sourcecodes/bnt-master/HMM') 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