% APRENDIZAJE AUTOMÁTICO: UN ENFOQUE PRÁCTICO
% Autores: Gonzalo Pajares, María Guijarro, P. Javier Herrera y Jesús M. de la Cruz
% Copyright RA-MA, 2010
% Capítulo 2: APRENDIZAJE ESTADÍSTICO

function Cvalidez = validezFuzzy(X,v,Ui,distancia,m,c)
%validation of the clustering

N = size(Ui,1); %numero de muestras
n = size(v,2);

%coeficiente de partición (CP)
     f = Ui.^m;
     CP = 1/N*sum(sum(f));
     
%coeficiente de entropía (CE)
     f = Ui.*log(Ui);
     CE = -1/N*sum(sum(f));
     
     Cvalidez.CP = CP;
     Cvalidez.CE = CE;   
        
%indice particion(SC)
     ni = sum(Ui);                        % cardinalidad fuzzy
     si = sum(distancia.*Ui.^(m/2));      % variación fuzzy 
     pii=si./ni;
     mask = zeros(c,n,c);                 % separación de los clusteres 
     for i = 1:c
         for j =1:c
             mask(j,:,i) = v(i,:);
         end
         dist(i) = sum(sum((mask(:,:,i) - v).^2));
     end
     s = dist;
     
     SC = sum(pii./s);

 % índice de separación (S)
     S = sum(pii)./(N*min(dist));

 % índice de Xie y Beni (XB)
     XB = sum((sum(distancia.*Ui.^2))./(N*min(distancia)));
    
     % coeficientes    
     Cvalidez.SC = SC;
     Cvalidez.S = S;
     Cvalidez.XB = XB;    
        
 % Dunn's index (ID)
     %%for identification of compact and well separated clusters
     [m,label] = min(distancia');%crisp clustering(Kmeans)

     for i = 1:c
        index=find(label == i);
        dat{i}=X(index,:);
        meret(i)= size(dat{i},1);
     end
     mindistmatriz =ones(c,c)*inf;
     mindistmatriz2 =ones(c,c)*inf;
        
     for cntrActualClust = 1:c
         for cntrOtrosClust = (cntrActualClust+1):c
             for cntrActualPoints = 1:meret(cntrActualClust)
                 dd = min(sqrt(sum([(repmat(dat{cntrActualClust}(cntrActualPoints,:),meret(cntrOtrosClust),1) ...
                 -dat{cntrOtrosClust}).^2]')));
                 % calcular distancias para el índice alternativo de Dunn 
                 dd2 = min(abs(distancia(cntrActualClust,:)-distancia(cntrOtrosClust,:)));
                     
                 if mindistmatriz(cntrActualClust,cntrOtrosClust) > dd
                    mindistmatriz(cntrActualClust,cntrOtrosClust) = dd;
                 end
                 if mindistmatriz2(cntrActualClust,cntrOtrosClust) > dd2
                    mindistmatriz2(cntrActualClust,cntrOtrosClust) = dd2;
                 end
             end
          end
      end

      minimaDist = min(min(mindistmatriz));
      minimaDist2 = min(min(mindistmatriz2));
        
      maxDispersion = 0;
      for cntrActualClust = 1:c
         DispersionActual = 0;
         for cntrActualPoints1 = 1:meret(cntrActualClust)
            dd = max(sqrt(sum([(repmat(dat{cntrActualClust}(cntrActualPoints1,:),meret(cntrActualClust),1) ...
                         -dat{cntrActualClust}).^2]')));
            if DispersionActual < dd
               DispersionActual = dd;
            end
            if maxDispersion < DispersionActual
               maxDispersion = DispersionActual;
            end
         end
      end

      ID = minimaDist/maxDispersion;
      
      % índice alternativo de Dunn
      IDA = minimaDist2/maxDispersion;
      
      %resultados
      Cvalidez.ID = ID;
      Cvalidez.IDA = IDA;   
       


