function [MI,R,M ] = ConditionallyIndependent_MutualInformation( LGObj,Var1,Var2,ConditionalVar )
% VarData1,VarData2,and ConditionalData must have the same number of rows
% I(VarData1,VarData2|ConditionalData )
if nargin == 3 || isempty( ConditionalVar ) == 1
[MI,R,M ] = MarginallyIndependent_MutualInformation( LGObj,Var1,Var2);
return
end
MI = 0;
LG = struct( LGObj );
N = LG.CaseLength;
OriginalData = LG.VarSample;
UsedSample = DiscardNoneExist( LG.VarSample,[ Var1,Var2,ConditionalVar ] );
M = N - sum( UsedSample );
Range1 = LG.VarRange( Var1,: );
Dim1 = LG.VarRangeLength( Var1 );
Range1 = Range1( 1:Dim1 );
Range2 = LG.VarRange( Var2,: );
Dim2 = LG.VarRangeLength( Var2 );
Range2 = Range2( 1:Dim2 );
R =( Dim1 -1 ) * ( Dim2 - 1 );
R = R * prod( LG.VarRange( ConditionalVar ));
% The location of the first unprocessed sample, it accelerates the
% searching.
d = 1 ;
while d <= N
Frequency = zeros( Dim1,Dim2 );
while d <= N && UsedSample( d ) == 1
d = d + 1;
end
if d > N,break;end
ParentValue = OriginalData( d, ConditionalVar );
for t1 = 1:Dim1
if Range1( t1 ) == OriginalData( d,Var1 )
break;
end
end
for t2 = 1:Dim2
if Range2( t2 ) == OriginalData(d, Var2 )
break;
end
end
Frequency( t1,t2 ) = 1;
% VarValue
UsedSample( d )=1;
d = d + 1;
if d > N,break;end
% test whether the class value in Sample(t) is the same as VarValue or not.
for t = d:N
if UsedSample( t )==0
if ParentValue == OriginalData( t, ConditionalVar )
t1 = find( Range1 == OriginalData( t,Var1 ));
t2 = find( Range2 == OriginalData( t,Var2 ));
Frequency(t1,t2) = Frequency(t1,t2) + 1;
UsedSample(t) = 1;
%Frequency
end
end
end
%UsedSample
%Frequency
%Fu = zeros(Dim1(1),1); Fv = zeros(1,Dim2(1));
Fu = sum( Frequency,2 );
Fv = sum( Frequency,1 );
Sum= sum(Fu);
% 1/20 * log2(1*2/1*1);
for u= 1 : Dim1
for v=1 : Dim2
if Frequency(u,v) ~= 0 % it also makes sure Fu(u)~=0 and Fv(v) ~=0
MI = MI + ( Frequency(u,v)/M ) * log2( Frequency(u,v)*Sum / ( Fu(u)*Fv(v) ) );
end
end
end
% WI
end
end