about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/BNT/inference/dynamic
diff options
context:
space:
mode:
authorziejd22017-09-28 15:04:40 -0500
committerziejd22017-09-28 15:04:40 -0500
commit8070dc963753142bb86c4ed698d91fd623ed28e7 (patch)
treed0f6dd8fc46a49b819aa55c1a90faa14d8448883 /sourcecodes/bnt-master/BNT/inference/dynamic
parent7cc31810d53176e805532b2789955f4eedbce6bb (diff)
downloadBNW-8070dc963753142bb86c4ed698d91fd623ed28e7.tar.gz
BNW using Octave instead of Matlab.
This version of BNW should perform the same as the original version. The only difference is that it uses Octave instead of Matlab when running BayesNet Toolbox during parameter learning.

I am calling this BNW_1.02. It can be accessed at:
compbio.uthsc.edu/BNW_1.02
Diffstat (limited to 'sourcecodes/bnt-master/BNT/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