Home > manopt > core > stoppingcriterion.m

stoppingcriterion

PURPOSE ^

Checks for standard stopping criteria, as a helper to solvers.

SYNOPSIS ^

function [stop, reason] = stoppingcriterion(problem, x, options, info, last)

DESCRIPTION ^

 Checks for standard stopping criteria, as a helper to solvers.

 function [stop, reason] = stoppingcriterion(problem, x, options, info, last)

 Executes standard stopping criterion checks, based on what is defined in
 the info(last) stats structure and in the options structure.

 The returned number 'stop' is 0 if none of the stopping criteria
 triggered, and a (strictly) positive integer otherwise. The integer
 identifies which criterion triggered:
  0 : Nothing triggered;
  1 : Cost tolerance reached;
  2 : Gradient norm tolerance reached;
  3 : Max time exceeded;
  4 : Max iteration count reached;
  6 : User defined stopfun criterion triggered.

 The output 'reason' is a string describing the triggered event.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [stop, reason] = stoppingcriterion(problem, x, options, info, last)
0002 % Checks for standard stopping criteria, as a helper to solvers.
0003 %
0004 % function [stop, reason] = stoppingcriterion(problem, x, options, info, last)
0005 %
0006 % Executes standard stopping criterion checks, based on what is defined in
0007 % the info(last) stats structure and in the options structure.
0008 %
0009 % The returned number 'stop' is 0 if none of the stopping criteria
0010 % triggered, and a (strictly) positive integer otherwise. The integer
0011 % identifies which criterion triggered:
0012 %  0 : Nothing triggered;
0013 %  1 : Cost tolerance reached;
0014 %  2 : Gradient norm tolerance reached;
0015 %  3 : Max time exceeded;
0016 %  4 : Max iteration count reached;
0017 %  6 : User defined stopfun criterion triggered.
0018 %
0019 % The output 'reason' is a string describing the triggered event.
0020 
0021 % This file is part of Manopt: www.manopt.org.
0022 % Original author: Nicolas Boumal, Dec. 30, 2012.
0023 % Contributors:
0024 % Change log:
0025 %
0026 %   Apr. 2, 2015 (NB):
0027 %       'reason' now contains the option (name and value) that triggered.
0028 %
0029 %   Aug. 3, 2018 (NB):
0030 %       Removed check for costevals, as it was never used, and the new
0031 %       manopt counters allow to do this in a more transparent way.
0032 %       Furthermore, now, options.stopfun can have 1 or 2 outputs: the
0033 %       first is a boolean indicating whether or not to stop, and the
0034 %       (optional) second output is a string indicating the reason.
0035 
0036 
0037     stop = 0;
0038     reason = '';
0039     
0040     stats = info(last);
0041 
0042     % Target cost attained
0043     if isfield(stats, 'cost') && isfield(options, 'tolcost') && ...
0044        stats.cost <= options.tolcost
0045         reason = sprintf('Cost tolerance reached; options.tolcost = %g.', options.tolcost);
0046         stop = 1;
0047         return;
0048     end
0049 
0050     % Target gradient norm attained
0051     if isfield(stats, 'gradnorm') && isfield(options, 'tolgradnorm') && ...
0052        stats.gradnorm < options.tolgradnorm
0053         reason = sprintf('Gradient norm tolerance reached; options.tolgradnorm = %g.', options.tolgradnorm);
0054         stop = 2;
0055         return;
0056     end
0057 
0058     % Allotted time exceeded
0059     if isfield(stats, 'time') && isfield(options, 'maxtime') && ...
0060        stats.time >= options.maxtime
0061         reason = sprintf('Max time exceeded; options.maxtime = %g.', options.maxtime);
0062         stop = 3;
0063         return;
0064     end
0065 
0066     % Allotted iteration count exceeded
0067     if isfield(stats, 'iter') && isfield(options, 'maxiter') && ...
0068        stats.iter >= options.maxiter
0069         reason = sprintf('Max iteration count reached; options.maxiter = %g.', options.maxiter);
0070         stop = 4;
0071         return;
0072     end
0073 
0074     % Check whether the possibly user defined stopping criterion
0075     % triggers or not.
0076     if isfield(options, 'stopfun')
0077         % options.stopfun can have 1 or 2 outputs, but checking this with
0078         % nargout does not always work because it is technical to determine
0079         % for anonymous functions. Thus, we use our best guess. Nargout
0080         % returns -1 when it cannot determine the number of outputs, in
0081         % which case we take the safer approach of assuming 1 output.
0082         switch nargout(options.stopfun)
0083             case 2
0084                 [userstop, reason] = options.stopfun(problem, x, info, last);
0085             case {1, -1}
0086                 userstop = options.stopfun(problem, x, info, last);
0087                 reason = ['User defined stopfun criterion triggered; ' ...
0088                           'see options.stopfun.'];
0089             otherwise
0090                 error('manopt:stoppingcriterion:stopfunoutputs', ...
0091                       'options.stopfun must have one or two outputs.');
0092         end
0093         if userstop
0094             stop = 6;
0095             if nargout(options.stopfun) == -1
0096                 reason = [reason, '\n(A reason may have been ' ...
0097                           'provided, but stoppingcriterion was ' ...
0098                           'unable to determine\nthe number of ' ...
0099                           'output arguments of options.stopfun.)'];
0100             end
0101             return;
0102         end
0103     end
0104 
0105 end

Generated on Fri 30-Sep-2022 13:18:25 by m2html © 2005