about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/SLP/scoring
diff options
context:
space:
mode:
Diffstat (limited to 'sourcecodes/bnt-master/SLP/scoring')
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/calculate_mutual_information_array.m32
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/cond_indep_chisquare.m184
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/cond_mutual_info_score.m28
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/kl_divergence.m48
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/kl_divergence2.m43
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/mutual_info_score.m25
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/score_add_to_cache.m67
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtab.m179
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtab_INFO.txt91
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtabx.m181
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtabxx.m141
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_dag_x.c72
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_family_x.c71
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_x.c168
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_x.h19
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/score_dags.m74
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/score_family.m218
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/score_find_in_cache.m63
-rw-r--r--sourcecodes/bnt-master/SLP/scoring/score_init_cache.m29
19 files changed, 1733 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/SLP/scoring/calculate_mutual_information_array.m b/sourcecodes/bnt-master/SLP/scoring/calculate_mutual_information_array.m
new file mode 100644
index 00000000..1128e411
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/calculate_mutual_information_array.m
@@ -0,0 +1,32 @@
+function [mi] = calculate_mutual_information_array(data)
+% FUNCTION [MI_ARRAY] = CALCULATE_MUTUAL_INFORMATION_ARRAY(DATA)
+% calculates the mutual information between all pairs of variables
+% Data must be discrete, and take values 1,2,...,size
+% data(i,m) is the node i in the case m.
+
+[num_nodes num_examples] = size(data);
+
+node_sizes = max(data');
+for i = 1:num_nodes
+  for ic = 1:node_sizes(i) % I CLASS ic
+    px(i,ic) = sum(data(i,:)==ic);
+    for j = 1:num_nodes    % J CLASS jc
+      for jc = 1:node_sizes(j)
+        pxy(i,ic,j,jc) = sum( (data(i,:)==ic) & (data(j,:)==jc) );
+      end
+      mi(i,j) = 0;
+    end
+  end
+end
+
+for i = 1:num_nodes
+  for ic = 1:node_sizes(i)
+    for j = 1:num_nodes
+      for jc = 1:node_sizes(j)
+        if( pxy(i,ic,j,jc)~=0 & px(i,ic)~=0 & px(j,jc)~= 0)
+          mi(i,j) = mi(i,j) + pxy(i,ic,j,jc)*log2( num_examples*pxy(i,ic,j,jc)/(px(i,ic)*px(j,jc)) )/num_examples; 
+        end
+      end
+    end
+  end
+end
diff --git a/sourcecodes/bnt-master/SLP/scoring/cond_indep_chisquare.m b/sourcecodes/bnt-master/SLP/scoring/cond_indep_chisquare.m
new file mode 100644
index 00000000..efc162cc
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/cond_indep_chisquare.m
@@ -0,0 +1,184 @@
+function [CI, Chi2, alpha2] = cond_indep_chisquare(X, Y, S, Data, test, alpha, ns)
+% COND_INDEP_CHISQUARE Test if X indep Y given Z
+%                      using either chisquare test or likelihood ratio test G2
+%
+% [CI Chi2 Prob_Chi2] = cond_indep_chisquare(X, Y, S, Data, test, alpha, node_sizes)
+%
+% Input :
+%       Data is the data matrix, N columns * NbVar rows
+%       X is the index of variable X in Data matrix
+%       Y is the index of variable Y in Data matrix
+%       S are the indexes of variables in set S
+%       alpha is the significance level (default: 0.05)
+%       test = 'pearson' for Pearson's chi2 test
+%		   'LRT' for G2 likelihood ratio test (default)
+%       node_sizes (default: max(Data'))
+%
+% Output :
+%       CI = test result (1=conditional independency, 0=no)
+%       Chi2 = chi2 value (-1 if not enough data to perform the test --> CI=0)
+%
+%
+% V1.4 : 24 july 2003 (Ph. Leray - philippe.leray@univ-nantes.fr)
+%
+%
+% Things to do :
+% - do not use 'find' in nij computation (when S=empty set)
+% - find a better way than 'warning off/on' in tmpij, tmpijk computation
+%
+
+if nargin < 5, test = 'LRT'; end
+if nargin < 6, alpha = 0.05; end
+if nargin < 7, ns = max(Data'); end
+
+Data=Data';
+
+N = size(Data,1);
+qi=ns(S);
+tmp=[1 cumprod(qi(1:end-1))];
+qs=1+(qi-1)*tmp';
+if isempty(qs),
+    nij=zeros(ns(X),ns(Y));
+    df=prod(ns([X Y])-1)*prod(ns(S));
+else
+
+%   Commented by Mingyi
+%    nijk=zeros(ns(X),ns(Y),qs);
+%    tijk=zeros(ns(X),ns(Y),qs);
+%   Commention ends
+%   Added by Mingyi
+    nijk=zeros(ns(X),ns(Y),1);
+    tijk=zeros(ns(X),ns(Y),1);
+%   Addition ends
+    df=prod(ns([X Y])-1)*qs;
+end
+
+
+if (N<10*df)
+    % Not enough data to perform the test
+    Chi2=-1;
+    CI=0;
+
+elseif isempty(S)
+    for i=1:ns(X),
+        for j=1:ns(Y),
+            nij(i,j)=length(find((Data(:,X)==i)&(Data(:,Y)==j))) ;
+        end
+    end
+    restr=find(sum(nij,1)==0);
+    if ~isempty(restr)
+        nij=nij(:,find(sum(nij,1)));
+    end
+
+    tij=sum(nij,2)*sum(nij,1)/N ;
+
+ switch test
+    case 'pearson',
+        tmpij=nij-tij;
+
+        [xi yj]=find(tij<10);
+        for i=1:length(xi),
+           tmpij(xi(i),yj(i))=abs(tmpij(xi(i),yj(i)))-0.5;
+        end
+
+        warning off;
+        tmp=(tmpij.^2)./tij;
+        warning on;
+        tmp(find(tmp==Inf))=0;
+
+    case 'LRT',
+        warning off;
+        tmp=nij./tij;
+        warning on;
+        tmp(find(tmp==Inf | tmp==0))=1;
+        tmp(find(tmp~=tmp))=1;
+        tmp=2*nij.*log(tmp);
+
+    otherwise,
+        error(['unrecognized test ' test]);
+    end
+
+    Chi2=sum(sum(tmp));
+    alpha2=1-chisquared_prob(Chi2,df);
+    CI=(alpha2>=alpha) ;
+
+else
+    SizeofSSi=1;
+    for exemple=1:N,
+        i=Data(exemple,X);
+        j=Data(exemple,Y);
+        Si=Data(exemple,S)-1;
+        %Added by Mingyi
+        if exemple==1
+            SSi(SizeofSSi,:)=Si;
+            nijk(i,j,SizeofSSi)=1;
+        else
+            flag=0;
+            for iii=1:SizeofSSi
+                if isequal(SSi(iii,:),Si)
+                    nijk(i,j,iii)=nijk(i,j,iii)+1;
+                    flag=1;
+                end
+            end
+            if flag==0
+                SizeofSSi=SizeofSSi+1;
+                SSi(SizeofSSi,:)=Si;
+                nijk(i,j,SizeofSSi)=1;
+            end
+        end
+        %Addition ends
+        %Commented by Mingyi
+%         k=1+Si*tmp';
+%         nijk(i,j,k)=nijk(i,j,k)+1;
+        %Commention ends
+    end
+
+    nik=sum(nijk,2);
+    njk=sum(nijk,1);
+    N2=sum(njk);
+
+ %   for k=1:qs,         %Commented by Mingyi
+    for k=1:SizeofSSi    %Added by Mingyi
+        if N2(:,:,k)==0
+            tijk(:,:,k)=0;
+        else
+            tijk(:,:,k)=nik(:,:,k)*njk(:,:,k)/N2(:,:,k);
+        end
+    end
+
+    switch test
+    case 'pearson',
+        tmpijk=nijk-tijk;
+
+        [xi yj]=find(tijk<10);
+        for i=1:length(xi),
+            tmpijk(xi(i),yj(i))=abs(tmpijk(xi(i),yj(i)))-0.5;
+        end
+
+        warning off;
+        tmp=(tmpijk.^2)./tijk;
+        warning on;
+        tmp(find(tmp==Inf))=0;
+
+    case 'LRT',
+        warning off;
+        tmp=nijk./tijk;
+        warning on;
+        tmp(find(tmp==Inf | tmp==0))=1;
+        tmp(find(tmp~=tmp))=1;
+        tmp=2*nijk.*log(tmp);
+
+    otherwise,
+        error(['unrecognized test ' test]);
+    end
+
+    Chi2=sum(sum(sum(tmp)));
+    alpha2=1-chisquared_prob(Chi2,df);
+    CI=(alpha2>=alpha) ;
+
+end
+clear tijk
+clear nijk
+clear nij
+clear tij
+clear tmpijk
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/SLP/scoring/cond_mutual_info_score.m b/sourcecodes/bnt-master/SLP/scoring/cond_mutual_info_score.m
new file mode 100644
index 00000000..b43cbfeb
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/cond_mutual_info_score.m
@@ -0,0 +1,28 @@
+function score = cond_mutual_info_score(i,si,j,sj,c,sc,data)
+% G = cond_mutual_info_score(i,si,j,sj,c,sc,data)
+% Only for tabular node which values are 1,2,...,size .
+% si is size of node i, sj is size of node j, sc is the size of node c.
+% data(i,m) is the node i in the case m.
+% 
+%
+% pphilippe.leray@univ-nantes.fr, francois.olivier.c.h@gmail.com
+
+[n N]=size(data);
+Pc=hist(data(c,:),1:sc)/N;
+score=0;
+
+for cvalue=1:sc,
+    ind=find(data(c,:)==cvalue);
+    Nj=hist(data(j,ind),1:sj);
+    Ni=hist(data(i,ind),1:si);
+    NiNj=Ni'*Nj;
+
+    for k=1:si
+        ind2=find(data(i,ind)==k) ;
+        Nij(k,:) = hist(data(j,ind(ind2)),1:sj);
+    end
+
+    % sommons les valeurs non-infinies:
+    ind=find(NiNj~=0 & Nij~=0);
+    score=score+Pc(cvalue)*sum(sum(Nij(ind).*log(N*Nij(ind)./NiNj(ind))/N));
+end
diff --git a/sourcecodes/bnt-master/SLP/scoring/kl_divergence.m b/sourcecodes/bnt-master/SLP/scoring/kl_divergence.m
new file mode 100644
index 00000000..f4e18147
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/kl_divergence.m
@@ -0,0 +1,48 @@
+function KLdiv = KL_divergence(bnetP, bnetQ)
+% KL_DIVERGENCE computes the Kullback-Leibler divergence between two BNET distributions
+% KLdiv = KL_divergence(bnetP, bnetQ)
+%
+% Output :
+%   div = sum_x  P(x).log(P(x)/Q(x))
+%
+% Rem : 
+%   This version is optimized for speed, but can use too many memory
+%     ==> if you have a memory problem, use kl_divergence2 instead
+%
+
+%   ONLY FOR TABULAR NODES
+%   Make sure that you have done the params learning.
+%  
+%   V1.1 : 8 oct 2004 (Ph. Leray - philippe.leray@univ-nantes.fr)
+
+N = size(bnetP.dag,1);
+N2 = size(bnetQ.dag,1);
+ns= bnetP.node_sizes;
+ns2= bnetQ.node_sizes;
+if N~=N2, error('size of dags must be the same'), end
+if ns~=ns2, error('node sizes of dags must be the same'), end
+tiny = exp(-700);
+KLdiv=0;
+
+inst = ind2subv(ns, 1:prod(ns)); 
+  %Px=1; Qx=1;
+  for i=1:N,
+    ps = parents(bnetP.dag, i);
+    %e = bnetP.equiv_class(i);
+    %[tmp Px(:,i)] = prob_node(bnetP.CPD{e}, inst(:,i)', inst(:,ps)');
+    [tmp Px(:,i)] = prob_node(bnetP.CPD{i}, inst(:,i)', inst(:,ps)');
+
+    ps = parents(bnetQ.dag, i);
+    %e = bnetQ.equiv_class(i);
+    %[tmp Qx(:,i)] = prob_node(bnetQ.CPD{e}, inst(:,i)', inst(:,ps)');
+    [tmp Qx(:,i)] = prob_node(bnetQ.CPD{i}, inst(:,i)', inst(:,ps)');
+  end
+ Px=prod(Px,2);
+ Px = Px + (Px==0)*tiny; % replace 0s by tiny
+ Qx=prod(Qx,2);
+ Qx = Qx + (Qx==0)*tiny; % replace 0s by tiny
+
+ %%%%% Faut-il diviser par le nb de configurations possibles ? (sum => mean)
+ KLdiv = sum(Px.*log(Px./Qx));
+  %end
+
diff --git a/sourcecodes/bnt-master/SLP/scoring/kl_divergence2.m b/sourcecodes/bnt-master/SLP/scoring/kl_divergence2.m
new file mode 100644
index 00000000..7b9664ba
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/kl_divergence2.m
@@ -0,0 +1,43 @@
+function KLdiv = KL_divergence2(bnetP, bnetQ)
+% KL_DIVERGENCE2 computes the Kullback-Leibler divergence between two BNET distributions
+% KLdiv = KL_divergence2(bnetP, bnetQ)
+%
+% Output :
+%   div = sum_x  P(x).log(P(x)/Q(x))
+%
+% Rem : 
+%   This version is optimized for memory use, but quite slow !!!
+%     ==> if you have no memory problem, use kl_divergence instead
+%
+%   ONLY FOR TABULAR NODES
+%   Make sure that you have done the params learning.
+%
+%   V1.1 : 8 oct 2004 (Ph. Leray - philippe.leray@univ-nantes.fr)
+
+N = size(bnetP.dag,1);
+N2 = size(bnetQ.dag,1);
+ns= bnetP.node_sizes;
+ns2= bnetQ.node_sizes;
+if N~=N2, error('size of dags must be the same'), end
+if ns~=ns2, error('node sizes of dags must be the same'), end
+tiny = exp(-700);
+KLdiv=0;
+
+for i=1:prod(ns),
+  inst = ind2subv(ns, i); % i'th instantiation
+  Px=1; Qx=1;
+  for i=1:N,
+    ps = parents(bnetP.dag, i);
+    e = bnetP.equiv_class(i);
+    [tmp Pxi] = prob_node(bnetP.CPD{e}, inst(i), inst(ps)');
+    Px=Px*Pxi;
+    ps = parents(bnetQ.dag, i);
+    e = bnetQ.equiv_class(i);
+    [tmp Qxi] = prob_node(bnetQ.CPD{e}, inst(i), inst(ps)');
+    Qx=Qx*Qxi;
+  end
+    Px = Px + (Px==0)*tiny; % replace 0s by tiny
+    Qx = Qx + (Qx==0)*tiny; % replace 0s by tiny
+  KLdiv = KLdiv + Px*log(Px/Qx);
+end
+
diff --git a/sourcecodes/bnt-master/SLP/scoring/mutual_info_score.m b/sourcecodes/bnt-master/SLP/scoring/mutual_info_score.m
new file mode 100644
index 00000000..8808a124
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/mutual_info_score.m
@@ -0,0 +1,25 @@
+function score = mutual_info_score(i,si,j,sj,data)
+% G = mutual_info_score(i,si,j,sj,data)
+% Only for tabular node which values are 1,2,...,size .
+% si is size of node i, sj is size of node j.
+% data(i,m) is the node i in the case m.
+% 
+% Ref :
+% C. Chow and C. Liu (1968). Approximating discrete probability distributions with dependence trees. 
+% IEEE Transactions on Information Theory, 14(3):462--467, May 1968.
+%
+% francois.olivier.c.h@gmail.com, philippe.leray@univ-nantes.fr, wangxiangyang@sjtu.edu.cn
+
+[n N]=size(data);
+Nj=hist(data(j,:),1:sj);
+Ni=hist(data(i,:),1:si);
+NiNj=Ni'*Nj;
+
+for k=1:si
+ ind=find(data(i,:)==k) ;
+ Nij(k,:) = hist(data(j,ind),1:sj);
+end
+
+% sommons les valeurs non-infinies:
+ind=find(NiNj~=0 & Nij~=0);
+score=sum(sum(Nij(ind).*log(N*Nij(ind)./NiNj(ind))/N));
diff --git a/sourcecodes/bnt-master/SLP/scoring/score_add_to_cache.m b/sourcecodes/bnt-master/SLP/scoring/score_add_to_cache.m
new file mode 100644
index 00000000..3c68e4d8
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/score_add_to_cache.m
@@ -0,0 +1,67 @@
+function [cache, place] = score_add_to_cache(cache,j,ps,score,scoring_fn)
+% [cache place] = score_add_to_cache(cache,j,ps,score,scoring_fn)
+% 
+% j is the son node,
+% ps is the list of parents of j, for example [12 5 7],
+% score is the score to add for this familly.
+% scoring_fn is 'bic' or 'bayesian'.
+%
+% place = where the entry was add.
+%
+% example for 2 nodes with cache of size 5 :
+%
+% cache =
+%   5   b        0      0      0  --> number of writing in cache +1 and b==1 iff the cache is full
+%   0   0        1   -239.12   1  --> 1st familly in the cache (node 1 without parents) calculate with bic
+%   0   0        2   -318.98   1
+%   1   0        2   -189.23   2  --> 3rd familly in the cache (node 2 with 1 as parent) calculate with bayesian
+%   0   1        1   -251.09   1
+% .ps2bool.      j    score  1or2 --> new entry
+%   |   |        |      |      |
+%   |   |        |      |      |___> 1 for 'bic' or 2 for 'bayesian'
+%   |   |        |      |__________> score of the familly
+%   |   |        |_________________> son node of the familly
+%   |   |__________________________> ==1 iff node 2 is parent of son node
+%   |______________________________> ==1 iff node 1 is parent of son node
+%
+% If the cache is FULL then the new place is RanDoMly choose.
+%
+% francois.olivier.c.h@gmail.com
+
+N=size(cache,2)-3;
+place=0;
+
+if ~isempty(find(ps==j))
+  disp('This is a cyclic entry, nothing was done.');
+elseif j>N | j<0
+  disp('This entry is not valid, nothing was done.');
+else
+
+  switch scoring_fn
+    case 'bic',
+      fn=1;
+    case 'bayesian',
+      fn=2;
+    otherwise,
+      fn=3;
+      %error(['unrecognized scoring fn ' scoring_fn]);
+  end
+  L=size(cache,1);
+
+  if cache(1,2)==0
+    place=cache(1,1);
+  else
+    place=ceil(rand(1)*(L-1))+1;
+  end
+
+  cache(place,:)=0
+  cache(place,ps)=1;
+  cache(place,N+1)=j;
+  cache(place,N+2)=score;
+  cache(place,N+3)=fn;
+  cache(1,1)=place+1;
+  if place==L | cache(1,2)~=0
+    cache(1,2)=1
+  end
+
+end
diff --git a/sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtab.m b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtab.m
new file mode 100644
index 00000000..5bc375fc
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtab.m
@@ -0,0 +1,179 @@
+function [dag,best_score] =	learn_struct_gs_dtab(data, nodesizes, seeddag, varargin)
+%
+% LEARN_STRUCT_GS(data,seeddag)	learns a structure of Bayesian net by Greedy Search.
+% dag =	learn_struct_gs(data, nodesizes, seeddag)
+%
+% dag: the final structurre	matrix
+% Data : training data,	data(i,m) is the m obsevation of node i
+% Nodesizes: the size array	of different nodes
+% seeddag: given seed Dag for hill climbing, optional
+%
+% by Gang Li @ Deakin University (gli73@hotmail.com)
+%
+% -----------------------------------------------------
+%
+% Modified from	learn_struct_gs (SLP 1.3)
+% to learn structure of	BN with	tabular	nodes:
+%
+% 1) make use of score decomposibility 
+% 2) still to do
+%
+% by Darima	<darrimma@yahoo.com>, 27/12/2005
+%
+
+[N ncases] = size(data);
+if (nargin < 3 ) 
+	seeddag	= zeros(N,N); %	mk_rnd_dag(N); %call BNT function
+elseif ~acyclic(seeddag)
+	seeddag	= mk_rnd_dag(N); %zeros(N,N);
+end;
+
+% set default params (the same as in score_dags)
+for i=1:N
+  type{i} = 'tabular';
+  params{i} = { 'prior_type', 'dirichlet', 'dirichlet_weight', 1 };
+end
+scoring_fn = 'bayesian';
+discrete = 1:N;
+verbose	 = 'yes';
+
+% get params
+args = varargin;
+nargs =	length(args);
+if length(args)	> 0
+	if isstr(args{1})
+		for	i =	1:2:nargs
+			switch args{i}
+			case 'scoring_fn', scoring_fn =	args{i+1};
+            case 'type',       type = args{i+1}; 
+            case 'discrete',   discrete = args{i+1}; 
+            case 'params',     
+                if isempty(args{i+1}), params = cell(1,n); 
+                else params = args{i+1};  end;           
+			case 'verbose',	 verbose  =	strcmp(args{i+1},'yes');
+			end;
+		end;
+	end;
+end;
+
+done = 0;
+best_score = score_dags(data,nodesizes,	{seeddag},'scoring_fn',scoring_fn);
+
+it = 0;
+while ~done
+	[dags,op,nodes]	= mk_nbrs_of_dag(seeddag);
+	nbrs = length(dags);
+%------ DEBUG    
+    fprintf('DEBUG: nbrs = %6d\n',nbrs);
+    time_inloop = cputime;
+%------ DEND
+    
+%  	scores	= score_dags(data, nodesizes, dags,'scoring_fn',scoring_fn);
+	scores = zeros(nbrs,1);
+	for	i =	1:nbrs
+		xj = nodes(i,2);	
+		ps_old = parents(seeddag, xj)';
+		ps_new = parents(dags{i}, xj)';
+        scor_old = score_family(xj, ps_old, type{xj}, scoring_fn, ...
+            nodesizes, discrete, data, params{xj});
+        scor_new = score_family(xj, ps_new, type{xj}, scoring_fn, ...
+            nodesizes, discrete, data, params{xj});
+		scores(i) =	best_score - scor_old +	scor_new;
+		if isequal(op{i},'rev')
+		    xi = nodes(i,1);
+			ps_old = parents(seeddag, xi);
+			ps_new = parents(dags{i}, xi);     
+            scor_old = score_family(xi, ps_old, type{xi}, scoring_fn, ...
+                nodesizes, discrete, data, params{xi});
+            scor_new = score_family(xi, ps_new, type{xi}, scoring_fn, ...
+                nodesizes, discrete, data, params{xi});
+			scores(i) =	scores(i) - scor_old +	scor_new;            
+		end
+    end
+    
+	max_score =	max(scores);
+	new	= find(scores == max_score );
+    
+%------ DEBUG
+    fprintf('       -> max_score = %7.5f\n',max_score);
+    fprintf('       -> find(scores == max_score): %d... of %d\n',...
+        new(1),length(new));
+%------ DEND
+	if ~isempty(new) & (max_score >	best_score)
+		p =	sample_discrete(normalise(ones(1, length(new))));
+		best_score = max_score;
+		seeddag	= dags{new(p)};
+	else
+		done = 1;
+	end;
+    
+    it = it+1;
+%------ DEBUG
+    time_inloop = cputime-time_inloop;
+    fprintf('       time = %12.5f\n',time_inloop);
+%------ DEND
+end;
+
+dag	= seeddag;
+
+outcount = 0; 
+best_score = score_dags(data,nodesizes,	{seeddag},'scoring_fn',scoring_fn);
+while outcount < 2
+	innercount = 0;
+	for	i=1:N
+		for	j=1:N
+		   if i==j,	continue;	 end;
+		   if seeddag(i,j) == 0	 % No edge i-->j, then try to add it
+			   tempdag = seeddag;
+			   tempdag(i,j)	= 1;
+			   if acyclic(tempdag)
+					temp_score = score_dags(data,nodesizes,	{tempdag},'scoring_fn',scoring_fn);
+					if temp_score >	best_score
+						seeddag	= tempdag;
+						best_score=	temp_score;
+						innercount = innercount	+1;
+					end;
+			   end
+		   else	 % exists edge i--j, then try reverse it or	remove it
+			   tempdag = seeddag;
+			   tempdag(i,j)	= 0; tempdag(j,i) =	1; 
+			   if acyclic(tempdag)
+				   temp_score =	score_dags(data,nodesizes, {tempdag},'scoring_fn',scoring_fn);
+				   if temp_score > best_score
+					   seeddag = tempdag;
+					   best_score =	temp_score;
+					   innercount =	innercount +1;
+				   else
+					   tempdag = seeddag;
+					   tempdag(i,j)	= 0;
+					   temp_score =	score_dags(data,nodesizes, {tempdag},'scoring_fn',scoring_fn);
+					   if temp_score > best_score
+						   seeddag = tempdag;
+						   best_score= temp_score;
+						   innercount =	innercount +1;
+					   end;
+				   end;
+			   else
+				   tempdag = seeddag;
+				   tempdag(i,j)=0;
+				   temp_score =	score_dags(data,nodesizes, {tempdag},'scoring_fn',scoring_fn);
+				   if temp_score > best_score
+					   seeddag = tempdag;
+					   best_score= temp_score;
+					   innercount =	innercount +1;
+				   end;
+			   end;
+		   end;
+		end; % end for j
+	end; % end for i
+	if innercount == 0
+		outcount = outcount	+1;
+	end;
+end;  %	end	while
+
+%------ DEBUG
+fprintf('DEBUG: Number of iterations = %d\n',it);
+fprintf('DEBUG: Outcount = %d\n',outcount);
+%------ DEND
+dag	= seeddag;
+
diff --git a/sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtab_INFO.txt b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtab_INFO.txt
new file mode 100644
index 00000000..dc076d78
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtab_INFO.txt
@@ -0,0 +1,91 @@
+Objet:  	Re: [BayesNetToolbox] cache size in structure learning package (SLP)	
+De:  	"Darima Lamazhapova" <darrimma@yahoo.com>	
+Date:  	Mar 3 janvier 2006 14:13	
+to:  	BayesNetToolbox@yahoogroups.com	
+
+Hi, 
+I have not done extensive tests with different dataset and cache sizes.
+Mostly because I was interested in the case of small dataset,
+say dataset size 100. Even in this case seems that using cache 
+drasticly improves the performance of greedy search. Here are some
+numbers (alarm network, dataset 100, greedy search):
+    no cache     - ~11000 sec
+    cache  100  -  1395 sec
+    cache  200  -  1386 sec
+    cache  300  -  1428 sec
+    cache  500  -  1567 sec
+    cache 1000 -  1680 sec
+    cache 3000 -  2196 sec
+The reason why greedy search takes so much time without using
+cache, i think is that it does not make use of score 
+decomposibility.
+When I have modified the code so that it used decomposibility,
+ time required for the search decreased from 11000 to 1362 sec
+without using cache. Reimplemening score_family in C decreased this
+time to 552 sec; after reimplementing score_dag in C and
+removing outcount cycle from the learn_struct_gs code (I did not
+understand why it is necessary, can anyone explain what is
+the use of it, please?) the time required for GS dropped up to  69 sec.
+Implementation in C was done only for tabular nodes, Bayesian scoring
+function with default priors. If anyone interested I can submit the codes,
+although they are not very well tested.
+Darima
+
+Olivier Francois <olivier.francois@insa-rouen.fr> wrote:
+
+> Hello,
+> Can anyone give recommendations on choosing cache size?
+> When I used 500, calculations using learn_struct_gs2 for
+> ALARM network took about 20 min (dataset size was 100).
+> I thought it is a bit slow for 3 GHz computer with 1 Gb memory,
+> or am I wrong here?
+> I thought that increasing cache size might increase performance,
+> however the calculations took even longer.
+> I am kinda lost right now.
+> Any comments would be highly appreciated.
+> Darima
+>
+
+Hi,
+
+I have seen this phenomenon.
+In fact, for all the tests I have done, I advise you to use a cache of size between 200
+and 500.
+
+When the size is bigger the time spent to search if an entry already exists is quite
+similar to the time spend to recalculate the score, specialy if you have a small dataset
+(under 1500-2000 samples).
+Nevertheless, if you've got a huge dataset (5000 or more), it will be very advantageous
+to use the cache option.
+
+Moreover, I have seen that when you use a big cache (1000 or more), it do not speed up
+the computationnal time but you not spent a lot of extented time in using it.
+I think it is better to have a too big cache than a too small.
+
+If the cache is too small you often erase entries that will be recalculate later,
+specially if you have a lot of attributes, and the time spent will be equivalent or
+higher than if you have not used it.
+
+But suprisigly, even if you have a lot of nodes and a lot of samples (I have tested to
+25x10000 if I remember well), upgrading the size of the cache (1000 and more) do not
+seem to improve the computation time.
+
+- More tests are needed to be sure of that -
+
+I have not done a lot of tests, and this is only what I believed to see.
+Maybe it is better to take a cache of size 2500 or 5000 for a dataset of size 40*50000
+or 60*5000...?
+
+I also have remarked that, if you use a 'sparse matrix' for the cache inst ead of a
+stardart one, that causes a waste of time even if the cache matrix is, in fact, sparse.
+
+
+In your case, with 100 samples, you don't need too use the cache option.
+
+If you make (or have made for some others ?) more tests with different sample sizes and
+different numbers of attributes, I am interrested in getting some comments on your use
+of this function.
+
+
+Bonne fetes - Happy Hollidays - Felice Fiestas
+    Olivier F.
diff --git a/sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtabx.m b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtabx.m
new file mode 100644
index 00000000..be624ee8
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtabx.m
@@ -0,0 +1,181 @@
+function [dag,best_score] =	learn_struct_gs_dtabx(data, nodesizes, seeddag, varargin)
+%
+% LEARN_STRUCT_GS(data,seeddag)	learns a structure of Bayesian net by Greedy Search.
+% dag =	learn_struct_gs(data, nodesizes, seeddag)
+%
+% dag: the final structure matrix
+% Data : training data,	data(i,m) is the m obsevation of node i
+% Nodesizes: the size array	of different nodes
+% seeddag: given seed Dag for hill climbing, optional
+%
+% by Gang Li @ Deakin University (gli73@hotmail.com)
+%
+% -----------------------------------------------------
+%
+% Modified from	learn_struct_gs (SLP 1.3)
+% to learn structure of	BN with	tabular	nodes:
+%
+% 1) make use of score decomposibility 
+% 2) replace score_family with score_family_x.c that calculates 
+%    Bayesian score with default parameters (non-adjustable)
+%
+% by Darima	<darrimma@yahoo.com>, 28/12/2005
+%
+
+[N ncases] = size(data);
+if (nargin < 3 ) 
+	seeddag	= zeros(N,N); %	mk_rnd_dag(N); %call BNT function
+elseif ~acyclic(seeddag)
+	seeddag	= mk_rnd_dag(N); %zeros(N,N);
+end;
+
+% set default params (the same as in score_dags)
+for i=1:N
+  type{i} = 'tabular';
+  params{i} = { 'prior_type', 'dirichlet', 'dirichlet_weight', 1 };
+end
+scoring_fn = 'bayesian';
+discrete = 1:N;
+verbose	 = 'yes';
+
+% get params
+args = varargin;
+nargs =	length(args);
+if length(args)	> 0
+	if isstr(args{1})
+		for	i =	1:2:nargs
+			switch args{i}
+			case 'scoring_fn', scoring_fn =	args{i+1};
+            case 'type',       type = args{i+1}; 
+            case 'discrete',   discrete = args{i+1}; 
+            case 'params',     
+                if isempty(args{i+1}), params = cell(1,n); 
+                else params = args{i+1};  end;           
+			case 'verbose',	 verbose  =	strcmp(args{i+1},'yes');
+			end;
+		end;
+	end;
+end;
+
+%%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+datax = data-ones(N,ncases);     %%+++++++++++++++++++++++ IMPORTANT!!!!
+%%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+best_score = score_dags(data,nodesizes,	{seeddag},'scoring_fn',scoring_fn);
+done = 0;
+it = 0;
+
+while ~done
+	[dags,op,nodes]	= mk_nbrs_of_dag(seeddag);
+	nbrs = length(dags);
+%------ DEBUG    
+    fprintf('DEBUG: nbrs = %6d\n',nbrs);
+    time_inloop = cputime;
+%------ DEND
+%     scores	= score_dags(data, nodesizes, dags,'scoring_fn',scoring_fn);
+	scores = zeros(nbrs,1);
+	for	i =	1:nbrs
+		xj = nodes(i,2);	
+		ps_old = parents(seeddag, xj)';
+		ps_new = parents(dags{i}, xj)';
+        scor_old = score_family_x([datax(ps_old,:);datax(xj,:)],...
+            [nodesizes(ps_old),nodesizes(xj)]);
+        scor_new = score_family_x([datax(ps_new,:);datax(xj,:)],...
+            [nodesizes(ps_new),nodesizes(xj)]);
+		scores(i) =	best_score - scor_old +	scor_new;
+		if isequal(op{i},'rev')
+		    xi = nodes(i,1);
+			ps_old = parents(seeddag, xi);
+			ps_new = parents(dags{i}, xi);
+            scor_old = score_family_x([datax(ps_old,:);datax(xi,:)],...
+                [nodesizes(ps_old),nodesizes(xi)]);
+            scor_new = score_family_x([datax(ps_new,:);datax(xi,:)],...
+                [nodesizes(ps_new),nodesizes(xi)]);
+			scores(i) =	scores(i) - scor_old +	scor_new;            
+		end
+    end    
+	max_score =	max(scores);
+	new	= find(scores == max_score );
+%------ DEBUG
+    fprintf('       -> max_score = %7.5f\n',max_score);
+    fprintf('       -> find(scores == max_score): %d... of %d\n',...
+        new(1),length(new));
+%------ DEND
+	if ~isempty(new) & (max_score >	best_score)
+		p =	sample_discrete(normalise(ones(1, length(new))));
+		best_score = max_score;
+		seeddag	= dags{new(p)};
+	else
+		done = 1;
+	end;    
+    it = it+1;
+%------ DEBUG
+    time_inloop = cputime-time_inloop;
+    fprintf('       time = %12.5f\n',time_inloop);
+%------ DEND
+end;
+dag	= seeddag;
+
+%----------------------------------------------------------------------
+
+outcount = 0; 
+best_score = score_dags(data,nodesizes,	{seeddag},'scoring_fn',scoring_fn);
+while outcount < 2
+	innercount = 0;
+	for	i=1:N
+		for	j=1:N
+		   if i==j,	continue;	 end;
+		   if seeddag(i,j) == 0	 % No edge i-->j, then try to add it
+			   tempdag = seeddag;
+			   tempdag(i,j)	= 1;
+			   if acyclic(tempdag)
+					temp_score = score_dags(data,nodesizes,	{tempdag},'scoring_fn',scoring_fn);
+					if temp_score >	best_score
+						seeddag	= tempdag;
+						best_score=	temp_score;
+						innercount = innercount	+1;
+					end;
+			   end
+		   else	 % exists edge i--j, then try reverse it or	remove it
+			   tempdag = seeddag;
+			   tempdag(i,j)	= 0; tempdag(j,i) =	1; 
+			   if acyclic(tempdag)
+				   temp_score =	score_dags(data,nodesizes, {tempdag},'scoring_fn',scoring_fn);
+				   if temp_score > best_score
+					   seeddag = tempdag;
+					   best_score =	temp_score;
+					   innercount =	innercount +1;
+				   else
+					   tempdag = seeddag;
+					   tempdag(i,j)	= 0;
+					   temp_score =	score_dags(data,nodesizes, {tempdag},'scoring_fn',scoring_fn);
+					   if temp_score > best_score
+						   seeddag = tempdag;
+						   best_score= temp_score;
+						   innercount =	innercount +1;
+					   end;
+				   end;
+			   else
+				   tempdag = seeddag;
+				   tempdag(i,j)=0;
+				   temp_score =	score_dags(data,nodesizes, {tempdag},'scoring_fn',scoring_fn);
+				   if temp_score > best_score
+					   seeddag = tempdag;
+					   best_score= temp_score;
+					   innercount =	innercount +1;
+				   end;
+			   end;
+		   end;
+		end; % end for j
+	end; % end for i
+	if innercount == 0
+		outcount = outcount	+1;
+	end;
+end;  %	end	while
+
+%------ DEBUG
+fprintf('DEBUG: Number of iterations = %d\n',it);
+fprintf('DEBUG: Outcount = %d\n',outcount);
+%------ DEND
+dag	= seeddag;
+
diff --git a/sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtabxx.m b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtabxx.m
new file mode 100644
index 00000000..c0d00f05
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/learn_struct_gs_dtabxx.m
@@ -0,0 +1,141 @@
+function [dag,best_score] =	learn_struct_gs_dtabxx(data, nodesizes, seeddag, varargin)
+%
+% LEARN_STRUCT_GS(data,seeddag)	learns a structure of Bayesian net by Greedy Search.
+% dag =	learn_struct_gs(data, nodesizes, seeddag)
+%
+% dag: the final structure matrix
+% Data : training data,	data(i,m) is the m obsevation of node i
+% Nodesizes: the size array	of different nodes
+% seeddag: given seed Dag for hill climbing, optional
+%
+% by Gang Li @ Deakin University (gli73@hotmail.com)
+%
+% -----------------------------------------------------
+%
+% Modified from	learn_struct_gs (SLP 1.3)
+% to learn structure of	BN with	tabular	nodes:
+%
+% 1) make use of score decomposibility 
+% 2) replace score_family with score_family_x.c that calculates 
+%    Bayesian score with default parameters (non-adjustable)%
+% 3) replace score_dags with score_dag_x.c
+%
+% by Darima	<darrimma@yahoo.com>, 28/12/2005
+%
+
+% useold = 0;
+% if useold
+%     best_score = score_dags(data,nodesizes,	{seeddag},'scoring_fn',scoring_fn);
+% else
+%     best_score = score_dag_x(datax,nodesizes,seeddag);
+% end
+
+[N ncases] = size(data);
+if (nargin < 3 ) 
+	seeddag	= zeros(N,N); %	mk_rnd_dag(N); %call BNT function
+elseif ~acyclic(seeddag)
+	seeddag	= mk_rnd_dag(N); %zeros(N,N);
+end;
+
+% set default params (the same as in score_dags)
+for i=1:N
+  type{i} = 'tabular';
+  params{i} = { 'prior_type', 'dirichlet', 'dirichlet_weight', 1 };
+end
+scoring_fn = 'bayesian';
+discrete = 1:N;
+verbose	 = 'yes';
+
+% get params
+args = varargin;
+nargs =	length(args);
+if length(args)	> 0
+	if isstr(args{1})
+		for	i =	1:2:nargs
+			switch args{i}
+			case 'scoring_fn', scoring_fn =	args{i+1};
+            case 'type',       type = args{i+1}; 
+            case 'discrete',   discrete = args{i+1}; 
+            case 'params',     
+                if isempty(args{i+1}), params = cell(1,n); 
+                else params = args{i+1};  end;           
+			case 'verbose',	 verbose  =	strcmp(args{i+1},'yes');
+			end;
+		end;
+	end;
+end;
+
+%%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+datax = data-ones(N,ncases);     %%+++++++++++++++++++++++ IMPORTANT!!!!
+%%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+useold = 0;
+if useold
+    best_score = score_dags(data,nodesizes,	{seeddag},'scoring_fn',scoring_fn);
+else
+    best_score = score_dag_x(datax,nodesizes,seeddag);
+end
+done = 0;
+it = 0;
+
+while ~done
+	[dags,op,nodes]	= mk_nbrs_of_dag(seeddag);
+	nbrs = length(dags);
+%------ DEBUG    
+%     fprintf('DEBUG: nbrs = %6d\n',nbrs);
+%     time_inloop = cputime;
+%------ DEND
+
+%     scores	= score_dags(data, nodesizes, dags,'scoring_fn',scoring_fn);
+	scores = zeros(nbrs,1);
+	for	i =	1:nbrs
+		xj = nodes(i,2);	
+		ps_old = parents(seeddag, xj)';
+		ps_new = parents(dags{i}, xj)';
+        scor_old = score_family_x([datax(ps_old,:);datax(xj,:)],...
+            [nodesizes(ps_old),nodesizes(xj)]);
+        scor_new = score_family_x([datax(ps_new,:);datax(xj,:)],...
+            [nodesizes(ps_new),nodesizes(xj)]);
+		scores(i) =	best_score - scor_old +	scor_new;
+		if isequal(op{i},'rev')
+		    xi = nodes(i,1);
+			ps_old = parents(seeddag, xi);
+			ps_new = parents(dags{i}, xi);
+            scor_old = score_family_x([datax(ps_old,:);datax(xi,:)],...
+                [nodesizes(ps_old),nodesizes(xi)]);
+            scor_new = score_family_x([datax(ps_new,:);datax(xi,:)],...
+                [nodesizes(ps_new),nodesizes(xi)]);
+			scores(i) =	scores(i) - scor_old +	scor_new;            
+		end
+    end
+    
+	max_score =	max(scores);
+	new	= find(scores == max_score );
+
+%------ DEBUG
+%     fprintf('       -> max_score = %7.5f\n',max_score);
+%     fprintf('       -> find(scores == max_score): %d... of %d\n',...
+%         new(1),length(new));
+%------ DEND
+	if ~isempty(new) & (max_score >	best_score)
+		p =	sample_discrete(normalise(ones(1, length(new))));
+		best_score = max_score;
+		seeddag	= dags{new(p)};
+	else
+		done = 1;
+	end;
+    
+    it = it+1;
+%------ DEBUG
+%     time_inloop = cputime-time_inloop;
+%     fprintf('       time = %12.5f\n',time_inloop);
+%------ DEND
+end;
+dag	= seeddag;
+
+%------ DEBUG
+% fprintf('DEBUG: Number of iterations = %d\n',it);
+% fprintf('DEBUG: Outcount = %d\n',0);
+%------ DEND
+
+
diff --git a/sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_dag_x.c b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_dag_x.c
new file mode 100644
index 00000000..d72bf591
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_dag_x.c
@@ -0,0 +1,72 @@
+//
+// File: score_dag_x.c
+//
+// MATLAB:
+// function score = score_dag_x(data,sz,dag)
+//
+// DESCRIPTION:
+// Calculates Bayesian score for the DAG with tabular nodes
+// (as in log_marg_prob_node.m):
+//      data        [nsz x ndata] array
+//                  IMPORTANT:                    <--- !!!!
+//                  - parents go first                             
+//                  - values of the nodes are in the range 0..sz[i] 
+//      sz          sizes of the nodes
+//		dag			DAG
+//      ndata       # of observations
+//      nsz         # of nodes in the DAG
+// with default parameters:  
+//      params{i} = { 'prior_type', 'dirichlet', 'dirichlet_weight', 1 }
+//                   ...and 'dirichlet_type','BDeu'
+//      scoring_fn = 'bayesian';
+//      etc...
+//
+// EXAMPLE:
+//   score_family_x([1 2 1; 1 2 2; 1 1 1],[2 2 2]);
+//
+// by Darima <darrimma@yahoo.com>, 27/12/2005 
+//
+
+#include "mex.h"
+#include "score_x.h"
+
+#define	IN_DATA	    prhs[0]
+#define IN_SZ       prhs[1]
+#define IN_DAG      prhs[2]
+#define	OUT_SCORE	plhs[0]
+#if !defined(MAX)
+#define	MAX(A, B)	((A) > (B) ? (A) : (B))
+#endif
+
+void mexFunction( int nlhs, mxArray *plhs[],
+                  int nrhs, const mxArray *prhs[] )   
+{ 
+    int nsz, ndata;
+    double *sz, *data,*dag, *score;
+   
+    /* Check for proper number of arguments */
+    
+    if (nrhs != 3) { 
+        mexErrMsgTxt("Three input arguments required."); 
+    } else if (nlhs > 1) {
+        mexErrMsgTxt("Too many output arguments."); 
+    } 
+
+    /* Assign input arguments */ 
+    
+    data   = mxGetPr(IN_DATA);
+    sz     = mxGetPr(IN_SZ);
+	dag	   = mxGetPr(IN_DAG);
+	ndata  = mxGetN(IN_DATA); 
+    nsz    = MAX(mxGetM(IN_SZ),mxGetN(IN_SZ)); 
+	
+    /* Create return argument */ 
+    
+    OUT_SCORE = mxCreateDoubleScalar(mxREAL);
+    score = mxGetPr(OUT_SCORE);
+
+    /* Do the actual computations in a subroutine */
+    
+    score_dag_x(data,sz,dag,ndata,nsz,score);
+    return;
+}
diff --git a/sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_family_x.c b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_family_x.c
new file mode 100644
index 00000000..ce45fd94
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_family_x.c
@@ -0,0 +1,71 @@
+//
+// File: score_family_x.c
+//
+// MATLAB:
+// function score = score_family_x(data,sz)
+//
+// DESCRIPTION:
+// Calculates Bayesian score for the family of tabular nodes
+// (as in log_marg_prob_node.m):
+//      data        [nsz x ndata] array
+//                  IMPORTANT:                    <--- !!!!
+//                  - parents go first                             
+//                  - values of the nodes are in the range 0..sz[i] 
+//      sz          sizes of the nodes in the family
+//      ndata       # of observations
+//      nsz         # of nodes in the family
+// with default parameters:  
+//      params{i} = { 'prior_type', 'dirichlet', 'dirichlet_weight', 1 }
+//                   ...and 'dirichlet_type','BDeu'
+//      scoring_fn = 'bayesian';
+//      etc...
+//
+// EXAMPLE:
+//   score_family_x([1 2 1; 1 2 2; 1 1 1],[2 2 2]);  // ans = -2.0794
+//
+// by Darima <darrimma@yahoo.com>, 27/12/2005 
+//
+
+#include "mex.h"
+#include "score_x.h"
+
+#define	IN_DATA	    prhs[0]
+#define IN_SZ       prhs[1]
+#define	OUT_SCORE	plhs[0]
+#if !defined(MAX)
+#define	MAX(A, B)	((A) > (B) ? (A) : (B))
+#endif
+
+void mexFunction( int nlhs, mxArray *plhs[],
+                  int nrhs, const mxArray *prhs[] )   
+{ 
+    int nsz, ndata;
+    double  *sz, *data, *score;
+	int i,j;
+    
+    /* Check for proper number of arguments */
+    
+    if (nrhs != 2) { 
+        mexErrMsgTxt("Two input arguments required."); 
+    } else if (nlhs > 1) {
+        mexErrMsgTxt("Too many output arguments."); 
+    } 
+
+    /* Assign input arguments */ 
+    
+    data   = mxGetPr(IN_DATA);
+    sz     = mxGetPr(IN_SZ);
+	ndata  = mxGetN(IN_DATA); 
+    nsz    = MAX(mxGetM(IN_SZ),mxGetN(IN_SZ));   
+
+    /* Create return argument */ 
+    
+    OUT_SCORE = mxCreateDoubleScalar(mxREAL);
+    score = mxGetPr(OUT_SCORE);
+
+    /* Do the actual computations in a subroutine */
+    
+    score_family_x(data,sz,nsz,ndata,score);
+    return;
+}
+
diff --git a/sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_x.c b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_x.c
new file mode 100644
index 00000000..b63111f6
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_x.c
@@ -0,0 +1,168 @@
+//
+// File: score_x.c
+//
+//
+// by Darima <darrimma@yahoo.com>, 27/12/2005 
+//
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include "score_x.h"
+
+void score_dag_x(double *data,double *sz,double *dag,
+    int ndata,int nsz,double* score)
+//
+// GOTO: score_dag_x.c
+// by Darima <darrimma@yahoo.com>, 27/12/2005 
+//    
+{
+	double *fdata,*fsz,*fscore;
+    int fnsz,*family; 
+	int i,j,k; 
+        
+	fdata = (double*)malloc(nsz*ndata*sizeof(double));
+	fsz = (double*)malloc(nsz*sizeof(double));
+    fscore = (double*)malloc(sizeof(double));
+    family = (int*)malloc(nsz*sizeof(int));
+	*score = 0;      
+   
+	for (j=0;j<nsz;j++) {
+        
+		// find parents of current node
+		        
+        fnsz = 0;
+		for (i=0;i<nsz;i++)
+			if (dag[i+j*nsz]==1) {family[fnsz] = i; fnsz++;}
+        family[fnsz] = j; fnsz++;
+        
+        // initialize data for current family
+        
+		for (i=0;i<fnsz;i++)
+            for (k=0;k<ndata;k++) {
+                fdata[i+k*fnsz] = data[family[i]+k*nsz];
+                fsz[i] = sz[family[i]];
+            }
+        
+		// calculater score for the family
+        
+        score_family_x(fdata,fsz,fnsz,ndata,fscore);
+        *score += *fscore;
+	}
+
+	free(fdata); free(fsz); free(fscore); free(family);
+	return;
+}
+
+void score_family_x(double *data,double *sz,
+    int nsz,int ndata,double* score)
+//
+// GOTO: score_family_x.c
+// by Darima <darrimma@yahoo.com>, 27/12/2005 
+//
+{ 
+    int self_sz, ps_sz;
+    double prior1, prior2, *count;
+    int i,j,k; double idx,tsz,N_ij;
+        
+    // self_sz - number of values of current node
+    // ps_sz   - number of configurations of parents    
+    
+    self_sz = sz[nsz-1]; 
+    ps_sz = 1; for (i=0;i<nsz-1;i++){ps_sz *= sz[i];}
+       
+    // calculate counts
+    //
+    // example: two binary parents for binary node
+    //  idx |  p1 p2 |   0   1   <-- values of the node
+    //  ---------------------
+    //   0  |  0  0  |   1   0
+    //   1  |  1  0  |   0  83
+    //   2  |  0  1  |   3   0   <-- counts
+    //   3  |  1  1  |  13   0
+    //  ^------------------------ configurations of parents
+    // count = [ps_sz x self_sz] array
+        
+    count = (double*)malloc(ps_sz*self_sz*sizeof(double));
+    for (i=0;i<self_sz*ps_sz;i++) { count[i] = 0; }
+
+    for (j=0;j<ndata;j++) {
+        
+        // for every data case:
+        // 1) calculate parent configuration index: p1_val,p2_val -> idx
+        // 2) increment corresponding count: count[idx,node_val]++
+        //
+        // example:
+        //             case1  case2  etc
+        // -----------------------------
+        // p1   |      0      1      ...
+        // p2   |      0      0      ...
+        // node |      1      1      ...
+        // 
+        // notice: array[i,j,k] -> array[i+j*ni+k*ni*nj]
+        //
+        // example 1: data[i,j] -> data[i+j*nsz]
+        //
+        // example 2: consider family with 5 parents
+        // - [p1,p2,..,p5] -> IDX5 
+        //   IDX5 = p1 + p2*p1_sz + p3*p1_sz*p2_sz + ... +
+        //          p5*p1_sz*p2_sz*p3_sz*p4_sz
+        // - [p1,p2,..,p5,node_val] -> IDXFAM
+        //   IDXFAM = IDX5 + node_val*ps_sz
+        //   count[IDX5,node_val] ->count[IDXFAM]
+        
+        idx = data[0+j*nsz]; tsz = 1;
+        for (i=1;i<nsz;i++) {tsz *= sz[i-1]; idx += data[i+j*nsz]*tsz;}
+        count[(int)idx]++;
+    }
+       
+    // calculate priors (BDeu,1)
+    
+    prior1 = 1/(double)(self_sz*ps_sz);
+    prior2 = 1/(double)(ps_sz);
+       
+    // calculate score
+    //
+    // LL = log[  PROD_j gamma(alpha_ij)/gamma(alpha_ij + N_ij)  *
+	//            PROD_k gamma(alpha_ijk + N_ijk)/gamma(alpha_ijk)  ] =
+    //    = SUM_j {  gammaln(alpha_ij)-gammaln(alpha_ij + N_ij) +
+    //         SUM_k [ gammaln(alpha_ijk + N_ijk)-gammaln(alpha_ijk) ]  }
+    //
+    // alpha_ijk  <- prior1
+    // alpha_ij   <- prior2
+    // N_ijk      <- count[j,k]
+
+    *score = 0;
+    for (j=0;j<ps_sz;j++) {    
+        N_ij = .0; 
+        for (k=0;k<self_sz;k++) {
+            N_ij += count[j+k*ps_sz];
+            *score += gammaln(prior1+count[j+k*ps_sz])-gammaln(prior1);
+        }
+        *score += gammaln(prior2)-gammaln(prior2 + N_ij);
+    }
+
+    free(count);
+    return;
+}
+
+double gammaln(double xx)
+//
+// Returns the value ln[Gamma(xx)] for xx > 0.
+// from "Numerical Recipes in C"
+//
+{
+    double x,y,tmp,ser;
+    static double cof[6]={
+        76.18009172947146,-86.50532032941677,
+        24.01409824083091,-1.231739572450155,
+        0.1208650973866179e-2,-0.5395239384953e-5};
+    int j;
+    y=x=xx;
+    tmp=x+5.5;
+    tmp -= (x+0.5)*log(tmp);
+    ser=1.000000000190015;
+    for (j=0;j<=5;j++) ser += cof[j]/++y;
+    return -tmp+log(2.5066282746310005*ser/x);
+}
diff --git a/sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_x.h b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_x.h
new file mode 100644
index 00000000..8fc1c213
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/score_dag.c/score_x.h
@@ -0,0 +1,19 @@
+//
+// File: score_x.h
+//
+//
+// by Darima <darrimma@yahoo.com>, 27/12/2005 
+//
+
+#ifndef score_x_h
+#define mex_h
+
+void score_family_x(double *data,double *sz,
+    int ndata,int nsz,double* score);
+
+void score_dag_x(double *data,double *sz,double *dag,
+    int nsz,int ndata,double* score);
+
+double gammaln(double xx);
+
+#endif // score_x_h
diff --git a/sourcecodes/bnt-master/SLP/scoring/score_dags.m b/sourcecodes/bnt-master/SLP/scoring/score_dags.m
new file mode 100644
index 00000000..acda3e0f
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/score_dags.m
@@ -0,0 +1,74 @@
+function [score, cache] = score_dags(data, ns, dags, varargin)
+% SCORE_DAGS Compute the score of one or more DAGs
+% score = score_dags(data, ns, dags, varargin)
+%
+% data{i,m} = value of node i in case m (can be a cell array).
+% node_sizes(i) is the number of size of node i.
+% dags{g} is the g'th dag
+% score(g) is the score of the i'th dag
+%
+% The following optional arguments can be specified in the form of name/value pairs:
+% [default value in brackets]
+%
+% scoring_fn - 'bayesian' or 'bic' [ 'bayesian' ]
+%              Currently, only networks with all tabular nodes support Bayesian scoring.
+% type       - type{i} is the type of CPD to use for node i, where the type is a string
+%              of the form 'tabular', 'noisy_or', 'gaussian', etc. [ all cells contain 'tabular' ]
+% params     - params{i} contains optional arguments passed to the CPD constructor for node i,
+%              or [] if none.  [ all cells contain {'prior', 1}, meaning use uniform Dirichlet priors ]
+% discrete   - the list of discrete nodes [ 1:N ]
+% clamped    - clamped(i,m) = 1 if node i is clamped in case m [ zeros(N, ncases) ]
+% cache      - data structure used to memorize local score computations (cf. SCORE_INIT_CACHE function) [ [] ]
+%
+% e.g., score = score_dags(data, ns, mk_all_dags(n), 'scoring_fn', 'bic', 'params', [],'cache',cache);
+%
+% (Caching implementation : francois.olivier.c.h@gmail.com, philippe.leray@univ-nantes.fr)
+% ("Clamped" optimisation : Derek Hoiem <dhoiem@cs.cmu.edu>)
+
+[n ncases] = size(data);
+
+% set default params
+type = cell(1,n);
+params = cell(1,n);
+cache=[];
+for i=1:n
+  type{i} = 'tabular';
+  params{i} = { 'prior_type', 'dirichlet', 'dirichlet_weight', 1 };
+end
+scoring_fn = 'bayesian';
+discrete = 1:n;
+
+isclamped = 0; % DWH
+clamped = zeros(n, ncases);
+u = [1:ncases]'; % DWH
+
+args = varargin;
+nargs = length(args);
+for i=1:2:nargs
+  switch args{i},
+   case 'scoring_fn', scoring_fn = args{i+1};
+   case 'type',       type = args{i+1};
+   case 'discrete',   discrete = args{i+1};
+   case 'clamped',    clamped = args{i+1}, isclamped = 1; %DWH
+   case 'params',     if isempty(args{i+1}), params = cell(1,n); else params = args{i+1};  end
+   case 'cache',      cache=args{i+1} ;
+  end
+end
+
+NG = length(dags);
+score = zeros(1, NG);
+
+for j=1:n
+    if isclamped %DWH
+        u = find(clamped(j,:)==0);
+    end
+    for g=1:NG
+        if isempty(dags{g})
+            score(g)=-Inf;
+        else
+            ps = parents(dags{g}, j);
+            [scor cache] = score_family(j, ps, type{j}, scoring_fn, ns, discrete, data(:,u), params{j}, cache);
+            score(g) = score(g) + scor;
+        end
+    end
+end
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/SLP/scoring/score_family.m b/sourcecodes/bnt-master/SLP/scoring/score_family.m
new file mode 100644
index 00000000..085fcf48
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/score_family.m
@@ -0,0 +1,218 @@
+function [score, cache] = score_family(j, ps, node_type, scoring_fn, ns, discrete, data, args, cache)
+% SCORE_FAMILY_COMPLETE Compute the score of a node and its parents given completely observed data
+% score = score_family(j, ps, node_type, scoring_fn, ns, discrete, data, args, cache)
+%
+% data(i,m) is the value of node i in case m (can be a cell array, if contain missing value, it uses only available complete cases for an entry)
+% args is a cell array containing optional arguments passed to the constructor,
+% or is [] if none
+% cache is a data structure used to memorize local score computations
+% (cf. SCORE_INIT_CACHE function)
+%
+% We create a whole Bayes net which only connects parents to node,
+% where node has a CPD of the specified type (with default parameters).
+% We then evaluate its score ('bic' or 'bayesian')
+% We should use a cache to avoid unnecessary computation.
+% In particular, log_marginal_prob_node for tabular CPDs calls gammaln
+% and compute_counts, both of which are slow.
+%
+% (Caching implementation : ofrancois.olivier.c.h@gmail.com, philippe.leray@univ-nantes.fr)
+%
+
+if (nargin<9 || isempty(cache)) , c=0; else c=1; end
+%tic
+if c==1
+    [b,score]=score_find_in_cache(cache,j,ps,scoring_fn);
+else
+    b=0;
+end
+%Tfind=toc
+ccc = iscell(data);
+ps = unique(ps);
+
+if b==0
+    misv = -9999;
+    if ccc, data = bnt_to_mat(data,misv); end
+    [n ncases] = size(data);
+    dag = zeros(n,n);
+    % SML added to sort ps b/c mk_bnet, learn_params use sorted ps to make
+    % CPTs    % Kevin had: if ~isempty(ps), dag(ps, j) = 1; end
+    if ~isempty(ps), dag(ps, j) = 1;, ps = sort(ps);, end
+
+    bnet = mk_bnet(dag, ns, 'discrete', discrete);
+    fname = sprintf('%s_CPD', node_type);
+    if isempty(args)
+        bnet.CPD{j} = feval(fname, bnet, j);
+    else
+        bnet.CPD{j} = feval(fname, bnet, j, args{:});
+    end
+    %tic
+    switch scoring_fn
+    case 'bic',
+        fam = [ps j];
+        if ccc,
+	    [tmp, available_case] = find(data(fam,:)==misv);
+	    available_case = mysetdiff(1:ncases, available_case);
+	else available_case = 1:ncases;
+	end
+        bnet.CPD{j} = learn_params(bnet.CPD{j}, fam, data(:,available_case), ns, bnet.cnodes);
+        %L = log_prob_node(bnet.CPD{j}, data(j,:), data(ps,:));
+	L = log_prob_node(bnet.CPD{j}, data(j,available_case), data(ps,available_case));
+        S = struct(bnet.CPD{j}); % violate object privacy
+        score = L - 0.5*S.nparams*log(length(available_case));
+    case 'bicmod',
+        fam = [ps j];
+        if ccc,
+	    [tmp, available_case] = find(data(fam,:)==misv);
+	    available_case = mysetdiff(1:ncases, available_case);
+	else available_case = 1:ncases;
+	end
+        bnet.CPD{j} = learn_params(bnet.CPD{j}, fam, data(:,available_case), ns, bnet.cnodes);
+	L = log_prob_node(bnet.CPD{j}, data(j,available_case), data(ps,available_case));
+        S = struct(bnet.CPD{j}); % violate object privacy
+        score = L - S.nparams*log(length(available_case));
+    case 'bayesian',
+        fam = [ps j];
+        if ccc,
+	    [tmp, available_case] = find(data(fam,:)==misv);
+	    available_case = mysetdiff(1:ncases, available_case);
+	else available_case = 1:ncases;
+	end
+        score = log_marg_prob_node(bnet.CPD{j}, data(j,available_case), data(ps,available_case));
+    otherwise,
+        error(['unrecognized scoring fn ' scoring_fn]);
+    end
+    %Tcalc=toc
+    %tic
+    if c==1
+%        fprintf('a\n')
+        cache=score_add_to_cache(cache,j,ps,score,scoring_fn);
+    end
+    %Tecr=toc
+% else
+%     fprintf('*\n')
+end
+
+%===========================Inner functions
+
+function [cache, place] = score_add_to_cache(cache,j,ps,score,scoring_fn)
+% [cache place] = score_add_to_cache(cache,j,ps,score,scoring_fn)
+%
+% j is the son node,
+% ps is the list of parents of j, for example [12 5 7],
+% score is the score to add for this familly.
+% scoring_fn is 'bic' or 'bayesian'.
+%
+% place = where the entry was add.
+%
+% example for 2 nodes with cache of size 5 :
+%
+% cache =
+%   Nw  b        0      0      0 --> Nw=number of writings in cache (+1) and b==1 iff the cache is full
+%   0   0        1   -239.12   1  --> 1st familly in the cache (node 1 without parents) calculate with bic
+%   0   0        2   -318.98   1
+%   1   0        2   -189.23   2  --> 3rd familly in the cache (node 2 with 1 as parent) calculate with bayésian
+%   0   1        1   -251.09   1
+% .ps2bool.      j    score  1or2 --> new entry
+%   |   |        |      |      |
+%   |   |        |      |      |___> scoring function : 1 for 'bic' or 2 for 'bayesian'
+%   |   |        |      |__________> score of the familly
+%   |   |        |_________________> son node of the familly
+%   |   |__________________________> ==1 iff node 2 is parent of son node
+%   |______________________________> ==1 iff node 1 is parent of son node
+%
+% If the cache is FULL then the new place is RanDomly choose.
+%
+% V1.1 : 5 may 2003 (O. Francois, Ph. Leray)
+
+N=size(cache,2)-3;
+L=size(cache,1)-1;
+cache_full=cache(1,2) ;
+
+place=0;
+
+if ismember(j,ps)
+    disp('This is a cyclic entry, nothing was done.');
+elseif j>N || j<=0
+    disp('This entry is not valid, nothing was done.');
+else
+    switch scoring_fn
+    case 'bic',
+        fn=1;
+    case 'bayesian',
+        fn=2;
+    otherwise,
+        fn=3;
+        %error(['unrecognized scoring fn ' scoring_fn]);
+    end
+
+    if ~cache_full
+        place=cache(1,1);
+    else
+    [ignore place]=max(rand(1,L)); place=place+1;
+    end
+
+    cache(place,:)=0;
+    cache(place,ps)=1;
+    cache(place,N+1)=j;
+    cache(place,N+2)=score;
+    cache(place,N+3)=fn;
+
+    cache(1,1)=place+1;
+    if place>L || cache(1,2)~=0
+        cache(1,2)=1;
+    end
+end
+
+
+%=========================================================================================
+function [bool, score] = score_find_in_cache(cache,j,ps,scoring_fn)
+% cache = score_find_in_cache(cache,j,ps,scoring_fn)
+%
+% V1.1 : 5 may 2003 (O. Francois, Ph. Leray)
+
+
+%tic
+L=size(cache,1)-1;
+N=size(cache,2)-3;
+
+if N<1
+    bool=0;
+    score=0;
+    return
+end
+
+parents=zeros(1,N);
+parents(ps)=1;
+%parents(N+1)=j;
+
+switch scoring_fn
+case 'bic',
+    fn=1;
+case 'bayesian',
+    fn=2;
+otherwise,
+    fn=3;
+    %error(['unrecognized scoring fn ' scoring_fn]);
+end
+
+tmp=find(cache(2:L+1,N+3)==fn);
+tmp=tmp+1;
+tmp2=find(cache(tmp,N+1)==j);
+candidats=tmp(tmp2);
+
+i=1;
+while i<=N & ~isempty(candidats)
+    tmp=find(cache(candidats,i)==parents(i));
+    candidats=candidats(tmp);
+    i=i+1;
+end
+
+%Tpre=toc
+
+bool=~isempty(candidats);
+
+if bool
+    score=cache(candidats(1),N+2);
+else
+    score=0;
+end
diff --git a/sourcecodes/bnt-master/SLP/scoring/score_find_in_cache.m b/sourcecodes/bnt-master/SLP/scoring/score_find_in_cache.m
new file mode 100644
index 00000000..61f282e9
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/score_find_in_cache.m
@@ -0,0 +1,63 @@
+function [bool, score] = score_find_in_cache(cache,j,ps,scoring_fn)
+% [bool, score] = score_find_in_cache(cache,j,ps,scoring_fn)
+% 
+% francois.olivier.c.h@gmail.com
+
+%tic
+L=size(cache,1);
+N=size(cache,2)-3;
+
+if N<1
+  bool=0;
+  score=0;
+  return
+end
+
+parents=zeros(1,N+1);
+parents(ps)=1;parents(N+1)=j;
+
+switch scoring_fn
+  case 'bic',
+    fn=1;
+  case 'bayesian',
+    fn=2;
+  otherwise,
+    fn=3;
+    %error(['unrecognized scoring fn ' scoring_fn]);     
+end
+
+%parent = str2num(num2str(parents,'%1d'));
+%[tmp y]=find(cache(:,N+3)==fn);
+%if ~isempty(tmp)
+%  [tmp2 y]=find(str2num(num2str(cache(tmp,1:N+1),'%1d'))==parent);
+%  candidats=tmp(tmp2);
+%else
+%  candidats=[];
+%end
+
+[tmp y]=find(cache(2:L,N+3)==fn);
+tmp=tmp+1;
+[tmp2 y]=find(cache(tmp,N+1)==j);
+candidats=tmp(tmp2);
+if ~isempty(candidats)
+  for i=1:N      % N=size(cache,2)-3;
+    if ~isempty(candidats)
+      [tmp2 y]=find(cache(tmp,i)==parents(i));
+      candidats=intersect(candidats,tmp(tmp2));
+    end
+  end
+end
+
+%Tpre=toc
+
+if ~isempty(candidats)
+  bool=1;
+else
+  bool=0;
+end
+
+if bool
+  score=cache(candidats(1),N+2);
+else
+  score=0;
+end
\ No newline at end of file
diff --git a/sourcecodes/bnt-master/SLP/scoring/score_init_cache.m b/sourcecodes/bnt-master/SLP/scoring/score_init_cache.m
new file mode 100644
index 00000000..fcbca268
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/scoring/score_init_cache.m
@@ -0,0 +1,29 @@
+function cache = score_init_cache(N,L)
+% SCORE_INIT_CACHE generate an empty cache for local computation in structure learning
+% cache = score_init_cache(number_of_nodes,cache_size)
+%
+% For 2 nodes with cache of size 5 :
+%
+% cache =
+%   Nw  b        0      0      0 --> Nw=number of writings in cache (+1) and b==1 iff the cache is full
+%   0   0        1   -239.12   1 --> 1st familly in the cache (node 1 without parents) calculate with bic
+%   0   0        2   -318.98   1
+%   1   0        2   -189.23   2 --> 3rd familly in the cache (node 2 with 1 as parent) calculate with bayesian
+%   0   1        1   -251.09   1
+%   0   0        0      0      0 --> empty entry
+%   |   |        |      |      |
+%   |   |        |      |      |___> scoring function : 1 for 'bic', 2 for 'bayesian', ...
+%   |   |        |      |__________> local score of the familly
+%   |   |        |_________________> son node of the familly
+%   |   |__________________________> ==1 iff node 2 is parent of son node
+%   |______________________________> ==1 iff node 1 is parent of son node
+%
+%
+% V1.1 : 6 may 2003 (O. Francois - francois.olivier.c.h@gmail.com, Ph. Leray - philippe.leray@univ-nantes.fr)
+%
+%
+
+cache=zeros(L+1,N+3);
+cache(1,1)=2;
+
+% using a sparse matrix does not improve performances