diff options
| author | ziejd2 | 2017-09-28 15:04:40 -0500 |
|---|---|---|
| committer | ziejd2 | 2017-09-28 15:04:40 -0500 |
| commit | 8070dc963753142bb86c4ed698d91fd623ed28e7 (patch) | |
| tree | d0f6dd8fc46a49b819aa55c1a90faa14d8448883 /sourcecodes/bnt-master/BNT/inference/online | |
| parent | 7cc31810d53176e805532b2789955f4eedbce6bb (diff) | |
| download | BNW-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')
71 files changed, 1222 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Entries new file mode 100644 index 00000000..9e03c43e --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Entries @@ -0,0 +1,6 @@ +/bnet_from_engine.m/1.1.1.1/Wed May 29 15:59:56 2002// +/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002// +/filter_engine.m/1.1.1.1/Wed May 29 15:59:56 2002// +/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002// +/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002// +D diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Repository new file mode 100644 index 00000000..02b22e5e --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Repository @@ -0,0 +1 @@ +FullBNT/BNT/inference/online/@filter_engine diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Root new file mode 100644 index 00000000..f3bd14a6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Root @@ -0,0 +1 @@ +:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/bnet_from_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/bnet_from_engine.m new file mode 100644 index 00000000..b57ee5f4 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/bnet_from_engine.m @@ -0,0 +1,5 @@ +function bnet = bnet_from_engine(engine) +% BNET_FROM_ENGINE Return the bnet structure stored inside the engine (smoother_engine) +% bnet = bnet_from_engine(engine) + +bnet = bnet_from_engine(engine.tbn_engine); diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/enter_evidence.m new file mode 100644 index 00000000..ab360c68 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/enter_evidence.m @@ -0,0 +1,14 @@ +function [engine, LL] = enter_evidence(engine, ev, t) +% ENTER_EVIDENCE Call the online filter +% [engine, loglik] = enter_evidence(engine, evidence, ...) +% +% evidence{i} = [] if if X(i) is hidden, and otherwise contains its observed value (scalar or column vector) + +engine.old_f = engine.f; +if t==1 + [engine.f, LL] = fwd1(engine.tbn_engine, ev, 1); +else + [engine.f, LL] = fwd(engine.tbn_engine, engine.old_f, ev, t); +end +engine.b = backT(engine.tbn_engine, engine.f, t); +engine.t = t; diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/filter_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/filter_engine.m new file mode 100644 index 00000000..437a247e --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/filter_engine.m @@ -0,0 +1,10 @@ +function engine = filter_engine(tbn_engine) +% FILTER_ENGINE Create an engine which does online filtering +% function engine = filter_engine(tbn_engine) + +engine.tbn_engine = tbn_engine; +engine.f = []; % space to store filtered message +engine.old_f = []; +engine.b = []; % space to store smoothed message +engine.t = []; +engine = class(engine, 'filter_engine'); diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_family.m new file mode 100644 index 00000000..21faea53 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_family.m @@ -0,0 +1,11 @@ +function marginal = marginal_family(engine, i, t, add_ev) +% MARGINAL_FAMILY Compute the joint distribution on a set of family (filter_engine) +% function marginal = marginal_family(engine, i, t, add_ev) + +if nargin < 4, add_ev = 0; end + +if t ~= engine.t + error('mixed up time stamps') +end + +marginal = marginal_family(engine.tbn_engine, engine.b, i, t, add_ev); diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_nodes.m new file mode 100644 index 00000000..4d83ea93 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_nodes.m @@ -0,0 +1,10 @@ +function marginal = marginal_nodes(engine, nodes, t, add_ev) +% MARGINAL_NODES Compute the joint distribution on a set of nodes (filter_engine) +% function marginal = marginal_nodes(engine, nodes, t, add_ev) + +if nargin < 4, add_ev = 0; end + +if t ~= engine.t + error('mixed up time stamps') +end +marginal = marginal_nodes(engine.tbn_engine, engine.b, nodes, t, add_ev); 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)); + diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Entries new file mode 100644 index 00000000..b64945b2 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Entries @@ -0,0 +1,13 @@ +/back.m/1.1.1.1/Mon Jun 17 23:34:12 2002// +/back1.m/1.1.1.1/Mon Jun 17 23:34:26 2002// +/back1_mpe.m/1.1.1.1/Mon Jun 17 23:49:40 2002// +/backT.m/1.1.1.1/Mon Jun 17 23:34:20 2002// +/backT_mpe.m/1.1.1.1/Mon Jun 17 23:38:56 2002// +/back_mpe.m/1.1.1.1/Sun Jul 21 00:32:52 2002// +/fwd.m/1.1.1.1/Mon Jun 17 23:46:06 2002// +/fwd1.m/1.1.1.1/Mon Jun 17 23:46:20 2002// +/jtree_2TBN_inf_engine.m/1.1.1.1/Thu Nov 14 16:31:58 2002// +/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002// +/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002// +/set_fields.m/1.1.1.1/Sun Jul 21 01:25:30 2002// +D diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Entries.Log new file mode 100644 index 00000000..24f16336 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Entries.Log @@ -0,0 +1 @@ +A D/Old//// diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Repository new file mode 100644 index 00000000..7f0022ff --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Repository @@ -0,0 +1 @@ +FullBNT/BNT/inference/online/@jtree_2TBN_inf_engine diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Root new file mode 100644 index 00000000..f3bd14a6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Root @@ -0,0 +1 @@ +:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Entries new file mode 100644 index 00000000..794b5de2 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Entries @@ -0,0 +1,2 @@ +/jtree_2TBN_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002// +D diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Repository new file mode 100644 index 00000000..a7b1e665 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Repository @@ -0,0 +1 @@ +FullBNT/BNT/inference/online/@jtree_2TBN_inf_engine/Old diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Root new file mode 100644 index 00000000..f3bd14a6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Root @@ -0,0 +1 @@ +:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/jtree_2TBN_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/jtree_2TBN_inf_engine.m new file mode 100644 index 00000000..b271e583 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/jtree_2TBN_inf_engine.m @@ -0,0 +1,116 @@ +function engine = jtree_2TBN_inf_engine(bnet, varargin) +% JTREE_ONLINE_INF_ENGINE Online Junction tree inference algorithm for DBNs. +% engine = jtree_online_inf_engine(bnet, ...) +% +% The following optional arguments can be specified in the form of name/value pairs: +% [default value in brackets] +% +% clusters - specifies variables that must be grouped in the 1.5 slice DBN +% maximize - 1 means do max-product, 0 means sum-product [0] +% +% The same nodes must be observed in every slice. + +ss = length(bnet.intra); +clusters = {}; +engine.maximize = 0; + +args = varargin; +nargs = length(args); +for i=1:2:length(args) + switch args{i}, + case 'clusters', clusters = args{i+1}; + case 'maximize', engine.maximize = args{i+1}; + otherwise, error(['unrecognized argument ' args{i}]) + end +end + +engine.evidence = []; +engine.node_sizes = []; + +%int = compute_interface_nodes(bnet.intra, bnet.inter); +int = []; + +if 1 +% include nodes with any outgoing arcs +for u=1:ss + if any(bnet.inter(u,:)) + int = [int u]; + end +end +end + +if 0 +% include nodes with any incoming arcs +incoming = []; +for u=1:ss + if any(bnet.inter(:,u)) + int = [int u]; + incoming = [incoming u]; + end +end +% include nodes which are parents of nodes with incoming +for u=1:ss + cs = children(bnet.intra, u); + if ~isempty(cs) & mysubset(cs, incoming) + int = [int u]; + end +end +int = unique(int); +end % if + +int +engine.interface = int; +engine.nonint = mysetdiff(1:ss, int); + +onodes = bnet.observed; + +% Create a "1.5 slice" jtree, containing the interface nodes of slice 1 +% and all the nodes of slice 2 +% To keep the node numbering the same, we simply disconnect the non-interface nodes +% from slice 1, and set their size to 1. +% We do this to speed things up, and so that the likelihood is computed correctly - we do not need to do +% this if we just want to compute marginals (i.e., we can include nodes whose potentials will +% be left as all 1s). +intra15 = bnet.intra; +for i=engine.nonint(:)' + intra15(:,i) = 0; + intra15(i,:) = 0; +end +dag15 = [intra15 bnet.inter; + zeros(ss) bnet.intra]; +ns = bnet.node_sizes(:); +%ns(engine.nonint) = 1; % disconnected nodes get size 1 +obs_nodes = [onodes(:) onodes(:)+ss]; +bnet15 = mk_bnet(dag15, ns, 'discrete', bnet.dnodes, 'equiv_class', bnet.equiv_class(:), ... + 'observed', obs_nodes(:)); + +% use unconstrained elimination, +% but force there to be a clique containing both interfaces +clusters(end+1:end+2) = {int, int+ss}; +engine.jtree_engine = jtree_inf_engine(bnet15, 'clusters', clusters, 'root', int+ss); +jtree_engine = struct(engine.jtree_engine); % violate object privacy + +engine.in_clq = clq_containing_nodes(engine.jtree_engine, int); +engine.out_clq = clq_containing_nodes(engine.jtree_engine, int+ss); +engine.clq_ass_to_node = jtree_engine.clq_ass_to_node; +engine.root = jtree_engine.root_clq; + +% Also create an engine just for slice 1 +bnet1 = mk_bnet(bnet.intra1, bnet.node_sizes_slice, 'discrete', myintersect(bnet.dnodes,1:ss), ... + 'equiv_class', bnet.equiv_class(:,1), 'observed', onodes); +for i=1:max(bnet1.equiv_class) + bnet1.CPD{i} = bnet.CPD{i}; +end +engine.jtree_engine1 = jtree_inf_engine(bnet1, 'clusters', {int}, 'root', int); +jtree_engine1 = struct(engine.jtree_engine1); % violate object privacy +engine.int_clq1 = clq_containing_nodes(engine.jtree_engine1, int); +engine.clq_ass_to_node1 = jtree_engine1.clq_ass_to_node; +engine.root1 = jtree_engine1.root_clq; + +engine.observed = [onodes onodes+ss]; +engine.observed1 = onodes; +engine.pot_type = determine_pot_type(bnet, onodes); +engine.slice_size = bnet.nnodes_per_slice; + +engine = class(engine, 'jtree_2TBN_inf_engine', inf_engine(bnet)); + diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back.m new file mode 100644 index 00000000..7f686d55 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back.m @@ -0,0 +1,27 @@ +function b = back(engine, bfuture, f, t) + +if f.t ~= t + error('mixed up time stamps') +end +if t==1 + b = back1(engine, bfuture, f, t); + return; +end + +bnet = bnet_from_engine(engine); +ss = bnet.nnodes_per_slice; + +int = engine.interface; +D = engine.in_clq; +C = engine.out_clq; +phiD = marginalize_pot(bfuture.clpot{D}, int, engine.maximize); +phiD = set_domain_pot(phiD, int+ss); % shift to slice 2 +phiC = marginalize_pot(f.clpot{C}, int+ss, engine.maximize); +ratio = divide_by_pot(phiD, phiC); +f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio); + +[b.clpot, seppot] = distribute_evidence(engine.jtree_engine, f.clpot, f.seppot); +for c=1:length(b.clpot) + [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c}); +end +b.t = t; diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1.m new file mode 100644 index 00000000..a8587a72 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1.m @@ -0,0 +1,21 @@ +function b = back1(engine, bfuture, f, t) + +if t ~= 1 + error('mixed up time stamps') +end +bnet = bnet_from_engine(engine); +ss = bnet.nnodes_per_slice; + +int = engine.interface; +D = engine.in_clq; % from J2 +C = engine.int_clq1; % from J1 +phiD = marginalize_pot(bfuture.clpot{D}, int, engine.maximize); +phiC = marginalize_pot(f.clpot{C}, int, engine.maximize); +ratio = divide_by_pot(phiD, phiC); +f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio); + +[b.clpot, seppot] = distribute_evidence(engine.jtree_engine1, f.clpot, f.seppot); +for c=1:length(b.clpot) + [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c}); +end +b.t = t; diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1_mpe.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1_mpe.m new file mode 100644 index 00000000..b20bfa57 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1_mpe.m @@ -0,0 +1,22 @@ +function [b, mpe] = back1_mpe(engine, bfuture, f, ev1, t) + +if t ~= 1 + error('mixed up time stamps') +end +bnet = bnet_from_engine(engine); +ss = bnet.nnodes_per_slice; +maximize = 1; + +int = engine.interface; +D = engine.in_clq; % from J2 +C = engine.int_clq1; % from J1 +phiD = marginalize_pot(bfuture.clpot{D}, int, maximize); +phiC = marginalize_pot(f.clpot{C}, int, maximize); +ratio = divide_by_pot(phiD, phiC); +f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio); + +[mpe, b.clpot] = find_max_config(engine.jtree_engine1, f.clpot, f.seppot, ev1); +for c=1:length(b.clpot) + [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c}); +end +b.t = t; diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT.m new file mode 100644 index 00000000..7f7a1b42 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT.m @@ -0,0 +1,11 @@ +function b = backT(engine, f, t) + +if t==1 + [b.clpot, seppot] = distribute_evidence(engine.jtree_engine1, f.clpot, f.seppot); +else + [b.clpot, seppot] = distribute_evidence(engine.jtree_engine, f.clpot, f.seppot); +end +for c=1:length(b.clpot) + [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c}); +end +b.t = t; diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT_mpe.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT_mpe.m new file mode 100644 index 00000000..93084eae --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT_mpe.m @@ -0,0 +1,16 @@ +function [b, mpe] = backT_mpe(engine, f, ev2, t) + +bnet = bnet_from_engine(engine); +ss = bnet.nnodes_per_slice; + +if t==1 + % ev2 is just the evidence on slice 1 + [mpe, b.clpot] = find_max_config(engine.jtree_engine1, f.clpot, f.seppot, ev2); +else + [mpe, b.clpot] = find_max_config(engine.jtree_engine, f.clpot, f.seppot, ev2); + mpe = mpe((1:ss)+ss); % extract values for slice 2 +end +for c=1:length(b.clpot) + [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c}); +end +b.t = t; diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back_mpe.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back_mpe.m new file mode 100644 index 00000000..9fdba411 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back_mpe.m @@ -0,0 +1,28 @@ +function [b, mpe] = back_mpe(engine, bfuture, f, ev2, t) + +if f.t ~= t + error('mixed up time stamps') +end +if t==1 + error('should call back1_mpe') +end + +maximize = 1; +bnet = bnet_from_engine(engine); +ss = bnet.nnodes_per_slice; + +int = engine.interface; +D = engine.in_clq; +C = engine.out_clq; +phiD = marginalize_pot(bfuture.clpot{D}, int, maximize); +phiD = set_domain_pot(phiD, int+ss); % shift to slice 2 +phiC = marginalize_pot(f.clpot{C}, int+ss, maximize); +ratio = divide_by_pot(phiD, phiC); +f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio); + +[mpe, b.clpot] = find_max_config(engine.jtree_engine, f.clpot, f.seppot, ev2); +mpe = mpe((1:ss)+ss); % extract values for slice 2 +for c=1:length(b.clpot) + [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c}); +end +b.t = t; diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd.m new file mode 100644 index 00000000..9c59cc3b --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd.m @@ -0,0 +1,44 @@ +function [f, logscale] = fwd(engine, fpast, ev, t) +% Forwards pass. + +bnet = bnet_from_engine(engine); +ss = bnet.nnodes_per_slice; + +ev2 = cell(ss, 2); +ev2(:,1) = fpast.evidence; +ev2(:,2) = ev; + +CPDpot = cell(1,ss); +for n=1:ss + fam = family(bnet.dag, n, 2); + e = bnet.equiv_class(n, 2); + CPDpot{n} = convert_to_pot(bnet.CPD{e}, engine.pot_type, fam(:), ev2); +end +f.evidence = ev; +f.t = t; + +% get prior +int = engine.interface; +if fpast.t==1 + prior = marginalize_pot(fpast.clpot{engine.int_clq1}, int, engine.maximize); +else + prior = marginalize_pot(fpast.clpot{engine.out_clq}, int+ss, engine.maximize); + prior = set_domain_pot(prior, int); % shift back to slice 1 +end + +pots = [ {prior} CPDpot ]; +slice1 = 1:ss; +slice2 = slice1 + ss; +CPDclqs = engine.clq_ass_to_node(slice2); +D = engine.in_clq; +clqs = [D CPDclqs]; + +[f.clpot, f.seppot] = init_pot(engine.jtree_engine, clqs, pots, engine.pot_type, engine.observed); +[f.clpot, f.seppot] = collect_evidence(engine.jtree_engine, f.clpot, f.seppot); +for c=1:length(f.clpot) + [f.clpot{c}, ll(c)] = normalize_pot(f.clpot{c}); +end +logscale = ll(engine.root); + + + diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd1.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd1.m new file mode 100644 index 00000000..68de1e50 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd1.m @@ -0,0 +1,26 @@ +function [f, logscale] = fwd1(engine, ev, t) +% Forwards pass for slice 1. + +bnet = bnet_from_engine(engine); +ss = bnet.nnodes_per_slice; + +CPDpot = cell(1,ss); +for n=1:ss + fam = family(bnet.dag, n, 1); + e = bnet.equiv_class(n, 1); + CPDpot{n} = convert_to_pot(bnet.CPD{e}, engine.pot_type, fam(:), ev); +end +f.t = t; +f.evidence = ev; + +pots = CPDpot; +slice1 = 1:ss; +CPDclqs = engine.clq_ass_to_node1(slice1); + +[f.clpot, f.seppot] = init_pot(engine.jtree_engine1, CPDclqs, CPDpot, engine.pot_type, engine.observed1); +[f.clpot, f.seppot] = collect_evidence(engine.jtree_engine1, f.clpot, f.seppot); +for c=1:length(f.clpot) + [f.clpot{c}, ll(c)] = normalize_pot(f.clpot{c}); +end +logscale = ll(engine.root1); + diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/jtree_2TBN_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/jtree_2TBN_inf_engine.m new file mode 100644 index 00000000..2d56445c --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/jtree_2TBN_inf_engine.m @@ -0,0 +1,69 @@ +function engine = jtree_2TBN_inf_engine(bnet, varargin) +% JTREE_ONLINE_INF_ENGINE Online Junction tree inference algorithm for DBNs. +% engine = jtree_online_inf_engine(bnet, ...) +% +% The following optional arguments can be specified in the form of name/value pairs: +% [default value in brackets] +% +% clusters - specifies variables that must be grouped in the 1.5 slice DBN +% +% The same nodes must be observed in every slice. +% +% This uses the forwards interface of slice t-1 plus all of slice t. +% By contrast, jtree_dbn uses all of slice t-1 plus the backwards interface of slice t. +% See my thesis for details. + + +clusters = {}; + +args = varargin; +nargs = length(args); +for i=1:2:length(args) + switch args{i}, + case 'clusters', clusters = args{i+1}; + otherwise, error(['unrecognized argument ' args{i}]) + end +end + +engine.maximize = 0; +engine.evidence = []; +engine.node_sizes = []; + +int = compute_fwd_interface(bnet.intra, bnet.inter); +engine.interface = int; +ss = length(bnet.intra); +engine.nonint = mysetdiff(1:ss, int); +onodes = bnet.observed; + +bnet15 = mk_slice_and_half_dbn(bnet, int); + +% use unconstrained elimination, +% but force there to be a clique containing both interfaces +clusters(end+1:end+2) = {int, int+ss}; +engine.jtree_engine = jtree_inf_engine(bnet15, 'clusters', clusters, 'root', int+ss); +jtree_engine = struct(engine.jtree_engine); % violate object privacy + +engine.in_clq = clq_containing_nodes(engine.jtree_engine, int); +engine.out_clq = clq_containing_nodes(engine.jtree_engine, int+ss); +engine.clq_ass_to_node = jtree_engine.clq_ass_to_node; +engine.root = jtree_engine.root_clq; + +% Also create an engine just for slice 1 +bnet1 = mk_bnet(bnet.intra1, bnet.node_sizes_slice, 'discrete', myintersect(bnet.dnodes,1:ss), ... + 'equiv_class', bnet.equiv_class(:,1), 'observed', onodes); +for i=1:max(bnet1.equiv_class) + bnet1.CPD{i} = bnet.CPD{i}; +end +engine.jtree_engine1 = jtree_inf_engine(bnet1, 'clusters', {int}, 'root', int); +jtree_engine1 = struct(engine.jtree_engine1); % violate object privacy +engine.int_clq1 = clq_containing_nodes(engine.jtree_engine1, int); +engine.clq_ass_to_node1 = jtree_engine1.clq_ass_to_node; +engine.root1 = jtree_engine1.root_clq; + +engine.observed = [onodes onodes+ss]; +engine.observed1 = onodes; +engine.pot_type = determine_pot_type(bnet, onodes); +engine.slice_size = bnet.nnodes_per_slice; + +engine = class(engine, 'jtree_2TBN_inf_engine', inf_engine(bnet)); + diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_family.m new file mode 100644 index 00000000..0b6e6186 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_family.m @@ -0,0 +1,12 @@ +function m = marginal_family(engine, b, i, t, add_ev) +% MARGINAL_FAMILY Compute the marginal on the specified family (jtree_2TBN) +% marginal = marginal_family(engine, b, i, t, add_ev) + +bnet = bnet_from_engine(engine); +if t==1 + m = marginal_nodes(engine, b, family(bnet.dag, i), t, add_ev, 1); +else + ss = length(bnet.intra); + fam = family(bnet.dag, i+ss); + m = marginal_nodes(engine, b, fam, t, add_ev, 1); +end diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_nodes.m new file mode 100644 index 00000000..e7ee2ae9 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_nodes.m @@ -0,0 +1,32 @@ +function marginal = marginal_nodes(engine, b, nodes, t, add_ev, is_fam) +% function marginal = marginal_nodes(engine, b, nodes, t, add_ev, is_fam) (jtree_2TBN) + +if nargin < 6, is_fam = 0; end +ss = engine.slice_size; + +if ~is_fam & (t > 1) & all(nodes<=ss) + nodes = nodes + ss; +end + +if t==1 + c = clq_containing_nodes(engine.jtree_engine1, nodes, is_fam); +else + c = clq_containing_nodes(engine.jtree_engine, nodes, is_fam); +end +if c == -1 + error(['no clique contains ' nodes]) +end +bigpot = b.clpot{c}; +pot = marginalize_pot(bigpot, nodes, engine.maximize); +marginal = pot_to_marginal(pot); + +% we convert the domain to the unrolled numbering system +% so that add_ev_to_dmarginal (maybe called in update_ess) extracts the right evidence. +if t > 1 + marginal.domain = nodes+(t-2)*engine.slice_size; +end +assert(~add_ev); + + + + diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/set_fields.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/set_fields.m new file mode 100644 index 00000000..51df3b32 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/set_fields.m @@ -0,0 +1,16 @@ +function engine = set_fields(engine, varargin) +% SET_FIELDS Set the fields for a generic engine +% engine = set_fields(engine, name/value pairs) +% +% e.g., engine = set_fields(engine, 'maximize', 1) + +args = varargin; +nargs = length(args); +for i=1:2:nargs + switch args{i}, + case 'maximize', + engine.maximize = args{i+1}; + engine.jtree_engine = set_fields(engine.jtree_engine, 'maximize', args{i+1}); + engine.jtree_engine1 = set_fields(engine.jtree_engine1, 'maximize', args{i+1}); + end +end diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Entries new file mode 100644 index 00000000..14219dd2 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Entries @@ -0,0 +1,10 @@ +/back.m/1.1.1.1/Wed May 29 15:59:56 2002// +/back1.m/1.1.1.1/Wed May 29 15:59:56 2002// +/backT.m/1.1.1.1/Wed May 29 15:59:56 2002// +/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002// +/fwd.m/1.1.1.1/Wed May 29 15:59:56 2002// +/fwd1.m/1.1.1.1/Wed May 29 15:59:56 2002// +/jtree_sparse_2TBN_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002// +/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002// +/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002// +D diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Repository new file mode 100644 index 00000000..2c445be3 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Repository @@ -0,0 +1 @@ +FullBNT/BNT/inference/online/@jtree_sparse_2TBN_inf_engine diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Root new file mode 100644 index 00000000..f3bd14a6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Root @@ -0,0 +1 @@ +:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back.m new file mode 100644 index 00000000..7f686d55 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back.m @@ -0,0 +1,27 @@ +function b = back(engine, bfuture, f, t) + +if f.t ~= t + error('mixed up time stamps') +end +if t==1 + b = back1(engine, bfuture, f, t); + return; +end + +bnet = bnet_from_engine(engine); +ss = bnet.nnodes_per_slice; + +int = engine.interface; +D = engine.in_clq; +C = engine.out_clq; +phiD = marginalize_pot(bfuture.clpot{D}, int, engine.maximize); +phiD = set_domain_pot(phiD, int+ss); % shift to slice 2 +phiC = marginalize_pot(f.clpot{C}, int+ss, engine.maximize); +ratio = divide_by_pot(phiD, phiC); +f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio); + +[b.clpot, seppot] = distribute_evidence(engine.jtree_engine, f.clpot, f.seppot); +for c=1:length(b.clpot) + [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c}); +end +b.t = t; diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back1.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back1.m new file mode 100644 index 00000000..a8587a72 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back1.m @@ -0,0 +1,21 @@ +function b = back1(engine, bfuture, f, t) + +if t ~= 1 + error('mixed up time stamps') +end +bnet = bnet_from_engine(engine); +ss = bnet.nnodes_per_slice; + +int = engine.interface; +D = engine.in_clq; % from J2 +C = engine.int_clq1; % from J1 +phiD = marginalize_pot(bfuture.clpot{D}, int, engine.maximize); +phiC = marginalize_pot(f.clpot{C}, int, engine.maximize); +ratio = divide_by_pot(phiD, phiC); +f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio); + +[b.clpot, seppot] = distribute_evidence(engine.jtree_engine1, f.clpot, f.seppot); +for c=1:length(b.clpot) + [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c}); +end +b.t = t; diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/backT.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/backT.m new file mode 100644 index 00000000..7f7a1b42 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/backT.m @@ -0,0 +1,11 @@ +function b = backT(engine, f, t) + +if t==1 + [b.clpot, seppot] = distribute_evidence(engine.jtree_engine1, f.clpot, f.seppot); +else + [b.clpot, seppot] = distribute_evidence(engine.jtree_engine, f.clpot, f.seppot); +end +for c=1:length(b.clpot) + [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c}); +end +b.t = t; diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/enter_evidence.m new file mode 100644 index 00000000..048d9064 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/enter_evidence.m @@ -0,0 +1,22 @@ +function [engine, loglik] = enter_evidence(engine, evidence, varargin) +% ENTER_EVIDENCE Add the specified evidence to the network (jtree_online) +% [engine, loglik] = enter_evidence(engine, evidence, ...) +% +% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector) +% +% The following optional arguments can be specified in the form of name/value pairs: +% [default value in brackets] +% +% maximize - if 1, does max-product instead of sum-product [0] +% + +engine.maximize = 0; +args = varargin; +for i=1:2:length(args) + switch args{i} + case 'maximize', engine.maximize = args{i+1}; + otherwise, error(['unrecognized argument ' args{i}]) + end +end + +[engine, loglik] = offline_smoother(engine, evidence); diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd.m new file mode 100644 index 00000000..948d8bc8 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd.m @@ -0,0 +1,47 @@ +function [f, logscale] = fwd(engine, fpast, ev, t) +% Forwards pass. + +bnet = bnet_from_engine(engine); +ss = bnet.nnodes_per_slice; + +ev2 = cell(ss, 2); +ev2(:,1) = fpast.evidence; +ev2(:,2) = ev; +CPDpot = cell(1,ss); +for n=1:ss + fam = family(bnet.dag, n, 2); + e = bnet.equiv_class(n, 2); + CPDpot{n} = convert_to_pot(bnet.CPD{e}, engine.pot_type, fam(:), ev2); +end +f.evidence = ev; +f.t = t; + +% get prior +int = engine.interface; +if fpast.t==1 + prior = marginalize_pot(fpast.clpot{engine.int_clq1}, int, engine.maximize); +else + prior = marginalize_pot(fpast.clpot{engine.out_clq}, int+ss, engine.maximize); + prior = set_domain_pot(prior, int); % shift back to slice 1 +end + +pots = [ {prior} CPDpot ]; +slice1 = 1:ss; +slice2 = slice1 + ss; +CPDclqs = engine.clq_ass_to_node(slice2); +D = engine.in_clq; +clqs = [D CPDclqs]; + +[f.clpot, f.seppot] = init_pot(engine.jtree_engine, clqs, pots, engine.pot_type, engine.observed); +[f.clpot, f.seppot] = collect_evidence(engine.jtree_engine, f.clpot, f.seppot); +for c=1:length(f.clpot) + if isa(f.clpot{c}, 'struct') + domain = f.clpot{c}.domain; + sizes = f.clpot{c}.sizes; + T = f.clpot{c}.T; + f.clpot{c} = dpot(domain, sizes, T); + end + [f.clpot{c}, ll(c)] = normalize_pot(f.clpot{c}); +end +logscale = ll(engine.root); + diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd1.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd1.m new file mode 100644 index 00000000..45d28c3f --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd1.m @@ -0,0 +1,32 @@ +function [f, logscale] = fwd1(engine, ev, t) +% Forwards pass for slice 1. + +bnet = bnet_from_engine(engine); +ss = bnet.nnodes_per_slice; + +CPDpot = cell(1,ss); +for n=1:ss + fam = family(bnet.dag, n, 1); + e = bnet.equiv_class(n, 1); + CPDpot{n} = convert_to_pot(bnet.CPD{e}, engine.pot_type, fam(:), ev); +end +f.evidence = ev; +f.t = t; + +pots = CPDpot; +slice1 = 1:ss; +CPDclqs = engine.clq_ass_to_node1(slice1); + +[f.clpot, f.seppot] = init_pot(engine.jtree_engine1, CPDclqs, CPDpot, engine.pot_type, engine.observed1); +[f.clpot, f.seppot] = collect_evidence(engine.jtree_engine1, f.clpot, f.seppot); +for c=1:length(f.clpot) + if isa(f.clpot{c}, 'struct') + domain = f.clpot{c}.domain; + sizes = f.clpot{c}.sizes; + T = f.clpot{c}.T; + f.clpot{c} = dpot(domain, sizes, T); + end + [f.clpot{c}, ll(c)] = normalize_pot(f.clpot{c}); +end +logscale = ll(engine.root1); + diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/jtree_sparse_2TBN_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/jtree_sparse_2TBN_inf_engine.m new file mode 100644 index 00000000..4897e8fd --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/jtree_sparse_2TBN_inf_engine.m @@ -0,0 +1,95 @@ +function engine = jtree_sparse_2TBN_inf_engine(bnet, varargin) +% JTREE_ONLINE_INF_ENGINE Online Junction tree inference algorithm for DBNs. +% engine = jtree_online_inf_engine(bnet, ...) +% +% The following optional arguments can be specified in the form of name/value pairs: +% [default value in brackets] +% +% clusters - specifies variables that must be grouped in the 1.5 slice DBN +% maximize - 1 means do max-product, 0 means sum-product [0] +% +% The same nodes must be observed in every slice. + +ss = length(bnet.intra); +clusters = {}; +engine.maximize = 0; + +args = varargin; +nargs = length(args); +for i=1:2:length(args) + switch args{i}, + case 'clusters', clusters = args{i+1}; + case 'maximize', engine.maximize = args{i+1}; + otherwise, error(['unrecognized argument ' args{i}]) + end +end + +engine.evidence = []; +engine.node_sizes = []; + +int = []; +% include nodes with any outgoing arcs +for u=1:ss + if any(bnet.inter(u,:)) + int = [int u]; + end +end + +engine.interface = int; +engine.nonint = mysetdiff(1:ss, int); + +onodes = bnet.observed; + +% Create a "1.5 slice" jtree, containing the interface nodes of slice 1 +% and all the nodes of slice 2 +% To keep the node numbering the same, we simply disconnect the non-interface nodes +% from slice 1, and set their size to 1. +% We do this to speed things up, and so that the likelihood is computed correctly - we do not need to do +% this if we just want to compute marginals (i.e., we can include nodes whose potentials will +% be left as all 1s). +intra15 = bnet.intra; +for i=engine.nonint(:)' + intra15(:,i) = 0; + intra15(i,:) = 0; + assert(~any(bnet.inter(i,:))) +end +dag15 = [intra15 bnet.inter; + zeros(ss) bnet.intra]; +ns = bnet.node_sizes(:); +ns(engine.nonint) = 1; % disconnected nodes get size 1 +obs_nodes = [onodes(:) onodes(:)+ss]; +bnet15 = mk_bnet(dag15, ns, 'discrete', bnet.dnodes, 'equiv_class', bnet.equiv_class(:), ... + 'observed', obs_nodes(:)); + +% use unconstrained elimination, +% but force there to be a clique containing both interfaces +clusters(end+1:end+2) = {int, int+ss}; +%engine.jtree_engine = jtree_inf_engine(bnet15, 'clusters', clusters, 'root', int+ss); +engine.jtree_engine = jtree_sparse_inf_engine(bnet15, 'clusters', clusters, 'root', int+ss); +jtree_engine = struct(engine.jtree_engine); % violate object privacy + +engine.in_clq = clq_containing_nodes(engine.jtree_engine, int); +engine.out_clq = clq_containing_nodes(engine.jtree_engine, int+ss); +engine.clq_ass_to_node = jtree_engine.clq_ass_to_node; +engine.root = jtree_engine.root_clq; + +% Also create an engine just for slice 1 +bnet1 = mk_bnet(bnet.intra1, bnet.node_sizes_slice, 'discrete', myintersect(bnet.dnodes,1:ss), ... + 'equiv_class', bnet.equiv_class(:,1), 'observed', onodes); +for i=1:max(bnet1.equiv_class) + bnet1.CPD{i} = bnet.CPD{i}; +end +%engine.jtree_engine1 = jtree_inf_engine(bnet1, 'clusters', {int}, 'root', int); +engine.jtree_engine1 = jtree_sparse_inf_engine(bnet1, 'clusters', {int}, 'root', int); +jtree_engine1 = struct(engine.jtree_engine1); % violate object privacy +engine.int_clq1 = clq_containing_nodes(engine.jtree_engine1, int); +engine.clq_ass_to_node1 = jtree_engine1.clq_ass_to_node; +engine.root1 = jtree_engine1.root_clq; + +engine.observed = [onodes onodes+ss]; +engine.observed1 = onodes; +engine.pot_type = determine_pot_type(bnet, onodes); +engine.slice_size = bnet.nnodes_per_slice; + +engine = class(engine, 'jtree_sparse_2TBN_inf_engine', inf_engine(bnet)); + diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_family.m new file mode 100644 index 00000000..0b6e6186 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_family.m @@ -0,0 +1,12 @@ +function m = marginal_family(engine, b, i, t, add_ev) +% MARGINAL_FAMILY Compute the marginal on the specified family (jtree_2TBN) +% marginal = marginal_family(engine, b, i, t, add_ev) + +bnet = bnet_from_engine(engine); +if t==1 + m = marginal_nodes(engine, b, family(bnet.dag, i), t, add_ev, 1); +else + ss = length(bnet.intra); + fam = family(bnet.dag, i+ss); + m = marginal_nodes(engine, b, fam, t, add_ev, 1); +end diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_nodes.m new file mode 100644 index 00000000..e7ee2ae9 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_nodes.m @@ -0,0 +1,32 @@ +function marginal = marginal_nodes(engine, b, nodes, t, add_ev, is_fam) +% function marginal = marginal_nodes(engine, b, nodes, t, add_ev, is_fam) (jtree_2TBN) + +if nargin < 6, is_fam = 0; end +ss = engine.slice_size; + +if ~is_fam & (t > 1) & all(nodes<=ss) + nodes = nodes + ss; +end + +if t==1 + c = clq_containing_nodes(engine.jtree_engine1, nodes, is_fam); +else + c = clq_containing_nodes(engine.jtree_engine, nodes, is_fam); +end +if c == -1 + error(['no clique contains ' nodes]) +end +bigpot = b.clpot{c}; +pot = marginalize_pot(bigpot, nodes, engine.maximize); +marginal = pot_to_marginal(pot); + +% we convert the domain to the unrolled numbering system +% so that add_ev_to_dmarginal (maybe called in update_ess) extracts the right evidence. +if t > 1 + marginal.domain = nodes+(t-2)*engine.slice_size; +end +assert(~add_ev); + + + + diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Entries new file mode 100644 index 00000000..d9c315a5 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Entries @@ -0,0 +1,8 @@ +/bnet_from_engine.m/1.1.1.1/Wed May 29 15:59:56 2002// +/enter_evidence.m/1.1.1.1/Mon Jun 17 23:46:46 2002// +/find_mpe.m/1.1.1.1/Mon Jun 17 23:50:16 2002// +/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002// +/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002// +/smoother_engine.m/1.1.1.1/Wed May 29 15:59:56 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/@smoother_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Repository new file mode 100644 index 00000000..a10f8a08 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Repository @@ -0,0 +1 @@ +FullBNT/BNT/inference/online/@smoother_engine diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Root new file mode 100644 index 00000000..f3bd14a6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Root @@ -0,0 +1 @@ +:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/bnet_from_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/bnet_from_engine.m new file mode 100644 index 00000000..b57ee5f4 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/bnet_from_engine.m @@ -0,0 +1,5 @@ +function bnet = bnet_from_engine(engine) +% BNET_FROM_ENGINE Return the bnet structure stored inside the engine (smoother_engine) +% bnet = bnet_from_engine(engine) + +bnet = bnet_from_engine(engine.tbn_engine); diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/enter_evidence.m new file mode 100644 index 00000000..299c2331 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/enter_evidence.m @@ -0,0 +1,21 @@ +function [engine, LL] = enter_evidence(engine, ev) +% ENTER_EVIDENCE Call the offline smoother +% [engine, loglik] = enter_evidence(engine, evidence, ...) +% +% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector) +% + +T = size(ev, 2); +f = cell(1,T); +b = cell(1,T); % b{t}.clpot{c} +ll = zeros(1,T); +[f{1}, ll(1)] = fwd1(engine.tbn_engine, ev(:,1), 1); +for t=2:T + [f{t}, ll(t)] = fwd(engine.tbn_engine, f{t-1}, ev(:,t), t); +end +LL = sum(ll); +b{T} = backT(engine.tbn_engine, f{T}, T); +for t=T-1:-1:1 + b{t} = back(engine.tbn_engine, b{t+1}, f{t}, t); +end +engine.b = b; diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/find_mpe.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/find_mpe.m new file mode 100644 index 00000000..5415f120 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/find_mpe.m @@ -0,0 +1,33 @@ +function mpe = find_mpe(engine, ev) +% FIND_MPE Find the most probable explanation (Viterbi) +% mpe = enter_evidence(engine, evidence, ...) +% +% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector) +% + +mpe = cell(size(ev)); +engine.tbn_engine = set_fields(engine.tbn_engine, 'maximize', 1); + +T = size(ev, 2); +f = cell(1,T); +b = cell(1,T); % b{t}.clpot{c} +ll = zeros(1,T); +[f{1}, ll(1)] = fwd1(engine.tbn_engine, ev(:,1), 1); +for t=2:T + [f{t}, ll(t)] = fwd(engine.tbn_engine, f{t-1}, ev(:,t), t); +end + +if T==1 + [b{1}, mpe(:,1)] = backT_mpe(engine.tbn_engine, f{1}, ev(:,1), 1); +else + [b{T}, mpe(:,T)] = backT_mpe(engine.tbn_engine, f{T}, ev(:,T-1:T), T); + for t=T-1:-1:2 + [b{t}, mpe(:,t)] = back_mpe(engine.tbn_engine, b{t+1}, f{t}, ev(:,t-1:t), t); + end + t = 1; + [b{t}, mpe(:,t)] = back1_mpe(engine.tbn_engine, b{t+1}, f{t}, ev(:,1), t); +end +engine.b = b; + + + diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_family.m new file mode 100644 index 00000000..b7b0d7ec --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_family.m @@ -0,0 +1,6 @@ +function marginal = marginal_family(engine, i, t, add_ev) +% MARGINAL_FAMILY Compute the joint distribution on a set of family (smoother_engine) +% function marginal = marginal_family(engine, i, t, add_ev) + +if nargin < 4, add_ev = 0; end +marginal = marginal_family(engine.tbn_engine, engine.b{t}, i, t, add_ev); diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_nodes.m new file mode 100644 index 00000000..e8574c53 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_nodes.m @@ -0,0 +1,7 @@ +function marginal = marginal_nodes(engine, nodes, t, add_ev) +% MARGINAL_NODES Compute the joint distribution on a set of nodes (smoother_engine) +% function marginal = marginal_nodes(engine, nodes, t, add_ev) + +if nargin < 4, add_ev = 0; end + +marginal = marginal_nodes(engine.tbn_engine, engine.b{t}, nodes, t, add_ev); diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/smoother_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/smoother_engine.m new file mode 100644 index 00000000..adf7ede8 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/smoother_engine.m @@ -0,0 +1,12 @@ +function engine = smoother_engine(tbn_engine) +% SMOOTHER_ENGINE Create an engine which does offline (fixed-interval) smoothing in O(T) space/time +% function engine = smoother_engine(tbn_engine) +% +% tbn_engine is any 2TBN inference engine which supports the following methods: +% fwd, fwd1, back, backT, back, marginal_nodes and marginal_family. + +engine.tbn_engine = tbn_engine; +engine.b = []; % space to store smoothed messages +engine = class(engine, 'smoother_engine'); +%engine = class(engine, 'smoother_engine', inf_engine(bnet_from_engine(tbn_engine))); + diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/update_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/update_engine.m new file mode 100644 index 00000000..ffe0661e --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/update_engine.m @@ -0,0 +1,5 @@ +function engine = update_engine(engine, newCPDs) +% UPDATE_ENGINE Update the engine to take into account the new parameters (smoother_engine). +% engine = update_engine(engine, newCPDs) + +engine.tbn_engine = update_engine(engine.tbn_engine, newCPDs); diff --git a/sourcecodes/bnt-master/BNT/inference/online/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/CVS/Entries new file mode 100644 index 00000000..842483c7 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/CVS/Entries @@ -0,0 +1,2 @@ +/dummy/1.1.1.1/Sat Jan 18 22:22:38 2003// +D diff --git a/sourcecodes/bnt-master/BNT/inference/online/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/online/CVS/Entries.Log new file mode 100644 index 00000000..794e1320 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/CVS/Entries.Log @@ -0,0 +1,5 @@ +A D/@filter_engine//// +A D/@hmm_2TBN_inf_engine//// +A D/@jtree_2TBN_inf_engine//// +A D/@jtree_sparse_2TBN_inf_engine//// +A D/@smoother_engine//// diff --git a/sourcecodes/bnt-master/BNT/inference/online/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/CVS/Repository new file mode 100644 index 00000000..2918a1ee --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/CVS/Repository @@ -0,0 +1 @@ +FullBNT/BNT/inference/online diff --git a/sourcecodes/bnt-master/BNT/inference/online/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/CVS/Root new file mode 100644 index 00000000..f3bd14a6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/CVS/Root @@ -0,0 +1 @@ +:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt diff --git a/sourcecodes/bnt-master/BNT/inference/online/dummy b/sourcecodes/bnt-master/BNT/inference/online/dummy new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/online/dummy |
