1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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
|