From 8070dc963753142bb86c4ed698d91fd623ed28e7 Mon Sep 17 00:00:00 2001 From: ziejd2 Date: Thu, 28 Sep 2017 15:04:40 -0500 Subject: BNW using Octave instead of Matlab. This version of BNW should perform the same as the original version. The only difference is that it uses Octave instead of Matlab when running BayesNet Toolbox during parameter learning. I am calling this BNW_1.02. It can be accessed at: compbio.uthsc.edu/BNW_1.02 --- .../inference/dynamic/@bk_inf_engine/CVS/Entries | 11 +++ .../dynamic/@bk_inf_engine/CVS/Repository | 1 + .../BNT/inference/dynamic/@bk_inf_engine/CVS/Root | 1 + .../dynamic/@bk_inf_engine/bk_inf_engine.m | 107 +++++++++++++++++++++ .../dynamic/@bk_inf_engine/dbn_init_bel.m | 8 ++ .../dynamic/@bk_inf_engine/dbn_marginal_from_bel.m | 18 ++++ .../dynamic/@bk_inf_engine/dbn_update_bel.m | 37 +++++++ .../dynamic/@bk_inf_engine/dbn_update_bel1.m | 30 ++++++ .../dynamic/@bk_inf_engine/enter_evidence.m | 48 +++++++++ .../dynamic/@bk_inf_engine/enter_soft_evidence.m | 88 +++++++++++++++++ .../dynamic/@bk_inf_engine/marginal_family.m | 25 +++++ .../dynamic/@bk_inf_engine/marginal_nodes.m | 67 +++++++++++++ .../dynamic/@bk_inf_engine/update_engine.m | 11 +++ 13 files changed, 452 insertions(+) create mode 100644 sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Entries create mode 100644 sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Repository create mode 100644 sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Root create mode 100644 sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/bk_inf_engine.m create mode 100644 sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_init_bel.m create mode 100644 sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_marginal_from_bel.m create mode 100644 sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel.m create mode 100644 sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel1.m create mode 100644 sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_evidence.m create mode 100644 sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_soft_evidence.m create mode 100644 sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_family.m create mode 100644 sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_nodes.m create mode 100644 sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/update_engine.m (limited to 'sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine') diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Entries new file mode 100644 index 00000000..b071e13e --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Entries @@ -0,0 +1,11 @@ +/bk_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002// +/dbn_init_bel.m/1.1.1.1/Wed May 29 15:59:56 2002// +/dbn_marginal_from_bel.m/1.1.1.1/Wed May 29 15:59:56 2002// +/dbn_update_bel.m/1.1.1.1/Wed May 29 15:59:56 2002// +/dbn_update_bel1.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// +/enter_soft_evidence.m/1.1.1.1/Sat Jan 11 18:13:50 2003// +/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// +/update_engine.m/1.1.1.1/Wed May 29 15:59:56 2002// +D diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Repository new file mode 100644 index 00000000..5e810837 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Repository @@ -0,0 +1 @@ +FullBNT/BNT/inference/dynamic/@bk_inf_engine diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Root new file mode 100644 index 00000000..f3bd14a6 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Root @@ -0,0 +1 @@ +:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/bk_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/bk_inf_engine.m new file mode 100644 index 00000000..2ca0350f --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/bk_inf_engine.m @@ -0,0 +1,107 @@ +function engine = bk_inf_engine(bnet, varargin) +% BK_INF_ENGINE Boyen-Koller approximate inference algorithm for DBNs. +% +% In the BK algorithm, the belief state is represented as a product of marginals, +% even though the factors may not be independent. +% +% engine = bk_inf_engine(bnet, ...) +% +% The following optional arguments can be specified in the form of name/value pairs: +% [default value in brackets] +% +% clusters - if a cell array, clusters{i} specifies the terms in the i'th factor. +% - 'exact' means create one cluster that contains all the nodes in a slice [exact] +% - 'ff' means create one cluster per node (ff = fully factorised). +% +% +% For details, see +% - "Tractable Inference for Complex Stochastic Processes", X. Boyen and D. Koller, UAI 98. +% - "Approximate learning of dynamic models", X. Boyen and D. Koller, NIPS 98. +% (The UAI98 paper discusses filtering and theory, and the NIPS98 paper discusses smoothing.) + +ss = length(bnet.intra); +% set default params +clusters = 'exact'; + + +if nargin >= 2 + args = varargin; + nargs = length(args); + for i=1:2:nargs + switch args{i}, + case 'clusters', clusters = args{i+1}; + otherwise, error(['unrecognized argument ' args{i}]) + end + end +end + +if strcmp(clusters, 'exact') + %clusters = { compute_interface_nodes(bnet.intra, bnet.inter) }; + clusters = { 1:ss }; +elseif strcmp(clusters, 'ff') + clusters = num2cell(1:ss); +end + + +% We need to insert the prior on the clusters in slice 1, +% and extract the posterior on the clusters in slice 2. +C = length(clusters); +clusters2 = cell(1,2*C); +clusters2(1:C) = clusters; +for c=1:C + clusters2{c+C} = clusters{c} + ss; +end + +onodes = bnet.observed; +obs_nodes = [onodes(:) onodes(:)+ss]; +engine.sub_engine = jtree_inf_engine(bnet, 'clusters', clusters2); + +engine.clq_ass_to_cluster = zeros(C, 2); +for c=1:C + engine.clq_ass_to_cluster(c,1) = clq_containing_nodes(engine.sub_engine, clusters{c}); + engine.clq_ass_to_cluster(c,2) = clq_containing_nodes(engine.sub_engine, clusters{c}+ss); +end +engine.clusters = clusters; + +engine.clq_ass_to_node = zeros(ss, 2); +for i=1:ss + engine.clq_ass_to_node(i, 1) = clq_containing_nodes(engine.sub_engine, i); + engine.clq_ass_to_node(i, 2) = clq_containing_nodes(engine.sub_engine, i+ss); +end + + + +% 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.sub_engine1 = jtree_inf_engine(bnet1, 'clusters', clusters); + +engine.clq_ass_to_cluster1 = zeros(1,C); +for c=1:C + engine.clq_ass_to_cluster1(c) = clq_containing_nodes(engine.sub_engine1, clusters{c}); +end + +engine.clq_ass_to_node1 = zeros(1, ss); +for i=1:ss + engine.clq_ass_to_node1(i) = clq_containing_nodes(engine.sub_engine1, i); +end + +engine.clpot = []; % this is where we store the results between enter_evidence and marginal_nodes +engine.filter = []; +engine.maximize = []; +engine.T = []; + +engine.bel = []; +engine.bel_clpot = []; +engine.slice1 = []; +%engine.pot_type = 'cg'; +% hack for online inference so we can cope with hidden Gaussians and discrete +% it will not affect the pot type used in enter_evidence +engine.pot_type = determine_pot_type(bnet, onodes); + +engine = class(engine, 'bk_inf_engine', inf_engine(bnet)); + diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_init_bel.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_init_bel.m new file mode 100644 index 00000000..fa6a27de --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_init_bel.m @@ -0,0 +1,8 @@ +function engine = dbn_init_bel(engine) +% DBN_INIT_BEL Compute the initial belief state (bk) +% engine = dbn_init_bel(engine)) + +bnet = bnet_from_engine(engine); +ss = length(bnet.intra); +evidence = cell(1,ss); +engine = dbn_update_bel1(engine, evidence); diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_marginal_from_bel.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_marginal_from_bel.m new file mode 100644 index 00000000..7e5a968d --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_marginal_from_bel.m @@ -0,0 +1,18 @@ +function marginal = dbn_marginal_from_bel(engine, i) +% DBN_MARGINAL_FROM_BEL Compute the marginal on a node given the current belief state (bk) +% marginal = dbn_marginal_from_bel(engine, i) + +if engine.slice1 + j = i; + c = clq_containing_nodes(engine.sub_engine1, j); +else + bnet = bnet_from_engine(engine); + ss = length(bnet.intra); + j = i+ss; + c = clq_containing_nodes(engine.sub_engine, j); +end +assert(c >= 1); +bigpot = engine.bel_clpot{c}; + +pot = marginalize_pot(bigpot, j); +marginal = pot_to_marginal(pot); diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel.m new file mode 100644 index 00000000..0c8e02b5 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel.m @@ -0,0 +1,37 @@ +function [engine, loglik] = dbn_update_bel(engine, evidence) +% DBN_UPDATE_BEL Update the belief state (bk) +% [engine, loglik] = dbn_update_bel(engine, evidence) +% +% evidence{i,1} contains the evidence on node i in slice t-1 +% evidence{i,2} contains the evidence on node i in slice t + +oldbel = engine.bel; + +ss = size(evidence, 1); +bnet = bnet_from_engine(engine); +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(:), evidence); +end + +observed = ~isemptycell(evidence); +onodes2 = find(observed(:)); +clqs = [engine.clq_ass_to_cluster(:,1); engine.clq_ass_to_node(:,2)]; +pots = [oldbel(:); CPDpot(:)]; + +[clpot, loglik] = enter_soft_evidence(engine.sub_engine, clqs, pots, onodes2(:), engine.pot_type); + +C = length(engine.clusters); +newbel = cell(1,C); +for c=1:C + k = engine.clq_ass_to_cluster(c,2); + cl = engine.clusters{c}; + newbel{c} = marginalize_pot(clpot{k}, cl+ss); % extract slice 2 posterior + newbel{c} = set_domain_pot(newbel{c}, cl); % shift back to slice 1 for re-use as prior +end + +engine.bel = newbel; +engine.bel_clpot = clpot; +engine.slice1 = 0; diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel1.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel1.m new file mode 100644 index 00000000..a3b6cc79 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel1.m @@ -0,0 +1,30 @@ +function [engine, loglik] = dbn_update_bel1(engine, evidence) +% DBN_UPDATE_BEL1 Update the initial belief state (bk) +% engine = dbn_update_bel1(engine, evidence) +% +% evidence{i} has the evidence on node i for slice 1 + +bnet = bnet_from_engine(engine); +ss = length(bnet.intra); +CPDpot = cell(1,ss); +t = 1; +for n=1:ss + fam = family(bnet.dag, n); + e = bnet.equiv_class(n, 1); + CPDpot{n} = convert_to_pot(bnet.CPD{e}, engine.pot_type, fam(:), evidence); +end + +onodes = find(~isemptycell(evidence)); + +[clpot, loglik] = enter_soft_evidence(engine.sub_engine1, engine.clq_ass_to_node1, CPDpot, onodes, engine.pot_type); + +C = length(engine.clusters); +newbel = cell(1,C); +for c=1:C + k = engine.clq_ass_to_cluster1(c); + newbel{c} = marginalize_pot(clpot{k}, engine.clusters{c}); +end + +engine.bel = newbel; +engine.bel_clpot = clpot; +engine.slice1 = 1; diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_evidence.m new file mode 100644 index 00000000..7008137b --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_evidence.m @@ -0,0 +1,48 @@ +function [engine, loglik] = enter_evidence(engine, evidence, varargin) +% ENTER_EVIDENCE Add the specified evidence to the network (bk) +% [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] +% 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 + +[ss T] = size(evidence); +engine.filter = filter; +engine.maximize = maximize; +engine.T = T; + +if maximize + error('BK does not yet support max propagation') + % because it calls enter_soft_evidence, not enter_evidence +end + +observed_bitv = ~isemptycell(evidence); +onodes = find(observed_bitv); +bnet = bnet_from_engine(engine); +pot_type = determine_pot_type(bnet, onodes); +CPDpot = convert_dbn_CPDs_to_pots(bnet, evidence, pot_type); +[engine.clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed_bitv, pot_type, filter); + diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_soft_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_soft_evidence.m new file mode 100644 index 00000000..1cbc634e --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_soft_evidence.m @@ -0,0 +1,88 @@ +function [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter) +% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (bk) +% [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter) + +[ss T] = size(CPDpot); +C = length(engine.clusters); +Q = length(cliques_from_engine(engine.sub_engine)); +Q1 = length(cliques_from_engine(engine.sub_engine1)); +clpot = cell(Q,T); +alpha = cell(C,T); + +% Forwards +% The method is a generalization of the following HMM equation: +% alpha(j,t) = normalise( (sum_i alpha(i,t-1) * transmat(i,j)) * obsmat(j,t) ) +% where alpha(j,t) = Pr(Q(t)=j | y(1:t)) +t = 1; +[clpot(1:Q1,t), logscale(t)] = enter_soft_evidence(engine.sub_engine1, engine.clq_ass_to_node1(:), ... + CPDpot(:,1), find(observed(:,1)), pot_type); +for c=1:C + k = engine.clq_ass_to_cluster1(c); + alpha{c,t} = marginalize_pot(clpot{k,t}, engine.clusters{c}); +end +% For filtering, clpot{1} contains evidence on slice 1 only + +%fprintf('alphas t=%d\n', t); +%for c=1:8 +% temp = pot_to_marginal(alpha{c,t}); +% temp.T +%end + +% clpot{t} contains evidence from slices t-1, t for t > 1 +clqs = [engine.clq_ass_to_cluster(:,1); engine.clq_ass_to_node(:,2)]; +for t=2:T + pots = [alpha(:,t-1); CPDpot(:,t)]; + [clpot(:,t), logscale(t)] = enter_soft_evidence(engine.sub_engine, clqs, pots, find(observed(:,t-1:t)), pot_type); + for c=1:C + k = engine.clq_ass_to_cluster(c,2); + cl = engine.clusters{c}; + alpha{c,t} = marginalize_pot(clpot{k,t}, cl+ss); % extract slice 2 posterior + alpha{c,t} = set_domain_pot(alpha{c,t}, cl); % shift back to slice 1 for re-use as prior + end + +end + +loglik = sum(logscale); + +if filter + return; +end + +% Backwards +% The method is a generalization of the following HMM equation: +% beta(i,t) = (sum_j transmat(i,j) * obsmat(j,t+1) * beta(j,t+1)) +% where beta(i,t) = Pr(y(t+1:T) | Q(t)=i) +t = T; +bnet = bnet_from_engine(engine); +beta = cell(C,T); +for c=1:C + beta{c,t} = mk_initial_pot(pot_type, engine.clusters{c} + ss, bnet.node_sizes(:), bnet.cnodes(:), ... + find(observed(:,t-1:t))); +end +for t=T-1:-1:1 + clqs = [engine.clq_ass_to_cluster(:,2); engine.clq_ass_to_node(:,2)]; + pots = [beta(:,t+1); CPDpot(:,t+1)]; + temp = enter_soft_evidence(engine.sub_engine, clqs, pots, find(observed(:,t:t+1)), pot_type); + for c=1:C + k = engine.clq_ass_to_cluster(c,1); + cl = engine.clusters{c}; + beta{c,t} = marginalize_pot(temp{k}, cl); % extract slice 1 + beta{c,t} = set_domain_pot(beta{c,t}, cl + ss); % shift fwd to slice 2 + end +end + +% Combine +% The method is a generalization of 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)) +for t=1:T-1 + clqs = [engine.clq_ass_to_cluster(:); engine.clq_ass_to_node(:,2)]; + pots = [alpha(:,t); beta(:,t+1); CPDpot(:,t+1)]; + clpot(:,t+1) = enter_soft_evidence(engine.sub_engine, clqs, pots, find(observed(:,t:t+1)), pot_type); +end +% for smoothing, clpot{1} is undefined +for k=1:Q1 + clpot{k,1} = []; +end + + diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_family.m new file mode 100644 index 00000000..e948b836 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_family.m @@ -0,0 +1,25 @@ +function m = marginal_family(engine, i, t) +% MARGINAL_FAMILY Compute the marginal on the specified family (bk) +% marginal = marginal_family(engine, i, t) + +% This is just like inf_engine/marginal_family, except when we call +% marginal_nodes, we provide a 4th argument, to tell it's a family. + +if nargin < 3, t = 1; end + +bnet = bnet_from_engine(engine); +if t==1 + m = marginal_nodes(engine, family(bnet.dag, i), t, 1); +else + ss = length(bnet.intra); + fam = family(bnet.dag, i+ss); + if any(fam<=ss) + % i has a parent in the preceeding slice + % Hence the lowest numbered slice containing the family is t-1 + m = marginal_nodes(engine, fam, t-1, 1); + else + % The family all fits inside slice t + % Hence shift the indexes back to slice 1 + m = marginal_nodes(engine, fam-ss, t, 1); + end +end diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_nodes.m new file mode 100644 index 00000000..30bf9a9d --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_nodes.m @@ -0,0 +1,67 @@ +function marginal = marginal_nodes(engine, nodes, t, fam) +% MARGINAL_NODES Compute the marginal on the specified query nodes (bk) +% +% 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)). +% +% marginal = marginal_nodes(engine, query, t) +% returns Pr(X(query(1),t), ... X(query(end),t) | Y(1:T)), +% where X(q,t) is the q'th node in the t'th slice. If q > ss (slice size), this is equal +% to X(q mod ss, t+1). That is, 't' specifies the time slice of the earliest node. +% 'query' cannot span more than 2 time slices. +% Example: +% Consider a DBN with 2 nodes per slice. +% Then t=2, nodes=[1 3] refers to node 1 in slice 2 and node 1 in slice 3. + +if nargin < 3, t = 1; end +if nargin < 4, fam = 0; else fam = 1; end + + +% clpot{t} contains slice t-1 and t +% Example +% clpot #: 1 2 3 +% slices: 1 1,2 2,3 +% For filtering, we must take care not to take future evidence into account. +% For smoothing, clpot{1} does not exist. + +bnet = bnet_from_engine(engine); +ss = length(bnet.intra); + +nodes2 = nodes; +if ~engine.filter + if t < engine.T + slice = t+1; + else % earliest t is T, so all nodes fit in one slice + slice = engine.T; + nodes2 = nodes + ss; + end +else + if t == 1 + slice = 1; + else + if all(nodes<=ss) + slice = t; + nodes2 = nodes + ss; + elseif t == engine.T + slice = t; + else + slice = t + 1; + end + end +end + +if engine.filter & t==1 + c = clq_containing_nodes(engine.sub_engine1, nodes2, fam); +else + c = clq_containing_nodes(engine.sub_engine, nodes2, fam); +end +assert(c >= 1); +bigpot = engine.clpot{c, slice}; + +pot = marginalize_pot(bigpot, nodes2); +marginal = pot_to_marginal(pot); + +% 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/@bk_inf_engine/update_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/update_engine.m new file mode 100644 index 00000000..b36833a1 --- /dev/null +++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/update_engine.m @@ -0,0 +1,11 @@ +function engine = update_engine(engine, newCPDs) +% UPDATE_ENGINE Update the engine to take into account the new parameters (bk) +% engine = update_engine(engine, newCPDs) + +engine.inf_engine = update_engine(engine.inf_engine, newCPDs); +engine.sub_engine = update_engine(engine.sub_engine, newCPDs); + +bnet = bnet_from_engine(engine); +eclass1 = bnet.equiv_class(:,1); +engine.sub_engine1 = update_engine(engine.sub_engine1, newCPDs(1:max(eclass1))); + -- cgit 1.4.1