diff options
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 |
