about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/BNT/general
diff options
context:
space:
mode:
Diffstat (limited to 'sourcecodes/bnt-master/BNT/general')
-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
64 files changed, 2654 insertions, 0 deletions
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;
+