2016-06-06 11:37:01 +02:00
function [opt_par_values,fval,exitflag,hessian_mat,options_,Scale,new_rat_hess_info]= dynare_minimize_objective ( objective_function,start_par_value,minimizer_algorithm,options_,bounds,parameter_names,prior_information,Initial_Hessian,varargin)
% function [opt_par_values,fval,exitflag,hessian_mat,options_,Scale,new_rat_hess_info]=dynare_minimize_objective(objective_function,start_par_value,minimizer_algorithm,options_,bounds,parameter_names,prior_information,Initial_Hessian,new_rat_hess_info,varargin)
2014-12-04 09:18:33 +01:00
% Calls a minimizer
%
% INPUTS
2015-02-23 14:35:41 +01:00
% objective_function [function handle] handle to the objective function
2014-12-04 09:18:33 +01:00
% start_par_value [n_params by 1] vector of doubles starting values for the parameters
2015-06-01 16:37:00 +02:00
% minimizer_algorithm [scalar double, or string] code of the optimizer algorithm, or string for the name of a user defined optimization routine (not shipped with dynare).
2014-12-04 09:18:33 +01:00
% options_ [matlab structure] Dynare options structure
% bounds [n_params by 2] vector of doubles 2 row vectors containing lower and upper bound for parameters
2017-05-16 15:10:20 +02:00
% parameter_names [n_params by 1] cell array strings containing the parameters names
2014-12-04 09:18:33 +01:00
% prior_information [matlab structure] Dynare prior information structure (bayestopt_) provided for algorithm 6
% Initial_Hessian [n_params by n_params] matrix initial hessian matrix provided for algorithm 6
2016-06-06 11:37:01 +02:00
% new_rat_hess_info [matlab structure] step size info used by algorith 5
2014-12-04 09:18:33 +01:00
% varargin [cell array] Input arguments for objective function
2017-05-16 15:10:20 +02:00
%
2014-12-04 09:18:33 +01:00
% OUTPUTS
% opt_par_values [n_params by 1] vector of doubles optimal parameter values minimizing the objective
% fval [scalar double] value of the objective function at the minimum
% exitflag [scalar double] return code of the respective optimizer
% hessian_mat [n_params by n_params] matrix hessian matrix at the mode returned by optimizer
% options_ [matlab structure] Dynare options structure (to return options set by algorithms 5)
% Scale [scalar double] scaling parameter returned by algorith 6
2017-05-16 15:10:20 +02:00
%
2014-12-04 09:18:33 +01:00
% SPECIAL REQUIREMENTS
% none.
2017-05-16 15:10:20 +02:00
%
%
2021-12-13 13:36:06 +01:00
% Copyright (C) 2014-2021 Dynare Team
2014-12-04 09:18:33 +01:00
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
2021-06-09 17:33:48 +02:00
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
2014-12-04 09:18:33 +01:00
2021-12-13 13:36:06 +01:00
if isfield ( options_ , ' occbin' ) && ( ( options_ . occbin . smoother . status && options_ . occbin . smoother . inversion_filter ) || ( options_ . occbin . likelihood . status && options_ . occbin . likelihood . inversion_filter ) )
warning ( ' off' , ' MATLAB:nearlySingularMatrix' )
end
2014-12-04 09:18:33 +01:00
%% set bounds and parameter names if not already set
n_params = size ( start_par_value , 1 ) ;
if isempty ( bounds )
2015-05-13 20:33:14 +02:00
bounds = [ - Inf ( n_params , 1 ) Inf ( n_params , 1 ) ] ;
2014-12-04 09:18:33 +01:00
end
if isempty ( parameter_names )
2020-07-08 11:39:07 +02:00
parameter_names = cellstr ( [ repmat ( ' parameter ' , n_params , 1 ) , num2str ( ( 1 : n_params ) ' ) ] ) ;
2014-12-04 09:18:33 +01:00
end
%% initialize function outputs
hessian_mat = [ ] ;
Scale = [ ] ;
exitflag = 1 ;
fval = NaN ;
opt_par_values = NaN ( size ( start_par_value ) ) ;
2016-06-06 11:37:01 +02:00
new_rat_hess_info = [ ] ;
2014-12-04 09:18:33 +01:00
switch minimizer_algorithm
case 1
2019-10-08 18:35:57 +02:00
if isoctave && ~ user_has_octave_forge_package ( ' optim' , ' 1.6' )
error ( ' Optimization algorithm 1 is not available, you need to install the optim Forge package, version 1.6 or above' )
elseif ~ isoctave && ~ user_has_matlab_license ( ' optimization_toolbox' )
2014-12-04 09:18:33 +01:00
error ( ' Optimization algorithm 1 requires the Optimization Toolbox' )
end
% Set default optimization options for fmincon.
2021-01-27 14:56:24 +01:00
if ~ isoctave
optim_options = optimoptions ( ' fmincon' , ' display' , ' iter' , ' MaxFunEvals' , 100000 , ' TolFun' , 1e-8 , ' TolX' , 1e-6 ) ;
else
optim_options = optimset ( ' display' , ' iter' , ' MaxFunEvals' , 100000 , ' TolFun' , 1e-8 , ' TolX' , 1e-6 ) ;
end
2019-10-08 18:35:57 +02:00
if isoctave
% Under Octave, use the active-set (i.e. octave_sqp of nonlin_min)
% algorithm. On a simple example (fs2000.mod), the default algorithm
% is not able to even move away from the initial point.
2021-01-27 14:56:24 +01:00
optim_options = optimset ( optim_options , ' Algorithm' , ' active-set' ) ;
2019-10-08 18:35:57 +02:00
end
2021-01-22 20:09:32 +01:00
if options_ . analytic_derivation || ( isfield ( options_ , ' mom' ) && options_ . mom . analytic_jacobian == 1 )
2021-01-27 14:56:24 +01:00
if ~ isoctave
optim_options = optimoptions ( optim_options , ' GradObj' , ' on' , ' TolX' , 1e-7 ) ; %alter default TolX
else
optim_options = optimset ( ' GradObj' , ' on' , ' TolX' , 1e-7 ) ;
end
2021-01-22 20:09:32 +01:00
end
2015-02-26 08:38:07 +01:00
if ~ isempty ( options_ . optim_opt )
2021-01-27 14:56:24 +01:00
if ~ isoctave
eval ( [ ' optim_options = optimoptions(optim_options,' options_ . optim_opt ' );' ] ) ;
else
eval ( [ ' optim_options = optimset(optim_options,' options_ . optim_opt ' );' ] ) ;
end
2014-12-04 09:18:33 +01:00
end
2015-05-02 14:21:13 +02:00
if options_ . silent_optimizer
2021-01-27 14:56:24 +01:00
if ~ isoctave
optim_options = optimoptions ( optim_options , ' display' , ' off' ) ;
else
optim_options = optimset ( optim_options , ' display' , ' off' ) ;
end
2015-05-02 14:21:13 +02:00
end
2021-01-22 20:09:32 +01:00
if options_ . analytic_derivation || ( isfield ( options_ , ' mom' ) && options_ . mom . analytic_jacobian == 1 ) %use wrapper
func = @ ( x ) analytic_gradient_wrapper ( x , objective_function , varargin { : } ) ;
if ~ isoctave
[ opt_par_values , fval , exitflag , output , lamdba , grad , hessian_mat ] = ...
fmincon ( func , start_par_value , [ ] , [ ] , [ ] , [ ] , bounds ( : , 1 ) , bounds ( : , 2 ) , [ ] , optim_options ) ;
else
% Under Octave, use a wrapper, since fmincon() does not have an 11th
% arg. Also, only the first 4 output arguments are available.
[ opt_par_values , fval , exitflag , output ] = ...
fmincon ( func , start_par_value , [ ] , [ ] , [ ] , [ ] , bounds ( : , 1 ) , bounds ( : , 2 ) , [ ] , optim_options ) ;
end
2019-10-08 18:35:57 +02:00
else
2021-01-22 20:09:32 +01:00
if ~ isoctave
[ opt_par_values , fval , exitflag , output , lamdba , grad , hessian_mat ] = ...
fmincon ( objective_function , start_par_value , [ ] , [ ] , [ ] , [ ] , bounds ( : , 1 ) , bounds ( : , 2 ) , [ ] , optim_options , varargin { : } ) ;
else
% Under Octave, use a wrapper, since fmincon() does not have an 11th
% arg. Also, only the first 4 output arguments are available.
func = @ ( x ) objective_function ( x , varargin { : } ) ;
[ opt_par_values , fval , exitflag , output ] = ...
fmincon ( func , start_par_value , [ ] , [ ] , [ ] , [ ] , bounds ( : , 1 ) , bounds ( : , 2 ) , [ ] , optim_options ) ;
end
2019-10-08 18:35:57 +02:00
end
2021-01-22 20:08:08 +01:00
2014-12-04 09:18:33 +01:00
case 2
2015-04-15 12:42:08 +02:00
%simulating annealing
sa_options = options_ . saopt ;
2015-04-06 11:28:32 +02:00
if ~ isempty ( options_ . optim_opt )
2015-04-15 12:42:08 +02:00
options_list = read_key_value_string ( options_ . optim_opt ) ;
for i = 1 : rows ( options_list )
switch options_list { i , 1 }
case ' neps'
sa_options . neps = options_list { i , 2 } ;
case ' rt'
sa_options . rt = options_list { i , 2 } ;
case ' MaxIter'
sa_options . MaxIter = options_list { i , 2 } ;
case ' TolFun'
sa_options . TolFun = options_list { i , 2 } ;
case ' verbosity'
sa_options . verbosity = options_list { i , 2 } ;
case ' initial_temperature'
sa_options . initial_temperature = options_list { i , 2 } ;
case ' ns'
sa_options . ns = options_list { i , 2 } ;
case ' nt'
sa_options . nt = options_list { i , 2 } ;
case ' step_length_c'
sa_options . step_length_c = options_list { i , 2 } ;
case ' initial_step_length'
sa_options . initial_step_length = options_list { i , 2 } ;
otherwise
warning ( [ ' solveopt: Unknown option (' options_list { i , 1 } ' )!' ] )
end
end
2015-04-06 11:28:32 +02:00
end
2015-05-02 14:21:13 +02:00
if options_ . silent_optimizer
sa_options . verbosity = 0 ;
end
2015-04-15 12:42:08 +02:00
npar = length ( start_par_value ) ;
2015-05-07 15:59:46 +02:00
[ LB , UB ] = set_bounds_to_finite_values ( bounds , options_ . huge_number ) ;
2015-05-13 20:58:47 +02:00
if sa_options . verbosity
fprintf ( ' \nNumber of parameters= %d, initial temperatur= %4.3f \n' , npar , sa_options . initial_temperature ) ;
fprintf ( ' rt= %4.3f; TolFun= %4.3f; ns= %4.3f;\n' , sa_options . rt , sa_options . TolFun , sa_options . ns ) ;
fprintf ( ' nt= %4.3f; neps= %4.3f; MaxIter= %d\n' , sa_options . nt , sa_options . neps , sa_options . MaxIter ) ;
fprintf ( ' Initial step length(vm): %4.3f; step_length_c: %4.3f\n' , sa_options . initial_step_length , sa_options . step_length_c ) ;
fprintf ( ' %-20s %-6s %-6s %-6s\n' , ' Name:' , ' LB;' , ' Start;' , ' UB;' ) ;
for pariter = 1 : npar
fprintf ( ' %-20s %6.4f; %6.4f; %6.4f;\n' , parameter_names { pariter } , LB ( pariter ) , start_par_value ( pariter ) , UB ( pariter ) ) ;
end
2015-04-15 12:42:08 +02:00
end
sa_options . initial_step_length = sa_options . initial_step_length * ones ( npar , 1 ) ; %bring step length to correct vector size
sa_options . step_length_c = sa_options . step_length_c * ones ( npar , 1 ) ; %bring step_length_c to correct vector size
[ opt_par_values , fval , exitflag , n_accepted_draws , n_total_draws , n_out_of_bounds_draws , t , vm ] = ...
simulated_annealing ( objective_function , start_par_value , sa_options , LB , UB , varargin { : } ) ;
2014-12-04 09:18:33 +01:00
case 3
if isoctave && ~ user_has_octave_forge_package ( ' optim' )
2018-06-05 19:43:43 +02:00
error ( ' Optimization algorithm 3 requires the optim package' )
2014-12-04 09:18:33 +01:00
elseif ~ isoctave && ~ user_has_matlab_license ( ' optimization_toolbox' )
2016-09-27 15:28:43 +02:00
error ( ' Optimization algorithm 3 requires the Optimization Toolbox' )
2014-12-04 09:18:33 +01:00
end
% Set default optimization options for fminunc.
2021-01-27 14:56:24 +01:00
if ~ isoctave
optim_options = optimoptions ( ' fminunc' , ' display' , ' iter' , ' MaxFunEvals' , 100000 , ' TolFun' , 1e-8 , ' TolX' , 1e-6 ) ;
else
optim_options = optimset ( ' display' , ' iter' , ' MaxFunEvals' , 100000 , ' TolFun' , 1e-8 , ' TolX' , 1e-6 ) ;
end
2015-02-26 08:38:07 +01:00
if ~ isempty ( options_ . optim_opt )
2021-01-27 14:56:24 +01:00
if ~ isoctave
eval ( [ ' optim_options = optimoptions(optim_options,' options_ . optim_opt ' );' ] ) ;
else
eval ( [ ' optim_options = optimset(optim_options,' options_ . optim_opt ' );' ] ) ;
end
2014-12-04 09:18:33 +01:00
end
2015-05-02 14:21:13 +02:00
if options_ . silent_optimizer
2021-01-27 14:56:24 +01:00
if ~ isoctave
optim_options = optimoptions ( optim_options , ' display' , ' off' ) ;
else
optim_options = optimset ( optim_options , ' display' , ' off' ) ;
end
2015-05-02 14:21:13 +02:00
end
2021-01-22 20:09:32 +01:00
if options_ . analytic_derivation || ( isfield ( options_ , ' mom' ) && options_ . mom . analytic_jacobian == 1 )
if ~ isoctave
2021-01-27 14:56:24 +01:00
optim_options = optimoptions ( optim_options , ' GradObj' , ' on' ) ;
2021-01-22 20:09:32 +01:00
func = @ ( x ) analytic_gradient_wrapper ( x , objective_function , varargin { : } ) ;
[ opt_par_values , fval , exitflag ] = fminunc ( func , start_par_value , optim_options ) ;
else
2021-01-29 11:10:37 +01:00
optim_options = optimset ( optim_options , ' GradObj' , ' on' ) ;
2021-01-22 20:09:32 +01:00
% Under Octave, use a wrapper, since fminunc() does not have a 4th arg
func = @ ( x ) analytic_gradient_wrapper ( x , objective_function , varargin { : } ) ;
[ opt_par_values , fval , exitflag ] = fminunc ( func , start_par_value , optim_options ) ;
end
2014-12-04 09:18:33 +01:00
else
2021-01-22 20:09:32 +01:00
if ~ isoctave
[ opt_par_values , fval , exitflag ] = fminunc ( objective_function , start_par_value , optim_options , varargin { : } ) ;
else
% Under Octave, use a wrapper, since fminunc() does not have a 4th arg
func = @ ( x ) objective_function ( x , varargin { : } ) ;
[ opt_par_values , fval , exitflag ] = fminunc ( func , start_par_value , optim_options ) ;
end
2014-12-04 09:18:33 +01:00
end
case 4
% Set default options.
H0 = 1e-4 * eye ( n_params ) ;
crit = options_ . csminwel . tolerance . f ;
nit = options_ . csminwel . maxiter ;
numgrad = options_ . gradient_method ;
epsilon = options_ . gradient_epsilon ;
2015-05-13 20:58:47 +02:00
Verbose = options_ . csminwel . verbosity ;
Save_files = options_ . csminwel . Save_files ;
2014-12-04 09:18:33 +01:00
% Change some options.
2015-02-26 08:38:07 +01:00
if ~ isempty ( options_ . optim_opt )
2014-12-04 09:18:33 +01:00
options_list = read_key_value_string ( options_ . optim_opt ) ;
for i = 1 : rows ( options_list )
switch options_list { i , 1 }
case ' MaxIter'
nit = options_list { i , 2 } ;
case ' InitialInverseHessian'
H0 = eval ( options_list { i , 2 } ) ;
case ' TolFun'
crit = options_list { i , 2 } ;
case ' NumgradAlgorithm'
numgrad = options_list { i , 2 } ;
case ' NumgradEpsilon'
epsilon = options_list { i , 2 } ;
2015-05-13 20:58:47 +02:00
case ' verbosity'
Verbose = options_list { i , 2 } ;
case ' SaveFiles'
2017-05-16 15:10:20 +02:00
Save_files = options_list { i , 2 } ;
2014-12-04 09:18:33 +01:00
otherwise
warning ( [ ' csminwel: Unknown option (' options_list { i , 1 } ' )!' ] )
end
end
end
2015-05-02 14:21:13 +02:00
if options_ . silent_optimizer
2017-05-16 15:10:20 +02:00
Save_files = 0 ;
2015-05-02 14:21:13 +02:00
Verbose = 0 ;
2017-05-16 15:10:20 +02:00
end
2014-12-04 09:18:33 +01:00
% Set flag for analytical gradient.
if options_ . analytic_derivation
analytic_grad = 1 ;
else
analytic_grad = [ ] ;
end
% Call csminwell.
2015-04-16 17:48:30 +02:00
[ fval , opt_par_values , grad , inverse_hessian_mat , itct , fcount , exitflag ] = ...
2015-05-13 20:58:47 +02:00
csminwel1 ( objective_function , start_par_value , H0 , analytic_grad , crit , nit , numgrad , epsilon , Verbose , Save_files , varargin { : } ) ;
2015-04-16 17:48:30 +02:00
hessian_mat = inv ( inverse_hessian_mat ) ;
2014-12-04 09:18:33 +01:00
case 5
2020-06-23 15:04:11 +02:00
if isempty ( prior_information ) %mr_hessian requires it, but can be NaN
prior_information . p2 = NaN ( n_params , 1 ) ;
end
2021-02-13 16:44:50 +01:00
if options_ . analytic_derivation
old_analytic_derivation = options_ . analytic_derivation ;
options_ . analytic_derivation = - 1 ; %force analytic outer product gradient hessian for each iteration
2014-12-04 09:18:33 +01:00
analytic_grad = 1 ;
crit = options_ . newrat . tolerance . f_analytic ;
newratflag = 0 ; %analytical Hessian
else
analytic_grad = 0 ;
crit = options_ . newrat . tolerance . f ;
newratflag = options_ . newrat . hess ; %default
end
nit = options_ . newrat . maxiter ;
2015-05-13 20:58:47 +02:00
Verbose = options_ . newrat . verbosity ;
Save_files = options_ . newrat . Save_files ;
2015-02-26 08:38:07 +01:00
if ~ isempty ( options_ . optim_opt )
2014-12-04 09:18:33 +01:00
options_list = read_key_value_string ( options_ . optim_opt ) ;
for i = 1 : rows ( options_list )
switch options_list { i , 1 }
case ' MaxIter'
nit = options_list { i , 2 } ;
case ' Hessian'
flag = options_list { i , 2 } ;
if options_ . analytic_derivation && flag ~= 0
error ( ' newrat: analytic_derivation is incompatible with numerical Hessian. Using analytic Hessian' )
else
2017-05-16 15:10:20 +02:00
newratflag = flag ;
2014-12-04 09:18:33 +01:00
end
case ' TolFun'
crit = options_list { i , 2 } ;
2015-05-13 20:58:47 +02:00
case ' verbosity'
Verbose = options_list { i , 2 } ;
case ' SaveFiles'
2017-05-16 15:10:20 +02:00
Save_files = options_list { i , 2 } ;
2014-12-04 09:18:33 +01:00
otherwise
warning ( [ ' newrat: Unknown option (' options_list { i , 1 } ' )!' ] )
end
end
end
2015-05-02 14:21:13 +02:00
if options_ . silent_optimizer
2017-05-16 15:10:20 +02:00
Save_files = 0 ;
2015-05-02 14:21:13 +02:00
Verbose = 0 ;
2017-05-16 15:10:20 +02:00
end
2016-06-06 11:37:01 +02:00
hess_info . gstep = options_ . gstep ;
hess_info . htol = 1.e-4 ;
hess_info . h1 = options_ . gradient_epsilon * ones ( n_params , 1 ) ;
2021-02-13 16:44:50 +01:00
% here we force 7th input argument (flagg) to be 0, since outer product
% gradient Hessian is handled in dynare_estimation_1
2020-07-08 11:34:40 +02:00
[ opt_par_values , hessian_mat , gg , fval , invhess , new_rat_hess_info ] = newrat ( objective_function , start_par_value , bounds , analytic_grad , crit , nit , 0 , Verbose , Save_files , hess_info , prior_information . p2 , options_ . gradient_epsilon , parameter_names , varargin { : } ) ; %hessian_mat is the plain outer product gradient Hessian
2021-02-13 16:44:50 +01:00
new_rat_hess_info . new_rat_hess_info = new_rat_hess_info ;
new_rat_hess_info . newratflag = newratflag ;
if options_ . analytic_derivation
options_ . analytic_derivation = old_analytic_derivation ;
end
2014-12-04 09:18:33 +01:00
case 6
2020-06-23 15:04:11 +02:00
if isempty ( prior_information ) %Inf will be reset
prior_information . p2 = Inf ( n_params , 1 ) ;
end
2015-02-24 20:34:35 +01:00
[ opt_par_values , hessian_mat , Scale , fval ] = gmhmaxlik ( objective_function , start_par_value , ...
Initial_Hessian , options_ . mh_jscale , bounds , prior_information . p2 , options_ . gmhmaxlik , options_ . optim_opt , varargin { : } ) ;
2014-12-04 09:18:33 +01:00
case 7
% Matlab's simplex (Optimization toolbox needed).
if isoctave && ~ user_has_octave_forge_package ( ' optim' )
error ( ' Option mode_compute=7 requires the optim package' )
elseif ~ isoctave && ~ user_has_matlab_license ( ' optimization_toolbox' )
error ( ' Option mode_compute=7 requires the Optimization Toolbox' )
end
optim_options = optimset ( ' display' , ' iter' , ' MaxFunEvals' , 1000000 , ' MaxIter' , 6000 , ' TolFun' , 1e-8 , ' TolX' , 1e-6 ) ;
2015-02-26 08:38:07 +01:00
if ~ isempty ( options_ . optim_opt )
2014-12-04 09:18:33 +01:00
eval ( [ ' optim_options = optimset(optim_options,' options_ . optim_opt ' );' ] ) ;
end
2015-05-02 14:21:13 +02:00
if options_ . silent_optimizer
optim_options = optimset ( optim_options , ' display' , ' off' ) ;
end
2015-04-22 11:08:32 +02:00
if ~ isoctave
[ opt_par_values , fval , exitflag ] = fminsearch ( objective_function , start_par_value , optim_options , varargin { : } ) ;
else
2016-10-21 17:37:00 +02:00
% Under Octave, use a wrapper, since fminsearch() does not have a
% 4th arg, and only has two output args
2015-04-22 11:08:32 +02:00
func = @ ( x ) objective_function ( x , varargin { : } ) ;
2016-10-21 17:37:00 +02:00
[ opt_par_values , fval ] = fminsearch ( func , start_par_value , optim_options ) ;
2015-04-22 11:08:32 +02:00
end
2014-12-04 09:18:33 +01:00
case 8
% Dynare implementation of the simplex algorithm.
simplexOptions = options_ . simplex ;
2015-02-26 08:38:07 +01:00
if ~ isempty ( options_ . optim_opt )
2014-12-04 09:18:33 +01:00
options_list = read_key_value_string ( options_ . optim_opt ) ;
for i = 1 : rows ( options_list )
switch options_list { i , 1 }
case ' MaxIter'
simplexOptions . maxiter = options_list { i , 2 } ;
case ' TolFun'
simplexOptions . tolerance . f = options_list { i , 2 } ;
case ' TolX'
simplexOptions . tolerance . x = options_list { i , 2 } ;
case ' MaxFunEvals'
simplexOptions . maxfcall = options_list { i , 2 } ;
case ' MaxFunEvalFactor'
simplexOptions . maxfcallfactor = options_list { i , 2 } ;
case ' InitialSimplexSize'
simplexOptions . delta_factor = options_list { i , 2 } ;
2015-05-13 20:58:47 +02:00
case ' verbosity'
2018-10-06 17:50:37 +02:00
simplexOptions . verbosity = options_list { i , 2 } ;
2014-12-04 09:18:33 +01:00
otherwise
warning ( [ ' simplex: Unknown option (' options_list { i , 1 } ' )!' ] )
end
end
end
2015-05-02 14:21:13 +02:00
if options_ . silent_optimizer
2018-10-06 17:50:37 +02:00
simplexOptions . verbosity = 0 ;
2017-05-16 15:10:20 +02:00
end
2014-12-04 09:18:33 +01:00
[ opt_par_values , fval , exitflag ] = simplex_optimization_routine ( objective_function , start_par_value , simplexOptions , parameter_names , varargin { : } ) ;
case 9
% Set defaults
2015-10-11 18:21:25 +02:00
H0 = ( bounds ( : , 2 ) - bounds ( : , 1 ) ) * 0.2 ;
H0 ( ~ isfinite ( H0 ) ) = 0.01 ;
2017-05-16 15:10:20 +02:00
while max ( H0 ) / min ( H0 ) > 1e6 %make sure initial search volume (SIGMA) is not badly conditioned
2017-04-12 13:39:34 +02:00
H0 ( H0 == max ( H0 ) ) = 0.9 * H0 ( H0 == max ( H0 ) ) ;
end
2014-12-04 09:18:33 +01:00
cmaesOptions = options_ . cmaes ;
2015-10-11 18:21:25 +02:00
cmaesOptions . LBounds = bounds ( : , 1 ) ;
cmaesOptions . UBounds = bounds ( : , 2 ) ;
2014-12-04 09:18:33 +01:00
% Modify defaults
2015-02-26 08:38:07 +01:00
if ~ isempty ( options_ . optim_opt )
2014-12-04 09:18:33 +01:00
options_list = read_key_value_string ( options_ . optim_opt ) ;
for i = 1 : rows ( options_list )
switch options_list { i , 1 }
case ' MaxIter'
cmaesOptions . MaxIter = options_list { i , 2 } ;
case ' TolFun'
cmaesOptions . TolFun = options_list { i , 2 } ;
case ' TolX'
cmaesOptions . TolX = options_list { i , 2 } ;
case ' MaxFunEvals'
cmaesOptions . MaxFunEvals = options_list { i , 2 } ;
2015-05-13 20:58:47 +02:00
case ' verbosity'
if options_list { i , 2 } == 0
cmaesOptions . DispFinal = ' off' ; % display messages like initial and final message';
cmaesOptions . DispModulo = ' 0' ; % [0:Inf], disp messages after every i-th iteration';
end
case ' SaveFiles'
if options_list { i , 2 } == 0
2017-05-16 15:10:20 +02:00
cmaesOptions . SaveVariables = ' off' ;
cmaesOptions . LogModulo = ' 0' ; % [0:Inf] if >1 record data less frequently after gen=100';
cmaesOptions . LogTime = ' 0' ; % [0:100] max. percentage of time for recording data';
2015-05-13 20:58:47 +02:00
end
2015-10-11 19:13:48 +02:00
case ' CMAESResume'
2017-05-16 15:10:20 +02:00
if options_list { i , 2 } == 1
2015-10-11 19:13:48 +02:00
cmaesOptions . Resume = ' yes' ;
2017-05-16 15:10:20 +02:00
end
2014-12-04 09:18:33 +01:00
otherwise
warning ( [ ' cmaes: Unknown option (' options_list { i , 1 } ' )!' ] )
end
end
end
2015-05-02 14:21:13 +02:00
if options_ . silent_optimizer
cmaesOptions . DispFinal = ' off' ; % display messages like initial and final message';
cmaesOptions . DispModulo = ' 0' ; % [0:Inf], disp messages after every i-th iteration';
cmaesOptions . SaveVariables = ' off' ;
cmaesOptions . LogModulo = ' 0' ; % [0:Inf] if >1 record data less frequently after gen=100';
cmaesOptions . LogTime = ' 0' ; % [0:100] max. percentage of time for recording data';
2017-05-16 15:10:20 +02:00
end
2014-12-04 09:18:33 +01:00
warning ( ' off' , ' CMAES:NonfinitenessRange' ) ;
warning ( ' off' , ' CMAES:InitialSigma' ) ;
[ x , fval , COUNTEVAL , STOPFLAG , OUT , BESTEVER ] = cmaes ( func2str ( objective_function ) , start_par_value , H0 , cmaesOptions , varargin { : } ) ;
opt_par_values = BESTEVER . x ;
fval = BESTEVER . f ;
case 10
simpsaOptions = options_ . simpsa ;
2015-02-26 08:38:07 +01:00
if ~ isempty ( options_ . optim_opt )
2014-12-04 09:18:33 +01:00
options_list = read_key_value_string ( options_ . optim_opt ) ;
for i = 1 : rows ( options_list )
switch options_list { i , 1 }
case ' MaxIter'
simpsaOptions . MAX_ITER_TOTAL = options_list { i , 2 } ;
case ' TolFun'
simpsaOptions . TOLFUN = options_list { i , 2 } ;
case ' TolX'
tolx = options_list { i , 2 } ;
if tolx < 0
simpsaOptions = rmfield ( simpsaOptions , ' TOLX' ) ; % Let simpsa choose the default.
else
simpsaOptions . TOLX = tolx ;
end
case ' EndTemparature'
simpsaOptions . TEMP_END = options_list { i , 2 } ;
case ' MaxFunEvals'
simpsaOptions . MAX_FUN_EVALS = options_list { i , 2 } ;
2015-05-13 20:58:47 +02:00
case ' verbosity'
2017-05-16 15:10:20 +02:00
if options_list { i , 2 } == 0
2015-05-13 20:58:47 +02:00
simpsaOptions . DISPLAY = ' none' ;
2017-05-16 15:10:20 +02:00
else
2015-05-13 20:58:47 +02:00
simpsaOptions . DISPLAY = ' iter' ;
2017-05-16 15:10:20 +02:00
end
2014-12-04 09:18:33 +01:00
otherwise
warning ( [ ' simpsa: Unknown option (' options_list { i , 1 } ' )!' ] )
end
end
end
2015-05-02 14:21:13 +02:00
if options_ . silent_optimizer
simpsaOptions . DISPLAY = ' none' ;
end
2014-12-04 09:18:33 +01:00
simpsaOptionsList = options2cell ( simpsaOptions ) ;
simpsaOptions = simpsaset ( simpsaOptionsList { : } ) ;
2015-05-07 15:59:46 +02:00
[ LB , UB ] = set_bounds_to_finite_values ( bounds , options_ . huge_number ) ;
2015-04-21 16:26:46 +02:00
[ opt_par_values , fval , exitflag ] = simpsa ( func2str ( objective_function ) , start_par_value , LB , UB , simpsaOptions , varargin { : } ) ;
2014-12-04 09:18:33 +01:00
case 11
2017-02-08 12:35:08 +01:00
options_ . cova_compute = 0 ;
2020-02-15 13:58:48 +01:00
subvarargin = [ varargin ( 1 ) , varargin ( 3 : 6 ) , varargin ( 8 ) ] ;
[ opt_par_values , stdh , lb_95 , ub_95 , med_param ] = online_auxiliary_filter ( start_par_value , subvarargin { : } ) ;
2017-02-08 12:35:08 +01:00
case 12
2019-10-09 12:30:09 +02:00
if isoctave
error ( ' Option mode_compute=12 is not available under Octave' )
2020-06-11 13:21:31 +02:00
elseif ~ user_has_matlab_license ( ' GADS_Toolbox' )
2019-10-09 12:30:09 +02:00
error ( ' Option mode_compute=12 requires the Global Optimization Toolbox' )
end
2017-02-08 12:35:08 +01:00
[ LB , UB ] = set_bounds_to_finite_values ( bounds , options_ . huge_number ) ;
tmp = transpose ( [ fieldnames ( options_ . particleswarm ) , struct2cell ( options_ . particleswarm ) ] ) ;
particleswarmOptions = optimoptions ( @ particleswarm ) ;
particleswarmOptions = optimoptions ( particleswarmOptions , tmp { : } ) ;
if ~ isempty ( options_ . optim_opt )
options_list = read_key_value_string ( options_ . optim_opt ) ;
SupportedListOfOptions = { ' CreationFcn' , ' Display' , ' DisplayInterval' , ' FunctionTolerance' , ...
2017-05-16 15:10:20 +02:00
' FunValCheck' , ' HybridFcn' , ' InertiaRange' , ' InitialSwarmMatrix' , ' InitialSwarmSpan' , ...
' MaxIterations' , ' MaxStallIterations' , ' MaxStallTime' , ' MaxTime' , ...
' MinNeighborsFraction' , ' ObjectiveLimit' , ' OutputFcn' , ' PlotFcn' , ' SelfAdjustmentWeight' , ...
' SocialAdjustmentWeight' , ' SwarmSize' , ' UseParallel' , ' UseVectorized' } ;
2017-02-08 12:35:08 +01:00
for i = 1 : rows ( options_list )
if ismember ( options_list { i , 1 } , SupportedListOfOptions )
particleswarmOptions = optimoptions ( particleswarmOptions , options_list { i , 1 } , options_list { i , 2 } ) ;
else
warning ( [ ' particleswarm: Unknown option (' options_list { i , 1 } ' )!' ] )
end
end
end
% Get number of instruments.
numberofvariables = length ( start_par_value ) ;
% Set objective function.
objfun = @ ( x ) objective_function ( x , varargin { : } ) ;
if ischar ( particleswarmOptions . SwarmSize )
eval ( [ ' particleswarmOptions.SwarmSize = ' particleswarmOptions . SwarmSize ' ;' ] )
end
if isempty ( particleswarmOptions . InitialSwarmMatrix )
particleswarmOptions . InitialSwarmMatrix = zeros ( particleswarmOptions . SwarmSize , numberofvariables ) ;
p = 1 ;
FVALS = zeros ( particleswarmOptions . SwarmSize , 1 ) ;
while p < = particleswarmOptions . SwarmSize
candidate = rand ( numberofvariables , 1 ) .* ( UB - LB ) + LB ;
[ fval , info , exit_flag ] = objfun ( candidate ) ;
if exit_flag
particleswarmOptions . InitialSwarmMatrix ( p , : ) = transpose ( candidate ) ;
FVALS ( p ) = fval ;
p = p + 1 ;
end
end
end
% Set penalty to the worst value of the objective function.
TMP = [ particleswarmOptions . InitialSwarmMatrix , FVALS ] ;
TMP = sortrows ( TMP , length ( start_par_value ) + 1 ) ;
penalty = TMP ( end , end ) ;
% Define penalized objective.
objfun = @ ( x ) penalty_objective_function ( x , objective_function , penalty , varargin { : } ) ;
% Minimize the penalized objective (note that the penalty is not updated).
[ opt_par_values , fval , exitflag , output ] = particleswarm ( objfun , length ( start_par_value ) , LB , UB , particleswarmOptions ) ;
opt_par_values = opt_par_values ( : ) ;
2021-01-24 13:19:16 +01:00
case 13
% Matlab's lsqnonlin (Optimization toolbox needed).
2022-01-04 14:33:05 +01:00
if ~ isfield ( options_ , ' mom' )
error ( ' Option mode_compute=13 is available only for method_of_moments estimation.' )
end
2021-01-24 13:19:16 +01:00
if isoctave && ~ user_has_octave_forge_package ( ' optim' )
error ( ' Option mode_compute=13 requires the optim package' )
elseif ~ isoctave && ~ user_has_matlab_license ( ' optimization_toolbox' )
error ( ' Option mode_compute=13 requires the Optimization Toolbox' )
end
2021-01-27 14:56:24 +01:00
if ~ isoctave
optim_options = optimoptions ( ' lsqnonlin' , ' display' , ' iter' , ' MaxFunEvals' , 5000 , ' MaxIter' , 5000 , ' TolFun' , 1e-6 , ' TolX' , 1e-6 ) ;
else
optim_options = optimset ( ' display' , ' iter' , ' MaxFunEvals' , 5000 , ' MaxIter' , 5000 , ' TolFun' , 1e-6 , ' TolX' , 1e-6 ) ;
end
2021-01-24 13:19:16 +01:00
if ~ isempty ( options_ . optim_opt )
2021-01-27 14:56:24 +01:00
if ~ isoctave
eval ( [ ' optim_options = optimoptions(optim_options,' options_ . optim_opt ' );' ] ) ;
else
eval ( [ ' optim_options = optimset(optim_options,' options_ . optim_opt ' );' ] ) ;
end
2021-01-24 13:19:16 +01:00
end
if options_ . silent_optimizer
optim_options . Display = ' off' ;
end
if options_ . analytic_derivation || ( isfield ( options_ , ' mom' ) && options_ . mom . analytic_jacobian == 1 )
2021-01-29 10:46:19 +01:00
if isoctave || matlab_ver_less_than ( ' 9.0' ) % Option names changed in MATLAB R2016a
optim_options . Jacobian = ' on' ;
else
optim_options . SpecifyObjectiveGradient = true ;
end
2021-01-24 13:19:16 +01:00
func = @ ( x ) analytic_gradient_wrapper ( x , objective_function , varargin { : } ) ;
[ opt_par_values , Resnorm , fval , exitflag , OUTPUT , LAMBDA , JACOB ] = ...
lsqnonlin ( func , start_par_value , bounds ( : , 1 ) , bounds ( : , 2 ) , optim_options ) ;
else
if ~ isoctave
[ opt_par_values , Resnorm , fval , exitflag , OUTPUT , LAMBDA , JACOB ] = lsqnonlin ( objective_function , start_par_value , bounds ( : , 1 ) , bounds ( : , 2 ) , optim_options , varargin { : } ) ;
else
% Under Octave, use a wrapper, since lsqnonlin() does not have a 6th arg
func = @ ( x ) objective_function ( x , varargin { : } ) ;
[ opt_par_values , Resnorm , fval , exitflag , OUTPUT , LAMBDA , JACOB ] = lsqnonlin ( func , start_par_value , bounds ( : , 1 ) , bounds ( : , 2 ) , optim_options ) ;
end
end
2014-12-04 09:18:33 +01:00
case 101
2015-04-06 11:05:12 +02:00
solveoptoptions = options_ . solveopt ;
if ~ isempty ( options_ . optim_opt )
options_list = read_key_value_string ( options_ . optim_opt ) ;
for i = 1 : rows ( options_list )
switch options_list { i , 1 }
case ' TolX'
solveoptoptions . TolX = options_list { i , 2 } ;
case ' TolFun'
solveoptoptions . TolFun = options_list { i , 2 } ;
case ' MaxIter'
solveoptoptions . MaxIter = options_list { i , 2 } ;
case ' verbosity'
solveoptoptions . verbosity = options_list { i , 2 } ;
case ' SpaceDilation'
solveoptoptions . SpaceDilation = options_list { i , 2 } ;
case ' LBGradientStep'
solveoptoptions . LBGradientStep = options_list { i , 2 } ;
otherwise
warning ( [ ' solveopt: Unknown option (' options_list { i , 1 } ' )!' ] )
end
end
end
2015-05-02 14:21:13 +02:00
if options_ . silent_optimizer
solveoptoptions . verbosity = 0 ;
end
2021-01-22 20:09:32 +01:00
if options_ . analytic_derivation || ( isfield ( options_ , ' mom' ) && options_ . mom . analytic_jacobian == 1 )
func = @ ( x ) analytic_gradient_wrapper ( x , objective_function , varargin { : } ) ;
[ opt_par_values , fval ] = solvopt ( start_par_value , func , 1 , [ ] , [ ] , solveoptoptions ) ;
else
[ opt_par_values , fval ] = solvopt ( start_par_value , objective_function , [ ] , [ ] , [ ] , solveoptoptions , varargin { : } ) ;
end
2014-12-04 09:18:33 +01:00
case 102
2015-04-15 12:42:08 +02:00
if isoctave
error ( ' Optimization algorithm 2 is not available under Octave' )
elseif ~ user_has_matlab_license ( ' GADS_Toolbox' )
error ( ' Optimization algorithm 2 requires the Global Optimization Toolbox' )
2015-04-06 11:08:20 +02:00
end
2016-05-20 19:57:58 +02:00
% Set default optimization options for simulannealbnd.
2021-01-27 14:56:24 +01:00
if ~ isoctave
optim_options = optimoptions ( ' simulannealbnd' , ' display' , ' iter' , ' TolFun' , 1e-8 ) ;
else
optim_options = saoptimset ( ' display' , ' iter' , ' TolFun' , 1e-8 ) ;
end
2015-04-15 12:42:08 +02:00
if ~ isempty ( options_ . optim_opt )
2021-01-27 14:56:24 +01:00
if ~ isoctave
eval ( [ ' optim_options = optimoptions(optim_options,' options_ . optim_opt ' );' ] ) ;
else
eval ( [ ' optim_options = saoptimset(optim_options,' options_ . optim_opt ' );' ] ) ;
end
2015-04-06 11:08:20 +02:00
end
2015-05-02 14:21:13 +02:00
if options_ . silent_optimizer
2021-01-27 14:56:24 +01:00
if ~ isoctave
optim_options = optimoptions ( optim_options , ' display' , ' off' ) ;
else
optim_options = saoptimset ( optim_options , ' display' , ' off' ) ;
end
2015-05-02 14:21:13 +02:00
end
2015-04-15 12:42:08 +02:00
func = @ ( x ) objective_function ( x , varargin { : } ) ;
[ opt_par_values , fval , exitflag , output ] = simulannealbnd ( func , start_par_value , bounds ( : , 1 ) , bounds ( : , 2 ) , optim_options ) ;
2014-12-04 09:18:33 +01:00
otherwise
if ischar ( minimizer_algorithm )
2015-05-27 18:58:17 +02:00
if exist ( minimizer_algorithm )
[ opt_par_values , fval , exitflag ] = feval ( minimizer_algorithm , objective_function , start_par_value , varargin { : } ) ;
2014-12-04 09:18:33 +01:00
else
error ( ' No minimizer with the provided name detected.' )
end
else
error ( [ ' Optimization algorithm ' int2str ( minimizer_algorithm ) ' is unknown!' ] )
end
end
2015-04-21 16:26:46 +02:00
2021-12-13 13:36:06 +01:00
if isfield ( options_ , ' occbin' ) && ( ( options_ . occbin . smoother . status && options_ . occbin . smoother . inversion_filter ) || ( options_ . occbin . likelihood . status && options_ . occbin . likelihood . inversion_filter ) )
warning ( ' on' , ' MATLAB:nearlySingularMatrix' )
end
2015-04-21 16:26:46 +02:00
end
2015-05-07 15:59:46 +02:00
function [LB, UB]= set_bounds_to_finite_values ( bounds, huge_number)
2017-05-16 15:10:20 +02:00
LB = bounds ( : , 1 ) ;
LB ( isinf ( LB ) ) = - huge_number ;
UB = bounds ( : , 2 ) ;
UB ( isinf ( UB ) ) = huge_number ;
2015-04-21 16:26:46 +02:00
end