Give access to more than one optimizer in PAC estimation (NLS).
Default is to use csminwel optimizer (because it seems to do the job and does not rely on the Mathworks toolbox).time-shift
parent
2e547edd26
commit
2437d7034e
|
@ -1,4 +1,4 @@
|
|||
function nls(eqname, params, data, range)
|
||||
function nls(eqname, params, data, range, optimizer, varargin)
|
||||
|
||||
% Estimates the parameters of a PAC equation by Nonlinear Least Squares.
|
||||
%
|
||||
|
@ -7,6 +7,12 @@ function nls(eqname, params, data, range)
|
|||
% - params [struct] Describes the parameters to be estimated.
|
||||
% - data [dseries] Database for the estimation
|
||||
% - range [dates] Range of dates for the estimation.
|
||||
% - optimizer [string] Set the optimization algorithm. Possible values
|
||||
% are 'fmincon', 'fminunc', 'csminwel',
|
||||
% 'fminsearch', 'simplex' and
|
||||
% 'annealing'. Default is 'csminwel'.
|
||||
% - varargin List of key/value pairs, each key must be a
|
||||
% string and values can be strings or real numbers.
|
||||
%
|
||||
% OUTPUTS
|
||||
% - none
|
||||
|
@ -21,6 +27,20 @@ function nls(eqname, params, data, range)
|
|||
% the variables appearing in the estimated equation. The residual of the
|
||||
% equation must have NaN values in the object.
|
||||
% [4] It is assumed that the residual is additive.
|
||||
% [5] If the used optimization routines handles inequalities over the
|
||||
% estimated parameters, we impose the positivity of the error correction parameter.
|
||||
%
|
||||
% EXAMPLE
|
||||
%
|
||||
% pac.estimate.nls('zpac', eparams, dbase, dates('2003Q1'):dates('2016Q3'),'fminunc', 'MaxIter', 50);
|
||||
%
|
||||
% where zpac is the name of the PAC equation, eparams is a structure
|
||||
% containing the guess values for the estimated parameters (in each field),
|
||||
% dbase is a dseries object containing the data,
|
||||
% dates('2003Q1'):dates('2016Q3') is the range of the sample used for
|
||||
% estimation, 'fminunc' is the name of the optimization algorithm (this one
|
||||
% is available only if the matylab optimization toolbox is installed), the
|
||||
% remaining inputs are the options (key/value) passed to the optimizers.
|
||||
|
||||
% Copyright (C) 2018 Dynare Team
|
||||
%
|
||||
|
@ -39,7 +59,7 @@ function nls(eqname, params, data, range)
|
|||
% You should have received a copy of the GNU General Public License
|
||||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
global M_ oo_
|
||||
global M_ oo_ options_
|
||||
|
||||
[pacmodl, lhs, rhs, pnames, enames, xnames, pid, eid, xid, ~, ipnames_, params, data, islaggedvariables] = ...
|
||||
pac.estimate.init(M_, oo_, eqname, params, data, range);
|
||||
|
@ -96,11 +116,16 @@ end
|
|||
% Create a routine for evaluating the sum of squared residuals
|
||||
ssrfun = ['ssr_' eqname];
|
||||
fid = fopen([ssrfun '.m'], 'w');
|
||||
fprintf(fid, 'function s = %s(params, data, DynareModel, DynareOutput)\n', ssrfun);
|
||||
fprintf(fid, 'function [s, fake1, fake2, fake3, fake4] = %s(params, data, DynareModel, DynareOutput)\n', ssrfun);
|
||||
fprintf(fid, '\n');
|
||||
fprintf(fid, '%% Evaluates the sum of square residuals for equation %s.\n', eqname);
|
||||
fprintf(fid, '%% File created by Dynare (%s).\n', datestr(datetime));
|
||||
fprintf(fid, '\n');
|
||||
fprintf(fid, 'fake1 = 0;\n');
|
||||
fprintf(fid, 'fake2 = [];\n');
|
||||
fprintf(fid, 'fake3 = [];\n');
|
||||
fprintf(fid, 'fake4 = [];\n');
|
||||
fprintf(fid, '\n');
|
||||
for i=1:length(ipnames_)
|
||||
fprintf(fid, 'DynareModel.params(%u) = params(%u);\n', ipnames_(i), i);
|
||||
end
|
||||
|
@ -123,11 +148,101 @@ ssr = @(p) feval(['ssr_' eqname], p, DATA, M_, oo_);
|
|||
% Set initial condition.
|
||||
params0 = cell2mat(struct2cell(params));
|
||||
|
||||
% Set optimization options.
|
||||
options = optimset('Display','iter');
|
||||
% Set defaults for optimizers
|
||||
bounds = [];
|
||||
parameter_names = [];
|
||||
|
||||
% Set optimizer routine.
|
||||
if nargin<5 || isempty(optimizer)
|
||||
% Use csminwel by default.
|
||||
minalgo = 4;
|
||||
else
|
||||
switch optimizer
|
||||
case 'fmincon'
|
||||
minalgo = 1;
|
||||
bounds = ones(length(params0),1)*[-10,10];
|
||||
bounds(strcmp(fieldnames(params), M_.param_names(M_.pac.pacman.ec.params)),1) = .0;
|
||||
case 'fminunc'
|
||||
minalgo = 3;
|
||||
case 'csminwel'
|
||||
minalgo = 4;
|
||||
case 'fminsearch'
|
||||
minalgo = 7;
|
||||
case 'simplex'
|
||||
minalgo = 8;
|
||||
case 'annealing'
|
||||
minalgo = 2;
|
||||
bounds = ones(length(params0),1)*[-10,10];
|
||||
bounds(strcmp(fieldnames(params), M_.param_names(M_.pac.pacman.ec.params)),1) = .0;
|
||||
parameter_names = fieldnames(params);
|
||||
case 'particleswarm'
|
||||
minalgo = 12;
|
||||
bounds = ones(length(params0),1)*[-10,10];
|
||||
bounds(strcmp(fieldnames(params), M_.param_names(M_.pac.pacman.ec.params)),1) = .0;
|
||||
parameter_names = fieldnames(params);
|
||||
otherwise
|
||||
msg = sprintf('%s is not an implemented optimization routine.\n', optimizer);
|
||||
msg = sprintf('%sAvailable algorithms are:\n', msg);
|
||||
msg = sprintf('%s - %s\n', msg, 'fmincon');
|
||||
msg = sprintf('%s - %s\n', msg, 'fminunc');
|
||||
msg = sprintf('%s - %s\n', msg, 'csminwel');
|
||||
msg = sprintf('%s - %s\n', msg, 'fminsearch');
|
||||
msg = sprintf('%s - %s\n', msg, 'simplex');
|
||||
msg = sprintf('%s - %s\n', msg, 'annealing');
|
||||
error(msg)
|
||||
end
|
||||
end
|
||||
|
||||
% Set options if provided as input arguments to nls routine.
|
||||
oldopt = options_.optim_opt;
|
||||
if nargin>5
|
||||
if mod(nargin-5, 2)
|
||||
error('Options must come by key/value pairs.')
|
||||
end
|
||||
i = 1;
|
||||
opt = '';
|
||||
while i<nargin-5
|
||||
if i==1
|
||||
opt = sprintf('''%s'',', varargin{i});
|
||||
else
|
||||
opt = sprintf('%s,''%s'',', opt, varargin{i});
|
||||
end
|
||||
if isnumeric(varargin{i+1})
|
||||
if (i+1)==(nargin-5)
|
||||
opt = sprintf('%s%s', opt, varargin{i+1});
|
||||
else
|
||||
opt = sprintf('%s%s,', opt, varargin{i+1});
|
||||
end
|
||||
else
|
||||
if (i+1)==(nargin-5)
|
||||
opt = sprintf('%s''%s''', opt, varargin{i+1});
|
||||
else
|
||||
opt = sprintf('%s''%s'',', opt, varargin{i+1});
|
||||
end
|
||||
end
|
||||
i = i+2;
|
||||
end
|
||||
options_.optim_opt = opt;
|
||||
else
|
||||
options_.optim_opt = [];
|
||||
end
|
||||
if nargin<5
|
||||
% If default optimization algorithm is used (csminwel), do not print
|
||||
% iterations.
|
||||
options_.optim_opt = '''verbosity'',0';
|
||||
end
|
||||
|
||||
|
||||
% Estimate the parameters by minimizing the sum of squared residuals.
|
||||
pparams1 = fminunc(ssr, params0, options);
|
||||
[pparams1, SSR, exitflag] = dynare_minimize_objective(ssr, params0, ...
|
||||
minalgo, ...
|
||||
options_, ...
|
||||
bounds, ...
|
||||
parameter_names, ...
|
||||
[], ...
|
||||
[]);
|
||||
|
||||
options_.optim_opt = oldopt;
|
||||
|
||||
% Update M_.params
|
||||
for i=1:length(pparams1)
|
||||
|
|
Loading…
Reference in New Issue