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