function [net,errs,erts]=traintst(net, x, y, xt, yt, par, beta, method)
%TRAINTST	Train and test the neural network.
%
%	[net,errs,erts,code] = TRAINTST (net, xtr, ytr, xt, yt, par, method);
%
%	Example: [net,e1,e2] = TRAINTST (net, x, y, xt, yt, [0.1,1000,0.01,1e-4]);
%
%	Input: 
%	  xtr, ytr: training data
%	  xt,  yt : testing data
%	  par: training parameters
%		par(1): training rate, default 0.1
%		par(2): training epochs, default 200
%		par(3): weight decay, default 0.01
%		par(4): minimum error, default 0.0001
%	  method: training method, 'seq' or 'bat'
%	Output: net, training/testing error.
%
%	See also: NEWNET, INITNET, FORWARD, BACKWARD, EPOCH, TRAINNET.

%	Ling Li, Caltech
%	10/21/96, 10/09/00

defaultpar = [0.1, 200, 0.01, 0.0001];
if nargin < 8
	method = 'seq';
end

if nargin < 6
	par = defaultpar;
elseif length(par) < length(defaultpar)
	par = [par, defaultpar(length(par)+1:length(defaultpar))];
end
lr = par(1);
epochs = par(2);
eta = par(3);
minerr = par(4);

if size(x, 1) ~= size(y, 1)
	error('input x and y do not agree');
end

errs = zeros(1, epochs); erts = errs;
err0 = sum(sum((forward(net, x) - y) .^ 2)) / size(x, 1);
ert0 = sum(sum((forward(net, xt) - yt) .^ 2)) / size(xt, 1);
ep = 0; disp(['0/' int2str(epochs) ': error = ' num2str(err0)]);

err = err0;
while (ep < epochs & err > minerr)
	ep = ep + 1;
	[net, err] = epoch(net, x, y, lr, eta, beta, method);
	errs(ep) = err;
	erts(ep) = sum(sum((forward(net, xt) - yt) .^ 2)) / size(xt, 1);
	
	if mod(ep, 50) == 0
		disp([int2str(ep) '/' int2str(epochs) ': error = ' num2str(err)]);
	end
end
if mod(ep, 50)
	disp([int2str(ep) '/' int2str(epochs) ': error = ' num2str(errs(ep))]);
end
errs = [err0, errs(1:ep)];
erts = [err0, erts(1:ep)];

figure; hold on;
plot(0:ep, errs, 'b-');
plot(0:ep, erts, 'r--');
legend('training error', 'testing error');
xlabel('number of epochs');
ylabel('error');
title([int2str(net.neurons(2)) ' hidden neurons, lr = ' num2str(lr) ', decay = ' num2str(eta) ...
	', beta = [' num2str(beta{1}) ', ' num2str(beta{2}) ']']);