function [W,Error,ErrorMin]=mlpbackprop(netp,X,d,Xv,dv,Xt,dt);

%
% Back-propagation algorithm for training MLP-NNs.
%
% Inputs:    netp - A vector [m,n], where m is the number of hidden units and n is the number of output units;  
%               X - Training samples. Each pattern is a column of X;
%               d - Target or Desired System output (row vector);
% (Optional):  Xv - Validation set;
%              dv - Validation Target;
%              Xt - Input test samples;
%              dt - Target test;
%
% Output: W - Cell with the synaptic weight vectors;
%     Error - Vector with the MSE by epoch;
%

[N,K]=size(X);

J=netp(1); L=netp(2); 
if length(netp)>2
  itmax=netp(3);
else
  itmax=100;
end 
clear netp;

% Initialization;
W{1}=(3/sqrt(N+1))*(2*rand(J,N+1)-1);
W{2}=(3/sqrt(J+1))*(2*rand(L,J+1)-1);

Kv=0; Kt=0;
ErrorMin=inf;
if nargin>3
  X=[X,Xv];
  Kv=size(Xv,2);
  clear Xv;
  ErrorMin=ones(2,1)*inf;
  if nargin>5
    X=[X,Xt];
    Kt=size(Xt,2);
    clear Xt;
    ErrorMin=ones(3,1)*inf;
  end
end

% Backprop parameters
rhoatual=0.01;
rhoanterior=rhoatual*0.8;

it=0; Terminate=0;
dWanterior{1}=zeros(J,N+1);
dWanterior{2}=zeros(L,J+1);

% Network evaluation...
% Hidden Layer;
neth=W{1}*[X;ones(1,K+Kv+Kt)];
Z=tanh(neth);
% Output Layer;
neto=W{2}*[Z;ones(1,K+Kv+Kt)];
Y=tanh(neto);

while (it<=itmax)&(~Terminate)
  % Iteration Counter...
  it=it+1;
  
  Kind=randperm(K);
  for i=1:K 
    % Select k;
    k=Kind(i);
    neth=neth(:,k);
    Z=Z(:,k);
    neto=neto(:,k);
    Y=Y(:,k);
  
    % Backpropagate the Error...
    gamma=(d(:,k)-Y).*((1+Y).*(1-Y));
    
    % Updating the heights of the hidden layer...
    dWatual{1}=((W{2}(:,1:J)'*gamma).*((1+Z).*(1-Z)))*[X(:,k);1]';
    W{1}=W{1}+rhoatual*dWatual{1}+rhoanterior*dWanterior{1};
    dWanterior{1}=dWatual{1};
    % Updating the heights of the output layer...
    dWatual{2}=gamma*[Z;1]';
    W{2}=W{2}+rhoatual*dWatual{2}+rhoanterior*dWanterior{2};
    dWanterior{2}=dWatual{2};
  
    % Network evaluation...
    % Hidden Layer;
    neth=W{1}*[X;ones(1,K+Kv+Kt)];
    Z=tanh(neth);
    % Output Layer;
    neto=W{2}*[Z;ones(1,K+Kv+Kt)];
    Y=tanh(neto);
  end
      
  Error(it,1)=norm(d-Y(:,1:K));
  disp(sprintf('Iteration: %d, Training Error = %2.4f (%2.4f)', it, Error(it,1),sum(abs(ceil(d)-ceil(Y(:,1:K))))))
end