wolffd@0
|
1 function bnet = mk_hhmm2(varargin)
|
wolffd@0
|
2 % MK_HHMM2 Make a 2 level Hierarchical HMM
|
wolffd@0
|
3 % bnet = mk_hhmm2(...)
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % 2-layer hierarchical HMM (node numbers in parens)
|
wolffd@0
|
6 %
|
wolffd@0
|
7 % Q1(1) ---------> Q1(5)
|
wolffd@0
|
8 % / | \ / |
|
wolffd@0
|
9 % | | v / |
|
wolffd@0
|
10 % | | F2(3) --- / |
|
wolffd@0
|
11 % | | ^ \ |
|
wolffd@0
|
12 % | | / \ |
|
wolffd@0
|
13 % | v \ v
|
wolffd@0
|
14 % | Q2(2)--------> Q2 (6)
|
wolffd@0
|
15 % | |
|
wolffd@0
|
16 % \ |
|
wolffd@0
|
17 % v v
|
wolffd@0
|
18 % O(4)
|
wolffd@0
|
19 %
|
wolffd@0
|
20 %
|
wolffd@0
|
21 % Optional arguments [default]
|
wolffd@0
|
22 %
|
wolffd@0
|
23 % discrete_obs - 1 means O is tabular_CPD, 0 means O is gaussian_CPD [0]
|
wolffd@0
|
24 % obsCPT - CPT(o,q1,q2) params for O ['rnd']
|
wolffd@0
|
25 % mu - mu(:,q1,q2) params for O [ [] ]
|
wolffd@0
|
26 % Sigma - Sigma(:,q1,q2) params for O [ [] ]
|
wolffd@0
|
27 %
|
wolffd@0
|
28 % F2toQ1 - 1 if Q2 is an hhmm_CPD, 0 if F2 -> Q2 arc is absent, so level 2 never resets [1]
|
wolffd@0
|
29 % Q1args - arguments to be passed to the constructors for Q1(t=2) [ {} ]
|
wolffd@0
|
30 % Q2args - arguments to be passed to the constructors for Q2(t=2) [ {} ]
|
wolffd@0
|
31 %
|
wolffd@0
|
32 % F2 only turns on (wp 0.5) when Q2 enters its final state.
|
wolffd@0
|
33 % Q1 (slice 1) is clamped to be uniform.
|
wolffd@0
|
34 % Q2 (slice 1) is clamped to always start in state 1.
|
wolffd@0
|
35
|
wolffd@0
|
36 [os nmodels nstates] = size(mu);
|
wolffd@0
|
37
|
wolffd@0
|
38 ss = 4;
|
wolffd@0
|
39 Q1 = 1; Q2 = 2; F2 = 3; obs = 4;
|
wolffd@0
|
40 Qnodes = [Q1 Q2];
|
wolffd@0
|
41 names = {'Q1', 'Q2', 'F2', 'obs'};
|
wolffd@0
|
42 intra = zeros(ss);
|
wolffd@0
|
43 intra(Q1, [Q2 F2 obs]) = 1;
|
wolffd@0
|
44 intra(Q2, [F2 obs]) = 1;
|
wolffd@0
|
45
|
wolffd@0
|
46 inter = zeros(ss);
|
wolffd@0
|
47 inter(Q1,Q1) = 1;
|
wolffd@0
|
48 inter(F2,Q1) = 1;
|
wolffd@0
|
49 if F2toQ2
|
wolffd@0
|
50 inter(F2,Q2)=1;
|
wolffd@0
|
51 end
|
wolffd@0
|
52 inter(Q2,Q2) = 1;
|
wolffd@0
|
53
|
wolffd@0
|
54 ns = zeros(1,ss);
|
wolffd@0
|
55
|
wolffd@0
|
56 ns(Q1) = nmodels;
|
wolffd@0
|
57 ns(Q2) = nstates;
|
wolffd@0
|
58 ns(F2) = 2;
|
wolffd@0
|
59 ns(obs) = os;
|
wolffd@0
|
60
|
wolffd@0
|
61 dnodes = [Q1 Q2 F2];
|
wolffd@0
|
62 if discrete_obs
|
wolffd@0
|
63 dnodes = [dnodes obs];
|
wolffd@0
|
64 end
|
wolffd@0
|
65 onodes = [obs];
|
wolffd@0
|
66
|
wolffd@0
|
67 bnet = mk_dbn(intra, inter, ns, 'observed', onodes, 'discrete', dnodes, 'names', names);
|
wolffd@0
|
68 eclass = bnet.equiv_class;
|
wolffd@0
|
69
|
wolffd@0
|
70 % SLICE 1
|
wolffd@0
|
71
|
wolffd@0
|
72 % We clamp untied nodes in the first slice, since their params can't be estimated
|
wolffd@0
|
73 % from just one sequence
|
wolffd@0
|
74
|
wolffd@0
|
75 % uniform prior on initial model
|
wolffd@0
|
76 CPT = normalise(ones(1,nmodels));
|
wolffd@0
|
77 bnet.CPD{eclass(Q1,1)} = tabular_CPD(bnet, Q1, 'CPT', CPT, 'adjustable', 0);
|
wolffd@0
|
78
|
wolffd@0
|
79 % each model always starts in state 1
|
wolffd@0
|
80 CPT = zeros(ns(Q1), ns(Q2));
|
wolffd@0
|
81 CPT(:, 1) = 1.0;
|
wolffd@0
|
82 bnet.CPD{eclass(Q2,1)} = tabular_CPD(bnet, Q2, 'CPT', CPT, 'adjustable', 0);
|
wolffd@0
|
83
|
wolffd@0
|
84 % Termination probability
|
wolffd@0
|
85 CPT = zeros(ns(Q1), ns(Q2), 2);
|
wolffd@0
|
86 if 1
|
wolffd@0
|
87 % Each model can only terminate in its final state.
|
wolffd@0
|
88 % 0 params will remain 0 during EM, thus enforcing this constraint.
|
wolffd@0
|
89 CPT(:, :, 1) = 1.0; % all states turn F off ...
|
wolffd@0
|
90 p = 0.5;
|
wolffd@0
|
91 CPT(:, ns(Q2), 2) = p; % except the last one
|
wolffd@0
|
92 CPT(:, ns(Q2), 1) = 1-p;
|
wolffd@0
|
93 end
|
wolffd@0
|
94 bnet.CPD{eclass(F2,1)} = tabular_CPD(bnet, F2, 'CPT', CPT);
|
wolffd@0
|
95
|
wolffd@0
|
96 if discrete_obs
|
wolffd@0
|
97 bnet.CPD{eclass(obs,1)} = tabular_CPD(bnet, obs, obs_args{:});
|
wolffd@0
|
98 else
|
wolffd@0
|
99 bnet.CPD{eclass(obs,1)} = gaussian_CPD(bnet, obs, obs_args{:});
|
wolffd@0
|
100 end
|
wolffd@0
|
101
|
wolffd@0
|
102 % SLICE 2
|
wolffd@0
|
103
|
wolffd@0
|
104
|
wolffd@0
|
105 bnet.CPD{eclass(Q1,2)} = hhmm_CPD(bnet, Q1+ss, Qnodes, 1, D, 'args', Q1args);
|
wolffd@0
|
106
|
wolffd@0
|
107 if F2toQ2
|
wolffd@0
|
108 bnet.CPD{eclass(Q2,2)} = hhmmQD_CPD(bnet, Q2+ss, Qnodes, 2, D, Q2args{:});
|
wolffd@0
|
109 else
|
wolffd@0
|
110 bnet.CPD{eclass(Q2,2)} = tabular_CPD(bnet, Q2+ss, Q2args{:});
|
wolffd@0
|
111 end
|