about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM
diff options
context:
space:
mode:
authorziejd22017-09-28 15:04:40 -0500
committerziejd22017-09-28 15:04:40 -0500
commit8070dc963753142bb86c4ed698d91fd623ed28e7 (patch)
treed0f6dd8fc46a49b819aa55c1a90faa14d8448883 /sourcecodes/bnt-master/BNT/examples/dynamic/HHMM
parent7cc31810d53176e805532b2789955f4eedbce6bb (diff)
downloadBNW-8070dc963753142bb86c4ed698d91fd623ed28e7.tar.gz
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
Diffstat (limited to 'sourcecodes/bnt-master/BNT/examples/dynamic/HHMM')
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries9
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries.Log5
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/mk_map_hhmm.m156
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/disp_map_hhmm.m13
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/learn_map.m40
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_map_hhmm.m181
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_rnd_map_hhmm.m73
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/sample_from_map.m41
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/mgram2.m191
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/letter2num.m12
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram1.m116
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram2.m200
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram3.m235
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/num2letter.m10
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/fixed_args_mk_motif_hhmm.m99
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/learn_motif_hhmm.m75
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/mk_motif_hhmm.m137
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/sample_motif_hhmm.m10
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Entries8
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_abcd_hhmm.m109
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_arrow_alpha_hhmm3.m86
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm2.m111
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3.m181
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3_args.m165
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/motif_hhmm.m95
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/remove_hhmm_end_state.m37
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Entries14
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/learn_square_hhmm.m294
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/mk_square_hhmm.m183
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/plot_square_hhmm.m32
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/sample_square_hhmm.m160
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/get_square_data.m70
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/hhmm_inference.m13
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/is_F2_true_D3.m12
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_cts.m152
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_discrete.m171
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/mk_square_hhmm.m180
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/plot_square_hhmm.m27
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_cts.m20
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_discrete.m20
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4.matbin0 -> 34672 bytes
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4_cases.matbin0 -> 156432 bytes
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.m1310
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.matbin0 -> 5304 bytes
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/abcd_hhmm.m97
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/add_hhmm_end_state.m34
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/hhmm_jtree_clqs.m143
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm.m258
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo.m76
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo_F1.m65
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/pretty_print_hhmm_parse.m67
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/remove_hhmm_end_state.m41
76 files changed, 5878 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries
new file mode 100644
index 00000000..6c5b3923
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries
@@ -0,0 +1,9 @@
+/abcd_hhmm.m/1.1.1.1/Sat Sep 21 21:37:54 2002//
+/add_hhmm_end_state.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/hhmm_jtree_clqs.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_hhmm.m/1.1.1.1/Sat Sep 21 20:58:06 2002//
+/mk_hhmm_topo.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_hhmm_topo_F1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/pretty_print_hhmm_parse.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/remove_hhmm_end_state.m/1.1.1.1/Mon Dec 16 19:16:50 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries.Log
new file mode 100644
index 00000000..1b0fe64f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries.Log
@@ -0,0 +1,5 @@
+A D/Map////
+A D/Mgram////
+A D/Motif////
+A D/Old////
+A D/Square////
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Repository
new file mode 100644
index 00000000..2ba8b9e6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Entries
new file mode 100644
index 00000000..dc32f52b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Entries
@@ -0,0 +1,6 @@
+/disp_map_hhmm.m/1.1.1.1/Tue Sep 24 22:45:56 2002//
+/learn_map.m/1.1.1.1/Sat Jan 11 18:48:46 2003//
+/mk_map_hhmm.m/1.1.1.1/Tue Sep 24 10:49:52 2002//
+/mk_rnd_map_hhmm.m/1.1.1.1/Tue Sep 24 22:13:48 2002//
+/sample_from_map.m/1.1.1.1/Tue Sep 24 13:02:30 2002//
+D/Old////
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Repository
new file mode 100644
index 00000000..66b47bbc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Map
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Entries
new file mode 100644
index 00000000..6079d451
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Entries
@@ -0,0 +1,2 @@
+/mk_map_hhmm.m/1.1.1.1/Tue Sep 24 07:02:44 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Repository
new file mode 100644
index 00000000..354057a9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Map/Old
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/mk_map_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/mk_map_hhmm.m
new file mode 100644
index 00000000..7b646745
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/mk_map_hhmm.m
@@ -0,0 +1,156 @@
+function bnet = mk_map_hhmm(varargin)
+
+% p is the prob of a successful move (defines the reliability of motors)
+p = 1;
+num_obs_nodes = 1;
+
+for i=1:2:length(varargin)
+  switch varargin{i},
+   case 'p', p = varargin{i+1};
+   case 'numobs', num_obs_node = varargin{i+1};
+  end
+end
+
+
+q = 1-p;
+
+% assign numbers to the nodes in topological order
+U = 1; A = 2; C = 3; F = 4; O = 5;
+
+% create graph structure
+
+ss = 5; % slice size
+intra = zeros(ss,ss);
+intra(U,F)=1;
+intra(A,[C F O])=1;
+intra(C,[F O])=1;
+
+inter = zeros(ss,ss);
+inter(U,[A C])=1;
+inter(A,[A C])=1;
+inter(F,[A C])=1;
+inter(C,C)=1;
+
+% node sizes
+ns = zeros(1,ss);
+ns(U) = 2; % left/right
+ns(A) = 2;
+ns(C) = 3;
+ns(F) = 2;
+ns(O) = 5; % we will assign each state a unique symbol
+l = 1; r = 2; % left/right
+L = 1; R = 2;
+
+% Make the DBN
+bnet = mk_dbn(intra, inter, ns, 'observed', O);
+eclass = bnet.equiv_class;
+
+
+
+% Define CPDs for slice 1
+% We clamp all of them, i.e., do not try to learn them.
+
+% uniform probs over actions (the input could be chosen from a policy)
+bnet.CPD{eclass(U,1)} = tabular_CPD(bnet, U, 'CPT', mk_stochastic(ones(ns(U),1)), ...
+				    'adjustable', 0);
+
+% uniform probs over starting abstract state
+bnet.CPD{eclass(A,1)} = tabular_CPD(bnet, A, 'CPT', mk_stochastic(ones(ns(A),1)), ...
+				    'adjustable', 0);
+
+% Uniform probs over starting concrete state, modulo the fact
+% that corridor 2 is only of length 2.
+CPT = zeros(ns(A), ns(C)); % CPT(i,j) = P(C starts in j | A=i)
+CPT(1, :) = [1/3 1/3 1/3];
+CPT(2, :) = [1/2 1/2 0];
+bnet.CPD{eclass(C,1)} = tabular_CPD(bnet, C, 'CPT', CPT, 'adjustable', 0);
+
+% Termination probs
+CPT = zeros(ns(U), ns(A), ns(C), ns(F));
+CPT(r,1,1,:) = [1 0];
+CPT(r,1,2,:) = [1 0];
+CPT(r,1,3,:) = [q p];
+CPT(r,2,1,:) = [1 0];
+CPT(r,2,2,:) = [q p];
+CPT(l,1,1,:) = [q p];
+CPT(l,1,2,:) = [1 0];
+CPT(l,1,3,:) = [1 0];
+CPT(l,2,1,:) = [q p];
+CPT(l,2,2,:) = [1 0];
+
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', CPT);
+
+
+% Assign each state a unique observation
+CPT = zeros(ns(A), ns(C), ns(O));
+CPT(1,1,1)=1; 
+CPT(1,2,2)=1;
+CPT(1,3,3)=1;
+CPT(2,1,4)=1;
+CPT(2,2,5)=1;
+%CPT(2,3,:) undefined
+
+bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', CPT);
+
+
+% Define the CPDs for slice 2
+
+% Abstract
+
+% Since the top level never resets, the starting distribution is irrelevant:
+% A2 will be determined by sampling from transmat(A1,:).
+% But the code requires we specify it anyway; we make it all 0s, a dummy value.
+startprob = zeros(ns(U), ns(A));
+
+transmat = zeros(ns(U), ns(A), ns(A));
+transmat(R,1,:) = [q p];
+transmat(R,2,:) = [0 1];
+transmat(L,1,:) = [1 0];
+transmat(L,2,:) = [p q];
+
+% Qps are the parents we condition the parameters on, in this case just
+% the past action.
+bnet.CPD{eclass(A,2)} = hhmm2Q_CPD(bnet, A+ss, 'Fbelow', F, ...
+				  'startprob', startprob, 'transprob', transmat);
+
+
+
+% Concrete
+
+transmat = zeros(ns(C), ns(U), ns(A), ns(C));
+transmat(1,r,1,:) = [q p 0.0];
+transmat(2,r,1,:) = [0.0 q p];
+transmat(3,r,1,:) = [0.0 0.0 1.0];
+transmat(1,r,2,:) = [q p 0.0];
+transmat(2,r,2,:) = [0.0 1.0 0.0];
+%
+transmat(1,l,1,:) = [1.0 0.0 0.0];
+transmat(2,l,1,:) = [p q 0.0];
+transmat(3,l,1,:) = [0.0 p q];
+transmat(1,l,2,:) = [1.0 0.0 0.0];
+transmat(2,l,2,:) = [p q 0.0];
+
+% Add a new dimension for A(t-1), by copying old vals,
+% so the matrix is the same size as startprob
+
+
+transmat = reshape(transmat, [ns(C) ns(U) ns(A) 1 ns(C)]);
+transmat = repmat(transmat, [1 1 1 ns(A) 1]);
+
+% startprob(C(t-1), U(t-1), A(t-1), A(t), C(t))
+startprob = zeros(ns(C), ns(U), ns(A), ns(A), ns(C));
+startprob(1,L,1,1,:) = [1.0 0.0 0.0];
+startprob(3,R,1,2,:) = [1.0 0.0 0.0];
+startprob(3,R,1,1,:) = [0.0 0.0 1.0];
+% 
+startprob(1,L,2,1,:) = [0.0 0.0 010];
+startprob(2,L,2,1,:) = [1.0 0.0 0.0];
+startprob(2,R,2,2,:) = [0.0 1.0 0.0];
+
+% want transmat(U,A,C,At,Ct), ie. in topo order
+transmat = permute(transmat, [2 3 1 4 5]);
+startprob  = permute(startprob, [2 3 1 4 5]);
+bnet.CPD{eclass(C,2)} = hhmm2Q_CPD(bnet, C+ss, 'Fself', F, ...
+				  'startprob', startprob, 'transprob', transmat);
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/disp_map_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/disp_map_hhmm.m
new file mode 100644
index 00000000..0aadf2bb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/disp_map_hhmm.m
@@ -0,0 +1,13 @@
+function disp_map_hhmm(bnet)
+
+eclass = bnet.equiv_class;
+U = 1; A = 2; C = 3; F = 4;
+
+S = struct(bnet.CPD{eclass(A,2)});
+disp('abstract trans')
+dispcpt(S.transprob)
+
+S = struct(bnet.CPD{eclass(C,2)});
+disp('concrete trans for go left') % UAC AC
+dispcpt(squeeze(S.transprob(1,:,:,:,:)))
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/learn_map.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/learn_map.m
new file mode 100644
index 00000000..ac36586a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/learn_map.m
@@ -0,0 +1,40 @@
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+obs_model = 'unique';  % each cell has a unique label (essentially fully observable)
+%obs_model = 'four'; % each cell generates 4 observations, NESW
+
+% Generate the true network, and a randomization of it
+realnet = mk_map_hhmm('p', 0.9, 'obs_model', obs_model);
+rndnet = mk_rnd_map_hhmm('obs_model', obs_model);
+eclass = realnet.equiv_class;
+U = 1; A = 2; C = 3; F = 4; onodes = 5;
+
+ss = realnet.nnodes_per_slice;
+T = 100;
+evidence = sample_dbn(realnet, 'length', T);
+ev = cell(ss,T);
+ev(onodes,:) = evidence(onodes,:);
+
+infeng = jtree_dbn_inf_engine(rndnet);
+
+if 0
+% suppose we do not observe the final finish node, but only know 
+% it is more likely to be on that off
+ev2 = ev;
+infeng = enter_evidence(infeng, ev2, 'soft_evidence_nodes', [F T], 'soft_evidence',  {[0.3 0.7]'});
+end
+
+
+learnednet = learn_params_dbn_em(infeng, {evidence}, 'max_iter', 5);
+
+disp('real model')
+disp_map_hhmm(realnet)
+
+disp('learned model')
+disp_map_hhmm(learnednet)
+
+disp('rnd model')
+disp_map_hhmm(rndnet)
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_map_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_map_hhmm.m
new file mode 100644
index 00000000..7b077ddb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_map_hhmm.m
@@ -0,0 +1,181 @@
+function bnet = mk_map_hhmm(varargin)
+
+% p is the prob of a successful move (defines the reliability of motors)
+p = 1;
+obs_model = 'unique';
+
+for i=1:2:length(varargin)
+  switch varargin{i},
+   case 'p', p = varargin{i+1};
+   case 'obs_model', obs_model = varargin{i+1};
+  end
+end
+
+
+q = 1-p;
+unique_obs = strcmp(obs_model, 'unique');
+
+% assign numbers to the nodes in topological order
+U = 1; A = 2; C = 3; F = 4;
+if unique_obs
+  onodes = 5;
+else
+  N = 5; E = 6; S = 7; W = 8; % north, east, south, west
+  onodes = [N E S W];
+end
+
+% create graph structure
+
+ss = 4 + length(onodes); % slice size
+intra = zeros(ss,ss);
+intra(U,F)=1;
+intra(A,[C F onodes])=1;
+intra(C,[F onodes])=1;
+
+inter = zeros(ss,ss);
+inter(U,[A C])=1;
+inter(A,[A C])=1;
+inter(F,[A C])=1;
+inter(C,C)=1;
+
+% node sizes
+ns = zeros(1,ss);
+ns(U) = 2; % left/right
+ns(A) = 2;
+ns(C) = 3;
+ns(F) = 2;
+if unique_obs
+  ns(onodes) = 5; % we will assign each state a unique symbol
+else
+  ns(onodes) = 2;
+end
+l = 1; r = 2; % left/right
+L = 1; R = 2;
+
+% Make the DBN
+bnet = mk_dbn(intra, inter, ns, 'observed', onodes);
+eclass = bnet.equiv_class;
+
+
+
+% Define CPDs for slice 1
+% We clamp all the CPDs that are not tied,
+% since we cannot learn them from a single sequence.
+
+% uniform probs over actions (the input could be chosen from a policy)
+bnet.CPD{eclass(U,1)} = tabular_CPD(bnet, U, 'CPT', mk_stochastic(ones(ns(U),1)), ...
+				    'adjustable', 0);
+
+% uniform probs over starting abstract state
+bnet.CPD{eclass(A,1)} = tabular_CPD(bnet, A, 'CPT', mk_stochastic(ones(ns(A),1)), ...
+				    'adjustable', 0);
+
+% Uniform probs over starting concrete state, modulo the fact
+% that corridor 2 is only of length 2.
+CPT = zeros(ns(A), ns(C)); % CPT(i,j) = P(C starts in j | A=i)
+CPT(1, :) = [1/3 1/3 1/3];
+CPT(2, :) = [1/2 1/2 0];
+bnet.CPD{eclass(C,1)} = tabular_CPD(bnet, C, 'CPT', CPT, 'adjustable', 0);
+
+% Termination probs
+CPT = zeros(ns(U), ns(A), ns(C), ns(F));
+CPT(r,1,1,:) = [1 0];
+CPT(r,1,2,:) = [1 0];
+CPT(r,1,3,:) = [q p];
+CPT(r,2,1,:) = [1 0];
+CPT(r,2,2,:) = [q p];
+CPT(l,1,1,:) = [q p];
+CPT(l,1,2,:) = [1 0];
+CPT(l,1,3,:) = [1 0];
+CPT(l,2,1,:) = [q p];
+CPT(l,2,2,:) = [1 0];
+
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', CPT);
+
+
+% Observation model
+if unique_obs
+  CPT = zeros(ns(A), ns(C), 5);
+  CPT(1,1,1)=1;  % Theo state 4
+  CPT(1,2,2)=1;  % Theo state 5
+  CPT(1,3,3)=1; % Theo state 6
+  CPT(2,1,4)=1; % Theo state 9
+  CPT(2,2,5)=1; % Theo state 10
+  %CPT(2,3,:) undefined
+  O = onodes(1);
+  bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', CPT);
+else
+  % north/east/south/west can see wall (1) or opening (2)
+  CPT = zeros(ns(A), ns(C), 2);
+  CPT(:,:,1) = q;
+  CPT(:,:,2) = p;
+  bnet.CPD{eclass(W,1)} = tabular_CPD(bnet, W, 'CPT', CPT);
+  bnet.CPD{eclass(E,1)} = tabular_CPD(bnet, E, 'CPT', CPT);
+  CPT = zeros(ns(A), ns(C), 2);
+  CPT(:,:,1) = p;
+  CPT(:,:,2) = q;
+  bnet.CPD{eclass(S,1)} = tabular_CPD(bnet, S, 'CPT', CPT);
+  bnet.CPD{eclass(N,1)} = tabular_CPD(bnet, N, 'CPT', CPT);
+end
+
+% Define the CPDs for slice 2
+
+% Abstract
+
+% Since the top level never resets, the starting distribution is irrelevant:
+% A2 will be determined by sampling from transmat(A1,:).
+% But the code requires we specify it anyway; we make it all 0s, a dummy value.
+startprob = zeros(ns(U), ns(A));
+
+transmat = zeros(ns(U), ns(A), ns(A));
+transmat(R,1,:) = [q p];
+transmat(R,2,:) = [0 1];
+transmat(L,1,:) = [1 0];
+transmat(L,2,:) = [p q];
+
+% Qps are the parents we condition the parameters on, in this case just
+% the past action.
+bnet.CPD{eclass(A,2)} = hhmm2Q_CPD(bnet, A+ss, 'Fbelow', F, ...
+				  'startprob', startprob, 'transprob', transmat);
+
+
+
+% Concrete
+
+transmat = zeros(ns(C), ns(U), ns(A), ns(C));
+transmat(1,r,1,:) = [q p 0.0];
+transmat(2,r,1,:) = [0.0 q p];
+transmat(3,r,1,:) = [0.0 0.0 1.0];
+transmat(1,r,2,:) = [q p 0.0];
+transmat(2,r,2,:) = [0.0 1.0 0.0];
+%
+transmat(1,l,1,:) = [1.0 0.0 0.0];
+transmat(2,l,1,:) = [p q 0.0];
+transmat(3,l,1,:) = [0.0 p q];
+transmat(1,l,2,:) = [1.0 0.0 0.0];
+transmat(2,l,2,:) = [p q 0.0];
+
+% Add a new dimension for A(t-1), by copying old vals,
+% so the matrix is the same size as startprob
+
+
+transmat = reshape(transmat, [ns(C) ns(U) ns(A) 1 ns(C)]);
+transmat = repmat(transmat, [1 1 1 ns(A) 1]);
+
+% startprob(C(t-1), U(t-1), A(t-1), A(t), C(t))
+startprob = zeros(ns(C), ns(U), ns(A), ns(A), ns(C));
+startprob(1,L,1,1,:) = [1.0 0.0 0.0];
+startprob(3,R,1,2,:) = [1.0 0.0 0.0];
+startprob(3,R,1,1,:) = [0.0 0.0 1.0];
+% 
+startprob(1,L,2,1,:) = [0.0 0.0 010];
+startprob(2,L,2,1,:) = [1.0 0.0 0.0];
+startprob(2,R,2,2,:) = [0.0 1.0 0.0];
+
+% want transmat(U,A,C,At,Ct), ie. in topo order
+transmat = permute(transmat, [2 3 1 4 5]);
+startprob  = permute(startprob, [2 3 1 4 5]);
+bnet.CPD{eclass(C,2)} = hhmm2Q_CPD(bnet, C+ss, 'Fself', F, ...
+				  'startprob', startprob, 'transprob', transmat);
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_rnd_map_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_rnd_map_hhmm.m
new file mode 100644
index 00000000..76b06fc7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_rnd_map_hhmm.m
@@ -0,0 +1,73 @@
+function bnet = mk_rnd_map_hhmm(varargin)
+
+% We copy the deterministic structure of the real HHMM,
+% but randomize the probabilities of the adjustable CPDs.
+% The key trick is that 0s in the real HHMM remain 0
+% even when multiplied by a randon number.
+
+obs_model = 'unique';
+
+for i=1:2:length(varargin)
+  switch varargin{i},
+   case 'obs_model', obs_model = varargin{i+1};
+  end
+end
+
+
+unique_obs = strcmp(obs_model, 'unique');
+
+psuccess = 0.9;
+% must be less than 1, so that pfail > 0
+% otherwise we copy too many 0s
+bnet = mk_map_hhmm('p', psuccess, 'obs_model', obs_model);
+ns = bnet.node_sizes;
+ss = bnet.nnodes_per_slice;
+
+U = 1; A = 2; C = 3; F = 4;
+%unique_obs = (bnet.nnodes_per_slice == 5);
+if unique_obs
+  onodes = 5;
+else
+  north = 5; east = 6; south = 7; west = 8;
+  onodes = [north east south west];
+end
+
+eclass = bnet.equiv_class;
+S=struct(bnet.CPD{eclass(F,1)});
+CPT = mk_stochastic(rand(size(S.CPT)) .* S.CPT);
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', CPT);
+
+
+% Observation model
+if unique_obs
+  CPT = zeros(ns(A), ns(C), 5);
+  CPT(1,1,1)=1;  % Theo state 4
+  CPT(1,2,2)=1;  % Theo state 5
+  CPT(1,3,3)=1; % Theo state 6
+  CPT(2,1,4)=1; % Theo state 9
+  CPT(2,2,5)=1; % Theo state 10
+  %CPT(2,3,:) undefined
+  O = onodes(1);
+  bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', CPT);
+else
+  for i=[north east south west]
+    CPT = mk_stochastic(rand(ns(A), ns(C), 2));
+    bnet.CPD{eclass(i,1)} = tabular_CPD(bnet, i, 'CPT', CPT);
+  end
+end
+
+% Define the CPDs for slice 2
+
+startprob = zeros(ns(U), ns(A));
+S = struct(bnet.CPD{eclass(A,2)});
+transprob = mk_stochastic(rand(size(S.transprob)) .* S.transprob);
+bnet.CPD{eclass(A,2)} = hhmm2Q_CPD(bnet, A+ss, 'Fbelow', F, ...
+				  'startprob', startprob, 'transprob', transprob);
+
+S = struct(bnet.CPD{eclass(C,2)});
+transprob = mk_stochastic(rand(size(S.transprob)) .* S.transprob);
+startprob = mk_stochastic(rand(size(S.startprob)) .* S.startprob);
+bnet.CPD{eclass(C,2)} = hhmm2Q_CPD(bnet, C+ss, 'Fself', F, ...
+				  'startprob', startprob, 'transprob', transprob);
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/sample_from_map.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/sample_from_map.m
new file mode 100644
index 00000000..816b741e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/sample_from_map.m
@@ -0,0 +1,41 @@
+if 0
+% Generate some sample paths
+
+bnet = mk_map_hhmm('p', 1);
+% assign numbers to the nodes in topological order
+U = 1; A = 2; C = 3; F = 4; O = 5;
+
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+% control policy = sweep right then left
+T = 10;
+ss = 5;
+ev = cell(ss, T);
+ev(U,:) = num2cell([R*ones(1,5) L*ones(1,5)]);
+
+% fix initial conditions to be in left most state
+ev{A,1} = 1; 
+ev{C,1} = 1; 
+evidence = sample_dbn(bnet, 'length', T, 'evidence', ev)
+
+
+% Now do same but with noisy actuators
+
+bnet = mk_map_hhmm('p', 0.8);
+evidence = sample_dbn(bnet, 'length', T, 'evidence', ev)
+
+end
+
+% Now do same but with 4 observations per slice
+
+bnet = mk_map_hhmm('p', 0.8, 'obs_model', 'four');
+ss = bnet.nnodes_per_slice;
+
+ev = cell(ss, T);
+ev(U,:) = num2cell([R*ones(1,5) L*ones(1,5)]);
+ev{A,1} = 1; 
+ev{C,1} = 1; 
+evidence = sample_dbn(bnet, 'length', T, 'evidence', ev)
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Entries
new file mode 100644
index 00000000..c4379581
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Entries
@@ -0,0 +1,6 @@
+/letter2num.m/1.1.1.1/Fri Nov 22 23:10:20 2002//
+/mgram1.m/1.1.1.1/Fri Nov 22 23:59:00 2002//
+/mgram2.m/1.1.1.1/Tue Nov 26 22:04:24 2002//
+/mgram3.m/1.1.1.1/Tue Nov 26 22:14:10 2002//
+/num2letter.m/1.1.1.1/Fri Nov 22 23:07:40 2002//
+D/Old////
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Repository
new file mode 100644
index 00000000..5ede715e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Mgram
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Entries
new file mode 100644
index 00000000..07b688e2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Entries
@@ -0,0 +1,2 @@
+/mgram2.m/1.1.1.1/Sat Nov 23 00:44:34 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Repository
new file mode 100644
index 00000000..ba3ae6df
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Mgram/Old
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/mgram2.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/mgram2.m
new file mode 100644
index 00000000..719a3167
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/mgram2.m
@@ -0,0 +1,191 @@
+% like mgram1, except we use a durational HMM instead of an HHMM2
+
+past = 0;
+
+words = {'the', 't', 'h', 'e'};
+data = 'the';
+nwords = length(words);
+word_len = zeros(1, nwords);
+word_prob = normalise(ones(1,nwords));
+word_logprob = log(word_prob);
+for wi=1:nwords
+  word_len(wi)=length(words{wi});
+end
+D = max(word_len);
+
+
+alphasize = 26*2;
+data = letter2num(data);
+T = length(data);
+
+% node numbers
+W = 1; % top level state = word id
+L = 2; % bottom level state = letter position within word
+F = 3;
+O = 4;
+
+ss = 4;
+intra = zeros(ss,ss);
+intra(W,[F L O])=1;
+intra(L,[O F])=1;
+
+inter = zeros(ss,ss);
+inter(W,W)=1;
+inter(L,L)=1;
+inter(F,[W L O])=1;
+
+% node sizes
+ns = zeros(1,ss);
+ns(W) = nwords;
+ns(L) = D;
+ns(F) = 2;
+ns(O) = alphasize;
+ns2 = [ns ns];
+
+% Make the DBN
+bnet = mk_dbn(intra, inter, ns, 'observed', O);
+eclass = bnet.equiv_class;
+
+% uniform start distrib over words, uniform trans mat
+Wstart = normalise(ones(1,nwords));
+Wtrans = mk_stochastic(ones(nwords,nwords));
+
+% always start in state d = length(word) for each bottom level HMM
+Lstart = zeros(nwords, D);
+for i=1:nwords
+  l = length(words{i});
+  Lstart(i,l)=1;
+end
+
+% make downcounters
+RLtrans = mk_rightleft_transmat(D, 0); % 0 self loop prob
+Ltrans = repmat(RLtrans, [1 1 nwords]);
+
+% Finish when downcoutner = 1
+Fprob = zeros(nwords, D, 2);
+Fprob(:,1,2)=1;
+Fprob(:,2:end,1)=1;
+
+
+% Define CPDs for slice 
+bnet.CPD{eclass(W,1)} = tabular_CPD(bnet, W, 'CPT', Wstart);
+bnet.CPD{eclass(L,1)} = tabular_CPD(bnet, L, 'CPT', Lstart);
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', Fprob);
+
+
+% Define CPDs for slice 2
+bnet.CPD{eclass(W,2)} = hhmmQ_CPD(bnet, W+ss, 'Fbelow', F, 'startprob', Wstart,  'transprob', Wtrans);
+bnet.CPD{eclass(L,2)} = hhmmQ_CPD(bnet, L+ss, 'Fself', F, 'Qps', W+ss, 'startprob', Lstart, 'transprob', Ltrans);
+
+
+if 0
+% To test it is generating correctly, we create an artificial
+% observation process that capitalizes at the start of a new segment
+% Oprob(Ft-1,Qt,Dt,Yt)
+Oprob = zeros(2,nwords,D,alphasize);
+Oprob(1,1,3,letter2num('t'),1)=1;
+Oprob(1,1,2,letter2num('h'),1)=1;
+Oprob(1,1,1,letter2num('e'),1)=1;
+Oprob(2,1,3,letter2num('T'),1)=1;
+Oprob(2,1,2,letter2num('H'),1)=1;
+Oprob(2,1,1,letter2num('E'),1)=1;
+Oprob(1,2,1,letter2num('a'),1)=1;
+Oprob(2,2,1,letter2num('A'),1)=1;
+Oprob(1,3,1,letter2num('b'),1)=1;
+Oprob(2,3,1,letter2num('B'),1)=1;
+Oprob(1,4,1,letter2num('c'),1)=1;
+Oprob(2,4,1,letter2num('C'),1)=1;
+
+% Oprob1(Qt,Dt,Yt)
+Oprob1 = zeros(nwords,D,alphasize);
+Oprob1(1,3,letter2num('t'),1)=1;
+Oprob1(1,2,letter2num('h'),1)=1;
+Oprob1(1,1,letter2num('e'),1)=1;
+Oprob1(2,1,letter2num('a'),1)=1;
+Oprob1(3,1,letter2num('b'),1)=1;
+Oprob1(4,1,letter2num('c'),1)=1;
+
+bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', Oprob);
+bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', Oprob1);
+
+evidence = cell(ss,T);
+%evidence{W,1}=1;
+sample = cell2num(sample_dbn(bnet, 'length', T, 'evidence', evidence));
+str = num2letter(sample(4,:))
+end
+
+
+
+
+[log_obslik, obslik, match] = mk_mgram_obslik(lower(data), words, word_len, word_prob);
+% obslik(j,t,d)
+softCPDpot = cell(ss,T);
+ens = ns;
+ens(O)=1;
+ens2 = [ens ens];
+for t=2:T
+  dom = [F W+ss L+ss O+ss];
+  % tab(Ft-1, Q2, Dt)
+  tab = ones(2, nwords, D);
+  if past
+    tab(1,:,:)=1; % if haven't finished previous word, likelihood is 1
+    tab(2,:,:) = squeeze(obslik(:,t,:)); % otherwise likelihood of this segment
+  else
+    for d=1:max(1,min(D,T+1-t))
+      tab(2,:,d) = squeeze(obslik(:,t+d-1,d));
+    end
+  end
+  softCPDpot{O,t} = dpot(dom, ens2(dom), tab);
+end
+t = 1;
+dom = [W L O];
+% tab(Q2, Dt)
+tab = ones(nwords, D);
+if past
+  tab = squeeze(obslik(:,t,:));
+else
+  for d=1:min(D,T-t)
+    tab(:,d) = squeeze(obslik(:,t+d-1,d));
+  end
+end
+softCPDpot{O,t} = dpot(dom, ens(dom), tab);
+
+
+%bnet.observed = [];
+% uniformative observations
+%bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', mk_stochastic(ones(2,nwords,D,alphasize)));
+%bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', mk_stochastic(ones(nwords,D,alphasize)));
+
+engine = jtree_dbn_inf_engine(bnet);
+evidence = cell(ss,T);
+% we add dummy data to O to force its effective size to be 1.
+% The actual values have already been incorporated into softCPDpot 
+evidence(O,:) = num2cell(ones(1,T));
+[engine, ll_dbn] = enter_evidence(engine, evidence, 'softCPDpot', softCPDpot);
+
+
+%evidence(F,:) = num2cell(2*ones(1,T));
+%[engine, ll_dbn] = enter_evidence(engine, evidence);
+
+
+gamma = zeros(nwords, T);
+for t=1:T
+  m = marginal_nodes(engine, [W F], t);
+  gamma(:,t) = m.T(:,2);
+end
+
+gamma
+
+xidbn = zeros(nwords, nwords);
+for t=1:T-1
+  m = marginal_nodes(engine, [W F W+ss], t);
+  xidbn = xidbn + squeeze(m.T(:,2,:));
+end
+
+% thee
+% xidbn(1,4)  = 0.9412  the->e
+% (2,3)=0.0588 t->h
+% (3,4)=0.0588 h-e
+% (4,4)=0.0588 e-e
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/letter2num.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/letter2num.m
new file mode 100644
index 00000000..f4e3f1d9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/letter2num.m
@@ -0,0 +1,12 @@
+function n = letter2num(l)
+
+% map a-z to 1:26 and A-Z to 27:52
+punct_code = [32:47 58:64 91:96 123:126];
+digits_code = 48:57;
+upper_code = 65:90;
+lower_code = 97:122;
+
+c = double(l);
+n = c-96;
+ndx = find(n <= 0); % upper case
+n(ndx) = c(ndx)  - 64 + 26;
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram1.m
new file mode 100644
index 00000000..52ca472e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram1.m
@@ -0,0 +1,116 @@
+% a multigram is a degenerate 2HHMM where the bottom level HMMs emit deterministic strings
+% and the the top level abstract states are independent of each other
+% cf. HSMM/test_mgram2 
+
+words = {'the', 't', 'h', 'e'};
+data = 'the';
+nwords = length(words);
+word_len = zeros(1, nwords);
+word_prob = normalise(ones(1,nwords));
+word_logprob = log(word_prob);
+for wi=1:nwords
+  word_len(wi)=length(words{wi});
+end
+D = max(word_len);
+
+alphasize = 26;
+data = letter2num(data);
+T = length(data);
+
+% node numbers
+W = 1; % top level state = word id
+L = 2; % bottom level state = letter position within word
+F = 3;
+O = 4;
+
+ss = 4;
+intra = zeros(ss,ss);
+intra(W,[F L O])=1;
+intra(L,[O F])=1;
+
+inter = zeros(ss,ss);
+inter(W,W)=1;
+inter(L,L)=1;
+inter(F,[W L])=1;
+
+% node sizes
+ns = zeros(1,ss);
+ns(W) = nwords;
+ns(L) = D;
+ns(F) = 2;
+ns(O) = alphasize;
+
+
+% Make the DBN
+bnet = mk_dbn(intra, inter, ns, 'observed', O);
+eclass = bnet.equiv_class;
+
+
+
+% uniform start distrib over words, uniform trans mat
+Wstart = normalise(ones(1,nwords));
+Wtrans = mk_stochastic(ones(nwords,nwords));
+
+% always start in state 1 for each bottom level HMM
+delta1_start = zeros(1, D);
+delta1_start(1) = 1;
+Lstart = repmat(delta1_start, nwords, 1);
+LRtrans = mk_leftright_transmat(D, 0); % 0 self loop prob
+Ltrans = repmat(LRtrans, [1 1 nwords]);
+
+% Finish in the last letter of each word
+Fprob = zeros(nwords, D, 2);
+Fprob(:,:,1)=1;
+for i=1:nwords
+  Fprob(i,length(words{i}),2)=1;
+  Fprob(i,length(words{i}),1)=0;
+end
+
+% Each state uniquely emits a letter
+Oprob = zeros(nwords, D, alphasize);
+for i=1:nwords
+  for l=1:length(words{i})
+    a = double(words{i}(l))-96;
+    Oprob(i,l,a)=1;
+  end
+end
+
+
+% Define CPDs for slice 
+bnet.CPD{eclass(W,1)} = tabular_CPD(bnet, W, 'CPT', Wstart);
+bnet.CPD{eclass(L,1)} = tabular_CPD(bnet, L, 'CPT', Lstart);
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', Fprob);
+bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', Oprob);
+
+% Define CPDs for slice 2
+bnet.CPD{eclass(W,2)} = hhmmQ_CPD(bnet, W+ss, 'Fbelow', F, 'startprob', Wstart,  'transprob', Wtrans);
+bnet.CPD{eclass(L,2)} = hhmmQ_CPD(bnet, L+ss, 'Fself', F, 'Qps', W+ss, 'startprob', Lstart, 'transprob', Ltrans);
+
+evidence = cell(ss,T);
+evidence{W,1}=1;
+sample = cell2num(sample_dbn(bnet, 'length', T, 'evidence', evidence));
+str = lower(sample(4,:))
+
+engine = jtree_dbn_inf_engine(bnet);
+evidence = cell(ss,T);
+evidence(O,:) = num2cell(data);
+[engine, ll_dbn] = enter_evidence(engine, evidence);
+
+gamma = zeros(nwords, T);
+for t=1:T
+  m = marginal_nodes(engine, [W F], t);
+  gamma(:,t) = m.T(:,2);
+end
+gamma
+
+xidbn = zeros(nwords, nwords);
+for t=1:T-1
+  m = marginal_nodes(engine, [W F W+ss], t);
+  xidbn = xidbn + squeeze(m.T(:,2,:));
+end
+
+% thee
+% xidbn(1,4)  = 0.9412  the->e
+% (2,3)=0.0588 t->h
+% (3,4)=0.0588 h-e
+% (4,4)=0.0588 e-e
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram2.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram2.m
new file mode 100644
index 00000000..c61f855a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram2.m
@@ -0,0 +1,200 @@
+% Like a durational HMM, except we use soft evidence on the observed nodes.
+% Should give the same results as HSMM/test_mgram2.
+
+past = 1;
+% If past=1, P(Yt|Qt=j,Dt=d) = P(y_{t-d+1:t}|j)
+% If past=0, P(Yt|Qt=j,Dt=d) = P(y_{t:t+d-1}|j) - future evidence
+
+words = {'the', 't', 'h', 'e'};
+data = 'the';
+nwords = length(words);
+word_len = zeros(1, nwords);
+word_prob = normalise(ones(1,nwords));
+word_logprob = log(word_prob);
+for wi=1:nwords
+  word_len(wi)=length(words{wi});
+end
+D = max(word_len);
+
+
+alphasize = 26*2;
+data = letter2num(data);
+T = length(data);
+
+% node numbers
+W = 1; % top level state = word id
+L = 2; % bottom level state = letter position within word
+F = 3;
+O = 4;
+
+ss = 4;
+intra = zeros(ss,ss);
+intra(W,[F L O])=1;
+intra(L,[O F])=1;
+
+inter = zeros(ss,ss);
+inter(W,W)=1;
+inter(L,L)=1;
+inter(F,[W L O])=1;
+
+% node sizes
+ns = zeros(1,ss);
+ns(W) = nwords;
+ns(L) = D;
+ns(F) = 2;
+ns(O) = alphasize;
+ns2 = [ns ns];
+
+% Make the DBN
+bnet = mk_dbn(intra, inter, ns, 'observed', O);
+eclass = bnet.equiv_class;
+
+% uniform start distrib over words, uniform trans mat
+Wstart = normalise(ones(1,nwords));
+Wtrans = mk_stochastic(ones(nwords,nwords));
+%Wtrans = ones(nwords,nwords);
+
+% always start in state d = length(word) for each bottom level HMM
+Lstart = zeros(nwords, D);
+for i=1:nwords
+  l = length(words{i});
+  Lstart(i,l)=1;
+end
+
+% make downcounters
+RLtrans = mk_rightleft_transmat(D, 0); % 0 self loop prob
+Ltrans = repmat(RLtrans, [1 1 nwords]);
+
+% Finish when downcoutner = 1
+Fprob = zeros(nwords, D, 2);
+Fprob(:,1,2)=1;
+Fprob(:,2:end,1)=1;
+
+
+% Define CPDs for slice 1
+bnet.CPD{eclass(W,1)} = tabular_CPD(bnet, W, 'CPT', Wstart);
+bnet.CPD{eclass(L,1)} = tabular_CPD(bnet, L, 'CPT', Lstart);
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', Fprob);
+
+
+% Define CPDs for slice 2
+bnet.CPD{eclass(W,2)} = hhmmQ_CPD(bnet, W+ss, 'Fbelow', F, 'startprob', Wstart,  'transprob', Wtrans);
+bnet.CPD{eclass(L,2)} = hhmmQ_CPD(bnet, L+ss, 'Fself', F, 'Qps', W+ss, 'startprob', Lstart, 'transprob', Ltrans);
+
+
+if 0
+% To test it is generating correctly, we create an artificial
+% observation process that capitalizes at the start of a new segment
+% Oprob(Ft-1,Qt,Dt,Yt)
+Oprob = zeros(2,nwords,D,alphasize);
+Oprob(1,1,3,letter2num('t'),1)=1;
+Oprob(1,1,2,letter2num('h'),1)=1;
+Oprob(1,1,1,letter2num('e'),1)=1;
+Oprob(2,1,3,letter2num('T'),1)=1;
+Oprob(2,1,2,letter2num('H'),1)=1;
+Oprob(2,1,1,letter2num('E'),1)=1;
+Oprob(1,2,1,letter2num('a'),1)=1;
+Oprob(2,2,1,letter2num('A'),1)=1;
+Oprob(1,3,1,letter2num('b'),1)=1;
+Oprob(2,3,1,letter2num('B'),1)=1;
+Oprob(1,4,1,letter2num('c'),1)=1;
+Oprob(2,4,1,letter2num('C'),1)=1;
+
+% Oprob1(Qt,Dt,Yt)
+Oprob1 = zeros(nwords,D,alphasize);
+Oprob1(1,3,letter2num('t'),1)=1;
+Oprob1(1,2,letter2num('h'),1)=1;
+Oprob1(1,1,letter2num('e'),1)=1;
+Oprob1(2,1,letter2num('a'),1)=1;
+Oprob1(3,1,letter2num('b'),1)=1;
+Oprob1(4,1,letter2num('c'),1)=1;
+
+bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', Oprob);
+bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', Oprob1);
+
+evidence = cell(ss,T);
+%evidence{W,1}=1;
+sample = cell2num(sample_dbn(bnet, 'length', T, 'evidence', evidence));
+str = num2letter(sample(4,:))
+end
+
+
+if 1
+
+[log_obslik, obslik, match] = mk_mgram_obslik(lower(data), words, word_len, word_prob);
+% obslik(j,t,d)
+softCPDpot = cell(ss,T);
+ens = ns;
+ens(O)=1;
+ens2 = [ens ens];
+for t=2:T
+  dom = [F W+ss L+ss O+ss];
+  % tab(Ft-1, Q2, Dt)
+  tab = ones(2, nwords, D);
+  if past
+    tab(1,:,:)=1; % if haven't finished previous word, likelihood is 1
+    %tab(2,:,:) = squeeze(obslik(:,t,:)); % otherwise likelihood of this segment
+    for d=1:min(t,D)
+      tab(2,:,d) = squeeze(obslik(:,t,d));
+    end
+  else
+    for d=1:max(1,min(D,T+1-t))
+      tab(2,:,d) = squeeze(obslik(:,t+d-1,d));
+    end
+  end
+  softCPDpot{O,t} = dpot(dom, ens2(dom), tab);
+end
+t = 1;
+dom = [W L O];
+% tab(Q2, Dt)
+tab = ones(nwords, D);
+if past
+  %tab = squeeze(obslik(:,t,:));
+  tab(:,1) = squeeze(obslik(:,t,1));
+else
+  for d=1:min(D,T-t)
+    tab(:,d) = squeeze(obslik(:,t+d-1,d));
+  end
+end
+softCPDpot{O,t} = dpot(dom, ens(dom), tab);
+
+
+%bnet.observed = [];
+% uniformative observations
+%bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', mk_stochastic(ones(2,nwords,D,alphasize)));
+%bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', mk_stochastic(ones(nwords,D,alphasize)));
+
+engine = jtree_dbn_inf_engine(bnet);
+evidence = cell(ss,T);
+% we add dummy data to O to force its effective size to be 1.
+% The actual values have already been incorporated into softCPDpot 
+evidence(O,:) = num2cell(ones(1,T));
+[engine, ll_dbn] = enter_evidence(engine, evidence, 'softCPDpot', softCPDpot);
+
+
+%evidence(F,:) = num2cell(2*ones(1,T));
+%[engine, ll_dbn] = enter_evidence(engine, evidence);
+
+
+gamma = zeros(nwords, T);
+for t=1:T
+  m = marginal_nodes(engine, [W F], t);
+  gamma(:,t) = m.T(:,2);
+end
+
+gamma
+
+xidbn = zeros(nwords, nwords);
+for t=1:T-1
+  m = marginal_nodes(engine, [W F W+ss], t);
+  xidbn = xidbn + squeeze(m.T(:,2,:));
+end
+
+% thee
+% xidbn(1,4)  = 0.9412  the->e
+% (2,3)=0.0588 t->h
+% (3,4)=0.0588 h-e
+% (4,4)=0.0588 e-e
+
+
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram3.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram3.m
new file mode 100644
index 00000000..49228584
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram3.m
@@ -0,0 +1,235 @@
+% like mgram2, except we unroll the DBN so we can use smaller
+% state spaces for the early duration nodes:
+% the state spaces are D1 in {1}, D2 in {1,2}
+
+past = 1;
+
+words = {'the', 't', 'h', 'e'};
+data = 'the';
+nwords = length(words);
+word_len = zeros(1, nwords);
+word_prob = normalise(ones(1,nwords));
+word_logprob = log(word_prob);
+for wi=1:nwords
+  word_len(wi)=length(words{wi});
+end
+D = max(word_len);
+
+
+alphasize = 26*2;
+data = letter2num(data);
+T = length(data);
+
+% node numbers
+W = 1; % top level state = word id
+L = 2; % bottom level state = letter position within word
+F = 3;
+O = 4;
+
+ss = 4;
+intra = zeros(ss,ss);
+intra(W,[F L O])=1;
+intra(L,[O F])=1;
+
+inter = zeros(ss,ss);
+inter(W,W)=1;
+inter(L,L)=1;
+inter(F,[W L O])=1;
+
+T = 3;
+dag = unroll_dbn_topology(intra, inter, T);
+
+% node sizes
+ns = zeros(1,ss);
+ns(W) = nwords;
+ns(L) = D;
+ns(F) = 2;
+ns(O) = alphasize;
+ns = repmat(ns(:), [1 T]);
+for d=1:D
+  ns(d,L)=d; % max duration
+end
+ns = ns(:);
+
+% Equiv class in brackets for D=3
+% The Lt's are not tied until t>=D, since they have different sizes.
+% W1 and W2 are not tied since they have different parent sets.
+
+% W1 (1)  W2 (5) W3 (5) W4 (5)
+% L1 (2)  L2 (6) L3 (7) L4 (7)
+% F1 (3)  F2 (3) F3 (4) F3 (4)
+% O1 (4)  O2 (4) O2 (4) O4 (4)
+
+% Since we are not learning, we can dispense with tying
+
+% Make the bnet
+Wnodes = unroll_set(W, ss, T);
+Lnodes = unroll_set(L, ss, T);
+Fnodes = unroll_set(F, ss, T);
+Onodes = unroll_set(O, ss, T);
+
+bnet = mk_bnet(dag, ns);
+eclass = bnet.equiv_class;
+
+% uniform start distrib over words, uniform trans mat
+Wstart = normalise(ones(1,nwords));
+Wtrans = mk_stochastic(ones(nwords,nwords));
+bnet.CPD{eclass(Wnodes(1))} = tabular_CPD(bnet, Wnodes(1), 'CPT', Wstart);
+for t=2:T
+bnet.CPD{eclass(Wnodes(t))} = hhmmQ_CPD(bnet, Wnodes(t), 'Fbelow', Fnodes(t-1), ...
+					'startprob', Wstart,  'transprob', Wtrans);
+end
+
+% always start in state d = length(word) for each bottom level HMM
+% and then count down
+% make downcounters
+RLtrans = mk_rightleft_transmat(D, 0); % 0 self loop prob
+Ltrans = repmat(RLtrans, [1 1 nwords]);
+
+for t=1:T
+  Lstart = zeros(nwords, min(t,D));
+  for i=1:nwords
+    l = length(words{i});
+    Lstart(i,l)=1;
+    if d==1
+      bnet.CPD{eclass(Lnodes(1))} = tabular_CPD(bnet, Lnodes(1), 'CPT', Lstart);
+    else
+      bnet.CPD{eclass(Lnodes(t))} = hhmmQ_CPD(bnet, Lnodes(t), 'Fself', Fnodes(t-1), 'Qps', Wnodes(t), ...
+					      'startprob', Lstart, 'transprob', Ltrans);
+    end
+  end
+end
+
+
+% Finish when downcoutner = 1
+Fprob = zeros(nwords, D, 2);
+Fprob(:,1,2)=1;
+Fprob(:,2:end,1)=1;
+
+
+% Define CPDs for slice 
+bnet.CPD{eclass(W,1)} = tabular_CPD(bnet, W, 'CPT', Wstart);
+bnet.CPD{eclass(L,1)} = tabular_CPD(bnet, L, 'CPT', Lstart);
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', Fprob);
+
+
+% Define CPDs for slice 2
+bnet.CPD{eclass(W,2)} = hhmmQ_CPD(bnet, W+ss, 'Fbelow', F, 'startprob', Wstart,  'transprob', Wtrans);
+bnet.CPD{eclass(L,2)} = hhmmQ_CPD(bnet, L+ss, 'Fself', F, 'Qps', W+ss, 'startprob', Lstart, 'transprob', Ltrans);
+
+
+if 0
+% To test it is generating correctly, we create an artificial
+% observation process that capitalizes at the start of a new segment
+% Oprob(Ft-1,Qt,Dt,Yt)
+Oprob = zeros(2,nwords,D,alphasize);
+Oprob(1,1,3,letter2num('t'),1)=1;
+Oprob(1,1,2,letter2num('h'),1)=1;
+Oprob(1,1,1,letter2num('e'),1)=1;
+Oprob(2,1,3,letter2num('T'),1)=1;
+Oprob(2,1,2,letter2num('H'),1)=1;
+Oprob(2,1,1,letter2num('E'),1)=1;
+Oprob(1,2,1,letter2num('a'),1)=1;
+Oprob(2,2,1,letter2num('A'),1)=1;
+Oprob(1,3,1,letter2num('b'),1)=1;
+Oprob(2,3,1,letter2num('B'),1)=1;
+Oprob(1,4,1,letter2num('c'),1)=1;
+Oprob(2,4,1,letter2num('C'),1)=1;
+
+% Oprob1(Qt,Dt,Yt)
+Oprob1 = zeros(nwords,D,alphasize);
+Oprob1(1,3,letter2num('t'),1)=1;
+Oprob1(1,2,letter2num('h'),1)=1;
+Oprob1(1,1,letter2num('e'),1)=1;
+Oprob1(2,1,letter2num('a'),1)=1;
+Oprob1(3,1,letter2num('b'),1)=1;
+Oprob1(4,1,letter2num('c'),1)=1;
+
+bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', Oprob);
+bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', Oprob1);
+
+evidence = cell(ss,T);
+%evidence{W,1}=1;
+sample = cell2num(sample_dbn(bnet, 'length', T, 'evidence', evidence));
+str = num2letter(sample(4,:))
+end
+
+
+
+
+[log_obslik, obslik, match] = mk_mgram_obslik(lower(data), words, word_len, word_prob);
+% obslik(j,t,d)
+softCPDpot = cell(ss,T);
+ens = ns;
+ens(O)=1;
+ens2 = [ens ens];
+for t=2:T
+  dom = [F W+ss L+ss O+ss];
+  % tab(Ft-1, Q2, Dt)
+  tab = ones(2, nwords, D);
+  if past
+    tab(1,:,:)=1; % if haven't finished previous word, likelihood is 1
+    %tab(2,:,:) = squeeze(obslik(:,t,:)); % otherwise likelihood of this segment
+    for d=1:min(t,D)
+      tab(2,:,d) = squeeze(obslik(:,t,d));
+    end
+  else
+    for d=1:max(1,min(D,T+1-t))
+      tab(2,:,d) = squeeze(obslik(:,t+d-1,d));
+    end
+  end
+  softCPDpot{O,t} = dpot(dom, ens2(dom), tab);
+end
+t = 1;
+dom = [W L O];
+% tab(Q2, Dt)
+tab = ones(nwords, D);
+if past
+  %tab = squeeze(obslik(:,t,:));
+  tab(:,1) = squeeze(obslik(:,t,1));
+else
+  for d=1:min(D,T-t)
+    tab(:,d) = squeeze(obslik(:,t+d-1,d));
+  end
+end
+softCPDpot{O,t} = dpot(dom, ens(dom), tab);
+
+
+%bnet.observed = [];
+% uniformative observations
+%bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', mk_stochastic(ones(2,nwords,D,alphasize)));
+%bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', mk_stochastic(ones(nwords,D,alphasize)));
+
+engine = jtree_dbn_inf_engine(bnet);
+evidence = cell(ss,T);
+% we add dummy data to O to force its effective size to be 1.
+% The actual values have already been incorporated into softCPDpot 
+evidence(O,:) = num2cell(ones(1,T));
+[engine, ll_dbn] = enter_evidence(engine, evidence, 'softCPDpot', softCPDpot);
+
+
+%evidence(F,:) = num2cell(2*ones(1,T));
+%[engine, ll_dbn] = enter_evidence(engine, evidence);
+
+
+gamma = zeros(nwords, T);
+for t=1:T
+  m = marginal_nodes(engine, [W F], t);
+  gamma(:,t) = m.T(:,2);
+end
+
+gamma
+
+xidbn = zeros(nwords, nwords);
+for t=1:T-1
+  m = marginal_nodes(engine, [W F W+ss], t);
+  xidbn = xidbn + squeeze(m.T(:,2,:));
+end
+
+% thee
+% xidbn(1,4)  = 0.9412  the->e
+% (2,3)=0.0588 t->h
+% (3,4)=0.0588 h-e
+% (4,4)=0.0588 e-e
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/num2letter.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/num2letter.m
new file mode 100644
index 00000000..139b81fa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/num2letter.m
@@ -0,0 +1,10 @@
+function l = num2letter(n)
+
+% map 1:26 to a-z and 27:52 to A-Z
+punct_code = [32:47 58:64 91:96 123:126];
+digits_code = 48:57;
+upper_code = 65:90;
+lower_code = 97:122;
+
+letters = [char(lower_code) char(upper_code)];
+l = letters(n);
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Entries
new file mode 100644
index 00000000..93258c2a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Entries
@@ -0,0 +1,5 @@
+/fixed_args_mk_motif_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/learn_motif_hhmm.m/1.1.1.1/Tue Jul  2 22:56:14 2002//
+/mk_motif_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_motif_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Repository
new file mode 100644
index 00000000..5062cfd4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Motif
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/fixed_args_mk_motif_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/fixed_args_mk_motif_hhmm.m
new file mode 100644
index 00000000..ce4e288b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/fixed_args_mk_motif_hhmm.m
@@ -0,0 +1,99 @@
+function bnet = fixed_args_mk_motif_hhmm(motif_length, motif_pattern, background_char)
+%
+% BNET = MK_MOTIF_HHMM(MOTIF_LENGTH)
+% Make the following HHMM
+%
+%    S2 <----------------------> S1
+%    |                           |
+%    |                           |
+%   M1 -> M2 -> M3 -> end        B1 -> end
+%
+% where Mi represents the i'th letter in the motif
+% and B is the background state.
+% Si chooses between running the motif or the background.
+% The Si and B states have self loops (not shown).
+%
+% The transition params are defined to respect the above topology.
+% The background is uniform; each motif state has a random obs. distribution.
+%
+% BNET = MK_MOTIF_HHMM(MOTIF_LENGTH, MOTIF_PATTERN)
+% In this case, we make the motif submodel deterministically
+% emit the motif pattern. 
+%
+% BNET = MK_MOTIF_HHMM(MOTIF_LENGTH, MOTIF_PATTERN, BACKGROUND_CHAR)
+% In this case, we make the background submodel
+% deterministically emit the specified character (to make the pattern
+% easier to see).
+
+if nargin < 2, motif_pattern = []; end
+if nargin < 3, background_char = []; end
+
+chars = ['a', 'c', 'g', 't'];
+Osize = length(chars);
+
+motif_length = length(motif_pattern);
+Qsize = [2 motif_length];
+Qnodes = 1:2;
+D = 2;
+transprob = cell(1,D);
+termprob = cell(1,D);
+startprob = cell(1,D);
+
+% startprob{d}(k,j), startprob{1}(1,j)
+% transprob{d}(i,k,j), transprob{1}(i,j)
+% termprob{d}(k,j)
+
+
+% LEVEL 1
+
+startprob{1} = zeros(1, 2);
+startprob{1} = [1 0]; % always start in the background model
+
+% When in the background state, we stay there with high prob
+% When in the motif state, we immediately return to the background state.
+transprob{1} = [0.8 0.2;
+		1.0 0.0];
+
+
+% LEVEL 2
+startprob{2} = 'leftstart'; % both submodels start in substate 1
+transprob{2} = zeros(motif_length, 2, motif_length);
+termprob{2} = zeros(2, motif_length);
+
+% In the background model, we only use state 1.
+transprob{2}(1,1,1) = 1; % self loop
+termprob{2}(1,1) = 0.2; % prob transition to end state
+
+% Motif model
+transprob{2}(:,2,:) = mk_leftright_transmat(motif_length, 0); % no self loops
+termprob{2}(2,end) = 1.0; % last state immediately terminates
+
+
+% OBS LEVEl
+
+obsprob = zeros([Qsize Osize]);
+if isempty(background_char)
+  % uniform background model
+  obsprob(1,1,:) = normalise(ones(Osize,1));
+else
+  % deterministic background model (easy to see!)
+  m = find(chars==background_char);
+  obsprob(1,1,m) = 1.0;
+end
+
+if gen_motif
+  % initialise with true motif (cheating)
+  for i=1:motif_length
+    m = find(chars == motif_pattern(i));
+    obsprob(2,i,m) = 1.0;
+  end
+else
+  obsprob(2,:,:) = mk_stochastic(ones(motif_length, Osize));
+end
+
+Oargs = {'CPT', obsprob};
+
+[bnet, Qnodes, Fnodes, Onode] = mk_hhmm('Qsizes', Qsize, 'Osize', Osize, 'discrete_obs', 1, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(1:2), ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/learn_motif_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/learn_motif_hhmm.m
new file mode 100644
index 00000000..54553460
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/learn_motif_hhmm.m
@@ -0,0 +1,75 @@
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+chars = ['a', 'c', 'g', 't'];
+motif = 'accca';
+motif_length = length(motif);
+motif_code = zeros(1, motif_length);
+for i=1:motif_length
+  motif_code(i) = find(chars == motif(i));
+end
+
+[bnet_init, Qnodes, Fnodes, Onode] = mk_motif_hhmm('motif_length', length(motif));
+%[bnet_init, Qnodes, Fnodes, Onode] = mk_motif_hhmm('motif_pattern', motif);
+ss = bnet_init.nnodes_per_slice;
+
+
+
+% We generate a training set by creating uniform sequences,
+% and inserting a single motif at a random location.
+ntrain = 100;
+T = 20;
+cases = cell(1, ntrain);
+
+if 1
+  % uniform background 
+  background_dist = normalise(ones(1, length(chars)));
+end
+if 0
+  % use a constant background
+  background_dist = zeros(1, length(chars));
+  m = find(chars=='t');
+  background_dist(m) = 1.0;
+end
+if 0
+  % use a background skewed away from the motif
+  p = 0.01; q = (1-(2*p))/2;
+  background_dist = [p p q q];
+end
+
+unif_pos = normalise(ones(1, T-length(motif)));
+cases = cell(1, ntrain);
+data = zeros(1,T);
+for i=1:ntrain
+  data = sample_discrete(background_dist, 1, T);
+  L = sample_discrete(unif_pos, 1, 1);
+  data(L:L+length(motif)-1) = motif_code;
+  cases{i} = cell(ss, T);
+  cases{i}(Onode,:) = num2cell(data);
+end
+disp('sample training cases')
+for i=1:5
+  chars(cell2num(cases{i}(Onode,:)))
+end
+
+engine_init = hmm_inf_engine(bnet_init);
+
+[bnet_learned, LL, engine_learned] = ...
+    learn_params_dbn_em(engine_init, cases, 'max_iter', 100, 'thresh', 1e-2);
+%			'anneal', 1, 'anneal_rate', 0.7);
+
+% extract the learned motif profile
+eclass = bnet_learned.equiv_class;
+CPDO=struct(bnet_learned.CPD{eclass(Onode,1)});
+fprintf('columns = chars, rows = states\n');
+profile_learned = squeeze(CPDO.CPT(2,:,:))
+[m,ndx] = max(profile_learned, [], 2);
+map_motif_learned = chars(ndx)
+back_learned = squeeze(CPDO.CPT(1,1,:))'
+%map_back_learned = chars(argmax(back_learned))
+
+CPDO_init = struct(bnet_init.CPD{eclass(Onode,1)});
+profile_init = squeeze(CPDO_init.CPT(2,:,:));
+back_init = squeeze(CPDO_init.CPT(1,1,:))';
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/mk_motif_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/mk_motif_hhmm.m
new file mode 100644
index 00000000..32980397
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/mk_motif_hhmm.m
@@ -0,0 +1,137 @@
+function [bnet, Qnodes, Fnodes, Onode] = mk_motif_hhmm(varargin)
+% [bnet, Qnodes, Fnodes, Onode] = mk_motif_hhmm(...)
+%
+% Make the following HHMM
+%
+%    S2 <----------------------> S1
+%    |                           |
+%    |                           |
+%   M1 -> M2 -> M3 -> end        B1 -> end
+%
+% where Mi represents the i'th letter in the motif
+% and B is the background state.
+% Si chooses between running the motif or the background.
+% The Si and B states have self loops (not shown).
+%
+% The transition params are defined to respect the above topology.
+% The background is uniform; each motif state has a random obs. distribution.
+%
+% Optional params:
+% motif_length  - required, unless we specify motif_pattern
+% motif_pattern - if specified, we make the motif submodel deterministically
+%                  emit this pattern
+% background    - if specified, we make the background submodel
+%                  deterministically emit this (makes the motif easier to see!)
+
+
+args = varargin;
+nargs = length(args);
+
+% extract pattern, if any
+motif_pattern = [];
+for i=1:2:nargs
+  switch args{i},
+   case 'motif_pattern', motif_pattern = args{i+1}; 
+  end
+end
+
+% set defaults
+motif_length = length(motif_pattern);
+background_char = [];
+
+% get params
+for i=1:2:nargs
+  switch args{i},
+   case 'motif_length', motif_length = args{i+1}; 
+   case 'background', background_char = args{i+1};
+  end
+end
+
+
+chars = ['a', 'c', 'g', 't'];
+Osize = length(chars);
+
+Qsize = [2 motif_length];
+Qnodes = 1:2;
+D = 2;
+transprob = cell(1,D);
+termprob = cell(1,D);
+startprob = cell(1,D);
+
+% startprob{d}(k,j), startprob{1}(1,j)
+% transprob{d}(i,k,j), transprob{1}(i,j)
+% termprob{d}(k,j)
+
+
+% LEVEL 1
+
+startprob{1} = zeros(1, 2);
+startprob{1} = [1 0]; % always start in the background model
+
+% When in the background state, we stay there with high prob
+% When in the motif state, we immediately return to the background state.
+transprob{1} = [0.8 0.2;
+		1.0 0.0];
+
+
+% LEVEL 2
+startprob{2} = 'leftstart'; % both submodels start in substate 1
+transprob{2} = zeros(motif_length, 2, motif_length);
+termprob{2} = zeros(2, motif_length);
+
+% In the background model, we only use state 1.
+transprob{2}(1,1,1) = 1; % self loop
+termprob{2}(1,1) = 0.2; % prob transition to end state
+
+% Motif model
+transprob{2}(:,2,:) = mk_leftright_transmat(motif_length, 0); % no self loops
+termprob{2}(2,end) = 1.0; % last state immediately terminates
+
+
+% OBS LEVEl
+
+obsprob = zeros([Qsize Osize]);
+if isempty(background_char)
+  % uniform background model
+  %obsprob(1,1,:) = normalise(ones(Osize,1));
+  obsprob(1,1,:) = normalise(rand(Osize,1));
+else
+  % deterministic background model (easy to see!)
+  m = find(chars==background_char);
+  obsprob(1,1,m) = 1.0;
+end
+
+if ~isempty(motif_pattern)
+  % initialise with true motif (cheating)
+  for i=1:motif_length
+    m = find(chars == motif_pattern(i));
+    obsprob(2,i,m) = 1.0;
+  end
+else
+  obsprob(2,:,:) = mk_stochastic(rand(motif_length, Osize));
+end
+
+if 0
+  Oargs = {'CPT', obsprob};
+else
+  % We use a minent prior for the emission distribution for the states in the motif model
+  % (but not the background model). This encourages nearly deterministic distributions.
+  % We create an index matrix  (where M = motif length)
+  %  [2 1
+  %   2 2
+  %   ...
+  %   2 M]
+  % and then convert this to a list of integers, which
+  % specifies when to use the minent prior (Q1=2 specifies motif model).
+  M = motif_length;
+  ndx = [2*ones(M,1) (1:M)'];
+  pcases = subv2ind([2 motif_length], ndx);
+  Oargs = {'CPT', obsprob, 'prior_type', 'entropic', 'entropic_pcases', pcases};
+end
+
+
+
+[bnet, Qnodes, Fnodes, Onode] = mk_hhmm('Qsizes', Qsize, 'Osize', Osize, 'discrete_obs', 1, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(1:2), ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/sample_motif_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/sample_motif_hhmm.m
new file mode 100644
index 00000000..b5822e10
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/sample_motif_hhmm.m
@@ -0,0 +1,10 @@
+%bnet = mk_motif_hhmm('motif_pattern', 'acca', 'background', 't');
+bnet = mk_motif_hhmm('motif_pattern', 'accaggggga', 'background', []);
+
+chars = ['a', 'c', 'g', 't'];
+Tmax = 100;
+
+for seqi=1:5
+  evidence = cell2num(sample_dbn(bnet, 'length', Tmax));
+  chars(evidence(end,:))
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Entries
new file mode 100644
index 00000000..6caae4a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Entries
@@ -0,0 +1,8 @@
+/mk_abcd_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_arrow_alpha_hhmm3.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_hhmm2.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_hhmm3.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_hhmm3_args.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/motif_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/remove_hhmm_end_state.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Repository
new file mode 100644
index 00000000..cc9acc63
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Old
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_abcd_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_abcd_hhmm.m
new file mode 100644
index 00000000..330bc304
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_abcd_hhmm.m
@@ -0,0 +1,109 @@
+% Make the HHMM in Figure 1 of the NIPS'01 paper
+
+Qsize = [2 3 2];
+D = 3;
+
+% transprob{d}(i,k,j), transprob{1}(i,j)
+% termprob{d}(k,j), termprob{1}(1,j)
+% startprob{d}(k,j), startprob{1}(1,j)
+% obsprob(k, o) for discrete outputs
+    
+% LEVEL 1
+%       1 2 e
+A{1} = [0 0 1;
+	0 0 1];
+[transprob{1}, termprob{1}] = remove_hhmm_end_state(A{1});
+startprob{1} = [0.5 0.5];
+Q1args = {'startprob', startprob{1}, 'transprob', transprob{1}};
+
+% LEVEL 2
+A{2} = zeros(Qsize(2), Qsize(1), Qsize(2)+1);
+
+%              1 2 3 e
+A{2}(:,1,:) = [0 1 0 0
+	       0 0 1 0
+	       0 0 0 1];
+
+%              1 2 3 e
+A{2}(:,2,:) = [0 1 0 0
+	       0 0 1 0
+	       0 0 0 1];
+
+[transprob{2}, termprob{2}] = remove_hhmm_end_state(A{2});	       
+
+% always enter level 2 in state 1
+startprob{2} = [1 0 0
+		1 0 0];
+
+Q2args = {'startprob', startprob{2}, 'transprob', transprob{2}};
+F2args = {'CPT', termprob{2}};
+
+
+% LEVEL 3
+
+A{3} = zeros([Qsize(3) Qsize(1:2) Qsize(3)+1]);
+endstate = Qsize(3)+1;
+%    Qt-1(3) Qt(1) Qt(2) Qt(3)
+%                               1   2   e
+A{3}(1,      1,    1,    endstate) = 1.0;
+A{3}(:,      1,    2,    :) = [0.0 1.0 0.0
+            	               0.5 0.0 0.5];
+A{3}(1,      1,    3,    endstate) = 1.0;
+
+A{3}(1,      2,    1,    endstate) = 1.0;
+A{3}(:,      2,    2,    :) = [0.0 1.0 0.0
+            	               0.5 0.0 0.5];
+A{3}(1,      2,    3,    endstate) = 1.0;
+
+A{3} = reshape(A{3}, [Qsize(3) prod(Qsize(1:2)) Qsize(3)+1]);
+[transprob{3}, termprob{3}] = remove_hhmm_end_state(A{3});	       
+
+% define the vertical entry points to level 3
+startprob{3} = zeros(Qsize);
+%            Q1 Q2 Q3
+startprob{3}(1, 1, 1) = 1.0;
+startprob{3}(1, 2, 1) = 1.0;
+startprob{3}(1, 3, 1) = 1.0;
+
+startprob{3}(2, 1, 1) = 1.0;
+startprob{3}(2, 2, 1) = 1.0;
+startprob{3}(2, 3, 1) = 1.0;
+
+startprob{3} = reshape(startprob{3}, prod(Qsize(1:2)), Qsize(3));
+
+chars = ['a', 'b', 'c', 'd', 'x', 'y'];
+Osize = length(chars);
+
+obsprob = zeros([Qsize Osize]);
+%       1 2 3 O
+obsprob(1,1,1,find(chars == 'a')) =  1.0;
+
+obsprob(1,2,1,find(chars == 'x')) =  1.0;
+obsprob(1,2,2,find(chars == 'y')) =  1.0;
+
+obsprob(1,3,1,find(chars == 'b')) =  1.0;
+
+obsprob(2,1,1,find(chars == 'c')) =  1.0;
+
+obsprob(2,2,1,find(chars == 'x')) =  1.0;
+obsprob(2,2,2,find(chars == 'y')) =  1.0;
+
+obsprob(2,3,1,find(chars == 'd')) =  1.0;
+
+obsprob = reshape(obsprob, prod(Qsize), Osize);
+
+[intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo(D);
+
+hhmm.Qnodes = Qnodes;
+hhmm.Fnodes = Fnodes;
+hhmm.Onode = Onode;
+hhmm.D = D;
+hhmm.Qsize = Qsize;
+hhmm.Osize = Osize;
+hhmm.startprob = startprob;
+hhmm.transprob = transprob;
+hhmm.termprob = termprob;
+hhmm.obsprob = obsprob;
+hhmm.A = A;
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_arrow_alpha_hhmm3.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_arrow_alpha_hhmm3.m
new file mode 100644
index 00000000..ba1aa8cb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_arrow_alpha_hhmm3.m
@@ -0,0 +1,86 @@
+% Make the following HHMM
+%
+%     LH                  RH
+%    /                      \
+%   /                        \
+%  LR -> UD -> RL -> DU       RL -> UD -> LR -> DU
+%   \
+%    \
+%     Q1 -> Q2
+%
+% where level 1 is fully interconnected (not shown)
+% level 2 is left-right
+% and each model at level 3 is a 2 state LR shared HMM 
+
+Qsizes = [2 4 2];
+D = 3;
+
+% LEVEL 1
+
+startprob1 = 'ergodic';
+transprob1 = 'ergodic';
+
+
+% LEVEL 2
+
+startprob = zeros(2, 4);
+%        Q1  Q2
+startprob(1, 1) = 1;
+startprob(2, 3) = 1;
+
+transprob = zeros(2, 4, 4);
+transprob(1,:,:) = [0 1 0 0
+		    0 0 1 0
+		    0 0 0 1
+		    0 0 0 1];
+transprob(2,:,:) = [0 0 0 1
+		    1 0 0 0
+		    0 1 0 0
+		    0 0 0 1];
+
+Q2args = {'startprob', startprob, 'transprob', transprob};
+
+% always terminate in state 4 (default)
+% F2args
+
+% LEVEL 3
+
+% Defaults are fine: always start in state 1, left-right model, finish in state 2
+
+
+% OBS LEVEl
+
+chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+Osize = length(chars);
+
+obsprob = zeros([4 2 Osize]);
+%       Q2 Q3 O
+obsprob(1, 1, find(chars == 'L')) =  1.0;
+obsprob(1, 2, find(chars == 'l')) =  1.0;
+
+obsprob(2, 1, find(chars == 'U')) =  1.0;
+obsprob(2, 2, find(chars == 'u')) =  1.0;
+
+obsprob(3, 1, find(chars == 'R')) =  1.0;
+obsprob(3, 2, find(chars == 'r')) =  1.0;
+
+obsprob(4, 1, find(chars == 'D')) =  1.0;
+obsprob(4, 2, find(chars == 'd')) =  1.0;
+
+Oargs = {'CPT', obsprob};
+
+
+bnet = mk_hhmm3('Qsizes', Qsizes, 'Osize', Osize', 'discrete_obs', 1, 'Oargs', Oargs, 'Q1args', Q1args, 'Q2args', Q2args);
+
+T = 20;
+usecell = 0;
+evidence = sample_dbn(bnet, T, usecell);      
+%chars(evidence(end,:))
+
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; obs = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+
+pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, obs, chars);
+
+eclass = bnet.equiv_class;
+S=struct(bnet.CPD{eclass(Q2,2)})
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm2.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm2.m
new file mode 100644
index 00000000..032015ba
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm2.m
@@ -0,0 +1,111 @@
+function bnet = mk_hhmm2(varargin)
+% MK_HHMM2 Make a 2 level Hierarchical HMM
+% bnet = mk_hhmm2(...)
+%
+% 2-layer hierarchical HMM  (node numbers in parens)
+%
+%   Q1(1) ---------> Q1(5)
+% /  | \            / |
+% |  |  v          /  |
+% |  |  F2(3) --- /   |
+% |  |  ^         \   |
+% |  | /           \  |
+% |  v              \ v
+% |  Q2(2)--------> Q2 (6)
+% |  |    
+% \  | 
+%  v v    
+%   O(4)
+%
+%
+% Optional arguments [default]
+%
+% discrete_obs - 1 means O is tabular_CPD, 0 means O is gaussian_CPD [0]
+% obsCPT       - CPT(o,q1,q2) params for O ['rnd']
+% mu           - mu(:,q1,q2) params for O [ [] ]
+% Sigma        - Sigma(:,q1,q2) params for O [ [] ]
+%
+% F2toQ1       - 1 if Q2 is an hhmm_CPD, 0 if F2 -> Q2 arc is absent, so level 2 never resets [1]
+% Q1args        - arguments to be passed to the constructors for Q1(t=2) [ {} ]
+% Q2args        - arguments to be passed to the constructors for Q2(t=2) [ {} ]
+%
+% F2 only turns on (wp 0.5) when Q2 enters its final state.
+% Q1 (slice 1) is clamped to be uniform.
+% Q2 (slice 1) is clamped to always start in state 1.
+
+[os nmodels nstates] = size(mu);
+
+ss = 4;
+Q1 = 1; Q2 = 2; F2 = 3; obs = 4;
+Qnodes = [Q1 Q2];
+names = {'Q1', 'Q2', 'F2', 'obs'};
+intra = zeros(ss);
+intra(Q1, [Q2 F2 obs]) = 1;
+intra(Q2, [F2 obs]) = 1;
+
+inter = zeros(ss);
+inter(Q1,Q1) = 1;
+inter(F2,Q1) = 1;
+if F2toQ2
+  inter(F2,Q2)=1;
+end
+inter(Q2,Q2) = 1;
+
+ns = zeros(1,ss);
+
+ns(Q1) = nmodels;
+ns(Q2) = nstates;
+ns(F2) = 2;
+ns(obs) = os;
+
+dnodes = [Q1 Q2 F2];
+if discrete_obs
+  dnodes = [dnodes obs];
+end
+onodes = [obs];
+
+bnet = mk_dbn(intra, inter, ns, 'observed', onodes, 'discrete', dnodes, 'names', names);
+eclass = bnet.equiv_class;
+
+% SLICE 1
+
+% We clamp untied nodes in the first slice, since their params can't be estimated
+% from just one sequence
+
+% uniform prior on initial model
+CPT = normalise(ones(1,nmodels));
+bnet.CPD{eclass(Q1,1)} = tabular_CPD(bnet, Q1, 'CPT', CPT, 'adjustable', 0);
+
+% each model always starts in state 1
+CPT = zeros(ns(Q1), ns(Q2));
+CPT(:, 1) = 1.0;
+bnet.CPD{eclass(Q2,1)} = tabular_CPD(bnet, Q2, 'CPT', CPT, 'adjustable', 0);
+
+% Termination probability
+CPT = zeros(ns(Q1), ns(Q2), 2);
+if 1
+  % Each model can only terminate in its final state.
+  % 0 params will remain 0 during EM, thus enforcing this constraint.
+  CPT(:, :, 1) = 1.0; % all states turn F off ...
+  p = 0.5;
+  CPT(:, ns(Q2), 2) = p; % except the last one
+  CPT(:, ns(Q2), 1) = 1-p;
+end
+bnet.CPD{eclass(F2,1)}  = tabular_CPD(bnet, F2, 'CPT', CPT);
+
+if discrete_obs
+  bnet.CPD{eclass(obs,1)} = tabular_CPD(bnet, obs, obs_args{:});
+else
+  bnet.CPD{eclass(obs,1)} = gaussian_CPD(bnet, obs, obs_args{:});
+end
+
+% SLICE 2
+
+
+bnet.CPD{eclass(Q1,2)} = hhmm_CPD(bnet, Q1+ss, Qnodes, 1, D, 'args', Q1args);
+
+if F2toQ2
+  bnet.CPD{eclass(Q2,2)} = hhmmQD_CPD(bnet, Q2+ss, Qnodes, 2, D, Q2args{:});
+else
+  bnet.CPD{eclass(Q2,2)} = tabular_CPD(bnet, Q2+ss, Q2args{:});
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3.m
new file mode 100644
index 00000000..5b2cd6aa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3.m
@@ -0,0 +1,181 @@
+function bnet = mk_hhmm3(varargin)
+% MK_HHMM3 Make a 3 level Hierarchical HMM
+% bnet = mk_hhmm3(...)
+%
+% 3-layer hierarchical HMM where level 1 only connects to level 2, not 3 or obs.
+% This enforces sub-models (which differ only in their Q1 index) to be shared.
+% Also, we enforce the fact that each model always starts in its initial state
+% and only finishes in its final state. However, the prob. of finishing (as opposed to
+% self-transitioning to the final state) can be learned.
+% The fact that we always finish from the same state means we do not need to condition
+% F(i) on Q(i-1), since finishing prob is indep of calling context.
+%
+% The DBN is the same as Fig 10 in my tech report.
+%
+%   Q1 ---------->  Q1
+%   |              / |
+%   |             /  |
+%   |  F2 -------    |
+%   |  ^         \   |
+%   | /|          \  |
+%   v  |           v v
+%   Q2-| -------->   Q2
+%  /|  |             ^
+% / |  |            /|
+% | |  F3 ---------/ |
+% | |  ^           \ |
+% | v /              v
+% | Q3 ----------->  Q3
+% |  |    
+% \  | 
+%  v v    
+%   O
+%
+%
+% Optional arguments in name/value format [default]
+%
+% Qsizes      - sizes at each level [ none ]
+% Osize       - size of O node [ none ]
+% discrete_obs - 1 means O is tabular_CPD, 0 means O is gaussian_CPD [0]
+% Oargs       - cell array of args to pass to the O CPD  [ {} ]
+% transprob1  - transprob1(i,j) = P(Q1(t)=j|Q1(t-1)=i)  ['ergodic']
+% startprob1  - startprob1(j) = P(Q1(t)=j)  ['leftstart']
+% transprob2  - transprob2(i,k,j) = P(Q2(t)=j|Q2(t-1)=i,Q1(t)=k)  ['leftright']
+% startprob2  - startprob2(k,j) = P(Q2(t)=j|Q1(t)=k)  ['leftstart']
+% termprob2   - termprob2(j,f) = P(F2(t)=f|Q2(t)=j)  ['rightstop']
+% transprob3  - transprob3(i,k,j) = P(Q3(t)=j|Q3(t-1)=i,Q2(t)=k)  ['leftright']
+% startprob3  - startprob3(k,j) = P(Q3(t)=j|Q2(t)=k)  ['leftstart']
+% termprob3   - termprob3(j,f) = P(F3(t)=f|Q3(t)=j)  ['rightstop']
+%
+% leftstart means the model always starts in state 1.
+% rightstop means the model always finished in its last state (Qsize(d)).
+%
+% Q1:Q3 in slice 1 are of type tabular_CPD
+% Q1:Q3 in slice 2 are of type hhmmQ_CPD.
+% F2 is of type hhmmF_CPD, F3 is of type tabular_CPD.
+
+ss = 6; D = 3;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; obs = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+names = {'Q1', 'Q2', 'Q3', 'F3', 'F2', 'obs'};
+
+intra = zeros(ss);
+intra(Q1, Q2) = 1;
+intra(Q2, [F2 Q3 obs]) = 1;
+intra(Q3, [F3 obs]) = 1;
+intra(F3, F2) = 1;
+
+inter = zeros(ss);
+inter(Q1,Q1) = 1;
+inter(Q2,Q2) = 1;
+inter(Q3,Q3) = 1;
+inter(F2,[Q1 Q2]) = 1;
+inter(F3,[Q2 Q3]) = 1;
+
+
+% get sizes of nodes
+args = varargin;
+nargs = length(args);
+Qsizes = [];
+Osize = 0;
+for i=1:2:nargs
+  switch args{i},
+   case 'Qsizes', Qsizes = args{i+1}; 
+   case 'Osize', Osize = args{i+1}; 
+  end
+end
+if isempty(Qsizes), error('must specify Qsizes'); end
+if Osize==0, error('must specify Osize'); end
+  
+% set default params
+discrete_obs = 0;
+Oargs = {};
+startprob1 = 'ergodic';
+startprob2 = 'leftstart';
+startprob3 = 'leftstart';
+transprob1 = 'ergodic';
+transprob2 = 'leftright';
+transprob3 = 'leftright';
+termprob2 = 'rightstop';
+termprob3 = 'rightstop';
+
+
+for i=1:2:nargs
+  switch args{i},
+   case 'discrete_obs', discrete_obs = args{i+1}; 
+   case 'Oargs',        Oargs = args{i+1};
+   case 'Q1args',       Q1args = args{i+1};
+   case 'Q2args',       Q2args = args{i+1};
+   case 'Q3args',       Q3args = args{i+1};
+   case 'F2args',       F2args = args{i+1};
+   case 'F3args',       F3args = args{i+1};
+  end
+end
+
+
+ns = zeros(1,ss);
+ns(Qnodes) = Qsizes;
+ns(obs) = Osize;
+ns(Fnodes) = 2;
+
+dnodes = [Qnodes Fnodes];
+if discrete_obs
+  dnodes = [dnodes obs];
+end
+onodes = [obs];
+
+bnet = mk_dbn(intra, inter, ns, 'observed', onodes, 'discrete', dnodes, 'names', names);
+eclass = bnet.equiv_class;
+
+if strcmp(startprob1, 'ergodic')
+  startprob1 = normalise(ones(1,ns(Q1)));
+end
+if strcmp(startprob2, 'leftstart')
+  startprob2 = zeros(ns(Q1), ns(Q2));
+  starpbrob2(:, 1) = 1.0;
+end
+if strcmp(startprob3, 'leftstart')
+  startprob3 = zeros(ns(Q2), ns(Q3));
+  starpbrob3(:, 1) = 1.0;
+end
+
+if strcmp(termprob2, 'rightstop')
+  p = 0.9;
+  termprob2 = zeros(Qsize(2),2);
+  termprob2(:, 2) = p; 
+  termprob2(:, 1) = 1-p; 
+  termprob2(1:(Qsize(2)-1), 1) = 1; 
+end
+if strcmp(termprob3, 'rightstop')
+  p = 0.9;
+  termprob3 = zeros(Qsize(3),2);
+  termprob3(:, 2) = p; 
+  termprob3(:, 1) = 1-p; 
+  termprob3(1:(Qsize(3)-1), 1) = 1; 
+end
+
+
+% SLICE 1
+
+% We clamp untied nodes in the first slice, since their params can't be estimated
+% from just one sequence
+
+bnet.CPD{eclass(Q1,1)} = tabular_CPD(bnet, Q1, 'CPT', startprob1, 'adjustable', 0);
+bnet.CPD{eclass(Q2,1)} = tabular_CPD(bnet, Q2, 'CPT', startprob2, 'adjustable', 0);
+bnet.CPD{eclass(Q3,1)} = tabular_CPD(bnet, Q3, 'CPT', startprob3, 'adjustable', 0);
+
+bnet.CPD{eclass(F2,1)}  = hhmmF_CPD(bnet, F2, Qnodes, 2, D, 'termprob', termprob2);
+bnet.CPD{eclass(F3,1)}  = tabular_CPD(bnet, F3, 'CPT', termprob3);
+
+if discrete_obs
+  bnet.CPD{eclass(obs,1)} = tabular_CPD(bnet, obs, Oargs{:});
+else
+  bnet.CPD{eclass(obs,1)} = gaussian_CPD(bnet, obs, Oargs{:});
+end
+
+% SLICE 2
+
+bnet.CPD{eclass(Q1,2)} = hhmmQ_CPD(bnet, Q1+ss, Qnodes, 1, D, 'transprob', transprob1, 'startprob', startprob1);
+bnet.CPD{eclass(Q2,2)} = hhmmQ_CPD(bnet, Q2+ss, Qnodes, 2, D, 'transprob', transprob2, 'startprob', startprob2);
+bnet.CPD{eclass(Q3,2)} = hhmmQ_CPD(bnet, Q3+ss, Qnodes, 3, D, 'transprob', transprob3, 'startprob', startprob3);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3_args.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3_args.m
new file mode 100644
index 00000000..bc3ec886
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3_args.m
@@ -0,0 +1,165 @@
+function bnet = mk_hhmm3(varargin)
+% MK_HHMM3 Make a 3 level Hierarchical HMM
+% bnet = mk_hhmm3(...)
+%
+% 3-layer hierarchical HMM where level 1 only connects to level 2, not 3 or obs.
+% This enforces sub-models (which differ only in their Q1 index) to be shared.
+% Also, we enforce the fact that each model always starts in its initial state
+% and only finishes in its final state. However, the prob. of finishing (as opposed to
+% self-transitioning to the final state) can be learned.
+% The fact that we always finish from the same state means we do not need to condition
+% F(i) on Q(i-1), since finishing prob is indep of calling context.
+%
+% The DBN is the same as Fig 10 in my tech report.
+%
+%   Q1 ---------->  Q1
+%   |              / |
+%   |             /  |
+%   |  F2 -------    |
+%   |  ^         \   |
+%   | /|          \  |
+%   v  |           v v
+%   Q2-| -------->   Q2
+%  /|  |             ^
+% / |  |            /|
+% | |  F3 ---------/ |
+% | |  ^           \ |
+% | v /              v
+% | Q3 ----------->  Q3
+% |  |    
+% \  | 
+%  v v    
+%   O
+%
+% Q1 (slice 1) is clamped to be uniform.
+% Q2 (slice 1) is clamped to always start in state 1.
+% Q3 (slice 1) is clamped to always start in state 1.
+% F3 by default will only finish if Q3 is in its last state (F3 is a tabular_CPD)
+% F2 by default gets the default hhmmF_CPD params.
+% Q1:Q3 (slice 2) by default gets the default hhmmQ_CPD params.
+% O by default gets the default tabular/Gaussian params.
+%
+% Optional arguments in name/value format [default]
+%
+% Qsizes      - sizes at each level [ none ]
+% Osize       - size of O node [ none ]
+% discrete_obs - 1 means O is tabular_CPD, 0 means O is gaussian_CPD [0]
+% Oargs       - cell array of args to pass to the O CPD  [ {} ]
+% Q1args      - args to be passed to constructor for Q1 (slice 2) [ {} ]
+% Q2args      - args to be passed to constructor for Q2 (slice 2) [ {} ]
+% Q3args      - args to be passed to constructor for Q3 (slice 2) [ {} ]
+% F2args       - args to be passed to constructor for F2 [ {} ]
+% F3args       - args to be passed to constructor for F3 [ {'CPT', finish in last Q3 state} ]
+%
+
+ss = 6; D = 3;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; obs = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+names = {'Q1', 'Q2', 'Q3', 'F3', 'F2', 'obs'};
+
+intra = zeros(ss);
+intra(Q1, Q2) = 1;
+intra(Q2, [F2 Q3 obs]) = 1;
+intra(Q3, [F3 obs]) = 1;
+intra(F3, F2) = 1;
+
+inter = zeros(ss);
+inter(Q1,Q1) = 1;
+inter(Q2,Q2) = 1;
+inter(Q3,Q3) = 1;
+inter(F2,[Q1 Q2]) = 1;
+inter(F3,[Q2 Q3]) = 1;
+
+
+% get sizes of nodes
+args = varargin;
+nargs = length(args);
+Qsizes = [];
+Osize = 0;
+for i=1:2:nargs
+  switch args{i},
+   case 'Qsizes', Qsizes = args{i+1}; 
+   case 'Osize', Osize = args{i+1}; 
+  end
+end
+if isempty(Qsizes), error('must specify Qsizes'); end
+if Osize==0, error('must specify Osize'); end
+  
+% set default params
+discrete_obs = 0;
+Oargs = {};
+Q1args = {};
+Q2args = {};
+Q3args = {};
+F2args = {};
+
+% P(Q3, F3)
+CPT = zeros(Qsizes(3), 2);
+% Each model can only terminate in its final state.
+% 0 params will remain 0 during EM, thus enforcing this constraint.
+CPT(:, 1) = 1.0; % all states turn F off ...
+p = 0.5;
+CPT(Qsizes(3), 2) = p; % except the last one
+CPT(Qsizes(3), 1) = 1-p;
+F3args = {'CPT', CPT};
+
+for i=1:2:nargs
+  switch args{i},
+   case 'discrete_obs', discrete_obs = args{i+1}; 
+   case 'Oargs',        Oargs = args{i+1};
+   case 'Q1args',       Q1args = args{i+1};
+   case 'Q2args',       Q2args = args{i+1};
+   case 'Q3args',       Q3args = args{i+1};
+   case 'F2args',       F2args = args{i+1};
+   case 'F3args',       F3args = args{i+1};
+  end
+end
+
+ns = zeros(1,ss);
+ns(Qnodes) = Qsizes;
+ns(obs) = Osize;
+ns(Fnodes) = 2;
+
+dnodes = [Qnodes Fnodes];
+if discrete_obs
+  dnodes = [dnodes obs];
+end
+onodes = [obs];
+
+bnet = mk_dbn(intra, inter, ns, 'observed', onodes, 'discrete', dnodes, 'names', names);
+eclass = bnet.equiv_class;
+
+% SLICE 1
+
+% We clamp untied nodes in the first slice, since their params can't be estimated
+% from just one sequence
+
+% uniform prior on initial model
+CPT = normalise(ones(1,ns(Q1)));
+bnet.CPD{eclass(Q1,1)} = tabular_CPD(bnet, Q1, 'CPT', CPT, 'adjustable', 0);
+
+% each model always starts in state 1
+CPT = zeros(ns(Q1), ns(Q2));
+CPT(:, 1) = 1.0;
+bnet.CPD{eclass(Q2,1)} = tabular_CPD(bnet, Q2, 'CPT', CPT, 'adjustable', 0);
+
+% each model always starts in state 1
+CPT = zeros(ns(Q2), ns(Q3));
+CPT(:, 1) = 1.0;
+bnet.CPD{eclass(Q3,1)} = tabular_CPD(bnet, Q3, 'CPT', CPT, 'adjustable', 0);
+
+bnet.CPD{eclass(F2,1)}  = hhmmF_CPD(bnet, F2, Qnodes, 2, D, F2args{:});
+
+bnet.CPD{eclass(F3,1)}  = tabular_CPD(bnet, F3, F3args{:});
+
+if discrete_obs
+  bnet.CPD{eclass(obs,1)} = tabular_CPD(bnet, obs, Oargs{:});
+else
+  bnet.CPD{eclass(obs,1)} = gaussian_CPD(bnet, obs, Oargs{:});
+end
+
+% SLICE 2
+
+bnet.CPD{eclass(Q1,2)} = hhmmQ_CPD(bnet, Q1+ss, Qnodes, 1, D, Q1args{:});
+bnet.CPD{eclass(Q2,2)} = hhmmQ_CPD(bnet, Q2+ss, Qnodes, 2, D, Q2args{:});
+bnet.CPD{eclass(Q3,2)} = hhmmQ_CPD(bnet, Q3+ss, Qnodes, 3, D, Q3args{:});
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/motif_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/motif_hhmm.m
new file mode 100644
index 00000000..10144b58
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/motif_hhmm.m
@@ -0,0 +1,95 @@
+% Make the following HHMM
+%
+%    S1 <----------------------> S2
+%    |                           |
+%    |                           |
+%   M1 -> M2 -> M3 -> end        B1 -> end
+%
+% where Mi represents the i'th letter in the motif
+% and B is the background state.
+% Si chooses between running the motif or the background.
+% The Si and B states have self loops (not shown).
+
+if 0
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+end
+
+chars = ['a', 'c', 'g', 't'];
+Osize = length(chars);
+
+motif_pattern = 'acca';
+motif_length = length(motif_pattern);
+Qsize = [2 motif_length];
+Qnodes = 1:2;
+D = 2;
+transprob = cell(1,D);
+termprob = cell(1,D);
+startprob = cell(1,D);
+
+% startprob{d}(k,j), startprob{1}(1,j)
+% transprob{d}(i,k,j), transprob{1}(i,j)
+% termprob{d}(k,j)
+
+
+% LEVEL 1
+
+startprob{1} = zeros(1, 2);
+startprob{1} = [1 0]; % always start in the background model
+
+% When in the background state, we stay there with high prob
+% When in the motif state, we immediately return to the background state.
+transprob{1} = [0.8 0.2;
+		1.0 0.0];
+
+
+% LEVEL 2
+startprob{2} = 'leftstart'; % both submodels start in substate 1
+transprob{2} = zeros(motif_length, 2, motif_length);
+termprob{2} = zeros(2, motif_length);
+
+% In the background model, we only use state 1.
+transprob{2}(1,1,1) = 1; % self loop
+termprob{2}(1,1) = 0.2; % prob transition to end state
+
+% Motif model
+transprob{2}(:,2,:) = mk_leftright_transmat(motif_length, 0);
+termprob{2}(2,end) = 1.0; % last state immediately terminates
+
+
+% OBS LEVEl
+
+obsprob = zeros([Qsize Osize]);
+if 0
+  % uniform background model
+  obsprob(1,1,:) = normalise(ones(Osize,1));
+else
+  % deterministic background model (easy to see!)
+  m = find(chars=='t');
+  obsprob(1,1,m) = 1.0;
+end
+if 1
+  % initialise with true motif (cheating)
+  for i=1:motif_length
+    m = find(chars == motif_pattern(i));
+    obsprob(2,i,m) = 1.0;
+  end
+end
+
+Oargs = {'CPT', obsprob};
+
+[bnet, Qnodes, Fnodes, Onode] = mk_hhmm('Qsizes', Qsize, 'Osize', Osize, 'discrete_obs', 1, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(1:2), ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
+
+Tmax = 20;
+usecell = 0;
+
+for seqi=1:5
+  evidence = sample_dbn(bnet, Tmax, usecell);
+  chars(evidence(end,:))
+  %T = size(evidence, 2)
+  %pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, Onode, chars);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/remove_hhmm_end_state.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/remove_hhmm_end_state.m
new file mode 100644
index 00000000..2bf10d72
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/remove_hhmm_end_state.m
@@ -0,0 +1,37 @@
+function [transprob, termprob] = remove_hhmm_end_state(A)
+% REMOVE_END_STATE Infer transition and termination probabilities from automaton with an end state
+% [transprob, termprob] = remove_end_state(A)
+% A(i,k,j) = Pr( i->j | Qps=k), where i in 1:Q, j in 1:(Q+1), and Q+1 is the end state
+
+if ndims(A)==2 % top level
+  Q = size(A,1);
+  transprob = A(:,1:Q);
+  termprob = A(:,Q+1)';
+  
+  % rescale
+  for i=1:Q
+    for j=1:Q
+      denom = (1-termprob(i));
+      denom = denom + (denom==0)*eps;
+      transprob(i,j) = transprob(i,j) / denom;
+    end
+  end    
+else
+  Q = size(A,1);
+  Qk = size(A,2);
+  transprob = A(:, :, 1:Q);
+  termprob = A(:,:,Q+1)';
+
+  % rescale
+  for k=1:Qk
+    for i=1:Q
+      for j=1:Q
+	denom = (1-termprob(k,i));
+	denom = denom + (denom==0)*eps;
+	transprob(i,k,j) = transprob(i,k,j) / denom;
+      end
+    end    
+  end
+  
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Entries
new file mode 100644
index 00000000..fdee19ae
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Entries
@@ -0,0 +1,14 @@
+/get_square_data.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/hhmm_inference.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/is_F2_true_D3.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/learn_square_hhmm_cts.m/1.1.1.1/Thu Jun 20 00:19:22 2002//
+/learn_square_hhmm_discrete.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_square_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/plot_square_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_square_hhmm_cts.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_square_hhmm_discrete.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/square4.mat/1.1.1.1/Wed May 29 15:59:54 2002//
+/square4_cases.mat/1.1.1.1/Wed May 29 15:59:54 2002//
+/test_square_fig.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/test_square_fig.mat/1.1.1.1/Wed May 29 15:59:54 2002//
+D/Old////
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Repository
new file mode 100644
index 00000000..e926a0d5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Square
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Entries
new file mode 100644
index 00000000..6d415d0d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Entries
@@ -0,0 +1,5 @@
+/learn_square_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_square_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/plot_square_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_square_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Repository
new file mode 100644
index 00000000..47df1a8c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Square/Old
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/learn_square_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/learn_square_hhmm.m
new file mode 100644
index 00000000..695ae047
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/learn_square_hhmm.m
@@ -0,0 +1,294 @@
+% Learn a 3 level HHMM similar to mk_square_hhmm
+
+% Because startprob should be shared for t=1:T,
+% but in the DBN is shared for t=2:T, we train using a single long sequence.
+
+discrete_obs = 0;
+supervised = 1;
+obs_finalF2 = 0;
+% It is not possible to observe F2 if we learn
+% because the update_ess method for hhmmF_CPD and hhmmQ_CPD assume
+% the F nodes are always hidden (for speed).
+% However, for generating, we might want to set the final F2=true
+% to force all subroutines to finish.
+
+ss = 6;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+if discrete_obs
+  Qsizes = [2 4 2];
+else
+  Qsizes = [2 4 1];
+end
+
+D = 3;
+Qnodes = 1:D;
+startprob = cell(1,D);
+transprob = cell(1,D);
+termprob = cell(1,D);
+
+startprob{1} = 'unif';
+transprob{1} = 'unif';
+
+% In the unsupervised case, it is essential that we break symmetry
+% in the initial param estimates.
+%startprob{2} = 'unif';
+%transprob{2} = 'unif';
+%termprob{2} = 'unif';
+startprob{2} = 'rnd';
+transprob{2} = 'rnd';
+termprob{2} = 'rnd';
+
+leftright = 0;
+if leftright
+  % Initialise base-level models as left-right.
+  % If we initialise with delta functions,
+  % they will remain delat funcitons after learning
+  startprob{3} = 'leftstart';
+  transprob{3}  = 'leftright';
+  termprob{3} = 'rightstop';
+else
+  % If we want to be able to run a base-level model backwards...
+  startprob{3} = 'rnd';
+  transprob{3}  = 'rnd';
+  termprob{3} = 'rnd';
+end
+
+if discrete_obs
+  % Initialise observations of lowest level primitives in a way which we can interpret
+  chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+  L=find(chars=='L'); l=find(chars=='l');
+  U=find(chars=='U'); u=find(chars=='u');
+  R=find(chars=='R'); r=find(chars=='r');
+  D=find(chars=='D'); d=find(chars=='d');
+  Osize = length(chars);
+  
+  p = 0.9;
+  obsprob = (1-p)*ones([4 2 Osize]);
+  %       Q2 Q3 O
+  obsprob(1, 1, L) =  p;
+  obsprob(1, 2, l) =  p;
+  obsprob(2, 1, U) =  p;
+  obsprob(2, 2, u) =  p;
+  obsprob(3, 1, R) =  p;
+  obsprob(3, 2, r) =  p;
+  obsprob(4, 1, D) =  p;
+  obsprob(4, 2, d) =  p;
+  obsprob = mk_stochastic(obsprob);
+  Oargs = {'CPT', obsprob};
+
+else
+  % Initialise means of lowest level primitives in a way which we can interpret
+  % These means are little vectors in the east, south, west, north directions.
+  % (left-right=east, up-down=south, right-left=west, down-up=north)
+  Osize = 2;
+  mu = zeros(2, Qsizes(2), Qsizes(3));
+  noise = 0;
+  scale = 3;
+  for q3=1:Qsizes(3)
+    mu(:, 1, q3) = scale*[1;0] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 2, q3) = scale*[0;-1] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 3, q3) = scale*[-1;0] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 4, q3) = scale*[0;1] + noise*rand(2,1);
+  end
+  Sigma = repmat(reshape(scale*eye(2), [2 2 1 1 ]), [1 1 Qsizes(2) Qsizes(3)]);
+  Oargs = {'mean', mu, 'cov', Sigma, 'cov_type', 'diag'};
+end
+
+bnet = mk_hhmm('Qsizes', Qsizes, 'Osize', Osize', 'discrete_obs', discrete_obs,...
+	       'Oargs', Oargs, 'Ops', Qnodes(2:3), ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
+if supervised
+  bnet.observed = [Q1 Q2 Onode];
+else
+  bnet.observed = [Onode];
+end
+
+if obs_finalF2
+  engine = jtree_dbn_inf_engine(bnet);
+  % can't use ndx version because sometimes F2 is hidden, sometimes observed
+  error('can''t observe F when learning')
+else
+  if supervised
+    engine = jtree_ndx_dbn_inf_engine(bnet);
+  else
+    engine = jtree_hmm_inf_engine(bnet);
+  end
+end
+  
+if discrete_obs
+  % generate some synthetic data (easier to debug)
+  cases = {};
+
+  T = 8;
+  ev = cell(ss, T);
+  ev(Onode,:) = num2cell([L l U u R r D d]);
+  if supervised
+    ev(Q1,:) = num2cell(1*ones(1,T));
+    ev(Q2,:) = num2cell( [1 1 2 2 3 3 4 4]);
+  end
+  cases{1} = ev;
+  cases{3} = ev;
+    
+  T  = 8;
+  ev = cell(ss, T);
+  if leftright % base model is left-right
+    ev(Onode,:) = num2cell([R r U u L l D d]);
+  else
+    ev(Onode,:) = num2cell([r R u U l L d D]);
+  end
+  if supervised
+    ev(Q1,:) = num2cell(2*ones(1,T));
+    ev(Q2,:) = num2cell( [3 3 2 2 1 1 4 4]);
+  end
+    
+  cases{2} = ev;
+  cases{4} = ev;
+
+  if obs_finalF2
+    for i=1:length(cases)
+      T = size(cases{i},2);
+      cases{i}(F2,T)={2}; % force F2 to be finished at end of seq
+    end
+  end
+
+  if 0
+    ev = cases{4};
+    engine2 = enter_evidence(engine2, ev);
+    T = size(ev,2);
+    for t=1:T
+      m=marginal_family(engine2, F2, t);
+      fprintf('t=%d\n', t);
+      reshape(m.T, [2 2])
+    end
+  end
+  
+  %  [bnet2, LL] = learn_params_dbn_em(engine, cases, 'max_iter', 10);
+  long_seq = cat(2, cases{:});
+  [bnet2, LL, engine2] = learn_params_dbn_em(engine, {long_seq}, 'max_iter', 200);
+  
+  % figure out which subsequence each model is responsible for
+  mpe = calc_mpe_dbn(engine2, long_seq);
+  pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, chars);
+
+else
+  load 'square4_cases' % cases{seq}{i,t} for i=1:ss 
+  %plot_square_hhmm(cases{1})
+  %long_seq = cat(2, cases{:});
+  train_cases = cases(1:2);
+  long_seq = cat(2, train_cases{:});
+  if ~supervised
+    T = size(long_seq,2);
+    for t=1:T
+      long_seq{Q1,t} = [];
+      long_seq{Q2,t} = [];
+    end
+  end
+  [bnet2, LL, engine2] = learn_params_dbn_em(engine, {long_seq}, 'max_iter', 100);
+
+  CPDO=struct(bnet2.CPD{eclass(Onode,1)});
+  mu = CPDO.mean;
+  Sigma = CPDO.cov;
+  CPDO_full = CPDO;
+  
+  % force diagonal covs after training
+  for k=1:size(Sigma,3)
+    Sigma(:,:,k) = diag(diag(Sigma(:,:,k)));
+  end
+  bnet2.CPD{6} = set_fields(bnet.CPD{6}, 'cov', Sigma);
+  
+  if 0
+  % visualize each model by concatenating means for each model for nsteps in a row
+  nsteps = 5;
+  ev = cell(ss, nsteps*prod(Qsizes(2:3)));
+  t = 1;
+  for q2=1:Qsizes(2)
+    for q3=1:Qsizes(3)
+      for i=1:nsteps
+	ev{Onode,t} = mu(:,q2,q3);
+	ev{Q2,t} = q2;
+	t = t + 1;
+      end
+    end
+  end
+  plot_square_hhmm(ev)      
+  end
+
+  % bnet3 is the same as the learned model, except we will use it in testing mode
+  if supervised
+    bnet3 = bnet2;
+    bnet3.observed = [Onode];
+    engine3 = hmm_inf_engine(bnet3);
+    %engine3 = jtree_ndx_dbn_inf_engine(bnet3);
+  else
+    bnet3 = bnet2;
+    engine3 = engine2;
+  end
+  
+  if 0
+  % segment whole sequence
+  mpe = calc_mpe_dbn(engine3, long_seq);
+  pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, []);
+  end
+  
+  % segment each sequence
+  test_cases = cases(3:4);
+  for i=1:2
+    ev = test_cases{i};
+    T = size(ev, 2);
+    for t=1:T
+      ev{Q1,t} = [];
+      ev{Q2,t} = [];
+    end
+    mpe = calc_mpe_dbn(engine3, ev);
+    subplot(1,2,i)
+    plot_square_hhmm(mpe)      
+    %pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, []);
+    q1s = cell2num(mpe(Q1,:));
+    h = hist(q1s, 1:Qsizes(1));
+    map_q1 = argmax(h);
+    str = sprintf('test seq %d is of type %d\n', i, map_q1);
+    title(str)
+  end
+
+end
+
+if 0
+% Estimate gotten by couting transitions in the labelled data
+% Note that a self transition shouldnt count if F2=off.
+Q2ev = cell2num(ev(Q2,:));
+Q2a = Q2ev(1:end-1);
+Q2b = Q2ev(2:end);
+counts = compute_counts([Q2a; Q2b], [4 4]);
+end
+
+eclass = bnet2.equiv_class;
+CPDQ1=struct(bnet2.CPD{eclass(Q1,2)});
+CPDQ2=struct(bnet2.CPD{eclass(Q2,2)});
+CPDQ3=struct(bnet2.CPD{eclass(Q3,2)});
+CPDF2=struct(bnet2.CPD{eclass(F2,1)});
+CPDF3=struct(bnet2.CPD{eclass(F3,1)});
+
+
+A=add_hhmm_end_state(CPDQ2.transprob, CPDF2.termprob(:,:,2));
+squeeze(A(:,1,:))
+squeeze(A(:,2,:))
+CPDQ2.startprob
+ 
+if 0
+S=struct(CPDF2.sub_CPD_term);
+S.nsamples
+reshape(S.counts, [2 4 2])
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/mk_square_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/mk_square_hhmm.m
new file mode 100644
index 00000000..608b6784
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/mk_square_hhmm.m
@@ -0,0 +1,183 @@
+function bnet = mk_square_hhmm(discrete_obs, true_params, topright)
+
+% Make a 3 level  HHMM described by the following grammar
+%
+% Square -> CLK | CCK % clockwise or counterclockwise
+% CLK -> LR UD RL DU start on top left (1 2 3 4)
+% CCK -> RL UD LR DU  if start at top right (3 2 1 4)
+% CCK -> UD LR DU RL if start at top left (2 1 4 3)
+%
+% LR = left-right, UD = up-down, RL = right-left, DU = down-up
+% LR, UD, RL, DU are sub HMMs.
+%
+% For discrete observations, the subHMMs are 2-state left-right.
+% LR emits L then l, etc.
+%
+% For cts observations, the subHMMs are 1 state.
+% LR emits a vector in the -> direction, with a little noise.
+% Since there is no constraint that we remain in the LR state as long as the RL state,
+% the sides of the square might have different lengths,
+% so the result is not really a square!
+%
+% If true_params = 0, we use random parameters at the top 2 levels
+% (ready for learning). At the bottom level, we use noisy versions
+% of the "true" observations.
+%
+% If topright=1, counter-clockwise starts at top right, not top left
+% This example was inspired by Ivanov and Bobick.
+
+if nargin < 3, topright = 1; end
+
+if 1 % discrete_obs
+  Qsizes = [2 4 2];
+else
+  Qsizes = [2 4 1];
+end
+
+D = 3;
+Qnodes = 1:D;
+startprob = cell(1,D);
+transprob = cell(1,D);
+termprob = cell(1,D);
+
+% LEVEL 1
+
+startprob{1} = 'unif';
+transprob{1} = 'unif';
+
+% LEVEL 2
+
+if true_params
+  startprob{2} = zeros(2, 4);
+  startprob{2}(1, :) = [1 0 0 0];
+  if topright
+    startprob{2}(2, :) = [0 0 1 0];
+  else
+    startprob{2}(2, :) = [0 1 0 0];
+  end
+  
+  transprob{2} = zeros(4, 2, 4);
+  
+  transprob{2}(:,1,:) = [0 1 0 0
+		    0 0 1 0
+		    0 0 0 1
+		    0 0 0 1]; % 4->e
+  if topright
+    transprob{2}(:,2,:) = [0 0 0 1
+		    1 0 0 0
+		    0 1 0 0
+		    0 0 0 1]; % 4->e
+  else
+    transprob{2}(:,2,:) = [0 0 0 1
+		    1 0 0 0
+		    0 0 1 0 % 3->e
+		    0 0 1 0];
+  end
+  
+  %termprob{2} = 'rightstop';
+  termprob{2} = zeros(2,4,2);
+  pfin = 0.8;
+  termprob{2}(1,:,2) = [0 0 0 pfin]; % finish in state 4 (DU)
+  termprob{2}(1,:,1) = 1 - [0 0 0 pfin];
+  if topright
+    termprob{2}(2,:,2) = [0 0 0 pfin];
+    termprob{2}(2,:,1) = 1 - [0 0 0 pfin];
+  else
+    termprob{2}(2,:,2) = [0 0 pfin 0];  % finish in state 3 (RL)
+    termprob{2}(2,:,1) = 1 - [0 0 pfin 0];
+  end
+else
+  % In the unsupervised case, it is essential that we break symmetry
+  % in the initial param estimates.
+  %startprob{2} = 'unif';
+  %transprob{2} = 'unif';
+  %termprob{2} = 'unif';
+  startprob{2} = 'rnd';
+  transprob{2} = 'rnd';
+  termprob{2} = 'rnd';
+end
+
+% LEVEL 3
+
+if 1 |  true_params
+  startprob{3} = 'leftstart';
+  transprob{3}  = 'leftright';
+  termprob{3} = 'rightstop';
+else
+  % If we want to be able to run a base-level model backwards...
+  startprob{3} = 'rnd';
+  transprob{3}  = 'rnd';
+  termprob{3} = 'rnd';
+end
+ 
+
+% OBS LEVEl
+
+if discrete_obs
+  % Initialise observations of lowest level primitives in a way which we can interpret
+  chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+  L=find(chars=='L'); l=find(chars=='l');
+  U=find(chars=='U'); u=find(chars=='u');
+  R=find(chars=='R'); r=find(chars=='r');
+  D=find(chars=='D'); d=find(chars=='d');
+  Osize = length(chars);
+  
+  if true_params
+    p = 1; % makes each state fully observed
+  else
+    p = 0.9;
+  end
+  
+  obsprob = (1-p)*ones([4 2 Osize]);
+  %       Q2 Q3 O
+  obsprob(1, 1, L) =  p;
+  obsprob(1, 2, l) =  p;
+  obsprob(2, 1, U) =  p;
+  obsprob(2, 2, u) =  p;
+  obsprob(3, 1, R) =  p;
+  obsprob(3, 2, r) =  p;
+  obsprob(4, 1, D) =  p;
+  obsprob(4, 2, d) =  p;
+  obsprob = mk_stochastic(obsprob);
+  Oargs = {'CPT', obsprob};
+else
+  % Initialise means of lowest level primitives in a way which we can interpret
+  % These means are little vectors in the east, south, west, north directions.
+  % (left-right=east, up-down=south, right-left=west, down-up=north)
+  Osize = 2;
+  mu = zeros(2, Qsizes(2), Qsizes(3));
+  scale = 3;
+  if true_params
+    noise = 0;
+  else
+    noise = 0.5*scale;
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 1, q3) = scale*[1;0] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 2, q3) = scale*[0;-1] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 3, q3) = scale*[-1;0] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 4, q3) = scale*[0;1] + noise*rand(2,1);
+  end
+  Sigma = repmat(reshape(scale*eye(2), [2 2 1 1 ]), [1 1 Qsizes(2) Qsizes(3)]);
+  Oargs = {'mean', mu, 'cov', Sigma, 'cov_type', 'diag'};
+end
+
+if discrete_obs
+  selfprob = 0.5;
+else
+  selfprob = 0.95;
+  % If less than this, it won't look like a square
+  % because it doesn't spend enough time in each state
+  % Unfortunately, the variance on durations (lengths of each side)
+  % is very large
+end
+bnet = mk_hhmm('Qsizes', Qsizes, 'Osize', Osize', 'discrete_obs', discrete_obs, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(2:3), 'selfprob', selfprob, ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/plot_square_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/plot_square_hhmm.m
new file mode 100644
index 00000000..e6701e45
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/plot_square_hhmm.m
@@ -0,0 +1,32 @@
+function plot_square_hhmm(ev)
+% Plot the square shape implicit in the evidence.
+% ev{i,t} is the value of node i in slice t.
+% The observed node contains a velocity (delta increment), which is converted
+% into a position.
+% The Q2 node specifies which model is used; each segment is color-coded
+% in the order red, green, blue, black.
+
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+
+delta = cell2num(ev(Onode,:)); % delta(:,t)
+Q2label = cell2num(ev(Q2,:)); 
+
+T = size(delta, 2);
+pos = zeros(2,T+1);
+clf
+hold on
+cols = {'r', 'g', 'b', 'k'};
+boundary = 0;
+coli = 1;
+for t=2:T+1
+  pos(:,t) = pos(:,t-1) + delta(:,t-1);
+  plot(pos(1,t), pos(2,t), sprintf('%c.', cols{coli}));
+  if t < T
+    boundary = (Q2label(t) ~= Q2label(t-1));
+  end
+  if boundary
+    coli = coli + 1;
+    coli = mod(coli-1, length(cols)) + 1;
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/sample_square_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/sample_square_hhmm.m
new file mode 100644
index 00000000..a0f9007e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/sample_square_hhmm.m
@@ -0,0 +1,160 @@
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+discrete_obs = 1;
+topright = 0;
+
+Qsizes = [2 4 2];
+D = 3;
+Qnodes = 1:D;
+startprob = cell(1,D);
+transprob = cell(1,D);
+termprob = cell(1,D);
+
+% LEVEL 1
+
+startprob{1} = 'ergodic';
+transprob{1} = 'ergodic';
+
+% LEVEL 2
+
+startprob{2} = zeros(2, 4);
+startprob{2}(1, :) = [1 0 0 0];
+if topright
+  startprob{2}(2, :) = [0 0 1 0];
+else
+  startprob{2}(2, :) = [0 1 0 0];
+end
+
+transprob{2} = zeros(4, 2, 4);
+
+transprob{2}(:,1,:) = [0 1 0 0
+		       0 0 1 0
+		       0 0 0 1
+		       0 0 0 1]; % 4->e
+if topright
+  transprob{2}(:,2,:) = [0 0 0 1
+		    1 0 0 0
+		    0 1 0 0
+		    0 0 0 1]; % 4->e
+else
+  transprob{2}(:,2,:) = [0 0 0 1
+		    1 0 0 0
+		    0 0 1 0 % 3->e
+		    0 0 1 0];
+end
+
+%termprob{2} = 'rightstop';
+termprob{2} = zeros(2,4,2);
+pfin = 0.8;
+termprob{2}(1,:,2) = [0 0 0 pfin]; % finish in state 4 (DU)
+termprob{2}(1,:,1) = 1 - [0 0 0 pfin];
+if topright
+  termprob{2}(2,:,2) = [0 0 0 pfin];
+  termprob{2}(2,:,1) = 1 - [0 0 0 pfin];
+else
+  termprob{2}(2,:,2) = [0 0 pfin 0];  % finish in state 3 (RL)
+  termprob{2}(2,:,1) = 1 - [0 0 pfin 0];
+end
+
+% LEVEL 3
+
+startprob{3} = 'leftstart';
+transprob{3}  = 'leftright';
+termprob{3} = 'rightstop';
+
+
+% OBS LEVEl
+
+if discrete_obs
+  chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+  L=find(chars=='L'); l=find(chars=='l');
+  U=find(chars=='U'); u=find(chars=='u');
+  R=find(chars=='R'); r=find(chars=='r');
+  D=find(chars=='D'); d=find(chars=='d');
+  Osize = length(chars);
+  
+  obsprob = zeros([4 2 Osize]);
+  %       Q2 Q3 O
+  obsprob(1, 1, L) =  1.0;
+  obsprob(1, 2, l) =  1.0;
+  obsprob(2, 1, U) =  1.0;
+  obsprob(2, 2, u) =  1.0;
+  obsprob(3, 1, R) =  1.0;
+  obsprob(3, 2, r) =  1.0;
+  obsprob(4, 1, D) =  1.0;
+  obsprob(4, 2, d) =  1.0;
+  
+  Oargs = {'CPT', obsprob};
+else
+  Osize = 2;
+  mu = zeros(2, 4, 2);
+  noise = 0;
+  scale = 10;
+  for q3=1:2
+    mu(:, 1, q3) = scale*[1;0] + noise*rand(2,1);
+  end
+  for q3=1:2
+    mu(:, 2, q3) = scale*[0;-1] + noise*rand(2,1);
+  end
+  for q3=1:2
+    mu(:, 3, q3) = scale*[-1;0] + noise*rand(2,1);
+  end
+  for q3=1:2
+    mu(:, 4, q3) = scale*[0;1] + noise*rand(2,1);
+  end
+  Sigma = repmat(reshape(0.01*eye(2), [2 2 1 1 ]), [1 1 4 2]);
+  Oargs = {'mean', mu, 'cov', Sigma};
+end
+
+bnet = mk_hhmm('Qsizes', Qsizes, 'Osize', Osize', 'discrete_obs', discrete_obs, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(2:3), ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
+if discrete_obs
+  Tmax = 30;
+else
+  Tmax = 200;
+end
+usecell = ~discrete_obs;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+
+for seqi=1:3
+  evidence = sample_dbn(bnet, Tmax, usecell, 'stop_sampling_F2');      
+  T = size(evidence, 2)
+  if discrete_obs
+    pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, Onode, chars);
+  else
+    pos = zeros(2,T+1);
+    delta = cell2num(evidence(Onode,:));
+    clf
+    hold on
+    cols = {'r', 'g', 'k', 'b'};
+    boundary = cell2num(evidence(F3,:))-1;
+    coli = 1;
+    for t=2:T+1
+      pos(:,t) = pos(:,t-1) + delta(:,t-1);
+      plot(pos(1,t), pos(2,t), sprintf('%c.', cols{coli}));
+      if boundary(t-1)
+	coli = coli + 1;
+	coli = mod(coli-1, length(cols)) + 1;
+      end
+    end
+    %plot(pos(1,:), pos(2,:), '.')
+    %pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, Onode, []);
+    pause
+  end
+end
+
+eclass = bnet.equiv_class;
+S=struct(bnet.CPD{eclass(Q2,2)});
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/get_square_data.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/get_square_data.m
new file mode 100644
index 00000000..9790221c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/get_square_data.m
@@ -0,0 +1,70 @@
+% Let the user draw a square with the mouse,
+% and then click on the corners to do a manual segmentation
+
+ss = 6;
+Q1 = 1; Q2 = 2; Q3 = 3; obsvel = 6;
+CLOCKWISE = 1; ANTICLOCK = 2;
+LR = 1; UD = 2; RL = 3; DU = 4;
+
+% repeat this block manually incrementing the sequence number
+% and setting ori.
+% (since I don't know how to call getmouse as a call-return function).
+seq = 4;
+%ori = CLOCKWISE
+ori = ANTICLOCK;
+clear xpos ypos
+getmouse
+% end block
+
+% manual segmentation with the mouse
+startseg(1) = 1;
+for i=2:4
+  fprintf('click on start of segment %d\n', i);
+  [x,y] = ginput(1);
+  plot(x,y,'ro')
+  d = dist2([xpos; ypos]', [x y]);
+  startseg(i) = argmin(d);
+end
+
+% plot corners in green 
+%ti = first point in (i+1)st segment
+t1 = startseg(1); t2 = startseg(2); t3 = startseg(3); t4 = startseg(4); 
+plot(xpos(t2), ypos(t2), 'g*')
+plot(xpos(t3), ypos(t3), 'g*')
+plot(xpos(t4), ypos(t4), 'g*')
+
+
+xvel = xpos(2:end) - xpos(1:end-1);
+yvel = ypos(2:end) - ypos(1:end-1);
+speed = [xvel(:)'; yvel(:)'];
+pos_data{seq} = [xpos(:)'; ypos(:)'];
+vel_data{seq} = [xvel(:)'; yvel(:)'];
+T = length(xvel);
+Q1label{seq} = num2cell(repmat(ori, 1, T));
+Q2label{seq} = zeros(1, T);
+if ori == CLOCKWISE
+  Q2label{seq}(t1:t2) = LR;
+  Q2label{seq}(t2+1:t3) = UD;
+  Q2label{seq}(t3+1:t4) = RL;
+  Q2label{seq}(t4+1:T) = DU;
+else
+  Q2label{seq}(t1:t2) = RL;
+  Q2label{seq}(t2+1:t3) = UD;
+  Q2label{seq}(t3+1:t4) = LR;
+  Q2label{seq}(t4+1:T) = DU;
+end
+
+% pos_data{seq}(:,t), vel_data{seq}(:,t) Q1label{seq}(t) Q2label{seq}(t)
+save 'square4' pos_data vel_data Q1label Q2label
+
+nseq = 4;
+cases = cell(1,nseq);
+for seq=1:nseq
+  T = size(vel_data{seq},2);
+  ev = cell(ss,T);
+  ev(obsvel,:) = num2cell(vel_data{seq},1);
+  ev(Q1,:) = Q1label{seq};
+  ev(Q2,:) = num2cell(Q2label{seq});
+  cases{seq} = ev;
+end
+save 'square4_cases' cases 
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/hhmm_inference.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/hhmm_inference.m
new file mode 100644
index 00000000..c3bc8441
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/hhmm_inference.m
@@ -0,0 +1,13 @@
+bnet = mk_square_hhmm(1, 1);
+
+engine = {};
+engine{end+1} = hmm_inf_engine(bnet);
+engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet));
+
+exact = 1:length(engine);
+filter = 0;
+single = 0;
+maximize = 0;
+T = 4;
+
+[err, inf_time, engine] = cmp_inference(bnet, engine, exact, T, filter, single, maximize);
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/is_F2_true_D3.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/is_F2_true_D3.m
new file mode 100644
index 00000000..38d0b6e8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/is_F2_true_D3.m
@@ -0,0 +1,12 @@
+function stop = is_F2_true_D3(vals)
+% function stop = is_F2_true_D3(vals)
+% 
+% If vals(F2)=2 then level 2 has finished, so we return stop=1
+% to stop sample_dbn. Otherwise we return stop=0.
+% We assume this is for a D=3 level HHMM.
+
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+stop = 0;
+if (iscell(vals) & vals{F2}==2) | (~iscell(vals) & vals(F2)==2)
+  stop = 1;
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_cts.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_cts.m
new file mode 100644
index 00000000..77bdaec3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_cts.m
@@ -0,0 +1,152 @@
+% Try to learn a 3 level HHMM similar to mk_square_hhmm
+% from hand-drawn squares.
+
+% Because startprob should be shared for t=1:T,
+% but in the DBN is shared for t=2:T, we train using a single long sequence.
+
+discrete_obs = 0;
+supervised = 1;
+obs_finalF2 = 0;
+% It is not possible to observe F2 if we learn
+% because the update_ess method for hhmmF_CPD and hhmmQ_CPD assume
+% the F nodes are always hidden (for speed).
+% However, for generating, we might want to set the final F2=true
+% to force all subroutines to finish.
+
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+bnet = mk_square_hhmm(discrete_obs, 0);
+ 
+ss = 6;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+Qsizes = [2 4 1];
+  
+if supervised
+  bnet.observed = [Q1 Q2 Onode];
+else
+  bnet.observed = [Onode];
+end
+
+if obs_finalF2
+  engine = jtree_dbn_inf_engine(bnet);
+  % can't use ndx version because sometimes F2 is hidden, sometimes observed
+  error('can''t observe F when learning')
+else
+  if supervised
+    engine = jtree_ndx_dbn_inf_engine(bnet);
+  else
+    engine = jtree_hmm_inf_engine(bnet);
+  end
+end
+
+load 'square4_cases' % cases{seq}{i,t} for i=1:ss 
+%plot_square_hhmm(cases{1})
+%long_seq = cat(2, cases{:});
+train_cases = cases(1:2);
+long_seq = cat(2, train_cases{:});
+if ~supervised
+  T = size(long_seq,2);
+  for t=1:T
+    long_seq{Q1,t} = [];
+    long_seq{Q2,t} = [];
+  end
+end
+[bnet2, LL, engine2] = learn_params_dbn_em(engine, {long_seq}, 'max_iter', 2);
+
+eclass = bnet2.equiv_class;
+CPDO=struct(bnet2.CPD{eclass(Onode,1)});
+mu = CPDO.mean;
+Sigma = CPDO.cov;
+CPDO_full = CPDO;
+
+% force diagonal covs after training
+for k=1:size(Sigma,3)
+  Sigma(:,:,k) = diag(diag(Sigma(:,:,k)));
+end
+bnet2.CPD{6} = set_fields(bnet.CPD{6}, 'cov', Sigma);
+
+if 0
+  % visualize each model by concatenating means for each model for nsteps in a row
+  nsteps = 5;
+  ev = cell(ss, nsteps*prod(Qsizes(2:3)));
+  t = 1;
+  for q2=1:Qsizes(2)
+    for q3=1:Qsizes(3)
+      for i=1:nsteps
+	ev{Onode,t} = mu(:,q2,q3);
+	ev{Q2,t} = q2;
+	t = t + 1;
+      end
+    end
+  end
+  plot_square_hhmm(ev)      
+end
+
+% bnet3 is the same as the learned model, except we will use it in testing mode
+if supervised
+  bnet3 = bnet2;
+  bnet3.observed = [Onode];
+  engine3 = hmm_inf_engine(bnet3);
+  %engine3 = jtree_ndx_dbn_inf_engine(bnet3);
+else
+  bnet3 = bnet2;
+  engine3 = engine2;
+end
+
+if 0
+  % segment whole sequence
+  mpe = calc_mpe_dbn(engine3, long_seq);
+  pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, []);
+end
+
+% segment each sequence
+test_cases = cases(3:4);
+for i=1:2
+  ev = test_cases{i};
+  T = size(ev, 2);
+  for t=1:T
+    ev{Q1,t} = [];
+    ev{Q2,t} = [];
+  end
+  %mpe = calc_mpe_dbn(engine3, ev);
+  mpe = find_mpe(engine3, ev)
+  subplot(1,2,i)
+  plot_square_hhmm(mpe)      
+  %pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, []);
+  q1s = cell2num(mpe(Q1,:));
+  h = hist(q1s, 1:Qsizes(1));
+  map_q1 = argmax(h);
+  str = sprintf('test seq %d is of type %d\n', i, map_q1);
+  title(str)
+end
+
+
+if 0
+% Estimate gotten by couting transitions in the labelled data
+% Note that a self transition shouldnt count if F2=off.
+Q2ev = cell2num(ev(Q2,:));
+Q2a = Q2ev(1:end-1);
+Q2b = Q2ev(2:end);
+counts = compute_counts([Q2a; Q2b], [4 4]);
+end
+
+eclass = bnet2.equiv_class;
+CPDQ1=struct(bnet2.CPD{eclass(Q1,2)});
+CPDQ2=struct(bnet2.CPD{eclass(Q2,2)});
+CPDQ3=struct(bnet2.CPD{eclass(Q3,2)});
+CPDF2=struct(bnet2.CPD{eclass(F2,1)});
+CPDF3=struct(bnet2.CPD{eclass(F3,1)});
+
+
+A=add_hhmm_end_state(CPDQ2.transprob, CPDF2.termprob(:,:,2));
+squeeze(A(:,1,:));
+CPDQ2.startprob;
+ 
+if 0
+S=struct(CPDF2.sub_CPD_term);
+S.nsamples
+reshape(S.counts, [2 4 2])
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_discrete.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_discrete.m
new file mode 100644
index 00000000..3110ae5e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_discrete.m
@@ -0,0 +1,171 @@
+% Try to learn a 3 level HHMM similar to mk_square_hhmm
+% from synthetic discrete sequences
+
+
+discrete_obs = 1;
+supervised = 0;
+obs_finalF2 = 0;
+
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+bnet_init = mk_square_hhmm(discrete_obs, 0);
+
+ss = 6;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+
+if supervised
+  bnet_init.observed = [Q1 Q2 Onode];
+else
+  bnet_init.observed = [Onode];
+end
+
+if obs_finalF2
+  engine_init = jtree_dbn_inf_engine(bnet_init);
+  % can't use ndx version because sometimes F2 is hidden, sometimes observed
+  error('can''t observe F when learning')
+  % It is not possible to observe F2 if we learn
+  % because the update_ess method for hhmmF_CPD and hhmmQ_CPD assume
+  % the F nodes are always hidden (for speed).
+  % However, for generating, we might want to set the final F2=true
+  % to force all subroutines to finish.
+else
+  if supervised
+    engine_init = jtree_ndx_dbn_inf_engine(bnet_init);
+  else
+    engine_init = hmm_inf_engine(bnet_init);
+  end
+end
+  
+% generate some synthetic data (easier to debug)
+chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+L=find(chars=='L'); l=find(chars=='l');
+U=find(chars=='U'); u=find(chars=='u');
+R=find(chars=='R'); r=find(chars=='r');
+D=find(chars=='D'); d=find(chars=='d');
+
+cases = {};
+
+T = 8;
+ev = cell(ss, T);
+ev(Onode,:) = num2cell([L l U u R r D d]);
+if supervised
+  ev(Q1,:) = num2cell(1*ones(1,T));
+  ev(Q2,:) = num2cell( [1 1 2 2 3 3 4 4]);
+end
+cases{1} = ev;
+cases{3} = ev;
+
+T  = 8;
+ev = cell(ss, T);
+%we start with R then r, even though we are running the model 'backwards'!
+ev(Onode,:) = num2cell([R r U u L l D d]);
+
+if supervised
+  ev(Q1,:) = num2cell(2*ones(1,T));
+  ev(Q2,:) = num2cell( [3 3 2 2 1 1 4 4]);
+end
+
+cases{2} = ev;
+cases{4} = ev;
+
+if obs_finalF2
+  for i=1:length(cases)
+    T = size(cases{i},2);
+    cases{i}(F2,T)={2}; % force F2 to be finished at end of seq
+  end
+end
+
+
+% startprob should be shared for t=1:T,
+% but in the DBN it is shared for t=2:T,
+% so we train using a single long sequence.
+long_seq = cat(2, cases{:});
+[bnet_learned, LL, engine_learned] = ...
+    learn_params_dbn_em(engine_init, {long_seq}, 'max_iter', 200);
+
+% figure out which subsequence each model is responsible for
+mpe = calc_mpe_dbn(engine_learned, long_seq);
+pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, chars);
+
+
+% The "true" segmentation of the training sequence  is
+% Q1: 1                 2
+% O:  L l U u R r D d | R r U u L l D d | etc.
+% 
+% When we learn in a supervised fashion, we recover the "truth".
+
+% When we learn in an unsupervised fashion with seed=1, we get
+% Q1: 2                       1
+% O:  L l U u R r D d  R r | U u L l D d | etc.
+%
+% This means for model 1:
+% starts in state 2
+% transitions 2->1, 1->4, 4->e, 3->2
+%
+% For model 2,
+% starts in state 1
+% transitions 1->2, 2->3, 3->4 or e, 4->3
+
+% examine the params
+eclass = bnet_learned.equiv_class;
+CPDQ1=struct(bnet_learned.CPD{eclass(Q1,2)});
+CPDQ2=struct(bnet_learned.CPD{eclass(Q2,2)});
+CPDQ3=struct(bnet_learned.CPD{eclass(Q3,2)});
+CPDF2=struct(bnet_learned.CPD{eclass(F2,1)});
+CPDF3=struct(bnet_learned.CPD{eclass(F3,1)});
+CPDO=struct(bnet_learned.CPD{eclass(Onode,1)});
+
+A_learned =add_hhmm_end_state(CPDQ2.transprob, CPDF2.termprob(:,:,2));
+squeeze(A_learned(:,1,:))
+squeeze(A_learned(:,2,:))
+
+
+% Does the "true" model have higher likelihood than the learned one?
+% i.e., Does the unsupervised method learn the wrong model because
+% we have the wrong cost fn, or because of local minima?
+
+bnet_true = mk_square_hhmm(discrete_obs,1);
+
+% examine the params
+eclass = bnet_learned.equiv_class;
+CPDQ1_true=struct(bnet_true.CPD{eclass(Q1,2)});
+CPDQ2_true=struct(bnet_true.CPD{eclass(Q2,2)});
+CPDQ3_true=struct(bnet_true.CPD{eclass(Q3,2)});
+CPDF2_true=struct(bnet_true.CPD{eclass(F2,1)});
+CPDF3_true=struct(bnet_true.CPD{eclass(F3,1)});
+
+A_true =add_hhmm_end_state(CPDQ2_true.transprob, CPDF2_true.termprob(:,:,2));
+squeeze(A_true(:,1,:))
+
+
+if supervised
+  engine_true = jtree_ndx_dbn_inf_engine(bnet_true);
+else
+  engine_true = hmm_inf_engine(bnet_true);
+end
+
+%[engine_learned, ll_learned] = enter_evidence(engine_learned, long_seq);
+%[engine_true, ll_true] = enter_evidence(engine_true, long_seq);
+[engine_learned, ll_learned] = enter_evidence(engine_learned, cases{2});
+[engine_true, ll_true] = enter_evidence(engine_true, cases{2});
+ll_learned
+ll_true
+
+
+% remove concatentation artefacts
+ll_learned = 0;
+ll_true = 0;
+for m=1:length(cases)
+  [engine_learned, ll_learned_tmp] = enter_evidence(engine_learned, cases{m});
+  [engine_true, ll_true_tmp] = enter_evidence(engine_true, cases{m});
+  ll_learned = ll_learned + ll_learned_tmp;
+  ll_true = ll_true + ll_true_tmp;
+end
+ll_learned
+ll_true
+
+% In both cases, ll_learned >> ll_true
+% which shows we are using the wrong cost function!
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/mk_square_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/mk_square_hhmm.m
new file mode 100644
index 00000000..41cfc539
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/mk_square_hhmm.m
@@ -0,0 +1,180 @@
+function bnet = mk_square_hhmm(discrete_obs, true_params, topright)
+
+% Make a 3 level  HHMM described by the following grammar
+%
+% Square -> CLK | CCK % clockwise or counterclockwise
+% CLK -> LR UD RL DU start on top left (1 2 3 4)
+% CCK -> RL UD LR DU  if start at top right (3 2 1 4)
+% CCK -> UD LR DU RL if start at top left (2 1 4 3)
+%
+% LR = left-right, UD = up-down, RL = right-left, DU = down-up
+% LR, UD, RL, DU are sub HMMs.
+%
+% For discrete observations, the subHMMs are 2-state left-right.
+% LR emits L then l, etc.
+%
+% For cts observations, the subHMMs are 1 state.
+% LR emits a vector in the -> direction, with a little noise.
+% Since there is no constraint that we remain in the LR state as long as the RL state,
+% the sides of the square might have different lengths,
+% so the result is not really a square!
+%
+% If true_params = 0, we use random parameters at the top 2 levels
+% (ready for learning). At the bottom level, we use noisy versions
+% of the "true" observations.
+%
+% If topright=1, counter-clockwise starts at top right, not top left
+% This example was inspired by Ivanov and Bobick.
+
+if nargin < 3, topright = 1; end
+
+if 1 % discrete_obs
+  Qsizes = [2 4 2];
+else
+  Qsizes = [2 4 1];
+end
+
+D = 3;
+Qnodes = 1:D;
+startprob = cell(1,D);
+transprob = cell(1,D);
+termprob = cell(1,D);
+
+% LEVEL 1
+
+startprob{1} = 'unif';
+transprob{1} = 'unif';
+
+% LEVEL 2
+
+if true_params
+  startprob{2} = zeros(2, 4);
+  startprob{2}(1, :) = [1 0 0 0];
+  if topright
+    startprob{2}(2, :) = [0 0 1 0];
+  else
+    startprob{2}(2, :) = [0 1 0 0];
+  end
+  
+  transprob{2} = zeros(4, 2, 4);
+  
+  transprob{2}(:,1,:) = [0 1 0 0
+		    0 0 1 0
+		    0 0 0 1
+		    0 0 0 1]; % 4->e
+  if topright
+    transprob{2}(:,2,:) = [0 0 0 1
+		    1 0 0 0
+		    0 1 0 0
+		    0 0 0 1]; % 4->e
+  else
+    transprob{2}(:,2,:) = [0 0 0 1
+		    1 0 0 0
+		    0 0 1 0 % 3->e
+		    0 0 1 0];
+  end
+  
+  %termprob{2} = 'rightstop';
+  termprob{2} = zeros(2,4);
+  pfin = 0.8;
+  termprob{2}(1,:) = [0 0 0 pfin]; % finish in state 4 (DU)
+  if topright
+    termprob{2}(2,:) = [0 0 0 pfin];
+  else
+    termprob{2}(2,:) = [0 0 pfin 0];  % finish in state 3 (RL)
+  end
+else
+  % In the unsupervised case, it is essential that we break symmetry
+  % in the initial param estimates.
+  %startprob{2} = 'unif';
+  %transprob{2} = 'unif';
+  %termprob{2} = 'unif';
+  startprob{2} = 'rnd';
+  transprob{2} = 'rnd';
+  termprob{2} = 'rnd';
+end
+
+% LEVEL 3
+
+if 1 |  true_params
+  startprob{3} = 'leftstart';
+  transprob{3}  = 'leftright';
+  termprob{3} = 'rightstop';
+else
+  % If we want to be able to run a base-level model backwards...
+  startprob{3} = 'rnd';
+  transprob{3}  = 'rnd';
+  termprob{3} = 'rnd';
+end
+ 
+
+% OBS LEVEl
+
+if discrete_obs
+  % Initialise observations of lowest level primitives in a way which we can interpret
+  chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+  L=find(chars=='L'); l=find(chars=='l');
+  U=find(chars=='U'); u=find(chars=='u');
+  R=find(chars=='R'); r=find(chars=='r');
+  D=find(chars=='D'); d=find(chars=='d');
+  Osize = length(chars);
+  
+  if true_params
+    p = 1; % makes each state fully observed
+  else
+    p = 0.9;
+  end
+  
+  obsprob = (1-p)*ones([4 2 Osize]);
+  %       Q2 Q3 O
+  obsprob(1, 1, L) =  p;
+  obsprob(1, 2, l) =  p;
+  obsprob(2, 1, U) =  p;
+  obsprob(2, 2, u) =  p;
+  obsprob(3, 1, R) =  p;
+  obsprob(3, 2, r) =  p;
+  obsprob(4, 1, D) =  p;
+  obsprob(4, 2, d) =  p;
+  obsprob = mk_stochastic(obsprob);
+  Oargs = {'CPT', obsprob};
+else
+  % Initialise means of lowest level primitives in a way which we can interpret
+  % These means are little vectors in the east, south, west, north directions.
+  % (left-right=east, up-down=south, right-left=west, down-up=north)
+  Osize = 2;
+  mu = zeros(2, Qsizes(2), Qsizes(3));
+  scale = 3;
+  if true_params
+    noise = 0;
+  else
+    noise = 0.5*scale;
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 1, q3) = scale*[1;0] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 2, q3) = scale*[0;-1] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 3, q3) = scale*[-1;0] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 4, q3) = scale*[0;1] + noise*rand(2,1);
+  end
+  Sigma = repmat(reshape(scale*eye(2), [2 2 1 1 ]), [1 1 Qsizes(2) Qsizes(3)]);
+  Oargs = {'mean', mu, 'cov', Sigma, 'cov_type', 'diag'};
+end
+
+if discrete_obs
+  selfprob = 0.5;
+else
+  selfprob = 0.95;
+  % If less than this, it won't look like a square
+  % because it doesn't spend enough time in each state
+  % Unfortunately, the variance on durations (lengths of each side)
+  % is very large
+end
+bnet = mk_hhmm('Qsizes', Qsizes, 'Osize', Osize', 'discrete_obs', discrete_obs, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(2:3), 'selfprob', selfprob, ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/plot_square_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/plot_square_hhmm.m
new file mode 100644
index 00000000..e61e5669
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/plot_square_hhmm.m
@@ -0,0 +1,27 @@
+function plot_square_hhmm(ev)
+% Plot the square shape implicit in the evidence.
+% ev{i,t} is the value of node i in slice t.
+% The observed node contains a velocity (delta increment), which is converted
+% into a position.
+% The Q2 node specifies which model is used, and hence which color
+% to use: 1=red, 2=green, 3=blue, 4=black.
+
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+
+delta = cell2num(ev(Onode,:)); % delta(:,t)
+Q2label = cell2num(ev(Q2,:)); 
+
+T = size(delta, 2);
+pos = zeros(2,T+1);
+hold on
+cols = {'r', 'g', 'b', 'k'};
+for t=2:T+1
+  pos(:,t) = pos(:,t-1) + delta(:,t-1);
+  plot(pos(1,t), pos(2,t), sprintf('%c.', cols{Q2label(t-1)}));
+  if (t==2)
+    text(pos(1,t-1),pos(2,t-1),sprintf('%d',t))
+  elseif (mod(t,20)==0)
+    text(pos(1,t),pos(2,t),sprintf('%d',t))
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_cts.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_cts.m
new file mode 100644
index 00000000..3ab2abb5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_cts.m
@@ -0,0 +1,20 @@
+% Generate samples from the HHMM with the true params.
+
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+discrete_obs = 0;
+
+bnet = mk_square_hhmm(discrete_obs, 1);
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+
+for seqi=1:1
+  evidence = sample_dbn(bnet, 'stop_test', 'is_F2_true_D3');      
+  clf
+  plot_square_hhmm(evidence);
+  %pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, Onode, []);
+  fprintf('sequence %d has length %d; press key to continue\n', seqi, size(evidence,2))
+  pause
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_discrete.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_discrete.m
new file mode 100644
index 00000000..20279899
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_discrete.m
@@ -0,0 +1,20 @@
+% Generate samples from the HHMM with the true params.
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+discrete_obs = 1;
+
+bnet = mk_square_hhmm(discrete_obs, 1);
+
+Tmax = 30;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+  
+for seqi=1:3
+  evidence = cell2num(sample_dbn(bnet, 'stop_test', 'is_F2_true_D3'));
+  T = size(evidence, 2)
+  pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, Onode, chars);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4.mat b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4.mat
new file mode 100644
index 00000000..cda0585b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4.mat
Binary files differdiff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4_cases.mat b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4_cases.mat
new file mode 100644
index 00000000..788c3239
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4_cases.mat
Binary files differdiff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.m
new file mode 100644
index 00000000..e983af14
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.m
@@ -0,0 +1,1310 @@
+function fig = test_square_fig()
+% This is the machine-generated representation of a Handle Graphics object
+% and its children.  Note that handle values may change when these objects
+% are re-created. This may cause problems with any callbacks written to
+% depend on the value of the handle at the time the object was saved.
+%
+% To reopen this object, just type the name of the M-file at the MATLAB
+% prompt. The M-file and its associated MAT-file must be on your path.
+
+load test_square_fig
+
+h0 = figure('Color',[0.8 0.8 0.8], ...
+	'Colormap',mat0, ...
+	'PointerShapeCData',mat1, ...
+	'Position',[540 374 476 292]);
+h1 = axes('Parent',h0, ...
+	'CameraUpVector',[0 1 0], ...
+	'Color',[1 1 1], ...
+	'ColorOrder',mat2, ...
+	'NextPlot','add', ...
+	'Position',[0.13 0.11 0.3270231213872832 0.8149999999999998], ...
+	'XColor',[0 0 0], ...
+	'XLim',[-10 50], ...
+	'XLimMode','manual', ...
+	'YColor',[0 0 0], ...
+	'YLim',[-60 10], ...
+	'YLimMode','manual', ...
+	'ZColor',[0 0 0]);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',0.4608294930875587, ...
+	'YData',0.2923976608187218);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'String','2');
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',1.152073732718893, ...
+	'YData',0.2923976608187218);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',2.995391705069125, ...
+	'YData',0.8771929824561511);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',3.686635944700463, ...
+	'YData',0.8771929824561511);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',6.451612903225808, ...
+	'YData',0.8771929824561511);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',9.677419354838712, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',10.36866359447005, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',15.43778801843318, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',17.51152073732719, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',19.81566820276498, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',20.50691244239631, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',23.73271889400922, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',25.57603686635945, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',29.95391705069125, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',31.79723502304147, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',35.02304147465438, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',35.71428571428572, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',38.47926267281106, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',40.3225806451613, ...
+	'YData',1.461988304093566);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[40.3225806451613 1.461988304093566 0], ...
+	'String','20');
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',42.62672811059908, ...
+	'YData',mat3);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',43.31797235023042, ...
+	'YData',mat4);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',43.31797235023042, ...
+	'YData',0.8771929824561511);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',43.54838709677419, ...
+	'YData',0);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',43.77880184331798, ...
+	'YData',-0.5847953216374293);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',44.47004608294931, ...
+	'YData',-2.339181286549703);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',44.93087557603687, ...
+	'YData',-4.385964912280699);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',46.7741935483871, ...
+	'YData',-9.064327485380119);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.00460829493088, ...
+	'YData',-10.81871345029239);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.69585253456221, ...
+	'YData',mat5);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.69585253456221, ...
+	'YData',-15.20467836257309);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-19.00584795321637);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-19.88304093567251);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-22.51461988304093);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-23.09941520467836);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-26.02339181286549);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-26.31578947368421);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-27.77777777777777);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-28.3625730994152);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-30.99415204678362);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[47.23502304147466 -30.99415204678362 0], ...
+	'String','40');
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.46543778801843, ...
+	'YData',-31.57894736842105);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.46543778801843, ...
+	'YData',-33.62573099415204);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.46543778801843, ...
+	'YData',-34.50292397660818);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.46543778801843, ...
+	'YData',-37.42690058479531);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.46543778801843, ...
+	'YData',-38.01169590643274);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.00460829493088, ...
+	'YData',-42.39766081871344);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.00460829493088, ...
+	'YData',-42.98245614035087);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.00460829493088, ...
+	'YData',-46.49122807017543);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',46.7741935483871, ...
+	'YData',-46.78362573099415);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',46.54377880184332, ...
+	'YData',-49.41520467836257);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',46.54377880184332, ...
+	'YData',-49.70760233918128);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',45.85253456221199, ...
+	'YData',-51.46198830409356);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',45.85253456221199, ...
+	'YData',-51.75438596491227);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',44.93087557603687, ...
+	'YData',-53.21637426900584);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',44.70046082949308, ...
+	'YData',-53.21637426900584);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',44.00921658986175, ...
+	'YData',-54.09356725146198);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',43.77880184331798, ...
+	'YData',-54.38596491228069);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',41.93548387096774, ...
+	'YData',-54.97076023391811);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',41.47465437788019, ...
+	'YData',-55.26315789473683);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',39.1705069124424, ...
+	'YData',-55.55555555555554);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[39.1705069124424 -55.55555555555554 0], ...
+	'String','60');
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',38.94009216589862, ...
+	'YData',-55.84795321637426);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',36.63594470046083, ...
+	'YData',-55.55555555555554);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',36.17511520737327, ...
+	'YData',-55.55555555555554);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',32.94930875576037, ...
+	'YData',-54.97076023391811);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',32.48847926267281, ...
+	'YData',-54.97076023391811);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',28.11059907834102, ...
+	'YData',-53.80116959064326);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',27.64976958525346, ...
+	'YData',-53.50877192982455);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',23.963133640553, ...
+	'YData',-53.50877192982455);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',23.27188940092166, ...
+	'YData',-53.50877192982455);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',19.5852534562212, ...
+	'YData',-54.97076023391811);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',19.12442396313364, ...
+	'YData',-54.97076023391811);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',mat6, ...
+	'YData',-56.14035087719297);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',mat7, ...
+	'YData',-56.14035087719297);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',9.907834101382491, ...
+	'YData',-57.30994152046782);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',9.447004608294932, ...
+	'YData',-57.30994152046782);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',6.221198156682029, ...
+	'YData',-57.30994152046782);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',4.838709677419356, ...
+	'YData',-56.7251461988304);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',2.764976958525345, ...
+	'YData',-56.14035087719297);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',2.534562211981569, ...
+	'YData',-56.14035087719297);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',0.9216589861751174, ...
+	'YData',-53.80116959064327);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[0.9216589861751174 -53.80116959064327 0], ...
+	'String','80');
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',0.6912442396313381, ...
+	'YData',-53.21637426900584);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.152073732718893, ...
+	'YData',-48.24561403508771);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.152073732718893, ...
+	'YData',-47.953216374269);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.843317972350228, ...
+	'YData',-44.73684210526315);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.843317972350228, ...
+	'YData',-44.44444444444444);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-2.304147465437787, ...
+	'YData',-39.76608187134502);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-2.764976958525345, ...
+	'YData',-38.01169590643274);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-3.225806451612904, ...
+	'YData',-30.99415204678362);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-3.225806451612904, ...
+	'YData',-29.82456140350877);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-3.225806451612904, ...
+	'YData',-24.85380116959064);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-3.225806451612904, ...
+	'YData',-24.26900584795321);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-2.534562211981566, ...
+	'YData',-17.5438596491228);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-2.304147465437787, ...
+	'YData',-16.95906432748537);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.612903225806452, ...
+	'YData',-11.98830409356725);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.612903225806452, ...
+	'YData',-11.40350877192982);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',mat8, ...
+	'YData',-8.47953216374269);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',mat9, ...
+	'YData',-8.187134502923968);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.152073732718893, ...
+	'YData',-5.263157894736835);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.152073732718893, ...
+	'YData',-4.970760233918128);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.9216589861751139, ...
+	'YData',-2.923976608187132);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[-0.9216589861751139 -2.923976608187132 0], ...
+	'String','100');
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.9216589861751139, ...
+	'YData',-2.631578947368411);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.6912442396313345, ...
+	'YData',mat10);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.6912442396313345, ...
+	'YData',-0.8771929824561369);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.6912442396313345, ...
+	'YData',-0.5847953216374293);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'HandleVisibility','off', ...
+	'HorizontalAlignment','center', ...
+	'Position',[19.80645161290322 12.0675105485232 17.32050807568877], ...
+	'VerticalAlignment','bottom');
+set(get(h2,'Parent'),'Title',h2);
+h1 = axes('Parent',h0, ...
+	'CameraUpVector',[0 1 0], ...
+	'Color',[1 1 1], ...
+	'ColorOrder',mat11, ...
+	'NextPlot','add', ...
+	'Position',[0.5779768786127169 0.11 0.3270231213872832 0.8149999999999998], ...
+	'XColor',[0 0 0], ...
+	'YColor',[0 0 0], ...
+	'ZColor',[0 0 0]);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.4608294930875587, ...
+	'YData',0);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'String','2');
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-2.764976958525345, ...
+	'YData',-0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-3.456221198156683, ...
+	'YData',-0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-7.834101382488477, ...
+	'YData',-0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-11.52073732718894, ...
+	'YData',-0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',mat12, ...
+	'YData',-0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-19.35483870967742, ...
+	'YData',0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-23.50230414746544, ...
+	'YData',0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-24.88479262672811, ...
+	'YData',0.8771929824561369);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-28.11059907834102, ...
+	'YData',0.8771929824561369);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-29.49308755760369, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-31.10599078341014, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-32.02764976958525, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-33.17972350230414, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-33.6405529953917, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-34.7926267281106, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-35.02304147465438, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-35.48387096774194, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-35.71428571428572, ...
+	'YData',1.461988304093566);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[-35.71428571428572 1.461988304093566 0], ...
+	'String','20');
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.17511520737327, ...
+	'YData',mat13);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',0.8771929824561369);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.63594470046083, ...
+	'YData',0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.63594470046083, ...
+	'YData',0);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.63594470046083, ...
+	'YData',mat14);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',-2.339181286549703);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',-2.631578947368425);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',-4.67836257309942);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',-5.555555555555557);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',-8.187134502923982);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',-8.771929824561397);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.86635944700461, ...
+	'YData',-13.15789473684211);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',mat15);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-16.08187134502924);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-17.54385964912281);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-18.12865497076023);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-19.88304093567251);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-20.17543859649123);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-21.92982456140351);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-22.22222222222222);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[-37.09677419354839 -22.22222222222222 0], ...
+	'String','40');
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-23.09941520467836);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-23.39181286549707);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-25.14619883040935);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-25.43859649122807);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-28.3625730994152);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.55760368663595, ...
+	'YData',-28.94736842105263);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-31.87134502923976);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-32.16374269005848);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-34.7953216374269);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-35.38011695906432);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-38.88888888888889);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-39.76608187134503);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-43.27485380116958);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-43.5672514619883);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-44.44444444444444);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.55760368663595, ...
+	'YData',-45.32163742690058);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.55760368663595, ...
+	'YData',-45.61403508771929);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-47.36842105263158);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-47.95321637426901);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.86635944700461, ...
+	'YData',-49.70760233918129);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[-36.86635944700461 -49.70760233918129 0], ...
+	'String','60');
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.86635944700461, ...
+	'YData',-50);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-35.71428571428572, ...
+	'YData',-50.29239766081872);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-35.25345622119816, ...
+	'YData',-50.29239766081872);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-32.02764976958527, ...
+	'YData',-50.29239766081872);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-31.33640552995393, ...
+	'YData',-50.29239766081872);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-27.88018433179725, ...
+	'YData',-50.58479532163743);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-27.41935483870969, ...
+	'YData',-50.58479532163743);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-18.20276497695854, ...
+	'YData',-50.58479532163743);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-16.82027649769586, ...
+	'YData',-51.16959064327486);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-12.21198156682029, ...
+	'YData',-50.58479532163743);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-11.52073732718895, ...
+	'YData',-50.58479532163743);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-6.912442396313377, ...
+	'YData',-51.16959064327486);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-5.069124423963142, ...
+	'YData',-51.75438596491229);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',mat16, ...
+	'YData',-52.046783625731);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.9216589861751281, ...
+	'YData',-52.33918128654972);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',0.2304147465437687, ...
+	'YData',-52.33918128654972);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',0.4608294930875481, ...
+	'YData',-52.33918128654972);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',2.304147465437776, ...
+	'YData',-52.63157894736843);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',2.534562211981548, ...
+	'YData',-52.63157894736843);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',3.917050691244224, ...
+	'YData',-52.63157894736843);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[3.917050691244224 -52.63157894736843 0], ...
+	'String','80');
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',4.147465437788011, ...
+	'YData',-52.63157894736843);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',4.147465437788011, ...
+	'YData',-52.33918128654972);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.529953917050673, ...
+	'YData',-46.19883040935674);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.990783410138231, ...
+	'YData',-44.44444444444446);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',7.834101382488466, ...
+	'YData',-28.0701754385965);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',8.294930875576025, ...
+	'YData',-22.80701754385966);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',8.755760368663584, ...
+	'YData',mat17);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',8.525345622119797, ...
+	'YData',-14.9122807017544);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',7.373271889400908, ...
+	'YData',-10.23391812865498);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',7.142857142857135, ...
+	'YData',-9.94152046783627);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',6.221198156682018, ...
+	'YData',-7.602339181286567);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',6.221198156682018, ...
+	'YData',-7.309941520467845);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.760368663594459, ...
+	'YData',-5.555555555555571);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.529953917050673, ...
+	'YData',-5.555555555555571);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.2995391705069, ...
+	'YData',-4.093567251462005);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.069124423963128, ...
+	'YData',-2.631578947368439);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.069124423963128, ...
+	'YData',-2.339181286549717);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.069124423963128, ...
+	'YData',mat18);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.069124423963128, ...
+	'YData',-1.169590643274873);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',4.838709677419342, ...
+	'YData',-0.2923976608187218);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[4.838709677419342 -0.2923976608187218 0], ...
+	'String','100');
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'HandleVisibility','off', ...
+	'HorizontalAlignment','center', ...
+	'Position',[-10.38961038961038 12.0675105485232 17.32050807568877], ...
+	'VerticalAlignment','bottom');
+set(get(h2,'Parent'),'Title',h2);
+if nargout > 0, fig = h0; end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.mat b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.mat
new file mode 100644
index 00000000..5b2b5f53
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.mat
Binary files differdiff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/abcd_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/abcd_hhmm.m
new file mode 100644
index 00000000..13e6d39f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/abcd_hhmm.m
@@ -0,0 +1,97 @@
+% Make the HHMM in Figure 1 of the NIPS'01 paper
+
+Qsize = [2 3 2];
+Qnodes = 1:3;
+D = 3;
+transprob = cell(1,D);
+termprob = cell(1,D);
+startprob = cell(1,D);
+clear A;
+
+% transprob{d}(i,k,j), transprob{1}(i,j)
+% termprob{d}(k,j), termprob{1}(1,j)
+% startprob{d}(k,j), startprob{1}(1,j)
+
+
+% LEVEL 1
+
+%       1 2 e
+A{1} = [0 0 1;
+	0 0 1];
+[transprob{1}, termprob{1}] = remove_hhmm_end_state(A{1});
+startprob{1} = [0.5 0.5];
+
+% LEVEL 2
+A{2} = zeros(Qsize(2), Qsize(1), Qsize(2)+1);
+
+%              1 2 3 e
+A{2}(:,1,:) = [0 1 0 0  % Q1=1 => model below state 0
+	       0 0 1 0
+	       0 0 0 1];
+
+%              1 2 3 e
+A{2}(:,2,:) = [0 1 0 0 % Q1=2 => model below state 1
+	       0 0 1 0
+	       0 0 0 1];
+
+[transprob{2}, termprob{2}] = remove_hhmm_end_state(A{2});	       
+
+% always enter level 2 in state 1
+startprob{2} = [1 0 0
+		1 0 0];
+
+% LEVEL 3
+
+A{3} = zeros([Qsize(3) Qsize(2) Qsize(3)+1]);
+endstate = Qsize(3)+1;
+%    Qt-1(3) Qt(2) Qt(3)
+%                        1   2   e
+A{3}(1,      1,    endstate) = 1.0; % Q2=1 => model below state 2/5
+A{3}(:,      2,    :) = [0.0 1.0 0.0 % Q2=2 => model below state 3/6
+            	         0.5 0.0 0.5]; 
+A{3}(1,      3,    endstate) = 1.0; % Q2=3 => model below state 4/7
+
+[transprob{3}, termprob{3}] = remove_hhmm_end_state(A{3});	       
+
+startprob{3} = 'leftstart';
+
+
+
+% OBS LEVEl
+
+chars = ['a', 'b', 'c', 'd', 'x', 'y'];
+Osize = length(chars);
+
+obsprob = zeros([Qsize Osize]);
+%       1 2 3 O
+obsprob(1,1,1,find(chars == 'a')) =  1.0;
+
+obsprob(1,2,1,find(chars == 'x')) =  1.0;
+obsprob(1,2,2,find(chars == 'y')) =  1.0;
+
+obsprob(1,3,1,find(chars == 'b')) =  1.0;
+
+obsprob(2,1,1,find(chars == 'c')) =  1.0;
+
+obsprob(2,2,1,find(chars == 'x')) =  1.0;
+obsprob(2,2,2,find(chars == 'y')) =  1.0;
+
+obsprob(2,3,1,find(chars == 'd')) =  1.0;
+
+Oargs = {'CPT', obsprob};
+
+bnet = mk_hhmm('Qsizes', Qsize, 'Osize', Osize, 'discrete_obs', 1, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(1:3), ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
+
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+
+for seqi=1:3
+  evidence = sample_dbn(bnet, 'stop_test', 'is_F2_true_D3');      
+  ev = cell2num(evidence);
+  chars(ev(end,:))
+  %T = size(evidence, 2)
+  %pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, Onode, chars);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/add_hhmm_end_state.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/add_hhmm_end_state.m
new file mode 100644
index 00000000..84c3c653
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/add_hhmm_end_state.m
@@ -0,0 +1,34 @@
+function A = add_hhmm_end_state(transprob, termprob)
+% ADD_HMM_END_STATE Combine trans and term probs into transmat for automaton with an end state
+% function A = add_hhmm_end_state(transprob, termprob)
+%
+% A(i,k,j) = Pr( i->j | Qps=k), where i in 1:Q, j in 1:(Q+1), and Q+1 is the end state
+% This implements the equation in sec 4.6 of my tech report, where
+% transprob(i,k,j) = \tilde{A}_k(i,j), termprob(k,j) = \tau_k(j)
+%
+% For the top level, the k index is missing.
+
+Q = size(transprob,1);
+toplevel = (ndims(transprob)==2);
+if toplevel
+  Qk = 1;
+  transprob = reshape(transprob, [Q 1 Q]);
+  termprob = reshape(termprob, [1 Q]);
+else
+  Qk = size(transprob, 2);
+end
+
+A = zeros(Q, Qk, Q+1);
+A(:,:,Q+1) = termprob';
+
+for k=1:Qk
+  for i=1:Q
+    for j=1:Q
+      A(i,k,j) = transprob(i,k,j) * (1-termprob(k,i));
+    end
+  end    
+end
+
+if toplevel
+  A = squeeze(A);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/hhmm_jtree_clqs.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/hhmm_jtree_clqs.m
new file mode 100644
index 00000000..4192af11
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/hhmm_jtree_clqs.m
@@ -0,0 +1,143 @@
+% Find out how big the cliques are in an HHMM as a function of depth
+% (This is how we get the complexity bound of O(D K^{1.5D}).)
+
+if 0
+Qsize = [];
+Fsize = [];
+Nclqs = [];
+end
+
+ds = 1:15;
+
+for d = ds
+  allQ = 1;
+  [intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo(d, allQ);
+  
+  N = length(intra);
+  ns = 2*ones(1,N);
+  
+  bnet = mk_dbn(intra, inter, ns);
+  for i=1:N
+    bnet.CPD{i} = tabular_CPD(bnet, i);
+  end
+  
+  if 0
+    T = 5;
+    dag = unroll_dbn_topology(intra, inter, T);
+    engine = jtree_unrolled_dbn_inf_engine(bnet, T, 'constrained', 1);
+    S = struct(engine);
+    S1 = struct(S.sub_engine);
+  end
+  
+  engine = jtree_dbn_inf_engine(bnet);
+  S = struct(engine);
+  J = S.jtree_struct;
+  
+  ss = 2*d+1;
+  Qnodes2 = Qnodes + ss;
+  QQnodes = [Qnodes Qnodes2];
+  
+  % find out how many Q nodes in each clique, and how many F nodes
+  C = length(J.cliques);
+  Nclqs(d) = 0;
+  for c=1:C
+    Qsize(c,d) = length(myintersect(J.cliques{c}, QQnodes));
+    Fsize(c,d) = length(myintersect(J.cliques{c}, Fnodes));
+    if length(J.cliques{c}) > 1 % exclude observed leaves
+      Nclqs(d) = Nclqs(d) + 1;
+    end
+  end
+  %pred_max_Qsize(d) = ceil(d+(d+1)/2);
+  pred_max_Qsize(d) = ceil(1.5*d);
+  
+  fprintf('d=%d\n', d);
+  %fprintf('D=%d, max F = %d. max Q = %d, pred max Q = %d\n', ...
+	%  D, max(Fsize), max(Qsize), ceil(D+(D+1)/2));
+	     
+  %histc(Qsize,1:max(Qsize)) % how many of each size?
+end % next d
+
+
+Q = 2;
+pred_mass = ds.*(Q.^ds) + Q.^(ceil(1.5 * ds))
+pred_mass2 = Q.^(ceil(1.5 * ds))
+
+for d=ds
+  mass(d) = 0;
+  for c=1:C
+    mass(d) = mass(d) + Q^Qsize(c,d);
+  end
+end
+    
+
+if 0
+%plot(ds, max(Qsize), 'o-',  ds, pred_max_Qsize, '*--');
+%plot(ds, max(Qsize), 'o-',  ds, 1.5*ds, '*--');
+%plot(ds, mass, 'o-',  ds, pred_mass, '*--');
+D = 15;
+%plot(ds(1:D), mass(1:D), 'bo-',  ds(1:D), pred_mass(1:D), 'g*--', ds(1:D), pred_mass2(1:D), 'k+-.');
+plot(ds(1:D), log(mass(1:D)), 'bo-',  ds(1:D), log(pred_mass(1:D)), 'g*--', ds(1:D), log(pred_mass2(1:D)), 'k+-.');
+
+grid on
+xlabel('depth of hierarchy')
+title('max num Q nodes in any clique vs. depth')
+legend('actual', 'predicted')
+
+%previewfig(gcf, 'width', 3, 'height', 1.5, 'color', 'bw');
+%exportfig(gcf, '/home/cs/murphyk/WP/ConferencePapers/HHMM/clqsize2.eps', ...
+%          'width', 3, 'height', 1.5, 'color', 'bw');   
+
+end
+
+
+if 0
+for d=ds
+  effnumclqs(d) = length(find(Qsize(:,d)>0));
+end
+ds = 1:10;
+Qs = 2:10;
+maxC = size(Qsize, 1);
+cost = [];
+cost_bound = [];
+for qi=1:length(Qs)
+  Q = Qs(qi);
+  for d=ds
+    cost(d,qi) = 0;
+    for c=1:maxC
+      if length(Qsize(c,d) > 0) % this clique contains Q nodes
+	cost(d,qi) = cost(d,qi) + Q^Qsize(c,d)*2^Fsize(c,d);
+      end
+    end
+    %cost_bound(d,qi) = effnumclqs(d) * 8 * Q^(max(Qsize(:,d)));
+    cost_bound(d,qi) = (effnumclqs(d)*8) + Q^(max(Qsize(:,d)));
+  end
+end
+
+qi=2; plot(ds, cost(:,qi), 'o-',  ds, cost_bound(:,qi), '*--');
+end
+
+
+if 0
+% convert numbers in cliques into names
+for d=1:D
+  Fdecode(Fnodes(d)) = d;
+end
+for c=8:15
+  clqs = J.cliques{c};
+  fprintf('clique %d: ', c);
+  for k=clqs
+    if myismember(k, Qnodes)
+      fprintf('Q%d ', k)
+    elseif myismember(k, Fnodes)
+      fprintf('F%d ', Fdecode(k))
+    elseif isequal(k, Onode)
+      fprintf('O ')
+    elseif myismember(k, Qnodes2)
+      fprintf('Q%d* ', k-ss)
+    else
+      error(['unrecognized node ' k])
+    end
+  end
+  fprintf('\n');
+end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm.m
new file mode 100644
index 00000000..85ff7f6a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm.m
@@ -0,0 +1,258 @@
+function [bnet, Qnodes, Fnodes, Onode] = mk_hhmm(varargin)
+% MK_HHMM Make a Hierarchical HMM
+% function [bnet, Qnodes, Fnodes, Onode] = mk_hhmm(...)
+%
+% e.g. 3-layer hierarchical HMM where level 1 only connects to level 2
+% and the parents of the observed node are levels 2 and 3.
+% (This DBN is the same as Fig 10 in my tech report.)
+%
+%   Q1 ---------->   Q1
+%   |  \            ^ |
+%   |   v          /  |
+%   |    F2 ------/   |
+%   |   ^ ^        \  |
+%   |  /  |         \ |
+%   | /   |          ||
+%   v     |          vv
+%   Q2----| --------> Q2
+%  /| \   |          ^|
+% / |  v  |         / |
+% | |   F3 --------/  |
+% | |   ^          \  |
+% | v  /            v v
+% | Q3 ----------->  Q3
+% |  |    
+% \  | 
+%  v v    
+%   O
+%
+%
+% Optional arguments in name/value format [default value in brackets]
+%
+% Qsizes      - sizes at each level [ none ]
+% allQ       - 1 means level i connects to all Q levels below, 0 means just to i+1 [0]
+% transprob  - transprob{d}(i,k,j) = P(Q(d,t)=j|Q(d,t-1)=i,Q(1:d-1,t)=k)  ['leftright']
+% startprob  - startprob{d}(k,j) = P(Q(d,t)=j|Q(1:d-1,t)=k)  ['leftstart']
+% termprob   - termprob{d}(k,j) = P(F(d,t)=2|Q(1:d-1,t)=k,Q(d,t)=j) for d>1 ['rightstop']
+% selfprop   - prob of a self transition (termprob default = 1-selfprop) [0.8]
+% Osize       - size of O node
+% discrete_obs - 1 means O is tabular_CPD, 0 means gaussian_CPD [0]
+% Oargs       - cell array of args to pass to the O CPD  [ {} ]
+% Ops         - Q parents of O [Qnodes(end)]
+% F1          - 1 means level 1 can finish (restart), else there is no F1->Q1 arc [0]
+% clamp1     - 1 means we clamp the params of the Q nodes in slice 1 (Qt1params) [1]
+%   Note: the Qt1params are startprob, which should be shared with other slices.
+%   However, in the current implementation, the Qt1params will only be estimated
+%   from the initial state of each sequence.
+%
+% For d=1, startprob{1}(1,j) is only used in the first slice and
+% termprob{1} is ignored, since we assume the top level never resets.
+% Also, transprob{1}(i,j) can be used instead of transprob{1}(i,1,j).
+%
+% leftstart means the model always starts in state 1.
+% rightstop means the model can only finish in its last state (Qsize(d)).
+% unif means each state is equally like to reach any other
+% rnd means the transition/starting probs are random (drawn from rand)
+%
+% Q1:QD in slice 1 are of type tabular_CPD
+% Q1:QD in slice 2 are of type hhmmQ_CPD.
+% F(2:D-1) is of type hhmmF_CPD, FD is of type tabular_CPD.
+
+args = varargin;
+nargs = length(args);
+
+% get sizes of nodes and topology
+Qsizes = [];
+Osize = [];
+allQ = 0;
+Ops = [];
+F1 = 0;
+for i=1:2:nargs
+  switch args{i},
+   case 'Qsizes', Qsizes = args{i+1}; 
+   case 'Osize',  Osize = args{i+1}; 
+   case 'allQ',   allQ = args{i+1}; 
+   case 'Ops',    Ops = args{i+1}; 
+   case 'F1',     F1 = args{i+1}; 
+  end
+end
+if isempty(Qsizes), error('must specify Qsizes'); end
+if Osize==0, error('must specify Osize'); end
+D = length(Qsizes);
+Qnodes = 1:D;
+
+if isempty(Ops), Ops = Qnodes(end); end
+
+
+[intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo(D, allQ, Ops, F1);
+ss = length(intra);
+names = {};
+
+if F1
+  Fnodes_ndx = Fnodes;
+else
+  Fnodes_ndx = [-1 Fnodes]; % Fnodes(1) is a dummy index
+end
+		
+% set default params
+discrete_obs = 0;
+Oargs = {};
+startprob = cell(1,D);
+startprob{1} = 'unif';
+for d=2:D
+  startprob{d} = 'leftstart';
+end
+transprob = cell(1,D);
+transprob{1} = 'unif';
+for d=2:D
+  transprob{d} = 'leftright';
+end
+termprob = cell(1,D);
+for d=2:D
+  termprob{d} = 'rightstop';
+end
+selfprob = 0.8;
+clamp1 = 1;
+
+for i=1:2:nargs
+  switch args{i},
+   case 'discrete_obs', discrete_obs = args{i+1}; 
+   case 'Oargs',        Oargs = args{i+1};
+   case 'startprob',    startprob = args{i+1};
+   case 'transprob',    transprob = args{i+1};
+   case 'termprob',     termprob = args{i+1};
+   case 'selfprob',     selfprob = args{i+1};
+   case 'clamp1',       clamp1 = args{i+1};
+  end
+end
+
+ns = zeros(1,ss);
+ns(Qnodes) = Qsizes;
+ns(Onode) = Osize;
+ns(Fnodes) = 2;
+
+dnodes = [Qnodes Fnodes];
+if discrete_obs
+  dnodes = [dnodes Onode];
+end
+onodes = [Onode];
+
+bnet = mk_dbn(intra, inter, ns, 'observed', onodes, 'discrete', dnodes, 'names', names);
+eclass = bnet.equiv_class;
+
+for d=1:D
+  if d==1
+    Qps = [];
+  elseif allQ
+    Qps = Qnodes(1:d-1);
+  else
+    Qps = Qnodes(d-1);
+  end
+  Qpsz = prod(ns(Qps));
+  Qsz = ns(Qnodes(d));
+  if isstr(startprob{d})
+    switch startprob{d}
+     case 'unif', startprob{d} = mk_stochastic(ones(Qpsz, Qsz));
+     case 'rnd', startprob{d} = mk_stochastic(rand(Qpsz, Qsz));
+     case 'leftstart', startprob{d} = zeros(Qpsz, Qsz); startprob{d}(:,1) = 1;
+    end
+  end
+  if isstr(transprob{d})
+    switch transprob{d}
+     case 'unif', transprob{d} = mk_stochastic(ones(Qsz, Qpsz, Qsz));
+     case 'rnd', transprob{d} = mk_stochastic(rand(Qsz, Qpsz, Qsz));
+     case 'leftright',
+      LR = mk_leftright_transmat(Qsz, selfprob);
+      temp = repmat(reshape(LR, [1 Qsz Qsz]), [Qpsz 1 1]); % transprob(k,i,j)
+      transprob{d} = permute(temp, [2 1 3]); % now transprob(i,k,j)
+    end
+  end
+  if isstr(termprob{d})
+    switch termprob{d}
+     case 'unif', termprob{d} = mk_stochastic(ones(Qpsz, Qsz, 2));
+     case 'rnd', termprob{d} = mk_stochastic(rand(Qpsz, Qsz, 2));
+     case 'rightstop',
+      %termprob(k,i,t) Might terminate if i=Qsz; will not terminate if i<Qsz
+      stopprob = 1-selfprob;
+      termprob{d} = zeros(Qpsz, Qsz, 2);
+      termprob{d}(:,Qsz,2) = stopprob;
+      termprob{d}(:,Qsz,1) = 1-stopprob;
+      termprob{d}(:,1:(Qsz-1),1) = 1;
+     otherwise, error(['unrecognized termprob ' termprob{d}])
+    end
+  elseif d>1 % passed in termprob{d}(k,j)
+    temp = termprob{d};
+    termprob{d} = zeros(Qpsz, Qsz, 2);
+    termprob{d}(:,:,2) = temp;
+    termprob{d}(:,:,1) = ones(Qpsz,Qsz) - temp;
+  end
+end
+
+
+% SLICE 1
+
+for d=1:D
+  bnet.CPD{eclass(Qnodes(d),1)} = tabular_CPD(bnet, Qnodes(d), 'CPT', startprob{d}, 'adjustable', clamp1);
+end
+
+if F1
+  d = 1;
+  bnet.CPD{eclass(Fnodes_ndx(d),1)}  = hhmmF_CPD(bnet, Fnodes_ndx(d), Qnodes(d), Fnodes_ndx(d+1), ...
+						 'termprob', termprob{d});
+end
+for d=2:D-1
+  if allQ
+    Qps = Qnodes(1:d-1);
+  else
+    Qps = Qnodes(d-1);
+  end
+  bnet.CPD{eclass(Fnodes_ndx(d),1)}  = hhmmF_CPD(bnet, Fnodes_ndx(d), Qnodes(d), Fnodes_ndx(d+1), ...
+						 'Qps', Qps, 'termprob', termprob{d});
+end
+bnet.CPD{eclass(Fnodes_ndx(D),1)}  = tabular_CPD(bnet, Fnodes_ndx(D), 'CPT', termprob{D});
+
+if discrete_obs
+  bnet.CPD{eclass(Onode,1)} = tabular_CPD(bnet, Onode, Oargs{:});
+else
+  bnet.CPD{eclass(Onode,1)} = gaussian_CPD(bnet, Onode, Oargs{:});
+end
+
+% SLICE 2
+
+%for d=1:D
+%  bnet.CPD{eclass(Qnodes(d),2)} = hhmmQ_CPD(bnet, Qnodes(d)+ss, Qnodes, d, D, ...
+%					    'startprob', startprob{d}, 'transprob', transprob{d}, ...
+%					    'allQ', allQ);
+%end
+
+d = 1;
+if F1
+  bnet.CPD{eclass(Qnodes(d),2)} = hhmmQ_CPD(bnet, Qnodes(d)+ss, 'Fself', Fnodes_ndx(d), ...
+					    'Fbelow', Fnodes_ndx(d+1), ...
+					    'startprob', startprob{d}, 'transprob', transprob{d});
+else
+    bnet.CPD{eclass(Qnodes(d),2)} = hhmmQ_CPD(bnet, Qnodes(d)+ss, ...
+					    'Fbelow', Fnodes_ndx(d+1), ...
+					    'startprob', startprob{d}, 'transprob', transprob{d});
+end
+for d=2:D-1
+  if allQ
+    Qps = Qnodes(1:d-1);
+  else
+    Qps = Qnodes(d-1);
+  end
+  Qps = Qps + ss; % since all in slice 2
+  bnet.CPD{eclass(Qnodes(d),2)} = hhmmQ_CPD(bnet, Qnodes(d)+ss, 'Fself', Fnodes_ndx(d), ...
+					    'Fbelow', Fnodes_ndx(d+1), 'Qps', Qps, ...
+					    'startprob', startprob{d}, 'transprob', transprob{d});
+end
+d = D;
+if allQ
+  Qps = Qnodes(1:d-1);
+else
+  Qps = Qnodes(d-1);
+end
+Qps = Qps + ss; % since all in slice 2
+bnet.CPD{eclass(Qnodes(d),2)} = hhmmQ_CPD(bnet, Qnodes(d)+ss, 'Fself', Fnodes_ndx(d), ...
+					  'Qps', Qps, ...
+					  'startprob', startprob{d}, 'transprob', transprob{d});
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo.m
new file mode 100644
index 00000000..7a5fe57c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo.m
@@ -0,0 +1,76 @@
+function [intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo(D, all_Q_to_Qs, Ops, F1)
+% MK_HHMM_TOPO Make Hierarchical HMM topology
+% function [intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo(D, all_Q_to_Qs, Ops, F1)
+%
+% D is the depth of the hierarchy
+% If all_Q_to_Qs = 1, level i connects to all levels below, else just to i+1 [0]
+% Ops are the Q parents of the observed node [Qnodes(end)]
+% If F1=1, level 1 can finish (restart), else there is no F1->Q1 arc [0]
+
+Qnodes = 1:D;
+
+if nargin < 2, all_Q_to_Qs = 1; end
+if nargin < 3, Ops = Qnodes(D); end
+if nargin < 4, F1 = 0; end
+
+if F1
+  Fnodes = 2*D:-1:D+1; % must number from bottom to top
+  Onode = 2*D+1;
+  ss = 2*D+1;
+else
+  Fnodes = [-1 (2*D)-1:-1:D+1]; % Fnodes(1) is a dummy index
+  Onode = 2*D;
+  ss = 2*D;
+end
+
+intra = zeros(ss);
+intra(Ops, Onode) = 1;
+for d=1:D-1
+  if all_Q_to_Qs
+    intra(Qnodes(d), Qnodes(d+1:end)) = 1;
+  else
+    intra(Qnodes(d), Qnodes(d+1)) = 1;
+  end
+end
+for d=D:-1:3
+  intra(Fnodes(d), Fnodes(d-1)) = 1;
+end
+if F1
+  intra(Fnodes(2), Fnodes(1)) = 1;
+end
+if all_Q_to_Qs
+  if F1
+    intra(Qnodes(1), Fnodes(1:end)) = 1;
+  else
+    intra(Qnodes(1), Fnodes(2:end)) = 1;
+  end
+  for d=2:D
+    intra(Qnodes(d), Fnodes(d:end)) = 1;
+  end
+else
+  if F1
+    intra(Qnodes(1), Fnodes([1 2])) = 1;
+  else
+    intra(Qnodes(1), Fnodes(2)) = 1;
+  end
+  for d=2:D-1
+    intra(Qnodes(d), Fnodes([d d+1])) = 1;
+  end
+  intra(Qnodes(D), Fnodes(D)) = 1;
+end
+
+
+inter = zeros(ss);
+for d=1:D
+  inter(Qnodes(d), Qnodes(d)) = 1;
+end
+if F1
+  inter(Fnodes(1), Qnodes(1)) = 1;
+end
+for d=2:D
+  inter(Fnodes(d), Qnodes([d-1 d])) = 1;
+end
+
+if ~F1
+  Fnodes = Fnodes(2:end); % strip off dummy -1 term
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo_F1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo_F1.m
new file mode 100644
index 00000000..2fc5f912
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo_F1.m
@@ -0,0 +1,65 @@
+function [intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo_F1(D, all_Q_to_Qs, Ops)
+% MK_HHMM_TOPO Make Hierarchical HMM topology assuming level 1 can finish 
+% function [intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo(D, all_Q_to_Qs, Ops, F1)
+%
+% D is the depth of the hierarchy
+% If all_Q_to_Qs = 1, level i connects to all levels below, else just to i+1 [0]
+% Ops are the Q parents of the observed node [Qnodes(end)]
+% If F1=1, level 1 can finish (restart), else there is no F1->Q1 arc [0]
+
+Qnodes = 1:D;
+
+if nargin < 2, all_Q_to_Qs = 1; end
+if nargin < 3, Ops = Qnodes(D); end
+if nargin < 4, F1 = 0; end
+
+if F1
+  Fnodes = 2*D:-1:D+1; % must number from bottom to top
+  Onode = 2*D+1;
+  ss = 2*D+1;
+else
+  Fnodes = (2*D)-1:-1:D+1;
+  Onode = 2*D;
+  ss = 2*D;
+end
+
+intra = zeros(ss);
+intra(Ops, Onode) = 1;
+for d=1:D-1
+  if all_Q_to_Qs
+    intra(Qnodes(d), Qnodes(d+1:end)) = 1;
+  else
+    intra(Qnodes(d), Qnodes(d+1)) = 1;
+  end
+end
+for d=D:-1:3
+  intra(Fnodes(d), Fnodes(d-1)) = 1;
+end
+if F1
+  intra(Fnodes(2), Fnodes(1)) = 1;
+end
+if all_Q_to_Qs
+  for d=1:D
+    intra(Qnodes(d), Fnodes(d:end)) = 1;
+  end
+else
+  for d=1:D
+    if d < D
+      intra(Qnodes(d), Fnodes([d d+1])) = 1;
+    else
+      intra(Qnodes(d), Fnodes(d)) = 1;
+    end
+  end
+end
+
+inter = zeros(ss);
+for d=1:D
+  inter(Qnodes(d), Qnodes(d)) = 1;
+end
+for d=1:D
+  if d==1
+    inter(Fnodes(d), Qnodes(d)) = 1;
+  else
+    inter(Fnodes(d), Qnodes([d-1 d])) = 1;
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/pretty_print_hhmm_parse.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/pretty_print_hhmm_parse.m
new file mode 100644
index 00000000..81b965d5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/pretty_print_hhmm_parse.m
@@ -0,0 +1,67 @@
+function pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, alphabet)
+% function pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, alphabet)
+%
+% mpe(i,t) is the most probable value of node i at time t
+% Qnodes(1:D), Fnodes = [F2 .. FD], Onode contain the node ids
+% alphabet(i) is the i'th output symbol, or [] if don't want displayed
+
+T = size(mpe,2);
+ncols = 20;
+t1 = 1; t2 = min(T, t1+ncols-1);
+while (t1 < T)
+  %fprintf('%d:%d\n', t1, t2);
+  if iscell(mpe)
+    print_block_cell(mpe(:,t1:t2), Qnodes, Fnodes, Onode, alphabet, t1);
+  else
+    print_block(mpe(:,t1:t2), Qnodes, Fnodes, Onode, alphabet, t1);
+  end
+  fprintf('\n\n');
+  t1 = t2+1; t2 = min(T, t1+ncols-1);
+end
+
+%%%%%%
+
+function print_block_cell(mpe, Qnodes, Fnodes, Onode, alphabet, start)
+
+D = length(Qnodes);
+T = size(mpe, 2);
+fprintf('%3d ', start:start+T-1); fprintf('\n');
+for d=1:D
+  for t=1:T
+    if (d > 1) & (mpe{Fnodes(d-1),t} == 2)
+      fprintf('%3d|', mpe{Qnodes(d), t});
+    else
+      fprintf('%3d ', mpe{Qnodes(d), t});
+    end
+  end
+  fprintf('\n');
+end
+if ~isempty(alphabet)
+  a = cell2num(mpe(Onode,:));
+  %fprintf('%3c ', alphabet(mpe{Onode,:}));
+  fprintf('%3c ', alphabet(a))
+  fprintf('\n');
+end
+
+
+%%%%%%
+
+function print_block(mpe, Qnodes, Fnodes, Onode, alphabet, start)
+
+D = length(Qnodes);
+T = size(mpe, 2);
+fprintf('%3d ', start:start+T-1); fprintf('\n');
+for d=1:D
+  for t=1:T
+    if (d > 1) & (mpe(Fnodes(d-1),t) == 2)
+      fprintf('%3d|', mpe(Qnodes(d), t));
+    else
+      fprintf('%3d ', mpe(Qnodes(d), t));
+    end
+  end
+  fprintf('\n');
+end
+if ~isempty(alphabet)
+  fprintf('%3c ', alphabet(mpe(Onode,:)));
+  fprintf('\n');
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/remove_hhmm_end_state.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/remove_hhmm_end_state.m
new file mode 100644
index 00000000..1ef9ded9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/remove_hhmm_end_state.m
@@ -0,0 +1,41 @@
+function [transprob, termprob] = remove_hhmm_end_state(A)
+% REMOVE_END_STATE Infer transition and termination probabilities from automaton with an end state
+% [transprob, termprob] = remove_end_state(A)
+%
+% A(i,k,j) = Pr( i->j | Qps=k), where i in 1:Q, j in 1:(Q+1), and Q+1 is the end state
+% This implements the equation in footnote 3 of my NIPS 01 paper,
+% transprob(i,k,j) = \tilde{A}_k(i,j)
+% termprob(k,j) = \tau_k(j)
+%
+% For the top level, the k index is missing.
+
+Q = size(A,1);
+toplevel = (ndims(A)==2);
+if toplevel
+  Qk = 1;
+  A = reshape(A, [Q 1 Q+1]);
+else
+  Qk = size(A, 2);
+end
+
+transprob = A(:, :, 1:Q);
+term = A(:,:,Q+1)'; % term(k,j) = P(Qj -> end | k)
+termprob = term;
+%termprob = zeros(Qk, Q, 2);
+%termprob(:,:,2) = term;
+%termprob(:,:,1) = 1-term;
+
+for k=1:Qk
+  for i=1:Q
+    for j=1:Q
+      denom = (1-termprob(k,i));
+      denom = denom + (denom==0)*eps;
+      transprob(i,k,j) = transprob(i,k,j) / denom;
+    end
+  end    
+end
+
+if toplevel
+  termprob = squeeze(termprob);
+  transprob = squeeze(transprob);
+end