about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/KPMstats
diff options
context:
space:
mode:
Diffstat (limited to 'sourcecodes/bnt-master/KPMstats')
-rw-r--r--sourcecodes/bnt-master/KPMstats/CVS/Entries80
-rw-r--r--sourcecodes/bnt-master/KPMstats/CVS/Repository1
-rw-r--r--sourcecodes/bnt-master/KPMstats/CVS/Root1
-rw-r--r--sourcecodes/bnt-master/KPMstats/KLgauss.m9
-rw-r--r--sourcecodes/bnt-master/KPMstats/README.txt4
-rw-r--r--sourcecodes/bnt-master/KPMstats/beta_sample.m76
-rw-r--r--sourcecodes/bnt-master/KPMstats/chisquared_histo.m5
-rw-r--r--sourcecodes/bnt-master/KPMstats/chisquared_prob.m35
-rw-r--r--sourcecodes/bnt-master/KPMstats/chisquared_readme.txt36
-rw-r--r--sourcecodes/bnt-master/KPMstats/chisquared_table.m63
-rw-r--r--sourcecodes/bnt-master/KPMstats/clg_Mstep.m203
-rw-r--r--sourcecodes/bnt-master/KPMstats/clg_Mstep_simple.m52
-rw-r--r--sourcecodes/bnt-master/KPMstats/clg_prob.m14
-rw-r--r--sourcecodes/bnt-master/KPMstats/condGaussToJoint.m22
-rw-r--r--sourcecodes/bnt-master/KPMstats/cond_indep_fisher_z.m142
-rw-r--r--sourcecodes/bnt-master/KPMstats/condgaussTrainObserved.m27
-rw-r--r--sourcecodes/bnt-master/KPMstats/condgauss_sample.m11
-rw-r--r--sourcecodes/bnt-master/KPMstats/convertBinaryLabels.m3
-rw-r--r--sourcecodes/bnt-master/KPMstats/cwr_demo.m124
-rw-r--r--sourcecodes/bnt-master/KPMstats/cwr_em.m161
-rw-r--r--sourcecodes/bnt-master/KPMstats/cwr_predict.m57
-rw-r--r--sourcecodes/bnt-master/KPMstats/cwr_prob.m39
-rw-r--r--sourcecodes/bnt-master/KPMstats/cwr_readme.txt20
-rw-r--r--sourcecodes/bnt-master/KPMstats/cwr_test.m80
-rw-r--r--sourcecodes/bnt-master/KPMstats/dirichlet_sample.m18
-rw-r--r--sourcecodes/bnt-master/KPMstats/dirichletpdf.m39
-rw-r--r--sourcecodes/bnt-master/KPMstats/dirichletrnd.m32
-rw-r--r--sourcecodes/bnt-master/KPMstats/distchck.m173
-rw-r--r--sourcecodes/bnt-master/KPMstats/eigdec.m59
-rw-r--r--sourcecodes/bnt-master/KPMstats/est_transmat.m15
-rw-r--r--sourcecodes/bnt-master/KPMstats/fit_paritioned_model_testfn.m5
-rw-r--r--sourcecodes/bnt-master/KPMstats/fit_partitioned_model.m59
-rw-r--r--sourcecodes/bnt-master/KPMstats/gamma_sample.m126
-rw-r--r--sourcecodes/bnt-master/KPMstats/gaussian_prob.m28
-rw-r--r--sourcecodes/bnt-master/KPMstats/gaussian_sample.m25
-rw-r--r--sourcecodes/bnt-master/KPMstats/histCmpChi2.m15
-rw-r--r--sourcecodes/bnt-master/KPMstats/linear_regression.m68
-rw-r--r--sourcecodes/bnt-master/KPMstats/logist2.m115
-rw-r--r--sourcecodes/bnt-master/KPMstats/logist2Apply.m13
-rw-r--r--sourcecodes/bnt-master/KPMstats/logist2ApplyRegularized.m3
-rw-r--r--sourcecodes/bnt-master/KPMstats/logist2Fit.m22
-rw-r--r--sourcecodes/bnt-master/KPMstats/logist2FitRegularized.m13
-rw-r--r--sourcecodes/bnt-master/KPMstats/logistK.m287
-rw-r--r--sourcecodes/bnt-master/KPMstats/logistK_eval.m83
-rw-r--r--sourcecodes/bnt-master/KPMstats/marginalize_gaussian.m7
-rw-r--r--sourcecodes/bnt-master/KPMstats/matrix_T_pdf.m12
-rw-r--r--sourcecodes/bnt-master/KPMstats/matrix_normal_pdf.m9
-rw-r--r--sourcecodes/bnt-master/KPMstats/mc_stat_distrib.m26
-rw-r--r--sourcecodes/bnt-master/KPMstats/mixgauss_Mstep.m106
-rw-r--r--sourcecodes/bnt-master/KPMstats/mixgauss_classifier_apply.m11
-rw-r--r--sourcecodes/bnt-master/KPMstats/mixgauss_classifier_train.m33
-rw-r--r--sourcecodes/bnt-master/KPMstats/mixgauss_em.m74
-rw-r--r--sourcecodes/bnt-master/KPMstats/mixgauss_init.m49
-rw-r--r--sourcecodes/bnt-master/KPMstats/mixgauss_prob.m133
-rw-r--r--sourcecodes/bnt-master/KPMstats/mixgauss_prob_test.m111
-rw-r--r--sourcecodes/bnt-master/KPMstats/mixgauss_sample.m22
-rw-r--r--sourcecodes/bnt-master/KPMstats/mkPolyFvec.m24
-rw-r--r--sourcecodes/bnt-master/KPMstats/mk_unit_norm.m13
-rw-r--r--sourcecodes/bnt-master/KPMstats/multinomial_prob.m20
-rw-r--r--sourcecodes/bnt-master/KPMstats/multinomial_sample.m22
-rw-r--r--sourcecodes/bnt-master/KPMstats/multipdf.m45
-rw-r--r--sourcecodes/bnt-master/KPMstats/multirnd.m48
-rw-r--r--sourcecodes/bnt-master/KPMstats/normal_coef.m7
-rw-r--r--sourcecodes/bnt-master/KPMstats/partial_corr_coef.m28
-rw-r--r--sourcecodes/bnt-master/KPMstats/parzen.m88
-rw-r--r--sourcecodes/bnt-master/KPMstats/parzenC.c116
-rw-r--r--sourcecodes/bnt-master/KPMstats/parzenC.dllbin0 -> 49152 bytes
-rw-r--r--sourcecodes/bnt-master/KPMstats/parzenC_test.m10
-rw-r--r--sourcecodes/bnt-master/KPMstats/parzen_fit_select_unif.m45
-rw-r--r--sourcecodes/bnt-master/KPMstats/pca.m42
-rw-r--r--sourcecodes/bnt-master/KPMstats/rndcheck.m294
-rw-r--r--sourcecodes/bnt-master/KPMstats/sample.m15
-rw-r--r--sourcecodes/bnt-master/KPMstats/sample_discrete.m40
-rw-r--r--sourcecodes/bnt-master/KPMstats/sample_gaussian.m19
-rw-r--r--sourcecodes/bnt-master/KPMstats/standardize.m18
-rw-r--r--sourcecodes/bnt-master/KPMstats/student_t_logprob.m13
-rw-r--r--sourcecodes/bnt-master/KPMstats/student_t_prob.m19
-rw-r--r--sourcecodes/bnt-master/KPMstats/test_dir.m19
-rw-r--r--sourcecodes/bnt-master/KPMstats/unidrndKPM.m7
-rw-r--r--sourcecodes/bnt-master/KPMstats/unif_discrete_sample.m6
-rw-r--r--sourcecodes/bnt-master/KPMstats/weightedRegression.m58
81 files changed, 4072 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/KPMstats/CVS/Entries b/sourcecodes/bnt-master/KPMstats/CVS/Entries
new file mode 100644
index 00000000..9e8985ba
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/CVS/Entries
@@ -0,0 +1,80 @@
+/KLgauss.m/1.1.1.1/Tue Apr 26 02:29:16 2005//
+/README.txt/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/beta_sample.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/chisquared_histo.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/chisquared_prob.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/chisquared_readme.txt/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/chisquared_table.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/clg_Mstep.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/clg_Mstep_simple.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/clg_prob.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/condGaussToJoint.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/cond_indep_fisher_z.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/condgaussTrainObserved.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/condgauss_sample.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/convertBinaryLabels.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/cwr_demo.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/cwr_em.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/cwr_predict.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/cwr_prob.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/cwr_readme.txt/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/cwr_test.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/dirichlet_sample.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/dirichletpdf.m/1.1.1.1/Sun May 22 23:32:18 2005//
+/dirichletrnd.m/1.1.1.1/Sun May 22 23:32:12 2005//
+/distchck.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/eigdec.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/est_transmat.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/fit_paritioned_model_testfn.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/fit_partitioned_model.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/gamma_sample.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/gaussian_prob.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/gaussian_sample.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/histCmpChi2.m/1.1.1.1/Tue May  3 20:18:16 2005//
+/linear_regression.m/1.1.1.1/Tue Apr 26 02:29:18 2005//
+/logist2.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/logist2Apply.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/logist2ApplyRegularized.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/logist2Fit.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/logist2FitRegularized.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/logistK.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/logistK_eval.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/marginalize_gaussian.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/matrix_T_pdf.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/matrix_normal_pdf.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/mc_stat_distrib.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/mixgauss_Mstep.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/mixgauss_classifier_apply.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/mixgauss_classifier_train.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/mixgauss_em.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/mixgauss_init.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/mixgauss_prob.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/mixgauss_prob_test.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/mixgauss_sample.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/mkPolyFvec.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/mk_unit_norm.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/multinomial_prob.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/multinomial_sample.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/multipdf.m/1.1.1.1/Sun May 22 23:32:42 2005//
+/multirnd.m/1.1.1.1/Sun May 22 23:32:38 2005//
+/normal_coef.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/partial_corr_coef.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/parzen.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/parzenC.c/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/parzenC.dll/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/parzenC.mexglx/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/parzenC_test.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/parzen_fit_select_unif.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/pca.m/1.1.1.1/Tue Apr 26 02:29:20 2005//
+/rndcheck.m/1.1.1.1/Tue Apr 26 02:29:22 2005//
+/sample.m/1.1.1.1/Tue Apr 26 02:29:22 2005//
+/sample_discrete.m/1.1.1.1/Tue Apr 26 02:29:22 2005//
+/sample_gaussian.m/1.1.1.1/Tue Apr 26 02:29:22 2005//
+/standardize.m/1.1.1.1/Wed May  4 04:35:36 2005//
+/student_t_logprob.m/1.1.1.1/Tue Apr 26 02:29:22 2005//
+/student_t_prob.m/1.1.1.1/Tue Apr 26 02:29:22 2005//
+/test_dir.m/1.1.1.1/Sun May 22 23:32:20 2005//
+/unidrndKPM.m/1.1.1.1/Tue May 31 18:19:24 2005//
+/unif_discrete_sample.m/1.1.1.1/Tue Apr 26 02:29:22 2005//
+/weightedRegression.m/1.1.1.1/Tue Apr 26 02:29:22 2005//
+D
diff --git a/sourcecodes/bnt-master/KPMstats/CVS/Repository b/sourcecodes/bnt-master/KPMstats/CVS/Repository
new file mode 100644
index 00000000..55a108ab
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/CVS/Repository
@@ -0,0 +1 @@
+FullBNT/KPMstats
diff --git a/sourcecodes/bnt-master/KPMstats/CVS/Root b/sourcecodes/bnt-master/KPMstats/CVS/Root
new file mode 100644
index 00000000..f3bd14a6
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/CVS/Root
@@ -0,0 +1 @@
+:ext:nsaunier@bnt.cvs.sourceforge.net:/cvsroot/bnt
diff --git a/sourcecodes/bnt-master/KPMstats/KLgauss.m b/sourcecodes/bnt-master/KPMstats/KLgauss.m
new file mode 100644
index 00000000..85f00619
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/KLgauss.m
@@ -0,0 +1,9 @@
+function kl = KLgauss(P, Q)
+%The following computes D(P||Q), the KL divergence between two zero-mean
+%Gaussians with covariance P and Q:
+%  klDiv = -0.5*(log(det(P*inv(Q))) + trace(eye(N)-P*inv(Q)));
+
+R = P*inv(Q);
+kl = -0.5*(log(det(R))) + trace(eye(length(P))-R);
+
+%To get MI, just set P=cov(X,Y) and Q=blockdiag(cov(X),cov(Y)).  
diff --git a/sourcecodes/bnt-master/KPMstats/README.txt b/sourcecodes/bnt-master/KPMstats/README.txt
new file mode 100644
index 00000000..29e828d8
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/README.txt
@@ -0,0 +1,4 @@
+KPMstats is a directory of miscellaneous statistics functions written by
+Kevin Patrick Murphy and various other people (see individual file headers).
+
+
diff --git a/sourcecodes/bnt-master/KPMstats/beta_sample.m b/sourcecodes/bnt-master/KPMstats/beta_sample.m
new file mode 100644
index 00000000..82bacbe4
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/beta_sample.m
@@ -0,0 +1,76 @@
+function r = betarnd(a,b,m,n);
+%BETARND Random matrices from beta distribution.
+%   R = BETARND(A,B) returns a matrix of random numbers chosen   
+%   from the beta distribution with parameters A and B.
+%   The size of R is the common size of A and B if both are matrices.
+%   If either parameter is a scalar, the size of R is the size of the other
+%   parameter. Alternatively, R = BETARND(A,B,M,N) returns an M by N matrix. 
+
+%   Reference:
+%      [1]  L. Devroye, "Non-Uniform Random Variate Generation", 
+%      Springer-Verlag, 1986
+
+%   Copyright (c) 1993-98 by The MathWorks, Inc.
+%   $Revision: 1.1.1.1 $  $Date: 2005/04/26 02:29:18 $
+
+if nargin < 2, 
+    error('Requires at least two input arguments'); 
+end 
+
+if nargin == 2
+    [errorcode rows columns] = rndcheck(2,2,a,b);
+end
+
+if nargin == 3
+    [errorcode rows columns] = rndcheck(3,2,a,b,m);
+end
+
+if nargin == 4
+    [errorcode rows columns] = rndcheck(4,2,a,b,m,n);
+end
+
+if errorcode > 0
+    error('Size information is inconsistent.');
+end
+
+r = zeros(rows,columns);
+
+% Use Theorem 4.1, case A (Devroye, page 430) to derive beta
+%   random numbers as a ratio of gamma random numbers.
+if prod(size(a)) == 1
+    a1 = a(ones(rows,1),ones(columns,1));
+    g1 = gamrnd(a1,1);
+else
+    g1 = gamrnd(a,1);
+end
+if prod(size(b)) == 1
+    b1 = b(ones(rows,1),ones(columns,1));
+    g2 = gamrnd(b1,1);
+else
+    g2 = gamrnd(b,1);
+end
+r = g1 ./ (g1 + g2);
+
+% Return NaN if b is not positive.
+if any(any(b <= 0));
+    if prod(size(b) == 1)
+        tmp = NaN;
+        r = tmp(ones(rows,columns));
+    else
+        k = find(b <= 0);
+        tmp = NaN;
+        r(k) = tmp(ones(size(k)));
+    end
+end
+
+% Return NaN if a is not positive.
+if any(any(a <= 0));
+    if prod(size(a) == 1)
+        tmp = NaN;
+        r = tmp(ones(rows,columns));
+    else
+        k = find(a <= 0);
+        tmp = NaN;
+        r(k) = tmp(ones(size(k)));
+    end
+end
diff --git a/sourcecodes/bnt-master/KPMstats/chisquared_histo.m b/sourcecodes/bnt-master/KPMstats/chisquared_histo.m
new file mode 100644
index 00000000..1b649335
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/chisquared_histo.m
@@ -0,0 +1,5 @@
+function s = chisquared_histo(h1, h2)
+% Measure distance between 2 histograms (small numbers means more similar)
+denom = h1 + h2;
+denom = denom + (denom==0);
+s = sum(((h1 - h2) .^ 2) ./ denom);
diff --git a/sourcecodes/bnt-master/KPMstats/chisquared_prob.m b/sourcecodes/bnt-master/KPMstats/chisquared_prob.m
new file mode 100644
index 00000000..4cf6fdc1
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/chisquared_prob.m
@@ -0,0 +1,35 @@
+function P = chisquared_prob(X2,v)
+%CHISQUARED_PROB computes the chi-squared probability function.
+%   P = CHISQUARED_PROB( X2, v ) returns P(X2|v), the probability
+%   of observing a chi-squared value <= X2 with v degrees of freedom.
+%   This is the probability that the sum of squares of v unit-variance
+%   normally-distributed random variables is <= X2.
+%   X2 and v may be matrices of the same size size, or either 
+%   may be a scalar.
+%   
+%   e.g., CHISQUARED_PROB(5.99,2) returns 0.9500, verifying the
+%   95% confidence bound for 2 degrees of freedom. This is also
+%   cross-checked in, e.g., Abramowitz & Stegun Table 26.8
+%
+%   See also CHISQUARED_TABLE
+%
+%Peter R. Shaw, WHOI
+
+% References: Press et al., Numerical Recipes, Cambridge, 1986;
+% Abramowitz & Stegun, Handbook of Mathematical Functions, Dover, 1972.
+
+% Peter R. Shaw, Woods Hole Oceanographic Institution
+% Woods Hole, MA 02543
+% (508) 457-2000 ext. 2473  pshaw@whoi.edu
+% March, 1990; fixed Oct 1992 for version 4
+
+% Computed using the Incomplete Gamma function,
+% as given by Press et al. (Recipes) eq. (6.2.17)
+
+% Following nonsense is necessary from Matlab version 3 -> version 4
+versn_str=version; eval(['versn=' versn_str(1) ';']);
+if versn<=3, %sigh
+ P = gamma(v/2, X2/2);
+else
+ P = gammainc(X2/2, v/2);
+end
diff --git a/sourcecodes/bnt-master/KPMstats/chisquared_readme.txt b/sourcecodes/bnt-master/KPMstats/chisquared_readme.txt
new file mode 100644
index 00000000..fc2ab64c
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/chisquared_readme.txt
@@ -0,0 +1,36 @@
+From ftp://ftp.mathworks.com/pub/contrib/v4/stats/chisquared/
+
+Chi-squared probability function.
+
+Abstract 
+m-files to compute the Chi-squared probability function, and
+the percentage points of the probability function.
+
+P = CHISQUARED_PROB( X2, v ) returns P(X2|v), the probability
+of observing a chi-squared value <= X2 with v degrees of freedom.
+This is the probability that the sum of squares of v unit-variance
+normally-distributed random variables is <= X2.
+
+Conversely:
+X2 = CHISQUARED_TABLE( P, v ) returns the X2, the value of
+chi-squared corresponding to v degrees of freedom and probability P.
+
+In reference textbooks, what is normally tabulated are the
+percentage points of the chi-squared distribution; thus, one
+would use CHISQUARED_TABLE rather than interpolate such a table.
+
+References: Press et al., Numerical Recipes, Cambridge, 1986;
+Abramowitz & Stegun, Handbook of Mathematical Functions,
+Dover, 1972;  Table 26.8
+
+Peter R. Shaw
+Woods Hole Oceanographic Institution, Woods Hole, MA 02543
+(508) 457-2000 ext. 2473
+pshaw@whoi.edu
+
+--FILES GENERATED--
+README_chisq
+chisquared_prob.m  (function) -- chi-squared probability function
+chisquared_table.m  (function) -- "percentage points" (i.e., inverse)
+                                   of chi-squared probability function
+chiaux.m (function) -- auxiliary fn. used by chisquared_table
diff --git a/sourcecodes/bnt-master/KPMstats/chisquared_table.m b/sourcecodes/bnt-master/KPMstats/chisquared_table.m
new file mode 100644
index 00000000..e9d191b3
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/chisquared_table.m
@@ -0,0 +1,63 @@
+function X2 = chisquared_table(P,v)
+%CHISQUARED_TABLE computes the "percentage points" of the
+%chi-squared distribution, as in Abramowitz & Stegun Table 26.8
+%   X2 = CHISQUARED_TABLE( P, v ) returns the value of chi-squared 
+%   corresponding to v degrees of freedom and probability P.
+%   P is the probability that the sum of squares of v unit-variance
+%   normally-distributed random variables is <= X2.
+%   P and v may be matrices of the same size size, or either 
+%   may be a scalar.
+%
+%   e.g., to find the 95% confidence interval for 2 degrees
+%   of freedom, use CHISQUARED_TABLE( .95, 2 ), yielding 5.99,
+%   in agreement with Abramowitz & Stegun's Table 26.8
+%
+%   This result can be checked through the function
+%   CHISQUARED_PROB( 5.99, 2 ), yielding 0.9500
+%
+%   The familiar 1.96-sigma confidence bounds enclosing 95% of
+%   a 1-D gaussian is found through 
+%   sqrt( CHISQUARED_TABLE( .95, 1 )), yielding 1.96
+%
+%   See also CHISQUARED_PROB
+%
+%Peter R. Shaw, WHOI
+%Leslie Rosenfeld, MBARI
+
+% References: Press et al., Numerical Recipes, Cambridge, 1986;
+% Abramowitz & Stegun, Handbook of Mathematical Functions, Dover, 1972.
+
+% Peter R. Shaw, Woods Hole Oceanographic Institution
+% Woods Hole, MA 02543  pshaw@whoi.edu
+% Leslie Rosenfeld, MBARI
+% Last revision: Peter Shaw, Oct 1992: fsolve with version 4
+
+% ** Calls function CHIAUX  **
+% Computed using the Incomplete Gamma function,
+% as given by Press et al. (Recipes) eq. (6.2.17)
+
+[mP,nP]=size(P);
+[mv,nv]=size(v);
+if mP~=mv | nP~=nv, 
+  if mP==1 & nP==1,
+    P=P*ones(mv,nv);
+  elseif mv==1 & nv==1,
+    v=v*ones(mP,nP);
+  else
+    error('P and v must be the same size')
+  end
+end
+[m,n]=size(P);  X2 = zeros(m,n);
+for i=1:m,
+ for j=1:n,
+  if v(i,j)<=10, 
+   x0=P(i,j)*v(i,j);
+  else
+   x0=v(i,j);
+  end
+% Note: "old" and "new" calls to fsolve may or may not follow 
+% Matlab version 3.5 -> version 4 (so I'm keeping the old call around...)
+%   X2(i,j) = fsolve('chiaux',x0,zeros(16,1),[v(i,j),P(i,j)]); %(old call)
+   X2(i,j) = fsolve('chiaux',x0,zeros(16,1),[],[v(i,j),P(i,j)]);
+ end
+end
diff --git a/sourcecodes/bnt-master/KPMstats/clg_Mstep.m b/sourcecodes/bnt-master/KPMstats/clg_Mstep.m
new file mode 100644
index 00000000..b7da903b
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/clg_Mstep.m
@@ -0,0 +1,203 @@
+function [mu, Sigma, B] = clg_Mstep(w, Y, YY, YTY, X, XX, XY, varargin)
+% MSTEP_CLG Compute ML/MAP estimates for a conditional linear Gaussian
+% [mu, Sigma, B] = Mstep_clg(w, Y, YY, YTY, X, XX, XY, varargin)
+%
+% We fit P(Y|X,Q=i) = N(Y; B_i X + mu_i, Sigma_i) 
+% and w(i,t) = p(M(t)=i|y(t)) = posterior responsibility
+% See www.ai.mit.edu/~murphyk/Papers/learncg.pdf.
+%
+% See process_options for how to specify the input arguments.
+%
+% INPUTS:
+% w(i) = sum_t w(i,t) = responsibilities for each mixture component
+%  If there is only one mixture component (i.e., Q does not exist),
+%  then w(i) = N = nsamples,  and 
+%  all references to i can be replaced by 1.
+% Y(:,i) = sum_t w(i,t) y(:,t) = weighted observations
+% YY(:,:,i) = sum_t w(i,t) y(:,t) y(:,t)' = weighted outer product
+% YTY(i) = sum_t w(i,t) y(:,t)' y(:,t) = weighted inner product
+%   You only need to pass in YTY if Sigma is to be estimated as spherical.
+%
+% In the regression context, we must also pass in the following
+% X(:,i) = sum_t w(i,t) x(:,t) = weighted inputs
+% XX(:,:,i) = sum_t w(i,t) x(:,t) x(:,t)' = weighted outer product
+% XY(i) = sum_t w(i,t) x(:,t) y(:,t)' = weighted outer product
+%
+% Optional inputs (default values in [])
+%
+% 'cov_type' - 'full', 'diag' or 'spherical' ['full']
+% 'tied_cov' - 1 (Sigma) or 0 (Sigma_i) [0]
+% 'clamped_cov' - pass in clamped value, or [] if unclamped [ [] ]
+% 'clamped_mean' - pass in clamped value, or [] if unclamped [ [] ]
+% 'clamped_weights' - pass in clamped value, or [] if unclamped [ [] ]
+% 'cov_prior' - added to Sigma(:,:,i) to ensure psd [0.01*eye(d,d,Q)]
+%
+% If cov is tied, Sigma has size d*d.
+% But diagonal and spherical covariances are represented in full size.
+
+[cov_type, tied_cov, ...
+ clamped_cov, clamped_mean, clamped_weights,  cov_prior, ...
+ xs, ys, post] = ...
+    process_options(varargin, ...
+		    'cov_type', 'full', 'tied_cov', 0,  'clamped_cov', [], 'clamped_mean', [], ...
+		    'clamped_weights', [], 'cov_prior', [], ...
+		    'xs', [], 'ys', [], 'post', []);
+
+[Ysz Q] = size(Y);
+
+if isempty(X) % no regression
+  %B = [];
+  B2 = zeros(Ysz, 1, Q);
+  for i=1:Q
+    B(:,:,i) = B2(:,1:0,i); % make an empty array of size Ysz x 0 x Q
+  end
+  [mu, Sigma] = mixgauss_Mstep(w, Y, YY, YTY, varargin{:});
+  return;
+end
+
+
+N = sum(w);
+if isempty(cov_prior)
+  cov_prior = 0.01*repmat(eye(Ysz,Ysz), [1 1 Q]);
+end
+%YY = YY + cov_prior; % regularize the scatter matrix
+
+% Set any zero weights to one before dividing
+% This is valid because w(i)=0 => Y(:,i)=0, etc
+w = w + (w==0);
+
+Xsz = size(X,1);
+% Append 1 to X to get Z
+ZZ = zeros(Xsz+1, Xsz+1, Q);
+ZY = zeros(Xsz+1, Ysz, Q);
+for i=1:Q
+  ZZ(:,:,i) = [XX(:,:,i)  X(:,i);
+	       X(:,i)'    w(i)];
+  ZY(:,:,i) = [XY(:,:,i);
+	       Y(:,i)'];
+end
+
+
+%%% Estimate mean and regression 
+
+if ~isempty(clamped_weights) & ~isempty(clamped_mean)
+  B = clamped_weights;
+  mu = clamped_mean;
+end
+if ~isempty(clamped_weights) & isempty(clamped_mean)
+  B = clamped_weights;
+  % eqn 5
+  mu = zeros(Ysz, Q);
+  for i=1:Q
+    mu(:,i) = (Y(:,i) - B(:,:,i)*X(:,i)) / w(i);
+  end
+end
+if isempty(clamped_weights) & ~isempty(clamped_mean)
+  mu = clamped_mean;
+  % eqn 3
+  B = zeros(Ysz, Xsz, Q);
+  for i=1:Q
+    tmp = XY(:,:,i)' - mu(:,i)*X(:,i)';
+    %B(:,:,i) = tmp * inv(XX(:,:,i));
+    B(:,:,i) = (XX(:,:,i) \ tmp')';
+  end
+end
+if isempty(clamped_weights) & isempty(clamped_mean)
+  mu = zeros(Ysz, Q);
+  B = zeros(Ysz, Xsz, Q);
+  % Nothing is clamped, so we must estimate B and mu jointly
+  for i=1:Q
+    % eqn 9
+    if rcond(ZZ(:,:,i)) < 1e-10
+      sprintf('clg_Mstep warning: ZZ(:,:,%d) is ill-conditioned', i);
+      % probably because there are too few cases for a high-dimensional input
+      ZZ(:,:,i) = ZZ(:,:,i) + 1e-5*eye(Xsz+1);
+    end
+    %A = ZY(:,:,i)' * inv(ZZ(:,:,i));
+    A = (ZZ(:,:,i) \ ZY(:,:,i))';
+    B(:,:,i) = A(:, 1:Xsz);
+    mu(:,i) = A(:, Xsz+1);
+  end
+end
+
+if ~isempty(clamped_cov)
+  Sigma = clamped_cov;
+  return;
+end
+
+
+%%% Estimate covariance
+
+% Spherical
+if cov_type(1)=='s'
+  if ~tied_cov
+    Sigma = zeros(Ysz, Ysz, Q);
+    for i=1:Q
+      % eqn 16
+      A = [B(:,:,i) mu(:,i)];
+      %s = trace(YTY(i) + A'*A*ZZ(:,:,i) - 2*A*ZY(:,:,i)) / (Ysz*w(i)); % wrong!
+      s = (YTY(i) + trace(A'*A*ZZ(:,:,i)) - trace(2*A*ZY(:,:,i))) / (Ysz*w(i));
+      Sigma(:,:,i) = s*eye(Ysz,Ysz);
+
+      %%%%%%%%%%%%%%%%%%% debug
+      if ~isempty(xs)
+	[nx T] = size(xs);
+	zs = [xs; ones(1,T)];
+	yty = 0;
+	zAAz = 0;
+	yAz = 0;
+	for t=1:T
+	  yty = yty + ys(:,t)'*ys(:,t) * post(i,t);
+	  zAAz = zAAz + zs(:,t)'*A'*A*zs(:,t)*post(i,t);
+	  yAz = yAz + ys(:,t)'*A*zs(:,t)*post(i,t);
+	end
+	assert(approxeq(yty, YTY(i)))
+	assert(approxeq(zAAz, trace(A'*A*ZZ(:,:,i))))
+	assert(approxeq(yAz, trace(A*ZY(:,:,i))))
+	s2 = (yty + zAAz - 2*yAz) / (Ysz*w(i));
+	assert(approxeq(s,s2))
+      end
+      %%%%%%%%%%%%%%% end debug
+      
+    end
+  else
+    S = 0;
+    for i=1:Q
+      % eqn 18
+      A = [B(:,:,i) mu(:,i)];
+      S = S + trace(YTY(i) + A'*A*ZZ(:,:,i) - 2*A*ZY(:,:,i));
+    end
+    Sigma = repmat(S / (N*Ysz), [1 1 Q]);
+  end
+else % Full/diagonal
+  if ~tied_cov
+    Sigma = zeros(Ysz, Ysz, Q);
+    for i=1:Q
+      A = [B(:,:,i) mu(:,i)];
+      % eqn 10
+      SS = (YY(:,:,i) - ZY(:,:,i)'*A' - A*ZY(:,:,i) + A*ZZ(:,:,i)*A') / w(i);
+      if cov_type(1)=='d'
+	Sigma(:,:,i) = diag(diag(SS));
+      else
+	Sigma(:,:,i) = SS;
+      end
+    end
+  else % tied
+    SS = zeros(Ysz, Ysz);
+    for i=1:Q
+      A = [B(:,:,i) mu(:,i)];
+      % eqn 13
+      SS = SS + (YY(:,:,i) - ZY(:,:,i)'*A' - A*ZY(:,:,i) + A*ZZ(:,:,i)*A');
+    end
+    SS = SS / N;
+    if cov_type(1)=='d'
+      Sigma = diag(diag(SS));
+    else
+      Sigma = SS;
+    end
+    Sigma = repmat(Sigma, [1 1 Q]);
+  end
+end
+
+Sigma = Sigma + cov_prior;
+  
diff --git a/sourcecodes/bnt-master/KPMstats/clg_Mstep_simple.m b/sourcecodes/bnt-master/KPMstats/clg_Mstep_simple.m
new file mode 100644
index 00000000..5b66bb0e
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/clg_Mstep_simple.m
@@ -0,0 +1,52 @@
+function [mu, B] = clg_Mstep_simple(w, Y, YY, YTY, X, XX, XY)
+% CLG_MSTEP_SIMPLE Same as CLG_MSTEP, but doesn;t estimate Sigma,  so is slightly faster
+% function [mu, B] = clg_Mstep_simple(w, Y, YY, YTY, X, XX, XY)
+%
+% See clg_Mstep for details.
+% Unlike clg_Mstep, there are no optional arguments, which are slow to process
+% if this function is inside a tight loop.
+
+[Ysz Q] = size(Y);
+
+if isempty(X) % no regression
+  %B = [];
+  B2 = zeros(Ysz, 1, Q);
+  for i=1:Q
+    B(:,:,i) = B2(:,1:0,i); % make an empty array of size Ysz x 0 x Q
+  end
+  [mu, Sigma] = mixgauss_Mstep(w, Y, YY, YTY);
+  return;
+end
+
+N = sum(w);
+%YY = YY + cov_prior; % regularize the scatter matrix
+
+% Set any zero weights to one before dividing
+% This is valid because w(i)=0 => Y(:,i)=0, etc
+w = w + (w==0);
+
+Xsz = size(X,1);
+% Append 1 to X to get Z
+ZZ = zeros(Xsz+1, Xsz+1, Q);
+ZY = zeros(Xsz+1, Ysz, Q);
+for i=1:Q
+  ZZ(:,:,i) = [XX(:,:,i)  X(:,i);
+	       X(:,i)'    w(i)];
+  ZY(:,:,i) = [XY(:,:,i);
+	       Y(:,i)'];
+end
+
+mu = zeros(Ysz, Q);
+B = zeros(Ysz, Xsz, Q);
+for i=1:Q
+  % eqn 9
+  if rcond(ZZ(:,:,i)) < 1e-10
+    sprintf('clg_Mstep warning: ZZ(:,:,%d) is ill-conditioned', i);
+    %probably because there are too few cases for a high-dimensional input
+    ZZ(:,:,i) = ZZ(:,:,i) + 1e-5*eye(Xsz+1);
+  end
+  %A = ZY(:,:,i)' * inv(ZZ(:,:,i));
+  A = (ZZ(:,:,i) \ ZY(:,:,i))';
+  B(:,:,i) = A(:, 1:Xsz);
+  mu(:,i) = A(:, Xsz+1);
+end
diff --git a/sourcecodes/bnt-master/KPMstats/clg_prob.m b/sourcecodes/bnt-master/KPMstats/clg_prob.m
new file mode 100644
index 00000000..3ad7b761
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/clg_prob.m
@@ -0,0 +1,14 @@
+function p = eval_pdf_clg(X,Y,mu,Sigma,W)
+% function p = eval_pdf_clg(X,Y,mu,Sigma,W)
+%
+% p(c,t) = N(Y(:,t); mu(:,c) + W(:,:,c)*X(:,t), Sigma(:,:,c))
+
+[d T] = size(Y);
+[d nc] = size(mu);
+p = zeros(nc,T);
+for c=1:nc
+  denom = (2*pi)^(d/2)*sqrt(abs(det(Sigma(:,:,c))));
+  M = repmat(mu(:,c), 1, T) + W(:,:,c)*X;
+  mahal = sum(((Y-M)'*inv(Sigma(:,:,c))).*(Y-M)',2); 
+  p(c,:) = (exp(-0.5*mahal) / denom)';
+end
diff --git a/sourcecodes/bnt-master/KPMstats/condGaussToJoint.m b/sourcecodes/bnt-master/KPMstats/condGaussToJoint.m
new file mode 100644
index 00000000..59075675
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/condGaussToJoint.m
@@ -0,0 +1,22 @@
+function [muXY, SigmaXY] = condGaussToJoint(muX, SigmaX, muY, SigmaY, WYgivenX)
+
+% Compute P(X,Y) from P(X) * P(Y|X) where P(X)=N(X;muX,SigmaX) 
+% and P(Y|X) = N(Y; WX + muY, SigmaY)
+
+% For details on how to compute a Gaussian from a Bayes net
+% - "Gaussian Influence Diagrams", R. Shachter and C. R. Kenley, Management Science, 35(5):527--550, 1989.
+
+% size(W) = dy x dx
+dx = length(muX);
+dy = length(muY);
+muXY = [muX(:); WYgivenX*muX(:) + muY];
+
+W = [zeros(dx,dx) WYgivenX';
+     zeros(dy,dx) zeros(dy,dy)];
+D = [SigmaX       zeros(dx,dy);
+     zeros(dy,dx) SigmaY];
+
+U = inv(eye(size(W)) - W')';
+SigmaXY = U' * D * U;
+
+
diff --git a/sourcecodes/bnt-master/KPMstats/cond_indep_fisher_z.m b/sourcecodes/bnt-master/KPMstats/cond_indep_fisher_z.m
new file mode 100644
index 00000000..e116ba59
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/cond_indep_fisher_z.m
@@ -0,0 +1,142 @@
+function [CI, r, p] = cond_indep_fisher_z(X, Y, S, C, N, alpha)
+% COND_INDEP_FISHER_Z Test if X indep Y given Z using Fisher's Z test
+% CI = cond_indep_fisher_z(X, Y, S, C, N, alpha)
+%
+% C is the covariance (or correlation) matrix
+% N is the sample size
+% alpha is the significance level (default: 0.05)
+%
+% See p133 of T. Anderson, "An Intro. to Multivariate Statistical Analysis", 1984
+
+if nargin < 6, alpha = 0.05; end
+
+r = partial_corr_coef(C, X, Y, S);
+z = 0.5*log( (1+r)/(1-r) );
+z0 = 0;
+W = sqrt(N - length(S) - 3)*(z-z0); % W ~ N(0,1)
+cutoff = norminv(1 - 0.5*alpha); % P(|W| <= cutoff) = 0.95
+%cutoff = mynorminv(1 - 0.5*alpha); % P(|W| <= cutoff) = 0.95
+if abs(W) < cutoff
+  CI = 1;
+else % reject the null hypothesis that rho = 0
+  CI = 0;
+end
+p = normcdf(W);
+%p = mynormcdf(W);
+
+%%%%%%%%%
+
+function p = normcdf(x,mu,sigma)
+%NORMCDF Normal cumulative distribution function (cdf).
+%   P = NORMCDF(X,MU,SIGMA) computes the normal cdf with mean MU and
+%   standard deviation SIGMA at the values in X.
+%
+%   The size of P is the common size of X, MU and SIGMA. A scalar input  
+%   functions as a constant matrix of the same size as the other inputs.    
+%
+%   Default values for MU and SIGMA are 0 and 1 respectively.
+
+%   References:
+%      [1]  M. Abramowitz and I. A. Stegun, "Handbook of Mathematical
+%      Functions", Government Printing Office, 1964, 26.2.
+
+%   Copyright (c) 1993-98 by The MathWorks, Inc.
+%   $Revision: 1.1.1.1 $  $Date: 2005/04/26 02:29:18 $
+
+if nargin < 3, 
+    sigma = 1;
+end
+
+if nargin < 2;
+    mu = 0;
+end
+
+[errorcode x mu sigma] = distchck(3,x,mu,sigma);
+
+if errorcode > 0
+    error('Requires non-scalar arguments to match in size.');
+end
+
+%   Initialize P to zero.
+p = zeros(size(x));
+
+% Return NaN if SIGMA is not positive.
+k1 = find(sigma <= 0);
+if any(k1)
+    tmp   = NaN;
+    p(k1) = tmp(ones(size(k1))); 
+end
+
+% Express normal CDF in terms of the error function.
+k = find(sigma > 0);
+if any(k)
+    p(k) = 0.5 * erfc( - (x(k) - mu(k)) ./ (sigma(k) * sqrt(2)));
+end
+
+% Make sure that round-off errors never make P greater than 1.
+k2 = find(p > 1);
+if any(k2)
+    p(k2) = ones(size(k2));
+end
+
+%%%%%%%%
+
+function x = norminv(p,mu,sigma);
+%NORMINV Inverse of the normal cumulative distribution function (cdf).
+%   X = NORMINV(P,MU,SIGMA) finds the inverse of the normal cdf with
+%   mean, MU, and standard deviation, SIGMA.
+%
+%   The size of X is the common size of the input arguments. A scalar input  
+%   functions as a constant matrix of the same size as the other inputs.    
+%
+%   Default values for MU and SIGMA are 0 and 1 respectively.
+
+%   References:
+%      [1]  M. Abramowitz and I. A. Stegun, "Handbook of Mathematical
+%      Functions", Government Printing Office, 1964, 7.1.1 and 26.2.2
+
+%   Copyright (c) 1993-98 by The MathWorks, Inc.
+%   $Revision: 1.1.1.1 $  $Date: 2005/04/26 02:29:18 $
+
+if nargin < 3, 
+    sigma = 1;
+end
+
+if nargin < 2;
+    mu = 0;
+end
+
+[errorcode p mu sigma] = distchck(3,p,mu,sigma);
+
+if errorcode > 0
+    error('Requires non-scalar arguments to match in size.');
+end
+
+% Allocate space for x.
+x = zeros(size(p));
+
+% Return NaN if the arguments are outside their respective limits.
+k = find(sigma <= 0 | p < 0 | p > 1);
+if any(k)
+    tmp  = NaN;
+    x(k) = tmp(ones(size(k))); 
+end
+
+% Put in the correct values when P is either 0 or 1.
+k = find(p == 0);
+if any(k)
+    tmp  = Inf;
+    x(k) = -tmp(ones(size(k)));
+end
+
+k = find(p == 1);
+if any(k)
+    tmp  = Inf;
+    x(k) = tmp(ones(size(k))); 
+end
+
+% Compute the inverse function for the intermediate values.
+k = find(p > 0  &  p < 1 & sigma > 0);
+if any(k),
+    x(k) = sqrt(2) * sigma(k) .* erfinv(2 * p(k) - 1) + mu(k);
+end
diff --git a/sourcecodes/bnt-master/KPMstats/condgaussTrainObserved.m b/sourcecodes/bnt-master/KPMstats/condgaussTrainObserved.m
new file mode 100644
index 00000000..2dd4cafa
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/condgaussTrainObserved.m
@@ -0,0 +1,27 @@
+function [mu, Sigma] = mixgaussTrainObserved(obsData, hiddenData, nstates, varargin);
+% mixgaussTrainObserved Max likelihood estimates of conditional Gaussian from raw data
+% function [mu, Sigma] = mixgaussTrainObserved(obsData, hiddenData, nstates, ...);
+%
+% Input:
+% obsData(:,i)
+% hiddenData(i)  - this is the mixture component label for example i
+% Optional arguments - same as mixgauss_Mstep
+%
+% Output:
+% mu(:,q)
+% Sigma(:,:,q) - same as mixgauss_Mstep
+
+[D numex] = size(obsData);
+Y = zeros(D, nstates);
+YY = zeros(D,D,nstates);
+YTY = zeros(nstates,1);
+w = zeros(nstates, 1);
+for q=1:nstates
+  ndx = find(hiddenData==q);
+  w(q) = length(ndx); % each data point has probability 1 of being in this cluster
+  data = obsData(:,ndx);
+  Y(:,q) = sum(data,2);
+  YY(:,:,q) = data*data';
+  YTY(q) = sum(diag(data'*data));
+end
+[mu, Sigma] = mixgauss_Mstep(w, Y, YY, YTY, varargin{:});
diff --git a/sourcecodes/bnt-master/KPMstats/condgauss_sample.m b/sourcecodes/bnt-master/KPMstats/condgauss_sample.m
new file mode 100644
index 00000000..17ca0eff
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/condgauss_sample.m
@@ -0,0 +1,11 @@
+function x = mixgauss_sample(mu, Sigma, labels)
+% MIXGAUSS_SAMPLE Sample from a mixture of Gaussians given known mixture labels
+% function x = mixgauss_sample(mu, Sigma, labels)
+
+T = length(labels);
+[D Q] = size(mu);
+x = zeros(D,T);
+for q=1:Q
+  ndx = find(labels==q);
+  x(:,ndx) = gaussian_sample(mu(:,q)', Sigma(:,:,q), length(ndx))';
+end
diff --git a/sourcecodes/bnt-master/KPMstats/convertBinaryLabels.m b/sourcecodes/bnt-master/KPMstats/convertBinaryLabels.m
new file mode 100644
index 00000000..aeb1e1ee
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/convertBinaryLabels.m
@@ -0,0 +1,3 @@
+% labels01 = (labelsPM+1)/2; % maps -1->0, +1->1
+% labelsPM = (2*labels01)-1; % maps 0,1 -> -1,1
+
diff --git a/sourcecodes/bnt-master/KPMstats/cwr_demo.m b/sourcecodes/bnt-master/KPMstats/cwr_demo.m
new file mode 100644
index 00000000..75090535
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/cwr_demo.m
@@ -0,0 +1,124 @@
+% Compare my code with
+% http://www.media.mit.edu/physics/publications/books/nmm/files/index.html
+%
+% cwm.m
+% (c) Neil Gershenfeld  9/1/97
+% 1D Cluster-Weighted Modeling example
+%
+clear all
+figure;
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+x = (-10:10)';
+y = (x > 0);
+npts = length(x);
+plot(x,y,'+')
+xlabel('x')
+ylabel('y')
+nclusters = 4;
+nplot = 100;
+xplot = 24*(1:nplot)'/nplot - 12;
+
+mux = 20*rand(1,nclusters) - 10;
+muy = zeros(1,nclusters);
+varx = ones(1,nclusters);
+vary = ones(1,nclusters);
+pc = 1/nclusters * ones(1,nclusters);
+niterations = 5;
+eps = 0.01;
+  
+
+I = repmat(eye(1,1), [1 1 nclusters]);
+O = repmat(zeros(1,1), [1 1 nclusters]);
+X = x(:)';
+Y = y(:)';
+
+cwr = cwr_em(X, Y, nclusters, 'muX', mux, 'muY', muy,  'SigmaX', I, ...
+	     'cov_typeX', 'spherical', 'SigmaY', I, 'cov_typeY', 'spherical', ...
+	     'priorC', pc, 'weightsY', O,  'create_init_params', 0, ...
+	     'clamp_weights', 1, 'max_iter', niterations, ...
+	     'cov_priorX', eps*ones(1,1,nclusters), ...
+	     'cov_priorY', eps*ones(1,1,nclusters));
+
+
+% Gershenfeld's EM code
+for step = 1:niterations
+    pplot = exp(-(kron(xplot,ones(1,nclusters)) ...
+		  - kron(ones(nplot,1),mux)).^2 ...
+		./ (2*kron(ones(nplot,1),varx))) ...
+	    ./ sqrt(2*pi*kron(ones(nplot,1),varx)) ...
+	    .* kron(ones(nplot,1),pc);
+    plot(xplot,pplot,'k');
+    pause(0);
+    px = exp(-(kron(x,ones(1,nclusters)) ...
+	       - kron(ones(npts,1),mux)).^2 ...
+	     ./ (2*kron(ones(npts,1),varx))) ...
+	 ./ sqrt(2*pi*kron(ones(npts,1),varx));
+    py = exp(-(kron(y,ones(1,nclusters)) ...
+	       - kron(ones(npts,1),muy)).^2 ...
+	     ./ (2*kron(ones(npts,1),vary))) ...
+	 ./ sqrt(2*pi*kron(ones(npts,1),vary));
+    p = px .* py .* kron(ones(npts,1),pc);
+    pp = p ./ kron(sum(p,2),ones(1,nclusters));
+    pc = sum(pp)/npts;
+    yfit = sum(kron(ones(npts,1),muy) .* p,2) ...
+	   ./ sum(p,2);
+    mux = sum(kron(x,ones(1,nclusters)) .* pp) ...
+	  ./ (npts*pc);
+    varx = eps + sum((kron(x,ones(1,nclusters)) ...
+		      - kron(ones(npts,1),mux)).^2 .* pp) ...
+	   ./ (npts*pc);
+    muy = sum(kron(y,ones(1,nclusters)) .* pp) ...
+	  ./ (npts*pc);
+    vary = eps + sum((kron(y,ones(1,nclusters)) ...
+		      - kron(ones(npts,1),muy)).^2 .* pp) ...
+	   ./ (npts*pc);
+end
+
+
+% Check equal
+cwr_pc = cwr.priorC';
+assert(approxeq(cwr_pc, pc))
+cwr_mux = cwr.muX;
+assert(approxeq(mux, cwr_mux))
+cwr_SigmaX = squeeze(cwr.SigmaX)';
+assert(approxeq(varx, cwr_SigmaX))
+cwr_muy = cwr.muY;
+assert(approxeq(muy, cwr_muy))
+cwr_SigmaY = squeeze(cwr.SigmaY)';
+assert(approxeq(vary, cwr_SigmaY))
+
+
+% Prediction
+
+X = xplot(:)';
+[cwr_mu, Sigma, post] = cwr_predict(cwr, X);
+cwr_ystd = squeeze(Sigma)';
+
+% pplot(t,c)
+pplot = exp(-(kron(xplot,ones(1,nclusters)) ...
+   - kron(ones(nplot,1),mux)).^2 ...
+   ./ (2*kron(ones(nplot,1),varx))) ...
+   ./ sqrt(2*pi*kron(ones(nplot,1),varx)) ...
+   .* kron(ones(nplot,1),pc);
+yplot = sum(kron(ones(nplot,1),muy) .* pplot,2) ...
+   ./ sum(pplot,2);
+ystdplot = sum(kron(ones(nplot,1),(muy.^2+vary)) .* pplot,2) ...
+   ./ sum(pplot,2) - yplot.^2;
+
+
+% Check equal
+assert(approxeq(yplot(:)', cwr_mu(:)'))
+assert(approxeq(ystdplot, cwr_ystd))
+assert(approxeq(pplot ./ repmat(sum(pplot,2), 1, nclusters),post') )
+
+plot(xplot,yplot,'k');
+hold on
+plot(xplot,yplot+ystdplot,'k--');
+plot(xplot,yplot-ystdplot,'k--');
+plot(x,y,'k+');
+axis([-12 12 -1 1.1]);
+plot(xplot,.8*pplot/max(max(pplot))-1,'k')
+hold off
+
diff --git a/sourcecodes/bnt-master/KPMstats/cwr_em.m b/sourcecodes/bnt-master/KPMstats/cwr_em.m
new file mode 100644
index 00000000..96bf491e
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/cwr_em.m
@@ -0,0 +1,161 @@
+function cwr  = cwr_em(X, Y, nc, varargin)
+% CWR_LEARN Fit the parameters of a cluster weighted regression model using EM
+% function cwr  = cwr_learn(X, Y, ...)
+%
+% X(:, t) is the t'th input example
+% Y(:, t) is the t'th output example
+% nc is the number of clusters
+%
+% Kevin Murphy, May 2003
+
+[max_iter, thresh, cov_typeX, cov_typeY, clamp_weights, ...
+ muX, muY, SigmaX, SigmaY, weightsY, priorC, create_init_params, ...
+cov_priorX, cov_priorY, verbose, regress, clamp_covX, clamp_covY] = process_options(...
+    varargin, 'max_iter', 10, 'thresh', 1e-2, 'cov_typeX', 'full', ...
+     'cov_typeY', 'full', 'clamp_weights', 0, ...
+     'muX', [], 'muY', [], 'SigmaX', [], 'SigmaY', [], 'weightsY', [], 'priorC', [], ...
+     'create_init_params', 1, 'cov_priorX', [], 'cov_priorY', [], 'verbose', 0, ...
+    'regress', 1, 'clamp_covX', 0, 'clamp_covY', 0);
+     
+[nx N] = size(X);
+[ny N2] = size(Y);
+if N ~= N2
+  error(sprintf('nsamples X (%d) ~= nsamples Y (%d)', N, N2));
+end
+%if N < nx 
+%  fprintf('cwr_em warning: dim X (%d) > nsamples X (%d)\n', nx, N);
+%end
+if (N < nx) & regress
+  fprintf('cwr_em warning: dim X = %d, nsamples X = %d\n', nx, N);
+end
+if (N < ny) 
+  fprintf('cwr_em warning: dim Y = %d, nsamples Y = %d\n', ny, N);
+end
+if (nc > N) 
+  error(sprintf('cwr_em: more centers (%d) than data', nc))
+end
+
+if nc==1
+  % No latent variable, so there is a closed-form solution
+  w = 1/N;
+  WYbig = Y*w;
+  WYY = WYbig * Y'; 
+  WY = sum(WYbig, 2);
+  WYTY = sum(diag(WYbig' * Y));
+  cwr.priorC = 1;
+  cwr.SigmaX = [];
+  if ~regress
+    % This is just fitting an unconditional Gaussian
+    cwr.weightsY = [];
+    [cwr.muY, cwr.SigmaY] = ...
+	mixgauss_Mstep(1, WY, WYY, WYTY, ...
+		       'cov_type', cov_typeY, 'cov_prior', cov_priorY);
+    % There is a much easier way...
+    assert(approxeq(cwr.muY, mean(Y')))
+    assert(approxeq(cwr.SigmaY, cov(Y') + 0.01*eye(ny)))
+  else
+    % This is just linear regression
+    WXbig = X*w;
+    WXX = WXbig * X';
+   WX = sum(WXbig, 2);
+    WXTX = sum(diag(WXbig' * X));
+    WXY = WXbig * Y';
+    [cwr.muY, cwr.SigmaY, cwr.weightsY] = ...
+	clg_Mstep(1, WY, WYY, WYTY, WX, WXX, WXY, ...
+		  'cov_type', cov_typeY, 'cov_prior', cov_priorY);
+  end
+  if clamp_covY, cwr.SigmaY = SigmaY; end
+  if clamp_weights,  cwr.weightsY = weightsY; end
+  return;
+end
+
+
+if create_init_params
+  [cwr.muX, cwr.SigmaX] = mixgauss_init(nc, X, cov_typeX);
+  [cwr.muY, cwr.SigmaY] = mixgauss_init(nc, Y, cov_typeY);
+  cwr.weightsY = zeros(ny, nx, nc);
+  cwr.priorC = normalize(ones(nc,1));
+else
+  cwr.muX = muX;  cwr.muY = muY; cwr.SigmaX = SigmaX; cwr.SigmaY = SigmaY;
+  cwr.weightsY = weightsY; cwr.priorC = priorC;
+end
+
+
+if clamp_covY, cwr.SigmaY = SigmaY; end
+if clamp_covX,  cwr.SigmaX = SigmaX; end
+if clamp_weights,  cwr.weightsY = weightsY; end
+
+previous_loglik = -inf;
+num_iter = 1;
+converged = 0;
+
+while (num_iter <= max_iter) & ~converged
+
+  % E step
+  
+  [likXandY, likYgivenX, post] = cwr_prob(cwr, X, Y);
+  loglik = sum(log(likXandY));
+  % extract expected sufficient statistics
+  w = sum(post,2);  % post(c,t)
+  WYY = zeros(ny, ny, nc);
+  WY = zeros(ny, nc);
+  WYTY = zeros(nc,1);
+  
+  WXX = zeros(nx, nx, nc);
+  WX = zeros(nx, nc);
+  WXTX = zeros(nc, 1);
+  WXY = zeros(nx,ny,nc);
+  %WYY = repmat(reshape(w, [1 1 nc]), [ny ny 1]) .*  repmat(Y*Y', [1 1 nc]);
+  for c=1:nc
+    weights = repmat(post(c,:), ny, 1);
+    WYbig = Y .* weights;
+    WYY(:,:,c) = WYbig * Y'; 
+    WY(:,c) = sum(WYbig, 2);
+    WYTY(c) = sum(diag(WYbig' * Y));
+
+    weights = repmat(post(c,:), nx, 1); % weights(nx, nsamples)
+    WXbig = X .* weights;
+    WXX(:,:,c) = WXbig * X';
+    WX(:,c) = sum(WXbig, 2);
+    WXTX(c) = sum(diag(WXbig' * X));
+    WXY(:,:,c) = WXbig * Y';
+  end
+
+  % M step
+  % Q -> X is called Q->Y in Mstep_clg
+  [cwr.muX, cwr.SigmaX] = mixgauss_Mstep(w, WX, WXX, WXTX, ...
+			    'cov_type', cov_typeX, 'cov_prior', cov_priorX);
+  for c=1:nc
+    assert(is_psd(cwr.SigmaX(:,:,c)))
+  end
+  
+  if clamp_weights % affects estimate of mu and Sigma
+    W = cwr.weightsY;
+  else
+    W = [];
+  end
+  [cwr.muY, cwr.SigmaY, cwr.weightsY] = ...
+      clg_Mstep(w, WY, WYY, WYTY, WX, WXX, WXY, ...
+		'cov_type', cov_typeY, 'clamped_weights', W, ...
+		'cov_prior', cov_priorY);
+  %'xs', X, 'ys', Y, 'post', post); % debug
+  %a = linspace(min(Y(2,:)), max(Y(2,:)), nc+2);
+  %cwr.muY(2,:) = a(2:end-1);
+
+  cwr.priorC = normalize(w);
+
+  for c=1:nc
+    assert(is_psd(cwr.SigmaY(:,:,c)))
+  end
+
+  if clamp_covY, cwr.SigmaY = SigmaY; end
+  if clamp_covX,  cwr.SigmaX = SigmaX; end
+  if clamp_weights,  cwr.weightsY = weightsY; end
+
+  if verbose, fprintf(1, 'iteration %d, loglik = %f\n', num_iter, loglik); end
+  num_iter =  num_iter + 1;
+  converged = em_converged(loglik, previous_loglik, thresh);
+  previous_loglik = loglik;
+  
+end
+
diff --git a/sourcecodes/bnt-master/KPMstats/cwr_predict.m b/sourcecodes/bnt-master/KPMstats/cwr_predict.m
new file mode 100644
index 00000000..9fe54cab
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/cwr_predict.m
@@ -0,0 +1,57 @@
+function  [mu, Sigma, weights, mask] = cwr_predict(cwr, X, mask_data)
+% CWR_PREDICT cluster weighted regression: predict Y given X 
+% function  [mu, Sigma] = cwr_predict(cwr, X)
+% 
+% mu(:,t) = E[Y|X(:,t)] = sum_c P(c | X(:,t)) E[Y|c, X(:,t)]
+% Sigma(:,:,t) = Cov[Y|X(:,t)]
+%
+% [mu, Sigma, weights, mask] = cwr_predict(cwr, X, mask_data)
+% mask(i) = sum_t sum_c p(mask_data(:,i) | X(:,t), c) P(c|X(:,t))
+% This evaluates the predictive density on a set of points
+% (This is only sensible if T=1, ie. X is a single vector)
+
+[nx T] = size(X);
+[ny nx nc] = size(cwr.weightsY);
+mu = zeros(ny, T);
+Sigma = zeros(ny, ny, T);
+
+if nargout == 4
+  comp_mask = 1;
+  N = size(mask_data,2);
+  mask = zeros(N,1);
+else
+  comp_mask = 0;
+end
+
+if nc==1
+  if isempty(cwr.weightsY)
+    mu = repmat(cwr.muY, 1, T);
+    Sigma = repmat(cwr.SigmaY, [1 1 T]);
+  else
+    mu = repmat(cwr.muY, 1, T) + cwr.weightsY * X;
+    Sigma = repmat(cwr.SigmaY, [1 1 T]);
+    %for t=1:T
+    %  mu(:,t) = cwr.muY + cwr.weightsY*X(:,t);
+    %  Sigma(:,:,t) = cwr.SigmaY;
+    %end
+  end
+  if comp_mask, mask = gaussian_prob(mask_data, mu, Sigma); end
+  weights = [];
+  return;
+end
+
+
+% likX(c,t) = p(x(:,t) | c)
+likX = mixgauss_prob(X, cwr.muX, cwr.SigmaX);
+weights = normalize(repmat(cwr.priorC, 1, T) .* likX, 1);
+for t=1:T
+  mut = zeros(ny, nc);
+  for c=1:nc
+    mut(:,c) = cwr.muY(:,c) + cwr.weightsY(:,:,c)*X(:,t);
+    if comp_mask
+      mask = mask + gaussian_prob(mask_data, mut(:,c), cwr.SigmaY(:,:,c)) * weights(c);
+    end
+  end
+  %w = normalise(cwr.priorC(:)  .* likX(:,t));
+  [mu(:,t), Sigma(:,:,t)] = collapse_mog(mut, cwr.SigmaY, weights(:,t));
+end
diff --git a/sourcecodes/bnt-master/KPMstats/cwr_prob.m b/sourcecodes/bnt-master/KPMstats/cwr_prob.m
new file mode 100644
index 00000000..6971e0de
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/cwr_prob.m
@@ -0,0 +1,39 @@
+function  [likXandY, likYgivenX, post] = cwr_prob(cwr, X, Y);
+% CWR_EVAL_PDF cluster weighted regression: evaluate likelihood of Y given X 
+% function  [likXandY, likYgivenX, post] = cwr_prob(cwr, X, Y);
+% 
+% likXandY(t) = p(x(:,t), y(:,t))
+% likXgivenY(t) = p(x(:,t)| y(:,t))
+% post(c,t) = p(c | x(:,t), y(:,t))
+
+[nx N] = size(X);
+nc = length(cwr.priorC);
+
+if nc == 1
+  [mu, Sigma] = cwr_predict(cwr, X);
+  likY = gaussian_prob(Y, mu, Sigma);
+  likXandY = likY;
+  likYgivenX = likY;
+  post = ones(1,N);
+  return;
+end
+
+
+% likY(c,t) = p(y(:,t) | c)
+likY = clg_prob(X, Y, cwr.muY, cwr.SigmaY, cwr.weightsY);
+
+% likX(c,t) = p(x(:,t) | c)
+[junk, likX] = mixgauss_prob(X, cwr.muX, cwr.SigmaX);
+likX = squeeze(likX);
+
+% prior(c,t) = p(c)
+prior = repmat(cwr.priorC(:), 1, N);
+
+post = likX .* likY .* prior;
+likXandY = sum(post, 1);
+post = post ./ repmat(likXandY, nc, 1);
+%loglik = sum(log(lik));
+%loglik = log(lik);
+
+likX = sum(likX .* prior, 1);
+likYgivenX = likXandY ./ likX;
diff --git a/sourcecodes/bnt-master/KPMstats/cwr_readme.txt b/sourcecodes/bnt-master/KPMstats/cwr_readme.txt
new file mode 100644
index 00000000..28f6ce72
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/cwr_readme.txt
@@ -0,0 +1,20 @@
+This directory implements Cluster Weighted Regression, as described in
+Neil Gershenfeld, "The nature of mathematical modelling", p182.
+(See also http://www.media.mit.edu/physics/publications/books/nmm/files/index.html)
+
+Written by K. Murphy, 2 May 2003
+
+The model is as follows:
+
+X<--|
+|   Q
+v   |
+Y<--
+
+where Q is a discrete latent mixture variable.
+
+A mixture of experts has an X->Q arc instead of a Q->X arc;
+the X->Q arc is modelled by a softmax, which is slightly harder to fit than a
+mixture of Gaussians.
+
+
diff --git a/sourcecodes/bnt-master/KPMstats/cwr_test.m b/sourcecodes/bnt-master/KPMstats/cwr_test.m
new file mode 100644
index 00000000..dce1ed65
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/cwr_test.m
@@ -0,0 +1,80 @@
+% Verify that my code gives the same results as the 1D example at
+% http://www.media.mit.edu/physics/publications/books/nmm/files/cwm.m
+
+seed = 0;
+rand('state', seed);
+randn('state', seed);
+x = (-10:10)';
+y = double(x > 0);
+npts = length(x);
+plot(x,y,'+')
+
+nclusters = 4;
+nplot = 100;
+xplot = 24*(1:nplot)'/nplot - 12;
+
+mux = 20*rand(1,nclusters) - 10;
+muy = zeros(1,nclusters);
+varx = ones(1,nclusters);
+vary = ones(1,nclusters);
+pc = 1/nclusters * ones(1,nclusters);
+
+
+I = repmat(eye(1,1), [1 1 nclusters]);
+O = repmat(zeros(1,1), [1 1 nclusters]);
+X = x(:)';
+Y = y(:)';
+
+% Do 1 iteration of EM
+
+%cwr = cwr_em(X, Y, nclusters, 'muX', mux, 'muY', muy,  'SigmaX', I, 'cov_typeX', 'spherical', 'SigmaY', I, 'cov_typeY', 'spherical', 'priorC', pc, 'weightsY', O,  'init_params', 0, 'clamp_weights', 1, 'max_iter', 1, 'cov_priorX', zeros(1,1,nclusters), 'cov_priorY', zeros(1,1,nclusters));
+
+cwr = cwr_em(X, Y, nclusters, 'muX', mux, 'muY', muy,  'SigmaX', I, 'cov_typeX', 'spherical', 'SigmaY', I, 'cov_typeY', 'spherical', 'priorC', pc, 'weightsY', O,  'create_init_params', 0, 'clamp_weights', 1, 'max_iter', 1);
+
+
+% Check this matches Gershenfeld's code
+
+% E step
+% px(t,c) = prob(x(t) | c)
+px = exp(-(kron(x,ones(1,nclusters)) ...
+	   - kron(ones(npts,1),mux)).^2 ...
+	 ./ (2*kron(ones(npts,1),varx))) ...
+     ./ sqrt(2*pi*kron(ones(npts,1),varx));
+py = exp(-(kron(y,ones(1,nclusters)) ...
+	   - kron(ones(npts,1),muy)).^2 ...
+	 ./ (2*kron(ones(npts,1),vary))) ...
+     ./ sqrt(2*pi*kron(ones(npts,1),vary));
+p = px .* py .* kron(ones(npts,1),pc);
+pp = p ./ kron(sum(p,2),ones(1,nclusters));
+
+% M step
+eps = 0.01;
+pc2 = sum(pp)/npts;
+
+mux2 = sum(kron(x,ones(1,nclusters)) .* pp) ...
+      ./ (npts*pc2);
+varx2 = eps + sum((kron(x,ones(1,nclusters)) ...
+		  - kron(ones(npts,1),mux2)).^2 .* pp) ...
+       ./ (npts*pc2);
+muy2 = sum(kron(y,ones(1,nclusters)) .* pp) ...
+      ./ (npts*pc2);
+vary2 = eps + sum((kron(y,ones(1,nclusters)) ...
+		  - kron(ones(npts,1),muy2)).^2 .* pp) ...
+       ./ (npts*pc2);
+
+
+denom = (npts*pc2);
+% denom(c) = N*pc(c) = w(c) = sum_t pp(c,t)
+% since pc(c) = sum_t pp(c,t) / N
+
+cwr_mux = cwr.muX;
+assert(approxeq(mux2, cwr_mux))
+cwr_SigmaX = squeeze(cwr.SigmaX)';
+assert(approxeq(varx2, cwr_SigmaX))
+
+cwr_muy = cwr.muY;
+assert(approxeq(muy2, cwr_muy))
+cwr_SigmaY = squeeze(cwr.SigmaY)';
+assert(approxeq(vary2, cwr_SigmaY))
+
+
diff --git a/sourcecodes/bnt-master/KPMstats/dirichlet_sample.m b/sourcecodes/bnt-master/KPMstats/dirichlet_sample.m
new file mode 100644
index 00000000..2ab09afb
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/dirichlet_sample.m
@@ -0,0 +1,18 @@
+function theta = dirichlet_sample(alpha, N)
+% SAMPLE_DIRICHLET Sample N vectors from Dir(alpha(1), ..., alpha(k))
+% theta = sample_dirichlet(alpha, N)
+% theta(i,j) = i'th sample of theta_j, where theta ~ Dir
+
+% We use the method from p. 482 of "Bayesian Data Analysis", Gelman et al.
+
+assert(alpha > 0);
+k = length(alpha);
+theta = zeros(N, k);
+scale = 1; % arbitrary
+for i=1:k
+  %theta(:,i) = gamrnd(alpha(i), scale, N, 1);
+  theta(:,i) = gamma_sample(alpha(i), scale, N, 1);
+end
+%theta = mk_stochastic(theta);
+S = sum(theta,2); 
+theta = theta ./ repmat(S, 1, k);
diff --git a/sourcecodes/bnt-master/KPMstats/dirichletpdf.m b/sourcecodes/bnt-master/KPMstats/dirichletpdf.m
new file mode 100644
index 00000000..8b789844
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/dirichletpdf.m
@@ -0,0 +1,39 @@
+function p = dirichletpdf(x, alpha)
+%DIRICHLETPDF Dirichlet probability density function.
+%   p = dirichletpdf(x, alpha) returns the probability of vector
+%   x under the Dirichlet distribution with parameter vector
+%   alpha.
+%
+%   Author: David Ross
+
+%-------------------------------------------------
+% Check the input
+%-------------------------------------------------
+error(nargchk(2,2,nargin));
+
+% enusre alpha is a vector
+if min(size(alpha)) ~= 1 | ndims(alpha) > 2 | length(alpha) == 1
+    error('alpha must be a vector');
+end
+
+% ensure x is is a vector of the same size as alpha
+if any(size(x) ~= size(alpha))
+    error('x and alpha must be the same size');
+end
+
+
+%-------------------------------------------------
+% Main
+%-------------------------------------------------
+if any(x < 0)
+    p = 0;
+elseif sum(x) ~= 1
+    disp(['dirichletpdf warning: sum(x)~=1, but this may be ' ...
+        'due to numerical issues']);
+    p = 0;
+else
+    z = gammaln(sum(alpha)) - sum(gammaln(alpha)); 
+    z = exp(z);
+
+    p = z * prod(x.^(alpha-1));
+end
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/KPMstats/dirichletrnd.m b/sourcecodes/bnt-master/KPMstats/dirichletrnd.m
new file mode 100644
index 00000000..f11074db
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/dirichletrnd.m
@@ -0,0 +1,32 @@
+function x = dirichletrnd(alpha)
+%DIRICHLETRND Random vector from a dirichlet distribution.
+%   x = dirichletrnd(alpha) returns a vector randomly selected
+%   from the Dirichlet distribution with parameter vector alpha.
+%
+%   The algorithm used is the following:
+%   For each alpha(i), generate a value s(i) with distribution
+%   Gamma(alpha(i),1).  Now x(i) = s(i) / sum_j s(j).
+%   
+%   The above algorithm was recounted to me by Radford Neal, but
+%   a reference would be appreciated...
+%   Do the gamma parameters always have to be 1?
+%
+%   Author: David Ross
+%   $Id: dirichletrnd.m,v 1.1.1.1 2005/05/22 23:32:12 yozhik Exp $
+
+%-------------------------------------------------
+% Check the input
+%-------------------------------------------------
+error(nargchk(1,1,nargin));
+
+if min(size(alpha)) ~= 1 | length(alpha) < 2
+    error('alpha must be a vector of length at least 2');
+end
+
+
+%-------------------------------------------------
+% Main
+%-------------------------------------------------
+gamma_vals = gamrnd(alpha, ones(size(alpha)), size(alpha));
+denom = sum(gamma_vals);
+x = gamma_vals / denom;
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/KPMstats/distchck.m b/sourcecodes/bnt-master/KPMstats/distchck.m
new file mode 100644
index 00000000..399f2b3f
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/distchck.m
@@ -0,0 +1,173 @@
+function [errorcode,out1,out2,out3,out4] = distchck(nparms,arg1,arg2,arg3,arg4)
+%DISTCHCK Checks the argument list for the probability functions.
+
+%   B.A. Jones  1-22-93
+%   Copyright (c) 1993-98 by The MathWorks, Inc.
+%   $Revision: 1.1.1.1 $  $Date: 2005/04/26 02:29:18 $
+
+errorcode = 0;
+
+if nparms == 1
+    out1 = arg1;
+    return;
+end
+    
+if nparms == 2
+    [r1 c1] = size(arg1);
+    [r2 c2] = size(arg2);
+    scalararg1 = (prod(size(arg1)) == 1);
+    scalararg2 = (prod(size(arg2)) == 1);
+    if ~scalararg1 & ~scalararg2
+        if r1 ~= r2 | c1 ~= c2
+            errorcode = 1;
+            return;         
+        end     
+    end
+    if scalararg1
+        out1 = arg1(ones(r2,1),ones(c2,1));
+    else
+        out1 = arg1;
+    end
+    if scalararg2
+        out2 = arg2(ones(r1,1),ones(c1,1));
+    else
+        out2 = arg2;
+    end
+end
+    
+if nparms == 3
+    [r1 c1] = size(arg1);
+    [r2 c2] = size(arg2);
+    [r3 c3] = size(arg3);
+    scalararg1 = (prod(size(arg1)) == 1);
+    scalararg2 = (prod(size(arg2)) == 1);
+    scalararg3 = (prod(size(arg3)) == 1);
+
+    if ~scalararg1 & ~scalararg2
+        if r1 ~= r2 | c1 ~= c2
+            errorcode = 1;
+            return;         
+        end
+    end
+
+    if ~scalararg1 & ~scalararg3
+        if r1 ~= r3 | c1 ~= c3
+            errorcode = 1;
+            return;                 
+        end
+    end
+
+    if ~scalararg3 & ~scalararg2
+        if r3 ~= r2 | c3 ~= c2
+            errorcode = 1;
+            return;         
+        end
+    end
+
+    if ~scalararg1
+      out1 = arg1;
+    end
+    if ~scalararg2
+      out2 = arg2;
+    end
+    if ~scalararg3
+      out3 = arg3;
+    end
+    rows = max([r1 r2 r3]);
+   columns = max([c1 c2 c3]);  
+       
+    if scalararg1
+        out1 = arg1(ones(rows,1),ones(columns,1));
+    end
+   if scalararg2
+        out2 = arg2(ones(rows,1),ones(columns,1));
+   end
+   if scalararg3
+       out3 = arg3(ones(rows,1),ones(columns,1));
+   end
+     out4 =[];
+    
+end
+
+if nparms == 4
+    [r1 c1] = size(arg1);
+    [r2 c2] = size(arg2);
+    [r3 c3] = size(arg3);
+    [r4 c4] = size(arg4);
+    scalararg1 = (prod(size(arg1)) == 1);
+    scalararg2 = (prod(size(arg2)) == 1);
+    scalararg3 = (prod(size(arg3)) == 1);
+    scalararg4 = (prod(size(arg4)) == 1);
+
+    if ~scalararg1 & ~scalararg2
+        if r1 ~= r2 | c1 ~= c2
+            errorcode = 1;
+            return;         
+        end
+    end
+
+    if ~scalararg1 & ~scalararg3
+        if r1 ~= r3 | c1 ~= c3
+            errorcode = 1;
+            return;                 
+        end
+    end
+
+    if ~scalararg1 & ~scalararg4
+        if r1 ~= r4 | c1 ~= c4
+            errorcode = 1;
+            return;                 
+        end
+    end
+
+    if ~scalararg3 & ~scalararg2
+        if r3 ~= r2 | c3 ~= c2
+            errorcode = 1;
+            return;         
+        end
+    end
+
+    if ~scalararg4 & ~scalararg2
+        if r4 ~= r2 | c4 ~= c2
+            errorcode = 1;
+            return;         
+        end
+    end
+
+    if ~scalararg3 & ~scalararg4
+        if r3 ~= r4 | c3 ~= c4
+            errorcode = 1;
+            return;         
+        end
+    end
+
+
+    if ~scalararg1
+       out1 = arg1;
+    end
+    if ~scalararg2
+       out2 = arg2;
+    end
+    if ~scalararg3
+      out3 = arg3;
+    end
+    if ~scalararg4
+      out4 = arg4;
+    end
+ 
+   rows = max([r1 r2 r3 r4]);
+   columns = max([c1 c2 c3 c4]);     
+    if scalararg1
+       out1 = arg1(ones(rows,1),ones(columns,1));
+   end
+   if scalararg2
+       out2 = arg2(ones(rows,1),ones(columns,1));
+   end
+   if scalararg3
+       out3 = arg3(ones(rows,1),ones(columns,1));
+   end
+   if scalararg4
+       out4 = arg4(ones(rows,1),ones(columns,1));
+   end
+end
+
diff --git a/sourcecodes/bnt-master/KPMstats/eigdec.m b/sourcecodes/bnt-master/KPMstats/eigdec.m
new file mode 100644
index 00000000..321cee4d
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/eigdec.m
@@ -0,0 +1,59 @@
+function [evals, evec] = eigdec(x, N)
+%EIGDEC	Sorted eigendecomposition
+%
+%	Description
+%	 EVALS = EIGDEC(X, N computes the largest N eigenvalues of the
+%	matrix X in descending order.  [EVALS, EVEC] = EIGDEC(X, N) also
+%	computes the corresponding eigenvectors.
+%
+%	See also
+%	PCA, PPCA
+%
+
+%	Copyright (c) Ian T Nabney (1996-2001)
+
+if nargout == 1
+   evals_only = logical(1);
+else
+   evals_only = logical(0);
+end
+
+if N ~= round(N) | N < 1 | N > size(x, 2)
+   error('Number of PCs must be integer, >0, < dim');
+end
+
+% Find the eigenvalues of the data covariance matrix
+if evals_only
+   % Use eig function as always more efficient than eigs here
+   temp_evals = eig(x);
+else
+   % Use eig function unless fraction of eigenvalues required is tiny
+   if (N/size(x, 2)) > 0.04
+     fprintf('netlab pca: using eig\n');
+      [temp_evec, temp_evals] = eig(x);
+   else
+      options.disp = 0;
+      fprintf('netlab pca: using eigs\n');
+      [temp_evec, temp_evals] = eigs(x, N, 'LM', options);
+   end
+   temp_evals = diag(temp_evals);
+end
+
+% Eigenvalues nearly always returned in descending order, but just
+% to make sure.....
+[evals perm] = sort(-temp_evals);
+evals = -evals(1:N);
+%evec=temp_evec(:,1:N);
+if ~evals_only
+  if evals == temp_evals(1:N)
+    % Originals were in order
+    evec = temp_evec(:, 1:N);
+    return
+  else
+    fprintf('netlab pca: sorting evec\n');
+    % Need to reorder the eigenvectors
+    for i=1:N
+      evec(:,i) = temp_evec(:,perm(i));
+    end
+  end
+end
diff --git a/sourcecodes/bnt-master/KPMstats/est_transmat.m b/sourcecodes/bnt-master/KPMstats/est_transmat.m
new file mode 100644
index 00000000..7654d9ab
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/est_transmat.m
@@ -0,0 +1,15 @@
+function [A,C] = est_transmat(seq)
+% ESTIMATE_TRANSMAT Max likelihood of a Markov chain transition matrix
+% [A,C] = estimate_transmat(seq)
+%
+% seq is a vector of positive integers
+%
+% e.g., seq = [1 2 1 2 3], C(1,2)=2, C(2,1)=1, C(2,3)=1, so
+% A(1,:)=[0 1 0], A(2,:) = [0.5 0 0.5],
+% all other entries are 0
+
+% Use a trick with sparse matrices to count the number of each transition.
+% From http://www.mathworks.com/company/newsletter/may03/dna.shtml
+
+C = full(sparse(seq(1:end-1), seq(2:end),1));
+A = mk_stochastic(C);
diff --git a/sourcecodes/bnt-master/KPMstats/fit_paritioned_model_testfn.m b/sourcecodes/bnt-master/KPMstats/fit_paritioned_model_testfn.m
new file mode 100644
index 00000000..756cdcf9
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/fit_paritioned_model_testfn.m
@@ -0,0 +1,5 @@
+function model = foo(inputs, outputs, varargin)
+
+model.inputs = inputs;
+model.outputs = outputs;
+
diff --git a/sourcecodes/bnt-master/KPMstats/fit_partitioned_model.m b/sourcecodes/bnt-master/KPMstats/fit_partitioned_model.m
new file mode 100644
index 00000000..fb9d178d
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/fit_partitioned_model.m
@@ -0,0 +1,59 @@
+function [model, partition_size] = fit_partitioned_model(...
+    inputs, outputs, selectors, sel_sizes, min_size, partition_names, fn_name, varargin)
+%function [models, partition_sizes] = fit_partitioned_model(...
+%    inputs, outputs, selectors, sel_sizes, min_size, partition_names, fn_name, varargin)
+%
+% Fit models to different subsets (columns)  of the input/output data, 
+% as chosen by the selectors matrix. If there is only output data, set input=[].
+% If there is less than min_size data in partition i, 
+% we set model{i} = []
+%
+% Example:
+% selectors = [1 2 1 1 1
+%              1 2 2 1 2]
+% sel_sizes = [2 2] so there are 4 models: (1,1), (2,1), (1,2), (2,2)
+% We fit model{1} to data from columns 1,4
+% We fit model{2} to no data
+% We fit model{3} to data from column 3,5
+% We fit model{4} to data from column 2 (assuming min_size <= 1)
+%
+% For each partition, we call the specified function with the specified arguments
+% as follows:
+%  model{i}  = fn(input(:,cols{i}), output(:,cols{i}), args)
+% (We omit input if [])
+% partition_size(i) is the amount of data in the i'th partition.
+%
+% Example use: row 1 of selectors is whether an object is present/absent
+% and row 2 is the location.
+%
+% Demo:
+% inputs = 1:5; outputs = 6:10; selectors = as above
+% fn = 'fit_partitioned_model_testfn';
+% [model, partition_size] = fit_partitioned_model(inputs, outputs, selectors, [2 2], fn)
+% should produce
+% model{1}.input = [1 4], model{1}.output = [6 9]
+% model{2} = []
+% model{3}.input = [3 5], model{3}.output = [8 10], 
+% model{4}.input = [2], model{3}.output = [7], 
+% partition_size = [2 0 2 1]
+
+
+sel_ndx = subv2ind(sel_sizes, selectors');
+Nmodels = prod(sel_sizes);
+model = cell(1, Nmodels);
+partition_size = zeros(1, Nmodels);
+for m=1:Nmodels
+  ndx = find(sel_ndx==m);
+  partition_size(m) = length(ndx);
+  if ~isempty(partition_names) % & (partition_size(m) < min_size)
+    fprintf('partition %s has size %d, min size = %d\n', ...
+	    partition_names{m}, partition_size(m), min_size);
+  end
+  if partition_size(m) >= min_size
+    if isempty(inputs)
+      model{m} = feval(fn_name, outputs(:, ndx), varargin{:});
+    else
+      model{m} = feval(fn_name, inputs(:,ndx), outputs(:, ndx), varargin{:});
+    end
+  end
+end
diff --git a/sourcecodes/bnt-master/KPMstats/gamma_sample.m b/sourcecodes/bnt-master/KPMstats/gamma_sample.m
new file mode 100644
index 00000000..e622df40
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/gamma_sample.m
@@ -0,0 +1,126 @@
+function r = gamrnd(a,b,m,n);
+%GAMRND Random matrices from gamma distribution.
+%   R = GAMRND(A,B) returns a matrix of random numbers chosen   
+%   from the gamma distribution with parameters A and B.
+%   The size of R is the common size of A and B if both are matrices.
+%   If either parameter is a scalar, the size of R is the size of the other
+%   parameter. Alternatively, R = GAMRND(A,B,M,N) returns an M by N matrix. 
+%
+%   Some references refer to the gamma distribution
+%   with a single parameter. This corresponds to GAMRND
+%   with B = 1. (See Devroye, pages 401-402.)
+
+%   GAMRND uses a rejection or an inversion method depending on the
+%   value of A. 
+
+%   References:
+%      [1]  L. Devroye, "Non-Uniform Random Variate Generation", 
+%      Springer-Verlag, 1986
+
+%   B.A. Jones 2-1-93
+%   Copyright (c) 1993-98 by The MathWorks, Inc.
+%   $Revision: 1.1.1.1 $  $Date: 2005/04/26 02:29:18 $
+
+if nargin < 2, 
+   error('Requires at least two input arguments.'); 
+end
+
+
+if nargin == 2
+   [errorcode rows columns] = rndcheck(2,2,a,b);
+end
+
+if nargin == 3
+   [errorcode rows columns] = rndcheck(3,2,a,b,m);
+end
+
+if nargin == 4
+   [errorcode rows columns] = rndcheck(4,2,a,b,m,n);
+end
+
+if errorcode > 0
+   error('Size information is inconsistent.');
+end
+
+% Initialize r to zero.
+lth = rows*columns;
+r = zeros(lth,1);
+a = a(:); b = b(:);
+
+scalara = (length(a) == 1);
+if scalara 
+   a = a*ones(lth,1);
+end
+
+scalarb = (length(b) == 1);
+if scalarb 
+   b = b*ones(lth,1);
+end
+
+% If a == 1, then gamma is exponential. (Devroye, page 405).
+k = find(a == 1);
+if any(k)
+   r(k) = -b(k) .* log(rand(size(k)));
+end 
+
+
+k = find(a < 1 & a > 0);
+% (Devroye, page 418 Johnk's generator)
+if any(k)
+  c = zeros(lth,1);
+  d = zeros(lth,1);
+  c(k) = 1 ./ a(k);
+  d(k) = 1 ./ (1 - a(k));
+  accept = k;
+  while ~isempty(accept)
+    u = rand(size(accept));
+    v = rand(size(accept));
+    x = u .^ c(accept);
+    y = v .^ d(accept);
+    k1 = find((x + y) <= 1); 
+    if ~isempty(k1)
+      e = -log(rand(size(k1))); 
+      r(accept(k1)) = e .* x(k1) ./ (x(k1) + y(k1));
+      accept(k1) = [];
+    end
+  end
+  r(k) = r(k) .* b(k);
+end
+
+% Use a rejection method for a > 1.
+k = find(a > 1);
+% (Devroye, page 410 Best's algorithm)
+bb = zeros(size(a));
+c  = bb;
+if any(k)
+  bb(k) = a(k) - 1;
+  c(k) = 3 * a(k) - 3/4;
+  accept = k; 
+  count = 1;
+  while ~isempty(accept)
+    m = length(accept);
+    u = rand(m,1);
+    v = rand(m,1);
+    w = u .* (1 - u);
+    y = sqrt(c(accept) ./ w) .* (u - 0.5);
+    x = bb(accept) + y;
+    k1 = find(x >= 0);
+    if ~isempty(k1)
+      z = 64 * (w .^ 3) .* (v .^ 2);
+      k2 = (z(k1) <= (1 - 2 * (y(k1) .^2) ./ x(k1)));
+      k3 = k1(find(k2));
+      r(accept(k3)) = x(k3); 
+      k4 = k1(find(~k2));
+      k5 = k4(find(log(z(k4)) <= (2*(bb(accept(k4)).*log(x(k4)./bb(accept(k4)))-y(k4)))));
+      r(accept(k5)) = x(k5);
+      omit = [k3; k5];
+      accept(omit) = [];
+    end
+  end
+  r(k) = r(k) .* b(k);
+end
+
+% Return NaN if a or b is not positive.
+r(b <= 0 | a <= 0) = NaN;
+
+r = reshape(r,rows,columns);
diff --git a/sourcecodes/bnt-master/KPMstats/gaussian_prob.m b/sourcecodes/bnt-master/KPMstats/gaussian_prob.m
new file mode 100644
index 00000000..0ac0b765
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/gaussian_prob.m
@@ -0,0 +1,28 @@
+function p = gaussian_prob(x, m, C, use_log)
+% GAUSSIAN_PROB Evaluate a multivariate Gaussian density.
+% p = gaussian_prob(X, m, C)
+% p(i) = N(X(:,i), m, C) where C = covariance matrix and each COLUMN of x is a datavector
+
+% p = gaussian_prob(X, m, C, 1) returns log N(X(:,i), m, C) (to prevents underflow).
+%
+% If X has size dxN, then p has size Nx1, where N = number of examples
+
+if nargin < 4, use_log = 0; end
+
+if length(m)==1 % scalar
+  x = x(:)';
+end
+[d N] = size(x);
+%assert(length(m)==d); % slow
+m = m(:);
+M = m*ones(1,N); % replicate the mean across columns
+denom = (2*pi)^(d/2)*sqrt(abs(det(C)));
+mahal = sum(((x-M)'*inv(C)).*(x-M)',2);   % Chris Bregler's trick
+if any(mahal<0)
+  warning('mahal < 0 => C is not psd')
+end
+if use_log
+  p = -0.5*mahal - log(denom);
+else
+  p = exp(-0.5*mahal) / (denom+eps);
+end
diff --git a/sourcecodes/bnt-master/KPMstats/gaussian_sample.m b/sourcecodes/bnt-master/KPMstats/gaussian_sample.m
new file mode 100644
index 00000000..a2f09df8
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/gaussian_sample.m
@@ -0,0 +1,25 @@
+function x = gsamp(mu, covar, nsamp)
+%GSAMP	Sample from a Gaussian distribution.
+%
+%	Description
+%
+%	X = GSAMP(MU, COVAR, NSAMP) generates a sample of size NSAMP from a
+%	D-dimensional Gaussian distribution. The Gaussian density has mean
+%	vector MU and covariance matrix COVAR, and the matrix X has NSAMP
+%	rows in which each row represents a D-dimensional sample vector.
+%
+%	See also
+%	GAUSS, DEMGAUSS
+%
+
+%	Copyright (c) Ian T Nabney (1996-2001)
+
+d = size(covar, 1);
+
+mu = reshape(mu, 1, d);   % Ensure that mu is a row vector
+
+[evec, eval] = eig(covar);
+
+coeffs = randn(nsamp, d)*sqrt(eval);
+
+x = ones(nsamp, 1)*mu + coeffs*evec';
diff --git a/sourcecodes/bnt-master/KPMstats/histCmpChi2.m b/sourcecodes/bnt-master/KPMstats/histCmpChi2.m
new file mode 100644
index 00000000..58f3da98
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/histCmpChi2.m
@@ -0,0 +1,15 @@
+function d = histCmpChi2(h1, h2)
+% Compare two histograms using chi-squared
+% function d = histCmpChi2(h1, h2)
+%
+% d(i,j) = chi^2(h1(i,:), h2(j,:)) = sum_b  (h1(i,b)-h2(j,b)^2 / (h1(i,b) + h2(j,b))
+
+[N B] = size(h1);
+d = zeros(N,N);
+for i=1:N
+  h1i = repmat(h1(i,:), N, 1);
+  numer = (h1i - h2).^2;
+  denom = h1i + h2 + eps; % if denom=0, then numer=0
+  d(i,:) = sum(numer ./ denom, 2);
+end
+  
diff --git a/sourcecodes/bnt-master/KPMstats/linear_regression.m b/sourcecodes/bnt-master/KPMstats/linear_regression.m
new file mode 100644
index 00000000..b33ab774
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/linear_regression.m
@@ -0,0 +1,68 @@
+function [muY, SigmaY, weightsY]  = linear_regression(X, Y, varargin)
+% LINEAR_REGRESSION Fit params for P(Y|X) = N(Y;  W X + mu, Sigma) 
+%
+% X(:, t) is the t'th input example
+% Y(:, t) is the t'th output example
+%
+% Kevin Murphy, August 2003
+%
+% This is a special case of cwr_em with 1 cluster.
+% You can also think of it as a front end to clg_Mstep.
+
+[cov_typeY, clamp_weights,  muY, SigmaY, weightsY,...
+ cov_priorY,  regress, clamp_covY] = process_options(...
+    varargin, ...
+     'cov_typeY', 'full', 'clamp_weights', 0, ...
+     'muY', [], 'SigmaY', [], 'weightsY', [], ...
+     'cov_priorY', [], 'regress', 1,  'clamp_covY', 0);
+     
+[nx N] = size(X);
+[ny N2] = size(Y);
+if N ~= N2
+  error(sprintf('nsamples X (%d) ~= nsamples Y (%d)', N, N2));
+end
+
+w = 1/N;
+WYbig = Y*w;
+WYY = WYbig * Y'; 
+WY = sum(WYbig, 2);
+WYTY = sum(diag(WYbig' * Y));
+if ~regress
+  % This is just fitting an unconditional Gaussian
+  weightsY = [];
+  [muY, SigmaY] = ...
+      mixgauss_Mstep(1, WY, WYY, WYTY, ...
+		     'cov_type', cov_typeY, 'cov_prior', cov_priorY);
+  % There is a much easier way...
+  assert(approxeq(muY, mean(Y')))
+  assert(approxeq(SigmaY, cov(Y') + 0.01*eye(ny)))
+else
+  % This is just linear regression
+  WXbig = X*w;
+  WXX = WXbig * X';
+  WX = sum(WXbig, 2);
+  WXTX = sum(diag(WXbig' * X));
+  WXY = WXbig * Y';
+  [muY, SigmaY, weightsY] = ...
+      clg_Mstep(1, WY, WYY, WYTY, WX, WXX, WXY, ...
+		'cov_type', cov_typeY, 'cov_prior', cov_priorY);
+end
+if clamp_covY, SigmaY = SigmaY; end
+if clamp_weights,  weightsY = weightsY; end
+
+if nx==1 & ny==1 & regress
+  P = polyfit(X,Y); % Y = P(1) X^1 + P(2) X^0 = ax + b
+  assert(approxeq(muY, P(2)))
+  assert(approxeq(weightsY, P(1)))
+end
+
+%%%%%%%% Test
+if 0 
+  c1 = randn(2,100);   c2 = randn(2,100);
+  y = c2(1,:); X = [ones(size(c1,2),1) c1'];
+  b = regress(y(:), X); % stats toolbox
+  [m,s,w] = linear_regression(c1, y);
+  assert(approxeq(b(1),m))
+  assert(approxeq(b(2), w(1)))
+  assert(approxeq(b(3), w(2)))
+end
diff --git a/sourcecodes/bnt-master/KPMstats/logist2.m b/sourcecodes/bnt-master/KPMstats/logist2.m
new file mode 100644
index 00000000..1c1e1619
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/logist2.m
@@ -0,0 +1,115 @@
+function [beta,p,lli] = logist2(y,x,w)
+% [beta,p,lli] = logist2(y,x) 
+%
+% 2-class logistic regression.  
+%
+% INPUT
+% 	y 	Nx1 colum vector of 0|1 class assignments
+% 	x 	NxK matrix of input vectors as rows
+% 	[w]	Nx1 vector of sample weights 
+%
+% OUTPUT
+% 	beta 	Kx1 column vector of model coefficients
+% 	p 	Nx1 column vector of fitted class 1 posteriors
+% 	lli 	log likelihood
+%
+% Class 1 posterior is 1 / (1 + exp(-x*beta))
+%
+% David Martin <dmartin@eecs.berkeley.edu> 
+% April 16, 2002
+
+% Copyright (C) 2002 David R. Martin <dmartin@eecs.berkeley.edu>
+%
+% This program is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation; either version 2 of the
+% License, or (at your option) any later version.
+% 
+
+% This program is distributed in the hope that it will be useful, but
+% WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+% General Public License for more details.
+% 
+% You should have received a copy of the GNU General Public License
+% along with this program; if not, write to the Free Software
+% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+% 02111-1307, USA, or see http://www.gnu.org/copyleft/gpl.html.
+
+error(nargchk(2,3,nargin));
+
+% check inputs
+if size(y,2) ~= 1,
+  error('Input y not a column vector.');
+end
+if size(y,1) ~= size(x,1), 
+  error('Input x,y sizes mismatched.'); 
+end
+
+% get sizes
+[N,k] = size(x);
+
+% if sample weights weren't specified, set them to 1
+if nargin < 3, 
+  w = 1;
+end
+
+% normalize sample weights so max is 1
+w = w / max(w);
+
+% initial guess for beta: all zeros
+beta = zeros(k,1);
+
+% Newton-Raphson via IRLS,
+% taken from Hastie/Tibshirani/Friedman Section 4.4.
+iter = 0;
+lli = 0;
+while 1==1,
+  iter = iter + 1;
+  
+  % fitted probabilities
+  p = 1 ./ (1 + exp(-x*beta));	
+  
+  % log likelihood
+  lli_prev = lli;
+  lli = sum( w .* (y.*log(p+eps) + (1-y).*log(1-p+eps)) );
+
+  % least-squares weights
+  wt = w .* p .* (1-p);		
+
+  % derivatives of likelihood w.r.t. beta
+  deriv = x'*(w.*(y-p));
+
+  % Hessian of likelihood w.r.t. beta
+  % hessian = x'Wx, where W=diag(w)
+  % Do it this way to be memory efficient and fast.
+  hess = zeros(k,k);
+  for i = 1:k,
+    wxi = wt .* x(:,i);
+    for j = i:k,
+      hij = wxi' * x(:,j);
+      hess(i,j) = -hij;
+      hess(j,i) = -hij;
+    end
+  end
+
+  % make sure Hessian is well conditioned
+  if (rcond(hess) < eps), 
+    error(['Stopped at iteration ' num2str(iter) ...
+           ' because Hessian is poorly conditioned.']);
+    break; 
+  end;
+
+  % Newton-Raphson update step
+  step = hess\deriv;
+  beta = beta - step;
+
+  % termination criterion based on derivatives
+  tol = 1e-6;
+  if abs(deriv'*step/k) < tol, break; end;
+
+  % termination criterion based on log likelihood
+%   tol = 1e-4;
+%   if abs((lli-lli_prev)/(lli+lli_prev)) < 0.5*tol, break; end;
+end;
+
diff --git a/sourcecodes/bnt-master/KPMstats/logist2Apply.m b/sourcecodes/bnt-master/KPMstats/logist2Apply.m
new file mode 100644
index 00000000..57be8c35
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/logist2Apply.m
@@ -0,0 +1,13 @@
+function p = logist2Apply(beta, x)
+% LOGIST2APPLY 2 class logistic regression: compute posterior prob of class 1
+% function p = logist2Apply(beta, x)
+%
+% x(:,i) - each COLUMN is a test case; we append 1s automatically, if appropriate
+
+[D Ncases] = size(x);
+if length(beta)==D+1
+  F = [x; ones(1,Ncases)];
+else
+  F = x;
+end
+p = 1./(1+exp(-beta(:)'*F));
diff --git a/sourcecodes/bnt-master/KPMstats/logist2ApplyRegularized.m b/sourcecodes/bnt-master/KPMstats/logist2ApplyRegularized.m
new file mode 100644
index 00000000..39095a3d
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/logist2ApplyRegularized.m
@@ -0,0 +1,3 @@
+function prob = logist2ApplyRegularized(net, features)
+
+prob = glmfwd(net, features')';
diff --git a/sourcecodes/bnt-master/KPMstats/logist2Fit.m b/sourcecodes/bnt-master/KPMstats/logist2Fit.m
new file mode 100644
index 00000000..7bc466b7
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/logist2Fit.m
@@ -0,0 +1,22 @@
+function [beta, p] = logist2Fit(y, x, addOne, w)
+% LOGIST2FIT 2 class logsitic classification
+% function beta = logist2Fit(y,x, addOne)
+%
+% y(i) = 0/1
+% x(:,i) = i'th input - we optionally append 1s to last dimension
+% w(i) = optional weight
+%
+% beta(j)- regression coefficient
+
+if nargin < 3, addOne = 1; end
+if nargin < 4, w = 1; end
+
+Ncases = size(x,2);
+if Ncases ~= length(y)
+  error(sprintf('size of data = %dx%d, size of labels=%d', size(x,1), size(x,2), length(y)))
+end
+if addOne
+  x = [x; ones(1,Ncases)];
+end
+[beta, p] = logist2(y(:), x', w(:));
+beta = beta(:);
diff --git a/sourcecodes/bnt-master/KPMstats/logist2FitRegularized.m b/sourcecodes/bnt-master/KPMstats/logist2FitRegularized.m
new file mode 100644
index 00000000..d521e8f7
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/logist2FitRegularized.m
@@ -0,0 +1,13 @@
+function [net, niter] = logist2FitRegularized(labels, features, maxIter)
+
+if nargin < 3, maxIter = 100; end
+
+[D  N] = size(features);
+weightPrior = 0.5;
+net = glm(D, 1, 'logistic', weightPrior);
+options = foptions;
+options(14) = maxIter;
+[net, options] = glmtrain(net, options, features', labels(:));
+niter = options(14);
+%w = logist2Fit(labelsPatches(jValidPatches), features(:, jValidPatches));
+
diff --git a/sourcecodes/bnt-master/KPMstats/logistK.m b/sourcecodes/bnt-master/KPMstats/logistK.m
new file mode 100644
index 00000000..8309328a
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/logistK.m
@@ -0,0 +1,287 @@
+function [beta,post,lli] = logistK(x,y,w,beta)
+% [beta,post,lli] = logistK(x,y,beta,w) 
+%
+% k-class logistic regression with optional sample weights
+%
+% k = number of classes
+% n = number of samples
+% d = dimensionality of samples
+%
+% INPUT
+% 	x 	dxn matrix of n input column vectors
+% 	y 	kxn vector of class assignments
+% 	[w]	1xn vector of sample weights 
+%	[beta]	dxk matrix of model coefficients
+%
+% OUTPUT
+% 	beta 	dxk matrix of fitted model coefficients 
+%		(beta(:,k) are fixed at 0) 
+% 	post 	kxn matrix of fitted class posteriors
+% 	lli 	log likelihood
+%
+% Let p(i,j) = exp(beta(:,j)'*x(:,i)),
+% Class j posterior for observation i is:
+%	post(j,i) = p(i,j) / (p(i,1) + ... p(i,k))
+%
+% See also logistK_eval.
+%
+% David Martin <dmartin@eecs.berkeley.edu> 
+% May 3, 2002
+
+% Copyright (C) 2002 David R. Martin <dmartin@eecs.berkeley.edu>
+%
+% This program is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation; either version 2 of the
+% License, or (at your option) any later version.
+% 
+% This program is distributed in the hope that it will be useful, but
+% WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+% General Public License for more details.
+% 
+% You should have received a copy of the GNU General Public License
+% along with this program; if not, write to the Free Software
+% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+% 02111-1307, USA, or see http://www.gnu.org/copyleft/gpl.html.
+
+% TODO - this code would be faster if x were transposed
+
+error(nargchk(2,4,nargin));
+
+debug = 0;
+if debug>0,
+  h=figure(1);
+  set(h,'DoubleBuffer','on');
+end
+
+% get sizes
+[d,nx] = size(x);
+[k,ny] = size(y);
+
+% check sizes
+if k < 2,
+  error('Input y must encode at least 2 classes.');
+end
+if nx ~= ny,
+  error('Inputs x,y not the same length.'); 
+end
+
+n = nx;
+
+% make sure class assignments have unit L1-norm
+sumy = sum(y,1);
+if abs(1-sumy) > eps,
+  sumy = sum(y,1);
+  for i = 1:k, y(i,:) = y(i,:) ./ sumy; end
+end
+clear sumy;
+
+% if sample weights weren't specified, set them to 1
+if nargin < 3, 
+  w = ones(1,n);
+end
+
+% normalize sample weights so max is 1
+w = w / max(w);
+
+% if starting beta wasn't specified, initialize randomly
+if nargin < 4,
+  beta = 1e-3*rand(d,k);
+  beta(:,k) = 0;	% fix beta for class k at zero
+else
+  if sum(beta(:,k)) ~= 0,
+    error('beta(:,k) ~= 0');
+  end
+end
+
+stepsize = 1;
+minstepsize = 1e-2;
+
+post = computePost(beta,x);
+lli = computeLogLik(post,y,w);
+
+for iter = 1:100,
+  %disp(sprintf('  logist iter=%d lli=%g',iter,lli));
+  vis(x,y,beta,lli,d,k,iter,debug);
+
+  % gradient and hessian
+  [g,h] = derivs(post,x,y,w);
+
+  % make sure Hessian is well conditioned
+  if rcond(h) < eps, 
+    % condition with Levenberg-Marquardt method
+    for i = -16:16,
+      h2 = h .* ((1 + 10^i)*eye(size(h)) + (1-eye(size(h))));
+      if rcond(h2) > eps, break, end
+    end
+    if rcond(h2) < eps,
+      warning(['Stopped at iteration ' num2str(iter) ...
+               ' because Hessian can''t be conditioned']);
+      break 
+    end
+    h = h2;
+  end
+
+  % save lli before update
+  lli_prev = lli;
+
+  % Newton-Raphson with step-size halving
+  while stepsize >= minstepsize,
+    % Newton-Raphson update step
+    step = stepsize * (h \ g);
+    beta2 = beta;
+    beta2(:,1:k-1) = beta2(:,1:k-1) - reshape(step,d,k-1);
+
+    % get the new log likelihood
+    post2 = computePost(beta2,x);
+    lli2 = computeLogLik(post2,y,w);
+
+    % if the log likelihood increased, then stop
+    if lli2 > lli, 
+      post = post2; lli = lli2; beta = beta2;
+      break
+    end
+
+    % otherwise, reduce step size by half
+    stepsize = 0.5 * stepsize;
+  end
+
+  % stop if the average log likelihood has gotten small enough
+  if 1-exp(lli/n) < 1e-2, break, end
+
+  % stop if the log likelihood changed by a small enough fraction
+  dlli = (lli_prev-lli) / lli;
+  if abs(dlli) < 1e-3, break, end
+
+  % stop if the step size has gotten too small
+  if stepsize < minstepsize, brea, end
+
+  % stop if the log likelihood has decreased; this shouldn't happen
+  if lli < lli_prev,
+    warning(['Stopped at iteration ' num2str(iter) ...
+             ' because the log likelihood decreased from ' ...
+             num2str(lli_prev) ' to ' num2str(lli) '.' ...
+            ' This may be a bug.']);
+    break
+  end
+end
+
+if debug>0, 
+  vis(x,y,beta,lli,d,k,iter,2); 
+end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% class posteriors
+function post = computePost(beta,x)
+  [d,n] = size(x);
+  [d,k] = size(beta);
+  post = zeros(k,n);
+  bx = zeros(k,n);
+  for j = 1:k, 
+    bx(j,:) = beta(:,j)'*x; 
+  end
+  for j = 1:k, 
+    post(j,:) = 1 ./ sum(exp(bx - repmat(bx(j,:),k,1)),1);
+  end
+  
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% log likelihood
+function lli = computeLogLik(post,y,w)
+  [k,n] = size(post);
+  lli = 0;
+  for j = 1:k,
+    lli = lli + sum(w.*y(j,:).*log(post(j,:)+eps));
+  end
+  if isnan(lli), 
+    error('lli is nan'); 
+  end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% gradient and hessian
+%% These are computed in what seems a verbose manner, but it is
+%% done this way to use minimal memory.  x should be transposed
+%% to make it faster.
+function [g,h] = derivs(post,x,y,w)
+
+  [k,n] = size(post);
+  [d,n] = size(x);
+
+  % first derivative of likelihood w.r.t. beta
+  g = zeros(d,k-1);
+  for j = 1:k-1,
+    wyp = w .* (y(j,:) - post(j,:));
+    for ii = 1:d, 
+      g(ii,j) = x(ii,:) * wyp'; 
+    end
+  end
+  g = reshape(g,d*(k-1),1);
+
+  % hessian of likelihood w.r.t. beta
+  h = zeros(d*(k-1),d*(k-1)); 
+  for i = 1:k-1,	% diagonal
+    wt = w .* post(i,:) .* (1 - post(i,:));
+    hii = zeros(d,d);
+    for a = 1:d,
+      wxa = wt .* x(a,:);
+      for b = a:d,
+        hii_ab = wxa * x(b,:)';
+        hii(a,b) = hii_ab;
+        hii(b,a) = hii_ab;
+      end
+    end
+    h( (i-1)*d+1 : i*d , (i-1)*d+1 : i*d ) = -hii;
+  end
+  for i = 1:k-1,	% off-diagonal
+    for j = i+1:k-1,
+      wt = w .* post(j,:) .* post(i,:);
+      hij = zeros(d,d);
+      for a = 1:d,
+        wxa = wt .* x(a,:);
+        for b = a:d,
+          hij_ab = wxa * x(b,:)';
+          hij(a,b) = hij_ab;
+          hij(b,a) = hij_ab;
+        end
+      end
+      h( (i-1)*d+1 : i*d , (j-1)*d+1 : j*d ) = hij;
+      h( (j-1)*d+1 : j*d , (i-1)*d+1 : i*d ) = hij;
+    end
+  end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% debug/visualization
+function vis (x,y,beta,lli,d,k,iter,debug)
+
+  if debug<=0, return, end
+
+  disp(['iter=' num2str(iter) ' lli=' num2str(lli)]);
+  if debug<=1, return, end
+
+  if d~=3 | k>10, return, end
+
+  figure(1);
+  res = 100;
+  r = abs(max(max(x)));
+  dom = linspace(-r,r,res);
+  [px,py] = meshgrid(dom,dom);
+  xx = px(:); yy = py(:);
+  points = [xx' ; yy' ; ones(1,res*res)];
+  func = zeros(k,res*res);
+  for j = 1:k,
+    func(j,:) = exp(beta(:,j)'*points);
+  end
+  [mval,ind] = max(func,[],1);
+  hold off; 
+  im = reshape(ind,res,res);
+  imagesc(xx,yy,im);
+  hold on;
+  syms = {'w.' 'wx' 'w+' 'wo' 'w*' 'ws' 'wd' 'wv' 'w^' 'w<'};
+  for j = 1:k,
+    [mval,ind] = max(y,[],1);
+    ind = find(ind==j);
+    plot(x(1,ind),x(2,ind),syms{j});
+  end
+  pause(0.1);
+
+% eof
diff --git a/sourcecodes/bnt-master/KPMstats/logistK_eval.m b/sourcecodes/bnt-master/KPMstats/logistK_eval.m
new file mode 100644
index 00000000..880a5f4b
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/logistK_eval.m
@@ -0,0 +1,83 @@
+function [post,lik,lli] = logistK_eval(beta,x,y)
+% [post,lik,lli] = logistK_eval(beta,x,y)
+%
+% Evaluate logistic regression model.
+% 
+% INPUT
+% 	beta 	dxk model coefficients (as returned by logistK)
+% 	x 	dxn matrix of n input column vectors
+% 	[y] 	kxn vector of class assignments
+%
+% OUTPUT
+% 	post 	kxn fitted class posteriors
+% 	lik 	1xn vector of sample likelihoods
+%	lli	log likelihood
+%
+% Let p(i,j) = exp(beta(:,j)'*x(:,i)),
+% Class j posterior for observation i is:
+%	post(j,i) = p(i,j) / (p(i,1) + ... p(i,k))
+% The likelihood of observation i given soft class assignments
+% y(:,i) is: 
+%	lik(i) = prod(post(:,i).^y(:,i))
+% The log-likelihood of the model given the labeled samples is:
+%	lli = sum(log(lik))
+% 
+% See also logistK.
+%
+% David Martin <dmartin@eecs.berkeley.edu> 
+% May 7, 2002
+
+% Copyright (C) 2002 David R. Martin <dmartin@eecs.berkeley.edu>
+%
+% This program is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation; either version 2 of the
+% License, or (at your option) any later version.
+% 
+% This program is distributed in the hope that it will be useful, but
+% WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+% General Public License for more details.
+% 
+% You should have received a copy of the GNU General Public License
+% along with this program; if not, write to the Free Software
+% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+% 02111-1307, USA, or see http://www.gnu.org/copyleft/gpl.html.
+
+error(nargchk(2,3,nargin));
+
+% check sizes
+if size(beta,1) ~= size(x,1),
+  error('Inputs beta,x not the same height.');
+end
+if nargin > 3 & size(y,2) ~= size(x,2), 
+  error('Inputs x,y not the same length.'); 
+end
+
+% get sizes
+[d,k] = size(beta);
+[d,n] = size(x);
+
+% class posteriors
+post = zeros(k,n);
+bx = zeros(k,n);
+for j = 1:k, 
+  bx(j,:) = beta(:,j)'*x; 
+end
+for j = 1:k, 
+  post(j,:) = 1 ./ sum(exp(bx - repmat(bx(j,:),k,1)),1);
+end
+clear bx;
+
+% likelihood of each sample
+if nargout > 1,
+  y = y ./ repmat(sum(y,1),k,1); % L1-normalize class assignments
+  lik = prod(post.^y,1);
+end
+
+% total log likelihood
+if nargout > 2,
+  lli = sum(log(lik+eps));
+end;
+
+% eof
diff --git a/sourcecodes/bnt-master/KPMstats/marginalize_gaussian.m b/sourcecodes/bnt-master/KPMstats/marginalize_gaussian.m
new file mode 100644
index 00000000..7f347f48
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/marginalize_gaussian.m
@@ -0,0 +1,7 @@
+function [muX, SXX] = marginalize_gaussian(mu, Sigma, X, Y, ns)
+% MARGINALIZE_GAUSSIAN Compute Pr(X) from Pr(X,Y) where X and Y are jointly Gaussian.
+% [muX, SXX] = marginalize_gaussian(mu, Sigma, X, Y, ns)
+
+[muX, muY, SXX, SXY, SYX, SYY] = partition_matrix_vec(mu, Sigma, X, Y, ns);
+
+
diff --git a/sourcecodes/bnt-master/KPMstats/matrix_T_pdf.m b/sourcecodes/bnt-master/KPMstats/matrix_T_pdf.m
new file mode 100644
index 00000000..b6fb92d4
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/matrix_T_pdf.m
@@ -0,0 +1,12 @@
+function p = matrix_T_pdf(A, M, V, K, n)
+% MATRIX_T_PDF Evaluate the density of a matrix under a Matrix-T distribution
+% p = matrix_T_pdf(A, M, V, K, n)
+
+% See "Bayesian Linear Regression", T. Minka, MIT Tech Report, 2001
+
+[d m] = size(K);
+is = 1:d;
+c1 = prod(gamma((n+1-is)/2)) / prod(gamma((n-m+1-is)/2));
+c2 = det(K)^(d/2) / det(pi*V)^(m/2); %% pi or 2pi?
+p = c1 * c2 * det((A-M)'*inv(V)*(A-M)*K + eye(m))^(-n/2);
+
diff --git a/sourcecodes/bnt-master/KPMstats/matrix_normal_pdf.m b/sourcecodes/bnt-master/KPMstats/matrix_normal_pdf.m
new file mode 100644
index 00000000..5e8e9a78
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/matrix_normal_pdf.m
@@ -0,0 +1,9 @@
+function p = matrix_normal_pdf(A, M, V, K)
+% MATRIX_NORMAL_PDF Evaluate the density of a matrix under a Matrix-Normal distribution
+% p = matrix_normal_pdf(A, M, V, K)
+
+% See "Bayesian Linear Regression", T. Minka, MIT Tech Report, 2001
+
+[d m] = size(K);
+c = det(K)^(d/2) / det(2*pi*V)^(m/2);
+p = c * exp(-0.5*tr((A-M)'*inv(V)*(A-M)*K));
diff --git a/sourcecodes/bnt-master/KPMstats/mc_stat_distrib.m b/sourcecodes/bnt-master/KPMstats/mc_stat_distrib.m
new file mode 100644
index 00000000..a5806092
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/mc_stat_distrib.m
@@ -0,0 +1,26 @@
+function pi = mc_stat_distrib(P)
+% MC_STAT_DISTRIB Compute stationary distribution of a Markov chain
+% function pi = mc_stat_distrib(P)
+% 
+% Each row of P should sum to one; pi is a column vector
+
+% Kevin Murphy, 16 Feb 2003
+
+% The stationary distribution pi satisfies pi P = pi
+% subject to sum_i pi(i) = 1,  0 <= pi(i) <= 1
+% Hence
+% (P'  0n   (pi  = (pi 
+%  1n  0)    1)     1)
+% or P2 pi2 = pi2.
+% Naively we can solve this using (P2 - I(n+1)) pi2 = 0(n+1)
+% or P3 pi2 = 0(n+1), i.e., pi2 = P3 \ zeros(n+1,1)
+% but this is singular (because of the sum-to-one constraint).
+% Hence we replace the last row of P' with 1s instead of appending ones to create P2, 
+% and similarly for pi.
+
+n = length(P);
+P4 = P'-eye(n);
+P4(end,:) = 1;
+pi = P4 \ [zeros(n-1,1);1];
+
+
diff --git a/sourcecodes/bnt-master/KPMstats/mixgauss_Mstep.m b/sourcecodes/bnt-master/KPMstats/mixgauss_Mstep.m
new file mode 100644
index 00000000..7908a704
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/mixgauss_Mstep.m
@@ -0,0 +1,106 @@
+function [mu, Sigma] = mixgauss_Mstep(w, Y, YY, YTY, varargin)
+% MSTEP_COND_GAUSS Compute MLEs for mixture of Gaussians given expected sufficient statistics
+% function [mu, Sigma] = Mstep_cond_gauss(w, Y, YY, YTY, varargin)
+%
+% We assume P(Y|Q=i) = N(Y; mu_i, Sigma_i)
+% and w(i,t) = p(Q(t)=i|y(t)) = posterior responsibility
+% See www.ai.mit.edu/~murphyk/Papers/learncg.pdf.
+%
+% INPUTS:
+% w(i) = sum_t w(i,t) = responsibilities for each mixture component
+%  If there is only one mixture component (i.e., Q does not exist),
+%  then w(i) = N = nsamples,  and 
+%  all references to i can be replaced by 1.
+% YY(:,:,i) = sum_t w(i,t) y(:,t) y(:,t)' = weighted outer product
+% Y(:,i) = sum_t w(i,t) y(:,t) = weighted observations
+% YTY(i) = sum_t w(i,t) y(:,t)' y(:,t) = weighted inner product
+%   You only need to pass in YTY if Sigma is to be estimated as spherical.
+%
+% Optional parameters may be passed as 'param_name', param_value pairs.
+% Parameter names are shown below; default values in [] - if none, argument is mandatory.
+%
+% 'cov_type' - 'full', 'diag' or 'spherical' ['full']
+% 'tied_cov' - 1 (Sigma) or 0 (Sigma_i) [0]
+% 'clamped_cov' - pass in clamped value, or [] if unclamped [ [] ]
+% 'clamped_mean' - pass in clamped value, or [] if unclamped [ [] ]
+% 'cov_prior' - Lambda_i, added to YY(:,:,i) [0.01*eye(d,d,Q)]
+%
+% If covariance is tied, Sigma has size d*d.
+% But diagonal and spherical covariances are represented in full size.
+
+[cov_type, tied_cov,  clamped_cov, clamped_mean, cov_prior, other] = ...
+    process_options(varargin,...
+		    'cov_type', 'full', 'tied_cov', 0,  'clamped_cov', [], 'clamped_mean', [], ...
+		    'cov_prior', []);
+
+[Ysz Q] = size(Y);
+N = sum(w);
+if isempty(cov_prior)
+  %cov_prior = zeros(Ysz, Ysz, Q);
+  %for q=1:Q
+  %  cov_prior(:,:,q) = 0.01*cov(Y(:,q)');
+  %end
+  cov_prior = repmat(0.01*eye(Ysz,Ysz), [1 1 Q]);
+end
+%YY = reshape(YY, [Ysz Ysz Q]) + cov_prior; % regularize the scatter matrix
+YY = reshape(YY, [Ysz Ysz Q]);
+
+% Set any zero weights to one before dividing
+% This is valid because w(i)=0 => Y(:,i)=0, etc
+w = w + (w==0);
+		    
+if ~isempty(clamped_mean)
+  mu = clamped_mean;
+else
+  % eqn 6
+  %mu = Y ./ repmat(w(:)', [Ysz 1]);% Y may have a funny size
+  mu = zeros(Ysz, Q);
+  for i=1:Q
+    mu(:,i) = Y(:,i) / w(i);
+  end
+end
+
+if ~isempty(clamped_cov)
+  Sigma = clamped_cov;
+  return;
+end
+
+if ~tied_cov
+  Sigma = zeros(Ysz,Ysz,Q);
+  for i=1:Q
+    if cov_type(1) == 's'
+      % eqn 17
+      s2 = (1/Ysz)*( (YTY(i)/w(i)) - mu(:,i)'*mu(:,i) );
+      Sigma(:,:,i) = s2 * eye(Ysz);
+    else
+      % eqn 12
+      SS = YY(:,:,i)/w(i)  - mu(:,i)*mu(:,i)';
+      if cov_type(1)=='d'
+	SS = diag(diag(SS));
+      end
+      Sigma(:,:,i) = SS;
+    end
+  end
+else % tied cov
+  if cov_type(1) == 's'
+    % eqn 19
+    s2 = (1/(N*Ysz))*(sum(YTY,2) + sum(diag(mu'*mu) .* w));
+    Sigma = s2*eye(Ysz);
+  else
+    SS = zeros(Ysz, Ysz);
+    % eqn 15
+    for i=1:Q % probably could vectorize this...
+      SS = SS + YY(:,:,i)/N - mu(:,i)*mu(:,i)';
+    end
+    if cov_type(1) == 'd'
+      Sigma = diag(diag(SS));
+    else
+      Sigma = SS;
+    end
+  end
+end
+
+if tied_cov
+  Sigma =  repmat(Sigma, [1 1 Q]);
+end
+Sigma = Sigma + cov_prior;
diff --git a/sourcecodes/bnt-master/KPMstats/mixgauss_classifier_apply.m b/sourcecodes/bnt-master/KPMstats/mixgauss_classifier_apply.m
new file mode 100644
index 00000000..73baaeb1
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/mixgauss_classifier_apply.m
@@ -0,0 +1,11 @@
+function [classHatTest, probPos] = mixgauss_classifier_apply(mixgauss, testFeatures)
+
+Bpos = mixgauss_prob(testFeatures, mixgauss.pos.mu, mixgauss.pos.Sigma, mixgauss.pos.prior);
+Bneg = mixgauss_prob(testFeatures, mixgauss.neg.mu, mixgauss.neg.Sigma,  mixgauss.neg.prior);
+prior_pos = mixgauss.priorC(1);
+prior_neg = mixgauss.priorC(2);
+post = normalize([Bpos * prior_pos; Bneg * prior_neg], 1);
+probPos = post(1,:)';
+[junk, classHatTest] = max(post);
+classHatTest(find(classHatTest==2))=0;
+classHatTest = classHatTest(:);
diff --git a/sourcecodes/bnt-master/KPMstats/mixgauss_classifier_train.m b/sourcecodes/bnt-master/KPMstats/mixgauss_classifier_train.m
new file mode 100644
index 00000000..fa0861ac
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/mixgauss_classifier_train.m
@@ -0,0 +1,33 @@
+function mixgauss = mixgauss_classifier_train(trainFeatures, trainLabels, nc, varargin)
+% function mixgauss = mixgauss_classifier_train(trainFeatures, trainLabels, nclusters, varargin)
+% trainFeatures(:,i) for i'th example
+% trainLabels should be 0,1
+% To evaluate performance on a tets set, use
+% mixgauss = mixgauss_classifier_train(trainFeatures, trainLabels, nc, 'testFeatures', tf, 'testLabels', tl)
+
+[testFeatures, testLabels, max_iter, thresh, cov_type, mu, Sigma, priorC, method, ...
+ cov_prior, verbose, prune_thresh] = process_options(...
+    varargin, 'testFeatures', [], 'testLabels', [], ...
+     'max_iter', 10, 'thresh', 0.01, 'cov_type', 'diag', ...
+    'mu', [], 'Sigma', [], 'priorC', [], 'method', 'kmeans', ...
+    'cov_prior', [], 'verbose', 0, 'prune_thresh', 0);
+
+Nclasses = 2; % max([trainLabels testLabels]) + 1;
+
+pos = find(trainLabels == 1);
+neg = find(trainLabels == 0);
+
+if verbose, fprintf('fitting pos\n'); end
+[mixgauss.pos.mu, mixgauss.pos.Sigma, mixgauss.pos.prior] = ...
+    mixgauss_em(trainFeatures(:, pos), nc, varargin{:});
+
+if verbose, fprintf('fitting neg\n'); end
+[mixgauss.neg.mu, mixgauss.neg.Sigma, mixgauss.neg.prior] = ...
+    mixgauss_em(trainFeatures(:, neg), nc, varargin{:});
+
+
+if ~isempty(priorC)
+  mixgauss.priorC = priorC;
+else
+  mixgauss.priorC = normalize([length(pos) length(neg)]);
+end
diff --git a/sourcecodes/bnt-master/KPMstats/mixgauss_em.m b/sourcecodes/bnt-master/KPMstats/mixgauss_em.m
new file mode 100644
index 00000000..a0a8154d
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/mixgauss_em.m
@@ -0,0 +1,74 @@
+function [mu, Sigma, prior] = mixgauss_em(Y, nc, varargin)
+% MIXGAUSS_EM Fit the parameters of a mixture of Gaussians using EM
+% function [mu, Sigma, prior] = mixgauss_em(data, nc, varargin)
+%
+% data(:, t) is the t'th data point
+% nc is the number of clusters
+
+% Kevin Murphy, 13 May 2003
+
+[max_iter, thresh, cov_type, mu, Sigma, method, ...
+ cov_prior, verbose, prune_thresh] = process_options(...
+    varargin, 'max_iter', 10, 'thresh', 1e-2, 'cov_type', 'full', ...
+    'mu', [], 'Sigma', [],  'method', 'kmeans', ...
+    'cov_prior', [], 'verbose', 0, 'prune_thresh', 0);
+
+[ny T] = size(Y);
+
+if nc==1
+  % No latent variable, so there is a closed-form solution
+  mu = mean(Y')';
+  Sigma = cov(Y');
+  if strcmp(cov_type, 'diag')
+    Sigma = diag(diag(Sigma));
+  end
+  prior = 1;
+  return;
+end
+
+if isempty(mu)
+  [mu, Sigma, prior] = mixgauss_init(nc, Y, cov_type, method);
+end
+
+previous_loglik = -inf;
+num_iter = 1;
+converged = 0;
+
+%if verbose, fprintf('starting em\n'); end
+
+while (num_iter <= max_iter) & ~converged
+  % E step
+  probY = mixgauss_prob(Y, mu, Sigma, prior); % probY(q,t)
+  [post, lik] = normalize(probY .* repmat(prior, 1, T), 1); % post(q,t)
+  loglik = log(sum(lik));
+ 
+  % extract expected sufficient statistics
+  w = sum(post,2);  % w(c) = sum_t post(c,t)
+  WYY = zeros(ny, ny, nc);  % WYY(:,:,c) = sum_t post(c,t) Y(:,t) Y(:,t)'
+  WY = zeros(ny, nc);  % WY(:,c) = sum_t post(c,t) Y(:,t)
+  WYTY = zeros(nc,1); % WYTY(c) = sum_t post(c,t) Y(:,t)' Y(:,t)
+  for c=1:nc
+    weights = repmat(post(c,:), ny, 1); % weights(:,t) = post(c,t)
+    WYbig = Y .* weights; % WYbig(:,t) = post(c,t) * Y(:,t)
+    WYY(:,:,c) = WYbig * Y';
+    WY(:,c) = sum(WYbig, 2); 
+    WYTY(c) = sum(diag(WYbig' * Y)); 
+  end
+  
+  % M step
+  prior = normalize(w);
+  [mu, Sigma] = mixgauss_Mstep(w, WY, WYY, WYTY, 'cov_type', cov_type, 'cov_prior', cov_prior);
+  
+  if verbose, fprintf(1, 'iteration %d, loglik = %f\n', num_iter, loglik); end
+  num_iter =  num_iter + 1;
+  converged = em_converged(loglik, previous_loglik, thresh);
+  previous_loglik = loglik;
+  
+end
+
+if prune_thresh > 0
+  ndx = find(prior < prune_thresh);
+  mu(:,ndx) = [];
+  Sigma(:,:,ndx) = [];
+  prior(ndx) = [];
+end
diff --git a/sourcecodes/bnt-master/KPMstats/mixgauss_init.m b/sourcecodes/bnt-master/KPMstats/mixgauss_init.m
new file mode 100644
index 00000000..5a4596e1
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/mixgauss_init.m
@@ -0,0 +1,49 @@
+function [mu, Sigma, weights] = mixgauss_init(M, data, cov_type, method)
+% MIXGAUSS_INIT Initial parameter estimates for a mixture of Gaussians
+% function [mu, Sigma, weights] = mixgauss_init(M, data, cov_type. method)
+%
+% INPUTS:
+% data(:,t) is the t'th example
+% M = num. mixture components
+% cov_type = 'full', 'diag' or 'spherical'
+% method = 'rnd' (choose centers randomly from data) or 'kmeans' (needs netlab)
+%
+% OUTPUTS:
+% mu(:,k) 
+% Sigma(:,:,k) 
+% weights(k)
+
+if nargin < 4, method = 'kmeans'; end
+
+[d T] = size(data);
+data = reshape(data, d, T); % in case it is data(:, t, sequence_num)
+
+switch method
+ case 'rnd', 
+  C = cov(data');
+  Sigma = repmat(diag(diag(C))*0.5, [1 1 M]);
+  % Initialize each mean to a random data point
+  indices = randperm(T);
+  mu = data(:,indices(1:M));
+  weights = normalise(ones(M,1));
+ case 'kmeans',
+  mix = gmm(d, M, cov_type);
+  options = foptions;
+  max_iter = 5;
+  options(1) = -1; % be quiet!
+  options(14) = max_iter;
+  mix = gmminit(mix, data', options);
+  mu = reshape(mix.centres', [d M]);
+  weights = mix.priors(:);
+  for m=1:M
+    switch cov_type
+     case 'diag',
+      Sigma(:,:,m) = diag(mix.covars(m,:));
+     case 'full',
+      Sigma(:,:,m) = mix.covars(:,:,m);
+     case 'spherical',
+      Sigma(:,:,m) = mix.covars(m) * eye(d);
+    end
+  end
+end
+
diff --git a/sourcecodes/bnt-master/KPMstats/mixgauss_prob.m b/sourcecodes/bnt-master/KPMstats/mixgauss_prob.m
new file mode 100644
index 00000000..3bd5afcc
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/mixgauss_prob.m
@@ -0,0 +1,133 @@
+function [B, B2] = mixgauss_prob(data, mu, Sigma, mixmat, unit_norm)
+% EVAL_PDF_COND_MOG Evaluate the pdf of a conditional mixture of Gaussians
+% function [B, B2] = eval_pdf_cond_mog(data, mu, Sigma, mixmat, unit_norm)
+%
+% Notation: Y is observation, M is mixture component, and both may be conditioned on Q.
+% If Q does not exist, ignore references to Q=j below.
+% Alternatively, you may ignore M if this is a conditional Gaussian.
+%
+% INPUTS:
+% data(:,t) = t'th observation vector 
+%
+% mu(:,k) = E[Y(t) | M(t)=k] 
+% or mu(:,j,k) = E[Y(t) | Q(t)=j, M(t)=k]
+%
+% Sigma(:,:,j,k) = Cov[Y(t) | Q(t)=j, M(t)=k]
+% or there are various faster, special cases:
+%   Sigma() - scalar, spherical covariance independent of M,Q.
+%   Sigma(:,:) diag or full, tied params independent of M,Q. 
+%   Sigma(:,:,j) tied params independent of M. 
+%
+% mixmat(k) = Pr(M(t)=k) = prior
+% or mixmat(j,k) = Pr(M(t)=k | Q(t)=j) 
+% Not needed if M is not defined.
+%
+% unit_norm - optional; if 1, means data(:,i) AND mu(:,i) each have unit norm (slightly faster)
+%
+% OUTPUT:
+% B(t) = Pr(y(t)) 
+% or
+% B(i,t) = Pr(y(t) | Q(t)=i) 
+% B2(i,k,t) = Pr(y(t) | Q(t)=i, M(t)=k) 
+%
+% If the number of mixture components differs depending on Q, just set the trailing
+% entries of mixmat to 0, e.g., 2 components if Q=1, 3 components if Q=2,
+% then set mixmat(1,3)=0. In this case, B2(1,3,:)=1.0.
+
+
+
+
+if isvectorBNT(mu) & size(mu,2)==1
+  d = length(mu);
+  Q = 1; M = 1;
+elseif ndims(mu)==2
+  [d Q] = size(mu);
+  M = 1;
+else
+  [d Q M] = size(mu);
+end
+[d T] = size(data);
+
+if nargin < 4, mixmat = ones(Q,1); end
+if nargin < 5, unit_norm = 0; end
+
+%B2 = zeros(Q,M,T); % ATB: not needed allways
+%B = zeros(Q,T);
+
+if isscalarBNT(Sigma)
+  mu = reshape(mu, [d Q*M]);
+  if unit_norm % (p-q)'(p-q) = p'p + q'q - 2p'q = n+m -2p'q since p(:,i)'p(:,i)=1
+    %avoid an expensive repmat
+    disp('unit norm')
+    %tic; D = 2 -2*(data'*mu)'; toc 
+    D = 2 - 2*(mu'*data);
+    tic; D2 = sqdist(data, mu)'; toc
+    assert(approxeq(D,D2)) 
+  else
+    D = sqdist(data, mu)';
+  end
+  clear mu data % ATB: clear big old data
+  % D(qm,t) = sq dist between data(:,t) and mu(:,qm)
+  logB2 = -(d/2)*log(2*pi*Sigma) - (1/(2*Sigma))*D; % det(sigma*I) = sigma^d
+  B2 = reshape(exp(logB2), [Q M T]);
+  clear logB2 % ATB: clear big old data
+  
+elseif ndims(Sigma)==2 % tied full
+  mu = reshape(mu, [d Q*M]);
+  D = sqdist(data, mu, inv(Sigma))';
+  % D(qm,t) = sq dist between data(:,t) and mu(:,qm)
+  logB2 = -(d/2)*log(2*pi) - 0.5*logdet(Sigma) - 0.5*D;
+  %denom = sqrt(det(2*pi*Sigma));
+  %numer = exp(-0.5 * D);
+  %B2 = numer/denom;
+  B2 = reshape(exp(logB2), [Q M T]);
+  
+elseif ndims(Sigma)==3 % tied across M
+  B2 = zeros(Q,M,T);
+  for j=1:Q
+    % D(m,t) = sq dist between data(:,t) and mu(:,j,m)
+    if isposdef(Sigma(:,:,j))
+      D = sqdist(data, permute(mu(:,j,:), [1 3 2]), inv(Sigma(:,:,j)))';
+      logB2 = -(d/2)*log(2*pi) - 0.5*logdet(Sigma(:,:,j)) - 0.5*D;
+      B2(j,:,:) = exp(logB2);
+    else
+      error(sprintf('mixgauss_prob: Sigma(:,:,q=%d) not psd\n', j));
+    end
+  end
+  
+else % general case
+  B2 = zeros(Q,M,T);
+  for j=1:Q
+    for k=1:M
+      %if mixmat(j,k) > 0
+      B2(j,k,:) = gaussian_prob(data, mu(:,j,k), Sigma(:,:,j,k));
+      %end
+    end
+  end
+end
+
+% B(j,t) = sum_k B2(j,k,t) * Pr(M(t)=k | Q(t)=j) 
+
+% The repmat is actually slower than the for-loop, because it uses too much memory
+% (this is true even for small T).
+
+%B = squeeze(sum(B2 .* repmat(mixmat, [1 1 T]), 2));
+%B = reshape(B, [Q T]); % undo effect of squeeze in case Q = 1
+  
+B = zeros(Q,T);
+if Q < T
+  for q=1:Q
+    %B(q,:) = mixmat(q,:) * squeeze(B2(q,:,:)); % squeeze chnages order if M=1
+    B(q,:) = mixmat(q,:) * permute(B2(q,:,:), [2 3 1]); % vector * matrix sums over m
+  end
+else
+  for t=1:T
+    B(:,t) = sum(mixmat .* B2(:,:,t), 2); % sum over m
+  end
+end
+%t=toc;fprintf('%5.3f\n', t)
+
+%tic
+%A = squeeze(sum(B2 .* repmat(mixmat, [1 1 T]), 2));
+%t=toc;fprintf('%5.3f\n', t)
+%assert(approxeq(A,B)) % may be false because of round off error
diff --git a/sourcecodes/bnt-master/KPMstats/mixgauss_prob_test.m b/sourcecodes/bnt-master/KPMstats/mixgauss_prob_test.m
new file mode 100644
index 00000000..a93eaf97
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/mixgauss_prob_test.m
@@ -0,0 +1,111 @@
+function test_eval_pdf_cond_mixgauss()
+
+%Q = 10; M = 100; d = 20; T = 500;
+Q = 2; M = 3; d = 4; T = 5;
+
+mu = rand(d,Q,M);
+data = randn(d,T);
+%mixmat = mk_stochastic(rand(Q,M));
+mixmat = mk_stochastic(ones(Q,M));
+
+% tied scalar
+Sigma = 0.01;
+
+mu = rand(d,M,Q);
+weights = mixmat';
+N = M*ones(1,Q);
+tic; [B, B2, D] = parzen(data, mu, Sigma, N, weights); toc
+tic; [BC, B2C, DC] = parzenC(data, mu, Sigma, N); toc
+approxeq(B,BC)
+B2C = reshape(B2C,[M Q T]);
+approxeq(B2,B2C)
+DC = reshape(DC,[M Q T]);
+approxeq(D,DC)
+
+
+return
+
+tic; [B, B2] = eval_pdf_cond_mixgauss(data, mu, Sigma, mixmat); toc
+tic; C = eval_pdf_cond_parzen(data, mu, Sigma); toc
+approxeq(B,C)
+
+return;
+
+
+mu = reshape(mu, [d Q*M]);
+
+data = mk_unit_norm(data);
+mu = mk_unit_norm(mu);
+tic; D = 2 -2*(data'*mu); toc % avoid an expensive repmat
+tic; D2 = sqdist(data, mu); toc
+approxeq(D,D2)
+
+
+% D(t,m) = sq dist between data(:,t) and mu(:,m)
+mu = reshape(mu, [d Q*M]);
+D = dist2(data', mu');
+%denom = (2*pi)^(d/2)*sqrt(abs(det(C)));
+denom = (2*pi*Sigma)^(d/2); % sqrt(det(2*pi*Sigma))
+numer = exp(-0.5/Sigma  * D');
+B2 = numer / denom;
+B2 = reshape(B2, [Q M T]);
+
+tic; B = squeeze(sum(B2 .* repmat(mixmat, [1 1 T]), 2)); toc
+
+tic
+A = zeros(Q,T);
+for q=1:Q
+  A(q,:) = mixmat(q,:) * squeeze(B2(q,:,:)); % sum over m
+end
+toc
+assert(approxeq(A,B))
+
+tic
+A = zeros(Q,T);
+for t=1:T
+  A(:,t) = sum(mixmat .* B2(:,:,t), 2); % sum over m
+end
+toc
+assert(approxeq(A,B))
+
+    
+
+
+mu = reshape(mu, [d Q M]);
+B3 = zeros(Q,M,T);
+for j=1:Q
+  for k=1:M
+    B3(j,k,:) = gaussian_prob(data, mu(:,j,k), Sigma*eye(d));
+  end
+end
+assert(approxeq(B2, B3))
+
+logB4 = -(d/2)*log(2*pi*Sigma) - (1/(2*Sigma))*D; % det(sigma*I) = sigma^d
+B4 = reshape(exp(logB4), [Q M T]);
+assert(approxeq(B4, B3))
+
+
+
+  
+% tied cov matrix
+
+Sigma = rand_psd(d,d);
+mu = reshape(mu, [d Q*M]);
+D = sqdist(data, mu, inv(Sigma))';
+denom = sqrt(det(2*pi*Sigma));
+numer = exp(-0.5 * D);
+B2 = numer / denom;
+B2 = reshape(B2, [Q M T]);
+
+mu = reshape(mu, [d Q M]);
+B3 = zeros(Q,M,T);
+for j=1:Q
+  for k=1:M
+    B3(j,k,:) = gaussian_prob(data, mu(:,j,k), Sigma);
+  end
+end
+assert(approxeq(B2, B3))
+
+logB4 = -(d/2)*log(2*pi) - 0.5*logdet(Sigma) - 0.5*D;
+B4 = reshape(exp(logB4), [Q M T]);
+assert(approxeq(B4, B3))
diff --git a/sourcecodes/bnt-master/KPMstats/mixgauss_sample.m b/sourcecodes/bnt-master/KPMstats/mixgauss_sample.m
new file mode 100644
index 00000000..9438d5f0
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/mixgauss_sample.m
@@ -0,0 +1,22 @@
+function [data, indices] = mixgauss_sample(mu, Sigma, mixweights, Nsamples)
+%  mixgauss_sample Sample data from a mixture of Gaussians
+% function [data, indices] = mixgauss_sample(mu, Sigma, mixweights, Nsamples)
+%
+% Model is P(X) = sum_k mixweights(k) N(X; mu(:,k), Sigma(:,:,k)) or Sigma(k) for scalar
+% data(:,i) is the i'th sample from P(X)
+% indices(i) is the component from which sample i was drawn
+
+[D K] = size(mu);
+data = zeros(D, Nsamples);
+indices = sample_discrete(mixweights, 1, Nsamples);
+for k=1:K
+  if ndims(Sigma) < 3
+    sig = Sigma(k);
+  else
+    sig = Sigma(:,:,k);
+  end
+  ndx = find(indices==k);
+  if length(ndx) > 0
+    data(:,ndx) = sample_gaussian(mu(:,k), sig, length(ndx))';
+  end
+end
diff --git a/sourcecodes/bnt-master/KPMstats/mkPolyFvec.m b/sourcecodes/bnt-master/KPMstats/mkPolyFvec.m
new file mode 100644
index 00000000..0ddbb259
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/mkPolyFvec.m
@@ -0,0 +1,24 @@
+function p = mkPolyFvec(x)
+% MKPOLYFVEC Make feature vector by constructing 2nd order polynomial from input data
+% function p = mkPolyFvec(x)
+%
+% x(:,i) for example i
+% p(:,i) = [x(1,i) x(2,i) x(3,i) x(1,i)^2 x(2,i)^2 x(3,i)^2 ..
+%           x(1,i)*x(2,i) x(1,i)*x(3,i) x(2,i)*x(3,i)]'
+%
+% Example
+% x = [4 5 6]'
+% p = [4 5 6  16 25 36  20 24 30]'
+
+fvec = x;
+fvecSq = x.*x;
+[D N] = size(x);
+fvecCross = zeros(D*(D-1)/2, N);
+i = 1;
+for d=1:D
+  for d2=d+1:D
+    fvecCross(i,:) = x(d,:) .* x(d2,:);
+    i = i + 1;
+  end
+end
+p = [fvec; fvecSq; fvecCross];
diff --git a/sourcecodes/bnt-master/KPMstats/mk_unit_norm.m b/sourcecodes/bnt-master/KPMstats/mk_unit_norm.m
new file mode 100644
index 00000000..99c150a1
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/mk_unit_norm.m
@@ -0,0 +1,13 @@
+function B = mk_unit_norm(A)
+% MK_UNIT_NORM Make each column be a unit norm vector
+% function B = mk_unit_norm(A)
+% 
+% We divide each column by its magnitude
+
+
+[nrows ncols] = size(A);
+s = sum(A.^2);
+ndx = find(s==0);
+s(ndx)=1; 
+B = A ./ repmat(sqrt(s), [nrows 1]);
+
diff --git a/sourcecodes/bnt-master/KPMstats/multinomial_prob.m b/sourcecodes/bnt-master/KPMstats/multinomial_prob.m
new file mode 100644
index 00000000..460ec782
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/multinomial_prob.m
@@ -0,0 +1,20 @@
+function B = eval_pdf_cond_multinomial(data, obsmat)
+% EVAL_PDF_COND_MULTINOMIAL Evaluate pdf of conditional multinomial 
+% function B = eval_pdf_cond_multinomial(data, obsmat)
+%
+% Notation: Y = observation (O values), Q = conditioning variable (K values)
+%
+% Inputs:
+% data(t) = t'th observation - must be an integer in {1,2,...,K}: cannot be 0!
+% obsmat(i,o) = Pr(Y(t)=o | Q(t)=i)
+%
+% Output:
+% B(i,t) = Pr(y(t) | Q(t)=i)
+
+[Q O] = size(obsmat);
+T = prod(size(data)); % length(data);
+B = zeros(Q,T);
+
+for t=1:T
+  B(:,t) = obsmat(:, data(t));
+end
diff --git a/sourcecodes/bnt-master/KPMstats/multinomial_sample.m b/sourcecodes/bnt-master/KPMstats/multinomial_sample.m
new file mode 100644
index 00000000..9c8d0cda
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/multinomial_sample.m
@@ -0,0 +1,22 @@
+function Y = sample_cond_multinomial(X, M)
+% SAMPLE_MULTINOMIAL Sample Y(i) ~ M(X(i), :)
+% function Y = sample_multinomial(X, M)
+%
+% X(i) = i'th sample
+% M(i,j) = P(Y=j | X=i) = noisy channel model
+%
+% e.g., if X is a binary image,
+% Y = sample_multinomial(softeye(2, 0.9), X)
+% will create a noisy version of X, where bits are flipped with probability 0.1
+
+if any(X(:)==0)
+  error('data must only contain positive integers')
+end
+
+Y = zeros(size(X));
+for i=min(X(:)):max(X(:))
+  ndx = find(X==i);
+  Y(ndx) = sample_discrete(M(i,:), length(ndx), 1);
+end
+
+
diff --git a/sourcecodes/bnt-master/KPMstats/multipdf.m b/sourcecodes/bnt-master/KPMstats/multipdf.m
new file mode 100644
index 00000000..592d0004
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/multipdf.m
@@ -0,0 +1,45 @@
+function p = multipdf(x,theta)
+%MULTIPDF Multinomial probability density function.
+%   p = multipdf(x,theta) returns the probabilities of 
+%   vector x, under the multinomial distribution
+%   with parameter vector theta.
+%
+%   Author: David Ross
+
+%--------------------------------------------------------
+% Check the arguments.
+%--------------------------------------------------------
+error(nargchk(2,2,nargin));
+
+% make sure theta is a vector
+if ndims(theta) > 2 | all(size(theta) > 1)
+    error('theta must be a vector');
+end
+
+% make sure x is of the appropriate size
+if ndims(x) > 2 | any(size(x) ~= size(theta))
+    error('columns of X must have same length as theta');
+end
+
+
+%--------------------------------------------------------
+% Main...
+%--------------------------------------------------------
+p = prod(theta .^ x);
+p = p .* factorial(sum(x)) ./ prod(factorial_v(x));
+
+
+%--------------------------------------------------------
+% Function factorial_v(x): computes the factorial function
+% on each element of x
+%--------------------------------------------------------
+function r = factorial_v(x)
+
+if size(x,2) == 1
+    x = x';
+end
+
+r = [];
+for y = x
+    r = [r factorial(y)];
+end
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/KPMstats/multirnd.m b/sourcecodes/bnt-master/KPMstats/multirnd.m
new file mode 100644
index 00000000..ba23f6fe
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/multirnd.m
@@ -0,0 +1,48 @@
+function r = multirnd(theta,k)
+%MULTIRND - Random vector from multinomial distribution.
+%   r = multirnd(theta,k) returns a vector randomly selected
+%   from the multinomial distribution with parameter vector
+%   theta, and count k (i.e. sum(r) = k).
+%
+%   Note: if k is unspecified, then it is assumed k=1.
+%
+%   Author: David Ross
+%
+
+%--------------------------------------------------------
+% Check the arguments.
+%--------------------------------------------------------
+error(nargchk(1,2,nargin));
+
+% make sure theta is a vector
+if ndims(theta) > 2 | all(size(theta) > 1)
+    error('theta must be a vector');
+end
+
+% if theta is a row vector, convert it to a column vector
+if size(theta,1) == 1
+    theta = theta';
+end
+
+% make sure k is a scalar?
+
+% if the number of samples has not been provided, set
+% it to one
+if nargin == 1
+    k = 1;
+end
+
+
+%--------------------------------------------------------
+% Main...
+%--------------------------------------------------------
+n = length(theta);
+theta_cdf = cumsum(theta);
+
+r = zeros(n,1);
+random_vals = rand(k,1);
+
+for j = 1:k
+    index = min(find(random_vals(j) <= theta_cdf));
+    r(index) = r(index) + 1;
+end
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/KPMstats/normal_coef.m b/sourcecodes/bnt-master/KPMstats/normal_coef.m
new file mode 100644
index 00000000..a185491e
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/normal_coef.m
@@ -0,0 +1,7 @@
+function c = normal_coef (Sigma)
+% NORMAL_COEF Compute the normalizing coefficient for a multivariate gaussian.
+% c = normal_coef (Sigma)
+
+n = length(Sigma);
+c = (2*pi)^(-n/2) * det(Sigma)^(-0.5);
+
diff --git a/sourcecodes/bnt-master/KPMstats/partial_corr_coef.m b/sourcecodes/bnt-master/KPMstats/partial_corr_coef.m
new file mode 100644
index 00000000..a27d0fb9
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/partial_corr_coef.m
@@ -0,0 +1,28 @@
+function [r, c] = partial_corr_coef(S, i, j, Y)
+% PARTIAL_CORR_COEF Compute a partial correlation coefficient
+% [r, c] = partial_corr_coef(S, i, j, Y)
+%
+% S is the covariance (or correlation) matrix for X, Y, Z
+% where X=[i j], Y is conditioned on, and Z is marginalized out.
+% Let S2 = Cov[X | Y] be the partial covariance matrix.
+% Then c = S2(i,j) and r = c / sqrt( S2(i,i) * S2(j,j) ) 
+%
+
+% Example: Anderson (1984) p129
+% S = [1.0 0.8 -0.4;
+%     0.8 1.0 -0.56;
+%     -0.4 -0.56 1.0];
+% r(1,3 | 2) = 0.0966 
+%
+% Example: Van de Geer (1971) p111
+%S = [1     0.453 0.322;
+%     0.453 1.0   0.596;
+%     0.322 0.596 1];
+% r(2,3 | 1) = 0.533
+
+X = [i j];
+i2 = 1; % find_equiv_posns(i, X);
+j2 = 2; % find_equiv_posns(j, X);
+S2 = S(X,X) - S(X,Y)*inv(S(Y,Y))*S(Y,X);
+c = S2(i2,j2);
+r = c / sqrt(S2(i2,i2) * S2(j2,j2));
diff --git a/sourcecodes/bnt-master/KPMstats/parzen.m b/sourcecodes/bnt-master/KPMstats/parzen.m
new file mode 100644
index 00000000..27a92783
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/parzen.m
@@ -0,0 +1,88 @@
+function [B,B2,dist] = parzen(data, mu, Sigma, N)
+% EVAL_PDF_COND_PARZEN Evaluate the pdf of a conditional Parzen window
+% function B = eval_pdf_cond_parzen(data, mu, Sigma, N)
+%
+% B(q,t) = Pr(data(:,t) | Q=q) = sum_{m=1}^{N(q)} w(m,q)*K(data(:,t) - mu(:,m,q); sigma)
+% where K() is a Gaussian kernel with spherical variance sigma,
+% and w(m,q) = 1/N(q) if m<=N(q) and = 0 otherwise
+% where N(q) is the number of mxiture components for q 
+%
+% B2(m,q,t) =  K(data(:,t) - mu(:,m,q); sigma) for m=1:max(N)
+
+% This is like eval_pdf_cond_parzen, except mu is mu(:,m,q) instead of mu(:,q,m)
+% and we use 1/N(q) instead of mixmat(q,m)
+
+if nargout >= 2
+  keep_B2 = 1;
+else
+  keep_B2 = 0;
+end
+
+if nargout >= 3
+  keep_dist = 1;
+else
+  keep_dist = 0;
+end
+
+[d M Q] = size(mu);
+[d T] = size(data);
+
+M = max(N(:));
+
+B = zeros(Q,T);
+const1 = (2*pi*Sigma)^(-d/2);
+const2 = -(1/(2*Sigma));
+if T*Q*M>20000000 % not enough memory to call sqdist
+  disp('eval parzen for loop')
+  if keep_dist,
+    dist = zeros(M,Q,T);
+  end
+  if keep_B2
+    B2 = zeros(M,Q,T);
+  end
+  for q=1:Q
+    D = sqdist(mu(:,1:N(q),q), data); % D(m,t)
+    if keep_dist
+      dist(:,q,:) = D;
+    end
+    tmp = const1 * exp(const2*D);
+    if keep_B2,
+      B2(:,q,:) = tmp;
+    end
+    if N(q) > 0
+      %B(q,:) = (1/N(q)) * const1 * sum(exp(const2*D), 2);
+      B(q,:) = (1/N(q)) * sum(tmp,1);
+    end
+  end
+else
+  %disp('eval parzen vectorized')
+  dist = sqdist(reshape(mu(:,1:M,:), [d M*Q]), data); % D(mq,t)
+  dist = reshape(dist, [M Q T]);
+  B2 = const1 * exp(const2*dist); % B2(m,q,t)
+  if ~keep_dist
+    clear dist
+  end
+  
+  % weights(m,q) is the weight of mixture component m for q  
+  %    = 1/N(q) if m<=N(q) and = 0 otherwise
+  % e.g., N = [2   3   1], M = 3,
+  % weights = [1/2 1/3 1   = 1/2 1/3 1/1      2 3 1     1 1 1
+  %            1/2 1/3 0     1/2 1/3 1/1 .*   2 3 1 <=  2 2 2
+  %            0   1/3 0]    1/2 1/3 1/1      2 3 1     3 3 3
+   
+  Ns = repmat(N(:)', [M 1]);
+  ramp = 1:M;
+  ramp = repmat(ramp(:), [1 Q]);
+  n = N + (N==0); % avoid 1/0 by replacing with 0* 1/1m where 0 comes from mask
+  N1 = repmat(1 ./ n(:)', [M 1]);
+  mask = (ramp <= Ns);
+  weights = N1 .* mask;
+  B2 = B2 .* repmat(mask, [1 1 T]);
+  
+  % B(q,t) = sum_m B2(m,q,t) * P(m|q) = sum_m B2(m,q,t) * weights(m,q)
+  B = squeeze(sum(B2 .* repmat(weights, [1 1 T]), 1)); 
+  B = reshape(B, [Q T]); % undo effect of squeeze in case Q = 1
+end
+
+  
+
diff --git a/sourcecodes/bnt-master/KPMstats/parzenC.c b/sourcecodes/bnt-master/KPMstats/parzenC.c
new file mode 100644
index 00000000..8fb07f1d
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/parzenC.c
@@ -0,0 +1,116 @@
+/* C mex version of parzen.m
+[B,B2] = parzen(feat, mu,  Sigma, Nproto); 
+*/
+#include "mex.h"
+#include <stdio.h>
+#include <math.h>
+
+#define PI 3.141592654
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
+  int    D, M, Q, T, d, m, q, t;
+  double *data, *mu, *SigmaPtr, *N, Sigma;
+  double *B, *dist, *B2, tmp;
+  const int* dim_mu;
+  double const1, const2, sum_m, sum_d, diff;
+  int Dt, DMq, Dm, MQt, Mq;
+  int dims_B2[3];
+
+  int ndim_mu, i, save_B2;
+  
+  data = mxGetPr(prhs[0]);
+  mu = mxGetPr(prhs[1]);
+  SigmaPtr = mxGetPr(prhs[2]);
+  Sigma = *SigmaPtr;
+  N = mxGetPr(prhs[3]);
+  
+  D = mxGetM(prhs[0]);
+  T = mxGetN(prhs[0]);
+
+  ndim_mu = mxGetNumberOfDimensions(prhs[1]);
+  dim_mu = mxGetDimensions(prhs[1]);
+  D = dim_mu[0];
+  M = dim_mu[1];
+  /* printf("parzenC: nlhs=%d, D=%d, M=%d, T=%d\n", nlhs, D, M, T);  */
+
+  /* If mu is mu(d,m,o,p), then [d M Q] = size(mu) in matlab sets Q=o*p,
+     i.e.. the size of all conditioning variabeles */
+  Q = 1;
+  for (i = 2; i < ndim_mu; i++) {
+    /* printf("dim_mu[%d]=%d\n", i, dim_mu[i]); */
+    Q = Q*dim_mu[i];
+  }
+
+  /* M = max(N) */
+  M = -1000000;
+  for (i=0; i < Q; i++) {
+    /* printf("N[%d]=%d\n", i, (int) N[i]); */
+    if (N[i] > M) {
+      M = (int) N[i];
+    }
+  }
+
+  /*  printf("parzenC: nlhs=%d, D=%d, Q=%d, M=%d, T=%d\n", nlhs, D, Q, M, T); */
+
+  plhs[0] = mxCreateDoubleMatrix(Q,T, mxREAL);
+  B = mxGetPr(plhs[0]);
+
+  if (nlhs >= 2)
+    save_B2 = 1;
+  else
+    save_B2 = 0;
+  
+  if (save_B2) {
+    /* printf("parzenC saving B2\n");  */
+    /*plhs[1] = mxCreateDoubleMatrix(M*Q*T,1, mxREAL);*/
+    dims_B2[0] = M;
+    dims_B2[1] = Q;
+    dims_B2[2] = T;
+    plhs[1] = mxCreateNumericArray(3, dims_B2, mxDOUBLE_CLASS, mxREAL);
+    B2 = mxGetPr(plhs[1]);
+  } else {
+    /* printf("parzenC not saving B2\n"); */
+  }
+  /*
+  plhs[2] = mxCreateDoubleMatrix(M*Q*T,1, mxREAL);
+  dist = mxGetPr(plhs[2]);
+  */
+  const1 = pow(2*PI*Sigma, -D/2.0);
+  const2 = -(1/(2*Sigma));
+ 
+  for (t=0; t < T; t++) {
+    /* printf("t=%d!\n",t); */
+    Dt  = D*t;
+    MQt = M*Q*t;
+    for (q=0; q < Q; q++) {
+      sum_m = 0;
+      DMq = D*M*q;
+      Mq = M*q;
+
+      for (m=0; m < (int)N[q]; m++) {
+	sum_d = 0;
+	Dm = D*m;
+	for (d=0; d < D; d++) {
+	  /* diff = data(d,t) - mu(d,m,q) */
+	  /*diff = data[d + D*t] - mu[d + D*m + D*M*q]; */
+	  diff = data[d + Dt] - mu[d + Dm + DMq];
+	  sum_d = sum_d + diff*diff;
+	}
+	/* dist[m,q,t] = dist[m + M*q + M*Q*t] = dist[m + Mq + MQt] = sum_d */
+	tmp = const1 * exp(const2*sum_d);
+	sum_m = sum_m + tmp;
+	if (save_B2)
+	  B2[m + Mq + MQt] = tmp;
+      }
+
+      if (N[q]>0) {
+	B[q + Q*t] = (1.0/N[q]) *  sum_m;
+      } else {
+	B[q + Q*t] = 0.0;
+      }
+    }
+  }
+}
+
+
+
diff --git a/sourcecodes/bnt-master/KPMstats/parzenC.dll b/sourcecodes/bnt-master/KPMstats/parzenC.dll
new file mode 100644
index 00000000..0700d413
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/parzenC.dll
Binary files differdiff --git a/sourcecodes/bnt-master/KPMstats/parzenC_test.m b/sourcecodes/bnt-master/KPMstats/parzenC_test.m
new file mode 100644
index 00000000..53a79681
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/parzenC_test.m
@@ -0,0 +1,10 @@
+d = 2; M = 3; Q = 4; T = 5; Sigma = 10;
+N = sample_discrete(normalize(ones(1,M)), 1, Q);
+data = randn(d,T);
+mu = randn(d,M,Q);
+
+[BM, B2M] = parzen(data, mu, Sigma, N);
+[B, B2] = parzenC(data, mu, Sigma, N);
+
+approxeq(B,BM)
+approxeq(B2,B2M)
diff --git a/sourcecodes/bnt-master/KPMstats/parzen_fit_select_unif.m b/sourcecodes/bnt-master/KPMstats/parzen_fit_select_unif.m
new file mode 100644
index 00000000..a9718475
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/parzen_fit_select_unif.m
@@ -0,0 +1,45 @@
+function [mu, N, pick] = parzen_fit_select_unif(data, labels, max_proto, varargin)
+% PARZEN_FIT_SELECT_UNIF Fit a parzen density estimator by selecting prototypes uniformly from data
+% [mu, N, pick] = parzen_fit_select_unif(data, max_proto, labels, ...)
+%
+% We partition the data into different subsets based on the labels.
+% We then choose up to max_proto columns from each subset, chosen uniformly.
+%
+% INPUTS
+% data(:,t)
+% labels(t) - should be in {1,2,..,Q}
+% max_proto - max number of prototypes per partition
+%
+% Optional args
+% partition_names{m} - for debugging
+% boundary - do not choose prototypes which are within 'boundary' of the label transition
+%
+% OUTPUTS
+% mu(:, m, q) for label q, prototype m for 1 <= m <= N(q)
+% N(q) = number of prototypes for label q
+% pick{q} = identity of the prototypes
+
+nclasses = max(labels);
+[boundary, partition_names] = process_options(...
+    varargin, 'boundary', 0, 'partition_names', []);
+
+[D T] = size(data);
+mu = zeros(D, 1, nclasses); % dynamically determine num prototypes (may be less than K)
+mean_feat = mean(data,2);
+pick = cell(1,nclasses);
+for c=1:nclasses
+  ndx = find(labels==c);
+  if isempty(ndx)
+    %fprintf('no training images have label %d (%s)\n', c, partition_names{c})
+    fprintf('no training images have label %d\n', c);
+    nviews = 1;
+    mu(:,1,c) = mean_feat;
+  else
+    foo = linspace(boundary+1, length(ndx-boundary), max_proto);
+    pick{c} = ndx(unique(floor(foo)));
+    nviews = length(pick{c});
+    %fprintf('picking %d views for class %d=%s\n', nviews, c, class_names{c});
+    mu(:,1:nviews,c) = data(:, pick{c});
+  end
+  N(c) = nviews;
+end
diff --git a/sourcecodes/bnt-master/KPMstats/pca.m b/sourcecodes/bnt-master/KPMstats/pca.m
new file mode 100644
index 00000000..4b7063d6
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/pca.m
@@ -0,0 +1,42 @@
+function [PCcoeff, PCvec] = pca(data, N)
+%PCA	Principal Components Analysis
+%
+%	Description
+%	 PCCOEFF = PCA(DATA) computes the eigenvalues of the covariance
+%	matrix of the dataset DATA and returns them as PCCOEFF.  These
+%	coefficients give the variance of DATA along the corresponding
+%	principal components.
+%
+%	PCCOEFF = PCA(DATA, N) returns the largest N eigenvalues.
+%
+%	[PCCOEFF, PCVEC] = PCA(DATA) returns the principal components as well
+%	as the coefficients.  This is considerably more computationally
+%	demanding than just computing the eigenvalues.
+%
+%	See also
+%	EIGDEC, GTMINIT, PPCA
+%
+
+%	Copyright (c) Ian T Nabney (1996-2001)
+
+if nargin == 1
+   N = size(data, 2);
+end
+
+if nargout == 1
+   evals_only = logical(1);
+else
+   evals_only = logical(0);
+end
+
+if N ~= round(N) | N < 1 | N > size(data, 2)
+   error('Number of PCs must be integer, >0, < dim');
+end
+
+% Find the sorted eigenvalues of the data covariance matrix
+if evals_only
+   PCcoeff = eigdec(cov(data), N);
+else
+  [PCcoeff, PCvec] = eigdec(cov(data), N);
+end
+
diff --git a/sourcecodes/bnt-master/KPMstats/rndcheck.m b/sourcecodes/bnt-master/KPMstats/rndcheck.m
new file mode 100644
index 00000000..21432bb2
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/rndcheck.m
@@ -0,0 +1,294 @@
+function [errorcode, rows, columns] = rndcheck(nargs,nparms,arg1,arg2,arg3,arg4,arg5)
+%RNDCHECK error checks the argument list for the random number generators.
+
+%   B.A. Jones  1-22-93
+%   Copyright (c) 1993-98 by The MathWorks, Inc.
+%   $Revision: 1.1.1.1 $  $Date: 2005/04/26 02:29:22 $
+
+sizeinfo = nargs - nparms;
+errorcode = 0;
+
+if nparms == 3
+    [r1 c1] = size(arg1);
+    [r2 c2] = size(arg2);
+    [r3 c3] = size(arg3);
+end
+
+if nparms == 2
+    [r1 c1] = size(arg1);
+    [r2 c2] = size(arg2);
+end 
+
+if sizeinfo == 0        
+    if nparms == 1
+        [rows columns] = size(arg1);
+    end
+    
+    if nparms == 2
+        scalararg1 = (prod(size(arg1)) == 1);
+        scalararg2 = (prod(size(arg2)) == 1);
+        if ~scalararg1 & ~scalararg2
+            if r1 ~= r2 | c1 ~= c2
+                errorcode = 1;
+                return;         
+            end
+        end
+        if ~scalararg1
+            [rows columns] = size(arg1);
+        elseif ~scalararg2
+            [rows columns] = size(arg2);
+        else
+            [rows columns] = size(arg1);
+        end
+    end
+    
+    if nparms == 3
+        scalararg1 = (prod(size(arg1)) == 1);
+        scalararg2 = (prod(size(arg2)) == 1);
+        scalararg3 = (prod(size(arg3)) == 1);
+
+        if ~scalararg1 & ~scalararg2
+            if r1 ~= r2 | c1 ~= c2
+                errorcode = 1;
+                return;         
+            end
+        end
+
+        if ~scalararg1 & ~scalararg3
+            if r1 ~= r3 | c1 ~= c3
+                errorcode = 1;
+                return;                 
+            end
+        end
+
+        if ~scalararg3 & ~scalararg2
+            if r3 ~= r2 | c3 ~= c2
+                errorcode = 1;
+                return;         
+            end
+        end
+            if ~scalararg1
+                [rows columns] = size(arg1);
+            elseif ~scalararg2
+            [rows columns] = size(arg2);
+            else
+                [rows columns] = size(arg3);
+            end
+    end 
+end
+
+if sizeinfo == 1
+    scalararg1 = (prod(size(arg1)) == 1);
+    if nparms == 1
+        if prod(size(arg2)) ~= 2
+            errorcode = 2;
+            return;
+        end
+        if  ~scalararg1 & arg2 ~= size(arg1)
+            errorcode = 3;
+            return;
+        end
+        if (arg2(1) < 0 | arg2(2) < 0 | arg2(1) ~= round(arg2(1)) | arg2(2) ~= round(arg2(2))),
+            errorcode = 4;
+            return;
+        end 
+        rows    = arg2(1);
+        columns = arg2(2);
+    end
+    
+    if nparms == 2
+        if prod(size(arg3)) ~= 2
+            errorcode = 2;
+            return;
+        end
+        scalararg2 = (prod(size(arg2)) == 1);
+        if ~scalararg1 & ~scalararg2
+            if r1 ~= r2 | c1 ~= c2
+                errorcode = 1;
+                return;         
+            end
+        end
+        if (arg3(1) < 0 | arg3(2) < 0 | arg3(1) ~= round(arg3(1)) | arg3(2) ~= round(arg3(2))),
+            errorcode = 4;
+            return;
+        end 
+        if ~scalararg1
+            if any(arg3 ~= size(arg1))
+                errorcode = 3;
+                return;
+            end
+            [rows columns] = size(arg1);
+        elseif ~scalararg2
+            if any(arg3 ~= size(arg2))
+                errorcode = 3;
+                return;
+            end
+            [rows columns] = size(arg2);
+        else
+            rows    = arg3(1);
+            columns = arg3(2);
+        end
+    end
+    
+    if nparms == 3
+        if prod(size(arg4)) ~= 2
+            errorcode = 2;
+            return;
+        end
+        scalararg1 = (prod(size(arg1)) == 1);
+        scalararg2 = (prod(size(arg2)) == 1);
+        scalararg3 = (prod(size(arg3)) == 1);
+
+        if (arg4(1) < 0 | arg4(2) < 0 | arg4(1) ~= round(arg4(1)) | arg4(2) ~= round(arg4(2))),
+            errorcode = 4;
+            return;
+        end 
+
+        if ~scalararg1 & ~scalararg2
+            if r1 ~= r2 | c1 ~= c2
+                errorcode = 1;
+                return;         
+            end
+        end
+
+        if ~scalararg1 & ~scalararg3
+            if r1 ~= r3 | c1 ~= c3
+                errorcode = 1;
+                return;                 
+            end
+        end
+
+        if ~scalararg3 & ~scalararg2
+            if r3 ~= r2 | c3 ~= c2
+                errorcode = 1;
+                return;         
+            end
+        end
+        if ~scalararg1
+            if any(arg4 ~= size(arg1))
+                errorcode = 3;
+                return;
+            end
+            [rows columns] = size(arg1);
+        elseif ~scalararg2
+            if any(arg4 ~= size(arg2))
+                errorcode = 3;
+                return;
+            end
+            [rows columns] = size(arg2);
+        elseif ~scalararg3
+            if any(arg4 ~= size(arg3))
+                errorcode = 3;
+                return;
+            end
+            [rows columns] = size(arg3);
+        else
+            rows    = arg4(1);
+            columns = arg4(2);
+        end
+    end 
+end
+
+if sizeinfo == 2
+    if nparms == 1
+        scalararg1 = (prod(size(arg1)) == 1);
+        if ~scalararg1
+            [rows columns] = size(arg1);
+            if rows ~= arg2 | columns ~= arg3 
+                errorcode = 3;
+                return;
+            end
+        end
+    if (arg2 < 0 | arg3 < 0 | arg2 ~= round(arg2) | arg3 ~= round(arg3)),
+        errorcode = 4;
+        return;
+    end 
+        rows = arg2;
+        columns = arg3;
+    end
+    
+    if nparms == 2
+        scalararg1 = (prod(size(arg1)) == 1);
+        scalararg2 = (prod(size(arg2)) == 1);
+        if ~scalararg1 & ~scalararg2
+            if r1 ~= r2 | c1 ~= c2
+                errorcode = 1;
+                return;         
+            end
+        end
+        if ~scalararg1
+            [rows columns] = size(arg1);
+            if rows ~= arg3 | columns ~= arg4 
+                errorcode = 3;
+                return;
+            end     
+        elseif ~scalararg2
+            [rows columns] = size(arg2);
+            if rows ~= arg3 | columns ~= arg4 
+                errorcode = 3;
+                return;
+            end     
+        else
+            if (arg3 < 0 | arg4 < 0 | arg3 ~= round(arg3) | arg4 ~= round(arg4)),
+                errorcode = 4;
+                return;
+            end 
+            rows = arg3;
+            columns = arg4;
+        end
+    end
+    
+    if nparms == 3
+        scalararg1 = (prod(size(arg1)) == 1);
+        scalararg2 = (prod(size(arg2)) == 1);
+        scalararg3 = (prod(size(arg3)) == 1);
+
+        if ~scalararg1 & ~scalararg2
+            if r1 ~= r2 | c1 ~= c2
+                errorcode = 1;
+                return;         
+            end
+        end
+
+        if ~scalararg1 & ~scalararg3
+            if r1 ~= r3 | c1 ~= c3
+                errorcode = 1;
+                return;                 
+            end
+        end
+
+        if ~scalararg3 & ~scalararg2
+            if r3 ~= r2 | c3 ~= c2
+                errorcode = 1;
+                return;         
+            end
+        end
+        
+        if ~scalararg1
+            [rows columns] = size(arg1);
+            if rows ~= arg4 | columns ~= arg5 
+                errorcode = 3;
+                return;
+            end     
+        elseif ~scalararg2
+            [rows columns] = size(arg2);
+            if rows ~= arg4 | columns ~= arg5 
+                errorcode = 3;
+                return;
+            end
+        elseif ~scalararg3
+            [rows columns] = size(arg3);
+            if rows ~= arg4 | columns ~= arg5 
+                errorcode = 3;
+                return;
+            end     
+        else
+            if (arg4 < 0 | arg5 < 0 | arg4 ~= round(arg4) | arg5 ~= round(arg5)),
+                errorcode = 4;
+                return;
+            end 
+            rows    = arg4;
+            columns = arg5;
+        end
+    end 
+end
diff --git a/sourcecodes/bnt-master/KPMstats/sample.m b/sourcecodes/bnt-master/KPMstats/sample.m
new file mode 100644
index 00000000..fc252da2
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/sample.m
@@ -0,0 +1,15 @@
+function x = sample(p, n)
+% SAMPLE    Sample from categorical distribution.
+% Returns a row vector of integers, sampled according to the probability
+% distribution p.
+% Uses the stick-breaking algorithm.
+% Much faster algorithms are also possible.
+
+if nargin < 2
+  n = 1;
+end
+
+cdf = cumsum(p(:));
+for i = 1:n
+  x(i) = sum(cdf < rand) + 1;
+end
diff --git a/sourcecodes/bnt-master/KPMstats/sample_discrete.m b/sourcecodes/bnt-master/KPMstats/sample_discrete.m
new file mode 100644
index 00000000..d8f6b687
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/sample_discrete.m
@@ -0,0 +1,40 @@
+function M = sample_discrete(prob, r, c)
+% SAMPLE_DISCRETE Like the built in 'rand', except we draw from a non-uniform discrete distrib.
+% M = sample_discrete(prob, r, c)
+%
+% Example: sample_discrete([0.8 0.2], 1, 10) generates a row vector of 10 random integers from {1,2},
+% where the prob. of being 1 is 0.8 and the prob of being 2 is 0.2.
+
+n = length(prob);
+
+if nargin == 1
+  r = 1; c = 1;
+elseif nargin == 2
+  c == r;
+end
+
+R = rand(r, c);
+M = ones(r, c);
+cumprob = cumsum(prob(:));
+
+if n < r*c
+  for i = 1:n-1
+    M = M + (R > cumprob(i));
+  end
+else
+  % loop over the smaller index - can be much faster if length(prob) >> r*c
+  cumprob2 = cumprob(1:end-1);
+  for i=1:r
+    for j=1:c
+      M(i,j) = sum(R(i,j) > cumprob2)+1;
+    end
+  end
+end
+
+
+% Slower, even though vectorized
+%cumprob = reshape(cumsum([0 prob(1:end-1)]), [1 1 n]);
+%M = sum(R(:,:,ones(n,1)) > cumprob(ones(r,1),ones(c,1),:), 3);
+
+% convert using a binning algorithm
+%M=bindex(R,cumprob);
diff --git a/sourcecodes/bnt-master/KPMstats/sample_gaussian.m b/sourcecodes/bnt-master/KPMstats/sample_gaussian.m
new file mode 100644
index 00000000..dbba6887
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/sample_gaussian.m
@@ -0,0 +1,19 @@
+function M = sample_gaussian(mu, Sigma, N)
+% SAMPLE_GAUSSIAN Draw N random row vectors from a Gaussian distribution
+% samples = sample_gaussian(mean, cov, N)
+
+if nargin==2
+  N = 1;
+end
+
+% If Y = CX, Var(Y) = C Var(X) C'.
+% So if Var(X)=I, and we want Var(Y)=Sigma, we need to find C. s.t. Sigma = C C'.
+% Since Sigma is psd, we have Sigma = U D U' = (U D^0.5) (D'^0.5 U').
+
+mu = mu(:);
+n=length(mu);
+[U,D,V] = svd(Sigma);
+M = randn(n,N);
+M = (U*sqrt(D))*M + mu*ones(1,N); % transform each column
+M = M';
+
diff --git a/sourcecodes/bnt-master/KPMstats/standardize.m b/sourcecodes/bnt-master/KPMstats/standardize.m
new file mode 100644
index 00000000..18c17ec3
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/standardize.m
@@ -0,0 +1,18 @@
+function [S, mu, sigma2] = standardize(M, mu, sigma2)
+% function S = standardize(M, mu, sigma2)
+% Make each column of M be zero mean, std 1.
+% Thus each row is scaled separately.
+%
+% If mu, sigma2 are omitted, they are computed from M
+
+M = double(M);
+if nargin < 2
+  mu = mean(M,2);
+  sigma2 = std(M,0,2);
+  sigma2 = sigma2 + eps*(sigma2==0);
+end
+
+[nrows ncols] = size(M);
+S = M - repmat(mu(:), [1 ncols]);
+S = S ./ repmat(sigma2, [1 ncols]);
+
diff --git a/sourcecodes/bnt-master/KPMstats/student_t_logprob.m b/sourcecodes/bnt-master/KPMstats/student_t_logprob.m
new file mode 100644
index 00000000..0aea837e
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/student_t_logprob.m
@@ -0,0 +1,13 @@
+function L = log_student_pdf(X, mu, lambda, alpha)
+% LOG_STUDENT_PDF Evaluate the log of the multivariate student-t distribution at a point
+% L = log_student_pdf(X, mu, lambda, alpha)
+%
+% Each column of X is evaluated.
+% See Bernardo and Smith p435.
+
+k = length(mu);
+assert(size(X,1) == k);
+[k N] = size(X);
+logc = gammaln(0.5*(alpha+k)) - gammaln(0.5*alpha) - (k/2)*log(alpha*pi) + 0.5*log(det(lambda));
+middle = (1 + (1/alpha)*(X-mu)'*lambda*(X-mu)); % scalar version
+L = logc - ((alpha+k)/2)*log(middle);
diff --git a/sourcecodes/bnt-master/KPMstats/student_t_prob.m b/sourcecodes/bnt-master/KPMstats/student_t_prob.m
new file mode 100644
index 00000000..8ec32a4c
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/student_t_prob.m
@@ -0,0 +1,19 @@
+function p = student_t_pdf(X, mu, lambda, alpha)
+% STUDENT_T_PDF Evaluate the multivariate student-t distribution at a point
+% p = student_t_pdf(X, mu, lambda, alpha)
+%
+% Each column of X is evaluated.
+% See Bernardo and Smith p435.
+
+k = length(mu);
+assert(size(X,1) == k);
+[k N] = size(X);
+numer = gamma(0.5*(alpha+k));
+denom = gamma(0.5*alpha) * (alpha*pi)^(k/2);
+c = (numer/denom) * det(lambda)^(0.5);
+p = c*(1 + (1/alpha)*(X-mu)'*lambda*(X-mu))^(-(alpha+k)/2); % scalar version
+%m = repmat(mu(:), 1, N);
+%exponent = sum((X-m)'*lambda*(X-m), 2); % column vector
+%p = c*(1 + (1/alpha)*exponent).^(-(alpha+k)/2);
+
+keyboard
diff --git a/sourcecodes/bnt-master/KPMstats/test_dir.m b/sourcecodes/bnt-master/KPMstats/test_dir.m
new file mode 100644
index 00000000..24849473
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/test_dir.m
@@ -0,0 +1,19 @@
+% # of sample points
+n_samples = 1000;
+
+p = ones(3,1)/3;
+
+% Low Entropy
+alpha = 0.5*p;
+
+% High Entropy
+%alpha = 10*p;
+
+% draw n_samples random points from the 3-d dirichlet(alpha),
+% and plot the results
+points = zeros(3,n_samples);
+for i = 1:n_samples
+    points(:,i) = dirichletrnd(alpha);
+end
+
+scatter3(points(1,:)', points(2,:)', points(3,:)', 'r', '.', 'filled');
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/KPMstats/unidrndKPM.m b/sourcecodes/bnt-master/KPMstats/unidrndKPM.m
new file mode 100644
index 00000000..2c96820d
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/unidrndKPM.m
@@ -0,0 +1,7 @@
+function R = unidrndKPM(min, max, nr, nc)
+
+if nargin < 3
+  nr = 1; nc = 1;
+end
+
+R = unidrnd(max-min+1, nr, nc) + (min-1);
diff --git a/sourcecodes/bnt-master/KPMstats/unif_discrete_sample.m b/sourcecodes/bnt-master/KPMstats/unif_discrete_sample.m
new file mode 100644
index 00000000..aad19e05
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/unif_discrete_sample.m
@@ -0,0 +1,6 @@
+function r = unif_discrete_sample(n, nrows, ncols)
+% UNIF_DISCRETE_SAMPLE Generate random numbers uniformly from {1,2,..,n}
+% function r = unif_discrete_sample(n, nrows, ncols)
+% Same as unidrnd in the stats toolbox.
+
+r = ceil(n .* rand(nrows,ncols));
diff --git a/sourcecodes/bnt-master/KPMstats/weightedRegression.m b/sourcecodes/bnt-master/KPMstats/weightedRegression.m
new file mode 100644
index 00000000..2d2438ee
--- /dev/null
+++ b/sourcecodes/bnt-master/KPMstats/weightedRegression.m
@@ -0,0 +1,58 @@
+function [a, b, error] = weightedRegression(x, z, w)
+% [a , b, error] = fitRegression(x, z, w);
+% % Weighted scalar linear regression
+%
+% Find a,b to minimize
+% error = sum(w * |z - (a*x + b)|^2) 
+% and x(i) is a scalar
+
+if nargin < 3, w = ones(1,length(x)); end
+
+w = w(:)';
+x = x(:)';
+z = z(:)';
+
+W = sum(w);
+Y = sum(w .* z);
+YY = sum(w .* z .* z);
+YTY = sum(w .* z .* z);
+X = sum(w .* x);
+XX = sum(w .* x .* x);
+XY = sum(w .* x .* z);
+
+[b, a] = clg_Mstep_simple(W, Y, YY, YTY, X, XX, XY);
+error = sum(w .* (z - (a*x + b)).^2 );
+
+if 0
+  % demo
+  seed = 1;
+  rand('state', seed);   randn('state', seed);
+  x = -10:10;
+  N = length(x);
+  noise = randn(1,N);
+  aTrue = rand(1,1);
+  bTrue = rand(1,1);
+  z = aTrue*x + bTrue + noise;
+  
+  w = ones(1,N);
+  [a, b, err] = weightedRegression(x, z, w);
+  
+  b2=regress(z(:), [x(:) ones(N,1)]);
+  assert(approxeq(b,b2(2)))
+  assert(approxeq(a,b2(1)))
+
+  % Make sure we go through x(15) perfectly
+  w(15) = 1000;
+  [aW, bW, errW] = weightedRegression(x, z, w);
+
+  figure;
+  plot(x, z, 'ro')
+  hold on
+  plot(x, a*x+b, 'bx-')
+  plot(x, aW*x+bW, 'gs-')
+  title(sprintf('a=%5.2f, aHat=%5.2f, aWHat=%5.3f, b=%5.2f, bHat=%5.2f, bWHat=%5.3f, err=%5.3f, errW=%5.3f', ...
+		aTrue, a, aW, bTrue, b, bW, err, errW))
+  legend('truth', 'ls', 'wls')
+  
+end
+