function [x, OPTIONS] = attgoal(FUN,x,GOAL,WEIGHT,OPTIONS,VLB,VUB,GRADFUN,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10)
%ATTGOAL Solves the multi-objective goal attainment optimization problem.
%
%	X = ATTGOAL('FUN',X0,GOAL,WEIGHT)
%	tries to make the objective functions (F) supplied by FUN
%	(usually an M-file: FUN.M)  attain the goals (GOAL) by varying X.
%
%	In doing so the following non-linear programming problem is solved:
%            min { LAMBDA | F(X)-WEIGHT.LAMBDA<=GOAL } 
%             K  
%
%	The function 'FUN' should return the values of the objectives, F.
%	F=FUN(X).
%
%	X=ATTGOAL('FUN',X,OPTIONS) allows a vector of optional parameters to 
%	be defined. For more information type HELP FOPTIONS.
%	
%	X=ATTGOAL('FUN',X,OPTIONS,VLB,VUB) defines a set of lower and upper
%	bounds on the design variables, X, so that the solution is always in 
%	the range VLB < X < VUB. 
% 	For details of other options see the M-file ATTGOAL.M.

%	Copyright (c) 1990 by the MathWorks, Inc.
%	Andy Grace 7-9-90.

         
% ---------------------More Details---------------------------
% [x]=attgoal(x,F,GOAL,WEIGHT,OPTIONS)
% Solves the goal attainment problem where:
%
%  X  Is a set of design parameters which can be varied.
%  F  Is a set of objectives which are dependent on X.
%  GOAL Set of design goals. The optimizer will try to make 
%         F<GOAL, F=GOAL, or F>GOAL depending on the formulation.
%  WEIGHT Set of weighting parameters which determine the 
%         relative under or over achievement of the objectives.
%         Notes:
%           1.Setting WEIGHT=abs(GOAL)  will try to make the objectives
%             less than the goals resulting  in roughly the same 
%             percentage under or over achievement of the goals.
%           2. Setting WEIGHT=-abs(GOAL) will try to make the objectives
%              greater then the goals resulting in roughly the same percentage 
%              under- or over-achievement in the goals.
%           3. Setting WEIGHT(i)=0  indicates a hard constraint.
%              i.e. F<GOAL.
%  OPTIONS OPTIONS(15) indicates the number of objectives for which it is
%	   required for the objectives (F) to equal the goals (GOAL). 
%          Such objectives should be partitioned into the first few 
%	   elements of F.
%          The remaining parameters determine tolerance settings.
%          For more information type HELP FOPTIONS.
%
%
%	X=ATTGOAL('FUN',X,OPTIONS,VLB,VUB,'GRADFUN') allows a function 
%	'GRADFUN' to be entered which returns the partial derivatives of the 
%	function and the  constraints at X:  GRADS = GRADFUN(X).
%
%	X=ATTGOAL('FUN',X,OPTIONS,VLB,VUB,[],P1,P2,..) allows
%	coefficients, P1, P2, P3 to be passed directly to FUN:
%	[F,G]=FUN(X,P1,P2,...).


        
if nargin < 5, OPTIONS=[]; end
if nargin < 6, VLB=[]; end
if nargin < 7, VUB=[]; end
if nargin < 8, GRADFUN=[]; end

lenopt = length(OPTIONS);
if ~lenopt, OPTIONS=0; end

xnew=x(:);
WEIGHT=WEIGHT(:);
GOAL=GOAL(:);
OPTIONS=foptions(OPTIONS);
OPTIONS(7) = ~OPTIONS(7);
neqcstr=OPTIONS(15); 

if ~any(FUN<48)
	evalstr1 = ['f=',FUN,];
        evalstr1=[evalstr1, '(x'];
        for i=1:nargin - 8
                evalstr1 = [evalstr1,',P',int2str(i)];
        end
        evalstr1 = [evalstr1, ');'];
else
        evalstr1=['f=',FUN,';'];
end
evalstr1=[evalstr1, 'g=[];'];


evalstr2='';
if length(GRADFUN)
	if ~any(GRADFUN<48) % Check alphanumeric
		evalstr2 = ['gf=',GRADFUN,'(x'];
		for i=1:nargin - 8
			evalstr2 = [evalstr2,',P',int2str(i)];
		end
		evalstr2 = [evalstr2, ');'];
		gfun  = 'goalgra';
	else
		evalstr2=['gf=', GRADFUN,';'];
	end
else
	gfun = [];
end

evalstr = ['[xnew, OPTIONS] = constr(''goalfun'',[xnew;0],OPTIONS,VLB,VUB,gfun,neqcstr,evalstr1,evalstr2,WEIGHT,GOAL,x'];


for i=1:nargin - 8
	evalstr = [evalstr,',P',int2str(i)];
end
evalstr = [evalstr, ');'];
 
eval(evalstr)
OPTIONS(7) = ~OPTIONS(7);
x(:) = xnew(1:length(xnew)-1);
