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/dynamic/@ff_inf_engine | |
| 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/dynamic/@ff_inf_engine')
16 files changed, 525 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Entries new file mode 100644 index 00000000..fda92284 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Entries @@ -0,0 +1,8 @@ +/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002// +/enter_soft_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002// +/ff_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002// +/filter_evidence.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// +/smooth_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002// +D/Old//// diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Repository new file mode 100644 index 00000000..56fb63d3 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Repository @@ -0,0 +1 @@ +FullBNT/BNT/inference/dynamic/@ff_inf_engine diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Root new file mode 100644 index 00000000..f3bd14a6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Root @@ -0,0 +1 @@ +:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Entries new file mode 100644 index 00000000..dd45ee37 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Entries @@ -0,0 +1,4 @@ +/enter_soft_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002// +/enter_soft_evidence1.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// +D diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Repository new file mode 100644 index 00000000..5582c6dd --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Repository @@ -0,0 +1 @@ +FullBNT/BNT/inference/dynamic/@ff_inf_engine/Old diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Root new file mode 100644 index 00000000..f3bd14a6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Root @@ -0,0 +1 @@ +:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence.m new file mode 100644 index 00000000..1e2acffb --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence.m @@ -0,0 +1,59 @@ +function [marginals, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter) +% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (bk_ff) +% [marginals, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter) + +assert(pot_type == 'd'); +[ss T] = size(CPDpot); +fwd = cell(ss,T); +hnodes = engine.hnodes(:)'; +onodes = engine.onodes(:)'; +bnet = bnet_from_engine(engine); +ns = bnet.node_sizes; +onodes2 = [onodes onodes+ss]; +ns(onodes2) = 1; + +logscale = zeros(1,T); +local_logscale = zeros(1,length(hnodes)); + +t = 1; +for i=hnodes + fwd{i,t} = CPDpot{i,t}; +end +for i=onodes + p = parents(bnet.dag, i); + assert(length(p)==1); + ev = marginalize_pot(CPDpot{i,t}, p); + fwd{p,t} = multiply_by_pot(fwd{p,t}, ev); +end +for i=hnodes + [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t}); +end +logscale(t) = sum(local_logscale); + +for t=2:T + for i=hnodes + ps = parents(bnet.dag, i+ss); + assert(all(ps<=ss)); % in previous slice + prior = CPDpot{i,t}; + for p=ps(:)' + prior = multiply_by_pot(prior, fwd{p,t-1}); + end + fwd{i,t} = marginalize_pot(prior, i+ss); + fwd{i,t} = set_domain_pot(fwd{i,t}, i); + end + for i=onodes + p = parents(bnet.dag, i); + assert(length(p)==1); + temp = pot_to_marginal(CPDpot{i,t}); + ev = dpot(p, ns(p), temp.T); + fwd{p,t} = multiply_by_pot(fwd{p,t}, ev); + end + + for i=hnodes + [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t}); + end + logscale(t) = sum(local_logscale); +end + +marginals = fwd; +loglik = sum(logscale); diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence1.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence1.m new file mode 100644 index 00000000..b4ff1a02 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence1.m @@ -0,0 +1,94 @@ +function [marginals, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter) +% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (ff) +% [marginals, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter) + +assert(pot_type == 'd'); +[ss T] = size(CPDpot); +fwd = cell(ss,T); +hnodes = engine.hnodes(:)'; +onodes = engine.onodes(:)'; +bnet = bnet_from_engine(engine); +ns = bnet.node_sizes; +onodes2 = [onodes onodes+ss]; +ns(onodes2) = 1; + +logscale = zeros(1,T); +H = length(hnodes); +local_logscale = zeros(1,ss); + +obschild = zeros(1,ss); +for i=hnodes + ocs = myintersect(children(bnet.dag, i), onodes); + assert(length(ocs)==1); + obschild(i) = ocs(1); +end + +t = 1; +for i=hnodes + fwd{i,t} = CPDpot{i,t}; + c = obschild(i); + temp = pot_to_marginal(CPDpot{c,t}); + ev = dpot(i, ns(i), temp.T); + fwd{i,t} = multiply_by_pot(fwd{i,t}, ev); + [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t}); +end +logscale(t) = sum(local_logscale); + +for t=2:T + for i=hnodes + ps = parents(bnet.dag, i+ss); + assert(all(ps<=ss)); % in previous slice + prior = CPDpot{i,t}; + for p=ps(:)' + prior = multiply_by_pot(prior, fwd{p,t-1}); + end + fwd{i,t} = marginalize_pot(prior, i+ss); + fwd{i,t} = set_domain_pot(fwd{i,t}, i); + c = obschild(i); + temp = pot_to_marginal(CPDpot{c,t}); + ev = dpot(i, ns(i), temp.T); + fwd{i,t} = multiply_by_pot(fwd{i,t}, ev); + [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t}); + end + logscale(t) = sum(local_logscale); +end + +loglik = sum(logscale); + + +if filter + marginals = fwd; + return; +end + +back = cell(ss,T); +t = T; +for i=hnodes + back{i,t} = dpot(i, ns(i)); + back{i,t} = set_domain_pot(back{i,t}, i+ss); +end +for t=T-1:-1:1 + for i=hnodes + pot = CPDpot{i,t+1}; + pot = multiply_by_pot(pot, back{i,t+1}); + c = obschild(i); + temp = pot_to_marginal(CPDpot{c,t+1}); + ev = dpot(i, ns(i), temp.T); + pot = multiply_by_pot(pot, ev); + back{i,t} = marginalize_pot(pot, i); + back{i,t} = normalize_pot(back{i,t}); + back{i,t} = set_domain_pot(back{i,t}, i+ss); + end +end + + + +% COMBINE +for t=1:T + for i=hnodes + back{i,t} = set_domain_pot(back{i,t}, i); + fwd{i,t} = multiply_by_pot(fwd{i,t}, back{i,t}); + marginals{i,t} = normalize_pot(fwd{i,t}); + %fwdback{i,t} = normalize_pot(multiply_pots(fwd{i,t}, back{i,t})); + end +end diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/marginal_family.m new file mode 100644 index 00000000..99813571 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/marginal_family.m @@ -0,0 +1,38 @@ +function marginal = marginal_family(engine, i, t) +% MARGINAL_FAMILY Compute the marginal on the specified family (ff) +% marginal = marginal_family(engine, i, t) + +if nargin < 3, t = 1; end + +% The method is similar to the following HMM equation: +% xi(i,j,t) = normalise( alpha(i,t) * transmat(i,j) * obsmat(j,t+1) * beta(j,t+1) ) +% where xi(i,j,t) = Pr(Q(t)=i, Q(t+1)=j | y(1:T)) + +bnet = bnet_from_engine(engine); + +if myismember(i, engine.onodes) + ps = parents(bnet.dag, i); + p = ps(1); + marginal = pot_to_marginal(engine.marginals{p,t}); + marginal.domain = [p i]; + return; +end + +if t==1 + marginal = pot_to_marginal(engine.marginals{i,t}); + return; +end + +bnet = bnet_from_engine(engine); +ss = length(bnet.intra); +pot = engine.CPDpot{i,t}; +c = engine.obschild(i); +pot = multiply_by_pot(pot, engine.CPDpot{c,t}); +pot = multiply_by_pot(pot, engine.back{i,t}); +ps = parents(bnet.dag, i+ss); +for p=ps(:)' + pot = multiply_by_pot(pot, engine.fwd{p,t-1}); +end +marginal = pot_to_marginal(normalize_pot(pot)); + + diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_evidence.m new file mode 100644 index 00000000..7fa9fa9b --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_evidence.m @@ -0,0 +1,62 @@ +function [engine, loglik] = enter_evidence(engine, evidence, varargin) +% ENTER_EVIDENCE Add the specified evidence to the network (ff) +% [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 (not yet supported), else sum-product [0] +% filter - if 1, do filtering, else smoothing [0] +% +% e.g., engine = enter_evidence(engine, ev, 'maximize', 1) + +maximize = 0; +filter = 0; + +% parse optional params +args = varargin; +nargs = length(args); +if nargs > 0 + for i=1:2:nargs + switch args{i}, + case 'maximize', maximize = args{i+1}; + case 'filter', filter = args{i+1}; + otherwise, + error(['invalid argument name ' args{i}]); + end + end +end + +assert(~maximize); + + +[ss T] = size(evidence); +observed = ~isemptycell(evidence); +bnet = bnet_from_engine(engine); +%pot_type = determine_pot_type(find(observed(:,1)), bnet.cnodes_slice, bnet.intra); +pot_type = determine_pot_type(bnet, observed); +% we assume we can use the same pot_type in all slices + +CPDpot = convert_dbn_CPDs_to_pots(bnet, evidence, pot_type); + +% Now convert CPDs on observed nodes to be potentials just on their parents +assert(pot_type == 'd'); +onodes = bnet.observed(:); +ns = bnet.node_sizes_slice; +ns(onodes) = 1; +for t=1:T + for i=onodes + p = parents(bnet.dag, i); + %CPDpot{i,t} = set_domain_pot(CPDpot{i,t}, p); % leaves size too long + temp = pot_to_marginal(CPDpot{i,t}); + CPDpot{i,t} = dpot(p, ns(p), temp.T); % assumes pot_type = d + end +end + +[engine.marginals, engine.fwd, engine.back, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter); + +engine.CPDpot = CPDpot; +engine.filter = filter; diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_soft_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_soft_evidence.m new file mode 100644 index 00000000..db16f39b --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_soft_evidence.m @@ -0,0 +1,11 @@ +function [marginals, fwd, back, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter) +% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (ff) +% [marginals, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter) + +if filter + [fwd, loglik] = filter_evidence(engine, CPDpot, observed, pot_type); + marginals = fwd; + back = []; +else + [marginals, fwd, back, loglik] = smooth_evidence(engine, CPDpot, observed, pot_type); +end diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/ff_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/ff_inf_engine.m new file mode 100644 index 00000000..ade26106 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/ff_inf_engine.m @@ -0,0 +1,44 @@ +function engine = ff_inf_engine(bnet) +% FF_INF_ENGINE Factored frontier inference engine for DBNs +% engine = ff_inf_engine(bnet) +% +% The model must be topologically isomorphic to an HMM. +% In addition, each hidden node is assumed to have at most one observed child, +% and each observed child is assumed to have exactly one hidden parent. +% +% For details of this algorithm, see +% "The Factored Frontier Algorithm for Approximate Inference in DBNs", +% Kevin Murphy and Yair Weiss, UAI 2001. +% +% THIS IS HIGHLY EXPERIMENTAL CODE! + +ss = length(bnet.intra); +onodes = bnet.observed; +hnodes = mysetdiff(1:ss, onodes); + +[persistent_nodes, transient_nodes] = partition_dbn_nodes(bnet.intra, bnet.inter); +assert(isequal(onodes, transient_nodes)); +assert(isequal(hnodes, persistent_nodes)); + +engine.onodes = onodes; +engine.hnodes = hnodes; +engine.marginals = []; +engine.fwd = []; +engine.back = []; +engine.CPDpot = []; +engine.filter = []; + +obschild = zeros(1,ss); +for i=engine.hnodes(:)' + %ocs = myintersect(children(bnet.dag, i), onodes); + ocs = children(bnet.intra, i); + assert(length(ocs) <= 1); + if length(ocs)==1 + obschild(i) = ocs(1); + end +end +engine.obschild = obschild; + + +engine = class(engine, 'ff_inf_engine', inf_engine(bnet)); + diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/filter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/filter_evidence.m new file mode 100644 index 00000000..3dd4835c --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/filter_evidence.m @@ -0,0 +1,48 @@ +function [fwd, loglik] = filter_evidence(engine, CPDpot, observed, pot_type) +% [fwd, loglik] = filter_evidence(engine, CPDpot, observed, pot_type) (ff) + +[ss T] = size(CPDpot); +fwd = cell(ss,T); +hnodes = engine.hnodes(:)'; +onodes = engine.onodes(:)'; +bnet = bnet_from_engine(engine); +ns = bnet.node_sizes; +onodes2 = [onodes onodes+ss]; +ns(onodes2) = 1; + +logscale = zeros(1,T); +H = length(hnodes); +local_logscale = zeros(1,ss); + +t = 1; +for i=hnodes + fwd{i,t} = CPDpot{i,t}; + c = engine.obschild(i); + if c > 0 + fwd{i,t} = multiply_by_pot(fwd{i,t}, CPDpot{c, t}); + end + [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t}); +end +logscale(t) = sum(local_logscale); + +for t=2:T + for i=hnodes + ps = parents(bnet.dag, i+ss); + assert(all(ps<=ss)); % in previous slice + prior = CPDpot{i,t}; + for p=ps(:)' + prior = multiply_by_pot(prior, fwd{p,t-1}); + end + fwd{i,t} = marginalize_pot(prior, i+ss); + fwd{i,t} = set_domain_pot(fwd{i,t}, i); + c = engine.obschild(i); + if c > 0 + fwd{i,t} = multiply_by_pot(fwd{i,t}, CPDpot{c,t}); + end + [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t}); + end + logscale(t) = sum(local_logscale); +end + +loglik = sum(logscale); + diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_family.m new file mode 100644 index 00000000..bdc783b7 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_family.m @@ -0,0 +1,44 @@ +function marginal = marginal_family(engine, i, t) +% MARGINAL_FAMILY Compute the marginal on the specified family (ff) +% marginal = marginal_family(engine, i, t) + + +if engine.filter + error('can''t currently use marginal_family when filtering with ff'); +end + +if nargin < 3, t = 1; end + +% The method is similar to the following HMM equation: +% xi(i,j,t) = normalise( alpha(i,t) * transmat(i,j) * obsmat(j,t+1) * beta(j,t+1) ) +% where xi(i,j,t) = Pr(Q(t)=i, Q(t+1)=j | y(1:T)) + +bnet = bnet_from_engine(engine); +ss = length(bnet.intra); + +if myismember(i, engine.onodes) + ps = parents(bnet.dag, i); + p = ps(1); + marginal = pot_to_marginal(engine.marginals{ps(1),t}); + fam = ([ps i]) + (t-1)*ss; +elseif t==1 + marginal = pot_to_marginal(engine.marginals{i,t}); + fam = i + (t-1)*ss; +else + pot = engine.CPDpot{i,t}; + c = engine.obschild(i); + if c>0 + pot = multiply_by_pot(pot, engine.CPDpot{c,t}); + end + pot = multiply_by_pot(pot, engine.back{i,t}); + ps = parents(bnet.dag, i+ss); + for p=ps(:)' + pot = multiply_by_pot(pot, engine.fwd{p,t-1}); + end + marginal = pot_to_marginal(normalize_pot(pot)); + fam = ([ps i+ss]) + (t-2)*ss; +end + +% we convert the domain to the unrolled numbering system +% so that update_ess extracts the right evidence. +marginal.domain = fam; diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_nodes.m new file mode 100644 index 00000000..f65a3bec --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_nodes.m @@ -0,0 +1,20 @@ +function marginal = marginal_nodes(engine, nodes, t) +% MARGINAL_NODES Compute the marginal on the specified query nodes (ff) +% marginal = marginal_nodes(engine, i, t) +% returns Pr(X(i,t) | Y(1:T)), where X(i,t) is the i'th node in the t'th slice. +% If enter_evidence used filtering instead of smoothing, this will return Pr(X(i,t) | Y(1:t)). + +if nargin < 3, t = 1; end +assert(length(nodes)==1); +i = nodes(end); +if myismember(i, engine.hnodes) + marginal = pot_to_marginal(engine.marginals{i,t}); +else + marginal = pot_to_marginal(dpot(i, 1, 1)); % observed +end + +bnet = bnet_from_engine(engine); +ss = length(bnet.intra); +% we convert the domain to the unrolled numbering system +% so that update_ess extracts the right evidence. +marginal.domain = nodes+(t-1)*ss; diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/smooth_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/smooth_evidence.m new file mode 100644 index 00000000..782f07aa --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/smooth_evidence.m @@ -0,0 +1,89 @@ +function [marginals, fwd, back, loglik] = smooth_evidence(engine, CPDpot, observed, pot_type) +% [marginals, fwd, back, loglik] = smooth_evidence(engine, CPDpot, observed, pot_type) (ff) + +error('ff smoothing is broken'); + +[ss T] = size(CPDpot); +fwd = cell(ss,T); +hnodes = engine.hnodes(:)'; +onodes = engine.onodes(:)'; +bnet = bnet_from_engine(engine); +ns = bnet.node_sizes; +onodes2 = [onodes onodes+ss]; +ns(onodes2) = 1; + +logscale = zeros(1,T); +H = length(hnodes); +local_logscale = zeros(1,ss); + +t = 1; +for i=hnodes + fwd{i,t} = CPDpot{i,t}; + c = engine.obschild(i); + if 0 % c > 0 + fwd{i,t} = multiply_by_pot(fwd{i,t}, CPDpot{c, t}); + end + [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t}); +end +logscale(t) = sum(local_logscale); + +for t=2:T + for i=hnodes + ps = parents(bnet.dag, i+ss); + assert(all(ps<=ss)); % in previous slice + prior = CPDpot{i,t}; + for p=ps(:)' + prior = multiply_by_pot(prior, fwd{p,t-1}); + end + fwd{i,t} = marginalize_pot(prior, i+ss); + fwd{i,t} = set_domain_pot(fwd{i,t}, i); + c = engine.obschild(i); + if 0 % c > 0 + fwd{i,t} = multiply_by_pot(fwd{i,t}, CPDpot{c,t}); + end + [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t}); + end + logscale(t) = sum(local_logscale); +end + +loglik = sum(logscale); + +back = cell(ss,T); +t = T; +for i=hnodes + pot = dpot(i, ns(i)); + cs = children(bnet.intra, i); + for c=cs(:)' + pot = multiply_pots(pot, CPDpot{c,t}); + end + back{i,t} = marginalize_pot(pot, i); + back{i,t} = normalize_pot(back{i,t}); + back{i,t} = set_domain_pot(back{i,t}, i+ss); +end +for t=T-1:-1:1 + for i=hnodes + pot = dpot(i, ns(i)); + cs = children(bnet.inter, i); + for c=cs(:)' + pot = multiply_pots(pot, back{c,t+1}); + pot = multiply_pots(pot, CPDpot{c,t+1}); + end + cs = children(bnet.intra, i); + for c=cs(:)' + pot = multiply_pots(pot, CPDpot{c,t}); + end + back{i,t} = marginalize_pot(pot, i); + back{i,t} = normalize_pot(back{i,t}); + back{i,t} = set_domain_pot(back{i,t}, i+ss); + end +end + + +% COMBINE +for t=1:T + for i=hnodes + back{i,t} = set_domain_pot(back{i,t}, i); + fwd{i,t} = multiply_by_pot(fwd{i,t}, back{i,t}); + marginals{i,t} = normalize_pot(fwd{i,t}); + end +end |
