📄 enter_evidence.m
字号:
function [engine, loglik] = enter_evidence(engine, evidence, varargin)
% ENTER_EVIDENCE enter evidence to engine including discrete and continuous evidence
% [engine, ll] = enter_evidence(engine, evidence)
%
% ll is always 0, which is wrong.
if ~isempty(engine.evidence)
bnet = bnet_from_engine(engine);
engine = stab_cond_gauss_inf_engine(bnet);
engine.evidence = evidence;
else
engine.evidence = evidence;
bnet = bnet_from_engine(engine);
end
engine.evidence = evidence;
bnet = bnet_from_engine(engine);
ns = bnet.node_sizes(:);
observed = ~isemptycell(evidence);
onodes = find(observed);
hnodes = find(isemptycell(evidence));
cobs = myintersect(bnet.cnodes, onodes);
dobs = myintersect(bnet.dnodes, onodes);
engine = incorporate_dis_evidence(engine, dobs, evidence);
l = length(cobs);
for i = 1:l
node = cobs(i);
engine = incorporate_singleconts_evidence(engine, node, evidence);
end
clpot = engine.clpot;
clq_num = length(engine.cliques);
for n=engine.postorder(1:end-1)
for p=parents(engine.jtree, n)
[margpot, comppot] = complement_pot(clpot{n}, engine.separator{p,n});
clpot{n} = comppot;
clpot{p} = combine_pots(clpot{p}, margpot);
end
end
temppot = clpot;
for n=engine.preorder
for c=children(engine.jtree, n)
seppot{n,c} = marginalize_pot(temppot{n}, engine.separator{n,c});
temppot{c} = direct_combine_pots(temppot{c}, seppot{n,c});
end
end
engine.clpot = clpot;
engine.seppot = seppot;
[pot,loglik]=normalize_pot(clpot{engine.root});
%%%%%%%%%%%%%%%%%%
function engine = incorporate_dis_evidence(engine, donodes, evidence)
l = length(donodes);
for i=donodes(:)'
node = i;
clqid = engine.clq_ass_to_node(node);
pot = struct(engine.clpot{clqid});
ns = zeros(1, max(pot.domain));
ns(pot.ddom) = pot.dsizes;
ns(pot.cheaddom) = pot.cheadsizes;
ns(pot.ctaildom) = pot.ctailsizes;
ddom = pot.ddom;
potcarray = cell(1, pot.dsize);
for j =1:pot.dsize
tpotc = struct(pot.scgpotc{j});
potcarray{j} = scgcpot(tpotc.cheadsize, tpotc.ctailsize, 0, tpotc.A, tpotc.B, tpotc.C);
end
if length(ns(ddom)) == 1
matrix = pot.scgpotc;
else
matrix = reshape(pot.scgpotc,ns(ddom));
potcarray = reshape(potcarray, ns(ddom));
end
map = find_equiv_posns(node, ddom);
vals = cat(1, evidence{node});
index = mk_multi_index(length(ddom), map, vals);
potcarray(index{:}) = matrix(index{:});
potcarray = potcarray(:);
%keyboard;
engine.clpot{clqid} = scgpot(pot.ddom, pot.cheaddom, pot.ctaildom, ns, potcarray);
end
%%%%%%%%%%%%%%%%%%
function engine = incorporate_singleconts_evidence(engine, node, evidence)
%incorporate_singleconts_evidence incorporate evidence of 1 continuous node
B = engine.cliques_bitv;
clqs_containnode = find(all(B(:,node), 2)); % all selected columns must be 1
% Every continuous node necessarily apears as head in exactly one clique,
% which is the clique where it appears closest to the strong root. In all other
% clique potentials where it appears, it must be a tail node.
clq_ev_as_head = [];
for i = clqs_containnode(:)'
pot = struct(engine.clpot{i});
if myismember(node, pot.cheaddom)
clq_ev_as_head = [clq_ev_as_head i];
break;
end
end
% If we will incorporate the evidence node which is head of a potential we must rearrange
% the juntion tree by push operation until the tail of the include potential is empty
if ~isempty(clq_ev_as_head)
assert(1 == length(clq_ev_as_head));
i = clq_ev_as_head;
pot = struct(engine.clpot{i});
while ~isempty(pot.ctaildom)
[engine, clqtoroot] = push(engine, i, node);
i = clqtoroot;
pot = struct(engine.clpot{i});
end
B = engine.cliques_bitv;
clqs_containnode = find(all(B(:,node), 2));
end
for i = clqs_containnode(:)'
pot = struct(engine.clpot{i});
if myismember(node, pot.cheaddom)
engine.clpot{i} = incoporate_evidence_headnode(engine.clpot{i}, node, evidence);
else
%assert(myismember(node, pot.ctaildom));
engine.clpot{i} = incoporate_evidence_tailnode(engine.clpot{i}, node, evidence);
end
end
%%%%%%%%%%%%%%%%%%
function newscgpot = incoporate_evidence_tailnode(pot, node, evidence)
%ENTER_EVIDENCE_TAILNODE enter the evidence of 1 tailnode of the scgpot
newscgpot = pot;
pot = struct(pot);
%if isempty(pot.ctaildom)
if ~myismember(node, pot.ctaildom)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% In this case there is no real dependency of the head nodes %
% on the tail. The potential should be returned unchanged %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
return;
end
%newscgpot = scgpot([], [], [], []);
assert(myismember(node, pot.ctaildom));
ni = block(find_equiv_posns(node, pot.ctaildom), pot.ctailsizes);
ctaildom = mysetdiff(pot.ctaildom, node);
cheaddom = pot.cheaddom;
ddom = pot.ddom;
domain = mysetdiff(pot.domain, node);
dsize = pot.dsize;
ns = zeros(1, max(pot.domain));
ns(pot.ddom) = pot.dsizes;
ns(pot.cheaddom) = pot.cheadsizes;
ns(pot.ctaildom) = pot.ctailsizes;
cheadsizes = pot.cheadsizes;
cheadsize = pot.cheadsize;
ctailsizes = ns(ctaildom);
ctailsize = sum(ns(ctaildom));
potarray = cell(1, dsize);
for i=1:dsize
potc = struct(pot.scgpotc{i});
B = potc.B;
A = potc.A + B(:, ni)*evidence{node};
B(:, ni) = [];
potarray{i} = scgcpot(cheadsize, ctailsize, potc.p, A, B, potc.C);
end
newscgpot = scgpot(ddom, cheaddom, ctaildom, ns, potarray);
%%%%%%%%%%%%%%%%
function newscgpot = incoporate_evidence_headnode(pot, node, evidence)
%ENTER_EVIDENCE_HEADNODE
pot = struct(pot);
y2 = evidence{node};
assert(myismember(node, pot.cheaddom));
assert(isempty(pot.ctaildom));
ddom = pot.ddom;
cheaddom = mysetdiff(pot.cheaddom, node);
ctaildom = pot.ctaildom;
dsize = pot.dsize;
domain = mysetdiff(pot.domain, node);
ns = zeros(1, max(pot.domain));
ns(pot.ddom) = pot.dsizes;
ns(pot.cheaddom) = pot.cheadsizes;
ns(pot.ctaildom) = pot.ctailsizes;
ctailsizes = ns(ctaildom);
ctailsize = sum(ctailsizes);
cheadsizes = ns(cheaddom);
cheadsize = sum(cheadsizes);
onodesize = ns(node);
p = zeros(1,dsize);
A1 = zeros(cheadsize, dsize);
A2 = zeros(onodesize, dsize);
C11 = zeros(cheadsize, cheadsize, dsize);
C12 = zeros(cheadsize, onodesize, dsize);
C21 = zeros(onodesize, cheadsize, dsize);
C22 = zeros(onodesize, onodesize, dsize);
ZM = zeros(onodesize, onodesize);
n1i = block(find_equiv_posns(cheaddom, pot.cheaddom), pot.cheadsizes);
n2i = block(find_equiv_posns(node, pot.cheaddom), pot.cheadsizes);
indic = 0;
for i=1:dsize
potc = struct(pot.scgpotc{i});
p(i) = potc.p;
if ~isempty(n1i)
A1(:,i) = potc.A(n1i);
end
if ~isempty(n2i)
A2(:,i) = potc.A(n2i);
end
C11(:,:,i) = potc.C(n1i, n1i);
C12(:,:,i) = potc.C(n1i, n2i);
C21(:,:,i) = potc.C(n2i, n1i);
C22(:,:,i) = potc.C(n2i, n2i);
if isequal(0, C22(:,:,i)) & isequal(evidence{node}, A2(:, i))
indic = i;
end
end
np = zeros(1,dsize);
nA = zeros(cheadsize, dsize);
nC = zeros(cheadsize, cheadsize, dsize);
if indic
np(:) = 0;
np(indic) = p(indic);
nA = A1;
nC = C11;
else
for i=1:dsize
if isequal(0, C22(:,:,i))
p(i) = 0;
nA(:, i) = A1(:, i);
nC(:,:,i) = C11(:,:,i);
else
sq = (y2 - A2(:,i))' * inv(C22(:,:,i)) * (y2 - A2(:,i));
ex = exp(-0.5*sq);
%np(i) = p(i) * ex / ( (2 * pi)^(-onodesize/2) * sqrt(det(C22(:,:,i))) );
np(i) = p(i) * ex / ( (2 * pi)^(onodesize/2) * sqrt(det(C22(:,:,i))) );
nA(:,i) = A1(:,i) + C12(:,:,i) * inv(C22(:,:,i)) * (y2 - A2(:,i));
tmp1 = C12(:,:,i) * inv(C22(:,:,i)) * C21(:,:,i);
nC(:,:,i) = C11(:,:,i) - tmp1;
end
end
end
scpot = cell(1, dsize);
W = zeros(cheadsize,ctailsize);
for i=1:dsize
scpot{i} = scgcpot(cheadsize, ctailsize, np(i), nA(:,i), W, nC(:,:,i));
end
ns(node) = 0;
newscgpot = scgpot(ddom, cheaddom, ctaildom, ns, scpot);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -