function [Pesos_new,Error_sal]=perceptron_train(In,Sal,ErrorMax,alfa,Umbral,Pesos0,MAX)
% PERCEPTRON	Ejemplo Doctorado 2001/2002
% 
%  [Pesos_new,Errores]=perceptron_train((In,Sal,ErrorMax,alfa,Umbral,Pesos0)
%
%	In:      (NxM) Entrada para aprendizaje 
%              N: Número de patrones de aprendizaje
%              M: Número de neuronas de entrada
%	Sal:	   (NxK) Salida para aprendizaje
%              N: Número de patrones de aprendizaje (una salida por patrón)
%              K: Número de neuronas de salida
%	ErroMax:	Error máximo permitido
%   alfa:       Velocidad de aprendizaje (por defecto 1)
%	Umbral:     0,1 indica si hay o no
%	Pesos0:    ((M*K+K*Umbral)x1) Pesos iniciales
%   MAX:        Número máximo de iteraciones (defecto 300)
%
%
%	Pesos_new:	Pesos calculados para la red en cada iteración.
%   Errores:    Error de la red en cada iteración.
%               Nota: se cuenta como una iteración la muestra de todos los
%               datos de entrada a la red.
%
%
%  Si se utiliza adaline_train((In,Sal,ErrorMax) entonces alfa es 1, no 
%  hay umbral y los pesos son aleatorios. 
%  El número máximo de iteraciones por defecto es de 300. 
%  Si no se introduce pesos iniciales o Pesos0=[], se calculan
%  aleatoriamente.

% 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


[filas,col]=size(In);
[filas_sal,col_sal]=size(Sal);

if (nargin < 4),
   alfa=1; 
end;

if (nargin < 5),
   Umbral=0; 
end;

if (nargin<6),  
   Pesos=rand(col*col_sal+Umbral*col_sal,1);
else
   Pesos=Pesos0;
end   

if (nargin<7),
      MAX=300;
end;      

if (Umbral)
   In=[ones(filas,1),In];
end;   

cambio=1;   % Indicará si hay algún cambio en los pesos
cont=0;		% Indica el número de intentos;

while ( (cambio) & (cont<MAX) )
cambio=0;

for i=1:filas,
   SalD=Sal(i,:);
   
   Salida=perceptron(In(i,2:3),Pesos);
   
   Error(i)=SalD - Salida;
   if (Error(i)~=0),
      Pesos=Pesos+ alfa* Error(i) * In(i,:)';
      cambio=cambio+1;
   end;
   
   % Pesos por cada vez que se realiza una iteración
   %Pesos_new(filas*cont+i,:)=Pesos';
   %Error_sal(filas*cont+i,:)=Error';
   
end; %for

% (error global de la red)
    %Salida=perceptron(In(:,2:3),Pesos);
    %cambio=sum(abs(Sal - Salida));

if ( cambio <= ErrorMax ),
  cambio=0; % Aunque haya cambio si el error total es menor de ErrorMax salgo
end;

cont=cont+1;
% Pesos cada vez que se muestra un conjunto de patrones
Pesos_new(cont,:)=Pesos';
Error_sal(cont,:)=cambio;

end; % while

if (cont==MAX), disp('Error el Perceptrón no converge'); end;
