function [Vnew,parnew,stop,delta,lambda,tlam]=...
msearch(V,z,par,struc,psi,e,delta,algorithm,lambdaold,tlamold,dispmode)
%MSEARCH   Searches for a lower value of the criterion function
%
%	[TH,ST] = search(Z,TH,G,LIM)
%
%	TH : New parameter giving a lower value of the criterion
%	ST=1 : No lower value of the criterion could be found.
%
%	The routine evaluates the prediction error criterion at values
%	along the G-direction, starting at TH. It is primarily intended
%	as a subroutine to MINCRIT. See PEM for an explanation of the
%	arguments.

%	L. Ljung 10-1-86,9-25-93
%	Copyright 1986-2000 The MathWorks, Inc.
%	$Revision: 1.8 $ $Date: 2000/08/24 12:53:43 $

% *** Set up the model orders ***
%lambda=1;
%par1=par;
npar=length(par);%npareff=length(algorithm.estindex);
update=zeros(npar,1); %I=eye(length(e));
%l=0;stop=0;
ind3 = algorithm.estindex;
% *** Looping, attempting to find a lower value of V along
%     the G-direction ***

pinvtol = algorithm.Advanced.Search.GnsPinvTol;
maxbis = algorithm.Advanced.Search.MaxBisections;
lmstep = algorithm.Advanced.Search.LmStep;
stepred = algorithm.Advanced.Search.StepReduction;
relimp = algorithm.Advanced.Search.RelImprovement;

%switch algorithm.SearchDirection
direc = lower(algorithm.SearchDirection);
if strcmp(direc,'auto')
   direc = {'gns','lm','grad'};
elseif any(strcmp(direc,{'gns','gn'}))
   direc = {direc,'grad'};
else
   direc = {direc};
end
stop = 1;
for kdir = direc
   if ~stop,break,end
    kdir = kdir{1};
   l=0;
   stop = 0;
   if dispmode,disp(['   Search direction: ',kdir]),end
      switch kdir   
case {'lm','gns'} % levenberg-marquard
   gdir = pinv(psi,pinvtol)*e; 
   delta = delta/lmstep/2;
case 'gn'
   gdir = psi\e;
case 'grad'
       gdir = psi'*e*npar/norm(psi);
end
if strcmp(struc.type,'ssfree')
   update=gdir;par=zeros(size(gdir));npar=length(par); % fix later %%LL%%
else
    update(ind3) = gdir;
end
parnew = par+update;
[lambda,tlam] = gnnew(z,parnew,struc,algorithm);
 
Vnew=det(lambda);if Vnew<0,Vnew=inf;end
while ((Vnew - V) > -V*relimp)& l<maxbis
   switch kdir
   case 'lm'
      if l>0
         delta = delta*lmstep;
      end
      if strcmp(struc.type,'ssfree')
         update = pinv([psi;delta*eye(npar)])*[e;zeros(npar,1)];
      else
         update(ind3) = pinv([psi;delta*eye(length(ind3))])*[e;zeros(length(ind3),1)];
      end
   case {'gns','gn','grad'}
      update = update/stepred;
   end
   parnew = par+update;
   [lambda,tlam] = gnnew(z,parnew,struc,algorithm);
   Vnew=det(lambda);if Vnew<=0,Vnew=inf;end
   
   l = l+1;
   if l==maxbis, stop = 1;end
end
end % kdir

if dispmode  % Give status information to the screen
   disp(['   Bisected search vector ',int2str(l),' times']),
end
 if stop,parnew=par;Vnew=V;lambda=lambdaold;tlam=tlamold;end






