From e6c716ae9b326c2aff56dde119603fda27e7853a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemia=20=28Scylla=29?= Date: Mon, 26 Nov 2018 09:53:18 +0100 Subject: [PATCH] Added the possibility to use Gauss-Newton in pac/nls. Also added the computation of the covariance matrix of the NLS estimator (using White and Domovitz approach) and integration test. --- matlab/+pac/+estimate/nls.m | 101 ++++++++++---- tests/pac/trend-component-17/clean | 8 ++ tests/pac/trend-component-17/example.mod | 160 +++++++++++++++++++++++ 3 files changed, 241 insertions(+), 28 deletions(-) create mode 100755 tests/pac/trend-component-17/clean create mode 100644 tests/pac/trend-component-17/example.mod diff --git a/matlab/+pac/+estimate/nls.m b/matlab/+pac/+estimate/nls.m index c21001d48..44fd9416d 100644 --- a/matlab/+pac/+estimate/nls.m +++ b/matlab/+pac/+estimate/nls.m @@ -61,6 +61,13 @@ function nls(eqname, params, data, range, optimizer, varargin) global M_ oo_ options_ +is_gauss_newton = false; +objective = 'ssr_'; +if nargin>4 && isequal(optimizer, 'GaussNewton') + is_gauss_newton = true; + objective = 'r_'; +end + [pacmodl, lhs, rhs, pnames, enames, xnames, pid, eid, xid, ~, ipnames_, params, data, islaggedvariables] = ... pac.estimate.init(M_, oo_, eqname, params, data, range); @@ -113,10 +120,27 @@ for i=1:length(objNames) end end -% Create a routine for evaluating the sum of squared residuals -ssrfun = ['ssr_' eqname]; -fid = fopen([ssrfun '.m'], 'w'); -fprintf(fid, 'function [s, fake1, fake2, fake3, fake4] = %s(params, data, DynareModel, DynareOutput)\n', ssrfun); +% Create a routine for evaluating the residuals of the nonlinear model +fun = ['r_' eqname]; +fid = fopen(['+' M_.fname filesep() fun '.m'], 'w'); +fprintf(fid, 'function r = %s(params, data, DynareModel, DynareOutput)\n', fun); +fprintf(fid, '\n'); +fprintf(fid, '%% Evaluates the residuals for equation %s.\n', eqname); +fprintf(fid, '%% File created by Dynare (%s).\n', datestr(datetime)); +fprintf(fid, '\n'); +for i=1:length(ipnames_) + fprintf(fid, 'DynareModel.params(%u) = params(%u);\n', ipnames_(i), i); +end +fprintf(fid, '\n'); +fprintf(fid, 'DynareModel = pac.update.parameters(''%s'', DynareModel, DynareOutput);\n', pacmodl); +fprintf(fid, '\n'); +fprintf(fid, 'r = %s-(%s);\n', lhs, rhs); +fclose(fid); + +% Create a routine for evaluating the sum of squared residuals of the nonlinear model +fun = ['ssr_' eqname]; +fid = fopen(['+' M_.fname filesep() fun '.m'], 'w'); +fprintf(fid, 'function [s, fake1, fake2, fake3, fake4] = %s(params, data, DynareModel, DynareOutput)\n', fun); 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)); @@ -136,10 +160,14 @@ fprintf(fid, 'r = %s-(%s);\n', lhs, rhs); fprintf(fid, 's = r''*r;\n'); fclose(fid); -% Create a function handle returning the sum of square residuals for a given -% vector of parameters. +% Copy (sub)sample data in a matrix. DATA = data([range(1)-1, range]).data; -ssr = @(p) feval(['ssr_' eqname], p, DATA, M_, oo_); + +% Create a function handle returning the sum of square residuals for a given vector of parameters. +ssrfun = @(p) feval([M_.fname '.ssr_' eqname], p, DATA, M_, oo_); + +% Create a function handle returning the sum of square residuals for a given vector of parameters. +resfun = @(p) feval([M_.fname '.r_' eqname], p, DATA, M_, oo_); % Set initial condition. params0 = cell2mat(struct2cell(params)); @@ -154,6 +182,8 @@ if nargin<5 || isempty(optimizer) minalgo = 4; else switch optimizer + case 'GaussNewton' + % Nothing to do here. case 'fmincon' if isoctave error('Optimization algorithm ''fmincon'' is not available under Octave') @@ -205,6 +235,7 @@ else msg = sprintf('%s - %s\n', msg, 'fminsearch'); msg = sprintf('%s - %s\n', msg, 'simplex'); msg = sprintf('%s - %s\n', msg, 'annealing'); + msg = sprintf('%s - %s\n', msg, 'GaussNewton'); error(msg) end end @@ -219,22 +250,14 @@ if nargin>5 opt = ''; while i.01 + error('Gauss Newton and direct SSR minimization do not provide consistent estimates (e_c_m)') +end + +if abs(c_z_1_nls-c_z_1_gauss_newton)>.01 + error('Gauss Newton and direct SSR minimization do not provide consistent estimates (c_z_1)') +end + +if abs(c_z_2_nls-c_z_2_gauss_newton)>.01 + error('Gauss Newton and direct SSR minimization do not provide consistent estimates (c_z_2)') +end + +if abs(lambda_nls-lambda_gauss_newton)>.01 + error('Gauss Newton and direct SSR minimization do not provide consistent estimates (lambda)') +end \ No newline at end of file