about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/BNT
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
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')
-rw-r--r--sourcecodes/bnt-master/BNT/@assocarray/CVS/Entries3
-rw-r--r--sourcecodes/bnt-master/BNT/@assocarray/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/@assocarray/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/@assocarray/assocarray.m10
-rw-r--r--sourcecodes/bnt-master/BNT/@assocarray/subsref.m15
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/boolean_CPD.m179
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/deterministic_CPD.m59
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CPD_to_lambda_msg.m16
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CPD_to_pi.m13
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CPD_to_scgpot.m25
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Entries15
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Entries.Log2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/convert_to_pot.m44
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/convert_to_table.m23
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/prob_CPD.m25
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/prob_node.m51
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/README5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_CPD_to_table_hidden_ps.m20
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_obs_CPD_to_table.m13
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_pot.m62
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_sparse_table.c154
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_table.m15
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/discrete_CPD.m6
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/dom_sizes.m5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/log_prob_node.m12
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/prod_CPT_and_pi_msgs.m18
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/prob_node.m81
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/sample_node.m34
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CPD_to_lambda_msg.m59
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CPD_to_pi.m22
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CPD_to_scgpot.m58
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Entries20
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Entries.Log2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CPD_to_lambda_msg.m64
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/gaussian_CPD.m184
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/log_prob_node.m59
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/maximize_params.m147
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/update_ess.m85
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/update_tied_ess.m118
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/adjustable_CPD.m5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/convert_CPD_to_table_hidden_ps.m20
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/convert_to_pot.m71
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/convert_to_table.m38
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/display.m4
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/gaussian_CPD.m161
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/gaussian_CPD_params_given_dps.m28
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/get_field.m19
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/learn_params.m31
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/log_prob_node.m49
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/maximize_params.m68
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/maximize_params_debug.m189
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CPD_to_linear_gaussian.m19
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/reset_ess.m11
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/sample_node.m22
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/set_fields.m43
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/update_ess.m88
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Entries8
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/BIC_score_CPD.m26
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CPD_to_dpots.m16
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CVS/Entries3
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/README2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/adjustable_CPD.m5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/display.m3
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/generic_CPD.m8
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/learn_params.m32
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/log_prior.m5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/set_clamped.m3
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CPD_to_lambda_msg.m62
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CPD_to_pi.m18
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/gmux_CPD.m92
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/convert_to_pot.m37
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/display.m4
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/gmux_CPD.m95
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/sample_node.m10
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CPD_to_CPT.m35
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/hhmm2Q_CPD.m65
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/maximize_params.m10
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/reset_ess.m12
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/update_ess.m26
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/hhmmF_CPD.m76
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/log_prior.m5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/maximize_params.m9
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/reset_ess.m5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/update_CPT.m13
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/update_ess.m61
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/hhmmF_CPD.m73
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/log_prior.m5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/maximize_params.m9
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/reset_ess.m5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/update_CPT.m13
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/update_ess.m40
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/CVS/Entries10
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/hhmmQ_CPD.m126
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/log_prior.m8
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/maximize_params.m40
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/reset_ess.m8
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_CPT.m74
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess.m141
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess2.m178
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess3.m80
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess4.m95
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/hhmmQ_CPD.m132
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/log_prior.m8
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/maximize_params.m40
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/reset_ess.m8
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/update_CPT.m70
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/update_ess.m86
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/convert_to_table.m80
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/maximize_params.m34
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/mlp_CPD.m139
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/reset_ess.m12
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/update_ess.m131
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m34
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m~70
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_lambda_msg.m19
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_pi.m12
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/noisyor_CPD.m79
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/sum_prod_CPD_and_pi_msgs.m25
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CPD_to_pi.m12
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CPD_to_CPT.m5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/convert_to_pot.m28
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/log_marg_prob_node.m9
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/log_prob_node.m9
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/root_CPD.m48
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@root_CPD/sample_node.m9
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Entries11
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/convert_to_pot.m58
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/convert_to_table.m52
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/display.m4
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/get_field.m18
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/maximize_params.m41
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/extract_params.m18
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/reset_ess.m8
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/sample_node.m14
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/set_fields.m45
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/softmax_CPD.m187
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/update_ess.m97
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CPD_to_CPT.m5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Entries15
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/BIC_score_CPD.m17
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/CVS/Entries11
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/bayesian_score_CPD.m13
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/log_marg_prob_node_case.m22
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/mult_CPD_and_pi_msgs.m17
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/prob_CPT.m16
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/prob_node.m40
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/sample_node.m53
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/sample_node_single_case.m39
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/tabular_CPD.m186
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/update_params.m15
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/bayes_update_params.m55
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/display.m5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/get_field.m16
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/learn_params.m17
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/log_marg_prob_node.m69
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/log_nextcase_prob_node.m72
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/log_prior.m18
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/maximize_params.m52
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/reset_ess.m7
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/set_fields.m52
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/tabular_CPD.m173
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/update_ess.m15
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/update_ess_simple.m6
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CPD_to_CPT.m5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/tabular_decision_node.m39
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/display.m4
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/get_field.m19
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/set_fields.m19
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/tabular_decision_node.m45
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/tabular_kernel.m45
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/convert_to_pot.m37
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/convert_to_table.m13
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/get_field.m11
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/set_fields.m13
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/tabular_kernel.m40
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/convert_to_pot.m11
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/display.m4
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/tabular_utility_node.m46
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/CVS/Entries8
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/display.m4
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/evaluate_tree_performance.m82
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/get_field.m16
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/learn_params.m642
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/readme.txt8
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/set_fields.m52
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/tree_CPD.m37
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/CVS/Entries.Log19
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/linear_gaussian_CPD.m87
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/log_marg_prob_node.m23
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/update_params_complete.m25
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/log_marg_prob_node.m26
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/root_gaussian_CPD.m74
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/update_params_complete.m29
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CPD_to_upot.m6
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CVS/Entries3
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/tabular_chance_node.m39
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Entries1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Entries.Log3
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/mk_isolated_tabular_CPD.m14
-rw-r--r--sourcecodes/bnt-master/BNT/CVS/Entries9
-rw-r--r--sourcecodes/bnt-master/BNT/CVS/Entries.Log7
-rw-r--r--sourcecodes/bnt-master/BNT/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/README.txt4
-rw-r--r--sourcecodes/bnt-master/BNT/copyright.txt2
-rw-r--r--sourcecodes/bnt-master/BNT/examples/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/examples/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dummy0
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Entries38
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Entries.Log3
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries9
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries.Log5
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/mk_map_hhmm.m156
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/disp_map_hhmm.m13
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/learn_map.m40
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_map_hhmm.m181
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_rnd_map_hhmm.m73
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/sample_from_map.m41
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/mgram2.m191
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/letter2num.m12
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram1.m116
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram2.m200
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram3.m235
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/num2letter.m10
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/fixed_args_mk_motif_hhmm.m99
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/learn_motif_hhmm.m75
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/mk_motif_hhmm.m137
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/sample_motif_hhmm.m10
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Entries8
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_abcd_hhmm.m109
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_arrow_alpha_hhmm3.m86
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm2.m111
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3.m181
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3_args.m165
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/motif_hhmm.m95
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/remove_hhmm_end_state.m37
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Entries14
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/learn_square_hhmm.m294
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/mk_square_hhmm.m183
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/plot_square_hhmm.m32
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/sample_square_hhmm.m160
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/get_square_data.m70
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/hhmm_inference.m13
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/is_F2_true_D3.m12
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_cts.m152
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_discrete.m171
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/mk_square_hhmm.m180
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/plot_square_hhmm.m27
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_cts.m20
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_discrete.m20
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4.matbin0 -> 34672 bytes
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4_cases.matbin0 -> 156432 bytes
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.m1310
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.matbin0 -> 5304 bytes
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/abcd_hhmm.m97
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/add_hhmm_end_state.m34
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/hhmm_jtree_clqs.m143
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm.m258
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo.m76
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo_F1.m65
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/pretty_print_hhmm_parse.m67
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/remove_hhmm_end_state.m41
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/Old/CVS/Entries8
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/Old/chmm1.m40
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/Old/cmp_inference.m75
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/Old/kalman1.m127
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/Old/old.water1.m48
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/Old/online1.m59
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/Old/online2.m33
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/Old/scg_dbn.m70
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/offline_loopy_slam.m231
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/paskin1.m238
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/skf_data_assoc_gmux2.m155
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/slam_kf.m172
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/mk_gmux_robot_dbn.m85
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/mk_linear_slam.m164
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_kf.m78
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_offline_loopy.m59
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_partial_kf.m107
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_stationary_loopy.m155
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/arhmm1.m42
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/bat1.m44
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/bkff1.m23
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/chmm1.m41
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/cmp_inference_dbn.m100
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/cmp_learning_dbn.m89
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/cmp_online_inference.m97
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/dhmm1.m66
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/ehmm1.m24
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/fhmm_infer.m324
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/filter_test1.m24
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/ghmm1.m64
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/ho1.m156
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/jtree_clq_test.m150
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/jtree_clq_test2.m23
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/kalman1.m66
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/kjaerulff1.m55
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/loopy_dbn1.m24
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/mhmm1.m85
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/mildew1.m30
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/mk_bat_dbn.m63
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/mk_chmm.m103
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/mk_collage_from_clqs.m44
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/mk_fhmm.m58
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/mk_mildew_dbn.m31
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/mk_orig_bat_dbn.m198
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/mk_orig_water_dbn.m121
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/mk_ps_from_clqs.m44
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/mk_uffe_dbn.m14
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/mk_water_dbn.m68
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/orig_water1.m28
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/reveal1.m73
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/scg_dbn.m39
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/skf_data_assoc_gmux.m139
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/viterbi1.m47
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/water1.m20
-rw-r--r--sourcecodes/bnt-master/BNT/examples/dynamic/water2.m22
-rw-r--r--sourcecodes/bnt-master/BNT/examples/limids/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/examples/limids/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/limids/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/limids/amnio.m135
-rw-r--r--sourcecodes/bnt-master/BNT/examples/limids/asia_dt1.m100
-rw-r--r--sourcecodes/bnt-master/BNT/examples/limids/id1.m50
-rw-r--r--sourcecodes/bnt-master/BNT/examples/limids/oil1.m91
-rw-r--r--sourcecodes/bnt-master/BNT/examples/limids/pigs1.m153
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Belprop/CVS/Entries11
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Belprop/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Belprop/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loop1_discrete.m26
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loop1_gauss.m25
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loopy_cg.m22
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loopy_discrete.m13
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loopy_gauss.m12
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_polytree_cg.m33
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_polytree_discrete.m38
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_polytree_gauss.m135
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Belprop/bp1.m24
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Belprop/gmux1.m90
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Brutti/Belief_IOhmm.m49
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Brutti/Belief_hmdt.m48
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Brutti/Belief_hme.m37
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Brutti/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Brutti/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Brutti/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Brutti/Sigmoid_Belief.m49
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/CVS/Entries30
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/CVS/Entries.Log10
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/CVS/Entries14
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/HMEforMatlab.jpgbin0 -> 43717 bytes
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/README2
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/fhme.m109
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/gen_data.m52
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/hme_class_plot.m142
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/hme_reg_plot.m43
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/hme_topobuilder.m47
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/hmemenu.m552
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/test_data_class.matbin0 -> 1400 bytes
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/test_data_class2.matbin0 -> 1000 bytes
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/test_data_reg.matbin0 -> 1000 bytes
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/train_data_class.matbin0 -> 2600 bytes
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/HME/train_data_reg.matbin0 -> 1800 bytes
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Misc/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Misc/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Misc/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Misc/mixexp_data.txt1000
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Misc/mixexp_graddesc.m51
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Misc/mixexp_plot.m49
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Misc/sprinkler.bif18
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/CVS/Entries12
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/Old/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/Old/mk_hmm_bnet.m58
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/mk_alarm_bnet.m118
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/mk_asia_bnet.m76
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/mk_cancer_bnet.m61
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/mk_car_bnet.m39
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/mk_hmm_bnet.m67
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/mk_ideker_bnet.m52
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/mk_incinerator_bnet.m61
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/mk_markov_chain_bnet.m9
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/mk_minimal_qmr_bnet.m82
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/mk_qmr_bnet.m41
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Models/mk_vstruct_bnet.m16
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/SCG/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/SCG/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/SCG/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/SCG/scg1.m77
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/SCG/scg2.m12
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/SCG/scg3.m42
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/SCG/scg_3node.m52
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/SCG/scg_unstable.m91
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/StructLearn/CVS/Entries9
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/StructLearn/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/StructLearn/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/StructLearn/bic1.m79
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/StructLearn/cooper_yoo.m65
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/StructLearn/k2demo1.m45
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/StructLearn/mcmc1.m35
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/StructLearn/model_select1.m121
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/StructLearn/model_select2.m83
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/StructLearn/pc1.m30
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/StructLearn/pc2.m21
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Zoubin/CVS/Entries10
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Zoubin/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Zoubin/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Zoubin/README61
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Zoubin/csum.m11
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Zoubin/ffa.m75
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Zoubin/mfa.m153
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Zoubin/mfa_cl.m54
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Zoubin/mfademo.m81
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Zoubin/rdiv.m25
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Zoubin/rprod.m15
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/Zoubin/rsum.m20
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/brainy.m44
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/burglar-alarm-net.lisp.txt45
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/burglary.m44
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/cg1.m86
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/cg2.m11
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/cmp_inference_static.m114
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/discrete1.m40
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/discrete2.m46
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/discrete3.m43
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/dtree/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/dtree/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/dtree/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/dtree/test_housing.m87
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/dtree/test_restaurants.m98
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/dtree/test_zoo1.m21
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/dtree/tmp.dot31
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/dtree/transform_data_into_bnt_format.m66
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/fa1.m57
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/fgraph/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/fgraph/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/fgraph/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/fgraph/fg1.m98
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/fgraph/fg2.m104
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/fgraph/fg3.m83
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/fgraph/fg_mrf1.m113
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/fgraph/fg_mrf2.m150
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/gaussian1.m34
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/gaussian2.m40
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/gibbs_test1.m107
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/learn1.m86
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/lw1.m51
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/mfa1.m80
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/mixexp1.m72
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/mixexp2.m104
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/mixexp3.m52
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/mog1.m81
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/mpe1.m45
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/mpe2.m53
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/nodeorderExample.m68
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/qmr1.m112
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/qmr2.m77
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/sample1.m34
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/softev1.m60
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/softmax1.m109
-rw-r--r--sourcecodes/bnt-master/BNT/examples/static/sprinkler1.m112
-rw-r--r--sourcecodes/bnt-master/BNT/general/CVS/Entries50
-rw-r--r--sourcecodes/bnt-master/BNT/general/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/general/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/general/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/general/Old/CVS/Entries9
-rw-r--r--sourcecodes/bnt-master/BNT/general/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/general/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/general/Old/bnet_to_gdl_graph.m18
-rw-r--r--sourcecodes/bnt-master/BNT/general/Old/calc_mpe.m58
-rw-r--r--sourcecodes/bnt-master/BNT/general/Old/calc_mpe_bucket.m160
-rw-r--r--sourcecodes/bnt-master/BNT/general/Old/calc_mpe_dbn.m41
-rw-r--r--sourcecodes/bnt-master/BNT/general/Old/calc_mpe_given_inf_engine.m32
-rw-r--r--sourcecodes/bnt-master/BNT/general/Old/calc_mpe_global.m28
-rw-r--r--sourcecodes/bnt-master/BNT/general/Old/compute_interface_nodes.m31
-rw-r--r--sourcecodes/bnt-master/BNT/general/Old/mk_gdl_graph.m86
-rw-r--r--sourcecodes/bnt-master/BNT/general/add_ev_to_dmarginal.m15
-rw-r--r--sourcecodes/bnt-master/BNT/general/add_evidence_to_gmarginal.m78
-rw-r--r--sourcecodes/bnt-master/BNT/general/bnet_to_fgraph.m16
-rw-r--r--sourcecodes/bnt-master/BNT/general/compute_fwd_interface.m11
-rw-r--r--sourcecodes/bnt-master/BNT/general/compute_interface_nodes.m42
-rw-r--r--sourcecodes/bnt-master/BNT/general/compute_joint_pot.m17
-rw-r--r--sourcecodes/bnt-master/BNT/general/compute_minimal_interface.m25
-rw-r--r--sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_pots.m30
-rw-r--r--sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_tables.m201
-rw-r--r--sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_tables1.m162
-rw-r--r--sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_tables_slow.m41
-rw-r--r--sourcecodes/bnt-master/BNT/general/dbn_to_bnet.m13
-rw-r--r--sourcecodes/bnt-master/BNT/general/dbn_to_hmm.m81
-rw-r--r--sourcecodes/bnt-master/BNT/general/determine_elim_constraints.m43
-rw-r--r--sourcecodes/bnt-master/BNT/general/dispcpt.m16
-rw-r--r--sourcecodes/bnt-master/BNT/general/do_intervention.m13
-rw-r--r--sourcecodes/bnt-master/BNT/general/dsep.m15
-rw-r--r--sourcecodes/bnt-master/BNT/general/dsep_test.m15
-rw-r--r--sourcecodes/bnt-master/BNT/general/enumerate_scenarios.m21
-rw-r--r--sourcecodes/bnt-master/BNT/general/fgraph_to_bnet.m30
-rw-r--r--sourcecodes/bnt-master/BNT/general/hodbn_to_bnet.m21
-rw-r--r--sourcecodes/bnt-master/BNT/general/is_mnet.m3
-rw-r--r--sourcecodes/bnt-master/BNT/general/linear_gaussian_to_cpot.m43
-rw-r--r--sourcecodes/bnt-master/BNT/general/log_lik_complete.m30
-rw-r--r--sourcecodes/bnt-master/BNT/general/log_marg_lik_complete.m40
-rw-r--r--sourcecodes/bnt-master/BNT/general/mk_bnet.m93
-rw-r--r--sourcecodes/bnt-master/BNT/general/mk_dbn.m133
-rw-r--r--sourcecodes/bnt-master/BNT/general/mk_fgraph.m60
-rw-r--r--sourcecodes/bnt-master/BNT/general/mk_fgraph_given_ev.m48
-rw-r--r--sourcecodes/bnt-master/BNT/general/mk_higher_order_dbn.m181
-rw-r--r--sourcecodes/bnt-master/BNT/general/mk_limid.m93
-rw-r--r--sourcecodes/bnt-master/BNT/general/mk_mnet.m14
-rw-r--r--sourcecodes/bnt-master/BNT/general/mk_mrf2.m8
-rw-r--r--sourcecodes/bnt-master/BNT/general/mk_mutilated_samples.m38
-rw-r--r--sourcecodes/bnt-master/BNT/general/mk_named_CPT.m52
-rw-r--r--sourcecodes/bnt-master/BNT/general/mk_slice_and_half_dbn.m28
-rw-r--r--sourcecodes/bnt-master/BNT/general/noisyORtoTable.m32
-rw-r--r--sourcecodes/bnt-master/BNT/general/partition_dbn_nodes.m17
-rw-r--r--sourcecodes/bnt-master/BNT/general/partition_matrix_vec_3.m22
-rw-r--r--sourcecodes/bnt-master/BNT/general/sample_bnet.m34
-rw-r--r--sourcecodes/bnt-master/BNT/general/sample_bnet_nocell.m0
-rw-r--r--sourcecodes/bnt-master/BNT/general/sample_dbn.m73
-rw-r--r--sourcecodes/bnt-master/BNT/general/score_bnet_complete.m28
-rw-r--r--sourcecodes/bnt-master/BNT/general/shrink_obs_dims_in_gaussian.m12
-rw-r--r--sourcecodes/bnt-master/BNT/general/shrink_obs_dims_in_table.m15
-rw-r--r--sourcecodes/bnt-master/BNT/general/solve_limid.m68
-rw-r--r--sourcecodes/bnt-master/BNT/general/unroll_dbn_topology.m28
-rw-r--r--sourcecodes/bnt-master/BNT/general/unroll_higher_order_topology.m30
-rw-r--r--sourcecodes/bnt-master/BNT/general/unroll_set.m7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/CVS/Entries3
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/marginal_family_pot.m14
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/observed_nodes.m5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/bnet_from_engine.m12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/get_field.m15
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/inf_engine.m6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/marginal_family.m24
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/set_fields.m13
-rw-r--r--sourcecodes/bnt-master/BNT/inference/@inf_engine/update_engine.m7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/inference/CVS/Entries.Log4
-rw-r--r--sourcecodes/bnt-master/BNT/inference/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/dummy0
-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
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@filter_engine/bnet_from_engine.m5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@filter_engine/enter_evidence.m14
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@filter_engine/filter_engine.m10
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_family.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_nodes.m10
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries9
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/back.m21
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/backT.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd.m17
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd1.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/hmm_2TBN_inf_engine.m86
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_family.m35
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_nodes.m27
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/mk_hmm_obs_lik_vec.m53
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/update_engine.m8
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Entries13
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/jtree_2TBN_inf_engine.m116
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back.m27
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1.m21
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1_mpe.m22
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT_mpe.m16
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back_mpe.m28
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd.m44
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd1.m26
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/jtree_2TBN_inf_engine.m69
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_family.m12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_nodes.m32
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/set_fields.m16
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Entries10
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back.m27
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back1.m21
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/backT.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/enter_evidence.m22
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd.m47
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd1.m32
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/jtree_sparse_2TBN_inf_engine.m95
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_family.m12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_nodes.m32
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Entries8
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/bnet_from_engine.m5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/enter_evidence.m21
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/find_mpe.m33
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_family.m6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_nodes.m7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/smoother_engine.m12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/update_engine.m5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/CVS/Entries.Log5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/online/dummy0
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/belprop_fg_inf_engine.m47
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/enter_evidence.m126
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/find_mpe.m49
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/loopy_converged.m12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/marginal_nodes.m6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/set_params.m24
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Entries.Log2
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/belprop_gdl_inf_engine.m67
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/belprop_inf_engine_nostr.m31
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/enter_evidence.m80
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/enter_evidence1.m94
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/marginal_domain.m5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/belprop_inf_engine.m90
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/enter_evidence.m86
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/find_mpe.m49
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/loopy_converged.m13
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/marginal_family.m6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/marginal_nodes.m14
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/junk68
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/parallel_protocol.m86
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/tree_protocol.m48
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/belprop_mrf2_inf_engine.m46
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/bp_mrf2.m209
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/enter_soft_evidence.m15
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/find_mpe.m12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/marginal_nodes.m10
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/set_params.m15
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/cond_gauss_inf_engine.m23
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/enter_evidence.m57
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/marginal_nodes.m36
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/enter_evidence.m10
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/enumerative_inf_engine.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/marginal_nodes.m41
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/enter_evidence.m46
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/gaussian_inf_engine.m25
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/marginal_nodes.m15
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/extract_params_from_gbn.m38
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/enter_evidence.m29
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/gibbs_sampling_inf_engine.m104
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/marginal_nodes.m135
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CPT.m5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CVS/Entries13
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_children.m12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_families.m12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_families_dbn.m13
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_posterior.c107
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_posterior_dbn.m59
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_strides.m27
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/get_cpts.m8
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/get_slice_dbn.c116
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/get_slice_dbn.m87
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/my_sample_discrete.m7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/sample_single_discrete.c22
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/enter_evidence.m42
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/find_mpe.m28
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/global_joint_inf_engine.m8
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/marginal_family.m7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/marginal_nodes.m8
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Entries14
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/collect_evidence.m29
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/distribute_evidence.m26
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/enter_evidence.m107
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/enter_soft_evidence.m19
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/cliques_from_engine.m5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/clq_containing_nodes.m24
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/collect_evidence.m12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/distribute_evidence.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/enter_evidence.m88
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/enter_soft_evidence.m21
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/find_max_config.m35
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/find_mpe.m71
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/init_pot.m20
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/jtree_inf_engine.m141
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/marginal_family.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/marginal_nodes.m22
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/set_fields.m13
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Entries3
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_family.m59
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_nodes_SS.m52
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/enter_evidence.m28
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/jtree_limid_inf_engine.m52
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_family.m52
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_nodes.m17
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/enter_evidence.m82
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/find_mpe.m71
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/jtree_mnet_inf_engine.m101
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Entries12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/cliques_from_engine.m5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/clq_containing_nodes.m24
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/collect_evidence.c634
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/distribute_evidence.c618
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/enter_evidence.m100
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/enter_soft_evidence.m19
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/init_pot.c624
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/jtree_sparse_inf_engine.m126
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/marginal_family.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/marginal_nodes.m22
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/collect_evidence.c635
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/distribute_evidence.c613
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/init_pot.c637
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/init_pot1.c636
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/init_pot1.m20
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/set_fields.m13
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/enter_evidence.m39
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/likelihood_weighting_inf_engine.m25
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/marginal_nodes.m53
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/bethe_free_energy.m50
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/enter_evidence.m153
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/loopy_converged.m13
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/marginal_family.m80
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/marginal_nodes.m43
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/pearl_inf_engine.m158
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/pearl_inf_engine.m~158
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/compute_bel.m24
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/parallel_protocol.m114
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/parallel_protocol.m~114
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/prod_lambda_msgs.m29
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/tree_protocol.m71
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/enter_evidence.m19
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/marginal_nodes.m11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/C_quickscore.c164
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/nr.h536
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/nrutil.c321
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/nrutil.h79
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/quickscore.m76
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/quickscore_inf_engine.m38
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries11
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/initialize_engine.m65
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/README12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/clq_containing_nodes.m24
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/enter_evidence.m260
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_difclq_nodes.m55
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_nodes.m77
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_singleclq_nodes.m30
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/problems.txt76
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push.m38
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push_pot_toclique.m7
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/stab_cond_gauss_inf_engine.m178
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/CVS/Entries5
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/enter_evidence.m12
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/find_mpe.m163
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/marginal_nodes.m79
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/var_elim_inf_engine.m15
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/CVS/Entries.Log17
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/inference/static/dummy0
-rw-r--r--sourcecodes/bnt-master/BNT/installC_BNT.m32
-rw-r--r--sourcecodes/bnt-master/BNT/installC_graph.m16
-rw-r--r--sourcecodes/bnt-master/BNT/learning/CVS/Entries23
-rw-r--r--sourcecodes/bnt-master/BNT/learning/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/learning/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/learning/CovMat.m39
-rw-r--r--sourcecodes/bnt-master/BNT/learning/bayes_update_params.m38
-rw-r--r--sourcecodes/bnt-master/BNT/learning/bic_score_family.m23
-rw-r--r--sourcecodes/bnt-master/BNT/learning/compute_cooling_schedule.m13
-rw-r--r--sourcecodes/bnt-master/BNT/learning/dirichlet_score_family.m42
-rw-r--r--sourcecodes/bnt-master/BNT/learning/kpm_learn_struct_mcmc.m265
-rw-r--r--sourcecodes/bnt-master/BNT/learning/learn_params.m26
-rw-r--r--sourcecodes/bnt-master/BNT/learning/learn_params_dbn.m36
-rw-r--r--sourcecodes/bnt-master/BNT/learning/learn_params_dbn_em.m179
-rw-r--r--sourcecodes/bnt-master/BNT/learning/learn_params_em.m88
-rw-r--r--sourcecodes/bnt-master/BNT/learning/learn_struct_K2.m104
-rw-r--r--sourcecodes/bnt-master/BNT/learning/learn_struct_dbn_reveal.m101
-rw-r--r--sourcecodes/bnt-master/BNT/learning/learn_struct_mcmc.m284
-rw-r--r--sourcecodes/bnt-master/BNT/learning/learn_struct_pdag_ic_star.m155
-rw-r--r--sourcecodes/bnt-master/BNT/learning/learn_struct_pdag_pc.m130
-rw-r--r--sourcecodes/bnt-master/BNT/learning/learn_struct_pdag_pc_constrain.m177
-rw-r--r--sourcecodes/bnt-master/BNT/learning/mcmc_sample_to_hist.m36
-rw-r--r--sourcecodes/bnt-master/BNT/learning/mk_schedule.m10
-rw-r--r--sourcecodes/bnt-master/BNT/learning/mk_tetrad_data_file.m25
-rw-r--r--sourcecodes/bnt-master/BNT/learning/score_dags_old.m62
-rw-r--r--sourcecodes/bnt-master/BNT/learning/score_dags_wocache.m67
-rw-r--r--sourcecodes/bnt-master/BNT/learning/score_family_wocache.m57
-rw-r--r--sourcecodes/bnt-master/BNT/license.gpl.txt450
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Entries15
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/CVS/Entries4
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/normalize_pot.m24
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/set_domain_pot.m9
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/simple_marginalize_pot.m86
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/cg_can_to_mom.m10
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/cg_mom_to_can.m10
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/cgpot.m38
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/display.m4
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/divide_by_pot.m19
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/domain_pot.m5
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/enter_cts_evidence_pot.m8
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/enter_discrete_evidence_pot.m16
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/marginalize_pot.m153
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/multiply_by_pot.m19
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/multiply_pots.m16
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/normalize_pot.m24
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/pot_to_marginal.m27
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cgpot/set_domain_pot.m21
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Entries14
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Entries.Log1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/Old/CVS/Entries3
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/Old/cpot_to_mpot.m25
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/Old/normalize_pot.convert.m9
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/cpot.m17
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/cpot_to_mpot.m29
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/display.m4
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/divide_by_pot.m13
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/domain_pot.m5
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/enter_cts_evidence_pot.m15
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/marginalize_pot.m31
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/multiply_by_pot.m13
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/multiply_pots.m11
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/normalize_pot.m10
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/pot_to_marginal.m6
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/rescale_pot.m5
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@cpot/set_domain_pot.m5
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/CVS/Entries17
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/approxeq_pot.m5
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/display.m4
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/divide_by_pot.m14
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/domain_pot.m5
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/dpot.m26
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/dpot_to_table.m3
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/find_most_prob_entry.m10
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/get_fields.m13
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/marginalize_pot.m17
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/multiply_by_pot.m13
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/multiply_pots.m12
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/normalize_pot.m12
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/pot_to_marginal.m12
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/set_domain_pot.m5
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/subsasgn.m3
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@dpot/subsref.m3
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@mpot/CVS/Entries9
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@mpot/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@mpot/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@mpot/display.m4
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@mpot/marginalize_pot.m27
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@mpot/mpot.m17
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@mpot/mpot_to_cpot.m21
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@mpot/normalize_pot.m6
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@mpot/pot_to_marginal.m13
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@mpot/rescale_pot.m5
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@mpot/set_domain_pot.m5
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgcpot/CVS/Entries6
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgcpot/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgcpot/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgcpot/marginalize_pot.m7
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgcpot/normalize_pot.m6
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgcpot/reduce_pot.m32
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgcpot/rescale_pot.m5
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgcpot/scgcpot.m49
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Entries12
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/README11
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/combine_pots.m24
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/complement_pot.m221
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/direct_combine_pots.m161
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/extension_pot.m55
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/marginalize_pot.m92
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/normalize_pot.m16
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/pot_to_marginal.m29
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/recursive_combine_pots.m40
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/reduce_pot.m53
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@scgpot/scgpot.m30
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@upot/CVS/Entries10
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@upot/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@upot/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@upot/approxeq_pot.m5
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@upot/display.m4
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@upot/divide_by_pot.m13
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@upot/marginalize_pot.m18
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@upot/multiply_by_pot.m12
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@upot/normalize_pot.m13
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@upot/pot_to_marginal.m9
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@upot/upot.m15
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/@upot/upot_to_opt_policy.m25
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/CPD_to_pot.m21
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/CVS/Entries7
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/CVS/Entries.Log9
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Old/CVS/Entries2
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Old/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Old/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Old/comp_eff_node_sizes.m11
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/README100
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/CVS/Entries19
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/divide_by_sparse_table.c126
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/divide_by_table.c120
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/divide_by_table.m12
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/extend_domain_table.m24
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/marg_sparse_table.c181
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/marg_table.c175
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/marg_table.m27
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/marg_tableC.c175
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/marg_tableM.m30
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_sparse_table.c155
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table.c114
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table.m7
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table2.m30
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_tableC.c114
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_tableM.m7
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table_global.m7
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/rep_mult.c92
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/Tables/repmat_and_mult.c97
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/check_for_cd_arcs.m23
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/determine_pot_type.m25
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/genops.c707
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/mk_initial_pot.m29
-rw-r--r--sourcecodes/bnt-master/BNT/test_BNT.m108
-rw-r--r--sourcecodes/bnt-master/BNT/uninstallC_BNT.m17
1355 files changed, 57138 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/BNT/@assocarray/CVS/Entries b/sourcecodes/bnt-master/BNT/@assocarray/CVS/Entries
new file mode 100644
index 00000000..dc217e2f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/@assocarray/CVS/Entries
@@ -0,0 +1,3 @@
+/assocarray.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/subsref.m/1.1.1.1/Wed Aug  4 19:36:30 2004//
+D
diff --git a/sourcecodes/bnt-master/BNT/@assocarray/CVS/Repository b/sourcecodes/bnt-master/BNT/@assocarray/CVS/Repository
new file mode 100644
index 00000000..258fe401
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/@assocarray/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/@assocarray
diff --git a/sourcecodes/bnt-master/BNT/@assocarray/CVS/Root b/sourcecodes/bnt-master/BNT/@assocarray/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/@assocarray/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/@assocarray/assocarray.m b/sourcecodes/bnt-master/BNT/@assocarray/assocarray.m
new file mode 100644
index 00000000..84f96361
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/@assocarray/assocarray.m
@@ -0,0 +1,10 @@
+function A = assocarray(keys, vals)
+% ASSOCARRAY Make an associative array
+% function A = assocarray(keys, vals)
+%
+% keys{i} is the i'th string, vals{i} is the i'th value.
+% After construction, A('foo') will return the value associated with foo.
+
+A.keys = keys;
+A.vals = vals;
+A = class(A, 'assocarray');
diff --git a/sourcecodes/bnt-master/BNT/@assocarray/subsref.m b/sourcecodes/bnt-master/BNT/@assocarray/subsref.m
new file mode 100644
index 00000000..12673106
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/@assocarray/subsref.m
@@ -0,0 +1,15 @@
+function val = subsref(A, S)
+% SUBSREF Subscript reference for an associative array
+% A('foo') will return the value associated with foo.
+% If there are multiple identicaly keys, the first match is returned.
+% Currently the search is sequential.
+
+i = 1;
+while i <= length(A.keys)
+  if strcmp(S.subs{1}, A.keys{i})
+    val = A.vals{i};
+    return;
+  end
+  i = i + 1;
+end
+error(['can''t find ' S.subs{1}])
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/CVS/Entries
new file mode 100644
index 00000000..06c13c68
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/CVS/Entries
@@ -0,0 +1,2 @@
+/boolean_CPD.m/1.1.1.1/Wed May 29 15:59:52 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/CVS/Repository
new file mode 100644
index 00000000..d57d477d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@boolean_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/boolean_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/boolean_CPD.m
new file mode 100644
index 00000000..3b35788f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@boolean_CPD/boolean_CPD.m
@@ -0,0 +1,179 @@
+function CPD = boolean_CPD(bnet, self, ftype, fname, pfail)
+% BOOLEAN_CPD Make a tabular CPD representing a (noisy) boolean function
+%
+% CPD = boolean_cpd(bnet, self, 'inline', f) uses the inline function f
+% to specify the CPT.
+% e.g., suppose X4 = X2 AND (NOT X3). Then we can write
+%    bnet.CPD{4} = boolean_CPD(bnet, 4, 'inline', inline('(x(1) & ~x(2)'));  
+% Note that x(1) refers pvals(1) = X2, and x(2) refers to pvals(2)=X3.
+%
+% CPD = boolean_cpd(bnet, self, 'named', f) assumes f is a function name.
+% f can be built-in to matlab, or a file.
+% e.g., If X4 = X2 AND X3, we can write
+%    bnet.CPD{4} = boolean_CPD(bnet, 4, 'named', 'and');
+% e.g., If X4 = X2 OR X3, we can write
+%    bnet.CPD{4} = boolean_CPD(bnet, 4, 'named', 'any');
+%
+% CPD = boolean_cpd(bnet, self, 'rnd') makes a random non-redundant bool fn.
+%
+% CPD = boolean_CPD(bnet, self, 'inline'/'named', f, pfail)
+% will put probability mass 1-pfail on f(parents), and put pfail on the other value.
+% This is useful for simulating noisy boolean functions.
+% If pfail is omitted, it is set to 0.
+% (Note that adding noise to a random (non-redundant) boolean function just creates a different
+% (potentially redundant) random boolean function.)
+%
+% Note: This cannot be used to simulate a noisy-OR gate.
+% Example: suppose C has parents A and B, and the
+% link of A->C fails with prob pA and the link B->C fails with pB.
+% Then the noisy-OR gate defines the following distribution
+%
+%  A  B  P(C=0)
+%  0  0  1.0
+%  1  0  pA
+%  0  1  pB
+%  1  1  pA * PB
+% 
+% By contrast, boolean_CPD(bnet, C, 'any', p) would define
+%
+%  A  B  P(C=0) 
+%  0  0  1-p    
+%  1  0  p      
+%  0  1  p
+%  1  1  p
+
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = tabular_CPD(bnet, self);
+  return;
+elseif isa(bnet, 'boolean_CPD')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+
+if nargin < 5, pfail = 0; end
+
+ps = parents(bnet.dag, self);
+ns = bnet.node_sizes;
+psizes = ns(ps);
+self_size = ns(self);
+
+psucc = 1-pfail;
+
+k = length(ps);
+switch ftype
+ case 'inline', f = eval_bool_fn(fname, k);
+ case 'named',  f = eval_bool_fn(fname, k);
+ case 'rnd',    f = mk_rnd_bool_fn(k);
+ otherwise,     error(['unknown function type ' ftype]);
+end
+
+CPT = zeros(prod(psizes), self_size);
+ndx = find(f==0);
+CPT(ndx, 1) = psucc;
+CPT(ndx, 2) = pfail;
+ndx = find(f==1);
+CPT(ndx, 2) = psucc;
+CPT(ndx, 1) = pfail;
+if k > 0
+  CPT = reshape(CPT, [psizes self_size]);  
+end
+
+clamp = 1;
+CPD = tabular_CPD(bnet, self, CPT, [], clamp);
+
+
+
+%%%%%%%%%%%%
+
+function f = eval_bool_fn(fname, n)
+% EVAL_BOOL_FN Evaluate a boolean function on all bit vectors of length n
+% f = eval_bool_fn(fname, n)
+%
+% e.g. f = eval_bool_fn(inline('x(1) & x(3)'), 3)
+% returns   0     0     0     0     0     1     0     1
+
+ns = 2*ones(1, n);
+f = zeros(1, 2^n);
+bits = ind2subv(ns, 1:2^n);
+for i=1:2^n
+  f(i) = feval(fname, bits(i,:)-1);
+end
+
+%%%%%%%%%%%%%%%
+
+function f = mk_rnd_bool_fn(n)
+% MK_RND_BOOL_FN Make a random bit vector of length n that encodes a non-redundant boolean function
+% f = mk_rnd_bool_fn(n)
+
+red = 1;
+while red
+  f = sample_discrete([0.5 0.5], 2^n, 1)-1;
+  red = redundant_bool_fn(f);
+end
+
+%%%%%%%%
+
+
+function red = redundant_bool_fn(f)
+% REDUNDANT_BOOL_FN Does a boolean function depend on all its input values?
+% r = redundant_bool_fn(f)
+%
+% f is a vector of length 2^n, representing the output for each bit vector.
+% An input is redundant if there is no assignment to the other bits
+% which changes the output e.g., input 1 is redundant if u(2:n) s.t.,
+% f([0 u(2:n)]) <> f([1 u(2:n)]). 
+% A function is redundant it it has any redundant inputs.
+
+n = log2(length(f));
+ns = 2*ones(1,n);
+red = 0;
+for i=1:n
+  ens = ns;
+  ens(i) = 1;
+  U = ind2subv(ens, 1:2^(n-1));
+  U(:,i) = 1;
+  f1 = f(subv2ind(ns, U));
+  U(:,i) = 2;
+  f2 = f(subv2ind(ns, U));
+  if isequal(f1, f2)
+    red = 1;
+    return;
+  end
+end
+
+
+%%%%%%%%%%
+
+function [b, iter] = rnd_truth_table(N)
+% RND_TRUTH_TABLE Construct the output of a random truth table s.t. each input is non-redundant
+% b = rnd_truth_table(N)
+%
+% N is the number of inputs. 
+% b is a random bit string of length N, representing the output of the truth table.
+% Non-redundant means that, for each input position k,
+% there are at least two bit patterns, u and v, that differ only in the k'th position,
+% s.t., f(u) ~= f(v), where f is the function represented by b.
+% We use rejection sampling to ensure non-redundancy.
+%
+% Example: b = [0 0 0 1  0 0 0 1] is indep of 3rd input (AND of inputs 1 and 2)
+
+bits = ind2subv(2*ones(1,N), 1:2^N)-1;
+redundant = 1;
+iter = 0;
+while redundant && (iter < 4)
+  iter = iter + 1;
+  b = sample_discrete([0.5 0.5], 1, 2^N)-1;
+  redundant = 0;
+  for i=1:N
+    on = find(bits(:,i)==1);
+    off = find(bits(:,i)==0);
+    if isequal(b(on), b(off))
+      redundant = 1;
+      break;
+    end
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/CVS/Entries
new file mode 100644
index 00000000..eb6be4f0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/CVS/Entries
@@ -0,0 +1,2 @@
+/deterministic_CPD.m/1.1.1.1/Mon Oct  7 13:26:36 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/CVS/Repository
new file mode 100644
index 00000000..fe1e84b5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@deterministic_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/deterministic_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/deterministic_CPD.m
new file mode 100644
index 00000000..f44b6545
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@deterministic_CPD/deterministic_CPD.m
@@ -0,0 +1,59 @@
+function CPD = deterministic_CPD(bnet, self, fname, pfail)
+% DETERMINISTIC_CPD Make a tabular CPD representing a (noisy) deterministic function
+%
+% CPD = deterministic_CPD(bnet, self, fname)
+% This calls feval(fname, pvals) for each possible vector of parent values.
+% e.g., suppose there are 2 ternary parents, then pvals = 
+%  [1 1], [2 1], [3 1],   [1 2], [2 2], [3 2],   [1 3], [2 3], [3 3]
+% If v = feval(fname, pvals(i)), then
+%  CPD(x | parents=pvals(i)) = 1 if x==v, and = 0 if x<>v
+% e.g., suppose X4 = X2 AND (NOT X3). Then
+%    bnet.CPD{4} = deterministic_CPD(bnet, 4, inline('((x(1)-1) & ~(x(2)-1)) + 1'));  
+% Note that x(1) refers pvals(1) = X2, and x(2) refers to pvals(2)=X3
+% See also boolean_CPD.
+%
+% CPD = deterministic_CPD(bnet, self, fname, pfail)
+% will put probability mass 1-pfail on f(parents), and distribute pfail over the other values.
+% This is useful for simulating noisy deterministic functions.
+% If pfail is omitted, it is set to 0.
+%
+
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = tabular_CPD(bnet, self);
+  return;
+elseif isa(bnet, 'deterministic_CPD')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+
+if nargin < 4, pfail = 0; end
+
+ps = parents(bnet.dag, self);
+ns = bnet.node_sizes;
+psizes = ns(ps);
+self_size = ns(self);
+
+psucc = 1-pfail;
+
+CPT = zeros(prod(psizes), self_size);
+pvals = zeros(1, length(ps));
+for i=1:prod(psizes)
+  pvals = ind2subv(psizes, i);
+  x = feval(fname, pvals);
+  %fprintf('%d ', [pvals x]); fprintf('\n');
+  if psucc == 1
+    CPT(i, x) = 1;
+  else
+    CPT(i, x) = psucc;
+    rest = mysetdiff(1:self_size, x);
+    CPT(i, rest) = pfail/length(rest);
+  end
+end
+CPT = reshape(CPT, [psizes self_size]);  
+
+CPD = tabular_CPD(bnet, self, 'CPT',CPT, 'clamped',1);
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CPD_to_lambda_msg.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CPD_to_lambda_msg.m
new file mode 100644
index 00000000..d53e9e0f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CPD_to_lambda_msg.m
@@ -0,0 +1,16 @@
+function lam_msg = CPD_to_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence)
+% CPD_TO_LAMBDA_MSG Compute lambda message (discrete)
+% lam_msg = compute_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence)
+% Pearl p183 eq 4.52
+
+switch msg_type
+  case 'd',
+   T = prod_CPT_and_pi_msgs(CPD, n, ps, msg, p);
+   mysize = length(msg{n}.lambda);
+   lambda = dpot(n, mysize, msg{n}.lambda);
+   T = multiply_by_pot(T, lambda);
+   lam_msg = pot_to_marginal(marginalize_pot(T, p));
+   lam_msg = lam_msg.T;           
+ case 'g',
+  error('discrete_CPD can''t create Gaussian msgs')
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CPD_to_pi.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CPD_to_pi.m
new file mode 100644
index 00000000..5962c92e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CPD_to_pi.m
@@ -0,0 +1,13 @@
+function pi = CPD_to_pi(CPD, msg_type, n, ps, msg, evidence)
+% COMPUTE_PI Compute pi vector (discrete) 
+% pi = compute_pi(CPD, msg_type, n, ps, msg, evidence)
+% Pearl p183 eq 4.51
+
+switch msg_type
+  case 'd',
+   T = prod_CPT_and_pi_msgs(CPD, n, ps, msg);
+   pi = pot_to_marginal(marginalize_pot(T, n));
+   pi = pi.T(:);                   
+ case 'g', 
+  error('can only convert discrete CPD to Gaussian pi if observed')
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CPD_to_scgpot.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CPD_to_scgpot.m
new file mode 100644
index 00000000..3d611536
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CPD_to_scgpot.m
@@ -0,0 +1,25 @@
+function pot = CPD_to_scgpot(CPD, domain, ns, cnodes, evidence)
+% CPD_TO_SCGPOT Convert a CPD to a CG potential, incorporating any evidence (discrete)
+% pot = CPD_to_scgpot(CPD, domain, ns, cnodes, evidence)
+%
+% domain is the domain of CPD.
+% node_sizes(i) is the size of node i.
+% cnodes
+% evidence{i} is the evidence on the i'th node.
+
+%odom = domain(~isemptycell(evidence(domain)));
+
+%vals = cat(1, evidence{odom});
+%map = find_equiv_posns(odom, domain);
+%index = mk_multi_index(length(domain), map, vals);
+CPT = CPD_to_CPT(CPD);
+%CPT = CPT(index{:});
+CPT = CPT(:);
+%ns(odom) = 1;
+potarray = cell(1, length(CPT));
+for i=1:length(CPT)
+  %p = CPT(i);
+  potarray{i} = scgcpot(0, 0, CPT(i));
+  %scpot{i} = scpot(0, 0);
+end
+pot = scgpot(domain, [], [], ns, potarray);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Entries
new file mode 100644
index 00000000..57599441
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Entries
@@ -0,0 +1,15 @@
+/CPD_to_lambda_msg.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/CPD_to_pi.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/CPD_to_scgpot.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/README/1.1.1.1/Wed May 29 15:59:52 2002//
+/convert_CPD_to_table_hidden_ps.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/convert_obs_CPD_to_table.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/convert_to_pot.m/1.1.1.1/Fri Feb 20 22:00:38 2004//
+/convert_to_sparse_table.c/1.1.1.1/Wed May 29 15:59:52 2002//
+/convert_to_table.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/discrete_CPD.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/dom_sizes.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/log_prob_node.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/prob_node.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/sample_node.m/1.1.1.1/Wed May 29 15:59:52 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Entries.Log
new file mode 100644
index 00000000..9c6f22e4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Entries.Log
@@ -0,0 +1,2 @@
+A D/Old////
+A D/private////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Repository
new file mode 100644
index 00000000..f3418ec7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@discrete_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/CVS/Entries
new file mode 100644
index 00000000..15bb91c3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/CVS/Entries
@@ -0,0 +1,5 @@
+/convert_to_pot.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/convert_to_table.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/prob_CPD.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/prob_node.m/1.1.1.1/Wed May 29 15:59:52 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/CVS/Repository
new file mode 100644
index 00000000..df41b4fd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@discrete_CPD/Old
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/convert_to_pot.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/convert_to_pot.m
new file mode 100644
index 00000000..3f178e1c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/convert_to_pot.m
@@ -0,0 +1,44 @@
+function pot = convert_to_pot(CPD, pot_type, domain, evidence)
+% CONVERT_TO_POT Convert a tabular CPD to one or more potentials
+% pots = convert_to_pot(CPD, pot_type, domain, evidence)
+%
+% pots{i} = CPD evaluated using evidence(domain(:,i))
+% If 'domains' is a single row vector, pots will be an object, not a cell array.
+
+ncases = size(domain,2);
+assert(ncases==1); % not yet vectorized
+
+sz = dom_sizes(CPD);
+ns = zeros(1, max(domain));
+ns(domain) = sz;
+
+local_ev = evidence(domain);
+obs_bitv = ~isemptycell(local_ev);
+odom = domain(obs_bitv);
+T = convert_to_table(CPD, domain, local_ev, obs_bitv);
+
+switch pot_type
+ case 'u',
+  pot = upot(domain, sz, T, 0*myones(sz));  
+ case 'd',
+  ns(odom) = 1;
+  pot = dpot(domain, ns(domain), T);          
+ case {'c','g'},
+  % Since we want the output to be a Gaussian, the whole family must be observed.
+  % In other words, the potential is really just a constant.
+  p = T;
+  %p = prob_node(CPD, evidence(domain(end)), evidence(domain(1:end-1)));
+  ns(domain) = 0;
+  pot = cpot(domain, ns(domain), log(p));       
+ case 'cg',
+  T = T(:);
+  ns(odom) = 1;
+  can = cell(1, length(T));
+  for i=1:length(T)
+    can{i} = cpot([], [], log(T(i)));
+  end
+  pot = cgpot(domain, [], ns, can);   
+ otherwise,
+  error(['unrecognized pot type ' pot_type])
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/convert_to_table.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/convert_to_table.m
new file mode 100644
index 00000000..65121122
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/convert_to_table.m
@@ -0,0 +1,23 @@
+function T = convert_to_table(CPD, domain, local_ev, obs_bitv)
+% CONVERT_TO_TABLE Convert a discrete CPD to a table
+% function T = convert_to_table(CPD, domain, local_ev, obs_bitv)
+%
+% We convert the CPD to a CPT, and then lookup the evidence on the discrete parents.
+% The resulting table can easily be converted to a potential.
+
+
+CPT = CPD_to_CPT(CPD);
+obs_child_only = ~any(obs_bitv(1:end-1)) & obs_bitv(end);
+
+if obs_child_only
+  sz = size(CPT);
+  CPT = reshape(CPT, prod(sz(1:end-1)), sz(end));
+  o = local_ev{end};
+  T = CPT(:, o);
+else
+  odom = domain(obs_bitv);  
+  vals = cat(1, local_ev{find(obs_bitv)}); % undo cell array
+  map = find_equiv_posns(odom, domain);
+  index = mk_multi_index(length(domain), map, vals);
+  T = CPT(index{:});
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/prob_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/prob_CPD.m
new file mode 100644
index 00000000..c0a79bda
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/prob_CPD.m
@@ -0,0 +1,25 @@
+function p = prob_CPD(CPD, domain, ns, cnodes, evidence)
+% PROB_CPD Compute prob of a node given evidence on the parents (discrete)
+% p = prob_CPD(CPD, domain, ns, cnodes, evidence)
+%
+% domain is the domain of CPD.
+% node_sizes(i) is the size of node i.
+% cnodes = all the cts nodes
+% evidence{i} is the evidence on the i'th node.
+
+ps = domain(1:end-1);
+self = domain(end);
+CPT = CPD_to_CPT(CPD);
+
+if isempty(ps)
+  T = CPT;
+else
+  assert(~any(isemptycell(evidence(ps))));
+  pvals = cat(1, evidence{ps});
+  i = subv2ind(ns(ps), pvals(:)');
+  T = reshape(CPT, [prod(ns(ps)) ns(self)]);
+  T = T(i,:);
+end
+p = T(evidence{self});
+
+ 
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/prob_node.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/prob_node.m
new file mode 100644
index 00000000..1a39fc79
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/Old/prob_node.m
@@ -0,0 +1,51 @@
+function [P, p] = prob_node(CPD, self_ev, pev)
+% PROB_NODE Compute prod_m P(x(i,m)| x(pi_i,m), theta_i) for node i (discrete)
+% [P, p] = prob_node(CPD, self_ev, pev)
+%
+% self_ev(m) is the evidence on this node in case m.
+% pev(i,m) is the evidence on the i'th parent in case m (if there are any parents).
+% (These may also be cell arrays.)
+%
+% p(m) = P(x(i,m)| x(pi_i,m), theta_i) 
+% P = prod p(m)
+
+if iscell(self_ev), usecell = 1; else usecell = 0; end
+
+ncases = length(self_ev);
+sz = dom_sizes(CPD);
+
+nparents = length(sz)-1;
+if nparents == 0
+  assert(isempty(pev));
+else
+  assert(isequal(size(pev), [nparents ncases]));
+end
+
+n = length(sz);
+dom = 1:n;
+p = zeros(1, ncases);
+if nparents == 0
+  for m=1:ncases
+    if usecell
+      evidence = {self_ev{m}};
+    else
+      evidence = num2cell(self_ev(m));
+    end
+    T = convert_to_table(CPD, dom, evidence);
+    p(m) = T;
+  end
+else
+  for m=1:ncases
+    if usecell
+      evidence = cell(1,n);
+      evidence(1:n-1) = pev(:,m);
+      evidence(n) = self_ev(m);
+    else
+      evidence = num2cell([pev(:,m)', self_ev(m)]);
+    end
+    T = convert_to_table(CPD, dom, evidence);
+    p(m) = T;
+  end
+end
+P = prod(p);
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/README b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/README
new file mode 100644
index 00000000..c0c5a3b3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/README
@@ -0,0 +1,5 @@
+Any CPD on a discrete child with discrete parents
+can be represented as a table (although this might be quite big).
+discrete_CPD uses this tabular representation to implement various
+functions. Subtypes are free to implement more efficient versions.
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_CPD_to_table_hidden_ps.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_CPD_to_table_hidden_ps.m
new file mode 100644
index 00000000..c8f44f7e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_CPD_to_table_hidden_ps.m
@@ -0,0 +1,20 @@
+function T = convert_CPD_to_table_hidden_ps(CPD, child_obs)
+% CONVERT_CPD_TO_TABLE_HIDDEN_PS Convert a discrete CPD to a table
+% T = convert_CPD_to_table_hidden_ps(CPD, child_obs)
+%
+% This is like convert_to_table, except that we are guaranteed that
+% none of the parents have evidence on them.
+% child_obs may be an integer (1,2,...) or [].
+
+CPT = CPD_to_CPT(CPD);
+if isempty(child_obs)
+  T = CPT(:);
+else
+  sz = dom_sizes(CPD);
+  if length(sz)==1 % no parents
+    T = CPT(child_obs);
+  else
+    CPT = reshape(CPT, prod(sz(1:end-1)), sz(end));
+    T = CPT(:, child_obs);
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_obs_CPD_to_table.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_obs_CPD_to_table.m
new file mode 100644
index 00000000..04004088
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_obs_CPD_to_table.m
@@ -0,0 +1,13 @@
+function T = convert_to_table(CPD, domain, evidence)
+% CONVERT_TO_TABLE Convert a discrete CPD to a table
+% T = convert_to_table(CPD, domain, evidence)
+%
+% We convert the CPD to a CPT, and then lookup the evidence on the discrete parents.
+% The resulting table can easily be converted to a potential.
+
+CPT = CPD_to_CPT(CPD);
+odom = domain(~isemptycell(evidence(domain)));
+vals = cat(1, evidence{odom});
+map = find_equiv_posns(odom, domain);
+index = mk_multi_index(length(domain), map, vals);
+T = CPT(index{:});
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_pot.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_pot.m
new file mode 100644
index 00000000..ecc57d49
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_pot.m
@@ -0,0 +1,62 @@
+function pot = convert_to_pot(CPD, pot_type, domain, evidence)
+% CONVERT_TO_POT Convert a discrete CPD to a potential
+% pot = convert_to_pot(CPD, pot_type, domain, evidence)
+%
+% pots = CPD evaluated using evidence(domain)
+
+ncases = size(domain,2);
+assert(ncases==1); % not yet vectorized
+
+sz = dom_sizes(CPD);
+ns = zeros(1, max(domain));
+ns(domain) = sz;
+
+CPT1 = CPD_to_CPT(CPD);
+spar = issparse(CPT1);
+odom = domain(~isemptycell(evidence(domain)));
+if spar
+   T = convert_to_sparse_table(CPD, domain, evidence);
+else 
+   T = convert_to_table(CPD, domain, evidence);
+end
+
+switch pot_type
+ case 'u',
+  pot = upot(domain, sz, T, 0*myones(sz));  
+ case 'd',
+  ns(odom) = 1;
+  pot = dpot(domain, ns(domain), T);          
+ case {'c','g'},
+  % Since we want the output to be a Gaussian, the whole family must be observed.
+  % In other words, the potential is really just a constant.
+  p = T;
+  %p = prob_node(CPD, evidence(domain(end)), evidence(domain(1:end-1)));
+  ns(domain) = 0;
+  pot = cpot(domain, ns(domain), log(p));       
+
+ case 'cg',
+  T = T(:);
+  ns(odom) = 1;
+  can = cell(1, length(T));
+  for i=1:length(T)
+    if T(i) == 0 
+      can{i} = cpot([], [], -Inf); % bug fix by Bob Welch 20/2/04
+    else
+      can{i} = cpot([], [], log(T(i)));
+    end;
+  end
+  pot = cgpot(domain, [], ns, can); 
+  
+ case 'scg'
+  T = T(:);
+  ns(odom) = 1;
+  pot_array = cell(1, length(T));
+  for i=1:length(T)
+    pot_array{i} = scgcpot([], [], T(i));
+  end
+  pot = scgpot(domain, [], [], ns, pot_array);   
+
+ otherwise,
+  error(['unrecognized pot type ' pot_type])
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_sparse_table.c b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_sparse_table.c
new file mode 100644
index 00000000..369f5b7e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_sparse_table.c
@@ -0,0 +1,154 @@
+/* convert_to_sparse_table.c  convert a sparse discrete CPD with evidence into sparse table */
+/* convert_to_pot.m located in ../CPDs/discrete_CPD call it */
+/* 3 input */
+/* CPD      prhs[0] with 1D sparse CPT */
+/* domain   prhs[1]                    */
+/* evidence prhs[2]                    */
+/* 1 output */
+/* T        plhs[0] sparse table       */
+
+#include <math.h>
+#include "mex.h"
+
+void ind_subv(int index, const int *cumprod, const int n, int *bsubv){
+	int i;
+
+	for (i = n-1; i >= 0; i--) {
+		bsubv[i] = ((int)floor(index / cumprod[i]));
+		index = index % cumprod[i];
+	}
+}
+
+int subv_ind(const int n, const int *cumprod, const int *subv){
+	int i, index=0;
+
+	for(i=0; i<n; i++){
+		index += subv[i] * cumprod[i];
+	}
+	return index;
+}
+
+void reset_nzmax(mxArray *spArray, const int old_nzmax, const int new_nzmax){
+	double *ptr;
+	void   *newptr;
+	int    *ir, *jc;
+	int    nbytes;
+
+	if(new_nzmax == old_nzmax) return;
+	nbytes = new_nzmax * sizeof(*ptr);
+	ptr = mxGetPr(spArray);
+	newptr = mxRealloc(ptr, nbytes);
+	mxSetPr(spArray, newptr);
+	nbytes = new_nzmax * sizeof(*ir);
+	ir = mxGetIr(spArray);
+	newptr = mxRealloc(ir, nbytes);
+	mxSetIr(spArray, newptr);
+	jc = mxGetJc(spArray);
+	jc[0] = 0;
+	jc[1] = new_nzmax;
+	mxSetNzmax(spArray, new_nzmax);
+}
+
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int     i, j, NS, NZB, count, bdim, match, domain, bindex, sindex, nzCounts=0;
+	int     *observed, *bsubv, *ssubv, *bir, *sir, *bjc, *sjc, *mask, *ssize, *bcumprod, *scumprod;
+	double  *pDomain, *pSize, *bpr, *spr;
+	mxArray *pTemp;
+
+	pTemp = mxGetField(prhs[0], 0, "CPT");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+	pTemp = mxGetField(prhs[0], 0, "sizes");
+	pSize = mxGetPr(pTemp);
+
+	pDomain = mxGetPr(prhs[1]);
+	bdim = mxGetNumberOfElements(prhs[1]);
+
+	mask = malloc(bdim * sizeof(int));
+	ssize = malloc(bdim * sizeof(int));
+	observed = malloc(bdim * sizeof(int));
+
+	for(i=0; i<bdim; i++){
+		ssize[i] = (int)pSize[i];
+	}
+
+	count = 0;
+	for(i=0; i<bdim; i++){
+		domain = (int)pDomain[i] - 1;
+		pTemp = mxGetCell(prhs[2], domain);
+		if(pTemp){
+			mask[count] = i;
+			ssize[i] = 1;
+			observed[count] = (int)mxGetScalar(pTemp) - 1;
+			count++;
+		}
+	}
+
+	if(count == 0){
+		pTemp = mxGetField(prhs[0], 0, "CPT");
+		plhs[0] = mxDuplicateArray(pTemp);
+		free(mask);
+		free(ssize);
+		free(observed);
+		return;
+	}
+
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(count * sizeof(int));
+	bcumprod = malloc(bdim * sizeof(int));
+	scumprod = malloc(bdim * sizeof(int));
+
+	NS = 1;
+	for(i=0; i<bdim; i++){
+		NS *= ssize[i];
+	}
+
+	plhs[0] = mxCreateSparse(NS, 1, NS, mxREAL);
+	spr = mxGetPr(plhs[0]);
+	sir = mxGetIr(plhs[0]);
+	sjc = mxGetJc(plhs[0]);
+	sjc[0] = 0;
+	sjc[1] = NS;
+
+	bcumprod[0] = 1;
+	scumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bcumprod[i+1] = bcumprod[i] * (int)pSize[i];
+		scumprod[i+1] = scumprod[i] * ssize[i];
+	}
+
+	nzCounts = 0;
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bcumprod, bdim, bsubv);
+		for(j=0; j<count; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		match = 1;
+		for(j=0; j<count; j++){
+			if((ssubv[j]) != observed[j]){
+				match = 0;
+				break;
+			}
+		}
+		if(match){
+			spr[nzCounts] = bpr[i];
+			sindex = subv_ind(bdim, scumprod, bsubv);
+			sir[nzCounts] = sindex;
+			nzCounts++;
+		}
+	}
+
+	reset_nzmax(plhs[0], NS, nzCounts);
+	free(mask);
+	free(ssize);
+	free(observed);
+	free(bsubv);
+	free(ssubv);
+	free(bcumprod);
+	free(scumprod);
+}
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_table.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_table.m
new file mode 100644
index 00000000..dc5bcd40
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_table.m
@@ -0,0 +1,15 @@
+function T = convert_to_table(CPD, domain, evidence)
+% CONVERT_TO_TABLE Convert a discrete CPD to a table
+% T = convert_to_table(CPD, domain, evidence)
+%
+% We convert the CPD to a CPT, and then lookup the evidence on the discrete parents.
+% The resulting table can easily be converted to a potential.
+
+domain = domain(:);
+CPT = CPD_to_CPT(CPD);
+odom = domain(~isemptycell(evidence(domain)));
+vals = cat(1, evidence{odom});
+map = find_equiv_posns(odom, domain);
+index = mk_multi_index(length(domain), map, vals);
+T = CPT(index{:});
+T = T(:);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/discrete_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/discrete_CPD.m
new file mode 100644
index 00000000..b4250831
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/discrete_CPD.m
@@ -0,0 +1,6 @@
+function CPD = discrete_CPD(clamped, dom_sizes)
+% DISCRETE_CPD Virtual constructor for generic discrete CPD
+% CPD = discrete_CPD(clamped, dom_sizes)
+
+CPD.dom_sizes = dom_sizes;
+CPD = class(CPD, 'discrete_CPD', generic_CPD(clamped));
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/dom_sizes.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/dom_sizes.m
new file mode 100644
index 00000000..2ee750de
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/dom_sizes.m
@@ -0,0 +1,5 @@
+function sz = dom_sizes(CPD)
+% DOM_SIZES Return the size of each node in the domain
+% sz = dom_sizes(CPD)
+
+sz = CPD.dom_sizes;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/log_prob_node.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/log_prob_node.m
new file mode 100644
index 00000000..315464a9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/log_prob_node.m
@@ -0,0 +1,12 @@
+function L = log_prob_node(CPD, self_ev, pev)
+% LOG_PROB_NODE Compute sum_m log P(x(i,m)| x(pi_i,m), theta_i) for node i (discrete)
+% L = log_prob_node(CPD, self_ev, pev)
+%
+% self_ev(m) is the evidence on this node in case m.
+% pev(i,m) is the evidence on the i'th parent in case m (if there are any parents).
+% (These may also be cell arrays.)
+
+[P, p] = prob_node(CPD, self_ev, pev); % P may underflow, so we use p
+tiny = exp(-700);
+p = p + (p==0)*tiny; % replace 0s by tiny
+L = sum(log(p));
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/CVS/Entries
new file mode 100644
index 00000000..da678df7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/CVS/Entries
@@ -0,0 +1,2 @@
+/prod_CPT_and_pi_msgs.m/1.1.1.1/Wed May 29 15:59:52 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/CVS/Repository
new file mode 100644
index 00000000..2b3c1c9d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@discrete_CPD/private
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/prod_CPT_and_pi_msgs.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/prod_CPT_and_pi_msgs.m
new file mode 100644
index 00000000..fe8f6a20
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/private/prod_CPT_and_pi_msgs.m
@@ -0,0 +1,18 @@
+function T = prod_CPT_and_pi_msgs(CPD, n, ps, msgs, except)
+% PROD_CPT_AND_PI_MSGS Multiply the CPD and all the pi messages from parents, perhaps excepting one
+% T = prod_CPY_and_pi_msgs(CPD, n, ps, msgs, except)
+
+if nargin < 5, except = -1; end
+
+dom = [ps n];
+%ns = sparse(1, max(dom));
+ns = zeros(1, max(dom));
+CPT = CPD_to_CPT(CPD);
+ns(dom) = mysize(CPT);
+T = dpot(dom, ns(dom), CPT);
+for i=1:length(ps)
+  p = ps(i);
+  if p ~= except
+    T = multiply_by_pot(T, dpot(p, ns(p), msgs{n}.pi_from_parent{i}));
+  end
+end         
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/prob_node.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/prob_node.m
new file mode 100644
index 00000000..275870c8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/prob_node.m
@@ -0,0 +1,81 @@
+function [P, p] = prob_node(CPD, self_ev, pev)
+% PROB_NODE Compute prod_m P(x(i,m)| x(pi_i,m), theta_i) for node i (discrete)
+% [P, p] = prob_node(CPD, self_ev, pev)
+%
+% self_ev(m) is the evidence on this node in case m.
+% pev(i,m) is the evidence on the i'th parent in case m (if there are any parents).
+% (These may also be cell arrays.)
+%
+% p(m) = P(x(i,m)| x(pi_i,m), theta_i) 
+% P = prod p(m)
+
+if iscell(self_ev), usecell = 1; else usecell = 0; end
+
+ncases = length(self_ev);
+sz = dom_sizes(CPD);
+
+nparents = length(sz)-1;
+if nparents == 0
+  assert(isempty(pev));
+else
+  assert(isequal(size(pev), [nparents ncases]));
+end
+
+n = length(sz);
+dom = 1:n;
+p = zeros(1, ncases);
+if isa(CPD, 'tabular_CPD')
+  % speed up by looking up CPT using index Zhang Yimin  2001-12-31
+  if usecell
+    if nparents == 0
+      data = [cell2num(self_ev)]; 
+    else
+      data = [cell2num(pev); cell2num(self_ev)]; 
+    end
+  else
+    if nparents == 0
+      data = [self_ev];
+    else
+      data = [pev; self_ev];
+    end
+  end
+  
+  indices = subv2ind(sz, data'); % each row of data' is a case 
+  
+  CPT=CPD_to_CPT(CPD);
+  p = CPT(indices);
+  
+  %get the prob list
+  %cpt_size = prod(sz);
+  %prob_list=reshape(CPT, cpt_size, 1);
+  %for m=1:ncases  %here we assume we get evidence for node and all its parents
+  %  idx=indices(m);
+  %  p(m)=prob_list(idx); 
+  %end
+  
+else % eg. softmax
+  
+  for m=1:ncases
+    if usecell
+      if nparents == 0
+	evidence = {self_ev{m}};
+      else
+	evidence = cell(1,n);
+	evidence(1:n-1) = pev(:,m);
+	evidence(n) = self_ev(m);
+      end
+    else
+      if nparents == 0
+	evidence = num2cell(self_ev(m));
+      else
+	evidence = num2cell([pev(:,m)', self_ev(m)]);
+      end
+    end
+    T = convert_to_table(CPD, dom, evidence);
+    p(m) = T;
+  end
+end
+  
+P = prod(p);
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/sample_node.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/sample_node.m
new file mode 100644
index 00000000..9e0ed994
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/sample_node.m
@@ -0,0 +1,34 @@
+function y = sample_node(CPD, pvals)
+% SAMPLE_NODE Draw a random sample from P(Xi | x(pi_i), theta_i)  (discrete)
+% y = sample_node(CPD, parent_evidence)
+%
+% parent_evidence{i} is the value of the i'th parent
+
+if 0
+n = length(pvals)+1;
+dom = 1:n;
+evidence = cell(1,n);
+evidence(1:n-1) = pvals;
+T = convert_to_table(CPD, dom, evidence);
+y = sample_discrete(T);
+end
+
+
+CPT = CPD_to_CPT(CPD);
+sz = mysize(CPT);
+nparents = length(sz)-1;
+switch nparents
+ case 0, T = CPT;
+ case 1, T = CPT(pvals{1}, :);
+ case 2, T = CPT(pvals{1}, pvals{2}, :);
+ case 3, T = CPT(pvals{1}, pvals{2}, pvals{3}, :);
+ case 4, T = CPT(pvals{1}, pvals{2}, pvals{3}, pvals{4}, :);
+ otherwise,
+  pvals = cat(1, pvals{:});
+  psz = sz(1:end-1);
+  ssz = sz(end);
+  i = subv2ind(psz, pvals(:)');
+  T = reshape(CPT, [prod(psz) ssz]);
+  T = T(i,:);
+end
+y = sample_discrete(T);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CPD_to_lambda_msg.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CPD_to_lambda_msg.m
new file mode 100644
index 00000000..340ebe5c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CPD_to_lambda_msg.m
@@ -0,0 +1,59 @@
+function lam_msg = CPD_to_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence)
+% CPD_TO_LAMBDA_MSG Compute lambda message (gaussian)
+% lam_msg = compute_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence)
+% Pearl p183 eq 4.52
+
+switch msg_type
+ case 'd',
+  error('gaussian_CPD can''t create discrete msgs')
+ case 'g',
+  cps = ps(CPD.cps);
+  cpsizes = CPD.sizes(CPD.cps);
+  self_size = CPD.sizes(end);
+  i = find_equiv_posns(p, cps); % p is n's i'th cts parent
+  psz = cpsizes(i);
+  if all(msg{n}.lambda.precision == 0) % no info to send on
+    lam_msg.precision = zeros(psz, psz);
+    lam_msg.info_state = zeros(psz, 1);
+    return;
+  end
+  [m, Q, W] = gaussian_CPD_params_given_dps(CPD, [ps n], evidence);
+  Bmu = m;
+  BSigma = Q;
+  for k=1:length(cps) % only get pi msgs from cts parents
+    pk = cps(k);
+    if pk ~= p
+      %bk = block(k, cpsizes);
+      bk = CPD.cps_block_ndx{k};
+      Bk = W(:, bk);
+      m = msg{n}.pi_from_parent{k}; 
+      BSigma = BSigma + Bk * m.Sigma * Bk';
+      Bmu = Bmu + Bk * m.mu;
+    end
+  end
+  % BSigma = Q + sum_{k \neq i} B_k Sigma_k B_k'
+  %bi = block(i, cpsizes);
+  bi = CPD.cps_block_ndx{i};
+  Bi = W(:,bi);
+  P = msg{n}.lambda.precision;
+  if (rcond(P) > 1e-3) || isinf(P)
+    if isinf(P) % Y is observed
+      Sigma_lambda = zeros(self_size, self_size); % infinite precision => 0 variance
+      mu_lambda = msg{n}.lambda.mu; % observed_value;
+    else
+      Sigma_lambda = inv(P);
+      mu_lambda = Sigma_lambda * msg{n}.lambda.info_state;
+    end
+    C = inv(Sigma_lambda + BSigma);
+    lam_msg.precision = Bi' * C * Bi;
+    lam_msg.info_state = Bi' * C * (mu_lambda - Bmu);
+  else
+    % method that uses matrix inversion lemma to avoid inverting P
+    A = inv(P + inv(BSigma));
+    C = P - P*A*P;
+    lam_msg.precision = Bi' * C * Bi;
+    D = eye(self_size) - P*A;
+    z = msg{n}.lambda.info_state;
+    lam_msg.info_state = Bi' * (D*z - D*P*Bmu);
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CPD_to_pi.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CPD_to_pi.m
new file mode 100644
index 00000000..910973e7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CPD_to_pi.m
@@ -0,0 +1,22 @@
+function pi = CPD_to_pi(CPD, msg_type, n, ps, msg, evidence)
+% CPD_TO_PI Compute the pi vector (gaussian)
+% function pi = CPD_to_pi(CPD, msg_type, n, ps, msg, evidence)
+
+switch msg_type
+ case 'd',
+  error('gaussian_CPD can''t create discrete msgs')
+ case 'g',
+  [m, Q, W] = gaussian_CPD_params_given_dps(CPD, [ps n], evidence);
+  cps = ps(CPD.cps);
+  cpsizes = CPD.sizes(CPD.cps);
+  pi.mu = m;
+  pi.Sigma = Q;
+  for k=1:length(cps) % only get pi msgs from cts parents
+    %bk = block(k, cpsizes);
+    bk = CPD.cps_block_ndx{k};
+    Bk = W(:, bk);
+    m = msg{n}.pi_from_parent{k}; 
+    pi.Sigma = pi.Sigma + Bk * m.Sigma * Bk';
+    pi.mu = pi.mu + Bk * m.mu; % m.mu = u(k)
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CPD_to_scgpot.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CPD_to_scgpot.m
new file mode 100644
index 00000000..90e7cc80
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CPD_to_scgpot.m
@@ -0,0 +1,58 @@
+function pot = CPD_to_scgpot(CPD, domain, ns, cnodes, evidence)
+% CPD_TO_CGPOT Convert a Gaussian CPD to a CG potential, incorporating any evidence   
+% pot = CPD_to_cgpot(CPD, domain, ns, cnodes, evidence)
+
+self = CPD.self;
+dnodes = mysetdiff(1:length(ns), cnodes);
+odom = domain(~isemptycell(evidence(domain)));
+cdom = myintersect(cnodes, domain);
+cheaddom = myintersect(self, domain);
+ctaildom = mysetdiff(cdom,cheaddom);
+ddom = myintersect(dnodes, domain);
+cobs = myintersect(cdom, odom);
+dobs = myintersect(ddom, odom);
+ens = ns; % effective node size
+ens(cobs) = 0;
+ens(dobs) = 1;
+
+% Extract the params compatible with the observations (if any) on the discrete parents (if any)
+% parents are all but the last domain element
+ps = domain(1:end-1);
+dps = myintersect(ps, ddom);
+dops = myintersect(dps, odom);
+
+map = find_equiv_posns(dops, dps);
+dpvals = cat(1, evidence{dops});
+index = mk_multi_index(length(dps), map, dpvals);
+
+dpsize = prod(ens(dps));
+cpsize = size(CPD.weights(:,:,1), 2); % cts parents size
+ss = size(CPD.mean, 1); % self size
+% the reshape acts like a squeeze
+m = reshape(CPD.mean(:, index{:}), [ss dpsize]);
+C = reshape(CPD.cov(:, :, index{:}), [ss ss dpsize]);
+W = reshape(CPD.weights(:, :, index{:}), [ss cpsize dpsize]);
+
+
+% Convert each conditional Gaussian to a canonical potential
+pot = cell(1, dpsize);
+for i=1:dpsize
+  %pot{i} = linear_gaussian_to_scgcpot(m(:,i), C(:,:,i), W(:,:,i), cdom, ns, cnodes, evidence);
+  pot{i} = scgcpot(ss, cpsize, 1, m(:,i), W(:,:,i), C(:,:,i));
+end
+
+pot = scgpot(ddom, cheaddom, ctaildom, ens, pot);
+
+
+function pot = linear_gaussian_to_scgcpot(mu, Sigma, W, domain, ns, cnodes, evidence)
+% LINEAR_GAUSSIAN_TO_CPOT Convert a linear Gaussian CPD  to a stable conditional potential element.
+% pot = linear_gaussian_to_cpot(mu, Sigma, W, domain, ns, cnodes, evidence)
+
+p = 1;
+A = mu;
+B = W;
+C = Sigma;
+ns(odom) = 0;
+%pot = scgcpot(, ns(domain), p, A, B, C);
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Entries
new file mode 100644
index 00000000..a6bd3e14
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Entries
@@ -0,0 +1,20 @@
+/CPD_to_lambda_msg.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/CPD_to_pi.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/CPD_to_scgpot.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/adjustable_CPD.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/convert_CPD_to_table_hidden_ps.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/convert_to_pot.m/1.1.1.1/Sun Mar  9 23:03:16 2003//
+/convert_to_table.m/1.1.1.1/Sun May 11 23:31:54 2003//
+/display.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/gaussian_CPD.m/1.1.1.1/Wed Jun 15 21:13:06 2005//
+/gaussian_CPD_params_given_dps.m/1.1.1.1/Sun May 11 23:13:40 2003//
+/get_field.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/learn_params.m/1.1.1.1/Thu Jun 10 01:28:10 2004//
+/log_prob_node.m/1.1.1.1/Tue Sep 10 17:44:00 2002//
+/maximize_params.m/1.1.1.1/Tue May 20 14:10:06 2003//
+/maximize_params_debug.m/1.1.1.1/Fri Jan 31 00:13:10 2003//
+/reset_ess.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/sample_node.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/set_fields.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/update_ess.m/1.1.1.1/Tue Jul 22 22:55:46 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Entries.Log
new file mode 100644
index 00000000..9c6f22e4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Entries.Log
@@ -0,0 +1,2 @@
+A D/Old////
+A D/private////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Repository
new file mode 100644
index 00000000..98ebf3cb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@gaussian_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CPD_to_lambda_msg.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CPD_to_lambda_msg.m
new file mode 100644
index 00000000..5a6d398a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CPD_to_lambda_msg.m
@@ -0,0 +1,64 @@
+function lam_msg = CPD_to_lambda_msg(CPD, msg_type, n, ps, msg, p)
+% CPD_TO_LAMBDA_MSG Compute lambda message (gaussian)
+% lam_msg = compute_lambda_msg(CPD, msg_type, n, ps, msg, p)
+% Pearl p183 eq 4.52
+
+switch msg_type
+ case 'd',
+  error('gaussian_CPD can''t create discrete msgs')
+ case 'g',
+  self_size = CPD.sizes(end);
+  if all(msg{n}.lambda.precision == 0) % no info to send on
+    lam_msg.precision = zeros(self_size);
+    lam_msg.info_state = zeros(self_size, 1);
+    return;
+  end
+  cpsizes = CPD.sizes(CPD.cps);
+  dpval = 1;
+  Q = CPD.cov(:,:,dpval);
+  Sigmai = Q;
+  wmu = zeros(self_size, 1);
+  for k=1:length(ps)
+    pk = ps(k);
+    if pk ~= p
+      bk = block(k, cpsizes);
+      Bk = CPD.weights(:, bk, dpval);
+      m = msg{n}.pi_from_parent{k};
+      Sigmai = Sigmai + Bk * m.Sigma * Bk';
+      wmu = wmu + Bk * m.mu; % m.mu = u(k)
+    end
+  end
+  % Sigmai = Q + sum_{k \neq i} B_k Sigma_k B_k'
+  i = find_equiv_posns(p, ps);
+  bi = block(i, cpsizes);
+  Bi = CPD.weights(:,bi, dpval);
+  
+  if 0
+  P = msg{n}.lambda.precision;
+  if isinf(P) % inv(P)=Sigma_lambda=0
+    precision_temp = inv(Sigmai);
+    lam_msg.precision = Bi' * precision_temp * Bi;
+    lam_msg.info_state = precision_temp * (msg{n}.lambda.mu - wmu);
+  else
+    A = inv(P + inv(Sigmai));
+    precision_temp = P + P*A*P;
+    lam_msg.precision = Bi' * precision_temp * Bi;
+    self_size = length(P);
+    C = eye(self_size) + P*A;
+    z = msg{n}.lambda.info_state;
+    lam_msg.info_state = C*z - C*P*wmu;
+  end
+  end
+  
+  if isinf(msg{n}.lambda.precision)
+    Sigma_lambda = zeros(self_size, self_size); % infinite precision => 0 variance
+    mu_lambda = msg{n}.lambda.mu; % observed_value;
+  else
+    Sigma_lambda = inv(msg{n}.lambda.precision);
+    mu_lambda = Sigma_lambda * msg{n}.lambda.info_state;
+  end
+  precision_temp = inv(Sigma_lambda + Sigmai);
+  lam_msg.precision = Bi' * precision_temp * Bi;
+  lam_msg.info_state = Bi' * precision_temp * (mu_lambda - wmu);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CVS/Entries
new file mode 100644
index 00000000..ea2f5a4c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CVS/Entries
@@ -0,0 +1,7 @@
+/CPD_to_lambda_msg.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/gaussian_CPD.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/log_prob_node.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/maximize_params.m/1.1.1.1/Thu Jan 30 22:38:16 2003//
+/update_ess.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/update_tied_ess.m/1.1.1.1/Wed May 29 15:59:52 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CVS/Repository
new file mode 100644
index 00000000..c89b5b86
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@gaussian_CPD/Old
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/gaussian_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/gaussian_CPD.m
new file mode 100644
index 00000000..6f7138fc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/gaussian_CPD.m
@@ -0,0 +1,184 @@
+function CPD = gaussian_CPD(varargin)
+% GAUSSIAN_CPD Make a conditional linear Gaussian distrib.
+%
+% To define this CPD precisely, call the continuous (cts) parents (if any) X,
+% the discrete parents (if any) Q, and this node Y. Then the distribution on Y is:
+% - no parents: Y ~ N(mu, Sigma)
+% - cts parents : Y|X=x ~ N(mu + W x, Sigma)
+% - discrete parents: Y|Q=i ~ N(mu(i), Sigma(i))
+% - cts and discrete parents: Y|X=x,Q=i ~ N(mu(i) + W(i) x, Sigma(i))
+%
+% CPD = gaussian_CPD(bnet, node, ...) will create a CPD with random parameters,
+% where node is the number of a node in this equivalence class.
+%
+% The list below gives optional arguments [default value in brackets].
+% (Let ns(i) be the size of node i, X = ns(X), Y = ns(Y) and Q = prod(ns(Q)).)
+%
+% mean       - mu(:,i) is the mean given Q=i [ randn(Y,Q) ]
+% cov        - Sigma(:,:,i) is the covariance given Q=i [ repmat(eye(Y,Y), [1 1 Q]) ]
+% weights    - W(:,:,i) is the regression matrix given Q=i [ randn(Y,X,Q) ]
+% cov_type   - if 'diag', Sigma(:,:,i) is diagonal [ 'full' ]
+% tied_cov   - if 1, we constrain Sigma(:,:,i) to be the same for all i [0]
+% clamp_mean - if 1, we do not adjust mu(:,i) during learning [0]
+% clamp_cov  - if 1, we do not adjust Sigma(:,:,i) during learning [0]
+% clamp_weights - if 1, we do not adjust W(:,:,i) during learning [0]
+% cov_prior_weight - weight given to I prior for estimating Sigma [0.01]
+%
+% e.g., CPD = gaussian_CPD(bnet, i, 'mean', [0; 0], 'clamp_mean', 'yes')
+%
+% For backwards compatibility with BNT2, you can also specify the parameters in the following order
+%   CPD = gaussian_CPD(bnet, self, mu, Sigma, W, cov_type, tied_cov, clamp_mean, clamp_cov, clamp_weight)
+%
+% Sometimes it is useful to create an "isolated" CPD, without needing to pass in a bnet.
+% In this case, you must specify the discrete and cts parents (dps, cps) and the family sizes, followed
+% by the optional arguments above:
+%   CPD = gaussian_CPD('self', i, 'dps', dps, 'cps', cps, 'sz', fam_size, ...)
+
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  clamp = 0;
+  CPD = class(CPD, 'gaussian_CPD', generic_CPD(clamp));
+  return;
+elseif isa(varargin{1}, 'gaussian_CPD')
+  % This might occur if we are copying an object.
+  CPD = varargin{1};
+  return;
+end
+CPD = init_fields;
+ 
+CPD = class(CPD, 'gaussian_CPD', generic_CPD(0));
+
+
+% parse mandatory arguments
+if ~isstr(varargin{1}) % pass in bnet
+  bnet = varargin{1};
+  self = varargin{2};
+  args = varargin(3:end);
+  ns = bnet.node_sizes;
+  ps = parents(bnet.dag, self);
+  dps = myintersect(ps, bnet.dnodes);
+  cps = myintersect(ps, bnet.cnodes);
+  fam_sz = ns([ps self]);
+else
+  disp('parsing new style')
+  for i=1:2:length(varargin)
+    switch varargin{i},
+     case 'self', self = varargin{i+1}; 
+     case 'dps',  dps = varargin{i+1};
+     case 'cps',  cps = varargin{i+1};
+     case 'sz',   fam_sz = varargin{i+1};
+    end
+  end
+  ps = myunion(dps, cps);
+  args = varargin;
+end
+
+CPD.self = self;
+CPD.sizes = fam_sz;
+
+% Figure out which (if any) of the parents are discrete, and which cts, and how big they are
+% dps = discrete parents, cps = cts parents
+CPD.cps = find_equiv_posns(cps, ps); % cts parent index
+CPD.dps = find_equiv_posns(dps, ps);
+ss = fam_sz(end);
+psz = fam_sz(1:end-1);
+dpsz = prod(psz(CPD.dps));
+cpsz = sum(psz(CPD.cps));
+
+% set default params
+CPD.mean = randn(ss, dpsz);
+CPD.cov = 100*repmat(eye(ss), [1 1 dpsz]);    
+CPD.weights = randn(ss, cpsz, dpsz);
+CPD.cov_type = 'full';
+CPD.tied_cov = 0;
+CPD.clamped_mean = 0;
+CPD.clamped_cov = 0;
+CPD.clamped_weights = 0;
+CPD.cov_prior_weight = 0.01;
+
+nargs = length(args);
+if nargs > 0
+  if ~isstr(args{1})
+    % gaussian_CPD(bnet, self, mu, Sigma, W, cov_type, tied_cov, clamp_mean, clamp_cov, clamp_weights)
+    if nargs >= 1 & ~isempty(args{1}), CPD.mean = args{1}; end
+    if nargs >= 2 & ~isempty(args{2}), CPD.cov = args{2}; end
+    if nargs >= 3 & ~isempty(args{3}), CPD.weights = args{3}; end
+    if nargs >= 4 & ~isempty(args{4}), CPD.cov_type = args{4}; end
+    if nargs >= 5 & ~isempty(args{5}) & strcmp(args{5}, 'tied'), CPD.tied_cov = 1; end
+    if nargs >= 6 & ~isempty(args{6}), CPD.clamped_mean = 1; end
+    if nargs >= 7 & ~isempty(args{7}), CPD.clamped_cov = 1; end
+    if nargs >= 8 & ~isempty(args{8}), CPD.clamped_weights = 1; end
+  else
+    CPD = set_fields(CPD, args{:});
+  end
+end
+
+% Make sure the matrices have 1 dimension per discrete parent.
+% Bug fix due to Xuejing Sun 3/6/01
+CPD.mean = myreshape(CPD.mean, [ss ns(dps)]);
+CPD.cov = myreshape(CPD.cov, [ss ss ns(dps)]);
+CPD.weights = myreshape(CPD.weights, [ss cpsz ns(dps)]);
+  
+CPD.init_cov = CPD.cov;  % we reset to this if things go wrong during learning
+
+% expected sufficient statistics 
+CPD.Wsum = zeros(dpsz,1);
+CPD.WYsum = zeros(ss, dpsz);
+CPD.WXsum = zeros(cpsz, dpsz);
+CPD.WYYsum = zeros(ss, ss, dpsz);
+CPD.WXXsum = zeros(cpsz, cpsz, dpsz);
+CPD.WXYsum = zeros(cpsz, ss, dpsz);
+
+% For BIC
+CPD.nsamples = 0;
+switch CPD.cov_type
+  case 'full',
+    ncov_params = ss*(ss-1)/2; % since symmetric (and positive definite)
+  case 'diag',
+    ncov_params = ss;
+  otherwise
+    error(['unrecognized cov_type ' cov_type]);
+end
+% params = weights + mean + cov
+if CPD.tied_cov
+  CPD.nparams = ss*cpsz*dpsz + ss*dpsz + ncov_params;
+else
+  CPD.nparams = ss*cpsz*dpsz + ss*dpsz + dpsz*ncov_params;
+end
+
+
+
+clamped = CPD.clamped_mean & CPD.clamped_cov & CPD.clamped_weights;
+CPD = set_clamped(CPD, clamped);
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.self = [];
+CPD.sizes = [];
+CPD.cps = [];
+CPD.dps = [];
+CPD.mean = [];
+CPD.cov = [];
+CPD.weights = [];
+CPD.clamped_mean = [];
+CPD.clamped_cov = [];
+CPD.clamped_weights = [];
+CPD.init_cov = [];
+CPD.cov_type = [];
+CPD.tied_cov = [];
+CPD.Wsum = [];
+CPD.WYsum = [];
+CPD.WXsum = [];
+CPD.WYYsum = [];
+CPD.WXXsum = [];
+CPD.WXYsum = [];
+CPD.nsamples = [];
+CPD.nparams = [];            
+CPD.cov_prior_weight = [];
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/log_prob_node.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/log_prob_node.m
new file mode 100644
index 00000000..3fa398c8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/log_prob_node.m
@@ -0,0 +1,59 @@
+function L = log_prob_node(CPD, self_ev, pev)
+% LOG_PROB_NODE Compute prod_m log P(x(i,m)| x(pi_i,m), theta_i) for node i (gaussian)
+% L = log_prob_node(CPD, self_ev, pev)
+%
+% self_ev(m) is the evidence on this node in case m.
+% pev(i,m) is the evidence on the i'th parent in case m (if there are any parents).
+% (These may also be cell arrays.)
+
+if iscell(self_ev), usecell = 1; else usecell = 0; end
+
+use_log = 1;
+ncases = length(self_ev);
+nparents = length(CPD.sizes)-1;
+assert(ncases == size(pev, 2));
+
+if ncases == 0
+  L = 0;
+  return;
+end
+
+if length(CPD.dps)==0 % no discrete parents, so we can vectorize
+  i = 1;
+  if usecell
+    Y = cell2num(self_ev);
+  else
+    Y = self_ev;
+  end
+  if length(CPD.cps) == 0 
+    L = gaussian_prob(Y, CPD.mean(:,i), CPD.cov(:,:,i), use_log);
+  else
+    if usecell
+      X = cell2num(pev);
+    else
+      X = pev;
+    end
+    L = gaussian_prob(Y, CPD.mean(:,i) + CPD.weights(:,:,i)*X, CPD.cov(:,:,i), use_log);
+  end
+else % each case uses a (potentially) different set of parameters
+  L = 0;
+  for m=1:ncases
+    if usecell
+      dpvals = cat(1, pev{CPD.dps, m});
+    else
+      dpvals = pev(CPD.dps, m);
+    end
+    i = subv2ind(CPD.sizes(CPD.dps), dpvals(:)');
+    y = self_ev{m};
+    if length(CPD.cps) == 0 
+      L = L + gaussian_prob(y, CPD.mean(:,i), CPD.cov(:,:,i), use_log);
+    else
+      if usecell
+	x = cat(1, pev{CPD.cps, m});
+      else
+	x = pev(CPD.cps, m);
+      end
+      L = L + gaussian_prob(y, CPD.mean(:,i) + CPD.weights(:,:,i)*x, CPD.cov(:,:,i), use_log);
+    end
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/maximize_params.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/maximize_params.m
new file mode 100644
index 00000000..48447358
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/maximize_params.m
@@ -0,0 +1,147 @@
+function CPD = maximize_params(CPD, temp)
+% MAXIMIZE_PARAMS Set the params of a CPD to their ML values (Gaussian)
+% CPD = maximize_params(CPD, temperature)
+%
+% Temperature is currently only used for entropic prior on Sigma
+
+% For details, see "Fitting a Conditional Gaussian Distribution", Kevin Murphy, tech. report,
+% 1998, available at www.cs.berkeley.edu/~murphyk/papers.html
+% Refering to table 2, we use equations 1/2 to estimate the covariance matrix in the untied/tied case,
+% and equation 9 to estimate the weight matrix and mean.
+% We do not implement spherical Gaussians - the code is already pretty complicated!
+
+if ~adjustable_CPD(CPD), return; end
+
+%assert(approxeq(CPD.nsamples, sum(CPD.Wsum)));
+assert(~any(isnan(CPD.WXXsum)))
+assert(~any(isnan(CPD.WXYsum)))
+assert(~any(isnan(CPD.WYYsum)))
+
+[self_size cpsize dpsize] = size(CPD.weights);
+
+% Append 1s to the parents, and derive the corresponding cross products.
+% This is used when estimate the means and weights simultaneosuly,
+% and when estimatting Sigma.
+% Let x2 = [x 1]'
+XY = zeros(cpsize+1, self_size, dpsize); % XY(:,:,i) = sum_l w(l,i) x2(l) y(l)' 
+XX = zeros(cpsize+1, cpsize+1, dpsize); % XX(:,:,i) = sum_l w(l,i) x2(l) x2(l)' 
+YY = zeros(self_size, self_size, dpsize); % YY(:,:,i) = sum_l w(l,i) y(l) y(l)' 
+for i=1:dpsize
+  XY(:,:,i) = [CPD.WXYsum(:,:,i) % X*Y
+	       CPD.WYsum(:,i)']; % 1*Y
+  % [x  * [x' 1]  = [xx' x
+  %  1]              x'  1]
+  XX(:,:,i) = [CPD.WXXsum(:,:,i) CPD.WXsum(:,i);
+	       CPD.WXsum(:,i)'   CPD.Wsum(i)];
+  YY(:,:,i) = CPD.WYYsum(:,:,i);
+end
+
+w = CPD.Wsum(:);
+% Set any zeros to one before dividing
+% This is valid because w(i)=0 => WYsum(:,i)=0, etc
+w = w + (w==0);
+
+if CPD.clamped_mean
+  % Estimating B2 and then setting the last column (the mean) to the clamped mean is *not* equivalent
+  % to estimating B and then adding the clamped_mean to the last column.
+  if ~CPD.clamped_weights
+    B = zeros(self_size, cpsize, dpsize);
+    for i=1:dpsize
+      if det(CPD.WXXsum(:,:,i))==0
+	B(:,:,i) = 0;
+      else
+	% Eqn 9 in table 2 of TR
+	%B(:,:,i) = CPD.WXYsum(:,:,i)' * inv(CPD.WXXsum(:,:,i));
+	B(:,:,i) = (CPD.WXXsum(:,:,i) \ CPD.WXYsum(:,:,i))';
+      end
+    end
+    %CPD.weights = reshape(B, [self_size cpsize dpsize]);
+    CPD.weights = B;
+  end
+elseif CPD.clamped_weights % KPM 1/25/02
+  if ~CPD.clamped_mean % ML estimate is just sample mean of the residuals
+    for i=1:dpsize
+      CPD.mean(:,i) = (CPD.WYsum(:,i) - CPD.weights(:,:,i) * CPD.WXsum(:,i)) / w(i);
+    end
+  end
+else % nothing is clamped, so estimate mean and weights simultaneously
+  B2 = zeros(self_size, cpsize+1, dpsize);
+  for i=1:dpsize
+    if det(XX(:,:,i))==0  % fix by U. Sondhauss 6/27/99
+      B2(:,:,i)=0;          
+    else                    
+      % Eqn 9 in table 2 of TR
+      %B2(:,:,i) = XY(:,:,i)' * inv(XX(:,:,i));
+      B2(:,:,i) = (XX(:,:,i) \ XY(:,:,i))';
+    end                   
+    CPD.mean(:,i) = B2(:,cpsize+1,i);
+    CPD.weights(:,:,i) = B2(:,1:cpsize,i);
+  end
+end
+
+% Let B2 = [W mu]
+if cpsize>0
+  B2(:,1:cpsize,:) = reshape(CPD.weights, [self_size cpsize dpsize]);
+end
+B2(:,cpsize+1,:) = reshape(CPD.mean, [self_size dpsize]);
+
+% To avoid singular covariance matrices,
+% we use the regularization method suggested in "A Quasi-Bayesian approach to estimating
+% parameters for mixtures of normal distributions", Hamilton 91.
+% If the ML estimate is Sigma = M/N, the MAP estimate is (M+gamma*I) / (N+gamma),
+% where gamma >=0 is a smoothing parameter (equivalent sample size of I prior)
+
+gamma = CPD.cov_prior_weight;
+
+if ~CPD.clamped_cov
+  if CPD.cov_prior_entropic % eqn 12 of Brand AI/Stat 99
+    Z = 1-temp;
+    % When temp > 1, Z is negative, so we are dividing by a smaller
+    % number, ie. increasing the variance.
+  else
+    Z = 0;
+  end
+  if CPD.tied_cov
+    S = zeros(self_size, self_size);
+    % Eqn 2 from table 2 in TR
+    for i=1:dpsize
+      S = S + (YY(:,:,i) - B2(:,:,i)*XY(:,:,i));
+    end
+    %denom = max(1, CPD.nsamples + gamma + Z);
+    denom = CPD.nsamples + gamma + Z;
+    S = (S + gamma*eye(self_size)) / denom;
+    if strcmp(CPD.cov_type, 'diag')
+      S = diag(diag(S));
+    end
+    CPD.cov = repmat(S, [1 1 dpsize]);
+  else 
+    for i=1:dpsize      
+      % Eqn 1 from table 2 in TR
+      S = YY(:,:,i) - B2(:,:,i)*XY(:,:,i);
+      %denom = max(1, w(i) + gamma + Z); % gives wrong answers on mhmm1
+      denom = w(i) + gamma + Z;
+      S = (S + gamma*eye(self_size)) / denom;
+      CPD.cov(:,:,i) = S;
+    end
+    if strcmp(CPD.cov_type, 'diag')
+      for i=1:dpsize      
+	CPD.cov(:,:,i) = diag(diag(CPD.cov(:,:,i)));
+      end
+    end
+  end
+end
+
+
+check_covars = 0;
+min_covar = 1e-5;
+if check_covars % prevent collapsing to a point
+  for i=1:dpsize
+    if min(svd(CPD.cov(:,:,i))) < min_covar
+      disp(['resetting singular covariance for node ' num2str(CPD.self)]);
+      CPD.cov(:,:,i) = CPD.init_cov(:,:,i);
+    end
+  end
+end
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/update_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/update_ess.m
new file mode 100644
index 00000000..988012e2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/update_ess.m
@@ -0,0 +1,85 @@
+function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+% UPDATE_ESS Update the Expected Sufficient Statistics of a Gaussian node
+% function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+
+%if nargin < 6
+%  hidden_bitv = zeros(1, max(fmarginal.domain));
+%  hidden_bitv(find(isempty(evidence)))=1;
+%end
+
+dom = fmarginal.domain;
+self = dom(end);
+ps = dom(1:end-1);
+hidden_self = hidden_bitv(self);
+cps = myintersect(ps, cnodes);
+dps = mysetdiff(ps, cps);
+hidden_cps = all(hidden_bitv(cps));
+hidden_dps = all(hidden_bitv(dps));
+
+CPD.nsamples = CPD.nsamples + 1;            
+[ss cpsz dpsz] = size(CPD.weights); % ss = self size
+
+% Let X be the cts parent (if any), Y be the cts child (self).
+
+if ~hidden_self & (isempty(cps) | ~hidden_cps) & hidden_dps % all cts nodes are observed, all discrete nodes are hidden
+  % Since X and Y are observed, SYY = 0, SXX = 0, SXY = 0
+  % Since discrete parents are hidden, we do not need to add evidence to w.
+  w = fmarginal.T(:);
+  CPD.Wsum = CPD.Wsum + w;
+  y = evidence{self};
+  Cyy = y*y';
+  if ~CPD.useC
+     W = repmat(w(:)',ss,1); % W(y,i) = w(i)
+     W2 = repmat(reshape(W, [ss 1 dpsz]), [1 ss 1]); % W2(x,y,i) = w(i)
+     CPD.WYsum = CPD.WYsum +  W .* repmat(y(:), 1, dpsz);
+     CPD.WYYsum = CPD.WYYsum + W2  .* repmat(reshape(Cyy, [ss ss 1]), [1 1 dpsz]);
+  else
+     W = w(:)';
+     W2 = reshape(W, [1 1 dpsz]);
+     CPD.WYsum = CPD.WYsum +  rep_mult(W, y(:), size(CPD.WYsum)); 
+     CPD.WYYsum = CPD.WYYsum + rep_mult(W2, Cyy, size(CPD.WYYsum));
+  end
+  if cpsz > 0 % X exists
+    x = cat(1, evidence{cps}); x = x(:);
+    Cxx = x*x';
+    Cxy = x*y';
+    if ~CPD.useC
+       CPD.WXsum = CPD.WXsum + W .* repmat(x(:), 1, dpsz);
+       CPD.WXXsum = CPD.WXXsum + W2 .* repmat(reshape(Cxx, [cpsz cpsz 1]), [1 1 dpsz]);
+       CPD.WXYsum = CPD.WXYsum + W2 .* repmat(reshape(Cxy, [cpsz ss 1]), [1 1 dpsz]);
+    else
+       CPD.WXsum = CPD.WXsum + rep_mult(W, x(:), size(CPD.WXsum));
+       CPD.WXXsum = CPD.WXXsum + rep_mult(W2, Cxx, size(CPD.WXXsum));
+       CPD.WXYsum = CPD.WXYsum + rep_mult(W2, Cxy, size(CPD.WXYsum));
+    end
+  end
+  return;
+end
+
+% general (non-vectorized) case
+fullm = add_evidence_to_gmarginal(fmarginal, evidence, ns, cnodes); % slow!
+
+if dpsz == 1 % no discrete parents
+  w = 1;
+else
+  w = fullm.T(:);
+end
+
+CPD.Wsum = CPD.Wsum + w;
+xi = 1:cpsz;
+yi = (cpsz+1):(cpsz+ss);
+for i=1:dpsz
+  muY = fullm.mu(yi, i);
+  SYY = fullm.Sigma(yi, yi, i);
+  CPD.WYsum(:,i) = CPD.WYsum(:,i) + w(i)*muY;
+  CPD.WYYsum(:,:,i) = CPD.WYYsum(:,:,i) + w(i)*(SYY + muY*muY'); % E[X Y] = Cov[X,Y] + E[X] E[Y]
+  if cpsz > 0
+    muX = fullm.mu(xi, i);
+    SXX = fullm.Sigma(xi, xi, i);
+    SXY = fullm.Sigma(xi, yi, i);
+    CPD.WXsum(:,i) = CPD.WXsum(:,i) + w(i)*muX;
+    CPD.WXXsum(:,:,i) = CPD.WXXsum(:,:,i) + w(i)*(SXX + muX*muX');
+    CPD.WXYsum(:,:,i) = CPD.WXYsum(:,:,i) + w(i)*(SXY + muX*muY');
+  end
+end                
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/update_tied_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/update_tied_ess.m
new file mode 100644
index 00000000..798c795c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/Old/update_tied_ess.m
@@ -0,0 +1,118 @@
+function CPD = update_tied_ess(CPD, domain, engine, evidence, ns, cnodes)
+
+if ~adjustable_CPD(CPD), return; end
+nCPDs = size(domain, 2);
+fmarginal = cell(1, nCPDs);
+for l=1:nCPDs
+  fmarginal{l} = marginal_family(engine, nodes(l));
+end
+
+[ss cpsz dpsz] = size(CPD.weights);
+if const_evidence_pattern(engine)
+  dom = domain(:,1);
+  dnodes = mysetdiff(1:length(ns), cnodes);
+  ddom = myintersect(dom, dnodes);
+  cdom = myintersect(dom, cnodes);
+  odom = dom(~isemptycell(evidence(dom)));
+  hdom = dom(isemptycell(evidence(dom)));
+  % If all hidden nodes are discrete and all cts nodes are observed 
+  % (e.g., HMM with Gaussian output)
+  % we can add the observed evidence in parallel
+  if mysubset(ddom, hdom) & mysubset(cdom, odom)
+    [mu, Sigma, T] = add_cts_ev_to_marginals(fmarginal, evidence, ns, cnodes);
+  else
+    mu = zeros(ss, dpsz, nCPDs);
+    Sigma = zeros(ss, ss, dpsz, nCPDs);
+    T = zeros(dpsz, nCPDs);
+    for l=1:nCPDs
+      [mu(:,:,l), Sigma(:,:,:,l), T(:,l)] = add_ev_to_marginals(fmarginal{l}, evidence, ns, cnodes);
+    end
+  end
+end
+CPD.nsamples = CPD.nsamples + nCPDs;            
+
+
+if dpsz == 1 % no discrete parents
+  w = 1;
+else
+  w = fullm.T(:);
+end
+CPD.Wsum = CPD.Wsum + w;
+% Let X be the cts parent (if any), Y be the cts child (self).
+xi = 1:cpsz;
+yi = (cpsz+1):(cpsz+ss);
+for i=1:dpsz
+  muY = fullm.mu(yi, i);
+  SYY = fullm.Sigma(yi, yi, i);
+  CPD.WYsum(:,i) = CPD.WYsum(:,i) + w(i)*muY;
+  CPD.WYYsum(:,:,i) = CPD.WYYsum(:,:,i) + w(i)*(SYY + muY*muY'); % E[X Y] = Cov[X,Y] + E[X] E[Y]
+  if cpsz > 0
+    muX = fullm.mu(xi, i);
+    SXX = fullm.Sigma(xi, xi, i);
+    SXY = fullm.Sigma(xi, yi, i);
+    CPD.WXsum(:,i) = CPD.WXsum(:,i) + w(i)*muX;
+    CPD.WXYsum(:,:,i) = CPD.WXYsum(:,:,i) + w(i)*(SXY + muX*muY');
+    CPD.WXXsum(:,:,i) = CPD.WXXsum(:,:,i) + w(i)*(SXX + muX*muX');
+  end
+end                
+
+
+%%%%%%%%%%%%%
+
+function fullm = add_evidence_to_marginal(fmarginal, evidence, ns, cnodes)
+
+
+dom = fmarginal.domain;
+
+% Find out which values of the discrete parents (if any) are compatible with 
+% the discrete evidence (if any).
+dnodes = mysetdiff(1:length(ns), cnodes);
+ddom = myintersect(dom, dnodes);
+cdom = myintersect(dom, cnodes);
+odom = dom(~isemptycell(evidence(dom)));
+hdom = dom(isemptycell(evidence(dom)));
+
+dobs = myintersect(ddom, odom);
+dvals = cat(1, evidence{dobs});
+ens = ns; % effective node sizes
+ens(dobs) = 1;
+S = prod(ens(ddom));
+subs = ind2subv(ens(ddom), 1:S);
+mask = find_equiv_posns(dobs, ddom);
+subs(mask) = dvals;
+supportedQs = subv2ind(ns(ddom), subs);
+
+if isempty(ddom)
+  Qarity = 1;
+else
+  Qarity = prod(ns(ddom));
+end
+fullm.T = zeros(Qarity, 1);
+fullm.T(supportedQs) = fmarginal.T(:);
+
+% Now put the hidden cts parts into their right blocks,
+% leaving the observed cts parts as 0.
+cobs = myintersect(cdom, odom);
+chid = myintersect(cdom, hdom);
+cvals = cat(1, evidence{cobs});
+n = sum(ns(cdom));
+fullm.mu = zeros(n,Qarity);
+fullm.Sigma = zeros(n,n,Qarity);
+
+if ~isempty(chid)
+  chid_blocks = block(find_equiv_posns(chid, cdom), ns(cdom));
+end
+if ~isempty(cobs)
+  cobs_blocks = block(find_equiv_posns(cobs, cdom), ns(cdom));
+end
+
+for i=1:length(supportedQs)
+  Q = supportedQs(i);
+  if ~isempty(chid)
+    fullm.mu(chid_blocks, Q) = fmarginal.mu(:, i);
+    fullm.Sigma(chid_blocks, chid_blocks, Q) = fmarginal.Sigma(:,:,i);
+  end
+  if ~isempty(cobs)
+    fullm.mu(cobs_blocks, Q) = cvals(:);
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/adjustable_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/adjustable_CPD.m
new file mode 100644
index 00000000..ea5190c3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/adjustable_CPD.m
@@ -0,0 +1,5 @@
+function p = adjustable_CPD(CPD)
+% ADJUSTABLE_CPD Does this CPD have any adjustable params? (gaussian)
+% p = adjustable_CPD(CPD)
+
+p = ~CPD.clamped_mean || ~CPD.clamped_cov || ~CPD.clamped_weights;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/convert_CPD_to_table_hidden_ps.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/convert_CPD_to_table_hidden_ps.m
new file mode 100644
index 00000000..acb2c7d2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/convert_CPD_to_table_hidden_ps.m
@@ -0,0 +1,20 @@
+function T = convert_CPD_to_table_hidden_ps(CPD, self_val)
+% CONVERT_CPD_TO_TABLE_HIDDEN_PS Convert a Gaussian CPD to a table
+% function T = convert_CPD_to_table_hidden_ps(CPD, self_val)
+%
+% self_val must be a non-empty vector.
+% All the parents are hidden.
+%
+% This is used by misc/convert_dbn_CPDs_to_tables
+
+m = CPD.mean;
+C = CPD.cov;
+W = CPD.weights;
+
+[ssz dpsize] = size(m);
+
+T = zeros(dpsize, 1);
+for i=1:dpsize
+  T(i) = gaussian_prob(self_val, m(:,i), C(:,:,i));
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/convert_to_pot.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/convert_to_pot.m
new file mode 100644
index 00000000..6afe8d1d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/convert_to_pot.m
@@ -0,0 +1,71 @@
+function pot = convert_to_pot(CPD, pot_type, domain, evidence)
+% CONVERT_TO_POT Convert a Gaussian CPD to one or more potentials
+% pot = convert_to_pot(CPD, pot_type, domain, evidence)
+
+sz = CPD.sizes;
+ns = zeros(1, max(domain));
+ns(domain) = sz;
+
+odom = domain(~isemptycell(evidence(domain)));
+ps = domain(1:end-1);
+cps = ps(CPD.cps);
+dps = ps(CPD.dps);
+self = domain(end);
+cdom = [cps(:)' self];
+ddom = dps;
+cnodes = cdom;
+  
+switch pot_type
+ case 'u',
+  error('gaussian utility potentials not yet supported');
+ 
+ case 'd',
+  T = convert_to_table(CPD, domain, evidence);
+  ns(odom) = 1;
+  pot = dpot(domain, ns(domain), T);          
+
+ case {'c','g'},
+  [m, C, W] = gaussian_CPD_params_given_dps(CPD, domain, evidence);
+  pot = linear_gaussian_to_cpot(m, C, W, domain, ns, cnodes, evidence);
+
+ case 'cg',
+  [m, C, W] = gaussian_CPD_params_given_dps(CPD, domain, evidence);
+  % Convert each conditional Gaussian to a canonical potential
+  cobs = myintersect(cdom, odom);
+  dobs = myintersect(ddom, odom);
+  ens = ns; % effective node size
+  ens(cobs) = 0;
+  ens(dobs) = 1;
+  dpsize = prod(ens(dps));
+  can = cell(1, dpsize);
+  for i=1:dpsize
+    if isempty(W)
+      can{i} = linear_gaussian_to_cpot(m(:,i), C(:,:,i), [], cdom, ns, cnodes, evidence);
+    else
+      can{i} = linear_gaussian_to_cpot(m(:,i), C(:,:,i), W(:,:,i), cdom, ns, cnodes, evidence);
+    end
+  end
+  pot = cgpot(ddom, cdom, ens, can);
+
+ case 'scg',
+  [m, C, W] = gaussian_CPD_params_given_dps(CPD, domain, evidence);
+  cobs = myintersect(cdom, odom);
+  dobs = myintersect(ddom, odom);
+  ens = ns; % effective node size
+  ens(cobs) = 0;
+  ens(dobs) = 1;
+  dpsize = prod(ens(dps));
+  cpsize = size(W, 2); % cts parents size
+  ss = size(m, 1); % self size
+  cheaddom = self;
+  ctaildom = cps(:)';
+  pot_array = cell(1, dpsize);
+  for i=1:dpsize
+    pot_array{i} = scgcpot(ss, cpsize, 1, m(:,i), W(:,:,i), C(:,:,i));
+  end
+  pot = scgpot(ddom, cheaddom, ctaildom, ens, pot_array);
+
+ otherwise,
+  error(['unrecognized pot_type' pot_type])
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/convert_to_table.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/convert_to_table.m
new file mode 100644
index 00000000..4a8d5904
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/convert_to_table.m
@@ -0,0 +1,38 @@
+function T = convert_to_table(CPD, domain, evidence)
+% CONVERT_TO_TABLE Convert a Gaussian CPD to a table
+% T = convert_to_table(CPD, domain, evidence)
+
+
+sz = CPD.sizes;
+ns = zeros(1, max(domain));
+ns(domain) = sz;
+
+odom = domain(~isemptycell(evidence(domain)));
+ps = domain(1:end-1);
+cps = ps(CPD.cps);
+dps = ps(CPD.dps);
+self = domain(end);
+cdom = [cps(:)' self];
+ddom = dps;
+cnodes = cdom;
+
+[m, C, W] = gaussian_CPD_params_given_dps(CPD, domain, evidence);
+
+
+ns(odom) = 1;
+dpsize = prod(ns(dps));
+self = domain(end);
+assert(myismember(self, odom));
+self_val = evidence{self};
+T = zeros(dpsize, 1);
+if length(cps) > 0 
+  assert(~any(isemptycell(evidence(cps))));
+  cps_vals = cat(1, evidence{cps});
+  for i=1:dpsize
+    T(i) = gaussian_prob(self_val, m(:,i) + W(:,:,i)*cps_vals, C(:,:,i));
+  end
+else
+  for i=1:dpsize
+    T(i) = gaussian_prob(self_val, m(:,i), C(:,:,i));
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/display.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/display.m
new file mode 100644
index 00000000..a3d73c83
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/display.m
@@ -0,0 +1,4 @@
+function display(CPD)
+
+disp('gaussian_CPD object');
+disp(struct(CPD)); 
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/gaussian_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/gaussian_CPD.m
new file mode 100644
index 00000000..de519218
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/gaussian_CPD.m
@@ -0,0 +1,161 @@
+function CPD = gaussian_CPD(bnet, self, varargin)
+% GAUSSIAN_CPD Make a conditional linear Gaussian distrib.
+%
+% CPD = gaussian_CPD(bnet, node, ...) will create a CPD with random parameters,
+% where node is the number of a node in this equivalence class.
+
+% To define this CPD precisely, call the continuous (cts) parents (if any) X,
+% the discrete parents (if any) Q, and this node Y. Then the distribution on Y is:
+% - no parents: Y ~ N(mu, Sigma)
+% - cts parents : Y|X=x ~ N(mu + W x, Sigma)
+% - discrete parents: Y|Q=i ~ N(mu(i), Sigma(i))
+% - cts and discrete parents: Y|X=x,Q=i ~ N(mu(i) + W(i) x, Sigma(i))
+%
+% The list below gives optional arguments [default value in brackets].
+% (Let ns(i) be the size of node i, X = ns(X), Y = ns(Y) and Q = prod(ns(Q)).)
+% Parameters will be reshaped to the right size if necessary.
+%
+% mean       - mu(:,i) is the mean given Q=i [ randn(Y,Q) ]
+% cov        - Sigma(:,:,i) is the covariance given Q=i [ repmat(100*eye(Y,Y), [1 1 Q]) ]
+% weights    - W(:,:,i) is the regression matrix given Q=i [ randn(Y,X,Q) ]
+% cov_type   - if 'diag', Sigma(:,:,i) is diagonal [ 'full' ]
+% tied_cov   - if 1, we constrain Sigma(:,:,i) to be the same for all i [0]
+% clamp_mean - if 1, we do not adjust mu(:,i) during learning [0]
+% clamp_cov  - if 1, we do not adjust Sigma(:,:,i) during learning [0]
+% clamp_weights - if 1, we do not adjust W(:,:,i) during learning [0]
+% cov_prior_weight - weight given to I prior for estimating Sigma [0.01]
+% cov_prior_entropic - if 1, we also use an entropic prior for Sigma [0]
+%
+% e.g., CPD = gaussian_CPD(bnet, i, 'mean', [0; 0], 'clamp_mean', 1)
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  clamp = 0;
+  CPD = class(CPD, 'gaussian_CPD', generic_CPD(clamp));
+  return;
+elseif isa(bnet, 'gaussian_CPD')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+CPD = init_fields;
+ 
+CPD = class(CPD, 'gaussian_CPD', generic_CPD(0));
+
+args = varargin;
+ns = bnet.node_sizes;
+ps = parents(bnet.dag, self);
+dps = myintersect(ps, bnet.dnodes);
+cps = myintersect(ps, bnet.cnodes);
+fam_sz = ns([ps self]);
+
+CPD.self = self;
+CPD.sizes = fam_sz;
+
+% Figure out which (if any) of the parents are discrete, and which cts, and how big they are
+% dps = discrete parents, cps = cts parents
+CPD.cps = find_equiv_posns(cps, ps); % cts parent index
+CPD.dps = find_equiv_posns(dps, ps);
+ss = fam_sz(end);
+psz = fam_sz(1:end-1);
+dpsz = prod(psz(CPD.dps));
+cpsz = sum(psz(CPD.cps));
+
+% set default params
+CPD.mean = randn(ss, dpsz);
+CPD.cov = 100*repmat(eye(ss), [1 1 dpsz]);    
+CPD.weights = randn(ss, cpsz, dpsz);
+CPD.cov_type = 'full';
+CPD.tied_cov = 0;
+CPD.clamped_mean = 0;
+CPD.clamped_cov = 0;
+CPD.clamped_weights = 0;
+CPD.cov_prior_weight = 0.01;
+CPD.cov_prior_entropic = 0;
+nargs = length(args);
+if nargs > 0
+  CPD = set_fields(CPD, args{:});
+end
+
+% Make sure the matrices have 1 dimension per discrete parent.
+% Bug fix due to Xuejing Sun 3/6/01
+CPD.mean = myreshape(CPD.mean, [ss ns(dps)]);
+CPD.cov = myreshape(CPD.cov, [ss ss ns(dps)]);
+CPD.weights = myreshape(CPD.weights, [ss cpsz ns(dps)]);
+
+% Precompute indices into block structured  matrices
+% to speed up CPD_to_lambda_msg and CPD_to_pi
+cpsizes = CPD.sizes(CPD.cps);
+CPD.cps_block_ndx = cell(1, length(cps));
+for i=1:length(cps)
+  CPD.cps_block_ndx{i} = block(i, cpsizes);
+end
+
+%%%%%%%%%%% 
+% Learning stuff
+
+% expected sufficient statistics 
+CPD.Wsum = zeros(dpsz,1);
+CPD.WYsum = zeros(ss, dpsz);
+CPD.WXsum = zeros(cpsz, dpsz);
+CPD.WYYsum = zeros(ss, ss, dpsz);
+CPD.WXXsum = zeros(cpsz, cpsz, dpsz);
+CPD.WXYsum = zeros(cpsz, ss, dpsz);
+
+% For BIC
+CPD.nsamples = 0;
+switch CPD.cov_type
+ case 'full',
+  % since symmetric 
+    %ncov_params = ss*(ss-1)/2; 
+    ncov_params = ss*(ss+1)/2; 
+  case 'diag',
+    ncov_params = ss;
+  otherwise
+    error(['unrecognized cov_type ' cov_type]);
+end
+% params = weights + mean + cov
+if CPD.tied_cov
+  CPD.nparams = ss*cpsz*dpsz + ss*dpsz + ncov_params;
+else
+  CPD.nparams = ss*cpsz*dpsz + ss*dpsz + dpsz*ncov_params;
+end
+
+% for speeding up maximize_params
+CPD.useC = exist('rep_mult');
+
+clamped = CPD.clamped_mean && CPD.clamped_cov && CPD.clamped_weights;
+CPD = set_clamped(CPD, clamped);
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.self = [];
+CPD.sizes = [];
+CPD.cps = [];
+CPD.dps = [];
+CPD.mean = [];
+CPD.cov = [];
+CPD.weights = [];
+CPD.clamped_mean = [];
+CPD.clamped_cov = [];
+CPD.clamped_weights = [];
+CPD.cov_type = [];
+CPD.tied_cov = [];
+CPD.Wsum = [];
+CPD.WYsum = [];
+CPD.WXsum = [];
+CPD.WYYsum = [];
+CPD.WXXsum = [];
+CPD.WXYsum = [];
+CPD.nsamples = [];
+CPD.nparams = [];            
+CPD.cov_prior_weight = [];
+CPD.cov_prior_entropic = [];
+CPD.useC = [];
+CPD.cps_block_ndx = [];
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/gaussian_CPD_params_given_dps.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/gaussian_CPD_params_given_dps.m
new file mode 100644
index 00000000..72231a76
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/gaussian_CPD_params_given_dps.m
@@ -0,0 +1,28 @@
+function [m, C, W] = gaussian_CPD_params_given_dps(CPD, domain, evidence)
+% GAUSSIAN_CPD_PARAMS_GIVEN_EV_ON_DPS Extract parameters given evidence on all discrete parents
+% function [m, C, W] = gaussian_CPD_params_given_ev_on_dps(CPD, domain, evidence)
+
+ps = domain(1:end-1);
+dps = ps(CPD.dps);
+if isempty(dps)
+  m = CPD.mean;
+  C = CPD.cov;
+  W = CPD.weights;
+else
+  odom = domain(~isemptycell(evidence(domain)));
+  dops = myintersect(dps, odom);
+  dpvals = cat(1, evidence{dops});
+  if length(dops) == length(dps)
+    dpsizes = CPD.sizes(CPD.dps);
+    dpval = subv2ind(dpsizes, dpvals(:)');
+    m = CPD.mean(:, dpval);
+    C = CPD.cov(:, :, dpval);
+    W = CPD.weights(:, :, dpval);
+  else
+    map = find_equiv_posns(dops, dps);
+    index = mk_multi_index(length(dps), map, dpvals);
+    m = CPD.mean(:, index{:});
+    C = CPD.cov(:, :, index{:});
+    W = CPD.weights(:, :, index{:});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/get_field.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/get_field.m
new file mode 100644
index 00000000..2a50e1ac
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/get_field.m
@@ -0,0 +1,19 @@
+function val = get_params(CPD, name)
+% GET_PARAMS Get the parameters (fields) for a gaussian_CPD object
+% val = get_params(CPD, name)
+%
+% The following fields can be accessed
+%
+% mean       - mu(:,i) is the mean given Q=i
+% cov        - Sigma(:,:,i) is the covariance given Q=i 
+% weights    - W(:,:,i) is the regression matrix given Q=i 
+%
+% e.g., mean = get_params(CPD, 'mean')
+
+switch name
+ case 'mean',      val = CPD.mean;
+ case 'cov',       val = CPD.cov;
+ case 'weights',   val = CPD.weights;
+ otherwise,
+  error(['invalid argument name ' name]);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/learn_params.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/learn_params.m
new file mode 100644
index 00000000..7ae5cb52
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/learn_params.m
@@ -0,0 +1,31 @@
+function CPD = learn_params(CPD, fam, data, ns, cnodes)
+%function CPD = learn_params(CPD, fam, data, ns, cnodes)
+% LEARN_PARAMS Compute the maximum likelihood estimate of the params of a gaussian CPD given complete data
+% CPD = learn_params(CPD, fam, data, ns, cnodes)
+%
+% data(i,m) is the value of node i in case m (can be cell array).
+% We assume this node has a maximize_params method.
+
+ncases = size(data, 2);
+CPD = reset_ess(CPD);
+% make a fully observed joint distribution over the family
+fmarginal.domain = fam;
+fmarginal.T = 1;
+fmarginal.mu = [];
+fmarginal.Sigma = [];
+if ~iscell(data)
+  cases = num2cell(data);
+else
+  cases = data;
+end
+hidden_bitv = zeros(1, max(fam));
+for m=1:ncases
+  % specify (as a bit vector) which elements in the family domain are hidden
+  hidden_bitv = zeros(1, max(fmarginal.domain));
+  ev = cases(:,m);
+  hidden_bitv(find(isempty(ev)))=1;
+  CPD = update_ess(CPD, fmarginal, ev, ns, cnodes, hidden_bitv);
+end
+CPD = maximize_params(CPD);
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/log_prob_node.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/log_prob_node.m
new file mode 100644
index 00000000..ac10f8a3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/log_prob_node.m
@@ -0,0 +1,49 @@
+function L = log_prob_node(CPD, self_ev, pev)
+% LOG_PROB_NODE Compute prod_m log P(x(i,m)| x(pi_i,m), theta_i) for node i (gaussian)
+% L = log_prob_node(CPD, self_ev, pev)
+%
+% self_ev(m) is the evidence on this node in case m.
+% pev(i,m) is the evidence on the i'th parent in case m (if there are any parents).
+% (These may also be cell arrays.)
+
+if iscell(self_ev), usecell = 1; else usecell = 0; end
+
+use_log = 1;
+ncases = length(self_ev);
+nparents = length(CPD.sizes)-1;
+assert(ncases == size(pev, 2));
+
+if ncases == 0
+  L = 0;
+  return;
+end
+
+L = 0;
+for m=1:ncases
+  if isempty(CPD.dps)
+    i = 1;
+  else
+    if usecell
+      dpvals = cat(1, pev{CPD.dps, m});
+    else
+      dpvals = pev(CPD.dps, m);
+    end
+    i = subv2ind(CPD.sizes(CPD.dps), dpvals(:)');
+  end
+  if usecell
+    y = self_ev{m};
+  else
+    y = self_ev(m);
+  end
+  if length(CPD.cps) == 0 
+    L = L + gaussian_prob(y, CPD.mean(:,i), CPD.cov(:,:,i), use_log);
+  else
+    if usecell
+      x = cat(1, pev{CPD.cps, m});
+    else
+      x = pev(CPD.cps, m);
+    end
+    L = L + gaussian_prob(y, CPD.mean(:,i) + CPD.weights(:,:,i)*x, CPD.cov(:,:,i), use_log);
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/maximize_params.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/maximize_params.m
new file mode 100644
index 00000000..1624cbf2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/maximize_params.m
@@ -0,0 +1,68 @@
+function CPD = maximize_params(CPD, temp)
+% MAXIMIZE_PARAMS Set the params of a CPD to their ML values (Gaussian)
+% CPD = maximize_params(CPD, temperature)
+%
+% Temperature is currently ignored.
+
+if ~adjustable_CPD(CPD), return; end
+
+
+if CPD.clamped_mean
+  cl_mean = CPD.mean;
+else
+  cl_mean = [];
+end
+
+if CPD.clamped_cov
+  cl_cov = CPD.cov;
+else
+  cl_cov = [];
+end
+
+if CPD.clamped_weights
+  cl_weights = CPD.weights;
+else
+  cl_weights = [];
+end
+
+[ssz psz Q] = size(CPD.weights);
+
+[ss cpsz dpsz] = size(CPD.weights); % ss = self size = ssz
+if cpsz > CPD.nsamples
+  fprintf('gaussian_CPD/maximize_params: warning: input dimension (%d) > nsamples (%d)\n', ...
+	  cpsz, CPD.nsamples);
+end
+
+prior =  repmat(CPD.cov_prior_weight*eye(ssz,ssz), [1 1 Q]);
+
+
+[CPD.mean, CPD.cov, CPD.weights] = ...
+    clg_Mstep(CPD.Wsum, CPD.WYsum, CPD.WYYsum, [], CPD.WXsum, CPD.WXXsum, CPD.WXYsum, ...
+	      'cov_type', CPD.cov_type, 'clamped_mean', cl_mean, ...
+	      'clamped_cov', cl_cov, 'clamped_weights', cl_weights, ...
+	      'tied_cov', CPD.tied_cov, ...
+	      'cov_prior', prior);
+
+if 0
+CPD.mean = reshape(CPD.mean, [ss dpsz]);
+CPD.cov = reshape(CPD.cov, [ss ss dpsz]);
+CPD.weights = reshape(CPD.weights, [ss cpsz dpsz]);
+end
+
+% Bug fix 11 May 2003 KPM
+% clg_Mstep collapses all discrete parents into one mega-node
+% but convert_to_CPT needs access to each parent separately
+sz = CPD.sizes;
+ss = sz(end);
+
+% Bug fix KPM 20 May 2003: 
+cpsz = sum(sz(CPD.cps));
+%if isempty(CPD.cps)
+%  cpsz = 0;
+%else
+%  cpsz = sz(CPD.cps);
+%end
+dpsz = sz(CPD.dps);
+CPD.mean = myreshape(CPD.mean, [ss dpsz]);
+CPD.cov = myreshape(CPD.cov, [ss ss dpsz]);
+CPD.weights = myreshape(CPD.weights, [ss cpsz dpsz]);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/maximize_params_debug.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/maximize_params_debug.m
new file mode 100644
index 00000000..a588756d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/maximize_params_debug.m
@@ -0,0 +1,189 @@
+function CPD = maximize_params(CPD, temp)
+% MAXIMIZE_PARAMS Set the params of a CPD to their ML values (Gaussian)
+% CPD = maximize_params(CPD, temperature)
+%
+% Temperature is currently ignored.
+
+if ~adjustable_CPD(CPD), return; end
+
+CPD1 = struct(new_maximize_params(CPD));
+CPD2 = struct(old_maximize_params(CPD));
+assert(approxeq(CPD1.mean, CPD2.mean))
+assert(approxeq(CPD1.cov, CPD2.cov))
+assert(approxeq(CPD1.weights, CPD2.weights))
+
+CPD = new_maximize_params(CPD);
+
+%%%%%%%
+function CPD = new_maximize_params(CPD)
+
+if CPD.clamped_mean
+  cl_mean = CPD.mean;
+else
+  cl_mean = [];
+end
+
+if CPD.clamped_cov
+  cl_cov = CPD.cov;
+else
+  cl_cov = [];
+end
+
+if CPD.clamped_weights
+  cl_weights = CPD.weights;
+else
+  cl_weights = [];
+end
+
+[ssz psz Q] = size(CPD.weights);
+
+prior =  repmat(CPD.cov_prior_weight*eye(ssz,ssz), [1 1 Q]);
+[CPD.mean, CPD.cov, CPD.weights] = ...
+    Mstep_clg('w', CPD.Wsum, 'YY', CPD.WYYsum, 'Y', CPD.WYsum, 'YTY', [], ...
+	      'XX', CPD.WXXsum, 'XY', CPD.WXYsum, 'X', CPD.WXsum, ...
+	      'cov_type', CPD.cov_type, 'clamped_mean', cl_mean, ...
+	      'clamped_cov', cl_cov, 'clamped_weights', cl_weights, ...
+	      'tied_cov', CPD.tied_cov, ...
+	      'cov_prior', prior);
+
+
+%%%%%%%%%%%
+
+function CPD = old_maximize_params(CPD)
+
+
+if ~adjustable_CPD(CPD), return; end
+
+%assert(approxeq(CPD.nsamples, sum(CPD.Wsum)));
+assert(~any(isnan(CPD.WXXsum)))
+assert(~any(isnan(CPD.WXYsum)))
+assert(~any(isnan(CPD.WYYsum)))
+
+[self_size cpsize dpsize] = size(CPD.weights);
+
+% Append 1s to the parents, and derive the corresponding cross products.
+% This is used when estimate the means and weights simultaneosuly,
+% and when estimatting Sigma.
+% Let x2 = [x 1]'
+XY = zeros(cpsize+1, self_size, dpsize); % XY(:,:,i) = sum_l w(l,i) x2(l) y(l)' 
+XX = zeros(cpsize+1, cpsize+1, dpsize); % XX(:,:,i) = sum_l w(l,i) x2(l) x2(l)' 
+YY = zeros(self_size, self_size, dpsize); % YY(:,:,i) = sum_l w(l,i) y(l) y(l)' 
+for i=1:dpsize
+  XY(:,:,i) = [CPD.WXYsum(:,:,i) % X*Y
+	       CPD.WYsum(:,i)']; % 1*Y
+  % [x  * [x' 1]  = [xx' x
+  %  1]              x'  1]
+  XX(:,:,i) = [CPD.WXXsum(:,:,i) CPD.WXsum(:,i);
+	       CPD.WXsum(:,i)'   CPD.Wsum(i)];
+  YY(:,:,i) = CPD.WYYsum(:,:,i);
+end
+
+w = CPD.Wsum(:);
+% Set any zeros to one before dividing
+% This is valid because w(i)=0 => WYsum(:,i)=0, etc
+w = w + (w==0);
+
+if CPD.clamped_mean
+  % Estimating B2 and then setting the last column (the mean) to the clamped mean is *not* equivalent
+  % to estimating B and then adding the clamped_mean to the last column.
+  if ~CPD.clamped_weights
+    B = zeros(self_size, cpsize, dpsize);
+    for i=1:dpsize
+      if det(CPD.WXXsum(:,:,i))==0
+	B(:,:,i) = 0;
+      else
+	% Eqn 9 in table 2 of TR
+	%B(:,:,i) = CPD.WXYsum(:,:,i)' * inv(CPD.WXXsum(:,:,i));
+	B(:,:,i) = (CPD.WXXsum(:,:,i) \ CPD.WXYsum(:,:,i))';
+      end
+    end
+    %CPD.weights = reshape(B, [self_size cpsize dpsize]);
+    CPD.weights = B;
+  end
+elseif CPD.clamped_weights % KPM 1/25/02
+  if ~CPD.clamped_mean % ML estimate is just sample mean of the residuals
+    for i=1:dpsize
+      CPD.mean(:,i) = (CPD.WYsum(:,i) - CPD.weights(:,:,i) * CPD.WXsum(:,i)) / w(i);
+    end
+  end
+else % nothing is clamped, so estimate mean and weights simultaneously
+  B2 = zeros(self_size, cpsize+1, dpsize);
+  for i=1:dpsize
+    if det(XX(:,:,i))==0  % fix by U. Sondhauss 6/27/99
+      B2(:,:,i)=0;          
+    else                    
+      % Eqn 9 in table 2 of TR
+      %B2(:,:,i) = XY(:,:,i)' * inv(XX(:,:,i));
+      B2(:,:,i) = (XX(:,:,i) \ XY(:,:,i))';
+    end                   
+    CPD.mean(:,i) = B2(:,cpsize+1,i);
+    CPD.weights(:,:,i) = B2(:,1:cpsize,i);
+  end
+end
+
+% Let B2 = [W mu]
+if cpsize>0
+  B2(:,1:cpsize,:) = reshape(CPD.weights, [self_size cpsize dpsize]);
+end
+B2(:,cpsize+1,:) = reshape(CPD.mean, [self_size dpsize]);
+
+% To avoid singular covariance matrices,
+% we use the regularization method suggested in "A Quasi-Bayesian approach to estimating
+% parameters for mixtures of normal distributions", Hamilton 91.
+% If the ML estimate is Sigma = M/N, the MAP estimate is (M+gamma*I) / (N+gamma),
+% where gamma >=0 is a smoothing parameter (equivalent sample size of I prior)
+
+gamma = CPD.cov_prior_weight;
+
+if ~CPD.clamped_cov
+  if CPD.cov_prior_entropic % eqn 12 of Brand AI/Stat 99
+    Z = 1-temp;
+    % When temp > 1, Z is negative, so we are dividing by a smaller
+    % number, ie. increasing the variance.
+  else
+    Z = 0;
+  end
+  if CPD.tied_cov
+    S = zeros(self_size, self_size);
+    % Eqn 2 from table 2 in TR
+    for i=1:dpsize
+      S = S + (YY(:,:,i) - B2(:,:,i)*XY(:,:,i));
+    end
+    %denom = CPD.nsamples + gamma + Z;
+    denom = CPD.nsamples +  Z;
+    S = (S + gamma*eye(self_size)) / denom;
+    if strcmp(CPD.cov_type, 'diag')
+      S = diag(diag(S));
+    end
+    CPD.cov = repmat(S, [1 1 dpsize]);
+  else 
+    for i=1:dpsize      
+      % Eqn 1 from table 2 in TR
+      S = YY(:,:,i) - B2(:,:,i)*XY(:,:,i);
+      %denom = w(i) + gamma + Z;
+      denom = w(i) + Z;
+      S = (S + gamma*eye(self_size)) / denom;
+      CPD.cov(:,:,i) = S;
+    end
+    if strcmp(CPD.cov_type, 'diag')
+      for i=1:dpsize      
+	CPD.cov(:,:,i) = diag(diag(CPD.cov(:,:,i)));
+      end
+    end
+  end
+end
+
+
+check_covars = 0;
+min_covar = 1e-5;
+if check_covars % prevent collapsing to a point
+  for i=1:dpsize
+    if min(svd(CPD.cov(:,:,i))) < min_covar
+      disp(['resetting singular covariance for node ' num2str(CPD.self)]);
+      CPD.cov(:,:,i) = CPD.init_cov(:,:,i);
+    end
+  end
+end
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CPD_to_linear_gaussian.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CPD_to_linear_gaussian.m
new file mode 100644
index 00000000..dfc0cccc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CPD_to_linear_gaussian.m
@@ -0,0 +1,19 @@
+function [mu, Sigma, W] = CPD_to_linear_gaussian(CPD, domain, ns, cnodes, evidence)
+
+ps = domain(1:end-1);
+dnodes = mysetdiff(1:length(ns), cnodes);
+dps = myintersect(ps, dnodes); % discrete parents
+
+if isempty(dps)
+  Q = 1;
+else
+  assert(~any(isemptycell(evidence(dps))));
+  dpvals = cat(1, evidence{dps});
+  Q = subv2ind(ns(dps), dpvals(:)');
+end
+
+mu = CPD.mean(:,Q);
+Sigma = CPD.cov(:,:,Q);
+W = CPD.weights(:,:,Q);
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CVS/Entries
new file mode 100644
index 00000000..afb40930
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CVS/Entries
@@ -0,0 +1,2 @@
+/CPD_to_linear_gaussian.m/1.1.1.1/Wed May 29 15:59:52 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CVS/Repository
new file mode 100644
index 00000000..8aa921a1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@gaussian_CPD/private
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/reset_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/reset_ess.m
new file mode 100644
index 00000000..d27105f0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/reset_ess.m
@@ -0,0 +1,11 @@
+function CPD = reset_ess(CPD)
+% RESET_ESS Reset the Expected Sufficient Statistics for a Gaussian CPD.
+% CPD = reset_ess(CPD)
+
+CPD.nsamples = 0;    
+CPD.Wsum = zeros(size(CPD.Wsum));
+CPD.WYsum = zeros(size(CPD.WYsum));
+CPD.WYYsum = zeros(size(CPD.WYYsum));
+CPD.WXsum = zeros(size(CPD.WXsum));
+CPD.WXXsum = zeros(size(CPD.WXXsum));
+CPD.WXYsum = zeros(size(CPD.WXYsum));
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/sample_node.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/sample_node.m
new file mode 100644
index 00000000..74875eeb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/sample_node.m
@@ -0,0 +1,22 @@
+function y = sample_node(CPD, pev)
+% SAMPLE_NODE Draw a random sample from P(Xi | x(pi_i), theta_i)  (gaussian)
+% y = sample_node(CPD, parent_evidence)
+%
+% pev{i} is the value of the i'th parent (if there are any parents)
+% y is the sampled value (a scalar or vector)
+
+if length(CPD.dps)==0
+  i = 1;
+else
+  dpvals = cat(1, pev{CPD.dps});
+  i = subv2ind(CPD.sizes(CPD.dps), dpvals(:)');
+end
+
+if length(CPD.cps) == 0 
+  y = gsamp(CPD.mean(:,i), CPD.cov(:,:,i), 1);
+else
+  pev = pev(:);
+  x = cat(1, pev{CPD.cps});
+  y = gsamp(CPD.mean(:,i) + CPD.weights(:,:,i)*x(:), CPD.cov(:,:,i), 1);
+end
+y = y(:);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/set_fields.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/set_fields.m
new file mode 100644
index 00000000..4c1aef22
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/set_fields.m
@@ -0,0 +1,43 @@
+function CPD = set_fields(CPD, varargin)
+% SET_PARAMS Set the parameters (fields) for a gaussian_CPD object
+% CPD = set_params(CPD, name/value pairs)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+%
+% mean       - mu(:,i) is the mean given Q=i
+% cov        - Sigma(:,:,i) is the covariance given Q=i 
+% weights    - W(:,:,i) is the regression matrix given Q=i 
+% cov_type   - if 'diag', Sigma(:,:,i) is diagonal 
+% tied_cov   - if 1, we constrain Sigma(:,:,i) to be the same for all i
+% clamp_mean - if 1, we do not adjust mu(:,i) during learning 
+% clamp_cov  - if 1, we do not adjust Sigma(:,:,i) during learning 
+% clamp_weights - if 1, we do not adjust W(:,:,i) during learning
+% clamp      - if 1, we do not adjust any params
+% cov_prior_weight - weight given to I prior for estimating Sigma
+% cov_prior_entropic - if 1, we also use an entropic prior for Sigma [0]
+%
+% e.g., CPD = set_params(CPD, 'mean', [0;0])
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'mean',        CPD.mean = args{i+1}; 
+   case 'cov',         CPD.cov = args{i+1}; 
+   case 'weights',     CPD.weights = args{i+1}; 
+   case 'cov_type',    CPD.cov_type = args{i+1}; 
+   %case 'tied_cov',    CPD.tied_cov = strcmp(args{i+1}, 'yes');
+   case 'tied_cov',    CPD.tied_cov = args{i+1};
+   case 'clamp_mean',  CPD.clamped_mean = args{i+1};
+   case 'clamp_cov',   CPD.clamped_cov = args{i+1};
+   case 'clamp_weights',  CPD.clamped_weights = args{i+1};
+   case 'clamp',  clamp = args{i+1};
+    CPD.clamped_mean = clamp;
+    CPD.clamped_cov = clamp;
+    CPD.clamped_weights = clamp;
+   case 'cov_prior_weight',  CPD.cov_prior_weight = args{i+1};
+   case 'cov_prior_entropic',  CPD.cov_prior_entropic = args{i+1};
+   otherwise,  
+    error(['invalid argument name ' args{i}]);
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/update_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/update_ess.m
new file mode 100644
index 00000000..3b58c02e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gaussian_CPD/update_ess.m
@@ -0,0 +1,88 @@
+function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+% UPDATE_ESS Update the Expected Sufficient Statistics of a Gaussian node
+% function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+
+%if nargin < 6
+%  hidden_bitv = zeros(1, max(fmarginal.domain));
+%  hidden_bitv(find(isempty(evidence)))=1;
+%end
+
+dom = fmarginal.domain;
+self = dom(end);
+ps = dom(1:end-1);
+cps = myintersect(ps, cnodes);
+dps = mysetdiff(ps, cps);
+
+CPD.nsamples = CPD.nsamples + 1;            
+[ss cpsz dpsz] = size(CPD.weights); % ss = self size
+[ss dpsz] = size(CPD.mean);
+
+% Let X be the cts parent (if any), Y be the cts child (self).
+
+if ~hidden_bitv(self) && ~any(hidden_bitv(cps)) && all(hidden_bitv(dps))
+  % Speedup for the common case that all cts nodes are observed, all discrete nodes are hidden
+  % Since X and Y are observed, SYY = 0, SXX = 0, SXY = 0
+  % Since discrete parents are hidden, we do not need to add evidence to w.
+  w = fmarginal.T(:);
+  CPD.Wsum = CPD.Wsum + w;
+  y = evidence{self};
+  Cyy = y*y';
+  if ~CPD.useC
+     WY = repmat(w(:)',ss,1); % WY(y,i) = w(i)
+     WYY = repmat(reshape(WY, [ss 1 dpsz]), [1 ss 1]); % WYY(y,y',i) = w(i)
+     %CPD.WYsum = CPD.WYsum +  WY .* repmat(y(:), 1, dpsz);
+     CPD.WYsum = CPD.WYsum +  y(:) * w(:)';
+     CPD.WYYsum = CPD.WYYsum + WYY  .* repmat(reshape(Cyy, [ss ss 1]), [1 1 dpsz]);
+  else
+     W = w(:)';
+     W2 = reshape(W, [1 1 dpsz]);
+     CPD.WYsum = CPD.WYsum +  rep_mult(W, y(:), size(CPD.WYsum)); 
+     CPD.WYYsum = CPD.WYYsum + rep_mult(W2, Cyy, size(CPD.WYYsum));
+  end
+  if cpsz > 0 % X exists
+    x = cat(1, evidence{cps}); x = x(:);
+    Cxx = x*x';
+    Cxy = x*y';
+    WX = repmat(w(:)',cpsz,1); % WX(x,i) = w(i)
+    WXX = repmat(reshape(WX, [cpsz 1 dpsz]), [1 cpsz 1]); % WXX(x,x',i) = w(i)
+    WXY = repmat(reshape(WX, [cpsz 1 dpsz]), [1 ss 1]); % WXY(x,y,i) = w(i)
+    if ~CPD.useC
+      CPD.WXsum = CPD.WXsum + WX .* repmat(x(:), 1, dpsz);
+      CPD.WXXsum = CPD.WXXsum + WXX .* repmat(reshape(Cxx, [cpsz cpsz 1]), [1 1 dpsz]);
+      CPD.WXYsum = CPD.WXYsum + WXY .* repmat(reshape(Cxy, [cpsz ss 1]), [1 1 dpsz]);
+    else
+      CPD.WXsum = CPD.WXsum + rep_mult(W, x(:), size(CPD.WXsum));
+      CPD.WXXsum = CPD.WXXsum + rep_mult(W2, Cxx, size(CPD.WXXsum));
+      CPD.WXYsum = CPD.WXYsum + rep_mult(W2, Cxy, size(CPD.WXYsum));
+    end
+  end
+  return;
+end
+
+% general (non-vectorized) case
+fullm = add_evidence_to_gmarginal(fmarginal, evidence, ns, cnodes); % slow!
+
+if dpsz == 1 % no discrete parents
+  w = 1;
+else
+  w = fullm.T(:);
+end
+
+CPD.Wsum = CPD.Wsum + w;
+xi = 1:cpsz;
+yi = (cpsz+1):(cpsz+ss);
+for i=1:dpsz
+  muY = fullm.mu(yi, i);
+  SYY = fullm.Sigma(yi, yi, i);
+  CPD.WYsum(:,i) = CPD.WYsum(:,i) + w(i)*muY;
+  CPD.WYYsum(:,:,i) = CPD.WYYsum(:,:,i) + w(i)*(SYY + muY*muY'); % E[X Y] = Cov[X,Y] + E[X] E[Y]
+  if cpsz > 0
+    muX = fullm.mu(xi, i);
+    SXX = fullm.Sigma(xi, xi, i);
+    SXY = fullm.Sigma(xi, yi, i);
+    CPD.WXsum(:,i) = CPD.WXsum(:,i) + w(i)*muX;
+    CPD.WXXsum(:,:,i) = CPD.WXXsum(:,:,i) + w(i)*(SXX + muX*muX');
+    CPD.WXYsum(:,:,i) = CPD.WXYsum(:,:,i) + w(i)*(SXY + muX*muY');
+  end
+end                
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Entries
new file mode 100644
index 00000000..47f0e262
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Entries
@@ -0,0 +1,8 @@
+/README/1.1.1.1/Wed May 29 15:59:52 2002//
+/adjustable_CPD.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/display.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/generic_CPD.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/learn_params.m/1.1.1.1/Thu Jun 10 01:53:20 2004//
+/log_prior.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/set_clamped.m/1.1.1.1/Wed May 29 15:59:52 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Repository
new file mode 100644
index 00000000..19ab61e0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@generic_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/BIC_score_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/BIC_score_CPD.m
new file mode 100644
index 00000000..a73d073b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/BIC_score_CPD.m
@@ -0,0 +1,26 @@
+function score = BIC_score_CPD(CPD, fam, data, ns, cnodes)
+% BIC_score_CPD Compute the BIC score of a generic CPD
+% score = BIC_score_CPD(CPD, fam, data, ns, cnodes)
+%
+% We assume this node has a maximize_params method
+
+ncases = size(data, 2);
+CPD = reset_ess(CPD);
+% make a fully observed joint distribution over the family
+fmarginal.domain = fam;
+fmarginal.T = 1;
+fmarginal.mu = [];
+fmarginal.Sigma = [];
+if ~iscell(data)
+  cases = num2cell(data);
+else
+  cases = data;
+end
+for m=1:ncases
+  CPD = update_ess(CPD, fmarginal, cases(:,m), ns, cnodes);
+end
+CPD = maximize_params(CPD);
+self = fam(end);
+ps = fam(1:end-1);
+L = log_prob_node(CPD, cases(self,:), cases(ps,:));
+score = L - 0.5*CPD.nparams*log(ncases);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CPD_to_dpots.m b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CPD_to_dpots.m
new file mode 100644
index 00000000..47daac88
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CPD_to_dpots.m
@@ -0,0 +1,16 @@
+function pots = CPD_to_dpots(CPD, domain, ns, cnodes, evidence)
+% CPD_TO_DPOTS Convert the CPD to several discrete potentials, for different instantiations (generic)
+% pots = CPD_to_dpots(CPD, domain, ns, cnodes, evidence)
+%
+% domain(:,i) is the domain of the i'th instantiation of CPD.
+% node_sizes(i) is the size of node i.
+% cnodes = all the cts nodes
+% evidence{i} is the evidence on the i'th node.
+%
+% This just calls CPD_to_dpot for each domain.
+    
+nCPDs = size(domain,2);
+pots = cell(1,nCPDs);
+for i=1:nCPDs
+  pots{i} = CPD_to_dpot(CPD, domain(:,i), ns, cnodes, evidence);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CVS/Entries
new file mode 100644
index 00000000..505b09aa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CVS/Entries
@@ -0,0 +1,3 @@
+/BIC_score_CPD.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/CPD_to_dpots.m/1.1.1.1/Wed May 29 15:59:52 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CVS/Repository
new file mode 100644
index 00000000..96b94fc8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@generic_CPD/Old
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/README b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/README
new file mode 100644
index 00000000..7a9b164b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/README
@@ -0,0 +1,2 @@
+A generic CPD implements general purpose functions like 'display',
+that subtypes can inherit.
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/adjustable_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/adjustable_CPD.m
new file mode 100644
index 00000000..78feea55
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/adjustable_CPD.m
@@ -0,0 +1,5 @@
+function p = adjustable_CPD(CPD)
+% ADJUSTABLE_CPD Does this CPD have any adjustable params? (generic)
+% p = adjustable_CPD(CPD)
+   
+p = ~CPD.clamped;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/display.m b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/display.m
new file mode 100644
index 00000000..001ab2c9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/display.m
@@ -0,0 +1,3 @@
+function display(CPD)
+
+disp(struct(CPD));
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/generic_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/generic_CPD.m
new file mode 100644
index 00000000..66a85e6a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/generic_CPD.m
@@ -0,0 +1,8 @@
+function CPD = generic_CPD(clamped)
+% GENERIC_CPD Virtual constructor for generic CPD
+% CPD = discrete_CPD(clamped)
+
+if nargin < 1, clamped = 0; end
+
+CPD.clamped = clamped;
+CPD = class(CPD, 'generic_CPD');
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/learn_params.m b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/learn_params.m
new file mode 100644
index 00000000..c36eb004
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/learn_params.m
@@ -0,0 +1,32 @@
+function CPD = learn_params(CPD, fam, data, ns, cnodes)
+% LEARN_PARAMS Compute the maximum likelihood estimate of the params of a generic CPD given complete data
+% CPD = learn_params(CPD, fam, data, ns, cnodes)
+%
+% data(i,m) is the value of node i in case m (can be cell array).
+% We assume this node has a maximize_params method.
+
+%error('no longer supported') % KPM 1 Feb 03
+
+if 1
+ncases = size(data, 2);
+CPD = reset_ess(CPD);
+% make a fully observed joint distribution over the family
+fmarginal.domain = fam;
+fmarginal.T = 1;
+fmarginal.mu = [];
+fmarginal.Sigma = [];
+if ~iscell(data)
+  cases = num2cell(data);
+else
+  cases = data;
+end
+hidden_bitv = zeros(1, max(fam));
+for m=1:ncases
+  % specify (as a bit vector) which elements in the family domain are hidden
+  hidden_bitv = zeros(1, max(fmarginal.domain));
+  ev = cases(:,m);
+  hidden_bitv(find(isempty(evidence)))=1;
+  CPD = update_ess(CPD, fmarginal, ev, ns, cnodes, hidden_bitv);
+end
+CPD = maximize_params(CPD);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/log_prior.m b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/log_prior.m
new file mode 100644
index 00000000..a73dcde0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/log_prior.m
@@ -0,0 +1,5 @@
+function L = log_prior(CPD)
+% LOG_PRIOR Return log P(theta) for a generic CPD  - we return 0
+% L = log_prior(CPD)
+
+L = 0;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/set_clamped.m b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/set_clamped.m
new file mode 100644
index 00000000..5ad68037
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@generic_CPD/set_clamped.m
@@ -0,0 +1,3 @@
+function CPD = set_clamped(CPD, bit)
+
+CPD.clamped = bit;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CPD_to_lambda_msg.m b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CPD_to_lambda_msg.m
new file mode 100644
index 00000000..c323e8e5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CPD_to_lambda_msg.m
@@ -0,0 +1,62 @@
+function lam_msg = CPD_to_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence)
+% CPD_TO_LAMBDA_MSG Compute lambda message (gmux)
+% lam_msg = compute_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence)
+% Pearl p183 eq 4.52
+
+% Let Y be this node, X1..Xn be the cts parents and M the discrete switch node.
+% e.g., for n=3, M=1
+%
+%  X1 X2 X3 M
+%   \
+%    \
+%      Y
+%
+% So the only case in which we send an informative message is if p=1=M.
+% To the other cts parents, we send the "know nothing" message.
+
+switch msg_type
+ case 'd',
+  error('gaussian_CPD can''t create discrete msgs')
+ case 'g',
+  cps = ps(CPD.cps);
+  cpsizes = CPD.sizes(CPD.cps);
+  self_size = CPD.sizes(end);
+  i = find_equiv_posns(p, cps); % p is n's i'th cts parent
+  psz = cpsizes(i);
+  dps = ps(CPD.dps);
+  M = evidence{dps};
+  if isempty(M)
+    error('gmux node must have observed discrete parent')
+  end
+  P = msg{n}.lambda.precision;
+  if all(P == 0) | (cps(M) ~= p) % if we know nothing, or are sending to a disconnected parent
+    lam_msg.precision = zeros(psz, psz);
+    lam_msg.info_state = zeros(psz, 1);
+    return;
+  end
+  % We are sending a message to the only effectively connected parent.
+  % There are no other incoming pi messages.
+  Bmu = CPD.mean(:,M);
+  BSigma = CPD.cov(:,:,M);
+  Bi = CPD.weights(:,:,M);
+  if (det(P) > 0) | isinf(P) 
+    if isinf(P) % Y is observed
+      Sigma_lambda = zeros(self_size, self_size); % infinite precision => 0 variance
+      mu_lambda = msg{n}.lambda.mu; % observed_value;
+    else
+      Sigma_lambda = inv(P);
+      mu_lambda = Sigma_lambda * msg{n}.lambda.info_state;
+    end
+    C = inv(Sigma_lambda + BSigma);
+    lam_msg.precision = Bi' * C * Bi;
+    lam_msg.info_state = Bi' * C * (mu_lambda - Bmu);
+  else
+    % method that uses matrix inversion lemma
+    A = inv(P + inv(BSigma));
+    C = P - P*A*P;
+    lam_msg.precision = Bi' * C * Bi;
+    D = eye(self_size) - P*A;
+    z = msg{n}.lambda.info_state;
+    lam_msg.info_state = Bi' * (D*z - D*P*Bmu);
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CPD_to_pi.m b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CPD_to_pi.m
new file mode 100644
index 00000000..63b5726b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CPD_to_pi.m
@@ -0,0 +1,18 @@
+function pi = CPD_to_pi(CPD, msg_type, n, ps, msg, evidence)
+% CPD_TO_PI Compute the pi vector (gaussian)
+% function pi = CPD_to_pi(CPD, msg_type, n, ps, msg, evidence)
+
+switch msg_type
+ case 'd',
+  error('gaussian_CPD can''t create discrete msgs')
+ case 'g',
+  dps = ps(CPD.dps);
+  k = evidence{dps};
+  if isempty(k)
+    error('gmux node must have observed discrete parent')
+  end
+  m = msg{n}.pi_from_parent{k}; 
+  B = CPD.weights(:,:,k);
+  pi.mu = CPD.mean(:,k) + B * m.mu;
+  pi.Sigma = CPD.cov(:,:,k) + B * m.Sigma * B';
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Entries
new file mode 100644
index 00000000..2a911068
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Entries
@@ -0,0 +1,7 @@
+/CPD_to_lambda_msg.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/CPD_to_pi.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/convert_to_pot.m/1.1.1.1/Wed May 29 15:59:52 2002//
+/display.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/gmux_CPD.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Repository
new file mode 100644
index 00000000..8d764710
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@gmux_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/CVS/Entries
new file mode 100644
index 00000000..f5a137ab
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/CVS/Entries
@@ -0,0 +1,2 @@
+/gmux_CPD.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/CVS/Repository
new file mode 100644
index 00000000..20395ac5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@gmux_CPD/Old
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/gmux_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/gmux_CPD.m
new file mode 100644
index 00000000..5c9507cf
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/Old/gmux_CPD.m
@@ -0,0 +1,92 @@
+function CPD = gmux_CPD(bnet, self, varargin)
+% GMUX_CPD Make a Gaussian multiplexer node
+%
+% CPD = gmux_CPD(bnet, node, ...) is used similarly to gaussian_CPD,
+% except we assume there is exactly one discrete parent (call it M)
+% which is used to select which cts parent to pass through to the output.
+% i.e., we define P(Y=y|M=m, X1, ..., XK) = N(y | W*x(m) + mu, Sigma)
+% where Y represents this node, and the Xi's are the cts parents.
+% All the Xi must have the same size, and the num values for M must be K.
+%
+% Currently the params for this kind of CPD cannot be learned.
+%
+% Optional arguments [ default in brackets ]
+%
+% mean       - mu  [zeros(Y,1)]
+% cov        - Sigma [eye(Y,Y)]
+% weights    - W [ randn(Y,X) ]
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  clamp = 0;
+  CPD = class(CPD, 'gmux_CPD', generic_CPD(clamp));
+  return;
+elseif isa(bnet, 'gmux_CPD')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+CPD = init_fields;
+ 
+CPD = class(CPD, 'gmux_CPD', generic_CPD(1));
+
+ns = bnet.node_sizes;
+ps = parents(bnet.dag, self);
+dps = myintersect(ps, bnet.dnodes);
+cps = myintersect(ps, bnet.cnodes);
+fam_sz = ns([ps self]);
+
+CPD.self = self;
+CPD.sizes = fam_sz;
+
+% Figure out which (if any) of the parents are discrete, and which cts, and how big they are
+% dps = discrete parents, cps = cts parents
+CPD.cps = find_equiv_posns(cps, ps); % cts parent index
+CPD.dps = find_equiv_posns(dps, ps);
+if length(CPD.dps) ~= 1
+  error('gmux must have exactly 1 discrete parent')
+end
+ss = fam_sz(end);
+cpsz = fam_sz(CPD.cps(1)); % in gaussian_CPD, cpsz = sum(fam_sz(CPD.cps))
+if ~all(fam_sz(CPD.cps) == cpsz)
+  error('all cts parents must have same size')
+end
+dpsz = fam_sz(CPD.dps);
+if dpsz ~= length(cps)
+  error(['the arity of the mux node is ' num2str(dpsz) ...
+	 ' but there are ' num2str(length(cps)) ' cts parents']);
+end
+
+% set default params
+CPD.mean = zeros(ss, 1);
+CPD.cov = eye(ss);
+CPD.weights = randn(ss, cpsz);
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'mean',        CPD.mean = args{i+1}; 
+   case 'cov',         CPD.cov = args{i+1}; 
+   case 'weights',    CPD.weights = args{i+1}; 
+   otherwise,  
+    error(['invalid argument name ' args{i}]);
+  end
+end
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.self = [];
+CPD.sizes = [];
+CPD.cps = [];
+CPD.dps = [];
+CPD.mean = [];
+CPD.cov = [];
+CPD.weights = [];
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/convert_to_pot.m b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/convert_to_pot.m
new file mode 100644
index 00000000..bf8c29c4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/convert_to_pot.m
@@ -0,0 +1,37 @@
+function pot = convert_to_pot(CPD, pot_type, domain, evidence)
+% CONVERT_TO_POT Convert a gmux CPD to a Gaussian potential
+% pot = convert_to_pot(CPD, pot_type, domain, evidence)
+  
+switch pot_type
+ case {'d', 'u', 'cg', 'scg'},
+  error(['can''t convert gmux to potential of type ' pot_type])
+
+ case {'c','g'},
+  % We create a large weight matrix with zeros in all blocks corresponding
+  % to the non-chosen parents, since they are effectively disconnected.
+  % The chosen parent is determined by the value, m,  of the discrete parent.
+  % Thus the potential is as large as the whole family.
+  ps = domain(1:end-1);
+  dps = ps(CPD.dps); % CPD.dps is an index, not a node number (because of param tying)
+  cps = ps(CPD.cps);
+  m = evidence{dps};
+  if isempty(m)
+    error('gmux node must have observed discrete parent')
+  end
+  bs = CPD.sizes(CPD.cps);
+  b = block(m, bs);
+  sum_cpsz = sum(CPD.sizes(CPD.cps));
+  selfsz = CPD.sizes(end);
+  W = zeros(selfsz, sum_cpsz);
+  W(:,b) = CPD.weights(:,:,m);
+
+  ns = zeros(1, max(domain));
+  ns(domain) = CPD.sizes;
+  self = domain(end);
+  cdom = [cps(:)' self];
+  pot = linear_gaussian_to_cpot(CPD.mean(:,m), CPD.cov(:,:,m), W, domain, ns, cdom, evidence);
+  
+ otherwise,
+  error(['unrecognized pot_type' pot_type])
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/display.m b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/display.m
new file mode 100644
index 00000000..4b04168c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/display.m
@@ -0,0 +1,4 @@
+function display(CPD)
+
+disp('gmux_CPD object');
+disp(struct(CPD));
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/gmux_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/gmux_CPD.m
new file mode 100644
index 00000000..4cef195c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/gmux_CPD.m
@@ -0,0 +1,95 @@
+function CPD = gmux_CPD(bnet, self, varargin)
+% GMUX_CPD Make a Gaussian multiplexer node
+%
+% CPD = gmux_CPD(bnet, node, ...) is used similarly to gaussian_CPD,
+% except we assume there is exactly one discrete parent (call it M)
+% which is used to select which cts parent to pass through to the output.
+% i.e., we define P(Y=y|M=m, X1, ..., XK) = N(y | W(m)*x(m) + mu(m), Sigma(m))
+% where Y represents this node, and the Xi's are the cts parents.
+% All the Xi must have the same size, and the num values for M must be K.
+%
+% Currently the params for this kind of CPD cannot be learned.
+%
+% Optional arguments [ default in brackets ]
+%
+% mean       - mu(:,i) is the mean given M=i [ zeros(Y,K) ]
+% cov        - Sigma(:,:,i) is the covariance given M=i [ repmat(1*eye(Y,Y), [1 1 K]) ]
+% weights    - W(:,:,i) is the regression matrix given M=i [ randn(Y,X,K) ]
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  clamp = 0;
+  CPD = class(CPD, 'gmux_CPD', generic_CPD(clamp));
+  return;
+elseif isa(bnet, 'gmux_CPD')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+CPD = init_fields;
+ 
+CPD = class(CPD, 'gmux_CPD', generic_CPD(1));
+
+ns = bnet.node_sizes;
+ps = parents(bnet.dag, self);
+dps = myintersect(ps, bnet.dnodes);
+cps = myintersect(ps, bnet.cnodes);
+fam_sz = ns([ps self]);
+
+CPD.self = self;
+CPD.sizes = fam_sz;
+
+% Figure out which (if any) of the parents are discrete, and which cts, and how big they are
+% dps = discrete parents, cps = cts parents
+CPD.cps = find_equiv_posns(cps, ps); % cts parent index
+CPD.dps = find_equiv_posns(dps, ps);
+if length(CPD.dps) ~= 1
+  error('gmux must have exactly 1 discrete parent')
+end
+ss = fam_sz(end);
+cpsz = fam_sz(CPD.cps(1)); % in gaussian_CPD, cpsz = sum(fam_sz(CPD.cps))
+if ~all(fam_sz(CPD.cps) == cpsz)
+  error('all cts parents must have same size')
+end
+dpsz = fam_sz(CPD.dps);
+if dpsz ~= length(cps)
+  error(['the arity of the mux node is ' num2str(dpsz) ...
+	 ' but there are ' num2str(length(cps)) ' cts parents']);
+end
+
+% set default params
+%CPD.mean = zeros(ss, 1);
+%CPD.cov = eye(ss);
+%CPD.weights = randn(ss, cpsz);
+CPD.mean = zeros(ss, dpsz);
+CPD.cov = 1*repmat(eye(ss), [1 1 dpsz]);    
+CPD.weights = randn(ss, cpsz, dpsz);
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'mean',        CPD.mean = args{i+1}; 
+   case 'cov',         CPD.cov = args{i+1}; 
+   case 'weights',    CPD.weights = args{i+1}; 
+   otherwise,  
+    error(['invalid argument name ' args{i}]);
+  end
+end
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.self = [];
+CPD.sizes = [];
+CPD.cps = [];
+CPD.dps = [];
+CPD.mean = [];
+CPD.cov = [];
+CPD.weights = [];
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/sample_node.m b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/sample_node.m
new file mode 100644
index 00000000..53842a5d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@gmux_CPD/sample_node.m
@@ -0,0 +1,10 @@
+function y = sample_node(CPD, pev)
+% SAMPLE_NODE Draw a random sample from P(Xi | x(pi_i), theta_i)  (gmux)
+% y = sample_node(CPD, parent_evidence)
+%
+% parent_ev{i} is the value of the i'th parent
+
+dpval = pev{CPD.dps};
+x = pev{CPD.cps(dpval)};
+y = gsamp(CPD.mean(:,dpval) + CPD.weights(:,:,dpval)*x(:), CPD.cov(:,:,dpval), 1);
+y = y(:);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CPD_to_CPT.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CPD_to_CPT.m
new file mode 100644
index 00000000..1942f60f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CPD_to_CPT.m
@@ -0,0 +1,35 @@
+function CPT = CPD_to_CPT(CPD)
+% Compute the big CPT for an HHMM Q node (including F parents)
+% by combining internal transprob and startprob
+% function CPT = CPD_to_CPT(CPD)
+
+Qsz = CPD.Qsz;
+
+if ~isempty(CPD.Fbelow_ndx)
+  if ~isempty(CPD.Fself_ndx) % general case
+    error('not implemented')
+  else % no F from self, hence no startprob (top level)
+    nps = length(CPD.dom_sz)-1; % num parents
+    CPT = 0*myones(CPD.dom_sz);
+    % when Fself=1, the CPT(i,j) = delta(i,j) for all k
+    for k=1:prod(CPD.Qpsizes)
+      Qps_vals = ind2subv(CPD.Qpsizes, k);
+      ndx = mk_multi_index(nps+1, [CPD.Fbelow_ndx CPD.Qps_ndx], [1 Qps_vals]);
+      CPT(ndx{:}) = eye(Qsz); % CPT(:,2,k,:) or CPT(:,k,2,:) etc
+    end
+    ndx = mk_multi_index(nps+1, CPD.Fbelow_ndx, 2);
+    CPT(ndx{:}) = CPD.transprob; % we assume transprob is in topo order
+  end
+else % no F signal from below
+  if ~isempty(CPD.Fself_ndx) % bottom level
+    nps = length(CPD.dom_sz)-1; % num parents
+    CPT = 0*myones(CPD.dom_sz);
+    ndx = mk_multi_index(nps+1, CPD.Fself_ndx, 1);
+    CPT(ndx{:}) = CPD.transprob;
+    ndx = mk_multi_index(nps+1, CPD.Fself_ndx, 2);
+    CPT(ndx{:}) = CPD.startprob;
+  else % no F from self
+    error('An hhmmQ node without any F parents is just a tabular_CPD')
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CVS/Entries
new file mode 100644
index 00000000..5e60dca6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CVS/Entries
@@ -0,0 +1,6 @@
+/CPD_to_CPT.m/1.1.1.1/Tue Sep 24 12:46:46 2002//
+/hhmm2Q_CPD.m/1.1.1.1/Tue Sep 24 22:34:40 2002//
+/maximize_params.m/1.1.1.1/Tue Sep 24 22:44:36 2002//
+/reset_ess.m/1.1.1.1/Tue Sep 24 22:36:16 2002//
+/update_ess.m/1.1.1.1/Tue Sep 24 22:43:30 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CVS/Repository
new file mode 100644
index 00000000..f66442c4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@hhmm2Q_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/hhmm2Q_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/hhmm2Q_CPD.m
new file mode 100644
index 00000000..c1a0cc20
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/hhmm2Q_CPD.m
@@ -0,0 +1,65 @@
+function CPD = hhmm2Q_CPD(bnet, self, varargin)
+% HHMMQ_CPD Make the CPD for a Q node in a 2 level hierarchical HMM
+% CPD = hhmmQ_CPD(bnet, self, ...)
+%
+%  Fself(t-1)   Qps
+%           \    |
+%            \   v
+%  Qold(t-1) ->  Q(t)
+%            /
+%           /
+%  Fbelow(t-1) 
+%
+%
+% optional args [defaults]
+%
+% Fself - node number <= ss
+% Fbelow  - node number  <= ss
+% Qps - node numbers (all <= 2*ss) - uses 2TBN indexing
+% transprob - CPT for when Fbelow=2 and Fself=1
+% startprob - CPT for when Fbelow=2 and Fself=2
+% If Fbelow=1, we cannot change state.
+
+ss = bnet.nnodes_per_slice;
+ns = bnet.node_sizes(:);
+
+% set default arguments
+Fself = [];
+Fbelow = [];
+Qps = [];
+startprob = [];
+transprob = [];
+
+for i=1:2:length(varargin)
+  switch varargin{i},
+   case 'Fself', Fself = varargin{i+1};
+   case 'Fbelow', Fbelow = varargin{i+1};
+   case 'Qps', Qps = varargin{i+1};
+   case 'transprob', transprob = varargin{i+1}; 
+   case 'startprob',  startprob = varargin{i+1}; 
+  end
+end
+
+ps = parents(bnet.dag, self);
+old_self = self-ss;
+ndsz = ns(:)';
+CPD.dom_sz = [ndsz(ps) ns(self)];
+CPD.Fself_ndx = find_equiv_posns(Fself, ps);
+CPD.Fbelow_ndx = find_equiv_posns(Fbelow, ps);
+Qps = mysetdiff(ps, [Fself Fbelow old_self]);
+CPD.Qps_ndx = find_equiv_posns(Qps, ps);
+CPD.old_self_ndx = find_equiv_posns(old_self, ps);
+
+Qps = ps(CPD.Qps_ndx);
+CPD.Qsz = ns(self);
+CPD.Qpsizes = ns(Qps);
+
+CPD.transprob = transprob;
+CPD.startprob = startprob;
+CPD.start_counts = [];
+CPD.trans_counts = [];
+
+CPD = class(CPD, 'hhmm2Q_CPD', discrete_CPD(0, CPD.dom_sz));
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/maximize_params.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/maximize_params.m
new file mode 100644
index 00000000..9fe4d0ac
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/maximize_params.m
@@ -0,0 +1,10 @@
+function CPD = maximize_params(CPD, temp)
+% MAXIMIZE_PARAMS Set the params of a hhmmQ node to their ML/MAP values.
+% CPD = maximize_params(CPD, temperature)
+
+if sum(CPD.start_counts(:)) > 0
+  CPD.startprob = mk_stochastic(CPD.start_counts);
+end
+if sum(CPD.trans_counts(:)) > 0
+  CPD.transprob = mk_stochastic(CPD.trans_counts);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/reset_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/reset_ess.m
new file mode 100644
index 00000000..8204c167
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/reset_ess.m
@@ -0,0 +1,12 @@
+function CPD = reset_ess(CPD)
+% RESET_ESS Reset the Expected Sufficient Statistics of a hhmm2 Q node.
+% CPD = reset_ess(CPD)
+
+domsz = CPD.dom_sz;
+domsz(CPD.Fself_ndx) = 1;
+domsz(CPD.Fbelow_ndx) = 1;
+Qdom_sz = domsz;
+Qdom_sz(Qdom_sz==1)=[]; % get rid of dimensions of size 1
+
+CPD.start_counts = zeros(Qdom_sz);
+CPD.trans_counts = zeros(Qdom_sz);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/update_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/update_ess.m
new file mode 100644
index 00000000..1a15d26c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmm2Q_CPD/update_ess.m
@@ -0,0 +1,26 @@
+function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+
+marg = add_ev_to_dmarginal(fmarginal, evidence,  ns);
+
+nps = length(CPD.dom_sz)-1; % num parents
+
+if ~isempty(CPD.Fbelow_ndx)
+  if ~isempty(CPD.Fself_ndx) % general case
+    ndx = mk_multi_index(nps+1, [CPD.Fbelow_ndx CPD.Fself_ndx], [2 1]);
+    CPD.trans_counts = CPD.trans_counts + squeeze(marg.T(ndx{:}));
+    ndx = mk_multi_index(nps+1, [CPD.Fbelow_ndx CPD.Fself_ndx], [2 2]);
+    CPD.start_counts = CPD.start_counts + squeeze(marg.T(ndx{:}));
+  else % no F from self, hence no startprob (top level)
+    ndx = mk_multi_index(nps+1, CPD.Fbelow_ndx, 2);
+    CPD.trans_counts = CPD.trans_counts + squeeze(marg.T(ndx{:}));
+  end
+else % no F signal from below
+  if ~isempty(CPD.Fself_ndx) % self F (bottom level)
+    ndx = mk_multi_index(nps+1, CPD.Fself_ndx, 1);
+    CPD.trans_counts = CPD.trans_counts + squeeze(marg.T(ndx{:}));
+    ndx = mk_multi_index(nps+1, CPD.Fself_ndx, 2);
+    CPD.start_counts = CPD.start_counts + squeeze(marg.T(ndx{:}));
+  else % no F from self or below
+    error('no F signal')
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/CVS/Entries
new file mode 100644
index 00000000..3e0cc360
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/CVS/Entries
@@ -0,0 +1,7 @@
+/hhmmF_CPD.m/1.1.1.1/Mon Jun 24 23:38:24 2002//
+/log_prior.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/maximize_params.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/reset_ess.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/update_CPT.m/1.1.1.1/Mon Jun 24 22:45:04 2002//
+/update_ess.m/1.1.1.1/Mon Jun 24 23:54:30 2002//
+D/Old////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/CVS/Repository
new file mode 100644
index 00000000..7c96bc38
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@hhmmF_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/CVS/Entries
new file mode 100644
index 00000000..3ab747df
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/CVS/Entries
@@ -0,0 +1,7 @@
+/hhmmF_CPD.m/1.1.1.1/Mon Jun 24 22:35:06 2002//
+/log_prior.m/1.1.1.1/Mon Jun 24 22:35:06 2002//
+/maximize_params.m/1.1.1.1/Mon Jun 24 22:35:06 2002//
+/reset_ess.m/1.1.1.1/Mon Jun 24 22:35:06 2002//
+/update_CPT.m/1.1.1.1/Mon Jun 24 22:35:06 2002//
+/update_ess.m/1.1.1.1/Mon Jun 24 22:35:06 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/CVS/Repository
new file mode 100644
index 00000000..8981a516
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@hhmmF_CPD/Old
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/hhmmF_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/hhmmF_CPD.m
new file mode 100644
index 00000000..4fdd9bc9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/hhmmF_CPD.m
@@ -0,0 +1,76 @@
+function CPD = hhmmF_CPD(bnet, self, Qnodes, d, D, varargin)
+% HHMMF_CPD Make the CPD for an F node at depth D of a D-level hierarchical HMM
+% CPD = hhmmF_CPD(bnet, self, Qnodes, d, D, ...)
+%
+%    Q(d-1)
+%          \
+%           \
+%           F(d)
+%         /   |
+%        /    |
+%    Q(d)  F(d+1)
+%
+% We assume nodes are ordered (numbered) as follows:
+% Q(1), ... Q(d), F(d+1), F(d)
+%
+% F(d)=2 means level d has finished. The prob this happens depends on Q(d)
+% and optionally on Q(d-1), Q(d=1), ..., Q(1).
+% Also, level d can only finish if the level below has finished
+% (hence the F(d+1) -> F(d) arc).
+%
+% If d=D, there is no F(d+1), so F(d) is just a regular tabular_CPD.
+% If all models always finish in the same state (e.g., their last),
+% we don't need to condition on the state of parent models (Q(d-1), ...)
+%
+% optional args [defaults]
+%
+% termprob - termprob(k,i,2) = prob finishing given Q(d)=i and Q(1:d-1)=k [ finish in last state ]
+%
+% hhmmF_CPD is a subclass of tabular_CPD so we inherit inference methods like CPD_to_pot, etc.
+%
+% We create an isolated tabular_CPD with no F parent to learn termprob
+% so we can avail of e.g., entropic or Dirichlet priors.
+%
+% For details, see "Linear-time inference in hierarchical HMMs", Murphy and Paskin, NIPS'01.
+
+
+ps = parents(bnet.dag, self);
+Qps = myintersect(ps, Qnodes);
+F = mysetdiff(ps, Qps);
+CPD.Q = Qps(end); % Q(d)
+assert(CPD.Q == Qnodes(d));
+CPD.Qps = Qps(1:end-1); % all Q parents except Q(d), i.e., calling context
+
+ns = bnet.node_sizes(:);
+CPD.Qsizes = ns(Qnodes);
+CPD.d = d;
+CPD.D = D;
+
+Qsz = ns(CPD.Q);
+Qpsz = prod(ns(CPD.Qps));
+
+% set default arguments
+p = 0.9;
+%termprob(k,i,t) Might terminate if i=Qsz; will not terminate if i<Qsz
+termprob = zeros(Qpsz, Qsz, 2);
+termprob(:, Qsz, 2) = p; 
+termprob(:, Qsz, 1) = 1-p; 
+termprob(:, 1:(Qsz-1), 1) = 1; 
+    
+for i=1:2:length(varargin)
+  switch varargin{i},
+   case 'termprob', termprob = varargin{i+1}; 
+   otherwise, error(['unrecognized argument ' varargin{i}])
+  end
+end
+
+ps = [CPD.Qps CPD.Q];
+% ns(self) = 2 since this is an F node
+CPD.sub_CPD_term = mk_isolated_tabular_CPD(ps, ns([ps self]), {'CPT', termprob});
+S = struct(CPD.sub_CPD_term);
+CPD.termprob = S.CPT;
+
+CPD = class(CPD, 'hhmmF_CPD', tabular_CPD(bnet, self));
+
+CPD = update_CPT(CPD);
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/log_prior.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/log_prior.m
new file mode 100644
index 00000000..7561205d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/log_prior.m
@@ -0,0 +1,5 @@
+function L = log_prior(CPD)
+% LOG_PRIOR Return log P(theta) for a hhmm F CPD 
+% L = log_prior(CPD)
+
+L = log_prior(CPD.sub_CPD_term);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/maximize_params.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/maximize_params.m
new file mode 100644
index 00000000..16e51ddc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/maximize_params.m
@@ -0,0 +1,9 @@
+function CPD = maximize_params(CPD, temp)
+% MAXIMIZE_PARAMS Set the params of a hhmmF node to their ML/MAP values.
+% CPD = maximize_params(CPD, temperature)
+
+CPD.sub_CPD_term = maximize_params(CPD.sub_CPD_term, temp);
+S = struct(CPD.sub_CPD_term);
+CPD.termprob = S.CPT;
+
+CPD = update_CPT(CPD);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/reset_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/reset_ess.m
new file mode 100644
index 00000000..f4428937
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/reset_ess.m
@@ -0,0 +1,5 @@
+function CPD = reset_ess(CPD)
+% RESET_ESS Reset the Expected Sufficient Statistics of a hhmm F node.
+% CPD = reset_ess(CPD)
+
+CPD.sub_CPD_term = reset_ess(CPD.sub_CPD_term);   
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/update_CPT.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/update_CPT.m
new file mode 100644
index 00000000..4ce14d9f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/update_CPT.m
@@ -0,0 +1,13 @@
+function CPD = update_CPT(CPD)
+% Compute the big CPT for an HHMM F node given internal termprob
+% function CPD = update_CPT(CPD)
+
+Qsz = CPD.Qsizes(CPD.Q);
+Qpsz = prod(CPD.Qsizes(CPD.Qps));
+
+% P(Q(1:d-1), Q(d), F(d+1), F(d))
+CPT = zeros(Qpsz, Qsz, 2, 2);
+CPT(:,:,1,1) = 1; % if F(d+1)=1, then F(d)=1
+CPT(:,:,2,:) = CPD.termprob;
+
+CPD = set_fields(CPD, 'CPT', CPT);          
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/update_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/update_ess.m
new file mode 100644
index 00000000..18f7057e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/Old/update_ess.m
@@ -0,0 +1,61 @@
+function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+% UPDATE_ESS Update the Expected Sufficient Statistics of a hhmmF node.
+% function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+
+% Figure out the node numbers associated with each parent
+% so we extract evidence from the right place
+dom = fmarginal.domain; % Q(1) .. Q(d) F(d+1) F(d)
+Qps = fmarginal.domain(1:end-2);
+Q = Qps(end);
+Qps = Qps(1:end-1);
+
+Qsz = CPD.Qsizes(CPD.Q);
+Qpsz = prod(CPD.Qsizes(CPD.Qps)); % may be 1
+
+% We assume the F node are always hidden, but allow some of the Q nodes
+% to be observed. We do case analysis for speed.
+%We only extract prob from fmarginal.T when F(d+1)=2 i.e., model below has finished.
+% wrong -> % We sum over the possibilities that F(d+1) = 1 or 2
+
+obs_self = ~hidden_bitv(Q);
+if obs_self
+  self_val = evidence{Q};
+end
+
+if isempty(Qps) % independent of parent context
+  counts = zeros(Qsz, 2);
+  %fmarginal.T(Q(d), F(d+1), F(d))
+  if obs_self
+    marg = myreshape(fmarginal.T, [1 2 2]);
+    counts(self_val,:) = marg(1,2,:);
+    %counts(self_val,:) = marg(1,1,:) + marg(1,2,:);
+  else
+    marg = myreshape(fmarginal.T, [Qsz 2 2]);
+    counts = squeeze(marg(:,2,:));
+    %counts = squeeze(marg(:,2,:)) + squeeze(marg(:,1,:));
+  end
+else
+  counts = zeros(Qpsz, Qsz, 2);
+  %fmarginal.T(Q(1:d-1), Q(d), F(d+1), F(d))
+  obs_Qps = ~any(hidden_bitv(Qps));  % we assume that all or none of the Q  parents are observed
+  if obs_Qps
+    Qps_val = subv2ind(Qpsz, cat(1, evidence{Qps}));
+  end
+  if obs_self & obs_Qps
+    marg = myreshape(fmarginal.T, [1 1 2 2]);
+    counts(Qps_val, self_val, :) = squeeze(marg(1,1,2,:));
+    %counts(Qps_val, self_val, :) = squeeze(marg(1,1,2,:)) + squeeze(marg(1,1,1,:));
+  elseif ~obs_self & obs_Qps
+    marg = myreshape(fmarginal.T, [1 Qsz 2 2]);
+    counts(Qps_val, :, :) = squeeze(marg(1,:,2,:));
+    %counts(Qps_val, :, :) = squeeze(marg(1,:,2,:)) + squeeze(marg(1,:,1,:));
+  elseif obs_self & ~obs_Qps
+    error('not yet implemented')
+  else
+    marg = myreshape(fmarginal.T, [Qpsz Qsz 2 2]);
+    counts(:, :, :) = squeeze(marg(:,:,2,:));
+    %counts(:, :, :) = squeeze(marg(:,:,2,:)) + squeeze(marg(:,:,1,:));
+  end    
+end
+
+CPD.sub_CPD_term = update_ess_simple(CPD.sub_CPD_term, counts);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/hhmmF_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/hhmmF_CPD.m
new file mode 100644
index 00000000..0c15580e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/hhmmF_CPD.m
@@ -0,0 +1,73 @@
+function CPD = hhmmF_CPD(bnet, self, Qself, Fbelow, varargin)
+% HHMMF_CPD Make the CPD for an F node in a hierarchical HMM
+% CPD = hhmmF_CPD(bnet, self, Qself,  Fbelow, ...)
+%
+%        Qps
+%          \
+%           \
+%           Fself
+%         /   |
+%        /    |
+%       Qself Fbelow
+%
+% We assume nodes are ordered (numbered) as follows: Qps, Q, Fbelow, F
+% All nodes numbers should be from slice 1.
+%
+% If Fbelow if missing, this becomes a regular tabular_CPD.
+% Qps may be omitted.
+%
+% optional args [defaults]
+% 
+% Qps - node numbers.
+% termprob - termprob(k,i,2) = prob finishing given Q(d)=i and Q(1:d-1)=k [ finish in last state wp 0.9]
+%
+% hhmmF_CPD is a subclass of tabular_CPD so we inherit inference methods like CPD_to_pot, etc.
+%
+% We create an isolated tabular_CPD with no F parent to learn termprob
+% so we can avail of e.g., entropic or Dirichlet priors.
+%
+% For details, see "Linear-time inference in hierarchical HMMs", Murphy and Paskin, NIPS'01.
+
+
+
+Qps = [];
+% get parents
+for i=1:2:length(varargin)
+  switch varargin{i},
+   case 'Qps', Qps = varargin{i+1}; 
+  end
+end
+
+ns = bnet.node_sizes(:);
+Qsz = ns(Qself);
+Qpsz = prod(ns(Qps));
+CPD.Qsz = Qsz;
+CPD.Qpsz = Qpsz;
+
+ps = parents(bnet.dag, self);
+CPD.Fbelow_ndx = find_equiv_posns(Fbelow, ps);
+CPD.Qps_ndx = find_equiv_posns(Qps, ps);
+CPD.Qself_ndx = find_equiv_posns(Qself, ps);
+
+% set default arguments
+p = 0.9;
+%termprob(k,i,t) Might terminate if i=Qsz; will not terminate if i<Qsz
+termprob = zeros(Qpsz, Qsz, 2);
+termprob(:, Qsz, 2) = p; 
+termprob(:, Qsz, 1) = 1-p; 
+termprob(:, 1:(Qsz-1), 1) = 1; 
+    
+for i=1:2:length(varargin)
+  switch varargin{i},
+   case 'termprob', termprob = varargin{i+1}; 
+  end
+end
+
+CPD.sub_CPD_term = mk_isolated_tabular_CPD([Qpsz Qsz 2], {'CPT', termprob});
+S = struct(CPD.sub_CPD_term);
+CPD.termprob = S.CPT;
+
+CPD = class(CPD, 'hhmmF_CPD', tabular_CPD(bnet, self));
+
+CPD = update_CPT(CPD);
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/log_prior.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/log_prior.m
new file mode 100644
index 00000000..7561205d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/log_prior.m
@@ -0,0 +1,5 @@
+function L = log_prior(CPD)
+% LOG_PRIOR Return log P(theta) for a hhmm F CPD 
+% L = log_prior(CPD)
+
+L = log_prior(CPD.sub_CPD_term);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/maximize_params.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/maximize_params.m
new file mode 100644
index 00000000..16e51ddc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/maximize_params.m
@@ -0,0 +1,9 @@
+function CPD = maximize_params(CPD, temp)
+% MAXIMIZE_PARAMS Set the params of a hhmmF node to their ML/MAP values.
+% CPD = maximize_params(CPD, temperature)
+
+CPD.sub_CPD_term = maximize_params(CPD.sub_CPD_term, temp);
+S = struct(CPD.sub_CPD_term);
+CPD.termprob = S.CPT;
+
+CPD = update_CPT(CPD);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/reset_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/reset_ess.m
new file mode 100644
index 00000000..f4428937
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/reset_ess.m
@@ -0,0 +1,5 @@
+function CPD = reset_ess(CPD)
+% RESET_ESS Reset the Expected Sufficient Statistics of a hhmm F node.
+% CPD = reset_ess(CPD)
+
+CPD.sub_CPD_term = reset_ess(CPD.sub_CPD_term);   
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/update_CPT.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/update_CPT.m
new file mode 100644
index 00000000..1250457e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/update_CPT.m
@@ -0,0 +1,13 @@
+function CPD = update_CPT(CPD)
+% Compute the big CPT for an HHMM F node given internal termprob
+% function CPD = update_CPT(CPD)
+
+Qsz = CPD.Qsz;
+Qpsz = CPD.Qpsz;
+
+% CPT(Qpsz, Q, Fbelow, Fself)
+CPT = zeros(Qpsz, Qsz, 2, 2);
+CPT(:,:,1,1) = 1; % if Fbelow=1 (off), then Fself=1 (off)
+CPT(:,:,2,:) = CPD.termprob;
+
+CPD = set_fields(CPD, 'CPT', CPT);          
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/update_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/update_ess.m
new file mode 100644
index 00000000..cc636520
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmF_CPD/update_ess.m
@@ -0,0 +1,40 @@
+function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+% UPDATE_ESS Update the Expected Sufficient Statistics of a hhmmF node.
+% function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+%
+% We assume the F nodes are always hidden
+
+% Figure out the node numbers associated with each parent
+dom = fmarginal.domain;
+%Fself = dom(end); 
+%Fbelow = dom(CPD.Fbelow_ndx);
+Qself = dom(CPD.Qself_ndx);
+Qps = dom(CPD.Qps_ndx);
+
+Qsz = CPD.Qsz;
+Qpsz = CPD.Qpsz;
+
+if all(hidden_bitv(Qps)) % we assume all are hidden or all are observed
+  k_ndx = 1:Qpsz;
+  eff_Qpsz = Qpsz;
+else
+  k_ndx = subv2ind(Qpsz, cat(1, evidence{Qps}));
+  eff_Qpsz = 1;
+end
+
+if hidden_bitv(Qself)
+  j_ndx = 1:Qsz;
+  eff_Qsz = Qsz;
+else
+  j_ndx = evidence{Qself};
+  eff_Qsz = 1;
+end
+
+% Fmarginal(Qps, Q, Fbelow, F)
+fmarg = myreshape(fmarginal.T, [eff_Qpsz eff_Qsz  2 2]);
+
+counts = zeros(Qpsz, Qsz, 2);
+%counts(k_ndx, j_ndx, :) = sum(fmarginal.T(:, :, :, :), 3); % sum over Fbelow
+counts(k_ndx, j_ndx, :) = fmarg(:, :, 2, :); % Fbelow = 2
+
+CPD.sub_CPD_term = update_ess_simple(CPD.sub_CPD_term, counts);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/CVS/Entries
new file mode 100644
index 00000000..0afc5821
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/CVS/Entries
@@ -0,0 +1,7 @@
+/hhmmQ_CPD.m/1.1.1.1/Tue Sep 24 04:19:26 2002//
+/log_prior.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/maximize_params.m/1.1.1.1/Tue Sep 24 13:10:18 2002//
+/reset_ess.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/update_CPT.m/1.1.1.1/Tue Sep 24 02:58:18 2002//
+/update_ess.m/1.1.1.1/Thu Jul 24 13:41:34 2003//
+D/Old////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/CVS/Repository
new file mode 100644
index 00000000..f226b7fc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@hhmmQ_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/CVS/Entries
new file mode 100644
index 00000000..06bd5c8c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/CVS/Entries
@@ -0,0 +1,10 @@
+/hhmmQ_CPD.m/1.1.1.1/Mon Jun 24 18:19:00 2002//
+/log_prior.m/1.1.1.1/Mon Jun 24 18:19:00 2002//
+/maximize_params.m/1.1.1.1/Mon Jun 24 18:19:00 2002//
+/reset_ess.m/1.1.1.1/Mon Jun 24 18:19:00 2002//
+/update_CPT.m/1.1.1.1/Tue Sep 24 02:30:32 2002//
+/update_ess.m/1.1.1.1/Mon Jun 24 18:19:00 2002//
+/update_ess2.m/1.1.1.1/Mon Jun 24 21:20:52 2002//
+/update_ess3.m/1.1.1.1/Mon Jun 24 22:08:08 2002//
+/update_ess4.m/1.1.1.1/Mon Jun 24 22:23:32 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/CVS/Repository
new file mode 100644
index 00000000..8e7c978a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@hhmmQ_CPD/Old
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/hhmmQ_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/hhmmQ_CPD.m
new file mode 100644
index 00000000..24ef464b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/hhmmQ_CPD.m
@@ -0,0 +1,126 @@
+function CPD = hhmmQ_CPD(bnet, self, Qnodes, d, D, varargin)
+% HHMMQ_CPD Make the CPD for a Q node at depth D of a D-level hierarchical HMM
+% CPD = hhmmQ_CPD(bnet, self, Qnodes, d, D, ...)
+%
+%  Fd(t-1) \   Q1:d-1(t)
+%           \  |
+%            \ v
+%  Qd(t-1) -> Qd(t)
+%            /
+%           /
+%  Fd+1(t-1) 
+%
+% We assume parents are ordered (numbered) as follows:
+% Qd(t-1), Fd+1(t-1), Fd(t-1), Q1(t), ..., Qd(t)
+%
+% The parents of Qd(t) can either be just Qd-1(t) or the whole stack Q1:d-1(t) (allQ)
+% In either case, we will call them Qps.
+% If d=1, Qps does not exist. Also, the F1(t-1) -> Q1(t) arc is optional.
+% If the arc is missing, startprob does not need to be specified,
+% since the toplevel is assumed to never reset (F1 does not exist).
+% If d=D, Fd+1(t-1) does not exist (there is no signal from below).
+%
+% optional args [defaults]
+%
+% transprob - transprob(i,k,j) = prob transition from i to j given Qps = k ['leftright']
+% selfprob  - prob of a transition from i to i given Qps=k [0.1]
+% startprob - startprob(k,j) = prob start in j given Qps = k ['leftstart']
+% startargs - other args to be passed to the sub tabular_CPD for learning startprob
+% transargs - other args will be passed to the sub tabular_CPD for learning transprob
+% allQ      - 1 means use all Q nodes above d as parents, 0 means just level d-1 [0]
+% F1toQ1    - 1 means add F1(t-1) -> Q1(t) arc, 0 means level 1 never resets [0]
+%
+% For d=1, startprob(1,j) is only needed if F1toQ1=1
+% Also, transprob(i,j) can be used instead of transprob(i,1,j).
+%
+% hhmmQ_CPD is a subclass of tabular_CPD so we inherit inference methods like CPD_to_pot, etc.
+%
+% We create isolated tabular_CPDs with no F parents to learn transprob/startprob
+% so we can avail of e.g., entropic or Dirichlet priors.
+% In the future, we will be able to represent the transprob using a tree_CPD.
+%
+% For details, see "Linear-time inference in hierarchical HMMs", Murphy and Paskin, NIPS'01.
+
+
+ss = bnet.nnodes_per_slice;
+%assert(self == Qnodes(d)+ss);
+ns = bnet.node_sizes(:);
+CPD.Qsizes = ns(Qnodes);
+CPD.d = d;
+CPD.D = D;
+allQ = 0;
+
+% find out which parents to use, to get right size
+for i=1:2:length(varargin)
+  switch varargin{i},
+   case 'allQ', allQ = varargin{i+1}; 
+  end
+end
+
+if d==1
+  CPD.Qps = [];
+else
+  if allQ
+    CPD.Qps = Qnodes(1:d-1);
+  else
+    CPD.Qps = Qnodes(d-1);
+  end
+end
+
+Qsz = ns(self);
+Qpsz = prod(ns(CPD.Qps));
+
+% set default arguments
+startprob = 'leftstart';
+transprob = 'leftright';
+startargs = {};
+transargs = {};
+CPD.F1toQ1 = 0;
+selfprob = 0.1;
+
+for i=1:2:length(varargin)
+  switch varargin{i},
+   case 'transprob', transprob = varargin{i+1}; 
+   case 'selfprob',  selfprob = varargin{i+1}; 
+   case 'startprob', startprob = varargin{i+1}; 
+   case 'startargs', startargs = varargin{i+1}; 
+   case 'transargs', transargs = varargin{i+1}; 
+   case 'F1toQ1',    CPD.F1toQ1 = varargin{i+1}; 
+  end
+end
+
+Qps = CPD.Qps + ss;
+old_self = self-ss;
+
+if strcmp(transprob, 'leftright')
+  LR = mk_leftright_transmat(Qsz, selfprob);
+  transprob = repmat(reshape(LR, [1 Qsz Qsz]), [Qpsz 1 1]); % transprob(k,i,j)
+  transprob = permute(transprob, [2 1 3]); % now transprob(i,k,j)
+end
+transargs{end+1} = 'CPT';
+transargs{end+1} = transprob;
+CPD.sub_CPD_trans = mk_isolated_tabular_CPD([old_self Qps], ns([old_self Qps self]), transargs);
+S = struct(CPD.sub_CPD_trans);
+CPD.transprob = myreshape(S.CPT, [Qsz Qpsz Qsz]);
+
+
+if strcmp(startprob, 'leftstart')
+  startprob = zeros(Qpsz, Qsz);
+  startprob(:,1) = 1;
+end
+
+if (d==1) & ~CPD.F1toQ1
+  CPD.sub_CPD_start = [];
+  CPD.startprob = [];
+else
+  startargs{end+1} = 'CPT';
+  startargs{end+1} = startprob;
+  CPD.sub_CPD_start = mk_isolated_tabular_CPD(Qps, ns([Qps self]), startargs);
+  S = struct(CPD.sub_CPD_start);
+  CPD.startprob = myreshape(S.CPT, [Qpsz Qsz]);
+end
+
+CPD = class(CPD, 'hhmmQ_CPD', tabular_CPD(bnet, self));
+
+CPD = update_CPT(CPD);
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/log_prior.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/log_prior.m
new file mode 100644
index 00000000..d44bec5e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/log_prior.m
@@ -0,0 +1,8 @@
+function L = log_prior(CPD)
+% LOG_PRIOR Return log P(theta) for a hhmm CPD 
+% L = log_prior(CPD)
+
+L = log_prior(CPD.sub_CPD_trans);
+if ~isempty(CPD.sub_CPD_start)
+  L = L + log_prior(CPD.sub_CPD_start);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/maximize_params.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/maximize_params.m
new file mode 100644
index 00000000..0e4632aa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/maximize_params.m
@@ -0,0 +1,40 @@
+function CPD = maximize_params(CPD, temp)
+% MAXIMIZE_PARAMS Set the params of a hhmmQ node to their ML/MAP values.
+% CPD = maximize_params(CPD, temperature)
+
+Qsz = CPD.Qsizes(CPD.d);
+Qpsz = prod(CPD.Qsizes(CPD.Qps));
+
+if ~isempty(CPD.sub_CPD_start)
+  CPD.sub_CPD_start = maximize_params(CPD.sub_CPD_start, temp);
+  S = struct(CPD.sub_CPD_start);
+  CPD.startprob = myreshape(S.CPT, [Qpsz Qsz]);
+  %CPD.startprob = S.CPT;
+end
+
+if 1
+  % If we are in a state that can only go the end state,
+  % we will never see a transition to another (non-end) state,
+  % so counts(i,k,j)=0 (and termprob(k,i)=1).
+  % We set counts(i,k,i)=1 in this case.
+  % This will cause remove_hhmm_end_state to return a
+  % stochastic matrix, but otherwise has no effect on EM.
+  counts = get_field(CPD.sub_CPD_trans, 'counts');
+  counts = reshape(counts, [Qsz Qpsz Qsz]);
+  for k=1:Qpsz
+    for i=1:Qsz
+      if sum(counts(i,k,:))==0 % never witnessed a transition out of i
+	counts(i,k,i)=1; % add self loop 
+	%fprintf('CPDQ d=%d i=%d k=%d\n', CPD.d, i, k);
+      end
+    end
+  end
+  CPD.sub_CPD_trans = set_fields(CPD.sub_CPD_trans, 'counts', counts(:)); 
+end
+ 
+CPD.sub_CPD_trans = maximize_params(CPD.sub_CPD_trans, temp);
+S = struct(CPD.sub_CPD_trans);
+%CPD.transprob = S.CPT;
+CPD.transprob = myreshape(S.CPT, [Qsz Qpsz Qsz]);
+
+CPD = update_CPT(CPD);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/reset_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/reset_ess.m
new file mode 100644
index 00000000..45a70ad7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/reset_ess.m
@@ -0,0 +1,8 @@
+function CPD = reset_ess(CPD)
+% RESET_ESS Reset the Expected Sufficient Statistics of a hhmm Q node.
+% CPD = reset_ess(CPD)
+
+if ~isempty(CPD.sub_CPD_start)
+  CPD.sub_CPD_start = reset_ess(CPD.sub_CPD_start);
+end
+CPD.sub_CPD_trans = reset_ess(CPD.sub_CPD_trans);   
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_CPT.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_CPT.m
new file mode 100644
index 00000000..503c225b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_CPT.m
@@ -0,0 +1,74 @@
+function CPD = update_CPT(CPD)
+% Compute the big CPT for an HHMM Q node (including F parents) given internal transprob and startprob
+% function CPD = update_CPT(CPD)
+
+Qsz = CPD.Qsz;
+Qpsz = CPD.Qpsz;
+
+if ~isempty(CPD.Fbelow_ndx)
+  if ~isempty(CPD.Fself_ndx) % general case
+    % Fb(t-1) Fself(t-1)  P(Q(t)=j| Q(t-1)=i, Qps(t)=k)
+    % ------------------------------------------------------
+    % 1        1         delta(i,j)
+    % 2        1         transprob(i,k,j)
+    % 1        2         impossible
+    % 2        2         startprob(k,j)
+    CPT = zeros(Qsz, 2, 2, Qpsz, Qsz);
+    I = repmat(eye(Qsz), [1 1 Qpsz]); % i,j,k
+    I = permute(I, [1 3 2]); % i,k,j
+    CPT(:, 1, 1, :, :) = I;
+    CPT(:, 2, 1, :, :) = CPD.transprob;
+    CPT(:, 1, 2, :, :) = I;
+    CPT(:, 2, 2, :, :) = repmat(reshape(CPD.startprob, [1 Qpsz Qsz]), [Qsz 1 1]); % replicate over i
+  else % no F from self, hence no startprob
+    % Fb(t-1) P(Q(t)=j| Q(t-1)=i, Qps(t)=k)
+    % ------------------------------------------------------
+    % 1       delta(i,j)
+    % 2       transprob(i,k,j)
+    
+    nps = length(CPD.dom_sz)-1; % num parents
+    CPT = 0*myones(CPD.dom_sz);
+    %CPT = zeros(Qsz, 2, Qpsz, Qsz); % assumes CPT(Q(t-1), F(t-1), Qps, Q(t))
+    % but a member of Qps may preceed Q(t-1) or F(t-1) in the ordering
+    
+    I = repmat(eye(Qsz), [1 1 Qpsz]); % i,j,k
+    I = permute(I, [1 3 2]); % i,k,j
+
+    % the following fails if there is a member of Qps with a lower
+    % number than F
+    %CPT(:, 1, :, :) = I;
+    %CPT(:, 2, :, :) = CPD.transprob;
+
+    ndx = mk_multi_index(nps+1, CPD.Fbelow_ndx, 1);
+    CPT(ndx{:}) = I;
+    ndx = mk_multi_index(nps+1, CPD.Fbelow_ndx, 2);
+    CPT(ndx{:}) = CPD.transprob;
+    keyboard
+  end
+else % no F signal from below
+  if ~isempty(CPD.Fself_ndx)
+    % Q(t-1), Fself(t-1), Qps, Q(t)
+    
+    % if condition start on previous concrete state (as in map learning),
+    % CPT(:, 1, :, :, :) = CPD.transprob(Q(t-1), Qps, Q(t))
+    % CPT(:, 2, :, :, :) = CPD.startprob(Q(t-1), Qps, Q(t))
+    
+    % Fself(t-1)  P(Q(t-1)=i, Qps(t)=k -> Q(t)=j)
+    % ------------------------------------------------------
+    % 1         transprob(i,k,j)
+    % 2         startprob(k,j)
+    CPT = zeros(Qsz, 2, Qpsz, Qsz);
+    I = repmat(eye(Qsz), [1 1 Qpsz]); % i,j,k
+    I = permute(I, [1 3 2]); % i,k,j
+    CPT(:, 1, :, :) = CPD.transprob;
+    if CPD.fullstartprob
+      CPT(:, 2, :, :) = CPD.startprob;
+    else
+      CPT(:, 2, :, :) = repmat(reshape(CPD.startprob, [1 Qpsz Qsz]), [Qsz 1 1]); % replicate over i
+    end
+    else % no F from self
+    error('An hhmmQ node without any F parents is just a tabular_CPD')
+  end
+end
+
+CPD = set_fields(CPD, 'CPT', CPT);          
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess.m
new file mode 100644
index 00000000..51c2bd1f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess.m
@@ -0,0 +1,141 @@
+function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+% UPDATE_ESS Update the Expected Sufficient Statistics of a hhmm Q node.
+% function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, idden_bitv)
+
+% Figure out the node numbers associated with each parent
+% e.g., D=4, d=3, Qps = all Qs above, so dom = [Q3(t-1) F4(t-1) F3(t-1) Q1(t) Q2(t) Q3(t)].
+% so self = Q3(t), old_self = Q3(t-1), CPD.Qps = [1 2], Qps = [Q1(t) Q2(t)]
+dom = fmarginal.domain;
+self = dom(end);
+old_self = dom(1);
+Qps = dom(length(dom)-length(CPD.Qps):end-1);
+
+Qsz = CPD.Qsizes(CPD.d);
+Qpsz = prod(CPD.Qsizes(CPD.Qps));
+
+% If some of the Q nodes are observed (which happens during supervised training)
+% the counts will only be non-zero in positions
+% consistent with the evidence. We put the computed marginal responsibilities
+% into the appropriate slots of the big counts array.
+% (Recall that observed discrete nodes only have a single effective value.)
+% (A more general, but much slower, way is to call add_evidence_to_dmarginal.)
+% We assume the F nodes are never observed.
+
+obs_self = ~hidden_bitv(self);
+obs_Qps = (~isempty(Qps)) & (~any(hidden_bitv(Qps))); % we assume that all or none of the Q parents are observed
+
+if obs_self
+  self_val = evidence{self};
+  oldself_val = evidence{old_self};
+end
+
+if obs_Qps
+  Qps_val = subv2ind(Qpsz, cat(1, evidence{Qps}));
+  if Qps_val == 0
+    keyboard
+  end
+end
+
+if CPD.d==1 % no Qps from above
+  if ~CPD.F1toQ1 % no F from self
+    % marg(Q1(t-1), F2(t-1), Q1(t))                            
+    % F2(t-1) P(Q1(t)=j | Q1(t-1)=i)
+    % 1       delta(i,j)
+    % 2       transprob(i,j)
+    if obs_self
+      hor_counts = zeros(Qsz, Qsz);
+      hor_counts(oldself_val, self_val) = fmarginal.T(2);
+    else
+      marg = reshape(fmarginal.T, [Qsz 2 Qsz]);
+      hor_counts = squeeze(marg(:,2,:));
+    end
+  else
+    % marg(Q1(t-1), F2(t-1), F1(t-1), Q1(t))                            
+    % F2(t-1) F1(t-1)  P(Qd(t)=j| Qd(t-1)=i)
+    % ------------------------------------------------------
+    % 1        1         delta(i,j)
+    % 2        1         transprob(i,j)
+    % 1        2         impossible
+    % 2        2         startprob(j)
+    if obs_self
+      marg = myreshape(fmarginal.T, [1 2 2 1]);
+      hor_counts = zeros(Qsz, Qsz);
+      hor_counts(oldself_val, self_val) = marg(1,2,1,1);
+      ver_counts = zeros(Qsz, 1);
+      %ver_counts(self_val) = marg(1,2,2,1);
+      ver_counts(self_val) = marg(1,2,2,1) + marg(1,1,2,1);
+    else
+      marg = reshape(fmarginal.T, [Qsz 2 2 Qsz]);
+      hor_counts = squeeze(marg(:,2,1,:));
+      %ver_counts = squeeze(sum(marg(:,2,2,:),1)); % sum over i
+      ver_counts = squeeze(sum(marg(:,2,2,:),1)) + squeeze(sum(marg(:,1,2,:),1)); % sum i,b
+    end
+  end % F1toQ1
+else % d ~= 1
+  if CPD.d < CPD.D % general case
+    % marg(Qd(t-1), Fd+1(t-1), Fd(t-1), Qps(t), Qd(t))                            
+    % Fd+1(t-1) Fd(t-1)  P(Qd(t)=j| Qd(t-1)=i, Qps(t)=k)
+    % ------------------------------------------------------
+    % 1        1         delta(i,j)
+    % 2        1         transprob(i,k,j)
+    % 1        2         impossible
+    % 2        2         startprob(k,j)
+    if obs_Qps & obs_self
+      marg = myreshape(fmarginal.T, [1 2 2 1 1]);
+      k = 1;
+      hor_counts = zeros(Qsz, Qpsz, Qsz);
+      hor_counts(oldself_val, Qps_val, self_val) = marg(1, 2,1, k,1);
+      ver_counts = zeros(Qpsz, Qsz);
+      %ver_counts(Qps_val, self_val) = marg(1, 2,2, k,1);
+      ver_counts(Qps_val, self_val) = marg(1, 2,2, k,1) + marg(1, 1,2, k,1);
+    elseif obs_Qps & ~obs_self
+      marg = myreshape(fmarginal.T, [Qsz 2 2 1 Qsz]);
+      k = 1;
+      hor_counts = zeros(Qsz, Qpsz, Qsz);
+      hor_counts(:, Qps_val, :) = marg(:, 2,1, k,:);
+      ver_counts = zeros(Qpsz, Qsz);
+      %ver_counts(Qps_val, :) = sum(marg(:, 2,2, k,:), 1);
+      ver_counts(Qps_val, :) = sum(marg(:, 2,2, k,:), 1) + sum(marg(:, 1,2, k,:), 1);
+    elseif ~obs_Qps & obs_self
+      error('not yet implemented')
+    else % everything is hidden
+      marg = reshape(fmarginal.T, [Qsz 2 2 Qpsz Qsz]);
+      hor_counts = squeeze(marg(:,2,1,:,:)); % i,k,j
+      %ver_counts = squeeze(sum(marg(:,2,2,:,:),1)); % sum over i
+      ver_counts = squeeze(sum(marg(:,2,2,:,:),1)) + squeeze(sum(marg(:,1,2,:,:),1)); % sum over i,b
+    end
+  else % d == D, so no F from below
+    % marg(QD(t-1), FD(t-1), Qps(t), QD(t))                            
+    % FD(t-1) P(QD(t)=j | QD(t-1)=i, Qps(t)=k)
+    % 1      transprob(i,k,j) 
+    % 2      startprob(k,j)
+    if obs_Qps & obs_self
+      marg = myreshape(fmarginal.T, [1 2 1 1]);
+      k = 1;
+      hor_counts = zeros(Qsz, Qpsz, Qsz);
+      hor_counts(oldself_val, Qps_val, self_val) = marg(1, 1, k,1);
+      ver_counts = zeros(Qpsz, Qsz);
+      ver_counts(Qps_val, self_val) = marg(1, 2, k,1);
+    elseif obs_Qps & ~obs_self
+      marg = myreshape(fmarginal.T, [Qsz 2 1 Qsz]);
+      k = 1;
+      hor_counts = zeros(Qsz, Qpsz, Qsz);
+      hor_counts(:, Qps_val, :) = marg(:, 1, k,:);
+      ver_counts = zeros(Qpsz, Qsz);
+      ver_counts(Qps_val, :) = sum(marg(:, 2, k, :), 1);
+    elseif ~obs_Qps & obs_self
+      error('not yet implemented')
+    else % everything is hidden
+      marg = reshape(fmarginal.T, [Qsz 2 Qpsz Qsz]);
+      hor_counts = squeeze(marg(:,1,:,:));
+      ver_counts = squeeze(sum(marg(:,2,:,:),1)); % sum over i
+    end
+  end
+end
+
+CPD.sub_CPD_trans = update_ess_simple(CPD.sub_CPD_trans, hor_counts);
+
+if ~isempty(CPD.sub_CPD_start)
+  CPD.sub_CPD_start = update_ess_simple(CPD.sub_CPD_start, ver_counts);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess2.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess2.m
new file mode 100644
index 00000000..41fc7380
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess2.m
@@ -0,0 +1,178 @@
+function CPD = update_ess2(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+% UPDATE_ESS Update the Expected Sufficient Statistics of a hhmm Q node.
+% function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, idden_bitv)
+
+% Figure out the node numbers associated with each parent
+dom = fmarginal.domain;
+self = dom(end); % by assumption
+old_self = dom(CPD.old_self_ndx);
+Fself = dom(CPD.Fself_ndx);
+Fbelow = dom(CPD.Fbelow_ndx);
+Qps = dom(CPD.Qps_ndx);
+
+Qsz = CPD.Qsz;
+Qpsz = CPD.Qpsz;
+
+
+fmarg = add_ev_to_dmarginal(fmarginal, evidence, ns);
+
+
+
+% hor_counts(old_self, Qps, self),
+% fmarginal(old_self, Fbelow, Fself, Qps, self)
+% hor_counts(i,k,j) = fmarginal(i,2,1,k,j) % below has finished, self has not
+% ver_counts(i,k,j) = fmarginal(i,2,2,k,j) % below has finished, and so has self (reset)
+% Since any of i,j,k may be observed, we write
+% hor_counts(counts_ndx{:}) = fmarginal(fmarg_ndx{:})
+% where e.g., counts_ndx = {1, ':', 2} if Qps is hidden but we observe old_self=1, self=2.
+% To create this counts_ndx, we write counts_ndx = mk_multi_ndx(3, obs_dim, obs_val)
+% where counts_obs_dim = [1 3], counts_obs_val = [1 2] specifies the values of dimensions 1 and 3.
+
+counts_obs_dim = [];
+fmarg_obs_dim = [];
+obs_val = []; 
+if hidden_bitv(self)
+  effQsz = Qsz;
+else
+  effQsz = 1;
+  counts_obs_dim = [counts_obs_dim 3];
+  fmarg_obs_dim = [fmarg_obs_dim 5];
+  obs_val = [obs_val evidence{self}];
+end
+  
+% e.g., D=4, d=3, Qps = all Qs above, so dom = [Q3(t-1) F4(t-1) F3(t-1) Q1(t) Q2(t) Q3(t)].
+% so self = Q3(t), old_self = Q3(t-1), CPD.Qps = [1 2], Qps = [Q1(t) Q2(t)]
+dom = fmarginal.domain;
+self = dom(end);
+old_self = dom(1);
+Qps = dom(length(dom)-length(CPD.Qps):end-1);
+
+Qsz = CPD.Qsizes(CPD.d);
+Qpsz = prod(CPD.Qsizes(CPD.Qps));
+
+% If some of the Q nodes are observed (which happens during supervised training)
+% the counts will only be non-zero in positions
+% consistent with the evidence. We put the computed marginal responsibilities
+% into the appropriate slots of the big counts array.
+% (Recall that observed discrete nodes only have a single effective value.)
+% (A more general, but much slower, way is to call add_evidence_to_dmarginal.)
+% We assume the F nodes are never observed.
+
+obs_self = ~hidden_bitv(self);
+obs_Qps = (~isempty(Qps)) & (~any(hidden_bitv(Qps))); % we assume that all or none of the Q parents are observed
+
+if obs_self
+  self_val = evidence{self};
+  oldself_val = evidence{old_self};
+end
+
+if obs_Qps
+  Qps_val = subv2ind(Qpsz, cat(1, evidence{Qps}));
+  if Qps_val == 0
+    keyboard
+  end
+end
+
+if CPD.d==1 % no Qps from above
+  if ~CPD.F1toQ1 % no F from self
+    % marg(Q1(t-1), F2(t-1), Q1(t))                            
+    % F2(t-1) P(Q1(t)=j | Q1(t-1)=i)
+    % 1       delta(i,j)
+    % 2       transprob(i,j)
+    if obs_self
+      hor_counts = zeros(Qsz, Qsz);
+      hor_counts(oldself_val, self_val) = fmarginal.T(2);
+    else
+      marg = reshape(fmarginal.T, [Qsz 2 Qsz]);
+      hor_counts = squeeze(marg(:,2,:));
+    end
+  else
+    % marg(Q1(t-1), F2(t-1), F1(t-1), Q1(t))                            
+    % F2(t-1) F1(t-1)  P(Qd(t)=j| Qd(t-1)=i)
+    % ------------------------------------------------------
+    % 1        1         delta(i,j)
+    % 2        1         transprob(i,j)
+    % 1        2         impossible
+    % 2        2         startprob(j)
+    if obs_self
+      marg = myreshape(fmarginal.T, [1 2 2 1]);
+      hor_counts = zeros(Qsz, Qsz);
+      hor_counts(oldself_val, self_val) = marg(1,2,1,1);
+      ver_counts = zeros(Qsz, 1);
+      %ver_counts(self_val) = marg(1,2,2,1);
+      ver_counts(self_val) = marg(1,2,2,1) + marg(1,1,2,1);
+    else
+      marg = reshape(fmarginal.T, [Qsz 2 2 Qsz]);
+      hor_counts = squeeze(marg(:,2,1,:));
+      %ver_counts = squeeze(sum(marg(:,2,2,:),1)); % sum over i
+      ver_counts = squeeze(sum(marg(:,2,2,:),1)) + squeeze(sum(marg(:,1,2,:),1)); % sum i,b
+    end
+  end % F1toQ1
+else % d ~= 1
+  if CPD.d < CPD.D % general case
+    % marg(Qd(t-1), Fd+1(t-1), Fd(t-1), Qps(t), Qd(t))                            
+    % Fd+1(t-1) Fd(t-1)  P(Qd(t)=j| Qd(t-1)=i, Qps(t)=k)
+    % ------------------------------------------------------
+    % 1        1         delta(i,j)
+    % 2        1         transprob(i,k,j)
+    % 1        2         impossible
+    % 2        2         startprob(k,j)
+    if obs_Qps & obs_self
+      marg = myreshape(fmarginal.T, [1 2 2 1 1]);
+      k = 1;
+      hor_counts = zeros(Qsz, Qpsz, Qsz);
+      hor_counts(oldself_val, Qps_val, self_val) = marg(1, 2,1, k,1);
+      ver_counts = zeros(Qpsz, Qsz);
+      %ver_counts(Qps_val, self_val) = marg(1, 2,2, k,1);
+      ver_counts(Qps_val, self_val) = marg(1, 2,2, k,1) + marg(1, 1,2, k,1);
+    elseif obs_Qps & ~obs_self
+      marg = myreshape(fmarginal.T, [Qsz 2 2 1 Qsz]);
+      k = 1;
+      hor_counts = zeros(Qsz, Qpsz, Qsz);
+      hor_counts(:, Qps_val, :) = marg(:, 2,1, k,:);
+      ver_counts = zeros(Qpsz, Qsz);
+      %ver_counts(Qps_val, :) = sum(marg(:, 2,2, k,:), 1);
+      ver_counts(Qps_val, :) = sum(marg(:, 2,2, k,:), 1) + sum(marg(:, 1,2, k,:), 1);
+    elseif ~obs_Qps & obs_self
+      error('not yet implemented')
+    else % everything is hidden
+      marg = reshape(fmarginal.T, [Qsz 2 2 Qpsz Qsz]);
+      hor_counts = squeeze(marg(:,2,1,:,:)); % i,k,j
+      %ver_counts = squeeze(sum(marg(:,2,2,:,:),1)); % sum over i
+      ver_counts = squeeze(sum(marg(:,2,2,:,:),1)) + squeeze(sum(marg(:,1,2,:,:),1)); % sum over i,b
+    end
+  else % d == D, so no F from below
+    % marg(QD(t-1), FD(t-1), Qps(t), QD(t))                            
+    % FD(t-1) P(QD(t)=j | QD(t-1)=i, Qps(t)=k)
+    % 1      transprob(i,k,j) 
+    % 2      startprob(k,j)
+    if obs_Qps & obs_self
+      marg = myreshape(fmarginal.T, [1 2 1 1]);
+      k = 1;
+      hor_counts = zeros(Qsz, Qpsz, Qsz);
+      hor_counts(oldself_val, Qps_val, self_val) = marg(1, 1, k,1);
+      ver_counts = zeros(Qpsz, Qsz);
+      ver_counts(Qps_val, self_val) = marg(1, 2, k,1);
+    elseif obs_Qps & ~obs_self
+      marg = myreshape(fmarginal.T, [Qsz 2 1 Qsz]);
+      k = 1;
+      hor_counts = zeros(Qsz, Qpsz, Qsz);
+      hor_counts(:, Qps_val, :) = marg(:, 1, k,:);
+      ver_counts = zeros(Qpsz, Qsz);
+      ver_counts(Qps_val, :) = sum(marg(:, 2, k, :), 1);
+    elseif ~obs_Qps & obs_self
+      error('not yet implemented')
+    else % everything is hidden
+      marg = reshape(fmarginal.T, [Qsz 2 Qpsz Qsz]);
+      hor_counts = squeeze(marg(:,1,:,:));
+      ver_counts = squeeze(sum(marg(:,2,:,:),1)); % sum over i
+    end
+  end
+end
+
+CPD.sub_CPD_trans = update_ess_simple(CPD.sub_CPD_trans, hor_counts);
+
+if ~isempty(CPD.sub_CPD_start)
+  CPD.sub_CPD_start = update_ess_simple(CPD.sub_CPD_start, ver_counts);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess3.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess3.m
new file mode 100644
index 00000000..da7ab6bd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess3.m
@@ -0,0 +1,80 @@
+function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+% UPDATE_ESS Update the Expected Sufficient Statistics of a hhmm Q node.
+% function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, idden_bitv)
+%
+% we assume if one of the Qps is observed, all of them are 
+% We assume the F nodes are already hidden 
+
+% Figure out the node numbers associated with each parent
+dom = fmarginal.domain;
+self = dom(CPD.self_ndx);
+old_self = dom(CPD.old_self_ndx);
+%Fself = dom(CPD.Fself_ndx);
+%Fbelow = dom(CPD.Fbelow_ndx);
+Qps = dom(CPD.Qps_ndx);
+
+Qsz = CPD.Qsz;
+Qpsz = CPD.Qpsz;
+
+
+% hor_counts(old_self, Qps, self),
+% fmarginal(old_self, Fbelow, Fself, Qps, self)
+% hor_counts(i,k,j) = fmarginal(i,2,1,k,j) % below has finished, self has not
+% ver_counts(i,k,j) = fmarginal(i,2,2,k,j) % below has finished, and so has self (reset)
+% Since any of i,j,k may be observed, we write
+% hor_counts(ndx{:}) = fmarginal(...)
+% where e.g., ndx = {1, ':', 2} if Qps is hidden but we observe old_self=1, self=2.
+
+% ndx{i,k,j}
+if hidden_bitv(old_self)
+  ndx{1} = ':';
+else
+  ndx{1} = evidence{old_self};
+end
+if hidden_bitv(Qps)
+  ndx{2} = ':';
+else
+  ndx{2} = subv2ind(Qpsz, cat(1, evidence{Qps}));
+end
+if hidden_bitv(self)
+  ndx{3} = ':';
+else
+  ndx{3} = evidence{self};
+end
+
+fmarg = add_ev_to_dmarginal(fmarginal, evidence, ns);
+% marg(Qold(t-1), Fbelow(t-1), Fself(t-1), Qps(t), Qself(t))                            
+hor_counts = zeros(Qsz, Qpsz, Qsz);
+ver_counts = zeros(Qpsz, Qsz);
+    
+if ~isempty(CPD.Fbelow_ndx)
+  if ~isempty(CPD.Fself_ndx) % general case
+    fmarg.T = myreshape(fmarg.T, [Qsz 2 2 Qpsz Qsz]);
+    marg_ndx = {ndx{1}, 2, 1, ndx{2}, ndx{3}};
+    hor_counts(ndx{:}) = fmarg.T(marg_ndx{:});
+    ver_counts(ndx{2:3}) = ... % sum over Fbelow and Qold=i
+	sum(fmarg.T({ndx{1}, 1, 2, ndx{2}, ndx{3}}),1) + ..
+	sum(fmarg.T({ndx{1}, 2, 2, ndx{2}, ndx{3}}),1);
+  else % no F from self, hence no startprob
+    fmarg.T = myreshape(fmarg.T, [Qsz 2 Qpsz Qsz]);
+    hor_counts(ndx{:}) = fmarg.T({ndx{1}, 2, ndx{2}, ndx{3}});
+  end
+else % no F signal from below
+  if ~isempty(CPD.Fself_ndx) % self F
+    fmarg.T = myreshape(fmarg.T, [Qsz 2 Qpsz Qsz]);
+    hor_counts(ndx{:}) = fmarg.T({ndx{1}, 1, ndx{2}, ndx{3}});
+    ver_counts(ndx{2:3}) = ... % sum over Qold=i
+	sum(fmarg.T({ndx{1}, 2, ndx{2}, ndx{3}}),1);
+  else % no F from self
+    error('An hhmmQ node without any F parents is just a tabular_CPD')
+  end
+end
+
+
+CPD.sub_CPD_trans = update_ess_simple(CPD.sub_CPD_trans, hor_counts);
+
+if ~isempty(CPD.sub_CPD_start)
+  CPD.sub_CPD_start = update_ess_simple(CPD.sub_CPD_start, ver_counts);
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess4.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess4.m
new file mode 100644
index 00000000..c826da1c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/Old/update_ess4.m
@@ -0,0 +1,95 @@
+function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+% UPDATE_ESS Update the Expected Sufficient Statistics of a hhmm Q node.
+% function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, idden_bitv)
+%
+% we assume if one of the Qps is observed, all of them are 
+% We assume the F nodes are already hidden 
+
+% Figure out the node numbers associated with each parent
+dom = fmarginal.domain;
+self = dom(CPD.self_ndx);
+old_self = dom(CPD.old_self_ndx);
+%Fself = dom(CPD.Fself_ndx);
+%Fbelow = dom(CPD.Fbelow_ndx);
+Qps = dom(CPD.Qps_ndx);
+
+Qsz = CPD.Qsz;
+Qpsz = CPD.Qpsz;
+
+
+% hor_counts(old_self, Qps, self),
+% fmarginal(old_self, Fbelow, Fself, Qps, self)
+% hor_counts(i,k,j) = fmarginal(i,2,1,k,j) % below has finished, self has not
+% ver_counts(i,k,j) = fmarginal(i,2,2,k,j) % below has finished, and so has self (reset)
+% Since any of i,j,k may be observed, we write
+% hor_counts(i_counts_ndx, kndx, jndx) = fmarginal(i_fmarg_ndx...)
+% where i_fmarg_ndx = 1 and i_counts_ndx = i if old_self is observed to have value i,
+% i_fmarg_ndx = 1:Qsz and i_counts_ndx = 1:Qsz if old_self is hidden, etc.
+
+
+if hidden_bitv(old_self)
+  i_counts_ndx = 1:Qsz;
+  i_fmarg_ndx = 1:Qsz;
+  eff_oldQsz = Qsz;
+else
+  i_counts_ndx = evidence{old_self};
+  i_fmarg_ndx = 1;
+  eff_oldQsz = 1;
+end
+
+if all(hidden_bitv(Qps)) % we assume all are hidden or all are observed
+  k_counts_ndx = 1:Qpsz;
+  k_fmarg_ndx = 1:Qpsz;
+  eff_Qpsz = Qpsz;
+else
+  k_counts_ndx = subv2ind(Qpsz, cat(1, evidence{Qps}));
+  k_fmarg_ndx = 1;
+  eff_Qpsz = 1;
+end
+
+if hidden_bitv(self)
+  j_counts_ndx = 1:Qsz;
+  j_fmarg_ndx = 1:Qsz;
+  eff_Qsz = Qsz;
+else
+  j_counts_ndx = evidence{self};
+  j_fmarg_ndx = 1;
+  eff_Qsz = 1;
+end
+
+hor_counts = zeros(Qsz, Qpsz, Qsz);
+ver_counts = zeros(Qpsz, Qsz);
+    
+if ~isempty(CPD.Fbelow_ndx)
+  if ~isempty(CPD.Fself_ndx) % general case
+    fmarg.T = myreshape(fmarg.T, [eff_oldQsz 2 2 eff_Qpsz eff_Qsz]);
+    hor_counts(i_counts_ndx, k_counts_ndx, j_counts_ndx) = ...
+	fmarg.T(:, i_fmarg_ndx, 2, 1, k_fmarg_ndx, j_fmarg_ndx);
+    ver_counts(k_counts_ndx, j_counts_ndx) = ... % sum over Fbelow and Qold
+	sum(fmarg.T(:, 1, 2, k_fmarg_ndx, j_fmarg_ndx), 1) + ...
+	sum(fmarg.T(:, 2, 2, k_fmarg_ndx, j_fmarg_ndx), 1); 
+  else % no F from self, hence no startprob
+    fmarg.T = myreshape(fmarg.T, [eff_oldQsz 2 eff_Qpsz eff_Qsz]);
+    hor_counts(i_counts_ndx, k_counts_ndx, j_counts_ndx) = ...
+	fmarg.T(i_fmarg_ndx, 2, k_fmarg_ndx, j_fmarg_ndx);
+  end
+else % no F signal from below
+  if ~isempty(CPD.Fself_ndx) % self F
+    fmarg.T = myreshape(fmarg.T, [eff_oldQsz 2 eff_Qpsz eff_Qsz]);
+    hor_counts(i_counts_ndx, k_counts_ndx, j_counts_ndx) = ...
+	fmarg.T(i_fmarg_ndx, 1, k_fmarg_ndx, j_fmarg_ndx);
+    ver_counts(k_counts_ndx, j_counts_ndx) = ... % sum over Qold
+	sum(fmarg.T(:, 2, k_fmarg_ndx, j_fmarg_ndx), 1);
+  else % no F from self
+    error('An hhmmQ node without any F parents is just a tabular_CPD')
+  end
+end
+
+
+CPD.sub_CPD_trans = update_ess_simple(CPD.sub_CPD_trans, hor_counts);
+
+if ~isempty(CPD.sub_CPD_start)
+  CPD.sub_CPD_start = update_ess_simple(CPD.sub_CPD_start, ver_counts);
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/hhmmQ_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/hhmmQ_CPD.m
new file mode 100644
index 00000000..6f289602
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/hhmmQ_CPD.m
@@ -0,0 +1,132 @@
+function CPD = hhmmQ_CPD(bnet, self, varargin)
+% HHMMQ_CPD Make the CPD for a Q node in a hierarchical HMM
+% CPD = hhmmQ_CPD(bnet, self, ...)
+%
+%  Fself(t-1)   Qps(t)
+%           \    |
+%            \   v
+%  Qold(t-1) ->  Q(t)
+%            /
+%           /
+%  Fbelow(t-1) 
+%
+% Let ss = slice size = num. nodes per slice.
+% This node is Q(t), and has mandatory parents Qold(t-1) (assumed to be numbered Q(t)-ss)
+% and optional parents Fbelow, Fself, Qps.
+% We require parents to be ordered (numbered) as follows:
+% Qold, Fbelow, Fself, Qps, Q.
+%
+% If Fself=2, we use the transition matrix, else we use the prior matrix.
+% If Fself node is omitted (eg. top level), we always use the transition matrix.
+% If Fbelow=2, we may change state, otherwise we must stay in the same state.
+% If Fbelow node is omitted (eg., bottom level), we may change state at every step.
+% If Qps (Q parents) are specified, all parameters are conditioned on their joint value.
+% We may choose any subset of nodes to condition on, as long as they as numbered lower than self.
+%
+% optional args [defaults]
+%
+% Fself - node number <= ss
+% Fbelow  - node number  <= ss
+% Qps - node numbers (all <= 2*ss) - uses 2TBN indexing
+% transprob - transprob(i,k,j) = prob transition from i to j given Qps = k ['leftright']
+% selfprob  - prob of a transition from i to i given Qps=k [0.1]
+% startprob - startprob(k,j) = prob start in j given Qps = k ['leftstart']
+% startargs - other args to be passed to the sub tabular_CPD for learning startprob
+% transargs - other args will be passed to the sub tabular_CPD for learning transprob
+% fullstartprob - 1 means startprob depends on Q(t-1) [0]
+% hhmmQ_CPD is a subclass of tabular_CPD so we inherit inference methods like CPD_to_pot, etc.
+%
+% We create isolated tabular_CPDs with no F parents to learn transprob/startprob
+% so we can avail of e.g., entropic or Dirichlet priors.
+% In the future, we will be able to represent the transprob using a tree_CPD.
+%
+% For details, see "Linear-time inference in hierarchical HMMs", Murphy and Paskin, NIPS'01.
+
+
+ss = bnet.nnodes_per_slice;
+ns = bnet.node_sizes(:);
+
+% set default arguments
+Fself = [];
+Fbelow = [];
+Qps = [];
+startprob = 'leftstart';
+transprob = 'leftright';
+startargs = {};
+transargs = {};
+selfprob = 0.1;
+fullstartprob = 0;
+
+for i=1:2:length(varargin)
+  switch varargin{i},
+   case 'Fself', Fself = varargin{i+1};
+   case 'Fbelow', Fbelow = varargin{i+1};
+   case 'Qps', Qps = varargin{i+1};
+   case 'transprob', transprob = varargin{i+1}; 
+   case 'selfprob',  selfprob = varargin{i+1}; 
+   case 'startprob', startprob = varargin{i+1}; 
+   case 'startargs', startargs = varargin{i+1}; 
+   case 'transargs', transargs = varargin{i+1}; 
+   case 'fullstartprob', fullstartprob = varargin{i+1}; 
+  end
+end
+
+CPD.fullstartprob = fullstartprob;
+
+ps = parents(bnet.dag, self);
+ndsz = ns(:)';
+CPD.dom_sz = [ndsz(ps) ns(self)];
+CPD.Fself_ndx = find_equiv_posns(Fself, ps);
+CPD.Fbelow_ndx = find_equiv_posns(Fbelow, ps);
+%CPD.Qps_ndx = find_equiv_posns(Qps+ss, ps);
+CPD.Qps_ndx = find_equiv_posns(Qps, ps);
+old_self = self-ss;
+CPD.old_self_ndx = find_equiv_posns(old_self, ps);
+
+Qps = ps(CPD.Qps_ndx);
+CPD.Qsz = ns(self);
+CPD.Qpsz = prod(ns(Qps));
+CPD.Qpsizes = ns(Qps);
+Qsz = CPD.Qsz;
+Qpsz = CPD.Qpsz;
+
+if strcmp(transprob, 'leftright')
+  LR = mk_leftright_transmat(Qsz, selfprob);
+  transprob = repmat(reshape(LR, [1 Qsz Qsz]), [Qpsz 1 1]); % transprob(k,i,j)
+  transprob = permute(transprob, [2 1 3]); % now transprob(i,k,j)
+end
+transargs{end+1} = 'CPT';
+transargs{end+1} = transprob;
+CPD.sub_CPD_trans = mk_isolated_tabular_CPD(ns([old_self Qps self]), transargs);
+S = struct(CPD.sub_CPD_trans);
+%CPD.transprob = myreshape(S.CPT, [Qsz Qpsz Qsz]);
+CPD.transprob = S.CPT;
+
+
+if strcmp(startprob, 'leftstart')
+  startprob = zeros(Qpsz, Qsz);
+  startprob(:,1) = 1;
+end
+if isempty(CPD.Fself_ndx)
+  CPD.sub_CPD_start = [];
+  CPD.startprob = [];
+else
+  startargs{end+1} = 'CPT';
+  startargs{end+1} = startprob;
+  if CPD.fullstartprob
+    CPD.sub_CPD_start = mk_isolated_tabular_CPD(ns([self Qps self]), startargs);
+    S = struct(CPD.sub_CPD_start);
+    %CPD.startprob = myreshape(S.CPT, [Qsz Qpsz Qsz]);
+    CPD.startprob = S.CPT;
+  else
+    CPD.sub_CPD_start = mk_isolated_tabular_CPD(ns([Qps self]), startargs);
+    S = struct(CPD.sub_CPD_start);
+    %CPD.startprob = myreshape(S.CPT, [CPD.Qpsizes Qsz]);
+    CPD.startprob = S.CPT;
+  end
+end
+
+CPD = class(CPD, 'hhmmQ_CPD', tabular_CPD(bnet, self));
+
+CPD = update_CPT(CPD);
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/log_prior.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/log_prior.m
new file mode 100644
index 00000000..d44bec5e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/log_prior.m
@@ -0,0 +1,8 @@
+function L = log_prior(CPD)
+% LOG_PRIOR Return log P(theta) for a hhmm CPD 
+% L = log_prior(CPD)
+
+L = log_prior(CPD.sub_CPD_trans);
+if ~isempty(CPD.sub_CPD_start)
+  L = L + log_prior(CPD.sub_CPD_start);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/maximize_params.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/maximize_params.m
new file mode 100644
index 00000000..541a50be
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/maximize_params.m
@@ -0,0 +1,40 @@
+function CPD = maximize_params(CPD, temp)
+% MAXIMIZE_PARAMS Set the params of a hhmmQ node to their ML/MAP values.
+% CPD = maximize_params(CPD, temperature)
+
+Qsz = CPD.Qsz;
+Qpsz = CPD.Qpsz;
+
+if ~isempty(CPD.sub_CPD_start)
+  CPD.sub_CPD_start = maximize_params(CPD.sub_CPD_start, temp);
+  S = struct(CPD.sub_CPD_start);
+  CPD.startprob = myreshape(S.CPT, [Qpsz Qsz]);
+  %CPD.startprob = S.CPT;
+end
+
+if 1
+  % If we are in a state that can only go the end state,
+  % we will never see a transition to another (non-end) state,
+  % so counts(i,k,j)=0 (and termprob(k,i)=1).
+  % We set counts(i,k,i)=1 in this case.
+  % This will cause remove_hhmm_end_state to return a
+  % stochastic matrix, but otherwise has no effect on EM.
+  counts = get_field(CPD.sub_CPD_trans, 'counts');
+  counts = reshape(counts, [Qsz Qpsz Qsz]);
+  for k=1:Qpsz
+    for i=1:Qsz
+      if sum(counts(i,k,:))==0 % never witnessed a transition out of i
+	counts(i,k,i)=1; % add self loop 
+	%fprintf('CPDQ d=%d i=%d k=%d\n', CPD.d, i, k);
+      end
+    end
+  end
+  CPD.sub_CPD_trans = set_fields(CPD.sub_CPD_trans, 'counts', counts(:)); 
+end
+ 
+CPD.sub_CPD_trans = maximize_params(CPD.sub_CPD_trans, temp);
+S = struct(CPD.sub_CPD_trans);
+%CPD.transprob = S.CPT;
+CPD.transprob = myreshape(S.CPT, [Qsz Qpsz Qsz]);
+
+CPD = update_CPT(CPD);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/reset_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/reset_ess.m
new file mode 100644
index 00000000..45a70ad7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/reset_ess.m
@@ -0,0 +1,8 @@
+function CPD = reset_ess(CPD)
+% RESET_ESS Reset the Expected Sufficient Statistics of a hhmm Q node.
+% CPD = reset_ess(CPD)
+
+if ~isempty(CPD.sub_CPD_start)
+  CPD.sub_CPD_start = reset_ess(CPD.sub_CPD_start);
+end
+CPD.sub_CPD_trans = reset_ess(CPD.sub_CPD_trans);   
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/update_CPT.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/update_CPT.m
new file mode 100644
index 00000000..9ed1a352
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/update_CPT.m
@@ -0,0 +1,70 @@
+function CPD = update_CPT(CPD)
+% Compute the big CPT for an HHMM Q node (including F parents) given internal transprob and startprob
+% function CPD = update_CPT(CPD)
+
+Qsz = CPD.Qsz;
+Qpsz = CPD.Qpsz;
+
+if ~isempty(CPD.Fbelow_ndx)
+  if ~isempty(CPD.Fself_ndx) % general case
+    % Fb(t-1) Fself(t-1)  P(Q(t)=j| Q(t-1)=i, Qps(t)=k)
+    % ------------------------------------------------------
+    % 1        1         delta(i,j)
+    % 2        1         transprob(i,k,j)
+    % 1        2         impossible
+    % 2        2         startprob(k,j)
+    CPT = zeros(Qsz, 2, 2, Qpsz, Qsz);
+    I = repmat(eye(Qsz), [1 1 Qpsz]); % i,j,k
+    I = permute(I, [1 3 2]); % i,k,j
+    CPT(:, 1, 1, :, :) = I;
+    CPT(:, 2, 1, :, :) = CPD.transprob;
+    CPT(:, 1, 2, :, :) = I;
+    CPT(:, 2, 2, :, :) = repmat(reshape(CPD.startprob, [1 Qpsz Qsz]), ...
+				[Qsz 1 1]); % replicate  over i 
+  else % no F from self, hence no startprob
+    % Fb(t-1) P(Q(t)=j| Q(t-1)=i, Qps(t)=k)
+    % ------------------------------------------------------
+    % 1       delta(i,j)
+    % 2       transprob(i,k,j)
+    
+    nps = length(CPD.dom_sz)-1; % num parents
+    CPT = 0*myones(CPD.dom_sz);
+    %CPT = zeros(Qsz, 2, Qpsz, Qsz); % assumes CPT(Q(t-1), F(t-1), Qps, Q(t))
+    % but a member of Qps may preceed Q(t-1) or F(t-1) in the ordering
+
+    for k=1:CPD.Qpsz
+      Qps_vals = ind2subv(CPD.Qpsizes, k);
+      ndx = mk_multi_index(nps+1, [CPD.Fbelow_ndx CPD.Qps_ndx], [1 Qps_vals]);
+      CPT(ndx{:}) = eye(Qsz); % CPT(:,2,k,:) or CPT(:,k,2,:) etc
+    end
+    ndx = mk_multi_index(nps+1, CPD.Fbelow_ndx, 2);
+    CPT(ndx{:}) = CPD.transprob; % we assume transprob is in topo order
+  end
+else % no F signal from below
+  if ~isempty(CPD.Fself_ndx)
+    % Q(t-1), Fself(t-1), Qps, Q(t)
+    
+    % Fself(t-1)  P(Q(t-1)=i, Qps(t)=k -> Q(t)=j)
+    % ------------------------------------------------------
+    % 1         transprob(i,k,j)
+    % 2         startprob(k,j)
+    
+    nps = length(CPD.dom_sz)-1; % num parents
+    CPT = 0*myones(CPD.dom_sz);
+    ndx = mk_multi_index(nps+1, CPD.Fself_ndx, 1);
+    CPT(ndx{:}) = CPD.transprob;
+    if CPD.fullstartprob
+      ndx = mk_multi_index(nps+1, CPD.Fself_ndx, 2);
+      CPT(ndx{:}) = CPD.startprob;
+    else
+      for i=1:CPD.Qsz
+	ndx = mk_multi_index(nps+1, [CPD.Fself_ndx CPD.old_self_ndx], [2 i]);
+	CPT(ndx{:}) = CPD.startprob;
+      end
+    end
+  else % no F from self
+    error('An hhmmQ node without any F parents is just a tabular_CPD')
+  end
+end
+
+CPD = set_fields(CPD, 'CPT', CPT);          
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/update_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/update_ess.m
new file mode 100644
index 00000000..07dfc72e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@hhmmQ_CPD/update_ess.m
@@ -0,0 +1,86 @@
+function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+% UPDATE_ESS Update the Expected Sufficient Statistics of a hhmm Q node.
+% function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, idden_bitv)
+%
+% we assume if one of the Qps is observed, all of them are 
+% We assume the F nodes are already hidden 
+
+% Figure out the node numbers associated with each parent
+dom = fmarginal.domain;
+self = dom(end);
+old_self = dom(CPD.old_self_ndx);
+%Fself = dom(CPD.Fself_ndx);
+%Fbelow = dom(CPD.Fbelow_ndx);
+Qps = dom(CPD.Qps_ndx);
+
+Qsz = CPD.Qsz;
+Qpsz = CPD.Qpsz;
+
+
+% hor_counts(old_self, Qps, self),
+% fmarginal(old_self, Fbelow, Fself, Qps, self)
+% hor_counts(i,k,j) = fmarginal(i,2,1,k,j) % below has finished, self has not
+% ver_counts(i,k,j) = fmarginal(i,2,2,k,j) % below has finished, and so has self (reset)
+% Since any of i,j,k may be observed, we write
+% hor_counts(i_counts_ndx, kndx, jndx) = fmarginal(i_fmarg_ndx...)
+% where i_fmarg_ndx = 1 and i_counts_ndx = i if old_self is observed to have value i,
+% i_fmarg_ndx = 1:Qsz and i_counts_ndx = 1:Qsz if old_self is hidden, etc.
+
+
+if hidden_bitv(old_self)
+  i_counts_ndx = 1:Qsz;
+  eff_oldQsz = Qsz;
+else
+  i_counts_ndx = evidence{old_self};
+  eff_oldQsz = 1;
+end
+
+if all(hidden_bitv(Qps)) % we assume all are hidden or all are observed
+  k_counts_ndx = 1:Qpsz;
+  eff_Qpsz = Qpsz;
+else
+  k_counts_ndx = subv2ind(Qpsz, cat(1, evidence{Qps}));
+  eff_Qpsz = 1;
+end
+
+if hidden_bitv(self)
+  j_counts_ndx = 1:Qsz;
+  eff_Qsz = Qsz;
+else
+  j_counts_ndx = evidence{self};
+  eff_Qsz = 1;
+end
+
+hor_counts = zeros(Qsz, Qpsz, Qsz);
+ver_counts = zeros(Qpsz, Qsz);
+    
+if ~isempty(CPD.Fbelow_ndx)
+  if ~isempty(CPD.Fself_ndx) % general case
+    fmarg = myreshape(fmarginal.T, [eff_oldQsz 2 2 eff_Qpsz eff_Qsz]);
+    hor_counts(i_counts_ndx, k_counts_ndx, j_counts_ndx) =  fmarg(:, 2, 1, :, :);
+    ver_counts(k_counts_ndx, j_counts_ndx) = ... % sum over Fbelow and Qold
+	sumv(fmarg(:, :,  2, :, :), [1 2]); % require Fself=2
+  else % no F from self, hence no startprob
+    fmarg = myreshape(fmarginal.T, [eff_oldQsz 2 eff_Qpsz eff_Qsz]);
+    hor_counts(i_counts_ndx, k_counts_ndx, j_counts_ndx) = ...
+	fmarg(:, 2, :, :); % require Fbelow = 2
+  end
+else % no F signal from below
+  if ~isempty(CPD.Fself_ndx) % self F
+    fmarg = myreshape(fmarginal.T, [eff_oldQsz 2 eff_Qpsz eff_Qsz]);
+    hor_counts(i_counts_ndx, k_counts_ndx, j_counts_ndx) =  fmarg(:, 1, :, :);
+    ver_counts(k_counts_ndx, j_counts_ndx) = ... % sum over Qold
+	squeeze(sum(fmarg(:, 2, :, :), 1)); % Fself=2
+  else % no F from self
+    error('An hhmmQ node without any F parents is just a tabular_CPD')
+  end
+end
+
+
+CPD.sub_CPD_trans = update_ess_simple(CPD.sub_CPD_trans, hor_counts);
+
+if ~isempty(CPD.sub_CPD_start)
+  CPD.sub_CPD_start = update_ess_simple(CPD.sub_CPD_start, ver_counts);
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/CVS/Entries
new file mode 100644
index 00000000..1cef220a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/CVS/Entries
@@ -0,0 +1,6 @@
+/convert_to_table.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/maximize_params.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mlp_CPD.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/reset_ess.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/update_ess.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/CVS/Repository
new file mode 100644
index 00000000..9fadd7fe
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@mlp_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/convert_to_table.m b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/convert_to_table.m
new file mode 100644
index 00000000..7e25d072
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/convert_to_table.m
@@ -0,0 +1,80 @@
+function T = convert_to_table(CPD, domain, evidence)
+% CONVERT_TO_TABLE Convert a mlp CPD to a table, incorporating any evidence 
+% T = convert_to_table(CPD, domain, evidence)
+
+self = domain(end);                    
+ps = domain(1:end-1);                               % self' parents                                       
+%cps = myintersect(ps, cnodes);                      % self' continous parents      
+cnodes     = domain(CPD.cpndx);
+cps        = myintersect(ps, cnodes);
+odom = domain(~isemptycell(evidence(domain)));      % obs nodes in the net
+assert(myismember(cps, odom));                      % !ALL the CTS parents must be observed!
+ns(cps)=1;
+dps = mysetdiff(ps, cps);                           % self' discrete parents                                                    
+dobs = myintersect(dps, odom);                      % discrete obs parents
+
+% Extract the params compatible with the observations (if any) on the discrete parents (if any)
+
+if ~isempty(dobs),
+    dvals = cat(1, evidence{dobs});             
+    ns_eff= CPD.sizes;                               % effective node sizes              
+    ens=ns_eff;
+    ens(dobs) = 1;                              
+    S=prod(ens(dps));
+    subs = ind2subv(ens(dps), 1:S);
+    mask = find_equiv_posns(dobs, dps);        
+    for i=1:length(mask),
+        subs(:,mask(i)) = dvals(i);
+    end     
+    support = subv2ind(ns_eff(dps), subs)';
+else 
+    ns_eff= CPD.sizes;
+    support=[1:prod(ns_eff(dps))];
+end
+
+W1=[]; b1=[]; W2=[]; b2=[];
+
+W1 = CPD.W1(:,:,support);
+b1= CPD.b1(support,:);
+W2 = CPD.W2(:,:,support);
+b2= CPD.b2(support,:);
+ns(odom) = 1;
+dpsize = prod(ns(dps));                             % overall size of the self' discrete parents  
+
+x = cat(1, evidence{cps});    
+ndata=size(x,2);
+
+if ~isempty(evidence{self})                         %
+    app=struct(CPD);                                %
+    ns(self)=app.mlp{1}.nout;                       % pump up self to the original dimension if observed
+    clear app;                                      %
+end                                                 %
+
+T =zeros(dpsize, ns(self));                         %
+for i=1:dpsize                                      %                 
+    W1app = W1(:,:,i);                              % 
+    b1app = b1(i,:);                                % 
+    W2app = W2(:,:,i);                              % 
+    b2app = b2(i,:);                                % for each of the dpsize combinations of self'parents values 
+    z = tanh(x(:)'*W1app + ones(ndata, 1)*b1app);   % we tabulate the corrisponding glm model
+    a = z*W2app + ones(ndata, 1)*b2app;             % (element of the cell array CPD.glim)
+    appoggio = normalise(exp(a));                   %
+    T(i,:)=appoggio;                                %
+    W1app=[]; W2app=[]; b1app=[]; b2app=[];         %
+    z=[]; a=[]; appoggio=[];                        %
+end                                                 %                
+
+if ~isempty(evidence{self})
+    appoggio=[];                            %
+    appoggio=zeros(1,ns(self));             %
+    r = evidence{self};                     %...if self is observed => in output there's only the probability of the 'true' class
+    for i=1:dpsize                          % 
+          appoggio(i)=T(i,r);               % 
+    end
+    T=zeros(dpsize,1);
+    for i=1:dpsize
+        T(i,1)=appoggio(i);                        
+    end
+    clear appoggio;
+    ns(self) = 1;
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/maximize_params.m b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/maximize_params.m
new file mode 100644
index 00000000..19d0a1be
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/maximize_params.m
@@ -0,0 +1,34 @@
+function CPD = maximize_params(CPD, temp)
+% MAXIMIZE_PARAMS Find ML params of an MLP using Scaled Conjugated Gradient (SCG)
+% CPD = maximize_params(CPD, temperature)
+% temperature parameter is ignored
+
+if ~adjustable_CPD(CPD), return; end
+options = foptions;
+
+% options(1) >= 0 means print an annoying message when the max. num. iter. is reached
+if CPD.verbose
+  options(1) = 1;
+else
+  options(1) = -1;
+end
+%options(1) = CPD.verbose;
+
+options(2) = CPD.wthresh;
+options(3) = CPD.llthresh;
+options(14) = CPD.max_iter;
+
+dpsz=length(CPD.mlp);
+
+for i=1:dpsz
+    mask=[];
+    mask=find(CPD.eso_weights(:,:,i)>0);    % for adapting the parameters we use only positive weighted example
+    if  ~isempty(mask),
+        CPD.mlp{i} = netopt_weighted(CPD.mlp{i}, options, CPD.parent_vals(mask',:), CPD.self_vals(mask',:,i), CPD.eso_weights(mask',:,i), 'scg');
+        
+        CPD.W1(:,:,i)=CPD.mlp{i}.w1;        % update the parameters matrix
+        CPD.b1(i,:)=CPD.mlp{i}.b1;          %
+        CPD.W2(:,:,i)=CPD.mlp{i}.w2;        % update the parameters matrix
+        CPD.b2(i,:)=CPD.mlp{i}.b2;          %
+    end
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/mlp_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/mlp_CPD.m
new file mode 100644
index 00000000..7e9d3f6b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/mlp_CPD.m
@@ -0,0 +1,139 @@
+function CPD = mlp_CPD(bnet, self, nhidden, w1, b1, w2, b2, clamped, max_iter, verbose, wthresh,  llthresh)
+% MLP_CPD Make a CPD from a Multi Layer Perceptron (i.e., feedforward neural network)
+%
+% We use a different MLP for each discrete parent combination (if there are any discrete parents).
+% We currently assume this node (the child) is discrete.
+%
+% CPD = mlp_CPD(bnet, self, nhidden)
+% will create a CPD with random parameters, where self is the number of this node and nhidden the number of the hidden nodes.
+% The params are drawn from N(0, s*I), where s = 1/sqrt(n+1), n = length(X).
+%
+% CPD = mlp_CPD(bnet, self, nhidden, w1, b1, w2, b2) allows you to specify the params, where
+%  w1 = first-layer weight matrix
+%  b1 = first-layer bias vector
+%  w2 = second-layer weight matrix
+%  b2 = second-layer bias vector
+% These are assumed to be the same for each discrete parent combination.
+% If any of these are [], random values will be created.
+%
+% CPD = mlp_CPD(bnet, self, nhidden, w1, b1, w2, b2, clamped) allows you to prevent the params from being
+% updated during learning (if clamped = 1). Default: clamped = 0.
+%
+% CPD = mlp_CPD(bnet, self, nhidden, w1, b1, w2, b2, clamped, max_iter, verbose, wthresh,  llthresh)
+% alllows you to specify params that control the M step:
+%  max_iter - the maximum number of steps to take (default: 10)
+%  verbose - controls whether to print (default: 0 means silent).
+%  wthresh - a measure of the precision required for the value of
+%     the weights W at the solution. Default: 1e-2.
+%  llthresh - a measure of the precision required of the objective
+%     function (log-likelihood) at the solution.  Both this and the previous condition must
+%     be satisfied for termination. Default: 1e-2.
+%
+% For learning, we use a weighted version of scaled conjugated gradient in the M step.
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  CPD = class(CPD, 'mlp_CPD', discrete_CPD(0,[]));
+  return;
+elseif isa(bnet, 'mlp_CPD')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+CPD = init_fields;
+
+assert(myismember(self, bnet.dnodes));
+ns = bnet.node_sizes;
+
+ps = parents(bnet.dag, self);
+dnodes = mysetdiff(1:length(bnet.dag), bnet.cnodes);
+dps = myintersect(ps, dnodes);
+cps = myintersect(ps, bnet.cnodes);
+dpsz = prod(ns(dps));
+cpsz = sum(ns(cps));
+self_size = ns(self);
+
+% discrete/cts parent index - which ones of my parents are discrete/cts?
+CPD.dpndx = find_equiv_posns(dps, ps); 
+CPD.cpndx = find_equiv_posns(cps, ps);
+
+CPD.mlp = cell(1,dpsz);
+for i=1:dpsz
+    CPD.mlp{i} = mlp(cpsz, nhidden, self_size, 'softmax');
+    if nargin >=4 & ~isempty(w1)
+        CPD.mlp{i}.w1 = w1;
+    end
+    if nargin >=5 & ~isempty(b1)
+        CPD.mlp{i}.b1 = b1; 
+    end
+    if nargin >=6 & ~isempty(w2)
+        CPD.mlp{i}.w2 = w2; 
+    end
+    if nargin >=7 & ~isempty(b2)
+        CPD.mlp{i}.b2 = b2; 
+    end
+    W1app(:,:,i)=CPD.mlp{i}.w1;
+    W2app(:,:,i)=CPD.mlp{i}.w2;
+    b1app(i,:)=CPD.mlp{i}.b1;
+    b2app(i,:)=CPD.mlp{i}.b2;
+end
+if nargin < 8, clamped = 0; end
+if nargin < 9, max_iter = 10; end
+if nargin < 10, verbose = 0; end
+if nargin < 11, wthresh = 1e-2; end
+if nargin < 12, llthresh = 1e-2; end
+
+CPD.self = self;
+CPD.max_iter = max_iter;
+CPD.verbose = verbose;
+CPD.wthresh = wthresh;
+CPD.llthresh = llthresh;
+
+% sufficient statistics 
+% Since MLP is not in the exponential family, we must store all the raw data.
+%
+CPD.W1=W1app;                     % Extract all the parameters of the node for handling discrete obs parents
+CPD.W2=W2app;                     %
+nparaW=[size(W1app) size(W2app)]; %
+CPD.b1=b1app;                     %
+CPD.b2=b2app;                     %
+nparab=[size(b1app) size(b2app)]; %
+
+CPD.sizes=bnet.node_sizes(:);   % used in CPD_to_table to pump up the node sizes
+
+CPD.parent_vals = [];        % X(l,:) = value of cts parents in l'th example
+
+CPD.eso_weights=[];          % weights used by the SCG algorithm 
+
+CPD.self_vals = [];          % Y(l,:) = value of self in l'th example
+
+% For BIC
+CPD.nsamples = 0;   
+CPD.nparams=prod(nparaW)+prod(nparab);
+CPD = class(CPD, 'mlp_CPD', discrete_CPD(clamped, ns([ps self])));
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.mlp = {};
+CPD.self = [];
+CPD.max_iter = [];
+CPD.verbose = [];
+CPD.wthresh = [];
+CPD.llthresh = [];
+CPD.approx_hess = [];
+CPD.W1 = [];
+CPD.W2 = [];
+CPD.b1 = [];
+CPD.b2 = [];
+CPD.sizes = [];
+CPD.parent_vals = [];
+CPD.eso_weights=[];
+CPD.self_vals = [];
+CPD.nsamples = [];
+CPD.nparams = [];
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/reset_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/reset_ess.m
new file mode 100644
index 00000000..ba7a7101
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/reset_ess.m
@@ -0,0 +1,12 @@
+function CPD = reset_ess(CPD)
+% RESET_ESS Reset the Expected Sufficient Statistics for a CPD (mlp)
+% CPD = reset_ess(CPD)
+
+CPD.W1 = [];
+CPD.W2 = [];
+CPD.b1 = [];
+CPD.b2 = [];
+CPD.parent_vals = [];
+CPD.eso_weights=[];
+CPD.self_vals = [];
+CPD.nsamples = 0;  
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/update_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/update_ess.m
new file mode 100644
index 00000000..353a0b5c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@mlp_CPD/update_ess.m
@@ -0,0 +1,131 @@
+function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+% UPDATE_ESS Update the Expected Sufficient Statistics of a CPD (MLP)
+% CPD = update_ess(CPD, family_marginal, evidence, node_sizes, cnodes, hidden_bitv)
+%
+% fmarginal = overall posterior distribution of self and its parents
+% fmarginal(i1,i2...,ik,s)=prob(Pa1=i1,...,Pak=ik, self=s| X)
+% 
+% => 1) prob(self|Pa1,...,Pak)=fmarginal/prob(Pa1,...,Pak) with prob(Pa1,...,Pak)=sum{s,fmarginal}
+%       [self estimation -> CPD.self_vals]
+% 	  2) prob(Pa1,...,Pak) [SCG weights -> CPD.eso_weights]
+%
+% Hidden_bitv is ignored
+
+% Written by Pierpaolo Brutti
+
+if ~adjustable_CPD(CPD), return; end
+
+dom = fmarginal.domain;                              
+cdom = myintersect(dom, cnodes);                     
+assert(~any(isemptycell(evidence(cdom))));           
+ns(cdom)=1;
+
+self = dom(end);                                  
+ps=dom(1:end-1);                                     
+dpdom=mysetdiff(ps,cdom);                            
+
+dnodes = mysetdiff(1:length(ns), cnodes);            
+
+ddom = myintersect(ps, dnodes);                      %
+if isempty(evidence{self}),                          % if self is hidden in what follow we must 
+    ddom = myintersect(dom, dnodes);                 % consider its dimension
+end                                                  % 
+
+odom = dom(~isemptycell(evidence(dom)));    
+hdom = dom(isemptycell(evidence(dom)));              % hidden parents in domain
+ 
+dobs = myintersect(ddom, odom);             
+dvals = cat(1, evidence{dobs});             
+ens = ns;                                            % effective node sizes              
+ens(dobs) = 1;                              
+                                            
+dpsz=prod(ns(dpdom));
+S=prod(ens(ddom));
+subs = ind2subv(ens(ddom), 1:S);
+mask = find_equiv_posns(dobs, ddom);
+for i=1:length(mask),
+    subs(:,mask(i)) = dvals(i);
+end
+supportedQs = subv2ind(ns(ddom), subs);
+
+Qarity = prod(ns(ddom));
+if isempty(ddom),                      
+  Qarity = 1;                         
+end                                
+fullm.T = zeros(Qarity, 1);
+fullm.T(supportedQs) = fmarginal.T(:);
+
+% For dynamic (recurrent) net-------------------------------------------------------------
+% ----------------------------------------------------------------------------------------
+high=size(evidence,1);                                  % slice height
+ss_ns=ns(1:high);                                       % single slice nodes sizes
+pos=self;                                               %
+slice_num=0;                                            %
+while pos>high,                                         % 
+    slice_num=slice_num+1;                              % find active slice
+    pos=pos-high;                                       % pos=self posistion into a single slice
+end                                                     %
+
+last_dim=pos-1;                                         % 
+if isempty(evidence{self}),                             % 
+    last_dim=pos;                                       %
+end                                                     % last_dim=last reshaping dimension      
+reg=dom-slice_num*high;
+dex=myintersect(reg(find(reg>=0)), [1:last_dim]);       %           
+rs_dim=ss_ns(dex);                                      % reshaping dimensions
+
+if slice_num>0,
+    act_slice=[]; past_ancest=[];                       %
+    act_slice=slice_num*high+[1:high];                  % recover the active slice nodes
+    % past_ancest=mysetdiff(ddom, act_slice);
+    past_ancest=mysetdiff(ps, act_slice);               % recover ancestors contained into past slices
+    app=ns(past_ancest);
+    rs_dim=[app(:)' rs_dim(:)'];                        %
+end                                                     %
+if length(rs_dim)==1, rs_dim=[1 rs_dim]; end            %
+if size(rs_dim,1)~=1, rs_dim=rs_dim';    end            %
+
+fullm.T=reshape(fullm.T, rs_dim);                       % reshaping the marginal
+
+% ----------------------------------------------------------------------------------------
+% ----------------------------------------------------------------------------------------
+
+% X = cts parent, R = discrete self
+
+% 1) observations vector -> CPD.parents_vals -------------------------------------------------
+x = cat(1, evidence{cdom});
+
+% 2) weights vector -> CPD.eso_weights -------------------------------------------------------
+if isempty(evidence{self}) % R is hidden
+    sum_over=length(rs_dim);
+    app=sum(fullm.T, sum_over);    
+    pesi=reshape(app,[dpsz,1]);
+    clear app;
+else
+    pesi=reshape(fullm.T,[dpsz,1]);
+end
+
+assert(approxeq(sum(pesi),1));
+
+% 3) estimate (if R is hidden) or recover (if R is obs) self'value----------------------------
+if isempty(evidence{self})              % R is hidden    
+    app=mk_stochastic(fullm.T);         % P(self|Pa1,...,Pak)=fmarginal/prob(Pa1,...,Pak)
+    app=reshape(app,[dpsz ns(self)]);   % matrix size: prod{j,ns(Paj)} x ns(self)      
+    r=app;
+    clear app;
+else
+    r = zeros(dpsz,ns(self));
+    for i=1:dpsz
+        if pesi(i)~=0, r(i,evidence{self}) = 1; end
+    end
+end
+for i=1:dpsz
+    if pesi(i) ~=0, assert(approxeq(sum(r(i,:)),1)); end
+end
+
+CPD.nsamples = CPD.nsamples + 1;            
+CPD.parent_vals(CPD.nsamples,:) = x(:)';
+for i=1:dpsz
+    CPD.eso_weights(CPD.nsamples,:,i)=pesi(i);
+    CPD.self_vals(CPD.nsamples,:,i) = r(i,:); 
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m
new file mode 100644
index 00000000..93a6dcef
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m
@@ -0,0 +1,34 @@
+function CPT = CPD_to_CPT(CPD)
+% CPD_TO_CPT Convert the discrete CPD to tabular form (noisyor)
+% CPT = CPD_to_CPT(CPD)
+%
+% CPT(U1,...,Un, X) = Pr(X|U1,...,Un) where the Us are the parents (excluding leak).
+
+if ~isempty(CPD.CPT)
+  CPT = CPD.CPT; % remember to flush cache if params change (e.g., during learning)
+  return;
+end
+
+q = [CPD.leak_inhibit CPD.inhibit(:)'];
+% q(i) is the prob. that the i'th parent will be inhibited (flipped from 1 to 0).
+% q(1) is the leak inhibition probability, and length(q) = n + 1.
+
+if length(q)==1
+  CPT = [q  1-q];
+  return;
+end
+
+n = length(q);
+Bn = ind2subv(2*ones(1,n), 1:(2^n))-1;  % all n bit vectors, with the left most column toggling fastest (LSB)
+CPT = zeros(2^n, 2);
+% Pr(X=0 | U_1 .. U_n) = prod_{i: U_i = on} q_i =  prod_i q_i ^ U_i = exp(u' * log(q_i))
+% This method is problematic when q contains zeros
+
+Q = repmat(q(:)', 2^n, 1);
+Q(logical(~Bn)) = 1;
+CPT(:,1) = prod(Q,2);
+CPT(:,2) = 1-CPT(:,1);
+
+CPT = reshape(CPT(2:2:end), 2*ones(1,n)); % skip cases in which the leak is off       
+
+CPD.CPT = CPT;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m~ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m~
new file mode 100644
index 00000000..6f4cacd4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_CPT.m~
@@ -0,0 +1,70 @@
+function CPT = CPD_to_CPT(CPD)
+% CPD_TO_CPT Convert the discrete CPD to tabular form (noisyor)
+% CPT = CPD_to_CPT(CPD)
+%
+% CPT(U1,...,Un, X) = Pr(X|U1,...,Un) where the Us are the parents (excluding leak).
+
+if ~isempty(CPD.CPT)
+  CPT = CPD.CPT; % remember to flush cache if params change (e.g., during learning)
+  return;
+end
+
+q = [CPD.leak_inhibit CPD.inhibit(:)'];
+% q(i) is the prob. that the i'th parent will be inhibited (flipped from 1 to 0).
+% q(1) is the leak inhibition probability, and length(q) = n + 1.
+
+if length(q)==1
+  CPT = [q  1-q];
+  return;
+end
+
+n = length(q);
+Bn = ind2subv(2*ones(1,n), 1:(2^n))-1;  % all n bit vectors, with the left most column toggling fastest (LSB)
+CPT = zeros(2^n, 2);
+% Pr(X=0 | U_1 .. U_n) = prod_{i: U_i = on} q_i =  prod_i q_i ^ U_i = exp(u' * log(q_i))
+% This method is problematic when q contains zeros
+
+Q = repmat(q(:)', 2^n, 1);
+Q(logical(~Bn)) = 1;
+CPT(:,1) = prod(Q,2);
+CPT(:,2) = 1-CPT(:,1);
+
+CPT = reshape(CPT(2:2:end), 2*ones(1,n)); % skip cases in which the leak is off       
+
+CPD.CPT = CPT;
+
+function CPT = CPD_to_CPT(CPD)
+% CPD_TO_CPT Convert the discrete CPD to tabular form (noisyor)
+% CPT = CPD_to_CPT(CPD)
+%
+% CPT(U1,...,Un, X) = Pr(X|U1,...,Un) where the Us are the parents (excluding leak).
+
+if ~isempty(CPD.CPT)
+  CPT = CPD.CPT; % remember to flush cache if params change (e.g., during learning)
+  return;
+end
+
+q = [CPD.leak_inhibit CPD.inhibit(:)'];
+% q(i) is the prob. that the i'th parent will be inhibited (flipped from 1 to 0).
+% q(1) is the leak inhibition probability, and length(q) = n + 1.
+
+if length(q)==1
+  CPT = [q  1-q];
+  return;
+end
+
+n = length(q);
+Bn = ind2subv(2*ones(1,n), 1:(2^n))-1;  % all n bit vectors, with the left most column toggling fastest (LSB)
+CPT = zeros(2^n, 2);
+% Pr(X=0 | U_1 .. U_n) = prod_{i: U_i = on} q_i =  prod_i q_i ^ U_i = exp(u' * log(q_i))
+% This method is problematic when q contains zeros
+
+Q = repmat(q(:)', 2^n, 1);
+Q(logical(~Bn)) = 1;
+CPT(:,1) = prod(Q,2);
+CPT(:,2) = 1-CPT(:,1);
+
+CPT = reshape(CPT(2:2:end), 2*ones(1,n)); % skip cases in which the leak is off       
+
+CPD.CPT = CPT;
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_lambda_msg.m b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_lambda_msg.m
new file mode 100644
index 00000000..8046c860
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_lambda_msg.m
@@ -0,0 +1,19 @@
+function lam_msg = CPD_to_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence)
+% CPD_TO_LAMBDA_MSG Compute lambda message (noisyor)
+% lam_msg = CPD_to_lambda_msg(CPD, msg_type, n, ps, msg, p)
+% Pearl p190 top eqn
+
+switch msg_type
+  case 'd', 
+   l0 = msg{n}.lambda(1);
+   l1 = msg{n}.lambda(2);
+   Pi = sum_prod_CPD_and_pi_msgs(CPD, n, ps, msg, p);
+   i = find(p==ps); % p is n's i'th parent
+   q = CPD.inhibit(i);
+   lam_msg = zeros(2,1);
+   for u=0:1
+     lam_msg(u+1) = l1 - (q^u)*(l1 - l0)*Pi;
+   end       
+ case 'g',
+  error('noisyor_CPD can''t create Gaussian msgs')
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_pi.m b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_pi.m
new file mode 100644
index 00000000..6955f115
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CPD_to_pi.m
@@ -0,0 +1,12 @@
+function pi = CPD_to_pi(CPD, msg_type, n, ps, msg, evidence)
+% CPD_TO_PI Compute pi vector (noisyor)
+% pi = CPD_to_pi(CPD, msg_type, n, ps, msg)
+% Pearl p188 eqn 4.57
+  
+switch msg_type
+ case 'd',
+   pi = sum_prod_CPD_and_pi_msgs(CPD, n, ps, msg);
+   pi = [pi 1-pi]';
+ case 'g', 
+  error('can''t convert noisy-or CPD to Gaussian pi')
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries
new file mode 100644
index 00000000..4cfae75b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries
@@ -0,0 +1,5 @@
+/CPD_to_CPT.m/1.1.1.1/Mon Aug  2 22:23:32 2004//
+/CPD_to_lambda_msg.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/CPD_to_pi.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/noisyor_CPD.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries.Log
new file mode 100644
index 00000000..b2cd71e0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/private////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Repository
new file mode 100644
index 00000000..a3f1a38a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@noisyor_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/noisyor_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/noisyor_CPD.m
new file mode 100644
index 00000000..aecf9b6d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/noisyor_CPD.m
@@ -0,0 +1,79 @@
+function CPD = noisyor_CPD(bnet, self, leak_inhibit, inhibit)
+% NOISYOR_CPD Make a noisy-or CPD
+% CPD = NOISYOR_CPD(BNET, NODE_NUM, LEAK_INHIBIT, INHIBIT)
+%
+% A noisy-or node turns on if any of its parents are on, provided they are not inhibited.
+% The prob. that the i'th parent gets inhibited (flipped from 1 to 0) is inhibit(i).
+% The prob that the leak node (a dummy parent that is always on) gets inhibit is leak_inhibit.
+% These params default to random values if omitted.
+%
+% Example: suppose C has parents A and B, and the
+% link of A->C fails with prob pA and the link B->C fails with pB.
+% Then the noisy-OR gate defines the following distribution
+%
+%  A  B  P(C=0)
+%  0  0  1.0
+%  1  0  pA
+%  0  1  pB
+%  1  1  pA * PB
+%
+% Currently, learning is not supported for noisy-or nodes
+% (since the M step is somewhat complicated).
+%
+% For simple generalizations of the noisy-OR model, see e.g.,
+% - Srinivas, "A generalization of the noisy-OR model", UAI 93
+% - Meek and Heckerman, "Learning Causal interaction models", UAI 97.
+  
+
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  CPD = class(CPD, 'noisyor_CPD', discrete_CPD(1, []));
+  return;
+elseif isa(bnet, 'noisyor_CPD')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+CPD = init_fields;
+
+
+ps = parents(bnet.dag, self);
+fam = [ps self];
+ns = bnet.node_sizes;
+assert(all(ns(fam)==2));
+assert(isempty(myintersect(fam, bnet.cnodes)));
+
+if nargin < 3, leak_inhibit = rand(1, 1); end
+if nargin < 4, inhibit = rand(1, length(ps)); end
+
+CPD.self = self;
+CPD.inhibit = inhibit;
+CPD.leak_inhibit = leak_inhibit;
+
+
+% For BIC
+CPD.nparams = 0;
+CPD.nsamples = 0;
+
+CPD.CPT = []; % cached copy, to speed up CPD_to_CPT
+
+clamped = 1;
+CPD = class(CPD, 'noisyor_CPD', discrete_CPD(clamped, ns([ps self])));
+
+
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.self = [];
+CPD.inhibit = [];
+CPD.leak_inhibit = [];
+CPD.nparams = [];
+CPD.nsamples = [];
+CPD.CPT = [];
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Entries
new file mode 100644
index 00000000..b56c53ed
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Entries
@@ -0,0 +1,2 @@
+/sum_prod_CPD_and_pi_msgs.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Repository
new file mode 100644
index 00000000..716dfddd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@noisyor_CPD/private
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/sum_prod_CPD_and_pi_msgs.m b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/sum_prod_CPD_and_pi_msgs.m
new file mode 100644
index 00000000..9ca31d3c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@noisyor_CPD/private/sum_prod_CPD_and_pi_msgs.m
@@ -0,0 +1,25 @@
+function pi = sum_prod_CPD_and_pi_msgs(CPD, n, ps, msg, except)
+% SUM_PROD_CPD_AND_PI_MSGS Compute pi = sum_{u\p} P(n|u) prod_{ui in ps\p} pi_msg(ui->n)
+% pi = sum_prod_CPD_and_pi_msgs(CPD, n, ps, msg, p)
+%
+% pi  = prod_i (qi pi_msg(ui->n) + 1 - pi_msg(ui->n)) = prod_i (1 - ci pi_msg(ui->n))
+% is the product of the endorsement withheld (Pearl p188 eqn 4.56)
+% We skip p from this product, if specified.
+
+if nargin < 5, except = -1; end
+pi = 1;
+for i=1:length(ps)
+  p = ps(i);
+  if p ~= except
+    pi_from_parent = msg{n}.pi_from_parent{i};
+    q = CPD.inhibit(i);
+    c = 1-q;
+    pi = pi * (1 - c*pi_from_parent(2));
+  end
+end
+% The pi msg that a leak node sends to its child is [0 1]
+% since its own pi is [0 1] and its lambda to self is [0 1].
+q = CPD.leak_inhibit;
+% 1 - c*pi_from_parent = 1-c*1 = q
+pi = pi * q;
+                 
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CPD_to_pi.m b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CPD_to_pi.m
new file mode 100644
index 00000000..65f4eb5e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CPD_to_pi.m
@@ -0,0 +1,12 @@
+function pi = CPD_to_pi(CPD, msg_type, n, ps, msg, evidence)
+% CPD_TO_PI Compute the pi vector (root)
+% function pi = CPD_to_pi(CPD, msg_type, n, ps, msg, evidence)
+
+self_ev = evidence{n};
+switch msg_type
+ case 'd',
+  error('root_CPD can''t create discrete msgs')
+ case 'g',
+  pi.mu = self_ev;
+  pi.Sigma = zeros(size(self_ev));
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Entries
new file mode 100644
index 00000000..215e86ce
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Entries
@@ -0,0 +1,7 @@
+/CPD_to_pi.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/convert_to_pot.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/log_marg_prob_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/log_prob_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/root_CPD.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Repository
new file mode 100644
index 00000000..0f9893ad
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@root_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CPD_to_CPT.m b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CPD_to_CPT.m
new file mode 100644
index 00000000..ffc23a75
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CPD_to_CPT.m
@@ -0,0 +1,5 @@
+function CPT = CPD_to_CPT(CPD)
+% CPD_TO_CPT Convert the CPD to tabular form (root)
+% CPT = CPD_to_CPT(CPD)
+
+CPT = 1;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CVS/Entries
new file mode 100644
index 00000000..7c0869aa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CVS/Entries
@@ -0,0 +1,2 @@
+/CPD_to_CPT.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CVS/Repository
new file mode 100644
index 00000000..ac53f91a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@root_CPD/Old
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/convert_to_pot.m b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/convert_to_pot.m
new file mode 100644
index 00000000..6a25f1aa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/convert_to_pot.m
@@ -0,0 +1,28 @@
+function pot = convert_to_pot(CPD, pot_type, domain, evidence)
+% CONVERT_TO_POT Convert a root CPD to one or more potentials
+% pots = convert_to_pot(CPD, pot_type, domain, evidence)
+
+assert(length(domain)==1);
+assert(~isempty(evidence(domain)));
+T = 1;   
+
+sz = CPD.sizes;
+ns = zeros(1, max(domain));
+ns(domain) = sz;
+
+switch pot_type
+ case 'u',
+  pot = upot(domain, 1, T, 0);
+ case 'd',
+  ns(domain) = 1;
+  pot = dpot(domain, ns(domain), T);          
+ case {'c','g'},
+  ns(domain) = 0;
+  pot = cpot(domain, ns(domain), 0);
+ case 'cg',
+  ddom = [];
+  cdom = domain; % we assume the root node is cts
+  %pot = cgpot(ddom, cdom, ns, {cpot([],[],0)});
+  pot = cgpot(ddom, cdom, ns);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/log_marg_prob_node.m b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/log_marg_prob_node.m
new file mode 100644
index 00000000..f45d3f4c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/log_marg_prob_node.m
@@ -0,0 +1,9 @@
+function L = log_marg_prob_node(CPD, self_ev, pev)
+% LOG_MARG_PROB_NODE Compute prod_m log int_{theta_i} P(x(i,m)| x(pi_i,m), theta_i) for node i (root)
+% L = log_marg_prob_node(CPD, self_ev, pev)
+%
+% self_ev{m} is the evidence on this node in case m
+% pev{i,m} is the evidence on the i'th parent in case m (ignored)
+% We always return L = 0.
+
+L = 0;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/log_prob_node.m b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/log_prob_node.m
new file mode 100644
index 00000000..8d549631
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/log_prob_node.m
@@ -0,0 +1,9 @@
+function L = log_prob_node(CPD, self_ev, pev)
+% LOG_PROB_NODE Compute prod_m log P(x(i,m)| x(pi_i,m), theta_i) for node i (root)
+% L = log_prob_node(CPD, self_ev, pev)
+%
+% self_ev{m} is the evidence on this node in case m
+% pev{i,m} is the evidence on the i'th parent in case m (ignored)
+% We always return L = 0.
+
+L = 0;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/root_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/root_CPD.m
new file mode 100644
index 00000000..b07df1e5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/root_CPD.m
@@ -0,0 +1,48 @@
+function CPD = root_CPD(bnet, self, val)
+% ROOT_CPD Make a conditional prob. distrib. which has no parameters.
+% CPD = ROOT_CPD(BNET, NODE_NUM, VAL)
+%
+% The node must not have any parents and is assumed to always be observed.
+% It is a way of modelling exogenous inputs to a model.
+% VAL is the value to which the root is clamped (default: [])
+
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  CPD = class(CPD, 'root_CPD', generic_CPD(1));
+  return;
+elseif isa(bnet, 'root_CPD')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+CPD = init_fields;
+
+
+if nargin < 3, val = []; end
+
+ns = bnet.node_sizes;
+ps = parents(bnet.dag, self);
+if ~isempty(ps)
+  error('root CPDs should have no parents')
+end
+
+CPD.self = self;
+CPD.val = val;
+CPD.sizes = ns(self);
+
+clamped = 1;
+CPD = class(CPD, 'root_CPD', generic_CPD(clamped));
+
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.self = [];
+CPD.val = [];
+CPD.sizes = [];
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/sample_node.m b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/sample_node.m
new file mode 100644
index 00000000..5ced75f4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@root_CPD/sample_node.m
@@ -0,0 +1,9 @@
+function y = sample_node(CPD, pev)
+% SAMPLE_NODE Draw a random sample from P(Y|pa(y), theta)  (root)
+% Y = SAMPLE_NODE(CPD, PEV)
+%
+% pev{i} is the evidence on the i'th parent.
+% Since a root has no parents, we ignore pev,
+% and return the value the root was clamped to when it was created.
+
+y = CPD.val;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Entries
new file mode 100644
index 00000000..1e0984dc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Entries
@@ -0,0 +1,11 @@
+/convert_to_pot.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/convert_to_table.m/1.1.1.1/Tue Mar 30 17:19:22 2004//
+/display.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/get_field.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/maximize_params.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/reset_ess.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/set_fields.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/softmax_CPD.m/1.1.1.1/Tue Jan  7 16:25:14 2003//
+/update_ess.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Entries.Log
new file mode 100644
index 00000000..b2cd71e0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/private////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Repository
new file mode 100644
index 00000000..d5dac28b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@softmax_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/convert_to_pot.m b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/convert_to_pot.m
new file mode 100644
index 00000000..518f4a50
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/convert_to_pot.m
@@ -0,0 +1,58 @@
+function pot = convert_to_pot(CPD, pot_type, domain, evidence)
+% CONVERT_TO_POT Convert a softmax CPD to a potential
+% pots = convert_to_pot(CPD, pot_type, domain, evidence)
+%
+% pots = CPD evaluated using evidence(domain)
+
+ncases = size(domain,2);
+assert(ncases==1); % not yet vectorized
+
+sz = dom_sizes(CPD);
+ns = zeros(1, max(domain));
+ns(domain) = sz;
+
+odom = domain(~isemptycell(evidence(domain)));
+T = convert_to_table(CPD, domain, evidence);
+
+switch pot_type
+ case 'u',
+  pot = upot(domain, sz, T, 0*myones(sz));  
+ case 'd',
+  ns(odom) = 1;
+  pot = dpot(domain, ns(domain), T);          
+ 
+ case {'c','g'},
+  % Since we want the output to be a Gaussian, the whole family must be observed.
+  % In other words, the potential is really just a constant.
+  p = T;
+  %p = prob_node(CPD, evidence(domain(end)), evidence(domain(1:end-1)));
+  ns(domain) = 0;
+  pot = cpot(domain, ns(domain), log(p));       
+ 
+ case 'cg',
+  T = T(:);
+  ns(odom) = 1;
+  can = cell(1, length(T));
+  for i=1:length(T)
+    can{i} = cpot([], [], log(T(i)));
+  end
+  ps = domain(1:end-1);
+  dps = ps(CPD.dpndx);
+  cps = ps(CPD.cpndx);
+  ddom = [dps CPD.self];
+  cdom = cps;
+  pot = cgpot(ddom, cdom, ns, can);   
+  
+ case 'scg'
+  T = T(:);
+  ns(odom) = 1;
+  pot_array = cell(1, length(T));
+  for i=1:length(T)
+    pot_array{i} = scgcpot([], [], T(i));
+  end
+  pot = scgpot(domain, [], [], ns, pot_array);   
+
+ otherwise,
+  error(['unrecognized pot type ' pot_type])
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/convert_to_table.m b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/convert_to_table.m
new file mode 100644
index 00000000..f703d79b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/convert_to_table.m
@@ -0,0 +1,52 @@
+function T = convert_to_table(CPD, domain, evidence)
+% CONVERT_TO_TABLE Convert a softmax CPD to a table, incorporating any evidence 
+% T = convert_to_table(CPD, domain, evidence)
+
+self       = domain(end);             
+ps         = domain(1:end-1);                            
+cnodes     = domain(CPD.cpndx);
+cps        = myintersect(ps, cnodes);
+dps        = domain(CPD.dpndx); 
+dps_as_cps = domain(CPD.dps_as_cps.ndx);
+all_dps    = union(dps,dps_as_cps);
+odom       = domain(~isemptycell(evidence(domain))); 
+if ~isempty(cps), assert(myismember(cps, odom)); end % all cts parents must be observed
+
+ns         = zeros(1, max(domain));
+ns(domain) = CPD.sizes;
+ens        = ns; % effective node sizes
+ens(odom)  = 1;
+
+% dpsize >= glimsz because the glm parameters are tied across the dps_as_cps parents
+dpsize       = prod(ens(all_dps)); % size of ALL self'discrete parents
+dpvals       = cat(1, evidence{myintersect(all_dps, odom)});
+cpvals       = cat(1, evidence{cps});
+if ~isempty(dps_as_cps),
+  separator          = CPD.dps_as_cps.separator;
+  dp_as_cpmap        = find_equiv_posns(dps_as_cps, all_dps);
+  dops_map           = find_equiv_posns(myintersect(all_dps, odom), all_dps);
+  puredp_map         = find_equiv_posns(dps, all_dps);
+  subs               = ind2subv(ens(all_dps), 1:prod(ens(all_dps)));
+  if ~isempty(dops_map), subs(:,dops_map) = subs(:,dops_map)+repmat(dpvals(:)',[size(subs,1) 1])-1; end
+end
+
+[w,b] = extract_params(CPD);
+T = zeros(dpsize, ns(self));                                       
+for i=1:dpsize,    
+  active_glm  = i;
+  dp_as_cpvals=zeros(1,sum(ns(dps_as_cps)));                                                                  
+  if ~isempty(dps_as_cps),                          
+    active_glm = max([1,subv2ind(ns(dps), subs(i,puredp_map))]);
+    % Extract the params compatible with the observations (if any) on the 'pure' discrete parents (if any)
+    where_one = separator + subs(i,dp_as_cpmap);
+    % and get in the dp_as_cp parents...
+    dp_as_cpvals(where_one)=1;                    
+  end                                               
+  T(i,:) = normalise(exp([dp_as_cpvals(:); cpvals(:)]'*w(:,:,active_glm) + b(:,active_glm)'));
+end
+if myismember(self, odom)
+  r = evidence{self};
+  T = T(:,r);
+end
+
+T = myreshape(T, ens(domain));
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/display.m b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/display.m
new file mode 100644
index 00000000..06a0f02c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/display.m
@@ -0,0 +1,4 @@
+function display(CPD)
+
+disp('softmax_CPD object');
+disp(struct(CPD)); 
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/get_field.m b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/get_field.m
new file mode 100644
index 00000000..240f1fd7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/get_field.m
@@ -0,0 +1,18 @@
+function val = get_params(CPD, name)
+% GET_PARAMS Get the parameters (fields) for a softmax_CPD object
+% val = get_params(CPD, name)
+%
+% The following fields can be accessed
+%
+% weights - W(X,Y,Q)
+% offset  - b(Y,Q)
+%
+% e.g., W = get_params(CPD, 'weights')
+
+[W, b] = extract_params(CPD);
+switch name
+ case 'weights',   val = W;
+ case 'offset',    val = b;
+ otherwise,
+  error(['invalid argument name ' name]);
+end                
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/maximize_params.m b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/maximize_params.m
new file mode 100644
index 00000000..15c94dd5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/maximize_params.m
@@ -0,0 +1,41 @@
+function CPD = maximize_params(CPD, temp)
+% MAXIMIZE_PARAMS Set the params of a CPD to their ML values (dsoftmax) using IRLS
+% CPD = maximize_params(CPD, temperature)
+% temperature parameter is ignored
+
+% Written by Pierpaolo Brutti
+
+if ~adjustable_CPD(CPD), return; end
+options = foptions;
+
+if CPD.verbose
+  options(1) = 1;
+else
+  options(1) = -1;
+end
+%options(1) = CPD.verbose;
+
+options(2) = CPD.wthresh;
+options(3) = CPD.llthresh;
+options(5) = CPD.approx_hess;
+options(14) = CPD.max_iter;
+
+dpsize = size(CPD.self_vals,3);
+for i=1:dpsize,
+  mask=find(CPD.eso_weights(:,:,i)>0); % for adapting the parameters we use only positive weighted example
+  if  ~isempty(mask),
+    if ~isempty(CPD.dps_as_cps.ndx),
+        puredp_map = find_equiv_posns(CPD.dpndx, union(CPD.dpndx, CPD.dps_as_cps.ndx)); % find the glm  structure
+        subs       = ind2subv(CPD.sizes(union(CPD.dpndx, CPD.dps_as_cps.ndx)),i);       % that corrisponds to the
+        active_glm = max([1,subv2ind(CPD.sizes(CPD.dpndx), subs(puredp_map))]);         % i-th 'fictitious' example
+        
+        CPD.glim{active_glm} = netopt_weighted(CPD.glim{active_glm}, options, CPD.parent_vals(mask',:,i),...
+            CPD.self_vals(mask',:,i), CPD.eso_weights(mask',:,i), 'scg');
+    else
+        alfa = 0.4; if CPD.solo, alfa = 1; end % learning step = 1 <=> self is all alone in the net
+        CPD.glim{i} = glmtrain_weighted(CPD.glim{i}, options, CPD.parent_vals(mask',:),...
+            CPD.self_vals(mask',:,i), CPD.eso_weights(mask',:,i), alfa);
+    end               
+  end
+  mask=[];
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/CVS/Entries
new file mode 100644
index 00000000..b6610f0d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/CVS/Entries
@@ -0,0 +1,2 @@
+/extract_params.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/CVS/Repository
new file mode 100644
index 00000000..1667449e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@softmax_CPD/private
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/extract_params.m b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/extract_params.m
new file mode 100644
index 00000000..486af06e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/private/extract_params.m
@@ -0,0 +1,18 @@
+function [W, b] = extract_params(CPD)
+
+% W(X,Y,Q), b(Y,Q)  where Y = ns(self), X = ns(cps), Q = prod(ns(dps))
+
+glimsz = prod(CPD.sizes(CPD.dpndx));
+ss = CPD.sizes(end);
+cpsz       = sum(CPD.sizes(CPD.cpndx));
+dp_as_cpsz = sum(CPD.sizes(CPD.dps_as_cps.ndx));
+W = zeros(dp_as_cpsz + cpsz, ss, glimsz);
+b = zeros(ss, glimsz);
+
+for i=1:glimsz
+  W(:,:,i) = CPD.glim{i}.w1;
+  b(:,i) = CPD.glim{i}.b1(:);
+end
+
+W = myreshape(W, [dp_as_cpsz + cpsz ss CPD.sizes(CPD.dpndx)]);
+b = myreshape(b, [ss CPD.sizes(CPD.dpndx)]);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/reset_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/reset_ess.m
new file mode 100644
index 00000000..abf7d54e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/reset_ess.m
@@ -0,0 +1,8 @@
+function CPD = reset_ess(CPD)
+% RESET_ESS Reset the Expected Sufficient Statistics for a CPD (dsoftmax)
+% CPD = reset_ess(CPD)
+
+CPD.parent_vals = [];
+CPD.eso_weights=[];
+CPD.self_vals = [];
+CPD.nsamples = 0;  
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/sample_node.m b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/sample_node.m
new file mode 100644
index 00000000..1c519049
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/sample_node.m
@@ -0,0 +1,14 @@
+function y = sample_node(CPD, pvals)
+% SAMPLE_NODE Draw a random sample from P(Xi | x(pi_i), theta_i)  (discrete)
+% y = sample_node(CPD, parent_evidence)
+%
+% parent_evidence{i} is the value of the i'th parent
+
+n = length(pvals)+1;
+dom = 1:n;
+%evidence = cell(1,n);
+%evidence(1:n-1) = pvals(:)';
+evidence = pvals;
+evidence{end+1} = [];
+T = convert_to_table(CPD, dom, evidence);
+y = sample_discrete(T);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/set_fields.m b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/set_fields.m
new file mode 100644
index 00000000..6c64b197
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/set_fields.m
@@ -0,0 +1,45 @@
+function CPD = set_params(CPD, varargin)
+% SET_PARAMS Set the parameters (fields) for a softmax_CPD object
+% CPD = set_params(CPD, name/value pairs)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% (Let ns(i) be the size of node i, X = ns(X), Y = ns(Y), Q1=ns(dps(1)), Q2=ns(dps(2)), ...
+%   where dps are the discrete parents; if there are no discrete parents, we set Q1=1.)
+%
+% weights - (W(:,j,a,b,...) - W(:,j',a,b,...)) is ppn to dec. boundary
+%           between j,j' given Q1=a,Q2=b,... [ randn(X,Y,Q1,Q2,...) ]
+% offset  - (offset(j,a,b,...) - offset(j',a,b,...)) is the offset to dec. boundary
+%           between j,j' given Q1=a,Q2=b,... [ randn(Y,Q1,Q2,...) ]
+% clamped     - 'yes' means don't adjust params during learning ['no']
+% max_iter    - the maximum number of steps to take [10]
+% verbose     - 'yes' means print the LL at each step of IRLS ['no']
+% wthresh     - convergence threshold for weights [1e-2]
+% llthresh    - convergence threshold for log likelihood [1e-2]
+% approx_hess - 'yes' means approximate the Hessian for speed ['no']
+%
+% e.g., CPD = set_params(CPD,'offset', zeros(ns(i),1));
+
+args = varargin;
+nargs = length(args);
+glimsz = prod(CPD.sizes(CPD.dpndx));
+for i=1:2:nargs
+  switch args{i},
+   case 'discrete',     str='nothing to do';   
+   case 'clamped',      CPD = set_clamped(CPD, strcmp(args{i+1}, 'yes'));
+   case 'max_iter',     CPD.max_iter = args{i+1};
+   case 'verbose',      CPD.verbose = strcmp(args{i+1}, 'yes');
+   case 'max_iter',     CPD.max_iter = args{i+1};
+   case 'wthresh',      CPD.wthresh = args{i+1};
+   case 'llthresh',     CPD.llthresh = args{i+1};
+   case 'approx_hess',  CPD.approx_hess = strcmp(args{i+1}, 'yes');
+   case 'weights',      for q=1:glimsz, CPD.glim{q}.w1 = args{i+1}(:,:,q); end; 
+   case 'offset',
+    if glimsz == 1
+      CPD.glim{1}.b1 = args{i+1};
+    else
+      for q=1:glimsz, CPD.glim{q}.b1 = args{i+1}(:,q); end; 
+    end
+   otherwise,  
+    error(['invalid argument name ' args{i}]);       
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/softmax_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/softmax_CPD.m
new file mode 100644
index 00000000..3d2e5153
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/softmax_CPD.m
@@ -0,0 +1,187 @@
+function CPD = softmax_CPD(bnet, self, varargin)
+% SOFTMAX_CPD Make a softmax (multinomial logit) CPD
+%
+% To define this CPD precisely, let W be an (m x n) matrix with W(i,:) = {i-th row of B} 
+% => we can define the following vectorial function:
+%    
+%                                   softmax: R^n |--> R^m  
+%                  softmax(z,i-th)=exp(W(i,:)*z)/sum_k(exp(W(k,:)*z))      
+%
+% (this constructor augments z with a one at the beginning to introduce an offset term (=bias, intercept))                                   
+% Now call the continuous (cts) and always observed (obs) parents X,
+% the discrete parents (if any) Q, and this node Y then we use the discrete parent(s) just  to index
+% the parameter vectors (c.f., conditional Gaussian nodes); that is:
+%                 prob(Y=i | X=x, Q=j) = softmax(x,i-th|j)
+% where '|j' means that we are using the j-th (m x n) parameters matrix W(:,:,j).
+% If there are no discrete parents, this is a regular softmax node.
+% If Y is binary, this is a logistic (sigmoid) function.
+%
+% CPD = softmax_CPD(bnet, node_num, ...) will create a softmax CPD with random parameters,
+% where node is the number of a node in this equivalence class.
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+% (Let ns(i) be the size of node i, X = ns(X), Y = ns(Y), Q1=ns(dps(1)), Q2=ns(dps(2)), ...
+% where dps are the discrete parents; if there are no discrete parents, we set Q1=1.)
+%
+% discrete - the discrete parents that we want to treat like the cts ones [ [] ]. 
+%            This can be used to define sigmoid belief network - see below the reference.             
+%            For example suppose that Y has one cts parents X and two discrete ones: Q, C1 where:
+%            -> Q is binary (1/2) and used just to index the parameters of 'self'
+%            -> C1 is ternary (1/2/3) and treated as a cts node <=> its values appear into the linear 
+%               part of the softmax function
+%            then:
+%                     prob(Y|X=x, Q=q, C1=c1)= softmax(W(:,:,q)' * y)
+%            where y = [1 | delta(C1,1) delta(C1,2) delta(C1,3) | x(:)']' and delta(Y,a)=indicator(Y=a).
+% weights - (w(:,j,a,b,...) - w(:,j',a,b,...)) is ppn to dec. boundary
+%           between j,j' given Q1=a,Q2=b,... [ randn(X,Y,Q1,Q2,...) ]
+% offset  - (b(j,a,b,...) - b(j',a,b,...)) is the offset to dec. boundary
+%           between j,j' given Q1=a,Q2=b,... [ randn(Y,Q1,Q2,...) ]
+%
+% e.g., CPD = softmax_CPD(bnet, i, 'offset', zeros(ns(i),1));
+%
+% The following fields control the behavior of the M step, which uses 
+% a weighted version of the Iteratively Reweighted Least Squares (WIRLS) if dps_as_cps=[]; or
+% a weighted SCG otherwise, as implemented in Netlab, and modified by Pierpaolo Brutti.
+%
+% clamped     - 'yes' means don't adjust params during learning ['no']
+% max_iter    - the maximum number of steps to take [10]
+% verbose     - 'yes' means print the LL at each step of IRLS ['no']
+% wthresh     - convergence threshold for weights [1e-2]
+% llthresh    - convergence threshold for log likelihood [1e-2]
+% approx_hess - 'yes' means approximate the Hessian for speed ['no']
+%
+% For backwards compatibility with BNT2, you can also specify the parameters in the following order
+%   softmax_CPD(bnet, self, w, b, clamped, max_iter, verbose, wthresh, llthresh, approx_hess)
+%
+% REFERENCE
+% For details on the sigmoid belief nets, see:
+% - Neal (1992). Connectionist learning of belief networks, Artificial Intelligence, 56, 71-113.
+% - Saul, Jakkola, Jordan (1996). Mean field theory for sigmoid belief networks, Journal of Artificial Intelligence Reseach (4), pagg. 61-76.
+%
+% For details on the M step, see:
+% - K. Chen, L. Xu, H. Chi (1999). Improved learning algorithms for mixtures of experts in multiclass 
+%       classification. Neural Networks 12, pp. 1229-1252.
+% - M.I. Jordan, R.A. Jacobs (1994). Hierarchical Mixtures of Experts and the EM algorithm. 
+%       Neural Computation 6, pp. 181-214.
+% - S.R. Waterhouse, A.J. Robinson (1994). Classification Using Hierarchical Mixtures of Experts. In Proc. IEEE
+%       Workshop on Neural Network for Signal Processing IV, pp. 177-186
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  CPD = class(CPD, 'softmax_CPD', discrete_CPD(0, []));
+  return;
+elseif isa(bnet, 'softmax_CPD')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+CPD = init_fields;
+
+assert(myismember(self, bnet.dnodes));
+ns = bnet.node_sizes;
+ps = parents(bnet.dag, self);
+dps = myintersect(ps, bnet.dnodes);
+cps = myintersect(ps, bnet.cnodes);
+
+clamped = 0;
+CPD = class(CPD, 'softmax_CPD', discrete_CPD(clamped, ns([ps self])));
+
+dps_as_cpssz = 0;
+dps_as_cps = [];
+% determine if any discrete parents are to be treated as cts
+if nargin >= 3 && isstr(varargin{1}) % might have passed in 'discrete'
+  for i=1:2:length(varargin)
+    if strcmp(varargin{i}, 'discrete')
+      dps_as_cps = varargin{i+1};
+      assert(myismember(dps_as_cps, dps));
+      dps = mysetdiff(dps, dps_as_cps);         % put out the dps treated as cts
+      CPD.dps_as_cps.ndx = find_equiv_posns(dps_as_cps, ps);
+      CPD.dps_as_cps.separator = [0 cumsum(ns(dps_as_cps(1:end-1)))]; % concatenated dps_as_cps dims separators
+      dps_as_cpssz = sum(ns(dps_as_cps));
+      break;
+    end
+  end
+end
+assert(~isempty(union(cps, dps_as_cps)));   % It have to be at least a cts or a dps_as_cps parents
+self_size = ns(self); 
+cpsz = sum(ns(cps));  
+glimsz = prod(ns(dps));
+CPD.dpndx = find_equiv_posns(dps, ps);  % it contains only the indeces of the 'pure' dps
+CPD.cpndx = find_equiv_posns(cps, ps);
+
+CPD.self  = self;
+CPD.solo  = (length(ns)<=2);
+CPD.sizes = bnet.node_sizes([ps self]);
+
+% set default params
+CPD.max_iter = 10;
+CPD.verbose = 0;
+CPD.wthresh = 1e-2;
+CPD.llthresh = 1e-2;
+CPD.approx_hess = 0;
+CPD.glim = cell(1,glimsz);
+for i=1:glimsz
+  CPD.glim{i} = glm(dps_as_cpssz + cpsz, self_size, 'softmax');
+end
+
+if nargin >= 3
+  args = varargin;
+  nargs = length(args);
+  if ~isstr(args{1})
+    %   softmax_CPD(bnet, self, w, b, clamped, max_iter, verbose, wthresh, llthresh, approx_hess)
+    if nargs >= 1 && ~isempty(args{1}), CPD = set_fields(CPD, 'weights', args{1}); end
+    if nargs >= 2 && ~isempty(args{2}), CPD = set_fields(CPD, 'offset', args{2});  end
+    if nargs >= 3 && ~isempty(args{3}), CPD = set_clamped(CPD, args{3});           end
+    if nargs >= 4 && ~isempty(args{4}), CPD.max_iter    = args{4}; end
+    if nargs >= 5 && ~isempty(args{5}), CPD.verbose     = args{5}; end
+    if nargs >= 6 && ~isempty(args{6}), CPD.wthresh     = args{6}; end
+    if nargs >= 7 && ~isempty(args{7}), CPD.llthresh   = args{7}; end
+    if nargs >= 8 && ~isempty(args{8}), CPD.approx_hess = args{8}; end
+  else
+    CPD = set_fields(CPD, args{:});
+  end
+end
+
+% sufficient statistics 
+% Since dsoftmax is not in the exponential family, we must store all the raw data.
+CPD.parent_vals = [];         % X(l,:) = value of cts parents in l'th example
+CPD.self_vals = [];           % Y(l,:) = value of self in l'th example
+
+CPD.eso_weights=[];           % weights used by the WIRLS algorithm
+
+% For BIC
+CPD.nsamples = 0;   
+if ~adjustable_CPD(CPD),
+   CPD.nparams=0;
+else
+   [W, b] = extract_params(CPD);
+   CPD.nparams= prod(size(W)) + prod(size(b));
+end
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.glim = {};
+CPD.self = [];
+CPD.solo = [];
+CPD.max_iter = [];
+CPD.verbose = [];
+CPD.wthresh = [];
+CPD.llthresh = [];
+CPD.approx_hess = [];
+CPD.sizes = [];
+CPD.parent_vals = [];
+CPD.eso_weights=[];
+CPD.self_vals = [];
+CPD.nsamples = [];
+CPD.nparams = [];
+CPD.dpndx = [];
+CPD.cpndx = [];
+CPD.dps_as_cps.ndx = [];
+CPD.dps_as_cps.separator = [];
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/update_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/update_ess.m
new file mode 100644
index 00000000..143c567c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@softmax_CPD/update_ess.m
@@ -0,0 +1,97 @@
+function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+% UPDATE_ESS Update the Expected Sufficient Statistics of a softmax node
+% function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+%
+% fmarginal = overall posterior distribution of self and its parents
+% fmarginal(i1,i2...,ik,s)=prob(Pa1=i1,...,Pak=ik, self=s| X)
+% 
+% => 1) prob(self|Pa1,...,Pak)=fmarginal/prob(Pa1,...,Pak) with prob(Pa1,...,Pak)=sum{s,fmarginal}
+%       [self estimation -> CPD.self_vals]
+% 	  2) prob(Pa1,...,Pak) [WIRLS weights -> CPD.eso_weights]
+%
+% Hidden_bitv is ignored
+
+% Written by Pierpaolo Brutti
+
+if ~adjustable_CPD(CPD), return; end
+
+domain     = fmarginal.domain;                              
+self       = domain(end);          
+ps         = domain(1:end-1);                                     
+cnodes     = domain(CPD.cpndx);
+cps        = myintersect(domain, cnodes);                     
+dps        = mysetdiff(ps, cps);                            
+dn_use     = dps;
+if isempty(evidence{self}) dn_use = [dn_use self]; end % if self is hidden we must consider its dimension  
+dps_as_cps = domain(CPD.dps_as_cps.ndx);
+odom       = domain(~isemptycell(evidence(domain))); 
+
+ns = zeros(1, max(domain));
+ns(domain) = CPD.sizes;     % CPD.sizes = bnet.node_sizes([ps self]);
+ens = ns;                   % effective node sizes
+ens(odom) = 1;              
+dpsize = prod(ns(dps));
+
+% Extract the params compatible with the observations (if any) on the discrete parents (if any)
+dops = myintersect(dps, odom);
+dpvals = cat(1, evidence{dops});
+
+subs = ind2subv(ens(dn_use), 1:prod(ens(dn_use)));
+dpmap = find_equiv_posns(dops, dn_use);
+if ~isempty(dpmap), subs(:,dpmap) = subs(:,dpmap)+repmat(dpvals(:)',[size(subs,1) 1])-1; end
+supportedQs = subv2ind(ns(dn_use), subs); subs=subs(1:prod(ens(dps)),1:length(dps));
+Qarity = prod(ns(dn_use));
+if isempty(dn_use), Qarity = 1; end   
+
+fullm.T              = zeros(Qarity, 1);
+fullm.T(supportedQs) = fmarginal.T(:);
+rs_dim = CPD.sizes;    rs_dim(CPD.cpndx) = 1;           %
+if ~isempty(evidence{self}), rs_dim(end)=1; end         % reshaping the marginal
+fullm.T              = reshape(fullm.T, rs_dim);        %
+
+% --------------------------------------------------------------------------------UPDATE--
+
+CPD.nsamples = CPD.nsamples + 1;
+
+% 1) observations vector -> CPD.parents_vals ---------------------------------------------
+cpvals = cat(1, evidence{cps});
+
+if ~isempty(dps_as_cps),   % ...get in the dp_as_cp parents... 
+    separator          = CPD.dps_as_cps.separator;
+    dp_as_cpmap        = find_equiv_posns(dps_as_cps, dps);       
+    for i=1:dpsize,
+        dp_as_cpvals=zeros(1,sum(ns(dps_as_cps)));
+        possible_vals = ind2subv(ns(dps),i);
+        ll=find(ismember(subs(:,dp_as_cpmap), possible_vals(dp_as_cpmap), 'rows')==1);   
+        if ~isempty(ll),
+            where_one = separator + possible_vals(dp_as_cpmap);
+            dp_as_cpvals(where_one)=1;                            
+        end
+        CPD.parent_vals(CPD.nsamples,:,i) = [dp_as_cpvals(:); cpvals(:)]';
+    end
+else
+    CPD.parent_vals(CPD.nsamples,:) = cpvals(:)';
+end
+
+% 2) weights vector -> CPD.eso_weights ----------------------------------------------------
+if isempty(evidence{self}),             % self is hidden
+    pesi=reshape(sum(fullm.T, length(rs_dim)),[dpsize,1]);
+else
+    pesi=reshape(fullm.T,[dpsize,1]);
+end
+assert(approxeq(sum(pesi),1));          % check
+
+% 3) estimate (if R is hidden) or recover (if R is obs) self'value-------------------------
+if isempty(evidence{self})                                  % P(self|Pa1,...,Pak)=fmarginal/prob(Pa1,...,Pak)
+    r=reshape(mk_stochastic(fullm.T), [dpsize ns(self)]);   % matrix size: prod{j,ns(Paj)} x ns(self)      
+else
+    r = zeros(dpsize,ns(self));
+    for i=1:dpsize, if pesi(i)~=0, r(i,evidence{self}) = 1; end; end
+end
+for i=1:dpsize, if pesi(i)~=0, assert(approxeq(sum(r(i,:)),1)); end; end     % check
+
+% 4) save the previous values --------------------------------------------------------------
+for i=1:dpsize
+    CPD.eso_weights(CPD.nsamples,:,i)=pesi(i);
+    CPD.self_vals(CPD.nsamples,:,i) = r(i,:); 
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CPD_to_CPT.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CPD_to_CPT.m
new file mode 100644
index 00000000..351f103c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CPD_to_CPT.m
@@ -0,0 +1,5 @@
+function CPT = CPD_to_CPT(CPD)
+% CPD_TO_CPT Convert the discrete CPD to tabular form (tabular)
+% CPT = CPD_to_CPT(CPD)
+
+CPT = CPD.CPT;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Entries
new file mode 100644
index 00000000..84ff987c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Entries
@@ -0,0 +1,15 @@
+/CPD_to_CPT.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/bayes_update_params.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/display.m/1.1.1.1/Tue Apr 22 21:00:02 2003//
+/get_field.m/1.1.1.1/Sun Jan 16 02:27:30 2005//
+/learn_params.m/1.1.1.1/Thu Jun 10 01:25:02 2004//
+/log_marg_prob_node.m/1.1.1.1/Fri Jun 11 21:16:00 2004//
+/log_nextcase_prob_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/log_prior.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/maximize_params.m/1.1.1.1/Sun Mar  9 22:44:40 2003//
+/reset_ess.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/set_fields.m/1.1.1.1/Sun Jan 16 02:27:30 2005//
+/tabular_CPD.m/1.1.1.1/Sun Jan 16 02:27:32 2005//
+/update_ess.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/update_ess_simple.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Repository
new file mode 100644
index 00000000..c64a17a7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@tabular_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/BIC_score_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/BIC_score_CPD.m
new file mode 100644
index 00000000..ab4ef6cf
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/BIC_score_CPD.m
@@ -0,0 +1,17 @@
+function score = BIC_score_CPD(CPD, fam, data, ns, cnodes)
+% BIC_score_CPD Compute the BIC score of a tabular CPD
+% score = BIC_score_CPD(CPD, fam, data, ns, cnodes)
+
+if iscell(data)
+  local_data = cell2num(data(fam,:));
+else
+  local_data = data(fam, :);
+end
+counts = compute_counts(local_data, CPD.sizes);
+CPT = mk_stochastic(counts); % MLE
+tiny = exp(-700); 
+CPT = CPT + (CPT==0)*tiny;  % replace 0s by tiny
+LL = sum(log(CPT(:)) .* counts(:));
+N = size(data, 2);
+score = LL - 0.5*CPD.nparams*log(N);
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/CVS/Entries
new file mode 100644
index 00000000..cbddfaa9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/CVS/Entries
@@ -0,0 +1,11 @@
+/BIC_score_CPD.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/bayesian_score_CPD.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/log_marg_prob_node_case.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mult_CPD_and_pi_msgs.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/prob_CPT.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/prob_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_node_single_case.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/tabular_CPD.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/update_params.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/CVS/Repository
new file mode 100644
index 00000000..b43e738b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@tabular_CPD/Old
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/bayesian_score_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/bayesian_score_CPD.m
new file mode 100644
index 00000000..083a00d7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/bayesian_score_CPD.m
@@ -0,0 +1,13 @@
+function score = bayesian_score_CPD(CPD, local_ev)
+% bayesian_score_CPD Compute the Bayesian score of a tabular CPD using uniform Dirichlet prior
+% score = bayesian_score_CPD(CPD, local_ev)
+%
+% The Bayesian score is the log marginal likelihood
+
+if iscell(local_ev)
+ data = num2cell(local_ev);
+else
+ data =	local_ev;
+end
+
+score = dirichlet_score_family(compute_counts(data, CPD.sizes));
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/log_marg_prob_node_case.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/log_marg_prob_node_case.m
new file mode 100644
index 00000000..2a177fe6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/log_marg_prob_node_case.m
@@ -0,0 +1,22 @@
+function L = log_marg_prob_node_case(CPD, y, x)
+% LOG_MARG_PROB_NODE_CASE Compute prod_m log P(x(i,m)| x(pi_i,m)) for node i (tabular)
+% L = log_marg_prob_node_case(CPD, self_ev, parent_ev)
+% 
+% This is a slightly optimised version of log_marg_prob_node.
+% We assume we have exactly 1 case, i.e., y is a scalar and x is a vector (not a cell array).
+
+sz = CPD.sizes;
+nparents = length(sz)-1;
+
+% We assume the CPTs are already set to the mean of the posterior (due to update_params)
+
+switch nparents
+ case 0, p = CPD.CPT(y);
+ case 1, p = CPD.CPT(x(1), y);
+ case 2, p = CPD.CPT(x(1), x(2), y);
+ case 3, p = CPD.CPT(x(1), x(2), x(3), y);
+ otherwise,
+  ind = subv2ind(sz, [x y]);
+  p = CPD.CPT(ind);
+end
+L = log(p);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/mult_CPD_and_pi_msgs.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/mult_CPD_and_pi_msgs.m
new file mode 100644
index 00000000..b67ed2e6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/mult_CPD_and_pi_msgs.m
@@ -0,0 +1,17 @@
+function T = mult_CPD_and_pi_msgs(CPD, n, ps, msgs, except)
+% MULT_CPD_AND_PI_MSGS Multiply the CPD and all the pi messages from parents, perhaps excepting one
+% T = mult_CPD_and_pi_msgs(CPD, n, ps, msgs, except)
+
+if nargin < 5, except = -1; end
+
+dom = [ps n];
+%ns = sparse(1, max(dom));
+ns = zeros(1, max(dom));
+ns(dom) = mysize(CPD.CPT);
+T = dpot(dom, ns(dom), CPD.CPT);
+for i=1:length(ps)
+  p = ps(i);
+  if p ~= except
+    T = multiply_by_pot(T, dpot(p, ns(p), msgs{n}.pi_from_parent{i}.T)); 
+  end
+end         
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/prob_CPT.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/prob_CPT.m
new file mode 100644
index 00000000..6685de30
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/prob_CPT.m
@@ -0,0 +1,16 @@
+function p = prob_CPT(CPD, x)
+% PROB_CPT Lookup the prob. of a family value in a tabular CPD
+% p = prob_CPT(CPD, x)
+%
+% This is a version of prob_CPD optimized for tables.
+
+switch length(x)
+ case 1, p = CPD.CPT(x);
+ case 2, p = CPD.CPT(x(1), x(2));
+ case 3, p = CPD.CPT(x(1), x(2), x(3));
+ case 4, p = CPD.CPT(x(1), x(2), x(3), x(4));
+ otherwise,
+  ind = subv2ind(mysize(CPD.CPT), x);
+  p = CPD.CPT(ind);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/prob_node.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/prob_node.m
new file mode 100644
index 00000000..2764e6c1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/prob_node.m
@@ -0,0 +1,40 @@
+function p = prob_node(CPD, self_ev, pev)
+% PROB_NODE Compute P(y|pa(y), theta) (tabular)
+% p = prob_node(CPD, self_ev, pev)
+%
+% self_ev{m} is the evidence on this node in case m
+% pev{i,m} is the evidence on the i'th parent in case m
+% If there is a single case, self_ev can be a scalar instead of a cell array
+
+ncases = size(pev, 2);
+
+%assert(~any(isemptycell(pev))); % slow
+%assert(~any(isemptycell(self_ev))); % slow
+
+CPT = CPD_to_CPT(CPD);  
+sz = mysize(CPT);
+nparents = length(sz)-1;
+assert(nparents == size(pev, 1));
+
+if ncases==1 
+  x = cat(1, pev{:});
+  if iscell(y)
+    y = self_ev{1};
+  else
+    y = self_ev;
+  end
+  switch nparents
+   case 0, p = CPT(y);
+   case 1, p = CPT(x(1), y);
+   case 2, p = CPT(x(1), x(2), y);
+   case 3, p = CPT(x(1), x(2), x(3), y);
+   otherwise,
+    ind = subv2ind(CPD.sizes, [x y]);
+    p = CPT(ind);
+  end
+else
+  x = num2cell(pev)'; % each row is a case
+  y = cat(1, self_ev{:})';
+  ind = subv2ind(CPD.sizes, [x y]);
+  p = CPT(ind);
+end     
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/sample_node.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/sample_node.m
new file mode 100644
index 00000000..3fd92d79
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/sample_node.m
@@ -0,0 +1,53 @@
+function y = sample_node(CPD, pev, nsamples)
+% SAMPLE_NODE Draw a random sample from P(Xi | x(pi_i), theta_i)  (tabular)
+% Y = SAMPLE_NODE(CPD, PEV, NSAMPLES)
+%
+% pev(i,m) is the value of the i'th parent in sample m (if there are any parents).
+% y(m) is the m'th sampled value (a row vector).
+% (If pev is a cell array, so is y.)
+% nsamples defaults to 1.
+
+if nargin < 3, nsamples = 1; end
+
+%if nargin < 4, usecell = 0; end
+if iscell(pev), usecell = 1; else usecell = 0; end
+
+if nsamples == 1, pev = pev(:); end
+
+sz = CPD.sizes; 
+nparents = length(sz)-1;
+if nparents==0
+  y = sample_discrete(CPD.CPT, 1, nsamples);
+  if usecell
+    y = num2cell(y);
+  end
+  return;
+end
+
+sz = CPD.sizes; 
+[nparents nsamples] = size(pev);
+
+if usecell
+  pvals = cell2num(pev)'; % each row is a case
+else
+  pvals = pev';
+end
+
+psz = sz(1:end-1);
+ssz = sz(end);
+ndx = subv2ind(psz, pvals);
+T = reshape(CPD.CPT, [prod(psz) ssz]);
+T2 = T(ndx,:); % each row is a distribution selected by the parents
+C = cumsum(T2, 2); % sum across columns
+R = rand(nsamples, 1);
+y = ones(nsamples, 1);
+for i=1:ssz-1
+  y = y + (R > C(:,i));
+end
+y = y(:)';
+if usecell
+  y = num2cell(y);
+end
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/sample_node_single_case.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/sample_node_single_case.m
new file mode 100644
index 00000000..3e1dcf34
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/sample_node_single_case.m
@@ -0,0 +1,39 @@
+function y = sample_node(CPD, pev)
+% SAMPLE_NODE Draw a random sample from P(Xi | x(pi_i), theta_i)  (tabular)
+% y = sample_node(CPD, pev)
+%
+% pev{i} is the value of the i'th parent (if any)
+
+%assert(~any(isemptycell(pev)));
+
+%CPT = CPD_to_CPT(CPD);
+%sz = mysize(CPT);
+sz = CPD.sizes; 
+nparents = length(sz)-1;
+if nparents > 0
+  pvals = cat(1, pev{:});
+end
+switch nparents
+ case 0, T = CPD.CPT;
+ case 1, T = CPD.CPT(pvals(1), :);
+ case 2, T = CPD.CPT(pvals(1), pvals(2), :);
+ case 3, T = CPD.CPT(pvals(1), pvals(2), pvals(3), :);
+ case 4, T = CPD.CPT(pvals(1), pvals(2), pvals(3), pvals(4), :);
+ otherwise,
+  psz = sz(1:end-1);
+  ssz = sz(end);
+  i = subv2ind(psz, pvals(:)');
+  T = reshape(CPD.CPT, [prod(psz) ssz]);
+  T = T(i,:);
+end
+
+if sz(end)==2
+  r = rand(1,1);
+  if r > T(1)
+    y = 2;
+  else
+    y = 1;
+  end
+else
+  y = sample_discrete(T);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/tabular_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/tabular_CPD.m
new file mode 100644
index 00000000..2227e051
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/tabular_CPD.m
@@ -0,0 +1,186 @@
+function CPD = tabular_CPD(bnet, self, varargin)
+% TABULAR_CPD Make a multinomial conditional prob. distrib. (CPT)
+%
+% CPD = tabular_CPD(bnet, node) creates a random CPT.
+%
+% The following arguments can be specified [default in brackets]
+%
+% CPT - specifies the params ['rnd']
+%   - T means use table T; it will be reshaped to the size of node's family.
+%   - 'rnd' creates rnd params (drawn from uniform)
+%   - 'unif' creates a uniform distribution
+%   - 'leftright' only transitions from i to i/i+1 are allowed, for each non-self parent context.
+%       The non-self parents are all parents except oldself.
+% selfprob - The prob of transition from i to i if CPT = 'leftright' [0.1]
+% old_self - id of the node corresponding to self in the previous slice [self-ss]
+% adjustable - 0 means don't adjust the parameters during learning [1]
+% prior_type - defines type of prior ['none']
+%  - 'none' means do ML estimation
+%  - 'dirichlet' means add pseudo-counts to every cell
+%  - 'entropic' means use a prior P(theta) propto exp(-H(theta)) (see Brand)
+% dirichlet_weight - equivalent sample size (ess) of the dirichlet prior [1]
+% dirichlet_type - defines the type of Dirichlet prior ['BDeu']
+%  - 'unif' means put dirichlet_weight in every cell
+%  - 'BDeu' means we put 'dirichlet_weight/(r q)' in every cell
+%    where r = self_sz and q = prod(parent_sz) (see Heckerman)
+% trim - 1 means trim redundant params (rows in CPT) when using entropic prior [0]
+%
+% e.g., tabular_CPD(bnet, i, 'CPT', T)
+% e.g., tabular_CPD(bnet, i, 'CPT', 'unif', 'dirichlet_weight', 2, 'dirichlet_type', 'unif')
+%
+% REFERENCES
+% M. Brand - "Structure learning in conditional probability models via an entropic  prior
+%   and parameter extinction", Neural Computation 11 (1999): 1155--1182
+% M. Brand - "Pattern discovery via entropy minimization" [covers annealing]
+%   AI & Statistics 1999. Equation numbers refer to this paper, which is available from
+%   www.merl.com/reports/docs/TR98-21.pdf
+% D. Heckerman, D. Geiger and M. Chickering, 
+%   "Learning Bayesian networks: the combination of knowledge and statistical data",
+%   Microsoft Research Tech Report, 1994
+
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  CPD = class(CPD, 'tabular_CPD', discrete_CPD(0, []));
+  return;
+elseif isa(bnet, 'tabular_CPD')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+CPD = init_fields;
+
+ns = bnet.node_sizes;
+ps = parents(bnet.dag, self);
+fam_sz = ns([ps self]);
+CPD.sizes = fam_sz;
+CPD.leftright = 0;
+
+% set defaults
+CPD.CPT = mk_stochastic(myrand(fam_sz));
+CPD.adjustable = 1;
+CPD.prior_type = 'none';
+dirichlet_type = 'BDeu';
+dirichlet_weight = 1;
+CPD.trim = 0;
+selfprob = 0.1;
+
+% extract optional args
+args = varargin;
+% check for old syntax CPD(bnet, i, CPT) as opposed to CPD(bnet, i, 'CPT', CPT)
+if ~isempty(args) && ~ischar(args{1})
+  CPD.CPT = myreshape(args{1}, fam_sz);
+  args = [];
+end
+
+% if old_self is specified, read in the value before CPT is created
+old_self = []; 
+for i=1:2:length(args)
+  switch args{i},
+   case 'old_self', old_self = args{i+1};
+  end
+end
+
+for i=1:2:length(args)
+  switch args{i},
+   case 'CPT',
+    T = args{i+1};
+    if ischar(T)
+      switch T
+       case 'unif', CPD.CPT = mk_stochastic(myones(fam_sz));
+       case 'rnd',  CPD.CPT = mk_stochastic(myrand(fam_sz));
+       case 'leftright', 
+	% we just initialise the CPT to leftright - this structure will
+	% be maintained by EM, assuming we don't use a prior...
+	CPD.leftright = 1;
+	if isempty(old_self) % we assume the network is a DBN
+	  ss = bnet.nnodes_per_slice;
+	  old_self = self-ss;
+	end
+	other_ps = mysetdiff(ps, old_self);
+	Qps = prod(ns(other_ps));
+	Q = ns(self);
+	p = selfprob;
+	LR = mk_leftright_transmat(Q, p);
+	transprob = repmat(reshape(LR, [1 Q Q]), [Qps 1 1]); % transprob(k,i,j)
+	transprob = permute(transprob, [2 1 3]); % now transprob(i,k,j)
+	CPD.CPT = myreshape(transprob, fam_sz);
+       otherwise,   error(['invalid CPT ' T]);       
+      end
+    else
+      CPD.CPT = myreshape(T, fam_sz);
+    end
+    
+   case 'prior_type', CPD.prior_type = args{i+1};
+   case 'dirichlet_type', dirichlet_type = args{i+1};
+   case 'dirichlet_weight', dirichlet_weight = args{i+1};
+   case 'adjustable', CPD.adjustable = args{i+1};
+   case 'clamped', CPD.adjustable = ~args{i+1};
+   case 'trim', CPD.trim = args{i+1};
+   case 'old_self', noop = 1; % already read in
+   otherwise, error(['invalid argument name: ' args{i}]);       
+  end
+end
+
+switch CPD.prior_type
+ case 'dirichlet',
+  switch dirichlet_type
+   case 'unif', CPD.dirichlet = dirichlet_weight * myones(fam_sz);
+   case 'BDeu',  CPD.dirichlet = dirichlet_weight * mk_stochastic(myones(fam_sz));
+   otherwise, error(['invalid dirichlet_type ' dirichlet_type])
+  end
+ case {'entropic', 'none'}
+  CPD.dirichlet = [];
+ otherwise, error(['invalid prior_type ' prior_type])
+end
+
+  
+
+% fields to do with learning
+if ~CPD.adjustable
+  CPD.counts = [];
+  CPD.nparams = 0;
+  CPD.nsamples = [];
+else
+  CPD.counts = zeros(size(CPD.CPT));
+  psz = fam_sz(1:end-1);
+  ss = fam_sz(end);
+  if CPD.leftright
+    % For each of the Qps contexts, we specify Q elements on the diagoanl
+    CPD.nparams = Qps * Q;
+  else
+    % sum-to-1 constraint reduces the effective arity of the node by 1
+    CPD.nparams = prod([psz ss-1]);
+  end
+  CPD.nsamples = 0;
+end
+
+fam_sz = CPD.sizes;
+psz = prod(fam_sz(1:end-1));
+ssz = fam_sz(end);
+CPD.trimmed_trans = zeros(psz, ssz); % must declare before reading
+
+CPD = class(CPD, 'tabular_CPD', discrete_CPD(~CPD.adjustable, fam_sz));
+
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.CPT = [];
+CPD.sizes = [];
+CPD.prior_type = [];
+CPD.dirichlet = [];
+CPD.adjustable = [];
+CPD.counts = [];
+CPD.nparams = [];
+CPD.nsamples = [];
+CPD.trim = [];
+CPD.trimmed_trans = [];
+CPD.leftright = [];
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/update_params.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/update_params.m
new file mode 100644
index 00000000..5a1e93a8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/Old/update_params.m
@@ -0,0 +1,15 @@
+function CPD = update_params(CPD, ev, counts)
+% UPDATE_PARAMS Update the Dirichlet pseudo counts and compute the new MAP param estimates (tabular)
+%
+% CPD = update_params(CPD, ev) uses the evidence on the family from a single case.
+%
+% CPD = update_params(CPD, [], counts) does a batch update using the specified suff. stats.
+
+if nargin < 3
+  n = length(ev);
+  data = cat(1, ev{:}); % convert to a vector of scalars
+  counts = compute_counts(data(:)', 1:n, mysize(CPD.CPT));
+end
+  
+CPD.prior = CPD.prior + counts;
+CPD.CPT = mk_stochastic(CPD.prior);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/bayes_update_params.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/bayes_update_params.m
new file mode 100644
index 00000000..0de0f8b8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/bayes_update_params.m
@@ -0,0 +1,55 @@
+function CPD = bayes_update_params(CPD, self_ev, pev)
+% UPDATE_PARAMS_COMPLETE Bayesian parameter updating given completely observed data (tabular)
+% CPD = update_params_complete(CPD, self_ev, pev)
+%
+% self_ev(m) is the evidence on this node in case m.
+% pev(i,m) is the evidence on the i'th parent in case m (if there are any parents).
+% These can be arrays or cell arrays.
+%
+% We update the Dirichlet pseudo counts and set the CPT to the mean of the posterior.
+
+if iscell(self_ev), usecell = 1; else usecell = 0; end
+
+ncases = length(self_ev);
+sz = CPD.sizes;
+nparents = length(sz)-1;
+assert(nparents == size(pev,1));
+
+if ncases == 0 | ~adjustable_CPD(CPD)
+  return;
+elseif ncases == 1 % speedup the sequential learning case by avoiding normalization of the whole array
+  if usecell
+    x = cat(1, pev{:})';
+    y = self_ev{1};
+  else
+    x = pev(:)';
+    y = self_ev;
+  end
+  switch nparents
+   case 0,
+    CPD.dirichlet(y) = CPD.dirichlet(y)+1;
+    CPD.CPT = CPD.dirichlet / sum(CPD.dirichlet);
+   case 1,
+    CPD.dirichlet(x(1), y) = CPD.dirichlet(x(1), y)+1;
+    CPD.CPT(x(1), :) = CPD.dirichlet(x(1), :) ./ sum(CPD.dirichlet(x(1), :));
+   case 2,
+    CPD.dirichlet(x(1), x(2), y) = CPD.dirichlet(x(1), x(2), y)+1;
+    CPD.CPT(x(1), x(2), :) = CPD.dirichlet(x(1), x(2), :) ./ sum(CPD.dirichlet(x(1), x(2), :));
+   case 3,
+    CPD.dirichlet(x(1), x(2), x(3), y) = CPD.dirichlet(x(1), x(2), x(3), y)+1;
+    CPD.CPT(x(1), x(2), x(3), :) = CPD.dirichlet(x(1), x(2), x(3), :) ./ sum(CPD.dirichlet(x(1), x(2), x(3), :));
+   otherwise,
+    ind = subv2ind(sz, [x y]);
+    CPD.dirichlet(ind) = CPD.dirichlet(ind) + 1;
+    CPD.CPT = mk_stochastic(CPD.dirichlet);
+  end
+else  
+  if usecell
+    data = [cell2num(pev); cell2num(self_ev)]; 
+  else
+    data = [pev; self_ev];
+  end
+  counts = compute_counts(data, sz);
+  CPD.dirichlet = CPD.dirichlet + counts;
+  CPD.CPT = mk_stochastic(CPD.dirichlet);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/display.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/display.m
new file mode 100644
index 00000000..6c9be2c3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/display.m
@@ -0,0 +1,5 @@
+function display(CPD)
+
+disp('tabular_CPD object');
+disp(struct(CPD)); 
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/get_field.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/get_field.m
new file mode 100644
index 00000000..ba233db9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/get_field.m
@@ -0,0 +1,16 @@
+function val = get_field(CPD, name)
+% GET_PARAMS Get the parameters (fields) for a tabular_CPD object
+% val = get_params(CPD, name)
+%
+% The following fields can be accessed
+%
+% cpt, counts
+%
+% e.g., CPT = get_params(CPD, 'cpt')
+
+switch name
+ case 'cpt',      val = CPD.CPT;
+ case 'counts',      val = CPD.counts;
+ otherwise,
+  error(['invalid argument name ' name]);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/learn_params.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/learn_params.m
new file mode 100644
index 00000000..970da8b1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/learn_params.m
@@ -0,0 +1,17 @@
+function CPD = learn_params(CPD, fam, data, ns, cnodes)
+%function CPD = learn_params(CPD, local_data)
+% LEARN_PARAMS Compute the ML/MAP estimate of the params of a tabular CPD given complete data
+% CPD = learn_params(CPD, local_data)
+%
+% local_data(i,m) is the value of i'th family member in case m (can be cell array).
+
+local_data = data(fam, :); 
+if iscell(local_data)
+  local_data = cell2num(local_data);
+end
+counts = compute_counts(local_data, CPD.sizes);
+switch CPD.prior_type
+ case 'none', CPD.CPT = mk_stochastic(counts); 
+ case 'dirichlet', CPD.CPT = mk_stochastic(counts + CPD.dirichlet); 
+ otherwise, error(['unrecognized prior ' CPD.prior_type])
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/log_marg_prob_node.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/log_marg_prob_node.m
new file mode 100644
index 00000000..8a819488
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/log_marg_prob_node.m
@@ -0,0 +1,69 @@
+function L = log_marg_prob_node(CPD, self_ev, pev, usecell)
+% LOG_MARG_PROB_NODE Compute sum_m log P(x(i,m)| x(pi_i,m)) for node i (tabular)
+% L = log_marg_prob_node(CPD, self_ev, pev)
+%
+% This differs from log_prob_node because we integrate out the parameters.
+% self_ev(m) is the evidence on this node in case m.
+% pev(i,m) is the evidence on the i'th parent in case m (if there are any parents).
+% (These may also be cell arrays.)
+
+ncases = length(self_ev);
+sz = CPD.sizes;
+nparents = length(sz)-1;
+assert(ncases == size(pev, 2)); 
+
+if nargin < 4
+  %usecell = 0;
+  if iscell(self_ev)
+    usecell = 1;
+  else
+    usecell = 0;
+  end
+end
+
+
+if ncases==0
+  L = 0;
+  return;
+elseif ncases==1  % speedup the sequential learning case
+  CPT = CPD.CPT;
+  % We assume the CPTs are already set to the mean of the posterior (due to bayes_update_params)
+  if usecell
+    x = cat(1, pev{:})';
+    y = self_ev{1};
+  else
+    %x = pev(:)';
+    x = pev;
+    y = self_ev;
+  end
+  switch nparents
+   case 0, p = CPT(y);
+   case 1, p = CPT(x(1), y);
+   case 2, p = CPT(x(1), x(2), y);
+   case 3, p = CPT(x(1), x(2), x(3), y);
+   otherwise,
+    ind = subv2ind(sz, [x y]);
+    p = CPT(ind);
+  end
+  L = log(p);
+else
+  % We ignore the CPTs here and assume the prior has not been changed
+  
+  % We arrange the data as in the following example.
+  % Let there be 2 parents and 3 cases. Let p(i,m) be parent i in case m,
+  % and y(m) be the child in case m. Then we create the data matrix
+  % 
+  % p(1,1) p(1,2) p(1,3)
+  % p(2,1) p(2,2) p(2,3)
+  % y(1)   y(2)   y(3)
+  if usecell
+    data = [cell2num(pev); cell2num(self_ev)]; 
+  else
+    data = [pev; self_ev];
+  end
+  %S = struct(CPD); fprintf('log marg prob node %d, ps\n', S.self); disp(S.parents)
+  counts = compute_counts(data, sz);
+  L = dirichlet_score_family(counts, CPD.dirichlet);
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/log_nextcase_prob_node.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/log_nextcase_prob_node.m
new file mode 100644
index 00000000..c946de69
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/log_nextcase_prob_node.m
@@ -0,0 +1,72 @@
+function L = log_nextcase_prob_node(CPD, self_ev, pev, test_self_ev, test_pev)
+% LOG_NEXTCASE_PROB_NODE compute the joint distribution of a node (tabular) of a new case given
+% completely observed data.
+%
+% The input arguments are mainly similar with log_marg_prob_node(CPD, self_ev, pev, usecell),
+% but add test_self_ev, test_pev, and without usecell
+% test_self_ev(m) is the evidence on this node in a test case.
+% test_pev(i) is the evidence on the i'th parent in the test case (if there are any parents).
+%
+% Written by qian.diao@intel.com
+
+ncases = length(self_ev);
+sz = CPD.sizes;
+nparents = length(sz)-1;
+assert(ncases == size(pev, 2)); 
+
+if nargin < 6
+  %usecell = 0;
+  if iscell(self_ev)
+    usecell = 1;
+  else
+    usecell = 0;
+  end
+end
+
+
+if ncases==0
+  L = 0;
+  return;
+elseif ncases==1  % speedup the sequential learning case; here need correction!!!
+  CPT = CPD.CPT;
+  % We assume the CPTs are already set to the mean of the posterior (due to bayes_update_params)
+  if usecell
+    x = cat(1, pev{:})';
+    y = self_ev{1};
+  else
+    %x = pev(:)';
+    x = pev;
+    y = self_ev;
+  end
+  switch nparents
+   case 0, p = CPT(y);
+   case 1, p = CPT(x(1), y);
+   case 2, p = CPT(x(1), x(2), y);
+   case 3, p = CPT(x(1), x(2), x(3), y);
+   otherwise,
+    ind = subv2ind(sz, [x y]);
+    p = CPT(ind);
+  end
+  L = log(p);
+else
+  % We ignore the CPTs here and assume the prior has not been changed
+  
+  % We arrange the data as in the following example.
+  % Let there be 2 parents and 3 cases. Let p(i,m) be parent i in case m,
+  % and y(m) be the child in case m. Then we create the data matrix
+  % 
+  % p(1,1) p(1,2) p(1,3)
+  % p(2,1) p(2,2) p(2,3)
+  % y(1)   y(2)   y(3)
+  if usecell
+    data = [cell2num(pev); cell2num(self_ev)]; 
+  else
+    data = [pev; self_ev];
+  end
+  counts = compute_counts(data, sz);
+  
+  % compute the (N_ijk'+ N_ijk)/(N_ij' + N_ij) under the condition of 1_m+1,ijk = 1 
+  L = predict_family(counts, CPD.prior, test_self_ev, test_pev);
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/log_prior.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/log_prior.m
new file mode 100644
index 00000000..1ac2dbd4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/log_prior.m
@@ -0,0 +1,18 @@
+function L = log_prior(CPD)
+% LOG_PRIOR Return log P(theta) for a tabular CPD 
+% L = log_prior(CPD)
+
+switch CPD.prior_type
+ case 'none',
+  L = 0;
+ case 'dirichlet',
+  D = CPD.dirichlet(:);
+  L = sum(log(D + (D==0)));
+ case 'entropic',
+  % log-prior = log exp(-H(theta)) = sum_i theta_i log (theta_i)
+  fam_sz = CPD.sizes;
+  psz = prod(fam_sz(1:end-1));
+  ssz = fam_sz(end);
+  C = reshape(CPD.CPT, psz, ssz);
+  L = sum(sum(C .* log(C + (C==0))));
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/maximize_params.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/maximize_params.m
new file mode 100644
index 00000000..c4317a78
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/maximize_params.m
@@ -0,0 +1,52 @@
+function CPD = maximize_params(CPD, temp)
+% MAXIMIZE_PARAMS Set the params of a tabular node to their ML/MAP values.
+% CPD = maximize_params(CPD, temp)
+
+if ~adjustable_CPD(CPD), return; end
+
+%assert(approxeq(sum(CPD.counts(:)), CPD.nsamples)); % false!
+switch CPD.prior_type
+ case 'none',
+  counts = reshape(CPD.counts, size(CPD.CPT));
+  CPD.CPT = mk_stochastic(counts);
+ case 'dirichlet',
+  counts = reshape(CPD.counts, size(CPD.CPT));
+  CPD.CPT = mk_stochastic(counts + CPD.dirichlet);
+ 
+ % case 'entropic',
+%   % For an HMM,
+%   % CPT(i,j) = pr(X(t)=j | X(t-1)=i) = transprob(i,j)
+%   % counts(i,j) = E #(X(t-1)=i, X(t)=j) = exp_num_trans(i,j)
+%   Z = 1-temp;
+%   fam_sz = CPD.sizes;
+%   psz = prod(fam_sz(1:end-1));
+%   ssz = fam_sz(end);
+%   counts = reshape(CPD.counts, psz, ssz);
+%   CPT = zeros(psz, ssz);
+%   for i=CPD.entropic_pcases(:)'
+%     [CPT(i,:), logpost] = entropic_map_estimate(counts(i,:), Z);
+%   end
+%   non_entropic_pcases = mysetdiff(1:psz, CPD.entropic_pcases);
+%   for i=non_entropic_pcases(:)'
+%     CPT(i,:) = mk_stochastic(counts(i,:));
+%   end
+%   %for i=1:psz
+%   %  [CPT(i,:), logpost] = entropic_map(counts(i,:), Z);
+%   %end
+%   if CPD.trim & (temp < 2) % at high temps, we would trim everything!
+%     % grad(j) = d log lik / d theta(i ->j)
+%     % CPT(i,j) = 0 => counts(i,j) = 0
+%     % so we can safely replace 0s by 1s in the denominator
+%     denom = CPT(i,:) + (CPT(i,:)==0);
+%     grad = counts(i,:) ./ denom;
+%     trim = find(CPT(i,:) <= exp(-(1/Z)*grad)); % eqn 32
+%     if ~isempty(trim)
+%       CPT(i,trim) = 0;
+%       if all(CPD.trimmed_trans(i,trim)==0) % trimming for 1st time
+% 	disp(['trimming CPT(' num2str(i) ',' num2str(trim) ')']) 
+%       end
+%       CPD.trimmed_trans(i,trim) = 1;
+%     end
+%   end
+%   CPD.CPT = myreshape(CPT, CPD.sizes);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/reset_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/reset_ess.m
new file mode 100644
index 00000000..0ce90e3a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/reset_ess.m
@@ -0,0 +1,7 @@
+function CPD = reset_ess(CPD)
+% RESET_ESS Reset the Expected Sufficient Statistics of a tabular node.
+% CPD = reset_ess(CPD)
+
+%CPD.counts = zeros(size(CPD.CPT));
+CPD.counts = zeros(prod(size(CPD.CPT)), 1);
+CPD.nsamples = 0;    
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/set_fields.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/set_fields.m
new file mode 100644
index 00000000..19c99ac0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/set_fields.m
@@ -0,0 +1,52 @@
+function CPD = set_fields(CPD, varargin)
+% SET_PARAMS Set the parameters (fields) for a tabular_CPD object
+% CPD = set_params(CPD, name/value pairs)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+%
+% CPT, prior, clamped, counts
+%
+% e.g., CPD = set_params(CPD, 'CPT', 'rnd')
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'CPT', 
+    if ischar(args{i+1})
+      switch args{i+1}
+       case 'unif', CPD.CPT = mk_stochastic(myones(CPD.sizes));
+       case 'rnd',  CPD.CPT = mk_stochastic(myrand(CPD.sizes));
+       otherwise,   error(['invalid type ' args{i+1}]);       
+      end
+    elseif isscalarBNT(args{i+1})
+      p = args{i+1};
+      k = CPD.sizes(end);
+      % Bug fix by Hervé Boutrouille 10/1/01
+      CPD.CPT = myreshape(sample_dirichlet(p*ones(1,k), prod(CPD.sizes(1:end-1)), CPD.sizes));   
+      %CPD.CPT = myreshape(sample_dirichlet(p*ones(1,k), prod(CPD.sizes(1:end-1))), CPD.sizes);
+    else
+      CPD.CPT = myreshape(args{i+1}, CPD.sizes);
+    end
+   
+   case 'prior',       
+    if ischar(args{i+1}) & strcmp(args{i+1}, 'unif')
+      CPD.prior = myones(CPD.sizes);
+    elseif isscalarBNT(args{i+1})
+      CPD.prior = args{i+1} * normalise(myones(CPD.sizes));
+    else
+      CPD.prior = myreshape(args{i+1}, CPD.sizes);
+    end
+    
+   %case 'clamped',      CPD.clamped = strcmp(args{i+1}, 'yes');
+   %case 'clamped',      CPD = set_clamped(CPD, strcmp(args{i+1}, 'yes'));
+   case 'clamped',      CPD = set_clamped(CPD, args{i+1});
+    
+   case 'counts',      CPD.counts = args{i+1};
+   
+   otherwise,  
+    %error(['invalid argument name ' args{i}]);       
+  end
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/tabular_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/tabular_CPD.m
new file mode 100644
index 00000000..728302d4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/tabular_CPD.m
@@ -0,0 +1,173 @@
+function CPD = tabular_CPD(bnet, self, varargin)
+% TABULAR_CPD Make a multinomial conditional prob. distrib. (CPT)
+%
+% CPD = tabular_CPD(bnet, node) creates a random CPT.
+%
+% The following arguments can be specified [default in brackets]
+%
+% CPT - specifies the params ['rnd']
+%   - T means use table T; it will be reshaped to the size of node's family.
+%   - 'rnd' creates rnd params (drawn from uniform)
+%   - 'unif' creates a uniform distribution
+% adjustable - 0 means don't adjust the parameters during learning [1]
+% prior_type - defines type of prior ['none']
+%  - 'none' means do ML estimation
+%  - 'dirichlet' means add pseudo-counts to every cell
+%  - 'entropic' means use a prior P(theta) propto exp(-H(theta)) (see Brand)
+% dirichlet_weight - equivalent sample size (ess) of the dirichlet prior [1]
+% dirichlet_type - defines the type of Dirichlet prior ['BDeu']
+%  - 'unif' means put dirichlet_weight in every cell
+%  - 'BDeu' means we put 'dirichlet_weight/(r q)' in every cell
+%    where r = self_sz and q = prod(parent_sz) (see Heckerman)
+% trim - 1 means trim redundant params (rows in CPT) when using entropic prior [0]
+% entropic_pcases - list of assignments to the parents nodes when we should use 
+%      the entropic prior; all other cases will be estimated using ML [1:psz]
+% sparse - 1 means use 1D sparse array to represent CPT [0]
+%
+% e.g., tabular_CPD(bnet, i, 'CPT', T)
+% e.g., tabular_CPD(bnet, i, 'CPT', 'unif', 'dirichlet_weight', 2, 'dirichlet_type', 'unif')
+%
+% REFERENCES
+% M. Brand - "Structure learning in conditional probability models via an entropic  prior
+%   and parameter extinction", Neural Computation 11 (1999): 1155--1182
+% M. Brand - "Pattern discovery via entropy minimization" [covers annealing]
+%   AI & Statistics 1999. Equation numbers refer to this paper, which is available from
+%   www.merl.com/reports/docs/TR98-21.pdf
+% D. Heckerman, D. Geiger and M. Chickering, 
+%   "Learning Bayesian networks: the combination of knowledge and statistical data",
+%   Microsoft Research Tech Report, 1994
+
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  CPD = class(CPD, 'tabular_CPD', discrete_CPD(0, []));
+  return;
+elseif isa(bnet, 'tabular_CPD')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+CPD = init_fields;
+
+ns = bnet.node_sizes;
+ps = parents(bnet.dag, self);
+fam_sz = ns([ps self]);
+psz = prod(ns(ps));
+CPD.sizes = fam_sz;
+CPD.leftright = 0;
+CPD.sparse = 0;
+
+% set defaults
+CPD.CPT = mk_stochastic(myrand(fam_sz));
+CPD.adjustable = 1;
+CPD.prior_type = 'none';
+dirichlet_type = 'BDeu';
+dirichlet_weight = 1;
+CPD.trim = 0;
+selfprob = 0.1;
+CPD.entropic_pcases = 1:psz;
+
+% extract optional args
+args = varargin;
+% check for old syntax CPD(bnet, i, CPT) as opposed to CPD(bnet, i, 'CPT', CPT)
+if ~isempty(args) && ~ischar(args{1})
+  CPD.CPT = myreshape(args{1}, fam_sz);
+  args = [];
+end
+
+for i=1:2:length(args)
+  switch args{i},
+   case 'CPT',
+    T = args{i+1};
+    if ischar(T)
+      switch T
+       case 'unif', CPD.CPT = mk_stochastic(myones(fam_sz));
+       case 'rnd',  CPD.CPT = mk_stochastic(myrand(fam_sz));
+       otherwise,   error(['invalid CPT ' T]);       
+      end
+    else
+      CPD.CPT = myreshape(T, fam_sz);
+    end
+   case 'prior_type', CPD.prior_type = args{i+1};
+   case 'dirichlet_type', dirichlet_type = args{i+1};
+   case 'dirichlet_weight', dirichlet_weight = args{i+1};
+   case 'adjustable', CPD.adjustable = args{i+1};
+   case 'clamped', CPD.adjustable = ~args{i+1};
+   case 'trim', CPD.trim = args{i+1};
+   case 'entropic_pcases', CPD.entropic_pcases = args{i+1};
+   case 'sparse', CPD.sparse = args{i+1};
+   otherwise, error(['invalid argument name: ' args{i}]);       
+  end
+end
+
+switch CPD.prior_type
+ case 'dirichlet',
+  switch dirichlet_type
+   case 'unif', CPD.dirichlet = dirichlet_weight * myones(fam_sz);
+   case 'BDeu',  CPD.dirichlet = (dirichlet_weight/psz) * mk_stochastic(myones(fam_sz));
+   otherwise, error(['invalid dirichlet_type ' dirichlet_type])
+  end
+ case {'entropic', 'none'}
+  CPD.dirichlet = [];
+ otherwise, error(['invalid prior_type ' prior_type])
+end
+
+  
+
+% fields to do with learning
+if ~CPD.adjustable
+  CPD.counts = [];
+  CPD.nparams = 0;
+  CPD.nsamples = [];
+else
+  %CPD.counts = zeros(size(CPD.CPT));
+  CPD.counts = zeros(prod(size(CPD.CPT)), 1);
+  psz = fam_sz(1:end-1);
+  ss = fam_sz(end);
+  if CPD.leftright
+    % For each of the Qps contexts, we specify Q elements on the diagoanl
+    CPD.nparams = Qps * Q;
+  else
+    % sum-to-1 constraint reduces the effective arity of the node by 1
+    CPD.nparams = prod([psz ss-1]);
+  end
+  CPD.nsamples = 0;
+end
+
+CPD.trimmed_trans = [];
+fam_sz = CPD.sizes;
+
+%psz = prod(fam_sz(1:end-1));
+%ssz = fam_sz(end);
+%CPD.trimmed_trans = zeros(psz, ssz); % must declare before reading
+
+%sparse CPT
+if CPD.sparse
+   CPD.CPT = sparse(CPD.CPT(:));
+end
+
+CPD = class(CPD, 'tabular_CPD', discrete_CPD(~CPD.adjustable, fam_sz));
+
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.CPT = [];
+CPD.sizes = [];
+CPD.prior_type = [];
+CPD.dirichlet = [];
+CPD.adjustable = [];
+CPD.counts = [];
+CPD.nparams = [];
+CPD.nsamples = [];
+CPD.trim = [];
+CPD.trimmed_trans = [];
+CPD.leftright = [];
+CPD.entropic_pcases = [];
+CPD.sparse = [];
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/update_ess.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/update_ess.m
new file mode 100644
index 00000000..7602ce9d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/update_ess.m
@@ -0,0 +1,15 @@
+function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+% UPDATE_ESS Update the Expected Sufficient Statistics of a tabular node.
+% function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv)
+
+dom = fmarginal.domain;
+
+if all(hidden_bitv(dom))
+  CPD = update_ess_simple(CPD, fmarginal.T);
+  %fullm = add_ev_to_dmarginal(fmarginal, evidence, ns);
+  %assert(approxeq(fullm.T(:), fmarginal.T(:)))
+else
+  fullm = add_ev_to_dmarginal(fmarginal, evidence, ns);
+  CPD = update_ess_simple(CPD, fullm.T);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/update_ess_simple.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/update_ess_simple.m
new file mode 100644
index 00000000..da3ee023
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/update_ess_simple.m
@@ -0,0 +1,6 @@
+function CPD = update_ess_simple(CPD, counts)
+% UPDATE_ESS_SIMPLE Update the Expected Sufficient Statistics of a tabular node.
+% function CPD = update_ess_simple(CPD, counts)
+
+CPD.nsamples = CPD.nsamples + 1;            
+CPD.counts = CPD.counts + counts(:);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CPD_to_CPT.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CPD_to_CPT.m
new file mode 100644
index 00000000..f3509acf
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CPD_to_CPT.m
@@ -0,0 +1,5 @@
+function CPT = CPD_to_CPT(CPD)
+% CPD_TO_CPT Convert the tabular_decision_node to a CPT
+% CPT = CPD_to_CPT(CPD)
+
+CPT = CPD.CPT;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Entries
new file mode 100644
index 00000000..70a7b527
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Entries
@@ -0,0 +1,6 @@
+/CPD_to_CPT.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/display.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/get_field.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/set_fields.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/tabular_decision_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Repository
new file mode 100644
index 00000000..df9f8a23
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@tabular_decision_node
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/CVS/Entries
new file mode 100644
index 00000000..f11d0269
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/CVS/Entries
@@ -0,0 +1,2 @@
+/tabular_decision_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/CVS/Repository
new file mode 100644
index 00000000..c14a3f7d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@tabular_decision_node/Old
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/tabular_decision_node.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/tabular_decision_node.m
new file mode 100644
index 00000000..7c4c26d5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/Old/tabular_decision_node.m
@@ -0,0 +1,39 @@
+function CPD = tabular_decision_node(sz, CPT)
+% TABULAR_DECISION_NODE Represent the randomized policy over a discrete decision/action node as a table
+% CPD = tabular_decision_node(sz, CPT)
+%
+% sz(1:end-1) is the sizes of the parents, sz(end) is the size of this node
+% By default, CPT is set to the uniform random policy
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  CPD = class(CPD, 'tabular_decision_node');
+  return;
+elseif isa(sz, 'tabular_decision_node')
+  % This might occur if we are copying an object.
+  CPD = sz;
+  return;
+end
+CPD = init_fields;
+
+if nargin < 2
+  CPT = mk_stochastic(myones(sz)); 
+else
+  CPT = myreshape(CPT, sz);
+end
+
+CPD.CPT = CPT;
+CPD.size = sz;
+
+CPD = class(CPD, 'tabular_decision_node');
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.CPT = [];
+CPD.size = [];
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/display.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/display.m
new file mode 100644
index 00000000..a029e5d6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/display.m
@@ -0,0 +1,4 @@
+function display(CPD)
+
+disp('tabular decision node object');
+disp(struct(CPD)); 
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/get_field.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/get_field.m
new file mode 100644
index 00000000..24c2cedc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/get_field.m
@@ -0,0 +1,19 @@
+function vals = get_field(CPD, name)
+% GET_PARAMS Get the parameters (fields) for a tabular_decision_node object
+% vals = get_params(CPD, name)
+%
+% The following fields can be accessed
+%
+% policy - the table containing the policy
+%
+% e.g., policy = get_params(CPD, 'policy')
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'policy',  vals =  CPD.CPT;
+   otherwise,
+    error(['invalid argument name ' args{i}]);
+  end
+end               
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/set_fields.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/set_fields.m
new file mode 100644
index 00000000..4fe62292
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/set_fields.m
@@ -0,0 +1,19 @@
+function CPD = set_params(CPD, varargin)
+% SET_PARAMS Set the parameters (fields) for a tabular_decision_node object
+% CPD = set_params(CPD, name/value pairs)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+%
+% policy - the table containing the policy
+%
+% e.g., CPD = set_params(CPD, 'policy', T)
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'policy',   CPD.CPT = args{i+1};
+   otherwise,
+    error(['invalid argument name ' args{i}]);
+  end
+end               
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/tabular_decision_node.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/tabular_decision_node.m
new file mode 100644
index 00000000..75ca5780
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_decision_node/tabular_decision_node.m
@@ -0,0 +1,45 @@
+function CPD = tabular_decision_node(bnet, self, CPT)
+% TABULAR_DECISION_NODE Represent a stochastic policy over a discrete decision/action node as a table
+% CPD = tabular_decision_node(bnet, self, CPT)
+%
+% node is the number of a node in this equivalence class.
+% CPT is an optional argument (see tabular_CPD for details); by default, it is the uniform policy.
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  CPD = class(CPD, 'tabular_decision_node', discrete_CPD(1, []));
+  return;
+elseif isa(bnet, 'tabular_decision_node')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+CPD = init_fields;
+
+ns = bnet.node_sizes;
+fam = family(bnet.dag, self);
+ps = parents(bnet.dag, self);
+sz = ns(fam);
+
+if nargin < 3
+  CPT = mk_stochastic(myones(sz)); 
+else
+  CPT = myreshape(CPT, sz);
+end
+
+CPD.CPT = CPT;
+CPD.sizes = sz; 
+
+clamped = 1; % don't update using EM
+CPD = class(CPD, 'tabular_decision_node', discrete_CPD(clamped, ns([ps self])));
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.CPT = [];
+CPD.sizes = [];
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Entries
new file mode 100644
index 00000000..45d8ee0d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Entries
@@ -0,0 +1,6 @@
+/convert_to_pot.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/convert_to_table.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/get_field.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/set_fields.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/tabular_kernel.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Repository
new file mode 100644
index 00000000..61f9dcd8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@tabular_kernel
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/CVS/Entries
new file mode 100644
index 00000000..b6c6e11c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/CVS/Entries
@@ -0,0 +1,2 @@
+/tabular_kernel.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/CVS/Repository
new file mode 100644
index 00000000..d2036843
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@tabular_kernel/Old
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/tabular_kernel.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/tabular_kernel.m
new file mode 100644
index 00000000..99f74450
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/Old/tabular_kernel.m
@@ -0,0 +1,45 @@
+function K = tabular_kernel(fg, self)
+% TABULAR_KERNEL Make a table-based local kernel (discrete potential)
+% K = tabular_kernel(fg, self)
+%
+% fg is a factor graph
+% self is the number of a representative domain
+%
+% Use 'set_params_kernel' to adjust the following fields
+%   table - a q[1]xq[2]x... array, where q[i] is the number of values for i'th node
+%       in this domain [default: random values from [0,1], which need not sum to 1]
+
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  K = init_fields;
+  K = class(K, 'tabular_kernel');
+  return;
+elseif isa(fg, 'tabular_kernel')
+  % This might occur if we are copying an object.
+  K = fg;
+  return;
+end
+K = init_fields;
+
+ns = fg.node_sizes;
+dom = fg.doms{self};
+% we don't store the actual domain since it may vary due to parameter tieing
+K.sz = ns(dom);
+K.table = myrand(K.sz);
+
+K = class(K, 'tabular_kernel');
+
+
+%%%%%%%
+
+
+function K = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+K.table = [];
+K.sz = [];
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/convert_to_pot.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/convert_to_pot.m
new file mode 100644
index 00000000..8f9adff1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/convert_to_pot.m
@@ -0,0 +1,37 @@
+function pot = convert_to_pot(CPD, pot_type, domain, evidence)
+% CONVERT_TO_POT Convert a tabular CPD to one or more potentials
+% pot = convert_to_pot(CPD, pot_type, domain, evidence)
+
+% This is the same as discrete_CPD/convert_to_pot,
+% except we didn't want to the kernel to inherit methods like sample_node etc.
+
+sz = CPD.sz;
+ns = zeros(1, max(domain));
+ns(domain) = sz;
+
+odom = domain(~isemptycell(evidence(domain)));
+T = convert_to_table(CPD, domain, evidence);
+
+switch pot_type
+ case 'u',
+  pot = upot(domain, sz, T, 0*myones(sz));  
+ case 'd',
+  ns(odom) = 1;
+  pot = dpot(domain, ns(domain), T);          
+ case 'c',
+  % Since we want the output to be a Gaussian, the whole family must be observed.
+  % In other words, the potential is really just a constant.
+  p = T.p;
+  %p = prob_node(CPD, evidence(domain(end)), evidence(domain(1:end-1)));
+  ns(domain) = 0;
+  pot = cpot(domain, ns(domain), log(p));       
+ case 'cg',
+  T = T(:);
+  ns(odom) = 1;
+  can = cell(1, length(T));
+  for i=1:length(T)
+    can{i} = cpot([], [], log(T(i)));
+  end
+  pot = cgpot(domain, [], ns, can);   
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/convert_to_table.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/convert_to_table.m
new file mode 100644
index 00000000..30703f3a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/convert_to_table.m
@@ -0,0 +1,13 @@
+function T = convert_to_table(CPD, domain, evidence)
+% CONVERT_TO_TABLE Convert a discrete CPD to a table
+% T = convert_to_table(CPD, domain, evidence)
+%
+% We convert the CPD to a CPT, and then lookup the evidence on the discrete parents.
+% The resulting table can easily be converted to a potential.
+
+CPT = CPD.table;
+odom = domain(~isemptycell(evidence(domain)));
+vals = cat(1, evidence{odom});
+map = find_equiv_posns(odom, domain);
+index = mk_multi_index(length(domain), map, vals);
+T = CPT(index{:});               
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/get_field.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/get_field.m
new file mode 100644
index 00000000..3319eadb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/get_field.m
@@ -0,0 +1,11 @@
+function val = get_params_kernel(K, name)
+% GET_PARAMS_KERNEL Accessor function for a field (tabular_kernel)
+% val = get_params_kernel(K, name)
+%
+% e.g., get_params_kernel(K, 'table')
+
+switch name
+ case 'table', val = K.table;
+ otherwise,
+  error(['invalid field name ' name]);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/set_fields.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/set_fields.m
new file mode 100644
index 00000000..2f7ac435
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/set_fields.m
@@ -0,0 +1,13 @@
+function K = set_params_kernel(K, name, val)
+% SET_PARAMS_KERNEL Accessor function for a field (table_kernel)
+% K = set_params_kernel(K, name, val)
+%
+% e.g., K = set_params_kernel(K, 'table', rand(2,3,2)) for a kernel on 3 nodes with 2,3,2 values each
+
+% We should check if the arguments are valid...
+
+switch name
+ case 'table', K.table = val;
+ otherwise,
+  error(['invalid field name ' name]);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/tabular_kernel.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/tabular_kernel.m
new file mode 100644
index 00000000..74a64450
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_kernel/tabular_kernel.m
@@ -0,0 +1,40 @@
+function K = tabular_kernel(sz, table)
+% TABULAR_KERNEL Make a table-based local kernel (discrete potential)
+% K = tabular_kernel(sz, table)
+%
+% sz(i) is the number of values the i'th member of this kernel can have
+% table is an optional array of size sz[1] x sz[2] x... [default: random]
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  K = init_fields;
+  K = class(K, 'tabular_kernel');
+  return;
+elseif isa(sz, 'tabular_kernel')
+  % This might occur if we are copying an object.
+  K = sz;
+  return;
+end
+K = init_fields;
+
+if nargin < 2, table = myrand(sz); end
+
+K.sz = sz;
+K.table = table;
+
+K = class(K, 'tabular_kernel');
+
+
+%%%%%%%
+
+
+function K = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+K.sz = [];
+K.table = [];
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/CVS/Entries
new file mode 100644
index 00000000..c4a82aa3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/CVS/Entries
@@ -0,0 +1,4 @@
+/convert_to_pot.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/display.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/tabular_utility_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/CVS/Repository
new file mode 100644
index 00000000..93b1ac57
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@tabular_utility_node
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/convert_to_pot.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/convert_to_pot.m
new file mode 100644
index 00000000..05eb287f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/convert_to_pot.m
@@ -0,0 +1,11 @@
+function pot = convert_to_pot(CPD, pot_type, domain, evidence)
+% CONVERT_TO_POT Convert a tabular utility node to one or more potentials
+% pot = convert_to_pot(CPD, pot_type, domain, evidence)
+
+switch pot_type
+ case 'u',
+  sz = [CPD.sizes 1]; % the utility node itself has size 1
+  pot = upot(domain, sz, 1*myones(sz), myreshape(CPD.T, sz));   
+ otherwise,
+  error(['can''t convert a utility node to a ' pot_type ' potential']);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/display.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/display.m
new file mode 100644
index 00000000..45b5c01a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/display.m
@@ -0,0 +1,4 @@
+function display(CPD)
+
+disp('tabular utility node object');
+disp(struct(CPD)); 
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/tabular_utility_node.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/tabular_utility_node.m
new file mode 100644
index 00000000..36dcad66
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_utility_node/tabular_utility_node.m
@@ -0,0 +1,46 @@
+function CPD = tabular_utility_node(bnet, node, T)
+% TABULAR_UTILITY_NODE Represent a utility function as a table
+% CPD = tabular_utility_node(bnet, node, T)
+%
+% node is the number of a node in this equivalence class.
+% T is an optional argument (same shape as the CPT in tabular_CPD, but missing the last (child)
+% dimension). By default, entries in T are chosen u.a.r. from 0:1 (using 'rand').
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  clamp = 0;
+  CPD = class(CPD, 'tabular_utility_node');
+  return;
+elseif isa(bnet, 'tabular_utility_node')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+CPD = init_fields;
+
+
+ns = bnet.node_sizes;
+ps = parents(bnet.dag, node);
+sz = ns(ps);
+
+if nargin < 3
+  T = myrand(sz);
+else
+  T = myreshape(T, sz);
+end
+
+CPD.T = T;
+CPD.sizes = sz;
+
+CPD = class(CPD, 'tabular_utility_node');
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.T = [];
+CPD.sizes = [];
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/CVS/Entries
new file mode 100644
index 00000000..62632403
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/CVS/Entries
@@ -0,0 +1,8 @@
+/display.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/evaluate_tree_performance.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/get_field.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/learn_params.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/readme.txt/1.1.1.1/Wed May 29 15:59:54 2002//
+/set_fields.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/tree_CPD.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/CVS/Repository
new file mode 100644
index 00000000..5ec8512b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/@tree_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/display.m b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/display.m
new file mode 100644
index 00000000..4e405bec
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/display.m
@@ -0,0 +1,4 @@
+function display(CPD)
+
+disp('dtree_CPD object');
+disp(struct(CPD)); 
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/evaluate_tree_performance.m b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/evaluate_tree_performance.m
new file mode 100644
index 00000000..2f72a5b9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/evaluate_tree_performance.m
@@ -0,0 +1,82 @@
+function [score,outputs] = evaluate(CPD, fam, data, ns, cnodes)
+% Evaluate evaluate the performance of the classification/regression tree on given complete data
+% score = evaluate(CPD, fam, data, ns, cnodes)
+%
+% fam(i) is the node id of the i-th node in the family of nodes, self node is the last one
+% data(i,m) is the value of node i in case m (can be cell array).
+% ns(i) is the node size for the i-th node in the whold bnet
+% cnodes(i) is the node id for the i-th continuous node in the whole bnet
+%  
+% Output
+% score is the classification accuracy (for classification) 
+%          or mean square deviation (for regression)
+%            here for every case we use the mean value at the tree leaf node as its predicted value
+% outputs(i) is the predicted output value for case i
+%
+% Author: yimin.zhang@intel.com
+% Last updated: Jan. 19, 2002
+
+
+if iscell(data)
+  local_data = cell2num(data(fam,:));
+else
+  local_data = data(fam, :);
+end
+
+%get local node sizes and node types
+node_sizes = ns(fam);
+node_types = zeros(1,size(ns,2)); %all nodes are disrete
+node_types(cnodes)=1;
+node_types=node_types(fam);
+
+fam_size=size(fam,2);
+output_type = node_types(fam_size);
+
+num_cases=size(local_data,2);
+total_error=0;
+
+outputs=zeros(1,num_cases);
+for i=1:num_cases
+  %class one case using the tree
+  cur_node=CPD.tree.root;  % at the root node of the tree
+  while (1)
+    if (CPD.tree.nodes(cur_node).is_leaf==1)
+      if (output_type==0) %output is discrete
+        %use the class with max probability as the output  
+        [maxvalue,class_id]=max(CPD.tree.nodes(cur_node).probs);
+        outputs(i)=class_id;
+        if (class_id~=local_data(fam_size,i))
+          total_error=total_error+1;
+        end
+      else   %output is continuous
+        %use the mean as the value
+        outputs(i)=CPD.tree.nodes(cur_node).mean;
+        cur_deviation = CPD.tree.nodes(cur_node).mean-local_data(fam_size,i);
+        total_error=total_error+cur_deviation*cur_deviation;
+      end
+      break;
+    end
+    cur_attr = CPD.tree.nodes(cur_node).split_id; 
+    attr_val = local_data(cur_attr,i);
+    if (node_types(cur_attr)==0)  %discrete attribute
+        % goto the attr_val -th child
+        cur_node = CPD.tree.nodes(cur_node).children(attr_val);
+    else
+        if (attr_val <= CPD.tree.nodes(cur_node).split_threshhold)
+          cur_node = CPD.tree.nodes(cur_node).children(1);
+        else
+          cur_node = CPD.tree.nodes(cur_node).children(2);  
+        end
+    end
+    if (cur_node > CPD.tree.num_node)
+      fprintf('Fatal error: Tree structure corrupted.\n');
+      return;
+    end
+  end
+  %update the classification error number
+end
+if (output_type==0)
+  score=1-total_error/num_cases;
+else
+  score=total_error/num_cases;
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/get_field.m b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/get_field.m
new file mode 100644
index 00000000..a299831f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/get_field.m
@@ -0,0 +1,16 @@
+function val = get_params(CPD, name)
+% GET_PARAMS Get the parameters (fields) for a tabular_CPD object
+% val = get_params(CPD, name)
+%
+% The following fields can be accessed
+%
+% cpt       - the CPT
+%
+% e.g., CPT = get_params(CPD, 'cpt')
+
+switch name
+ case 'cpt',      val = CPD.CPT;
+ case 'tree',     val = CPD.tree;
+ otherwise,
+  error(['invalid argument name ' name]);
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/learn_params.m b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/learn_params.m
new file mode 100644
index 00000000..baa48ed1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/learn_params.m
@@ -0,0 +1,642 @@
+function CPD = learn_params(CPD, fam, data, ns, cnodes, varargin)
+% LEARN_PARAMS Construct classification/regression tree given complete data
+% CPD = learn_params(CPD, fam, data, ns, cnodes)
+%
+% fam(i) is the node id of the i-th node in the family of nodes, self node is the last one
+% data(i,m) is the value of node i in case m (can be cell array).
+% ns(i) is the node size for the i-th node in the whold bnet
+% cnodes(i) is the node id for the i-th continuous node in the whole bnet
+%  
+% The following optional arguments can be specified in the form of name/value pairs:
+% stop_cases: for early stop (pruning). A node is not split if it has less than k cases. default is 0.
+% min_gain: for early stop (pruning). 
+%     For discrete output: A node is not split when the gain of best split is less than min_gain. default is 0.  
+%     For continuous (cts) outpt: A node is not split when the gain of best split is less than min_gain*score(root) 
+%                                 (we denote it cts_min_gain). default is 0.006
+% %%%%%%%%%%%%%%%%%%%Struction definition of dtree_CPD.tree%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% tree.num_node               the last position in tree.nodes array for adding new nodes,
+%                             it is not always same to number of nodes in a tree, because some position in the 
+%                             tree.nodes array can be set to unused (e.g. in tree pruning)  
+% tree.nodes is the array of nodes in the tree plus some unused nodes.
+% tree.nodes(1) is the root for the tree.
+%
+% Below is the attributes for each node
+% tree.nodes(i).used;     % flag this node is used (0 means node not used, it can be removed from tree to save memory)
+% tree.nodes(i).is_leaf;  % if 1 means this node is a leaf, if 0 not a leaf.
+% tree.nodes(i).children; % children(i) is the node number in tree.nodes array for the i-th child node
+% tree.nodes(i).split_id; % the attribute id used to split this node
+% tree.nodes(i).split_threshhold; % the threshhold for continuous attribute to split this node
+% %%%%%attributes specially for classification tree (discrete output)
+% tree.nodes(i).probs     % probs(i) is the prob for i-th value of class node 
+%                         % For three output class, the probs = [0.9 0.1 0.0] means the probability of 
+%                         % class 1 is 0.9, for class 2 is 0.1, for class 3 is 0.0.
+% %%%%%attributes specially for regression tree (continuous output)                          
+% tree.nodes(i).mean      % mean output value for this node
+% tree.nodes(i).std       % standard deviation for output values in this node
+%
+% Author: yimin.zhang@intel.com
+% Last updated: Jan. 19, 2002
+
+% Want list:
+% (1) more efficient for cts attributes: get the values of cts attributes at first (the begining of build_tree function), then doing bi_search in finding threshhold
+% (2) pruning classification tree using Pessimistic Error Pruning
+% (3) bi_search for strings (used for transform data to BNT format)
+
+global tree %tree must be global so that it can be accessed in recursive slitting function
+global cts_min_gain
+tree=[]; % clear the tree
+tree.num_node=0;
+cts_min_gain=0;
+
+stop_cases=0;
+min_gain=0;
+
+args = varargin;
+nargs = length(args);
+if (nargs>0)
+  if isstr(args{1})
+    for i=1:2:nargs
+      switch args{i},
+        case 'stop_cases', stop_cases = args{i+1};   
+        case 'min_gain', min_gain = args{i+1};
+      end
+    end
+  else
+    error(['error in input parameters']);
+  end
+end
+
+if iscell(data)
+  local_data = cell2num(data(fam,:));
+else
+  local_data = data(fam, :);
+end
+%counts = compute_counts(local_data, CPD.sizes);
+%CPD.CPT = mk_stochastic(counts + CPD.prior); % bug fix 11/5/01
+node_types = zeros(1,size(ns,2)); %all nodes are disrete
+node_types(cnodes)=1;
+%make the data be BNT compliant (values for discrete nodes are from 1-n, here n is the node size)
+%trans_data=transform_data(local_data,'tmp.dat',[]); %here no cts nodes
+
+build_dtree (CPD, local_data, ns(fam), node_types(fam),stop_cases,min_gain);
+%CPD.tree=copy_tree(tree);
+CPD.tree=tree; %copy the tree constructed to CPD
+
+
+function new_tree = copy_tree(tree)
+% copy the tree to new_tree
+new_tree.num_node=tree.num_node;
+new_tree.root = tree.root;
+for i=1:tree.num_node
+  new_tree.nodes(i)=tree.nodes(i);
+end
+
+
+function build_dtree (CPD, fam_ev, node_sizes, node_types,stop_cases,min_gain)
+global tree
+global cts_min_gain
+
+tree.num_node=0; %the current number of nodes in the tree
+tree.root=1;
+
+T = 1:size(fam_ev,2) ; %all cases
+candidate_attrs = 1:(size(node_sizes,2)-1); %all attributes
+node_id=1;  %the root node
+lastnode=size(node_sizes,2); %the last element in all nodes is the dependent variable (category node)
+num_cat=node_sizes(lastnode);
+
+% get minimum gain for cts output (used in stop splitting)
+if (node_types(size(fam_ev,1))==1) %cts output
+  N = size(fam_ev,2);
+  output_id = size(fam_ev,1);
+  cases_T = fam_ev(output_id,:); %get all the output value for cases T
+  std_T = std(cases_T);
+  avg_y_T = mean(cases_T);
+  sqr_T = cases_T - avg_y_T;
+  cts_min_gain = min_gain*(sum(sqr_T.*sqr_T)/N);  % min_gain * (R(root) = 1/N * SUM(y-avg_y)^2)
+end  
+
+split_dtree (CPD, fam_ev, node_sizes, node_types, stop_cases,min_gain, T, candidate_attrs, num_cat);
+  
+
+
+% pruning method
+% (1) Restrictions on minimum node size: A node is not split if it has smaller than k cases.
+% (2) Threshholds on impurity: a threshhold is imposed on the splitting test score. Threshhold can be 
+% imposed on local goodness measure (the gain_ratio of a node) or global goodness.
+% (3) Mininum Error Pruning (MEP), (no need pruning set)
+%     Prune if static error<=backed-up error
+%      Static error at node v: e(v) = (Nc + 1)/(N+k) (laplace estimate, prior for each class equal) 
+%        here N is # of all examples, Nc is # of majority class examples, k is number of classes 
+%      Backed-up error at node v: (Ti is the i-th subtree root)
+%         E(T) = Sum_1_to_n(pi*e(Ti))
+% (4) Pessimistic Error Pruning (PEP), used in Quilan C4.5 (no need pruning set, efficient because of pruning top-down)
+%       Probability of error (apparent error rate)
+%           q = (N-Nc+0.5)/N
+%         where N=#examples, Nc=#examples in majority class
+%     Error of a node v (if pruned)  q(v)= (Nv- Nc,v + 0.5)/Nv
+%     Error of a subtree   q(T)= Sum_of_l_leaves(Nl - Nc,l + 0.5)/Sum_of_l_leaves(Nl)
+%     Prune if q(v)<=q(T)
+% 
+% Implementation statuts:
+% (1)(2) has been implemented as the input parameters of learn_params.
+% (4) is implemented in this function
+function pruning(fam_ev,node_sizes,node_types)
+% PRUNING prune the constructed tree using PEP
+% pruning(fam_ev,node_sizes,node_types)
+%
+% fam_ev(i,j)  is the value of attribute i in j-th training cases (for whole tree), the last row is for the class label (self_ev)
+% node_sizes(i) is the node size for the i-th node in the family
+% node_types(i) is the node type for the i-th node in the family, 0 for disrete node, 1 for continous node
+% the global parameter 'tree' is for storing the input tree and the pruned tree
+
+
+function split_T = split_cases(fam_ev,node_sizes,node_types,T,node_i, threshhold)
+% SPLIT_CASES split the cases T according to values of node_i in the family
+% split_T = split_cases(fam_ev,node_sizes,node_types,T,node_i)
+%
+% fam_ev(i,j)  is the value of attribute i in j-th training cases (for whole tree), the last row is for the class label (self_ev)
+% node_sizes(i) is the node size for the i-th node in the family
+% node_types(i) is the node type for the i-th node in the family, 0 for disrete node, 1 for continous node
+% node_i is the attribute we need to split
+
+if (node_types(node_i)==0) %discrete attribute
+  %init the subsets of T
+  split_T = cell(1,node_sizes(node_i)); %T will be separated into |node_size of i| subsets according to different values of node i
+  for i=1:node_sizes(node_i)   % here we assume that the value of an attribute is 1:node_size
+    split_T{i}=zeros(1,0);
+  end
+
+  size_t = size(T,2);
+  for i=1:size_t
+    case_id = T(i);
+    %put this case into one subset of split_T according to its value for node_i
+    value = fam_ev(node_i,case_id); 
+    pos = size(split_T{value},2)+1;
+    split_T{value}(pos)=case_id;  % here assumes the value of an attribute is 1:node_size 
+  end
+else %continuous attribute
+  %init the subsets of T
+  split_T = cell(1,2); %T will be separated into 2 subsets (<=threshhold) (>threshhold)
+  for i=1:2   
+    split_T{i}=zeros(1,0);
+  end
+
+  size_t = size(T,2);
+  for i=1:size_t
+    case_id = T(i);
+    %put this case into one subset of split_T according to its value for node_i
+    value = fam_ev(node_i,case_id); 
+    subset_num=1;
+    if (value>threshhold)
+      subset_num=2;
+    end  
+    pos = size(split_T{subset_num},2)+1;
+    split_T{subset_num}(pos)=case_id;  
+  end
+end
+
+
+  
+function new_node = split_dtree (CPD, fam_ev, node_sizes, node_types, stop_cases, min_gain, T, candidate_attrs, num_cat)
+% SPLIT_TREE Split the tree at node node_id with cases T (actually it is just indexes to family evidences).
+% new_node = split_dtree (fam_ev, node_sizes, node_types, T, node_id, num_cat, method)
+%
+% fam_ev(i,j)  is the value of attribute i in j-th training cases (for whole tree), the last row is for the class label (self_ev)
+% node_sizes{i} is the node size for the i-th node in the family
+% node_types{i} is the node type for the i-th node in the family, 0 for disrete node, 1 for continous node
+% stop_cases is the threshold of number of cases to stop slitting
+% min_gain is the minimum gain need to split a node
+% T(i) is the index of i-th cases in current decision tree node, we need split it further
+% candidate_attrs(i) the node id for the i-th attribute that still need to be considered as split attribute 
+%%%%% node_id is the index of current node considered for a split
+% num_cat is the number of output categories for the decision tree
+% output:
+% new_node is the new node created
+global tree
+global cts_min_gain
+
+size_fam = size(fam_ev,1);            %number of family size
+output_type = node_types(size_fam);   %the type of output for the tree (0 is discrete, 1 is continuous)
+size_attrs = size(candidate_attrs,2); %number of candidate attributes
+size_t = size(T,2);                   %number of training cases in this tree node
+
+%(1)computeFrequenceyForEachClass(T)
+if (output_type==0) %discrete output
+  class_freqs = zeros(1,num_cat);
+  for i=1:size_t
+    case_id = T(i);
+    case_class = fam_ev(size_fam,case_id); %get the class label for this case
+    class_freqs(case_class)=class_freqs(case_class)+1;
+  end
+else  %cts output
+  N = size(fam_ev,2);
+  cases_T = fam_ev(size(fam_ev,1),T); %get the output value for cases T
+  std_T = std(cases_T);
+end
+
+%(2) if OneClass (for discrete output) or same output value (for cts output) or Class With #examples < stop_cases
+%         return a leaf;
+%    create a decision node N;
+
+% get majority class in this node
+if (output_type == 0)
+  top1_class = 0;       %the class with the largest number of cases
+  top1_class_cases = 0; %the number of cases in top1_class
+  [top1_class_cases,top1_class]=max(class_freqs);
+end
+  
+if (size_t==0)     %impossble
+  new_node=-1;
+  fprintf('Fatal error: please contact the author. \n');
+  return;
+end
+
+% stop splitting if needed
+  %for discrete output: one class 
+  %for cts output, all output value in cases are same
+  %cases too little
+if ( (output_type==0 & top1_class_cases == size_t) | (output_type==1 & std_T == 0) | (size_t < stop_cases))             
+  %create one new leaf node
+  tree.num_node=tree.num_node+1;
+  tree.nodes(tree.num_node).used=1; %flag this node is used (0 means node not used, it will be removed from tree at last to save memory)
+  tree.nodes(tree.num_node).is_leaf=1;
+  tree.nodes(tree.num_node).children=[];
+  tree.nodes(tree.num_node).split_id=0;  %the attribute(parent) id to split this tree node
+  tree.nodes(tree.num_node).split_threshhold=0;  
+  if (output_type==0)
+    tree.nodes(tree.num_node).probs=class_freqs/size_t; %the prob for each value of class node 
+
+    %  tree.nodes(tree.num_node).probs=zeros(1,num_cat); %the prob for each value of class node 
+    %  tree.nodes(tree.num_node).probs(top1_class)=1; %use the majority class of parent node, like for binary class, 
+                                                   %and majority is class 2, then the CPT is [0 1]
+                                                   %we may need to use prior to do smoothing, to get [0.001 0.999]
+    tree.nodes(tree.num_node).error.self_error=1-top1_class_cases/size_t; %the classfication error in this tree node when use default class
+    tree.nodes(tree.num_node).error.all_error=1-top1_class_cases/size_t;  %no total classfication error in this tree node and its subtree
+    tree.nodes(tree.num_node).error.all_error_num=size_t - top1_class_cases;
+    fprintf('Create leaf node(onecla) %d. Class %d Cases %d Error %d \n',tree.num_node, top1_class, size_t, size_t - top1_class_cases );
+  else
+    avg_y_T = mean(cases_T);
+    tree.nodes(tree.num_node).mean = avg_y_T; 
+    tree.nodes(tree.num_node).std = std_T;
+    fprintf('Create leaf node(samevalue) %d. Mean %8.4f Std %8.4f Cases %d \n',tree.num_node, avg_y_T, std_T, size_t);
+  end  
+  new_node = tree.num_node;
+  return;
+end
+    
+%create one new node
+tree.num_node=tree.num_node+1;
+tree.nodes(tree.num_node).used=1; %flag this node is used (0 means node not used, it will be removed from tree at last to save memory)
+tree.nodes(tree.num_node).is_leaf=1;
+tree.nodes(tree.num_node).children=[];
+tree.nodes(tree.num_node).split_id=0;
+tree.nodes(tree.num_node).split_threshhold=0;  
+if (output_type==0)
+  tree.nodes(tree.num_node).error.self_error=1-top1_class_cases/size_t; 
+  tree.nodes(tree.num_node).error.all_error=0;
+  tree.nodes(tree.num_node).error.all_error_num=0;
+else
+  avg_y_T = mean(cases_T);
+  tree.nodes(tree.num_node).mean = avg_y_T; 
+  tree.nodes(tree.num_node).std = std_T;
+end
+new_node = tree.num_node;
+
+%Stop splitting if no attributes left in this node
+if (size_attrs==0) 
+  if (output_type==0)
+    tree.nodes(tree.num_node).probs=class_freqs/size_t; %the prob for each value of class node 
+    tree.nodes(tree.num_node).error.all_error=1-top1_class_cases/size_t;  
+    tree.nodes(tree.num_node).error.all_error_num=size_t - top1_class_cases;
+    fprintf('Create leaf node(noattr) %d. Class %d Cases %d Error %d \n',tree.num_node, top1_class, size_t, size_t - top1_class_cases );
+  else
+    fprintf('Create leaf node(noattr) %d. Mean %8.4f Std %8.4f Cases %d \n',tree.num_node, avg_y_T, std_T, size_t);
+  end
+  return;
+end
+      
+  
+%(3) for each attribute A
+%        ComputeGain(A);
+max_gain=0;  %the max gain score (for discrete information gain or gain ration, for cts node the R(T))
+best_attr=0;  %the attribute with the max_gain
+best_split = []; %the split of T according to the value of best_attr
+cur_best_threshhold = 0; %the threshhold for split continuous attribute
+best_threshhold=0;
+
+% compute Info(T) (for discrete output)
+if (output_type == 0)
+  class_split_T = split_cases(fam_ev,node_sizes,node_types,T,size(fam_ev,1),0); %split cases according to class
+  info_T = compute_info (fam_ev, T, class_split_T);
+else % compute R(T) (for cts output)
+%  N = size(fam_ev,2);
+%  cases_T = fam_ev(size(fam_ev,1),T); %get the output value for cases T
+%  std_T = std(cases_T);
+%  avg_y_T = mean(cases_T);
+  sqr_T = cases_T - avg_y_T;
+  R_T = sum(sqr_T.*sqr_T)/N;  % get R(T) = 1/N * SUM(y-avg_y)^2
+  info_T = R_T;
+end
+
+for i=1:(size_fam-1)
+  if (myismember(i,candidate_attrs))  %if this attribute still in the candidate attribute set
+    if (node_types(i)==0) %discrete attibute
+      split_T = split_cases(fam_ev,node_sizes,node_types,T,i,0); %split cases according to value of attribute i
+      % For cts output, we compute the least square gain.
+      % For discrete output, we compute gain ratio
+      cur_gain = compute_gain(fam_ev,node_sizes,node_types,T,info_T,i,split_T,0,output_type); %gain ratio
+    else %cts attribute
+      %get the values of this attribute
+      ev = fam_ev(:,T);
+      values = ev(i,:);
+      sort_v = sort(values); 
+        %remove the duplicate values in sort_v
+      v_set = unique(sort_v);  
+      best_gain = 0;
+      best_threshhold = 0;
+      best_split1 = [];
+      
+      %find the best split for this cts attribute
+      % see "Quilan 96: Improved Use of Continuous Attributes in C4.5"
+      for j=1:(size(v_set,2)-1)
+        mid_v = (v_set(j)+v_set(j+1))/2; 
+        split_T = split_cases(fam_ev,node_sizes,node_types,T,i,mid_v); %split cases according to value of attribute i (<=mid_v)
+        % For cts output, we compute the least square gain.
+        % For discrete output, we use Quilan 96: use information gain instead of gain ratio to select threshhold
+        cur_gain = compute_gain(fam_ev,node_sizes,node_types,T,info_T,i,split_T,1,output_type); 
+        %if (i==6)
+        %  fprintf('gain %8.5f threshhold %6.3f spliting %d\n', cur_gain, mid_v, size(split_T{1},2));
+        %end
+
+        if (best_gain < cur_gain)
+          best_gain = cur_gain;
+          best_threshhold = mid_v;
+          %best_split1 = split_T;     %here we need to copy array, not good!!! (maybe we can compute after we get best_attr
+        end
+      end
+      %recalculate the gain_ratio of the best_threshhold
+      split_T = split_cases(fam_ev,node_sizes,node_types,T,i,best_threshhold);
+      best_gain = compute_gain(fam_ev,node_sizes,node_types,T,info_T,i,split_T,0,output_type); %gain_ratio
+      if (output_type==0) %for discrete output
+        cur_gain = best_gain-log2(size(v_set,2)-1)/size_t; % Quilan 96: use the gain_ratio-log2(N-1)/|D| as the gain of this attr
+      else                %for cts output
+        cur_gain = best_gain;
+      end
+    end
+    
+    if (max_gain < cur_gain)
+      max_gain = cur_gain;
+      best_attr = i;
+      cur_best_threshhold=best_threshhold;  %save the threshhold
+      %best_split = split_T;        %here we need to copy array, not good!!! So we will recalculate in below line 313
+    end
+  end
+end
+
+% stop splitting if gain is too small
+if (max_gain==0 | (output_type==0 & max_gain < min_gain) | (output_type==1 & max_gain < cts_min_gain)) 
+  if (output_type==0)
+    tree.nodes(tree.num_node).probs=class_freqs/size_t; %the prob for each value of class node 
+    tree.nodes(tree.num_node).error.all_error=1-top1_class_cases/size_t;  
+    tree.nodes(tree.num_node).error.all_error_num=size_t - top1_class_cases;
+    fprintf('Create leaf node(nogain) %d. Class %d Cases %d Error %d \n',tree.num_node, top1_class, size_t, size_t - top1_class_cases );
+  else
+    fprintf('Create leaf node(nogain) %d. Mean %8.4f Std %8.4f Cases %d \n',tree.num_node, avg_y_T, std_T, size_t);
+  end
+  return;
+end
+
+%get the split of cases according to the best split attribute
+if (node_types(best_attr)==0) %discrete attibute
+  best_split = split_cases(fam_ev,node_sizes,node_types,T,best_attr,0);  
+else  
+  best_split = split_cases(fam_ev,node_sizes,node_types,T,best_attr,cur_best_threshhold);
+end
+  
+%(4) best_attr = AttributeWithBestGain;
+%(5) if best_attr is continuous             ???? why need this? maybe the value in the decision tree must appeared in data
+%       find threshhold in all cases that <= max_V
+%    change the split of T
+tree.nodes(tree.num_node).split_id=best_attr;
+tree.nodes(tree.num_node).split_threshhold=cur_best_threshhold; %for cts attribute only
+
+%note: below threshhold rejust is linera search, so it is slow. A better method is described in paper "Efficient C4.5"
+%if (output_type==0)
+if (node_types(best_attr)==1)  %is a continuous attribute
+  %find the value that approximate best_threshhold from below (the largest that <= best_threshhold)
+  best_value=0;
+  for i=1:size(fam_ev,2)  %note: need to search in all cases for all tree, not just in cases for this node
+    val = fam_ev(best_attr,i);
+    if (val <= cur_best_threshhold & val > best_value) %val is more clear to best_threshhold
+      best_value=val;
+    end
+  end
+  tree.nodes(tree.num_node).split_threshhold=best_value; %for cts attribute only
+end
+%end
+  
+if (output_type == 0)
+  fprintf('Create node %d split at %d gain %8.4f Th %d. Class %d Cases %d Error %d \n',tree.num_node, best_attr, max_gain, tree.nodes(tree.num_node).split_threshhold, top1_class, size_t, size_t - top1_class_cases );
+else
+  fprintf('Create node %d split at %d gain %8.4f Th %d. Mean %8.4f Cases %d\n',tree.num_node, best_attr, max_gain, tree.nodes(tree.num_node).split_threshhold, avg_y_T, size_t );
+end
+  
+%(6) Foreach T' in the split_T
+%        if T' is Empty
+%            Child of node_id is a leaf
+%        else
+%            Child of node_id = split_tree (T')
+tree.nodes(new_node).is_leaf=0; %because this node will be split, it is not leaf now
+for i=1:size(best_split,2)
+  if (size(best_split{i},2)==0) %T(i) is empty
+    %create one new leaf node
+    tree.num_node=tree.num_node+1;
+    tree.nodes(tree.num_node).used=1; %flag this node is used (0 means node not used, it will be removed from tree at last to save memory)
+    tree.nodes(tree.num_node).is_leaf=1;
+    tree.nodes(tree.num_node).children=[];
+    tree.nodes(tree.num_node).split_id=0;
+    tree.nodes(tree.num_node).split_threshhold=0;  
+    if (output_type == 0)
+      tree.nodes(tree.num_node).probs=zeros(1,num_cat); %the prob for each value of class node 
+      tree.nodes(tree.num_node).probs(top1_class)=1; %use the majority class of parent node, like for binary class, 
+                                                   %and majority is class 2, then the CPT is [0 1]
+                                                   %we may need to use prior to do smoothing, to get [0.001 0.999]
+      tree.nodes(tree.num_node).error.self_error=0; 
+      tree.nodes(tree.num_node).error.all_error=0;  
+      tree.nodes(tree.num_node).error.all_error_num=0;
+    else
+      tree.nodes(tree.num_node).mean = avg_y_T; %just use parent node's mean value
+      tree.nodes(tree.num_node).std = std_T;
+    end
+    %add the new leaf node to parents
+    num_children=size(tree.nodes(new_node).children,2);
+    tree.nodes(new_node).children(num_children+1)=tree.num_node;
+    if (output_type==0)
+      fprintf('Create leaf node(nullset) %d. %d-th child of Father %d Class %d\n',tree.num_node, i, new_node, top1_class );
+    else
+      fprintf('Create leaf node(nullset) %d. %d-th child of Father %d \n',tree.num_node, i, new_node );
+    end
+
+  else
+    if (node_types(best_attr)==0)  % if attr is discrete, it should be removed from the candidate set  
+      new_candidate_attrs = mysetdiff(candidate_attrs,[best_attr]);
+    else
+      new_candidate_attrs = candidate_attrs;
+    end
+    new_sub_node = split_dtree (CPD, fam_ev, node_sizes, node_types, stop_cases, min_gain, best_split{i}, new_candidate_attrs, num_cat);  
+    %tree.nodes(parent_id).error.all_error += tree.nodes(new_sub_node).error.all_error;
+    fprintf('Add subtree node %d to %d. #nodes %d\n',new_sub_node,new_node, tree.num_node );
+
+%   tree.nodes(new_node).error.all_error_num = tree.nodes(new_node).error.all_error_num + tree.nodes(new_sub_node).error.all_error_num;
+    %add the new leaf node to parents
+    num_children=size(tree.nodes(new_node).children,2);
+    tree.nodes(new_node).children(num_children+1)=new_sub_node;
+  end
+end   
+  
+%(7) Compute errors of N; for doing pruning
+%    get the total error for the subtree
+if (output_type==0)
+  tree.nodes(new_node).error.all_error=tree.nodes(new_node).error.all_error_num/size_t;
+end
+%doing pruning, but doing here is not so efficient, because it is bottom up.
+%if tree.nodes()
+%after doing pruning, need to update the all_error to self_error
+
+%(8) Return N
+  
+
+
+
+%(1) For discrete output, we use GainRatio defined as below
+%  			         Gain(X,T)
+% 	GainRatio(X,T) = ----------
+% 			         SplitInfo(X,T)
+%   where
+%   Gain(X,T) = Info(T) - Info(X,T)
+%    				                       |Ti|
+% 	Info(X,T) = Sum for i from 1 to n of ( ---- * Info(Ti))
+%                                          |T|
+ 			 
+%   SplitInfo(D,T) is the information due to the split of T on the basis
+%    of the value of the categorical attribute D. Thus SplitInfo(D,T) is
+%  		 I(|T1|/|T|, |T2|/|T|, .., |Tm|/|T|)
+%    where {T1, T2, .. Tm} is the partition of T induced by the value of D.
+
+%   Definition of Info(Ti)
+%     If a set T of records is partitioned into disjoint exhaustive classes C1, C2, .., Ck on the basis of the 
+%     value of the categorical attribute, then the information needed to identify the class of an element of T 
+%     is Info(T) = I(P), where P is the probability distribution of the partition (C1, C2, .., Ck): 
+%     	P = (|C1|/|T|, |C2|/|T|, ..., |Ck|/|T|)
+%     Here I(P) is defined as
+%       I(P) = -(p1*log(p1) + p2*log(p2) + .. + pn*log(pn))
+% 
+%(2) For continuous output (regression tree), we use least squares score (adapted from Leo Breiman's book "Classification and regression trees", page 231
+%    The original support only binary split, we further extend it to permit multiple-child split
+%                                        
+%     Delta_R = R(T) - Sum for all childe nodes Ti (R(Ti))
+%     Where R(Ti)= 1/N * Sum for all cases i in node Ti ((yi - avg_y(Ti))^2)
+%     here N is the number of all training cases for construct the regression tree
+%          avg_y(Ti) is the average value for output variable for the cases in node Ti
+
+function gain_score = compute_gain (fam_ev, node_sizes, node_types, T, info_T, attr_id, split_T, score_type, output_type)
+% COMPUTE_GAIN Compute the score for the split of cases T using attribute attr_id
+% gain_score = compute_gain (fam_ev, T, attr_id, node_size, method)
+%
+% fam_ev(i,j)  is the value of attribute i in j-th training cases, the last row is for the class label (self_ev)
+% T(i) is the index of i-th cases in current decision tree node, we need split it further
+% attr_id is the index of current node considered for a split
+% split_T{i} is the i_th subset in partition of cases T according to the value of attribute attr_id
+% score_type if 0, is gain ratio, 1 is information gain (only apply to discrete output)
+% node_size(i) the node size of i-th node in the family
+% output_type: 0 means discrete output, 1 means continuous output.
+gain_score=0;
+% ***********for DISCRETE output*******************************************************
+if (output_type == 0)
+  % compute Info(T)
+  total_cnt = size(T,2);
+  if (total_cnt==0)
+    return;
+  end;
+  %class_split_T = split_cases(fam_ev,node_sizes,node_types,T,size(fam_ev,1),0); %split cases according to class
+  %info_T = compute_info (fam_ev, T, class_split_T);
+
+  % compute Info(X,T)
+  num_class = size(split_T,2); 
+  subset_sizes = zeros(1,num_class);
+  info_ti = zeros(1,num_class);
+  for i=1:num_class
+    subset_sizes(i)=size(split_T{i},2);
+    if (subset_sizes(i)~=0)
+      class_split_Ti = split_cases(fam_ev,node_sizes,node_types,split_T{i},size(fam_ev,1),0); %split cases according to class
+      info_ti(i) = compute_info(fam_ev, split_T{i}, class_split_Ti);
+    end
+  end    
+  ti_ratios = subset_sizes/total_cnt;  %get the |Ti|/|T|
+  info_X_T = sum(ti_ratios.*info_ti);
+
+  %get Gain(X,T)
+  gain_X_T = info_T - info_X_T;
+
+  if (score_type == 1) %information gain
+    gain_score=gain_X_T;
+    return;
+  end
+  %compute the SplitInfo(X,T)   //is this also for cts attr, only split into two subsets
+  splitinfo_T = compute_info (fam_ev, T, split_T);
+  if (splitinfo_T~=0)
+    gain_score = gain_X_T/splitinfo_T;
+  end
+
+% ************for continuous output**************************************************
+else 
+  N = size(fam_ev,2);
+
+  % compute R(Ti)
+  num_class = size(split_T,2); 
+  R_Ti = zeros(1,num_class);
+  for i=1:num_class
+    if (size(split_T{i},2)~=0)
+      cases_T = fam_ev(size(fam_ev,1),split_T{i});
+      avg_y_T = mean(cases_T);
+      sqr_T = cases_T - avg_y_T;
+      R_Ti(i) = sum(sqr_T.*sqr_T)/N;  % get R(Ti) = 1/N * SUM(y-avg_y)^2
+    end
+  end
+  %delta_R = R(T) - SUM(R(Ti))
+  gain_score = info_T - sum(R_Ti);
+
+end
+
+
+%   Definition of Info(Ti)
+%     If a set T of records is partitioned into disjoint exhaustive classes C1, C2, .., Ck on the basis of the 
+%     value of the categorical attribute, then the information needed to identify the class of an element of T 
+%     is Info(T) = I(P), where P is the probability distribution of the partition (C1, C2, .., Ck): 
+%     	P = (|C1|/|T|, |C2|/|T|, ..., |Ck|/|T|)
+%     Here I(P) is defined as
+%       I(P) = -(p1*log(p1) + p2*log(p2) + .. + pn*log(pn))
+function info = compute_info (fam_ev, T, split_T)
+% COMPUTE_INFO compute the information for the split of T into split_T
+% info = compute_info (fam_ev, T, split_T)
+
+total_cnt = size(T,2);
+num_class = size(split_T,2);
+subset_sizes = zeros(1,num_class);
+probs = zeros(1,num_class);
+log_probs = zeros(1,num_class);
+for i=1:num_class
+  subset_sizes(i)=size(split_T{i},2);
+end    
+
+probs = subset_sizes/total_cnt;
+%log_probs = log2(probs);  % if probs(i)=0, the log2(probs(i)) will be Inf
+for i=1:size(probs,2)
+  if (probs(i)~=0)
+    log_probs(i)=log2(probs(i));
+  end
+end
+
+info = sum(-(probs.*log_probs));
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/readme.txt b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/readme.txt
new file mode 100644
index 00000000..d938d972
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/readme.txt
@@ -0,0 +1,8 @@
+Decision/regression tree CPD
+Author: Yimin Zhang yimin.zhang@intel.com
+21 Jan 2002
+
+
+See also Paul Bradley's Multisurface Method-Tree matlab code
+ http://www.cs.wisc.edu/~paulb/msmt/
+http://www.cs.wisc.edu/~olvi/uwmp/msmt.html
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/set_fields.m b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/set_fields.m
new file mode 100644
index 00000000..a8e94ba1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/set_fields.m
@@ -0,0 +1,52 @@
+function CPD = set_fields(CPD, varargin)
+% SET_PARAMS Set the parameters (fields) for a tabular_CPD object
+% CPD = set_params(CPD, name/value pairs)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+%
+% CPT     - the CPT
+% prior   - the prior
+% clamped - 1 means don't adjust during EM
+%
+% e.g., CPD = set_params(CPD, 'CPT', 'rnd')
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'CPT', 
+    if ischar(args{i+1})
+      switch args{i+1}
+       case 'unif', CPD.CPT = mk_stochastic(myones(CPD.sizes));
+       case 'rnd',  CPD.CPT = mk_stochastic(myrand(CPD.sizes));
+       otherwise,   error(['invalid type ' args{i+1}]);       
+      end
+    elseif isscalarBNT(args{i+1})
+      p = args{i+1};
+      k = CPD.sizes(end);
+      % Bug fix by Hervé BOUTROUILLE 10/1/01
+      CPD.CPT = myreshape(sample_dirichlet(p*ones(1,k), prod(CPD.sizes(1:end-1)), CPD.sizes));   
+      %CPD.CPT = myreshape(sample_dirichlet(p*ones(1,k), prod(CPD.sizes(1:end-1))), CPD.sizes);
+    else
+      CPD.CPT = myreshape(args{i+1}, CPD.sizes);
+    end
+   
+   case 'prior',       
+    if ischar(args{i+1}) & strcmp(args{i+1}, 'unif')
+      CPD.prior = myones(CPD.sizes);
+    elseif isscalarBNT(args{i+1})
+      CPD.prior = args{i+1} * normalise(myones(CPD.sizes));
+    else
+      CPD.prior = myreshape(args{i+1}, CPD.sizes);
+    end
+    
+   %case 'clamped',      CPD.clamped = strcmp(args{i+1}, 'yes');
+   %case 'clamped',      CPD = set_clamped(CPD, strcmp(args{i+1}, 'yes'));
+   case 'clamped',      CPD = set_clamped(CPD, args{i+1});
+   
+   otherwise,  
+    %error(['invalid argument name ' args{i}]);       
+  end
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/tree_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/tree_CPD.m
new file mode 100644
index 00000000..a9ef3776
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tree_CPD/tree_CPD.m
@@ -0,0 +1,37 @@
+function CPD = tree_CPD(varargin)
+%DTREE_CPD Make a conditional prob. distrib. which is a decision/regression tree.
+%
+% CPD =dtree_CPD() will create an empty tree.
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  clamp = 0;
+  CPD = class(CPD, 'tree_CPD', discrete_CPD(clamp, []));
+  return;
+elseif isa(varargin{1}, 'tree_CPD')
+  % This might occur if we are copying an object.
+  CPD = varargin{1};
+  return;
+end
+
+CPD = init_fields;
+
+
+clamped = 0;
+fam_sz = [];
+CPD = class(CPD, 'tree_CPD', discrete_CPD(clamped, fam_sz));
+
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+%init the decision tree set the root to null
+CPD.tree.num_node = 0;
+CPD.tree.root=1;
+CPD.tree.nodes=[];
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/CVS/Entries
new file mode 100644
index 00000000..a527d2ad
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/CVS/Entries
@@ -0,0 +1,2 @@
+/mk_isolated_tabular_CPD.m/1.1.1.1/Mon Jun 24 18:58:32 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CPDs/CVS/Entries.Log
new file mode 100644
index 00000000..b7997b3c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/CVS/Entries.Log
@@ -0,0 +1,19 @@
+A D/@boolean_CPD////
+A D/@deterministic_CPD////
+A D/@discrete_CPD////
+A D/@gaussian_CPD////
+A D/@generic_CPD////
+A D/@gmux_CPD////
+A D/@hhmm2Q_CPD////
+A D/@hhmmF_CPD////
+A D/@hhmmQ_CPD////
+A D/@mlp_CPD////
+A D/@noisyor_CPD////
+A D/@root_CPD////
+A D/@softmax_CPD////
+A D/@tabular_CPD////
+A D/@tabular_decision_node////
+A D/@tabular_kernel////
+A D/@tabular_utility_node////
+A D/@tree_CPD////
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/CVS/Repository
new file mode 100644
index 00000000..a8bb51a5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs
diff --git a/sourcecodes/bnt-master/BNT/CPDs/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/CVS/Entries
new file mode 100644
index 00000000..96e99049
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/CVS/Entries
@@ -0,0 +1,4 @@
+/linear_gaussian_CPD.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/log_marg_prob_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/update_params_complete.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/CVS/Repository
new file mode 100644
index 00000000..ac2255d4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/Old/@linear_gaussian_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/linear_gaussian_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/linear_gaussian_CPD.m
new file mode 100644
index 00000000..55076c4b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/linear_gaussian_CPD.m
@@ -0,0 +1,87 @@
+function CPD = linear_gaussian_CPD(bnet, self, theta, sigma, theta0, n0, alpha0, beta0)
+% LINEAR_GAUSSIAN_CPD Make a linear Gaussian distrib.
+%
+% CPD = linear_gaussian_CPD(bnet, self, theta, lambda)
+% This defines the distribution P(Y|X) =  N(y | theta'*x, sigma),
+% where y (self) is a scalar, theta is a regression vector, and sigma is the variance.
+% Pass in [] to generate a default random value for a parameter.
+%
+% CPD = linear_gaussian_CPD(bnet, self, [], [], theta0, n0, alpha0, beta0)
+% defines a Normal-Gamma prior over the parameters:
+%   P(theta | lambda) = N(theta | theta0, n0*lambda)
+%   P(lambda) = Gamma(lambda | alpha0, beta0)
+% where lambda = 1/sigma is the precision for y.
+% n0 is a precision matrix, beta0 is a scale factor.
+% Pass in [] to generate a default value for a hyperparameter.
+% theta and sigma will be set to their prior expected values.
+% See "Bayesian Theory", Bernardo and Smith (2000), p442.
+
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  CPD = class(CPD, 'linear_gaussian_CPD', generic_CPD(0));
+  return;
+elseif isa(bnet, 'linear_gaussian_CPD')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+CPD = init_fields;
+
+
+ns = bnet.node_sizes;
+ps = parents(bnet.dag, self);
+d = sum(ns(ps));
+assert(ns(self)==1);
+
+
+if nargin < 5,
+  prior = [];
+  if isempty(theta), theta = randn(d, 1); end
+  if isempty(sigma), sigma = 1; end
+else
+  
+  %if isempty(theta0), theta0 = zeros(d, 1); end
+  %if isempty(n0), n0 = 0.1*eye(d); end
+  %if isempty(alpha0), alpha0 = 0.1; end
+  %if isempty(beta0), beta0 = 0.1; end
+   
+  % use non-informative priors
+  if isempty(theta0), theta0 = zeros(d, 1); end
+  if isempty(n0), n0 = 0.001*ones(d); end
+  if isempty(alpha0), alpha0 = -d/2 + 0.001; end
+  if isempty(beta0), beta0 = 0.001; end
+
+  prior.theta = theta0;
+  prior.n = n0;
+  prior.alpha = alpha0;
+  prior.beta = beta0;
+  
+  % set params to their mean
+  theta = prior.theta;
+  %sigma = prior.beta/prior.alpha; % mean of Gamma is E[lambda] = alpha/beta 
+end
+
+
+CPD.self = self;
+CPD.theta = theta;
+CPD.sigma = sigma;
+CPD.prior = prior;
+
+
+clamped = 0;
+CPD = class(CPD, 'linear_gaussian_CPD', generic_CPD(clamped));
+
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.self = [];
+CPD.theta = [];
+CPD.sigma = [];
+CPD.prior = [];
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/log_marg_prob_node.m b/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/log_marg_prob_node.m
new file mode 100644
index 00000000..3d06244f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/log_marg_prob_node.m
@@ -0,0 +1,23 @@
+function L = log_marg_prob_node(CPD, self_ev, pev)
+% LOG_MARG_PROB_NODE Compute prod_m log P(x(i,m)| x(pi_i,m)) for node i (linear_gaussian)
+% L = log_marg_prob_node(CPD, self_ev, pev)
+%
+% This differs from log_prob_node because we integrate out the parameters.
+% self_ev{m} is the evidence on this node in case m.
+% pev{i,m} is the evidence on the i'th parent in case m 
+% We assume there is <= 1 case.
+
+ncases = length(self_ev);
+
+if ncases==0
+  L = 0;
+  return;
+elseif ncases==1 
+  y = self_ev{1};
+  x = cat(1, pev{:}); % column vector
+  f = 1-x'*inv(x*x' + CPD.prior.n)*x;
+  alpha = CPD.prior.alpha;
+  L = log_student_pdf(y, x'*CPD.prior.theta, f*alpha/CPD.prior.beta, 2*alpha);
+else
+  error('can''t handle batch data');
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/update_params_complete.m b/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/update_params_complete.m
new file mode 100644
index 00000000..dbe8d5da
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@linear_gaussian_CPD/update_params_complete.m
@@ -0,0 +1,25 @@
+function CPD = update_params_complete(CPD, self_ev, pev)
+% UPDATE_PARAMS_COMPLETE Bayesian parameter updating given completely observed data (linear_gaussian)
+% CPD = update_params_complete(CPD, self_ev, pev)
+%
+% self_ev{m} is the evidence on this node in case m.
+% pev{i,m} is the evidence on the i'th parent in case m
+%
+% We update the hyperparams and set the params to the mean of the posterior.
+
+y = cat(1, self_ev{:});
+X = cell2num(pev)';
+[N k] = size(X); % each row is a case
+
+n0 = CPD.prior.n;
+th0 = CPD.prior.theta;
+CPD.prior.theta = inv(n0 + X'*X)*(n0*th0 + X'*y);
+thn = CPD.prior.theta;
+CPD.prior.beta = CPD.prior.beta + 0.5*(y-X*thn)'*y + 0.5*(th0-thn)'*n0*th0;
+CPD.prior.alpha = CPD.prior.alpha + 0.5*N;
+CPD.prior.n = CPD.prior.n + X'*X;
+
+  
+% set params to their mean
+CPD.theta = CPD.prior.theta;
+%CPD.sigma = CPD.prior.beta/CPD.prior.alpha; % mean of Gamma is E[lambda] = alpha/beta 
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/CVS/Entries
new file mode 100644
index 00000000..5335ec72
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/CVS/Entries
@@ -0,0 +1,4 @@
+/log_marg_prob_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/root_gaussian_CPD.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/update_params_complete.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/CVS/Repository
new file mode 100644
index 00000000..ff9bf8d4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/Old/@root_gaussian_CPD
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/log_marg_prob_node.m b/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/log_marg_prob_node.m
new file mode 100644
index 00000000..4d4e21fc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/log_marg_prob_node.m
@@ -0,0 +1,26 @@
+function L = log_marg_prob_node(CPD, self_ev, pev)
+% LOG_MARG_PROB_NODE Compute prod_m log P(x(i,m)| x(pi_i,m)) for node i (root_gaussian)
+% L = log_marg_prob_node(CPD, self_ev, pev)
+%
+% This differs from log_prob_node because we integrate out the parameters.
+% self_ev{m} is the evidence on this node in case m.
+% pev{i,m} is the evidence on the i'th parent in case m (ignored).
+
+ncases = length(self_ev);
+
+if ncases==0
+  L = 0;
+  return;
+elseif ncases==1 
+  x = cat(1, self_ev{:});
+  k = length(x);
+  n0 = CPD.prior.n;
+  mu = CPD.prior.mu;
+  alpha = CPD.prior.alpha;
+  beta = CPD.prior.beta;
+  gamma = 2*alpha - k + 1;
+  % Bernardo and Smith p441
+  L = log_student_pdf(x, mu, n0/(n0+1)*0.5*gamma*inv(beta), gamma);
+else
+  error('can''t handle batch data');
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/root_gaussian_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/root_gaussian_CPD.m
new file mode 100644
index 00000000..bd4ffd9e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/root_gaussian_CPD.m
@@ -0,0 +1,74 @@
+function CPD = root_gaussian_CPD(bnet, self, mu, Sigma, mu0, n0, alpha0, beta0)
+% ROOT_GAUSSIAN_CPD Make an unconditional Gaussian distrib.
+%
+% CPD = root_gaussian_CPD(bnet, self, mu, Sigma)
+% This defines the distribution Y ~ N(mu, Sigma),
+% Pass in [] to generate a default random value for a parameter.
+%
+% CPD = root_gaussian_CPD(bnet, self, [], [], mu0, n0, alpha0, beta0)
+% defines a Normal-Wishart prior over the parameters:
+%   P(mu | lambda) = N(mu | mu0, n0*lambda)
+%   P(lambda) = Wishart(lambda | alpha0, beta0)
+% where lambda = inv(Sigma) is the precision matrix of mu.
+% n0 is a scale factor, beta0 is a precision matrix.
+% Pass in [] to generate a default value for a hyperparameter.
+% mu and Sigma will be set to their prior expected values.
+% See "Bayesian Theory", Bernardo and Smith (2000), p441.
+
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  CPD = class(CPD, 'root_gaussian_CPD', generic_CPD(0));
+  return;
+elseif isa(bnet, 'root_gaussian_CPD')
+  % This might occur if we are copying an object.
+  CPD = bnet;
+  return;
+end
+CPD = init_fields;
+
+
+ns = bnet.node_sizes;
+d = ns(self);
+
+if nargin < 5,
+  prior = [];
+  if isempty(mu), mu = randn(d, 1); end
+  if isempty(Sigma), Sigma = eye(d); end
+else
+  if isempty(mu0), mu0 = zeros(d, 1); end
+  if isempty(n0), n0 = 0.1; end
+  if isempty(alpha0), alpha0 = (d-1)/2 + 1; end % Wishart requires 2 alpha > d-1
+  if isempty(beta0), beta0 = eye(d); end
+  
+  prior.mu = mu0;
+  prior.n = n0;
+  prior.alpha = alpha0;
+  prior.beta = beta0;
+  
+  % set params to their mean
+  mu = prior.mu;
+  Sigma = prior.beta/prior.alpha; % mean of Wishart is E[lambda] = alpha*inv(beta)
+end
+
+CPD.self = self;
+CPD.mu = mu;
+CPD.Sigma = Sigma;
+CPD.prior = prior;
+
+clamped = 0;
+CPD = class(CPD, 'root_gaussian_CPD', generic_CPD(clamped));
+
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.self = [];
+CPD.mu = [];
+CPD.Sigma = [];
+CPD.prior = [];
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/update_params_complete.m b/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/update_params_complete.m
new file mode 100644
index 00000000..7ce58944
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@root_gaussian_CPD/update_params_complete.m
@@ -0,0 +1,29 @@
+function CPD = update_params_complete(CPD, self_ev, pev)
+% UPDATE_PARAMS_COMPLETE Bayesian parameter updating given completely observed data (root_gaussian)
+% CPD = update_params_complete(CPD, self_ev, pev)
+%
+% self_ev{m} is the evidence on this node in case m.
+% pev{i,m} is the evidence on the i'th parent in case m (ignored)
+%
+% We update the hyperparams and set the params to the mean of the posterior.
+
+X = cell2num(self_ev);
+[k N] = size(X); % each column is a case
+
+one = ones(N,1);
+xbar = X*one / N; % = mean(X')'
+S = X*(eye(N) - one*one'/N)*X';
+
+n0 = CPD.prior.n;
+nn = 1/(n0 + N);
+mu0 = CPD.prior.mu;
+CPD.prior.mu = nn*(n0*mu0 + N*xbar);
+CPD.prior.alpha = CPD.prior.alpha + 0.5*N;
+CPD.prior.beta = CPD.prior.beta + 0.5*S + 0.5*nn*N*n0*(mu0-xbar)*(mu0-xbar)';
+CPD.prior.n = CPD.prior.n + N;
+
+% set params to their mean
+CPD.mu = CPD.prior.mu;
+% E[Cov] = E inv(n lambda) = 1/(n (alpha-(k+1)/2)) beta
+CPD.Sigma = CPD.prior.beta /(CPD.prior.n * (CPD.prior.alpha - (k+1)/2));
+  
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CPD_to_upot.m b/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CPD_to_upot.m
new file mode 100644
index 00000000..3ce87d0b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CPD_to_upot.m
@@ -0,0 +1,6 @@
+function pot = CPD_to_upot(CPD, domain)
+% CPD_TO_UPOT Convert a CPD to a utility potential
+% pot = CPD_to_upot(CPD, domain)
+
+sz = CPD.size; % mysize(CPD.CPT);
+pot = upot(domain, sz, CPD.CPT, 0*myones(sz));
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CVS/Entries
new file mode 100644
index 00000000..02628802
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CVS/Entries
@@ -0,0 +1,3 @@
+/CPD_to_upot.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/tabular_chance_node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CVS/Repository
new file mode 100644
index 00000000..3a232db2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/Old/@tabular_chance_node
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/tabular_chance_node.m b/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/tabular_chance_node.m
new file mode 100644
index 00000000..3476536c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/@tabular_chance_node/tabular_chance_node.m
@@ -0,0 +1,39 @@
+function CPD = tabular_chance_node(sz, CPT)
+% TABULAR_CHANCE_NODE Like tabular_CPD, but simplified
+% CPD = tabular_chance_node(sz, CPT)
+%
+% sz(1:end-1) is the sizes of the parents, sz(end) is the size of this node
+% By default, CPT is a random stochastic matrix.
+
+if nargin==0
+  % This occurs if we are trying to load an object from a file.
+  CPD = init_fields;
+  CPD = class(CPD, 'tabular_chance_node');
+  return;
+elseif isa(sz, 'tabular_chance_node')
+  % This might occur if we are copying an object.
+  CPD = sz;
+  return;
+end
+CPD = init_fields;
+
+if nargin < 2,
+  CPT = mk_stochastic(myones(sz)); 
+else
+  CPT = myreshape(CPT, sz);
+end
+
+CPD.CPT = CPT;
+CPD.size = sz;
+
+CPD = class(CPD, 'tabular_chance_node');
+
+%%%%%%%%%%%
+
+function CPD = init_fields()
+% This ensures we define the fields in the same order 
+% no matter whether we load an object from a file,
+% or create it from scratch. (Matlab requires this.)
+
+CPD.CPT = [];
+CPD.size = [];
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Entries
new file mode 100644
index 00000000..17848105
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Entries
@@ -0,0 +1 @@
+D
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Entries.Log
new file mode 100644
index 00000000..ed4a9516
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Entries.Log
@@ -0,0 +1,3 @@
+A D/@linear_gaussian_CPD////
+A D/@root_gaussian_CPD////
+A D/@tabular_chance_node////
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Repository
new file mode 100644
index 00000000..cf1b510a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/CPDs/Old
diff --git a/sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Root b/sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/CPDs/mk_isolated_tabular_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/mk_isolated_tabular_CPD.m
new file mode 100644
index 00000000..6c2c237e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/mk_isolated_tabular_CPD.m
@@ -0,0 +1,14 @@
+function CPD = mk_isolated_tabular_CPD(fam_sz, args)
+% function CPD = mk_isolated_tabular_CPD(fam_sz, args)
+% function CPD = mk_isolated_tabular_CPD(fam_sz, args)
+% Make a single CPD by creating a mini-bnet containing just this one family.
+% This is necessary because the CPD constructor requires a bnet.
+
+n = length(fam_sz);
+dag = zeros(n,n);
+ps = 1:(n-1);
+if ~isempty(ps)
+  dag(ps,n) = 1;
+end
+bnet = mk_bnet(dag, fam_sz);
+CPD = tabular_CPD(bnet, n, args{:});
diff --git a/sourcecodes/bnt-master/BNT/CVS/Entries b/sourcecodes/bnt-master/BNT/CVS/Entries
new file mode 100644
index 00000000..c031c8fd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CVS/Entries
@@ -0,0 +1,9 @@
+/README.txt/1.1.1.1/Thu Jun 10 01:56:50 2004//
+/add_BNT_to_path.m/1.2/Sat Sep 17 16:58:43 2005//
+/copyright.txt/1.1.1.1/Sat Jan 18 23:00:58 2003//
+/installC_BNT.m/1.1.1.1/Thu Mar 31 19:20:56 2005//
+/installC_graph.m/1.1.1.1/Tue May 18 14:50:12 2004//
+/license.gpl.txt/1.1.1.1/Wed May 29 15:59:56 2002//
+/test_BNT.m/1.3/Sat Sep 17 16:56:27 2005//
+/uninstallC_BNT.m/1.1.1.1/Sun May  4 22:31:38 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/CVS/Entries.Log
new file mode 100644
index 00000000..cd7b6619
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CVS/Entries.Log
@@ -0,0 +1,7 @@
+A D/@assocarray////
+A D/CPDs////
+A D/examples////
+A D/general////
+A D/inference////
+A D/learning////
+A D/potentials////
diff --git a/sourcecodes/bnt-master/BNT/CVS/Repository b/sourcecodes/bnt-master/BNT/CVS/Repository
new file mode 100644
index 00000000..f77dc640
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT
diff --git a/sourcecodes/bnt-master/BNT/CVS/Root b/sourcecodes/bnt-master/BNT/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/README.txt b/sourcecodes/bnt-master/BNT/README.txt
new file mode 100644
index 00000000..5b4f3dd6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/README.txt
@@ -0,0 +1,4 @@
+The Bayes Net Toolbox for Matlab was written by Kevin Patrick Murphy et al.
+This version was last updated on 17 Oct 2007..
+To download the latest version, and to get documentation, please go to
+   http://www.cs.ubc.ca/~murphyk/Software/BNT/bnt.html
diff --git a/sourcecodes/bnt-master/BNT/copyright.txt b/sourcecodes/bnt-master/BNT/copyright.txt
new file mode 100644
index 00000000..f1c46c10
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/copyright.txt
@@ -0,0 +1,2 @@
+Written by Kevin Murphy (murphyk@ai.mit.edu), 1997-2003
+Distributed under the GNU Library GPL - see license.gpl for details.
diff --git a/sourcecodes/bnt-master/BNT/examples/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/CVS/Entries
new file mode 100644
index 00000000..5d1ca70d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/CVS/Entries
@@ -0,0 +1,4 @@
+/dummy/1.1.1.1/Sat Jan 18 22:22:06 2003//
+D/dynamic////
+D/limids////
+D/static////
diff --git a/sourcecodes/bnt-master/BNT/examples/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/CVS/Repository
new file mode 100644
index 00000000..9b5676b5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples
diff --git a/sourcecodes/bnt-master/BNT/examples/CVS/Root b/sourcecodes/bnt-master/BNT/examples/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dummy b/sourcecodes/bnt-master/BNT/examples/dummy
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dummy
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Entries
new file mode 100644
index 00000000..6f98ef27
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Entries
@@ -0,0 +1,38 @@
+/arhmm1.m/1.1.1.1/Thu Nov 14 01:03:34 2002//
+/bat1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/bkff1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/chmm1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/cmp_inference_dbn.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/cmp_learning_dbn.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/cmp_online_inference.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/dhmm1.m/1.1.1.1/Sun May  4 22:23:18 2003//
+/ehmm1.m/1.1.1.1/Sat Jan 18 22:16:24 2003//
+/fhmm_infer.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/filter_test1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/ghmm1.m/1.1.1.1/Sun May  4 22:23:32 2003//
+/ho1.m/1.1.1.1/Fri Mar 28 17:22:36 2003//
+/jtree_clq_test.m/1.1.1.1/Sat Jan 18 22:16:38 2003//
+/jtree_clq_test2.m/1.1.1.1/Thu Oct 10 23:45:12 2002//
+/kalman1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/kjaerulff1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/loopy_dbn1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mhmm1.m/1.1.1.1/Sun May  4 22:23:40 2003//
+/mildew1.m/1.1.1.1/Thu Jun 20 20:30:24 2002//
+/mk_bat_dbn.m/1.1.1.1/Mon Jun  7 19:07:18 2004//
+/mk_chmm.m/1.1.1.1/Tue May 11 19:23:14 2004//
+/mk_collage_from_clqs.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_fhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_mildew_dbn.m/1.1.1.1/Thu Oct 10 23:14:36 2002//
+/mk_orig_bat_dbn.m/1.1.1.1/Wed Feb  4 23:53:06 2004//
+/mk_orig_water_dbn.m/1.1.1.1/Sat Jan 31 02:57:52 2004//
+/mk_ps_from_clqs.m/1.1.1.1/Wed Oct  9 20:36:56 2002//
+/mk_uffe_dbn.m/1.1.1.1/Thu Oct 10 23:14:54 2002//
+/mk_water_dbn.m/1.1.1.1/Tue May 11 18:45:38 2004//
+/orig_water1.m/1.1.1.1/Mon Nov 22 22:41:42 2004//
+/reveal1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/scg_dbn.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/skf_data_assoc_gmux.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/viterbi1.m/1.1.1.1/Tue May 13 14:35:40 2003//
+/water1.m/1.1.1.1/Thu Nov 14 20:07:56 2002//
+/water2.m/1.1.1.1/Thu Nov 14 20:33:42 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Entries.Log
new file mode 100644
index 00000000..0634c982
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Entries.Log
@@ -0,0 +1,3 @@
+A D/HHMM////
+A D/Old////
+A D/SLAM////
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Repository
new file mode 100644
index 00000000..587019a2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries
new file mode 100644
index 00000000..6c5b3923
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries
@@ -0,0 +1,9 @@
+/abcd_hhmm.m/1.1.1.1/Sat Sep 21 21:37:54 2002//
+/add_hhmm_end_state.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/hhmm_jtree_clqs.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_hhmm.m/1.1.1.1/Sat Sep 21 20:58:06 2002//
+/mk_hhmm_topo.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_hhmm_topo_F1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/pretty_print_hhmm_parse.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/remove_hhmm_end_state.m/1.1.1.1/Mon Dec 16 19:16:50 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries.Log
new file mode 100644
index 00000000..1b0fe64f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Entries.Log
@@ -0,0 +1,5 @@
+A D/Map////
+A D/Mgram////
+A D/Motif////
+A D/Old////
+A D/Square////
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Repository
new file mode 100644
index 00000000..2ba8b9e6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Entries
new file mode 100644
index 00000000..dc32f52b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Entries
@@ -0,0 +1,6 @@
+/disp_map_hhmm.m/1.1.1.1/Tue Sep 24 22:45:56 2002//
+/learn_map.m/1.1.1.1/Sat Jan 11 18:48:46 2003//
+/mk_map_hhmm.m/1.1.1.1/Tue Sep 24 10:49:52 2002//
+/mk_rnd_map_hhmm.m/1.1.1.1/Tue Sep 24 22:13:48 2002//
+/sample_from_map.m/1.1.1.1/Tue Sep 24 13:02:30 2002//
+D/Old////
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Repository
new file mode 100644
index 00000000..66b47bbc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Map
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Entries
new file mode 100644
index 00000000..6079d451
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Entries
@@ -0,0 +1,2 @@
+/mk_map_hhmm.m/1.1.1.1/Tue Sep 24 07:02:44 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Repository
new file mode 100644
index 00000000..354057a9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Map/Old
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/mk_map_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/mk_map_hhmm.m
new file mode 100644
index 00000000..7b646745
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/Old/mk_map_hhmm.m
@@ -0,0 +1,156 @@
+function bnet = mk_map_hhmm(varargin)
+
+% p is the prob of a successful move (defines the reliability of motors)
+p = 1;
+num_obs_nodes = 1;
+
+for i=1:2:length(varargin)
+  switch varargin{i},
+   case 'p', p = varargin{i+1};
+   case 'numobs', num_obs_node = varargin{i+1};
+  end
+end
+
+
+q = 1-p;
+
+% assign numbers to the nodes in topological order
+U = 1; A = 2; C = 3; F = 4; O = 5;
+
+% create graph structure
+
+ss = 5; % slice size
+intra = zeros(ss,ss);
+intra(U,F)=1;
+intra(A,[C F O])=1;
+intra(C,[F O])=1;
+
+inter = zeros(ss,ss);
+inter(U,[A C])=1;
+inter(A,[A C])=1;
+inter(F,[A C])=1;
+inter(C,C)=1;
+
+% node sizes
+ns = zeros(1,ss);
+ns(U) = 2; % left/right
+ns(A) = 2;
+ns(C) = 3;
+ns(F) = 2;
+ns(O) = 5; % we will assign each state a unique symbol
+l = 1; r = 2; % left/right
+L = 1; R = 2;
+
+% Make the DBN
+bnet = mk_dbn(intra, inter, ns, 'observed', O);
+eclass = bnet.equiv_class;
+
+
+
+% Define CPDs for slice 1
+% We clamp all of them, i.e., do not try to learn them.
+
+% uniform probs over actions (the input could be chosen from a policy)
+bnet.CPD{eclass(U,1)} = tabular_CPD(bnet, U, 'CPT', mk_stochastic(ones(ns(U),1)), ...
+				    'adjustable', 0);
+
+% uniform probs over starting abstract state
+bnet.CPD{eclass(A,1)} = tabular_CPD(bnet, A, 'CPT', mk_stochastic(ones(ns(A),1)), ...
+				    'adjustable', 0);
+
+% Uniform probs over starting concrete state, modulo the fact
+% that corridor 2 is only of length 2.
+CPT = zeros(ns(A), ns(C)); % CPT(i,j) = P(C starts in j | A=i)
+CPT(1, :) = [1/3 1/3 1/3];
+CPT(2, :) = [1/2 1/2 0];
+bnet.CPD{eclass(C,1)} = tabular_CPD(bnet, C, 'CPT', CPT, 'adjustable', 0);
+
+% Termination probs
+CPT = zeros(ns(U), ns(A), ns(C), ns(F));
+CPT(r,1,1,:) = [1 0];
+CPT(r,1,2,:) = [1 0];
+CPT(r,1,3,:) = [q p];
+CPT(r,2,1,:) = [1 0];
+CPT(r,2,2,:) = [q p];
+CPT(l,1,1,:) = [q p];
+CPT(l,1,2,:) = [1 0];
+CPT(l,1,3,:) = [1 0];
+CPT(l,2,1,:) = [q p];
+CPT(l,2,2,:) = [1 0];
+
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', CPT);
+
+
+% Assign each state a unique observation
+CPT = zeros(ns(A), ns(C), ns(O));
+CPT(1,1,1)=1; 
+CPT(1,2,2)=1;
+CPT(1,3,3)=1;
+CPT(2,1,4)=1;
+CPT(2,2,5)=1;
+%CPT(2,3,:) undefined
+
+bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', CPT);
+
+
+% Define the CPDs for slice 2
+
+% Abstract
+
+% Since the top level never resets, the starting distribution is irrelevant:
+% A2 will be determined by sampling from transmat(A1,:).
+% But the code requires we specify it anyway; we make it all 0s, a dummy value.
+startprob = zeros(ns(U), ns(A));
+
+transmat = zeros(ns(U), ns(A), ns(A));
+transmat(R,1,:) = [q p];
+transmat(R,2,:) = [0 1];
+transmat(L,1,:) = [1 0];
+transmat(L,2,:) = [p q];
+
+% Qps are the parents we condition the parameters on, in this case just
+% the past action.
+bnet.CPD{eclass(A,2)} = hhmm2Q_CPD(bnet, A+ss, 'Fbelow', F, ...
+				  'startprob', startprob, 'transprob', transmat);
+
+
+
+% Concrete
+
+transmat = zeros(ns(C), ns(U), ns(A), ns(C));
+transmat(1,r,1,:) = [q p 0.0];
+transmat(2,r,1,:) = [0.0 q p];
+transmat(3,r,1,:) = [0.0 0.0 1.0];
+transmat(1,r,2,:) = [q p 0.0];
+transmat(2,r,2,:) = [0.0 1.0 0.0];
+%
+transmat(1,l,1,:) = [1.0 0.0 0.0];
+transmat(2,l,1,:) = [p q 0.0];
+transmat(3,l,1,:) = [0.0 p q];
+transmat(1,l,2,:) = [1.0 0.0 0.0];
+transmat(2,l,2,:) = [p q 0.0];
+
+% Add a new dimension for A(t-1), by copying old vals,
+% so the matrix is the same size as startprob
+
+
+transmat = reshape(transmat, [ns(C) ns(U) ns(A) 1 ns(C)]);
+transmat = repmat(transmat, [1 1 1 ns(A) 1]);
+
+% startprob(C(t-1), U(t-1), A(t-1), A(t), C(t))
+startprob = zeros(ns(C), ns(U), ns(A), ns(A), ns(C));
+startprob(1,L,1,1,:) = [1.0 0.0 0.0];
+startprob(3,R,1,2,:) = [1.0 0.0 0.0];
+startprob(3,R,1,1,:) = [0.0 0.0 1.0];
+% 
+startprob(1,L,2,1,:) = [0.0 0.0 010];
+startprob(2,L,2,1,:) = [1.0 0.0 0.0];
+startprob(2,R,2,2,:) = [0.0 1.0 0.0];
+
+% want transmat(U,A,C,At,Ct), ie. in topo order
+transmat = permute(transmat, [2 3 1 4 5]);
+startprob  = permute(startprob, [2 3 1 4 5]);
+bnet.CPD{eclass(C,2)} = hhmm2Q_CPD(bnet, C+ss, 'Fself', F, ...
+				  'startprob', startprob, 'transprob', transmat);
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/disp_map_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/disp_map_hhmm.m
new file mode 100644
index 00000000..0aadf2bb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/disp_map_hhmm.m
@@ -0,0 +1,13 @@
+function disp_map_hhmm(bnet)
+
+eclass = bnet.equiv_class;
+U = 1; A = 2; C = 3; F = 4;
+
+S = struct(bnet.CPD{eclass(A,2)});
+disp('abstract trans')
+dispcpt(S.transprob)
+
+S = struct(bnet.CPD{eclass(C,2)});
+disp('concrete trans for go left') % UAC AC
+dispcpt(squeeze(S.transprob(1,:,:,:,:)))
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/learn_map.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/learn_map.m
new file mode 100644
index 00000000..ac36586a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/learn_map.m
@@ -0,0 +1,40 @@
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+obs_model = 'unique';  % each cell has a unique label (essentially fully observable)
+%obs_model = 'four'; % each cell generates 4 observations, NESW
+
+% Generate the true network, and a randomization of it
+realnet = mk_map_hhmm('p', 0.9, 'obs_model', obs_model);
+rndnet = mk_rnd_map_hhmm('obs_model', obs_model);
+eclass = realnet.equiv_class;
+U = 1; A = 2; C = 3; F = 4; onodes = 5;
+
+ss = realnet.nnodes_per_slice;
+T = 100;
+evidence = sample_dbn(realnet, 'length', T);
+ev = cell(ss,T);
+ev(onodes,:) = evidence(onodes,:);
+
+infeng = jtree_dbn_inf_engine(rndnet);
+
+if 0
+% suppose we do not observe the final finish node, but only know 
+% it is more likely to be on that off
+ev2 = ev;
+infeng = enter_evidence(infeng, ev2, 'soft_evidence_nodes', [F T], 'soft_evidence',  {[0.3 0.7]'});
+end
+
+
+learnednet = learn_params_dbn_em(infeng, {evidence}, 'max_iter', 5);
+
+disp('real model')
+disp_map_hhmm(realnet)
+
+disp('learned model')
+disp_map_hhmm(learnednet)
+
+disp('rnd model')
+disp_map_hhmm(rndnet)
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_map_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_map_hhmm.m
new file mode 100644
index 00000000..7b077ddb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_map_hhmm.m
@@ -0,0 +1,181 @@
+function bnet = mk_map_hhmm(varargin)
+
+% p is the prob of a successful move (defines the reliability of motors)
+p = 1;
+obs_model = 'unique';
+
+for i=1:2:length(varargin)
+  switch varargin{i},
+   case 'p', p = varargin{i+1};
+   case 'obs_model', obs_model = varargin{i+1};
+  end
+end
+
+
+q = 1-p;
+unique_obs = strcmp(obs_model, 'unique');
+
+% assign numbers to the nodes in topological order
+U = 1; A = 2; C = 3; F = 4;
+if unique_obs
+  onodes = 5;
+else
+  N = 5; E = 6; S = 7; W = 8; % north, east, south, west
+  onodes = [N E S W];
+end
+
+% create graph structure
+
+ss = 4 + length(onodes); % slice size
+intra = zeros(ss,ss);
+intra(U,F)=1;
+intra(A,[C F onodes])=1;
+intra(C,[F onodes])=1;
+
+inter = zeros(ss,ss);
+inter(U,[A C])=1;
+inter(A,[A C])=1;
+inter(F,[A C])=1;
+inter(C,C)=1;
+
+% node sizes
+ns = zeros(1,ss);
+ns(U) = 2; % left/right
+ns(A) = 2;
+ns(C) = 3;
+ns(F) = 2;
+if unique_obs
+  ns(onodes) = 5; % we will assign each state a unique symbol
+else
+  ns(onodes) = 2;
+end
+l = 1; r = 2; % left/right
+L = 1; R = 2;
+
+% Make the DBN
+bnet = mk_dbn(intra, inter, ns, 'observed', onodes);
+eclass = bnet.equiv_class;
+
+
+
+% Define CPDs for slice 1
+% We clamp all the CPDs that are not tied,
+% since we cannot learn them from a single sequence.
+
+% uniform probs over actions (the input could be chosen from a policy)
+bnet.CPD{eclass(U,1)} = tabular_CPD(bnet, U, 'CPT', mk_stochastic(ones(ns(U),1)), ...
+				    'adjustable', 0);
+
+% uniform probs over starting abstract state
+bnet.CPD{eclass(A,1)} = tabular_CPD(bnet, A, 'CPT', mk_stochastic(ones(ns(A),1)), ...
+				    'adjustable', 0);
+
+% Uniform probs over starting concrete state, modulo the fact
+% that corridor 2 is only of length 2.
+CPT = zeros(ns(A), ns(C)); % CPT(i,j) = P(C starts in j | A=i)
+CPT(1, :) = [1/3 1/3 1/3];
+CPT(2, :) = [1/2 1/2 0];
+bnet.CPD{eclass(C,1)} = tabular_CPD(bnet, C, 'CPT', CPT, 'adjustable', 0);
+
+% Termination probs
+CPT = zeros(ns(U), ns(A), ns(C), ns(F));
+CPT(r,1,1,:) = [1 0];
+CPT(r,1,2,:) = [1 0];
+CPT(r,1,3,:) = [q p];
+CPT(r,2,1,:) = [1 0];
+CPT(r,2,2,:) = [q p];
+CPT(l,1,1,:) = [q p];
+CPT(l,1,2,:) = [1 0];
+CPT(l,1,3,:) = [1 0];
+CPT(l,2,1,:) = [q p];
+CPT(l,2,2,:) = [1 0];
+
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', CPT);
+
+
+% Observation model
+if unique_obs
+  CPT = zeros(ns(A), ns(C), 5);
+  CPT(1,1,1)=1;  % Theo state 4
+  CPT(1,2,2)=1;  % Theo state 5
+  CPT(1,3,3)=1; % Theo state 6
+  CPT(2,1,4)=1; % Theo state 9
+  CPT(2,2,5)=1; % Theo state 10
+  %CPT(2,3,:) undefined
+  O = onodes(1);
+  bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', CPT);
+else
+  % north/east/south/west can see wall (1) or opening (2)
+  CPT = zeros(ns(A), ns(C), 2);
+  CPT(:,:,1) = q;
+  CPT(:,:,2) = p;
+  bnet.CPD{eclass(W,1)} = tabular_CPD(bnet, W, 'CPT', CPT);
+  bnet.CPD{eclass(E,1)} = tabular_CPD(bnet, E, 'CPT', CPT);
+  CPT = zeros(ns(A), ns(C), 2);
+  CPT(:,:,1) = p;
+  CPT(:,:,2) = q;
+  bnet.CPD{eclass(S,1)} = tabular_CPD(bnet, S, 'CPT', CPT);
+  bnet.CPD{eclass(N,1)} = tabular_CPD(bnet, N, 'CPT', CPT);
+end
+
+% Define the CPDs for slice 2
+
+% Abstract
+
+% Since the top level never resets, the starting distribution is irrelevant:
+% A2 will be determined by sampling from transmat(A1,:).
+% But the code requires we specify it anyway; we make it all 0s, a dummy value.
+startprob = zeros(ns(U), ns(A));
+
+transmat = zeros(ns(U), ns(A), ns(A));
+transmat(R,1,:) = [q p];
+transmat(R,2,:) = [0 1];
+transmat(L,1,:) = [1 0];
+transmat(L,2,:) = [p q];
+
+% Qps are the parents we condition the parameters on, in this case just
+% the past action.
+bnet.CPD{eclass(A,2)} = hhmm2Q_CPD(bnet, A+ss, 'Fbelow', F, ...
+				  'startprob', startprob, 'transprob', transmat);
+
+
+
+% Concrete
+
+transmat = zeros(ns(C), ns(U), ns(A), ns(C));
+transmat(1,r,1,:) = [q p 0.0];
+transmat(2,r,1,:) = [0.0 q p];
+transmat(3,r,1,:) = [0.0 0.0 1.0];
+transmat(1,r,2,:) = [q p 0.0];
+transmat(2,r,2,:) = [0.0 1.0 0.0];
+%
+transmat(1,l,1,:) = [1.0 0.0 0.0];
+transmat(2,l,1,:) = [p q 0.0];
+transmat(3,l,1,:) = [0.0 p q];
+transmat(1,l,2,:) = [1.0 0.0 0.0];
+transmat(2,l,2,:) = [p q 0.0];
+
+% Add a new dimension for A(t-1), by copying old vals,
+% so the matrix is the same size as startprob
+
+
+transmat = reshape(transmat, [ns(C) ns(U) ns(A) 1 ns(C)]);
+transmat = repmat(transmat, [1 1 1 ns(A) 1]);
+
+% startprob(C(t-1), U(t-1), A(t-1), A(t), C(t))
+startprob = zeros(ns(C), ns(U), ns(A), ns(A), ns(C));
+startprob(1,L,1,1,:) = [1.0 0.0 0.0];
+startprob(3,R,1,2,:) = [1.0 0.0 0.0];
+startprob(3,R,1,1,:) = [0.0 0.0 1.0];
+% 
+startprob(1,L,2,1,:) = [0.0 0.0 010];
+startprob(2,L,2,1,:) = [1.0 0.0 0.0];
+startprob(2,R,2,2,:) = [0.0 1.0 0.0];
+
+% want transmat(U,A,C,At,Ct), ie. in topo order
+transmat = permute(transmat, [2 3 1 4 5]);
+startprob  = permute(startprob, [2 3 1 4 5]);
+bnet.CPD{eclass(C,2)} = hhmm2Q_CPD(bnet, C+ss, 'Fself', F, ...
+				  'startprob', startprob, 'transprob', transmat);
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_rnd_map_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_rnd_map_hhmm.m
new file mode 100644
index 00000000..76b06fc7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/mk_rnd_map_hhmm.m
@@ -0,0 +1,73 @@
+function bnet = mk_rnd_map_hhmm(varargin)
+
+% We copy the deterministic structure of the real HHMM,
+% but randomize the probabilities of the adjustable CPDs.
+% The key trick is that 0s in the real HHMM remain 0
+% even when multiplied by a randon number.
+
+obs_model = 'unique';
+
+for i=1:2:length(varargin)
+  switch varargin{i},
+   case 'obs_model', obs_model = varargin{i+1};
+  end
+end
+
+
+unique_obs = strcmp(obs_model, 'unique');
+
+psuccess = 0.9;
+% must be less than 1, so that pfail > 0
+% otherwise we copy too many 0s
+bnet = mk_map_hhmm('p', psuccess, 'obs_model', obs_model);
+ns = bnet.node_sizes;
+ss = bnet.nnodes_per_slice;
+
+U = 1; A = 2; C = 3; F = 4;
+%unique_obs = (bnet.nnodes_per_slice == 5);
+if unique_obs
+  onodes = 5;
+else
+  north = 5; east = 6; south = 7; west = 8;
+  onodes = [north east south west];
+end
+
+eclass = bnet.equiv_class;
+S=struct(bnet.CPD{eclass(F,1)});
+CPT = mk_stochastic(rand(size(S.CPT)) .* S.CPT);
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', CPT);
+
+
+% Observation model
+if unique_obs
+  CPT = zeros(ns(A), ns(C), 5);
+  CPT(1,1,1)=1;  % Theo state 4
+  CPT(1,2,2)=1;  % Theo state 5
+  CPT(1,3,3)=1; % Theo state 6
+  CPT(2,1,4)=1; % Theo state 9
+  CPT(2,2,5)=1; % Theo state 10
+  %CPT(2,3,:) undefined
+  O = onodes(1);
+  bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', CPT);
+else
+  for i=[north east south west]
+    CPT = mk_stochastic(rand(ns(A), ns(C), 2));
+    bnet.CPD{eclass(i,1)} = tabular_CPD(bnet, i, 'CPT', CPT);
+  end
+end
+
+% Define the CPDs for slice 2
+
+startprob = zeros(ns(U), ns(A));
+S = struct(bnet.CPD{eclass(A,2)});
+transprob = mk_stochastic(rand(size(S.transprob)) .* S.transprob);
+bnet.CPD{eclass(A,2)} = hhmm2Q_CPD(bnet, A+ss, 'Fbelow', F, ...
+				  'startprob', startprob, 'transprob', transprob);
+
+S = struct(bnet.CPD{eclass(C,2)});
+transprob = mk_stochastic(rand(size(S.transprob)) .* S.transprob);
+startprob = mk_stochastic(rand(size(S.startprob)) .* S.startprob);
+bnet.CPD{eclass(C,2)} = hhmm2Q_CPD(bnet, C+ss, 'Fself', F, ...
+				  'startprob', startprob, 'transprob', transprob);
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/sample_from_map.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/sample_from_map.m
new file mode 100644
index 00000000..816b741e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Map/sample_from_map.m
@@ -0,0 +1,41 @@
+if 0
+% Generate some sample paths
+
+bnet = mk_map_hhmm('p', 1);
+% assign numbers to the nodes in topological order
+U = 1; A = 2; C = 3; F = 4; O = 5;
+
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+% control policy = sweep right then left
+T = 10;
+ss = 5;
+ev = cell(ss, T);
+ev(U,:) = num2cell([R*ones(1,5) L*ones(1,5)]);
+
+% fix initial conditions to be in left most state
+ev{A,1} = 1; 
+ev{C,1} = 1; 
+evidence = sample_dbn(bnet, 'length', T, 'evidence', ev)
+
+
+% Now do same but with noisy actuators
+
+bnet = mk_map_hhmm('p', 0.8);
+evidence = sample_dbn(bnet, 'length', T, 'evidence', ev)
+
+end
+
+% Now do same but with 4 observations per slice
+
+bnet = mk_map_hhmm('p', 0.8, 'obs_model', 'four');
+ss = bnet.nnodes_per_slice;
+
+ev = cell(ss, T);
+ev(U,:) = num2cell([R*ones(1,5) L*ones(1,5)]);
+ev{A,1} = 1; 
+ev{C,1} = 1; 
+evidence = sample_dbn(bnet, 'length', T, 'evidence', ev)
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Entries
new file mode 100644
index 00000000..c4379581
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Entries
@@ -0,0 +1,6 @@
+/letter2num.m/1.1.1.1/Fri Nov 22 23:10:20 2002//
+/mgram1.m/1.1.1.1/Fri Nov 22 23:59:00 2002//
+/mgram2.m/1.1.1.1/Tue Nov 26 22:04:24 2002//
+/mgram3.m/1.1.1.1/Tue Nov 26 22:14:10 2002//
+/num2letter.m/1.1.1.1/Fri Nov 22 23:07:40 2002//
+D/Old////
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Repository
new file mode 100644
index 00000000..5ede715e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Mgram
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Entries
new file mode 100644
index 00000000..07b688e2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Entries
@@ -0,0 +1,2 @@
+/mgram2.m/1.1.1.1/Sat Nov 23 00:44:34 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Repository
new file mode 100644
index 00000000..ba3ae6df
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Mgram/Old
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/mgram2.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/mgram2.m
new file mode 100644
index 00000000..719a3167
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/Old/mgram2.m
@@ -0,0 +1,191 @@
+% like mgram1, except we use a durational HMM instead of an HHMM2
+
+past = 0;
+
+words = {'the', 't', 'h', 'e'};
+data = 'the';
+nwords = length(words);
+word_len = zeros(1, nwords);
+word_prob = normalise(ones(1,nwords));
+word_logprob = log(word_prob);
+for wi=1:nwords
+  word_len(wi)=length(words{wi});
+end
+D = max(word_len);
+
+
+alphasize = 26*2;
+data = letter2num(data);
+T = length(data);
+
+% node numbers
+W = 1; % top level state = word id
+L = 2; % bottom level state = letter position within word
+F = 3;
+O = 4;
+
+ss = 4;
+intra = zeros(ss,ss);
+intra(W,[F L O])=1;
+intra(L,[O F])=1;
+
+inter = zeros(ss,ss);
+inter(W,W)=1;
+inter(L,L)=1;
+inter(F,[W L O])=1;
+
+% node sizes
+ns = zeros(1,ss);
+ns(W) = nwords;
+ns(L) = D;
+ns(F) = 2;
+ns(O) = alphasize;
+ns2 = [ns ns];
+
+% Make the DBN
+bnet = mk_dbn(intra, inter, ns, 'observed', O);
+eclass = bnet.equiv_class;
+
+% uniform start distrib over words, uniform trans mat
+Wstart = normalise(ones(1,nwords));
+Wtrans = mk_stochastic(ones(nwords,nwords));
+
+% always start in state d = length(word) for each bottom level HMM
+Lstart = zeros(nwords, D);
+for i=1:nwords
+  l = length(words{i});
+  Lstart(i,l)=1;
+end
+
+% make downcounters
+RLtrans = mk_rightleft_transmat(D, 0); % 0 self loop prob
+Ltrans = repmat(RLtrans, [1 1 nwords]);
+
+% Finish when downcoutner = 1
+Fprob = zeros(nwords, D, 2);
+Fprob(:,1,2)=1;
+Fprob(:,2:end,1)=1;
+
+
+% Define CPDs for slice 
+bnet.CPD{eclass(W,1)} = tabular_CPD(bnet, W, 'CPT', Wstart);
+bnet.CPD{eclass(L,1)} = tabular_CPD(bnet, L, 'CPT', Lstart);
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', Fprob);
+
+
+% Define CPDs for slice 2
+bnet.CPD{eclass(W,2)} = hhmmQ_CPD(bnet, W+ss, 'Fbelow', F, 'startprob', Wstart,  'transprob', Wtrans);
+bnet.CPD{eclass(L,2)} = hhmmQ_CPD(bnet, L+ss, 'Fself', F, 'Qps', W+ss, 'startprob', Lstart, 'transprob', Ltrans);
+
+
+if 0
+% To test it is generating correctly, we create an artificial
+% observation process that capitalizes at the start of a new segment
+% Oprob(Ft-1,Qt,Dt,Yt)
+Oprob = zeros(2,nwords,D,alphasize);
+Oprob(1,1,3,letter2num('t'),1)=1;
+Oprob(1,1,2,letter2num('h'),1)=1;
+Oprob(1,1,1,letter2num('e'),1)=1;
+Oprob(2,1,3,letter2num('T'),1)=1;
+Oprob(2,1,2,letter2num('H'),1)=1;
+Oprob(2,1,1,letter2num('E'),1)=1;
+Oprob(1,2,1,letter2num('a'),1)=1;
+Oprob(2,2,1,letter2num('A'),1)=1;
+Oprob(1,3,1,letter2num('b'),1)=1;
+Oprob(2,3,1,letter2num('B'),1)=1;
+Oprob(1,4,1,letter2num('c'),1)=1;
+Oprob(2,4,1,letter2num('C'),1)=1;
+
+% Oprob1(Qt,Dt,Yt)
+Oprob1 = zeros(nwords,D,alphasize);
+Oprob1(1,3,letter2num('t'),1)=1;
+Oprob1(1,2,letter2num('h'),1)=1;
+Oprob1(1,1,letter2num('e'),1)=1;
+Oprob1(2,1,letter2num('a'),1)=1;
+Oprob1(3,1,letter2num('b'),1)=1;
+Oprob1(4,1,letter2num('c'),1)=1;
+
+bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', Oprob);
+bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', Oprob1);
+
+evidence = cell(ss,T);
+%evidence{W,1}=1;
+sample = cell2num(sample_dbn(bnet, 'length', T, 'evidence', evidence));
+str = num2letter(sample(4,:))
+end
+
+
+
+
+[log_obslik, obslik, match] = mk_mgram_obslik(lower(data), words, word_len, word_prob);
+% obslik(j,t,d)
+softCPDpot = cell(ss,T);
+ens = ns;
+ens(O)=1;
+ens2 = [ens ens];
+for t=2:T
+  dom = [F W+ss L+ss O+ss];
+  % tab(Ft-1, Q2, Dt)
+  tab = ones(2, nwords, D);
+  if past
+    tab(1,:,:)=1; % if haven't finished previous word, likelihood is 1
+    tab(2,:,:) = squeeze(obslik(:,t,:)); % otherwise likelihood of this segment
+  else
+    for d=1:max(1,min(D,T+1-t))
+      tab(2,:,d) = squeeze(obslik(:,t+d-1,d));
+    end
+  end
+  softCPDpot{O,t} = dpot(dom, ens2(dom), tab);
+end
+t = 1;
+dom = [W L O];
+% tab(Q2, Dt)
+tab = ones(nwords, D);
+if past
+  tab = squeeze(obslik(:,t,:));
+else
+  for d=1:min(D,T-t)
+    tab(:,d) = squeeze(obslik(:,t+d-1,d));
+  end
+end
+softCPDpot{O,t} = dpot(dom, ens(dom), tab);
+
+
+%bnet.observed = [];
+% uniformative observations
+%bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', mk_stochastic(ones(2,nwords,D,alphasize)));
+%bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', mk_stochastic(ones(nwords,D,alphasize)));
+
+engine = jtree_dbn_inf_engine(bnet);
+evidence = cell(ss,T);
+% we add dummy data to O to force its effective size to be 1.
+% The actual values have already been incorporated into softCPDpot 
+evidence(O,:) = num2cell(ones(1,T));
+[engine, ll_dbn] = enter_evidence(engine, evidence, 'softCPDpot', softCPDpot);
+
+
+%evidence(F,:) = num2cell(2*ones(1,T));
+%[engine, ll_dbn] = enter_evidence(engine, evidence);
+
+
+gamma = zeros(nwords, T);
+for t=1:T
+  m = marginal_nodes(engine, [W F], t);
+  gamma(:,t) = m.T(:,2);
+end
+
+gamma
+
+xidbn = zeros(nwords, nwords);
+for t=1:T-1
+  m = marginal_nodes(engine, [W F W+ss], t);
+  xidbn = xidbn + squeeze(m.T(:,2,:));
+end
+
+% thee
+% xidbn(1,4)  = 0.9412  the->e
+% (2,3)=0.0588 t->h
+% (3,4)=0.0588 h-e
+% (4,4)=0.0588 e-e
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/letter2num.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/letter2num.m
new file mode 100644
index 00000000..f4e3f1d9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/letter2num.m
@@ -0,0 +1,12 @@
+function n = letter2num(l)
+
+% map a-z to 1:26 and A-Z to 27:52
+punct_code = [32:47 58:64 91:96 123:126];
+digits_code = 48:57;
+upper_code = 65:90;
+lower_code = 97:122;
+
+c = double(l);
+n = c-96;
+ndx = find(n <= 0); % upper case
+n(ndx) = c(ndx)  - 64 + 26;
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram1.m
new file mode 100644
index 00000000..52ca472e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram1.m
@@ -0,0 +1,116 @@
+% a multigram is a degenerate 2HHMM where the bottom level HMMs emit deterministic strings
+% and the the top level abstract states are independent of each other
+% cf. HSMM/test_mgram2 
+
+words = {'the', 't', 'h', 'e'};
+data = 'the';
+nwords = length(words);
+word_len = zeros(1, nwords);
+word_prob = normalise(ones(1,nwords));
+word_logprob = log(word_prob);
+for wi=1:nwords
+  word_len(wi)=length(words{wi});
+end
+D = max(word_len);
+
+alphasize = 26;
+data = letter2num(data);
+T = length(data);
+
+% node numbers
+W = 1; % top level state = word id
+L = 2; % bottom level state = letter position within word
+F = 3;
+O = 4;
+
+ss = 4;
+intra = zeros(ss,ss);
+intra(W,[F L O])=1;
+intra(L,[O F])=1;
+
+inter = zeros(ss,ss);
+inter(W,W)=1;
+inter(L,L)=1;
+inter(F,[W L])=1;
+
+% node sizes
+ns = zeros(1,ss);
+ns(W) = nwords;
+ns(L) = D;
+ns(F) = 2;
+ns(O) = alphasize;
+
+
+% Make the DBN
+bnet = mk_dbn(intra, inter, ns, 'observed', O);
+eclass = bnet.equiv_class;
+
+
+
+% uniform start distrib over words, uniform trans mat
+Wstart = normalise(ones(1,nwords));
+Wtrans = mk_stochastic(ones(nwords,nwords));
+
+% always start in state 1 for each bottom level HMM
+delta1_start = zeros(1, D);
+delta1_start(1) = 1;
+Lstart = repmat(delta1_start, nwords, 1);
+LRtrans = mk_leftright_transmat(D, 0); % 0 self loop prob
+Ltrans = repmat(LRtrans, [1 1 nwords]);
+
+% Finish in the last letter of each word
+Fprob = zeros(nwords, D, 2);
+Fprob(:,:,1)=1;
+for i=1:nwords
+  Fprob(i,length(words{i}),2)=1;
+  Fprob(i,length(words{i}),1)=0;
+end
+
+% Each state uniquely emits a letter
+Oprob = zeros(nwords, D, alphasize);
+for i=1:nwords
+  for l=1:length(words{i})
+    a = double(words{i}(l))-96;
+    Oprob(i,l,a)=1;
+  end
+end
+
+
+% Define CPDs for slice 
+bnet.CPD{eclass(W,1)} = tabular_CPD(bnet, W, 'CPT', Wstart);
+bnet.CPD{eclass(L,1)} = tabular_CPD(bnet, L, 'CPT', Lstart);
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', Fprob);
+bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', Oprob);
+
+% Define CPDs for slice 2
+bnet.CPD{eclass(W,2)} = hhmmQ_CPD(bnet, W+ss, 'Fbelow', F, 'startprob', Wstart,  'transprob', Wtrans);
+bnet.CPD{eclass(L,2)} = hhmmQ_CPD(bnet, L+ss, 'Fself', F, 'Qps', W+ss, 'startprob', Lstart, 'transprob', Ltrans);
+
+evidence = cell(ss,T);
+evidence{W,1}=1;
+sample = cell2num(sample_dbn(bnet, 'length', T, 'evidence', evidence));
+str = lower(sample(4,:))
+
+engine = jtree_dbn_inf_engine(bnet);
+evidence = cell(ss,T);
+evidence(O,:) = num2cell(data);
+[engine, ll_dbn] = enter_evidence(engine, evidence);
+
+gamma = zeros(nwords, T);
+for t=1:T
+  m = marginal_nodes(engine, [W F], t);
+  gamma(:,t) = m.T(:,2);
+end
+gamma
+
+xidbn = zeros(nwords, nwords);
+for t=1:T-1
+  m = marginal_nodes(engine, [W F W+ss], t);
+  xidbn = xidbn + squeeze(m.T(:,2,:));
+end
+
+% thee
+% xidbn(1,4)  = 0.9412  the->e
+% (2,3)=0.0588 t->h
+% (3,4)=0.0588 h-e
+% (4,4)=0.0588 e-e
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram2.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram2.m
new file mode 100644
index 00000000..c61f855a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram2.m
@@ -0,0 +1,200 @@
+% Like a durational HMM, except we use soft evidence on the observed nodes.
+% Should give the same results as HSMM/test_mgram2.
+
+past = 1;
+% If past=1, P(Yt|Qt=j,Dt=d) = P(y_{t-d+1:t}|j)
+% If past=0, P(Yt|Qt=j,Dt=d) = P(y_{t:t+d-1}|j) - future evidence
+
+words = {'the', 't', 'h', 'e'};
+data = 'the';
+nwords = length(words);
+word_len = zeros(1, nwords);
+word_prob = normalise(ones(1,nwords));
+word_logprob = log(word_prob);
+for wi=1:nwords
+  word_len(wi)=length(words{wi});
+end
+D = max(word_len);
+
+
+alphasize = 26*2;
+data = letter2num(data);
+T = length(data);
+
+% node numbers
+W = 1; % top level state = word id
+L = 2; % bottom level state = letter position within word
+F = 3;
+O = 4;
+
+ss = 4;
+intra = zeros(ss,ss);
+intra(W,[F L O])=1;
+intra(L,[O F])=1;
+
+inter = zeros(ss,ss);
+inter(W,W)=1;
+inter(L,L)=1;
+inter(F,[W L O])=1;
+
+% node sizes
+ns = zeros(1,ss);
+ns(W) = nwords;
+ns(L) = D;
+ns(F) = 2;
+ns(O) = alphasize;
+ns2 = [ns ns];
+
+% Make the DBN
+bnet = mk_dbn(intra, inter, ns, 'observed', O);
+eclass = bnet.equiv_class;
+
+% uniform start distrib over words, uniform trans mat
+Wstart = normalise(ones(1,nwords));
+Wtrans = mk_stochastic(ones(nwords,nwords));
+%Wtrans = ones(nwords,nwords);
+
+% always start in state d = length(word) for each bottom level HMM
+Lstart = zeros(nwords, D);
+for i=1:nwords
+  l = length(words{i});
+  Lstart(i,l)=1;
+end
+
+% make downcounters
+RLtrans = mk_rightleft_transmat(D, 0); % 0 self loop prob
+Ltrans = repmat(RLtrans, [1 1 nwords]);
+
+% Finish when downcoutner = 1
+Fprob = zeros(nwords, D, 2);
+Fprob(:,1,2)=1;
+Fprob(:,2:end,1)=1;
+
+
+% Define CPDs for slice 1
+bnet.CPD{eclass(W,1)} = tabular_CPD(bnet, W, 'CPT', Wstart);
+bnet.CPD{eclass(L,1)} = tabular_CPD(bnet, L, 'CPT', Lstart);
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', Fprob);
+
+
+% Define CPDs for slice 2
+bnet.CPD{eclass(W,2)} = hhmmQ_CPD(bnet, W+ss, 'Fbelow', F, 'startprob', Wstart,  'transprob', Wtrans);
+bnet.CPD{eclass(L,2)} = hhmmQ_CPD(bnet, L+ss, 'Fself', F, 'Qps', W+ss, 'startprob', Lstart, 'transprob', Ltrans);
+
+
+if 0
+% To test it is generating correctly, we create an artificial
+% observation process that capitalizes at the start of a new segment
+% Oprob(Ft-1,Qt,Dt,Yt)
+Oprob = zeros(2,nwords,D,alphasize);
+Oprob(1,1,3,letter2num('t'),1)=1;
+Oprob(1,1,2,letter2num('h'),1)=1;
+Oprob(1,1,1,letter2num('e'),1)=1;
+Oprob(2,1,3,letter2num('T'),1)=1;
+Oprob(2,1,2,letter2num('H'),1)=1;
+Oprob(2,1,1,letter2num('E'),1)=1;
+Oprob(1,2,1,letter2num('a'),1)=1;
+Oprob(2,2,1,letter2num('A'),1)=1;
+Oprob(1,3,1,letter2num('b'),1)=1;
+Oprob(2,3,1,letter2num('B'),1)=1;
+Oprob(1,4,1,letter2num('c'),1)=1;
+Oprob(2,4,1,letter2num('C'),1)=1;
+
+% Oprob1(Qt,Dt,Yt)
+Oprob1 = zeros(nwords,D,alphasize);
+Oprob1(1,3,letter2num('t'),1)=1;
+Oprob1(1,2,letter2num('h'),1)=1;
+Oprob1(1,1,letter2num('e'),1)=1;
+Oprob1(2,1,letter2num('a'),1)=1;
+Oprob1(3,1,letter2num('b'),1)=1;
+Oprob1(4,1,letter2num('c'),1)=1;
+
+bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', Oprob);
+bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', Oprob1);
+
+evidence = cell(ss,T);
+%evidence{W,1}=1;
+sample = cell2num(sample_dbn(bnet, 'length', T, 'evidence', evidence));
+str = num2letter(sample(4,:))
+end
+
+
+if 1
+
+[log_obslik, obslik, match] = mk_mgram_obslik(lower(data), words, word_len, word_prob);
+% obslik(j,t,d)
+softCPDpot = cell(ss,T);
+ens = ns;
+ens(O)=1;
+ens2 = [ens ens];
+for t=2:T
+  dom = [F W+ss L+ss O+ss];
+  % tab(Ft-1, Q2, Dt)
+  tab = ones(2, nwords, D);
+  if past
+    tab(1,:,:)=1; % if haven't finished previous word, likelihood is 1
+    %tab(2,:,:) = squeeze(obslik(:,t,:)); % otherwise likelihood of this segment
+    for d=1:min(t,D)
+      tab(2,:,d) = squeeze(obslik(:,t,d));
+    end
+  else
+    for d=1:max(1,min(D,T+1-t))
+      tab(2,:,d) = squeeze(obslik(:,t+d-1,d));
+    end
+  end
+  softCPDpot{O,t} = dpot(dom, ens2(dom), tab);
+end
+t = 1;
+dom = [W L O];
+% tab(Q2, Dt)
+tab = ones(nwords, D);
+if past
+  %tab = squeeze(obslik(:,t,:));
+  tab(:,1) = squeeze(obslik(:,t,1));
+else
+  for d=1:min(D,T-t)
+    tab(:,d) = squeeze(obslik(:,t+d-1,d));
+  end
+end
+softCPDpot{O,t} = dpot(dom, ens(dom), tab);
+
+
+%bnet.observed = [];
+% uniformative observations
+%bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', mk_stochastic(ones(2,nwords,D,alphasize)));
+%bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', mk_stochastic(ones(nwords,D,alphasize)));
+
+engine = jtree_dbn_inf_engine(bnet);
+evidence = cell(ss,T);
+% we add dummy data to O to force its effective size to be 1.
+% The actual values have already been incorporated into softCPDpot 
+evidence(O,:) = num2cell(ones(1,T));
+[engine, ll_dbn] = enter_evidence(engine, evidence, 'softCPDpot', softCPDpot);
+
+
+%evidence(F,:) = num2cell(2*ones(1,T));
+%[engine, ll_dbn] = enter_evidence(engine, evidence);
+
+
+gamma = zeros(nwords, T);
+for t=1:T
+  m = marginal_nodes(engine, [W F], t);
+  gamma(:,t) = m.T(:,2);
+end
+
+gamma
+
+xidbn = zeros(nwords, nwords);
+for t=1:T-1
+  m = marginal_nodes(engine, [W F W+ss], t);
+  xidbn = xidbn + squeeze(m.T(:,2,:));
+end
+
+% thee
+% xidbn(1,4)  = 0.9412  the->e
+% (2,3)=0.0588 t->h
+% (3,4)=0.0588 h-e
+% (4,4)=0.0588 e-e
+
+
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram3.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram3.m
new file mode 100644
index 00000000..49228584
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/mgram3.m
@@ -0,0 +1,235 @@
+% like mgram2, except we unroll the DBN so we can use smaller
+% state spaces for the early duration nodes:
+% the state spaces are D1 in {1}, D2 in {1,2}
+
+past = 1;
+
+words = {'the', 't', 'h', 'e'};
+data = 'the';
+nwords = length(words);
+word_len = zeros(1, nwords);
+word_prob = normalise(ones(1,nwords));
+word_logprob = log(word_prob);
+for wi=1:nwords
+  word_len(wi)=length(words{wi});
+end
+D = max(word_len);
+
+
+alphasize = 26*2;
+data = letter2num(data);
+T = length(data);
+
+% node numbers
+W = 1; % top level state = word id
+L = 2; % bottom level state = letter position within word
+F = 3;
+O = 4;
+
+ss = 4;
+intra = zeros(ss,ss);
+intra(W,[F L O])=1;
+intra(L,[O F])=1;
+
+inter = zeros(ss,ss);
+inter(W,W)=1;
+inter(L,L)=1;
+inter(F,[W L O])=1;
+
+T = 3;
+dag = unroll_dbn_topology(intra, inter, T);
+
+% node sizes
+ns = zeros(1,ss);
+ns(W) = nwords;
+ns(L) = D;
+ns(F) = 2;
+ns(O) = alphasize;
+ns = repmat(ns(:), [1 T]);
+for d=1:D
+  ns(d,L)=d; % max duration
+end
+ns = ns(:);
+
+% Equiv class in brackets for D=3
+% The Lt's are not tied until t>=D, since they have different sizes.
+% W1 and W2 are not tied since they have different parent sets.
+
+% W1 (1)  W2 (5) W3 (5) W4 (5)
+% L1 (2)  L2 (6) L3 (7) L4 (7)
+% F1 (3)  F2 (3) F3 (4) F3 (4)
+% O1 (4)  O2 (4) O2 (4) O4 (4)
+
+% Since we are not learning, we can dispense with tying
+
+% Make the bnet
+Wnodes = unroll_set(W, ss, T);
+Lnodes = unroll_set(L, ss, T);
+Fnodes = unroll_set(F, ss, T);
+Onodes = unroll_set(O, ss, T);
+
+bnet = mk_bnet(dag, ns);
+eclass = bnet.equiv_class;
+
+% uniform start distrib over words, uniform trans mat
+Wstart = normalise(ones(1,nwords));
+Wtrans = mk_stochastic(ones(nwords,nwords));
+bnet.CPD{eclass(Wnodes(1))} = tabular_CPD(bnet, Wnodes(1), 'CPT', Wstart);
+for t=2:T
+bnet.CPD{eclass(Wnodes(t))} = hhmmQ_CPD(bnet, Wnodes(t), 'Fbelow', Fnodes(t-1), ...
+					'startprob', Wstart,  'transprob', Wtrans);
+end
+
+% always start in state d = length(word) for each bottom level HMM
+% and then count down
+% make downcounters
+RLtrans = mk_rightleft_transmat(D, 0); % 0 self loop prob
+Ltrans = repmat(RLtrans, [1 1 nwords]);
+
+for t=1:T
+  Lstart = zeros(nwords, min(t,D));
+  for i=1:nwords
+    l = length(words{i});
+    Lstart(i,l)=1;
+    if d==1
+      bnet.CPD{eclass(Lnodes(1))} = tabular_CPD(bnet, Lnodes(1), 'CPT', Lstart);
+    else
+      bnet.CPD{eclass(Lnodes(t))} = hhmmQ_CPD(bnet, Lnodes(t), 'Fself', Fnodes(t-1), 'Qps', Wnodes(t), ...
+					      'startprob', Lstart, 'transprob', Ltrans);
+    end
+  end
+end
+
+
+% Finish when downcoutner = 1
+Fprob = zeros(nwords, D, 2);
+Fprob(:,1,2)=1;
+Fprob(:,2:end,1)=1;
+
+
+% Define CPDs for slice 
+bnet.CPD{eclass(W,1)} = tabular_CPD(bnet, W, 'CPT', Wstart);
+bnet.CPD{eclass(L,1)} = tabular_CPD(bnet, L, 'CPT', Lstart);
+bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', Fprob);
+
+
+% Define CPDs for slice 2
+bnet.CPD{eclass(W,2)} = hhmmQ_CPD(bnet, W+ss, 'Fbelow', F, 'startprob', Wstart,  'transprob', Wtrans);
+bnet.CPD{eclass(L,2)} = hhmmQ_CPD(bnet, L+ss, 'Fself', F, 'Qps', W+ss, 'startprob', Lstart, 'transprob', Ltrans);
+
+
+if 0
+% To test it is generating correctly, we create an artificial
+% observation process that capitalizes at the start of a new segment
+% Oprob(Ft-1,Qt,Dt,Yt)
+Oprob = zeros(2,nwords,D,alphasize);
+Oprob(1,1,3,letter2num('t'),1)=1;
+Oprob(1,1,2,letter2num('h'),1)=1;
+Oprob(1,1,1,letter2num('e'),1)=1;
+Oprob(2,1,3,letter2num('T'),1)=1;
+Oprob(2,1,2,letter2num('H'),1)=1;
+Oprob(2,1,1,letter2num('E'),1)=1;
+Oprob(1,2,1,letter2num('a'),1)=1;
+Oprob(2,2,1,letter2num('A'),1)=1;
+Oprob(1,3,1,letter2num('b'),1)=1;
+Oprob(2,3,1,letter2num('B'),1)=1;
+Oprob(1,4,1,letter2num('c'),1)=1;
+Oprob(2,4,1,letter2num('C'),1)=1;
+
+% Oprob1(Qt,Dt,Yt)
+Oprob1 = zeros(nwords,D,alphasize);
+Oprob1(1,3,letter2num('t'),1)=1;
+Oprob1(1,2,letter2num('h'),1)=1;
+Oprob1(1,1,letter2num('e'),1)=1;
+Oprob1(2,1,letter2num('a'),1)=1;
+Oprob1(3,1,letter2num('b'),1)=1;
+Oprob1(4,1,letter2num('c'),1)=1;
+
+bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', Oprob);
+bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', Oprob1);
+
+evidence = cell(ss,T);
+%evidence{W,1}=1;
+sample = cell2num(sample_dbn(bnet, 'length', T, 'evidence', evidence));
+str = num2letter(sample(4,:))
+end
+
+
+
+
+[log_obslik, obslik, match] = mk_mgram_obslik(lower(data), words, word_len, word_prob);
+% obslik(j,t,d)
+softCPDpot = cell(ss,T);
+ens = ns;
+ens(O)=1;
+ens2 = [ens ens];
+for t=2:T
+  dom = [F W+ss L+ss O+ss];
+  % tab(Ft-1, Q2, Dt)
+  tab = ones(2, nwords, D);
+  if past
+    tab(1,:,:)=1; % if haven't finished previous word, likelihood is 1
+    %tab(2,:,:) = squeeze(obslik(:,t,:)); % otherwise likelihood of this segment
+    for d=1:min(t,D)
+      tab(2,:,d) = squeeze(obslik(:,t,d));
+    end
+  else
+    for d=1:max(1,min(D,T+1-t))
+      tab(2,:,d) = squeeze(obslik(:,t+d-1,d));
+    end
+  end
+  softCPDpot{O,t} = dpot(dom, ens2(dom), tab);
+end
+t = 1;
+dom = [W L O];
+% tab(Q2, Dt)
+tab = ones(nwords, D);
+if past
+  %tab = squeeze(obslik(:,t,:));
+  tab(:,1) = squeeze(obslik(:,t,1));
+else
+  for d=1:min(D,T-t)
+    tab(:,d) = squeeze(obslik(:,t+d-1,d));
+  end
+end
+softCPDpot{O,t} = dpot(dom, ens(dom), tab);
+
+
+%bnet.observed = [];
+% uniformative observations
+%bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', mk_stochastic(ones(2,nwords,D,alphasize)));
+%bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', mk_stochastic(ones(nwords,D,alphasize)));
+
+engine = jtree_dbn_inf_engine(bnet);
+evidence = cell(ss,T);
+% we add dummy data to O to force its effective size to be 1.
+% The actual values have already been incorporated into softCPDpot 
+evidence(O,:) = num2cell(ones(1,T));
+[engine, ll_dbn] = enter_evidence(engine, evidence, 'softCPDpot', softCPDpot);
+
+
+%evidence(F,:) = num2cell(2*ones(1,T));
+%[engine, ll_dbn] = enter_evidence(engine, evidence);
+
+
+gamma = zeros(nwords, T);
+for t=1:T
+  m = marginal_nodes(engine, [W F], t);
+  gamma(:,t) = m.T(:,2);
+end
+
+gamma
+
+xidbn = zeros(nwords, nwords);
+for t=1:T-1
+  m = marginal_nodes(engine, [W F W+ss], t);
+  xidbn = xidbn + squeeze(m.T(:,2,:));
+end
+
+% thee
+% xidbn(1,4)  = 0.9412  the->e
+% (2,3)=0.0588 t->h
+% (3,4)=0.0588 h-e
+% (4,4)=0.0588 e-e
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/num2letter.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/num2letter.m
new file mode 100644
index 00000000..139b81fa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Mgram/num2letter.m
@@ -0,0 +1,10 @@
+function l = num2letter(n)
+
+% map 1:26 to a-z and 27:52 to A-Z
+punct_code = [32:47 58:64 91:96 123:126];
+digits_code = 48:57;
+upper_code = 65:90;
+lower_code = 97:122;
+
+letters = [char(lower_code) char(upper_code)];
+l = letters(n);
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Entries
new file mode 100644
index 00000000..93258c2a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Entries
@@ -0,0 +1,5 @@
+/fixed_args_mk_motif_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/learn_motif_hhmm.m/1.1.1.1/Tue Jul  2 22:56:14 2002//
+/mk_motif_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_motif_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Repository
new file mode 100644
index 00000000..5062cfd4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Motif
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/fixed_args_mk_motif_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/fixed_args_mk_motif_hhmm.m
new file mode 100644
index 00000000..ce4e288b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/fixed_args_mk_motif_hhmm.m
@@ -0,0 +1,99 @@
+function bnet = fixed_args_mk_motif_hhmm(motif_length, motif_pattern, background_char)
+%
+% BNET = MK_MOTIF_HHMM(MOTIF_LENGTH)
+% Make the following HHMM
+%
+%    S2 <----------------------> S1
+%    |                           |
+%    |                           |
+%   M1 -> M2 -> M3 -> end        B1 -> end
+%
+% where Mi represents the i'th letter in the motif
+% and B is the background state.
+% Si chooses between running the motif or the background.
+% The Si and B states have self loops (not shown).
+%
+% The transition params are defined to respect the above topology.
+% The background is uniform; each motif state has a random obs. distribution.
+%
+% BNET = MK_MOTIF_HHMM(MOTIF_LENGTH, MOTIF_PATTERN)
+% In this case, we make the motif submodel deterministically
+% emit the motif pattern. 
+%
+% BNET = MK_MOTIF_HHMM(MOTIF_LENGTH, MOTIF_PATTERN, BACKGROUND_CHAR)
+% In this case, we make the background submodel
+% deterministically emit the specified character (to make the pattern
+% easier to see).
+
+if nargin < 2, motif_pattern = []; end
+if nargin < 3, background_char = []; end
+
+chars = ['a', 'c', 'g', 't'];
+Osize = length(chars);
+
+motif_length = length(motif_pattern);
+Qsize = [2 motif_length];
+Qnodes = 1:2;
+D = 2;
+transprob = cell(1,D);
+termprob = cell(1,D);
+startprob = cell(1,D);
+
+% startprob{d}(k,j), startprob{1}(1,j)
+% transprob{d}(i,k,j), transprob{1}(i,j)
+% termprob{d}(k,j)
+
+
+% LEVEL 1
+
+startprob{1} = zeros(1, 2);
+startprob{1} = [1 0]; % always start in the background model
+
+% When in the background state, we stay there with high prob
+% When in the motif state, we immediately return to the background state.
+transprob{1} = [0.8 0.2;
+		1.0 0.0];
+
+
+% LEVEL 2
+startprob{2} = 'leftstart'; % both submodels start in substate 1
+transprob{2} = zeros(motif_length, 2, motif_length);
+termprob{2} = zeros(2, motif_length);
+
+% In the background model, we only use state 1.
+transprob{2}(1,1,1) = 1; % self loop
+termprob{2}(1,1) = 0.2; % prob transition to end state
+
+% Motif model
+transprob{2}(:,2,:) = mk_leftright_transmat(motif_length, 0); % no self loops
+termprob{2}(2,end) = 1.0; % last state immediately terminates
+
+
+% OBS LEVEl
+
+obsprob = zeros([Qsize Osize]);
+if isempty(background_char)
+  % uniform background model
+  obsprob(1,1,:) = normalise(ones(Osize,1));
+else
+  % deterministic background model (easy to see!)
+  m = find(chars==background_char);
+  obsprob(1,1,m) = 1.0;
+end
+
+if gen_motif
+  % initialise with true motif (cheating)
+  for i=1:motif_length
+    m = find(chars == motif_pattern(i));
+    obsprob(2,i,m) = 1.0;
+  end
+else
+  obsprob(2,:,:) = mk_stochastic(ones(motif_length, Osize));
+end
+
+Oargs = {'CPT', obsprob};
+
+[bnet, Qnodes, Fnodes, Onode] = mk_hhmm('Qsizes', Qsize, 'Osize', Osize, 'discrete_obs', 1, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(1:2), ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/learn_motif_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/learn_motif_hhmm.m
new file mode 100644
index 00000000..54553460
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/learn_motif_hhmm.m
@@ -0,0 +1,75 @@
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+chars = ['a', 'c', 'g', 't'];
+motif = 'accca';
+motif_length = length(motif);
+motif_code = zeros(1, motif_length);
+for i=1:motif_length
+  motif_code(i) = find(chars == motif(i));
+end
+
+[bnet_init, Qnodes, Fnodes, Onode] = mk_motif_hhmm('motif_length', length(motif));
+%[bnet_init, Qnodes, Fnodes, Onode] = mk_motif_hhmm('motif_pattern', motif);
+ss = bnet_init.nnodes_per_slice;
+
+
+
+% We generate a training set by creating uniform sequences,
+% and inserting a single motif at a random location.
+ntrain = 100;
+T = 20;
+cases = cell(1, ntrain);
+
+if 1
+  % uniform background 
+  background_dist = normalise(ones(1, length(chars)));
+end
+if 0
+  % use a constant background
+  background_dist = zeros(1, length(chars));
+  m = find(chars=='t');
+  background_dist(m) = 1.0;
+end
+if 0
+  % use a background skewed away from the motif
+  p = 0.01; q = (1-(2*p))/2;
+  background_dist = [p p q q];
+end
+
+unif_pos = normalise(ones(1, T-length(motif)));
+cases = cell(1, ntrain);
+data = zeros(1,T);
+for i=1:ntrain
+  data = sample_discrete(background_dist, 1, T);
+  L = sample_discrete(unif_pos, 1, 1);
+  data(L:L+length(motif)-1) = motif_code;
+  cases{i} = cell(ss, T);
+  cases{i}(Onode,:) = num2cell(data);
+end
+disp('sample training cases')
+for i=1:5
+  chars(cell2num(cases{i}(Onode,:)))
+end
+
+engine_init = hmm_inf_engine(bnet_init);
+
+[bnet_learned, LL, engine_learned] = ...
+    learn_params_dbn_em(engine_init, cases, 'max_iter', 100, 'thresh', 1e-2);
+%			'anneal', 1, 'anneal_rate', 0.7);
+
+% extract the learned motif profile
+eclass = bnet_learned.equiv_class;
+CPDO=struct(bnet_learned.CPD{eclass(Onode,1)});
+fprintf('columns = chars, rows = states\n');
+profile_learned = squeeze(CPDO.CPT(2,:,:))
+[m,ndx] = max(profile_learned, [], 2);
+map_motif_learned = chars(ndx)
+back_learned = squeeze(CPDO.CPT(1,1,:))'
+%map_back_learned = chars(argmax(back_learned))
+
+CPDO_init = struct(bnet_init.CPD{eclass(Onode,1)});
+profile_init = squeeze(CPDO_init.CPT(2,:,:));
+back_init = squeeze(CPDO_init.CPT(1,1,:))';
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/mk_motif_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/mk_motif_hhmm.m
new file mode 100644
index 00000000..32980397
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/mk_motif_hhmm.m
@@ -0,0 +1,137 @@
+function [bnet, Qnodes, Fnodes, Onode] = mk_motif_hhmm(varargin)
+% [bnet, Qnodes, Fnodes, Onode] = mk_motif_hhmm(...)
+%
+% Make the following HHMM
+%
+%    S2 <----------------------> S1
+%    |                           |
+%    |                           |
+%   M1 -> M2 -> M3 -> end        B1 -> end
+%
+% where Mi represents the i'th letter in the motif
+% and B is the background state.
+% Si chooses between running the motif or the background.
+% The Si and B states have self loops (not shown).
+%
+% The transition params are defined to respect the above topology.
+% The background is uniform; each motif state has a random obs. distribution.
+%
+% Optional params:
+% motif_length  - required, unless we specify motif_pattern
+% motif_pattern - if specified, we make the motif submodel deterministically
+%                  emit this pattern
+% background    - if specified, we make the background submodel
+%                  deterministically emit this (makes the motif easier to see!)
+
+
+args = varargin;
+nargs = length(args);
+
+% extract pattern, if any
+motif_pattern = [];
+for i=1:2:nargs
+  switch args{i},
+   case 'motif_pattern', motif_pattern = args{i+1}; 
+  end
+end
+
+% set defaults
+motif_length = length(motif_pattern);
+background_char = [];
+
+% get params
+for i=1:2:nargs
+  switch args{i},
+   case 'motif_length', motif_length = args{i+1}; 
+   case 'background', background_char = args{i+1};
+  end
+end
+
+
+chars = ['a', 'c', 'g', 't'];
+Osize = length(chars);
+
+Qsize = [2 motif_length];
+Qnodes = 1:2;
+D = 2;
+transprob = cell(1,D);
+termprob = cell(1,D);
+startprob = cell(1,D);
+
+% startprob{d}(k,j), startprob{1}(1,j)
+% transprob{d}(i,k,j), transprob{1}(i,j)
+% termprob{d}(k,j)
+
+
+% LEVEL 1
+
+startprob{1} = zeros(1, 2);
+startprob{1} = [1 0]; % always start in the background model
+
+% When in the background state, we stay there with high prob
+% When in the motif state, we immediately return to the background state.
+transprob{1} = [0.8 0.2;
+		1.0 0.0];
+
+
+% LEVEL 2
+startprob{2} = 'leftstart'; % both submodels start in substate 1
+transprob{2} = zeros(motif_length, 2, motif_length);
+termprob{2} = zeros(2, motif_length);
+
+% In the background model, we only use state 1.
+transprob{2}(1,1,1) = 1; % self loop
+termprob{2}(1,1) = 0.2; % prob transition to end state
+
+% Motif model
+transprob{2}(:,2,:) = mk_leftright_transmat(motif_length, 0); % no self loops
+termprob{2}(2,end) = 1.0; % last state immediately terminates
+
+
+% OBS LEVEl
+
+obsprob = zeros([Qsize Osize]);
+if isempty(background_char)
+  % uniform background model
+  %obsprob(1,1,:) = normalise(ones(Osize,1));
+  obsprob(1,1,:) = normalise(rand(Osize,1));
+else
+  % deterministic background model (easy to see!)
+  m = find(chars==background_char);
+  obsprob(1,1,m) = 1.0;
+end
+
+if ~isempty(motif_pattern)
+  % initialise with true motif (cheating)
+  for i=1:motif_length
+    m = find(chars == motif_pattern(i));
+    obsprob(2,i,m) = 1.0;
+  end
+else
+  obsprob(2,:,:) = mk_stochastic(rand(motif_length, Osize));
+end
+
+if 0
+  Oargs = {'CPT', obsprob};
+else
+  % We use a minent prior for the emission distribution for the states in the motif model
+  % (but not the background model). This encourages nearly deterministic distributions.
+  % We create an index matrix  (where M = motif length)
+  %  [2 1
+  %   2 2
+  %   ...
+  %   2 M]
+  % and then convert this to a list of integers, which
+  % specifies when to use the minent prior (Q1=2 specifies motif model).
+  M = motif_length;
+  ndx = [2*ones(M,1) (1:M)'];
+  pcases = subv2ind([2 motif_length], ndx);
+  Oargs = {'CPT', obsprob, 'prior_type', 'entropic', 'entropic_pcases', pcases};
+end
+
+
+
+[bnet, Qnodes, Fnodes, Onode] = mk_hhmm('Qsizes', Qsize, 'Osize', Osize, 'discrete_obs', 1, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(1:2), ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/sample_motif_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/sample_motif_hhmm.m
new file mode 100644
index 00000000..b5822e10
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Motif/sample_motif_hhmm.m
@@ -0,0 +1,10 @@
+%bnet = mk_motif_hhmm('motif_pattern', 'acca', 'background', 't');
+bnet = mk_motif_hhmm('motif_pattern', 'accaggggga', 'background', []);
+
+chars = ['a', 'c', 'g', 't'];
+Tmax = 100;
+
+for seqi=1:5
+  evidence = cell2num(sample_dbn(bnet, 'length', Tmax));
+  chars(evidence(end,:))
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Entries
new file mode 100644
index 00000000..6caae4a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Entries
@@ -0,0 +1,8 @@
+/mk_abcd_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_arrow_alpha_hhmm3.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_hhmm2.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_hhmm3.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_hhmm3_args.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/motif_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/remove_hhmm_end_state.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Repository
new file mode 100644
index 00000000..cc9acc63
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Old
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_abcd_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_abcd_hhmm.m
new file mode 100644
index 00000000..330bc304
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_abcd_hhmm.m
@@ -0,0 +1,109 @@
+% Make the HHMM in Figure 1 of the NIPS'01 paper
+
+Qsize = [2 3 2];
+D = 3;
+
+% transprob{d}(i,k,j), transprob{1}(i,j)
+% termprob{d}(k,j), termprob{1}(1,j)
+% startprob{d}(k,j), startprob{1}(1,j)
+% obsprob(k, o) for discrete outputs
+    
+% LEVEL 1
+%       1 2 e
+A{1} = [0 0 1;
+	0 0 1];
+[transprob{1}, termprob{1}] = remove_hhmm_end_state(A{1});
+startprob{1} = [0.5 0.5];
+Q1args = {'startprob', startprob{1}, 'transprob', transprob{1}};
+
+% LEVEL 2
+A{2} = zeros(Qsize(2), Qsize(1), Qsize(2)+1);
+
+%              1 2 3 e
+A{2}(:,1,:) = [0 1 0 0
+	       0 0 1 0
+	       0 0 0 1];
+
+%              1 2 3 e
+A{2}(:,2,:) = [0 1 0 0
+	       0 0 1 0
+	       0 0 0 1];
+
+[transprob{2}, termprob{2}] = remove_hhmm_end_state(A{2});	       
+
+% always enter level 2 in state 1
+startprob{2} = [1 0 0
+		1 0 0];
+
+Q2args = {'startprob', startprob{2}, 'transprob', transprob{2}};
+F2args = {'CPT', termprob{2}};
+
+
+% LEVEL 3
+
+A{3} = zeros([Qsize(3) Qsize(1:2) Qsize(3)+1]);
+endstate = Qsize(3)+1;
+%    Qt-1(3) Qt(1) Qt(2) Qt(3)
+%                               1   2   e
+A{3}(1,      1,    1,    endstate) = 1.0;
+A{3}(:,      1,    2,    :) = [0.0 1.0 0.0
+            	               0.5 0.0 0.5];
+A{3}(1,      1,    3,    endstate) = 1.0;
+
+A{3}(1,      2,    1,    endstate) = 1.0;
+A{3}(:,      2,    2,    :) = [0.0 1.0 0.0
+            	               0.5 0.0 0.5];
+A{3}(1,      2,    3,    endstate) = 1.0;
+
+A{3} = reshape(A{3}, [Qsize(3) prod(Qsize(1:2)) Qsize(3)+1]);
+[transprob{3}, termprob{3}] = remove_hhmm_end_state(A{3});	       
+
+% define the vertical entry points to level 3
+startprob{3} = zeros(Qsize);
+%            Q1 Q2 Q3
+startprob{3}(1, 1, 1) = 1.0;
+startprob{3}(1, 2, 1) = 1.0;
+startprob{3}(1, 3, 1) = 1.0;
+
+startprob{3}(2, 1, 1) = 1.0;
+startprob{3}(2, 2, 1) = 1.0;
+startprob{3}(2, 3, 1) = 1.0;
+
+startprob{3} = reshape(startprob{3}, prod(Qsize(1:2)), Qsize(3));
+
+chars = ['a', 'b', 'c', 'd', 'x', 'y'];
+Osize = length(chars);
+
+obsprob = zeros([Qsize Osize]);
+%       1 2 3 O
+obsprob(1,1,1,find(chars == 'a')) =  1.0;
+
+obsprob(1,2,1,find(chars == 'x')) =  1.0;
+obsprob(1,2,2,find(chars == 'y')) =  1.0;
+
+obsprob(1,3,1,find(chars == 'b')) =  1.0;
+
+obsprob(2,1,1,find(chars == 'c')) =  1.0;
+
+obsprob(2,2,1,find(chars == 'x')) =  1.0;
+obsprob(2,2,2,find(chars == 'y')) =  1.0;
+
+obsprob(2,3,1,find(chars == 'd')) =  1.0;
+
+obsprob = reshape(obsprob, prod(Qsize), Osize);
+
+[intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo(D);
+
+hhmm.Qnodes = Qnodes;
+hhmm.Fnodes = Fnodes;
+hhmm.Onode = Onode;
+hhmm.D = D;
+hhmm.Qsize = Qsize;
+hhmm.Osize = Osize;
+hhmm.startprob = startprob;
+hhmm.transprob = transprob;
+hhmm.termprob = termprob;
+hhmm.obsprob = obsprob;
+hhmm.A = A;
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_arrow_alpha_hhmm3.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_arrow_alpha_hhmm3.m
new file mode 100644
index 00000000..ba1aa8cb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_arrow_alpha_hhmm3.m
@@ -0,0 +1,86 @@
+% Make the following HHMM
+%
+%     LH                  RH
+%    /                      \
+%   /                        \
+%  LR -> UD -> RL -> DU       RL -> UD -> LR -> DU
+%   \
+%    \
+%     Q1 -> Q2
+%
+% where level 1 is fully interconnected (not shown)
+% level 2 is left-right
+% and each model at level 3 is a 2 state LR shared HMM 
+
+Qsizes = [2 4 2];
+D = 3;
+
+% LEVEL 1
+
+startprob1 = 'ergodic';
+transprob1 = 'ergodic';
+
+
+% LEVEL 2
+
+startprob = zeros(2, 4);
+%        Q1  Q2
+startprob(1, 1) = 1;
+startprob(2, 3) = 1;
+
+transprob = zeros(2, 4, 4);
+transprob(1,:,:) = [0 1 0 0
+		    0 0 1 0
+		    0 0 0 1
+		    0 0 0 1];
+transprob(2,:,:) = [0 0 0 1
+		    1 0 0 0
+		    0 1 0 0
+		    0 0 0 1];
+
+Q2args = {'startprob', startprob, 'transprob', transprob};
+
+% always terminate in state 4 (default)
+% F2args
+
+% LEVEL 3
+
+% Defaults are fine: always start in state 1, left-right model, finish in state 2
+
+
+% OBS LEVEl
+
+chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+Osize = length(chars);
+
+obsprob = zeros([4 2 Osize]);
+%       Q2 Q3 O
+obsprob(1, 1, find(chars == 'L')) =  1.0;
+obsprob(1, 2, find(chars == 'l')) =  1.0;
+
+obsprob(2, 1, find(chars == 'U')) =  1.0;
+obsprob(2, 2, find(chars == 'u')) =  1.0;
+
+obsprob(3, 1, find(chars == 'R')) =  1.0;
+obsprob(3, 2, find(chars == 'r')) =  1.0;
+
+obsprob(4, 1, find(chars == 'D')) =  1.0;
+obsprob(4, 2, find(chars == 'd')) =  1.0;
+
+Oargs = {'CPT', obsprob};
+
+
+bnet = mk_hhmm3('Qsizes', Qsizes, 'Osize', Osize', 'discrete_obs', 1, 'Oargs', Oargs, 'Q1args', Q1args, 'Q2args', Q2args);
+
+T = 20;
+usecell = 0;
+evidence = sample_dbn(bnet, T, usecell);      
+%chars(evidence(end,:))
+
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; obs = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+
+pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, obs, chars);
+
+eclass = bnet.equiv_class;
+S=struct(bnet.CPD{eclass(Q2,2)})
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm2.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm2.m
new file mode 100644
index 00000000..032015ba
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm2.m
@@ -0,0 +1,111 @@
+function bnet = mk_hhmm2(varargin)
+% MK_HHMM2 Make a 2 level Hierarchical HMM
+% bnet = mk_hhmm2(...)
+%
+% 2-layer hierarchical HMM  (node numbers in parens)
+%
+%   Q1(1) ---------> Q1(5)
+% /  | \            / |
+% |  |  v          /  |
+% |  |  F2(3) --- /   |
+% |  |  ^         \   |
+% |  | /           \  |
+% |  v              \ v
+% |  Q2(2)--------> Q2 (6)
+% |  |    
+% \  | 
+%  v v    
+%   O(4)
+%
+%
+% Optional arguments [default]
+%
+% discrete_obs - 1 means O is tabular_CPD, 0 means O is gaussian_CPD [0]
+% obsCPT       - CPT(o,q1,q2) params for O ['rnd']
+% mu           - mu(:,q1,q2) params for O [ [] ]
+% Sigma        - Sigma(:,q1,q2) params for O [ [] ]
+%
+% F2toQ1       - 1 if Q2 is an hhmm_CPD, 0 if F2 -> Q2 arc is absent, so level 2 never resets [1]
+% Q1args        - arguments to be passed to the constructors for Q1(t=2) [ {} ]
+% Q2args        - arguments to be passed to the constructors for Q2(t=2) [ {} ]
+%
+% F2 only turns on (wp 0.5) when Q2 enters its final state.
+% Q1 (slice 1) is clamped to be uniform.
+% Q2 (slice 1) is clamped to always start in state 1.
+
+[os nmodels nstates] = size(mu);
+
+ss = 4;
+Q1 = 1; Q2 = 2; F2 = 3; obs = 4;
+Qnodes = [Q1 Q2];
+names = {'Q1', 'Q2', 'F2', 'obs'};
+intra = zeros(ss);
+intra(Q1, [Q2 F2 obs]) = 1;
+intra(Q2, [F2 obs]) = 1;
+
+inter = zeros(ss);
+inter(Q1,Q1) = 1;
+inter(F2,Q1) = 1;
+if F2toQ2
+  inter(F2,Q2)=1;
+end
+inter(Q2,Q2) = 1;
+
+ns = zeros(1,ss);
+
+ns(Q1) = nmodels;
+ns(Q2) = nstates;
+ns(F2) = 2;
+ns(obs) = os;
+
+dnodes = [Q1 Q2 F2];
+if discrete_obs
+  dnodes = [dnodes obs];
+end
+onodes = [obs];
+
+bnet = mk_dbn(intra, inter, ns, 'observed', onodes, 'discrete', dnodes, 'names', names);
+eclass = bnet.equiv_class;
+
+% SLICE 1
+
+% We clamp untied nodes in the first slice, since their params can't be estimated
+% from just one sequence
+
+% uniform prior on initial model
+CPT = normalise(ones(1,nmodels));
+bnet.CPD{eclass(Q1,1)} = tabular_CPD(bnet, Q1, 'CPT', CPT, 'adjustable', 0);
+
+% each model always starts in state 1
+CPT = zeros(ns(Q1), ns(Q2));
+CPT(:, 1) = 1.0;
+bnet.CPD{eclass(Q2,1)} = tabular_CPD(bnet, Q2, 'CPT', CPT, 'adjustable', 0);
+
+% Termination probability
+CPT = zeros(ns(Q1), ns(Q2), 2);
+if 1
+  % Each model can only terminate in its final state.
+  % 0 params will remain 0 during EM, thus enforcing this constraint.
+  CPT(:, :, 1) = 1.0; % all states turn F off ...
+  p = 0.5;
+  CPT(:, ns(Q2), 2) = p; % except the last one
+  CPT(:, ns(Q2), 1) = 1-p;
+end
+bnet.CPD{eclass(F2,1)}  = tabular_CPD(bnet, F2, 'CPT', CPT);
+
+if discrete_obs
+  bnet.CPD{eclass(obs,1)} = tabular_CPD(bnet, obs, obs_args{:});
+else
+  bnet.CPD{eclass(obs,1)} = gaussian_CPD(bnet, obs, obs_args{:});
+end
+
+% SLICE 2
+
+
+bnet.CPD{eclass(Q1,2)} = hhmm_CPD(bnet, Q1+ss, Qnodes, 1, D, 'args', Q1args);
+
+if F2toQ2
+  bnet.CPD{eclass(Q2,2)} = hhmmQD_CPD(bnet, Q2+ss, Qnodes, 2, D, Q2args{:});
+else
+  bnet.CPD{eclass(Q2,2)} = tabular_CPD(bnet, Q2+ss, Q2args{:});
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3.m
new file mode 100644
index 00000000..5b2cd6aa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3.m
@@ -0,0 +1,181 @@
+function bnet = mk_hhmm3(varargin)
+% MK_HHMM3 Make a 3 level Hierarchical HMM
+% bnet = mk_hhmm3(...)
+%
+% 3-layer hierarchical HMM where level 1 only connects to level 2, not 3 or obs.
+% This enforces sub-models (which differ only in their Q1 index) to be shared.
+% Also, we enforce the fact that each model always starts in its initial state
+% and only finishes in its final state. However, the prob. of finishing (as opposed to
+% self-transitioning to the final state) can be learned.
+% The fact that we always finish from the same state means we do not need to condition
+% F(i) on Q(i-1), since finishing prob is indep of calling context.
+%
+% The DBN is the same as Fig 10 in my tech report.
+%
+%   Q1 ---------->  Q1
+%   |              / |
+%   |             /  |
+%   |  F2 -------    |
+%   |  ^         \   |
+%   | /|          \  |
+%   v  |           v v
+%   Q2-| -------->   Q2
+%  /|  |             ^
+% / |  |            /|
+% | |  F3 ---------/ |
+% | |  ^           \ |
+% | v /              v
+% | Q3 ----------->  Q3
+% |  |    
+% \  | 
+%  v v    
+%   O
+%
+%
+% Optional arguments in name/value format [default]
+%
+% Qsizes      - sizes at each level [ none ]
+% Osize       - size of O node [ none ]
+% discrete_obs - 1 means O is tabular_CPD, 0 means O is gaussian_CPD [0]
+% Oargs       - cell array of args to pass to the O CPD  [ {} ]
+% transprob1  - transprob1(i,j) = P(Q1(t)=j|Q1(t-1)=i)  ['ergodic']
+% startprob1  - startprob1(j) = P(Q1(t)=j)  ['leftstart']
+% transprob2  - transprob2(i,k,j) = P(Q2(t)=j|Q2(t-1)=i,Q1(t)=k)  ['leftright']
+% startprob2  - startprob2(k,j) = P(Q2(t)=j|Q1(t)=k)  ['leftstart']
+% termprob2   - termprob2(j,f) = P(F2(t)=f|Q2(t)=j)  ['rightstop']
+% transprob3  - transprob3(i,k,j) = P(Q3(t)=j|Q3(t-1)=i,Q2(t)=k)  ['leftright']
+% startprob3  - startprob3(k,j) = P(Q3(t)=j|Q2(t)=k)  ['leftstart']
+% termprob3   - termprob3(j,f) = P(F3(t)=f|Q3(t)=j)  ['rightstop']
+%
+% leftstart means the model always starts in state 1.
+% rightstop means the model always finished in its last state (Qsize(d)).
+%
+% Q1:Q3 in slice 1 are of type tabular_CPD
+% Q1:Q3 in slice 2 are of type hhmmQ_CPD.
+% F2 is of type hhmmF_CPD, F3 is of type tabular_CPD.
+
+ss = 6; D = 3;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; obs = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+names = {'Q1', 'Q2', 'Q3', 'F3', 'F2', 'obs'};
+
+intra = zeros(ss);
+intra(Q1, Q2) = 1;
+intra(Q2, [F2 Q3 obs]) = 1;
+intra(Q3, [F3 obs]) = 1;
+intra(F3, F2) = 1;
+
+inter = zeros(ss);
+inter(Q1,Q1) = 1;
+inter(Q2,Q2) = 1;
+inter(Q3,Q3) = 1;
+inter(F2,[Q1 Q2]) = 1;
+inter(F3,[Q2 Q3]) = 1;
+
+
+% get sizes of nodes
+args = varargin;
+nargs = length(args);
+Qsizes = [];
+Osize = 0;
+for i=1:2:nargs
+  switch args{i},
+   case 'Qsizes', Qsizes = args{i+1}; 
+   case 'Osize', Osize = args{i+1}; 
+  end
+end
+if isempty(Qsizes), error('must specify Qsizes'); end
+if Osize==0, error('must specify Osize'); end
+  
+% set default params
+discrete_obs = 0;
+Oargs = {};
+startprob1 = 'ergodic';
+startprob2 = 'leftstart';
+startprob3 = 'leftstart';
+transprob1 = 'ergodic';
+transprob2 = 'leftright';
+transprob3 = 'leftright';
+termprob2 = 'rightstop';
+termprob3 = 'rightstop';
+
+
+for i=1:2:nargs
+  switch args{i},
+   case 'discrete_obs', discrete_obs = args{i+1}; 
+   case 'Oargs',        Oargs = args{i+1};
+   case 'Q1args',       Q1args = args{i+1};
+   case 'Q2args',       Q2args = args{i+1};
+   case 'Q3args',       Q3args = args{i+1};
+   case 'F2args',       F2args = args{i+1};
+   case 'F3args',       F3args = args{i+1};
+  end
+end
+
+
+ns = zeros(1,ss);
+ns(Qnodes) = Qsizes;
+ns(obs) = Osize;
+ns(Fnodes) = 2;
+
+dnodes = [Qnodes Fnodes];
+if discrete_obs
+  dnodes = [dnodes obs];
+end
+onodes = [obs];
+
+bnet = mk_dbn(intra, inter, ns, 'observed', onodes, 'discrete', dnodes, 'names', names);
+eclass = bnet.equiv_class;
+
+if strcmp(startprob1, 'ergodic')
+  startprob1 = normalise(ones(1,ns(Q1)));
+end
+if strcmp(startprob2, 'leftstart')
+  startprob2 = zeros(ns(Q1), ns(Q2));
+  starpbrob2(:, 1) = 1.0;
+end
+if strcmp(startprob3, 'leftstart')
+  startprob3 = zeros(ns(Q2), ns(Q3));
+  starpbrob3(:, 1) = 1.0;
+end
+
+if strcmp(termprob2, 'rightstop')
+  p = 0.9;
+  termprob2 = zeros(Qsize(2),2);
+  termprob2(:, 2) = p; 
+  termprob2(:, 1) = 1-p; 
+  termprob2(1:(Qsize(2)-1), 1) = 1; 
+end
+if strcmp(termprob3, 'rightstop')
+  p = 0.9;
+  termprob3 = zeros(Qsize(3),2);
+  termprob3(:, 2) = p; 
+  termprob3(:, 1) = 1-p; 
+  termprob3(1:(Qsize(3)-1), 1) = 1; 
+end
+
+
+% SLICE 1
+
+% We clamp untied nodes in the first slice, since their params can't be estimated
+% from just one sequence
+
+bnet.CPD{eclass(Q1,1)} = tabular_CPD(bnet, Q1, 'CPT', startprob1, 'adjustable', 0);
+bnet.CPD{eclass(Q2,1)} = tabular_CPD(bnet, Q2, 'CPT', startprob2, 'adjustable', 0);
+bnet.CPD{eclass(Q3,1)} = tabular_CPD(bnet, Q3, 'CPT', startprob3, 'adjustable', 0);
+
+bnet.CPD{eclass(F2,1)}  = hhmmF_CPD(bnet, F2, Qnodes, 2, D, 'termprob', termprob2);
+bnet.CPD{eclass(F3,1)}  = tabular_CPD(bnet, F3, 'CPT', termprob3);
+
+if discrete_obs
+  bnet.CPD{eclass(obs,1)} = tabular_CPD(bnet, obs, Oargs{:});
+else
+  bnet.CPD{eclass(obs,1)} = gaussian_CPD(bnet, obs, Oargs{:});
+end
+
+% SLICE 2
+
+bnet.CPD{eclass(Q1,2)} = hhmmQ_CPD(bnet, Q1+ss, Qnodes, 1, D, 'transprob', transprob1, 'startprob', startprob1);
+bnet.CPD{eclass(Q2,2)} = hhmmQ_CPD(bnet, Q2+ss, Qnodes, 2, D, 'transprob', transprob2, 'startprob', startprob2);
+bnet.CPD{eclass(Q3,2)} = hhmmQ_CPD(bnet, Q3+ss, Qnodes, 3, D, 'transprob', transprob3, 'startprob', startprob3);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3_args.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3_args.m
new file mode 100644
index 00000000..bc3ec886
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/mk_hhmm3_args.m
@@ -0,0 +1,165 @@
+function bnet = mk_hhmm3(varargin)
+% MK_HHMM3 Make a 3 level Hierarchical HMM
+% bnet = mk_hhmm3(...)
+%
+% 3-layer hierarchical HMM where level 1 only connects to level 2, not 3 or obs.
+% This enforces sub-models (which differ only in their Q1 index) to be shared.
+% Also, we enforce the fact that each model always starts in its initial state
+% and only finishes in its final state. However, the prob. of finishing (as opposed to
+% self-transitioning to the final state) can be learned.
+% The fact that we always finish from the same state means we do not need to condition
+% F(i) on Q(i-1), since finishing prob is indep of calling context.
+%
+% The DBN is the same as Fig 10 in my tech report.
+%
+%   Q1 ---------->  Q1
+%   |              / |
+%   |             /  |
+%   |  F2 -------    |
+%   |  ^         \   |
+%   | /|          \  |
+%   v  |           v v
+%   Q2-| -------->   Q2
+%  /|  |             ^
+% / |  |            /|
+% | |  F3 ---------/ |
+% | |  ^           \ |
+% | v /              v
+% | Q3 ----------->  Q3
+% |  |    
+% \  | 
+%  v v    
+%   O
+%
+% Q1 (slice 1) is clamped to be uniform.
+% Q2 (slice 1) is clamped to always start in state 1.
+% Q3 (slice 1) is clamped to always start in state 1.
+% F3 by default will only finish if Q3 is in its last state (F3 is a tabular_CPD)
+% F2 by default gets the default hhmmF_CPD params.
+% Q1:Q3 (slice 2) by default gets the default hhmmQ_CPD params.
+% O by default gets the default tabular/Gaussian params.
+%
+% Optional arguments in name/value format [default]
+%
+% Qsizes      - sizes at each level [ none ]
+% Osize       - size of O node [ none ]
+% discrete_obs - 1 means O is tabular_CPD, 0 means O is gaussian_CPD [0]
+% Oargs       - cell array of args to pass to the O CPD  [ {} ]
+% Q1args      - args to be passed to constructor for Q1 (slice 2) [ {} ]
+% Q2args      - args to be passed to constructor for Q2 (slice 2) [ {} ]
+% Q3args      - args to be passed to constructor for Q3 (slice 2) [ {} ]
+% F2args       - args to be passed to constructor for F2 [ {} ]
+% F3args       - args to be passed to constructor for F3 [ {'CPT', finish in last Q3 state} ]
+%
+
+ss = 6; D = 3;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; obs = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+names = {'Q1', 'Q2', 'Q3', 'F3', 'F2', 'obs'};
+
+intra = zeros(ss);
+intra(Q1, Q2) = 1;
+intra(Q2, [F2 Q3 obs]) = 1;
+intra(Q3, [F3 obs]) = 1;
+intra(F3, F2) = 1;
+
+inter = zeros(ss);
+inter(Q1,Q1) = 1;
+inter(Q2,Q2) = 1;
+inter(Q3,Q3) = 1;
+inter(F2,[Q1 Q2]) = 1;
+inter(F3,[Q2 Q3]) = 1;
+
+
+% get sizes of nodes
+args = varargin;
+nargs = length(args);
+Qsizes = [];
+Osize = 0;
+for i=1:2:nargs
+  switch args{i},
+   case 'Qsizes', Qsizes = args{i+1}; 
+   case 'Osize', Osize = args{i+1}; 
+  end
+end
+if isempty(Qsizes), error('must specify Qsizes'); end
+if Osize==0, error('must specify Osize'); end
+  
+% set default params
+discrete_obs = 0;
+Oargs = {};
+Q1args = {};
+Q2args = {};
+Q3args = {};
+F2args = {};
+
+% P(Q3, F3)
+CPT = zeros(Qsizes(3), 2);
+% Each model can only terminate in its final state.
+% 0 params will remain 0 during EM, thus enforcing this constraint.
+CPT(:, 1) = 1.0; % all states turn F off ...
+p = 0.5;
+CPT(Qsizes(3), 2) = p; % except the last one
+CPT(Qsizes(3), 1) = 1-p;
+F3args = {'CPT', CPT};
+
+for i=1:2:nargs
+  switch args{i},
+   case 'discrete_obs', discrete_obs = args{i+1}; 
+   case 'Oargs',        Oargs = args{i+1};
+   case 'Q1args',       Q1args = args{i+1};
+   case 'Q2args',       Q2args = args{i+1};
+   case 'Q3args',       Q3args = args{i+1};
+   case 'F2args',       F2args = args{i+1};
+   case 'F3args',       F3args = args{i+1};
+  end
+end
+
+ns = zeros(1,ss);
+ns(Qnodes) = Qsizes;
+ns(obs) = Osize;
+ns(Fnodes) = 2;
+
+dnodes = [Qnodes Fnodes];
+if discrete_obs
+  dnodes = [dnodes obs];
+end
+onodes = [obs];
+
+bnet = mk_dbn(intra, inter, ns, 'observed', onodes, 'discrete', dnodes, 'names', names);
+eclass = bnet.equiv_class;
+
+% SLICE 1
+
+% We clamp untied nodes in the first slice, since their params can't be estimated
+% from just one sequence
+
+% uniform prior on initial model
+CPT = normalise(ones(1,ns(Q1)));
+bnet.CPD{eclass(Q1,1)} = tabular_CPD(bnet, Q1, 'CPT', CPT, 'adjustable', 0);
+
+% each model always starts in state 1
+CPT = zeros(ns(Q1), ns(Q2));
+CPT(:, 1) = 1.0;
+bnet.CPD{eclass(Q2,1)} = tabular_CPD(bnet, Q2, 'CPT', CPT, 'adjustable', 0);
+
+% each model always starts in state 1
+CPT = zeros(ns(Q2), ns(Q3));
+CPT(:, 1) = 1.0;
+bnet.CPD{eclass(Q3,1)} = tabular_CPD(bnet, Q3, 'CPT', CPT, 'adjustable', 0);
+
+bnet.CPD{eclass(F2,1)}  = hhmmF_CPD(bnet, F2, Qnodes, 2, D, F2args{:});
+
+bnet.CPD{eclass(F3,1)}  = tabular_CPD(bnet, F3, F3args{:});
+
+if discrete_obs
+  bnet.CPD{eclass(obs,1)} = tabular_CPD(bnet, obs, Oargs{:});
+else
+  bnet.CPD{eclass(obs,1)} = gaussian_CPD(bnet, obs, Oargs{:});
+end
+
+% SLICE 2
+
+bnet.CPD{eclass(Q1,2)} = hhmmQ_CPD(bnet, Q1+ss, Qnodes, 1, D, Q1args{:});
+bnet.CPD{eclass(Q2,2)} = hhmmQ_CPD(bnet, Q2+ss, Qnodes, 2, D, Q2args{:});
+bnet.CPD{eclass(Q3,2)} = hhmmQ_CPD(bnet, Q3+ss, Qnodes, 3, D, Q3args{:});
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/motif_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/motif_hhmm.m
new file mode 100644
index 00000000..10144b58
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/motif_hhmm.m
@@ -0,0 +1,95 @@
+% Make the following HHMM
+%
+%    S1 <----------------------> S2
+%    |                           |
+%    |                           |
+%   M1 -> M2 -> M3 -> end        B1 -> end
+%
+% where Mi represents the i'th letter in the motif
+% and B is the background state.
+% Si chooses between running the motif or the background.
+% The Si and B states have self loops (not shown).
+
+if 0
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+end
+
+chars = ['a', 'c', 'g', 't'];
+Osize = length(chars);
+
+motif_pattern = 'acca';
+motif_length = length(motif_pattern);
+Qsize = [2 motif_length];
+Qnodes = 1:2;
+D = 2;
+transprob = cell(1,D);
+termprob = cell(1,D);
+startprob = cell(1,D);
+
+% startprob{d}(k,j), startprob{1}(1,j)
+% transprob{d}(i,k,j), transprob{1}(i,j)
+% termprob{d}(k,j)
+
+
+% LEVEL 1
+
+startprob{1} = zeros(1, 2);
+startprob{1} = [1 0]; % always start in the background model
+
+% When in the background state, we stay there with high prob
+% When in the motif state, we immediately return to the background state.
+transprob{1} = [0.8 0.2;
+		1.0 0.0];
+
+
+% LEVEL 2
+startprob{2} = 'leftstart'; % both submodels start in substate 1
+transprob{2} = zeros(motif_length, 2, motif_length);
+termprob{2} = zeros(2, motif_length);
+
+% In the background model, we only use state 1.
+transprob{2}(1,1,1) = 1; % self loop
+termprob{2}(1,1) = 0.2; % prob transition to end state
+
+% Motif model
+transprob{2}(:,2,:) = mk_leftright_transmat(motif_length, 0);
+termprob{2}(2,end) = 1.0; % last state immediately terminates
+
+
+% OBS LEVEl
+
+obsprob = zeros([Qsize Osize]);
+if 0
+  % uniform background model
+  obsprob(1,1,:) = normalise(ones(Osize,1));
+else
+  % deterministic background model (easy to see!)
+  m = find(chars=='t');
+  obsprob(1,1,m) = 1.0;
+end
+if 1
+  % initialise with true motif (cheating)
+  for i=1:motif_length
+    m = find(chars == motif_pattern(i));
+    obsprob(2,i,m) = 1.0;
+  end
+end
+
+Oargs = {'CPT', obsprob};
+
+[bnet, Qnodes, Fnodes, Onode] = mk_hhmm('Qsizes', Qsize, 'Osize', Osize, 'discrete_obs', 1, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(1:2), ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
+
+Tmax = 20;
+usecell = 0;
+
+for seqi=1:5
+  evidence = sample_dbn(bnet, Tmax, usecell);
+  chars(evidence(end,:))
+  %T = size(evidence, 2)
+  %pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, Onode, chars);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/remove_hhmm_end_state.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/remove_hhmm_end_state.m
new file mode 100644
index 00000000..2bf10d72
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Old/remove_hhmm_end_state.m
@@ -0,0 +1,37 @@
+function [transprob, termprob] = remove_hhmm_end_state(A)
+% REMOVE_END_STATE Infer transition and termination probabilities from automaton with an end state
+% [transprob, termprob] = remove_end_state(A)
+% A(i,k,j) = Pr( i->j | Qps=k), where i in 1:Q, j in 1:(Q+1), and Q+1 is the end state
+
+if ndims(A)==2 % top level
+  Q = size(A,1);
+  transprob = A(:,1:Q);
+  termprob = A(:,Q+1)';
+  
+  % rescale
+  for i=1:Q
+    for j=1:Q
+      denom = (1-termprob(i));
+      denom = denom + (denom==0)*eps;
+      transprob(i,j) = transprob(i,j) / denom;
+    end
+  end    
+else
+  Q = size(A,1);
+  Qk = size(A,2);
+  transprob = A(:, :, 1:Q);
+  termprob = A(:,:,Q+1)';
+
+  % rescale
+  for k=1:Qk
+    for i=1:Q
+      for j=1:Q
+	denom = (1-termprob(k,i));
+	denom = denom + (denom==0)*eps;
+	transprob(i,k,j) = transprob(i,k,j) / denom;
+      end
+    end    
+  end
+  
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Entries
new file mode 100644
index 00000000..fdee19ae
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Entries
@@ -0,0 +1,14 @@
+/get_square_data.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/hhmm_inference.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/is_F2_true_D3.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/learn_square_hhmm_cts.m/1.1.1.1/Thu Jun 20 00:19:22 2002//
+/learn_square_hhmm_discrete.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_square_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/plot_square_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_square_hhmm_cts.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_square_hhmm_discrete.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/square4.mat/1.1.1.1/Wed May 29 15:59:54 2002//
+/square4_cases.mat/1.1.1.1/Wed May 29 15:59:54 2002//
+/test_square_fig.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/test_square_fig.mat/1.1.1.1/Wed May 29 15:59:54 2002//
+D/Old////
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Repository
new file mode 100644
index 00000000..e926a0d5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Square
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Entries
new file mode 100644
index 00000000..6d415d0d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Entries
@@ -0,0 +1,5 @@
+/learn_square_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_square_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/plot_square_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_square_hhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Repository
new file mode 100644
index 00000000..47df1a8c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/HHMM/Square/Old
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/learn_square_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/learn_square_hhmm.m
new file mode 100644
index 00000000..695ae047
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/learn_square_hhmm.m
@@ -0,0 +1,294 @@
+% Learn a 3 level HHMM similar to mk_square_hhmm
+
+% Because startprob should be shared for t=1:T,
+% but in the DBN is shared for t=2:T, we train using a single long sequence.
+
+discrete_obs = 0;
+supervised = 1;
+obs_finalF2 = 0;
+% It is not possible to observe F2 if we learn
+% because the update_ess method for hhmmF_CPD and hhmmQ_CPD assume
+% the F nodes are always hidden (for speed).
+% However, for generating, we might want to set the final F2=true
+% to force all subroutines to finish.
+
+ss = 6;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+if discrete_obs
+  Qsizes = [2 4 2];
+else
+  Qsizes = [2 4 1];
+end
+
+D = 3;
+Qnodes = 1:D;
+startprob = cell(1,D);
+transprob = cell(1,D);
+termprob = cell(1,D);
+
+startprob{1} = 'unif';
+transprob{1} = 'unif';
+
+% In the unsupervised case, it is essential that we break symmetry
+% in the initial param estimates.
+%startprob{2} = 'unif';
+%transprob{2} = 'unif';
+%termprob{2} = 'unif';
+startprob{2} = 'rnd';
+transprob{2} = 'rnd';
+termprob{2} = 'rnd';
+
+leftright = 0;
+if leftright
+  % Initialise base-level models as left-right.
+  % If we initialise with delta functions,
+  % they will remain delat funcitons after learning
+  startprob{3} = 'leftstart';
+  transprob{3}  = 'leftright';
+  termprob{3} = 'rightstop';
+else
+  % If we want to be able to run a base-level model backwards...
+  startprob{3} = 'rnd';
+  transprob{3}  = 'rnd';
+  termprob{3} = 'rnd';
+end
+
+if discrete_obs
+  % Initialise observations of lowest level primitives in a way which we can interpret
+  chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+  L=find(chars=='L'); l=find(chars=='l');
+  U=find(chars=='U'); u=find(chars=='u');
+  R=find(chars=='R'); r=find(chars=='r');
+  D=find(chars=='D'); d=find(chars=='d');
+  Osize = length(chars);
+  
+  p = 0.9;
+  obsprob = (1-p)*ones([4 2 Osize]);
+  %       Q2 Q3 O
+  obsprob(1, 1, L) =  p;
+  obsprob(1, 2, l) =  p;
+  obsprob(2, 1, U) =  p;
+  obsprob(2, 2, u) =  p;
+  obsprob(3, 1, R) =  p;
+  obsprob(3, 2, r) =  p;
+  obsprob(4, 1, D) =  p;
+  obsprob(4, 2, d) =  p;
+  obsprob = mk_stochastic(obsprob);
+  Oargs = {'CPT', obsprob};
+
+else
+  % Initialise means of lowest level primitives in a way which we can interpret
+  % These means are little vectors in the east, south, west, north directions.
+  % (left-right=east, up-down=south, right-left=west, down-up=north)
+  Osize = 2;
+  mu = zeros(2, Qsizes(2), Qsizes(3));
+  noise = 0;
+  scale = 3;
+  for q3=1:Qsizes(3)
+    mu(:, 1, q3) = scale*[1;0] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 2, q3) = scale*[0;-1] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 3, q3) = scale*[-1;0] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 4, q3) = scale*[0;1] + noise*rand(2,1);
+  end
+  Sigma = repmat(reshape(scale*eye(2), [2 2 1 1 ]), [1 1 Qsizes(2) Qsizes(3)]);
+  Oargs = {'mean', mu, 'cov', Sigma, 'cov_type', 'diag'};
+end
+
+bnet = mk_hhmm('Qsizes', Qsizes, 'Osize', Osize', 'discrete_obs', discrete_obs,...
+	       'Oargs', Oargs, 'Ops', Qnodes(2:3), ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
+if supervised
+  bnet.observed = [Q1 Q2 Onode];
+else
+  bnet.observed = [Onode];
+end
+
+if obs_finalF2
+  engine = jtree_dbn_inf_engine(bnet);
+  % can't use ndx version because sometimes F2 is hidden, sometimes observed
+  error('can''t observe F when learning')
+else
+  if supervised
+    engine = jtree_ndx_dbn_inf_engine(bnet);
+  else
+    engine = jtree_hmm_inf_engine(bnet);
+  end
+end
+  
+if discrete_obs
+  % generate some synthetic data (easier to debug)
+  cases = {};
+
+  T = 8;
+  ev = cell(ss, T);
+  ev(Onode,:) = num2cell([L l U u R r D d]);
+  if supervised
+    ev(Q1,:) = num2cell(1*ones(1,T));
+    ev(Q2,:) = num2cell( [1 1 2 2 3 3 4 4]);
+  end
+  cases{1} = ev;
+  cases{3} = ev;
+    
+  T  = 8;
+  ev = cell(ss, T);
+  if leftright % base model is left-right
+    ev(Onode,:) = num2cell([R r U u L l D d]);
+  else
+    ev(Onode,:) = num2cell([r R u U l L d D]);
+  end
+  if supervised
+    ev(Q1,:) = num2cell(2*ones(1,T));
+    ev(Q2,:) = num2cell( [3 3 2 2 1 1 4 4]);
+  end
+    
+  cases{2} = ev;
+  cases{4} = ev;
+
+  if obs_finalF2
+    for i=1:length(cases)
+      T = size(cases{i},2);
+      cases{i}(F2,T)={2}; % force F2 to be finished at end of seq
+    end
+  end
+
+  if 0
+    ev = cases{4};
+    engine2 = enter_evidence(engine2, ev);
+    T = size(ev,2);
+    for t=1:T
+      m=marginal_family(engine2, F2, t);
+      fprintf('t=%d\n', t);
+      reshape(m.T, [2 2])
+    end
+  end
+  
+  %  [bnet2, LL] = learn_params_dbn_em(engine, cases, 'max_iter', 10);
+  long_seq = cat(2, cases{:});
+  [bnet2, LL, engine2] = learn_params_dbn_em(engine, {long_seq}, 'max_iter', 200);
+  
+  % figure out which subsequence each model is responsible for
+  mpe = calc_mpe_dbn(engine2, long_seq);
+  pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, chars);
+
+else
+  load 'square4_cases' % cases{seq}{i,t} for i=1:ss 
+  %plot_square_hhmm(cases{1})
+  %long_seq = cat(2, cases{:});
+  train_cases = cases(1:2);
+  long_seq = cat(2, train_cases{:});
+  if ~supervised
+    T = size(long_seq,2);
+    for t=1:T
+      long_seq{Q1,t} = [];
+      long_seq{Q2,t} = [];
+    end
+  end
+  [bnet2, LL, engine2] = learn_params_dbn_em(engine, {long_seq}, 'max_iter', 100);
+
+  CPDO=struct(bnet2.CPD{eclass(Onode,1)});
+  mu = CPDO.mean;
+  Sigma = CPDO.cov;
+  CPDO_full = CPDO;
+  
+  % force diagonal covs after training
+  for k=1:size(Sigma,3)
+    Sigma(:,:,k) = diag(diag(Sigma(:,:,k)));
+  end
+  bnet2.CPD{6} = set_fields(bnet.CPD{6}, 'cov', Sigma);
+  
+  if 0
+  % visualize each model by concatenating means for each model for nsteps in a row
+  nsteps = 5;
+  ev = cell(ss, nsteps*prod(Qsizes(2:3)));
+  t = 1;
+  for q2=1:Qsizes(2)
+    for q3=1:Qsizes(3)
+      for i=1:nsteps
+	ev{Onode,t} = mu(:,q2,q3);
+	ev{Q2,t} = q2;
+	t = t + 1;
+      end
+    end
+  end
+  plot_square_hhmm(ev)      
+  end
+
+  % bnet3 is the same as the learned model, except we will use it in testing mode
+  if supervised
+    bnet3 = bnet2;
+    bnet3.observed = [Onode];
+    engine3 = hmm_inf_engine(bnet3);
+    %engine3 = jtree_ndx_dbn_inf_engine(bnet3);
+  else
+    bnet3 = bnet2;
+    engine3 = engine2;
+  end
+  
+  if 0
+  % segment whole sequence
+  mpe = calc_mpe_dbn(engine3, long_seq);
+  pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, []);
+  end
+  
+  % segment each sequence
+  test_cases = cases(3:4);
+  for i=1:2
+    ev = test_cases{i};
+    T = size(ev, 2);
+    for t=1:T
+      ev{Q1,t} = [];
+      ev{Q2,t} = [];
+    end
+    mpe = calc_mpe_dbn(engine3, ev);
+    subplot(1,2,i)
+    plot_square_hhmm(mpe)      
+    %pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, []);
+    q1s = cell2num(mpe(Q1,:));
+    h = hist(q1s, 1:Qsizes(1));
+    map_q1 = argmax(h);
+    str = sprintf('test seq %d is of type %d\n', i, map_q1);
+    title(str)
+  end
+
+end
+
+if 0
+% Estimate gotten by couting transitions in the labelled data
+% Note that a self transition shouldnt count if F2=off.
+Q2ev = cell2num(ev(Q2,:));
+Q2a = Q2ev(1:end-1);
+Q2b = Q2ev(2:end);
+counts = compute_counts([Q2a; Q2b], [4 4]);
+end
+
+eclass = bnet2.equiv_class;
+CPDQ1=struct(bnet2.CPD{eclass(Q1,2)});
+CPDQ2=struct(bnet2.CPD{eclass(Q2,2)});
+CPDQ3=struct(bnet2.CPD{eclass(Q3,2)});
+CPDF2=struct(bnet2.CPD{eclass(F2,1)});
+CPDF3=struct(bnet2.CPD{eclass(F3,1)});
+
+
+A=add_hhmm_end_state(CPDQ2.transprob, CPDF2.termprob(:,:,2));
+squeeze(A(:,1,:))
+squeeze(A(:,2,:))
+CPDQ2.startprob
+ 
+if 0
+S=struct(CPDF2.sub_CPD_term);
+S.nsamples
+reshape(S.counts, [2 4 2])
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/mk_square_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/mk_square_hhmm.m
new file mode 100644
index 00000000..608b6784
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/mk_square_hhmm.m
@@ -0,0 +1,183 @@
+function bnet = mk_square_hhmm(discrete_obs, true_params, topright)
+
+% Make a 3 level  HHMM described by the following grammar
+%
+% Square -> CLK | CCK % clockwise or counterclockwise
+% CLK -> LR UD RL DU start on top left (1 2 3 4)
+% CCK -> RL UD LR DU  if start at top right (3 2 1 4)
+% CCK -> UD LR DU RL if start at top left (2 1 4 3)
+%
+% LR = left-right, UD = up-down, RL = right-left, DU = down-up
+% LR, UD, RL, DU are sub HMMs.
+%
+% For discrete observations, the subHMMs are 2-state left-right.
+% LR emits L then l, etc.
+%
+% For cts observations, the subHMMs are 1 state.
+% LR emits a vector in the -> direction, with a little noise.
+% Since there is no constraint that we remain in the LR state as long as the RL state,
+% the sides of the square might have different lengths,
+% so the result is not really a square!
+%
+% If true_params = 0, we use random parameters at the top 2 levels
+% (ready for learning). At the bottom level, we use noisy versions
+% of the "true" observations.
+%
+% If topright=1, counter-clockwise starts at top right, not top left
+% This example was inspired by Ivanov and Bobick.
+
+if nargin < 3, topright = 1; end
+
+if 1 % discrete_obs
+  Qsizes = [2 4 2];
+else
+  Qsizes = [2 4 1];
+end
+
+D = 3;
+Qnodes = 1:D;
+startprob = cell(1,D);
+transprob = cell(1,D);
+termprob = cell(1,D);
+
+% LEVEL 1
+
+startprob{1} = 'unif';
+transprob{1} = 'unif';
+
+% LEVEL 2
+
+if true_params
+  startprob{2} = zeros(2, 4);
+  startprob{2}(1, :) = [1 0 0 0];
+  if topright
+    startprob{2}(2, :) = [0 0 1 0];
+  else
+    startprob{2}(2, :) = [0 1 0 0];
+  end
+  
+  transprob{2} = zeros(4, 2, 4);
+  
+  transprob{2}(:,1,:) = [0 1 0 0
+		    0 0 1 0
+		    0 0 0 1
+		    0 0 0 1]; % 4->e
+  if topright
+    transprob{2}(:,2,:) = [0 0 0 1
+		    1 0 0 0
+		    0 1 0 0
+		    0 0 0 1]; % 4->e
+  else
+    transprob{2}(:,2,:) = [0 0 0 1
+		    1 0 0 0
+		    0 0 1 0 % 3->e
+		    0 0 1 0];
+  end
+  
+  %termprob{2} = 'rightstop';
+  termprob{2} = zeros(2,4,2);
+  pfin = 0.8;
+  termprob{2}(1,:,2) = [0 0 0 pfin]; % finish in state 4 (DU)
+  termprob{2}(1,:,1) = 1 - [0 0 0 pfin];
+  if topright
+    termprob{2}(2,:,2) = [0 0 0 pfin];
+    termprob{2}(2,:,1) = 1 - [0 0 0 pfin];
+  else
+    termprob{2}(2,:,2) = [0 0 pfin 0];  % finish in state 3 (RL)
+    termprob{2}(2,:,1) = 1 - [0 0 pfin 0];
+  end
+else
+  % In the unsupervised case, it is essential that we break symmetry
+  % in the initial param estimates.
+  %startprob{2} = 'unif';
+  %transprob{2} = 'unif';
+  %termprob{2} = 'unif';
+  startprob{2} = 'rnd';
+  transprob{2} = 'rnd';
+  termprob{2} = 'rnd';
+end
+
+% LEVEL 3
+
+if 1 |  true_params
+  startprob{3} = 'leftstart';
+  transprob{3}  = 'leftright';
+  termprob{3} = 'rightstop';
+else
+  % If we want to be able to run a base-level model backwards...
+  startprob{3} = 'rnd';
+  transprob{3}  = 'rnd';
+  termprob{3} = 'rnd';
+end
+ 
+
+% OBS LEVEl
+
+if discrete_obs
+  % Initialise observations of lowest level primitives in a way which we can interpret
+  chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+  L=find(chars=='L'); l=find(chars=='l');
+  U=find(chars=='U'); u=find(chars=='u');
+  R=find(chars=='R'); r=find(chars=='r');
+  D=find(chars=='D'); d=find(chars=='d');
+  Osize = length(chars);
+  
+  if true_params
+    p = 1; % makes each state fully observed
+  else
+    p = 0.9;
+  end
+  
+  obsprob = (1-p)*ones([4 2 Osize]);
+  %       Q2 Q3 O
+  obsprob(1, 1, L) =  p;
+  obsprob(1, 2, l) =  p;
+  obsprob(2, 1, U) =  p;
+  obsprob(2, 2, u) =  p;
+  obsprob(3, 1, R) =  p;
+  obsprob(3, 2, r) =  p;
+  obsprob(4, 1, D) =  p;
+  obsprob(4, 2, d) =  p;
+  obsprob = mk_stochastic(obsprob);
+  Oargs = {'CPT', obsprob};
+else
+  % Initialise means of lowest level primitives in a way which we can interpret
+  % These means are little vectors in the east, south, west, north directions.
+  % (left-right=east, up-down=south, right-left=west, down-up=north)
+  Osize = 2;
+  mu = zeros(2, Qsizes(2), Qsizes(3));
+  scale = 3;
+  if true_params
+    noise = 0;
+  else
+    noise = 0.5*scale;
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 1, q3) = scale*[1;0] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 2, q3) = scale*[0;-1] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 3, q3) = scale*[-1;0] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 4, q3) = scale*[0;1] + noise*rand(2,1);
+  end
+  Sigma = repmat(reshape(scale*eye(2), [2 2 1 1 ]), [1 1 Qsizes(2) Qsizes(3)]);
+  Oargs = {'mean', mu, 'cov', Sigma, 'cov_type', 'diag'};
+end
+
+if discrete_obs
+  selfprob = 0.5;
+else
+  selfprob = 0.95;
+  % If less than this, it won't look like a square
+  % because it doesn't spend enough time in each state
+  % Unfortunately, the variance on durations (lengths of each side)
+  % is very large
+end
+bnet = mk_hhmm('Qsizes', Qsizes, 'Osize', Osize', 'discrete_obs', discrete_obs, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(2:3), 'selfprob', selfprob, ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/plot_square_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/plot_square_hhmm.m
new file mode 100644
index 00000000..e6701e45
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/plot_square_hhmm.m
@@ -0,0 +1,32 @@
+function plot_square_hhmm(ev)
+% Plot the square shape implicit in the evidence.
+% ev{i,t} is the value of node i in slice t.
+% The observed node contains a velocity (delta increment), which is converted
+% into a position.
+% The Q2 node specifies which model is used; each segment is color-coded
+% in the order red, green, blue, black.
+
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+
+delta = cell2num(ev(Onode,:)); % delta(:,t)
+Q2label = cell2num(ev(Q2,:)); 
+
+T = size(delta, 2);
+pos = zeros(2,T+1);
+clf
+hold on
+cols = {'r', 'g', 'b', 'k'};
+boundary = 0;
+coli = 1;
+for t=2:T+1
+  pos(:,t) = pos(:,t-1) + delta(:,t-1);
+  plot(pos(1,t), pos(2,t), sprintf('%c.', cols{coli}));
+  if t < T
+    boundary = (Q2label(t) ~= Q2label(t-1));
+  end
+  if boundary
+    coli = coli + 1;
+    coli = mod(coli-1, length(cols)) + 1;
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/sample_square_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/sample_square_hhmm.m
new file mode 100644
index 00000000..a0f9007e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/Old/sample_square_hhmm.m
@@ -0,0 +1,160 @@
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+discrete_obs = 1;
+topright = 0;
+
+Qsizes = [2 4 2];
+D = 3;
+Qnodes = 1:D;
+startprob = cell(1,D);
+transprob = cell(1,D);
+termprob = cell(1,D);
+
+% LEVEL 1
+
+startprob{1} = 'ergodic';
+transprob{1} = 'ergodic';
+
+% LEVEL 2
+
+startprob{2} = zeros(2, 4);
+startprob{2}(1, :) = [1 0 0 0];
+if topright
+  startprob{2}(2, :) = [0 0 1 0];
+else
+  startprob{2}(2, :) = [0 1 0 0];
+end
+
+transprob{2} = zeros(4, 2, 4);
+
+transprob{2}(:,1,:) = [0 1 0 0
+		       0 0 1 0
+		       0 0 0 1
+		       0 0 0 1]; % 4->e
+if topright
+  transprob{2}(:,2,:) = [0 0 0 1
+		    1 0 0 0
+		    0 1 0 0
+		    0 0 0 1]; % 4->e
+else
+  transprob{2}(:,2,:) = [0 0 0 1
+		    1 0 0 0
+		    0 0 1 0 % 3->e
+		    0 0 1 0];
+end
+
+%termprob{2} = 'rightstop';
+termprob{2} = zeros(2,4,2);
+pfin = 0.8;
+termprob{2}(1,:,2) = [0 0 0 pfin]; % finish in state 4 (DU)
+termprob{2}(1,:,1) = 1 - [0 0 0 pfin];
+if topright
+  termprob{2}(2,:,2) = [0 0 0 pfin];
+  termprob{2}(2,:,1) = 1 - [0 0 0 pfin];
+else
+  termprob{2}(2,:,2) = [0 0 pfin 0];  % finish in state 3 (RL)
+  termprob{2}(2,:,1) = 1 - [0 0 pfin 0];
+end
+
+% LEVEL 3
+
+startprob{3} = 'leftstart';
+transprob{3}  = 'leftright';
+termprob{3} = 'rightstop';
+
+
+% OBS LEVEl
+
+if discrete_obs
+  chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+  L=find(chars=='L'); l=find(chars=='l');
+  U=find(chars=='U'); u=find(chars=='u');
+  R=find(chars=='R'); r=find(chars=='r');
+  D=find(chars=='D'); d=find(chars=='d');
+  Osize = length(chars);
+  
+  obsprob = zeros([4 2 Osize]);
+  %       Q2 Q3 O
+  obsprob(1, 1, L) =  1.0;
+  obsprob(1, 2, l) =  1.0;
+  obsprob(2, 1, U) =  1.0;
+  obsprob(2, 2, u) =  1.0;
+  obsprob(3, 1, R) =  1.0;
+  obsprob(3, 2, r) =  1.0;
+  obsprob(4, 1, D) =  1.0;
+  obsprob(4, 2, d) =  1.0;
+  
+  Oargs = {'CPT', obsprob};
+else
+  Osize = 2;
+  mu = zeros(2, 4, 2);
+  noise = 0;
+  scale = 10;
+  for q3=1:2
+    mu(:, 1, q3) = scale*[1;0] + noise*rand(2,1);
+  end
+  for q3=1:2
+    mu(:, 2, q3) = scale*[0;-1] + noise*rand(2,1);
+  end
+  for q3=1:2
+    mu(:, 3, q3) = scale*[-1;0] + noise*rand(2,1);
+  end
+  for q3=1:2
+    mu(:, 4, q3) = scale*[0;1] + noise*rand(2,1);
+  end
+  Sigma = repmat(reshape(0.01*eye(2), [2 2 1 1 ]), [1 1 4 2]);
+  Oargs = {'mean', mu, 'cov', Sigma};
+end
+
+bnet = mk_hhmm('Qsizes', Qsizes, 'Osize', Osize', 'discrete_obs', discrete_obs, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(2:3), ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
+if discrete_obs
+  Tmax = 30;
+else
+  Tmax = 200;
+end
+usecell = ~discrete_obs;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+
+for seqi=1:3
+  evidence = sample_dbn(bnet, Tmax, usecell, 'stop_sampling_F2');      
+  T = size(evidence, 2)
+  if discrete_obs
+    pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, Onode, chars);
+  else
+    pos = zeros(2,T+1);
+    delta = cell2num(evidence(Onode,:));
+    clf
+    hold on
+    cols = {'r', 'g', 'k', 'b'};
+    boundary = cell2num(evidence(F3,:))-1;
+    coli = 1;
+    for t=2:T+1
+      pos(:,t) = pos(:,t-1) + delta(:,t-1);
+      plot(pos(1,t), pos(2,t), sprintf('%c.', cols{coli}));
+      if boundary(t-1)
+	coli = coli + 1;
+	coli = mod(coli-1, length(cols)) + 1;
+      end
+    end
+    %plot(pos(1,:), pos(2,:), '.')
+    %pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, Onode, []);
+    pause
+  end
+end
+
+eclass = bnet.equiv_class;
+S=struct(bnet.CPD{eclass(Q2,2)});
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/get_square_data.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/get_square_data.m
new file mode 100644
index 00000000..9790221c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/get_square_data.m
@@ -0,0 +1,70 @@
+% Let the user draw a square with the mouse,
+% and then click on the corners to do a manual segmentation
+
+ss = 6;
+Q1 = 1; Q2 = 2; Q3 = 3; obsvel = 6;
+CLOCKWISE = 1; ANTICLOCK = 2;
+LR = 1; UD = 2; RL = 3; DU = 4;
+
+% repeat this block manually incrementing the sequence number
+% and setting ori.
+% (since I don't know how to call getmouse as a call-return function).
+seq = 4;
+%ori = CLOCKWISE
+ori = ANTICLOCK;
+clear xpos ypos
+getmouse
+% end block
+
+% manual segmentation with the mouse
+startseg(1) = 1;
+for i=2:4
+  fprintf('click on start of segment %d\n', i);
+  [x,y] = ginput(1);
+  plot(x,y,'ro')
+  d = dist2([xpos; ypos]', [x y]);
+  startseg(i) = argmin(d);
+end
+
+% plot corners in green 
+%ti = first point in (i+1)st segment
+t1 = startseg(1); t2 = startseg(2); t3 = startseg(3); t4 = startseg(4); 
+plot(xpos(t2), ypos(t2), 'g*')
+plot(xpos(t3), ypos(t3), 'g*')
+plot(xpos(t4), ypos(t4), 'g*')
+
+
+xvel = xpos(2:end) - xpos(1:end-1);
+yvel = ypos(2:end) - ypos(1:end-1);
+speed = [xvel(:)'; yvel(:)'];
+pos_data{seq} = [xpos(:)'; ypos(:)'];
+vel_data{seq} = [xvel(:)'; yvel(:)'];
+T = length(xvel);
+Q1label{seq} = num2cell(repmat(ori, 1, T));
+Q2label{seq} = zeros(1, T);
+if ori == CLOCKWISE
+  Q2label{seq}(t1:t2) = LR;
+  Q2label{seq}(t2+1:t3) = UD;
+  Q2label{seq}(t3+1:t4) = RL;
+  Q2label{seq}(t4+1:T) = DU;
+else
+  Q2label{seq}(t1:t2) = RL;
+  Q2label{seq}(t2+1:t3) = UD;
+  Q2label{seq}(t3+1:t4) = LR;
+  Q2label{seq}(t4+1:T) = DU;
+end
+
+% pos_data{seq}(:,t), vel_data{seq}(:,t) Q1label{seq}(t) Q2label{seq}(t)
+save 'square4' pos_data vel_data Q1label Q2label
+
+nseq = 4;
+cases = cell(1,nseq);
+for seq=1:nseq
+  T = size(vel_data{seq},2);
+  ev = cell(ss,T);
+  ev(obsvel,:) = num2cell(vel_data{seq},1);
+  ev(Q1,:) = Q1label{seq};
+  ev(Q2,:) = num2cell(Q2label{seq});
+  cases{seq} = ev;
+end
+save 'square4_cases' cases 
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/hhmm_inference.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/hhmm_inference.m
new file mode 100644
index 00000000..c3bc8441
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/hhmm_inference.m
@@ -0,0 +1,13 @@
+bnet = mk_square_hhmm(1, 1);
+
+engine = {};
+engine{end+1} = hmm_inf_engine(bnet);
+engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet));
+
+exact = 1:length(engine);
+filter = 0;
+single = 0;
+maximize = 0;
+T = 4;
+
+[err, inf_time, engine] = cmp_inference(bnet, engine, exact, T, filter, single, maximize);
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/is_F2_true_D3.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/is_F2_true_D3.m
new file mode 100644
index 00000000..38d0b6e8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/is_F2_true_D3.m
@@ -0,0 +1,12 @@
+function stop = is_F2_true_D3(vals)
+% function stop = is_F2_true_D3(vals)
+% 
+% If vals(F2)=2 then level 2 has finished, so we return stop=1
+% to stop sample_dbn. Otherwise we return stop=0.
+% We assume this is for a D=3 level HHMM.
+
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+stop = 0;
+if (iscell(vals) & vals{F2}==2) | (~iscell(vals) & vals(F2)==2)
+  stop = 1;
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_cts.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_cts.m
new file mode 100644
index 00000000..77bdaec3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_cts.m
@@ -0,0 +1,152 @@
+% Try to learn a 3 level HHMM similar to mk_square_hhmm
+% from hand-drawn squares.
+
+% Because startprob should be shared for t=1:T,
+% but in the DBN is shared for t=2:T, we train using a single long sequence.
+
+discrete_obs = 0;
+supervised = 1;
+obs_finalF2 = 0;
+% It is not possible to observe F2 if we learn
+% because the update_ess method for hhmmF_CPD and hhmmQ_CPD assume
+% the F nodes are always hidden (for speed).
+% However, for generating, we might want to set the final F2=true
+% to force all subroutines to finish.
+
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+bnet = mk_square_hhmm(discrete_obs, 0);
+ 
+ss = 6;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+Qsizes = [2 4 1];
+  
+if supervised
+  bnet.observed = [Q1 Q2 Onode];
+else
+  bnet.observed = [Onode];
+end
+
+if obs_finalF2
+  engine = jtree_dbn_inf_engine(bnet);
+  % can't use ndx version because sometimes F2 is hidden, sometimes observed
+  error('can''t observe F when learning')
+else
+  if supervised
+    engine = jtree_ndx_dbn_inf_engine(bnet);
+  else
+    engine = jtree_hmm_inf_engine(bnet);
+  end
+end
+
+load 'square4_cases' % cases{seq}{i,t} for i=1:ss 
+%plot_square_hhmm(cases{1})
+%long_seq = cat(2, cases{:});
+train_cases = cases(1:2);
+long_seq = cat(2, train_cases{:});
+if ~supervised
+  T = size(long_seq,2);
+  for t=1:T
+    long_seq{Q1,t} = [];
+    long_seq{Q2,t} = [];
+  end
+end
+[bnet2, LL, engine2] = learn_params_dbn_em(engine, {long_seq}, 'max_iter', 2);
+
+eclass = bnet2.equiv_class;
+CPDO=struct(bnet2.CPD{eclass(Onode,1)});
+mu = CPDO.mean;
+Sigma = CPDO.cov;
+CPDO_full = CPDO;
+
+% force diagonal covs after training
+for k=1:size(Sigma,3)
+  Sigma(:,:,k) = diag(diag(Sigma(:,:,k)));
+end
+bnet2.CPD{6} = set_fields(bnet.CPD{6}, 'cov', Sigma);
+
+if 0
+  % visualize each model by concatenating means for each model for nsteps in a row
+  nsteps = 5;
+  ev = cell(ss, nsteps*prod(Qsizes(2:3)));
+  t = 1;
+  for q2=1:Qsizes(2)
+    for q3=1:Qsizes(3)
+      for i=1:nsteps
+	ev{Onode,t} = mu(:,q2,q3);
+	ev{Q2,t} = q2;
+	t = t + 1;
+      end
+    end
+  end
+  plot_square_hhmm(ev)      
+end
+
+% bnet3 is the same as the learned model, except we will use it in testing mode
+if supervised
+  bnet3 = bnet2;
+  bnet3.observed = [Onode];
+  engine3 = hmm_inf_engine(bnet3);
+  %engine3 = jtree_ndx_dbn_inf_engine(bnet3);
+else
+  bnet3 = bnet2;
+  engine3 = engine2;
+end
+
+if 0
+  % segment whole sequence
+  mpe = calc_mpe_dbn(engine3, long_seq);
+  pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, []);
+end
+
+% segment each sequence
+test_cases = cases(3:4);
+for i=1:2
+  ev = test_cases{i};
+  T = size(ev, 2);
+  for t=1:T
+    ev{Q1,t} = [];
+    ev{Q2,t} = [];
+  end
+  %mpe = calc_mpe_dbn(engine3, ev);
+  mpe = find_mpe(engine3, ev)
+  subplot(1,2,i)
+  plot_square_hhmm(mpe)      
+  %pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, []);
+  q1s = cell2num(mpe(Q1,:));
+  h = hist(q1s, 1:Qsizes(1));
+  map_q1 = argmax(h);
+  str = sprintf('test seq %d is of type %d\n', i, map_q1);
+  title(str)
+end
+
+
+if 0
+% Estimate gotten by couting transitions in the labelled data
+% Note that a self transition shouldnt count if F2=off.
+Q2ev = cell2num(ev(Q2,:));
+Q2a = Q2ev(1:end-1);
+Q2b = Q2ev(2:end);
+counts = compute_counts([Q2a; Q2b], [4 4]);
+end
+
+eclass = bnet2.equiv_class;
+CPDQ1=struct(bnet2.CPD{eclass(Q1,2)});
+CPDQ2=struct(bnet2.CPD{eclass(Q2,2)});
+CPDQ3=struct(bnet2.CPD{eclass(Q3,2)});
+CPDF2=struct(bnet2.CPD{eclass(F2,1)});
+CPDF3=struct(bnet2.CPD{eclass(F3,1)});
+
+
+A=add_hhmm_end_state(CPDQ2.transprob, CPDF2.termprob(:,:,2));
+squeeze(A(:,1,:));
+CPDQ2.startprob;
+ 
+if 0
+S=struct(CPDF2.sub_CPD_term);
+S.nsamples
+reshape(S.counts, [2 4 2])
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_discrete.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_discrete.m
new file mode 100644
index 00000000..3110ae5e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/learn_square_hhmm_discrete.m
@@ -0,0 +1,171 @@
+% Try to learn a 3 level HHMM similar to mk_square_hhmm
+% from synthetic discrete sequences
+
+
+discrete_obs = 1;
+supervised = 0;
+obs_finalF2 = 0;
+
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+bnet_init = mk_square_hhmm(discrete_obs, 0);
+
+ss = 6;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+
+if supervised
+  bnet_init.observed = [Q1 Q2 Onode];
+else
+  bnet_init.observed = [Onode];
+end
+
+if obs_finalF2
+  engine_init = jtree_dbn_inf_engine(bnet_init);
+  % can't use ndx version because sometimes F2 is hidden, sometimes observed
+  error('can''t observe F when learning')
+  % It is not possible to observe F2 if we learn
+  % because the update_ess method for hhmmF_CPD and hhmmQ_CPD assume
+  % the F nodes are always hidden (for speed).
+  % However, for generating, we might want to set the final F2=true
+  % to force all subroutines to finish.
+else
+  if supervised
+    engine_init = jtree_ndx_dbn_inf_engine(bnet_init);
+  else
+    engine_init = hmm_inf_engine(bnet_init);
+  end
+end
+  
+% generate some synthetic data (easier to debug)
+chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+L=find(chars=='L'); l=find(chars=='l');
+U=find(chars=='U'); u=find(chars=='u');
+R=find(chars=='R'); r=find(chars=='r');
+D=find(chars=='D'); d=find(chars=='d');
+
+cases = {};
+
+T = 8;
+ev = cell(ss, T);
+ev(Onode,:) = num2cell([L l U u R r D d]);
+if supervised
+  ev(Q1,:) = num2cell(1*ones(1,T));
+  ev(Q2,:) = num2cell( [1 1 2 2 3 3 4 4]);
+end
+cases{1} = ev;
+cases{3} = ev;
+
+T  = 8;
+ev = cell(ss, T);
+%we start with R then r, even though we are running the model 'backwards'!
+ev(Onode,:) = num2cell([R r U u L l D d]);
+
+if supervised
+  ev(Q1,:) = num2cell(2*ones(1,T));
+  ev(Q2,:) = num2cell( [3 3 2 2 1 1 4 4]);
+end
+
+cases{2} = ev;
+cases{4} = ev;
+
+if obs_finalF2
+  for i=1:length(cases)
+    T = size(cases{i},2);
+    cases{i}(F2,T)={2}; % force F2 to be finished at end of seq
+  end
+end
+
+
+% startprob should be shared for t=1:T,
+% but in the DBN it is shared for t=2:T,
+% so we train using a single long sequence.
+long_seq = cat(2, cases{:});
+[bnet_learned, LL, engine_learned] = ...
+    learn_params_dbn_em(engine_init, {long_seq}, 'max_iter', 200);
+
+% figure out which subsequence each model is responsible for
+mpe = calc_mpe_dbn(engine_learned, long_seq);
+pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, chars);
+
+
+% The "true" segmentation of the training sequence  is
+% Q1: 1                 2
+% O:  L l U u R r D d | R r U u L l D d | etc.
+% 
+% When we learn in a supervised fashion, we recover the "truth".
+
+% When we learn in an unsupervised fashion with seed=1, we get
+% Q1: 2                       1
+% O:  L l U u R r D d  R r | U u L l D d | etc.
+%
+% This means for model 1:
+% starts in state 2
+% transitions 2->1, 1->4, 4->e, 3->2
+%
+% For model 2,
+% starts in state 1
+% transitions 1->2, 2->3, 3->4 or e, 4->3
+
+% examine the params
+eclass = bnet_learned.equiv_class;
+CPDQ1=struct(bnet_learned.CPD{eclass(Q1,2)});
+CPDQ2=struct(bnet_learned.CPD{eclass(Q2,2)});
+CPDQ3=struct(bnet_learned.CPD{eclass(Q3,2)});
+CPDF2=struct(bnet_learned.CPD{eclass(F2,1)});
+CPDF3=struct(bnet_learned.CPD{eclass(F3,1)});
+CPDO=struct(bnet_learned.CPD{eclass(Onode,1)});
+
+A_learned =add_hhmm_end_state(CPDQ2.transprob, CPDF2.termprob(:,:,2));
+squeeze(A_learned(:,1,:))
+squeeze(A_learned(:,2,:))
+
+
+% Does the "true" model have higher likelihood than the learned one?
+% i.e., Does the unsupervised method learn the wrong model because
+% we have the wrong cost fn, or because of local minima?
+
+bnet_true = mk_square_hhmm(discrete_obs,1);
+
+% examine the params
+eclass = bnet_learned.equiv_class;
+CPDQ1_true=struct(bnet_true.CPD{eclass(Q1,2)});
+CPDQ2_true=struct(bnet_true.CPD{eclass(Q2,2)});
+CPDQ3_true=struct(bnet_true.CPD{eclass(Q3,2)});
+CPDF2_true=struct(bnet_true.CPD{eclass(F2,1)});
+CPDF3_true=struct(bnet_true.CPD{eclass(F3,1)});
+
+A_true =add_hhmm_end_state(CPDQ2_true.transprob, CPDF2_true.termprob(:,:,2));
+squeeze(A_true(:,1,:))
+
+
+if supervised
+  engine_true = jtree_ndx_dbn_inf_engine(bnet_true);
+else
+  engine_true = hmm_inf_engine(bnet_true);
+end
+
+%[engine_learned, ll_learned] = enter_evidence(engine_learned, long_seq);
+%[engine_true, ll_true] = enter_evidence(engine_true, long_seq);
+[engine_learned, ll_learned] = enter_evidence(engine_learned, cases{2});
+[engine_true, ll_true] = enter_evidence(engine_true, cases{2});
+ll_learned
+ll_true
+
+
+% remove concatentation artefacts
+ll_learned = 0;
+ll_true = 0;
+for m=1:length(cases)
+  [engine_learned, ll_learned_tmp] = enter_evidence(engine_learned, cases{m});
+  [engine_true, ll_true_tmp] = enter_evidence(engine_true, cases{m});
+  ll_learned = ll_learned + ll_learned_tmp;
+  ll_true = ll_true + ll_true_tmp;
+end
+ll_learned
+ll_true
+
+% In both cases, ll_learned >> ll_true
+% which shows we are using the wrong cost function!
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/mk_square_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/mk_square_hhmm.m
new file mode 100644
index 00000000..41cfc539
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/mk_square_hhmm.m
@@ -0,0 +1,180 @@
+function bnet = mk_square_hhmm(discrete_obs, true_params, topright)
+
+% Make a 3 level  HHMM described by the following grammar
+%
+% Square -> CLK | CCK % clockwise or counterclockwise
+% CLK -> LR UD RL DU start on top left (1 2 3 4)
+% CCK -> RL UD LR DU  if start at top right (3 2 1 4)
+% CCK -> UD LR DU RL if start at top left (2 1 4 3)
+%
+% LR = left-right, UD = up-down, RL = right-left, DU = down-up
+% LR, UD, RL, DU are sub HMMs.
+%
+% For discrete observations, the subHMMs are 2-state left-right.
+% LR emits L then l, etc.
+%
+% For cts observations, the subHMMs are 1 state.
+% LR emits a vector in the -> direction, with a little noise.
+% Since there is no constraint that we remain in the LR state as long as the RL state,
+% the sides of the square might have different lengths,
+% so the result is not really a square!
+%
+% If true_params = 0, we use random parameters at the top 2 levels
+% (ready for learning). At the bottom level, we use noisy versions
+% of the "true" observations.
+%
+% If topright=1, counter-clockwise starts at top right, not top left
+% This example was inspired by Ivanov and Bobick.
+
+if nargin < 3, topright = 1; end
+
+if 1 % discrete_obs
+  Qsizes = [2 4 2];
+else
+  Qsizes = [2 4 1];
+end
+
+D = 3;
+Qnodes = 1:D;
+startprob = cell(1,D);
+transprob = cell(1,D);
+termprob = cell(1,D);
+
+% LEVEL 1
+
+startprob{1} = 'unif';
+transprob{1} = 'unif';
+
+% LEVEL 2
+
+if true_params
+  startprob{2} = zeros(2, 4);
+  startprob{2}(1, :) = [1 0 0 0];
+  if topright
+    startprob{2}(2, :) = [0 0 1 0];
+  else
+    startprob{2}(2, :) = [0 1 0 0];
+  end
+  
+  transprob{2} = zeros(4, 2, 4);
+  
+  transprob{2}(:,1,:) = [0 1 0 0
+		    0 0 1 0
+		    0 0 0 1
+		    0 0 0 1]; % 4->e
+  if topright
+    transprob{2}(:,2,:) = [0 0 0 1
+		    1 0 0 0
+		    0 1 0 0
+		    0 0 0 1]; % 4->e
+  else
+    transprob{2}(:,2,:) = [0 0 0 1
+		    1 0 0 0
+		    0 0 1 0 % 3->e
+		    0 0 1 0];
+  end
+  
+  %termprob{2} = 'rightstop';
+  termprob{2} = zeros(2,4);
+  pfin = 0.8;
+  termprob{2}(1,:) = [0 0 0 pfin]; % finish in state 4 (DU)
+  if topright
+    termprob{2}(2,:) = [0 0 0 pfin];
+  else
+    termprob{2}(2,:) = [0 0 pfin 0];  % finish in state 3 (RL)
+  end
+else
+  % In the unsupervised case, it is essential that we break symmetry
+  % in the initial param estimates.
+  %startprob{2} = 'unif';
+  %transprob{2} = 'unif';
+  %termprob{2} = 'unif';
+  startprob{2} = 'rnd';
+  transprob{2} = 'rnd';
+  termprob{2} = 'rnd';
+end
+
+% LEVEL 3
+
+if 1 |  true_params
+  startprob{3} = 'leftstart';
+  transprob{3}  = 'leftright';
+  termprob{3} = 'rightstop';
+else
+  % If we want to be able to run a base-level model backwards...
+  startprob{3} = 'rnd';
+  transprob{3}  = 'rnd';
+  termprob{3} = 'rnd';
+end
+ 
+
+% OBS LEVEl
+
+if discrete_obs
+  % Initialise observations of lowest level primitives in a way which we can interpret
+  chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+  L=find(chars=='L'); l=find(chars=='l');
+  U=find(chars=='U'); u=find(chars=='u');
+  R=find(chars=='R'); r=find(chars=='r');
+  D=find(chars=='D'); d=find(chars=='d');
+  Osize = length(chars);
+  
+  if true_params
+    p = 1; % makes each state fully observed
+  else
+    p = 0.9;
+  end
+  
+  obsprob = (1-p)*ones([4 2 Osize]);
+  %       Q2 Q3 O
+  obsprob(1, 1, L) =  p;
+  obsprob(1, 2, l) =  p;
+  obsprob(2, 1, U) =  p;
+  obsprob(2, 2, u) =  p;
+  obsprob(3, 1, R) =  p;
+  obsprob(3, 2, r) =  p;
+  obsprob(4, 1, D) =  p;
+  obsprob(4, 2, d) =  p;
+  obsprob = mk_stochastic(obsprob);
+  Oargs = {'CPT', obsprob};
+else
+  % Initialise means of lowest level primitives in a way which we can interpret
+  % These means are little vectors in the east, south, west, north directions.
+  % (left-right=east, up-down=south, right-left=west, down-up=north)
+  Osize = 2;
+  mu = zeros(2, Qsizes(2), Qsizes(3));
+  scale = 3;
+  if true_params
+    noise = 0;
+  else
+    noise = 0.5*scale;
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 1, q3) = scale*[1;0] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 2, q3) = scale*[0;-1] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 3, q3) = scale*[-1;0] + noise*rand(2,1);
+  end
+  for q3=1:Qsizes(3)
+    mu(:, 4, q3) = scale*[0;1] + noise*rand(2,1);
+  end
+  Sigma = repmat(reshape(scale*eye(2), [2 2 1 1 ]), [1 1 Qsizes(2) Qsizes(3)]);
+  Oargs = {'mean', mu, 'cov', Sigma, 'cov_type', 'diag'};
+end
+
+if discrete_obs
+  selfprob = 0.5;
+else
+  selfprob = 0.95;
+  % If less than this, it won't look like a square
+  % because it doesn't spend enough time in each state
+  % Unfortunately, the variance on durations (lengths of each side)
+  % is very large
+end
+bnet = mk_hhmm('Qsizes', Qsizes, 'Osize', Osize', 'discrete_obs', discrete_obs, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(2:3), 'selfprob', selfprob, ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/plot_square_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/plot_square_hhmm.m
new file mode 100644
index 00000000..e61e5669
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/plot_square_hhmm.m
@@ -0,0 +1,27 @@
+function plot_square_hhmm(ev)
+% Plot the square shape implicit in the evidence.
+% ev{i,t} is the value of node i in slice t.
+% The observed node contains a velocity (delta increment), which is converted
+% into a position.
+% The Q2 node specifies which model is used, and hence which color
+% to use: 1=red, 2=green, 3=blue, 4=black.
+
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+
+delta = cell2num(ev(Onode,:)); % delta(:,t)
+Q2label = cell2num(ev(Q2,:)); 
+
+T = size(delta, 2);
+pos = zeros(2,T+1);
+hold on
+cols = {'r', 'g', 'b', 'k'};
+for t=2:T+1
+  pos(:,t) = pos(:,t-1) + delta(:,t-1);
+  plot(pos(1,t), pos(2,t), sprintf('%c.', cols{Q2label(t-1)}));
+  if (t==2)
+    text(pos(1,t-1),pos(2,t-1),sprintf('%d',t))
+  elseif (mod(t,20)==0)
+    text(pos(1,t),pos(2,t),sprintf('%d',t))
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_cts.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_cts.m
new file mode 100644
index 00000000..3ab2abb5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_cts.m
@@ -0,0 +1,20 @@
+% Generate samples from the HHMM with the true params.
+
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+discrete_obs = 0;
+
+bnet = mk_square_hhmm(discrete_obs, 1);
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+
+for seqi=1:1
+  evidence = sample_dbn(bnet, 'stop_test', 'is_F2_true_D3');      
+  clf
+  plot_square_hhmm(evidence);
+  %pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, Onode, []);
+  fprintf('sequence %d has length %d; press key to continue\n', seqi, size(evidence,2))
+  pause
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_discrete.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_discrete.m
new file mode 100644
index 00000000..20279899
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/sample_square_hhmm_discrete.m
@@ -0,0 +1,20 @@
+% Generate samples from the HHMM with the true params.
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+discrete_obs = 1;
+
+bnet = mk_square_hhmm(discrete_obs, 1);
+
+Tmax = 30;
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+chars = ['L', 'l', 'U', 'u', 'R', 'r', 'D', 'd'];
+  
+for seqi=1:3
+  evidence = cell2num(sample_dbn(bnet, 'stop_test', 'is_F2_true_D3'));
+  T = size(evidence, 2)
+  pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, Onode, chars);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4.mat b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4.mat
new file mode 100644
index 00000000..cda0585b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4.mat
Binary files differdiff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4_cases.mat b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4_cases.mat
new file mode 100644
index 00000000..788c3239
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/square4_cases.mat
Binary files differdiff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.m
new file mode 100644
index 00000000..e983af14
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.m
@@ -0,0 +1,1310 @@
+function fig = test_square_fig()
+% This is the machine-generated representation of a Handle Graphics object
+% and its children.  Note that handle values may change when these objects
+% are re-created. This may cause problems with any callbacks written to
+% depend on the value of the handle at the time the object was saved.
+%
+% To reopen this object, just type the name of the M-file at the MATLAB
+% prompt. The M-file and its associated MAT-file must be on your path.
+
+load test_square_fig
+
+h0 = figure('Color',[0.8 0.8 0.8], ...
+	'Colormap',mat0, ...
+	'PointerShapeCData',mat1, ...
+	'Position',[540 374 476 292]);
+h1 = axes('Parent',h0, ...
+	'CameraUpVector',[0 1 0], ...
+	'Color',[1 1 1], ...
+	'ColorOrder',mat2, ...
+	'NextPlot','add', ...
+	'Position',[0.13 0.11 0.3270231213872832 0.8149999999999998], ...
+	'XColor',[0 0 0], ...
+	'XLim',[-10 50], ...
+	'XLimMode','manual', ...
+	'YColor',[0 0 0], ...
+	'YLim',[-60 10], ...
+	'YLimMode','manual', ...
+	'ZColor',[0 0 0]);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',0.4608294930875587, ...
+	'YData',0.2923976608187218);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'String','2');
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',1.152073732718893, ...
+	'YData',0.2923976608187218);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',2.995391705069125, ...
+	'YData',0.8771929824561511);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',3.686635944700463, ...
+	'YData',0.8771929824561511);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',6.451612903225808, ...
+	'YData',0.8771929824561511);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',9.677419354838712, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',10.36866359447005, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',15.43778801843318, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',17.51152073732719, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',19.81566820276498, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',20.50691244239631, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',23.73271889400922, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',25.57603686635945, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',29.95391705069125, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',31.79723502304147, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',35.02304147465438, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',35.71428571428572, ...
+	'YData',2.046783625730996);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',38.47926267281106, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',40.3225806451613, ...
+	'YData',1.461988304093566);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[40.3225806451613 1.461988304093566 0], ...
+	'String','20');
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',42.62672811059908, ...
+	'YData',mat3);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',43.31797235023042, ...
+	'YData',mat4);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',43.31797235023042, ...
+	'YData',0.8771929824561511);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',43.54838709677419, ...
+	'YData',0);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',43.77880184331798, ...
+	'YData',-0.5847953216374293);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',44.47004608294931, ...
+	'YData',-2.339181286549703);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',44.93087557603687, ...
+	'YData',-4.385964912280699);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',46.7741935483871, ...
+	'YData',-9.064327485380119);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.00460829493088, ...
+	'YData',-10.81871345029239);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.69585253456221, ...
+	'YData',mat5);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.69585253456221, ...
+	'YData',-15.20467836257309);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-19.00584795321637);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-19.88304093567251);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-22.51461988304093);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-23.09941520467836);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-26.02339181286549);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-26.31578947368421);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-27.77777777777777);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-28.3625730994152);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.23502304147466, ...
+	'YData',-30.99415204678362);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[47.23502304147466 -30.99415204678362 0], ...
+	'String','40');
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.46543778801843, ...
+	'YData',-31.57894736842105);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.46543778801843, ...
+	'YData',-33.62573099415204);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.46543778801843, ...
+	'YData',-34.50292397660818);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.46543778801843, ...
+	'YData',-37.42690058479531);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.46543778801843, ...
+	'YData',-38.01169590643274);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.00460829493088, ...
+	'YData',-42.39766081871344);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.00460829493088, ...
+	'YData',-42.98245614035087);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',47.00460829493088, ...
+	'YData',-46.49122807017543);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',46.7741935483871, ...
+	'YData',-46.78362573099415);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',46.54377880184332, ...
+	'YData',-49.41520467836257);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',46.54377880184332, ...
+	'YData',-49.70760233918128);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',45.85253456221199, ...
+	'YData',-51.46198830409356);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',45.85253456221199, ...
+	'YData',-51.75438596491227);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',44.93087557603687, ...
+	'YData',-53.21637426900584);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',44.70046082949308, ...
+	'YData',-53.21637426900584);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',44.00921658986175, ...
+	'YData',-54.09356725146198);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',43.77880184331798, ...
+	'YData',-54.38596491228069);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',41.93548387096774, ...
+	'YData',-54.97076023391811);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',41.47465437788019, ...
+	'YData',-55.26315789473683);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',39.1705069124424, ...
+	'YData',-55.55555555555554);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[39.1705069124424 -55.55555555555554 0], ...
+	'String','60');
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',38.94009216589862, ...
+	'YData',-55.84795321637426);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',36.63594470046083, ...
+	'YData',-55.55555555555554);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',36.17511520737327, ...
+	'YData',-55.55555555555554);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',32.94930875576037, ...
+	'YData',-54.97076023391811);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',32.48847926267281, ...
+	'YData',-54.97076023391811);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',28.11059907834102, ...
+	'YData',-53.80116959064326);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',27.64976958525346, ...
+	'YData',-53.50877192982455);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',23.963133640553, ...
+	'YData',-53.50877192982455);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',23.27188940092166, ...
+	'YData',-53.50877192982455);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',19.5852534562212, ...
+	'YData',-54.97076023391811);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',19.12442396313364, ...
+	'YData',-54.97076023391811);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',mat6, ...
+	'YData',-56.14035087719297);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',mat7, ...
+	'YData',-56.14035087719297);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',9.907834101382491, ...
+	'YData',-57.30994152046782);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',9.447004608294932, ...
+	'YData',-57.30994152046782);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',6.221198156682029, ...
+	'YData',-57.30994152046782);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',4.838709677419356, ...
+	'YData',-56.7251461988304);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',2.764976958525345, ...
+	'YData',-56.14035087719297);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',2.534562211981569, ...
+	'YData',-56.14035087719297);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',0.9216589861751174, ...
+	'YData',-53.80116959064327);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[0.9216589861751174 -53.80116959064327 0], ...
+	'String','80');
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',0.6912442396313381, ...
+	'YData',-53.21637426900584);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.152073732718893, ...
+	'YData',-48.24561403508771);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.152073732718893, ...
+	'YData',-47.953216374269);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.843317972350228, ...
+	'YData',-44.73684210526315);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.843317972350228, ...
+	'YData',-44.44444444444444);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-2.304147465437787, ...
+	'YData',-39.76608187134502);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-2.764976958525345, ...
+	'YData',-38.01169590643274);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-3.225806451612904, ...
+	'YData',-30.99415204678362);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-3.225806451612904, ...
+	'YData',-29.82456140350877);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-3.225806451612904, ...
+	'YData',-24.85380116959064);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-3.225806451612904, ...
+	'YData',-24.26900584795321);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-2.534562211981566, ...
+	'YData',-17.5438596491228);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-2.304147465437787, ...
+	'YData',-16.95906432748537);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.612903225806452, ...
+	'YData',-11.98830409356725);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.612903225806452, ...
+	'YData',-11.40350877192982);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',mat8, ...
+	'YData',-8.47953216374269);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',mat9, ...
+	'YData',-8.187134502923968);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.152073732718893, ...
+	'YData',-5.263157894736835);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-1.152073732718893, ...
+	'YData',-4.970760233918128);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.9216589861751139, ...
+	'YData',-2.923976608187132);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[-0.9216589861751139 -2.923976608187132 0], ...
+	'String','100');
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.9216589861751139, ...
+	'YData',-2.631578947368411);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.6912442396313345, ...
+	'YData',mat10);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.6912442396313345, ...
+	'YData',-0.8771929824561369);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.6912442396313345, ...
+	'YData',-0.5847953216374293);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'HandleVisibility','off', ...
+	'HorizontalAlignment','center', ...
+	'Position',[19.80645161290322 12.0675105485232 17.32050807568877], ...
+	'VerticalAlignment','bottom');
+set(get(h2,'Parent'),'Title',h2);
+h1 = axes('Parent',h0, ...
+	'CameraUpVector',[0 1 0], ...
+	'Color',[1 1 1], ...
+	'ColorOrder',mat11, ...
+	'NextPlot','add', ...
+	'Position',[0.5779768786127169 0.11 0.3270231213872832 0.8149999999999998], ...
+	'XColor',[0 0 0], ...
+	'YColor',[0 0 0], ...
+	'ZColor',[0 0 0]);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.4608294930875587, ...
+	'YData',0);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'String','2');
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-2.764976958525345, ...
+	'YData',-0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-3.456221198156683, ...
+	'YData',-0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-7.834101382488477, ...
+	'YData',-0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-11.52073732718894, ...
+	'YData',-0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',mat12, ...
+	'YData',-0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-19.35483870967742, ...
+	'YData',0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-23.50230414746544, ...
+	'YData',0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-24.88479262672811, ...
+	'YData',0.8771929824561369);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-28.11059907834102, ...
+	'YData',0.8771929824561369);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-29.49308755760369, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-31.10599078341014, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-32.02764976958525, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-33.17972350230414, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-33.6405529953917, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 1], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-34.7926267281106, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-35.02304147465438, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-35.48387096774194, ...
+	'YData',1.461988304093566);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-35.71428571428572, ...
+	'YData',1.461988304093566);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[-35.71428571428572 1.461988304093566 0], ...
+	'String','20');
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.17511520737327, ...
+	'YData',mat13);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',0.8771929824561369);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.63594470046083, ...
+	'YData',0.2923976608187076);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.63594470046083, ...
+	'YData',0);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.63594470046083, ...
+	'YData',mat14);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',-2.339181286549703);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',-2.631578947368425);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',-4.67836257309942);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',-5.555555555555557);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',-8.187134502923982);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.40552995391705, ...
+	'YData',-8.771929824561397);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.86635944700461, ...
+	'YData',-13.15789473684211);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',mat15);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-16.08187134502924);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-17.54385964912281);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-18.12865497076023);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-19.88304093567251);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-20.17543859649123);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-21.92982456140351);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-22.22222222222222);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[-37.09677419354839 -22.22222222222222 0], ...
+	'String','40');
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-23.09941520467836);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.09677419354839, ...
+	'YData',-23.39181286549707);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-25.14619883040935);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-25.43859649122807);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-28.3625730994152);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.55760368663595, ...
+	'YData',-28.94736842105263);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-31.87134502923976);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-32.16374269005848);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-34.7953216374269);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-35.38011695906432);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-38.88888888888889);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-39.76608187134503);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-43.27485380116958);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-43.5672514619883);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.78801843317973, ...
+	'YData',-44.44444444444444);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.55760368663595, ...
+	'YData',-45.32163742690058);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.55760368663595, ...
+	'YData',-45.61403508771929);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-47.36842105263158);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-37.32718894009217, ...
+	'YData',-47.95321637426901);
+h2 = line('Parent',h1, ...
+	'Color',[0 1 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.86635944700461, ...
+	'YData',-49.70760233918129);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[-36.86635944700461 -49.70760233918129 0], ...
+	'String','60');
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-36.86635944700461, ...
+	'YData',-50);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-35.71428571428572, ...
+	'YData',-50.29239766081872);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-35.25345622119816, ...
+	'YData',-50.29239766081872);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-32.02764976958527, ...
+	'YData',-50.29239766081872);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-31.33640552995393, ...
+	'YData',-50.29239766081872);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-27.88018433179725, ...
+	'YData',-50.58479532163743);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-27.41935483870969, ...
+	'YData',-50.58479532163743);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-18.20276497695854, ...
+	'YData',-50.58479532163743);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-16.82027649769586, ...
+	'YData',-51.16959064327486);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-12.21198156682029, ...
+	'YData',-50.58479532163743);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-11.52073732718895, ...
+	'YData',-50.58479532163743);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-6.912442396313377, ...
+	'YData',-51.16959064327486);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-5.069124423963142, ...
+	'YData',-51.75438596491229);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',mat16, ...
+	'YData',-52.046783625731);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',-0.9216589861751281, ...
+	'YData',-52.33918128654972);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',0.2304147465437687, ...
+	'YData',-52.33918128654972);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',0.4608294930875481, ...
+	'YData',-52.33918128654972);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',2.304147465437776, ...
+	'YData',-52.63157894736843);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',2.534562211981548, ...
+	'YData',-52.63157894736843);
+h2 = line('Parent',h1, ...
+	'Color',[1 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',3.917050691244224, ...
+	'YData',-52.63157894736843);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[3.917050691244224 -52.63157894736843 0], ...
+	'String','80');
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',4.147465437788011, ...
+	'YData',-52.63157894736843);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',4.147465437788011, ...
+	'YData',-52.33918128654972);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.529953917050673, ...
+	'YData',-46.19883040935674);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.990783410138231, ...
+	'YData',-44.44444444444446);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',7.834101382488466, ...
+	'YData',-28.0701754385965);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',8.294930875576025, ...
+	'YData',-22.80701754385966);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',8.755760368663584, ...
+	'YData',mat17);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',8.525345622119797, ...
+	'YData',-14.9122807017544);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',7.373271889400908, ...
+	'YData',-10.23391812865498);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',7.142857142857135, ...
+	'YData',-9.94152046783627);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',6.221198156682018, ...
+	'YData',-7.602339181286567);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',6.221198156682018, ...
+	'YData',-7.309941520467845);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.760368663594459, ...
+	'YData',-5.555555555555571);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.529953917050673, ...
+	'YData',-5.555555555555571);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.2995391705069, ...
+	'YData',-4.093567251462005);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.069124423963128, ...
+	'YData',-2.631578947368439);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.069124423963128, ...
+	'YData',-2.339181286549717);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.069124423963128, ...
+	'YData',mat18);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',5.069124423963128, ...
+	'YData',-1.169590643274873);
+h2 = line('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'LineStyle','none', ...
+	'Marker','.', ...
+	'XData',4.838709677419342, ...
+	'YData',-0.2923976608187218);
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'Position',[4.838709677419342 -0.2923976608187218 0], ...
+	'String','100');
+h2 = text('Parent',h1, ...
+	'Color',[0 0 0], ...
+	'HandleVisibility','off', ...
+	'HorizontalAlignment','center', ...
+	'Position',[-10.38961038961038 12.0675105485232 17.32050807568877], ...
+	'VerticalAlignment','bottom');
+set(get(h2,'Parent'),'Title',h2);
+if nargout > 0, fig = h0; end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.mat b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.mat
new file mode 100644
index 00000000..5b2b5f53
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/Square/test_square_fig.mat
Binary files differdiff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/abcd_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/abcd_hhmm.m
new file mode 100644
index 00000000..13e6d39f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/abcd_hhmm.m
@@ -0,0 +1,97 @@
+% Make the HHMM in Figure 1 of the NIPS'01 paper
+
+Qsize = [2 3 2];
+Qnodes = 1:3;
+D = 3;
+transprob = cell(1,D);
+termprob = cell(1,D);
+startprob = cell(1,D);
+clear A;
+
+% transprob{d}(i,k,j), transprob{1}(i,j)
+% termprob{d}(k,j), termprob{1}(1,j)
+% startprob{d}(k,j), startprob{1}(1,j)
+
+
+% LEVEL 1
+
+%       1 2 e
+A{1} = [0 0 1;
+	0 0 1];
+[transprob{1}, termprob{1}] = remove_hhmm_end_state(A{1});
+startprob{1} = [0.5 0.5];
+
+% LEVEL 2
+A{2} = zeros(Qsize(2), Qsize(1), Qsize(2)+1);
+
+%              1 2 3 e
+A{2}(:,1,:) = [0 1 0 0  % Q1=1 => model below state 0
+	       0 0 1 0
+	       0 0 0 1];
+
+%              1 2 3 e
+A{2}(:,2,:) = [0 1 0 0 % Q1=2 => model below state 1
+	       0 0 1 0
+	       0 0 0 1];
+
+[transprob{2}, termprob{2}] = remove_hhmm_end_state(A{2});	       
+
+% always enter level 2 in state 1
+startprob{2} = [1 0 0
+		1 0 0];
+
+% LEVEL 3
+
+A{3} = zeros([Qsize(3) Qsize(2) Qsize(3)+1]);
+endstate = Qsize(3)+1;
+%    Qt-1(3) Qt(2) Qt(3)
+%                        1   2   e
+A{3}(1,      1,    endstate) = 1.0; % Q2=1 => model below state 2/5
+A{3}(:,      2,    :) = [0.0 1.0 0.0 % Q2=2 => model below state 3/6
+            	         0.5 0.0 0.5]; 
+A{3}(1,      3,    endstate) = 1.0; % Q2=3 => model below state 4/7
+
+[transprob{3}, termprob{3}] = remove_hhmm_end_state(A{3});	       
+
+startprob{3} = 'leftstart';
+
+
+
+% OBS LEVEl
+
+chars = ['a', 'b', 'c', 'd', 'x', 'y'];
+Osize = length(chars);
+
+obsprob = zeros([Qsize Osize]);
+%       1 2 3 O
+obsprob(1,1,1,find(chars == 'a')) =  1.0;
+
+obsprob(1,2,1,find(chars == 'x')) =  1.0;
+obsprob(1,2,2,find(chars == 'y')) =  1.0;
+
+obsprob(1,3,1,find(chars == 'b')) =  1.0;
+
+obsprob(2,1,1,find(chars == 'c')) =  1.0;
+
+obsprob(2,2,1,find(chars == 'x')) =  1.0;
+obsprob(2,2,2,find(chars == 'y')) =  1.0;
+
+obsprob(2,3,1,find(chars == 'd')) =  1.0;
+
+Oargs = {'CPT', obsprob};
+
+bnet = mk_hhmm('Qsizes', Qsize, 'Osize', Osize, 'discrete_obs', 1, ...
+	       'Oargs', Oargs, 'Ops', Qnodes(1:3), ...
+	       'startprob', startprob, 'transprob', transprob, 'termprob', termprob);
+
+
+Q1 = 1; Q2 = 2; Q3 = 3; F3 = 4; F2 = 5; Onode = 6;
+Qnodes = [Q1 Q2 Q3]; Fnodes = [F2 F3];
+
+for seqi=1:3
+  evidence = sample_dbn(bnet, 'stop_test', 'is_F2_true_D3');      
+  ev = cell2num(evidence);
+  chars(ev(end,:))
+  %T = size(evidence, 2)
+  %pretty_print_hhmm_parse(evidence, Qnodes, Fnodes, Onode, chars);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/add_hhmm_end_state.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/add_hhmm_end_state.m
new file mode 100644
index 00000000..84c3c653
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/add_hhmm_end_state.m
@@ -0,0 +1,34 @@
+function A = add_hhmm_end_state(transprob, termprob)
+% ADD_HMM_END_STATE Combine trans and term probs into transmat for automaton with an end state
+% function A = add_hhmm_end_state(transprob, termprob)
+%
+% A(i,k,j) = Pr( i->j | Qps=k), where i in 1:Q, j in 1:(Q+1), and Q+1 is the end state
+% This implements the equation in sec 4.6 of my tech report, where
+% transprob(i,k,j) = \tilde{A}_k(i,j), termprob(k,j) = \tau_k(j)
+%
+% For the top level, the k index is missing.
+
+Q = size(transprob,1);
+toplevel = (ndims(transprob)==2);
+if toplevel
+  Qk = 1;
+  transprob = reshape(transprob, [Q 1 Q]);
+  termprob = reshape(termprob, [1 Q]);
+else
+  Qk = size(transprob, 2);
+end
+
+A = zeros(Q, Qk, Q+1);
+A(:,:,Q+1) = termprob';
+
+for k=1:Qk
+  for i=1:Q
+    for j=1:Q
+      A(i,k,j) = transprob(i,k,j) * (1-termprob(k,i));
+    end
+  end    
+end
+
+if toplevel
+  A = squeeze(A);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/hhmm_jtree_clqs.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/hhmm_jtree_clqs.m
new file mode 100644
index 00000000..4192af11
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/hhmm_jtree_clqs.m
@@ -0,0 +1,143 @@
+% Find out how big the cliques are in an HHMM as a function of depth
+% (This is how we get the complexity bound of O(D K^{1.5D}).)
+
+if 0
+Qsize = [];
+Fsize = [];
+Nclqs = [];
+end
+
+ds = 1:15;
+
+for d = ds
+  allQ = 1;
+  [intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo(d, allQ);
+  
+  N = length(intra);
+  ns = 2*ones(1,N);
+  
+  bnet = mk_dbn(intra, inter, ns);
+  for i=1:N
+    bnet.CPD{i} = tabular_CPD(bnet, i);
+  end
+  
+  if 0
+    T = 5;
+    dag = unroll_dbn_topology(intra, inter, T);
+    engine = jtree_unrolled_dbn_inf_engine(bnet, T, 'constrained', 1);
+    S = struct(engine);
+    S1 = struct(S.sub_engine);
+  end
+  
+  engine = jtree_dbn_inf_engine(bnet);
+  S = struct(engine);
+  J = S.jtree_struct;
+  
+  ss = 2*d+1;
+  Qnodes2 = Qnodes + ss;
+  QQnodes = [Qnodes Qnodes2];
+  
+  % find out how many Q nodes in each clique, and how many F nodes
+  C = length(J.cliques);
+  Nclqs(d) = 0;
+  for c=1:C
+    Qsize(c,d) = length(myintersect(J.cliques{c}, QQnodes));
+    Fsize(c,d) = length(myintersect(J.cliques{c}, Fnodes));
+    if length(J.cliques{c}) > 1 % exclude observed leaves
+      Nclqs(d) = Nclqs(d) + 1;
+    end
+  end
+  %pred_max_Qsize(d) = ceil(d+(d+1)/2);
+  pred_max_Qsize(d) = ceil(1.5*d);
+  
+  fprintf('d=%d\n', d);
+  %fprintf('D=%d, max F = %d. max Q = %d, pred max Q = %d\n', ...
+	%  D, max(Fsize), max(Qsize), ceil(D+(D+1)/2));
+	     
+  %histc(Qsize,1:max(Qsize)) % how many of each size?
+end % next d
+
+
+Q = 2;
+pred_mass = ds.*(Q.^ds) + Q.^(ceil(1.5 * ds))
+pred_mass2 = Q.^(ceil(1.5 * ds))
+
+for d=ds
+  mass(d) = 0;
+  for c=1:C
+    mass(d) = mass(d) + Q^Qsize(c,d);
+  end
+end
+    
+
+if 0
+%plot(ds, max(Qsize), 'o-',  ds, pred_max_Qsize, '*--');
+%plot(ds, max(Qsize), 'o-',  ds, 1.5*ds, '*--');
+%plot(ds, mass, 'o-',  ds, pred_mass, '*--');
+D = 15;
+%plot(ds(1:D), mass(1:D), 'bo-',  ds(1:D), pred_mass(1:D), 'g*--', ds(1:D), pred_mass2(1:D), 'k+-.');
+plot(ds(1:D), log(mass(1:D)), 'bo-',  ds(1:D), log(pred_mass(1:D)), 'g*--', ds(1:D), log(pred_mass2(1:D)), 'k+-.');
+
+grid on
+xlabel('depth of hierarchy')
+title('max num Q nodes in any clique vs. depth')
+legend('actual', 'predicted')
+
+%previewfig(gcf, 'width', 3, 'height', 1.5, 'color', 'bw');
+%exportfig(gcf, '/home/cs/murphyk/WP/ConferencePapers/HHMM/clqsize2.eps', ...
+%          'width', 3, 'height', 1.5, 'color', 'bw');   
+
+end
+
+
+if 0
+for d=ds
+  effnumclqs(d) = length(find(Qsize(:,d)>0));
+end
+ds = 1:10;
+Qs = 2:10;
+maxC = size(Qsize, 1);
+cost = [];
+cost_bound = [];
+for qi=1:length(Qs)
+  Q = Qs(qi);
+  for d=ds
+    cost(d,qi) = 0;
+    for c=1:maxC
+      if length(Qsize(c,d) > 0) % this clique contains Q nodes
+	cost(d,qi) = cost(d,qi) + Q^Qsize(c,d)*2^Fsize(c,d);
+      end
+    end
+    %cost_bound(d,qi) = effnumclqs(d) * 8 * Q^(max(Qsize(:,d)));
+    cost_bound(d,qi) = (effnumclqs(d)*8) + Q^(max(Qsize(:,d)));
+  end
+end
+
+qi=2; plot(ds, cost(:,qi), 'o-',  ds, cost_bound(:,qi), '*--');
+end
+
+
+if 0
+% convert numbers in cliques into names
+for d=1:D
+  Fdecode(Fnodes(d)) = d;
+end
+for c=8:15
+  clqs = J.cliques{c};
+  fprintf('clique %d: ', c);
+  for k=clqs
+    if myismember(k, Qnodes)
+      fprintf('Q%d ', k)
+    elseif myismember(k, Fnodes)
+      fprintf('F%d ', Fdecode(k))
+    elseif isequal(k, Onode)
+      fprintf('O ')
+    elseif myismember(k, Qnodes2)
+      fprintf('Q%d* ', k-ss)
+    else
+      error(['unrecognized node ' k])
+    end
+  end
+  fprintf('\n');
+end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm.m
new file mode 100644
index 00000000..85ff7f6a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm.m
@@ -0,0 +1,258 @@
+function [bnet, Qnodes, Fnodes, Onode] = mk_hhmm(varargin)
+% MK_HHMM Make a Hierarchical HMM
+% function [bnet, Qnodes, Fnodes, Onode] = mk_hhmm(...)
+%
+% e.g. 3-layer hierarchical HMM where level 1 only connects to level 2
+% and the parents of the observed node are levels 2 and 3.
+% (This DBN is the same as Fig 10 in my tech report.)
+%
+%   Q1 ---------->   Q1
+%   |  \            ^ |
+%   |   v          /  |
+%   |    F2 ------/   |
+%   |   ^ ^        \  |
+%   |  /  |         \ |
+%   | /   |          ||
+%   v     |          vv
+%   Q2----| --------> Q2
+%  /| \   |          ^|
+% / |  v  |         / |
+% | |   F3 --------/  |
+% | |   ^          \  |
+% | v  /            v v
+% | Q3 ----------->  Q3
+% |  |    
+% \  | 
+%  v v    
+%   O
+%
+%
+% Optional arguments in name/value format [default value in brackets]
+%
+% Qsizes      - sizes at each level [ none ]
+% allQ       - 1 means level i connects to all Q levels below, 0 means just to i+1 [0]
+% transprob  - transprob{d}(i,k,j) = P(Q(d,t)=j|Q(d,t-1)=i,Q(1:d-1,t)=k)  ['leftright']
+% startprob  - startprob{d}(k,j) = P(Q(d,t)=j|Q(1:d-1,t)=k)  ['leftstart']
+% termprob   - termprob{d}(k,j) = P(F(d,t)=2|Q(1:d-1,t)=k,Q(d,t)=j) for d>1 ['rightstop']
+% selfprop   - prob of a self transition (termprob default = 1-selfprop) [0.8]
+% Osize       - size of O node
+% discrete_obs - 1 means O is tabular_CPD, 0 means gaussian_CPD [0]
+% Oargs       - cell array of args to pass to the O CPD  [ {} ]
+% Ops         - Q parents of O [Qnodes(end)]
+% F1          - 1 means level 1 can finish (restart), else there is no F1->Q1 arc [0]
+% clamp1     - 1 means we clamp the params of the Q nodes in slice 1 (Qt1params) [1]
+%   Note: the Qt1params are startprob, which should be shared with other slices.
+%   However, in the current implementation, the Qt1params will only be estimated
+%   from the initial state of each sequence.
+%
+% For d=1, startprob{1}(1,j) is only used in the first slice and
+% termprob{1} is ignored, since we assume the top level never resets.
+% Also, transprob{1}(i,j) can be used instead of transprob{1}(i,1,j).
+%
+% leftstart means the model always starts in state 1.
+% rightstop means the model can only finish in its last state (Qsize(d)).
+% unif means each state is equally like to reach any other
+% rnd means the transition/starting probs are random (drawn from rand)
+%
+% Q1:QD in slice 1 are of type tabular_CPD
+% Q1:QD in slice 2 are of type hhmmQ_CPD.
+% F(2:D-1) is of type hhmmF_CPD, FD is of type tabular_CPD.
+
+args = varargin;
+nargs = length(args);
+
+% get sizes of nodes and topology
+Qsizes = [];
+Osize = [];
+allQ = 0;
+Ops = [];
+F1 = 0;
+for i=1:2:nargs
+  switch args{i},
+   case 'Qsizes', Qsizes = args{i+1}; 
+   case 'Osize',  Osize = args{i+1}; 
+   case 'allQ',   allQ = args{i+1}; 
+   case 'Ops',    Ops = args{i+1}; 
+   case 'F1',     F1 = args{i+1}; 
+  end
+end
+if isempty(Qsizes), error('must specify Qsizes'); end
+if Osize==0, error('must specify Osize'); end
+D = length(Qsizes);
+Qnodes = 1:D;
+
+if isempty(Ops), Ops = Qnodes(end); end
+
+
+[intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo(D, allQ, Ops, F1);
+ss = length(intra);
+names = {};
+
+if F1
+  Fnodes_ndx = Fnodes;
+else
+  Fnodes_ndx = [-1 Fnodes]; % Fnodes(1) is a dummy index
+end
+		
+% set default params
+discrete_obs = 0;
+Oargs = {};
+startprob = cell(1,D);
+startprob{1} = 'unif';
+for d=2:D
+  startprob{d} = 'leftstart';
+end
+transprob = cell(1,D);
+transprob{1} = 'unif';
+for d=2:D
+  transprob{d} = 'leftright';
+end
+termprob = cell(1,D);
+for d=2:D
+  termprob{d} = 'rightstop';
+end
+selfprob = 0.8;
+clamp1 = 1;
+
+for i=1:2:nargs
+  switch args{i},
+   case 'discrete_obs', discrete_obs = args{i+1}; 
+   case 'Oargs',        Oargs = args{i+1};
+   case 'startprob',    startprob = args{i+1};
+   case 'transprob',    transprob = args{i+1};
+   case 'termprob',     termprob = args{i+1};
+   case 'selfprob',     selfprob = args{i+1};
+   case 'clamp1',       clamp1 = args{i+1};
+  end
+end
+
+ns = zeros(1,ss);
+ns(Qnodes) = Qsizes;
+ns(Onode) = Osize;
+ns(Fnodes) = 2;
+
+dnodes = [Qnodes Fnodes];
+if discrete_obs
+  dnodes = [dnodes Onode];
+end
+onodes = [Onode];
+
+bnet = mk_dbn(intra, inter, ns, 'observed', onodes, 'discrete', dnodes, 'names', names);
+eclass = bnet.equiv_class;
+
+for d=1:D
+  if d==1
+    Qps = [];
+  elseif allQ
+    Qps = Qnodes(1:d-1);
+  else
+    Qps = Qnodes(d-1);
+  end
+  Qpsz = prod(ns(Qps));
+  Qsz = ns(Qnodes(d));
+  if isstr(startprob{d})
+    switch startprob{d}
+     case 'unif', startprob{d} = mk_stochastic(ones(Qpsz, Qsz));
+     case 'rnd', startprob{d} = mk_stochastic(rand(Qpsz, Qsz));
+     case 'leftstart', startprob{d} = zeros(Qpsz, Qsz); startprob{d}(:,1) = 1;
+    end
+  end
+  if isstr(transprob{d})
+    switch transprob{d}
+     case 'unif', transprob{d} = mk_stochastic(ones(Qsz, Qpsz, Qsz));
+     case 'rnd', transprob{d} = mk_stochastic(rand(Qsz, Qpsz, Qsz));
+     case 'leftright',
+      LR = mk_leftright_transmat(Qsz, selfprob);
+      temp = repmat(reshape(LR, [1 Qsz Qsz]), [Qpsz 1 1]); % transprob(k,i,j)
+      transprob{d} = permute(temp, [2 1 3]); % now transprob(i,k,j)
+    end
+  end
+  if isstr(termprob{d})
+    switch termprob{d}
+     case 'unif', termprob{d} = mk_stochastic(ones(Qpsz, Qsz, 2));
+     case 'rnd', termprob{d} = mk_stochastic(rand(Qpsz, Qsz, 2));
+     case 'rightstop',
+      %termprob(k,i,t) Might terminate if i=Qsz; will not terminate if i<Qsz
+      stopprob = 1-selfprob;
+      termprob{d} = zeros(Qpsz, Qsz, 2);
+      termprob{d}(:,Qsz,2) = stopprob;
+      termprob{d}(:,Qsz,1) = 1-stopprob;
+      termprob{d}(:,1:(Qsz-1),1) = 1;
+     otherwise, error(['unrecognized termprob ' termprob{d}])
+    end
+  elseif d>1 % passed in termprob{d}(k,j)
+    temp = termprob{d};
+    termprob{d} = zeros(Qpsz, Qsz, 2);
+    termprob{d}(:,:,2) = temp;
+    termprob{d}(:,:,1) = ones(Qpsz,Qsz) - temp;
+  end
+end
+
+
+% SLICE 1
+
+for d=1:D
+  bnet.CPD{eclass(Qnodes(d),1)} = tabular_CPD(bnet, Qnodes(d), 'CPT', startprob{d}, 'adjustable', clamp1);
+end
+
+if F1
+  d = 1;
+  bnet.CPD{eclass(Fnodes_ndx(d),1)}  = hhmmF_CPD(bnet, Fnodes_ndx(d), Qnodes(d), Fnodes_ndx(d+1), ...
+						 'termprob', termprob{d});
+end
+for d=2:D-1
+  if allQ
+    Qps = Qnodes(1:d-1);
+  else
+    Qps = Qnodes(d-1);
+  end
+  bnet.CPD{eclass(Fnodes_ndx(d),1)}  = hhmmF_CPD(bnet, Fnodes_ndx(d), Qnodes(d), Fnodes_ndx(d+1), ...
+						 'Qps', Qps, 'termprob', termprob{d});
+end
+bnet.CPD{eclass(Fnodes_ndx(D),1)}  = tabular_CPD(bnet, Fnodes_ndx(D), 'CPT', termprob{D});
+
+if discrete_obs
+  bnet.CPD{eclass(Onode,1)} = tabular_CPD(bnet, Onode, Oargs{:});
+else
+  bnet.CPD{eclass(Onode,1)} = gaussian_CPD(bnet, Onode, Oargs{:});
+end
+
+% SLICE 2
+
+%for d=1:D
+%  bnet.CPD{eclass(Qnodes(d),2)} = hhmmQ_CPD(bnet, Qnodes(d)+ss, Qnodes, d, D, ...
+%					    'startprob', startprob{d}, 'transprob', transprob{d}, ...
+%					    'allQ', allQ);
+%end
+
+d = 1;
+if F1
+  bnet.CPD{eclass(Qnodes(d),2)} = hhmmQ_CPD(bnet, Qnodes(d)+ss, 'Fself', Fnodes_ndx(d), ...
+					    'Fbelow', Fnodes_ndx(d+1), ...
+					    'startprob', startprob{d}, 'transprob', transprob{d});
+else
+    bnet.CPD{eclass(Qnodes(d),2)} = hhmmQ_CPD(bnet, Qnodes(d)+ss, ...
+					    'Fbelow', Fnodes_ndx(d+1), ...
+					    'startprob', startprob{d}, 'transprob', transprob{d});
+end
+for d=2:D-1
+  if allQ
+    Qps = Qnodes(1:d-1);
+  else
+    Qps = Qnodes(d-1);
+  end
+  Qps = Qps + ss; % since all in slice 2
+  bnet.CPD{eclass(Qnodes(d),2)} = hhmmQ_CPD(bnet, Qnodes(d)+ss, 'Fself', Fnodes_ndx(d), ...
+					    'Fbelow', Fnodes_ndx(d+1), 'Qps', Qps, ...
+					    'startprob', startprob{d}, 'transprob', transprob{d});
+end
+d = D;
+if allQ
+  Qps = Qnodes(1:d-1);
+else
+  Qps = Qnodes(d-1);
+end
+Qps = Qps + ss; % since all in slice 2
+bnet.CPD{eclass(Qnodes(d),2)} = hhmmQ_CPD(bnet, Qnodes(d)+ss, 'Fself', Fnodes_ndx(d), ...
+					  'Qps', Qps, ...
+					  'startprob', startprob{d}, 'transprob', transprob{d});
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo.m
new file mode 100644
index 00000000..7a5fe57c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo.m
@@ -0,0 +1,76 @@
+function [intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo(D, all_Q_to_Qs, Ops, F1)
+% MK_HHMM_TOPO Make Hierarchical HMM topology
+% function [intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo(D, all_Q_to_Qs, Ops, F1)
+%
+% D is the depth of the hierarchy
+% If all_Q_to_Qs = 1, level i connects to all levels below, else just to i+1 [0]
+% Ops are the Q parents of the observed node [Qnodes(end)]
+% If F1=1, level 1 can finish (restart), else there is no F1->Q1 arc [0]
+
+Qnodes = 1:D;
+
+if nargin < 2, all_Q_to_Qs = 1; end
+if nargin < 3, Ops = Qnodes(D); end
+if nargin < 4, F1 = 0; end
+
+if F1
+  Fnodes = 2*D:-1:D+1; % must number from bottom to top
+  Onode = 2*D+1;
+  ss = 2*D+1;
+else
+  Fnodes = [-1 (2*D)-1:-1:D+1]; % Fnodes(1) is a dummy index
+  Onode = 2*D;
+  ss = 2*D;
+end
+
+intra = zeros(ss);
+intra(Ops, Onode) = 1;
+for d=1:D-1
+  if all_Q_to_Qs
+    intra(Qnodes(d), Qnodes(d+1:end)) = 1;
+  else
+    intra(Qnodes(d), Qnodes(d+1)) = 1;
+  end
+end
+for d=D:-1:3
+  intra(Fnodes(d), Fnodes(d-1)) = 1;
+end
+if F1
+  intra(Fnodes(2), Fnodes(1)) = 1;
+end
+if all_Q_to_Qs
+  if F1
+    intra(Qnodes(1), Fnodes(1:end)) = 1;
+  else
+    intra(Qnodes(1), Fnodes(2:end)) = 1;
+  end
+  for d=2:D
+    intra(Qnodes(d), Fnodes(d:end)) = 1;
+  end
+else
+  if F1
+    intra(Qnodes(1), Fnodes([1 2])) = 1;
+  else
+    intra(Qnodes(1), Fnodes(2)) = 1;
+  end
+  for d=2:D-1
+    intra(Qnodes(d), Fnodes([d d+1])) = 1;
+  end
+  intra(Qnodes(D), Fnodes(D)) = 1;
+end
+
+
+inter = zeros(ss);
+for d=1:D
+  inter(Qnodes(d), Qnodes(d)) = 1;
+end
+if F1
+  inter(Fnodes(1), Qnodes(1)) = 1;
+end
+for d=2:D
+  inter(Fnodes(d), Qnodes([d-1 d])) = 1;
+end
+
+if ~F1
+  Fnodes = Fnodes(2:end); % strip off dummy -1 term
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo_F1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo_F1.m
new file mode 100644
index 00000000..2fc5f912
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/mk_hhmm_topo_F1.m
@@ -0,0 +1,65 @@
+function [intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo_F1(D, all_Q_to_Qs, Ops)
+% MK_HHMM_TOPO Make Hierarchical HMM topology assuming level 1 can finish 
+% function [intra, inter, Qnodes, Fnodes, Onode] = mk_hhmm_topo(D, all_Q_to_Qs, Ops, F1)
+%
+% D is the depth of the hierarchy
+% If all_Q_to_Qs = 1, level i connects to all levels below, else just to i+1 [0]
+% Ops are the Q parents of the observed node [Qnodes(end)]
+% If F1=1, level 1 can finish (restart), else there is no F1->Q1 arc [0]
+
+Qnodes = 1:D;
+
+if nargin < 2, all_Q_to_Qs = 1; end
+if nargin < 3, Ops = Qnodes(D); end
+if nargin < 4, F1 = 0; end
+
+if F1
+  Fnodes = 2*D:-1:D+1; % must number from bottom to top
+  Onode = 2*D+1;
+  ss = 2*D+1;
+else
+  Fnodes = (2*D)-1:-1:D+1;
+  Onode = 2*D;
+  ss = 2*D;
+end
+
+intra = zeros(ss);
+intra(Ops, Onode) = 1;
+for d=1:D-1
+  if all_Q_to_Qs
+    intra(Qnodes(d), Qnodes(d+1:end)) = 1;
+  else
+    intra(Qnodes(d), Qnodes(d+1)) = 1;
+  end
+end
+for d=D:-1:3
+  intra(Fnodes(d), Fnodes(d-1)) = 1;
+end
+if F1
+  intra(Fnodes(2), Fnodes(1)) = 1;
+end
+if all_Q_to_Qs
+  for d=1:D
+    intra(Qnodes(d), Fnodes(d:end)) = 1;
+  end
+else
+  for d=1:D
+    if d < D
+      intra(Qnodes(d), Fnodes([d d+1])) = 1;
+    else
+      intra(Qnodes(d), Fnodes(d)) = 1;
+    end
+  end
+end
+
+inter = zeros(ss);
+for d=1:D
+  inter(Qnodes(d), Qnodes(d)) = 1;
+end
+for d=1:D
+  if d==1
+    inter(Fnodes(d), Qnodes(d)) = 1;
+  else
+    inter(Fnodes(d), Qnodes([d-1 d])) = 1;
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/pretty_print_hhmm_parse.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/pretty_print_hhmm_parse.m
new file mode 100644
index 00000000..81b965d5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/pretty_print_hhmm_parse.m
@@ -0,0 +1,67 @@
+function pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, alphabet)
+% function pretty_print_hhmm_parse(mpe, Qnodes, Fnodes, Onode, alphabet)
+%
+% mpe(i,t) is the most probable value of node i at time t
+% Qnodes(1:D), Fnodes = [F2 .. FD], Onode contain the node ids
+% alphabet(i) is the i'th output symbol, or [] if don't want displayed
+
+T = size(mpe,2);
+ncols = 20;
+t1 = 1; t2 = min(T, t1+ncols-1);
+while (t1 < T)
+  %fprintf('%d:%d\n', t1, t2);
+  if iscell(mpe)
+    print_block_cell(mpe(:,t1:t2), Qnodes, Fnodes, Onode, alphabet, t1);
+  else
+    print_block(mpe(:,t1:t2), Qnodes, Fnodes, Onode, alphabet, t1);
+  end
+  fprintf('\n\n');
+  t1 = t2+1; t2 = min(T, t1+ncols-1);
+end
+
+%%%%%%
+
+function print_block_cell(mpe, Qnodes, Fnodes, Onode, alphabet, start)
+
+D = length(Qnodes);
+T = size(mpe, 2);
+fprintf('%3d ', start:start+T-1); fprintf('\n');
+for d=1:D
+  for t=1:T
+    if (d > 1) & (mpe{Fnodes(d-1),t} == 2)
+      fprintf('%3d|', mpe{Qnodes(d), t});
+    else
+      fprintf('%3d ', mpe{Qnodes(d), t});
+    end
+  end
+  fprintf('\n');
+end
+if ~isempty(alphabet)
+  a = cell2num(mpe(Onode,:));
+  %fprintf('%3c ', alphabet(mpe{Onode,:}));
+  fprintf('%3c ', alphabet(a))
+  fprintf('\n');
+end
+
+
+%%%%%%
+
+function print_block(mpe, Qnodes, Fnodes, Onode, alphabet, start)
+
+D = length(Qnodes);
+T = size(mpe, 2);
+fprintf('%3d ', start:start+T-1); fprintf('\n');
+for d=1:D
+  for t=1:T
+    if (d > 1) & (mpe(Fnodes(d-1),t) == 2)
+      fprintf('%3d|', mpe(Qnodes(d), t));
+    else
+      fprintf('%3d ', mpe(Qnodes(d), t));
+    end
+  end
+  fprintf('\n');
+end
+if ~isempty(alphabet)
+  fprintf('%3c ', alphabet(mpe(Onode,:)));
+  fprintf('\n');
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/remove_hhmm_end_state.m b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/remove_hhmm_end_state.m
new file mode 100644
index 00000000..1ef9ded9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/HHMM/remove_hhmm_end_state.m
@@ -0,0 +1,41 @@
+function [transprob, termprob] = remove_hhmm_end_state(A)
+% REMOVE_END_STATE Infer transition and termination probabilities from automaton with an end state
+% [transprob, termprob] = remove_end_state(A)
+%
+% A(i,k,j) = Pr( i->j | Qps=k), where i in 1:Q, j in 1:(Q+1), and Q+1 is the end state
+% This implements the equation in footnote 3 of my NIPS 01 paper,
+% transprob(i,k,j) = \tilde{A}_k(i,j)
+% termprob(k,j) = \tau_k(j)
+%
+% For the top level, the k index is missing.
+
+Q = size(A,1);
+toplevel = (ndims(A)==2);
+if toplevel
+  Qk = 1;
+  A = reshape(A, [Q 1 Q+1]);
+else
+  Qk = size(A, 2);
+end
+
+transprob = A(:, :, 1:Q);
+term = A(:,:,Q+1)'; % term(k,j) = P(Qj -> end | k)
+termprob = term;
+%termprob = zeros(Qk, Q, 2);
+%termprob(:,:,2) = term;
+%termprob(:,:,1) = 1-term;
+
+for k=1:Qk
+  for i=1:Q
+    for j=1:Q
+      denom = (1-termprob(k,i));
+      denom = denom + (denom==0)*eps;
+      transprob(i,k,j) = transprob(i,k,j) / denom;
+    end
+  end    
+end
+
+if toplevel
+  termprob = squeeze(termprob);
+  transprob = squeeze(transprob);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/CVS/Entries
new file mode 100644
index 00000000..b5b0dc43
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/CVS/Entries
@@ -0,0 +1,8 @@
+/chmm1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/cmp_inference.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/kalman1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/old.water1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/online1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/online2.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/scg_dbn.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/CVS/Repository
new file mode 100644
index 00000000..b23f8f6d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/Old
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/Old/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/Old/chmm1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/chmm1.m
new file mode 100644
index 00000000..d4195c97
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/chmm1.m
@@ -0,0 +1,40 @@
+% Compare the speeds of various inference engines on a coupled HMM
+
+N = 2;
+Q = 2;
+rand('state', 0);
+randn('state', 0);
+discrete = 1;
+if discrete
+  Y = 2; % size of output alphabet
+else
+  Y = 1;
+end
+coupled = 1;
+[bnet, onodes] = mk_chmm(N, Q, Y, discrete, coupled);
+ss = N*2;
+
+T = 3;
+
+
+engine = {};
+tic; engine{end+1} = jtree_dbn_inf_engine(bnet, 'observed', onodes);  toc
+%tic; engine{end+1} = jtree_ndxSD_dbn_inf_engine(bnet, onodes);  toc
+%tic; engine{end+1} = jtree_ndxB_dbn_inf_engine(bnet, onodes);  toc
+engine{end+1} = hmm_inf_engine(bnet, onodes);
+%engine{end+1} = dhmm_inf_engine(bnet, onodes);
+tic; engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T, onodes);  toc
+
+%engine{end+1} = bk_inf_engine(bnet, 'ff', onodes);
+%engine{end+1} = loopy_dbn_inf_engine(bnet, onodes);
+
+exact = [1 2 3];
+
+filter = 0;
+single = 0;
+maximize = 0;
+
+[err, time, engine] = cmp_inference(bnet, onodes, engine, exact, T, filter, single, maximize);
+%err = cmp_learning(bnet, onodes, engine, exact, T);
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/Old/cmp_inference.m b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/cmp_inference.m
new file mode 100644
index 00000000..b5c936f0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/cmp_inference.m
@@ -0,0 +1,75 @@
+function [err, time, engine] = cmp_inference(bnet, engine, exact, T, filter, singletons, maximize)
+% CMP_INFERENCE Compare several inference engines on a DBN
+% [err, time, engine] = cmp_inference(bnet, engine, exact, T, filter, singletons, maximize)
+%
+% engine{i} is the i'th inference engine.
+% 'exact' specifies which engines do exact inference - 
+%   we check that these all give the same results.
+% 'T' is the length of the random sequence we generate.
+% If filter=1, we do filtering, else smoothing (default: smoothing)
+% If singletons=1, we compare marginal_nodes, else marginal_family (default: family)
+%
+% err(e,n,t) = sum_i | Pr_exact(X(n,t)=i) - Pr_e(X(n,t)=i) |
+%   where Pr_e = prob. according to engine e
+% time(e) = elapsed time for doing inference with engine e
+
+err = [];
+
+if nargin < 5, filter = 0; end
+if nargin < 6, singletons = 0; end
+if nargin < 7, maximize = 0; end
+
+check_ll = 1;
+
+assert(~maximize);
+
+E = length(engine);
+ref = exact(1); % reference
+
+ss = length(bnet.intra);
+ev = sample_dbn(bnet, 'length', T);
+evidence = cell(ss,T);
+onodes = bnet.observed;
+evidence(onodes,:) = ev(onodes, :);
+
+assert(~filter);
+for i=1:E
+  tic;
+  %[engine{i}, ll(i)] = enter_evidence(engine{i}, evidence, 'maximize', maximize);
+  [engine{i}, ll(i)] = enter_evidence(engine{i}, evidence);
+  time(i)=toc;
+  fprintf('engine %d took %6.4f seconds\n', i, time(i));
+end
+
+cmp = mysetdiff(exact, ref);
+if check_ll
+for i=cmp(:)'
+  if ~approxeq(ll(ref), ll(i))
+    error(['engine ' num2str(i) ' has wrong ll'])
+  end
+end
+end
+ll
+
+hnodes = mysetdiff(1:ss, onodes);
+m = cell(1,E);
+for t=1:T
+  for n=hnodes(:)'
+    for e=1:E
+      if singletons
+	m{e} = marginal_nodes(engine{e}, n, t);
+      else
+	m{e} = marginal_family(engine{e}, n, t);
+      end
+    end
+    for e=1:E
+      assert(isequal(m{e}.domain, m{ref}.domain));
+    end
+    for e=cmp(:)'
+      if ~approxeq(m{ref}.T(:), m{e}.T(:))
+	str= sprintf('engine %d is wrong; n=%d, t=%d', e, n, t);
+	error(str)
+      end
+    end
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/Old/kalman1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/kalman1.m
new file mode 100644
index 00000000..c068ab3e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/kalman1.m
@@ -0,0 +1,127 @@
+% Make a linear dynamical system
+%   X1 -> X2
+%   |     | 
+%   v     v
+%   Y1    Y2 
+
+intra = zeros(2);
+intra(1,2) = 1;
+inter = zeros(2);
+inter(1,1) = 1;
+n = 2;
+
+X = 2; % size of hidden state
+Y = 2; % size of observable state
+
+ns = [X Y];
+dnodes = [];
+onodes = [2];
+eclass1 = [1 2];
+eclass2 = [3 2];
+bnet = mk_dbn(intra, inter, ns, 'discrete', dnodes, 'eclass1', eclass1, 'eclass2', eclass2, ...
+	      'observed', onodes);
+
+x0 = rand(X,1);
+V0 = eye(X);
+C0 = rand(Y,X);
+R0 = eye(Y);
+A0 = rand(X,X);
+Q0 = eye(X);
+
+bnet.CPD{1} = gaussian_CPD(bnet, 1, 'mean', x0, 'cov', V0, 'cov_prior_weight', 0);
+bnet.CPD{2} = gaussian_CPD(bnet, 2, 'mean', zeros(Y,1), 'cov', R0, 'weights', C0, ...
+			   'clamp_mean', 1, 'cov_prior_weight', 0);
+bnet.CPD{3} = gaussian_CPD(bnet, 3, 'mean', zeros(X,1), 'cov', Q0, 'weights', A0, ...
+			   'clamp_mean', 1, 'cov_prior_weight', 0);
+
+
+T = 5; % fixed length sequences
+
+clear engine;
+engine{1} = kalman_inf_engine(bnet);
+engine{2} = jtree_unrolled_dbn_inf_engine(bnet, T);
+engine{3} = jtree_dbn_inf_engine(bnet);
+N = length(engine);
+
+% inference
+
+ev = sample_dbn(bnet, T);
+evidence = cell(n,T);
+evidence(onodes,:) = ev(onodes, :);
+
+t = 1;
+query = [1 3];
+m = cell(1, N);
+ll = zeros(1, N);
+for i=1:N
+  [engine{i}, ll(i)] = enter_evidence(engine{i}, evidence);
+  m{i} = marginal_nodes(engine{i}, query, t);
+end
+
+% compare all engines to engine{1}
+for i=2:N
+  assert(approxeq(m{1}.mu, m{i}.mu));
+  assert(approxeq(m{1}.Sigma, m{i}.Sigma));
+  assert(approxeq(ll(1), ll(i)));
+end
+
+if 0
+for i=2:N
+  approxeq(m{1}.mu, m{i}.mu)
+  approxeq(m{1}.Sigma, m{i}.Sigma)
+  approxeq(ll(1), ll(i))
+end
+end
+
+% learning
+
+ncases = 5;
+cases = cell(1, ncases);
+for i=1:ncases
+  ev = sample_dbn(bnet, T);
+  cases{i} = cell(n,T);
+  cases{i}(onodes,:) = ev(onodes, :);
+end
+
+max_iter = 2;
+bnet2 = cell(1,N);
+LLtrace = cell(1,N);
+for i=1:N
+  [bnet2{i}, LLtrace{i}] = learn_params_dbn_em(engine{i}, cases, 'max_iter', max_iter);
+end
+
+for i=1:N
+  temp = bnet2{i};
+  for e=1:3
+    CPD{i,e} = struct(temp.CPD{e});
+  end
+end
+
+for i=2:N
+  assert(approxeq(LLtrace{i}, LLtrace{1}));
+  for e=1:3
+    assert(approxeq(CPD{i,e}.mean, CPD{1,e}.mean));
+    assert(approxeq(CPD{i,e}.cov, CPD{1,e}.cov));
+    assert(approxeq(CPD{i,e}.weights, CPD{1,e}.weights));
+  end
+end
+
+
+% Compare to KF toolbox
+
+data = zeros(Y, T, ncases);
+for i=1:ncases
+  data(:,:,i) = cell2num(cases{i}(onodes, :));
+end   
+[A2, C2, Q2, R2, x2, V2, LL2trace] =  learn_kalman(data, A0, C0, Q0, R0, x0, V0, max_iter);
+
+
+e = 1;
+assert(approxeq(x2, CPD{e,1}.mean))
+assert(approxeq(V2, CPD{e,1}.cov))
+assert(approxeq(C2, CPD{e,2}.weights))
+assert(approxeq(R2, CPD{e,2}.cov));
+assert(approxeq(A2, CPD{e,3}.weights))
+assert(approxeq(Q2, CPD{e,3}.cov));
+assert(approxeq(LL2trace, LLtrace{1}))
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/Old/old.water1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/old.water1.m
new file mode 100644
index 00000000..0a356ef8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/old.water1.m
@@ -0,0 +1,48 @@
+% Compare the speeds of various inference engines on the water DBN
+
+[bnet, onodes] = mk_water_dbn;
+
+T = 3;
+
+engine = {};
+engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T, onodes);
+engine{end+1} = hmm_inf_engine(bnet, onodes);
+engine{end+1} = frontier_inf_engine(bnet, onodes);
+engine{end+1} = jtree_dbn_inf_engine(bnet, onodes);
+engine{end+1} = bk_inf_engine(bnet, 'exact', onodes);
+
+engine{end+1} = bk_inf_engine(bnet, 'ff', onodes);
+engine{end+1} = bk_inf_engine(bnet, { [1 2], [3 4 5 6], [7 8] }, onodes);
+
+N = length(engine);
+exact = 1:5;
+
+
+filter = 0;
+err = cmp_inference(bnet, onodes, engine, exact, T, filter);
+
+% elapsed times for enter_evidence  (matlab 5.3 on PIII with 256MB running Redhat linux)  
+
+% T = 5, 4/20/00
+%     0.6266 unrolled *
+%     0.3490 hmm *
+%     1.1743 frontier
+%     1.4621 old frontier
+%     0.3270 fast frontier *
+%     1.3926 jtree 
+%     1.3790 bk 
+%     0.4916 fast bk
+%     0.4190 fast bk compiled
+%     0.3574 fast jtree *
+
+
+err = cmp_learning(bnet, onodes, engine, exact, T);
+
+% elapsed times for learn_params_dbn_em (matlab 5.3 on PIII with 256MB running Redhat linux)  
+
+% T = 5, 2cases, 2 iter, 4/20/00
+% 3.5750 unrolled
+% 3.7475 hmm
+% 2.1452 fast frontier
+% 2.5724 fast bk compiled
+% 2.3387 fast jtree
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/Old/online1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/online1.m
new file mode 100644
index 00000000..05708e10
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/online1.m
@@ -0,0 +1,59 @@
+% Check that online inference gives same results as filtering for various algorithms
+
+N = 3;
+Q = 2;
+ss = N*2;
+
+rand('state', 0);
+randn('state', 0);
+
+
+obs_size = 1;
+discrete_obs = 0;
+bnet = mk_chmm(N, Q, obs_size, discrete_obs);
+ns = bnet.node_sizes_slice;
+
+engine = {};
+engine{end+1} = hmm_inf_engine(bnet);
+E = length(engine);
+
+onodes = (1:N)+N;
+
+T = 4;
+ev = cell(ss,T);
+ev(onodes,:) = num2cell(randn(N, T));
+
+
+filter = 1;
+loglik2 = zeros(1,E);
+for e=1:E
+  [engine2{e}, loglik2(e)] = enter_evidence(engine{e}, ev, 'filter', filter);
+end
+
+loglik = zeros(1,E);
+marg1 = cell(E,N,T);
+for e=1:E
+  ll = zeros(1,T);
+  engine{e} = dbn_init_bel(engine{e});
+  for t=1:T
+    [engine{e}, ll(t)] = dbn_update_bel(engine{e}, ev(:,t), t);
+    for i=1:N
+      marg1{e,i,t} = dbn_marginal_from_bel(engine{e}, i);
+    end
+  end
+  loglik1(e) = sum(ll);
+end
+
+assert(approxeq(loglik1, loglik2))
+
+a = zeros(E,N,T);
+for e=1:E
+  for t=1:T
+    for i=1:N
+      marg2{e,i,t} = marginal_nodes(engine2{e}, i, t);
+      a(e,i,t) = (approxeq(marg2{e,i,t}.T(:), marg1{e,i,t}.T(:)));
+    end
+  end
+end
+
+assert(all(a(:)==1))
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/Old/online2.m b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/online2.m
new file mode 100644
index 00000000..6b141f19
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/online2.m
@@ -0,0 +1,33 @@
+N = 1; % regular HMM
+Q = 2;
+ss = 2;
+hnodes = 1;
+onodes = 2;
+
+rand('state', 0);
+randn('state', 0);
+O = 2;
+discrete_obs = 1;
+bnet = mk_chmm(N, Q, O, discrete_obs);
+ns = bnet.node_sizes_slice;
+
+engine = hmm_inf_engine(bnet, onodes);
+
+T = 4;
+ev = cell(ss,T);
+ev(onodes,:) = num2cell(sample_discrete([0.5 0.5], N, T));
+
+
+engine = dbn_init_bel(engine);
+for t=1:T
+  if t==1
+    [engine, ll(t)] = dbn_update_bel1(engine, ev(:,t));
+  else
+    [engine, ll(t)] = dbn_update_bel(engine, ev(:,t-1:t));
+  end
+  % one-step ahead prediction
+  lag = 1;
+  engine2 = dbn_predict_bel(engine, lag);  
+  marg = dbn_marginal_from_bel(engine2, 1)
+  marg = dbn_marginal_from_bel(engine2, 2)
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/Old/scg_dbn.m b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/scg_dbn.m
new file mode 100644
index 00000000..0ddabb34
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/Old/scg_dbn.m
@@ -0,0 +1,70 @@
+% to test whether scg inference engine can handl dynameic BN
+% Make a linear dynamical system
+%   X1 -> X2
+%   |     | 
+%   v     v
+%   Y1    Y2 
+
+intra = zeros(2);
+intra(1,2) = 1;
+inter = zeros(2);
+inter(1,1) = 1;
+n = 2;
+
+X = 2; % size of hidden state
+Y = 2; % size of observable state
+
+ns = [X Y];
+dnodes = [];
+onodes = [2];
+eclass1 = [1 2];
+eclass2 = [3 2];
+bnet = mk_dbn(intra, inter, ns, dnodes, eclass1, eclass2);
+
+x0 = rand(X,1);
+V0 = eye(X);
+C0 = rand(Y,X);
+R0 = eye(Y);
+A0 = rand(X,X);
+Q0 = eye(X);
+
+bnet.CPD{1} = gaussian_CPD(bnet, 1, 'mean', x0, 'cov', V0);
+%bnet.CPD{2} = gaussian_CPD(bnet, 2, 'mean', zeros(Y,1), 'cov', R0, 'weights', C0, 'full', 'untied', 'clamped_mean');
+%bnet.CPD{3} = gaussian_CPD(bnet, 3, 'mean', zeros(X,1), 'cov', Q0, 'weights', A0, 'full', 'untied', 'clamped_mean');
+bnet.CPD{2} = gaussian_CPD(bnet, 2, 'mean', zeros(Y,1), 'cov', R0, 'weights', C0);
+bnet.CPD{3} = gaussian_CPD(bnet, 3, 'mean', zeros(X,1), 'cov', Q0, 'weights', A0);
+
+
+T = 5; % fixed length sequences
+
+clear engine;
+%engine{1} = kalman_inf_engine(bnet, onodes);
+engine{1} = scg_unrolled_dbn_inf_engine(bnet, T, onodes);
+engine{2} = jtree_unrolled_dbn_inf_engine(bnet, T);
+
+N = length(engine);
+
+% inference
+
+ev = sample_dbn(bnet, T);
+evidence = cell(n,T);
+evidence(onodes,:) = ev(onodes, :);
+
+t = 2;
+query = [1 3];
+m = cell(1, N);
+ll = zeros(1, N);
+
+engine{1} = enter_evidence(engine{1}, evidence);
+[engine{2}, ll(2)] = enter_evidence(engine{2}, evidence);
+m{1} = marginal_nodes(engine{1}, query);
+m{2} = marginal_nodes(engine{2}, query, t);
+
+
+% compare all engines to engine{1}
+for i=2:N
+  assert(approxeq(m{1}.mu, m{i}.mu));
+  assert(approxeq(m{1}.Sigma, m{i}.Sigma));
+%  assert(approxeq(ll(1), ll(i)));
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/CVS/Entries
new file mode 100644
index 00000000..6810ce1d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/CVS/Entries
@@ -0,0 +1,7 @@
+/mk_gmux_robot_dbn.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_linear_slam.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/slam_kf.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/slam_offline_loopy.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/slam_partial_kf.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/slam_stationary_loopy.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D/Old////
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/CVS/Repository
new file mode 100644
index 00000000..e32a23fa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/SLAM
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/CVS/Entries
new file mode 100644
index 00000000..37fe6bb1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/CVS/Entries
@@ -0,0 +1,5 @@
+/offline_loopy_slam.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/paskin1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/skf_data_assoc_gmux2.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/slam_kf.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/CVS/Repository
new file mode 100644
index 00000000..1bae1a70
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/dynamic/SLAM/Old
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/CVS/Root b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/offline_loopy_slam.m b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/offline_loopy_slam.m
new file mode 100644
index 00000000..377a4659
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/offline_loopy_slam.m
@@ -0,0 +1,231 @@
+% We navigate a robot around a square using a fixed control policy and no noise.
+% We assume the robot observes the relative distance to the nearest landmark.
+% Everything is linear-Gaussian.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Create toy data set
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+if 1
+  T = 20;
+  ctrl_signal = [repmat([1 0]', 1, T/4) repmat([0 1]', 1, T/4) ...
+		 repmat([-1 0]', 1, T/4) repmat([0 -1]', 1, T/4)];
+else
+  T = 5;
+  ctrl_signal = repmat([1 0]', 1, T);
+end
+
+nlandmarks = 4;
+true_landmark_pos = [1 1;
+		     4 1;
+		     4 4;
+		     1 4]';
+init_robot_pos = [0 0]';
+
+true_robot_pos = zeros(2, T);
+true_data_assoc = zeros(1, T);
+true_rel_dist = zeros(2, T);
+for t=1:T
+  if t>1
+    true_robot_pos(:,t) = true_robot_pos(:,t-1) + ctrl_signal(:,t);
+  else
+    true_robot_pos(:,t) = init_robot_pos + ctrl_signal(:,t);
+  end
+  nn = argmin(dist2(true_robot_pos(:,t)', true_landmark_pos'));
+  %nn = t; % observe 1, 2, 3
+  true_data_assoc(t) = nn;
+  true_rel_dist(:,t) = true_landmark_pos(:, nn) - true_robot_pos(:,t);
+end
+
+figure(1);
+%clf; 
+hold on
+%plot(true_landmark_pos(1,:), true_landmark_pos(2,:), '*');
+for i=1:nlandmarks
+  text(true_landmark_pos(1,i), true_landmark_pos(2,i), sprintf('L%d',i));
+end
+for t=1:T
+  text(true_robot_pos(1,t), true_robot_pos(2,t), sprintf('%d',t));
+end
+hold off
+axis([-1 6 -1 6])
+
+R = 1e-3*eye(2); % noise added to observation
+Q = 1e-3*eye(2); % noise added to robot motion
+
+% Create data set
+obs_noise_seq = sample_gaussian([0 0]', R, T)';
+obs_rel_pos = true_rel_dist + obs_noise_seq;
+%obs_rel_pos = true_rel_dist;
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Create params for inference
+
+% X(t) = A X(t-1) + B U(t) + noise(Q)
+
+% [L1]  = [1     ]  * [L1]       + [0]  * Ut  + [0   ]
+% [L2]    [  1   ]    [L2]         [0]          [ 0  ]
+% [R ]t   [     1]    [R ]t-1      [1]          [   Q]
+
+% Y(t)|S(t)=s  = C(s) X(t) + noise(R)
+% Yt|St=1 = [1 0 -1]  * [L1]  + R
+%                       [L2]    
+%                       [R ]    
+
+% Create indices into block structure
+bs = 2*ones(1, nlandmarks+1); % sizes of blocks in state space
+robot_block =  block(nlandmarks+1, bs);
+for i=1:nlandmarks
+  landmark_block(:,i) = block(i, bs)';
+end
+Xsz = 2*(nlandmarks+1); % 2 values for each landmark plus robot
+Ysz = 2; % observe relative location
+Usz = 2; % input is (dx, dy)
+
+
+% create block-diagonal trans matrix for each switch
+A = zeros(Xsz, Xsz);
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  A(bi, bi) = eye(2);
+end
+bi = robot_block;
+A(bi, bi) = eye(2);
+A = repmat(A, [1 1 nlandmarks]); % same for all switch values
+
+% create block-diagonal system cov
+
+
+Qbig = zeros(Xsz, Xsz);
+bi = robot_block;
+Qbig(bi,bi) = Q; % only add noise to robot motion
+Qbig = repmat(Qbig, [1 1 nlandmarks]);
+
+% create input matrix
+B = zeros(Xsz, Usz);
+B(robot_block,:) = eye(2); % only add input to robot position
+B = repmat(B, [1 1 nlandmarks]);
+
+% create observation matrix for each value of the switch node
+% C(:,:,i) = (0 ... I ... -I) where the I is in the i'th posn.
+% This computes L(i) - R
+C = zeros(Ysz, Xsz, nlandmarks);
+for i=1:nlandmarks
+  C(:, landmark_block(:,i), i) = eye(2); 
+  C(:, robot_block, i) = -eye(2);
+end
+
+% create observation cov for each value of the switch node
+Rbig = repmat(R, [1 1 nlandmarks]);
+
+% initial conditions
+init_x = zeros(Xsz, 1);
+init_v = zeros(Xsz, Xsz);
+bi = robot_block;
+init_x(bi) = init_robot_pos;
+init_V(bi, bi) = 1e-5*eye(2); % very sure of robot posn
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  init_V(bi,bi)= 1e5*eye(2); % very uncertain of landmark psosns
+  %init_x(bi) = true_landmark_pos(:,i);
+  %init_V(bi,bi)= 1e-5*eye(2); % very sure of landmark psosns
+end
+
+%%%%%%%%%%%%%%%%%%%%%
+% Inference
+if 1
+[xsmooth, Vsmooth] = kalman_smoother(obs_rel_pos, A, C, Qbig, Rbig, init_x, init_V, ...
+				     'model', true_data_assoc, 'u', ctrl_signal, 'B', B);
+
+est_robot_pos = xsmooth(robot_block, :);
+est_robot_pos_cov = Vsmooth(robot_block, robot_block, :);
+
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  est_landmark_pos(:,i) = xsmooth(bi, T);
+  est_landmark_pos_cov(:,:,i) = Vsmooth(bi, bi, T);
+end
+end
+
+
+if 0
+figure(1); hold on
+for i=1:nlandmarks
+  h=plotgauss2d(est_landmark_pos(:,i), est_landmark_pos_cov(:,:,i));
+  set(h, 'color', 'r')
+end
+hold off
+
+hold on
+for t=1:T
+  h=plotgauss2d(est_robot_pos(:,t), est_robot_pos_cov(:,:,t));
+  set(h,'color','r')
+  h=text(est_robot_pos(1,t), est_robot_pos(2,2), sprintf('R%d', t));
+  set(h,'color','r')
+end
+hold off
+end
+
+
+if 0
+figure(3)
+if 0
+  for t=1:T
+    imagesc(inv(Vsmooth(:,:,t)))
+    colorbar
+    fprintf('t=%d; press key to continue\n', t);
+    pause
+  end
+else
+  for t=1:T
+    subplot(5,4,t)
+    imagesc(inv(Vsmooth(:,:,t)))
+  end
+end
+end
+
+
+
+
+
+%%%%%%%%%%%%%%%%%
+% DBN inference
+
+if 1
+  [bnet, Unode, Snode, Lnodes, Rnode, Ynode, Lsnode] = ...
+      mk_gmux_robot_dbn(nlandmarks, Q, R, init_x, init_V, robot_block, landmark_block);
+  engine = pearl_unrolled_dbn_inf_engine(bnet, 'max_iter', 50, 'filename', ...
+					 '/home/eecs/murphyk/matlab/loopyslam.txt');
+else
+  [bnet, Unode, Snode, Lnodes, Rnode, Ynode] = ...
+      mk_gmux2_robot_dbn(nlandmarks, Q, R, init_x, init_V, robot_block, landmark_block);
+  engine = jtree_dbn_inf_engine(bnet);
+end
+
+nnodes = bnet.nnodes_per_slice;
+evidence = cell(nnodes, T);
+evidence(Ynode, :) = num2cell(obs_rel_pos, 1);
+evidence(Unode, :) = num2cell(ctrl_signal, 1);
+evidence(Snode, :) = num2cell(true_data_assoc);
+
+
+[engine, ll, niter] = enter_evidence(engine, evidence);
+niter
+
+loopy_est_robot_pos = zeros(2, T);
+for t=1:T
+  m = marginal_nodes(engine, Rnode, t);
+  loopy_est_robot_pos(:,t) = m.mu;
+end
+
+for i=1:nlandmarks
+  m = marginal_nodes(engine, Lnodes(i), T);
+  loopy_est_landmark_pos(:,i) = m.mu;
+  loopy_est_landmark_pos_cov(:,:,i) = m.Sigma;
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/paskin1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/paskin1.m
new file mode 100644
index 00000000..286793d3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/paskin1.m
@@ -0,0 +1,238 @@
+% This is like robot1, except we only use a Kalman filter.
+% The goal is to study how the precision matrix changes.
+
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+if 0
+  T = 20;
+  ctrl_signal = [repmat([1 0]', 1, T/4) repmat([0 1]', 1, T/4) ...
+		 repmat([-1 0]', 1, T/4) repmat([0 -1]', 1, T/4)];
+else
+  T = 60;
+  ctrl_signal = repmat([1 0]', 1, T);
+end
+
+nlandmarks = 6;
+if 0
+  true_landmark_pos = [1 1;
+		    4 1;
+		    4 4;
+		    1 4]';
+else
+  true_landmark_pos = 10*rand(2,nlandmarks);
+end
+if 0
+figure(1); clf
+hold on
+for i=1:nlandmarks
+  %text(true_landmark_pos(1,i), true_landmark_pos(2,i), sprintf('L%d',i));
+  plot(true_landmark_pos(1,i), true_landmark_pos(2,i), '*')
+end
+hold off
+end
+
+init_robot_pos = [0 0]';
+
+true_robot_pos = zeros(2, T);
+true_data_assoc = zeros(1, T);
+true_rel_dist = zeros(2, T);
+for t=1:T
+  if t>1
+    true_robot_pos(:,t) = true_robot_pos(:,t-1) + ctrl_signal(:,t);
+  else
+    true_robot_pos(:,t) = init_robot_pos + ctrl_signal(:,t);
+  end
+  nn = argmin(dist2(true_robot_pos(:,t)', true_landmark_pos'));
+  %true_data_assoc(t) = nn;
+  %true_data_assoc = wrap(t, nlandmarks); % observe 1, 2, 3, 4, 1, 2, ...
+  true_data_assoc  = sample_discrete(normalise(ones(1,nlandmarks)),1,T);
+  true_rel_dist(:,t) = true_landmark_pos(:, nn) - true_robot_pos(:,t);
+end
+
+R = 1e-3*eye(2); % noise added to observation
+Q = 1e-3*eye(2); % noise added to robot motion
+
+% Create data set
+obs_noise_seq = sample_gaussian([0 0]', R, T)';
+obs_rel_pos = true_rel_dist + obs_noise_seq;
+%obs_rel_pos = true_rel_dist;
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Create params for inference
+
+% X(t) = A X(t-1) + B U(t) + noise(Q) 
+
+% [L1]  = [1     ]  * [L1]       + [0]  * Ut  + [0   ]
+% [L2]    [  1   ]    [L2]         [0]          [ 0  ]
+% [R ]t   [     1]    [R ]t-1      [1]          [   Q]
+
+% Y(t)|S(t)=s  = C(s) X(t) + noise(R)
+% Yt|St=1 = [1 0 -1]  * [L1]  + R
+%                       [L2]    
+%                       [R ]    
+
+% Create indices into block structure
+bs = 2*ones(1, nlandmarks+1); % sizes of blocks in state space
+robot_block =  block(nlandmarks+1, bs);
+for i=1:nlandmarks
+  landmark_block(:,i) = block(i, bs)';
+end
+Xsz = 2*(nlandmarks+1); % 2 values for each landmark plus robot
+Ysz = 2; % observe relative location
+Usz = 2; % input is (dx, dy)
+
+
+% create block-diagonal trans matrix for each switch
+A = zeros(Xsz, Xsz);
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  A(bi, bi) = eye(2);
+end
+bi = robot_block;
+A(bi, bi) = eye(2);
+A = repmat(A, [1 1 nlandmarks]); % same for all switch values
+
+% create block-diagonal system cov
+
+
+Qbig = zeros(Xsz, Xsz);
+bi = robot_block;
+Qbig(bi,bi) = Q; % only add noise to robot motion
+Qbig = repmat(Qbig, [1 1 nlandmarks]);
+
+% create input matrix
+B = zeros(Xsz, Usz);
+B(robot_block,:) = eye(2); % only add input to robot position
+B = repmat(B, [1 1 nlandmarks]);
+
+% create observation matrix for each value of the switch node
+% C(:,:,i) = (0 ... I ... -I) where the I is in the i'th posn.
+% This computes L(i) - R
+C = zeros(Ysz, Xsz, nlandmarks);
+for i=1:nlandmarks
+  C(:, landmark_block(:,i), i) = eye(2); 
+  C(:, robot_block, i) = -eye(2);
+end
+
+% create observation cov for each value of the switch node
+Rbig = repmat(R, [1 1 nlandmarks]);
+
+% initial conditions
+init_x = zeros(Xsz, 1);
+init_v = zeros(Xsz, Xsz);
+bi = robot_block;
+init_x(bi) = init_robot_pos;
+%init_V(bi, bi) = 1e-5*eye(2); % very sure of robot posn
+init_V(bi, bi) = Q; % simualate uncertainty due to 1 motion step
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  init_V(bi,bi)= 1e5*eye(2); % very uncertain of landmark psosns
+  %init_x(bi) = true_landmark_pos(:,i);
+  %init_V(bi,bi)= 1e-5*eye(2); % very sure of landmark psosns
+end
+
+%k = nlandmarks-1; % exact
+k = 3;
+ndx = {};
+for t=1:T
+  landmarks = unique(true_data_assoc(t:-1:max(t-k,1)));
+  tmp = [landmark_block(:, landmarks) robot_block'];
+  ndx{t} = tmp(:);
+end
+
+[xa, Va] = kalman_filter(obs_rel_pos, A, C, Qbig, Rbig, init_x, init_V, ...
+				     'model', true_data_assoc, 'u', ctrl_signal, 'B', B, ...
+		       'ndx', ndx);
+
+[xe, Ve] = kalman_filter(obs_rel_pos, A, C, Qbig, Rbig, init_x, init_V, ...
+				     'model', true_data_assoc, 'u', ctrl_signal, 'B', B);
+
+
+if 0
+est_robot_pos = x(robot_block, :);
+est_robot_pos_cov = V(robot_block, robot_block, :);
+
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  est_landmark_pos(:,i) = x(bi, T);
+  est_landmark_pos_cov(:,:,i) = V(bi, bi, T);
+end
+end
+
+
+
+nrows = 10;
+stepsize = T/(2*nrows);
+ts = 1:stepsize:T;
+
+if 1 % plot
+  
+clim = [0 max(max(Va(:,:,end)))];
+
+figure(2)
+if 0
+  imagesc(Ve(1:2:end,1:2:end, T))
+  clim = get(gca,'clim');
+else
+  i = 1;
+  for t=ts(:)'
+    subplot(nrows,2,i)
+    i = i + 1;
+    imagesc(Ve(1:2:end,1:2:end, t))
+    set(gca, 'clim', clim)
+    colorbar
+  end
+end
+suptitle('exact')
+
+
+figure(3)
+if 0
+  imagesc(Va(1:2:end,1:2:end, T))
+  set(gca,'clim', clim)
+else
+  i = 1;
+  for t=ts(:)'
+    subplot(nrows,2,i)
+    i = i+1;
+    imagesc(Va(1:2:end,1:2:end, t))
+    set(gca, 'clim', clim)
+    colorbar
+  end
+end
+suptitle('approx')
+
+
+figure(4)
+i = 1;
+for t=ts(:)'
+  subplot(nrows,2,i)
+  i = i+1;
+  Vd = Va(1:2:end,1:2:end, t) - Ve(1:2:end,1:2:end,t);
+  imagesc(Vd)
+  set(gca, 'clim', clim)
+  colorbar
+end
+suptitle('diff')
+
+end % all plot
+
+
+for t=1:T
+  i = 1:2*nlandmarks;
+  denom = Ve(i,i,t) + (Ve(i,i,t)==0);
+  Vd =(Va(i,i,t)-Ve(i,i,t)) ./ denom;
+  Verr(t) = max(Vd(:));
+end
+figure(6); plot(Verr)
+title('max relative Verr')
+
+for t=1:T
+  %err(t)=rms(xa(:,t), xe(:,t));
+  err(t)=rms(xa(1:end-2,t), xe(1:end-2,t)); % exclude robot
+end
+figure(5);plot(err)
+title('rms mean pos')
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/skf_data_assoc_gmux2.m b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/skf_data_assoc_gmux2.m
new file mode 100644
index 00000000..0272d3f6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/skf_data_assoc_gmux2.m
@@ -0,0 +1,155 @@
+% This is like skf_data_assoc_gmux, except the objects don't move.
+% We are uncertain of their initial positions, and get more and more observations
+% over time. The goal is to test deterministic links (0 covariance).
+% This is like robot1, except the robot doesn't move and is always at [0 0],
+% so the relative location is simply L(s).
+
+nobj = 2;
+N = nobj+2;
+Xs = 1:nobj;
+S = nobj+1;
+Y = nobj+2;
+
+intra = zeros(N,N);
+inter = zeros(N,N);
+intra([Xs S], Y) =1;
+for i=1:nobj
+  inter(Xs(i), Xs(i))=1;
+end
+
+Xsz = 2; % state space = (x y)
+Ysz = 2;
+ns = zeros(1,N);
+ns(Xs) = Xsz;
+ns(Y) = Ysz;
+ns(S) = nobj;
+
+bnet = mk_dbn(intra, inter, ns, 'discrete', S, 'observed', [S Y]);
+
+% For each object, we have
+% X(t+1) = F X(t) + noise(Q)
+% Y(t) = H X(t) + noise(R)
+F = eye(2);
+H = eye(2);
+Q = 0*eye(Xsz); % no noise in dynamics
+R = eye(Ysz);
+
+init_state{1} = [10 10]';
+init_state{2} = [10 -10]';
+init_cov = eye(2);
+
+% Uncertain of initial state (position)
+for i=1:nobj
+  bnet.CPD{Xs(i)} = gaussian_CPD(bnet, Xs(i), 'mean', init_state{i}, 'cov', init_cov);
+end
+bnet.CPD{S} = root_CPD(bnet, S); % always observed
+bnet.CPD{Y} = gmux_CPD(bnet, Y, 'cov', repmat(R, [1 1 nobj]), 'weights', repmat(H, [1 1 nobj]));
+% slice 2
+eclass = bnet.equiv_class;
+for i=1:nobj
+  bnet.CPD{eclass(Xs(i), 2)} = gaussian_CPD(bnet, Xs(i)+N, 'mean', zeros(Xsz,1), 'cov', Q, 'weights', F);
+end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Create LDS params 
+
+% X(t) = A X(t-1) + B U(t) + noise(Q)
+
+% [L11]  = [1  ]  * [L1]       +   [Q ]
+% [L2]     [  1]    [L2]           [ Q]
+
+% Y(t)|S(t)=s  = C(s) X(t) + noise(R)
+% Yt|St=1 = [1 0]  * [L1]  + R
+%                    [L2]    
+
+nlandmarks = nobj;
+
+% Create indices into block structure
+bs = 2*ones(1, nobj); % sizes of blocks in state space
+for i=1:nlandmarks
+  landmark_block(:,i) = block(i, bs)';
+end
+Xsz = 2*(nlandmarks); % 2 values for each landmark plus robot
+Ysz = 2; % observe relative location
+
+% create block-diagonal trans matrix for each switch
+A = zeros(Xsz, Xsz);
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  A(bi, bi) = eye(2);
+end
+A = repmat(A, [1 1 nlandmarks]); % same for all switch values
+
+% create block-diagonal system cov
+Qbig = zeros(Xsz, Xsz);
+Qbig = repmat(Qbig, [1 1 nlandmarks]);
+
+
+% create observation matrix for each value of the switch node
+% C(:,:,i) = (0 ... I ...) where the I is in the i'th posn.
+C = zeros(Ysz, Xsz, nlandmarks);
+for i=1:nlandmarks
+  C(:, landmark_block(:,i), i) = eye(2);
+end
+
+% create observation cov for each value of the switch node
+Rbig = repmat(R, [1 1 nlandmarks]);
+
+% initial conditions
+init_x = [init_state{1}; init_state{2}];
+init_V = zeros(Xsz, Xsz);
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  init_V(bi,bi) = init_cov;
+end
+
+
+
+%%%%%%%%%%%%%%%%
+% Observe objects at random
+T = 10;
+evidence = cell(N, T);
+data_assoc = sample_discrete(normalise(ones(1,nobj)), 1, T);
+evidence(S,:) = num2cell(data_assoc);
+evidence = sample_dbn(bnet, 'evidence', evidence);
+
+
+% Inference
+ev = cell(N,T);
+ev(bnet.observed,:) = evidence(bnet.observed, :);
+y = cell2num(evidence(Y,:));
+
+engine = pearl_unrolled_dbn_inf_engine(bnet);
+engine = enter_evidence(engine, ev);
+
+loopy_est_pos = zeros(2, nlandmarks);
+loopy_est_pos_cov = zeros(2, 2, nlandmarks);
+for i=1:nobj
+  m = marginal_nodes(engine, Xs(i), T);
+  loopy_est_pos(:,i) = m.mu;
+  loopy_est_pos_cov(:,:,i) = m.Sigma;
+end
+
+
+[xsmooth, Vsmooth] = kalman_smoother(y, A, C, Qbig, Rbig, init_x, init_V, 'model', data_assoc);
+
+kf_est_pos = zeros(2, nlandmarks);
+kf_est_pos_cov = zeros(2, 2, nlandmarks);
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  kf_est_pos(:,i) = xsmooth(bi, T);
+  kf_est_pos_cov(:,:,i) = Vsmooth(bi, bi, T);
+end
+
+
+kf_est_pos
+loopy_est_pos
+
+kf_est_pos_time = zeros(2, nlandmarks, T);
+for t=1:T
+  for i=1:nlandmarks
+    bi = landmark_block(:,i);
+    kf_est_pos_time(:,i,t) = xsmooth(bi, t);
+  end
+end
+kf_est_pos_time % same for all t since smoothed
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/slam_kf.m b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/slam_kf.m
new file mode 100644
index 00000000..ba98140f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/Old/slam_kf.m
@@ -0,0 +1,172 @@
+% This is like robot1, except we only use a Kalman filter.
+% The goal is to study how the precision matrix changes.
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+if 0
+  T = 20;
+  ctrl_signal = [repmat([1 0]', 1, T/4) repmat([0 1]', 1, T/4) ...
+		 repmat([-1 0]', 1, T/4) repmat([0 -1]', 1, T/4)];
+else
+  T = 12;
+  ctrl_signal = repmat([1 0]', 1, T);
+end
+
+nlandmarks = 6;
+if 0
+  true_landmark_pos = [1 1;
+		    4 1;
+		    4 4;
+		    1 4]';
+else
+  true_landmark_pos = 10*rand(2,nlandmarks);
+end
+figure(1); clf
+hold on
+for i=1:nlandmarks
+  %text(true_landmark_pos(1,i), true_landmark_pos(2,i), sprintf('L%d',i));
+  plot(true_landmark_pos(1,i), true_landmark_pos(2,i), '*')
+end
+hold off
+
+init_robot_pos = [0 0]';
+
+true_robot_pos = zeros(2, T);
+true_data_assoc = zeros(1, T);
+true_rel_dist = zeros(2, T);
+for t=1:T
+  if t>1
+    true_robot_pos(:,t) = true_robot_pos(:,t-1) + ctrl_signal(:,t);
+  else
+    true_robot_pos(:,t) = init_robot_pos + ctrl_signal(:,t);
+  end
+  %nn = argmin(dist2(true_robot_pos(:,t)', true_landmark_pos'));
+  nn = wrap(t, nlandmarks); % observe 1, 2, 3, 4, 1, 2, ...
+  true_data_assoc(t) = nn;
+  true_rel_dist(:,t) = true_landmark_pos(:, nn) - true_robot_pos(:,t);
+end
+
+R = 1e-3*eye(2); % noise added to observation
+Q = 1e-3*eye(2); % noise added to robot motion
+
+% Create data set
+obs_noise_seq = sample_gaussian([0 0]', R, T)';
+obs_rel_pos = true_rel_dist + obs_noise_seq;
+%obs_rel_pos = true_rel_dist;
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Create params for inference
+
+% X(t) = A X(t-1) + B U(t) + noise(Q)
+
+% [L1]  = [1     ]  * [L1]       + [0]  * Ut  + [0   ]
+% [L2]    [  1   ]    [L2]         [0]          [ 0  ]
+% [R ]t   [     1]    [R ]t-1      [1]          [   Q]
+
+% Y(t)|S(t)=s  = C(s) X(t) + noise(R)
+% Yt|St=1 = [1 0 -1]  * [L1]  + R
+%                       [L2]    
+%                       [R ]    
+
+% Create indices into block structure
+bs = 2*ones(1, nlandmarks+1); % sizes of blocks in state space
+robot_block =  block(nlandmarks+1, bs);
+for i=1:nlandmarks
+  landmark_block(:,i) = block(i, bs)';
+end
+Xsz = 2*(nlandmarks+1); % 2 values for each landmark plus robot
+Ysz = 2; % observe relative location
+Usz = 2; % input is (dx, dy)
+
+
+% create block-diagonal trans matrix for each switch
+A = zeros(Xsz, Xsz);
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  A(bi, bi) = eye(2);
+end
+bi = robot_block;
+A(bi, bi) = eye(2);
+A = repmat(A, [1 1 nlandmarks]); % same for all switch values
+
+% create block-diagonal system cov
+
+
+Qbig = zeros(Xsz, Xsz);
+bi = robot_block;
+Qbig(bi,bi) = Q; % only add noise to robot motion
+Qbig = repmat(Qbig, [1 1 nlandmarks]);
+
+% create input matrix
+B = zeros(Xsz, Usz);
+B(robot_block,:) = eye(2); % only add input to robot position
+B = repmat(B, [1 1 nlandmarks]);
+
+% create observation matrix for each value of the switch node
+% C(:,:,i) = (0 ... I ... -I) where the I is in the i'th posn.
+% This computes L(i) - R
+C = zeros(Ysz, Xsz, nlandmarks);
+for i=1:nlandmarks
+  C(:, landmark_block(:,i), i) = eye(2); 
+  C(:, robot_block, i) = -eye(2);
+end
+
+% create observation cov for each value of the switch node
+Rbig = repmat(R, [1 1 nlandmarks]);
+
+% initial conditions
+init_x = zeros(Xsz, 1);
+init_v = zeros(Xsz, Xsz);
+bi = robot_block;
+init_x(bi) = init_robot_pos;
+init_V(bi, bi) = 1e-5*eye(2); % very sure of robot posn
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  init_V(bi,bi)= 1e5*eye(2); % very uncertain of landmark psosns
+  %init_x(bi) = true_landmark_pos(:,i);
+  %init_V(bi,bi)= 1e-5*eye(2); % very sure of landmark psosns
+end
+
+[xsmooth, Vsmooth] = kalman_filter(obs_rel_pos, A, C, Qbig, Rbig, init_x, init_V, ...
+				     'model', true_data_assoc, 'u', ctrl_signal, 'B', B);
+
+est_robot_pos = xsmooth(robot_block, :);
+est_robot_pos_cov = Vsmooth(robot_block, robot_block, :);
+
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  est_landmark_pos(:,i) = xsmooth(bi, T);
+  est_landmark_pos_cov(:,:,i) = Vsmooth(bi, bi, T);
+end
+
+
+
+P = zeros(size(Vsmooth));
+for t=1:T
+  P(:,:,t) = inv(Vsmooth(:,:,t));
+end
+
+figure(1)
+for t=1:T
+  subplot(T/2,2,t)
+  imagesc(P(1:2:end,1:2:end, t))
+  colorbar
+end
+
+figure(2)
+for t=1:T
+  subplot(T/2,2,t)
+  imagesc(Vsmooth(1:2:end,1:2:end, t))
+  colorbar
+end
+
+
+
+% marginalize out robot position and then check structure
+bi = landmark_block(:);
+V = Vsmooth(bi,bi,T); 
+P = inv(V);
+P(1:2:end,1:2:end)
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/mk_gmux_robot_dbn.m b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/mk_gmux_robot_dbn.m
new file mode 100644
index 00000000..8ee3a7ca
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/mk_gmux_robot_dbn.m
@@ -0,0 +1,85 @@
+function [bnet, Unode, Snode, Lnodes, Rnode, Ynode, Lsnode] = ...
+    mk_gmux_robot_dbn(nlandmarks, Q, R, init_x, init_V, robot_block, landmark_block)
+
+% Make DBN
+
+% S
+% | L1 -------> L1'
+% |  | L2 ----------> L2'
+% \  | /
+%  v v v
+%    Ls
+%    |
+%    v
+%    Y
+%    ^
+%    |
+%    R ------->  R'
+%    ^      
+%    |      
+%    U      
+%
+%
+% S is a switch, Ls is a deterministic gmux, Y = Ls-R,
+% R(t+1) = R(t) + U(t+1), L(t+1) = L(t)
+
+
+% number nodes topologically
+Snode = 1;
+Lnodes = 2:nlandmarks+1;
+Lsnode = nlandmarks+2;
+Unode = nlandmarks+3;
+Rnode = nlandmarks+4;
+Ynode = nlandmarks+5;
+
+nnodes = nlandmarks+5; 
+intra = zeros(nnodes, nnodes);
+intra([Snode Lnodes], Lsnode) =1;
+intra(Unode,Rnode)=1;
+intra([Rnode Lsnode], Ynode)=1;
+
+inter = zeros(nnodes, nnodes);
+inter(Rnode, Rnode)=1;
+for i=1:nlandmarks
+  inter(Lnodes(i), Lnodes(i))=1;
+end
+
+Lsz = 2; % (x y) posn of landmark
+Rsz = 2; % (x y) posn of robot
+Ysz = 2; % relative distance
+Usz = 2; % (dx dy) ctrl
+Ssz = nlandmarks; % can switch between any landmark
+
+ns = zeros(1,nnodes);
+ns(Snode) = Ssz;
+ns(Lnodes) = Lsz;
+ns(Lsnode) = Lsz;
+ns(Ynode) = Ysz;
+ns(Rnode) = Rsz;
+ns(Ynode) = Usz;
+ns(Unode) = Usz;
+
+bnet = mk_dbn(intra, inter, ns, 'discrete', Snode, 'observed', [Snode Ynode Unode]);
+
+
+bnet.CPD{Snode} = root_CPD(bnet, Snode); % always observed
+bnet.CPD{Unode} = root_CPD(bnet, Unode); % always observed
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  bnet.CPD{Lnodes(i)} = gaussian_CPD(bnet, Lnodes(i), 'mean', init_x(bi), 'cov', init_V(bi,bi));
+end
+bi = robot_block;
+bnet.CPD{Rnode} = gaussian_CPD(bnet, Rnode, 'mean', init_x(bi), 'cov', init_V(bi,bi), 'weights', eye(2));
+bnet.CPD{Lsnode} = gmux_CPD(bnet, Lsnode, 'cov', repmat(zeros(Lsz,Lsz), [1 1 nlandmarks]), ...
+			    'weights', repmat(eye(Lsz,Lsz), [1 1 nlandmarks]));
+W = [eye(2) -eye(2)]; % Y = Ls - R, where Ls is the lower-numbered parent
+bnet.CPD{Ynode} = gaussian_CPD(bnet, Ynode, 'mean', zeros(Ysz,1), 'cov', R, 'weights', W);
+
+% slice 2
+eclass = bnet.equiv_class;
+W = [eye(2) eye(2)]; % R(t) = R(t-1) + U(t), where R(t-1) is the lower-numbered parent
+bnet.CPD{eclass(Rnode,2)} = gaussian_CPD(bnet, Rnode+nnodes, 'mean', zeros(Rsz,1), 'cov', Q, 'weights', W);
+for i=1:nlandmarks
+  bnet.CPD{eclass(Lnodes(i), 2)} = gaussian_CPD(bnet, Lnodes(i)+nnodes, 'mean', zeros(2,1), ...
+						   'cov', zeros(2,2), 'weights', eye(2));
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/mk_linear_slam.m b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/mk_linear_slam.m
new file mode 100644
index 00000000..b8a819a2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/mk_linear_slam.m
@@ -0,0 +1,164 @@
+function [A,B,C,Q,R,Qbig,Rbig,init_x,init_V,robot_block,landmark_block,...
+	  true_landmark_pos, true_robot_pos, true_data_assoc, ...
+	  obs_rel_pos, ctrl_signal] = mk_linear_slam(varargin)
+
+% We create data from a linear system for testing SLAM algorithms.
+% i.e. , new robot pos = old robot pos + ctrl_signal, which is just a displacement vector.
+% and  observation = landmark_pos - robot_pos, which is just a displacement vector.
+%
+% The behavior is determined by the following optional arguments:
+%
+% 'nlandmarks' - num. landmarks
+% 'landmarks' - 'rnd' means random locations in the unit sqyare
+%               'square' means at [1 1], [4 1], [4 4] and [1 4]
+% 'T' - num steps to run
+% 'ctrl' - 'stationary' means the robot remains at [0 0],
+%          'leftright' means the robot receives a constant contol of [1 0],
+%          'square' means we navigate the robot around the square
+% 'data-assoc' - 'rnd' means we observe landmarks at random
+%                'nn' means we observe the nearest neighbor landmark
+%                'cycle' means we observe landmarks in order 1,2,.., 1, 2, ...
+
+args = varargin;
+% get mandatory params
+for i=1:2:length(args)
+  switch args{i},
+   case 'nlandmarks', nlandmarks = args{i+1};
+   case 'T', T = args{i+1};
+  end
+end
+
+% set defaults
+true_landmark_pos = rand(2,nlandmarks);
+true_data_assoc = [];
+
+% get args
+for i=1:2:length(args)
+  switch args{i},
+   case 'landmarks',
+    switch args{i+1},
+     case 'rnd',   true_landmark_pos = rand(2,nlandmarks);
+     case 'square',   true_landmark_pos = [1 1; 4 1; 4 4; 1 4]';
+    end
+   case 'ctrl',
+    switch args{i+1},
+     case 'stationary', ctrl_signal = repmat([0 0]', 1, T);
+     case 'leftright', ctrl_signal = repmat([1 0]', 1, T);
+     case 'square',   ctrl_signal = [repmat([1 0]', 1, T/4) repmat([0 1]', 1, T/4) ...
+		    repmat([-1 0]', 1, T/4) repmat([0 -1]', 1, T/4)];
+    end
+   case 'data-assoc', 
+    switch args{i+1},
+     case 'rnd', true_data_assoc  = sample_discrete(normalise(ones(1,nlandmarks)),1,T);
+     case 'cycle', true_data_assoc = wrap(1:T, nlandmarks);
+    end
+  end
+end
+if isempty(true_data_assoc)
+  use_nn = 1;
+else
+  use_nn = 0;
+end
+
+%%%%%%%%%%%%%%%%%%%%%%%%
+% generate data
+
+init_robot_pos = [0 0]';
+true_robot_pos = zeros(2, T);
+true_rel_dist = zeros(2, T);
+for t=1:T
+  if t>1
+    true_robot_pos(:,t) = true_robot_pos(:,t-1) + ctrl_signal(:,t);
+  else
+    true_robot_pos(:,t) = init_robot_pos + ctrl_signal(:,t);
+  end
+  nn = argmin(dist2(true_robot_pos(:,t)', true_landmark_pos'));
+  if use_nn
+    true_data_assoc(t) = nn;
+  end
+  true_rel_dist(:,t) = true_landmark_pos(:, nn) - true_robot_pos(:,t);
+end
+
+
+R = 1e-3*eye(2); % noise added to observation
+Q = 1e-3*eye(2); % noise added to robot motion
+
+% Create data set
+obs_noise_seq = sample_gaussian([0 0]', R, T)';
+obs_rel_pos = true_rel_dist + obs_noise_seq;
+%obs_rel_pos = true_rel_dist;
+
+%%%%%%%%%%%%%%%%%%
+% Create params
+
+
+% X(t) = A X(t-1) + B U(t) + noise(Q) 
+
+% [L1]  = [1     ]  * [L1]       + [0]  * Ut  + [0   ]
+% [L2]    [  1   ]    [L2]         [0]          [ 0  ]
+% [R ]t   [     1]    [R ]t-1      [1]          [   Q]
+
+% Y(t)|S(t)=s  = C(s) X(t) + noise(R)
+% Yt|St=1 = [1 0 -1]  * [L1]  + R
+%                       [L2]    
+%                       [R ]    
+
+% Create indices into block structure
+bs = 2*ones(1, nlandmarks+1); % sizes of blocks in state space
+robot_block =  block(nlandmarks+1, bs);
+for i=1:nlandmarks
+  landmark_block(:,i) = block(i, bs)';
+end
+Xsz = 2*(nlandmarks+1); % 2 values for each landmark plus robot
+Ysz = 2; % observe relative location
+Usz = 2; % input is (dx, dy)
+
+
+% create block-diagonal trans matrix for each switch
+A = zeros(Xsz, Xsz);
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  A(bi, bi) = eye(2);
+end
+bi = robot_block;
+A(bi, bi) = eye(2);
+A = repmat(A, [1 1 nlandmarks]); % same for all switch values
+
+% create block-diagonal system cov
+
+
+Qbig = zeros(Xsz, Xsz);
+bi = robot_block;
+Qbig(bi,bi) = Q; % only add noise to robot motion
+Qbig = repmat(Qbig, [1 1 nlandmarks]);
+
+% create input matrix
+B = zeros(Xsz, Usz);
+B(robot_block,:) = eye(2); % only add input to robot position
+B = repmat(B, [1 1 nlandmarks]);
+
+% create observation matrix for each value of the switch node
+% C(:,:,i) = (0 ... I ... -I) where the I is in the i'th posn.
+% This computes L(i) - R
+C = zeros(Ysz, Xsz, nlandmarks);
+for i=1:nlandmarks
+  C(:, landmark_block(:,i), i) = eye(2); 
+  C(:, robot_block, i) = -eye(2);
+end
+
+% create observation cov for each value of the switch node
+Rbig = repmat(R, [1 1 nlandmarks]);
+
+% initial conditions
+init_x = zeros(Xsz, 1);
+init_v = zeros(Xsz, Xsz);
+bi = robot_block;
+init_x(bi) = init_robot_pos;
+%init_V(bi, bi) = 1e-5*eye(2); % very sure of robot posn
+init_V(bi, bi) = Q; % simualate uncertainty due to 1 motion step
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  init_V(bi,bi)= 1e5*eye(2); % very uncertain of landmark psosns
+  %init_x(bi) = true_landmark_pos(:,i);
+  %init_V(bi,bi)= 1e-5*eye(2); % very sure of landmark psosns
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_kf.m b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_kf.m
new file mode 100644
index 00000000..9844352b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_kf.m
@@ -0,0 +1,78 @@
+% Plot how precision matrix changes over time for KF solution
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+[A,B,C,Q,R,Qbig,Rbig,init_x,init_V,robot_block,landmark_block,...
+	  true_landmark_pos, true_robot_pos, true_data_assoc, ...
+	  obs_rel_pos, ctrl_signal] = mk_linear_slam(...
+	      'nlandmarks', 6, 'T', 12, 'ctrl', 'leftright', 'data-assoc', 'cycle');
+
+figure(1); clf
+hold on
+for i=1:nlandmarks
+  %text(true_landmark_pos(1,i), true_landmark_pos(2,i), sprintf('L%d',i));
+  plot(true_landmark_pos(1,i), true_landmark_pos(2,i), '*')
+end
+hold off
+
+
+[x, V] = kalman_filter(obs_rel_pos, A, C, Qbig, Rbig, init_x, init_V, ...
+				     'model', true_data_assoc, 'u', ctrl_signal, 'B', B);
+
+est_robot_pos = x(robot_block, :);
+est_robot_pos_cov = V(robot_block, robot_block, :);
+
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  est_landmark_pos(:,i) = x(bi, T);
+  est_landmark_pos_cov(:,:,i) = V(bi, bi, T);
+end
+
+
+if 0
+figure(1); hold on
+for i=1:nlandmarks
+  h=plotgauss2d(est_landmark_pos(:,i), est_landmark_pos_cov(:,:,i));
+  set(h, 'color', 'r')
+end
+hold off
+
+hold on
+for t=1:T
+  h=plotgauss2d(est_robot_pos(:,t), est_robot_pos_cov(:,:,t));
+  set(h,'color','r')
+  h=text(est_robot_pos(1,t), est_robot_pos(2,2), sprintf('R%d', t));
+  set(h,'color','r')
+end
+hold off
+end
+
+
+P = zeros(size(V));
+for t=1:T
+  P(:,:,t) = inv(V(:,:,t));
+end
+
+if 0
+  figure(2)
+  for t=1:T
+    subplot(T/2,2,t)
+    imagesc(P(1:2:end,1:2:end, t))
+    colorbar
+  end
+else
+  figure(2)
+  for t=1:T
+    subplot(T/2,2,t)
+    imagesc(V(1:2:end,1:2:end, t))
+    colorbar
+  end
+end
+
+% marginalize out robot position and then check structure
+bi = landmark_block(:);
+V = V(bi,bi,T); 
+P = inv(V);
+P(1:2:end,1:2:end)
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_offline_loopy.m b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_offline_loopy.m
new file mode 100644
index 00000000..6abc0fe0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_offline_loopy.m
@@ -0,0 +1,59 @@
+% Compare Kalman smoother with loopy
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+nlandmarks = 6;
+T = 12;
+
+[A,B,C,Q,R,Qbig,Rbig,init_x,init_V,robot_block,landmark_block,...
+	  true_landmark_pos, true_robot_pos, true_data_assoc, ...
+	  obs_rel_pos, ctrl_signal] = mk_linear_slam(...
+	      'nlandmarks', nlandmarks, 'T', T, 'ctrl', 'leftright', 'data-assoc', 'cycle');
+
+[xsmooth, Vsmooth] = kalman_smoother(obs_rel_pos, A, C, Qbig, Rbig, init_x, init_V, ...
+				     'model', true_data_assoc, 'u', ctrl_signal, 'B', B);
+
+est_robot_pos = xsmooth(robot_block, :);
+est_robot_pos_cov = Vsmooth(robot_block, robot_block, :);
+
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  est_landmark_pos(:,i) = xsmooth(bi, T);
+  est_landmark_pos_cov(:,:,i) = Vsmooth(bi, bi, T);
+end
+
+
+if 1
+  [bnet, Unode, Snode, Lnodes, Rnode, Ynode, Lsnode] = ...
+      mk_gmux_robot_dbn(nlandmarks, Q, R, init_x, init_V, robot_block, landmark_block);
+  engine = pearl_unrolled_dbn_inf_engine(bnet, 'max_iter', 50, 'filename', ...
+					 '/home/eecs/murphyk/matlab/loopyslam.txt');
+else
+  [bnet, Unode, Snode, Lnodes, Rnode, Ynode] = ...
+      mk_gmux2_robot_dbn(nlandmarks, Q, R, init_x, init_V, robot_block, landmark_block);
+  engine = jtree_dbn_inf_engine(bnet);
+end
+
+nnodes = bnet.nnodes_per_slice;
+evidence = cell(nnodes, T);
+evidence(Ynode, :) = num2cell(obs_rel_pos, 1);
+evidence(Unode, :) = num2cell(ctrl_signal, 1);
+evidence(Snode, :) = num2cell(true_data_assoc);
+
+[engine, ll, niter] = enter_evidence(engine, evidence);
+niter
+
+loopy_est_robot_pos = zeros(2, T);
+for t=1:T
+  m = marginal_nodes(engine, Rnode, t);
+  loopy_est_robot_pos(:,t) = m.mu;
+end
+
+for i=1:nlandmarks
+  m = marginal_nodes(engine, Lnodes(i), T);
+  loopy_est_landmark_pos(:,i) = m.mu;
+  loopy_est_landmark_pos_cov(:,:,i) = m.Sigma;
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_partial_kf.m b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_partial_kf.m
new file mode 100644
index 00000000..3fe998be
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_partial_kf.m
@@ -0,0 +1,107 @@
+% See how well partial Kalman filter updates work
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+nlandmarks = 6;
+T = 12;
+
+[A,B,C,Q,R,Qbig,Rbig,init_x,init_V,robot_block,landmark_block,...
+	  true_landmark_pos, true_robot_pos, true_data_assoc, ...
+	  obs_rel_pos, ctrl_signal] = mk_linear_slam(...
+	      'nlandmarks', nlandmarks, 'T', T, 'ctrl', 'leftright', 'data-assoc', 'cycle');
+
+% exact
+[xe, Ve] = kalman_filter(obs_rel_pos, A, C, Qbig, Rbig, init_x, init_V, ...
+				     'model', true_data_assoc, 'u', ctrl_signal, 'B', B);
+
+
+% approx
+%k = nlandmarks-1; % exact
+k = 3;
+ndx = {};
+for t=1:T
+  landmarks = unique(true_data_assoc(t:-1:max(t-k,1)));
+  tmp = [landmark_block(:, landmarks) robot_block'];
+  ndx{t} = tmp(:);
+end
+
+[xa, Va] = kalman_filter(obs_rel_pos, A, C, Qbig, Rbig, init_x, init_V, ...
+			 'model', true_data_assoc, 'u', ctrl_signal, 'B', B, ...
+		       'ndx', ndx);
+
+
+
+nrows = 10;
+stepsize = T/(2*nrows);
+ts = 1:stepsize:T;
+
+if 1 % plot
+  
+clim = [0 max(max(Va(:,:,end)))];
+
+figure(2)
+if 0
+  imagesc(Ve(1:2:end,1:2:end, T))
+  clim = get(gca,'clim');
+else
+  i = 1;
+  for t=ts(:)'
+    subplot(nrows,2,i)
+    i = i + 1;
+    imagesc(Ve(1:2:end,1:2:end, t))
+    set(gca, 'clim', clim)
+    colorbar
+  end
+end
+suptitle('exact')
+
+
+figure(3)
+if 0
+  imagesc(Va(1:2:end,1:2:end, T))
+  set(gca,'clim', clim)
+else
+  i = 1;
+  for t=ts(:)'
+    subplot(nrows,2,i)
+    i = i+1;
+    imagesc(Va(1:2:end,1:2:end, t))
+    set(gca, 'clim', clim)
+    colorbar
+  end
+end
+suptitle('approx')
+
+
+figure(4)
+i = 1;
+for t=ts(:)'
+  subplot(nrows,2,i)
+  i = i+1;
+  Vd = Va(1:2:end,1:2:end, t) - Ve(1:2:end,1:2:end,t);
+  imagesc(Vd)
+  set(gca, 'clim', clim)
+  colorbar
+end
+suptitle('diff')
+
+end % all plot
+
+
+for t=1:T
+  %err(t)=rms(xa(:,t), xe(:,t));
+  err(t)=rms(xa(1:end-2,t), xe(1:end-2,t)); % exclude robot
+end
+figure(5);plot(err)
+title('rms mean pos')
+
+
+for t=1:T
+  i = 1:2*nlandmarks;
+  denom = Ve(i,i,t) + (Ve(i,i,t)==0);
+  Vd =(Va(i,i,t)-Ve(i,i,t)) ./ denom;
+  Verr(t) = max(Vd(:));
+end
+figure(6); plot(Verr)
+title('max relative Verr')
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_stationary_loopy.m b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_stationary_loopy.m
new file mode 100644
index 00000000..0272d3f6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/SLAM/slam_stationary_loopy.m
@@ -0,0 +1,155 @@
+% This is like skf_data_assoc_gmux, except the objects don't move.
+% We are uncertain of their initial positions, and get more and more observations
+% over time. The goal is to test deterministic links (0 covariance).
+% This is like robot1, except the robot doesn't move and is always at [0 0],
+% so the relative location is simply L(s).
+
+nobj = 2;
+N = nobj+2;
+Xs = 1:nobj;
+S = nobj+1;
+Y = nobj+2;
+
+intra = zeros(N,N);
+inter = zeros(N,N);
+intra([Xs S], Y) =1;
+for i=1:nobj
+  inter(Xs(i), Xs(i))=1;
+end
+
+Xsz = 2; % state space = (x y)
+Ysz = 2;
+ns = zeros(1,N);
+ns(Xs) = Xsz;
+ns(Y) = Ysz;
+ns(S) = nobj;
+
+bnet = mk_dbn(intra, inter, ns, 'discrete', S, 'observed', [S Y]);
+
+% For each object, we have
+% X(t+1) = F X(t) + noise(Q)
+% Y(t) = H X(t) + noise(R)
+F = eye(2);
+H = eye(2);
+Q = 0*eye(Xsz); % no noise in dynamics
+R = eye(Ysz);
+
+init_state{1} = [10 10]';
+init_state{2} = [10 -10]';
+init_cov = eye(2);
+
+% Uncertain of initial state (position)
+for i=1:nobj
+  bnet.CPD{Xs(i)} = gaussian_CPD(bnet, Xs(i), 'mean', init_state{i}, 'cov', init_cov);
+end
+bnet.CPD{S} = root_CPD(bnet, S); % always observed
+bnet.CPD{Y} = gmux_CPD(bnet, Y, 'cov', repmat(R, [1 1 nobj]), 'weights', repmat(H, [1 1 nobj]));
+% slice 2
+eclass = bnet.equiv_class;
+for i=1:nobj
+  bnet.CPD{eclass(Xs(i), 2)} = gaussian_CPD(bnet, Xs(i)+N, 'mean', zeros(Xsz,1), 'cov', Q, 'weights', F);
+end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Create LDS params 
+
+% X(t) = A X(t-1) + B U(t) + noise(Q)
+
+% [L11]  = [1  ]  * [L1]       +   [Q ]
+% [L2]     [  1]    [L2]           [ Q]
+
+% Y(t)|S(t)=s  = C(s) X(t) + noise(R)
+% Yt|St=1 = [1 0]  * [L1]  + R
+%                    [L2]    
+
+nlandmarks = nobj;
+
+% Create indices into block structure
+bs = 2*ones(1, nobj); % sizes of blocks in state space
+for i=1:nlandmarks
+  landmark_block(:,i) = block(i, bs)';
+end
+Xsz = 2*(nlandmarks); % 2 values for each landmark plus robot
+Ysz = 2; % observe relative location
+
+% create block-diagonal trans matrix for each switch
+A = zeros(Xsz, Xsz);
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  A(bi, bi) = eye(2);
+end
+A = repmat(A, [1 1 nlandmarks]); % same for all switch values
+
+% create block-diagonal system cov
+Qbig = zeros(Xsz, Xsz);
+Qbig = repmat(Qbig, [1 1 nlandmarks]);
+
+
+% create observation matrix for each value of the switch node
+% C(:,:,i) = (0 ... I ...) where the I is in the i'th posn.
+C = zeros(Ysz, Xsz, nlandmarks);
+for i=1:nlandmarks
+  C(:, landmark_block(:,i), i) = eye(2);
+end
+
+% create observation cov for each value of the switch node
+Rbig = repmat(R, [1 1 nlandmarks]);
+
+% initial conditions
+init_x = [init_state{1}; init_state{2}];
+init_V = zeros(Xsz, Xsz);
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  init_V(bi,bi) = init_cov;
+end
+
+
+
+%%%%%%%%%%%%%%%%
+% Observe objects at random
+T = 10;
+evidence = cell(N, T);
+data_assoc = sample_discrete(normalise(ones(1,nobj)), 1, T);
+evidence(S,:) = num2cell(data_assoc);
+evidence = sample_dbn(bnet, 'evidence', evidence);
+
+
+% Inference
+ev = cell(N,T);
+ev(bnet.observed,:) = evidence(bnet.observed, :);
+y = cell2num(evidence(Y,:));
+
+engine = pearl_unrolled_dbn_inf_engine(bnet);
+engine = enter_evidence(engine, ev);
+
+loopy_est_pos = zeros(2, nlandmarks);
+loopy_est_pos_cov = zeros(2, 2, nlandmarks);
+for i=1:nobj
+  m = marginal_nodes(engine, Xs(i), T);
+  loopy_est_pos(:,i) = m.mu;
+  loopy_est_pos_cov(:,:,i) = m.Sigma;
+end
+
+
+[xsmooth, Vsmooth] = kalman_smoother(y, A, C, Qbig, Rbig, init_x, init_V, 'model', data_assoc);
+
+kf_est_pos = zeros(2, nlandmarks);
+kf_est_pos_cov = zeros(2, 2, nlandmarks);
+for i=1:nlandmarks
+  bi = landmark_block(:,i);
+  kf_est_pos(:,i) = xsmooth(bi, T);
+  kf_est_pos_cov(:,:,i) = Vsmooth(bi, bi, T);
+end
+
+
+kf_est_pos
+loopy_est_pos
+
+kf_est_pos_time = zeros(2, nlandmarks, T);
+for t=1:T
+  for i=1:nlandmarks
+    bi = landmark_block(:,i);
+    kf_est_pos_time(:,i,t) = xsmooth(bi, t);
+  end
+end
+kf_est_pos_time % same for all t since smoothed
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/arhmm1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/arhmm1.m
new file mode 100644
index 00000000..ac1f7fce
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/arhmm1.m
@@ -0,0 +1,42 @@
+% Make an HMM with autoregressive Gaussian observations (switching AR model)
+%   X1 -> X2
+%   |     | 
+%   v     v
+%   Y1 -> Y2 
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+intra = zeros(2);
+intra(1,2) = 1;
+inter = zeros(2);
+inter(1,1) = 1;
+inter(2,2) = 1;
+n = 2;
+
+Q = 2; % num hidden states
+O = 2; % size of observed vector
+
+ns = [Q O];
+dnodes = 1;
+onodes = [2];
+bnet = mk_dbn(intra, inter, ns, 'discrete', dnodes, 'observed', onodes);
+
+bnet.CPD{1} = tabular_CPD(bnet, 1);
+bnet.CPD{2} = gaussian_CPD(bnet, 2);
+bnet.CPD{3} = tabular_CPD(bnet, 3);
+bnet.CPD{4} = gaussian_CPD(bnet, 4);
+
+
+T = 10; % fixed length sequences
+
+engine = {};
+%engine{end+1} = hmm_inf_engine(bnet);
+engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T);
+%engine{end+1} = smoother_engine(hmm_2TBN_inf_engine(bnet));
+%engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet));
+
+inf_time = cmp_inference_dbn(bnet, engine, T, 'check_ll',1);
+learning_time = cmp_learning_dbn(bnet, engine, T, 'check_ll', 1);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/bat1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/bat1.m
new file mode 100644
index 00000000..3b24e144
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/bat1.m
@@ -0,0 +1,44 @@
+% Compare the speeds of various inference engines on the BAT DBN
+[bnet, names] = mk_bat_dbn;
+
+T = 3; % fixed length sequence - we make it short just for speed
+
+USEC = exist('@jtree_C_inf_engine/collect_evidence','file');
+
+disp('constructing engines for BAT');
+engine = {}; % time in seconds for inference
+engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T, 'useC', USEC);  % 0.39
+engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet)); % 4.89
+engine{end+1} = jtree_dbn_inf_engine(bnet); % 4.45
+if 0
+engine{end+1} = jtree_ndx_dbn_inf_engine(bnet, 'ndx_type', 'SD'); % 2.98
+engine{end+1} = jtree_ndx_dbn_inf_engine(bnet, 'ndx_type', 'D'); % 3.52
+engine{end+1} = jtree_ndx_dbn_inf_engine(bnet, 'ndx_type', 'B'); % 2.40
+if USEC, engine{end+1} = jtree_C_dbn_inf_engine(bnet); end % 3.54
+%engine{end+1} = hmm_inf_engine(bnet, onodes); % too big
+end
+
+%tic; engine{end+1} = frontier_inf_engine(bnet); toc % very slow
+% The frontier engine thrashes badly on the BAT network
+%tic; engine{end+1} = bk_inf_engine(bnet, 'exact', onodes); toc  % SLOW!
+
+%tic; engine{end+1} = bk_inf_engine(bnet, 'ff', onodes); toc
+
+%clusters{1} = [stringmatch({'LeftClr', 'RightClr', 'LatAct', 'Xdot', 'InLane'}, names)];
+%clusters{2} = [stringmatch({'FwdAct', 'Ydot', 'Stopped', 'EngStatus', 'FBStatus'}, names)];      
+
+%tic; engine{end+1} = bk_inf_engine(bnet, clusters, onodes); toc
+
+disp('inference')
+time = cmp_inference_dbn(bnet, engine, T)
+
+disp('learning')
+time = cmp_learning_dbn(bnet, engine, T)
+
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/bkff1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/bkff1.m
new file mode 100644
index 00000000..c5b62332
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/bkff1.m
@@ -0,0 +1,23 @@
+% Compare different implementations of fully factored Boyen Koller
+
+water = 1;
+if water
+  bnet = mk_water_dbn;
+else
+  N = 5;
+  Q = 2;
+  Y = 2;
+  bnet = mk_chmm(N, Q, Y);
+end
+ss = length(bnet.intra);
+
+engine = {};
+engine{end+1} = bk_inf_engine(bnet, 'clusters', 'ff');        
+engine{end+1} = bk_ff_hmm_inf_engine(bnet);   
+E = length(engine);
+
+T = 5;
+time = cmp_inference_dbn(bnet, engine, T, 'singletons_only', 1)
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/chmm1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/chmm1.m
new file mode 100644
index 00000000..10df79d8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/chmm1.m
@@ -0,0 +1,41 @@
+% Compare the speeds of various inference engines on a coupled HMM
+
+N = 3;
+Q = 2;
+rand('state', 0);
+randn('state', 0);
+discrete = 0;
+if discrete
+  Y = 2; % size of output alphabet
+else
+  Y = 3; % size of observed vectors
+end
+coupled = 1;
+bnet = mk_chmm(N, Q, Y, discrete, coupled); 
+%bnet = mk_fhmm(N, Q, Y, discrete);  % factorial HMM
+ss = length(bnet.node_sizes_slice);
+
+T = 3;
+
+USEC = exist('@jtree_C_inf_engine/collect_evidence','file');
+
+engine = {};
+engine{end+1} = jtree_dbn_inf_engine(bnet);
+%engine{end+1} = jtree_ndx_dbn_inf_engine(bnet, 'ndx_type', 'SD');
+%engine{end+1} = jtree_ndx_dbn_inf_engine(bnet, 'ndx_type', 'D');
+%engine{end+1} = jtree_ndx_dbn_inf_engine(bnet, 'ndx_type', 'B');
+if USEC, engine{end+1} = jtree_C_dbn_inf_engine(bnet); end
+engine{end+1} = hmm_inf_engine(bnet);
+engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T); 
+
+% times in matlab N=4 Q=4 T=5 (* = winner)
+%     jtree    SD       B          hmm       dhmm      unrolled
+%    0.6266    1.1563    8.3815    0.3069    0.1948*    0.8654  inf
+%    0.9057*   2.1522   12.6314    2.6847    2.3107    3.1905  learn
+
+%engine{end+1} = bk_inf_engine(bnet, 'ff', onodes);
+%engine{end+1} = pearl_unrolled_dbn_inf_engine(bnet, T);
+
+inf_time = cmp_inference_dbn(bnet, engine, T)
+learning_time = cmp_learning_dbn(bnet, engine, T)
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/cmp_inference_dbn.m b/sourcecodes/bnt-master/BNT/examples/dynamic/cmp_inference_dbn.m
new file mode 100644
index 00000000..da54095f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/cmp_inference_dbn.m
@@ -0,0 +1,100 @@
+function [time, engine] = cmp_inference_dbn(bnet, engine, T, varargin)
+% CMP_INFERENCE_DBN Compare several inference engines on a DBN
+% function [time, engine] = cmp_inference_dbn(bnet, engine, T, ...)
+%
+% engine{i} is the i'th inference engine.
+% time(e) = elapsed time for doing inference with engine e
+%
+% The list below gives optional arguments [default value in brackets].
+%
+% exact - specifies which engines do exact inference [ 1:length(engine) ]
+% singletons_only - if 1, we only call marginal_nodes, else this  and marginal_family [0]
+% check_ll - 1 means we check that the log-likelihoods are correct [1]
+
+% set default params
+exact = 1:length(engine);
+singletons_only = 0;
+check_ll = 1;
+onodes = bnet.observed;
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'exact', exact = args{i+1};
+   case 'singletons_only', singletons_only = args{i+1};
+   case 'check_ll', check_ll = args{i+1};
+   case 'observed', onodes = args{i+1};
+   otherwise,
+    error(['unrecognized argument ' args{i}])
+  end
+end
+
+E = length(engine);
+ref = exact(1); % reference
+
+ss = length(bnet.intra);
+ev = sample_dbn(bnet, 'length', T);
+evidence = cell(ss,T);
+evidence(onodes,:) = ev(onodes, :);
+
+for i=1:E
+  tic;
+  [engine{i}, ll(i)] = enter_evidence(engine{i}, evidence);
+  time(i)=toc;
+  fprintf('engine %d took %6.4f seconds\n', i, time(i));
+end
+
+cmp = mysetdiff(exact, ref);
+if check_ll
+  for i=cmp(:)'
+    if ~approxeq(ll(ref), ll(i))
+      error(['engine ' num2str(i) ' has wrong ll'])
+    end
+  end
+end
+ll
+
+hnodes = mysetdiff(1:ss, onodes);
+
+if ~singletons_only
+  get_marginals(engine, hnodes, exact, 0, T);
+end
+get_marginals(engine, hnodes, exact, 1, T);
+
+%%%%%%%%%%
+
+function get_marginals(engine, hnodes, exact, singletons, T)
+
+bnet = bnet_from_engine(engine{1});
+N = length(bnet.intra);
+cnodes_bitv = zeros(1,N);
+cnodes_bitv(bnet.cnodes) = 1;
+ref = exact(1); % reference
+cmp = exact(2:end);
+E = length(engine);
+m = cell(1,E);
+
+for t=1:T
+  for n=1:N
+  %for n=hnodes(:)'
+    for e=1:E
+      if singletons
+	m{e} = marginal_nodes(engine{e}, n, t);
+      else
+	m{e} = marginal_family(engine{e}, n, t);
+      end
+    end
+    for e=cmp(:)'
+      assert(isequal(m{e}.domain, m{ref}.domain));
+      if cnodes_bitv(n) & isfield(m{e}, 'mu') & isfield(m{ref}, 'mu')
+	wrong = ~approxeq(m{ref}.mu, m{e}.mu) | ~approxeq(m{ref}.Sigma, m{e}.Sigma);
+      else
+	wrong = ~approxeq(m{ref}.T(:), m{e}.T(:));
+      end
+      if wrong
+	error(sprintf('engine %d is wrong; n=%d, t=%d, fam=%d', e, n, t, ~singletons))
+      end
+    end
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/cmp_learning_dbn.m b/sourcecodes/bnt-master/BNT/examples/dynamic/cmp_learning_dbn.m
new file mode 100644
index 00000000..d6138f9d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/cmp_learning_dbn.m
@@ -0,0 +1,89 @@
+function [time, CPD, LL, cases] = cmp_learning_dbn(bnet, engine, T, varargin)
+% CMP_LEARNING_DBN Compare a bunch of inference engines by learning a DBN
+% function [time, CPD, LL, cases] = cmp_learning_dbn(bnet, engine, exact, T, ncases, max_iter)
+%
+% engine{i} is the i'th inference engine.
+% time(e) = elapsed time for doing inference with engine e
+% CPD{e,c} is the learned CPD for eclass c in engine e
+% LL{e} is the learning curve for engine e
+% cases{i} is the i'th training case
+%
+% The list below gives optional arguments [default value in brackets].
+%
+% exact - specifies which engines do exact inference [ 1:length(engine) ]
+% check_ll - 1 means we check that the log-likelihoods are correct [1]
+% ncases - num. random training cases [2]
+% max_iter - max. num EM iterations [2]
+
+% set default params
+exact = 1:length(engine);
+check_ll = 1;
+ncases = 2;
+max_iter = 2;
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'exact', exact = args{i+1};
+   case 'check_ll', check_ll = args{i+1};
+   case 'ncases', ncases = args{i+1};
+   case 'max_iter', max_iter = args{i+1};
+   otherwise,
+    error(['unrecognized argument ' args{i}])
+  end
+end
+
+E = length(engine);
+ss = length(bnet.intra);
+onodes = bnet.observed;
+
+cases = cell(1, ncases);
+for i=1:ncases
+  ev = sample_dbn(bnet, 'length', T);
+  cases{i} = cell(ss,T);
+  cases{i}(onodes,:) = ev(onodes, :);
+end
+
+LL = cell(1,E);
+time = zeros(1,E);
+for i=1:E
+  tic
+  [bnet2{i}, LL{i}] = learn_params_dbn_em(engine{i}, cases, 'max_iter', max_iter);
+  time(i) = toc;
+  fprintf('engine %d took %6.4f seconds\n', i, time(i));
+end
+
+ref = exact(1); % reference
+cmp = mysetdiff(exact, ref);
+if check_ll
+  for i=cmp(:)'
+    if ~approxeq(LL{ref}, LL{i})
+      error(['engine ' num2str(i) ' has wrong ll'])
+    end
+  end
+end
+
+nCPDs = length(bnet.CPD);
+CPD = cell(E, nCPDs);
+tabular = zeros(1, nCPDs);
+for i=1:E
+  temp = bnet2{i};
+  for c=1:nCPDs
+    tabular(c) = isa(temp.CPD{c}, 'tabular_CPD');
+    CPD{i,c} = struct(temp.CPD{c});
+  end
+end
+
+for i=cmp(:)'
+  for c=1:nCPDs
+    if tabular(c)
+      assert(approxeq(CPD{i,c}.CPT, CPD{ref,c}.CPT));
+    else
+      assert(approxeq(CPD{i,c}.mean, CPD{ref,c}.mean));
+      assert(approxeq(CPD{i,c}.cov, CPD{ref,c}.cov));
+      assert(approxeq(CPD{i,c}.weights, CPD{ref,c}.weights));
+    end
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/cmp_online_inference.m b/sourcecodes/bnt-master/BNT/examples/dynamic/cmp_online_inference.m
new file mode 100644
index 00000000..5360d120
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/cmp_online_inference.m
@@ -0,0 +1,97 @@
+function [time, engine] = cmp_online_inference(bnet, engine, T, varargin)
+% CMP_ONLINE_INFERENCE Compare several online inference engines on a DBN
+% function [time, engine] = cmp_online_inference(bnet, engine, T, ...)
+%
+% engine{i} is the i'th inference engine.
+% time(e) = elapsed time for doing inference with engine e
+%
+% The list below gives optional arguments [default value in brackets].
+%
+% exact - specifies which engines do exact inference [ 1:length(engine) ]
+% singletons_only - if 1, we only call marginal_nodes, else this  and marginal_family [0]
+% check_ll - 1 means we check that the log-likelihoods are correct [1]
+
+% set default params
+exact = 1:length(engine);
+singletons_only = 0;
+check_ll = 1;
+onodes = bnet.observed;
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'exact', exact = args{i+1};
+   case 'singletons_only', singletons_only = args{i+1};
+   case 'check_ll', check_ll = args{i+1};
+   case 'observed', onodes = args{i+1};
+   otherwise,
+    error(['unrecognized argument ' args{i}])
+  end
+end
+
+E = length(engine);
+ref = exact(1); % reference
+cmp = mysetdiff(exact, ref);
+
+ss = length(bnet.intra);
+hnodes = mysetdiff(1:ss, onodes);
+ev = sample_dbn(bnet, 'length', T);
+evidence = cell(ss,T);
+evidence(onodes,:) = ev(onodes, :);
+
+time = zeros(1,E);
+for t=1:T
+  for e=1:E
+    tic;
+    [engine{e}, ll(e)] = enter_evidence(engine{e}, evidence(:,t), t);
+    time(e)= time(e) + toc;
+  end
+  if check_ll
+    for e=cmp(:)'
+      if ~approxeq(ll(ref), ll(e))
+	error(['engine ' num2str(e) ' has wrong ll'])
+      end
+    end
+  end
+  if ~singletons_only
+    check_marginals(engine, hnodes, exact, 0, t);
+  end
+  check_marginals(engine, hnodes, exact, 1, t);
+end
+
+
+%%%%%%%%%%
+
+function check_marginals(engine, hnodes, exact, singletons, t)
+
+bnet = bnet_from_engine(engine{1});
+N = length(bnet.intra);
+cnodes_bitv = zeros(1,N);
+cnodes_bitv(bnet.cnodes) = 1;
+ref = exact(1); % reference
+cmp = exact(2:end);
+E = length(engine);
+m = cell(1,E);
+
+for n=1:N
+  %for n=hnodes(:)'
+  for e=1:E
+    if singletons
+      m{e} = marginal_nodes(engine{e}, n, t);
+    else
+      m{e} = marginal_family(engine{e}, n, t);
+    end
+  end
+  for e=cmp(:)'
+    assert(isequal(m{e}.domain, m{ref}.domain));
+    if cnodes_bitv(n) & isfield(m{e}, 'mu') & isfield(m{ref}, 'mu')
+      wrong = ~approxeq(m{ref}.mu, m{e}.mu) | ~approxeq(m{ref}.Sigma, m{e}.Sigma);
+    else
+      wrong = ~approxeq(m{ref}.T(:), m{e}.T(:));
+    end
+    if wrong
+      error(sprintf('engine %d is wrong; n=%d, t=%d, fam=%d', e, n, t, ~singletons))
+    end
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/dhmm1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/dhmm1.m
new file mode 100644
index 00000000..a3c4084d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/dhmm1.m
@@ -0,0 +1,66 @@
+% Make an HMM with discrete observations
+%   X1 -> X2
+%   |     | 
+%   v     v
+%   Y1    Y2 
+
+intra = zeros(2);
+intra(1,2) = 1;
+inter = zeros(2);
+inter(1,1) = 1;
+n = 2;
+
+Q = 2; % num hidden states
+O = 2; % num observable symbols
+
+ns = [Q O];
+dnodes = 1:2;
+onodes = [2];
+eclass1 = [1 2];
+eclass2 = [3 2];
+bnet = mk_dbn(intra, inter, ns, 'discrete', dnodes, 'eclass1', eclass1, 'eclass2', eclass2, ...
+	      'observed', onodes);
+
+rand('state', 0);
+prior1 = normalise(rand(Q,1));
+transmat1 = mk_stochastic(rand(Q,Q));
+obsmat1 = mk_stochastic(rand(Q,O));
+bnet.CPD{1} = tabular_CPD(bnet, 1, prior1);
+bnet.CPD{2} = tabular_CPD(bnet, 2, obsmat1);
+bnet.CPD{3} = tabular_CPD(bnet, 3, transmat1);
+
+
+T = 5; % fixed length sequences
+
+engine = {};
+engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T);
+engine{end+1} = hmm_inf_engine(bnet);
+engine{end+1} = smoother_engine(hmm_2TBN_inf_engine(bnet));
+engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet));
+if 1
+%engine{end+1} = frontier_inf_engine(bnet); % broken
+engine{end+1} = bk_inf_engine(bnet, 'clusters', {[1]});
+engine{end+1} = jtree_dbn_inf_engine(bnet);
+end
+
+inf_time = cmp_inference_dbn(bnet, engine, T);
+
+ncases = 2;
+max_iter = 2;
+[learning_time, CPD, LL, cases] = cmp_learning_dbn(bnet, engine, T, 'ncases', ncases, 'max_iter', max_iter);
+
+% Compare to HMM toolbox
+
+data = zeros(ncases, T);
+for i=1:ncases
+  %data(i,:) = cat(2, cases{i}{onodes,:});
+  data(i,:) = cell2num(cases{i}(onodes,:));
+end
+[LL2, prior2, transmat2, obsmat2] = dhmm_em(data, prior1, transmat1, obsmat1, 'max_iter', max_iter);
+
+e = 1;
+assert(approxeq(prior2, CPD{e,1}.CPT))
+assert(approxeq(obsmat2, CPD{e,2}.CPT))
+assert(approxeq(transmat2, CPD{e,3}.CPT))
+assert(approxeq(LL2, LL{e}))        
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/ehmm1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/ehmm1.m
new file mode 100644
index 00000000..d6af4147
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/ehmm1.m
@@ -0,0 +1,24 @@
+% make the structure of an embedded HMM with 2 rows and 3 columns
+
+% 1------------>2
+% |\   \        | \  \
+% 3->4->5       6->7->8
+
+n = 8;
+dag = zeros(n);
+dag(1,[2 3 4 5])=1;
+dag(2,[6 7 8])=1;
+for i=3:4
+  dag(i,i+1)=1;
+end
+for i=6:7
+  dag(i,i+1)=1;
+end
+ns = 2*ones(1,n);
+bnet = mk_bnet(dag,ns);
+for i=1:n
+  bnet.CPD{i}=tabular_CPD(bnet,i);
+end
+[jtree, root, cliques] =  graph_to_jtree(moralize(bnet.dag), ones(1,n), {}, {});
+%[jtree, root, cliques, B, w, elim_order, moral_edges, fill_in_edges] = dag_to_jtree(bnet);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/fhmm_infer.m b/sourcecodes/bnt-master/BNT/examples/dynamic/fhmm_infer.m
new file mode 100644
index 00000000..62eec4a3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/fhmm_infer.m
@@ -0,0 +1,324 @@
+function [loglik, gamma] = fhmm_infer(inter, CPTs_slice1, CPTs, obsmat, node_sizes)
+% FHMM_INFER Exact inference for a factorial HMM.
+% [loglik, gamma] = fhmm_infer(inter, CPTs_slice1, CPTs, obsmat, node_sizes)
+%
+% Inputs:
+% inter - the inter-slice adjacency matrix
+% CPTs_slice1{s}(j) = Pr(Q(s,1) = j) where Q(s,t) = hidden node s in slice t
+% CPT{s}(i1, i2, ..., j) = Pr(Q(s,t) = j | Pa(s,t-1) = i1, i2, ...),
+% obsmat(i,t) = Pr(y(t) | Q(t)=i)
+% node_sizes is a vector with the cardinality of the hidden nodes
+%
+% Outputs:
+% gamma(i,t) = Pr(X(t)=i | O(1:T)) as in an HMM,
+% except that i is interpreted as an M digit, base-K number (if there are M chains each of cardinality K).
+%
+%
+% For M chains each of cardinality K, the frontiers  (i.e., cliques)
+% contain M+1 nodes, and it takes M steps to advance the frontier by one time step,
+% so the run time is O(T M K^(M+1)).
+% An HMM takes O(T S^2) where S is the size of the state space.
+% Collapsing the FHMM to an HMM results in S = K^M.
+% For details, see
+%   "The Factored Frontier Algorithm for Approximate Inference in DBNs",
+%    Kevin Murphy and Yair Weiss, submitted to NIPS 2000.
+%
+% The frontier algorithm makes the following topological assumptions:
+% 
+%  - All nodes are persistent (connect to the next slice)
+%  - No connections within a timeslice
+%  - There is a single observation variable, which depends on all the hidden nodes
+%  - Each node can have several parents in the previous time slice (generalizes a FHMM slightly)
+%
+
+% The forwards pass of the frontier algorithm can be explained with the following example.
+% Suppose we have 3 hidden nodes per slice, A, B, C.
+% The goal is to compute alpha(j, t) = Pr( (A_t,B_t,C_t)=j | Y(1:t))
+% We move alpha from t to t+1 one node at a time, as follows.
+% We define the following quantities:
+% s([a1 b1 c1], 1) = Prob(A(t)=a1, B(t)=b1, C(t)=c1 | Y(1:t)) = alpha(j, t)
+% s([a2 b1 c1], 2) = Prob(A(t+1)=a2, B(t)=b1, C(t)=c1 | Y(1:t))
+% s([a2 b2 c1], 3) = Prob(A(t+1)=a2, B(t+1)=b2, C(t)=c1 | Y(1:t))
+% s([a2 b2 c2], 4) = Prob(A(t+1)=a2, B(t+1)=b2, C(t+1)=c2 | Y(1:t))
+% s([a2 b2 c2], 5) = Prob(A(t+1)=a2, B(t+1)=b2, C(t+1)=c2 | Y(1:t+1)) = alpha(j, t+1)
+%
+% These can be computed recursively as follows:
+%
+% s([a2 b1 c1], 2) = sum_{a1} P(a2|a1) s([a1 b1 c1], 1)
+% s([a2 b2 c1], 3) = sum_{b1} P(b2|b1) s([a2 b1 c1], 2)
+% s([a2 b2 c2], 4) = sum_{c1} P(c2|c1) s([a2 b2 c1], 1)
+% s([a2 b2 c2], 5) = normalise( s([a2 b2 c2], 4) .* P(Y(t+1)|a2,b2,c2)
+
+
+[kk,ll,mm] = make_frontier_indices(inter, node_sizes); % can pass in as args
+
+scaled = 1;
+
+M = length(node_sizes);
+S = prod(node_sizes);
+T = size(obsmat, 2);
+
+alpha = zeros(S, T);
+beta = zeros(S, T);
+gamma = zeros(S, T);
+scale = zeros(1,T);
+tiny = exp(-700);
+
+
+alpha(:,1) = make_prior_from_CPTs(CPTs_slice1, node_sizes);
+alpha(:,1) = alpha(:,1) .* obsmat(:, 1);
+
+if scaled
+  s = sum(alpha(:,1));
+  if s==0, s = s + tiny; end
+  scale(1) = 1/s;
+else
+  scale(1) = 1;
+end
+alpha(:,1) = alpha(:,1) * scale(1);
+
+%a = zeros(S, M+1);
+%b = zeros(S, M+1);
+anew = zeros(S,1);
+aold = zeros(S,1);
+bnew = zeros(S,1);
+bold = zeros(S,1);
+
+for t=2:T
+  %a(:,1) = alpha(:,t-1);
+  aold =  alpha(:,t-1);
+  
+  c = 1;
+  for i=1:M
+    ns = node_sizes(i);
+    cpt = CPTs{i};
+    for j=1:S
+      s = 0;
+      for xx=1:ns
+	%k = kk(xx,j,i);
+	%l = ll(xx,j,i);
+	k = kk(c);
+	l = ll(c);
+	c = c + 1;
+	% s = s + a(k,i) * CPTs{i}(l);
+	s = s + aold(k) * cpt(l);
+      end
+      %a(j,i+1) = s;
+      anew(j) = s;
+    end
+    aold = anew;
+  end
+  
+  %alpha(:,t) = a(:,M+1) .* obsmat(:, obs(t));
+  alpha(:,t) = anew .* obsmat(:, t);
+
+  if scaled
+    s = sum(alpha(:,t));
+    if s==0, s = s + tiny; end
+    scale(t) = 1/s;
+  else
+    scale(t) = 1;
+  end
+  alpha(:,t) = alpha(:,t) * scale(t);
+
+end
+
+
+beta(:,T) = ones(S,1) * scale(T);
+for t=T-1:-1:1
+  %b(:,1) = beta(:,t+1) .* obsmat(:, obs(t+1));
+  bold = beta(:,t+1) .* obsmat(:, t+1);
+
+  c = 1;
+  for i=1:M
+    ns = node_sizes(i);
+    cpt = CPTs{i};
+    for j=1:S
+      s = 0;
+      for xx=1:ns
+	%k = kk(xx,j,i);
+	%m = mm(xx,j,i);
+	k = kk(c);
+	m = mm(c);
+	c = c + 1;
+	% s = s + b(k,i) * CPTs{i}(m);
+	s = s + bold(k) * cpt(m);
+      end
+      %b(j,i+1) = s;
+      bnew(j) = s;
+    end
+    bold = bnew;
+  end
+  % beta(:,t) = b(:,M+1) * scale(t);
+  beta(:,t) = bnew * scale(t);
+end
+
+
+if scaled
+  loglik = -sum(log(scale)); % scale(i) is finite
+else
+  lik = alpha(:,1)' * beta(:,1);
+  loglik = log(lik+tiny);
+end
+
+for t=1:T
+  gamma(:,t) = normalise(alpha(:,t) .* beta(:,t));
+end
+
+%%%%%%%%%%%
+
+function [kk,ll,mm] = make_frontier_indices(inter, node_sizes)
+%
+% Precompute indices for use in the frontier algorithm.
+% These only depend on the topology, not the parameters or data.
+% Hence we can compute them outside of fhmm_infer.
+% This saves a lot of run-time computation.
+
+M = length(node_sizes);
+S = prod(node_sizes);
+
+mns = max(node_sizes);
+kk = zeros(mns, S, M);
+ll = zeros(mns, S, M);
+mm = zeros(mns, S, M);
+
+for i=1:M
+  for j=1:S
+    u = ind2subv(node_sizes, j);
+    x = u(i);
+    for xx=1:node_sizes(i)
+      uu = u;
+      uu(i) = xx;
+      k = subv2ind(node_sizes, uu);
+      kk(xx,j,i) = k;
+      ps = find(inter(:,i)==1);
+      ps = ps(:)';
+      l = subv2ind(node_sizes([ps i]), [uu(ps) x]); % sum over parent
+      ll(xx,j,i) = l;
+      m = subv2ind(node_sizes([ps i]), [u(ps) xx]); % sum over child
+      mm(xx,j,i) = m;
+    end
+  end
+end
+
+%%%%%%%%%
+
+function prior=make_prior_from_CPTs(indiv_priors, node_sizes)
+%
+% composite_prior=make_prior(individual_priors, node_sizes)
+% Make the prior for the first node in a Markov chain
+% from the priors on each node in the equivalent DBN.
+% prior{i}(j) = Pr(X_i=j), where X_i is the i'th node in slice 1.
+% composite_prior(i) = Pr(slice1 = i).
+
+n = length(indiv_priors);
+S = prod(node_sizes);
+prior = zeros(S,1);
+for i=1:S
+  vi = ind2subv(node_sizes, i);
+  p = 1;
+  for k=1:n
+    p = p * indiv_priors{k}(vi(k));
+  end
+  prior(i) = p;
+end
+
+
+
+%%%%%%%%%%%
+
+function [loglik, alpha, beta] = FHMM_slow(inter, CPTs_slice1, CPTs, obsmat, node_sizes, data)
+% 
+% Same as the above, except we don't use the optimization of computing the indices outside the loop.
+
+
+scaled = 1;
+
+M = length(node_sizes);
+S = prod(node_sizes);
+[numex T] = size(data);
+
+obs = data;
+
+alpha = zeros(S, T);
+beta = zeros(S, T);
+a = zeros(S, M+1);
+b = zeros(S, M+1);
+scale = zeros(1,T);
+
+alpha(:,1) = make_prior_from_CPTs(CPTs_slice1, node_sizes);
+alpha(:,1) = alpha(:,1) .* obsmat(:, obs(1));
+if scaled
+  s = sum(alpha(:,1));
+  if s==0, s = s + tiny; end
+  scale(1) = 1/s;
+else
+  scale(1) = 1;
+end
+alpha(:,1) = alpha(:,1) * scale(1);
+
+for t=2:T
+  fprintf(1, 't %d\n', t);
+  a(:,1) = alpha(:,t-1);
+  for i=1:M
+    for j=1:S
+      u = ind2subv(node_sizes, j);
+      xnew = u(i);
+      s = 0;
+      for xold=1:node_sizes(i)
+	uold = u;
+	uold(i) = xold;
+	k = subv2ind(node_sizes, uold);
+	ps = find(inter(:,i)==1);
+	ps = ps(:)';
+	l = subv2ind(node_sizes([ps i]), [uold(ps) xnew]);
+	s = s + a(k,i) * CPTs{i}(l);
+      end
+      a(j,i+1) = s;
+    end
+  end
+  alpha(:,t) = a(:,M+1) .* obsmat(:, obs(t));
+
+  if scaled
+    s = sum(alpha(:,t));
+    if s==0, s = s + tiny; end
+    scale(t) = 1/s;
+  else
+    scale(t) = 1;
+  end
+  alpha(:,t) = alpha(:,t) * scale(t);
+
+end
+
+
+beta(:,T) = ones(S,1) * scale(T);
+for t=T-1:-1:1
+  fprintf(1, 't %d\n', t);
+  b(:,1) = beta(:,t+1) .* obsmat(:, obs(t+1));
+  for i=1:M
+    for j=1:S
+      u = ind2subv(node_sizes, j);
+      xold = u(i);
+      s = 0;
+      for xnew=1:node_sizes(i)
+	unew = u;
+	unew(i) = xnew;
+	k = subv2ind(node_sizes, unew);
+	ps = find(inter(:,i)==1);
+	ps = ps(:)';
+	l = subv2ind(node_sizes([ps i]), [u(ps) xnew]);
+	s = s + b(k,i) * CPTs{i}(l);
+      end
+      b(j,i+1) = s;
+    end
+  end
+  beta(:,t) = b(:,M+1) * scale(t);
+end
+
+
+if scaled
+  loglik = -sum(log(scale)); % scale(i) is finite
+else
+  lik = alpha(:,1)' * beta(:,1);
+  loglik = log(lik+tiny);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/filter_test1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/filter_test1.m
new file mode 100644
index 00000000..9e65508a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/filter_test1.m
@@ -0,0 +1,24 @@
+% Compare online filtering algorithms on some DBNs
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+if 0
+  N = 3;
+  Q = 2;
+  obs_size = 1;
+  discrete_obs = 0;
+  bnet = mk_chmm(N, Q, obs_size, discrete_obs);
+else
+  %bnet = mk_bat_dbn;
+  bnet = mk_water_dbn;
+end
+
+T = 3;
+
+engine = {};
+engine{end+1} = filter_engine(hmm_2TBN_inf_engine(bnet));
+engine{end+1} = filter_engine(jtree_2TBN_inf_engine(bnet));
+
+time = cmp_online_inference(bnet, engine, T);
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/ghmm1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/ghmm1.m
new file mode 100644
index 00000000..8590a25a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/ghmm1.m
@@ -0,0 +1,64 @@
+% Make an HMM with Gaussian observations
+%   X1 -> X2
+%   |     | 
+%   v     v
+%   Y1    Y2 
+
+intra = zeros(2);
+intra(1,2) = 1;
+inter = zeros(2);
+inter(1,1) = 1;
+n = 2;
+
+Q = 2; % num hidden states
+O = 2; % size of observed vector
+ns = [Q O];
+bnet = mk_dbn(intra, inter, ns, 'discrete', 1, 'observed', 2);
+
+prior0 = normalise(rand(Q,1));
+transmat0 = mk_stochastic(rand(Q,Q));
+mu0 = rand(O,Q);
+Sigma0 = repmat(eye(O), [1 1 Q]);
+bnet.CPD{1} = tabular_CPD(bnet, 1, prior0);
+%% we set the cov prior to 0 to give same results as HMM toolbox
+%bnet.CPD{2} = gaussian_CPD(bnet, 2, 'mean', mu0, 'cov', Sigma0, 'cov_prior_weight', 0);
+bnet.CPD{2} = gaussian_CPD(bnet, 2, 'mean', mu0, 'cov', Sigma0);
+bnet.CPD{3} = tabular_CPD(bnet, 3, transmat0);
+
+
+T = 5; % fixed length sequences
+
+engine = {};
+engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet));
+engine{end+1} = smoother_engine(hmm_2TBN_inf_engine(bnet));
+engine{end+1} = hmm_inf_engine(bnet);
+engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T);
+%engine{end+1} = frontier_inf_engine(bnet);
+engine{end+1} = bk_inf_engine(bnet, 'clusters', {[1]});
+engine{end+1} = jtree_dbn_inf_engine(bnet);
+
+
+inf_time = cmp_inference_dbn(bnet, engine, T);
+
+ncases = 2;
+max_iter = 2;
+[learning_time, CPD, LL, cases] = cmp_learning_dbn(bnet, engine, T, 'ncases', ncases, 'max_iter', max_iter);
+
+% Compare to HMM toolbox
+
+data = zeros(O, T, ncases);
+for i=1:ncases
+  data(:,:,i) = cell2num(cases{i}(bnet.observed, :));  
+end
+
+tic
+[LL2, prior2, transmat2, mu2, Sigma2] = mhmm_em(data, prior0, transmat0, mu0, Sigma0, [],  'max_iter', max_iter);
+t=toc;
+disp(['HMM toolbox took ' num2str(t) ' seconds '])
+
+e = 1;
+assert(approxeq(prior2, CPD{e,1}.CPT))
+assert(approxeq(mu2, CPD{e,2}.mean))
+assert(approxeq(Sigma2, CPD{e,2}.cov))
+assert(approxeq(transmat2, CPD{e,3}.CPT))
+assert(approxeq(LL2, LL{e}))
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/ho1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/ho1.m
new file mode 100644
index 00000000..b6825ce1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/ho1.m
@@ -0,0 +1,156 @@
+function ho1()
+
+% Example of how to create a higher order DBN
+% Written by Rainer Deventer <deventer@informatik.uni-erlangen.de> 3/28/03
+
+bnet = createBNetNL();
+
+%%%%%%%%%%%%
+
+
+function bnet = createBNetNL(varargin)
+     % Generate a Bayesian network, which is able to model nonlinearities at
+% the input. The only input is the order of the dynamic system. If this 
+% parameter is missing, the an order of two is assumed
+if nargin > 0 
+    order = varargin{1}
+else
+    order = 2;
+end
+
+ss = 6; % For each time slice the following nodes are modeled
+        % ud(t_k) Discrete node, which decides whether saturation is reached.
+        %         Node number 2
+        % uv(t_k) Visible input node with node number  2
+        % uh(t_k) Hidden  input node with node number 3     
+        % y(t_k)  Modeled output, Number 4
+        % z(t_k)  Disturbing variable, number 5
+        % q(t_k), number6 6
+
+intra = zeros(ss,ss);
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Within each timeslice ud(t_k) is connected with uv(t_k) and uh(t_k)    %
+% This part is used to model saturation                                  %
+% A connection from  uv(t_k) to uh(t_k) is omitted                       %
+% Additionally   y(t_k) is connected with q(t_k). To model the disturbing%
+% value z(t_k) is connected with q(t_k).                                 %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+intra(1,2:3) = 1; % Connections ud(t_k) -> uv(t_k) and ud(t_k) -> uh(t_k)
+intra(4:5,6) = 1; % Connectios  y(t_k)  -> q(t_k)  and z(t_k)  -> q(t_k) 
+
+
+  
+inter = zeros(ss,ss,order);
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% The Markov assumption is not met as connections from time slice t to t+2 %
+% exist.                                                                   %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+for i = 1:order
+    if i == 1
+        inter(1,1,i) = 1; %Connect the discrete nodes. This is necessary to improve
+                          %the disturbing reaction
+        inter(3,4,i) = 1; %Connect uh(t_{k-1}) with y(t_k)
+        inter(4,4,i) = 1; %Connect y(t_{k-1})  with y(t_k)    
+        inter(5,5,i) = 1; %Connect z(t_{k-1})  with z(t_k)
+    else
+        inter(3,4,i) = 1; %Connect uh(t_{k-i}) with y(t_k)
+        inter(4,4,i) = 1; %Connect  y(t_{k-i}) with y(t_k)
+    end
+end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Define the dimensions of the discrete nodes. Node 1 has two states     %
+% 1 = lower saturation reached                                           %
+% 2 = Upper saturation reached                                           %
+% Values in between are model by probabilities between 0 and 1           %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+node_sizes = ones(1,ss);
+node_sizes(1) = 2;
+dnodes = [1];
+
+eclass = [1:6;7 2:3 8 9 6;7 2:3 10 11 6];
+bnet = mk_higher_order_dbn(intra,inter,node_sizes,...
+                           'discrete',dnodes,...
+                           'eclass',eclass);
+
+cov_high = 400;
+cov_low  = 0.01;
+weight1 = randn(1,1);
+weight2 = randn(1,1);
+weight3 = randn(1,1);
+weight4 = randn(1,1);
+
+numOfNodes = 5 + order;
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Nodes of the first time-slice   %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Discrete input node, 
+bnet.CPD{1} = tabular_CPD(bnet,1,'CPT',[1/2 1/2],'adjustable',0);
+
+
+% Modeled visible input
+bnet.CPD{2} = gaussian_CPD(bnet,2,'mean',[0 10],'clamp_mean',1,...
+                            'cov',[10 10],'clamp_cov',1);
+
+% Modeled hidden input
+bnet.CPD{3} = gaussian_CPD(bnet,3,'mean',[0, 10],'clamp_mean',1,...
+			          'cov',[0.1 0.1],'clamp_cov',1);
+
+% Modeled output in the first timeslice, thus there are no parents
+% Usuallz the output nodes get a low covariance. But in the first
+% time-slice a prediction of the output is not possible due to 
+% missing information
+bnet.CPD{4} = gaussian_CPD(bnet,4,'mean',0,'clamp_mean',1,...
+			          'cov',cov_high,'clamp_cov',1);
+
+%Disturbance
+bnet.CPD{5} = gaussian_CPD(bnet,5,'mean',0,...
+                                  'cov',[4],...
+                                  'clamp_mean',1,...
+                                  'clamp_cov',1);
+
+%Observed output. 
+bnet.CPD{6} = gaussian_CPD(bnet,6,'mean',0,...
+                                  'clamp_mean',1,...
+                                  'cov',cov_low,'clamp_cov',1,...
+                                  'weights',[1 1],'clamp_weights',1);
+
+% Discrete node at second time slice
+bnet.CPD{7} = tabular_CPD(bnet,7,'CPT',[0.6 0.4 0.4 0.6],'adjustable',0);
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Node for the model output %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+bnet.CPD{8} = gaussian_CPD(bnet,10,'mean',0,...
+				   'cov',cov_high,...
+				   'clamp_mean',1,...
+			           'clamp_cov',1);
+%                                   'weights',[0.0791 0.9578]);
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Node for the disturbance %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%                        
+bnet.CPD{9} = gaussian_CPD(bnet,11,'mean',0,'clamp_mean',1,...
+                                   'cov',[4],'clamp_cov',1,...
+                                   'weights',[1],'clamp_weights',1);
+                                   
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Node for the model output %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+bnet.CPD{10} = gaussian_CPD(bnet,16,'mean',0,'clamp_mean',1,...
+                                    'cov',cov_low,'clamp_cov',1);
+%                                   'weights',[0.0188 -0.0067 0.0791 0.9578]);
+
+
+
+    
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Node for the disturbance %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%                        
+bnet.CPD{11} = gaussian_CPD(bnet,17,'mean',0,'clamp_mean',1,...
+                                           'cov',[0.2],'clamp_cov',1,...
+                                           'weights',[1],'clamp_weights',1);
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/jtree_clq_test.m b/sourcecodes/bnt-master/BNT/examples/dynamic/jtree_clq_test.m
new file mode 100644
index 00000000..647a2763
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/jtree_clq_test.m
@@ -0,0 +1,150 @@
+% Construct various DBNs and examine their clique structure.
+% This was used to generate various figures in chap 3-4 of my thesis.
+
+% Examine the cliques in the unrolled mildew net
+
+%dbn = mk_mildew_dbn;
+dbn = mk_chmm(4);
+ss = dbn.nnodes_per_slice;
+T = 7;
+N = ss*T;
+bnet = dbn_to_bnet(dbn, T);
+
+constrained = 0;
+if constrained
+  stages = num2cell(unroll_set(1:ss, ss, T), 1);
+else
+  stages = { 1:N; };
+end
+clusters = {};
+%[jtree, root, cliques, B, w, elim_order, moral_edges, fill_in_edges] = ...
+%    dag_to_jtree(bnet, bnet.observed, stages, clusters);
+[jtree, root, cliques] =  graph_to_jtree(moralize(bnet.dag), ones(1,N), stages, clusters);
+
+flip=1;
+clf;[dummyx, dummyy, h] = draw_dbn(dbn.intra, dbn.inter, flip, T, -1);
+dir = '/home/eecs/murphyk/WP/Thesis/Figures/Inf/MildewUnrolled';
+mk_ps_from_clqs(dbn, T, cliques, [])
+%mk_collage_from_clqs(dir, cliques)
+
+
+% Examine the cliques in the cascade DBN
+
+% A-A
+%  \
+% B B
+%  \
+% C C
+%  \
+% D D
+ss = 4;
+intra = zeros(ss);
+inter = zeros(ss);
+inter(1, [1 2])=1;
+for i=2:ss-1
+  inter(i,i+1)=1;
+end
+
+
+% 2 coupled HMMs 1,3  and 2,4
+ss = 4;
+intra = zeros(ss);
+inter = zeros(ss); % no persistent edges
+%inter = diag(ones(ss,1)); % persitence edges
+inter(1,3)=1; inter(3,1)=1;
+inter(2,4)=1; inter(4,2)=1;
+
+%bnet = mk_fhmm(3);
+bnet = mk_chmm(4);
+intra = bnet.intra;
+inter = bnet.inter;
+
+clqs = compute_minimal_interface(intra, inter);
+celldisp(clqs)
+
+
+
+
+% A A
+%  \
+% B B
+%  \
+% C C
+%  \
+% D-D
+ss = 4;
+intra = zeros(ss);
+inter = zeros(ss);
+for i=1:ss-1
+  inter(i,i+1)=1;
+end
+inter(4,4)=1;
+
+
+
+ns = 2*ones(1,ss);
+dbn = mk_dbn(intra, inter, ns);
+for i=2*ss
+  dbn.CPD{i} = tabular_CPD(bnet, i);
+end
+
+T = 4;
+N = ss*T;
+bnet = dbn_to_bnet(dbn, T);
+
+constrained = 1;
+if constrained
+  % elim first 3 slices first in any order
+  stages = {1:12, 13:16};
+  %stages = num2cell(unroll_set(1:ss, ss, T), 1);
+else
+  stages = { 1:N; };
+end
+clusters = {};
+%[jtree, root, cliques, B, w, elim_order, moral_edges, fill_in_edges] = ...
+%    dag_to_jtree(bnet, bnet.observed, stages, clusters);
+[jtree, root, cliques] =  graph_to_jtree(moralize(bnet.dag), ones(1,N), stages, clusters);
+
+
+
+
+
+% Examine the cliques in the 1.5 slice DBN
+
+%dbn = mk_mildew_dbn;
+dbn = mk_water_dbn;
+%dbn = mk_bat_dbn;
+ss = dbn.nnodes_per_slice;
+int = compute_fwd_interface(dbn);
+bnet15 = mk_slice_and_half_dbn(dbn, int);
+N = length(bnet15.dag);
+stages = {1:N};
+
+% bat
+%cl1 = [16 17 19 7 14];
+%cl2 = [27 25 21 23 20];
+%clusters = {cl1, cl2, cl1+ss, cl2+ss};
+
+% water
+%cl1 = 1:2; cl2 = 3:6; cl3 = 7:8;
+%clusters = {cl1, cl2, cl3, cl1+ss, cl2+ss, cl3+ss};
+
+%clusters = {};
+clusters = {int, int+ss};
+%[jtree, root, cliques, B, w, elim_order, moral_edges, fill_in_edges] = ...
+%    dag_to_jtree(bnet15, bnet.observed, stages, clusters);
+[jtree, root, cliques] =  graph_to_jtree(moralize(bnet15.dag), ones(1,N), stages, clusters);
+
+clq_len = [];
+for c=1:length(cliques)
+  clq_len(c) = length(cliques{c});
+end
+hist(clq_len, 1:max(clq_len));
+h=hist(clq_len, 1:max(clq_len));
+axis([1 max(clq_len)+1 0 max(h)+1])
+xlabel('clique size','fontsize',16)
+ylabel('number','fontsize',16)
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/jtree_clq_test2.m b/sourcecodes/bnt-master/BNT/examples/dynamic/jtree_clq_test2.m
new file mode 100644
index 00000000..975cc46b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/jtree_clq_test2.m
@@ -0,0 +1,23 @@
+
+%bnet = mk_uffe_dbn;
+bnet = mk_mildew_dbn;
+ss = length(bnet.intra);
+
+% construct jtree from 1.5 slice DBN
+
+int = compute_fwd_interface(bnet.intra, bnet.inter);
+bnet15 = mk_slice_and_half_dbn(bnet, int);
+
+% use unconstrained elimination,
+% but force there to be a clique containing both interfaces
+clusters = {int, int+ss};
+jtree_engine = jtree_inf_engine(bnet15, 'clusters', clusters, 'root', int+ss);
+S=struct(jtree_engine)
+in_clq = clq_containing_nodes(jtree_engine, int);
+out_clq = clq_containing_nodes(jtree_engine, int+ss)
+
+
+% Also make a jtree from slice 1
+bnet1 = mk_bnet(bnet.intra1, bnet.node_sizes_slice);
+jtree_engine1 = jtree_inf_engine(bnet1, 'clusters', {int}, 'root', int);
+S1=struct(jtree_engine1)
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/kalman1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/kalman1.m
new file mode 100644
index 00000000..32c3583c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/kalman1.m
@@ -0,0 +1,66 @@
+% Make a linear dynamical system
+%   X1 -> X2
+%   |     | 
+%   v     v
+%   Y1    Y2 
+
+intra = zeros(2);
+intra(1,2) = 1;
+inter = zeros(2);
+inter(1,1) = 1;
+n = 2;
+
+X = 2; % size of hidden state
+Y = 2; % size of observable state
+ns = [X Y];
+bnet = mk_dbn(intra, inter, ns, 'discrete', [], 'observed', 2);
+
+x0 = rand(X,1);
+V0 = eye(X);
+C0 = rand(Y,X);
+R0 = eye(Y);
+A0 = rand(X,X);
+Q0 = eye(X);
+
+bnet.CPD{1} = gaussian_CPD(bnet, 1, 'mean', x0, 'cov', V0, 'cov_prior_weight', 0);
+bnet.CPD{2} = gaussian_CPD(bnet, 2, 'mean', zeros(Y,1), 'cov', R0, 'weights', C0, ...
+			   'clamp_mean', 1, 'cov_prior_weight', 0);
+bnet.CPD{3} = gaussian_CPD(bnet, 3, 'mean', zeros(X,1), 'cov', Q0, 'weights', A0, ...
+			   'clamp_mean', 1, 'cov_prior_weight', 0);
+
+
+T = 5; % fixed length sequences
+
+clear engine;
+engine{1} = kalman_inf_engine(bnet);
+engine{2} = jtree_unrolled_dbn_inf_engine(bnet, T);
+engine{3} = jtree_dbn_inf_engine(bnet);
+engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet));
+N = length(engine);
+
+
+inf_time = cmp_inference_dbn(bnet, engine, T);
+
+ncases = 2;
+max_iter = 2;
+[learning_time, CPD, LL, cases] = cmp_learning_dbn(bnet, engine, T, 'ncases', ncases, 'max_iter', max_iter);
+
+
+% Compare to KF toolbox
+
+data = zeros(Y, T, ncases);
+for i=1:ncases
+  data(:,:,i) = cell2num(cases{i}(onodes, :));
+end   
+[A2, C2, Q2, R2, x2, V2, LL2trace] =  learn_kalman(data, A0, C0, Q0, R0, x0, V0, max_iter);
+
+
+e = 1;
+assert(approxeq(x2, CPD{e,1}.mean))
+assert(approxeq(V2, CPD{e,1}.cov))
+assert(approxeq(C2, CPD{e,2}.weights))
+assert(approxeq(R2, CPD{e,2}.cov));
+assert(approxeq(A2, CPD{e,3}.weights))
+assert(approxeq(Q2, CPD{e,3}.cov));
+assert(approxeq(LL2trace, LL{1}))
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/kjaerulff1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/kjaerulff1.m
new file mode 100644
index 00000000..28b315fc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/kjaerulff1.m
@@ -0,0 +1,55 @@
+% Compare the speeds of various inference engines on the DBN in Kjaerulff
+% "dHugin: A computational system for dynamic time-sliced {B}ayesian networks",
+% Intl. J. Forecasting 11:89-111, 1995.
+%
+% The intra structure is (all arcs point downwards)
+%
+%  1 -> 2
+%   \  /
+%     3
+%     |
+%     4
+%    / \
+%   5   6
+%   \  /
+%     7
+%     |
+%     8
+%
+% The inter structure is 1->1, 4->4, 8->8
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+ss = 8;
+intra = zeros(ss);
+intra(1,[2 3])=1;
+intra(2,3)=1;
+intra(3,4)=1;
+intra(4,[5 6])=1;
+intra([5 6], 7)=1;
+intra(7,8)=1;
+
+inter = zeros(ss);
+inter(1,1)=1;
+inter(4,4)=1;
+inter(8,8)=1;
+
+ns = 2*ones(1,ss);
+onodes = 2;
+bnet = mk_dbn(intra, inter, ns, 'observed', onodes, 'eclass2', (1:ss)+ss);
+for i=1:2*ss
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+end
+
+T = 4;
+
+engine = {};
+engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T);
+engine{end+1} = jtree_dbn_inf_engine(bnet);
+engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet));
+%engine{end+1} = smoother_engine(hmm_2TBN_inf_engine(bnet)); % observed nodes have children
+
+inf_time = cmp_inference_dbn(bnet, engine, T)
+learning_time = cmp_learning_dbn(bnet, engine, T)
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/loopy_dbn1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/loopy_dbn1.m
new file mode 100644
index 00000000..27facf0b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/loopy_dbn1.m
@@ -0,0 +1,24 @@
+N = 1; % single chain = HMM - should give exact answers
+Q = 2;
+rand('state', 0);
+randn('state', 0);
+discrete = 1;
+if discrete
+  Y = 2; % size of output alphabet
+else
+  Y = 1;
+end
+coupled = 1;
+bnet  = mk_chmm(N, Q, Y, discrete, coupled);
+ss = N*2;
+
+T = 3;
+
+engine = {};
+engine{end+1} = jtree_dbn_inf_engine(bnet); 
+engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T); 
+engine{end+1} = pearl_unrolled_dbn_inf_engine(bnet, 'protocol', 'tree');  
+
+inf_time = cmp_inference_dbn(bnet, engine, T)
+learning_time = cmp_learning_dbn(bnet, engine, T)
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/mhmm1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/mhmm1.m
new file mode 100644
index 00000000..6efb9f72
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/mhmm1.m
@@ -0,0 +1,85 @@
+% Make an HMM with mixture of Gaussian observations
+%    Q1 ---> Q2
+%  /  |   /  |
+% M1  |  M2  | 
+%  \  v   \  v
+%    Y1     Y2 
+% where Pr(m=j|q=i) is a multinomial and Pr(y|m,q) is a Gaussian     
+
+%seed = 3;
+%rand('state', seed);
+%randn('state', seed);
+
+intra = zeros(3);
+intra(1,[2 3]) = 1;
+intra(2,3) = 1;
+inter = zeros(3);
+inter(1,1) = 1;
+n = 3;
+
+Q = 2; % num hidden states
+O = 2; % size of observed vector
+M = 2; % num mixture components per state
+
+ns = [Q M O];
+dnodes = [1 2];
+onodes = [3];
+eclass1 = [1 2 3];
+eclass2 = [4 2 3];
+bnet = mk_dbn(intra, inter, ns, 'discrete', dnodes, 'eclass1', eclass1, 'eclass2', eclass2, ...
+	      'observed', onodes);
+
+prior0 = normalise(rand(Q,1));
+transmat0 = mk_stochastic(rand(Q,Q));
+mixmat0 = mk_stochastic(rand(Q,M));
+mu0 = rand(O,Q,M);
+Sigma0 = repmat(eye(O), [1 1 Q M]);
+bnet.CPD{1} = tabular_CPD(bnet, 1, prior0);
+bnet.CPD{2} = tabular_CPD(bnet, 2, mixmat0);
+%% we set the cov prior to 0 to give same results as HMM toolbox
+%bnet.CPD{3} = gaussian_CPD(bnet, 3, 'mean', mu0, 'cov', Sigma0, 'cov_prior_weight', 0);
+% new version of HMM toolbox uses the same default prior on Gaussians as BNT
+bnet.CPD{3} = gaussian_CPD(bnet, 3, 'mean', mu0, 'cov', Sigma0);
+bnet.CPD{4} = tabular_CPD(bnet, 4, transmat0);
+
+
+
+T = 5; % fixed length sequences
+
+engine = {};
+engine{end+1} = hmm_inf_engine(bnet);
+engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet));
+engine{end+1} = smoother_engine(hmm_2TBN_inf_engine(bnet));
+if 0
+engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T);
+%engine{end+1} = frontier_inf_engine(bnet);
+engine{end+1} = bk_inf_engine(bnet, 'clusters', 'exact');
+engine{end+1} = jtree_dbn_inf_engine(bnet);
+end
+
+inf_time = cmp_inference_dbn(bnet, engine, T);
+
+ncases = 2;
+max_iter = 2;
+[learning_time, CPD, LL, cases] = cmp_learning_dbn(bnet, engine, T, 'ncases', ncases, 'max_iter', max_iter);
+
+% Compare to HMM toolbox
+
+data = zeros(O, T, ncases);
+for i=1:ncases
+  data(:,:,i) = reshape(cell2num(cases{i}(onodes,:)), [O T]);
+end
+tic;
+[LL2, prior2, transmat2, mu2, Sigma2, mixmat2] = ...
+    mhmm_em(data, prior0, transmat0,  mu0, Sigma0, mixmat0, 'max_iter', max_iter);
+t=toc;
+disp(['HMM toolbox took ' num2str(t) ' seconds '])
+
+for e = 1:length(engine)
+  assert(approxeq(prior2, CPD{e,1}.CPT))
+  assert(approxeq(mixmat2, CPD{e,2}.CPT))
+  assert(approxeq(mu2, CPD{e,3}.mean))
+  assert(approxeq(Sigma2, CPD{e,3}.cov))
+  assert(approxeq(transmat2, CPD{e,4}.CPT))
+  assert(approxeq(LL2, LL{e}))
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/mildew1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/mildew1.m
new file mode 100644
index 00000000..f38aee91
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/mildew1.m
@@ -0,0 +1,30 @@
+bnet = mk_mildew_dbn;
+
+T = 4;
+engine = {};
+engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T);
+engine{end+1} = jtree_dbn_inf_engine(bnet); 
+%engine{end+1} = hmm_inf_engine(bnet); % 8 is observed but has kids
+engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet));
+%engine{end+1} = smoother_engine(hmm_2TBN_inf_engine(bnet));
+
+inf_time = cmp_inference_dbn(bnet, engine, T, 'check_ll', 0)
+%learning_time = cmp_learning_dbn(bnet, engine, T)
+
+S = struct(engine{1});
+S1 = struct(S.unrolled_engine);
+G = S1.jtree;
+%graph_to_dot(G, 'directed', 0, 'leftright', 1, ...
+%	     'filename', '/home/eecs/murphyk/WP/Thesis/Figures/Inf/Mildew/jtree.dot')
+%!dot -Tps jtree.dot -o jtree.ps
+% The resulting ps file cannot be converted using ps2pdf.
+
+N = length(G);
+for i=1:N
+  for j=1:N
+    if G(i,j)
+      G(j,i)=1;
+    end
+  end
+end
+draw_graph(G)
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/mk_bat_dbn.m b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_bat_dbn.m
new file mode 100644
index 00000000..e4d6f8b9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_bat_dbn.m
@@ -0,0 +1,63 @@
+function [bnet, names] = mk_bat_dbn()
+% MK_BAT_DBN Make the BAT DBN
+% [bnet, names] = mk_bat_dbn()
+% See
+% - Forbes, Huang, Kanazawa and Russell, "The BATmobile: Towards a Bayesian Automated Taxi", IJCAI 95
+% - Boyen and Koller, "Tractable Inference for Complex Stochastic Processes", UAI98.
+
+names = {'LeftClr', 'RightClr', 'LatAct', 'Xdot', 'InLane', 'FwdAct', ...
+      'Ydot', 'Stopped', 'EngStatus', 'FBStatus', ...
+      'LeftClrSens', 'RightClrSens', 'TurnSignalSens', 'XdotSens', 'YdotSens', ...
+      'FYdotDiffSens', 'FclrSens', 'BXdotSens', 'BclrSens', 'BYdotDiffSens', ...
+      'SensorValid', 'FYdotDiff', 'FcloseSlow', 'Fclr', 'BXdot', 'BcloseFast', 'Bclr', 'BYdotDiff'};
+ss = length(names);
+
+intrac = {...
+      'LeftClr', 'LeftClrSens';
+  'RightClr', 'RightClrSens';
+  'LatAct', 'TurnSignalSens'; 'LatAct', 'Xdot';
+  'Xdot', 'XdotSens';
+  'FwdAct', 'Ydot';
+  'Ydot', 'YdotSens'; 'Ydot', 'Stopped';
+  'EngStatus', 'Ydot'; 'EngStatus', 'FYdotDiff'; 'EngStatus', 'Fclr'; 'EngStatus', 'BXdot';
+  'SensorValid', 'XdotSens';   'SensorValid', 'YdotSens';
+  'FYdotDiff', 'FYdotDiffSens'; 'FYdotDiff', 'FcloseSlow';
+  'FcloseSlow', 'FBStatus';
+  'Fclr', 'FclrSens'; 'Fclr', 'FcloseSlow';
+  'BXdot', 'BXdotSens';
+  'Bclr', 'BclrSens'; 'Bclr', 'BXdot'; 'Bclr', 'BcloseFast';
+  'BcloseFast', 'FBStatus';
+  'BYdotDiff', 'BYdotDiffSens'; 'BYdotDiff', 'BcloseFast'};
+[intra, names] = mk_adj_mat(intrac, names, 1);
+
+
+interc = {...
+      'LeftClr', 'LeftClr'; 'LeftClr', 'LatAct';
+  'RightClr', 'RightClr'; 'RightClr', 'LatAct';
+  'LatAct', 'LatAct'; 'LatAct', 'FwdAct';
+  'Xdot', 'Xdot'; 'Xdot', 'InLane';
+  'InLane', 'InLane'; 'InLane', 'LatAct';
+  'FwdAct', 'FwdAct';
+  'Ydot', 'Ydot';
+  'Stopped', 'Stopped';
+  'EngStatus', 'EngStatus';
+  'FBStatus', 'FwdAct'; 'FBStatus', 'LatAct'};
+inter = mk_adj_mat(interc, names, 0);  
+
+obs = {'LeftClrSens', 'RightClrSens', 'TurnSignalSens', 'XdotSens', 'YdotSens', 'FYdotDiffSens', ...
+      'FclrSens', 'BXdotSens', 'BclrSens', 'BYdotDiffSens'};
+
+for i=1:length(obs)
+  onodes(i) = strmatch(obs{i}, names); %stringmatch(obs{i}, names);
+end
+onodes = sort(onodes);
+
+dnodes = 1:ss; 
+ns = 2*ones(1,ss); % binary nodes
+bnet = mk_dbn(intra, inter, ns, 'discrete', dnodes, 'observed', onodes, 'eclass2', (1:ss)+ss);
+
+% make rnd params
+for i=1:2*ss
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/mk_chmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_chmm.m
new file mode 100644
index 00000000..8da245ef
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_chmm.m
@@ -0,0 +1,103 @@
+function bnet = mk_chmm(N, Q, Y, discrete_obs, coupled, CPD)
+% MK_CHMM Make a coupled Hidden Markov Model
+%
+% There are N hidden nodes, each connected to itself and its two nearest neighbors in the next
+% slice (apart from the edges, where there is 1 nearest neighbor).
+%
+% Example: If N = 3, the hidden backbone is as follows, where all arrows point to the righ+t
+%
+% X1--X2
+%   \/ 
+%   /\
+% X2--X2
+%   \/ 
+%   /\
+% X3--X3
+%
+% Each hidden node has a "private" observed child (not shown).
+%
+% BNET = MK_CHMM(N, Q, Y)
+% Each hidden node is discrete and has Q values.
+% Each observed node is a Gaussian vector of length Y.
+%
+% BNET = MK_CHMM(N, Q, Y, DISCRETE_OBS)
+% If discrete_obs = 1, the observations are discrete (values in {1, .., Y}).
+%
+% BNET = MK_CHMM(N, Q, Y, DISCRETE_OBS, COUPLED)
+% If coupled = 0, the chains are not coupled, i.e., we make N parallel HMMs.
+%
+% BNET = MK_CHMM(N, Q, Y, DISCRETE_OBS, COUPLED, CPDs)
+% means use the specified CPD structures instead of creating random params.
+%  CPD{i}.CPT, i=1:N specifies the prior
+%  CPD{i}.CPT, i=2N+1:3N specifies the transition model
+%  CPD{i}.mean, CPD{i}.cov, i=N+1:2N specifies the observation model if Gaussian
+%  CPD{i}.CPT, i=N+1:2N if discrete
+
+
+if nargin < 2, Q = 2; end
+if nargin < 3, Y = 1; end
+if nargin < 4, discrete_obs = 0; end
+if nargin < 5, coupled = 1; end
+if nargin < 6, rnd = 1; else rnd = 0; end
+  
+ss = N*2;
+hnodes = 1:N;
+onodes = (1:N)+N;
+
+intra = zeros(ss);
+for i=1:N
+  intra(hnodes(i), onodes(i))=1;
+end
+
+inter = zeros(ss);
+if coupled
+  for i=1:N
+    inter(i, max(i-1,1):min(i+1,N))=1;
+  end
+else
+  inter(1:N, 1:N) = eye(N);
+end  
+
+ns = [Q*ones(1,N) Y*ones(1,N)]; 
+
+eclass1 = [hnodes onodes];
+eclass2 = [hnodes+ss onodes];
+if discrete_obs
+  dnodes = 1:ss;
+else
+  dnodes = hnodes;
+end
+bnet = mk_dbn(intra, inter, ns, 'discrete', dnodes, 'eclass1', eclass1, 'eclass2', eclass2, ...
+	      'observed', onodes);
+
+if rnd
+  for i=hnodes(:)'
+    bnet.CPD{i} = tabular_CPD(bnet, i);
+  end
+  for i=onodes(:)'
+    if discrete_obs
+      bnet.CPD{i} = tabular_CPD(bnet, i);
+    else
+      bnet.CPD{i} = gaussian_CPD(bnet, i);
+    end
+  end
+  for i=hnodes(:)'+ss
+    bnet.CPD{i} = tabular_CPD(bnet, i);
+  end
+else
+  for i=hnodes(:)'
+    bnet.CPD{i} = tabular_CPD(bnet, i, CPD{i}.CPT);
+  end
+  for i=onodes(:)'
+    if discrete_obs
+      bnet.CPD{i} = tabular_CPD(bnet, i, CPD{i}.CPT);
+    else
+      bnet.CPD{i} = gaussian_CPD(bnet, i, CPD{i}.mean, CPD{i}.cov);
+    end
+  end
+  for i=hnodes(:)'+ss
+    bnet.CPD{i} = tabular_CPD(bnet, i, CPD{i}.CPT);
+  end
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/mk_collage_from_clqs.m b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_collage_from_clqs.m
new file mode 100644
index 00000000..90159f7e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_collage_from_clqs.m
@@ -0,0 +1,44 @@
+function mk_collage_from_clqs(dir, cliques)
+
+% For use with mk_ps_from_clqs.
+% This generates a latex file that glues all the .ps files
+% into one big figure.
+
+cd(dir)
+C = length(cliques);
+
+ncols = 4;
+width = 1.5;
+fid = fopen('collage.tex', 'w');
+fprintf(fid, '\\documentclass{article}\n');
+fprintf(fid, '\\usepackage{psfig}\n');
+fprintf(fid, '\\begin{document}\n');
+fprintf(fid, '\\centerline{\n');
+fprintf(fid, '\\begin{tabular}{');
+for col=1:ncols,  fprintf(fid, 'c'); end
+fprintf(fid, '}\n');
+c = 1;
+for row = 1:floor(C/ncols)
+  for col=1:ncols-1
+    fname = sprintf('%s/clq%d.ps', dir, c);
+    fprintf(fid, '\\psfig{file=%s,width=%3fin} & \n', fname, width);
+    c = c + 1;
+  end
+  fname = sprintf('%s/clq%d.ps', dir, c);
+  fprintf(fid, '\\psfig{file=%s,width=%3fin} \\\\ \n', fname, width);
+  c = c + 1;
+end
+% last row
+while (c <= C)
+  fname = sprintf('%s/clq%d.ps', dir, c);
+  fprintf(fid, '\\psfig{file=%s,width=%3fin} & \n', fname, width);
+  c = c + 1;
+end
+fprintf(fid, '\\end{tabular}\n');
+fprintf(fid, '}\n');
+fprintf(fid, '\\end{document}');
+fclose(fid);
+
+!latex collage.tex &
+!dvips -o collage.ps collage.dvi &
+!ghostview collage.ps &
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/mk_fhmm.m b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_fhmm.m
new file mode 100644
index 00000000..ffbe05a5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_fhmm.m
@@ -0,0 +1,58 @@
+function bnet = mk_fhmm(N, Q, Y, discrete_obs)
+% MK_FHMM Make a factorial Hidden Markov Model
+%
+% There are N independent parallel hidden chains, each connected to the output
+%
+% e.g., N = 2 (vertical/diagonal edges point down)
+%
+% A1--->A2
+% | B1--|->B2
+% | /   |/
+% Y1    Y2
+%
+% [bnet, onode] = mk_chmm(n, q, y, discrete_obs)
+%
+% Each hidden node is discrete and has Q values.
+% If discrete_obs = 1, each observed node is discrete and has values 1..Y.
+% If discrete_obs = 0, each observed node is a Gaussian vector of length Y.
+
+if nargin < 2, Q = 2; end
+if nargin < 3, Y = 2; end
+if nargin < 4, discrete_obs = 1; end
+
+ss = N+1;
+hnodes = 1:N;
+onode = N+1;
+
+intra = zeros(ss);
+intra(hnodes, onode) = 1;
+
+inter = eye(ss);
+inter(onode,onode) = 0;
+
+ns = [Q*ones(1,N) Y];
+
+eclass1 = [hnodes onode];
+eclass2 = [hnodes+ss onode];
+if discrete_obs
+  dnodes = 1:ss;
+else
+  dnodes = hnodes;
+end
+bnet = mk_dbn(intra, inter, ns, 'discrete', dnodes, 'eclass1', eclass1, 'eclass2', eclass2, ...
+	      'observed', onode);
+
+for i=hnodes(:)'
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+end
+i = onode;
+if discrete_obs
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+else
+  bnet.CPD{i} = gaussian_CPD(bnet, i);
+end
+for i=hnodes(:)'+ss
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/mk_mildew_dbn.m b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_mildew_dbn.m
new file mode 100644
index 00000000..71f393e3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_mildew_dbn.m
@@ -0,0 +1,31 @@
+function bnet = mk_mildew_dbn()
+
+% DBN for foreacasting the gross yield of wheat based on climatic data,
+% observations of leaf area index (LAI) and extension of mildew,
+% and knowledge of amount of fungicides used and time of usage.
+% From Kjaerulff '95.
+
+Fungi=1; Mildew=2; LAI=3; Precip=4; Temp=5; Micro=6; Solar=7; Photo=8; Dry=9;
+n = 9;
+intra = zeros(n,n);
+intra(Mildew, LAI)=1;
+intra(LAI,[Micro Photo])=1;
+intra(Precip,Micro)=1;
+intra(Temp,[Micro Photo])=1;
+intra(Solar,Photo)=1;
+intra(Photo,Dry)=1;
+
+inter = zeros(n,n);
+inter(Fungi,Mildew)=1;
+inter(Mildew,Mildew)=1;
+inter(LAI,LAI)=1;
+inter(Micro,Mildew)=1;
+inter(Dry,Dry)=1;
+
+ns = 2*ones(1,n);
+bnet = mk_dbn(intra, inter, ns, 'observed', [Photo]);
+
+for e=1:max(bnet.equiv_class(:))
+  i = bnet.rep_of_eclass(e);
+  bnet.CPD{e} = tabular_CPD(bnet,i);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/mk_orig_bat_dbn.m b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_orig_bat_dbn.m
new file mode 100644
index 00000000..0065ad5e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_orig_bat_dbn.m
@@ -0,0 +1,198 @@
+function [bnet, names] = mk_orig_bat_dbn()
+% MK_BAT_DBN Make the BAT DBN
+% [bnet, names] = mk_bat_dbn()
+% See
+% - Forbes, Huang, Kanazawa and Russell, "The BATmobile: Towards a Bayesian Automated Taxi", IJCAI 95
+% - Boyen and Koller, "Tractable Inference for Complex Stochastic Processes", UAI98.
+
+names = {'LeftClr', 'RightClr', 'LatAct', 'Xdot', 'InLane', 'FwdAct', ...
+      'Ydot', 'Stopped', 'EngStatus', 'FBStatus', ...
+      'LeftClrSens', 'RightClrSens', 'TurnSignalSens', 'XdotSens', 'YdotSens', ...
+      'FYdotDiffSens', 'FclrSens', 'BXdotSens', 'BclrSens', 'BYdotDiffSens', ...
+      'SensorValid', 'FYdotDiff', 'FcloseSlow', 'Fclr', 'BXdot', 'BcloseFast', 'Bclr', 'BYdotDiff'};
+ss = length(names);
+
+intrac = {...
+      'LeftClr', 'LeftClrSens';
+  'RightClr', 'RightClrSens';
+  'LatAct', 'TurnSignalSens'; 'LatAct', 'Xdot';
+  'Xdot', 'XdotSens';
+  'FwdAct', 'Ydot';
+  'Ydot', 'YdotSens'; 'Ydot', 'Stopped';
+  'EngStatus', 'Ydot'; 'EngStatus', 'FYdotDiff'; 'EngStatus', 'Fclr'; 'EngStatus', 'BXdot';
+  'SensorValid', 'XdotSens';   'SensorValid', 'YdotSens';
+  'FYdotDiff', 'FYdotDiffSens'; 'FYdotDiff', 'FcloseSlow';
+  'FcloseSlow', 'FBStatus';
+  'Fclr', 'FclrSens'; 'Fclr', 'FcloseSlow';
+  'BXdot', 'BXdotSens';
+  'Bclr', 'BclrSens'; 'Bclr', 'BXdot'; 'Bclr', 'BcloseFast';
+  'BcloseFast', 'FBStatus';
+  'BYdotDiff', 'BYdotDiffSens'; 'BYdotDiff', 'BcloseFast'};
+[intra, names] = mk_adj_mat(intrac, names, 1);
+
+
+interc = {...
+      'LeftClr', 'LeftClr'; 'LeftClr', 'LatAct';
+  'RightClr', 'RightClr'; 'RightClr', 'LatAct';
+  'LatAct', 'LatAct'; 'LatAct', 'FwdAct';
+  'Xdot', 'Xdot'; 'Xdot', 'InLane';
+  'InLane', 'InLane'; 'InLane', 'LatAct';
+  'FwdAct', 'FwdAct';
+  'Ydot', 'Ydot';
+  'Stopped', 'Stopped';
+  'EngStatus', 'EngStatus';
+  'FBStatus', 'FwdAct'; 'FBStatus', 'LatAct'};
+inter = mk_adj_mat(interc, names, 0);  
+
+obs = {'LeftClrSens', 'RightClrSens', 'TurnSignalSens', 'XdotSens', 'YdotSens', 'FYdotDiffSens', ...
+      'FclrSens', 'BXdotSens', 'BclrSens', 'BYdotDiffSens'};
+
+for i=1:length(obs)
+  onodes(i) = stringmatch(obs{i}, names);
+end
+onodes = sort(onodes);
+
+dnodes = 1:ss; 
+ns = zeros(1,ss);
+
+ns(stringmatch('LeftClr', names)) = 2;
+ns(stringmatch('RightClr', names)) = 2;
+ns(stringmatch('LatAct', names)) = 3;
+ns(stringmatch('Xdot', names)) = 7;
+ns(stringmatch('InLane', names)) = 2;
+ns(stringmatch('FwdAct', names)) = 3;
+ns(stringmatch('Ydot', names)) = 11;
+ns(stringmatch('Stopped', names)) = 2;
+ns(stringmatch('EngStatus', names)) = 2;
+ns(stringmatch('FBStatus', names)) = 3;
+ns(stringmatch('LeftClrSens', names)) = 2;
+ns(stringmatch('RightClrSens', names)) = 2;
+ns(stringmatch('TurnSignalSens', names)) = 3;
+ns(stringmatch('XdotSens', names)) = 7;
+ns(stringmatch('YdotSens', names)) = 11;
+ns(stringmatch('FYdotDiffSens', names)) = 8;
+ns(stringmatch('FclrSens', names)) = 20;
+ns(stringmatch('BXdotSens', names)) = 8;
+ns(stringmatch('BclrSens', names)) = 20;
+ns(stringmatch('BYdotDiffSens', names)) = 8;
+ns(stringmatch('SensorValid', names)) = 2;
+ns(stringmatch('FYdotDiff', names)) = 4;
+ns(stringmatch('FcloseSlow', names)) = 2;
+ns(stringmatch('Fclr', names)) = 3;
+ns(stringmatch('BXdot', names)) = 8;
+ns(stringmatch('BcloseFast', names)) = 2;
+ns(stringmatch('Bclr', names)) = 3;
+ns(stringmatch('BYdotDiff', names)) = 4;
+
+%ns = 2*ones(1,ss);
+
+
+bnet = mk_dbn(intra, inter, ns, 'discrete', dnodes, 'observed', onodes, 'eclass2', (1:ss)+ss);
+
+% make unif params
+for i=1:2*ss
+  bnet.CPD{i} = tabular_CPD(bnet, i, 'CPT', 'unif');
+end
+
+i = stringmatch('LeftClr', names)+ss;
+bnet.CPD{i} = tabular_CPD(bnet, i, [0.99 0.01 0.01 0.99]);
+
+i = stringmatch('RightClr', names)+ss;
+bnet.CPD{i} = tabular_CPD(bnet, i, [0.99 0.01 0.01 0.99]);
+
+i = stringmatch('LatAct', names)+ss;
+bnet.CPD{i} = tabular_CPD(bnet, i, [0.166666666666667 0.975609756097561 0.111111111111111 0.961538461538462 0.00980392156862745 0.0380952380952381 0.00952380952380952 0.037037037037037 0.166666666666667 0.444444444444444 0.0048780487804878 0.0192307692307692 0.0384615384615385 0.888888888888889 0.0344827586206897 0.87719298245614 0.00819672131147541 0.032 0.008 0.03125 0.0384615384615385 0.137931034482759 0.00444444444444444 0.0175438596491228 0.166666666666667 0.975609756097561 0.111111111111111 0.961538461538462 0.166666666666667 0.8 0.04 0.454545454545455 0.166666666666667 0.444444444444444 0.0048780487804878 0.0192307692307692 0.0384615384615385 0.888888888888889 0.0344827586206897 0.87719298245614 0.0384615384615385 0.444444444444444 0.0222222222222222 0.3125 0.0384615384615385 0.137931034482759 0.00444444444444444 0.0175438596491228 0.166666666666667 0.975609756097561 0.111111111111111 0.961538461538462 0.166666666666667 0.8 0.04 0.454545454545455 0.166666666666667 0.444444444444444 0.0048780487804878 0.0192307692307692 0.0384615384615385 0.888888888888889 0.0344827586206897 0.87719298245614 0.0384615384615385 0.444444444444444 0.0222222222222222 0.3125 0.0384615384615385 0.137931034482759 0.00444444444444444 0.0175438596491228 0.666666666666667 0.0195121951219512 0.444444444444444 0.0192307692307692 0.980392156862745 0.952380952380952 0.952380952380952 0.925925925925926 0.666666666666667 0.444444444444444 0.0195121951219512 0.0192307692307692 0.923076923076923 0.106666666666667 0.827586206896552 0.105263157894737 0.983606557377049 0.96 0.96 0.9375 0.923076923076923 0.827586206896552 0.106666666666667 0.105263157894737 0.666666666666667 0.0195121951219512 0.444444444444444 0.0192307692307692 0.666666666666667 0.16 0.16 0.0909090909090909 0.666666666666667 0.444444444444444 0.0195121951219512 0.0192307692307692 0.923076923076923 0.106666666666667 0.827586206896552 0.105263157894737 0.923076923076923 0.533333333333333 0.533333333333333 0.375 0.923076923076923 0.827586206896552 0.106666666666667 0.105263157894737 0.666666666666667 0.0195121951219512 0.444444444444444 0.0192307692307692 0.666666666666667 0.16 0.16 0.0909090909090909 0.666666666666667 0.444444444444444 0.0195121951219512 0.0192307692307692 0.923076923076923 0.106666666666667 0.827586206896552 0.105263157894737 0.923076923076923 0.533333333333333 0.533333333333333 0.375 0.923076923076923 0.827586206896552 0.106666666666667 0.105263157894737 0.166666666666667 0.0048780487804878 0.444444444444444 0.0192307692307692 0.00980392156862745 0.00952380952380952 0.0380952380952381 0.037037037037037 0.166666666666667 0.111111111111111 0.975609756097561 0.961538461538462 0.0384615384615385 0.00444444444444444 0.137931034482759 0.0175438596491228 0.00819672131147541 0.008 0.032 0.03125 0.0384615384615385 0.0344827586206897 0.888888888888889 0.87719298245614 0.166666666666667 0.0048780487804878 0.444444444444444 0.0192307692307692 0.166666666666667 0.04 0.8 0.454545454545455 0.166666666666667 0.111111111111111 0.975609756097561 0.961538461538462 0.0384615384615385 0.00444444444444444 0.137931034482759 0.0175438596491228 0.0384615384615385 0.0222222222222222 0.444444444444444 0.3125 0.0384615384615385 0.0344827586206897 0.888888888888889 0.87719298245614 0.166666666666667 0.0048780487804878 0.444444444444444 0.0192307692307692 0.166666666666667 0.04 0.8 0.454545454545455 0.166666666666667 0.111111111111111 0.975609756097561 0.961538461538462 0.0384615384615385 0.00444444444444444 0.137931034482759 0.0175438596491228 0.0384615384615385 0.0222222222222222 0.444444444444444 0.3125 0.0384615384615385 0.0344827586206897 0.888888888888889 0.87719298245614]);
+
+i = stringmatch('Xdot', names)+ss;
+bnet.CPD{i} = tabular_CPD(bnet, i, [0.497512437810945 0.115207373271889 0.0564971751412429 0.0290697674418605 0.075187969924812 0.0300751879699248 0.0298507462686567 0.0980392156862745 0.0392156862745098 0.043956043956044 0.0294117647058824 0.0283687943262411 0.0392156862745098 0.0392156862745098 0.0373134328358209 0.0300751879699248 0.0300751879699248 0.0232558139534884 0.0225988700564972 0.0184331797235023 0.0199004975124378 0.373134328358209 0.460829493087558 0.282485875706215 0.290697674418605 0.37593984962406 0.075187969924812 0.0373134328358209 0.490196078431373 0.0980392156862745 0.043956043956044 0.0294117647058824 0.0283687943262411 0.0392156862745098 0.0392156862745098 0.0746268656716418 0.037593984962406 0.0300751879699248 0.0232558139534884 0.0225988700564972 0.0184331797235023 0.0199004975124378 0.0497512437810945 0.345622119815668 0.564971751412429 0.581395348837209 0.37593984962406 0.37593984962406 0.0746268656716418 0.245098039215686 0.490196078431373 0.21978021978022 0.0735294117647059 0.0354609929078014 0.0490196078431373 0.0392156862745098 0.373134328358209 0.075187969924812 0.037593984962406 0.0232558139534884 0.0225988700564972 0.0184331797235023 0.0199004975124378 0.0199004975124378 0.0230414746543779 0.0282485875706215 0.0290697674418605 0.075187969924812 0.37593984962406 0.373134328358209 0.0490196078431373 0.245098039215686 0.54945054945055 0.735294117647059 0.709219858156028 0.245098039215686 0.0490196078431373 0.373134328358209 0.37593984962406 0.075187969924812 0.0290697674418605 0.0282485875706215 0.0230414746543779 0.0199004975124378 0.0199004975124378 0.0184331797235023 0.0225988700564972 0.0232558139534884 0.037593984962406 0.075187969924812 0.373134328358209 0.0392156862745098 0.0490196078431373 0.0549450549450549 0.0735294117647059 0.141843971631206 0.490196078431373 0.245098039215686 0.0746268656716418 0.37593984962406 0.37593984962406 0.581395348837209 0.564971751412429 0.345622119815668 0.0497512437810945 0.0199004975124378 0.0184331797235023 0.0225988700564972 0.0232558139534884 0.0300751879699248 0.037593984962406 0.0746268656716418 0.0392156862745098 0.0392156862745098 0.043956043956044 0.0294117647058824 0.0283687943262411 0.0980392156862745 0.490196078431373 0.0373134328358209 0.075187969924812 0.37593984962406 0.290697674418605 0.282485875706215 0.460829493087558 0.373134328358209 0.0199004975124378 0.0184331797235023 0.0225988700564972 0.0232558139534884 0.0300751879699248 0.0300751879699248 0.0373134328358209 0.0392156862745098 0.0392156862745098 0.043956043956044 0.0294117647058824 0.0283687943262411 0.0392156862745098 0.0980392156862745 0.0298507462686567 0.0300751879699248 0.075187969924812 0.0290697674418605 0.0564971751412429 0.115207373271889 0.497512437810945]);
+
+i = stringmatch('InLane', names)+ss;
+bnet.CPD{i} = tabular_CPD(bnet, i, [0.5 0.3 0.5 0.3 0.5 0.3 0.9 0.01 0.5 0.3 0.5 0.3 0.5 0.3 0.5 0.7 0.5 0.7 0.5 0.7 0.1 0.99 0.5 0.7 0.5 0.7 0.5 0.7]);
+
+i = stringmatch('FwdAct', names)+ss;
+bnet.CPD{i} = tabular_CPD(bnet, i, [0.4 0.4 0.4 0.949050949050949 0.949050949050949 0.949050949050949 0.4 0.4 0.4 0.6 0.1 0.1 0.949050949050949 0.949050949050949 0.949050949050949 0.05 0.05 0.05 0.4 0.4 0.4 0.949050949050949 0.949050949050949 0.949050949050949 0.4 0.4 0.4 0.4 0.4 0.4 0.04995004995005 0.04995004995005 0.04995004995005 0.4 0.4 0.4 0.3 0.8 0.3 0.04995004995005 0.04995004995005 0.04995004995005 0.7 0.7 0.7 0.4 0.4 0.4 0.04995004995005 0.04995004995005 0.04995004995005 0.4 0.4 0.4 0.2 0.2 0.2 0.000999000999000999 0.000999000999000999 0.000999000999000999 0.2 0.2 0.2 0.1 0.1 0.6 0.000999000999000999 0.000999000999000999 0.000999000999000999 0.25 0.25 0.25 0.2 0.2 0.2 0.000999000999000999 0.000999000999000999 0.000999000999000999 0.2 0.2 0.2]);
+
+i = stringmatch('Ydot', names)+ss;
+bnet.CPD{i} = tabular_CPD(bnet, i, [0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.999880014398272 0.72463768115942 0.595238095238095 0.230414746543779 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.595238095238095 0.230414746543779 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.230414746543779 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.0144927536231884 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 9.99880014398272e-005 0.144927536231884 0.297619047619048 0.460829493087558 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.297619047619048 0.460829493087558 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.460829493087558 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.0144927536231884 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 0.0144927536231884 0.0595238095238095 0.230414746543779 0.442477876106195 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.0595238095238095 0.230414746543779 0.442477876106195 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.230414746543779 0.442477876106195 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.0144927536231884 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 9.99880014398272e-006 0.0144927536231884 0.00595238095238095 0.0460829493087558 0.221238938053097 0.442477876106195 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.0460829493087558 0.221238938053097 0.442477876106195 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.0460829493087558 0.221238938053097 0.442477876106195 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.0144927536231884 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0144927536231884 0.00595238095238095 0.00460829493087558 0.0442477876106195 0.221238938053097 0.442477876106195 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.00460829493087558 0.0442477876106195 0.221238938053097 0.442477876106195 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.00460829493087558 0.0442477876106195 0.221238938053097 0.442477876106195 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.0144927536231884 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0144927536231884 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.0442477876106195 0.221238938053097 0.442477876106195 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.0442477876106195 0.221238938053097 0.442477876106195 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.0442477876106195 0.221238938053097 0.442477876106195 0.221238938053097 0.0442477876106195 0.00442477876106195 0.00460829493087558 0.00595238095238095 0.0144927536231884 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0144927536231884 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.221238938053097 0.442477876106195 0.221238938053097 0.0442477876106195 0.00460829493087558 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.221238938053097 0.442477876106195 0.221238938053097 0.0442477876106195 0.00460829493087558 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.221238938053097 0.442477876106195 0.221238938053097 0.0442477876106195 0.00460829493087558 0.00595238095238095 0.0144927536231884 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0144927536231884 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.221238938053097 0.442477876106195 0.221238938053097 0.0460829493087558 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.221238938053097 0.442477876106195 0.221238938053097 0.0460829493087558 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.221238938053097 0.442477876106195 0.221238938053097 0.0460829493087558 0.00595238095238095 0.0144927536231884 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0144927536231884 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.221238938053097 0.442477876106195 0.230414746543779 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.221238938053097 0.442477876106195 0.230414746543779 0.0595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.221238938053097 0.442477876106195 0.230414746543779 0.0595238095238095 0.0144927536231884 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0144927536231884 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.221238938053097 0.460829493087558 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.221238938053097 0.460829493087558 0.297619047619048 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.221238938053097 0.460829493087558 0.297619047619048 0.144927536231884 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0144927536231884 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.230414746543779 0.00595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.230414746543779 0.595238095238095 0.00460829493087558 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.00442477876106195 0.0442477876106195 0.230414746543779 0.595238095238095 0.72463768115942]);
+
+i = stringmatch('Stopped', names)+ss;
+bnet.CPD{i} = tabular_CPD(bnet, i, [0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0]);
+
+i = stringmatch('EngStatus', names)+ss;
+bnet.CPD{i} = tabular_CPD(bnet, i, [0.9 1.0e-006 0.1 0.999999]);
+
+i = stringmatch('FBStatus', names)+ss;
+bnet.CPD{i} = tabular_CPD(bnet, i, [1.0 0.0 0.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0 1.0 0.0]);
+
+i = stringmatch('SensorValid', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [1.0e-004 0.9999]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [1.0e-004 0.9999]);
+
+i = stringmatch('FYdotDiff', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.908182726364545 0.238095238095238 0.000908182726364545 0.476190476190476 9.08182726364545e-005 0.238095238095238 0.0908182726364545 0.0476190476190476]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.908182726364545 0.238095238095238 0.000908182726364545 0.476190476190476 9.08182726364545e-005 0.238095238095238 0.0908182726364545 0.0476190476190476]);
+
+i = stringmatch('FcloseSlow', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [1.0 1.0 1.0 1.0 1.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [1.0 1.0 1.0 1.0 1.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0]);
+
+i = stringmatch('Fclr', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.000499750124937531 0.142857142857143 0.499750124937531 0.285714285714286 0.499750124937531 0.571428571428571]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.000499750124937531 0.142857142857143 0.499750124937531 0.285714285714286 0.499750124937531 0.571428571428571]);
+
+i = stringmatch('BXdot', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.00980392156862745 0.00980392156862745 0.00980392156862745 0.00980392156862745 0.0454545454545455 0.00980392156862745 0.0490196078431373 0.0490196078431373 0.0490196078431373 0.0490196078431373 0.136363636363636 0.0490196078431373 0.196078431372549 0.196078431372549 0.196078431372549 0.196078431372549 0.136363636363636 0.196078431372549 0.392156862745098 0.392156862745098 0.392156862745098 0.392156862745098 0.181818181818182 0.392156862745098 0.196078431372549 0.196078431372549 0.196078431372549 0.196078431372549 0.136363636363636 0.196078431372549 0.0490196078431373 0.0490196078431373 0.0490196078431373 0.0490196078431373 0.136363636363636 0.0490196078431373 0.00980392156862745 0.00980392156862745 0.00980392156862745 0.00980392156862745 0.0454545454545455 0.00980392156862745 0.0980392156862745 0.0980392156862745 0.0980392156862745 0.0980392156862745 0.181818181818182 0.0980392156862745]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.00980392156862745 0.00980392156862745 0.00980392156862745 0.00980392156862745 0.0454545454545455 0.00980392156862745 0.0490196078431373 0.0490196078431373 0.0490196078431373 0.0490196078431373 0.136363636363636 0.0490196078431373 0.196078431372549 0.196078431372549 0.196078431372549 0.196078431372549 0.136363636363636 0.196078431372549 0.392156862745098 0.392156862745098 0.392156862745098 0.392156862745098 0.181818181818182 0.392156862745098 0.196078431372549 0.196078431372549 0.196078431372549 0.196078431372549 0.136363636363636 0.196078431372549 0.0490196078431373 0.0490196078431373 0.0490196078431373 0.0490196078431373 0.136363636363636 0.0490196078431373 0.00980392156862745 0.00980392156862745 0.00980392156862745 0.00980392156862745 0.0454545454545455 0.00980392156862745 0.0980392156862745 0.0980392156862745 0.0980392156862745 0.0980392156862745 0.181818181818182 0.0980392156862745]);
+
+i = stringmatch('BcloseFast', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0]);
+
+i = stringmatch('Bclr', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.142857142857143 0.285714285714286 0.571428571428571]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.142857142857143 0.285714285714286 0.571428571428571]);
+
+i = stringmatch('BYdotDiff', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.238095238095238 0.476190476190476 0.238095238095238 0.0476190476190476]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.238095238095238 0.476190476190476 0.238095238095238 0.0476190476190476]);
+
+i = stringmatch('LeftClrSens', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.909090909090909 0.0909090909090909 0.0909090909090909 0.909090909090909]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.909090909090909 0.0909090909090909 0.0909090909090909 0.909090909090909]);
+
+i = stringmatch('RightClrSens', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.909090909090909 0.0909090909090909 0.0909090909090909 0.909090909090909]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.909090909090909 0.0909090909090909 0.0909090909090909 0.909090909090909]);
+
+i = stringmatch('TurnSignalSens', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.75 0.000998003992015968 0.01 0.24 0.998003992015968 0.24 0.01 0.000998003992015968 0.75]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.75 0.000998003992015968 0.01 0.24 0.998003992015968 0.24 0.01 0.000998003992015968 0.75]);
+
+i = stringmatch('XdotSens', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.142857142857143 0.897666068222621 0.142857142857143 0.0824402308326463 0.142857142857143 0.00818330605564648 0.142857142857143 0.000818330605564648 0.142857142857143 0.000818330605564648 0.142857142857143 0.000824402308326463 0.142857142857143 0.000897666068222621 0.142857142857143 0.0897666068222621 0.142857142857143 0.824402308326463 0.142857142857143 0.0818330605564648 0.142857142857143 0.00818330605564648 0.142857142857143 0.000818330605564648 0.142857142857143 0.000824402308326463 0.142857142857143 0.000897666068222621 0.142857142857143 0.00897666068222621 0.142857142857143 0.0824402308326463 0.142857142857143 0.818330605564648 0.142857142857143 0.0818330605564648 0.142857142857143 0.00818330605564648 0.142857142857143 0.000824402308326463 0.142857142857143 0.000897666068222621 0.142857142857143 0.000897666068222621 0.142857142857143 0.00824402308326463 0.142857142857143 0.0818330605564648 0.142857142857143 0.818330605564648 0.142857142857143 0.0818330605564648 0.142857142857143 0.00824402308326463 0.142857142857143 0.000897666068222621 0.142857142857143 0.000897666068222621 0.142857142857143 0.000824402308326463 0.142857142857143 0.00818330605564648 0.142857142857143 0.0818330605564648 0.142857142857143 0.818330605564648 0.142857142857143 0.0824402308326463 0.142857142857143 0.00897666068222621 0.142857142857143 0.000897666068222621 0.142857142857143 0.000824402308326463 0.142857142857143 0.000818330605564648 0.142857142857143 0.00818330605564648 0.142857142857143 0.0818330605564648 0.142857142857143 0.824402308326463 0.142857142857143 0.0897666068222621 0.142857142857143 0.000897666068222621 0.142857142857143 0.000824402308326463 0.142857142857143 0.000818330605564648 0.142857142857143 0.000818330605564648 0.142857142857143 0.00818330605564648 0.142857142857143 0.0824402308326463 0.142857142857143 0.897666068222621]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.142857142857143 0.897666068222621 0.142857142857143 0.0824402308326463 0.142857142857143 0.00818330605564648 0.142857142857143 0.000818330605564648 0.142857142857143 0.000818330605564648 0.142857142857143 0.000824402308326463 0.142857142857143 0.000897666068222621 0.142857142857143 0.0897666068222621 0.142857142857143 0.824402308326463 0.142857142857143 0.0818330605564648 0.142857142857143 0.00818330605564648 0.142857142857143 0.000818330605564648 0.142857142857143 0.000824402308326463 0.142857142857143 0.000897666068222621 0.142857142857143 0.00897666068222621 0.142857142857143 0.0824402308326463 0.142857142857143 0.818330605564648 0.142857142857143 0.0818330605564648 0.142857142857143 0.00818330605564648 0.142857142857143 0.000824402308326463 0.142857142857143 0.000897666068222621 0.142857142857143 0.000897666068222621 0.142857142857143 0.00824402308326463 0.142857142857143 0.0818330605564648 0.142857142857143 0.818330605564648 0.142857142857143 0.0818330605564648 0.142857142857143 0.00824402308326463 0.142857142857143 0.000897666068222621 0.142857142857143 0.000897666068222621 0.142857142857143 0.000824402308326463 0.142857142857143 0.00818330605564648 0.142857142857143 0.0818330605564648 0.142857142857143 0.818330605564648 0.142857142857143 0.0824402308326463 0.142857142857143 0.00897666068222621 0.142857142857143 0.000897666068222621 0.142857142857143 0.000824402308326463 0.142857142857143 0.000818330605564648 0.142857142857143 0.00818330605564648 0.142857142857143 0.0818330605564648 0.142857142857143 0.824402308326463 0.142857142857143 0.0897666068222621 0.142857142857143 0.000897666068222621 0.142857142857143 0.000824402308326463 0.142857142857143 0.000818330605564648 0.142857142857143 0.000818330605564648 0.142857142857143 0.00818330605564648 0.142857142857143 0.0824402308326463 0.142857142857143 0.897666068222621]);
+
+i = stringmatch('YdotSens', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.0909090909090909 0.894454382826476 0.0909090909090909 0.0821692686935086 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.0894454382826476 0.0909090909090909 0.821692686935086 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.00894454382826476 0.0909090909090909 0.0821692686935086 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.00821692686935086 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0821692686935086 0.0909090909090909 0.00894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.821692686935086 0.0909090909090909 0.0894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0821692686935086 0.0909090909090909 0.894454382826476]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.0909090909090909 0.894454382826476 0.0909090909090909 0.0821692686935086 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.0894454382826476 0.0909090909090909 0.821692686935086 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.00894454382826476 0.0909090909090909 0.0821692686935086 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.00821692686935086 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.00821692686935086 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.815660685154976 0.0909090909090909 0.0821692686935086 0.0909090909090909 0.00894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0815660685154976 0.0909090909090909 0.821692686935086 0.0909090909090909 0.0894454382826476 0.0909090909090909 0.000894454382826476 0.0909090909090909 0.000821692686935086 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.000815660685154976 0.0909090909090909 0.00815660685154975 0.0909090909090909 0.0821692686935086 0.0909090909090909 0.894454382826476]);
+
+i = stringmatch('FYdotDiffSens', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.53191206429753 0.00806445109313635 0.0053191206429753 9.9930048965724e-005 0.265956032148765 0.00806445109313635 0.0053191206429753 9.9930048965724e-005 0.132978016074383 0.0806445109313634 0.0053191206429753 9.9930048965724e-005 0.053191206429753 0.806445109313635 0.053191206429753 9.9930048965724e-005 0.0053191206429753 0.0806445109313634 0.132978016074383 9.9930048965724e-005 0.0053191206429753 0.00806445109313635 0.265956032148765 9.9930048965724e-005 0.0053191206429753 0.00806445109313635 0.53191206429753 9.9930048965724e-005 5.3191206429753e-006 8.06445109313635e-006 5.3191206429753e-006 0.99930048965724]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.53191206429753 0.00806445109313635 0.0053191206429753 9.9930048965724e-005 0.265956032148765 0.00806445109313635 0.0053191206429753 9.9930048965724e-005 0.132978016074383 0.0806445109313634 0.0053191206429753 9.9930048965724e-005 0.053191206429753 0.806445109313635 0.053191206429753 9.9930048965724e-005 0.0053191206429753 0.0806445109313634 0.132978016074383 9.9930048965724e-005 0.0053191206429753 0.00806445109313635 0.265956032148765 9.9930048965724e-005 0.0053191206429753 0.00806445109313635 0.53191206429753 9.9930048965724e-005 5.3191206429753e-006 8.06445109313635e-006 5.3191206429753e-006 0.99930048965724]);
+
+i = stringmatch('FclrSens', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.472366556447804 0.0044762757385855 6.20655412115194e-005 0.472366556447804 0.044762757385855 6.20655412115194e-005 0.0472366556447804 0.44762757385855 0.000620655412115194 0.000472366556447804 0.44762757385855 0.00620655412115194 0.000472366556447804 0.044762757385855 0.0620655412115194 0.000472366556447804 0.0044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.472366556447804 0.0044762757385855 6.20655412115194e-005 0.472366556447804 0.044762757385855 6.20655412115194e-005 0.0472366556447804 0.44762757385855 0.000620655412115194 0.000472366556447804 0.44762757385855 0.00620655412115194 0.000472366556447804 0.044762757385855 0.0620655412115194 0.000472366556447804 0.0044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194]);
+
+i = stringmatch('BXdotSens', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.689655172413793 0.172413793103448 0.0546448087431694 0.00546448087431694 0.00546448087431694 0.00546448087431694 0.00574712643678161 0.00689655172413793 0.206896551724138 0.574712643678161 0.163934426229508 0.0546448087431694 0.00546448087431694 0.00546448087431694 0.00574712643678161 0.00689655172413793 0.0689655172413793 0.172413793103448 0.546448087431694 0.163934426229508 0.0546448087431694 0.00546448087431694 0.00574712643678161 0.00689655172413793 0.00689655172413793 0.0574712643678161 0.163934426229508 0.546448087431694 0.163934426229508 0.0546448087431694 0.00574712643678161 0.00689655172413793 0.00689655172413793 0.00574712643678161 0.0546448087431694 0.163934426229508 0.546448087431694 0.163934426229508 0.0574712643678161 0.00689655172413793 0.00689655172413793 0.00574712643678161 0.00546448087431694 0.0546448087431694 0.163934426229508 0.546448087431694 0.172413793103448 0.0689655172413793 0.00689655172413793 0.00574712643678161 0.00546448087431694 0.00546448087431694 0.0546448087431694 0.163934426229508 0.574712643678161 0.206896551724138 0.00689655172413793 0.00574712643678161 0.00546448087431694 0.00546448087431694 0.00546448087431694 0.0546448087431694 0.172413793103448 0.689655172413793]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.689655172413793 0.172413793103448 0.0546448087431694 0.00546448087431694 0.00546448087431694 0.00546448087431694 0.00574712643678161 0.00689655172413793 0.206896551724138 0.574712643678161 0.163934426229508 0.0546448087431694 0.00546448087431694 0.00546448087431694 0.00574712643678161 0.00689655172413793 0.0689655172413793 0.172413793103448 0.546448087431694 0.163934426229508 0.0546448087431694 0.00546448087431694 0.00574712643678161 0.00689655172413793 0.00689655172413793 0.0574712643678161 0.163934426229508 0.546448087431694 0.163934426229508 0.0546448087431694 0.00574712643678161 0.00689655172413793 0.00689655172413793 0.00574712643678161 0.0546448087431694 0.163934426229508 0.546448087431694 0.163934426229508 0.0574712643678161 0.00689655172413793 0.00689655172413793 0.00574712643678161 0.00546448087431694 0.0546448087431694 0.163934426229508 0.546448087431694 0.172413793103448 0.0689655172413793 0.00689655172413793 0.00574712643678161 0.00546448087431694 0.00546448087431694 0.0546448087431694 0.163934426229508 0.574712643678161 0.206896551724138 0.00689655172413793 0.00574712643678161 0.00546448087431694 0.00546448087431694 0.00546448087431694 0.0546448087431694 0.172413793103448 0.689655172413793]);
+
+i = stringmatch('BclrSens', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.472366556447804 0.0044762757385855 6.20655412115194e-005 0.472366556447804 0.044762757385855 6.20655412115194e-005 0.0472366556447804 0.44762757385855 0.000620655412115194 0.000472366556447804 0.44762757385855 0.00620655412115194 0.000472366556447804 0.044762757385855 0.0620655412115194 0.000472366556447804 0.0044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.472366556447804 0.0044762757385855 6.20655412115194e-005 0.472366556447804 0.044762757385855 6.20655412115194e-005 0.0472366556447804 0.44762757385855 0.000620655412115194 0.000472366556447804 0.44762757385855 0.00620655412115194 0.000472366556447804 0.044762757385855 0.0620655412115194 0.000472366556447804 0.0044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194 0.000472366556447804 0.00044762757385855 0.0620655412115194]);
+
+i = stringmatch('BYdotDiffSens', names);
+%bnet.CPD{i} = tabular_CPD(bnet, i, [0.53191206429753 0.00806445109313635 0.0053191206429753 9.9930048965724e-005 0.265956032148765 0.00806445109313635 0.0053191206429753 9.9930048965724e-005 0.132978016074383 0.0806445109313634 0.0053191206429753 9.9930048965724e-005 0.053191206429753 0.806445109313635 0.053191206429753 9.9930048965724e-005 0.0053191206429753 0.0806445109313634 0.132978016074383 9.9930048965724e-005 0.0053191206429753 0.00806445109313635 0.265956032148765 9.9930048965724e-005 0.0053191206429753 0.00806445109313635 0.53191206429753 9.9930048965724e-005 5.3191206429753e-006 8.06445109313635e-006 5.3191206429753e-006 0.99930048965724]);
+bnet.CPD{i+ss} = tabular_CPD(bnet, i+ss, [0.53191206429753 0.00806445109313635 0.0053191206429753 9.9930048965724e-005 0.265956032148765 0.00806445109313635 0.0053191206429753 9.9930048965724e-005 0.132978016074383 0.0806445109313634 0.0053191206429753 9.9930048965724e-005 0.053191206429753 0.806445109313635 0.053191206429753 9.9930048965724e-005 0.0053191206429753 0.0806445109313634 0.132978016074383 9.9930048965724e-005 0.0053191206429753 0.00806445109313635 0.265956032148765 9.9930048965724e-005 0.0053191206429753 0.00806445109313635 0.53191206429753 9.9930048965724e-005 5.3191206429753e-006 8.06445109313635e-006 5.3191206429753e-006 0.99930048965724]);
+%BIF2BNT added a bunch of zeros at the end of this cpd. Hopefully the only occurence of this bug!  0 0 0 0 0 0 0 0]);
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/mk_orig_water_dbn.m b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_orig_water_dbn.m
new file mode 100644
index 00000000..67a4e24a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_orig_water_dbn.m
@@ -0,0 +1,121 @@
+function dbn = mk_orig_water_dbn
+% Converted by Frank Hutter:
+%   Provided in Phrog format by Xavier Boyen.
+%   Manually converted into BIF.
+%   Converted to BNT from BIF by Web-based bif2bnt (2004-01-30T05:28:10)
+%   Manually converted into function creating DBN.
+%   Manually changed the node numbering s.t. A-B-C-D-E-F-G-H from the BK paper correspond to 1-2-3-4-5-6-7-8
+
+node = struct('C_NI_12_ANT', 1, ...
+              'CKNI_12_ANT', 2, ...
+              'CBODD_12_ANT', 3, ...
+              'CNOD_12_ANT', 4, ...
+              'CBODN_12_ANT', 5, ...
+              'CNON_12_ANT', 6, ...
+              'CKND_12_ANT', 7, ...
+              'CKNN_12_ANT', 8, ...
+              'C_NI_12_OBS', 9, ...
+              'CKNI_12_OBS', 10, ...
+              'CBODD_12_OBS', 11, ...
+              'CNOD_12_OBS', 12, ...
+              'CBODN_12_OBS', 13, ...
+              'CNON_12_OBS', 14, ...
+              'CKND_12_OBS', 15, ...
+              'CKNN_12_OBS', 16, ...
+              'C_NI_12_ULT', 17, ...
+              'CKNI_12_ULT', 18, ...
+              'CBODD_12_ULT', 19, ...
+              'CNOD_12_ULT', 20, ...
+              'CBODN_12_ULT', 21, ...
+              'CNON_12_ULT', 22, ...
+              'CKND_12_ULT', 23, ...
+              'CKNN_12_ULT', 24);
+
+adjacency = zeros(24);
+adjacency([node.C_NI_12_ANT], node.C_NI_12_OBS) = 1;
+adjacency([node.CKNI_12_ANT], node.CKNI_12_OBS) = 1;
+adjacency([node.CBODD_12_ANT], node.CBODD_12_OBS) = 1;
+adjacency([node.CKND_12_ANT], node.CKND_12_OBS) = 1;
+adjacency([node.CNOD_12_ANT], node.CNOD_12_OBS) = 1;
+adjacency([node.CBODN_12_ANT], node.CBODN_12_OBS) = 1;
+adjacency([node.CKNN_12_ANT], node.CKNN_12_OBS) = 1;
+adjacency([node.CNON_12_ANT], node.CNON_12_OBS) = 1;
+adjacency([node.C_NI_12_ANT], node.C_NI_12_ULT) = 1;
+adjacency([node.CKNI_12_ANT], node.CKNI_12_ULT) = 1;
+adjacency([node.CBODN_12_ANT node.CNOD_12_ANT node.CBODD_12_ANT node.CKNI_12_ANT node.C_NI_12_ANT], node.CBODD_12_ULT) = 1;
+adjacency([node.CKNN_12_ANT node.CKND_12_ANT node.CKNI_12_ANT], node.CKND_12_ULT) = 1;
+adjacency([node.CNON_12_ANT node.CNOD_12_ANT node.CBODD_12_ANT], node.CNOD_12_ULT) = 1;
+adjacency([node.CNON_12_ANT node.CBODN_12_ANT node.CBODD_12_ANT], node.CBODN_12_ULT) = 1;
+adjacency([node.CKNN_12_ANT node.CKND_12_ANT], node.CKNN_12_ULT) = 1;
+adjacency([node.CNON_12_ANT node.CKNN_12_ANT node.CBODN_12_ANT node.CNOD_12_ANT], node.CNON_12_ULT) = 1;
+
+ss = 16;
+dnodes = 1:ss;
+ant = 1:8;
+onodes = 9:16;
+ult = 17:24;
+intra = adjacency(1:ss, 1:ss);
+inter_real = adjacency(ant, ult);
+inter = zeros(ss);
+inter(ant,1:length(ult)) = inter_real;
+
+eclass1 = 1:16;
+eclass2 = [17:24 9:16];
+
+value = {{'zz3num'; 'zz4num'; 'zz5num'; 'zz6num'}, ...
+         {'zz20mgl'; 'zz30mgl'; 'zz40mgl'}, ...
+         {'zz15mgl'; 'zz20mgl'; 'zz25mgl'; 'zz30mgl'}, ...
+         {'zz05mgl'; 'zz1mgl'; 'zz2mgl'; 'zz4mgl'}, ...
+         {'zz5mgl'; 'zz10mgl'; 'zz15mgl'; 'zz20mgl'}, ...
+         {'zz2mgl'; 'zz4mgl'; 'zz6mgl'; 'zz10mgl'}, ...
+         {'zz2mgl'; 'zz4mgl'; 'zz6mgl'}, ...
+         {'zz05mgl'; 'zz1mgl'; 'zz2mgl'}, ...
+         {'zz3num'; 'zz4num'; 'zz5num'; 'zz6num'}, ...
+         {'zz20mgl'; 'zz30mgl'; 'zz40mgl'}, ...
+         {'zz15mgl'; 'zz20mgl'; 'zz25mgl'; 'zz30mgl'}, ...
+         {'zz05mgl'; 'zz1mgl'; 'zz2mgl'; 'zz4mgl'}, ...
+         {'zz5mgl'; 'zz10mgl'; 'zz15mgl'; 'zz20mgl'}, ...
+         {'zz2mgl'; 'zz4mgl'; 'zz6mgl'; 'zz10mgl'}, ...
+         {'zz2mgl'; 'zz4mgl'; 'zz6mgl'}, ...
+         {'zz05mgl'; 'zz1mgl'; 'zz2mgl'}, ...
+         {'zz3num'; 'zz4num'; 'zz5num'; 'zz6num'}, ...
+         {'zz20mgl'; 'zz30mgl'; 'zz40mgl'}, ...
+         {'zz15mgl'; 'zz20mgl'; 'zz25mgl'; 'zz30mgl'}, ...
+         {'zz05mgl'; 'zz1mgl'; 'zz2mgl'; 'zz4mgl'}, ...
+         {'zz5mgl'; 'zz10mgl'; 'zz15mgl'; 'zz20mgl'}, ...
+         {'zz2mgl'; 'zz4mgl'; 'zz6mgl'; 'zz10mgl'}, ...
+         {'zz2mgl'; 'zz4mgl'; 'zz6mgl'}, ...
+         {'zz05mgl'; 'zz1mgl'; 'zz2mgl'}};
+          
+ns = zeros(1,24);
+for i=1:24
+    ns(i) = length(value{i});
+end
+
+dbn = mk_dbn(intra, inter, ns, 'discrete', dnodes, 'eclass1', eclass1, 'eclass2', eclass2, ...
+	      'observed', onodes);
+
+dbn.CPD{node.C_NI_12_ANT} = tabular_CPD(dbn, node.C_NI_12_ANT, 1/ns(1) * ones(1,ns(1)));
+dbn.CPD{node.CKNI_12_ANT} = tabular_CPD(dbn, node.CKNI_12_ANT, 1/ns(2) * ones(1,ns(2)));
+dbn.CPD{node.CBODD_12_ANT} = tabular_CPD(dbn, node.CBODD_12_ANT, 1/ns(3) * ones(1,ns(3)));
+dbn.CPD{node.CNOD_12_ANT} = tabular_CPD(dbn, node.CNOD_12_ANT, 1/ns(4) * ones(1,ns(4)));
+dbn.CPD{node.CBODN_12_ANT} = tabular_CPD(dbn, node.CBODN_12_ANT, 1/ns(5) * ones(1,ns(5)));
+dbn.CPD{node.CNON_12_ANT} = tabular_CPD(dbn, node.CNON_12_ANT, 1/ns(6) * ones(1,ns(6)));
+dbn.CPD{node.CKND_12_ANT} = tabular_CPD(dbn, node.CKND_12_ANT, 1/ns(7) * ones(1,ns(7)));
+dbn.CPD{node.CKNN_12_ANT} = tabular_CPD(dbn, node.CKNN_12_ANT, 1/ns(8) * ones(1,ns(8)));
+dbn.CPD{node.C_NI_12_OBS} = tabular_CPD(dbn, node.C_NI_12_OBS, [0.7 0.1 0.1 0.1 0.1 0.7 0.1 0.1 0.1 0.1 0.7 0.1 0.1 0.1 0.1 0.7]);
+dbn.CPD{node.CKNI_12_OBS} = tabular_CPD(dbn, node.CKNI_12_OBS, [0.8 0.1 0.1 0.1 0.8 0.1 0.1 0.1 0.8]);
+dbn.CPD{node.CBODD_12_OBS} = tabular_CPD(dbn, node.CBODD_12_OBS, [0.7 0.1 0.1 0.1 0.1 0.7 0.1 0.1 0.1 0.1 0.7 0.1 0.1 0.1 0.1 0.7]);
+dbn.CPD{node.CKND_12_OBS} = tabular_CPD(dbn, node.CKND_12_OBS, [0.8 0.1 0.1 0.1 0.8 0.1 0.1 0.1 0.8]);
+dbn.CPD{node.CNOD_12_OBS} = tabular_CPD(dbn, node.CNOD_12_OBS, [0.7 0.1 0.1 0.1 0.1 0.7 0.1 0.1 0.1 0.1 0.7 0.1 0.1 0.1 0.1 0.7]);
+dbn.CPD{node.CBODN_12_OBS} = tabular_CPD(dbn, node.CBODN_12_OBS, [0.7 0.1 0.1 0.1 0.1 0.7 0.1 0.1 0.1 0.1 0.7 0.1 0.1 0.1 0.1 0.7]);
+dbn.CPD{node.CKNN_12_OBS} = tabular_CPD(dbn, node.CKNN_12_OBS, [0.8 0.1 0.1 0.1 0.8 0.1 0.1 0.1 0.8]);
+dbn.CPD{node.CNON_12_OBS} = tabular_CPD(dbn, node.CNON_12_OBS, [0.7 0.1 0.1 0.1 0.1 0.7 0.1 0.1 0.1 0.1 0.7 0.1 0.1 0.1 0.1 0.7]);
+dbn.CPD{node.C_NI_12_ULT} = tabular_CPD(dbn, node.C_NI_12_ULT, [0.5 0.2 0.1 0 0.4 0.55 0.3 0.15 0.1 0.2 0.5 0.25 0 0.05 0.1 0.6]);
+dbn.CPD{node.CKNI_12_ULT} = tabular_CPD(dbn, node.CKNI_12_ULT, [0.48 0.2 0.04 0.48 0.6 0.48 0.04 0.2 0.48]);
+dbn.CPD{node.CBODD_12_ULT} = tabular_CPD(dbn, node.CBODD_12_ULT, [1 1 0.9791 0.9473 0.9949 0.9473 0.8997 0.8521 0.9473 0.8838 0.8203 0.7568 0.0903 0.0585 0.0268 0 0.0426 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0.9951 0.9634 1 0.9634 0.9158 0.8681 0.9634 0.8999 0.8364 0.7729 0.109 0.0773 0.0455 0.0138 0.0614 0.0138 0 0 0.0138 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0.9762 1 0.9762 0.9286 0.881 0.9762 0.9127 0.8493 0.7858 0.124 0.0923 0.0605 0.0288 0.0764 0.0288 0 0 0.0288 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0.9848 1 0.9848 0.9372 0.8896 0.9848 0.9213 0.8578 0.7943 0.134 0.1023 0.0705 0.0388 0.0864 0.0388 0 0 0.0388 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0.9791 0.9473 0.9156 0.9632 0.9156 0.8679 0.8203 0.9156 0.8521 0.7886 0.7251 0.0585 0.0268 0 0 0.0109 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0.9951 0.9634 0.9316 0.9793 0.9316 0.884 0.8364 0.9316 0.8681 0.8046 0.7412 0.0773 0.0455 0.0138 0 0.0296 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0.9762 0.9445 0.9921 0.9445 0.8969 0.8493 0.9445 0.881 0.8175 0.754 0.0923 0.0605 0.0288 0 0.0446 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0.9848 0.9531 1 0.9531 0.9054 0.8578 0.9531 0.8896 0.8261 0.7626 0.1023 0.0705 0.0388 0.007 0.0546 0.007 0 0 0.007 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.9791 0.9473 0.9156 0.8838 0.9314 0.8838 0.8362 0.7886 0.8838 0.8203 0.7568 0.6933 0.0268 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.9951 0.9634 0.9316 0.8999 0.9475 0.8999 0.8523 0.8046 0.8999 0.8364 0.7729 0.7094 0.0455 0.0138 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0.9762 0.9445 0.9127 0.9604 0.9127 0.8651 0.8175 0.9127 0.8493 0.7858 0.7223 0.0605 0.0288 0 0 0.0129 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0.9848 0.9531 0.9213 0.9689 0.9213 0.8737 0.8261 0.9213 0.8578 0.7943 0.7308 0.0705 0.0388 0.007 0 0.0229 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.9473 0.9156 0.8838 0.8521 0.8997 0.8521 0.8045 0.7568 0.8521 0.7886 0.7251 0.6616 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.9634 0.9316 0.8999 0.8681 0.9158 0.8681 0.8205 0.7729 0.8681 0.8046 0.7412 0.6777 0.0138 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.9762 0.9445 0.9127 0.881 0.9286 0.881 0.8334 0.7858 0.881 0.8175 0.754 0.6905 0.0288 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.9848 0.9531 0.9213 0.8896 0.9372 0.8896 0.842 0.7943 0.8896 0.8261 0.7626 0.6991 0.0388 0.007 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0209 0.0527 0.0051 0.0527 0.1003 0.1479 0.0527 0.1162 0.1797 0.2432 0.9097 0.9415 0.9732 0.995 0.9574 0.995 0.9474 0.8998 0.995 0.9315 0.868 0.8045 0.1362 0.1045 0.0727 0.041 0.0886 0.041 0 0 0.041 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0049 0.0366 0 0.0366 0.0842 0.1319 0.0366 0.1001 0.1636 0.2271 0.891 0.9227 0.9545 0.9862 0.9386 0.9862 0.9662 0.9185 0.9862 0.9503 0.8868 0.8233 0.157 0.1253 0.0935 0.0618 0.1094 0.0618 0.0142 0 0.0618 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0238 0 0.0238 0.0714 0.119 0.0238 0.0873 0.1507 0.2142 0.876 0.9077 0.9395 0.9712 0.9236 0.9712 0.9812 0.9335 0.9712 0.9653 0.9018 0.8383 0.1737 0.142 0.1102 0.0785 0.1261 0.0785 0.0308 0 0.0785 0.015 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0152 0 0.0152 0.0628 0.1104 0.0152 0.0787 0.1422 0.2057 0.866 0.8977 0.9295 0.9612 0.9136 0.9612 0.9912 0.9435 0.9612 0.9753 0.9118 0.8483 0.1848 0.1531 0.1213 0.0896 0.1372 0.0896 0.042 0 0.0896 0.0261 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0209 0.0527 0.0844 0.0368 0.0844 0.1321 0.1797 0.0844 0.1479 0.2114 0.2749 0.9415 0.9732 0.995 0.9633 0.9891 0.9633 0.9157 0.868 0.9633 0.8998 0.8363 0.7728 0.1045 0.0727 0.041 0.0092 0.0568 0.0092 0 0 0.0092 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0049 0.0366 0.0684 0.0207 0.0684 0.116 0.1636 0.0684 0.1319 0.1954 0.2588 0.9227 0.9545 0.9862 0.982 0.9704 0.982 0.9344 0.8868 0.982 0.9185 0.855 0.7916 0.1253 0.0935 0.0618 0.03 0.0777 0.03 0 0 0.03 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0238 0.0555 0.0079 0.0555 0.1031 0.1507 0.0555 0.119 0.1825 0.246 0.9077 0.9395 0.9712 0.997 0.9554 0.997 0.9494 0.9018 0.997 0.9335 0.87 0.8066 0.142 0.1102 0.0785 0.0467 0.0943 0.0467 0 0 0.0467 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0152 0.0469 0 0.0469 0.0946 0.1422 0.0469 0.1104 0.1739 0.2374 0.8977 0.9295 0.9612 0.993 0.9454 0.993 0.9594 0.9118 0.993 0.9435 0.88 0.8166 0.1531 0.1213 0.0896 0.0578 0.1054 0.0578 0.0102 0 0.0578 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0209 0.0527 0.0844 0.1162 0.0686 0.1162 0.1638 0.2114 0.1162 0.1797 0.2432 0.3067 0.9732 0.995 0.9633 0.9315 0.9792 0.9315 0.8839 0.8363 0.9315 0.868 0.8045 0.7411 0.0727 0.041 0.0092 0 0.0251 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0049 0.0366 0.0684 0.1001 0.0525 0.1001 0.1477 0.1954 0.1001 0.1636 0.2271 0.2906 0.9545 0.9862 0.982 0.9503 0.9979 0.9503 0.9027 0.855 0.9503 0.8868 0.8233 0.7598 0.0935 0.0618 0.03 0 0.0459 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0238 0.0555 0.0873 0.0396 0.0873 0.1349 0.1825 0.0873 0.1507 0.2142 0.2777 0.9395 0.9712 0.997 0.9653 0.9871 0.9653 0.9177 0.87 0.9653 0.9018 0.8383 0.7748 0.1102 0.0785 0.0467 0.015 0.0626 0.015 0 0 0.015 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0152 0.0469 0.0787 0.0311 0.0787 0.1263 0.1739 0.0787 0.1422 0.2057 0.2692 0.9295 0.9612 0.993 0.9753 0.9771 0.9753 0.9277 0.88 0.9753 0.9118 0.8483 0.7848 0.1213 0.0896 0.0578 0.0261 0.0737 0.0261 0 0 0.0261 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0527 0.0844 0.1162 0.1479 0.1003 0.1479 0.1955 0.2432 0.1479 0.2114 0.2749 0.3384 0.995 0.9633 0.9315 0.8998 0.9474 0.8998 0.8522 0.8045 0.8998 0.8363 0.7728 0.7093 0.041 0.0092 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0366 0.0684 0.1001 0.1319 0.0842 0.1319 0.1795 0.2271 0.1319 0.1954 0.2588 0.3223 0.9862 0.982 0.9503 0.9185 0.9662 0.9185 0.8709 0.8233 0.9185 0.855 0.7916 0.7281 0.0618 0.03 0 0 0.0142 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0238 0.0555 0.0873 0.119 0.0714 0.119 0.1666 0.2142 0.119 0.1825 0.246 0.3095 0.9712 0.997 0.9653 0.9335 0.9812 0.9335 0.8859 0.8383 0.9335 0.87 0.8066 0.7431 0.0785 0.0467 0.015 0 0.0308 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0152 0.0469 0.0787 0.1104 0.0628 0.1104 0.158 0.2057 0.1104 0.1739 0.2374 0.3009 0.9612 0.993 0.9753 0.9435 0.9912 0.9435 0.8959 0.8483 0.9435 0.88 0.8166 0.7531 0.0896 0.0578 0.0261 0 0.042 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.005 0 0.005 0.0526 0.1002 0.005 0.0685 0.132 0.1955 0.8638 0.8955 0.9273 0.959 0.9114 0.959 0.9933 0.9457 0.959 0.9775 0.914 0.8505 0.1809 0.1491 0.1174 0.0856 0.1333 0.0856 0.038 0 0.0856 0.0221 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0338 0.0815 0 0.0497 0.1132 0.1767 0.843 0.8747 0.9065 0.9382 0.8906 0.9382 0.9858 0.9666 0.9382 0.9983 0.9348 0.8713 0.2034 0.1716 0.1399 0.1081 0.1558 0.1081 0.0605 0.0129 0.1081 0.0446 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0188 0.0665 0 0.0347 0.0982 0.1617 0.8263 0.858 0.8898 0.9215 0.8739 0.9215 0.9692 0.9832 0.9215 0.985 0.9515 0.888 0.2214 0.1896 0.1579 0.1261 0.1738 0.1261 0.0785 0.0309 0.1261 0.0626 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0088 0.0565 0 0.0247 0.0882 0.1517 0.8152 0.8469 0.8787 0.9104 0.8628 0.9104 0.958 0.9943 0.9104 0.9739 0.9626 0.8991 0.2334 0.2016 0.1699 0.1381 0.1858 0.1381 0.0905 0.0429 0.1381 0.0746 0.0112 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.005 0.0367 0 0.0367 0.0843 0.132 0.0367 0.1002 0.1637 0.2272 0.8955 0.9273 0.959 0.9908 0.9432 0.9908 0.9616 0.914 0.9908 0.9457 0.8822 0.8187 0.1491 0.1174 0.0856 0.0539 0.1015 0.0539 0.0063 0 0.0539 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.018 0 0.018 0.0656 0.1132 0.018 0.0815 0.145 0.2084 0.8747 0.9065 0.9382 0.97 0.9223 0.97 0.9824 0.9348 0.97 0.9666 0.9031 0.8396 0.1716 0.1399 0.1081 0.0764 0.124 0.0764 0.0288 0 0.0764 0.0129 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.003 0 0.003 0.0506 0.0982 0.003 0.0665 0.13 0.1934 0.858 0.8898 0.9215 0.9533 0.9057 0.9533 0.9991 0.9515 0.9533 0.9832 0.9197 0.8562 0.1896 0.1579 0.1261 0.0944 0.142 0.0944 0.0468 0 0.0944 0.0309 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0406 0.0882 0 0.0565 0.12 0.1834 0.8469 0.8787 0.9104 0.9422 0.8946 0.9422 0.9898 0.9626 0.9422 0.9943 0.9308 0.8673 0.2016 0.1699 0.1381 0.1064 0.154 0.1064 0.0588 0.0112 0.1064 0.0429 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.005 0.0367 0.0685 0.0208 0.0685 0.1161 0.1637 0.0685 0.132 0.1955 0.2589 0.9273 0.959 0.9908 0.9775 0.9749 0.9775 0.9298 0.8822 0.9775 0.914 0.8505 0.787 0.1174 0.0856 0.0539 0.0221 0.0698 0.0221 0 0 0.0221 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.018 0.0497 0.0021 0.0497 0.0973 0.145 0.0497 0.1132 0.1767 0.2402 0.9065 0.9382 0.97 0.9983 0.9541 0.9983 0.9507 0.9031 0.9983 0.9348 0.8713 0.8078 0.1399 0.1081 0.0764 0.0446 0.0923 0.0446 0 0 0.0446 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.003 0.0347 0 0.0347 0.0823 0.13 0.0347 0.0982 0.1617 0.2252 0.8898 0.9215 0.9533 0.985 0.9374 0.985 0.9673 0.9197 0.985 0.9515 0.888 0.8245 0.1579 0.1261 0.0944 0.0626 0.1103 0.0626 0.015 0 0.0626 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0247 0 0.0247 0.0723 0.12 0.0247 0.0882 0.1517 0.2152 0.8787 0.9104 0.9422 0.9739 0.9263 0.9739 0.9785 0.9308 0.9739 0.9626 0.8991 0.8356 0.1699 0.1381 0.1064 0.0746 0.1223 0.0746 0.027 0 0.0746 0.0112 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.005 0.0367 0.0685 0.1002 0.0526 0.1002 0.1478 0.1955 0.1002 0.1637 0.2272 0.2907 0.959 0.9908 0.9775 0.9457 0.9933 0.9457 0.8981 0.8505 0.9457 0.8822 0.8187 0.7552 0.0856 0.0539 0.0221 0 0.038 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.018 0.0497 0.0815 0.0338 0.0815 0.1291 0.1767 0.0815 0.145 0.2084 0.2719 0.9382 0.97 0.9983 0.9666 0.9858 0.9666 0.9189 0.8713 0.9666 0.9031 0.8396 0.7761 0.1081 0.0764 0.0446 0.0129 0.0605 0.0129 0 0 0.0129 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.003 0.0347 0.0665 0.0188 0.0665 0.1141 0.1617 0.0665 0.13 0.1934 0.2569 0.9215 0.9533 0.985 0.9832 0.9692 0.9832 0.9356 0.888 0.9832 0.9197 0.8562 0.7927 0.1261 0.0944 0.0626 0.0309 0.0785 0.0309 0 0 0.0309 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0247 0.0565 0.0088 0.0565 0.1041 0.1517 0.0565 0.12 0.1834 0.2469 0.9104 0.9422 0.9739 0.9943 0.958 0.9943 0.9467 0.8991 0.9943 0.9308 0.8673 0.8039 0.1381 0.1064 0.0746 0.0429 0.0905 0.0429 0 0 0.0429 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0067 0.0543 0 0.0225 0.086 0.1495 0.8191 0.8509 0.8826 0.9144 0.8667 0.9144 0.962 1 0.9144 0.9779 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0334 0 0.0017 0.0652 0.1287 0.7966 0.8284 0.8601 0.8919 0.8442 0.8919 0.9395 0.9871 0.8919 0.9554 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0168 0 0 0.0485 0.112 0.7786 0.8104 0.8421 0.8739 0.8262 0.8739 0.9215 0.9691 0.8739 0.9374 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0057 0 0 0.0374 0.1009 0.7666 0.7984 0.8301 0.8619 0.8142 0.8619 0.9095 0.9571 0.8619 0.9254 0.9888 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0384 0.086 0 0.0543 0.1178 0.1813 0.8509 0.8826 0.9144 0.9461 0.8985 0.9461 0.9937 1 0.9461 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0176 0.0652 0 0.0334 0.0969 0.1604 0.8284 0.8601 0.8919 0.9236 0.876 0.9236 0.9712 1 0.9236 0.9871 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0009 0.0485 0 0.0168 0.0803 0.1438 0.8104 0.8421 0.8739 0.9056 0.858 0.9056 0.9532 1 0.9056 0.9691 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0374 0 0.0057 0.0692 0.1327 0.7984 0.8301 0.8619 0.8936 0.846 0.8936 0.9412 0.9888 0.8936 0.9571 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0225 0 0.0225 0.0702 0.1178 0.0225 0.086 0.1495 0.213 0.8826 0.9144 0.9461 0.9779 0.9302 0.9779 1 1 0.9779 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0017 0 0.0017 0.0493 0.0969 0.0017 0.0652 0.1287 0.1922 0.8601 0.8919 0.9236 0.9554 0.9077 0.9554 1 1 0.9554 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0327 0.0803 0 0.0485 0.112 0.1755 0.8421 0.8739 0.9056 0.9374 0.8897 0.9374 0.985 1 0.9374 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0215 0.0692 0 0.0374 0.1009 0.1644 0.8301 0.8619 0.8936 0.9254 0.8777 0.9254 0.973 1 0.9254 0.9888 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0225 0.0543 0.0067 0.0543 0.1019 0.1495 0.0543 0.1178 0.1813 0.2448 0.9144 0.9461 0.9779 1 0.962 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0017 0.0334 0 0.0334 0.0811 0.1287 0.0334 0.0969 0.1604 0.2239 0.8919 0.9236 0.9554 0.9871 0.9395 0.9871 1 1 0.9871 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0168 0 0.0168 0.0644 0.112 0.0168 0.0803 0.1438 0.2073 0.8739 0.9056 0.9374 0.9691 0.9215 0.9691 1 1 0.9691 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0057 0 0.0057 0.0533 0.1009 0.0057 0.0692 0.1327 0.1961 0.8619 0.8936 0.9254 0.9571 0.9095 0.9571 1 1 0.9571 1 1 1]);
+dbn.CPD{node.CKND_12_ULT} = tabular_CPD(dbn, node.CKND_12_ULT, [0.9524 0.9127 0.873 0 0 0 0 0 0 0.9444 0.9048 0.8651 0 0 0 0 0 0 0.9286 0.8889 0.8492 0 0 0 0 0 0 0.0476 0.0873 0.127 0.9921 0.9524 0.9127 0.0317 0 0 0.0556 0.0952 0.1349 0.9841 0.9444 0.9048 0.0238 0 0 0.0714 0.1111 0.1508 0.9683 0.9286 0.8889 0.0079 0 0 0 0 0 0.0079 0.0476 0.0873 0.9683 1 1 0 0 0 0.0159 0.0556 0.0952 0.9762 1 1 0 0 0 0.0317 0.0714 0.1111 0.9921 1 1]);
+dbn.CPD{node.CNOD_12_ULT} = tabular_CPD(dbn, node.CNOD_12_ULT, [1 1 1 1 0.3675 0.4905 0.5862 0.6627 0 0 0 0 0 0 0 0 1 1 1 1 0.2405 0.3635 0.4592 0.5358 0 0 0 0 0 0 0 0 0.8893 0.9816 1 1 0.1135 0.2366 0.3322 0.4088 0 0 0 0 0 0 0 0 0.6354 0.7276 0.7994 0.8568 0 0 0.0783 0.1548 0 0 0 0 0 0 0 0 0 0 0 0 0.6325 0.5095 0.4138 0.3373 0.2972 0.3711 0.4285 0.4744 0 0 0 0 0 0 0 0 0.7595 0.6365 0.5408 0.4642 0.2338 0.3076 0.365 0.4109 0 0 0 0 0.1107 0.0184 0 0 0.8865 0.7634 0.6678 0.5912 0.1703 0.2441 0.3015 0.3474 0 0 0 0 0.3646 0.2724 0.2006 0.1432 0.9298 0.9913 0.9217 0.8452 0.0433 0.1171 0.1745 0.2204 0 0 0 0 0 0 0 0 0 0 0 0 0.7028 0.6289 0.5715 0.5256 0.2129 0.2539 0.2858 0.3113 0 0 0 0 0 0 0 0 0.7662 0.6924 0.635 0.5891 0.1812 0.2222 0.2541 0.2796 0 0 0 0 0 0 0 0 0.8297 0.7559 0.6985 0.6526 0.1494 0.1904 0.2223 0.2478 0 0 0 0 0.0702 0.0087 0 0 0.9567 0.8829 0.8255 0.7796 0.0859 0.1269 0.1588 0.1843 0 0 0 0 0 0 0 0 0 0 0 0 0.7871 0.7461 0.7142 0.6887 0 0 0 0 0 0 0 0 0 0 0 0 0.8188 0.7778 0.7459 0.7204 0 0 0 0 0 0 0 0 0 0 0 0 0.8506 0.8096 0.7777 0.7522 0 0 0 0 0 0 0 0 0 0 0 0 0.9141 0.8731 0.8412 0.8157]);
+dbn.CPD{node.CBODN_12_ULT} = tabular_CPD(dbn, node.CBODN_12_ULT, [0.9557 0.9067 0.8577 0.8087 0.0406 0 0 0 0 0 0 0 0 0 0 0 0.9561 0.9071 0.8581 0.809 0.0412 0 0 0 0 0 0 0 0 0 0 0 0.9562 0.9072 0.8582 0.8092 0.0414 0 0 0 0 0 0 0 0 0 0 0 0.9564 0.9073 0.8583 0.8093 0.0416 0 0 0 0 0 0 0 0 0 0 0 0.0443 0.0933 0.1423 0.1913 0.9594 0.9916 0.9426 0.8936 0.1152 0.0662 0.0172 0 0 0 0 0 0.0439 0.0929 0.1419 0.191 0.9588 0.9922 0.9432 0.8942 0.116 0.067 0.018 0 0 0 0 0 0.0438 0.0928 0.1418 0.1908 0.9586 0.9924 0.9434 0.8944 0.1163 0.0673 0.0183 0 0 0 0 0 0.0436 0.0927 0.1417 0.1907 0.9584 0.9926 0.9436 0.8946 0.1166 0.0676 0.0185 0 0 0 0 0 0 0 0 0 0 0.0084 0.0574 0.1064 0.8848 0.9338 0.9828 0.9682 0.1835 0.1344 0.0854 0.0364 0 0 0 0 0 0.0078 0.0568 0.1058 0.884 0.933 0.982 0.969 0.1844 0.1354 0.0863 0.0373 0 0 0 0 0 0.0076 0.0566 0.1056 0.8837 0.9327 0.9817 0.9693 0.1847 0.1357 0.0867 0.0377 0 0 0 0 0 0.0074 0.0564 0.1054 0.8834 0.9324 0.9815 0.9695 0.185 0.136 0.087 0.038 0 0 0 0 0 0 0 0 0 0 0 0.0318 0.8165 0.8656 0.9146 0.9636 0 0 0 0 0 0 0 0 0 0 0 0.031 0.8156 0.8646 0.9137 0.9627 0 0 0 0 0 0 0 0 0 0 0 0.0307 0.8153 0.8643 0.9133 0.9623 0 0 0 0 0 0 0 0 0 0 0 0.0305 0.815 0.864 0.913 0.962]);
+dbn.CPD{node.CKNN_12_ULT} = tabular_CPD(dbn, node.CKNN_12_ULT, [1 1 0.8234 0.4459 0.2499 0.0538 0 0 0 0 0 0.1766 0.5541 0.7501 0.9462 0.3627 0.2646 0.1666 0 0 0 0 0 0 0.6373 0.7354 0.8334]);
+dbn.CPD{node.CNON_12_ULT} = tabular_CPD(dbn, node.CNON_12_ULT, [0.9555 0.9432 0.9187 0.8697 0.9618 0.9495 0.925 0.876 0.9662 0.954 0.9295 0.8804 0.9696 0.9573 0.9328 0.8838 0.9102 0.8979 0.8734 0.8244 0.9164 0.9042 0.8797 0.8306 0.9209 0.9086 0.8841 0.8351 0.9243 0.912 0.8875 0.8385 0.8648 0.8526 0.8281 0.779 0.8711 0.8588 0.8343 0.7853 0.8756 0.8633 0.8388 0.7898 0.8789 0.8667 0.8422 0.7931 0.0056 0 0 0 0.0125 0.0003 0 0 0.0175 0.0052 0 0 0.0212 0.009 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0445 0.0568 0.0813 0.1303 0.0382 0.0505 0.075 0.124 0.0338 0.046 0.0705 0.1196 0.0304 0.0427 0.0672 0.1162 0.0898 0.1021 0.1266 0.1756 0.0836 0.0958 0.1203 0.1694 0.0791 0.0914 0.1159 0.1649 0.0757 0.088 0.1125 0.1615 0.1352 0.1474 0.1719 0.221 0.1289 0.1412 0.1657 0.2147 0.1244 0.1367 0.1612 0.2102 0.1211 0.1333 0.1578 0.2069 0.9944 0.9933 0.9688 0.9198 0.9875 0.9997 0.9758 0.9267 0.9825 0.9948 0.9807 0.9317 0.9788 0.991 0.9845 0.9354 0.9602 0.948 0.9235 0.8744 0.9672 0.9549 0.9304 0.8814 0.9722 0.9599 0.9354 0.8864 0.9759 0.9636 0.9391 0.8901 0.9149 0.9026 0.8781 0.8291 0.9219 0.9096 0.8851 0.8361 0.9268 0.9146 0.8901 0.841 0.9306 0.9183 0.8938 0.8448 0.055 0.0427 0.0182 0 0.0622 0.05 0.0254 0 0.0674 0.0551 0.0306 0 0.0712 0.059 0.0345 0 0.0096 0 0 0 0.0169 0.0046 0 0 0.022 0.0098 0 0 0.0259 0.0137 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0067 0.0312 0.0802 0 0 0.0242 0.0733 0 0 0.0193 0.0683 0 0 0.0155 0.0646 0.0398 0.052 0.0765 0.1256 0.0328 0.0451 0.0696 0.1186 0.0278 0.0401 0.0646 0.1136 0.0241 0.0364 0.0609 0.1099 0.0851 0.0974 0.1219 0.1709 0.0781 0.0904 0.1149 0.1639 0.0732 0.0854 0.1099 0.159 0.0694 0.0817 0.1062 0.1552 0.945 0.9573 0.9818 0.9846 0.9378 0.95 0.9746 0.9882 0.9326 0.9449 0.9694 0.9908 0.9288 0.941 0.9655 0.9927 0.9904 0.9987 0.9864 0.9619 0.9831 0.9954 0.9901 0.9655 0.978 0.9902 0.9926 0.9681 0.9741 0.9863 0.9946 0.9701 0.9822 0.976 0.9638 0.9393 0.9858 0.9796 0.9674 0.9429 0.9884 0.9822 0.97 0.9455 0.9903 0.9842 0.9719 0.9474 0.0767 0.0706 0.0583 0.0338 0.0804 0.0743 0.062 0.0375 0.0831 0.0769 0.0647 0.0402 0.0851 0.0789 0.0667 0.0422 0.054 0.0479 0.0356 0.0111 0.0577 0.0516 0.0394 0.0149 0.0604 0.0543 0.042 0.0175 0.0624 0.0563 0.044 0.0195 0.0313 0.0252 0.013 0 0.0351 0.0289 0.0167 0 0.0377 0.0316 0.0194 0 0.0397 0.0336 0.0214 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0154 0 0 0 0.0118 0 0 0 0.0092 0 0 0 0.0073 0 0.0013 0.0136 0.0381 0 0 0.0099 0.0345 0 0 0.0074 0.0319 0 0 0.0054 0.0299 0.0178 0.024 0.0362 0.0607 0.0142 0.0204 0.0326 0.0571 0.0116 0.0178 0.03 0.0545 0.0097 0.0158 0.0281 0.0526 0.9233 0.9294 0.9417 0.9662 0.9196 0.9257 0.938 0.9625 0.9169 0.9231 0.9353 0.9598 0.9149 0.9211 0.9333 0.9578 0.946 0.9521 0.9644 0.9889 0.9423 0.9484 0.9606 0.9851 0.9396 0.9457 0.958 0.9825 0.9376 0.9437 0.956 0.9805 0.9687 0.9748 0.987 1 0.9649 0.9711 0.9833 1 0.9623 0.9684 0.9806 1 0.9603 0.9664 0.9786 1]);
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/mk_ps_from_clqs.m b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_ps_from_clqs.m
new file mode 100644
index 00000000..6e469446
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_ps_from_clqs.m
@@ -0,0 +1,44 @@
+function mk_ps_from_clqs(dbn, T, cliques, dir)
+
+% Draw multiple copies of the DBN,
+% and indicate the nodes in each clique by shading the nodes.
+% Generate a series of color postscript files,
+% or, if dir=[], displays them to the screen and pauses.
+
+if isempty(dir)
+  print_to_file = 0;
+else
+  print_to_file = 1;
+end
+
+if print_to_file, cd(dir), end
+flip = 1;
+clf;
+[dummyx, dummyy, h] = draw_dbn(dbn.intra, dbn.inter, flip, T, -1);
+
+C = length(cliques);
+
+% nodes = [];
+% for i=1:C
+%   cl = cliques{i};
+%   nodes = [nodes cl(:)'];
+% end
+%nodes = unique(nodes);
+ss = length(dbn.intra);
+nodes = 1:(ss*T);
+
+for c=1:C
+  for i=cliques{c}
+    set(h(i,2), 'facecolor', 'r'); 
+  end
+  rest = mysetdiff(nodes, cliques{c});
+  for i=rest
+    set(h(i,2), 'facecolor', 'w'); 
+  end
+  if print_to_file
+    print(gcf, '-depsc', sprintf('clq%d.ps', c))
+  else
+   disp(['clique ' num2str(c) ' = ' num2str(cliques{c}) '; hit key for next'])
+    pause
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/mk_uffe_dbn.m b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_uffe_dbn.m
new file mode 100644
index 00000000..2e881dc1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_uffe_dbn.m
@@ -0,0 +1,14 @@
+function bnet = mk_uffe_dbn()
+
+% Make the Uffe DBN from fig 3.4 p55 of my thesis
+
+ss = 4;
+intra = zeros(ss,ss);
+intra(1,[2 3])=1;
+intra(2,3)=1;
+intra(3,4)=1;
+inter = zeros(ss,ss);
+inter(1,1)=1;
+inter(4,4)=1;
+ns = 2*ones(1,ss);
+bnet = mk_dbn(intra, inter, ns);
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/mk_water_dbn.m b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_water_dbn.m
new file mode 100644
index 00000000..38cc5124
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/mk_water_dbn.m
@@ -0,0 +1,68 @@
+function bnet = mk_water_dbn(discrete_obs, obs_leaves)
+% MK_WATER_DBN
+% bnet = mk_water_dbn(discrete_obs, obs_leaves)
+%
+% If discrete_obs = 1 (default), the leaves are binary, else scalar Gaussians
+% If obs_leaves = 1, all the leaves are observed, otherwise rnd nodes are observed
+%
+% This is a model of the biological processes of a water purification plant, developed
+% by Finn V. Jensen, Uffe Kjærulff, Kristian G. Olesen, and Jan Pedersen.
+% See http://www-nt.cs.berkeley.edu/home/nir/public_html/Repository/water.htm
+% See also Boyen and Koller, "Tractable Inference for Complex Stochastic Processes", UAI98
+
+if nargin < 1, discrete_obs = 1; end
+if nargin < 1, obs_leaves = 1; end
+
+ss = 12;
+intra = zeros(ss);
+intra(1,9) = 1;
+intra(3,10) = 1;
+intra(4,11) = 1;
+intra(8,12) = 1;
+
+inter = zeros(ss);
+inter(1, [1 3]) = 1;
+inter(2, [2 3 7]) = 1;
+inter(3, [3 4 5]) = 1;
+inter(4, [3 4 6]) = 1;
+inter(5, [3 5 6]) = 1;
+inter(6, [4 5 6]) = 1;
+inter(7, [7 8]) = 1;
+inter(8, [6 7 8]) = 1;
+
+if obs_leaves
+  onodes = 9:12; % leaves
+else
+  onodes = [1 5 9:12]; % throw in some other nodes
+end
+hnodes = 1:8;
+if discrete_obs
+  ns = 2*ones(1 ,ss);
+  dnodes = 1:ss;
+else
+  ns = [2*ones(1,length(hnodes)) 1*ones(length(onodes))];
+  dnodes = hnodes;
+end
+
+eclass1 = 1:12;
+eclass2 = [13:20 9:12];
+bnet = mk_dbn(intra, inter, ns, 'discrete', dnodes, 'eclass1', eclass1, 'eclass2', eclass2, ...
+	      'observed', onodes);
+if discrete_obs
+  for i=1:max(eclass2)
+    bnet.CPD{i} = tabular_CPD(bnet, i);
+  end
+else
+  for i=hnodes(:)'
+    bnet.CPD{i} = tabular_CPD(bnet, i);
+  end
+  for i=onodes(:)'
+    bnet.CPD{i} = gaussian_CPD(bnet, i);
+  end
+  for i=hnodes(:)'+ss
+    bnet.CPD{i} = tabular_CPD(bnet, i);
+  end
+end
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/orig_water1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/orig_water1.m
new file mode 100644
index 00000000..7daa533c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/orig_water1.m
@@ -0,0 +1,28 @@
+% Compare the speeds of various inference engines on the water DBN
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+%bnet = mk_water_dbn;
+bnet = mk_orig_water_dbn;
+
+T = 3;
+engine = {};
+%engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet));
+%engine{end+1} = smoother_engine(hmm_2TBN_inf_engine(bnet));
+%engine{end+1} = jtree_dbn_inf_engine(bnet);
+engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T);
+engine{end+1} = cbk_inf_engine(bnet, 'clusters', {[1],[2],[3],[4],[5],[6],[7],[8]}); %ff
+engine{end+1} = cbk_inf_engine(bnet, 'clusters', {[1 2],[3 4 5 6],[7 8]}); %manually designed marginally independent by BK
+engine{end+1} = cbk_inf_engine(bnet, 'clusters', {[1:5], [3:7], [7:8]}); %manually designed conditionally independent by BK
+engine{end+1} = cbk_inf_engine(bnet, 'clusters', {[1 3], [2 3 7], [3 5], [3 4 7], [6 7 8]}); %automatically found using TJTs offline 
+engine{end+1} = cbk_inf_engine(bnet, 'clusters', {[1 3 5], [2 3 5 7], [3 4 7], [4 6 7], [6 7 8]}); %automatically found using TJTs offline 
+engine{end+1} = cbk_inf_engine(bnet, 'clusters', {[1 3 4 5], [2 3 4 7 8], [4 6 7 8]}); %automatically found using TJTs offline 
+
+% bk_inf_engine yields exactly the same results for the marginally independent cases. 
+%engine{end+1} = bk_inf_engine(bnet, 'clusters', 'ff');
+%engine{end+1} = bk_inf_engine(bnet, 'clusters', { [1 2], [3 4 5 6], [7 8] });
+
+
+inf_time = cmp_inference_dbn(bnet, engine, T, 'exact', 1)
+learning_time = cmp_learning_dbn(bnet, engine, T, 'exact', 1)
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/reveal1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/reveal1.m
new file mode 100644
index 00000000..938f4b46
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/reveal1.m
@@ -0,0 +1,73 @@
+% Make a DBN with the following inter-connectivity matrix
+%    1
+%   /  \
+%  2   3
+%   \ /
+%    4 
+%    |
+%    5
+% where all arcs point down. In addition, there are persistence arcs from each node to itself.
+% There are no intra-slice connections.
+% Nodes have noisy-or CPDs.
+% Node 1 turns on spontaneously due to its leaky source.
+% This effect trickles down to the other nodes in the order shown.
+% All the other nodes inhibit their leaks.
+% None of the nodes inhibit the connection from themselves, so that once they are on, they remain
+% on (persistence).
+%
+% This model was used in the experiments reported in
+% - "Learning the structure of DBNs", Friedman, Murphy and Russell, UAI 1998.
+% where the structure was learned even in the presence of missing data.
+% In that paper, we used the structural EM algorithm.
+% Here, we assume full observability and tabular CPDs for the learner, so we can use a much
+% simpler learning algorithm.
+
+ss = 5;
+
+inter = eye(ss);
+inter(1,[2 3]) = 1;
+inter(2,4)=1;
+inter(3,4)=1;
+inter(4,5)=1;
+
+intra = zeros(ss);
+ns = 2*ones(1,ss);
+
+bnet = mk_dbn(intra, inter, ns);
+
+% All nodes start out off
+for i=1:ss
+  bnet.CPD{i} = tabular_CPD(bnet, i, [1.0 0.0]');
+end
+
+% The following params correspond to Fig 4a in the UAI 98 paper
+% The first arg is the leak inhibition prob.
+% The vector contains the inhib probs from the parents in the previous slice;
+% the last element is self, which is never inhibited.
+bnet.CPD{1+ss} = noisyor_CPD(bnet, 1+ss, 0.8, 0);
+bnet.CPD{2+ss} = noisyor_CPD(bnet, 2+ss, 1, [0.9 0]);
+bnet.CPD{3+ss} = noisyor_CPD(bnet, 3+ss, 1, [0.8 0]);
+bnet.CPD{4+ss} = noisyor_CPD(bnet, 4+ss, 1, [0.7 0.6 0]);
+bnet.CPD{5+ss} = noisyor_CPD(bnet, 5+ss, 1, [0.5 0]);
+
+
+% Generate some training data
+
+nseqs = 20;
+seqs = cell(1,nseqs);
+T = 30;
+for i=1:nseqs
+  seqs{i} = sample_dbn(bnet, T);
+end
+
+max_fan_in = 3; % let's cheat a little here
+
+% computing num. incorrect edges as a fn of the size of the training set
+%sz = [5 10 15 20];    
+sz = [5 10];    
+h = zeros(1, length(sz));
+for i=1:length(sz)
+  inter2 = learn_struct_dbn_reveal(seqs(1:sz(i)), ns, max_fan_in);
+  h(i) = sum(abs(inter(:)-inter2(:))); % hamming distance
+end
+h
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/scg_dbn.m b/sourcecodes/bnt-master/BNT/examples/dynamic/scg_dbn.m
new file mode 100644
index 00000000..7281e58c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/scg_dbn.m
@@ -0,0 +1,39 @@
+% Test whether stable conditional Gaussian inference works
+% Make a linear dynamical system
+%   X1 -> X2
+%   |     | 
+%   v     v
+%   Y1    Y2 
+
+intra = zeros(2);
+intra(1,2) = 1;
+inter = zeros(2);
+inter(1,1) = 1;
+n = 2;
+
+X = 2; % size of hidden state
+Y = 2; % size of observable state
+
+ns = [X Y];
+bnet = mk_dbn(intra, inter, ns, 'discrete', [], 'observed', 2);
+
+x0 = rand(X,1);
+V0 = eye(X);
+C0 = rand(Y,X);
+R0 = eye(Y);
+A0 = rand(X,X);
+Q0 = eye(X);
+
+bnet.CPD{1} = gaussian_CPD(bnet, 1, 'mean', x0, 'cov', V0);
+bnet.CPD{2} = gaussian_CPD(bnet, 2, 'mean', zeros(Y,1), 'cov', R0, 'weights', C0);
+bnet.CPD{3} = gaussian_CPD(bnet, 3, 'mean', zeros(X,1), 'cov', Q0, 'weights', A0);
+
+
+T = 5; % fixed length sequences
+
+engine = {};
+engine{end+1} = kalman_inf_engine(bnet);
+engine{end+1} = scg_unrolled_dbn_inf_engine(bnet, T);
+engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T);
+
+inf_time = cmp_inference_dbn(bnet, engine, T, 'check_ll', 0);
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/skf_data_assoc_gmux.m b/sourcecodes/bnt-master/BNT/examples/dynamic/skf_data_assoc_gmux.m
new file mode 100644
index 00000000..31fdeda9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/skf_data_assoc_gmux.m
@@ -0,0 +1,139 @@
+% We consider a switching Kalman filter of the kind studied
+% by Zoubin Ghahramani, i.e., where the switch node determines
+% which of the hidden chains we get to observe (data association).
+% e.g., for n=2 chains
+% 
+% X1 -> X1
+% | X2 -> X2
+% \ |
+%  v
+%  Y
+%  ^
+%  |
+%  S
+%
+% Y is a gmux (multiplexer) node, where S switches in one of the parents.
+% We differ from Zoubin by not connecting the S nodes over time (which
+% doesn't make sense for data association).
+% Indeed, we assume the S nodes are always observed.
+% 
+%
+% We will track 2 objects (points) moving in the plane, as in BNT/Kalman/tracking_demo.
+% We will alternate between observing them.
+
+nobj = 2;
+N = nobj+2;
+Xs = 1:nobj;
+S = nobj+1;
+Y = nobj+2;
+
+intra = zeros(N,N);
+inter = zeros(N,N);
+intra([Xs S], Y) =1;
+for i=1:nobj
+  inter(Xs(i), Xs(i))=1;
+end
+
+Xsz = 4; % state space = (x y xdot ydot)
+Ysz = 2;
+ns = zeros(1,N);
+ns(Xs) = Xsz;
+ns(Y) = Ysz;
+ns(S) = n;
+
+bnet = mk_dbn(intra, inter, ns, 'discrete', S, 'observed', [S Y]);
+
+% For each object, we have
+% X(t+1) = F X(t) + noise(Q)
+% Y(t) = H X(t) + noise(R)
+F = [1 0 1 0; 0 1 0 1; 0 0 1 0; 0 0 0 1];
+H = [1 0 0 0; 0 1 0 0];
+Q = 1e-3*eye(Xsz);
+%R = 1e-3*eye(Ysz);
+R = eye(Ysz);
+
+% We initialise object 1 moving to the right, and object 2 moving to the left
+% (Here, we assume nobj=2)
+init_state{1} = [10 10 1 0]';
+init_state{2} = [10 -10 -1 0]';
+
+for i=1:nobj
+  bnet.CPD{Xs(i)} = gaussian_CPD(bnet, Xs(i), 'mean', init_state{i}, 'cov', 1e-4*eye(Xsz));
+end
+bnet.CPD{S} = root_CPD(bnet, S); % always observed
+bnet.CPD{Y} = gmux_CPD(bnet, Y, 'cov', repmat(R, [1 1 nobj]), 'weights', repmat(H, [1 1 nobj]));
+% slice 2
+eclass = bnet.equiv_class;
+for i=1:nobj
+  bnet.CPD{eclass(Xs(i), 2)} = gaussian_CPD(bnet, Xs(i)+N, 'mean', zeros(Xsz,1), 'cov', Q, 'weights', F);
+end
+
+% Observe objects at random
+T = 10;
+evidence = cell(N, T);
+data_assoc = sample_discrete(normalise(ones(1,nobj)), 1, T);
+evidence(S,:) = num2cell(data_assoc);
+evidence = sample_dbn(bnet, 'evidence', evidence);
+
+% plot the data
+true_state = cell(1,nobj);
+for i=1:nobj
+  true_state{i} = cell2num(evidence(Xs(i), :)); % true_state{i}(:,t) = [x y xdot ydot]'
+end
+obs_pos = cell2num(evidence(Y,:));
+figure(1)
+clf
+hold on
+styles = {'rx', 'go', 'b+', 'k*'};
+for i=1:nobj
+  plot(true_state{i}(1,:), true_state{i}(2,:), styles{i});
+end
+for t=1:T
+  text(obs_pos(1,t), obs_pos(2,t), sprintf('%d', t));
+end
+hold off
+relax_axes(0.1)
+
+
+% Inference
+ev = cell(N,T);
+ev(bnet.observed,:) = evidence(bnet.observed, :);
+
+engines = {};
+engines{end+1} = jtree_dbn_inf_engine(bnet);
+%engines{end+1} = scg_unrolled_dbn_inf_engine(bnet, T);
+engines{end+1} = pearl_unrolled_dbn_inf_engine(bnet);
+E = length(engines);
+
+inferred_state = cell(nobj,E); % inferred_state{i,e}(:,t)
+for e=1:E
+  engines{e} = enter_evidence(engines{e}, ev);
+  for i=1:nobj
+    inferred_state{i,e} = zeros(4, T);
+    for t=1:T
+      m = marginal_nodes(engines{e}, Xs(i), t);
+      inferred_state{i,e}(:,t) = m.mu;
+    end
+  end
+end
+inferred_state{1,1}
+inferred_state{1,2}
+
+% Plot results
+figure(2)
+clf
+hold on
+styles = {'rx', 'go', 'b+', 'k*'};
+nstyles = length(styles);
+c = 1;
+for e=1:E
+  for i=1:nobj
+    plot(inferred_state{i,e}(1,:), inferred_state{i,e}(2,:), styles{mod(c-1,nstyles)+1});
+    c = c + 1;
+  end
+end
+for t=1:T
+  text(obs_pos(1,t), obs_pos(2,t), sprintf('%d', t));
+end
+hold off
+relax_axes(0.1)
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/viterbi1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/viterbi1.m
new file mode 100644
index 00000000..6ad07d91
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/viterbi1.m
@@ -0,0 +1,47 @@
+% Compute Viterbi path discrete HMM by different methods
+
+intra = zeros(2);
+intra(1,2) = 1;
+inter = zeros(2);
+inter(1,1) = 1;
+n = 2;
+
+Q = 2; % num hidden states
+O = 2; % num observable symbols
+
+ns = [Q O];
+dnodes = 1:2;
+onodes = [2];
+eclass1 = [1 2];
+eclass2 = [3 2];
+bnet = mk_dbn(intra, inter, ns, 'discrete', dnodes, 'eclass1', eclass1, 'eclass2', eclass2, ...
+	      'observed', onodes);
+
+for seed=1:10
+rand('state', seed);
+prior = normalise(rand(Q,1));
+transmat = mk_stochastic(rand(Q,Q));
+obsmat = mk_stochastic(rand(Q,O));
+bnet.CPD{1} = tabular_CPD(bnet, 1, prior);
+bnet.CPD{2} = tabular_CPD(bnet, 2, obsmat);
+bnet.CPD{3} = tabular_CPD(bnet, 3, transmat);
+
+
+% Create a sequence
+T = 5; 
+ev = sample_dbn(bnet, T);
+evidence = cell(2,T);
+evidence(2,:) = ev(2,:); % extract observed component
+data = cell2num(ev(2,:));
+
+%obslik = mk_dhmm_obs_lik(data, obsmat);
+obslik = multinomial_prob(data, obsmat);
+path = viterbi_path(prior, transmat, obslik);
+
+engine = {};
+engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet));
+
+mpe = find_mpe(engine{1}, evidence);
+
+assert(isequal(cell2num(mpe(1,:)), path)) % extract values of hidden nodes
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/water1.m b/sourcecodes/bnt-master/BNT/examples/dynamic/water1.m
new file mode 100644
index 00000000..7dcf205f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/water1.m
@@ -0,0 +1,20 @@
+% Compare the speeds of various inference engines on the water DBN
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+bnet = mk_water_dbn;
+
+T = 3;
+engine = {};
+engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet));
+engine{end+1} = smoother_engine(hmm_2TBN_inf_engine(bnet));
+engine{end+1} = jtree_dbn_inf_engine(bnet);
+engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T); 
+
+%engine{end+1} = bk_inf_engine(bnet, 'ff', onodes);
+%engine{end+1} = bk_inf_engine(bnet, { [1 2], [3 4 5 6], [7 8] }, onodes);
+
+inf_time = cmp_inference_dbn(bnet, engine, T)
+learning_time = cmp_learning_dbn(bnet, engine, T)
+
diff --git a/sourcecodes/bnt-master/BNT/examples/dynamic/water2.m b/sourcecodes/bnt-master/BNT/examples/dynamic/water2.m
new file mode 100644
index 00000000..f7b9a42e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/dynamic/water2.m
@@ -0,0 +1,22 @@
+% Compare the speeds of various inference engines on the water DBN
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+bnet = mk_water_dbn;
+
+T = 3;
+
+engine = {};
+engine{end+1} = smoother_engine(jtree_2TBN_inf_engine(bnet));
+engine{end+1} = smoother_engine(jtree_sparse_2TBN_inf_engine(bnet));
+engine{end+1} = smoother_engine(hmm_2TBN_inf_engine(bnet));
+engine{end+1} = jtree_dbn_inf_engine(bnet);
+%engine{end+1} = jtree_unrolled_dbn_inf_engine(bnet, T); 
+
+%engine{end+1} = bk_inf_engine(bnet, 'ff', onodes);
+%engine{end+1} = bk_inf_engine(bnet, { [1 2], [3 4 5 6], [7 8] }, onodes);
+
+inf_time = cmp_inference_dbn(bnet, engine, T)
+%learning_time = cmp_learning_dbn(bnet, engine, T)
+
diff --git a/sourcecodes/bnt-master/BNT/examples/limids/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/limids/CVS/Entries
new file mode 100644
index 00000000..f7f12046
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/limids/CVS/Entries
@@ -0,0 +1,6 @@
+/amnio.m/1.1.1.1/Mon Sep 13 03:21:04 2004//
+/asia_dt1.m/1.1.1.1/Mon Jun  7 15:53:54 2004//
+/id1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/oil1.m/1.1.1.1/Mon Sep 13 02:27:08 2004//
+/pigs1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/limids/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/limids/CVS/Repository
new file mode 100644
index 00000000..bd5dd5af
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/limids/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/limids
diff --git a/sourcecodes/bnt-master/BNT/examples/limids/CVS/Root b/sourcecodes/bnt-master/BNT/examples/limids/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/limids/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/limids/amnio.m b/sourcecodes/bnt-master/BNT/examples/limids/amnio.m
new file mode 100644
index 00000000..fd621b6c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/limids/amnio.m
@@ -0,0 +1,135 @@
+
+clear all
+B0 = 1; Rtriple = 2; Damnio = 3;
+B1 = 4; Ramnio = 5; Dabort = 6; 
+B2 = 7; U = 8;
+
+N = 8;
+dag = zeros(N,N);
+dag(B0, [Rtriple B1 Ramnio]) = 1;
+dag(Rtriple, [Damnio Dabort]) = 1;
+dag(Damnio, [B1 Ramnio]) = 1;
+dag(B1, B2) = 1;
+dag(Ramnio, [Dabort U]) = 1;
+dag(Dabort, B2) = 1;
+dag(B2, U) = 1;
+
+
+
+ns = zeros(1,N);
+ns(B0) = 2;
+ns(B1) = 3;
+ns(B2) = 4;
+ns(Rtriple) = 2;
+ns(Ramnio) = 3;
+ns(Damnio) = 2;
+ns(Dabort) = 2;
+ns(U) = 1;
+
+limid = mk_limid(dag, ns, 'chance', [B0 B1 B2], ...
+		 'decision', [Damnio Dabort], 'utility', [U]);
+
+% states of nature
+healthy = 1; downs = 2; miscarry = 3; aborted = 4;
+% test results
+pos = 1; neg = 2; unk = 3;
+% actions
+yes = 1; no = 2;
+
+% Prior probability baby has downs syndrome
+tbl = zeros(2,1);
+p = 1/1000; % from www.downs-syndrome.org.uk figure
+p = 24/10000; % www-personal.umich.edu/~bobwolfe/560/review/Downs.pdf (for women agen 35-40)
+tbl(healthy) = 1-p;
+tbl(downs) = p;
+limid.CPD{B0} = tabular_CPD(limid, B0, tbl);
+
+% Reliability of triple screen test
+% Unreliable sensor
+% B0 -> Rtriple
+tbl = zeros(2,2); % Rtriple = pos, neg
+p = 0.5;  % high false positive rate (guess)
+tbl(healthy, :) = [p 1-p];
+p = 0.6; % low detection rate (march of dimes figure)
+tbl(downs, :) = [p 1-p]; 
+limid.CPD{Rtriple} = tabular_CPD(limid, Rtriple, tbl);
+
+limid.CPD{Damnio} = tabular_decision_node(limid, Damnio);
+
+% Effect of amnio on baby  B0,Damnio -> B1
+ % 1/200 risk of miscarry 
+p = 1/200; % (march of dimes figure)
+tbl = zeros(2, 2, 3); % B1 = healthy, downs, miscarry
+tbl(healthy, no, :) =  [1     0     0];
+tbl(downs, no, :) =    [0     1     0];
+tbl(healthy, yes, :) = [1-p     0   p];
+tbl(downs, yes, :) =   [0     1-p   p];
+limid.CPD{B1} = tabular_CPD(limid, B1, tbl);
+
+% Reliability of amnio  B0, Damnio -> Ramnio
+% Perfect sensor
+tbl = zeros(2,2,3); % Ramnio = pos, neg, unk
+tbl(:, no, :) =        repmat([0 0 1], 2 ,1);
+tbl(healthy, yes, :) = [0 1 0]; 
+tbl(downs, yes, :) =   [1 0 0]; 
+limid.CPD{Ramnio} = tabular_CPD(limid, Ramnio, tbl);
+
+limid.CPD{Dabort} = tabular_decision_node(limid, Dabort);
+
+% Effect of abortion on baby  B1, Dabort -> B2
+tbl = zeros(3, 2, 4); % B2 = healthy, downs, miscarry, aborted
+tbl(:, yes, :) =       repmat([0 0 0 1], 3, 1);
+tbl(healthy, no, :) =  [1 0 0 0];
+tbl(downs, no, :) =    [0 1 0 0];
+tbl(miscarry, no, :) = [0 0 1 0];
+limid.CPD{B2} = tabular_CPD(limid, B2, tbl);
+
+% Utility U(Ramnio, B2)
+tbl = zeros(3, 4);
+tbl(:, healthy) = 5000;
+tbl(:, downs) = -50000;
+tbl(:, miscarry) = -1000;
+tbl(:, aborted) = -1000;
+
+if 0
+%tbl(unk, miscarry) = 0; % this case is impossible
+tbl(pos, miscarry) = -1;
+tbl(neg, miscarry) = -1000;
+if 1
+  tbl(unk, aborted) = -100;
+  tbl(pos, aborted) = -1;
+  tbl(neg, aborted) = -500;
+else % pro-life utility fn
+  tbl(unk, aborted) = -500000;
+  tbl(pos, aborted) = -500000;
+  tbl(neg, aborted) = -500000;
+end 
+end
+
+limid.CPD{U} = tabular_utility_node(limid, U,  tbl);
+
+
+
+engine = jtree_limid_inf_engine(limid);
+[strategy, MEU] = solve_limid(engine);
+
+% Rtriple U(Damnio=1=yes)  U(Damnio=2=no)
+% 1=pos    0               1
+% 2=neg    0               1
+dispcpt(strategy{Damnio})
+if isequal(strategy{Damnio}(1,:), strategy{Damnio}(2,:))
+  % Rtriple result irrelevant
+  doAmnio = argmax(strategy{Damnio}(1,:))
+else
+  doAmnio = 1;
+end
+
+% Rtriple Ramnio U(Dabort=yes=1) U(Dabort=no=2)
+% 1=pos   1=pos  1               0
+% 2=neg   1=pos  1               0
+% 1=pos   2=neg  0               1
+% 2=neg   2=neg  0               1
+% 1=pos   3=unk  0               1
+% 2=neg   3=unk  0               1
+dispcpt(strategy{Dabort})
+
diff --git a/sourcecodes/bnt-master/BNT/examples/limids/asia_dt1.m b/sourcecodes/bnt-master/BNT/examples/limids/asia_dt1.m
new file mode 100644
index 00000000..de305818
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/limids/asia_dt1.m
@@ -0,0 +1,100 @@
+% decision theoretic version of asia network
+% Cowell et al, p177
+% We explicitely add the no-forgetting arcs.
+
+Smoking = 1;
+VisitToAsia = 2;
+Bronchitis = 3;
+LungCancer = 4;
+TB = 5;
+Do_Xray = 6;
+TBorCancer = 7;
+Util_Xray = 8;
+Dys = 9;
+posXray = 10;
+Do_Hosp = 11;
+Util_Hosp = 12;
+
+n = 12;
+dag = zeros(n);
+dag(Smoking, [Bronchitis LungCancer]) = 1;
+dag(VisitToAsia, [TB Do_Xray Do_Hosp]) = 1;
+dag(Bronchitis, Dys) = 1;
+dag(LungCancer, [Util_Hosp TBorCancer]) = 1;
+dag(TB, [Util_Hosp TBorCancer Util_Xray]) = 1;
+dag(Do_Xray, [posXray Util_Xray Do_Hosp]) = 1;
+dag(TBorCancer, [Dys posXray]) = 1;
+dag(Dys, Do_Hosp) = 1;
+dag(posXray, Do_Hosp) = 1;
+dag(Do_Hosp, Util_Hosp) = 1;
+
+dnodes = [Do_Xray Do_Hosp];
+unodes = [Util_Xray Util_Hosp];
+cnodes = mysetdiff(1:n, [dnodes unodes]); % chance nodes
+ns = 2*ones(1,n);
+ns(unodes) = 1;
+limid = mk_limid(dag, ns, 'chance', cnodes, 'decision', dnodes, 'utility', unodes);
+
+% 1 = yes, 2 = no
+limid.CPD{VisitToAsia} = tabular_CPD(limid, VisitToAsia, [0.01 0.99]);
+limid.CPD{Bronchitis} = tabular_CPD(limid, Bronchitis, [0.6 0.3  0.4 0.7]);
+limid.CPD{Dys} = tabular_CPD(limid, Dys, [0.9 0.7 0.8 0.1  0.1 0.3 0.2 0.9]);
+limid.CPD{TBorCancer} = tabular_CPD(limid, TBorCancer, [1 1 1 0  0 0 0 1]);
+
+limid.CPD{LungCancer} = tabular_CPD(limid, LungCancer, [0.1 0.01  0.9 0.99]);
+limid.CPD{Smoking} = tabular_CPD(limid, Smoking, [0.5 0.5]);
+limid.CPD{TB} = tabular_CPD(limid, TB, [0.05 0.01  0.95 0.99]);
+limid.CPD{posXray} = tabular_CPD(limid, posXray, [0.98 0.5 0.05 0.5  0.02 0.5 0.95 0.5]);
+
+limid.CPD{Util_Hosp} = tabular_utility_node(limid, Util_Hosp, [180 120 160 15  2 4 0 40]);
+limid.CPD{Util_Xray} = tabular_utility_node(limid, Util_Xray, [0 1 10 10]);
+
+for i=dnodes(:)'
+  limid.CPD{i} = tabular_decision_node(limid, i);
+end
+
+engines = {};
+engines{end+1} = global_joint_inf_engine(limid);
+engines{end+1} = jtree_limid_inf_engine(limid);
+%engines{end+1} = belprop_inf_engine(limid);
+
+exact = [1 2];
+%approx = 3;
+approx = [];
+
+
+NE = length(engines);
+MEU = zeros(1, NE);
+niter = zeros(1, NE);
+strategy = cell(1, NE);
+
+tol = 1e-2;
+for e=1:length(engines)
+  [strategy{e}, MEU(e), niter(e)] = solve_limid(engines{e});
+end
+
+for e=exact(:)'
+  assert(approxeq(MEU(e), 47.49, tol))
+  assert(isequal(strategy{e}{Do_Xray}(:)', [1 0 0 1]))
+  
+  % Check the hosptialize strategy is correct (p180)
+  % We assume the patient has not been to Asia and therefore did not have an Xray.
+  % In this case it is optimal not to hospitalize regardless of whether the patient has
+  % dyspnoea or not (and of course regardless of the value of pos_xray).
+  asia = 2;
+  do_xray = 2;
+  for dys = 1:2
+    for pos_xray = 1:2
+      assert(argmax(squeeze(strategy{e}{Do_Hosp}(asia, do_xray, dys, pos_xray, :))) == 2)
+    end
+  end
+end
+
+
+for e=approx(:)'
+  approxeq(strategy{exact(1)}{Do_Xray}, strategy{e}{Do_Xray})
+  approxeq(strategy{exact(1)}{Do_Hosp}, strategy{e}{Do_Hosp})
+end
+
+ 
+
diff --git a/sourcecodes/bnt-master/BNT/examples/limids/id1.m b/sourcecodes/bnt-master/BNT/examples/limids/id1.m
new file mode 100644
index 00000000..ddacd67a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/limids/id1.m
@@ -0,0 +1,50 @@
+% influence diagram with no loops
+%
+% rv  dec
+%  \  /
+%  utility
+
+N = 3;
+dag = zeros(N);
+X = 1; D = 2; U = 3;
+dag([X D], U)=1;
+
+ns = zeros(1,N);
+ns(X) = 2; ns(D) = 2; ns(U) = 1;
+
+limid = mk_limid(dag, ns, 'chance', X, 'decision', D, 'utility', U);
+
+% use random params
+limid.CPD{X} = tabular_CPD(limid, X);
+limid.CPD{D} = tabular_decision_node(limid, D);
+limid.CPD{U} = tabular_utility_node(limid, U);
+
+%fname = '/home/cs/murphyk/matlab/Misc/loopybel.txt';
+global BNT_HOME
+fname = sprintf('%s/loopybel.txt', BNT_HOME);
+
+engines = {};
+engines{end+1} = global_joint_inf_engine(limid);
+engines{end+1} = jtree_limid_inf_engine(limid);
+%engines{end+1} = belprop_inf_engine(limid, 'max_iter', 2*N, 'filename', fname);
+engines{end+1} = belprop_inf_engine(limid, 'max_iter', 2*N);
+
+exact = [1 2];
+approx = 3;
+
+E = length(engines);
+strategy = cell(1, E);
+MEU = zeros(1, E);
+for e=1:E
+  [strategy{e}, MEU(e)] = solve_limid(engines{e});
+  MEU
+end
+MEU
+
+for e=exact(:)'
+  assert(approxeq(strategy{exact(1)}{D}, strategy{e}{D}))
+end
+
+for e=approx(:)'
+  approxeq(strategy{exact(1)}{D}, strategy{e}{D})
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/limids/oil1.m b/sourcecodes/bnt-master/BNT/examples/limids/oil1.m
new file mode 100644
index 00000000..192acc9d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/limids/oil1.m
@@ -0,0 +1,91 @@
+% oil wildcatter influence diagram in Cowell et al p172
+
+% T = test for oil?
+% UT = utility (negative cost) of testing
+% O = amount of oil = Dry, Wet or Soaking
+% R = results of test = NoStrucure, OpenStructure, ClosedStructure or NoResult
+% D = drill?
+% UD = utility of drilling
+
+% Decision sequence = T R D O
+
+T = 1; UT = 2; O = 3; R = 4; D = 5; UD = 6;
+N = 6;
+dag = zeros(N);
+dag(T, [UT R D]) = 1;
+dag(O, [R UD]) = 1;
+dag(R, D) = 1;
+dag(D, UD) = 1;
+
+ns = zeros(1,N);
+ns(O) = 3; ns(R) = 4; ns(T) = 2; ns(D) = 2; ns(UT) = 1; ns(UD) = 1;
+
+limid = mk_limid(dag, ns, 'chance', [O R], 'decision', [T D], 'utility', [UT UD]);
+
+limid.CPD{O} = tabular_CPD(limid, O, [0.5 0.3 0.2]);
+tbl = [0.6 0 0.3 0 0.1 0  0.3 0 0.4 0 0.4 0  0.1 0 0.3 0 0.5 0  0 1 0 1 0 1];
+limid.CPD{R} = tabular_CPD(limid, R, tbl);
+
+limid.CPD{UT} = tabular_utility_node(limid, UT,  [-10 0]);
+limid.CPD{UD} = tabular_utility_node(limid, UD, [-70 50 200  0 0 0]);
+
+if 1
+  % start with uniform policies
+  limid.CPD{T} = tabular_decision_node(limid, T);
+  limid.CPD{D} = tabular_decision_node(limid, D);
+else
+  % hard code optimal policies
+  limid.CPD{T} = tabular_decision_node(limid, T, [1.0 0.0]);        
+  a = 0.5; b = 1-a; % arbitrary value
+  tbl = myreshape([0 a 1 a 1 a a a  1 b 0 b 0 b b b], ns([T R D]));
+  limid.CPD{D} = tabular_decision_node(limid, D,  tbl);
+end
+
+%fname = '/home/cs/murphyk/matlab/Misc/loopybel.txt';
+
+engines = {};
+engines{end+1} = global_joint_inf_engine(limid);
+engines{end+1} = jtree_limid_inf_engine(limid);
+%engines{end+1} = belprop_inf_engine(limid, 'max_iter', 3*N, 'filename', fname);
+
+exact = [1 2];
+%approx = 3;
+approx = [];
+
+E = length(engines);
+strategy = cell(1, E);
+MEU = zeros(1, E);
+for e=1:E
+  [strategy{e}, MEU(e)] = solve_limid(engines{e});
+  MEU
+end
+MEU
+
+for e=exact(:)'
+  assert(approxeq(MEU(e), 22.5))
+  % U(T=yes)  U(T=no)
+  % 1         0
+  assert(argmax(strategy{e}{T}) == 1); % test = yes
+  t = 1; % test = yes
+  % strategy{D} T       R      U(D=yes=1)  U(D=no=2)
+  %             1=yes   1=noS  0           1         Don't drill
+  %             2=no    1=noS  1           0
+  %             1=yes   2=opS  1           0
+  %             2=no    2=opS  1           0
+  %             1=yes   3=clS  1           0
+  %             2=no    3=clS  1           0
+  %             1=yes   4=unk  1           0
+  %             2=no    4=unk  1           0
+  
+  for r=[2 3] % OpS, ClS
+    assert(argmax(squeeze(strategy{e}{D}(t,r,:))) == 1); % drill = yes
+  end
+  r = 1; % noS
+  assert(argmax(squeeze(strategy{e}{D}(t,r,:))) == 2); % drill = no
+end
+
+
+for e=approx(:)'
+  approxeq(strategy{exact(1)}{T}, strategy{e}{T})
+  approxeq(strategy{exact(1)}{D}, strategy{e}{D})
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/limids/pigs1.m b/sourcecodes/bnt-master/BNT/examples/limids/pigs1.m
new file mode 100644
index 00000000..6a56ad04
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/limids/pigs1.m
@@ -0,0 +1,153 @@
+% pigs model from Lauritzen and Nilsson, 2001
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+% we number nodes down and to the right
+h = [1 5 9 13];
+t = [2 6 10];
+d = [3 7 11];
+u = [4 8 12 14];
+
+N = 14;
+dag = zeros(N);
+
+% causal arcs
+for i=1:3
+  dag(h(i), [t(i) h(i+1)]) = 1;
+  dag(d(i), [u(i) h(i+1)]) = 1;
+end
+dag(h(4), u(4)) = 1;
+
+% information arcs
+fig = 2;
+switch fig
+ case 0,
+  % no info arcs
+ case 1,
+   % no-forgetting policy (figure 1)
+   for i=1:3
+     dag(t(i), d(i:3)) = 1;
+   end
+ case 2,
+  % reactive policy (figure 2)
+  for i=1:3
+    dag(t(i), d(i)) = 1;
+  end
+ case 7,
+  % omniscient policy (figure 7: di has access to hidden state h(i-1))
+  dag(t(1), d(1)) = 1;
+  for i=2:3
+    %dag([h(i-1) t(i-1) d(i-1)], d(i)) = 1;
+    dag([h(i-1) d(i-1)], d(i)) = 1; % t(i-1) is redundant given h(i-1)
+  end
+end
+
+
+ns = 2*ones(1,N);
+ns(u) = 1;
+
+% parameter tying
+params = ones(1,N);
+uparam = 1;
+final_uparam = 2;
+tparam = 3;
+h1_param = 4;
+hparam = 5;
+dparams = 6:8;
+
+params(u(1:3)) = uparam;
+params(u(4)) = final_uparam;
+params(t) = tparam;
+params(h(1)) = h1_param;
+params(h(2:end)) = hparam;
+params(d) = dparams;
+
+limid = mk_limid(dag, ns, 'chance', [h t], 'decision', d, 'utility', u, 'equiv_class', params);
+
+% h = 1 means healthy, h = 2 means diseased
+% d = 1 means don't treat, d = 2 means treat
+% t = 1 means test shows healthy, t = 2 means test shows diseased
+
+if 0
+  % use random params
+  limid.CPD{final_uparam} = tabular_utility_node(limid, u(4));
+  limid.CPD{uparam} = tabular_utility_node(limid, u(1));
+  limid.CPD{tparam} = tabular_CPD(limid, t(1));
+  limid.CPD{h1_param} = tabular_CPD(limid, h(1));
+  limid.CPD{hparam} = tabular_CPD(limid, h(2));
+else
+  limid.CPD{final_uparam} = tabular_utility_node(limid, u(4), [1000 300]);
+  limid.CPD{uparam} = tabular_utility_node(limid, u(1), [0 -100]); % costs have negative utility!
+  
+  % h  P(t=1) P(t=2)
+  % 1  0.9   0.1
+  % 2  0.2   0.8
+  limid.CPD{tparam} = tabular_CPD(limid, t(1), [0.9 0.2 0.1 0.8]);
+  
+  % P(h1)
+  limid.CPD{h1_param} = tabular_CPD(limid, h(1), [0.9 0.1]);
+  
+  % hi di P(hj=1) P(hj=2),  j = i+1, i=1:3
+  % 1  1  0.8     0.2
+  % 2  1  0.1     0.9
+  % 1  2  0.9     0.1
+  % 2  2  0.5     0.5
+  limid.CPD{hparam} = tabular_CPD(limid, h(2), [0.8 0.1 0.9 0.5 0.2 0.9 0.1 0.5]);
+end
+
+% Decision nodes get assigned uniform policies by default
+for i=1:3
+  limid.CPD{dparams(i)} = tabular_decision_node(limid, d(i));
+end
+
+
+fname = '/home/cs/murphyk/matlab/Misc/loopybel.txt';
+
+engines = {};
+engines{end+1} = global_joint_inf_engine(limid);
+engines{end+1} = jtree_limid_inf_engine(limid);
+%engines{end+1} = belprop_inf_engine(limid, 'max_iter', 1*N, 'filename', fname, 'tol', 1e-3);
+
+exact = [1 2];
+%approx = 3;
+approx = [];
+
+max_iter = 1;
+order = d(end:-1:1);
+%order = d(1:end);
+
+NE = length(engines);
+MEU = zeros(1, NE);
+niter = zeros(1, NE);
+strategy = cell(1, NE);
+for e=1:NE
+  [strategy{e}, MEU(e), niter(e)] = solve_limid(engines{e}, 'max_iter', max_iter, 'order',  order);
+end
+MEU
+
+% check results match those in the paper (p. 22)
+direct_policy = eye(2); % treat iff test is positive
+never_policy = [1 0; 1 0]; % never treat
+tol = 1e-0; % results in paper are reported to 0dp
+for e=exact(:)'
+  switch fig
+   case 2, % reactive policy
+    assert(approxeq(MEU(e), 727, tol));
+    assert(approxeq(strategy{e}{d(1)}(:), never_policy(:)))
+    assert(approxeq(strategy{e}{d(2)}(:), direct_policy(:)))
+    assert(approxeq(strategy{e}{d(3)}(:), direct_policy(:)))
+   case 1, assert(approxeq(MEU(e), 729, tol));
+   case 7, assert(approxeq(MEU(e), 732, tol));
+  end
+end
+
+
+for e=approx(:)'
+  for i=1:3
+    approxeq(strategy{exact(1)}{d(i)}, strategy{e}{d(i)})
+    dispcpt(strategy{e}{d(i)})
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Belprop/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/static/Belprop/CVS/Entries
new file mode 100644
index 00000000..6550caa0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Belprop/CVS/Entries
@@ -0,0 +1,11 @@
+/belprop_loop1_discrete.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/belprop_loop1_gauss.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/belprop_loopy_cg.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/belprop_loopy_discrete.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/belprop_loopy_gauss.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/belprop_polytree_cg.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/belprop_polytree_discrete.m/1.1.1.1/Tue Oct  1 18:21:26 2002//
+/belprop_polytree_gauss.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/bp1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/gmux1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Belprop/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/static/Belprop/CVS/Repository
new file mode 100644
index 00000000..f3d573bd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Belprop/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/static/Belprop
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Belprop/CVS/Root b/sourcecodes/bnt-master/BNT/examples/static/Belprop/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Belprop/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loop1_discrete.m b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loop1_discrete.m
new file mode 100644
index 00000000..20faed5e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loop1_discrete.m
@@ -0,0 +1,26 @@
+% Compare different loopy belief propagation algorithms on a graph with a single loop.
+% LBP should give exact results if it converges.
+
+N = 4;
+dag = zeros(N,N);
+C = 1; S = 2; R = 3; W = 4;
+dag(C,[R S]) = 1;
+dag(R,W) = 1;
+dag(S,W)=1;
+ns = 2*ones(1,N); 
+bnet = mk_bnet(dag, ns);
+for i=1:N
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+end
+
+engines = {};
+engines{end+1} = jtree_inf_engine(bnet);
+engines{end+1} = pearl_inf_engine(bnet, 'protocol', 'parallel');
+engines{end+1} = belprop_fg_inf_engine(bnet_to_fgraph(bnet));
+engines{end+1} = belprop_inf_engine(bnet, 'protocol', 'parallel');
+
+% belprop_fg does not support marginal_family
+% belprop_fg and belprop do not support loglik even on discrete
+[time, engines] = cmp_inference_static(bnet, engines, 'maximize', 0, 'exact', 1, 'observed', 2, ...
+				   'check_ll', 0, 'singletons_only', 1, 'check_converged', 2:4);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loop1_gauss.m b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loop1_gauss.m
new file mode 100644
index 00000000..e547e44a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loop1_gauss.m
@@ -0,0 +1,25 @@
+% Compare different loopy belief propagation algorithms on a graph with a single loop.
+% LBP should give exact results if it converges.
+
+N = 4;
+dag = zeros(N,N);
+C = 1; S = 2; R = 3; W = 4;
+dag(C,[R S]) = 1;
+dag(R,W) = 1;
+dag(S,W)=1;
+ns = 2*ones(1,N); 
+bnet = mk_bnet(dag, ns, 'discrete', []);
+for i=1:N
+  bnet.CPD{i} = gaussian_CPD(bnet, i);
+end
+
+engines = {};
+engines{end+1} = jtree_inf_engine(bnet);
+engines{end+1} = pearl_inf_engine(bnet, 'protocol', 'parallel', 'max_iter', 20);
+%engines{end+1} = pearl_inf_engine(bnet, 'protocol', 'parallel', 'max_iter', 20, 'filename', ...
+%				  '/home/eecs/murphyk/matlab/gausspearl.txt', 'tol', 1e-5);
+
+% pearl gaussian does not compute loglik
+[time, engines] = cmp_inference_static(bnet, engines, 'maximize', 0, 'exact', 1, 'observed', [2], ...
+				   'check_ll', 0, 'singletons_only', 0, 'check_converged', [2]);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loopy_cg.m b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loopy_cg.m
new file mode 100644
index 00000000..01f36b03
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loopy_cg.m
@@ -0,0 +1,22 @@
+% Same as cg1, except we assume all discretes are observed,
+% and use loopy for approximate inference.
+
+ns = 2*ones(1,9);
+F = 1; W = 2; E = 3; B = 4; C = 5; D = 6; Min = 7; Mout = 8; L = 9;
+n = 9;
+dnodes = [B F W];
+cnodes = mysetdiff(1:n, dnodes);
+
+%bnet  = mk_incinerator_bnet(ns);
+bnet  = mk_incinerator_bnet;
+
+bnet.observed = [dnodes E];
+
+engines = {};
+engines{end+1} = jtree_inf_engine(bnet);
+engines{end+1} = pearl_inf_engine(bnet, 'protocol', 'parallel');
+nengines = length(engines);
+
+
+[time, engines] = cmp_inference_static(bnet, engines, 'maximize', 0, 'check_ll', 0, ...
+				      'singletons_only', 0, 'exact', 1, 'check_converged', 2);
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loopy_discrete.m b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loopy_discrete.m
new file mode 100644
index 00000000..c46e6d02
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loopy_discrete.m
@@ -0,0 +1,13 @@
+% Compare different loopy belief propagation algorithms on a graph with many loops
+
+bnet = mk_asia_bnet('orig');
+
+engines = {};
+engines{end+1} = jtree_inf_engine(bnet);
+engines{end+1} = pearl_inf_engine(bnet, 'protocol', 'parallel');
+engines{end+1} = belprop_fg_inf_engine(bnet_to_fgraph(bnet));
+engines{end+1} = belprop_inf_engine(bnet, 'protocol', 'parallel');
+
+[time, engines] = cmp_inference_static(bnet, engines, 'maximize', 0, 'exact', 1, 'observed', [1 3 5], ...
+				   'check_ll', 0, 'singletons_only', 1, 'check_converged', 2:4);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loopy_gauss.m b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loopy_gauss.m
new file mode 100644
index 00000000..a9924aed
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_loopy_gauss.m
@@ -0,0 +1,12 @@
+% Compare different loopy belief propagation algorithms on a graph with many loops
+% If LBP converges, the means should be exact
+
+bnet = mk_asia_bnet('gauss');
+
+engines = {};
+engines{end+1} = jtree_inf_engine(bnet);
+engines{end+1} = pearl_inf_engine(bnet, 'protocol', 'parallel');
+
+[time, engines] = cmp_inference_static(bnet, engines, 'maximize', 0, 'exact', 1, 'observed', [1 3 5], ...
+				   'check_ll', 0, 'singletons_only', 0, 'check_converged', 2);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_polytree_cg.m b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_polytree_cg.m
new file mode 100644
index 00000000..70aa03da
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_polytree_cg.m
@@ -0,0 +1,33 @@
+% Inference on a conditional Gaussian model
+
+% Make the following polytree, where all arcs point down
+
+% 1   2
+%  \ /
+%   3
+%  / \
+% 4   5
+
+N = 5;
+dag = zeros(N,N);
+dag(1,3) = 1;
+dag(2,3) = 1;
+dag(3, [4 5]) = 1;
+
+ns = [2 1 2 1 2];
+
+dnodes = 1;
+%onodes = [1 5];
+bnet = mk_bnet(dag, ns, 'discrete', dnodes, 'observed', dnodes);
+
+bnet.CPD{1} = tabular_CPD(bnet, 1);
+for i=2:N
+  bnet.CPD{i} = gaussian_CPD(bnet, i);
+end
+
+engine = {};
+engine{end+1} = jtree_inf_engine(bnet);
+engine{end+1} = pearl_inf_engine(bnet, 'protocol', 'parallel');
+
+[time, engine] = cmp_inference_static(bnet, engine, 'maximize', 0, 'check_ll', 0, ...
+				      'singletons_only', 0, 'observed', [1 3]);
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_polytree_discrete.m b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_polytree_discrete.m
new file mode 100644
index 00000000..d8a3a229
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_polytree_discrete.m
@@ -0,0 +1,38 @@
+% Make the following polytree, where all arcs point down
+
+% 1   2
+%  \ /
+%   3
+%  / \
+% 4   5
+
+N = 5;
+dag = zeros(N,N);
+dag(1,3) = 1;
+dag(2,3) = 1;
+dag(3, [4 5]) = 1;
+
+ns = 2*ones(1,N); % binary nodes
+
+onodes = [1 5];
+
+bnet = mk_bnet(dag, ns, 'observed', onodes);
+
+if 0
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+end
+
+for i=1:N
+  %bnet.CPD{i} = tabular_CPD(bnet, i);
+  bnet.CPD{i} = noisyor_CPD(bnet, i);
+end
+
+engine = {};
+engine{end+1} = jtree_inf_engine(bnet);
+engine{end+1} = pearl_inf_engine(bnet, 'protocol', 'tree');
+engine{end+1} = pearl_inf_engine(bnet, 'protocol', 'parallel');
+
+[err, time] = cmp_inference_static(bnet, engine, 'maximize', 0, 'check_ll', 1);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_polytree_gauss.m b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_polytree_gauss.m
new file mode 100644
index 00000000..1823c107
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Belprop/belprop_polytree_gauss.m
@@ -0,0 +1,135 @@
+% Do the example from Satnam Alag's PhD thesis, UCB ME dept 1996 p46
+
+% Make the following polytree, where all arcs point down
+
+% 1   2
+%  \ /
+%   3
+%  / \
+% 4   5
+
+N = 5;
+dag = zeros(N,N);
+dag(1,3) = 1;
+dag(2,3) = 1;
+dag(3, [4 5]) = 1;
+
+ns = [2 1 2 1 2];
+
+bnet = mk_bnet(dag, ns, 'discrete', []);
+
+bnet.CPD{1} = gaussian_CPD(bnet, 1, 'mean', [1 0]', 'cov', [4 1; 1 4]);
+bnet.CPD{2} = gaussian_CPD(bnet, 2, 'mean', 1, 'cov', 1);
+B1 = [1 2; 1 0]; B2 = [2 1]';
+bnet.CPD{3} = gaussian_CPD(bnet, 3, 'mean', [0 0]', 'cov', [2 1; 1 1], ...
+			   'weights', [B1 B2]);
+H1 = [1 1];
+bnet.CPD{4} = gaussian_CPD(bnet, 4, 'mean', 0, 'cov', 1, 'weights', H1);
+H2 = [1 0; 1 1];
+bnet.CPD{5} = gaussian_CPD(bnet, 5, 'mean', [0 0]', 'cov', eye(2), 'weights', H2);
+
+engine = {};
+engine{end+1} = jtree_inf_engine(bnet);
+engine{end+1} = pearl_inf_engine(bnet, 'protocol', 'tree');
+engine{end+1} = pearl_inf_engine(bnet, 'protocol', 'parallel');
+E = length(engine);
+
+if 1
+% no evidence
+evidence = cell(1,N);
+ll = zeros(1,E);
+for e=1:E
+  [engine{e}, ll(e)] = enter_evidence(engine{e}, evidence);
+  add_ev = 1;
+  m = marginal_nodes(engine{e}, 3, add_ev);
+  assert(approxeq(m.mu, [3 2]'))
+  assert(approxeq(m.Sigma, [30 9; 9 6]))
+
+  m = marginal_nodes(engine{e}, 4, add_ev);
+  assert(approxeq(m.mu, 5))
+  assert(approxeq(m.Sigma, 55))
+
+  m = marginal_nodes(engine{e}, 5, add_ev);
+  assert(approxeq(m.mu, [3 5]'))
+  assert(approxeq(m.Sigma, [31 39; 39 55]))
+end
+end
+
+if 1
+% evidence on leaf 5
+evidence = cell(1,N);
+evidence{5} = [5 5]';
+for e=1:E
+  [engine{e}, ll(e)] = enter_evidence(engine{e}, evidence);
+  add_ev = 1;
+  m = marginal_nodes(engine{e}, 3, add_ev);
+  assert(approxeq(m.mu, [4.4022 1.0217]'))
+  assert(approxeq(m.Sigma, [0.7011 -0.4891; -0.4891 1.1087]))
+
+  m = marginal_nodes(engine{e}, 4, add_ev);
+  assert(approxeq(m.mu, 5.4239))
+  assert(approxeq(m.Sigma, 1.8315))
+
+  m = marginal_nodes(engine{e}, 1, add_ev);
+  assert(approxeq(m.mu, [0.3478 1.1413]'))
+  assert(approxeq(m.Sigma, [1.8261 -0.1957; -0.1957 1.0924]))
+
+  m = marginal_nodes(engine{e}, 2, add_ev);
+  assert(approxeq(m.mu, 0.9239))
+  assert(approxeq(m.Sigma, 0.8315))
+
+  m = marginal_nodes(engine{e}, 5, add_ev);
+  assert(approxeq(m.mu, evidence{5}))
+  assert(approxeq(m.Sigma, zeros(2)))
+end
+end
+
+if 1
+% evidence on leaf 4 (non-info-state version is uninvertible)
+evidence = cell(1,N);
+evidence{4} = 10;
+for e=1:E
+  [engine{e}, ll(e)] = enter_evidence(engine{e}, evidence);
+  add_ev = 1;
+  m = marginal_nodes(engine{e}, 3, add_ev);
+  assert(approxeq(m.mu, [6.5455 3.3636]'))
+  assert(approxeq(m.Sigma, [2.3455 -1.6364; -1.6364 1.9091]))
+
+  m = marginal_nodes(engine{e}, 5, add_ev);
+  assert(approxeq(m.mu, [6.5455 9.9091]'))
+  assert(approxeq(m.Sigma, [3.3455 0.7091; 0.7091 1.9818]))
+
+  m = marginal_nodes(engine{e}, 1, add_ev);
+  assert(approxeq(m.mu, [1.9091 0.9091]'))
+  assert(approxeq(m.Sigma, [2.1818 -0.8182; -0.8182 2.1818]))
+
+  m = marginal_nodes(engine{e}, 2, add_ev);
+  assert(approxeq(m.mu, 1.2727))
+  assert(approxeq(m.Sigma, 0.8364))
+end
+end
+
+
+if 1
+% evidence on leaves 4,5 and root 2
+evidence = cell(1,N);
+evidence{2} = 0;
+evidence{4} = 10;
+evidence{5} = [5 5]';
+for e=1:E
+  [engine{e}, ll(e)] = enter_evidence(engine{e}, evidence);
+  add_ev = 1;
+  m = marginal_nodes(engine{e}, 3, add_ev);
+  assert(approxeq(m.mu, [4.9964 2.4444]'));
+  assert(approxeq(m.Sigma, [0.6738 -0.5556; -0.5556 0.8889]));
+
+  m = marginal_nodes(engine{e}, 1, add_ev);
+  assert(approxeq(m.mu, [2.2043 1.2151]'));
+  assert(approxeq(m.Sigma, [1.2903 -0.4839; -0.4839 0.8065]));
+end
+end
+
+if 1
+  [time, engine] = cmp_inference_static(bnet, engine, 'maximize', 0, 'check_ll', 0, ...
+				     'singletons_only', 0, 'observed', [1 3 5]);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Belprop/bp1.m b/sourcecodes/bnt-master/BNT/examples/static/Belprop/bp1.m
new file mode 100644
index 00000000..93cba443
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Belprop/bp1.m
@@ -0,0 +1,24 @@
+% Compare different loopy belief propagation algorithms on a graph with a single loop.
+% LBP should give exact results if it converges.
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+N = 2;
+dag = zeros(N,N);
+dag(1,2)=1;
+ns = ones(1,N); 
+bnet = mk_bnet(dag, ns, 'discrete', []);
+for i=1:N
+  %bnet.CPD{i} = gaussian_CPD(bnet, i, 'mean', 0);
+  bnet.CPD{i} = gaussian_CPD(bnet, i);
+end
+
+engines = {};
+engines{end+1} = jtree_inf_engine(bnet);
+engines{end+1} = pearl_inf_engine(bnet, 'protocol', 'tree');
+
+[time, engines] = cmp_inference_static(bnet, engines, 'maximize', 0, 'exact', 1:2, 'observed', [2], ...
+				   'check_ll', 0, 'singletons_only', 1, 'check_converged', []);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Belprop/gmux1.m b/sourcecodes/bnt-master/BNT/examples/static/Belprop/gmux1.m
new file mode 100644
index 00000000..21846b68
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Belprop/gmux1.m
@@ -0,0 +1,90 @@
+% Test gmux.
+% The following model, where Y is a gmux node,
+% and M is set to 1, should be equivalent to X1 -> Y
+%
+% X1 Xn M
+% \ |  /
+%   Y
+
+n = 3;
+N = n+2;
+Xs = 1:n;
+M = n+1; 
+Y = n+2;
+dag = zeros(N,N);
+dag([Xs M], Y)=1; 
+
+dnodes = M;
+ns = zeros(1, N);
+sz = 2;
+ns(Xs) = sz;
+ns(M) = n;
+ns(Y) = sz;
+
+bnet = mk_bnet(dag, ns, 'discrete', M, 'observed', [M Y]);
+
+psz = ns(Xs(1));
+selfsz = ns(Y);
+
+W = randn(selfsz, psz);
+mu = randn(selfsz, 1);
+Sigma = eye(selfsz, selfsz);
+
+bnet.CPD{M} = root_CPD(bnet, M);
+for i=Xs(:)'
+  bnet.CPD{i} = gaussian_CPD(bnet, i, 'mean', zeros(psz, 1), 'cov', eye(psz, psz));
+end
+bnet.CPD{Y} = gmux_CPD(bnet, Y, 'mean', mu, 'weights', W, 'cov', Sigma);
+  
+evidence = cell(1,N);
+yval = randn(selfsz, 1);
+evidence{Y} = yval;
+m = 2;
+%notm = not(m-1)+1; % only valid for n=2
+notm = mysetdiff(1:n, m);
+evidence{M} = m;
+
+engines = {};
+engines{end+1} = jtree_inf_engine(bnet);
+engines{end+1} = pearl_inf_engine(bnet, 'protocol', 'parallel');
+
+for e=1:length(engines)
+  engines{e} = enter_evidence(engines{e}, evidence);
+  mXm{e} = marginal_nodes(engines{e}, Xs(m));
+
+  % Since M=m, only Xm was updated.
+  % Hence the posterior on Xnotm should equal the prior.
+  for i=notm(:)'
+    mXnotm = marginal_nodes(engines{e}, Xs(i));
+    assert(approxeq(mXnotm.mu, zeros(psz,1)))
+    assert(approxeq(mXnotm.Sigma, eye(psz, psz)))
+  end
+end
+
+% Check that all engines give the same posterior
+for e=2:length(engines)
+  assert(approxeq(mXm{e}.mu, mXm{1}.mu))
+  assert(approxeq(mXm{e}.Sigma, mXm{1}.Sigma))
+end
+
+
+% Compute the correct posterior by building Xm -> Y
+
+N = 2;
+dag = zeros(N,N);
+dag(1, 2)=1;
+ns = [psz selfsz];
+bnet = mk_bnet(dag, ns, 'discrete', [], 'observed', 2);
+
+bnet.CPD{1} = gaussian_CPD(bnet, 1, 'mean', zeros(psz, 1), 'cov', eye(psz, psz));
+bnet.CPD{2} = gaussian_CPD(bnet, 2, 'mean', mu, 'cov', Sigma, 'weights', W);
+
+jengine  = jtree_inf_engine(bnet);
+evidence = {[], yval};
+jengine = enter_evidence(jengine, evidence); % apply Bayes rule to invert the arc
+mX = marginal_nodes(jengine, 1);
+
+for e=1:length(engines)
+  assert(approxeq(mX.mu, mXm{e}.mu))
+  assert(approxeq(mX.Sigma, mXm{e}.Sigma))
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Brutti/Belief_IOhmm.m b/sourcecodes/bnt-master/BNT/examples/static/Brutti/Belief_IOhmm.m
new file mode 100644
index 00000000..43c6c802
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Brutti/Belief_IOhmm.m
@@ -0,0 +1,49 @@
+% Sigmoid Belief IOHMM
+% Here is the model
+%
+%  X \  X \
+%  | |  | |
+%  Q-|->Q-|-> ...
+%  | /  | /
+%  Y    Y
+%
+clear all;
+clc;
+rand('state',0); randn('state',0);
+X = 1; Q = 2; Y = 3;
+% intra time-slice graph
+intra=zeros(3);
+intra(X,[Q Y])=1;
+intra(Q,Y)=1;
+% inter time-slice graph
+inter=zeros(3);
+inter(Q,Q)=1;
+
+ns = [1 3 1]; 
+dnodes = [2];
+eclass1 = [1 2 3];
+eclass2 = [1 4 3];
+bnet = mk_dbn(intra, inter, ns, dnodes, eclass1, eclass2);
+bnet.CPD{1} = root_CPD(bnet, 1);
+% ==========================================================
+bnet.CPD{2} = softmax_CPD(bnet, 2);
+bnet.CPD{4} = softmax_CPD(bnet, 5, 'discrete', [2]);
+% ==========================================================
+bnet.CPD{3} = gaussian_CPD(bnet, 3);
+
+% make some data
+T=20;
+cases = cell(3, T);
+cases(1,:)=num2cell(round(rand(1,T)*2)+1);
+%cases(2,:)=num2cell(round(rand(1,T))+1);
+cases(3,:)=num2cell(rand(1,T));
+
+engine = bk_inf_engine(bnet, 'exact', [1 2 3]);
+
+% log lik before learning
+[engine, loglik] = enter_evidence(engine, cases);
+
+% do learning
+ev=cell(1,1);
+ev{1}=cases;
+[bnet2, LL2] = learn_params_dbn_em(engine, ev, 3);
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Brutti/Belief_hmdt.m b/sourcecodes/bnt-master/BNT/examples/static/Brutti/Belief_hmdt.m
new file mode 100644
index 00000000..88c4ae00
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Brutti/Belief_hmdt.m
@@ -0,0 +1,48 @@
+% Sigmoid Belief Hidden Markov Decision Tree    (Jordan/Gharhamani 1996)
+% 
+clear all;
+%clc;
+rand('state',0); randn('state',0);
+X = 1; Q1 = 2; Q2 = 3; Y = 4;
+% intra time-slice graph
+intra=zeros(4);
+intra(X,[Q1 Q2 Y])=1;
+intra(Q1,[Q2 Y])=1;
+intra(Q2, Y)=1;
+% inter time-slice graph
+inter=zeros(4);
+inter(Q1,Q1)=1;
+inter(Q2,Q2)=1;
+
+ns = [1 2 3 1]; 
+dnodes = [2 3]; 
+eclass1 = [1 2 3 4];
+eclass2 = [1 5 6 4];
+bnet = mk_dbn(intra, inter, ns, dnodes, eclass1, eclass2);
+
+bnet.CPD{1} = root_CPD(bnet, 1);
+% =========================================
+bnet.CPD{2} = softmax_CPD(bnet, 2);
+bnet.CPD{3} = softmax_CPD(bnet, 3, 'discrete', [2]);
+bnet.CPD{5} = softmax_CPD(bnet, 6);
+bnet.CPD{6} = softmax_CPD(bnet, 7, 'discrete', [3 6]);
+% =========================================
+bnet.CPD{4} = gaussian_CPD(bnet, 4);
+
+% make some data
+T=20;
+cases = cell(4, T);
+cases(1,:)=num2cell(round(rand(1,T)*2)+1);
+%cases(2,:)=num2cell(round(rand(1,T))+1);
+%cases(3,:)=num2cell(round(rand(1,T)*2)+1);
+cases(4,:)=num2cell(rand(1,T));
+
+engine = bk_inf_engine(bnet, 'exact', [1 2 3 4]);
+
+% log lik before learning
+[engine, loglik] = enter_evidence(engine, cases);
+
+% do learning
+ev=cell(1,1);
+ev{1}=cases;
+[bnet2, LL2] = learn_params_dbn_em(engine, ev, 10);
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Brutti/Belief_hme.m b/sourcecodes/bnt-master/BNT/examples/static/Brutti/Belief_hme.m
new file mode 100644
index 00000000..0b298d48
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Brutti/Belief_hme.m
@@ -0,0 +1,37 @@
+% Sigmoid Belief Hierarchical Mixtures of Experts
+
+clear all
+clc
+X = 1;
+Q1 = 2;
+Q2 = 3;
+Y = 4;
+dag = zeros(4,4);
+dag(X,[Q1 Q2 Y]) = 1;
+dag(Q1, [Q2 Y]) = 1;
+dag(Q2,Y)=1;
+ns = [1 3 4 3];
+dnodes = [2 3 4];
+onodes=[1 2 3 4];
+bnet = mk_bnet(dag,ns, dnodes);
+
+rand('state',0); randn('state',0);
+
+bnet.CPD{1} = root_CPD(bnet, 1);
+bnet.CPD{2} = softmax_CPD(bnet, 2, 'max_iter', 3);
+bnet.CPD{3} = softmax_CPD(bnet, 3, 'discrete', [2], 'max_iter', 3);
+bnet.CPD{4} = softmax_CPD(bnet, 4, 'discrete', [2 3], 'max_iter', 3);
+
+T=5;
+cases = cell(4, T);
+cases(1,:)=num2cell(rand(1,T));
+%cases(2,:)=num2cell(round(rand(1,T)*2)+1);
+%cases(3,:)=num2cell(round(rand(1,T)*3)+1);
+cases(4,:)=num2cell(round(rand(1,T)*2)+1);
+
+engine = jtree_inf_engine(bnet, onodes);
+
+[engine, loglik] = enter_evidence(engine, cases);
+
+disp('learning-------------------------------------------')
+[bnet2, LL2] = learn_params_em(engine, cases, 4);
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Brutti/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/static/Brutti/CVS/Entries
new file mode 100644
index 00000000..bf214c0a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Brutti/CVS/Entries
@@ -0,0 +1,5 @@
+/Belief_IOhmm.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/Belief_hmdt.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/Belief_hme.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/Sigmoid_Belief.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Brutti/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/static/Brutti/CVS/Repository
new file mode 100644
index 00000000..52d4e2ed
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Brutti/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/static/Brutti
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Brutti/CVS/Root b/sourcecodes/bnt-master/BNT/examples/static/Brutti/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Brutti/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Brutti/Sigmoid_Belief.m b/sourcecodes/bnt-master/BNT/examples/static/Brutti/Sigmoid_Belief.m
new file mode 100644
index 00000000..1a6ecc35
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Brutti/Sigmoid_Belief.m
@@ -0,0 +1,49 @@
+% Sigmoid Belief Net
+
+clear all
+clc
+dum1 = 1;
+dum2 = 2;
+dum3 = 3;
+Q1 = 4;
+Q2 = 5;
+Y = 6;
+dag = zeros(6,6);
+dag(dum1,[Q1 Y]) = 1;
+dag(dum2, Q2)=1;
+dag(dum3, [Q1 Q2])=1;
+dag(Q1,[Q2 Y]) = 1;
+dag(Q2, Y)=1;
+
+ns = [2 2 3 3 4 3];
+dnodes = [1:6];
+bnet = mk_bnet(dag,ns, dnodes);
+
+rand('state',0); randn('state',0);
+n_iter=10;
+clamped=0;
+
+bnet.CPD{1} = tabular_CPD(bnet, 1);
+bnet.CPD{2} = tabular_CPD(bnet, 2);
+bnet.CPD{3} = tabular_CPD(bnet, 3);
+% CPD = dsoftmax_CPD(bnet, self, dummy_pars, w, b, clamped, max_iter, verbose, wthresh,...
+%    llthresh, approx_hess)
+bnet.CPD{4} = softmax_CPD(bnet, 4, 'discrete', [1 3]);
+bnet.CPD{5} = softmax_CPD(bnet, 5, 'discrete', [2 3]);
+bnet.CPD{6} = softmax_CPD(bnet, 6, 'discrete', [1 4]);
+
+T=5;
+cases = cell(6, T);
+cases(1,:)=num2cell(round(rand(1,T)*1)+1);
+%cases(2,:)=num2cell(round(rand(1,T)*1)+1);
+cases(3,:)=num2cell(round(rand(1,T)*2)+1);
+cases(4,:)=num2cell(round(rand(1,T)*2)+1); 
+%cases(5,:)=num2cell(round(rand(1,T)*3)+1);
+cases(6,:)=num2cell(round(rand(1,T)*2)+1);
+
+engine = jtree_inf_engine(bnet);
+
+[engine, loglik] = enter_evidence(engine, cases);
+
+disp('learning-------------------------------------------')
+[bnet2, LL2, eng2] = learn_params_em(engine, cases, n_iter);
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/examples/static/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/static/CVS/Entries
new file mode 100644
index 00000000..f27bc17d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/CVS/Entries
@@ -0,0 +1,30 @@
+/brainy.m/1.1.1.1/Sun Feb 22 19:43:32 2004//
+/burglar-alarm-net.lisp.txt/1.1.1.1/Thu Mar  4 22:27:48 2004//
+/burglary.m/1.1.1.1/Thu Mar  4 22:34:14 2004//
+/cg1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/cg2.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/cmp_inference_static.m/1.2/Sat Sep 17 16:59:57 2005//
+/discrete1.m/1.1.1.1/Mon Jun  7 19:45:06 2004//
+/discrete2.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/discrete3.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/fa1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/gaussian1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/gaussian2.m/1.1.1.1/Thu Jun 10 01:31:02 2004//
+/gibbs_test1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/learn1.m/1.1.1.1/Sat Feb 28 17:25:40 2004//
+/lw1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mfa1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mixexp1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mixexp2.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mixexp3.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mog1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mpe1.m/1.1.1.1/Wed Jun 19 22:08:58 2002//
+/mpe2.m/1.1.1.1/Wed Jun 19 22:09:08 2002//
+/nodeorderExample.m/1.1.1.1/Thu Jun 10 01:42:04 2004//
+/qmr1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/qmr2.m/1.1.1.1/Thu Nov 14 01:01:46 2002//
+/sample1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/softev1.m/1.1.1.1/Wed Jun 19 23:59:18 2002//
+/softmax1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sprinkler1.m/1.1.1.1/Sun Sep 12 21:01:38 2004//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/static/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/examples/static/CVS/Entries.Log
new file mode 100644
index 00000000..d4b2cb30
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/CVS/Entries.Log
@@ -0,0 +1,10 @@
+A D/Belprop////
+A D/Brutti////
+A D/HME////
+A D/Misc////
+A D/Models////
+A D/SCG////
+A D/StructLearn////
+A D/Zoubin////
+A D/dtree////
+A D/fgraph////
diff --git a/sourcecodes/bnt-master/BNT/examples/static/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/static/CVS/Repository
new file mode 100644
index 00000000..f43b2803
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/static
diff --git a/sourcecodes/bnt-master/BNT/examples/static/CVS/Root b/sourcecodes/bnt-master/BNT/examples/static/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/static/HME/CVS/Entries
new file mode 100644
index 00000000..b27a9df8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/CVS/Entries
@@ -0,0 +1,14 @@
+/HMEforMatlab.jpg/1.1.1.1/Wed May 29 15:59:54 2002//
+/README/1.1.1.1/Wed May 29 15:59:54 2002//
+/fhme.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/gen_data.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/hme_class_plot.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/hme_reg_plot.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/hme_topobuilder.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/hmemenu.m/1.1.1.1/Thu Feb 12 12:57:28 2004//
+/test_data_class.mat/1.1.1.1/Wed May 29 15:59:54 2002//
+/test_data_class2.mat/1.1.1.1/Wed May 29 15:59:54 2002//
+/test_data_reg.mat/1.1.1.1/Wed May 29 15:59:54 2002//
+/train_data_class.mat/1.1.1.1/Wed May 29 15:59:54 2002//
+/train_data_reg.mat/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/static/HME/CVS/Repository
new file mode 100644
index 00000000..2ac6a351
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/static/HME
diff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/CVS/Root b/sourcecodes/bnt-master/BNT/examples/static/HME/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/HMEforMatlab.jpg b/sourcecodes/bnt-master/BNT/examples/static/HME/HMEforMatlab.jpg
new file mode 100644
index 00000000..16682678
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/HMEforMatlab.jpg
Binary files differdiff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/README b/sourcecodes/bnt-master/BNT/examples/static/HME/README
new file mode 100644
index 00000000..4c794975
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/README
@@ -0,0 +1,2 @@
+This directory contains code for hierarchical mixture of experts,
+written by Pierpaolo Brutti (May 2001). Run the file hmemenu to get started.
diff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/fhme.m b/sourcecodes/bnt-master/BNT/examples/static/HME/fhme.m
new file mode 100644
index 00000000..6aeb7196
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/fhme.m
@@ -0,0 +1,109 @@
+function risultati = fhme(net, nodes_info, data, n)
+%HMEFWD	Forward propagation through an HME model
+%
+% Each row of the (n x class_num) matrix 'risultati' containes the estimated class posterior prob.
+%
+% ----------------------------------------------------------------------------------------------------
+% -> pierpaolo_b@hotmail.com   or   -> pampo@interfree.it
+% ----------------------------------------------------------------------------------------------------
+%
+ns=net.node_sizes;
+if nargin==3
+    ndata=n;
+else
+    ndata=size(data, 1);
+end
+altezza=size(ns,2);
+coeff=cell(altezza-1,1);
+for m=1:ndata
+    %- i=2 --------------------------------------------------------------------------------------
+    s=struct(net.CPD{2});    
+    if nodes_info(1,2)==0,
+        mu=[]; W=[]; predict=[];
+        mu=s.mean(:,:);
+        W=s.weights(:,:,:);
+        predict=mu(:,:)+W(:,:,:)*data(m,:)';            
+        coeff{1,1}=predict';            
+    elseif nodes_info(1,2)==1,
+        coeff{1,1}=fglm(s.glim{1}, data(m,:));
+    else,
+        coeff{1,1}=fmlp(s.mlp{1}, data(m,:));
+    end
+    %----------------------------------------------------------------------------------------------
+    if altezza>3,
+        for i=3:altezza-1,
+            s=[]; f=[]; dpsz=[];
+            f=family(net.dag,i); f=f(2:end-1); dpsz=prod(ns(f));
+            s=struct(net.CPD{i});
+            for j=1:dpsz,
+                if nodes_info(1,i)==1,
+                    coeff{i-1,1}(j,:)=coeff{i-2,1}(1,j)*fglm(s.glim{j}, data(m,:));
+                else
+                    coeff{i-1,1}(j,:)=coeff{i-2,1}(1,j)*fmlp(s.mlp{j}, data(m,:));
+                end
+            end       
+            app=cat(2, coeff{i-1,1}(:)); coeff{i-1,1}=app'; clear app;
+        end
+    end
+    %- i=altezza ----------------------------------------------------------------------------------
+    if altezza>2,
+        i=altezza;
+        s=[]; f=[]; dpsz=[];
+        f=family(net.dag,i); f=f(2:end-1); dpsz=prod(ns(f));
+        s=struct(net.CPD{i});
+        if nodes_info(1,i)==0,            
+            mu=[]; W=[];
+            mu=s.mean(:,:);
+            W=s.weights(:,:,:);
+        end
+        for j=1:dpsz,
+            if nodes_info(1,i)==0,            
+                predict=[];
+                predict=mu(:,j)+W(:,:,j)*data(m,:)';            
+                coeff{i-1,1}(j,:)=coeff{i-2,1}(1,j)*predict';            
+            elseif nodes_info(1,i)==1,
+                coeff{i-1,1}(j,:)=coeff{i-2,1}(1,j)*fglm(s.glim{j}, data(m,:));
+            else
+                coeff{i-1,1}(j,:)=coeff{i-2,1}(1,j)*fmlp(s.mlp{j}, data(m,:));
+            end
+        end
+    end
+    %----------------------------------------------------------------------------------------------
+    risultati(m,:)=sum(coeff{altezza-1,1},1);
+    clear coeff; coeff=cell(altezza-1,1);
+end
+return
+
+%-------------------------------------------------------------------
+
+function [y, a] = fglm(net, x)
+%GLMFWD	Forward propagation through 1-layer net->GLM statistical model
+
+ndata = size(x, 1);
+
+a = x*net.w1 + ones(ndata, 1)*net.b1;
+
+nout = size(a,2);
+% Ensure that sum(exp(a), 2) does not overflow
+maxcut = log(realmax) - log(nout);
+% Ensure that exp(a) > 0
+mincut = log(realmin);
+a = min(a, maxcut);
+a = max(a, mincut);
+temp = exp(a);
+y = temp./(sum(temp, 2)*ones(1,nout));
+
+%-------------------------------------------------------------------
+
+function [y, z, a] = fmlp(net, x)
+%MLPFWD	Forward propagation through 2-layer network.
+
+ndata = size(x, 1);
+
+z = tanh(x*net.w1 + ones(ndata, 1)*net.b1);
+a = z*net.w2 + ones(ndata, 1)*net.b2;  
+temp = exp(a);
+nout = size(a,2);
+y = temp./(sum(temp,2)*ones(1,nout));
+
+%-------------------------------------------------------------------
diff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/gen_data.m b/sourcecodes/bnt-master/BNT/examples/static/HME/gen_data.m
new file mode 100644
index 00000000..c37f9d28
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/gen_data.m
@@ -0,0 +1,52 @@
+function [data, ndata1, ndata2, targets]=gen_data(ndata, seed)
+% Generate data from three classes in 2d
+% Setting 'seed' for reproducible results
+% OUTPUT
+% data : data set
+% ndata1, ndata2: separator
+
+if nargin<1,
+   error('Missing data size');
+end
+
+input_dim = 2;
+num_classes = 3;
+
+if nargin==2,
+   % Fix seeds for reproducible results
+   randn('state', seed);
+   rand('state', seed);
+end
+
+% Generate mixture of three Gaussians in two dimensional space
+data = randn(ndata, input_dim);
+targets = zeros(ndata, 3);
+
+% Priors for the clusters
+prior(1) = 0.4;
+prior(2) = 0.3;
+prior(3) = 0.3;
+
+% Cluster centres
+c = [2.0, 2.0; 0.0, 0.0; 1, -1];
+
+ndata1 = round(prior(1)*ndata);
+ndata2 = round((prior(1) + prior(2))*ndata);
+% Put first cluster at (2, 2)
+data(1:ndata1, 1) = data(1:ndata1, 1) * 0.5 + c(1,1);
+data(1:ndata1, 2) = data(1:ndata1, 2) * 0.5 + c(1,2);
+targets(1:ndata1, 1) = 1;
+
+% Leave second cluster at (0,0)
+data((ndata1 + 1):ndata2, :) = data((ndata1 + 1):ndata2, :);
+targets((ndata1+1):ndata2, 2) = 1;
+
+data((ndata2+1):ndata, 1) = data((ndata2+1):ndata,1) *0.6 + c(3, 1);
+data((ndata2+1):ndata, 2) = data((ndata2+1):ndata,2) *0.6 + c(3, 2);
+targets((ndata2+1):ndata, 3) = 1;
+
+if 0
+  ndata = 1;
+  data = x;
+  targets = [1 0 0];
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/hme_class_plot.m b/sourcecodes/bnt-master/BNT/examples/static/HME/hme_class_plot.m
new file mode 100644
index 00000000..de60c2ee
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/hme_class_plot.m
@@ -0,0 +1,142 @@
+function fh=hme_class_plot(net, nodes_info, train_data, test_data)
+% 
+% Use this function ONLY when the input dimension is 2
+% and the problem is a classification one.
+% We assume that each row of 'train_data' & 'test_data' is an example.
+%
+%------Line Spec------------------------------------------------------------------------
+%
+% LineWidth       - specifies the width (in points) of the line
+% MarkerEdgeColor - specifies the color of the marker or the edge color
+%                   forfilled markers (circle, square, diamond, pentagram, hexagram, and the
+%                   four triangles).
+% MarkerFaceColor - specifies the color of the face of filled markers.
+% MarkerSize      - specifies the size of the marker in points.
+%
+% Example
+% -------
+% plot(t,sin(2*t),'-mo',...
+%                'LineWidth',2,...
+%                'MarkerEdgeColor','k',...                          % 'k'=black
+%                'MarkerFaceColor',[.49 1 .63],...                  % RGB color
+%                'MarkerSize',12)
+%----------------------------------------------------------------------------------------
+
+class_num=nodes_info(2,end);
+mn_x = round(min(train_data(:,1)));     mx_x = round(max(train_data(:,1)));
+mn_y = round(min(train_data(:,2)));     mx_y = round(max(train_data(:,2)));
+if nargin==4,
+    mn_x = round(min([train_data(:,1); test_data(:,1)]));     
+    mx_x = round(max([train_data(:,1); test_data(:,1)]));
+    mn_y = round(min([train_data(:,2); test_data(:,2)]));
+    mx_y = round(max([train_data(:,1); test_data(:,2)]));
+end
+x = mn_x(1)-1:0.2:mx_x(1)+1;
+y = mn_y(1)-1:0.2:mx_y(1)+1;
+[X, Y] = meshgrid(x,y);
+X = X(:); 
+Y = Y(:);
+num_g=size(X,1);
+griglia = [X Y];
+rand('state',1);
+if class_num<=6,
+    colors=['r'; 'g'; 'b'; 'c'; 'm'; 'y'];
+else
+    colors=rand(class_num, 3);  % each row is an RGB color
+end
+fh = figure('Name','Data & decision boundaries', 'MenuBar', 'none', 'NumberTitle', 'off');
+ms=5;           % Marker Size
+if nargin==4,
+%    ms=4;       % Marker Size
+    subplot(1,2,1);
+end
+% Plot of train_set -------------------------------------------------------------------------
+axis([mn_x-1 mx_x+1 mn_y-1 mx_y+1]);
+set(gca, 'Box', 'on');
+c_max_train = max(train_data(:,3));
+hold on
+for m=1:c_max_train,
+    app_x=train_data(:,1);
+    app_y=train_data(:,2);
+    thisX=app_x(train_data(:,3)==m);
+    thisY=app_y(train_data(:,3)==m);
+    if class_num<=6,
+       str_col=[];
+       str_col=['o', colors(m,:)];
+       plot(thisX, thisY, str_col, 'MarkerSize', ms);
+    else
+        plot(thisX, thisY, 'o',...
+            'LineWidth', 1,...            
+            'MarkerEdgeColor', colors(m,:), 'MarkerSize', ms)
+    end
+end
+%---hmefwd_generale(net,data,ndata)-----------------------------------------------------------
+Z=fhme(net, nodes_info, griglia, num_g);      % forward propagation trougth the HME
+%---------------------------------------------------------------------------------------------
+[foo , class] = max(Z'); % 0/1 loss function => we assume that the true class is the one with the
+                         % maximum posterior prob.
+class = class';
+for m = 1:class_num,
+  thisX=[]; thisY=[];
+  thisX = X(class == m);
+  thisY = Y(class == m);
+  if class_num<=6,
+      str_col=[];
+      str_col=['d', colors(m,:)];
+      h=plot(thisX, thisY, str_col);      
+  else
+      h = plot(thisX, thisY, 'd',...
+          'MarkerEdgeColor',colors(m,:),...
+          'MarkerFaceColor','w');
+  end
+  set(h, 'MarkerSize', 4);
+end
+title('Training set and Decision Boundaries (0/1 loss)')
+hold off
+
+% Plot of test_set --------------------------------------------------------------------------
+if nargin==4,
+    subplot(1,2,2);
+    axis([mn_x-1 mx_x+1 mn_y-1 mx_y+1]);
+    set(gca, 'Box', 'on');
+    hold on     
+    if size(test_data,2)==3,  % we know the classification of the test set examples
+        c_max_test = max(test_data(:,3));
+        for m=1:c_max_test,
+            app_x=test_data(:,1);
+            app_y=test_data(:,2);
+            thisX=app_x(test_data(:,3)==m);
+            thisY=app_y(test_data(:,3)==m);
+            if class_num<=6,
+                str_col=[];
+                str_col=['o', colors(m,:)];
+                plot(thisX, thisY, str_col, 'MarkerSize', ms);
+            else
+                plot(thisX, thisY, 'o',...
+                     'LineWidth', 1,...
+                     'MarkerEdgeColor', colors(m,:),...
+                     'MarkerSize',ms);
+            end
+        end
+    else
+        plot(test_data(:,1), test_data(:,2), 'ko',...
+            'MarkerSize', ms);
+    end
+    for m = 1:class_num,
+        thisX=[]; thisY=[];
+        thisX = X(class == m);
+        thisY = Y(class == m);
+        if class_num<=6,
+          str_col=[];
+          str_col=['d', colors(m,:)];
+          h=plot(thisX, thisY, str_col);  
+        else
+           h = plot(thisX, thisY, 'd',...
+                    'MarkerEdgeColor', colors(m,:),...
+                    'MarkerFaceColor','w');
+        end
+        set(h, 'MarkerSize', 4);
+    end
+    title('Test set and Decision Boundaries (0/1 loss)')
+    hold off
+end
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/hme_reg_plot.m b/sourcecodes/bnt-master/BNT/examples/static/HME/hme_reg_plot.m
new file mode 100644
index 00000000..510e96c2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/hme_reg_plot.m
@@ -0,0 +1,43 @@
+function fh=hme_reg_plot(net, nodes_info, train_data, test_data)
+% 
+% Use this function ONLY when the input dimension is 1
+% and the problem is a regression one.
+% We assume that each row of 'train_data' & 'test_data' is an example.
+%
+% ----------------------------------------------------------------------------------------------------
+% -> pierpaolo_b@hotmail.com   or   -> pampo@interfree.it
+% ----------------------------------------------------------------------------------------------------
+
+fh=figure('Name','HME based regression', 'MenuBar', 'none', 'NumberTitle', 'off');
+
+mn_x_train = round(min(train_data(:,1)));
+mx_x_train = round(max(train_data(:,1)));     
+x_train = mn_x_train(1):0.01:mx_x_train(1);
+Z_train=fhme(net, nodes_info, x_train',size(x_train,2));      % forward propagation trougth the HME
+
+if nargin==4,
+    subplot(2,1,1);
+    mn_x_test = round(min(test_data(:,1)));
+    mx_x_test = round(max(test_data(:,1)));
+    x_test = mn_x_test(1):0.01:mx_x_test(1);
+    Z_test=fhme(net, nodes_info, x_test',size(x_test,2));      % forward propagation trougth the HME
+end
+
+hold on;
+set(gca, 'Box', 'on');
+plot(x_train', Z_train, 'r');
+plot(train_data(:,1),train_data(:,2),'+k');
+title('Training set and prediction');
+hold off
+
+if nargin==4,
+    subplot(2,1,2);
+    hold on;
+    set(gca, 'Box', 'on');
+    plot(x_train', Z_train, 'r');
+    if size(test_data,2)==2,
+        plot(test_data(:,1),test_data(:,2),'+k');
+    end
+    title('Test set and prediction');
+    hold off
+end
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/hme_topobuilder.m b/sourcecodes/bnt-master/BNT/examples/static/HME/hme_topobuilder.m
new file mode 100644
index 00000000..0893bc38
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/hme_topobuilder.m
@@ -0,0 +1,47 @@
+function [bnet, onodes]=hme_topobuilder(nodes_info);
+%
+% HME topology builder
+%
+% ----------------------------------------------------------------------------------------------------
+% -> pierpaolo_b@hotmail.com   or   -> pampo@interfree.it
+% ----------------------------------------------------------------------------------------------------
+
+nodes_num=size(nodes_info,2);
+dag = zeros(nodes_num);
+list=[1:nodes_num];
+for i=1:(nodes_num-1)
+    app=[];
+    app=list((i+1):end);
+    dag(i,app) = 1;
+end
+onodes = [1 nodes_num];                           
+dnodes = list(2:end-1);
+if nodes_info(1,end)>0,
+    dnodes=[dnodes nodes_num];
+end
+ns = nodes_info(2,:);
+
+bnet = mk_bnet(dag, ns, dnodes);
+clamped = 0;
+
+bnet.CPD{1} = root_CPD(bnet, 1);
+
+rand('state', 50);
+randn('state', 50);
+
+for i=2:nodes_num,
+    if (nodes_info(1,i)==0)&(nodes_info(4,i)==1),
+        bnet.CPD{i} = gaussian_CPD(bnet, i, [], [], [], 'full');
+    elseif (nodes_info(1,i)==0)&(nodes_info(4,i)==2),
+        bnet.CPD{i} = gaussian_CPD(bnet, i, [], [], [], 'diag');
+    elseif (nodes_info(1,i)==0)&(nodes_info(4,i)==3),
+        bnet.CPD{i} = gaussian_CPD(bnet, i, [], [], [], 'full', 'tied');
+    elseif (nodes_info(1,i)==0)&(nodes_info(4,i)==4),
+        bnet.CPD{i} = gaussian_CPD(bnet, i, [], [], [], 'diag', 'tied');        
+    elseif nodes_info(1,i)==1,
+        %bnet.CPD{i} = dsoftmax_CPD(bnet, i, [], [], clamped, nodes_info(4,i));
+	bnet.CPD{i} = softmax_CPD(bnet, i, 'clamped', clamped, 'max_iter', nodes_info(4,i));
+    else
+        bnet.CPD{i} = mlp_CPD(bnet, i, nodes_info(3,i), [], [], [], [], clamped, nodes_info(4,i));
+    end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/hmemenu.m b/sourcecodes/bnt-master/BNT/examples/static/HME/hmemenu.m
new file mode 100644
index 00000000..64762b8e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/hmemenu.m
@@ -0,0 +1,552 @@
+% dataset      -> (1=>user data) or (2=>toy example)
+% type         -> (1=> Regression model) or (2=>Classification model)
+% num_glevel   -> number of hidden nodes in the net (gating levels)
+% num_exp      -> number of experts in the net
+% branch_fact  -> dimension of the hidden nodes in the net
+% cov_dim      -> root node dimension
+% res_dim      -> output node dimension
+% nodes_info   -> 4 x num_glevel+2 matrix that contain all the info about the nodes:
+%                 nodes_info(1,:) = nodes type: (0=>gaussian)or(1=>softmax)or(2=>mlp)
+%                 nodes_info(2,:) = nodes size: [cov_dim   num_glevel x branch_fact   res_dim]
+%                 nodes_info(3,:) = hidden units number (for mlp nodes)
+%                                  |- optimizer iteration number (for softmax & mlp CPD)
+%                 nodes_info(4,:) =|- covariance type (for gaussian CPD)-> 
+%                                  | (1=>Full)or(2=>Diagonal)or(3=>Full&Tied)or(4=>Diagonal&Tied)
+% fh1 -> Figure: data & decizion boundaries; fh2 -> confusion matrix; fh3 -> LL trace                                                                       
+% test_data    -> test data matrix
+% train_data   -> training data matrix
+% ntrain       -> size(train_data,2)
+% ntest        -> size(test_data,2)
+% cases        -> (cell array) training data formatted for the learning engine
+% bnet         -> bayesian net before learning
+% bnet2        -> bayesian net after learning
+% ll           -> log-likelihood before learning
+% LL2          -> log-likelihood trace
+% onodes       -> obs nodes in bnet & bnet2
+% max_em_iter  -> maximum number of interations of the EM algorithm
+% train_result -> prediction on the training set (as test_result)
+% 
+% IMPORTANT: CHECK the loading path (lines 64 & 364)
+% ----------------------------------------------------------------------------------------------------
+% -> pierpaolo_b@hotmail.com   or   -> pampo@interfree.it
+% ----------------------------------------------------------------------------------------------------
+
+error('this no longer works with the latest version of BNT')
+
+clear all;
+clc;
+disp('---------------------------------------------------');
+disp('  Hierarchical Mixtures of Experts models builder ');
+disp('---------------------------------------------------');
+disp(' ')
+disp('   Using this script you can build both an HME model')
+disp('as in [Wat94] and [Jor94] i.e. with ''softmax'' gating')
+disp('nodes and ''gaussian'' ( for regression ) or ''softmax''') 
+disp('( for classification ) expert node, and its variants')
+disp('called ''gated nets'' where we use ''mlp'' models in')
+disp('place of a number of ''softmax'' ones [Mor98], [Wei95].')
+disp('  You can decide to train and test the model on your')
+disp('datasets  or  to evaluate its  performance on  a toy')
+disp('example.')
+disp(' ')
+disp('Reference')
+disp('[Mor98] P. Moerland (1998):')
+disp('        Localized mixtures of experts. (http://www.idiap.ch/~perry/)')
+disp('[Jor94] M.I. Jordan, R.A. Jacobs (1994):')
+disp('        HME and the EM algorithm. (http://www.cs.berkeley.edu/~jordan/)')
+disp('[Wat94] S.R. Waterhouse, A.J. Robinson (1994):') 
+disp('        Classification using HME. (http://www.oigeeza.com/steve/)')
+disp('[Wei95] A.S. Weigend, M. Mangeas (1995):') 
+disp('        Nonlinear gated experts for time series.')
+disp(' ')
+
+if 0
+disp('(See the figure)')
+pause(5);
+%%%%%WARNING!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+im_path=which('HMEforMatlab.jpg');
+fig=imread(im_path, 'jpg');
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+figure('Units','pixels','MenuBar','none','NumberTitle','off', 'Name', 'HME model');
+image(fig); 
+axis image;
+axis off;
+clear fig;
+set(gca,'Position',[0 0 1 1])
+disp('(Press any key to continue)')
+pause
+end
+
+clc
+disp('---------------------------------------------------');
+disp('              Specify the Architecture             ');
+disp('---------------------------------------------------');
+disp(' ');
+disp('What kind of model do you need?')
+disp(' ')
+disp('1) Regression ')
+disp('2) Classification')
+disp(' ')
+type=input('1 or 2?: ');
+if (isempty(type)|(~ismember(type,[1 2]))), error('Invalid value'); end
+clc
+disp('----------------------------------------------------');
+disp('               Specify the Architecture             ');
+disp('----------------------------------------------------');
+disp(' ')
+disp('Now you have to set the number of experts and gating')
+disp('levels in the net.  This script builds only balanced')
+disp('hierarchy with the same branching factor (>1)at each')
+disp('(gating) level. So remember that: ')
+disp(' ')
+disp('         num_exp = branch_fact^num_glevel           ')
+disp(' ')
+disp('with branch_fact >=2.')
+disp('You can also set to zeros the number of gating level')
+disp('in order to obtain a classical GLM model.           ')
+disp(' ')
+disp('----------------------------------------------------');
+disp(' ')
+num_glevel=input('Insert the number of gating levels {0,...,20}: ');
+if (isempty(num_glevel)|(~ismember(num_glevel,[0:20]))), error('Invalid value'); end
+nodes_info=zeros(4,num_glevel+2);
+if num_glevel>0, %------------------------------------------------------------------------------------
+    for i=2:num_glevel+1,
+        clc
+        disp('----------------------------------------------------');
+        disp('               Specify the Architecture             ');
+        disp('----------------------------------------------------');
+        disp(' ')   
+        disp(['-> Gating network ', num2str(i-1), ' is a: '])
+        disp(' ')
+        disp('   1) Softmax model');
+        disp('   2) Two layer perceptron model')
+        disp(' ')
+        nodes_info(1,i)=input('1 or 2?: ');
+        if (isempty(nodes_info(1,i))|(~ismember(nodes_info(1,i),[1 2]))), error('Invalid value'); end
+        disp(' ')
+        if nodes_info(1,i)==2,
+           nodes_info(3,i)=input('Insert the number of units in the hidden layer: ');
+           if (isempty(nodes_info(3,i))|(floor(nodes_info(3,i))~=nodes_info(3,i))|(nodes_info(3,i)<=0)), 
+              error(['Invalid value: ', num2str(nodes_info(3,i)), ' is not a positive integer!']);
+           end
+           disp(' ')
+        end
+        nodes_info(4,i)=input('Insert the optimizer iteration number: ');
+        if (isempty(nodes_info(4,i))|(floor(nodes_info(4,i))~=nodes_info(4,i))|(nodes_info(4,i)<=0)), 
+           error(['Invalid value: ', num2str(nodes_info(4,i)), ' is not a positive integer!']);
+        end    
+    end
+    clc
+    disp('---------------------------------------------------------');
+    disp('                 Specify the Architecture                ');
+    disp('---------------------------------------------------------');
+    disp(' ')
+    disp('Now you have to set the number  of experts in the network');
+    disp('The value will be adjusted in order to obtain a hierarchy');
+    disp('as said above.')
+    disp(' ');    
+    num_exp=input(['Insert the approximative number of experts (>=', num2str(2^num_glevel), '): ']);
+    if (isempty(num_exp)|(num_exp<=0)|(num_exp<2^num_glevel)), 
+        error('Invalid value');
+    end
+    app1=0; base=2;
+    while app1<num_exp,
+        app1=base^num_glevel;
+        base=base+1;
+    end
+    app2=(base-2)^num_glevel;
+    branch_fact=base-1;
+    if app2>=(2^num_glevel)&(abs(app2-num_exp)<abs(app1-num_exp)),
+        branch_fact=base-2;
+    end
+    clear app1 app2 base;
+    disp(' ')
+    disp(['The effective number of experts in the net is: ', num2str(branch_fact^num_glevel), '.'])
+    disp(' ');
+else
+    clc
+    disp('---------------------------------------------------------');
+    disp('        Specify the Architecture (GLM model)             ');
+    disp('---------------------------------------------------------');
+    disp(' ')
+end % END of: if num_glevel>0-------------------------------------------------------------------------
+
+if type==2,
+    disp(['-> Expert node is a: '])
+    disp(' ')
+    disp('   1) Softmax model');
+    disp('   2) Two layer perceptron model')
+    disp(' ')
+    nodes_info(1,end)=input('1 or 2?: ');
+    if (isempty(nodes_info(1,end))|(~ismember(nodes_info(1,end),[1 2]))), 
+        error('Invalid value'); 
+    end
+    disp(' ')
+    if nodes_info(1,end)==2,
+       nodes_info(3,end)=input('Insert the number of units in the hidden layer: ');
+       if (isempty(nodes_info(3,end))|(floor(nodes_info(3,end))~=nodes_info(3,end))|(nodes_info(3,end)<=0)), 
+           error(['Invalid value: ', num2str(nodes_info(3,end)), ' is not a positive integer!']);
+       end
+       disp(' ')
+    end
+    nodes_info(4,end)=input('Insert the optimizer iteration number: ');
+    if (isempty(nodes_info(4,end))|(floor(nodes_info(4,end))~=nodes_info(4,end))|(nodes_info(4,end)<=0)), 
+        error(['Invalid value: ', num2str(nodes_info(4,end)), ' is not a positive integer!']);
+    end
+elseif type==1,
+    disp('What kind of covariance matrix structure do you want?')
+    disp(' ')
+    disp('   1) Full');
+    disp('   2) Diagonal')
+    disp('   3) Full & Tied');
+    disp('   4) Diagonal & Tied')
+
+    disp(' ')
+    nodes_info(4,end)=input('1, 2, 3 or 4?: ');
+    if (isempty(nodes_info(4,end))|(~ismember(nodes_info(4,end),[1 2 3 4]))), 
+        error('Invalid value'); 
+    end  
+end
+clc
+disp('----------------------------------------------------');
+disp('                    Specify the Input               ');
+disp('----------------------------------------------------');
+disp(' ')
+disp('Do you want to...')
+disp(' ')
+disp('1) ...use your own dataset?')
+disp('2) ...apply the model on a toy example?')
+disp(' ')
+dataset=input('1 or 2?: ');
+if (isempty(dataset)|(~ismember(dataset,[1 2]))), error('Invalid value'); end
+if dataset==1,
+    if type==1,
+        clc
+        disp('-------------------------------------------------------');
+        disp('        Specify the Input - Regression problem         ');
+        disp('-------------------------------------------------------');
+        disp(' ')
+        disp('Be sure that each row of your data matrix is an example');
+        disp('with the covariate values that precede the respond ones')
+        disp(' ')
+        disp('-------------------------------------------------------');
+        disp(' ')
+        cov_dim=input('Insert the covariate space dimension: ');
+        if (isempty(cov_dim)|(floor(cov_dim)~=cov_dim)|(cov_dim<=0)), 
+          error(['Invalid value: ', num2str(cov_dim), ' is not a positive integer!']);
+        end
+        disp(' ')
+        res_dim=input('Insert the dimension of the respond variable: ');
+        if (isempty(res_dim)|(floor(res_dim)~=res_dim)|(res_dim<=0)), 
+            error(['Invalid value: ', num2str(res_dim), ' is not a positive integer!']);
+        end 
+        disp(' ');
+    elseif type==2
+        clc
+        disp('-------------------------------------------------------');
+        disp('      Specify the Input - Classification problem       ');
+        disp('-------------------------------------------------------');
+        disp(' ')
+        disp('Be sure that each row of your data matrix is an example');
+        disp('with the covariate values that precede the class labels');
+        disp('(integer value >=1).                                   ');
+        disp(' ')
+        disp('-------------------------------------------------------');
+        disp(' ')
+        cov_dim=input('Insert the covariate space dimension: ');
+        if (isempty(cov_dim)|(floor(cov_dim)~=cov_dim)|(cov_dim<=0)), 
+          error(['Invalid value: ', num2str(cov_dim), ' is not a positive integer!']);
+        end
+        disp(' ')
+        res_dim=input('Insert the number of classes: ');
+        if (isempty(res_dim)|(floor(res_dim)~=res_dim)|(res_dim<=0)), 
+          error(['Invalid value: ', num2str(res_dim), ' is not a positive integer!']);
+        end        
+        disp(' ')               
+    end    
+    % ------------------------------------------------------------------------------------------------
+    % Loading training data --------------------------------------------------------------------------
+    % ------------------------------------------------------------------------------------------------
+    train_path=input('Insert the complete (with extension) path of the training data file:\n >> ','s');    
+    if isempty(train_path), error('You must specify a data set for training!'); end
+    if ~isempty(findstr('.mat',train_path)),
+        ap=load(train_path); app=fieldnames(ap); train_data=eval(['ap.', app{1,1}]);
+        clear ap app;
+    elseif ~isempty(findstr('.txt',train_path)),
+        train_data=load(train_path, '-ascii');
+    else
+        error('Invalid data format: not a .mat or a .txt file')
+    end
+    if (size(train_data,2)~=cov_dim+res_dim)&(type==1),
+        error(['Invalid data matrix size: ', num2str(size(train_data,2)), ' columns rather than ',...
+            num2str(cov_dim+res_dim),'!']);
+    elseif (size(train_data,2)~=cov_dim+1)&(type==2),
+        error(['Invalid data matrix size: ', num2str(size(train_data,2)), ' columns rather than ',...
+            num2str(cov_dim+1),'!']);    
+    elseif (~isempty(find(ismember(intersect([train_data(:,end)' 1:res_dim],...
+            train_data(:,end)'),[1:res_dim])==0)))&(type==2),
+        error('Invalid class label');
+    end    
+    ntrain=size(train_data,1);
+    train_d=train_data(:,1:cov_dim);
+    if type==2,
+        train_t=zeros(ntrain, res_dim);
+        for m=1:res_dim,
+            train_t((find(train_data(:,end)==m))',m)=1;
+        end
+    else
+        train_t=train_data(:,cov_dim+1:end);
+    end        
+    disp(' ')
+    % ------------------------------------------------------------------------------------------------
+    % Loading test data ------------------------------------------------------------------------------
+    % ------------------------------------------------------------------------------------------------
+    disp('(If you don''t want to specify a test-set press ''return'' only)');
+    test_path=input('Insert the complete (with extension) path of the test data file:\n >> ','s');  
+    if ~isempty(test_path),
+        if ~isempty(findstr('.mat',test_path)),        
+            ap=load(test_path); app=fieldnames(ap); test_data=eval(['ap.', app{1,1}]);
+            clear ap app;
+        elseif ~isempty(findstr('.txt',test_path)),
+            test_data=load(test_path, '-ascii');
+        else
+            error('Invalid data format: not a .mat or a .txt file')
+        end
+        if (size(test_data,2)~=cov_dim)&(size(test_data,2)~=cov_dim+res_dim)&(type==1),
+            error(['Invalid data matrix size: ', num2str(size(test_data,2)), ' columns rather than ',...
+                num2str(cov_dim+res_dim), ' or ', num2str(cov_dim), '!']);
+        elseif (size(test_data,2)~=cov_dim)&(size(test_data,2)~=cov_dim+1)&(type==2),
+            error(['Invalid data matrix size: ', num2str(size(test_data,2)), ' columns rather than ',...
+                num2str(cov_dim+1), ' or ', num2str(cov_dim), '!']);
+        elseif (~isempty(find(ismember(intersect([test_data(:,end)' 1:res_dim],...
+                test_data(:,end)'),[1:res_dim])==0)))&(type==2)&(size(test_data,2)==cov_dim+1),
+            error('Invalid class label');
+        end
+        ntest=size(test_data,1);        
+        test_d=test_data(:,1:cov_dim);
+        if (type==2)&(size(test_data,2)>cov_dim),
+            test_t=zeros(ntest, res_dim);
+            for m=1:res_dim,
+                test_t((find(test_data(:,end)==m))',m)=1;
+            end
+        elseif (type==1)&(size(test_data,2)>cov_dim),
+            test_t=test_data(:,cov_dim+1:end);
+        end
+        disp(' ');
+    end
+else    
+    clc
+    disp('----------------------------------------------------');
+    disp('                  Specify the Input                 ');
+    disp('----------------------------------------------------');
+    disp(' ')
+    ntrain = input('Insert the number of examples in training (<500): ');
+    if (isempty(ntrain)|(floor(ntrain)~=ntrain)|(ntrain<=0)|(ntrain>500)), 
+          error(['Invalid value: ', num2str(ntrain), ' is not a positive integer <500!']);
+    end        
+    disp(' ')
+    test_path='toy';
+    ntest = input('Insert the number of examples in test (<500): ');
+    if (isempty(ntest)|(floor(ntest)~=ntest)|(ntest<=0)|(ntest>500)), 
+          error(['Invalid value: ', num2str(ntest), ' is not a positive integer <500!']);
+    end        
+
+    if type==2,
+        cov_dim=2;
+        res_dim=3;
+        seed = 42;
+        [train_d, ntrain1, ntrain2, train_t]=gen_data(ntrain, seed);
+        for m=1:ntrain
+            q=[]; q = find(train_t(m,:)==1);
+            train_data(m,:)=[train_d(m,:) q];
+        end
+        [test_d, ntest1, ntest2, test_t]=gen_data(ntest);
+        for m=1:ntest
+            q=[]; q = find(test_t(m,:)==1);
+            test_data(m,:)=[test_d(m,:) q];
+        end
+    else
+        cov_dim=1;
+        res_dim=1;
+        global HOME
+        %%%%%WARNING!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+        load([HOME '/examples/static/Misc/mixexp_data.txt'], '-ascii');
+        %%%%%WARNING!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+        train_data = mixexp_data(1:ntrain, :);
+        train_d=train_data(:,1:cov_dim); train_t=train_data(:,cov_dim+1:end);
+        test_data = mixexp_data(ntrain+1:ntrain+ntest, :);
+        test_d=test_data(:,1:cov_dim); 
+        if size(test_data,2)>cov_dim,
+            test_t=test_data(:,cov_dim+1:end);
+        end
+    end    
+end
+% Set the nodes dimension-----------------------------------
+if num_glevel>0,
+    nodes_info(2,2:num_glevel+1)=branch_fact;
+end
+nodes_info(2,1)=cov_dim; nodes_info(2,end)=res_dim;
+%-----------------------------------------------------------
+% Prepare the training data for the learning engine---------
+%-----------------------------------------------------------
+cases = cell(size(nodes_info,2), ntrain);
+for m=1:ntrain,
+    cases{1,m}=train_data(m,1:cov_dim)';
+    cases{end,m}=train_data(m,cov_dim+1:end)';
+end
+%-----------------------------------------------------------------------------------------------------
+[bnet onodes]=hme_topobuilder(nodes_info);
+engine = jtree_inf_engine(bnet, onodes);
+clc
+disp('---------------------------------------------------------------------');
+disp('                         L  E  A  R  N  I  N  G                      ');
+disp('---------------------------------------------------------------------');
+disp(' ')
+ll = 0;
+for l=1:ntrain
+  scritta=['example number: ', int2str(l),'---------------------------------------------'];
+  disp(scritta);
+  ev = cases(:,l);
+  [engine, loglik] = enter_evidence(engine, ev);
+  ll = ll + loglik;
+end
+disp(' ')
+disp(['Log-likelihood before learning: ', num2str(ll)]);
+disp(' ')
+disp('(Press any key to continue)');
+pause
+%-----------------------------------------------------------
+clc
+disp('---------------------------------------------------------------------');
+disp('                         L  E  A  R  N  I  N  G                      ');
+disp('---------------------------------------------------------------------');
+disp(' ')
+max_em_iter=input('Insert the maximum number of the EM algorithm iterations: ');
+if (isempty(max_em_iter)|(floor(max_em_iter)~=max_em_iter)|(max_em_iter<=1)), 
+          error(['Invalid value: ', num2str(ntest), ' is not a positive integer >1!']);
+end 
+disp(' ')
+disp(['Log-likelihood before learning: ', num2str(ll)]);
+disp(' ')
+
+[bnet2, LL2] = learn_params_em(engine, cases, max_em_iter);
+disp(' ')
+fprintf('HME: loglik before learning %f, after %d iters %f\n', ll, length(LL2),  LL2(end));
+disp(' ')
+disp('(Press any key to continue)');
+pause
+%-----------------------------------------------------------------------------------
+% Classification problem: plot data & decision boundaries if the input data size = 2
+% Regression problem: plot data & prediction if the input data size = 1
+%-----------------------------------------------------------------------------------
+if (type==2)&(nodes_info(2,1)==2)&(~isempty(test_path)),
+    fh1=hme_class_plot(bnet2, nodes_info, train_data, test_data);
+    disp(' ');
+    disp('(See the figure)');
+elseif (type==2)&(nodes_info(2,1)==2)&(isempty(test_path)),
+    fh1=hme_class_plot(bnet2, nodes_info, train_data);
+    disp(' ');
+    disp('(See the figure)');
+elseif (type==1)&(nodes_info(2,1)==1)&(~isempty(test_path)),
+    fh1=hme_reg_plot(bnet2, nodes_info, train_data, test_data);
+    disp(' ');
+    disp('(See the figure)');
+elseif (type==1)&(nodes_info(2,1)==1)&(isempty(test_path)),
+    fh1=hme_reg_plot(bnet2, nodes_info, train_data);
+    disp(' ')
+    disp('(See the figure)');
+end
+%-----------------------------------------------------------------------------------
+% Classification problem: plot confusion matrix
+%-----------------------------------------------------------------------------------
+if (type==2)
+    ztrain=fhme(bnet2, nodes_info, train_d, size(train_d,1));  
+    [Htrain, trainRate]=confmat(ztrain, train_t); % CM on the training set
+    fh2=figure('Name','Confusion matrix', 'MenuBar', 'none', 'NumberTitle', 'off');
+    if (~isempty(test_path))&(size(test_data,2)>cov_dim),
+        ztest=fhme(bnet2, nodes_info, test_d, size(test_d,1));
+        [Htest, testRate]=confmat(ztest, test_t);   % CM on the test set
+        subplot(1,2,1);
+    end
+    plotmat(Htrain,'b','k',12)
+    tick=[0.5:1:(0.5+nodes_info(2,end)-1)];
+    set(gca,'XTick',tick)
+    set(gca,'YTick',tick)
+    grid('off')
+    ylabel('True')
+    xlabel('Prediction')
+    title(['Confusion Matrix: training set (' num2str(trainRate(1)) '%)'])
+    if (~isempty(test_path))&(size(test_data,2)>cov_dim),
+        subplot(1,2,2)
+        plotmat(Htest,'b','k',12)
+        set(gca,'XTick',tick)
+        set(gca,'YTick',tick)
+        grid('off')
+        ylabel('True')
+        xlabel('Prediction')
+        title(['Confusion Matrix: test set (' num2str(testRate(1)) '%)'])
+    end
+    disp(' ')
+    disp('(Press any key to continue)');
+    pause
+end
+%-----------------------------------------------------------------------------------
+% Regression & Classification problem: calculate the predictions & plot the LL trace
+%-----------------------------------------------------------------------------------
+train_result=fhme(bnet2,nodes_info,train_d,size(train_d,1));
+if ~isempty(test_path),
+    test_result=fhme(bnet2,nodes_info,test_d,size(test_d,1));
+end
+fh3=figure('Name','Log-likelihood trace', 'MenuBar', 'none', 'NumberTitle', 'off')
+plot(LL2,'-ro',...
+                'MarkerEdgeColor','k',...
+                'MarkerFaceColor',[1 1 0],...
+                'MarkerSize',4)
+title('Log-likelihood trace')
+%-----------------------------------------------------------------------------------
+% Regression & Classification problem: save the predictions
+%-----------------------------------------------------------------------------------
+clc
+disp('------------------------------------------------------------------');
+disp('                           Save the results                       ');
+disp('------------------------------------------------------------------');
+disp(' ')
+%-----------------------------------------------------------------------------------
+save_quest_m=input('Do you want to save the HME model (Y/N)? [Y default]: ', 's');
+if isempty(save_quest_m),
+    save_quest_m='Y';
+end
+if ~findstr(save_quest_m, ['Y', 'N']), error('Invalid input'); end
+if save_quest_m=='Y',
+    disp(' ');
+    m_save=input('Insert the complete path for save the HME model (.mat):\n >> ', 's');
+    if isempty(m_save), error('You must specify a path!'); end
+    save(m_save, 'bnet2');
+end
+%-----------------------------------------------------------------------------------    
+disp(' ')
+save_quest=input('Do you want to save the HME predictions (Y/N)? [Y default]: ', 's');
+disp(' ')
+if isempty(save_quest),
+    save_quest='Y';
+end
+if ~findstr(save_quest, ['Y', 'N']), error('Invalid input'); end
+if save_quest=='Y',
+    tr_save=input('Insert the complete path for save the training data prediction (.mat):\n >> ', 's');    
+    if isempty(tr_save), error('You must specify a path!'); end
+    save(tr_save, 'train_result');  
+    if ~isempty(test_path),
+        disp(' ')
+        te_save=input('Insert the complete path for save the test data prediction (.mat):\n >> ', 's');
+        if isempty(te_save), error('You must specify a path!'); end
+        save(te_save, 'test_result');
+    end
+end
+clc
+disp('----------------------------------------------------');
+disp('                      B  Y  E !                     ');
+disp('----------------------------------------------------');
+pause(2)
+%clear 
+clc
diff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/test_data_class.mat b/sourcecodes/bnt-master/BNT/examples/static/HME/test_data_class.mat
new file mode 100644
index 00000000..7340c99e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/test_data_class.mat
Binary files differdiff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/test_data_class2.mat b/sourcecodes/bnt-master/BNT/examples/static/HME/test_data_class2.mat
new file mode 100644
index 00000000..33b9aa43
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/test_data_class2.mat
Binary files differdiff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/test_data_reg.mat b/sourcecodes/bnt-master/BNT/examples/static/HME/test_data_reg.mat
new file mode 100644
index 00000000..daffe218
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/test_data_reg.mat
Binary files differdiff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/train_data_class.mat b/sourcecodes/bnt-master/BNT/examples/static/HME/train_data_class.mat
new file mode 100644
index 00000000..f181a433
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/train_data_class.mat
Binary files differdiff --git a/sourcecodes/bnt-master/BNT/examples/static/HME/train_data_reg.mat b/sourcecodes/bnt-master/BNT/examples/static/HME/train_data_reg.mat
new file mode 100644
index 00000000..a0a2be2c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/HME/train_data_reg.mat
Binary files differdiff --git a/sourcecodes/bnt-master/BNT/examples/static/Misc/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/static/Misc/CVS/Entries
new file mode 100644
index 00000000..9e60b950
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Misc/CVS/Entries
@@ -0,0 +1,5 @@
+/mixexp_data.txt/1.1.1.1/Wed May 29 15:59:54 2002//
+/mixexp_graddesc.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mixexp_plot.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sprinkler.bif/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Misc/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/static/Misc/CVS/Repository
new file mode 100644
index 00000000..cd252fd6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Misc/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/static/Misc
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Misc/CVS/Root b/sourcecodes/bnt-master/BNT/examples/static/Misc/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Misc/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Misc/mixexp_data.txt b/sourcecodes/bnt-master/BNT/examples/static/Misc/mixexp_data.txt
new file mode 100644
index 00000000..9bff9448
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Misc/mixexp_data.txt
@@ -0,0 +1,1000 @@
+  0.68   0.65
+ -0.31  -0.24
+  0.85   0.94
+ -0.34  -0.31
+ -0.58   0.62
+ -0.04  -0.11
+ -0.82   0.61
+ -0.38   0.16
+  0.71   0.75
+  0.80   0.95
+  0.66   0.64
+ -0.11  -0.03
+ -0.16   0.11
+ -0.47   0.75
+  0.09   0.43
+  0.04  -0.36
+ -0.80   0.77
+ -0.63   0.79
+ -0.13   0.46
+  0.49   0.78
+  0.93   1.12
+  0.08  -0.35
+  0.27  -0.19
+ -0.66   0.56
+  0.98   1.02
+  0.13  -0.16
+ -0.21   0.10
+  0.41   0.29
+  0.18   0.34
+ -0.46   0.21
+  0.03  -0.24
+  0.96   1.42
+  0.96   1.45
+  0.93   1.12
+  0.08  -0.21
+ -0.49   0.39
+  0.66   0.21
+ -0.70   0.45
+ -0.81   0.57
+ -0.17   0.10
+ -0.22   0.03
+  0.24   0.32
+ -0.07   0.31
+ -0.47   0.58
+  0.41   0.28
+ -0.16   0.03
+  0.97   0.79
+ -0.07  -0.09
+  0.22   0.32
+ -0.71   0.73
+  0.51   0.22
+  0.21   0.57
+  0.64   0.58
+ -0.65   0.74
+  0.05   0.55
+  0.41   0.67
+ -0.96   1.36
+ -0.35   0.03
+ -0.38  -0.15
+  0.61   0.71
+ -0.93   0.75
+  0.98   0.99
+  0.58   0.61
+  0.53   0.62
+ -0.24  -0.04
+ -0.84   1.07
+ -0.35   0.42
+ -0.12   0.15
+ -0.38   0.18
+ -0.87   1.15
+  0.38   0.38
+ -0.58   0.57
+  0.42   0.48
+  0.64   0.59
+ -0.52   0.54
+  0.56   0.54
+ -0.22   0.21
+ -0.64   0.94
+  0.92   0.99
+  0.73   0.31
+ -0.04   0.39
+ -0.42   0.40
+ -0.73   1.08
+ -0.67   0.51
+ -0.51  -0.11
+ -0.71   0.81
+ -0.44   0.32
+  0.34   0.15
+  0.45   0.27
+  0.83   0.57
+ -0.91   1.07
+ -0.27   0.46
+ -0.51   0.23
+ -0.90   0.66
+  0.09   0.03
+  0.05  -0.16
+ -0.87   0.45
+ -0.43   0.61
+ -0.00   0.16
+  0.48   0.49
+ -0.84   1.06
+ -0.45   0.34
+ -0.25   0.30
+ -0.91   1.03
+ -0.82   0.88
+ -0.45   0.23
+  0.77   0.59
+ -0.40   0.30
+  0.45   0.28
+ -0.56   0.17
+ -0.81   1.00
+  0.68   0.81
+  0.18   0.03
+  0.64   1.01
+  0.63   0.61
+ -0.16   0.48
+  0.66   0.92
+ -0.22   0.14
+ -0.49   0.36
+ -0.66   0.92
+  0.77   0.91
+ -0.10  -0.28
+ -0.42   0.22
+  0.96   1.23
+  0.85   0.72
+  0.87   0.71
+  0.86   0.85
+ -0.53   0.72
+ -0.60   0.54
+  0.43   0.65
+ -0.37   0.29
+ -0.84   0.72
+ -0.46   0.35
+  0.11  -0.39
+  0.72   0.97
+  0.92   0.89
+ -0.32   0.29
+  0.27   0.05
+  0.45   0.44
+ -0.25   0.34
+ -0.45   1.16
+ -0.52   0.85
+ -0.78   0.90
+  0.03  -0.11
+ -0.88   0.33
+ -0.56   1.02
+  0.83   0.54
+ -0.01   0.14
+  0.86   1.05
+ -0.53   0.21
+ -0.60   0.10
+  0.89   1.15
+  0.65   0.61
+ -0.04   0.29
+  0.72   0.51
+ -0.32   0.40
+ -0.75   0.69
+  0.47   0.48
+  0.49   0.69
+  0.55   0.59
+ -0.20  -0.15
+ -0.52   0.36
+ -0.61   1.07
+ -0.02  -0.02
+ -0.67   0.63
+  0.42   0.46
+ -0.20   0.66
+  0.84   0.27
+  0.05  -0.12
+  0.96   0.51
+ -0.71   0.72
+  0.04  -0.16
+ -0.68   0.91
+ -0.38   0.26
+  0.11   0.18
+  0.40   0.32
+ -0.75   0.59
+ -0.43   0.54
+  0.96   1.53
+ -0.20   0.31
+ -0.14  -0.48
+  0.84   0.50
+  0.12  -0.28
+  0.66   1.07
+ -0.15   0.19
+  0.28   0.48
+  0.78   0.54
+ -0.75   0.73
+  0.37   0.26
+ -0.67   0.39
+ -0.71   0.31
+ -0.96   0.82
+  0.68   0.75
+ -0.36   0.56
+  0.59   0.44
+  0.68   0.23
+  0.10  -0.04
+  0.13   0.43
+  0.28   0.52
+ -0.83   0.55
+ -0.41   0.38
+ -0.21  -0.00
+  0.08   0.23
+  0.04  -0.02
+ -0.11   0.14
+  0.40   0.34
+  0.22   0.43
+  0.30   0.19
+ -0.85   0.83
+  0.13  -0.12
+ -0.55   0.49
+  0.15   0.09
+  0.48   0.15
+ -0.19   0.24
+ -0.39  -0.11
+ -0.79   0.50
+ -0.53   0.73
+  0.07  -0.17
+  0.51   0.75
+  0.84   0.78
+  0.70   0.39
+  0.94   0.55
+ -0.73   1.00
+  0.95   1.10
+ -0.44   0.55
+ -0.50   0.54
+ -0.34   0.00
+  0.31   0.61
+  0.02   0.14
+  0.85   0.57
+  0.74   0.58
+ -0.05  -0.14
+ -0.94   0.80
+ -0.59   0.18
+  0.28  -0.32
+  0.98   0.88
+  0.64   0.20
+ -0.20   0.13
+  0.58   1.10
+  0.08  -0.05
+ -0.39   0.66
+  0.22   0.36
+  0.07  -0.08
+ -0.87   1.11
+ -0.05   0.14
+  0.91   0.91
+  0.87   1.19
+ -0.99   1.14
+  0.55   1.30
+ -0.90   0.81
+  0.49   0.42
+  0.11   0.30
+ -0.90   0.64
+ -0.38   0.52
+  0.38   0.61
+ -0.67   0.58
+ -0.05   0.25
+  0.36   0.85
+  0.84   0.51
+  0.04   0.08
+  0.05   0.08
+ -0.20   0.22
+ -0.98   0.74
+  0.14   0.29
+  0.93   1.22
+  0.19   0.41
+ -0.85   1.16
+  0.44   0.84
+  0.34  -0.04
+ -0.33   0.16
+  0.90   0.73
+  0.58   0.39
+ -0.97   0.70
+ -0.18   0.09
+ -1.00   0.83
+ -0.75   1.07
+  0.98   1.01
+ -0.94   1.11
+  0.46   1.00
+  0.64   0.38
+ -0.21  -0.10
+ -0.18   0.04
+ -0.39   0.61
+ -0.85   0.46
+ -0.94   1.08
+  0.49   0.26
+ -0.94   0.87
+  0.08   0.19
+ -0.05   0.45
+ -0.98   0.94
+  0.75   0.86
+  0.67   0.83
+  0.62   0.21
+ -0.29  -0.33
+  0.64   0.42
+ -0.32   0.48
+  0.39   0.34
+ -0.88   1.29
+ -0.03  -0.23
+  0.77   0.68
+  0.15   0.18
+ -0.99   1.20
+ -0.38   0.25
+ -0.58   0.45
+  0.08   0.00
+  0.30   0.29
+ -0.78   0.61
+  0.85   0.55
+ -0.79   0.57
+  0.75   0.40
+ -0.13  -0.03
+ -0.34  -0.00
+ -0.27  -0.03
+  0.76   1.15
+  0.12   0.66
+  0.91   1.48
+  0.10  -0.07
+ -0.17  -0.18
+ -0.65   0.98
+ -0.54   0.18
+  0.02   0.07
+  0.15   0.43
+ -0.82   0.94
+  0.73   0.40
+ -0.47   0.41
+ -0.32   0.59
+ -0.33   0.41
+  0.66   0.70
+  0.88   0.79
+  0.24   0.29
+ -0.89   1.25
+  0.83   0.84
+  0.35   0.74
+  0.16   0.32
+ -0.70   0.83
+  0.71   0.58
+  0.17  -0.38
+ -0.83   0.77
+  0.47   0.47
+  0.28   0.51
+  0.18   0.54
+ -0.86   0.79
+ -0.36  -0.00
+  0.22  -0.04
+ -0.07   0.57
+  0.49   0.31
+ -0.96   0.58
+ -0.85   0.80
+  0.92   0.93
+ -0.96   0.94
+  0.19  -0.39
+ -0.33   0.07
+ -0.71   0.67
+  0.30  -0.22
+ -0.29   0.67
+ -0.18  -0.17
+  0.68   0.52
+  0.57   0.39
+ -0.17   0.41
+ -0.08   0.06
+  0.89   0.86
+  0.99   0.88
+ -0.69   0.71
+  0.09   0.42
+ -0.95   1.04
+  0.71   0.57
+  0.67   0.95
+  0.24   0.13
+ -0.34   0.22
+ -0.00  -0.00
+ -0.05   0.71
+  0.93   1.59
+ -0.29   0.32
+  0.27   0.50
+ -0.90   0.91
+  0.17   0.17
+  0.23   0.16
+  0.19  -0.16
+  0.93   0.50
+  0.11  -0.39
+  0.96   1.11
+  0.64   1.04
+ -0.75   0.89
+ -0.55   0.11
+  0.20   0.12
+ -0.10  -0.50
+  0.40   0.75
+  0.91   0.84
+ -0.60   0.31
+  0.20   0.38
+ -0.85   0.87
+  0.91   1.19
+  0.27   0.42
+  0.18  -0.01
+ -0.47   0.33
+  0.02  -0.30
+  0.84   1.08
+  0.75   1.10
+  0.06  -0.20
+ -0.32   0.31
+ -0.03  -0.19
+  0.40   0.07
+ -0.33   0.20
+  0.50   0.81
+  0.57   1.11
+ -0.70   0.96
+  0.09  -0.01
+ -0.99   0.86
+  0.67   0.68
+  0.15   0.04
+  0.29   0.58
+  0.03  -0.25
+ -0.59   0.75
+ -0.98   0.48
+ -0.33   0.25
+ -0.10   0.51
+ -0.78   0.67
+ -0.89   0.84
+ -0.23   0.13
+ -0.55   0.20
+  0.61   0.79
+ -0.34   0.31
+  0.90   0.79
+  0.15   0.60
+ -0.48   0.04
+ -0.89   1.15
+ -0.92   1.34
+  0.91   0.87
+ -0.34   0.12
+  0.08   0.51
+  0.82   0.58
+ -0.66   0.72
+  0.02  -0.23
+ -0.05   0.51
+  0.39   0.44
+ -0.64   0.79
+  0.22  -0.30
+ -0.13   0.56
+ -0.03   0.14
+  0.67   0.68
+ -0.02   0.05
+ -0.35   0.22
+ -0.50   0.57
+ -0.71   0.63
+  0.70   0.73
+ -0.52   1.35
+  0.51   0.38
+ -0.67   0.48
+ -0.34   0.56
+ -0.45   0.32
+  0.82   0.73
+ -0.32  -0.31
+ -0.06   0.23
+ -0.33   0.00
+ -0.28   0.39
+  0.98   1.13
+  0.11   0.08
+ -0.01  -0.05
+  0.36   0.13
+ -0.35   0.47
+  0.84   1.12
+ -0.45   0.14
+ -0.48   0.03
+  0.01  -0.27
+  0.04  -0.14
+  0.37   0.78
+  0.58  -0.14
+  0.56   0.50
+  0.71   0.63
+ -0.79   0.64
+ -0.35   0.16
+  0.16  -0.10
+  0.73   1.05
+ -0.11   0.23
+ -0.76   0.56
+  0.88   0.71
+  0.43   0.26
+ -0.33   0.51
+ -0.55   0.53
+ -0.17   0.23
+ -0.16  -0.32
+  0.53   0.29
+  0.99   1.28
+  0.30   0.24
+ -0.29   0.54
+  0.23   0.34
+  0.19  -0.00
+  0.71   1.04
+ -0.35   0.39
+  0.54   0.73
+ -0.25   0.03
+ -0.16   0.12
+  0.43   0.51
+  0.07   0.12
+  0.58  -0.60
+ -0.59   0.36
+ -0.68   0.89
+ -0.24   0.08
+  0.52   0.36
+  0.23   0.14
+  0.26   0.48
+  0.50   0.68
+  1.00   0.86
+  0.25  -0.21
+ -0.37   0.24
+  0.13  -0.40
+  0.86   0.78
+  0.81   1.03
+  0.52   0.57
+  0.79   0.79
+ -0.54   0.99
+  0.19  -0.14
+  0.09  -0.06
+ -0.73   0.52
+ -0.70   0.35
+ -0.16   0.47
+ -0.10   0.25
+ -0.19   0.08
+ -0.41  -0.05
+ -0.71   1.07
+  0.19  -0.01
+  0.94   1.21
+  0.23   0.05
+ -0.25   0.25
+ -0.03  -0.48
+ -0.10   0.12
+ -0.59   0.73
+  0.66   1.12
+  0.36   0.29
+ -0.18   0.17
+  0.99   1.20
+  0.22  -0.22
+ -0.82   0.99
+ -0.54   0.93
+ -0.73   0.74
+  0.34   0.63
+  0.66   0.75
+ -0.72   0.68
+  0.73   0.87
+  0.72   0.60
+ -0.36   0.59
+ -0.01  -0.03
+ -0.20   0.33
+ -0.22  -0.30
+  0.90   1.11
+  0.37   0.13
+ -0.92   0.69
+ -0.93   1.00
+  0.84   1.16
+ -0.70   0.99
+ -0.51   0.50
+ -0.78   1.09
+ -0.65   1.21
+ -0.85   0.68
+  0.42   0.37
+  0.65   0.37
+ -0.25   0.13
+ -0.61   0.40
+ -0.54   0.29
+  0.98   1.38
+ -0.16   0.43
+  0.66   0.41
+ -0.27   0.25
+  0.40   0.76
+  0.97   1.05
+  0.81   1.14
+ -0.67   0.26
+ -0.39   0.49
+  0.57   0.71
+  0.84   0.65
+  0.42   0.81
+ -0.73   0.85
+  0.54  -0.01
+  0.82   0.47
+ -0.20   0.51
+  0.15   0.16
+  0.79   1.09
+ -0.22   0.19
+ -0.78   0.89
+ -0.51   0.16
+  0.69   0.56
+ -0.87   0.79
+ -0.95   1.23
+  0.02  -0.14
+ -0.47   0.50
+  0.82   0.83
+ -0.25   0.08
+ -0.14   0.42
+  0.20   0.55
+  0.97   1.04
+  0.30   0.44
+ -0.66   0.85
+ -0.02  -0.34
+  0.02   0.34
+  0.27  -0.23
+  0.51   0.26
+ -0.00  -0.15
+  0.70   0.80
+ -0.74   0.83
+  0.05  -0.09
+ -0.97   0.64
+  0.98   1.12
+  0.92   0.76
+ -0.43   0.58
+  0.74   0.87
+  0.42   0.74
+ -0.00  -0.27
+ -0.78   0.59
+ -0.15   0.24
+  0.19  -0.09
+ -0.57   0.40
+ -0.45   0.43
+ -0.46   0.39
+ -0.63   0.83
+ -0.50   0.32
+  0.46   0.59
+ -0.96   0.81
+ -0.69   0.45
+ -0.51   0.93
+  0.35   0.33
+ -0.17   0.13
+ -0.70   0.54
+ -0.17   0.07
+  0.32   0.59
+ -0.01  -0.17
+ -0.77   0.55
+ -0.35   0.25
+ -0.19  -0.20
+ -0.08   0.16
+  0.77   0.60
+  0.52   1.07
+  0.41   0.62
+  0.09  -0.35
+  0.24   0.74
+ -0.64   0.65
+  0.96   0.80
+  0.28   0.09
+  0.51   0.54
+ -0.79   0.77
+ -0.73   0.96
+ -0.57   0.59
+ -0.75   0.78
+ -0.44   0.13
+  0.61   0.40
+ -0.24   0.13
+  0.64   1.05
+ -0.48   0.04
+ -0.87   0.61
+ -0.34   0.23
+  0.23   0.17
+ -0.67   0.58
+  0.33  -0.01
+ -0.86   1.48
+  0.71   0.97
+  0.16  -0.33
+ -0.49   0.46
+  0.21   0.66
+  0.46   0.58
+  0.99   1.08
+ -0.36   0.49
+  0.09  -0.12
+ -0.10  -0.35
+  0.33   0.52
+ -0.97   1.56
+ -0.53   0.17
+  0.31   0.38
+  0.71   0.85
+ -0.56   0.81
+  0.74   0.77
+  0.48   0.65
+  0.65   1.18
+  0.70   0.73
+ -0.97   0.62
+  0.75   0.32
+  0.76   0.57
+  0.32   0.49
+  0.46   0.62
+  0.95   1.14
+  0.84   0.74
+ -0.78   0.37
+  0.19   0.44
+  0.39   0.44
+  0.16   0.04
+ -0.88   1.11
+ -0.62   0.78
+ -0.20   0.06
+ -0.73   0.87
+  0.49   0.56
+ -0.68   0.67
+  0.31  -0.22
+  0.99   0.74
+  0.50   0.35
+ -0.46   0.75
+ -0.50   0.53
+ -0.02   0.03
+ -0.42   0.23
+  0.91   0.59
+ -0.12   0.03
+ -0.57   0.73
+  0.67   0.50
+ -0.52   0.32
+ -0.35   0.15
+ -0.07   0.01
+ -0.02   0.22
+  0.23   0.29
+ -0.10  -0.44
+ -0.22   0.24
+ -0.34  -0.07
+  0.43   0.51
+  0.94   1.08
+ -0.80   1.10
+  0.31   0.21
+  0.82   0.78
+ -0.19   0.14
+ -0.07   0.07
+ -0.86   0.83
+  0.97   0.99
+ -0.18   0.11
+ -0.49   0.18
+ -0.88   0.69
+ -0.13  -0.01
+ -0.29   0.19
+  0.58   0.37
+ -0.64   0.28
+ -0.49   0.44
+ -0.85   0.72
+  0.73   0.74
+  0.43   0.32
+ -0.36   0.44
+  0.30   0.08
+ -0.58   0.28
+ -0.40   0.40
+ -0.69   0.99
+ -0.54   0.30
+ -0.04   0.03
+  0.13   0.33
+  0.10   0.02
+  0.20   0.42
+  0.97   0.93
+ -0.98   1.33
+ -0.60   0.05
+ -0.11  -0.23
+ -0.82   0.75
+ -0.35   0.47
+  0.14   0.11
+  0.87   1.13
+ -0.34   0.66
+ -0.84   1.18
+ -0.82   1.03
+ -0.53   0.61
+  0.60   0.40
+  0.90   1.08
+ -0.56   0.73
+  0.89   0.47
+ -0.72   0.70
+  0.15   0.24
+  0.95   1.05
+  0.63   0.36
+ -0.76   0.64
+  0.38   0.53
+  0.55   0.62
+  0.42   0.35
+ -0.91   0.88
+ -0.93   0.94
+ -0.64   0.18
+ -0.99   1.08
+ -0.71   1.04
+  0.64   0.13
+ -0.48   0.51
+ -0.10  -0.10
+  0.67   0.86
+ -0.83   0.69
+ -0.25   0.18
+ -0.07   0.17
+  0.13   0.11
+  0.77   1.05
+  0.01   0.34
+ -0.12   0.02
+  0.50   0.62
+ -0.07  -0.19
+  0.76   1.08
+ -0.68   0.23
+  0.18   0.01
+ -0.55   1.31
+  0.68   0.83
+ -0.08   0.12
+  0.31   0.53
+  0.35   0.29
+ -0.61   0.51
+ -0.18   0.25
+  0.50   0.58
+ -0.36   0.33
+  0.46  -0.02
+  0.72   0.96
+ -0.56   0.41
+  0.73   0.96
+ -0.14  -0.15
+  0.08   0.08
+  0.76   0.62
+  0.15  -0.25
+  0.23   0.13
+ -0.12   0.11
+  0.12  -0.57
+ -0.24   0.44
+ -0.63   0.67
+ -0.44   0.31
+  0.84   0.99
+ -0.74   0.56
+ -0.74   0.51
+  0.25   0.20
+  0.76   0.88
+  0.44   0.49
+  0.32   0.42
+ -0.44   0.87
+  0.33   0.62
+ -0.76   1.23
+  0.74   1.40
+  0.81   0.39
+ -0.40   0.23
+  0.16   0.15
+ -0.54   0.92
+ -0.44   0.64
+  0.85   1.25
+  0.27   0.41
+ -0.94   0.76
+  0.65   0.56
+  0.87   0.82
+ -0.04  -0.10
+ -0.43   0.35
+ -0.78   0.77
+ -0.80   0.54
+ -0.04   0.23
+  0.21   0.30
+  0.71   0.64
+  0.51   0.43
+ -0.38   0.33
+ -0.32   0.37
+  0.77   0.95
+ -0.91   0.89
+  0.79   0.70
+ -0.94   0.78
+ -0.05  -0.18
+  0.85   0.98
+ -0.33   0.61
+ -0.51   0.82
+ -0.63   0.47
+ -0.77   0.40
+ -0.56   0.89
+  0.67   0.68
+ -0.87   1.17
+ -0.25   0.43
+  0.17   0.44
+ -0.13   0.20
+ -0.01  -0.14
+  0.87  -0.02
+  0.22   0.05
+ -0.77   0.75
+ -0.73   0.38
+  0.68   0.53
+ -0.69   0.55
+ -0.17   0.28
+ -0.42   0.40
+ -0.53   1.08
+ -0.46   0.66
+  0.89   0.73
+ -0.15  -0.02
+  0.30   0.44
+  0.42   0.43
+  0.68   0.87
+ -0.66   0.84
+ -0.18  -0.03
+ -0.86   0.96
+ -0.93   1.08
+ -0.34   0.05
+  0.42   0.40
+ -0.36   0.34
+ -0.44  -0.30
+  0.80   0.66
+ -0.01   0.24
+ -0.40  -0.03
+ -0.47   0.46
+ -0.15   0.07
+ -0.41  -0.54
+  0.25  -0.16
+  0.86   0.92
+  0.35   0.51
+  0.90   1.17
+ -0.82   0.74
+ -0.90   1.10
+  0.88   1.01
+  0.95   0.89
+  0.01   0.23
+  0.54   0.70
+ -0.37   0.33
+ -0.12  -0.71
+ -0.47   0.88
+  0.24   0.47
+ -0.17   0.35
+  0.68   0.56
+ -0.93   0.82
+  0.60   0.86
+  0.49   0.86
+  0.78   0.81
+ -0.01   0.26
+ -0.96   1.34
+ -0.71   0.96
+  0.17   0.37
+ -0.94   0.53
+ -0.42   0.77
+  0.12  -0.05
+  0.84   0.87
+ -0.57   0.48
+ -0.54   0.51
+ -0.98   0.56
+ -0.07  -0.16
+ -0.49   0.47
+ -0.08   0.28
+ -0.59   0.89
+  0.32   0.11
+ -0.59   0.63
+  0.08   0.34
+  0.24   0.21
+ -0.35   0.52
+ -0.18  -0.07
+  0.70   0.56
+ -0.05   0.24
+ -0.13  -0.36
+  0.24   0.14
+  0.54   0.55
+  0.17  -0.32
+ -0.36   0.61
+ -0.64   0.70
+  0.92   1.14
+  0.35   0.29
+ -0.47   0.70
+ -0.96   0.97
+  0.79   0.53
+  0.54   0.32
+ -0.19   0.41
+ -0.41   0.57
+  0.77   0.79
+ -0.53   0.53
+ -0.90   0.85
+  0.54   0.38
+ -0.42   0.77
+  0.02   0.19
+ -0.68   0.34
+ -0.87   0.48
+ -0.37   0.60
+ -0.46   0.47
+  0.08  -0.01
+  0.51   0.64
+ -0.53   0.06
+  0.87   0.82
+ -0.25   0.41
+ -0.46  -0.06
+  0.33   0.36
+ -0.05   0.01
+ -1.00   0.66
+ -0.42   0.10
+  0.08   0.53
+ -0.98   0.72
+  0.24   0.41
+  0.18   0.36
+ -0.24   0.62
+  0.56   0.35
+  0.39   0.18
+  0.76   0.27
+  1.00   0.68
+ -0.52   0.39
+ -0.66   0.75
+  0.53   0.67
+  0.77   0.62
+  0.84   0.70
+  0.07  -0.28
+ -0.67   0.86
+ -0.75   0.92
+  0.42   0.48
+ -0.32   0.59
+  0.39   0.43
+  0.79   1.31
+  0.34   0.43
+  0.48   0.86
+ -0.50   0.81
+  0.94   1.67
+  0.66   0.02
+ -0.28   0.02
+  0.89   1.28
+ -0.74   1.16
+  0.81   0.75
+  0.96   0.12
+ -0.63   0.53
+ -0.86   1.20
+  0.61   0.56
+  0.53   0.95
+  0.20   0.50
+ -0.07  -0.15
+  0.28  -0.11
+ -0.23   0.47
+  0.02   0.29
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Misc/mixexp_graddesc.m b/sourcecodes/bnt-master/BNT/examples/static/Misc/mixexp_graddesc.m
new file mode 100644
index 00000000..534d9e58
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Misc/mixexp_graddesc.m
@@ -0,0 +1,51 @@
+
+%%%%%%%%%%
+
+function [theta, eta] = mixture_of_experts(q, data, num_iter, theta, eta)
+% MIXTURE_OF_EXPERTS Fit a piecewise linear regression model using stochastic gradient descent.
+% [theta, eta] = mixture_of_experts(q, data, num_iter)
+%
+% Inputs:
+% q = number of pieces (experts)
+% data(l,:) = input example l 
+% 
+% Outputs:
+% theta(i,:) = regression vector for expert i
+% eta(i,:) = softmax (gating) params for expert i
+
+[num_cases dim] = size(data);
+data = [ones(num_cases,1) data]; % prepend with offset
+mu = 0.5; % step size
+sigma = 1; % variance of noise
+
+if nargin < 4
+  theta = 0.1*rand(q, dim);
+  eta = 0.1*rand(q, dim);
+end
+
+for t=1:num_iter
+  for iter=1:num_cases
+    x = data(iter, 1:dim);
+    ystar = data(iter, dim+1); % target
+    % yhat(i) = E[y | Q=i, x] = prediction of i'th expert
+    yhat = theta * x'; 
+    % gate_prior(i,:) = Pr(Q=i | x)
+    gate_prior = exp(eta * x');
+    gate_prior = gate_prior / sum(gate_prior);
+    % lik(i) = Pr(y | Q=i, x)
+    lik = (1/(sqrt(2*pi)*sigma)) * exp(-(0.5/sigma^2) * ((ystar - yhat) .* (ystar - yhat)));
+    % gate_posterior(i,:) = Pr(Q=i | x, y)
+    gate_posterior = gate_prior .* lik;
+    gate_posterior = gate_posterior / sum(gate_posterior);
+    % Update
+    eta = eta + mu*(gate_posterior - gate_prior)*x;
+    theta = theta + mu*(gate_posterior .* (ystar - yhat))*x;
+  end
+
+  if mod(t,100)==0
+    fprintf(1, 'iter %d\n', t);
+  end
+
+end
+fprintf(1, '\n');
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Misc/mixexp_plot.m b/sourcecodes/bnt-master/BNT/examples/static/Misc/mixexp_plot.m
new file mode 100644
index 00000000..bb2a2fec
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Misc/mixexp_plot.m
@@ -0,0 +1,49 @@
+function plot_mixexp(theta, eta, data)
+% PLOT_MIXEXP  Plot the results for a piecewise linear regression model
+% plot_mixexp(theta, eta, data)
+% 
+% data(l,:) = [x y] for example l
+% theta(i,:) = regression vector for expert i
+% eta(i,:) = softmax (gating) params for expert i
+
+numexp = size(theta, 1);
+
+mn = min(data);
+mx = max(data);
+xa = mn(1):0.01:mx(1);
+x = [ones(length(xa),1) xa'];
+% pr(i,l) = posterior probability of expert i on example l
+pr = exp(eta * x');
+pr = pr ./ (ones(numexp,1) * sum(pr));
+% y(i,l) = prediction of expert i for example l
+y = theta * x';
+% yg(l) = weighted prediction  for example l
+yg = sum(y .* pr)';
+
+subplot(3,2,1);
+plot(xa, y(1,:));
+title('expert 1');
+
+subplot(3,2,2);
+plot(xa, y(2,:));
+title('expert 2');
+
+subplot(3,2,3);
+plot(xa, pr(1,:));
+title('gating 1');
+
+subplot(3,2,4);
+plot(xa, pr(2,:));
+title('gating 2');
+
+subplot(3,2,5);
+plot(xa, yg);
+axis([-1 1 -1 2])
+title('prediction');
+
+subplot(3,2,6);
+title('data');
+hold on
+plot(data(:,1), data(:,2), '+');
+hold off
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Misc/sprinkler.bif b/sourcecodes/bnt-master/BNT/examples/static/Misc/sprinkler.bif
new file mode 100644
index 00000000..8925e79c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Misc/sprinkler.bif
@@ -0,0 +1,18 @@
+network Grass
+    {}
+variable Cloudy
+    { type discrete[2] {false true}; }
+variable Sprinkler
+    { type discrete[2] {false true}; }
+variable Rain
+    { type discrete[2] {false true}; }
+variable WetGrass
+    { type discrete[2] {false true}; }
+probability (Cloudy)
+    { table 0.5 0.5; }
+probability (Sprinkler | Cloudy)
+    { table 0.5 0.9 0.5 0.1; }
+probability (Rain | Cloudy)
+    { table 0.8 0.2 0.2 0.8; }
+probability (WetGrass | Rain Sprinkler)
+    { table 1.0 0.1 0.1 0.01 0.0 0.9 0.9 0.99; }
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/static/Models/CVS/Entries
new file mode 100644
index 00000000..398be87c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/CVS/Entries
@@ -0,0 +1,12 @@
+/mk_alarm_bnet.m/1.1.1.1/Sun Nov  3 16:44:14 2002//
+/mk_asia_bnet.m/1.1.1.1/Wed Mar 26 00:06:42 2003//
+/mk_cancer_bnet.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_car_bnet.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_hmm_bnet.m/1.1.1.1/Thu Jan 15 01:06:12 2004//
+/mk_ideker_bnet.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_incinerator_bnet.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_markov_chain_bnet.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_minimal_qmr_bnet.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_qmr_bnet.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_vstruct_bnet.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D/Old////
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/static/Models/CVS/Repository
new file mode 100644
index 00000000..2218a7f5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/static/Models
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/CVS/Root b/sourcecodes/bnt-master/BNT/examples/static/Models/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/static/Models/Old/CVS/Entries
new file mode 100644
index 00000000..c7e92b5c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/Old/CVS/Entries
@@ -0,0 +1,2 @@
+/mk_hmm_bnet.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/static/Models/Old/CVS/Repository
new file mode 100644
index 00000000..fdee291b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/static/Models/Old
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/Old/CVS/Root b/sourcecodes/bnt-master/BNT/examples/static/Models/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/Old/mk_hmm_bnet.m b/sourcecodes/bnt-master/BNT/examples/static/Models/Old/mk_hmm_bnet.m
new file mode 100644
index 00000000..1179c6d8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/Old/mk_hmm_bnet.m
@@ -0,0 +1,58 @@
+function [bnet, onodes] = mk_hmm_bnet(T, Q, O, cts_obs, param_tying)
+% MK_HMM_BNET Make a (static( bnet to represent a hidden Markov model
+% [bnet, onodes] = mk_hmm_bnet(T, Q, O, cts_obs, param_tying)
+%
+% T = num time slices
+% Q = num hidden states
+% O = size of the observed node (num discrete values or length of vector)
+% cts_obs - 1 means the observed node is a continuous-valued vector, 0 means it's discrete
+% param_tying - 1 means we create 3 CPDs, 0 means we create 1 CPD per node
+
+N = 2*T;
+dag = zeros(N);
+for i=1:T-1
+  dag(i,i+1)=1;
+end
+onodes = T+1:N;
+for i=1:T
+  dag(i, onodes(i)) = 1;
+end
+
+if cts_obs
+  dnodes = 1:T;
+else
+  dnodes = 1:N;
+end
+ns = [Q*ones(1,T) O*ones(1,T)];
+
+if param_tying
+  eclass = [1 2*ones(1,T-1) 3*ones(1,T)];
+else
+  eclass = 1:N;
+end
+
+bnet = mk_bnet(dag, ns, dnodes, eclass);
+
+hnodes = mysetdiff(1:N, onodes);
+if ~param_tying
+  for i=hnodes(:)'
+    bnet.CPD{i} = tabular_CPD(bnet, i);
+  end
+  if cts_obs
+    for i=onodes(:)'
+      bnet.CPD{i} = gaussian_CPD(bnet, i);
+    end
+  else
+    for i=onodes(:)'
+      bnet.CPD{i} = tabular_CPD(bnet, i);
+    end
+  end
+else
+  bnet.CPD{1} = tabular_CPD(bnet, 1);
+  bnet.CPD{2} = tabular_CPD(bnet, 2);
+  if cts_obs
+    bnet.CPD{3} = gaussian_CPD(bnet, 3);
+  else
+    bnet.CPD{3} = tabular_CPD(bnet, 3);
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/mk_alarm_bnet.m b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_alarm_bnet.m
new file mode 100644
index 00000000..5705909b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_alarm_bnet.m
@@ -0,0 +1,118 @@
+function bnet = mk_alarm_bnet()
+
+% Written by Qian Diao <qian.diao@intel.com> on 11 Dec 01
+
+N = 37;
+dag = zeros(N,N);
+dag(21,23) = 1 ;
+dag(21,24) = 1 ;
+dag(1,24) = 1 ;
+dag(1,23) = 1 ;
+dag(2,26) = 1 ;
+dag(2,25) = 1 ;
+dag(2,24) = 1 ;
+dag(2,13) = 1 ;
+dag(2,23) = 1 ;
+dag(13,30) = 1 ;
+dag(30,31) = 1 ;
+dag(3,14) = 1 ;
+dag(3,19) = 1 ;
+dag(4,36) = 1 ;
+dag(14,35) = 1 ;
+dag(32,33) = 1 ;
+dag(32,35) = 1 ;
+dag(32,34) = 1 ;
+dag(32,36) = 1 ;
+dag(15,21) = 1 ;
+dag(5,31) = 1 ;
+dag(27,30) = 1 ;
+dag(28,31) = 1 ;
+dag(28,29) = 1 ;
+dag(26,28) = 1 ;
+dag(26,27) = 1 ;
+dag(16,31) = 1 ;
+dag(16,37) = 1 ;
+dag(23,26) = 1 ;
+dag(23,29) = 1 ;
+dag(23,25) = 1 ;
+dag(6,15) = 1 ;
+dag(7,27) = 1 ;
+dag(8,21) = 1 ;
+dag(19,20) = 1 ;
+dag(19,22) = 1 ;
+dag(31,32) = 1 ;
+dag(9,14) = 1 ;
+dag(9,17) = 1 ;
+dag(9,19) = 1 ;
+dag(10,33) = 1 ;
+dag(10,34) = 1 ;
+dag(11,16) = 1 ;
+dag(12,13) = 1 ;
+dag(12,18) = 1 ;
+dag(35,37) = 1 ;
+
+node_sizes = 2*ones(1,N);
+node_sizes(2) = 3;
+node_sizes(6) = 3;
+node_sizes(14) = 3;
+node_sizes(15) = 4;
+node_sizes(16) = 3;
+node_sizes(18) = 3;
+node_sizes(19) = 3;
+node_sizes(20) = 3;
+node_sizes(21) = 4;
+node_sizes(22) = 3;
+node_sizes(23) = 4;
+node_sizes(24) = 4;
+node_sizes(25) = 4;
+node_sizes(26) = 4;
+node_sizes(27) = 3;
+node_sizes(28) = 3;
+node_sizes(29) = 4;
+node_sizes(30) = 3;
+node_sizes(32) = 3;
+node_sizes(33) = 3;
+node_sizes(34) = 3;
+node_sizes(35) = 3;
+node_sizes(36) = 3;
+node_sizes(37) = 3;
+
+bnet = mk_bnet(dag, node_sizes);
+
+bnet.CPD{1} = tabular_CPD(bnet, 1,[0.96 0.04 ]);
+bnet.CPD{2} = tabular_CPD(bnet, 2,[0.92 0.03 0.05 ]);
+bnet.CPD{3} = tabular_CPD(bnet, 3,[0.8 0.2 ]);
+bnet.CPD{4} = tabular_CPD(bnet, 4,[0.95 0.05 ]);
+bnet.CPD{5} = tabular_CPD(bnet, 5,[0.8 0.2 ]);
+bnet.CPD{6} = tabular_CPD(bnet, 6,[0.01 0.98 0.01 ]);
+bnet.CPD{7} = tabular_CPD(bnet, 7,[0.01 0.99 ]);
+bnet.CPD{8} = tabular_CPD(bnet, 8,[0.95 0.05 ]);
+bnet.CPD{9} = tabular_CPD(bnet, 9,[0.95 0.05 ]);
+bnet.CPD{10} = tabular_CPD(bnet, 10,[0.9 0.1 ]);
+bnet.CPD{11} = tabular_CPD(bnet, 11,[0.99 0.01 ]);
+bnet.CPD{12} = tabular_CPD(bnet, 12,[0.99 0.01 ]);
+bnet.CPD{13} = tabular_CPD(bnet, 13,[0.95 0.95 0.05 0.1 0.1 0.01 0.05 0.05 0.95 0.9 0.9 0.99 ]);
+bnet.CPD{14} = tabular_CPD(bnet, 14,[0.05 0.95 0.5 0.98 0.9 0.04 0.49 0.01 0.05 0.01 0.01 0.01 ]);
+bnet.CPD{15} = tabular_CPD(bnet, 15,[0.01 0.01 0.01 0.97 0.01 0.01 0.01 0.97 0.01 0.01 0.01 0.97 ]);
+bnet.CPD{16} = tabular_CPD(bnet, 16,[0.3 0.98 0.4 0.01 0.3 0.01 ]);
+bnet.CPD{17} = tabular_CPD(bnet, 17,[0.99 0.1 0.01 0.9 ]);
+bnet.CPD{18} = tabular_CPD(bnet, 18,[0.05 0.01 0.9 0.19 0.05 0.8 ]);
+bnet.CPD{19} = tabular_CPD(bnet, 19,[0.05 0.98 0.01 0.95 0.9 0.01 0.09 0.04 0.05 0.01 0.9 0.01 ]);
+bnet.CPD{20} = tabular_CPD(bnet, 20,[0.95 0.04 0.01 0.04 0.95 0.29 0.01 0.01 0.7 ]);
+bnet.CPD{21} = tabular_CPD(bnet, 21,[0.97 0.97 0.01 0.97 0.01 0.97 0.01 0.97 0.01 0.01 0.97 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.97 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.97 0.01 ]);
+bnet.CPD{22} = tabular_CPD(bnet, 22,[0.95 0.04 0.01 0.04 0.95 0.04 0.01 0.01 0.95 ]);
+bnet.CPD{23} = tabular_CPD(bnet, 23,[0.97 0.97 0.97 0.97 0.97 0.97 0.01 0.95 0.97 0.97 0.01 0.95 0.01 0.4 0.97 0.97 0.01 0.5 0.01 0.3 0.97 0.97 0.01 0.3 0.01 0.01 0.01 0.01 0.01 0.01 0.97 0.03 0.01 0.01 0.97 0.03 0.01 0.58 0.01 0.01 0.01 0.48 0.01 0.68 0.01 0.01 0.01 0.68 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.97 0.01 0.01 0.01 0.97 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.97 0.01 0.01 0.01 0.97 0.01 ]);
+bnet.CPD{24} = tabular_CPD(bnet, 24,[0.97 0.97 0.97 0.97 0.97 0.97 0.01 0.01 0.4 0.1 0.01 0.01 0.01 0.01 0.2 0.05 0.01 0.01 0.01 0.01 0.2 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.97 0.49 0.58 0.84 0.9 0.29 0.01 0.01 0.75 0.25 0.01 0.01 0.01 0.01 0.7 0.15 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.3 0.01 0.05 0.08 0.3 0.97 0.08 0.04 0.25 0.38 0.08 0.01 0.01 0.09 0.25 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.2 0.01 0.01 0.01 0.4 0.01 0.9 0.01 0.45 0.6 0.9 0.97 0.97 0.01 0.59 0.97 0.97 ]);
+bnet.CPD{25} = tabular_CPD(bnet, 25,[0.97 0.97 0.97 0.01 0.6 0.01 0.01 0.5 0.01 0.01 0.5 0.01 0.01 0.01 0.01 0.97 0.38 0.97 0.01 0.48 0.01 0.01 0.48 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.97 0.01 0.97 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.97 0.01 0.97 ]);
+bnet.CPD{26} = tabular_CPD(bnet, 26,[0.97 0.97 0.97 0.01 0.01 0.03 0.01 0.01 0.01 0.97 0.01 0.01 0.01 0.01 0.01 0.97 0.97 0.95 0.01 0.01 0.94 0.01 0.01 0.88 0.01 0.01 0.01 0.01 0.01 0.01 0.97 0.97 0.04 0.01 0.01 0.1 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.97 0.97 0.01 ]);
+bnet.CPD{27} = tabular_CPD(bnet, 27,[0.98 0.98 0.98 0.98 0.95 0.01 0.95 0.01 0.01 0.01 0.01 0.01 0.04 0.95 0.04 0.01 0.01 0.01 0.01 0.01 0.01 0.04 0.01 0.98 ]);
+bnet.CPD{28} = tabular_CPD(bnet, 28,[0.01 0.01 0.04 0.9 0.01 0.01 0.92 0.09 0.98 0.98 0.04 0.01 ]);
+bnet.CPD{29} = tabular_CPD(bnet, 29,[0.97 0.01 0.01 0.01 0.97 0.01 0.01 0.01 0.97 0.01 0.01 0.01 0.01 0.97 0.97 0.97 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.97 0.97 0.97 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.97 0.97 0.43 ]);
+bnet.CPD{30} = tabular_CPD(bnet, 30,[0.98 0.98 0.01 0.98 0.01 0.69 0.01 0.01 0.98 0.01 0.01 0.3 0.01 0.01 0.01 0.01 0.98 0.01 ]);
+bnet.CPD{31} = tabular_CPD(bnet, 31,[0.05 0.01 0.05 0.01 0.05 0.01 0.05 0.01 0.05 0.01 0.05 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.1 0.01 0.95 0.01 0.95 0.05 0.1 0.01 0.95 0.01 0.95 0.05 0.1 0.01 0.3 0.01 0.3 0.01 0.95 0.01 0.99 0.05 0.95 0.05 0.95 0.01 0.99 0.05 0.99 0.05 0.3 0.01 0.99 0.01 0.3 0.01 0.95 0.99 0.95 0.99 0.95 0.99 0.95 0.99 0.95 0.99 0.95 0.99 0.99 0.99 0.99 0.99 0.99 0.99 0.9 0.99 0.05 0.99 0.05 0.95 0.9 0.99 0.05 0.99 0.05 0.95 0.9 0.99 0.7 0.99 0.7 0.99 0.05 0.99 0.00999999 0.95 0.05 0.95 0.05 0.99 0.01 0.95 0.01 0.95 0.7 0.99 0.01 0.99 0.7 0.99 ]);
+bnet.CPD{32} = tabular_CPD(bnet, 32,[0.1 0.01 0.89 0.09 0.01 0.9 ]);
+bnet.CPD{33} = tabular_CPD(bnet, 33,[0.98 0.33333334 0.01 0.33333334 0.01 0.33333334 0.01 0.33333334 0.98 0.33333334 0.01 0.33333334 0.01 0.33333334 0.01 0.33333334 0.98 0.33333334 ]);
+bnet.CPD{34} = tabular_CPD(bnet, 34,[0.98 0.33333334 0.01 0.33333334 0.01 0.33333334 0.01 0.33333334 0.98 0.33333334 0.01 0.33333334 0.01 0.33333334 0.01 0.33333334 0.98 0.33333334 ]);
+bnet.CPD{35} = tabular_CPD(bnet, 35,[0.98 0.95 0.3 0.95 0.04 0.01 0.8 0.01 0.01 0.01 0.04 0.69 0.04 0.95 0.3 0.19 0.04 0.01 0.01 0.01 0.01 0.01 0.01 0.69 0.01 0.95 0.98 ]);
+bnet.CPD{36} = tabular_CPD(bnet, 36,[0.98 0.98 0.01 0.4 0.01 0.3 0.01 0.01 0.98 0.59 0.01 0.4 0.01 0.01 0.01 0.01 0.98 0.3 ]);
+bnet.CPD{37} = tabular_CPD(bnet, 37,[0.98 0.98 0.3 0.98 0.1 0.05 0.9 0.05 0.01 0.01 0.01 0.6 0.01 0.85 0.4 0.09 0.2 0.09 0.01 0.01 0.1 0.01 0.05 0.55 0.01 0.75 0.9 ]);
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/mk_asia_bnet.m b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_asia_bnet.m
new file mode 100644
index 00000000..fce24c3a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_asia_bnet.m
@@ -0,0 +1,76 @@
+function bnet = mk_asia_bnet(CPD_type, p, arity)
+% MK_ASIA_BNET Make the 'Asia' bayes net.
+%
+% BNET = MK_ASIA_BNET uses the parameters specified on p21 of Cowell et al, 
+% "Probabilistic networks and expert systems", Springer Verlag 1999.
+% 
+% BNET = MK_ASIA_BNET('cpt', p) uses random parameters drawn from a Dirichlet(p,p,...)
+% distribution. If p << 1, this is nearly deterministic; if p >> 1, this is nearly uniform.
+% 
+% BNET = MK_ASIA_BNET('bool') makes each CPT a random boolean function.
+%
+% BNET = MK_ASIA_BNET('gauss') makes each CPT a random linear Gaussian distribution.
+%
+% BNET = MK_ASIA_BNET('orig') is the same as MK_ASIA_BNET.
+%
+% BNET = MK_ASIA_BNET('cpt', p, arity) can specify non-binary nodes.
+
+
+if nargin == 0, CPD_type = 'orig'; end
+if nargin < 3, arity = 2; end
+
+Smoking = 1;
+Bronchitis = 2;
+LungCancer = 3;
+VisitToAsia = 4;
+TB = 5;
+TBorCancer = 6;
+Dys = 7;
+Xray = 8;
+
+n = 8;
+dag = zeros(n);
+dag(Smoking, [Bronchitis LungCancer]) = 1;
+dag(Bronchitis, Dys) = 1;
+dag(LungCancer, TBorCancer) = 1;
+dag(VisitToAsia, TB) = 1;
+dag(TB, TBorCancer) = 1;
+dag(TBorCancer, [Dys Xray]) = 1;
+
+ns = arity*ones(1,n);
+if strcmp(CPD_type, 'gauss')
+  dnodes = [];
+else
+  dnodes = 1:n;
+end
+bnet = mk_bnet(dag, ns, 'discrete', dnodes);
+
+switch CPD_type
+  case 'orig', 
+    % true is 2, false is 1
+    bnet.CPD{VisitToAsia} = tabular_CPD(bnet, VisitToAsia, [0.99   0.01]);
+    bnet.CPD{Bronchitis} = tabular_CPD(bnet, Bronchitis, [0.7 0.4   0.3 0.6]);
+    % minka: bug fix
+    bnet.CPD{Dys} = tabular_CPD(bnet, Dys, [0.9 0.2 0.3 0.1   0.1 0.8 0.7 0.9]);
+    bnet.CPD{TBorCancer} = tabular_CPD(bnet, TBorCancer, [1 0 0 0   0 1 1 1]);
+    % minka: bug fix
+    bnet.CPD{LungCancer} = tabular_CPD(bnet, LungCancer, [0.99 0.9  0.01 0.1]);
+    bnet.CPD{Smoking} = tabular_CPD(bnet, Smoking, [0.5 0.5]);
+    bnet.CPD{TB} = tabular_CPD(bnet, TB, [0.99 0.95  0.01 0.05]);
+    bnet.CPD{Xray} = tabular_CPD(bnet, Xray, [0.95 0.02  0.05 0.98]);
+ case 'bool',
+  for i=1:n
+    bnet.CPD{i} = boolean_CPD(bnet, i, 'rnd');
+  end
+ case 'gauss',
+  for i=1:n
+    bnet.CPD{i} = gaussian_CPD(bnet, i, 'cov', 1*eye(ns(i)));
+  end
+ case 'cpt',
+  for i=1:n
+    bnet.CPD{i} = tabular_CPD(bnet, i, p);
+  end
+end
+
+  
+  
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/mk_cancer_bnet.m b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_cancer_bnet.m
new file mode 100644
index 00000000..c54cbfad
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_cancer_bnet.m
@@ -0,0 +1,61 @@
+function bnet = mk_cancer_bnet(CPD_type, p)
+% MK_CANCER_BNET Make the 'Cancer' Bayes net.
+%
+% BNET = MK_CANCER_BNET uses the noisy-or parameters specified in Fig 4a of the UAI98 paper by
+% Friedman, Murphy and Russell, "Learning the Structure of DPNs", p145.
+%
+% BNET = MK_CANCER_BNET('noisyor', p) makes each CPD a noisy-or, with probability p of
+% suppression for each parent; leaks are turned off.
+%
+% BNET = MK_CANCER_BNET('cpt', p) uses random CPT parameters drawn from a Dirichlet(p,p,...)
+% distribution. If p << 1, this is near deterministic; if p >> 1, this is near 1/k.
+% p defaults to 1.0 (uniform distribution).
+%
+% BNET = MK_CANCER_BNET('bool') makes each CPT a random boolean function.
+%
+% In all cases, the root is set to a uniform distribution.
+
+if nargin == 0
+  rnd = 0;
+else
+  rnd = 1;
+end
+
+n = 5;
+dag = zeros(n);
+dag(1,[2 3]) = 1;
+dag(2,4) = 1;
+dag(3,4) = 1;
+dag(4,5) = 1;
+
+ns = 2*ones(1,n);
+bnet = mk_bnet(dag, ns);
+    
+if ~rnd
+  bnet.CPD{1} = tabular_CPD(bnet, 1, [0.5 0.5]);
+  bnet.CPD{2} = noisyor_CPD(bnet, 2, 1.0, 1-0.9);
+  bnet.CPD{3} = noisyor_CPD(bnet, 3, 1.0, 1-0.2);
+  bnet.CPD{4} = noisyor_CPD(bnet, 4, 1.0, 1-[0.7 0.6]);
+  bnet.CPD{5} = noisyor_CPD(bnet, 5, 1.0, 1-0.5);
+else
+  switch CPD_type
+   case 'noisyor',
+    for i=1:n
+      ps = parents(dag, i);
+      bnet.CPD{i} = noisyor_CPD(bnet, i, 1.0, p*ones(1,length(ps)));
+    end
+   case 'bool',
+    for i=1:n
+      bnet.CPD{i} = boolean_CPD(bnet, i, 'rnd');
+    end
+   case 'cpt',
+    for i=1:n
+      bnet.CPD{i} = tabular_CPD(bnet, i, p);
+    end
+   otherwise
+    error(['bad CPD type ' CPD_type]);
+  end
+end
+  
+  
+  
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/mk_car_bnet.m b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_car_bnet.m
new file mode 100644
index 00000000..c9a27c9c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_car_bnet.m
@@ -0,0 +1,39 @@
+function bnet = mk_car_bnet()
+% MK_CAR_BNET Make the car trouble-shooter bayes net.
+%
+% This network is from p13 of "Troubleshooting under uncertainty", Heckerman, Breese and
+% Rommelse, Microsoft Research Tech Report 1994.
+
+
+BatteryAge = 1;
+Battery = 2;
+Starter = 3;
+Lights = 4;
+TurnsOver = 5;
+FuelPump = 6;
+FuelLine = 7;
+FuelSubsys =8;
+Fuel = 9;
+Spark = 10;
+Starts = 11;
+Gauge = 12;
+
+n = 12;
+dag = zeros(n);
+dag(1,2) = 1;
+dag(2,[4 5])=1;
+dag(3,5) = 1;
+dag(6,8) = 1;
+dag(7,8) = 1;
+dag(8,11) = 1;
+dag(9,12) = 1;
+dag(10,11) = 1;
+
+arity = 2;
+ns = arity*ones(1,n);
+bnet = mk_bnet(dag, ns);
+for i=1:n
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+end
+
+  
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/mk_hmm_bnet.m b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_hmm_bnet.m
new file mode 100644
index 00000000..6e2dbfba
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_hmm_bnet.m
@@ -0,0 +1,67 @@
+function bnet = mk_hmm_bnet(T, Q, O, cts_obs, param_tying)
+% MK_HMM_BNET Make a (static) bnet to represent a hidden Markov model
+% bnet = mk_hmm_bnet(T, Q, O, cts_obs, param_tying)
+%
+% T = num time slices
+% Q = num hidden states
+% O = size of the observed node (num discrete values or length of vector)
+% cts_obs - 1 means the observed node is a continuous-valued vector, 0 means it's discrete
+% param_tying - 1 means we create 3 CPDs, 0 means we create 1 CPD per node
+
+N = 2*T;
+dag = zeros(N);
+%hnodes = 1:2:2*T;
+hnodes = 1:T;
+for i=1:T-1
+  dag(hnodes(i), hnodes(i+1))=1;
+end
+%onodes = 2:2:2*T;
+onodes = T+1:2*T;
+for i=1:T
+  dag(hnodes(i), onodes(i)) = 1;
+end
+
+if cts_obs
+  dnodes = hnodes;
+else
+  dnodes = 1:N;
+end
+ns = ones(1,N);
+ns(hnodes) = Q;
+ns(onodes) = O;
+
+if param_tying
+  H1class = 1; Hclass = 2; Oclass = 3;
+  eclass = ones(1,N);
+  eclass(hnodes(2:end)) = Hclass;
+  eclass(hnodes(1)) = H1class;
+  eclass(onodes) = Oclass;
+else
+  eclass = 1:N;
+end
+
+bnet = mk_bnet(dag, ns, 'observed', onodes, 'discrete', dnodes, 'equiv_class', eclass);
+
+hnodes = mysetdiff(1:N, onodes);
+if ~param_tying
+  for i=hnodes(:)'
+    bnet.CPD{i} = tabular_CPD(bnet, i);
+  end
+  if cts_obs
+    for i=onodes(:)'
+      bnet.CPD{i} = gaussian_CPD(bnet, i);
+    end
+  else
+    for i=onodes(:)'
+      bnet.CPD{i} = tabular_CPD(bnet, i);
+    end
+  end
+else
+  bnet.CPD{H1class} = tabular_CPD(bnet, hnodes(1)); % prior
+  bnet.CPD{Hclass} = tabular_CPD(bnet, hnodes(2)); % transition matrix
+  if cts_obs
+    bnet.CPD{Oclass} = gaussian_CPD(bnet, onodes(1));
+  else
+    bnet.CPD{Oclass} = tabular_CPD(bnet, onodes(1));
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/mk_ideker_bnet.m b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_ideker_bnet.m
new file mode 100644
index 00000000..67f95bae
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_ideker_bnet.m
@@ -0,0 +1,52 @@
+function bnet = mk_ideker_bnet(CPD_type, p)
+% MK_IDEKER_BNET Make the Bayes net in the PSB'00 paper by Ideker, Thorsson and Karp.
+%
+% BNET = MK_IDEKER_BNET uses the boolean functions specified in the paper 
+% "Discovery of regulatory interactions through perturbation: inference and experimental design",
+% Pacific Symp. on Biocomputing, 2000.
+% 
+% BNET = MK_IDEKER_BNET('root') uses the above boolean functions, but puts a uniform
+% distribution on the root nodes.
+%
+% BNET = MK_IDEKER_BNET('cpt', p) uses random parameters drawn from a Dirichlet(p,p,...)
+% distribution. If p << 1, this is nearly deterministic; if p >> 1, this is nearly uniform.
+% 
+% BNET = MK_IDEKER_BNET('bool') makes each CPT a random boolean function.
+%
+% BNET = MK_IDEKER_BNET('orig') is the same as MK_IDEKER_BNET.
+
+
+if nargin == 0
+  CPD_type = 'orig';
+end
+
+n = 4;
+dag = zeros(n);
+dag(1,3)=1;
+dag(2,[3 4])=1;
+dag(3,4)=1;
+ns = 2*ones(1,n);
+bnet = mk_bnet(dag, ns);
+
+switch CPD_type
+ case 'orig',
+  bnet.CPD{1} = tabular_CPD(bnet, 1, [0 1]);
+  bnet.CPD{2} = tabular_CPD(bnet, 2, [0 1]);
+  bnet.CPD{3} = boolean_CPD(bnet, 3, 'inline', inline('x(1) & x(2)'));
+  bnet.CPD{4} = boolean_CPD(bnet, 4, 'inline', inline('x(1) & ~x(2)'));
+ case 'root',
+  bnet.CPD{1} = tabular_CPD(bnet, 1, [0.5 0.5]);
+  bnet.CPD{2} = tabular_CPD(bnet, 2, [0.5 0.5]);
+  bnet.CPD{3} = boolean_CPD(bnet, 3, 'inline', inline('x(1) & x(2)'));
+  bnet.CPD{4} = boolean_CPD(bnet, 4, 'inline', inline('x(1) & ~x(2)'));
+ case 'bool',
+  for i=1:n
+    bnet.CPD{i} = boolean_CPD(bnet, i, 'rnd');
+  end
+ case 'cpt',
+  for i=1:n
+    bnet.CPD{i} = tabular_CPD(bnet, i, p);
+  end
+ otherwise,
+  error(['unknown type ' CPD_type]);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/mk_incinerator_bnet.m b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_incinerator_bnet.m
new file mode 100644
index 00000000..1583ad17
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_incinerator_bnet.m
@@ -0,0 +1,61 @@
+function bnet  = mk_incinerator_bnet(ns)
+% MK_INCINERATOR_BNET The waste incinerator emissions example from Cowell et al p145
+% function bnet  = mk_incinerator_bnet(ns)
+% 
+% If ns is omitted, we use the scalars and binary nodes and the original params.
+% Otherwise, we use random params of the desired size.
+%
+% Lauritzen, "Propogation of Probabilities, Means and Variances in Mixed Graphical Association Models", 
+% JASA 87(420): 1098--1108
+% This example is reprinted on p145 of "Probabilistic Networks and Expert Systems",
+% Cowell, Dawid, Lauritzen and Spiegelhalter, 1999, Springer. 
+% For a picture, see http://www.cs.berkeley.edu/~murphyk/Bayes/usage.html#cg_model
+
+% node numbers
+F = 1; W = 2; E = 3; B = 4; C = 5; D = 6; Min = 7; Mout = 8; L = 9;
+names = {'F', 'W', 'E', 'B', 'C', 'D', 'Min', 'Mout', 'L'};
+n = 9;
+dnodes = [F W B];
+cnodes = mysetdiff(1:n, dnodes);
+
+% node sizes - all cts nodes are scalar, all discrete nodes are binary
+if nargin < 1
+  ns = ones(1, n);
+  ns(dnodes) = 2;
+  rnd = 0;
+else
+  rnd = 1;
+end
+  
+% topology (p 1099, fig 1)
+dag = zeros(n);
+dag(F,E)=1;
+dag(W,[E Min D]) = 1;
+dag(E,D)=1;
+dag(B,[C D])=1;
+dag(D,[L Mout])=1;
+dag(Min,Mout)=1;
+
+% params (p 1102)
+bnet = mk_bnet(dag, ns, 'discrete', dnodes, 'names', names);
+
+if rnd
+  for i=dnodes(:)'
+    bnet.CPD{i} = tabular_CPD(bnet, i);
+  end
+  for i=cnodes(:)'
+    bnet.CPD{i} = gaussian_CPD(bnet, i);
+  end
+else
+  bnet.CPD{B} = tabular_CPD(bnet, B, 'CPT', [0.85 0.15]); % 1=stable, 2=unstable
+  bnet.CPD{F} = tabular_CPD(bnet, F, 'CPT', [0.95 0.05]); % 1=intact, 2=defect
+  bnet.CPD{W} = tabular_CPD(bnet, W, 'CPT', [2/7 5/7]); % 1=industrial, 2=household
+  bnet.CPD{E} = gaussian_CPD(bnet, E, 'mean', [-3.9 -0.4 -3.2 -0.5], ...
+			     'cov', [0.00002 0.0001 0.00002 0.0001]);
+  bnet.CPD{D} = gaussian_CPD(bnet, D, 'mean', [6.5 6.0 7.5 7.0], ...
+			     'cov', [0.03 0.04 0.1 0.1], 'weights', [1 1 1 1]);
+  bnet.CPD{C} = gaussian_CPD(bnet, C, 'mean', [-2 -1], 'cov', [0.1 0.3]);
+  bnet.CPD{L} = gaussian_CPD(bnet, L, 'mean', 3, 'cov', 0.25, 'weights', -0.5);
+  bnet.CPD{Min} = gaussian_CPD(bnet, Min, 'mean', [0.5 -0.5], 'cov', [0.01 0.005]);
+  bnet.CPD{Mout} = gaussian_CPD(bnet, Mout, 'mean', 0, 'cov', 0.002, 'weights', [1 1]);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/mk_markov_chain_bnet.m b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_markov_chain_bnet.m
new file mode 100644
index 00000000..a911ece5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_markov_chain_bnet.m
@@ -0,0 +1,9 @@
+function bnet = mk_markov_chain_bnet(N, Q)
+
+dag = zeros(N);
+dag(1,2)=1; dag(2,3)=1;
+ns = Q*ones(1,N); 
+bnet = mk_bnet(dag, ns);
+for i=1:N
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/mk_minimal_qmr_bnet.m b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_minimal_qmr_bnet.m
new file mode 100644
index 00000000..99ad6e24
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_minimal_qmr_bnet.m
@@ -0,0 +1,82 @@
+function [bnet, vals] = mk_minimal_qmr_bnet(G, inhibit, leak, prior, pos, neg, pos_only)
+% MK_MINIMAL_QMR_BNET Make a QMR model which only contains the observed findings
+% [bnet, vals] = mk_minimal_qmr_bnet(G, inhibit, prior, leak, pos, neg)
+%
+% Input:
+% G(i,j) = 1 iff there is an arc from disease i to finding j
+% inhibit(i,j) = inhibition probability on i->j arc
+% leak(j) = inhibition prob. on leak->j arc
+% prior(i) = prob. disease i is on
+% pos = list of leaves that have positive observations
+% neg = list of leaves that have negative observations
+% pos_only = 1 means only include positively observed leaves in the model - the negative
+%   ones are absorbed into the prior terms
+%
+% Output:
+% bnet
+% vals is their value
+
+if pos_only
+  obs = pos;
+else
+  obs = myunion(pos, neg);
+end
+Nfindings = length(obs);
+[Ndiseases maxNfindings] = size(inhibit);
+N = Ndiseases + Nfindings;
+finding_node = Ndiseases+1:N;
+
+% j = finding_node(i) means the i'th finding node is the j'th node in the bnet
+% k = obs(i) means the i'th observed (positive) finding is the k'th finding overall
+% If all findings are observed, and posonly = 0, we have i = obs(i) for all i.
+
+%dag = sparse(N, N);
+dag = zeros(N, N);
+dag(1:Ndiseases, Ndiseases+1:N) = G(:,obs);
+
+ns = 2*ones(1,N);
+bnet = mk_bnet(dag, ns, 'observed', finding_node);
+
+CPT = cell(1, Ndiseases);
+for d=1:Ndiseases
+  CPT{d} = [1-prior(d) prior(d)];
+end
+
+if pos_only
+  % Fold in the negative evidence into the prior
+  for i=1:length(neg)
+    n = neg(i);
+    ps = parents(G,n);
+    for pi=1:length(ps)
+      p = ps(pi);
+      q = inhibit(p,n);
+      CPT{p} = CPT{p} .* [1 q];
+    end
+    % Arbitrarily attach the leak term to the first parent
+    p = ps(1);
+    q = leak(n);
+    CPT{p} = CPT{p} .* [q q];
+  end
+end
+
+for d=1:Ndiseases
+  bnet.CPD{d} = tabular_CPD(bnet, d, CPT{d}');
+end
+
+for i=1:Nfindings
+  fnode = finding_node(i);
+  fid = obs(i);
+  ps = parents(G, fid);
+  bnet.CPD{fnode} = noisyor_CPD(bnet, fnode, leak(fid), inhibit(ps, fid));
+end
+
+obs_nodes = finding_node;
+vals = sparse(1, maxNfindings);
+vals(pos) = 2;
+vals(neg) = 1;
+vals = full(vals(obs));
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/mk_qmr_bnet.m b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_qmr_bnet.m
new file mode 100644
index 00000000..1532ae4c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_qmr_bnet.m
@@ -0,0 +1,41 @@
+function bnet = mk_qmr_bnet(G, inhibit, leak, prior, tabular_findings, onodes)
+% MK_QMR_BNET Make a QMR model
+% bnet = mk_qmr_bnet(G, inhibit, leak, prior)
+%
+% G(i,j) = 1 iff there is an arc from disease i to finding j
+% inhibit(i,j) = inhibition probability on i->j arc
+% leak(j) = inhibition prob. on leak->j arc
+% prior(i) = prob. disease i is on
+% tabular_findings = 1 means multinomial leaves (ignores leak/inhibit params)
+%   = 0 means noisy-OR leaves (default = 0)
+
+if nargin < 5, tabular_findings = 0; end
+
+[Ndiseases Nfindings] = size(inhibit);
+N = Ndiseases + Nfindings;
+finding_node = Ndiseases+1:N;
+ns = 2*ones(1,N);
+dag = zeros(N,N);
+dag(1:Ndiseases, finding_node) = G;
+if nargin < 6, onodes = finding_node; end
+bnet = mk_bnet(dag, ns, 'observed', onodes);
+
+for d=1:Ndiseases
+  CPT = [1-prior(d) prior(d)];
+  bnet.CPD{d} = tabular_CPD(bnet, d, CPT');
+end
+
+for i=1:Nfindings
+  fnode = finding_node(i);
+  ps = parents(G, i);
+  if tabular_findings
+    bnet.CPD{fnode} = tabular_CPD(bnet, fnode); 
+  else
+    bnet.CPD{fnode} = noisyor_CPD(bnet, fnode, leak(i), inhibit(ps, i));
+  end
+end
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Models/mk_vstruct_bnet.m b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_vstruct_bnet.m
new file mode 100644
index 00000000..a37a4548
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Models/mk_vstruct_bnet.m
@@ -0,0 +1,16 @@
+function oracle = mk_vstruct_bnet()
+% MK_VSTRUCT_BNET Make a simple V-structured 3-node noisy-AND Bayes net
+% oracle = mk_vstruct_bnet()
+
+N = 3;
+dag = zeros(N);
+A = 1; B = 2; C = 3;
+dag(A,C)=1;
+dag(B,C)=1;
+ns = 2*ones(1,N);
+
+oracle = mk_bnet(dag, ns);
+oracle.CPD{1} = tabular_CPD(oracle, 1, [0.5 0.5]);
+oracle.CPD{2} = tabular_CPD(oracle, 2, [0.5 0.5]);
+pnoise = 0.1; % degree of noise
+oracle.CPD{3} = boolean_CPD(oracle, 3, 'named', 'all', pnoise);
diff --git a/sourcecodes/bnt-master/BNT/examples/static/SCG/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/static/SCG/CVS/Entries
new file mode 100644
index 00000000..8a722650
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/SCG/CVS/Entries
@@ -0,0 +1,6 @@
+/scg1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/scg2.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/scg3.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/scg_3node.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/scg_unstable.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/static/SCG/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/static/SCG/CVS/Repository
new file mode 100644
index 00000000..1b551eef
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/SCG/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/static/SCG
diff --git a/sourcecodes/bnt-master/BNT/examples/static/SCG/CVS/Root b/sourcecodes/bnt-master/BNT/examples/static/SCG/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/SCG/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/static/SCG/scg1.m b/sourcecodes/bnt-master/BNT/examples/static/SCG/scg1.m
new file mode 100644
index 00000000..f504c1fe
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/SCG/scg1.m
@@ -0,0 +1,77 @@
+% Same as cg1, except we call stab_cond_gauss_inf_engine
+
+bnet  = mk_incinerator_bnet;
+
+engines = {};
+engines{end+1} = stab_cond_gauss_inf_engine(bnet);
+engines{end+1} = jtree_inf_engine(bnet);
+engines{end+1} = cond_gauss_inf_engine(bnet);
+nengines = length(engines);
+
+F = 1; W = 2; E = 3; B = 4; C = 5; D = 6; Min = 7; Mout = 8; L = 9;
+n = 9;
+dnodes = [B F W];
+cnodes = mysetdiff(1:n, dnodes);
+
+evidence = cell(1,n); % no evidence
+ll = zeros(1, nengines);
+for e=1:nengines
+  [engines{e}, ll(e)] = enter_evidence(engines{e}, evidence);
+end
+%assert(approxeq(ll(1), ll)))
+ll
+
+% Compare to the results in table on p1107.
+% These results are printed to 3dp in Cowell p150
+
+mu = zeros(1,n);
+sigma = zeros(1,n);
+dprob = zeros(1,n);
+addev = 1;
+tol = 1e-2;
+for e=1:nengines
+  for i=cnodes(:)'
+    m = marginal_nodes(engines{e}, i, addev);
+    mu(i) = m.mu;
+    sigma(i) = sqrt(m.Sigma);
+  end
+  for i=dnodes(:)'
+    m = marginal_nodes(engines{e}, i, addev);
+    dprob(i) = m.T(1);
+  end
+  assert(approxeq(mu([E D C L Min Mout]), [-3.25 3.04 -1.85 1.48 -0.214 2.83], tol))
+  assert(approxeq(sigma([E D C L Min Mout]), [0.709 0.770 0.507 0.631 0.459 0.860], tol))
+  assert(approxeq(dprob([B F W]), [0.85 0.95 0.29], tol))
+  %m = marginal_nodes(engines{e}, bnet.names('E'), addev);
+  %assert(approxeq(m.mu, -3.25, tol))
+  %assert(approxeq(sqrt(m.Sigma), 0.709, tol))
+end
+
+% Add evidence (p 1105, top right)
+evidence = cell(1,n);
+evidence{W} = 1; % industrial
+evidence{L} = 1.1;
+evidence{C} = -0.9;
+
+ll = zeros(1, nengines);
+for e=1:nengines
+  [engines{e}, ll(e)] = enter_evidence(engines{e}, evidence);
+end
+%assert(all(approxeq(ll(1), ll)))
+ll
+
+for e=1:nengines
+  for i=cnodes(:)'
+    m = marginal_nodes(engines{e}, i, addev);
+    mu(i) = m.mu;
+    sigma(i) = sqrt(m.Sigma);
+  end
+  for i=dnodes(:)'
+    m = marginal_nodes(engines{e}, i, addev);
+    dprob(i) = m.T(1);
+  end
+  assert(approxeq(mu([E D C L Min Mout]), [-3.90 3.61 -0.9 1.1 0.5 4.11], tol))
+  assert(approxeq(sigma([E D C L Min Mout]), [0.076 0.326 0 0 0.1 0.344], tol))
+  assert(approxeq(dprob([B F W]), [0.0122 0.9995 1], tol))
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/SCG/scg2.m b/sourcecodes/bnt-master/BNT/examples/static/SCG/scg2.m
new file mode 100644
index 00000000..a9779248
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/SCG/scg2.m
@@ -0,0 +1,12 @@
+% Same as cg2, except we call stab_cond_gauss_inf_engine
+
+ns = 2*ones(1,9);
+bnet  = mk_incinerator_bnet(ns);
+
+engines = {};
+engines{end+1} = stab_cond_gauss_inf_engine(bnet);
+engines{end+1} = jtree_inf_engine(bnet);
+engines{end+1} = cond_gauss_inf_engine(bnet);
+nengines = length(engines);
+
+[err, time] = cmp_inference_static(bnet, engines, 'singletons_only', 1);
diff --git a/sourcecodes/bnt-master/BNT/examples/static/SCG/scg3.m b/sourcecodes/bnt-master/BNT/examples/static/SCG/scg3.m
new file mode 100644
index 00000000..cc35b0a5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/SCG/scg3.m
@@ -0,0 +1,42 @@
+% Compare various inference engines on the following network (from Jensen (1996) p84 fig 4.17)
+%    1
+%  / | \
+% 2  3  4
+% |  |  |
+% 5  6  7
+%  \/ \/
+%  8   9
+% where all arcs point downwards
+
+N = 9;
+dag = zeros(N,N);
+dag(1,2)=1; dag(1,3)=1; dag(1,4)=1;
+dag(2,5)=1; dag(3,6)=1; dag(4,7)=1;
+dag(5,8)=1; dag(6,8)=1; dag(6,9)=1; dag(7,9) = 1;
+
+gauss = 1;
+if gauss
+  ns = ones(1,N); % scalar nodes
+  ns(1) = 2;
+  ns(9) = 3;
+  dnodes = [];
+else
+  ns = 2*ones(1,N); % binary nodes
+  dnodes = 1:N;
+end
+
+bnet = mk_bnet(dag, ns, 'discrete', dnodes);
+% use random params
+for i=1:N
+  if gauss
+    bnet.CPD{i} = gaussian_CPD(bnet, i);
+  else
+    bnet.CPD{i} = tabular_CPD(bnet, i);
+  end
+end
+
+engines = {};
+engines{1} = jtree_inf_engine(bnet);
+engines{2} = stab_cond_gauss_inf_engine(bnet);
+
+[err, time] = cmp_inference_static(bnet, engines);
diff --git a/sourcecodes/bnt-master/BNT/examples/static/SCG/scg_3node.m b/sourcecodes/bnt-master/BNT/examples/static/SCG/scg_3node.m
new file mode 100644
index 00000000..5f75946a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/SCG/scg_3node.m
@@ -0,0 +1,52 @@
+% This example is from Page.143 of "Probabilistic Networks and Expert Systems",
+% Cowell, Dawid, Lauritzen and Spiegelhalter, 1999, Springer.
+
+X = 1; Y = 2; Z = 3;
+n = 3;
+
+dag = zeros(n);
+dag(X, Y)=1;
+dag(Y, Z)=1;
+
+ns = ones(1, n);
+dnodes = [];
+
+bnet = mk_bnet(dag, ns, dnodes);
+bnet.CPD{X} = gaussian_CPD(bnet, X, 'mean', 0, 'cov', 1);
+bnet.CPD{Y} = gaussian_CPD(bnet, Y, 'mean', 0, 'cov', 1, 'weights', 1);
+bnet.CPD{Z} = gaussian_CPD(bnet, Z, 'mean', 0, 'cov', 1, 'weights', 1);
+
+engines = {};
+engines{end+1} = jtree_inf_engine(bnet);
+engines{end+1} = stab_cond_gauss_inf_engine(bnet);
+nengines = length(engines);
+
+evidence = cell(1,n);
+evidence{Y} = 1.5; 
+
+for e=1:nengines
+  engines{e} = enter_evidence(engines{e}, evidence);
+  margX = marginal_nodes(engines{e}, X);
+  assert(approxeq(margX.mu, 0.75))
+  assert(approxeq(margX.Sigma, 0.5))
+  
+  margZ = marginal_nodes(engines{e}, Z);
+  assert(approxeq(margZ.mu, 1.5))
+  assert(approxeq(margZ.Sigma, 1))
+end
+
+
+evidence = cell(1,n);
+evidence{Z} = 1.5; 
+
+for e=1:nengines
+  engines{e} = enter_evidence(engines{e}, evidence);
+  margX = marginal_nodes(engines{e}, X);
+  assert(approxeq(margX.mu, 1/2))
+  assert(approxeq(margX.Sigma, 2/3))
+  
+  margY = marginal_nodes(engines{e}, Y);
+  assert(approxeq(margY.mu, 1))
+  assert(approxeq(margY.Sigma, 2/3))
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/SCG/scg_unstable.m b/sourcecodes/bnt-master/BNT/examples/static/SCG/scg_unstable.m
new file mode 100644
index 00000000..6617bfa9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/SCG/scg_unstable.m
@@ -0,0 +1,91 @@
+function scg_unstable()
+
+% the objective of this script is to test if the stable conditonal gaussian
+% inference can handle the numerical instability problem described on
+% page.151 of 'Probabilistic networks and expert system' by Cowell, Dawid, Lauritzen and
+% Spiegelhalter, 1999.
+
+A = 1; Y = 2;
+n = 2;
+
+ns = ones(1, n);
+dnodes = [A];
+cnodes = Y;
+ns = [2 1];
+
+dag = zeros(n);
+dag(A, Y) = 1;
+
+bnet = mk_bnet(dag, ns, dnodes);
+
+bnet.CPD{A} = tabular_CPD(bnet, A, [0.5 0.5]'); 
+bnet.CPD{Y} = gaussian_CPD(bnet, Y, 'mean', [0 1], 'cov', [1e-5 1e-6]);
+
+evidence = cell(1, n);
+
+pot_type = 'cg';
+potYgivenA = convert_to_pot(bnet.CPD{Y}, pot_type, [A Y], evidence);
+potA = convert_to_pot(bnet.CPD{A}, pot_type, A, evidence);
+potYandA = multiply_by_pot(potYgivenA, potA);
+potA2 = marginalize_pot(potYandA, A);
+
+thresh = 1; % 0dp
+
+[g,h,K] = extract_can(potA);
+assert(approxeq(g(:)', [-0.693147 -0.693147], thresh))
+
+
+[g,h,K] = extract_can(potYgivenA);
+assert(approxeq(g(:)', [4.83752 -499994], thresh))
+assert(approxeq(h(:)', [0 1e6]))
+assert(approxeq(K(:)', [1e5 1e6]))
+
+[g,h,K] = extract_can(potYandA);
+assert(approxeq(g(:)', [4.14437 -499995], thresh))
+assert(approxeq(h(:)', [0 1e6]))
+assert(approxeq(K(:)', [1e5 1e6]))
+
+
+[g,h,K] = extract_can(potA2);
+%assert(approxeq(g(:)', [-0.69315 -1]))
+g
+assert(approxeq(g(:)', [-0.69315 -0.69315]))
+
+
+
+if 0
+pot_type = 'scg';
+spotYgivenA = convert_to_pot(bnet.CPD{Y}, pot_type, [A Y], evidence);
+spotA = convert_to_pot(bnet.CPD{A}, pot_type, A, evidence);
+spotYandA = direct_combine_pots(spotYgivenA, spotA); 
+spotA2 = marginalize_pot(spotYandA, A);
+
+spotA=struct(spotA);
+spotA2=struct(spotA2);
+for i=1:2
+  assert(approxeq(spotA2.scgpotc{i}.p, spotA.scgpotc{i}.p))
+  assert(approxeq(spotA2.scgpotc{i}.A, spotA.scgpotc{i}.A))
+  assert(approxeq(spotA2.scgpotc{i}.B, spotA.scgpotc{i}.B))
+  assert(approxeq(spotA2.scgpotc{i}.C, spotA.scgpotc{i}.C))
+end
+
+end
+
+
+%%%%%%%%%%%
+
+function [g,h,K] = extract_can(pot)
+
+pot = struct(pot);
+D = length(pot.can);
+g = zeros(1, D);
+h = zeros(1, D);
+K = zeros(1, D);
+for i=1:D
+  S = struct(pot.can{i});
+  g(i) = S.g;
+  if length(S.h) > 0
+    h(i) = S.h;
+    K(i) = S.K;
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/StructLearn/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/CVS/Entries
new file mode 100644
index 00000000..0586b211
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/CVS/Entries
@@ -0,0 +1,9 @@
+/bic1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/cooper_yoo.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/k2demo1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mcmc1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/model_select1.m/1.1.1.1/Sat Nov  6 20:55:18 2004//
+/model_select2.m/1.1.1.1/Sat Nov  6 21:52:42 2004//
+/pc1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/pc2.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/static/StructLearn/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/CVS/Repository
new file mode 100644
index 00000000..5b40c54c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/static/StructLearn
diff --git a/sourcecodes/bnt-master/BNT/examples/static/StructLearn/CVS/Root b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/static/StructLearn/bic1.m b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/bic1.m
new file mode 100644
index 00000000..22473564
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/bic1.m
@@ -0,0 +1,79 @@
+% compare BIC and Bayesian score 
+
+N = 4;
+dag = zeros(N,N);
+%C = 1; S = 2; R = 3; W = 4; % topological order
+C = 4; S = 2; R = 3; W = 1; % arbitrary order
+dag(C,[R S]) = 1;
+dag(R,W) = 1;
+dag(S,W)=1;
+
+
+false = 1; true = 2;
+ns = 2*ones(1,N); % binary nodes
+bnet = mk_bnet(dag, ns);
+bnet.CPD{C} = tabular_CPD(bnet, C, 'CPT', [0.5 0.5]);
+bnet.CPD{R} = tabular_CPD(bnet, R, 'CPT', [0.8 0.2 0.2 0.8]);
+bnet.CPD{S} = tabular_CPD(bnet, S, 'CPT', [0.5 0.9 0.5 0.1]);
+bnet.CPD{W} = tabular_CPD(bnet, W, 'CPT', [1 0.1 0.1 0.01 0 0.9 0.9 0.99]);
+
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+ncases = 1000;
+data = cell(N, ncases);
+for m=1:ncases
+  data(:,m) = sample_bnet(bnet);
+end
+
+priors = [0.1 1 10];
+P = length(priors);
+params = cell(1,P);
+for p=1:P
+  params{p} = cell(1,N);
+  for i=1:N
+    %params{p}{i} = {'prior', priors(p)};
+    params{p}{i} = {'prior_type', 'dirichlet', 'dirichlet_weight', priors(p)};
+  end
+end
+
+%sz = 1000:1000:10000;
+sz = 10:10:100;
+S = length(sz);
+bic_score = zeros(S, 1);
+bayes_score = zeros(S, P);
+for i=1:S
+  bic_score(i) = score_dags(data(:,1:sz(i)), ns, {dag}, 'scoring_fn', 'bic', 'params', []);
+end
+diff = zeros(S,P);
+for p=1:P
+  for i=1:S
+    bayes_score(i,p) = score_dags(data(:,1:sz(i)), ns, {dag}, 'params', params{p});
+  end
+end
+
+for p=1:P
+  for i=1:S
+    diff(i,p) = bayes_score(i,p)/ bic_score(i);
+    %diff(i,p) = abs(bayes_score(i,p) - bic_score(i));
+  end
+end
+
+if 0
+plot(sz, diff(:,1), 'g--*', sz, diff(:,2), 'b-.+', sz, diff(:,3), 'k:s');
+title('Relative BIC error vs. size of data set')
+legend('BDeu 0.1', 'BDeu 1', 'Bdeu 10', 2)
+end
+
+if 0
+plot(sz, bic_score, 'r-o',  sz, bayes_score(:,1), 'g--*', sz, bayes_score(:,2), 'b-.+', sz, bayes_score(:,3), 'k:s');
+legend('bic', 'BDeu 0.01', 'BDeu 1', 'Bdeu 100')
+ylabel('score')
+title('score vs. size of data set')
+end
+
+%xlabel('num. data cases')
+
+%previewfig(gcf, 'format', 'png', 'height', 2, 'color', 'rgb')
+%exportfig(gcf, '/home/cs/murphyk/public_html/Bayes/Figures/bic.png', 'format', 'png', 'height', 2, 'color', 'rgb')
diff --git a/sourcecodes/bnt-master/BNT/examples/static/StructLearn/cooper_yoo.m b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/cooper_yoo.m
new file mode 100644
index 00000000..97ceb44a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/cooper_yoo.m
@@ -0,0 +1,65 @@
+% Do the example in Cooper and Yoo, "Causal discovery from a mixture of experimental and
+% observational data", UAI 99, p120
+
+N = 2;
+dag = zeros(N);
+A = 1; B = 2;
+dag(A,B) = 1;
+ns = 2*ones(1,N);
+
+bnet0 = mk_bnet(dag, ns);
+%bnet0.CPD{A} = tabular_CPD(bnet0, A, 'unif', 1);
+bnet0.CPD{A} = tabular_CPD(bnet0, A, 'CPT', 'unif', 'prior_type', 'dirichlet');
+bnet0.CPD{B} = tabular_CPD(bnet0, B, 'CPT', 'unif', 'prior_type', 'dirichlet');
+
+samples = [2 2;
+	   2 1; 
+	   2 2;
+	   1 1;
+	   1 2;
+	   2 2;
+	   1 1;
+	   2 2;
+	   1 2;
+	   2 1;
+	   1 1];
+
+clamped = [0 0;
+	   0 0;
+	   0 0;
+	   0 0;
+	   0 0;
+	   1 0;
+	   1 0;
+	   0 1;
+	   0 1;
+	   0 1;
+	   0 1];
+
+nsamples = size(samples, 1);
+
+% sequential version
+LL = 0;
+bnet = bnet0;
+for l=1:nsamples
+  ev = num2cell(samples(l,:)');
+  manip = find(clamped(l,:)');
+  LL = LL + log_marg_lik_complete(bnet, ev, manip);
+  bnet = bayes_update_params(bnet, ev, manip);
+end
+assert(approxeq(exp(LL), 5.97e-7)) % compare with result from UAI paper
+
+
+% batch version
+cases = num2cell(samples');
+LL2 = log_marg_lik_complete(bnet0, cases, clamped');
+bnet2 = bayes_update_params(bnet0, cases, clamped');
+
+assert(approxeq(LL, LL2))
+
+for j=1:N
+  s1 = struct(bnet.CPD{j}); % violate object privacy
+  s2 = struct(bnet2.CPD{j});
+  assert(approxeq(s1.CPT, s2.CPT))
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/StructLearn/k2demo1.m b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/k2demo1.m
new file mode 100644
index 00000000..a6288286
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/k2demo1.m
@@ -0,0 +1,45 @@
+N = 4;
+dag = zeros(N,N);
+%C = 1; S = 2; R = 3; W = 4;
+C = 4; S = 2; R = 3; W = 1; % arbitrary order
+dag(C,[R S]) = 1;
+dag(R,W) = 1;
+dag(S,W)=1;
+
+false = 1; true = 2;
+ns = 2*ones(1,N); % binary nodes
+
+bnet = mk_bnet(dag, ns);
+bnet.CPD{C} = tabular_CPD(bnet, C, [0.5 0.5]);
+bnet.CPD{R} = tabular_CPD(bnet, R, [0.8 0.2 0.2 0.8]);
+bnet.CPD{S} = tabular_CPD(bnet, S, [0.5 0.9 0.5 0.1]);
+bnet.CPD{W} = tabular_CPD(bnet, W, [1 0.1 0.1 0.01 0 0.9 0.9 0.99]);
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+ncases = 100;
+data = zeros(N, ncases);
+for m=1:ncases
+  data(:,m) = cell2num(sample_bnet(bnet));
+end
+
+order = [C S R W];
+max_fan_in = 2;
+
+%dag2 = learn_struct_K2(data, ns, order, 'max_fan_in', max_fan_in, 'verbose', 'yes');
+  
+sz = 5:5:50;
+for i=1:length(sz)
+  dag2 = learn_struct_K2(data(:,1:sz(i)), ns, order, 'max_fan_in', max_fan_in);
+  correct(i) = isequal(dag, dag2);
+end
+correct
+
+for i=1:length(sz)
+  dag3 = learn_struct_K2(data(:,1:sz(i)), ns, order, 'max_fan_in', max_fan_in, 'scoring_fn', 'bic', 'params', []);
+  correct(i) = isequal(dag, dag3);
+end
+correct
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/StructLearn/mcmc1.m b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/mcmc1.m
new file mode 100644
index 00000000..241d0686
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/mcmc1.m
@@ -0,0 +1,35 @@
+% We compare MCMC structure learning with exhaustive enumeration of all dags.
+
+N = 3;
+%N = 4;
+dag = mk_rnd_dag(N);
+ns = 2*ones(1,N);
+bnet = mk_bnet(dag, ns);
+for i=1:N
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+end
+
+ncases = 100;
+data = zeros(N, ncases);
+for m=1:ncases
+  data(:,m) = cell2num(sample_bnet(bnet));
+end
+
+dags = mk_all_dags(N);
+score = score_dags(data, ns, dags);
+post  = normalise(exp(score));
+
+[sampled_graphs, accept_ratio] = learn_struct_mcmc(data, ns, 'nsamples', 100, 'burnin', 10);
+mcmc_post = mcmc_sample_to_hist(sampled_graphs, dags);
+
+if 0
+  subplot(2,1,1)
+  bar(post)
+  subplot(2,1,2)
+  bar(mcmc_post)
+  print(gcf, '-djpeg', '/home/cs/murphyk/public_html/Bayes/Figures/mcmc_post.jpg')
+
+  clf
+  plot(accept_ratio)
+  print(gcf, '-djpeg', '/home/cs/murphyk/public_html/Bayes/Figures/mcmc_accept.jpg')
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/StructLearn/model_select1.m b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/model_select1.m
new file mode 100644
index 00000000..c79131c3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/model_select1.m
@@ -0,0 +1,121 @@
+% Bayesian model selection demo.
+
+% We generate data from the model A->B
+% and compute the posterior prob of all 3 dags on 2 nodes:
+%  (1) A B,  (2) A <- B , (3) A -> B
+% Models 2 and 3 are Markov equivalent, and therefore indistinguishable from 
+% observational data alone.
+% Using the "difficult" params, the true model only gets a higher posterior after 2000 trials!
+% However, using the noisy NOT gate, the true model wins after 12 trials.
+
+% ground truth
+N = 2;
+dag = zeros(N);
+A = 1; B = 2; 
+dag(A,B) = 1;
+
+difficult = 0;
+if difficult
+  ntrials = 2000;
+  ns = 3*ones(1,N);
+  true_bnet = mk_bnet(dag, ns);
+  rand('state', 0);
+  temp = 5;
+  for i=1:N
+    %true_bnet.CPD{i} = tabular_CPD(true_bnet, i, temp);
+    true_bnet.CPD{i} = tabular_CPD(true_bnet, i);
+  end
+else
+  ntrials = 25;
+  ns = 2*ones(1,N);
+  true_bnet = mk_bnet(dag, ns);
+  true_bnet.CPD{1} = tabular_CPD(true_bnet, 1, [0.5 0.5]);
+  pfail = 0.1;
+  psucc = 1-pfail;
+  true_bnet.CPD{2} = tabular_CPD(true_bnet, 2, [pfail psucc; psucc pfail]); % NOT gate
+end
+
+G = mk_all_dags(N);
+nhyp = length(G);
+hyp_bnet = cell(1, nhyp);
+for h=1:nhyp
+  hyp_bnet{h} = mk_bnet(G{h}, ns);
+  for i=1:N
+    % We must set the CPTs to the mean of the prior for sequential log_marg_lik to be correct
+    % The BDeu prior is score equivalent, so models 2,3 will be indistinguishable.
+    % The uniform Dirichlet prior is not score equivalent...
+    fam = family(G{h}, i);
+    hyp_bnet{h}.CPD{i}= tabular_CPD(hyp_bnet{h}, i, 'prior_type', 'dirichlet', ...
+				    'CPT', 'unif');
+  end
+end
+prior = normalise(ones(1, nhyp));
+
+% save results before doing sequential updating
+init_hyp_bnet = hyp_bnet; 
+init_prior = prior;
+
+
+rand('state', 0);
+hyp_w = zeros(ntrials+1, nhyp);
+hyp_w(1,:) = prior(:)';
+
+data = zeros(N, ntrials);
+
+% First we compute the posteriors sequentially
+
+LL = zeros(1, nhyp);
+ll = zeros(1, nhyp);
+for t=1:ntrials
+  ev = cell2num(sample_bnet(true_bnet));
+  data(:,t) = ev;
+  for i=1:nhyp
+    ll(i) = log_marg_lik_complete(hyp_bnet{i}, ev);
+    hyp_bnet{i} = bayes_update_params(hyp_bnet{i}, ev);
+  end
+  prior = normalise(prior .* exp(ll));
+  LL = LL + ll;
+  hyp_w(t+1,:) = prior;
+end
+
+% Plot posterior model probabilities
+% Red = model 1 (no arcs), blue/green = models 2/3 (1 arc)
+% Blue = model 2 (2->1)
+% Green = model 3 (1->2, "ground truth")
+
+if 1
+  figure;
+m = size(hyp_w, 1);
+h=plot(1:m, hyp_w(:,1), 'r-',  1:m, hyp_w(:,2), 'b-.', 1:m, hyp_w(:,3), 'g:');
+axis([0 m   0 1])
+title('model posterior vs. time')
+%previewfig(gcf, 'format', 'png', 'height', 2, 'color', 'rgb')
+%exportfig(gcf, '/home/cs/murphyk/public_html/Bayes/Figures/model_select.png',...
+%'format', 'png', 'height', 2, 'color', 'rgb')
+drawnow
+end
+
+
+% Now check that batch updating gives same result
+hyp_bnet2 = init_hyp_bnet;
+prior2 = init_prior;
+
+cases = num2cell(data);
+LL2 = zeros(1, nhyp);
+for i=1:nhyp
+  LL2(i) = log_marg_lik_complete(hyp_bnet2{i}, cases);
+  hyp_bnet2{i} = bayes_update_params(hyp_bnet2{i}, cases);
+end
+
+
+assert(approxeq(LL, LL2))
+LL
+
+for i=1:nhyp
+  for j=1:N
+    s1 = struct(hyp_bnet{i}.CPD{j});
+    s2 = struct(hyp_bnet2{i}.CPD{j});
+    assert(approxeq(s1.CPT, s2.CPT))
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/StructLearn/model_select2.m b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/model_select2.m
new file mode 100644
index 00000000..d34c75c4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/model_select2.m
@@ -0,0 +1,83 @@
+% Online Bayesian model selection demo.
+
+% We generate data from the model A->B
+% and compute the posterior prob of all 3 dags on 2 nodes:
+%  (1) A B,  (2) A <- B , (3) A -> B
+% Models 2 and 3 are Markov equivalent, and therefore indistinguishable from 
+% observational data alone.
+
+% We control the dependence of B on A by setting
+% P(B|A) = 0.5 - epislon and vary epsilon
+% as in Koller & Friedman book p512
+
+% ground truth
+N = 2;
+dag = zeros(N);
+A = 1; B = 2; 
+dag(A,B) = 1;
+
+ntrials = 100;
+ns = 2*ones(1,N);
+true_bnet = mk_bnet(dag, ns);
+true_bnet.CPD{1} = tabular_CPD(true_bnet, 1, [0.5 0.5]);
+
+% hypothesis space
+G = mk_all_dags(N);
+nhyp = length(G);
+hyp_bnet = cell(1, nhyp);
+for h=1:nhyp
+  hyp_bnet{h} = mk_bnet(G{h}, ns);
+  for i=1:N
+    % We must set the CPTs to the mean of the prior for sequential log_marg_lik to be correct
+    % The BDeu prior is score equivalent, so models 2,3 will be indistinguishable.
+    % The uniform Dirichlet prior is not score equivalent...
+    fam = family(G{h}, i);
+    hyp_bnet{h}.CPD{i}= tabular_CPD(hyp_bnet{h}, i, 'prior_type', 'dirichlet', ...
+				    'CPT', 'unif');
+  end
+end
+
+clf
+seeds = 1:3;
+expt = 1;
+for seedi=1:length(seeds)
+  seed = seeds(seedi);
+  rand('state', seed);
+  randn('state', seed);
+    
+  es = [0.05 0.1 0.15 0.2];
+  for ei=1:length(es)
+    e = es(ei);
+    true_bnet.CPD{2} = tabular_CPD(true_bnet, 2, [0.5+e 0.5-e; 0.5-e 0.5+e]);
+
+    prior = normalise(ones(1, nhyp));
+    hyp_w = zeros(ntrials+1, nhyp);
+    hyp_w(1,:) = prior(:)';
+    LL = zeros(1, nhyp);
+    ll = zeros(1, nhyp);
+    for t=1:ntrials
+      ev = cell2num(sample_bnet(true_bnet));
+      for i=1:nhyp
+	ll(i) = log_marg_lik_complete(hyp_bnet{i}, ev);
+	hyp_bnet{i} = bayes_update_params(hyp_bnet{i}, ev);
+      end
+      prior = normalise(prior .* exp(ll));
+      LL = LL + ll;
+      hyp_w(t+1,:) = prior;
+    end
+
+    % Plot posterior model probabilities
+    % Red = model 1 (no arcs), blue/green = models 2/3 (1 arc)
+    % Blue = model 2 (2->1)
+    % Green = model 3 (1->2, "ground truth")
+    
+    subplot2(length(seeds), length(es), seedi, ei);
+    m = size(hyp_w,1);
+    h=plot(1:m, hyp_w(:,1), 'r-',  1:m, hyp_w(:,2), 'b-.', 1:m, hyp_w(:,3), 'g:');
+    axis([0 m   0 1])
+    %title('model posterior vs. time')
+    title(sprintf('e=%3.2f, seed=%d', e, seed));
+    drawnow
+    expt = expt + 1;
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/StructLearn/pc1.m b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/pc1.m
new file mode 100644
index 00000000..a6fbb9bd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/pc1.m
@@ -0,0 +1,30 @@
+% SGS p118
+% Try learning the structure using an oracle for the cond indep tests
+
+n = 5;
+
+A = 1; B = 2; C = 3; D = 4; E = 5;
+
+G = zeros(n);
+G(A,B)=1;
+G(B,[C D]) = 1;
+G(C,E)=1;
+G(D,E)=1;
+
+k = 2;
+
+pdag = learn_struct_pdag_pc('dsep', n, k, G)
+
+
+
+
+if 0
+N = 4; 
+dag = zeros(N,N);
+C = 1; S = 2; R = 3; W = 4;
+dag(C,[R S]) = 1;
+dag(R,W) = 1;
+dag(S,W)=1;
+
+pdag = learn_struct_pdag_pc('dsep', N, 2, dag)
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/StructLearn/pc2.m b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/pc2.m
new file mode 100644
index 00000000..7b7e2066
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/StructLearn/pc2.m
@@ -0,0 +1,21 @@
+% SGS p141 (female orgasm data set)
+
+C = eye(7,7);
+C(2,1:1) = [-0.132];
+C(3,1:2) = [0.009 -0.136];
+C(4,1:3) = [0.22 -0.166 0.403];
+C(5,1:4) = [-0.008 0.008 0.598 0.282];
+C(6,1:5) = [0.119 -0.076 0.264 0.514 0.176];
+C(7,1:6) = [0.118 -0.137 0.368 0.414 0.336 0.338];
+
+n = 7;
+for i=1:n
+  for j=i+1:n
+    C(i,j)=C(j,i);
+  end
+end
+
+max_fan_in = 4;
+nsamples = 281;
+alpha = 0.05;
+pdag = learn_struct_pdag_pc('cond_indep_fisher_z', n, max_fan_in, C, nsamples, alpha)
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Zoubin/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/CVS/Entries
new file mode 100644
index 00000000..31efa304
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/CVS/Entries
@@ -0,0 +1,10 @@
+/README/1.1.1.1/Wed May 29 15:59:54 2002//
+/csum.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/ffa.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mfa.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mfa_cl.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mfademo.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/rdiv.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/rprod.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/rsum.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Zoubin/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/CVS/Repository
new file mode 100644
index 00000000..15fbcd8e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/static/Zoubin
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Zoubin/CVS/Root b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Zoubin/README b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/README
new file mode 100644
index 00000000..0fe8214b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/README
@@ -0,0 +1,61 @@
+This software was downloaded from
+   http://www.gatsby.ucl.ac.uk/~zoubin/software.html
+with permission of the author.
+
+
+This software was written by 
+
+Zoubin Ghahramani
+Dept of Computer Science
+University of Toronto
+zoubin@cs.toronto.edu
+
+This software is written in Matlab 4.2c and should run on all platforms
+supporting this version of Matlab. Matlab is a commercial software
+package available from The MathWorks (http://www.mathworks.com/). 
+
+This software is meant for free non-commercial use and distribution. See the
+copyright notice at the bottom of this page.
+
+If you use it, please refer to the accompanying technical report: 
+
+Ghahramani, Z. and Hinton, G.E. (1996) The EM Algorithm for Mixtures
+of Factor Analyzers. University of Toronto Technical Report CRG-TR-96-1. 
+Available at ftp://ftp.cs.toronto.edu/pub/zoubin/tr-96-1.ps.gz  
+
+If you find bugs, or would like to see if I've implemented any
+extensions, please send me email at zoubin@cs.toronto.edu. The
+software is provided "as is", and I cannot guarantee I will be able
+to fix all problems or answer all inquiries. 
+
+See mfademo.m for a demo.
+
+Hope you find it useful. Please send me email if you find it useful
+and I will put you on a mailing list announcing releases of other
+statistical machine learning software in Matlab.
+
+
+----------------------------------------------------------------------
+	Copyright (c) 1996 by Zoubin Ghahramani
+                Toronto, Ontario, Canada. 
+                   All Rights Reserved 
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for non-commercial purposes only is hereby granted
+without fee, provided that the above copyright notice appears in all
+copies and that both the copyright notice and this permission notice
+appear in supporting documentation, and that my name not be used in
+advertising or publicity pertaining to distribution of the software
+without specific, written prior permission. I make no representations
+about the suitability of this software for any purpose. It is provided
+"as is" without express or implied warranty.
+
+I disclaim all warranties with regard to this software, including all
+implied warranties of merchantability and fitness. In no event shall I
+be liable for any special, indirect or consequential damages or any
+damages whatsoever resulting from loss of use, data or profits,
+whether in an action of contract, negligence or other tortious action,
+arising out of or in connection with the use or performance of this
+software.
+
+Zoubin Ghahramani					 Dec 17, 1996
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Zoubin/csum.m b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/csum.m
new file mode 100644
index 00000000..2fba6ca5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/csum.m
@@ -0,0 +1,11 @@
+% column sum
+% function Z=csum(X)
+
+function Z=csum(X)
+
+N=length(X(:,1));
+if (N>1)
+  Z=sum(X);
+else
+  Z=X;
+end;
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Zoubin/ffa.m b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/ffa.m
new file mode 100644
index 00000000..e4caa3e0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/ffa.m
@@ -0,0 +1,75 @@
+% function [L,Ph,LL]=ffa(X,K,cyc,tol);
+% 
+% Fast Maximum Likelihood Factor Analysis using EM
+%
+% X - data matrix
+% K - number of factors
+% cyc - maximum number of cycles of EM (default 100)
+% tol - termination tolerance (prop change in likelihood) (default 0.0001)
+%
+% L - factor loadings 
+% Ph - diagonal uniquenesses matrix
+% LL - log likelihood curve
+%
+% Iterates until a proportional change < tol in the log likelihood 
+% or cyc steps of EM 
+%
+
+function [L,Ph,LL]=ffa(X,K,cyc,tol);
+
+if nargin<4  tol=0.0001; end;
+if nargin<3  cyc=100; end;
+
+N=length(X(:,1));
+D=length(X(1,:));
+tiny=exp(-700);
+
+X=X-ones(N,1)*mean(X);
+XX=X'*X/N;
+diagXX=diag(XX);
+
+randn('seed', 0);
+cX=cov(X);
+scale=det(cX)^(1/D);
+L=randn(D,K)*sqrt(scale/K);
+Ph=diag(cX);
+
+I=eye(K);
+
+lik=0; LL=[];
+
+const=-D/2*log(2*pi);
+
+
+for i=1:cyc;
+
+  %%%% E Step %%%%
+  Phd=diag(1./Ph);
+  LP=Phd*L;
+  MM=Phd-LP*inv(I+L'*LP)*LP';
+  dM=sqrt(det(MM));
+  beta=L'*MM;
+  XXbeta=XX*beta';
+  EZZ=I-beta*L +beta*XXbeta;
+
+  %%%% Compute log likelihood %%%%
+  
+  oldlik=lik;
+  lik=N*const+N*log(dM)-0.5*N*sum(diag(MM*XX));
+  fprintf('cycle %i lik %g \n',i,lik);
+  LL=[LL lik];
+  
+  %%%% M Step %%%%
+
+  L=XXbeta*inv(EZZ);
+  Ph=diagXX-diag(L*XXbeta');
+
+  if (i<=2)    
+    likbase=lik;
+  elseif (lik<oldlik)     
+    disp('VIOLATION');
+  elseif ((lik-likbase)<(1+tol)*(oldlik-likbase)||~isfinite(lik))  
+    break;
+  end;
+
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Zoubin/mfa.m b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/mfa.m
new file mode 100644
index 00000000..2060e331
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/mfa.m
@@ -0,0 +1,153 @@
+% function [Lh,Ph,Mu,Pi,LL]=mfa(X,M,K,cyc,tol);
+% 
+% Maximum Likelihood Mixture of Factor Analysis using EM
+%
+% X - data matrix
+% M - number of mixtures (default 1)
+% K - number of factors in each mixture (default 2)
+% cyc - maximum number of cycles of EM (default 100)
+% tol - termination tolerance (prop change in likelihood) (default 0.0001)
+%
+% Lh - factor loadings 
+% Ph - diagonal uniquenesses matrix
+% Mu - mean vectors
+% Pi - priors
+% LL - log likelihood curve
+%
+% Iterates until a proportional change < tol in the log likelihood 
+% or cyc steps of EM 
+
+function [Lh, Ph,  Mu, Pi, LL] = mfa(X,M,K,cyc,tol)
+
+if nargin<5   tol=0.0001; end;
+if nargin<4   cyc=100; end;
+if nargin<3   K=2; end;
+if nargin<2   M=1; end;
+
+N=length(X(:,1));
+D=length(X(1,:));
+tiny=exp(-700);
+
+%rand('state',0);
+
+fprintf('\n');
+
+if (M==1)
+  [Lh,Ph,LL]=ffa(X,K,cyc,tol);
+  Mu=mean(X);
+  Pi=1;
+else
+  if N==1
+    mX = X;
+  else
+    mX=mean(X);
+  end
+  cX=cov(X);
+  scale=det(cX)^(1/D);
+  randn('state',0); 
+  Lh=randn(D*M,K)*sqrt(scale/K);
+  Ph=diag(cX)+tiny;
+  Pi=ones(M,1)/M;
+  %randn('state',0); 
+  Mu=randn(M,D)*sqrtm(cX)+ones(M,1)*mX;
+  oldMu=Mu;
+  I=eye(K);
+
+  lik=0;
+  LL=[];
+
+  H=zeros(N,M); 	% E(w|x) 
+  EZ=zeros(N*M,K);
+  EZZ=zeros(K*M,K);
+  XX=zeros(D*M,D);
+  s=zeros(M,1);
+  const=(2*pi)^(-D/2);
+  %%%%%%%%%%%%%%%%%%%%
+  for i=1:cyc;
+
+    %%%% E Step %%%%
+
+    Phi=1./Ph;
+    Phid=diag(Phi);
+    for k=1:M
+      Lht=Lh((k-1)*D+1:k*D,:);
+      LP=Phid*Lht;
+      MM=Phid-LP*inv(I+Lht'*LP)*LP';
+      dM=sqrt(det(MM));      	
+      Xk=(X-ones(N,1)*Mu(k,:)); 
+      XM=Xk*MM;
+      H(:,k)=const*Pi(k)*dM*exp(-0.5*rsum(XM.*Xk)); 	
+      EZ((k-1)*N+1:k*N,:)=XM*Lht;
+    end;
+    
+    Hsum=rsum(H);
+    oldlik=lik;
+    lik=sum(log(Hsum+(Hsum==0)*exp(-744)));
+
+    Hzero=(Hsum==0); Nz=sum(Hzero); 
+    H(Hzero,:)=tiny*ones(Nz,M)/M; 
+    Hsum(Hzero)=tiny*ones(Nz,1);
+    
+    H=rdiv(H,Hsum); 				
+    s=csum(H);
+    s=s+(s==0)*tiny;
+    s2=sum(s)+tiny;
+    
+    for k=1:M  
+      kD=(k-1)*D+1:k*D;
+      Lht=Lh(kD,:);
+      LP=Phid*Lht;
+      MM=Phid-LP*inv(I+Lht'*LP)*LP';
+      Xk=(X-ones(N,1)*Mu(k,:)); 
+      XX(kD,:)=rprod(Xk,H(:,k))'*Xk/s(k); 
+      beta=Lht'*MM;
+      EZZ((k-1)*K+1:k*K,:)=I-beta*Lht +beta*XX(kD,:)*beta'; 
+    end;
+
+    %%%% log likelihood %%%%
+
+    LL=[LL lik];
+    fprintf('cycle %g   \tlog likelihood %g ',i,lik);
+    
+    if (i<=2)
+      likbase=lik;
+    elseif (lik<oldlik) 
+      fprintf(' violation');
+    elseif ((lik-likbase)<(1 + tol)*(oldlik-likbase)||~isfinite(lik)) 
+      break;
+    end;
+
+    fprintf('\n');
+    
+    %%%% M Step %%%%
+    
+    % means and covariance structure
+    
+    Ph=zeros(D,1);
+    for k=1:M
+      kD=(k-1)*D+1:k*D;
+      kK=(k-1)*K+1:k*K;
+      kN=(k-1)*N+1:k*N;
+
+      T0=rprod(X,H(:,k));
+      T1=T0'*[EZ(kN,:) ones(N,1)];
+      XH=EZ(kN,:)'*H(:,k);
+      T2=inv([s(k)*EZZ(kK,:) XH; XH' s(k)]);
+      T3=T1*T2;
+      Lh(kD,:)=T3(:,1:K);
+      Mu(k,:)=T3(:,K+1)';
+      T4=diag(T0'*X-T3*T1')/s2;
+      Ph=Ph+T4.*(T4>0); 
+    end;
+
+    Phmin=exp(-700);
+    Ph=Ph.*(Ph>Phmin)+(Ph<=Phmin)*Phmin; % to avoid zero variances
+
+    % priors
+    Pi=s'/s2;
+    
+  end;
+  fprintf('\n');
+end;
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Zoubin/mfa_cl.m b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/mfa_cl.m
new file mode 100644
index 00000000..b90bab18
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/mfa_cl.m
@@ -0,0 +1,54 @@
+% function [lik, likv]=mfa_cl(X,Lh,Ph,Mu,Pi);
+% 
+% Calculates log likelihoods of a data set under a mixture of factor
+% analysis model.
+%
+% X - data matrix
+% Lh - factor loadings 
+% Ph - diagonal uniquenesses matrix
+% Mu - mean vectors
+% Pi - priors
+%
+% lik - log likelihood of X 
+% likv - vector of log likelihoods
+% 
+% If 0 or 1 output arguments requested, lik is returned. If 2 output
+% arguments requested, [lik likv] is returned.
+
+function [lik, likv]=mfa_cl(X,Lh,Ph,Mu,Pi);
+
+N=length(X(:,1));
+D=length(X(1,:));
+K=length(Lh(1,:));
+M=length(Pi);
+
+if (abs(sum(Pi)-1) > 1e-6) 
+  disp('ERROR: Pi should sum to 1');
+  return;
+elseif ((size(Lh) ~= [D*M K]) | (size(Ph) ~= [D 1]) | (size(Mu) ~= [M D]) ...
+  | (size(Pi) ~= [M 1] & size(Pi) ~= [1 M]))   
+  disp('ERROR in input matrix sizes');
+  return;
+end;  
+
+tiny=exp(-744);
+const=(2*pi)^(-D/2);
+
+I=eye(K);
+Phi=1./Ph;
+Phid=diag(Phi);
+for k=1:M  
+  Lht=Lh((k-1)*D+1:k*D,:);
+  LP=Phid*Lht;
+  MM=Phid-LP*inv(I+Lht'*LP)*LP';
+  dM=sqrt(det(MM));      	
+  Xk=(X-ones(N,1)*Mu(k,:)); 
+  XM=Xk*MM; 
+  H(:,k)=const*Pi(k)*dM*exp(-0.5*sum((XM.*Xk)'))'; 	
+end;
+
+Hsum=rsum(H); 				
+
+likv=log(Hsum+(Hsum==0)*tiny);
+lik=sum(likv);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Zoubin/mfademo.m b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/mfademo.m
new file mode 100644
index 00000000..508d840b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/mfademo.m
@@ -0,0 +1,81 @@
+echo on;
+
+clc;
+
+% This is a very basic demo of the mixture of factor analyzer software
+% written in Matlab by	Zoubin Ghahramani
+%			Dept of Computer Science
+%			University of Toronto
+
+pause;		% Hit any key to continue 
+
+% To demonstrate the software we generate a sample data set
+% from a mixture of two Gaussians
+
+pause;		% Hit any key to continue 
+
+X1=randn(300,5);	% zero mean 5 dim Gaussian data 
+X2=randn(200,5)+2;	% 5 dim Gaussian data with mean [1 1 1 1 1]
+X=[X1;X2];		% total 500 data points from mixture
+
+% Fitting the model is very easy. For example to fit a mixture of 2
+% factor analyzers with three factors each...
+
+pause;		% Hit any key to continue 
+
+
+[Lh,Ph,Mu,Pi,LL]=mfa(X,2,3);
+
+% Lh, Ph, Mu, and Pi are the factor loadings, observervation
+% variances, observation means for each mixture, and mixing
+% proportions. LL is the vector of log likelihoods (the learning
+% curve). For more information type: help mfa
+
+% to plot the learning curve (log likelihood at each step of EM)...
+
+pause;		% Hit any key to continue 
+
+plot(LL);
+
+% you get a more informative picture of convergence by looking at the
+% log of the first difference of the log likelihoods...
+
+pause;		% Hit any key to continue 
+
+semilogy(diff(LL)); 
+
+% you can look at some of the parameters of the fitted model... 
+
+pause;		% Hit any key to continue 
+
+Mu
+
+Pi
+
+% ...to see whether they make any sense given that me know how the
+% data was generated. 
+
+% you can also evaluate the log likelihood of another data set under
+% the model we have just fitted using the mfa_cl (for Calculate
+% Likelihood) function. For example, here we generate a test from the
+% same distribution. 
+
+
+X1=randn(300,5);
+X2=randn(200,5)+2;
+Xtest=[X1; X2];
+
+pause;		% Hit any key to continue 
+
+mfa_cl(Xtest,Lh,Ph,Mu,Pi)
+
+% we should expect the log likelihood of the test set to be lower than
+% that of the training set.
+
+% finally, we can also fit a regular factor analyzer using the ffa
+% function (Fast Factor Analysis)...
+
+pause;		% Hit any key to continue 
+
+[L,Ph,LL]=ffa(X,3);
+  
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Zoubin/rdiv.m b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/rdiv.m
new file mode 100644
index 00000000..3128061e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/rdiv.m
@@ -0,0 +1,25 @@
+% function Z=rdiv(X,Y)
+%
+% row division: Z = X / Y row-wise
+% Y must have one column 
+
+function Z=rdiv(X,Y)
+
+[N M]=size(X);
+[K L]=size(Y);
+if(N ~= K | L ~=1)
+  disp('Error in RDIV');
+  return;
+end
+
+Z=zeros(N,M);
+
+if M<N,
+  for m=1:M
+    Z(:,m)=X(:,m)./Y;
+  end
+else
+  for n=1:N
+    Z(n,:)=X(n,:)/Y(n);
+  end;
+end;
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Zoubin/rprod.m b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/rprod.m
new file mode 100644
index 00000000..95d3565d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/rprod.m
@@ -0,0 +1,15 @@
+% row product
+% function Z=rprod(X,Y)
+
+function Z=rprod(X,Y)
+
+if(length(X(:,1)) ~= length(Y(:,1)) | length(Y(1,:)) ~=1)
+  disp('Error in RPROD');
+  return;
+end
+
+Z=zeros(size(X));
+
+for i=1:length(X(1,:))
+  Z(:,i)=X(:,i).*Y;
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/Zoubin/rsum.m b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/rsum.m
new file mode 100644
index 00000000..0af53fde
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/Zoubin/rsum.m
@@ -0,0 +1,20 @@
+% row sum
+% function Z=rsum(X)
+
+function Z=rsum(X)
+
+[N M]=size(X);
+
+Z=zeros(N,1);
+
+if M==1,
+  Z=X;
+elseif M<2*N,
+  for m=1:M,
+    Z=Z+X(:,m);
+  end;
+else
+  for n=1:N
+    Z(n)=sum(X(n,:));
+  end;
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/brainy.m b/sourcecodes/bnt-master/BNT/examples/static/brainy.m
new file mode 100644
index 00000000..cf9a1623
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/brainy.m
@@ -0,0 +1,44 @@
+% Example of explaining away from
+% http://www.ai.mit.edu/~murphyk/Bayes/bnintro.html#explainaway
+%
+% Suppose you have to be brainy or smart to get into college.
+% B S P(C=1) P(C=2)  1=false 2=true
+% 1 1 1.0    0.0 
+% 2 1 0.0    1.0
+% 1 2 0.0    1.0
+% 2 2 0.0    1.0
+%
+%
+% If we observe that you are in college, you must be either brainy or sporty or both.
+% If we observre you are in college and sporty, it is less likely you are brainy, 
+% since brainy-ness and sporty-ness compete as causal explanations of the effect.
+
+% B  S
+%  \/
+%   C
+
+B = 1; S = 2; C = 3;
+dag = zeros(3,3);
+dag([B S], C)=1;
+ns = 2*ones(1,3);
+bnet = mk_bnet(dag, ns);
+bnet.CPD{B} = tabular_CPD(bnet, B, 'CPT', [0.5 0.5]');
+bnet.CPD{S} = tabular_CPD(bnet, S, 'CPT', [0.5 0.5]');
+CPT = zeros(2,2,2);
+CPT(1,1,:) = [1 0];
+CPT(2,1,:) = [0 1];
+CPT(1,2,:) = [0 1];
+CPT(2,2,:) = [0 1];
+bnet.CPD{C} = tabular_CPD(bnet, C, 'CPT', CPT);
+
+engine = jtree_inf_engine(bnet);
+ev = cell(1,3);
+ev{C} = 2;
+engine = enter_evidence(engine, ev);
+m = marginal_nodes(engine, B);
+fprintf('P(B=true|C=true) = %5.3f\n', m.T(2)) % 0.67
+
+ev{S} = 2;
+engine = enter_evidence(engine, ev);
+m = marginal_nodes(engine, B);
+fprintf('P(B=true|C=true,S=true) = %5.3f\n', m.T(2)) % 0.5 = unconditional baseline P(B=true)
diff --git a/sourcecodes/bnt-master/BNT/examples/static/burglar-alarm-net.lisp.txt b/sourcecodes/bnt-master/BNT/examples/static/burglar-alarm-net.lisp.txt
new file mode 100644
index 00000000..a48f48fb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/burglar-alarm-net.lisp.txt
@@ -0,0 +1,45 @@
+#|
+The following code represents the burglar alarm Bayes network from
+Chapter 14 of Russell & Norvig, 2nd Edition.  This network representation
+is used in the corresponding Bayes net code found in this directory.
+
+The conditional probability tables consist of the values listed here
+(along with the probabilities of the corresponding complementary events):
+
+P(Burglary = true) = 0.001    (=> P(Burglary = false) = 0.999)
+P(Earthquake = true) = 0.002  (=> P(Earthquake = false) = 0.998)
+
+P(Alarm = true | Burglary = true, Earthquake = true) = 0.95
+P(Alarm = true | Burglary = true, Earthquake = false) = 0.94
+P(Alarm = true | Burglary = false, Earthquake = true) = 0.29
+P(Alarm = true | Burglary = false, Earthquake = false) = 0.001
+
+P(JohnCalls = true | Alarm = true) = 0.90
+P(JohnCalls = true | Alarm = false) = 0.05
+
+P(MaryCalls = true | Alarm = true) = 0.70
+P(MaryCalls = true | Alarm = false) = 0.01
+|#
+
+(setf *burglar-alarm-net*
+      '((MaryCalls (true false)
+		   (Alarm)
+		   ((true) 0.70 0.30)
+		   ((false) 0.01 0.99))
+	(JohnCalls (true false)
+		   (Alarm)
+		   ((true) 0.90 0.10)
+		   ((false) 0.05 0.95))
+	(Alarm (true false)
+	       (Burglary Earthquake)
+	       ((true true) 0.95 0.05)
+	       ((true false) 0.94 0.06)
+	       ((false true) 0.29 0.71)
+	       ((false false) 0.001 0.999))
+	(Burglary (true false)
+		  ()
+		  (0.001 0.999))
+	(Earthquake (true false)
+		    ()
+		    (0.002 0.998))
+	))
diff --git a/sourcecodes/bnt-master/BNT/examples/static/burglary.m b/sourcecodes/bnt-master/BNT/examples/static/burglary.m
new file mode 100644
index 00000000..c93e144e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/burglary.m
@@ -0,0 +1,44 @@
+% Burglar alarm example
+
+N = 5;
+dag = zeros(N,N);
+E = 1; B = 2; R = 3; A = 4; C = 5;
+dag(E,[R A]) = 1;
+dag(B,A) = 1;
+dag(A,C)=1;
+
+% true = state 1, false = state 2
+ns = 2*ones(1,N); % binary nodes
+bnet = mk_bnet(dag, ns);
+
+bnet.CPD{E} = tabular_CPD(bnet, E, [0.1 0.9]);
+bnet.CPD{B} = tabular_CPD(bnet, B, [0.01 0.99]);
+%bnet.CPD{R} = tabular_CPD(bnet, R, [0.65 0.00001 0.35 0.99999]);
+bnet.CPD{R} = tabular_CPD(bnet, R, [0.65 0.01 0.35 0.99]);
+bnet.CPD{A} = tabular_CPD(bnet, A, [0.95 0.8 0.3 0.001 0.05 0.2 0.7 0.999]);
+bnet.CPD{C} = tabular_CPD(bnet, C, [0.7 0.05 0.3 0.95]);
+
+
+engine = jtree_inf_engine(bnet);
+ev  = cell(1,N);
+ev{C} = 1;
+engine = enter_evidence(engine, ev);
+mE = marginal_nodes(engine, E);
+mB = marginal_nodes(engine, B);
+fprintf('P(E|c)=%5.3f, P(B|c)=%5.3f\n', mE.T(1), mB.T(1))
+
+ev{C} = 1;
+ev{R} = 1;
+engine = enter_evidence(engine, ev);
+mE = marginal_nodes(engine, E);
+mB = marginal_nodes(engine, B);
+fprintf('P(E|c,r)=%5.3f, P(B|c,r)=%5.3f\n', mE.T(1), mB.T(1))
+
+
+if 0
+nsamples = 100;
+samples = zeros(nsamples, 5);
+for i=1:nsamples
+  samples(i,:) = cell2num(sample_bnet(bnet))';
+end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/cg1.m b/sourcecodes/bnt-master/BNT/examples/static/cg1.m
new file mode 100644
index 00000000..00821cc2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/cg1.m
@@ -0,0 +1,86 @@
+% Conditional Gaussian network
+% The waste incinerator emissions example from Lauritzen (1992),
+% "Propogation of Probabilities, Means and Variances in Mixed Graphical Association Models", 
+% JASA 87(420): 1098--1108
+%
+% This example is reprinted on p145 of "Probabilistic Networks and Expert Systems",
+% Cowell, Dawid, Lauritzen and Spiegelhalter, 1999, Springer.
+%
+% For a picture, see http://www.cs.berkeley.edu/~murphyk/Bayes/usage.html#cg_model
+
+ns = 2*ones(1,9);
+%bnet  = mk_incinerator_bnet(ns);
+bnet  = mk_incinerator_bnet;
+
+engines = {};
+%engines{end+1} = stab_cond_gauss_inf_engine(bnet);
+engines{end+1} = jtree_inf_engine(bnet);
+engines{end+1} = cond_gauss_inf_engine(bnet);
+nengines = length(engines);
+
+F = 1; W = 2; E = 3; B = 4; C = 5; D = 6; Min = 7; Mout = 8; L = 9;
+n = 9;
+dnodes = [B F W];
+cnodes = mysetdiff(1:n, dnodes);
+
+evidence = cell(1,n); % no evidence
+ll = zeros(1, nengines);
+for e=1:nengines
+  [engines{e}, ll(e)] = enter_evidence(engines{e}, evidence);
+end
+%assert(approxeq(ll(1), ll)))
+ll
+
+% Compare to the results in table on p1107.
+% These results are printed to 3dp in Cowell p150
+
+mu = zeros(1,n);
+sigma = zeros(1,n);
+dprob = zeros(1,n);
+addev = 1;
+tol = 1e-2;
+for e=1:nengines
+  for i=cnodes(:)'
+    m = marginal_nodes(engines{e}, i, addev);
+    mu(i) = m.mu;
+    sigma(i) = sqrt(m.Sigma);
+  end
+  for i=dnodes(:)'
+    m = marginal_nodes(engines{e}, i, addev);
+    dprob(i) = m.T(1);
+  end
+  assert(approxeq(mu([E D C L Min Mout]), [-3.25 3.04 -1.85 1.48 -0.214 2.83], tol))
+  assert(approxeq(sigma([E D C L Min Mout]), [0.709 0.770 0.507 0.631 0.459 0.860], tol))
+  assert(approxeq(dprob([B F W]), [0.85 0.95 0.29], tol))
+  %m = marginal_nodes(engines{e}, bnet.names('E'), addev);
+  %assert(approxeq(m.mu, -3.25, tol))
+  %assert(approxeq(sqrt(m.Sigma), 0.709, tol))
+end
+
+% Add evidence (p 1105, top right)
+evidence = cell(1,n);
+evidence{W} = 1; % industrial
+evidence{L} = 1.1;
+evidence{C} = -0.9;
+
+ll = zeros(1, nengines);
+for e=1:nengines
+  [engines{e}, ll(e)] = enter_evidence(engines{e}, evidence);
+end
+assert(all(approxeq(ll(1), ll)))
+
+for e=1:nengines
+  for i=cnodes(:)'
+    m = marginal_nodes(engines{e}, i, addev);
+    mu(i) = m.mu;
+    sigma(i) = sqrt(m.Sigma);
+  end
+  for i=dnodes(:)'
+    m = marginal_nodes(engines{e}, i, addev);
+    dprob(i) = m.T(1);
+  end
+  assert(approxeq(mu([E D C L Min Mout]), [-3.90 3.61 -0.9 1.1 0.5 4.11], tol))
+  assert(approxeq(sigma([E D C L Min Mout]), [0.076 0.326 0 0 0.1 0.344], tol))
+  assert(approxeq(dprob([B F W]), [0.0122 0.9995 1], tol))
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/cg2.m b/sourcecodes/bnt-master/BNT/examples/static/cg2.m
new file mode 100644
index 00000000..9d70bff2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/cg2.m
@@ -0,0 +1,11 @@
+% Conditional Gaussian network with vector-valued nodes and random params
+
+ns = 2*ones(1,9);
+bnet  = mk_incinerator_bnet(ns);
+
+engines = {};
+%engines{end+1} = stab_cond_gauss_inf_engine(bnet);
+engines{end+1} = jtree_inf_engine(bnet);
+engines{end+1} = cond_gauss_inf_engine(bnet);
+
+[err, time] = cmp_inference_static(bnet, engines, 'singletons_only', 1);
diff --git a/sourcecodes/bnt-master/BNT/examples/static/cmp_inference_static.m b/sourcecodes/bnt-master/BNT/examples/static/cmp_inference_static.m
new file mode 100644
index 00000000..4eeb22d8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/cmp_inference_static.m
@@ -0,0 +1,114 @@
+function [time, engine] = cmp_inference_static(bnet, engine, varargin)
+% CMP_INFERENCE Compare several inference engines on a BN
+% function [time, engine] = cmp_inference_static(bnet, engine, ...)
+%
+% engine{i} is the i'th inference engine.
+% time(e) = elapsed time for doing inference with engine e
+%
+% The list below gives optional arguments [default value in brackets].
+%
+% exact - specifies which engines do exact inference [ 1:length(engine) ]
+% singletons_only - if 1, we only call marginal_nodes, else this  and marginal_family [0]
+% maximize - 1 means we do max-propagation, 0 means sum-propagation [0]
+% check_ll - 1 means we check that the log-likelihoods are correct [1]
+% observed - list of the observed ndoes [ bnet.observed ]
+% check_converged - list of loopy engines that should be checked for convergence [ [] ]
+%    If an engine has converged, it is added to the exact list.
+
+
+% set default params
+exact = 1:length(engine);
+singletons_only = 0;
+maximize = 0;
+check_ll = 1;
+observed = bnet.observed;
+check_converged = [];
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'exact', exact = args{i+1};
+   case 'singletons_only', singletons_only = args{i+1};
+   case 'maximize', maximize = args{i+1};
+   case 'check_ll', check_ll = args{i+1};
+   case 'observed', observed = args{i+1};
+   case 'check_converged', check_converged = args{i+1};
+   otherwise,
+    error(['unrecognized argument ' args{i}])
+  end
+end
+
+E = length(engine);
+ref = exact(1); % reference
+
+N = length(bnet.dag);
+ev = sample_bnet(bnet);
+evidence = cell(1,N);
+evidence(observed) = ev(observed);
+%celldisp(evidence(observed))
+
+for i=1:E
+  tic;
+  if check_ll
+    [engine{i}, ll(i)] = enter_evidence(engine{i}, evidence, 'maximize', maximize);
+  else
+    engine{i} = enter_evidence(engine{i}, evidence, 'maximize', maximize);
+  end
+  time(i)=toc;
+end
+
+for i=check_converged(:)'
+  niter = loopy_converged(engine{i});
+  if niter > 0
+    fprintf('loopy engine %d  converged in %d iterations\n', i, niter);
+%    exact = myunion(exact, i);
+  else
+    fprintf('loopy engine %d has not converged\n', i);
+  end
+end
+
+cmp = exact(2:end);
+if check_ll
+  for i=cmp(:)'
+    assert(approxeq(ll(ref), ll(i)));
+  end
+end
+
+hnodes = mysetdiff(1:N, observed);
+
+if ~singletons_only
+  get_marginals(engine, hnodes, exact, 0);
+end
+get_marginals(engine, hnodes, exact, 1);
+
+%%%%%%%%%%
+
+function get_marginals(engine, hnodes, exact, singletons)
+
+bnet = bnet_from_engine(engine{1});
+N = length(bnet.dag);
+cnodes_bitv = zeros(1,N);
+cnodes_bitv(bnet.cnodes) = 1;
+ref = exact(1); % reference
+cmp = exact(2:end);
+E = length(engine);
+
+for n=hnodes(:)'
+  for e=1:E
+    if singletons
+      m{e} = marginal_nodes(engine{e}, n);
+    else
+      m{e} = marginal_family(engine{e}, n);
+    end
+  end
+  for e=cmp(:)'
+    if cnodes_bitv(n)
+      assert(approxeq(m{ref}.mu, m{e}.mu))
+      assert(approxeq(m{ref}.Sigma, m{e}.Sigma))
+    else
+      assert(approxeq(m{ref}.T, m{e}.T))
+    end
+    assert(isequal(m{e}.domain, m{ref}.domain));
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/discrete1.m b/sourcecodes/bnt-master/BNT/examples/static/discrete1.m
new file mode 100644
index 00000000..37761f37
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/discrete1.m
@@ -0,0 +1,40 @@
+% Compare various inference engines on the following network (from Jensen (1996) p84 fig 4.17)
+%    1
+%  / | \
+% 2  3  4
+% |  |  |
+% 5  6  7
+%  \/ \/
+%  8   9
+% where all arcs point downwards
+
+N = 9;
+dag = zeros(N,N);
+dag(1,2)=1; dag(1,3)=1; dag(1,4)=1;
+dag(2,5)=1; dag(3,6)=1; dag(4,7)=1;
+dag(5,8)=1; dag(6,8)=1; dag(6,9)=1; dag(7,9) = 1;
+
+dnodes = 1:N;
+false = 1; true = 2;
+ns = 2*ones(1,N); % binary nodes
+
+onodes = [2 7];
+bnet = mk_bnet(dag, ns, 'observed', onodes);
+% use random params
+for i=1:N
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+end
+
+query = [3];
+engine = {};
+engine{end+1} = jtree_inf_engine(bnet);
+engine{end+1} = var_elim_inf_engine(bnet);
+%engine{end+1} = global_joint_inf_engine(bnet);
+% global joint is designed for limids because does not normalize
+
+%engine{end+1} = enumerative_inf_engine(bnet);
+%engine{end+1} = jtree_onepass_inf_engine(bnet, query, onodes);
+
+maximize = 0;  % jtree_ndx crashes on max-prop
+[err, time] = cmp_inference_static(bnet, engine, 'maximize', maximize);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/discrete2.m b/sourcecodes/bnt-master/BNT/examples/static/discrete2.m
new file mode 100644
index 00000000..c7ca5f41
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/discrete2.m
@@ -0,0 +1,46 @@
+% Compare various inference engines on the following network (from Jensen (1996) p84 fig 4.17)
+%    1
+%  / | \
+% 2  3  4
+% |  |  |
+% 5  6  7
+%  \/ \/
+%  8   9
+% where all arcs point downwards
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+N = 9;
+dag = zeros(N,N);
+dag(1,2)=1; dag(1,3)=1; dag(1,4)=1;
+dag(2,5)=1; dag(3,6)=1; dag(4,7)=1;
+dag(5,8)=1; dag(6,8)=1; dag(6,9)=1; dag(7,9) = 1;
+
+dnodes = 1:N;
+false = 1; true = 2;
+ns = 2*ones(1,N); % binary nodes
+
+onodes = [2 4];
+bnet = mk_bnet(dag, ns, 'observed', onodes);
+% use random params
+for i=1:N
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+end
+
+%USEC = exist('@jtree_C_inf_engine/collect_evidence','file');
+query = [3];
+engine = {};
+engine{end+1} = jtree_inf_engine(bnet);
+engine{end+1} = jtree_sparse_inf_engine(bnet);
+%engine{end+1} = jtree_ndx_inf_engine(bnet, 'ndx_type', 'SD');
+%engine{end+1} = jtree_ndx_inf_engine(bnet, 'ndx_type', 'B');
+%engine{end+1} = jtree_ndx_inf_engine(bnet, 'ndx_type', 'D');
+%if USEC, engine{end+1} = jtree_C_inf_engine(bnet); end
+%engine{end+1} = var_elim_inf_engine(bnet);
+%engine{end+1} = enumerative_inf_engine(bnet);
+%engine{end+1} = jtree_onepass_inf_engine(bnet, query, onodes);
+
+maximize = 0;  % jtree_ndx crashes on max-prop
+[err, time] = cmp_inference_static(bnet, engine, 'maximize', maximize);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/discrete3.m b/sourcecodes/bnt-master/BNT/examples/static/discrete3.m
new file mode 100644
index 00000000..70164e86
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/discrete3.m
@@ -0,0 +1,43 @@
+% Compare various inference engines on the following network (from Jensen (1996) p84 fig 4.17)
+%    1
+%  / | \
+% 2  3  4
+% |  |  |
+% 5  6  7
+%  \/ \/
+%  8   9
+% where all arcs point downwards
+
+N = 9;
+dag = zeros(N,N);
+dag(1,2)=1; dag(1,3)=1; dag(1,4)=1;
+dag(2,5)=1; dag(3,6)=1; dag(4,7)=1;
+dag(5,8)=1; dag(6,8)=1; dag(6,9)=1; dag(7,9) = 1;
+
+dnodes = 1:N;
+false = 1; true = 2;
+ns = 2*ones(1,N); % binary nodes
+
+onodes = [1];
+evidence = cell(1,N);
+evidence(onodes) = num2cell(1);
+bnet = mk_bnet(dag, ns, 'observed', onodes);
+% use random params
+%for i=1:N
+%  bnet.CPD{i} = tabular_CPD(bnet, i);
+%end
+bnet.CPD{1} = tabular_CPD(bnet, 1, 'sparse', 1, 'CPT', [0.8, 0.2]);
+bnet.CPD{2} = tabular_CPD(bnet, 2, 'sparse', 1, 'CPT', [1 0 0 1]);
+bnet.CPD{3} = tabular_CPD(bnet, 3, 'sparse', 1, 'CPT', [0 1 1 0]);
+bnet.CPD{4} = tabular_CPD(bnet, 4, 'sparse', 1, 'CPT', [1 1 0 0]);
+bnet.CPD{5} = tabular_CPD(bnet, 5, 'sparse', 1, 'CPT', [0 0 1 1]);
+bnet.CPD{6} = tabular_CPD(bnet, 6, 'sparse', 1, 'CPT', [1 0 0 1]);
+bnet.CPD{7} = tabular_CPD(bnet, 7, 'sparse', 1, 'CPT', [0 1 1 0]);
+bnet.CPD{8} = tabular_CPD(bnet, 8, 'sparse', 1, 'CPT', [1 1 0 0 0 0 1 1]);
+bnet.CPD{9} = tabular_CPD(bnet, 9, 'sparse', 1, 'CPT', [0 1 0 1 1 0 1 0]);
+
+engine = jtree_sparse_inf_engine(bnet);
+tic
+[engine, ll] = enter_evidence(engine, evidence);
+toc
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/dtree/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/static/dtree/CVS/Entries
new file mode 100644
index 00000000..81dc9c31
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/dtree/CVS/Entries
@@ -0,0 +1,6 @@
+/test_housing.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/test_restaurants.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/test_zoo1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/tmp.dot/1.1.1.1/Wed May 29 15:59:54 2002//
+/transform_data_into_bnt_format.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/static/dtree/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/static/dtree/CVS/Repository
new file mode 100644
index 00000000..f45a3265
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/dtree/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/static/dtree
diff --git a/sourcecodes/bnt-master/BNT/examples/static/dtree/CVS/Root b/sourcecodes/bnt-master/BNT/examples/static/dtree/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/dtree/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/static/dtree/test_housing.m b/sourcecodes/bnt-master/BNT/examples/static/dtree/test_housing.m
new file mode 100644
index 00000000..40184b47
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/dtree/test_housing.m
@@ -0,0 +1,87 @@
+% Here the training data is adapted from UCI ML repository, 'housing' data
+% Input variables: 12 continous, one binary
+% Ouput variables: continous
+% The testing result trace is in the end of this script, it is same to the graph in page 219 of 
+% Leo Brieman etc. 1984 book titled "Classification and regression trees".
+
+dtreeCPD=tree_CPD;
+
+% load data
+fname = fullfile(BNT_HOME, 'examples', 'static', 'uci_data', 'housing', 'housing.data');
+data=load(fname);
+data=data';
+data=transform_data_into_bnt_format(data,[1:3,5:14]); 
+
+% learn decision tree from data 
+ns=1*ones(1,14);
+ns(4)=2;
+dtreeCPD1=learn_params(dtreeCPD,1:14,data,ns,[1:3,5:14],'stop_cases',5,'min_gain',0.006); 
+
+% evaluate on data
+[score,outputs]=evaluate_tree_performance(dtreeCPD1,1:14,data,ns,[1:3,5:14]);
+fprintf('Mean square deviation (using regression tree to predict) in old training data %6.3f\n',score);
+
+
+% show decision tree using graphpad
+% It should be easy, but still not implemented
+
+
+
+% >> test_housing
+% Create node 1 split at 6 gain  38.2205 Th 6.939000e+000. Mean  22.5328 Cases 506
+% Create node 2 split at 13 gain  14.4503 Th 1.437000e+001. Mean  19.9337 Cases 430
+% Create node 3 split at 8 gain   4.9809 Th 1.358000e+000. Mean  23.3498 Cases 255
+% Create node 4 split at 1 gain   0.7722 Th 1.023300e+001. Mean  45.5800 Cases 5
+% Create leaf node(samevalue) 5. Mean  50.0000 Std   0.0000 Cases 4 
+% Add subtree node 5 to 4. #nodes 5
+% Create leaf node(samevalue) 6. Mean  27.9000 Std   0.0000 Cases 1 
+% Add subtree node 6 to 4. #nodes 6
+% Add subtree node 4 to 3. #nodes 6
+% Create node 7 split at 6 gain   2.8497 Th 6.540000e+000. Mean  22.9052 Cases 250
+% Create node 8 split at 13 gain   0.5970 Th 7.560000e+000. Mean  21.6297 Cases 195
+% Create leaf node(nogain) 9. Mean  23.9698 Std   1.7568 Cases 43 
+% Add subtree node 9 to 8. #nodes 9
+% Create leaf node(nogain) 10. Mean  20.9678 Std   2.8242 Cases 152 
+% Add subtree node 10 to 8. #nodes 10
+% Add subtree node 8 to 7. #nodes 10
+% Create leaf node(nogain) 11. Mean  27.4273 Std   3.4512 Cases 55 
+% Add subtree node 11 to 7. #nodes 11
+% Add subtree node 7 to 3. #nodes 11
+% Add subtree node 3 to 2. #nodes 11
+% Create node 12 split at 1 gain   2.2467 Th 6.962150e+000. Mean  14.9560 Cases 175
+% Create node 13 split at 5 gain   0.5172 Th 5.240000e-001. Mean  17.1376 Cases 101
+% Create leaf node(nogain) 14. Mean  20.0208 Std   3.0672 Cases 24 
+% Add subtree node 14 to 13. #nodes 14
+% Create leaf node(nogain) 15. Mean  16.2390 Std   2.9746 Cases 77 
+% Add subtree node 15 to 13. #nodes 15
+% Add subtree node 13 to 12. #nodes 15
+% Create node 16 split at 5 gain   0.6133 Th 6.050000e-001. Mean  11.9784 Cases 74
+% Create leaf node(nogain) 17. Mean  16.6333 Std   4.5052 Cases 12 
+% Add subtree node 17 to 16. #nodes 17
+% Create leaf node(nogain) 18. Mean  11.0774 Std   3.0090 Cases 62 
+% Add subtree node 18 to 16. #nodes 18
+% Add subtree node 16 to 12. #nodes 18
+% Add subtree node 12 to 2. #nodes 18
+% Add subtree node 2 to 1. #nodes 18
+% Create node 19 split at 6 gain   6.0493 Th 7.420000e+000. Mean  37.2382 Cases 76
+% Create node 20 split at 1 gain   1.9900 Th 7.367110e+000. Mean  32.1130 Cases 46
+% Create node 21 split at 8 gain   0.6273 Th 1.877300e+000. Mean  33.3488 Cases 43
+% Create leaf node(samevalue) 22. Mean  45.6500 Std   6.1518 Cases 2 
+% Add subtree node 22 to 21. #nodes 22
+% Create leaf node(nogain) 23. Mean  32.7488 Std   3.5690 Cases 41 
+% Add subtree node 23 to 21. #nodes 23
+% Add subtree node 21 to 20. #nodes 23
+% Create leaf node(samevalue) 24. Mean  14.4000 Std   3.7363 Cases 3 
+% Add subtree node 24 to 20. #nodes 24
+% Add subtree node 20 to 19. #nodes 24
+% Create node 25 split at 1 gain   1.1001 Th 2.733970e+000. Mean  45.0967 Cases 30
+% Create leaf node(nogain) 26. Mean  45.8966 Std   4.4005 Cases 29 
+% Add subtree node 26 to 25. #nodes 26
+% Create leaf node(samevalue) 27. Mean  21.9000 Std   0.0000 Cases 1 
+% Add subtree node 27 to 25. #nodes 27
+% Add subtree node 25 to 19. #nodes 27
+% Add subtree node 19 to 1. #nodes 27
+% Mean square deviation (using regression tree to predict) in old training data  9.405
+% 
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/dtree/test_restaurants.m b/sourcecodes/bnt-master/BNT/examples/static/dtree/test_restaurants.m
new file mode 100644
index 00000000..9727847a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/dtree/test_restaurants.m
@@ -0,0 +1,98 @@
+% Here the training data is adapted from Russell95 book. See restaurant.names for description.
+% (1) Use infomation-gain as the split testing score, we get the the same decision tree as the book Russell 95 (page 537),
+% and the Gain(Patrons) is 0.5409, equal to the result in Page 541 of Russell 95. (see below output trace)
+% (Note: the dtree in that book has small compilation error, the Type node is from YES of Hungry node, not NO.)
+% (2) Use gain-ratio (Quilan 93), the splitting defavorite attribute with more values. (e.g. the Type attribute here)
+
+dtreeCPD=tree_CPD;
+
+% load data
+fname = fullfile(BNT_HOME, 'examples', 'static', 'uci_data', 'restaurant', 'restaurant.data');
+data=load(fname);
+data=data';
+
+%make the data be BNT compliant (values for discrete nodes are from 1-n, here n is the node size)
+  % e.g. if the values are [0 1 6], they must be mapping to [1 2 3]
+%data=transform_data(data,'tmp.dat',[]); %here no cts nodes
+
+% learn decision tree from data 
+ns=2*ones(1,11);
+ns(5:6)=3;
+ns(9:10)=4;
+dtreeCPD1=learn_params(dtreeCPD,1:11,data,ns,[]);
+
+% evaluate on data
+[score,outputs]=evaluate_tree_performance(dtreeCPD1,1:11,data,ns,[]);
+fprintf('Accuracy in training data %6.3f\n',score);
+
+% show decision tree using graphpad
+
+
+
+% --------------------------Output trace: using Information-Gain------------------------------
+% The splits are Patron, Hungry, Type, Fri/Sat
+% *********************************
+% Create node 1 split at 5 gain 0.5409 Th 0. Class 1 Cases 12 Error 6 
+% Create leaf node(onecla) 2. Class 1 Cases 2 Error 0 
+% Add subtree node 2 to 1. #nodes 2
+% Create leaf node(onecla) 3. Class 2 Cases 4 Error 0 
+% Add subtree node 3 to 1. #nodes 3
+% Create node 4 split at 4 gain 0.2516 Th 0. Class 1 Cases 6 Error 2 
+% Create leaf node(onecla) 5. Class 1 Cases 2 Error 0 
+% Add subtree node 5 to 4. #nodes 5
+% Create node 6 split at 9 gain 0.5000 Th 0. Class 1 Cases 4 Error 2 
+% Create leaf node(nullset) 7. Father 6 Class 1
+% Create node 8 split at 3 gain 1.0000 Th 0. Class 1 Cases 2 Error 1 
+% Create leaf node(onecla) 9. Class 1 Cases 1 Error 0 
+% Add subtree node 9 to 8. #nodes 9
+% Create leaf node(onecla) 10. Class 2 Cases 1 Error 0 
+% Add subtree node 10 to 8. #nodes 10
+% Add subtree node 8 to 6. #nodes 10
+% Create leaf node(onecla) 11. Class 2 Cases 1 Error 0 
+% Add subtree node 11 to 6. #nodes 11
+% Create leaf node(onecla) 12. Class 1 Cases 1 Error 0 
+% Add subtree node 12 to 6. #nodes 12
+% Add subtree node 6 to 4. #nodes 12
+% Add subtree node 4 to 1. #nodes 12
+% ********************************
+% 
+% Note:
+% ***Create node 4 split at 4 gain 0.2516 Th 0. Class 1 Cases 6 Error 2 
+% This mean we create a new node number 4, it is splitting at the attribute 4, and info-gain is 0.2516, 
+% "Th 0" means threshhold for splitting continous attribute, "Class 1" means the majority class at node 4 is 1,
+% and "Cases 6" means it has 6 cases attached to it, "Error 2" means it has two errors if changing the class lable of 
+% all the cases in it to the majority class.
+% *** Add subtree node 12 to 6. #nodes 12
+% It means we add the child node 12 to node 6.
+% *** Create leaf node(onecla) 10. Class 2 Cases 1 Error 0 
+% here 'onecla' means all cases in this node belong to one class, so no need to split further. 
+%      'nullset' means no training cases belong to this node, we use its parent node majority class as its class
+% 
+% 
+% 
+% ---------------Output trace: using GainRatio-----------------------
+% The splits are Patron, Hungry, Fri/Sat, Price
+% 
+% 
+% Create node 1 split at 5 gain 0.3707 Th 0. Class 1 Cases 12 Error 6 
+% Create leaf node(onecla) 2. Class 1 Cases 2 Error 0 
+% Add subtree node 2 to 1. #nodes 2
+% Create leaf node(onecla) 3. Class 2 Cases 4 Error 0 
+% Add subtree node 3 to 1. #nodes 3
+% Create node 4 split at 4 gain 0.2740 Th 0. Class 1 Cases 6 Error 2 
+% Create leaf node(onecla) 5. Class 1 Cases 2 Error 0 
+% Add subtree node 5 to 4. #nodes 5
+% Create node 6 split at 3 gain 0.3837 Th 0. Class 1 Cases 4 Error 2 
+% Create leaf node(onecla) 7. Class 1 Cases 1 Error 0 
+% Add subtree node 7 to 6. #nodes 7
+% Create node 8 split at 6 gain 1.0000 Th 0. Class 2 Cases 3 Error 1 
+% Create leaf node(onecla) 9. Class 2 Cases 2 Error 0 
+% Add subtree node 9 to 8. #nodes 9
+% Create leaf node(nullset) 10. Father 8 Class 2
+% Create leaf node(onecla) 11. Class 1 Cases 1 Error 0 
+% Add subtree node 11 to 8. #nodes 11
+% Add subtree node 8 to 6. #nodes 11
+% Add subtree node 6 to 4. #nodes 11
+% Add subtree node 4 to 1. #nodes 11
+% 
+% 
diff --git a/sourcecodes/bnt-master/BNT/examples/static/dtree/test_zoo1.m b/sourcecodes/bnt-master/BNT/examples/static/dtree/test_zoo1.m
new file mode 100644
index 00000000..23c258b3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/dtree/test_zoo1.m
@@ -0,0 +1,21 @@
+% Here the training data is adapted from UCI ML repository, 'zoo' data
+
+dtreeCPD=tree_CPD;
+
+% load data
+fname = fullfile(BNT_HOME, 'examples', 'static', 'uci_data', 'zoo', 'zoo1.data')
+data=load(fname);
+data=data';
+
+data=transform_data_into_bnt_format(data, []);
+
+% learn decision tree from data 
+ns=2*ones(1,17);
+ns(13)=6;
+ns(17)=7;
+dtreeCPD1=learn_params(dtreeCPD,1:17,data,ns,[],'stop_cases',5); % a node with less than 5 cases will not be splitted
+
+% evaluate on data
+[score,outputs]=evaluate_tree_performance(dtreeCPD1,1:17,data,ns,[]);
+fprintf('Accuracy in old training data %6.3f\n',score);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/dtree/tmp.dot b/sourcecodes/bnt-master/BNT/examples/static/dtree/tmp.dot
new file mode 100644
index 00000000..de359ea7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/dtree/tmp.dot
@@ -0,0 +1,31 @@
+digraph G {
+center = 1;
+size="4,4";
+n1 [ label = "1 :" ];
+n2 [ label = "2 :" ];
+n3 [ label = "3 :" ];
+n4 [ label = "4 :" ];
+n5 [ label = "5 :" ];
+n6 [ label = "6 :" ];
+n7 [ label = "7 :" ];
+n8 [ label = "8 :" ];
+n9 [ label = "9 :" ];
+n10 [ label = "10 :" ];
+n1 -> n5 [label="1.000"];
+n2 -> n7 [label="0.800"];
+n2 -> n10 [label="0.200"];
+n3 -> n2 [label="1.000"];
+n4 -> n8 [label="1.000"];
+n5 -> n3 [label="0.143"];
+n5 -> n5 [label="0.571"];
+n5 -> n8 [label="0.286"];
+n6 -> n4 [label="1.000"];
+n7 -> n6 [label="0.333"];
+n7 -> n9 [label="0.667"];
+n8 -> n1 [label="0.333"];
+n8 -> n5 [label="0.333"];
+n8 -> n10 [label="0.333"];
+n9 -> n2 [label="1.000"];
+n10 -> n9 [label="1.000"];
+
+}
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/examples/static/dtree/transform_data_into_bnt_format.m b/sourcecodes/bnt-master/BNT/examples/static/dtree/transform_data_into_bnt_format.m
new file mode 100644
index 00000000..92739590
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/dtree/transform_data_into_bnt_format.m
@@ -0,0 +1,66 @@
+function [bnt_data, old_values] = transform_data_into_bnt_format(data,cnodes)
+% TRANSFORM_DATA_TO_BNT_FORMAT Ensures discrete variables have values 1,2,..,k
+% e.g., if the values of a discrete are [0 1 6], they must be mapped to [1 2 3]
+%
+% data(i,j) is the value for i-th node in j-th case.
+% bnt_data(i,j) is the new value.
+% old_values{i} are the original values for node i.
+% cnodes is the list of all continous nodes, e.g. [3 5] means the 3rd and 5th node is continuous
+%
+% Author: yimin.zhang@intel.com
+% Last updated: Jan. 22, 2002 by Kevin Murphy.
+
+num_nodes=size(data,1);
+num_cases=size(data,2);
+old_values=cell(1,num_nodes);
+
+for i=1:num_nodes
+  if (myismember(i,cnodes)==1)  %cts nodes no need to be transformed 
+    %just copy the data
+    bnt_data(i,:)=data(i,:);
+    continue;
+  end
+  values = data(i,:);
+  sort_v = sort(values); 
+  %remove the duplicate values in sort_v
+  v_set = unique(sort_v);  
+  
+  %transform the values
+  for j=1:size(values,2)
+    index = binary_search(v_set,values(j));
+    if (index==-1)
+      fprintf('value not found in tranforming data to bnt format.\n');   
+      return;
+    end
+    bnt_data(i,j)=index;
+  end
+  old_values{i}=v_set;
+end
+
+
+%%%%%%%%%%%%
+
+function index=binary_search(vector, value)
+% BI_SEARCH do binary search for value in the vector
+% Author: yimin.zhang@intel.com
+% Last updated: Jan. 19, 2002
+
+begin_index=1;
+end_index=size(vector,2); 
+index=-1;
+while (begin_index<=end_index)
+  mid=floor((begin_index+end_index)/2);
+  if (isstr(vector(mid)))
+    % need to write a strcmp to return three result (< = >)
+  else
+    if (value==vector(mid))
+      index=mid;
+      return;
+    elseif (value>vector(mid))
+      begin_index=mid+1;    
+    else
+      end_index=mid-1;
+    end
+  end
+end
+return;
diff --git a/sourcecodes/bnt-master/BNT/examples/static/fa1.m b/sourcecodes/bnt-master/BNT/examples/static/fa1.m
new file mode 100644
index 00000000..7e131198
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/fa1.m
@@ -0,0 +1,57 @@
+% Factor analysis
+% Z -> X,  Z in R^k, X in R^D, k << D (high dimensional observations explained by small source)
+% Z ~ N(0,I),   X|Z ~ N(L z, Psi), where Psi is diagonal.
+%
+% We compare to Zoubin Ghahramani's code.
+
+state = 0;
+rand('seed', state);
+randn('seed', state);
+max_iter = 3;
+k = 2;
+D = 4;
+N = 10;
+X = randn(N, D);
+
+% Initialize as in Zoubin's ffa (fast factor analysis)
+X=X-ones(N,1)*mean(X);
+XX=X'*X/N;
+diagXX=diag(XX);
+cX=cov(X);
+scale=det(cX)^(1/D);
+randn('seed', 0);  % must reset seed here so initial params are identical to mfa
+L0=randn(D,k)*sqrt(scale/k);
+W0 = L0;
+Psi0=diag(cX);
+
+[L1, Psi1, LL1] = ffa(X,k,max_iter);
+
+
+ns = [k D];
+dag = zeros(2,2);
+dag(1,2) = 1;
+bnet = mk_bnet(dag, ns, 'discrete', [], 'observed', 2);
+bnet.CPD{1} = gaussian_CPD(bnet, 1, 'mean', zeros(k,1), 'cov', eye(k), 'cov_type', 'diag', ...
+			   'clamp_mean', 1, 'clamp_cov', 1);
+bnet.CPD{2} = gaussian_CPD(bnet, 2, 'mean', zeros(D,1), 'cov', diag(Psi0), 'weights', W0, ...
+			   'cov_type', 'diag', 'cov_prior_weight', 0, 'clamp_mean', 1);
+
+engine = jtree_inf_engine(bnet);
+evidence = cell(2,N);
+evidence(2,:) = num2cell(X', 1);
+
+[bnet2, LL2] = learn_params_em(engine, evidence, max_iter);
+
+s = struct(bnet2.CPD{2});
+L2 = s.weights;
+Psi2 = s.cov;
+
+
+
+% Compare to Zoubin's code
+assert(approxeq(LL2, LL1));
+assert(approxeq(Psi2, diag(Psi1)));
+assert(approxeq(L2, L1));
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/fgraph/CVS/Entries b/sourcecodes/bnt-master/BNT/examples/static/fgraph/CVS/Entries
new file mode 100644
index 00000000..0ed34e12
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/fgraph/CVS/Entries
@@ -0,0 +1,6 @@
+/fg1.m/1.1.1.1/Thu Jun 20 00:03:30 2002//
+/fg2.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/fg3.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/fg_mrf1.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/fg_mrf2.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/examples/static/fgraph/CVS/Repository b/sourcecodes/bnt-master/BNT/examples/static/fgraph/CVS/Repository
new file mode 100644
index 00000000..14dfb0d0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/fgraph/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/examples/static/fgraph
diff --git a/sourcecodes/bnt-master/BNT/examples/static/fgraph/CVS/Root b/sourcecodes/bnt-master/BNT/examples/static/fgraph/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/fgraph/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg1.m b/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg1.m
new file mode 100644
index 00000000..0b8adc47
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg1.m
@@ -0,0 +1,98 @@
+% make an unrolled HMM, convert to factor graph, and check that 
+% loopy propagation on the fgraph gives the exact answers.
+
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+T = 3;
+Q = 3;
+O = 3;
+cts_obs = 0;
+param_tying = 1;
+bnet = mk_hmm_bnet(T, Q, O, cts_obs, param_tying);
+
+data = sample_bnet(bnet);
+
+fgraph = bnet_to_fgraph(bnet);
+big_bnet = fgraph_to_bnet(fgraph);
+% converting factor graph back does not recover the structure of the original bnet
+
+max_iter = 2*T;
+
+engine = {};
+engine{1} = jtree_inf_engine(bnet);
+engine{2} = belprop_inf_engine(bnet, 'max_iter', max_iter);
+engine{3} = belprop_fg_inf_engine(fgraph, 'max_iter', max_iter);
+engine{4} = jtree_inf_engine(big_bnet);
+nengines = length(engine);
+
+big_engine = 4;
+fgraph_engine = 3;
+
+
+N = 2*T;
+evidence = cell(1,N);
+onodes = bnet.observed;
+evidence(onodes) = data(onodes);
+hnodes = mysetdiff(1:N, onodes);
+
+bigN = length(big_bnet.dag);
+big_evidence = cell(1, bigN);
+big_evidence(onodes) = data(onodes);
+big_evidence(N+1:end) = {1}; % factors are observed to be 1
+
+ll = zeros(1, nengines);
+for i=1:nengines
+  if i==big_engine
+    tic; [engine{i}, ll(i)] = enter_evidence(engine{i}, big_evidence); toc
+  else
+    tic; [engine{i}, ll(i)] = enter_evidence(engine{i}, evidence); toc
+  end
+end
+
+% compare all engines to engine{1}
+
+% the log likelihood values may be bogus...
+for i=2:nengines
+  %assert(approxeq(ll(1), ll(i)));
+end
+
+
+marg = zeros(T, nengines, Q); % marg(t,e,:)
+for t=1:T
+  for e=1:nengines
+    m = marginal_nodes(engine{e}, t);
+    marg(t,e,:) = m.T;
+  end
+end
+marg
+
+
+m = cell(nengines, T);
+for i=1:T
+  for e=1:nengines
+    m{e,i} = marginal_nodes(engine{e}, hnodes(i));
+  end
+  for e=2:nengines
+    assert(approxeq(m{e,i}.T, m{1,i}.T));
+  end
+end
+
+mpe = {};
+ll = zeros(1, nengines);
+for e=1:nengines
+  if e==big_engine
+    mpe{e} = find_mpe(engine{e}, big_evidence);
+    mpe{e} = mpe{e}(1:N); % chop off dummy nodes
+  else
+    mpe{e} = find_mpe(engine{e}, evidence);
+  end
+end
+
+% fgraph can't compute loglikelihood for software reasons
+% jtree on the big_bnet gives the wrong ll
+for e=2:nengines
+  %assert(approxeq(ll(1), ll(e)));
+  assert(approxeq(cell2num(mpe{1}), cell2num(mpe{e})))
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg2.m b/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg2.m
new file mode 100644
index 00000000..c982f0c7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg2.m
@@ -0,0 +1,104 @@
+% make a factor graph corresponding to an  HMM, where we absorb the evidence up front,
+% and then eliminate the observed nodes.
+% Compare this with not absorbing the evidence.
+
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+T = 3;
+Q = 3;
+O = 2;
+cts_obs = 0;
+param_tying = 1;
+bnet = mk_hmm_bnet(T, Q, O, cts_obs, param_tying);
+N = 2*T;
+onodes = bnet.observed;
+hnodes = mysetdiff(1:N, onodes);
+
+data = sample_bnet(bnet);
+
+init_factor = bnet.CPD{1};
+obs_factor = bnet.CPD{3};
+edge_factor = bnet.CPD{2}; % trans matrix
+
+nfactors = T;
+nvars = T; % hidden only
+G = zeros(nvars, nfactors);
+G(1,1) = 1;
+for t=1:T-1
+  G(t:t+1, t+1)=1;
+end
+
+node_sizes = Q*ones(1,T);
+
+% We tie params as follows:
+% the first hidden node use init_factor (number 1)
+% all hidden nodes on the backbone use edge_factor (number 2)
+% all observed nodes use the same factor, namely obs_factor
+
+small_fg = mk_fgraph_given_ev(G, node_sizes, {init_factor, edge_factor}, {obs_factor}, data(onodes), ...
+			 'equiv_class', [1 2*ones(1,T-1)], 'ev_equiv_class', ones(1,T));
+
+small_bnet = fgraph_to_bnet(small_fg);
+
+% don't pre-process evidence
+big_fg = bnet_to_fgraph(bnet);
+big_bnet = fgraph_to_bnet(big_fg);
+
+
+
+engine = {};
+engine{1} = jtree_inf_engine(bnet);
+engine{2} = belprop_fg_inf_engine(small_fg, 'max_iter', 2*T);
+engine{3} = jtree_inf_engine(small_bnet);
+engine{4} = belprop_fg_inf_engine(big_fg, 'max_iter', 3*T);
+engine{5} = jtree_inf_engine(big_bnet);
+nengines = length(engine);
+
+
+% on BN, use the original evidence
+evidence = cell(1, 2*T);
+evidence(onodes) = data(onodes);
+tic; [engine{1}, ll(1)] = enter_evidence(engine{1}, evidence); toc
+
+
+% on small_fg, we have already included the evidence
+evidence = cell(1,T);
+tic; [engine{2}, ll(2)] = enter_evidence(engine{2}, evidence); toc
+
+
+% on small_bnet, we must add evidence to the dummy nodes 
+V = small_fg.nvars;
+dummy = V+1:V+small_fg.nfactors;
+N = max(dummy);
+evidence = cell(1, N);
+evidence(dummy) = {1};
+tic; [engine{3}, ll(3)] = enter_evidence(engine{3}, evidence); toc
+
+
+% on big_fg, use the original evidence
+evidence = cell(1, 2*T);
+evidence(onodes) = data(onodes);
+tic; [engine{4}, ll(4)] = enter_evidence(engine{4}, evidence); toc
+
+
+% on big_bnet, we must add evidence to the dummy nodes
+V = big_fg.nvars;
+assert(V == 2*T);
+dummy = V+1:V+big_fg.nfactors;
+N = max(dummy);
+evidence = cell(1, N);
+evidence(onodes) = data(onodes);
+evidence(dummy) = {1};
+tic; [engine{5}, ll(5)] = enter_evidence(engine{5}, evidence); toc
+
+
+marg = zeros(T, nengines, Q); % marg(t,e,:)
+for t=1:T
+  for e=1:nengines
+    m = marginal_nodes(engine{e}, t);
+    marg(t,e,:) = m.T;
+  end
+end
+marg(:,:,1)
diff --git a/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg3.m b/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg3.m
new file mode 100644
index 00000000..ec3f28f2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg3.m
@@ -0,0 +1,83 @@
+% make a factor graph corresponding to an  HMM with Gaussian outputs, where we absorb the
+% evidence up front 
+
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+T = 3;
+Q = 3;
+O = 2;
+cts_obs = 1;
+param_tying = 1;
+bnet = mk_hmm_bnet(T, Q, O, cts_obs, param_tying);
+N = 2*T;
+onodes = bnet.observed;
+hnodes = mysetdiff(1:N, onodes);
+
+data = sample_bnet(bnet);
+
+init_factor = bnet.CPD{1};
+obs_factor = bnet.CPD{3};
+edge_factor = bnet.CPD{2}; % trans matrix
+
+nfactors = T;
+nvars = T; % hidden only
+G = zeros(nvars, nfactors);
+G(1,1) = 1;
+for t=1:T-1
+  G(t:t+1, t+1)=1;
+end
+
+node_sizes = Q*ones(1,T);
+
+% We tie params as follows:
+% the first hidden node use init_factor (number 1)
+% all hidden nodes on the backbone use edge_factor (number 2)
+% all observed nodes use the same factor, namely obs_factor
+
+small_fg = mk_fgraph_given_ev(G, node_sizes, {init_factor, edge_factor}, {obs_factor}, data(onodes), ...
+			 'equiv_class', [1 2*ones(1,T-1)], 'ev_equiv_class', ones(1,T));
+
+small_bnet = fgraph_to_bnet(small_fg);
+
+% don't pre-process evidence
+% big_fg = bnet_to_fgraph(bnet); % can't handle Gaussian node
+
+
+engine = {};
+engine{1} = jtree_inf_engine(bnet);
+engine{2} = belprop_fg_inf_engine(small_fg, 'max_iter', 2*T);
+engine{3} = jtree_inf_engine(small_bnet);
+nengines = length(engine);
+
+
+% on BN, use the original evidence
+evidence = cell(1, 2*T);
+evidence(onodes) = data(onodes);
+tic; [engine{1}, ll(1)] = enter_evidence(engine{1}, evidence); toc
+
+
+% on small_fg, we have already included the evidence
+evidence = cell(1,T);
+tic; [engine{2}, ll(2)] = enter_evidence(engine{2}, evidence); toc
+
+
+% on small_bnet, we must add evidence to the dummy nodes 
+V = small_fg.nvars;
+dummy = V+1:V+small_fg.nfactors;
+N = max(dummy);
+evidence = cell(1, N);
+evidence(dummy) = {1};
+tic; [engine{3}, ll(3)] = enter_evidence(engine{3}, evidence); toc
+
+
+
+marg = zeros(T, nengines, Q); % marg(t,e,:)
+for t=1:T
+  for e=1:nengines
+    m = marginal_nodes(engine{e}, t);
+    marg(t,e,:) = m.T;
+  end
+end
+marg(:,:,1)
diff --git a/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg_mrf1.m b/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg_mrf1.m
new file mode 100644
index 00000000..2e204a60
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg_mrf1.m
@@ -0,0 +1,113 @@
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+nrows = 3;
+ncols = 3;
+npixels = nrows*ncols;
+
+% we number pixels in transposed raster scan order (top to bottom, left to right)
+
+% hidden var
+HV = reshape(1:npixels, nrows, ncols);
+% observed var
+OV = reshape(1:npixels, nrows, ncols) + length(HV(:));
+
+% observed factor
+OF = reshape(1:npixels, nrows, ncols);
+% vertical edge factor VEF(i,j) is the factor for edge HV(i,j) - HV(i+1,j)
+VEF = reshape((1:(nrows-1)*ncols), nrows-1, ncols) + length(OF(:));
+% horizontal edge factor HEF(i,j) is the factor for edge HV(i,j) - HV(i,j+1)
+HEF = reshape((1:nrows*(ncols-1)), nrows, ncols-1) + length(OF(:)) + length(VEF(:));
+
+nvars = length(HV(:))+length(OV(:));
+assert(nvars == 2*npixels);
+nfac = length(OF(:)) + length(VEF(:)) + length(HEF(:));
+
+K = 2; % number of discrete values for the hidden vars
+%O = 1; % each observed pixel is a scalar
+O = 2; % each observed pixel is binary
+
+factors = cell(1,3);
+
+% hidden states generate observed 0 or 1 plus noise
+%factors{2} = cond_gauss1_kernel(K, O, 'mean', [0 1], 'cov', [0.1 0.1]);
+pnoise = 0.2;
+factors{1} = tabular_kernel([K O], [1-pnoise pnoise; pnoise 1-pnoise]);
+ofactor = 1;
+
+% encourage compatibility between neighboring vertical pixels
+factors{2} = tabular_kernel([K K], [0.8 0.2; 0.2 0.8]);
+vedge_factor = 2;
+
+%% no constraint between neighboring horizontal pixels
+%factors{3} = tabular_kernel([K K], [0.5 0.5; 0.5 0.5]);
+
+factors{3} = tabular_kernel([K K], [0.8 0.2; 0.2 0.8]);
+hedge_factor = 3;
+
+
+
+factor_ndx = zeros(1, 3);
+G = zeros(nvars, nfac);
+ns = [K*ones(1,length(HV(:))) O*ones(1,length(OV(:)))];
+
+N = length(ns);
+%cnodes = OV(:);
+cnodes = [];
+dnodes = 1:N;
+
+for i=1:nrows
+  for j=1:ncols
+    G([HV(i,j), OV(i,j)], OF(i,j)) = 1;
+    factor_ndx(OF(i,j)) = ofactor;
+
+    if i < nrows
+      G(HV(i:i+1,j), VEF(i,j)) = 1;
+      factor_ndx(VEF(i,j)) = vedge_factor;
+    end
+
+    if j < ncols
+      G(HV(i,j:j+1), HEF(i,j)) = 1;
+      factor_ndx(HEF(i,j)) = hedge_factor;
+    end
+
+  end
+end
+
+
+fg = mk_fgraph(G, ns, factors, 'discrete', dnodes, 'equiv_class', factor_ndx);
+
+if 1
+  % make image with vertical stripes
+  I = zeros(nrows, ncols);
+  for j=1:2:ncols
+    I(:,j) = 1;
+  end
+else
+  % make image with square in middle
+  I = zeros(nrows, ncols);
+  I(3:6,3:6) = 1;
+end
+
+  
+% corrupt image
+O = mod(I + (rand(nrows,ncols)> (1-pnoise)), 2);
+
+maximize = 1;
+engine = belprop_fg_inf_engine(fg, 'maximize', maximize, 'max_iter', npixels*5);
+
+evidence = cell(1, nvars);
+onodes = OV(:);
+evidence(onodes) = num2cell(O+1); % values must be in range {1,2}
+
+engine = enter_evidence(engine, evidence);
+
+for i=1:nrows
+  for j=1:ncols
+    m = marginal_nodes(engine, HV(i,j));
+    Ihat(i,j) = argmax(m.T)-1;
+  end
+end
+
+Ihat
diff --git a/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg_mrf2.m b/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg_mrf2.m
new file mode 100644
index 00000000..1f8981a0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/fgraph/fg_mrf2.m
@@ -0,0 +1,150 @@
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+
+nrows = 5;
+ncols = 5;
+npixels = nrows*ncols;
+
+% we number pixels in transposed raster scan order (top to bottom, left to right)
+
+% H(i,j) is the number of the hidden node at (i,j)
+H = reshape(1:npixels, nrows, ncols);
+% O(i,j) is the number of the obsevred node at (i,j)
+O = reshape(1:npixels, nrows, ncols) + length(H(:));
+
+
+% Make a Bayes net where each hidden pixel generates an observed pixel
+% but there are no connections between the hidden pixels.
+% We use this just to generate noisy versions of known images.
+N = 2*npixels;
+dag = zeros(N);
+for i=1:nrows
+  for j=1:ncols
+    dag(H(i,j), O(i,j)) = 1;
+  end
+end
+
+
+K = 2; % number of discrete values for the hidden vars
+ns = ones(N,1);
+ns(H(:)) = K;
+ns(O(:)) = 1;
+
+
+% make image with vertical stripes
+I = zeros(nrows, ncols);
+for j=1:2:ncols
+  I(:,j) = 1;
+end
+
+% each "hidden" node will be instantiated to the pixel in the known image
+% each observed node has conditional Gaussian distribution
+eclass = ones(1,N);
+%eclass(H(:)) = 1;
+%eclass(O(:)) = 2;
+eclass(H(:)) = 1:npixels;
+eclass(O(:)) = npixels+1;
+bnet = mk_bnet(dag, ns, 'discrete', H(:), 'equiv_class', eclass);
+
+
+%bnet.CPD{1} = tabular_CPD(bnet, H(1), 'CPT', normalise(ones(1,K)));
+for i=1:nrows
+  for j=1:ncols
+    bnet.CPD{H(i,j)} = root_CPD(bnet, H(i,j), I(i,j) + 1);
+  end
+end
+
+% If H(i,j)=1, O(i,j)=+1 plus noise
+% If H(i,j)=2, O(i,j)=-1 plus noise
+sigma = 0.5;
+bnet.CPD{eclass(O(1,1))} = gaussian_CPD(bnet, O(1,1), 'mean', [1 -1], 'cov', reshape(sigma*ones(1,K), [1 1 K]));
+ofactor = bnet.CPD{eclass(O(1,1))};
+%ofactor = gaussian_CPD('self', 2, 'dps', 1, 'cps', [], 'sz', [K O], 'mean', [1 -1], 'cov', reshape(sigma*ones(1,K), [1 1 K)));
+
+
+data = sample_bnet(bnet);
+img = reshape(data(O(:)), nrows, ncols)
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Now create MRF represented as a factor graph to try and recover the scene
+
+% VEF(i,j) is the number of the factor for the vertical edge between HV(i,j) - HV(i+1,j)
+VEF = reshape((1:(nrows-1)*ncols), nrows-1, ncols);
+% HEF(i,j) is the number of the factor for the horizontal edge between HV(i,j) - HV(i,j+1)
+HEF = reshape((1:nrows*(ncols-1)), nrows, ncols-1) + length(VEF(:));
+
+nvars = npixels;
+nfac = length(VEF(:)) + length(HEF(:));
+
+G = zeros(nvars, nfac);
+N = length(ns);
+eclass = zeros(1, nfac); % eclass(i)=j  means factor i gets its params from factors{j}
+vfactor_ndx = 1; % all vertcial edges get their params from factors{1}
+hfactor_ndx = 2; % all vertcial edges get their params from factors{2}
+for i=1:nrows
+  for j=1:ncols
+    if i < nrows
+      G(H(i:i+1,j), VEF(i,j)) = 1;
+      eclass(VEF(i,j)) = vfactor_ndx;
+    end
+    if j < ncols
+      G(H(i,j:j+1), HEF(i,j)) = 1;
+      eclass(HEF(i,j)) = hfactor_ndx;
+    end
+  end
+end
+
+
+% "kitten raised in cage" prior - more likely to see continguous vertical lines
+vfactor = tabular_kernel([K K], softeye(K, 0.9));
+hfactor = tabular_kernel([K K], softeye(K, 0.5));
+factors = cell(1,2);
+factors{vfactor_ndx} = vfactor;
+factors{hfactor_ndx} = hfactor;
+
+ev_eclass = ones(1,N); % every observation factor gets is params from ofactor
+ns = K*ones(1,nvars);
+%fg = mk_fgraph_given_ev(G, ns, factors, {ofactor}, num2cell(img), 'equiv_class', eclass, 'ev_equiv_class', ev_eclass);
+fg = mk_fgraph_given_ev(G, ns, factors, {ofactor}, img, 'equiv_class', eclass, 'ev_equiv_class', ev_eclass);
+
+bnet2 = fgraph_to_bnet(fg);
+
+% inference
+
+
+maximize = 1;
+
+engine = {};
+engine{1} = belprop_fg_inf_engine(fg, 'max_iter', npixels*2);
+engine{2} = jtree_inf_engine(bnet2);
+nengines = length(engine);
+
+% on fg, we have already included the evidence
+evidence = cell(1,npixels);
+tic; [engine{1}, ll(1)] = enter_evidence(engine{1}, evidence, 'maximize', maximize); toc
+
+
+% on bnet2, we must add evidence to the dummy nodes 
+V = fg.nvars;
+dummy = V+1:V+fg.nfactors;
+N = max(dummy);
+evidence = cell(1, N);
+evidence(dummy) = {1};
+tic; [engine{2}, ll(2)] = enter_evidence(engine{2}, evidence); toc
+
+
+Ihat = zeros(nrows, ncols, nengines);
+for e=1:nengines
+  for i=1:nrows
+    for j=1:ncols
+      m = marginal_nodes(engine{e}, H(i,j));
+      Ihat(i,j,e) = argmax(m.T)-1;
+    end
+  end
+end
+Ihat
diff --git a/sourcecodes/bnt-master/BNT/examples/static/gaussian1.m b/sourcecodes/bnt-master/BNT/examples/static/gaussian1.m
new file mode 100644
index 00000000..20bb3007
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/gaussian1.m
@@ -0,0 +1,34 @@
+% Make the following network (from Jensen (1996) p84 fig 4.17)
+%    1
+%  / | \
+% 2  3  4
+% |  |  |
+% 5  6  7
+%  \/ \/
+%  8   9
+% where all arcs point downwards
+
+
+N = 9;
+dag = zeros(N,N);
+dag(1,2)=1; dag(1,3)=1; dag(1,4)=1;
+dag(2,5)=1; dag(3,6)=1; dag(4,7)=1;
+dag(5,8)=1; dag(6,8)=1; dag(6,9)=1; dag(7,9) = 1;
+
+ns = [5 4 3 2 2 1 2 2 2]; % vector-valued nodes
+%ns = ones(1,9); % scalar nodes
+dnodes = [];
+
+bnet = mk_bnet(dag, ns, 'discrete', []);
+rand('state', 0);
+randn('state', 0);
+for i=1:N
+  bnet.CPD{i} = gaussian_CPD(bnet, i);
+end
+
+clear engine;
+engine{1} = gaussian_inf_engine(bnet);
+engine{2} = jtree_inf_engine(bnet);
+
+[err, time] = cmp_inference_static(bnet, engine);
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/gaussian2.m b/sourcecodes/bnt-master/BNT/examples/static/gaussian2.m
new file mode 100644
index 00000000..157a86cb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/gaussian2.m
@@ -0,0 +1,40 @@
+% Make the following network (from Jensen (1996) p84 fig 4.17)
+%    1
+%  / | \
+% 2  3  4
+% |  |  |
+% 5  6  7
+%  \/ \/
+%  8   9
+% where all arcs point downwards
+
+
+N = 9;
+dag = zeros(N,N);
+dag(1,2)=1; dag(1,3)=1; dag(1,4)=1;
+dag(2,5)=1; dag(3,6)=1; dag(4,7)=1;
+dag(5,8)=1; dag(6,8)=1; dag(6,9)=1; dag(7,9) = 1;
+
+ns = [5 4 3 2 2 1 2 2 2]; % vector-valued nodes
+%ns = ones(1,9); % scalar nodes
+dnodes = [];
+
+bnet = mk_bnet(dag, ns, 'discrete', []);
+rand('state', 0);
+randn('state', 0);
+for i=1:N
+  bnet.CPD{i} = gaussian_CPD(bnet, i);
+end
+
+clear engine;
+engine{1} = gaussian_inf_engine(bnet);
+engine{2} = jtree_inf_engine(bnet);
+
+[err, time] = cmp_inference_static(bnet, engine);
+
+Nsamples = 100;
+samples = cell(N, Nsamples);
+for s=1:Nsamples
+  samples(:,s) = sample_bnet(bnet);
+end
+bnet2 = learn_params(bnet, samples);
diff --git a/sourcecodes/bnt-master/BNT/examples/static/gibbs_test1.m b/sourcecodes/bnt-master/BNT/examples/static/gibbs_test1.m
new file mode 100644
index 00000000..7c961b3c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/gibbs_test1.m
@@ -0,0 +1,107 @@
+function gibbs_test1()
+
+disp('gibbs test 1')
+
+rand('state', 0);
+randn('state', 0);
+
+%[bnet onodes hnodes qnodes] = gibbs_ex_1;
+[bnet onodes hnodes qnodes] = gibbs_ex_2;
+
+je = jtree_inf_engine(bnet);
+ge = gibbs_sampling_inf_engine (bnet, 'T', 50, 'burnin', 0, ...
+				'order', [2 2 1 2 1]);
+
+ev = sample_bnet(bnet);
+
+evidence = cell(length(bnet.dag), 1);
+evidence(onodes) = ev(onodes);
+[je lj] = enter_evidence(je, evidence);
+[ge lg] = enter_evidence(ge, evidence);
+
+
+mj = marginal_nodes(je, qnodes);
+
+[mg ge] = marginal_nodes (ge, qnodes);
+for t = 1:100
+  [mg ge] = marginal_nodes (ge, qnodes, 'reset_counts', 0);
+  diff = mj.T - mg.T;
+  err(t) = norm (diff(:), 1);
+end
+clf
+plot(err);
+%title('error vs num. Gibbs samples')
+
+
+%%%%%%%
+
+function [bnet, onodes, hnodes, qnodes] = gibbs_ex_1
+% bnet = gibbs_ex_1
+% a simple network to test the gibbs sampling engine
+%    1
+%  / | \
+% 2  3  4
+% |  |  |
+% 5  6  7
+%  \/ \/
+%  8   9
+% where all arcs point downwards
+
+N = 9;
+dag = zeros(N,N);
+dag(1,2)=1; dag(1,3)=1; dag(1,4)=1;
+dag(2,5)=1; dag(3,6)=1; dag(4,7)=1;
+dag(5,8)=1; dag(6,8)=1; dag(6,9)=1; dag(7,9) = 1;
+
+onodes = 8:9;
+hnodes = 1:7;
+qnodes = [1 2 6];
+ns = [2 3 4 3 5 2 4 3 2];
+
+eclass = [1 2 3 2 4 5 6 7 8];
+
+bnet = mk_bnet (dag, ns, 'equiv_class', eclass);
+
+for i = 1:3
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+end
+
+for i = 4:8
+  bnet.CPD{i} = tabular_CPD(bnet, i+1);
+end
+
+
+
+%%%%%%%
+
+function [bnet, onodes, hnodes, qnodes] = gibbs_ex_2
+% bnet = gibbs_ex_2
+% a very simple network
+%
+% 1   2
+%  \ /
+%   3
+
+N = 3;
+dag = zeros(N,N);
+dag(1,3)=1; dag(2,3)=1;
+
+onodes = 3;
+hnodes = 1:2;
+qnodes = 1:2;
+ns = [2 4 3];
+
+eclass = [1 2 3];
+
+bnet = mk_bnet (dag, ns, 'equiv_class', eclass);
+
+for i = 1:3
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+end
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/learn1.m b/sourcecodes/bnt-master/BNT/examples/static/learn1.m
new file mode 100644
index 00000000..d2b7522b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/learn1.m
@@ -0,0 +1,86 @@
+% Lawn sprinker example from Russell and Norvig p454
+% See www.cs.berkeley.edu/~murphyk/Bayes/usage.html for details.
+
+N = 4; 
+dag = zeros(N,N);
+C = 1; S = 2; R = 3; W = 4;
+dag(C,[R S]) = 1;
+dag(R,W) = 1;
+dag(S,W)=1;
+
+false = 1; true = 2;
+ns = 2*ones(1,N); % binary nodes
+
+bnet = mk_bnet(dag, ns);
+bnet.CPD{C} = tabular_CPD(bnet, C, [0.5 0.5]);
+bnet.CPD{R} = tabular_CPD(bnet, R, [0.8 0.2 0.2 0.8]);
+bnet.CPD{S} = tabular_CPD(bnet, S, [0.5 0.9 0.5 0.1]);
+bnet.CPD{W} = tabular_CPD(bnet, W, [1 0.1 0.1 0.01 0 0.9 0.9 0.99]);
+
+CPT = cell(1,N);
+for i=1:N
+  s=struct(bnet.CPD{i});  % violate object privacy
+  CPT{i}=s.CPT;
+end
+
+% Generate training data
+nsamples = 50;
+samples = cell(N, nsamples);
+for i=1:nsamples
+  samples(:,i) = sample_bnet(bnet);
+end
+data = cell2num(samples);
+
+% Make a tabula rasa
+bnet2 = mk_bnet(dag, ns);
+seed = 0;
+rand('state', seed);
+bnet2.CPD{C} = tabular_CPD(bnet2, C, 'clamped', 1, 'CPT', [0.5 0.5], ...
+			   'prior_type', 'dirichlet', 'dirichlet_weight', 0);
+bnet2.CPD{R} = tabular_CPD(bnet2, R, 'prior_type', 'dirichlet', 'dirichlet_weight', 0);
+bnet2.CPD{S} = tabular_CPD(bnet2, S, 'prior_type', 'dirichlet', 'dirichlet_weight', 0);
+bnet2.CPD{W} = tabular_CPD(bnet2, W, 'prior_type', 'dirichlet', 'dirichlet_weight', 0);
+
+
+% Find MLEs from fully observed data
+bnet4 = learn_params(bnet2, samples);
+
+% Bayesian updating with 0 prior is equivalent to ML estimation
+bnet5 = bayes_update_params(bnet2, samples);
+
+CPT4 = cell(1,N);
+for i=1:N
+  s=struct(bnet4.CPD{i});  % violate object privacy
+  CPT4{i}=s.CPT;
+end
+
+CPT5 = cell(1,N);
+for i=1:N
+  s=struct(bnet5.CPD{i});  % violate object privacy
+  CPT5{i}=s.CPT;
+  assert(approxeq(CPT5{i}, CPT4{i}))
+end
+
+
+if 1
+% Find MLEs from partially observed data
+
+% hide 50% of the nodes
+samplesH = samples;
+hide = rand(N, nsamples) > 0.5;
+[I,J]=find(hide);
+for k=1:length(I)
+  samplesH{I(k), J(k)} = [];
+end
+
+engine = jtree_inf_engine(bnet2);
+max_iter = 5;
+[bnet6, LL] = learn_params_em(engine, samplesH, max_iter);
+
+CPT6 = cell(1,N);
+for i=1:N
+  s=struct(bnet6.CPD{i});  % violate object privacy
+  CPT6{i}=s.CPT;
+end
+
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/lw1.m b/sourcecodes/bnt-master/BNT/examples/static/lw1.m
new file mode 100644
index 00000000..a6a35577
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/lw1.m
@@ -0,0 +1,51 @@
+% Evaluate effectiveness of likelihood weighting on the lawn sprinkler example
+
+N = 4; 
+dag = zeros(N,N);
+C = 1; R = 2; S = 3; W = 4;
+dag(C,[R S]) = 1;
+dag(R,W) = 1;
+dag(S,W)=1;
+
+false = 1; true = 2;
+ns = 2*ones(1,N); % binary nodes
+
+bnet = mk_bnet(dag, ns);
+bnet.CPD{C} = tabular_CPD(bnet, C, [0.5 0.5]);
+bnet.CPD{R} = tabular_CPD(bnet, R, [0.8 0.2 0.2 0.8]);
+bnet.CPD{S} = tabular_CPD(bnet, S, [0.5 0.9 0.5 0.1]);
+bnet.CPD{W} = tabular_CPD(bnet, W, [1 0.1 0.1 0.01 0 0.9 0.9 0.99]);
+
+
+clear engine;
+engine{1} = jtree_inf_engine(bnet);
+engine{2} = likelihood_weighting_inf_engine(bnet);
+
+nengines = length(engine);
+m = cell(1, nengines);
+ll = zeros(1, nengines);
+
+evidence = cell(1,N);
+%evidence{C} = true; % evidence at the top is the easiest
+evidence{W} = true; % evidence at the bottom is the hardets
+
+query = [R];
+
+i=1;
+engine{i}  = enter_evidence(engine{i}, evidence);
+exact_m = marginal_nodes(engine{i}, query);
+
+i=2;
+samples = 100:100:500;
+err = zeros(1, length(samples));
+for j=1:length(samples)
+  nsamples = samples(j);
+  engine{i}  = enter_evidence(engine{i}, evidence, nsamples);
+  approx_m = marginal_nodes(engine{i}, query);
+  a1=approxeq(approx_m.T,exact_m.T,1e-1);
+  a2=approxeq(approx_m.T,exact_m.T,1e-2);
+  a3=approxeq(approx_m.T,exact_m.T,1e-3);
+  e = sum(abs(approx_m.T(:) - exact_m.T(:)));
+  fprintf('%d samples, 1dp %d, 2dp %d, 3dp %d,  err %f\n', nsamples, a1, a2, a3, e);
+  err(j) = e;
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/mfa1.m b/sourcecodes/bnt-master/BNT/examples/static/mfa1.m
new file mode 100644
index 00000000..17eb8667
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/mfa1.m
@@ -0,0 +1,80 @@
+% Factor analysis
+% Z -> X,  Z in R^k, X in R^D, k << D (high dimensional observations explained by small source)
+% Z ~ N(0,I),   X|Z ~ N(L z, Psi), where Psi is diagonal.
+%
+% Mixtures of FA
+% Now X|Z,W=i ~ N(mu(i) + L(i) Z, Psi(i))
+%
+% We compare to Zoubin Ghahramani's code.
+
+randn('state', 0);
+max_iter = 3;
+M = 2;
+k = 3;
+D = 5;
+
+n = 5;
+X1 = randn(n, D);
+X2 = randn(n, D) + 2; % move the mean to (2,2,2...)
+X = [X1; X2];
+N = size(X, 1);
+
+% initialise as in mfa
+tiny=exp(-700);
+mX = mean(X);
+cX=cov(X);
+scale=det(cX)^(1/D);
+randn('state',0); % must reset seed here so initial params are identical to mfa
+L0=randn(D*M,k)*sqrt(scale/k);
+W0 = permute(reshape(L0, [D M k]), [1 3 2]); % use D,K,M 
+Psi0=diag(cX)+tiny;
+Pi0=ones(M,1)/M;
+Mu0=randn(M,D)*sqrtm(cX)+ones(M,1)*mX;
+
+[Lh1, Ph1, Mu1, Pi1, LL1] = mfa(X,M,k,max_iter);
+Lh1 = permute(reshape(Lh1, [D M k]), [1 3 2]); % use D,K,M 
+
+
+ns = [M k D];
+dag = zeros(3);
+dag(1,3) = 1;
+dag(2,3) = 1;
+dnodes = 1;
+onodes = 3;
+
+bnet = mk_bnet(dag, ns, 'discrete', dnodes, 'observed', onodes);
+bnet.CPD{1} = tabular_CPD(bnet, 1, Pi0);
+
+%bnet.CPD{2} = gaussian_CPD(bnet, 2, zeros(k, 1), eye(k), [], 'diag', 'untied', 'clamp_mean',  'clamp_cov');
+
+bnet.CPD{2} = gaussian_CPD(bnet, 2, 'mean', zeros(k, 1), 'cov', eye(k), 'cov_type', 'diag', ...
+			   'cov_prior_weight', 0, 'clamp_mean', 1, 'clamp_cov', 1);
+
+%bnet.CPD{3} = gaussian_CPD(bnet, 3, Mu0', repmat(diag(Psi0), [1 1 M]), W0, 'diag', 'tied');
+
+bnet.CPD{3} = gaussian_CPD(bnet, 3, 'mean', Mu0', 'cov', repmat(diag(Psi0), [1 1 M]), ...
+			   'weights', W0, 'cov_type', 'diag', 'cov_prior_weight', 0, 'tied_cov', 1);
+
+engine = jtree_inf_engine(bnet);
+evidence = cell(3, N);
+evidence(3,:) = num2cell(X', 1);
+
+[bnet2, LL2, engine2] = learn_params_em(engine, evidence, max_iter);
+
+s = struct(bnet2.CPD{1});
+Pi2 = s.CPT(:);
+s = struct(bnet2.CPD{3});
+Mu2 = s.mean;
+W2 = s.weights;
+Sigma2 = s.cov;
+
+
+% Compare to Zoubin's code
+assert(approxeq(LL1,LL2));
+for i=1:M
+  assert(approxeq(W2(:,:,i), Lh1(:,:,i)));
+  assert(approxeq(Sigma2(:,:,i), diag(Ph1)));
+  assert(approxeq(Mu2(:,i), Mu1(i,:)));
+  assert(approxeq(Pi2(:), Pi1(:)));
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/mixexp1.m b/sourcecodes/bnt-master/BNT/examples/static/mixexp1.m
new file mode 100644
index 00000000..ee66610c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/mixexp1.m
@@ -0,0 +1,72 @@
+% Fit a piece-wise linear regression model.
+% Here is the model
+%
+%  X \
+%  | |
+%  Q |
+%  | /
+%  Y
+%
+% where all arcs point down.
+% We condition everything on X, so X is a root node. Q is a softmax, and Y is a linear Gaussian.
+% Q is hidden, X and Y are observed.
+
+X = 1;
+Q = 2;
+Y = 3;
+dag = zeros(3,3);
+dag(X,[Q Y]) = 1;
+dag(Q,Y) = 1;
+ns = [1 2 1]; % make X and Y scalars, and have 2 experts
+dnodes = [2];
+onodes = [1 3];
+bnet = mk_bnet(dag, ns, 'discrete', dnodes, 'observed', onodes);
+
+
+w = [-5 5];  % w(:,i) is the normal vector to the i'th decisions boundary
+b = [0 0];  % b(i) is the offset (bias) to the i'th decisions boundary
+
+mu = [0 0];
+sigma = 1;
+Sigma = repmat(sigma*eye(ns(Y)), [ns(Y) ns(Y) ns(Q)]);
+W = [-1 1];
+W2 = reshape(W, [ns(Y) ns(X) ns(Q)]);
+
+bnet.CPD{1} = root_CPD(bnet, 1);
+bnet.CPD{2} = softmax_CPD(bnet, 2, w, b);
+bnet.CPD{3} = gaussian_CPD(bnet, 3, 'mean', mu, 'cov', Sigma, 'weights', W2);
+
+
+
+% Check inference
+
+x = 0.1;
+ystar = 1;
+
+engine = jtree_inf_engine(bnet);
+[engine, loglik] = enter_evidence(engine, {x, [], ystar});
+Qpost = marginal_nodes(engine, 2);
+
+% eta(i,:) = softmax (gating) params for expert i
+eta = [b' w'];
+
+% theta(i,:) = regression vector for expert i
+theta = [mu' W'];
+
+% yhat(i) = E[y | Q=i, x] = prediction of i'th expert
+x1 = [1 x]';
+yhat = theta * x1;
+
+% gate_prior(i,:) = Pr(Q=i | x)
+gate_prior = normalise(exp(eta * x1));
+
+% cond_lik(i) = Pr(y | Q=i, x)
+cond_lik = (1/(sqrt(2*pi)*sigma)) * exp(-(0.5/sigma^2) * ((ystar - yhat) .* (ystar - yhat)));
+
+% gate_posterior(i,:) = Pr(Q=i | x, y)
+[gate_posterior, lik] = normalise(gate_prior .* cond_lik);
+
+assert(approxeq(gate_posterior(:), Qpost.T(:)));
+assert(approxeq(log(lik), loglik));
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/mixexp2.m b/sourcecodes/bnt-master/BNT/examples/static/mixexp2.m
new file mode 100644
index 00000000..6bcbc646
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/mixexp2.m
@@ -0,0 +1,104 @@
+% Fit a piece-wise linear regression model.
+% Here is the model
+%
+%  X \
+%  | |
+%  Q |
+%  | /
+%  Y
+%
+% where all arcs point down.
+% We condition everything on X, so X is a root node. Q is a softmax, and Y is a linear Gaussian.
+% Q is hidden, X and Y are observed.
+
+X = 1;
+Q = 2;
+Y = 3;
+dag = zeros(3,3);
+dag(X,[Q Y]) = 1;
+dag(Q,Y) = 1;
+ns = [1 2 1]; % make X and Y scalars, and have 2 experts
+dnodes = [2];
+onodes = [1 3];
+bnet = mk_bnet(dag, ns, 'discrete', dnodes, 'observed', onodes);
+
+IRLS_iter = 10;
+clamped = 0;
+
+bnet.CPD{1} = root_CPD(bnet, 1);
+
+if 0
+  % start with good initial params
+  w = [-5 5];  % w(:,i) is the normal vector to the i'th decisions boundary
+  b = [0 0];  % b(i) is the offset (bias) to the i'th decisions boundary
+  
+  mu = [0 0];
+  sigma = 1;
+  Sigma = repmat(sigma*eye(ns(Y)), [ns(Y) ns(Y) ns(Q)]);
+  W = [-1 1];
+  W2 = reshape(W, [ns(Y) ns(X) ns(Q)]);
+
+  bnet.CPD{2} = softmax_CPD(bnet, 2, w, b,  clamped, IRLS_iter);
+  bnet.CPD{3} = gaussian_CPD(bnet, 3, mu, Sigma, W2);
+else
+  % start with rnd initial params
+  rand('state', 0);
+  randn('state', 0);
+  bnet.CPD{2} = softmax_CPD(bnet, 2, 'clamped', clamped, 'max_iter', IRLS_iter);
+  bnet.CPD{3} = gaussian_CPD(bnet, 3);
+end
+
+
+
+load('C:/Users/jziebrth/Documents/data/BNW/BNT/bnt-master-octave/bnt-master/BNT/examples/static/Misc/mixexp_data.txt', '-ascii');        
+% Just use 1/10th of the data, to speed things up
+data = mixexp_data(1:10:end, :);
+%data = mixexp_data;
+ 
+%plot(data(:,1), data(:,2), '.')
+
+
+s = struct(bnet.CPD{2}); % violate object privacy
+%eta0 = [s.glim.b1; s.glim.w1]';
+eta0 = [s.glim{1}.b1; s.glim{1}.w1]';
+s = struct(bnet.CPD{3}); % violate object privacy
+W = reshape(s.weights, [1 2]);
+theta0 = [s.mean; W]';
+
+%figure(1)
+%mixexp_plot(theta0, eta0, data);
+%suptitle('before learning')
+
+ncases = size(data, 1);
+cases = cell(3, ncases);
+cases([1 3], :) = num2cell(data');
+
+engine = jtree_inf_engine(bnet);
+
+% log lik before learning
+ll = 0;
+for l=1:ncases
+  ev = cases(:,l);
+  [engine, loglik] = enter_evidence(engine, ev);
+  ll = ll + loglik;
+end
+
+% do learning
+max_iter = 5;
+[bnet2, LL2] = learn_params_em(engine, cases, max_iter);
+
+s = struct(bnet2.CPD{2});
+%eta2 = [s.glim.b1; s.glim.w1]';
+eta2 = [s.glim{1}.b1; s.glim{1}.w1]';
+s = struct(bnet2.CPD{3});
+W = reshape(s.weights, [1 2]);
+theta2 = [s.mean; W]';
+
+%figure(2)
+%mixexp_plot(theta2, eta2, data);
+%suptitle('after learning')
+
+fprintf('mixexp2: loglik before learning %f, after %d iters %f\n', ll, length(LL2),  LL2(end));
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/mixexp3.m b/sourcecodes/bnt-master/BNT/examples/static/mixexp3.m
new file mode 100644
index 00000000..a6ce1a4b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/mixexp3.m
@@ -0,0 +1,52 @@
+% Fit a piece-wise linear regression model.
+% Here is the model
+%
+%  X \
+%  | |
+%  Q |
+%  | /
+%  Y
+%
+% where all arcs point down.
+% We condition everything on X, so X is a root node. Q is a softmax, and Y is a linear Gaussian.
+% Q is hidden, X and Y are observed.
+
+X = 1;
+Q = 2;
+Y = 3;
+dag = zeros(3,3);
+dag(X,[Q Y]) = 1;
+dag(Q,Y) = 1;
+ns = [1 2 1]; % make X and Y scalars, and have 2 experts
+dnodes = [2];
+onodes = [1 3];
+bnet = mk_bnet(dag, ns, 'discrete', dnodes, 'observed', onodes);
+
+IRLS_iter = 10;
+clamped = 0;
+
+bnet.CPD{1} = root_CPD(bnet, 1);
+
+% start with good initial params
+w = [-5 5];  % w(:,i) is the normal vector to the i'th decisions boundary
+b = [0 0];  % b(i) is the offset (bias) to the i'th decisions boundary
+
+mu = [0 0];
+sigma = 1;
+Sigma = repmat(sigma*eye(ns(Y)), [ns(Y) ns(Y) ns(Q)]);
+W = [-1 1];
+W2 = reshape(W, [ns(Y) ns(X) ns(Q)]);
+
+bnet.CPD{2} = softmax_CPD(bnet, 2, w, b,  clamped, IRLS_iter);
+bnet.CPD{3} = gaussian_CPD(bnet, 3, 'mean', mu, 'cov', Sigma, 'weights', W2);
+
+
+engine = jtree_inf_engine(bnet);
+
+evidence = cell(1,3);
+evidence{X} = 0.68;
+
+engine = enter_evidence(engine, evidence);
+
+m = marginal_nodes(engine, Y);
+m.mu
diff --git a/sourcecodes/bnt-master/BNT/examples/static/mog1.m b/sourcecodes/bnt-master/BNT/examples/static/mog1.m
new file mode 100644
index 00000000..442f067b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/mog1.m
@@ -0,0 +1,81 @@
+% Fit a mixture of Gaussians using netlab and BNT
+
+rand('state', 0);
+randn('state', 0);
+
+% Q -> Y
+ncenters = 2; dim = 2;
+cov_type = 'full';
+
+% Generate the data from a mixture of 2 Gaussians
+%mu = randn(dim, ncenters);
+mu = zeros(dim, ncenters);
+mu(:,1) = [-1 -1]';
+mu(:,1) = [1 1]';
+Sigma = repmat(0.1*eye(dim),[1 1 ncenters]);
+ndat1 = 8; ndat2 = 8;
+%ndat1 = 2; ndat2 = 2;
+ndata = ndat1+ndat2;
+x1 = gsamp(mu(:,1), Sigma(:,:,1), ndat1);
+x2 = gsamp(mu(:,2), Sigma(:,:,2), ndat2);
+data = [x1; x2];
+%plot(x1(:,1),x1(:,2),'ro', x2(:,1),x2(:,2),'bx')
+
+% Fit using netlab
+max_iter = 3;
+mix = gmm(dim, ncenters, cov_type);
+options = foptions;
+options(1) = 1; % verbose
+options(14) = max_iter;
+
+% extract initial params
+%mix = gmminit(mix, x, options); % Initialize with K-means
+mu0 = mix.centres';
+pi0 = mix.priors(:);
+Sigma0 = mix.covars; % repmat(eye(dim), [1 1 ncenters]);
+
+[mix, options] = gmmem(mix, data, options);
+
+% Final params
+ll1 = options(8);
+mu1 = mix.centres';
+pi1 = mix.priors(:);
+Sigma1 = mix.covars;
+
+
+
+
+% BNT
+
+dag = zeros(2);
+dag(1,2) = 1;
+node_sizes = [ncenters dim];
+discrete_nodes = 1;
+onodes = 2;
+
+bnet = mk_bnet(dag, node_sizes, 'discrete', discrete_nodes, 'observed', onodes);
+bnet.CPD{1} = tabular_CPD(bnet, 1, pi0);
+bnet.CPD{2} = gaussian_CPD(bnet, 2, 'mean', mu0, 'cov', Sigma0, 'cov_type', cov_type, ...
+			   'cov_prior_weight', 0);
+
+engine = jtree_inf_engine(bnet);
+
+evidence = cell(2, ndata);
+evidence(2,:) = num2cell(data', 1);
+
+[bnet2, LL] = learn_params_em(engine, evidence, max_iter);
+
+ll2 = LL(end);
+s1 = struct(bnet2.CPD{1});
+pi2 = s1.CPT(:);
+
+s2 = struct(bnet2.CPD{2});
+mu2 = s2.mean;
+Sigma2 = s2.cov;
+
+% assert(approxeq(ll1, ll2)); % gmmem returns the value after the final M step, GMT before
+assert(approxeq(mu1, mu2));
+assert(approxeq(Sigma1, Sigma2))
+assert(approxeq(pi1, pi2))
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/mpe1.m b/sourcecodes/bnt-master/BNT/examples/static/mpe1.m
new file mode 100644
index 00000000..2d393c9a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/mpe1.m
@@ -0,0 +1,45 @@
+seed = 1;
+rand('state', seed);
+randn('state', seed);
+
+N = 4; 
+dag = zeros(N,N);
+C = 1; S = 2; R = 3; W = 4;
+dag(C,[R S]) = 1;
+dag(R,W) = 1;
+dag(S,W)=1;
+
+false = 1; true = 2;
+ns = 2*ones(1,N); % binary nodes
+
+bnet = mk_bnet(dag, ns);
+if 0
+  bnet.CPD{C} = tabular_CPD(bnet, C, [0.5 0.5]);
+  bnet.CPD{R} = tabular_CPD(bnet, R, [0.8 0.2 0.2 0.8]);
+  bnet.CPD{S} = tabular_CPD(bnet, S, [0.5 0.9 0.5 0.1]);
+  bnet.CPD{W} = tabular_CPD(bnet, W, [1 0.1 0.1 0.01 0 0.9 0.9 0.99]);
+else
+  for i=1:N, bnet.CPD{i} = tabular_CPD(bnet, i); end
+end
+
+
+
+evidence = cell(1,N);
+onodes = [1 3];
+data = sample_bnet(bnet);
+evidence(onodes) = data(onodes);
+
+clear engine;
+engine{1} = belprop_inf_engine(bnet);
+engine{2} = jtree_inf_engine(bnet);
+engine{3} = global_joint_inf_engine(bnet);
+engine{4} = var_elim_inf_engine(bnet);
+E = length(engine);
+
+clear mpe;
+for e=1:E
+  mpe{e} = find_mpe(engine{e}, evidence);
+end
+for e=2:E
+  assert(isequal(mpe{1}, mpe{e}))
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/mpe2.m b/sourcecodes/bnt-master/BNT/examples/static/mpe2.m
new file mode 100644
index 00000000..032cc0b1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/mpe2.m
@@ -0,0 +1,53 @@
+% Computing most probable explanation.
+
+% If you don't break ties consistently, loopy can give wrong mpe
+% even though the graph has no cycles, and even though the max-marginals are the same.
+% This example was contributed by Wentau Yih <wtyih@yahoo.com> 29 Jan 02.
+
+% define loop-free graph structure (all edges point down)
+%
+% Xe1   Xe2
+%  |    |
+%  E1   E2
+%    \ /
+%     R1
+%     |
+%    Xr1
+
+N = 6;
+dag = zeros(N,N);
+Xe1 = 1; Xe2 = 2; E1 = 3; E2 = 4; R1 = 5; Xr1 = 6;
+dag(Xe1, E1) = 1;
+dag(Xe2, E2) = 1;
+dag([E1 E2], R1) = 1;
+dag(R1, Xr1) = 1;
+
+node_sizes = [ 1 1 2 2 2 1 ];
+
+% create BN
+
+bnet = mk_bnet(dag, node_sizes, 'observed', [Xe1 Xe2 Xr1]);
+
+% fill in CPT
+
+bnet.CPD{Xe1} = tabular_CPD(bnet, Xe1, [1]);
+bnet.CPD{Xe2} = tabular_CPD(bnet, Xe2, [1]);
+bnet.CPD{E1} = tabular_CPD(bnet, E1, [0.2 0.8]);
+bnet.CPD{E2} = tabular_CPD(bnet, E2, [0.3 0.7]);
+bnet.CPD{R1} = tabular_CPD(bnet, R1, [1 1 1 0.8 0 0 0 0.2]);
+bnet.CPD{Xr1} = tabular_CPD(bnet, Xr1, [0.15 0.85]);
+
+clear engine;
+engine{1} = belprop_inf_engine(bnet);
+engine{2} = jtree_inf_engine(bnet);
+engine{3} = global_joint_inf_engine(bnet);
+engine{4} = var_elim_inf_engine(bnet);
+
+evidence = cell(1,N);
+evidence{Xe1} = 1;  evidence{Xe2} = 1;  evidence{Xr1} = 1;
+
+mpe = find_mpe(engine{1}, evidence, 'break_ties', 0) % gives wrong results
+mpe = find_mpe(engine{1}, evidence)
+for i=2:4
+  mpe = find_mpe(engine{i}, evidence)
+end
diff --git a/sourcecodes/bnt-master/BNT/examples/static/nodeorderExample.m b/sourcecodes/bnt-master/BNT/examples/static/nodeorderExample.m
new file mode 100644
index 00000000..165f3210
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/nodeorderExample.m
@@ -0,0 +1,68 @@
+% example to illustrate why nodes must be numbered topologically.
+% Due to Shinya OHTANI <ohtani@pdp.crl.sony.co.jp>
+% 9 June 2004
+
+%%%%%%%%% WRONG RESULTS because 2 -> 1 
+% should have P(parent|no evidence) = prior = [03. 0.7]
+
+node = struct('ChildNode', 1, ...
+               'ParentNode', 2);
+
+adjacency = zeros(2);
+adjacency([node.ParentNode], node.ChildNode) = 1;
+
+value = {{'TRUE'; 'FALSE'}, ...
+          {'TRUE'; 'FALSE'}};
+
+bnet = mk_bnet(adjacency, [2 2]);
+bnet.CPD{node.ChildNode} = tabular_CPD(bnet, node.ChildNode, [0.2 0.4 0.8 0.6]);
+bnet.CPD{node.ParentNode} = tabular_CPD(bnet, node.ParentNode, [0.3 0.7]);
+
+evidence = cell(1,2);
+% evidence{node.ChildNode} = 1;
+% evidence{node.ParentNode} = 1;
+
+engine = jtree_inf_engine(bnet);
+[engine, loglik] = enter_evidence(engine, evidence);
+
+
+marg = marginal_nodes(engine, node.ChildNode);
+disp(sprintf('    ChildNode     : %8.6f   %8.6f',marg.T(1),marg.T(2)) );
+marg = marginal_nodes(engine, node.ParentNode);
+disp(sprintf('    ParentNode    : %8.6f   %8.6f',marg.T(1),marg.T(2)) );
+
+% 
+%     ChildNode   : 0.534483   0.465517
+%     ParentNode  : 0.155172   0.844828
+% loglik = 0.15
+
+
+
+%%%%%%%%% RIGHT RESULTS because 1 -> 2
+
+node = struct('ChildNode', 2, ...
+               'ParentNode', 1);
+
+
+adjacency = zeros(2);
+adjacency([node.ParentNode], node.ChildNode) = 1;
+
+value = {{'TRUE'; 'FALSE'}, ...
+          {'TRUE'; 'FALSE'}};
+
+bnet = mk_bnet(adjacency, [2 2]);
+bnet.CPD{node.ChildNode} = tabular_CPD(bnet, node.ChildNode, [0.2 0.4 0.8 0.6]);
+bnet.CPD{node.ParentNode} = tabular_CPD(bnet, node.ParentNode, [0.3 0.7]);
+
+evidence = cell(1,2);
+% evidence{node.ChildNode} = 1;
+% evidence{node.ParentNode} = 1;
+
+engine = jtree_inf_engine(bnet);
+[engine, loglik] = enter_evidence(engine, evidence);
+
+
+marg = marginal_nodes(engine, node.ChildNode);
+disp(sprintf('    ChildNode     : %8.6f   %8.6f',marg.T(1),marg.T(2)) );
+marg = marginal_nodes(engine, node.ParentNode);
+disp(sprintf('    ParentNode    : %8.6f   %8.6f',marg.T(1),marg.T(2)) );
diff --git a/sourcecodes/bnt-master/BNT/examples/static/qmr1.m b/sourcecodes/bnt-master/BNT/examples/static/qmr1.m
new file mode 100644
index 00000000..a618fbb6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/qmr1.m
@@ -0,0 +1,112 @@
+% Make a QMR-like network 
+% This is a bipartite graph, where the top layer contains hidden disease nodes,
+% and the bottom later contains observed finding nodes.
+% The diseases have Bernoulli CPDs, the findings noisy-or CPDs.
+% See quickscore_inf_engine for references.
+
+pMax = 0.01;
+Nfindings = 10;
+Ndiseases = 5;
+%Nfindings = 20;
+%Ndiseases = 10;
+
+N=Nfindings+Ndiseases;
+findings = Ndiseases+1:N;
+diseases = 1:Ndiseases;
+
+G = zeros(Ndiseases, Nfindings);
+for i=1:Nfindings
+  v= rand(1,Ndiseases);
+  rents = find(v<0.8);
+  if (length(rents)==0)
+    rents=ceil(rand(1)*Ndiseases);
+  end
+  G(rents,i)=1;
+end       
+
+prior = pMax*rand(1,Ndiseases);
+leak = 0.5*rand(1,Nfindings); % in real QMR, leak approx exp(-0.02) = 0.98     
+%leak = ones(1,Nfindings); % turns off leaks, which makes inference much harder
+inhibit = rand(Ndiseases, Nfindings);
+inhibit(not(G)) = 1;
+
+
+% first half of findings are +ve, second half -ve
+% The very first and last findings are hidden
+pos = 2:floor(Nfindings/2);
+neg = (pos(end)+1):(Nfindings-1);
+
+% Make the bnet in the straightforward way
+tabular_leaves = 0;
+obs_nodes = myunion(pos, neg) + Ndiseases;
+big_bnet = mk_qmr_bnet(G, inhibit, leak, prior, tabular_leaves, obs_nodes);
+big_evidence = cell(1, N);
+big_evidence(findings(pos)) = num2cell(repmat(2, 1, length(pos)));
+big_evidence(findings(neg)) = num2cell(repmat(1, 1, length(neg)));
+
+%clf;draw_layout(big_bnet.dag);
+%filename = '../public_html/Bayes/Figures/qmr.rnd.jpg';
+%% 3x3 inches
+%set(gcf,'units','inches');
+%set(gcf,'PaperPosition',[0 0 3 3])  
+%print(gcf,'-djpeg','-r100',filename);
+
+
+% Marginalize out hidden leaves apriori
+positive_leaves_only = 1;
+[bnet, vals] = mk_minimal_qmr_bnet(G, inhibit, leak, prior, pos, neg, positive_leaves_only);
+obs_nodes = bnet.observed;
+evidence = cell(1, Ndiseases + length(obs_nodes));
+evidence(obs_nodes) = num2cell(vals);
+
+
+clear engine;
+engine{1} = quickscore_inf_engine(inhibit, leak, prior);
+engine{2} = jtree_inf_engine(big_bnet);
+engine{3} = jtree_inf_engine(bnet);
+
+%fname = '/home/cs/murphyk/matlab/Misc/loopybel.txt';
+global BNT_HOME
+fname = sprintf('%s/loopybel.txt', BNT_HOME);
+
+
+max_iter = 6;
+engine{4} = pearl_inf_engine(bnet, 'protocol', 'parallel', 'max_iter', max_iter);
+%engine{5} = belprop_inf_engine(bnet, 'max_iter', max_iter, 'filename', fname);
+engine{5} = belprop_inf_engine(bnet, 'max_iter', max_iter);
+
+E = length(engine);
+exact = 1:3;
+loopy = [4 5];
+
+ll = zeros(1,E);
+tic; engine{1} = enter_evidence(engine{1}, pos, neg); toc
+tic; [engine{2}, ll(2)] = enter_evidence(engine{2}, big_evidence); toc
+tic; [engine{3}, ll(3)] = enter_evidence(engine{3}, evidence); toc
+tic; [engine{4}, ll(4), niter(4)] = enter_evidence(engine{4}, evidence); toc
+tic; [engine{5}, niter(5)] = enter_evidence(engine{5}, evidence); toc
+
+ll
+
+post = zeros(E, Ndiseases);
+for e=1:E
+  for i=diseases(:)'
+    m = marginal_nodes(engine{e}, i);
+    post(e, i) = m.T(2);
+  end
+end
+
+for e=exact(:)'
+  for i=diseases(:)'
+    assert(approxeq(post(1, i), post(e, i)));
+  end
+end
+
+a = zeros(Ndiseases, 2);
+for ei=1:length(loopy)
+  for i=diseases(:)'
+    a(i,ei) = approxeq(post(1, i), post(loopy(ei), i));
+  end
+end
+disp('is the loopy posterior correct?');
+disp(a)
diff --git a/sourcecodes/bnt-master/BNT/examples/static/qmr2.m b/sourcecodes/bnt-master/BNT/examples/static/qmr2.m
new file mode 100644
index 00000000..921cf57e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/qmr2.m
@@ -0,0 +1,77 @@
+% Test jtree_compiled on a toy QMR network.
+
+rand('state', 0);
+randn('state', 0);
+pMax = 0.01;
+Nfindings = 10;
+Ndiseases = 5;
+
+N=Nfindings+Ndiseases;
+findings = Ndiseases+1:N;
+diseases = 1:Ndiseases;
+
+G = zeros(Ndiseases, Nfindings);
+for i=1:Nfindings
+  v= rand(1,Ndiseases);
+  rents = find(v<0.8);
+  if (length(rents)==0)
+    rents=ceil(rand(1)*Ndiseases);
+  end
+  G(rents,i)=1;
+end       
+
+prior = pMax*rand(1,Ndiseases);
+leak = 0.5*rand(1,Nfindings); % in real QMR, leak approx exp(-0.02) = 0.98     
+%leak = ones(1,Nfindings); % turns off leaks, which makes inference much harder
+inhibit = rand(Ndiseases, Nfindings);
+inhibit(not(G)) = 1;
+
+% first half of findings are +ve, second half -ve
+% The very first and last findings are hidden
+pos = 2:floor(Nfindings/2);
+neg = (pos(end)+1):(Nfindings-1);
+
+big = 1;
+
+if big
+  % Make the bnet in the straightforward way
+  tabular_leaves = 1;
+  obs_nodes = myunion(pos, neg) + Ndiseases;
+  bnet = mk_qmr_bnet(G, inhibit, leak, prior, tabular_leaves, obs_nodes);
+  evidence = cell(1, N);
+  evidence(findings(pos)) = num2cell(repmat(2, 1, length(pos)));
+  evidence(findings(neg)) = num2cell(repmat(1, 1, length(neg)));
+else
+  % Marginalize out hidden leaves apriori
+  positive_leaves_only = 1;
+  [bnet, vals] = mk_minimal_qmr_bnet(G, inhibit, leak, prior, pos, neg, positive_leaves_only);
+  obs_nodes = bnet.observed;
+  evidence = cell(1, Ndiseases + length(obs_nodes));
+  evidence(obs_nodes) = num2cell(vals);
+end
+
+engine = {};
+engine{end+1} = jtree_inf_engine(bnet);
+
+E = length(engine);
+exact = 1:E;
+ll = zeros(1,E);
+for e=1:E
+  tic; [engine{e}, ll(e)] = enter_evidence(engine{e}, evidence); toc
+end
+
+assert(all(approxeq(ll(exact), ll(exact(1)))))
+
+post = zeros(E, Ndiseases);
+for e=1:E
+  for i=diseases(:)'
+    m = marginal_nodes(engine{e}, i);
+    post(e, i) = m.T(2);
+  end
+end
+for e=exact(:)'
+  for i=diseases(:)'
+    assert(approxeq(post(1, i), post(e, i)));
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/sample1.m b/sourcecodes/bnt-master/BNT/examples/static/sample1.m
new file mode 100644
index 00000000..46dcdb1e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/sample1.m
@@ -0,0 +1,34 @@
+% Check sampling on a mixture of experts model
+%
+%  X \
+%  | |
+%  Q |
+%  | /
+%  Y
+%
+% where all arcs point down.
+% We condition everything on X, so X is a root node. Q is a softmax, and Y is a linear Gaussian.
+% Q is hidden, X and Y are observed.
+
+X = 1;
+Q = 2;
+Y = 3;
+dag = zeros(3,3);
+dag(X,[Q Y]) = 1;
+dag(Q,Y) = 1;
+ns = [1 2 2];
+dnodes = [2];
+bnet = mk_bnet(dag, ns, dnodes);
+
+x = 0.5;
+bnet.CPD{1} = root_CPD(bnet, 1, x);
+bnet.CPD{2} = softmax_CPD(bnet, 2);
+bnet.CPD{3} = gaussian_CPD(bnet, 3);
+
+data_case = sample_bnet(bnet, 'evidence', {0.8, [], []})
+ll = log_lik_complete(bnet, data_case)
+
+data_case = sample_bnet(bnet, 'evidence', {-11, [], []})
+ll = log_lik_complete(bnet, data_case)
+
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/softev1.m b/sourcecodes/bnt-master/BNT/examples/static/softev1.m
new file mode 100644
index 00000000..5af7ba22
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/softev1.m
@@ -0,0 +1,60 @@
+% Check that adding soft evidence to a hidden node is equivalent to evaluating its leaf CPD.
+
+% Make an HMM
+T = 3; Q = 2; O = 2; cts_obs = 0; param_tying = 0;
+bnet = mk_hmm_bnet(T, Q, O, cts_obs, param_tying);
+N = 2*T;
+onodes = bnet.observed;
+hnodes = mysetdiff(1:N, onodes);
+for i=1:N
+  bnet.CPD{i} = tabular_CPD(bnet, i);
+end
+
+ev = sample_bnet(bnet);
+evidence = cell(1,N);
+evidence(onodes) = ev(onodes);
+
+engine = jtree_inf_engine(bnet);
+
+[engine, ll] = enter_evidence(engine, evidence);
+query = 1;
+m = marginal_nodes(engine, query);
+
+
+% Make a Markov chain with the same backbone
+bnet2 = mk_markov_chain_bnet(T, Q);
+for i=1:T
+  S = struct(bnet.CPD{hnodes(i)}); % violate object privacy
+  bnet2.CPD{i} = tabular_CPD(bnet2, i, S.CPT);
+end
+
+% Evaluate the observed leaves of the HMM
+soft_ev = cell(1,T);
+for i=1:T
+  S = struct(bnet.CPD{onodes(i)}); % violate object privacy
+  dist = S.CPT(:, evidence{onodes(i)});
+  soft_ev{i} = dist;
+end
+
+% Use the leaf potentials as soft evidence
+engine2 = jtree_inf_engine(bnet2);
+[engine2, ll2] = enter_evidence(engine2, cell(1,T), 'soft', soft_ev);
+m2 = marginal_nodes(engine2, query);
+
+assert(approxeq(m2.T, m.T))
+assert(approxeq(ll2, ll))
+
+
+
+% marginal on node 1 without evidence
+[engine2, ll2] = enter_evidence(engine2, cell(1,T));
+m2 = marginal_nodes(engine2, 1);
+
+% add soft evidence
+soft_ev=cell(1,T);
+soft_ev{1}=[0.7 0.3]; 
+[engine2, ll2] = enter_evidence(engine2, cell(1,T), 'soft', soft_ev);
+m3 = marginal_nodes(engine2, 1);
+
+assert(approxeq(normalise(m2.T .* [0.7 0.3]'), m3.T))
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/softmax1.m b/sourcecodes/bnt-master/BNT/examples/static/softmax1.m
new file mode 100644
index 00000000..06434549
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/softmax1.m
@@ -0,0 +1,109 @@
+% Check that softmax works with a simple classification demo.
+% Based on netlab's demglm2
+% X -> Q where X is an input node, and Q is a softmax
+
+rand('state', 0);
+randn('state', 0);
+  
+% Check inference
+
+input_dim = 2;
+num_classes = 3;
+IRLS_iter = 3;
+
+net = glm(input_dim, num_classes, 'softmax');
+
+dag = zeros(2);
+dag(1,2) = 1;
+discrete_nodes = [2];
+bnet = mk_bnet(dag, [input_dim num_classes], 'discrete', discrete_nodes, 'observed', 1);
+bnet.CPD{1} = root_CPD(bnet, 1);
+clamped = 0;
+bnet.CPD{2} = softmax_CPD(bnet, 2, net.w1, net.b1, clamped, IRLS_iter);
+
+engine = jtree_inf_engine(bnet);
+
+x = rand(1, input_dim);
+q = glmfwd(net, x);
+
+[engine, ll] = enter_evidence(engine, {x, []});
+m = marginal_nodes(engine, 2);
+assert(approxeq(m.T(:), q(:)));
+
+
+% Check learning
+% We use EM, but in fact there is no hidden data.
+% The M step will call IRLS on the softmax node.
+
+% Generate data from three classes in 2d
+input_dim = 2;
+num_classes = 3;
+
+% Fix seeds for reproducible results
+randn('state', 42);
+rand('state', 42);
+
+ndata = 10;
+% Generate mixture of three Gaussians in two dimensional space
+data = randn(ndata, input_dim);
+targets = zeros(ndata, 3);
+
+% Priors for the clusters
+prior(1) = 0.4;
+prior(2) = 0.3;
+prior(3) = 0.3;
+
+% Cluster centres
+c = [2.0, 2.0; 0.0, 0.0; 1, -1];
+
+ndata1 = prior(1)*ndata;
+ndata2 = (prior(1) + prior(2))*ndata;
+% Put first cluster at (2, 2)
+data(1:ndata1, 1) = data(1:ndata1, 1) * 0.5 + c(1,1);
+data(1:ndata1, 2) = data(1:ndata1, 2) * 0.5 + c(1,2);
+targets(1:ndata1, 1) = 1;
+
+% Leave second cluster at (0,0)
+data((ndata1 + 1):ndata2, :) = ...
+  data((ndata1 + 1):ndata2, :);
+targets((ndata1+1):ndata2, 2) = 1;
+
+data((ndata2+1):ndata, 1) = data((ndata2+1):ndata,1) *0.6 + c(3, 1);
+data((ndata2+1):ndata, 2) = data((ndata2+1):ndata,2) *0.6 + c(3, 2);
+targets((ndata2+1):ndata, 3) = 1;
+
+
+if 0
+  ndata = 1;
+  data = x;
+  targets = [1 0 0];
+end
+
+options = foptions;
+options(1) = -1; % verbose
+options(14) = IRLS_iter;
+[net2, options2] = glmtrain(net, options, data, targets);
+net2.ll = options2(8); % type 'help foptions' for details
+
+cases = cell(2, ndata);
+for l=1:ndata
+  q = find(targets(l,:)==1);
+  x = data(l,:);
+  cases{1,l} = x(:);
+  cases{2,l} = q;
+end
+
+max_iter = 2; % we have complete observability, so 1 iter is enough
+[bnet2, ll2] = learn_params_em(engine, cases, max_iter);
+
+w = get_field(bnet2.CPD{2},'weights');
+b = get_field(bnet2.CPD{2},'offset')';
+
+w
+net2.w1
+
+b
+net2.b1
+
+% assert(approxeq(net2.ll, ll2)); % glmtrain returns ll after final M step, learn_params before
+
diff --git a/sourcecodes/bnt-master/BNT/examples/static/sprinkler1.m b/sourcecodes/bnt-master/BNT/examples/static/sprinkler1.m
new file mode 100644
index 00000000..f021cf46
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/examples/static/sprinkler1.m
@@ -0,0 +1,112 @@
+% Lawn sprinker example from Russell and Norvig p454
+% For a picture, see http://www.cs.berkeley.edu/~murphyk/Bayes/usage.html#basics
+
+N = 4; 
+dag = zeros(N,N);
+C = 1; S = 2; R = 3; W = 4;
+dag(C,[R S]) = 1;
+dag(R,W) = 1;
+dag(S,W)=1;
+
+false = 1; true = 2;
+ns = 2*ones(1,N); % binary nodes
+
+%bnet = mk_bnet(dag, ns);
+bnet = mk_bnet(dag, ns, 'names', {'cloudy','S','R','W'}, 'discrete', 1:4);
+names = bnet.names;
+%C = names{'cloudy'};
+bnet.CPD{C} = tabular_CPD(bnet, C, [0.5 0.5]);
+bnet.CPD{R} = tabular_CPD(bnet, R, [0.8 0.2 0.2 0.8]);
+bnet.CPD{S} = tabular_CPD(bnet, S, [0.5 0.9 0.5 0.1]);
+bnet.CPD{W} = tabular_CPD(bnet, W, [1 0.1 0.1 0.01 0 0.9 0.9 0.99]);
+
+
+CPD{C} = reshape([0.5 0.5], 2, 1);
+CPD{R} = reshape([0.8 0.2 0.2 0.8], 2, 2);
+CPD{S} = reshape([0.5 0.9 0.5 0.1], 2, 2);
+CPD{W} = reshape([1 0.1 0.1 0.01 0 0.9 0.9 0.99], 2, 2, 2);
+joint = zeros(2,2,2,2);
+for c=1:2
+  for r=1:2
+    for s=1:2
+      for w=1:2
+	joint(c,s,r,w) = CPD{C}(c) * CPD{S}(c,s) * CPD{R}(c,r) * ...
+	    CPD{W}(s,r,w);
+      end
+    end
+  end
+end
+
+joint2 = repmat(reshape(CPD{C}, [2 1 1 1]), [1 2 2 2]) .* ...
+	 repmat(reshape(CPD{S}, [2 2 1 1]), [1 1 2 2]) .* ...
+	 repmat(reshape(CPD{R}, [2 1 2 1]), [1 2 1 2]) .* ...
+	 repmat(reshape(CPD{W}, [1 2 2 2]), [2 1 1 1]);
+
+assert(approxeq(joint, joint2));
+
+
+engine = jtree_inf_engine(bnet);
+
+evidence = cell(1,N);
+evidence{W} = true;
+
+[engine, ll] = enter_evidence(engine, evidence);
+
+m = marginal_nodes(engine, S);
+p1 = m.T(true) % P(S=true|W=true) = 0.4298
+lik1 = exp(ll); % P(W=true) = 0.6471
+assert(approxeq(p1, 0.4298));
+assert(approxeq(lik1, 0.6471));
+
+pSandW = sumv(joint(:,true,:,true), [C R]); % P(S,W) = sum_cr P(CSRW)
+pW = sumv(joint(:,:,:,true), [C S R]);
+pSgivenW = pSandW / pW; % P(S=t|W=t) = P(S=t,W=t)/P(W=t)
+assert(approxeq(pW, lik1))
+assert(approxeq(pSgivenW, p1))
+
+
+m = marginal_nodes(engine, R);
+p2 = m.T(true)  % P(R=true|W=true) =  0.7079     
+
+pRandW = sumv(joint(:,:,true,true), [C S]); % P(R,W) = sum_cr P(CSRW)
+pRgivenW = pRandW / pW; % P(R=t|W=t) = P(R=t,W=t)/P(W=t)
+assert(approxeq(pRgivenW, p2))
+
+
+% Add extra evidence that R=true
+evidence{R} = true;
+
+[engine, ll] = enter_evidence(engine, evidence);
+
+m = marginal_nodes(engine, S);
+p3 = m.T(true) % P(S=true|W=true,R=true) = 0.1945 
+assert(approxeq(p3, 0.1945))
+
+
+pSandRandW = sumv(joint(:,true,true,true), [C]); % P(S,R,W) = sum_c P(cSRW)
+pRandW = sumv(joint(:,:,true,true), [C S]); % P(R,W) = sum_cs P(cSRW)
+pSgivenWR = pSandRandW / pRandW; % P(S=t|W=t,R=t) = P(S=t,R=t,W=t)/P(W=t,R=t)
+assert(approxeq(pSgivenWR, p3))
+
+% So the sprinkler is less likely to be on if we know that
+% it is raining, since the rain can "explain away" the fact
+% that the grass is wet.
+
+lik3 = exp(ll); % P(W=true, R=true) = 0.4581
+% So the combined evidence is less likely (of course)
+
+
+
+
+% Joint distributions
+
+evidence = cell(1,N);
+[engine, ll] = enter_evidence(engine, evidence);
+m = marginal_nodes(engine, [S R W]);
+
+evidence{R} = 2;
+[engine, ll] = enter_evidence(engine, evidence);
+m = marginal_nodes(engine, [S R W]);
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/general/CVS/Entries b/sourcecodes/bnt-master/BNT/general/CVS/Entries
new file mode 100644
index 00000000..de13cc9a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/CVS/Entries
@@ -0,0 +1,50 @@
+/add_ev_to_dmarginal.m/1.1.1.1/Thu Jun 27 20:34:32 2002//
+/add_evidence_to_gmarginal.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/bnet_to_fgraph.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/compute_fwd_interface.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/compute_interface_nodes.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/compute_joint_pot.m/1.1.1.1/Mon Jun  7 15:50:34 2004//
+/compute_minimal_interface.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/convert_dbn_CPDs_to_pots.m/1.1.1.1/Fri Nov 22 22:35:00 2002//
+/convert_dbn_CPDs_to_tables.m/1.1.1.1/Thu Jan 23 18:44:50 2003//
+/convert_dbn_CPDs_to_tables1.m/1.1.1.1/Thu Jan 23 18:49:48 2003//
+/convert_dbn_CPDs_to_tables_slow.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/dbn_to_bnet.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/dbn_to_hmm.m/1.1.1.1/Sun Feb  2 00:23:38 2003//
+/determine_elim_constraints.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/dispcpt.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/do_intervention.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/dsep.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/dsep_test.m/1.1.1.1/Sat Jan 18 23:10:16 2003//
+/enumerate_scenarios.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/fgraph_to_bnet.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/hodbn_to_bnet.m/1.1.1.1/Wed Jul 24 14:48:06 2002//
+/is_mnet.m/1.1.1.1/Sun Jun 16 20:01:22 2002//
+/linear_gaussian_to_cpot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/log_lik_complete.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/log_marg_lik_complete.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_bnet.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_dbn.m/1.1.1.1/Sat Feb  1 19:42:14 2003//
+/mk_fgraph.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_fgraph_given_ev.m/1.1.1.1/Mon Jun 24 18:56:26 2002//
+/mk_higher_order_dbn.m/1.1.1.1/Tue Jul 23 13:17:04 2002//
+/mk_limid.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_mnet.m/1.1.1.1/Sun Jun 16 19:52:12 2002//
+/mk_mrf2.m/1.1.1.1/Tue Dec 31 22:06:48 2002//
+/mk_mutilated_samples.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_named_CPT.m/1.1.1.1/Tue Mar 30 17:18:54 2004//
+/mk_slice_and_half_dbn.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/noisyORtoTable.m/1.1.1.1/Mon Aug  2 22:05:58 2004//
+/partition_dbn_nodes.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/partition_matrix_vec_3.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/sample_bnet.m/1.1.1.1/Thu Jun 10 01:17:46 2004//
+/sample_bnet_nocell.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/sample_dbn.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/score_bnet_complete.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/shrink_obs_dims_in_gaussian.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/shrink_obs_dims_in_table.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/solve_limid.m/1.1.1.1/Mon Jun  7 15:48:02 2004//
+/unroll_dbn_topology.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/unroll_higher_order_topology.m/1.1.1.1/Fri May 31 10:25:58 2002//
+/unroll_set.m/1.1.1.1/Mon Dec 16 17:57:14 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/general/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/general/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/general/CVS/Repository b/sourcecodes/bnt-master/BNT/general/CVS/Repository
new file mode 100644
index 00000000..08dc139c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/general
diff --git a/sourcecodes/bnt-master/BNT/general/CVS/Root b/sourcecodes/bnt-master/BNT/general/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/general/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/general/Old/CVS/Entries
new file mode 100644
index 00000000..a1785ca4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/Old/CVS/Entries
@@ -0,0 +1,9 @@
+/bnet_to_gdl_graph.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/calc_mpe.m/1.1.1.1/Mon Jun 17 21:58:38 2002//
+/calc_mpe_bucket.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/calc_mpe_dbn.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/calc_mpe_given_inf_engine.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/calc_mpe_global.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/compute_interface_nodes.m/1.1.1.1/Wed May 29 15:59:54 2002//
+/mk_gdl_graph.m/1.1.1.1/Wed May 29 15:59:54 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/general/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/general/Old/CVS/Repository
new file mode 100644
index 00000000..46960c1c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/general/Old
diff --git a/sourcecodes/bnt-master/BNT/general/Old/CVS/Root b/sourcecodes/bnt-master/BNT/general/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/general/Old/bnet_to_gdl_graph.m b/sourcecodes/bnt-master/BNT/general/Old/bnet_to_gdl_graph.m
new file mode 100644
index 00000000..d6ff45f3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/Old/bnet_to_gdl_graph.m
@@ -0,0 +1,18 @@
+function gdl = bnet_to_gdl_graph(bnet)
+% BNET_TO_GDL_GRAPH Convert a Bayesian network to a GDL graph
+% gdl = bnet_to_gdl_graph(bnet)
+%
+% Each node in the BN gets converted to a single node in the GDL graph,
+% representing its family; its kernel function is the corresponding CPD.
+
+N = length(bnet.dag);
+doms = cell(1,N);
+for i=1:N
+  doms{i} = family(bnet.dag, i);
+end
+
+U = mk_undirected(bnet.dag);
+gdl = mk_gdl_graph(U, doms, bnet.node_sizes, bnet.CPD, 'equiv_class', bnet.equiv_class, ...
+		   'discrete', bnet.dnodes, 'chance', bnet.chance_nodes, ...
+		   'decision', bnet.decision_nodes, 'utility', bnet.utility_nodes);
+
diff --git a/sourcecodes/bnt-master/BNT/general/Old/calc_mpe.m b/sourcecodes/bnt-master/BNT/general/Old/calc_mpe.m
new file mode 100644
index 00000000..5f55e708
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/Old/calc_mpe.m
@@ -0,0 +1,58 @@
+function [mpe, ll] = calc_mpe(engine, evidence, break_ties)
+% CALC_MPE Computes the most probable explanation of the evidence
+% [mpe, ll] = calc_mpe_given_inf_engine(engine, evidence, break_ties)
+%
+% INPUT
+% engine must support max-propagation
+% evidence{i} is the observed value of node i, or [] if hidden
+% break_ties is optional. If 1, we will force ties to be broken consistently
+%  by calling enter_evidence N times.
+%
+% OUTPUT
+% mpe{i} is the most likely value of node i (cell array!)
+% ll is the log-likelihood of the globally best assignment
+%
+% This currently only works when all hidden nodes are discrete
+
+if nargin < 3, break_ties = 0; end
+
+
+[engine, ll] = enter_evidence(engine, evidence, 'maximize', 1);
+
+observed = ~isemptycell(evidence);
+
+if 0 % fgraphs don't support bnet_from_engine
+onodes = find(observed);
+bnet = bnet_from_engine(engine);
+pot_type = determine_pot_type(bnet, onodes);
+assert(pot_type == 'd');
+end
+
+scalar = 1;
+evidence = evidence(:); % hack to handle unrolled DBNs
+N = length(evidence);
+mpe = cell(1,N);
+for i=1:N
+  m = marginal_nodes(engine, i);
+  % observed nodes are all set to 1 inside the inference engine, so we must undo this
+  if observed(i)
+    mpe{i} = evidence{i};
+  else
+    mpe{i} = argmax(m.T);
+    % Bug fix by Ron Zohar, 8/15/01
+    % If there are ties, we must break them as follows (see Jensen96, p106)
+    if break_ties
+      evidence{i} = mpe{i};                             
+      [engine, ll] = enter_evidence(engine, evidence, 'maximize', 1);  
+    end
+  end
+  if length(mpe{i}) > 1, scalar = 0; end
+end
+
+if nargout >= 2
+  bnet = bnet_from_engine(engine);
+  ll = log_lik_complete(bnet, mpe(:));
+end
+if 0 % scalar
+  mpe = cell2num(mpe);
+end
diff --git a/sourcecodes/bnt-master/BNT/general/Old/calc_mpe_bucket.m b/sourcecodes/bnt-master/BNT/general/Old/calc_mpe_bucket.m
new file mode 100644
index 00000000..40602725
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/Old/calc_mpe_bucket.m
@@ -0,0 +1,160 @@
+function [mpe, ll] = calc_mpe_bucket(bnet, new_evidence, max_over)
+%
+% PURPOSE:
+%       CALC_MPE Computes the most probable explanation to the network nodes
+%       given the evidence.
+%       
+%       [mpe, ll] = calc_mpe(engine, new_evidence, max_over)
+%
+% INPUT:
+%       bnet  - the bayesian network
+%       new_evidence - optional, if specified - evidence to be incorporated [cell(1,n)]
+%       max_over - optional, if specified determines the variable elimination order [1:n]
+%
+% OUTPUT:
+%       mpe - the MPE assignmet for the net variables (or [] if no satisfying assignment)
+%       ll - log assignment probability.
+%
+% Notes:
+% 1. Adapted from '@var_elim_inf_engine\marginal_nodes' for MPE by Ron Zohar, 8/7/01
+% 2. Only discrete potentials are supported at this time.
+% 3. Complexity: O(nw*) where n is the number of nodes and w* is the induced tree width.
+% 4. Implementation based on:
+%  - R. Dechter, "Bucket Elimination: A Unifying Framework for Probabilistic Inference", 
+%                 UA1 96, pp. 211-219.
+
+
+ns = bnet.node_sizes;
+n = length(bnet.dag);
+evidence = cell(1,n);
+if (nargin<2)
+    new_evidence = evidence;
+end
+
+onodes = find(~isemptycell(new_evidence));  % observed nodes
+hnodes = find(isemptycell(new_evidence));  % hidden nodes
+pot_type = determine_pot_type(bnet, onodes);
+
+if pot_type ~= 'd'
+  error('only disrete potentials supported at this time')    
+end
+
+for i=1:n
+  fam = family(bnet.dag, i);
+  CPT{i} = convert_to_pot(bnet.CPD{bnet.equiv_class(i)}, pot_type, fam(:), evidence);        
+end 
+
+% handle observed nodes: set impossible cases' probability to zero
+% rather than prun matrix (this makes backtracking easier)
+
+for ii=onodes
+  lIdx = 1:ns(ii);
+  lIdx = setdiff(lIdx, new_evidence{ii});
+  
+  sCPT=struct(CPT{ii});  % violate object privacy
+  
+  sargs = '';
+  for jj=1:(length(sCPT.domain)-1)
+    sargs = [sargs, ':,']; 
+  end        
+  for jj=lIdx
+    eval(['sCPT.T(', sargs, num2str(jj), ')=0;']);
+  end
+  CPT{ii}=dpot(sCPT.domain, sCPT.sizes, sCPT.T);        
+end
+
+B = cell(1,n); 
+for b=1:n
+  B{b} = mk_initial_pot(pot_type, [], [], [], []);
+end
+
+if (nargin<3)
+  max_over = (1:n);
+end   
+order = max_over; % no attempt to optimize this
+
+
+% Initialize the buckets with the CPDs assigned to them
+for i=1:n
+  b = bucket_num(domain_pot(CPT{i}), order);
+  B{b} = multiply_pots(B{b}, CPT{i});
+end
+
+% Do backward phase
+max_over = max_over(length(max_over):-1:1); % reverse
+for i=max_over(1:end-1)        
+  % max-ing over variable i which occurs in bucket j
+  j = bucket_num(i, order);
+  rest = mysetdiff(domain_pot(B{j}), i);
+  %temp = marginalize_pot_max(B{j}, rest);
+  temp = marginalize_pot(B{j}, rest, 1);
+  b = bucket_num(domain_pot(temp), order);
+  %        fprintf('maxing over bucket %d (var %d), putting result into bucket %d\n', j, i, b);
+  sB=struct(B{b});  % violate object privacy
+  if ~isempty(sB.domain)
+    B{b} = multiply_pots(B{b}, temp);
+  else
+    B{b} = temp;
+  end
+end
+result = B{1};
+marginal = pot_to_marginal(result);
+[prob, mpe] = max(marginal.T);
+
+% handle impossible cases
+if ~(prob>0)
+  mpe = [];    
+  ll = -inf;
+  %warning('evidence has zero probability')
+  return
+end
+
+ll = log(prob);
+
+% Do forward phase    
+for ii=2:n
+  marginal = pot_to_marginal(B{ii});
+  mpeidx = [];
+  for jj=order(1:length(mpe))
+    assert(ismember(jj, marginal.domain)) %%% bug
+    temp = find_equiv_posns(jj, marginal.domain);
+    mpeidx = [mpeidx, temp] ;
+    if isempty(temp)
+      mpeidx = [mpeidx, Inf] ;
+    end
+  end
+  [mpeidxsorted sortedtompe] = sort(mpeidx) ;
+  
+  % maximize the matrix obtained from assigning values from previous buckets.
+  % this is done by building a string and using eval.
+  
+  kk=1;
+  sargs = '(';
+  for jj=1:length(marginal.domain)
+    if (jj~=1)
+      sargs = [sargs, ','];
+    end
+    if (mpeidxsorted(kk)==jj)
+      sargs = [sargs, num2str(mpe(sortedtompe(kk)))];
+      if (kk<length(mpe))
+	kk = kk+1 ;
+      end
+    else
+      sargs = [sargs, ':'];
+    end
+  end
+  sargs = [sargs, ')'] ;   
+  eval(['[val, loc] = max(marginal.T', sargs, ');'])        
+  mpe = [mpe loc];
+end     
+[I,J] = sort(order);
+mpe = mpe(J);
+
+
+
+%%%%%%%%%
+
+function b = bucket_num(domain, order)
+
+b = max(find_equiv_posns(domain, order));
+
diff --git a/sourcecodes/bnt-master/BNT/general/Old/calc_mpe_dbn.m b/sourcecodes/bnt-master/BNT/general/Old/calc_mpe_dbn.m
new file mode 100644
index 00000000..8889d49f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/Old/calc_mpe_dbn.m
@@ -0,0 +1,41 @@
+function [mpe, ll] = calc_mpe_dbn(engine, evidence, break_ties)
+% CALC_MPE Computes the most probable explanation of the evidence
+% [mpe, ll] = calc_mpe_dbn(engine, evidence, break_ties)
+%
+% INPUT
+% engine must support max-propagation
+% evidence{i,t} is the observed value of node i in slice t, or [] if hidden
+%
+% OUTPUT
+% mpe{i,t} is the most likely value of node i (cell array!)
+% ll is the log-likelihood of the globally best assignment
+%
+% This currently only works when all hidden nodes are discrete
+
+if nargin < 3, break_ties = 0; end
+
+if break_ties
+  disp('warning: break ties is ignored')
+end
+
+[engine, ll] = enter_evidence(engine, evidence, 'maximize', 1);
+
+observed = ~isemptycell(evidence);
+[ss T] = size(evidence);
+scalar = 1;
+N = length(evidence);
+mpe = cell(ss,T);
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes;
+for t=1:T
+  for i=1:ss
+    m = marginal_nodes(engine, i, t);
+    % observed nodes are all set to 1 inside the inference engine, so we must undo this
+    if observed(i,t)
+      mpe{i,t} = evidence{i,t};
+    else
+      assert(length(m.T) == ns(i));
+      mpe{i,t} = argmax(m.T);
+    end
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/general/Old/calc_mpe_given_inf_engine.m b/sourcecodes/bnt-master/BNT/general/Old/calc_mpe_given_inf_engine.m
new file mode 100644
index 00000000..cd17a623
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/Old/calc_mpe_given_inf_engine.m
@@ -0,0 +1,32 @@
+function [mpe, prob] = calc_mpe_given_inf_engine(engine, evidence)
+% CALC_MPE_GIVEN_ENGINE Computes the most probable explanation of the evidence
+% [mpe, prob] = calc_mpe_given_inf_engine(engine, evidence)
+%
+% INPUT
+% engine must support max-propagation
+% evidence{i} is the obsevred value of node i, or [] if hidden
+%
+% OUTPUT
+% mpe(i) is the most likely value of node i
+% prob is the likelihood of the globally best assignment
+%
+% This currently only works when all nodes are discrete
+
+[engine, ll] = enter_evidence(engine, evidence);
+
+observed = ~isemptycell(evidence);
+N = length(evidence);
+mpe = zeros(1,N);
+for i=1:N
+  m = marginal_nodes(engine, i);
+  % discrete observed nodes are all set to 1 inside the inference engine, so we must undo this
+  if observed(i)
+    mpe(i) = evidence{i};
+  else
+    mpe(i) = argmax(m.T);
+  end
+end
+
+bnet = bnet_from_engine(engine);
+ll = log_lik_complete(bnet, num2cell(mpe(:)));
+prob = exp(ll);
diff --git a/sourcecodes/bnt-master/BNT/general/Old/calc_mpe_global.m b/sourcecodes/bnt-master/BNT/general/Old/calc_mpe_global.m
new file mode 100644
index 00000000..cf191966
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/Old/calc_mpe_global.m
@@ -0,0 +1,28 @@
+function [mpe, ll] = calc_mpe_global(bnet, evidence)
+% CALC_MPE_GLOBAL Compute the most probable explanation(s) from the global joint
+% [mpe, ll] = calc_mpe_global(bnet, evidence)
+%
+% mpe(k,i) is the most probable value of node i in the k'th global mode 
+% ll is the log likelihood
+%
+% We assume all nodes are discrete
+
+engine = global_joint_inf_engine(bnet);
+engine = enter_evidence(engine, evidence);
+S1 = struct(engine); % violate object privacy
+S2 = struct(S1.jpot); % joint potential
+prob = max(S2.T(:));
+modes = find(S2.T(:) == prob);
+
+ens = bnet.node_sizes;
+onodes = find(~isemptycell(evidence));
+ens(onodes) = 1;
+mpe = ind2subv(ens, modes);
+for k=1:length(modes)
+  for i=onodes(:)'
+    mpe(k,i) = evidence{i};
+  end
+end
+ll = log(prob);
+
+mpe = num2cell(mpe);
diff --git a/sourcecodes/bnt-master/BNT/general/Old/compute_interface_nodes.m b/sourcecodes/bnt-master/BNT/general/Old/compute_interface_nodes.m
new file mode 100644
index 00000000..85f5c693
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/Old/compute_interface_nodes.m
@@ -0,0 +1,31 @@
+function [int, persist, transient] = compute_interface_nodes(intra, inter)
+% COMPUTE_INTERFACE_NODES Find the nodes in a DBN that represent a sufficient statistic
+% [int, persist, transient] = compute_interface_nodes(intra, inter)
+%
+% The interface nodes are all those that has an incoming temporal arc,
+% or which have a child which has an incoming temporal arc,
+% where a temporal arc means one coming from the previous slice.
+% (The parents of nodes with incoming temporal arcs are needed
+% because moralization will bring them into the clique.)
+%
+% The persisent nodes are all those that have one or more incoming temporal arc.
+% The transient nodes are all the non-persistent.
+%
+% See U. Kjaerulff, "dHugin: A computational system for dynamic
+% time-sliced Bayesian networks", Intl. J. Forecasting (11) 89-111, 1995
+
+n = length(intra);
+int = [];
+persist = [];
+for u=1:n
+  if any(inter(:,u))
+    int = [int u];
+    persist = [persist u];
+  end
+  if any(inter(:, children(intra, u)))
+    int = [int u];
+  end
+end
+int = unique(int);
+persist = unique(persist);
+transient = mysetdiff(1:n, persist);
diff --git a/sourcecodes/bnt-master/BNT/general/Old/mk_gdl_graph.m b/sourcecodes/bnt-master/BNT/general/Old/mk_gdl_graph.m
new file mode 100644
index 00000000..ec5350d7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/Old/mk_gdl_graph.m
@@ -0,0 +1,86 @@
+function gdl = mk_gdl_graph(G, domains, node_sizes, kernels, varargin)
+% MK_GDL_GRAPH Make a GDL (generalized distributed law) graph
+% gdl = mk_gdl_graph(G, domains, node_sizes, kernels, ...)
+%
+% A GDL graph is like a moralized, but untriangulated, Bayes net:
+% each "node" represents a domain with a corresponding kernel function.
+% For details, see "The Generalized Distributive Law", Aji and McEliece,
+% IEEE Trans. Info. Theory, 46(2): 325--343, 2000
+% 
+% G(i,j) = 1 if there is an (undirected) edge between domains i,j
+%
+% domains{i} is the domain of node i
+%
+% node_sizes(i) is the number of values node i can take on,
+%   or the length of node i if i is a continuous-valued vector.
+% node_sizes(i) = 1 if i is a utility node.
+%
+% kernels is the list of kernel functions
+%
+% The list below gives optional arguments [default value in brackets].
+% 
+% equiv_class - equiv_class(i)=j  means factor node i gets its params from factors{j} [1:F]
+% discrete - the list of nodes which are discrete random variables [1:N]
+% chance   - the list of nodes which are random variables [1:N]
+% decision - the list of nodes which are decision nodes [ [] ]
+% utility  - the list of nodes which are utility nodes [ [] ]
+
+
+ns = node_sizes;
+N = length(domains);
+vars = [];
+for i=1:N
+  vars = myunion(vars, domains{i});
+end
+Nvars  = length(vars);
+
+gdl.equiv_class = 1:length(kernels);
+gdl.chance_nodes = 1:Nvars;
+gdl.utility_nodes = [];
+gdl.decision_nodes = [];
+gdl.dnodes = 1:Nvars;
+
+if nargin >= 5
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'equiv_class', bnet.equiv_class = args{i+1}; 
+     case 'chance',      bnet.chance_nodes = args{i+1}; 
+     case 'utility',     bnet.utility_nodes = args{i+1}; 
+     case 'decision',    bnet.decision_nodes = args{i+1}; 
+     case 'discrete',    bnet.dnodes = args{i+1}; 
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+
+gdl.G = G;
+gdl.vars = vars;
+gdl.doms = domains;
+gdl.node_sizes = node_sizes;
+gdl.cnodes = mysetdiff(vars, gdl.dnodes);
+gdl.kernels = kernels;
+gdl.type = 'gdl';
+
+% Compute a bit vector representation of the set of domains
+% dom_bitv(i,j) = 1 iff variable j occurs in domain i
+gdl.dom_bitv = zeros(N, length(vars));
+for i=1:N
+  gdl.dom_bitv(i, domains{i}) = 1;
+end
+
+% compute the interesection of the domains on either side of each edge (separating set)
+gdl.sepset = cell(N, N);
+gdl.nbrs = cell(1,N);
+for i=1:N
+  nbrs = neighbors(G, i);
+  gdl.nbrs{i} = nbrs;
+  for j = nbrs(:)'
+    gdl.sepset{i,j} = myintersect(domains{i}, domains{j});
+  end
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/general/add_ev_to_dmarginal.m b/sourcecodes/bnt-master/BNT/general/add_ev_to_dmarginal.m
new file mode 100644
index 00000000..b51f4983
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/add_ev_to_dmarginal.m
@@ -0,0 +1,15 @@
+function fmarginal = add_ev_to_dmarginal(fmarginal, evidence, ns)
+% ADD_EV_TO_DMARGINAL 'pump up' observed nodes back to their original size.
+% fmarginal = add_ev_to_dmarginal(fmarginal, evidence, ns)
+%
+% We introduce 0s into the array in positions which are incompatible with the evidence.
+
+dom = fmarginal.domain;
+odom = dom(~isemptycell(evidence(dom)));
+vals = cat(1, evidence{odom});
+index = mk_multi_index(length(dom), find_equiv_posns(odom, dom), vals);
+T = 0*myones(ns(dom));
+ens = ns(:)';
+ens(odom) = 1;
+T(index{:}) = myreshape(fmarginal.T, ens(dom));
+fmarginal.T = T;
diff --git a/sourcecodes/bnt-master/BNT/general/add_evidence_to_gmarginal.m b/sourcecodes/bnt-master/BNT/general/add_evidence_to_gmarginal.m
new file mode 100644
index 00000000..5cbd7d96
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/add_evidence_to_gmarginal.m
@@ -0,0 +1,78 @@
+function fullm = add_evidence_to_gmarginal(fmarginal, evidence, ns, cnodes)
+% ADD_EVIDENCE_TO_GMARGINAL 'pump up' observed nodes back to their original size.
+% function fullm = add_evidence_to_gmarginal(fmarginal, evidence, ns, cnodes)
+%
+% We introduce 0s into the array in positions which are incompatible with the evidence.
+% for both discrete and continuous nodes.
+%
+% See also add_ev_to_dmarginal
+
+dom = fmarginal.domain;
+fullm.domain = fmarginal.domain;
+
+% Find out which values of the discrete parents (if any) are compatible with 
+% the discrete evidence (if any).
+dnodes = mysetdiff(1:length(ns), cnodes);
+ddom = myintersect(dom, dnodes);
+cdom = myintersect(dom, cnodes);
+odom = dom(~isemptycell(evidence(dom)));
+hdom = dom(isemptycell(evidence(dom)));
+
+% Find the entries in the big table that are compatible with the discrete evidence.
+% (We will put the probabilities from the small inferred table into these positions.)
+% We could use add_ev_to_dmarginal to do this.
+dobs = myintersect(ddom, odom);
+dvals = cat(1, evidence{dobs});
+ens = ns; % effective node sizes
+ens(dobs) = 1;
+S = prod(ens(ddom));
+subs = ind2subv(ens(ddom), 1:S);
+mask = find_equiv_posns(dobs, ddom);
+%subs(mask) = dvals; % bug fix by P. Brutti
+for i=1:length(mask),
+  subs(:,mask(i)) = dvals(i);
+end       
+supportedQs = subv2ind(ns(ddom), subs);
+
+if isempty(ddom)
+  Qarity = 1;
+else
+  Qarity = prod(ns(ddom));
+end
+fullm.T = zeros(Qarity, 1);
+fullm.T(supportedQs) = fmarginal.T(:);
+fullm.T = myreshape(fullm.T, ns(ddom));
+
+
+if isempty(cdom)
+  fullm.mu = [];
+  fullm.sigma = [];
+  return;
+end
+
+% Now put the hidden cts parts into their right blocks,
+% leaving the observed cts parts as 0.
+cobs = myintersect(cdom, odom);
+chid = myintersect(cdom, hdom);
+cvals = cat(1, evidence{cobs});
+n = sum(ns(cdom));
+fullm.mu = zeros(n,Qarity);
+fullm.Sigma = zeros(n,n,Qarity);
+
+if ~isempty(chid)
+  chid_blocks = block(find_equiv_posns(chid, cdom), ns(cdom));
+end
+if ~isempty(cobs)
+  cobs_blocks = block(find_equiv_posns(cobs, cdom), ns(cdom));
+end
+
+for i=1:length(supportedQs)
+  Q = supportedQs(i);
+  if ~isempty(chid)
+    fullm.mu(chid_blocks, Q) = fmarginal.mu(:, i);
+    fullm.Sigma(chid_blocks, chid_blocks, Q) = fmarginal.Sigma(:,:,i);
+  end
+  if ~isempty(cobs)
+    fullm.mu(cobs_blocks, Q) = cvals(:);
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/general/bnet_to_fgraph.m b/sourcecodes/bnt-master/BNT/general/bnet_to_fgraph.m
new file mode 100644
index 00000000..fa2763b9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/bnet_to_fgraph.m
@@ -0,0 +1,16 @@
+function fg = bnet_to_fgraph(bnet)
+% BNET_TO_FGRAPH Convert a Bayes net to a factor graph
+% fg = bnet_to_fgraph(bnet)
+%
+% We create one factor per family, whose kernel is the CPD
+
+nnodes = length(bnet.dag);
+G = zeros(nnodes, nnodes);
+for i=1:nnodes
+  G(family(bnet.dag, i), i) = 1;
+end
+
+fg = mk_fgraph(G, bnet.node_sizes, bnet.CPD, 'equiv_class', bnet.equiv_class, 'discrete', bnet.dnodes);
+
+	       
+
diff --git a/sourcecodes/bnt-master/BNT/general/compute_fwd_interface.m b/sourcecodes/bnt-master/BNT/general/compute_fwd_interface.m
new file mode 100644
index 00000000..db4807c7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/compute_fwd_interface.m
@@ -0,0 +1,11 @@
+function int = compute_fwd_interface(intra, inter)
+% COMPUTE_FWD_INTERFACE Compute nodes with children in the next slice
+% function int = compute_fwd_interface(intra, inter)
+
+int = [];
+ss = length(intra);
+for u=1:ss
+  if any(inter(u,:))
+    int = [int u];
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/general/compute_interface_nodes.m b/sourcecodes/bnt-master/BNT/general/compute_interface_nodes.m
new file mode 100644
index 00000000..43370172
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/compute_interface_nodes.m
@@ -0,0 +1,42 @@
+function [interface, persist, transient] = compute_interface_nodes(intra, inter)
+% COMPUTE_INTERFACE_NODES Find the nodes in a DBN that represent a sufficient statistic
+% [interface, persist, transient] = compute_interface_nodes(intra, inter)
+%
+% The interface nodes are all those that has an incoming temporal arc,
+% or which are parents of such nodes.
+% If the parents are in the previous slice, this just means they have an
+% outgoing temporal arc.
+% (The parents of nodes with incoming temporal arcs are needed
+% because moralization will bring them into the clique.)
+%
+% The persisent nodes are all those that have one or more incoming temporal arc.
+% The transient nodes are all the non-persistent.
+%
+% See U. Kjaerulff, "dHugin: A computational system for dynamic
+% time-sliced Bayesian networks", Intl. J. Forecasting (11) 89-111, 1995
+
+n = length(intra);
+interface = [];
+persist = [];
+% any nodes with incoming arcs
+for u=1:n
+  if any(inter(:,u))
+    interface = [interface u];
+    persist = [persist u];
+  end
+end
+% Any nodes which are parents of nodes with incoming arcs
+for u=1:n
+  cs = children(intra, u);
+  if any(inter(:, cs))
+    interface = [interface u];
+  end
+  %cs = children(inter, u);
+  % if ~isempty(myintersect(cs, persist))
+  %  interface = [interface u];
+  %end
+end
+interface = unique(interface);
+persist = unique(persist);
+transient = mysetdiff(1:n, persist);
+
diff --git a/sourcecodes/bnt-master/BNT/general/compute_joint_pot.m b/sourcecodes/bnt-master/BNT/general/compute_joint_pot.m
new file mode 100644
index 00000000..056aa998
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/compute_joint_pot.m
@@ -0,0 +1,17 @@
+function [jpot, loglik] = compute_joint_pot(bnet, nodes, evidence, domain)
+% COMPUTE_JOINT_POT Compute the global joint potential of a Bayes net
+% function jpot = compute_joint_pot(bnet, nodes, evidence, domain)
+
+if nargin < 4, domain = nodes; end
+
+onodes = find(~isemptycell(evidence));
+pot_type = determine_pot_type(bnet, onodes, domain);
+
+jpot = mk_initial_pot(pot_type, domain, bnet.node_sizes, bnet.cnodes, onodes);
+for i=nodes(:)'
+  e = bnet.equiv_class(i);
+  fam = family(bnet.dag, i);
+  pot = convert_to_pot(bnet.CPD{e}, pot_type, fam(:), evidence);
+  jpot = multiply_by_pot(jpot, pot);
+end                                                  
+%[jpot, loglik] = normalize_pot(jpot); % causes errors in asia_dt1 etc
diff --git a/sourcecodes/bnt-master/BNT/general/compute_minimal_interface.m b/sourcecodes/bnt-master/BNT/general/compute_minimal_interface.m
new file mode 100644
index 00000000..34dc8e62
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/compute_minimal_interface.m
@@ -0,0 +1,25 @@
+function clqs = compute_minimal_interface(intra, inter)
+
+int = compute_fwd_interface(intra, inter);
+ss  = length(intra);
+Z = zeros(ss);
+dag = [intra inter;
+       Z     intra];
+G = moralize(dag);
+intra2 = G(1:ss,1:ss);
+inter2 = G(1:ss,(1:ss)+ss);
+G = unroll_dbn_topology(intra2, inter2, ss);
+T = ss;
+last_slice = (1:ss) + (T-1)*ss;
+G = (G + G')/2; % mk symmetric
+G2 = (expm(full(G)) > 0); % closure of graph
+G3 = G2(last_slice, last_slice);
+[c,v] = scc(G3); % connected components
+ncomp = size(v,1);
+clqs = cell(1,ncomp);
+for i=1:ncomp
+  ndx = find(v(i,:)>0);
+  clqs{i} = v(i,ndx);
+  clqs{i} = myintersect(clqs{i}, int);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_pots.m b/sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_pots.m
new file mode 100644
index 00000000..425e23b7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_pots.m
@@ -0,0 +1,30 @@
+function CPDpot = convert_dbn_CPDs_to_pots(bnet, evidence, pot_type, softCPDpot)
+% CONVERT_DBN_CPDS_TO_POTS Convert CPDs of (possibly instantiated) DBN nodes to potentials
+% CPDpot = convert_dbn_CPDs_to_pots(bnet, evidence, pot_type, softCPDpot)
+%
+% CPDpot{n,t} is a potential containing P(n,t|pa(n,t), ev)
+% softCPDpot{n,t} is a potential containing P(n,t|pa(n,t), ev) insted of using n's CPD
+
+[ss T] = size(evidence);
+
+if nargin < 4, softCPDpot = cell(ss,T); end
+CPDpot = softCPDpot;
+
+% Convert CPDs of instantiated nodes to potential form
+t = 1;
+for n=1:ss
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n, 1);
+  if isempty(softCPDpot{n,t})
+    CPDpot{n,t} = convert_to_pot(bnet.CPD{e}, pot_type, fam(:), evidence(:,1));
+  end
+end
+for n=1:ss
+  fam = family(bnet.dag, n, 2);
+  e = bnet.equiv_class(n, 2);
+  for t=2:T
+    if isempty(softCPDpot{n,t})
+      CPDpot{n,t} = convert_to_pot(bnet.CPD{e}, pot_type, fam(:), evidence(:,t-1:t));
+    end
+  end       
+end
diff --git a/sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_tables.m b/sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_tables.m
new file mode 100644
index 00000000..c10d58f7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_tables.m
@@ -0,0 +1,201 @@
+function CPDpot = convert_dbn_CPDs_to_tables(bnet, evidence)
+% CONVERT_DBN_CPDS_TO_TABLES Convert CPDs of (possibly instantiated) DBN nodes to tables
+% CPDpot = convert_dbn_CPDs_to_tables(bnet, evidence)
+%
+% CPDpot{n,t} is a table containing P(n,t|pa(n,t), ev)
+% All hidden nodes are assumed to be discrete.
+% We assume the observed nodes are the same in every slice.
+%
+% Evaluating the conditional likelihood of long evidence sequences can be very slow,
+% so we take pains to vectorize where possible.
+
+[ss T] = size(evidence);
+%obs_bitv = ~isemptycell(evidence(:));
+obs_bitv = zeros(1, 2*ss);
+obs_bitv(bnet.observed) = 1;
+obs_bitv(bnet.observed+ss) = 1;
+
+ns = bnet.node_sizes(:);
+CPDpot = cell(ss,T); 
+
+for n=1:ss
+  % slice 1
+  t = 1;
+  ps = parents(bnet.dag, n);
+  e = bnet.equiv_class(n, 1);
+  if ~any(obs_bitv(ps))
+    CPDpot{n,t} = convert_CPD_to_table_hidden_ps(bnet.CPD{e}, evidence{n,t});
+  else
+    CPDpot{n,t} = convert_to_table(bnet.CPD{e}, [ps n], evidence(:,1));
+  end
+
+% special cases: c=child, p=parents, d=discrete, h=hidden, 1sl=1slice
+% if c=h=1 then c=d=1, since hidden nodes must be discrete
+% c=h c=d p=h p=d 1sl method
+% ---------------------------
+% 1   1   1   1   -   replicate CPT
+% -   1   -   1   -   evaluate CPT on evidence *
+% 0   1   1   1   1   dhmm
+% 0   0   1   1   1   ghmm
+% other               loop
+%
+% * = any subset of the domain may be observed
+
+% Example where all of the special cases occur - a hierarchical HMM
+% where the top layer (G) and leaves (Y) are observed and
+% all nodes are discrete except Y.
+% (O turns on if Y is an outlier)
+
+% G ---------> G 
+% |            |
+% v            v
+% S  --------> S
+% |            |
+% v            v
+% Y            Y
+% ^            ^
+% |            |
+% O            O
+
+% Evaluating P(yt|St,Ot) is the ghmm case
+% Evaluating P(St|S(t-1),gt) is the eval CPT case
+% Evaluating P(gt|g(t-1) is the eval CPT case (hdom = [])
+% Evaluating P(Ot) is the replicated CPT case
+
+% Cts parents (e.g., inputs) would require an additional special case for speed
+
+
+  % slices 2..T
+  [ss T] = size(evidence);
+  self = n+ss;
+  ps = parents(bnet.dag, self);
+  e = bnet.equiv_class(n, 2);
+
+  if 1
+  debug = 0;
+  hidden_child = ~obs_bitv(n);
+  discrete_child = myismember(n, bnet.dnodes);
+  hidden_ps = all(~obs_bitv(ps));
+  discrete_ps = mysubset(ps, bnet.dnodes);
+  parents_in_same_slice = all(ps > ss);
+  
+  if hidden_child & discrete_child & hidden_ps & discrete_ps
+    CPDpot = helper_repl(bnet, evidence, n, CPDpot, obs_bitv, debug);
+  elseif discrete_child & discrete_ps
+    CPDpot = helper_eval(bnet, evidence, n, CPDpot, obs_bitv, debug);
+  elseif discrete_child & hidden_ps & discrete_ps & parents_in_same_slice
+    CPDpot = helper_dhmm(bnet, evidence, n, CPDpot, obs_bitv, debug);
+  elseif ~discrete_child & hidden_ps & discrete_ps & parents_in_same_slice
+    CPDpot = helper_ghmm(bnet, evidence, n, CPDpot, obs_bitv, debug);
+  else
+    if debug, fprintf('node %d, slow\n', n); end
+    for t=2:T
+      CPDpot{n,t} = convert_to_table(bnet.CPD{e}, [ps self], evidence(:,t-1:t));
+    end
+  end
+  end
+  
+  if 0
+  for t=2:T
+    CPDpot2{n,t} = convert_to_table(bnet.CPD{e}, [ps self], evidence(:,t-1:t));
+    if ~approxeq(CPDpot{n,t}, CPDpot2{n,t})
+      fprintf('CPDpot n=%d, t=%d\n',n,t);
+      keyboard
+    end
+  end
+  end
+
+  
+end
+
+
+
+
+%%%%%%%
+function CPDpot = helper_repl(bnet, evidence, n, CPDpot, obs_bitv, debug)
+
+[ss T] = size(evidence);
+if debug, fprintf('node %d, repl\n', n); end
+e = bnet.equiv_class(n, 2);
+CPT = convert_CPD_to_table_hidden_ps(bnet.CPD{e}, []);
+CPDpot(n,2:T) = num2cell(repmat(CPT, [1 1 T-1]), [1 2]);
+
+
+
+%%%%%%%
+function CPDpot = helper_eval(bnet, evidence, n, CPDpot, obs_bitv, debug)
+
+[ss T] = size(evidence);
+self = n+ss;
+ps = parents(bnet.dag, self);
+e = bnet.equiv_class(n, 2);
+ns = bnet.node_sizes(:);
+% Example: given CPT(p1, p2, p3, p4, c), where p1,p3 are observed
+% we create CPT([p2 p4 c], [p1 p3]).
+% We then convert all observed p1,p3 into indices ndx
+% and return CPT(:, ndx)
+CPT = CPD_to_CPT(bnet.CPD{e});
+domain = [ps self];
+% if dom is [3 7 8] and 3,8 are observed, odom_rel = [1 3], hdom_rel = 2,
+% odom = [3 8], hdom = 7
+odom_rel = find(obs_bitv(domain));
+hdom_rel = find(~obs_bitv(domain));
+odom = domain(odom_rel);
+hdom = domain(hdom_rel);
+if isempty(hdom)
+  CPT = CPT(:);
+else
+  CPT = permute(CPT, [hdom_rel odom_rel]);
+  CPT = reshape(CPT, prod(ns(hdom)), prod(ns(odom)));
+end
+parents_in_same_slice = all(ps > ss);
+if parents_in_same_slice
+  if debug, fprintf('node %d eval 1 slice\n', n); end
+  data = cell2num(evidence(odom-ss,2:T)); %data(i,t) = val of i'th obs parent at t+1
+else
+  if debug, fprintf('node %d eval 2 slice\n', n); end
+  % there's probably a way of vectorizing this...
+  data = zeros(length(odom), T-1);
+  for t=2:T
+    ev = evidence(:,t-1:t);
+    ev = ev(:);
+    ev2 = ev(odom);
+    data(:,t-1) = cat(1, ev2{:});
+    %data(:,t-1) = cell2num(ev2);
+  end
+end
+ndx = subv2ind(ns(odom), data'); % ndx(t) encodes data(:,t)
+if isempty(hdom)
+  CPDpot(n,2:T) = num2cell(CPT(ndx)); % a cell array of floats
+else
+  CPDpot(n,2:T) = num2cell(CPT(:, ndx), 1); % a cell array of column vectors
+end
+
+%%%%%%%
+function CPDpot = helper_dhmm(bnet, evidence, n, CPDpot, obs_bitv, debug)
+
+if debug, fprintf('node %d, dhmm\n', n); end
+[ss T] = size(evidence);
+self = n+ss;
+ps = parents(bnet.dag, self);
+e = bnet.equiv_class(n, 2);
+ns = bnet.node_sizes(:);
+CPT = CPD_to_CPT(bnet.CPD{e});
+CPT = reshape(CPT, [prod(ns(ps)) ns(self)]); % what if no parents?
+%obslik = mk_dhmm_obs_lik(cell2num(evidence(n,2:T)), CPT);
+obslik = eval_pdf_cond_multinomial(cell2num(evidence(n,2:T)), CPT);
+CPDpot(n,2:T) = num2cell(obslik, 1);
+
+
+%%%%%%%
+function CPDpot = helper_ghmm(bnet, evidence, n, CPDpot, obs_bitv, debug)
+
+if debug, fprintf('node %d, ghmm\n', n); end
+[ss T] = size(evidence);
+e = bnet.equiv_class(n, 2);
+S = struct(bnet.CPD{e}); 
+ev2 = cell2num(evidence(n,2:T));
+%obslik = mk_ghmm_obs_lik(ev2, S.mean, S.cov);
+obslik = eval_pdf_cond_gauss(ev2, S.mean, S.cov);
+CPDpot(n,2:T) = num2cell(obslik, 1);
+
diff --git a/sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_tables1.m b/sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_tables1.m
new file mode 100644
index 00000000..c1b2c756
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_tables1.m
@@ -0,0 +1,162 @@
+function CPDpot = convert_dbn_CPDs_to_tables1(bnet, evidence)
+% CONVERT_DBN_CPDS_TO_TABLES Convert CPDs of (possibly instantiated) DBN nodes to tables
+% CPDpot = convert_dbn_CPDs_to_tables(bnet, evidence)
+%
+% CPDpot{n,t} is a table containing P(n,t|pa(n,t), ev)
+% All hidden nodes are assumed to be discrete
+% We assume the observed nodes are the same in every slice
+%
+% Evaluating the conditional likelihood of the evidence can be very slow,
+% so we take pains to vectorize where possible, i.e., we try to avoid
+% calling convert_to_table
+
+[ss T] = size(evidence);
+%obs_bitv = ~isemptycell(evidence(:));
+obs_bitv = zeros(1, 2*ss);
+obs_bitv(bnet.observed) = 1;
+obs_bitv(bnet.observed+ss) = 1;
+
+ns = bnet.node_sizes(:);
+CPDpot = cell(ss,T); 
+
+for n=1:ss
+  % slice 1
+  t = 1;
+  ps = parents(bnet.dag, n);
+  e = bnet.equiv_class(n, 1);
+  if ~any(obs_bitv(ps))
+    CPDpot{n,t} = convert_CPD_to_table_hidden_ps(bnet.CPD{e}, evidence{n,t});
+  else
+    CPDpot{n,t} = convert_to_table(bnet.CPD{e}, [ps n], evidence(:,1));
+  end
+  
+  % slices 2..T
+  debug = 1;
+  if ~obs_bitv(n)
+    CPDpot = helper_hidden_child(bnet, evidence, n, CPDpot, obs_bitv, debug);
+  else
+    CPDpot = helper_obs_child(bnet, evidence, n, CPDpot, obs_bitv, debug);
+  end
+end
+
+if 0
+CPDpot2 = convert_dbn_CPDs_to_tables_slow(bnet, evidence);
+for t=1:T
+  for n=1:ss
+    if ~approxeq(CPDpot{n,t}, CPDpot2{n,t})
+      fprintf('CPDpot n=%d, t=%d\n',n,t);
+      keyboard
+    end
+  end
+end
+end
+
+
+% special cases: c=child, p=parents, d=discrete, h=hidden, 1=1slice
+% if c=h=1 then c=d=1, since hidden nodes must be discrete
+% c=h c=d p=h p=d p=1 method
+% ---------------------------
+% 1   1   1   1   -   replicate CPT
+% 0   1   1   1   1   dhmm
+% 0   0   1   1   1   ghmm
+% -   1   -   1   -   evaluate CPT on evidence
+% other               loop
+
+%%%%%%%
+function CPDpot = helper_hidden_child(bnet, evidence, n, CPDpot, obs_bitv, debug)
+
+[ss T] = size(evidence);
+self = n+ss;
+ps = parents(bnet.dag, self);
+e = bnet.equiv_class(n, 2);
+ns = bnet.node_sizes(:);
+if ~any(obs_bitv(ps)) % all parents are hidden (hence discrete)
+  if debug, fprintf('node %d is hidden, all ps are hidden\n', n); end
+  if myismember(n, bnet.dnodes) 
+    %CPT = CPD_to_CPT(bnet.CPD{e});
+    %CPT = reshape(CPT, [prod(ns(ps)) ns(self)]);
+    CPT = convert_CPD_to_table_hidden_ps(bnet.CPD{e}, []);
+    CPDpot(n,2:T) = num2cell(repmat(CPT, [1 1 T-1]), [1 2]);
+  else
+    error(['hidden cts node disallowed'])
+  end
+else % some parents are observed - slow
+  if mysubset(ps, bnet.dnodes) % all parents are discrete
+    % given CPT(p1, p2, p3, p4, c), where p1,p3 are observed
+    % we create CPT([p2 p4 c], [p1 p3]).
+    % We then convert all observed p1,p3 into indices ndx
+    % and return CPT(:, ndx)
+    CPT = CPD_to_CPT(bnet.CPD{e});
+    domain = [ps self];
+    % if dom is [3 7 8] and 3,8 are observed, odom_rel = [1 3], hdom_rel = 2,
+    % odom = [3 8], hdom = 7
+    odom_rel = find(obs_bitv(domain));
+    hdom_rel = find(~obs_bitv(domain));
+    odom = domain(odom_rel);
+    hdom = domain(hdom_rel);
+    CPT = permute(CPT, [hdom_rel odom_rel]);
+    CPT = reshape(CPT, prod(ns(hdom)), prod(ns(odom)));
+    parents_in_same_slice = all(ps > ss);
+    if parents_in_same_slice
+      if debug, fprintf('node %d is hidden, some ps are obs, all ps discrete, 1 slice\n', n); end
+      data = cell2num(evidence(odom-ss,2:T)); %data(i,t) = val of i'th obs parent at t+1
+    else
+      if debug, fprintf('node %d is hidden, some ps are obs, all ps discrete, 2 slice\n', n); end
+      data = zeros(length(odom), T-1);
+      for t=2:T
+	ev = evidence(:,t-1:t);
+	data(:,t-1) = cell2num(ev(odom));
+      end
+    end
+    ndx = subv2ind(ns(odom), data'); % ndx(t) encodes data(:,t)
+    CPDpot(n,2:T) = num2cell(CPT(:, ndx), [1 2]);
+  else % some parents are cts - v slow
+    if debug, fprintf('node %d is hidden, some ps are obs, some ps cts\n', n); end
+    for t=2:T
+      CPDpot{n,t} = convert_to_table(bnet.CPD{e}, [ps self], evidence(:,t-1:t));
+    end
+  end
+end
+  
+%%%%%%%
+function CPDpot = helper_obs_child(bnet, evidence, n, CPDpot, obs_bitv, debug)
+
+[ss T] = size(evidence);
+self = n+ss;
+ps = parents(bnet.dag, self);
+e = bnet.equiv_class(n, 2);
+ns = bnet.node_sizes(:);
+if ~any(obs_bitv(ps)) % all parents are hidden
+  parents_in_same_slice = all(ps > ss);
+  if parents_in_same_slice
+    if debug, fprintf('node %d is obs, all ps are hidden, 1 slice\n', n); end
+    ps1 = ps - ss;
+    if myismember(n, bnet.dnodes) 
+      CPT = CPD_to_CPT(bnet.CPD{e});
+      CPT = reshape(CPT, [prod(ns(ps)) ns(self)]); % what if no parents?
+      obslik = eval_pdf_cond_multinomial(cell2num(evidence(n,2:T)), CPT);
+      CPDpot(n,2:T) = num2cell(obslik, 1);
+    else
+      S = struct(bnet.CPD{e}); 
+      obslik = eval_pdf_cond_gauss(cell2num(evidence(n,2:T)), S.mean, S.cov);
+      CPDpot(n,2:T) = num2cell(obslik, 1);
+    end
+  else % parents span 2 slices - slow
+    if debug, fprintf('node %d is obs, all ps are hidden , 2 slice\n', n); end
+    for t=2:T
+      CPDpot{n,t} = convert_to_table(bnet.CPD{e}, [ps self], evidence(:,t-1:t));
+    end
+  end
+else 
+  if isempty(ps) % observed root
+    if debug, fprintf('node %d is obs, no ps\n', n); end
+    CPT = CPD_to_CPT(bnet.CPD{e});
+    data = cell2num(evidence(n,2:T));
+    CPDpot(n,2:T) = CPT(data);
+  else  % some parents are observed  - slow
+    if debug, fprintf('node %d is obs, some ps are obs\n', n); end
+    for t=2:T
+      CPDpot{n,t} = convert_to_table(bnet.CPD{e}, [ps self], evidence(:,t-1:t));
+    end
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_tables_slow.m b/sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_tables_slow.m
new file mode 100644
index 00000000..90e87046
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/convert_dbn_CPDs_to_tables_slow.m
@@ -0,0 +1,41 @@
+function CPDpot = convert_dbn_CPDs_to_tables_slow(bnet, evidence)
+% CONVERT_DBN_CPDS_TO_TABLES_SLOW Convert CPDs of (possibly instantiated) DBN nodes to tables
+% CPDpot = convert_dbn_CPDs_to_tables_slow(bnet, evidence)
+%
+% CPDpot{n,t} is a table containing P(n,t|pa(n,t), ev)
+% All hidden nodes are assumed to be discrete
+%
+% Non-vectorized method; this is less efficient for long sequences of observed Gaussian
+% nodes, because of the (unnecessary) repeated matrix inversion.
+
+obs_bitv = ~isemptycell(evidence(:));
+[ss T] = size(evidence);
+ns = bnet.node_sizes(:);
+
+CPDpot = cell(ss,T); 
+
+t = 1;
+for n=1:ss
+  %ps = engine.bnet_parents{n};
+  ps = parents(bnet.dag, n);
+  e = bnet.equiv_class(n, 1);
+  if ~any(obs_bitv(ps))
+    CPDpot{n,t} = convert_CPD_to_table_hidden_ps(bnet.CPD{e}, evidence{n,t});
+  else
+    CPDpot{n,t} = convert_to_table(bnet.CPD{e}, [ps n], evidence(:,1));
+  end
+end
+for t=2:T
+  for n=1:ss
+    self = n+ss;
+    ps = parents(bnet.dag, self);
+    e = bnet.equiv_class(n, 2);
+    if ~any(obs_bitv(ps))
+      CPDpot{n,t} = convert_CPD_to_table_hidden_ps(bnet.CPD{e}, evidence{n,t});
+    else
+      CPDpot{n,t} = convert_to_table(bnet.CPD{e}, [ps self], evidence(:,t-1:t));
+    end
+  end
+end       
+
+
diff --git a/sourcecodes/bnt-master/BNT/general/dbn_to_bnet.m b/sourcecodes/bnt-master/BNT/general/dbn_to_bnet.m
new file mode 100644
index 00000000..e15b9309
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/dbn_to_bnet.m
@@ -0,0 +1,13 @@
+function bnet = dbn_to_bnet(dbn, T)
+% DBN_TO_BNET Convert a DBN to a static network by unroll for T slices
+% bnet = dbn_to_bnet(dbn, T)
+
+ss = length(dbn.intra);
+eclass = [dbn.equiv_class(:,1) repmat(dbn.equiv_class(:,2), 1, T-1)];
+dnodes = unroll_set(dbn.dnodes_slice, ss, T);
+ns = repmat(dbn.node_sizes_slice(:), 1, T);
+dag = unroll_dbn_topology(dbn.intra, dbn.inter, T, dbn.intra1);
+onodes = unroll_set(dbn.observed(:), ss, T);
+bnet = mk_bnet(dag, ns(:), 'discrete', dnodes(:), 'equiv_class', eclass(:), 'observed', onodes(:));
+bnet.CPD = dbn.CPD;
+ 
diff --git a/sourcecodes/bnt-master/BNT/general/dbn_to_hmm.m b/sourcecodes/bnt-master/BNT/general/dbn_to_hmm.m
new file mode 100644
index 00000000..8a783999
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/dbn_to_hmm.m
@@ -0,0 +1,81 @@
+function [startprob, transprob, obsprob] = dbn_to_hmm(bnet)
+% DBN_TO_HMM % Convert DBN params to HMM params
+% [startprob, transprob, obsprob] = dbn_to_hmm(bnet, onodes)
+% startprob(i)
+% transprob(i,j)
+% obsprob{k}.big_CPT(i,o) if k'th observed node is discrete
+% obsprob{k}.big_mu(:,i), .big_Sigma(:,:,i) if k'th observed node is Gaussian
+% Big means the domain contains all the hidden discrete nodes, not just the parents.
+
+% Called by constructor and by update_engine
+
+ss = length(bnet.intra);
+onodes = bnet.observed;
+hnodes = mysetdiff(1:ss, onodes);
+evidence = cell(ss, 2);
+ns = bnet.node_sizes(:);
+Qh = prod(ns(hnodes));
+tmp = dpot_to_table(compute_joint_pot(bnet, hnodes, evidence));
+startprob = reshape(tmp, Qh, 1);
+
+tmp = dpot_to_table(compute_joint_pot(bnet, hnodes+ss, evidence, [hnodes hnodes+ss]));
+transprob = mk_stochastic(reshape(tmp, Qh, Qh));
+
+% P(o|ps) is used by mk_hmm_obs_lik_vec for a single time slice
+% P(o|h) (the big version), where h = all hidden nodes, is used by enter_evidence
+
+obsprob = cell(1, length(onodes));
+for i=1:length(onodes)
+  o = onodes(i);
+  if bnet.auto_regressive(o)
+    % We assume the parents of this node are all the hidden nodes in the slice,
+    % so the params already are "big". Also, we assume we regress only on our old selves.
+    % slice 1
+    e = bnet.equiv_class(o);
+    CPD = struct(bnet.CPD{e});
+    O = ns(o);
+    ps = bnet.parents{o};
+    Qps = prod(ns(ps));
+    obsprob{i}.big_mu0 = reshape(CPD.mean, [O Qps]);
+    obsprob{i}.big_Sigma0 = reshape(CPD.cov, [O O Qps]);
+
+    % slice t>1
+    e = bnet.equiv_class(o+ss);
+    CPD = struct(bnet.CPD{e});
+    O = ns(o);
+    dps = mysetdiff(bnet.parents{o+ss}, o);
+    Qdps = prod(ns(dps));
+    obsprob{i}.big_mu = reshape(CPD.mean, [O Qdps]);
+    obsprob{i}.big_Sigma = reshape(CPD.cov, [O O Qdps]);
+    obsprob{i}.big_W = reshape(CPD.weights, [O O Qdps]);
+  else
+    e = bnet.equiv_class(o+ss);
+    CPD = struct(bnet.CPD{e});
+    O = ns(o);
+    ps = bnet.parents{o};
+    Qps = prod(ns(ps));
+    % We make a big potential, replicating the params if necessary
+    % e.g., for a 2 chain coupled HMM, mu(:,Q1) becomes mu(:,Q1,Q2)
+    bigpot = pot_to_marginal(compute_joint_pot(bnet, onodes(i), evidence, [hnodes onodes(i)]));
+
+    if myismember(o, bnet.dnodes)
+      obsprob{i}.CPT = reshape(CPD.CPT, [Qps O]);
+      obsprob{i}.big_CPT = reshape(bigpot.T, Qh, O); 
+    else
+      obsprob{i}.big_mu = bigpot.mu;
+      obsprob{i}.big_Sigma = bigpot.Sigma;
+      
+      if 1
+      obsprob{i}.mu = reshape(CPD.mean, [O Qps]);
+      C = reshape(CPD.cov, [O O Qps]);
+      obsprob{i}.Sigma = C;
+      d = size(obsprob{i}.mu, 1);
+      for j=1:Qps
+	obsprob{i}.inv_Sigma(:,:,j) = inv(C(:,:,j));
+	obsprob{i}.denom(j) = (2*pi)^(d/2)*sqrt(abs(det(C(:,:,j))));
+      end
+      end
+      
+    end % if discrete
+  end % if ar
+end % for
diff --git a/sourcecodes/bnt-master/BNT/general/determine_elim_constraints.m b/sourcecodes/bnt-master/BNT/general/determine_elim_constraints.m
new file mode 100644
index 00000000..01c3f14c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/determine_elim_constraints.m
@@ -0,0 +1,43 @@
+function partial_order = determine_elim_constraints(bnet, onodes)
+% DETERMINE_ELIM_CONSTRAINTS Determine what the constraints are (if any) on the elimination ordering.
+% partial_order = determine_elim_constraints(bnet, onodes)
+%
+% A graph with different kinds of nodes (e.g., discrete and cts, or decision and rnd) is called marked. 
+% A strong root is guaranteed to exist if the marked graph is triangulated and does not have any paths of
+% the form discrete -> cts -> discrete. In general we need to add extra edges to
+% the moral graph to ensure this (see example in Lauritzen (1992) fig 3b).
+% However, a simpler sufficient condition is to eliminate all the cts nodes before the discrete ones,
+% because then, as we move from the leaves to the root, the cts nodes get marginalized away
+% and we are left with purely discrete cliques.
+%
+% partial_order(i,j)=1 if we must marginalize j *before* i
+% (so i will be nearer the strong root).
+% If the hidden nodes are either all discrete or all cts, we set partial_order = [].
+%
+% For details, see
+% - Jensen, Jensen and Dittmer, "From influence diagrams to junction trees", UAI 94.
+% - Lauritzen, "Propgation of probabilities, means, and variances in mixed graphical
+%   association models", JASA 87(420):1098--1108, 1992.
+% - K. Olesen, "Causal probabilistic networks with both discrete and continuous variables",
+%      IEEE Pami 15(3), 1993
+
+
+n = length(bnet.dag);
+pot_type = determine_pot_type(bnet, onodes);
+if (pot_type == 'd') || (pot_type == 'g')
+  partial_order = [];
+  return;
+end
+
+
+partial_order = sparse(n,n);
+partial_order(bnet.dnodes, bnet.cnodes) = 1;
+
+% Integrate out cts nodes before their discrete parents - see Olesen (1993) p9
+% This method gives the wrong results on cg1.m!
+if 0
+for i=bnet.cnodes(:)'
+  dps = myintersect(parents(bnet.dag, i), bnet.dnodes);
+  partial_order(dps, i)=1;
+end
+end
diff --git a/sourcecodes/bnt-master/BNT/general/dispcpt.m b/sourcecodes/bnt-master/BNT/general/dispcpt.m
new file mode 100644
index 00000000..ba4c5607
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/dispcpt.m
@@ -0,0 +1,16 @@
+function display_CPT(CPT)
+
+n = ndims(CPT);
+parents_size = size(CPT);
+parents_size = parents_size(1:end-1);
+child_size = size(CPT,n);
+c = 1;
+for i=1:prod(parents_size)
+  parent_inst = ind2subv(parents_size, i);
+  fprintf(1, '%d ', parent_inst);
+  fprintf(1, ': ');
+  index = num2cell([parent_inst 1]);
+  index{n} = ':';
+  fprintf(1, '%6.4f ', CPT(index{:}));
+  fprintf(1, '\n');
+end
diff --git a/sourcecodes/bnt-master/BNT/general/do_intervention.m b/sourcecodes/bnt-master/BNT/general/do_intervention.m
new file mode 100644
index 00000000..2cfab871
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/do_intervention.m
@@ -0,0 +1,13 @@
+function bnet = mutilate_bnet(bnet, nodes, vals)
+% MUTILATE_BNET Clamp nodes to specific values (perform a surgical intervention)
+% bnet = mutilate_bnet(bnet, nodes, vals)
+%
+% We make all the clamped nodes roots.
+
+ns = bnet.node_sizes;
+for i=1:length(nodes)
+  X = nodes(i);
+  x = vals(i);
+  bnet.dag(:,X) = 0;
+  bnet.CPD{X} = root_CPD(bnet, X, x);
+end
diff --git a/sourcecodes/bnt-master/BNT/general/dsep.m b/sourcecodes/bnt-master/BNT/general/dsep.m
new file mode 100644
index 00000000..d4d9c441
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/dsep.m
@@ -0,0 +1,15 @@
+function sep = dsep(X, Y, S, G)
+% DSEP Is X indep Y given S wrt DAG G?
+% sep = dsep(X, Y, S, G)
+%
+% Instead of using the Bayes-Ball criterion, we see if S separates X and Y
+% in the moralized ancestral graph.
+
+conn = reachability_graph(G);
+M = myunion(myunion(X, Y), S);
+[A,junk] = find(conn(:, M));
+A = unique(A);
+A = myunion(A, M);
+GM = moralize(G(A,A));
+%sep = graph_separated(GM, X, Y, S);
+sep = graph_separated(GM, find_equiv_posns(X,A), find_equiv_posns(Y,A), find_equiv_posns(S,A));
diff --git a/sourcecodes/bnt-master/BNT/general/dsep_test.m b/sourcecodes/bnt-master/BNT/general/dsep_test.m
new file mode 100644
index 00000000..f0f14638
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/dsep_test.m
@@ -0,0 +1,15 @@
+
+% Cowell et al p72
+G = zeros(10);
+G(1,2)=1;
+G(2,3)=1;
+G(3,7)=1;
+G(4,[5 8])=1;
+G(5,6)=1;
+G(6,7)=1;
+G(7,[9 10])=1;
+G(8,9)=1;
+
+dsep(1, 4, [5 7], G)
+dsep(1, 4, [7], G)
+dsep(1, 4, [10 5], G)
diff --git a/sourcecodes/bnt-master/BNT/general/enumerate_scenarios.m b/sourcecodes/bnt-master/BNT/general/enumerate_scenarios.m
new file mode 100644
index 00000000..7d143065
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/enumerate_scenarios.m
@@ -0,0 +1,21 @@
+function [scenarios, log_probs] = enumerate_scenarios(bnet, evidence)
+% ENUMERATE_SCENARIOS Enumerate all assignments, and return the prob. of the non-zeros ones
+% function [scenarios, log_probs] = enumerate_scenarios(bnet, evidence)
+
+assert(isempty(bnet.cnodes));
+n = length(bnet.dag);
+observed = ~isemptycell(evidence);
+vals = cat(1,evidence{observed});
+vals = vals(:)';
+ns = bnet.node_sizes;
+
+log_probs = [];
+scenarios = [];
+for i=1:prod(ns)
+  inst = ind2subv(ns, i); % i'th instantiation
+  if isempty(vals) | inst(observed) == vals % agrees with evidence
+    ll = log_lik_complete(bnet, num2cell(inst(:)));
+    log_probs = [log_probs ll];
+    scenarios = [scenarios(:)' inst];
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/general/fgraph_to_bnet.m b/sourcecodes/bnt-master/BNT/general/fgraph_to_bnet.m
new file mode 100644
index 00000000..9aaf40ef
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/fgraph_to_bnet.m
@@ -0,0 +1,30 @@
+function bnet = fgraph_to_bnet(fg)
+% FGRAPH_TO_BNET Convert a factor graph to a Bayes net
+% bnet = fgraph_to_bnet(fg)
+%
+% We assume all factors are tabular_CPD.
+% We create 1 dummy observed node for every factor.
+
+N = fg.nvars + fg.nfactors;
+vnodes = 1:fg.nvars;
+fnodes = fg.nvars+1:N;
+dag = zeros(N);
+for x=1:fg.nvars
+  dag(x, fnodes(fg.dep{x})) = 1;
+end
+ns = [fg.node_sizes ones(1, fg.nfactors)];
+discrete = [fg.dnodes fnodes];
+bnet = mk_bnet(dag, ns, 'discrete', discrete);
+for x=1:fg.nvars
+  bnet.CPD{x} = tabular_CPD(bnet, x, 'CPT', 'unif');
+end
+ev = cell(1, fg.nvars); % no evidence
+for i=1:fg.nfactors
+  f = fnodes(i);
+  e = fg.equiv_class(i);
+  pot = convert_to_pot(fg.factors{e}, 'd', fg.dom{i}, ev);
+  m = pot_to_marginal(pot);
+  bnet.CPD{f} = tabular_CPD(bnet, f, 'CPT', m.T);
+end
+  
+  
diff --git a/sourcecodes/bnt-master/BNT/general/hodbn_to_bnet.m b/sourcecodes/bnt-master/BNT/general/hodbn_to_bnet.m
new file mode 100644
index 00000000..3026665d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/hodbn_to_bnet.m
@@ -0,0 +1,21 @@
+function bnet = hodbn_to_bnet(dbn, T)
+% DBN_TO_BNET Convert a DBN to a static network by unroll for T slices
+% bnet = dbn_to_bnet(dbn, T)
+ss = length(dbn.intra);
+[row,order] = size(dbn.equiv_class);
+eclass = [];
+for i = 1:min(order,T)
+     eclass = [eclass ; dbn.equiv_class(:,i)];
+end
+if T > order
+    eclass = [eclass ; repmat(dbn.equiv_class(:,order),T-order,1)]; 
+end
+
+dnodes = unroll_set(dbn.dnodes_slice, ss, T);
+ns = repmat(dbn.node_sizes_slice(:), 1, T);
+dag = unroll_higher_order_topology(dbn.intra, dbn.inter, T, dbn.intra1);
+onodes = unroll_set(dbn.observed(:), ss, T);
+bnet = mk_bnet(dag, ns(:), 'discrete', dnodes(:), 'equiv_class', eclass(:), 'observed', onodes(:));
+bnet.CPD = dbn.CPD;
+ 
+
diff --git a/sourcecodes/bnt-master/BNT/general/is_mnet.m b/sourcecodes/bnt-master/BNT/general/is_mnet.m
new file mode 100644
index 00000000..c6202e41
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/is_mnet.m
@@ -0,0 +1,3 @@
+function m = is_mnet(model)
+
+m = isfield(model, 'markov_net');
diff --git a/sourcecodes/bnt-master/BNT/general/linear_gaussian_to_cpot.m b/sourcecodes/bnt-master/BNT/general/linear_gaussian_to_cpot.m
new file mode 100644
index 00000000..f5a4251b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/linear_gaussian_to_cpot.m
@@ -0,0 +1,43 @@
+function pot = linear_gaussian_to_cpot(mu, Sigma, W, domain, ns, cnodes, evidence)
+% LINEAR_GAUSSIAN_TO_CPOT Convert a linear Gaussian CPD  to a canonical potential.
+% pot = linear_gaussian_to_cpot(mu, Sigma, W, domain, ns, cnodes, evidence)
+%
+% We include any cts evidence, but ignore any discrete evidence.
+% (Use gaussian_CPD_params_given_dps to use discrete evidence to select mu, Sigma, W.)
+
+odom = domain(~isemptycell(evidence(domain)));
+hdom = domain(isemptycell(evidence(domain)));
+cobs = myintersect(cnodes, odom);
+chid = myintersect(cnodes, hdom);
+cvals = cat(1, evidence{cobs});
+
+%[g,h,K] = gaussian_to_canonical(mu, Sigma, W);
+Sinv = inv(Sigma);
+g = -0.5*mu'*Sinv*mu + log(normal_coef(Sigma));
+if isempty(W) || (size(W,2)==0)  % no cts parents
+  h = Sinv*mu;
+  K = Sinv;
+else
+  h = [-W'*Sinv*mu; Sinv*mu];
+  K = [W'*Sinv*W  -W'*Sinv';
+       -Sinv*W     Sinv]; 
+end
+
+if ~isempty(cvals)
+  %[g, h, K] = enter_evidence_canonical(g, h, K, chid, cobs, cvals(:), ns);  
+  [hx, hy, KXX, KXY, KYX, KYY] = partition_matrix_vec(h, K, chid, cobs, ns);
+  y = cvals(:);
+  g = g + hy'*y - 0.5*y'*KYY*y;
+  if length(hx)==0 % isempty(X) % i.e., we have instantiated everything away
+    h = [];
+    K = [];
+  else
+    h = hx - KXY*y;
+    K = KXX;
+  end
+end
+
+ns(odom) = 0;
+pot = cpot(domain, ns(domain), g, h, K);
+
+
diff --git a/sourcecodes/bnt-master/BNT/general/log_lik_complete.m b/sourcecodes/bnt-master/BNT/general/log_lik_complete.m
new file mode 100644
index 00000000..de0d9c51
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/log_lik_complete.m
@@ -0,0 +1,30 @@
+function L = log_lik_complete(bnet, cases, clamped)
+% LOG_LIK_COMPLETE Compute sum_m sum_i log P(x(i,m)| x(pi_i,m), theta_i) for a completely observed data set
+% L = log_lik_complete(bnet, cases, clamped)
+%
+% If there is a missing data, you must use an inference engine.
+% cases(i,m) is the value assigned to node i in case m.
+% (If there are vector-valued nodes, cases should be a cell array.)
+% clamped(i,m) = 1 if node i was set by intervention in case m (default: clamped = zeros)
+% Clamped nodes contribute a factor of 1.0 to the likelihood.
+
+if iscell(cases), usecell = 1; else usecell = 0; end
+
+n = length(bnet.dag);
+ncases = size(cases, 2);
+if n ~= size(cases, 1)
+  error('data should be of size nnodes * ncases');
+end
+
+if nargin < 3, clamped = zeros(n,ncases); end
+
+L = 0;
+for i=1:n
+  ps = parents(bnet.dag, i);
+  e = bnet.equiv_class(i);
+  u = find(clamped(i,:)==0);
+  ll = log_prob_node(bnet.CPD{e}, cases(i,u), cases(ps,u));
+  if approxeq(exp(ll), 0),  fprintf('node %d has very low likelihood\n'); end
+  L = L + ll;
+end
+
diff --git a/sourcecodes/bnt-master/BNT/general/log_marg_lik_complete.m b/sourcecodes/bnt-master/BNT/general/log_marg_lik_complete.m
new file mode 100644
index 00000000..8737b757
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/log_marg_lik_complete.m
@@ -0,0 +1,40 @@
+function L = log_marg_lik_complete(bnet, cases, clamped)
+% LOG_MARG_LIK_COMPLETE Compute sum_m sum_i log P(x(i,m)| x(pi_i,m)) for a completely observed data set
+% L = log_marg_lik_complete(bnet, cases, clamped)
+%
+% This differs from log_lik_complete because we integrate out the parameters.   
+% If there is a missing data, you must use an inference engine.
+% cases(i,m) is the value assigned to node i in case m.
+% (If there are vector-valued nodes, cases should be a cell array.)
+% clamped(i,m) = 1 if node i was set by intervention in case m (default: clamped = zeros)
+% Clamped nodes contribute a factor of 1.0 to the likelihood.
+%
+% If there is a single case, clamped is a list of the clamped nodes, not a bit vector.
+
+if iscell(cases), usecell = 1; else usecell = 0; end
+
+n = length(bnet.dag);
+ncases = size(cases, 2);
+if n ~= size(cases, 1)
+  error('data should be of size nnodes * ncases');
+end
+
+if ncases == 1
+  if nargin < 3, clamped = []; end
+  clamp_set = clamped;
+  clamped = zeros(n,1);
+  clamped(clamp_set) = 1;
+else
+  if nargin < 3, clamped = zeros(n,ncases); end
+end
+
+L = 0;
+for i=1:n
+  ps = parents(bnet.dag, i);
+  e = bnet.equiv_class(i);
+  u = find(clamped(i,:)==0);
+  L = L + log_marg_prob_node(bnet.CPD{e}, cases(i,u), cases(ps,u));
+end
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/general/mk_bnet.m b/sourcecodes/bnt-master/BNT/general/mk_bnet.m
new file mode 100644
index 00000000..37560ac2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/mk_bnet.m
@@ -0,0 +1,93 @@
+function bnet = mk_bnet(dag, node_sizes, varargin)
+% MK_BNET Make a Bayesian network.
+%
+% BNET = MK_BNET(DAG, NODE_SIZES, ...) makes a graphical model with an arc from i to j iff DAG(i,j) = 1.
+% Thus DAG is the adjacency matrix for a directed acyclic graph.
+% The nodes are assumed to be in topological order. Use TOPOLOGICAL_SORT if necessary.
+%
+% node_sizes(i) is the number of values node i can take on,
+%   or the length of node i if i is a continuous-valued vector.
+% node_sizes(i) = 1 if i is a utility node.
+% 
+% Below are the names of optional arguments [and their default value in brackets].
+% Pass as 'PropertyName1', PropertyValue1, 'PropertyName2', PropertyValue2, ...
+% 
+% discrete - the list of nodes which are discrete random variables [1:N]
+% equiv_class - equiv_class(i)=j  means node i gets its params from CPD{j} [1:N]
+% observed - the list of nodes which will definitely be observed in every case [ [] ]
+% 'names' - a cell array of strings to be associated with nodes 1:n [{}]
+%    This creates an associative array, so you write e.g.
+%     'evidence(bnet.names{'bar'}) = 42' instead of  'evidence(2} = 42' 
+%     assuming names = { 'foo', 'bar', ...}.
+%
+% e.g., bnet = mk_bnet(dag, ns, 'discrete', [1 3])
+%
+% For backwards compatibility with BNT2, you can also specify the parameters in the following order
+%   bnet = mk_bnet(dag, node_sizes, discrete_nodes, equiv_class)
+
+n = length(dag);
+
+% default values for parameters
+bnet.equiv_class = 1:n;
+bnet.dnodes = 1:n; % discrete 
+bnet.observed = [];
+bnet.names = {};
+
+if nargin >= 3
+  args = varargin;
+  nargs = length(args);
+  if ~ischar(args{1})
+    if nargs >= 1, bnet.dnodes = args{1}; end
+    if nargs >= 2, bnet.equiv_class = args{2}; end
+  else    
+    for i=1:2:nargs
+      switch args{i},
+       case 'equiv_class', bnet.equiv_class = args{i+1}; 
+       case 'discrete',    bnet.dnodes = args{i+1}; 
+       case 'observed',    bnet.observed = args{i+1}; 
+       case 'names',  bnet.names = assocarray(args{i+1}, num2cell(1:n)); 
+       otherwise,  
+	error(['invalid argument name ' args{i}]);       
+      end
+    end
+  end
+end
+
+bnet.observed = sort(bnet.observed); % for comparing sets
+bnet.hidden = mysetdiff(1:n, bnet.observed(:)');
+bnet.hidden_bitv = zeros(1,n);
+bnet.hidden_bitv(bnet.hidden) = 1;
+bnet.dag = dag;
+bnet.node_sizes = node_sizes(:)';
+
+bnet.cnodes = mysetdiff(1:n, bnet.dnodes);
+% too many functions refer to cnodes to rename it to cts_nodes - 
+% We hope it won't be confused with chance nodes!
+
+bnet.parents = cell(1,n);
+for i=1:n
+  bnet.parents{i} = parents(dag, i);
+end
+
+E = max(bnet.equiv_class);
+mem = cell(1,E);
+for i=1:n
+  e = bnet.equiv_class(i);
+  mem{e} = [mem{e} i];
+end
+bnet.members_of_equiv_class = mem;
+
+bnet.CPD = cell(1, E);
+
+bnet.rep_of_eclass = zeros(1,E);
+for e=1:E
+  mems = bnet.members_of_equiv_class{e};
+  bnet.rep_of_eclass(e) = mems(1);
+end
+
+directed = 1;
+if ~acyclic(dag,directed)
+  error('graph must be acyclic')
+end
+
+bnet.order = topological_sort(bnet.dag);
diff --git a/sourcecodes/bnt-master/BNT/general/mk_dbn.m b/sourcecodes/bnt-master/BNT/general/mk_dbn.m
new file mode 100644
index 00000000..82859bc3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/mk_dbn.m
@@ -0,0 +1,133 @@
+function bnet = mk_dbn(intra, inter, node_sizes, varargin)
+% MK_DBN Make a Dynamic Bayesian Network.
+%
+% BNET = MK_DBN(INTRA, INTER, NODE_SIZES, ...) makes a DBN with arcs
+% from i in slice t to j in slice t iff intra(i,j) = 1, and 
+% from i in slice t to j in slice t+1 iff inter(i,j) = 1,
+% for i,j in {1, 2, ..., n}, where n = num. nodes per slice, and t >= 1.
+% node_sizes(i) is the number of values node i can take on.
+% The nodes are assumed to be in topological order. Use TOPOLOGICAL_SORT if necessary.
+% See also mk_bnet.
+%
+% Optional arguments [default in brackets]
+% 'discrete' - list of discrete nodes [1:n]
+% 'observed' - the list of nodes which will definitely be observed in every slice of every case [ [] ]
+% 'eclass1' - equiv class for slice 1 [1:n]
+% 'eclass2' - equiv class for slice 2 [tie nodes with equivalent parents to slice 1]
+%    equiv_class1(i) = j means node i in slice 1 gets its parameters from bnet.CPD{j},
+%    i.e., nodes i and j have tied parameters.
+% 'intra1' - topology of first slice, if different from others
+% 'names' - a cell array of strings to be associated with nodes 1:n [{}]
+%    This creates an associative array, so you write e.g.
+%     'evidence(bnet.names{'bar'}) = 42' instead of  'evidence(2} = 42' 
+%     assuming names = { 'foo', 'bar', ...}.
+%    
+% For backwards compatibility with BNT2, arguments can also be specified as follows
+%   bnet = mk_dbn(intra, inter, node_sizes, dnodes, eclass1, eclass2, intra1)
+%
+% After calling this function, you must specify the parameters (conditional probability
+% distributions) using bnet.CPD{i} = gaussian_CPD(...) or tabular_CPD(...) etc.
+
+
+n = length(intra);
+ss = n;
+bnet.nnodes_per_slice = ss;
+bnet.intra = intra;
+bnet.inter = inter;
+bnet.intra1 = intra;
+dag = zeros(2*n);
+dag(1:n,1:n) = bnet.intra1;
+dag(1:n,(1:n)+n) = bnet.inter;
+dag((1:n)+n,(1:n)+n) = bnet.intra;
+bnet.dag = dag;
+bnet.names = {};
+
+directed = 1;
+if ~acyclic(dag,directed)
+  error('graph must be acyclic')
+end
+
+
+bnet.eclass1 = 1:n;
+%bnet.eclass2 = (1:n)+n;
+bnet.eclass2 = bnet.eclass1;
+for i=1:ss
+  if isequal(parents(dag, i+ss), parents(dag, i)+ss)
+    %fprintf('%d has isomorphic parents, eclass %d\n', i, bnet.eclass2(i))
+  else
+    bnet.eclass2(i) = max(bnet.eclass2) + 1;
+    %fprintf('%d has non isomorphic parents, eclass %d\n', i, bnet.eclass2(i))
+  end
+end
+
+dnodes = 1:n;
+bnet.observed = [];
+
+if nargin >= 4
+  args = varargin;
+  nargs = length(args);
+  if ~isstr(args{1})
+    if nargs >= 1, dnodes = args{1}; end
+    if nargs >= 2, bnet.eclass1 = args{2}; end
+    if nargs >= 3, bnet.eclass2 = args{3}; end
+    if nargs >= 4, bnet.intra1 = args{4}; end
+  else
+    for i=1:2:nargs
+      switch args{i},
+       case 'discrete', dnodes = args{i+1}; 
+       case 'observed', bnet.observed = args{i+1}; 
+       case 'eclass1',  bnet.eclass1 = args{i+1}; 
+       case 'eclass2',  bnet.eclass2 = args{i+1}; 
+       case 'intra1',  bnet.intra1 = args{i+1}; 
+       %case 'ar_hmm',  bnet.ar_hmm = args{i+1};  % should check topology
+       case 'names',  bnet.names = assocarray(args{i+1}, num2cell(1:n)); 
+       otherwise,  
+	error(['invalid argument name ' args{i}]);       
+      end
+    end
+  end
+end
+
+
+bnet.observed = sort(bnet.observed); % for comparing sets
+ns = node_sizes;
+bnet.node_sizes_slice = ns(:)';
+bnet.node_sizes = [ns(:) ns(:)];
+
+cnodes = mysetdiff(1:n, dnodes);
+bnet.dnodes_slice = dnodes;
+bnet.cnodes_slice = cnodes;
+bnet.dnodes = [dnodes dnodes+n];
+bnet.cnodes = [cnodes cnodes+n];
+
+bnet.equiv_class = [bnet.eclass1(:) bnet.eclass2(:)];
+bnet.CPD = cell(1,max(bnet.equiv_class(:)));
+eclass = bnet.equiv_class(:);
+E = max(eclass);
+bnet.rep_of_eclass = zeros(1,E);
+for e=1:E
+  mems = find(eclass==e);
+  bnet.rep_of_eclass(e) = mems(1);
+end
+
+ss = n;
+onodes = bnet.observed;
+hnodes = mysetdiff(1:ss, onodes);
+bnet.hidden_bitv = zeros(1,2*ss);
+bnet.hidden_bitv(hnodes) = 1;
+bnet.hidden_bitv(hnodes+ss) = 1;
+
+bnet.parents = cell(1, 2*ss);
+for i=1:ss
+  bnet.parents{i} = parents(bnet.dag, i);
+  bnet.parents{i+ss} = parents(bnet.dag, i+ss);
+end
+
+bnet.auto_regressive = zeros(1,ss);
+% ar(i)=1 means (observed) node i depends on i in the  previous slice
+for o=bnet.observed(:)'
+  if any(bnet.parents{o+ss} <= ss)
+    bnet.auto_regressive(o) = 1;
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/general/mk_fgraph.m b/sourcecodes/bnt-master/BNT/general/mk_fgraph.m
new file mode 100644
index 00000000..8ac50338
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/mk_fgraph.m
@@ -0,0 +1,60 @@
+function fg = mk_fgraph(G, node_sizes, factors, varargin)
+% MK_FGRAPH Make a factor graph
+% fg = mk_fgraph(G, node_sizes, factors, ...)
+%
+% A factor graph is a bipartite graph, with one side containing variables,
+% and the other containing functions of (subsets of) these variables.
+% For details, see "Factor Graphs and the Sum-Product Algorithm",
+%  F. Kschischang and B. Frey and H-A. Loeliger,
+%  IEEE Trans. Info. Theory, 2001
+%
+% G(i,j) = 1 if there is an arc from variable i to factor j
+%
+% node_sizes(i) is the number of values node i can take on,
+%   or the length of node i if i is a continuous-valued vector.
+%
+% 'factors' is the list of factors (kernel functions)
+%
+% The list below gives optional arguments [default value in brackets].
+% 
+% equiv_class - equiv_class(i)=j  means factor node i gets its params from factors{j} [1:F]
+% discrete - the list of nodes which are discrete random variables [1:N]
+%
+% e.g., fg = mk_fgraph(G, [2 2], {bnet.CPD{1},bnet.CPD{2}}, 'discrete', [1 2])
+
+fg.G = G;
+fg.node_sizes = node_sizes;
+fg.factors = factors;
+[fg.nvars fg.nfactors] = size(G);
+
+% default values for parameters
+fg.equiv_class = 1:fg.nfactors;
+fg.dnodes = 1:fg.nvars;
+
+if nargin >= 4
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'equiv_class', fg.equiv_class = args{i+1}; 
+     case 'discrete',    fg.dnodes = args{i+1}; 
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+% so that determine_pot_type will work...
+fg.utility_nodes = [];
+%fg.decision_nodes = [];
+%fg.chance_nodes = fg.nvars;
+
+fg.dom = cell(1, fg.nfactors);
+for f=1:fg.nfactors
+  fg.dom{f} = find(G(:,f));
+end
+fg.dep = cell(1, fg.nvars);
+for x=1:fg.nvars
+  fg.dep{x} = find(G(x,:));
+end
+fg.cnodes = mysetdiff(1:fg.nvars, fg.dnodes);
diff --git a/sourcecodes/bnt-master/BNT/general/mk_fgraph_given_ev.m b/sourcecodes/bnt-master/BNT/general/mk_fgraph_given_ev.m
new file mode 100644
index 00000000..5e65ed10
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/mk_fgraph_given_ev.m
@@ -0,0 +1,48 @@
+function fg = mk_fgraph_given_ev(G, node_sizes, factors, ev_CPD, evidence, varargin)
+% MK_FGRAPH_GIVEN_EV Make a factor graph where each node has its own private evidence term
+% fg = mk_fgraph(G, node_sizes, factors, ev_CPD, evidence, ...)
+%
+% G, node_sizes and factors are as in mk_fgraph, but they refer to the hidden nodes.
+% ev_CPD{i} is a CPD for the i'th hidden node; this will be converted into a factor
+% for node i using evidence{i}.
+% We currently assume all hidden nodes are discrete, for simplicity.
+%
+% The list below gives optional arguments [default value in brackets].
+% 
+% equiv_class - equiv_class(i)=j  means factor node i gets its params from factors{j} [1:F]
+% ev_equiv_class - ev_equiv_class(i)=j  means evidence node i gets its params from ev_CPD{j} [1:N]
+
+
+N = length(node_sizes);
+nfactors = length(factors);
+
+% default values for parameters
+eclass = 1:nfactors;
+ev_eclass = 1:N;
+
+if nargin >= 6
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'equiv_class', eclass = args{i+1}; 
+     case 'ev_equiv_class', ev_eclass = args{i+1}; 
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+pot_type = 'd';
+for x=1:N
+  ev = cell(1,2); % cell 1 is the hidden parent, cell 2 is the observed child
+  ev(2) = evidence(x); 
+  dom = 1:2;
+  F = convert_to_pot(ev_CPD{ev_eclass(x)}, pot_type, dom(:), ev);
+  M = pot_to_marginal(F);
+  %factors{end+1} = tabular_CPD('self', 1, 'ps', [], 'sz', node_sizes(x), 'CPT', M.T);
+  factors{end+1} = mk_isolated_tabular_CPD(node_sizes(x), {'CPT', M.T});
+end
+
+E = max(eclass);
+fg = mk_fgraph([G eye(N)], node_sizes, factors, 'equiv_class', [eclass E+1:E+N]);
diff --git a/sourcecodes/bnt-master/BNT/general/mk_higher_order_dbn.m b/sourcecodes/bnt-master/BNT/general/mk_higher_order_dbn.m
new file mode 100644
index 00000000..eb01636e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/mk_higher_order_dbn.m
@@ -0,0 +1,181 @@
+function bnet = mk_higher_order_dbn(intra, inter, node_sizes, varargin)
+% MK_DBN Make a Dynamic Bayesian Network.
+%
+% BNET = MK_DBN(INTRA, INTER, NODE_SIZES, ...) makes a DBN with arcs
+% from i in slice t to j in slice t iff intra(i,j) = 1, and 
+% from i in slice t to j in slice t+1 iff inter(i,j) = 1,
+% for i,j in {1, 2, ..., n}, where n = num. nodes per slice, and t >= 1.
+% node_sizes(i) is the number of values node i can take on.
+% The nodes are assumed to be in topological order. Use TOPOLOGICAL_SORT if necessary.
+% See also mk_bnet.
+%
+% Optional arguments [default in brackets]
+% 'discrete' - list of discrete nodes [1:n]
+% 'observed' - the list of nodes which will definitely be observed in every slice of every case [ [] ]
+% 'eclass1' - equiv class for slice 1 [1:n]
+% 'eclass2' - equiv class for slice 2 [tie nodes with equivalent parents to slice 1]
+%    equiv_class1(i) = j means node i in slice 1 gets its parameters from bnet.CPD{j},
+%    i.e., nodes i and j have tied parameters.
+% 'intra1' - topology of first slice, if different from others
+% 'names' - a cell array of strings to be associated with nodes 1:n [{}]
+%    This creates an associative array, so you write e.g.
+%     'evidence(bnet.names{'bar'}) = 42' instead of  'evidence(2} = 42' 
+%     assuming names = { 'foo', 'bar', ...}.
+%    
+% For backwards compatibility with BNT2, arguments can also be specified as follows
+%   bnet = mk_dbn(intra, inter, node_sizes, dnodes, eclass1, eclass2, intra1)
+%
+% After calling this function, you must specify the parameters (conditional probability
+% distributions) using bnet.CPD{i} = gaussian_CPD(...) or tabular_CPD(...) etc.
+
+
+n = length(intra);
+ss = n;
+bnet.nnodes_per_slice = ss;
+bnet.intra = intra;
+bnet.inter = inter;
+bnet.intra1 = intra;
+
+% As this method is used to generate a higher order Markov Model
+% also connect from time slice t - i -> t with i > 1 has to be 
+% taken into account.
+
+%inter should be a three dimensional array where inter(:,:,i)
+%describes the connections from time-slice t - i to t.  
+[rows,columns,order] = size(inter);
+assert(rows    == n);
+assert(columns == n);
+dag = zeros((order + 1)*n);
+
+i = 0;
+while i <= order
+    j = i;
+    while j <= order
+        if j == i
+            dag(1 + i*n:(i+1)*n,1+i*n:(i+1)*n) = intra;
+        else
+            dag(1+i*n:(i+1)*n,1+j*n:(j+1)*n) = inter(:,:,j - i);
+        end
+        j = j + 1;
+    end;
+    i = i + 1;
+end;
+
+bnet.dag = dag;
+bnet.names = {};
+
+directed = 1;
+if ~acyclic(dag,directed)
+  error('graph must be acyclic')
+end
+
+% Calculation of the equivalence classes
+bnet.eclass1 = 1:n;
+bnet.eclass = zeros(order + 1,ss);
+bnet.eclass(1,:) = 1:n;
+for i = 1:order
+    bnet.eclass(i+1,:) = bnet.eclass(i,:);
+    for j = 1:ss 
+        if(isequal(parents(dag,(i-1)*n+j)+ss,parents(dag,(i*n + j))))
+	   %fprintf('%d has isomorphic parents, eclass %d \n',j,bnet.eclass(i,j))
+        else
+	   bnet.eclass(i + 1,j) = max(bnet.eclass(i+1,:))+1;
+	   %fprintf('%d has non isomorphic parents, eclass %d \n',j,bnet.eclass(i,j))  
+	end;
+    end;
+end;
+bnet.eclass1 = 1:n;
+
+% To be compatible with whe rest of the code 
+bnet.eclass2 = bnet.eclass(2,:);
+
+dnodes = 1:n;
+bnet.observed = [];
+
+if nargin >= 4
+  args = varargin;
+  nargs = length(args);
+  if ~isstr(args{1})
+    if nargs >= 1 dnodes = args{1}; end
+    if nargs >= 2 bnet.eclass1 = args{2}; bnet.eclass(1,:) = args{2}; end
+    if nargs >= 3 bnet.eclass2 = args{3}; bnet.eclass(2,:) = args{2}; end
+    if nargs >= 4 bnet.intra1 = args{4}; end
+  else
+    for i=1:2:nargs
+      switch args{i},
+       case 'discrete', dnodes = args{i+1}; 
+       case 'observed', bnet.observed = args{i+1}; 
+       case 'eclass1',  bnet.eclass1 = args{i+1}; bnet.eclass(1,:) = args{i+1}; 
+       case 'eclass2',  bnet.eclass2 = args{i+1}; bnet.eclass(2,:) = args{i+1};
+       case 'eclass',   bnet.eclass = args{i+1};  
+       case 'intra1',  bnet.intra1 = args{i+1}; 
+       %case 'ar_hmm',  bnet.ar_hmm = args{i+1};  % should check topology
+       case 'names',  bnet.names = assocarray(args{i+1}, num2cell(1:n)); 
+       otherwise,  
+	error(['invalid argument name ' args{i}]);       
+      end
+    end
+  end
+end
+
+bnet.observed = sort(bnet.observed); % for comparing sets
+ns = node_sizes;
+bnet.node_sizes_slice = ns(:)';
+bnet.node_sizes = repmat(ns(:),1,order + 1);
+
+cnodes = mysetdiff(1:n, dnodes);
+bnet.dnodes_slice = dnodes;
+bnet.cnodes_slice = cnodes;
+bnet.dnodes = dnodes;
+bnet.cnodes = cnodes;
+% To adapt the function to higher order Markov models include dnodes for more 
+% time slices
+for i = 1:order
+    bnet.dnodes = [bnet.dnodes dnodes+i*n];
+    bnet.cnodes = [bnet.cnodes cnodes+i*n];
+end
+
+% Generieren einer Matrix, deren i-te Spalte die Aequivalenzklassen
+% der i-ten Zeitscheibe enthaelt. 
+bnet.equiv_class = [bnet.eclass(1,:)]';
+for i = 2:(order + 1)
+    bnet.equiv_class = [bnet.equiv_class   bnet.eclass(i,:)'];
+end
+
+bnet.CPD = cell(1,max(bnet.equiv_class(:)));
+
+ss = n;
+onodes = bnet.observed;
+hnodes = mysetdiff(1:ss, onodes);
+bnet.hidden_bitv = zeros(1,(order + 1)*ss);
+for i = 0:order
+    bnet.hidden_bitv(hnodes +i*ss) = 1;
+end;
+
+bnet.parents = cell(1, (order + 1)*ss);
+for i=1:(order + 1)*ss
+  bnet.parents{i} = parents(bnet.dag, i);
+end
+
+bnet.auto_regressive = zeros(1,ss);
+% ar(i)=1 means (observed) node i depends on i in the  previous slice
+for o=bnet.observed(:)'
+  if any(bnet.parents{o+ss} <= ss)
+    bnet.auto_regressive(o) = 1;
+  end
+end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/general/mk_limid.m b/sourcecodes/bnt-master/BNT/general/mk_limid.m
new file mode 100644
index 00000000..3c10ed81
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/mk_limid.m
@@ -0,0 +1,93 @@
+function bnet = mk_limid(dag, node_sizes, varargin)
+% MK_LIMID Make a limited information influence diagram
+%
+% BNET = MK_LIMID(DAG, NODE_SIZES, ...) 
+% DAG is the adjacency matrix for a directed acyclic graph.
+% The nodes are assumed to be in topological order. Use TOPOLOGICAL_SORT if necessary.
+% For decision nodes, the parents must explicitely include all nodes
+% on which it can depends, in contrast to the implicit no-forgetting assumption of influence diagrams.
+% (For details, see "Representing and solving decision problems with limited information",
+%    Lauritzen and Nilsson, Management Science, 2001.)
+%
+% node_sizes(i) is the number of values node i can take on,
+%   or the length of node i if i is a continuous-valued vector.
+% node_sizes(i) = 1 if i is a utility node.
+% 
+% The list below gives optional arguments [default value in brackets].
+% 
+% chance   - the list of nodes which are random variables [1:N]
+% decision - the list of nodes which are decision nodes [ [] ]
+% utility  - the list of nodes which are utility nodes [ [] ]
+% equiv_class - equiv_class(i)=j  means node i gets its params from CPD{j} [1:N]
+%
+% e.g., limid = mk_limid(dag, ns, 'chance', [1 3], 'utility', [2])
+
+n = length(dag);
+
+% default values for parameters
+bnet.chance_nodes = 1:n;
+bnet.equiv_class = 1:n;
+bnet.utility_nodes = [];
+bnet.decision_nodes = [];
+bnet.dnodes = 1:n; % discrete 
+
+if nargin >= 3
+  args = varargin;
+  nargs = length(args);
+  if ~isstr(args{1})
+    if nargs >= 1, bnet.dnodes = args{1}; end
+    if nargs >= 2, bnet.equiv_class = args{2}; end
+  else    
+    for i=1:2:nargs
+      switch args{i},
+       case 'equiv_class', bnet.equiv_class = args{i+1}; 
+       case 'chance',      bnet.chance_nodes = args{i+1}; 
+       case 'utility',     bnet.utility_nodes = args{i+1}; 
+       case 'decision',    bnet.decision_nodes = args{i+1}; 
+       case 'discrete',    bnet.dnodes = args{i+1}; 
+        otherwise,  
+	error(['invalid argument name ' args{i}]);       
+      end
+    end
+  end
+end
+ 
+bnet.limid = 1;
+
+bnet.dag = dag;
+bnet.node_sizes = node_sizes(:)';
+
+bnet.cnodes = mysetdiff(1:n, bnet.dnodes);
+% too many functions refer to cnodes to rename it to cts_nodes - 
+% We hope it won't be confused with chance nodes!
+
+bnet.parents = cell(1,n);
+for i=1:n
+  bnet.parents{i} = parents(dag, i);
+end
+
+E = max(bnet.equiv_class);
+mem = cell(1,E);
+for i=1:n
+  e = bnet.equiv_class(i);
+  mem{e} = [mem{e} i];
+end
+bnet.members_of_equiv_class = mem;
+
+bnet.CPD = cell(1, E);
+
+% for e=1:E
+%   i = bnet.members_of_equiv_class{e}(1); % pick arbitrary member
+%   switch type{e}
+%     case 'tabular',  bnet.CPD{e} = tabular_CPD(bnet, i);
+%     case 'gaussian', bnet.CPD{e} = gaussian_CPD(bnet, i);
+%     otherwise, error(['unrecognized CPD type ' type{e}]);
+%   end
+% end
+
+directed = 1;
+if ~acyclic(dag,directed)
+  error('graph must be acyclic')
+end
+
+bnet.order = topological_sort(bnet.dag);
diff --git a/sourcecodes/bnt-master/BNT/general/mk_mnet.m b/sourcecodes/bnt-master/BNT/general/mk_mnet.m
new file mode 100644
index 00000000..38d4cab3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/mk_mnet.m
@@ -0,0 +1,14 @@
+function mnet = mk_mnet(graph, node_sizes, cliques, potentials)
+% MK_MNET Make a Markov network (Markov Random Field)
+%
+% mnet = mk_mnet(adj_mat, node_sizes, cliques, potentials)
+%
+% cliques{i} is a list of the nodes in clq i
+% potentials{i} is a dpot object corresponding to the potential for clique i
+%
+
+mnet.markov_net = 1;
+mnet.graph = graph;
+mnet.node_sizes = node_sizes;
+mnet.user_cliques = cliques;
+mnet.user_potentials = potentials;
diff --git a/sourcecodes/bnt-master/BNT/general/mk_mrf2.m b/sourcecodes/bnt-master/BNT/general/mk_mrf2.m
new file mode 100644
index 00000000..4d948864
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/mk_mrf2.m
@@ -0,0 +1,8 @@
+function mrf2 = mk_mrf2(adj_mat, pot)
+% MK_MRF2 Make a Markov random field with pairwise potentials
+% function mrf2 = mk_mrf2(adj_mat, pot)
+%
+% pot{i,j}(k1,k2)
+
+mrf2.adj_mat = adj_mat;
+mrf2.pot = pot;
diff --git a/sourcecodes/bnt-master/BNT/general/mk_mutilated_samples.m b/sourcecodes/bnt-master/BNT/general/mk_mutilated_samples.m
new file mode 100644
index 00000000..21a91063
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/mk_mutilated_samples.m
@@ -0,0 +1,38 @@
+function [data, clamped] = mk_mutilated_samples(bnet, ncases, max_clamp, usecell)
+% GEN_MUTILATED_SAMPLES Do random interventions and then draw random samples
+% [data, clamped] = gen_mutilated_samples(bnet, ncases, max_clamp, usecell)
+%
+% At each step, we pick a random subset of size 0 .. max_clamp, and 
+% clamp these nodes to random values.
+%
+% data(i,m) is the value of node i in case m.
+% clamped(i,m) = 1 if node i in case m was set by intervention.
+
+if nargin < 4, usecell = 1; end
+
+ns = bnet.node_sizes;
+n = length(bnet.dag);
+if usecell
+  data = cell(n, ncases);
+else
+  data = zeros(n, ncases);
+end
+clamped = zeros(n, ncases);
+
+csubsets = subsets(1:n, max_clamp, 0); % includes the empty set
+distrib_cset = normalise(ones(1, length(csubsets)));
+
+for m=1:ncases
+  cset = csubsets{sample_discrete(distrib_cset)};
+  nvals = prod(ns(cset));
+  distrib_cvals = normalise(ones(1, nvals));
+  cvals = ind2subv(ns(cset), sample_discrete(distrib_cvals));
+  mutilated_bnet = do_intervention(bnet, cset, cvals);
+  ev = sample_bnet(mutilated_bnet);
+  if usecell
+    data(:,m) = ev;
+  else
+    data(:,m) = cell2num(ev);
+  end
+  clamped(cset,m) = 1;
+end
diff --git a/sourcecodes/bnt-master/BNT/general/mk_named_CPT.m b/sourcecodes/bnt-master/BNT/general/mk_named_CPT.m
new file mode 100644
index 00000000..5f39a981
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/mk_named_CPT.m
@@ -0,0 +1,52 @@
+function CPT2 = mk_named_CPT(family_names, names, dag, CPT1)
+% MK_NAMED_CPT Permute the dimensions of a CPT so they agree with the internal numbering convention
+% CPT2 = mk_named_CPT(family_names, names, dag, CPT1)
+%
+% This is best explained by example.
+% Consider the following directed acyclic graph
+%
+%     C
+%   /   \
+%  R     S
+%   \   /
+%     W
+%
+% where all arcs point down.
+% When we create the CPT for node W, we consider S as its first parent, and R as its
+% second, and hence write
+%
+%      S R W
+% CPT1(1,1,:) = [1.0 0.0];
+% CPT1(2,1,:) = [0.2 0.8];  % P(W=1 | R=1, S=2) = 0.2
+% CPT1(1,2,:) = [0.1 0.9]; 
+% CPT1(2,2,:) = [0.01 0.99];
+%
+% However, when we create the dag using mk_adj_mat, the nodes get topologically sorted,
+% and by chance, node R preceeds node S in this ordering.
+% Hence we should have written
+%
+%      R S W
+% CPT2(1,1,:) = [1.0 0.0];
+% CPT2(2,1,:) = [0.1 0.9];
+% CPT2(1,2,:) = [0.2 0.8]; % P(W=1 | R=1, S=2) = 0.2
+% CPT2(2,2,:) = [0.01 0.99];
+%
+% Since we do not know the order of the nodes in advance, we can write
+%   CPT2 = mk_named_CPT({'S', 'R', 'W'}, names, dag, CPT1)
+% where 'S', 'R', 'W' are the order of the dimensions we assumed (the child node must be last in this list),
+% and names{i} is the name of the i'th node.
+
+n = length(family_names);
+family_nums = zeros(1,n);
+for i=1:n
+  family_nums(i) = stringmatch(family_names{i}, names); % was strmatch
+end
+
+fam = family(dag, family_nums(end));
+perm = zeros(1,n);
+for i=1:n
+  %  perm(i) = find(family_nums(i) == fam);
+  perm(i) = find(fam(i) == family_nums);
+end
+
+CPT2 = permute(CPT1, perm);
diff --git a/sourcecodes/bnt-master/BNT/general/mk_slice_and_half_dbn.m b/sourcecodes/bnt-master/BNT/general/mk_slice_and_half_dbn.m
new file mode 100644
index 00000000..80faad17
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/mk_slice_and_half_dbn.m
@@ -0,0 +1,28 @@
+function bnet15 = mk_slice_and_half_dbn(bnet, int)
+% function bnet = mk_slice_and_half_dbn(bnet, int)
+% function bnet = mk_slice_and_half_dbn(bnet, int)
+%
+% Create a "1.5 slice" jtree, containing the interface nodes of slice 1
+% and all the nodes of slice 2
+% To keep the node numbering the same, we simply disconnect the non-interface nodes
+% from slice 1, 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 (i.e., we can include nodes whose potentials will
+% be left as all 1s).
+
+intra15 = bnet.intra;
+ss = length(bnet.intra);
+nonint = mysetdiff(1:ss, int);
+for i=nonint(:)'
+  intra15(:,i) = 0;
+  intra15(i,:) = 0;
+  %assert(~any(bnet.inter(i,:)))
+end
+dag15 = [intra15      bnet.inter;
+	 zeros(ss)    bnet.intra];
+ns = bnet.node_sizes(:);
+ns(nonint) = 1; % disconnected nodes get size 1
+obs_nodes = [bnet.observed(:) bnet.observed(:)+ss];
+bnet15 = mk_bnet(dag15, ns, 'discrete', bnet.dnodes, 'equiv_class', bnet.equiv_class(:), ...
+		 'observed', obs_nodes(:));
diff --git a/sourcecodes/bnt-master/BNT/general/noisyORtoTable.m b/sourcecodes/bnt-master/BNT/general/noisyORtoTable.m
new file mode 100644
index 00000000..18dadd46
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/noisyORtoTable.m
@@ -0,0 +1,32 @@
+function CPT = noisyORtoTable(inhibit, leak_inhibit)
+% NOISYORTOTABLE Convert noisyOR distribution to CPT
+% function CPT = noisyORtoTable(inhibit, leak_inhibit)
+%
+% inhibit(i) = prob i'th parent will be inhibited (flipped from 1 to 0)
+% leak_inhibit - optional suppression of leak
+% CPT(U1,...,Un, X) = Pr(X|U1,...,Un) where the Us are the parents (excluding leak).
+% State 1 = off, 2 = on
+
+if nargin < 2, leak_inhibit = 1; end
+
+q = [leak_inhibit inhibit(:)'];
+
+if length(q)==1
+  CPT = [q  1-q];
+  return;
+end
+
+n = length(q);
+Bn = ind2subv(2*ones(1,n), 1:(2^n))-1;  % all n bit vectors, with the left most column toggling fastest (LSB)
+CPT = zeros(2^n, 2);
+% Pr(X=0 | U_1 .. U_n) = prod_{i: U_i = on} q_i =  prod_i q_i ^ U_i = exp(u' * log(q_i))
+% This method is problematic when q contains zeros
+
+Q = repmat(q(:)', 2^n, 1);
+Q(logical(~Bn)) = 1;
+CPT(:,1) = prod(Q,2);
+CPT(:,2) = 1-CPT(:,1);
+
+CPT = reshape(CPT(2:2:end), 2*ones(1,n)); % skip cases in which the leak is off       
+
+
diff --git a/sourcecodes/bnt-master/BNT/general/partition_dbn_nodes.m b/sourcecodes/bnt-master/BNT/general/partition_dbn_nodes.m
new file mode 100644
index 00000000..5185c6cb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/partition_dbn_nodes.m
@@ -0,0 +1,17 @@
+function [pnodes, tnodes] = partition_dbn_nodes(intra, inter)
+% PARTITION_DBN_NODES Divide the nodes into a DBN into persistent and transient.
+% [pnodes, tnodes] = partition_dbn_nodes(intra, inter)
+% Persistent nodes have children in the next time slice, transient nodes do not.
+ 
+ss = length(intra);
+pnodes = []; 
+tnodes = [];
+for i=1:ss
+  cs = children(inter, i);
+  if isempty(cs)
+    tnodes = [tnodes i];
+  else
+    pnodes = [pnodes i];
+  end
+end
+  
diff --git a/sourcecodes/bnt-master/BNT/general/partition_matrix_vec_3.m b/sourcecodes/bnt-master/BNT/general/partition_matrix_vec_3.m
new file mode 100644
index 00000000..86873a3e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/partition_matrix_vec_3.m
@@ -0,0 +1,22 @@
+function [A1, A2, B1, B2, C11, C12, C21, C22] = partition_matrix_vec_3(A, B, C, n1, n2, bs)
+
+dom = myunion(n1, n2);
+n1i = block(find_equiv_posns(n1, dom), bs(dom));
+n2i = block(find_equiv_posns(n2, dom), bs(dom));
+
+
+    A1 = A(n1i);
+    A2 = A(n2i);
+    if isempty(B)
+        B1 = zeros(size(n1i, 2),size(B, 2));
+        B2 = zeros(size(n2i, 2),size(B, 2));
+    else
+        B1 = B(n1i, :);
+        B2 = B(n2i, :);
+    end
+    
+    
+    C11 = C(n1i, n1i);
+    C12 = C(n1i, n2i);
+    C21 = C(n2i, n1i);
+    C22 = C(n2i, n2i);
diff --git a/sourcecodes/bnt-master/BNT/general/sample_bnet.m b/sourcecodes/bnt-master/BNT/general/sample_bnet.m
new file mode 100644
index 00000000..3c219c24
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/sample_bnet.m
@@ -0,0 +1,34 @@
+function sample = sample_bnet(bnet, varargin)
+% SAMPLE_BNET Generate a random sample from a Bayes net.
+% SAMPLE = SAMPLE_BNET(BNET, ...)
+%
+% sample{i} contains the value of the i'th node.
+% i.e., the result is an Nx1 cell array.
+% Nodes are sampled in the order given by bnet.order.
+%
+% Optional arguments:
+%
+% evidence - initial evidence; if evidence{i} is non-empty, node i won't be sampled.
+
+% set defauly params
+n = length(bnet.dag);
+sample = cell(n,1);
+
+% get optional params
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'evidence',    sample = args{i+1}(:);
+   otherwise, error(['unrecognized argument ' args{i}])
+  end
+end
+
+for j=bnet.order(:)'
+  if isempty(sample{j})
+    %ps = parents(bnet.dag, j);
+    ps = bnet.parents{j};
+    e = bnet.equiv_class(j);
+    sample{j} = sample_node(bnet.CPD{e}, sample(ps));
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/general/sample_bnet_nocell.m b/sourcecodes/bnt-master/BNT/general/sample_bnet_nocell.m
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/sample_bnet_nocell.m
diff --git a/sourcecodes/bnt-master/BNT/general/sample_dbn.m b/sourcecodes/bnt-master/BNT/general/sample_dbn.m
new file mode 100644
index 00000000..0477ac4a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/sample_dbn.m
@@ -0,0 +1,73 @@
+function seq = sample_dbn(bnet, varargin)
+% SAMPLE_DBN Generate a random sequence from a DBN.
+% seq = sample_dbn(bnet, ...)
+%
+% seq{i,t} contains the values of the i'th node in the t'th slice.
+%
+% Optional arguments:
+%
+% length - length of sequence  to be generated (can also just use sample_dbn(bnet,T))
+% stop_test - name of a function which is used to decide when to stop;
+%   This will be called as feval(stop_test, seq(:,t))
+%   i.e., stop_test is passed a cell array containing all the nodes in the current slice.   
+% evidence - initial evidence; if evidence{i,t} is non-empty, this node won't be sampled.
+
+args = varargin;
+nargs = length(args);
+
+if (nargs == 1) & ~isstr(args{1})
+  % Old syntax: sample_dbn(bnet, T)
+  T = args{1};
+else
+  % get length
+  T = 1;
+  for i=1:2:nargs
+    switch args{i},
+     case 'length',      T = args{i+1}; 
+     case 'evidence',    T = size(args{i+1}, 2);
+    end
+  end
+end
+
+ss = length(bnet.intra);
+% set default arguments
+seq = cell(ss, T);
+stop_test = [];
+for i=1:2:nargs
+  switch args{i},
+   case 'evidence',    seq = args{i+1}; % initialise observed nodes
+   case 'stop_test',  stop_test = args{i+1};
+  end
+end
+
+t = 1;
+for i=1:ss
+  if ~isempty(stop_test) | isempty(seq{i,t})
+    ps = parents(bnet.dag, i);
+    e = bnet.equiv_class(i,1);
+    pvals = seq(ps);
+    seq{i,t} = sample_node(bnet.CPD{e}, pvals);
+    %fprintf('sample i=%d,t=%d,val=%d,ps\n', i, t, seq(i,t)); pvals(:)'
+  end
+end
+t = 2;
+done = 0;
+while ~done
+  for i=1:ss
+    if ~isempty(stop_test) | isempty(seq{i,t})
+      ps = parents(bnet.dag, i+ss) + (t-2)*ss;
+      e = bnet.equiv_class(i,2);
+      pvals = seq(ps);
+      seq{i,t} = sample_node(bnet.CPD{e}, pvals);
+      %fprintf('sample i=%d,t=%d,val=%d,ps\n', i, t, seq(i,t)); pvals(:)'
+    end
+  end
+  if ~isempty(stop_test)
+    done = feval(stop_test, seq(:,t));
+  else
+    if t==T
+      done = 1;
+    end
+  end
+  t = t + 1;
+end
diff --git a/sourcecodes/bnt-master/BNT/general/score_bnet_complete.m b/sourcecodes/bnt-master/BNT/general/score_bnet_complete.m
new file mode 100644
index 00000000..93caf1d7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/score_bnet_complete.m
@@ -0,0 +1,28 @@
+function L = log_lik_complete(bnet, cases, clamped)
+% LOG_LIK_COMPLETE Compute sum_m sum_i log P(x(i,m)| x(pi_i,m), theta_i) for a completely observed data set
+% L = log_lik_complete(bnet, cases, clamped)
+%
+% If there is a missing data, you must use an inference engine.
+% cases(i,m) is the value assigned to node i in case m.
+% (If there are vector-valued nodes, cases should be a cell array.)
+% clamped(i,m) = 1 if node i was set by intervention in case m (default: clamped = zeros)
+% Clamped nodes contribute a factor of 1.0 to the likelihood.
+
+if iscell(cases), usecell = 1; else usecell = 0; end
+
+n = length(bnet.dag);
+ncases = size(cases, 2);
+if n ~= size(cases, 1)
+  error('data should be of size nnodes * ncases');
+end
+
+if nargin < 3, clamped = zeros(n,ncases); end
+
+L = 0;
+for i=1:n
+  ps = parents(bnet.dag, i);
+  e = bnet.equiv_class(i);
+  u = find(clamped(i,:)==0);
+  L = L + log_prob_node(bnet.CPD{e}, cases(i,u), cases(ps,u));
+end
+
diff --git a/sourcecodes/bnt-master/BNT/general/shrink_obs_dims_in_gaussian.m b/sourcecodes/bnt-master/BNT/general/shrink_obs_dims_in_gaussian.m
new file mode 100644
index 00000000..8d4a3481
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/shrink_obs_dims_in_gaussian.m
@@ -0,0 +1,12 @@
+function marg2 = shrink_obs_dims_in_gaussian(marg1, dom, evidence, ns)
+% SHRINK_OBS_DIMS_IN_GAUSSIAN Remove observed dimensions from mu/Sigma
+% function marg2 = shrink_obs_dims_in_gaussian(marg1, dom, evidence, ns)
+
+% This is used by loopy
+
+hdom = dom(isemptycell(evidence(dom)));
+ndx = find_equiv_posns(hdom, dom);
+b = block(ndx, ns(dom));
+marg2.mu = marg1.mu(b);
+marg2.Sigma = marg1.Sigma(b,b);
+marg2.domain = marg1.domain;
diff --git a/sourcecodes/bnt-master/BNT/general/shrink_obs_dims_in_table.m b/sourcecodes/bnt-master/BNT/general/shrink_obs_dims_in_table.m
new file mode 100644
index 00000000..37c7d804
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/shrink_obs_dims_in_table.m
@@ -0,0 +1,15 @@
+function T2 = shrink_obs_dims_in_table(T1, dom, evidence)
+% SHRINK_OBS_DIMS_IN_TABLE Set observed dimensions to size 1
+% T2 = shrink_obs_dims_in_table(T1, dom, evidence)
+%
+% If 'T1' contains observed nodes, it will have 0s in the positions that are
+% inconsistent with the evidence. We now remove these 0s and set the corresponding dimensions to
+% size 1, to be consistent with the way most inference engines handle evidence, which is to
+% shrink observed nodes before doing inference.
+
+% This is used by pearl and enumerative inf. engines.
+
+odom = dom(~isemptycell(evidence(dom)));
+vals = cat(1,evidence{odom});
+ndx = mk_multi_index(length(dom), find_equiv_posns(odom, dom), vals(:));
+T2 = T1(ndx{:});
diff --git a/sourcecodes/bnt-master/BNT/general/solve_limid.m b/sourcecodes/bnt-master/BNT/general/solve_limid.m
new file mode 100644
index 00000000..0009cd7c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/solve_limid.m
@@ -0,0 +1,68 @@
+function [strategy, MEU, niter] = solve_limid(engine, varargin)
+% SOLVE_LIMID Find the (locally) optimal strategy for a LIMID
+% [strategy, MEU, niter] = solve_limid(inf_engine, ...)
+%
+% strategy{d} = stochastic policy for node d (a decision node)
+% MEU = maximum expected utility
+% niter = num iterations used
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default in brackets]
+%
+% max_iter - max. num. iterations [ 1 ]
+% tol - tolerance required of consecutive MEU values, used to assess convergence [1e-3]
+% order - order in which decision nodes are optimized [ reverse numerical order ]
+%
+% e.g., solve_limid(engine, 'tol', 1e-2, 'max_iter', 10)
+
+bnet = bnet_from_engine(engine);
+
+% default values
+max_iter = 1;
+tol = 1e-3;
+D = bnet.decision_nodes;
+order = D(end:-1:1);
+
+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 'order',    order = args{i+1}; 
+   otherwise,  
+    error(['invalid argument name ' args{i}]);       
+  end
+end
+
+CPDs = bnet.CPD;
+ns = bnet.node_sizes;
+N = length(ns);
+evidence = cell(1,N);
+strategy = cell(1, N);
+
+iter = 1;
+converged = 0;
+oldMEU = 0;
+while ~converged & (iter <= max_iter)
+  for d=order(:)'
+    engine = enter_evidence(engine, evidence, 'exclude', d);
+    [m, pot] = marginal_family(engine, d);
+    %pot = marginal_family_pot(engine, d);
+    [policy, score] = upot_to_opt_policy(pot);    
+    e = bnet.equiv_class(d);
+    CPDs{e} = set_fields(CPDs{e}, 'policy', policy);
+    engine = update_engine(engine, CPDs);
+    strategy{d} = policy;
+  end  
+  engine = enter_evidence(engine, evidence);
+  [m, pot] = marginal_nodes(engine, []);
+  %pot = marginal_family_pot(engine, []);
+  [dummy, MEU] = upot_to_opt_policy(pot);    
+  if approxeq(MEU, oldMEU, tol)
+    converged = 1;
+  end
+  oldMEU = MEU;
+  iter = iter + 1;
+end
+niter = iter - 1;
diff --git a/sourcecodes/bnt-master/BNT/general/unroll_dbn_topology.m b/sourcecodes/bnt-master/BNT/general/unroll_dbn_topology.m
new file mode 100644
index 00000000..6b9ddcdb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/unroll_dbn_topology.m
@@ -0,0 +1,28 @@
+function M = unroll_dbn_topology(intra, inter, T, intra1)
+% UNROLL_DBN_TOPOLOGY Make the block diagonal adjacency matrix for a DBN consisting of T slices
+% M = unroll_dbn_topology(intra, inter, T, intra1)
+%
+% intra is the connectivity within a slice, inter between two slices.
+% M will have intra along the diagonal, and inter one above the diagonal.
+% intra1 is an optional argumnet, in case the intra is different for the first slice.
+
+if nargin < 4, intra1 = intra; end
+
+ss = length(intra); % slice size
+M = sparse(ss*T, ss*T);
+
+b = 1:ss;
+M(b,b) = intra1;
+M(b,b+ss) = inter;
+
+for t=2:T-1
+  b = (1:ss) + (t-1)*ss;
+  M(b,b) = intra;
+  M(b,b+ss) = inter;
+end
+
+t = T;
+b = (1:ss) + (t-1)*ss;
+M(b,b) = intra;
+
+   
diff --git a/sourcecodes/bnt-master/BNT/general/unroll_higher_order_topology.m b/sourcecodes/bnt-master/BNT/general/unroll_higher_order_topology.m
new file mode 100644
index 00000000..29e78ef2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/unroll_higher_order_topology.m
@@ -0,0 +1,30 @@
+function M = unroll_higher_order_topology(intra, inter, T, intra1)
+% UNROLL_DBN_TOPOLOGY Make the block diagonal adjacency matrix for a DBN consisting of T slices
+% M = unroll_dbn_topology(intra, inter, T, intra1)
+%
+% intra is the connectivity within a slice, inter between two slices.
+% M will have intra along the diagonal, and inter one above the diagonal.
+% intra1 is an optional argumnet, in case the intra is different for the first slice.
+
+if nargin < 4 
+    intra1 = intra; 
+end;
+
+
+ss = length(intra); % slice size
+M = sparse(ss*T, ss*T);
+[rows,columns,order] = size(inter);
+for t1 = 1:T
+  b = 1 + (t1 - 1)*ss : t1*ss;
+  if t1 == 1
+      M(b,b) = intra1;
+  else
+      M(b,b) = intra;
+  end
+  for t2 = 1:order
+    if t1 + t2 <= T
+      M(b,b+t2*ss) = inter(:,:,t2);
+    end
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/general/unroll_set.m b/sourcecodes/bnt-master/BNT/general/unroll_set.m
new file mode 100644
index 00000000..277efcd2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/general/unroll_set.m
@@ -0,0 +1,7 @@
+function U = unroll_set(S, ss, T)
+% UNROLL_SET Make T shifted copies of the set of nodes S in a slice of size ss.
+% U = unroll_set(S, ss, T)
+
+offset = repmat(0:ss:(T-1)*ss, [length(S) 1]);
+U = repmat(S(:), [1 T]) + offset;
+    
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Entries
new file mode 100644
index 00000000..a5ebeece
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Entries
@@ -0,0 +1,7 @@
+/bnet_from_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/get_field.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/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//
+/set_fields.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/@inf_engine/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Repository
new file mode 100644
index 00000000..07b838d4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/@inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/CVS/Entries
new file mode 100644
index 00000000..ce1f8c1e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/CVS/Entries
@@ -0,0 +1,3 @@
+/marginal_family_pot.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/observed_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/CVS/Repository
new file mode 100644
index 00000000..de36d64e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/@inf_engine/Old
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/marginal_family_pot.m b/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/marginal_family_pot.m
new file mode 100644
index 00000000..c1e63710
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/marginal_family_pot.m
@@ -0,0 +1,14 @@
+function pot = marginal_family_pot(engine, i)
+% MARGINAL_FAMILY_POT Compute the marginal on i's family and return as a potentila (inf_engine)
+% function pot = marginal_family_pot(engine,i)
+
+% This function is only called by solve_limid.
+% It requires that engine's marginal_family function return a potential.
+% This is true for jtree_inf_engine, but not for, say, jtree_ndx_inf_engine.
+% All limids must be solved using potentials,
+% but this is not true for bnets.
+
+%[m, pot] = marginal_family(engine, i);
+
+bnet = bnet_from_engine(engine);
+[m, pot] = marginal_nodes(engine, family(bnet.dag, i));
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/observed_nodes.m b/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/observed_nodes.m
new file mode 100644
index 00000000..97fccdb3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/Old/observed_nodes.m
@@ -0,0 +1,5 @@
+function onodes = observed_nodes(engine)
+% OBSERVED_NODES  Return nodes that are guaranteed to be observed, indep of evidence (generic inf_engine)
+% onodes = observed_nodes(engine)
+
+onodes = [];
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/bnet_from_engine.m b/sourcecodes/bnt-master/BNT/inference/@inf_engine/bnet_from_engine.m
new file mode 100644
index 00000000..cf579fb0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/bnet_from_engine.m
@@ -0,0 +1,12 @@
+function bnet = bnet_from_engine(engine)
+% BNET_FROM_ENGINE Return the bnet structure stored inside the engine (inf_engine)
+% bnet = bnet_from_engine(engine)
+
+bnet = engine.bnet;
+
+% We cannot write 'engine.bnet' without writing a 'subsref' function,
+% since engine is an object with private parts.
+% The bnet field should be the only thing external users of the engine should need access to.
+% We do not pass bnet as a separate argument, since it could get out of synch with the one
+% encoded inside the engine.
+       
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/get_field.m b/sourcecodes/bnt-master/BNT/inference/@inf_engine/get_field.m
new file mode 100644
index 00000000..a1d16335
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/get_field.m
@@ -0,0 +1,15 @@
+function val = get_field(engine, name)
+% GET_FIELD Get the value of a named field from a generic engine
+% val = get_field(engine, name)
+%
+% The following fields can be accessed
+%
+% bnet
+%
+% e.g., bnet = get_field(engine, 'bnet')
+
+switch name
+ case 'bnet',      val = engine.bnet;
+ otherwise,
+  error(['invalid argument name ' name]);
+end                                  
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/inf_engine.m b/sourcecodes/bnt-master/BNT/inference/@inf_engine/inf_engine.m
new file mode 100644
index 00000000..f08e2438
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/inf_engine.m
@@ -0,0 +1,6 @@
+function engine = inf_engine(bnet)
+
+engine.bnet = bnet;
+engine = class(engine, 'inf_engine');
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/@inf_engine/marginal_family.m
new file mode 100644
index 00000000..0107f1d3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/marginal_family.m
@@ -0,0 +1,24 @@
+function m = marginal_family(engine, i, t)
+% MARGINAL_FAMILY Compute the marginal on i's family (inf_engine)
+% m = marginal_family(engine, i, t)
+%
+% t defaults to 1.
+
+if nargin < 3, t = 1; end
+
+bnet = bnet_from_engine(engine);
+if t==1
+  m = marginal_nodes(engine, family(bnet.dag, i));
+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);
+  else
+    % The family all fits inside slice t
+    % Hence shift the indexes back to slice 1
+    m = marginal_nodes(engine, fam-ss, t);
+  end
+end     
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/set_fields.m b/sourcecodes/bnt-master/BNT/inference/@inf_engine/set_fields.m
new file mode 100644
index 00000000..e75cfa45
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@inf_engine/set_fields.m
@@ -0,0 +1,13 @@
+function engine = set_fields(engine, varargin)
+% SET_FIELDS Set the fields for a generic engine
+% engine = set_fields(engine, name/value pairs)
+%
+% e.g., engine = set_fields(engine, 'maximize', 1)
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'maximize', engine.maximize = args{i+1};
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/@inf_engine/update_engine.m b/sourcecodes/bnt-master/BNT/inference/@inf_engine/update_engine.m
new file mode 100644
index 00000000..afafdeb9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/@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 (inf_engine).
+% engine = update_engine(engine, newCPDs)
+%
+% This generic method is suitable for engines that do not process the parameters until 'enter_evidence'.
+
+engine.bnet.CPD = newCPDs;
diff --git a/sourcecodes/bnt-master/BNT/inference/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/CVS/Entries
new file mode 100644
index 00000000..1ab405cf
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/CVS/Entries
@@ -0,0 +1,2 @@
+/dummy/1.1.1.1/Sat Jan 18 22:22:22 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/CVS/Entries.Log
new file mode 100644
index 00000000..09d6954b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/CVS/Entries.Log
@@ -0,0 +1,4 @@
+A D/@inf_engine////
+A D/dynamic////
+A D/online////
+A D/static////
diff --git a/sourcecodes/bnt-master/BNT/inference/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/CVS/Repository
new file mode 100644
index 00000000..7889e181
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference
diff --git a/sourcecodes/bnt-master/BNT/inference/CVS/Root b/sourcecodes/bnt-master/BNT/inference/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/dummy b/sourcecodes/bnt-master/BNT/inference/dummy
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/dummy
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
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Entries
new file mode 100644
index 00000000..9e03c43e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Entries
@@ -0,0 +1,6 @@
+/bnet_from_engine.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_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/online/@filter_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Repository
new file mode 100644
index 00000000..02b22e5e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/online/@filter_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/bnet_from_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/bnet_from_engine.m
new file mode 100644
index 00000000..b57ee5f4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/bnet_from_engine.m
@@ -0,0 +1,5 @@
+function bnet = bnet_from_engine(engine)
+% BNET_FROM_ENGINE Return the bnet structure stored inside the engine (smoother_engine)
+% bnet = bnet_from_engine(engine)
+
+bnet = bnet_from_engine(engine.tbn_engine);
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/enter_evidence.m
new file mode 100644
index 00000000..ab360c68
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/enter_evidence.m
@@ -0,0 +1,14 @@
+function [engine, LL] = enter_evidence(engine, ev, t)
+% ENTER_EVIDENCE Call the online filter
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i} = [] if if X(i) is hidden, and otherwise contains its observed value (scalar or column vector)
+
+engine.old_f = engine.f;
+if t==1
+  [engine.f, LL] = fwd1(engine.tbn_engine, ev, 1);
+else
+  [engine.f, LL] = fwd(engine.tbn_engine, engine.old_f, ev, t);
+end
+engine.b = backT(engine.tbn_engine, engine.f, t);
+engine.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/filter_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/filter_engine.m
new file mode 100644
index 00000000..437a247e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/filter_engine.m
@@ -0,0 +1,10 @@
+function engine = filter_engine(tbn_engine)
+% FILTER_ENGINE Create an engine which does online filtering
+% function engine = filter_engine(tbn_engine)
+
+engine.tbn_engine = tbn_engine;
+engine.f = [];  % space to store filtered message
+engine.old_f = [];
+engine.b = []; % space to store smoothed message
+engine.t = [];
+engine = class(engine, 'filter_engine');
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_family.m
new file mode 100644
index 00000000..21faea53
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_family.m
@@ -0,0 +1,11 @@
+function marginal = marginal_family(engine, i, t, add_ev)
+% MARGINAL_FAMILY Compute the joint distribution on a set of family (filter_engine)
+% function marginal = marginal_family(engine, i, t, add_ev)
+
+if nargin < 4, add_ev = 0; end
+
+if t ~= engine.t
+  error('mixed up time stamps')
+end
+
+marginal = marginal_family(engine.tbn_engine, engine.b, i, t, add_ev);
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_nodes.m
new file mode 100644
index 00000000..4d83ea93
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@filter_engine/marginal_nodes.m
@@ -0,0 +1,10 @@
+function marginal = marginal_nodes(engine, nodes, t, add_ev)
+% MARGINAL_NODES Compute the joint distribution on a set of nodes (filter_engine)
+% function marginal = marginal_nodes(engine, nodes, t, add_ev)
+
+if nargin < 4, add_ev = 0; end
+
+if t ~= engine.t
+  error('mixed up time stamps')
+end
+marginal = marginal_nodes(engine.tbn_engine, engine.b, nodes, t, add_ev);
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries
new file mode 100644
index 00000000..9d562fd8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries
@@ -0,0 +1,9 @@
+/back.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/backT.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/fwd.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/fwd1.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/hmm_2TBN_inf_engine.m/1.1.1.1/Thu Nov 14 20:03:50 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:02:46 2002//
+/update_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries.Log
new file mode 100644
index 00000000..b2cd71e0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/private////
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Repository
new file mode 100644
index 00000000..858ed017
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/online/@hmm_2TBN_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/back.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/back.m
new file mode 100644
index 00000000..8ad416f7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/back.m
@@ -0,0 +1,21 @@
+function b = back(engine, bfuture, f, t)
+
+if f.t ~= t
+  error('mixed up time stamps')
+end
+
+b.t = t;
+b.obslik = f.obslik;
+bb_future = bfuture.beta .* bfuture.obslik;
+if engine.maximize
+  B = repmat(bb_future(:)', length(bfuture.beta), 1);
+  b.beta = normalise(max(engine.transprob .* B, [], 2));
+else
+  b.beta = normalise((engine.transprob * bb_future));
+end
+b.gamma = normalise(f.alpha .* b.beta);
+if t > 1
+  bb_t = b.beta .* b.obslik;
+  b.xi = normalise((engine.transprob .* (f.past_alpha * bb_t'))); % t-1,t
+end
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/backT.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/backT.m
new file mode 100644
index 00000000..ffeb6628
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/backT.m
@@ -0,0 +1,11 @@
+function b = backT(engine, f, t)
+
+b.t = t;
+b.obslik = f.obslik;
+Q = length(f.alpha);
+b.beta = ones(Q,1);
+b.gamma = f.alpha;
+if t > 1
+  bb_t = b.obslik;
+  b.xi = normalise((engine.transprob .* (f.past_alpha * bb_t'))); % T-1,T
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd.m
new file mode 100644
index 00000000..3afdf714
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd.m
@@ -0,0 +1,17 @@
+function [f, logscale] = fwd(engine, fpast, ev, t)
+% Forwards pass.
+
+f.obslik = mk_hmm_obs_lik_vec(engine, ev);
+transmat = engine.transprob;
+f.past_alpha = fpast.alpha;
+if engine.maximize
+  Q = length(fpast.alpha);
+  A = repmat(fpast.alpha, [1 Q]);
+  m = max(transmat .* A, [], 1);
+  [f.alpha, scale] = normalise(m(:) .* f.obslik);
+else
+  [f.alpha, scale] = normalise((transmat' * fpast.alpha) .* f.obslik);
+end
+logscale = log(scale);
+%f.xi = normalise((fpast.alpha * obslik') .* transmat); % t-1,t
+f.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd1.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd1.m
new file mode 100644
index 00000000..ec16db4b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/fwd1.m
@@ -0,0 +1,11 @@
+function [f, logscale] = fwd1(engine, ev, t)
+% Forwards pass for slice 1.
+
+if t ~= 1
+  error('mixed up time stamps')
+end
+prior = engine.startprob(:);
+f.obslik = mk_hmm_obs_lik_vec(engine, ev);
+[f.alpha, lik] = normalise(prior .* f.obslik);
+logscale = log(lik);
+f.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/hmm_2TBN_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/hmm_2TBN_inf_engine.m
new file mode 100644
index 00000000..8504124b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/hmm_2TBN_inf_engine.m
@@ -0,0 +1,86 @@
+function engine = hmm_2TBN_inf_engine(bnet, varargin)
+% HMM_2TBN_INF_ENGINE Inference engine for DBNs which uses the forwards-backwards algorithm.
+% engine = hmm_2TBN_inf_engine(bnet, ...)
+%
+% 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.
+% 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.
+
+
+%% Optional arguments
+%% ndx_type - 'B', 'D', or 'SD', used in marginal_family [ 'SD' ]
+
+ndx_type = 'SD';
+ss = bnet.nnodes_per_slice;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  for i=1:2:nargs
+    switch args{i},
+     %case 'ndx_type', ndx_type = args{i+1};
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+% Stuff to do with speeding up marginal_family
+%engine.ndx_type = ndx_type;
+
+[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 n=1:ss
+%   dom = 1:(2*ss); % domain of xi(:,:,1)
+%   fam = family(bnet.dag, n+ss);
+%   engine.marg_fam2_ndx_id(n) = add_ndx(dom, fam, ns, ndx_type);
+ 
+%   dom = 1:ss; % domain of gamma(:,:,1)
+%   fam = family(bnet.dag, n);
+%   engine.marg_fam1_ndx_id(n) = add_ndx(dom, fam, ns, ndx_type);
+
+%   engine.marg_singleton_ndx_id(n) = add_ndx(dom, n, ns, ndx_type);
+% end
+
+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.maximize = [];
+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.bel = [];
+engine = class(engine, 'hmm_2TBN_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_family.m
new file mode 100644
index 00000000..cd8a6997
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_family.m
@@ -0,0 +1,35 @@
+function marginal = marginal_family(engine, b, i, t, add_ev)
+% MARGINAL_FAMILY Compute the marginal on the specified family (hmm_2TBN)
+% marginal = marginal_family(engine, b, i, t, add_ev)
+
+ns = engine.eff_node_sizes(:);
+ss = engine.slice_size;
+
+if t==1 % | ~engine.persist_bitv(i)
+  bigT = b.gamma;
+  ps = engine.parents{i};
+  dom = [ps i];
+  %id = engine.marg_fam1_ndx_id(i);
+  bigdom = 1:ss;
+  bigsz = ns(bigdom);
+  bigdom = bigdom + (t-1)*ss;
+else % some parents are in previous slice
+  bigT = b.xi; % (t-1,t)
+  ps = engine.parents{i+ss};
+  dom = [ps i+ss] + (t-2)*ss;
+  %id = engine.marg_fam2_ndx_id(i);
+  bigdom = 1:(2*ss); % domain of xi(:,:,t)
+  bigsz = ns(bigdom);
+  bigdom = bigdom + (t-2)*ss;
+end
+marginal.domain = dom;
+
+%ndx = get_ndx(id, engine.ndx_type);
+%marginal.T = marg_table_ndx(bigT, engine.maximize, ndx, engine.ndx_type);
+%global SD_NDX
+%ndx = SD_NDX{id};
+%marginal.T = marg_table_ndxSD(bigT, engine.maximize, ndx);
+marginal.T = marg_table(bigT, bigdom, bigsz, dom, engine.maximize); 
+
+assert(~add_ev);
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..6fa6c2b3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/marginal_nodes.m
@@ -0,0 +1,27 @@
+function marginal = marginal_nodes(engine, b, nodes, t, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified nodes (hmm_2TBN)
+% marginal = marginal_nodes(engine, b, nodes, t, add_ev)
+%
+% nodes must be a singleton set 
+
+assert(length(nodes)==1)
+ss = engine.slice_size;
+
+i = nodes(1);
+bigT = b.gamma;
+dom = i + (t-1)*ss;
+
+%id = engine.marg_singleton_ndx_id(i);
+%global SD_NDX
+%ndx = SD_NDX{id};
+%marginal.T = marg_table_ndxSD(bigT, engine.maximize, ndx);
+
+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;
+assert(~add_ev);
+%if add_ev
+%  marginal = add_ev_to_dmarginal(marginal, engine.evidence, engine.node_sizes);
+%end    
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Entries
new file mode 100644
index 00000000..c37a30a9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Entries
@@ -0,0 +1,2 @@
+/mk_hmm_obs_lik_vec.m/1.1.1.1/Sun May  4 21:47:44 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Repository
new file mode 100644
index 00000000..81419e91
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/online/@hmm_2TBN_inf_engine/private
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/mk_hmm_obs_lik_vec.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/mk_hmm_obs_lik_vec.m
new file mode 100644
index 00000000..915a2f39
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/private/mk_hmm_obs_lik_vec.m
@@ -0,0 +1,53 @@
+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);
+    obslik_i = multinomial_prob(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/online/@hmm_2TBN_inf_engine/update_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_inf_engine/update_engine.m
new file mode 100644
index 00000000..e6cd1f79
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@hmm_2TBN_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/online/@jtree_2TBN_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Entries
new file mode 100644
index 00000000..b64945b2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Entries
@@ -0,0 +1,13 @@
+/back.m/1.1.1.1/Mon Jun 17 23:34:12 2002//
+/back1.m/1.1.1.1/Mon Jun 17 23:34:26 2002//
+/back1_mpe.m/1.1.1.1/Mon Jun 17 23:49:40 2002//
+/backT.m/1.1.1.1/Mon Jun 17 23:34:20 2002//
+/backT_mpe.m/1.1.1.1/Mon Jun 17 23:38:56 2002//
+/back_mpe.m/1.1.1.1/Sun Jul 21 00:32:52 2002//
+/fwd.m/1.1.1.1/Mon Jun 17 23:46:06 2002//
+/fwd1.m/1.1.1.1/Mon Jun 17 23:46:20 2002//
+/jtree_2TBN_inf_engine.m/1.1.1.1/Thu Nov 14 16:31:58 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_fields.m/1.1.1.1/Sun Jul 21 01:25:30 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Repository
new file mode 100644
index 00000000..7f0022ff
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/online/@jtree_2TBN_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Entries
new file mode 100644
index 00000000..794b5de2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Entries
@@ -0,0 +1,2 @@
+/jtree_2TBN_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Repository
new file mode 100644
index 00000000..a7b1e665
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/online/@jtree_2TBN_inf_engine/Old
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/jtree_2TBN_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/jtree_2TBN_inf_engine.m
new file mode 100644
index 00000000..b271e583
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/Old/jtree_2TBN_inf_engine.m
@@ -0,0 +1,116 @@
+function engine = jtree_2TBN_inf_engine(bnet, varargin)
+% JTREE_ONLINE_INF_ENGINE Online Junction tree inference algorithm for DBNs.
+% engine = jtree_online_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 do max-product, 0 means sum-product [0]
+%
+% The same nodes must be observed in every slice.
+
+ss = length(bnet.intra);
+clusters = {};
+engine.maximize = 0;
+
+args = varargin;
+nargs = length(args);
+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 = compute_interface_nodes(bnet.intra, bnet.inter);
+int = [];
+
+if 1
+% include nodes with any outgoing arcs
+for u=1:ss
+  if any(bnet.inter(u,:))
+    int = [int u];
+  end
+end
+end
+
+if 0
+% include nodes with any incoming  arcs
+incoming = [];
+for u=1:ss
+  if any(bnet.inter(:,u))
+    int = [int u];
+    incoming = [incoming u];
+  end
+end
+% include nodes which are parents of nodes with incoming
+for u=1:ss
+  cs = children(bnet.intra, u);
+  if ~isempty(cs) & mysubset(cs, incoming)
+    int = [int u];
+  end
+end
+int = unique(int);
+end % if
+
+int
+engine.interface = int;
+engine.nonint = mysetdiff(1:ss, int);
+
+onodes = bnet.observed;
+
+% Create a "1.5 slice" jtree, containing the interface nodes of slice 1
+% and all the nodes of slice 2
+% To keep the node numbering the same, we simply disconnect the non-interface nodes
+% from slice 1, 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 (i.e., we can include nodes whose potentials will
+% be left as all 1s).
+intra15 = bnet.intra;
+for i=engine.nonint(:)'
+  intra15(:,i) = 0;
+  intra15(i,:) = 0;
+end
+dag15 = [intra15      bnet.inter;
+	 zeros(ss)    bnet.intra];
+ns = bnet.node_sizes(:);
+%ns(engine.nonint) = 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(:));
+
+% 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);
+jtree_engine = struct(engine.jtree_engine); % violate object privacy
+
+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 = jtree_engine.clq_ass_to_node;
+engine.root = jtree_engine.root_clq;
+
+% 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);
+jtree_engine1 = struct(engine.jtree_engine1); % violate object privacy
+engine.int_clq1 = clq_containing_nodes(engine.jtree_engine1, int);
+engine.clq_ass_to_node1 = jtree_engine1.clq_ass_to_node;
+engine.root1 = jtree_engine1.root_clq;
+
+engine.observed = [onodes onodes+ss];
+engine.observed1 = onodes;
+engine.pot_type = determine_pot_type(bnet, onodes);
+engine.slice_size = bnet.nnodes_per_slice;
+
+engine = class(engine, 'jtree_2TBN_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back.m
new file mode 100644
index 00000000..7f686d55
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back.m
@@ -0,0 +1,27 @@
+function b = back(engine, bfuture, f, t)
+
+if f.t ~= t
+  error('mixed up time stamps')
+end
+if t==1
+  b = back1(engine, bfuture, f, t);
+  return;
+end
+
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+int = engine.interface;
+D = engine.in_clq;
+C = engine.out_clq;
+phiD = marginalize_pot(bfuture.clpot{D}, int, engine.maximize);
+phiD = set_domain_pot(phiD, int+ss); % shift to slice 2
+phiC = marginalize_pot(f.clpot{C}, int+ss, engine.maximize);
+ratio = divide_by_pot(phiD, phiC);
+f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio);
+
+[b.clpot, seppot] = distribute_evidence(engine.jtree_engine, f.clpot, f.seppot);
+for c=1:length(b.clpot)
+  [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c});
+end
+b.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1.m
new file mode 100644
index 00000000..a8587a72
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1.m
@@ -0,0 +1,21 @@
+function b = back1(engine, bfuture, f, t)
+
+if t ~= 1
+  error('mixed up time stamps')
+end
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+int = engine.interface;
+D = engine.in_clq; % from J2
+C = engine.int_clq1; % from J1
+phiD = marginalize_pot(bfuture.clpot{D}, int, engine.maximize);
+phiC = marginalize_pot(f.clpot{C}, int, engine.maximize);
+ratio = divide_by_pot(phiD, phiC);
+f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio);
+
+[b.clpot, seppot] = distribute_evidence(engine.jtree_engine1, f.clpot, f.seppot);
+for c=1:length(b.clpot)
+  [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c});
+end
+b.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1_mpe.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1_mpe.m
new file mode 100644
index 00000000..b20bfa57
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back1_mpe.m
@@ -0,0 +1,22 @@
+function [b, mpe] = back1_mpe(engine, bfuture, f, ev1, t)
+
+if t ~= 1
+  error('mixed up time stamps')
+end
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+maximize = 1;
+
+int = engine.interface;
+D = engine.in_clq; % from J2
+C = engine.int_clq1; % from J1
+phiD = marginalize_pot(bfuture.clpot{D}, int, maximize);
+phiC = marginalize_pot(f.clpot{C}, int, maximize);
+ratio = divide_by_pot(phiD, phiC);
+f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio);
+
+[mpe, b.clpot] = find_max_config(engine.jtree_engine1, f.clpot, f.seppot, ev1);
+for c=1:length(b.clpot)
+  [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c});
+end
+b.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT.m
new file mode 100644
index 00000000..7f7a1b42
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT.m
@@ -0,0 +1,11 @@
+function b = backT(engine, f, t)
+
+if t==1
+  [b.clpot, seppot] = distribute_evidence(engine.jtree_engine1, f.clpot, f.seppot);
+else
+  [b.clpot, seppot] = distribute_evidence(engine.jtree_engine, f.clpot, f.seppot);
+end
+for c=1:length(b.clpot)
+  [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c});
+end
+b.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT_mpe.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT_mpe.m
new file mode 100644
index 00000000..93084eae
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/backT_mpe.m
@@ -0,0 +1,16 @@
+function [b, mpe] = backT_mpe(engine, f, ev2, t)
+
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+if t==1
+  % ev2 is just the evidence on slice 1
+  [mpe, b.clpot] = find_max_config(engine.jtree_engine1, f.clpot, f.seppot, ev2);
+else
+  [mpe, b.clpot] = find_max_config(engine.jtree_engine, f.clpot, f.seppot, ev2);
+  mpe = mpe((1:ss)+ss); % extract values for slice 2
+end
+for c=1:length(b.clpot)
+  [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c});
+end
+b.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back_mpe.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back_mpe.m
new file mode 100644
index 00000000..9fdba411
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/back_mpe.m
@@ -0,0 +1,28 @@
+function [b, mpe] = back_mpe(engine, bfuture, f, ev2, t)
+
+if f.t ~= t
+  error('mixed up time stamps')
+end
+if t==1
+  error('should call back1_mpe')
+end
+
+maximize = 1;
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+int = engine.interface;
+D = engine.in_clq;
+C = engine.out_clq;
+phiD = marginalize_pot(bfuture.clpot{D}, int, maximize);
+phiD = set_domain_pot(phiD, int+ss); % shift to slice 2
+phiC = marginalize_pot(f.clpot{C}, int+ss, maximize);
+ratio = divide_by_pot(phiD, phiC);
+f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio);
+
+[mpe, b.clpot] = find_max_config(engine.jtree_engine, f.clpot, f.seppot, ev2);
+mpe = mpe((1:ss)+ss); % extract values for slice 2
+for c=1:length(b.clpot)
+  [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c});
+end
+b.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd.m
new file mode 100644
index 00000000..9c59cc3b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd.m
@@ -0,0 +1,44 @@
+function [f, logscale] = fwd(engine, fpast, ev, t)
+% Forwards pass.
+
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+ev2 = cell(ss, 2);
+ev2(:,1) = fpast.evidence;
+ev2(:,2) = ev;
+
+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(:), ev2);
+end       
+f.evidence = ev;
+f.t = t;
+
+% get prior
+int = engine.interface;
+if fpast.t==1
+  prior = marginalize_pot(fpast.clpot{engine.int_clq1}, int, engine.maximize);
+else
+  prior = marginalize_pot(fpast.clpot{engine.out_clq}, int+ss, engine.maximize);
+  prior = set_domain_pot(prior, int); % shift back to slice 1
+end
+
+pots = [ {prior} CPDpot ];
+slice1 = 1:ss;
+slice2 = slice1 + ss; 
+CPDclqs = engine.clq_ass_to_node(slice2);
+D = engine.in_clq;
+clqs = [D CPDclqs];
+
+[f.clpot, f.seppot] =  init_pot(engine.jtree_engine, clqs, pots, engine.pot_type, engine.observed);
+[f.clpot, f.seppot] = collect_evidence(engine.jtree_engine, f.clpot, f.seppot);
+for c=1:length(f.clpot)
+  [f.clpot{c}, ll(c)] = normalize_pot(f.clpot{c});
+end
+logscale = ll(engine.root);
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd1.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd1.m
new file mode 100644
index 00000000..68de1e50
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/fwd1.m
@@ -0,0 +1,26 @@
+function [f, logscale] = fwd1(engine, ev, t)
+% Forwards pass for slice 1.
+
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+CPDpot = cell(1,ss);
+for n=1:ss
+  fam = family(bnet.dag, n, 1);
+  e = bnet.equiv_class(n, 1);
+  CPDpot{n} = convert_to_pot(bnet.CPD{e}, engine.pot_type, fam(:), ev);
+end       
+f.t = t;
+f.evidence = ev;
+
+pots = CPDpot;
+slice1 = 1:ss;
+CPDclqs = engine.clq_ass_to_node1(slice1);
+
+[f.clpot, f.seppot] =  init_pot(engine.jtree_engine1, CPDclqs, CPDpot, engine.pot_type, engine.observed1);
+[f.clpot, f.seppot] = collect_evidence(engine.jtree_engine1, f.clpot, f.seppot);
+for c=1:length(f.clpot)
+  [f.clpot{c}, ll(c)] = normalize_pot(f.clpot{c});
+end
+logscale = ll(engine.root1);
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/jtree_2TBN_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/jtree_2TBN_inf_engine.m
new file mode 100644
index 00000000..2d56445c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/jtree_2TBN_inf_engine.m
@@ -0,0 +1,69 @@
+function engine = jtree_2TBN_inf_engine(bnet, varargin)
+% JTREE_ONLINE_INF_ENGINE Online Junction tree inference algorithm for DBNs.
+% engine = jtree_online_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
+%
+% The same nodes must be observed in every slice.
+%
+% This uses the forwards interface of slice t-1 plus all of slice t.
+% By contrast, jtree_dbn uses all of slice t-1 plus the backwards interface of slice t.
+% See my thesis for details.
+
+
+clusters = {};
+
+args = varargin;
+nargs = length(args);
+for i=1:2:length(args)
+  switch args{i},
+   case 'clusters', clusters = args{i+1};
+   otherwise, error(['unrecognized argument ' args{i}])
+  end
+end
+
+engine.maximize = 0;
+engine.evidence = [];
+engine.node_sizes = [];
+
+int = compute_fwd_interface(bnet.intra, bnet.inter);
+engine.interface = int;
+ss = length(bnet.intra);
+engine.nonint = mysetdiff(1:ss, int);
+onodes = bnet.observed;
+
+bnet15 = mk_slice_and_half_dbn(bnet, int);
+
+% 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);
+jtree_engine = struct(engine.jtree_engine); % violate object privacy
+
+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 = jtree_engine.clq_ass_to_node;
+engine.root = jtree_engine.root_clq;
+
+% 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);
+jtree_engine1 = struct(engine.jtree_engine1); % violate object privacy
+engine.int_clq1 = clq_containing_nodes(engine.jtree_engine1, int);
+engine.clq_ass_to_node1 = jtree_engine1.clq_ass_to_node;
+engine.root1 = jtree_engine1.root_clq;
+
+engine.observed = [onodes onodes+ss];
+engine.observed1 = onodes;
+engine.pot_type = determine_pot_type(bnet, onodes);
+engine.slice_size = bnet.nnodes_per_slice;
+
+engine = class(engine, 'jtree_2TBN_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_family.m
new file mode 100644
index 00000000..0b6e6186
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_family.m
@@ -0,0 +1,12 @@
+function m = marginal_family(engine, b, i, t, add_ev)
+% MARGINAL_FAMILY Compute the marginal on the specified family (jtree_2TBN)
+% marginal = marginal_family(engine, b, i, t, add_ev)
+
+bnet = bnet_from_engine(engine);
+if t==1
+  m = marginal_nodes(engine, b, family(bnet.dag, i), t, add_ev, 1);
+else
+  ss = length(bnet.intra);
+  fam = family(bnet.dag, i+ss);
+  m = marginal_nodes(engine, b, fam, t, add_ev, 1);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..e7ee2ae9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/marginal_nodes.m
@@ -0,0 +1,32 @@
+function marginal = marginal_nodes(engine, b, nodes, t, add_ev, is_fam)
+% function marginal = marginal_nodes(engine, b, nodes, t, add_ev, is_fam) (jtree_2TBN)
+
+if nargin < 6, is_fam = 0; end
+ss = engine.slice_size;
+
+if ~is_fam & (t > 1) & all(nodes<=ss)
+  nodes = nodes + ss;
+end
+
+if t==1
+  c = clq_containing_nodes(engine.jtree_engine1, nodes, is_fam);
+else
+  c = clq_containing_nodes(engine.jtree_engine, nodes, is_fam);
+end
+if c == -1
+  error(['no clique contains ' nodes])
+end
+bigpot = b.clpot{c};
+pot = marginalize_pot(bigpot, nodes, engine.maximize);
+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.
+if t > 1
+  marginal.domain = nodes+(t-2)*engine.slice_size;
+end
+assert(~add_ev);
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/set_fields.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/set_fields.m
new file mode 100644
index 00000000..51df3b32
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_2TBN_inf_engine/set_fields.m
@@ -0,0 +1,16 @@
+function engine = set_fields(engine, varargin)
+% SET_FIELDS Set the fields for a generic engine
+% engine = set_fields(engine, name/value pairs)
+%
+% e.g., engine = set_fields(engine, 'maximize', 1)
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'maximize',
+     engine.maximize = args{i+1};
+     engine.jtree_engine = set_fields(engine.jtree_engine, 'maximize', args{i+1});
+     engine.jtree_engine1 = set_fields(engine.jtree_engine1, 'maximize', args{i+1});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Entries
new file mode 100644
index 00000000..14219dd2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Entries
@@ -0,0 +1,10 @@
+/back.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/back1.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/backT.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//
+/fwd.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/fwd1.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/jtree_sparse_2TBN_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/online/@jtree_sparse_2TBN_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Repository
new file mode 100644
index 00000000..2c445be3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/online/@jtree_sparse_2TBN_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back.m
new file mode 100644
index 00000000..7f686d55
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back.m
@@ -0,0 +1,27 @@
+function b = back(engine, bfuture, f, t)
+
+if f.t ~= t
+  error('mixed up time stamps')
+end
+if t==1
+  b = back1(engine, bfuture, f, t);
+  return;
+end
+
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+int = engine.interface;
+D = engine.in_clq;
+C = engine.out_clq;
+phiD = marginalize_pot(bfuture.clpot{D}, int, engine.maximize);
+phiD = set_domain_pot(phiD, int+ss); % shift to slice 2
+phiC = marginalize_pot(f.clpot{C}, int+ss, engine.maximize);
+ratio = divide_by_pot(phiD, phiC);
+f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio);
+
+[b.clpot, seppot] = distribute_evidence(engine.jtree_engine, f.clpot, f.seppot);
+for c=1:length(b.clpot)
+  [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c});
+end
+b.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back1.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back1.m
new file mode 100644
index 00000000..a8587a72
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/back1.m
@@ -0,0 +1,21 @@
+function b = back1(engine, bfuture, f, t)
+
+if t ~= 1
+  error('mixed up time stamps')
+end
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+int = engine.interface;
+D = engine.in_clq; % from J2
+C = engine.int_clq1; % from J1
+phiD = marginalize_pot(bfuture.clpot{D}, int, engine.maximize);
+phiC = marginalize_pot(f.clpot{C}, int, engine.maximize);
+ratio = divide_by_pot(phiD, phiC);
+f.clpot{C} = multiply_by_pot(f.clpot{C}, ratio);
+
+[b.clpot, seppot] = distribute_evidence(engine.jtree_engine1, f.clpot, f.seppot);
+for c=1:length(b.clpot)
+  [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c});
+end
+b.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/backT.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/backT.m
new file mode 100644
index 00000000..7f7a1b42
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/backT.m
@@ -0,0 +1,11 @@
+function b = backT(engine, f, t)
+
+if t==1
+  [b.clpot, seppot] = distribute_evidence(engine.jtree_engine1, f.clpot, f.seppot);
+else
+  [b.clpot, seppot] = distribute_evidence(engine.jtree_engine, f.clpot, f.seppot);
+end
+for c=1:length(b.clpot)
+  [b.clpot{c}, ll(c)] = normalize_pot(b.clpot{c});
+end
+b.t = t;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..048d9064
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/enter_evidence.m
@@ -0,0 +1,22 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (jtree_online)
+% [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]
+%
+
+engine.maximize = 0;
+args = varargin;
+for i=1:2:length(args)
+  switch args{i}
+   case 'maximize', engine.maximize = args{i+1};
+   otherwise, error(['unrecognized argument ' args{i}])
+  end
+end
+
+[engine, loglik] = offline_smoother(engine, evidence);
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd.m
new file mode 100644
index 00000000..948d8bc8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd.m
@@ -0,0 +1,47 @@
+function [f, logscale] = fwd(engine, fpast, ev, t)
+% Forwards pass.
+
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+ev2 = cell(ss, 2);
+ev2(:,1) = fpast.evidence;
+ev2(:,2) = ev;
+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(:), ev2);
+end       
+f.evidence = ev;
+f.t = t;
+
+% get prior
+int = engine.interface;
+if fpast.t==1
+  prior = marginalize_pot(fpast.clpot{engine.int_clq1}, int, engine.maximize);
+else
+  prior = marginalize_pot(fpast.clpot{engine.out_clq}, int+ss, engine.maximize);
+  prior = set_domain_pot(prior, int); % shift back to slice 1
+end
+
+pots = [ {prior} CPDpot ];
+slice1 = 1:ss;
+slice2 = slice1 + ss; 
+CPDclqs = engine.clq_ass_to_node(slice2);
+D = engine.in_clq;
+clqs = [D CPDclqs];
+
+[f.clpot, f.seppot] =  init_pot(engine.jtree_engine, clqs, pots, engine.pot_type, engine.observed);
+[f.clpot, f.seppot] = collect_evidence(engine.jtree_engine, f.clpot, f.seppot);
+for c=1:length(f.clpot)
+  if isa(f.clpot{c}, 'struct')
+     domain = f.clpot{c}.domain;
+     sizes = f.clpot{c}.sizes;
+     T = f.clpot{c}.T;
+     f.clpot{c} = dpot(domain, sizes, T);
+  end
+  [f.clpot{c}, ll(c)] = normalize_pot(f.clpot{c});
+end
+logscale = ll(engine.root);
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd1.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd1.m
new file mode 100644
index 00000000..45d28c3f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/fwd1.m
@@ -0,0 +1,32 @@
+function [f, logscale] = fwd1(engine, ev, t)
+% Forwards pass for slice 1.
+
+bnet = bnet_from_engine(engine);
+ss = bnet.nnodes_per_slice;
+
+CPDpot = cell(1,ss);
+for n=1:ss
+  fam = family(bnet.dag, n, 1);
+  e = bnet.equiv_class(n, 1);
+  CPDpot{n} = convert_to_pot(bnet.CPD{e}, engine.pot_type, fam(:), ev);
+end       
+f.evidence = ev;
+f.t = t;
+
+pots = CPDpot;
+slice1 = 1:ss;
+CPDclqs = engine.clq_ass_to_node1(slice1);
+
+[f.clpot, f.seppot] =  init_pot(engine.jtree_engine1, CPDclqs, CPDpot, engine.pot_type, engine.observed1);
+[f.clpot, f.seppot] = collect_evidence(engine.jtree_engine1, f.clpot, f.seppot);
+for c=1:length(f.clpot)
+  if isa(f.clpot{c}, 'struct')
+     domain = f.clpot{c}.domain;
+     sizes = f.clpot{c}.sizes;
+     T = f.clpot{c}.T;
+     f.clpot{c} = dpot(domain, sizes, T);
+  end
+  [f.clpot{c}, ll(c)] = normalize_pot(f.clpot{c});
+end
+logscale = ll(engine.root1);
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/jtree_sparse_2TBN_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/jtree_sparse_2TBN_inf_engine.m
new file mode 100644
index 00000000..4897e8fd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/jtree_sparse_2TBN_inf_engine.m
@@ -0,0 +1,95 @@
+function engine = jtree_sparse_2TBN_inf_engine(bnet, varargin)
+% JTREE_ONLINE_INF_ENGINE Online Junction tree inference algorithm for DBNs.
+% engine = jtree_online_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 do max-product, 0 means sum-product [0]
+%
+% The same nodes must be observed in every slice.
+
+ss = length(bnet.intra);
+clusters = {};
+engine.maximize = 0;
+
+args = varargin;
+nargs = length(args);
+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 = [];
+% include nodes with any outgoing arcs
+for u=1:ss
+  if any(bnet.inter(u,:))
+    int = [int u];
+  end
+end
+
+engine.interface = int;
+engine.nonint = mysetdiff(1:ss, int);
+
+onodes = bnet.observed;
+
+% Create a "1.5 slice" jtree, containing the interface nodes of slice 1
+% and all the nodes of slice 2
+% To keep the node numbering the same, we simply disconnect the non-interface nodes
+% from slice 1, 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 (i.e., we can include nodes whose potentials will
+% be left as all 1s).
+intra15 = bnet.intra;
+for i=engine.nonint(:)'
+  intra15(:,i) = 0;
+  intra15(i,:) = 0;
+  assert(~any(bnet.inter(i,:)))
+end
+dag15 = [intra15      bnet.inter;
+	 zeros(ss)    bnet.intra];
+ns = bnet.node_sizes(:);
+ns(engine.nonint) = 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(:));
+
+% 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);
+engine.jtree_engine = jtree_sparse_inf_engine(bnet15, 'clusters', clusters, 'root', int+ss);
+jtree_engine = struct(engine.jtree_engine); % violate object privacy
+
+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 = jtree_engine.clq_ass_to_node;
+engine.root = jtree_engine.root_clq;
+
+% 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.jtree_engine1 = jtree_sparse_inf_engine(bnet1, 'clusters', {int}, 'root', int);
+jtree_engine1 = struct(engine.jtree_engine1); % violate object privacy
+engine.int_clq1 = clq_containing_nodes(engine.jtree_engine1, int);
+engine.clq_ass_to_node1 = jtree_engine1.clq_ass_to_node;
+engine.root1 = jtree_engine1.root_clq;
+
+engine.observed = [onodes onodes+ss];
+engine.observed1 = onodes;
+engine.pot_type = determine_pot_type(bnet, onodes);
+engine.slice_size = bnet.nnodes_per_slice;
+
+engine = class(engine, 'jtree_sparse_2TBN_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_family.m
new file mode 100644
index 00000000..0b6e6186
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_family.m
@@ -0,0 +1,12 @@
+function m = marginal_family(engine, b, i, t, add_ev)
+% MARGINAL_FAMILY Compute the marginal on the specified family (jtree_2TBN)
+% marginal = marginal_family(engine, b, i, t, add_ev)
+
+bnet = bnet_from_engine(engine);
+if t==1
+  m = marginal_nodes(engine, b, family(bnet.dag, i), t, add_ev, 1);
+else
+  ss = length(bnet.intra);
+  fam = family(bnet.dag, i+ss);
+  m = marginal_nodes(engine, b, fam, t, add_ev, 1);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..e7ee2ae9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@jtree_sparse_2TBN_inf_engine/marginal_nodes.m
@@ -0,0 +1,32 @@
+function marginal = marginal_nodes(engine, b, nodes, t, add_ev, is_fam)
+% function marginal = marginal_nodes(engine, b, nodes, t, add_ev, is_fam) (jtree_2TBN)
+
+if nargin < 6, is_fam = 0; end
+ss = engine.slice_size;
+
+if ~is_fam & (t > 1) & all(nodes<=ss)
+  nodes = nodes + ss;
+end
+
+if t==1
+  c = clq_containing_nodes(engine.jtree_engine1, nodes, is_fam);
+else
+  c = clq_containing_nodes(engine.jtree_engine, nodes, is_fam);
+end
+if c == -1
+  error(['no clique contains ' nodes])
+end
+bigpot = b.clpot{c};
+pot = marginalize_pot(bigpot, nodes, engine.maximize);
+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.
+if t > 1
+  marginal.domain = nodes+(t-2)*engine.slice_size;
+end
+assert(~add_ev);
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Entries
new file mode 100644
index 00000000..d9c315a5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Entries
@@ -0,0 +1,8 @@
+/bnet_from_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enter_evidence.m/1.1.1.1/Mon Jun 17 23:46:46 2002//
+/find_mpe.m/1.1.1.1/Mon Jun 17 23:50:16 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//
+/smoother_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/online/@smoother_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Repository
new file mode 100644
index 00000000..a10f8a08
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/online/@smoother_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/bnet_from_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/bnet_from_engine.m
new file mode 100644
index 00000000..b57ee5f4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/bnet_from_engine.m
@@ -0,0 +1,5 @@
+function bnet = bnet_from_engine(engine)
+% BNET_FROM_ENGINE Return the bnet structure stored inside the engine (smoother_engine)
+% bnet = bnet_from_engine(engine)
+
+bnet = bnet_from_engine(engine.tbn_engine);
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/enter_evidence.m
new file mode 100644
index 00000000..299c2331
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/enter_evidence.m
@@ -0,0 +1,21 @@
+function [engine, LL] = enter_evidence(engine, ev)
+% ENTER_EVIDENCE Call the offline smoother
+% [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)
+%
+
+T = size(ev, 2);
+f = cell(1,T);
+b = cell(1,T); % b{t}.clpot{c}
+ll = zeros(1,T);
+[f{1}, ll(1)] = fwd1(engine.tbn_engine, ev(:,1), 1);
+for t=2:T
+  [f{t}, ll(t)] = fwd(engine.tbn_engine, f{t-1}, ev(:,t), t);
+end
+LL = sum(ll);
+b{T} = backT(engine.tbn_engine, f{T}, T);
+for t=T-1:-1:1
+  b{t} = back(engine.tbn_engine, b{t+1}, f{t}, t);
+end
+engine.b = b;
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/find_mpe.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/find_mpe.m
new file mode 100644
index 00000000..5415f120
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/find_mpe.m
@@ -0,0 +1,33 @@
+function mpe = find_mpe(engine, ev)
+% 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)
+%
+
+mpe = cell(size(ev));
+engine.tbn_engine = set_fields(engine.tbn_engine, 'maximize', 1);
+
+T = size(ev, 2);
+f = cell(1,T);
+b = cell(1,T); % b{t}.clpot{c}
+ll = zeros(1,T);
+[f{1}, ll(1)] = fwd1(engine.tbn_engine, ev(:,1), 1);
+for t=2:T
+  [f{t}, ll(t)] = fwd(engine.tbn_engine, f{t-1}, ev(:,t), t);
+end
+
+if T==1
+  [b{1}, mpe(:,1)] = backT_mpe(engine.tbn_engine, f{1}, ev(:,1), 1);
+else
+  [b{T}, mpe(:,T)] = backT_mpe(engine.tbn_engine, f{T}, ev(:,T-1:T), T);
+  for t=T-1:-1:2
+    [b{t}, mpe(:,t)] = back_mpe(engine.tbn_engine, b{t+1}, f{t}, ev(:,t-1:t), t);
+  end
+  t = 1;
+  [b{t}, mpe(:,t)] = back1_mpe(engine.tbn_engine, b{t+1}, f{t}, ev(:,1), t);
+end
+engine.b = b;
+  
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_family.m
new file mode 100644
index 00000000..b7b0d7ec
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_family.m
@@ -0,0 +1,6 @@
+function marginal = marginal_family(engine, i, t, add_ev)
+% MARGINAL_FAMILY Compute the joint distribution on a set of family (smoother_engine)
+% function marginal = marginal_family(engine, i, t, add_ev)
+
+if nargin < 4, add_ev = 0; end
+marginal = marginal_family(engine.tbn_engine, engine.b{t}, i, t, add_ev);
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_nodes.m
new file mode 100644
index 00000000..e8574c53
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/marginal_nodes.m
@@ -0,0 +1,7 @@
+function marginal = marginal_nodes(engine, nodes, t, add_ev)
+% MARGINAL_NODES Compute the joint distribution on a set of nodes (smoother_engine)
+% function marginal = marginal_nodes(engine, nodes, t, add_ev)
+
+if nargin < 4, add_ev = 0; end
+
+marginal = marginal_nodes(engine.tbn_engine, engine.b{t}, nodes, t, add_ev);
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/smoother_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/smoother_engine.m
new file mode 100644
index 00000000..adf7ede8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/smoother_engine.m
@@ -0,0 +1,12 @@
+function engine = smoother_engine(tbn_engine)
+% SMOOTHER_ENGINE Create an engine which does offline (fixed-interval) smoothing in O(T) space/time
+% function engine = smoother_engine(tbn_engine)
+%
+% tbn_engine is any 2TBN inference engine which supports the following methods:
+% fwd, fwd1, back, backT, back, marginal_nodes and marginal_family.
+
+engine.tbn_engine = tbn_engine;
+engine.b = []; % space to store smoothed messages
+engine = class(engine, 'smoother_engine');
+%engine = class(engine, 'smoother_engine', inf_engine(bnet_from_engine(tbn_engine)));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/update_engine.m b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/update_engine.m
new file mode 100644
index 00000000..ffe0661e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/@smoother_engine/update_engine.m
@@ -0,0 +1,5 @@
+function engine = update_engine(engine, newCPDs)
+% UPDATE_ENGINE Update the engine to take into account the new parameters (smoother_engine).
+% engine = update_engine(engine, newCPDs)
+
+engine.tbn_engine = update_engine(engine.tbn_engine, newCPDs);
diff --git a/sourcecodes/bnt-master/BNT/inference/online/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/online/CVS/Entries
new file mode 100644
index 00000000..842483c7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/CVS/Entries
@@ -0,0 +1,2 @@
+/dummy/1.1.1.1/Sat Jan 18 22:22:38 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/online/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/online/CVS/Entries.Log
new file mode 100644
index 00000000..794e1320
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/CVS/Entries.Log
@@ -0,0 +1,5 @@
+A D/@filter_engine////
+A D/@hmm_2TBN_inf_engine////
+A D/@jtree_2TBN_inf_engine////
+A D/@jtree_sparse_2TBN_inf_engine////
+A D/@smoother_engine////
diff --git a/sourcecodes/bnt-master/BNT/inference/online/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/online/CVS/Repository
new file mode 100644
index 00000000..2918a1ee
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/online
diff --git a/sourcecodes/bnt-master/BNT/inference/online/CVS/Root b/sourcecodes/bnt-master/BNT/inference/online/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/online/dummy b/sourcecodes/bnt-master/BNT/inference/online/dummy
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/online/dummy
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/CVS/Entries
new file mode 100644
index 00000000..a4fbc6ee
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/CVS/Entries
@@ -0,0 +1,7 @@
+/belprop_fg_inf_engine.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//
+/find_mpe.m/1.1.1.1/Thu Jun 20 00:02:12 2002//
+/loopy_converged.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_params.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/CVS/Repository
new file mode 100644
index 00000000..7e75998c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@belprop_fg_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/belprop_fg_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/belprop_fg_inf_engine.m
new file mode 100644
index 00000000..1945c3f2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/belprop_fg_inf_engine.m
@@ -0,0 +1,47 @@
+function engine = belprop_fg_inf_engine(fg, varargin) 
+% BELPROP_FG_INF_ENGINE Make a belief propagation inference engine for factor graphs
+% engine = belprop_fg_inf_engine(factor_graph, ...)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default in brackets]
+% e.g., engine = belprop_inf_engine(fg, 'tol', 1e-2, 'max_iter', 10)
+%
+% max_iter - max. num. iterations [ 2*num_nodes ]
+% momentum - weight assigned to old message in convex combination (useful for damping oscillations) [0]
+% tol - tolerance used to assess convergence [1e-3]
+% maximize - 1 means use max-product, 0 means use sum-product [0]
+%
+% This uses potential objects, like belprop_inf_engine, and hence is quite slow.
+
+engine = init_fields;
+engine = class(engine, 'belprop_fg_inf_engine');
+
+% set params to default values
+N = length(fg.G);
+engine.max_iter = 2*N;
+engine.momentum = 0;
+engine.tol = 1e-3;
+engine.maximize = 0;
+
+% parse optional arguments
+engine = set_params(engine, varargin);
+
+engine.fgraph = fg;
+
+% store results computed by enter_evidence here
+engine.marginal_nodes = cell(1, fg.nvars);
+engine.evidence = [];
+
+
+%%%%%%%%%%%%
+
+function engine = init_fields()
+
+engine.fgraph = [];
+engine.max_iter = [];
+engine.momentum = [];
+engine.tol = [];
+engine.maximize = [];
+engine.marginal_nodes = [];
+engine.evidence = [];
+engine.niter = [];
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..e275e298
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/enter_evidence.m
@@ -0,0 +1,126 @@
+function [engine, ll, niter] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Propagate evidence using belief propagation
+% [engine, ll, niter] = enter_evidence(engine, evidence, ...)
+%
+% The log-likelihood is not computed; ll = 0.
+% niter contains the number of iterations used 
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - 1 means use max-product, 0 means use sum-product [0]
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+ll = 0;
+maximize = 0;
+
+if nargin >= 3
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'maximize', maximize = args{i+1};
+     otherwise,
+      error(['invalid argument name ' args{i}]);
+    end
+  end
+end
+
+verbose = 0;
+
+ns = engine.fgraph.node_sizes;
+onodes = find(~isemptycell(evidence));
+hnodes = find(isemptycell(evidence));
+cnodes = engine.fgraph.cnodes;
+pot_type = determine_pot_type(engine.fgraph, onodes);
+
+% prime each local kernel with evidence (if any)
+nfactors = engine.fgraph.nfactors;
+nvars = engine.fgraph.nvars;
+factors = cell(1,nfactors);
+for f=1:nfactors
+  K = engine.fgraph.factors{engine.fgraph.equiv_class(f)};
+  factors{f} = convert_to_pot(K, pot_type, engine.fgraph.dom{f}(:), evidence);
+end
+  
+% initialise msgs
+msg_var_to_fac = cell(nvars, nfactors);
+for x=1:nvars
+  for f=engine.fgraph.dep{x}
+    msg_var_to_fac{x,f} = mk_initial_pot(pot_type, x, ns, cnodes, onodes);
+  end
+end
+msg_fac_to_var = cell(nfactors, nvars);
+dom = cell(1, nfactors);
+for f=1:nfactors
+  %hdom{f} = myintersect(engine.fgraph.dom{f}, hnodes);
+  dom{f} = engine.fgraph.dom{f}(:)';
+  for x=dom{f}
+    msg_fac_to_var{f,x} = mk_initial_pot(pot_type, x, ns, cnodes, onodes);
+    %msg_fac_to_var{f,x} = marginalize_pot(factors{f}, x);
+  end
+end
+
+
+
+converged = 0;
+iter = 1;
+var_prod = cell(1, nvars);
+fac_prod = cell(1, nfactors);
+
+while ~converged && (iter <= engine.max_iter)
+  if verbose, fprintf('iter %d\n', iter);  end
+  
+  % absorb
+  old_var_prod = var_prod;
+  for x=1:nvars
+    var_prod{x} = mk_initial_pot(pot_type, x, ns, cnodes, onodes);
+    for f=engine.fgraph.dep{x}
+      var_prod{x} = multiply_by_pot(var_prod{x}, msg_fac_to_var{f,x});
+    end
+  end
+  for f=1:nfactors
+    fac_prod{f} = mk_initial_pot(pot_type, dom{f}, ns, cnodes, onodes);
+    for x=dom{f}
+      fac_prod{f} = multiply_by_pot(fac_prod{f}, msg_var_to_fac{x,f});
+    end
+  end
+
+  % send msgs to neighbors
+  old_msg_var_to_fac = msg_var_to_fac;
+  old_msg_fac_to_var = msg_fac_to_var;
+  converged = 1;
+  for x=1:nvars
+    %if verbose, disp(['var ' num2str(x) ' sending to fac ' num2str(engine.fgraph.dep{x})]); end
+    for f=engine.fgraph.dep{x}
+      temp = divide_by_pot(var_prod{x}, old_msg_fac_to_var{f,x});
+      msg_var_to_fac{x,f} = normalize_pot(temp);
+      if ~approxeq_pot(msg_var_to_fac{x,f}, old_msg_var_to_fac{x,f}, engine.tol), converged = 0; end
+    end
+  end
+  for f=1:nfactors
+    %if verbose, disp(['fac ' num2str(f) ' sending to var ' num2str(dom{f})]); end
+    for x=dom{f}
+      temp = divide_by_pot(fac_prod{f}, old_msg_var_to_fac{x,f});
+      temp2 = multiply_by_pot(factors{f}, temp);
+      temp3 = marginalize_pot(temp2, x, maximize);
+      msg_fac_to_var{f,x} = normalize_pot(temp3);
+      if ~approxeq_pot(msg_fac_to_var{f,x}, old_msg_fac_to_var{f,x}, engine.tol), converged = 0; end
+    end
+  end
+
+  if iter==1
+    converged = 0;
+  end
+  iter = iter + 1;
+end
+
+niter = iter - 1;
+engine.niter = niter;
+
+for x=1:nvars
+  engine.marginal_nodes{x} = normalize_pot(var_prod{x});
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/find_mpe.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/find_mpe.m
new file mode 100644
index 00000000..439936d5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/find_mpe.m
@@ -0,0 +1,49 @@
+function mpe = find_mpe(engine, evidence, varargin)
+% FIND_MPE Find the most probable explanation of the data  (belprop_fg)
+% function mpe = find_mpe(engine, evidence,...)
+%
+% evidence{i} = [] if X(i) is hidden, and otherwise contains its observed value (scalar or column vector).
+%
+% This finds the marginally most likely value for each hidden node,
+% and may give the wrong results even if the graph is acyclic,
+% unless you set break_ties = 1.
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% break_ties is optional. If 1, we will force ties to be broken consistently
+%  by calling enter_evidence N times. (see Jensen96, p106) Default = 1.
+
+break_ties = 1;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'break_ties',    break_ties = args{i+1}; 
+   otherwise,  
+    error(['invalid argument name ' args{i}]);       
+  end
+end
+
+engine = enter_evidence(engine, evidence, 'maximize', 1);
+
+observed = ~isemptycell(evidence);
+evidence = evidence(:); % hack to handle unrolled DBNs
+N = length(evidence);
+mpe = cell(1,N);
+for i=1:N
+  m = marginal_nodes(engine, i);
+  % observed nodes are all set to 1 inside the inference engine, so we must undo this
+  if observed(i)
+    mpe{i} = evidence{i};
+  else
+    mpe{i} = argmax(m.T);
+    if break_ties
+      evidence{i} = mpe{i};                             
+      [engine, ll] = enter_evidence(engine, evidence, 'maximize', 1);  
+    end
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/loopy_converged.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/loopy_converged.m
new file mode 100644
index 00000000..b9015e85
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/loopy_converged.m
@@ -0,0 +1,12 @@
+function niter = loopy_converged(engine)
+% LOOPY_CONVERGED Did loopy belief propagation converge? 0 means no, eles we return the num. iterations.
+% function niter = loopy_converged(engine)
+%
+% We use a simple heuristic: we say convergence occurred if the number of iterations
+% used was less than the maximum allowed.
+
+if engine.niter == engine.max_iter
+  niter = 0;
+else
+  niter = engine.niter;
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..0c85aed6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/marginal_nodes.m
@@ -0,0 +1,6 @@
+function marginal = marginal_nodes(engine, query)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (belprop)
+% marginal = marginal_nodes(engine, query)
+
+assert(length(query)==1);
+marginal = pot_to_marginal(engine.marginal_nodes{query});
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/set_params.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/set_params.m
new file mode 100644
index 00000000..a495b3bb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_fg_inf_engine/set_params.m
@@ -0,0 +1,24 @@
+function engine = set_params(engine, varargin)
+% SET_PARAMS Set the parameters (fields) for a belprop_inf_engine object
+% engine = set_params(engine, name/value pairs)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% e.g., engine = set_params(engine, 'tol', 1e-2, 'max_iter', 10)
+%
+% max_iter - max. num. loopy iterations 
+% momentum - weight assigned to old message in convex combination 
+% tol - tolerance used to assess convergence 
+% maximize - 1 means use max-product, 0 means use sum-product
+
+args = varargin{1};
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'max_iter', engine.max_iter = args{i+1};
+   case 'momentum', engine.momentum = args{i+1};
+   case 'tol',      engine.tol = args{i+1};
+   case 'maximize', engine.maximize = args{i+1};
+   otherwise,
+    error(['invalid argument name ' args{i}]);
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Entries
new file mode 100644
index 00000000..b2150de3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Entries
@@ -0,0 +1,7 @@
+/belprop_inf_engine.m/1.1.1.1/Tue Dec 31 19:00:06 2002//
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/find_mpe.m/1.1.1.1/Wed Jun 19 22:08:40 2002//
+/loopy_converged.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/static/@belprop_inf_engine/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Entries.Log
new file mode 100644
index 00000000..9c6f22e4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Entries.Log
@@ -0,0 +1,2 @@
+A D/Old////
+A D/private////
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Repository
new file mode 100644
index 00000000..928be328
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@belprop_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/CVS/Entries
new file mode 100644
index 00000000..06598b7b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/CVS/Entries
@@ -0,0 +1,6 @@
+/belprop_gdl_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/belprop_inf_engine_nostr.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_evidence1.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_domain.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/CVS/Repository
new file mode 100644
index 00000000..f6b12595
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@belprop_inf_engine/Old
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/belprop_gdl_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/belprop_gdl_inf_engine.m
new file mode 100644
index 00000000..f3b84925
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/belprop_gdl_inf_engine.m
@@ -0,0 +1,67 @@
+function engine = belprop_gdl_inf_engine(gdl, varargin) 
+% BELPROP_GDL_INF_ENGINE Make a belief propagation inference engine for a GDL graph
+% engine = belprop_gdl_inf_engine(gdl_graph, ...)
+%
+% If the GDL graph is a tree, this will give exact results.
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default in brackets]
+% e.g., engine = belprop_inf_engine(gdl, 'tol', 1e-2, 'max_iter', 10)
+%
+% protocol - 'tree' means send messages up then down the tree,
+%            'parallel' means use synchronous updates ['parallel']
+% max_iter - max. num. iterations [ 2*num_nodes ]
+% momentum - weight assigned to old message in convex combination (useful for damping oscillations) [0]
+% tol - tolerance used to assess convergence [1e-3]
+% maximize - 1 means use max-product, 0 means use sum-product [0]
+
+
+engine = init_fields;
+engine = class(engine, 'belprop_gdl_inf_engine');
+
+% set default params
+N = length(gdl.G);
+engine.protocol = 'parallel';
+engine.max_iter = 2*N;
+engine.momentum = 0;
+engine.tol = 1e-3;
+engine.maximize = 0;
+
+engine = set_params(engine, varargin);
+
+engine.gdl = gdl;
+
+if strcmp(engine.protocol, 'tree')
+  % Make a rooted tree, so there is a fixed message passing order.
+  root = N;
+  [engine.tree, engine.preorder, engine.postorder, height, cyclic] = mk_rooted_tree(gdl.G, root);
+  assert(~cyclic);
+end
+
+% store results computed by enter_evidence here
+ndoms = length(gdl.doms);
+nvars = length(gdl.vars);
+engine.marginal_domains = cell(1, ndoms);
+
+% to compute the marginal on each variable, we need to know which domain to marginalize
+% and we want to choose the lightest. We compute the weight once we have seen the evidence.
+engine.dom_weight = [];
+engine.evidence = [];
+
+
+%%%%%%%%%
+
+function engine = init_fields()
+
+engine.protocol = [];
+engine.gdl = [];
+engine.max_iter = [];
+engine.momentum = [];
+engine.tol = [];
+engine.maximize = [];
+engine.marginal_domains = [];
+engine.evidence = [];
+engine.tree = [];
+engine.preorder = [];
+engine.postorder = [];
+engine.dom_weight = [];
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/belprop_inf_engine_nostr.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/belprop_inf_engine_nostr.m
new file mode 100644
index 00000000..8219a868
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/belprop_inf_engine_nostr.m
@@ -0,0 +1,31 @@
+function engine = belprop_inf_engine(fg, max_iter, momentum, tol, maximize)
+
+if nargin < 2, max_iter = length(fg.G); end
+if nargin < 3, momentum = 0; end
+if nargin < 4, tol = 1e-3; end
+if nargin < 5, maximize = 0; end
+
+engine.fgraph = fg;
+engine.max_iter = max_iter;
+engine.momentum = momentum;
+engine.tol = tol;
+engine.maximize = maximize;
+
+% store results computed by enter_evidence here
+ndoms = length(fg.doms);
+nvars = length(fg.vars);
+engine.marginal_domains = cell(1, ndoms);
+
+% to compute the marginal on each variable, we need to know which domain to marginalize
+% so we represent each domain as a bit vector, and compute its (pre-evidence) weight
+engine.dom_weight = [];
+
+% engine.dom_bitv = sparse(ndoms, nvars);
+% ns = fg.node_sizes;
+% for i=1:ndoms
+%   engine.dom_bitv(i, fg.doms{i}) = 1;
+%   engine.dom_weight(i) = prod(ns(fg.doms{i}));
+% end
+
+
+engine = class(engine, 'belprop_inf_engine');
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/enter_evidence.m
new file mode 100644
index 00000000..54649557
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/enter_evidence.m
@@ -0,0 +1,80 @@
+function engine = enter_evidence(engine, evidence)
+
+doms = engine.fg.doms;
+ndoms = length(doms);
+ns = engine.fg.node_sizes;
+obs = find(~isemptycell(evidence));
+cobs = myintersect(obs, engine.fg.cnodes);
+dobs = myintersect(obs, engine.fg.dnodes);
+ns(cobs) = 0;
+ns(dobs) = 1;
+
+% prime each local kernel with evidence (if any)
+local_kernel = cell(1, ndoms);
+for i=1:length(engine.fg.kernels_of_type)
+  u = engine.fg.kernels_of_type{i};
+  local_kernel(u) = kernel_to_dpots(engine.fg.kernels{i}, evidence, engine.fg.domains_of_type{i});
+end
+  
+% initialise all msgs to 1s
+nedges = engine.fg.nedges;
+msg = cell(1, nedges);
+for i=1:nedges
+  msg{i} = dpot(engine.fg.sepset{i}, ns(engine.fg.sepset{i}));
+end
+
+prod_of_msg = cell(1, ndoms);
+bel = cell(1, ndoms);
+old_bel = cell(1, ndoms);
+
+converged = 0;
+iter = 1;
+while ~converged & (iter <= engine.max_iter)
+  
+  % each node multiplies all its incoming msgs
+  for i=1:ndoms
+    prod_of_msg{i} = dpot(doms{i}, ns(doms{i}));
+    nbrs = engine.fg.nbrs{i};
+    for j=1:length(nbrs)
+      ndx = engine.fg.edge_ndx(j,i);
+      prod_of_msg{i} = multiply_by_pot(prod_of_msg{i}, msg{ndx});
+    end
+  end
+  old_msg = msg;
+  
+  % each node computes its local belief
+  for i=1:ndoms
+    bel{i} = normalize_pot(multiply_pots(prod_of_msg{i}, local_kernel{i}));
+  end
+
+  % converged?
+  converged = 1;
+  for i=1:ndoms
+    if ~approxeq(bel{i}, old_bel{i}, engine.tol)
+      converged = 0;
+      break;
+    end
+  end
+
+  if ~converged
+    % each node sends a msg to each of its neighbors
+    for i=1:ndoms
+      nbrs = engine.fg.nbrs{i};
+      for j=1:length(nbrs)
+	% multiply all incoming msgs except from j
+	temp = prod_of_msg{i};
+	ndx = engine.fg.edge_ndx(j,i);
+	temp = divide_by_pot(temp, old_msg{ndx});
+	% send msg from i to j
+	temp = multiply_by_pot(temp, local_kernel{i});
+	ndx = engine.fg.edge_ndx(i,j);
+	msg{ndx} = normalize_pot(marginalize_pot(temp, engine.fg.sepset{ndx}));
+      end
+    end
+  end
+
+  iter = iter + 1;
+end
+
+  
+engine.marginal = bel;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/enter_evidence1.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/enter_evidence1.m
new file mode 100644
index 00000000..b38cd3cb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/enter_evidence1.m
@@ -0,0 +1,94 @@
+function engine = enter_evidence(engine, evidence)
+
+doms = engine.fgraph.doms;
+ndoms = length(doms);
+ns = engine.fgraph.node_sizes;
+obs = find(~isemptycell(evidence));
+cobs = myintersect(obs, engine.fgraph.cnodes);
+dobs = myintersect(obs, engine.fgraph.dnodes);
+ns(cobs) = 0;
+ns(dobs) = 1;
+
+% recompute the weight of each domain now that we know what nodes are observed
+for i=1:ndoms
+  engine.dom_weight(i) = prod(ns(engine.fgraph.doms{i}));
+end
+
+% prime each local kernel with evidence (if any)
+local_kernel = cell(1, ndoms);
+for i=1:length(engine.fgraph.kernels_of_type)
+  u = engine.fgraph.kernels_of_type{i};
+  local_kernel(u) = kernel_to_dpots(engine.fgraph.kernels{i}, evidence, engine.fgraph.domains_of_type{i});
+end
+  
+% initialise all msgs to 1s
+msg = cell(ndoms, ndoms);
+for i=1:ndoms
+  nbrs = engine.fgraph.nbrs{i};
+  for j=nbrs(:)'
+    dom = engine.fgraph.sepset{i,j};
+    msg{i,j} = dpot(dom, ns(dom));
+  end
+end
+
+prod_of_msg = cell(1, ndoms);
+bel = cell(1, ndoms);
+old_bel = cell(1, ndoms);
+
+converged = 0;
+iter = 1;
+while ~converged & (iter <= engine.max_iter)
+  
+  % each node multiplies all its incoming msgs
+  for i=1:ndoms
+    prod_of_msg{i} = dpot(doms{i}, ns(doms{i}));
+    nbrs = engine.fgraph.nbrs{i};
+    for j=nbrs(:)'
+      prod_of_msg{i} = multiply_by_pot(prod_of_msg{i}, msg{j,i});
+    end
+  end
+  
+  % each node computes its local belief
+  old_bel = bel;
+  for i=1:ndoms
+    bel{i} = normalize_pot(multiply_pots(prod_of_msg{i}, local_kernel{i}));
+  end
+
+  % converged?
+  if iter==1
+    converged = 0;
+  else
+    converged = 1;
+    for i=1:ndoms
+      belT = get_params(bel{i}, 'table');
+      old_belT = get_params(old_bel{i}, 'table');
+      if ~approxeq(belT, old_belT, engine.tol)
+	converged = 0;
+	break;
+      end
+    end
+  end
+
+  if ~converged
+    old_msg = msg;
+    % each node sends a msg to each of its neighbors
+    for i=1:ndoms
+      nbrs = engine.fgraph.nbrs{i};
+      for j=nbrs(:)'
+	% multiply all incoming msgs except from j
+	temp = prod_of_msg{i};
+	temp = divide_by_pot(temp, old_msg{j,i});
+	% send msg from i to j
+	temp = multiply_by_pot(temp, local_kernel{i});
+	msg{i,j} = normalize_pot(marginalize_pot(temp, engine.fgraph.sepset{i,j}));
+      end
+    end
+  end
+
+  iter = iter + 1
+end
+
+engine.marginal_domains = bel;
+%for i=1:ndoms  
+  %engine.marginal_domains{i} = get_params(bel{i}, 'table');
+%end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/marginal_domain.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/marginal_domain.m
new file mode 100644
index 00000000..49ad94c5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/Old/marginal_domain.m
@@ -0,0 +1,5 @@
+function marginal = marginal_domain(engine, i)
+% MARGINAL_DOMAIN Return the marginal on the specified domain (belprop)
+% marginal = marginal_domain(engine, i)
+
+marginal = pot_to_marginal(engine.marginal_domains{i});
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/belprop_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/belprop_inf_engine.m
new file mode 100644
index 00000000..839af506
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/belprop_inf_engine.m
@@ -0,0 +1,90 @@
+function engine = belprop_inf_engine(bnet, varargin) 
+% BELPROP_INF_ENGINE Make a loopy belief propagation inference engine
+% engine = belprop_inf_engine(bnet, ...)
+%
+% This is like pearl_inf_engine, except it uses potential objects,
+% instead of lambda/pi structs. Hence it is slower.
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default in brackets]
+%
+% protocol - 'tree' means send messages up then down the tree,
+%            'parallel' means use synchronous updates ['parallel']
+% max_iter - max. num. iterations [ 2*num_nodes ]
+% momentum - weight assigned to old message in convex combination (useful for damping oscillations) [0]
+% tol      - tolerance used to assess convergence [1e-3]
+% maximize - 1 means use max-product, 0 means use sum-product [0]
+% filename - name of file to write beliefs to after each iteration within enter_evidence [ [] ]
+%
+% e.g., engine = belprop_inf_engine(bnet, 'maximize', 1, 'max_iter', 10)
+
+% gdl = general distributive law
+engine.gdl = bnet_to_gdl(bnet);
+
+% set default params
+N = length(engine.gdl.G);
+engine.protocol = 'parallel';
+engine.max_iter = 2*N;
+engine.momentum = 0;
+engine.tol = 1e-3;
+engine.maximize = 0;
+engine.filename = [];
+engine.fid = [];
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'max_iter', engine.max_iter = args{i+1};
+   case 'momentum', engine.momentum = args{i+1};
+   case 'tol',      engine.tol = args{i+1};
+   case 'protocol', engine.protocol = args{i+1};
+   case 'filename', engine.filename = args{i+1};
+   otherwise,
+    error(['invalid argument name ' args{i}]);
+  end
+end
+
+
+if strcmp(engine.protocol, 'tree')
+  % Make a rooted tree, so there is a fixed message passing order.
+  root = N;
+  [engine.tree, engine.preorder, engine.postorder, height, cyclic] = mk_rooted_tree(engine.gdl.G, root);
+  assert(~cyclic);
+end
+
+% store results computed by enter_evidence here
+engine.marginal_domains = cell(1, N);
+
+engine.niter = [];
+
+engine = class(engine, 'belprop_inf_engine', inf_engine(bnet));
+
+%%%%%%%%%
+
+function gdl = bnet_to_gdl(bnet)
+
+gdl.G = mk_undirected(bnet.dag);
+N = length(bnet.dag);
+gdl.doms = cell(1,N);
+for i=1:N
+  gdl.doms{i} = family(bnet.dag, i);
+end 
+
+% Compute a bit vector representation of the set of domains
+% dom_bitv(i,j) = 1 iff variable j occurs in domain i
+gdl.dom_bitv = zeros(N, N);
+for i=1:N
+  gdl.dom_bitv(i, gdl.doms{i}) = 1;
+end
+   
+% compute the interesection of the domains on either side of each edge (separating set)
+gdl.sepset = cell(N, N);
+gdl.nbrs = cell(1,N);
+for i=1:N
+  nbrs = neighbors(gdl.G, i);
+  gdl.nbrs{i} = nbrs;
+  for j = nbrs(:)'
+    gdl.sepset{i,j} = myintersect(gdl.doms{i}, gdl.doms{j});
+  end
+end  
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..88cce18e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/enter_evidence.m
@@ -0,0 +1,86 @@
+function [engine, ll, niter] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Propagate evidence using belief propagation
+% [engine, ll, niter] = enter_evidence(engine, evidence, ...)
+%
+% The log-likelihood is not computed; ll = 0.
+% niter contains the number of iterations used (if engine.protocol = 'parallel')
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% maximize - 1 means use max-product, 0 means use sum-product [0]
+% exclude  - list of nodes whose potential will not be included in the joint [ [] ]
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+
+ll = 0;
+exclude = [];
+maximize = 0;
+
+if nargin >= 3
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'exclude', exclude = args{i+1};
+     case 'maximize', maximize = args{i+1};
+     otherwise,
+      error(['invalid argument name ' args{i}]);
+    end
+  end
+end
+
+engine.maximize = maximize;
+
+if ~isempty(engine.filename)
+  engine.fid = fopen(engine.filename, 'w');
+  if engine.fid == 0
+    error(['can''t open ' engine.filename]);
+  end
+else
+  engine.fid = [];
+end
+
+gdl = engine.gdl;
+bnet = bnet_from_engine(engine);
+
+ndoms = length(gdl.doms);
+ns = bnet.node_sizes;
+onodes = find(~isemptycell(evidence));
+pot_type = determine_pot_type(bnet, onodes);
+
+% prime each local kernel with evidence (if any)
+local_kernel = cell(1, ndoms);
+for i=1:ndoms
+  if myismember(i, exclude)
+    local_kernel{i} =  mk_initial_pot(pot_type, gdl.doms{i}, ns, bnet.cnodes, onodes);
+  else
+    e = bnet.equiv_class(i);
+    local_kernel{i} =  convert_to_pot(bnet.CPD{e}, pot_type, gdl.doms{i}(:), evidence);
+  end
+end
+  
+% initialise all msgs to 1s
+msg = cell(ndoms, ndoms);
+for i=1:ndoms
+  nbrs = gdl.nbrs{i};
+  for j=nbrs(:)'
+    dom = gdl.sepset{i,j};
+    msg{i,j} = mk_initial_pot(pot_type, dom, ns, bnet.cnodes, onodes);
+  end
+end
+
+switch engine.protocol
+ case 'parallel', 
+   [engine.marginal_domains, niter] = parallel_protocol(engine, evidence, pot_type, local_kernel, msg);
+ case 'tree',
+  engine.marginal_domains = serial_protocol(engine, evidence, pot_type, local_kernel, msg);
+  niter = 1;
+end
+engine.niter = niter;
+
+%fprintf('just finished %d iterations of belprop\n', niter);
+
+if ~isempty(engine.filename)
+  fclose(engine.fid);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/find_mpe.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/find_mpe.m
new file mode 100644
index 00000000..73bd0abc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/find_mpe.m
@@ -0,0 +1,49 @@
+function mpe = find_mpe(engine, evidence, varargin)
+% FIND_MPE Find the most probable explanation of the data  (belprop)
+% function mpe = find_mpe(engine, evidence,...)
+%
+% evidence{i} = [] if X(i) is hidden, and otherwise contains its observed value (scalar or column vector).
+%
+% This finds the marginally most likely value for each hidden node,
+% and may give the wrong results even if the graph is acyclic,
+% unless you set break_ties = 1.
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% break_ties is optional. If 1, we will force ties to be broken consistently
+%  by calling enter_evidence N times. (see Jensen96, p106) Default = 1.
+
+break_ties = 1;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'break_ties',    break_ties = args{i+1}; 
+   otherwise,  
+    error(['invalid argument name ' args{i}]);       
+  end
+end
+
+engine = enter_evidence(engine, evidence, 'maximize', 1);
+
+observed = ~isemptycell(evidence);
+evidence = evidence(:); % hack to handle unrolled DBNs
+N = length(evidence);
+mpe = cell(1,N);
+for i=1:N
+  m = marginal_nodes(engine, i);
+  % observed nodes are all set to 1 inside the inference engine, so we must undo this
+  if observed(i)
+    mpe{i} = evidence{i};
+  else
+    mpe{i} = argmax(m.T);
+    if break_ties
+      evidence{i} = mpe{i};                             
+      [engine, ll] = enter_evidence(engine, evidence, 'maximize', 1);  
+    end
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/loopy_converged.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/loopy_converged.m
new file mode 100644
index 00000000..fba4f2fd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/loopy_converged.m
@@ -0,0 +1,13 @@
+function niter = loopy_converged(engine)
+% LOOPY_CONVERGED Did loopy belief propagation converge? 0 means no, eles we return the num. iterations.
+% function niter = loopy_converged(engine)
+%
+% We use a simple heuristic: we say convergence occurred if the number of iterations
+% used was less than the maximum allowed.
+
+if engine.niter == engine.max_iter
+  niter = 0;
+else
+  niter = engine.niter;
+end
+%conv = (strcmp(engine.protocol, 'tree') | (engine.niter < engine.max_iter));
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/marginal_family.m
new file mode 100644
index 00000000..afe404a8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/marginal_family.m
@@ -0,0 +1,6 @@
+function [marginal, pot] = marginal_family(engine, query)
+% MARGINAL_NODES Compute the marginal on the family of the specified query node (belprop)
+% [marginal, pot] = marginal_family(engine, query)
+
+pot = engine.marginal_domains{query};
+marginal = pot_to_marginal(pot);
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..0c2b5d94
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/marginal_nodes.m
@@ -0,0 +1,14 @@
+function [marginal, pot] = marginal_nodes(engine, query)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (belprop)
+% [marginal, pot] = marginal_nodes(engine, query)
+%
+% query must be a subset of a family
+
+if isempty(query)
+  big_pot = engine.marginal_domains{1}; % pick an arbitrary domain
+else
+  big_pot = engine.marginal_domains{query(end)};   
+end
+pot = marginalize_pot(big_pot, query);
+marginal = pot_to_marginal(pot);
+ 
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/CVS/Entries
new file mode 100644
index 00000000..938d9867
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/CVS/Entries
@@ -0,0 +1,4 @@
+/junk/1.1.1.1/Wed May 29 15:59:56 2002//
+/parallel_protocol.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/tree_protocol.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/CVS/Repository
new file mode 100644
index 00000000..9681913e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@belprop_inf_engine/private
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/junk b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/junk
new file mode 100644
index 00000000..11438db0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/junk
@@ -0,0 +1,68 @@
+fgraph
+fgraph%fgraph%fgraph%fgraph%fgraph%fgraph%fgraph%fgraph%fgraph%fgraph%fgraph%fgraph
+fgraph
+fgraphffgraphufgraphnfgraphcfgraphtfgraphifgraphofgraphnfgraph fgraph[fgraphbfgraphefgraphlfgraph,fgraph fgraphifgraphtfgraphefgraphrfgraph]fgraph fgraph=fgraph fgraphpfgraphafgraphrfgraphafgraphlfgraphlfgraphefgraphlfgraph_fgraphpfgraphrfgraphofgraphtfgraphofgraphcfgraphofgraphlfgraph(fgraphefgraphnfgraphgfgraphifgraphnfgraphefgraph,fgraph fgraphefgraphvfgraphifgraphdfgraphefgraphnfgraphcfgraphefgraph,fgraph fgraphpfgraphofgraphtfgraph_fgraphtfgraphyfgraphpfgraphefgraph,fgraph fgraphlfgraphofgraphcfgraphafgraphlfgraph_fgraphkfgraphefgraphrfgraphnfgraphefgraphlfgraph,fgraph fgraphmfgraphsfgraphgfgraph)fgraph
+fgraph
+fgraphdfgraphofgraphmfgraphsfgraph fgraph=fgraph fgraphefgraphnfgraphgfgraphifgraphnfgraphefgraph.fgraphffgraphgfgraphrfgraphafgraphpfgraphhfgraph.fgraphdfgraphofgraphmfgraphsfgraph;fgraph
+fgraphnfgraphdfgraphofgraphmfgraphsfgraph fgraph=fgraph fgraphlfgraphefgraphnfgraphgfgraphtfgraphhfgraph(fgraphdfgraphofgraphmfgraphsfgraph)fgraph;fgraph
+fgraphnfgraphsfgraph fgraph=fgraph fgraphefgraphnfgraphgfgraphifgraphnfgraphefgraph.fgraphffgraphgfgraphrfgraphafgraphpfgraphhfgraph.fgraphnfgraphofgraphdfgraphefgraph_fgraphsfgraphifgraphzfgraphefgraphsfgraph;fgraph
+fgraphofgraphnfgraphofgraphdfgraphefgraphsfgraph fgraph=fgraph fgraphffgraphifgraphnfgraphdfgraph(fgraph~fgraphifgraphsfgraphefgraphmfgraphpfgraphtfgraphyfgraphcfgraphefgraphlfgraphlfgraph(fgraphefgraphvfgraphifgraphdfgraphefgraphnfgraphcfgraphefgraph)fgraph)fgraph;fgraph
+fgraphcfgraphnfgraphofgraphdfgraphefgraphsfgraph fgraph=fgraph fgraphefgraphnfgraphgfgraphifgraphnfgraphefgraph.fgraphffgraphgfgraphrfgraphafgraphpfgraphhfgraph.fgraphcfgraphnfgraphofgraphdfgraphefgraphsfgraph;fgraph
+fgraph
+fgraphpfgraphrfgraphofgraphdfgraph_fgraphofgraphffgraph_fgraphmfgraphsfgraphgfgraph fgraph=fgraph fgraphcfgraphefgraphlfgraphlfgraph(fgraph1fgraph,fgraph fgraphnfgraphdfgraphofgraphmfgraphsfgraph)fgraph;fgraph
+fgraphbfgraphefgraphlfgraph fgraph=fgraph fgraphcfgraphefgraphlfgraphlfgraph(fgraph1fgraph,fgraph fgraphnfgraphdfgraphofgraphmfgraphsfgraph)fgraph;fgraph
+fgraphofgraphlfgraphdfgraph_fgraphbfgraphefgraphlfgraph fgraph=fgraph fgraphcfgraphefgraphlfgraphlfgraph(fgraph1fgraph,fgraph fgraphnfgraphdfgraphofgraphmfgraphsfgraph)fgraph;fgraph
+fgraph
+fgraphcfgraphofgraphnfgraphvfgraphefgraphrfgraphgfgraphefgraphdfgraph fgraph=fgraph fgraph0fgraph;fgraph
+fgraphifgraphtfgraphefgraphrfgraph fgraph=fgraph fgraph1fgraph;fgraph
+fgraphwfgraphhfgraphifgraphlfgraphefgraph fgraph~fgraphcfgraphofgraphnfgraphvfgraphefgraphrfgraphgfgraphefgraphdfgraph fgraph&fgraph fgraph(fgraphifgraphtfgraphefgraphrfgraph fgraph<fgraph=fgraph fgraphefgraphnfgraphgfgraphifgraphnfgraphefgraph.fgraphmfgraphafgraphxfgraph_fgraphifgraphtfgraphefgraphrfgraph)fgraph
+fgraph fgraph fgraph
+fgraph fgraph fgraph%fgraph fgraphefgraphafgraphcfgraphhfgraph fgraphnfgraphofgraphdfgraphefgraph fgraphmfgraphufgraphlfgraphtfgraphifgraphpfgraphlfgraphifgraphefgraphsfgraph fgraphafgraphlfgraphlfgraph fgraphifgraphtfgraphsfgraph fgraphifgraphnfgraphcfgraphofgraphmfgraphifgraphnfgraphgfgraph fgraphmfgraphsfgraphgfgraphsfgraph fgraphafgraphnfgraphdfgraph fgraphcfgraphofgraphmfgraphpfgraphufgraphtfgraphefgraphsfgraph fgraphifgraphtfgraphsfgraph fgraphlfgraphofgraphcfgraphafgraphlfgraph fgraphbfgraphefgraphlfgraphifgraphefgraphffgraph
+fgraph fgraph fgraphofgraphlfgraphdfgraph_fgraphbfgraphefgraphlfgraph fgraph=fgraph fgraphbfgraphefgraphlfgraph;fgraph
+fgraph fgraph fgraphffgraphofgraphrfgraph fgraphifgraph=fgraph1fgraph:fgraphnfgraphdfgraphofgraphmfgraphsfgraph
+fgraph fgraph fgraph fgraph fgraphpfgraphrfgraphofgraphdfgraph_fgraphofgraphffgraph_fgraphmfgraphsfgraphgfgraph{fgraphifgraph}fgraph fgraph=fgraph fgraphmfgraphkfgraph_fgraphifgraphnfgraphifgraphtfgraphifgraphafgraphlfgraph_fgraphpfgraphofgraphtfgraph(fgraphpfgraphofgraphtfgraph_fgraphtfgraphyfgraphpfgraphefgraph,fgraph fgraphdfgraphofgraphmfgraphsfgraph{fgraphifgraph}fgraph,fgraph fgraphnfgraphsfgraph,fgraph fgraphcfgraphnfgraphofgraphdfgraphefgraphsfgraph,fgraph fgraphofgraphnfgraphofgraphdfgraphefgraphsfgraph)fgraph;fgraph
+fgraph fgraph fgraph fgraph fgraphnfgraphbfgraphrfgraphsfgraph fgraph=fgraph fgraphefgraphnfgraphgfgraphifgraphnfgraphefgraph.fgraphffgraphgfgraphrfgraphafgraphpfgraphhfgraph.fgraphnfgraphbfgraphrfgraphsfgraph{fgraphifgraph}fgraph;fgraph
+fgraph fgraph fgraph fgraph fgraphffgraphofgraphrfgraph fgraphjfgraph=fgraphnfgraphbfgraphrfgraphsfgraph(fgraph:fgraph)fgraph'fgraph
+fgraph fgraph fgraph fgraph fgraph fgraph fgraphpfgraphrfgraphofgraphdfgraph_fgraphofgraphffgraph_fgraphmfgraphsfgraphgfgraph{fgraphifgraph}fgraph fgraph=fgraph fgraphmfgraphufgraphlfgraphtfgraphifgraphpfgraphlfgraphyfgraph_fgraphbfgraphyfgraph_fgraphpfgraphofgraphtfgraph(fgraphpfgraphrfgraphofgraphdfgraph_fgraphofgraphffgraph_fgraphmfgraphsfgraphgfgraph{fgraphifgraph}fgraph,fgraph fgraphmfgraphsfgraphgfgraph{fgraphjfgraph,fgraphifgraph}fgraph)fgraph;fgraph
+fgraph fgraph fgraph fgraph fgraphefgraphnfgraphdfgraph
+fgraph fgraph fgraph fgraph fgraphbfgraphefgraphlfgraph{fgraphifgraph}fgraph fgraph=fgraph fgraphnfgraphofgraphrfgraphmfgraphafgraphlfgraphifgraphzfgraphefgraph_fgraphpfgraphofgraphtfgraph(fgraphmfgraphufgraphlfgraphtfgraphifgraphpfgraphlfgraphyfgraph_fgraphpfgraphofgraphtfgraphsfgraph(fgraphpfgraphrfgraphofgraphdfgraph_fgraphofgraphffgraph_fgraphmfgraphsfgraphgfgraph{fgraphifgraph}fgraph,fgraph fgraphlfgraphofgraphcfgraphafgraphlfgraph_fgraphkfgraphefgraphrfgraphnfgraphefgraphlfgraph{fgraphifgraph}fgraph)fgraph)fgraph;fgraph
+fgraph fgraph fgraphefgraphnfgraphdfgraph
+fgraph
+fgraph fgraph fgraph%fgraph fgraphcfgraphofgraphnfgraphvfgraphefgraphrfgraphgfgraphefgraphdfgraph?fgraph
+fgraph fgraph fgraphifgraphffgraph fgraphifgraphtfgraphefgraphrfgraph=fgraph=fgraph1fgraph
+fgraph fgraph fgraph fgraph fgraphcfgraphofgraphnfgraphvfgraphefgraphrfgraphgfgraphefgraphdfgraph fgraph=fgraph fgraph0fgraph;fgraph
+fgraph fgraph fgraphefgraphlfgraphsfgraphefgraph
+fgraph fgraph fgraph fgraph fgraphcfgraphofgraphnfgraphvfgraphefgraphrfgraphgfgraphefgraphdfgraph fgraph=fgraph fgraph1fgraph;fgraph
+fgraph fgraph fgraph fgraph fgraphffgraphofgraphrfgraph fgraphifgraph=fgraph1fgraph:fgraphnfgraphdfgraphofgraphmfgraphsfgraph
+fgraph fgraph fgraph fgraph fgraph fgraph fgraphifgraphffgraph fgraph~fgraphafgraphpfgraphpfgraphrfgraphofgraphxfgraphefgraphqfgraph_fgraphpfgraphofgraphtfgraph(fgraphbfgraphefgraphlfgraph{fgraphifgraph}fgraph,fgraph fgraphofgraphlfgraphdfgraph_fgraphbfgraphefgraphlfgraph{fgraphifgraph}fgraph,fgraph fgraphefgraphnfgraphgfgraphifgraphnfgraphefgraph.fgraphtfgraphofgraphlfgraph)fgraph
+fgraph	fgraphcfgraphofgraphnfgraphvfgraphefgraphrfgraphgfgraphefgraphdfgraph fgraph=fgraph fgraph0fgraph;fgraph
+fgraph	fgraphbfgraphrfgraphefgraphafgraphkfgraph;fgraph
+fgraph fgraph fgraph fgraph fgraph fgraph fgraphefgraphnfgraphdfgraph
+fgraph fgraph fgraph fgraph fgraphefgraphnfgraphdfgraph
+fgraph fgraph fgraphefgraphnfgraphdfgraph
+fgraph
+fgraph fgraph fgraphifgraphffgraph fgraph~fgraphcfgraphofgraphnfgraphvfgraphefgraphrfgraphgfgraphefgraphdfgraph
+fgraph fgraph fgraph fgraph fgraphofgraphlfgraphdfgraph_fgraphmfgraphsfgraphgfgraph fgraph=fgraph fgraphmfgraphsfgraphgfgraph;fgraph
+fgraph fgraph fgraph fgraph fgraph%fgraph fgraphefgraphafgraphcfgraphhfgraph fgraphnfgraphofgraphdfgraphefgraph fgraphsfgraphefgraphnfgraphdfgraphsfgraph fgraphafgraph fgraphmfgraphsfgraphgfgraph fgraphtfgraphofgraph fgraphefgraphafgraphcfgraphhfgraph fgraphofgraphffgraph fgraphifgraphtfgraphsfgraph fgraphnfgraphefgraphifgraphgfgraphhfgraphbfgraphofgraphrfgraphsfgraph
+fgraph fgraph fgraph fgraph fgraphffgraphofgraphrfgraph fgraphifgraph=fgraph1fgraph:fgraphnfgraphdfgraphofgraphmfgraphsfgraph
+fgraph fgraph fgraph fgraph fgraph fgraph fgraphnfgraphbfgraphrfgraphsfgraph fgraph=fgraph fgraphefgraphnfgraphgfgraphifgraphnfgraphefgraph.fgraphffgraphgfgraphrfgraphafgraphpfgraphhfgraph.fgraphnfgraphbfgraphrfgraphsfgraph{fgraphifgraph}fgraph;fgraph
+fgraph fgraph fgraph fgraph fgraph fgraph fgraphffgraphofgraphrfgraph fgraphjfgraph=fgraphnfgraphbfgraphrfgraphsfgraph(fgraph:fgraph)fgraph'fgraph
+fgraph	fgraph%fgraph fgraphmfgraphufgraphlfgraphtfgraphifgraphpfgraphlfgraphyfgraph fgraphafgraphlfgraphlfgraph fgraphifgraphnfgraphcfgraphofgraphmfgraphifgraphnfgraphgfgraph fgraphmfgraphsfgraphgfgraphsfgraph fgraphefgraphxfgraphcfgraphefgraphpfgraphtfgraph fgraphffgraphrfgraphofgraphmfgraph fgraphjfgraph
+fgraph	fgraphtfgraphefgraphmfgraphpfgraph fgraph=fgraph fgraphpfgraphrfgraphofgraphdfgraph_fgraphofgraphffgraph_fgraphmfgraphsfgraphgfgraph{fgraphifgraph}fgraph;fgraph
+fgraph	fgraphtfgraphefgraphmfgraphpfgraph fgraph=fgraph fgraphdfgraphifgraphvfgraphifgraphdfgraphefgraph_fgraphbfgraphyfgraph_fgraphpfgraphofgraphtfgraph(fgraphtfgraphefgraphmfgraphpfgraph,fgraph fgraphofgraphlfgraphdfgraph_fgraphmfgraphsfgraphgfgraph{fgraphjfgraph,fgraphifgraph}fgraph)fgraph;fgraph
+fgraph	fgraph%fgraph fgraphsfgraphefgraphnfgraphdfgraph fgraphmfgraphsfgraphgfgraph fgraphffgraphrfgraphofgraphmfgraph fgraphifgraph fgraphtfgraphofgraph fgraphjfgraph
+fgraph	fgraphtfgraphefgraphmfgraphpfgraph fgraph=fgraph fgraphmfgraphufgraphlfgraphtfgraphifgraphpfgraphlfgraphyfgraph_fgraphbfgraphyfgraph_fgraphpfgraphofgraphtfgraph(fgraphtfgraphefgraphmfgraphpfgraph,fgraph fgraphlfgraphofgraphcfgraphafgraphlfgraph_fgraphkfgraphefgraphrfgraphnfgraphefgraphlfgraph{fgraphifgraph}fgraph)fgraph;fgraph
+fgraph	fgraphifgraphffgraph fgraphefgraphnfgraphgfgraphifgraphnfgraphefgraph.fgraphmfgraphafgraphxfgraphifgraphmfgraphifgraphzfgraphefgraph
+fgraph	fgraph fgraph fgraphtfgraphefgraphmfgraphpfgraph2fgraph fgraph=fgraph fgraphmfgraphafgraphrfgraphgfgraphifgraphnfgraphafgraphlfgraphifgraphzfgraphefgraph_fgraphpfgraphofgraphtfgraph_fgraphmfgraphafgraphxfgraph(fgraphtfgraphefgraphmfgraphpfgraph,fgraph fgraphefgraphnfgraphgfgraphifgraphnfgraphefgraph.fgraphffgraphgfgraphrfgraphafgraphpfgraphhfgraph.fgraphsfgraphefgraphpfgraphsfgraphefgraphtfgraph{fgraphifgraph,fgraphjfgraph}fgraph)fgraph;fgraph
+fgraph	fgraphefgraphlfgraphsfgraphefgraph
+fgraph	fgraph fgraph fgraphtfgraphefgraphmfgraphpfgraph2fgraph fgraph=fgraph fgraphmfgraphafgraphrfgraphgfgraphifgraphnfgraphafgraphlfgraphifgraphzfgraphefgraph_fgraphpfgraphofgraphtfgraph(fgraphtfgraphefgraphmfgraphpfgraph,fgraph fgraphefgraphnfgraphgfgraphifgraphnfgraphefgraph.fgraphffgraphgfgraphrfgraphafgraphpfgraphhfgraph.fgraphsfgraphefgraphpfgraphsfgraphefgraphtfgraph{fgraphifgraph,fgraphjfgraph}fgraph)fgraph;fgraph
+fgraph	fgraphefgraphnfgraphdfgraph
+fgraph	fgraphmfgraphsfgraphgfgraph{fgraphifgraph,fgraphjfgraph}fgraph fgraph=fgraph fgraphnfgraphofgraphrfgraphmfgraphafgraphlfgraphifgraphzfgraphefgraph_fgraphpfgraphofgraphtfgraph(fgraphtfgraphefgraphmfgraphpfgraph2fgraph)fgraph;fgraph
+fgraph fgraph fgraph fgraph fgraph fgraph fgraphefgraphnfgraphdfgraph
+fgraph fgraph fgraph fgraph fgraphefgraphnfgraphdfgraph
+fgraph fgraph fgraphefgraphnfgraphdfgraph
+fgraph
+fgraph fgraph fgraphifgraphtfgraphefgraphrfgraph fgraph=fgraph fgraphifgraphtfgraphefgraphrfgraph fgraph+fgraph fgraph1fgraph;fgraph
+fgraphefgraphnfgraphdfgraph
+fgraph
+gdl
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/parallel_protocol.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/parallel_protocol.m
new file mode 100644
index 00000000..3e702f7b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/parallel_protocol.m
@@ -0,0 +1,86 @@
+function [bel, niter] = parallel_protocol(engine, evidence, pot_type, local_kernel, msg)
+
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes;
+onodes = find(~isemptycell(evidence));
+
+ndoms = length(engine.gdl.doms);
+prod_of_msg = cell(1, ndoms);
+bel = cell(1, ndoms);
+old_bel = cell(1, ndoms);
+
+converged = 0;
+iter = 1;
+while ~converged && (iter <= engine.max_iter)
+  
+  % each node multiplies all its incoming msgs and computes its local belief
+  old_bel = bel;
+  for i=1:ndoms
+    prod_of_msg{i} = mk_initial_pot(pot_type, engine.gdl.doms{i}, ns, bnet.cnodes, onodes);
+    nbrs = engine.gdl.nbrs{i};
+    for j=nbrs(:)'
+      prod_of_msg{i} = multiply_by_pot(prod_of_msg{i}, msg{j,i});
+    end
+    bel{i} = normalize_pot(multiply_by_pot(local_kernel{i}, prod_of_msg{i}));
+  end
+
+  if ~isempty(engine.fid)
+    for i=1:ndoms
+      tmp = pot_to_marginal(bel{i});
+      %fprintf(engine.fid, '%9.7f ', tmp.T(1));
+      fprintf(engine.fid, '%9.7f ', tmp.U(1));
+    end
+    %fprintf(engine.fid, '  U ');
+    %for i=1:ndoms
+    %  tmp = pot_to_marginal(bel{i});
+    %  fprintf(engine.fid, '%9.7f ', tmp.U(1));
+    %end
+    fprintf(engine.fid, '\n');
+  end
+
+  % converged?
+  if iter==1
+    converged = 0;
+  else
+    converged = 1;
+    for i=1:ndoms
+      if ~approxeq_pot(bel{i}, old_bel{i}, engine.tol)
+	converged = 0;
+	break;
+      end
+    end
+  end
+
+  if ~converged
+    old_msg = msg;
+    % each node sends a msg to each of its neighbors
+    for i=1:ndoms
+      nbrs = engine.gdl.nbrs{i};
+      for j=nbrs(:)'
+	% multiply all incoming msgs except from j
+	temp = prod_of_msg{i};
+	temp = divide_by_pot(temp, old_msg{j,i});
+	% send msg from i to j
+	temp = multiply_by_pot(temp, local_kernel{i});
+	temp2 = marginalize_pot(temp, engine.gdl.sepset{i,j}, engine.maximize);
+	msg{i,j} = normalize_pot(temp2);
+      end
+    end
+  end
+
+  iter = iter + 1;
+end
+
+
+niter = iter-1;
+
+if 0
+for i=1:ndoms
+  prod_of_msg{i} = mk_initial_pot(pot_type, engine.gdl.doms{i}, ns, bnet.cnodes, onodes);
+  nbrs = engine.gdl.nbrs{i};
+  for j=nbrs(:)'
+    prod_of_msg{i} = multiply_by_pot(prod_of_msg{i}, msg{j,i});
+  end
+  bel{i} = normalize_pot(multiply_by_pot(local_kernel{i}, prod_of_msg{i}));
+end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/tree_protocol.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/tree_protocol.m
new file mode 100644
index 00000000..940e74ae
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_inf_engine/private/tree_protocol.m
@@ -0,0 +1,48 @@
+function bel = tree_protocol(engine, evidence, pot_type, local_kernel, msg)
+
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes;
+onodes = find(~isemptycell(evidence));
+
+ndoms = length(engine.gdl.doms);
+prod_of_msg = cell(1, ndoms);
+bel = cell(1, ndoms);
+  
+% collect to root (node to parents)
+for n=engine.postorder
+  % absorb msgs from children
+  prod_of_msg{n} = mk_initial_pot(pot_type, engine.gdl.doms{n}, ns, bnet.cnodes, onodes);
+  for c=children(engine.tree, n)
+    prod_of_msg{n} = multiply_by_pot(prod_of_msg{n}, msg{c,n});
+  end
+  % send msg to parents
+  for p=parents(engine.tree, n)
+    if iter==1
+      temp = prod_of_msg{n};
+    else
+      temp = divide_by_pot(prod_of_msg{n}, old_msg{p,n});
+    end
+    temp = multiply_by_pot(temp, local_kernel{n});
+    temp2 = marginalize_pot(temp, engine.gdl.sepset{n,p}, engine.maximize);
+    %fprintf('%d sends %d\n', n, p);
+    msg{n,p} = normalize_pot(temp2);
+  end
+end
+
+% distribute from root (node to children)
+for n=engine.preorder
+  % absorb from parents
+  %prod_of_msg{n} = mk_initial_pot(pot_type, doms{n}, ns, cnodes, onodes);
+  for p=parents(engine.tree, n)
+    prod_of_msg{n} = multiply_by_pot(prod_of_msg{n}, msg{p,n});
+  end
+  bel{n} = normalize_pot(multiply_pots(prod_of_msg{n}, local_kernel{n}));
+  % send msg to children
+  for c=children(engine.tree, n)
+    temp = divide_by_pot(prod_of_msg{n}, msg{c,n});
+    temp = multiply_by_pot(temp, local_kernel{n});
+    temp2 = marginalize_pot(temp, engine.gdl.sepset{n,c}, engine.maximize);
+    %fprintf('%d sends %d\n', n, c);
+    msg{n,c} = normalize_pot(temp2);
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/CVS/Entries
new file mode 100644
index 00000000..a2b559af
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/CVS/Entries
@@ -0,0 +1,7 @@
+/belprop_mrf2_inf_engine.m/1.1.1.1/Fri Jan  3 22:01:56 2003//
+/bp_mrf2.m/1.1.1.1/Mon Jan  5 01:23:34 2004//
+/enter_soft_evidence.m/1.1.1.1/Thu Jan  2 17:29:54 2003//
+/find_mpe.m/1.1.1.1/Thu Jan  2 17:49:18 2003//
+/marginal_nodes.m/1.1.1.1/Tue Dec 31 21:24:30 2002//
+/set_params.m/1.1.1.1/Thu Jan  2 17:28:56 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/CVS/Repository
new file mode 100644
index 00000000..fe4612c3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@belprop_mrf2_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/belprop_mrf2_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/belprop_mrf2_inf_engine.m
new file mode 100644
index 00000000..f7e9d695
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/belprop_mrf2_inf_engine.m
@@ -0,0 +1,46 @@
+function engine = belprop_mrf2_inf_engine(mrf2, varargin) 
+% BELPROP_MRF2_INF_ENGINE Belief propagation for MRFs with discrete pairwise potentials
+% engine = belprop_mrf2_inf_engine(mrf2, ...)
+%
+% This is like belprop_inf_engine, except it is designed for mrf2, so is much faster.
+%
+% [ ... ] = belprop_mrf2_inf_engine(..., 'param1',val1, 'param2',val2, ...)
+% allows you to specify optional parameters as name/value pairs.
+% Parameters modifying behavior of enter_evidence are below [default value in brackets]
+%
+% max_iter - max. num. iterations [ 5*nnodes]
+% momentum - weight assigned to old message in convex combination
+%            (useful for damping oscillations) [0]
+% tol      - tolerance used to assess convergence [1e-3]
+% verbose - 1 means print error at every iteration [0]
+%
+% Parameters can be changed later using set_params 
+
+
+% The advantages of pairwise potentials are
+% (1) we can compute messages using vector-matrix multiplication
+% (2) we can easily specify the parameters: one potential per edge
+% In contrast, potentials on larger cliques are more complicated to deal with.
+
+
+nnodes = length(mrf2.adj_mat);
+
+[engine.max_iter, engine.momentum, engine.tol, engine.verbose] = ...
+    process_options(varargin, 'max_iter', [], 'momentum', 0, 'tol', 1e-3, ...
+		   'verbose', 0);
+
+if isempty(engine.max_iter) % no user supplied value, so compute default
+  engine.max_iter = 5*nnodes;
+  %if acyclic(mrf2.adj_mat, 0) --- can be very slow!
+  %  engine.max_iter = nnodes;
+  %else
+  %  engine.max_iter = 5*nnodes;
+  %end
+end
+
+engine.bel = cell(1, nnodes); % store results of enter_evidence here
+engine.mrf2 = mrf2;
+
+engine = class(engine, 'belprop_mrf2_inf_engine');
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/bp_mrf2.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/bp_mrf2.m
new file mode 100644
index 00000000..90baaba1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/bp_mrf2.m
@@ -0,0 +1,209 @@
+function [new_bel, niter, new_msg, edge_id, nstates] = bp_mrf2_general(adj_mat, pot, local_evidence, varargin)
+% BP_MRF2_GENERAL Belief propagation on an MRF with pairwise potentials
+% function [bel, niter] = bp_mrf2_general(adj_mat, pot, local_evidence, varargin)
+%
+% Input:
+% adj_mat(i,j) = 1 iff there is an edge between nodes i and j
+% pot(ki,kj,i,j) or pot{i,j}(ki,kj) = potential on edge between nodes i,j
+%   If the potentials on all edges are the same,
+%   you can just pass in 1 array, pot(ki,kj)
+% local_evidence(state, node) or local_evidence{i}(k) = Pr(observation at node i | Xi=k)
+%
+% Use cell arrays if the hidden nodes do not all have the same number of values.
+%
+% Output:
+% bel(k,i) or bel{i}(k) = P(Xi=k|evidence)
+% niter contains the number of iterations used 
+%
+% [ ... ] = bp_mrf2(..., 'param1',val1, 'param2',val2, ...)
+% allows you to specify optional parameters as name/value pairs.
+% Parameters names are below [default value in brackets]
+%
+% max_iter - max. num. iterations [ 5*nnodes]
+% momentum - weight assigned to old message in convex combination
+%            (useful for damping oscillations) - currently ignored i[0]
+% tol      - tolerance used to assess convergence [1e-3]
+% maximize - 1 means use max-product, 0 means use sum-product [0]
+% verbose - 1 means print error at every iteration [0]
+%
+% fn - name of function to call at end of every iteration [ [] ]
+% fnargs - we call feval(fn, bel, iter, fnargs{:}) [ [] ]
+
+nnodes = length(adj_mat);
+
+[max_iter, momentum, tol, maximize, verbose, fn, fnargs] = ...
+    process_options(varargin, 'max_iter', 5*nnodes, 'momentum', 0, ...
+		    'tol', 1e-3, 'maximize', 0, 'verbose', 0, ...
+		    'fn', [], 'fnargs', []);
+
+if iscell(local_evidence)
+  use_cell = 1;
+else
+  use_cell = 0;
+  [nstates nnodes] = size(local_evidence);
+end
+
+if iscell(pot)
+  tied_pot = 0;
+else
+  tied_pot = (ndims(pot)==2);
+end
+
+
+% give each edge a unique number
+ndx = find(adj_mat);
+nedges = length(ndx);
+edge_id = zeros(1, nnodes*nnodes);
+edge_id(ndx) = 1:nedges; 
+edge_id = reshape(edge_id, nnodes, nnodes);
+
+% initialise messages
+if use_cell
+  prod_of_msgs = cell(1, nnodes);
+  old_bel = cell(1, nnodes);
+  nstates = zeros(1, nnodes);
+  old_msg = cell(1, nedges);
+  for i=1:nnodes
+    nstates(i) = length(local_evidence{i});
+    prod_of_msgs{i} = local_evidence{i};
+    old_bel{i} = local_evidence{i};
+  end
+  for i=1:nnodes
+    nbrs = find(adj_mat(:,i));
+    for j=nbrs(:)'
+      old_msg{edge_id(i,j)} = normalise(ones(nstates(j),1));
+    end
+  end
+else
+  prod_of_msgs = local_evidence;
+  old_bel = local_evidence;
+  %old_msg = zeros(nstates, nnodes, nnodes); 
+  old_msg = zeros(nstates, nedges); 
+  m = normalise(ones(nstates,1));
+  for i=1:nnodes
+    nbrs = find(adj_mat(:,i));
+    for j=nbrs(:)'
+      old_msg(:, edge_id(i,j)) = m;
+      %old_msg(:,i,j) = m;
+    end
+  end
+end
+
+
+converged = 0;
+iter = 1;
+
+while ~converged & (iter <= max_iter)
+  
+  % each node sends a msg to each of its neighbors
+  for i=1:nnodes
+    nbrs = find(adj_mat(i,:));
+    for j=nbrs(:)'
+      if tied_pot
+	pot_ij = pot;
+      else
+	if iscell(pot)
+	  pot_ij = pot{i,j};
+	else
+	  pot_ij = pot(:,:,i,j);
+	end
+      end
+      pot_ij = pot_ij'; % now pot_ij(xj, xi) 
+      % so pot_ij * msg(xi) = sum_xi pot(xj,xi) msg(xi) = f(xj)
+
+      if 1
+	% Compute temp = product of all incoming msgs except from j
+	% by dividing out old msg from j from the product of all msgs sent to i
+	if use_cell
+	  temp = prod_of_msgs{i};
+	  m = old_msg{edge_id(j,i)};
+	else
+	  temp = prod_of_msgs(:,i);
+	  m = old_msg(:, edge_id(j,i));
+	end
+	if any(m==0)
+	  fprintf('iter=%d, send from i=%d to j=%d\n', iter, i, j);
+	  keyboard
+	end
+	m = m + (m==0); % valid since m(k)=0 => temp(k)=0, so can replace 0's with anything
+	temp = temp ./ m;
+	temp_div = temp;
+      end
+      
+      if 1
+	% Compute temp = product of all incoming msgs except from j in obvious way
+	if use_cell
+	  %temp = ones(nstates(i),1);
+	  temp = local_evidence{i};
+	  for k=nbrs(:)'
+	    if k==j, continue, end;
+	    temp = temp .* old_msg{edge_id(k,i)};
+	  end
+	else
+	  %temp = ones(nstates,1);
+	  temp = local_evidence(:,i);
+	  for k=nbrs(:)'
+	    if k==j, continue, end;
+	    temp = temp .* old_msg(:, edge_id(k,i));
+	  end
+	end
+      end
+      %assert(approxeq(temp, temp_div))
+      assert(approxeq(normalise(pot_ij * temp), normalise(pot_ij * temp_div)))
+	
+      if maximize
+	newm = max_mult(pot_ij, temp); % bottleneck
+      else
+	newm = pot_ij * temp;
+      end
+      newm = normalise(newm);
+      if use_cell
+	new_msg{edge_id(i,j)} = newm;
+      else
+	new_msg(:, edge_id(i,j)) = newm;
+      end
+    end % for j 
+  end % for i
+  old_prod_of_msgs = prod_of_msgs;
+  
+  % each node multiplies all its incoming msgs and computes its local belief
+  if use_cell
+    for i=1:nnodes
+      nbrs = find(adj_mat(:,i));
+      prod_of_msgs{i} = local_evidence{i};
+      for j=nbrs(:)'
+	prod_of_msgs{i} = prod_of_msgs{i} .* new_msg{edge_id(j,i)};
+      end
+      new_bel{i} = normalise(prod_of_msgs{i});
+    end
+    err = abs(cat(1,new_bel{:}) - cat(1, old_bel{:}));
+  else
+    for i=1:nnodes
+      nbrs = find(adj_mat(:,i));
+      prod_of_msgs(:,i) = local_evidence(:,i);
+      for j=nbrs(:)'
+	prod_of_msgs(:,i) = prod_of_msgs(:,i) .* new_msg(:,edge_id(j,i));
+      end
+      new_bel(:,i) = normalise(prod_of_msgs(:,i));
+    end
+    err = abs(new_bel(:) - old_bel(:));
+  end
+  converged = all(err < tol);
+  if verbose, fprintf('error at iter %d = %f\n', iter, sum(err)); end
+  if ~isempty(fn)
+    if isempty(fnargs)
+      feval(fn, new_bel);
+    else
+      feval(fn, new_bel, iter, fnargs{:});
+    end
+  end
+  
+  iter = iter + 1;
+  old_msg = new_msg;
+  old_bel = new_bel;
+end % while
+
+niter = iter-1;
+
+fprintf('converged in %d iterations\n', niter);
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/enter_soft_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/enter_soft_evidence.m
new file mode 100644
index 00000000..032ca064
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/enter_soft_evidence.m
@@ -0,0 +1,15 @@
+function [engine, ll, niter] = enter_soft_evidence(engine, local_evidence)
+% ENTER_SOFT_EVIDENCE Propagate evidence using belief propagation
+% [engine, ll, niter] = enter_soft_evidence(engine, local_evidence)
+%
+% local_evidence{i}(j) = Pr(observation at node i | S(i)=j)
+%
+% The log-likelihood is not computed; ll = 0.
+% niter contains the number of iterations used 
+
+ll = 0;
+mrf2 = engine.mrf2;
+[bel, niter] = bp_mrf2(mrf2.adj_mat, mrf2.pot, local_evidence, ...
+		       'max_iter', engine.max_iter, 'momentum', engine.momentum, ...
+		       'tol', engine.tol, 'maximize', 0, 'verbose', engine.verbose);
+engine.bel = bel;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/find_mpe.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/find_mpe.m
new file mode 100644
index 00000000..fbd91265
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/find_mpe.m
@@ -0,0 +1,12 @@
+function mpe = find_mpe(engine, local_evidence)
+% FIND_MPE Find the most probable explanation of the data  
+% function mpe = find_mpe(engine, local_evidence
+%
+% local_evidence{i}(j) = Pr(observation at node i | S(i)=j)
+%
+% This finds the marginally most likely value for each hidden node.
+% It may give inconsistent results if there are ties.
+
+[mpe, niter] = bp_mpe_mrf2(engine.mrf2.adj_mat, engine.mrf2.pot, local_evidence, ...
+			   'max_iter', engine.max_iter, 'momentum', engine.momentum, ...
+			   'tol', engine.tol);
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..c51ed666
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/marginal_nodes.m
@@ -0,0 +1,10 @@
+function marginal = marginal_nodes(engine, query)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (belprop)
+% marginal = marginal_nodes(engine, query)
+%
+% query must be a single node
+
+if length(query)>1
+  error('can only handle single node marginals')
+end
+marginal = engine.bel{query};
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/set_params.m b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/set_params.m
new file mode 100644
index 00000000..f5328006
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@belprop_mrf2_inf_engine/set_params.m
@@ -0,0 +1,15 @@
+function engine = set_params(engine, varargin)
+% SET_PARAMS Modify parameters of the inference engine
+% engine = set_params(engine, 'param1',val1, 'param2',val2, ...)
+%
+% Parameter names are listed below.
+%
+% max_iter - max. num. iterations 
+% momentum - weight assigned to old message in convex combination
+%            (useful for damping oscillations) 
+% tol      - tolerance used to assess convergence
+% verbose - 1 means print error at every iteration [0]
+
+[engine.max_iter, engine.momentum, engine.tol, engine.verbose] = ...
+    process_options('max_iter', engine.max_iter, 'momentum', engine.momentum, ...
+		    'tol', engine.tol, 'verbose', engine.verbose);
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/CVS/Entries
new file mode 100644
index 00000000..a79c7562
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/CVS/Entries
@@ -0,0 +1,4 @@
+/cond_gauss_inf_engine.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_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/CVS/Repository
new file mode 100644
index 00000000..41961f94
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@cond_gauss_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/cond_gauss_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/cond_gauss_inf_engine.m
new file mode 100644
index 00000000..166ed4cd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/cond_gauss_inf_engine.m
@@ -0,0 +1,23 @@
+function engine = cond_gauss_inf_engine(bnet)
+% COND_GAUSS_INF_ENGINE Conditional Gaussian inference engine
+% engine = cond_gauss_inf_engine(bnet)
+%
+% Enumerates all the discrete roots, and runs jtree on the remaining Gaussian nodes.
+
+dnodes = mysetdiff(1:length(bnet.dag), bnet.cnodes);
+
+%onodes = dnodes; % all the discrete ndoes will be observed
+%engine.sub_engine = jtree_inf_engine(bnet, onodes);
+bnet2 = bnet;
+bnet2.observed = dnodes;
+engine.sub_engine = jtree_inf_engine(bnet2);
+
+% This is where we will store the results between enter_evidence and marginal_nodes
+engine.T = [];
+engine.mu = [];
+engine.Sigma = [];
+engine.joint_dmarginal = [];
+engine.onodes = []; % needed for marginal_nodes
+engine.evidence = []; % needed for marginal_nodes add_ev
+
+engine = class(engine, 'cond_gauss_inf_engine', inf_engine(bnet));
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..db5019b1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/enter_evidence.m
@@ -0,0 +1,57 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (cond_gauss)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i} = [] if if X(i) is hidden, and otherwise contains its observed value (scalar or column vector)
+
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes(:);
+observed = ~isemptycell(evidence);
+onodes = find(observed);
+hnodes = find(isemptycell(evidence));
+engine.evidence = evidence;
+
+% check there are no C->D links where C is hidden
+pot_type = determine_pot_type(bnet, onodes);
+
+dhid = myintersect(hnodes, bnet.dnodes);
+S = prod(ns(dhid));
+T = zeros(S,1);
+
+N = length(bnet.dag);
+mu = cell(1,N);
+Sigma = cell(1,N); 
+cobs = myintersect(bnet.cnodes, onodes);
+chid = myintersect(bnet.cnodes, hnodes);
+ens = ns;
+ens(cobs) = 0;
+for j=chid(:)'
+  mu{j} = zeros(ens(j), S);
+  Sigma{j} = zeros(ens(j), ens(j), S);
+end
+ 
+for i=1:S
+  dvals = ind2subv(ns(dhid), i);
+  evidence(dhid) = num2cell(dvals);
+  [sub_engine, loglik] = enter_evidence(engine.sub_engine, evidence);
+  for j=chid(:)'
+    m = marginal_nodes(sub_engine, j);
+    mu{j}(:,i) = m.mu;
+    Sigma{j}(:,:,i) = m.Sigma;
+  end
+  T(i) = exp(loglik);
+end
+
+[T, lik] = normalise(T);
+loglik = log(lik);
+
+engine.T = T;
+engine.mu = mu;
+engine.Sigma = Sigma;
+
+dnodes = bnet.dnodes;
+dobs = myintersect(dnodes, onodes);
+ens(dobs) = 1;
+engine.joint_dmarginal = dpot(dnodes, ens(dnodes), myreshape(engine.T, ens(dnodes)));
+
+engine.onodes = onodes;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..9c5d60a7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@cond_gauss_inf_engine/marginal_nodes.m
@@ -0,0 +1,36 @@
+function marginal = marginal_nodes(engine, query, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (cond_gauss)
+% marginal = marginal_nodes(engine, query, add_ev)
+%
+% 'query' must be a singleton set
+% 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, add_ev = 0; end
+
+if length(query) ~= 1
+  error('cond_gauss_inf_engine can only handle marginal queries on single nodes')
+end
+j = query;
+bnet = bnet_from_engine(engine);
+
+if myismember(j, bnet.cnodes)
+  if ~myismember(j, engine.onodes)
+    [m, C] = collapse_mog(engine.mu{j}, engine.Sigma{j}, engine.T);    
+    marginal.mu = m;
+    marginal.Sigma = C;
+    marginal.T = 1.0; % single mixture component
+  else
+    marginal.mu = engine.evidence{j};
+    k = bnet.node_sizes(j);
+    marginal.Sigma = zeros(k,k);
+    marginal.T = 1.0; % since P(E|E)=1
+  end
+else
+  marginal = pot_to_marginal(marginalize_pot(engine.joint_dmarginal, j));
+  if add_ev
+    marginal = add_ev_to_dmarginal(marginal, engine.evidence, bnet.node_sizes);
+  end
+end
+
+marginal.domain = query;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/CVS/Entries
new file mode 100644
index 00000000..e4399482
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/CVS/Entries
@@ -0,0 +1,4 @@
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/enumerative_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//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/CVS/Repository
new file mode 100644
index 00000000..ee8672a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@enumerative_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..eeb2193c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/enter_evidence.m
@@ -0,0 +1,10 @@
+function [engine, loglik] = enter_evidence(engine, evidence)
+% ENTER_EVIDENCE Add the specified evidence to the network (enumerative_inf)
+% [engine, loglik] = enter_evidence(engine, evidence)
+%
+% evidence{i} = [] if if X(i) is hidden, and otherwise contains its observed value (scalar or column vector)
+
+engine.evidence = evidence;
+if nargout == 2
+  [m, loglik] = marginal_nodes(engine, []);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/enumerative_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/enumerative_inf_engine.m
new file mode 100644
index 00000000..c31c64c9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/enumerative_inf_engine.m
@@ -0,0 +1,11 @@
+function engine = enumerative_inf_engine(bnet)
+% ENUMERATIVE_INF_ENGINE Inference engine for fully discrete BNs that uses exhaustive enumeration.
+% engine = enumerative_inf_engine(bnet)
+
+
+assert(isempty(bnet.cnodes));
+
+% This is where we store stuff between enter_evidence and marginal_nodes
+engine.evidence = [];
+
+engine = class(engine, 'enumerative_inf_engine', inf_engine(bnet));
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..1c31eae1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@enumerative_inf_engine/marginal_nodes.m
@@ -0,0 +1,41 @@
+function [marginal, loglik] = marginal_nodes(engine, query)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (enumerative_inf)
+% [marginal, loglik] = marginal_nodes(engine, query)
+
+
+if isempty(query) & nargout < 2
+  marginal.T = 1;
+  marginal.domain = [];
+  return;
+end
+
+evidence = engine.evidence;
+bnet = bnet_from_engine(engine);
+assert(isempty(bnet.cnodes));
+n = length(bnet.dag);
+observed = ~isemptycell(evidence);
+vals = cat(1,evidence{observed});
+vals = vals(:)';
+ns = bnet.node_sizes;
+
+sz = ns(query);
+T = 0*myones(sz);
+p = 0;
+for i=1:prod(ns)
+  inst = ind2subv(ns, i); % i'th instantiation
+  if isempty(vals) | inst(observed) == vals % agrees with evidence
+    prob = exp(log_lik_complete(bnet, num2cell(inst(:))));
+    p = p + prob;
+    v = inst(query);
+    j = subv2ind(sz, v);
+    T(j) = T(j) + prob;
+  end
+end
+
+[T, lik] = normalise(T);
+lik = p;
+loglik = log(lik);
+
+Tsmall = shrink_obs_dims_in_table(T, query, evidence);
+marginal.domain = query;
+marginal.T = Tsmall;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/CVS/Entries
new file mode 100644
index 00000000..16ace516
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/CVS/Entries
@@ -0,0 +1,4 @@
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/gaussian_inf_engine.m/1.1.1.1/Fri May 14 01:13:26 2004//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D/private////
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/CVS/Repository
new file mode 100644
index 00000000..26418ea5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@gaussian_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..c509a725
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/enter_evidence.m
@@ -0,0 +1,46 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (gaussian_inf_engine)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i} = [] if if X(i) is hidden, and otherwise contains its observed value (scalar or column vector)
+
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes;
+O = find(~isemptycell(evidence));
+H = find(isemptycell(evidence));
+vals = cat(1, evidence{O});
+
+% Compute Pr(H|o)
+[Hmu, HSigma, loglik] = condition_gaussian(engine.mu, engine.Sigma, H, O, vals(:), ns);
+
+engine.Hmu = Hmu;
+engine.HSigma = HSigma;
+engine.hnodes = H;
+
+%%%%%%%%
+
+function [mu2, Sigma2, loglik] = condition_gaussian(mu, Sigma, X, Y, y, ns)
+% CONDITION_GAUSSIAN Compute Pr(X|Y=y) where X and Y are jointly Gaussian.
+% [mu2, Sigma2, ll] = condition_gaussian(mu, Sigma, X, Y, y, ns)
+
+if isempty(y)
+  mu2 = mu;
+  Sigma2 = Sigma;
+  loglik = 0;
+  return;
+end
+
+use_log = 1;
+
+if length(Y)==length(mu) % instantiating every variable
+  mu2 = y;
+  Sigma2 = zeros(length(y));
+  loglik = gaussian_prob(y, mu, Sigma, use_log);
+  return;
+end
+
+[muX, muY, SXX, SXY, SYX, SYY] = partition_matrix_vec(mu, Sigma, X, Y, ns);
+K = SXY*inv(SYY);
+mu2 = muX + K*(y-muY);
+Sigma2 = SXX - K*SYX;
+loglik = gaussian_prob(y, muY, SYY, use_log);
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/gaussian_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/gaussian_inf_engine.m
new file mode 100644
index 00000000..3e34c166
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/gaussian_inf_engine.m
@@ -0,0 +1,25 @@
+function engine = gaussian_inf_engine(bnet)
+% GAUSSIAN_INF_ENGINE Computes the joint multivariate Gaussian corresponding to the bnet
+% engine = gaussian_inf_engine(bnet)
+%
+% For details on how to compute the joint Gaussian from the bnet, see
+% - "Gaussian Influence Diagrams", R. Shachter and C. R. Kenley, Management Science, 35(5):527--550, 1989.
+% Once we have the Gaussian, we can apply the standard formulas for conditioning and marginalization.
+
+assert(isequal(bnet.cnodes, 1:length(bnet.dag)));
+
+[W, D, mu] = extract_params_from_gbn(bnet);
+U = inv(eye(size(W)) - W')';
+Sigma = U' * D * U;
+
+engine.mu = mu;
+engine.Sigma = Sigma;
+%engine.logp = log(normal_coef(Sigma));
+
+% This is where we will store the results between enter_evidence and marginal_nodes  
+engine.Hmu = [];
+engine.HSigma = [];
+engine.hnodes = [];
+
+engine = class(engine, 'gaussian_inf_engine', inf_engine(bnet));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..f3142cd5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/marginal_nodes.m
@@ -0,0 +1,15 @@
+function marginal = marginal_nodes(engine, query)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (gaussian)
+% marginal = marginal_nodes(engine, query)
+
+% Compute sum_{Hsum} Pr(Hkeep, Hsum | o)
+H = engine.hnodes;
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes;
+Hkeep = myintersect(H, query);
+Hsum = mysetdiff(H, Hkeep);
+
+[marginal.mu, marginal.Sigma] = marginalize_gaussian(engine.Hmu, engine.HSigma, Hkeep, Hsum, ns);
+marginal.domain = query;
+marginal.T = 1;
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/CVS/Entries
new file mode 100644
index 00000000..de387328
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/CVS/Entries
@@ -0,0 +1,2 @@
+/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/static/@gaussian_inf_engine/private/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/CVS/Repository
new file mode 100644
index 00000000..15f3d8c4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@gaussian_inf_engine/private
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/extract_params_from_gbn.m b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_inf_engine/private/extract_params_from_gbn.m
new file mode 100644
index 00000000..86345830
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gaussian_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/static/@gibbs_sampling_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/CVS/Entries
new file mode 100644
index 00000000..c19ebdd4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/CVS/Entries
@@ -0,0 +1,4 @@
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/gibbs_sampling_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//
+D/private////
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/CVS/Repository
new file mode 100644
index 00000000..3338daf9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@gibbs_sampling_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..0710d5c8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/enter_evidence.m
@@ -0,0 +1,29 @@
+function [engine, loglik] = enter_evidence(engine, evidence)
+% ENTER_EVIDENCE Add the specified evidence to the network (gibbs_sampling_inf_engine)
+% [engine, loglik] = enter_evidence(engine, evidence)
+%
+% evidence{i} = [] if if X(i) is hidden, and otherwise contains its observed value 
+%
+% loglik is not computed... we just return a 0 value
+
+bnet = bnet_from_engine(engine);
+
+engine.hnodes = find(isemptycell(evidence));
+engine.onodes = mysetdiff(1:length(evidence), engine.hnodes);
+
+engine.evidence = zeros(engine.slice_size, 1);
+
+% Reset all counts since they are no longer valid
+engine.marginal_counts = {};
+%engine.state = sample_bnet (bnet, 1, 0);
+engine.state = cell2num(sample_bnet(bnet));
+
+% For speed, we use a normal (not cell) array.  We're making use of
+% the current restriction to discrete nodes.
+for i = engine.onodes
+    engine.evidence(i) = evidence{i};
+end
+
+loglik = 0;
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/gibbs_sampling_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/gibbs_sampling_inf_engine.m
new file mode 100644
index 00000000..3dc4b361
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/gibbs_sampling_inf_engine.m
@@ -0,0 +1,104 @@
+function engine = gibbs_sampling_inf_engine(bnet, varargin)
+% GIBBS_SAMPLING_INF_ENGINE
+%
+% engine = gibbs_sampling_inf_engine(bnet, ...) 
+%
+% Optional parameters [default in brackets]
+% 'burnin' - How long before you start using the samples [100].
+% 'gap' - how often you use the samples in the estimate [1].
+% 'T' - number of samples [1000]
+%   i.e, number of node flips (so, for
+%   example if there are 10 nodes in the bnet, and T is 1000, each
+%   node will get flipped 100 times (assuming a deterministic schedule)) 
+%   The total running time is proportional to burnin + T*gap.
+%
+% 'order' - if the sampling schedule is deterministic, use this
+% parameter to specify the order in which nodes are sampled.
+% Order is allowed to include multiple copies of nodes, which is
+% useful if you want to, say, focus sampling on particular nodes.
+% Default is to use a deterministic schedule that goes through the
+% nodes in order.
+%
+% 'sampling_dist' - when using a stochastic sampling method, at
+% each step the node to sample is chosen according to this
+% distribution (may be unnormalized)
+% 
+% The sampling_dist and order parameters shouldn't both be used,
+% and this will cause an assert.
+%
+%
+% Written by "Bhaskara Marthi" <bhaskara@cs.berkeley.edu> Feb 02.
+
+
+engine.burnin = 100;
+engine.gap = 1;
+engine.T = 1000; 
+use_default_order = 1;
+engine.deterministic = 1;
+engine.order = {};
+engine.sampling_dist = {};
+
+if nargin >= 2
+  args = varargin;
+  nargs = length(args);
+  for i = 1:2:nargs
+    switch args{i}
+     case 'burnin'
+      engine.burnin = args{i+1};
+     case 'gap'
+      engine.gap = args{i+1};
+     case 'T'
+      engine.T = args{i+1};
+     case 'order'
+      assert (use_default_order);
+      use_default_order = 0;
+      engine.order = args{i+1};
+     case 'sampling_dist'
+      assert (use_default_order);
+      use_default_order = 0;
+      engine.deterministic = 0;
+      engine.sampling_dist = args{i+1};
+     otherwise
+      error(['unrecognized parameter to gibbs_sampling_inf_engine']);
+    end
+  end
+end
+
+engine.slice_size = size(bnet.dag, 2);
+if (use_default_order)
+  engine.order = 1:engine.slice_size;
+end
+engine.hnodes = [];
+engine.onodes = [];
+engine.evidence = [];
+engine.state = [];
+engine.marginal_counts = {};
+
+% Precompute the strides for each CPT
+engine.strides = compute_strides(bnet);
+
+% Precompute graphical information
+engine.families = compute_families(bnet);
+engine.children = compute_children(bnet);
+
+% For convenience, store the CPTs as tables rather than objects
+engine.CPT = get_cpts(bnet);
+
+engine = class(engine, 'gibbs_sampling_inf_engine', inf_engine(bnet));
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..8df75552
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/marginal_nodes.m
@@ -0,0 +1,135 @@
+function [marginal, engine] = marginal_nodes(engine, nodes, varargin);
+% MARGINAL_NODES Compute the marginal on the specified query nodes
+% (gibbs_sampling_engine)
+% [marginal, engine] = marginal_nodes(engine, nodes, ...)
+%
+% returns Pr(X(nodes) | X(observedNodes))
+%
+% The engine is also modified, and so it is returned as well, since
+% Matlab doesn't support passing by reference(!)  So
+% if you want to, for example, incrementally run gibbs for a few 100
+% steps at a time, you should use the returned value.
+%
+% Optional arguments :
+%
+% 'reset_counts' is 1 if you want to reset the counts made in the
+% past, and 0 otherwise (if the current query nodes are different
+% from the previous query nodes, or if marginal_nodes has not been
+% called before, reset_counts should be set to 1).
+% By default it is 1.
+
+
+reset_counts = 1;
+
+if (nargin > 3)
+  args = varargin;
+  nargs = length(args);
+  for i = 1:2:nargs
+    switch args{i}
+     case 'reset_counts'
+      reset_counts = args{i+1};
+     otherwise
+      error(['Incorrect argument to gibbs_sampling_engine/' ...
+	     ' marginal_nodes']);
+    end
+  end
+end
+
+% initialization stuff 
+bnet = bnet_from_engine(engine);
+slice_size = engine.slice_size;
+hnodes = engine.hnodes;
+onodes = engine.onodes;
+nonqnodes = mysetdiff(1:slice_size, nodes);
+gap = engine.gap;
+burnin = engine.burnin;
+T_max = engine.T;
+ns = bnet.node_sizes(nodes);
+
+
+% Cache the strides for the marginal table
+marg_strides = [1 cumprod(ns(1:end-1))];
+  
+% Reset counts if necessary
+if (reset_counts == 1) 
+  %state = sample_bnet(bnet, 1, 0);
+  %state = cell2num(sample_bnet(bnet, 'evidence', num2cell(engine.evidence)));
+  state = cell2num(sample_bnet(bnet));
+  state(onodes) = engine.evidence(onodes);
+  if (length(ns) == 1)
+    marginal_counts = zeros(ns(1),1);
+  else
+    marginal_counts = zeros(ns);
+  end
+  
+% Otherwise, use the counts that have been stored in the engine  
+else
+  state = engine.state;
+  state(onodes, :) = engine.evidence(onodes, :);
+  marginal_counts = engine.marginal_counts;
+end
+
+if (engine.deterministic == 1)
+  pos = 1;
+  order = engine.order;
+  orderSize = length(engine.order);
+else
+  sampling_dist = normalise(engine.sampling_dist);
+end
+
+
+for t = 1:(T_max*gap+burnin)
+
+  % First, select node m to sample
+  if (engine.deterministic == 1)
+    m = engine.order(pos);
+    pos = pos+1;
+    if (pos > orderSize)
+      pos = 1;
+    end
+  else
+    m = my_sample_discrete(sampling_dist);
+  end
+
+  
+  % If the node is observed, then don't bother resampling
+  if (myismember(m, onodes))
+    continue;
+  end
+
+  % Next, compute the posterior
+  post = compute_posterior (bnet, state, m, engine.strides, engine.families, ...
+			    engine.children, engine.CPT);
+  state(m) = my_sample_discrete(post);
+
+  % Now update our monte carlo estimate of the posterior
+  % distribution on the query node 
+  if ((mod(t-burnin, gap) == 0) & (t > burnin))
+
+    vals = state(nodes);
+    index = 1+marg_strides*(vals-1);
+    marginal_counts(index) = marginal_counts(index)+1;
+  end
+end
+
+% Store results for future computation.  Note that we store
+% unnormalized counts
+engine.state = state;
+engine.marginal_counts = marginal_counts;
+
+marginal.T = normalise(marginal_counts);
+
+
+  
+    
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CPT.m b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CPT.m
new file mode 100644
index 00000000..772f137c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CPT.m
@@ -0,0 +1,5 @@
+function c = CPT(bnet, i)
+% CPT Helper function avoid having to type in
+% CPD_to_CPT(bnet.CPD{i}) every time
+
+c = CPD_to_CPT(bnet.CPD{i});
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CVS/Entries
new file mode 100644
index 00000000..0919a694
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CVS/Entries
@@ -0,0 +1,13 @@
+/CPT.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/compute_children.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/compute_families.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/compute_families_dbn.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/compute_posterior.c/1.1.1.1/Wed May 29 15:59:56 2002//
+/compute_posterior_dbn.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/compute_strides.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/get_cpts.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/get_slice_dbn.c/1.1.1.1/Wed May 29 15:59:56 2002//
+/get_slice_dbn.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/my_sample_discrete.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/sample_single_discrete.c/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CVS/Repository
new file mode 100644
index 00000000..a3027631
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@gibbs_sampling_inf_engine/private
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_children.m b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_children.m
new file mode 100644
index 00000000..3af799f8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_children.m
@@ -0,0 +1,12 @@
+function c = compute_children(bnet)
+% COMPUTE_CHILDREN
+% precomputes the children of nodes in a bnet
+%
+% The return value is a cell array for now
+
+ss = size(bnet.dag, 1);
+c = cell(ss, 1);
+for i = 1:ss
+  c{i} = children(bnet.dag, i);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_families.m b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_families.m
new file mode 100644
index 00000000..e75974cc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_families.m
@@ -0,0 +1,12 @@
+function families = compute_families(bnet)
+% COMPUTE_FAMILIES 
+% precomputes the families of nodes in a bnet
+%
+% The return value is a cell array for now
+
+ss = size(bnet.dag, 1);
+families = cell(ss, 1);
+for i = 1:ss
+  families{i} = family(bnet.dag, i);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_families_dbn.m b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_families_dbn.m
new file mode 100644
index 00000000..7647bc28
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_families_dbn.m
@@ -0,0 +1,13 @@
+function families = compute_families_dbn(bnet)
+% COMPUTE_FAMILIES 
+% precomputes the families of nodes in a dbn
+%
+% The return value is a cell array for now
+
+ss = size(bnet.intra, 1);
+families = cell(ss, 2);
+for i = 1:ss
+  families{i, 1} = family(bnet.dag, i, 1);
+  families{i, 2} = family(bnet.dag, i, 2);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_posterior.c b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_posterior.c
new file mode 100644
index 00000000..3c61b7f3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_posterior.c
@@ -0,0 +1,107 @@
+#include "mex.h"
+
+/* Helper function that extracts a one-dimensional slice from a cpt */
+/*
+void multiplySlice(mxArray *bnet, mxArray *state, int i, int nsi, int j,
+		   mxArray *strides, mxArray *fam, mxArray *cpts,
+		   double *y)
+*/
+void multiplySlice(const mxArray *bnet, const mxArray *state, int i, int nsi, int j,
+		   const mxArray *strides, const mxArray *fam, const mxArray *cpts,
+		   double *y)
+{
+  mxArray *ec, *cpt, *family;
+  double *ecElts, *cptElts, *famElts, *strideElts, *ev;
+  int c1, k, famSize, startInd, strideStride, pos, stride;
+  
+  strideStride = mxGetM(strides);
+  strideElts = mxGetPr(strides);
+
+  ev = mxGetPr(state);
+
+  /* Get the CPT */
+  ec = mxGetField (bnet, 0, "equiv_class");
+  ecElts = mxGetPr(ec);
+  k = (int) ecElts[j-1];
+  cpt = mxGetCell (cpts, k-1);
+  cptElts = mxGetPr (cpt);
+
+  /* Get the family vector for this cpt */
+  family = mxGetCell (fam, j-1);
+  famSize = mxGetNumberOfElements (family);
+  famElts = mxGetPr (family);
+
+  /* Figure out starting position and stride */
+  startInd = 0;
+  for (c1 = 0, pos = k-1; c1 < famSize; c1++, pos +=strideStride) {
+    if (famElts[c1] != i) {
+      startInd += strideElts[pos]*(ev[(int)famElts[c1]-1]-1);
+    }
+    else {
+      stride = strideElts[pos];
+    }
+  }
+
+  for (c1 = 0, pos = startInd; c1 < nsi; c1++, pos+=stride) {
+    y[c1] *= cptElts[pos];
+  }
+}
+
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray
+		 *prhs[])
+{
+  double *pi, *nsElts, *y, *childrenElts;
+  mxArray *ns, *children;
+  double sum;
+  int i, nsi, c1, numChildren;
+
+  pi = mxGetPr(prhs[2]);
+  i = (int) pi[0];
+
+  ns = mxGetField(prhs[0], 0, "node_sizes");
+  nsElts = mxGetPr(ns);
+  nsi = (int) nsElts[i-1];
+
+  /* Initialize the posterior */
+  plhs[0] = mxCreateDoubleMatrix (1, nsi, mxREAL);
+  y = mxGetPr(plhs[0]);
+  for (c1 = 0; c1 < nsi; c1++) {
+    y[c1] = 1;
+  }
+
+  /* Multiply in the cpt of the node i */
+  multiplySlice(prhs[0], prhs[1], i, nsi, i, prhs[3], prhs[4],
+		prhs[6], y);
+
+
+  /* Multiply in cpts of children of i */
+  children = mxGetCell (prhs[5], i-1);
+  numChildren = mxGetNumberOfElements (children);
+  childrenElts = mxGetPr (children);
+  
+  for (c1 = 0; c1 < numChildren; c1++) {
+    int j;
+    j = (int) childrenElts[c1];
+    multiplySlice (prhs[0], prhs[1], i, nsi, j, prhs[3], prhs[4],
+		   prhs[6], y);
+  }
+
+  sum = 0;
+  /* normalize! */
+  for (c1 = 0; c1 < nsi; c1++) {
+    sum += y[c1];
+  }
+
+  for (c1 = 0; c1 < nsi; c1++) {
+    y[c1] /= sum;
+  }
+}
+
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_posterior_dbn.m b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_posterior_dbn.m
new file mode 100644
index 00000000..e9a69b24
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_posterior_dbn.m
@@ -0,0 +1,59 @@
+function post = compute_posterior_dbn(bnet, state, i, n, strides, families, ...
+				  CPT)
+% COMPUTE_POSTERIOR
+%
+% post = compute_posterior(bnet, state, i, n, strides, families,
+% cpts)
+%
+% Compute the posterior distribution on node X_i^n of a DBN,
+% conditional on evidence in the cell array state
+%
+% strides is the cached result of compute_strides(bnet)
+% families is the cached result of compute_families(bnet)
+% cpt is the cached result of get_cpts(bnet)
+%
+% post is a one-dimensional table
+
+
+
+% First multiply in the cpt of the node itself
+post = get_slice_dbn(bnet, state, i, n, i, n, strides, families, CPT);
+post = post(:);
+
+% Then multiply in CPTs of children that are in this slice
+for j = children(bnet.intra, i)
+  slice = get_slice_dbn(bnet, state, j, n, i, n, strides, families, CPT);
+  post = post.*slice(:);
+end
+
+% Finally, if necessary, multiply in CPTs of children in the next
+% slice 
+if (n < size(state,2))
+  for j = children(bnet.inter, i)
+    slice = get_slice_dbn(bnet, state, j, n+1, i, n, strides, families, ...
+			    CPT);
+    post = post.*slice(:);
+  end
+end
+
+post = normalise(post);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_strides.m b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_strides.m
new file mode 100644
index 00000000..a8e26c25
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/compute_strides.m
@@ -0,0 +1,27 @@
+function strides = compute_strides(bnet)
+% COMPUTE_STRIDES For each CPT and each variable in that CPT,
+% returns the stride of that variable.  So in future, we can
+% quickly extract a slice of the CPT.
+%
+% The return value is a 2d array, where strides(i,j) contains the
+% stride of the jth variable in the ith CPT.  Cell arrays would
+% have saved space but they are slower.
+% 
+
+num_cpts = size(bnet.CPD, 2);
+max_cpt_dim = 1 + max(sum(bnet.dag));
+strides = zeros(num_cpts, max_cpt_dim);
+
+for i = 1:num_cpts
+  c = CPT(bnet, i);
+  siz = size(CPT(bnet, i));
+  
+  % Deal with the special case of a 1-d array separately
+  if siz(2) == 1
+    dim = 1;
+  else
+    dim = size(siz, 2);
+  end
+
+  strides(i, 1:dim ) = [1 cumprod(siz(1:dim-1))];
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/get_cpts.m b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/get_cpts.m
new file mode 100644
index 00000000..77c86070
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/get_cpts.m
@@ -0,0 +1,8 @@
+function c = get_cpts(bnet)
+% Get all the cpts in tabular form
+
+cpds = bnet.CPD;
+c = cell(size(cpds));
+for i = 1:length(c)
+  c{i} = CPT(bnet, i);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/get_slice_dbn.c b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/get_slice_dbn.c
new file mode 100644
index 00000000..33540eff
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/get_slice_dbn.c
@@ -0,0 +1,116 @@
+#include "mex.h"
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray
+		 *prhs[]) 
+{
+  double *pn, *pi, *pj, *pm, *y, *ecElts, *pcpt, *famElts, *strideElts,
+    *ev, *nsElts;
+  int i, k, j, m, n;
+  mxArray *ec, *cpt, *fam, *ns;
+  int c1, famSize, nsj;
+  int strideStride, startInd, stride, pos, numNodes;
+
+  const int BNET = 0;
+  const int STATE = 1;
+  const int STRIDES = 6;
+  const int FAMILIES = 7;
+  const int CPT = 8;
+
+  pn = mxGetPr(prhs[3]);
+  n = (int) pn[0];
+  pi = mxGetPr(prhs[2]);
+  i = (int) pi[0];
+  pj = mxGetPr(prhs[4]);
+  j = (int) pj[0];
+  pm = mxGetPr(prhs[5]);
+  m = (int) pm[0];
+  ev = mxGetPr(prhs[STATE]);
+  ns = mxGetField (prhs[BNET], 0, "node_sizes");
+  nsElts = mxGetPr (ns);
+  numNodes = mxGetM(ns);
+
+  strideStride = mxGetM(prhs[STRIDES]);
+  strideElts = mxGetPr(prhs[STRIDES]);
+
+
+  
+  /* Treat the case n = 1 separately */
+  if (pn[0] == 1) {
+
+    /* Get the appropriate CPT */
+    ec = mxGetField (prhs[BNET], 0, "eclass1");
+    ecElts = mxGetPr(ec);
+    k = (int) ecElts[i-1];
+    cpt = mxGetCell (prhs[8], k-1);
+    pcpt = mxGetPr(cpt);
+
+    nsj = (int) nsElts[j-1];
+
+    /* Get the correct family vector */
+    /* (Note : MEX is painful) */
+    fam = mxGetCell (prhs[FAMILIES], i - 1);
+    famSize = mxGetNumberOfElements(fam);
+    famElts = mxGetPr(fam);
+
+
+    /* Figure out starting position and stride */
+    startInd = 0;
+    for (c1 = 0, pos = k-1; c1 < famSize; c1++, pos+=strideStride) {
+      if (famElts[c1] != j) {
+	startInd += strideElts[pos]*(ev[(int)famElts[c1]-1]-1);
+      }
+      else {
+	stride = strideElts[pos];
+      }
+    }
+    
+    plhs[0] = mxCreateDoubleMatrix (1, nsj, mxREAL);
+    y = mxGetPr(plhs[0]);
+    for (c1 = 0, pos = startInd; c1 < nsj; c1++, pos+=stride) {
+      y[c1] = pcpt[pos];
+    }
+  }
+
+  /* Handle the case n > 1 */
+  else {
+
+    /* Get the appropriate CPT */
+    ec = mxGetField (prhs[BNET], 0, "eclass2");
+    ecElts = mxGetPr(ec);
+    k = (int) ecElts[i-1];
+    cpt = mxGetCell (prhs[8], k-1);
+    pcpt = mxGetPr(cpt);
+
+    /* Figure out size of slice */
+    if (m == 1) {
+      nsj = (int) nsElts[j-1];
+    }
+    else {
+      nsj = (int) nsElts[j-1+numNodes];
+    }
+
+    /* Figure out family */
+    fam = mxGetCell (prhs[FAMILIES], i - 1 + numNodes);
+    famSize = mxGetNumberOfElements(fam);
+    famElts = mxGetPr(fam);
+    
+    startInd = 0;
+    for (c1 = 0, pos = k-1; c1 < famSize; c1++, pos+=strideStride) {
+      int f = (int) famElts[c1];
+
+      if (((f == j+numNodes) && (m == n)) || ((f == j) && (m ==
+							    n-1))) {
+	stride = strideElts[pos];
+      }
+      else {
+	startInd += strideElts[pos] * (ev[f-1+((n-2)*numNodes)]-1);
+      }
+    }
+
+    plhs[0] = mxCreateDoubleMatrix(1,nsj, mxREAL);
+    y = mxGetPr(plhs[0]);
+    for (c1 = 0, pos = startInd; c1 < nsj; c1++, pos+=stride) {
+      y[c1] = pcpt[pos];
+    }
+  }
+}
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/get_slice_dbn.m b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/get_slice_dbn.m
new file mode 100644
index 00000000..22841784
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/get_slice_dbn.m
@@ -0,0 +1,87 @@
+function slice = get_slice_dbn(bnet, state, i, n, j, m, strides, families, ...
+				 CPT)
+% slice = get_slice(bnet, state, i, n, j, m, strides, families, cpt)
+%
+% GET_SLICE get one-dimensional slice of the CPT for node X_i^n
+% that corresponds to the different values of X_j^m, where all
+% other nodes have values given by state.  
+% strides is the result of
+% calling compute_strides(bnet)
+% families is the result of calling compute_families(bnet)
+% cpts is the result of calling get_cpts(bnet)
+%
+% slice is a 1-d array
+
+
+if (n == 1)
+
+  k = bnet.eclass1(i);
+  c = CPT{k};
+  
+  % Figure out evidence on family
+  fam = families{i, 1};
+  ev = state(fam, 1);
+  
+  % Remove evidence on node j
+  pos = find(fam == j);
+  ev(pos) = 1;
+  dim = size(ev, 1);
+  
+  % Compute initial index and stride
+  start_ind = 1+strides(k, 1:dim)*(ev-1);
+  stride = strides(k, pos);
+
+  % Compute the slice
+  slice = c(start_ind:stride:start_ind+(bnet.node_sizes(j, 1)-1)*stride);
+						  
+else
+  
+  k = bnet.eclass2(i);
+  c = CPT{k};
+  
+  fam = families{i, 2};
+  ss = length(bnet.intra);
+  
+  % Divide the family into nodes in this time step and nodes in the
+  % previous time step
+  this_time_step = fam(find(fam > ss));
+  prev_time_step = fam(find(fam <= ss));
+
+  % Normalize the node numbers
+  this_time_step = this_time_step - ss;
+  
+  % Get the evidence
+  this_step_ev = state(this_time_step, n);
+  prev_step_ev = state(prev_time_step, n-1);
+  
+  % Remove the evidence for X_j^m
+  if (m == n)
+    pos = find(this_time_step == j);
+    this_step_ev(pos) = 1;
+    pos = pos + size(prev_time_step, 2);
+  else
+    assert (m == n-1);
+    pos = find(prev_time_step == j);
+    prev_step_ev(pos) = 1;
+  end
+  
+  % Combine the two time steps
+  ev = [prev_step_ev; this_step_ev];
+  dim = size(ev, 1);
+
+
+  % Compute starting index and stride
+  start_ind = 1 + strides(k, 1:dim)*(ev-1);
+  stride = strides(k, pos);
+  
+  % Compute slice 
+  if (m == 1)
+    q = 1;
+  else
+    q = 2;
+  end
+  slice = c(start_ind:stride:start_ind+(bnet.node_sizes(j, q)-1)*stride);
+end
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/my_sample_discrete.m b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/my_sample_discrete.m
new file mode 100644
index 00000000..70f0615b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/my_sample_discrete.m
@@ -0,0 +1,7 @@
+function M = my_sample_discrete(prob)
+% A faster version that calls a c subfunction.  Will update one
+% day to have r and c parameters as well
+
+R = rand (1,1);
+M = sample_single_discrete(R, prob);
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/sample_single_discrete.c b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/sample_single_discrete.c
new file mode 100644
index 00000000..36112de6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@gibbs_sampling_inf_engine/private/sample_single_discrete.c
@@ -0,0 +1,22 @@
+#include "mex.h"
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray
+		 *prhs[]) 
+{
+  double *y, *pr, *dist;
+  int k, distSize;
+  double r, cumSum;
+  
+  plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);
+  y = mxGetPr (plhs[0]);
+
+  pr = mxGetPr (prhs[0]);
+  r = pr[0];
+
+  dist = mxGetPr (prhs[1]);
+  distSize = mxGetNumberOfElements (prhs[1]);
+
+  for (k = 0, cumSum = 0; (k < distSize) && (r >= cumSum); cumSum += dist[k], k++);
+
+  y[0] = k;
+}
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/CVS/Entries
new file mode 100644
index 00000000..1c5d76dd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/CVS/Entries
@@ -0,0 +1,6 @@
+/enter_evidence.m/1.1.1.1/Mon Jun  7 19:05:42 2004//
+/find_mpe.m/1.1.1.1/Wed Jun 19 21:56:32 2002//
+/global_joint_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/Mon Jun  7 19:04:48 2004//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/CVS/Repository
new file mode 100644
index 00000000..0c8fadf5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@global_joint_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..105894ff
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/enter_evidence.m
@@ -0,0 +1,42 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (global_joint)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i} = [] if if X(i) is hidden, and otherwise contains its observed value.
+%
+% Warning: Computing the log likelihood requires marginalizing all the nodes and can be slow.
+%
+% The list below gives optional arguments [default value in brackets].      
+%
+% exclude - list of nodes whose potential will not be included in the joint [ [] ]
+%
+% e.g., engine = enter_evidence(engine, ev, 'exclude', 3)
+
+exclude = [];
+maximize = 0;
+
+if nargin >= 3
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'exclude', exclude = args{i+1};
+     case 'maximize', maximize = args{i+1};
+     otherwise,
+      error(['invalid argument name ' args{i}]);
+    end
+  end
+end
+  
+assert(~maximize)
+bnet = bnet_from_engine(engine);
+N = length(bnet.node_sizes);
+%[engine.jpot, loglik] = compute_joint_pot(bnet, mysetdiff(1:N, exclude), evidence, 1:N);
+[engine.jpot] = compute_joint_pot(bnet, mysetdiff(1:N, exclude), evidence, 1:N);
+% jpot should not be normalized, otherwise it gives wrong resutls for limids like asia_dt1
+if nargout == 2
+  [m] = marginal_nodes(engine, []);
+  [T, lik] = normalize(m.T);
+  loglik = log(lik);
+end     
+%[engine.jpot loglik] = normalize_pot(engine.jpot);
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/find_mpe.m b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/find_mpe.m
new file mode 100644
index 00000000..92915b6c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/find_mpe.m
@@ -0,0 +1,28 @@
+function [mpe, ll] = find_mpe(engine, evidence)
+% FIND_MPE_GLOBAL Compute the most probable explanation(s) from the global joint
+% [mpe, ll] = find_mpe(engine, evidence)
+%
+% mpe(k,i) is the most probable value of node i in the k'th global mode  (cell array)
+%
+% We assume all nodes are discrete
+
+%engine = global_joint_inf_engine(bnet);
+bnet = bnet_from_engine(engine);
+engine = enter_evidence(engine, evidence);
+S1 = struct(engine); % violate object privacy
+S2 = struct(S1.jpot); % joint potential
+prob = max(S2.T(:));
+modes = find(S2.T(:) == prob);
+
+ens = bnet.node_sizes;
+onodes = find(~isemptycell(evidence));
+ens(onodes) = 1;
+mpe = ind2subv(ens, modes);
+for k=1:length(modes)
+  for i=onodes(:)'
+    mpe(k,i) = evidence{i};
+  end
+end
+ll = log(prob);
+
+mpe = num2cell(mpe);
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/global_joint_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/global_joint_inf_engine.m
new file mode 100644
index 00000000..86bca532
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/global_joint_inf_engine.m
@@ -0,0 +1,8 @@
+function engine = global_joint_inf_engine(bnet)
+% GLOBAL_JOINT_INF_ENGINE Construct the global joint distribution as a potential
+% engine = global_joint_inf_engine(bnet)
+%
+% Warning: this has size exponential in the number of discrete hidden variables
+
+engine.jpot = [];
+engine = class(engine, 'global_joint_inf_engine', inf_engine(bnet));    
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/marginal_family.m
new file mode 100644
index 00000000..6931814c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/marginal_family.m
@@ -0,0 +1,7 @@
+function [m, pot] = marginal_family(engine, i)
+% MARGINAL_FAMILY Compute the marginal on i's family (global_inf_engine)
+% [m, pot] = marginal_family(engine, i)
+%
+
+bnet = bnet_from_engine(engine);
+[m, pot] = marginal_nodes(engine, family(bnet.dag, i));
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..223e6574
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@global_joint_inf_engine/marginal_nodes.m
@@ -0,0 +1,8 @@
+function [m, pot] = marginal_nodes(engine, query)
+% MARGINAL_NODES Compute the marginal on the specified set of nodes (global_joint)
+% [m, pot] = marginal_nodes(engine, query)
+
+pot = marginalize_pot(engine.jpot, query);
+m = pot_to_marginal(pot);
+%[m.T, lik] = normalize(m.T);
+%loglik = log(lik);
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Entries
new file mode 100644
index 00000000..8a9c45e2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Entries
@@ -0,0 +1,14 @@
+/cliques_from_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/clq_containing_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/collect_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/distribute_evidence.m/1.1.1.1/Mon Jun 17 21:00:08 2002//
+/enter_evidence.m/1.1.1.1/Mon Jun 17 20:59:30 2002//
+/enter_soft_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/find_max_config.m/1.1.1.1/Mon Jun 17 23:14:52 2002//
+/find_mpe.m/1.1.1.1/Mon Jun 17 23:14:08 2002//
+/init_pot.m/1.1.1.1/Sun Jun 16 19:34:56 2002//
+/jtree_inf_engine.m/1.1.1.1/Fri Oct 31 22:37:48 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//
+/set_fields.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Repository
new file mode 100644
index 00000000..c25f18d5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@jtree_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/CVS/Entries
new file mode 100644
index 00000000..5d0e75e3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/CVS/Entries
@@ -0,0 +1,5 @@
+/collect_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/distribute_evidence.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/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/CVS/Repository
new file mode 100644
index 00000000..cf59323d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@jtree_inf_engine/Old
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/collect_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/collect_evidence.m
new file mode 100644
index 00000000..2f7757f1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/collect_evidence.m
@@ -0,0 +1,29 @@
+function engine = collect_evidence(engine, root)
+
+if isempty(engine.postorder{root})
+  % this is the first time we have collected to this root
+  % memoize the order
+  [jtree, preorder, postorder] = mk_rooted_tree(engine.jtree, root);
+  postorder_parents = cell(1,length(postorder));
+  for n=postorder(1:end-1)
+    postorder_parents{n} = parents(jtree, n);
+  end
+  engine.postorder{root} = postorder;
+  engine.postorder_parents{root} = postorder_parents;
+else
+  postorder = engine.postorder{root};
+  postorder_parents = engine.postorder_parents{root};
+end
+
+C = length(engine.clpot);
+seppot = cell(C, C);
+% separators are implicitely initialized to 1s
+
+% collect to root (node to parents)
+for n=postorder(1:end-1)
+  for p=postorder_parents{n}
+    %clpot{p} = divide_by_pot(clpot{n}, seppot{p,n}); % dividing by 1 is redundant
+    engine.seppot{p,n} = marginalize_pot(engine.clpot{n}, engine.separator{p,n}, engine.maximize);
+    engine.clpot{p} = multiply_by_pot(engine.clpot{p}, engine.seppot{p,n});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/distribute_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/distribute_evidence.m
new file mode 100644
index 00000000..f8d78be4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/distribute_evidence.m
@@ -0,0 +1,26 @@
+function engine = distribute_evidence(engine, root)
+
+if isempty(engine.preorder{root})
+  % this is the first time we have distributed from this root
+  % memoize the order
+  [jtree, preorder, postorder] = mk_rooted_tree(engine.jtree, root);
+  preorder_children = cell(1,length(preorder));
+  for n=preorder
+    preorder_children{n} = children(jtree, n);
+  end
+  engine.preorder{root} = preorder;
+  engine.preorder_children{root} = preorder_children;
+else
+  preorder = engine.preorder{root};
+  preorder_children = engine.preorder_children{root};
+end
+
+
+% distribute from root (node to children)
+for n=preorder(:)'
+  for c=preorder_children{n}(:)'
+    engine.clpot{c} = divide_by_pot(engine.clpot{c}, engine.seppot{n,c}); 
+    engine.seppot{n,c} = marginalize_pot(engine.clpot{n}, engine.separator{n,c}, engine.maximize);
+    engine.clpot{c} = multiply_by_pot(engine.clpot{c}, engine.seppot{n,c});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/enter_evidence.m
new file mode 100644
index 00000000..aafeeecb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/enter_evidence.m
@@ -0,0 +1,107 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (jtree)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i} = [] if X(i) 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]
+% soft    - a cell array of soft/virtual evidence;
+%           soft{i} is a prob. distrib. over i's values, or [] [ cell(1,N) ]
+%
+% e.g., engine = enter_evidence(engine, ev, 'soft', soft_ev)
+%
+% For backwards compatibility with BNT2, you can also specify the parameters in the following order
+%  engine = enter_evidence(engine, ev, soft_ev)
+
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes(:);
+N = length(bnet.dag);
+
+% set default params
+exclude = [];
+soft_evidence = cell(1,N);
+maximize = 0;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  if iscell(args{1})
+    soft_evidence = args{1};
+  else
+    for i=1:2:nargs
+      switch args{i},
+       case 'soft',    soft_evidence = args{i+1}; 
+       case 'maximize', maximize = args{i+1}; 
+       otherwise,  
+	error(['invalid argument name ' args{i}]);       
+      end
+    end
+  end
+end
+
+engine.maximize = maximize;
+
+onodes = find(~isemptycell(evidence));
+hnodes = find(isemptycell(evidence));
+pot_type = determine_pot_type(bnet, onodes);
+ if strcmp(pot_type, 'cg')
+  check_for_cd_arcs(onodes, bnet.cnodes, bnet.dag);
+end
+
+
+hard_nodes = 1:N;
+soft_nodes = find(~isemptycell(soft_evidence));
+S = length(soft_nodes);
+if S > 0
+  assert(pot_type == 'd');
+  assert(mysubset(soft_nodes, bnet.dnodes));
+end
+ 
+% Evaluate CPDs with evidence, and convert to potentials  
+pot = cell(1, N+S);
+for n=1:N
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n);
+  pot{n} = convert_to_pot(bnet.CPD{e}, pot_type, fam(:), evidence);
+end
+
+for i=1:S
+  n = soft_nodes(i);
+  pot{N+i} = dpot(n, ns(n), soft_evidence{n});
+end
+
+%clqs = engine.clq_ass_to_node([hard_nodes soft_nodes]); 
+%[clpot, loglik] = enter_soft_evidence(engine, clqs, pot, onodes, pot_type);
+%engine.clpot = clpot; % save the results for marginal_nodes
+
+
+clique = engine.clq_ass_to_node([hard_nodes soft_nodes]); 
+potential = pot;
+
+
+% Set the clique potentials to all 1s
+C = length(engine.cliques);
+for i=1:C
+  engine.clpot{i} = mk_initial_pot(pot_type, engine.cliques{i}, ns, bnet.cnodes, onodes);
+end
+
+% Multiply on specified potentials
+for i=1:length(clique)
+  c = clique(i);
+  engine.clpot{c} = multiply_by_pot(engine.clpot{c}, potential{i});
+end
+
+root = 1; % arbitrary
+engine = collect_evidence(engine, root);
+engine = distribute_evidence(engine, root);
+
+ll = zeros(1, C);
+for i=1:C
+  [engine.clpot{i}, ll(i)] = normalize_pot(engine.clpot{i});
+end
+loglik = ll(1); % we can extract the likelihood from any clique
+    
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/enter_soft_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/enter_soft_evidence.m
new file mode 100644
index 00000000..59671415
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/Old/enter_soft_evidence.m
@@ -0,0 +1,19 @@
+function [clpot, loglik] = enter_soft_evidence(engine, clique, potential, onodes, pot_type)
+% ENTER_SOFT_EVIDENCE Add the specified potentials to the network (jtree)
+% [clpot, loglik] = enter_soft_evidence(engine, clique, potential, onodes, pot_type, maximize)
+%
+% We multiply potential{i} onto clique(i) before propagating.
+% We return all the modified clique potentials.
+
+[clpot, seppot] = init_pot(engine, clique, potential, pot_type, onodes);
+[clpot, seppot] = collect_evidence(engine, clpot, seppot);
+[clpot, seppot] = distribute_evidence(engine, clpot, seppot);
+
+C = length(clpot);
+ll = zeros(1, C);
+for i=1:C
+  [clpot{i}, ll(i)] = normalize_pot(clpot{i});
+end
+loglik = ll(1); % we can extract the likelihood from any clique
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/cliques_from_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/cliques_from_engine.m
new file mode 100644
index 00000000..cd9d871d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/cliques_from_engine.m
@@ -0,0 +1,5 @@
+function cliques = cliques_from_engine(engine)
+% CLIQUES_FROM_ENGINE Return the cliques stored inside the inf. engine (jtree)
+% cliques = cliques_from_engine(engine)
+
+cliques = engine.cliques;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/clq_containing_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/clq_containing_nodes.m
new file mode 100644
index 00000000..8904fa49
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/clq_containing_nodes.m
@@ -0,0 +1,24 @@
+function c = clq_containing_nodes(engine, nodes, fam)
+% CLQ_CONTAINING_NODES Find the lightest clique (if any) that contains the set of nodes
+% c = clq_containing_nodes(engine, nodes, family)
+%
+% If the optional 'family' argument is specified, it means nodes = family(nodes(end)).
+% (This is useful since clq_ass_to_node is not accessible to outsiders.)
+% Returns c=-1 if there is no such clique.
+
+if nargin < 3, fam = 0; else fam = 1; end
+
+if length(nodes)==1
+  c = engine.clq_ass_to_node(nodes(1));
+%elseif fam
+%  c = engine.clq_ass_to_node(nodes(end));
+else
+  B = engine.cliques_bitv;
+  w = engine.clique_weight;
+  clqs = find(all(B(:,nodes), 2)); % all selected columns must be 1
+  if isempty(clqs)
+    c = -1;
+  else
+    c = clqs(argmin(w(clqs)));     
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/collect_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/collect_evidence.m
new file mode 100644
index 00000000..03c00edf
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/collect_evidence.m
@@ -0,0 +1,12 @@
+function [clpot, seppot] = collect_evidence(engine, clpot, seppot)
+% COLLECT_EVIDENCE Do message passing from leaves to root (children then parents)
+% [clpot, seppot] = collect_evidence(engine, clpot, seppot)
+
+for n=engine.postorder %postorder(1:end-1)
+  for p=engine.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}, engine.separator{p,n}, engine.maximize);
+    clpot{p} = multiply_by_pot(clpot{p}, seppot{p,n});
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/distribute_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/distribute_evidence.m
new file mode 100644
index 00000000..403b8970
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/distribute_evidence.m
@@ -0,0 +1,11 @@
+function [clpot, seppot] = distribute_evidence(engine, clpot, seppot)
+% DISTRIBUTE_EVIDENCE Do message passing from root to leaves (parents then children)
+% [clpot, seppot] = distribute_evidence(engine, clpot, seppot)
+
+for n=engine.preorder
+  for c=engine.preorder_children{n}
+    clpot{c} = divide_by_pot(clpot{c}, seppot{n,c}); 
+    seppot{n,c} = marginalize_pot(clpot{n}, engine.separator{n,c}, engine.maximize);
+    clpot{c} = multiply_by_pot(clpot{c}, seppot{n,c});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..c85d03a7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/enter_evidence.m
@@ -0,0 +1,88 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (jtree)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i} = [] if X(i) 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]
+%
+% soft    - a cell array of soft/virtual evidence;
+%           soft{i} is a prob. distrib. over i's values, or [] [ cell(1,N) ]
+%
+% e.g., engine = enter_evidence(engine, ev, 'soft', soft_ev)
+
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes(:);
+N = length(bnet.dag);
+
+engine.evidence = evidence; % store this for marginal_nodes with add_ev option
+engine.maximize = 0;
+
+% set default params
+exclude = [];
+soft_evidence = cell(1,N);
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'soft',    soft_evidence = args{i+1}; 
+   case 'maximize', engine.maximize = args{i+1};
+   otherwise,  
+    error(['invalid argument name ' args{i}]);       
+  end
+end
+
+onodes = find(~isemptycell(evidence));
+hnodes = find(isemptycell(evidence));
+pot_type = determine_pot_type(bnet, onodes);
+ if strcmp(pot_type, 'cg')
+  check_for_cd_arcs(onodes, bnet.cnodes, bnet.dag);
+end
+
+if is_mnet(bnet)
+  pot = engine.user_pot;
+  clqs = engine.nums_ass_to_user_clqs;
+else
+  % Evaluate CPDs with evidence, and convert to potentials  
+  pot = cell(1, N);
+  for n=1:N
+    fam = family(bnet.dag, n);
+    e = bnet.equiv_class(n);
+    if isempty(bnet.CPD{e})
+      error(['must define CPD ' num2str(e)])
+    else
+      pot{n} = convert_to_pot(bnet.CPD{e}, pot_type, fam(:), evidence);
+    end
+  end
+  clqs = engine.clq_ass_to_node(1:N);
+end
+
+% soft evidence
+soft_nodes = find(~isemptycell(soft_evidence));
+S = length(soft_nodes);
+if S > 0
+  assert(pot_type == 'd');
+  assert(mysubset(soft_nodes, bnet.dnodes));
+end
+for i=1:S
+  n = soft_nodes(i);
+  pot{end+1} = dpot(n, ns(n), soft_evidence{n});
+end
+clqs = [clqs engine.clq_ass_to_node(soft_nodes)]; 
+
+
+[clpot, seppot] = init_pot(engine, clqs, pot, pot_type, onodes);
+[clpot, seppot] = collect_evidence(engine, clpot, seppot);
+[clpot, seppot] = distribute_evidence(engine, clpot, seppot);
+
+C = length(clpot);
+ll = zeros(1, C);
+for i=1:C
+  [clpot{i}, ll(i)] = normalize_pot(clpot{i});
+end
+loglik = ll(1); % we can extract the likelihood from any clique
+
+engine.clpot = clpot;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/enter_soft_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/enter_soft_evidence.m
new file mode 100644
index 00000000..0a4346c6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/enter_soft_evidence.m
@@ -0,0 +1,21 @@
+function [clpot, loglik] = enter_soft_evidence(engine, clique, potential, onodes, pot_type)
+% ENTER_SOFT_EVIDENCE Add the specified potentials to the network (jtree)
+% [clpot, loglik] = enter_soft_evidence(engine, clique, potential, onodes, pot_type, maximize)
+%
+% We multiply potential{i} onto clique(i) before propagating.
+% We return all the modified clique potentials.
+
+% only used by BK!
+
+[clpot, seppot] = init_pot(engine, clique, potential, pot_type, onodes);
+[clpot, seppot] = collect_evidence(engine, clpot, seppot);
+[clpot, seppot] = distribute_evidence(engine, clpot, seppot);
+
+C = length(clpot);
+ll = zeros(1, C);
+for i=1:C
+  [clpot{i}, ll(i)] = normalize_pot(clpot{i});
+end
+loglik = ll(1); % we can extract the likelihood from any clique
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/find_max_config.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/find_max_config.m
new file mode 100644
index 00000000..5053b1e8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/find_max_config.m
@@ -0,0 +1,35 @@
+function [mpe, clpot, seppot] = find_max_config(engine, clpot, seppot, evidence)
+% FIND_MAX_CONFIG Backwards pass of Viterbi fro jtree
+% function [mpe, clpot, seppot] = find_max_config(engine, clpot, seppot, evidence)
+% See Cowell99 p98
+
+bnet = bnet_from_engine(engine);
+nnodes = length(bnet.dag);
+mpe = cell(1, nnodes);
+maximize = 1;
+
+c = engine.root_clq;
+pot = struct(clpot{c}); % violate object privacy
+dom = pot.domain;
+[indices, clpot{c}] = find_most_prob_entry(clpot{c});
+mpe(dom) = num2cell(indices);
+
+for n=engine.preorder
+  for c=engine.preorder_children{n}
+    clpot{c} = divide_by_pot(clpot{c}, seppot{n,c}); 
+    seppot{n,c} = marginalize_pot(clpot{n}, engine.separator{n,c}, maximize);
+    clpot{c} = multiply_by_pot(clpot{c}, seppot{n,c});
+    
+    pot = struct(clpot{c}); % violate object privacy
+    dom = pot.domain;
+    [indices, clpot{c}] = find_most_prob_entry(clpot{c});
+    mpe(dom) = num2cell(indices);
+  end
+end
+
+obs_nodes = find(~isemptycell(evidence));
+% indices for observed nodes will be 1 - need to overwrite these
+mpe(obs_nodes) = evidence(obs_nodes);
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/find_mpe.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/find_mpe.m
new file mode 100644
index 00000000..8a46c1ed
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/find_mpe.m
@@ -0,0 +1,71 @@
+function mpe = find_mpe(engine, evidence, varargin)
+% FIND_MPE Find the most probable explanation of the data (assignment to the hidden nodes)
+% function mpe = find_mpe(engine, evidence,...)
+%
+% evidence{i} = [] if X(i) 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]
+%
+% soft    - a cell array of soft/virtual evidence;
+%           soft{i} is a prob. distrib. over i's values, or [] [ cell(1,N) ]
+%
+
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes(:);
+N = length(bnet.dag);
+
+engine.evidence = evidence;
+  
+% set default params
+exclude = [];
+soft_evidence = cell(1,N);
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'soft',    soft_evidence = args{i+1}; 
+   otherwise,  
+    error(['invalid argument name ' args{i}]);       
+  end
+end
+engine.maximize = 1;
+
+onodes = find(~isemptycell(evidence));
+hnodes = find(isemptycell(evidence));
+pot_type = determine_pot_type(bnet, onodes);
+ if strcmp(pot_type, 'cg')
+  check_for_cd_arcs(onodes, bnet.cnodes, bnet.dag);
+end
+
+hard_nodes = 1:N;
+soft_nodes = find(~isemptycell(soft_evidence));
+S = length(soft_nodes);
+if S > 0
+  assert(pot_type == 'd');
+  assert(mysubset(soft_nodes, bnet.dnodes));
+end
+ 
+% Evaluate CPDs with evidence, and convert to potentials  
+pot = cell(1, N+S);
+for n=1:N
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n);
+  if isempty(bnet.CPD{e})
+    error(['must define CPD ' num2str(e)])
+  else
+    pot{n} = convert_to_pot(bnet.CPD{e}, pot_type, fam(:), evidence);
+  end
+end
+
+for i=1:S
+  n = soft_nodes(i);
+  pot{N+i} = dpot(n, ns(n), soft_evidence{n});
+end
+clqs = engine.clq_ass_to_node([hard_nodes soft_nodes]); 
+
+[clpot, seppot] = init_pot(engine, clqs, pot, pot_type, onodes);
+[clpot, seppot] = collect_evidence(engine, clpot, seppot);
+mpe = find_max_config(engine, clpot, seppot, evidence); % instead of distribute evidence
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/init_pot.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/init_pot.m
new file mode 100644
index 00000000..857e6266
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/init_pot.m
@@ -0,0 +1,20 @@
+function [clpot, seppot] = init_pot(engine, clqs, pots, pot_type, onodes, ndx)
+% INIT_POT Initialise potentials with evidence (jtree_inf)
+% function [clpot, seppot] = init_pot(engine, clqs, pots, pot_type, onodes)
+
+cliques = engine.cliques;
+bnet = bnet_from_engine(engine);
+% 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}, bnet.node_sizes(:), bnet.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
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/jtree_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/jtree_inf_engine.m
new file mode 100644
index 00000000..dd744dc0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/jtree_inf_engine.m
@@ -0,0 +1,141 @@
+function engine = jtree_inf_engine(bnet, varargin)
+% JTREE_INF_ENGINE Junction tree inference engine
+% engine = jtree_inf_engine(bnet, ...)
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% clusters  - a cell array of sets of nodes we want to ensure are in the same clique (in addition to families) [ {} ]
+% root      - the root of the junction tree will be a clique that contains this set of nodes [N]
+% stages    - stages{t} is a set of nodes we want to eliminate before stages{t+1}, ... [ {1:N} ]
+%
+% e.g., engine = jtree_inf_engine(bnet, 'maximize', 1);
+%
+% For more details on the junction tree algorithm, see
+% - "Probabilistic networks and expert systems", Cowell, Dawid, Lauritzen and Spiegelhalter, Springer, 1999
+% - "Inference in Belief Networks: A procedural guide", C. Huang and A. Darwiche, 
+%      Intl. J. Approximate Reasoning, 15(3):225-263, 1996.
+
+
+% set default params
+N = length(bnet.dag);
+clusters = {};
+root = N;
+stages = { 1:N };
+maximize = 0;
+
+if nargin >= 2
+  args = varargin;
+  nargs = length(args);
+  if ~isstr(args{1})
+    error('the interface to jtree has changed; now, onodes is not allowed and all optional params must be passed by name')
+  end
+  for i=1:2:nargs
+    switch args{i},
+     case 'clusters', clusters = args{i+1}; 
+     case 'root',     root = args{i+1}; 
+     case 'stages',   stages = args{i+1}; 
+     case 'maximize', maximize = args{i+1};
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+engine = init_fields;
+engine = class(engine, 'jtree_inf_engine', inf_engine(bnet));
+
+engine.maximize = maximize;
+
+onodes = bnet.observed;
+
+%[engine.jtree, dummy, engine.cliques, B, w, elim_order, moral_edges, fill_in_edges, strong] = ...
+%    dag_to_jtree(bnet, onodes, stages, clusters);
+
+porder = determine_elim_constraints(bnet, onodes);
+strong = ~isempty(porder);
+ns = bnet.node_sizes(:);
+ns(onodes) = 1; % observed nodes have only 1 possible value
+[engine.jtree, root2, engine.cliques, B, w] = ...
+    graph_to_jtree(moralize(bnet.dag), ns, porder, stages, clusters);
+
+
+engine.cliques_bitv = B;
+engine.clique_weight = w;
+C = length(engine.cliques);
+engine.clpot = cell(1,C);
+
+% Compute the separators between connected cliques.
+[is,js] = find(engine.jtree > 0);
+engine.separator = cell(C,C);
+for k=1:length(is)
+  i = is(k); j = js(k);
+  engine.separator{i,j} = find(B(i,:) & B(j,:)); % intersect(cliques{i}, cliques{j});
+end
+
+% A node can be a member of many cliques, but is assigned to exactly one, to avoid
+% double-counting its CPD. We assign node i to clique c if c is the "lightest" clique that
+% contains i's family, so it can accomodate its CPD.
+
+engine.clq_ass_to_node = zeros(1, N);
+for i=1:N
+  %c = clq_containing_nodes(engine, family(bnet.dag, i));
+  clqs_containing_family = find(all(B(:,family(bnet.dag, i)), 2)); % all selected columns must be 1
+  c = clqs_containing_family(argmin(w(clqs_containing_family)));  
+  engine.clq_ass_to_node(i) = c; 
+end
+
+% Make the jtree rooted, so there is a fixed message passing order.
+if strong
+  % the last clique is guaranteed to be a strong root
+  % engine.root_clq = length(engine.cliques);
+  
+  % --- 4/17/2010, by Wei Sun (George Mason University):
+  % It has been proved that the last clique is not necessary to be the  
+  % strong root, instead, a clique called interface clique, that contains
+  % all discrete parents and at least one continuous node from a connected
+  % continuous component in a CLG, is guaranteed to be a strong root.
+  engine.root_clq = findroot(bnet, engine.cliques) ;
+else
+  % jtree_dbn_inf_engine requires the root to contain the interface.
+  % This may conflict with the strong root requirement! *********** BUG *************
+  engine.root_clq = clq_containing_nodes(engine, root);
+  if engine.root_clq <= 0
+    error(['no clique contains ' num2str(root)]);
+  end
+end  
+
+[engine.jtree, engine.preorder, engine.postorder] = mk_rooted_tree(engine.jtree, engine.root_clq);
+
+% collect 
+engine.postorder_parents = cell(1,length(engine.postorder));
+for n=engine.postorder(:)'
+  engine.postorder_parents{n} = parents(engine.jtree, n);
+end
+% distribute
+engine.preorder_children = cell(1,length(engine.preorder));
+for n=engine.preorder(:)'
+  engine.preorder_children{n} = children(engine.jtree, n);
+end
+
+  
+
+%%%%%%%%
+
+function engine = init_fields()
+
+engine.jtree = [];
+engine.cliques = [];
+engine.separator = [];
+engine.cliques_bitv = [];
+engine.clique_weight = [];
+engine.clpot = [];
+engine.clq_ass_to_node = [];
+engine.root_clq = [];
+engine.preorder = [];
+engine.postorder = [];
+engine.preorder_children = [];
+engine.postorder_parents = [];
+engine.maximize = [];
+engine.evidence = [];
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/marginal_family.m
new file mode 100644
index 00000000..eff60ca2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/marginal_family.m
@@ -0,0 +1,11 @@
+function marginal = marginal_family(engine, i, add_ev)
+% MARGINAL_FAMILY Compute the marginal on the specified family (jtree)
+% marginal = marginal_family(engine, i)
+
+if nargin < 3, add_ev = 0; end
+assert(~add_ev);
+
+bnet = bnet_from_engine(engine);
+fam = family(bnet.dag, i);
+c = engine.clq_ass_to_node(i);
+marginal = pot_to_marginal(marginalize_pot(engine.clpot{c}, fam));
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..6413172c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/marginal_nodes.m
@@ -0,0 +1,22 @@
+function marginal = marginal_nodes(engine, query, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (jtree)
+% marginal = marginal_nodes(engine, query, add_ev)
+%
+% 'query' must be a subset of some clique; an error will be raised if not.
+% 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, add_ev = 0; end
+
+c = clq_containing_nodes(engine, query);
+if c == -1
+  error(['no clique contains ' num2str(query)]);
+end
+marginal = pot_to_marginal(marginalize_pot(engine.clpot{c}, query, engine.maximize));
+
+if add_ev
+  bnet = bnet_from_engine(engine);
+  %marginal = add_ev_to_dmarginal(marginal, engine.evidence, bnet.node_sizes);
+  marginal = add_evidence_to_gmarginal(marginal, engine.evidence, bnet.node_sizes, bnet.cnodes);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/set_fields.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/set_fields.m
new file mode 100644
index 00000000..e75cfa45
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_inf_engine/set_fields.m
@@ -0,0 +1,13 @@
+function engine = set_fields(engine, varargin)
+% SET_FIELDS Set the fields for a generic engine
+% engine = set_fields(engine, name/value pairs)
+%
+% e.g., engine = set_fields(engine, 'maximize', 1)
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'maximize', engine.maximize = args{i+1};
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Entries
new file mode 100644
index 00000000..932cb3b4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Entries
@@ -0,0 +1,5 @@
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/jtree_limid_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/Old////
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Repository
new file mode 100644
index 00000000..e8bf097c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@jtree_limid_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Entries
new file mode 100644
index 00000000..0b350b99
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_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_SS.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Repository
new file mode 100644
index 00000000..59988183
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@jtree_limid_inf_engine/Old
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_family.m
new file mode 100644
index 00000000..cd660ae4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_family.m
@@ -0,0 +1,59 @@
+function [m, pot] = marginal_family(engine, query)
+% MARGINAL_NODES Compute the marginal on the family of the specified node (jtree_limid)
+% [m, pot] = marginal_family(engine, query)
+%
+% query should be a single decision node, or [] (to compute global max expected utility)
+
+bnet = bnet_from_engine(engine);
+if isempty(query)
+  compute_meu = 1;
+  d = bnet.decision_nodes(1); % pick an arbitrary root to collect to
+  fam = []; % marginalize root pot down to a point
+else
+  compute_meu = 0;
+  d = query;
+  assert(myismember(d, bnet.decision_nodes));
+  fam = family(bnet.dag, d);
+end
+
+clpot = init_clpot(bnet, engine.cliques, engine.clq_ass_to_node, engine.evidence, engine.exclude);
+
+% collect to root (clique containing d) 
+C = length(engine.cliques);
+seppot = cell(C, C);    % separators are implicitely initialized to 1s
+for n=engine.postorder{d}(1:end-1)
+  for p=parents(engine.rooted_jtree{d}, n)
+    %clpot{p} = divide_by_pot(clpot{n}, seppot{p,n}); % dividing by 1 is redundant
+    seppot{p,n} = marginalize_pot(clpot{n}, engine.separator{p,n});
+    clpot{p} = multiply_by_pot(clpot{p}, seppot{p,n});
+  end
+end
+
+root = engine.clq_ass_to_node(d);
+assert(root == engine.postorder{d}(end));
+pot = marginalize_pot(clpot{root}, fam);
+m = pot_to_marginal(pot);
+
+%%%%%%%%%%%
+
+
+function clpot = init_clpot(bnet, cliques, clq_ass_to_node, evidence, exclude)
+
+% Set the clique potentials to all 1s
+C = length(cliques);
+clpot = cell(1, C);
+ns = bnet.node_sizes;
+for i=1:C
+  clpot{i} = upot(cliques{i}, ns(cliques{i}));
+end
+
+N = length(bnet.dag);
+nodes = mysetdiff(1:N, exclude);
+
+for n=nodes(:)'
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n);
+  c = clq_ass_to_node(n);
+  pot = convert_to_pot(bnet.CPD{e}, 'u', ns, fam, evidence);
+  clpot{c} = multiply_by_pot(clpot{c}, pot);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_nodes_SS.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_nodes_SS.m
new file mode 100644
index 00000000..2b6ff642
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/Old/marginal_nodes_SS.m
@@ -0,0 +1,52 @@
+function [pot, MEU] = marginal_nodes(engine, d)
+
+C = length(cliques);
+%clpot = init_clpot(limid, cliques, d, clq_ass_to_node);
+clpot = init_clpot(limid, cliques, [], clq_ass_to_node);
+
+% collect to root
+if 1
+  % HUGIN
+  seppot = cell(C, C);    % separators are implicitely initialized to 1s
+  for n=postorder{di}(1:end-1)
+    for p=parents(rooted_jtree{di}, 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});
+      clpot{p} = multiply_by_pot(clpot{p}, seppot{p,n});
+    end
+  end
+else
+  % Shafer-Shenoy
+  msg = cell(C,C);
+  for n=postorder{di}(1:end-1)
+    for c=children(rooted_jtree{di}, n)
+      clpot{n} = multiply_by_pot(clpot{n}, msg{c,n});
+    end
+    p = parents(rooted_jtree{di}, n);
+    %msg{n,p} = marginalize_pot(clpot{n}, cliques{p});
+    msg{n,p} = marginalize_pot(clpot{n}, separator{n,p});
+  end
+  root = clq_ass_to_node(d);
+  n=postorder{di}(end);
+  assert(n == root);
+  for c=children(rooted_jtree{di}, n)
+    clpot{n} = multiply_by_pot(clpot{n}, msg{c,n});
+  end
+end	
+
+fam = family(limid.dag, d);
+pot = marginalize_pot(clpot{root}, fam);
+
+%%%%%%%
+jpot = compute_joint_pot_limid(limid);
+pot2 = marginalize_pot(jpot, fam);
+assert(approxeq_pot(pot, pot2))
+%%%%%%
+
+[policy, score] = extract_policy(pot);
+
+e = limid.equiv_class(d);
+limid.CPD{e} = set_params(limid.CPD{e}, 'policy', policy);
+
+  
+    
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..5d874803
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/enter_evidence.m
@@ -0,0 +1,28 @@
+function engine = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (jtree_limid)
+% engine = enter_evidence(engine, evidence, ...)
+%
+% evidence{i} = [] if if X(i) is hidden, and otherwise contains its observed value.
+%
+% The list below gives optional arguments [default value in brackets].      
+%
+% exclude - list of nodes whose potential will not be included in the joint [ [] ]
+%
+% e.g., engine = enter_evidence(engine, ev, 'exclude', 3)
+
+exclude = [];
+
+if nargin >= 3
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'exclude', exclude = args{i+1};
+     otherwise,
+      error(['invalid argument name ' args{i}]);
+    end
+  end
+end
+  
+engine.exclude = exclude;
+engine.evidence = evidence;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/jtree_limid_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/jtree_limid_inf_engine.m
new file mode 100644
index 00000000..83dd89ef
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/jtree_limid_inf_engine.m
@@ -0,0 +1,52 @@
+function engine = jtree_limid_inf_engine(bnet)
+% JTREE_LIMID_INF_ENGINE Make a junction tree engine for use by solve_limid
+% engine = jtree_limid_inf_engine(bnet)
+%
+% This engine is designed to compute marginals on decision nodes
+
+
+MG = moralize(bnet.dag);
+% We do not remove the utility nodes, because that complicates the book-keeping.
+% Leaving them in will not introduce any un-necessary triangulation arcs, because they are always leaves.
+% Also, since utility nodes have size 1, they do not increase the size of the potentials.
+
+ns = bnet.node_sizes;
+elim_order = best_first_elim_order(MG, ns);
+[MTG, engine.cliques]  = triangulate(MG, elim_order);
+[engine.jtree, root, B, w] = cliques_to_jtree(engine.cliques, ns);
+
+% A node can be a member of many cliques, but is assigned to exactly one, to avoid
+% double-counting its CPD. We assign node i to clique c if c is the "lightest" clique that
+% contains i's family, so it can accomodate its CPD.
+N = length(bnet.dag);
+engine.clq_ass_to_node = zeros(1, N);
+for i=1:N
+  clqs_containing_family = find(all(B(:,family(bnet.dag, i)), 2)); % all selected columns must be 1
+  c = clqs_containing_family(argmin(w(clqs_containing_family)));  
+  engine.clq_ass_to_node(i) = c; 
+end
+
+
+% Compute the separators between connected cliques.
+[is,js] = find(engine.jtree > 0);
+num_cliques = length(engine.cliques);
+engine.separator = cell(num_cliques, num_cliques);
+for k=1:length(is)
+  i = is(k); j = js(k);
+  engine.separator{i,j} = find(B(i,:) & B(j,:)); % intersect(cliques{i}, cliques{j});
+end
+
+
+% create |D| different rooted jtree's
+engine.rooted_jtree = cell(1, N);
+engine.preorder = cell(1, N);
+engine.postorder = cell(1, N);
+for d=bnet.decision_nodes(:)'
+  root = engine.clq_ass_to_node(d);
+  [engine.rooted_jtree{d}, engine.preorder{d}, engine.postorder{d}] = mk_rooted_tree(engine.jtree, root);
+end
+
+engine.exclude = [];
+engine.evidence = [];
+
+engine = class(engine, 'jtree_limid_inf_engine', inf_engine(bnet));
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_family.m
new file mode 100644
index 00000000..dd3bf95e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_family.m
@@ -0,0 +1,52 @@
+function [m, pot] = marginal_family(engine, query)
+% MARGINAL_NODES Compute the marginal on the family of the specified node (jtree_limid)
+% [m, pot] = marginal_family(engine, query)
+%
+% query should be a single decision node
+
+bnet = bnet_from_engine(engine);
+d = query;
+assert(myismember(d, bnet.decision_nodes));
+fam = family(bnet.dag, d);
+
+clpot = init_clpot(bnet, engine.cliques, engine.clq_ass_to_node, engine.evidence, engine.exclude);
+
+% collect to root (clique containing d) 
+C = length(engine.cliques);
+seppot = cell(C, C);    % separators are implicitely initialized to 1s
+for n=engine.postorder{d}(1:end-1)
+  for p=parents(engine.rooted_jtree{d}, n)
+    %clpot{p} = divide_by_pot(clpot{n}, seppot{p,n}); % dividing by 1 is redundant
+    seppot{p,n} = marginalize_pot(clpot{n}, engine.separator{p,n});
+    clpot{p} = multiply_by_pot(clpot{p}, seppot{p,n});
+  end
+end
+
+root = engine.clq_ass_to_node(d);
+assert(root == engine.postorder{d}(end));
+pot = marginalize_pot(clpot{root}, fam);
+m = pot_to_marginal(pot);
+
+%%%%%%%%%%%
+
+
+function clpot = init_clpot(bnet, cliques, clq_ass_to_node, evidence, exclude)
+
+% Set the clique potentials to all 1s
+C = length(cliques);
+clpot = cell(1, C);
+ns = bnet.node_sizes;
+for i=1:C
+  clpot{i} = upot(cliques{i}, ns(cliques{i}));
+end
+
+N = length(bnet.dag);
+nodes = mysetdiff(1:N, exclude);
+
+for n=nodes(:)'
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n);
+  c = clq_ass_to_node(n);
+  pot = convert_to_pot(bnet.CPD{e}, 'u', fam(:), evidence);
+  clpot{c} = multiply_by_pot(clpot{c}, pot);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..d3700270
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_limid_inf_engine/marginal_nodes.m
@@ -0,0 +1,17 @@
+function [m, pot] = marginal_nodes(engine, query)
+% MARGINAL_NODES Compute the marginal on the specified nodes (jtree_limid)
+% [m, pot] = marginal_nodes(engine, query)
+%
+% query should be a subset of a family of a decision node
+
+if isempty(query)
+  bnet = bnet_from_engine(engine);
+  d = bnet.decision_nodes(1); % pick an arbitrary decision node
+  [dummy, big_pot] = marginal_family(engine, d); 
+else
+  [dummy, big_pot] = marginal_family(engine, query);
+end
+pot = marginalize_pot(big_pot, query);
+m = pot_to_marginal(pot);
+
+  
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/CVS/Entries
new file mode 100644
index 00000000..33ee0f34
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/CVS/Entries
@@ -0,0 +1,4 @@
+/enter_evidence.m/1.1.1.1/Mon Jun 17 20:30:02 2002//
+/find_mpe.m/1.1.1.1/Mon Jun 17 20:29:40 2002//
+/jtree_mnet_inf_engine.m/1.1.1.1/Sat Jan 18 22:13:32 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/CVS/Repository
new file mode 100644
index 00000000..2deff959
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@jtree_mnet_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..97546f4b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/enter_evidence.m
@@ -0,0 +1,82 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (jtree)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i} = [] if X(i) 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]
+%
+% soft    - a cell array of soft/virtual evidence;
+%           soft{i} is a prob. distrib. over i's values, or [] [ cell(1,N) ]
+%
+% e.g., engine = enter_evidence(engine, ev, 'soft', soft_ev)
+
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes(:);
+N = length(bnet.dag);
+
+engine.evidence = evidence; % store this for marginal_nodes with add_ev option
+engine.maximize = 0;
+
+% set default params
+exclude = [];
+soft_evidence = cell(1,N);
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'soft',    soft_evidence = args{i+1}; 
+   otherwise,  
+    error(['invalid argument name ' args{i}]);       
+  end
+end
+
+onodes = find(~isemptycell(evidence));
+hnodes = find(isemptycell(evidence));
+pot_type = determine_pot_type(bnet, onodes);
+ if strcmp(pot_type, 'cg')
+  check_for_cd_arcs(onodes, bnet.cnodes, bnet.dag);
+end
+
+% Evaluate CPDs with evidence, and convert to potentials  
+pot = cell(1, N);
+for n=1:N
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n);
+  if isempty(bnet.CPD{e})
+    error(['must define CPD ' num2str(e)])
+  else
+    pot{n} = convert_to_pot(bnet.CPD{e}, pot_type, fam(:), evidence);
+  end
+end
+clqs = engine.clq_ass_to_node(1:N);
+
+% soft evidence
+soft_nodes = find(~isemptycell(soft_evidence));
+S = length(soft_nodes);
+if S > 0
+  assert(pot_type == 'd');
+  assert(mysubset(soft_nodes, bnet.dnodes));
+end
+for i=1:S
+  n = soft_nodes(i);
+  pot{end+1} = dpot(n, ns(n), soft_evidence{n});
+end
+clqs = [clqs engine.clq_ass_to_node(soft_nodes)]; 
+
+
+[clpot, seppot] = init_pot(engine, clqs, pot, pot_type, onodes);
+[clpot, seppot] = collect_evidence(engine, clpot, seppot);
+[clpot, seppot] = distribute_evidence(engine, clpot, seppot);
+
+C = length(clpot);
+ll = zeros(1, C);
+for i=1:C
+  [clpot{i}, ll(i)] = normalize_pot(clpot{i});
+end
+loglik = ll(1); % we can extract the likelihood from any clique
+
+engine.clpot = clpot;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/find_mpe.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/find_mpe.m
new file mode 100644
index 00000000..f5c04ba8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/find_mpe.m
@@ -0,0 +1,71 @@
+function mpe = find_mpe(engine, evidence, varargin)
+% FIND_MPE Find the most probable explanation of the data (assignment to the hidden nodes)
+% function mpe = find_mpe(engine, evidence,...)
+%
+% evidence{i} = [] if X(i) 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]
+%
+% soft    - a cell array of soft/virtual evidence;
+%           soft{i} is a prob. distrib. over i's values, or [] [ cell(1,N) ]
+%
+
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes(:);
+N = length(bnet.dag);
+
+engine.evidence = evidence;
+  
+% set default params
+exclude = [];
+soft_evidence = cell(1,N);
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'soft',    soft_evidence = args{i+1}; 
+   otherwise,  
+    error(['invalid argument name ' args{i}]);       
+  end
+end
+engine.maximize = 1;
+
+onodes = find(~isemptycell(evidence));
+hnodes = find(isemptycell(evidence));
+pot_type = determine_pot_type(bnet, onodes);
+ if strcmp(pot_type, 'cg')
+  check_for_cd_arcs(onodes, bnet.cnodes, bnet.dag);
+end
+
+hard_nodes = 1:N;
+soft_nodes = find(~isemptycell(soft_evidence));
+S = length(soft_nodes);
+if S > 0
+  assert(pot_type == 'd');
+  assert(mysubset(soft_nodes, bnet.dnodes));
+end
+ 
+% Evaluate CPDs with evidence, and convert to potentials  
+pot = cell(1, N+S);
+for n=1:N
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n);
+  if isempty(bnet.CPD{e})
+    error(['must define CPD ' num2str(e)])
+  else
+    pot{n} = convert_to_pot(bnet.CPD{e}, pot_type, fam(:), evidence);
+  end
+end
+
+for i=1:S
+  n = soft_nodes(i);
+  pot{N+i} = dpot(n, ns(n), soft_evidence{n});
+end
+clqs = engine.clq_ass_to_node([hard_nodes soft_nodes]); 
+
+[clpot, seppot] = init_pot(engine, clqs, pot, pot_type, onodes);
+[clpot, seppot] = collect_evidence(engine, clpot, seppot);
+mpe = find_max_config(engine, clpot, seppot);
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/jtree_mnet_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/jtree_mnet_inf_engine.m
new file mode 100644
index 00000000..ff21ae47
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_mnet_inf_engine/jtree_mnet_inf_engine.m
@@ -0,0 +1,101 @@
+function engine = jtree_mnet_inf_engine(model, varargin)
+% JTREE_MNET_INF_ENGINE Junction tree inference engine for Markov nets
+% engine = jtree_inf_engine(mnet, ...)
+%
+
+% set default params
+N = length(mnet.graph);
+root = N;
+
+engine = init_fields;
+engine = class(engine, 'jtree_mnet_inf_engine', inf_engine(bnet));
+
+onodes = bnet.observed;
+if is_mnet(bnet)
+  MG = bnet.graph;
+else
+  error('should be a mnet')
+end
+
+%[engine.jtree, dummy, engine.cliques, B, w, elim_order, moral_edges, fill_in_edges, strong] = ...
+%    dag_to_jtree(bnet, onodes, stages, clusters);
+
+porder = determine_elim_constraints(bnet, onodes);
+strong = ~isempty(porder);
+ns = bnet.node_sizes(:);
+ns(onodes) = 1; % observed nodes have only 1 possible value
+[engine.jtree, root2, engine.cliques, B, w] = ...
+    graph_to_jtree(MG, ns, porder, stages, clusters);
+
+engine.cliques_bitv = B;
+engine.clique_weight = w;
+C = length(engine.cliques);
+engine.clpot = cell(1,C);
+
+% Compute the separators between connected cliques.
+[is,js] = find(engine.jtree > 0);
+engine.separator = cell(C,C);
+for k=1:length(is)
+  i = is(k); j = js(k);
+  engine.separator{i,j} = find(B(i,:) & B(j,:)); % intersect(cliques{i}, cliques{j});
+end
+
+% A node can be a member of many cliques, but is assigned to exactly one, to avoid
+% double-counting its CPD. We assign node i to clique c if c is the "lightest" clique that
+% contains i's family, so it can accomodate its CPD.
+
+engine.clq_ass_to_node = zeros(1, N);
+for i=1:N
+  %c = clq_containing_nodes(engine, family(bnet.dag, i));
+  clqs_containing_family = find(all(B(:,family(bnet.dag, i)), 2)); % all selected columns must be 1
+  c = clqs_containing_family(argmin(w(clqs_containing_family)));  
+  engine.clq_ass_to_node(i) = c; 
+end
+
+% Make the jtree rooted, so there is a fixed message passing order.
+if strong
+  % the last clique is guaranteed to be a strong root
+  engine.root_clq = length(engine.cliques);
+else
+  % jtree_dbn_inf_engine requires the root to contain the interface.
+  % This may conflict with the strong root requirement! *********** BUG *************
+  engine.root_clq = clq_containing_nodes(engine, root);
+  if engine.root_clq <= 0
+    error(['no clique contains ' num2str(root)]);
+  end
+end  
+
+[engine.jtree, engine.preorder, engine.postorder] = mk_rooted_tree(engine.jtree, engine.root_clq);
+
+% collect 
+engine.postorder_parents = cell(1,length(engine.postorder));
+for n=engine.postorder(:)'
+  engine.postorder_parents{n} = parents(engine.jtree, n);
+end
+% distribute
+engine.preorder_children = cell(1,length(engine.preorder));
+for n=engine.preorder(:)'
+  engine.preorder_children{n} = children(engine.jtree, n);
+end
+
+  
+
+%%%%%%%%
+
+function engine = init_fields()
+
+engine.jtree = [];
+engine.cliques = [];
+engine.separator = [];
+engine.cliques_bitv = [];
+engine.clique_weight = [];
+engine.clpot = [];
+engine.clq_ass_to_node = [];
+engine.root_clq = [];
+engine.preorder = [];
+engine.postorder = [];
+engine.preorder_children = [];
+engine.postorder_parents = [];
+engine.maximize = [];
+engine.evidence = [];
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Entries
new file mode 100644
index 00000000..cc6f3f5b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Entries
@@ -0,0 +1,12 @@
+/cliques_from_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/clq_containing_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/collect_evidence.c/1.1.1.1/Wed May 29 15:59:56 2002//
+/distribute_evidence.c/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/Wed May 29 15:59:56 2002//
+/init_pot.c/1.1.1.1/Wed May 29 15:59:56 2002//
+/jtree_sparse_inf_engine.m/1.1.1.1/Sat Jan 18 22:11:32 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//
+/set_fields.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Entries.Log
new file mode 100644
index 00000000..61d96f3f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/old////
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Repository
new file mode 100644
index 00000000..ccd02123
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@jtree_sparse_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/cliques_from_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/cliques_from_engine.m
new file mode 100644
index 00000000..cd9d871d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/cliques_from_engine.m
@@ -0,0 +1,5 @@
+function cliques = cliques_from_engine(engine)
+% CLIQUES_FROM_ENGINE Return the cliques stored inside the inf. engine (jtree)
+% cliques = cliques_from_engine(engine)
+
+cliques = engine.cliques;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/clq_containing_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/clq_containing_nodes.m
new file mode 100644
index 00000000..8904fa49
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/clq_containing_nodes.m
@@ -0,0 +1,24 @@
+function c = clq_containing_nodes(engine, nodes, fam)
+% CLQ_CONTAINING_NODES Find the lightest clique (if any) that contains the set of nodes
+% c = clq_containing_nodes(engine, nodes, family)
+%
+% If the optional 'family' argument is specified, it means nodes = family(nodes(end)).
+% (This is useful since clq_ass_to_node is not accessible to outsiders.)
+% Returns c=-1 if there is no such clique.
+
+if nargin < 3, fam = 0; else fam = 1; end
+
+if length(nodes)==1
+  c = engine.clq_ass_to_node(nodes(1));
+%elseif fam
+%  c = engine.clq_ass_to_node(nodes(end));
+else
+  B = engine.cliques_bitv;
+  w = engine.clique_weight;
+  clqs = find(all(B(:,nodes), 2)); % all selected columns must be 1
+  if isempty(clqs)
+    c = -1;
+  else
+    c = clqs(argmin(w(clqs)));     
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/collect_evidence.c b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/collect_evidence.c
new file mode 100644
index 00000000..8480c701
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/collect_evidence.c
@@ -0,0 +1,634 @@
+/* C mex for collect_evidence.c in @jtree_sparse_inf_engine directory */
+/* File enter_evidence.m in directory @jtree_sparse_inf_engine call it*/
+
+/******************************************/
+/* collect_evidence has 3 input & 2 output*/
+/* engine                                 */
+/* clpot                                  */
+/* seppot                                 */
+/*                                        */
+/* clpot                                  */
+/* seppot                                 */
+/******************************************/
+
+#include <math.h>
+#include <stdlib.h>
+#include "mex.h"
+
+int compare(const void* src1, const void* src2){
+	int i1 = *(int*)src1 ;
+	int i2 = *(int*)src2 ;
+	return i1-i2 ;
+}
+
+void ind_subv(int index, const int *cumprod, int n, int *bsubv){
+	int i;
+
+	for (i = n-1; i >= 0; i--) {
+		bsubv[i] = ((int)floor(index / cumprod[i]));
+		index = index % cumprod[i];
+	}
+}
+
+int subv_ind(const int n, const int *cumprod, const int *subv){
+	int i, index=0;
+
+	for(i=0; i<n; i++){
+		index += subv[i] * cumprod[i];
+	}
+	return index;
+}
+
+void compute_fixed_weight(int *weight, const double *pbSize, const int *dmask, const int *bCumprod, const int ND, const int diffdim){
+	int i, j;
+	int *eff_cumprod, *subv, *diffsize, *diff_cumprod;
+
+	subv = malloc(diffdim * sizeof(int));
+	eff_cumprod = malloc(diffdim * sizeof(int));
+	diffsize = malloc(diffdim * sizeof(int));
+	diff_cumprod = malloc(diffdim * sizeof(int));
+	for(i=0; i<diffdim; i++){
+		eff_cumprod[i] = bCumprod[dmask[i]];
+		diffsize[i] = (int)pbSize[dmask[i]];
+	}
+	diff_cumprod[0] = 1;
+	for(i=0; i<diffdim-1; i++){
+		diff_cumprod[i+1] = diff_cumprod[i] * diffsize[i];
+	}
+	for(i=0; i<ND; i++){
+		ind_subv(i, diff_cumprod, diffdim, subv);
+		weight[i] = 0;
+		for(j=0; j<diffdim; j++){
+			weight[i] += eff_cumprod[j] * subv[j];
+		}
+	}
+	free(eff_cumprod);
+	free(subv);
+	free(diffsize);
+	free(diff_cumprod);
+}
+
+void reset_nzmax(mxArray *spArray, const int old_nzmax, const int new_nzmax){
+	double *ptr;
+	void   *newptr;
+	int    *ir, *jc;
+	int    nbytes;
+
+	if(new_nzmax == old_nzmax) return;
+	nbytes = new_nzmax * sizeof(*ptr);
+	ptr = mxGetPr(spArray);
+	newptr = mxRealloc(ptr, nbytes);
+	mxSetPr(spArray, newptr);
+	nbytes = new_nzmax * sizeof(*ir);
+	ir = mxGetIr(spArray);
+	newptr = mxRealloc(ir, nbytes);
+	mxSetIr(spArray, newptr);
+	jc = mxGetJc(spArray);
+	jc[0] = 0;
+	jc[1] = new_nzmax;
+	mxSetNzmax(spArray, new_nzmax);
+}
+
+mxArray* convert_ill_table_to_sparse(const double *Table, const int *sequence, const int nzCounts, const int N){
+	mxArray *spTable;
+	int     i, temp, *irs, *jcs, count=0;
+	double  *sr;
+
+	spTable = mxCreateSparse(N, 1, nzCounts, mxREAL);
+    sr  = mxGetPr(spTable);
+    irs = mxGetIr(spTable);
+    jcs = mxGetJc(spTable);
+
+	jcs[0] = 0;
+	jcs[1] = nzCounts;
+
+	for(i=0; i<nzCounts; i++){
+		irs[i] = sequence[count];
+		count++;
+		temp = sequence[count];
+		sr[i] = Table[temp];
+		count++;
+	}
+	return spTable;
+}
+
+void multiply_null_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, count1, match, temp, bdim, sdim, diffdim, NB, NS, ND, NZB, NZS, bindex, sindex, nzCounts=0;
+	int     *samemask, *diffmask, *sir, *sjc, *bCumprod, *sCumprod, *ssubv, *sequence, *weight;
+	double  *bigTable, *pbDomain, *psDomain, *pbSize, *psSize, *spr, *bpr;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	if(sdim == 0){
+		pTemp = mxCreateSparse(NB, 1, NB, mxREAL);
+		mxSetField(bigPot, 0, "T", pTemp);
+		bpr = mxGetPr(pTemp);
+		sir = mxGetIr(pTemp);
+		sjc = mxGetJc(pTemp);
+		sjc[0] = 0;
+		sjc[1] = NB;
+		for(i=0; i<NB; i++){
+			bpr[i] = *spr;
+			sir[i] = i;
+		}	
+		return;
+	}
+
+	NS = 1;
+	for(i=0; i<sdim; i++){
+		NS *= (int)psSize[i];
+	}
+	ND = NB / NS;
+
+	if(ND == 1){
+		pTemp1 = mxGetField(smallPot, 0, "T");
+		pTemp = mxDuplicateArray(pTemp1);
+		mxSetField(bigPot, 0, "T", pTemp);
+		return;
+	}
+
+
+	NZB = ND * NZS;
+
+	diffdim = bdim - sdim;
+	sequence = malloc(NZB * 2 * sizeof(int));
+	bigTable = malloc(NZB * sizeof(double));
+	samemask = malloc(sdim * sizeof(int));
+	diffmask = malloc(diffdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	weight = malloc(ND * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	count1 = 0;
+	for(i=0; i<bdim; i++){
+		match = 0;
+		for(j=0; j<sdim; j++){
+			if(pbDomain[i] == psDomain[j]){
+				samemask[count] = i;
+				match = 1;
+				count++;
+				break;
+			}
+		}
+		if(match == 0){
+			diffmask[count1] = i; 
+			count1++;
+		}
+	}
+
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	count = 0;
+	compute_fixed_weight(weight, pbSize, diffmask, bCumprod, ND, diffdim);
+	for(i=0; i<NZS; i++){
+		sindex = sir[i];
+		ind_subv(sindex, sCumprod, sdim, ssubv);
+		temp = 0;
+		for(j=0; j<sdim; j++){
+			temp += ssubv[j] * bCumprod[samemask[j]];
+		}
+		for(j=0; j<ND; j++){
+			bindex = weight[j] + temp;
+			bigTable[nzCounts] = spr[i];
+			sequence[count] = bindex;
+			count++;
+			sequence[count] = nzCounts;
+			nzCounts++;
+			count++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	qsort(sequence, nzCounts, sizeof(int) * 2, compare);
+	pTemp = convert_ill_table_to_sparse(bigTable, sequence, nzCounts, NB);
+	mxSetField(bigPot, 0, "T", pTemp);
+
+	free(sequence); 
+	free(bigTable);
+	free(samemask);
+	free(diffmask);
+	free(bCumprod);
+	free(sCumprod);
+	free(weight);
+	free(ssubv);
+}
+
+void multiply_spPot_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, bdim, sdim, NB, NZB, NZS, position, bindex, sindex, nzCounts=0;
+	int     *mask, *result, *bir, *sir, *rir, *bjc, *sjc, *rjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, *rpr;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	if(sdim == 0){
+		for(i=0; i<NZB; i++){
+			bpr[i] *= *spr;
+		}	
+		return;
+	}
+
+	pTemp1 = mxCreateSparse(NB, 1, NZB, mxREAL);
+	rpr = mxGetPr(pTemp1);
+	rir = mxGetIr(pTemp1);
+	rjc = mxGetJc(pTemp1);
+	rjc[0] = 0;
+	rjc[1] = NZB;
+
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sir, NZS, sizeof(int), compare);
+		if(result){
+			position = result - sir;
+			rpr[nzCounts] = bpr[i] * spr[position];
+			rir[nzCounts] = bindex;
+			nzCounts++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	reset_nzmax(pTemp1, NZB, nzCounts);
+	mxSetField(bigPot, 0, "T", pTemp1);
+
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+mxArray* marginal_null_to_spPot(const mxArray *bigPot, const mxArray *sDomain, const int maximize){
+	int     i, j, count, bdim, sdim, NB, NS, ND;
+	int     *mask, *sir, *sjc;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *spr;
+	mxArray *pTemp, *smallPot;
+	const char *field_names[] = {"domain", "T", "sizes"};
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	psDomain = mxGetPr(sDomain);
+	sdim = mxGetNumberOfElements(sDomain);
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+
+	smallPot = mxCreateStructMatrix(1, 1, 3, field_names);
+	pTemp = mxDuplicateArray(sDomain);
+	mxSetField(smallPot, 0, "domain", pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	if(sdim == 0){
+		pTemp = mxCreateSparse(1, 1, 1, mxREAL);
+		mxSetField(smallPot, 0, "T", pTemp);
+		spr = mxGetPr(pTemp);
+		sir = mxGetIr(pTemp);
+		sjc = mxGetJc(pTemp);
+		*spr = 0;
+		*sir = 0;
+		sjc[0] = 0;
+		sjc[1] = 1;
+		if(maximize) *spr = 1;
+		else *spr = NB;
+
+		pTemp = mxCreateDoubleMatrix(1, 1, mxREAL);
+		*mxGetPr(pTemp) = 1;
+		mxSetField(smallPot, 0, "sizes", pTemp);
+		return smallPot;
+	}
+
+	mask = malloc(sdim * sizeof(int));
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	pTemp = mxCreateDoubleMatrix(1, count, mxREAL);
+	psSize = mxGetPr(pTemp);
+	NS = 1;
+	for(i=0; i<count; i++){
+		psSize[i] = pbSize[mask[i]];
+		NS *= (int)psSize[i];
+	}
+	mxSetField(smallPot, 0, "sizes", pTemp);
+
+	ND = NB / NS;
+
+	pTemp = mxCreateSparse(NS, 1, NS, mxREAL);
+	mxSetField(smallPot, 0, "T", pTemp);
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	if(maximize){
+		for(i=0; i<NS; i++){
+			spr[i] = 1;
+			sir[i] = i;
+		}
+	}
+	else{
+		for(i=0; i<NS; i++){
+			spr[i] = ND;
+			sir[i] = i;
+		}
+	}
+	sjc[0] = 0;
+	sjc[1] = NS;
+
+	free(mask);
+	return smallPot;
+}
+
+mxArray* marginal_spPot_to_spPot(const mxArray *bigPot, const mxArray *sDomain, const int maximize){
+	int     i, j, count, bdim, sdim, NB, NS, NZB, position, bindex, sindex, nzCounts=0;
+	int     *mask, *sequence, *result, *bir, *bjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *sTable, *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr;
+	mxArray *pTemp, *smallPot;
+	const char *field_names[] = {"domain", "T", "sizes"};
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	psDomain = mxGetPr(sDomain);
+	sdim = mxGetNumberOfElements(sDomain);
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	smallPot = mxCreateStructMatrix(1, 1, 3, field_names);
+	pTemp = mxDuplicateArray(sDomain);
+	mxSetField(smallPot, 0, "domain", pTemp);
+
+	if(sdim == 0){
+		pTemp = mxCreateSparse(1, 1, 1, mxREAL);
+		mxSetField(smallPot, 0, "T", pTemp);
+		spr = mxGetPr(pTemp);
+		bir = mxGetIr(pTemp);
+		bjc = mxGetJc(pTemp);
+		*spr = 0;
+		*bir = 0;
+		bjc[0] = 0;
+		bjc[1] = 1;
+		if(maximize){
+			for(i=0; i<NZB; i++){
+				*spr = (*spr < bpr[i])? bpr[i] : *spr;
+			}
+		}
+		else{
+			for(i=0; i<NZB; i++){
+				*spr += bpr[i];
+			}
+		}
+
+		pTemp = mxCreateDoubleMatrix(1, 1, mxREAL);
+		*mxGetPr(pTemp) = 1;
+		mxSetField(smallPot, 0, "sizes", pTemp);
+		return smallPot;
+	}
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	mask = malloc(sdim * sizeof(int));
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	pTemp = mxCreateDoubleMatrix(1, count, mxREAL);
+	psSize = mxGetPr(pTemp);
+	NS = 1;
+	for(i=0; i<count; i++){
+		psSize[i] = pbSize[mask[i]];
+		NS *= (int)psSize[i];
+	}
+	mxSetField(smallPot, 0, "sizes", pTemp);
+
+
+	sTable = malloc(NZB * sizeof(double));
+	sequence = malloc(NZB * 2 * sizeof(double));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	for(i=0; i<NZB; i++)sTable[i] = 0;
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	count = 0;
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sequence, nzCounts, sizeof(int)*2, compare);
+		if(result){
+			position = (result - sequence) / 2;
+			if(maximize) 
+				sTable[position] = (sTable[position] < bpr[i]) ? bpr[i] : sTable[position];
+			else sTable[position] += bpr[i];
+		}
+		else {
+			if(maximize) 
+				sTable[nzCounts] = (sTable[nzCounts] < bpr[i]) ? bpr[i] : sTable[nzCounts];
+			else sTable[nzCounts] += bpr[i];
+			sequence[count] = sindex;
+			count++;
+			sequence[count] = nzCounts;
+			nzCounts++;
+			count++;
+		}
+	}
+	
+	qsort(sequence, nzCounts, sizeof(int) * 2, compare);
+	pTemp = convert_ill_table_to_sparse(sTable, sequence, nzCounts, NS);
+	mxSetField(smallPot, 0, "T", pTemp);
+
+	free(sTable);
+	free(sequence);
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+
+	return smallPot;
+}
+
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int     i, n, p, np, pn, loop, loops, nCliques, temp, maximize;
+	int     *collect_order;
+	double  *pr, *pr1;
+	mxArray *pTemp, *pTemp1, *pPostP, *pClpot, *pSeppot, *pSeparator;
+
+	pTemp = mxGetField(prhs[0], 0, "cliques");
+	nCliques = mxGetNumberOfElements(pTemp);
+	loops = nCliques - 1;
+	pTemp = mxGetField(prhs[0], 0, "maximize");
+	maximize = (int)mxGetScalar(pTemp);
+	pSeparator = mxGetField(prhs[0], 0, "separator");
+
+	collect_order = malloc(2 * loops * sizeof(int));
+
+	pTemp = mxGetField(prhs[0], 0, "postorder");
+	pr = mxGetPr(pTemp);
+	pPostP = mxGetField(prhs[0], 0, "postorder_parents");
+	for(i=0; i<loops; i++){
+		temp = (int)pr[i] - 1;
+		pTemp = mxGetCell(pPostP, temp);
+		pr1 = mxGetPr(pTemp);
+		collect_order[i] = (int)pr1[0] - 1;
+		collect_order[i+loops] = temp;
+	}
+
+	plhs[0] = mxDuplicateArray(prhs[1]);
+	plhs[1] = mxDuplicateArray(prhs[2]);
+
+	for(loop=0; loop<loops; loop++){
+		p = collect_order[loop];
+		n = collect_order[loop+loops];
+		np = p * nCliques + n;
+		pn = n * nCliques + p;
+		pClpot = mxGetCell(plhs[0], n);
+		pTemp1 = mxGetField(pClpot, 0, "T");
+		pTemp = mxGetCell(pSeparator, pn);
+		if(pTemp1)
+			pSeppot = marginal_spPot_to_spPot(pClpot, pTemp, maximize);
+		else pSeppot = marginal_null_to_spPot(pClpot, pTemp, maximize);
+		mxSetCell(plhs[1], pn, pSeppot);
+
+		pClpot = mxGetCell(plhs[0], p);
+		pTemp1 = mxGetField(pClpot, 0, "T");
+		if(pTemp1)
+			multiply_spPot_by_spPot(pClpot, pSeppot);
+		else multiply_null_by_spPot(pClpot, pSeppot);
+	}
+	free(collect_order);
+}
+	
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/distribute_evidence.c b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/distribute_evidence.c
new file mode 100644
index 00000000..8147c403
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/distribute_evidence.c
@@ -0,0 +1,618 @@
+/* C mex for distribute_evidence.c in @jtree_sparse_inf_engine directory*/
+/* File enter_evidence.m in directory @jtree_sparse_inf_engine call it  */
+
+/*********************************************/
+/* distribute_evidence has 3 input & 2 output*/
+/* engine                                    */
+/* clpot                                     */
+/* seppot                                    */
+/*                                           */
+/* clpot                                     */
+/* seppot                                    */
+/*********************************************/
+
+#include <math.h>
+#include <stdlib.h>
+#include "mex.h"
+
+int compare(const void* src1, const void* src2){
+	int i1 = *(int*)src1 ;
+	int i2 = *(int*)src2 ;
+	return i1-i2 ;
+}
+
+void ind_subv(int index, const int *cumprod, int n, int *bsubv){
+	int i;
+
+	for (i = n-1; i >= 0; i--) {
+		bsubv[i] = ((int)floor(index / cumprod[i]));
+		index = index % cumprod[i];
+	}
+}
+
+int subv_ind(const int n, const int *cumprod, const int *subv){
+	int i, index=0;
+
+	for(i=0; i<n; i++){
+		index += subv[i] * cumprod[i];
+	}
+	return index;
+}
+
+void reset_nzmax(mxArray *spArray, const int old_nzmax, const int new_nzmax){
+	double *ptr;
+	void   *newptr;
+	int    *ir, *jc;
+	int    nbytes;
+
+	if(new_nzmax == old_nzmax) return;
+	nbytes = new_nzmax * sizeof(*ptr);
+	ptr = mxGetPr(spArray);
+	newptr = mxRealloc(ptr, nbytes);
+	mxSetPr(spArray, newptr);
+	nbytes = new_nzmax * sizeof(*ir);
+	ir = mxGetIr(spArray);
+	newptr = mxRealloc(ir, nbytes);
+	mxSetIr(spArray, newptr);
+	jc = mxGetJc(spArray);
+	jc[0] = 0;
+	jc[1] = new_nzmax;
+	mxSetNzmax(spArray, new_nzmax);
+}
+
+void compute_fixed_weight(int *weight, const double *pbSize, const int *dmask, const int *bCumprod, const int ND, const int diffdim){
+	int i, j;
+	int *eff_cumprod, *subv, *diffsize, *diff_cumprod;
+
+	subv = malloc(diffdim * sizeof(int));
+	eff_cumprod = malloc(diffdim * sizeof(int));
+	diffsize = malloc(diffdim * sizeof(int));
+	diff_cumprod = malloc(diffdim * sizeof(int));
+	for(i=0; i<diffdim; i++){
+		eff_cumprod[i] = bCumprod[dmask[i]];
+		diffsize[i] = (int)pbSize[dmask[i]];
+	}
+	diff_cumprod[0] = 1;
+	for(i=0; i<diffdim-1; i++){
+		diff_cumprod[i+1] = diff_cumprod[i] * diffsize[i];
+	}
+	for(i=0; i<ND; i++){
+		ind_subv(i, diff_cumprod, diffdim, subv);
+		weight[i] = 0;
+		for(j=0; j<diffdim; j++){
+			weight[i] += eff_cumprod[j] * subv[j];
+		}
+	}
+	free(eff_cumprod);
+	free(subv);
+	free(diffsize);
+	free(diff_cumprod);
+}
+
+mxArray* convert_ill_table_to_sparse(const double *Table, const int *sequence, const int nzCounts, const int N){
+	mxArray *spTable;
+	int     i, temp, *irs, *jcs, count=0;
+	double  *sr;
+
+	spTable = mxCreateSparse(N, 1, nzCounts, mxREAL);
+    sr  = mxGetPr(spTable);
+    irs = mxGetIr(spTable);
+    jcs = mxGetJc(spTable);
+
+	jcs[0] = 0;
+	jcs[1] = nzCounts;
+
+	for(i=0; i<nzCounts; i++){
+		irs[i] = sequence[count];
+		count++;
+		temp = sequence[count];
+		sr[i] = Table[temp];
+		count++;
+	}
+	return spTable;
+}
+
+void multiply_spPot_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, bdim, sdim, NB, NZB, NZS, position, bindex, sindex, nzCounts=0;
+	int     *mask, *result, *bir, *sir, *rir, *bjc, *sjc, *rjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, *rpr;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	if(sdim == 0){
+		for(i=0; i<NZB; i++){
+			bpr[i] *= *spr;
+		}	
+		return;
+	}
+
+	pTemp1 = mxCreateSparse(NB, 1, NZB, mxREAL);
+	rpr = mxGetPr(pTemp1);
+	rir = mxGetIr(pTemp1);
+	rjc = mxGetJc(pTemp1);
+	rjc[0] = 0;
+	rjc[1] = NZB;
+
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sir, NZS, sizeof(int), compare);
+		if(result){
+			position = result - sir;
+			rpr[nzCounts] = bpr[i] * spr[position];
+			rir[nzCounts] = bindex;
+			nzCounts++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	reset_nzmax(pTemp1, NZB, nzCounts);
+	mxSetField(bigPot, 0, "T", pTemp1);
+
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+void marginal_spPot_to_spPot(const mxArray *bigPot, mxArray *smallPot, const int maximize){
+	int     i, j, count, bdim, sdim, NB, NS, NZB, position, bindex, sindex, nzCounts=0;
+	int     *mask, *sequence, *result, *bir, *bjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *sTable, *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr;
+	mxArray *pTemp;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+	NS = 1;
+	for(i=0; i<sdim; i++){
+		NS *= (int)psSize[i];
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	if(sdim == 0){
+		pTemp = mxGetField(smallPot, 0, "T");
+		spr = mxGetPr(pTemp);
+		*spr = 0;
+		if(maximize){
+			for(i=0; i<NZB; i++){
+				*spr = (*spr < bpr[i])? bpr[i] : *spr;
+			}
+		}
+		else{
+			for(i=0; i<NZB; i++){
+				*spr += bpr[i];
+			}
+		}	
+		return;
+	}
+
+	mask = malloc(sdim * sizeof(int));
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+
+
+	sTable = malloc(NZB * sizeof(double));
+	sequence = malloc(NZB * 2 * sizeof(double));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	for(i=0; i<NZB; i++){
+		sTable[i] = 0;
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	count = 0;
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sequence, nzCounts, sizeof(int)*2, compare);
+		if(result){
+			position = (result - sequence) / 2;
+			if(maximize)
+				sTable[position] = (sTable[position] < bpr[i]) ? bpr[i] : sTable[position];
+			else sTable[position] += bpr[i];
+		}
+		else {
+			if(maximize) 
+				sTable[nzCounts] = (sTable[nzCounts] < bpr[i]) ? bpr[i] : sTable[nzCounts];
+			else sTable[nzCounts] += bpr[i];
+			sequence[count] = sindex;
+			count++;
+			sequence[count] = nzCounts;
+			nzCounts++;
+			count++;
+		}
+	}
+	
+	pTemp = mxGetField(smallPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	qsort(sequence, nzCounts, sizeof(int) * 2, compare);
+	pTemp = convert_ill_table_to_sparse(sTable, sequence, nzCounts, NS);
+	mxSetField(smallPot, 0, "T", pTemp);
+
+	free(sTable);
+	free(sequence);
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+void divide_null_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, count1, match, temp, bdim, sdim, diffdim, NB, NS, ND, NZB, NZS, bindex, sindex;
+	int     *samemask, *diffmask, *rir, *rjc, *sir, *sjc, *bCumprod, *sCumprod, *ssubv, *weight;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *rpr, *spr, value;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	if(sdim == 0){
+		pTemp1 = mxGetField(bigPot, 0, "T");
+		if(pTemp1)mxDestroyArray(pTemp1);
+		pTemp = mxCreateSparse(NB, 1, NB, mxREAL);
+		mxSetField(bigPot, 0, "T", pTemp);
+		rpr = mxGetPr(pTemp);
+		rir = mxGetIr(pTemp);
+		rjc = mxGetJc(pTemp);
+		rjc[0] = 0;
+		rjc[1] = NB;
+		value = *spr;
+		if(value == 0) value = 1;
+		for(i=0; i<NB; i++){
+			rpr[i] = 1 / value;
+			rir[i] = i;
+		}	
+		return;
+	}
+
+	NS = 1;
+	for(i=0; i<sdim; i++){
+		NS *= (int)psSize[i];
+	}
+	ND = NB / NS;
+
+	pTemp = mxCreateSparse(NB, 1, NB, mxREAL);
+	rpr = mxGetPr(pTemp);
+	rir = mxGetIr(pTemp);
+	rjc = mxGetJc(pTemp);
+	rjc[0] = 0;
+	rjc[1] = NB;
+	for(i=0; i<NB; i++){
+		rpr[i] = 1;
+		rir[i] = i;
+	}
+
+	NZB = ND * NZS;
+
+	diffdim = bdim - sdim;
+	samemask = malloc(sdim * sizeof(int));
+	diffmask = malloc(diffdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	weight = malloc(ND * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	count1 = 0;
+	for(i=0; i<bdim; i++){
+		match = 0;
+		for(j=0; j<sdim; j++){
+			if(pbDomain[i] == psDomain[j]){
+				samemask[count] = i;
+				match = 1;
+				count++;
+				break;
+			}
+		}
+		if(match == 0){
+			diffmask[count1] = i; 
+			count1++;
+		}
+	}
+
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	count = 0;
+	compute_fixed_weight(weight, pbSize, diffmask, bCumprod, ND, diffdim);
+	for(i=0; i<NZS; i++){
+		sindex = sir[i];
+		ind_subv(sindex, sCumprod, sdim, ssubv);
+		temp = 0;
+		for(j=0; j<sdim; j++){
+			temp += ssubv[j] * bCumprod[samemask[j]];
+		}
+		for(j=0; j<ND; j++){
+			bindex = weight[j] + temp;
+			rpr[bindex] = 1 / (spr[i]);
+		}
+	}
+
+	pTemp1 = mxGetField(bigPot, 0, "T");
+	if(pTemp1)mxDestroyArray(pTemp1);
+	mxSetField(bigPot, 0, "T", pTemp);
+
+	free(samemask);
+	free(diffmask);
+	free(bCumprod);
+	free(sCumprod);
+	free(weight);
+	free(ssubv);
+}
+
+void divide_spPot_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, bdim, sdim, NB, NZB, NZS, position, bindex, sindex;
+	int     *mask, *result, *bir, *sir, *bjc, *sjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, value;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp1 = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp1);
+	bir = mxGetIr(pTemp1);
+	bjc = mxGetJc(pTemp1);
+	NZB = bjc[1];
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	if(sdim == 0){
+		value = *spr;
+		if(value == 0)value = 1;
+		for(i=0; i<NZB; i++){
+			bpr[i] /= value;
+		}	
+		return;
+	}
+
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sir, NZS, sizeof(int), compare);
+		if(result){
+			position = result - sir;
+			bpr[i] /= spr[position];
+		}
+	}
+
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int     i, j, loop, loops, nCliques, temp, count, parent, child, maximize, *distribute_order;
+	double  *pr, *pr1;
+	mxArray *pTemp, *pPreCh, *pClpot, *pSeppot;
+
+	pTemp = mxGetField(prhs[0], 0, "cliques");
+	nCliques = mxGetNumberOfElements(pTemp);
+	loops = nCliques - 1;
+	pTemp = mxGetField(prhs[0], 0, "maximize");
+	maximize = (int)mxGetScalar(pTemp);
+
+	distribute_order = malloc(2 * loops * sizeof(int));
+	pTemp = mxGetField(prhs[0], 0, "preorder");
+	pr = mxGetPr(pTemp);
+	pPreCh = mxGetField(prhs[0], 0, "preorder_children");
+	count = 0;
+	for(i=0; i<nCliques; i++){
+		temp = (int)pr[i] - 1;
+		pTemp = mxGetCell(pPreCh, temp);
+		pr1 = mxGetPr(pTemp);
+		loop = mxGetNumberOfElements(pTemp);
+		for(j=0; j<loop; j++){
+			distribute_order[count] = temp;
+			distribute_order[count + loops] = (int)pr1[j] - 1;
+			count++;
+		}
+	}
+
+	plhs[0] = mxDuplicateArray(prhs[1]);
+	plhs[1] = mxDuplicateArray(prhs[2]);
+
+	for(loop=0; loop<loops; loop++){
+		parent = distribute_order[loop];
+		child  = distribute_order[loop+loops];
+		i = nCliques * child + parent;
+		pClpot = mxGetCell(plhs[0], child);
+		pTemp = mxGetField(pClpot, 0, "T");
+		pSeppot = mxGetCell(plhs[1], i);
+		if(pTemp){
+			if(mxIsEmpty(pTemp)) 
+				divide_null_by_spPot(pClpot, pSeppot);
+			else 
+				divide_spPot_by_spPot(pClpot, pSeppot);
+		}
+		else divide_null_by_spPot(pClpot, pSeppot);
+
+		pClpot = mxGetCell(plhs[0], parent);
+		marginal_spPot_to_spPot(pClpot, pSeppot, maximize);
+		mxSetCell(plhs[1], i, pSeppot);
+
+		pClpot = mxGetCell(plhs[0], child);
+		multiply_spPot_by_spPot(pClpot, pSeppot); 
+	}
+	free(distribute_order);
+}
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..86041be2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/enter_evidence.m
@@ -0,0 +1,100 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (jtree)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i} = [] if X(i) 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]
+% soft    - a cell array of soft/virtual evidence;
+%           soft{i} is a prob. distrib. over i's values, or [] [ cell(1,N) ]
+%
+% e.g., engine = enter_evidence(engine, ev, 'soft', soft_ev)
+%
+% For backwards compatibility with BNT2, you can also specify the parameters in the following order
+%  engine = enter_evidence(engine, ev, soft_ev)
+
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes(:);
+N = length(bnet.dag);
+
+engine.evidence = evidence; % store this for marginal_nodes with add_ev option
+  
+% set default params
+exclude = [];
+soft_evidence = cell(1,N);
+maximize = 0;
+
+% parse optional params
+args = varargin;
+nargs = length(args);
+if nargs > 0
+  if iscell(args{1})
+    soft_evidence = args{1};
+  else
+    for i=1:2:nargs
+      switch args{i},
+       case 'soft',    soft_evidence = args{i+1}; 
+       case 'maximize', maximize = args{i+1}; 
+       otherwise,  
+	error(['invalid argument name ' args{i}]);       
+      end
+    end
+  end
+end
+
+engine.maximize = maximize;
+
+onodes = find(~isemptycell(evidence));
+hnodes = find(isemptycell(evidence));
+pot_type = determine_pot_type(bnet, onodes);
+ if strcmp(pot_type, 'cg')
+  check_for_cd_arcs(onodes, bnet.cnodes, bnet.dag);
+end
+
+hard_nodes = 1:N;
+soft_nodes = find(~isemptycell(soft_evidence));
+S = length(soft_nodes);
+if S > 0
+  assert(pot_type == 'd');
+  assert(mysubset(soft_nodes, bnet.dnodes));
+end
+ 
+% Evaluate CPDs with evidence, and convert to potentials  
+pot = cell(1, N+S);
+for n=1:N
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n);
+  if isempty(bnet.CPD{e})
+    error(['must define CPD ' num2str(e)])
+  else
+    pot{n} = convert_to_pot(bnet.CPD{e}, pot_type, fam(:), evidence);
+  end
+end
+
+for i=1:S
+  n = soft_nodes(i);
+  pot{N+i} = dpot(n, ns(n), soft_evidence{n});
+end
+clqs = engine.clq_ass_to_node([hard_nodes soft_nodes]); 
+
+[clpot, seppot] = init_pot(engine, clqs, pot, pot_type, onodes);
+[clpot, seppot] = collect_evidence(engine, clpot, seppot);
+[clpot, seppot] = distribute_evidence(engine, clpot, seppot);
+C = length(clpot);
+ll = zeros(1, C);
+for i=1:C
+   domain = clpot{i}.domain;
+   sizes = clpot{i}.sizes;
+   T = clpot{i}.T;
+   clpot{i} = dpot(domain, sizes, T);
+end
+   
+for i=1:C
+  [clpot{i}, ll(i)] = normalize_pot(clpot{i});
+end
+loglik = ll(1); % we can extract the likelihood from any clique
+
+engine.clpot = clpot;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/enter_soft_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/enter_soft_evidence.m
new file mode 100644
index 00000000..59671415
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/enter_soft_evidence.m
@@ -0,0 +1,19 @@
+function [clpot, loglik] = enter_soft_evidence(engine, clique, potential, onodes, pot_type)
+% ENTER_SOFT_EVIDENCE Add the specified potentials to the network (jtree)
+% [clpot, loglik] = enter_soft_evidence(engine, clique, potential, onodes, pot_type, maximize)
+%
+% We multiply potential{i} onto clique(i) before propagating.
+% We return all the modified clique potentials.
+
+[clpot, seppot] = init_pot(engine, clique, potential, pot_type, onodes);
+[clpot, seppot] = collect_evidence(engine, clpot, seppot);
+[clpot, seppot] = distribute_evidence(engine, clpot, seppot);
+
+C = length(clpot);
+ll = zeros(1, C);
+for i=1:C
+  [clpot{i}, ll(i)] = normalize_pot(clpot{i});
+end
+loglik = ll(1); % we can extract the likelihood from any clique
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/init_pot.c b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/init_pot.c
new file mode 100644
index 00000000..86e09eae
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/init_pot.c
@@ -0,0 +1,624 @@
+/* C mex init_pot for in @jtree_sparse_inf_engine directory               */
+/* The file enter_evidence.m in directory @jtree_sparse_inf_engine call it*/
+
+/**************************************/
+/* init_pot.c has 5 input & 2 output  */
+/* engine                             */
+/* clqs                               */
+/* pots                               */
+/* pot_type                           */
+/* onodes                             */
+/*                                    */
+/* clpot                              */
+/* seppot                             */
+/**************************************/
+#include <math.h>
+#include <stdlib.h>
+#include "mex.h"
+
+int compare(const void* src1, const void* src2){
+	int i1 = *(int*)src1 ;
+	int i2 = *(int*)src2 ;
+	return i1-i2 ;
+}
+
+void ind_subv(int index, const int *cumprod, int n, int *bsubv){
+	int i;
+
+	for (i = n-1; i >= 0; i--) {
+		bsubv[i] = ((int)floor(index / cumprod[i]));
+		index = index % cumprod[i];
+	}
+}
+
+int subv_ind(const int n, const int *cumprod, const int *subv){
+	int i, index=0;
+
+	for(i=0; i<n; i++){
+		index += subv[i] * cumprod[i];
+	}
+	return index;
+}
+
+void compute_fixed_weight(int *weight, const double *pbSize, const int *dmask, const int *bCumprod, const int ND, const int diffdim){
+	int i, j;
+	int *eff_cumprod, *subv, *diffsize, *diff_cumprod;
+
+	subv = malloc(diffdim * sizeof(int));
+	eff_cumprod = malloc(diffdim * sizeof(int));
+	diffsize = malloc(diffdim * sizeof(int));
+	diff_cumprod = malloc(diffdim * sizeof(int));
+	for(i=0; i<diffdim; i++){
+		eff_cumprod[i] = bCumprod[dmask[i]];
+		diffsize[i] = (int)pbSize[dmask[i]];
+	}
+	diff_cumprod[0] = 1;
+	for(i=0; i<diffdim-1; i++){
+		diff_cumprod[i+1] = diff_cumprod[i] * diffsize[i];
+	}
+	for(i=0; i<ND; i++){
+		ind_subv(i, diff_cumprod, diffdim, subv);
+		weight[i] = 0;
+		for(j=0; j<diffdim; j++){
+			weight[i] += eff_cumprod[j] * subv[j];
+		}
+	}
+	free(eff_cumprod);
+	free(subv);
+	free(diffsize);
+	free(diff_cumprod);
+}
+
+void reset_nzmax(mxArray *spArray, const int old_nzmax, const int new_nzmax){
+	double *ptr;
+	void   *newptr;
+	int    *ir, *jc;
+	int    nbytes;
+
+	if(new_nzmax == old_nzmax) return;
+	nbytes = new_nzmax * sizeof(*ptr);
+	ptr = mxGetPr(spArray);
+	newptr = mxRealloc(ptr, nbytes);
+	mxSetPr(spArray, newptr);
+	nbytes = new_nzmax * sizeof(*ir);
+	ir = mxGetIr(spArray);
+	newptr = mxRealloc(ir, nbytes);
+	mxSetIr(spArray, newptr);
+	jc = mxGetJc(spArray);
+	jc[0] = 0;
+	jc[1] = new_nzmax;
+	mxSetNzmax(spArray, new_nzmax);
+}
+
+mxArray* convert_ill_table_to_sparse(const double *bigTable, const int *sequence, const int nzCounts, const int NB){
+	mxArray *spTable;
+	int     i, temp, *irs, *jcs, count=0;
+	double  *sr;
+
+	spTable = mxCreateSparse(NB, 1, nzCounts, mxREAL);
+    sr  = mxGetPr(spTable);
+    irs = mxGetIr(spTable);
+    jcs = mxGetJc(spTable);
+
+	jcs[0] = 0;
+	jcs[1] = nzCounts;
+
+	for(i=0; i<nzCounts; i++){
+		irs[i] = sequence[count];
+		count++;
+		temp = sequence[count];
+		sr[i] = bigTable[temp];
+		count++;
+	}
+	return spTable;
+}
+
+void multiply_null_by_fuPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, NB, NS, siz_b, siz_s, ndim, nzCounts=0;
+	int     *mask, *sx, *sy, *cpsy, *subs, *s, *cpsy2, *bir, *bjc;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *spr, *bpr, value;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	siz_b = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	siz_s = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<siz_b; i++){
+		NB *= (int)pbSize[i];
+	}
+	NS = 1;
+	for(i=0; i<siz_s; i++){
+		NS *= (int)psSize[i];
+	}
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+
+	pTemp1 = mxCreateSparse(NB, 1, NB, mxREAL);
+	bpr = mxGetPr(pTemp1);
+	bir = mxGetIr(pTemp1);
+	bjc = mxGetJc(pTemp1);
+	bjc[0] = 0;
+	bjc[1] = NB;
+
+	if(NS == 1){
+		value = *spr;
+		for(i=0; i<NB; i++){
+			bpr[i] = value;
+			bir[i] = i;
+		}
+		nzCounts = NB;
+		pTemp = mxGetField(bigPot, 0, "T");
+		if(pTemp)mxDestroyArray(pTemp);
+		reset_nzmax(pTemp1, NB, nzCounts);
+		mxSetField(bigPot, 0, "T", pTemp1);
+		return;
+	}
+
+	if(NS == NB){
+		for(i=0; i<NB; i++){
+			if(spr[i] != 0){
+				bpr[nzCounts] = spr[i];
+				bir[nzCounts] = i;
+				nzCounts++;
+			}
+		}
+		pTemp = mxGetField(bigPot, 0, "T");
+		if(pTemp)mxDestroyArray(pTemp);
+		reset_nzmax(pTemp1, NB, nzCounts);
+		mxSetField(bigPot, 0, "T", pTemp1);
+		return;
+	}
+
+	mask = malloc(siz_s * sizeof(int));
+	count = 0;
+	for(i=0; i<siz_s; i++){
+		for(j=0; j<siz_b; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	ndim = siz_b;
+	sx = (int *)malloc(sizeof(int)*ndim);
+	sy = (int *)malloc(sizeof(int)*ndim);
+	for(i=0; i<ndim; i++){
+		sx[i] = (int)pbSize[i];
+		sy[i] = 1;
+	}
+	for(i=0; i<count; i++){
+		sy[mask[i]] = sx[mask[i]];
+	}
+
+	s = (int *)malloc(sizeof(int)*ndim);
+	*(cpsy = (int *)malloc(sizeof(int)*ndim)) = 1;
+	subs =   (int *)malloc(sizeof(int)*ndim);
+	cpsy2 =  (int *)malloc(sizeof(int)*ndim);
+	for(i = 0; i < ndim; i++){
+		subs[i] = 0;
+		s[i] = sx[i] - 1;
+	}
+			
+	for(i = 0; i < ndim-1; i++){
+		cpsy[i+1] = cpsy[i]*sy[i]--;
+		cpsy2[i] = cpsy[i]*sy[i];
+	}
+	cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);
+
+	for(j=0; j<NB; j++){
+		if(*spr != 0){
+			bpr[nzCounts] = *spr;
+			bir[nzCounts] = j;
+			nzCounts++;
+		}
+		for(i = 0; i < ndim; i++){
+			if(subs[i] == s[i]){
+				subs[i] = 0;
+				if(sy[i])
+					spr -= cpsy2[i];
+			}
+			else{
+				subs[i]++;
+				if(sy[i])
+					spr += cpsy[i];
+				break;
+			}
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	reset_nzmax(pTemp1, NB, nzCounts);
+	mxSetField(bigPot, 0, "T", pTemp1);
+
+	free(sx);
+	free(sy);
+	free(s);
+	free(cpsy);
+	free(subs);
+	free(cpsy2);
+    free(mask);
+}
+
+void multiply_null_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, count1, match, temp, bdim, sdim, diffdim, NB, NS, ND, NZB, NZS, bindex, sindex, nzCounts=0;
+	int     *samemask, *diffmask, *sir, *sjc, *bCumprod, *sCumprod, *ssubv, *sequence, *weight;
+	double  *bigTable, *pbDomain, *psDomain, *pbSize, *psSize, *spr;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+	NS = 1;
+	for(i=0; i<sdim; i++){
+		NS *= (int)psSize[i];
+	}
+	ND = NB / NS;
+
+	if(ND == 1){
+		pTemp = mxGetField(bigPot, 0, "T");
+		if(pTemp)mxDestroyArray(pTemp);
+		pTemp1 = mxGetField(smallPot, 0, "T");
+		pTemp = mxDuplicateArray(pTemp1);
+		mxSetField(bigPot, 0, "T", pTemp);
+		return;
+	}
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	NZB = ND * NZS;
+
+	diffdim = bdim - sdim;
+	sequence = malloc(NZB * 2 * sizeof(int));
+	bigTable = malloc(NZB * sizeof(double));
+	samemask = malloc(sdim * sizeof(int));
+	diffmask = malloc(diffdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	weight = malloc(ND * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	count1 = 0;
+	for(i=0; i<bdim; i++){
+		match = 0;
+		for(j=0; j<sdim; j++){
+			if(pbDomain[i] == psDomain[j]){
+				samemask[count] = i;
+				match = 1;
+				count++;
+				break;
+			}
+		}
+		if(match == 0){
+			diffmask[count1] = i; 
+			count1++;
+		}
+	}
+
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	count = 0;
+	compute_fixed_weight(weight, pbSize, diffmask, bCumprod, ND, diffdim);
+	for(i=0; i<NZS; i++){
+		sindex = sir[i];
+		ind_subv(sindex, sCumprod, sdim, ssubv);
+		temp = 0;
+		for(j=0; j<sdim; j++){
+			temp += ssubv[j] * bCumprod[samemask[j]];
+		}
+		for(j=0; j<ND; j++){
+			bindex = weight[j] + temp;
+			bigTable[nzCounts] = spr[i];
+			sequence[count] = bindex;
+			count++;
+			sequence[count] = nzCounts;
+			nzCounts++;
+			count++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	qsort(sequence, nzCounts, sizeof(int) * 2, compare);
+	pTemp = convert_ill_table_to_sparse(bigTable, sequence, nzCounts, NB);
+	mxSetField(bigPot, 0, "T", pTemp);
+
+	free(sequence); 
+	free(bigTable);
+	free(samemask);
+	free(diffmask);
+	free(bCumprod);
+	free(sCumprod);
+	free(weight);
+	free(ssubv);
+}
+
+void multiply_spPot_by_fuPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, bdim, sdim, NB, NZB, bindex, sindex, nzCounts=0;
+	int     *mask, *bir, *bjc, *rir, *rjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, *rpr, value;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+
+	pTemp1 = mxCreateSparse(NB, 1, NZB, mxREAL);
+	rpr = mxGetPr(pTemp1);
+	rir = mxGetIr(pTemp1);
+	rjc = mxGetJc(pTemp1);
+	rjc[0] = 0;
+	rjc[1] = NZB;
+
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		value = spr[sindex];
+		if(value != 0){
+			rpr[nzCounts] = bpr[i] * value;
+			rir[nzCounts] = bindex;
+			nzCounts++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	reset_nzmax(pTemp1, NZB, nzCounts);
+	mxSetField(bigPot, 0, "T", pTemp1);
+
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+void multiply_spPot_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, bdim, sdim, NB, NZB, NZS, position, bindex, sindex, nzCounts=0;
+	int     *mask, *result, *bir, *sir, *rir, *bjc, *sjc, *rjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, *rpr;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	pTemp1 = mxCreateSparse(NB, 1, NZB, mxREAL);
+	rpr = mxGetPr(pTemp1);
+	rir = mxGetIr(pTemp1);
+	rjc = mxGetJc(pTemp1);
+	rjc[0] = 0;
+	rjc[1] = NZB;
+
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sir, NZS, sizeof(int), compare);
+		if(result){
+			position = result - sir;
+			rpr[nzCounts] = bpr[i] * spr[position];
+			rir[nzCounts] = bindex;
+			nzCounts++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	reset_nzmax(pTemp1, NZB, nzCounts);
+	mxSetField(bigPot, 0, "T", pTemp1);
+
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int     i, j, c, loop, nNodes, nCliques, ndomain, ns_num, nOnodes, dims[2];
+	double  *pClqs, *pr, *pt, *pSize, *eff_ns;
+	mxArray *pTemp, *pTemp1, *pStruct, *pCliques, *pBigpot, *pSmallpot;
+	const char *field_names[] = {"domain", "T", "sizes"};
+
+	nNodes = mxGetNumberOfElements(prhs[1]);
+	pCliques = mxGetField(prhs[0], 0, "cliques");
+	nCliques = mxGetNumberOfElements(pCliques);
+	pTemp = mxGetField(prhs[0], 0, "actual_node_sizes");
+	ns_num = mxGetNumberOfElements(pTemp);
+	pSize = mxGetPr(pTemp);
+
+	eff_ns = (double *)malloc(ns_num * sizeof(double));
+	for(i=0; i<ns_num; i++) eff_ns[i] = pSize[i];
+	nOnodes = mxGetNumberOfElements(prhs[4]);
+	pr = mxGetPr(prhs[4]);
+	for(i=0; i<nOnodes; i++) eff_ns[(int)pr[i] - 1] = 1;
+
+	plhs[0] = mxCreateCellArray(1, &nCliques);
+    for(i=0; i<nCliques; i++){
+        pStruct = mxCreateStructMatrix(1, 1, 3, field_names);
+		mxSetCell(plhs[0], i, pStruct);
+		pTemp = mxGetCell(pCliques, i);
+		ndomain = mxGetNumberOfElements(pTemp);
+		pt = mxGetPr(pTemp);
+		pTemp1 = mxDuplicateArray(pTemp);
+		mxSetField(pStruct, 0, "domain", pTemp1);
+		
+		pTemp = mxCreateDoubleMatrix(1, ndomain, mxREAL);
+		mxSetField(pStruct, 0, "sizes", pTemp);
+		pr = mxGetPr(pTemp);
+        for(j=0; j<ndomain; j++){
+            pr[j] = eff_ns[(int)pt[j]-1];
+        }
+    }
+
+	pClqs = mxGetPr(prhs[1]);
+	for(loop=0; loop<nNodes; loop++){
+		c = (int)pClqs[loop] - 1;
+		pSmallpot = mxGetCell(prhs[2], loop);
+		pTemp = mxGetField(pSmallpot, 0, "T");
+		pBigpot = mxGetCell(plhs[0], c);
+		pTemp1 = mxGetField(pBigpot, 0, "T");
+		if(pTemp1){
+			if(mxIsSparse(pTemp))
+				multiply_spPot_by_spPot(pBigpot, pSmallpot);
+			else multiply_spPot_by_fuPot(pBigpot, pSmallpot);
+		}
+		else{
+			if(mxIsSparse(pTemp))
+				multiply_null_by_spPot(pBigpot, pSmallpot);
+			else multiply_null_by_fuPot(pBigpot, pSmallpot);
+		}		
+	}
+
+	free(eff_ns);
+	dims[0] = nCliques;
+	dims[1] = nCliques;
+	plhs[1] = mxCreateCellArray(2, dims);
+}
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/jtree_sparse_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/jtree_sparse_inf_engine.m
new file mode 100644
index 00000000..49dcd69f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/jtree_sparse_inf_engine.m
@@ -0,0 +1,126 @@
+function engine = jtree_sparse_inf_engine(bnet, varargin)
+% JTREE_SPARSE_INF_ENGINE Junction tree inference engine when CPTs and Potentials are sparse
+% engine = jtree_sparse_inf_engine(bnet, ...)
+% It differs from jtree_inf_engine with all CPTs and potentials are 1D sparse arrays.
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% clusters  - a cell array of sets of nodes we want to ensure are in the same clique (in addition to families) [ {} ]
+% root      - the root of the junction tree will be a clique that contains this set of nodes [N]
+% stages    - stages{t} is a set of nodes we want to eliminate before stages{t+1}, ... [ {1:N} ]
+%
+% e.g., engine = jtree_inf_engine(bnet, 'maximize', 1);
+%
+% For more details on the junction tree algorithm, see
+% - "Probabilistic networks and expert systems", Cowell, Dawid, Lauritzen and Spiegelhalter, Springer, 1999
+% - "Inference in Belief Networks: A procedural guide", C. Huang and A. Darwiche, 
+%      Intl. J. Approximate Reasoning, 15(3):225-263, 1996.
+
+
+% set default params
+N = length(bnet.dag);
+clusters = {};
+root = N;
+stages = { 1:N };
+
+if nargin >= 2
+  args = varargin;
+  nargs = length(args);
+  if ~isstr(args{1})
+    error('the interface to jtree has changed; now, onodes is not allowed and all optional params must be passed by name')
+  end
+  for i=1:2:nargs
+    switch args{i},
+     case 'clusters', clusters = args{i+1}; 
+     case 'root',     root = args{i+1}; 
+     case 'stages',   stages = args{i+1}; 
+     otherwise,  
+      error(['invalid argument name ' args{i}]);       
+    end
+  end
+end
+
+engine = init_fields;
+engine = class(engine, 'jtree_sparse_inf_engine', inf_engine(bnet));
+
+onodes = bnet.observed;
+%[engine.jtree, dummy, engine.cliques, B, w] = dag_to_jtree(bnet, onodes, stages, clusters);
+
+porder = determine_elim_constraints(bnet, onodes);
+strong = ~isempty(porder);
+ns = bnet.node_sizes(:);
+ns(onodes) = 1; % observed nodes have only 1 possible value
+[engine.jtree, root2, engine.cliques, B, w] = ...
+    graph_to_jtree(moralize(bnet.dag), ns, porder, stages, clusters);
+
+engine.cliques_bitv = B;
+engine.clique_weight = w;
+C = length(engine.cliques);
+engine.clpot = cell(1,C);
+
+% Compute the separators between connected cliques.
+[is,js] = find(engine.jtree > 0);
+engine.separator = cell(C,C);
+for k=1:length(is)
+  i = is(k); j = js(k);
+  engine.separator{i,j} = find(B(i,:) & B(j,:)); % intersect(cliques{i}, cliques{j});
+end
+
+% A node can be a member of many cliques, but is assigned to exactly one, to avoid
+% double-counting its CPD. We assign node i to clique c if c is the "lightest" clique that
+% contains i's family, so it can accomodate its CPD.
+
+engine.clq_ass_to_node = zeros(1, N);
+for i=1:N
+  %c = clq_containing_nodes(engine, family(bnet.dag, i));
+  clqs_containing_family = find(all(B(:,family(bnet.dag, i)), 2)); % all selected columns must be 1
+  c = clqs_containing_family(argmin(w(clqs_containing_family)));  
+  engine.clq_ass_to_node(i) = c; 
+end
+
+% Make the jtree rooted, so there is a fixed message passing order.
+engine.root_clq = clq_containing_nodes(engine, root);
+if engine.root_clq <= 0
+  error(['no clique contains ' num2str(root)]);
+end
+
+[engine.jtree, engine.preorder, engine.postorder] = mk_rooted_tree(engine.jtree, engine.root_clq);
+
+% collect 
+engine.postorder_parents = cell(1,length(engine.postorder));
+for n=engine.postorder(:)'
+  engine.postorder_parents{n} = parents(engine.jtree, n);
+end
+% distribute
+engine.preorder_children = cell(1,length(engine.preorder));
+for n=engine.preorder(:)'
+  engine.preorder_children{n} = children(engine.jtree, n);
+end
+
+ns = bnet.node_sizes;
+engine.actual_node_sizes = ns;
+ 
+
+%%%%%%%%
+
+function engine = init_fields()
+
+engine.jtree = [];
+engine.cliques = [];
+engine.separator = [];
+engine.cliques_bitv = [];
+engine.clique_weight = [];
+engine.clpot = [];
+engine.clq_ass_to_node = [];
+engine.root_clq = [];
+engine.preorder = [];
+engine.postorder = [];
+engine.preorder_children = [];
+engine.postorder_parents = [];
+engine.maximize = [];
+engine.evidence = [];
+engine.actual_node_sizes = [];
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/marginal_family.m
new file mode 100644
index 00000000..eff60ca2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/marginal_family.m
@@ -0,0 +1,11 @@
+function marginal = marginal_family(engine, i, add_ev)
+% MARGINAL_FAMILY Compute the marginal on the specified family (jtree)
+% marginal = marginal_family(engine, i)
+
+if nargin < 3, add_ev = 0; end
+assert(~add_ev);
+
+bnet = bnet_from_engine(engine);
+fam = family(bnet.dag, i);
+c = engine.clq_ass_to_node(i);
+marginal = pot_to_marginal(marginalize_pot(engine.clpot{c}, fam));
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..6413172c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/marginal_nodes.m
@@ -0,0 +1,22 @@
+function marginal = marginal_nodes(engine, query, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (jtree)
+% marginal = marginal_nodes(engine, query, add_ev)
+%
+% 'query' must be a subset of some clique; an error will be raised if not.
+% 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, add_ev = 0; end
+
+c = clq_containing_nodes(engine, query);
+if c == -1
+  error(['no clique contains ' num2str(query)]);
+end
+marginal = pot_to_marginal(marginalize_pot(engine.clpot{c}, query, engine.maximize));
+
+if add_ev
+  bnet = bnet_from_engine(engine);
+  %marginal = add_ev_to_dmarginal(marginal, engine.evidence, bnet.node_sizes);
+  marginal = add_evidence_to_gmarginal(marginal, engine.evidence, bnet.node_sizes, bnet.cnodes);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/CVS/Entries
new file mode 100644
index 00000000..f74fd729
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/CVS/Entries
@@ -0,0 +1,6 @@
+/collect_evidence.c/1.1.1.1/Wed May 29 15:59:56 2002//
+/distribute_evidence.c/1.1.1.1/Wed May 29 15:59:56 2002//
+/init_pot.c/1.1.1.1/Wed May 29 15:59:56 2002//
+/init_pot1.c/1.1.1.1/Wed May 29 15:59:56 2002//
+/init_pot1.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/CVS/Repository
new file mode 100644
index 00000000..eb323e83
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@jtree_sparse_inf_engine/old
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/collect_evidence.c b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/collect_evidence.c
new file mode 100644
index 00000000..3e6d35c7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/collect_evidence.c
@@ -0,0 +1,635 @@
+/* C mex for collect_evidence.c in @jtree_sparse_inf_engine directory */
+/* File enter_evidence.m in directory @jtree_sparse_inf_engine call it*/
+
+/******************************************/
+/* collect_evidence has 3 input & 2 output*/
+/* engine                                 */
+/* clpot                                  */
+/* seppot                                 */
+/*                                        */
+/* clpot                                  */
+/* seppot                                 */
+/******************************************/
+
+#include <math.h>
+#include <search.h>
+#include "mex.h"
+
+int compare(const void* src1, const void* src2){
+	int i1 = *(int*)src1 ;
+	int i2 = *(int*)src2 ;
+	return i1-i2 ;
+}
+
+void ind_subv(int index, const int *cumprod, int n, int *bsubv){
+	int i;
+
+	for (i = n-1; i >= 0; i--) {
+		bsubv[i] = ((int)floor(index / cumprod[i]));
+		index = index % cumprod[i];
+	}
+}
+
+int subv_ind(const int n, const int *cumprod, const int *subv){
+	int i, index=0;
+
+	for(i=0; i<n; i++){
+		index += subv[i] * cumprod[i];
+	}
+	return index;
+}
+
+void compute_fixed_weight(int *weight, const double *pbSize, const int *dmask, const int *bCumprod, const int ND, const int diffdim){
+	int i, j;
+	int *eff_cumprod, *subv, *diffsize, *diff_cumprod;
+
+	subv = malloc(diffdim * sizeof(int));
+	eff_cumprod = malloc(diffdim * sizeof(int));
+	diffsize = malloc(diffdim * sizeof(int));
+	diff_cumprod = malloc(diffdim * sizeof(int));
+	for(i=0; i<diffdim; i++){
+		eff_cumprod[i] = bCumprod[dmask[i]];
+		diffsize[i] = (int)pbSize[dmask[i]];
+	}
+	diff_cumprod[0] = 1;
+	for(i=0; i<diffdim-1; i++){
+		diff_cumprod[i+1] = diff_cumprod[i] * diffsize[i];
+	}
+	for(i=0; i<ND; i++){
+		ind_subv(i, diff_cumprod, diffdim, subv);
+		weight[i] = 0;
+		for(j=0; j<diffdim; j++){
+			weight[i] += eff_cumprod[j] * subv[j];
+		}
+	}
+	free(eff_cumprod);
+	free(subv);
+	free(diffsize);
+	free(diff_cumprod);
+}
+
+mxArray* convert_table_to_sparse(const double *bT, const int *index, const int nzCounts, const int N){
+	mxArray  *spTable;
+    int      i, *irs, *jcs;
+    double   *sr;
+    
+	spTable = mxCreateSparse(N, 1, nzCounts, mxREAL);
+    sr  = mxGetPr(spTable);
+    irs = mxGetIr(spTable);
+    jcs = mxGetJc(spTable);
+
+	jcs[0] = 0;
+	jcs[1] = nzCounts;
+
+	for(i=0; i<nzCounts; i++){
+			sr[i] = bT[i];
+			irs[i] = index[i];
+    }
+	return spTable;	
+}
+
+mxArray* convert_ill_table_to_sparse(const double *Table, const int *sequence, const int nzCounts, const int N){
+	mxArray *spTable;
+	int     i, temp, *irs, *jcs, count=0;
+	double  *sr;
+
+	spTable = mxCreateSparse(N, 1, nzCounts, mxREAL);
+    sr  = mxGetPr(spTable);
+    irs = mxGetIr(spTable);
+    jcs = mxGetJc(spTable);
+
+	jcs[0] = 0;
+	jcs[1] = nzCounts;
+
+	for(i=0; i<nzCounts; i++){
+		irs[i] = sequence[count];
+		count++;
+		temp = sequence[count];
+		sr[i] = Table[temp];
+		count++;
+	}
+	return spTable;
+}
+
+void multiply_null_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, count1, match, temp, bdim, sdim, diffdim, NB, NS, ND, NZB, NZS, bindex, sindex, nzCounts=0;
+	int     *samemask, *diffmask, *sir, *sjc, *bCumprod, *sCumprod, *ssubv, *sequence, *weight;
+	double  *bigTable, *pbDomain, *psDomain, *pbSize, *psSize, *spr, *bpr;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	if(sdim == 0){
+		pTemp = mxCreateSparse(NB, 1, NB, mxREAL);
+		mxSetField(bigPot, 0, "T", pTemp);
+		bpr = mxGetPr(pTemp);
+		sir = mxGetIr(pTemp);
+		sjc = mxGetJc(pTemp);
+		sjc[0] = 0;
+		sjc[1] = NB;
+		for(i=0; i<NB; i++){
+			bpr[i] = *spr;
+			sir[i] = i;
+		}	
+		return;
+	}
+
+	NS = 1;
+	for(i=0; i<sdim; i++){
+		NS *= (int)psSize[i];
+	}
+	ND = NB / NS;
+
+	if(ND == 1){
+		pTemp1 = mxGetField(smallPot, 0, "T");
+		pTemp = mxDuplicateArray(pTemp1);
+		mxSetField(bigPot, 0, "T", pTemp);
+		return;
+	}
+
+
+	NZB = ND * NZS;
+
+	diffdim = bdim - sdim;
+	sequence = malloc(NZB * 2 * sizeof(int));
+	bigTable = malloc(NZB * sizeof(double));
+	samemask = malloc(sdim * sizeof(int));
+	diffmask = malloc(diffdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	weight = malloc(ND * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	count1 = 0;
+	for(i=0; i<bdim; i++){
+		match = 0;
+		for(j=0; j<sdim; j++){
+			if(pbDomain[i] == psDomain[j]){
+				samemask[count] = i;
+				match = 1;
+				count++;
+				break;
+			}
+		}
+		if(match == 0){
+			diffmask[count1] = i; 
+			count1++;
+		}
+	}
+
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	count = 0;
+	compute_fixed_weight(weight, pbSize, diffmask, bCumprod, ND, diffdim);
+	for(i=0; i<NZS; i++){
+		sindex = sir[i];
+		ind_subv(sindex, sCumprod, sdim, ssubv);
+		temp = 0;
+		for(j=0; j<sdim; j++){
+			temp += ssubv[j] * bCumprod[samemask[j]];
+		}
+		for(j=0; j<ND; j++){
+			bindex = weight[j] + temp;
+			bigTable[nzCounts] = spr[i];
+			sequence[count] = bindex;
+			count++;
+			sequence[count] = nzCounts;
+			nzCounts++;
+			count++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	qsort(sequence, nzCounts, sizeof(int) * 2, compare);
+	pTemp = convert_ill_table_to_sparse(bigTable, sequence, nzCounts, NB);
+	mxSetField(bigPot, 0, "T", pTemp);
+
+	free(sequence); 
+	free(bigTable);
+	free(samemask);
+	free(diffmask);
+	free(bCumprod);
+	free(sCumprod);
+	free(weight);
+	free(ssubv);
+}
+
+void multiply_spPot_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, bdim, sdim, NB, NZB, NZS, position, bindex, sindex, nzCounts=0;
+	int     *mask, *index, *result, *bir, *sir, *bjc, *sjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *bigTable, *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, value;
+	mxArray *pTemp;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	if(sdim == 0){
+		for(i=0; i<NZB; i++){
+			bpr[i] *= *spr;
+		}	
+		return;
+	}
+
+	bigTable = malloc(NZB * sizeof(double));
+	index = malloc(NZB * sizeof(double));
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	for(i=0; i<NZB; i++){
+		bigTable[i] = 0;
+	}
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		value = bpr[i];
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sir, NZS, sizeof(int), compare);
+		if(result){
+			position = result - sir;
+			value *= spr[position];
+			bigTable[nzCounts] = value;
+			index[nzCounts] = bindex;
+			nzCounts++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	pTemp = convert_table_to_sparse(bigTable, index, nzCounts, NB);
+	mxSetField(bigPot, 0, "T", pTemp);
+
+	free(bigTable);
+	free(index);
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+mxArray* marginal_null_to_spPot(const mxArray *bigPot, const mxArray *sDomain, const int maximize){
+	int     i, j, count, bdim, sdim, NB, NS, ND;
+	int     *mask, *sir, *sjc;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *spr;
+	mxArray *pTemp, *smallPot;
+	const char *field_names[] = {"domain", "T", "sizes"};
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	psDomain = mxGetPr(sDomain);
+	sdim = mxGetNumberOfElements(sDomain);
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+
+	smallPot = mxCreateStructMatrix(1, 1, 3, field_names);
+	pTemp = mxDuplicateArray(sDomain);
+	mxSetField(smallPot, 0, "domain", pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	if(sdim == 0){
+		pTemp = mxCreateSparse(1, 1, 1, mxREAL);
+		mxSetField(smallPot, 0, "T", pTemp);
+		spr = mxGetPr(pTemp);
+		sir = mxGetIr(pTemp);
+		sjc = mxGetJc(pTemp);
+		*spr = 0;
+		*sir = 0;
+		sjc[0] = 0;
+		sjc[1] = 1;
+		if(maximize) *spr = 1;
+		else *spr = NB;
+
+		pTemp = mxCreateDoubleMatrix(1, 1, mxREAL);
+		*mxGetPr(pTemp) = 1;
+		mxSetField(smallPot, 0, "sizes", pTemp);
+		return smallPot;
+	}
+
+	mask = malloc(sdim * sizeof(int));
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	pTemp = mxCreateDoubleMatrix(1, count, mxREAL);
+	psSize = mxGetPr(pTemp);
+	NS = 1;
+	for(i=0; i<count; i++){
+		psSize[i] = pbSize[mask[i]];
+		NS *= (int)psSize[i];
+	}
+	mxSetField(smallPot, 0, "sizes", pTemp);
+
+	ND = NB / NS;
+
+	pTemp = mxCreateSparse(NS, 1, NS, mxREAL);
+	mxSetField(smallPot, 0, "T", pTemp);
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	if(maximize){
+		for(i=0; i<NS; i++){
+			spr[i] = 1;
+			sir[i] = i;
+		}
+	}
+	else{
+		for(i=0; i<NS; i++){
+			spr[i] = ND;
+			sir[i] = i;
+		}
+	}
+	sjc[0] = 0;
+	sjc[1] = NS;
+
+	free(mask);
+	return smallPot;
+}
+
+mxArray* marginal_spPot_to_spPot(const mxArray *bigPot, const mxArray *sDomain, const int maximize){
+	int     i, j, count, bdim, sdim, NB, NS, NZB, position, bindex, sindex, nzCounts=0;
+	int     *mask, *sequence, *result, *bir, *bjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *sTable, *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr;
+	mxArray *pTemp, *smallPot;
+	const char *field_names[] = {"domain", "T", "sizes"};
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	psDomain = mxGetPr(sDomain);
+	sdim = mxGetNumberOfElements(sDomain);
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	smallPot = mxCreateStructMatrix(1, 1, 3, field_names);
+	pTemp = mxDuplicateArray(sDomain);
+	mxSetField(smallPot, 0, "domain", pTemp);
+
+	if(sdim == 0){
+		pTemp = mxCreateSparse(1, 1, 1, mxREAL);
+		mxSetField(smallPot, 0, "T", pTemp);
+		spr = mxGetPr(pTemp);
+		bir = mxGetIr(pTemp);
+		bjc = mxGetJc(pTemp);
+		*spr = 0;
+		*bir = 0;
+		bjc[0] = 0;
+		bjc[1] = 1;
+		if(maximize){
+			for(i=0; i<NZB; i++){
+				*spr = (*spr < bpr[i])? bpr[i] : *spr;
+			}
+		}
+		else{
+			for(i=0; i<NZB; i++){
+				*spr += bpr[i];
+			}
+		}
+
+		pTemp = mxCreateDoubleMatrix(1, 1, mxREAL);
+		*mxGetPr(pTemp) = 1;
+		mxSetField(smallPot, 0, "sizes", pTemp);
+		return smallPot;
+	}
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	mask = malloc(sdim * sizeof(int));
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	pTemp = mxCreateDoubleMatrix(1, count, mxREAL);
+	psSize = mxGetPr(pTemp);
+	NS = 1;
+	for(i=0; i<count; i++){
+		psSize[i] = pbSize[mask[i]];
+		NS *= (int)psSize[i];
+	}
+	mxSetField(smallPot, 0, "sizes", pTemp);
+
+
+	sTable = malloc(NZB * sizeof(double));
+	sequence = malloc(NZB * 2 * sizeof(double));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	for(i=0; i<NZB; i++)sTable[i] = 0;
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	count = 0;
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sequence, nzCounts, sizeof(int)*2, compare);
+		if(result){
+			position = (result - sequence) / 2;
+			if(maximize) 
+				sTable[position] = (sTable[position] < bpr[i]) ? bpr[i] : sTable[position];
+			else sTable[position] += bpr[i];
+		}
+		else {
+			if(maximize) 
+				sTable[nzCounts] = (sTable[nzCounts] < bpr[i]) ? bpr[i] : sTable[nzCounts];
+			else sTable[nzCounts] += bpr[i];
+			sequence[count] = sindex;
+			count++;
+			sequence[count] = nzCounts;
+			nzCounts++;
+			count++;
+		}
+	}
+	
+	qsort(sequence, nzCounts, sizeof(int) * 2, compare);
+	pTemp = convert_ill_table_to_sparse(sTable, sequence, nzCounts, NS);
+	mxSetField(smallPot, 0, "T", pTemp);
+
+	free(sTable);
+	free(sequence);
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+
+	return smallPot;
+}
+
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int     i, n, p, np, pn, loop, loops, nCliques, temp, maximize;
+	int     *collect_order;
+	double  *pr, *pr1;
+	mxArray *pTemp, *pTemp1, *pPostP, *pClpot, *pSeppot, *pSeparator;
+
+	pTemp = mxGetField(prhs[0], 0, "cliques");
+	nCliques = mxGetNumberOfElements(pTemp);
+	loops = nCliques - 1;
+	pTemp = mxGetField(prhs[0], 0, "maximize");
+	maximize = (int)mxGetScalar(pTemp);
+	pSeparator = mxGetField(prhs[0], 0, "separator");
+
+	collect_order = malloc(2 * loops * sizeof(int));
+
+	pTemp = mxGetField(prhs[0], 0, "postorder");
+	pr = mxGetPr(pTemp);
+	pPostP = mxGetField(prhs[0], 0, "postorder_parents");
+	for(i=0; i<loops; i++){
+		temp = (int)pr[i] - 1;
+		pTemp = mxGetCell(pPostP, temp);
+		pr1 = mxGetPr(pTemp);
+		collect_order[i] = (int)pr1[0] - 1;
+		collect_order[i+loops] = temp;
+	}
+
+	plhs[0] = mxDuplicateArray(prhs[1]);
+	plhs[1] = mxDuplicateArray(prhs[2]);
+
+	for(loop=0; loop<loops; loop++){
+		p = collect_order[loop];
+		n = collect_order[loop+loops];
+		np = p * nCliques + n;
+		pn = n * nCliques + p;
+		pClpot = mxGetCell(plhs[0], n);
+		pTemp1 = mxGetField(pClpot, 0, "T");
+		pTemp = mxGetCell(pSeparator, pn);
+		if(pTemp1)
+			pSeppot = marginal_spPot_to_spPot(pClpot, pTemp, maximize);
+		else pSeppot = marginal_null_to_spPot(pClpot, pTemp, maximize);
+		mxSetCell(plhs[1], pn, pSeppot);
+
+		pClpot = mxGetCell(plhs[0], p);
+		pTemp1 = mxGetField(pClpot, 0, "T");
+		if(pTemp1)
+			multiply_spPot_by_spPot(pClpot, pSeppot);
+		else multiply_null_by_spPot(pClpot, pSeppot);
+	}
+	free(collect_order);
+}
+	
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/distribute_evidence.c b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/distribute_evidence.c
new file mode 100644
index 00000000..3d8ec66b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/distribute_evidence.c
@@ -0,0 +1,613 @@
+/* C mex for distribute_evidence.c in @jtree_sparse_inf_engine directory*/
+/* File enter_evidence.m in directory @jtree_sparse_inf_engine call it  */
+
+/*********************************************/
+/* distribute_evidence has 3 input & 2 output*/
+/* engine                                    */
+/* clpot                                     */
+/* seppot                                    */
+/*                                           */
+/* clpot                                     */
+/* seppot                                    */
+/*********************************************/
+
+#include "mex.h"
+
+#include <math.h>
+#include <search.h>
+#include "mex.h"
+
+int compare(const void* src1, const void* src2){
+	int i1 = *(int*)src1 ;
+	int i2 = *(int*)src2 ;
+	return i1-i2 ;
+}
+
+void ind_subv(int index, const int *cumprod, int n, int *bsubv){
+	int i;
+
+	for (i = n-1; i >= 0; i--) {
+		bsubv[i] = ((int)floor(index / cumprod[i]));
+		index = index % cumprod[i];
+	}
+}
+
+int subv_ind(const int n, const int *cumprod, const int *subv){
+	int i, index=0;
+
+	for(i=0; i<n; i++){
+		index += subv[i] * cumprod[i];
+	}
+	return index;
+}
+
+void compute_fixed_weight(int *weight, const double *pbSize, const int *dmask, const int *bCumprod, const int ND, const int diffdim){
+	int i, j;
+	int *eff_cumprod, *subv, *diffsize, *diff_cumprod;
+
+	subv = malloc(diffdim * sizeof(int));
+	eff_cumprod = malloc(diffdim * sizeof(int));
+	diffsize = malloc(diffdim * sizeof(int));
+	diff_cumprod = malloc(diffdim * sizeof(int));
+	for(i=0; i<diffdim; i++){
+		eff_cumprod[i] = bCumprod[dmask[i]];
+		diffsize[i] = (int)pbSize[dmask[i]];
+	}
+	diff_cumprod[0] = 1;
+	for(i=0; i<diffdim-1; i++){
+		diff_cumprod[i+1] = diff_cumprod[i] * diffsize[i];
+	}
+	for(i=0; i<ND; i++){
+		ind_subv(i, diff_cumprod, diffdim, subv);
+		weight[i] = 0;
+		for(j=0; j<diffdim; j++){
+			weight[i] += eff_cumprod[j] * subv[j];
+		}
+	}
+	free(eff_cumprod);
+	free(subv);
+	free(diffsize);
+	free(diff_cumprod);
+}
+
+mxArray* convert_table_to_sparse(const double *bT, const int *index, const int nzCounts, const int N){
+	mxArray  *spTable;
+    int      i, *irs, *jcs;
+    double   *sr;
+    
+	spTable = mxCreateSparse(N, 1, nzCounts, mxREAL);
+    sr  = mxGetPr(spTable);
+    irs = mxGetIr(spTable);
+    jcs = mxGetJc(spTable);
+
+	jcs[0] = 0;
+	jcs[1] = nzCounts;
+
+	for(i=0; i<nzCounts; i++){
+			sr[i] = bT[i];
+			irs[i] = index[i];
+    }
+	return spTable;	
+}
+
+mxArray* convert_ill_table_to_sparse(const double *Table, const int *sequence, const int nzCounts, const int N){
+	mxArray *spTable;
+	int     i, temp, *irs, *jcs, count=0;
+	double  *sr;
+
+	spTable = mxCreateSparse(N, 1, nzCounts, mxREAL);
+    sr  = mxGetPr(spTable);
+    irs = mxGetIr(spTable);
+    jcs = mxGetJc(spTable);
+
+	jcs[0] = 0;
+	jcs[1] = nzCounts;
+
+	for(i=0; i<nzCounts; i++){
+		irs[i] = sequence[count];
+		count++;
+		temp = sequence[count];
+		sr[i] = Table[temp];
+		count++;
+	}
+	return spTable;
+}
+
+void multiply_spPot_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, bdim, sdim, NB, NZB, NZS, position, bindex, sindex, nzCounts=0;
+	int     *mask, *index, *result, *bir, *sir, *bjc, *sjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *bigTable, *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, value;
+	mxArray *pTemp;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	if(sdim == 0){
+		for(i=0; i<NZB; i++){
+			bpr[i] *= *spr;
+		}	
+		return;
+	}
+
+	bigTable = malloc(NZB * sizeof(double));
+	index = malloc(NZB * sizeof(double));
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		value = bpr[i];
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sir, NZS, sizeof(int), compare);
+		if(result){
+			position = result - sir;
+			value *= spr[position];
+			bigTable[nzCounts] = value;
+			index[nzCounts] = bindex;
+			nzCounts++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	pTemp = convert_table_to_sparse(bigTable, index, nzCounts, NB);
+	mxSetField(bigPot, 0, "T", pTemp);
+
+	free(bigTable);
+	free(index);
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+void marginal_spPot_to_spPot(const mxArray *bigPot, mxArray *smallPot, const int maximize){
+	int     i, j, count, bdim, sdim, NB, NS, NZB, position, bindex, sindex, nzCounts=0;
+	int     *mask, *sequence, *result, *bir, *bjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *sTable, *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr;
+	mxArray *pTemp;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+	NS = 1;
+	for(i=0; i<sdim; i++){
+		NS *= (int)psSize[i];
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	if(sdim == 0){
+		pTemp = mxGetField(smallPot, 0, "T");
+		spr = mxGetPr(pTemp);
+		*spr = 0;
+		if(maximize){
+			for(i=0; i<NZB; i++){
+				*spr = (*spr < bpr[i])? bpr[i] : *spr;
+			}
+		}
+		else{
+			for(i=0; i<NZB; i++){
+				*spr += bpr[i];
+			}
+		}	
+		return;
+	}
+
+	mask = malloc(sdim * sizeof(int));
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+
+
+	sTable = malloc(NZB * sizeof(double));
+	sequence = malloc(NZB * 2 * sizeof(double));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	for(i=0; i<NZB; i++){
+		sTable[i] = 0;
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	count = 0;
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sequence, nzCounts, sizeof(int)*2, compare);
+		if(result){
+			position = (result - sequence) / 2;
+			if(maximize)
+				sTable[position] = (sTable[position] < bpr[i]) ? bpr[i] : sTable[position];
+			else sTable[position] += bpr[i];
+		}
+		else {
+			if(maximize) 
+				sTable[nzCounts] = (sTable[nzCounts] < bpr[i]) ? bpr[i] : sTable[nzCounts];
+			else sTable[nzCounts] += bpr[i];
+			sequence[count] = sindex;
+			count++;
+			sequence[count] = nzCounts;
+			nzCounts++;
+			count++;
+		}
+	}
+	
+	pTemp = mxGetField(smallPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	qsort(sequence, nzCounts, sizeof(int) * 2, compare);
+	pTemp = convert_ill_table_to_sparse(sTable, sequence, nzCounts, NS);
+	mxSetField(smallPot, 0, "T", pTemp);
+
+	free(sTable);
+	free(sequence);
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+void divide_null_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, count1, match, temp, bdim, sdim, diffdim, NB, NS, ND, NZB, NZS, bindex, sindex;
+	int     *samemask, *diffmask, *rir, *rjc, *sir, *sjc, *bCumprod, *sCumprod, *ssubv, *weight;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *rpr, *spr, value;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	if(sdim == 0){
+		pTemp = mxCreateSparse(NB, 1, NB, mxREAL);
+		mxSetField(bigPot, 0, "T", pTemp);
+		rpr = mxGetPr(pTemp);
+		rir = mxGetIr(pTemp);
+		rjc = mxGetJc(pTemp);
+		rjc[0] = 0;
+		rjc[1] = NB;
+		value = *spr;
+		if(value == 0) value = 1;
+		for(i=0; i<NB; i++){
+			rpr[i] = 1 / value;
+			rir[i] = i;
+		}	
+		return;
+	}
+
+	NS = 1;
+	for(i=0; i<sdim; i++){
+		NS *= (int)psSize[i];
+	}
+	ND = NB / NS;
+
+
+	pTemp = mxCreateSparse(NB, 1, NB, mxREAL);
+	rpr = mxGetPr(pTemp);
+	rir = mxGetIr(pTemp);
+	rjc = mxGetJc(pTemp);
+	rjc[0] = 0;
+	rjc[1] = NB;
+	for(i=0; i<NB; i++){
+		rpr[i] = 1;
+		rir[i] = i;
+	}
+
+	NZB = ND * NZS;
+
+	diffdim = bdim - sdim;
+	samemask = malloc(sdim * sizeof(int));
+	diffmask = malloc(diffdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	weight = malloc(ND * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	count1 = 0;
+	for(i=0; i<bdim; i++){
+		match = 0;
+		for(j=0; j<sdim; j++){
+			if(pbDomain[i] == psDomain[j]){
+				samemask[count] = i;
+				match = 1;
+				count++;
+				break;
+			}
+		}
+		if(match == 0){
+			diffmask[count1] = i; 
+			count1++;
+		}
+	}
+
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	count = 0;
+	compute_fixed_weight(weight, pbSize, diffmask, bCumprod, ND, diffdim);
+	for(i=0; i<NZS; i++){
+		sindex = sir[i];
+		ind_subv(sindex, sCumprod, sdim, ssubv);
+		temp = 0;
+		for(j=0; j<sdim; j++){
+			temp += ssubv[j] * bCumprod[samemask[j]];
+		}
+		for(j=0; j<ND; j++){
+			bindex = weight[j] + temp;
+			rpr[bindex] = 1 / (spr[i]);
+		}
+	}
+
+	pTemp1 = mxGetField(bigPot, 0, "T");
+	if(pTemp1)mxDestroyArray(pTemp1);
+	mxSetField(bigPot, 0, "T", pTemp);
+
+	free(samemask);
+	free(diffmask);
+	free(bCumprod);
+	free(sCumprod);
+	free(weight);
+	free(ssubv);
+}
+
+void divide_spPot_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, bdim, sdim, NB, NZB, NZS, position, bindex, sindex;
+	int     *mask, *result, *bir, *sir, *bjc, *sjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, value;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp1 = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp1);
+	bir = mxGetIr(pTemp1);
+	bjc = mxGetJc(pTemp1);
+	NZB = bjc[1];
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	if(sdim == 0){
+		value = *spr;
+		if(value == 0)value = 1;
+		for(i=0; i<NZB; i++){
+			bpr[i] /= value;
+		}	
+		return;
+	}
+
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sir, NZS, sizeof(int), compare);
+		if(result){
+			position = result - sir;
+			bpr[i] /= spr[position];
+		}
+	}
+
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int     i, j, loop, loops, nCliques, temp, count, parent, child, maximize, *distribute_order;
+	double  *pr, *pr1;
+	mxArray *pTemp, *pPreCh, *pClpot, *pSeppot;
+
+	pTemp = mxGetField(prhs[0], 0, "cliques");
+	nCliques = mxGetNumberOfElements(pTemp);
+	loops = nCliques - 1;
+	pTemp = mxGetField(prhs[0], 0, "maximize");
+	maximize = (int)mxGetScalar(pTemp);
+
+	distribute_order = malloc(2 * loops * sizeof(int));
+	pTemp = mxGetField(prhs[0], 0, "preorder");
+	pr = mxGetPr(pTemp);
+	pPreCh = mxGetField(prhs[0], 0, "preorder_children");
+	count = 0;
+	for(i=0; i<nCliques; i++){
+		temp = (int)pr[i] - 1;
+		pTemp = mxGetCell(pPreCh, temp);
+		pr1 = mxGetPr(pTemp);
+		loop = mxGetNumberOfElements(pTemp);
+		for(j=0; j<loop; j++){
+			distribute_order[count] = temp;
+			distribute_order[count + loops] = (int)pr1[j] - 1;
+			count++;
+		}
+	}
+
+	plhs[0] = mxDuplicateArray(prhs[1]);
+	plhs[1] = mxDuplicateArray(prhs[2]);
+
+	for(loop=0; loop<loops; loop++){
+		parent = distribute_order[loop];
+		child  = distribute_order[loop+loops];
+		i = nCliques * child + parent;
+		pClpot = mxGetCell(plhs[0], child);
+		pTemp = mxGetField(pClpot, 0, "T");
+		pSeppot = mxGetCell(plhs[1], i);
+		if(pTemp)
+			divide_spPot_by_spPot(pClpot, pSeppot);
+		else divide_null_by_spPot(pClpot, pSeppot);
+
+		pClpot = mxGetCell(plhs[0], parent);
+		marginal_spPot_to_spPot(pClpot, pSeppot, maximize);
+		mxSetCell(plhs[1], i, pSeppot);
+
+		pClpot = mxGetCell(plhs[0], child);
+		multiply_spPot_by_spPot(pClpot, pSeppot); 
+	}
+	free(distribute_order);
+}
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/init_pot.c b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/init_pot.c
new file mode 100644
index 00000000..5d0ed8a3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/init_pot.c
@@ -0,0 +1,637 @@
+/* C mex init_pot for in @jtree_sparse_inf_engine directory               */
+/* The file enter_evidence.m in directory @jtree_sparse_inf_engine call it*/
+
+/**************************************/
+/* init_pot.c has 6 input & 2 output  */
+/* engine                             */
+/* clqs                               */
+/* pots                               */
+/* pot_type                           */
+/* onodes                             */
+/* ndx                                */
+/*                                    */
+/* clpot                              */
+/* seppot                             */
+/**************************************/
+#include <math.h>
+#include <search.h>
+#include "mex.h"
+
+int compare(const void* src1, const void* src2){
+	int i1 = *(int*)src1 ;
+	int i2 = *(int*)src2 ;
+	return i1-i2 ;
+}
+
+void ind_subv(int index, const int *cumprod, int n, int *bsubv){
+	int i;
+
+	for (i = n-1; i >= 0; i--) {
+		bsubv[i] = ((int)floor(index / cumprod[i]));
+		index = index % cumprod[i];
+	}
+}
+
+int subv_ind(const int n, const int *cumprod, const int *subv){
+	int i, index=0;
+
+	for(i=0; i<n; i++){
+		index += subv[i] * cumprod[i];
+	}
+	return index;
+}
+
+void compute_fixed_weight(int *weight, const double *pbSize, const int *dmask, const int *bCumprod, const int ND, const int diffdim){
+	int i, j;
+	int *eff_cumprod, *subv, *diffsize, *diff_cumprod;
+
+	subv = malloc(diffdim * sizeof(int));
+	eff_cumprod = malloc(diffdim * sizeof(int));
+	diffsize = malloc(diffdim * sizeof(int));
+	diff_cumprod = malloc(diffdim * sizeof(int));
+	for(i=0; i<diffdim; i++){
+		eff_cumprod[i] = bCumprod[dmask[i]];
+		diffsize[i] = (int)pbSize[dmask[i]];
+	}
+	diff_cumprod[0] = 1;
+	for(i=0; i<diffdim-1; i++){
+		diff_cumprod[i+1] = diff_cumprod[i] * diffsize[i];
+	}
+	for(i=0; i<ND; i++){
+		ind_subv(i, diff_cumprod, diffdim, subv);
+		weight[i] = 0;
+		for(j=0; j<diffdim; j++){
+			weight[i] += eff_cumprod[j] * subv[j];
+		}
+	}
+	free(eff_cumprod);
+	free(subv);
+	free(diffsize);
+	free(diff_cumprod);
+}
+
+mxArray* convert_to_sparse(const double *table, const int NB, const int counts){
+	mxArray  *spTable;
+    int      i, k, *ir, *jc;
+    double   *sr;
+    
+	spTable = mxCreateSparse(NB, 1, counts, mxREAL);
+    sr = mxGetPr(spTable);
+    ir = mxGetIr(spTable);
+    jc = mxGetJc(spTable);
+
+    k = 0; 
+	jc[0] = 0;
+	jc[1] = counts;
+	for(i=0; i<NB; i++){
+		if(table[i] != 0.0){
+			sr[k] = table[i];
+			ir[k] = i;
+			k++;
+		}
+    }
+
+	return spTable;
+}
+
+mxArray* convert_table_to_sparse(const double *bT, const int *index, const int nzCounts, const int NB){
+	mxArray  *spTable;
+    int      i, *irs, *jcs;
+    double   *sr;
+    
+	spTable = mxCreateSparse(NB, 1, nzCounts, mxREAL);
+    sr  = mxGetPr(spTable);
+    irs = mxGetIr(spTable);
+    jcs = mxGetJc(spTable);
+
+	jcs[0] = 0;
+	jcs[1] = nzCounts;
+
+	for(i=0; i<nzCounts; i++){
+			sr[i] = bT[i];
+			irs[i] = index[i];
+    }
+	return spTable;	
+}
+
+mxArray* convert_ill_table_to_sparse(const double *bigTable, const int *sequence, const int nzCounts, const int NB){
+	mxArray *spTable;
+	int     i, temp, *irs, *jcs, count=0;
+	double  *sr;
+
+	spTable = mxCreateSparse(NB, 1, nzCounts, mxREAL);
+    sr  = mxGetPr(spTable);
+    irs = mxGetIr(spTable);
+    jcs = mxGetJc(spTable);
+
+	jcs[0] = 0;
+	jcs[1] = nzCounts;
+
+	for(i=0; i<nzCounts; i++){
+		irs[i] = sequence[count];
+		count++;
+		temp = sequence[count];
+		sr[i] = bigTable[temp];
+		count++;
+	}
+	return spTable;
+}
+
+void multiply_null_by_fuPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, NB, NS, siz_b, siz_s, ndim, nzCounts=0;
+	int     *mask, *sx, *sy, *cpsy, *subs, *s, *cpsy2, *jc;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *bTable, *sTable, value;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	siz_b = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	siz_s = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<siz_b; i++){
+		NB *= (int)pbSize[i];
+	}
+	NS = 1;
+	for(i=0; i<siz_s; i++){
+		NS *= (int)psSize[i];
+	}
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	sTable = mxGetPr(pTemp);
+	bTable = malloc(NB * sizeof(double));
+	for(i=0; i<NB; i++){
+		bTable[i] = 0;
+	}
+
+	if(NS == 1){
+		value = *sTable;
+		for(i=0; i<NB; i++){
+			bTable[i] = value;
+		}
+		nzCounts = NB;
+		pTemp = mxGetField(bigPot, 0, "T");
+		if(pTemp)mxDestroyArray(pTemp);
+		pTemp = convert_to_sparse(bTable, NB, NB);
+		mxSetField(bigPot, 0, "T", pTemp);
+		free(bTable);
+		return;
+	}
+
+	if(NS == NB){
+		for(i=0; i<NB; i++){
+			bTable[i] = sTable[i];
+			if(sTable[i] != 0) nzCounts++;
+		}
+		pTemp = mxGetField(bigPot, 0, "T");
+		if(pTemp)mxDestroyArray(pTemp);
+		pTemp = convert_to_sparse(bTable, NB, nzCounts);
+		mxSetField(bigPot, 0, "T", pTemp);
+		free(bTable);
+		return;
+	}
+
+	mask = malloc(siz_s * sizeof(int));
+	count = 0;
+	for(i=0; i<siz_s; i++){
+		for(j=0; j<siz_b; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	ndim = siz_b;
+	sx = (int *)malloc(sizeof(int)*ndim);
+	sy = (int *)malloc(sizeof(int)*ndim);
+	for(i=0; i<ndim; i++){
+		sx[i] = (int)pbSize[i];
+		sy[i] = 1;
+	}
+	for(i=0; i<count; i++){
+		sy[mask[i]] = sx[mask[i]];
+	}
+
+	s = (int *)malloc(sizeof(int)*ndim);
+	*(cpsy = (int *)malloc(sizeof(int)*ndim)) = 1;
+	subs =   (int *)malloc(sizeof(int)*ndim);
+	cpsy2 =  (int *)malloc(sizeof(int)*ndim);
+	for(i = 0; i < ndim; i++){
+		subs[i] = 0;
+		s[i] = sx[i] - 1;
+	}
+			
+	for(i = 0; i < ndim-1; i++){
+		cpsy[i+1] = cpsy[i]*sy[i]--;
+		cpsy2[i] = cpsy[i]*sy[i];
+	}
+	cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);
+
+	for(j=0; j<NB; j++){
+		bTable[j] = *sTable;
+		if(*sTable != 0.0) nzCounts++;
+		for(i = 0; i < ndim; i++){
+			if(subs[i] == s[i]){
+				subs[i] = 0;
+				if(sy[i])
+					sTable -= cpsy2[i];
+			}
+			else{
+				subs[i]++;
+				if(sy[i])
+					sTable += cpsy[i];
+				break;
+			}
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	pTemp = convert_to_sparse(bTable, NB, nzCounts);
+	mxSetField(bigPot, 0, "T", pTemp);
+	pTemp1 = mxGetField(bigPot, 0, "T");
+	jc = mxGetJc(pTemp1);
+
+	free(sx);
+	free(sy);
+	free(s);
+	free(cpsy);
+	free(subs);
+	free(cpsy2);
+    free(mask);
+	free(bTable);
+}
+
+void multiply_null_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, count1, match, temp, bdim, sdim, diffdim, NB, NS, ND, NZB, NZS, bindex, sindex, nzCounts=0;
+	int     *samemask, *diffmask, *sir, *sjc, *bCumprod, *sCumprod, *ssubv, *sequence, *weight;
+	double  *bigTable, *pbDomain, *psDomain, *pbSize, *psSize, *spr;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+	NS = 1;
+	for(i=0; i<sdim; i++){
+		NS *= (int)psSize[i];
+	}
+	ND = NB / NS;
+
+	if(ND == 1){
+		pTemp = mxGetField(bigPot, 0, "T");
+		if(pTemp)mxDestroyArray(pTemp);
+		pTemp1 = mxGetField(smallPot, 0, "T");
+		pTemp = mxDuplicateArray(pTemp1);
+		mxSetField(bigPot, 0, "T", pTemp);
+		return;
+	}
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	NZB = ND * NZS;
+
+	diffdim = bdim - sdim;
+	sequence = malloc(NZB * 2 * sizeof(int));
+	bigTable = malloc(NZB * sizeof(double));
+	samemask = malloc(sdim * sizeof(int));
+	diffmask = malloc(diffdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	weight = malloc(ND * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	count1 = 0;
+	for(i=0; i<bdim; i++){
+		match = 0;
+		for(j=0; j<sdim; j++){
+			if(pbDomain[i] == psDomain[j]){
+				samemask[count] = i;
+				match = 1;
+				count++;
+				break;
+			}
+		}
+		if(match == 0){
+			diffmask[count1] = i; 
+			count1++;
+		}
+	}
+
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	count = 0;
+	compute_fixed_weight(weight, pbSize, diffmask, bCumprod, ND, diffdim);
+	for(i=0; i<NZS; i++){
+		sindex = sir[i];
+		ind_subv(sindex, sCumprod, sdim, ssubv);
+		temp = 0;
+		for(j=0; j<sdim; j++){
+			temp += ssubv[j] * bCumprod[samemask[j]];
+		}
+		for(j=0; j<ND; j++){
+			bindex = weight[j] + temp;
+			bigTable[nzCounts] = spr[i];
+			sequence[count] = bindex;
+			count++;
+			sequence[count] = nzCounts;
+			nzCounts++;
+			count++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	qsort(sequence, nzCounts, sizeof(int) * 2, compare);
+	pTemp = convert_ill_table_to_sparse(bigTable, sequence, nzCounts, NB);
+	mxSetField(bigPot, 0, "T", pTemp);
+
+	free(sequence); 
+	free(bigTable);
+	free(samemask);
+	free(diffmask);
+	free(bCumprod);
+	free(sCumprod);
+	free(weight);
+	free(ssubv);
+}
+
+void multiply_spPot_by_fuPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, bdim, sdim, NB, NZB, bindex, sindex, nzCounts=0;
+	int     *mask, *index, *bir, *bjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *bigTable, *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, value;
+	mxArray *pTemp;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+
+	bigTable = malloc(NZB * sizeof(double));
+	index = malloc(NZB * sizeof(double));
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	for(i=0; i<NZB; i++){
+		bigTable[i] = 0;
+	}
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		value = spr[sindex];
+		if(value != 0){
+			bigTable[nzCounts] = bpr[i] * value;
+			index[nzCounts] = bindex;
+			nzCounts++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	pTemp = convert_table_to_sparse(bigTable, index, nzCounts, NB);
+	mxSetField(bigPot, 0, "T", pTemp);
+
+	free(bigTable);
+	free(index);
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+void multiply_spPot_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, bdim, sdim, NB, NZB, NZS, position, bindex, sindex, nzCounts=0;
+	int     *mask, *index, *result, *bir, *sir, *bjc, *sjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *bigTable, *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, value;
+	mxArray *pTemp;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	bigTable = malloc(NZB * sizeof(double));
+	index = malloc(NZB * sizeof(double));
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	for(i=0; i<NZB; i++){
+		bigTable[i] = 0;
+	}
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		value = bpr[i];
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sir, NZS, sizeof(int), compare);
+		if(result){
+			position = result - sir;
+			value *= spr[position];
+			bigTable[nzCounts] = value;
+			index[nzCounts] = bindex;
+			nzCounts++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	pTemp = convert_table_to_sparse(bigTable, index, nzCounts, NB);
+	mxSetField(bigPot, 0, "T", pTemp);
+
+	free(bigTable);
+	free(index);
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int     i, j, c, loop, nNodes, nCliques, ndomain, dims[2];
+	double  *pClqs, *pr, *pt, *pSize;
+	mxArray *pTemp, *pTemp1, *pStruct, *pCliques, *pBigpot, *pSmallpot;
+	const char *field_names[] = {"domain", "T", "sizes"};
+
+	nNodes = mxGetNumberOfElements(prhs[1]);
+	pCliques = mxGetField(prhs[0], 0, "cliques");
+	nCliques = mxGetNumberOfElements(pCliques);
+	pTemp = mxGetField(prhs[0], 0, "eff_node_sizes");
+	pSize = mxGetPr(pTemp);
+
+	plhs[0] = mxCreateCellArray(1, &nCliques);
+    for(i=0; i<nCliques; i++){
+        pStruct = mxCreateStructMatrix(1, 1, 3, field_names);
+		mxSetCell(plhs[0], i, pStruct);
+		pTemp = mxGetCell(pCliques, i);
+		ndomain = mxGetNumberOfElements(pTemp);
+		pt = mxGetPr(pTemp);
+		pTemp1 = mxDuplicateArray(pTemp);
+		mxSetField(pStruct, 0, "domain", pTemp1);
+		
+		pTemp = mxCreateDoubleMatrix(1, ndomain, mxREAL);
+		mxSetField(pStruct, 0, "sizes", pTemp);
+		pr = mxGetPr(pTemp);
+        for(j=0; j<ndomain; j++){
+            pr[j] = pSize[(int)pt[j]-1];
+        }
+    }
+
+	pClqs = mxGetPr(prhs[1]);
+	for(loop=0; loop<nNodes; loop++){
+		c = (int)pClqs[loop] - 1;
+		pSmallpot = mxGetCell(prhs[2], loop);
+		pTemp = mxGetField(pSmallpot, 0, "T");
+		pBigpot = mxGetCell(plhs[0], c);
+		pTemp1 = mxGetField(pBigpot, 0, "T");
+		if(pTemp1){
+			if(mxIsSparse(pTemp))
+				multiply_spPot_by_spPot(pBigpot, pSmallpot);
+			else multiply_spPot_by_fuPot(pBigpot, pSmallpot);
+		}
+		else{
+			if(mxIsSparse(pTemp))
+				multiply_null_by_spPot(pBigpot, pSmallpot);
+			else multiply_null_by_fuPot(pBigpot, pSmallpot);
+		}		
+	}
+
+	dims[0] = nCliques;
+	dims[1] = nCliques;
+	plhs[1] = mxCreateCellArray(2, dims);
+}
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/init_pot1.c b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/init_pot1.c
new file mode 100644
index 00000000..b3a6a66d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/init_pot1.c
@@ -0,0 +1,636 @@
+/* C mex init_pot for in @jtree_sparse_inf_engine directory               */
+/* The file enter_evidence.m in directory @jtree_sparse_inf_engine call it*/
+
+/**************************************/
+/* init_pot.c has 6 input & 2 output  */
+/* engine                             */
+/* clqs                               */
+/* pots                               */
+/* pot_type                           */
+/* onodes                             */
+/* ndx                                */
+/*                                    */
+/* clpot                              */
+/* seppot                             */
+/**************************************/
+#include <math.h>
+#include <search.h>
+#include "mex.h"
+
+int compare(const void* src1, const void* src2){
+	int i1 = *(int*)src1 ;
+	int i2 = *(int*)src2 ;
+	return i1-i2 ;
+}
+
+void ind_subv(int index, const int *cumprod, int n, int *bsubv){
+	int i;
+
+	for (i = n-1; i >= 0; i--) {
+		bsubv[i] = ((int)floor(index / cumprod[i]));
+		index = index % cumprod[i];
+	}
+}
+
+int subv_ind(const int n, const int *cumprod, const int *subv){
+	int i, index=0;
+
+	for(i=0; i<n; i++){
+		index += subv[i] * cumprod[i];
+	}
+	return index;
+}
+
+void compute_fixed_weight(int *weight, const double *pbSize, const int *dmask, const int *bCumprod, const int ND, const int diffdim){
+	int i, j;
+	int *eff_cumprod, *subv, *diffsize, *diff_cumprod;
+
+	subv = malloc(diffdim * sizeof(int));
+	eff_cumprod = malloc(diffdim * sizeof(int));
+	diffsize = malloc(diffdim * sizeof(int));
+	diff_cumprod = malloc(diffdim * sizeof(int));
+	for(i=0; i<diffdim; i++){
+		eff_cumprod[i] = bCumprod[dmask[i]];
+		diffsize[i] = (int)pbSize[dmask[i]];
+	}
+	diff_cumprod[0] = 1;
+	for(i=0; i<diffdim-1; i++){
+		diff_cumprod[i+1] = diff_cumprod[i] * diffsize[i];
+	}
+	for(i=0; i<ND; i++){
+		ind_subv(i, diff_cumprod, diffdim, subv);
+		weight[i] = 0;
+		for(j=0; j<diffdim; j++){
+			weight[i] += eff_cumprod[j] * subv[j];
+		}
+	}
+	free(eff_cumprod);
+	free(subv);
+	free(diffsize);
+	free(diff_cumprod);
+}
+
+void reset_nzmax(mxArray *spArray, const int old_nzmax, const int new_nzmax){
+	double *ptr;
+	void   *newptr;
+	int    *ir, *jc;
+	int    nbytes;
+
+	if(new_nzmax == old_nzmax) return;
+	nbytes = new_nzmax * sizeof(*ptr);
+	ptr = mxGetPr(spArray);
+	newptr = mxRealloc(ptr, nbytes);
+	mxSetPr(spArray, newptr);
+	nbytes = new_nzmax * sizeof(*ir);
+	ir = mxGetIr(spArray);
+	newptr = mxRealloc(ir, nbytes);
+	mxSetIr(spArray, newptr);
+	jc = mxGetJc(spArray);
+	jc[0] = 0;
+	jc[1] = new_nzmax;
+	mxSetNzmax(spArray, new_nzmax);
+}
+
+mxArray* convert_table_to_sparse(const double *bT, const int *index, const int nzCounts, const int NB){
+	mxArray  *spTable;
+    int      i, *irs, *jcs;
+    double   *sr;
+    
+	spTable = mxCreateSparse(NB, 1, nzCounts, mxREAL);
+    sr  = mxGetPr(spTable);
+    irs = mxGetIr(spTable);
+    jcs = mxGetJc(spTable);
+
+	jcs[0] = 0;
+	jcs[1] = nzCounts;
+
+	for(i=0; i<nzCounts; i++){
+			sr[i] = bT[i];
+			irs[i] = index[i];
+    }
+	return spTable;	
+}
+
+mxArray* convert_ill_table_to_sparse(const double *bigTable, const int *sequence, const int nzCounts, const int NB){
+	mxArray *spTable;
+	int     i, temp, *irs, *jcs, count=0;
+	double  *sr;
+
+	spTable = mxCreateSparse(NB, 1, nzCounts, mxREAL);
+    sr  = mxGetPr(spTable);
+    irs = mxGetIr(spTable);
+    jcs = mxGetJc(spTable);
+
+	jcs[0] = 0;
+	jcs[1] = nzCounts;
+
+	for(i=0; i<nzCounts; i++){
+		irs[i] = sequence[count];
+		count++;
+		temp = sequence[count];
+		sr[i] = bigTable[temp];
+		count++;
+	}
+	return spTable;
+}
+
+void multiply_null_by_fuPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, NB, NS, siz_b, siz_s, ndim, nzCounts=0;
+	int     *mask, *sx, *sy, *cpsy, *subs, *s, *cpsy2, *bir, *bjc;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *spr, *bpr, value;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	siz_b = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	siz_s = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<siz_b; i++){
+		NB *= (int)pbSize[i];
+	}
+	NS = 1;
+	for(i=0; i<siz_s; i++){
+		NS *= (int)psSize[i];
+	}
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+
+	pTemp1 = mxCreateSparse(NB, 1, NB, mxREAL);
+	bpr = mxGetPr(pTemp1);
+	bir = mxGetIr(pTemp1);
+	bjc = mxGetJc(pTemp1);
+	bjc[0] = 0;
+	bjc[1] = NB;
+
+	if(NS == 1){
+		value = *spr;
+		for(i=0; i<NB; i++){
+			bpr[i] = value;
+			bir[i] = i;
+		}
+		nzCounts = NB;
+		pTemp = mxGetField(bigPot, 0, "T");
+		if(pTemp)mxDestroyArray(pTemp);
+		reset_nzmax(pTemp1, NB, nzCounts);
+		mxSetField(bigPot, 0, "T", pTemp1);
+		return;
+	}
+
+	if(NS == NB){
+		for(i=0; i<NB; i++){
+			if(spr[i] != 0){
+				bpr[nzCounts] = spr[i];
+				bir[nzCounts] = i;
+				nzCounts++;
+			}
+		}
+		pTemp = mxGetField(bigPot, 0, "T");
+		if(pTemp)mxDestroyArray(pTemp);
+		reset_nzmax(pTemp1, NB, nzCounts);
+		mxSetField(bigPot, 0, "T", pTemp1);
+		return;
+	}
+
+	mask = malloc(siz_s * sizeof(int));
+	count = 0;
+	for(i=0; i<siz_s; i++){
+		for(j=0; j<siz_b; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	ndim = siz_b;
+	sx = (int *)malloc(sizeof(int)*ndim);
+	sy = (int *)malloc(sizeof(int)*ndim);
+	for(i=0; i<ndim; i++){
+		sx[i] = (int)pbSize[i];
+		sy[i] = 1;
+	}
+	for(i=0; i<count; i++){
+		sy[mask[i]] = sx[mask[i]];
+	}
+
+	s = (int *)malloc(sizeof(int)*ndim);
+	*(cpsy = (int *)malloc(sizeof(int)*ndim)) = 1;
+	subs =   (int *)malloc(sizeof(int)*ndim);
+	cpsy2 =  (int *)malloc(sizeof(int)*ndim);
+	for(i = 0; i < ndim; i++){
+		subs[i] = 0;
+		s[i] = sx[i] - 1;
+	}
+			
+	for(i = 0; i < ndim-1; i++){
+		cpsy[i+1] = cpsy[i]*sy[i]--;
+		cpsy2[i] = cpsy[i]*sy[i];
+	}
+	cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);
+
+	for(j=0; j<NB; j++){
+		if(*spr != 0){
+			bpr[nzCounts] = *spr;
+			bir[nzCounts] = j;
+			nzCounts++;
+		}
+		for(i = 0; i < ndim; i++){
+			if(subs[i] == s[i]){
+				subs[i] = 0;
+				if(sy[i])
+					spr -= cpsy2[i];
+			}
+			else{
+				subs[i]++;
+				if(sy[i])
+					spr += cpsy[i];
+				break;
+			}
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	reset_nzmax(pTemp1, NB, nzCounts);
+	mxSetField(bigPot, 0, "T", pTemp1);
+
+	free(sx);
+	free(sy);
+	free(s);
+	free(cpsy);
+	free(subs);
+	free(cpsy2);
+    free(mask);
+}
+
+void multiply_null_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, count1, match, temp, bdim, sdim, diffdim, NB, NS, ND, NZB, NZS, bindex, sindex, nzCounts=0;
+	int     *samemask, *diffmask, *sir, *sjc, *bCumprod, *sCumprod, *ssubv, *sequence, *weight;
+	double  *bigTable, *pbDomain, *psDomain, *pbSize, *psSize, *spr;
+	mxArray *pTemp, *pTemp1;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+	NS = 1;
+	for(i=0; i<sdim; i++){
+		NS *= (int)psSize[i];
+	}
+	ND = NB / NS;
+
+	if(ND == 1){
+		pTemp = mxGetField(bigPot, 0, "T");
+		if(pTemp)mxDestroyArray(pTemp);
+		pTemp1 = mxGetField(smallPot, 0, "T");
+		pTemp = mxDuplicateArray(pTemp1);
+		mxSetField(bigPot, 0, "T", pTemp);
+		return;
+	}
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	NZB = ND * NZS;
+
+	diffdim = bdim - sdim;
+	sequence = malloc(NZB * 2 * sizeof(int));
+	bigTable = malloc(NZB * sizeof(double));
+	samemask = malloc(sdim * sizeof(int));
+	diffmask = malloc(diffdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	weight = malloc(ND * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	count1 = 0;
+	for(i=0; i<bdim; i++){
+		match = 0;
+		for(j=0; j<sdim; j++){
+			if(pbDomain[i] == psDomain[j]){
+				samemask[count] = i;
+				match = 1;
+				count++;
+				break;
+			}
+		}
+		if(match == 0){
+			diffmask[count1] = i; 
+			count1++;
+		}
+	}
+
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	count = 0;
+	compute_fixed_weight(weight, pbSize, diffmask, bCumprod, ND, diffdim);
+	for(i=0; i<NZS; i++){
+		sindex = sir[i];
+		ind_subv(sindex, sCumprod, sdim, ssubv);
+		temp = 0;
+		for(j=0; j<sdim; j++){
+			temp += ssubv[j] * bCumprod[samemask[j]];
+		}
+		for(j=0; j<ND; j++){
+			bindex = weight[j] + temp;
+			bigTable[nzCounts] = spr[i];
+			sequence[count] = bindex;
+			count++;
+			sequence[count] = nzCounts;
+			nzCounts++;
+			count++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	qsort(sequence, nzCounts, sizeof(int) * 2, compare);
+	pTemp = convert_ill_table_to_sparse(bigTable, sequence, nzCounts, NB);
+	mxSetField(bigPot, 0, "T", pTemp);
+
+	free(sequence); 
+	free(bigTable);
+	free(samemask);
+	free(diffmask);
+	free(bCumprod);
+	free(sCumprod);
+	free(weight);
+	free(ssubv);
+}
+
+void multiply_spPot_by_fuPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, bdim, sdim, NB, NZB, bindex, sindex, nzCounts=0;
+	int     *mask, *index, *bir, *bjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *bigTable, *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, value;
+	mxArray *pTemp;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+
+	bigTable = malloc(NZB * sizeof(double));
+	index = malloc(NZB * sizeof(double));
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		value = spr[sindex];
+		if(value != 0){
+			bigTable[nzCounts] = bpr[i] * value;
+			index[nzCounts] = bindex;
+			nzCounts++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	pTemp = convert_table_to_sparse(bigTable, index, nzCounts, NB);
+	mxSetField(bigPot, 0, "T", pTemp);
+
+	free(bigTable);
+	free(index);
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+void multiply_spPot_by_spPot(mxArray *bigPot, const mxArray *smallPot){
+	int     i, j, count, bdim, sdim, NB, NZB, NZS, position, bindex, sindex, nzCounts=0;
+	int     *mask, *index, *result, *bir, *sir, *bjc, *sjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *bigTable, *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, value;
+	mxArray *pTemp;
+
+	pTemp = mxGetField(bigPot, 0, "domain");
+	pbDomain = mxGetPr(pTemp);
+	bdim = mxGetNumberOfElements(pTemp);
+	pTemp = mxGetField(smallPot, 0, "domain");
+	psDomain = mxGetPr(pTemp);
+	sdim = mxGetNumberOfElements(pTemp);
+
+	pTemp = mxGetField(bigPot, 0, "sizes");
+	pbSize = mxGetPr(pTemp);
+	pTemp = mxGetField(smallPot, 0, "sizes");
+	psSize = mxGetPr(pTemp);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	bpr = mxGetPr(pTemp);
+	bir = mxGetIr(pTemp);
+	bjc = mxGetJc(pTemp);
+	NZB = bjc[1];
+
+	pTemp = mxGetField(smallPot, 0, "T");
+	spr = mxGetPr(pTemp);
+	sir = mxGetIr(pTemp);
+	sjc = mxGetJc(pTemp);
+	NZS = sjc[1];
+
+	bigTable = malloc(NZB * sizeof(double));
+	index = malloc(NZB * sizeof(double));
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	for(i=0; i<NZB; i++){
+		bigTable[i] = 0;
+	}
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		value = bpr[i];
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sir, NZS, sizeof(int), compare);
+		if(result){
+			position = result - sir;
+			value *= spr[position];
+			bigTable[nzCounts] = value;
+			index[nzCounts] = bindex;
+			nzCounts++;
+		}
+	}
+
+	pTemp = mxGetField(bigPot, 0, "T");
+	if(pTemp)mxDestroyArray(pTemp);
+	pTemp = convert_table_to_sparse(bigTable, index, nzCounts, NB);
+	mxSetField(bigPot, 0, "T", pTemp);
+
+	free(bigTable);
+	free(index);
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
+
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int     i, j, c, loop, nNodes, nCliques, ndomain, dims[2];
+	double  *pClqs, *pr, *pt, *pSize;
+	mxArray *pTemp, *pTemp1, *pStruct, *pCliques, *pBigpot, *pSmallpot;
+	const char *field_names[] = {"domain", "T", "sizes"};
+
+	nNodes = mxGetNumberOfElements(prhs[1]);
+	pCliques = mxGetField(prhs[0], 0, "cliques");
+	nCliques = mxGetNumberOfElements(pCliques);
+	pTemp = mxGetField(prhs[0], 0, "eff_node_sizes");
+	pSize = mxGetPr(pTemp);
+
+	plhs[0] = mxCreateCellArray(1, &nCliques);
+    for(i=0; i<nCliques; i++){
+        pStruct = mxCreateStructMatrix(1, 1, 3, field_names);
+		mxSetCell(plhs[0], i, pStruct);
+		pTemp = mxGetCell(pCliques, i);
+		ndomain = mxGetNumberOfElements(pTemp);
+		pt = mxGetPr(pTemp);
+		pTemp1 = mxDuplicateArray(pTemp);
+		mxSetField(pStruct, 0, "domain", pTemp1);
+		
+		pTemp = mxCreateDoubleMatrix(1, ndomain, mxREAL);
+		mxSetField(pStruct, 0, "sizes", pTemp);
+		pr = mxGetPr(pTemp);
+        for(j=0; j<ndomain; j++){
+            pr[j] = pSize[(int)pt[j]-1];
+        }
+    }
+
+	pClqs = mxGetPr(prhs[1]);
+	for(loop=0; loop<nNodes; loop++){
+		c = (int)pClqs[loop] - 1;
+		pSmallpot = mxGetCell(prhs[2], loop);
+		pTemp = mxGetField(pSmallpot, 0, "T");
+		pBigpot = mxGetCell(plhs[0], c);
+		pTemp1 = mxGetField(pBigpot, 0, "T");
+		if(pTemp1){
+			if(mxIsSparse(pTemp))
+				multiply_spPot_by_spPot(pBigpot, pSmallpot);
+			else multiply_spPot_by_fuPot(pBigpot, pSmallpot);
+		}
+		else{
+			if(mxIsSparse(pTemp))
+				multiply_null_by_spPot(pBigpot, pSmallpot);
+			else multiply_null_by_fuPot(pBigpot, pSmallpot);
+		}		
+	}
+
+	dims[0] = nCliques;
+	dims[1] = nCliques;
+	plhs[1] = mxCreateCellArray(2, dims);
+}
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/init_pot1.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/init_pot1.m
new file mode 100644
index 00000000..857e6266
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/old/init_pot1.m
@@ -0,0 +1,20 @@
+function [clpot, seppot] = init_pot(engine, clqs, pots, pot_type, onodes, ndx)
+% INIT_POT Initialise potentials with evidence (jtree_inf)
+% function [clpot, seppot] = init_pot(engine, clqs, pots, pot_type, onodes)
+
+cliques = engine.cliques;
+bnet = bnet_from_engine(engine);
+% 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}, bnet.node_sizes(:), bnet.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
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/set_fields.m b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/set_fields.m
new file mode 100644
index 00000000..e75cfa45
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@jtree_sparse_inf_engine/set_fields.m
@@ -0,0 +1,13 @@
+function engine = set_fields(engine, varargin)
+% SET_FIELDS Set the fields for a generic engine
+% engine = set_fields(engine, name/value pairs)
+%
+% e.g., engine = set_fields(engine, 'maximize', 1)
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'maximize', engine.maximize = args{i+1};
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/CVS/Entries
new file mode 100644
index 00000000..c9482cbd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/CVS/Entries
@@ -0,0 +1,4 @@
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/likelihood_weighting_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//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/CVS/Repository
new file mode 100644
index 00000000..e39429d7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@likelihood_weighting_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..62e252aa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/enter_evidence.m
@@ -0,0 +1,39 @@
+function [engine, ll] = enter_evidence(engine, evidence, nsamples)
+% ENTER_EVIDENCE Add the specified evidence to the network (likelihood_weighting)
+% [engine, ll] = enter_evidence(engine, evidence, nsamples)
+% evidence{i} = [] if if X(i) is hidden, and otherwise contains its observed value (scalar or column vector)
+%
+% If nsamples is not specified, the value specified when the engine was created will be used.
+% ll (log-likelihood) is set to [].
+
+ll = [];
+if nargin < 3, nsamples = engine.nsamples; end
+
+bnet = bnet_from_engine(engine);
+N = length(bnet.dag);
+samples = cell(nsamples, N);
+weights = zeros(1, nsamples);
+
+ns = bnet.node_sizes;
+original_evidence = evidence;
+observed = ~isemptycell(original_evidence);
+for s=1:nsamples
+  evidence = original_evidence(:); % must be a column vector
+  w = 1;
+  for i=1:N
+    ps = parents(bnet.dag, i);
+    e = bnet.equiv_class(i);
+    if observed(i)
+      p = exp(log_prob_node(bnet.CPD{e}, evidence(i), evidence(ps)));
+      w = w * p;
+    else
+      x = sample_node(bnet.CPD{e}, evidence(ps));
+      evidence{i} = x;
+    end
+  end
+  samples(s,:) = evidence;
+  weights(s) = w;
+end                 
+
+engine.samples = samples;
+engine.weights = weights;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/likelihood_weighting_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/likelihood_weighting_inf_engine.m
new file mode 100644
index 00000000..eb1794fa
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/likelihood_weighting_inf_engine.m
@@ -0,0 +1,25 @@
+function engine = likelihood_weighting_inf_engine(bnet, varargin)
+% LIKELIHOOD_WEIGHTING_INF_ENGINE 
+% engine = likelihood_weighting_inf_engine(bnet, ...)
+%
+% Optional arguments [defaults]
+% nsamples - [500]
+
+nsamples = 500;
+
+if nargin >= 2
+  args = varargin;
+  nargs = length(args);
+  for i=1:2:nargs
+    switch args{i},
+     case 'nsamples', nsamples= args{i+1};
+     otherwise,
+      error(['invalid argument name ' args{i}]);
+    end
+  end
+end   
+
+engine.nsamples = nsamples;
+engine.samples = [];
+engine.weights = [];
+engine = class(engine, 'likelihood_weighting_inf_engine', inf_engine(bnet));
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..d00ee606
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@likelihood_weighting_inf_engine/marginal_nodes.m
@@ -0,0 +1,53 @@
+function marginal = marginal_nodes(engine, nodes)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (likelihood_weighting)
+% marginal = marginal_nodes(engine, nodes)
+
+bnet = bnet_from_engine(engine);
+ddom = myintersect(nodes, bnet.dnodes);
+cdom = myintersect(nodes, bnet.cnodes);
+nsamples = size(engine.samples, 1);
+ns = bnet.node_sizes;
+
+%w = normalise(engine.weights);
+w = engine.weights;
+if mysubset(nodes, ddom)
+  T = 0*myones(ns(nodes));
+  P = prod(ns(nodes));
+  indices = ind2subv(ns(nodes), 1:P);
+  samples = reshape(cat(1, engine.samples{:,nodes}), nsamples, length(nodes));
+  for j = 1:P
+    rows = find_rows(samples, indices(j,:));
+    T(j) = sum(w(rows));
+  end
+  T = normalise(T);
+  marginal.T = T;
+elseif subset(nodes, cdom)
+  samples = reshape(cat(1, engine.samples{:,nodes}), nsamples*sum(ns(nodes)), length(nodes));
+  [marginal.mu, marginal.Sigma] =  wstats(samples', normalise(w));
+else
+  error('can''t handle mixed marginals yet');
+end
+
+marginal.domain = nodes;
+
+%%%%%%%%%
+
+function rows = find_rows(M, v)
+% FINDROWS Find rows which are equal to a specified vector
+% rows = findrows(M, v)
+% Each row of M is a sample
+
+temp = abs(M - repmat(v, size(M, 1), 1));
+rows = find(sum(temp,2) == 0);      
+
+%%%%%%%%
+
+function [mu, Sigma] = wstats(X, w)
+
+% Computes the weighted mean and weighted covariance matrix for a given
+% set of observations X(:,i), and a set of normalised weights w(i).
+% Each column of X is a sample.
+
+d = X - repmat(X * w', 1, size(X, 2));
+mu = sum(X .* repmat(w, size(X, 1), 1), 2);
+Sigma = d * diag(w) * d';          
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Entries
new file mode 100644
index 00000000..50ed260c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Entries
@@ -0,0 +1,7 @@
+/bethe_free_energy.m/1.1.1.1/Sun Jul  6 20:57:18 2003//
+/enter_evidence.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/loopy_converged.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/marginal_family.m/1.1.1.1/Fri Oct 18 20:05:16 2002//
+/marginal_nodes.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/pearl_inf_engine.m/1.1.1.1/Sat Jan 11 18:53:28 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Entries.Log
new file mode 100644
index 00000000..b2cd71e0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/private////
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Repository
new file mode 100644
index 00000000..d88c6406
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@pearl_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/bethe_free_energy.m b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/bethe_free_energy.m
new file mode 100644
index 00000000..67495fd0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/bethe_free_energy.m
@@ -0,0 +1,50 @@
+function loglik = bethe_free_energy(engine, evidence)
+% BETHE_FREE_ENERGY Compute Bethe free energy approximation to the log likelihood
+% loglik = bethe_free_energy(engine, evidence)
+%
+% The Bethe free energy is given by an exact energy term and an approximate entropy term.
+% Energy
+%  E = -sum_f sum_i b(f,i) ln theta(f,i)
+% where b(f,i) = approximate Pr(family f = i) 
+% and theta(f,i) = Pr(f = i)
+% Entropy
+%  S = H1 - H2
+%  H1 = sum_f sum_p H(b(f))
+% where b(f) = belief on family f, H(.) = entropy
+%  H2 = sum_n (q(n)-1) H(b(n))
+% where q(n) = num. neighbors of n
+%
+% This function was written by Yair Weiss, 8/22/01.
+
+hidden = find(isemptycell(evidence));
+bnet = bnet_from_engine(engine);
+N = length(bnet.dag);
+
+add_ev = 1;
+E=0;H1=0;H2=0;
+loglik=0;
+for n=1:N
+  ps=parents(bnet.dag,n);
+  if (length(ps)==0) % root node
+    qi=length(children(bnet.dag,n))-1;
+  else
+    qi=length(children(bnet.dag,n));
+  end
+  bf = marginal_family(engine, n, add_ev);
+  bf = bf.T(:);
+  e = bnet.equiv_class(n);
+  T = CPD_to_CPT(bnet.CPD{e});
+  T = T(:);
+  E = E-sum(log(T+(T==0)).*bf);
+
+  if length(ps) > 0
+    % root nodes don't count as fmailies
+    H1 = H1+sum(log(bf+(bf==0)).*bf);
+  end
+  
+  bi = marginal_nodes(engine, n, add_ev);
+  bi = bi.T(:);
+  H2 = H2+qi*sum(log(bi+(bi==0)).*bi);
+end
+loglik=E+H1-H2;
+loglik=-loglik;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..65e45b15
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/enter_evidence.m
@@ -0,0 +1,153 @@
+function [engine, loglik, niter] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (pearl)
+% [engine, loglik, num_iter] = enter_evidence(engine, evidence, ...)
+% evidence{i} = [] if if X(i) 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 pa irs:
+% [default value in brackets]
+%
+% maximize - if 1, does max-product instead of sum-product [0]
+% 'filename' -  msgs will be printed to this file, so you can assess convergence while it runs [engine.filename]
+%
+% e.g., engine = enter_evidence(engine, ev, 'maximize', 1)
+%     
+% For discrete nodes, loglik is the negative Bethe free energy evaluated at the final beliefs.
+% For Gaussian nodes, loglik is currently always 0.
+%
+% 'num_iter' returns the number of iterations used.
+
+maximize = 0;
+filename = engine.filename;
+
+% 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 'filename', filename = args{i+1};
+     otherwise,
+      error(['invalid argument name ' args{i}]);
+    end
+  end
+end
+    
+
+if maximize
+  error('can''t handle max-prop yet')
+end
+
+engine.maximize = maximize;
+engine.filename = filename;
+engine.bel = []; % reset if necessary
+
+bnet = bnet_from_engine(engine);
+N = length(bnet.dag);
+ns = bnet.node_sizes(:);
+
+observed_bitv = ~isemptycell(evidence);
+disconnected = find(engine.disconnected_nodes_bitv);
+if ~all(observed_bitv(disconnected))
+  error(['The following discrete nodes must be observed: ' num2str(disconnected)])
+end
+msg = init_pearl_msgs(engine.msg_type, engine.msg_dag, ns, evidence);
+
+niter = 1;
+switch engine.protocol
+ case 'parallel', [msg, niter] = parallel_protocol(engine, evidence, msg);
+ case 'tree', msg = tree_protocol(engine, evidence, msg);
+ otherwise,
+  error(['unrecognized protocol ' engine.protocol])
+end
+engine.niter = niter;
+
+engine.marginal = cell(1,N);
+nodes = find(~engine.disconnected_nodes_bitv);
+for n=nodes(:)'
+  engine.marginal{n} = compute_bel(engine.msg_type, msg{n}.pi, msg{n}.lambda);
+end
+
+engine.evidence = evidence; % needed by marginal_nodes and marginal_family
+engine.msg = msg;  % needed by marginal_family
+
+if (nargout >= 2)
+  if (engine.msg_type == 'd')
+    loglik = bethe_free_energy(engine, evidence);
+  else
+    loglik = 0;
+  end
+end
+
+
+
+%%%%%%%%%%%
+
+function msg =  init_pearl_msgs(msg_type, dag, ns, evidence)
+% INIT_MSGS Initialize the lambda/pi message and state vectors
+% msg =  init_msgs(dag, ns, evidence)
+%
+
+N = length(dag);
+msg = cell(1,N);
+observed = ~isemptycell(evidence);
+lam_msg = 1;
+
+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} = mk_msg(msg_type, ns(p));
+  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} = mk_msg(msg_type, ns(n), lam_msg);
+  end
+
+  msg{n}.lambda = mk_msg(msg_type, ns(n), lam_msg);
+  msg{n}.pi = mk_msg(msg_type, ns(n));
+  
+  if observed(n)
+    msg{n}.lambda_from_self = mk_msg_with_evidence(msg_type, ns(n), evidence{n});
+  else
+    msg{n}.lambda_from_self = mk_msg(msg_type, ns(n), lam_msg);
+  end
+end
+
+
+
+%%%%%%%%%
+
+function msg =  mk_msg(msg_type, sz, is_lambda_msg)
+
+if nargin < 3, is_lambda_msg = 0; end
+
+switch msg_type
+ case 'd', msg = ones(sz, 1);
+ case 'g', 
+  if is_lambda_msg
+    msg.precision = zeros(sz, sz);
+    msg.info_state = zeros(sz, 1);
+  else
+    msg.Sigma = zeros(sz, sz);
+    msg.mu = zeros(sz,1);
+  end
+end
+
+%%%%%%%%%%%%
+
+function msg = mk_msg_with_evidence(msg_type, sz, val)
+
+switch msg_type
+ case 'd',
+  msg = zeros(sz, 1);
+  msg(val) = 1;
+ case 'g',
+  %msg.observed_val = val(:);
+  msg.precision = inf;
+  msg.mu = val(:);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/loopy_converged.m b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/loopy_converged.m
new file mode 100644
index 00000000..fba4f2fd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/loopy_converged.m
@@ -0,0 +1,13 @@
+function niter = loopy_converged(engine)
+% LOOPY_CONVERGED Did loopy belief propagation converge? 0 means no, eles we return the num. iterations.
+% function niter = loopy_converged(engine)
+%
+% We use a simple heuristic: we say convergence occurred if the number of iterations
+% used was less than the maximum allowed.
+
+if engine.niter == engine.max_iter
+  niter = 0;
+else
+  niter = engine.niter;
+end
+%conv = (strcmp(engine.protocol, 'tree') | (engine.niter < engine.max_iter));
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/marginal_family.m b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/marginal_family.m
new file mode 100644
index 00000000..9226afda
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/marginal_family.m
@@ -0,0 +1,80 @@
+function m = marginal_family(engine, n, add_ev)
+% MARGINAL_FAMILY Compute the marginal on i's family (loopy)
+% m = marginal_family(engine, n, add_ev)
+
+if nargin < 3, add_ev = 0; end
+
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes;
+ps = parents(bnet.dag, n);
+dom = [ps n];
+CPD = bnet.CPD{bnet.equiv_class(n)};
+
+switch engine.msg_type
+  case 'd',
+   % 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))   
+   % beta == lambda, alpha == pi, alpha from each parent = pi msg
+   % In general, if A,B are parents of C,
+   % P(A,B,C) = P(C|A,B) pi_msg(A->C) pi_msg(B->C) lambda(C)
+   % where lambda(C) = P(ev below and including C|C) = prod incoming lamba_msg(children->C)
+   % and pi_msg(X->C) = P(X|ev above) etc
+   
+   T = dpot(dom, ns(dom), CPD_to_CPT(CPD));
+   for j=1:length(ps)
+     p = ps(j);
+     pi_msg = dpot(p, ns(p), engine.msg{n}.pi_from_parent{j});
+     T = multiply_by_pot(T, pi_msg);
+   end         
+   lambda = dpot(n, ns(n), engine.msg{n}.lambda);
+   T = multiply_by_pot(T, lambda);
+   T = normalize_pot(T);
+   m = pot_to_marginal(T);
+   if ~add_ev
+     m.T = shrink_obs_dims_in_table(m.T, dom, engine.evidence);
+   end
+ case 'g',
+  if engine.disconnected_nodes_bitv(n)
+    m.T = 1;
+    m.domain = dom;
+    if add_ev
+      m = add_ev_to_dmarginal(m, engine.evidence, ns)
+    end
+    return;
+  end
+
+  [m, C, W] = gaussian_CPD_params_given_dps(CPD, dom, engine.evidence);
+  cdom = myintersect(dom, bnet.cnodes);
+  pot = linear_gaussian_to_cpot(m, C, W, dom, ns, cdom, engine.evidence); 
+  % linear_gaussian_to_cpot will set the effective size of observed nodes to 0,
+  % so we need to do this explicitely for the messages, too,
+  % so they are all the same size.
+  obs_bitv = ~isemptycell(engine.evidence);
+  ps = parents(engine.msg_dag, n);
+  for j=1:length(ps)
+    p = ps(j);
+    msg = engine.msg{n}.pi_from_parent{j};
+    if obs_bitv(p)
+      pi_msg = mpot(p, 0);
+    else
+      pi_msg = mpot(p, ns(p), 0, msg.mu, msg.Sigma);
+    end
+    pot = multiply_by_pot(pot, mpot_to_cpot(pi_msg));
+  end         
+  msg = engine.msg{n}.lambda;
+  if obs_bitv(n)
+    lambda = cpot(n, 0);
+  else
+    lambda = cpot(n, ns(n), 0, msg.info_state, msg.precision);
+  end
+  pot = multiply_by_pot(pot, lambda);
+  m = pot_to_marginal(pot);
+  if add_ev
+    m = add_evidence_to_gmarginal(m, engine.evidence, bnet.node_sizes, bnet.cnodes);
+  end
+end
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..bee6ec37
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/marginal_nodes.m
@@ -0,0 +1,43 @@
+function marginal = marginal_nodes(engine, query, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (loopy)
+% marginal = marginal_nodes(engine, query, add_ev)
+%
+% 'query' must be a single node.
+% add_ev is an optional argument; if 1, observed nodes will be set to their original size,
+% otherwise they will be treated like points.
+   
+if nargin < 3, add_ev = 0; end
+
+if length(query) > 1
+  error('can only compute marginal on single nodes or families')
+end
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes(:);
+
+switch engine.msg_type
+ case 'd',
+  T = engine.marginal{query};
+  if ~add_ev
+    marginal.T = shrink_obs_dims_in_table(T, query, engine.evidence);
+  else
+    marginal.T = T;
+  end
+  marginal.domain = query;
+ 
+ case 'g',
+  if engine.disconnected_nodes_bitv(query)
+    marginal.T = 1;
+    marginal.domain = query;
+    if add_ev
+      marginal = add_ev_to_dmarginal(marginal, engine.evidence, ns)
+    end
+    return;
+  end
+
+  marginal = engine.marginal{query};
+  marginal.domain = query;
+  if ~add_ev
+    marginal = shrink_obs_dims_in_gaussian(marginal, query, engine.evidence, ns);
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/pearl_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/pearl_inf_engine.m
new file mode 100644
index 00000000..d4eb3059
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/pearl_inf_engine.m
@@ -0,0 +1,158 @@
+function engine = pearl_inf_engine(bnet, varargin)
+% PEARL_INF_ENGINE Pearl's algorithm (belief propagation)
+% engine = pearl_inf_engine(bnet, ...)
+%
+% If the graph has no loops (undirected cycles), you should use the tree protocol,
+% and the results will be exact.
+% Otherwise, you should use the parallel protocol, and the results may be approximate.
+%
+% Optional arguments [default in brackets]
+% 'protocol' - tree or parallel ['parallel']
+%
+% Optional arguments for the loopy case
+% 'max_iter' - specifies the max num. iterations to perform [2*num nodes]
+% 'tol' - convergence criterion on messages  [1e-3]
+% 'momentum' - msg = (m*old + (1-m)*new). [m=0]
+% 'filename' -  msgs will be printed to this file, so you can assess convergence while it runs [[]]
+% 'storebel' - 1 means save engine.bel{n,t} for every iteration t and hidden node n [0]
+%
+% If there are discrete and cts nodes, we assume all the discretes are observed. In this
+% case, you must use the parallel protocol, and the evidence pattern must be fixed.
+
+
+N = length(bnet.dag);
+protocol = 'parallel';
+max_iter = 2*N;
+% We use N+2 for the following reason:
+% In N iterations, we get the exact answer for a tree.
+% In the N+1st iteration, we notice that the results are the same as before, and terminate.
+% In loopy_converged, we see that N+1 < max = N+2, and declare convergence.
+tol = 1e-3;
+momentum = 0;
+filename = [];
+storebel = 0;
+
+args = varargin;
+for i=1:2:length(args)
+  switch args{i},
+   case 'protocol', protocol = args{i+1};
+   case 'max_iter', max_iter = args{i+1};
+   case 'tol', tol = args{i+1};
+   case 'momentum', momentum = args{i+1};
+   case 'filename', filename = args{i+1};
+   case 'storebel', storebel = args{i+1};
+  end
+end
+
+engine.filename = filename;
+engine.storebel = storebel;
+engine.bel = [];
+
+if strcmp(protocol, 'tree')
+  % We first send messages up to the root (pivot node), and then back towards the leaves.
+  % If the bnet is a singly connected graph (no loops), choosing a root induces a directed tree.
+  % Peot and Shachter discuss ways to pick the root so as to minimize the work,
+  % taking into account which nodes have changed.
+  % For simplicity, we always pick the root to be the last node in the graph.
+  % This means the first pass is equivalent to going forward in time in a DBN.
+
+  engine.root = N;
+  [engine.adj_mat, engine.preorder, engine.postorder, loopy] = ...
+    mk_rooted_tree(bnet.dag, engine.root);
+  % engine.adj_mat might have different edge orientations from bnet.dag
+  if loopy
+    error('can only apply tree protocol to loop-less graphs')
+  end
+else
+  engine.root = [];
+  engine.adj_mat = [];
+  engine.preorder = [];
+  engine.postorder = [];
+end
+
+engine.niter = [];
+engine.protocol = protocol;
+engine.max_iter = max_iter;
+engine.tol = tol;
+engine.momentum = momentum;
+engine.maximize = [];
+
+%onodes = find(~isemptycell(evidence));
+onodes = bnet.observed;
+engine.msg_type = determine_pot_type(bnet, onodes, 1:N); % needed also by marginal_nodes
+if strcmp(engine.msg_type, 'cg')
+  error('messages must be discrete or Gaussian')
+end
+[engine.msg_dag, disconnected_nodes] = mk_msg_dag(bnet, engine.msg_type, onodes);
+engine.disconnected_nodes_bitv = zeros(1,N);
+engine.disconnected_nodes_bitv(disconnected_nodes) = 1;
+
+
+% this is where we store stuff between enter_evidence and marginal_nodes
+engine.marginal = cell(1,N);
+engine.evidence = []; 
+engine.msg = [];
+
+[engine.parent_index, engine.child_index] = mk_loopy_msg_indices(engine.msg_dag);
+
+engine = class(engine, 'pearl_inf_engine', inf_engine(bnet));
+ 
+
+%%%%%%%%%
+
+function [dag, disconnected_nodes] = mk_msg_dag(bnet, msg_type, onodes)
+
+% If we are using Gaussian msgs, all discrete nodes must be observed;
+% they are then disconnected from the graph, so we don't try to send
+% msgs to/from them: their observed value simply serves to index into
+% the right set of parameters for the Gaussian nodes (which use CPD.ps
+% instead of parents(dag), and hence are unaffected by this "surgery").
+
+disconnected_nodes = [];
+switch msg_type
+ case 'd', dag = bnet.dag;
+ case 'g',
+  disconnected_nodes = bnet.dnodes;
+  dag = bnet.dag;
+  for i=disconnected_nodes(:)'
+    ps = parents(bnet.dag, i);
+    cs = children(bnet.dag, i);
+    if ~isempty(ps), dag(ps, i) = 0; end
+    if ~isempty(cs), dag(i, cs) = 0; end
+  end
+end
+
+
+%%%%%%%%%%
+function [parent_index, child_index] = mk_loopy_msg_indices(dag)
+% MK_LOOPY_MSG_INDICES Compute "port numbers" for message passing
+% [parent_index, child_index] = mk_loopy_msg_indices(bnet)
+%
+% child_index{n}(c) = i means c is n's i'th child, i.e., i = find_equiv_posns(c, children(n))
+% child_index{n}(c) = 0 means c is not a child of n.
+% parent_index{n}{p} is defined similarly.
+% We need to use these indices since the pi_from_parent/ lambda_from_child cell arrays
+% cannot be sparse, and hence cannot be indexed by the actual number of the node.
+% Instead, we use the number of the "port" on which the message arrived.
+
+N = length(dag);
+child_index = cell(1,N);
+parent_index = cell(1,N);
+for n=1:N
+  cs = children(dag, n);
+  child_index{n} = sparse(1,N);
+  for i=1:length(cs)
+    c = cs(i);
+    child_index{n}(c) = i;
+  end
+  ps = parents(dag, n);
+  parent_index{n} = sparse(1,N);
+  for i=1:length(ps)
+    p = ps(i);
+    parent_index{n}(p) = i;
+  end
+end
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/pearl_inf_engine.m~ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/pearl_inf_engine.m~
new file mode 100644
index 00000000..946233d0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/pearl_inf_engine.m~
@@ -0,0 +1,158 @@
+function engine = pearl_inf_engine(bnet, varargin)
+% PEARL_INF_ENGINE Pearl's algorithm (belief propagation)
+% engine = pearl_inf_engine(bnet, ...)
+%
+% If the graph has no loops (undirected cycles), you should use the tree protocol,
+% and the results will be exact.
+% Otherwise, you should use the parallel protocol, and the results may be approximate.
+%
+% Optional arguments [default in brackets]
+% 'protocol' - tree or parallel ['parallel']
+%
+% Optional arguments for the loopy case
+% 'max_iter' - specifies the max num. iterations to perform [2*num nodes]
+% 'tol' - convergence criterion on messages  [1e-3]
+% 'momentum' - msg = (m*old + (1-m)*new). [m=0]
+% 'filename' -  msgs will be printed to this file, so you can assess convergence while it runs [[]]
+% 'storebel' - 1 means save engine.bel{n,t} for every iteration t and hidden node n [0]
+%
+% If there are discrete and cts nodes, we assume all the discretes are observed. In this
+% case, you must use the parallel protocol, and the evidence pattern must be fixed.
+
+
+N = length(bnet.dag);
+protocol = [];
+max_iter = 2*N;
+% We use N+2 for the following reason:
+% In N iterations, we get the exact answer for a tree.
+% In the N+1st iteration, we notice that the results are the same as before, and terminate.
+% In loopy_converged, we see that N+1 < max = N+2, and declare convergence.
+tol = 1e-3;
+momentum = 0;
+filename = [];
+storebel = 0;
+
+args = varargin;
+for i=1:2:length(args)
+  switch args{i},
+   case 'protocol', protocol = args{i+1};
+   case 'max_iter', max_iter = args{i+1};
+   case 'tol', tol = args{i+1};
+   case 'momentum', momentum = args{i+1};
+   case 'filename', filename = args{i+1};
+   case 'storebel', storebel = args{i+1};
+  end
+end
+
+engine.filename = filename;
+engine.storebel = storebel;
+engine.bel = [];
+
+if strcmp(protocol, 'tree')
+  % We first send messages up to the root (pivot node), and then back towards the leaves.
+  % If the bnet is a singly connected graph (no loops), choosing a root induces a directed tree.
+  % Peot and Shachter discuss ways to pick the root so as to minimize the work,
+  % taking into account which nodes have changed.
+  % For simplicity, we always pick the root to be the last node in the graph.
+  % This means the first pass is equivalent to going forward in time in a DBN.
+
+  engine.root = N;
+  [engine.adj_mat, engine.preorder, engine.postorder, loopy] = ...
+    mk_rooted_tree(bnet.dag, engine.root);
+  % engine.adj_mat might have different edge orientations from bnet.dag
+  if loopy
+    error('can only apply tree protocol to loop-less graphs')
+  end
+else
+  engine.root = [];
+  engine.adj_mat = [];
+  engine.preorder = [];
+  engine.postorder = [];
+end
+
+engine.niter = [];
+engine.protocol = protocol;
+engine.max_iter = max_iter;
+engine.tol = tol;
+engine.momentum = momentum;
+engine.maximize = [];
+
+%onodes = find(~isemptycell(evidence));
+onodes = bnet.observed;
+engine.msg_type = determine_pot_type(bnet, onodes, 1:N); % needed also by marginal_nodes
+if strcmp(engine.msg_type, 'cg')
+  error('messages must be discrete or Gaussian')
+end
+[engine.msg_dag, disconnected_nodes] = mk_msg_dag(bnet, engine.msg_type, onodes);
+engine.disconnected_nodes_bitv = zeros(1,N);
+engine.disconnected_nodes_bitv(disconnected_nodes) = 1;
+
+
+% this is where we store stuff between enter_evidence and marginal_nodes
+engine.marginal = cell(1,N);
+engine.evidence = []; 
+engine.msg = [];
+
+[engine.parent_index, engine.child_index] = mk_loopy_msg_indices(engine.msg_dag);
+
+engine = class(engine, 'pearl_inf_engine', inf_engine(bnet));
+ 
+
+%%%%%%%%%
+
+function [dag, disconnected_nodes] = mk_msg_dag(bnet, msg_type, onodes)
+
+% If we are using Gaussian msgs, all discrete nodes must be observed;
+% they are then disconnected from the graph, so we don't try to send
+% msgs to/from them: their observed value simply serves to index into
+% the right set of parameters for the Gaussian nodes (which use CPD.ps
+% instead of parents(dag), and hence are unaffected by this "surgery").
+
+disconnected_nodes = [];
+switch msg_type
+ case 'd', dag = bnet.dag;
+ case 'g',
+  disconnected_nodes = bnet.dnodes;
+  dag = bnet.dag;
+  for i=disconnected_nodes(:)'
+    ps = parents(bnet.dag, i);
+    cs = children(bnet.dag, i);
+    if ~isempty(ps), dag(ps, i) = 0; end
+    if ~isempty(cs), dag(i, cs) = 0; end
+  end
+end
+
+
+%%%%%%%%%%
+function [parent_index, child_index] = mk_loopy_msg_indices(dag)
+% MK_LOOPY_MSG_INDICES Compute "port numbers" for message passing
+% [parent_index, child_index] = mk_loopy_msg_indices(bnet)
+%
+% child_index{n}(c) = i means c is n's i'th child, i.e., i = find_equiv_posns(c, children(n))
+% child_index{n}(c) = 0 means c is not a child of n.
+% parent_index{n}{p} is defined similarly.
+% We need to use these indices since the pi_from_parent/ lambda_from_child cell arrays
+% cannot be sparse, and hence cannot be indexed by the actual number of the node.
+% Instead, we use the number of the "port" on which the message arrived.
+
+N = length(dag);
+child_index = cell(1,N);
+parent_index = cell(1,N);
+for n=1:N
+  cs = children(dag, n);
+  child_index{n} = sparse(1,N);
+  for i=1:length(cs)
+    c = cs(i);
+    child_index{n}(c) = i;
+  end
+  ps = parents(dag, n);
+  parent_index{n} = sparse(1,N);
+  for i=1:length(ps)
+    p = ps(i);
+    parent_index{n}(p) = i;
+  end
+end
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/CVS/Entries
new file mode 100644
index 00000000..283482a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/CVS/Entries
@@ -0,0 +1,5 @@
+/compute_bel.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/parallel_protocol.m/1.1.1.1/Sun Aug 21 20:00:12 2005//
+/prod_lambda_msgs.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/tree_protocol.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/CVS/Repository
new file mode 100644
index 00000000..e913d5b6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@pearl_inf_engine/private
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/compute_bel.m b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/compute_bel.m
new file mode 100644
index 00000000..ebcbc747
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/compute_bel.m
@@ -0,0 +1,24 @@
+function bel = compute_bel(msg_type, pi, lambda)
+
+switch msg_type,
+ case 'd', bel = normalise(pi .* lambda);
+ case 'g',
+  if isinf(lambda.precision) % ignore pi because lambda is completely certain (observed)
+    bel.mu = lambda.mu;
+    bel.Sigma = zeros(length(bel.mu)); % infinite precision => 0 variance
+  elseif all(pi.Sigma==0) % ignore lambda because pi is completely certain (delta fn prior)
+    bel.Sigma = pi.Sigma;
+    bel.mu = pi.mu;
+  elseif all(isinf(pi.Sigma)) % ignore pi because pi is completely uncertain
+    bel.Sigma  = inv(lambda.precision);
+    bel.mu = bel.Sigma * lambda.info_state;
+  elseif all(lambda.precision == 0) % ignore lambda because lambda is completely uncertain
+    bel.Sigma = pi.Sigma;
+    bel.mu = pi.mu;
+  else % combine both pi and lambda
+    pi_precision = inv(pi.Sigma);
+    bel.Sigma = inv(pi_precision + lambda.precision);
+    bel.mu = bel.Sigma*(pi_precision * pi.mu + lambda.info_state);
+  end
+ otherwise, error(['unrecognized msg type ' msg_type])
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/parallel_protocol.m b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/parallel_protocol.m
new file mode 100644
index 00000000..8aa178b4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/parallel_protocol.m
@@ -0,0 +1,114 @@
+function [msg, niter] = parallel_protocol(engine, evidence, msg)
+
+bnet = bnet_from_engine(engine);
+N = length(bnet.dag);
+ns = bnet.node_sizes(:);
+
+if ~isempty(engine.filename)
+  fid = fopen(engine.filename, 'w');
+  if fid == 0
+    error(['could not open ' engine.filename ' for writing'])
+  end
+else
+  fid = [];
+end
+
+converged = 0;
+iter = 1;
+hidden = find(isemptycell(evidence));
+bel = cell(1,N);
+old_bel = cell(1,N);
+%nodes = mysetdiff(1:N, engine.disconnected_nodes);
+nodes = find(~engine.disconnected_nodes_bitv);
+while ~converged && (iter <= engine.max_iter)
+  % Everybody updates their state in parallel
+  for n=nodes(:)'
+    cs_msg = children(engine.msg_dag, n);
+    %msg{n}.lambda = compute_lambda(n, cs, msg);
+    msg{n}.lambda = prod_lambda_msgs(n, cs_msg, msg, engine.msg_type);
+    ps_orig = parents(bnet.dag, n);
+    msg{n}.pi = CPD_to_pi(bnet.CPD{bnet.equiv_class(n)}, engine.msg_type, n, ps_orig, msg, evidence);
+  end
+  
+  changed = 0;
+  if ~isempty(fid)
+    fprintf(fid, 'ITERATION %d\n', iter);
+  end
+  for n=hidden(:)' % this will not contain any disconnected nodes
+    old_bel{n} = bel{n};
+    bel{n}  = compute_bel(engine.msg_type, msg{n}.pi, msg{n}.lambda);
+    if ~isempty(fid)
+      fprintf(fid, 'node %d: %s\n', n, bel_to_str(bel{n}, engine.msg_type));
+    end
+    if engine.storebel
+      engine.bel{n,iter} = bel{n};
+    end
+    if (iter == 1) | ~approxeq_bel(bel{n}, old_bel{n}, engine.tol, engine.msg_type)
+      changed = 1;
+    end
+  end
+  %converged = ~changed;
+  converged = ~changed && (iter > 1);  % Sonia Leach changed this
+
+  if ~converged
+    % Everybody sends to all their neighbors in parallel
+    for n=nodes(:)'
+      % lambda msgs to parents
+      ps_msg = parents(engine.msg_dag, n);
+      ps_orig = parents(bnet.dag, n);
+      for p=ps_msg(:)'
+	j = engine.child_index{p}(n); % n is p's j'th child
+	old_msg = msg{p}.lambda_from_child{j}(:);
+	new_msg = CPD_to_lambda_msg(bnet.CPD{bnet.equiv_class(n)}, engine.msg_type, n, ps_orig, ...
+				    msg, p, evidence);
+	lam_msg = convex_combination_msg(old_msg, new_msg, engine.momentum, engine.msg_type);
+	msg{p}.lambda_from_child{j} = lam_msg;
+      end 
+
+      % pi msgs to children
+      cs_msg = children(engine.msg_dag, n);
+      for c=cs_msg(:)'
+	j = engine.parent_index{c}(n); % n is c's j'th parent
+	old_msg = msg{c}.pi_from_parent{j}(:);
+	%new_msg = compute_pi_msg(n, cs, msg, c));
+	new_msg = compute_bel(engine.msg_type, msg{n}.pi, prod_lambda_msgs(n, cs_msg, msg, engine.msg_type, c));
+	pi_msg = convex_combination_msg(old_msg, new_msg, engine.momentum, engine.msg_type);
+	msg{c}.pi_from_parent{j} = pi_msg;
+      end
+    end
+    iter = iter + 1;
+  end
+end
+
+if fid > 0, fclose(fid); end
+%niter = iter - 1;
+niter = iter;
+
+%%%%%%%%%%
+
+function str = bel_to_str(bel, type)
+
+switch type
+ case 'd', str = sprintf('%9.4f ', bel(:)');
+ case 'g', str = sprintf('%9.4f ', bel.mu(:)');
+end
+
+
+%%%%%%%
+
+function a = approxeq_bel(bel1, bel2, tol, type)
+
+switch type
+ case 'd', a = approxeq(bel1, bel2, tol);
+ case 'g', a = approxeq(bel1.mu, bel2.mu, tol) && approxeq(bel1.Sigma, bel2.Sigma, tol);
+end
+
+
+%%%%%%%
+
+function msg = convex_combination_msg(old_msg, new_msg, old_weight, type)
+
+switch type
+ case 'd', msg = old_weight * old_msg + (1-old_weight)*new_msg;
+ case 'g', msg = new_msg;
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/parallel_protocol.m~ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/parallel_protocol.m~
new file mode 100644
index 00000000..cc6fe6b3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/parallel_protocol.m~
@@ -0,0 +1,114 @@
+function [msg, niter] = parallel_protocol(engine, evidence, msg)
+
+bnet = bnet_from_engine(engine);
+N = length(bnet.dag);
+ns = bnet.node_sizes(:);
+
+if ~isempty(engine.filename)
+  fid = fopen(engine.filename, 'w');
+  if fid == 0
+    error(['could not open ' engine.filename ' for writing'])
+  end
+else
+  fid = 0;
+end
+
+converged = 0;
+iter = 1;
+hidden = find(isemptycell(evidence));
+bel = cell(1,N);
+old_bel = cell(1,N);
+%nodes = mysetdiff(1:N, engine.disconnected_nodes);
+nodes = find(~engine.disconnected_nodes_bitv);
+while ~converged & (iter <= engine.max_iter)
+  % Everybody updates their state in parallel
+  for n=nodes(:)'
+    cs_msg = children(engine.msg_dag, n);
+    %msg{n}.lambda = compute_lambda(n, cs, msg);
+    msg{n}.lambda = prod_lambda_msgs(n, cs_msg, msg, engine.msg_type);
+    ps_orig = parents(bnet.dag, n);
+    msg{n}.pi = CPD_to_pi(bnet.CPD{bnet.equiv_class(n)}, engine.msg_type, n, ps_orig, msg, evidence);
+  end
+  
+  changed = 0;
+  if ~isempty(fid)
+    fprintf(fid, 'ITERATION %d\n', iter);
+  end
+  for n=hidden(:)' % this will not contain any disconnected nodes
+    old_bel{n} = bel{n};
+    bel{n}  = compute_bel(engine.msg_type, msg{n}.pi, msg{n}.lambda);
+    if ~isempty(fid)
+      fprintf(fid, 'node %d: %s\n', n, bel_to_str(bel{n}, engine.msg_type));
+    end
+    if engine.storebel
+      engine.bel{n,iter} = bel{n};
+    end
+    if (iter == 1) | ~approxeq_bel(bel{n}, old_bel{n}, engine.tol, engine.msg_type)
+      changed = 1;
+    end
+  end
+  %converged = ~changed;
+  converged = ~changed & (iter > 1);  % Sonia Leach changed this
+
+  if ~converged
+    % Everybody sends to all their neighbors in parallel
+    for n=nodes(:)'
+      % lambda msgs to parents
+      ps_msg = parents(engine.msg_dag, n);
+      ps_orig = parents(bnet.dag, n);
+      for p=ps_msg(:)'
+	j = engine.child_index{p}(n); % n is p's j'th child
+	old_msg = msg{p}.lambda_from_child{j}(:);
+	new_msg = CPD_to_lambda_msg(bnet.CPD{bnet.equiv_class(n)}, engine.msg_type, n, ps_orig, ...
+				    msg, p, evidence);
+	lam_msg = convex_combination_msg(old_msg, new_msg, engine.momentum, engine.msg_type);
+	msg{p}.lambda_from_child{j} = lam_msg;
+      end 
+
+      % pi msgs to children
+      cs_msg = children(engine.msg_dag, n);
+      for c=cs_msg(:)'
+	j = engine.parent_index{c}(n); % n is c's j'th parent
+	old_msg = msg{c}.pi_from_parent{j}(:);
+	%new_msg = compute_pi_msg(n, cs, msg, c));
+	new_msg = compute_bel(engine.msg_type, msg{n}.pi, prod_lambda_msgs(n, cs_msg, msg, engine.msg_type, c));
+	pi_msg = convex_combination_msg(old_msg, new_msg, engine.momentum, engine.msg_type);
+	msg{c}.pi_from_parent{j} = pi_msg;
+      end
+    end
+    iter = iter + 1;
+  end
+end
+
+if fid > 0, fclose(fid); end
+%niter = iter - 1;
+niter = iter;
+
+%%%%%%%%%%
+
+function str = bel_to_str(bel, type)
+
+switch type
+ case 'd', str = sprintf('%9.4f ', bel(:)');
+ case 'g', str = sprintf('%9.4f ', bel.mu(:)');
+end
+
+
+%%%%%%%
+
+function a = approxeq_bel(bel1, bel2, tol, type)
+
+switch type
+ case 'd', a = approxeq(bel1, bel2, tol);
+ case 'g', a = approxeq(bel1.mu, bel2.mu, tol) & approxeq(bel1.Sigma, bel2.Sigma, tol);
+end
+
+
+%%%%%%%
+
+function msg = convex_combination_msg(old_msg, new_msg, old_weight, type)
+
+switch type
+ case 'd', msg = old_weight * old_msg + (1-old_weight)*new_msg;
+ case 'g', msg = new_msg;
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/prod_lambda_msgs.m b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/prod_lambda_msgs.m
new file mode 100644
index 00000000..5a96d259
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/prod_lambda_msgs.m
@@ -0,0 +1,29 @@
+function lam = prod_lambda_msgs(n, cs, msg, msg_type, except)
+
+if nargin < 5, except = -1; end
+
+lam = msg{n}.lambda_from_self;
+switch msg_type
+  case 'd',
+   for i=1:length(cs)
+     c = cs(i);
+     if c ~= except
+       lam = lam .* msg{n}.lambda_from_child{i};
+     end
+   end  
+ case 'g',
+  if isinf(lam.precision) % isfield(lam, 'observed_val')
+    return; % pass on the observed msg
+  end
+   for i=1:length(cs)
+     c = cs(i);
+     if c ~= except
+       m = msg{n}.lambda_from_child{i};
+       lam.precision = lam.precision + m.precision;
+       lam.info_state = lam.info_state + m.info_state;
+     end
+   end  
+end
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/tree_protocol.m b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/tree_protocol.m
new file mode 100644
index 00000000..b0ba2fc8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@pearl_inf_engine/private/tree_protocol.m
@@ -0,0 +1,71 @@
+function msg = tree_protocol(engine, evidence, msg)
+
+bnet = bnet_from_engine(engine);
+N = length(bnet.dag);
+
+% Send messages from leaves to root
+for i=1:N-1
+  n = engine.postorder(i);
+  above = parents(engine.adj_mat, n);
+  msg = send_msgs_to_some_neighbors(n, msg, above, bnet, engine.child_index, engine.parent_index, ...
+				    engine.msg_type, evidence);
+end
+
+% Process root
+n = engine.root;
+cs = children(bnet.dag, n);
+%msg{n}.lambda = compute_lambda(n, cs, msg, engine.msg_type);
+msg{n}.lambda = prod_lambda_msgs(n, cs, msg, engine.msg_type);
+ps = parents(bnet.dag, n);
+msg{n}.pi = CPD_to_pi(bnet.CPD{bnet.equiv_class(n)}, engine.msg_type, n, ps, msg, evidence);
+
+% Send messages from root to leaves
+for i=1:N
+  n = engine.preorder(i);
+  below = children(engine.adj_mat, n);
+  msg = send_msgs_to_some_neighbors(n, msg, below, bnet, engine.child_index, engine.parent_index, ...
+				    engine.msg_type, evidence);
+end
+
+  
+%%%%%%%%%%
+
+function msg = send_msgs_to_some_neighbors(n, msg, valid_nbrs, bnet, child_index, parent_index, ...
+					   msg_type, evidence)
+
+verbose = 0;
+
+ns = bnet.node_sizes;
+dag = bnet.dag;
+e = bnet.equiv_class(n);
+CPD = bnet.CPD{e};
+
+
+cs = children(dag, n);
+%msg{n}.lambda = compute_lambda(n, cs, msg);
+msg{n}.lambda = prod_lambda_msgs(n, cs, msg, msg_type);
+if verbose, fprintf('%d computes lambda\n', n); display(msg{n}.lambda); end
+
+ps = parents(dag, n);
+msg{n}.pi = CPD_to_pi(CPD, msg_type, n, ps, msg, evidence);
+if verbose, fprintf('%d computes pi\n', n); display(msg{n}.pi); end
+
+ps2 = myintersect(parents(dag, n), valid_nbrs);
+for p=ps2(:)'
+  lam_msg = CPD_to_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence);
+  j = child_index{p}(n); % n is p's j'th child
+  msg{p}.lambda_from_child{j} = lam_msg;
+  if verbose, fprintf('%d sends lambda to %d\n', n, p); display(lam_msg); end
+end
+
+cs2 = myintersect(cs, valid_nbrs);
+for c=cs2(:)'
+  %pi_msg = compute_pi_msg(n, cs, msg, c);
+  pi_msg = compute_bel(msg_type, msg{n}.pi, prod_lambda_msgs(n, cs, msg, msg_type, c));
+  j = parent_index{c}(n); % n is c's j'th parent
+  msg{c}.pi_from_parent{j} = pi_msg;
+  if verbose, fprintf('%d sends pi to %d\n', n, c); display(pi_msg); end
+end
+
+
+ 
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/CVS/Entries
new file mode 100644
index 00000000..68df5d27
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/CVS/Entries
@@ -0,0 +1,4 @@
+/enter_evidence.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//
+/quickscore_inf_engine.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D/private////
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/CVS/Repository
new file mode 100644
index 00000000..cdd697e4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@quickscore_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..c697264b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/enter_evidence.m
@@ -0,0 +1,19 @@
+function engine = enter_evidence(engine, pos, neg)
+% ENTER_EVIDENCE Add evidence to the QMR network
+% engine = enter_evidence(engine, pos, neg)
+%
+% pos = list of leaves that have positive observations
+% neg = list of leaves that have negative observations
+
+% Extract params for the observed findings
+obs = myunion(pos, neg);
+%inhibit_obs = engine.inhibit(obs, :);
+inhibit_obs = engine.inhibit(:,obs)';
+leak_obs = engine.leak(obs);
+
+% Find what nodes correspond to the original observed leaves
+pos2 = find_equiv_posns(pos, obs);
+neg2 = find_equiv_posns(neg, obs);
+engine.post = quickscore(pos2, neg2, inhibit_obs, engine.prior, leak_obs); 
+%engine.post = C_quickscore(pos2, neg2, inhibit_obs, engine.prior, leak_obs); 
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..e07c04c2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/marginal_nodes.m
@@ -0,0 +1,11 @@
+function m = marginal_nodes(engine, query)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (quickscore)
+% marginal = marginal_nodes(engine, query)
+%
+% 'query' must be a single disease (root) node.
+
+assert(length(query)==1);
+p = engine.post(query);
+m.T = [1-p p]';
+m.domain = query;
+  
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/CVS/Entries
new file mode 100644
index 00000000..6a6a34f0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/CVS/Entries
@@ -0,0 +1,6 @@
+/C_quickscore.c/1.1.1.1/Wed May 29 15:59:56 2002//
+/nr.h/1.1.1.1/Wed May 29 15:59:56 2002//
+/nrutil.c/1.1.1.1/Wed May 29 15:59:56 2002//
+/nrutil.h/1.1.1.1/Wed May 29 15:59:56 2002//
+/quickscore.m/1.1.1.1/Wed May 29 15:59:56 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/CVS/Repository
new file mode 100644
index 00000000..33f7b87e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@quickscore_inf_engine/private
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/C_quickscore.c b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/C_quickscore.c
new file mode 100644
index 00000000..b9b46f04
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/C_quickscore.c
@@ -0,0 +1,164 @@
+/* To compile, type "mex C_quickscore.c" */
+
+#include <stdio.h>
+#include "nrutil.h"
+#include "nrutil.c"
+#include <math.h>
+#include "mex.h"
+
+#define MAX(X,Y) (X)>(Y)?(X):(Y)
+
+int two_to_the(int n)
+{
+  return 1 << n;
+}
+
+void int2bin(int num, int nbits, int bits[])
+{
+  int i, mask;
+  mask = 1 << (nbits-1); /* mask = 0010...0 , where the 1 is in col nbits (rightmost = col 1) */
+  for (i = 0; i < nbits; i++) {
+    bits[i] = ((num & mask) == 0) ? 0 : 1;
+    num <<= 1;
+  }
+}
+
+
+void quickscore(int ndiseases, int nfindings, const double *fpos, int npos, const double *fneg, int nneg,
+                  const double *inhibit, const double *prior, const double *leak, double *prob)
+{
+  double *Pon, *Poff, **Uon, **Uoff, **post, *pterm, *ptermOff, *ptermOn, temp, p, myp;
+  int *bits, nsubsets, *fmask;
+  int f, d, i, j, si, size_subset, sign;
+
+  Pon = dvector(0, ndiseases);
+  Poff = dvector(0, ndiseases);
+  Pon[0] = 1;
+  Poff[0] = 0;
+  for (i=1; i <= ndiseases; i++) {
+    Pon[i] = prior[i-1];
+    Poff[i] = 1-Pon[i];
+  }
+
+  Uon = dmatrix(0, nfindings-1, 0, ndiseases);
+  Uoff = dmatrix(0, nfindings-1, 0, ndiseases);
+  d = 0;
+  for (f=0; f < nfindings; f++) {
+    Uon[f][d] = leak[f];
+    Uoff[f][d] = leak[f];
+  }
+  for (f=0; f < nfindings; f++) {
+    for (d=1; d <= ndiseases; d++) {
+      Uon[f][d] = inhibit[f + nfindings*(d-1)];
+      Uoff[f][d] = 1;
+    }
+  }
+  
+  post = dmatrix(0, ndiseases, 0, 1);
+  for (d = 0; d <= ndiseases; d++) {
+    post[d][0] = 0;
+    post[d][1] = 0;
+  }
+  
+  bits = ivector(0, npos-1);
+  fmask = ivector(0, nfindings-1);
+  pterm = dvector(0, ndiseases);
+  ptermOff = dvector(0, ndiseases);
+  ptermOn = dvector(0, ndiseases);
+
+  nsubsets = two_to_the(npos);
+
+  for (si = 0; si < nsubsets; si++) {
+    int2bin(si, npos, bits);
+    for (i=0; i < nfindings; i++) fmask[i] = 0;
+    for (i=0; i < nneg; i++) fmask[(int)fneg[i]-1] = 1;
+    size_subset = 0;
+    for (i=0; i < npos; i++) {
+      if (bits[i]) {
+	size_subset++;
+	fmask[(int)fpos[i]-1] = 1;
+      }
+    }
+    p = 1;
+    for (d=0; d <= ndiseases; d++) {
+      temp = 1;
+      for (j = 0; j < nfindings; j++) {
+	if (fmask[j]) temp *= Uoff[j][d];
+      }
+      ptermOff[d] = temp;
+
+      temp = 1;
+      for (j = 0; j < nfindings; j++) {
+	if (fmask[j]) temp *= Uon[j][d];
+      }
+      ptermOn[d] = temp;
+
+      pterm[d] = Poff[d]*ptermOff[d] + Pon[d]*ptermOn[d];
+      p *= pterm[d];
+    }
+    sign = (int) pow(-1, size_subset);
+    for (d=0; d <= ndiseases; d++) {
+      myp = p / pterm[d];
+      post[d][0] += sign*(myp * ptermOff[d]);
+      post[d][1] += sign*(myp * ptermOn[d]);
+    }
+  } /* next si */
+
+  
+  for (d=0; d <= ndiseases; d++) {
+    post[d][0] *= Poff[d];
+    post[d][1] *= Pon[d];
+  }
+  for (d=0; d <= ndiseases; d++) {
+    temp = post[d][0] + post[d][1];
+    post[d][0] /= temp;
+    post[d][1] /= temp;
+    if (d>0) { prob[d-1] = post[d][1]; }
+  }
+
+  
+  free_dvector(Pon, 0, ndiseases);
+  free_dvector(Poff, 0, ndiseases);
+  free_dmatrix(Uon, 0, nfindings-1, 0, ndiseases);
+  free_dmatrix(Uoff, 0, nfindings-1, 0, ndiseases);
+  free_dmatrix(post, 0, ndiseases, 0, 1);
+  free_ivector(bits, 0, npos-1);
+  free_ivector(fmask, 0, nfindings-1);
+  free_dvector(pterm, 0, ndiseases);
+  free_dvector(ptermOff, 0, ndiseases);
+  free_dvector(ptermOn, 0, ndiseases);
+}
+
+
+void mexFunction(
+                 int nlhs,       mxArray *plhs[],
+                 int nrhs, const mxArray *prhs[]
+                 )
+{
+  double *fpos, *fneg, *inhibit, *prior, *leak, *prob;
+  int npos, nneg, ndiseases, nfindings;
+  double *p;
+
+  /* read the input args */
+  fpos = mxGetPr(prhs[0]);
+  npos = MAX(mxGetM(prhs[0]), mxGetN(prhs[0]));
+
+  fneg = mxGetPr(prhs[1]);
+  nneg = MAX(mxGetM(prhs[1]), mxGetN(prhs[1]));
+
+  inhibit = mxGetPr(prhs[2]); /* inhibit(finding, disease) */
+  nfindings = mxGetM(prhs[2]);
+  ndiseases = mxGetN(prhs[2]);
+
+  prior = mxGetPr(prhs[3]);
+
+  leak = mxGetPr(prhs[4]);
+
+
+ /* set the output pointers */
+  plhs[0] = mxCreateDoubleMatrix(1, ndiseases, mxREAL);
+  prob = mxGetPr(plhs[0]);
+
+  quickscore(ndiseases, nfindings, fpos, npos, fneg, nneg, inhibit, prior, leak, prob);
+}
+  
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/nr.h b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/nr.h
new file mode 100644
index 00000000..a7751566
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/nr.h
@@ -0,0 +1,536 @@
+/* CAUTION: This is the ANSI C (only) version of the Numerical Recipes
+   utility file nr.h.  Do not confuse this file with the same-named
+   file nr.h that is supplied in the 'misc' subdirectory.
+   *That* file is the one from the book, and contains both ANSI and
+   traditional K&R versions, along with #ifdef macros to select the
+   correct version.  *This* file contains only ANSI C.               */
+
+#ifndef _NR_H_
+#define _NR_H_
+
+#ifndef _FCOMPLEX_DECLARE_T_
+typedef struct FCOMPLEX {float r,i;} fcomplex;
+#define _FCOMPLEX_DECLARE_T_
+#endif /* _FCOMPLEX_DECLARE_T_ */
+
+#ifndef _ARITHCODE_DECLARE_T_
+typedef struct {
+	unsigned long *ilob,*iupb,*ncumfq,jdif,nc,minint,nch,ncum,nrad;
+} arithcode;
+#define _ARITHCODE_DECLARE_T_
+#endif /* _ARITHCODE_DECLARE_T_ */
+
+#ifndef _HUFFCODE_DECLARE_T_
+typedef struct {
+	unsigned long *icod,*ncod,*left,*right,nch,nodemax;
+} huffcode;
+#define _HUFFCODE_DECLARE_T_
+#endif /* _HUFFCODE_DECLARE_T_ */
+
+#include <stdio.h>
+
+void addint(double **uf, double **uc, double **res, int nf);
+void airy(float x, float *ai, float *bi, float *aip, float *bip);
+void amebsa(float **p, float y[], int ndim, float pb[],	float *yb,
+	float ftol, float (*funk)(float []), int *iter, float temptr);
+void amoeba(float **p, float y[], int ndim, float ftol,
+	float (*funk)(float []), int *iter);
+float amotry(float **p, float y[], float psum[], int ndim,
+	float (*funk)(float []), int ihi, float fac);
+float amotsa(float **p, float y[], float psum[], int ndim, float pb[],
+	float *yb, float (*funk)(float []), int ihi, float *yhi, float fac);
+void anneal(float x[], float y[], int iorder[], int ncity);
+double anorm2(double **a, int n);
+void arcmak(unsigned long nfreq[], unsigned long nchh, unsigned long nradd,
+	arithcode *acode);
+void arcode(unsigned long *ich, unsigned char **codep, unsigned long *lcode,
+	unsigned long *lcd, int isign, arithcode *acode);
+void arcsum(unsigned long iin[], unsigned long iout[], unsigned long ja,
+	int nwk, unsigned long nrad, unsigned long nc);
+void asolve(unsigned long n, double b[], double x[], int itrnsp);
+void atimes(unsigned long n, double x[], double r[], int itrnsp);
+void avevar(float data[], unsigned long n, float *ave, float *var);
+void balanc(float **a, int n);
+void banbks(float **a, unsigned long n, int m1, int m2, float **al,
+	unsigned long indx[], float b[]);
+void bandec(float **a, unsigned long n, int m1, int m2, float **al,
+	unsigned long indx[], float *d);
+void banmul(float **a, unsigned long n, int m1, int m2, float x[], float b[]);
+void bcucof(float y[], float y1[], float y2[], float y12[], float d1,
+	float d2, float **c);
+void bcuint(float y[], float y1[], float y2[], float y12[],
+	float x1l, float x1u, float x2l, float x2u, float x1,
+	float x2, float *ansy, float *ansy1, float *ansy2);
+void beschb(double x, double *gam1, double *gam2, double *gampl,
+	double *gammi);
+float bessi(int n, float x);
+float bessi0(float x);
+float bessi1(float x);
+void bessik(float x, float xnu, float *ri, float *rk, float *rip,
+	float *rkp);
+float bessj(int n, float x);
+float bessj0(float x);
+float bessj1(float x);
+void bessjy(float x, float xnu, float *rj, float *ry, float *rjp,
+	float *ryp);
+float bessk(int n, float x);
+float bessk0(float x);
+float bessk1(float x);
+float bessy(int n, float x);
+float bessy0(float x);
+float bessy1(float x);
+float beta(float z, float w);
+float betacf(float a, float b, float x);
+float betai(float a, float b, float x);
+float bico(int n, int k);
+void bksub(int ne, int nb, int jf, int k1, int k2, float ***c);
+float bnldev(float pp, int n, long *idum);
+float brent(float ax, float bx, float cx,
+	float (*f)(float), float tol, float *xmin);
+float brent_arg(float ax, float bx, float cx,
+	float (*f)(float, void*), float tol, float *xmin, void *arg);
+void broydn(float x[], int n, int *check,
+	void (*vecfunc)(int, float [], float []));
+void bsstep(float y[], float dydx[], int nv, float *xx, float htry,
+	float eps, float yscal[], float *hdid, float *hnext,
+	void (*derivs)(float, float [], float []));
+void caldat(long julian, int *mm, int *id, int *iyyy);
+void chder(float a, float b, float c[], float cder[], int n);
+float chebev(float a, float b, float c[], int m, float x);
+void chebft(float a, float b, float c[], int n, float (*func)(float));
+void chebpc(float c[], float d[], int n);
+void chint(float a, float b, float c[], float cint[], int n);
+float chixy(float bang);
+void choldc(float **a, int n, float p[]);
+void cholsl(float **a, int n, float p[], float b[], float x[]);
+void chsone(float bins[], float ebins[], int nbins, int knstrn,
+	float *df, float *chsq, float *prob);
+void chstwo(float bins1[], float bins2[], int nbins, int knstrn,
+	float *df, float *chsq, float *prob);
+void cisi(float x, float *ci, float *si);
+void cntab1(int **nn, int ni, int nj, float *chisq,
+	float *df, float *prob, float *cramrv, float *ccc);
+void cntab2(int **nn, int ni, int nj, float *h, float *hx, float *hy,
+	float *hygx, float *hxgy, float *uygx, float *uxgy, float *uxy);
+void convlv(float data[], unsigned long n, float respns[], unsigned long m,
+	int isign, float ans[]);
+void copy(double **aout, double **ain, int n);
+void correl(float data1[], float data2[], unsigned long n, float ans[]);
+void cosft(float y[], int n, int isign);
+void cosft1(float y[], int n);
+void cosft2(float y[], int n, int isign);
+void covsrt(float **covar, int ma, int ia[], int mfit);
+void crank(unsigned long n, float w[], float *s);
+void cyclic(float a[], float b[], float c[], float alpha, float beta,
+	float r[], float x[], unsigned long n);
+void daub4(float a[], unsigned long n, int isign);
+float dawson(float x);
+float dbrent(float ax, float bx, float cx,
+	float (*f)(float), float (*df)(float), float tol, float *xmin);
+void ddpoly(float c[], int nc, float x, float pd[], int nd);
+int decchk(char string[], int n, char *ch);
+void derivs(float x, float y[], float dydx[]);
+float df1dim(float x);
+void dfour1(double data[], unsigned long nn, int isign);
+void dfpmin(float p[], int n, float gtol, int *iter, float *fret,
+	float (*func)(float []), void (*dfunc)(float [], float []));
+float dfridr(float (*func)(float), float x, float h, float *err);
+void dftcor(float w, float delta, float a, float b, float endpts[],
+	float *corre, float *corim, float *corfac);
+void dftint(float (*func)(float), float a, float b, float w,
+	float *cosint, float *sinint);
+void difeq(int k, int k1, int k2, int jsf, int is1, int isf,
+	int indexv[], int ne, float **s, float **y);
+void dlinmin(float p[], float xi[], int n, float *fret,
+	float (*func)(float []), void (*dfunc)(float [], float[]));
+double dpythag(double a, double b);
+void drealft(double data[], unsigned long n, int isign);
+void dsprsax(double sa[], unsigned long ija[], double x[], double b[],
+	unsigned long n);
+void dsprstx(double sa[], unsigned long ija[], double x[], double b[],
+	unsigned long n);
+void dsvbksb(double **u, double w[], double **v, int m, int n, double b[],
+	double x[]);
+void dsvdcmp(double **a, int m, int n, double w[], double **v);
+void eclass(int nf[], int n, int lista[], int listb[], int m);
+void eclazz(int nf[], int n, int (*equiv)(int, int));
+float ei(float x);
+void eigsrt(float d[], float **v, int n);
+float elle(float phi, float ak);
+float ellf(float phi, float ak);
+float ellpi(float phi, float en, float ak);
+void elmhes(float **a, int n);
+float erfcc(float x);
+float erff(float x);
+float erffc(float x);
+void eulsum(float *sum, float term, int jterm, float wksp[]);
+float evlmem(float fdt, float d[], int m, float xms);
+float expdev(long *idum);
+float expint(int n, float x);
+float f1(float x);
+float f1dim(float x);
+float f1dim_arg(float x, void *arg);
+float f2(float y);
+float f3(float z);
+float factln(int n);
+float factrl(int n);
+void fasper(float x[], float y[], unsigned long n, float ofac, float hifac,
+	float wk1[], float wk2[], unsigned long nwk, unsigned long *nout,
+	unsigned long *jmax, float *prob);
+void fdjac(int n, float x[], float fvec[], float **df,
+	void (*vecfunc)(int, float [], float []));
+void fgauss(float x, float a[], float *y, float dyda[], int na);
+void fill0(double **u, int n);
+void fit(float x[], float y[], int ndata, float sig[], int mwt,
+	float *a, float *b, float *siga, float *sigb, float *chi2, float *q);
+void fitexy(float x[], float y[], int ndat, float sigx[], float sigy[],
+	float *a, float *b, float *siga, float *sigb, float *chi2, float *q);
+void fixrts(float d[], int m);
+void fleg(float x, float pl[], int nl);
+void flmoon(int n, int nph, long *jd, float *frac);
+float fmin(float x[]);
+void four1(float data[], unsigned long nn, int isign);
+void fourew(FILE *file[5], int *na, int *nb, int *nc, int *nd);
+void fourfs(FILE *file[5], unsigned long nn[], int ndim, int isign);
+void fourn(float data[], unsigned long nn[], int ndim, int isign);
+void fpoly(float x, float p[], int np);
+void fred2(int n, float a, float b, float t[], float f[], float w[],
+	float (*g)(float), float (*ak)(float, float));
+float fredin(float x, int n, float a, float b, float t[], float f[], float w[],
+	float (*g)(float), float (*ak)(float, float));
+void frenel(float x, float *s, float *c);
+void frprmn(float p[], int n, float ftol, int *iter, float *fret,
+	float (*func)(float []), void (*dfunc)(float [], float []));
+void frprmn_arg(float p[], int n, float ftol, int *iter, float *fret,
+	float (*func)(float [], void*), void (*dfunc)(float [], float [], void*), void* arg);
+void ftest(float data1[], unsigned long n1, float data2[], unsigned long n2,
+	float *f, float *prob);
+float gamdev(int ia, long *idum);
+float gammln(float xx);
+float gammp(float a, float x);
+float gammq(float a, float x);
+float gasdev(long *idum);
+void gaucof(int n, float a[], float b[], float amu0, float x[], float w[]);
+void gauher(float x[], float w[], int n);
+void gaujac(float x[], float w[], int n, float alf, float bet);
+void gaulag(float x[], float w[], int n, float alf);
+void gauleg(float x1, float x2, float x[], float w[], int n);
+void gaussj(float **a, int n, float **b, int m);
+void gcf(float *gammcf, float a, float x, float *gln);
+float golden(float ax, float bx, float cx, float (*f)(float), float tol,
+	float *xmin);
+void gser(float *gamser, float a, float x, float *gln);
+void hpsel(unsigned long m, unsigned long n, float arr[], float heap[]);
+void hpsort(unsigned long n, float ra[]);
+void hqr(float **a, int n, float wr[], float wi[]);
+void hufapp(unsigned long index[], unsigned long nprob[], unsigned long n,
+	unsigned long i);
+void hufdec(unsigned long *ich, unsigned char *code, unsigned long lcode,
+	unsigned long *nb, huffcode *hcode);
+void hufenc(unsigned long ich, unsigned char **codep, unsigned long *lcode,
+	unsigned long *nb, huffcode *hcode);
+void hufmak(unsigned long nfreq[], unsigned long nchin, unsigned long *ilong,
+	unsigned long *nlong, huffcode *hcode);
+void hunt(float xx[], unsigned long n, float x, unsigned long *jlo);
+void hypdrv(float s, float yy[], float dyyds[]);
+fcomplex hypgeo(fcomplex a, fcomplex b, fcomplex c, fcomplex z);
+void hypser(fcomplex a, fcomplex b, fcomplex c, fcomplex z,
+	fcomplex *series, fcomplex *deriv);
+unsigned short icrc(unsigned short crc, unsigned char *bufptr,
+	unsigned long len, short jinit, int jrev);
+unsigned short icrc1(unsigned short crc, unsigned char onech);
+unsigned long igray(unsigned long n, int is);
+void iindexx(unsigned long n, long arr[], unsigned long indx[]);
+void indexx(unsigned long n, float arr[], unsigned long indx[]);
+void interp(double **uf, double **uc, int nf);
+int irbit1(unsigned long *iseed);
+int irbit2(unsigned long *iseed);
+void jacobi(float **a, int n, float d[], float **v, int *nrot);
+void jacobn(float x, float y[], float dfdx[], float **dfdy, int n);
+long julday(int mm, int id, int iyyy);
+void kendl1(float data1[], float data2[], unsigned long n, float *tau, float *z,
+	float *prob);
+void kendl2(float **tab, int i, int j, float *tau, float *z, float *prob);
+void kermom(double w[], double y, int m);
+void ks2d1s(float x1[], float y1[], unsigned long n1,
+	void (*quadvl)(float, float, float *, float *, float *, float *),
+	float *d1, float *prob);
+void ks2d2s(float x1[], float y1[], unsigned long n1, float x2[], float y2[],
+	unsigned long n2, float *d, float *prob);
+void ksone(float data[], unsigned long n, float (*func)(float), float *d,
+	float *prob);
+void kstwo(float data1[], unsigned long n1, float data2[], unsigned long n2,
+	float *d, float *prob);
+void laguer(fcomplex a[], int m, fcomplex *x, int *its);
+void lfit(float x[], float y[], float sig[], int ndat, float a[], int ia[],
+	int ma, float **covar, float *chisq, void (*funcs)(float, float [], int));
+void linbcg(unsigned long n, double b[], double x[], int itol, double tol,
+	 int itmax, int *iter, double *err);
+void linmin(float p[], float xi[], int n, float *fret,
+	float (*func)(float []));
+void linmin_arg(float p[], float xi[], int n, float *fret,
+	float (*func)(float [], void*), void *arg);
+void lnsrch(int n, float xold[], float fold, float g[], float p[], float x[],
+	 float *f, float stpmax, int *check, float (*func)(float []));
+void load(float x1, float v[], float y[]);
+void load1(float x1, float v1[], float y[]);
+void load2(float x2, float v2[], float y[]);
+void locate(float xx[], unsigned long n, float x, unsigned long *j);
+void lop(double **out, double **u, int n);
+void lubksb(float **a, int n, int *indx, float b[]);
+void ludcmp(float **a, int n, int *indx, float *d);
+void machar(int *ibeta, int *it, int *irnd, int *ngrd,
+	int *machep, int *negep, int *iexp, int *minexp, int *maxexp,
+	float *eps, float *epsneg, float *xmin, float *xmax);
+void matadd(double **a, double **b, double **c, int n);
+void matsub(double **a, double **b, double **c, int n);
+void medfit(float x[], float y[], int ndata, float *a, float *b, float *abdev);
+void memcof(float data[], int n, int m, float *xms, float d[]);
+int metrop(float de, float t);
+void mgfas(double **u, int n, int maxcyc);
+void mglin(double **u, int n, int ncycle);
+float midexp(float (*funk)(float), float aa, float bb, int n);
+float midinf(float (*funk)(float), float aa, float bb, int n);
+float midpnt(float (*func)(float), float a, float b, int n);
+float midsql(float (*funk)(float), float aa, float bb, int n);
+float midsqu(float (*funk)(float), float aa, float bb, int n);
+void miser(float (*func)(float []), float regn[], int ndim, unsigned long npts,
+	float dith, float *ave, float *var);
+void mmid(float y[], float dydx[], int nvar, float xs, float htot,
+	int nstep, float yout[], void (*derivs)(float, float[], float[]));
+void mnbrak(float *ax, float *bx, float *cx, float *fa, float *fb,
+	float *fc, float (*func)(float));
+void mnbrak_arg(float *ax, float *bx, float *cx, float *fa, float *fb,
+	float *fc, float (*func)(float, void*), void *arg);
+void mnewt(int ntrial, float x[], int n, float tolx, float tolf);
+void moment(float data[], int n, float *ave, float *adev, float *sdev,
+	float *var, float *skew, float *curt);
+void mp2dfr(unsigned char a[], unsigned char s[], int n, int *m);
+void mpadd(unsigned char w[], unsigned char u[], unsigned char v[], int n);
+void mpdiv(unsigned char q[], unsigned char r[], unsigned char u[],
+	unsigned char v[], int n, int m);
+void mpinv(unsigned char u[], unsigned char v[], int n, int m);
+void mplsh(unsigned char u[], int n);
+void mpmov(unsigned char u[], unsigned char v[], int n);
+void mpmul(unsigned char w[], unsigned char u[], unsigned char v[], int n,
+	int m);
+void mpneg(unsigned char u[], int n);
+void mppi(int n);
+void mprove(float **a, float **alud, int n, int indx[], float b[],
+	float x[]);
+void mpsad(unsigned char w[], unsigned char u[], int n, int iv);
+void mpsdv(unsigned char w[], unsigned char u[], int n, int iv, int *ir);
+void mpsmu(unsigned char w[], unsigned char u[], int n, int iv);
+void mpsqrt(unsigned char w[], unsigned char u[], unsigned char v[], int n,
+	int m);
+void mpsub(int *is, unsigned char w[], unsigned char u[], unsigned char v[],
+	int n);
+void mrqcof(float x[], float y[], float sig[], int ndata, float a[],
+	int ia[], int ma, float **alpha, float beta[], float *chisq,
+	void (*funcs)(float, float [], float *, float [], int));
+void mrqmin(float x[], float y[], float sig[], int ndata, float a[],
+	int ia[], int ma, float **covar, float **alpha, float *chisq,
+	void (*funcs)(float, float [], float *, float [], int), float *alamda);
+void newt(float x[], int n, int *check,
+	void (*vecfunc)(int, float [], float []));
+void odeint(float ystart[], int nvar, float x1, float x2,
+	float eps, float h1, float hmin, int *nok, int *nbad,
+	void (*derivs)(float, float [], float []),
+	void (*rkqs)(float [], float [], int, float *, float, float,
+	float [], float *, float *, void (*)(float, float [], float [])));
+void orthog(int n, float anu[], float alpha[], float beta[], float a[],
+	float b[]);
+void pade(double cof[], int n, float *resid);
+void pccheb(float d[], float c[], int n);
+void pcshft(float a, float b, float d[], int n);
+void pearsn(float x[], float y[], unsigned long n, float *r, float *prob,
+	float *z);
+void period(float x[], float y[], int n, float ofac, float hifac,
+	float px[], float py[], int np, int *nout, int *jmax, float *prob);
+void piksr2(int n, float arr[], float brr[]);
+void piksrt(int n, float arr[]);
+void pinvs(int ie1, int ie2, int je1, int jsf, int jc1, int k,
+	float ***c, float **s);
+float plgndr(int l, int m, float x);
+float poidev(float xm, long *idum);
+void polcoe(float x[], float y[], int n, float cof[]);
+void polcof(float xa[], float ya[], int n, float cof[]);
+void poldiv(float u[], int n, float v[], int nv, float q[], float r[]);
+void polin2(float x1a[], float x2a[], float **ya, int m, int n,
+	float x1, float x2, float *y, float *dy);
+void polint(float xa[], float ya[], int n, float x, float *y, float *dy);
+void powell(float p[], float **xi, int n, float ftol, int *iter, float *fret,
+	float (*func)(float []));
+void predic(float data[], int ndata, float d[], int m, float future[], int nfut);
+float probks(float alam);
+void psdes(unsigned long *lword, unsigned long *irword);
+void pwt(float a[], unsigned long n, int isign);
+void pwtset(int n);
+float pythag(float a, float b);
+void pzextr(int iest, float xest, float yest[], float yz[], float dy[],
+	int nv);
+float qgaus(float (*func)(float), float a, float b);
+void qrdcmp(float **a, int n, float *c, float *d, int *sing);
+float qromb(float (*func)(float), float a, float b);
+float qromo(float (*func)(float), float a, float b,
+	float (*choose)(float (*)(float), float, float, int));
+void qroot(float p[], int n, float *b, float *c, float eps);
+void qrsolv(float **a, int n, float c[], float d[], float b[]);
+void qrupdt(float **r, float **qt, int n, float u[], float v[]);
+float qsimp(float (*func)(float), float a, float b);
+float qtrap(float (*func)(float), float a, float b);
+float quad3d(float (*func)(float, float, float), float x1, float x2);
+void quadct(float x, float y, float xx[], float yy[], unsigned long nn,
+	float *fa, float *fb, float *fc, float *fd);
+void quadmx(float **a, int n);
+void quadvl(float x, float y, float *fa, float *fb, float *fc, float *fd);
+float ran0(long *idum);
+float ran1(long *idum);
+float ran2(long *idum);
+float ran3(long *idum);
+float ran4(long *idum);
+void rank(unsigned long n, unsigned long indx[], unsigned long irank[]);
+void ranpt(float pt[], float regn[], int n);
+void ratint(float xa[], float ya[], int n, float x, float *y, float *dy);
+void ratlsq(double (*fn)(double), double a, double b, int mm, int kk,
+	double cof[], double *dev);
+double ratval(double x, double cof[], int mm, int kk);
+float rc(float x, float y);
+float rd(float x, float y, float z);
+void realft(float data[], unsigned long n, int isign);
+void rebin(float rc, int nd, float r[], float xin[], float xi[]);
+void red(int iz1, int iz2, int jz1, int jz2, int jm1, int jm2, int jmf,
+	int ic1, int jc1, int jcf, int kc, float ***c, float **s);
+void relax(double **u, double **rhs, int n);
+void relax2(double **u, double **rhs, int n);
+void resid(double **res, double **u, double **rhs, int n);
+float revcst(float x[], float y[], int iorder[], int ncity, int n[]);
+void reverse(int iorder[], int ncity, int n[]);
+float rf(float x, float y, float z);
+float rj(float x, float y, float z, float p);
+void rk4(float y[], float dydx[], int n, float x, float h, float yout[],
+	void (*derivs)(float, float [], float []));
+void rkck(float y[], float dydx[], int n, float x, float h,
+	float yout[], float yerr[], void (*derivs)(float, float [], float []));
+void rkdumb(float vstart[], int nvar, float x1, float x2, int nstep,
+	void (*derivs)(float, float [], float []));
+void rkqs(float y[], float dydx[], int n, float *x,
+	float htry, float eps, float yscal[], float *hdid, float *hnext,
+	void (*derivs)(float, float [], float []));
+void rlft3(float ***data, float **speq, unsigned long nn1,
+	unsigned long nn2, unsigned long nn3, int isign);
+float rofunc(float b);
+void rotate(float **r, float **qt, int n, int i, float a, float b);
+void rsolv(float **a, int n, float d[], float b[]);
+void rstrct(double **uc, double **uf, int nc);
+float rtbis(float (*func)(float), float x1, float x2, float xacc);
+float rtflsp(float (*func)(float), float x1, float x2, float xacc);
+float rtnewt(void (*funcd)(float, float *, float *), float x1, float x2,
+	float xacc);
+float rtsafe(void (*funcd)(float, float *, float *), float x1, float x2,
+	float xacc);
+float rtsec(float (*func)(float), float x1, float x2, float xacc);
+void rzextr(int iest, float xest, float yest[], float yz[], float dy[], int nv);
+void savgol(float c[], int np, int nl, int nr, int ld, int m);
+void score(float xf, float y[], float f[]);
+void scrsho(float (*fx)(float));
+float select(unsigned long k, unsigned long n, float arr[]);
+float selip(unsigned long k, unsigned long n, float arr[]);
+void shell(unsigned long n, float a[]);
+void shoot(int n, float v[], float f[]);
+void shootf(int n, float v[], float f[]);
+void simp1(float **a, int mm, int ll[], int nll, int iabf, int *kp,
+	float *bmax);
+void simp2(float **a, int n, int l2[], int nl2, int *ip, int kp, float *q1);
+void simp3(float **a, int i1, int k1, int ip, int kp);
+void simplx(float **a, int m, int n, int m1, int m2, int m3, int *icase,
+	int izrov[], int iposv[]);
+void simpr(float y[], float dydx[], float dfdx[], float **dfdy,
+	int n, float xs, float htot, int nstep, float yout[],
+	void (*derivs)(float, float [], float []));
+void sinft(float y[], int n);
+void slvsm2(double **u, double **rhs);
+void slvsml(double **u, double **rhs);
+void sncndn(float uu, float emmc, float *sn, float *cn, float *dn);
+double snrm(unsigned long n, double sx[], int itol);
+void sobseq(int *n, float x[]);
+void solvde(int itmax, float conv, float slowc, float scalv[],
+	int indexv[], int ne, int nb, int m, float **y, float ***c, float **s);
+void sor(double **a, double **b, double **c, double **d, double **e,
+	double **f, double **u, int jmax, double rjac);
+void sort(unsigned long n, float arr[]);
+void sort2(unsigned long n, float arr[], float brr[]);
+void sort3(unsigned long n, float ra[], float rb[], float rc[]);
+void spctrm(FILE *fp, float p[], int m, int k, int ovrlap);
+void spear(float data1[], float data2[], unsigned long n, float *d, float *zd,
+	float *probd, float *rs, float *probrs);
+void sphbes(int n, float x, float *sj, float *sy, float *sjp, float *syp);
+void splie2(float x1a[], float x2a[], float **ya, int m, int n, float **y2a);
+void splin2(float x1a[], float x2a[], float **ya, float **y2a, int m, int n,
+	float x1, float x2, float *y);
+void spline(float x[], float y[], int n, float yp1, float ypn, float y2[]);
+void splint(float xa[], float ya[], float y2a[], int n, float x, float *y);
+void spread(float y, float yy[], unsigned long n, float x, int m);
+void sprsax(float sa[], unsigned long ija[], float x[], float b[],
+	unsigned long n);
+void sprsin(float **a, int n, float thresh, unsigned long nmax, float sa[],
+	unsigned long ija[]);
+void sprspm(float sa[], unsigned long ija[], float sb[], unsigned long ijb[],
+	float sc[], unsigned long ijc[]);
+void sprstm(float sa[], unsigned long ija[], float sb[], unsigned long ijb[],
+	float thresh, unsigned long nmax, float sc[], unsigned long ijc[]);
+void sprstp(float sa[], unsigned long ija[], float sb[], unsigned long ijb[]);
+void sprstx(float sa[], unsigned long ija[], float x[], float b[],
+	unsigned long n);
+void stifbs(float y[], float dydx[], int nv, float *xx,
+	float htry, float eps, float yscal[], float *hdid, float *hnext,
+	void (*derivs)(float, float [], float []));
+void stiff(float y[], float dydx[], int n, float *x,
+	float htry, float eps, float yscal[], float *hdid, float *hnext,
+	void (*derivs)(float, float [], float []));
+void stoerm(float y[], float d2y[], int nv, float xs,
+	float htot, int nstep, float yout[],
+	void (*derivs)(float, float [], float []));
+void svbksb(float **u, float w[], float **v, int m, int n, float b[],
+	float x[]);
+void svdcmp(float **a, int m, int n, float w[], float **v);
+void svdfit(float x[], float y[], float sig[], int ndata, float a[],
+	int ma, float **u, float **v, float w[], float *chisq,
+	void (*funcs)(float, float [], int));
+void svdvar(float **v, int ma, float w[], float **cvm);
+void toeplz(float r[], float x[], float y[], int n);
+void tptest(float data1[], float data2[], unsigned long n, float *t, float *prob);
+void tqli(float d[], float e[], int n, float **z);
+float trapzd(float (*func)(float), float a, float b, int n);
+void tred2(float **a, int n, float d[], float e[]);
+void tridag(float a[], float b[], float c[], float r[], float u[],
+	unsigned long n);
+float trncst(float x[], float y[], int iorder[], int ncity, int n[]);
+void trnspt(int iorder[], int ncity, int n[]);
+void ttest(float data1[], unsigned long n1, float data2[], unsigned long n2,
+	float *t, float *prob);
+void tutest(float data1[], unsigned long n1, float data2[], unsigned long n2,
+	float *t, float *prob);
+void twofft(float data1[], float data2[], float fft1[], float fft2[],
+	unsigned long n);
+void vander(double x[], double w[], double q[], int n);
+void vegas(float regn[], int ndim, float (*fxn)(float [], float), int init,
+	unsigned long ncall, int itmx, int nprn, float *tgral, float *sd,
+	float *chi2a);
+void voltra(int n, int m, float t0, float h, float *t, float **f,
+	float (*g)(int, float), float (*ak)(int, int, float, float));
+void wt1(float a[], unsigned long n, int isign,
+	void (*wtstep)(float [], unsigned long, int));
+void wtn(float a[], unsigned long nn[], int ndim, int isign,
+	void (*wtstep)(float [], unsigned long, int));
+void wwghts(float wghts[], int n, float h,
+	void (*kermom)(double [], double ,int));
+int zbrac(float (*func)(float), float *x1, float *x2);
+void zbrak(float (*fx)(float), float x1, float x2, int n, float xb1[],
+	float xb2[], int *nb);
+float zbrent(float (*func)(float), float x1, float x2, float tol);
+void zrhqr(float a[], int m, float rtr[], float rti[]);
+float zriddr(float (*func)(float), float x1, float x2, float xacc);
+void zroots(fcomplex a[], int m, fcomplex roots[], int polish);
+
+#endif /* _NR_H_ */
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/nrutil.c b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/nrutil.c
new file mode 100644
index 00000000..059dce54
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/nrutil.c
@@ -0,0 +1,321 @@
+/* CAUTION: This is the ANSI C (only) version of the Numerical Recipes
+   utility file nrutil.c.  Do not confuse this file with the same-named
+   file nrutil.c that is supplied in the 'misc' subdirectory.
+   *That* file is the one from the book, and contains both ANSI and
+   traditional K&R versions, along with #ifdef macros to select the
+   correct version.  *This* file contains only ANSI C.               */
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#define NR_END 1
+#define FREE_ARG char*
+
+void nrerror(char error_text[])
+/* Numerical Recipes standard error handler */
+{
+	fprintf(stderr,"Numerical Recipes run-time error...\n");
+	fprintf(stderr,"%s\n",error_text);
+	fprintf(stderr,"...now exiting to system...\n");
+	exit(1);
+}
+
+float *vector(long nl, long nh)
+/* allocate a float vector with subscript range v[nl..nh] */
+{
+	float *v;
+
+	v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float)));
+	if (!v) nrerror("allocation failure in vector()");
+	return v-nl+NR_END;
+}
+
+int *ivector(long nl, long nh)
+/* allocate an int vector with subscript range v[nl..nh] */
+{
+	int *v;
+
+	v=(int *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(int)));
+	if (!v) nrerror("allocation failure in ivector()");
+	return v-nl+NR_END;
+}
+
+unsigned char *cvector(long nl, long nh)
+/* allocate an unsigned char vector with subscript range v[nl..nh] */
+{
+	unsigned char *v;
+
+	v=(unsigned char *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(unsigned char)));
+	if (!v) nrerror("allocation failure in cvector()");
+	return v-nl+NR_END;
+}
+
+unsigned long *lvector(long nl, long nh)
+/* allocate an unsigned long vector with subscript range v[nl..nh] */
+{
+	unsigned long *v;
+
+	v=(unsigned long *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(long)));
+	if (!v) nrerror("allocation failure in lvector()");
+	return v-nl+NR_END;
+}
+
+double *dvector(long nl, long nh)
+/* allocate a double vector with subscript range v[nl..nh] */
+{
+	double *v;
+
+	v=(double *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(double)));
+	if (!v) nrerror("allocation failure in dvector()");
+	return v-nl+NR_END;
+}
+
+float **matrix(long nrl, long nrh, long ncl, long nch)
+/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */
+{
+	long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
+	float **m;
+
+	/* allocate pointers to rows */
+	m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*)));
+	if (!m) nrerror("allocation failure 1 in matrix()");
+	m += NR_END;
+	m -= nrl;
+
+	/* allocate rows and set pointers to them */
+	m[nrl]=(float *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float)));
+	if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
+	m[nrl] += NR_END;
+	m[nrl] -= ncl;
+
+	for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
+
+	/* return pointer to array of pointers to rows */
+	return m;
+}
+
+double **dmatrix(long nrl, long nrh, long ncl, long nch)
+/* allocate a double matrix with subscript range m[nrl..nrh][ncl..nch] */
+{
+	long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
+	double **m;
+
+	/* allocate pointers to rows */
+	m=(double **) malloc((size_t)((nrow+NR_END)*sizeof(double*)));
+	if (!m) nrerror("allocation failure 1 in matrix()");
+	m += NR_END;
+	m -= nrl;
+
+	/* allocate rows and set pointers to them */
+	m[nrl]=(double *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(double)));
+	if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
+	m[nrl] += NR_END;
+	m[nrl] -= ncl;
+
+	for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
+
+	/* return pointer to array of pointers to rows */
+	return m;
+}
+
+int **imatrix(long nrl, long nrh, long ncl, long nch)
+/* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */
+{
+	long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
+	int **m;
+
+	/* allocate pointers to rows */
+	m=(int **) malloc((size_t)((nrow+NR_END)*sizeof(int*)));
+	if (!m) nrerror("allocation failure 1 in matrix()");
+	m += NR_END;
+	m -= nrl;
+
+
+	/* allocate rows and set pointers to them */
+	m[nrl]=(int *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(int)));
+	if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
+	m[nrl] += NR_END;
+	m[nrl] -= ncl;
+
+	for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
+
+	/* return pointer to array of pointers to rows */
+	return m;
+}
+
+float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch,
+	long newrl, long newcl)
+/* point a submatrix [newrl..][newcl..] to a[oldrl..oldrh][oldcl..oldch] */
+{
+	long i,j,nrow=oldrh-oldrl+1,ncol=oldcl-newcl;
+	float **m;
+
+	/* allocate array of pointers to rows */
+	m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*)));
+	if (!m) nrerror("allocation failure in submatrix()");
+	m += NR_END;
+	m -= newrl;
+
+	/* set pointers to rows */
+	for(i=oldrl,j=newrl;i<=oldrh;i++,j++) m[j]=a[i]+ncol;
+
+	/* return pointer to array of pointers to rows */
+	return m;
+}
+
+float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch)
+/* allocate a float matrix m[nrl..nrh][ncl..nch] that points to the matrix
+declared in the standard C manner as a[nrow][ncol], where nrow=nrh-nrl+1
+and ncol=nch-ncl+1. The routine should be called with the address
+&a[0][0] as the first argument. */
+{
+	long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1;
+	float **m;
+
+	/* allocate pointers to rows */
+	m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*)));
+	if (!m) nrerror("allocation failure in convert_matrix()");
+	m += NR_END;
+	m -= nrl;
+
+	/* set pointers to rows */
+	m[nrl]=a-ncl;
+	for(i=1,j=nrl+1;i<nrow;i++,j++) m[j]=m[j-1]+ncol;
+	/* return pointer to array of pointers to rows */
+	return m;
+}
+
+double **convert_dmatrix(double *a, long nrl, long nrh, long ncl, long nch)
+/* allocate a float matrix m[nrl..nrh][ncl..nch] that points to the matrix
+declared in the standard C manner as a[nrow][ncol], where nrow=nrh-nrl+1
+and ncol=nch-ncl+1. The routine should be called with the address
+&a[0][0] as the first argument. */
+{
+	long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1;
+	double **m;
+
+	/* allocate pointers to rows */
+	m=(double **) malloc((size_t) ((nrow+NR_END)*sizeof(double*)));
+	if (!m) nrerror("allocation failure in convert_dmatrix()");
+	m += NR_END;
+	m -= nrl;
+
+	/* set pointers to rows */
+	m[nrl]=a-ncl;
+	for(i=1,j=nrl+1;i<nrow;i++,j++) m[j]=m[j-1]+ncol;
+	/* return pointer to array of pointers to rows */
+	return m;
+}
+
+float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh)
+/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */
+{
+	long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
+	float ***t;
+
+	/* allocate pointers to pointers to rows */
+	t=(float ***) malloc((size_t)((nrow+NR_END)*sizeof(float**)));
+	if (!t) nrerror("allocation failure 1 in f3tensor()");
+	t += NR_END;
+	t -= nrl;
+
+	/* allocate pointers to rows and set pointers to them */
+	t[nrl]=(float **) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float*)));
+	if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
+	t[nrl] += NR_END;
+	t[nrl] -= ncl;
+
+	/* allocate rows and set pointers to them */
+	t[nrl][ncl]=(float *) malloc((size_t)((nrow*ncol*ndep+NR_END)*sizeof(float)));
+	if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
+	t[nrl][ncl] += NR_END;
+	t[nrl][ncl] -= ndl;
+
+	for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
+	for(i=nrl+1;i<=nrh;i++) {
+		t[i]=t[i-1]+ncol;
+		t[i][ncl]=t[i-1][ncl]+ncol*ndep;
+		for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
+	}
+
+	/* return pointer to array of pointers to rows */
+	return t;
+}
+
+void free_vector(float *v, long nl, long nh)
+/* free a float vector allocated with vector() */
+{
+	free((FREE_ARG) (v+nl-NR_END));
+}
+
+void free_ivector(int *v, long nl, long nh)
+/* free an int vector allocated with ivector() */
+{
+	free((FREE_ARG) (v+nl-NR_END));
+}
+
+void free_cvector(unsigned char *v, long nl, long nh)
+/* free an unsigned char vector allocated with cvector() */
+{
+	free((FREE_ARG) (v+nl-NR_END));
+}
+
+void free_lvector(unsigned long *v, long nl, long nh)
+/* free an unsigned long vector allocated with lvector() */
+{
+	free((FREE_ARG) (v+nl-NR_END));
+}
+
+void free_dvector(double *v, long nl, long nh)
+/* free a double vector allocated with dvector() */
+{
+	free((FREE_ARG) (v+nl-NR_END));
+}
+
+void free_matrix(float **m, long nrl, long nrh, long ncl, long nch)
+/* free a float matrix allocated by matrix() */
+{
+	free((FREE_ARG) (m[nrl]+ncl-NR_END));
+	free((FREE_ARG) (m+nrl-NR_END));
+}
+
+void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch)
+/* free a double matrix allocated by dmatrix() */
+{
+	free((FREE_ARG) (m[nrl]+ncl-NR_END));
+	free((FREE_ARG) (m+nrl-NR_END));
+}
+
+void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch)
+/* free an int matrix allocated by imatrix() */
+{
+	free((FREE_ARG) (m[nrl]+ncl-NR_END));
+	free((FREE_ARG) (m+nrl-NR_END));
+}
+
+void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch)
+/* free a submatrix allocated by submatrix() */
+{
+	free((FREE_ARG) (b+nrl-NR_END));
+}
+
+void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch)
+/* free a matrix allocated by convert_matrix() */
+{
+	free((FREE_ARG) (b+nrl-NR_END));
+}
+
+void free_convert_dmatrix(double **b, long nrl, long nrh, long ncl, long nch)
+/* free a matrix allocated by convert_matrix() */
+{
+	free((FREE_ARG) (b+nrl-NR_END));
+}
+
+void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch,
+	long ndl, long ndh)
+/* free a float f3tensor allocated by f3tensor() */
+{
+	free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END));
+	free((FREE_ARG) (t[nrl]+ncl-NR_END));
+	free((FREE_ARG) (t+nrl-NR_END));
+}
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/nrutil.h b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/nrutil.h
new file mode 100644
index 00000000..45b1447f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/nrutil.h
@@ -0,0 +1,79 @@
+/* CAUTION: This is the ANSI C (only) version of the Numerical Recipes
+   utility file nrutil.h.  Do not confuse this file with the same-named
+   file nrutil.h that is supplied in the 'misc' subdirectory.
+   *That* file is the one from the book, and contains both ANSI and
+   traditional K&R versions, along with #ifdef macros to select the
+   correct version.  *This* file contains only ANSI C.               */
+
+#ifndef _NR_UTILS_H_
+#define _NR_UTILS_H_
+
+static float sqrarg;
+#define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
+
+static double dsqrarg;
+#define DSQR(a) ((dsqrarg=(a)) == 0.0 ? 0.0 : dsqrarg*dsqrarg)
+
+static double dmaxarg1,dmaxarg2;
+#define DMAX(a,b) (dmaxarg1=(a),dmaxarg2=(b),(dmaxarg1) > (dmaxarg2) ?\
+        (dmaxarg1) : (dmaxarg2))
+
+static double dminarg1,dminarg2;
+#define DMIN(a,b) (dminarg1=(a),dminarg2=(b),(dminarg1) < (dminarg2) ?\
+        (dminarg1) : (dminarg2))
+
+static float maxarg1,maxarg2;
+#define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\
+        (maxarg1) : (maxarg2))
+
+static float minarg1,minarg2;
+#define FMIN(a,b) (minarg1=(a),minarg2=(b),(minarg1) < (minarg2) ?\
+        (minarg1) : (minarg2))
+
+static long lmaxarg1,lmaxarg2;
+#define LMAX(a,b) (lmaxarg1=(a),lmaxarg2=(b),(lmaxarg1) > (lmaxarg2) ?\
+        (lmaxarg1) : (lmaxarg2))
+
+static long lminarg1,lminarg2;
+#define LMIN(a,b) (lminarg1=(a),lminarg2=(b),(lminarg1) < (lminarg2) ?\
+        (lminarg1) : (lminarg2))
+
+static int imaxarg1,imaxarg2;
+#define IMAX(a,b) (imaxarg1=(a),imaxarg2=(b),(imaxarg1) > (imaxarg2) ?\
+        (imaxarg1) : (imaxarg2))
+
+static int iminarg1,iminarg2;
+#define IMIN(a,b) (iminarg1=(a),iminarg2=(b),(iminarg1) < (iminarg2) ?\
+        (iminarg1) : (iminarg2))
+
+#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
+
+void nrerror(char error_text[]);
+float *vector(long nl, long nh);
+int *ivector(long nl, long nh);
+unsigned char *cvector(long nl, long nh);
+unsigned long *lvector(long nl, long nh);
+double *dvector(long nl, long nh);
+float **matrix(long nrl, long nrh, long ncl, long nch);
+double **dmatrix(long nrl, long nrh, long ncl, long nch);
+int **imatrix(long nrl, long nrh, long ncl, long nch);
+float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch,
+	long newrl, long newcl);
+float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch);
+double **convert_dmatrix(double *a, long nrl, long nrh, long ncl, long nch);
+float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
+void free_vector(float *v, long nl, long nh);
+void free_ivector(int *v, long nl, long nh);
+void free_cvector(unsigned char *v, long nl, long nh);
+void free_lvector(unsigned long *v, long nl, long nh);
+void free_dvector(double *v, long nl, long nh);
+void free_matrix(float **m, long nrl, long nrh, long ncl, long nch);
+void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch);
+void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch);
+void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch);
+void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch);
+void free_convert_dmatrix(double **b, long nrl, long nrh, long ncl, long nch);
+void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch,
+	long ndl, long ndh);
+
+#endif /* _NR_UTILS_H_ */
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/quickscore.m b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/quickscore.m
new file mode 100644
index 00000000..1a9b534a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/private/quickscore.m
@@ -0,0 +1,76 @@
+function prob = quickscore(fpos, fneg, inhibit, prior, leak)
+% QUICKSCORE Heckerman's algorithm for BN2O networks.
+% prob = quickscore(fpos, fneg, inhibit, prior, leak)
+% 
+% Consider a BN2O (Binary Node 2-layer Noisy-or) network such as QMR with
+% dieases on the top and findings on the bottom. (We assume all findings are observed,
+% since hidden leaves can be marginalized away.)
+% This algorithm takes O(2^|fpos|) time to compute the marginal on all the diseases.
+%
+% Inputs:
+% fpos = the positive findings (a vector of numbers in {1, ..., Nfindings})
+% fneg = the negative findings (a vector of numbers in {1, ..., Nfindings})
+% inhibit(i,j) = inhibition prob. for finding i, disease j, or 1.0 if j is not a parent.
+% prior(j) = prior prob. disease j is ON. We assume prior(off) = 1-prior(on).
+% leak(i) = inhibition prob. for the leak node for finding i
+%
+% Output:
+% prob(d) = Pr(disease d = on | ev)
+%
+% For details, see
+% - Heckerman, "A tractable inference algorithm for diagnosing multiple diseases", UAI89.
+% - Rish and Dechter, "On the impact of causal independence", UCI tech report, 1998.
+%
+% Note that this algorithm is numerically unstable, since it adds a large number of positive and
+% negative terms and hopes that some of them exactly cancel.
+%
+% For matlab experts, use 'mex' to compile C_quickscore, which has identical behavior to this function.
+
+[nfindings ndiseases] = size(inhibit);
+
+% make the first disease be always on, for the leak term
+Pon = [1 prior(:)'];
+Poff = 1-Pon;
+Uon = [leak(:) inhibit]; % U(f,d) = Pr(f=0|d=1)
+Uoff = [leak(:) ones(nfindings, ndiseases)]; % Uoff(f,d) = Pr(f=0|d=0)
+ndiseases = ndiseases + 1;
+
+npos = length(fpos);
+post = zeros(ndiseases, 2);
+% post(d,1) = alpha Pr(d=off), post(d,2) = alpha Pr(d=m)
+
+FP = length(fpos);
+%allbits = logical(dec2bitv(0:(2^FP - 1), FP));
+allbits = logical(ind2subv(2*ones(1,FP), 1:(2^FP))-1);
+
+for si=1:2^FP
+  bits = allbits(si,:);
+  fprime = fpos(bits);
+  fmask = zeros(1, nfindings);
+  fmask(fneg)=1;
+  fmask(fprime)=1;
+  fmask = logical(fmask);
+  p = 1;
+  pterm = zeros(1, ndiseases);
+  ptermOff = zeros(1, ndiseases);
+  ptermOn = zeros(1, ndiseases);
+  for d=1:ndiseases
+    ptermOff(d) = prod(Uoff(fmask,d));
+    ptermOn(d) = prod(Uon(fmask,d));
+    pterm(d) = Poff(d)*ptermOff(d) + Pon(d)*ptermOn(d);
+  end
+  p = prod(pterm);
+  sign = (-1)^(length(fprime));
+  for d=1:ndiseases
+    myp = p / pterm(d);
+    post(d,1) = post(d,1) + sign*(myp * ptermOff(d));
+    post(d,2) = post(d,2) + sign*(myp * ptermOn(d));
+  end
+end
+
+post(:,1) = post(:,1) .* Poff(:);
+post(:,2) = post(:,2) .* Pon(:);
+post = mk_stochastic(post);
+prob = post(2:end,2)'; % skip the leak term
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/quickscore_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/quickscore_inf_engine.m
new file mode 100644
index 00000000..a9463c40
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@quickscore_inf_engine/quickscore_inf_engine.m
@@ -0,0 +1,38 @@
+function engine = quickscore_inf_engine(inhibit, leak, prior)
+% QUICKSCORE_INF_ENGINE Exact inference for the QMR network
+% engine = quickscore_inf_engine(inhibit, leak, prior)
+%
+% We create an inference engine for QMR-like networks.
+% QMR is a bipartite graph, where the top layer contains hidden disease nodes,
+% and the bottom later contains observed finding nodes.
+% The diseases have Bernoulli CPDs, the findings noisy-or CPDs.
+% The original QMR (Quick Medical Reference) network has specific parameter values which we are not
+% allowed to release, for commercial reasons.
+%
+% inhibit(f,d) = inhibition probability on f->d arc for disease d, finding f
+% If inhibit(f,d) = 1, there is effectively no arc from d->f
+% leak(j) = inhibition prob. on leak node -> finding j arc
+% prior(i) = prob. disease i is on
+%
+% We use exact inference, which takes O(2^P) time, where P is the number of positive findings.
+% For details, see
+% - Heckerman, "A tractable inference algorithm for diagnosing multiple diseases", UAI 89.
+% - Rish and Dechter, "On the impact of causal independence", UCI tech report, 1998.
+% Note that this algorithm is numerically unstable, since it adds a large number of positive and
+% negative terms and hopes that some of them exactly cancel.
+%
+% For an interesting variational approximation, see
+% - Jaakkola and Jordan, "Variational probabilistic inference and the QMR-DT network", JAIR 10, 1999.
+%
+% See also 
+% - "Loopy belief propagation for approximate inference: an empirical study",
+%      K. Murphy, Y. Weiss and M. Jordan, UAI 99.
+
+engine.inhibit = inhibit;
+engine.leak = leak;
+engine.prior = prior;
+
+% store results here between enter_evidence and marginal_nodes
+engine.post = [];
+
+engine = class(engine, 'quickscore_inf_engine'); % not a child of the inf_engine class!
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries
new file mode 100644
index 00000000..055aa4df
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries
@@ -0,0 +1,11 @@
+/README/1.1.1.1/Sun May 11 15:39:50 2003//
+/clq_containing_nodes.m/1.1.1.1/Wed May 29 11:59:46 2002//
+/enter_evidence.m/1.1.1.1/Wed Mar 12 10:38:00 2003//
+/marginal_difclq_nodes.m/1.1.1.1/Fri Feb 21 11:20:32 2003//
+/marginal_nodes.m/1.1.1.1/Fri Feb 21 11:13:10 2003//
+/marginal_singleclq_nodes.m/1.1.1.1/Wed Jan 29 11:23:58 2003//
+/problems.txt/1.1.1.1/Wed May 29 11:59:46 2002//
+/push.m/1.1.1.1/Mon Feb 10 15:38:04 2003//
+/push_pot_toclique.m/1.1.1.1/Wed May 29 11:59:46 2002//
+/stab_cond_gauss_inf_engine.m/1.1.1.1/Fri Mar 28 17:12:42 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Repository
new file mode 100644
index 00000000..849daef7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@stab_cond_gauss_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Entries
new file mode 100644
index 00000000..ce0c4813
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Entries
@@ -0,0 +1,2 @@
+/initialize_engine.m/1.1.1.1/Wed May 29 11:59:46 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Repository
new file mode 100644
index 00000000..eb292815
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@stab_cond_gauss_inf_engine/Old
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/initialize_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/initialize_engine.m
new file mode 100644
index 00000000..6fb51c2e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/Old/initialize_engine.m
@@ -0,0 +1,65 @@
+function [engine, loglik] = initialize_engine(engine)
+%initialize
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes(:);
+N = length(bnet.dag);
+
+pot_type = 'scg'
+check_for_cd_arcs([], bnet.cnodes, bnet.dag);
+
+% Evaluate CPDs with evidence, and convert to potentials  
+pot = cell(1, N);
+C = length(engine.cliques);
+inited = zeros(1, C);
+clpot = cell(1, C);
+evidence = cell(1, N);
+for n=1:N
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n);
+  pot{n} = CPD_to_scgpot(bnet.CPD{e}, fam, ns, bnet.cnodes, evidence);
+  cindex = engine.clq_ass_to_node(n);
+  if inited(cindex)
+      %clpot{cindex} = direct_combine_pots(clpot{cindex}, pot{n});
+      clpot{cindex} = direct_combine_pots(pot{n}, clpot{cindex});
+  else
+      clpot{cindex} = pot{n};
+      inited(cindex) = 1;
+  end
+end
+
+for i=1:C
+    if inited(i) == 0
+        clpot{i} = scgpot([], [], [], []);
+    end
+end
+
+seppot = cell(C, C);
+% separators are is not need to initialize
+
+% collect to root (node to parents)
+for n=engine.postorder(1:end-1)
+  for p=parents(engine.jtree, n)
+      [margpot, comppot] = complement_pot(clpot{n}, engine.separator{p,n});
+      margpot = marginalize_pot(clpot{n}, engine.separator{p,n});
+      clpot{n} = comppot;
+      %seppot{p, n} = margpot;
+      clpot{p} = combine_pots(clpot{p}, margpot);
+      %clpot{p} = combine_pots(margpot, clpot{p});
+  end
+end
+
+temppot = clpot;
+%temppot = clpot{engine.root};
+for n=engine.preorder
+  for c=children(engine.jtree, n)
+    seppot{n,c} = marginalize_pot(temppot{n}, engine.separator{n,c});
+    %seppot{n,c} = marginalize_pot(clpot{n}, engine.separator{n,c});
+    %clpot{c} = direct_combine_pots(clpot{c}, seppot{n,c});
+    temppot{c} = direct_combine_pots(temppot{c}, seppot{n,c});
+  end
+end
+
+engine.clpot = clpot;
+engine.seppot = seppot;
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/README b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/README
new file mode 100644
index 00000000..e905e28c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/README
@@ -0,0 +1,12 @@
+% Stable conditional Gaussian inference
+% Originally written by Huang, Shan <shan.huang@intel.com> 2001
+% Fixed by Rainer Deventer 2003
+
+
+@techreport{Lauritzen99,
+  author = "S. Lauritzen and F. Jensen",
+  title = "Stable Local Computation with Conditional {G}aussian Distributions",
+  year = 1999,
+  number = "R-99-2014",
+  institution = "Dept. Math. Sciences, Aalborg Univ."
+}
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/clq_containing_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/clq_containing_nodes.m
new file mode 100644
index 00000000..c64d2bff
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/clq_containing_nodes.m
@@ -0,0 +1,24 @@
+function c = clq_containing_nodes(engine, nodes, fam)
+% CLQ_CONTAINING_NODES Find the lightest clique (if any) that contains the set of nodes
+% c = clq_containing_nodes(engine, nodes, family)
+%
+% If the optional 'family' argument is specified, it means nodes = family(nodes(end)).
+% (This is useful since clq_ass_to_node is not accessible to outsiders.)
+% Returns c=-1 if there is no such clique.
+
+if nargin < 3, fam = 0; else fam = 1; end
+
+if length(nodes)==1
+  c = engine.clq_ass_to_node(nodes(1));
+elseif fam
+  c = engine.clq_ass_to_node(nodes(end));
+else
+  B = engine.cliques_bitv;
+  w = engine.clique_weight;
+  clqs = find(all(B(:,nodes), 2)); % all selected columns must be 1
+  if isempty(clqs)
+    c = -1;
+  else
+    c = clqs(argmin(w(clqs)));     
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..4b02fc8f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/enter_evidence.m
@@ -0,0 +1,260 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE enter evidence to engine including discrete and continuous evidence
+% [engine, ll] = enter_evidence(engine, evidence)
+%
+% ll is always 0, which is wrong.
+
+if ~isempty(engine.evidence)
+    bnet = bnet_from_engine(engine);
+    engine = stab_cond_gauss_inf_engine(bnet);
+    engine.evidence = evidence;
+else
+    engine.evidence = evidence;
+    bnet = bnet_from_engine(engine);
+end
+
+engine.evidence = evidence;
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes(:);
+observed = ~isemptycell(evidence);
+onodes = find(observed);
+hnodes = find(isemptycell(evidence));
+cobs = myintersect(bnet.cnodes, onodes);
+dobs = myintersect(bnet.dnodes, onodes);
+
+engine = incorporate_dis_evidence(engine, dobs, evidence);
+l = length(cobs);
+for i = 1:l
+    node = cobs(i);
+    engine = incorporate_singleconts_evidence(engine, node, evidence);
+end
+clpot = engine.clpot;
+
+clq_num = length(engine.cliques);
+for n=engine.postorder(1:end-1)
+  for p=parents(engine.jtree, n)
+      [margpot, comppot] = complement_pot(clpot{n}, engine.separator{p,n});
+      clpot{n} = comppot;
+      clpot{p} = combine_pots(clpot{p}, margpot);
+  end
+end
+
+temppot = clpot;
+for n=engine.preorder
+  for c=children(engine.jtree, n)
+    seppot{n,c} = marginalize_pot(temppot{n}, engine.separator{n,c});
+    temppot{c} = direct_combine_pots(temppot{c}, seppot{n,c});
+  end
+end
+engine.clpot = clpot;
+engine.seppot = seppot;
+
+[pot,loglik]=normalize_pot(clpot{engine.root});
+
+%%%%%%%%%%%%%%%%%%
+function engine = incorporate_dis_evidence(engine, donodes, evidence)
+l = length(donodes);
+for i=donodes(:)'
+    node = i;
+    clqid = engine.clq_ass_to_node(node);
+    pot = struct(engine.clpot{clqid});
+    ns = zeros(1, max(pot.domain));
+    ns(pot.ddom) = pot.dsizes;
+    ns(pot.cheaddom) = pot.cheadsizes;
+    ns(pot.ctaildom) = pot.ctailsizes;
+    ddom = pot.ddom;
+    
+    potcarray = cell(1, pot.dsize);
+    for j =1:pot.dsize
+        tpotc = struct(pot.scgpotc{j});
+        potcarray{j} = scgcpot(tpotc.cheadsize, tpotc.ctailsize, 0, tpotc.A, tpotc.B, tpotc.C);
+    end
+    
+    if length(ns(ddom)) == 1
+        matrix = pot.scgpotc;
+    else
+        matrix = reshape(pot.scgpotc,ns(ddom)); 
+        potcarray = reshape(potcarray, ns(ddom));
+    end
+    
+    map = find_equiv_posns(node, ddom);
+    vals = cat(1, evidence{node});
+    index = mk_multi_index(length(ddom), map, vals);
+    potcarray(index{:}) = matrix(index{:});
+    potcarray = potcarray(:);
+    %keyboard;
+    engine.clpot{clqid} = scgpot(pot.ddom, pot.cheaddom, pot.ctaildom, ns, potcarray);
+end
+
+%%%%%%%%%%%%%%%%%%
+function engine = incorporate_singleconts_evidence(engine, node, evidence)
+%incorporate_singleconts_evidence incorporate evidence of 1 continuous node
+B = engine.cliques_bitv;
+clqs_containnode = find(all(B(:,node), 2)); % all selected columns must be 1
+% Every continuous node necessarily apears as head in exactly one clique,
+% which is the clique where it appears closest to the strong root. In all other
+% clique potentials where it appears, it must be a tail node.
+clq_ev_as_head = [];
+for i = clqs_containnode(:)'
+    pot = struct(engine.clpot{i});
+    if myismember(node, pot.cheaddom)
+        clq_ev_as_head = [clq_ev_as_head i];
+        break;
+    end
+end
+	       
+% If we will incorporate the evidence node which is head of a potential we must rearrange
+% the juntion tree by push operation until the tail of the include potential is empty
+if ~isempty(clq_ev_as_head)
+    assert(1 == length(clq_ev_as_head));
+    i = clq_ev_as_head;
+    pot = struct(engine.clpot{i});
+    while ~isempty(pot.ctaildom)
+        [engine, clqtoroot] = push(engine, i, node);
+        i = clqtoroot;
+        pot = struct(engine.clpot{i});
+    end
+    B = engine.cliques_bitv;
+    clqs_containnode = find(all(B(:,node), 2));
+end
+
+for i = clqs_containnode(:)'
+    pot = struct(engine.clpot{i});
+    if myismember(node, pot.cheaddom)
+        engine.clpot{i} = incoporate_evidence_headnode(engine.clpot{i}, node, evidence);
+    else
+        %assert(myismember(node, pot.ctaildom));
+        engine.clpot{i} = incoporate_evidence_tailnode(engine.clpot{i}, node, evidence);
+    end
+end
+
+%%%%%%%%%%%%%%%%%%
+function newscgpot = incoporate_evidence_tailnode(pot, node, evidence)
+%ENTER_EVIDENCE_TAILNODE enter the evidence of 1 tailnode of the scgpot
+newscgpot = pot;
+pot = struct(pot);
+%if isempty(pot.ctaildom)
+if ~myismember(node, pot.ctaildom)
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % In this case there is no real dependency of the head nodes %
+    % on the tail. The potential should be returned unchanged    %
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    return;
+end
+%newscgpot = scgpot([], [], [], []);
+assert(myismember(node, pot.ctaildom));
+ni = block(find_equiv_posns(node, pot.ctaildom), pot.ctailsizes);
+
+ctaildom = mysetdiff(pot.ctaildom, node);
+cheaddom = pot.cheaddom;
+ddom = pot.ddom;
+domain = mysetdiff(pot.domain, node);
+dsize = pot.dsize;
+ns = zeros(1, max(pot.domain));
+ns(pot.ddom) = pot.dsizes;
+ns(pot.cheaddom) = pot.cheadsizes;
+ns(pot.ctaildom) = pot.ctailsizes;
+cheadsizes = pot.cheadsizes;
+cheadsize = pot.cheadsize;
+ctailsizes = ns(ctaildom);
+ctailsize = sum(ns(ctaildom));
+
+potarray = cell(1, dsize);
+for i=1:dsize
+    potc = struct(pot.scgpotc{i});
+    B = potc.B;
+    A = potc.A + B(:, ni)*evidence{node};
+    B(:, ni) = [];
+    potarray{i} = scgcpot(cheadsize, ctailsize, potc.p, A, B, potc.C);
+end
+
+newscgpot = scgpot(ddom, cheaddom, ctaildom, ns, potarray);
+
+%%%%%%%%%%%%%%%%
+function newscgpot = incoporate_evidence_headnode(pot, node, evidence)
+%ENTER_EVIDENCE_HEADNODE 
+pot = struct(pot);
+y2 = evidence{node};
+assert(myismember(node, pot.cheaddom));
+assert(isempty(pot.ctaildom));
+ddom = pot.ddom;
+cheaddom = mysetdiff(pot.cheaddom, node);
+ctaildom = pot.ctaildom;
+dsize = pot.dsize;
+domain = mysetdiff(pot.domain, node);
+
+ns = zeros(1, max(pot.domain));
+ns(pot.ddom) = pot.dsizes;
+ns(pot.cheaddom) = pot.cheadsizes;
+ns(pot.ctaildom) = pot.ctailsizes;
+ctailsizes = ns(ctaildom);
+ctailsize = sum(ctailsizes);
+cheadsizes = ns(cheaddom);
+cheadsize = sum(cheadsizes);
+onodesize = ns(node);
+
+p = zeros(1,dsize);
+A1 = zeros(cheadsize, dsize);
+A2 = zeros(onodesize, dsize);
+C11 = zeros(cheadsize, cheadsize, dsize);
+C12 = zeros(cheadsize, onodesize, dsize);
+C21 = zeros(onodesize, cheadsize, dsize);
+C22 = zeros(onodesize, onodesize, dsize);
+ZM = zeros(onodesize, onodesize);
+
+n1i = block(find_equiv_posns(cheaddom, pot.cheaddom), pot.cheadsizes);
+n2i = block(find_equiv_posns(node, pot.cheaddom), pot.cheadsizes);
+
+indic = 0;
+for i=1:dsize
+    potc = struct(pot.scgpotc{i});
+    p(i) = potc.p;
+    if ~isempty(n1i)
+        A1(:,i) = potc.A(n1i);
+    end 
+    if ~isempty(n2i)
+        A2(:,i) = potc.A(n2i);
+    end
+    C11(:,:,i) = potc.C(n1i, n1i);
+    C12(:,:,i) = potc.C(n1i, n2i);
+    C21(:,:,i) = potc.C(n2i, n1i);
+    C22(:,:,i) = potc.C(n2i, n2i);
+    if isequal(0, C22(:,:,i)) & isequal(evidence{node}, A2(:, i))
+        indic = i;
+    end
+end
+
+np = zeros(1,dsize);
+nA = zeros(cheadsize, dsize);
+nC = zeros(cheadsize, cheadsize, dsize);
+
+if indic
+    np(:) = 0;
+    np(indic) = p(indic);
+    nA = A1;
+    nC = C11;
+else
+    for i=1:dsize
+        if isequal(0, C22(:,:,i))
+            p(i) = 0;
+            nA(:, i) = A1(:, i);
+            nC(:,:,i) = C11(:,:,i);
+        else
+            sq = (y2 - A2(:,i))' * inv(C22(:,:,i)) * (y2 - A2(:,i));
+            ex = exp(-0.5*sq);
+            %np(i) = p(i) * ex / ( (2 * pi)^(-onodesize/2) * sqrt(det(C22(:,:,i))) );
+            np(i) = p(i) * ex / ( (2 * pi)^(onodesize/2) * sqrt(det(C22(:,:,i))) );
+            nA(:,i) = A1(:,i) + C12(:,:,i) * inv(C22(:,:,i)) * (y2 - A2(:,i));
+            tmp1 = C12(:,:,i) * inv(C22(:,:,i)) * C21(:,:,i);
+            nC(:,:,i) = C11(:,:,i) - tmp1;
+        end
+    end
+end 
+
+scpot = cell(1, dsize);
+W = zeros(cheadsize,ctailsize);
+for i=1:dsize
+    scpot{i} = scgcpot(cheadsize, ctailsize, np(i), nA(:,i), W, nC(:,:,i));
+end
+ns(node) = 0;
+newscgpot = scgpot(ddom, cheaddom, ctaildom, ns, scpot);
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_difclq_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_difclq_nodes.m
new file mode 100644
index 00000000..e1cad6c7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_difclq_nodes.m
@@ -0,0 +1,55 @@
+function marginal = marginal_difclq_nodes(engine, query_nodes)
+% MARGINAL_DIFCLQ_NODES get the marginal distribution of nodes which is not in a single clique
+% marginal = marginal_difclq_nodes(engine, query_nodes)
+
+keyboard
+num_clique = length(engine.cliques);
+B = engine.cliques_bitv;
+clqs_containnodes = [];
+for i=1:length(query_nodes)
+    node = query_nodes(i);
+    tnodes = find(all(B(:, node), 2));
+    clqs_containnodes = myunion(clqs_containnodes, tnodes);
+end
+% get all cliques contains query nodes
+
+% get the minimal sub tree in junction which contains these cliques and the node closest to the root of jtree
+[subtree, nroot_node] = min_subtree_conti_nodes(engine.jtree, engine.root, clqs_containnodes);
+if ~mysubset(query_nodes, engine.cliques{nroot_node});
+    % if query nodes is not all memers of the clique closest to the root clique performe push operation
+    engine = push_tree(engine, subtree, query_nodes, nroot_node);
+end
+
+if ~(nroot_node == engine.root)
+    % if the clique closest to the root clique is not the root clique we must direct combine the 
+    % potential with the potential stored in separator toward to root
+    p = parents(engine.jtree, nroot_node);
+    tpot = direct_combine_pots(engine.clpot{nroot_node}, engine.seppot{p, nroot_node});
+else
+    tpot = engine.clpot{nroot_node};
+end
+
+pot = marginalize_pot(tpot, query_nodes);
+marginal = pot_to_marginal(pot);
+marginal.T = normalise(marginal.T);
+
+
+
+function engine = push_tree(engine, tree, query_nodes, inode)
+% PUSH_TREE recursive perform push opeartion on tree
+% engine = push_tree(engine, tree, query_nodes, inode)
+
+cs = children(tree, inode);
+for i = 1:length(cs)
+    node = cs(i);
+    push_tree(engine, tree, query_nodes, node);
+    push_dom = myintersect(engine.cliques{node}, query_nodes);
+    [engine, clqtoroot] = push(engine, node, push_dom);
+end
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..063c2439
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_nodes.m
@@ -0,0 +1,77 @@
+function marginal = marginal_nodes(engine, query, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (stab_cond_gauss)
+% marginal = marginal_nodes(engine, query, add_ev)
+%
+% 'query' must be a singleton set.
+% 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, add_ev = 0; end
+if isempty(engine.evidence)
+    hquery = query;  
+else   
+    hquery = [];
+    for i = query
+        if isempty(engine.evidence{i})
+        hquery = [hquery i];
+        end
+    end
+end
+
+bnet = bnet_from_engine(engine);
+
+nclq = length(engine.cliques);
+clique = 0;
+for i = 1:nclq
+  if mysubset(hquery, engine.cliques{i})
+    pot = struct(engine.clpot{i});
+    %if mysubset(hquery, pot.cheaddom) | mysubset(hquery, pot.ddom)
+    if mysubset(hquery, pot.domain)
+     clique = i;
+      break;
+    end
+  end
+end
+
+if isempty(hquery)
+     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+     % If all requested variables are observed, no query is necessary %
+     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+     marginal.mu = [];
+     marginal.Sigma = [];
+     marginal.T = 1.0;
+     marginal.domain = query;
+else
+    if clique == 0
+        marginal = marginal_difclq_nodes(engine, hquery);
+    else 
+        marginal = marginal_singleclq_nodes(engine, clique, hquery);
+    end
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % Change the format of output, so that it is identical to the %
+    % format obtained by the same request for the junction-tree   %
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    marginal.domain = query;
+    bnet = bnet_from_engine(engine);
+    dquery = myintersect(bnet.dnodes,hquery);
+    ns = bnet.node_sizes(dquery);
+    if length(ns) == 0
+    marginal.T = 1;
+    else
+        if length(ns) == 1
+            ns = [1 ns];
+        end
+        marginal.T = reshape(marginal.T,ns);
+    end
+end
+if add_ev
+  bnet = bnet_from_engine(engine);
+  %marginal = add_ev_to_dmarginal(marginal, engine.evidence, bnet.node_sizes);
+  marginal = add_evidence_to_gmarginal(marginal, engine.evidence, bnet.node_sizes, bnet.cnodes);
+end
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_singleclq_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_singleclq_nodes.m
new file mode 100644
index 00000000..d755617f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_singleclq_nodes.m
@@ -0,0 +1,30 @@
+function marginal = marginal_singleclq_nodes(engine, i, query)
+% MARGINAL_SINGLECLQ_NODES get the marginal distribution of nodes which is in a single clique
+% marginal = marginal_singleclq_nodes(engine, i, query)
+
+pot = struct(engine.clpot{i});
+if isempty(pot.ctaildom)
+    if i ~= engine.root
+        p = parents(engine.jtree, i);
+        tpot = direct_combine_pots(engine.clpot{i}, engine.seppot{p, i});
+    else
+        tpot = engine.clpot{i};
+    end
+    pot = marginalize_pot(tpot, query);
+    
+    marginal = pot_to_marginal(pot);
+    marginal.T = normalise(marginal.T);
+else
+    [engine, clqtoroot] = push(engine, i, query);
+    if clqtoroot == engine.root
+        tpot = engine.clpot{clqtoroot};
+    else
+        p = parents(engine.jtree, clqtoroot);
+        tpot = direct_combine_pots(engine.clpot{clqtoroot}, engine.seppot{p, clqtoroot});
+    end
+    pot = marginalize_pot(tpot, query);
+    
+    marginal = pot_to_marginal(pot);
+    marginal.T = normalise(marginal.T);
+end
+                
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/problems.txt b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/problems.txt
new file mode 100644
index 00000000..fa7c6be8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/problems.txt
@@ -0,0 +1,76 @@
+PROBLEMS WITH STAB_COND_GAUSS_INF_ENGINE
+
+
+- enter_evidence always returns ll=0
+  (I set ll=0 since it is not computed)
+
+- fails on scg_3node, probably because the engine needs to be
+re-initialized every time before enter_evidence is called, not just
+when the engine is constructed.
+
+??? Error using ==> assert
+assertion violated: 
+
+K>> dbstack
+dbstack
+> In /home/eecs/murphyk/matlab/BNT/HMM/assert.m at line 9
+  In /home/eecs/murphyk/matlab/BNT/examples/static/SCG/scg_3node.m at line 45
+
+
+
+- crashes on scg3
+
+Error in ==> /home/eecs/murphyk/matlab/BNT/inference/static/@stab_cond_gauss_inf_engine/stab_cond_gauss_inf_engine.m
+On line 77  ==>       clpot{cindex} = direct_combine_pots(pot{n}, clpot{cindex});
+
+K>> dbstack
+dbstack
+> In /home/eecs/murphyk/matlab/BNT/inference/static/@stab_cond_gauss_inf_engine/stab_cond_gauss_inf_engine.m at line 77
+  In /home/eecs/murphyk/matlab/BNT/examples/static/SCG/scg3.m at line 41
+K>> 
+
+
+
+
+
+- fails on scg1 and scg2
+
+Warning: One or more output arguments not assigned during call to 'min_subtree_conti_nodes (nearsest_node2)'.
+Warning in ==> /home/eecs/murphyk/matlab/BNT/graph/min_subtree_conti_nodes.m (nearsest_node2)
+On line 60  ==>     nea_node = nearsest_node2(tree, nodes, n);
+
+K>> dbstack
+dbstack
+> In /home/eecs/murphyk/matlab/BNT/graph/min_subtree_conti_nodes.m (nearsest_node2) at line 60
+  In /home/eecs/murphyk/matlab/BNT/graph/min_subtree_conti_nodes.m (nearest_node) at line 50
+  In /home/eecs/murphyk/matlab/BNT/graph/min_subtree_conti_nodes.m at line 11
+  In /home/eecs/murphyk/matlab/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_difclq_nodes.m at line 17
+  In /home/eecs/murphyk/matlab/BNT/inference/static/@stab_cond_gauss_inf_engine/marginal_nodes.m at line 23
+  In /home/eecs/murphyk/matlab/BNT/examples/static/SCG/scg1.m at line 42
+
+
+
+
+
+- This code fragment, from BNT/graph/min_subtree_conti_nodes, is clearly redundant
+
+function nea_node = nearest_node(tree, root, nodes)
+%get the nearest node to the root in the tree
+nea_node = nearsest_node2(tree, nodes, root);
+
+function nea_node = nearsest_node2(tree, nodes, inode)
+if myismember(inode, nodes)
+    nea_node = inode;
+    return;
+end
+cs = children(tree, inode);
+for i = 1:length(cs)
+    n = cs(i);
+    nea_node = nearsest_node2(tree, nodes, n);
+end
+    
+
+- Some names are badly chosen. 'nearsest' is a mis-spelling. 'min_subtree_conti_nodes' should be
+'min_subtree_containing_nodes' or 'min_subtree_con_nodes'.
+
+- In general, the code needs some heavy polishing.
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push.m
new file mode 100644
index 00000000..193bf722
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push.m
@@ -0,0 +1,38 @@
+function [engine, clqtoroot] = push(engine, clq, pushdom)
+%PUSH_POT push the variables in putshdom which is subset of clq to the clique toword the root and get new engine
+%pushdom is pushed variables set
+%clq is the index of the clique that pushdom belongs to
+
+clqdom = engine.cliques{clq};
+assert( mysubset(pushdom, clqdom));
+clqtoroot = parents(engine.jtree, clq);
+%sepdom = engine.separator{clq, clqtoroot};
+sepdom = engine.separator{clqtoroot, clq};
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Calculate the strong marginal of the union of pushdom and and the separatordomain and  %
+% the corresponding complement                                                           %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%[margpot, comppot] = complement_pot(engine.clpot{clq}, pushdom);
+newsepdom = myunion(pushdom,sepdom);
+[margpot,comppot] = complement_pot(engine.clpot{clq}, newsepdom);
+engine.clpot{clqtoroot} = direct_combine_pots(engine.clpot{clqtoroot}, margpot);
+engine.clpot{clq} = comppot;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Calculation of the new separator and separatorpotential of the junction tree %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+engine.seppot{clqtoroot, clq} = direct_combine_pots(engine.seppot{clqtoroot, clq}, margpot);
+engine.separator{clqtoroot, clq} = myunion(engine.separator{clqtoroot, clq}, pushdom);
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Add pushdomain to the clique towards the root %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
+engine.cliques{clqtoroot} = myunion(engine.cliques{clqtoroot}, pushdom);
+
+num_cliques = length(engine.cliques);
+B = sparse(num_cliques, 1);
+for i=1:num_cliques
+  B(i, engine.cliques{i}) = 1;
+end
+engine.cliques_bitv = B;
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push_pot_toclique.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push_pot_toclique.m
new file mode 100644
index 00000000..4bcd0ed0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/push_pot_toclique.m
@@ -0,0 +1,7 @@
+function engine = push_pot_toclique(engine, clqtarget, clq, nodes)
+% PUSH_POT push the variables in putshdom which is subset of clq to the target clique toword the root and get new engine
+% engine = push_pot_toclique(engine, clqtarget, clq, nodes)
+[engine, clqtoroot] = push_pot(engine, clq, nodes)
+while clqtoroot ~= clqtarget
+    [engine, clqtoroot] = push_pot(engine, clqtoroot, nodes)
+end
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/stab_cond_gauss_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/stab_cond_gauss_inf_engine.m
new file mode 100644
index 00000000..42c47c6a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@stab_cond_gauss_inf_engine/stab_cond_gauss_inf_engine.m
@@ -0,0 +1,178 @@
+function engine = stab_cond_gauss_inf_engine(bnet)
+% STAB_COND_GAUSS_INF_ENGINE Junction tree using stable CG potentials
+% engine = cond_gauss_inf_engine(bnet)
+% 
+% This class was written by Shan Huang (shan.huang@intel.com) 2001
+% and fixed by Rainer Deventer deventer@informatik.uni-erlangen.de March 2003
+N = length(bnet.dag);
+clusters = {};
+root = N;
+stages = { 1:N };
+onodes = [];
+engine = init_fields;
+engine.evidence = [];
+engine = class(engine, 'stab_cond_gauss_inf_engine', inf_engine(bnet));
+
+ns = bnet.node_sizes(:);
+ns(onodes) = 1; % observed nodes have only 1 possible value
+
+%[engine.jtree, dummy, engine.cliques, B, w, elim_order, moral_edges, fill_in_edges, strong] = ...
+%    dag_to_jtree(bnet, onodes, stages, clusters);
+
+
+partial_order = determine_elim_constraints(bnet, onodes);
+strong = ~isempty(partial_order);
+stages = {};
+clusters = {};
+[engine.jtree, dummy_root, engine.cliques, B, w, elim_order] = 
+    graph_to_jtree(moralize(bnet.dag), ns, partial_order, stages, clusters);
+
+    
+engine.cliques_bitv = B;
+engine.clique_weight = w;
+C = length(engine.cliques);
+engine.clpot = cell(1,C);
+
+% A node can be a member of many cliques, but is assigned to exactly one, to avoid
+% double-counting its CPD. We assign node i to clique c if c is the "lightest" clique that
+% contains i's family, so it can accomodate its CPD.
+
+engine.clq_ass_to_node = zeros(1, N);
+num_cliques = length(engine.cliques);
+for i=1:N
+  clqs_containing_family = find(all(B(:,family(bnet.dag, i)), 2)); % all selected columns must be 1
+  c = clqs_containing_family(argmin(w(clqs_containing_family)));  
+  engine.clq_ass_to_node(i) = c; 
+end
+
+% Compute the separators between connected cliques.
+[is,js] = find(engine.jtree > 0);
+engine.separator = cell(num_cliques, num_cliques);
+for k=1:length(is)
+  i = is(k); j = js(k);
+  engine.separator{i,j} = find(B(i,:) & B(j,:)); % intersect(cliques{i}, cliques{j});
+end
+%keyboard;
+engine.seppot = cell(C,C);
+
+pot_type = 'scg';
+check_for_cd_arcs([], bnet.cnodes, bnet.dag);
+
+% Make the jtree rooted, so there is a fixed message passing order.
+if strong
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  % Start the search for the strong root at the clique with the  %
+  % highest number.                                              %
+  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+  root = length(engine.cliques);
+  root_found = 0;
+  
+  while ((~root_found) & (root >= 1))
+      root_found = test_strong_root(engine.jtree,engine.cliques,bnet.dnodes,root);
+      if ~root_found
+          root = root - 1;
+      end
+  end
+  assert(root > 0)
+  engine.root = root;
+  % the last clique is guaranteed to be a strong root
+  %engine.root = length(engine.cliques);
+else
+  % jtree_dbn_inf_engine requires the root to contain the interface.
+  % This may conflict with the strong root requirement! *********** BUG *************
+  engine.root = clq_containing_nodes(engine, root);
+  if engine.root <= 0
+    error(['no clique contains ' num2str(root)]);
+  end
+end  
+
+[engine.jtree, engine.preorder, engine.postorder] = mk_rooted_tree(engine.jtree, engine.root);
+
+% Evaluate CPDs with evidence, and convert to potentials  
+pot = cell(1, N);
+inited = zeros(1, C);
+clpot = cell(1, C);
+evidence = cell(1, N);
+for n=1:N
+  fam = family(bnet.dag, n);
+  e = bnet.equiv_class(n);
+  %pot{n} = CPD_to_scgpot(bnet.CPD{e}, fam, ns, bnet.cnodes, evidence);
+  pot{n} = convert_to_pot(bnet.CPD{e}, pot_type, fam(:), evidence);
+  cindex = engine.clq_ass_to_node(n);
+  if inited(cindex)
+      clpot{cindex} = direct_combine_pots(pot{n}, clpot{cindex});
+  else
+      clpot{cindex} = pot{n};
+      inited(cindex) = 1;
+  end
+end
+
+for i=1:C
+    if inited(i) == 0
+        clpot{i} = scgpot([], [], [], []);
+    end
+end
+
+seppot = cell(C, C);
+% separators are is not need to initialize
+
+% collect to root (node to parents)
+% Unlike the HUGIN architecture the complements are stored in the cliques during COLLECT 
+% and the separators are not playing a specific role during this process
+for n=engine.postorder(1:end-1)
+  for p=parents(engine.jtree, n)
+    if ~isempty(engine.separator{p,n})
+      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+      % The empty case might happen for unlinked nodes, i.e. the DAG is not %
+      % a single tree, but a forest                                           %
+      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+      [margpot, comppot] = complement_pot(clpot{n}, engine.separator{p,n});
+      clpot{n} = comppot;
+      clpot{p} = combine_pots(clpot{p}, margpot);
+    end
+  end
+end
+
+% distribute message from root
+% We have not to store the weak clique marginals and keep the original complement potentials. 
+% This is a minor variation of HUGIN architecture.
+temppot = clpot;
+for n=engine.preorder
+  for c=children(engine.jtree, n)
+    seppot{n,c} = marginalize_pot(temppot{n}, engine.separator{n,c});
+    temppot{c} = direct_combine_pots(temppot{c}, seppot{n,c});
+  end
+end
+
+engine.clpot = clpot;
+engine.seppot = seppot;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% init_fields()                  %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+function engine = init_fields()
+
+engine.evidence = [];
+engine.jtree = [];
+engine.cliques = [];
+engine.cliques_bitv = [];
+engine.clique_weight = [];
+engine.preorder = [];
+engine.postorder = [];
+engine.root = []; 
+engine.clq_ass_to_node = [];
+engine.separator = [];
+engine.clpot =[];
+engine.seppot = [];
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/CVS/Entries
new file mode 100644
index 00000000..0cfdeafe
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/CVS/Entries
@@ -0,0 +1,5 @@
+/enter_evidence.m/1.1.1.1/Wed Jun 19 22:05:04 2002//
+/find_mpe.m/1.1.1.1/Wed Jun 19 22:11:42 2002//
+/marginal_nodes.m/1.1.1.1/Thu Sep 30 03:09:00 2004//
+/var_elim_inf_engine.m/1.1.1.1/Wed Jun 19 22:04:50 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/CVS/Repository
new file mode 100644
index 00000000..8595410d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static/@var_elim_inf_engine
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/enter_evidence.m b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/enter_evidence.m
new file mode 100644
index 00000000..ed3fbe19
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/enter_evidence.m
@@ -0,0 +1,12 @@
+function [engine, loglik] = enter_evidence(engine, evidence, varargin)
+% ENTER_EVIDENCE Add the specified evidence to the network (var_elim)
+% [engine, loglik] = enter_evidence(engine, evidence, ...)
+%
+% evidence{i} = [] if if X(i) is hidden, and otherwise contains its observed value (scalar or column vector)
+
+% we could pre-process the evidence here, to prevent repeated work, but we don't.
+engine.evidence = evidence;
+
+if nargout == 2
+  [m, loglik] = marginal_nodes(engine, [1]);
+end
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/find_mpe.m b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/find_mpe.m
new file mode 100644
index 00000000..63be5625
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/find_mpe.m
@@ -0,0 +1,163 @@
+function mpe = find_mpe(engine, new_evidence, max_over)
+% FIND_MPE Find the most probable explanation of the data (assignment to the hidden nodes)
+% function mpe = find_mpe(engine, evidence, order)
+%
+% PURPOSE:
+%       CALC_MPE Computes the most probable explanation to the network nodes
+%       given the evidence.
+%       
+%       [mpe, ll] = calc_mpe(engine, new_evidence, max_over)
+%
+% INPUT:
+%       bnet  - the bayesian network
+%       new_evidence - optional, if specified - evidence to be incorporated [cell(1,n)]
+%       max_over - optional, if specified determines the variable elimination order [1:n]
+%
+% OUTPUT:
+%       mpe - the MPE assignmet for the net variables (or [] if no satisfying assignment)
+%       ll - log assignment probability.
+%
+% Notes:
+% 1. Adapted from '@var_elim_inf_engine\marginal_nodes' for MPE by Ron Zohar, 8/7/01
+% 2. Only discrete potentials are supported at this time.
+% 3. Complexity: O(nw*) where n is the number of nodes and w* is the induced tree width.
+% 4. Implementation based on:
+%  - R. Dechter, "Bucket Elimination: A Unifying Framework for Probabilistic Inference", 
+%                 UA1 96, pp. 211-219.
+
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes;
+n = length(bnet.dag);
+evidence = cell(1,n);
+if (nargin<2)
+    new_evidence = evidence;
+end
+
+onodes = find(~isemptycell(new_evidence));  % observed nodes
+hnodes = find(isemptycell(new_evidence));  % hidden nodes
+pot_type = determine_pot_type(bnet, onodes);
+
+if pot_type ~= 'd'
+  error('only disrete potentials supported at this time')    
+end
+
+for i=1:n
+  fam = family(bnet.dag, i);
+  CPT{i} = convert_to_pot(bnet.CPD{bnet.equiv_class(i)}, pot_type, fam(:), evidence);        
+end 
+
+% handle observed nodes: set impossible cases' probability to zero
+% rather than prun matrix (this makes backtracking easier)
+
+for ii=onodes
+  lIdx = 1:ns(ii);
+  lIdx = setdiff(lIdx, new_evidence{ii});
+  
+  sCPT=struct(CPT{ii});  % violate object privacy
+  
+  sargs = '';
+  for jj=1:(length(sCPT.domain)-1)
+    sargs = [sargs, ':,']; 
+  end        
+  for jj=lIdx
+    eval(['sCPT.T(', sargs, num2str(jj), ')=0;']);
+  end
+  CPT{ii}=dpot(sCPT.domain, sCPT.sizes, sCPT.T);        
+end
+
+B = cell(1,n); 
+for b=1:n
+  B{b} = mk_initial_pot(pot_type, [], [], [], []);
+end
+
+if (nargin<3)
+  max_over = (1:n);
+end   
+order = max_over; % no attempt to optimize this
+
+
+% Initialize the buckets with the CPDs assigned to them
+for i=1:n
+  b = bucket_num(domain_pot(CPT{i}), order);
+  B{b} = multiply_pots(B{b}, CPT{i});
+end
+
+% Do backward phase
+max_over = max_over(length(max_over):-1:1); % reverse
+maximize = 1;
+for i=max_over(1:end-1)        
+  % max-ing over variable i which occurs in bucket j
+  j = bucket_num(i, order);
+  rest = mysetdiff(domain_pot(B{j}), i);
+  %temp = marginalize_pot_max(B{j}, rest);
+  temp = marginalize_pot(B{j}, rest, maximize);
+  b = bucket_num(domain_pot(temp), order);
+  %        fprintf('maxing over bucket %d (var %d), putting result into bucket %d\n', j, i, b);
+  sB=struct(B{b});  % violate object privacy
+  if ~isempty(sB.domain)
+    B{b} = multiply_pots(B{b}, temp);
+  else
+    B{b} = temp;
+  end
+end
+result = B{1};
+marginal = pot_to_marginal(result);
+[prob, mpe] = max(marginal.T);
+
+% handle impossible cases
+if ~(prob>0)
+  mpe = [];    
+  ll = -inf;
+  %warning('evidence has zero probability')
+  return
+end
+
+ll = log(prob);
+
+% Do forward phase    
+for ii=2:n
+  marginal = pot_to_marginal(B{ii});
+  mpeidx = [];
+  for jj=order(1:length(mpe))
+    %assert(ismember(jj, marginal.domain)) %%% bug
+    temp = find_equiv_posns(jj, marginal.domain);
+    mpeidx = [mpeidx, temp] ;
+    if isempty(temp)
+      mpeidx = [mpeidx, Inf] ;
+    end
+  end
+  [mpeidxsorted sortedtompe] = sort(mpeidx) ;
+  
+  % maximize the matrix obtained from assigning values from previous buckets.
+  % this is done by building a string and using eval.
+  
+  kk=1;
+  sargs = '(';
+  for jj=1:length(marginal.domain)
+    if (jj~=1)
+      sargs = [sargs, ','];
+    end
+    if (mpeidxsorted(kk)==jj)
+      sargs = [sargs, num2str(mpe(sortedtompe(kk)))];
+      if (kk<length(mpe))
+	kk = kk+1 ;
+      end
+    else
+      sargs = [sargs, ':'];
+    end
+  end
+  sargs = [sargs, ')'] ;   
+  eval(['[val, loc] = max(marginal.T', sargs, ');'])        
+  mpe = [mpe loc];
+end     
+[I,J] = sort(order);
+mpe = mpe(J);
+
+mpe = num2cell(mpe);
+
+%%%%%%%%%
+
+function b = bucket_num(domain, order)
+
+b = max(find_equiv_posns(domain, order));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/marginal_nodes.m b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/marginal_nodes.m
new file mode 100644
index 00000000..98551cb0
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/marginal_nodes.m
@@ -0,0 +1,79 @@
+function [marginal, loglik] = marginal_nodes(engine, query, add_ev)
+% MARGINAL_NODES Compute the marginal on the specified query nodes (var_elim)
+% [marginal, loglik] = marginal_nodes(engine, query)
+
+if nargin < 3, add_ev = 0; end
+
+assert(length(query)>=1);
+
+evidence = engine.evidence;
+
+bnet = bnet_from_engine(engine);
+ns = bnet.node_sizes;
+n = length(bnet.dag);
+
+onodes = find(~isemptycell(evidence));
+hnodes = find(isemptycell(evidence));
+pot_type = determine_pot_type(bnet, onodes);
+
+% Fold the evidence into the CPTs - this could be done in 'enter_evidence'
+CPT = cell(1,n);
+for i=1:n
+  fam = family(bnet.dag, i);
+  CPT{i} = convert_to_pot(bnet.CPD{bnet.equiv_class(i)}, pot_type, fam(:), evidence);
+end
+
+
+
+sum_over = mysetdiff(1:n, query);
+order = [query sum_over]; % no attempt to optimize this
+
+% Initialize the buckets with the product of the CPTs assigned to them
+B = cell(1,n+1); 
+for b=1:n+1
+  B{b} = mk_initial_pot(pot_type, [], [], [], []);
+end
+for i=1:n
+  b = bucket_num(domain_pot(CPT{i}), order);
+  B{b} = multiply_pots(B{b}, CPT{i});
+end
+
+% Do the marginalization
+sum_over = sum_over(length(sum_over):-1:1); % reverse
+for i=sum_over(:)'
+  % summing over variable i which occurs in bucket j
+  j = bucket_num(i, order);
+  rest = mysetdiff(domain_pot(B{j}), i);
+  % minka
+  if ~isempty(rest)
+    temp = marginalize_pot(B{j}, rest);
+    b = bucket_num(domain_pot(temp), order);
+    %fprintf('summing over bucket %d (var %d), putting result into bucket %d\n', j, i, b);
+    B{b} = multiply_pots(B{b}, temp);
+  end
+end
+
+% Combine all the remaining buckets into one
+result = B{1};
+for i=2:length(query)
+  if ~isempty(domain_pot(B{i}))
+    result = multiply_pots(result, B{i});
+  end
+end
+[result, loglik] = normalize_pot(result);
+
+
+marginal = pot_to_marginal(result);
+% minka: from jtree_inf_engine
+if add_ev
+  bnet = bnet_from_engine(engine);
+  %marginal = add_ev_to_dmarginal(marginal, engine.evidence, bnet.node_sizes);
+  marginal = add_evidence_to_gmarginal(marginal, engine.evidence, bnet.node_sizes, bnet.cnodes);
+end
+
+%%%%%%%%%
+
+function b = bucket_num(domain, order)
+
+b = max(find_equiv_posns(domain, order));
+
diff --git a/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/var_elim_inf_engine.m b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/var_elim_inf_engine.m
new file mode 100644
index 00000000..dd3c940a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/@var_elim_inf_engine/var_elim_inf_engine.m
@@ -0,0 +1,15 @@
+function engine = var_elim_inf_engine(bnet, varargin)
+% VAR_ELIM_INF_ENGINE Variable elimination inference engine
+% engine = var_elim_inf_engine(bnet)
+%
+% For details on variable elimination, see
+% - R. Dechter, "Bucket Elimination: A Unifying Framework for Probabilistic Inference", UA1 96, pp. 211-219. 
+% - Z. Li and B. D'Ambrosio, "Efficient inference in Bayes networks as a combinatorial
+%     optimization problem", Intl. J. Approximate Reasoning, 11(1):55-81, 1994
+% - R. McEliece and S. M. Aji, "The Generalized Distributive Law", IEEE Trans. Inform. Theory, 46(2), 2000
+
+
+% This is where we will store the results between enter_evidence and marginal_nodes
+engine.evidence = [];
+
+engine = class(engine, 'var_elim_inf_engine', inf_engine(bnet));
diff --git a/sourcecodes/bnt-master/BNT/inference/static/CVS/Entries b/sourcecodes/bnt-master/BNT/inference/static/CVS/Entries
new file mode 100644
index 00000000..2108bb8c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/CVS/Entries
@@ -0,0 +1,2 @@
+/dummy/1.1.1.1/Sat Jan 18 22:22:46 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/inference/static/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/inference/static/CVS/Entries.Log
new file mode 100644
index 00000000..844f5ce7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/CVS/Entries.Log
@@ -0,0 +1,17 @@
+A D/@belprop_fg_inf_engine////
+A D/@belprop_inf_engine////
+A D/@belprop_mrf2_inf_engine////
+A D/@cond_gauss_inf_engine////
+A D/@enumerative_inf_engine////
+A D/@gaussian_inf_engine////
+A D/@gibbs_sampling_inf_engine////
+A D/@global_joint_inf_engine////
+A D/@jtree_inf_engine////
+A D/@jtree_limid_inf_engine////
+A D/@jtree_mnet_inf_engine////
+A D/@jtree_sparse_inf_engine////
+A D/@likelihood_weighting_inf_engine////
+A D/@pearl_inf_engine////
+A D/@quickscore_inf_engine////
+A D/@stab_cond_gauss_inf_engine////
+A D/@var_elim_inf_engine////
diff --git a/sourcecodes/bnt-master/BNT/inference/static/CVS/Repository b/sourcecodes/bnt-master/BNT/inference/static/CVS/Repository
new file mode 100644
index 00000000..347cab89
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/inference/static
diff --git a/sourcecodes/bnt-master/BNT/inference/static/CVS/Root b/sourcecodes/bnt-master/BNT/inference/static/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/inference/static/dummy b/sourcecodes/bnt-master/BNT/inference/static/dummy
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/inference/static/dummy
diff --git a/sourcecodes/bnt-master/BNT/installC_BNT.m b/sourcecodes/bnt-master/BNT/installC_BNT.m
new file mode 100644
index 00000000..5613598c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/installC_BNT.m
@@ -0,0 +1,32 @@
+BNT_HOME = '/home/ai2/murphyk/matlab/FullBNT'; % edit this
+
+d = fullfile(BNT_HOME, 'BNT');
+%PC = (strncmp(computer,'PC',2));
+
+cd(sprintf('%s/potentials/Tables', d))
+mex marg_table.c % used by @dpot/marginalize_pot.m
+mex marg_sparse_table.c %used by sparse jtree
+mex mult_by_table.c
+mex mult_by_sparse_table.c
+mex divide_by_table.c
+mex divide_by_sparse_table.c
+mex rep_mult.c
+
+% Written by Wei Hu
+cd(sprintf('%s/CPDs/@discrete_CPD', d))
+mex convert_to_sparse_table.c
+
+% Written by Wei Hu
+cd(sprintf('%s/inference/static/@jtree_sparse_inf_engine', d))
+mex init_pot.c
+mex collect_evidence.c
+mex distribute_evidence.c
+
+% written by Bhaskara Marthi 
+cd(sprintf('%s/inference/static/@gibbs_sampling_inf_engine/private', d))
+mex compute_posterior.c
+mex get_slice_dbn.c
+mex sample_single_discrete.c
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/installC_graph.m b/sourcecodes/bnt-master/BNT/installC_graph.m
new file mode 100644
index 00000000..56d1bb3e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/installC_graph.m
@@ -0,0 +1,16 @@
+% These C functions were written by Ilya Shpitser.
+
+if isunix
+  mex -c elim.c;
+  mex -c cell.c;
+  mex -c map.c;
+  mex -DUNIX  best_first_elim_order.c  elim.o  cell.o  map.o;
+  mex -DUNIX  triangulate.c  elim.o  cell.o  map.o;
+else
+  mex -c elim.c;
+  mex -c cell.c;
+  mex -c map.c;
+  mex  best_first_elim_order.c  elim.obj  cell.obj  map.obj;
+  mex  triangulate.c  elim.obj  cell.obj  map.obj;
+end
+
diff --git a/sourcecodes/bnt-master/BNT/learning/CVS/Entries b/sourcecodes/bnt-master/BNT/learning/CVS/Entries
new file mode 100644
index 00000000..02e90b7f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/CVS/Entries
@@ -0,0 +1,23 @@
+/CovMat.m/1.1.1.1/Sun Jul 28 23:09:42 2002//
+/bayes_update_params.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/bic_score_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/compute_cooling_schedule.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/dirichlet_score_family.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/kpm_learn_struct_mcmc.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/learn_params.m/1.1.1.1/Thu Jun 10 01:28:08 2004//
+/learn_params_dbn.m/1.1.1.1/Sun Feb  2 00:23:38 2003//
+/learn_params_dbn_em.m/1.1.1.1/Mon Aug 18 21:50:34 2003//
+/learn_params_em.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/learn_struct_K2.m/1.1.1.1/Thu Sep 26 08:39:16 2002//
+/learn_struct_dbn_reveal.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/learn_struct_mcmc.m/1.1.1.1/Fri Sep  5 14:06:40 2003//
+/learn_struct_pdag_ic_star.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/learn_struct_pdag_pc.m/1.2/Mon Feb 12 01:15:13 2007//
+/learn_struct_pdag_pc_constrain.m/1.1.1.1/Sun Jul 28 23:09:38 2002//
+/mcmc_sample_to_hist.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/mk_schedule.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/mk_tetrad_data_file.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/score_dags.m/1.1.1.1/Mon Apr  4 01:39:46 2005//
+/score_dags_old.m/1.1.1.1/Wed May 29 15:59:56 2002//
+/score_family.m/1.1.1.1/Thu Jun 10 01:33:14 2004//
+D
diff --git a/sourcecodes/bnt-master/BNT/learning/CVS/Repository b/sourcecodes/bnt-master/BNT/learning/CVS/Repository
new file mode 100644
index 00000000..ed7d464f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/learning
diff --git a/sourcecodes/bnt-master/BNT/learning/CVS/Root b/sourcecodes/bnt-master/BNT/learning/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/learning/CovMat.m b/sourcecodes/bnt-master/BNT/learning/CovMat.m
new file mode 100644
index 00000000..9b788172
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/CovMat.m
@@ -0,0 +1,39 @@
+function [CovMatrix, obs, varfields] = CovMat(filename,row_cols)
+%[CovMatrix, obs, varfields] = CovMat(filename,row_cols)
+%% generates a Covariance Matrix from a file of data consisting of N columns of M data rows
+%%      filename        string name (with path and extension) of file to open
+%%      row_cols        Number_of_converstions_per_row  (turns into  [3 inf])
+%% Return
+%%      CovMatrix       Covariance matrix
+%%      obs             Number of observations read in
+%%      varfields       Labels of the variables see filename structure below
+%%
+%%  Filename structure: 
+%%      Comma separated, starting with the variable labels, then the data in rows.
+%%    filename test.txt consists of:
+%%
+%%      Earthquake,Burglar,Radio,Alarm,Call
+%%      1,2,3,4,5
+%%      11,22,33,44,55
+%%      . . .
+%%
+%% Example call: 
+%%  [cvmat numdat lables] = CovMat('test.txt',5);
+%%
+%%      Returns Covariance matrix, number of date rows and variable field names
+%% Gary R. Bradski   7/2002
+
+fmtstr = '%f';
+for i = 2:row_cols
+    fmtstr = strcat(fmtstr,',%f');
+end
+
+%% load data
+fidCov = fopen(filename,'r');
+
+varfields = fgetl(fidCov);
+Corx = fscanf(fidCov,fmtstr,[row_cols inf]);
+Corx= Corx';
+[obs bla] = size(Corx);
+CovMatrix = cov(Corx); 
+fclose(fidCov);
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/learning/bayes_update_params.m b/sourcecodes/bnt-master/BNT/learning/bayes_update_params.m
new file mode 100644
index 00000000..4a0a28f4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/bayes_update_params.m
@@ -0,0 +1,38 @@
+function bnet = bayes_update_params(bnet, cases, clamped)
+% BAYES_UPDATE_PARAMS Bayesian parameter updating given completely observed data
+% bnet = bayes_update_params(bnet, cases, clamped)
+%
+% If there is a missing data, you must use EM.
+% cases(i,m) is the value assigned to node i in case m (this can also be a cell array).
+% clamped(i,m) = 1 if node i was set by intervention in case m (default: clamped = zeros).
+% Clamped nodes are not updated.
+% If there is a single case, clamped is a list of the clamped nodes, not a bit vector.
+
+
+%if iscell(cases), usecell = 1; else usecell = 0; end
+
+n = length(bnet.dag);
+ncases = size(cases, 2);
+if n ~= size(cases, 1)
+  error('data must be of size nnodes * ncases');
+end
+
+if ncases == 1 % clamped is a list of nodes
+  if nargin < 3, clamped = []; end
+  clamp_set = clamped;
+  clamped = zeros(n,1);
+  clamped(clamp_set) = 1;
+else % each row of clamped is a bit vector
+  if nargin < 3, clamped = zeros(n,ncases); end
+end
+
+for i=1:n
+  e = bnet.equiv_class(i);
+  if adjustable_CPD(bnet.CPD{e})
+    u = find(clamped(i,:)==0);
+    ps = parents(bnet.dag, i);
+    bnet.CPD{e} = bayes_update_params(bnet.CPD{e}, cases(i,u), cases(ps,u));
+  end
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/learning/bic_score_family.m b/sourcecodes/bnt-master/BNT/learning/bic_score_family.m
new file mode 100644
index 00000000..f3725ecb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/bic_score_family.m
@@ -0,0 +1,23 @@
+function [S, LL] = bic_score(counts, CPT, ncases)
+% BIC_SCORE Bayesian Information Criterion score for a single family
+% [S, LL] = bic_score(counts, CPT, ncases)
+%
+% S is a large sample approximation to the log marginal likelihood,
+% which can be computed using dirichlet_score.
+%
+% S  = \log [ prod_j _prod_k theta_ijk ^ N_ijk ]  - 0.5*d*log(ncases) 
+% where counts encode N_ijk, theta_ijk is the MLE comptued from counts,
+% and d is the num of free parameters.
+
+%CPT = mk_stochastic(counts);
+tiny = exp(-700);
+LL = sum(log(CPT(:)  + tiny) .* counts(:));
+% CPT(i) = 0 iff counts(i) = 0 so it is okay to add tiny
+
+ns = mysize(counts);
+ns_ps = ns(1:end-1);
+ns_self = ns(end);
+nparams = prod([ns_ps (ns_self-1)]);
+% sum-to-1 constraint reduces the effective num. vals of the node by 1
+
+S = LL - 0.5*nparams*log(ncases);
diff --git a/sourcecodes/bnt-master/BNT/learning/compute_cooling_schedule.m b/sourcecodes/bnt-master/BNT/learning/compute_cooling_schedule.m
new file mode 100644
index 00000000..397c2f8c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/compute_cooling_schedule.m
@@ -0,0 +1,13 @@
+function temp_schedule = compute_cooling_schedule(init_temp, final_temp, anneal_rate)
+
+temp_schedule = [];
+i = 1;
+temp_schedule(i)=init_temp;
+while temp_schedule(i) > final_temp
+  i = i + 1;
+  temp_schedule(i)=temp_schedule(i-1)*anneal_rate;
+end
+
+  
+
+
diff --git a/sourcecodes/bnt-master/BNT/learning/dirichlet_score_family.m b/sourcecodes/bnt-master/BNT/learning/dirichlet_score_family.m
new file mode 100644
index 00000000..abfb046b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/dirichlet_score_family.m
@@ -0,0 +1,42 @@
+function LL = dirichlet_score_family(counts, prior)
+% DIRICHLET_SCORE Compute the log marginal likelihood of a single family
+% LL = dirichlet_score(counts, prior)
+%
+% counts(a, b, ..., z) is the number of times parent 1 = a, parent 2 = b, ..., child = z
+% prior is an optional multidimensional array of the same shape as counts.
+% It defaults to a uniform prior.
+% 
+% We marginalize out the parameters:
+% LL = log \int \prod_m P(x(i,m) | x(Pa_i,m), theta_i) P(theta_i) d(theta_i)
+
+
+% LL = log[  prod_j gamma(alpha_ij)/gamma(alpha_ij + N_ij)  *
+%            prod_k gamma(alpha_ijk + N_ijk)/gamma(alpha_ijk)  ]
+% Call the prod_k term U and the prod_j term  V.
+% We reshape all quantities into (j,k) matrices
+% This formula was first derived by Cooper and Herskovits, 1992.
+% See also "Learning Bayesian Networks", Heckerman, Geiger and Chickering, MLJ 95.
+
+ns = mysize(counts);
+ns_ps = ns(1:end-1);
+ns_self = ns(end);
+
+if nargin < 2, prior = normalise(myones(ns)); end
+
+
+if 1
+  prior = reshape(prior(:), [prod(ns_ps) ns_self]);
+  counts = reshape(counts,  [prod(ns_ps) ns_self]);
+  %U = prod(gamma(prior + counts) ./ gamma(prior), 2); % mult over k
+  LU = sum(gammaln(prior + counts) - gammaln(prior), 2);
+  alpha_ij = sum(prior, 2); % sum over k
+  N_ij = sum(counts, 2);
+  %V = gamma(alpha_ij) ./ gamma(alpha_ij + N_ij);
+  LV = gammaln(alpha_ij) - gammaln(alpha_ij + N_ij);
+  %L = prod(U .* V);
+  LL = sum(LU + LV);
+else
+  CPT = mk_stochastic(prior + counts);
+  LL = sum(log(CPT(:) .* counts(:)));
+end
+
diff --git a/sourcecodes/bnt-master/BNT/learning/kpm_learn_struct_mcmc.m b/sourcecodes/bnt-master/BNT/learning/kpm_learn_struct_mcmc.m
new file mode 100644
index 00000000..b73910d2
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/kpm_learn_struct_mcmc.m
@@ -0,0 +1,265 @@
+function [sampled_graphs, accept_ratio, num_edges] = learn_struct_mcmc(data, ns, varargin)
+% LEARN_STRUCT_MCMC  Monte Carla Markov Chain search over DAGs assuming fully observed data
+% [sampled_graphs, accept_ratio, num_edges] = learn_struct_mcmc(data, ns, ...)
+% 
+% data(i,m) is the value of node i in case m.
+% ns(i) is the number of discrete values node i can take on.
+%
+% sampled_graphs{m} is the m'th sampled graph.
+% accept_ratio(t) = acceptance ratio at iteration t
+% num_edges(t) = number of edges in model at iteration t
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% scoring_fn - 'bayesian' or 'bic' [ 'bayesian' ]
+%              Currently, only networks with all tabular nodes support Bayesian scoring.
+% type       - type{i} is the type of CPD to use for node i, where the type is a string
+%              of the form 'tabular', 'noisy_or', 'gaussian', etc. [ all cells contain 'tabular' ]
+% params     - params{i} contains optional arguments passed to the CPD constructor for node i,
+%              or [] if none.  [ all cells contain {'prior', 1}, meaning use uniform Dirichlet priors ]
+% discrete   - the list of discrete nodes [ 1:N ]
+% clamped    - clamped(i,m) = 1 if node i is clamped in case m [ zeros(N, ncases) ]
+% nsamples   - number of samples to draw from the chain after burn-in [ 100*N ]
+% burnin     - number of steps to take before drawing samples [ 5*N ]
+% init_dag   - starting point for the search [ zeros(N,N) ]
+%
+% e.g., samples = learn_struct_mcmc(data, ns, 'nsamples', 1000);
+%
+% This interface is not backwards compatible with BNT2,
+% but is designed to be compatible with the other learn_struct_xxx routines.
+%
+% Note: We currently assume a uniform structural prior.
+
+[n ncases] = size(data);
+
+
+% set default params
+type = cell(1,n);
+params = cell(1,n);
+for i=1:n
+  type{i} = 'tabular';
+  %params{i} = { 'prior', 1 };
+  params{i} = { 'prior_type', 'dirichlet', 'dirichlet_weight', 1 };
+end
+scoring_fn = 'bayesian';
+discrete = 1:n;
+clamped = zeros(n, ncases);
+nsamples = 100*n;
+burnin = 5*n;
+dag = zeros(n);
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'nsamples',   nsamples = args{i+1};
+   case 'burnin',     burnin = args{i+1};
+   case 'init_dag',   dag = args{i+1};
+   case 'scoring_fn', scoring_fn = args{i+1};
+   case 'type',       type = args{i+1}; 
+   case 'discrete',   discrete = args{i+1}; 
+   case 'clamped',    clamped = args{i+1}; 
+   case 'params',     if isempty(args{i+1}), params = cell(1,n); else params = args{i+1};  end
+  end
+end
+
+% We implement the fast acyclicity check described by P. Giudici and R. Castelo,
+% "Improving MCMC model search for data mining", submitted to J. Machine Learning, 2001.
+use_giudici = 1;
+if use_giudici
+  [nbrs, ops, nodes] = mk_nbrs_of_digraph(dag);
+  A = init_ancestor_matrix(dag);
+else
+  [nbrs, ops, nodes] = mk_nbrs_of_dag(dag);
+  A = [];
+end
+
+num_accepts = 1;
+num_rejects = 1;
+T = burnin + nsamples;
+accept_ratio = zeros(1, T);
+num_edges = zeros(1, T);
+sampled_graphs = cell(1, nsamples);
+%sampled_bitv = zeros(nsamples, n^2);
+
+for t=1:T
+  [dag, nbrs, ops, nodes, A, accept] = take_step(dag, nbrs, ops, nodes, ns, data, clamped, A, ...
+						 scoring_fn, discrete, type, params);
+  num_edges(t) = sum(dag(:));
+  num_accepts = num_accepts + accept;
+  num_rejects = num_rejects + (1-accept);
+  accept_ratio(t) =  num_accepts/num_rejects;
+  if t > burnin
+    sampled_graphs{t-burnin} = dag;
+    %sampled_bitv(t-burnin, :) = dag(:)';
+  end
+end
+
+
+%%%%%%%%%
+
+
+function [new_dag, new_nbrs, new_ops, new_nodes, A, accept] = ...
+    take_step(dag, nbrs, ops, nodes, ns, data, clamped, A, ...
+	      scoring_fn, discrete, type, params)
+
+
+use_giudici = ~isempty(A);
+if use_giudici
+  [new_dag, op, i, j] = pick_digraph_nbr(dag, nbrs, ops, nodes, A);
+  %assert(acyclic(new_dag));
+  [new_nbrs, new_ops, new_nodes] = mk_nbrs_of_digraph(new_dag);
+else
+  d = sample_discrete(normalise(ones(1, length(nbrs))));
+  new_dag = nbrs{d};
+  op = ops{d};
+  i = nodes(d, 1); j = nodes(d, 2);
+  [new_nbrs, new_ops, new_nodes] = mk_nbrs_of_dag(new_dag);
+end
+
+bf =  bayes_factor(dag, new_dag, op, i, j, ns, data, clamped, scoring_fn, discrete, type, params);
+
+%R = bf * (new_prior / prior) * (length(nbrs) / length(new_nbrs)); 
+R = bf * (length(nbrs) / length(new_nbrs)); 
+u = rand(1,1);
+if u > min(1,R) % reject the move
+  accept = 0;
+  new_dag = dag;
+  new_nbrs = nbrs;
+  new_ops = ops;
+  new_nodes = nodes;
+else
+  accept = 1;
+  if use_giudici
+    A = update_ancestor_matrix(A, op, i, j, new_dag);
+  end
+end
+
+
+%%%%%%%%%
+
+function bfactor = bayes_factor(old_dag, new_dag, op, i, j, ns, data, clamped, scoring_fn, discrete, type, params)
+
+u = find(clamped(j,:)==0);
+LLnew = score_family(j, parents(new_dag, j), type{j}, scoring_fn, ns, discrete, data(:,u), params{j});
+LLold = score_family(j, parents(old_dag, j), type{j}, scoring_fn, ns, discrete, data(:,u), params{j});
+bf1 = exp(LLnew - LLold);
+
+if strcmp(op, 'rev')  % must also multiply in the changes to i's family
+  u = find(clamped(i,:)==0);
+  LLnew = score_family(i, parents(new_dag, i), type{i}, scoring_fn, ns, discrete, data(:,u), params{i});
+  LLold = score_family(i, parents(old_dag, i), type{i}, scoring_fn, ns, discrete, data(:,u), params{i});
+  bf2 = exp(LLnew - LLold);
+else
+  bf2 = 1;
+end
+bfactor = bf1 * bf2;
+
+
+%%%%%%%% Giudici stuff follows %%%%%%%%%%
+
+
+function [new_dag, op, i, j] = pick_digraph_nbr(dag, digraph_nbrs, ops, nodes, A)
+
+legal = 0;
+while ~legal
+  d = sample_discrete(normalise(ones(1, length(digraph_nbrs))));
+  i = nodes(d, 1); j = nodes(d, 2);
+  switch ops{d}
+   case 'add',
+    if A(i,j)==0
+      legal = 1;
+    end
+   case 'del',
+    legal = 1;
+   case 'rev',
+    ps = mysetdiff(parents(dag, j), i);
+    % if any(A(ps,i)) then there is a path i -> parent of j -> j
+    % so reversing i->j would create a cycle
+    legal = ~any(A(ps, i));
+  end
+end
+%new_dag = digraph_nbrs{d};
+new_dag = digraph_nbrs(:,:,d);
+op = ops{d};
+i = nodes(d, 1); j = nodes(d, 2);
+
+
+%%%%%%%%%%%%%%
+
+
+function A = update_ancestor_matrix(A, op, i, j, dag)
+
+switch op
+ case 'add',
+  A = do_addition(A, op, i, j, dag);
+ case 'del', 
+  A = do_removal(A, op, i, j, dag);
+ case 'rev', 
+  A = do_removal(A, op, i, j, dag);
+  A = do_addition(A, op, j, i, dag);
+end
+
+  
+%%%%%%%%%%%%
+
+function A = do_addition(A, op, i, j, dag)
+
+A(j,i) = 1; % i is an ancestor of j
+anci = find(A(i,:));
+if ~isempty(anci)
+  A(j,anci) = 1; % all of i's ancestors are added to Anc(j)
+end
+ancj = find(A(j,:));
+descj = find(A(:,j)); 
+if ~isempty(ancj)
+  for k=descj(:)'
+    A(k,ancj) = 1; % all of j's ancestors are added to each descendant of j
+  end
+end
+
+%%%%%%%%%%%
+
+function A = do_removal(A, op, i, j, dag)
+
+% find all the descendants of j, and put them in topological order
+%descj = find(A(:,j)); 
+R = reachability_graph(dag);
+descj = find(R(j,:)); 
+order = topological_sort(dag);
+descj_topnum = order(descj);
+[junk, perm] = sort(descj_topnum);
+descj = descj(perm);
+% Update j and all its descendants
+A = update_row(A, j, dag);
+for k = descj(:)'
+  A = update_row(A, k, dag);
+end
+
+%%%%%%%%%
+
+function A = update_row(A, j, dag)
+
+% We compute row j of A
+A(j, :) = 0;
+ps = parents(dag, j);
+if ~isempty(ps)
+  A(j, ps) = 1;
+end
+for k=ps(:)'
+  anck = find(A(k,:));
+  if ~isempty(anck)
+    A(j, anck) = 1;
+  end
+end
+  
+%%%%%%%%
+
+function A = init_ancestor_matrix(dag)
+
+order = topological_sort(dag);
+A = zeros(length(dag));
+for j=order(:)'
+  A = update_row(A, j, dag);
+end
diff --git a/sourcecodes/bnt-master/BNT/learning/learn_params.m b/sourcecodes/bnt-master/BNT/learning/learn_params.m
new file mode 100644
index 00000000..1bf9c843
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/learn_params.m
@@ -0,0 +1,26 @@
+function bnet = learn_params(bnet, data)
+% LEARN_PARAMS Find the maximum likelihood params for a fully observed model
+% bnet = learn_params(bnet, data)
+%
+% data(i,m) is the value of node i in case m (can be a cell array)
+%
+% We set bnet.CPD{i} to its ML/MAP estimate.
+%
+% Currently we assume no param tying
+
+% AND THAT EACH DATA POINT IS A SCALAR - no longer assumed
+
+%if iscell(data)
+%  data=cell2num(data);
+%end
+[n ncases] = size(data);
+for j=1:n
+  e = bnet.equiv_class(j);
+  assert(e==j);
+  if adjustable_CPD(bnet.CPD{e})
+    fam = family(bnet.dag,j);
+    %bnet.CPD{j} = learn_params(bnet.CPD{j}, data(fam,:));
+    bnet.CPD{j} = learn_params(bnet.CPD{j}, fam, data, bnet.node_sizes, bnet.cnodes);
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/learning/learn_params_dbn.m b/sourcecodes/bnt-master/BNT/learning/learn_params_dbn.m
new file mode 100644
index 00000000..4d0dc501
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/learn_params_dbn.m
@@ -0,0 +1,36 @@
+function bnet = learn_params_dbn(bnet, data)
+% LEARN_PARAM_DBN Estimate params of a DBN for a fully observed model
+% bnet = learn_params_dbn(bnet, data)
+%
+% data(i,t) is the value of node i in slice t (can be a cell array)
+% We currently assume there is a single time series
+%
+% We set bnet.CPD{i} to its ML/MAP estimate.
+%
+% Currently we assume each node in the first 2 slices has its own CPD (no param tying);
+% all nodes in slices >2 share their params with slice 2 as usual.
+
+[ss T] = size(data);
+
+% slice 1
+for j=1:ss
+  if adjustable_CPD(bnet.CPD{j})
+    fam = family(bnet.dag,j);
+    bnet.CPD{j} = learn_params(bnet.CPD{j}, data(fam,1));
+  end
+end
+
+
+% slices 2:T
+% data2(:,t) contains [data(:,t-1); data(:,t)].
+% Then we extract out the rows corresponding to the parents in the current and previous slice.
+data2 = [data(:,1:T-1);
+	 data(:,2:T)];
+for j=1:ss
+  j2 = j+ss;
+  if adjustable_CPD(bnet.CPD{j2})
+    fam = family(bnet.dag,j2);
+    bnet.CPD{j2} = learn_params(bnet.CPD{j2}, data2(fam,:));
+  end
+end
+
diff --git a/sourcecodes/bnt-master/BNT/learning/learn_params_dbn_em.m b/sourcecodes/bnt-master/BNT/learning/learn_params_dbn_em.m
new file mode 100644
index 00000000..e6f7f9f7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/learn_params_dbn_em.m
@@ -0,0 +1,179 @@
+function [bnet, LL, engine] = learn_params_dbn_em(engine, evidence, varargin)
+% LEARN_PARAMS_DBN Set the parameters in a DBN to their ML/MAP values using batch EM.
+% [bnet, LLtrace, engine] = learn_params_dbn_em(engine, data, ...)
+%
+% data{l}{i,t} = value of node i in slice t of time-series l, or [] if hidden.
+%   Suppose you have L time series, each of length T, in an O*T*L array D, 
+%   where O is the num of observed scalar nodes, and N is the total num nodes per slice.
+%   Then you can create data as follows, where onodes is the index of the observable nodes:
+%      data = cell(1,L);
+%      for l=1:L
+%        data{l} = cell(N, T);
+%        data{l}(onodes,:) = num2cell(D(:,:,l));
+%      end
+% Of course it is possible for different sets of nodes to be observed in
+% each slice/ sequence, and for each sequence to be a different length.
+%
+% LLtrace is the learning curve: the vector of log-likelihood scores at each iteration.
+%
+% Optional arguments [default]
+%
+% max_iter - specifies the maximum number of iterations [100]
+% thresh - specifies the thresold for stopping EM [1e-3]
+%   We stop when |f(t) - f(t-1)| / avg < threshold,
+%   where avg = (|f(t)| + |f(t-1)|)/2 and f is log lik.
+% verbose - display loglik at each iteration [1]
+% anneal - 1 means do deterministic annealing (only for entropic priors) [0]
+% anneal_rate - geometric cooling rate [0.8]
+% init_temp - initial annealing temperature [10]
+% final_temp - final annealing temperature [1e-3]
+%
+
+max_iter = 100;
+thresh = 1e-3;
+anneal = 0;
+anneal_rate = 0.8;
+init_temp = 10;
+final_temp = 1e-3;
+verbose = 1;
+
+for i=1:2:length(varargin)
+  switch varargin{i}
+   case 'max_iter', max_iter = varargin{i+1}; 
+   case 'thresh', thresh = varargin{i+1}; 
+   case 'anneal', anneal = varargin{i+1}; 
+   case 'anneal_rate', anneal_rate = varargin{i+1}; 
+   case 'init_temp', init_temp = varargin{i+1}; 
+   case 'final_temp', final_temp = varargin{i+1}; 
+   otherwise, error(['unrecognized argument' varargin{i}])
+  end
+end
+
+% take 1 EM step at each temperature value, then when temp=0, run to convergence
+% When using an entropic prior, Z = 1-T, so 
+% T=2 => Z=-1 (max entropy)
+% T=1 => Z=0 (max likelihood)
+% T=0 => Z=1 (min entropy / max structure)
+num_iter = 1;
+LL = [];
+if anneal
+  temperature = init_temp;
+  while temperature > final_temp
+    [engine, loglik, logpost] = EM_step(engine, evidence, temperature);
+    if verbose
+      fprintf('EM iteration %d, loglik = %8.4f, logpost = %8.4f, temp=%8.4f\n', ...
+	      num_iter, loglik, logpost, temperature);
+    end
+    num_iter = num_iter + 1;
+    LL = [LL loglik];
+    temperature = temperature * anneal_rate;
+  end
+  temperature = 0;
+  previous_loglik = loglik;
+  previous_logpost = logpost;
+else
+  temperature = 0;
+  previous_loglik = -inf;
+  previous_logpost = -inf;
+end
+
+converged = 0;
+while ~converged & (num_iter <= max_iter)
+  [engine, loglik, logpost] = EM_step(engine, evidence, temperature);
+  if verbose
+    %fprintf('EM iteration %d, loglik = %8.4f, logpost = %8.4f\n', ...
+    %	    num_iter, loglik, logpost);
+    fprintf('EM iteration %d, loglik = %8.4f\n', num_iter, loglik);
+  end
+  num_iter = num_iter + 1;
+  [converged, decreased] = em_converged(loglik, previous_loglik, thresh);
+  %[converged, decreased] = em_converged(logpost, previous_logpost, thresh);
+  previous_loglik = loglik;
+  previous_logpost = logpost;
+  LL = [LL loglik];
+end
+
+bnet = bnet_from_engine(engine);
+
+%%%%%%%%%
+
+function [engine, loglik, logpost] = EM_step(engine, cases, temp)
+
+bnet = bnet_from_engine(engine); % engine contains the old params that are used for the E step
+ss = length(bnet.intra);
+CPDs = bnet.CPD; % these are the new params that get maximized
+num_CPDs = length(CPDs);
+
+% log P(theta|D) = (log P(D|theta) + log P(theta)) - log(P(D))
+% where log P(D|theta) = sum_cases log P(case|theta)
+% and log P(theta) = sum_CPDs log P(CPD) - only count once even if tied!
+% logpost = log P(theta,D) (un-normalized)
+% This should be negative, and increase at every step.
+
+adjustable = zeros(1,num_CPDs);
+logprior = zeros(1, num_CPDs);
+for e=1:num_CPDs
+  adjustable(e) = adjustable_CPD(CPDs{e});
+end
+adj = find(adjustable);
+
+for e=adj(:)'
+  logprior(e) = log_prior(CPDs{e});
+  CPDs{e} = reset_ess(CPDs{e});
+end
+
+loglik = 0;
+for l=1:length(cases)
+  evidence = cases{l};
+  if ~iscell(evidence)
+    error('training data must be a cell array of cell arrays')
+  end
+  [engine, ll] = enter_evidence(engine, evidence);
+  assert(~isnan(ll))
+  loglik = loglik + ll;
+  T = size(evidence, 2);
+  
+  % We unroll ns etc because in update_ess, we refer to nodes by their unrolled number
+  % so that they extract evidence from the right place.
+  % (The CPD should really store its own version of ns and cnodes...)
+  ns = repmat(bnet.node_sizes_slice(:), [1 T]);
+  cnodes = unroll_set(bnet.cnodes_slice, ss, T);
+ 
+  %hidden_bitv = repmat(bnet.hidden_bitv(1:ss), [1 T]);
+  hidden_bitv = zeros(ss, T);
+  hidden_bitv(isemptycell(evidence))=1;
+  % hidden_bitv(i) = 1 means node i is hidden.
+  % We pass this in, rather than using isemptycell(evidence(dom)), because
+  % isemptycell is very slow.
+  
+  t = 1;
+  for i=1:ss
+    e = bnet.equiv_class(i,1);
+    if adjustable(e)
+      fmarg = marginal_family(engine, i, t);
+      CPDs{e} = update_ess(CPDs{e}, fmarg, evidence, ns(:), cnodes(:), hidden_bitv(:)); 
+    end
+  end
+  
+  for i=1:ss   
+    e = bnet.equiv_class(i,2);
+    if adjustable(e)
+      for t=2:T
+	fmarg = marginal_family(engine, i, t);
+	CPDs{e} = update_ess(CPDs{e}, fmarg, evidence, ns(:), cnodes(:), hidden_bitv(:));
+      end
+    end
+  end
+end
+
+logpost = loglik + sum(logprior(:));
+
+for e=adj(:)'
+  CPDs{e} = maximize_params(CPDs{e}, temp);
+end
+
+engine = update_engine(engine, CPDs);
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/learning/learn_params_em.m b/sourcecodes/bnt-master/BNT/learning/learn_params_em.m
new file mode 100644
index 00000000..f673e712
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/learn_params_em.m
@@ -0,0 +1,88 @@
+function [bnet, LL, engine] = learn_params_em(engine, evidence, max_iter, thresh)
+% LEARN_PARAMS_EM Set the parameters of each adjustable node to their ML/MAP values using batch EM.
+% [bnet, LLtrace, engine] = learn_params_em(engine, data, max_iter, thresh)
+%
+% data{i,l} is the value of node i in case l, or [] if hidden.
+%   Suppose you have L training cases in an O*L array, D, where O is the num observed
+%   scalar nodes, and N is the total num nodes.
+%   Then you can create 'data' as follows, where onodes is the index of the observable nodes:
+%      data = cell(N, L);
+%      data(onodes,:) = num2cell(D);
+%   Of course it is possible for different sets of nodes to be observed in each case.
+%
+% We return the modified bnet and engine.
+% To see the learned parameters for node i, use the construct
+%   s = struct(bnet.CPD{i}); % violate object privacy
+% LLtrace is the learning curve: the vector of log-likelihood scores at each iteration.
+%
+% max_iter specifies the maximum number of iterations. Default: 10.
+%
+% thresh specifies the thresold for stopping EM. Default: 1e-3.
+% We stop when |f(t) - f(t-1)| / avg < threshold,
+% where avg = (|f(t)| + |f(t-1)|)/2 and f is log lik.  
+
+if nargin < 3, max_iter = 10; end
+if nargin < 4, thresh = 1e-3; end
+
+verbose = 1;
+
+loglik = 0;
+previous_loglik = -inf;
+converged = 0;
+num_iter = 1;
+LL = [];
+
+while ~converged & (num_iter <= max_iter)
+  [engine, loglik] = EM_step(engine, evidence);
+  if verbose, fprintf('EM iteration %d, ll = %8.4f\n', num_iter, loglik); end
+  num_iter = num_iter + 1;
+  converged = em_converged(loglik, previous_loglik, thresh);
+  previous_loglik = loglik;
+  LL = [LL loglik];
+end
+if verbose, fprintf('\n'); end
+
+bnet = bnet_from_engine(engine);
+
+%%%%%%%%%
+
+function [engine, loglik] = EM_step(engine, cases)
+
+bnet = bnet_from_engine(engine); % engine contains the old params that are used for the E step
+CPDs = bnet.CPD; % these are the new params that get maximized
+num_CPDs = length(CPDs);
+adjustable = zeros(1,num_CPDs);
+for e=1:num_CPDs
+  adjustable(e) = adjustable_CPD(CPDs{e});
+end
+adj = find(adjustable);
+n = length(bnet.dag);
+
+for e=adj(:)'
+  CPDs{e} = reset_ess(CPDs{e});
+end
+
+loglik = 0;
+ncases = size(cases, 2);
+for l=1:ncases
+  evidence = cases(:,l);
+  [engine, ll] = enter_evidence(engine, evidence);
+  loglik = loglik + ll;
+  hidden_bitv = zeros(1,n);
+  hidden_bitv(isemptycell(evidence))=1;
+  for i=1:n
+    e = bnet.equiv_class(i);
+    if adjustable(e)
+      fmarg = marginal_family(engine, i);
+      CPDs{e} = update_ess(CPDs{e}, fmarg, evidence, bnet.node_sizes, bnet.cnodes, hidden_bitv);
+    end
+  end
+end
+
+for e=adj(:)'
+  CPDs{e} = maximize_params(CPDs{e});
+end
+
+engine = update_engine(engine, CPDs);
+
+
diff --git a/sourcecodes/bnt-master/BNT/learning/learn_struct_K2.m b/sourcecodes/bnt-master/BNT/learning/learn_struct_K2.m
new file mode 100644
index 00000000..8a01a2e9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/learn_struct_K2.m
@@ -0,0 +1,104 @@
+function dag = learn_struct_K2(data, ns, order, varargin)
+% LEARN_STRUCT_K2 Greedily learn the best structure compatible with a fixed node ordering
+% best_dag = learn_struct_K2(data, node_sizes, order, ...)
+%
+% data(i,m) = value of node i in case m (can be a cell array).
+% node_sizes(i) is the size of node i.
+% order(i) is the i'th node in the topological ordering.
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% max_fan_in - this the largest number of parents we allow per node [N]
+% scoring_fn - 'bayesian' or 'bic' [ 'bayesian' ]
+%              Currently, only networks with all tabular nodes support Bayesian scoring.
+% type       - type{i} is the type of CPD to use for node i, where the type is a string
+%              of the form 'tabular', 'noisy_or', 'gaussian', etc. [ all cells contain 'tabular' ]
+% params     - params{i} contains optional arguments passed to the CPD constructor for node i,
+%              or [] if none.  [ all cells contain {'prior', 1}, meaning use uniform Dirichlet priors ]
+% discrete   - the list of discrete nodes [ 1:N ]
+% clamped    - clamped(i,m) = 1 if node i is clamped in case m [ zeros(N, ncases) ]
+% verbose    - 'yes' means display output while running [ 'no' ]
+%
+% e.g., dag = learn_struct_K2(data, ns, order, 'scoring_fn', 'bic', 'params', [])
+%
+% To be backwards compatible with BNT2, you can also specify arguments as follows
+%   dag = learn_struct_K2(data, node_sizes, order, max_fan_in)    
+%
+% This algorithm is described in
+% - Cooper and Herskovits,  "A Bayesian method for the induction of probabilistic
+%      networks from data", Machine Learning Journal 9:308--347, 1992
+
+[n ncases] = size(data);
+
+% set default params
+type = cell(1,n);
+params = cell(1,n);
+for i=1:n
+  type{i} = 'tabular';
+  %params{i} = { 'prior', 1 };
+  params{i} = { 'prior_type', 'dirichlet', 'dirichlet_weight', 1 };
+end
+scoring_fn = 'bayesian';
+discrete = 1:n;
+clamped = zeros(n, ncases);
+
+max_fan_in = n;
+verbose = 0;
+
+args = varargin;
+nargs = length(args);
+if length(args) > 0 
+  if isstr(args{1})
+    for i=1:2:nargs
+      switch args{i},
+       case 'verbose',    verbose = strcmp(args{i+1}, 'yes');
+       case 'max_fan_in', max_fan_in = args{i+1}; 
+       case 'scoring_fn', scoring_fn = args{i+1};
+       case 'type',       type = args{i+1}; 
+       case 'discrete',   discrete = args{i+1}; 
+       case 'clamped',    clamped = args{i+1}; 
+       case 'params',     if isempty(args{i+1}), params = cell(1,n); else params = args{i+1};  end
+      end
+    end
+  else
+    max_fan_in = args{1};
+  end
+end
+
+dag = zeros(n,n);
+
+for i=1:n
+  ps = [];
+  j = order(i);
+  u = find(clamped(j,:)==0);    
+  score = score_family(j, ps, type{j}, scoring_fn, ns, discrete, data(:,u), params{j});
+  if verbose, fprintf('\nnode %d, empty score %6.4f\n', j, score); end
+  done = 0;
+  while ~done & (length(ps) <= max_fan_in)
+    pps = mysetdiff(order(1:i-1), ps); % potential parents
+    nps = length(pps);
+    pscore = zeros(1, nps);
+    for pi=1:nps
+      p = pps(pi);
+      pscore(pi) = score_family(j, [ps p], type{j}, scoring_fn, ns, discrete, data(:,u), params{j});
+      if verbose, fprintf('considering adding %d to %d, score %6.4f\n', p, j, pscore(pi)); end
+    end
+    [best_pscore, best_p] = max(pscore);
+    best_p = pps(best_p);
+    if best_pscore > score
+      score = best_pscore;
+      ps = [ps best_p];
+      if verbose, fprintf('* adding %d to %d, score %6.4f\n', best_p, j, best_pscore); end
+    else
+      done = 1;
+    end
+  end
+  if ~isempty(ps) % need this check for matlab 5.2
+    dag(ps, j) = 1;
+  end
+end
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/learning/learn_struct_dbn_reveal.m b/sourcecodes/bnt-master/BNT/learning/learn_struct_dbn_reveal.m
new file mode 100644
index 00000000..7be4e5da
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/learn_struct_dbn_reveal.m
@@ -0,0 +1,101 @@
+function inter = learn_struct_dbn_reveal(seqs, ns, max_fan_in, penalty)
+% LEARN_STRUCT_DBN_REVEAL Learn inter-slice adjacency matrix given fully observable discrete time series
+% inter = learn_struct_dbn_reveal(seqs, node_sizes, max_fan_in, penalty)
+% 
+% seqs{l}{i,t} = value of node i in slice t of time-series l.
+%   If you have a single time series in an N*T array D, use
+%      seqs = { num2cell(D) }.
+%   If you have L time series, each of length T, in an N*T*L array D, use
+%      seqs= cell(1,L); for l=1:L, seqs{l} = num2cell(D(:,:,l)); end
+%   or, in vectorized form,
+%      seqs = squeeze(num2cell(num2cell(D),[1 2]));
+% Currently the data is assumed to be discrete (1,2,...)
+%
+% node_sizes(i) is the number of possible values for node i
+% max_fan_in is the largest number of parents we allow per node (default: N)
+% penalty is weight given to the complexity penalty (default: 0.5)
+%  A penalty of 0.5 gives the BIC score.
+%  A penalty of 0 gives the ML score.
+%  Maximizing likelihood is equivalent to maximizing mutual information between parents and child.
+%
+% inter(i,j) = 1 iff node in slice t connects to node j in slice t+1
+%
+% The parent set for each node in slice 2 is computed by evaluating all subsets of nodes in slice 1,
+% and picking the largest scoring one. This takes O(n^k) time per node, where n is the num. nodes
+% per slice, and k <= n is the max fan in.
+% Since all the nodes are observed, we do not need to use an inference engine.
+% And since we are only learning the inter-slice matrix, we do not need to check for cycles.
+%
+% This algorithm is described in
+% - "REVEAL: A general reverse engineering algorithm for inference of genetic network
+%      architectures", Liang et al. PSB 1998
+% - "Extended dependency analysis of large systems",
+%       Roger Conant, Intl. J. General Systems, 1988, vol 14, pp 97-141
+% - "Learning the structure of DBNs", Friedman, Murphy and Russell, UAI 1998.
+
+n = length(ns);
+
+if nargin < 3, max_fan_in = n; end
+if nargin < 4, penalty = 0.5; end
+
+inter = zeros(n,n);
+
+if ~iscell(seqs)
+  data{1} = seqs;
+end
+
+nseq = length(seqs);
+nslices = 0;
+data = cell(1, nseq);
+for l=1:nseq
+  nslices = nslices + size(seqs{l}, 2);
+  data{l} = cell2num(seqs{l})'; % each row is a case
+end
+ndata = nslices - nseq; % subtract off the initial slice of each sequence
+
+% We concatenate the sequences as in the following example.
+% Let there be 2 sequences of lengths 4 and 5, with n nodes per slice,
+% and let i be the target node.
+% Then we construct following matrix D 
+%
+% s{1}{1,1} ... s{1}{1,3}     s{2}{1,1} ... s{2}{1,4}
+% ....
+% s{1}{n,1} ... s{1}{n,3}     s{2}{n,1} ... s{2}{n,4}
+% s{1}{i,2} ... s{1}{i,4}     s{2}{i,2} ... s{2}{i,5}
+%
+% D(1:n, i) is the i'th input and D(n+1, i) is the i'th output.
+% 
+% We concatenate each sequence separately to avoid treating the transition
+% from the end of one sequence to the beginning of another as a "normal" transition.
+
+
+for i=1:n
+  D = [];
+  for l=1:nseq
+    T = size(seqs{l}, 2);
+    A = cell2num(seqs{l}(:, 1:T-1));
+    B = cell2num(seqs{l}(i, 2:T));
+    C = [A;B];
+    D = [D C];
+  end
+  SS = subsets(1:n, max_fan_in, 1); % skip the empty set 
+  nSS = length(SS);
+  bic_score = zeros(1, nSS);
+  ll_score = zeros(1, nSS);
+  target = n+1;
+  ns2 = [ns ns(i)];
+  for h=1:nSS
+    ps = SS{h};
+    dom = [ps target];
+    counts = compute_counts(D(dom, :), ns2(dom));
+    CPT = mk_stochastic(counts);
+    [bic_score(h), ll_score(h)] = bic_score_family(counts, CPT, ndata);
+  end
+  if penalty == 0
+    h = argmax(ll_score);
+  else
+    h = argmax(bic_score);
+  end
+  ps = SS{h};
+  inter(ps, i) = 1;
+end
diff --git a/sourcecodes/bnt-master/BNT/learning/learn_struct_mcmc.m b/sourcecodes/bnt-master/BNT/learning/learn_struct_mcmc.m
new file mode 100644
index 00000000..d39af881
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/learn_struct_mcmc.m
@@ -0,0 +1,284 @@
+function [sampled_graphs, accept_ratio, num_edges] = learn_struct_mcmc(data, ns, varargin)
+% MY_LEARN_STRUCT_MCMC  Monte Carlo Markov Chain search over DAGs assuming fully observed data
+% [sampled_graphs, accept_ratio, num_edges] = learn_struct_mcmc(data, ns, ...)
+% 
+% data(i,m) is the value of node i in case m.
+% ns(i) is the number of discrete values node i can take on.
+%
+% sampled_graphs{m} is the m'th sampled graph.
+% accept_ratio(t) = acceptance ratio at iteration t
+% num_edges(t) = number of edges in model at iteration t
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% scoring_fn - 'bayesian' or 'bic' [ 'bayesian' ]
+%              Currently, only networks with all tabular nodes support Bayesian scoring.
+% type       - type{i} is the type of CPD to use for node i, where the type is a string
+%              of the form 'tabular', 'noisy_or', 'gaussian', etc. [ all cells contain 'tabular' ]
+% params     - params{i} contains optional arguments passed to the CPD constructor for node i,
+%              or [] if none.  [ all cells contain {'prior', 1}, meaning use uniform Dirichlet priors ]
+% discrete   - the list of discrete nodes [ 1:N ]
+% clamped    - clamped(i,m) = 1 if node i is clamped in case m [ zeros(N, ncases) ]
+% nsamples   - number of samples to draw from the chain after burn-in [ 100*N ]
+% burnin     - number of steps to take before drawing samples [ 5*N ]
+% init_dag   - starting point for the search [ zeros(N,N) ]
+%
+% e.g., samples = my_learn_struct_mcmc(data, ns, 'nsamples', 1000);
+%
+% Modified by Sonia Leach (SML) 2/4/02, 9/5/03
+
+
+
+[n ncases] = size(data);
+
+
+% set default params
+type = cell(1,n);
+params = cell(1,n);
+for i=1:n
+ type{i} = 'tabular';
+ %params{i} = { 'prior', 1};
+ params{i} = { 'prior_type', 'dirichlet', 'dirichlet_weight', 1 };
+end
+scoring_fn = 'bayesian';
+discrete = 1:n;
+clamped = zeros(n, ncases);
+nsamples = 100*n;
+burnin = 5*n;
+dag = zeros(n);
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+ switch args{i},
+  case 'nsamples',   nsamples = args{i+1};
+  case 'burnin',     burnin = args{i+1};
+  case 'init_dag',   dag = args{i+1};
+  case 'scoring_fn', scoring_fn = args{i+1};
+  case 'type',       type = args{i+1}; 
+  case 'discrete',   discrete = args{i+1}; 
+  case 'clamped',    clamped = args{i+1}; 
+  case 'params',     if isempty(args{i+1}), params = cell(1,n); else params = args{i+1};  end
+ end
+end
+
+% We implement the fast acyclicity check described by P. Giudici and R. Castelo,
+% "Improving MCMC model search for data mining", submitted to J. Machine Learning, 2001.
+
+% SML: also keep descendant matrix C
+use_giudici = 1;
+if use_giudici
+ [nbrs, ops, nodes, A] = mk_nbrs_of_digraph(dag);
+else
+ [nbrs, ops, nodes] = mk_nbrs_of_dag(dag);
+ A = [];
+end
+
+num_accepts = 1;
+num_rejects = 1;
+T = burnin + nsamples;
+accept_ratio = zeros(1, T);
+num_edges = zeros(1, T);
+sampled_graphs = cell(1, nsamples);
+%sampled_bitv = zeros(nsamples, n^2);
+
+for t=1:T
+ [dag, nbrs, ops, nodes, A, accept] = take_step(dag, nbrs, ops, ...
+                    nodes, ns, data, clamped, A, ...
+                      scoring_fn, discrete, type, params);
+ num_edges(t) = sum(dag(:));
+ num_accepts = num_accepts + accept;
+ num_rejects = num_rejects + (1-accept);
+ accept_ratio(t) =  num_accepts/num_rejects;
+ if t > burnin
+   sampled_graphs{t-burnin} = dag;
+   %sampled_bitv(t-burnin, :) = dag(:)';
+ end
+end
+
+
+%%%%%%%%%
+
+
+function [new_dag, new_nbrs, new_ops, new_nodes, A,  accept] = ...
+   take_step(dag, nbrs, ops, nodes, ns, data, clamped, A,  ...
+     scoring_fn, discrete, type, params, prior_w)
+
+
+use_giudici = ~isempty(A);
+if use_giudici
+ [new_dag, op, i, j, new_A] =  pick_digraph_nbr(dag, nbrs, ops, nodes,A); % updates A
+ [new_nbrs, new_ops, new_nodes] =  mk_nbrs_of_digraph(new_dag, new_A);
+else
+ d = sample_discrete(normalise(ones(1, length(nbrs))));
+ new_dag = nbrs{d};
+ op = ops{d};
+ i = nodes(d, 1); j = nodes(d, 2);
+ [new_nbrs, new_ops, new_nodes] = mk_nbrs_of_dag(new_dag);
+end
+
+bf =  bayes_factor(dag, new_dag, op, i, j, ns, data, clamped, scoring_fn, discrete, type, params);
+
+%R = bf * (new_prior / prior) * (length(nbrs) / length(new_nbrs)); 
+R = bf * (length(nbrs) / length(new_nbrs)); 
+u = rand(1,1);
+if u > min(1,R) % reject the move
+ accept = 0;
+ new_dag = dag;
+ new_nbrs = nbrs;
+ new_ops = ops;
+ new_nodes = nodes;
+else
+ accept = 1;
+ if use_giudici
+A = new_A; % new_A already updated in pick_digraph_nbr
+ end
+end
+
+
+%%%%%%%%%
+
+function bfactor = bayes_factor(old_dag, new_dag, op, i, j, ns, data, clamped, scoring_fn, discrete, type, params)
+
+u = find(clamped(j,:)==0);
+LLnew = score_family(j, parents(new_dag, j), type{j}, scoring_fn, ns, discrete, data(:,u), params{j});
+LLold = score_family(j, parents(old_dag, j), type{j}, scoring_fn, ns, discrete, data(:,u), params{j});
+bf1 = exp(LLnew - LLold);
+
+if strcmp(op, 'rev')  % must also multiply in the changes to i's family
+ u = find(clamped(i,:)==0);
+ LLnew = score_family(i, parents(new_dag, i), type{i}, scoring_fn, ns, discrete, data(:,u), params{i});
+ LLold = score_family(i, parents(old_dag, i), type{i}, scoring_fn, ns, discrete, data(:,u), params{i});
+ bf2 = exp(LLnew - LLold);
+else
+ bf2 = 1;
+end
+bfactor = bf1 * bf2;
+
+
+%%%%%%%% Giudici stuff follows %%%%%%%%%%
+
+
+% SML: This now updates A as it goes from digraph it choses
+function [new_dag, op, i, j, new_A] = pick_digraph_nbr(dag, digraph_nbrs, ops, nodes, A)
+
+d = sample_discrete(normalise(ones(1, length(digraph_nbrs))));
+%d = myunidrnd(length(digraph_nbrs),1,1);
+i = nodes(d, 1); j = nodes(d, 2);
+new_dag = digraph_nbrs(:,:,d);
+op = ops{d};
+new_A = update_ancestor_matrix(A, op, i, j, new_dag); 
+
+
+%%%%%%%%%%%%%%
+
+
+function A = update_ancestor_matrix(A,  op, i, j, dag)
+
+switch op
+case 'add',
+ A = do_addition(A,  op, i, j, dag);
+case 'del', 
+ A = do_removal(A,  op, i, j, dag);
+case 'rev', 
+ A = do_removal(A,  op, i, j, dag);
+ A = do_addition(A,  op, j, i, dag);
+end
+
+ 
+%%%%%%%%%%%%
+
+function A = do_addition(A, op, i, j, dag)
+
+A(j,i) = 1; % i is an ancestor of j
+anci = find(A(i,:));
+if ~isempty(anci)
+ A(j,anci) = 1; % all of i's ancestors are added to Anc(j)
+end
+ancj = find(A(j,:));
+descj = find(A(:,j)); 
+if ~isempty(ancj)
+ for k=descj(:)'
+   A(k,ancj) = 1; % all of j's ancestors are added to each descendant of j
+ end
+end
+
+%%%%%%%%%%%
+function A = do_removal(A, op, i, j, dag)
+
+% find all the descendants of j, and put them in topological order
+
+% SML: originally Kevin had the next line commented and the %* lines
+% being used but I think this is equivalent and much less expensive
+% I assume he put it there for debugging and never changed it back...?
+descj = find(A(:,j));
+%*  R = reachability_graph(dag);
+%*  descj = find(R(j,:));
+
+order = topological_sort(dag);
+
+% SML: originally Kevin used the %* line but this was extracting the
+% wrong things to sort
+%* descj_topnum = order(descj);
+[junk, perm] = sort(order); %SML:node i is perm(i)-TH in order
+descj_topnum = perm(descj); %SML:descj(i) is descj_topnum(i)-th in order
+
+% SML: now re-sort descj by rank in descj_topnum
+[junk, perm] = sort(descj_topnum);
+descj = descj(perm);
+
+% Update j and all its descendants
+A = update_row(A, j, dag);
+for k = descj(:)'
+   A = update_row(A, k, dag);
+end
+
+%%%%%%%%%%%
+
+function A = old_do_removal(A, op, i, j, dag)
+
+% find all the descendants of j, and put them in topological order
+% SML: originally Kevin had the next line commented and the %* lines
+% being used but I think this is equivalent and much less expensive
+% I assume he put it there for debugging and never changed it back...?
+descj = find(A(:,j)); 
+%*  R = reachability_graph(dag);
+%*  descj = find(R(j,:)); 
+
+order = topological_sort(dag);
+descj_topnum = order(descj);
+[junk, perm] = sort(descj_topnum);
+descj = descj(perm);
+% Update j and all its descendants
+A = update_row(A, j, dag);
+for k = descj(:)'
+ A = update_row(A, k, dag);
+end
+
+%%%%%%%%%
+
+function A = update_row(A, j, dag)
+
+% We compute row j of A
+A(j, :) = 0;
+ps = parents(dag, j);
+if ~isempty(ps)
+ A(j, ps) = 1;
+end
+for k=ps(:)'
+ anck = find(A(k,:));
+ if ~isempty(anck)
+   A(j, anck) = 1;
+ end
+end
+ 
+%%%%%%%%
+
+function A = init_ancestor_matrix(dag)
+
+order = topological_sort(dag);
+A = zeros(length(dag));
+for j=order(:)'
+ A = update_row(A, j, dag);
+end
diff --git a/sourcecodes/bnt-master/BNT/learning/learn_struct_pdag_ic_star.m b/sourcecodes/bnt-master/BNT/learning/learn_struct_pdag_ic_star.m
new file mode 100644
index 00000000..4bbba20e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/learn_struct_pdag_ic_star.m
@@ -0,0 +1,155 @@
+function [pdag, G] = learn_struct_pdag_ic_star(cond_indep, n, k, varargin)
+% LEARN_STRUCT_PDAG_IC_STAR Learn a partially oriented DAG (pattern) with latent 
+% variables using the IC* algorithm
+% P = learn_struct_pdag_ic_star(cond_indep, n, k, ...)
+%
+% n is the number of nodes.
+% k is an optional upper bound on the fan-in (default: n)
+% cond_indep is a boolean function that will be called as follows:
+% feval(cond_indep, x, y, S, ...)
+% where x and y are nodes, and S is a set of nodes (positive integers),
+% and ... are any optional parameters passed to this function.
+%
+% The output P is an adjacency matrix, in which
+% P(i,j) = -1 if there is either a latent variable L such that i <-L-> j 
+% OR there is a directed edge from i->j.
+% P(i,j) = -2 if there is a marked directed i-*>j edge.
+% P(i,j) = P(j,i) = 1 if there is and undirected edge i--j
+% P(i,j) = P(j,i) = 2 if there is a latent variable L such that i<-L->j.
+%
+% The IC* algorithm learns a latent structure associated with a set of observed 
+% variables. 
+% The latent structure revealed is the projection in which every latent variable is
+% 1) a root node
+% 2) linked to exactly two observed variables.
+% Latent variables in the projection are represented using a bidirectional graph, 
+% and thus remain implicit.
+%
+% See Pearl, "Causality: Models, Reasoning, and Inference", 2000, p52 for more details.
+% Written by Tamar Kushnir, 2000
+
+sep = cell(n,n);
+ord = 0;
+done = 0;
+G = ones(n,n);
+G = setdiag(G,0);
+while ~done
+  done = 1;
+  [X,Y] = find(G); 
+  for i=1:length(X)
+    x = X(i); y = Y(i);
+    nbrs = mysetdiff(myunion(neighbors(G, x), neighbors(G,y)), [x y]);
+    if length(nbrs) >= ord & G(x,y) ~= 0
+      done = 0;
+      SS = subsets(nbrs, ord, ord); % all subsets of size ord
+      for si=1:length(SS)
+	S = SS{si};
+	if feval(cond_indep, x, y, S, varargin{:})  
+	  G(x,y) = 0;
+	  G(y,x) = 0;
+	  sep{x,y} = myunion(sep{x,y}, S);
+	  sep{y,x} = myunion(sep{y,x}, S);
+	  break; % no need to check any more subsets 
+	end
+      end
+    end
+  end
+  ord = ord + 1;
+end
+
+% Create the minimal pattern,
+% i.e., the only directed edges are V structures.
+pdag = G;
+[X, Y] = find(G);
+% We want to generate all unique triples x,y,z
+% where y is a common neighbor to x and z
+for i=1:length(X)
+  x = X(i);
+  y = Y(i);
+  Z = find(G(y,:));
+  Z = mysetdiff(Z, x);
+  for z=Z(:)'
+    if G(x,z)==0 & ~ismember(y, sep{x,z}) & ~ismember(y, sep{z,x})
+      pdag(x,y) = -1; pdag(y,x) = 0;
+      pdag(z,y) = -1; pdag(y,z) = 0;
+    end
+  end
+end
+
+% Convert the minimal pattern to a complete one using the following rules:
+% Rule 1:
+% if a and b are non-adjacent nodes with a common neighbor c,
+% if a->c and not b->c then c-*>b (marked arrow).
+% Rule 2:
+% if a and b are adjacent and there is a directed path (marked links) from a to b
+% then a->b (add arrowhead).
+%Pearl (2000)
+
+arrowin = [-1 -2 2];
+old_pdag = zeros(n);
+iter = 0;
+while ~isequal(pdag, old_pdag)
+  iter = iter + 1;
+  old_pdag = pdag;
+  % rule 1
+  [X, Y] = find(pdag);
+  for i=1:length(X)
+    x = X(i);
+    y = Y(i);
+    Z = find(pdag(y,:));
+    Z = mysetdiff(Z, x);
+    for z=Z(:)'
+      if G(x,z)==0 & ismember(pdag(x,y),arrowin) & ~ismember(pdag(z,y),arrowin)
+        pdag(y,z) = -2; pdag(z,y) = 0;
+      end
+    end
+  end
+  % rule 2
+  [X, Y] = find(G); 
+  %check all adjacent nodes because if pdag(x,y) = -1 
+  %and pdag(y,x) = 0 there could still be an bidirected edge between x & y.
+  for i=1:length(X)
+    x = X(i);
+    y = Y(i);
+    if ~ismember(pdag(x,y), arrowin) %x->y doesn't exist yet
+      %find marked path from x to y
+      add_arrow = marked_path(x,y,pdag);
+      if add_arrow 
+        if pdag(y,x)==-1 %bidirected edge
+          pdag(x,y) = 2; pdag(y,x) = 2;
+        else
+          pdag(x,y) = -1;pdag(y,x) = 0;
+        end
+      end
+    end
+  end
+end
+
+
+%%%%%%%%%%%%%
+
+function t = marked_path(x,y,L)
+% MARKED_PATH is a boolean function which returns 1 if a marked path 
+% between nodes x and y exists in the partially directed latent structure L.
+%
+% t = marked_path(x,y,L)
+%
+% x and y are the starting and ending nodes in the path, respectively.
+% L is a latent structure (partially directed graph with possible latent variables).
+%
+% Rule 2 of IC* algorithm (see Pearl, 2000)
+
+t=0;
+
+%find set of marked links from x
+marked = find(L(x,:)==-2);
+if ismember(y,marked)
+  t=1; %marked path found
+else
+  for m=marked(:)'
+    t = marked_path(m,y,L);
+    if t==1
+      break; %stop when marked path found
+    end
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/learning/learn_struct_pdag_pc.m b/sourcecodes/bnt-master/BNT/learning/learn_struct_pdag_pc.m
new file mode 100644
index 00000000..d734a0bd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/learn_struct_pdag_pc.m
@@ -0,0 +1,130 @@
+function [pdag, G] = learn_struct_pdag_pc(cond_indep, n, k, varargin)
+% LEARN_STRUCT_PDAG_PC Learn a partially oriented DAG (pattern) using the PC algorithm
+% P = learn_struct_pdag_pc(cond_indep, n, k, ...)
+%
+% n is the number of nodes.
+% k is an optional upper bound on the fan-in (default: n)
+% cond_indep is a boolean function that will be called as follows:
+%   feval(cond_indep, x, y, S, ...)
+% where x and y are nodes, and S is a set of nodes (positive integers),
+% and ... are any optional parameters passed to this function.
+%
+% The output P is an adjacency matrix, in which
+% P(i,j) = -1 if there is an i->j edge.
+% P(i,j) = P(j,i) = 1 if there is an undirected edge i <-> j
+%
+% The PC algorithm does structure learning assuming all variables are observed.
+% See Spirtes, Glymour and Scheines, "Causation, Prediction and Search", 1993, p117.
+% This algorithm may take O(n^k) time if there are n variables and k is the max fan-in,
+% but this is quicker than the Verma-Pearl IC algorithm, which is always O(n^n).
+
+  
+sep = cell(n,n);
+ord = 0;
+done = 0;
+G = ones(n,n);
+G=setdiag(G,0);
+while ~done
+  done = 1;
+  [X,Y] = find(G); 
+  for i=1:length(X)
+    x = X(i); y = Y(i);
+    %nbrs = mysetdiff(myunion(neighbors(G, x), neighbors(G,y)), [x y]);
+    nbrs = mysetdiff(neighbors(G, y), x);  % bug fix by Raanan Yehezkel <raanany@ee.bgu.ac.il> 6/27/04
+    nbrs = unique(nbrs); % bug fix Immer Ebert ebert@tree.com 3/278/11
+    if length(nbrs) >= ord & G(x,y) ~= 0
+      done = 0;
+      %SS = subsets(nbrs, ord, ord); % all subsets of size ord
+      SS = subsets1(nbrs, ord);
+      for si=1:length(SS)
+	S = SS{si};
+	if feval(cond_indep, x, y, S, varargin{:})
+	  %if isempty(S)
+ 	  %  fprintf('%d indep of %d ', x, y);
+	  %else
+ 	  %  fprintf('%d indep of %d given ', x, y); fprintf('%d ', S);
+ 	  %end
+ 	  %fprintf('\n');
+	  
+	  % diagnostic
+	  %[CI, r] = cond_indep_fisher_z(x, y, S, varargin{:});
+	  %fprintf(': r = %6.4f\n', r);
+	  
+	  G(x,y) = 0;
+	  G(y,x) = 0;
+	  sep{x,y} = myunion(sep{x,y}, S);
+	  sep{y,x} = myunion(sep{y,x}, S);
+	  break; % no need to check any more subsets 
+	end
+      end
+    end 
+  end
+  ord = ord + 1;
+end
+
+
+% Create the minimal pattern,
+% i.e., the only directed edges are V structures.
+pdag = G;
+[X, Y] = find(G);
+% We want to generate all unique triples x,y,z
+% This code generates x,y,z and z,y,x.
+for i=1:length(X)
+  x = X(i);
+  y = Y(i);
+  Z = find(G(y,:));
+  Z = mysetdiff(Z, x);
+  for z=Z(:)'
+    if G(x,z)==0 & ~ismember(y, sep{x,z}) & ~ismember(y, sep{z,x})
+      %fprintf('%d -> %d <- %d\n', x, y, z);
+      pdag(x,y) = -1; pdag(y,x) = 0;
+      pdag(z,y) = -1; pdag(y,z) = 0;
+    end
+  end
+end
+
+% Convert the minimal pattern to a complete one,
+% i.e., every directed edge in P is compelled
+% (must be directed in all Markov equivalent models),
+% and every undirected edge in P is reversible.
+% We use the rules of Pearl (2000) p51 (derived in Meek (1995))
+
+old_pdag = zeros(n);
+iter = 0;
+while ~isequal(pdag, old_pdag)
+  iter = iter + 1;
+  old_pdag = pdag;
+  % rule 1
+  [A,B] = find(pdag==-1); % a -> b
+  for i=1:length(A)
+    a = A(i); b = B(i);
+    C = find(pdag(b,:)==1 & G(a,:)==0); % all nodes adj to b but not a
+    if ~isempty(C)
+      pdag(b,C) = -1; pdag(C,b) = 0;
+      %fprintf('rule 1: a=%d->b=%d and b=%d-c=%d implies %d->%d\n', a, b, b, C, b, C);
+    end
+  end
+  % rule 2
+  [A,B] = find(pdag==1); % unoriented a-b edge
+  for i=1:length(A)
+    a = A(i); b = B(i);
+    if any( (pdag(a,:)==-1) & (pdag(:,b)==-1)' );
+      pdag(a,b) = -1; pdag(b,a) = 0;
+      %fprintf('rule 2: %d -> %d\n', a, b);
+    end
+  end
+  % rule 3
+  [A,B] = find(pdag==1); % a-b
+  for i=1:length(A)
+    a = A(i); b = B(i);
+    C = find( (pdag(a,:)==1) & (pdag(:,b)==-1)' );
+    % C contains nodes c s.t. a-c->ba
+    G2 = setdiag(G(C, C), 1);
+    if any(G2(:)==0) % there are 2 different non adjacent elements of C
+      pdag(a,b) = -1; pdag(b,a) = 0;
+      %fprintf('rule 3: %d -> %d\n', a, b);
+    end
+  end
+end
+
+  
diff --git a/sourcecodes/bnt-master/BNT/learning/learn_struct_pdag_pc_constrain.m b/sourcecodes/bnt-master/BNT/learning/learn_struct_pdag_pc_constrain.m
new file mode 100644
index 00000000..f226b87e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/learn_struct_pdag_pc_constrain.m
@@ -0,0 +1,177 @@
+function [pdag, G] = dn_learn_struct_pdag_pc_constrain(adj, cond_indep, n, k, varargin)
+% LEARN_STRUCT_PDAG_PC Learn a partially oriented DAG (pattern) using the PC algorithm
+% Pdag = learn_struct_pdag_pc_constrain(adj, cond_indep, n, k, ...)
+%
+% adj = adjacency matrix learned from dependency network P(i,j) = 1 => i--j; 0 => i  j
+% n is the number of nodes.
+% k is an optional upper bound on the fan-in (default: n)
+% cond_indep is a boolean function that will be called as follows:
+%   feval(cond_indep, x, y, S, ...)
+% where x and y are nodes, and S is a set of nodes (positive integers),
+% and ... are any optional parameters passed to this function.
+%
+%Output
+% pdag  Partially directed graph
+% G     Resulting adjacency graph prior to setting direction arrows
+%
+% The output P is an adjacency matrix, in which
+% P(i,j) = -1 if there is an i->j edge.
+% P(i,j) = P(j,i) = 1 if there is an undirected edge i <-> j
+%
+% The PC algorithm does structure learning assuming all variables are observed.
+% See Spirtes, Glymour and Scheines, "Causation, Prediction and Search", 1993, p117.
+% This algorithm may take O(n^k) time if there are n variables and k is the max fan-in,
+% but this is quicker than the Verma-Pearl IC algorithm, which is always O(n^n).
+% 
+%%  Example
+%%  Given data in a comma separated, filename starting with the variable labels, then the data in rows.
+%%    filename test.txt consists of:
+%%
+%%      Earthquake,Burglar,Radio,Alarm,Call
+%%      1,2,2,2,1
+%%      1,1,2,1,2
+%%      . . .
+%[CovMatrix, obs, varfields] = CovMat('test.txt',5);
+%
+%dn = zeros(5,5); 
+%dn(1,2) = 1;   % This was the known Markov blanket of the system that generated test.txt
+%dn(2,1) = 1;
+%dn(2,4) = 1;
+%dn(4,2) = 1;
+%dn(1,3) = 1;
+%dn(3,1) = 1;
+%dn(1,4) = 1;
+%dn(4,1) = 1;
+%dn(4,5) = 1;
+%dn(5,4) = 1;
+%dn(3,5) = 1; %loop r->c
+%dn(5,3) = 1; %loop c-r
+%dn(3,4) = 1;
+%dn(4,3) = 1;
+%
+%max_fan_in = 4;
+%alpha = 0.05;
+%
+%[pdag G] = learn_struct_pdag_pc_constrain(dn,'cond_indep_fisher_z', 5, max_fan_in, CovMatrix, obs, alpha);
+%%
+%%
+%% Gary Bradski, 7/2002 Modified this to take an adjacency matrix from a dependency network.
+
+  
+sep = cell(n,n);
+ord = 0;
+done = 0;
+G = ones(n,n);
+G=setdiag(G,0);
+
+while ~done
+    done = 1;
+    [X,Y] = find(G);
+    for i=1:length(X)
+        x = X(i); y = Y(i);
+%        nbrs = mysetdiff(myunion(neighbors(G, x), neighbors(G,y)), [x y]);%parents, children, but not self
+        nbrs = mysetdiff(myunion(neighbors(adj, x), neighbors(adj,y)), [x y]);%parents, children, but not self
+
+        if length(nbrs) >= ord & G(x,y) ~= 0
+            done = 0;
+            SS = subsets(nbrs, ord, ord); % all subsets of size ord
+            for si=1:length(SS)
+                S = SS{si};
+                 %if (feval(dsep,x,y,S,adj)) | (feval(cond_indep, x, y, S, varargin{:}))
+                 if feval(cond_indep, x, y, S, varargin{:})
+                     %if isempty(S)
+                    %  fprintf('%d indep of %d ', x, y);
+                    %else
+                    %  fprintf('%d indep of %d given ', x, y); fprintf('%d ', S);
+                    %end
+                    %fprintf('\n');
+                    
+                    % diagnostic
+                    %[CI, r] = cond_indep_fisher_z(x, y, S, varargin{:});
+                    %fprintf(': r = %6.4f\n', r);
+                    
+                    G(x,y) = 0;
+                    G(y,x) = 0;
+                    adj(x,y) = 0;  %make sure found cond. independencies are marked out
+                    adj(y,x) = 0;
+                    sep{x,y} = myunion(sep{x,y}, S);
+                    sep{y,x} = myunion(sep{y,x}, S);
+                    break; % no need to check any more subsets 
+                end
+            end
+        end 
+    end
+    ord = ord + 1;
+end
+
+
+
+
+% Create the minimal pattern,
+% i.e., the only directed edges are V structures.
+
+pdag = G;
+[X, Y] = find(G);
+% We want to generate all unique triples x,y,z
+% This code generates x,y,z and z,y,x.
+for i=1:length(X)
+  x = X(i);
+  y = Y(i);
+  Z = find(G(y,:));
+  Z = mysetdiff(Z, x);
+  for z=Z(:)'
+    if G(x,z)==0 & ~ismember(y, sep{x,z}) & ~ismember(y, sep{z,x})
+      %fprintf('%d -> %d <- %d\n', x, y, z);
+      pdag(x,y) = -1; pdag(y,x) = 0;
+      pdag(z,y) = -1; pdag(y,z) = 0;
+    end
+  end
+end
+
+% Convert the minimal pattern to a complete one,
+% i.e., every directed edge in P is compelled
+% (must be directed in all Markov equivalent models),
+% and every undirected edge in P is reversible.
+% We use the rules of Pearl (2000) p51 (derived in Meek (1995))
+
+old_pdag = zeros(n);
+iter = 0;
+while ~isequal(pdag, old_pdag)
+  iter = iter + 1;
+  old_pdag = pdag;
+  % rule 1
+  [A,B] = find(pdag==-1); % a -> b
+  for i=1:length(A)
+    a = A(i); b = B(i);
+    C = find(pdag(b,:)==1 & G(a,:)==0); % all nodes adj to b but not a
+    if ~isempty(C)
+      pdag(b,C) = -1; pdag(C,b) = 0;
+      %fprintf('rule 1: a=%d->b=%d and b=%d-c=%d implies %d->%d\n', a, b, b, C, b, C);
+    end
+  end
+  % rule 2
+  [A,B] = find(pdag==1); % unoriented a-b edge
+  for i=1:length(A)
+    a = A(i); b = B(i);
+    if any( (pdag(a,:)==-1) & (pdag(:,b)==-1)' );
+      pdag(a,b) = -1; pdag(b,a) = 0;
+      %fprintf('rule 2: %d -> %d\n', a, b);
+    end
+  end
+  % rule 3
+  [A,B] = find(pdag==1); % a-b
+  for i=1:length(A)
+    a = A(i); b = B(i);
+    C = find( (G(a,:)==1) & (pdag(:,b)==-1)' );
+    % C contains nodes c s.t. a-c->ba
+    G2 = setdiag(G(C, C), 1);
+    if any(G2(:)==0) % there are 2 different non adjacent elements of C
+      pdag(a,b) = -1; pdag(b,a) = 0;
+      %fprintf('rule 3: %d -> %d\n', a, b);
+    end
+  end
+end
+
+
+  
+
diff --git a/sourcecodes/bnt-master/BNT/learning/mcmc_sample_to_hist.m b/sourcecodes/bnt-master/BNT/learning/mcmc_sample_to_hist.m
new file mode 100644
index 00000000..8b277c8a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/mcmc_sample_to_hist.m
@@ -0,0 +1,36 @@
+function mcmc_post = mcmc_sample_to_hist(sampled_graphs, dags)
+% MCMC_SAMPLE_TO_HIST Convert a set of sampled dags into a histogram over dags
+% hist = mcmc_sample_to_hist(sampled_graphs, dags)
+%
+% sampled_graphs{m} is the m'th sampled dag
+% dags{i} is the i'th dag in the hypothesis space
+% hist(i) = Pr(model i | data)
+
+ndags = length(dags);
+nsamples = length(sampled_graphs);
+nnodes = length(dags{1});
+% sampled_bitv(m, :) is the m'th sampled graph represented as a vector of n^2 bits, computed
+% by stacking the columns of the adjacency matrix vertically.
+sampled_bitvs = zeros(nsamples, nnodes*nnodes);
+for m=1:nsamples
+  sampled_bitvs(m, :) = sampled_graphs{m}(:)';
+end
+  
+[ugraphs, I, J] = unique(sampled_bitvs, 'rows');  % each row of ugraphs is a unique bit vector
+sampled_indices  = subv2ind(2*ones(1,nnodes*nnodes), ugraphs+1);
+counts = hist(J, 1:size(ugraphs,1)); % counts(i) = number of times graphs(i,:) occurs in the sample
+
+mcmc_post = zeros(1, ndags);
+for i=1:ndags
+  bitv = dags{i}(:)';
+  % Find the samples that corresponds to this graph by converting the graphs to bitvectors and
+  % then to integers.
+  ndx = subv2ind(2*ones(1,nnodes*nnodes), bitv+1);
+  locn = find(ndx == sampled_indices);
+  if ~isempty(locn)
+    mcmc_post(i) = counts(locn);
+  end
+end
+mcmc_post = normalise(mcmc_post);
+
+
diff --git a/sourcecodes/bnt-master/BNT/learning/mk_schedule.m b/sourcecodes/bnt-master/BNT/learning/mk_schedule.m
new file mode 100644
index 00000000..018f3d16
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/mk_schedule.m
@@ -0,0 +1,10 @@
+function schedule = mk_schedule(init_temp, final_temp, anneal_rate)
+
+init_temp = 10; final_temp = 1e-2; anneal_rate = 0.8;
+schedule = [];
+temp=init_temp;
+schedule = [schedule temp];
+while temp > final_temp
+  temp = temp * anneal_rate;
+  schedule = [schedule temp];
+end
diff --git a/sourcecodes/bnt-master/BNT/learning/mk_tetrad_data_file.m b/sourcecodes/bnt-master/BNT/learning/mk_tetrad_data_file.m
new file mode 100644
index 00000000..9c556556
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/mk_tetrad_data_file.m
@@ -0,0 +1,25 @@
+function mk_tetrad_data_file(filename, samples, sig)
+% MK_TETRAD_DATA_FILE Make a file containing raw discrete data for input to TETRAD
+% mk_tetrad_data_file(filename, samples, sig)
+%
+% samples(i,j) is the value for case i, variable j
+% The resulting file can be used for the 'build' part of Tetrad.
+% For details on tetrad, see hss.cmu.edu/html/departments/philosophy/TETRAD/tetrad.html
+
+[nsamples N] = size(samples);
+
+fid = fopen(filename, 'w');
+fprintf(fid, '/Raw\n');
+fprintf(fid, '%d\n', nsamples);
+for i=1:N
+  fprintf(fid, 'x%d ', i);
+end
+fprintf(fid, '\n');
+for i=1:nsamples
+  fprintf(fid, '%d ', samples(i,:)-1); % tetrad counts from 0
+  fprintf(fid, '\n');
+end
+%fprintf(fid, '/Knowledge\n');
+%fprintf(fid, 'Significance %4.2f\n', sig);
+fclose(fid);
+
diff --git a/sourcecodes/bnt-master/BNT/learning/score_dags_old.m b/sourcecodes/bnt-master/BNT/learning/score_dags_old.m
new file mode 100644
index 00000000..507721f6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/score_dags_old.m
@@ -0,0 +1,62 @@
+function score = score_dags(data, ns, dags, varargin)
+% SCORE_DAGS Compute the score of one or more DAGs
+% score = score_dags(data, ns, dags, varargin)
+%
+% data{i,m} = value of node i in case m (can be a cell array).
+% node_sizes(i) is the number of size of node i.
+% dags{g} is the g'th dag
+% score(g) is the score of the i'th dag
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% scoring_fn - 'bayesian' or 'bic' [ 'bayesian' ]
+%              Currently, only networks with all tabular nodes support Bayesian scoring.
+% type       - type{i} is the type of CPD to use for node i, where the type is a string
+%              of the form 'tabular', 'noisy_or', 'gaussian', etc. [ all cells contain 'tabular' ]
+% params     - params{i} contains optional arguments passed to the CPD constructor for node i,
+%              or [] if none.  [ all cells contain {'prior', 1}, meaning use uniform Dirichlet priors ]
+% discrete   - the list of discrete nodes [ 1:N ]
+% clamped    - clamped(i,m) = 1 if node i is clamped in case m [ zeros(N, ncases) ]
+%
+% e.g., score = score_dags(data, ns, mk_all_dags(n), 'scoring_fn', 'bic', 'params', []);
+%
+% If the DAGs have a lot of families in common, we can cache the sufficient statistics,
+% making this potentially more efficient than scoring the DAGs one at a time.
+% (Caching is not currently implemented, however.)
+
+[n ncases] = size(data);
+
+% set default params
+type = cell(1,n);
+params = cell(1,n);
+for i=1:n
+  type{i} = 'tabular';
+  params{i} = { 'prior_type', 'dirichlet', 'dirichlet_weight', 1 };
+end
+scoring_fn = 'bayesian';
+discrete = 1:n;
+clamped = zeros(n, ncases);
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'scoring_fn', scoring_fn = args{i+1};
+   case 'type',       type = args{i+1}; 
+   case 'discrete',   discrete = args{i+1}; 
+   case 'clamped',    clamped = args{i+1}; 
+   case 'params',     if isempty(args{i+1}), params = cell(1,n); else params = args{i+1};  end
+  end
+end
+
+NG = length(dags);
+score = zeros(1, NG);
+for g=1:NG
+  dag = dags{g};
+  for j=1:n
+    u = find(clamped(j,:)==0);    
+    ps = parents(dag, j);
+    score(g) = score(g) + score_family(j, ps, type{j}, scoring_fn, ns, discrete, data(:,u), params{j});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/learning/score_dags_wocache.m b/sourcecodes/bnt-master/BNT/learning/score_dags_wocache.m
new file mode 100644
index 00000000..79684080
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/score_dags_wocache.m
@@ -0,0 +1,67 @@
+function score = score_dags(data, ns, dags, varargin)
+% SCORE_DAGS Compute the score of one or more DAGs
+% score = score_dags(data, ns, dags, varargin)
+%
+% data{i,m} = value of node i in case m (can be a cell array).
+% node_sizes(i) is the number of size of node i.
+% dags{g} is the g'th dag
+% score(g) is the score of the i'th dag
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% scoring_fn - 'bayesian' or 'bic' [ 'bayesian' ]
+%              Currently, only networks with all tabular nodes support Bayesian scoring.
+% type       - type{i} is the type of CPD to use for node i, where the type is a string
+%              of the form 'tabular', 'noisy_or', 'gaussian', etc. [ all cells contain 'tabular' ]
+% params     - params{i} contains optional arguments passed to the CPD constructor for node i,
+%              or [] if none.  [ all cells contain {'prior', 1}, meaning use uniform Dirichlet priors ]
+% discrete   - the list of discrete nodes [ 1:N ]
+% clamped    - clamped(i,m) = 1 if node i is clamped in case m [ zeros(N, ncases) ]
+%
+% e.g., score = score_dags(data, ns, mk_all_dags(n), 'scoring_fn', 'bic', 'params', []);
+%
+% If the DAGs have a lot of families in common, we can cache the sufficient statistics,
+% making this potentially more efficient than scoring the DAGs one at a time.
+% (Caching is not currently implemented, however.)
+
+[n ncases] = size(data);
+
+% set default params
+type = cell(1,n);
+params = cell(1,n);
+for i=1:n
+  type{i} = 'tabular';
+  params{i} = { 'prior_type', 'dirichlet', 'dirichlet_weight', 1 };
+end
+scoring_fn = 'bayesian';
+discrete = 1:n;
+
+u = [1:ncases]'; % DWH
+isclamped = 0; %DWH
+clamped = zeros(n, ncases);
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'scoring_fn', scoring_fn = args{i+1};
+   case 'type',       type = args{i+1}; 
+   case 'discrete',   discrete = args{i+1}; 
+   case 'clamped',    clamped = args{i+1}, isclamped = 1; %DWH
+   case 'params',     if isempty(args{i+1}), params = cell(1,n); else params = args{i+1};  end
+  end
+end
+
+NG = length(dags);
+score = zeros(1, NG);
+for g=1:NG
+  dag = dags{g};
+  for j=1:n
+    if isclamped %DWH
+        u = find(clamped(j,:)==0);    
+    end
+    ps = parents(dag, j);
+    score(g) = score(g) + score_family(j, ps, type{j}, scoring_fn, ns, discrete, data(:,u), params{j});
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/learning/score_family_wocache.m b/sourcecodes/bnt-master/BNT/learning/score_family_wocache.m
new file mode 100644
index 00000000..a0710ba5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/learning/score_family_wocache.m
@@ -0,0 +1,57 @@
+function score = score_family(j, ps, node_type, scoring_fn, ns, discrete, data, args)
+% SCORE_FAMILY_COMPLETE Compute the score of a node and its parents given completely observed data
+% score = score_family(j, ps, node_type, scoring_fn, ns, discrete, data, args)
+%
+% data(i,m) is the value of node i in case m (can be a cell array)
+% args is a cell array containing optional arguments passed to the constructor,
+% or is [] if none
+%
+% We create a whole Bayes net which only connects parents to node,
+% where node has a CPD of the specified type (with default parameters).
+% We then evaluate its score ('bic' or 'bayesian')
+
+% We should use a cache to avoid unnecessary computation.
+% In particular, log_marginal_prob_node for tabular CPDs calls gammaln
+% and compute_counts, both of which are slow.
+
+[n ncases] = size(data);
+dag = zeros(n,n);
+% SML added to sort ps b/c mk_bnet, learn_params use sorted ps to make
+% CPTs
+% Kevin had: if ~isempty(ps), dag(ps, j) = 1; end
+if ~isempty(ps), dag(ps, j) = 1;, ps = sort(ps);, end
+
+bnet = mk_bnet(dag, ns, 'discrete', discrete);
+%bnet.CPD{j} = xxx_CPD(bnet, j);
+%eval(sprintf('bnet.CPD{j} = %s_CPD(bnet, j);', node_type));
+fname = sprintf('%s_CPD', node_type);
+%fprintf('score CPD %d\n', j);
+if isempty(args)
+  bnet.CPD{j} = feval(fname, bnet, j);
+else
+  bnet.CPD{j} = feval(fname, bnet, j, args{:});
+end
+switch scoring_fn
+ case 'bic',
+  fam = [ps j];
+  %score = BIC_score_CPD(bnet.CPD{j}, fam, data, ns, bnet.cnodes);
+  %bnet.CPD{j} = learn_params(bnet.CPD{j}, fam, data, ns, bnet.cnodes);
+  
+  % SML 03/16/04 had to special case gaussian b/c generic_CPD/learn_params
+  % no longer supported because of simple interface to learn_params
+  % introduced by KPM for tabular nodes below:
+  % KPM 9 June 04 - tabular nodes have changed back!
+  if 1 % (isempty(find(j==discrete)))
+     bnet.CPD{j} = learn_params(bnet.CPD{j},  fam, data, ns, bnet.cnodes);
+  else 
+  	bnet.CPD{j} = learn_params(bnet.CPD{j}, data(fam, :));
+  end
+  L = log_prob_node(bnet.CPD{j}, data(j,:), data(ps,:));
+  S = struct(bnet.CPD{j}); % violate object privacy
+  score = L - 0.5*S.nparams*log(ncases);
+ case 'bayesian', 
+  %score = bayesian_score_CPD(bnet.CPD{j}, data(fam, :));
+  score = log_marg_prob_node(bnet.CPD{j}, data(j,:), data(ps,:));
+ otherwise,
+  error(['unrecognized scoring fn ' scoring_fn]);
+end
diff --git a/sourcecodes/bnt-master/BNT/license.gpl.txt b/sourcecodes/bnt-master/BNT/license.gpl.txt
new file mode 100644
index 00000000..6a2d5712
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/license.gpl.txt
@@ -0,0 +1,450 @@
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License version 2 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+
+GNU Library General Public License
+
+----------------------------------------------------------------------------
+
+Table of Contents
+
+   * GNU LIBRARY GENERAL PUBLIC LICENSE
+        o Preamble
+        o TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+----------------------------------------------------------------------------
+
+GNU LIBRARY GENERAL PUBLIC LICENSE
+
+Version 2, June 1991
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+675 Mass Ave, Cambridge, MA 02139, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to
+share and change it. By contrast, the GNU General Public Licenses are
+intended to guarantee your freedom to share and change free software--to
+make sure the software is free for all its users.
+
+This license, the Library General Public License, applies to some specially
+designated Free Software Foundation software, and to any other libraries
+whose authors decide to use it. You can use it for your libraries, too.
+
+When we speak of free software, we are referring to freedom, not price. Our
+General Public Licenses are designed to make sure that you have the freedom
+to distribute copies of free software (and charge for this service if you
+wish), that you receive source code or can get it if you want it, that you
+can change the software or use pieces of it in new free programs; and that
+you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to
+deny you these rights or to ask you to surrender the rights. These
+restrictions translate to certain responsibilities for you if you distribute
+copies of the library, or if you modify it.
+
+For example, if you distribute copies of the library, whether gratis or for
+a fee, you must give the recipients all the rights that we gave you. You
+must make sure that they, too, receive or can get the source code. If you
+link a program with the library, you must provide complete object files to
+the recipients so that they can relink them with the library, after making
+changes to the library and recompiling it. And you must show them these
+terms so they know their rights.
+
+Our method of protecting your rights has two steps: (1) copyright the
+library, and (2) offer you this license which gives you legal permission to
+copy, distribute and/or modify the library.
+
+Also, for each distributor's protection, we want to make certain that
+everyone understands that there is no warranty for this free library. If the
+library is modified by someone else and passed on, we want its recipients to
+know that what they have is not the original version, so that any problems
+introduced by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We
+wish to avoid the danger that companies distributing free software will
+individually obtain patent licenses, thus in effect transforming the program
+into proprietary software. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+Most GNU software, including some libraries, is covered by the ordinary GNU
+General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary one;
+be sure to read it in full, and don't assume that anything in it is the same
+as in the ordinary license.
+
+The reason we have a separate public license for some libraries is that they
+blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in a
+textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+Because of this blurred distinction, using the ordinary General Public
+License for libraries did not effectively promote software sharing, because
+most developers did not use the libraries. We concluded that weaker
+conditions might promote sharing better.
+
+However, unrestricted linking of non-free programs would deprive the users
+of those programs of all benefit from the free status of the libraries
+themselves. This Library General Public License is intended to permit
+developers of non-free programs to use free libraries, while preserving your
+freedom as a user of such programs to change the free libraries that are
+incorporated in them. (We have not seen how to achieve this as regards
+changes in header files, but we have achieved it as regards changes in the
+actual functions of the Library.) The hope is that this will lead to faster
+development of free libraries.
+
+The precise terms and conditions for copying, distribution and modification
+follow. Pay close attention to the difference between a "work based on the
+library" and a "work that uses the library". The former contains code
+derived from the library, while the latter only works together with the
+library.
+
+Note that it is possible for a library to be covered by the ordinary General
+Public License rather than by this special one.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License Agreement applies to any software library which contains a
+notice placed by the copyright holder or other authorized party saying it
+may be distributed under the terms of this Library General Public License
+(also called "this License"). Each licensee is addressed as "you".
+
+A "library" means a collection of software functions and/or data prepared so
+as to be conveniently linked with application programs (which use some of
+those functions and data) to form executables.
+
+The "Library", below, refers to any such software library or work which has
+been distributed under these terms. A "work based on the Library" means
+either the Library or any derivative work under copyright law: that is to
+say, a work containing the Library or a portion of it, either verbatim or
+with modifications and/or translated straightforwardly into another
+language. (Hereinafter, translation is included without limitation in the
+term "modification".)
+
+"Source code" for a work means the preferred form of the work for making
+modifications to it. For a library, complete source code means all the
+source code for all modules it contains, plus any associated interface
+definition files, plus the scripts used to control compilation and
+installation of the library.
+
+Activities other than copying, distribution and modification are not covered
+by this License; they are outside its scope. The act of running a program
+using the Library is not restricted, and output from such a program is
+covered only if its contents constitute a work based on the Library
+(independent of the use of the Library in a tool for writing it). Whether
+that is true depends on what the Library does and what the program that uses
+the Library does.
+
+1. You may copy and distribute verbatim copies of the Library's complete
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the notices
+that refer to this License and to the absence of any warranty; and
+distribute a copy of this License along with the Library.
+
+You may charge a fee for the physical act of transferring a copy, and you
+may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Library or any portion of it,
+thus forming a work based on the Library, and copy and distribute such
+modifications or work under the terms of Section 1 above, provided that you
+also meet all of these conditions:
+
+        o a) The modified work must itself be a software library.
+
+        o b) You must cause the files modified to carry prominent notices
+          stating that you changed the files and the date of any change.
+
+        o c) You must cause the whole of the work to be licensed at no
+          charge to all third parties under the terms of this License.
+
+        o d) If a facility in the modified Library refers to a function or a
+          table of data to be supplied by an application program that uses
+          the facility, other than as an argument passed when the facility
+          is invoked, then you must make a good faith effort to ensure that,
+          in the event an application does not supply such function or
+          table, the facility still operates, and performs whatever part of
+          its purpose remains meaningful.
+
+          (For example, a function in a library to compute square roots has
+          a purpose that is entirely well-defined independent of the
+          application. Therefore, Subsection 2d requires that any
+          application-supplied function or table used by this function must
+          be optional: if the application does not supply it, the square
+          root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Library, and can be
+reasonably considered independent and separate works in themselves, then
+this License, and its terms, do not apply to those sections when you
+distribute them as separate works. But when you distribute the same sections
+as part of a whole which is a work based on the Library, the distribution of
+the whole must be on the terms of this License, whose permissions for other
+licensees extend to the entire whole, and thus to each and every part
+regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise
+the right to control the distribution of derivative or collective works
+based on the Library.
+
+In addition, mere aggregation of another work not based on the Library with
+the Library (or with a work based on the Library) on a volume of a storage
+or distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may opt to apply the terms of the ordinary GNU General Public License
+instead of this License to a given copy of the Library. To do this, you must
+alter all the notices that refer to this License, so that they refer to the
+ordinary GNU General Public License, version 2, instead of to this License.
+(If a newer version than version 2 of the ordinary GNU General Public
+License has appeared, then you can specify that version instead if you
+wish.) Do not make any other change in these notices.
+
+Once this change is made in a given copy, it is irreversible for that copy,
+so the ordinary GNU General Public License applies to all subsequent copies
+and derivative works made from that copy.
+
+This option is useful when you wish to copy part of the code of the Library
+into a program that is not a library.
+
+4. You may copy and distribute the Library (or a portion or derivative of
+it, under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you accompany it with the complete
+corresponding machine-readable source code, which must be distributed under
+the terms of Sections 1 and 2 above on a medium customarily used for
+software interchange.
+
+If distribution of object code is made by offering access to copy from a
+designated place, then offering equivalent access to copy the source code
+from the same place satisfies the requirement to distribute the source code,
+even though third parties are not compelled to copy the source along with
+the object code.
+
+5. A program that contains no derivative of any portion of the Library, but
+is designed to work with the Library by being compiled or linked with it, is
+called a "work that uses the Library". Such a work, in isolation, is not a
+derivative work of the Library, and therefore falls outside the scope of
+this License.
+
+However, linking a "work that uses the Library" with the Library creates an
+executable that is a derivative of the Library (because it contains portions
+of the Library), rather than a "work that uses the library". The executable
+is therefore covered by this License. Section 6 states terms for
+distribution of such executables.
+
+When a "work that uses the Library" uses material from a header file that is
+part of the Library, the object code for the work may be a derivative work
+of the Library even though the source code is not. Whether this is true is
+especially significant if the work can be linked without the Library, or if
+the work is itself a library. The threshold for this to be true is not
+precisely defined by law.
+
+If such an object file uses only numerical parameters, data structure
+layouts and accessors, and small macros and small inline functions (ten
+lines or less in length), then the use of the object file is unrestricted,
+regardless of whether it is legally a derivative work. (Executables
+containing this object code plus portions of the Library will still fall
+under Section 6.)
+
+Otherwise, if the work is a derivative of the Library, you may distribute
+the object code for the work under the terms of Section 6. Any executables
+containing that work also fall under Section 6, whether or not they are
+linked directly with the Library itself.
+
+6. As an exception to the Sections above, you may also compile or link a
+"work that uses the Library" with the Library to produce a work containing
+portions of the Library, and distribute that work under terms of your
+choice, provided that the terms permit modification of the work for the
+customer's own use and reverse engineering for debugging such modifications.
+
+You must give prominent notice with each copy of the work that the Library
+is used in it and that the Library and its use are covered by this License.
+You must supply a copy of this License. If the work during execution
+displays copyright notices, you must include the copyright notice for the
+Library among them, as well as a reference directing the user to the copy of
+this License. Also, you must do one of these things:
+
+        o a) Accompany the work with the complete corresponding
+          machine-readable source code for the Library including whatever
+          changes were used in the work (which must be distributed under
+          Sections 1 and 2 above); and, if the work is an executable linked
+          with the Library, with the complete machine-readable "work that
+          uses the Library", as object code and/or source code, so that the
+          user can modify the Library and then relink to produce a modified
+          executable containing the modified Library. (It is understood that
+          the user who changes the contents of definitions files in the
+          Library will not necessarily be able to recompile the application
+          to use the modified definitions.)
+
+        o b) Accompany the work with a written offer, valid for at least
+          three years, to give the same user the materials specified in
+          Subsection 6a, above, for a charge no more than the cost of
+          performing this distribution.
+
+        o c) If distribution of the work is made by offering access to copy
+          from a designated place, offer equivalent access to copy the above
+          specified materials from the same place.
+
+        o d) Verify that the user has already received a copy of these
+          materials or that you have already sent this user a copy.
+
+For an executable, the required form of the "work that uses the Library"
+must include any data and utility programs needed for reproducing the
+executable from it. However, as a special exception, the source code
+distributed need not include anything that is normally distributed (in
+either source or binary form) with the major components (compiler, kernel,
+and so on) of the operating system on which the executable runs, unless that
+component itself accompanies the executable.
+
+It may happen that this requirement contradicts the license restrictions of
+other proprietary libraries that do not normally accompany the operating
+system. Such a contradiction means you cannot use both them and the Library
+together in an executable that you distribute.
+
+7. You may place library facilities that are a work based on the Library
+side-by-side in a single library together with other library facilities not
+covered by this License, and distribute such a combined library, provided
+that the separate distribution of the work based on the Library and of the
+other library facilities is otherwise permitted, and provided that you do
+these two things:
+
+        o a) Accompany the combined library with a copy of the same work
+          based on the Library, uncombined with any other library
+          facilities. This must be distributed under the terms of the
+          Sections above.
+
+        o b) Give prominent notice with the combined library of the fact
+          that part of it is a work based on the Library, and explaining
+          where to find the accompanying uncombined form of the same work.
+
+8. You may not copy, modify, sublicense, link with, or distribute the
+Library except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense, link with, or distribute the Library
+is void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under this
+License will not have their licenses terminated so long as such parties
+remain in full compliance.
+
+9. You are not required to accept this License, since you have not signed
+it. However, nothing else grants you permission to modify or distribute the
+Library or its derivative works. These actions are prohibited by law if you
+do not accept this License. Therefore, by modifying or distributing the
+Library (or any work based on the Library), you indicate your acceptance of
+this License to do so, and all its terms and conditions for copying,
+distributing or modifying the Library or works based on it.
+
+10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the original
+licensor to copy, distribute, link with or modify the Library subject to
+these terms and conditions. You may not impose any further restrictions on
+the recipients' exercise of the rights granted herein. You are not
+responsible for enforcing compliance by third parties to this License.
+
+11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot distribute so
+as to satisfy simultaneously your obligations under this License and any
+other pertinent obligations, then as a consequence you may not distribute
+the Library at all. For example, if a patent license would not permit
+royalty-free redistribution of the Library by all those who receive copies
+directly or indirectly through you, then the only way you could satisfy both
+it and this License would be to refrain entirely from distribution of the
+Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents
+or other property right claims or to contest validity of any such claims;
+this section has the sole purpose of protecting the integrity of the free
+software distribution system which is implemented by public license
+practices. Many people have made generous contributions to the wide range of
+software distributed through that system in reliance on consistent
+application of that system; it is up to the author/donor to decide if he or
+she is willing to distribute software through any other system and a
+licensee cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+12. If the distribution and/or use of the Library is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Library under this License may add an
+explicit geographical distribution limitation excluding those countries, so
+that distribution is permitted only in or among countries not thus excluded.
+In such case, this License incorporates the limitation as if written in the
+body of this License.
+
+13. The Free Software Foundation may publish revised and/or new versions of
+the Library General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Library does not specify a license version
+number, you may choose any version ever published by the Free Software
+Foundation.
+
+14. If you wish to incorporate parts of the Library into other free programs
+whose distribution conditions are incompatible with these, write to the
+author to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals of
+preserving the free status of all derivatives of our free software and of
+promoting the sharing and reuse of software generally.
+
+NO WARRANTY
+
+15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO
+THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY
+PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+CORRECTION.
+
+16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO
+LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR
+THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER
+SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License version 2 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Entries b/sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Entries
new file mode 100644
index 00000000..25f4b469
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Entries
@@ -0,0 +1,15 @@
+/cg_can_to_mom.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/cg_mom_to_can.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/cgpot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/display.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/divide_by_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/domain_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/enter_cts_evidence_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/enter_discrete_evidence_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/marginalize_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/multiply_by_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/multiply_pots.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/normalize_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/pot_to_marginal.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/set_domain_pot.m/1.1.1.1/Wed Jul 30 13:38:24 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Repository b/sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Repository
new file mode 100644
index 00000000..ee9924e1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/potentials/@cgpot
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Root b/sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/CVS/Entries
new file mode 100644
index 00000000..680a9046
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/CVS/Entries
@@ -0,0 +1,4 @@
+/normalize_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/set_domain_pot.m/1.1.1.1/Wed Jul 30 13:38:08 2003//
+/simple_marginalize_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/CVS/Repository
new file mode 100644
index 00000000..7feb051e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/potentials/@cgpot/Old
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/CVS/Root b/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/normalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/normalize_pot.m
new file mode 100644
index 00000000..1debd5bc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/normalize_pot.m
@@ -0,0 +1,24 @@
+function [pot, loglik] = normalize_pot(pot)
+% NORMALIZE_POT Convert the CG potential Pr(X,E) into Pr(X|E) and return log Pr(E).
+% [pot, loglik] = normalize_pot(pot)
+
+% Marginalize down to [], so that the normalizing constant becomes Pr(E)
+temp = marginalize_pot(cg_can_to_mom(pot), []); 
+%loglik = temp.mom{1}.logp;
+[temp2, loglik] = normalize_pot(temp.mom{1});
+  
+% Adjust scale factor to reflect the fact that the pot now represents Pr(X | E) instead of Pr(X,E).
+
+scale = -loglik;
+if 1
+switch pot.subtype
+  case 'm'
+    for i=1:pot.dsize
+      pot.mom{i} = rescale_pot(pot.mom{i}, scale);
+    end
+  case 'c'
+    for i=1:pot.dsize
+      pot.can{i} = rescale_pot(pot.can{i}, scale);
+    end
+end        
+end
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/set_domain_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/set_domain_pot.m
new file mode 100644
index 00000000..f0df6ea7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/set_domain_pot.m
@@ -0,0 +1,9 @@
+function pot = set_domain_pot(pot, domain)
+% SET_DOMAIN_POT Change the domain of a potential (cgpot)
+% pot = set_domain_pot(pot, domain)
+
+delta = domain(1) - pot.domain(1);
+assert(all(domain == pot.domain + delta));
+pot.domain = pot.domain + delta;
+pot.ddom = pot.ddom + delta;
+pot.cdom = pot.cdom + delta;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/simple_marginalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/simple_marginalize_pot.m
new file mode 100644
index 00000000..a2774636
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/Old/simple_marginalize_pot.m
@@ -0,0 +1,86 @@
+function smallpot = marginalize_pot(bigpot, keep)
+% MARGINALIZE_POT Marginalize a cgpot onto a smaller domain.
+% smallpot = marginalize_pot(bigpot, keep)
+
+sumover = mysetdiff(bigpot.domain, keep);
+csumover = myintersect(sumover, bigpot.cdom);
+dsumover = myintersect(sumover, bigpot.ddom);
+dkeep = myintersect(keep, bigpot.ddom);
+ckeep = myintersect(keep, bigpot.cdom);
+%ns = sparse(1, max(bigpot.domain)); % must be full, so I is an integer
+ns = zeros(1, max(bigpot.domain));
+ns(bigpot.ddom) = bigpot.dsizes;
+ns(bigpot.cdom) = bigpot.csizes;
+
+% sum(ns(csumover))==0 is like isempty(csumover) but handles observed nodes.
+% Similarly, prod(ns(dsumover))==1 is like isempty(dsumover)
+
+% Marginalize the cts parts.
+% If we are in canonical form, we stay that way, since moment form might not exist.
+% Besides, we would like to minimize the number of conversions.
+if sum(ns(csumover)) > 0
+  if bigpot.subtype == 'm'
+    for i=1:bigpot.dsize
+      bigpot.mom{i} = marginalize_pot(bigpot.mom{i}, ckeep);
+    end
+  else
+    for i=1:bigpot.dsize
+      bigpot.can{i} = marginalize_pot(bigpot.can{i}, ckeep);
+    end
+  end
+end
+
+% If we are not marginalizing over any discrete nodes, we are done.
+if prod(ns(dsumover))==1
+  smallpot = cgpot(dkeep, ckeep, ns, bigpot.can, bigpot.mom, bigpot.subtype);
+  return;
+end
+
+% To marginalize the discrete parts, we must be in moment form.
+bigpot = cg_can_to_mom(bigpot);
+
+I = prod(ns(dkeep));
+J = prod(ns(dsumover));
+C = sum(ns(ckeep));
+
+% Reshape bigpot into the form mu1(:,j,i), where i is in dkeep, j is in dsumover
+T1 = zeros(I,J);
+mu1 = zeros(C,J,I);
+Sigma1 = zeros(C,C,J,I);
+sum_map = find_equiv_posns(dsumover, bigpot.ddom);
+keep_map = find_equiv_posns(dkeep, bigpot.ddom);
+iv = zeros(1, length(bigpot.ddom)); % index vector
+for i=1:I
+  keep_iv = ind2subv(ns(dkeep), i);
+  iv(keep_map) = keep_iv;
+  for j=1:J
+    sum_iv = ind2subv(ns(dsumover), j);
+    iv(sum_map) = sum_iv;
+    k = subv2ind(ns(bigpot.ddom), iv);
+    mom = struct(bigpot.mom{k}); % violate object privacy
+    T1(i,j) = exp(mom.logp);
+    if C > 0 % so mu1 and Sigma1 are non-empty
+      mu1(:,j,i) = mom.mu;
+      Sigma1(:,:,j,i) = mom.Sigma;
+    end
+  end
+end
+
+% Collapse the mixture of Gaussians
+coef = mk_stochastic(T1); % coef must be convex combination
+T2 = sum(T1,2);
+T2 = T2 + (T2==0)*eps;
+%if C > 0, disp('collapsing onto '); disp(leep); end
+mu = [];
+Sigma = [];
+mom = cell(1,I);
+for i=1:I
+  if C > 0
+    [mu, Sigma] = collapse_mog(mu1(:,:,i), Sigma1(:,:,:,i), coef(i,:));
+  end
+  logp = log(T2(i));
+  mom{i} = mpot(ckeep, ns(ckeep), logp, mu, Sigma);
+end
+
+smallpot = cgpot(dkeep, ckeep, ns, [], mom, 'm');
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/cg_can_to_mom.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/cg_can_to_mom.m
new file mode 100644
index 00000000..951dc910
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/cg_can_to_mom.m
@@ -0,0 +1,10 @@
+function pot = cg_can_to_mom(pot)
+% CG_CAN_TO_MOM Convert a CG potential from canonical to moment form, if necessary.
+% pot = cg_can_to_mom(pot)
+
+if pot.subtype ~= 'm'
+  for i=1:pot.dsize
+    pot.mom{i} = cpot_to_mpot(pot.can{i});
+  end
+  pot.subtype = 'm';
+end   
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/cg_mom_to_can.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/cg_mom_to_can.m
new file mode 100644
index 00000000..61aa053f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/cg_mom_to_can.m
@@ -0,0 +1,10 @@
+function pot = cg_mom_to_can(pot)
+% CG_MOM_TO_CAN Convert a CG potential from moment to canonical form, if necessary.
+% pot = cg_mom_to_can(pot)
+
+if pot.subtype ~= 'c'
+  for i=1:pot.dsize
+    pot.can{i} = mpot_to_cpot(pot.mom{i});
+  end
+  pot.subtype = 'c';
+end   
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/cgpot.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/cgpot.m
new file mode 100644
index 00000000..676e3ce1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/cgpot.m
@@ -0,0 +1,38 @@
+function pot = cgpot(ddom, cdom, node_sizes, can, mom, subtype)
+% CPOT Make a canonical CG potential.
+% function pot = cgpot(ddom, cdom, node_sizes, can, mom, subtype)
+%
+% node_sizes(i) is the size of the i'th node.
+% can and mom default to 0s.
+% subtype defaults to 'c'.
+
+if nargin < 6, subtype = 'c'; end
+
+pot.ddom = ddom;
+pot.cdom = cdom;
+node_sizes = node_sizes(:)'; % row vectors print better
+pot.domain = myunion(ddom, cdom);
+pot.dsizes = node_sizes(pot.ddom);
+pot.dsize = prod(node_sizes(pot.ddom));
+pot.csizes = node_sizes(pot.cdom);
+pot.csize = sum(node_sizes(pot.cdom));
+pot.subtype = subtype;
+
+if nargin < 4
+  can = cell(1, pot.dsize);
+  for i=1:pot.dsize
+    can{i} = cpot(cdom, node_sizes(cdom));
+  end
+end
+pot.can = can;              
+
+if nargin < 5
+  mom = cell(1, pot.dsize);
+  for i=1:pot.dsize
+    mom{i} = mpot(cdom, node_sizes(cdom));
+  end
+end
+pot.mom = mom;
+
+pot = class(pot, 'cgpot');
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/display.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/display.m
new file mode 100644
index 00000000..78813bec
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/display.m
@@ -0,0 +1,4 @@
+function display(pot)
+
+disp('conditional Gaussian potential object');
+disp(struct(pot));
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/divide_by_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/divide_by_pot.m
new file mode 100644
index 00000000..d3c6e7f9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/divide_by_pot.m
@@ -0,0 +1,19 @@
+function bigpot = divide_by_pot(bigpot, smallpot)
+% DIVIDE_BY_POT bigpot /= smallpot for cgpot
+% bigpot = divide_by_pot(bigpot, smallpot)
+%
+% smallpot's domain must be a subset of bigpot's domain.
+
+bigpot = cg_mom_to_can(bigpot);
+smallpot = cg_mom_to_can(smallpot);
+
+mask = find_equiv_posns(smallpot.ddom, bigpot.ddom);
+for i=1:bigpot.dsize
+  if isempty(smallpot.ddom)
+    src = 1;
+  else
+    sub = ind2subv(bigpot.dsizes, i);
+    src = subv2ind(smallpot.dsizes, sub(mask));
+  end
+  bigpot.can{i} = divide_by_pot(bigpot.can{i}, smallpot.can{src});
+end                   
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/domain_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/domain_pot.m
new file mode 100644
index 00000000..a09e39e6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/domain_pot.m
@@ -0,0 +1,5 @@
+function dom = domain_pot(pot)
+% DOMAIN_POT Return the domain of this cgpot.
+% dom = domain_pot(pot)
+
+dom = pot.domain;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/enter_cts_evidence_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/enter_cts_evidence_pot.m
new file mode 100644
index 00000000..e5267bbd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/enter_cts_evidence_pot.m
@@ -0,0 +1,8 @@
+function pot = enter_cts_evidence_pot(pot, Y, y)
+% function pot = enter_cts_evidence_pot(pot, Y, y) cgpot
+
+
+pot = cg_mom_to_can(pot);
+for i=1:pot.dsize
+  pot.can{i} = enter_cts_evidence_pot(pot.can{i}, Y, y);
+end
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/enter_discrete_evidence_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/enter_discrete_evidence_pot.m
new file mode 100644
index 00000000..972df966
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/enter_discrete_evidence_pot.m
@@ -0,0 +1,16 @@
+function pot = enter_discrete_evidence_pot(pot, Y, y)
+
+%ns = sparse(1, max(pot.domain));
+ns = zeros(1, max(pot.domain));
+ns(pot.ddom) = pot.dsizes;
+ns(pot.cdom) = pot.csizes;
+
+ddom = pot.ddom;
+S = prod(ns(ddom));
+sub = ind2subv(ns(ddom), 1:S);
+mask = find_equiv_posns(Y, ddom);
+sub(mask) = y;
+ndx = subv2ind(ns(ddom), sub);
+
+pot.can = pot.can(ndx);
+pot.mom = pot.mom(ndx);
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/marginalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/marginalize_pot.m
new file mode 100644
index 00000000..4e666b1a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/marginalize_pot.m
@@ -0,0 +1,153 @@
+function smallpot = marginalize_pot(bigpot, keep, maximize, useC)
+% MARGINALIZE_POT Marginalize a cgpot onto a smaller domain.
+% smallpot = marginalize_pot(bigpot, keep, maximize, useC)
+%
+% If maximize = 1, we raise an error.
+% useC is ignored.
+
+if nargin < 3, maximize = 0; end
+assert(~maximize);
+
+
+sumover = mysetdiff(bigpot.domain, keep);
+csumover = myintersect(sumover, bigpot.cdom);
+dsumover = myintersect(sumover, bigpot.ddom);
+dkeep = myintersect(keep, bigpot.ddom);
+ckeep = myintersect(keep, bigpot.cdom);
+%ns = sparse(1, max(bigpot.domain)); % must be full, so I is an integer
+ns = zeros(1, max(bigpot.domain));
+ns(bigpot.ddom) = bigpot.dsizes;
+ns(bigpot.cdom) = bigpot.csizes;
+
+% sum(ns(csumover))==0 is like isempty(csumover) but handles observed nodes.
+% Similarly, prod(ns(dsumover))==1 is like isempty(dsumover)
+
+% Marginalize the cts parts.
+% If we are in canonical form, we stay that way, since moment form might not exist.
+% Besides, we would like to minimize the number of conversions.
+if sum(ns(csumover)) > 0
+  if bigpot.subtype == 'm'
+    for i=1:bigpot.dsize
+      bigpot.mom{i} = marginalize_pot(bigpot.mom{i}, ckeep);
+    end
+  else
+    for i=1:bigpot.dsize
+      bigpot.can{i} = marginalize_pot(bigpot.can{i}, ckeep);
+    end
+  end
+end
+
+% If we are not marginalizing over any discrete nodes, we are done.
+if prod(ns(dsumover))==1
+  smallpot = cgpot(dkeep, ckeep, ns, bigpot.can, bigpot.mom, bigpot.subtype);
+  return;
+end
+
+% To marginalize the discrete parts, we partition the cts parts into those that depend
+% on dkeep (i) and those that depend on on dsumover (j).
+
+I = prod(ns(dkeep));
+J = prod(ns(dsumover));
+C = sum(ns(ckeep));   
+sum_map = find_equiv_posns(dsumover, bigpot.ddom);
+keep_map = find_equiv_posns(dkeep, bigpot.ddom);
+iv = zeros(1, length(bigpot.ddom)); % index vector
+
+% If in canonical form, marginalize if possible, else convert to moment form.
+if 0 && bigpot.subtype == 'c'
+  p1 = zeros(I,J);
+  h1 = zeros(C,J,I);
+  K1 = zeros(C,C,J,I);
+  for i=1:I
+    keep_iv = ind2subv(ns(dkeep), i);
+    iv(keep_map) = keep_iv;
+    for j=1:J
+      sum_iv = ind2subv(ns(dsumover), j);
+      iv(sum_map) = sum_iv;
+      k = subv2ind(ns(bigpot.ddom), iv);
+      can = struct(bigpot.can{k}); % violate object privacy
+      p1(i,j) = exp(can.g);
+      if C > 0 % so mu1 and Sigma1 are non-empty
+	h1(:,j,i) = can.h;
+	K1(:,:,j,i) = can.K;
+      end
+    end
+  end
+  
+  % If the cts parts do not depend on j, we can just marginalize the weighting coefficient g.
+  jdepends = 0;
+  for i=1:I
+    for j=2:J
+      if ~approxeq(h1(:,j,i), h1(:,1,i)) | ~approxeq(K1(:,:,j,i), K1(:,:,1,i))
+	jdepends = 1;
+	break
+      end
+    end
+  end
+
+  if ~jdepends
+    %g2 = log(sum(p1, 2));
+    g2 = zeros(I,1);
+    for i=1:I
+      s = sum(p1(i,:));
+      if s > 0
+	g2(i) = log(s);
+      end
+    end
+    h2 = h1;
+    K2 = K1;
+    can = cell(1,I);
+    j = 1; % arbitrary
+    for i=1:I
+      can{i} = cpot(ckeep, ns(ckeep), g2(i), h2(:,j,i), K2(:,:,j,i));
+    end
+    smallpot = cgpot(dkeep, ckeep, ns, can, [], 'c');  
+    return;
+  else
+    % Since the cts parts depend on j, we must convert to moment form
+    bigpot = cg_can_to_mom(bigpot);
+  end
+end
+
+
+% Marginalize in moment form
+bigpot = cg_can_to_mom(bigpot);
+
+% Now partition the moment components.
+T1 = zeros(I,J);
+mu1 = zeros(C,J,I);
+Sigma1 = zeros(C,C,J,I);
+for i=1:I
+  keep_iv = ind2subv(ns(dkeep), i);
+  iv(keep_map) = keep_iv;
+  for j=1:J
+    sum_iv = ind2subv(ns(dsumover), j);
+    iv(sum_map) = sum_iv;
+    k = subv2ind(ns(bigpot.ddom), iv);
+    mom = struct(bigpot.mom{k}); % violate object privacy
+    T1(i,j) = exp(mom.logp);
+    if C > 0 % so mu1 and Sigma1 are non-empty
+      mu1(:,j,i) = mom.mu;
+      Sigma1(:,:,j,i) = mom.Sigma;
+    end
+  end
+end
+
+% Collapse the mixture of Gaussians
+coef = mk_stochastic(T1); % coef must be convex combination
+T2 = sum(T1,2);
+T2 = T2 + (T2==0)*eps;
+%if C > 0, disp('collapsing onto '); disp(leep); end
+mu = [];
+Sigma = [];
+mom = cell(1,I);
+for i=1:I
+  if C > 0
+    [mu, Sigma] = collapse_mog(mu1(:,:,i), Sigma1(:,:,:,i), coef(i,:));
+  end
+  logp = log(T2(i));
+  mom{i} = mpot(ckeep, ns(ckeep), logp, mu, Sigma);
+end
+
+smallpot = cgpot(dkeep, ckeep, ns, [], mom, 'm');
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/multiply_by_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/multiply_by_pot.m
new file mode 100644
index 00000000..0dcad3fc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/multiply_by_pot.m
@@ -0,0 +1,19 @@
+function bigpot = multiply_by_pot(bigpot, smallpot, varargin)
+% MULTIPLY_BY_POT bigpot *= smallpot for cgpot
+% bigpot = multiply_by_pot(bigpot, smallpot)
+%
+% smallpot's domain must be a subset of bigpot's domain.
+
+bigpot = cg_mom_to_can(bigpot);
+smallpot = cg_mom_to_can(smallpot);
+
+mask = find_equiv_posns(smallpot.ddom, bigpot.ddom);
+for i=1:bigpot.dsize
+  if isempty(smallpot.ddom)
+    src = 1;
+  else
+    sub = ind2subv(bigpot.dsizes, i);
+    src = subv2ind(smallpot.dsizes, sub(mask));
+  end
+  bigpot.can{i} = multiply_by_pot(bigpot.can{i}, smallpot.can{src});
+end                   
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/multiply_pots.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/multiply_pots.m
new file mode 100644
index 00000000..8035d6de
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/multiply_pots.m
@@ -0,0 +1,16 @@
+function T = multiply_pots(T1, T2)
+% MULTIPLY_POTS Multiply a pair of dpots together pointwise (cgpot)
+% T = multiply_pots(pots)
+
+ddom = myunion(T1.ddom, T2.ddom);
+cdom = myunion(T1.cdom, T2.cdom);
+dom = myunion(ddom, cdom);
+ns = zeros(1, max(dom));
+ns(T1.ddom) = T1.dsizes;
+ns(T2.ddom) = T2.dsizes;
+ns(T1.cdom) = T1.csizes;
+ns(T2.cdom) = T2.csizes;
+
+T = cgpot(ddom, cdom, ns);
+T = multiply_by_pot(T, T1);
+T = multiply_by_pot(T, T2);   
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/normalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/normalize_pot.m
new file mode 100644
index 00000000..0c05ae5d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/normalize_pot.m
@@ -0,0 +1,24 @@
+function [pot, loglik] = normalize_pot(pot)
+% NORMALIZE_POT Convert the CG potential Pr(X,E) into Pr(X|E) and return log Pr(E).
+% [pot, loglik] = normalize_pot(pot)
+
+% Marginalize down to [], so that the normalizing constant becomes Pr(E)
+temp = cg_can_to_mom(marginalize_pot(pot, []));
+%loglik = temp.mom{1}.logp;
+[temp2, loglik] = normalize_pot(temp.mom{1});
+  
+% Adjust scale factor to reflect the fact that the pot now represents Pr(X | E) instead of Pr(X,E).
+
+scale = -loglik;
+if 1
+switch pot.subtype
+  case 'm'
+    for i=1:pot.dsize
+      pot.mom{i} = rescale_pot(pot.mom{i}, scale);
+    end
+  case 'c'
+    for i=1:pot.dsize
+      pot.can{i} = rescale_pot(pot.can{i}, scale);
+    end
+end        
+end
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/pot_to_marginal.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/pot_to_marginal.m
new file mode 100644
index 00000000..a651e192
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/pot_to_marginal.m
@@ -0,0 +1,27 @@
+function m = pot_to_marginal(pot)
+% POT_TO_MARGINAL Convert a cgpot to a marginal structure.
+% m = pot_to_marginal(pot)
+
+pot = cg_can_to_mom(pot);
+m.domain = pot.domain;
+n = pot.csize;
+d = length(pot.mom);
+if n==0
+  m.mu = [];
+  m.Sigma = [];
+else
+  m.mu = zeros(n, d);
+  m.Sigma = zeros(n, n, d);
+end
+m.T = 0*myones(pot.dsizes);
+for i=1:pot.dsize
+  s = struct(pot.mom{i}); % violate privacy of object
+  if n > 0
+    m.mu(:,i) = s.mu;
+    m.Sigma(:,:,i) = s.Sigma;
+  end
+  m.T(i) = exp(s.logp);
+end     
+if isvectorBNT(m.T)
+  m.T = m.T(:)';
+end
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cgpot/set_domain_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cgpot/set_domain_pot.m
new file mode 100644
index 00000000..07364648
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cgpot/set_domain_pot.m
@@ -0,0 +1,21 @@
+function pot = set_domain_pot(pot, domain)
+% SET_DOMAIN_POT Change the domain of a potential (cgpot)
+% pot = set_domain_pot(pot, domain)
+
+delta = domain(1) - pot.domain(1);
+assert(all(domain == pot.domain + delta));
+pot.domain = pot.domain + delta;
+pot.ddom = pot.ddom + delta;
+pot.cdom = pot.cdom + delta;
+cdomain = pot.cdom;
+n = prod(pot.dsizes);
+if(pot.subtype == 'm')
+    for i = 1: n
+        pot.mom{i} = set_domain_pot(pot.mom{i}, cdomain);
+    end
+end
+if(pot.subtype == 'c')
+    for i = 1: n
+        pot.can{i} = set_domain_pot(pot.can{i}, cdomain);
+    end
+end
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Entries b/sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Entries
new file mode 100644
index 00000000..7f4397ef
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Entries
@@ -0,0 +1,14 @@
+/cpot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/cpot_to_mpot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/display.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/divide_by_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/domain_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/enter_cts_evidence_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/marginalize_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/multiply_by_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/multiply_pots.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/normalize_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/pot_to_marginal.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/rescale_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/set_domain_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Entries.Log
new file mode 100644
index 00000000..24f16336
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/Old////
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Repository b/sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Repository
new file mode 100644
index 00000000..12ecad25
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/potentials/@cpot
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Root b/sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/CVS/Entries
new file mode 100644
index 00000000..3345f808
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/CVS/Entries
@@ -0,0 +1,3 @@
+/cpot_to_mpot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/normalize_pot.convert.m/1.1.1.1/Wed May 29 15:59:58 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/CVS/Repository
new file mode 100644
index 00000000..bdb2b68d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/potentials/@cpot/Old
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/CVS/Root b/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/cpot_to_mpot.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/cpot_to_mpot.m
new file mode 100644
index 00000000..05899b99
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/cpot_to_mpot.m
@@ -0,0 +1,25 @@
+function mom = cpot_to_mpot(can)
+% CPOT_TO_MPOT Convert a canonical potential to moment form.
+% mom = cpot_to_mpot(can)
+
+[logp, mu, Sigma] = canonical_to_moment(can.g, can.h, can.K);
+mom = mpot(can.domain, can.sizes, logp, mu, Sigma);
+
+%%%%%%%
+
+function [logp, mu, Sigma] = canonical_to_moment(g, h, K)
+% CANONICAL_TO_MOMENT Convert canonical characteristics to moment form.
+% [logp, mu, Sigma] = canonical_to_moment(g, h, K)
+
+if det(K)==0
+  Sigma = inf*size(K);
+else
+  Sigma = inv(K);
+end
+mu = Sigma*h;
+n = length(mu);
+if isempty(mu)
+  logp = g - 0.5*(log(det(K)) - n*log(2*pi));
+else
+  logp = g - 0.5*(log(det(K)) - n*log(2*pi) - mu'*K*mu);
+end
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/normalize_pot.convert.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/normalize_pot.convert.m
new file mode 100644
index 00000000..59c473cc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/Old/normalize_pot.convert.m
@@ -0,0 +1,9 @@
+function [mom2, loglik] = normalize_pot(can)
+% NORMALIZE_POT Convert the canonical potential Pr(X,E) into moment potential Pr(X|E) and return log Pr(E).
+% [mom, loglik] = normalize_pot(can)
+
+mom = cpot_to_mpot(can);
+mom = struct(mom); % violate privacy of object
+loglik = mom.logp;
+%mom.logp = 0; % now represents Pr(X | E) instead of Pr(X, E). 
+mom2 = mpot(mom.domain, mom.sizes, 0, mom.mu, mom.Sigma);
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/cpot.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/cpot.m
new file mode 100644
index 00000000..b8dfbf03
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/cpot.m
@@ -0,0 +1,17 @@
+function pot = cpot(members, sizes, g, h, K)
+% CPOT Make a canonical Gaussian potential.
+% pot = cpot(members, sizes, g, h, K)
+%
+% All params default to 0 if omitted.
+
+n = sum(sizes);
+if nargin < 3, g = 0; end
+if nargin < 4, h = zeros(n,1); end
+if nargin < 5, K = zeros(n,n); end
+  
+pot.domain = members;
+pot.sizes = sizes(:)';
+pot.g = g;
+pot.h = h;
+pot.K = K;
+pot = class(pot, 'cpot');
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/cpot_to_mpot.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/cpot_to_mpot.m
new file mode 100644
index 00000000..73739d7e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/cpot_to_mpot.m
@@ -0,0 +1,29 @@
+function mom = cpot_to_mpot(can)
+% CPOT_TO_MPOT Convert a canonical potential to moment form.
+% mom = cpot_to_mpot(can)
+
+[logp, mu, Sigma] = canonical_to_moment(can.g, can.h, can.K);
+mom = mpot(can.domain, can.sizes, logp, mu, Sigma);
+
+%%%%%%%
+
+function [logp, mu, Sigma] = canonical_to_moment(g, h, K)
+% CANONICAL_TO_MOMENT Convert canonical characteristics to moment form.
+% [logp, mu, Sigma] = canonical_to_moment(g, h, K)
+
+n = length(K);
+if isempty(K)
+  logp = g - 0.5*(log(det(K)) - n*log(2*pi));
+  Sigma = [];
+  mu = [];
+else
+  if det(K)==0
+    Sigma = inf*ones(n,n);
+    mu = zeros(n,1); % if the precision is zero, the mean is arbitrary
+    logp = g; % the scaling factor for the uniform distribution is 1
+  else
+    Sigma = inv(K);
+    mu = Sigma*h;
+    logp = g - 0.5*(log(det(K)) - n*log(2*pi) - mu'*K*mu);
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/display.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/display.m
new file mode 100644
index 00000000..35a4f0b3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/display.m
@@ -0,0 +1,4 @@
+function display(pot)
+
+disp('canonical potential object');
+disp(struct(pot));
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/divide_by_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/divide_by_pot.m
new file mode 100644
index 00000000..1e2bb2b9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/divide_by_pot.m
@@ -0,0 +1,13 @@
+function bigpot = divide_by_pot(bigpot, smallpot)
+% DIVIDE_BY_POT bigpot /= smallpot for cpot
+% bigpot = divide_by_pot(bigpot, smallpot)
+%
+% smallpot's domain must be a subset of bigpot's domain.
+
+bigpot.g = bigpot.g - smallpot.g;
+if sum(smallpot.sizes) > 0
+  mask = find_equiv_posns(smallpot.domain, bigpot.domain);
+  u = block(mask, bigpot.sizes);
+  bigpot.h(u) = bigpot.h(u) - smallpot.h;
+  bigpot.K(u, u) = bigpot.K(u, u) - smallpot.K;
+end               
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/domain_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/domain_pot.m
new file mode 100644
index 00000000..aa5ce392
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/domain_pot.m
@@ -0,0 +1,5 @@
+function dom = domain_pot(pot)
+% DOMAIN_POT Return the domain of this cpot.
+% dom = domain_pot(pot)
+
+dom = pot.domain;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/enter_cts_evidence_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/enter_cts_evidence_pot.m
new file mode 100644
index 00000000..246729ae
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/enter_cts_evidence_pot.m
@@ -0,0 +1,15 @@
+function pot = enter_cts_evidence_pot(pot, Y, y)
+% function pot = enter_cts_evidence_pot(pot, Y, y) (cpot)
+
+ns = sparse(1, max(pot.domain));
+ns(pot.domain) = pot.sizes;
+
+X = mysetdiff(pot.domain, Y);
+[hx, hy, KXX, KXY, KYX, KYY] = partition_matrix_vec(pot.h, pot.K, X, Y, ns);
+pot.g = pot.g + hy'*y - 0.5*y'*KYY*y;
+if ~isempty(X)
+  pot.h = hx - KXY*y;
+  pot.K = KXX;
+end
+
+pot.sizes(find_equiv_posns(Y,pot.domain)) = 0;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/marginalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/marginalize_pot.m
new file mode 100644
index 00000000..ae9ee839
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/marginalize_pot.m
@@ -0,0 +1,31 @@
+function smallpot = marginalize_pot(bigpot, keep, maximize, useC)
+% MARGINALIZE_POT Marginalize a cpot onto a smaller domain.
+% smallpot = marginalize_pot(bigpot, keep, maximize, useC)
+%
+% The maximize argument is ignored - maxing out a Gaussian is the same as summing it out,
+% since the mode and mean are equal.
+% The useC argument is ignored.
+
+node_sizes = sparse(1, max(bigpot.domain));
+node_sizes(bigpot.domain) = bigpot.sizes;
+sum_over = mysetdiff(bigpot.domain, keep);
+
+if sum(node_sizes(sum_over))==0 % isempty(sum_over)
+  %smallpot = bigpot;
+  smallpot = cpot(keep, node_sizes(keep), bigpot.g, bigpot.h, bigpot.K);
+else
+  [h1, h2, K11, K12, K21, K22] = partition_matrix_vec(bigpot.h, bigpot.K, sum_over, keep, node_sizes);
+  n = length(h1);
+  K11inv = inv(K11);
+  g = bigpot.g + 0.5*(n*log(2*pi) - log(det(K11)) + h1'*K11inv*h1);
+  if length(h2) > 0 % ~isempty(keep) % we are are actually keeping something
+    A = K21*K11inv;
+    h = h2 - A*h1;
+    K = K22 - A*K12;
+  else
+    h = [];
+    K = [];
+  end
+  smallpot = cpot(keep, node_sizes(keep), g, h, K);
+end
+           
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/multiply_by_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/multiply_by_pot.m
new file mode 100644
index 00000000..1ab24f55
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/multiply_by_pot.m
@@ -0,0 +1,13 @@
+function bigpot = multiply_by_pot(bigpot, smallpot, varargin)
+% MULTIPLY_BY_POT bigpot *= smallpot for cpot
+% bigpot = multiply_by_pot(bigpot, smallpot)
+%
+% smallpot's domain must be a subset of bigpot's domain.
+
+bigpot.g = bigpot.g + smallpot.g;
+if sum(smallpot.sizes) > 0
+  mask = find_equiv_posns(smallpot.domain, bigpot.domain);
+  u = block(mask, bigpot.sizes);
+  bigpot.h(u) = bigpot.h(u) + smallpot.h;
+  bigpot.K(u, u) = bigpot.K(u, u) + smallpot.K;
+end               
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/multiply_pots.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/multiply_pots.m
new file mode 100644
index 00000000..3506e36e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/multiply_pots.m
@@ -0,0 +1,11 @@
+function T = multiply_pots(T1, T2)
+% MULTIPLY_POTS Multiply a pair of dpots together pointwise (cpot)
+% T = multiply_pots(pots)
+
+dom = myunion(T1.domain, T2.domain);
+ns = sparse(1, max(dom));
+ns(T1.domain) = T1.sizes;
+ns(T2.domain) = T2.sizes;
+T = cpot(dom, ns(dom));
+T = multiply_by_pot(T, T1);
+T = multiply_by_pot(T, T2);   
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/normalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/normalize_pot.m
new file mode 100644
index 00000000..c6f89dc3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/normalize_pot.m
@@ -0,0 +1,10 @@
+function [pot, loglik] = normalize_pot(pot)
+% NORMALIZE_POT Convert the canonical potential Pr(X,E) into Pr(X|E) and return log Pr(E).
+% [pot, loglik] = normalize_pot(pot)
+
+mom = cpot_to_mpot(pot);  % move the normalizing constant out of g, to reveal the coefficient          
+%loglik = scaling_factor_pot(mom);
+%loglik = mom.logp; 
+[temp, loglik] = normalize_pot(mom);
+pot.g = pot.g - loglik;
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/pot_to_marginal.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/pot_to_marginal.m
new file mode 100644
index 00000000..4c3fb79f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/pot_to_marginal.m
@@ -0,0 +1,6 @@
+function m = pot_to_marginal(pot)
+% POT_TO_MARGINAL Convert a cpot to a marginal structure.
+% m = pot_to_marginal(pot)
+
+mom = cpot_to_mpot(pot);
+m = pot_to_marginal(mom);
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/rescale_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/rescale_pot.m
new file mode 100644
index 00000000..ad962455
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/rescale_pot.m
@@ -0,0 +1,5 @@
+function pot = rescale_pot(pot, s)
+% RESCALE_POT Add a constant to the cpot scale factor.
+% pot = rescale_pot(pot, s)
+
+pot.g = pot.g + s;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@cpot/set_domain_pot.m b/sourcecodes/bnt-master/BNT/potentials/@cpot/set_domain_pot.m
new file mode 100644
index 00000000..2178c51d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@cpot/set_domain_pot.m
@@ -0,0 +1,5 @@
+function pot = set_domain_pot(pot, domain)
+% SET_DOMAIN_POT Change the domain of a potential (dpot)
+% pot = set_domain_pot(pot, domain)
+
+pot.domain = domain;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/CVS/Entries b/sourcecodes/bnt-master/BNT/potentials/@dpot/CVS/Entries
new file mode 100644
index 00000000..d37ad7eb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/CVS/Entries
@@ -0,0 +1,17 @@
+/approxeq_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/display.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/divide_by_pot.m/1.1.1.1/Thu Aug  5 15:25:08 2004//
+/domain_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/dpot.m/1.1.1.1/Tue Oct  1 19:04:44 2002//
+/dpot_to_table.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/find_most_prob_entry.m/1.1.1.1/Sun Jun 16 19:06:20 2002//
+/get_fields.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/marginalize_pot.m/1.1.1.1/Wed Aug  4 19:59:14 2004//
+/multiply_by_pot.m/1.1.1.1/Wed Aug  4 19:59:14 2004//
+/multiply_pots.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/normalize_pot.m/1.1.1.1/Wed Aug  4 15:54:48 2004//
+/pot_to_marginal.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/set_domain_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/subsasgn.m/1.1.1.1/Wed Apr 27 18:34:48 2005//
+/subsref.m/1.1.1.1/Wed Apr 27 18:34:48 2005//
+D
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/CVS/Repository b/sourcecodes/bnt-master/BNT/potentials/@dpot/CVS/Repository
new file mode 100644
index 00000000..485f27df
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/potentials/@dpot
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/CVS/Root b/sourcecodes/bnt-master/BNT/potentials/@dpot/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/approxeq_pot.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/approxeq_pot.m
new file mode 100644
index 00000000..b0f8d0ed
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/approxeq_pot.m
@@ -0,0 +1,5 @@
+function p = approxeq_pot(A, B, tol)
+
+if nargin < 3, tol = 1e-3; end
+
+p = approxeq(A.T, B.T, tol);
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/display.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/display.m
new file mode 100644
index 00000000..1b0647bb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/display.m
@@ -0,0 +1,4 @@
+function display(pot)
+
+disp('discrete potential object');
+disp(struct(pot));
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/divide_by_pot.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/divide_by_pot.m
new file mode 100644
index 00000000..aae4790c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/divide_by_pot.m
@@ -0,0 +1,14 @@
+function Tbig = divide_by_pot(Tbig, Tsmall)
+% DIVIDE_BY_POT Tbig /= Tsmall
+% Tbig = divide_by_pot(Tbig, Tsmall)
+%
+% Tsmall's domain must be a subset of Tbig's domain.
+
+%process sparse dpot, we do not concern only one of the two pots is sparse
+if issparse(Tbig.T) && issparse(Tsmall.T)
+   Tbig.T = divide_by_sparse_table(Tbig.T, Tbig.domain, Tbig.sizes, Tsmall.T, Tsmall.domain, Tsmall.sizes);
+else
+   Tbig.T = divide_by_table(Tbig.T, Tbig.domain, Tbig.sizes, Tsmall.T, Tsmall.domain, Tsmall.sizes);
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/domain_pot.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/domain_pot.m
new file mode 100644
index 00000000..a67cef02
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/domain_pot.m
@@ -0,0 +1,5 @@
+function dom = domain_pot(pot)
+% DOMAIN_POT Return the domain of this dpot.
+% dom = domain_pot(pot)
+
+dom = pot.domain;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/dpot.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/dpot.m
new file mode 100644
index 00000000..74b5dd9e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/dpot.m
@@ -0,0 +1,26 @@
+function pot = dpot(domain, sizes, T)
+% DPOT Make a discrete (sparse) potential.
+% pot = dpot(domain, sizes, T, spar)
+%
+% sizes(i) is the size of the i'th domain element.
+% T defaults to all 1s.
+
+%assert(length(sizes) == length(domain));
+
+pot.domain = domain(:)'; % so we can see it when we display
+if nargin < 3
+  pot.T = myones(sizes);
+  %pot.T = ones(1,prod(sizes)); % 1D vector
+else 
+   if isempty(T)
+      pot.T = [];
+   else
+      if issparse(T)
+         pot.T = T;   
+      else
+         pot.T = myreshape(T, sizes);  
+      end
+   end
+end
+pot.sizes = sizes(:)';
+pot = class(pot, 'dpot');
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/dpot_to_table.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/dpot_to_table.m
new file mode 100644
index 00000000..bd2d3d98
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/dpot_to_table.m
@@ -0,0 +1,3 @@
+function T = dpot_to_table(pot)
+
+T = pot.T;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/find_most_prob_entry.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/find_most_prob_entry.m
new file mode 100644
index 00000000..d30561a8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/find_most_prob_entry.m
@@ -0,0 +1,10 @@
+function [indices, pot] = find_most_prob_entry(pot)
+% function [indices, pot] = find_most_prob_entry(pot)
+% function [indices, pot] = find_most_prob_entry(pot)
+% Find the indices of the argmax, and set all other enties to 0.
+
+%indices = argmax(pot.T);
+[m i] = max(pot.T(:));
+indices = ind2subv(pot.sizes, i);
+pot.T = 0*myones(pot.sizes);
+pot.T(i) = m;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/get_fields.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/get_fields.m
new file mode 100644
index 00000000..2400bc99
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/get_fields.m
@@ -0,0 +1,13 @@
+function val = get_params(pot, name)
+% GET_PARAMS Accessor function for a field (dpot)
+% val = get_params(pot, name)
+%
+% e.g., get_params(pot, 'table') or 'domain'
+
+switch name
+ case 'table', val = pot.T;
+ case 'domain', val = pot.domain;
+ otherwise,
+  error(['invalid field name ' name]);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/marginalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/marginalize_pot.m
new file mode 100644
index 00000000..d38c5c82
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/marginalize_pot.m
@@ -0,0 +1,17 @@
+function smallpot = marginalize_pot(bigpot, onto, maximize)
+% MARGINALIZE_POT Marginalize a dpot onto a smaller domain.
+% smallpot = marginalize_pot(bigpot, onto, maximize)
+%
+% 'onto' must be in ascending order.
+
+if nargin < 3, maximize = 0; end
+
+ns = zeros(1, max(bigpot.domain));
+ns(bigpot.domain) = bigpot.sizes;
+%assert(isequal(bigpot.sizes, mysize(bigpot.T))); % may fail if there are trailing dimensions of size 1
+if issparse(bigpot.T)
+   smallT = marg_sparse_table(bigpot.T, bigpot.domain, bigpot.sizes, onto, maximize);
+else 
+   smallT = marg_table(bigpot.T, bigpot.domain, bigpot.sizes, onto, maximize);
+end
+smallpot = dpot(onto, ns(onto), smallT);
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/multiply_by_pot.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/multiply_by_pot.m
new file mode 100644
index 00000000..ad7caaa7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/multiply_by_pot.m
@@ -0,0 +1,13 @@
+function Tbig = multiply_by_pot(Tbig, Tsmall)
+% MULTIPLY_BY_POT Tbig *= Tsmall
+% Tbig = multiply_by_pot(Tbig, Tsmall)
+%
+% Tsmall's domain must be a subset of Tbig's domain.
+
+%process sparse dpot, we do not consider only one of the two pots is sparse
+if issparse(Tbig.T) && issparse(Tsmall.T)
+   Tbig.T = mult_by_sparse_table(Tbig.T, Tbig.domain, Tbig.sizes, Tsmall.T, Tsmall.domain, Tsmall.sizes);
+else 
+   Tbig.T = mult_by_table(Tbig.T, Tbig.domain, Tbig.sizes, Tsmall.T, Tsmall.domain, Tsmall.sizes);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/multiply_pots.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/multiply_pots.m
new file mode 100644
index 00000000..0188f01b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/multiply_pots.m
@@ -0,0 +1,12 @@
+function T = multiply_pots(T1, T2)
+% MULTIPLY_POTS Multiply a pair of dpots together pointwise.
+% T = multiply_pots(pots)
+
+dom = myunion(T1.domain, T2.domain);
+%ns = sparse(1, max(dom)); % causes problems in myreshape on NT
+ns = zeros(1, max(dom));
+ns(T1.domain) = T1.sizes;
+ns(T2.domain) = T2.sizes;
+T = dpot(dom, ns(dom));
+T = multiply_by_pot(T, T1);
+T = multiply_by_pot(T, T2);   
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/normalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/normalize_pot.m
new file mode 100644
index 00000000..1bc43cdb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/normalize_pot.m
@@ -0,0 +1,12 @@
+function [pot, loglik] = normalize_pot(pot)
+% NORMALIZE_POT Convert the discrete potential Pr(X,E) into Pr(X|E) and return log Pr(E).
+% [pot, loglik] = normalize_pot(pot)
+
+if isempty(pot.T)  %add to process sparse
+   loglik = 0;
+   return;
+end
+[pot.T, lik] = normalise(pot.T);
+loglik = log(lik + (lik==0)*eps);
+
+      
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/pot_to_marginal.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/pot_to_marginal.m
new file mode 100644
index 00000000..36ed70ea
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/pot_to_marginal.m
@@ -0,0 +1,12 @@
+function m = pot_to_marginal(pot)
+% POT_TO_MARGINAL Convert a dpot to a marginal structure.
+% m = pot_to_marginal(pot)
+
+m.domain = pot.domain;
+m.T = pot.T;
+m.mu = [];
+m.Sigma = [];  
+
+%if isvector(m.T)
+%  m.T = m.T(:);
+%end
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/set_domain_pot.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/set_domain_pot.m
new file mode 100644
index 00000000..2178c51d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/set_domain_pot.m
@@ -0,0 +1,5 @@
+function pot = set_domain_pot(pot, domain)
+% SET_DOMAIN_POT Change the domain of a potential (dpot)
+% pot = set_domain_pot(pot, domain)
+
+pot.domain = domain;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/subsasgn.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/subsasgn.m
new file mode 100644
index 00000000..90d43d70
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/subsasgn.m
@@ -0,0 +1,3 @@
+function B = subsasgn(A, S, B)
+
+B = builtin('subsasgn', A, S, B);
diff --git a/sourcecodes/bnt-master/BNT/potentials/@dpot/subsref.m b/sourcecodes/bnt-master/BNT/potentials/@dpot/subsref.m
new file mode 100644
index 00000000..4a48bffe
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@dpot/subsref.m
@@ -0,0 +1,3 @@
+function B = subsref(A, S)
+
+B = builtin('subsref', A, S);
diff --git a/sourcecodes/bnt-master/BNT/potentials/@mpot/CVS/Entries b/sourcecodes/bnt-master/BNT/potentials/@mpot/CVS/Entries
new file mode 100644
index 00000000..c542af05
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@mpot/CVS/Entries
@@ -0,0 +1,9 @@
+/display.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/marginalize_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/mpot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/mpot_to_cpot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/normalize_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/pot_to_marginal.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/rescale_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/set_domain_pot.m/1.1.1.1/Wed Jul 30 13:37:52 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/potentials/@mpot/CVS/Repository b/sourcecodes/bnt-master/BNT/potentials/@mpot/CVS/Repository
new file mode 100644
index 00000000..1d9311e4
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@mpot/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/potentials/@mpot
diff --git a/sourcecodes/bnt-master/BNT/potentials/@mpot/CVS/Root b/sourcecodes/bnt-master/BNT/potentials/@mpot/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@mpot/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/potentials/@mpot/display.m b/sourcecodes/bnt-master/BNT/potentials/@mpot/display.m
new file mode 100644
index 00000000..90f0e2fc
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@mpot/display.m
@@ -0,0 +1,4 @@
+function display(pot)
+
+disp('moment Gaussian potential object');
+disp(struct(pot));
diff --git a/sourcecodes/bnt-master/BNT/potentials/@mpot/marginalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@mpot/marginalize_pot.m
new file mode 100644
index 00000000..88751c62
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@mpot/marginalize_pot.m
@@ -0,0 +1,27 @@
+function smallpot = marginalize_pot(bigpot, keep, maximize, useC)
+% MARGINALIZE_POT Marginalize a mpot onto a smaller domain.
+% smallpot = marginalize_pot(bigpot, keep, maximize, useC)
+%
+% The maximize argument is ignored - maxing out a Gaussian is the same as summing it out,
+% since the mode and mean are equal.
+% The useC argument is ignored.
+
+
+node_sizes = sparse(1, max(bigpot.domain));
+node_sizes(bigpot.domain) = bigpot.sizes;
+sum_over = mysetdiff(bigpot.domain, keep);
+
+[logp, mu, Sigma] = marginalize_gaussian(bigpot.logp, bigpot.mu, bigpot.Sigma, ...
+					 keep, sum_over, node_sizes);
+smallpot = mpot(keep, node_sizes(keep), logp, mu, Sigma);
+
+%%%%%%
+
+function [logpX, muX, SXX] = marginalize_gaussian(logp, mu, Sigma, X, Y, ns)
+% MARGINALIZE_GAUSSIAN Compute Pr(X) from Pr(X,Y) where X and Y are jointly Gaussian.
+% [logpX, muX, SXX] = marginalize_gaussian(logp, mu, Sigma, X, Y, ns)
+%
+% sizes(i) is the size of the i'th block in domain.
+ 
+[muX, muY, SXX, SXY, SYX, SYY] = partition_matrix_vec(mu, Sigma, X, Y, ns);
+logpX = logp; % Lauritzen (1996) p161          
diff --git a/sourcecodes/bnt-master/BNT/potentials/@mpot/mpot.m b/sourcecodes/bnt-master/BNT/potentials/@mpot/mpot.m
new file mode 100644
index 00000000..1c790f8a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@mpot/mpot.m
@@ -0,0 +1,17 @@
+function pot = mpot(members, sizes, logp, mu, Sigma)
+% MPOT Make a moment Gaussian potential.
+% pot = mpot(members, sizes, logp, mu, Sigma)
+%
+% All params default to 0 if omitted.
+
+n = sum(sizes);
+if nargin < 3, logp = 0; end
+if nargin < 4, mu = zeros(n,1); end
+if nargin < 5, Sigma = zeros(n,n); end
+  
+pot.domain = members;
+pot.sizes = sizes;
+pot.logp = logp;
+pot.mu = mu;
+pot.Sigma = Sigma;zeros(n,n);      
+pot = class(pot, 'mpot');
diff --git a/sourcecodes/bnt-master/BNT/potentials/@mpot/mpot_to_cpot.m b/sourcecodes/bnt-master/BNT/potentials/@mpot/mpot_to_cpot.m
new file mode 100644
index 00000000..ffb3192b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@mpot/mpot_to_cpot.m
@@ -0,0 +1,21 @@
+function can = mpot_to_cpot(mom)
+% MPOT_TO_CPOT Convert a moment potential to canonical form.
+% mom = mpot_to_cpot(can)
+
+[g, h, K] = moment_to_canonical(mom.logp, mom.mu, mom.Sigma);
+can = cpot(mom.domain, mom.sizes, g, h, K);
+
+%%%%%%%%%%%
+
+function [g, h, K] = moment_to_canonical(logp, mu, Sigma)
+% MOMENT_TO_CANONICAL Convert moment characteristics to canonical form.
+% [g, h, K] = moment_to_canonical(logp, mu, Sigma)
+
+K = inv(Sigma);
+h = K*mu;
+n = length(K);
+if isempty(mu)
+  g = logp + 0.5*(log(det(K)) - n*log(2*pi));
+else
+  g = logp + 0.5*(log(det(K)) - n*log(2*pi) - mu'*K*mu);
+end        
diff --git a/sourcecodes/bnt-master/BNT/potentials/@mpot/normalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@mpot/normalize_pot.m
new file mode 100644
index 00000000..a9c2e935
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@mpot/normalize_pot.m
@@ -0,0 +1,6 @@
+function [pot, loglik] = normalize_pot(pot)
+% NORMALIZE_POT Convert the moment potential Pr(X,E) into Pr(X|E) and return log Pr(E).
+% [pot, loglik] = normalize_pot(pot)
+
+loglik = pot.logp;
+pot.logp = 0;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@mpot/pot_to_marginal.m b/sourcecodes/bnt-master/BNT/potentials/@mpot/pot_to_marginal.m
new file mode 100644
index 00000000..b5bd041e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@mpot/pot_to_marginal.m
@@ -0,0 +1,13 @@
+function m = pot_to_marginal(pot)
+% POT_TO_MARGINAL Convert a mpot to a marginal structure.
+% m = pot_to_marginal(pot)
+
+m.domain = pot.domain;
+m.T = exp(pot.logp);
+m.mu = pot.mu;
+m.Sigma = pot.Sigma;
+
+if isvectorBNT(m.T)
+  m.T = m.T(:)';
+end
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@mpot/rescale_pot.m b/sourcecodes/bnt-master/BNT/potentials/@mpot/rescale_pot.m
new file mode 100644
index 00000000..39d1809d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@mpot/rescale_pot.m
@@ -0,0 +1,5 @@
+function pot = rescale_pot(pot, s)
+% RESCALE_POT Add a constant to the mpot scale factor.
+% pot = rescale_pot(pot, s)
+
+pot.logp = pot.logp + s;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@mpot/set_domain_pot.m b/sourcecodes/bnt-master/BNT/potentials/@mpot/set_domain_pot.m
new file mode 100644
index 00000000..91d5a7bb
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@mpot/set_domain_pot.m
@@ -0,0 +1,5 @@
+function pot = set_domain_pot(pot, domain)
+% SET_DOMAIN_POT Change the domain of a potential (mpot)
+% pot = set_domain_pot(pot, domain)
+
+pot.domain = domain;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgcpot/CVS/Entries b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/CVS/Entries
new file mode 100644
index 00000000..d5b4bd91
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/CVS/Entries
@@ -0,0 +1,6 @@
+/marginalize_pot.m/1.1.1.1/Sun May 19 22:11:08 2002//
+/normalize_pot.m/1.1.1.1/Sun May 19 22:11:08 2002//
+/reduce_pot.m/1.1.1.1/Tue Mar 11 17:37:02 2003//
+/rescale_pot.m/1.1.1.1/Sun May 19 22:11:08 2002//
+/scgcpot.m/1.1.1.1/Sun May 19 22:11:08 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgcpot/CVS/Repository b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/CVS/Repository
new file mode 100644
index 00000000..18dc4d80
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/potentials/@scgcpot
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgcpot/CVS/Root b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgcpot/marginalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/marginalize_pot.m
new file mode 100644
index 00000000..c4ca9b68
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/marginalize_pot.m
@@ -0,0 +1,7 @@
+function smallpot = marginalize_pot(bigpot, keepdom, sumoverdom, nodesizes)
+% MARGINALIZE_POT Marginalize a mpot onto a smaller domain.
+% smallpot = marginalize_pot(bigpot, keep)
+
+keepsize = sum(nodesizes(keepdom));
+[A1, A2, B1, B2, C11, C12, C21, C22] = partition_matrix_vec_3(bigpot.A, bigpot.B, bigpot.C, keepdom, sumoverdom, nodesizes);
+smallpot = scgcpot(keepsize, bigpot.ctailsize, bigpot.p, A1, B1, C11);
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgcpot/normalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/normalize_pot.m
new file mode 100644
index 00000000..8900c66e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/normalize_pot.m
@@ -0,0 +1,6 @@
+function [pot, loglik] = normalize_pot(pot)
+% NORMALIZE_POT Convert the element of stable conditional gaussian potential Pr(X,E) into Pr(X|E) and return log Pr(E).
+% [pot, loglik] = normalize_pot(pot)
+
+loglik = log(pot.p);
+pot.p = 1;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgcpot/reduce_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/reduce_pot.m
new file mode 100644
index 00000000..466a7a72
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/reduce_pot.m
@@ -0,0 +1,32 @@
+function [reduced_pot,successful] = reduce(pot,tailnodes)
+% Executes the reduce operation defined in 
+% Stable Local Computation with Conditional Gaussian Distributions
+% Steffen L. Lauritzen
+% Frank Jensen
+% September 1999
+% The potential pot is reduced if B contains any zero columns 
+% The test are restricted to the positions in tailnodes.
+% Any columns successfully deleted are entered in the array successful
+
+if nargin < 2
+    tailnodes = 1:pot.ctailsize;
+end
+
+successful = [];
+
+% Look for all columns beeing equal to zero
+for i = tailnodes
+    if ~any(pot.B(:,i))
+        successful = [successful i]; 
+    end
+end
+
+remain = mysetdiff(1:pot.ctailsize,successful);
+
+% Erase the zero-columns and decrease the tailsize
+pot.B = pot.B(:,remain);
+pot.ctailsize = pot.ctailsize - length(successful);
+
+% Return the reduced potential
+reduced_pot = pot;
+  
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgcpot/rescale_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/rescale_pot.m
new file mode 100644
index 00000000..996a6351
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/rescale_pot.m
@@ -0,0 +1,5 @@
+function pot = rescale_pot(pot, s)
+% RESCALE_POT Add a constant to the mpot scale factor.
+% pot = rescale_pot(pot, s)
+
+pot.p = pot.p*s;
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgcpot/scgcpot.m b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/scgcpot.m
new file mode 100644
index 00000000..6d53a16f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgcpot/scgcpot.m
@@ -0,0 +1,49 @@
+function pot = scgcpot(cheadsize, ctailsize, p, A, B, C)
+% SCGCPOT Make a base object of stable conditional gaussian potential.
+% pot = scgcpot(cheadsize, ctailsize, p, A, B, C)
+%
+% cheadsize is the demension of head nodes.
+% ctailsize is the demension of tail nodes.
+% r = cheadsize, s = ctailsize
+% p is discrete probability.
+% A is table of r*1 vectors;
+% B is r*s matrices
+% C is r*r positive semidefinite symmetric matrices
+
+if nargin < 3
+    p = 1; 
+end
+if nargin < 4
+    A = zeros(cheadsize,1); 
+end
+if nargin < 5
+    B = zeros(cheadsize,ctailsize); 
+end
+if nargin < 6
+    C = zeros(cheadsize,cheadsize); 
+end
+
+if isempty(A)
+    A = zeros(cheadsize,1); 
+end
+if isempty(B)
+    B = zeros(cheadsize,ctailsize); 
+end
+if isempty(C)
+    C = zeros(cheadsize,cheadsize); 
+end
+  
+pot.cheadsize = cheadsize;
+pot.ctailsize = ctailsize;
+
+pot.p = p;
+pot.A = A;
+pot.B = B;
+pot.C = C;
+%if cheadsize == 0
+%   pot.A = [];
+%end
+%if ctailsize == 0
+%    pot.B = [];
+%end
+pot = class(pot, 'scgcpot');
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Entries b/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Entries
new file mode 100644
index 00000000..c990d57d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Entries
@@ -0,0 +1,12 @@
+/README/1.1.1.1/Thu Mar 20 15:07:16 2003//
+/combine_pots.m/1.1.1.1/Tue Mar 11 17:49:28 2003//
+/complement_pot.m/1.1.1.1/Wed May 21 13:49:34 2003//
+/direct_combine_pots.m/1.1.1.1/Sun May 19 22:11:08 2002//
+/extension_pot.m/1.1.1.1/Fri Jan 24 12:52:34 2003//
+/marginalize_pot.m/1.1.1.1/Tue Mar 11 17:06:08 2003//
+/normalize_pot.m/1.1.1.1/Wed May 21 13:49:44 2003//
+/pot_to_marginal.m/1.1.1.1/Sun May 19 22:11:08 2002//
+/recursive_combine_pots.m/1.1.1.1/Wed May 21 13:49:48 2003//
+/reduce_pot.m/1.1.1.1/Tue Mar 11 18:07:12 2003//
+/scgpot.m/1.1.1.1/Tue Mar 11 14:04:48 2003//
+D
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Repository b/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Repository
new file mode 100644
index 00000000..ffef4774
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/potentials/@scgpot
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Root b/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/README b/sourcecodes/bnt-master/BNT/potentials/@scgpot/README
new file mode 100644
index 00000000..1a3c9d16
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/README
@@ -0,0 +1,11 @@
+% Stable conditional Gaussian inference
+% Written by Rainer Deventer
+
+
+@techreport{Lauritzen99,
+  author = "S. Lauritzen and F. Jensen",
+  title = "Stable Local Computation with Conditional {G}aussian Distributions",
+  year = 1999,
+  number = "R-99-2014",
+  institution = "Dept. Math. Sciences, Aalborg Univ."
+}
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/combine_pots.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/combine_pots.m
new file mode 100644
index 00000000..2315176a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/combine_pots.m
@@ -0,0 +1,24 @@
+function pot = combine_pots(pot1, pot2)
+% COMBINE_POTS combine two potentials 
+% pot = combine_pots(pot1, pot2)
+
+% Reduce both potentials before trying to combine them. 
+% Cf. "Stable Local computation with Conditional Gaussian Distributions", page 9
+% Consider again two potentials with minimal tail
+
+% Guarantee minimal tails. If pot1 or pot2 are minimal, they are not changed
+pot1 = reduce_pot(pot1);
+pot2 = reduce_pot(pot2);
+
+%if the intersect set of these two potentials' head conts. combination is undifined
+if ~isempty( myintersect(pot1.cheaddom, pot2.cheaddom) )
+    return;
+end
+
+if  isempty( myintersect(pot1.domain, pot2.cheaddom) ) | isempty( myintersect(pot2.domain, pot1.cheaddom))
+    % if satisfy the condition of directed combine
+    pot = direct_combine_pots(pot1, pot2);
+else
+    % perform recursive combine
+    pot = recursive_combine_pots(pot1, pot2);
+end
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/complement_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/complement_pot.m
new file mode 100644
index 00000000..25f1c1c6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/complement_pot.m
@@ -0,0 +1,221 @@
+function [margpot, comppot] = complement_pot(pot, keep)
+% COMPLEMENT_POT complement means decompose of a potential into its strong marginal and 
+% its complement corresponds exactly to the decomposition of a probability distribution 
+% into its marginal and conditional
+% [margpot, comppot] = complement_pot(pot, keep)
+
+% keep can only include continuous head nodes and discrete nodes
+% margpot is the stable CG potential of keep nodes
+% comppot is the stable CG potential of others in corresponds exactly to 
+% the discomposition of a probability distribution of its marginal and conditional
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Calculation of the marginal requires integration over      %
+% all variables in csumover. Thus cheadkeep contains all     %
+% continuous variables in the marginal potential             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%keyboard;
+csumover = mysetdiff(pot.cheaddom, keep);
+cheadkeep = mysetdiff(pot.cheaddom, csumover);
+
+nodesizes = zeros(1, max(pot.domain));
+nodesizes(pot.ddom) = pot.dsizes;
+nodesizes(pot.cheaddom) = pot.cheadsizes;
+nodesizes(pot.ctaildom) = pot.ctailsizes;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Description of the variables in the marginal domain        %
+% For the calculation of a strong marginal first integration %
+% over all continuous variables in the head takes place.     %
+% The calculation of the marginal over the head variables    %
+% might result in a smaller or empty tail                    %
+% If there are no head variables, and therefore no tail      %
+% variables, left marginalisation over discrete variables    %
+% may take place                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
+margdom      = mysetdiff(pot.domain,keep);
+% margddom   = pot.ddom;
+margcheaddom = cheadkeep;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Marginalisation over discrete variables is only allowed when %
+% the tail is empty                                            %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+margddom = myintersect(pot.ddom,keep);               % Discrete domain of marginal
+margctaildom = myintersect(pot.ctaildom,keep);       % Tail domain
+assert(isempty(mysetdiff(pot.ddom,margddom)) | isempty(margctaildom))  
+
+
+%margctaildom = pot.ctaildom;
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Even if marginalisation over continuous variables is only defined %
+% for head variables, the marginalisation over haed-variables might %
+% result in a smaller tail                                          %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+margctaildom = myintersect(pot.ctaildom,keep);
+
+margcheadsizes = nodesizes(margcheaddom);
+margcheadsize = sum(margcheadsizes);
+margctailsizes = nodesizes(margctaildom);
+margctailsize = sum(margctailsizes);
+
+compdom = pot.domain;
+compddom = pot.ddom;
+compcheaddom = csumover;
+compctaildom = myunion(pot.ctaildom, cheadkeep);
+compcheadsizes = nodesizes(compcheaddom);
+compcheadsize = sum(compcheadsizes);
+compctailsizes = nodesizes(compctaildom);
+compctailsize = sum(compctailsizes);
+
+dkeep = myintersect(pot.ddom, keep);
+%if dom is only contain discrete node
+if isempty(pot.cheaddom)
+    dsumover = mysetdiff(pot.ddom, dkeep);
+    
+    if isempty(dsumover)
+        margpot = pot;
+        comppot = scgpot([], [], [], []);
+        return;
+    end
+        
+    
+    I = prod(nodesizes(dkeep));
+    J = prod(nodesizes(dsumover));
+    sum_map = find_equiv_posns(dsumover, pot.ddom);
+    keep_map = find_equiv_posns(dkeep, pot.ddom);
+    iv = zeros(1, length(pot.ddom)); % index vector
+    p1 = zeros(I,J);
+    for i=1:I
+        keep_iv = ind2subv(nodesizes(dkeep), i);
+        iv(keep_map) = keep_iv;
+        for j=1:J
+            sum_iv = ind2subv(nodesizes(dsumover), j);
+            iv(sum_map) = sum_iv;
+            k = subv2ind(nodesizes(pot.ddom), iv);
+            potc = struct(pot.scgpotc{k}); % violate object privacy
+            p1(i,j) = potc.p;
+        end
+    end
+    p2 = sum(p1,2);
+    p2 = p2 + (p2==0)*eps;
+    
+    margscpot = cell(1, I);
+    compscpot = cell(1, I*J);
+    iv = zeros(1, length(pot.ddom)); % index vector
+    for i=1:I
+        margscpot{i} = scgcpot(0, 0, p2(i));
+        keep_iv = ind2subv(nodesizes(dkeep), i);
+        iv(keep_map) = keep_iv;
+        for j=1:J
+            sum_iv = ind2subv(nodesizes(dsumover), j);
+            iv(sum_map) = sum_iv;
+            k = subv2ind(nodesizes(pot.ddom), iv);
+            q = p1(i,j)/p2(i);
+            compscpot{k} = scgcpot(0, 0, q);
+        end
+    end
+    
+    margpot = scgpot(dkeep, [], [], nodesizes, margscpot);
+    comppot = scgpot(pot.ddom, [], [], nodesizes,compscpot);
+    return;
+end
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% head of the potential is not empty %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+dsize = pot.dsize;
+compscpot = cell(1, dsize);
+
+fmaskh = find_equiv_posns(margcheaddom, compctaildom);
+fmaskt = find_equiv_posns(margctaildom, compctaildom);
+
+fh = block(fmaskh, compctailsizes);
+ft = block(fmaskt, compctailsizes);
+
+
+if ~isempty(margcheaddom)
+    for i=1:dsize
+        potc = struct(pot.scgpotc{i});
+        q = 1;
+        p = potc.p;
+        [A1, A2, B1, B2, C11, C12, C21, C22] = partition_matrix_vec_3(potc.A, potc.B, potc.C, margcheaddom, compcheaddom, nodesizes);
+
+        if ~isempty(margcheaddom)
+            margscpot{i} = scgcpot(margcheadsize, margctailsize, p, A1, B1, C11);
+        else
+            margscpot{i} = scgcpot(margcheadsize, margctailsize, p);
+        end 
+    
+        if ~isempty(compcheaddom)
+            if ~isempty(margcheaddom)
+                E = A2 - C21*pinv(C11)*A1;
+                tmp1 = C21*pinv(C11);
+                tmp2 = B2 - C21*pinv(C11)*B1;
+                F = zeros(compcheadsize, compctailsize);
+                F(:, fh) = tmp1;
+                F(:, ft) = tmp2;
+                G = C22 - C21*pinv(C11)*C12;
+            else
+                E = A2;
+                F = B2;
+                G = C22;
+            end
+            compscpot{i} = scgcpot(compcheadsize, compctailsize, q, E, F, G);
+        else
+            compscpot{i} = scgcpot(compcheadsize, 0, q);
+        end
+        if isempty(margcheaddom)
+            margpot = scgpot(margddom, [], [], nodesizes, margscpot);
+        else
+            margpot = scgpot(margddom, margcheaddom, margctaildom, nodesizes, margscpot);
+        end
+    end
+else
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % Marginalisation took place over all head variables.                               %
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % Calculate the strong marginal %
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    margpot = marginalize_pot(pot,keep);
+    mPot    = struct(margpot); 
+    for i =1:dsize
+        potc = struct(pot.scgpotc{i});  
+        % Get the probability of the original potential % 
+	q = potc.p;
+         
+        % Get the configuration defined by the index i%
+        config = ind2subv(pot.dsizes,i);
+        
+        % Calculate the corresponding configuration in the marginal potential
+        if isempty(margpot.dsizes)
+            % keep == []
+	    indMargPot = 1;
+        else
+            equivPos   = find_equiv_posns(dkeep,pot.ddom);
+            indMargPot = subv2ind(margpot.dsizes,config(equivPos));
+        end
+        % Figure out the corresponding marginal potential
+        mPotC = struct(mPot.scgpotc{indMargPot});
+        p = mPotC.p;
+        if p == 0
+            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+            % The following assignment is correct as p is only zero if q is also zero %
+            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+            compscpot{i} = scgcpot(compcheadsize,compctailsize,0,potc.A,potc.B,potc.C);
+        else
+            compscpot{i} = scgcpot(compcheadsize,compctailsize,q/p,potc.A,potc.B,potc.C);
+        end
+    end
+end
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Put all components in one potential %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+if isempty(compcheaddom)
+    comppot = scgpot(compddom, [], [], nodesizes,compscpot);
+else
+    comppot = scgpot(compddom, compcheaddom, compctaildom, nodesizes,compscpot);
+end
+
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/direct_combine_pots.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/direct_combine_pots.m
new file mode 100644
index 00000000..deeb002d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/direct_combine_pots.m
@@ -0,0 +1,161 @@
+function pot = direct_combine_pots(pot1, pot2)
+% DIRECTED_COMBINE_POTS The combination operation corresponds to ordinary composition of conditional distributions. 
+% In some sense is similar to that of forming disjoint union of set.
+% pot = direct_combine_pots(pot1, pot2)
+
+% directed combine can be performed under the conditon that the head node set of pot1 is disjoint from the domain of 
+% pot2 or vice versa. if the last conditon was satisfied we exchange the pot1 and pot2 firstly then perform the operation.
+% If neither of them was satified the directed combine is undifined.
+
+
+if isempty( myintersect(pot1.domain, pot2.cheaddom) )
+    pot1 = pot1;
+    pot2 = pot2;
+elseif  isempty( myintersect(pot2.domain, pot1.cheaddom))
+    temppot = pot1;
+    pot1 = pot2;
+    pot2 = temppot;
+else
+    assert(0);
+    return;
+end
+
+domain = myunion(pot1.domain, pot2.domain);
+nodesizes = zeros(1,max(domain));
+nodesizes(pot2.ctaildom) = pot2.ctailsizes;
+nodesizes(pot2.cheaddom) = pot2.cheadsizes;
+nodesizes(pot2.ddom) = pot2.dsizes;
+nodesizes(pot1.ctaildom) = pot1.ctailsizes;
+nodesizes(pot1.cheaddom) = pot1.cheadsizes;
+nodesizes(pot1.ddom) = pot1.dsizes;
+
+dom_u = mysetdiff(pot2.ctaildom, pot1.cheaddom);
+if ~isempty(dom_u) & ~mysubset(dom_u, pot1.ctaildom)
+    pot1 = extension_pot(pot1, [], [], dom_u, nodesizes(dom_u));
+end
+
+dom_u = myunion(pot1.cheaddom, pot1.ctaildom);
+if ~isempty(dom_u) & ~mysubset(dom_u, pot2.ctaildom)
+    pot2 = extension_pot(pot2, [], [], dom_u, nodesizes(dom_u));
+end
+
+
+cheaddom = myunion(pot1.cheaddom, pot2.cheaddom);
+ctaildom = mysetdiff(myunion(pot1.ctaildom, pot2.ctaildom), cheaddom);
+cdom = myunion(cheaddom, ctaildom);
+ddom = mysetdiff(domain, cdom);
+dsizes = nodesizes(ddom);
+dsize = prod(nodesizes(ddom));
+cheadsizes = nodesizes(cheaddom);
+cheadsize = sum(nodesizes(cheaddom));
+ctailsizes = nodesizes(ctaildom);
+ctailsize = sum(nodesizes(ctaildom));
+
+r1 = pot1.cheadsize;
+s1 = pot1.ctailsize;
+scpot = cell(1, dsize);
+mask1 = [];
+mask2 = [];
+if ~isempty(pot1.ddom)
+    mask1 = find_equiv_posns(pot1.ddom, ddom);
+end
+if ~isempty(pot2.ddom)
+    mask2 = find_equiv_posns(pot2.ddom, ddom);
+end
+cmask1 = [];
+cmask2 = [];
+if ~isempty(pot1.cheaddom)
+    cmask1 = find_equiv_posns(pot1.cheaddom, cheaddom);
+end
+if ~isempty(pot2.cheaddom)
+    cmask2 = find_equiv_posns(pot2.cheaddom, cheaddom);
+end
+
+u1 = block(cmask1, cheadsizes);
+u2 = block(cmask2, cheadsizes);
+
+fmaskh = find_equiv_posns(pot1.cheaddom, pot2.ctaildom);
+fmaskt = find_equiv_posns(pot1.ctaildom, pot2.ctaildom);
+
+fh = block(fmaskh, pot2.ctailsizes);
+ft = block(fmaskt, pot2.ctailsizes);
+
+for i=1:dsize
+    sub = ind2subv(dsizes, i);
+    sub1 = sub(mask1);
+    sub2 = sub(mask2);
+    ind1 = subv2ind(pot1.dsizes, sub1);
+    ind2 = subv2ind(pot2.dsizes, sub2);
+    
+    if isempty(ind1)
+        ind1 = 1;
+    end
+    if isempty(ind2)
+        ind2 = 1;
+    end
+    potc1 = struct(pot1.scgpotc{ind1});
+    potc2 = struct(pot2.scgpotc{ind2});
+    p = potc1.p;
+    q = potc2.p;
+    ro = p*q;
+    
+    A = potc1.A;
+    B = potc1.B;
+    C = potc1.C;
+   
+    E = potc2.A;
+    F = potc2.B;
+    G = potc2.C;
+    
+    F1 = F(:, fh);
+    F2 = F(:, ft);
+    
+    if ~isempty(F1)
+        K1 = F1*A;
+        K2 = F1*B;
+        FCF = F1*C*F1';
+        FC = F1*C;
+        CFT = C*F1';
+    else
+        K1 = zeros(size(E));
+        K2 = zeros(size(F2));
+        FCF = zeros(size(G));
+        FC = zeros(size(C, 1), size(G, 2));
+        CFT = zeros(size(G, 2), size(C, 1));
+    end
+    
+    
+    U = zeros(cheadsize,1); 
+    W = zeros(cheadsize,cheadsize);
+    V = zeros(cheadsize,ctailsize); 
+    
+    if cheadsize > 0
+        U(u1) = A;
+        U(u2) = E + K1;
+        W(u1, u1) = C;
+        W(u2, u2) = G + FCF;
+        W(u1, u2) = CFT;
+        W(u2, u1) = FC;
+    else
+        U = zeros(cheadsize,1); 
+        W = zeros(cheadsize,cheadsize); 
+    end
+    if cheadsize > 0 | ctailsize > 0
+        if ~isempty(u1)
+            V(u1, :) = B;
+        else
+            V(u1, :) = zeros(potc1.cheadsize, ctailsize);
+        end
+        if ~isempty(u2)
+            V(u2, :) = F2 + K2;
+        else
+            V(u2, :) = zeros(potc2.cheadsize, ctailsize);
+        end
+    else
+        V = zeros(cheadsize,ctailsize); 
+    end
+
+    scpot{i} = scgcpot(cheadsize, ctailsize, ro, U, V, W);
+end
+
+pot = scgpot(ddom, cheaddom, ctaildom, nodesizes, scpot);
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/extension_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/extension_pot.m
new file mode 100644
index 00000000..a4c2b0e6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/extension_pot.m
@@ -0,0 +1,55 @@
+function pot = extension_pot(oldpot, ddom_u, dsizes, ctaildom_u, csizes)
+% EXTENSION_POT Extense a stable CG potential.
+% pot = extension_pot(oldpot, ddom_u, ctaildom_u, dsizes, csizes)
+% ddom_u Added discrete nodes
+% ctaildom_u Added continuous tail nodes
+% csizes is the size of the tail nodes.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% A CG potential can be extended by adding discrete variables to its %
+% domain of continuous variables to its tail                         %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ddom = myunion(oldpot.ddom, ddom_u);
+ctaildom = myunion(oldpot.ctaildom, ctaildom_u);
+cheaddom = oldpot.cheaddom;
+udom = myunion(ddom_u, ctaildom_u);
+domain = myunion(oldpot.domain, udom);
+
+ns = zeros(1,max(domain));
+ns(ddom_u) = dsizes;
+ns(ctaildom_u) = csizes;
+ns(oldpot.ddom) = oldpot.dsizes;
+ns(oldpot.cheaddom) = oldpot.cheadsizes;
+ns(oldpot.ctaildom) = oldpot.ctailsizes;
+
+dsizes = ns(ddom);
+dsize = prod(ns(ddom));
+cheadsizes = ns(cheaddom);
+cheadsize = sum(ns(cheaddom));
+ctailsizes = ns(ctaildom);
+ctailsize = sum(ns(ctaildom));
+
+BZ = zeros(cheadsize, ctailsize);
+potarray = cell(1, dsize);
+mask = find_equiv_posns(oldpot.ddom, ddom);
+
+tmask = find_equiv_posns(oldpot.ctaildom, ctaildom);
+tu = block(tmask, ctailsizes);
+
+for i=1:dsize
+    sub1 = ind2subv(dsizes, i);
+    sub2 = sub1(mask);
+    ind = subv2ind(oldpot.dsizes, sub2);
+    if isempty(ind)
+        ind = 1;
+    end
+    potc = struct(oldpot.scgpotc{ind});
+    p = potc.p;
+    B = BZ;
+    if ~isempty(B)
+        B(:, tu) = potc.B;
+    end
+    potarray{i} = scgcpot(cheadsize, ctailsize, p, potc.A, B, potc.C);
+end
+
+pot = scgpot(ddom, cheaddom, ctaildom, ns,potarray);
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/marginalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/marginalize_pot.m
new file mode 100644
index 00000000..317f9f10
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/marginalize_pot.m
@@ -0,0 +1,92 @@
+function smallpot = marginalize_pot(bigpot, keep)
+% MARGINALIZE_POT Marginalize a cgpot onto a smaller domain.
+% smallpot = marginalize_pot(bigpot, keep)
+
+sumover = mysetdiff(bigpot.domain, keep);
+cdom = myunion(bigpot.cheaddom, bigpot.ctaildom);
+csumover = myintersect(sumover, bigpot.cheaddom);
+dsumover = myintersect(sumover, bigpot.ddom);
+
+dkeep = myintersect(keep, bigpot.ddom);
+ckeep = myintersect(keep, bigpot.cheaddom);
+cheaddom = myintersect(keep, bigpot.cheaddom);
+
+assert(isempty(myintersect(csumover,bigpot.ctaildom)));
+ns = zeros(1, max(bigpot.domain));
+ns(bigpot.ddom) = bigpot.dsizes;
+ns(bigpot.cheaddom) = bigpot.cheadsizes;
+ns(bigpot.ctaildom) = bigpot.ctailsizes;
+
+
+if sum(ns(csumover)) > 0
+    for i=1:bigpot.dsize
+      bigpot.scgpotc{i} = marginalize_pot(bigpot.scgpotc{i}, ckeep, csumover, ns);
+    end
+end
+
+if (isequal(csumover, cheaddom))
+    bigpot.ctaildom = [];
+end
+% If we are not marginalizing over any discrete nodes, we are done.
+if prod(ns(dsumover))==1
+  smallpot = scgpot(dkeep, cheaddom, bigpot.ctaildom, ns, bigpot.scgpotc);
+  return;
+end
+
+if (~isempty(bigpot.ctaildom))
+    assert(0);
+    return;
+end
+
+I = prod(ns(dkeep));
+J = prod(ns(dsumover));
+C = sum(ns(ckeep));   
+sum_map = find_equiv_posns(dsumover, bigpot.ddom);
+keep_map = find_equiv_posns(dkeep, bigpot.ddom);
+iv = zeros(1, length(bigpot.ddom)); % index vector
+
+p1 = zeros(I,J);
+A1 = zeros(C,J,I);
+C1 = zeros(C,C,J,I);
+for i=1:I
+  keep_iv = ind2subv(ns(dkeep), i);
+  iv(keep_map) = keep_iv;
+  for j=1:J
+    sum_iv = ind2subv(ns(dsumover), j);
+    iv(sum_map) = sum_iv;
+    k = subv2ind(ns(bigpot.ddom), iv);
+    pot = struct(bigpot.scgpotc{k}); % violate object privacy
+    p1(i,j) = pot.p;
+    if C > 0 % so mu1 and Sigma1 are non-empty
+      A1(:,j,i) = pot.A;
+      C1(:,:,j,i) = pot.C;
+    end
+  end
+end
+
+% Collapse the mixture of Gaussians
+coef = mk_stochastic(p1); % coef must be convex combination
+%keyboard
+p2 = sum(p1,2);
+if (all(p2 == 0))
+    p2 = p2 + (p2==0)*eps;
+end
+A = [];
+S = [];
+
+pot = cell(1,I);
+ctailsize = sum(ns(bigpot.ctaildom));
+tB = zeros(C, ctailsize);
+for i=1:I
+  if C > 0
+    [A, S] = collapse_mog(A1(:,:,i), C1(:,:,:,i), coef(i,:));
+  end
+  p = p2(i);
+  pot{i} = scgcpot(C, ctailsize, p, A, tB, S);
+end
+
+smallpot = scgpot(dkeep, ckeep, bigpot.ctaildom, ns, pot);
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/normalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/normalize_pot.m
new file mode 100644
index 00000000..da265ef5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/normalize_pot.m
@@ -0,0 +1,16 @@
+function [pot, loglik] = normalize_pot(pot)
+% NORMALIZE_POT Convert the SCG potential Pr(X,E) into Pr(X|E) and return log Pr(E).
+% [pot, loglik] = normalize_pot(pot)
+
+% Marginalize down to [], so that the normalizing constant becomes Pr(E)
+temp = marginalize_pot(pot, []);
+[temp2, loglik] = normalize_pot(temp.scgpotc{1});
+  
+% Adjust scale factor to reflect the fact that the pot now represents Pr(X | E) instead of Pr(X,E).
+
+scale = -loglik;
+if 1
+    for i=1:pot.dsize
+        pot.scgpotc{i} = rescale_pot( pot.scgpotc{i}, scale);
+    end
+end
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/pot_to_marginal.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/pot_to_marginal.m
new file mode 100644
index 00000000..f7478ef8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/pot_to_marginal.m
@@ -0,0 +1,29 @@
+function m = pot_to_marginal(pot)
+% POT_TO_MARGINAL Convert a scgpot to a marginal structure.
+% m = pot_to_marginal(pot)
+
+assert(isempty(pot.ctaildom))
+m.domain = pot.domain;
+n = pot.cheadsize;
+d = pot.dsize;
+
+if n==0
+  m.mu = [];
+  m.Sigma = [];
+else
+  m.mu = zeros(n, d);
+  m.Sigma = zeros(n, n, d);
+end
+%m.T = 0*myones(pot.dsizes);
+m.T = 0*myones(pot.dsize);
+for i=1:pot.dsize
+  potc = struct(pot.scgpotc{i}); % violate privacy of object
+  if n > 0
+    m.mu(:,i) = potc.A;
+    m.Sigma(:,:,i) = potc.C;
+  end
+  m.T(i) = potc.p;
+end     
+if isvectorBNT(m.T)
+  m.T = m.T(:)';
+end
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/recursive_combine_pots.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/recursive_combine_pots.m
new file mode 100644
index 00000000..27c04b75
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/recursive_combine_pots.m
@@ -0,0 +1,40 @@
+function pot = recursive_combine_pots(pot1, pot2)
+% RECURSIVE_COMBINE_POTS recursive combine two potentials
+% pot = recursive_combine_pots(pot1, pot2)
+
+pot1 = reduce_pot(pot1);
+pot2 = reduce_pot(pot2);
+% Recursion is stopped, if recusive-combination is defined by direct combination, 
+% i.e. if the domain of one potential is disjoint from the head of the other.
+if (isempty(myintersect(pot1.domain,pot2.cheaddom))|...
+    isempty(myintersect(pot1.cheaddom,pot2.domain)))    
+    pot = direct_combine_pots(pot1,pot2);
+else 
+    % Test wether one of the set-differences is not empty 
+    % as defined in Lauritzen99 "Stable Local Computation with Conditional Gaussian Distributions"
+    % on page 9
+    D12 = mysetdiff(pot1.cheaddom, pot2.domain);
+    D21 = mysetdiff(pot2.cheaddom, pot1.domain);
+    if (isempty(D12) & isempty(D21))
+       assert(0,'Recursive combination is not defined');
+    end
+
+    if ~isempty(D12)
+        % Calculate the complementary potential for the set 
+        % D1\D12 as defined in Lauritzen 99, page 9
+    keep = mysetdiff(pot1.domain,D12);
+        [margpot, comppot] = complement_pot(pot1,keep);
+        margpot = reduce_pot(margpot);
+        comppot = reduce_pot(comppot);
+        pot = direct_combine_pots( recursive_combine_pots(margpot, pot2), comppot);
+    elseif ~isempty(D21)
+        keep = mysetdiff(pot2.domain,D21);
+        [margpot, comppot] = complement_pot(pot2,D21);
+        margpot = reduce_pot(margpot);
+        comppot = reduce_pot(comppot);
+        pot = direct_combine_pots( recursive_combine_pots(pot1, margpot), comppot);
+    end
+end
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/reduce_pot.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/reduce_pot.m
new file mode 100644
index 00000000..7ee4ab49
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/reduce_pot.m
@@ -0,0 +1,53 @@
+function [reduced_pot,successful] = reduce_pot(pot,tailnodes)
+% Executes the reduce operation defined in
+% Stable Local Computation with Conditional Gaussian Distributions
+% Steffen L. Lauritzen
+% Frank Jensen
+% September 1999
+% The potential pot is reduced if B contains any zero columns
+% The test are restricted to the positions in tailnodes.
+% Any columns successfully deleted are entered in the array successful
+if nargin < 2
+    tailnodes = pot.ctaildom;
+end
+
+successful = [];
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Keep track of remaining tailnodes %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+rem_tailnodes = pot.ctaildom;
+for i = tailnodes
+    pos = find(i==rem_tailnodes);
+    successful_red = [pos];
+    red_scgcpot = cell(1,pot.dsize);
+    j = 1;
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % Test whether all components of pot.scgpotc can be reduced %
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    while ((j <= pot.dsize) & ~isempty(successful_red))
+        [cpot,successful_red] = reduce_pot(pot.scgpotc{j},pos);
+        red_scgcpot{j} = cpot;
+        j = j + 1;
+    end
+
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    % If i is a reducible tailnode, then reduce the potential %
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    if ~isempty(successful_red)
+        successful = [successful i];
+        pot.scgpotc = red_scgcpot;
+        rem_tailnodes = mysetdiff(rem_tailnodes,i);
+    end;
+end
+
+pot.ctaildom = rem_tailnodes;
+positions = find_equiv_posns(rem_tailnodes,pot.ctaildom);
+pot.ctailsizes = pot.ctailsizes(positions);
+pot.ctailsize = sum(pot.ctailsizes);
+pot.domain = mysetdiff(pot.domain,successful);
+reduced_pot = pot;
+
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@scgpot/scgpot.m b/sourcecodes/bnt-master/BNT/potentials/@scgpot/scgpot.m
new file mode 100644
index 00000000..7f923f22
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@scgpot/scgpot.m
@@ -0,0 +1,30 @@
+function pot = scgpot(ddom, cheaddom, ctaildom, node_sizes, scgpotc)
+% SCGPOT Make a stable CG potential.
+% pot = scgpot(ddom, cheaddom, ctaildom, node_sizes, scgpotc)
+%
+% ddom is discrete nodes contains in the potential
+% cheaddom is head nodes constains in the potential
+% ctaildom is tail nodes contains in the potential
+% node_sizes(i) is the size of the i'th node.
+% scgpotc is list of scgcpot objects.
+
+pot.ddom = ddom;
+pot.cheaddom = cheaddom;
+pot.ctaildom = ctaildom;
+pot.domain = myunion(ddom, myunion(cheaddom, ctaildom));
+pot.dsizes = node_sizes(pot.ddom);
+pot.dsize = prod(node_sizes(pot.ddom));
+pot.cheadsizes = node_sizes(pot.cheaddom);
+pot.cheadsize = sum(node_sizes(pot.cheaddom));
+pot.ctailsizes = node_sizes(pot.ctaildom);
+pot.ctailsize = sum(node_sizes(pot.ctaildom));
+
+if nargin < 5
+    scgpotc = cell(1, pot.dsize);
+    for i=1:pot.dsize
+        scgpotc{i} = scgcpot(pot.cheadsize, pot.ctailsize);
+    end
+end
+pot.scgpotc = scgpotc;              
+
+pot = class(pot, 'scgpot');
diff --git a/sourcecodes/bnt-master/BNT/potentials/@upot/CVS/Entries b/sourcecodes/bnt-master/BNT/potentials/@upot/CVS/Entries
new file mode 100644
index 00000000..25bc0a31
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@upot/CVS/Entries
@@ -0,0 +1,10 @@
+/approxeq_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/display.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/divide_by_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/marginalize_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/multiply_by_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/normalize_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/pot_to_marginal.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/upot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/upot_to_opt_policy.m/1.1.1.1/Wed May 29 15:59:58 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/potentials/@upot/CVS/Repository b/sourcecodes/bnt-master/BNT/potentials/@upot/CVS/Repository
new file mode 100644
index 00000000..b7cf8acd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@upot/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/potentials/@upot
diff --git a/sourcecodes/bnt-master/BNT/potentials/@upot/CVS/Root b/sourcecodes/bnt-master/BNT/potentials/@upot/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@upot/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/potentials/@upot/approxeq_pot.m b/sourcecodes/bnt-master/BNT/potentials/@upot/approxeq_pot.m
new file mode 100644
index 00000000..de47ee12
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@upot/approxeq_pot.m
@@ -0,0 +1,5 @@
+function p = approxeq_pot(A, B, tol)
+
+if nargin < 3, tol = 1e-3; end
+
+p = approxeq(A.p, B.p, tol) & approxeq(A.u, B.u, tol);
diff --git a/sourcecodes/bnt-master/BNT/potentials/@upot/display.m b/sourcecodes/bnt-master/BNT/potentials/@upot/display.m
new file mode 100644
index 00000000..bb8e76e9
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@upot/display.m
@@ -0,0 +1,4 @@
+function display(pot)
+
+disp('utility potential object');
+disp(struct(pot));
diff --git a/sourcecodes/bnt-master/BNT/potentials/@upot/divide_by_pot.m b/sourcecodes/bnt-master/BNT/potentials/@upot/divide_by_pot.m
new file mode 100644
index 00000000..8ac75785
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@upot/divide_by_pot.m
@@ -0,0 +1,13 @@
+function Tbig = divide_by_pot(Tbig, Tsmall)
+% DIVIDE_BY_POT Tbig /= Tsmall
+% Tbig = divide_by_pot(Tbig, Tsmall)
+%
+% Tsmall's domain must be a subset of Tbig's domain.
+
+smallp = extend_domain_table(Tsmall.p, Tsmall.domain, Tsmall.sizes, Tbig.domain, Tbig.sizes);
+smallp = smallp + (smallp==0);
+Tbig.p = Tbig.p ./ smallp;
+
+smallu = extend_domain_table(Tsmall.u, Tsmall.domain, Tsmall.sizes, Tbig.domain, Tbig.sizes);
+Tbig.u = Tbig.u - smallu;
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@upot/marginalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@upot/marginalize_pot.m
new file mode 100644
index 00000000..be4bf249
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@upot/marginalize_pot.m
@@ -0,0 +1,18 @@
+function smallpot = marginalize_pot(bigpot, onto, maximize)
+% MARGINALIZE_POT Marginalize a upot onto a smaller domain.
+% smallpot = marginalize_pot(bigpot, onto, maximize)
+%
+% The maximize argument is ignored
+
+numer = marg_table(bigpot.p .* bigpot.u, bigpot.domain, bigpot.sizes, onto);
+denom = marg_table(bigpot.p, bigpot.domain, bigpot.sizes, onto);
+
+p = denom;
+% replace 0s by 1s before dividing. This is valid since demon(i) = 0 => numer(i) = 0
+denom = denom + (denom == 0); 
+u = numer ./ denom;
+
+ns = zeros(1, max(bigpot.domain));
+ns(bigpot.domain) = bigpot.sizes;
+
+smallpot = upot(onto, ns(onto), p, u);
diff --git a/sourcecodes/bnt-master/BNT/potentials/@upot/multiply_by_pot.m b/sourcecodes/bnt-master/BNT/potentials/@upot/multiply_by_pot.m
new file mode 100644
index 00000000..28b3586d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@upot/multiply_by_pot.m
@@ -0,0 +1,12 @@
+function Tbig = multiply_by_pot(Tbig, Tsmall)
+% MULTIPLY_BY_POT Tbig *= Tsmall
+% Tbig = multiply_by_pot(Tbig, Tsmall)
+%
+% Tsmall's domain must be a subset of Tbig's domain.
+
+smallp = extend_domain_table(Tsmall.p, Tsmall.domain, Tsmall.sizes, Tbig.domain, Tbig.sizes);
+Tbig.p = Tbig.p .* smallp;
+
+smallu = extend_domain_table(Tsmall.u, Tsmall.domain, Tsmall.sizes, Tbig.domain, Tbig.sizes);
+Tbig.u = Tbig.u + smallu;
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/@upot/normalize_pot.m b/sourcecodes/bnt-master/BNT/potentials/@upot/normalize_pot.m
new file mode 100644
index 00000000..dc3dfa8a
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@upot/normalize_pot.m
@@ -0,0 +1,13 @@
+function [pot, loglik] = normalize_pot(pot)
+% NORMALIZE_POT Convert the probability part of a utility potential
+% [pot, loglik] = normalize_pot(pot)
+
+[pot.p, lik] = normalise(pot.p);
+%pot.u = pot.u - sum(pot.u(:));
+%pot.u = pot.u ./ sum(pot.u(:)); % same as normalise(pot.u)
+%pot.u = normalise(pot.u);
+%pot.u = pot.u / 726.8121;
+pot.u = pot.u / 10;
+loglik = log(lik + (lik==0)*eps);
+
+      
diff --git a/sourcecodes/bnt-master/BNT/potentials/@upot/pot_to_marginal.m b/sourcecodes/bnt-master/BNT/potentials/@upot/pot_to_marginal.m
new file mode 100644
index 00000000..4d3a1c37
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@upot/pot_to_marginal.m
@@ -0,0 +1,9 @@
+function m = pot_to_marginal(pot)
+% POT_TO_MARGINAL Convert a upot to a structure.
+% m = pot_to_marginal(pot)
+
+m.domain = pot.domain;
+m.T = pot.p;
+m.U = pot.u;
+
+    
diff --git a/sourcecodes/bnt-master/BNT/potentials/@upot/upot.m b/sourcecodes/bnt-master/BNT/potentials/@upot/upot.m
new file mode 100644
index 00000000..502858b8
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@upot/upot.m
@@ -0,0 +1,15 @@
+function pot = upot(domain, sizes, p, u)
+% UPOT Make a discrete utility potential.
+% pot = upot(domain, sizes, p, u)
+%
+% sizes(i) is the size of the i'th domain element.
+% p defaults to all 1s, u defaults to all 0s.
+
+if nargin < 3, p = myones(sizes); end
+if nargin < 4, u = 0*myones(sizes); end
+
+pot.domain = domain;
+pot.p = myreshape(p, sizes);
+pot.u = myreshape(u, sizes);
+pot.sizes = sizes(:)';
+pot = class(pot, 'upot');
diff --git a/sourcecodes/bnt-master/BNT/potentials/@upot/upot_to_opt_policy.m b/sourcecodes/bnt-master/BNT/potentials/@upot/upot_to_opt_policy.m
new file mode 100644
index 00000000..20f8d2ec
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/@upot/upot_to_opt_policy.m
@@ -0,0 +1,25 @@
+function [policy, EU] = upot_to_opt_policy(pot)
+% UPOT_TO_OPT_POLICY Compute an optimal deterministic policy given a utility potential
+% [policy, EU] = upot_to_opt_policy(pot)
+%
+% policy(a,b, ..., z) = P(do z | a, b, ..), which will be a delta function
+% EU is the contraction of this potential, i.e., P .* U
+
+sz = pot.sizes; % mysize(pot.p);
+if isempty(sz)
+  EU = pot.u;
+  policy = [];
+  return;
+end
+
+parent_size = prod(sz(1:end-1));
+self_size = sz(end); 
+C = pot.p .* pot.u; % contraction
+C = reshape(C, parent_size, self_size);
+policy = zeros(parent_size, self_size);
+for i=1:parent_size
+  act = argmax(C(i,:));
+  policy(i, act) = 1;
+end
+policy = myreshape(policy, sz);
+EU = sum(C(:));
diff --git a/sourcecodes/bnt-master/BNT/potentials/CPD_to_pot.m b/sourcecodes/bnt-master/BNT/potentials/CPD_to_pot.m
new file mode 100644
index 00000000..8d0aa3ce
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/CPD_to_pot.m
@@ -0,0 +1,21 @@
+function pot = CPD_to_pot(pot_type, CPD, domain, ns, cnodes, evidence)
+% CPD_TO_POT Convert a CPD to a potential of the specified form, incorporating any evidence
+% pot = CPD_to_pot(pot_type, CPD, domain, node_sizes, cnodes, evidence)
+%
+% pot_type is one of 'd', 'g', or 'cg'.
+% domain is the domain of CPD.
+% node_sizes(i) is the size of node i.
+% cnodes = the cts nodes
+% evidence{i} is the evidence on the i'th node.
+
+switch pot_type
+ case 'd',
+  pot = CPD_to_dpot(CPD, domain, ns, cnodes, evidence);
+ case 'g',
+  pot = CPD_to_cpot(CPD, domain, ns, cnodes, evidence);
+ case 'cg',
+  pot = CPD_to_cgpot(CPD, domain, ns, cnodes, evidence);
+ otherwise,
+  error(['can''t handle pot_type ' pot_type]);
+end
+              
diff --git a/sourcecodes/bnt-master/BNT/potentials/CVS/Entries b/sourcecodes/bnt-master/BNT/potentials/CVS/Entries
new file mode 100644
index 00000000..bfef35ea
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/CVS/Entries
@@ -0,0 +1,7 @@
+/CPD_to_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/README/1.1.1.1/Wed May 29 15:59:58 2002//
+/check_for_cd_arcs.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/determine_pot_type.m/1.1.1.1/Wed May 29 15:59:58 2002//
+/genops.c/1.1.1.1/Sat Jul 28 15:43:40 2001//
+/mk_initial_pot.m/1.1.1.1/Wed May 29 15:59:58 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/potentials/CVS/Entries.Log b/sourcecodes/bnt-master/BNT/potentials/CVS/Entries.Log
new file mode 100644
index 00000000..35415310
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/CVS/Entries.Log
@@ -0,0 +1,9 @@
+A D/@cgpot////
+A D/@cpot////
+A D/@dpot////
+A D/@mpot////
+A D/@scgcpot////
+A D/@scgpot////
+A D/@upot////
+A D/Old////
+A D/Tables////
diff --git a/sourcecodes/bnt-master/BNT/potentials/CVS/Repository b/sourcecodes/bnt-master/BNT/potentials/CVS/Repository
new file mode 100644
index 00000000..3517a1ca
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/potentials
diff --git a/sourcecodes/bnt-master/BNT/potentials/CVS/Root b/sourcecodes/bnt-master/BNT/potentials/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/potentials/Old/CVS/Entries b/sourcecodes/bnt-master/BNT/potentials/Old/CVS/Entries
new file mode 100644
index 00000000..e7d041f1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Old/CVS/Entries
@@ -0,0 +1,2 @@
+/comp_eff_node_sizes.m/1.1.1.1/Wed May 29 15:59:58 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/potentials/Old/CVS/Repository b/sourcecodes/bnt-master/BNT/potentials/Old/CVS/Repository
new file mode 100644
index 00000000..48670656
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Old/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/potentials/Old
diff --git a/sourcecodes/bnt-master/BNT/potentials/Old/CVS/Root b/sourcecodes/bnt-master/BNT/potentials/Old/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Old/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/potentials/Old/comp_eff_node_sizes.m b/sourcecodes/bnt-master/BNT/potentials/Old/comp_eff_node_sizes.m
new file mode 100644
index 00000000..e245f602
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Old/comp_eff_node_sizes.m
@@ -0,0 +1,11 @@
+function ens = comp_eff_node_sizes(ns, cnodes, ev, domain)
+
+dnodes = mysetdiff(1:length(ns), cnodes);
+odom = domain(~isemptycell(evidence(domain)));
+cdom = myintersect(cnodes, domain);
+ddom = myintersect(dnodes, domain);
+cobs = myintersect(cdom, odom);
+dobs = myintersect(ddom, odom);
+ens = ns; 
+ens(cobs) = 0;
+ens(dobs) = 1;
diff --git a/sourcecodes/bnt-master/BNT/potentials/README b/sourcecodes/bnt-master/BNT/potentials/README
new file mode 100644
index 00000000..116266ee
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/README
@@ -0,0 +1,100 @@
+The following kinds of potentials are supported
+- dpot: discrete
+- upot: utility
+- mpot: Gaussian in moment form
+- cpot: Gaussian in canonical form
+- cgpot: conditional (mixture) Gaussian, a list of mpots/cpot
+- scgpot: stable conditional Gaussian, a list of scgcpots
+- scgcpot: just used by scgpot
+
+Many of these are described in the following book
+
+@book{Cowell99,
+  author = "R. G. Cowell and A. P. Dawid and S. L. Lauritzen and D. J. Spiegelhalter",
+  title = "Probabilistic Networks and Expert Systems",
+  year = 1999,
+  publisher = "Springer"
+}
+
+CPD_to_pot converts P(Z|A,B,...) to phi(A,B,...,Z).
+
+A table is like a dpot, except it is a structure, not an object.
+Code that uses tables is faster but less flexible.
+
+                         -----------
+
+A potential is a joint probability distribution on a set of nodes,
+which we call the potential's domain (which is always sorted).
+A potential supports the operations of multiplication and
+marginalization.
+
+If the nodes are discrete, the potential can be represented as a table
+(multi-dimensional array). If the nodes are Gaussian, the potential
+can be represented as a quadratic form. If there are both discrete and
+Gaussian nodes, we use a table of quadratic forms. For details on the
+Gaussian case, see below.
+
+For discrete potentials, the 'sizes' field specifies the number of
+values each node in the domain can take on. For continuous potentials,
+the 'sizes' field specifies the block-size of each node.
+
+If some of the nodes are observed, extra complications arise.  We
+handle the discrete and continuous cases differently.  Suppose the
+domain is [X Y], with sizes [6 2], where X is observed to have value x.
+In the discrete case, the potential will have many zeros in it
+(T(X,:) will be 0 for all X ~= x), which can be inefficient. Instead,
+we set sizes to [1 2], to indicate that X has only one possible value
+(namely x). For continuous nodes, we set sizes = [0 2], to indicate that X no
+longer appears in the mean vector or covariance matrix (we must avoid
+0s in Sigma, lest it be uninvertible). When a potential is created, we
+assume the sizes of the nodes have been adjusted to include the
+evidence. This is so that the evidence can be incorporated at the
+outset, and thereafter the inference algorithms can ignore it.
+
+                         ------------
+
+A Gaussian potential can be represented in terms of its
+moment characteristics (mu, Sigma, logp), or in terms of its canonical
+characteristics (g, h, K). Although the moment characteristics are
+more familiar, it turns out that canonical characteristics are
+more convenient for the junction tree algorithm, for the same kinds of
+reasons why backwards inference in an LDS uses the information form of
+the Kalman filter (see Murphy (1998a) for a discussion).
+
+When working with *conditional* Gaussian potentials, the method proposed
+by Lauritzen (1992), and implemented here, requires converting from
+canonical to moment form before marginalizing the discrete variables,
+and converting back from moment to canonical form before
+multiplying/dividing. A new algorithm, due to Lauritzen and Jensen
+(1999), works exclusively in moment form, and
+hence is more numerically stable. It can also handle 0s in the
+covariance matrix, i.e., deterministic relationships between cts
+variables. However, it has not yet been implemented,
+since it requires major changes to the jtree algorithm.
+
+In Murphy (1998b) we extend Lauritzen (1992) to handle
+vector-valued nodes. This means the vectors and matrices become block
+vectors and matrices. This manifests itself in the code as in the
+following example.
+Suppose we have a potential on nodes dom=[3,4,7] with block sizes=[2,1,3].
+Then nodes 3 and 7 correspond to blocks 1,3 which correspond to indices 1,2,4,5,6.
+>> find_equiv_posns([3 7], dom)=[1,3]
+>> block([1,3],blocks)=[1,2,4,5,6].
+
+For more details, see
+
+- "Filtering and Smoothing in Linear Dynamical Systems using the Junction Tree Algorithm",
+   K. Murphy, 1998a. UCB Tech Report.
+
+- "Inference and learning in hybrid Bayesian networks",
+   K. Murphy. UCB Technical Report CSD-98-990, 1998b.
+
+- "Propagation of probabilities, means and variances in mixed
+  graphical association models", S. L. Lauritzen, 1992, JASA 87(420):1098--1108.
+
+- "Causal probabilistic networks with both discrete and continuous variables",
+  K. G. Olesen, 1993. PAMI 3(15). This discusses implementation details.
+
+- "Stable local computation with Conditional Gaussian distributions",
+  S. Lauritzen and F. Jensen, 1999. Univ. Aalborg Tech Report R-99-2014.
+  www.math.auc.dk/research/Reports.html.
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/CVS/Entries b/sourcecodes/bnt-master/BNT/potentials/Tables/CVS/Entries
new file mode 100644
index 00000000..f550f801
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/CVS/Entries
@@ -0,0 +1,19 @@
+/divide_by_sparse_table.c/1.1.1.1/Wed May 29 15:59:58 2002//
+/divide_by_table.c/1.1.1.1/Wed May 29 15:59:58 2002//
+/divide_by_table.m/1.1.1.1/Thu Aug  5 15:25:54 2004//
+/extend_domain_table.m/1.1.1.1/Wed Aug  4 15:53:26 2004//
+/marg_sparse_table.c/1.1.1.1/Wed May 29 15:59:58 2002//
+/marg_table.c/1.1.1.1/Wed May 29 15:59:58 2002//
+/marg_table.m/1.1.1.1/Wed Aug  4 15:51:48 2004//
+/marg_tableC.c/1.1.1.1/Wed Oct  2 15:39:02 2002//
+/marg_tableM.m/1.1.1.1/Tue Oct  1 17:39:08 2002//
+/mult_by_sparse_table.c/1.1.1.1/Wed May 29 15:59:58 2002//
+/mult_by_table.c/1.1.1.1/Tue Oct  1 21:23:22 2002//
+/mult_by_table.m/1.1.1.1/Wed Aug  4 15:52:58 2004//
+/mult_by_table2.m/1.1.1.1/Wed Oct  2 15:30:32 2002//
+/mult_by_tableC.c/1.1.1.1/Tue Oct  1 21:33:50 2002//
+/mult_by_tableM.m/1.1.1.1/Wed Oct  2 15:28:48 2002//
+/mult_by_table_global.m/1.1.1.1/Sun Sep 29 10:21:30 2002//
+/rep_mult.c/1.1.1.1/Wed May 29 15:59:58 2002//
+/repmat_and_mult.c/1.1.1.1/Tue Oct  1 21:20:00 2002//
+D
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/CVS/Repository b/sourcecodes/bnt-master/BNT/potentials/Tables/CVS/Repository
new file mode 100644
index 00000000..e52428a3
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/BNT/potentials/Tables
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/CVS/Root b/sourcecodes/bnt-master/BNT/potentials/Tables/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/divide_by_sparse_table.c b/sourcecodes/bnt-master/BNT/potentials/Tables/divide_by_sparse_table.c
new file mode 100644
index 00000000..d7645ab1
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/divide_by_sparse_table.c
@@ -0,0 +1,126 @@
+/* divide_by_sparse_table.c ../potential/tables*/
+
+/******************************************/
+/* 6 input & 1 output                     */
+/* Big table    [0]                       */
+/* Big domain   [1]                       */
+/* big sizes    [2]                       */
+/* Small table  [3]                       */
+/* small domain [4]                       */
+/* small sizes  [5]                       */
+/*                                        */
+/* New big table[0]                       */
+/******************************************/
+
+#include <math.h>
+#include <stdlib.h>
+#include "mex.h"
+
+int compare(const void* src1, const void* src2){
+	int i1 = *(int*)src1 ;
+	int i2 = *(int*)src2 ;
+	return i1-i2 ;
+}
+
+void ind_subv(int index, const int *cumprod, int n, int *bsubv){
+	int i;
+
+	for (i = n-1; i >= 0; i--) {
+		bsubv[i] = ((int)floor(index / cumprod[i]));
+		index = index % cumprod[i];
+	}
+}
+
+int subv_ind(const int n, const int *cumprod, const int *subv){
+	int i, index=0;
+
+	for(i=0; i<n; i++){
+		index += subv[i] * cumprod[i];
+	}
+	return index;
+}
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int     i, j, count, bdim, sdim, NB, NZB, NZS, position, bindex, sindex;
+	int     *mask, *result, *bir, *sir, *bjc, *sjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, value;
+
+	plhs[0] = mxDuplicateArray(prhs[0]);
+	pbDomain = mxGetPr(prhs[1]);
+	bdim = mxGetNumberOfElements(prhs[1]);
+	psDomain = mxGetPr(prhs[4]);
+	sdim = mxGetNumberOfElements(prhs[4]);
+
+	pbSize = mxGetPr(prhs[2]);
+	psSize = mxGetPr(prhs[5]);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	bpr = mxGetPr(plhs[0]);
+	bir = mxGetIr(plhs[0]);
+	bjc = mxGetJc(plhs[0]);
+	NZB = bjc[1];
+
+	spr = mxGetPr(prhs[3]);
+	sir = mxGetIr(prhs[3]);
+	sjc = mxGetJc(prhs[3]);
+	NZS = sjc[1];
+
+	if(sdim == 0){
+		value = *spr;
+		if(value == 0)value = 1;
+		for(i=0; i<NZB; i++){
+			bpr[i] /= value;
+		}	
+		return;
+	}
+
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sir, NZS, sizeof(int), compare);
+		if(result){
+			position = result - sir;
+			bpr[i] /= spr[position];
+		}
+	}
+
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/divide_by_table.c b/sourcecodes/bnt-master/BNT/potentials/Tables/divide_by_table.c
new file mode 100644
index 00000000..6942eddd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/divide_by_table.c
@@ -0,0 +1,120 @@
+/* divide_by_table.c  ../potential/tables  */
+
+
+/******************************************/
+/* 6 input & 1 output                     */
+/* Big table    [0]                       */
+/* Big domain   [1]                       */
+/* big sizes    [2]                       */
+/* Small table  [3]                       */
+/* small domain [4]                       */
+/* small sizes  [5]                       */
+/*                                        */
+/* New big table[0]                       */
+/******************************************/
+
+#include "mex.h"
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int     i, j, count, NB, NS, siz_b, siz_s, ndim, temp;
+	int     *mask, *sx, *sy, *cpsy, *subs, *s, *cpsy2;
+	double  *pbDomain, *psDomain, *sp, *zp, *bs, value;
+
+	plhs[0] = mxDuplicateArray(prhs[0]);
+	zp = mxGetPr(plhs[0]);
+
+	siz_b = mxGetNumberOfElements(prhs[1]);
+	siz_s = mxGetNumberOfElements(prhs[4]);
+	pbDomain = mxGetPr(prhs[1]);
+	psDomain = mxGetPr(prhs[4]);
+
+	NB = mxGetNumberOfElements(prhs[0]);
+	NS = mxGetNumberOfElements(prhs[3]);
+	sp = mxGetPr(prhs[3]);
+
+	bs = mxGetPr(prhs[2]);
+
+	if(NS == 1){
+		value = *sp;
+		if(value == 0) value = 1;
+		for(i=0; i<NB; i++){
+			zp[i] /= value;
+		}
+		return;
+	}
+
+	if(NS == NB){
+		for(i=0; i<NB; i++){
+			value = sp[i];
+			if(value == 0) value = 1;
+			zp[i] /= value;
+		}
+		return;
+	}
+
+	mask = malloc(siz_s * sizeof(int));
+	count = 0;
+	for(i=0; i<siz_s; i++){
+		for(j=0; j<siz_b; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	ndim = siz_b;
+	sx = (int *)malloc(sizeof(int)*ndim);
+	sy = (int *)malloc(sizeof(int)*ndim);
+	for(i=0; i<ndim; i++){
+		sx[i] = (int)bs[i];
+		sy[i] = 1;
+	}
+	for(i=0; i<count; i++){
+		temp = mask[i];
+		sy[temp] = sx[temp];
+	}
+
+	s = (int *)malloc(sizeof(int)*ndim);
+	*(cpsy = (int *)malloc(sizeof(int)*ndim)) = 1;
+	subs =   (int *)malloc(sizeof(int)*ndim);
+	cpsy2 =  (int *)malloc(sizeof(int)*ndim);
+	for(i = 0; i < ndim; i++){
+		subs[i] = 0;
+		s[i] = sx[i] - 1;
+	}
+			
+	for(i = 0; i < ndim-1; i++){
+		cpsy[i+1] = cpsy[i]*sy[i]--;
+		cpsy2[i] = cpsy[i]*sy[i];
+	}
+	cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);
+
+	for(j=0; j<NB; j++){
+		value = *sp;
+		if(value == 0) value = 1;
+		*zp++ /= value;
+		for(i = 0; i < ndim; i++){
+			if(subs[i] == s[i]){
+				subs[i] = 0;
+				if(sy[i])
+					sp -= cpsy2[i];
+			}
+			else{
+				subs[i]++;
+				if(sy[i])
+					sp += cpsy[i];
+				break;
+			}
+		}
+	}
+	free(sx);
+	free(sy);
+	free(s);
+	free(cpsy);
+	free(subs);
+	free(cpsy2);
+    free(mask);
+}
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/divide_by_table.m b/sourcecodes/bnt-master/BNT/potentials/Tables/divide_by_table.m
new file mode 100644
index 00000000..6f10718b
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/divide_by_table.m
@@ -0,0 +1,12 @@
+function bigT = divide_by_table(bigT, bigdom, bigsz, smallT, smalldom, smallsz)
+% DIVIDE_BY_TABLE 
+% bigT = divide_by_table(bigT, bigdom, bigsz, smallT, smalldom, smallsz)
+%
+
+
+Ts = extend_domain_table(smallT, smalldom, smallsz, bigdom, bigsz);
+% Replace 0s by 1s before dividing. This is valid, Ts(i)=0 iff Tbig(i)=0.
+Ts = Ts + (Ts==0);
+%Tbig.T(:) = Tbig.T(:) ./ Ts(:);
+bigT(:) = bigT(:) ./ Ts(:);
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/extend_domain_table.m b/sourcecodes/bnt-master/BNT/potentials/Tables/extend_domain_table.m
new file mode 100644
index 00000000..4ed0b2cd
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/extend_domain_table.m
@@ -0,0 +1,24 @@
+function B = extend_domain_table(A, smalldom, smallsz, bigdom, bigsz)
+% EXTEND_DOMAIN_TABLE Expand an array so it has the desired size.
+% B = extend_domain_table(A, smalldom, smallsz, bigdom, bigsz)
+%
+% A is the array with domain smalldom and sizes smallsz.
+% bigdom is the desired domain, with sizes bigsz.
+%
+% Example:
+% smalldom = [1 3], smallsz = [2 4], bigdom = [1 2 3 4], bigsz = [2 1 4 5],
+% so B(i,j,k,l) = A(i,k) for i in 1:2, j in 1:1, k in 1:4, l in 1:5
+
+if isequal(size(A), [1 1]) % a scalar
+  B = A; % * myones(bigsz);
+  return;
+end
+
+map = find_equiv_posns(smalldom, bigdom);
+sz = ones(1, length(bigdom));
+sz(map) = smallsz;
+B = myreshape(A, sz); % add dimensions for the stuff not in A
+sz = bigsz;
+sz(map) = 1; % don't replicate along A's dimensions
+B = myrepmat(B, sz(:)');
+                           
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/marg_sparse_table.c b/sourcecodes/bnt-master/BNT/potentials/Tables/marg_sparse_table.c
new file mode 100644
index 00000000..f6f7aa26
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/marg_sparse_table.c
@@ -0,0 +1,181 @@
+/* marg_sparse_table.c ../potential/tables*/
+
+/******************************************/
+/* 5 input & 1 output                     */
+/* Big sparse table                       */
+/* Big domain                             */
+/* Big sizes                              */
+/* onto                                   */
+/* maximize, if missed, maximize=0        */
+/*                                        */
+/* small sparse table                     */
+/******************************************/
+
+#include <math.h>
+#include <stdlib.h>
+#include "mex.h"
+
+int compare(const void* src1, const void* src2){
+	int i1 = *(int*)src1 ;
+	int i2 = *(int*)src2 ;
+	return i1-i2 ;
+}
+
+void ind_subv(int index, const int *cumprod, int n, int *bsubv){
+	int i;
+
+	for (i = n-1; i >= 0; i--) {
+		bsubv[i] = ((int)floor(index / cumprod[i]));
+		index = index % cumprod[i];
+	}
+}
+
+int subv_ind(const int n, const int *cumprod, const int *subv){
+	int i, index=0;
+
+	for(i=0; i<n; i++){
+		index += subv[i] * cumprod[i];
+	}
+	return index;
+}
+
+mxArray* convert_table_to_sparse(const double *Table, const int *sequence, const int nzCounts, const int N){
+	mxArray *spTable;
+	int     i, temp, *irs, *jcs, count=0;
+	double  *sr;
+
+	spTable = mxCreateSparse(N, 1, nzCounts, mxREAL);
+    sr  = mxGetPr(spTable);
+    irs = mxGetIr(spTable);
+    jcs = mxGetJc(spTable);
+
+	jcs[0] = 0;
+	jcs[1] = nzCounts;
+
+	for(i=0; i<nzCounts; i++){
+		irs[i] = sequence[count];
+		count++;
+		temp = sequence[count];
+		sr[i] = Table[temp];
+		count++;
+	}
+	return spTable;
+}
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int        i, j, count, bdim, sdim, NS, NZB, position, bindex, sindex, maximize, nzCounts=0;
+	int        *mask, *sequence, *result, *bir, *bjc, *ssize, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double     *sTable, *pbDomain, *psDomain, *pbSize, *bpr, *spr;
+	const char *field_names[] = {"domain", "T", "sizes"};
+
+	if(nrhs < 5) maximize = 0;
+	else maximize = (int)mxGetScalar(prhs[4]);
+
+	bdim = mxGetNumberOfElements(prhs[1]);
+	sdim = mxGetNumberOfElements(prhs[3]);
+	pbSize = mxGetPr(prhs[2]);
+	pbDomain = mxGetPr(prhs[1]);
+	psDomain = mxGetPr(prhs[3]);
+	bpr = mxGetPr(prhs[0]);
+	bir = mxGetIr(prhs[0]);
+	bjc = mxGetJc(prhs[0]);
+	NZB = bjc[1];
+
+	if(sdim == 0){
+		plhs[0] = mxCreateSparse(1, 1, 1, mxREAL);
+		spr = mxGetPr(plhs[0]);
+		bir = mxGetIr(plhs[0]);
+		bjc = mxGetJc(plhs[0]);
+		*spr = 0;
+		*bir = 0;
+		bjc[0] = 0;
+		bjc[1] = 1;
+		if(maximize){
+			for(i=0; i<NZB; i++){
+				*spr = (*spr < bpr[i])? bpr[i] : *spr;
+			}
+		}
+		else{
+			for(i=0; i<NZB; i++){
+				*spr += bpr[i];
+			}
+		}	
+		return;
+	}
+
+	mask = malloc(sdim * sizeof(int));
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+		
+	sTable = malloc(NZB * sizeof(double));
+	sequence = malloc(NZB * 2 * sizeof(double));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+	ssize = malloc(sdim * sizeof(int));
+
+	NS = 1;
+	for(i=0; i<count; i++){
+		ssize[i] = (int)pbSize[mask[i]];
+		NS *= ssize[i];
+	}
+
+	for(i=0; i<NZB; i++)sTable[i] = 0;
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * ssize[i];
+	}
+
+	count = 0;
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sequence, nzCounts, sizeof(int)*2, compare);
+		if(result){
+			position = (result - sequence) / 2;
+			if(maximize) 
+				sTable[position] = (sTable[position] < bpr[i]) ? bpr[i] : sTable[position];
+			else sTable[position] += bpr[i];
+		}
+		else {
+			if(maximize) 
+				sTable[nzCounts] = (sTable[nzCounts] < bpr[i]) ? bpr[i] : sTable[nzCounts];
+			else sTable[nzCounts] += bpr[i];
+			sequence[count] = sindex;
+			count++;
+			sequence[count] = nzCounts;
+			nzCounts++;
+			count++;
+		}
+	}
+	
+	qsort(sequence, nzCounts, sizeof(int) * 2, compare);
+	plhs[0] = convert_table_to_sparse(sTable, sequence, nzCounts, NS);
+
+	free(sTable);
+	free(sequence);
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+	free(ssize);
+}
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/marg_table.c b/sourcecodes/bnt-master/BNT/potentials/Tables/marg_table.c
new file mode 100644
index 00000000..16329dee
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/marg_table.c
@@ -0,0 +1,175 @@
+/* marg_table.c  ../potential/tables     */
+
+
+/******************************************/
+/* 5 input & 1 output                     */
+/* Big table                              */
+/* Big domain                             */
+/* Big sizes                              */
+/* onto                                   */
+/* maximize, if missed, maximize=0        */
+/*                                        */
+/* small table                            */
+/******************************************/
+
+#include "mex.h"
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int     i, j, count, NB, NS, siz_b, siz_s, ndim, temp, maximize;
+	int     *mask, *sx, *sy, *cpsy, *subs, *s, *cpsy2, *ssize;
+	double  *pb, *ps, *bp, *sp, *pbd;
+
+
+	siz_b = mxGetNumberOfElements(prhs[1]);
+	siz_s = mxGetNumberOfElements(prhs[3]);
+	pb = mxGetPr(prhs[1]);
+	ps = mxGetPr(prhs[3]);
+
+	NB = mxGetNumberOfElements(prhs[0]);
+	bp = mxGetPr(prhs[0]);
+
+	pbd = mxGetPr(prhs[2]);
+
+	if(nrhs < 5) maximize = 0;
+	else maximize = (int)mxGetScalar(prhs[4]);
+
+	if(siz_s == 0){
+		plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
+		sp = mxGetPr(plhs[0]);
+		if(maximize){
+			for(i=0; i<NB; i++){
+				*sp = (*sp < bp[i])? bp[i] : *sp;
+			}
+		}
+		else{
+			for(i=0; i<NB; i++){
+				*sp += bp[i];
+			}
+		}
+		return;
+	}
+
+	mask = malloc(siz_s * sizeof(int));
+	ssize = malloc(siz_s * sizeof(int));
+	count = 0;
+	for(i=0; i<siz_s; i++){
+		for(j=0; j<siz_b; j++){
+			if(ps[i] == pb[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	ndim = siz_b;
+	sx = (int *)malloc(sizeof(int)*ndim);
+	sy = (int *)malloc(sizeof(int)*ndim);
+	for(i=0; i<ndim; i++){
+		sx[i] = (int)pbd[i];
+		sy[i] = 1;
+	}
+	for(i=0; i<siz_s; i++){
+		temp = mask[i];
+		sy[temp] = sx[temp];
+		ssize[i] = sx[temp];
+	}
+
+	NS = 1;
+	for(i=0; i<ndim; i++){
+		NS *= sy[i];
+	}
+
+	plhs[0] = mxCreateNumericArray(siz_s, ssize, mxDOUBLE_CLASS, mxREAL);
+	sp = mxGetPr(plhs[0]);
+
+	if(NS == 1){
+		if(maximize){
+			for(i=0; i<NB; i++){
+				*sp = (*sp < bp[i])? bp[i] : *sp;
+			}
+		}
+		else{
+			for(i=0; i<NB; i++){
+				*sp += bp[i];
+			}
+		}
+		free(mask);
+		free(sx);
+		free(sy);
+		free(ssize);
+		return;
+	}
+
+	if(NS == NB){
+		for(i=0; i<NB; i++) *sp++ = *bp++;
+		free(mask);
+		free(sx);
+		free(sy);
+		free(ssize);
+		return;
+	}
+
+	s = (int *)malloc(sizeof(int)*ndim);
+	*(cpsy = (int *)malloc(sizeof(int)*ndim)) = 1;
+	subs =   (int *)malloc(sizeof(int)*ndim);
+	cpsy2 =  (int *)malloc(sizeof(int)*ndim);
+	for(i = 0; i < ndim; i++){
+		subs[i] = 0;
+		s[i] = sx[i] - 1;
+	}
+			
+	for(i = 0; i < ndim-1; i++){
+		cpsy[i+1] = cpsy[i]*sy[i]--;
+		cpsy2[i] = cpsy[i]*sy[i];
+	}
+	cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);
+
+	if(maximize){
+		for(j=0; j<NB; j++){
+			*sp = (*sp < *bp)? *bp : *sp;
+			bp++;
+			for(i = 0; i < ndim; i++){
+				if(subs[i] == s[i]){
+					subs[i] = 0;
+					if(sy[i])
+						sp -= cpsy2[i];
+				}
+				else{
+					subs[i]++;
+					if(sy[i])
+						sp += cpsy[i];
+					break;
+				}
+			}
+		}
+	}
+	else{
+		for(j=0; j<NB; j++){
+			*sp += *bp++;
+			for(i = 0; i < ndim; i++){
+				if(subs[i] == s[i]){
+					subs[i] = 0;
+					if(sy[i])
+						sp -= cpsy2[i];
+				}
+				else{
+					subs[i]++;
+					if(sy[i])
+						sp += cpsy[i];
+					break;
+				}
+			}
+		}
+	}
+
+	free(sx);
+	free(sy);
+	free(s);
+	free(cpsy);
+	free(subs);
+	free(cpsy2);
+    free(mask);
+	free(ssize);
+}
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/marg_table.m b/sourcecodes/bnt-master/BNT/potentials/Tables/marg_table.m
new file mode 100644
index 00000000..0f1e5be5
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/marg_table.m
@@ -0,0 +1,27 @@
+function smallT = marg_table(bigT, bigdom, bigsz, onto, maximize)
+% MARG_TABLE Marginalize a table
+% smallT = marg_table(bigT, bigdom, bigsz, onto, maximize)
+
+if nargin < 5, maximize = 0; end
+
+
+smallT = myreshape(bigT, bigsz); % make sure it is a multi-dim array
+sum_over = mysetdiff(bigdom, onto);
+ndx = find_equiv_posns(sum_over, bigdom);
+if maximize
+  for i=1:length(ndx)
+    smallT = max(smallT, [], ndx(i));
+  end
+else
+  for i=1:length(ndx)
+    smallT = sum(smallT, ndx(i));
+  end
+end
+
+
+ns = zeros(1, max(bigdom));
+%ns(bigdom) = mysize(bigT); % ignores trailing dimensions of size 1
+ns(bigdom) = bigsz;
+
+smallT = squeeze(smallT); % remove all dimensions of size 1
+smallT = myreshape(smallT, ns(onto)); % put back relevant dims of size 1
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/marg_tableC.c b/sourcecodes/bnt-master/BNT/potentials/Tables/marg_tableC.c
new file mode 100644
index 00000000..16329dee
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/marg_tableC.c
@@ -0,0 +1,175 @@
+/* marg_table.c  ../potential/tables     */
+
+
+/******************************************/
+/* 5 input & 1 output                     */
+/* Big table                              */
+/* Big domain                             */
+/* Big sizes                              */
+/* onto                                   */
+/* maximize, if missed, maximize=0        */
+/*                                        */
+/* small table                            */
+/******************************************/
+
+#include "mex.h"
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int     i, j, count, NB, NS, siz_b, siz_s, ndim, temp, maximize;
+	int     *mask, *sx, *sy, *cpsy, *subs, *s, *cpsy2, *ssize;
+	double  *pb, *ps, *bp, *sp, *pbd;
+
+
+	siz_b = mxGetNumberOfElements(prhs[1]);
+	siz_s = mxGetNumberOfElements(prhs[3]);
+	pb = mxGetPr(prhs[1]);
+	ps = mxGetPr(prhs[3]);
+
+	NB = mxGetNumberOfElements(prhs[0]);
+	bp = mxGetPr(prhs[0]);
+
+	pbd = mxGetPr(prhs[2]);
+
+	if(nrhs < 5) maximize = 0;
+	else maximize = (int)mxGetScalar(prhs[4]);
+
+	if(siz_s == 0){
+		plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
+		sp = mxGetPr(plhs[0]);
+		if(maximize){
+			for(i=0; i<NB; i++){
+				*sp = (*sp < bp[i])? bp[i] : *sp;
+			}
+		}
+		else{
+			for(i=0; i<NB; i++){
+				*sp += bp[i];
+			}
+		}
+		return;
+	}
+
+	mask = malloc(siz_s * sizeof(int));
+	ssize = malloc(siz_s * sizeof(int));
+	count = 0;
+	for(i=0; i<siz_s; i++){
+		for(j=0; j<siz_b; j++){
+			if(ps[i] == pb[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	ndim = siz_b;
+	sx = (int *)malloc(sizeof(int)*ndim);
+	sy = (int *)malloc(sizeof(int)*ndim);
+	for(i=0; i<ndim; i++){
+		sx[i] = (int)pbd[i];
+		sy[i] = 1;
+	}
+	for(i=0; i<siz_s; i++){
+		temp = mask[i];
+		sy[temp] = sx[temp];
+		ssize[i] = sx[temp];
+	}
+
+	NS = 1;
+	for(i=0; i<ndim; i++){
+		NS *= sy[i];
+	}
+
+	plhs[0] = mxCreateNumericArray(siz_s, ssize, mxDOUBLE_CLASS, mxREAL);
+	sp = mxGetPr(plhs[0]);
+
+	if(NS == 1){
+		if(maximize){
+			for(i=0; i<NB; i++){
+				*sp = (*sp < bp[i])? bp[i] : *sp;
+			}
+		}
+		else{
+			for(i=0; i<NB; i++){
+				*sp += bp[i];
+			}
+		}
+		free(mask);
+		free(sx);
+		free(sy);
+		free(ssize);
+		return;
+	}
+
+	if(NS == NB){
+		for(i=0; i<NB; i++) *sp++ = *bp++;
+		free(mask);
+		free(sx);
+		free(sy);
+		free(ssize);
+		return;
+	}
+
+	s = (int *)malloc(sizeof(int)*ndim);
+	*(cpsy = (int *)malloc(sizeof(int)*ndim)) = 1;
+	subs =   (int *)malloc(sizeof(int)*ndim);
+	cpsy2 =  (int *)malloc(sizeof(int)*ndim);
+	for(i = 0; i < ndim; i++){
+		subs[i] = 0;
+		s[i] = sx[i] - 1;
+	}
+			
+	for(i = 0; i < ndim-1; i++){
+		cpsy[i+1] = cpsy[i]*sy[i]--;
+		cpsy2[i] = cpsy[i]*sy[i];
+	}
+	cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);
+
+	if(maximize){
+		for(j=0; j<NB; j++){
+			*sp = (*sp < *bp)? *bp : *sp;
+			bp++;
+			for(i = 0; i < ndim; i++){
+				if(subs[i] == s[i]){
+					subs[i] = 0;
+					if(sy[i])
+						sp -= cpsy2[i];
+				}
+				else{
+					subs[i]++;
+					if(sy[i])
+						sp += cpsy[i];
+					break;
+				}
+			}
+		}
+	}
+	else{
+		for(j=0; j<NB; j++){
+			*sp += *bp++;
+			for(i = 0; i < ndim; i++){
+				if(subs[i] == s[i]){
+					subs[i] = 0;
+					if(sy[i])
+						sp -= cpsy2[i];
+				}
+				else{
+					subs[i]++;
+					if(sy[i])
+						sp += cpsy[i];
+					break;
+				}
+			}
+		}
+	}
+
+	free(sx);
+	free(sy);
+	free(s);
+	free(cpsy);
+	free(subs);
+	free(cpsy2);
+    free(mask);
+	free(ssize);
+}
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/marg_tableM.m b/sourcecodes/bnt-master/BNT/potentials/Tables/marg_tableM.m
new file mode 100644
index 00000000..22487dff
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/marg_tableM.m
@@ -0,0 +1,30 @@
+function smallT = marg_tableM(bigT, bigdom, bigsz, onto, maximize)
+% MARG_TABLE Marginalize a table
+% smallT = marg_table(bigT, bigdom, bigsz, onto, maximize)
+
+  % marg_tableM is the same as marg_table.m, but we are sure
+  % it is not marg_table.c
+
+if nargin < 5, maximize = 0; end
+
+
+smallT = myreshape(bigT, bigsz); % make sure it is a multi-dim array
+sum_over = mysetdiff(bigdom, onto);
+ndx = find_equiv_posns(sum_over, bigdom);
+if maximize
+  for i=1:length(ndx)
+    smallT = max(smallT, [], ndx(i));
+  end
+else
+  for i=1:length(ndx)
+    smallT = sum(smallT, ndx(i));
+  end
+end
+
+
+ns = zeros(1, max(bigdom));
+%ns(bigdom) = mysize(bigT); % ignores trailing dimensions of size 1
+ns(bigdom) = bigsz;
+
+smallT = squeeze(smallT); % remove all dimensions of size 1
+smallT = myreshape(smallT, ns(onto)); % put back relevant dims of size 1
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_sparse_table.c b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_sparse_table.c
new file mode 100644
index 00000000..c1331508
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_sparse_table.c
@@ -0,0 +1,155 @@
+/* mult_by_sparse_table.c ../potential/tables*/
+
+
+/******************************************/
+/* 6 input & 1 output                     */
+/* Big table    [0]                       */
+/* Big domain   [1]                       */
+/* big sizes    [2]                       */
+/* Small table  [3]                       */
+/* small domain [4]                       */
+/* small sizes  [5]                       */
+/*                                        */
+/* New big table[0]                       */
+/******************************************/
+
+#include <math.h>
+#include <stdlib.h>
+#include "mex.h"
+
+int compare(const void* src1, const void* src2){
+	int i1 = *(int*)src1 ;
+	int i2 = *(int*)src2 ;
+	return i1-i2 ;
+}
+
+void ind_subv(int index, const int *cumprod, int n, int *bsubv){
+	int i;
+
+	for (i = n-1; i >= 0; i--) {
+		bsubv[i] = ((int)floor(index / cumprod[i]));
+		index = index % cumprod[i];
+	}
+}
+
+int subv_ind(const int n, const int *cumprod, const int *subv){
+	int i, index=0;
+
+	for(i=0; i<n; i++){
+		index += subv[i] * cumprod[i];
+	}
+	return index;
+}
+
+void reset_nzmax(mxArray *spArray, const int old_nzmax, const int new_nzmax){
+	double *ptr;
+	void   *newptr;
+	int    *ir, *jc;
+	int    nbytes;
+
+	if(new_nzmax == old_nzmax) return;
+	nbytes = new_nzmax * sizeof(*ptr);
+	ptr = mxGetPr(spArray);
+	newptr = mxRealloc(ptr, nbytes);
+	mxSetPr(spArray, newptr);
+	nbytes = new_nzmax * sizeof(*ir);
+	ir = mxGetIr(spArray);
+	newptr = mxRealloc(ir, nbytes);
+	mxSetIr(spArray, newptr);
+	jc = mxGetJc(spArray);
+	jc[0] = 0;
+	jc[1] = new_nzmax;
+	mxSetNzmax(spArray, new_nzmax);
+}
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+	int     i, j, count, bdim, sdim, NB, NZB, NZS, position, bindex, sindex, nzCounts=0;
+	int     *mask, *result, *bir, *sir, *rir, *bjc, *sjc, *rjc, *bCumprod, *sCumprod, *bsubv, *ssubv;
+	double  *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, *rpr;
+
+	pbDomain = mxGetPr(prhs[1]);
+	bdim = mxGetNumberOfElements(prhs[1]);
+	psDomain = mxGetPr(prhs[4]);
+	sdim = mxGetNumberOfElements(prhs[4]);
+
+	pbSize = mxGetPr(prhs[2]);
+	psSize = mxGetPr(prhs[5]);
+
+	NB = 1;
+	for(i=0; i<bdim; i++){
+		NB *= (int)pbSize[i];
+	}
+
+	bpr = mxGetPr(prhs[0]);
+	bir = mxGetIr(prhs[0]);
+	bjc = mxGetJc(prhs[0]);
+	NZB = bjc[1];
+
+	spr = mxGetPr(prhs[3]);
+	sir = mxGetIr(prhs[3]);
+	sjc = mxGetJc(prhs[3]);
+	NZS = sjc[1];
+
+	plhs[0] = mxDuplicateArray(prhs[0]);
+	rpr = mxGetPr(plhs[0]);
+	rir = mxGetIr(plhs[0]);
+	rjc = mxGetJc(plhs[0]);
+	rjc[0] = 0;
+	rjc[1] = NZB;
+
+	if(sdim == 0){
+		for(i=0; i<NZB; i++){
+			rpr[i] *= *spr;
+		}	
+		return;
+	}
+
+	mask = malloc(sdim * sizeof(int));
+	bCumprod = malloc(bdim * sizeof(int));
+	sCumprod = malloc(sdim * sizeof(int));
+	bsubv = malloc(bdim * sizeof(int));
+	ssubv = malloc(sdim * sizeof(int));
+
+	count = 0;
+	for(i=0; i<sdim; i++){
+		for(j=0; j<bdim; j++){
+			if(psDomain[i] == pbDomain[j]){
+				mask[count] = j;
+				count++;
+				break;
+			}
+		}
+	}
+	
+	bCumprod[0] = 1;
+	for(i=0; i<bdim-1; i++){
+		bCumprod[i+1] = bCumprod[i] * (int)pbSize[i];
+	}
+	sCumprod[0] = 1;
+	for(i=0; i<sdim-1; i++){
+		sCumprod[i+1] = sCumprod[i] * (int)psSize[i];
+	}
+
+	for(i=0; i<NZB; i++){
+		bindex = bir[i];
+		ind_subv(bindex, bCumprod, bdim, bsubv);
+		for(j=0; j<sdim; j++){
+			ssubv[j] = bsubv[mask[j]];
+		}
+		sindex = subv_ind(sdim, sCumprod, ssubv);
+		result = (int *) bsearch(&sindex, sir, NZS, sizeof(int), compare);
+		if(result){
+			position = result - sir;
+			rpr[nzCounts] = bpr[i] * spr[position];
+			rir[nzCounts] = bindex;
+			nzCounts++;
+		}
+	}
+
+	reset_nzmax(plhs[0], NZB, nzCounts);
+	free(mask);
+	free(bCumprod);
+	free(sCumprod);
+	free(bsubv);
+	free(ssubv);
+}
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table.c b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table.c
new file mode 100644
index 00000000..3f67983d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table.c
@@ -0,0 +1,114 @@
+/* mult_by_table.c  ../potential/tables  */
+
+
+/******************************************/
+/* 6 input & 1 output                     */
+/* Big table    [0]                       */
+/* Big domain   [1]                       */
+/* big sizes    [2]                       */
+/* Small table  [3]                       */
+/* small domain [4]                       */
+/* small sizes  [5]                       */
+/*                                        */
+/* New big table[0]                       */
+/******************************************/
+
+#include "mex.h"
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+  int     i, j, count, NB, NS, siz_b, siz_s, ndim, temp;
+  int     *mask, *sx, *sy, *cpsy, *subs, *s, *cpsy2;
+  double  *pbDomain, *psDomain, *sp, *zp, *bs;
+  
+  plhs[0] = mxDuplicateArray(prhs[0]);
+  zp = mxGetPr(plhs[0]);
+  
+  siz_b = mxGetNumberOfElements(prhs[1]);
+  siz_s = mxGetNumberOfElements(prhs[4]);
+  pbDomain = mxGetPr(prhs[1]);
+  psDomain = mxGetPr(prhs[4]);
+  
+  NB = mxGetNumberOfElements(prhs[0]);
+  NS = mxGetNumberOfElements(prhs[3]);
+  sp = mxGetPr(prhs[3]);
+  
+  bs = mxGetPr(prhs[2]);
+  
+  if(NS == 1){
+    for(i=0; i<NB; i++){
+      zp[i] *= *sp;
+    }
+    return;
+  }
+  
+  if(NS == NB){
+    for(i=0; i<NB; i++){
+      zp[i] *= sp[i];
+    }
+    return;
+  }
+  
+  mask = malloc(siz_s * sizeof(int));
+  count = 0;
+  for(i=0; i<siz_s; i++){
+    for(j=0; j<siz_b; j++){
+      if(psDomain[i] == pbDomain[j]){
+	mask[count] = j;
+	count++;
+	break;
+      }
+    }
+  }
+  
+  ndim = siz_b;
+  sx = (int *)malloc(sizeof(int)*ndim);
+  sy = (int *)malloc(sizeof(int)*ndim);
+  for(i=0; i<ndim; i++){
+    sx[i] = (int)bs[i];
+    sy[i] = 1;
+  }
+  for(i=0; i<count; i++){
+    temp = mask[i];
+    sy[temp] = sx[temp];
+  }
+  
+  s = (int *)malloc(sizeof(int)*ndim);
+  *(cpsy = (int *)malloc(sizeof(int)*ndim)) = 1;
+  subs =   (int *)malloc(sizeof(int)*ndim);
+  cpsy2 =  (int *)malloc(sizeof(int)*ndim);
+  for(i = 0; i < ndim; i++){
+    subs[i] = 0;
+    s[i] = sx[i] - 1;
+  }
+  
+  for(i = 0; i < ndim-1; i++){
+    cpsy[i+1] = cpsy[i]*sy[i]--;
+    cpsy2[i] = cpsy[i]*sy[i];
+  }
+  cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);
+  
+  for(j=0; j<NB; j++){
+    *zp++ *= *sp;
+    for(i = 0; i < ndim; i++){
+      if(subs[i] == s[i]){
+	subs[i] = 0;
+	if(sy[i])
+	  sp -= cpsy2[i];
+      }
+      else{
+	subs[i]++;
+	if(sy[i])
+	  sp += cpsy[i];
+	break;
+      }
+    }
+  }
+  free(sx);
+  free(sy);
+  free(s);
+  free(cpsy);
+  free(subs);
+  free(cpsy2);
+  free(mask);
+}
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table.m b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table.m
new file mode 100644
index 00000000..a92e340f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table.m
@@ -0,0 +1,7 @@
+function bigT = mult_by_table(bigT, bigdom, bigsz, smallT, smalldom, smallsz)
+% MULT_BY_TABLE 
+% bigT = mult_by_table(bigT, bigdom, bigsz, smallT, smalldom, smallsz)
+%
+
+Ts = extend_domain_table(smallT, smalldom, smallsz, bigdom, bigsz);
+bigT(:) = bigT(:) .* Ts(:); % must have bigT(:) on LHS to preserve shape
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table2.m b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table2.m
new file mode 100644
index 00000000..92fb4ac7
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table2.m
@@ -0,0 +1,30 @@
+function bigT = mult_by_table2(bigT, bigdom, bigsz, smallT, smalldom, smallsz)
+% MULT_BY_TABLE 
+% bigT = mult_by_table(bigT, bigdom, bigsz, smallT, smalldom, smallsz)
+%
+
+%Ts = extend_domain_table(smallT, smalldom, smallsz, bigdom, bigsz);
+%bigT(:) = bigT(:) .* Ts(:); % must have bigT(:) on LHS to preserve shape
+
+% extend_domain_table has a lot of overhead for small tables,
+% since it calls myreshape and myrepmat, which check for 1 dimensional case.
+% Here, we check up front.
+
+if length(bigdom)==1 % vector
+  bigT = bigT .* smallT; % smallT can be scalar or vector
+else
+  if (length(bigsz) == length(smallsz)) & all(bigsz == smallsz)
+    bigT = bigT .* smallT;
+  else
+    map = find_equiv_posns(smalldom, bigdom);
+    sz = ones(1, length(bigdom));
+    sz(map) = smallsz;
+    smallT = reshape(smallT, sz); % add dimensions of size 1 for missing domain
+    % we can use reshape instead of myreshape, because we know length(sz)>1
+    sz = bigsz;
+    sz(map) = 1; % don't replicate along small domain, which is shared
+    % we can use repmat instead of myrepmat, because we know length(sz)>1
+    smallT = repmat(smallT, sz(:)');
+    bigT(:) = bigT(:) .* smallT(:);
+  end
+end
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_tableC.c b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_tableC.c
new file mode 100644
index 00000000..3f67983d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_tableC.c
@@ -0,0 +1,114 @@
+/* mult_by_table.c  ../potential/tables  */
+
+
+/******************************************/
+/* 6 input & 1 output                     */
+/* Big table    [0]                       */
+/* Big domain   [1]                       */
+/* big sizes    [2]                       */
+/* Small table  [3]                       */
+/* small domain [4]                       */
+/* small sizes  [5]                       */
+/*                                        */
+/* New big table[0]                       */
+/******************************************/
+
+#include "mex.h"
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+  int     i, j, count, NB, NS, siz_b, siz_s, ndim, temp;
+  int     *mask, *sx, *sy, *cpsy, *subs, *s, *cpsy2;
+  double  *pbDomain, *psDomain, *sp, *zp, *bs;
+  
+  plhs[0] = mxDuplicateArray(prhs[0]);
+  zp = mxGetPr(plhs[0]);
+  
+  siz_b = mxGetNumberOfElements(prhs[1]);
+  siz_s = mxGetNumberOfElements(prhs[4]);
+  pbDomain = mxGetPr(prhs[1]);
+  psDomain = mxGetPr(prhs[4]);
+  
+  NB = mxGetNumberOfElements(prhs[0]);
+  NS = mxGetNumberOfElements(prhs[3]);
+  sp = mxGetPr(prhs[3]);
+  
+  bs = mxGetPr(prhs[2]);
+  
+  if(NS == 1){
+    for(i=0; i<NB; i++){
+      zp[i] *= *sp;
+    }
+    return;
+  }
+  
+  if(NS == NB){
+    for(i=0; i<NB; i++){
+      zp[i] *= sp[i];
+    }
+    return;
+  }
+  
+  mask = malloc(siz_s * sizeof(int));
+  count = 0;
+  for(i=0; i<siz_s; i++){
+    for(j=0; j<siz_b; j++){
+      if(psDomain[i] == pbDomain[j]){
+	mask[count] = j;
+	count++;
+	break;
+      }
+    }
+  }
+  
+  ndim = siz_b;
+  sx = (int *)malloc(sizeof(int)*ndim);
+  sy = (int *)malloc(sizeof(int)*ndim);
+  for(i=0; i<ndim; i++){
+    sx[i] = (int)bs[i];
+    sy[i] = 1;
+  }
+  for(i=0; i<count; i++){
+    temp = mask[i];
+    sy[temp] = sx[temp];
+  }
+  
+  s = (int *)malloc(sizeof(int)*ndim);
+  *(cpsy = (int *)malloc(sizeof(int)*ndim)) = 1;
+  subs =   (int *)malloc(sizeof(int)*ndim);
+  cpsy2 =  (int *)malloc(sizeof(int)*ndim);
+  for(i = 0; i < ndim; i++){
+    subs[i] = 0;
+    s[i] = sx[i] - 1;
+  }
+  
+  for(i = 0; i < ndim-1; i++){
+    cpsy[i+1] = cpsy[i]*sy[i]--;
+    cpsy2[i] = cpsy[i]*sy[i];
+  }
+  cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);
+  
+  for(j=0; j<NB; j++){
+    *zp++ *= *sp;
+    for(i = 0; i < ndim; i++){
+      if(subs[i] == s[i]){
+	subs[i] = 0;
+	if(sy[i])
+	  sp -= cpsy2[i];
+      }
+      else{
+	subs[i]++;
+	if(sy[i])
+	  sp += cpsy[i];
+	break;
+      }
+    }
+  }
+  free(sx);
+  free(sy);
+  free(s);
+  free(cpsy);
+  free(subs);
+  free(cpsy2);
+  free(mask);
+}
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_tableM.m b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_tableM.m
new file mode 100644
index 00000000..a92e340f
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_tableM.m
@@ -0,0 +1,7 @@
+function bigT = mult_by_table(bigT, bigdom, bigsz, smallT, smalldom, smallsz)
+% MULT_BY_TABLE 
+% bigT = mult_by_table(bigT, bigdom, bigsz, smallT, smalldom, smallsz)
+%
+
+Ts = extend_domain_table(smallT, smalldom, smallsz, bigdom, bigsz);
+bigT(:) = bigT(:) .* Ts(:); % must have bigT(:) on LHS to preserve shape
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table_global.m b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table_global.m
new file mode 100644
index 00000000..cc6d7124
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/mult_by_table_global.m
@@ -0,0 +1,7 @@
+function mult_by_table_global(bigT, bigdom, bigsz, smallT, smalldom, smallsz)
+
+% all arguments are read only
+global NEWBIGT_GLOBAL
+
+Ts = extend_domain_table(smallT, smalldom, smallsz, bigdom, bigsz);
+NEWBIGT_GLOBAL = bigT(:) .* Ts(:);
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/rep_mult.c b/sourcecodes/bnt-master/BNT/potentials/Tables/rep_mult.c
new file mode 100644
index 00000000..c7b687a6
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/rep_mult.c
@@ -0,0 +1,92 @@
+/* rep_mult.c  repmat first two operands to the size provided by */
+/* the third operand, then perform point multiply                */
+/* 3 input, 1 output                                             */
+/* C = rep_mult(A, B, sizes)                                     */
+
+#include "mex.h"
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
+{
+	double		*xp, *yp, *zp, *pSizes;
+	int			xnd, ynd, numElements = 1;
+	const int	*xdim, *ydim;
+	int         i, j, ndim;
+	int			*s, *sx, *sy, *cpsx, *cpsy;
+	int			*subs, *s1, *cpsx2, *cpsy2;
+
+	if (nrhs != 3)
+		mexErrMsgTxt("Incorrect number of inputs.");
+	
+	if (nlhs > 1)
+		mexErrMsgTxt("Too many output arguments.");
+	
+	xnd = mxGetNumberOfDimensions(prhs[0]);
+	ynd = mxGetNumberOfDimensions(prhs[1]);
+	xdim = mxGetDimensions(prhs[0]);
+	ydim = mxGetDimensions(prhs[1]);
+	ndim = mxGetNumberOfElements(prhs[2]);
+
+	pSizes = mxGetPr(prhs[2]);
+
+	sx = (int *)malloc(sizeof(int)*ndim);
+	sy = (int *)malloc(sizeof(int)*ndim);
+	s =  (int *)malloc(sizeof(int)*ndim);
+	s1 = (int *)malloc(sizeof(int)*ndim);
+	*(cpsx = (int *)malloc(sizeof(int)*ndim)) = 1;
+	*(cpsy = (int *)malloc(sizeof(int)*ndim)) = 1;
+	subs =   (int *)malloc(sizeof(int)*ndim);
+	cpsx2 =  (int *)malloc(sizeof(int)*ndim);
+	cpsy2 =  (int *)malloc(sizeof(int)*ndim);
+	for(i=0; i<ndim; i++){
+		subs[i] = 0;
+		sx[i] = (i < xnd) ? xdim[i] : 1;
+		sy[i] = (i < ynd) ? ydim[i] : 1;
+		s[i] = (int)pSizes[i];
+		s1[i] = s[i] - 1;
+		numElements *= s[i];
+	}
+				
+	for(i=0; i<ndim-1; i++){
+		cpsx[i+1] = cpsx[i]*sx[i]--;
+		cpsy[i+1] = cpsy[i]*sy[i]--;
+		cpsx2[i] = cpsx[i]*sx[i];
+		cpsy2[i] = cpsy[i]*sy[i];
+	}
+	cpsx2[ndim-1] = cpsx[ndim-1]*(--sx[ndim-1]);
+	cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);
+	
+	plhs[0] = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
+	zp = mxGetPr(plhs[0]);
+	xp = mxGetPr(prhs[0]);
+	yp = mxGetPr(prhs[1]);
+
+	for(j=0; j<numElements; j++){
+		*zp++ = *xp * *yp;
+		for(i=0; i<ndim; i++){
+			if(subs[i] == s1[i]){
+				subs[i] = 0;
+				if(sx[i])
+					xp -= cpsx2[i];
+				if(sy[i])
+					yp -= cpsy2[i];
+			}
+			else{
+				subs[i]++;
+				if(sx[i])
+					xp += cpsx[i];
+				if(sy[i])
+					yp += cpsy[i];
+				break;
+			}
+		}
+	}
+	free(sx);
+	free(sy);
+	free(s);
+	free(s1);
+	free(cpsx);
+	free(cpsy);
+	free(subs);
+	free(cpsx2);
+	free(cpsy2);
+}
diff --git a/sourcecodes/bnt-master/BNT/potentials/Tables/repmat_and_mult.c b/sourcecodes/bnt-master/BNT/potentials/Tables/repmat_and_mult.c
new file mode 100644
index 00000000..a7bdba35
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/Tables/repmat_and_mult.c
@@ -0,0 +1,97 @@
+/****************************************************
+A = mult_by_array(big, small)
+implicitely copies small |big|/|small| times 
+and then does element-wise multiplication.
+
+i.e.,
+C = repmat(small(:), 1, length(big(:))/length(small(:)))
+A = reshape(big(:) .* C(:), size(big))
+
+However, this C version avoids the expense of the repmat.
+
+Written by wei.hu@intel.com, 28 Jan 2002.
+/****************************************************/
+
+
+#include "mex.h"
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
+{
+  double		*sp, *zp;
+  int			i, j, NB, NS, xnd, ynd, ndim;
+  const int	*xdim, *ydim;
+  int			*s, *sx, *sy, *cpsy, *subs, *cpsy2;
+  
+  if (nrhs != 2)
+    mexErrMsgTxt("Incorrect number of inputs.");
+  
+  if (nlhs > 1)
+    mexErrMsgTxt("Too many output arguments.");
+  
+  plhs[0] = mxDuplicateArray(prhs[0]);
+  zp = mxGetPr(plhs[0]);
+  sp = mxGetPr(prhs[1]);
+  
+  xnd = mxGetNumberOfDimensions(prhs[0]);
+  ynd = mxGetNumberOfDimensions(prhs[1]);
+  xdim = mxGetDimensions(prhs[0]);
+  ydim = mxGetDimensions(prhs[1]);
+  ndim = xnd;
+  
+  NB = mxGetNumberOfElements(prhs[0]);
+  NS = mxGetNumberOfElements(prhs[1]);
+  
+  if(NS == 1){
+    for(i=0; i<NB; i++){
+      *zp++ *= *sp;
+    }
+    return;
+  }
+  
+  if(NS == NB){
+    for(i=0; i<NB; i++){
+      *zp++ *= *sp++;
+    }
+    return;
+  }
+  
+  sx = (int *)malloc(sizeof(int)*ndim);
+  sy = (int *)malloc(sizeof(int)*ndim);
+  s =  (int *)malloc(sizeof(int)*ndim);
+  *(cpsy = (int *)malloc(sizeof(int)*ndim)) = 1;
+  subs =   (int *)malloc(sizeof(int)*ndim);
+  cpsy2 =  (int *)malloc(sizeof(int)*ndim);
+  for(i=0; i<ndim; i++){
+    subs[i] = 0;
+    sx[i] = xdim[i];
+    sy[i] = (i < ynd) ? ydim[i] : 1;
+    s[i] = sx[i] - 1;
+  }
+  
+  for (i = 0; i < ndim-1; i++){
+    cpsy[i+1] = cpsy[i]*sy[i]--;
+    cpsy2[i] = cpsy[i]*sy[i];
+  }
+  cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);
+  
+  for(j=0; j<NB; j++){
+    *zp++ *= *sp;
+    for(i=0; i<ndim; i++){
+      if(subs[i] == s[i]){
+	subs[i] = 0;
+	if(sy[i]) sp -= cpsy2[i];
+      }
+      else{
+	subs[i]++;
+	if(sy[i]) sp += cpsy[i];
+	break;
+      }
+    }
+  }
+  free(sx);
+  free(sy);
+  free(s);
+  free(cpsy);
+  free(subs);
+  free(cpsy2);
+}
diff --git a/sourcecodes/bnt-master/BNT/potentials/check_for_cd_arcs.m b/sourcecodes/bnt-master/BNT/potentials/check_for_cd_arcs.m
new file mode 100644
index 00000000..8915d533
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/check_for_cd_arcs.m
@@ -0,0 +1,23 @@
+function check_for_cd_arcs(onodes, cnodes, dag)
+% CHECK_FOR_CD_ARCS Raise an error if there are any C->D links where the C node is hidden.
+% check_for_cd_arcs(onodes, cnodes, dag)
+%
+% We cannot convert the logistic/softmax function (C->D CPD) to a Gaussian potential
+% unless we use the variational approximation discussed in 
+% "A variational approximation for Bayesian networks with discrete and continuous latent
+% variables", K. Murphy, UAI 1999.
+
+n = length(dag);
+hnodes = mysetdiff(1:n, onodes);
+chid = myintersect(cnodes, hnodes);
+dnodes = mysetdiff(1:n, cnodes);
+for i=chid(:)'
+  dcs = myintersect(children(dag, i), dnodes);
+  if ~isempty(dcs)
+    error(['hidden cts node ' num2str(i) ' has a discrete child']);
+  end
+end
+
+
+
+
diff --git a/sourcecodes/bnt-master/BNT/potentials/determine_pot_type.m b/sourcecodes/bnt-master/BNT/potentials/determine_pot_type.m
new file mode 100644
index 00000000..772cc84e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/determine_pot_type.m
@@ -0,0 +1,25 @@
+function pot_type = determine_pot_type(model, onodes, nodes)
+% DETERMINE_POT_TYPE Determine the type of potential based on the evidence pattern.
+% pot_type = determine_pot_type(model, onodes, nodes)
+%
+% If there are any utility nodes, pot_type = 'u'
+% else
+% If all hidden nodes are discrete, pot_type = 'd'.
+% If all hidden nodes are continuous, pot_type = 'g' (Gaussian).
+% If some hidden nodes are discrete, and some cts, pot_type = 'cg' (conditional Gaussian).
+%
+% nodes defaults to all nodes in graph
+
+nnodes = length(model.node_sizes);
+if nargin < 3, nodes = 1:nnodes; end
+
+hnodes = mysetdiff(nodes, onodes);
+if isfield(model, 'limid') %~isempty(model.utility_nodes)
+  pot_type = 'u';
+elseif isempty(myintersect(model.cnodes, hnodes))
+  pot_type = 'd';
+elseif mysubset(hnodes, model.cnodes)
+  pot_type = 'g';
+else
+  pot_type = 'cg';
+end
diff --git a/sourcecodes/bnt-master/BNT/potentials/genops.c b/sourcecodes/bnt-master/BNT/potentials/genops.c
new file mode 100644
index 00000000..0416ff68
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/genops.c
@@ -0,0 +1,707 @@
+/*
+
+	GENOPS.C
+		Generalized arithmetic operators overloading built-in functions.
+
+	written by Douglas M. Schwarz
+	schwarz@servtech.com
+	26 December 1998
+	Last modified: 2 April 1999
+
+	Copyright 1998-1999 by Douglas M. Schwarz.  All rights reserved.
+
+*/
+
+
+/*
+
+Build MEX file by entering the appropriate command at the MATLAB prompt
+(-D<name> option is equivalent to #define <name> in source file):
+
+mex genops.c -DPLUS_MEX -output plus
+mex genops.c -DMINUS_MEX -output minus
+mex genops.c -DTIMES_MEX -output times
+mex genops.c -DRDIVIDE_MEX -output rdivide
+mex genops.c -DLDIVIDE_MEX -output ldivide
+mex genops.c -DPOWER_MEX -output power
+mex genops.c -DEQ_MEX -output eq
+mex genops.c -DNE_MEX -output ne
+mex genops.c -DLT_MEX -output lt
+mex genops.c -DGT_MEX -output gt
+mex genops.c -DLE_MEX -output le
+mex genops.c -DGE_MEX -output ge
+
+*/
+
+/*	This file has been formatted for a tab equal to 4 spaces. */
+
+#if defined(EQ_MEX) || defined(NE_MEX) || defined(LT_MEX) || defined(GT_MEX) \
+		|| defined(LE_MEX) || defined(GE_MEX)
+#define	RELOP_MEX
+#endif
+
+#include "mex.h"
+#include "matrix.h"
+#ifdef POWER_MEX
+#include <math.h>
+#define PI 3.141592653589793
+#endif
+
+bool allequal(int, const int *, const int *);
+void removeZeroImag(double *, double *, int, const int *, int, mxArray **);
+
+#define	xMat  prhs[0]
+#define	yMat  prhs[1]
+#define	zMat  plhs[0]
+
+#define	min(A,B)  ((A) < (B) ? (A) : (B))
+#define	max(A,B)  ((A) > (B) ? (A) : (B))
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
+{
+	double		*xrp, *xip, *yrp, *yip;
+#ifndef RELOP_MEX
+	double		*zr, *zi, *zip;
+#endif
+	double		*zrp, *zrend;
+	int			xnd, ynd, numElements = 1;
+	const int	*xdim, *ydim;
+	bool		xcmplx, ycmplx;
+	mxClassID	yclass;
+	int			*s, ndim, *sx, *sy, i, *cpsx, *cpsy;
+	int			*subs, *s1, *cpsx2, *cpsy2;
+	int			ix = 0, iy = 0;
+	mxArray		*args[3], *result[1];
+#if defined(RDIVIDE_MEX) || defined(LDIVIDE_MEX)
+	double		denom;
+#endif
+#ifdef POWER_MEX
+	double		mag, theta, phi, magx;
+	int			flops = 0;
+#endif
+	
+	
+	if (nrhs != 2)
+		mexErrMsgTxt("Incorrect number of inputs.");
+	
+	if (nlhs > 1)
+		mexErrMsgTxt("Too many output arguments.");
+	
+	xnd = mxGetNumberOfDimensions(xMat);
+	ynd = mxGetNumberOfDimensions(yMat);
+	xdim = mxGetDimensions(xMat);
+	ydim = mxGetDimensions(yMat);
+	
+	yclass = mxGetClassID(yMat);
+	
+/*	If the built-in function in MATLAB can handle the arguments
+	then use that. */
+	if (yclass != mxDOUBLE_CLASS || 
+		(xnd == 2  &&  xdim[0] == 1  &&  xdim[1] == 1) || 
+		(ynd == 2  &&  ydim[0] == 1  &&  ydim[1] == 1) || 
+		(xnd == ynd  &&  allequal(xnd,xdim,ydim)))
+	{
+#ifdef PLUS_MEX
+		args[0] = mxCreateString("plus");
+#elif defined(MINUS_MEX)
+		args[0] = mxCreateString("minus");
+#elif defined(TIMES_MEX)
+		args[0] = mxCreateString("times");
+#elif defined(RDIVIDE_MEX)
+		args[0] = mxCreateString("rdivide");
+#elif defined(LDIVIDE_MEX)
+		args[0] = mxCreateString("ldivide");
+#elif defined(POWER_MEX)
+		args[0] = mxCreateString("power");
+#elif defined(EQ_MEX)
+		args[0] = mxCreateString("eq");
+#elif defined(NE_MEX)
+		args[0] = mxCreateString("ne");
+#elif defined(LT_MEX)
+		args[0] = mxCreateString("lt");
+#elif defined(GT_MEX)
+		args[0] = mxCreateString("gt");
+#elif defined(LE_MEX)
+		args[0] = mxCreateString("le");
+#elif defined(GE_MEX)
+		args[0] = mxCreateString("ge");
+#endif
+		args[1] = (mxArray *)xMat;
+		args[2] = (mxArray *)yMat;
+		mexCallMATLAB(1, result, 3, args, "builtin");
+		mxDestroyArray(args[0]);
+		zMat = result[0];
+	}
+	else  /* X and Y are both N-D and different dimensionality. */
+	{
+		ndim = max(xnd,ynd);
+		sx = (int *)mxMalloc(sizeof(int)*ndim);
+		sy = (int *)mxMalloc(sizeof(int)*ndim);
+		s =  (int *)mxMalloc(sizeof(int)*ndim);
+		s1 = (int *)mxMalloc(sizeof(int)*ndim);
+		*(cpsx = (int *)mxMalloc(sizeof(int)*ndim)) = 1;
+		*(cpsy = (int *)mxMalloc(sizeof(int)*ndim)) = 1;
+		subs =   (int *)mxMalloc(sizeof(int)*ndim);
+		cpsx2 =  (int *)mxMalloc(sizeof(int)*ndim);
+		cpsy2 =  (int *)mxMalloc(sizeof(int)*ndim);
+		for (i = 0; i < ndim; i++)
+		{
+			subs[i] = 0;
+			sx[i] = (i < xnd) ? xdim[i] : 1;
+			sy[i] = (i < ynd) ? ydim[i] : 1;
+			if (sx[i] == sy[i])
+				s[i] = sx[i];
+			else if (sx[i] == 1)
+				s[i] = sy[i];
+			else if (sy[i] == 1)
+				s[i] = sx[i];
+			else
+			{
+				mxFree(sx);
+				mxFree(sy);
+				mxFree(s);
+				mxFree(s1);
+				mxFree(cpsx);
+				mxFree(cpsy);
+				mxFree(subs);
+				mxFree(cpsx2);
+				mxFree(cpsy2);
+				mexErrMsgTxt("Array dimensions are not appropriate.");
+			}
+			s1[i] = s[i] - 1;
+			numElements *= s[i];
+		}
+				
+		for (i = 0; i < ndim-1; i++)
+		{
+			cpsx[i+1] = cpsx[i]*sx[i]--;
+			cpsy[i+1] = cpsy[i]*sy[i]--;
+			cpsx2[i] = cpsx[i]*sx[i];
+			cpsy2[i] = cpsy[i]*sy[i];
+		}
+		cpsx2[ndim-1] = cpsx[ndim-1]*(--sx[ndim-1]);
+		cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);
+		
+		xcmplx = mxIsComplex(xMat);
+		ycmplx = mxIsComplex(yMat);
+		
+		if (!xcmplx && !ycmplx)  /* X and Y both N-D, both real. */
+		{
+#ifdef POWER_MEX
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
+			zrp = zr = mxGetPr(zMat);
+			zip = zi = mxGetPi(zMat);
+#elif defined(RELOP_MEX)
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
+			mxSetLogical(zMat);
+			zrp = mxGetPr(zMat);
+#else
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
+			zrp = mxGetPr(zMat);
+#endif
+			xrp = mxGetPr(xMat);
+			yrp = mxGetPr(yMat);
+			zrend = zrp + numElements;
+			while (zrp < zrend)
+			{
+#ifdef PLUS_MEX
+				*zrp++ = *xrp + *yrp;
+#elif defined(MINUS_MEX)
+				*zrp++ = *xrp - *yrp;
+#elif defined(TIMES_MEX)
+				*zrp++ = *xrp * *yrp;
+#elif defined(RDIVIDE_MEX)
+				*zrp++ = *xrp / *yrp;
+#elif defined(LDIVIDE_MEX)
+				*zrp++ = *yrp / *xrp;
+#elif defined(POWER_MEX)
+				if (*xrp < 0.0 && *yrp != floor(*yrp))
+				{
+					mag = pow(-*xrp,*yrp);
+					theta = PI * *yrp;
+					*zrp++ = mag*cos(theta);
+					*zip++ = mag*sin(theta);
+					flops += 18;
+				}
+				else
+				{
+					*zrp++ = pow(*xrp,*yrp);
+					*zip++ = 0.0;
+					flops++;
+				}
+#elif defined(EQ_MEX)
+				*zrp++ = (*xrp == *yrp);
+#elif defined(NE_MEX)
+				*zrp++ = (*xrp != *yrp);
+#elif defined(LT_MEX)
+				*zrp++ = (*xrp < *yrp);
+#elif defined(GT_MEX)
+				*zrp++ = (*xrp > *yrp);
+#elif defined(LE_MEX)
+				*zrp++ = (*xrp <= *yrp);
+#elif defined(GE_MEX)
+				*zrp++ = (*xrp >= *yrp);
+#endif
+				for (i = 0; i < ndim; i++)
+				{
+					if (subs[i] == s1[i])
+					{
+						subs[i] = 0;
+						if (sx[i])
+							xrp -= cpsx2[i];
+						if (sy[i])
+							yrp -= cpsy2[i];
+					}
+					else
+					{
+						subs[i]++;
+						if (sx[i])
+							xrp += cpsx[i];
+						if (sy[i])
+							yrp += cpsy[i];
+						break;
+					}
+				}
+			}
+#ifdef POWER_MEX
+			mexAddFlops(flops);
+			removeZeroImag(zr, zi, ndim, (const int *)s, numElements, &zMat);
+#elif !defined(RELOP_MEX)
+			mexAddFlops(numElements);
+#endif
+		}
+		else if (!xcmplx && ycmplx)  /* X and Y both N-D, X real, Y complex. */
+		{
+#ifdef POWER_MEX
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
+			zrp = zr = mxGetPr(zMat);
+			zip = zi = mxGetPi(zMat);
+#elif defined(RELOP_MEX)
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
+			mxSetLogical(zMat);
+			zrp = mxGetPr(zMat);
+#else
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
+			zrp = mxGetPr(zMat);
+			zip = mxGetPi(zMat);
+#endif
+			xrp = mxGetPr(xMat);
+			yrp = mxGetPr(yMat);
+			yip = mxGetPi(yMat);
+			zrend = zrp + numElements;
+			while (zrp < zrend)
+			{
+#ifdef PLUS_MEX
+				*zrp++ = *xrp + *yrp;
+				*zip++ = *yip;
+#elif defined(MINUS_MEX)
+				*zrp++ = *xrp - *yrp;
+				*zip++ = -*yip;
+#elif defined(TIMES_MEX)
+				*zrp++ = *xrp * *yrp;
+				*zip++ = *xrp * *yip;
+#elif defined(RDIVIDE_MEX)
+				denom = *yrp * *yrp + *yip * *yip;
+				*zrp++ = (*xrp * *yrp)/denom;
+				*zip++ = (-*xrp * *yip)/denom;
+#elif defined(LDIVIDE_MEX)
+				*zrp++ = *yrp / *xrp;
+				*zip++ = *yip / *xrp;
+#elif defined(POWER_MEX)
+				if (*yip == 0.0)
+				{
+					if (*xrp < 0.0 && *yrp != floor(*yrp))
+					{
+						mag = pow(-*xrp,*yrp);
+						theta = PI * *yrp;
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 18;
+					}
+					else
+					{
+						*zrp++ = pow(*xrp,*yrp);
+						*zip++ = 0.0;
+						flops++;
+					}
+				}
+				else
+				{
+					if (*xrp < 0.0)
+					{
+						mag = pow(-*xrp,*yrp)*exp(-PI * *yip);
+						theta = *yip * log(-*xrp) + PI * *yrp;
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 18;
+					}
+					else
+					{
+						mag = pow(*xrp,*yrp);
+						theta = *yip * log(*xrp);
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 13;
+					}
+				}
+#elif defined(EQ_MEX)
+				*zrp++ = (*xrp == *yrp) && (*yip == 0.0);
+#elif defined(NE_MEX)
+				*zrp++ = (*xrp != *yrp) || (*yip != 0.0);
+#elif defined(LT_MEX)
+				*zrp++ = (*xrp < *yrp);
+#elif defined(GT_MEX)
+				*zrp++ = (*xrp > *yrp);
+#elif defined(LE_MEX)
+				*zrp++ = (*xrp <= *yrp);
+#elif defined(GE_MEX)
+				*zrp++ = (*xrp >= *yrp);
+#endif
+				for (i = 0; i < ndim; i++)
+				{
+					if (subs[i] == s1[i])
+					{
+						subs[i] = 0;
+						if (sx[i])
+							xrp -= cpsx2[i];
+						if (sy[i])
+						{
+							yrp -= cpsy2[i];
+							yip -= cpsy2[i];
+						}
+					}
+					else
+					{
+						subs[i]++;
+						if (sx[i])
+							xrp += cpsx[i];
+						if (sy[i])
+						{
+							yrp += cpsy[i];
+							yip += cpsy[i];
+						}
+						break;
+					}
+				}
+			}
+#if defined(PLUS_MEX) || defined(MINUS_MEX)
+			mexAddFlops(2*numElements);
+#elif defined(TIMES_MEX) || defined(RDIVIDE_MEX) || defined(LDIVIDE_MEX)
+			mexAddFlops(6*numElements);
+#elif defined(POWER_MEX)
+			mexAddFlops(flops);
+			removeZeroImag(zr, zi, ndim, (const int *)s, numElements, &zMat);
+#endif
+		}
+		else if (xcmplx && !ycmplx)  /* X and Y both N-D, X complex, Y real. */
+		{
+#ifdef POWER_MEX
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
+			zrp = zr = mxGetPr(zMat);
+			zip = zi = mxGetPi(zMat);
+#elif defined(RELOP_MEX)
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
+			mxSetLogical(zMat);
+			zrp = mxGetPr(zMat);
+#else
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
+			zrp = mxGetPr(zMat);
+			zip = mxGetPi(zMat);
+#endif
+			xrp = mxGetPr(xMat);
+			xip = mxGetPi(xMat);
+			yrp = mxGetPr(yMat);
+			zrend = zrp + numElements;
+			while (zrp < zrend)
+			{
+#ifdef PLUS_MEX
+				*zrp++ = *xrp + *yrp;
+				*zip++ = *xip;
+#elif defined(MINUS_MEX)
+				*zrp++ = *xrp - *yrp;
+				*zip++ = *xip;
+#elif defined(TIMES_MEX)
+				*zrp++ = *xrp * *yrp;
+				*zip++ = *xip * *yrp;
+#elif defined(RDIVIDE_MEX)
+				*zrp++ = *xrp / *yrp;
+				*zip++ = *xip / *yrp;
+#elif defined(LDIVIDE_MEX)
+				denom = *xrp * *xrp + *xip * *xip;
+				*zrp++ = (*xrp * *yrp)/denom;
+				*zip++ = (-*xip * *yrp)/denom;
+#elif defined(POWER_MEX)
+				if (*xip == 0.0)
+				{
+					if (*xrp < 0.0 && *yrp != floor(*yrp))
+					{
+						mag = pow(-*xrp,*yrp);
+						theta = PI * *yrp;
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 18;
+					}
+					else
+					{
+						*zrp++ = pow(*xrp,*yrp);
+						*zip++ = 0.0;
+						flops++;
+					}
+				}
+				else
+				{
+					mag = pow(*xrp * *xrp + *xip * *xip,0.5 * *yrp);
+					theta = *yrp*atan2(*xip,*xrp);
+					*zrp++ = mag*cos(theta);
+					*zip++ = mag*sin(theta);
+					flops += 18;
+				}
+#elif defined(EQ_MEX)
+				*zrp++ = (*xrp == *yrp) && (*xip == 0.0);
+#elif defined(NE_MEX)
+				*zrp++ = (*xrp != *yrp) || (*xip != 0.0);
+#elif defined(LT_MEX)
+				*zrp++ = (*xrp < *yrp);
+#elif defined(GT_MEX)
+				*zrp++ = (*xrp > *yrp);
+#elif defined(LE_MEX)
+				*zrp++ = (*xrp <= *yrp);
+#elif defined(GE_MEX)
+				*zrp++ = (*xrp >= *yrp);
+#endif
+				for (i = 0; i < ndim; i++)
+				{
+					if (subs[i] == s1[i])
+					{
+						subs[i] = 0;
+						if (sx[i])
+						{
+							xrp -= cpsx2[i];
+							xip -= cpsx2[i];
+						}
+						if (sy[i])
+							yrp -= cpsy2[i];
+					}
+					else
+					{
+						subs[i]++;
+						if (sx[i])
+						{
+							xrp += cpsx[i];
+							xip += cpsx[i];
+						}
+						if (sy[i])
+							yrp += cpsy[i];
+						break;
+					}
+				}
+			}
+#if defined(PLUS_MEX) || defined(MINUS_MEX)
+			mexAddFlops(2*numElements);
+#elif defined(TIMES_MEX) || defined(RDIVIDE_MEX) || defined(LDIVIDE_MEX)
+			mexAddFlops(6*numElements);
+#elif defined(POWER_MEX)
+			mexAddFlops(flops);
+			removeZeroImag(zr, zi, ndim, (const int *)s, numElements, &zMat);
+#endif
+		}
+		else if (xcmplx && ycmplx)  /* X and Y both N-D, both complex. */
+		{
+#if defined(RELOP_MEX)
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
+			mxSetLogical(zMat);
+			zrp = mxGetPr(zMat);
+#else
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
+			zrp = zr = mxGetPr(zMat);
+			zip = zi = mxGetPi(zMat);
+#endif
+			xrp = mxGetPr(xMat);
+			xip = mxGetPi(xMat);
+			yrp = mxGetPr(yMat);
+			yip = mxGetPi(yMat);
+			zrend = zrp + numElements;
+			while (zrp < zrend)
+			{
+#ifdef PLUS_MEX
+				*zrp++ = *xrp + *yrp;
+				*zip++ = *xip + *yip;
+#elif defined(MINUS_MEX)
+				*zrp++ = *xrp - *yrp;
+				*zip++ = *xip - *yip;
+#elif defined(TIMES_MEX)
+				*zrp++ = *xrp * *yrp - *xip * *yip;
+				*zip++ = *xip * *yrp + *xrp * *yip;
+#elif defined(RDIVIDE_MEX)
+				denom = *yrp * *yrp + *yip * *yip;
+				*zrp++ = (*xrp * *yrp + *xip * *yip)/denom;
+				*zip++ = (*xip * *yrp - *xrp * *yip)/denom;
+#elif defined(LDIVIDE_MEX)
+				denom = *xrp * *xrp + *xip * *xip;
+				*zrp++ = (*xrp * *yrp + *xip * *yip)/denom;
+				*zip++ = (*xrp * *yip - *xip * *yrp)/denom;
+#elif defined(POWER_MEX)
+				if (*xip == 0.0 && *yip == 0.0)
+				{
+					if (*xrp < 0.0 && *yrp != floor(*yrp))
+					{
+						mag = pow(-*xrp,*yrp);
+						theta = PI * *yrp;
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 18;
+					}
+					else
+					{
+						*zrp++ = pow(*xrp,*yrp);
+						*zip++ = 0.0;
+						flops++;
+					}
+				}
+				else if (*xip == 0.0)
+				{
+					if (*xrp < 0.0)
+					{
+						mag = pow(-*xrp,*yrp)*exp(-PI * *yip);
+						theta = *yip * log(-*xrp) + PI * *yrp;
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 18;
+					}
+					else
+					{
+						mag = pow(*xrp,*yrp);
+						theta = *yip * log(*xrp);
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 13;
+					}
+				}
+				else if (*yip == 0.0)
+				{
+					mag = pow(*xrp * *xrp + *xip * *xip,0.5 * *yrp);
+					theta = *yrp * atan2(*xip,*xrp);
+					*zrp++ = mag*cos(theta);
+					*zip++ = mag*sin(theta);
+					flops += 18;
+				}
+				else
+				{
+					magx = sqrt(*xrp * *xrp + *xip * *xip);
+					phi = atan2(*xip,*xrp);
+					mag = pow(magx,*yrp)*exp(-*yip * phi);
+					theta = *yip * log(magx) + *yrp * phi;
+					*zrp++ = mag*cos(theta);
+					*zip++ = mag*sin(theta);
+					flops += 18;
+				}
+#elif defined(EQ_MEX)
+				*zrp++ = (*xrp == *yrp) && (*xip == *yip);
+#elif defined(NE_MEX)
+				*zrp++ = (*xrp != *yrp) || (*xip != *yip);
+#elif defined(LT_MEX)
+				*zrp++ = (*xrp < *yrp);
+#elif defined(GT_MEX)
+				*zrp++ = (*xrp > *yrp);
+#elif defined(LE_MEX)
+				*zrp++ = (*xrp <= *yrp);
+#elif defined(GE_MEX)
+				*zrp++ = (*xrp >= *yrp);
+#endif
+				for (i = 0; i < ndim; i++)
+				{
+					if (subs[i] == s1[i])
+					{
+						subs[i] = 0;
+						if (sx[i])
+						{
+							xrp -= cpsx2[i];
+							xip -= cpsx2[i];
+						}
+						if (sy[i])
+						{
+							yrp -= cpsy2[i];
+							yip -= cpsy2[i];
+						}
+					}
+					else
+					{
+						subs[i]++;
+						if (sx[i])
+						{
+							xrp += cpsx[i];
+							xip += cpsx[i];
+						}
+						if (sy[i])
+						{
+							yrp += cpsy[i];
+							yip += cpsy[i];
+						}
+						break;
+					}
+				}
+			}
+#if defined(PLUS_MEX) || defined(MINUS_MEX)
+			mexAddFlops(2*numElements);
+#elif defined(TIMES_MEX) || defined(RDIVIDE_MEX) || defined(LDIVIDE_MEX)
+			mexAddFlops(6*numElements);
+#elif defined(POWER_MEX)
+			mexAddFlops(flops);
+#endif
+#ifndef RELOP_MEX
+			removeZeroImag(zr, zi, ndim, (const int *)s, numElements, &zMat);
+#endif
+		}
+	}
+}
+
+
+/***********************************************************
+*                                                          *
+*   Tests to see if the vectors xdim and ydim are equal.   *
+*                                                          *
+***********************************************************/
+bool allequal(int ndim, const int *xdim, const int *ydim)
+{
+	int		i;
+	bool	result = true;
+	
+	for (i = 0; i < ndim; i++)
+		result = result && (xdim[i] == ydim[i]);
+	
+	return(result);
+}
+
+
+/******************************************************************************
+*                                                                             *
+*   Tests to see if every imaginary element is identically zero and, if so,   *
+*   creates a new array which is real and copies the real elements to it.     *
+*                                                                             *
+******************************************************************************/
+void removeZeroImag(double *zr, double *zi, int ndim, const int *s,
+					int numElements, mxArray *plhs[])
+{
+	double			*zrend, *ziend, *zip, *z1p, *z2p;
+	bool			allImZero = true;
+	mxArray			*temp;
+	
+	zip = zi;
+	ziend = zi + numElements;
+	while (zip < ziend)
+	{
+		allImZero = allImZero && (*zip++ == 0.0);
+		if (!allImZero)
+			return;
+	}
+	
+	temp = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
+	z1p = zr;
+	z2p = mxGetPr(temp);
+	zrend = z1p + numElements;
+	while (z1p < zrend)
+		*z2p++ = *z1p++;
+	mxDestroyArray(plhs[0]);
+	plhs[0] = temp;
+	return;
+}
diff --git a/sourcecodes/bnt-master/BNT/potentials/mk_initial_pot.m b/sourcecodes/bnt-master/BNT/potentials/mk_initial_pot.m
new file mode 100644
index 00000000..0a52731c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/mk_initial_pot.m
@@ -0,0 +1,29 @@
+function pot = mk_initial_pot(pot_type, dom, ns, cnodes, onodes)
+% MK_INITIAL_POT A "initial" potential is one which has not had any evidence entered into it.
+% pot = mk_initial_pot(pot_type, domain, node_sizes, cnodes, onodes)
+%
+% pot_type is one of 'd', 'g', 'cg' or 'u'
+% domain is the set of nodes to be included in the potential.
+% node_sizes(i) is the size of node i.
+
+switch pot_type 
+ case 'd',
+  ns(onodes) = 1;
+  pot = dpot(dom, ns(dom));
+ case 'u',
+  ns(onodes) = 1;
+  pot = upot(dom, ns(dom));
+ case 'g',
+  ns(onodes) = 0;
+  pot = cpot(dom, ns(dom));
+ case 'cg',
+  dnodes = mysetdiff(1:length(ns), cnodes);
+  ddom = myintersect(dnodes, dom);
+  cdom = myintersect(cnodes, dom);
+  dobs = myintersect(dnodes, onodes);
+  cobs = myintersect(cnodes, onodes);
+  ns(dobs) = 1;
+  ns(cobs) = 0;
+  pot = cgpot(ddom, cdom, ns);
+end
+
diff --git a/sourcecodes/bnt-master/BNT/test_BNT.m b/sourcecodes/bnt-master/BNT/test_BNT.m
new file mode 100644
index 00000000..0db86e2e
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/test_BNT.m
@@ -0,0 +1,108 @@
+% If all is well, all of these scripts should run without errors.
+
+
+% bnets
+cg1
+cg2
+discrete1
+fa1
+gaussian1
+gaussian2
+if exist('@gibbs_sampling_inf_engine/private/compute_posterior','file')
+  % only exists if installC has been run
+  gibbs_test1
+end
+learn1
+lw1
+mfa1
+mixexp1
+mixexp2
+mixexp3
+mog1
+mpe1
+mpe2
+qmr1
+qmr2
+sample1
+softev1
+softmax1
+sprinkler1
+
+
+% belief propagation
+belprop_polytree_discrete
+belprop_polytree_gauss % alag
+belprop_polytree_cg
+belprop_loop1_discrete
+belprop_loop1_gauss
+belprop_loopy_discrete
+belprop_loopy_gauss
+belprop_loopy_cg % like cg1
+
+
+% factor graphs
+%fg1   failed since marginals were not exact
+
+fg2
+fg3
+fg_mrf1
+fg_mrf2
+
+
+% Structure learning
+bic1
+cooper_yoo
+k2demo1
+mcmc1
+model_select1
+pc1
+%pc2   failed due to numerical problems in KPMstats/cond_indep_fisher_z
+
+
+
+
+% limids
+asia_dt1
+id1
+oil1
+pigs1
+
+
+% dbns
+arhmm1
+bat1
+bkff1
+chmm1
+dhmm1
+filter_test1
+ghmm1
+kalman1
+kjaerulff1
+loopy_dbn1
+mhmm1
+mildew1
+reveal1
+viterbi1
+water1
+
+
+% HHMMs
+abcd_hhmm
+sample_square_hhmm_discrete
+%learn_square_hhmm_cts
+sample_motif_hhmm
+
+%sparse jtree engine & ndx 2TBN engine
+if exist('@jtree_sparse_inf_engine/init_pot','file')
+  % only exists if installC has been run
+  discrete2
+  discrete3 
+  filter_test1
+  water2
+end
+
+%find . -path '*.m' -exec wc -l {} \; | ~/count.pl
+
+% we cannot use tic;toc to time test_BNT, since functions within this script
+% reset the tic;toc timer. Hence we use the following:
+%clock0=clock; cpu0 = cputime; test_BNT; cpu=cputime-cpu0; elapsed=etime(clock, clock0)
diff --git a/sourcecodes/bnt-master/BNT/uninstallC_BNT.m b/sourcecodes/bnt-master/BNT/uninstallC_BNT.m
new file mode 100644
index 00000000..2dd51543
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/uninstallC_BNT.m
@@ -0,0 +1,17 @@
+dirs = {'potentials/Tables', ...
+	'CPDs/@discrete_CPD', ...
+      'inference/static/@jtree_sparse_inf_engine', ...
+      'inference/static/@gibbs_sampling_inf_engine/private'};
+
+BNT_HOME = '/home/ai2/murphyk/matlab/FullBNT'; % edit this
+%global BNT_HOME
+
+for d=1:length(dirs)
+  f = fullfile(BNT_HOME, 'BNT', dirs{d});
+  fprintf('removing Cmex files from %s\n', f);
+  cd(f)
+  delete *.mex*
+  delete *.dll
+  delete *.obj
+  delete *.o
+end