% 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 [v,Ui, distancia, iteraciones, Jcost] = fuzzy_clustering (X,c,m,e,vEstimados,DatosClasificados,iterMax)
  
  [N,n] = size(X);
  X1 = ones(N,1);

  if DatosClasificados == false
     % inicio de los centros de forma aleatoria
     Me = mean(X);             %valor medio de los datos (1,n)
     Md = max(abs(X - ones(N,1)*Me)); %maxima distancia en el conjunto de datos
     rand('state',0)
     v = 2*(ones(c,1)*Md).*(rand(c,n)-0.5) + ones(c,1)*Me;
  else
     % los datos han sido ya clasificados y los centros se inicializan a
     % los valores de los centros de las clases, existentes
     v = vEstimados; %ya se conocen de una clasificación previa
  end
     
  % Inicializar la matriz de partición fuzzy 
  for j = 1 : c,
    xv = X - X1*v(j,:);
    d(:,j) = sum((xv*eye(n).*xv),2);
  end;
  d = (d).^(-2/(m-1));
  Ui = (d ./ (sum(d,2)*ones(1,c)));

  Uf = zeros(N,c);               % matriz particion
  iter = 0;                      % iteraciones

  J(1) = 0; %para evitar una falsa asignación de J
  % Iterar 
  while  (max(max(Ui-Uf)) > e) && (iter <= iterMax)
    iter = iter + 1;
    Uf = Ui;
    % Calcular centros
    Um = Uf.^m;
    sumU = sum(Um);
    v = (Um'*X)./(sumU'*ones(1,n));
    for j = 1 : c,
      xv = X - X1*v(j,:);
      d(:,j) = sum((xv*eye(n).*xv),2);
    end;
    distancia=sqrt(d);
    J(iter) = sum(sum(Ui.*d));

    % Actulizar Ui
    d = d.^(-2/(m-1));
    Ui = (d ./ (sum(d,2)*ones(1,c)));
  end
  iteraciones = iter;
  Jcost = J;
  
  
