% APRENDIZAJE AUTOMÁTICO (Gonzalo Pajares y Jesús M. de la Cruz, Eds.)
% Editorial: RA-MA
% Capítulo 4: Redes Neuronales Artificiales
% Autores: José Antonio López Orozco



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%  SELECCIÓN DEL EJEMPLO %%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Ejemplo: 
% 1 : Mapa de colores obtenido de una serie de colores en la entrada
% 2 : Aprendizaje competitivo sin influencia en ninguna vecina
% 3 : Captura de la estructura de la información de entrada (cuadrado)
% 4 : Captura de la estructura de la información de entrada (arandela)


Ejemplo=4; %1%2;%3;%4


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%  PREPARACIÓN DE LOS DATOS DE ENTRADA Y PARÁMETROS DE LA RED %%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if Ejemplo==1,  % -- Mapa de colores obtenido de una serie de colores en la entrada --
    rho = 0.1;
    nivelVecindad = 10;
    decrementoNivelVecindad = 0.01;
    
    Entrada=load('colores.txt');
    
    tamRed = [20 20];
    maxIteraciones = 500;
    faseConvergencia=400;
    
    frecuenciaPintado = 10;
    
    % Colores RGB:
    R_peso = rand(tamRed)*255;
    G_peso = rand(tamRed)*255;
    B_peso = rand(tamRed)*255;
    PesosNeuronas(:,:,1)=R_peso;
    PesosNeuronas(:,:,2)=G_peso;
    PesosNeuronas(:,:,3)=B_peso;
    
elseif Ejemplo==2  % -- Aprendizaje competitivo sin influencia en ninguna vecina --
    rho = 0.3;
    nivelVecindad = 0;
    decrementoNivelVecindad = 0;
    
    puntos=load('puntosBasicos.txt');
    xEntrada=puntos(1,:);
    yEntrada=puntos(2,:);
    Entrada=[xEntrada', yEntrada'];
    
    tamRed = [1 2];
    frecuenciaPintado = 4;
    maxIteraciones = 20;
    faseConvergencia=20;
    fondo=[];
    
    %Inicializamos todas las neuronas situándolas en una posición aleatoria
    rand('seed',1);
    %dentro del rectángulo dado por los vértices (0,0) y (9,9)
    %xNeuronas = rand(tamRed)*9;
    %yNeuronas = rand(tamRed)*9;
    xNeuronas=[5 5];
    yNeuronas=[3 7];
    PesosNeuronas(1:tamRed(1),1:tamRed(2),:)=[xNeuronas' yNeuronas'];
    
elseif ((Ejemplo==3) | (Ejemplo==4)) % -- Captura de la estructura de la información de entrada --
    rho = 0.1;
    nivelVecindad = 5;
    decrementoNivelVecindad = 0.001;
    
    maxIteraciones = 10000;
    faseConvergencia=5000;
    
    if Ejemplo==3,
    % EJEMPLO A:
    %Aqui obtenemos puntos del rectángulo dado por los vértices (0.5,1) y (2.5,2)
    fondo='cuadrado';
    xEntrada = rand(1,400)*2+0.5;
    yEntrada = rand(1,400)+1;
    Entrada=[xEntrada', yEntrada'];
    end;
    if Ejemplo==4,
    % EJEMPLO B:
    %ejemplo con un circulo con agujero en medio:
    fondo='circulo';
    puntos=load('puntosCirculo.txt');
    xEntrada=puntos(1,:);
    yEntrada=puntos(2,:);
    Entrada=[xEntrada', yEntrada'];
    end;
    
    tamRed = [10 10];%[5 5];

    frecuenciaPintado = 10;
    
    
    %Inicializamos todas las neuronas situándolas en una posición aleatoria
    rand('seed',1);
    %dentro del rectángulo dado por los vértices (0,0) y (3,3)
    xNeuronas = rand(tamRed)*3;
    yNeuronas = rand(tamRed)*3;
    PesosNeuronas(:,:,1)=xNeuronas;
    PesosNeuronas(:,:,2)=yNeuronas;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%  ENTRENAMIENTO DE LA SOM %%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   

[PesosNeuronasFIN,EvolPesos,EvolRho,EvolVecindad]=som_train(PesosNeuronas,Entrada,rho,nivelVecindad,decrementoNivelVecindad,maxIteraciones,faseConvergencia);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%  REPRESENTACIÓN DE LOS RESULTADOS %%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

f=figure;
tamEntrada = size(Entrada);

% ---------------------- Evolución del Aprendizaje -----------------------
tamPesos= size(EvolPesos);
for numIter=1:tamPesos(1),
    
    Pesos=reshape(EvolPesos(numIter,:),tamRed(1),tamRed(2),tamEntrada(2));

if (rem(numIter,frecuenciaPintado)== 0)||(numIter==1),
                
switch Ejemplo,
   case 1,
       % ---------------------------------------------------------
        figure(f);
        clf(f);
        dibujarcolor(Pesos);
        pause(0.001);
       
   case 2,
       % ---------------------------------------------------------
       figure(f);
       plot(xEntrada,yEntrada,'b.',Pesos(:,:,1),Pesos(:,:,2),'r*');
       hold on;

       pause;
       
   case {3,4}
       % ---------------------------------------------------------

       figure(f);
       clf(f);
       dibujarptos(xEntrada,yEntrada,Pesos(:,:,1),Pesos(:,:,2),fondo);
       %fprintf('Número de iteraciones: %d\n',numIter);
       pause(0.001);
       if ((numIter==4900)|(numIter==1)|(numIter==100)),pause; end;   

end; %case 

fprintf('Número de iteraciones: %d/%d\n',numIter,maxIteraciones);
end; %if
end; %for

% -------------------- Análisis de la red resultante ---------------------
switch Ejemplo,
   case 1,
       % ---------------------------------------------------------
       % Dibujo de los representantes de los colores de entrada
       [Sal,patron]=som(PesosNeuronasFIN,Entrada);
       hold on, plot(Sal(:,1)+0.5,Sal(:,2)+0.5,'ok'); hold off;
       
    case {3,4}
       % ---------------------------------------------------------
       % Encontrar la salida de la red (el representante) de un conjunto de 
       % entradas después del aprendizaje:
       
       % 5 puntos al azar:
       if Ejemplo==3,
            % EJEMPLO A:
            % Rectángulo dado por los vértices (0.5,1) y (2.5,2)
            xEntradaPrueba = rand(1,5)*2+0.5;
            yEntradaPrueba = rand(1,5)+1;
            EntradaPrueba=[xEntradaPrueba', yEntradaPrueba'];
       end;
       if Ejemplo==4,
            % EJEMPLO B:
            % Circulo con agujero en medio:
            ipto=round(rand(5,1)*tamEntrada(1)+1);
            xEntradaPrueba=puntos(1,ipto);
            yEntradaPrueba=puntos(2,ipto);
            EntradaPrueba=[xEntradaPrueba', yEntradaPrueba'];
       end;
       [neuronaGanadora,patronGanadora]=som(PesosNeuronasFIN,EntradaPrueba); 
       hold on, 
       plot(EntradaPrueba(:,1),EntradaPrueba(:,2),'.m')
       plot(patronGanadora(:,1),patronGanadora(:,2),'om')
       hold off 
end; %case
disp('Fin de la representación gráfica');