To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / _FullBNT / BNT / CPDs / @hhmmF_CPD / Old / hhmmF_CPD.m @ 8:b5b38998ef3b
History | View | Annotate | Download (2.22 KB)
| 1 |
function CPD = hhmmF_CPD(bnet, self, Qnodes, d, D, varargin) |
|---|---|
| 2 |
% HHMMF_CPD Make the CPD for an F node at depth D of a D-level hierarchical HMM |
| 3 |
% CPD = hhmmF_CPD(bnet, self, Qnodes, d, D, ...) |
| 4 |
% |
| 5 |
% Q(d-1) |
| 6 |
% \ |
| 7 |
% \ |
| 8 |
% F(d) |
| 9 |
% / | |
| 10 |
% / | |
| 11 |
% Q(d) F(d+1) |
| 12 |
% |
| 13 |
% We assume nodes are ordered (numbered) as follows: |
| 14 |
% Q(1), ... Q(d), F(d+1), F(d) |
| 15 |
% |
| 16 |
% F(d)=2 means level d has finished. The prob this happens depends on Q(d) |
| 17 |
% and optionally on Q(d-1), Q(d=1), ..., Q(1). |
| 18 |
% Also, level d can only finish if the level below has finished |
| 19 |
% (hence the F(d+1) -> F(d) arc). |
| 20 |
% |
| 21 |
% If d=D, there is no F(d+1), so F(d) is just a regular tabular_CPD. |
| 22 |
% If all models always finish in the same state (e.g., their last), |
| 23 |
% we don't need to condition on the state of parent models (Q(d-1), ...) |
| 24 |
% |
| 25 |
% optional args [defaults] |
| 26 |
% |
| 27 |
% termprob - termprob(k,i,2) = prob finishing given Q(d)=i and Q(1:d-1)=k [ finish in last state ] |
| 28 |
% |
| 29 |
% hhmmF_CPD is a subclass of tabular_CPD so we inherit inference methods like CPD_to_pot, etc. |
| 30 |
% |
| 31 |
% We create an isolated tabular_CPD with no F parent to learn termprob |
| 32 |
% so we can avail of e.g., entropic or Dirichlet priors. |
| 33 |
% |
| 34 |
% For details, see "Linear-time inference in hierarchical HMMs", Murphy and Paskin, NIPS'01. |
| 35 |
|
| 36 |
|
| 37 |
ps = parents(bnet.dag, self); |
| 38 |
Qps = myintersect(ps, Qnodes); |
| 39 |
F = mysetdiff(ps, Qps); |
| 40 |
CPD.Q = Qps(end); % Q(d) |
| 41 |
assert(CPD.Q == Qnodes(d)); |
| 42 |
CPD.Qps = Qps(1:end-1); % all Q parents except Q(d), i.e., calling context |
| 43 |
|
| 44 |
ns = bnet.node_sizes(:); |
| 45 |
CPD.Qsizes = ns(Qnodes); |
| 46 |
CPD.d = d; |
| 47 |
CPD.D = D; |
| 48 |
|
| 49 |
Qsz = ns(CPD.Q); |
| 50 |
Qpsz = prod(ns(CPD.Qps)); |
| 51 |
|
| 52 |
% set default arguments |
| 53 |
p = 0.9; |
| 54 |
%termprob(k,i,t) Might terminate if i=Qsz; will not terminate if i<Qsz |
| 55 |
termprob = zeros(Qpsz, Qsz, 2); |
| 56 |
termprob(:, Qsz, 2) = p; |
| 57 |
termprob(:, Qsz, 1) = 1-p; |
| 58 |
termprob(:, 1:(Qsz-1), 1) = 1; |
| 59 |
|
| 60 |
for i=1:2:length(varargin) |
| 61 |
switch varargin{i},
|
| 62 |
case 'termprob', termprob = varargin{i+1};
|
| 63 |
otherwise, error(['unrecognized argument ' varargin{i}])
|
| 64 |
end |
| 65 |
end |
| 66 |
|
| 67 |
ps = [CPD.Qps CPD.Q]; |
| 68 |
% ns(self) = 2 since this is an F node |
| 69 |
CPD.sub_CPD_term = mk_isolated_tabular_CPD(ps, ns([ps self]), {'CPT', termprob});
|
| 70 |
S = struct(CPD.sub_CPD_term); |
| 71 |
CPD.termprob = S.CPT; |
| 72 |
|
| 73 |
CPD = class(CPD, 'hhmmF_CPD', tabular_CPD(bnet, self)); |
| 74 |
|
| 75 |
CPD = update_CPT(CPD); |
| 76 |
|