about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/BNT/inference/dynamic
diff options
context:
space:
mode:
authorziejd22018-03-14 23:23:33 -0500
committerGitHub2018-03-14 23:23:33 -0500
commit1ff6baa44e22b91eefb48aea6f3befa078c0489b (patch)
treee0fd79d2e32fd2aedda2eadaed0f19af3514c520 /sourcecodes/bnt-master/BNT/inference/dynamic
parent6882395afdadf4e982b25b5215071a0932730950 (diff)
parentc80226899f5cdd9f11c163817d59445213f5bef0 (diff)
downloadBNW-1ff6baa44e22b91eefb48aea6f3befa078c0489b.tar.gz
Merge pull request #1 from ziejd2/octave_php_separate
Octave php separate
Diffstat (limited to 'sourcecodes/bnt-master/BNT/inference/dynamic')
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Entries10
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/bk_ff_hmm_inf_engine.m21
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_init_bel.m5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_marginal_from_bel.m5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_predict_bel.m19
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_update_bel.m19
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_update_bel1.m18
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/enter_evidence.m60
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/marginal_family.m5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/marginal_nodes.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/CVS/Entries8
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/bk_ff_fb.m59
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/combine_marginals_into_joint.m8
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/dbn_to_hmm.m41
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/mk_hmm_obs_lik_mat.m34
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/mk_hmm_obs_lik_vec.m27
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/mk_hmm_obs_lik_vec1.m25
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/project_joint_onto_marginals.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Entries11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/bk_inf_engine.m107
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_init_bel.m8
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_marginal_from_bel.m18
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel.m37
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel1.m30
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_evidence.m48
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_soft_evidence.m88
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_family.m25
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_nodes.m67
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/update_engine.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/CVS/Entries12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/cbk_inf_engine.m175
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_init_bel.m8
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_marginal_from_bel.m18
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_update_bel.m37
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_update_bel1.m30
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/enter_evidence.m48
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/enter_soft_evidence.m115
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/junk176
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/marginal_family.m25
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/marginal_nodes.m67
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/update_engine.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Entries8
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence.m59
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence1.m94
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/marginal_family.m38
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_evidence.m62
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_soft_evidence.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/ff_inf_engine.m44
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/filter_evidence.m48
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_family.m44
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_nodes.m20
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/smooth_evidence.m89
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/enter_evidence.m44
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/enter_soft_evidence.m142
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/frontier_inf_engine.m121
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/marginal_family.m7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/marginal_nodes.m21
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/set_fwdback.m8
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/CVS/Entries9
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/dhmm_inf_engine.m34
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/marginal_family.m31
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/marginal_nodes.m30
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/enter_evidence.m64
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/find_mpe.m16
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/fwdback_twoslice.m198
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/hmm_inf_engine.m71
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/marginal_family.m35
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/marginal_nodes.m29
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/CVS/Entries3
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/mk_hmm_obs_lik_matrix.m30
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/mk_hmm_obs_lik_vec.m52
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/update_engine.m8
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence1.m119
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence2.m143
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence3.m125
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence4.m149
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/marginal_nodes.m51
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Entries.Log2
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/enter_soft_evidence_nonint.m135
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/enter_soft_evidence_trans.m135
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/jtree_dbn_inf_engine.m67
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/jtree_dbn_inf_engine1.m62
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/jtree_dbn_inf_engine2.m57
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/enter_evidence.m70
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/enter_soft_evidence.m126
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/jtree_dbn_inf_engine.m109
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/marginal_family.m26
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/marginal_nodes.m66
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/CVS/Entries3
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/marginal_family.m10
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/marginal_nodes.m18
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/enter_evidence.m43
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/jtree_unrolled_dbn_inf_engine.m57
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/marginal_family.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/marginal_nodes.m16
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/update_engine.m7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/enter_evidence.m83
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/kalman_inf_engine.m23
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/marginal_nodes.m25
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/CVS/Entries3
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/dbn_to_lds.m26
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/extract_params_from_gbn.m38
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/update_engine.m9
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/CVS/Entries8
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/correct_smooth.m244
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/enter_evidence.m123
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/filter_evidence.m146
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/filter_evidence_obj_oriented.m158
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/smooth_evidence.m181
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/smooth_evidence_fast.m179
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/wrong_smooth.m210
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/enter_evidence.m35
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/enter_soft_ev.m137
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/marginal_nodes.m18
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/pearl_dbn_inf_engine.m65
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/init_pearl_dbn_ev_msgs.m28
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/enter_evidence.m41
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/marginal_family.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/marginal_nodes.m16
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/pearl_unrolled_dbn_inf_engine.m39
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/update_engine.m6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/enter_evidence.m43
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/marginal_family.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/marginal_nodes.m16
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/stable_ho_inf_engine.m67
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/test_ho_inf_enginge.m87
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/update_engine.m7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Entries.Log12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dynamic/dummy0
189 files changed, 6844 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Entries
new file mode 100644
index 00000000..5cd139de
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Entries
@@ -0,0 +1,10 @@
+/bk_ff_hmm_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/dbn_init_bel.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/dbn_marginal_from_bel.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/dbn_predict_bel.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/dbn_update_bel.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/dbn_update_bel1.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Entries.Log
new file mode 100644
index 00000000..b2cd71e0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/private////
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Repository
new file mode 100644
index 00000000..af5c9df5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@bk_ff_hmm_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/bk_ff_hmm_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/bk_ff_hmm_inf_engine.m
new file mode 100644
index 00000000..c726a1fd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/bk_ff_hmm_inf_engine.m
@@ -0,0 +1,21 @@
+function engine = bk_ff_hmm_inf_engine(bnet)
+% BK_FF_HMM_INF_ENGINE Naive (HMM-based) implementation of fully factored form of Boyen-Koller 
+% engine = bk_ff_hmm_inf_engine(bnet)
+%
+% This is implemented on top of the forwards-backwards algo for HMMs,
+% so it is *less* efficient than exact inference! However, it is good for educational purposes,
+% because it illustrates the BK algorithm very clearly.
+
+[persistent_nodes, transient_nodes] = partition_dbn_nodes(bnet.intra, bnet.inter);
+assert(isequal(sort(bnet.observed), transient_nodes));
+[engine.prior, engine.transmat] = dbn_to_hmm(bnet);
+
+ss = length(bnet.intra);
+
+engine.bel = [];
+engine.bel_marginals = [];
+engine.marginals = [];
+
+
+engine = class(engine, 'bk_ff_hmm_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_init_bel.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_init_bel.m
new file mode 100644
index 00000000..2ab39d37
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_init_bel.m
@@ -0,0 +1,5 @@
+function engine = dbn_init_bel(engine)
+% DBN_INIT_BEL Compute the initial belief state (bk_ff_hmm)
+% engine = dbn_init_bel(engine)
+
+engine.bel = engine.prior(:);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_marginal_from_bel.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_marginal_from_bel.m
new file mode 100644
index 00000000..a40d43b9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_marginal_from_bel.m
@@ -0,0 +1,5 @@
+function marginal = dbn_marginal_from_bel(engine, i)
+% DBN_MARGINAL_FROM_BEL Compute the marginal on a node given the current belief state (bk_ff_hmm)
+% marginal = dbn_marginal_from_bel(engine, i)
+
+marginal = pot_to_marginal(engine.bel_marginals{i});
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_predict_bel.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_predict_bel.m
new file mode 100644
index 00000000..5195e53f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_predict_bel.m
@@ -0,0 +1,19 @@
+function engine = dbn_predict_bel(engine, lag)
+% DBN_PREDICT_BEL Predict the belief state 'lag' steps into the future (bk_ff_hmm)
+% engine = dbn_predict_bel(engine, lag)
+% 'lag' defaults to 1
+
+if nargin < 2, lag = 1; end
+
+for d=1:lag
+  %newbel = engine.transmat' * engine.bel;
+  newbel = normalise(engine.transmat' * engine.bel); 
+  
+  hnodes = engine.hnodes;
+  bnet = bnet_from_engine(engine);
+  ns = bnet.node_sizes;
+  [marginals, marginalsT] = project_joint_onto_marginals(newbel, hnodes, ns);
+  newbel = combine_marginals_into_joint(marginalsT, hnodes, ns);          
+  engine.bel_marginals = marginalsT;
+  engine.bel = newbel;
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_update_bel.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_update_bel.m
new file mode 100644
index 00000000..8323b38a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_update_bel.m
@@ -0,0 +1,19 @@
+function [engine, loglik] = dbn_update_bel(engine, evidence)
+% DBN_UPDATE_BEL Update the belief state (bk_ff_hmm)
+% [engine, loglik] = dbn_update_bel(engine, evidence)
+%
+% evidence{i,1} contains the evidence on node i in slice t-1
+% evidence{i,2} contains the evidence on node i in slice t
+
+oldbel = engine.bel;
+bnet = bnet_from_engine(engine);
+obslik = mk_hmm_obs_lik_vec(bnet, evidence);
+[newbel, lik] = normalise((engine.transmat' * oldbel) .* obslik);
+loglik = log(lik);
+
+hnodes = engine.hnodes;
+ns = bnet.node_sizes;
+[marginals, marginalsT] = project_joint_onto_marginals(newbel, hnodes, ns);
+newbel = combine_marginals_into_joint(marginalsT, hnodes, ns);          
+engine.bel_marginals = marginalsT;
+engine.bel = newbel;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_update_bel1.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_update_bel1.m
new file mode 100644
index 00000000..6280ee77
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/dbn_update_bel1.m
@@ -0,0 +1,18 @@
+function [engine, loglik] = dbn_update_bel1(engine, evidence)
+% DBN_UPDATE_BEL Update the initial belief state (bk_ff_hmm)
+% [engine, loglik] = dbn_update_bel(engine, evidence)
+%
+%  evidence{i} contains the evidence on node i in slice 1
+
+oldbel = engine.bel;
+bnet = bnet_from_engine(engine);
+obslik = mk_hmm_obs_lik_vec1(bnet, evidence);
+[newbel, lik] = normalise(oldbel .* obslik);
+loglik = log(lik);
+
+hnodes = engine.hnodes;
+ns = bnet.node_sizes;
+[marginals, marginalsT] = project_joint_onto_marginals(newbel, hnodes, ns);
+newbel = combine_marginals_into_joint(marginalsT, hnodes, ns);          
+engine.bel_marginals = marginalsT;
+engine.bel = newbel;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..4719e0e9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/enter_evidence.m
@@ -0,0 +1,60 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (bk_ff_hmm)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product (not yet supported), else sum-product [0]
+% filter -   if 1, do filtering, else smoothing [0]
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+maximize = 0;
+filter = 0;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', maximize = args{i+1}; 
+     case 'filter', filter = args{i+1}; 
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+assert(~maximize);
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+onodes = bnet.observed;
+hnodes = mysetdiff(1:ss, onodes);
+T = size(evidence, 2);
+assertBNT(~any(isemptycell(evidence(onodes,:))));
+
+obslik = mk_hmm_obs_lik_mat(bnet, onodes, evidence);
+
+ns = bnet.node_sizes_slice;
+ns(onodes) = 1;
+
+[gamma, loglik, marginals, marginalsT] = bk_ff_fb(engine.prior, engine.transmat, obslik, filter, hnodes, ns);
+  
+for t=1:T
+  for i=hnodes(:)'
+    engine.marginals{i,t} = pot_to_marginal(marginalsT{i,t});
+  end
+  for i=onodes(:)'
+    m.domain = i + (t-1)*ss;
+    m.T = 1;
+    engine.marginals{i,t} = m;
+  end
+end
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/marginal_family.m
new file mode 100644
index 00000000..fe58a0f8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/marginal_family.m
@@ -0,0 +1,5 @@
+function m = marginal_family(engine, i, t)
+% MARGINAL_FAMILY Compute the marginal on the specified family (bk_ff_hmm)
+% marginal = marginal_family(engine, i, t)
+
+error('bk_ff_hmm doesn''t support marginal_family');
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..8c2f9e81
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/marginal_nodes.m
@@ -0,0 +1,11 @@
+function marginal = marginal_nodes(engine, nodes, t)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (bk_ff_hmm)
+% marginal = marginal_nodes(engine, i, t)
+
+assert(length(nodes)==1);
+i = nodes(end);
+%assert(myismember(i, engine.hnodes));
+marginal = engine.marginals{i,t};
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+marginal.domain = i + (t-1)*ss;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/CVS/Entries
new file mode 100644
index 00000000..b4ab4b45
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/CVS/Entries
@@ -0,0 +1,8 @@
+/bk_ff_fb.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/combine_marginals_into_joint.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/dbn_to_hmm.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/mk_hmm_obs_lik_mat.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/mk_hmm_obs_lik_vec.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/mk_hmm_obs_lik_vec1.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/project_joint_onto_marginals.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/CVS/Repository
new file mode 100644
index 00000000..3b0b141c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/bk_ff_fb.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/bk_ff_fb.m
new file mode 100644
index 00000000..ca41f77c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/bk_ff_fb.m
@@ -0,0 +1,59 @@
+function [gamma, loglik, marginals, marginalsT] = bk_ff_fb(prior, transmat, obslik, filter_only, hnodes, ns)
+% BK_FF_FB Fully factored Boyen-Koller version of forwards-backwards
+% [gamma, loglik, marginals, marginalsT] = bk_ff_hmm(prior, transmat, obslik, filter_only, hnodes, ns)
+
+ss  = length(ns);
+S = length(prior);
+T = size(obslik, 2);
+marginals = cell(ss,T);
+marginalsT = cell(ss,T);
+scale = zeros(1,T);
+alpha = zeros(S, T);
+
+transmat2 = transmat';
+for t=1:T
+  if t==1
+    [alpha(:,t), scale(t)] = normalise(prior(:) .* obslik(:,t));
+  else
+    [alpha(:,t), scale(t)] = normalise((transmat2 * alpha(:,t-1)) .* obslik(:,t));
+  end
+  [marginals(:,t), marginalsT(:,t)] = project_joint_onto_marginals(alpha(:,t), hnodes, ns);
+  alpha(:,t) = combine_marginals_into_joint(marginalsT(:,t), hnodes, ns);
+  %fprintf('alpha t=%d\n', t);
+  %celldisp(marginals(1:8,t))
+end
+loglik = sum(log(scale));
+
+if filter_only
+  gamma = alpha;
+  return;
+end
+
+beta = zeros(S,T);
+gamma = zeros(S,T);
+t = T;
+beta(:,t) = ones(S,1);
+gamma(:,t) = normalise(alpha(:,t) .* beta(:,t));
+[marginals(:,t), marginalsT(:,t)] = project_joint_onto_marginals(gamma(:,t), hnodes, ns);
+
+for t=T-1:-1:1
+  b = beta(:,t+1) .* obslik(:,t+1); 
+  beta(:,t) = normalise((transmat * b));
+  [junk, tempT] = project_joint_onto_marginals(beta(:,t), hnodes, ns);
+  beta(:,t) = combine_marginals_into_joint(tempT, hnodes, ns);
+  %gamma(:,t) = normalise(alpha(:,t) .* beta(:,t));
+  %[marginals(:,t), marginalsT(:,t)] = project_joint_onto_marginals(gamma(:,t), hnodes, ns);
+end
+
+gamma2 = zeros(S,T);
+for t=T-1:-1:1
+  b = beta(:,t+1) .* obslik(:,t+1); 
+  xi(:,:,t) = normalise((transmat .* (alpha(:,t) * b')));      
+  if t==T-1
+    gamma2(:,T) = sum(xi(:,:,T-1), 1)';
+  end
+  gamma2(:,t) = sum(xi(:,:,t), 2);
+  [marginals(:,t), marginalsT(:,t)] = project_joint_onto_marginals(gamma2(:,t), hnodes, ns);
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/combine_marginals_into_joint.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/combine_marginals_into_joint.m
new file mode 100644
index 00000000..74065662
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/combine_marginals_into_joint.m
@@ -0,0 +1,8 @@
+function joint = combine_marginals_into_joint(marginalsT, hnodes, ns)
+
+jointT = dpot(hnodes, ns(hnodes));
+for i=hnodes(:)'
+  jointT = multiply_by_pot(jointT, marginalsT{i});
+end
+m = pot_to_marginal(jointT);
+joint = m.T(:);           
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/dbn_to_hmm.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/dbn_to_hmm.m
new file mode 100644
index 00000000..4a921bfd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/dbn_to_hmm.m
@@ -0,0 +1,41 @@
+function [prior, transmat] = dbn_to_hmm(bnet)
+% DBN_TO_HMM Compute the discrete HMM matrices from a simple DBN
+% [prior, transmat] = dbn_to_hmm(bnet)
+
+onodes = bnet.observed;
+ss = length(bnet.intra);
+evidence = cell(1,2*ss);
+hnodes = mysetdiff(1:ss, onodes);
+prior = multiply_CPTs(bnet, [], hnodes, evidence);
+transmat = multiply_CPTs(bnet, hnodes, hnodes+ss, evidence);
+%obsmat1 = multiply_CPTs(bnet, hnodes, onodes, evidence);
+%obsmat = multiply_CPTs(bnet, hnodes+ss, onodes+ss, evidence);
+%obsmat1 = obsmat if the observation matrices are tied across slices
+
+
+
+%%%%%%%%%%%%
+
+function mat = multiply_CPTs(bnet, pdom, cdom, evidence)
+
+% MULTIPLY_CPTS Make a matrix Pr(Y|X), where X represents all the parents, and Y all the children
+% We assume the children have no intra-connections.
+%
+% e.g., Consider the DBN with interconnectivity i->i', j->j',k', k->i',k'
+% Then transition matrix = Pr(i,j,k -> i',j',k') = Pr(i,k->i') Pr(j->j') Pr(j,k->k')
+
+dom = [pdom cdom];
+ns = bnet.node_sizes;
+bigpot = dpot(dom, ns(dom));
+for j=cdom(:)'
+  e = bnet.equiv_class(j);
+  fam = family(bnet.dag, j);
+  pot = convert_to_pot(bnet.CPD{e}, 'd', fam(:), evidence);
+  bigpot = multiply_by_pot(bigpot, pot);
+end
+psize = prod(ns(pdom));
+csize = prod(ns(cdom));
+T = pot_to_marginal(bigpot);
+mat = reshape(T.T, [psize csize]);
+
+          
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/mk_hmm_obs_lik_mat.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/mk_hmm_obs_lik_mat.m
new file mode 100644
index 00000000..b3e4c4cc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/mk_hmm_obs_lik_mat.m
@@ -0,0 +1,34 @@
+function obslik = mk_hmm_obs_lik_mat(bnet, onodes, evidence)
+% MK_HMM_OBS_LIK_MAT Make the observation likelihood matrix for all slices
+% obslik = mk_hmm_obs_lik_mat(bnet, onodes, evidence)
+%
+% obslik(i,t) = Pr(Y(t) | X(t)=i)
+
+[ss T] = size(evidence);
+
+hnodes = mysetdiff(1:ss, onodes);
+ns = bnet.node_sizes_slice;
+ns(onodes) = 1;
+Q = prod(ns(hnodes));
+obslik = zeros(Q,T);
+
+dom = 1:ss;
+for t=1:T
+  bigpot = dpot(dom, ns(dom));
+  for i=onodes(:)'
+    if t==1
+      e = bnet.equiv_class(i,1);
+      fam = family(bnet.dag, i);
+    else
+      e = bnet.equiv_class(i,2);
+      fam = family(bnet.dag, i, 2) + ss*(t-2);
+    end
+    pot = convert_to_pot(bnet.CPD{e}, 'd', fam(:), evidence);
+    pot = set_domain_pot(pot, family(bnet.dag, i));
+    bigpot = multiply_by_pot(bigpot, pot);
+  end
+  m = pot_to_marginal(bigpot);
+  obslik(:,t) = m.T(:);
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/mk_hmm_obs_lik_vec.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/mk_hmm_obs_lik_vec.m
new file mode 100644
index 00000000..23247bd5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/mk_hmm_obs_lik_vec.m
@@ -0,0 +1,27 @@
+function obslik = mk_hmm_obs_lik_vec(bnet, evidence)
+% MK_HMM_OBS_LIK_VEC Make the observation likelihood vector for one slice
+% obslik = mk_obs_lik(bnet, evidence)
+%
+% obslik(i) = Pr(y(t) | X(t)=i)
+% evidence{i,1} contains the evidence on node i in slice t-1
+% evidence{i,2} contains the evidence on node i in slice t
+
+ns = bnet.node_sizes;
+ss = length(bnet.intra);
+onodes = find(~isemptycell(evidence(:)));
+hnodes = find(isemptycell(evidence(:)));
+ens = ns;
+ens(onodes) = 1;
+Q = prod(ens(hnodes));
+obslik = zeros(1,Q);
+dom = (1:ss)+ss;
+bigpot = dpot(dom, ens(dom));
+onodes1 = find(~isemptycell(evidence(:,1)));
+for i=onodes1(:)'
+  e = bnet.equiv_class(i,2);
+  fam = family(bnet.dag, i, 2);
+  pot = convert_to_pot(bnet.CPD{e}, 'd', fam, evidence);
+  bigpot = multiply_by_pot(bigpot, pot);
+end
+m = pot_to_marginal(bigpot);
+obslik = m.T(:);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/mk_hmm_obs_lik_vec1.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/mk_hmm_obs_lik_vec1.m
new file mode 100644
index 00000000..6d0c1d35
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/mk_hmm_obs_lik_vec1.m
@@ -0,0 +1,25 @@
+function obslik = mk_hmm_obs_lik_vec1(bnet, evidence)
+% MK_HMM_OBS_LIK_VEC1 Make the observation likelihood vector for the first slice
+% obslik = mk_hmm_obs_lik_vec1(engine, evidence)
+%
+% obslik(i) = Pr(y(1) | X(1)=i)
+% evidence{i} contains the evidence on node i in slice 1
+
+ns = bnet.node_sizes;
+ss = length(ns);
+onodes = find(~isemptycell(evidence(:)));
+hnodes = find(isemptycell(evidence(:)));
+ens = ns;
+ens(onodes) = 1;
+Q = prod(ens(hnodes));
+obslik = zeros(1,Q);
+dom = (1:ss);
+bigpot = dpot(dom, ens(dom));
+for i=onodes(:)'
+  e = bnet.equiv_class(i,1);
+  fam = family(bnet.dag, i);
+  pot = convert_to_pot(bnet.CPD{e}, 'd', fam(:), evidence);
+  bigpot = multiply_by_pot(bigpot, pot);
+end
+m = pot_to_marginal(bigpot);
+obslik = m.T(:);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/project_joint_onto_marginals.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/project_joint_onto_marginals.m
new file mode 100644
index 00000000..3f4036db
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_ff_hmm_inf_engine/private/project_joint_onto_marginals.m
@@ -0,0 +1,11 @@
+function [marginals, marginalsT] = project_joint_onto_marginals(joint, hnodes, ns)
+
+ss = length(ns);
+jointT = dpot(hnodes, ns(hnodes), joint);
+marginalsT = cell(1, ss);
+marginals = cell(1,ss);
+for i=hnodes(:)'
+  marginalsT{i} = marginalize_pot(jointT, i);
+  m = pot_to_marginal(marginalsT{i});
+  marginals{i} = m.T(:);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Entries
new file mode 100644
index 00000000..b071e13e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Entries
@@ -0,0 +1,11 @@
+/bk_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/dbn_init_bel.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/dbn_marginal_from_bel.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/dbn_update_bel.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/dbn_update_bel1.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_soft_evidence.m/1.1.1.1/Sat Jan 11 18:13:50 2003//
+/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/update_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Repository
new file mode 100644
index 00000000..5e810837
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@bk_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/bk_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/bk_inf_engine.m
new file mode 100644
index 00000000..2ca0350f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/bk_inf_engine.m
@@ -0,0 +1,107 @@
+function engine = bk_inf_engine(bnet, varargin)
+% BK_INF_ENGINE Boyen-Koller approximate inference algorithm for DBNs.
+%
+% In the BK algorithm, the belief state is represented as a product of marginals,
+% even though the factors may not be independent.
+%
+% engine = bk_inf_engine(bnet, ...)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+% 
+% clusters - if a cell array, clusters{i} specifies the terms in the i'th factor.
+%          - 'exact' means create one cluster that contains all the nodes in a slice [exact]
+%          - 'ff' means create one cluster per node (ff = fully factorised).
+%
+%
+% For details, see
+% - "Tractable Inference for Complex Stochastic Processes", X. Boyen and D. Koller, UAI 98.
+% - "Approximate learning of dynamic models",  X. Boyen and D. Koller, NIPS 98.
+% (The UAI98 paper discusses filtering and theory, and the NIPS98 paper discusses smoothing.)
+
+ss = length(bnet.intra);
+% set default params
+clusters = 'exact';
+
+
+if nargin >= 2
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'clusters',  clusters = args{i+1};
+     otherwise, error(['unrecognized argument ' args{i}])
+    end
+  end
+end
+
+if strcmp(clusters, 'exact')
+  %clusters = { compute_interface_nodes(bnet.intra, bnet.inter) };
+  clusters = { 1:ss }; 
+elseif strcmp(clusters, 'ff')
+  clusters = num2cell(1:ss);
+end
+
+
+% We need to insert the prior on the clusters in slice 1,
+% and extract the posterior on the clusters in slice 2.
+C = length(clusters);
+clusters2 = cell(1,2*C);
+clusters2(1:C) = clusters;
+for c=1:C
+  clusters2{c+C} = clusters{c} + ss;
+end
+
+onodes = bnet.observed;
+obs_nodes = [onodes(:) onodes(:)+ss];
+engine.sub_engine = jtree_inf_engine(bnet, 'clusters', clusters2);
+
+engine.clq_ass_to_cluster = zeros(C, 2);
+for c=1:C
+  engine.clq_ass_to_cluster(c,1) = clq_containing_nodes(engine.sub_engine, clusters{c});
+  engine.clq_ass_to_cluster(c,2) = clq_containing_nodes(engine.sub_engine, clusters{c}+ss);
+end
+engine.clusters = clusters;
+
+engine.clq_ass_to_node = zeros(ss, 2);
+for i=1:ss
+  engine.clq_ass_to_node(i, 1) = clq_containing_nodes(engine.sub_engine, i);
+  engine.clq_ass_to_node(i, 2) = clq_containing_nodes(engine.sub_engine, i+ss);
+end
+
+
+
+% Also create an engine just for slice 1
+bnet1 = mk_bnet(bnet.intra1, bnet.node_sizes_slice, 'discrete', myintersect(bnet.dnodes, 1:ss), ...
+		'equiv_class', bnet.equiv_class(:,1), 'observed', onodes);
+for i=1:max(bnet1.equiv_class)
+  bnet1.CPD{i} = bnet.CPD{i};
+end
+
+engine.sub_engine1 = jtree_inf_engine(bnet1, 'clusters', clusters);
+
+engine.clq_ass_to_cluster1 = zeros(1,C);
+for c=1:C
+  engine.clq_ass_to_cluster1(c) = clq_containing_nodes(engine.sub_engine1, clusters{c});
+end
+
+engine.clq_ass_to_node1 = zeros(1, ss);
+for i=1:ss
+  engine.clq_ass_to_node1(i) = clq_containing_nodes(engine.sub_engine1, i);
+end
+
+engine.clpot = []; % this is where we store the results between enter_evidence and marginal_nodes
+engine.filter = [];
+engine.maximize = [];
+engine.T = [];
+
+engine.bel = [];
+engine.bel_clpot = [];
+engine.slice1 = [];
+%engine.pot_type = 'cg';
+% hack for online inference so we can cope with hidden Gaussians and discrete
+% it will not affect the pot type used in enter_evidence
+engine.pot_type = determine_pot_type(bnet, onodes);
+
+engine = class(engine, 'bk_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_init_bel.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_init_bel.m
new file mode 100644
index 00000000..fa6a27de
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_init_bel.m
@@ -0,0 +1,8 @@
+function engine = dbn_init_bel(engine)
+% DBN_INIT_BEL Compute the initial belief state (bk)
+% engine = dbn_init_bel(engine))
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+evidence = cell(1,ss);
+engine = dbn_update_bel1(engine, evidence);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_marginal_from_bel.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_marginal_from_bel.m
new file mode 100644
index 00000000..7e5a968d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_marginal_from_bel.m
@@ -0,0 +1,18 @@
+function marginal = dbn_marginal_from_bel(engine, i)
+% DBN_MARGINAL_FROM_BEL Compute the marginal on a node given the current belief state (bk)
+% marginal = dbn_marginal_from_bel(engine, i)
+  
+if engine.slice1
+  j = i;
+  c = clq_containing_nodes(engine.sub_engine1, j);
+else
+  bnet = bnet_from_engine(engine);
+  ss = length(bnet.intra);
+  j = i+ss;
+  c = clq_containing_nodes(engine.sub_engine, j);
+end
+assert(c >= 1);
+bigpot = engine.bel_clpot{c};
+
+pot = marginalize_pot(bigpot, j);
+marginal = pot_to_marginal(pot);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel.m
new file mode 100644
index 00000000..0c8e02b5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel.m
@@ -0,0 +1,37 @@
+function [engine, loglik] = dbn_update_bel(engine, evidence)
+% DBN_UPDATE_BEL Update the belief state (bk)
+% [engine, loglik] = dbn_update_bel(engine, evidence)
+%
+% evidence{i,1} contains the evidence on node i in slice t-1
+% evidence{i,2} contains the evidence on node i in slice t
+
+oldbel = engine.bel;
+
+ss = size(evidence, 1);
+bnet = bnet_from_engine(engine);
+CPDpot = cell(1, ss);
+for n=1:ss
+  fam = family(bnet.dag, n, 2);
+  e = bnet.equiv_class(n, 2);
+  CPDpot{n} = convert_to_pot(bnet.CPD{e}, engine.pot_type, fam(:), evidence);
+end
+
+observed = ~isemptycell(evidence);
+onodes2 = find(observed(:));
+clqs = [engine.clq_ass_to_cluster(:,1); engine.clq_ass_to_node(:,2)];
+pots = [oldbel(:); CPDpot(:)];
+
+[clpot, loglik] = enter_soft_evidence(engine.sub_engine, clqs, pots, onodes2(:), engine.pot_type);
+
+C = length(engine.clusters);
+newbel = cell(1,C);
+for c=1:C
+  k = engine.clq_ass_to_cluster(c,2);
+  cl = engine.clusters{c};
+  newbel{c} = marginalize_pot(clpot{k}, cl+ss); % extract slice 2 posterior
+  newbel{c} = set_domain_pot(newbel{c}, cl); % shift back to slice 1 for re-use as prior
+end
+
+engine.bel = newbel;
+engine.bel_clpot = clpot;
+engine.slice1 = 0;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel1.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel1.m
new file mode 100644
index 00000000..a3b6cc79
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/dbn_update_bel1.m
@@ -0,0 +1,30 @@
+function [engine, loglik] = dbn_update_bel1(engine, evidence)
+% DBN_UPDATE_BEL1 Update  the initial belief state (bk)
+% engine = dbn_update_bel1(engine, evidence)
+%
+% evidence{i} has the evidence on node i for slice 1
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+CPDpot = cell(1,ss);      
+t = 1;
+for n=1:ss
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n, 1);
+  CPDpot{n} = convert_to_pot(bnet.CPD{e}, engine.pot_type, fam(:), evidence);
+end
+
+onodes = find(~isemptycell(evidence));
+
+[clpot, loglik] = enter_soft_evidence(engine.sub_engine1, engine.clq_ass_to_node1, CPDpot, onodes, engine.pot_type);
+
+C  = length(engine.clusters);
+newbel = cell(1,C);
+for c=1:C
+  k = engine.clq_ass_to_cluster1(c);
+  newbel{c} = marginalize_pot(clpot{k}, engine.clusters{c});
+end
+
+engine.bel = newbel;
+engine.bel_clpot = clpot;
+engine.slice1 = 1;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..7008137b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_evidence.m
@@ -0,0 +1,48 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (bk)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product instead of sum-product [0]
+% filter -   if 1, do filtering, else smoothing [0]
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+maximize = 0;
+filter = 0;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', maximize = args{i+1}; 
+     case 'filter', filter = args{i+1}; 
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+[ss T] = size(evidence);
+engine.filter = filter;
+engine.maximize = maximize;
+engine.T = T;
+
+if maximize
+  error('BK does not yet support max propagation')
+  % because it calls enter_soft_evidence, not enter_evidence
+end
+
+observed_bitv = ~isemptycell(evidence);
+onodes = find(observed_bitv);
+bnet = bnet_from_engine(engine);
+pot_type = determine_pot_type(bnet, onodes); 
+CPDpot = convert_dbn_CPDs_to_pots(bnet, evidence, pot_type);
+[engine.clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed_bitv, pot_type, filter);
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_soft_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_soft_evidence.m
new file mode 100644
index 00000000..1cbc634e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/enter_soft_evidence.m
@@ -0,0 +1,88 @@
+function [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (bk)
+% [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+
+[ss T] = size(CPDpot);
+C = length(engine.clusters);
+Q = length(cliques_from_engine(engine.sub_engine));
+Q1 = length(cliques_from_engine(engine.sub_engine1));
+clpot = cell(Q,T);
+alpha = cell(C,T);
+
+% Forwards
+% The method is a generalization of the following HMM equation:
+% alpha(j,t) = normalise( (sum_i alpha(i,t-1) * transmat(i,j)) * obsmat(j,t) )
+% where alpha(j,t) = Pr(Q(t)=j | y(1:t))
+t = 1;
+[clpot(1:Q1,t), logscale(t)] = enter_soft_evidence(engine.sub_engine1, engine.clq_ass_to_node1(:), ...
+					   CPDpot(:,1), find(observed(:,1)), pot_type);
+for c=1:C
+  k = engine.clq_ass_to_cluster1(c);
+  alpha{c,t} = marginalize_pot(clpot{k,t}, engine.clusters{c});
+end
+% For filtering, clpot{1} contains evidence on slice 1 only
+
+%fprintf('alphas t=%d\n', t);
+%for c=1:8
+%  temp = pot_to_marginal(alpha{c,t});
+%  temp.T
+%end
+
+% clpot{t} contains evidence from slices t-1, t for t > 1
+clqs = [engine.clq_ass_to_cluster(:,1); engine.clq_ass_to_node(:,2)];
+for t=2:T
+  pots = [alpha(:,t-1); CPDpot(:,t)];
+  [clpot(:,t), logscale(t)] = enter_soft_evidence(engine.sub_engine, clqs, pots, find(observed(:,t-1:t)),  pot_type);
+  for c=1:C
+    k = engine.clq_ass_to_cluster(c,2);
+    cl = engine.clusters{c};
+    alpha{c,t} = marginalize_pot(clpot{k,t}, cl+ss); % extract slice 2 posterior
+    alpha{c,t} = set_domain_pot(alpha{c,t}, cl); % shift back to slice 1 for re-use as prior
+  end
+
+end
+
+loglik = sum(logscale);
+
+if filter
+  return;
+end
+
+% Backwards
+% The method is a generalization of the following HMM equation:
+% beta(i,t) = (sum_j transmat(i,j) * obsmat(j,t+1) * beta(j,t+1))
+% where beta(i,t) = Pr(y(t+1:T) | Q(t)=i)
+t = T;
+bnet = bnet_from_engine(engine);
+beta = cell(C,T);
+for c=1:C
+  beta{c,t} = mk_initial_pot(pot_type, engine.clusters{c} + ss, bnet.node_sizes(:), bnet.cnodes(:), ...
+			     find(observed(:,t-1:t)));
+end
+for t=T-1:-1:1
+  clqs = [engine.clq_ass_to_cluster(:,2); engine.clq_ass_to_node(:,2)];
+  pots = [beta(:,t+1); CPDpot(:,t+1)];
+  temp = enter_soft_evidence(engine.sub_engine, clqs, pots, find(observed(:,t:t+1)),  pot_type);
+  for c=1:C
+    k = engine.clq_ass_to_cluster(c,1);
+    cl = engine.clusters{c};
+    beta{c,t} = marginalize_pot(temp{k}, cl); % extract slice 1
+    beta{c,t} = set_domain_pot(beta{c,t}, cl + ss); % shift fwd to slice 2
+  end
+end
+
+% Combine
+% The method is a generalization of the following HMM equation:
+% xi(i,j,t) = normalise( alpha(i,t) * transmat(i,j) * obsmat(j,t+1) * beta(j,t+1) )
+% where xi(i,j,t) = Pr(Q(t)=i, Q(t+1)=j | y(1:T))
+for t=1:T-1
+  clqs = [engine.clq_ass_to_cluster(:); engine.clq_ass_to_node(:,2)];
+  pots = [alpha(:,t); beta(:,t+1); CPDpot(:,t+1)];
+  clpot(:,t+1) = enter_soft_evidence(engine.sub_engine, clqs, pots, find(observed(:,t:t+1)),  pot_type);
+end
+% for smoothing, clpot{1} is undefined
+for k=1:Q1
+  clpot{k,1} = []; 
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_family.m
new file mode 100644
index 00000000..e948b836
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_family.m
@@ -0,0 +1,25 @@
+function m = marginal_family(engine, i, t)
+% MARGINAL_FAMILY Compute the marginal on the specified family (bk)
+% marginal = marginal_family(engine, i, t)
+
+% This is just like inf_engine/marginal_family, except when we call
+% marginal_nodes, we provide a 4th argument, to tell it's a family.
+
+if nargin < 3, t = 1; end
+
+bnet = bnet_from_engine(engine);
+if t==1
+  m = marginal_nodes(engine, family(bnet.dag, i), t, 1);
+else
+  ss = length(bnet.intra);
+  fam = family(bnet.dag, i+ss);
+  if any(fam<=ss)
+    % i has a parent in the preceeding slice
+    % Hence the lowest numbered slice containing the family is t-1
+    m = marginal_nodes(engine, fam, t-1, 1);
+  else
+    % The family all fits inside slice t
+    % Hence shift the indexes back to slice 1
+    m = marginal_nodes(engine, fam-ss, t, 1);
+  end
+end     
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..30bf9a9d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/marginal_nodes.m
@@ -0,0 +1,67 @@
+function marginal = marginal_nodes(engine, nodes, t, fam)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (bk)
+%
+%   marginal = marginal_nodes(engine, i, t)
+% returns Pr(X(i,t) | Y(1:T)), where X(i,t) is the i'th node in the t'th slice.
+% If enter_evidence used filtering instead of smoothing, this will return  Pr(X(i,t) | Y(1:t)).
+%
+%   marginal = marginal_nodes(engine, query, t)
+% returns Pr(X(query(1),t), ... X(query(end),t) | Y(1:T)),
+% where X(q,t) is the q'th node in the t'th slice. If q > ss (slice size), this is equal
+% to X(q mod ss, t+1). That is, 't' specifies the time slice of the earliest node.
+% 'query' cannot span more than 2 time slices.
+% Example:
+% Consider a DBN with 2 nodes per slice.
+% Then t=2, nodes=[1 3] refers to node 1 in slice 2 and node 1 in slice 3.
+
+if nargin < 3, t = 1; end
+if nargin < 4, fam = 0; else fam = 1; end
+
+
+% clpot{t} contains slice t-1 and t
+% Example
+% clpot #: 1    2    3
+% slices:  1  1,2  2,3
+% For filtering, we must take care not to take future evidence into account.
+% For smoothing, clpot{1} does not exist.
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+
+nodes2 = nodes;
+if ~engine.filter
+  if t < engine.T
+    slice = t+1;
+  else % earliest t is T, so all nodes fit in one slice
+    slice = engine.T;
+    nodes2 = nodes + ss;
+  end
+else
+  if t == 1
+   slice = 1;
+  else
+    if all(nodes<=ss)
+      slice = t;
+      nodes2 = nodes + ss;
+    elseif t == engine.T
+      slice = t;
+    else
+      slice = t + 1;
+    end
+  end
+end
+  
+if engine.filter & t==1
+  c = clq_containing_nodes(engine.sub_engine1, nodes2, fam);
+else
+  c = clq_containing_nodes(engine.sub_engine, nodes2, fam);
+end
+assert(c >= 1);
+bigpot = engine.clpot{c, slice};
+
+pot = marginalize_pot(bigpot, nodes2);
+marginal = pot_to_marginal(pot);
+
+% we convert the domain to the unrolled numbering system
+% so that update_ess extracts the right evidence.
+marginal.domain = nodes+(t-1)*ss;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/update_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/update_engine.m
new file mode 100644
index 00000000..b36833a1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@bk_inf_engine/update_engine.m
@@ -0,0 +1,11 @@
+function engine = update_engine(engine, newCPDs)
+% UPDATE_ENGINE Update the engine to take into account the new parameters (bk)
+% engine = update_engine(engine, newCPDs)
+
+engine.inf_engine = update_engine(engine.inf_engine, newCPDs);
+engine.sub_engine = update_engine(engine.sub_engine, newCPDs);
+
+bnet = bnet_from_engine(engine);
+eclass1 = bnet.equiv_class(:,1);
+engine.sub_engine1 = update_engine(engine.sub_engine1, newCPDs(1:max(eclass1)));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/CVS/Entries
new file mode 100644
index 00000000..4aa8d100
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/CVS/Entries
@@ -0,0 +1,12 @@
+/cbk_inf_engine.m/1.1.1.1/Mon Nov 22 22:15:34 2004//
+/dbn_init_bel.m/1.1.1.1/Tue Jul 29 02:44:58 2003//
+/dbn_marginal_from_bel.m/1.1.1.1/Tue Jul 29 02:44:58 2003//
+/dbn_update_bel.m/1.1.1.1/Tue Jul 29 02:44:58 2003//
+/dbn_update_bel1.m/1.1.1.1/Tue Jul 29 02:44:58 2003//
+/enter_evidence.m/1.1.1.1/Mon Jan 12 20:53:54 2004//
+/enter_soft_evidence.m/1.1.1.1/Wed Feb  4 07:42:38 2004//
+/junk/1.1.1.1/Wed Nov 24 20:12:38 2004//
+/marginal_family.m/1.1.1.1/Tue Jul 29 02:44:58 2003//
+/marginal_nodes.m/1.1.1.1/Tue Dec 16 06:17:18 2003//
+/update_engine.m/1.1.1.1/Tue Jul 29 02:44:58 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/CVS/Repository
new file mode 100644
index 00000000..67ff288b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@cbk_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/cbk_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/cbk_inf_engine.m
new file mode 100644
index 00000000..20b4c4eb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/cbk_inf_engine.m
@@ -0,0 +1,175 @@
+function engine = cbk_inf_engine(bnet, varargin)
+% Just the same as bk_inf_engine, but you can specify overlapping clusters.
+
+ss = length(bnet.intra);
+% set default params
+clusters = 'exact';
+
+if nargin >= 2
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'clusters',  clusters = args{i+1};
+     otherwise, error(['unrecognized argument ' args{i}])
+    end
+  end
+end
+
+if strcmp(clusters, 'exact')
+  %clusters = { compute_interface_nodes(bnet.intra, bnet.inter) };
+  clusters = { 1:ss };
+elseif strcmp(clusters, 'ff')
+  clusters = num2cell(1:ss);
+end
+
+
+% We need to insert the prior on the clusters in slice 1,
+% and extract the posterior on the clusters in slice 2.
+% We don't need to care about the separators, b/c they're subsets of the clusters.
+C = length(clusters);
+clusters2 = cell(1,2*C);
+clusters2(1:C) = clusters;
+for c=1:C
+  clusters2{c+C} = clusters{c} + ss;
+end
+
+onodes = bnet.observed;
+obs_nodes = [onodes(:) onodes(:)+ss];
+engine.sub_engine = jtree_inf_engine(bnet, 'clusters', clusters2);
+
+%FH >>>
+%Compute separators. 
+ns = bnet.node_sizes(:,1);
+ns(onodes) = 1;
+[clusters, separators] = build_jt(clusters, 1:length(ns), ns);
+S = length(separators);
+engine.separators = separators;
+
+%Compute size of clusters.
+cl_sizes = zeros(1,C);
+for c=1:C
+    cl_sizes(c) = prod(ns(clusters{c}));
+end
+
+%Assign separators to the smallest cluster subsuming them.
+engine.cluster_ass_to_separator = zeros(S, 1);
+for s=1:S
+    subsuming_clusters = [];
+    %find smallest cluster containing s
+    for c=1:C
+        if mysubset(separators{s}, clusters{c}) 
+            subsuming_clusters(end+1) = c;
+        end
+    end
+    c = argmin(cl_sizes(subsuming_clusters));
+    engine.cluster_ass_to_separator(s) = subsuming_clusters(c);
+end
+
+%<<< FH
+
+engine.clq_ass_to_cluster = zeros(C, 2);
+for c=1:C
+  engine.clq_ass_to_cluster(c,1) = clq_containing_nodes(engine.sub_engine, clusters{c});
+  engine.clq_ass_to_cluster(c,2) = clq_containing_nodes(engine.sub_engine, clusters{c}+ss);
+end
+engine.clusters = clusters;
+
+engine.clq_ass_to_node = zeros(ss, 2);
+for i=1:ss
+  engine.clq_ass_to_node(i, 1) = clq_containing_nodes(engine.sub_engine, i);
+  engine.clq_ass_to_node(i, 2) = clq_containing_nodes(engine.sub_engine, i+ss);
+end
+
+
+
+% Also create an engine just for slice 1
+bnet1 = mk_bnet(bnet.intra1, bnet.node_sizes_slice, 'discrete', myintersect(bnet.dnodes, 1:ss), ...
+		'equiv_class', bnet.equiv_class(:,1), 'observed', onodes);
+for i=1:max(bnet1.equiv_class)
+  bnet1.CPD{i} = bnet.CPD{i};
+end
+
+engine.sub_engine1 = jtree_inf_engine(bnet1, 'clusters', clusters);
+
+engine.clq_ass_to_cluster1 = zeros(1,C);
+for c=1:C
+  engine.clq_ass_to_cluster1(c) = clq_containing_nodes(engine.sub_engine1, clusters{c});
+end
+
+engine.clq_ass_to_node1 = zeros(1, ss);
+for i=1:ss
+  engine.clq_ass_to_node1(i) = clq_containing_nodes(engine.sub_engine1, i);
+end
+
+engine.clpot = []; % this is where we store the results between enter_evidence and marginal_nodes
+engine.filter = [];
+engine.maximize = [];
+engine.T = [];
+
+engine.bel = [];
+engine.bel_clpot = [];
+engine.slice1 = [];
+%engine.pot_type = 'cg';
+% hack for online inference so we can cope with hidden Gaussians and discrete
+% it will not affect the pot type used in enter_evidence
+engine.pot_type = determine_pot_type(bnet, onodes);
+
+engine = class(engine, 'cbk_inf_engine', inf_engine(bnet));
+
+
+
+
+function [cliques, seps, jt_size] = build_jt(cliques, vars, ns)
+% BUILD_JT connects the cliques into a jtree, computes the respective 
+% separators and the size of the resulting jtree.
+%
+% [cliques, seps, jt_size] = build_jt(cliques, vars, ns)
+% ns(i) has to hold the size of vars(i)
+% vars has to be a superset of the union of cliques.
+
+%======== Compute the jtree with tool from BNT. This wants the vars to be 1:N.
+%==== Map from nodes to their indices.
+%disp('Computing jtree for cliques with vars and ns:');
+%cliques
+%vars
+%ns'
+
+inv_nodes = sparse(1,max(vars));
+N = length(vars);
+for i=1:N
+    inv_nodes(vars(i)) = i;
+end
+
+tmp_cliques = cell(1,length(cliques));
+%==== Temporarily map clique vars to their indices.
+for i=1:length(cliques)
+    tmp_cliques{i} = inv_nodes(cliques{i});
+end
+
+%=== Compute the jtree, using BNT.
+[jtree, root, B, w] = cliques_to_jtree(tmp_cliques, ns);
+
+
+%======== Now, compute the separators between connected cliques and their weights.
+seps = {};
+s_w = [];
+[is,js] = find(jtree > 0);
+for k=1:length(is)
+  i = is(k); j = js(k);
+  sep = vars(find(B(i,:) & B(j,:))); % intersect(cliques{i}, cliques{j});
+  if i>j | length(sep) == 0, continue; end;
+  seps{end+1} = sep;
+  s_w(end+1) = prod(ns(inv_nodes(seps{end})));
+end
+
+cl_w = sum(w);
+sep_w = sum(s_w);
+assert(cl_w > sep_w, 'Weight of cliques must be bigger than weight of separators');
+
+jt_size = cl_w + sep_w;
+% jt.cliques = cliques;
+% jt.seps = seps;
+% jt.size = jt_size;
+% jt.ns = ns';
+% jt;
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_init_bel.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_init_bel.m
new file mode 100644
index 00000000..fa6a27de
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_init_bel.m
@@ -0,0 +1,8 @@
+function engine = dbn_init_bel(engine)
+% DBN_INIT_BEL Compute the initial belief state (bk)
+% engine = dbn_init_bel(engine))
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+evidence = cell(1,ss);
+engine = dbn_update_bel1(engine, evidence);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_marginal_from_bel.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_marginal_from_bel.m
new file mode 100644
index 00000000..7e5a968d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_marginal_from_bel.m
@@ -0,0 +1,18 @@
+function marginal = dbn_marginal_from_bel(engine, i)
+% DBN_MARGINAL_FROM_BEL Compute the marginal on a node given the current belief state (bk)
+% marginal = dbn_marginal_from_bel(engine, i)
+  
+if engine.slice1
+  j = i;
+  c = clq_containing_nodes(engine.sub_engine1, j);
+else
+  bnet = bnet_from_engine(engine);
+  ss = length(bnet.intra);
+  j = i+ss;
+  c = clq_containing_nodes(engine.sub_engine, j);
+end
+assert(c >= 1);
+bigpot = engine.bel_clpot{c};
+
+pot = marginalize_pot(bigpot, j);
+marginal = pot_to_marginal(pot);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_update_bel.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_update_bel.m
new file mode 100644
index 00000000..0c8e02b5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_update_bel.m
@@ -0,0 +1,37 @@
+function [engine, loglik] = dbn_update_bel(engine, evidence)
+% DBN_UPDATE_BEL Update the belief state (bk)
+% [engine, loglik] = dbn_update_bel(engine, evidence)
+%
+% evidence{i,1} contains the evidence on node i in slice t-1
+% evidence{i,2} contains the evidence on node i in slice t
+
+oldbel = engine.bel;
+
+ss = size(evidence, 1);
+bnet = bnet_from_engine(engine);
+CPDpot = cell(1, ss);
+for n=1:ss
+  fam = family(bnet.dag, n, 2);
+  e = bnet.equiv_class(n, 2);
+  CPDpot{n} = convert_to_pot(bnet.CPD{e}, engine.pot_type, fam(:), evidence);
+end
+
+observed = ~isemptycell(evidence);
+onodes2 = find(observed(:));
+clqs = [engine.clq_ass_to_cluster(:,1); engine.clq_ass_to_node(:,2)];
+pots = [oldbel(:); CPDpot(:)];
+
+[clpot, loglik] = enter_soft_evidence(engine.sub_engine, clqs, pots, onodes2(:), engine.pot_type);
+
+C = length(engine.clusters);
+newbel = cell(1,C);
+for c=1:C
+  k = engine.clq_ass_to_cluster(c,2);
+  cl = engine.clusters{c};
+  newbel{c} = marginalize_pot(clpot{k}, cl+ss); % extract slice 2 posterior
+  newbel{c} = set_domain_pot(newbel{c}, cl); % shift back to slice 1 for re-use as prior
+end
+
+engine.bel = newbel;
+engine.bel_clpot = clpot;
+engine.slice1 = 0;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_update_bel1.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_update_bel1.m
new file mode 100644
index 00000000..a3b6cc79
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/dbn_update_bel1.m
@@ -0,0 +1,30 @@
+function [engine, loglik] = dbn_update_bel1(engine, evidence)
+% DBN_UPDATE_BEL1 Update  the initial belief state (bk)
+% engine = dbn_update_bel1(engine, evidence)
+%
+% evidence{i} has the evidence on node i for slice 1
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+CPDpot = cell(1,ss);      
+t = 1;
+for n=1:ss
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n, 1);
+  CPDpot{n} = convert_to_pot(bnet.CPD{e}, engine.pot_type, fam(:), evidence);
+end
+
+onodes = find(~isemptycell(evidence));
+
+[clpot, loglik] = enter_soft_evidence(engine.sub_engine1, engine.clq_ass_to_node1, CPDpot, onodes, engine.pot_type);
+
+C  = length(engine.clusters);
+newbel = cell(1,C);
+for c=1:C
+  k = engine.clq_ass_to_cluster1(c);
+  newbel{c} = marginalize_pot(clpot{k}, engine.clusters{c});
+end
+
+engine.bel = newbel;
+engine.bel_clpot = clpot;
+engine.slice1 = 1;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..f6057ba2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/enter_evidence.m
@@ -0,0 +1,48 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% this is unchanged from bk_inf_engine.
+% ENTER_EVIDENCE Add the specified evidence to the network (bk)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product instead of sum-product [0]
+% filter -   if 1, do filtering, else smoothing [0]
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+maximize = 0;
+filter = 0;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', maximize = args{i+1}; 
+     case 'filter', filter = args{i+1}; 
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+[ss T] = size(evidence);
+engine.filter = filter;
+engine.maximize = maximize;
+engine.T = T;
+
+if maximize
+  error('BK does not yet support max propagation')
+  % because it calls enter_soft_evidence, not enter_evidence
+end
+
+observed_bitv = ~isemptycell(evidence);
+onodes = find(observed_bitv);
+bnet = bnet_from_engine(engine);
+pot_type = determine_pot_type(bnet, onodes); 
+CPDpot = convert_dbn_CPDs_to_pots(bnet, evidence, pot_type);
+[engine.clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed_bitv, pot_type, filter);
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/enter_soft_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/enter_soft_evidence.m
new file mode 100644
index 00000000..e102a11e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/enter_soft_evidence.m
@@ -0,0 +1,115 @@
+function [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (bk)
+% [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+
+[ss T] = size(CPDpot);
+C = length(engine.clusters);
+S = length(engine.separators);
+Q = length(cliques_from_engine(engine.sub_engine));
+Q1 = length(cliques_from_engine(engine.sub_engine1));
+clpot = cell(Q,T);
+alpha = cell(C,T);
+
+% Forwards
+% The method is a generalization of the following HMM equation:
+% alpha(j,t) = normalise( (sum_i alpha(i,t-1) * transmat(i,j)) * obsmat(j,t) )
+% where alpha(j,t) = Pr(Q(t)=j | y(1:t))
+t = 1;
+[clpot(1:Q1,t), logscale(t)] = enter_soft_evidence(engine.sub_engine1, engine.clq_ass_to_node1(:), ...
+					   CPDpot(:,1), find(observed(:,1)), pot_type);
+for c=1:C
+  k = engine.clq_ass_to_cluster1(c);
+  alpha{c,t} = marginalize_pot(clpot{k,t}, engine.clusters{c});
+end
+
+%=== FH: For each separator s, divide some cluster potential by s's potential
+alpha_orig = alpha(:,t);
+for s=1:S
+  c = engine.cluster_ass_to_separator(s);
+  alpha{c,t} = divide_by_pot(alpha{c,t}, marginalize_pot(alpha_orig{c}, engine.separators{s}));
+end
+
+% For filtering, clpot{1} contains evidence on slice 1 only
+
+%fprintf('alphas t=%d\n', t);
+%for c=1:8
+%  temp = pot_to_marginal(alpha{c,t});
+%  temp.T
+%end
+
+% clpot{t} contains evidence from slices t-1, t for t > 1
+clqs = [engine.clq_ass_to_cluster(:,1); engine.clq_ass_to_node(:,2)];
+for t=2:T
+  pots = [alpha(:,t-1); CPDpot(:,t)];
+  [clpot(:,t), logscale(t)] = enter_soft_evidence(engine.sub_engine, clqs, pots, find(observed(:,t-1:t)),  pot_type);
+  for c=1:C
+    k = engine.clq_ass_to_cluster(c,2);
+    cl = engine.clusters{c};
+    alpha{c,t} = marginalize_pot(clpot{k,t}, cl+ss); % extract slice 2 posterior
+    alpha{c,t} = set_domain_pot(alpha{c,t}, cl); % shift back to slice 1 for re-use as prior
+  end
+  %=== FH: For each separator s, divide some cluster potential by s's potential
+  alpha_orig = alpha(:,t);
+  for s=1:S
+    c = engine.cluster_ass_to_separator(s);
+    alpha{c,t} = divide_by_pot(alpha{c,t}, marginalize_pot(alpha_orig{c}, engine.separators{s}));
+  end
+end
+
+loglik = sum(logscale); 
+
+if filter
+  return;
+end
+
+% Backwards
+% The method is a generalization of the following HMM equation:
+% beta(i,t) = (sum_j transmat(i,j) * obsmat(j,t+1) * beta(j,t+1))
+% where beta(i,t) = Pr(y(t+1:T) | Q(t)=i)
+t = T;
+bnet = bnet_from_engine(engine);
+beta = cell(C,T);
+for c=1:C
+  beta{c,t} = mk_initial_pot(pot_type, engine.clusters{c} + ss, bnet.node_sizes(:), bnet.cnodes(:), ...
+			     find(observed(:,t-1:t)));
+end
+%=== FH: For each separator s, divide some cluster potential by s's potential
+beta_orig = beta(:,t);
+for s=1:S
+  c = engine.cluster_ass_to_separator(s);
+  beta{c,t} = divide_by_pot(beta{c,t}, marginalize_pot(beta_orig{c}, engine.separators{s}+ss));
+end
+
+for t=T-1:-1:1
+  clqs = [engine.clq_ass_to_cluster(:,2); engine.clq_ass_to_node(:,2)];
+  pots = [beta(:,t+1); CPDpot(:,t+1)];
+  temp = enter_soft_evidence(engine.sub_engine, clqs, pots, find(observed(:,t:t+1)),  pot_type);
+  for c=1:C
+    k = engine.clq_ass_to_cluster(c,1);
+    cl = engine.clusters{c};
+    beta{c,t} = marginalize_pot(temp{k}, cl); % extract slice 1
+    beta{c,t} = set_domain_pot(beta{c,t}, cl + ss); % shift fwd to slice 2
+  end
+  %=== FH: For each separator s, divide some cluster potential by s's potential
+  beta_orig = beta(:,t);
+  for s=1:S
+    c = engine.cluster_ass_to_separator(s);
+    beta{c,t} = divide_by_pot(beta{c,t}, marginalize_pot(beta_orig{c}, engine.separators{s}+ss));
+  end
+end
+
+% Combine
+% The method is a generalization of the following HMM equation:
+% xi(i,j,t) = normalise( alpha(i,t) * transmat(i,j) * obsmat(j,t+1) * beta(j,t+1) )
+% where xi(i,j,t) = Pr(Q(t)=i, Q(t+1)=j | y(1:T))
+for t=1:T-1
+  clqs = [engine.clq_ass_to_cluster(:); engine.clq_ass_to_node(:,2)];
+  pots = [alpha(:,t); beta(:,t+1); CPDpot(:,t+1)];
+  clpot(:,t+1) = enter_soft_evidence(engine.sub_engine, clqs, pots, find(observed(:,t:t+1)),  pot_type);
+end
+% for smoothing, clpot{1} is undefined
+for k=1:Q1
+  clpot{k,1} = []; 
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/junk b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/junk
new file mode 100644
index 00000000..31e9cab8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/junk
@@ -0,0 +1,176 @@
+function engine = cbk_inf_engine(bnet, varargin)
+% Just the same as bk_inf_engine, but you can specify overlapping clusters.
+
+ss = length(bnet.intra);
+% set default params
+clusters = 'exact';
+
+if nargin >= 2
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'clusters',  clusters = args{i+1};
+     otherwise, error(['unrecognized argument ' args{i}])
+    end
+  end
+end
+
+if strcmp(clusters, 'exact')
+  %clusters = { compute_interface_nodes(bnet.intra, bnet.inter) };
+  clusters = { 1:ss };
+elseif strcmp(clusters, 'ff')
+  clusters = num2cell(1:ss);
+end
+
+
+% We need to insert the prior on the clusters in slice 1,
+% and extract the posterior on the clusters in slice 2.
+% We don't need to care about the separators, b/c they're subsets of the clusters.
+C = length(clusters);
+clusters2 = cell(1,2*C);
+clusters2(1:C) = clusters;
+for c=1:C
+  clusters2{c+C} = clusters{c} + ss;
+end
+
+onodes = bnet.observed;
+obs_nodes = [onodes(:) onodes(:)+ss];
+engine.sub_engine = jtree_inf_engine(bnet, 'clusters', clusters2);
+
+%FH >>>
+%Compute separators. 
+ns = bnet.node_sizes(:,1);
+ns(onodes) = 1;
+[clusters, separators] = build_jt(clusters, 1:length(ns), ns);
+S = length(separators);
+engine.separators = separators;
+
+%Compute size of clusters.
+cl_sizes = zeros(1,C);
+for c=1:C
+    cl_sizes(c) = prod(ns(clusters{c}));
+end
+
+%Assign separators to the smallest cluster subsuming them.
+engine.cluster_ass_to_separator = zeros(S, 1);
+for s=1:S
+    subsuming_clusters = [];
+    %find smaunk
+    
+    for c=1:C
+        if mysubset(separators{s}, clusters{c}) 
+            subsuming_clusters(end+1) = c;
+        end
+    end
+    c = argmin(cl_sizes(subsuming_clusters));
+    engine.cluster_ass_to_separator(s) = subsuming_clusters(c);
+end
+
+%<<< FH
+
+engine.clq_ass_to_cluster = zeros(C, 2);
+for c=1:C
+  engine.clq_ass_to_cluster(c,1) = clq_containing_nodes(engine.sub_engine, clusters{c});
+  engine.clq_ass_to_cluster(c,2) = clq_containing_nodes(engine.sub_engine, clusters{c}+ss);
+end
+engine.clusters = clusters;
+
+engine.clq_ass_to_node = zeros(ss, 2);
+for i=1:ss
+  engine.clq_ass_to_node(i, 1) = clq_containing_nodes(engine.sub_engine, i);
+  engine.clq_ass_to_node(i, 2) = clq_containing_nodes(engine.sub_engine, i+ss);
+end
+
+
+
+% Also create an engine just for slice 1
+bnet1 = mk_bnet(bnet.intra1, bnet.node_sizes_slice, 'discrete', myintersect(bnet.dnodes, 1:ss), ...
+		'equiv_class', bnet.equiv_class(:,1), 'observed', onodes);
+for i=1:max(bnet1.equiv_class)
+  bnet1.CPD{i} = bnet.CPD{i};
+end
+
+engine.sub_engine1 = jtree_inf_engine(bnet1, 'clusters', clusters);
+
+engine.clq_ass_to_cluster1 = zeros(1,C);
+for c=1:C
+  engine.clq_ass_to_cluster1(c) = clq_containing_nodes(engine.sub_engine1, clusters{c});
+end
+
+engine.clq_ass_to_node1 = zeros(1, ss);
+for i=1:ss
+  engine.clq_ass_to_node1(i) = clq_containing_nodes(engine.sub_engine1, i);
+end
+
+engine.clpot = []; % this is where we store the results between enter_evidence and marginal_nodes
+engine.filter = [];
+engine.maximize = [];
+engine.T = [];
+
+engine.bel = [];
+engine.bel_clpot = [];
+engine.slice1 = [];
+%engine.pot_type = 'cg';
+% hack for online inference so we can cope with hidden Gaussians and discrete
+% it will not affect the pot type used in enter_evidence
+engine.pot_type = determine_pot_type(bnet, onodes);
+
+engine = class(engine, 'cbk_inf_engine', inf_engine(bnet));
+
+
+
+
+function [cliques, seps, jt_size] = build_jt(cliques, vars, ns)
+% BUILD_JT connects the cliques into a jtree, computes the respective 
+% separators and the size of the resulting jtree.
+%
+% [cliques, seps, jt_size] = build_jt(cliques, vars, ns)
+% ns(i) has to hold the size of vars(i)
+% vars has to be a superset of the union of cliques.
+
+%======== Compute the jtree with tool from BNT. This wants the vars to be 1:N.
+%==== Map from nodes to their indices.
+%disp('Computing jtree for cliques with vars and ns:');
+%cliques
+%vars
+%ns'
+
+inv_nodes = sparse(1,max(vars));
+N = length(vars);
+for i=1:N
+    inv_nodes(vars(i)) = i;
+end
+
+tmp_cliques = cell(1,length(cliques));
+%==== Temporarily map clique vars to their indices.
+for i=1:length(cliques)
+    tmp_cliques{i} = inv_nodes(cliques{i});
+end
+
+%=== Compute the jtree, using BNT.
+[jtree, root, B, w] = cliques_to_jtree(tmp_cliques, ns);
+
+
+%======== Now, compute the separators between connected cliques and their weights.
+seps = {};
+s_w = [];
+[is,js] = find(jtree > 0);
+for k=1:length(is)
+  i = is(k); j = js(k);
+  sep = vars(find(B(i,:) & B(j,:))); % intersect(cliques{i}, cliques{j});
+  if i>j | length(sep) == 0, continue; end;
+  seps{end+1} = sep;
+  s_w(end+1) = prod(ns(inv_nodes(seps{end})));
+end
+
+cl_w = sum(w);
+sep_w = sum(s_w);
+assert(cl_w > sep_w, 'Weight of cliques must be bigger than weight of separators');
+
+jt_size = cl_w + sep_w;
+% jt.cliques = cliques;
+% jt.seps = seps;
+% jt.size = jt_size;
+% jt.ns = ns';
+% jt;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/marginal_family.m
new file mode 100644
index 00000000..e948b836
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/marginal_family.m
@@ -0,0 +1,25 @@
+function m = marginal_family(engine, i, t)
+% MARGINAL_FAMILY Compute the marginal on the specified family (bk)
+% marginal = marginal_family(engine, i, t)
+
+% This is just like inf_engine/marginal_family, except when we call
+% marginal_nodes, we provide a 4th argument, to tell it's a family.
+
+if nargin < 3, t = 1; end
+
+bnet = bnet_from_engine(engine);
+if t==1
+  m = marginal_nodes(engine, family(bnet.dag, i), t, 1);
+else
+  ss = length(bnet.intra);
+  fam = family(bnet.dag, i+ss);
+  if any(fam<=ss)
+    % i has a parent in the preceeding slice
+    % Hence the lowest numbered slice containing the family is t-1
+    m = marginal_nodes(engine, fam, t-1, 1);
+  else
+    % The family all fits inside slice t
+    % Hence shift the indexes back to slice 1
+    m = marginal_nodes(engine, fam-ss, t, 1);
+  end
+end     
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..30bf9a9d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/marginal_nodes.m
@@ -0,0 +1,67 @@
+function marginal = marginal_nodes(engine, nodes, t, fam)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (bk)
+%
+%   marginal = marginal_nodes(engine, i, t)
+% returns Pr(X(i,t) | Y(1:T)), where X(i,t) is the i'th node in the t'th slice.
+% If enter_evidence used filtering instead of smoothing, this will return  Pr(X(i,t) | Y(1:t)).
+%
+%   marginal = marginal_nodes(engine, query, t)
+% returns Pr(X(query(1),t), ... X(query(end),t) | Y(1:T)),
+% where X(q,t) is the q'th node in the t'th slice. If q > ss (slice size), this is equal
+% to X(q mod ss, t+1). That is, 't' specifies the time slice of the earliest node.
+% 'query' cannot span more than 2 time slices.
+% Example:
+% Consider a DBN with 2 nodes per slice.
+% Then t=2, nodes=[1 3] refers to node 1 in slice 2 and node 1 in slice 3.
+
+if nargin < 3, t = 1; end
+if nargin < 4, fam = 0; else fam = 1; end
+
+
+% clpot{t} contains slice t-1 and t
+% Example
+% clpot #: 1    2    3
+% slices:  1  1,2  2,3
+% For filtering, we must take care not to take future evidence into account.
+% For smoothing, clpot{1} does not exist.
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+
+nodes2 = nodes;
+if ~engine.filter
+  if t < engine.T
+    slice = t+1;
+  else % earliest t is T, so all nodes fit in one slice
+    slice = engine.T;
+    nodes2 = nodes + ss;
+  end
+else
+  if t == 1
+   slice = 1;
+  else
+    if all(nodes<=ss)
+      slice = t;
+      nodes2 = nodes + ss;
+    elseif t == engine.T
+      slice = t;
+    else
+      slice = t + 1;
+    end
+  end
+end
+  
+if engine.filter & t==1
+  c = clq_containing_nodes(engine.sub_engine1, nodes2, fam);
+else
+  c = clq_containing_nodes(engine.sub_engine, nodes2, fam);
+end
+assert(c >= 1);
+bigpot = engine.clpot{c, slice};
+
+pot = marginalize_pot(bigpot, nodes2);
+marginal = pot_to_marginal(pot);
+
+% we convert the domain to the unrolled numbering system
+% so that update_ess extracts the right evidence.
+marginal.domain = nodes+(t-1)*ss;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/update_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/update_engine.m
new file mode 100644
index 00000000..b36833a1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@cbk_inf_engine/update_engine.m
@@ -0,0 +1,11 @@
+function engine = update_engine(engine, newCPDs)
+% UPDATE_ENGINE Update the engine to take into account the new parameters (bk)
+% engine = update_engine(engine, newCPDs)
+
+engine.inf_engine = update_engine(engine.inf_engine, newCPDs);
+engine.sub_engine = update_engine(engine.sub_engine, newCPDs);
+
+bnet = bnet_from_engine(engine);
+eclass1 = bnet.equiv_class(:,1);
+engine.sub_engine1 = update_engine(engine.sub_engine1, newCPDs(1:max(eclass1)));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Entries
new file mode 100644
index 00000000..fda92284
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Entries
@@ -0,0 +1,8 @@
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_soft_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/ff_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/filter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/smooth_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D/Old////
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Repository
new file mode 100644
index 00000000..56fb63d3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@ff_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Entries
new file mode 100644
index 00000000..dd45ee37
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Entries
@@ -0,0 +1,4 @@
+/enter_soft_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_soft_evidence1.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Repository
new file mode 100644
index 00000000..5582c6dd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@ff_inf_engine/Old
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence.m
new file mode 100644
index 00000000..1e2acffb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence.m
@@ -0,0 +1,59 @@
+function [marginals, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (bk_ff)
+% [marginals, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+
+assert(pot_type == 'd');
+[ss T] = size(CPDpot);
+fwd = cell(ss,T);
+hnodes = engine.hnodes(:)';
+onodes = engine.onodes(:)';
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes;
+onodes2 = [onodes onodes+ss];
+ns(onodes2) = 1;
+
+logscale = zeros(1,T);
+local_logscale = zeros(1,length(hnodes));
+
+t = 1;
+for i=hnodes
+  fwd{i,t} = CPDpot{i,t};
+end
+for i=onodes
+  p = parents(bnet.dag, i);
+  assert(length(p)==1);
+  ev = marginalize_pot(CPDpot{i,t}, p);
+  fwd{p,t} = multiply_by_pot(fwd{p,t}, ev);
+end
+for i=hnodes
+  [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t});
+end
+logscale(t) = sum(local_logscale);
+
+for t=2:T
+  for i=hnodes
+    ps = parents(bnet.dag, i+ss);
+    assert(all(ps<=ss)); % in previous slice
+    prior = CPDpot{i,t};
+    for p=ps(:)'
+      prior = multiply_by_pot(prior, fwd{p,t-1});
+    end
+    fwd{i,t} = marginalize_pot(prior, i+ss);
+    fwd{i,t} = set_domain_pot(fwd{i,t}, i);
+  end
+  for i=onodes
+    p = parents(bnet.dag, i);
+    assert(length(p)==1);
+    temp = pot_to_marginal(CPDpot{i,t}); 
+    ev = dpot(p, ns(p), temp.T);
+    fwd{p,t} = multiply_by_pot(fwd{p,t}, ev);
+  end
+  
+  for i=hnodes
+    [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t});
+  end
+  logscale(t) = sum(local_logscale);
+end
+
+marginals = fwd;
+loglik = sum(logscale);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence1.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence1.m
new file mode 100644
index 00000000..b4ff1a02
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/enter_soft_evidence1.m
@@ -0,0 +1,94 @@
+function [marginals, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (ff)
+% [marginals, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+
+assert(pot_type == 'd');
+[ss T] = size(CPDpot);
+fwd = cell(ss,T);
+hnodes = engine.hnodes(:)';
+onodes = engine.onodes(:)';
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes;
+onodes2 = [onodes onodes+ss];
+ns(onodes2) = 1;
+
+logscale = zeros(1,T);
+H = length(hnodes);
+local_logscale = zeros(1,ss);
+
+obschild = zeros(1,ss);
+for i=hnodes
+  ocs = myintersect(children(bnet.dag, i), onodes);
+  assert(length(ocs)==1);
+  obschild(i) = ocs(1);
+end  
+  
+t = 1;
+for i=hnodes
+  fwd{i,t} = CPDpot{i,t};
+  c = obschild(i);
+  temp = pot_to_marginal(CPDpot{c,t}); 
+  ev = dpot(i, ns(i), temp.T);
+  fwd{i,t} = multiply_by_pot(fwd{i,t}, ev);
+  [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t});
+end
+logscale(t) = sum(local_logscale);
+
+for t=2:T
+  for i=hnodes
+    ps = parents(bnet.dag, i+ss);
+    assert(all(ps<=ss)); % in previous slice
+    prior = CPDpot{i,t};
+    for p=ps(:)'
+      prior = multiply_by_pot(prior, fwd{p,t-1});
+    end
+    fwd{i,t} = marginalize_pot(prior, i+ss);
+    fwd{i,t} = set_domain_pot(fwd{i,t}, i);
+    c = obschild(i);
+    temp = pot_to_marginal(CPDpot{c,t});
+    ev = dpot(i, ns(i), temp.T);
+    fwd{i,t} = multiply_by_pot(fwd{i,t}, ev);
+    [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t});
+  end
+  logscale(t) = sum(local_logscale);
+end
+
+loglik = sum(logscale);
+
+
+if filter
+  marginals = fwd;
+  return;
+end
+
+back = cell(ss,T);
+t = T;
+for i=hnodes
+  back{i,t} = dpot(i, ns(i));
+  back{i,t} = set_domain_pot(back{i,t}, i+ss);
+end
+for t=T-1:-1:1
+  for i=hnodes
+    pot = CPDpot{i,t+1};
+    pot = multiply_by_pot(pot, back{i,t+1});
+    c = obschild(i);
+    temp = pot_to_marginal(CPDpot{c,t+1});
+    ev = dpot(i, ns(i), temp.T);
+    pot = multiply_by_pot(pot, ev);
+    back{i,t} = marginalize_pot(pot, i);
+    back{i,t} = normalize_pot(back{i,t});
+    back{i,t} = set_domain_pot(back{i,t}, i+ss);
+  end
+end
+
+
+
+% COMBINE
+for t=1:T
+  for i=hnodes
+    back{i,t} = set_domain_pot(back{i,t}, i);
+    fwd{i,t} = multiply_by_pot(fwd{i,t}, back{i,t});
+    marginals{i,t} = normalize_pot(fwd{i,t});
+    %fwdback{i,t} = normalize_pot(multiply_pots(fwd{i,t}, back{i,t}));
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/marginal_family.m
new file mode 100644
index 00000000..99813571
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/Old/marginal_family.m
@@ -0,0 +1,38 @@
+function marginal = marginal_family(engine, i, t)
+% MARGINAL_FAMILY Compute the marginal on the specified family (ff)
+% marginal = marginal_family(engine, i, t)
+
+if nargin < 3, t = 1; end
+
+% The method is similar to the following HMM equation:
+% xi(i,j,t) = normalise( alpha(i,t) * transmat(i,j) * obsmat(j,t+1) * beta(j,t+1) )
+% where xi(i,j,t) = Pr(Q(t)=i, Q(t+1)=j | y(1:T))
+
+bnet = bnet_from_engine(engine);
+
+if myismember(i, engine.onodes)
+  ps = parents(bnet.dag, i);
+  p = ps(1);
+  marginal = pot_to_marginal(engine.marginals{p,t});
+  marginal.domain = [p i];
+  return;
+end
+
+if t==1
+  marginal = pot_to_marginal(engine.marginals{i,t});
+  return;
+end
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+pot = engine.CPDpot{i,t};
+c = engine.obschild(i);
+pot = multiply_by_pot(pot, engine.CPDpot{c,t});
+pot = multiply_by_pot(pot, engine.back{i,t});
+ps = parents(bnet.dag, i+ss);
+for p=ps(:)'
+  pot = multiply_by_pot(pot, engine.fwd{p,t-1});
+end
+marginal = pot_to_marginal(normalize_pot(pot));
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..7fa9fa9b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_evidence.m
@@ -0,0 +1,62 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (ff)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or
+% column vector)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product (not yet supported), else sum-product [0]
+% filter -   if 1, do filtering, else smoothing [0]
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+maximize = 0;
+filter = 0;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', maximize = args{i+1}; 
+     case 'filter', filter = args{i+1}; 
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+assert(~maximize);
+
+
+[ss T] = size(evidence);
+observed = ~isemptycell(evidence);
+bnet = bnet_from_engine(engine);
+%pot_type = determine_pot_type(find(observed(:,1)), bnet.cnodes_slice, bnet.intra);
+pot_type = determine_pot_type(bnet, observed);
+% we assume we can use the same pot_type in all slices
+
+CPDpot = convert_dbn_CPDs_to_pots(bnet, evidence, pot_type);
+
+% Now convert CPDs on observed nodes to be potentials just on their parents
+assert(pot_type == 'd');
+onodes = bnet.observed(:);
+ns = bnet.node_sizes_slice;
+ns(onodes) = 1;
+for t=1:T
+  for i=onodes
+    p = parents(bnet.dag, i);
+    %CPDpot{i,t} = set_domain_pot(CPDpot{i,t}, p); % leaves size too long
+    temp = pot_to_marginal(CPDpot{i,t});
+    CPDpot{i,t} = dpot(p, ns(p), temp.T); % assumes pot_type = d
+  end
+end
+
+[engine.marginals, engine.fwd, engine.back, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter);
+
+engine.CPDpot = CPDpot;
+engine.filter = filter;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_soft_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_soft_evidence.m
new file mode 100644
index 00000000..db16f39b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/enter_soft_evidence.m
@@ -0,0 +1,11 @@
+function [marginals, fwd, back, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (ff)
+% [marginals, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+
+if filter
+  [fwd, loglik] = filter_evidence(engine, CPDpot, observed, pot_type);
+  marginals = fwd;
+  back = [];
+else
+  [marginals, fwd, back, loglik] = smooth_evidence(engine, CPDpot, observed, pot_type);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/ff_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/ff_inf_engine.m
new file mode 100644
index 00000000..ade26106
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/ff_inf_engine.m
@@ -0,0 +1,44 @@
+function engine = ff_inf_engine(bnet)
+% FF_INF_ENGINE Factored frontier inference engine for DBNs
+% engine = ff_inf_engine(bnet)
+%
+% The model must be topologically isomorphic to an HMM.
+% In addition, each hidden node is assumed to have at most one observed child,
+% and each observed child is assumed to have exactly one hidden parent.
+%
+% For details of this algorithm, see
+%  "The Factored Frontier Algorithm for Approximate Inference in DBNs",
+%   Kevin Murphy and Yair Weiss, UAI 2001.
+%
+% THIS IS HIGHLY EXPERIMENTAL CODE!
+
+ss = length(bnet.intra);
+onodes = bnet.observed;
+hnodes = mysetdiff(1:ss, onodes);
+
+[persistent_nodes, transient_nodes] = partition_dbn_nodes(bnet.intra, bnet.inter);
+assert(isequal(onodes, transient_nodes));
+assert(isequal(hnodes, persistent_nodes));
+
+engine.onodes = onodes;
+engine.hnodes = hnodes;
+engine.marginals = [];
+engine.fwd = [];
+engine.back = [];
+engine.CPDpot = [];
+engine.filter = [];
+
+obschild = zeros(1,ss);
+for i=engine.hnodes(:)'
+  %ocs = myintersect(children(bnet.dag, i), onodes);
+  ocs = children(bnet.intra, i);
+  assert(length(ocs) <= 1);
+  if length(ocs)==1
+    obschild(i) = ocs(1);
+  end
+end  
+engine.obschild = obschild;
+
+
+engine = class(engine, 'ff_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/filter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/filter_evidence.m
new file mode 100644
index 00000000..3dd4835c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/filter_evidence.m
@@ -0,0 +1,48 @@
+function [fwd, loglik] = filter_evidence(engine, CPDpot, observed, pot_type)
+% [fwd, loglik] = filter_evidence(engine, CPDpot, observed, pot_type) (ff)
+
+[ss T] = size(CPDpot);
+fwd = cell(ss,T);
+hnodes = engine.hnodes(:)';
+onodes = engine.onodes(:)';
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes;
+onodes2 = [onodes onodes+ss];
+ns(onodes2) = 1;
+
+logscale = zeros(1,T);
+H = length(hnodes);
+local_logscale = zeros(1,ss);
+  
+t = 1;
+for i=hnodes
+  fwd{i,t} = CPDpot{i,t};
+  c = engine.obschild(i);
+  if c > 0
+    fwd{i,t} = multiply_by_pot(fwd{i,t}, CPDpot{c, t});
+  end
+  [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t});
+end
+logscale(t) = sum(local_logscale);
+
+for t=2:T
+  for i=hnodes
+    ps = parents(bnet.dag, i+ss);
+    assert(all(ps<=ss)); % in previous slice
+    prior = CPDpot{i,t};
+    for p=ps(:)'
+      prior = multiply_by_pot(prior, fwd{p,t-1});
+    end
+    fwd{i,t} = marginalize_pot(prior, i+ss);
+    fwd{i,t} = set_domain_pot(fwd{i,t}, i);
+    c = engine.obschild(i);
+    if c > 0
+      fwd{i,t} = multiply_by_pot(fwd{i,t}, CPDpot{c,t});
+    end
+    [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t});
+  end
+  logscale(t) = sum(local_logscale);
+end
+
+loglik = sum(logscale);
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_family.m
new file mode 100644
index 00000000..bdc783b7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_family.m
@@ -0,0 +1,44 @@
+function marginal = marginal_family(engine, i, t)
+% MARGINAL_FAMILY Compute the marginal on the specified family (ff)
+% marginal = marginal_family(engine, i, t)
+
+
+if engine.filter
+  error('can''t currently use marginal_family when filtering with ff');
+end
+
+if nargin < 3, t = 1; end
+
+% The method is similar to the following HMM equation:
+% xi(i,j,t) = normalise( alpha(i,t) * transmat(i,j) * obsmat(j,t+1) * beta(j,t+1) )
+% where xi(i,j,t) = Pr(Q(t)=i, Q(t+1)=j | y(1:T))
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+
+if myismember(i, engine.onodes)
+  ps = parents(bnet.dag, i);
+  p = ps(1);
+  marginal = pot_to_marginal(engine.marginals{ps(1),t});
+  fam = ([ps i]) + (t-1)*ss;
+elseif t==1
+  marginal = pot_to_marginal(engine.marginals{i,t});
+  fam = i + (t-1)*ss;
+else
+  pot = engine.CPDpot{i,t};
+  c = engine.obschild(i);
+  if c>0
+    pot = multiply_by_pot(pot, engine.CPDpot{c,t});
+  end
+  pot = multiply_by_pot(pot, engine.back{i,t});
+  ps = parents(bnet.dag, i+ss);
+  for p=ps(:)'
+    pot = multiply_by_pot(pot, engine.fwd{p,t-1});
+  end
+  marginal = pot_to_marginal(normalize_pot(pot));
+  fam = ([ps i+ss]) + (t-2)*ss;
+end
+
+% we convert the domain to the unrolled numbering system
+% so that update_ess extracts the right evidence.
+marginal.domain = fam;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..f65a3bec
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/marginal_nodes.m
@@ -0,0 +1,20 @@
+function marginal = marginal_nodes(engine, nodes, t)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (ff)
+% marginal = marginal_nodes(engine, i, t)
+% returns Pr(X(i,t) | Y(1:T)), where X(i,t) is the i'th node in the t'th slice.
+% If enter_evidence used filtering instead of smoothing, this will return  Pr(X(i,t) | Y(1:t)).
+
+if nargin < 3, t = 1; end
+assert(length(nodes)==1);
+i = nodes(end);
+if myismember(i, engine.hnodes)
+  marginal = pot_to_marginal(engine.marginals{i,t});
+else
+  marginal = pot_to_marginal(dpot(i, 1, 1)); % observed
+end
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+% we convert the domain to the unrolled numbering system
+% so that update_ess extracts the right evidence.
+marginal.domain = nodes+(t-1)*ss;   
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/smooth_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/smooth_evidence.m
new file mode 100644
index 00000000..782f07aa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@ff_inf_engine/smooth_evidence.m
@@ -0,0 +1,89 @@
+function [marginals, fwd, back, loglik] = smooth_evidence(engine, CPDpot, observed, pot_type)
+% [marginals, fwd, back, loglik] = smooth_evidence(engine, CPDpot, observed, pot_type) (ff)
+
+error('ff smoothing is broken');
+
+[ss T] = size(CPDpot);
+fwd = cell(ss,T);
+hnodes = engine.hnodes(:)';
+onodes = engine.onodes(:)';
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes;
+onodes2 = [onodes onodes+ss];
+ns(onodes2) = 1;
+
+logscale = zeros(1,T);
+H = length(hnodes);
+local_logscale = zeros(1,ss);
+  
+t = 1;
+for i=hnodes
+  fwd{i,t} = CPDpot{i,t};
+  c = engine.obschild(i);
+  if 0 %  c > 0
+    fwd{i,t} = multiply_by_pot(fwd{i,t}, CPDpot{c, t});
+  end
+  [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t});
+end
+logscale(t) = sum(local_logscale);
+
+for t=2:T
+  for i=hnodes
+    ps = parents(bnet.dag, i+ss);
+    assert(all(ps<=ss)); % in previous slice
+    prior = CPDpot{i,t};
+    for p=ps(:)'
+      prior = multiply_by_pot(prior, fwd{p,t-1});
+    end
+    fwd{i,t} = marginalize_pot(prior, i+ss);
+    fwd{i,t} = set_domain_pot(fwd{i,t}, i);
+    c = engine.obschild(i);
+    if 0 % c > 0
+      fwd{i,t} = multiply_by_pot(fwd{i,t}, CPDpot{c,t});
+    end
+    [fwd{i,t}, local_logscale(i)] = normalize_pot(fwd{i,t});
+  end
+  logscale(t) = sum(local_logscale);
+end
+
+loglik = sum(logscale);
+
+back = cell(ss,T);
+t = T;
+for i=hnodes
+  pot = dpot(i, ns(i));
+  cs = children(bnet.intra, i);
+  for c=cs(:)'
+    pot = multiply_pots(pot, CPDpot{c,t});
+  end
+  back{i,t} = marginalize_pot(pot, i);
+  back{i,t} = normalize_pot(back{i,t});
+  back{i,t} = set_domain_pot(back{i,t}, i+ss);
+end
+for t=T-1:-1:1
+  for i=hnodes
+    pot = dpot(i, ns(i));
+    cs = children(bnet.inter, i);
+    for c=cs(:)'
+      pot = multiply_pots(pot, back{c,t+1});
+      pot = multiply_pots(pot, CPDpot{c,t+1});
+    end
+    cs = children(bnet.intra, i);
+    for c=cs(:)'
+      pot = multiply_pots(pot, CPDpot{c,t});
+    end
+    back{i,t} = marginalize_pot(pot, i);
+    back{i,t} = normalize_pot(back{i,t});
+    back{i,t} = set_domain_pot(back{i,t}, i+ss);
+  end
+end
+
+
+% COMBINE
+for t=1:T
+  for i=hnodes
+    back{i,t} = set_domain_pot(back{i,t}, i);
+    fwd{i,t} = multiply_by_pot(fwd{i,t}, back{i,t});
+    marginals{i,t} = normalize_pot(fwd{i,t});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/CVS/Entries
new file mode 100644
index 00000000..79297e05
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/CVS/Entries
@@ -0,0 +1,7 @@
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_soft_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/frontier_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/set_fwdback.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/CVS/Repository
new file mode 100644
index 00000000..0e85f66f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@frontier_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..bd30a57c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/enter_evidence.m
@@ -0,0 +1,44 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (frontier)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product (not yet supported), else sum-product [0]
+% filter -   if 1, do filtering, else smoothing [0]
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+maximize = 0;
+filter = 0;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', maximize = args{i+1}; 
+     case 'filter', filter = args{i+1}; 
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+assert(~maximize);
+
+[ss T] = size(evidence);
+bnet = bnet_from_engine(engine);
+onodes = find(~isemptycell(evidence));
+cnodes = unroll_set(bnet.cnodes(:), ss, T);
+pot_type = determine_pot_type(bnet, onodes);
+
+CPDpot = convert_dbn_CPDs_to_pots(bnet, evidence, pot_type);
+
+[engine.fwdback, loglik, engine.fwd_frontier, engine.back_frontier] = ...
+    enter_soft_evidence(engine, CPDpot, onodes, pot_type, filter);
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/enter_soft_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/enter_soft_evidence.m
new file mode 100644
index 00000000..8da339c7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/enter_soft_evidence.m
@@ -0,0 +1,142 @@
+function [fwdback, loglik, fwd_frontier, back_frontier] = enter_soft_evidence(engine, CPD, onodes, pot_type, filter)
+% ENTER_SOFT_EVIDENCE Add soft evidence to network (frontier)
+% [fwdback, loglik] = enter_soft_evidence(engine, CPDpot, onodes, filter)
+
+if nargin < 3, filter = 0; end
+
+[ss T] = size(CPD);
+bnet = bnet_from_engine(engine);
+ns = repmat(bnet.node_sizes_slice(:), 1, T);
+cnodes = unroll_set(bnet.cnodes(:), ss, T);
+
+% FORWARDS
+fwd = cell(ss,T);
+ll = zeros(1,T);
+S = 2*ss; % num. intermediate frontiers to get from t to t+1
+frontier = cell(S,T);
+
+% Start with empty frontier, and add each node in slice 1
+init = mk_initial_pot(pot_type, [], ns, cnodes, onodes);  
+t = 1;
+s = 1;
+j = 1;
+frontier{s,t} = update(init, j, 1, CPD{j}, engine.fdom1{s}, pot_type, ns, cnodes, onodes);
+fwd{j} = frontier{s,t};
+for s=2:ss
+  j = s; % add node j at step s
+  frontier{s,t} = update(frontier{s-1,t}, j, 1, CPD{j}, engine.fdom1{s}, pot_type, ns, cnodes, onodes);
+  fwd{j} = frontier{s,t};
+end
+frontier{S,t} = frontier{ss,t};
+[frontier{S,t}, ll(1)] = normalize_pot(frontier{S,t});
+
+% Now move frontier from slice to slice
+OPS = engine.ops;
+add = OPS>0;
+nodes = [zeros(S,1) unroll_set(abs(OPS(:)), ss, T-1)];
+for t=2:T
+  offset = (t-2)*ss;
+  for s=1:S
+    if s==1
+      prev_ndx = (t-2)*S + S; % S,t-1
+    else
+      prev_ndx = (t-1)*S + s-1; % s-1,t
+    end
+    j = nodes(s,t);
+    frontier{s,t} = update(frontier{prev_ndx}, j, add(s), CPD{j}, engine.fdom{s}+offset, pot_type, ns, cnodes, onodes);
+    if add(s)
+      fwd{j} = frontier{s,t};
+    end
+  end
+  [frontier{S,t}, ll(t)] = normalize_pot(frontier{S,t});
+end
+loglik = sum(ll);
+
+
+fwd_frontier = frontier;
+
+if filter
+  fwdback = fwd;
+  return;
+end
+
+
+% BACKWARDS
+back = cell(ss,T);
+add = ~add; % forwards add = backwards remove 
+frontier = cell(S,T+1);
+t = T;
+dom = (1:ss) + (t-1)*ss;
+frontier{1,T+1} = mk_initial_pot(pot_type, dom, ns, cnodes, onodes); % all 1s for last slice
+for t=T:-1:2
+  offset = (t-2)*ss;
+  for s=S:-1:1 % reverse order
+    if s==S
+      prev_ndx = t*S + 1; % 1,t+1
+    else
+      prev_ndx = (t-1)*S + (s+1); % s+1,t
+    end
+    j = nodes(s,t);
+    if ~add(s)
+      back{j} = frontier{prev_ndx}; % save frontier before removing
+    end
+    frontier{s,t} = rev_update(frontier{prev_ndx}, t, s, j, add(s), CPD{j}, engine.fdom{s}+offset, pot_type, ns, cnodes, onodes);
+  end
+  frontier{1,t} = normalize_pot(frontier{1,t});
+end
+% Remove each node in first slice until left with empty set
+t = 1;
+frontier{ss+1,t} = frontier{1,2};
+add = 0;
+for s=ss:-1:1
+  j = s; % remove node j at step s
+  back{j} = frontier{s+1,t};
+  frontier{s,t} = rev_update(frontier{s+1,t}, t, s, j, add, CPD{j}, 1:s, pot_type, ns, cnodes, onodes);
+end
+
+% COMBINE
+for t=1:T
+  for i=1:ss
+    %fwd{i,t} = multiply_by_pot(fwd{i,t}, back{i,t});
+    %fwdback{i,t} = normalize_pot(fwd{i,t});
+    fwdback{i,t} = normalize_pot(multiply_pots(fwd{i,t}, back{i,t}));
+  end
+end
+
+back_frontier = frontier;
+
+%%%%%%%%%%
+function new_frontier = update(old_frontier, j, add, CPD, newdom, pot_type, ns, cnodes, onodes)
+
+if add
+  new_frontier = mk_initial_pot(pot_type, newdom, ns, cnodes, onodes);      
+  new_frontier = multiply_by_pot(new_frontier, old_frontier);
+  new_frontier = multiply_by_pot(new_frontier, CPD);
+else
+  new_frontier = marginalize_pot(old_frontier, mysetdiff(domain_pot(old_frontier), j));    
+end
+
+
+%%%%%%
+function new_frontier = rev_update(old_frontier, t, s, j, add, CPD, junk, pot_type, ns, cnodes, onodes)
+
+olddom = domain_pot(old_frontier);
+assert(isequal(junk, olddom));
+
+if add
+  % add: extend domain to include j by multiplying by 1
+  newdom = myunion(olddom, j);
+  new_frontier = mk_initial_pot(pot_type, newdom, ns, cnodes, onodes);      
+  new_frontier = multiply_by_pot(new_frontier, old_frontier);
+  %fprintf('t=%d, s=%d, add %d to %s to make %s\n', t, s, j, num2str(olddom), num2str(newdom));
+else 
+  % remove: multiply in CPT and then marginalize out j
+  % parents of j are guaranteed to be in old_frontier, else couldn't have added j on fwds pass
+  old_frontier = multiply_by_pot(old_frontier, CPD);
+  newdom = mysetdiff(olddom, j);
+  new_frontier = marginalize_pot(old_frontier, newdom);
+  %newdom2 = domain_pot(new_frontier);
+  %fprintf('t=%d, s=%d, rem %d from %s to make %s\n', t, s, j, num2str(olddom), num2str(newdom2));
+end
+
+       
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/frontier_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/frontier_inf_engine.m
new file mode 100644
index 00000000..fd550579
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/frontier_inf_engine.m
@@ -0,0 +1,121 @@
+function engine = frontier_inf_engine(bnet)
+% FRONTIER_INF_ENGINE Inference engine for DBNs which which uses the frontier algorithm.
+% engine = frontier_inf_engine(bnet)
+%
+% The frontier algorithm extends the forwards-backwards algorithm to DBNs in the obvious way,
+% maintaining a joint distribution (frontier) over all the nodes in a time slice.
+% When all the hidden nodes in the DBN are persistent (have children in the next time slice),
+% its theoretical running time is often similar to that of the junction tree algorithm,
+% although in practice, this algorithm seems to very slow (at least in matlab).
+% However, it is extremely simple to describe and implement.
+%
+% Suppose there are n binary nodes per slice, so the frontier takes O(2^n) space.
+% Each time step takes between O(n 2^{n+1}) and O(n 2^{2n}) operations, depending on the graph structure.
+% The lower bound is achieved by a set of n independent chains, as in a factorial HMM.
+% The upper bound is achieved by a set of n fully interconnected chains, as in an HMM.
+%
+% The factor of n arises because we need to multiply in each CPD from slice t+1.
+% The second factor depends on the size of the frontier to which we add the new node.
+% In an FHMM, once we have added X(i,t+1), we can marginalize out X(i,t) from the frontier, since
+% no other nodes depend on it; hence the frontier never contains more than n+1 nodes.
+% In a fully coupled HMM, we must leave X(i,t) in the frontier until all X(j,t+1) have been
+% added; hence the frontier will contain 2*n nodes at its peak.
+%
+% For details, see
+%   "The Factored Frontier Algorithm for Approximate Inference in DBNs",
+%   Kevin Murphy and Yair Weiss, UAI 01.
+
+ns = bnet.node_sizes_slice;
+onodes = bnet.observed;
+ns(onodes) = 1;
+ss = length(bnet.intra);
+
+[engine.ops, engine.fdom] = best_first_frontier_seq(ns, bnet.dag);
+engine.ops1 = 1:ss;
+
+engine.fwdback = [];
+engine.fwd_frontier = [];
+engine.back_frontier = [];
+
+engine.fdom1 = cell(1,ss);
+for s=1:ss
+  engine.fdom1{s} = 1:s;
+end
+
+engine = class(engine, 'frontier_inf_engine', inf_engine(bnet));
+
+
+%%%%%%%%%
+
+function [ops, frontier_set] = best_first_frontier_seq(ns, dag)
+% BEST_FIRST_FRONTIER_SEQ Do a greedy search for the sequence of additions/removals to the frontier.
+% [ops, frontier_set] = best_first_frontier_seq(ns, dag)
+%
+% We maintain 3 sets: the frontier (F), the right set (R), and the left set (L).
+% The invariant is that the nodes in R are d-separated from L given F.
+% We start with slice 1 in F and slice 2 in R.
+% The goal is to move slice 1 from F to L, and slice 2 from R to F, so as to minimize the size
+% of the frontier at each step, where the size(F) = product of the node-sizes of nodes in F.
+% A node may be removed (from F to L) if it has no children in R.
+% A node may be added (from R to F) if its parents are in F.
+%
+% ns(i) = num. discrete values node i can take on (i=1..ss, where ss = slice size)
+% dag is the (2*ss) x (2*ss) adjacency matrix for the 2-slice DBN.
+
+% Example:
+%
+% 4    9
+% ^    ^
+% |    |
+% 2 -> 7
+% ^    ^
+% |    |
+% 1 -> 6
+% |    |
+% v    v
+% 3 -> 8
+% |    |
+% v    V
+% 5    10
+%
+% ops = -4, -5, 6, -1, 7, -2, 8, -3, 9, 10
+
+ss = length(ns);
+ns = [ns(:)' ns(:)'];
+ops = zeros(1,ss);
+L = []; F = 1:ss; R = (1:ss)+ss;
+frontier_set = cell(1,2*ss);
+for s=1:2*ss
+  remcost = inf*ones(1,2*ss);
+  %disp(['L: ' num2str(L) ', F: ' num2str(F) ', R: ' num2str(R)]);
+  maybe_removable = myintersect(F, 1:ss);
+  for n=maybe_removable(:)'
+    cs = children(dag, n);
+    if isempty(myintersect(cs, R))
+      remcost(n) = prod(ns(mysetdiff(F, n)));
+    end
+  end
+  %remcost
+  if any(remcost < inf)
+    n = argmin(remcost);
+    ops(s) = -n;
+    L = myunion(L, n);
+    F = mysetdiff(F, n);
+  else
+    addcost = inf*ones(1,2*ss);
+    for n=R(:)'
+      ps = parents(dag, n);
+      if mysubset(ps, F)
+	addcost(n) = prod(ns(myunion(F, [ps n])));
+      end
+    end
+    %addcost
+    assert(any(addcost < inf));
+    n = argmin(addcost);
+    ops(s) = n;
+    R  = mysetdiff(R, n);
+    F = myunion(F, n);
+  end
+  %fprintf('op at step %d = %d\n\n', s, ops(s));
+  frontier_set{s} = F;
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/marginal_family.m
new file mode 100644
index 00000000..4d28263b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/marginal_family.m
@@ -0,0 +1,7 @@
+function marginal = marginal_family(engine, i, t)
+% MARGINAL_FAMILY Compute the marginal on node i in slice t and its parents  (frontier)
+% marginal = marginal_family(engine, i, t)
+
+bnet = bnet_from_engine(engine);    
+fam = family(bnet.dag, i, t);
+marginal = pot_to_marginal(normalize_pot(marginalize_pot(engine.fwdback{i,t}, fam)));
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..898d1130
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/marginal_nodes.m
@@ -0,0 +1,21 @@
+function marginal = marginal_nodes(engine, nodes, t)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (frontier)
+% marginal = marginal_nodes(engine, nodes, t)
+%
+% 't' specifies the time slice of the earliest node in 'nodes'.
+% 'nodes' cannot span more than 2 time slices.
+%
+% Example:
+% Consider a DBN with 2 nodes per slice.
+% Then t=2, nodes=[1 3] refers to node 1 in slice 2 and node 1 in slice 3,
+% i.e., nodes 3 and 5 in the unrolled network,
+
+if nargin < 3, t = 1; end
+assert(length(nodes)==1);
+i = nodes(1);
+bigpot = engine.fwdback{i,t};
+bnet = bnet_from_engine(engine);
+ss  = length(bnet.intra);
+nodes = nodes + (t-1)*ss;
+%if t > 1, nodes = nodes + ss; end
+marginal = pot_to_marginal(marginalize_pot(bigpot, nodes));
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/set_fwdback.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/set_fwdback.m
new file mode 100644
index 00000000..6752d827
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@frontier_inf_engine/set_fwdback.m
@@ -0,0 +1,8 @@
+function engine = set_fwdback(engine, fb)
+% SET_FWDBACK Set the field 'fwdback', which contains the frontiers after propagation
+% engine = set_fwdback(engine, fb)
+%
+% This is used by frontier_fast_inf_engine/enter_evidence
+% as a workaround for Matlab's annoying privacy control
+    
+engine.fwdback = fb;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/CVS/Entries
new file mode 100644
index 00000000..e1ab6d00
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/CVS/Entries
@@ -0,0 +1,9 @@
+/enter_evidence.m/1.2/Sat Sep 17 17:00:30 2005//
+/find_mpe.m/1.1.1.1/Thu Jun 20 00:18:24 2002//
+/fwdback_twoslice.m/1.1/Sat Nov 26 01:24:09 2005//
+/hmm_inf_engine.m/1.1.1.1/Thu Nov 14 20:05:36 2002//
+/marginal_family.m/1.1.1.1/Thu Nov 14 20:05:36 2002//
+/marginal_nodes.m/1.1.1.1/Thu Nov 14 20:03:28 2002//
+/update_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D/Old////
+D/private////
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/CVS/Repository
new file mode 100644
index 00000000..b7392efa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@hmm_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/CVS/Entries
new file mode 100644
index 00000000..528b5843
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/CVS/Entries
@@ -0,0 +1,4 @@
+/dhmm_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/CVS/Repository
new file mode 100644
index 00000000..f82b2bea
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@hmm_inf_engine/Old
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/dhmm_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/dhmm_inf_engine.m
new file mode 100644
index 00000000..2b0c8810
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/dhmm_inf_engine.m
@@ -0,0 +1,34 @@
+function engine = dhmm_inf_engine(bnet, onodes)
+% DHMM_INF_ENGINE Inference engine for discrete DBNs which uses the forwards-backwards algorithm.
+% engine = dhmm_inf_engine(bnet, onodes)
+%
+% 'onodes' specifies which nodes are observed; these must be leaves, and can be discrete or continuous.
+% The remaining nodes are all hidden, and must be discrete.
+% The DBN is converted to an HMM, with a single meganode, but which may have factored obs.
+
+ss = length(bnet.intra);
+hnodes = mysetdiff(1:ss, onodes);
+evidence = cell(ss, 2);
+ns = bnet.node_sizes;
+Q = prod(ns(hnodes));
+tmp = dpot_to_table(compute_joint_pot(bnet, hnodes, evidence));
+engine.startprob = reshape(tmp, Q, 1);
+tmp = dpot_to_table(compute_joint_pot(bnet, [hnodes hnodes+ss], evidence));
+engine.transprob = mk_stochastic(reshape(tmp, Q, Q));
+engine.obsprob = cell(1, length(onodes));
+for i=1:length(onodes)
+  tmp = dpot_to_table(compute_joint_pot(bnet, [hnodes onodes(i)], evidence));
+  O = ns(onodes(i));
+  engine.obsprob{i} = mk_stochastic(reshape(tmp, Q, O));
+end
+
+% This is where we will store the results between enter_evidence and marginal_nodes
+engine.gamma = [];
+engine.xi = [];
+
+engine.onodes = onodes;
+engine.hnodes = hnodes;
+engine.maximize = [];
+
+engine = class(engine, 'dhmm_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/marginal_family.m
new file mode 100644
index 00000000..681e1591
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/marginal_family.m
@@ -0,0 +1,31 @@
+function marginal = marginal_family(engine, i, t, add_ev)
+% MARGINAL_FAMILY Compute the marginal on the specified family  (hmm)
+% marginal = marginal_nodes(engine, i, t, add_ev)
+%
+
+if nargin < 3, t = 1; end
+if nargin < 4, add_ev = 0; end
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+if t==1
+ fam = family(bnet.dag, i);
+ bigpot = engine.one_slice_marginal{t};
+ nodes = fam;
+else
+  fam = family(bnet.dag, i+ss);
+  if any(fam <= ss) % family spans 2 slices
+    bigpot = engine.two_slice_marginal{t-1}; % t-1 and t
+    nodes = fam + (t-2)*ss;
+  else
+    bigpot = engine.one_slice_marginal{t};
+    nodes = fam-ss + (t-1)*ss;
+  end
+end
+
+marginal = pot_to_marginal(marginalize_pot(bigpot, nodes, engine.maximize));
+
+if add_ev
+  marginal = add_ev_to_dmarginal(marginal, engine.evidence, engine.node_sizes);
+end    
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/marginal_nodes.m
new file mode 100644
index 00000000..4b8d6008
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/Old/marginal_nodes.m
@@ -0,0 +1,30 @@
+function marginal = marginal_nodes(engine, nodes, t, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (hmm)
+% marginal = marginal_nodes(engine, nodes, t, add_ev)
+%
+% 't' specifies the time slice of the earliest node in 'nodes'.
+% 'nodes' cannot span more than 2 time slices.
+%
+% Example:
+% Consider a DBN with 2 nodes per slice.
+% Then t=2, nodes=[1 3] refers to node 1 in slice 2 and node 1 in slice 3,
+% i.e., nodes 3 and 5 in the unrolled network,
+
+if nargin < 3, t = 1; end
+if nargin < 4, add_ev = 0; end
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+if all(nodes <= ss)
+  bigpot = engine.one_slice_marginal{t};
+else
+  bigpot = engine.two_slice_marginal{t};
+end
+
+nodes = nodes + (t-1)*ss;
+marginal = pot_to_marginal(marginalize_pot(bigpot, nodes, engine.maximize));
+
+if add_ev
+  marginal = add_ev_to_dmarginal(marginal, engine.evidence, engine.node_sizes);
+end    
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..8af97edf
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/enter_evidence.m
@@ -0,0 +1,64 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (hmm)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product (not yet supported), else sum-product [0]
+% filter   - if 1, does filtering, else smoothing [0]
+% oneslice - 1 means only compute marginals on nodes within a single slice [0]
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+maximize = 0;
+filter = 0;
+oneslice = 0;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', maximize = args{i+1}; 
+     case 'filter',  filter = args{i+1}; 
+     case 'oneslice', oneslice = args{i+1};
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+[ss T] = size(evidence);
+engine.maximize = maximize;
+engine.evidence = evidence;
+bnet = bnet_from_engine(engine);
+engine.node_sizes = repmat(bnet.node_sizes_slice(:), [1 T]);
+
+obs_bitv = ~isemptycell(evidence(:));
+bitv = reshape(obs_bitv, ss, T);
+for t=1:T
+  onodes = find(bitv(:,t));
+  if ~isequal(onodes, bnet.observed(:))
+    error(['dbn was created assuming observed nodes per slice were '...
+	   num2str(bnet.observed(:)')  ' but the evidence in slice ' num2str(t) ...
+	   ' has observed nodes ' num2str(onodes(:)')]);
+  end
+end
+
+obslik = mk_hmm_obs_lik_matrix(engine, evidence);
+
+%[alpha, beta, gamma, loglik, xi] = fwdback(engine.startprob, engine.transprob, obslik, ...
+[alpha, beta, gamma, loglik, xi] = fwdback_twoslice(engine, engine.startprob,...
+                                                    engine.transprob, obslik, ...
+                                                    'maximize', maximize, 'fwd_only', filter, ...
+                                                    'compute_xi', ~oneslice);
+
+engine.one_slice_marginal = gamma; % gamma(:,t) for t=1:T
+if ~oneslice
+  Q = size(gamma,1);
+  engine.two_slice_marginal = reshape(xi, [Q*Q T-1]); % xi(:,t) for t=1:T-1
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/find_mpe.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/find_mpe.m
new file mode 100644
index 00000000..ba2cba74
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/find_mpe.m
@@ -0,0 +1,16 @@
+function mpe = find_mpe(engine, evidence)
+% FIND_MPE Find the most probable explanation (Viterbi)
+% mpe = enter_evidence(engine, evidence, ...)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+%
+
+obslik = mk_hmm_obs_lik_matrix(engine, evidence);
+path = viterbi_path(engine.startprob, engine.transprob, obslik);
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes_slice;
+ns(bnet.observed) = 1;
+ass = ind2subv(ns, path);
+mpe = num2cell(ass');
+mpe(bnet.observed,:) = evidence(bnet.observed,:);
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/fwdback_twoslice.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/fwdback_twoslice.m
new file mode 100644
index 00000000..0565e727
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/fwdback_twoslice.m
@@ -0,0 +1,198 @@
+function [alpha, beta, gamma, loglik, xi, gamma2] = fwdback_twoslice(engine, init_state_distrib, transmat, obslik, varargin)
+% FWDBACK Compute the posterior probs. in an HMM using the forwards backwards algo.
+%
+% [alpha, beta, gamma, loglik, xi, gamma2] = fwdback(init_state_distrib, transmat, obslik, ...)
+%
+% Notation:
+% Y(t) = observation, Q(t) = hidden state, M(t) = mixture variable (for MOG outputs)
+% A(t) = discrete input (action) (for POMDP models)
+%
+% INPUT:
+% init_state_distrib(i) = Pr(Q(1) = i)
+% transmat(i,j) = Pr(Q(t) = j | Q(t-1)=i)
+%  or transmat{a}(i,j) = Pr(Q(t) = j | Q(t-1)=i, A(t-1)=a) if there are discrete inputs
+% obslik(i,t) = Pr(Y(t)| Q(t)=i)
+%   (Compute obslik using eval_pdf_xxx on your data sequence first.)
+%
+% Optional parameters may be passed as 'param_name', param_value pairs.
+% Parameter names are shown below; default values in [] - if none, argument is mandatory.
+%
+% For HMMs with MOG outputs: if you want to compute gamma2, you must specify
+% 'obslik2' - obslik(i,j,t) = Pr(Y(t)| Q(t)=i,M(t)=j)  []
+% 'mixmat' - mixmat(i,j) = Pr(M(t) = j | Q(t)=i)  []
+%
+% For HMMs with discrete inputs:
+% 'act' - act(t) = action performed at step t
+%
+% Optional arguments:
+% 'fwd_only' - if 1, only do a forwards pass and set beta=[], gamma2=[]  [0]
+% 'scaled' - if 1,  normalize alphas and betas to prevent underflow [1]
+% 'maximize' - if 1, use max-product instead of sum-product [0]
+%
+% OUTPUTS:
+% alpha(i,t) = p(Q(t)=i | y(1:t)) (or p(Q(t)=i, y(1:t)) if scaled=0)
+% beta(i,t) = p(y(t+1:T) | Q(t)=i)*p(y(t+1:T)|y(1:t)) (or p(y(t+1:T) | Q(t)=i) if scaled=0)
+% gamma(i,t) = p(Q(t)=i | y(1:T))
+% loglik = log p(y(1:T))
+% xi(i,j,t-1)  = p(Q(t-1)=i, Q(t)=j | y(1:T))
+% gamma2(j,k,t) = p(Q(t)=j, M(t)=k | y(1:T)) (only for MOG  outputs)
+%
+% If fwd_only = 1, these become
+% alpha(i,t) = p(Q(t)=i | y(1:t))
+% beta = []
+% gamma(i,t) = p(Q(t)=i | y(1:t))
+% xi(i,j,t-1)  = p(Q(t-1)=i, Q(t)=j | y(1:t))
+% gamma2 = []
+%
+% Note: we only compute xi if it is requested as a return argument, since it can be very large.
+% Similarly, we only compute gamma2 on request (and if using MOG outputs).
+%
+% Examples:
+%
+% [alpha, beta, gamma, loglik] = fwdback(pi, A, multinomial_prob(sequence, B));
+%
+% [B, B2] = mixgauss_prob(data, mu, Sigma, mixmat);
+% [alpha, beta, gamma, loglik, xi, gamma2] = fwdback(pi, A, B, 'obslik2', B2, 'mixmat', mixmat);
+
+
+if nargout >= 5, compute_xi = 1; else compute_xi = 0; end
+if nargout >= 6, compute_gamma2 = 1; else compute_gamma2 = 0; end
+
+[obslik2, mixmat, fwd_only, scaled, act, maximize, compute_xi, compute_gamma2] = process_options(varargin, 'obslik2', [], 'mixmat', [], 'fwd_only', 0, 'scaled', 1, 'act', [], 'maximize', 0, 'compute_xi', compute_xi, 'compute_gamma2', compute_gamma2);
+
+
+[Q T] = size(obslik);
+
+if isempty(obslik2)
+  compute_gamma2 = 0;
+end
+
+if isempty(act)
+  act = ones(1,T);
+  transmat = { transmat } ;
+end
+
+scale = ones(1,T);
+
+% scale(t) = Pr(O(t) | O(1:t-1)) = 1/c(t) as defined by Rabiner (1989).
+% Hence prod_t scale(t) = Pr(O(1)) Pr(O(2)|O(1)) Pr(O(3) | O(1:2)) = Pr(O(1), ... ,O(T))
+% or log P = sum_t log scale(t).
+% Rabiner suggests multiplying beta(t) by scale(t), but we can instead
+% normalise beta(t) - the constants will cancel when we compute gamma.
+
+loglik = 0;
+
+alpha = zeros(Q,T);
+gamma = zeros(Q,T);
+if compute_xi
+  xi = zeros(Q,Q,T-1);
+else
+  xi = [];
+end
+
+
+%%%%%%%%% Forwards %%%%%%%%%%
+
+t = 1;
+alpha(:,1) = init_state_distrib(:) .* obslik(:,t);
+if scaled
+  %[alpha(:,t), scale(t)] = normaliseC(alpha(:,t));
+  [alpha(:,t), scale(t)] = normalise(alpha(:,t));
+end
+if scaled, assert(approxeq(sum(alpha(:,t)),1)), end
+for t=2:T
+  %trans = transmat(:,:,act(t-1))';
+  trans = transmat{act(t-1)};
+  if maximize
+    m = max_mult(trans', alpha(:,t-1));
+    %A = repmat(alpha(:,t-1), [1 Q]);
+    %m = max(trans .* A, [], 1);
+  else
+    m = trans' * alpha(:,t-1);
+  end
+  alpha(:,t) = m(:) .* obslik(:,t);
+  if scaled
+    %[alpha(:,t), scale(t)] = normaliseC(alpha(:,t));
+    [alpha(:,t), scale(t)] = normalise(alpha(:,t));
+  end
+  if compute_xi & fwd_only  % useful for online EM
+    %xi(:,:,t-1) = normaliseC((alpha(:,t-1) * obslik(:,t)') .* trans);
+    xi(:,:,t-1) = normalise((alpha(:,t-1) * obslik(:,t)') .* trans);
+  end
+  if scaled, assert(approxeq(sum(alpha(:,t)),1)), end
+end
+if scaled
+  if any(scale==0)
+    loglik = -inf;
+  else
+    loglik = sum(log(scale));
+  end
+else
+  loglik = log(sum(alpha(:,T)));
+end
+
+if fwd_only
+  gamma = alpha;
+  beta = [];
+  gamma2 = [];
+  return;
+end
+
+
+%%%%%%%%% Backwards %%%%%%%%%%
+
+beta = zeros(Q,T);
+if compute_gamma2
+  M = size(mixmat, 2);
+  gamma2 = zeros(Q,M,T);
+else
+  gamma2 = [];
+end
+
+beta(:,T) = ones(Q,1);
+%gamma(:,T) = normaliseC(alpha(:,T) .* beta(:,T));
+gamma(:,T) = normalise(alpha(:,T) .* beta(:,T));
+t=T;
+if compute_gamma2
+  denom = obslik(:,t) + (obslik(:,t)==0); % replace 0s with 1s before dividing
+  gamma2(:,:,t) = obslik2(:,:,t) .* mixmat .* repmat(gamma(:,t), [1 M]) ./ repmat(denom, [1 M]);
+  %gamma2(:,:,t) = normaliseC(obslik2(:,:,t) .* mixmat .* repmat(gamma(:,t), [1 M])); % wrong!
+end
+for t=T-1:-1:1
+  b = beta(:,t+1) .* obslik(:,t+1);
+  %trans = transmat(:,:,act(t));
+  trans = transmat{act(t)};
+  if maximize
+    B = repmat(b(:)', Q, 1);
+    beta(:,t) = max(trans .* B, [], 2);
+  else
+    beta(:,t) = trans * b;
+  end
+  if scaled
+    %beta(:,t) = normaliseC(beta(:,t));
+    beta(:,t) = normalise(beta(:,t));
+  end
+  %gamma(:,t) = normaliseC(alpha(:,t) .* beta(:,t));
+  gamma(:,t) = normalise(alpha(:,t) .* beta(:,t));
+  if compute_xi
+    %xi(:,:,t) = normaliseC((trans .* (alpha(:,t) * b')));
+    xi(:,:,t) = normalise((trans .* (alpha(:,t) * b')));
+    %xi(:,:,t) = (trans .* (alpha(:,t) * b'));
+  end
+  if compute_gamma2
+    denom = obslik(:,t) + (obslik(:,t)==0); % replace 0s with 1s before dividing
+    gamma2(:,:,t) = obslik2(:,:,t) .* mixmat .* repmat(gamma(:,t), [1 M]) ./ repmat(denom, [1 M]);
+    %gamma2(:,:,t) = normaliseC(obslik2(:,:,t) .* mixmat .* repmat(gamma(:,t), [1 M]));
+  end
+end
+
+
+% We now explain the equation for gamma2
+% Let zt=y(1:t-1,t+1:T) be all observations except y(t)
+% gamma2(Q,M,t) = P(Qt,Mt|yt,zt) = P(yt|Qt,Mt,zt) P(Qt,Mt|zt) / P(yt|zt)
+%                = P(yt|Qt,Mt) P(Mt|Qt) P(Qt|zt) / P(yt|zt)
+% Now gamma(Q,t) = P(Qt|yt,zt) = P(yt|Qt) P(Qt|zt) / P(yt|zt)
+% hence
+% P(Qt,Mt|yt,zt) = P(yt|Qt,Mt) P(Mt|Qt) [P(Qt|yt,zt) P(yt|zt) / P(yt|Qt)] / P(yt|zt)
+%                = P(yt|Qt,Mt) P(Mt|Qt) P(Qt|yt,zt) / P(yt|Qt)
+%
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/hmm_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/hmm_inf_engine.m
new file mode 100644
index 00000000..3de17b40
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/hmm_inf_engine.m
@@ -0,0 +1,71 @@
+function engine = hmm_inf_engine(bnet, varargin)
+% HMM_INF_ENGINE Inference engine for DBNs which uses the forwards-backwards algorithm.
+% engine = hmm_inf_engine(bnet, ...)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - 1 means max-product, 0 means sum-product [0]
+%
+% The DBN is converted to an HMM with a single meganode, but the observed nodes remain factored.
+% This can be faster than jtree if the num. hidden nodes is low, because of lower constant factors.
+%
+% All hidden nodes must be discrete.
+% All observed nodes are assumed to be leaves, i.e., they cannot be parents of anything.
+% The parents of each observed leaf are assumed to be a subset of the hidden nodes within the same slice.
+% The only exception is if bnet is an AR-HMM, where the parents are assumed to be self in the
+% previous slice (continuous), plus all the discrete nodes in the current slice.
+
+ss = bnet.nnodes_per_slice;
+
+engine.maximize = 0;
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', engine.maximize = args{i+1};
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+% Stuff to do with speeding up marginal_family
+[int, engine.persist, engine.transient] = compute_interface_nodes(bnet.intra, bnet.inter);
+engine.persist_bitv = zeros(1, ss);
+engine.persist_bitv(engine.persist) = 1;
+
+
+ns = bnet.node_sizes(:);
+ns(bnet.observed) = 1;
+ns(bnet.observed+ss) = 1;
+engine.eff_node_sizes = ns;
+
+for o=bnet.observed(:)'
+  %if bnet.equiv_class(o,1) ~= bnet.equiv_class(o,2)
+  %  error(['observed node ' num2str(o) ' is not tied'])
+  %end
+  cs = children(bnet.dag, o);
+  if ~isempty(cs)
+    error(['observed node ' num2str(o) ' is not allowed children'])
+  end
+end
+
+[engine.startprob, engine.transprob, engine.obsprob] = dbn_to_hmm(bnet);
+
+% This is where we will store the results between enter_evidence and marginal_nodes
+engine.one_slice_marginal = [];
+engine.two_slice_marginal = [];
+
+ss = length(bnet.intra);
+engine.evidence = [];
+engine.node_sizes = [];
+
+% avoid the need to do bnet_from_engine, which is slow
+engine.slice_size = ss;
+engine.parents = bnet.parents;
+
+engine = class(engine, 'hmm_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/marginal_family.m
new file mode 100644
index 00000000..56b9fb6c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/marginal_family.m
@@ -0,0 +1,35 @@
+function marginal = marginal_family(engine, i, t, add_ev)
+% MARGINAL_FAMILY Compute the marginal on the specified family (hmm)
+% marginal = marginal_family(engine, i, t, add_ev)
+
+if nargin < 3, t = 1; end
+if nargin < 4, add_ev = 0; end
+
+ns = engine.eff_node_sizes(:);
+ss = engine.slice_size;
+
+if t==1 | ~engine.persist_bitv(i)
+  bigT = engine.one_slice_marginal(:,t);
+  ps = engine.parents{i};
+  dom = [ps i] + (t-1)*ss;
+  bigdom = 1:ss;
+  bigsz = ns(bigdom);
+  bigdom = bigdom + (t-1)*ss;
+else % some parents are in previous slice
+  bigT = engine.two_slice_marginal(:,t-1); % t-1 and t
+  ps = engine.parents{i+ss};
+  dom = [ps i+ss] + (t-2)*ss; 
+  bigdom = 1:(2*ss); % domain of xi(:,:,t)
+  bigsz = ns(bigdom);
+  bigdom = bigdom + (t-2)*ss;
+end
+marginal.domain = dom;
+
+marginal.T = marg_table(bigT, bigdom, bigsz, dom, engine.maximize); 
+marginal.mu = []; 
+marginal.Sigma = [];
+
+if add_ev
+  marginal = add_ev_to_dmarginal(marginal, engine.evidence, engine.node_sizes);
+end    
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..0a2bec4f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/marginal_nodes.m
@@ -0,0 +1,29 @@
+function marginal = marginal_nodes(engine, nodes, t, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (hmm)
+% marginal = marginal_nodes(engine, nodes, t, add_ev)
+%
+% 'nodes' must be a single node.
+% t is the time slice.
+
+if nargin < 3, t = 1; end
+if nargin < 4, add_ev = 0; end
+
+assert(length(nodes)==1)
+ss = engine.slice_size;
+
+i = nodes(1);
+bigT = engine.one_slice_marginal(:,t);
+dom = i + (t-1)*ss;
+
+ns = engine.eff_node_sizes(:);
+bigdom = 1:ss;
+marginal.T = marg_table(bigT, bigdom + (t-1)*ss, ns(bigdom), dom, engine.maximize);
+
+marginal.domain = dom;
+marginal.mu = [];
+marginal.Sigma = [];
+
+if add_ev
+  marginal = add_ev_to_dmarginal(marginal, engine.evidence, engine.node_sizes);
+end    
+ 
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/CVS/Entries
new file mode 100644
index 00000000..a35185ea
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/CVS/Entries
@@ -0,0 +1,3 @@
+/mk_hmm_obs_lik_matrix.m/1.1.1.1/Sun May  4 21:42:26 2003//
+/mk_hmm_obs_lik_vec.m/1.1.1.1/Thu Jan 23 18:50:10 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/CVS/Repository
new file mode 100644
index 00000000..20dfc6fd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@hmm_inf_engine/private
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/mk_hmm_obs_lik_matrix.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/mk_hmm_obs_lik_matrix.m
new file mode 100644
index 00000000..441f3c0a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/mk_hmm_obs_lik_matrix.m
@@ -0,0 +1,30 @@
+function obslik = mk_hmm_obs_lik_matrix(engine, evidence)
+
+T  = size(evidence,2);
+Q = length(engine.startprob);
+obslik = ones(Q, T);
+bnet = bnet_from_engine(engine);
+% P(o1,o2| Q1,Q2) = P(o1|Q1,Q2) * P(o2|Q1,Q2)
+onodes = bnet.observed;
+for i=1:length(onodes)
+  data = cell2num(evidence(onodes(i),:));
+  if bnet.auto_regressive(onodes(i))
+    params = engine.obsprob{i};
+    mu = params.big_mu;
+    Sigma = params.big_Sigma,
+    W = params.big_W;
+    mu0 = params.big_mu0;
+    Sigma0 = params.big_Sigma0;
+    %obslik_i = mk_arhmm_obs_lik(data, mu, Sigma, W, mu0, Sigma0
+    obslik_i = clg_prob(data(:,1:T-1), data(:,2:T), mu, Sigma, W);
+    obslik_i = [mixgauss_prob(data(:,1), mu0, Sigma0) obslik_i];
+  elseif myismember(onodes(i), bnet.dnodes)
+    %obslik_i = eval_pdf_cond_multinomial(data, engine.obsprob{i}.big_CPT);
+    obslik_i = multinomial_prob(data, engine.obsprob{i}.big_CPT);
+  else
+    %obslik_i = eval_pdf_cond_gauss(data, engine.obsprob{i}.big_mu, engine.obsprob{i}.big_Sigma);
+    obslik_i = mixgauss_prob(data, engine.obsprob{i}.big_mu, engine.obsprob{i}.big_Sigma);
+  end
+  obslik = obslik .* obslik_i;
+end
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/mk_hmm_obs_lik_vec.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/mk_hmm_obs_lik_vec.m
new file mode 100644
index 00000000..16d30aec
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/private/mk_hmm_obs_lik_vec.m
@@ -0,0 +1,52 @@
+function obslik = mk_hmm_obs_lik_vec(engine, evidence)
+
+% P(o1,o2| h) = P(o1|h) * P(o2|h) where h = Q1,Q2,...
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+onodes = bnet.observed;
+hnodes = mysetdiff(1:ss, onodes);
+ns = bnet.node_sizes(:);
+ns(onodes) = 1;
+
+Q = length(engine.startprob);
+obslik = ones(Q, 1);
+
+for i=1:length(onodes)
+  o = onodes(i);
+  %data = cell2num(evidence(o,1));
+  data = evidence{o,1};
+  if myismember(o, bnet.dnodes)
+    obslik_i = eval_pdf_cond_multinomial(data, engine.obsprob{i}.CPT);
+  else
+    if bnet.auto_regressive(o)
+      error('can''t handle AR nodes')
+    end
+    %% calling mk_ghmm_obs_lik, which calls gaussian_prob, is slow, so we inline it
+    %% and use the pre-computed  inverse matrix
+    %obslik_i = mk_ghmm_obs_lik(data, engine.obsprob{i}.mu, engine.obsprob{i}.Sigma);
+    x = data(:);
+    m = engine.obsprob{i}.mu;
+    Qi = size(m, 2);
+    obslik_i = size(Qi, 1);
+    invC = engine.obsprob{i}.inv_Sigma;
+    denom = engine.obsprob{i}.denom;
+    for j=1:Qi
+      numer = exp(-0.5 * (x-m(:,j))' * invC(:,:,j) * (x-m(:,j)));
+      obslik_i(j) = numer / denom(j);
+    end
+  end
+  % convert P(o|ps) into P(o|h) by multiplying onto a (h,o) potential of all 1s
+  ps = bnet.parents{o};
+  dom = [ps o];
+  obspot_i = dpot(dom, ns(dom), obslik_i);
+  dom = [hnodes o];
+  obspot = dpot(dom, ns(dom));
+  obspot = multiply_by_pot(obspot, obspot_i);
+  % compute p(oi|h) * p(oj|h)
+  S = struct(obspot);
+  obslik = obslik .* S.T(:);
+end
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/update_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/update_engine.m
new file mode 100644
index 00000000..e6cd1f79
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@hmm_inf_engine/update_engine.m
@@ -0,0 +1,8 @@
+function engine = update_engine(engine, newCPDs)
+% UPDATE_ENGINE Update the engine to take into account the new parameters (hmm)
+% engine = update_engine(engine, newCPDs)
+
+%engine.inf_engine.bnet.CPD = newCPDs;
+engine.inf_engine = update_engine(engine.inf_engine, newCPDs);
+[engine.startprob, engine.transprob, engine.obsprob] = dbn_to_hmm(bnet_from_engine(engine));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/CVS/Entries
new file mode 100644
index 00000000..3baa09c7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/CVS/Entries
@@ -0,0 +1,6 @@
+/enter_soft_evidence1.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_soft_evidence2.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_soft_evidence3.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_soft_evidence4.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/CVS/Repository
new file mode 100644
index 00000000..a9b61e36
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence1.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence1.m
new file mode 100644
index 00000000..8f82b57e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence1.m
@@ -0,0 +1,119 @@
+function [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type)
+% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (jtree_dbn)
+% [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+
+[ss T] = size(CPDpot);
+Q = length(engine.jtree_struct.cliques);
+clpot = cell(Q,T); % clpot{t} contains evidence from slices (t-1, t) 
+seppot = cell(Q,Q,T);
+ll = zeros(1,Q);
+logscale = zeros(1,T);
+bnet = bnet_from_engine(engine);
+
+% Forwards pass.
+% Compute distribution on clq C,
+% where C is the out interface to (t-1,t).
+% Then pass this to clq D, where D is the in inferface to (t+1,t).
+% Then propagate from D to later slices.
+
+C = engine.out_clq;
+assert(C==engine.jtree_struct.root_clq);
+D = engine.in_clq;
+slice1 = 1:ss;
+slice2 = slice1 + ss;
+for t=2:T
+  if t==2
+    clqs = engine.jtree_struct.clq_ass_to_node([slice1 slice2]);
+    pots = CPDpot(:,t-1:t);
+  else
+    %clqs = [D; engine.clq_ass_to_node(:,2)];
+    clqs = [D engine.jtree_struct.clq_ass_to_node(slice2)];
+    phiC = set_domain_pot(phiC, engine.interface); % shift back to slice 1
+    pots = [ {phiC}; CPDpot(:,t)]; % CPDpot domains are always slice 2
+  end
+  [clpot(:,t), seppot(:,:,t)] =  init_pot(engine.jtree_struct.cliques, clqs, pots, pot_type, ...
+					 find(observed(:,t-1:t)), bnet.node_sizes(:), bnet.cnodes);
+  [clpot(:,t), seppot(:,:,t)] = collect_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.postorder, ...
+						    engine.jtree_struct.postorder_parents,...
+						    engine.jtree_struct.separator);
+
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  logscale(t) = ll(C);
+
+  phiC = marginalize_pot(clpot{C,t}, engine.interface+ss, engine.maximize);
+end
+
+
+
+% Backwards pass.
+% Pass evidence from clq C to clq D,
+% where C is the in interface to (t,t+1) and D is the out inferface to (t-1,t)
+% Then propagate evidence from D to earlier slices.
+C = engine.in_clq;
+D = engine.out_clq;
+for t=T:-1:2
+  [clpot(:,t), seppot(:,:,t)] = distribute_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.preorder, ...
+						    engine.jtree_struct.preorder_children, ...
+						    engine.jtree_struct.separator);
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  logscale(t) = ll(C);
+  
+  if t >= 3
+    phiC = marginalize_pot(clpot{C,t}, engine.interface, engine.maximize);
+    phiC = set_domain_pot(phiC, engine.interface+ss); % shift forward to slice 2
+    phiD = marginalize_pot(clpot{D,t-1}, engine.interface+ss, engine.maximize);
+    ratio = divide_by_pot(phiC, phiD);
+    clpot{D,t-1} = multiply_by_pot(clpot{D,t-1}, ratio);
+  end
+end
+
+loglik = sum(logscale);
+
+
+%%%%%%%
+function [clpot, seppot] = init_pot(cliques, clqs, pots, pot_type, onodes, ns, cnodes);
+
+% Set the clique potentials to all 1s
+C = length(cliques);
+clpot = cell(1,C);
+for i=1:C
+  clpot{i} = mk_initial_pot(pot_type, cliques{i}, ns, cnodes, onodes);
+end
+
+% Multiply on specified potentials
+for i=1:length(clqs)
+  c = clqs(i);
+  clpot{c} = multiply_by_pot(clpot{c}, pots{i});
+end
+
+seppot = cell(C,C); % implicitely initialized to 1
+
+
+%%%%
+function [clpot, seppot] = collect_evidence(clpot, seppot, maximize, postorder, postorder_parents,...
+					    separator)
+for n=postorder %postorder(1:end-1)
+  for p=postorder_parents{n}
+    %clpot{p} = divide_by_pot(clpot{n}, seppot{p,n}); % dividing by 1 is redundant
+    seppot{p,n} = marginalize_pot(clpot{n}, separator{p,n}, maximize);
+    clpot{p} = multiply_by_pot(clpot{p}, seppot{p,n});
+  end
+end
+
+
+%%%%
+function [clpot, seppot] = distribute_evidence(clpot, seppot, maximize, preorder, preorder_children,...
+					       separator)
+for n=preorder
+  for c=preorder_children{n}
+    clpot{c} = divide_by_pot(clpot{c}, seppot{n,c}); 
+    seppot{n,c} = marginalize_pot(clpot{n}, separator{n,c}, maximize);
+    clpot{c} = multiply_by_pot(clpot{c}, seppot{n,c});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence2.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence2.m
new file mode 100644
index 00000000..0adfef0d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence2.m
@@ -0,0 +1,143 @@
+function [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type)
+% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (jtree_dbn)
+% [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+
+[ss T] = size(CPDpot);
+Q = length(engine.jtree_struct.cliques);
+clpot = cell(Q,T); % clpot{t} contains evidence from slices (t-1, t) 
+seppot = cell(Q,Q,T);
+ll = zeros(1,Q);
+logscale = ones(1,T); % log(logscale(1)) = 0
+bnet = bnet_from_engine(engine);
+
+slice1 = 1:ss;
+slice2 = slice1+ss;
+
+% calibrate each 2-slice jtree in isolation
+for t=2:T
+  if t==2
+    clqs = engine.jtree_struct.clq_ass_to_node([slice1 slice2]);
+    pots = CPDpot(:,t-1:t);
+  else
+    clqs = engine.jtree_struct.clq_ass_to_node(slice2);
+    pots = CPDpot(:,t); % CPDpot domains are always slice 2
+  end
+  [clpot(:,t), sepot(:,:,t)] =  init_pot(engine.jtree_struct.cliques, clqs, pots, pot_type, ...
+					 find(observed(:,t-1:t)), bnet.node_sizes(:), bnet.cnodes);
+  [clpot(:,t), seppot(:,:,t)] = collect_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.postorder, ...
+						    engine.jtree_struct.postorder_parents,...
+						    engine.jtree_struct.separator);
+  [clpot(:,t), seppot(:,:,t)] = distribute_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.preorder, ...
+						    engine.jtree_struct.preorder_children, ...
+						    engine.jtree_struct.separator);
+end
+
+% Forwards pass.
+% Compute distribution on clq C,
+% where C is the out interface to (t-1,t).
+% Then pass this to clq D, where D is the in inferface to (t+1,t).
+% Then propagate from D to later slices.
+
+C = engine.out_clq;
+D = engine.in_clq;
+for t=2:T-1
+  phiC = marginalize_pot(clpot{C,t}, engine.interface+ss, engine.maximize);
+  phiC = set_domain_pot(phiC, engine.interface); % shift back to slice 1
+  phiD = marginalize_pot(clpot{D,t+1}, engine.interface, engine.maximize);
+  ratio = divide_by_pot(phiC, phiD);
+  clpot{D,t+1} = multiply_by_pot(clpot{D,t+1}, ratio);
+
+  [clpot(:,t), seppot(:,:,t)] = distribute_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.preorder, ...
+						    engine.jtree_struct.preorder_children, ...
+						    engine.jtree_struct.separator);
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  logscale(t) = ll(1);
+end
+
+% Backwards pass.
+% Pass evidence from clq C to clq D,
+% where C is the in interface to (t,t+1) and D is the out inferface to (t-1,t)
+% Then propagate evidence from D to earlier slices.
+C = engine.in_clq;
+D = engine.out_clq;
+for t=T:-1:2
+  [clpot(:,t), seppot(:,:,t)] = collect_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						 engine.jtree_struct.postorder, ...
+						 engine.jtree_struct.postorder_parents,...
+						 engine.jtree_struct.separator);
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  logscale(t) = ll(1);
+
+  if t >= 3
+    phiC = marginalize_pot(clpot{C,t}, engine.interface, engine.maximize);
+    phiC = set_domain_pot(phiC, engine.interface+ss); % shift forward to slice 2
+    phiD = marginalize_pot(clpot{D,t-1}, engine.interface+ss, engine.maximize);
+    ratio = divide_by_pot(phiC, phiD);
+    clpot{D,t-1} = multiply_by_pot(clpot{D,t-1}, ratio);
+  end
+end
+
+loglik = sum(logscale);
+
+%%%%%%%%%%
+
+function [clpot, seppot] = calibrate(engine, clpot, seppot)
+
+  [clpot(:,t), seppot(:,:,t)] = collect_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.postorder, ...
+						    engine.jtree_struct.postorder_parents,...
+						    engine.jtree_struct.separator);
+  [clpot(:,t), seppot(:,:,t)] = distribute_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.preorder, ...
+						    engine.jtree_struct.preorder_children, ...
+						    engine.jtree_struct.separator);
+
+
+%%%%%%%
+function [clpot, seppot] = init_pot(cliques, clqs, pots, pot_type, onodes, ns, cnodes);
+
+% Set the clique potentials to all 1s
+C = length(cliques);
+clpot = cell(1,C);
+for i=1:C
+  clpot{i} = mk_initial_pot(pot_type, cliques{i}, ns, cnodes, onodes);
+end
+
+% Multiply on specified potentials
+for i=1:length(clqs)
+  c = clqs(i);
+  clpot{c} = multiply_by_pot(clpot{c}, pots{i});
+end
+
+seppot = cell(C,C); % implicitely initialized to 1
+
+
+%%%%
+function [clpot, seppot] = collect_evidence(clpot, seppot, maximize, postorder, postorder_parents,...
+					    separator)
+for n=postorder %postorder(1:end-1)
+  for p=postorder_parents{n}
+    %clpot{p} = divide_by_pot(clpot{n}, seppot{p,n}); % dividing by 1 is redundant
+    seppot{p,n} = marginalize_pot(clpot{n}, separator{p,n}, maximize);
+    clpot{p} = multiply_by_pot(clpot{p}, seppot{p,n});
+  end
+end
+
+
+%%%%
+function [clpot, seppot] = distribute_evidence(clpot, seppot, maximize, preorder, preorder_children,...
+					       separator)
+for n=preorder
+  for c=preorder_children{n}
+    clpot{c} = divide_by_pot(clpot{c}, seppot{n,c}); 
+    seppot{n,c} = marginalize_pot(clpot{n}, separator{n,c}, maximize);
+    clpot{c} = multiply_by_pot(clpot{c}, seppot{n,c});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence3.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence3.m
new file mode 100644
index 00000000..c1189460
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence3.m
@@ -0,0 +1,125 @@
+function [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type)
+% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (jtree_dbn)
+% [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+
+[ss T] = size(CPDpot);
+Q = length(engine.jtree_struct.cliques);
+clpot = cell(Q,T); % clpot{t} contains evidence from slices (t-1, t) 
+seppot = cell(Q,Q,T);
+ll = zeros(1,Q);
+logscale = zeros(1,T);
+bnet = bnet_from_engine(engine);
+
+% Forwards pass.
+% Compute distribution on clq C,
+% where C is the out interface to (t-1,t).
+% Then pass this to clq D, where D is the in inferface to (t+1,t).
+% Then propagate from D to later slices.
+
+C = engine.out_clq;
+assert(C==engine.jtree_struct.root_clq);
+D = engine.in_clq;
+slice1 = 1:ss;
+slice2 = slice1 + ss;
+Ntransient = length(engine.transient);
+trans = cell(Ntransient,1);
+for t=2:T
+  if t==2
+    clqs = engine.jtree_struct.clq_ass_to_node([slice1 slice2]);
+    pots = CPDpot(:,t-1:t);
+  else
+    %clqs = [D; engine.clq_ass_to_node(:,2)];
+    clqs = [D engine.jtree_struct.clq_ass_to_node([engine.transient slice2])];
+    phiC = set_domain_pot(phiC, engine.interface); % shift back to slice 1
+    for i=1:Ntransient
+      trans{i} = CPDpot{engine.transient(i), t-1};
+      trans{i} = set_domain_pot(trans{i}, domain_pot(trans{i})-ss); % shift back to slice 1
+    end
+    pots = [ {phiC}; trans; CPDpot(:,t)]; 
+  end
+  [clpot(:,t), seppot(:,:,t)] =  init_pot(engine.jtree_struct.cliques, clqs, pots, pot_type, ...
+					 find(observed(:,t-1:t)), bnet.node_sizes(:), bnet.cnodes);
+  [clpot(:,t), seppot(:,:,t)] = collect_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.postorder, ...
+						    engine.jtree_struct.postorder_parents,...
+						    engine.jtree_struct.separator);
+
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  logscale(t) = ll(C);
+
+  phiC = marginalize_pot(clpot{C,t}, engine.interface+ss, engine.maximize);
+end
+
+
+
+% Backwards pass.
+% Pass evidence from clq C to clq D,
+% where C is the in interface to (t,t+1) and D is the out inferface to (t-1,t)
+% Then propagate evidence from D to earlier slices.
+C = engine.in_clq;
+D = engine.out_clq;
+for t=T:-1:2
+  [clpot(:,t), seppot(:,:,t)] = distribute_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.preorder, ...
+						    engine.jtree_struct.preorder_children, ...
+						    engine.jtree_struct.separator);
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  logscale(t) = ll(C);
+  
+  if t >= 3
+    phiC = marginalize_pot(clpot{C,t}, engine.interface, engine.maximize);
+    phiC = set_domain_pot(phiC, engine.interface+ss); % shift forward to slice 2
+    phiD = marginalize_pot(clpot{D,t-1}, engine.interface+ss, engine.maximize);
+    ratio = divide_by_pot(phiC, phiD);
+    clpot{D,t-1} = multiply_by_pot(clpot{D,t-1}, ratio);
+  end
+end
+
+loglik = sum(logscale);
+
+
+%%%%%%%
+function [clpot, seppot] = init_pot(cliques, clqs, pots, pot_type, onodes, ns, cnodes);
+
+% Set the clique potentials to all 1s
+C = length(cliques);
+clpot = cell(1,C);
+for i=1:C
+  clpot{i} = mk_initial_pot(pot_type, cliques{i}, ns, cnodes, onodes);
+end
+
+% Multiply on specified potentials
+for i=1:length(clqs)
+  c = clqs(i);
+  clpot{c} = multiply_by_pot(clpot{c}, pots{i});
+end
+
+seppot = cell(C,C); % implicitely initialized to 1
+
+
+%%%%
+function [clpot, seppot] = collect_evidence(clpot, seppot, maximize, postorder, postorder_parents,...
+					    separator)
+for n=postorder %postorder(1:end-1)
+  for p=postorder_parents{n}
+    %clpot{p} = divide_by_pot(clpot{n}, seppot{p,n}); % dividing by 1 is redundant
+    seppot{p,n} = marginalize_pot(clpot{n}, separator{p,n}, maximize);
+    clpot{p} = multiply_by_pot(clpot{p}, seppot{p,n});
+  end
+end
+
+
+%%%%
+function [clpot, seppot] = distribute_evidence(clpot, seppot, maximize, preorder, preorder_children,...
+					       separator)
+for n=preorder
+  for c=preorder_children{n}
+    clpot{c} = divide_by_pot(clpot{c}, seppot{n,c}); 
+    seppot{n,c} = marginalize_pot(clpot{n}, separator{n,c}, maximize);
+    clpot{c} = multiply_by_pot(clpot{c}, seppot{n,c});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence4.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence4.m
new file mode 100644
index 00000000..a4ec90c6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/enter_soft_evidence4.m
@@ -0,0 +1,149 @@
+function [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type)
+% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (jtree_dbn)
+% [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+
+[ss T] = size(CPDpot);
+Q = length(engine.jtree_struct.cliques);
+clpot = cell(Q,T); % clpot{t} contains evidence from slices (t-1, t) 
+seppot = cell(Q,Q,T);
+ll = zeros(1,Q);
+logscale = ones(1,T); % log(logscale(1)) = 0
+bnet = bnet_from_engine(engine);
+
+slice1 = 1:ss;
+slice2 = slice1+ss;
+Ntransient = length(engine.transient);
+trans = cell(Ntransient,1);
+
+% calibrate each 2-slice jtree in isolation
+for t=2:T
+  if t==2
+    clqs = engine.jtree_struct.clq_ass_to_node([slice1 slice2]);
+    pots = CPDpot(:,t-1:t);
+  else
+    clqs = engine.jtree_struct.clq_ass_to_node([engine.transient slice2]);
+    for i=1:Ntransient
+      trans{i} = CPDpot{engine.transient(i), t-1};
+      trans{i} = set_domain_pot(trans{i}, domain_pot(trans{i})-ss); % shift back to slice 1
+    end
+    pots = [ trans; CPDpot(:,t)]; 
+  end
+  [clpot(:,t), sepot(:,:,t)] =  init_pot(engine.jtree_struct.cliques, clqs, pots, pot_type, ...
+					 find(observed(:,t-1:t)), bnet.node_sizes(:), bnet.cnodes);
+  [clpot(:,t), seppot(:,:,t)] = collect_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.postorder, ...
+						    engine.jtree_struct.postorder_parents,...
+						    engine.jtree_struct.separator);
+  [clpot(:,t), seppot(:,:,t)] = distribute_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.preorder, ...
+						    engine.jtree_struct.preorder_children, ...
+						    engine.jtree_struct.separator);
+end
+
+% Forwards pass.
+% Compute distribution on clq C,
+% where C is the out interface to (t-1,t).
+% Then pass this to clq D, where D is the in inferface to (t+1,t).
+% Then propagate from D to later slices.
+
+C = engine.out_clq;
+D = engine.in_clq;
+for t=2:T-1
+  phiC = marginalize_pot(clpot{C,t}, engine.interface+ss, engine.maximize);
+  phiC = set_domain_pot(phiC, engine.interface); % shift back to slice 1
+  phiD = marginalize_pot(clpot{D,t+1}, engine.interface, engine.maximize);
+  ratio = divide_by_pot(phiC, phiD);
+  clpot{D,t+1} = multiply_by_pot(clpot{D,t+1}, ratio);
+
+  [clpot(:,t), seppot(:,:,t)] = distribute_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.preorder, ...
+						    engine.jtree_struct.preorder_children, ...
+						    engine.jtree_struct.separator);
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  logscale(t) = ll(1);
+end
+
+% Backwards pass.
+% Pass evidence from clq C to clq D,
+% where C is the in interface to (t,t+1) and D is the out inferface to (t-1,t)
+% Then propagate evidence from D to earlier slices.
+C = engine.in_clq;
+D = engine.out_clq;
+for t=T:-1:2
+  [clpot(:,t), seppot(:,:,t)] = collect_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						 engine.jtree_struct.postorder, ...
+						 engine.jtree_struct.postorder_parents,...
+						 engine.jtree_struct.separator);
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  logscale(t) = ll(1);
+
+  if t >= 3
+    phiC = marginalize_pot(clpot{C,t}, engine.interface, engine.maximize);
+    phiC = set_domain_pot(phiC, engine.interface+ss); % shift forward to slice 2
+    phiD = marginalize_pot(clpot{D,t-1}, engine.interface+ss, engine.maximize);
+    ratio = divide_by_pot(phiC, phiD);
+    clpot{D,t-1} = multiply_by_pot(clpot{D,t-1}, ratio);
+  end
+end
+
+loglik = sum(logscale);
+
+%%%%%%%%%%
+
+function [clpot, seppot] = calibrate(engine, clpot, seppot)
+
+  [clpot(:,t), seppot(:,:,t)] = collect_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.postorder, ...
+						    engine.jtree_struct.postorder_parents,...
+						    engine.jtree_struct.separator);
+  [clpot(:,t), seppot(:,:,t)] = distribute_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.preorder, ...
+						    engine.jtree_struct.preorder_children, ...
+						    engine.jtree_struct.separator);
+
+
+%%%%%%%
+function [clpot, seppot] = init_pot(cliques, clqs, pots, pot_type, onodes, ns, cnodes);
+
+% Set the clique potentials to all 1s
+C = length(cliques);
+clpot = cell(1,C);
+for i=1:C
+  clpot{i} = mk_initial_pot(pot_type, cliques{i}, ns, cnodes, onodes);
+end
+
+% Multiply on specified potentials
+for i=1:length(clqs)
+  c = clqs(i);
+  clpot{c} = multiply_by_pot(clpot{c}, pots{i});
+end
+
+seppot = cell(C,C); % implicitely initialized to 1
+
+
+%%%%
+function [clpot, seppot] = collect_evidence(clpot, seppot, maximize, postorder, postorder_parents,...
+					    separator)
+for n=postorder %postorder(1:end-1)
+  for p=postorder_parents{n}
+    %clpot{p} = divide_by_pot(clpot{n}, seppot{p,n}); % dividing by 1 is redundant
+    seppot{p,n} = marginalize_pot(clpot{n}, separator{p,n}, maximize);
+    clpot{p} = multiply_by_pot(clpot{p}, seppot{p,n});
+  end
+end
+
+
+%%%%
+function [clpot, seppot] = distribute_evidence(clpot, seppot, maximize, preorder, preorder_children,...
+					       separator)
+for n=preorder
+  for c=preorder_children{n}
+    clpot{c} = divide_by_pot(clpot{c}, seppot{n,c}); 
+    seppot{n,c} = marginalize_pot(clpot{n}, separator{n,c}, maximize);
+    clpot{c} = multiply_by_pot(clpot{c}, seppot{n,c});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/marginal_nodes.m
new file mode 100644
index 00000000..fe1d38f6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Broken/marginal_nodes.m
@@ -0,0 +1,51 @@
+function marginal = marginal_nodes(engine, nodes, t, fam)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (bk)
+%
+%   marginal = marginal_nodes(engine, i, t)
+% returns Pr(X(i,t) | Y(1:T)), where X(i,t) is the i'th node in the t'th slice.
+%
+%   marginal = marginal_nodes(engine, query, t)
+% returns Pr(X(query(1),t), ... X(query(end),t) | Y(1:T)),
+% where 't' specifies the time slice of the earliest node in the query.
+% 'query' cannot span more than 2 time slices.
+%
+% Example:
+% Consider a DBN with 2 nodes per slice.
+% Then t=2, nodes=[1 3] refers to node 1 in slice 2 and node 1 in slice 3.
+
+if nargin < 3, t = 1; end
+if nargin < 4, fam = 0; else fam = 1; end
+
+
+% clpot{t} contains slice t-1 and t
+% Example
+% clpot #: 1    2    3
+% slices:  1  1,2  2,3
+% For filtering, we must take care not to take future evidence into account.
+% For smoothing, clpot{1} does not exist.
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+
+if t < engine.T
+  slice = t+1;
+  nodes2 = nodes;
+else % earliest t is T, so all nodes fit in one slice
+  slice = engine.T;
+  nodes2 = nodes + ss;
+end
+  
+c = clq_containing_nodes(engine.jtree_engine, nodes2, fam);
+assert(c >= 1);
+
+%disp(['computing marginal on ' num2str(nodes) ' t = ' num2str(t)]);
+%disp(['using ' num2str(nodes2) ' slice = ' num2str(slice) 'clq = ' num2str(c)]);
+
+bigpot = engine.clpot{c, slice};
+
+pot = marginalize_pot(bigpot, nodes2, engine.maximize);
+marginal = pot_to_marginal(pot);
+
+% we convert the domain to the unrolled numbering system
+% so that update_ess extracts the right evidence.
+marginal.domain = nodes+(t-1)*ss;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Entries
new file mode 100644
index 00000000..aea2a602
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Entries
@@ -0,0 +1,6 @@
+/enter_evidence.m/1.1.1.1/Sat Jan 11 18:41:30 2003//
+/enter_soft_evidence.m/1.1.1.1/Thu Feb 19 01:12:08 2004//
+/jtree_dbn_inf_engine.m/1.1.1.1/Thu Nov 14 16:32:00 2002//
+/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes.m/1.1.1.1/Fri Nov 22 23:51:58 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Entries.Log
new file mode 100644
index 00000000..2fb9e4b6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Entries.Log
@@ -0,0 +1,2 @@
+A D/Broken////
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Repository
new file mode 100644
index 00000000..590182fa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@jtree_dbn_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/CVS/Entries
new file mode 100644
index 00000000..0bc2d941
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/CVS/Entries
@@ -0,0 +1,6 @@
+/enter_soft_evidence_nonint.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_soft_evidence_trans.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/jtree_dbn_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/jtree_dbn_inf_engine1.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/jtree_dbn_inf_engine2.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/CVS/Repository
new file mode 100644
index 00000000..0b90d866
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/enter_soft_evidence_nonint.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/enter_soft_evidence_nonint.m
new file mode 100644
index 00000000..72641580
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/enter_soft_evidence_nonint.m
@@ -0,0 +1,135 @@
+function [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type)
+% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (jtree_dbn)
+% [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+
+[ss T] = size(CPDpot);
+Q = length(engine.jtree_struct.cliques);
+clpot = cell(Q,T); % clpot{t} contains evidence from slices (t-1, t) 
+seppot = cell(Q,Q,T);
+ll = zeros(1,Q);
+logscale = zeros(1,T);
+bnet = bnet_from_engine(engine);
+
+% Forwards pass.
+% Compute distribution on clq C,
+% where C is the out interface to (t-1,t).
+% Then pass this to clq D, where D is the in inferface to (t+1,t).
+% Then propagate from D to later slices.
+
+C = engine.out_clq;
+assert(C==engine.jtree_struct.root_clq);
+D = engine.in_clq;
+slice1 = 1:ss;
+slice2 = slice1 + ss;
+Nnonint = length(engine.nonint);
+nonint = cell(Nnonint, 1);
+for t=1:T
+  if t==1
+    pots = [CPDpot(:,1); CPDpot(engine.interface, 2)];
+    clqs = engine.jtree_struct.clq_ass_to_node([slice1 engine.interface+ss]);
+    obs = find(observed(:,1:2));
+  elseif t==T
+    clqs = [D engine.jtree_struct.clq_ass_to_node(engine.nonint)];
+    phiC = set_domain_pot(phiC, engine.interface); % shift back to slice 1
+    for i=1:Nnonint
+      nonint{i} = CPDpot{engine.nonint(i), t};
+      nonint{i} = set_domain_pot(nonint{i}, domain_pot(nonint{i})-ss); % shift back to slice 1
+    end
+    pots = [ {phiC}; nonint]; 
+    obs = find(observed(:,T));
+  else
+    clqs = [D engine.jtree_struct.clq_ass_to_node([engine.nonint engine.interface+ss])];
+    phiC = set_domain_pot(phiC, engine.interface); % shift back to slice 1
+    for i=1:Nnonint
+      nonint{i} = CPDpot{engine.nonint(i), t};
+      nonint{i} = set_domain_pot(nonint{i}, domain_pot(nonint{i})-ss); % shift back to slice 1
+    end
+    pots = [ {phiC}; nonint; CPDpot(engine.interface, t+1)]; 
+    obs = find(observed(:,t:t+1));
+  end
+  [clpot(:,t), seppot(:,:,t)] =  init_pot(engine.jtree_struct.cliques, clqs, pots, pot_type, ...
+					 obs, bnet.node_sizes(:), bnet.cnodes);
+  [clpot(:,t), seppot(:,:,t)] = collect_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.postorder, ...
+						    engine.jtree_struct.postorder_parents,...
+						    engine.jtree_struct.separator);
+
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  logscale(t) = ll(C);
+
+  phiC = marginalize_pot(clpot{C,t}, engine.interface+ss, engine.maximize);
+end
+
+
+
+% Backwards pass.
+% Pass evidence from clq C to clq D,
+% where C is the in interface to (t,t+1) and D is the out inferface to (t-1,t)
+% Then propagate evidence from D to earlier slices.
+C = engine.in_clq;
+D = engine.out_clq;
+for t=T:-1:1
+  [clpot(:,t), seppot(:,:,t)] = distribute_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.preorder, ...
+						    engine.jtree_struct.preorder_children, ...
+						    engine.jtree_struct.separator);
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  %logscale(t) = ll(C);
+  
+  if t >= 2
+    phiC = marginalize_pot(clpot{C,t}, engine.interface, engine.maximize);
+    phiC = set_domain_pot(phiC, engine.interface+ss); % shift forward to slice 2
+    phiD = marginalize_pot(clpot{D,t-1}, engine.interface+ss, engine.maximize);
+    ratio = divide_by_pot(phiC, phiD);
+    clpot{D,t-1} = multiply_by_pot(clpot{D,t-1}, ratio);
+  end
+end
+
+loglik = sum(logscale);
+
+
+%%%%%%%
+function [clpot, seppot] = init_pot(cliques, clqs, pots, pot_type, onodes, ns, cnodes);
+
+% Set the clique potentials to all 1s
+C = length(cliques);
+clpot = cell(1,C);
+for i=1:C
+  clpot{i} = mk_initial_pot(pot_type, cliques{i}, ns, cnodes, onodes);
+end
+
+% Multiply on specified potentials
+for i=1:length(clqs)
+  c = clqs(i);
+  clpot{c} = multiply_by_pot(clpot{c}, pots{i});
+end
+
+seppot = cell(C,C); % implicitely initialized to 1
+
+
+%%%%
+function [clpot, seppot] = collect_evidence(clpot, seppot, maximize, postorder, postorder_parents,...
+					    separator)
+for n=postorder %postorder(1:end-1)
+  for p=postorder_parents{n}
+    %clpot{p} = divide_by_pot(clpot{n}, seppot{p,n}); % dividing by 1 is redundant
+    seppot{p,n} = marginalize_pot(clpot{n}, separator{p,n}, maximize);
+    clpot{p} = multiply_by_pot(clpot{p}, seppot{p,n});
+  end
+end
+
+
+%%%%
+function [clpot, seppot] = distribute_evidence(clpot, seppot, maximize, preorder, preorder_children,...
+					       separator)
+for n=preorder
+  for c=preorder_children{n}
+    clpot{c} = divide_by_pot(clpot{c}, seppot{n,c}); 
+    seppot{n,c} = marginalize_pot(clpot{n}, separator{n,c}, maximize);
+    clpot{c} = multiply_by_pot(clpot{c}, seppot{n,c});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/enter_soft_evidence_trans.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/enter_soft_evidence_trans.m
new file mode 100644
index 00000000..b9c85b80
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/enter_soft_evidence_trans.m
@@ -0,0 +1,135 @@
+function [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type)
+% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (jtree_dbn)
+% [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type, filter)
+
+[ss T] = size(CPDpot);
+Q = length(engine.jtree_struct.cliques);
+clpot = cell(Q,T); % clpot{t} contains evidence from slices (t-1, t) 
+seppot = cell(Q,Q,T);
+ll = zeros(1,Q);
+logscale = zeros(1,T);
+bnet = bnet_from_engine(engine);
+
+% Forwards pass.
+% Compute distribution on clq C,
+% where C is the out interface to (t-1,t).
+% Then pass this to clq D, where D is the in inferface to (t+1,t).
+% Then propagate from D to later slices.
+
+C = engine.out_clq;
+assert(C==engine.jtree_struct.root_clq);
+D = engine.in_clq;
+slice1 = 1:ss;
+slice2 = slice1 + ss;
+Ntransient = length(engine.transient);
+trans = cell(Ntransient,1);
+for t=1:T
+  if t==1
+    pots = [CPDpot(:,1); CPDpot(engine.persist, 2)];
+    clqs = engine.jtree_struct.clq_ass_to_node([slice1 engine.persist+ss]);
+    obs = find(observed(:,1:2));
+  elseif t==T
+    clqs = [D engine.jtree_struct.clq_ass_to_node(engine.transient)];
+    phiC = set_domain_pot(phiC, engine.interface); % shift back to slice 1
+    for i=1:Ntransient
+      trans{i} = CPDpot{engine.transient(i), t};
+      trans{i} = set_domain_pot(trans{i}, domain_pot(trans{i})-ss); % shift back to slice 1
+    end
+    pots = [ {phiC}; trans]; 
+    obs = find(observed(:,T));
+  else
+    clqs = [D engine.jtree_struct.clq_ass_to_node([engine.transient engine.persist+ss])];
+    phiC = set_domain_pot(phiC, engine.interface); % shift back to slice 1
+    for i=1:Ntransient
+      trans{i} = CPDpot{engine.transient(i), t};
+      trans{i} = set_domain_pot(trans{i}, domain_pot(trans{i})-ss); % shift back to slice 1
+    end
+    pots = [ {phiC}; trans; CPDpot(engine.persist, t+1)]; 
+    obs = find(observed(:,t:t+1));
+  end
+  [clpot(:,t), seppot(:,:,t)] =  init_pot(engine.jtree_struct.cliques, clqs, pots, pot_type, ...
+					 obs, bnet.node_sizes(:), bnet.cnodes);
+  [clpot(:,t), seppot(:,:,t)] = collect_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.postorder, ...
+						    engine.jtree_struct.postorder_parents,...
+						    engine.jtree_struct.separator);
+
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  logscale(t) = ll(C);
+
+  phiC = marginalize_pot(clpot{C,t}, engine.interface+ss, engine.maximize);
+end
+
+
+
+% Backwards pass.
+% Pass evidence from clq C to clq D,
+% where C is the in interface to (t,t+1) and D is the out inferface to (t-1,t)
+% Then propagate evidence from D to earlier slices.
+C = engine.in_clq;
+D = engine.out_clq;
+for t=T:-1:1
+  [clpot(:,t), seppot(:,:,t)] = distribute_evidence(clpot(:,t), seppot(:,:,t), engine.maximize, ...
+						    engine.jtree_struct.preorder, ...
+						    engine.jtree_struct.preorder_children, ...
+						    engine.jtree_struct.separator);
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  %logscale(t) = ll(C);
+  
+  if t >= 2
+    phiC = marginalize_pot(clpot{C,t}, engine.interface, engine.maximize);
+    phiC = set_domain_pot(phiC, engine.interface+ss); % shift forward to slice 2
+    phiD = marginalize_pot(clpot{D,t-1}, engine.interface+ss, engine.maximize);
+    ratio = divide_by_pot(phiC, phiD);
+    clpot{D,t-1} = multiply_by_pot(clpot{D,t-1}, ratio);
+  end
+end
+
+loglik = sum(logscale);
+
+
+%%%%%%%
+function [clpot, seppot] = init_pot(cliques, clqs, pots, pot_type, onodes, ns, cnodes);
+
+% Set the clique potentials to all 1s
+C = length(cliques);
+clpot = cell(1,C);
+for i=1:C
+  clpot{i} = mk_initial_pot(pot_type, cliques{i}, ns, cnodes, onodes);
+end
+
+% Multiply on specified potentials
+for i=1:length(clqs)
+  c = clqs(i);
+  clpot{c} = multiply_by_pot(clpot{c}, pots{i});
+end
+
+seppot = cell(C,C); % implicitely initialized to 1
+
+
+%%%%
+function [clpot, seppot] = collect_evidence(clpot, seppot, maximize, postorder, postorder_parents,...
+					    separator)
+for n=postorder %postorder(1:end-1)
+  for p=postorder_parents{n}
+    %clpot{p} = divide_by_pot(clpot{n}, seppot{p,n}); % dividing by 1 is redundant
+    seppot{p,n} = marginalize_pot(clpot{n}, separator{p,n}, maximize);
+    clpot{p} = multiply_by_pot(clpot{p}, seppot{p,n});
+  end
+end
+
+
+%%%%
+function [clpot, seppot] = distribute_evidence(clpot, seppot, maximize, preorder, preorder_children,...
+					       separator)
+for n=preorder
+  for c=preorder_children{n}
+    clpot{c} = divide_by_pot(clpot{c}, seppot{n,c}); 
+    seppot{n,c} = marginalize_pot(clpot{n}, separator{n,c}, maximize);
+    clpot{c} = multiply_by_pot(clpot{c}, seppot{n,c});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/jtree_dbn_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/jtree_dbn_inf_engine.m
new file mode 100644
index 00000000..5b5cc8ba
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/jtree_dbn_inf_engine.m
@@ -0,0 +1,67 @@
+function engine = jtree_dbn_inf_engine(bnet, varargin)
+% JTREE_DBN_INF_ENGINE Junction tree inference algorithm for DBNs.
+
+ss = length(bnet.intra);
+
+onodes = [];
+
+if nargin >= 2
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'observed', onodes = args{i+1};
+    end
+  end
+end
+
+[int, engine.persist, engine.transient] = compute_interface_nodes(bnet.intra, bnet.inter);
+%engine.interface = engine.persist; % WRONG!
+engine.interface = int;
+engine.nonint = mysetdiff(1:ss, int);
+
+if 0
+  % Create a 2 slice jtree
+  % We force there to be cliques containing the in and out interfaces for slices t and t+1.
+  obs_nodes = [onodes(:) onodes(:)+ss];
+  engine.jtree_engine = jtree_inf_engine(bnet, 'observed', obs_nodes(:), ...
+					 'clusters', {int, int+ss}, 'root', int+ss);
+else
+  % Create a "1.5 slice" jtree, containing slice 1 and the interface nodes of slice 2
+  nodes15 = [1:ss int+ss];
+  N = length(nodes15);
+  dag15 = bnet.dag(nodes15, nodes15);
+  ns15 = bnet.node_sizes(nodes15);
+  eclass15 = bnet.equiv_class(nodes15);
+  discrete_bitv = zeros(1,2*ss);
+  discrete_bitv(bnet.dnodes) = 1;
+  discrete15 = find(discrete_bitv(nodes15));
+  bnet15 = mk_bnet(dag15, ns15, 'equiv_class', eclass15, 'discrete', discrete15);
+  bnet15.CPD = bnet.CPD; % CPDs for non-interface nodes in slice 2 will not be used
+  obs_bitv = zeros(1, 2*ss);
+  obs_bitv([onodes onodes+ss]) = 1;
+  obs_nodes15 = find(obs_bitv(nodes15));
+  int_bitv = zeros(1,ss);
+  int_bitv(int) = 1;
+  engine.jtree_engine = jtree_inf_engine(bnet15, 'observed', obs_nodes15(:), ...
+				     'clusters', {int, int+ss}, 'root', int+ss);
+end
+
+engine.in_clq = clq_containing_nodes(engine.jtree_engine, int);
+engine.out_clq = clq_containing_nodes(engine.jtree_engine, int+ss);
+
+engine.clq_ass_to_node = zeros(ss, 2);
+for i=1:ss
+  engine.clq_ass_to_node(i, 1) = clq_containing_nodes(engine.jtree_engine, i);
+  engine.clq_ass_to_node(i, 2) = clq_containing_nodes(engine.jtree_engine, i+ss);
+end
+
+engine.jtree_struct = struct(engine.jtree_engine); % violate object privacy
+
+% stuff needed by marginal_nodes
+engine.clpot = [];
+engine.maximize = [];
+engine.T = [];
+
+engine = class(engine, 'jtree_dbn_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/jtree_dbn_inf_engine1.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/jtree_dbn_inf_engine1.m
new file mode 100644
index 00000000..5edad836
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/jtree_dbn_inf_engine1.m
@@ -0,0 +1,62 @@
+function engine = jtree_dbn_inf_engine(bnet, varargin)
+% JTREE_DBN_INF_ENGINE Junction tree inference algorithm for DBNs.
+
+ss = length(bnet.intra);
+
+onodes = [];
+
+if nargin >= 2
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'observed', onodes = args{i+1};
+    end
+  end
+end
+
+[int, engine.persist, engine.transient] = compute_interface_nodes(bnet.intra, bnet.inter);
+%engine.interface = engine.persist; % WRONG!
+engine.interface = int;
+engine.nonint = mysetdiff(1:ss, int);
+
+if 1
+  % Create a 2 slice jtree
+  % We force there to be cliques containing the in and out interfaces for slices t and t+1.
+  obs_nodes = [onodes(:) onodes(:)+ss];
+  engine.jtree_engine = jtree_inf_engine(bnet, 'observed', obs_nodes(:), ...
+					 'clusters', {int, int+ss}, 'root', int+ss);
+else
+  % Create a "1.5 slice" jtree, containing slice 1 and the interface nodes of slice 2
+  % To keep the node numbering the same, we simply disconnect the non-interface nodes
+  % from slice 2.
+  intra15 = bnet.intra;
+  for i=engine.nonint(:)'
+    intra15(i,:) = 0;
+    intra15(:,i) = 0;
+  end
+  bnet15 = mk_dbn(intra15, bnet.inter, bnet.node_sizes_slice, bnet.dnodes_slice, ...
+		  bnet.equiv_class(:,1), bnet.equiv_class(:,2), bnet.intra);
+  obs_nodes = [onodes(:) onodes(:)+ss];
+  engine.jtree_engine = jtree_inf_engine(bnet15, 'observed', obs_nodes(:), ...
+				     'clusters', {int, int+ss}, 'root', int+ss);
+end
+
+engine.in_clq = clq_containing_nodes(engine.jtree_engine, int);
+engine.out_clq = clq_containing_nodes(engine.jtree_engine, int+ss);
+
+engine.clq_ass_to_node = zeros(ss, 2);
+for i=1:ss
+  engine.clq_ass_to_node(i, 1) = clq_containing_nodes(engine.jtree_engine, i);
+  engine.clq_ass_to_node(i, 2) = clq_containing_nodes(engine.jtree_engine, i+ss);
+end
+
+engine.jtree_struct = struct(engine.jtree_engine); % violate object privacy
+
+% stuff needed by marginal_nodes
+engine.clpot = [];
+engine.maximize = [];
+engine.T = [];
+
+engine = class(engine, 'jtree_dbn_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/jtree_dbn_inf_engine2.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/jtree_dbn_inf_engine2.m
new file mode 100644
index 00000000..68ac2aff
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/Old/jtree_dbn_inf_engine2.m
@@ -0,0 +1,57 @@
+function engine = jtree_dbn_inf_engine(bnet, varargin)
+% JTREE_DBN_INF_ENGINE Junction tree inference algorithm for DBNs.
+
+ss = length(bnet.intra);
+
+onodes = [];
+
+if nargin >= 2
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'observed', onodes = args{i+1};
+    end
+  end
+end
+
+[int, engine.persist, engine.transient] = compute_interface_nodes(bnet.intra, bnet.inter);
+%engine.interface = engine.persist; % WRONG!
+engine.interface = int;
+engine.nonint = mysetdiff(1:ss, int);
+
+
+% Create a 2 slice jtree
+% We force there to be cliques containing the in and out interfaces for slices t and t+1.
+obs_nodes = [onodes(:) onodes(:)+ss];
+engine.jtree_engine = jtree_inf_engine(bnet, 'observed', obs_nodes(:), ...
+					 'clusters', {int, int+ss}, 'root', int+ss);
+
+engine.in_clq = clq_containing_nodes(engine.jtree_engine, int);
+engine.out_clq = clq_containing_nodes(engine.jtree_engine, int+ss);
+engine.jtree_struct = struct(engine.jtree_engine); % violate object privacy
+
+
+
+% Also create an engine just for slice 1
+bnet1 = mk_bnet(bnet.intra1, bnet.node_sizes_slice, bnet.dnodes, bnet.equiv_class(:,1));
+for i=1:max(bnet1.equiv_class)
+  bnet1.CPD{i} = bnet.CPD{i};
+end
+
+engine.jtree_engine1 = jtree_inf_engine(bnet1, 'observed', onodes, 'clusters', {int}, ...
+					'root', int);
+
+engine.in_clq1 = clq_containing_nodes(engine.jtree_engine1, int);
+engine.jtree_struct1 = struct(engine.jtree_engine1); % violate object privacy
+
+
+
+
+% stuff needed by marginal_nodes
+engine.clpot = [];
+engine.T = [];
+engine.maximize = [];
+
+engine = class(engine, 'jtree_dbn_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..e21bb07d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/enter_evidence.m
@@ -0,0 +1,70 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (jtree_dbn)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product instead of sum-product [engine.maximize]
+% softCPDpot{n,t} - use soft potential for node n instead of its CPD; set to [] to use CPD
+% soft_evidence_nodes(i,1:2) = [n t] means the i'th piece of soft evidence is on node n in slice t 
+% soft_evidence{i} - prob distribution over values for soft_evidence_nodes(i,:)
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+
+% for add_ev in marginal_nodes
+T = size(evidence, 2);
+engine.evidence = evidence;
+bnet = bnet_from_engine(engine);
+ss = length(bnet.node_sizes_slice);
+ns = bnet.node_sizes_slice(:);
+engine.node_sizes = repmat(ns, [1 T]);
+softCPDpot = cell(ss,T);
+soft_evidence = {};
+soft_evidence_nodes = [];
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', engine.maximize = args{i+1}; 
+     case 'softCPDpot', softCPDpot = args{i+1};
+     case 'soft_evidence', soft_evidence = args{i+1};
+     case 'soft_evidence_nodes', soft_evidence_nodes = args{i+1};
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+engine.jtree_engine = set_fields(engine.jtree_engine, 'maximize', engine.maximize);
+engine.jtree_engine1 = set_fields(engine.jtree_engine1, 'maximize', engine.maximize);
+
+[ss T] = size(evidence);
+engine.T = T;
+observed_bitv = ~isemptycell(evidence);
+onodes = find(observed_bitv);
+pot_type = determine_pot_type(bnet, onodes);
+CPDpot = convert_dbn_CPDs_to_pots(bnet, evidence, pot_type, softCPDpot);
+
+if ~isempty(soft_evidence_nodes)
+  nsoft = size(soft_evidence_nodes,1);
+  for i=1:nsoft
+    n = soft_evidence_nodes(i,1);
+    t = soft_evidence_nodes(i,2);
+    if t==1
+      dom = n;
+    else
+      dom = n+ss;
+    end
+    pot = dpot(dom, ns(n), soft_evidence{i});
+    CPDpot{n,t} = multiply_by_pot(CPDpot{n,t}, pot);
+  end
+end
+  
+[engine.clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed_bitv, pot_type);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/enter_soft_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/enter_soft_evidence.m
new file mode 100644
index 00000000..5ffc55b0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/enter_soft_evidence.m
@@ -0,0 +1,126 @@
+function [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type)
+% ENTER_SOFT_EVIDENCE Add the specified soft evidence to the network (jtree_dbn)
+% [clpot, loglik] = enter_soft_evidence(engine, CPDpot, observed, pot_type)
+
+scale = 1;
+verbose = 0;
+
+[ss T] = size(CPDpot);
+Q = length(engine.jtree_struct.cliques);
+clpot = cell(Q,T); % clpot{t} contains evidence from slices (t-1, t) 
+seppot = cell(Q,Q,T);
+ll = zeros(1,Q);
+logscale = zeros(1,T);
+bnet = bnet_from_engine(engine);
+root = engine.jtree_struct.root_clq;
+
+% Forwards pass.
+% Compute distribution on clq C,
+% where C is the out interface to (t-1,t).
+% Then pass this to clq D, where D is the in inferface to (t+1,t).
+
+% Then propagate from D to later slices.
+
+slice1 = 1:ss;
+slice2 = slice1 + ss; 
+transient = engine.transient;
+persist = engine.persist;
+Ntransient = length(transient);
+trans = cell(Ntransient,1);
+if verbose, fprintf('forward pass\n'); end
+for t=1:T
+  if verbose, fprintf('%d ', t); end
+  if t==1
+    pots = [CPDpot(:,1); CPDpot(persist, 2)];
+    clqs = engine.jtree_struct.clq_ass_to_node([slice1 persist+ss]);
+    obs = find(observed(:,1:2));
+  elseif t==T
+    clqs = [engine.in_clq1 engine.jtree_struct1.clq_ass_to_node(transient)];
+    phi = set_domain_pot(phi, engine.interface); % shift back to slice 1
+    for i=1:Ntransient
+      trans{i} = CPDpot{transient(i), t};
+      trans{i} = set_domain_pot(trans{i}, domain_pot(trans{i})-ss); % shift back to slice 1
+    end
+    pots = [ {phi}; trans]; 
+    obs = find(observed(:,T));
+  else
+    clqs = [engine.in_clq engine.jtree_struct.clq_ass_to_node([transient persist+ss])];
+    phi = set_domain_pot(phi, engine.interface); % shift back to slice 1
+    for i=1:Ntransient
+      trans{i} = CPDpot{transient(i), t};
+      trans{i} = set_domain_pot(trans{i}, domain_pot(trans{i})-ss); % shift back to slice 1
+    end
+    pots = [ {phi}; trans; CPDpot(persist, t+1)]; 
+    obs = find(observed(:,t:t+1));
+  end
+
+  if t < T
+    [clpot(1:Q,t), seppot(1:Q,1:Q,t)] =  init_pot(engine.jtree_engine, clqs, pots, pot_type, obs);
+    [clpot(1:Q,t), seppot(1:Q,1:Q,t)] = collect_evidence(engine.jtree_engine, clpot(1:Q,t), seppot(1:Q,1:Q,t));
+  else
+    Q = length(engine.jtree_struct1.cliques);
+    root = engine.jtree_struct1.root_clq;
+    [clpot(1:Q,t), seppot(1:Q,1:Q,t)] =  init_pot(engine.jtree_engine1, clqs, pots, pot_type, obs);
+    [clpot(1:Q,t), seppot(1:Q,1:Q,t)] = collect_evidence(engine.jtree_engine1, clpot(1:Q,t), seppot(1:Q,1:Q,t));
+  end
+
+
+  if scale
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  logscale(t) = ll(root);
+  end
+  
+  if t < T
+    % bug fix by Bob Welch 30 Jan 04
+    phi = marginalize_pot(clpot{engine.out_clq,t}, engine.interface+ss,engine.maximize);
+    %phi = marginalize_pot(clpot{root,t}, engine.interface+ss, engine.maximize);
+  end
+end
+
+if scale
+loglik = sum(logscale);
+else
+loglik = [];
+end
+
+
+% Backwards pass.
+% Pass evidence from clq C to clq D,
+% where C is the in interface to (t,t+1) and D is the out inferface to (t-1,t)
+% Then propagate evidence from D to earlier slices.
+% (C and D are reversed names from the tech report!)
+D = engine.out_clq;
+if verbose, fprintf('\nbackwards pass\n'); end
+for t=T:-1:1
+  if verbose, fprintf('%d ', t); end
+  
+  if t == T
+    Q = length(engine.jtree_struct1.cliques);
+    C = engine.in_clq1;
+    [clpot(1:Q,t), seppot(1:Q,1:Q,t)] = distribute_evidence(engine.jtree_engine1, clpot(1:Q,t), seppot(1:Q,1:Q,t));
+  else
+    Q = length(engine.jtree_struct.cliques);
+    C = engine.in_clq;
+    [clpot(1:Q,t), seppot(1:Q,1:Q,t)] = distribute_evidence(engine.jtree_engine, clpot(1:Q,t), seppot(1:Q,1:Q,t));
+  end
+
+  if scale
+  for c=1:Q
+    [clpot{c,t}, ll(c)] = normalize_pot(clpot{c,t});
+  end
+  end
+  
+  if t >= 2
+    phiC = marginalize_pot(clpot{C,t}, engine.interface, engine.maximize);
+    phiC = set_domain_pot(phiC, engine.interface+ss); % shift forward to slice 2
+    phiD = marginalize_pot(clpot{D,t-1}, engine.interface+ss, engine.maximize);
+    ratio = divide_by_pot(phiC, phiD);
+    clpot{D,t-1} = multiply_by_pot(clpot{D,t-1}, ratio);
+  end
+end
+if verbose, fprintf('\n'); end
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/jtree_dbn_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/jtree_dbn_inf_engine.m
new file mode 100644
index 00000000..c49ba4c4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/jtree_dbn_inf_engine.m
@@ -0,0 +1,109 @@
+function engine = jtree_dbn_inf_engine(bnet, varargin)
+% JTREE_DBN_INF_ENGINE Junction tree inference algorithm for DBNs.
+% engine = jtree_inf_engine(bnet, ...)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% clusters - specifies variables that must be grouped in the 1.5 slice DBN
+% maximize - 1 means max-product, 0 means sum-product [0]
+%
+% e.g., engine = jtree_dbn_inf_engine(dbn, 'clusters', {[1 2]});
+%
+% This uses all of slice t-1 plus the backwards interface of slice t.
+% By contrast, jtree_2TBN_inf_engine in the online directory uses
+% the forwards interface of slice t-1 plus all of slice t.
+% See my thesis for details.
+
+ss = length(bnet.intra);
+
+engine.maximize = 0;
+clusters = {};
+
+args = varargin;
+for i=1:2:length(args)
+  switch args{i},
+   case 'clusters', clusters = args{i+1};
+   case 'maximize', engine.maximize = args{i+1};
+   otherwise, error(['unrecognized argument ' args{i}])
+  end
+end
+
+
+engine.evidence = [];
+engine.node_sizes = [];
+
+[int, engine.persist, engine.transient] = compute_interface_nodes(bnet.intra, bnet.inter);
+engine.interface = int;
+engine.nonint = mysetdiff(1:ss, int);
+
+onodes = bnet.observed;
+
+if 0
+  % Create a 2 slice jtree
+  % We force there to be cliques containing the in and out interfaces for slices t and t+1.
+  obs_nodes = [onodes(:) onodes(:)+ss];
+  engine.jtree_engine = jtree_inf_engine(bnet, 'observed', obs_nodes(:), ...
+					 'clusters', {int, int+ss}, 'root', int+ss);
+else
+  % Create a "1.5 slice" jtree, containing slice 1 and the interface nodes of slice 2
+  % To keep the node numbering the same, we simply disconnect the non-interface nodes
+  % from slice 2, and set their size to 1.
+  % We do this to speed things up, and so that the likelihood is computed correctly - we do not need to do
+  % this if we just want to compute marginals. 
+  intra15 = bnet.intra;
+  for i=engine.nonint(:)'
+    intra15(i,:) = 0;
+    intra15(:,i) = 0;
+  end
+  dag15 = [bnet.intra bnet.inter;
+	 zeros(ss)    intra15];
+  ns = bnet.node_sizes(:);
+  ns(engine.nonint+ss) = 1; % disconnected nodes get size 1
+  obs_nodes = [onodes(:) onodes(:)+ss];
+  bnet15 = mk_bnet(dag15, ns, 'discrete', bnet.dnodes, 'equiv_class', bnet.equiv_class(:), ...
+		   'observed', obs_nodes(:));
+
+  %bnet15 = mk_dbn(intra15, bnet.inter, bnet.node_sizes_slice, bnet.dnodes_slice, ...
+  %		  bnet.equiv_class(:,1), bnet.equiv_class(:,2), bnet.intra);
+  % with the dbn, we can't independently control the sizes of slice 2 nodes
+  
+  if 1
+    % use unconstrained elimination,
+    % but force there to be a clique containing both interfaces
+    clusters(end+1:end+2) = {int, int+ss};
+    engine.jtree_engine = jtree_inf_engine(bnet15, 'clusters', clusters, 'root', int+ss);
+  else
+    % Use constrained elimination - this induces a clique that contain the 2nd interface,
+    % but not the first.
+    % Hence we throw in the first interface as an extra.
+    stages = {1:ss, [1:ss]+ss};
+    clusters(end+1:end+2) = {int, int+ss};
+    engine.jtree_engine = jtree_inf_engine(bnet15, 'clusters', clusters, ...
+					   'stages', stages, 'root', int+ss);
+  end
+end
+
+engine.in_clq = clq_containing_nodes(engine.jtree_engine, int);
+engine.out_clq = clq_containing_nodes(engine.jtree_engine, int+ss);
+engine.jtree_struct = struct(engine.jtree_engine); % violate object privacy
+
+
+% Also create an engine just for slice 1
+bnet1 = mk_bnet(bnet.intra1, bnet.node_sizes_slice, 'discrete', myintersect(bnet.dnodes,1:ss), ...
+		'equiv_class', bnet.equiv_class(:,1), 'observed', onodes);
+for i=1:max(bnet1.equiv_class)
+  bnet1.CPD{i} = bnet.CPD{i};
+end
+
+engine.jtree_engine1 = jtree_inf_engine(bnet1, 'clusters', {int}, 'root', int);
+
+engine.in_clq1 = clq_containing_nodes(engine.jtree_engine1, int);
+engine.jtree_struct1 = struct(engine.jtree_engine1); % violate object privacy
+
+% stuff needed by marginal_nodes
+engine.clpot = [];
+engine.T = [];
+
+engine = class(engine, 'jtree_dbn_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/marginal_family.m
new file mode 100644
index 00000000..1fe59f61
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/marginal_family.m
@@ -0,0 +1,26 @@
+function m = marginal_family(engine, i, t, add_ev)
+% MARGINAL_FAMILY Compute the marginal on the specified family (jtree_dbn)
+% marginal = marginal_family(engine, i, t)
+
+% This is just like inf_engine/marginal_family, except when we call
+% marginal_nodes, we provide a 4th argument, to tell it's a family.
+
+if nargin < 3, t = 1; end
+if nargin < 4, add_ev = 0; end
+
+bnet = bnet_from_engine(engine);
+if t==1
+  m = marginal_nodes(engine, family(bnet.dag, i), t, add_ev, 1);
+else
+  ss = length(bnet.intra);
+  fam = family(bnet.dag, i+ss);
+  if any(fam<=ss)
+    % i has a parent in the preceeding slice
+    % Hence the lowest numbered slice containing the family is t-1
+    m = marginal_nodes(engine, fam, t-1, add_ev, 1);
+  else
+    % The family all fits inside slice t
+    % Hence shift the indexes back to slice 1
+    m = marginal_nodes(engine, fam-ss, t, add_ev, 1);
+  end
+end     
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..c9a40488
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_dbn_inf_engine/marginal_nodes.m
@@ -0,0 +1,66 @@
+function marginal = marginal_nodes(engine, nodes, t, add_ev, fam)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (bk)
+%
+%   marginal = marginal_nodes(engine, i, t)
+% returns Pr(X(i,t) | Y(1:T)), where X(i,t) is the i'th node in the t'th slice.
+%
+%   marginal = marginal_nodes(engine, query, t)
+% returns Pr(X(query(1),t), ... X(query(end),t) | Y(1:T)),
+% where 't' specifies the time slice of the earliest node in the query.
+% 'query' cannot span more than 2 time slices.
+%
+% Example:
+% Consider a DBN with 2 nodes per slice.
+% Then t=2, nodes=[1 3] refers to node 1 in slice 2 and node 1 in slice 3.
+%
+% marginal = marginal_nodes(engine, nodes, t, add_ev, fam)
+% add_ev is an optional argument; if 1, we will "inflate" the marginal of observed nodes
+% to their original size, adding 0s to the positions which contradict the evidence
+   
+if nargin < 3, t = 1; end
+if nargin < 4, add_ev = 0; end
+if nargin < 5, fam = 0; end
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+
+if t==1 | t==engine.T
+  slice = t;
+  nodes2 = nodes;
+elseif mysubset(nodes, engine.persist)
+  slice = t-1;
+  nodes2 = nodes+ss;
+else
+  slice = t;
+  nodes2 = nodes;
+end
+
+%disp(['computing marginal on ' num2str(nodes) ' t = ' num2str(t) ' fam = ' num2str(fam)]);
+
+if t==engine.T
+  c = clq_containing_nodes(engine.jtree_engine1, nodes2, fam);
+else
+  c = clq_containing_nodes(engine.jtree_engine, nodes2, fam);
+end
+if c == -1
+  error(['no clique contains ' nodes2])
+end
+
+
+%disp(['using ' num2str(nodes2) ' slice = ' num2str(slice) ' clq = ' num2str(c)]);
+
+bigpot = engine.clpot{c, slice};
+
+pot = marginalize_pot(bigpot, nodes2, engine.maximize);
+%pot = normalize_pot(pot);
+marginal = pot_to_marginal(pot);
+
+
+% we convert the domain to the unrolled numbering system
+% so that add_ev_to_dmarginal (maybe called in update_ess) extracts the right evidence.
+marginal.domain = nodes+(t-1)*ss;
+
+if add_ev
+  marginal = add_ev_to_dmarginal(marginal, engine.evidence, engine.node_sizes);
+end    
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/CVS/Entries
new file mode 100644
index 00000000..2809c39f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/CVS/Entries
@@ -0,0 +1,6 @@
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/jtree_unrolled_dbn_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/update_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D/Old////
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/CVS/Repository
new file mode 100644
index 00000000..e9fd6fe5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/CVS/Entries
new file mode 100644
index 00000000..eafb1997
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/CVS/Entries
@@ -0,0 +1,3 @@
+/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/CVS/Repository
new file mode 100644
index 00000000..2ad645e2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/marginal_family.m
new file mode 100644
index 00000000..efb38b26
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/marginal_family.m
@@ -0,0 +1,10 @@
+function marginal = marginal_family(engine, i, t)
+% MARGINAL_FAMILY Compute the marginal on the specified family (jtree_unrolled_dbn)
+% marginal = marginal_family(engine, i, t)
+
+if nargin < 3, t = 1; end
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+marginal = marginal_family(engine.sub_engine, i + (t-1)*ss);
+ 
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/marginal_nodes.m
new file mode 100644
index 00000000..b0cfb04e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/Old/marginal_nodes.m
@@ -0,0 +1,18 @@
+function marginal = marginal_nodes(engine, nodes, t)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (jtree_unrolled_dbn)
+% marginal = marginal_nodes(engine, nodes, t)
+%
+% 't' specifies the time slice of the earliest node in 'nodes'.
+% 'nodes' must occur in some clique.
+%
+% Example:
+% Consider a DBN with 2 nodes per slice.
+% Then t=2, nodes=[1 3] refers to node 1 in slice 2 and node 1 in slice 3,
+% i.e., nodes 3 and 5 in the unrolled network,
+
+if nargin < 3, t = 1; end
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+query = nodes + (t-1)*ss;
+marginal = marginal_nodes(engine.sub_engine, query);    
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..48b230c9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/enter_evidence.m
@@ -0,0 +1,43 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (jtree_unrolled_dbn)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+% 
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product instead of sum-product [0]
+% filter   - if 1, does filtering (not supported), else smoothing [0]
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+maximize = 0;
+filter = 0;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', maximize = args{i+1}; 
+     case 'filter',  filter = args{i+1}; 
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+if filter
+  error('jtree_unrolled_dbn does not support filtering')
+end
+
+if size(evidence,2) ~= engine.nslices
+  error(['engine was created assuming there are ' num2str(engine.nslices) ...
+	 ' slices, but evidence has ' num2str(size(evidence,2))])
+end
+
+[engine.unrolled_engine, loglik] = enter_evidence(engine.unrolled_engine, evidence, 'maximize', maximize);
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/jtree_unrolled_dbn_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/jtree_unrolled_dbn_inf_engine.m
new file mode 100644
index 00000000..156c6ee2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/jtree_unrolled_dbn_inf_engine.m
@@ -0,0 +1,57 @@
+function engine = jtree_unrolled_dbn_inf_engine(bnet, T, varargin)
+% JTREE_UNROLLED_DBN_INF_ENGINE Unroll the DBN for T time-slices and apply jtree to the resulting static net
+% engine = jtree_unrolled_dbn_inf_engine(bnet, T, ...)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% useC      - 1 means use jtree_C_inf_engine instead of jtree_inf_engine [0]
+% constrained - 1 means we constrain ourselves to eliminate slice t before t+1 [1]
+%
+% e.g., engine = jtree_unrolled_inf_engine(bnet, 'useC', 1);
+
+% set default params
+N = length(bnet.intra);
+useC = 0;
+constrained = 1;
+
+if nargin >= 3
+  args = varargin;
+  nargs = length(args);
+  if isstr(args{1})
+    for i=1:2:nargs
+      switch args{i},
+       case 'useC',   useC = args{i+1};
+       case 'constrained',  constrained = args{i+1};
+       otherwise,  
+	error(['invalid argument name ' args{i}]);       
+      end
+    end
+  else
+    error(['invalid argument name ' args{1}]);       
+  end
+end
+
+bnet2 = dbn_to_bnet(bnet, T);
+ss = length(bnet.intra);
+engine.ss = ss;
+
+% If constrained_order = 1 we constrain ourselves to eliminate slice t before t+1.
+% This prevents cliques containing nodes from far-apart time-slices.
+if constrained
+  stages = num2cell(unroll_set(1:ss, ss, T), 1);
+else
+  stages = { 1:length(bnet2.dag) };
+end
+if useC
+  jengine = jtree_C_inf_engine(bnet2, 'stages', stages);
+else
+  jengine = jtree_inf_engine(bnet2, 'stages', stages);
+end
+
+engine.unrolled_engine = jengine;
+% we don't inherit from jtree_inf_engine, because that would only store bnet2,
+% and we would lose access to the DBN-specific fields like intra/inter
+
+engine.nslices = T;
+engine = class(engine, 'jtree_unrolled_dbn_inf_engine', inf_engine(bnet));
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/marginal_family.m
new file mode 100644
index 00000000..a40f2974
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/marginal_family.m
@@ -0,0 +1,11 @@
+function marginal = marginal_family(engine, i, t, add_ev)
+% MARGINAL_FAMILY Compute the marginal on the specified family (jtree_unrolled_dbn)
+% marginal = marginal_family(engine, i, t)
+
+if nargin < 3, t = 1; end
+if nargin < 4, add_ev = 0; end
+assert(~add_ev);
+
+%marginal = marginal_family(engine.unrolled_engine, i + (t-1)*engine.ss, add_ev);
+marginal = marginal_family(engine.unrolled_engine, i + (t-1)*engine.ss);
+              
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..0fb095e5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/marginal_nodes.m
@@ -0,0 +1,16 @@
+function marginal = marginal_nodes(engine, nodes, t, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (loopy_unrolled_dbn)
+% marginal = marginal_nodes(engine, nodes, t)
+%
+% 't' specifies the time slice of the earliest node in 'nodes'.
+% 'nodes' must occur in some clique.
+%
+% Example:
+% Consider a DBN with 2 nodes per slice.
+% Then t=2, nodes=[1 3] refers to node 1 in slice 2 and node 1 in slice 3,
+% i.e., nodes 3 and 5 in the unrolled network,
+
+if nargin < 3, t = 1; end
+if nargin < 4, add_ev = 0; end
+
+marginal = marginal_nodes(engine.unrolled_engine, nodes + (t-1)*engine.ss, add_ev);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/update_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/update_engine.m
new file mode 100644
index 00000000..5c42d4f6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@jtree_unrolled_dbn_inf_engine/update_engine.m
@@ -0,0 +1,7 @@
+function engine = update_engine(engine, newCPDs)
+% UPDATE_ENGINE Update the engine to take into account the new parameters (jtree_unrolled_dbn)
+% engine = update_engine(engine, newCPDs)
+
+engine.inf_engine = update_engine(engine.inf_engine, newCPDs);
+engine.unrolled_engine = update_engine(engine.unrolled_engine, newCPDs);
+                                                            
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/CVS/Entries
new file mode 100644
index 00000000..dce274e1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/CVS/Entries
@@ -0,0 +1,5 @@
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/kalman_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/update_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D/private////
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/CVS/Repository
new file mode 100644
index 00000000..674f2eea
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@kalman_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..4ba51942
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/enter_evidence.m
@@ -0,0 +1,83 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (kalman)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product (same as sum-product for Gaussians!), else sum-product [0]
+% filter -   if 1, do filtering, else smoothing [0]
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+maximize = 0;
+filter = 0;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', maximize = args{i+1}; 
+     case 'filter', filter = args{i+1}; 
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+assert(~maximize);
+
+bnet = bnet_from_engine(engine);
+n = length(bnet.intra);
+onodes = bnet.observed;
+hnodes = mysetdiff(1:n, onodes);
+T = size(evidence, 2);
+ns = bnet.node_sizes;
+O = sum(ns(onodes));
+data = reshape(cat(1, evidence{onodes,:}), [O T]);
+
+A = engine.trans_mat;
+C = engine.obs_mat;
+Q = engine.trans_cov;
+R = engine.obs_cov;
+init_x = engine.init_state;
+init_V = engine.init_cov;
+
+if filter
+  [x, V, VV, loglik] = kalman_filter(data, A, C, Q, R, init_x, init_V);
+else
+  [x, V, VV, loglik] = kalman_smoother(data, A, C, Q, R, init_x, init_V);
+end
+
+  
+% Wrap the posterior inside a potential, so it can be marginalized easily
+engine.one_slice_marginal = cell(1,T);
+engine.two_slice_marginal = cell(1,T);
+ns(onodes) = 0;
+ns(onodes+n) = 0;
+ss = length(bnet.intra);
+for t=1:T
+  dom = (1:n);
+  engine.one_slice_marginal{t} = mpot(dom+(t-1)*ss, ns(dom), 1, x(:,t), V(:,:,t));
+end
+% for t=1:T-1
+%   dom = (1:(2*n));
+%   mu = [x(:,t); x(:,t)];
+%   Sigma = [V(:,:,t) VV(:,:,t+1)';
+% 	   VV(:,:,t+1) V(:,:,t+1)];
+%   engine.two_slice_marginal{t} = mpot(dom+(t-1)*ss, ns(dom), 1, mu, Sigma);
+% end
+for t=2:T
+  %dom = (1:(2*n));
+  current_slice = hnodes;
+  next_slice = hnodes + ss;
+  dom = [current_slice next_slice];   
+  mu = [x(:,t-1); x(:,t)];
+  Sigma = [V(:,:,t-1) VV(:,:,t)';
+	   VV(:,:,t) V(:,:,t)];
+  engine.two_slice_marginal{t-1} = mpot(dom+(t-2)*ss, ns(dom), 1, mu, Sigma);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/kalman_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/kalman_inf_engine.m
new file mode 100644
index 00000000..df03a56f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/kalman_inf_engine.m
@@ -0,0 +1,23 @@
+function engine = kalman_inf_engine(bnet)
+% KALMAN_INF_ENGINE Inference engine for Linear-Gaussian state-space models.
+% engine = kalman_inf_engine(bnet)
+%
+% 'onodes' specifies which nodes are observed; these must be leaves.
+% The remaining nodes are all hidden. All nodes must have linear-Gaussian CPDs.
+% The hidden nodes must be persistent, i.e., they must have children in
+% the next time slice. In addition, they may not have any children within the current slice,
+% except to the observed leaves. In other words, the topology must be isomorphic to a standard LDS.
+%
+% There are many derivations of the filtering and smoothing equations for Linear Dynamical
+% Systems in the literature. I particularly like the following
+% - "From HMMs to LDSs", T. Minka, MIT Tech Report, (no date), available from
+%    ftp://vismod.www.media.mit.edu/pub/tpminka/papers/minka-lds-tut.ps.gz
+
+[engine.trans_mat, engine.trans_cov, engine.obs_mat, engine.obs_cov, engine.init_state, engine.init_cov] = ...
+    dbn_to_lds(bnet);
+
+% This is where we will store the results between enter_evidence and marginal_nodes
+engine.one_slice_marginal = [];
+engine.two_slice_marginal = [];
+
+engine = class(engine, 'kalman_inf_engine', inf_engine(bnet));
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..738c30dc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/marginal_nodes.m
@@ -0,0 +1,25 @@
+function marginal = marginal_nodes(engine, nodes, t)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (kalman)
+% marginal = marginal_nodes(engine, nodes, t)
+%
+% 't' specifies the time slice of the earliest node in 'nodes'.
+% 'nodes' cannot span more than 2 time slices.
+%
+% Example:
+% Consider a DBN with 2 nodes per slice.
+% Then t=2, nodes=[1 3] refers to node 1 in slice 2 and node 1 in slice 3,
+% i.e., nodes 3 and 5 in the unrolled network,
+
+if nargin < 3, t = 1; end
+
+bnet = bnet_from_engine(engine);
+ss = length(bnet.intra);
+if all(nodes <= ss)
+  bigpot = engine.one_slice_marginal{t};
+else
+  bigpot = engine.two_slice_marginal{t};
+end
+
+nodes = nodes + (t-1)*ss;
+pot = marginalize_pot(bigpot, nodes);
+marginal = pot_to_marginal(pot);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/CVS/Entries
new file mode 100644
index 00000000..9a351a87
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/CVS/Entries
@@ -0,0 +1,3 @@
+/dbn_to_lds.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/extract_params_from_gbn.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/CVS/Repository
new file mode 100644
index 00000000..3f67aee0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@kalman_inf_engine/private
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/dbn_to_lds.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/dbn_to_lds.m
new file mode 100644
index 00000000..6249ac0d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/dbn_to_lds.m
@@ -0,0 +1,26 @@
+function [trans_mat, trans_cov, obs_mat, obs_cov, init_state, init_cov] = dbn_to_lds(bnet)
+% DBN_TO_LDS Compute the Linear Dynamical System parameters from the Gaussian DBN.
+% [trans_mat, trans_cov, obs_mat, obs_cov, init_state, init_cov] = dbn_to_lds(bnet)
+
+onodes = bnet.observed;
+ss = length(bnet.intra);
+num_nodes = ss*2;
+assert(isequal(bnet.cnodes_slice, 1:ss));
+[W,D,mu] = extract_params_from_gbn(bnet);
+
+hnodes = mysetdiff(1:ss, onodes);
+bs = bnet.node_sizes(:); % block sizes
+
+obs_mat = W(block(hnodes,bs), block(onodes,bs))';
+u = block(onodes,bs);
+obs_cov = D(u,u);
+
+trans_mat = W(block(hnodes,bs), block(hnodes + ss, bs))';
+u = block(hnodes + ss, bs);
+trans_cov = D(u,u);
+
+u = block(hnodes,bs);
+init_cov = D(u,u);
+init_state = mu(u);
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/extract_params_from_gbn.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/extract_params_from_gbn.m
new file mode 100644
index 00000000..86345830
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/private/extract_params_from_gbn.m
@@ -0,0 +1,38 @@
+function [B,D,mu] = extract_params_from_gbn(bnet)
+% Extract all the local parameters of each Gaussian node, and collect them into global matrices.
+% [B,D,mu] = extract_params_from_gbn(bnet)
+%
+% B(i,j) is a block matrix that contains the transposed weight matrix from node i to node j.
+% D(i,i) is a block matrix that contains the noise covariance matrix for node i.
+% mu(i) is a block vector that contains the shifted noise mean for node i.
+
+% In Shachter's model, the mean of each node in the global gaussian is
+% the same as the node's local unconditional mean.
+% In Alag's model (which we use), the global mean gets shifted.
+
+
+num_nodes = length(bnet.dag);
+bs = bnet.node_sizes(:); % bs = block sizes
+N = sum(bs); % num scalar nodes
+
+B = zeros(N,N);
+D = zeros(N,N);
+mu = zeros(N,1);
+
+for i=1:num_nodes % in topological order
+  ps = parents(bnet.dag, i);
+  e = bnet.equiv_class(i);
+  %[m, Sigma, weights] = extract_params_from_CPD(bnet.CPD{e});
+  s = struct(bnet.CPD{e}); % violate privacy of object
+  m = s.mean; Sigma = s.cov; weights = s.weights;
+  if length(ps) == 0
+    mu(block(i,bs)) = m;
+  else
+    mu(block(i,bs)) = m + weights *  mu(block(ps,bs));
+  end
+  B(block(ps,bs), block(i,bs)) = weights';
+  D(block(i,bs), block(i,bs)) = Sigma;
+end
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/update_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/update_engine.m
new file mode 100644
index 00000000..d89605e7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@kalman_inf_engine/update_engine.m
@@ -0,0 +1,9 @@
+function engine = update_engine(engine, newCPDs)
+% UPDATE_ENGINE Update the engine to take into account the new parameters (kalman)
+% engine = update_engine(engine, newCPDs)
+
+engine.inf_engine = update_engine(engine.inf_engine, newCPDs);
+[engine.trans_mat, engine.trans_cov, engine.obs_mat, engine.obs_cov, engine.init_state, engine.init_cov] = ...
+    dbn_to_lds(bnet_from_engine(engine));
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/CVS/Entries
new file mode 100644
index 00000000..84a6daa1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/CVS/Entries
@@ -0,0 +1,6 @@
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_soft_ev.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/pearl_dbn_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D/Old////
+D/private////
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/CVS/Repository
new file mode 100644
index 00000000..b7a44128
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@pearl_dbn_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/CVS/Entries
new file mode 100644
index 00000000..d729c48f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/CVS/Entries
@@ -0,0 +1,8 @@
+/correct_smooth.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/filter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/filter_evidence_obj_oriented.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/smooth_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/smooth_evidence_fast.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/wrong_smooth.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/CVS/Repository
new file mode 100644
index 00000000..db9771c6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/correct_smooth.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/correct_smooth.m
new file mode 100644
index 00000000..275afd41
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/correct_smooth.m
@@ -0,0 +1,244 @@
+function [marginal, msg, loglik] = smooth_evidence(engine, evidence)
+% [marginal, msg, loglik] = smooth_evidence(engine, evidence) (pearl_dbn)
+
+disp('warning: broken');
+
+[ss T] = size(evidence);
+bnet = bnet_from_engine(engine);
+bnet2 = dbn_to_bnet(bnet, T);
+ns = bnet2.node_sizes;
+hnodes = mysetdiff(1:ss, engine.onodes);
+hnodes = hnodes(:)';
+
+onodes2 = unroll_set(engine.onodes(:), ss, T);
+onodes2 = onodes2(:)';
+
+hnodes2 = unroll_set(hnodes(:), ss, T);
+hnodes2 = hnodes2(:)';
+
+[engine.parent_index, engine.child_index] = mk_pearl_msg_indices(bnet2);
+
+msg = init_msgs(bnet2.dag, ns, evidence, bnet2.equiv_class, bnet2.CPD);
+
+verbose = 0;
+
+niter = 1;
+for iter=1:niter
+  % FORWARD
+  for t=1:T
+    if verbose, fprintf('t=%d\n', t); end
+    % observed leaves send lambda to parents
+    for i=engine.onodes(:)'
+      n = i + (t-1)*ss;
+      ps = parents(bnet2.dag, n);
+      for p=ps(:)'
+	j = engine.child_index{p}(n); % n is p's j'th child
+	if t > 1
+	  e = bnet.equiv_class(i, 2);
+	else
+	  e = bnet.equiv_class(i, 1);
+	end
+	lam_msg = normalise(compute_lambda_msg(bnet.CPD{e}, n, ps, msg, p));
+	msg{p}.lambda_from_child{j} = lam_msg;
+	if verbose, fprintf('%d sends lambda to %d\n', n, p); disp(lam_msg); end
+      end 
+    end
+
+    % update pi
+    for i=hnodes
+      n = i + (t-1)*ss;
+      ps = parents(bnet2.dag, n);
+      if t==1
+	e = bnet.equiv_class(i,1);
+      else
+	e = bnet.equiv_class(i,2);
+      end
+      msg{n}.pi = compute_pi(bnet.CPD{e}, n, ps, msg);
+      if verbose, fprintf('%d computes pi\n', n); disp(msg{n}.pi); end
+    end
+    
+    % send pi msg to children
+    for i=hnodes
+      n = i + (t-1)*ss;
+      %cs = myintersect(children(bnet2.dag, n), hnodes2);
+      cs = children(bnet2.dag, n);
+      for c=cs(:)'
+	j = engine.parent_index{c}(n); % n is c's j'th parent
+	pi_msg = normalise(compute_pi_msg(n, cs, msg, c, ns));
+	msg{c}.pi_from_parent{j} = pi_msg;
+	if verbose, fprintf('%d sends pi to %d\n', n, c); disp(pi_msg); end
+      end
+    end
+  end
+
+  % BACKWARD
+  for t=T:-1:1
+    if verbose, fprintf('t = %d\n', t); end
+    % update lambda
+    for i=hnodes
+      n = i + (t-1)*ss;
+      cs = children(bnet2.dag, n);
+      msg{n}.lambda = compute_lambda(n, cs, msg, ns);
+      if verbose, fprintf('%d computes lambda\n', n); disp(msg{n}.lambda); end
+    end
+    % send lambda msgs to parents
+    for i=hnodes
+      n = i + (t-1)*ss;
+      %ps = myintersect(parents(bnet2.dag, n), hnodes2);
+      ps = parents(bnet2.dag, n);
+      for p=ps(:)'
+	j = engine.child_index{p}(n); % n is p's j'th child
+	if t > 1
+	  e = bnet.equiv_class(i, 2);
+	else
+	  e = bnet.equiv_class(i, 1);
+	end
+	lam_msg = normalise(compute_lambda_msg(bnet.CPD{e}, n, ps, msg, p));
+	msg{p}.lambda_from_child{j} = lam_msg;
+	if verbose, fprintf('%d sends lambda to %d\n', n, p); disp(lam_msg); end
+      end 
+    end
+  end
+  
+end
+
+
+marginal = cell(ss,T);
+lik = zeros(1,ss*T);
+for t=1:T
+  for i=1:ss
+    n = i + (t-1)*ss;
+    [bel, lik(n)] = normalise(msg{n}.pi .* msg{n}.lambda);     
+    marginal{i,t} = bel;
+  end
+end
+
+loglik = sum(log(lik));
+
+
+
+%%%%%%%
+
+function lambda = compute_lambda(n, cs, msg, ns)
+% Pearl p183 eq 4.50
+lambda = prod_lambda_msgs(n, cs, msg, ns);
+
+%%%%%%%
+
+function pi_msg = compute_pi_msg(n, cs, msg, c, ns)
+% Pearl p183 eq 4.53 and 4.51
+pi_msg = msg{n}.pi .* prod_lambda_msgs(n, cs, msg, ns, c);
+
+%%%%%%%%%
+
+function lam = prod_lambda_msgs(n, cs, msg, ns, except)
+
+if nargin < 5, except = -1; end
+
+lam = msg{n}.lambda_from_self(:);
+lam = ones(ns(n), 1);
+for i=1:length(cs)
+  c = cs(i);
+  if c ~= except
+    lam = lam .* msg{n}.lambda_from_child{i};
+  end
+end   
+
+
+%%%%%%%%%
+
+function msg = init_msgs(dag, ns, evidence, eclass, CPD)
+% INIT_MSGS Initialize the lambda/pi message and state vectors (pearl_dbn)
+% msg =  init_msgs(dag, ns, evidence)
+
+N = length(dag);
+msg = cell(1,N);
+observed = ~isemptycell(evidence(:));
+
+for n=1:N
+  ps = parents(dag, n);
+  msg{n}.pi_from_parent = cell(1, length(ps));
+  for i=1:length(ps)
+    p = ps(i);
+    msg{n}.pi_from_parent{i} = ones(ns(p), 1);
+  end
+  
+  cs = children(dag, n);
+  msg{n}.lambda_from_child = cell(1, length(cs));
+  for i=1:length(cs)
+    c = cs(i);
+    msg{n}.lambda_from_child{i} = ones(ns(n), 1);
+  end
+
+  msg{n}.lambda = ones(ns(n), 1);
+  msg{n}.lambda_from_self = ones(ns(n), 1);
+  msg{n}.pi = ones(ns(n), 1);
+
+ % Initialize the lambdas with any evidence
+  if observed(n)
+    v = evidence{n};
+    %msg{n}.lambda_from_self = zeros(ns(n), 1);
+    %msg{n}.lambda_from_self(v) = 1; % delta function
+    msg{n}.lambda = zeros(ns(n), 1);
+    msg{n}.lambda(v) = 1; % delta function
+  end      
+  
+end
+
+
+%%%%%%%%
+
+function msg = init_ev_msgs(engine, evidence, msg)
+
+[ss T] = size(evidence);
+bnet = bnet_from_engine(engine);
+pot_type = 'd';
+t = 1;
+hnodes = mysetdiff(1:ss, engine.onodes);
+for i=engine.onodes(:)'
+  fam = family(bnet.dag, i);
+  e = bnet.equiv_class(i, 1);
+  CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,1));
+  temp = pot_to_marginal(CPDpot);
+  msg{i}.lambda_from_self = temp.T;
+end
+for t=2:T
+  for i=engine.onodes(:)'
+    fam = family(bnet.dag, i, 2); % extract from slice t
+    e = bnet.equiv_class(i, 2);
+    CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,t-1:t));
+    temp = pot_to_marginal(CPDpot);
+    n = i + (t-1)*ss;
+    msg{n}.lambda_from_self = temp.T;
+  end
+end
+
+
+%%%%%%%%%%%
+
+function msg = init_ev_msgs2(engine, evidence, msg)
+
+[ss T] = size(evidence);
+bnet = bnet_from_engine(engine);
+pot_type = 'd';
+t = 1;
+hnodes = mysetdiff(1:ss, engine.onodes);
+for i=engine.onodes(:)'
+  fam = family(bnet.dag, i);
+  e = bnet.equiv_class(i, 1);
+  CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,1));
+  temp = pot_to_marginal(CPDpot);
+  msg{i}.lambda_from_self = temp.T;
+end
+for t=2:T
+  for i=engine.onodes(:)'
+    fam = family(bnet.dag, i, 2); % extract from slice t
+    e = bnet.equiv_class(i, 2);
+    CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,t-1:t));
+    temp = pot_to_marginal(CPDpot);
+    n = i + (t-1)*ss;
+    msg{n}.lambda_from_self = temp.T;
+  end
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/enter_evidence.m
new file mode 100644
index 00000000..18e7519b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/enter_evidence.m
@@ -0,0 +1,123 @@
+function [engine, loglik] = enter_evidence(engine, evidence, filter)
+% ENTER_EVIDENCE Add the specified evidence to the network (pearl_dbn)
+% [engine, loglik] = enter_evidence(engine, evidence, filter)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+% If filter = 1, we do filtering, otherwise smoothing (default).
+
+if nargin < 3, filter = 0; end
+
+[ss T] = size(evidence);
+bnet = bnet_from_engine(engine);
+bnet2 = dbn_to_bnet(bnet, T);
+ns = bnet2.node_sizes;
+hnodes = mysetdiff(1:ss, engine.onodes);
+hnodes = hnodes(:)';
+
+[engine.parent_index, engine.child_index] = mk_pearl_msg_indices(bnet2);
+
+msg = init_msgs(bnet2.dag, ns, evidence);
+msg = init_ev_msgs(engine, evidence, msg);
+
+niter = 1;
+for iter=1:niter
+  % FORWARD
+  for t=1:T
+    % update pi
+    for i=1:ss %hnodes
+      n = i + (t-1)*ss;
+      ps = parents(bnet2.dag, n);
+      if t==1
+	e = bnet.equiv_class(i,1);
+      else
+	e = bnet.equiv_class(i,2);
+      end
+      msg{n}.pi = compute_pi(bnet.CPD{e}, n, ps, msg);
+      %msg{n}.pi = normalise(msg{n}.pi(:) .* msg{n}.lambda_from_self(:));
+    end
+    % send pi msg to children
+    for i=1:ss % hnodes
+      n = i + (t-1)*ss;
+      cs = children(bnet2.dag, n);
+      for c=cs(:)'
+	j = engine.parent_index{c}(n); % n is c's j'th parent
+	msg{c}.pi_from_parent{j} = normalise(compute_pi_msg(n, cs, msg, c, ns));
+      end
+    end
+  end
+
+  if filter
+    disp('skipping smoothing');
+    break;
+  end
+    
+  % BACKWARD
+  for t=T:-1:1
+    % update lambda
+    for i=1:ss % hnodes
+      n = i + (t-1)*ss;
+      cs = children(bnet2.dag, n);
+      msg{n}.lambda = compute_lambda(n, cs, msg, ns);
+    end
+    % send lambda msgs to parents
+    for i=1:ss % hnodes
+      n = i + (t-1)*ss;
+      ps = parents(bnet2.dag, n);
+      for p=ps(:)'
+	j = engine.child_index{p}(n); % n is p's j'th child
+	if t > 1
+	  e = bnet.equiv_class(i, 2);
+	else
+	  e = bnet.equiv_class(i, 1);
+	end
+	msg{p}.lambda_from_child{j} = normalise(compute_lambda_msg(bnet.CPD{e}, n, ps, msg, p));
+      end 
+    end
+  end
+  
+end
+
+
+engine.marginal = cell(ss,T);
+lik = zeros(1,ss*T);
+for t=1:T
+  for i=1:ss
+    n = i + (t-1)*ss;
+    [bel, lik(n)] = normalise(msg{n}.pi .* msg{n}.lambda);     
+    engine.marginal{i,t} = bel;
+  end
+end
+
+engine.evidence = evidence; % needed by marginal_nodes and marginal_family
+engine.msg = msg;  % needed by marginal_family
+loglik = sum(log(lik));
+
+
+
+%%%%%%%
+
+function lambda = compute_lambda(n, cs, msg, ns)
+% Pearl p183 eq 4.50
+lambda = prod_lambda_msgs(n, cs, msg, ns);
+
+%%%%%%%
+
+function pi_msg = compute_pi_msg(n, cs, msg, c, ns)
+% Pearl p183 eq 4.53 and 4.51
+pi_msg = msg{n}.pi .* prod_lambda_msgs(n, cs, msg, ns, c);
+
+%%%%%%%%%
+
+function lam = prod_lambda_msgs(n, cs, msg, ns, except)
+
+if nargin < 5, except = -1; end
+
+lam = msg{n}.lambda_from_self(:);
+%lam = ones(ns(n), 1);
+for i=1:length(cs)
+  c = cs(i);
+  if c ~= except
+    lam = lam .* msg{n}.lambda_from_child{i};
+  end
+end   
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/filter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/filter_evidence.m
new file mode 100644
index 00000000..a3462437
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/filter_evidence.m
@@ -0,0 +1,146 @@
+function [marginal, msg, loglik] = filter_evidence(engine, evidence)
+
+error('broken');
+
+[ss T] = size(evidence);
+bnet = bnet_from_engine(engine);
+onodes = engine.onodes;
+hnodes = mysetdiff(1:ss, onodes);
+hnodes = hnodes(:)';
+
+ns = bnet.node_sizes(:);
+onodes2 = [onodes(:); onodes(:)+ss];
+ns(onodes2) = 1;
+	   
+verbose = 1;
+if verbose, fprintf('\nnew filtering\n'); end
+  
+pot_type = 'd';
+niter = engine.max_iter;
+
+% msg(i1,t1,i2,j2) (i1,t1) -> (i2,t2)
+%lambda_msg = cell(ss,T,ss,T);
+%pi_msg = cell(ss,T,ss,T);
+
+% intra_lambda_msg(i,j,t) (i,t) -> (j,t), i is child
+% inter_lambda_msg(i,j,t) (i,t+1) -> (j,t), i is child
+% inter_pi_msg(i,j,t) (i,t-1) -> (j,t), i is parent
+intra_lambda_msg = cell(ss,ss,T);
+inter_lambda_msg = cell(ss,ss,T);
+inter_pi_msg = cell(ss,ss,T);
+
+lambda = cell(ss,T);
+pi = cell(ss,T);
+
+for t=1:T
+  for i=1:ss
+    lambda{i,t} = ones(ns(i), 1);
+    pi{i,t} = ones(ns(i), 1);
+    
+    cs = children(bnet.intra, i);
+    for c=cs(:)'
+      intra_lambda_msg{c,i,t} = ones(ns(i),1);
+    end
+    
+    cs = children(bnet.inter, i);
+    for c=cs(:)'
+      inter_lambda_msg{c,i,t} = ones(ns(i),1);
+    end
+    
+    ps = parents(bnet.inter, i);
+    for p=ps(:)'
+      inter_pi_msg{p,i,t} = ones(ns(i), 1); % not used for t==1
+    end
+  end
+end
+
+% each hidden node absorbs lambda from its observed child (if any)
+for t=1:T
+  for i=hnodes
+    c = engine.obschild(i);
+    if c > 0
+      if t==1
+	fam = family(bnet.dag, c);
+	e = bnet.equiv_class(c, 1);
+	CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,1));
+      else
+	fam = family(bnet.dag, c, 2); % within 2 slice network
+	e = bnet.equiv_class(c, 2);
+	CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,t-1:t));
+      end
+      temp = pot_to_marginal(CPDpot);
+      lam_msg = normalise(temp.T);
+      %if verbose, fprintf('(%d,%d) sends lambda to (%d,%d)\n', c,t, i,t); disp(lam_msg); end
+      intra_lambda_msg{c,i,t} = lam_msg;
+    end
+  end
+end
+
+% FORWARD
+for t=1:T
+  % update pi
+  for i=hnodes
+    if t==1
+      e = bnet.equiv_class(i,1);
+      temp = struct(bnet.CPD{e});
+      pi{i,t} = temp.CPT;
+    else
+      e = bnet.equiv_class(i,2);
+      temp = struct(bnet.CPD{e});
+      ps = parents(bnet.inter, i);
+      dom = [ps i+ss];
+      pot = dpot(dom, ns(dom), temp.CPT);
+      for p=ps(:)'
+	temp = dpot(p, ns(p), inter_pi_msg{p,i,t});
+	pot = multiply_by_pot(pot, temp);
+      end
+      pot = marginalize_pot(pot, i+ss);
+      temp = pot_to_marginal(pot);
+      pi{i,t} = temp.T;
+      %if verbose, fprintf('(%d,%d) computes pi\n', i,t); disp(pi{i,t}); end
+    end
+    
+    c = engine.obschild(i);
+    if c > 0
+      pi{i,t} = normalise(pi{i,t} .* intra_lambda_msg{c,i,t});
+    end
+    %if verbose, fprintf('(%d,%d) recomputes pi\n', i,t); disp(pi{i,t}); end
+    if verbose, fprintf('%d recomputes pi\n', i+(t-1)*ss); disp(pi{i,t}); end
+  end
+  
+  % send pi msg to children 
+  for i=hnodes
+    cs = children(bnet.inter, i);
+    for c=cs(:)'
+      pot = pi{i,t};
+      for k=cs(:)'
+	if k ~= c
+	  pot = pot .* inter_lambda_msg{k,i,t};
+	end
+      end
+      cs2 = children(bnet.intra, i);
+      for k=cs2(:)'
+	pot = pot .* intra_lambda_msg{k,i,t};
+      end
+      pot = normalise(pot);
+      %if verbose, fprintf('(%d,%d) sends pi to (%d,%d)\n', i,t, c,t+1); disp(pot); end
+      if verbose, fprintf('%d sends pi to %d\n', i+(t-1)*ss, c+t*ss); disp(pot); end
+      inter_pi_msg{i,c,t+1} = pot;
+    end
+  end
+end
+
+
+marginal = cell(ss,T);
+for t=1:T
+  for i=hnodes
+    %marginal{i,t} = normalise(pi{i,t} .* lambda{i,t});     
+    marginal{i,t} = normalise(pi{i,t});
+  end
+end
+
+loglik = 0;
+
+msg.inter_pi_msg = inter_pi_msg;
+msg.inter_lambda_msg = inter_lambda_msg;
+msg.intra_lambda_msg = intra_lambda_msg;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/filter_evidence_obj_oriented.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/filter_evidence_obj_oriented.m
new file mode 100644
index 00000000..fec80b11
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/filter_evidence_obj_oriented.m
@@ -0,0 +1,158 @@
+function [marginal, msg, loglik] = filter_evidence_old(engine, evidence)
+% [marginal, msg, loglik] = filter_evidence(engine, evidence) (pearl_dbn)
+
+[ss T] = size(evidence);
+bnet = bnet_from_engine(engine);
+bnet2 = dbn_to_bnet(bnet, T);
+ns = bnet2.node_sizes;
+hnodes = mysetdiff(1:ss, engine.onodes);
+hnodes = hnodes(:)';
+
+[engine.parent_index, engine.child_index] = mk_pearl_msg_indices(bnet2);
+
+msg = init_msgs(bnet2.dag, ns, evidence);
+msg = init_ev_msgs(engine, evidence, msg);
+
+verbose = 1;
+if verbose, fprintf('\nold filtering\n'); end
+
+for t=1:T
+  % update pi
+  for i=hnodes
+    n = i + (t-1)*ss;
+    ps = parents(bnet2.dag, n);
+    if t==1
+      e = bnet.equiv_class(i,1);
+    else
+      e = bnet.equiv_class(i,2);
+    end
+    msg{n}.pi = compute_pi(bnet.CPD{e}, n, ps, msg);
+    %if verbose, fprintf('%d computes pi\n', n); disp(msg{n}.pi); end
+    msg{n}.pi = normalise(msg{n}.pi(:) .* msg{n}.lambda_from_self(:));
+    if verbose, fprintf('%d recomputes pi\n', n); disp(msg{n}.pi); end
+  end
+  % send pi msg to children
+  for i=hnodes
+    n = i + (t-1)*ss;
+    cs = children(bnet2.dag, n);
+    for c=cs(:)'
+      j = engine.parent_index{c}(n); % n is c's j'th parent
+      pi_msg = normalise(compute_pi_msg(n, cs, msg, c, ns));
+      msg{c}.pi_from_parent{j} = pi_msg;
+      if verbose, fprintf('%d sends pi to %d\n', n,c); disp(pi_msg); end
+    end
+  end
+end
+
+
+marginal = cell(ss,T);
+lik = zeros(1,ss*T);
+for t=1:T
+  for i=1:ss
+    n = i + (t-1)*ss;
+    %[bel, lik(n)] = normalise(msg{n}.pi .* msg{n}.lambda);     
+    [bel, lik(n)] = normalise(msg{n}.pi);
+    marginal{i,t} = bel;
+  end
+end
+
+loglik = sum(log(lik));
+
+
+
+%%%%%%%
+
+function lambda = compute_lambda(n, cs, msg, ns)
+% Pearl p183 eq 4.50
+lambda = prod_lambda_msgs(n, cs, msg, ns);
+
+%%%%%%%
+
+function pi_msg = compute_pi_msg(n, cs, msg, c, ns)
+% Pearl p183 eq 4.53 and 4.51
+pi_msg = msg{n}.pi .* prod_lambda_msgs(n, cs, msg, ns, c);
+
+%%%%%%%%%
+
+function lam = prod_lambda_msgs(n, cs, msg, ns, except)
+
+if nargin < 5, except = -1; end
+
+%lam = msg{n}.lambda_from_self(:);
+lam = ones(ns(n), 1);
+for i=1:length(cs)
+  c = cs(i);
+  if c ~= except
+    lam = lam .* msg{n}.lambda_from_child{i};
+  end
+end   
+
+
+%%%%%%%%%%%
+
+function msg = init_msgs(dag, ns, evidence)
+% INIT_MSGS Initialize the lambda/pi message and state vectors (pearl_dbn)
+% msg =  init_msgs(dag, ns, evidence)
+%
+% We assume all the hidden nodes are discrete.
+
+N = length(dag);
+msg = cell(1,N);
+observed = ~isemptycell(evidence(:));
+
+for n=1:N
+  ps = parents(dag, n);
+  msg{n}.pi_from_parent = cell(1, length(ps));
+  for i=1:length(ps)
+    p = ps(i);
+    msg{n}.pi_from_parent{i} = ones(ns(p), 1);
+  end
+  
+  cs = children(dag, n);
+  msg{n}.lambda_from_child = cell(1, length(cs));
+  for i=1:length(cs)
+    c = cs(i);
+    msg{n}.lambda_from_child{i} = ones(ns(n), 1);
+  end
+
+  msg{n}.lambda = ones(ns(n), 1);
+  msg{n}.pi = ones(ns(n), 1);
+  
+  msg{n}.lambda_from_self = ones(ns(n), 1);
+end
+
+
+%%%%%%%%%
+
+function msg = init_ev_msgs(engine, evidence, msg)
+% Initialize the lambdas with any evidence
+
+[ss T] = size(evidence);
+bnet = bnet_from_engine(engine);
+pot_type = 'd';
+t = 1;
+hnodes = mysetdiff(1:ss, engine.onodes);
+for i=hnodes(:)'
+  c = engine.obschild(i);
+  if c > 0
+    fam = family(bnet.dag, c);
+    e = bnet.equiv_class(c, 1);
+    CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,1));
+    temp = pot_to_marginal(CPDpot);
+    n = i;
+    msg{n}.lambda_from_self = temp.T;
+  end
+end
+for t=2:T
+  for i=hnodes(:)'
+    c = engine.obschild(i);
+    if c > 0 
+      fam = family(bnet.dag, c, 2);
+      e = bnet.equiv_class(c, 2);
+      CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,t-1:t));
+      temp = pot_to_marginal(CPDpot);
+      n = i + (t-1)*ss;
+      msg{n}.lambda_from_self = temp.T;
+    end
+  end
+end       
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/smooth_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/smooth_evidence.m
new file mode 100644
index 00000000..554b579f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/smooth_evidence.m
@@ -0,0 +1,181 @@
+function [marginal, msg, loglik] = smooth_evidence(engine, evidence)
+
+[ss T] = size(evidence);
+bnet = bnet_from_engine(engine);
+onodes = engine.onodes;
+hnodes = mysetdiff(1:ss, onodes);
+hnodes = hnodes(:)';
+
+ns = bnet.node_sizes(:);
+onodes2 = [onodes(:); onodes(:)+ss];
+ns(onodes2) = 1;
+	   
+verbose = 0;
+pot_type = 'd';
+niter = engine.max_iter;
+
+if verbose, fprintf('new smooth\n'); end
+
+% msg(i1,t1,i2,j2) (i1,t1) -> (i2,t2)
+%lambda_msg = cell(ss,T,ss,T);
+%pi_msg = cell(ss,T,ss,T);
+
+% intra_lambda_msg(i,j,t) (i,t) -> (j,t), i is child
+% inter_lambda_msg(i,j,t) (i,t+1) -> (j,t), i is child
+% inter_pi_msg(i,j,t) (i,t-1) -> (j,t), i is parent
+intra_lambda_msg = cell(ss,ss,T);
+inter_lambda_msg = cell(ss,ss,T);
+inter_pi_msg = cell(ss,ss,T);
+
+lambda = cell(ss,T);
+pi = cell(ss,T);
+
+for t=1:T
+  for i=1:ss
+    lambda{i,t} = ones(ns(i), 1);
+    pi{i,t} = ones(ns(i), 1);
+    
+    cs = children(bnet.intra, i);
+    for c=cs(:)'
+      intra_lambda_msg{c,i,t} = ones(ns(i),1);
+    end
+    
+    cs = children(bnet.inter, i);
+    for c=cs(:)'
+      inter_lambda_msg{c,i,t} = ones(ns(i),1);
+    end
+    
+    ps = parents(bnet.inter, i);
+    for p=ps(:)'
+      inter_pi_msg{p,i,t} = ones(ns(i), 1); % not used for t==1
+    end
+  end
+end
+
+
+% each hidden node absorbs lambda from its observed child (if any)
+for t=1:T
+  for i=hnodes
+    c = engine.obschild(i);
+    if c > 0
+      if t==1
+	fam = family(bnet.dag, c);
+	e = bnet.equiv_class(c, 1);
+	CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,1));
+      else
+	fam = family(bnet.dag, c, 2); % within 2 slice network
+	e = bnet.equiv_class(c, 2);
+	CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,t-1:t));
+      end
+      temp = pot_to_marginal(CPDpot);
+      lam_msg = normalise(temp.T);
+      intra_lambda_msg{c,i,t} = lam_msg;
+    end
+  end
+end
+
+for iter=1:engine.max_iter
+  % FORWARD
+  for t=1:T
+    % update pi
+    for i=hnodes
+      if t==1
+	e = bnet.equiv_class(i,1);
+	CPD = struct(bnet.CPD{e});
+	pi{i,t} = CPD.CPT;
+      else
+	e = bnet.equiv_class(i,2);
+	CPD = struct(bnet.CPD{e});
+	ps = parents(bnet.inter, i);
+	dom = [ps i+ss];
+	pot = dpot(dom, ns(dom), CPD.CPT);
+	for p=ps(:)'
+	  temp = dpot(p, ns(p), inter_pi_msg{p,i,t});
+	  pot = multiply_by_pot(pot, temp);
+	end
+	pot = marginalize_pot(pot, i+ss);
+	temp = pot_to_marginal(pot);
+	pi{i,t} = temp.T;
+      end
+      if verbose, fprintf('%d updates pi\n', i+(t-1)*ss); disp(pi{i,t}); end
+    end
+    
+    % send pi msg to children 
+    for i=hnodes
+      cs = children(bnet.inter, i);
+      for c=cs(:)'
+	pot = pi{i,t};
+	for k=cs(:)'
+	  if k ~= c
+	    pot = pot .* inter_lambda_msg{k,i,t};
+	  end
+	end
+	cs2 = children(bnet.intra, i);
+	for k=cs2(:)'
+	  pot = pot .* intra_lambda_msg{k,i,t};
+	end
+	inter_pi_msg{i,c,t+1} = normalise(pot);
+	if verbose, fprintf('%d sends pi to %d\n', i+(t-1)*ss, c+t*ss); disp(inter_pi_msg{i,c,t+1}); end
+      end
+    end
+  end
+
+  if verbose, fprintf('backwards\n'); end
+  % BACKWARD
+  for t=T:-1:1
+    % update lambda
+    for i=hnodes
+      pot = ones(ns(i), 1);
+      cs = children(bnet.inter, i);
+      for c=cs(:)'
+	pot = pot .* inter_lambda_msg{c,i,t};
+      end
+      cs = children(bnet.intra, i);
+      for c=cs(:)'
+	pot = pot .* intra_lambda_msg{c,i,t};
+      end
+      lambda{i,t} = normalise(pot);
+      if verbose, fprintf('%d computes lambda\n', i+(t-1)*ss); disp(lambda{i,t}); end
+    end
+    
+    % send lambda msgs to hidden parents in prev slcie
+    for i=hnodes
+      ps = parents(bnet.inter, i);
+      if t > 1
+	e = bnet.equiv_class(i, 2);
+	CPD = struct(bnet.CPD{e});
+	fam = [ps i+ss];
+	for p=ps(:)'
+	  pot = dpot(fam, ns(fam), CPD.CPT);
+	  temp = dpot(i+ss, ns(i), lambda{i,t});
+	  pot = multiply_by_pot(pot, temp);
+	  for k=ps(:)'
+	    if k ~= p
+	      temp = dpot(k, ns(k), inter_pi_msg{k,i,t});
+	      pot = multiply_by_pot(pot, temp);
+	    end
+	  end
+	  pot = marginalize_pot(pot, p);
+	  temp = pot_to_marginal(pot);
+	  inter_lambda_msg{i,p,t-1} = normalise(temp.T);
+	  if verbose, fprintf('%d sends lambda to %d\n', i+(t-1)*ss, p+(t-2)*ss); disp(inter_lambda_msg{i,p,t-1}); end
+	end
+      end
+    end
+  end
+end
+
+
+
+marginal = cell(ss,T);
+for t=1:T
+  for i=hnodes
+    marginal{i,t} = normalise(pi{i,t} .* lambda{i,t});     
+  end
+end
+
+loglik = 0;
+
+msg.inter_pi_msg = inter_pi_msg;
+msg.inter_lambda_msg = inter_lambda_msg;
+msg.intra_lambda_msg = intra_lambda_msg;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/smooth_evidence_fast.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/smooth_evidence_fast.m
new file mode 100644
index 00000000..8f4ebd2f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/smooth_evidence_fast.m
@@ -0,0 +1,179 @@
+function [marginal, msg, loglik] = smooth_evidence_fast(engine, evidence)
+
+[ss T] = size(evidence);
+bnet = bnet_from_engine(engine);
+onodes = engine.onodes;
+hnodes = mysetdiff(1:ss, onodes);
+hnodes = hnodes(:)';
+
+ns = bnet.node_sizes(:);
+onodes2 = [onodes(:); onodes(:)+ss];
+ns(onodes2) = 1;
+	   
+verbose = 0;
+pot_type = 'd';
+niter = engine.max_iter;
+
+if verbose, fprintf('new smooth\n'); end
+
+% msg(i1,t1,i2,j2) (i1,t1) -> (i2,t2)
+%lambda_msg = cell(ss,T,ss,T);
+%pi_msg = cell(ss,T,ss,T);
+
+% intra_lambda_msg(i,j,t) (i,t) -> (j,t), i is child
+% inter_lambda_msg(i,j,t) (i,t+1) -> (j,t), i is child
+% inter_pi_msg(i,j,t) (i,t-1) -> (j,t), i is parent
+intra_lambda_msg = cell(ss,ss,T);
+inter_lambda_msg = cell(ss,ss,T);
+inter_pi_msg = cell(ss,ss,T);
+
+lambda = cell(ss,T);
+pi = cell(ss,T);
+
+for t=1:T
+  for i=1:ss
+    lambda{i,t} = ones(ns(i), 1);
+    pi{i,t} = ones(ns(i), 1);
+    
+    cs = children(bnet.intra, i);
+    for c=cs(:)'
+      intra_lambda_msg{c,i,t} = ones(ns(i),1);
+    end
+    
+    cs = children(bnet.inter, i);
+    for c=cs(:)'
+      inter_lambda_msg{c,i,t} = ones(ns(i),1);
+    end
+    
+    ps = parents(bnet.inter, i);
+    for p=ps(:)'
+      inter_pi_msg{p,i,t} = ones(ns(i), 1); % not used for t==1
+    end
+  end
+end
+
+
+% each hidden node absorbs lambda from its observed child (if any)
+for t=1:T
+  for i=hnodes
+    c = engine.obschild(i);
+    if c > 0
+      if t==1
+	fam = family(bnet.dag, c);
+	e = bnet.equiv_class(c, 1);
+	CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,1));
+      else
+	fam = family(bnet.dag, c, 2); % within 2 slice network
+	e = bnet.equiv_class(c, 2);
+	CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,t-1:t));
+      end
+      temp = pot_to_marginal(CPDpot);
+      lam_msg = normalise(temp.T);
+      intra_lambda_msg{c,i,t} = lam_msg;
+    end
+  end
+end
+
+for iter=1:engine.max_iter
+  % FORWARD
+  for t=1:T
+    % update pi
+    for i=hnodes
+      if t==1
+	e = bnet.equiv_class(i,1);
+	temp = struct(bnet.CPD{e});
+	pi{i,t} = temp.CPT;
+      else
+	e = bnet.equiv_class(i,2);
+	CPD = struct(bnet.CPD{e});
+	ps = parents(bnet.inter, i);
+	temp = CPD.CPT;
+	for p=ps(:)'
+	  temp(:) = temp(:) .* inter_pi_msg{p,i,t}(engine.mult_parent_ndx{i,p});
+	end
+	dom = [ps i+ss];
+	pot = dpot(dom, ns(dom), temp);
+	pot = marginalize_pot(pot, i+ss);
+	temp = pot_to_marginal(pot);
+	pi{i,t} = temp.T;
+      end
+      if verbose, fprintf('%d updates pi\n', i+(t-1)*ss); disp(pi{i,t}); end
+    end
+    
+    % send pi msg to children 
+    for i=hnodes
+      cs = children(bnet.inter, i);
+      for c=cs(:)'
+	pot = pi{i,t};
+	for k=cs(:)'
+	  if k ~= c
+	    pot = pot .* inter_lambda_msg{k,i,t};
+	  end
+	end
+	cs2 = children(bnet.intra, i);
+	for k=cs2(:)'
+	  pot = pot .* intra_lambda_msg{k,i,t};
+	end
+	inter_pi_msg{i,c,t+1} = normalise(pot);
+	if verbose, fprintf('%d sends pi to %d\n', i+(t-1)*ss, c+t*ss); disp(inter_pi_msg{i,c,t+1}); end
+      end
+    end
+  end
+
+  if verbose, fprintf('backwards\n'); end
+  % BACKWARD
+  for t=T:-1:1
+    % update lambda
+    for i=hnodes
+      pot = ones(ns(i), 1);
+      cs = children(bnet.inter, i);
+      for c=cs(:)'
+	pot = pot .* inter_lambda_msg{c,i,t};
+      end
+      cs = children(bnet.intra, i);
+      for c=cs(:)'
+	pot = pot .* intra_lambda_msg{c,i,t};
+      end
+      lambda{i,t} = normalise(pot);
+      if verbose, fprintf('%d computes lambda\n', i+(t-1)*ss); disp(lambda{i,t}); end
+    end
+    
+    % send lambda msgs to hidden parents in prev slcie
+    for i=hnodes
+      ps = parents(bnet.inter, i);
+      if t > 1
+	e = bnet.equiv_class(i, 2);
+	CPD = struct(bnet.CPD{e});
+	for p=ps(:)'
+	  temp = CPD.CPT(:) .* lambda{i,t}(engine.mult_self_ndx{i});
+	  for k=ps(:)'
+	    if k ~= p
+	      temp(:) = temp(:) .* inter_pi_msg{k,i,t}(engine.mult_parent_ndx{i,k});
+	    end
+	  end
+	  fam = [ps i+ss];
+	  pot = dpot(fam, ns(fam), temp);
+	  pot = marginalize_pot(pot, p);
+	  temp = pot_to_marginal(pot);
+	  inter_lambda_msg{i,p,t-1} = normalise(temp.T);
+	  if verbose, fprintf('%d sends lambda to %d\n', i+(t-1)*ss, p+(t-2)*ss); disp(inter_lambda_msg{i,p,t-1}); end
+	end
+      end
+    end
+  end
+end
+
+
+
+marginal = cell(ss,T);
+for t=1:T
+  for i=hnodes
+    marginal{i,t} = normalise(pi{i,t} .* lambda{i,t});     
+  end
+end
+
+loglik = 0;
+
+msg.inter_pi_msg = inter_pi_msg;
+msg.inter_lambda_msg = inter_lambda_msg;
+msg.intra_lambda_msg = intra_lambda_msg;
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/wrong_smooth.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/wrong_smooth.m
new file mode 100644
index 00000000..d66d61ad
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/Old/wrong_smooth.m
@@ -0,0 +1,210 @@
+function [marginal, msg, loglik] = smooth_evidence(engine, evidence)
+% [marginal, msg, loglik] = smooth_evidence(engine, evidence) (pearl_dbn)
+
+disp('warning: pearl_dbn smoothing is broken');
+
+[ss T] = size(evidence);
+bnet = bnet_from_engine(engine);
+bnet2 = dbn_to_bnet(bnet, T);
+ns = bnet2.node_sizes;
+hnodes = mysetdiff(1:ss, engine.onodes);
+hnodes = hnodes(:)';
+
+onodes2 = unroll_set(engine.onodes(:), ss, T);
+onodes2 = onodes2(:)';
+
+hnodes2 = unroll_set(hnodes(:), ss, T);
+hnodes2 = hnodes2(:)';
+
+[engine.parent_index, engine.child_index] = mk_pearl_msg_indices(bnet2);
+
+msg = init_msgs(bnet2.dag, ns, evidence, bnet2.equiv_class, bnet2.CPD);
+
+verbose = 0;
+pot_type = 'd';
+niter = 1;
+for iter=1:niter
+  % FORWARD
+  for t=1:T
+    if verbose, fprintf('t=%d\n', t); end
+
+    % each hidden node absorbs lambda from its observed child (if any)
+    for i=hnodes
+      c = engine.obschild(i);
+      if c > 0
+	if t==1
+	  fam = family(bnet.dag, c);
+	  e = bnet.equiv_class(c, 1);
+	  CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,1));
+	else
+	  fam = family(bnet.dag, 2); % within 2 slice network
+	  e = bnet.equiv_class(c, 2);
+	  CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,t-1:t));
+	end
+	temp = pot_to_marginal(CPDpot);
+	n = i + (t-1)*ss;
+	lam_msg = normalise(temp.T);
+	j = engine.child_index{n}(c+(t-1)*ss);
+	assert(j==1);
+	msg{n}.lambda_from_child{j} = lam_msg;
+	if verbose, fprintf('%d sends lambda to %d\n', c + (t-1)*ss, n); disp(lam_msg); end
+      end
+    end
+    
+    % update pi
+    for i=hnodes
+      n = i + (t-1)*ss;
+      ps = parents(bnet2.dag, n);
+      if t==1
+	e = bnet.equiv_class(i,1);
+      else
+	e = bnet.equiv_class(i,2);
+      end
+      msg{n}.pi = compute_pi(bnet.CPD{e}, n, ps, msg);
+      if verbose, fprintf('%d computes pi\n', n); disp(msg{n}.pi); end
+    end
+    
+    % send pi msg to children in next slice
+    for i=hnodes
+      n = i + (t-1)*ss;
+      %cs = myintersect(children(bnet2.dag, n), hnodes2);
+      cs = children(bnet2.dag, n);
+      for c=cs(:)'
+	j = engine.parent_index{c}(n); % n is c's j'th parent
+	pi_msg = normalise(compute_pi_msg(n, cs, msg, c, ns));
+	msg{c}.pi_from_parent{j} = pi_msg;
+	if verbose, fprintf('%d sends pi to %d\n', n, c); disp(pi_msg); end
+      end
+    end
+  end
+
+  % BACKWARD
+  for t=T:-1:1
+    if verbose, fprintf('t = %d\n', t); end
+
+    % update lambda
+    for i=hnodes
+      n = i + (t-1)*ss;
+      cs = children(bnet2.dag, n);
+      msg{n}.lambda = compute_lambda(n, cs, msg, ns);
+      if verbose, fprintf('%d computes lambda\n', n); disp(msg{n}.lambda); end
+    end
+    
+    % send lambda msgs to hidden parents in prev slcie
+    for i=hnodes
+      n = i + (t-1)*ss;
+      %ps = myintersect(parents(bnet2.dag, n), hnodes2);
+      ps = parents(bnet2.dag, n);
+      for p=ps(:)'
+	j = engine.child_index{p}(n); % n is p's j'th child
+	if t > 1
+	  e = bnet.equiv_class(i, 2);
+	else
+	  e = bnet.equiv_class(i, 1);
+	end
+	lam_msg = normalise(compute_lambda_msg(bnet.CPD{e}, n, ps, msg, p));
+	msg{p}.lambda_from_child{j} = lam_msg;
+	if verbose, fprintf('%d sends lambda to %d\n', n, p); disp(lam_msg); end
+      end 
+    end
+        
+    % send pi msg to observed children 
+    if 0
+    for i=hnodes
+      n = i + (t-1)*ss;
+      cs = myintersect(children(bnet2.dag, n), onodes2);
+      %cs = children(bnet2.dag, n);
+      for c=cs(:)'
+	j = engine.parent_index{c}(n); % n is c's j'th parent
+	pi_msg = normalise(compute_pi_msg(n, cs, msg, c, ns));
+	msg{c}.pi_from_parent{j} = pi_msg;
+	if verbose, fprintf('%d sends pi to %d\n', n, c); disp(pi_msg); end
+      end
+    end
+    end
+    
+  end
+end
+
+
+marginal = cell(ss,T);
+lik = zeros(1,ss*T);
+for t=1:T
+  for i=hnodes
+    n = i + (t-1)*ss;
+    [bel, lik(n)] = normalise(msg{n}.pi .* msg{n}.lambda);     
+    marginal{i,t} = bel;
+  end
+end
+
+loglik = 0;
+%loglik = sum(log(lik));
+
+
+
+%%%%%%%
+
+function lambda = compute_lambda(n, cs, msg, ns)
+% Pearl p183 eq 4.50
+lambda = prod_lambda_msgs(n, cs, msg, ns);
+
+%%%%%%%
+
+function pi_msg = compute_pi_msg(n, cs, msg, c, ns)
+% Pearl p183 eq 4.53 and 4.51
+pi_msg = msg{n}.pi .* prod_lambda_msgs(n, cs, msg, ns, c);
+
+%%%%%%%%%
+
+function lam = prod_lambda_msgs(n, cs, msg, ns, except)
+
+if nargin < 5, except = -1; end
+
+%lam = msg{n}.lambda_from_self(:);
+lam = ones(ns(n), 1);
+for i=1:length(cs)
+  c = cs(i);
+  if c ~= except
+    lam = lam .* msg{n}.lambda_from_child{i};
+  end
+end   
+
+
+%%%%%%%%%
+
+function msg = init_msgs(dag, ns, evidence, eclass, CPD)
+% INIT_MSGS Initialize the lambda/pi message and state vectors (pearl_dbn)
+% msg =  init_msgs(dag, ns, evidence)
+
+N = length(dag);
+msg = cell(1,N);
+observed = ~isemptycell(evidence(:));
+
+for n=1:N
+  ps = parents(dag, n);
+  msg{n}.pi_from_parent = cell(1, length(ps));
+  for i=1:length(ps)
+    p = ps(i);
+    msg{n}.pi_from_parent{i} = ones(ns(p), 1);
+  end
+  
+  cs = children(dag, n);
+  msg{n}.lambda_from_child = cell(1, length(cs));
+  for i=1:length(cs)
+    c = cs(i);
+    msg{n}.lambda_from_child{i} = ones(ns(n), 1);
+  end
+
+  msg{n}.lambda = ones(ns(n), 1);
+  msg{n}.pi = ones(ns(n), 1);
+
+  % Initialize the lambdas with any evidence
+  if observed(n)
+    v = evidence{n};
+    msg{n}.lambda = zeros(ns(n), 1);
+    msg{n}.lambda(v) = 1; % delta function
+    msg{n}.lambda = [];
+  end      
+  
+end
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..624cac96
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/enter_evidence.m
@@ -0,0 +1,35 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (loopy_dbn)
+% [engine, loglik] = enter_evidence(engine, evidence, ....)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product (not yet supported), else sum-product [0]
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+maximize = 0;
+filter = 0;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', maximize = args{i+1}; 
+     case 'filter', filter = args{i+1}; 
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+assert(~maximize);
+assert(~filter);
+
+[engine.marginal, engine.msg, loglik] = enter_soft_ev(engine, evidence);
+engine.evidence = evidence; % needed by marginal_nodes and marginal_family
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/enter_soft_ev.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/enter_soft_ev.m
new file mode 100644
index 00000000..5c88f53f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/enter_soft_ev.m
@@ -0,0 +1,137 @@
+function [marginal, msg, loglik] = enter_soft_ev(engine, evidence)
+% [marginal, msg, loglik] = smooth_evidence(engine, evidence) (pearl_dbn)
+
+
+[ss T] = size(evidence);
+bnet = bnet_from_engine(engine);
+bnet2 = dbn_to_bnet(bnet, T);
+ns = bnet2.node_sizes;
+hnodes = mysetdiff(1:ss, engine.onodes);
+hnodes = hnodes(:)';
+
+onodes2 = unroll_set(engine.onodes(:), ss, T);
+onodes2 = onodes2(:)';
+
+hnodes2 = unroll_set(hnodes(:), ss, T);
+hnodes2 = hnodes2(:)';
+
+[engine.parent_index, engine.child_index] = mk_pearl_msg_indices(bnet2);
+
+rand_init = 0;
+use_ev = 0;
+msg = init_pearl_msgs(bnet2.dag, ns, evidence, rand_init, use_ev);
+msg = init_pearl_dbn_ev_msgs(bnet, evidence, engine);
+
+verbose = 0;
+pot_type = 'd';
+niter = engine.max_iter;
+
+if verbose, fprintf('old smooth\n'); end
+
+for iter=1:niter
+  % FORWARD
+  for t=1:T
+    if verbose, fprintf('t=%d\n', t); end
+    
+    % update pi
+    for i=hnodes
+      n = i + (t-1)*ss;
+      ps = parents(bnet2.dag, n);
+      if t==1
+	e = bnet.equiv_class(i,1);
+      else
+	e = bnet.equiv_class(i,2);
+      end
+      msg{n}.pi = compute_pi(bnet.CPD{e}, n, ps, msg);
+      if verbose, fprintf('%d computes pi\n', n); disp(msg{n}.pi); end
+    end
+    
+    % send pi msg to children 
+    for i=hnodes
+      n = i + (t-1)*ss;
+      %cs = myintersect(children(bnet2.dag, n), hnodes2);
+      cs = children(bnet2.dag, n); % must use all children to get index right
+      for c=cs(:)'
+	j = engine.parent_index{c}(n); % n is c's j'th parent
+	pi_msg = normalise(compute_pi_msg(n, cs, msg, c, ns));
+	msg{c}.pi_from_parent{j} = pi_msg;
+	if verbose, fprintf('%d sends pi to %d\n', n, c); disp(pi_msg); end
+      end
+    end
+  end
+
+  % BACKWARD
+  for t=T:-1:1
+    if verbose, fprintf('t = %d\n', t); end
+
+    % update lambda
+    for i=hnodes
+      n = i + (t-1)*ss;
+      cs = children(bnet2.dag, n);
+      msg{n}.lambda = compute_lambda(n, cs, msg, ns);
+      if verbose, fprintf('%d computes lambda\n', n); disp(msg{n}.lambda); end
+    end
+    
+    % send lambda msgs to hidden parents in prev slcie
+    for i=hnodes
+      n = i + (t-1)*ss;
+      ps = parents(bnet2.dag, n);
+      for p=ps(:)'
+	j = engine.child_index{p}(n); % n is p's j'th child
+	if t > 1
+	  e = bnet.equiv_class(i, 2);
+	else
+	  e = bnet.equiv_class(i, 1);
+	end
+	lam_msg = normalise(compute_lambda_msg(bnet.CPD{e}, n, ps, msg, p));
+	msg{p}.lambda_from_child{j} = lam_msg;
+	if verbose, fprintf('%d sends lambda to %d\n', n, p); disp(lam_msg); end
+      end 
+    end
+    
+  end
+end
+
+
+marginal = cell(ss,T);
+lik = zeros(1,ss*T);
+for t=1:T
+  for i=hnodes
+    n = i + (t-1)*ss;
+    [bel, lik(n)] = normalise(msg{n}.pi .* msg{n}.lambda);     
+    marginal{i,t} = bel;
+  end
+end
+
+loglik = 0;
+%loglik = sum(log(lik));
+
+
+
+%%%%%%%
+
+function lambda = compute_lambda(n, cs, msg, ns)
+% Pearl p183 eq 4.50
+lambda = prod_lambda_msgs(n, cs, msg, ns);
+
+%%%%%%%
+
+function pi_msg = compute_pi_msg(n, cs, msg, c, ns)
+% Pearl p183 eq 4.53 and 4.51
+pi_msg = msg{n}.pi .* prod_lambda_msgs(n, cs, msg, ns, c);
+
+%%%%%%%%%
+
+function lam = prod_lambda_msgs(n, cs, msg, ns, except)
+
+if nargin < 5, except = -1; end
+
+%lam = msg{n}.lambda_from_self(:);
+lam = ones(ns(n), 1);
+for i=1:length(cs)
+  c = cs(i);
+  if c ~= except
+    lam = lam .* msg{n}.lambda_from_child{i};
+  end
+end   
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..9440459a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/marginal_nodes.m
@@ -0,0 +1,18 @@
+function marginal = marginal_nodes(engine, nodes, t)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (pearl_dbn)
+% marginal = marginal_nodes(engine, i, t)
+% returns Pr(X(i,t) | Y(1:T)), where X(i,t) is the i'th node in the t'th slice.
+% If enter_evidence used filtering instead of smoothing, this will return  Pr(X(i,t) | Y(1:t)).
+
+if nargin < 3, t = 1; end
+assert(length(nodes)==1);
+i = nodes(end);
+if ~myismember(i, engine.onodes)
+  marginal.T = engine.marginal{i,t};
+else
+  marginal.T = 1; % observed
+end
+
+% we convert the domain to the unrolled numbering system
+% so that update_ess extracts the right evidence.
+marginal.domain = nodes+(t-1)*engine.ss;       
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/pearl_dbn_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/pearl_dbn_inf_engine.m
new file mode 100644
index 00000000..2e0509fd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/pearl_dbn_inf_engine.m
@@ -0,0 +1,65 @@
+function engine = pearl_dbn_inf_engine(bnet, varargin)
+% LOOPY_DBN_INF_ENGINE Loopy Pearl version of forwards-backwards
+% engine = loopy_dbn_inf_engine(bnet, ...)
+%
+% Optional arguments
+% 'max_iter' - specifies the max num. forward-backward passes to perform [1]
+% 'tol' - as in loopy_pearl [1e-3]
+% 'momentum' - as in loopy_pearl [0]
+
+error('pearl_dbn does not work yet')
+
+max_iter = 1;
+tol = 1e-3;
+momentum = 0;
+
+if nargin >= 2
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'max_iter', max_iter = args{i+1};
+     case 'tol', tol = args{i+1};
+     case 'momentum', momentum = args{i+1};
+    end
+  end
+end
+
+          
+engine.max_iter = max_iter;
+engine.tol = tol;
+engine.momentum = momentum;
+engine.pearl_engine = [];
+engine.T = [];
+engine.ss = length(bnet.intra);
+
+engine.marginal = [];
+engine.evidence = [];
+engine.msg = [];
+engine.parent_index = [];
+engine.child_index = [];
+%[engine.parent_index, engine.child_index] = mk_pearl_msg_indices(bnet); % need to unroll first
+
+ss = length(bnet.intra);
+engines.ss = ss;
+onodes = bnet.observed;
+hnodes = mysetdiff(1:ss, onodes);
+obschild = zeros(1,ss);
+for i=hnodes(:)'
+  %ocs = myintersect(children(bnet.dag, i), onodes);
+  ocs = children(bnet.intra, i);
+  assert(length(ocs) <= 1);
+  if length(ocs)==1
+    obschild(i) = ocs(1);
+  end
+end
+engine.obschild = obschild;
+
+engine.mult_self_ndx = [];
+engine.mult_parent_ndx = [];
+engine.marg_self_ndx = [];
+engine.marg_parent_ndx = [];
+
+
+engine = class(engine, 'loopy_dbn_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/CVS/Entries
new file mode 100644
index 00000000..e35b6662
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/CVS/Entries
@@ -0,0 +1,2 @@
+/init_pearl_dbn_ev_msgs.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/CVS/Repository
new file mode 100644
index 00000000..2cb0fa7a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@pearl_dbn_inf_engine/private
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/init_pearl_dbn_ev_msgs.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/init_pearl_dbn_ev_msgs.m
new file mode 100644
index 00000000..893af2ae
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_dbn_inf_engine/private/init_pearl_dbn_ev_msgs.m
@@ -0,0 +1,28 @@
+function msg = init_pearl_dbn_ev_msgs(bnet, evidence, engine)
+
+[ss T] = size(evidence);
+pot_type = 'd';
+
+% each hidden node absorbs lambda from its observed child (if any)
+for t=1:T
+  for i=hnodes
+    c = engine.obschild(i);
+    if c > 0
+      if t==1
+	fam = family(bnet.dag, c);
+	e = bnet.equiv_class(c, 1);
+	CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,1));
+      else
+	fam = family(bnet.dag, c, 2); % within 2 slice network
+	e = bnet.equiv_class(c, 2);
+	CPDpot = CPD_to_pot(pot_type, bnet.CPD{e}, fam, bnet.node_sizes(:), bnet.cnodes(:), evidence(:,t-1:t));
+      end
+      temp = pot_to_marginal(CPDpot);
+      n = i + (t-1)*ss;
+      lam_msg = normalise(temp.T);
+      j = engine.child_index{n}(c+(t-1)*ss);
+      assert(j==1);
+      msg{n}.lambda_from_child{j} = lam_msg;
+    end
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/CVS/Entries
new file mode 100644
index 00000000..d2a809f0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/CVS/Entries
@@ -0,0 +1,6 @@
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/pearl_unrolled_dbn_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/update_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/CVS/Repository
new file mode 100644
index 00000000..5c0fed50
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..a9731ffd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/enter_evidence.m
@@ -0,0 +1,41 @@
+function [engine, loglik, niter] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (loopy_unrolled_dbn)
+% [engine, loglik, niter] = enter_evidence(engine, evidence, ....)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product (not yet supported), else sum-product [0]
+% filename - as in loopy_pearl
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+maximize = 0;
+filename = engine.filename;
+
+if nargin >= 2
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', maximize = args{i+1};
+     case 'filename', filename = args{i+1};
+    end
+  end
+end
+
+
+[ss T] = size(evidence);
+if T ~= engine.T
+  bnetT = dbn_to_bnet(bnet_from_engine(engine), T);
+  engine.unrolled_engine = pearl_inf_engine(bnetT, 'protocol', engine.protocol, ...
+					    'max_iter', engine.max_iter_per_slice * T, ...
+					    'tol', engine.tol, 'momentum', engine.momentum);
+  engine.T = T;
+end
+[engine.unrolled_engine, loglik, niter] = enter_evidence(engine.unrolled_engine, evidence(:), ...
+						  'maximize', maximize, 'filename', filename);
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/marginal_family.m
new file mode 100644
index 00000000..a40f2974
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/marginal_family.m
@@ -0,0 +1,11 @@
+function marginal = marginal_family(engine, i, t, add_ev)
+% MARGINAL_FAMILY Compute the marginal on the specified family (jtree_unrolled_dbn)
+% marginal = marginal_family(engine, i, t)
+
+if nargin < 3, t = 1; end
+if nargin < 4, add_ev = 0; end
+assert(~add_ev);
+
+%marginal = marginal_family(engine.unrolled_engine, i + (t-1)*engine.ss, add_ev);
+marginal = marginal_family(engine.unrolled_engine, i + (t-1)*engine.ss);
+              
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..0fb095e5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/marginal_nodes.m
@@ -0,0 +1,16 @@
+function marginal = marginal_nodes(engine, nodes, t, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (loopy_unrolled_dbn)
+% marginal = marginal_nodes(engine, nodes, t)
+%
+% 't' specifies the time slice of the earliest node in 'nodes'.
+% 'nodes' must occur in some clique.
+%
+% Example:
+% Consider a DBN with 2 nodes per slice.
+% Then t=2, nodes=[1 3] refers to node 1 in slice 2 and node 1 in slice 3,
+% i.e., nodes 3 and 5 in the unrolled network,
+
+if nargin < 3, t = 1; end
+if nargin < 4, add_ev = 0; end
+
+marginal = marginal_nodes(engine.unrolled_engine, nodes + (t-1)*engine.ss, add_ev);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/pearl_unrolled_dbn_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/pearl_unrolled_dbn_inf_engine.m
new file mode 100644
index 00000000..637d29c8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/pearl_unrolled_dbn_inf_engine.m
@@ -0,0 +1,39 @@
+function engine = pearl_unrolled_dbn_inf_engine(bnet, varargin)
+% LOOPY_DBN_INF_ENGINE Loopy Pearl version of forwards-backwards
+% engine = loopy_unrolld_dbn_inf_engine(bnet, ...)
+%
+% Optional arguments
+% 'max_iter' - specifies the max num. forward-backward passes to perform PER SLICE [2]
+% 'tol' - as in loopy_pearl [1e-3]
+% 'momentum' - as in loopy_pearl [0]
+% protocol - tree or parallel [parallel]
+% filename - as in pearl [ '' ]
+
+max_iter_per_slice = 2;
+tol = 1e-3;
+momentum = 0;
+protocol = 'parallel';
+filename = '';
+
+args = varargin;
+for i=1:2:length(args)
+  switch args{i},
+   case 'max_iter', max_iter_per_slice = args{i+1};
+   case 'tol', tol = args{i+1};
+   case 'momentum', momentum = args{i+1};
+   case 'protocol', protocol = args{i+1};
+   case 'filename', filename = args{i+1};
+  end
+end
+
+engine.filename = filename;
+engine.max_iter_per_slice = max_iter_per_slice;
+engine.tol = tol;
+engine.momentum = momentum;
+engine.unrolled_engine = [];
+engine.T = -1;
+engine.ss = length(bnet.intra);
+engine.protocol = protocol;
+
+engine = class(engine, 'pearl_unrolled_dbn_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/update_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/update_engine.m
new file mode 100644
index 00000000..e8613a43
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@pearl_unrolled_dbn_inf_engine/update_engine.m
@@ -0,0 +1,6 @@
+function engine = update_engine(engine, newCPDs) 
+% UPDATE_ENGINE Update the engine to take into account the new parameters (pearl_unrolled_dbn)
+% engine = update_engine(engine, newCPDs)
+
+engine.inf_engine = update_engine(engine.inf_engine, newCPDs);
+engine.unrolled_engine = update_engine(engine.unrolled_engine, newCPDs);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/CVS/Entries
new file mode 100644
index 00000000..cb266b88
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/CVS/Entries
@@ -0,0 +1,7 @@
+/enter_evidence.m/1.1.1.1/Wed Feb 19 09:52:12 2003//
+/marginal_family.m/1.1.1.1/Wed Feb 19 09:52:12 2003//
+/marginal_nodes.m/1.1.1.1/Wed Feb 19 09:52:12 2003//
+/stable_ho_inf_engine.m/1.1.1.1/Fri Mar 14 09:45:34 2003//
+/test_ho_inf_enginge.m/1.1.1.1/Wed Feb 19 09:52:12 2003//
+/update_engine.m/1.1.1.1/Wed Feb 19 09:52:12 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/CVS/Repository
new file mode 100644
index 00000000..0769f5f6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic/@stable_ho_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..48b230c9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/enter_evidence.m
@@ -0,0 +1,43 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (jtree_unrolled_dbn)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i,t} = [] if if X(i,t) is hidden, and otherwise contains its observed value (scalar or column vector)
+% 
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product instead of sum-product [0]
+% filter   - if 1, does filtering (not supported), else smoothing [0]
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+maximize = 0;
+filter = 0;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', maximize = args{i+1}; 
+     case 'filter',  filter = args{i+1}; 
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+if filter
+  error('jtree_unrolled_dbn does not support filtering')
+end
+
+if size(evidence,2) ~= engine.nslices
+  error(['engine was created assuming there are ' num2str(engine.nslices) ...
+	 ' slices, but evidence has ' num2str(size(evidence,2))])
+end
+
+[engine.unrolled_engine, loglik] = enter_evidence(engine.unrolled_engine, evidence, 'maximize', maximize);
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/marginal_family.m
new file mode 100644
index 00000000..a40f2974
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/marginal_family.m
@@ -0,0 +1,11 @@
+function marginal = marginal_family(engine, i, t, add_ev)
+% MARGINAL_FAMILY Compute the marginal on the specified family (jtree_unrolled_dbn)
+% marginal = marginal_family(engine, i, t)
+
+if nargin < 3, t = 1; end
+if nargin < 4, add_ev = 0; end
+assert(~add_ev);
+
+%marginal = marginal_family(engine.unrolled_engine, i + (t-1)*engine.ss, add_ev);
+marginal = marginal_family(engine.unrolled_engine, i + (t-1)*engine.ss);
+              
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..0fb095e5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/marginal_nodes.m
@@ -0,0 +1,16 @@
+function marginal = marginal_nodes(engine, nodes, t, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (loopy_unrolled_dbn)
+% marginal = marginal_nodes(engine, nodes, t)
+%
+% 't' specifies the time slice of the earliest node in 'nodes'.
+% 'nodes' must occur in some clique.
+%
+% Example:
+% Consider a DBN with 2 nodes per slice.
+% Then t=2, nodes=[1 3] refers to node 1 in slice 2 and node 1 in slice 3,
+% i.e., nodes 3 and 5 in the unrolled network,
+
+if nargin < 3, t = 1; end
+if nargin < 4, add_ev = 0; end
+
+marginal = marginal_nodes(engine.unrolled_engine, nodes + (t-1)*engine.ss, add_ev);
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/stable_ho_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/stable_ho_inf_engine.m
new file mode 100644
index 00000000..523a2fbb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/stable_ho_inf_engine.m
@@ -0,0 +1,67 @@
+function engine = dv_unrolled_dbn_inf_engine(bnet, T, varargin)
+% JTREE_UNROLLED_DBN_INF_ENGINE Unroll the DBN for T time-slices and apply jtree to the resulting static net
+% engine = jtree_unrolled_dbn_inf_engine(bnet, T, ...)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% useC      - 1 means use jtree_C_inf_engine instead of jtree_inf_engine [0]
+% constrained - 1 means we constrain ourselves to eliminate slice t before t+1 [1]
+%
+% e.g., engine = jtree_unrolled_inf_engine(bnet, 'useC', 1);
+
+% set default params
+N = length(bnet.intra);
+useC = 0;
+constrained = 1;
+
+if nargin >= 3
+  args = varargin;
+  nargs = length(args);
+  if isstr(args{1})
+    for i=1:2:nargs
+      switch args{i},
+       case 'useC',   useC = args{i+1};
+       case 'constrained',  constrained = args{i+1};
+       otherwise,  
+	error(['invalid argument name ' args{i}]);       
+      end
+    end
+  else
+    error(['invalid argument name ' args{1}]);       
+  end
+end
+
+bnet2 = hodbn_to_bnet(bnet, T);
+ss = length(bnet.intra);
+engine.ss = ss;
+
+% If constrained_order = 1 we constrain ourselves to eliminate slice t before t+1.
+% This prevents cliques containing nodes from far-apart time-slices.
+if constrained
+  stages = num2cell(unroll_set(1:ss, ss, T), 1);
+else
+  stages = { 1:length(bnet2.dag) };
+end
+if useC
+  %jengine = jtree_C_inf_engine(bnet2, 'stages', stages);
+  %function is not implemented
+  assert(0)
+else
+  jengine = stab_cond_gauss_inf_engine(bnet2);
+end
+
+engine.unrolled_engine = jengine;
+% we don't inherit from jtree_inf_engine, because that would only store bnet2,
+% and we would lose access to the DBN-specific fields like intra/inter
+
+engine.nslices = T;
+engine = class(engine, 'stable_ho_inf_engine', inf_engine(bnet));
+
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/test_ho_inf_enginge.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/test_ho_inf_enginge.m
new file mode 100644
index 00000000..6165f500
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/test_ho_inf_enginge.m
@@ -0,0 +1,87 @@
+function [engine,engine2] = test_ho_inf_enginge(order,T)
+
+assert(order >= 1)
+% Model a SISO system, i. e. all node are one-dimensional
+% The nodes are numbered as follows
+% u(t) = 1 input
+% y(t) = 2 model output
+% z(t) = 3 noise
+% q(t) = 4 observed output = noise + model output
+
+ns = [1 1 1 1];
+
+% Model a linear system, i.e. there are no discrete nodes
+dn = [];
+
+% Modeling of connections within a time slice
+intra = zeros(4);
+intra(2,4) = 1; % Connection y(t) -> q(t)
+intra(3,4) = 1; % Connection z(t) -> q(t)
+
+% Connections to the next time slice
+inter = zeros(4,4,order);
+inter(1,2,1) = 1; % u(t) -> y(t+1);
+inter(2,2,1) = 1; %y(t) -> y(t+1);
+inter(3,3,1) = 1; %z(t) -> z(t+1);
+
+if order >= 2
+    inter(1,2,2) = 1; % u(t) -> y(t+2);
+    inter(2,2,2) = 1; % y(t) -> y(t+2);
+end
+
+for i = 3: order
+    inter(:,:,i) = inter(:,:,i-1); %u(t) -> y(t+i) y(t) -> y(t) +i
+end;
+
+
+% Compution of a higer order Markov Model
+bnet = mk_higher_order_dbn(intra,inter,ns,'discrete',dn);
+bnet2 = mk_dbn(intra,inter(:,:,1),ns,'discrete',dn)
+
+
+%Calculation of the number of nodes with different parameters
+%There is one input and one output nodes  2
+%There are two different disturbance node 2
+%There are order +1 nodes for y           1 + order
+numOfNodes = 5 + order; 
+
+% First input node
+bnet.CPD{1} = gaussian_CPD(bnet,1,'mean',0);
+bnet2.CPD{1} = gaussian_CPD(bnet,1,'mean',0);
+% Modeled output
+bnet.CPD{2} = gaussian_CPD(bnet,2,'mean',0);
+bnet2.CPD{2} = gaussian_CPD(bnet,2,'mean',0);
+%Disturbance
+bnet.CPD{3} = gaussian_CPD(bnet,3,'mean',0);
+bnet2.CPD{3} = gaussian_CPD(bnet,3,'mean',0);
+
+%Qutput
+bnet.CPD{4} = gaussian_CPD(bnet,4,'mean',0);
+bnet2.CPD{4} = gaussian_CPD(bnet,4,'mean',0);
+
+
+%Output node in the second time-slice
+%Remember that node number 6 is an example for 
+%the fifth equivalence class
+bnet.CPD{5} = gaussian_CPD(bnet,6,'mean',0);
+bnet2.CPD{5} = gaussian_CPD(bnet,6,'mean',0);
+
+%Disturbance node in the second time slice
+bnet.CPD{6} = gaussian_CPD(bnet,7,'mean',0);
+bnet2.CPD{6} = gaussian_CPD(bnet,7,'mean',0);
+
+% Modeling of the remaining nodes for y
+for i = 7:numOfNodes
+    bnet.CPD{i} = gaussian_CPD(bnet,(i - 6)*4 + 7,'mean',0);
+end
+
+% Generation of the inference engine
+engine = dv_unrolled_dbn_inf_engine(bnet,T);
+engine2 = jtree_unrolled_dbn_inf_engine(bnet,T);
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/update_engine.m b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/update_engine.m
new file mode 100644
index 00000000..5c42d4f6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/@stable_ho_inf_engine/update_engine.m
@@ -0,0 +1,7 @@
+function engine = update_engine(engine, newCPDs)
+% UPDATE_ENGINE Update the engine to take into account the new parameters (jtree_unrolled_dbn)
+% engine = update_engine(engine, newCPDs)
+
+engine.inf_engine = update_engine(engine.inf_engine, newCPDs);
+engine.unrolled_engine = update_engine(engine.unrolled_engine, newCPDs);
+                                                            
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Entries
new file mode 100644
index 00000000..0593a1e2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Entries
@@ -0,0 +1,2 @@
+/dummy/1.1.1.1/Sat Jan 18 22:22:28 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Entries.Log
new file mode 100644
index 00000000..ab4d0aa0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Entries.Log
@@ -0,0 +1,12 @@
+A D/@bk_ff_hmm_inf_engine////
+A D/@bk_inf_engine////
+A D/@cbk_inf_engine////
+A D/@ff_inf_engine////
+A D/@frontier_inf_engine////
+A D/@hmm_inf_engine////
+A D/@jtree_dbn_inf_engine////
+A D/@jtree_unrolled_dbn_inf_engine////
+A D/@kalman_inf_engine////
+A D/@pearl_dbn_inf_engine////
+A D/@pearl_unrolled_dbn_inf_engine////
+A D/@stable_ho_inf_engine////
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Repository
new file mode 100644
index 00000000..cc4cac18
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/dynamic
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Root b/sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dynamic/dummy b/sourcecodes/bnt-master/BNT/inference/dynamic/dummy
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dynamic/dummy