function m=steep_desc(m,select,treshold,eta,do_plot);
%STEEP_DESC performs a fitting of the model by means of a steepest descent algorithm
%    
%    
%    M=STEEP_DESC(M,SELECT,TRESHOLD,ETA,DO_PLOT) performs a Levenbergh Marquardt
%    optimisation of the model M. A subset of the parameters defined by SELECT
%    is taken into account. SELECT is a binary number wxyz. w is set for 
%    the parameters related to the centers. x for the covariance matrices,
%    y for the linears consequents and z for the affine terms. THRESHOLD is the
%    minimum difference between two consecutive normalised mean square error
%    before the optimisation is stopped. If DO_PLOT is greater than  0, an
%    intermediary plot is drawed every DO_PLOT steps.
%    
%    

%MAN_PAGE_BEGIN
%
%   @purpose performs a fitting of the model by means of a steepest descent algorithm.
%
%
%   @synopsis	m=steep_desc(m,select,treshold,eta,do_plot)
%   @description  performs a Levenbergh Marquardt
%   optimisation of the model M. A subset of the parameters defined by SELECT
%   is taken into account. SELECT is a binary number wxyz. w is set for 
%   the parameters related to the centers. x for the covariance matrices,
%   y for the linears consequents and z for the affine terms. THRESHOLD is the
%   minimum difference between two consecutive normalised mean square error
%   before the optimisation is stopped. If DO_PLOT is greater than  0, an
%   intermediary plot is drawed every DO_PLOT steps.
%
%MAN_PAGE_END   



%   Copyright (c) 1998 by Antoine Duchateau			
%	$Revision: 0.1$  $Date: 13/09/98 12:02
%
%	All rights reserved

check(m);
for no=1:get(m,'n_out'),
	if strcmpi(m.description{no}.model_code{1},'projected'),
		error('This function only supports product space antecedents');
	end
end

if nargin < 2, select = 3; end
if nargin < 3, treshold = 0.001; end
if nargin < 4, eta = 0.01; end
if nargin < 5, do_plot=0; end

m=normalise(m);

if do_plot,
	ax=plot(m);
	option=get(ax,'userdata');
end
	
[in,out]=get_regressors(m);

for j=1:get(m,'n_out'),
	old_err = realmax;
	new_err = error(m,j);
	p = get_params(m,select,j);
	
	%allocate space
	dfdp = zeros(size(p,1),size(in{j},1));
	y = zeros(size(in{j},1),1);
	num = 0;
	
	test_m=m;
	
	while((new_err<old_err*(1-treshold))|(num<20)),
		old_err = new_err;
		num = num+1;
		
		%compute the derivatives
		for ii = 1:size(in{j},1),
			[dfdp(:,ii),y(ii)]=jacob_params(in{j}(ii,:),test_m.description{j}.centers, test_m.description{j}.ivariances, test_m.description{j}.linears,uint8(select));
		end

		indiv_errors = (y - out{j})';

		deriv = sum((indiv_errors(ones(1,size(p,1)),:).*dfdp)')';
		eta=eta*10;
		
		new_err = 2*old_err;
		
		%Adjust the learning speed
		while (new_err>old_err)&(eta>1e-10),
			
			eta=eta/10;
			test_p = p - eta * deriv;
			test_m = set_params(m,test_p,select,j);
			try,
				new_err = error(test_m,j);
				if ~isfinite(new_err),
					new_err = realmax;
					test_p = p;
				end
			catch,
				new_err = realmax;
				test_p = p;
			end
			
		end
		
		eta=eta*20;
		p = test_p;
		
		if do_plot&(rem(num,do_plot)==do_plot-1),
			plot(test_m,[],option);
			drawnow;
		end
				
	end
	
	m = set_params(m,p,select,j);
	
end

m=denormalise(m);

if do_plot,
	ax=plot(m);
end

