1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
// Copyright (C) 2009 - INRIA - Michael Baudin
//
// This file must be used under the terms of the CeCILL.
// This source file is licensed as described in the file COPYING, which
// you should have received as part of this distribution. The terms
// are also available at
// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
//
// optimbase_terminate --
// Returns %t if the algorithm terminates.
// Returns %f if the algorithm must continue.
// Arguments, input
// this : the current object
// previousfopt : the previous value of the objective function
// currentfopt : the current value of the objective function
// previousxopt : the previous value of x
// currentxopt : the current value of x
// terminate : 1 if the algorithm terminates, 0 if the algorithm must continue.
// Arguments, output
// status : termination status
// status = "continue"
// status = "maxiter"
// status = "maxfuneval"
// status = "tolf"
// status = "tolx"
//
function [ this , terminate , status ] = optimbase_terminate (this , ...
previousfopt , currentfopt , previousxopt , currentxopt )
terminate = %f;
status = "continue";
if ( this.verbose == 1 ) then
this = optimbase_stoplog (this,sprintf(" > Termination ?"));
end
//
// Criteria #1 : maximum number of iterations
//
if ( ~terminate ) then
if ( this.verbose == 1 ) then
this = optimbase_stoplog (this,sprintf(" > iterations=%d >= maxiter=%d",this.iterations, this.maxiter));
end
if ( this.iterations >= this.maxiter ) then
terminate = %t;
status = "maxiter";
end
end
//
// Criteria #2 : maximum number of call to function
//
if ( ~terminate ) then
if ( this.verbose == 1 ) then
this = optimbase_stoplog (this,sprintf(" > funevals=%d >= maxfunevals=%d",this.funevals, this.maxfunevals));
end
if ( this.funevals >= this.maxfunevals ) then
terminate = %t;
status = "maxfuneval";
end
end
//
// Criteria #3 : tolerance on function
// Note :
// This termination criteria works well in the special case where the function
// value at optimum is several order of magnitude smaller
// than the initial function value (ie f(x0)).
// This is the case when the function value at optimum is zero.
// When the function value at optimum is non-zero, or if the
// initial function value is strictly positive (e.g. f(x0)=10)
// and the optimum function value is strictly negative (e.g. f(x*)=-10),
// that criteria fails miserably.
//
if ( ~terminate ) then
if ( this.tolfunmethod )
tolfr = this.tolfunrelative;
tolfa = this.tolfunabsolute;
acfopt = abs(currentfopt);
apfopt = abs(previousfopt);
if ( this.verbose == 1 ) then
this = optimbase_stoplog (this,sprintf(" > abs(currentfopt)=%e < tolfunrelative * abs(previousfopt) + tolfunabsolute=%e",...
acfopt, tolfr * apfopt + tolfa));
end
if ( acfopt < tolfr * apfopt + tolfa ) then
terminate = %t;
status = "tolf";
end
end
end
//
// Criteria #4 : tolerance on x
// Note
// What means a relative error on x ?
// Notes: if xn and xn+1 are very close to xopt and xopt different from 0,
// the relative error between xn and xn+1 is small.
// But if xopt, xn and xn+1 are close to 0, the relative error may be a
// completely wrong criteria. The absolute tolerance should be used in this case.
//
if ( ~terminate ) then
if ( this.tolxmethod ) then
normdelta = norm(currentxopt - previousxopt);
normold = norm(currentxopt);
tolxr = this.tolxrelative;
tolxa = this.tolxabsolute;
if ( this.verbose == 1 ) then
this = optimbase_stoplog (this,sprintf(" > e(x)=%e < %e * %e + %e",...
normdelta, tolxr , normold , tolxa ));
end
if ( normdelta < tolxr * normold + tolxa ) then
terminate = %t;
status = "tolx";
end
end
end
if ( this.verbose == 1 ) then
this = optimbase_stoplog (this,sprintf(" > Terminate = %s, status = %s",...
string(terminate) , status ));
end
endfunction
|