function [PesosNeuronas,EvolPesos,EvolRho,EvolVecindad]=som_train(PesosNeuronas,Entrada,rho,nivelVecindad,decrementoNivelVecindad,maxIteraciones,faseConvergencia)
% function [PesosNeuronas,EvolPesos,EvolRho,EvolVecindad]=som_train(PesosNeuronas,Entrada,rho,nivelVecindad,decrementoNivelVecindad,maxIteraciones,faseConvergencia)
%
% Función de entrenamiento de la red SOM mono o bi-dimensional
%
% [PesosNeuronasFIN,EvolPesos,EvolRho,EvolVecindad]=som_train(PesosNeuronas,Entrada,rho,nivelVecindad,decrementoNivelVecindad,maxIteraciones,faseConvergencia);
% 
% PesosNeuronas:            (NxMxE) Representa la red SOM. Se le indica los 
%                           valores de los pesos de la entrada a cada una de 
%                           las neuronas. Existen NxM neuronas en un plano 
%                           de forma NxM. El tamaño del vector de entrada
%                           es de E.
% Entrada:                  (DxE) La entrada a la SOM para realizar el
%                           aprendizaje. Se introducen D vectores de tamaño
%                           E.
% rho:                      Velocidad de aprendizaje.
% nivelVecindad:            Nivel de vecindad.
% decrementoNivelVecindad:  Variación del nivel de vecindad por iteración.
% maxIteraciones:           Número máximo de iteraciones.
% faseConvergencia:         Número de la iteración en la que comienza la
%                           fase de convergencia (desde 1 a faseConvergencia 
%                           es la de Ordenación y es en la que se realiza la 
%                           variación de rho).
%
%
% PesosNeuronasFIN:         (NxMxE) Pesos finales de la red
% EvolPesos:                (maxIteracionesxprod(N,M,E)) Vector fila con
%                           los pesos de la SOM en cada iteración.
% EvolRho:                  (maxIteracionesx1) Evolución de rho.
% EvolVecindad:             (maxIteracionesx1) Evolución de la Vecindad.



% 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




tam=size(PesosNeuronas);
tamRed=tam(1:2);

formaRed = ones(tamRed);
tamEntrada = size(Entrada);

numIter = 1;

while numIter <= maxIteraciones
    for i=1:tamEntrada(1)
            neuronaGanadora = ganadora2(PesosNeuronas,Entrada(i,:));
            %Se calculan las vecinas
            vec = vecinas(formaRed,neuronaGanadora,nivelVecindad);
            mascara = vec>0;
            %Se mueven la neurona ganadora y las vecinas
            for ii=1:tamEntrada(2),
                varPesos = rho*vec/(nivelVecindad+1).*(Entrada(i,ii).*formaRed - PesosNeuronas(:,:,ii));
                varPesos = varPesos.*mascara;
                PesosNeuronas(:,:,ii) = PesosNeuronas(:,:,ii) + varPesos;
            end;

            % Se guardan por columnas:      
            EvolPesos(numIter,:)=reshape(PesosNeuronas,1,tamRed(1)*tamRed(2)*tamEntrada(2));
            EvolRho(numIter)=rho;
            EvolVecindad(numIter)=nivelVecindad;
            numIter = numIter + 1;
            
            fprintf('Número de iteraciones: %d/%d\n',numIter,maxIteraciones);
                        
            if (numIter <= faseConvergencia),
                if nivelVecindad > 0
                    nivelVecindad = nivelVecindad - decrementoNivelVecindad;
                    if nivelVecindad==0, nivelVecindad=0; end;
                end
            end
            
            
            
            % -----------------------------------------------------------
            if (0),
                
                if ejemplo==7,
                figure(f);
                clf(f);
                dibujarptos(xEntrada,yEntrada,PesosNeuronas(:,:,1),PesosNeuronas(:,:,2),fondo);
                fprintf('Número de iteraciones: %d/%d\n',numIter,maxIteraciones);
                pause(0.001);
                if ((numIter==4900)|(numIter==1)|(numIter==100)),pause; end;
                end;
                
                if ejemplo==4,
                    plot(xEntrada,yEntrada,'b.',PesosNeuronas(:,:,1),PesosNeuronas(:,:,2),'r*');
                    hold on;
                    fprintf('Número de iteraciones: %d/%d\n',numIter,maxIteraciones);
                    pause;
                end;
                
                if ejemplo==1,
                    dibujarcolor(PesosNeuronas);
                    pause(0.001);
                end;
            end
    end
end