www.gusucode.com > sloptim工具箱matlab源码程序 > sloptim/sloptim/@sroengine/@fmincon/minimize.m

    function OptimInfo = minimize(this)
% Solves constraint minimization problem associated with given optimizer.

% Author(s): P. Gahinet
% Copyright 1986-2009 The MathWorks, Inc.

% Param spec and data -> decision vector
v = par2var(this);
x0 = [v.Initial ; 0];
if this.Info.StopIfFeasible
   %Pure feasibility problem
   xMin = [v.Minimum ; 0];
else
   %Allow slack variable to be negative
   xMin = [v.Minimum; -Inf];
end

xMax = [v.Maximum ; Inf];
xScale = abs([v.Typical ; 1]);
this.Info.xMin = xMin;
this.Info.xMax = xMax;
this.Info.xScale = xScale;

% Setup
if this.Info.hasConstr
   ConstrFun = @LocalConstrFun;
else
   ConstrFun = [];
end
Options = this.Options;
Options.Display = 'off';  % Never use built-in display
xScale(xScale==0) = 1;
Options.TypicalX = xScale; 
Options.OutputFcn = @LocalOutput;

% Startup display
this.showIter('init',this.Info.Display)

% Minimization:
%    min gamma over x,gamma subject to c(x,gamma)<=0, gamma>=0
startTime = clock;
[x, fval, exitflag, output] = fmincon( @LocalCostFun, x0, ...
   [], [], [], [], xMin, xMax, ConstrFun, Options, this );

if ~this.Info.hasCost && all(ConstrFun(x,this) <= Options.TolCon)
    %Avoid false termination reports when performing constraint
    %only optimisation. 
    exitflag = 1;
end
if ~this.Info.StopIfFeasible && any(exitflag==[1 -2])
   %Check for feasible solution exit flag is correct
   if all( (ConstrFun(x,this)+x(end))<=0)
      exitflag = 1;
   else
      %No feasible solution found when looking for interior point
      exitflag = -2;
   end
end
% Output
if ~any(isnan(x))
   fConstr = this.evalRequirements(x,'Constraint');
else
   fConstr = [];
end
OptimInfo = struct(...
   'Cost', fval,...
   'X', x,...
   'ExitFlag', exitflag,...
   'Iteration', output.iterations,...
   'Algorithm', output.algorithm, ...
   'StartTime', startTime, ...
   'EndTime', clock, ...
   'Constraints', fConstr);

% Termination message
this.showIter('done',this.Info.Display,exitflag)
   
% ------------------------------------------------------------------------- %
function stop = LocalOutput(x, state, type, Optimizer)
% Used to plot progress and stop optimization
drawnow % force processing of any stop event
Proj = Optimizer.Project;
stop = strcmp(Proj.OptimStatus,'stop');
if strcmp(type,'iter')
   if ~stop
      % Resync project data with current best X
      Optimizer.syncProject(x);
      % Update progress plots
      Specs = find(Proj.Specs,'Enable',true,'Optimized',true);
      for ct=1:length(Specs)
         %Check that there is at least one active requirement
         optimUpdate(Specs(ct))
      end
   end
   %Find number of 'evaluations'
   [state.simcount,state.lincount] = Proj.Specs.totalCounts;
   % Update display
   Optimizer.showIter(type,Optimizer.Info.Display,state,x)
end

% ------------------------------------------------------------------------- %
function [F, G] = LocalCostFun(x, this)

if strcmp(this.Project.OptimStatus,'stop')
   %Quick return, optimization stopped by user
   F = nan; G = nan(numel(x),1);
   return
end

% Computes cost function and its gradient
GradRequest = (nargout>1);

if this.Info.hasCost
   % Minimize objective sum(evalcost(Spec))
   % RE: Ignoring slack variable in this case
   F = sum(this.evalRequirements(x,'Cost'));
   if GradRequest
      G = this.evalRequirementsGradient(x,'Cost');
      if isempty(G)
         G = zeros(length(x),1);
      else
         G = [sum(G,2) ; 0];
      end
   end
else
   nv = length(x);
   F = x(nv);  % slack
   G = [zeros(nv-1,1) ; 1];
end
% Update TypicalX
% RE: At major steps only to insulate TypicalX from large X tried during
%     line search
if GradRequest
   this.Info.xScale = max(this.Info.xScale,abs(x));
end

% ------------------------------------------------------------------------- %
function [C, Ceq, G, Geq] = LocalConstrFun(x, this)

if strcmp(this.Project.OptimStatus,'stop')
   %Quick return, optimization stopped by user
   C = nan; Ceq = nan;
   G = nan(numel(x),1); Geq = nan(numel(x),1);
   return
end

% Evaluates nonlinear constraints and their gradient
nv = length(x);
if this.Info.hasCost
   % RE: Ignoring slack variable in this case
   x(nv) = 0;
end
C = this.evalRequirements(x,'Constraint');
Ceq = [];

if nargout>2
   % Gradient wrt decision variables
   G = this.evalRequirementsGradient(x,'Constraint');
   % Add gradient wrt slack (saves 1-2 simulations / iter)
   if isempty(G)
      G = zeros(length(x),length(C));
   elseif this.Info.hasCost
      G = [G ; zeros(1,length(C))];
   else
      G = [G ; this.slackgrad(x)];
   end
   Geq = [];
end