function [Pesos_new,Error_sal]=adaline_train(In,Sal,ErrorMax,alfa,Umbral,Pesos0,MAX)
% Aprendizaje de una Red ADALINE
% 
%  [Pesos_new,Errores]=adaline_train((In,Sal,ErrorMax,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 slida 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) | isempty(Pesos0)),  
   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;   

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

while ( (seguir) & (cont<MAX) )

for i=1:filas,
   SalD=Sal(i,:);
   
   Salida=adaline(In(i,2:3),Pesos);
   %Salida=adaline(In(i,2:3),Pesos,3);
   
   Error=SalD - Salida;
   Pesos=Pesos+ alfa* Error * In(i,:)';
   
end;

Salida=adaline(In(i,2:3),Pesos);
Error= Sal - Salida;
if ( (sum(abs(Error))/(2*filas)) < ErrorMax ),
  seguir=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,:)=sum(abs(Error))/(2*filas);

end; % while

if (cont==MAX), disp('Error la adaline no converge'); end;
cont, Error