function [x,u,y,dx,options]=trim(fun,x0,u0,y0,ix,iu,iy,dx0,idx,para,t,coeff1,coeff2,coeff3,coeff4,coeff5,coeff6);
%TRIM	Finds steady state parameters for a system given a set of conditions.
%	TRIM enables steady state parameters to be found that 
%	that satisfy certain input, output and state conditions. 
%
%	[X,U,Y,DX]=TRIM('SFUNC') attempts to find values for X, U and
%	Y that set the state derivatives, DX, of the S-function 'SFUNC'
%	to zero. TRIM uses a constrained optimization technique. 
%	SFUNC may be a SIMULINK or other model, see SFUNC.
%
%	[X,U,Y,DX]=TRIM('SFUNC',X0,U0) sets the initial starting guesses
%	for X and U to X0 and U0, respectively.           
%	
% 	[X,U,Y,DX]=TRIM('SFUNC',X0,U0,Y0,IX,IU,IY) fixes X, U and Y
%	to X0(IX), U0(IU) and Y0(IY). The variables IX, IU and IY are 
%	vectors of indices.  If no solution to this problem can be found 
%	then TRIM will attempt to find values that minimize the maximum
%	deviation from the intended values.
%
%	[X,U,Y,DX]=TRIM('SFUNC',X0,U0,Y0,IX,IU,IY,DX0,IDX) fixes the
%	derivatives indexed by IDX to DX(IDX). Derivatives not indexed 
%	are free to vary.
%
%	[X,U,Y,DX]=TRIM('SFUNC',X0,U0,Y0,IX,IU,IY,DX,IDX,OPTIONS) allows
%	the optimization parameters to be set. See CONSTR for details.
%
%	[X,U,Y,DX]=TRIM('foo',X0,U0,Y0,IX,IU,IY,DX0,IDX,OPTIONS,T) for systems 
%	dependent on time sets the time to T.
%
%	To see more help, enter TYPE TRIM.
%	See also LINMOD, SFUNC, DSFUNC, and the M-file TRIM.M.

%	Copyright (c) 1990-94 by The MathWorks, Inc.
%	Andrew Grace 11-12-90.
%	Revised ACWG 3-9-91

%	[X,U,Y,DX]=TRIM('SFUNC',X0,U0,Y0,IX,IU,IY,DX,IDX,T,OPTIONS,COEFF)
%	passes coefficients, COEFF, to SFUNC at each call: 
%	[X,T]=SFUNC(X,T,U,FLAG,COEFF). 
%
%	Any or all of X0,U0,Y0,IX,IU,IY,DX0,IDX,OPTIONS,T 
%	may be empty matrices in which case these parameters will be assumed 
%	to be undefined and the default option will be used. 
%	For example,  TRIM('foo',X0,U0,Y0) is equivalent to 
%	TRIM('foo',X0,U0,Y0,[],[],[]);
%
%	The function 'SFUNC'  must return state derivatives and 
%	outputs given input and state information: [SYS]=SFUNC(X,t,U,FLAG) 
%	depending on FLAG.
%	Calling SFUNC without input arguments should return a vector 
%	containing the number of inputs, outputs and states. See, SFUNC.
%

% ---------Extra parameters for S-function systems ------
outstr=[];
for i=1:nargin-11
        outstr=[outstr,',coeff',int2str(i)];
end
% ---------------Options--------------------
ifun = [fun,'([],[],[],0', outstr,')'];
sizes = eval(ifun);
sizes=[sizes(:); zeros(6-length(sizes),1)];
nxz=sizes(1)+sizes(2); nu=sizes(4); ny=sizes(3); nx = sizes(1);

% If arguments not defined then make empty
if nargin<2, x0=[]; end
if nargin<3, u0=[]; end
if nargin<4, y0=[]; end
if nargin<5, ix=[]; end
if nargin<6, iu=[]; end
if nargin<7, iy=[]; end
if nargin<8, dx0=[]; end
if nargin<9, idx=[]; end
if nargin<10, para=[]; end
if nargin<11, t=0; end

% If no intial guesses then use zeros
if isempty(x0), x0=zeros(nxz,1); end
if isempty(u0), u0=zeros(nu,1); end
if isempty(y0), y0=zeros(ny,1); end
if isempty(dx0), dx0=zeros(nxz,1); end
if isempty(para), para=0; end



% If no fixed elements set index to minimize worst deviation from given
% values:
if isempty([ix(:);iy(:);iu(:)]), ix=[1:nxz]; iy=[1:ny]; iu=[1:nu]; end
if isempty(idx); idx=[1:nx]; end

evalstr=['ret=',fun,'(t, x,u,flag',outstr, ');'];

% Set up nx+nz equality constraints to force the derivatives to zero.
para(13)=length(idx);
para(7) = 1; % Use minimax merit function and Hessian update.   

% Initial guesses
x=x0;
u=u0;
flag = 3; 

eval(evalstr);
y = ret; 
gg=[x(ix)-x0(ix);y(iy)-y0(iy);u(iu)-u0(iu)];
% Objective function is lambda
lambda=max(abs(gg));
[xu,options] = constr('trimfun',[x;u;lambda],para,[],[],[],x0,u0,y0,ix,iu,iy,dx0,idx,evalstr,t);
% Unravel x and u
x=xu(1:nxz); u=xu(nxz+1:nxz+nu);
flag =3;
eval(evalstr);
y=ret; 
flag =1; 
eval(evalstr)
dx= ret;
