Compare commits

...

15 Commits

Author SHA1 Message Date
Stéphane Adjemian (Ryûk) 572db78143
Add the possibility to specify bounds for the BGP solver. 2022-10-23 17:16:36 +02:00
Stéphane Adjemian (Ryûk) 872de4e781
Fix typo. 2022-10-20 17:56:21 +02:00
Stéphane Adjemian (Ryûk) e82ba1b626
Bug fix (related to constraints on growth factors again). 2022-10-20 13:20:39 +02:00
Stéphane Adjemian (Ryûk) e7d37e177b
Bug fix (wrong index for constrained growth factors) + cosmetic. 2022-10-19 10:58:10 +02:00
Stéphane Adjemian (Ryûk) fb2390b7c8
Add missing call to fclose. 2022-10-18 15:17:51 +02:00
Stéphane Adjemian (Ryûk) b99a83120d
Bug fix.
Calibration of growth factors were not working.
2022-10-18 14:37:56 +02:00
Stéphane Adjemian (Ryûk) 56a874d428
Test that additional arguments come by key/value pairs. 2022-10-18 10:22:33 +02:00
Stéphane Adjemian (Ryûk) a89c9198dc
Terminate function with end. 2022-10-17 22:17:13 +02:00
Stéphane Adjemian (Charybdis) cf98446219
Add normalization (hard constraints on endogenous variables). 2022-10-17 22:06:51 +02:00
Stéphane Adjemian (Ryûk) 2c5b58e8ef
Cosmetic change. 2022-10-17 16:48:14 +02:00
Stéphane Adjemian (Ryûk) 8f3e56b85b
Add unit tests for the generated BGP routine (jacobian matrix). 2022-10-17 16:48:14 +02:00
Stéphane Adjemian (Ryûk) c7b7bd9b8d
Cosmetic change (moved conditional statement inside verbatim block). 2022-10-17 16:48:14 +02:00
Stéphane Adjemian (Ryûk) c1ec097ea0
Add randomness in the initial guess for the growth factors. 2022-10-17 16:48:14 +02:00
Stéphane Adjemian (Ryûk) 5e3603a1b6
Remove useless condition (since octave is already disabled). 2022-10-17 16:48:14 +02:00
Stéphane Adjemian (Ryûk) dcc831254e
Reduce the number of simulations. 2022-10-17 16:48:14 +02:00
16 changed files with 1039 additions and 310 deletions

47
matlab/+bgp/+hdl/in.m Normal file
View File

@ -0,0 +1,47 @@
function Variables = in(DynareModel, constraints, variables, id)
if ~iscell(constraints)
error('Second argument must be a one-dimensional cell array.')
end
if mod(length(constraints), 2)
error('Number of elements in second argument must be even.')
end
if nargin<4
id = zeros(length(constraints)/2,1);
j = 1;
for i=1:2:length(constraints)
if isempty(regexp(constraints{i}, 'G\(\w+\)')) i
tmp = find(strcmp(constraints{i}, DynareModel.endo_names));
else
tmp = find(strcmp(constraints{i}(3:end-1), DynareModel.endo_names));
if ~isempty(tmp)
tmp = tmp+DynareModel.endo_nbr;
end
end
if isempty(tmp)
error('Unknown variable (%s).', constraints{i})
else
id(j) = tmp;
end
j = j+1;
end
end
Variables = NaN(2*DynareModel.endo_nbr, 1);
jj = 1:length(Variables);
ll = setdiff(jj, id);
Variables(ll) = variables;
values = NaN(length(constraints)/2, 1);
j = 1;
for i=2:2:length(constraints)
values(j) = constraints{i};
j = j+1;
end
Variables(id) = values;

29
matlab/+bgp/+hdl/out.m Normal file
View File

@ -0,0 +1,29 @@
function [variables, id] = out(DynareModel, constraints, variables)
if ~iscell(constraints)
error('Second argument must be a one-dimensional cell array.')
end
if mod(length(constraints), 2)
error('Number of elements in second argument must be even.')
end
id = zeros(length(constraints)/2,1);
j = 1;
for i=1:2:length(constraints)
if isempty(regexp(constraints{i}, 'G\(\w+\)'))
tmp = find(strcmp(constraints{i}, DynareModel.endo_names));
else
tmp = find(strcmp(constraints{i}(3:end-1), DynareModel.endo_names));
if ~isempty(tmp)
tmp = tmp+DynareModel.endo_nbr;
end
end
assert(~isempty(tmp), 'Unknown variable (%s).', constraints{i})
id(j) = tmp;
j = j+1;
end
variables(id) = [];

101
matlab/+bgp/+transform/in.m Normal file
View File

@ -0,0 +1,101 @@
function Variables = in(DynareModel, constraints, variables, id, lb, ub)
if ~iscell(constraints)
error('Second argument must be a one-dimensional cell array.')
end
if iskeyvalue(constraints)
if nargin<4
id = zeros(length(constraints)/2,1);
j = 1;
for i=1:2:length(constraints)
if isempty(regexp(constraints{i}, 'G\(\w+\)')) i
tmp = find(strcmp(constraints{i}, DynareModel.endo_names));
else
tmp = find(strcmp(constraints{i}(3:end-1), DynareModel.endo_names));
if ~isempty(tmp)
tmp = tmp+DynareModel.endo_nbr;
end
end
if isempty(tmp)
error('Unknown variable (%s).', constraints{i})
else
id(j) = tmp;
end
j = j+1;
end
end
Variables = NaN(2*DynareModel.endo_nbr, 1);
jj = 1:length(Variables);
ll = setdiff(jj, id);
Variables(ll) = variables;
values = NaN(length(constraints)/2, 1);
j = 1;
for i=2:2:length(constraints)
values(j) = constraints{i};
j = j+1;
end
Variables(id) = values;
return
end
if iskeyvalues(constraints)
halfline.right = @(x, a) a+exp(x);
halfline.left = @(x, a) a-exp(x);
interval = @(x, a, b) a+(b-a)/(1+exp(x));
if nargin<4
id = zeros(length(constraints)/3,1);
lb = [-Inf(DynareModel.endo_nbr, 1); zeros(DynareModel.endo_nbr, 1)];
ub = Inf(2*DynareModel.endo_nbr, 1);
j = 1;
for i=1:3:length(constraints)
if isempty(regexp(constraints{i}, 'G\(\w+\)'))
tmp = find(strcmp(constraints{i}, DynareModel.endo_names));
else
tmp = find(strcmp(constraints{i}(3:end-1), DynareModel.endo_names));
if ~isempty(tmp)
tmp = tmp + DynareModel.endo_nbr;
end
end
assert(~isempty(tmp), 'Unknown variable (%s).', constraints{i})
lb(tmp) = constraints{i+1};
ub(tmp) = constraints{i+2};
if abs(lb(tmp)-ub(tmp))<1e-6
id(j) = tmp;
end
j = j+1;
end
id = id(id>0);
end
Variables = NaN(2*DynareModel.endo_nbr, 1);
jj = 1:length(Variables);
ll = setdiff(jj, id);
Variables(ll) = variables;
values = NaN(length(id), 1);
j = 1;
for i=1:length(id)
if id(i)>DynareModel.endo_nbr
j = find(strcmp(sprintf('G(%s)', DynareModel.endo_names{id(i)-DynareModel.endo_nbr}), constraints));
else
j = find(strcmp(sprintf('%s', DynareModel.endo_names{id(i)}), constraints));
end
assert(~isempty(j), 'Unknown variable (indexing issue).')
values(i) = constraints{j+1};
end
Variables(id) = values;
for i=1:length(Variables)
if isfinite(lb(i)) && isinf(ub(i))
Variables(i) = halfline.right(Variables(i), lb(i));
elseif isinf(lb(i)) && isfinite(ub(i))
Variables(i) = halfline.left(Variables(i), ub(i));
elseif isfinite(lb(i)) && isfinite(ub(i)) && ub(i)-lb(i)>1e-6
Variables(i) = interval(Variables(i), lb(i), ub(i));
end
end
return
end
error('Second argument must be a cell array of key/value pairs or key/values triplets.')
end

View File

@ -0,0 +1,78 @@
function [variables, id, lb, ub] = out(DynareModel, constraints, variables)
if ~iscell(constraints)
error('Second argument must be a one-dimensional cell array.')
end
if iskeyvalue(constraints)
% Calibrated variables.
id = zeros(length(constraints)/2,1);
j = 1;
for i=1:2:length(constraints)
if isempty(regexp(constraints{i}, 'G\(\w+\)'))
tmp = find(strcmp(constraints{i}, DynareModel.endo_names));
else
tmp = DynareModel.endo_nbr+find(strcmp(constraints{i}(3:end-1), DynareModel.endo_names));
end
assert(~isempty(tmp), 'Unknown variable (%s).', constraints{i})
id(j) = tmp;
j = j+1;
end
variables(id) = [];
lb = []; ub = [];
return
end
if iskeyvalues(constraints)
% Boundaries on variables and calibrated variables
halfline.right = @(x, a) log(x-a);
halfline.x = @(left, a) log(a-x);
interval = @(x, a, b) log(x-a)-log(b-x);
id = zeros(length(constraints)/3,1);
lb = [-Inf(DynareModel.endo_nbr, 1); zeros(DynareModel.endo_nbr, 1)];
ub = Inf(2*DynareModel.endo_nbr, 1);
j = 1;
for i=1:3:length(constraints)
if isempty(regexp(constraints{i}, 'G\(\w+\)'))
tmp = find(strcmp(constraints{i}, DynareModel.endo_names));
else
tmp = find(strcmp(constraints{i}(3:end-1), DynareModel.endo_names));
if isempty(tmp)
tmp = tmp + DynareModel.endo_nbr;
end
end
assert(~isempty(tmp), 'Unknown variable (%s).', constraints{i})
lb(tmp) = constraints{i+1};
ub(tmp) = constraints{i+2};
if abs(lb(tmp)-ub(tmp))<1e-6
id(j) = tmp;
end
j = j+1;
end
id = id(id>0);
id
for i=1:2*DynareModel.endo_nbr
if ~ismember(i, id)
if i>DynareModel.endo_nbr
assert(lb(i)<variables(i) && ub(i)>variables(i), 'Initial condition not consistent with declared boundaries (G(%s)).', DynareModel.endo_names{i-DynareModel.endo_nbr})
else
assert(lb(i)<variables(i) && ub(i)>variables(i), 'Initial condition not consistent with declared boundaries (%s)', DynareModel.endo_names{i})
end
if isfinite(lb(i)) && isinf(ub(i))
variables(i) = halfline.right(variables(i), lb(i));
elseif isinf(lb(i)) && isfinite(ub(i))
variables(i) = halfline.left(variables(i), ub(i));
elseif isfinite(lb(i)) && isfinite(ub(i)) && lb(i)<ub(i)
variables(i) = interval(variables(i), lb(i), ub(i));
end
end
end
length(variables)
variables(id) = [];
length(variables)
return
end
error('Second argument must be a cell array of key/value pairs or key/values triplets.')
end

View File

@ -1,4 +1,4 @@
function write(DynareModel)
function write(DynareModel, varargin)
% Writes the nonlinear problem to be solved for computing the growth
% rates and levels along the Balanced Growth Path. Note that for
@ -15,7 +15,7 @@ function write(DynareModel)
% REMARKS
% - The trends are assumed to be multiplicative.
% Copyright © 2019 Dynare Team
% Copyright © 2019-2022 Dynare Team
%
% This file is part of Dynare.
%
@ -32,156 +32,185 @@ function write(DynareModel)
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
if DynareModel.maximum_lag && ~DynareModel.maximum_lead
i0 = transpose(DynareModel.lead_lag_incidence(1,:)); % Indices of the lagged variables.
i1 = transpose(DynareModel.lead_lag_incidence(2,:)); % Indices of the current variables.
i2 = []; % Indices of the leaded variables.
elseif DynareModel.maximum_lag && DynareModel.maximum_lead
i0 = transpose(DynareModel.lead_lag_incidence(1,:)); % Indices of the lagged variables.
i1 = transpose(DynareModel.lead_lag_incidence(2,:)); % Indices of the current variables.
i2 = transpose(DynareModel.lead_lag_incidence(3,:)); % Indices of the leaded variables.
elseif ~DynareModel.maximum_lag && DynareModel.maximum_lead
i0 = []; % Indices of the lagged variables.
i1 = transpose(DynareModel.lead_lag_incidence(1,:)); % Indices of the current variables.
i2 = transpose(DynareModel.lead_lag_incidence(2,:)); % Indices of the leaded variables.
else
error('The model is static. The BGP is trivial.')
end
n0 = length(find(i0)); % Number of lagged variables.
n1 = length(find(i1)); % Number of current variables.
n2 = length(find(i2)); % Number of leaded variables.
purely_backward_model = logical(n0 && n1 && ~n2);
purely_forward_model = logical(~n0 && n1 && n2);
if purely_backward_model
I0 = i0;
I1 = i1;
I2 = [];
elseif purely_forward_model
I0 = i1;
I1 = i2;
I2 = [];
else
% Model has both leads and lags.
I0 = i0;
I1 = i1;
I2 = i2;
end
% Create function in mod namespace.
fid = fopen(sprintf('+%s/bgpfun.m', DynareModel.fname), 'w');
% Write header.
fprintf(fid, 'function [F, JAC] = bgpfun(z)\n\n');
fprintf(fid, '%% This file has been generated by dynare (%s).\n\n', datestr(now));
% The function admits a unique vector as input argument. The first
% half of the elements are for the levels of the endogenous
% variables, the second half for the growth factors.
fprintf(fid, 'y = z(1:%u);\n\n', DynareModel.endo_nbr);
fprintf(fid, 'g = z(%u:%u);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr);
% Define the point where the dynamic model is to be evaluated.
fprintf(fid, 'Y = zeros(%u, 1);\n', 2*(n0+n1+n2));
for i=1:length(I0) % period t equations, lagged variables.
if I0(i)
fprintf(fid, 'Y(%u) = y(%u);\n', I0(i), i);
end
end
for i=1:length(I1) % period t equations, current variables.
if I1(i)
fprintf(fid, 'Y(%u) = y(%u)*g(%u);\n', I1(i), i, i);
end
end
for i=1:length(I2) % period t equations, leaded variables.
if I2(i)
fprintf(fid, 'Y(%u) = y(%u)*g(%u)*g(%u);\n', I2(i), i, i, i);
end
end
for i=1:length(I0) % period t+1 equations lagged variables.
if I0(i)
fprintf(fid, 'Y(%u) = y(%u)*g(%u);\n', n0+n1+n2+I0(i), i, i);
end
end
for i=1:length(I1) % period t+1 equations current variables.
if I1(i)
fprintf(fid, 'Y(%u) = y(%u)*g(%u)*g(%u);\n', n0+n1+n2+I1(i), i, i, i);
end
end
for i=1:length(I2) % period t+1 equations leaded variables.
if I2(i)
fprintf(fid, 'Y(%u) = y(%u)*g(%u)*g(%u)*g(%u);\n', n0+n1+n2+I2(i), i, i, i, i);
end
end
fprintf(fid, '\n');
% Define the vector of parameters.
fprintf(fid, 'p = zeros(%u, 1);\n', DynareModel.param_nbr);
for i = 1:DynareModel.param_nbr
fprintf(fid, 'p(%u) = %16.12f;\n', i, DynareModel.params(i));
end
fprintf(fid, '\n');
% Initialize the vector holding the residuals over the two periods.
fprintf(fid, 'F = NaN(%u, 1);\n', 2*DynareModel.endo_nbr);
% Set vector of exogenous variables to 0.
fprintf(fid, 'x = zeros(1, %u);\n\n', DynareModel.exo_nbr);
% Evaluate the residuals and jacobian of the dynamic model in periods t and t+1.
fprintf(fid, 'if nargout>1\n');
fprintf(fid, ' J = zeros(%u, %u);\n', 2*DynareModel.endo_nbr, n0+n1+n2+DynareModel.endo_nbr);
fprintf(fid, ' [F(1:%u), tmp] = %s.dynamic(Y(1:%u), x, p, y, 1);\n', DynareModel.endo_nbr, DynareModel.fname, n0+n1+n2);
fprintf(fid, ' J(1:%u,1:%u) = tmp(:,1:%u);\n', DynareModel.endo_nbr, n0+n1+n2, n0+n1+n2);
fprintf(fid, ' [F(%u:%u), tmp] = %s.dynamic(Y(1+%u:%u), x, p, y, 1);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, DynareModel.fname, n0+n1+n2, 2*(n0+n1+n2));
fprintf(fid, ' J(%u:%u,1:%u) = tmp(:,1:%u);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, n0+n1+n2, n0+n1+n2);
fprintf(fid, 'else\n');
fprintf(fid, ' F(1:%u) = %s.dynamic(Y(1:%u), x, p, y, 1);\n', DynareModel.endo_nbr, DynareModel.fname, n0+n1+n2);
fprintf(fid, ' F(%u:%u) = %s.dynamic(Y(1+%u:%u), x, p, y, 1);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, DynareModel.fname, n0+n1+n2, 2*(n0+n1+n2));
fprintf(fid, 'end\n\n');
% Compute the jacobian if required.
fprintf(fid, 'if nargout>1\n');
fprintf(fid, ' JAC = zeros(%u,%u);\n', 2*DynareModel.endo_nbr, 2*DynareModel.endo_nbr);
% Compute the derivatives of the first block of equations (period t)
% with respect to the endogenous variables.
if purely_backward_model || purely_forward_model
for i=1:DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I1(j)
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)+J(%u,%u)*g(%u);\n', i, j, i, I0(j), i, I1(j), j);
if nargin>1
if iskeyvalue(varargin)
idy = NaN(length(varargin)/2, 1);
vly = NaN(length(varargin)/2, 1);
idg = NaN(length(varargin)/2, 1);
vlg = NaN(length(varargin)/2, 1);
prn = 0;
for i=1:2:length(varargin)
prn = prn+1;
if ismember(varargin{i}, DynareModel.endo_names)
idy(prn) = find(strcmp(varargin{i}, DynareModel.endo_names));
vly(prn) = varargin{i+1};
elseif ~isempty(regexp(varargin{i}, 'G\(\w+\)')) && ismember(varargin{i}(3:end-1), DynareModel.endo_names)
idg(prn) = find(strcmp(varargin{i}(3:end-1),DynareModel.endo_names));
vlg(prn) = varargin{i+1};
else
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u);\n', i, j, i, I1(j), j);
end
else
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u);\n', i, j, i, I0(j));
error('Wrong input arguments (%s is not an endogenous variable).', varargin{1})
end
end
end
end
else
for i=1:DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I2(j)
if I1(j)
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)+J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I0(j), i, I1(j), j, i, I2(j), j, j);
else
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I1(j), j, i, I2(j), j, j);
elseif iskeyvalues(varargin)
idy = NaN(length(varargin)/3, 1);
vly = NaN(length(varargin)/3, 1);
idg = NaN(length(varargin)/3, 1);
vlg = NaN(length(varargin)/3, 1);
lb = [-Inf(DynareModel.endo_nbr, 1); zeros(DynareModel.endo_nbr, 1)];
ub = Inf(2*DynareModel.endo_nbr, 1);
prn = 0;
for i=1:3:length(varargin)
prn = prn+1;
if ismember(varargin{i}, DynareModel.endo_names)
j = find(strcmp(varargin{i}, DynareModel.endo_names));
lb(j) = varargin{i+1};
ub(j) = varargin{i+2};
if ub(j)-lb(j)<0
error('An upper bound cannot be smaller than a lower bound (%s).', varargin{i})
end
if ub(j)-lb(j)<1e-6
idy(prn) = find(strcmp(varargin{i}, DynareModel.endo_names));
vly(prn) = varargin{i+1};
end
elseif ~isempty(regexp(varargin{i}, 'G\(\w+\)')) && ismember(varargin{i}(3:end-1), DynareModel.endo_names)
j = DynareModel.endo_nbr+find(strcmp(varargin{i}(3:end-1), DynareModel.endo_names));
lb(j) = varargin{i+1};
ub(j) = varargin{i+2};
if ub(j)-lb(j)<0
error('An upper bound cannot be smaller than a lower bound (%s).', varargin{i})
end
if ub(j)-lb(j)<1e-6
idg(prn) = find(strcmp(varargin{i}, DynareModel.endo_names));
vlg(prn) = varargin{i+1};
end
else
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I0(j), i, I2(j), j, j);
else
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I2(j), j, j);
end
error('Wrong input arguments (%s is not an endogenous variable).', varargin{1})
end
else
end
else
error('Wrong input arguments.')
end
end
if DynareModel.maximum_lag && ~DynareModel.maximum_lead
i0 = transpose(DynareModel.lead_lag_incidence(1,:)); % Indices of the lagged variables.
i1 = transpose(DynareModel.lead_lag_incidence(2,:)); % Indices of the current variables.
i2 = []; % Indices of the leaded variables.
elseif DynareModel.maximum_lag && DynareModel.maximum_lead
i0 = transpose(DynareModel.lead_lag_incidence(1,:)); % Indices of the lagged variables.
i1 = transpose(DynareModel.lead_lag_incidence(2,:)); % Indices of the current variables.
i2 = transpose(DynareModel.lead_lag_incidence(3,:)); % Indices of the leaded variables.
elseif ~DynareModel.maximum_lag && DynareModel.maximum_lead
i0 = []; % Indices of the lagged variables.
i1 = transpose(DynareModel.lead_lag_incidence(1,:)); % Indices of the current variables.
i2 = transpose(DynareModel.lead_lag_incidence(2,:)); % Indices of the leaded variables.
else
error('The model is static. The BGP is trivial.')
end
n0 = length(find(i0)); % Number of lagged variables.
n1 = length(find(i1)); % Number of current variables.
n2 = length(find(i2)); % Number of leaded variables.
purely_backward_model = logical(n0 && n1 && ~n2);
purely_forward_model = logical(~n0 && n1 && n2);
if purely_backward_model
I0 = i0;
I1 = i1;
I2 = [];
elseif purely_forward_model
I0 = i1;
I1 = i2;
I2 = [];
else
% Model has both leads and lags.
I0 = i0;
I1 = i1;
I2 = i2;
end
% Create function in mod namespace.
fid = fopen(sprintf('+%s/bgpfun.m', DynareModel.fname), 'w');
% Write header.
fprintf(fid, 'function [F, JAC] = bgpfun(z)\n\n');
fprintf(fid, '%% This file has been generated by dynare (%s).\n\n', datestr(now));
% The function admits a unique vector as input argument. The first
% half of the elements are for the levels of the endogenous
% variables, the second half for the growth factors.
fprintf(fid, 'y = z(1:%u);\n\n', DynareModel.endo_nbr);
fprintf(fid, 'g = z(%u:%u);\n\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr);
% Define the point where the dynamic model is to be evaluated.
fprintf(fid, 'Y = zeros(%u, 1);\n', 2*(n0+n1+n2));
for i=1:length(I0) % period t equations, lagged variables.
if I0(i)
fprintf(fid, 'Y(%u) = y(%u);\n', I0(i), i);
end
end
for i=1:length(I1) % period t equations, current variables.
if I1(i)
fprintf(fid, 'Y(%u) = y(%u)*g(%u);\n', I1(i), i, i);
end
end
for i=1:length(I2) % period t equations, leaded variables.
if I2(i)
fprintf(fid, 'Y(%u) = y(%u)*g(%u)*g(%u);\n', I2(i), i, i, i);
end
end
for i=1:length(I0) % period t+1 equations lagged variables.
if I0(i)
fprintf(fid, 'Y(%u) = y(%u)*g(%u);\n', n0+n1+n2+I0(i), i, i);
end
end
for i=1:length(I1) % period t+1 equations current variables.
if I1(i)
fprintf(fid, 'Y(%u) = y(%u)*g(%u)*g(%u);\n', n0+n1+n2+I1(i), i, i, i);
end
end
for i=1:length(I2) % period t+1 equations leaded variables.
if I2(i)
fprintf(fid, 'Y(%u) = y(%u)*g(%u)*g(%u)*g(%u);\n', n0+n1+n2+I2(i), i, i, i, i);
end
end
fprintf(fid, '\n');
% Define the vector of parameters.
fprintf(fid, 'p = zeros(%u, 1);\n', DynareModel.param_nbr);
for i = 1:DynareModel.param_nbr
fprintf(fid, 'p(%u) = %16.12f;\n', i, DynareModel.params(i));
end
fprintf(fid, '\n');
% Initialize the vector holding the residuals over the two periods.
fprintf(fid, 'F = NaN(%u, 1);\n', 2*DynareModel.endo_nbr);
% Set vector of exogenous variables to 0.
fprintf(fid, 'x = zeros(1, %u);\n\n', DynareModel.exo_nbr);
% Evaluate the residuals and jacobian of the dynamic model in periods t and t+1.
fprintf(fid, 'if nargout>1\n');
fprintf(fid, ' J = zeros(%u, %u);\n', 2*DynareModel.endo_nbr, n0+n1+n2+DynareModel.endo_nbr);
fprintf(fid, ' [F(1:%u), tmp] = %s.dynamic(Y(1:%u), x, p, y, 1);\n', DynareModel.endo_nbr, DynareModel.fname, n0+n1+n2);
fprintf(fid, ' J(1:%u,1:%u) = tmp(:,1:%u);\n', DynareModel.endo_nbr, n0+n1+n2, n0+n1+n2);
fprintf(fid, ' [F(%u:%u), tmp] = %s.dynamic(Y(1+%u:%u), x, p, y, 1);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, DynareModel.fname, n0+n1+n2, 2*(n0+n1+n2));
fprintf(fid, ' J(%u:%u,1:%u) = tmp(:,1:%u);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, n0+n1+n2, n0+n1+n2);
fprintf(fid, 'else\n');
fprintf(fid, ' F(1:%u) = %s.dynamic(Y(1:%u), x, p, y, 1);\n', DynareModel.endo_nbr, DynareModel.fname, n0+n1+n2);
fprintf(fid, ' F(%u:%u) = %s.dynamic(Y(1+%u:%u), x, p, y, 1);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, DynareModel.fname, n0+n1+n2, 2*(n0+n1+n2));
fprintf(fid, 'end\n\n');
% Compute the jacobian if required.
fprintf(fid, 'if nargout>1\n');
fprintf(fid, ' JAC = zeros(%u,%u);\n', 2*DynareModel.endo_nbr, 2*DynareModel.endo_nbr);
% Compute the derivatives of the first block of equations (period t)
% with respect to the endogenous variables.
if purely_backward_model || purely_forward_model
for i=1:DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I1(j)
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)+J(%u,%u)*g(%u);\n', i, j, i, I0(j), i, I1(j), j);
@ -195,45 +224,45 @@ else
end
end
end
end
end
% Compute the derivatives of the second block of equations (period t+1)
% with respect to the endogenous variables.
if purely_backward_model || purely_forward_model
for i=DynareModel.eq_nbr+1:2*DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I1(j)
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I0(j), j, i, I1(j), j, j);
else
for i=1:DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I2(j)
if I1(j)
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)+J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I0(j), i, I1(j), j, i, I2(j), j, j);
else
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I1(j), j, i, I2(j), j, j);
end
else
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I0(j), i, I2(j), j, j);
else
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I2(j), j, j);
end
end
else
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I1(j), j, j);
end
else
if I0(j)
fprintf(fid, ' JAC(%u, %u) = J(%u, %u)*g(%u);\n', i, j, i, I0(j), j);
if I1(j)
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)+J(%u,%u)*g(%u);\n', i, j, i, I0(j), i, I1(j), j);
else
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u);\n', i, j, i, I1(j), j);
end
else
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u);\n', i, j, i, I0(j));
end
end
end
end
end
end
else
for i=DynareModel.eq_nbr+1:2*DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I2(j)
if I1(j)
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u)+J(%u,%u)*g(%u)*g(%u)*g(%u);\n', i, j, i, I0(j), j, i, I1(j), j, j, i, I2(j), j, j, j);
else
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)*g(%u)+J(%u,%u)*g(%u)*g(%u)*g(%u);\n', i, j, i, I1(j), j, j, i, I2(j), j, j, j);
end
else
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u)*g(%u);\n', i, j, i, I0(j), j, i, I2(j), j, j, j);
else
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)*g(%u)*g(%u);\n', i, j, i, I2(j), j, j, j);
end
end
else
% Compute the derivatives of the second block of equations (period t+1)
% with respect to the endogenous variables.
if purely_backward_model || purely_forward_model
for i=DynareModel.eq_nbr+1:2*DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I1(j)
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I0(j), j, i, I1(j), j, j);
@ -247,85 +276,215 @@ else
end
end
end
end
end
% Compute the derivatives of the first block of equations (period t)
% with respect to the growth factors.
if purely_backward_model || purely_forward_model
for i=1:DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I1(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u);\n', i, n0+n1+n2+j, i, I1(j), j);
else
for i=DynareModel.eq_nbr+1:2*DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I2(j)
if I1(j)
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u)+J(%u,%u)*g(%u)*g(%u)*g(%u);\n', i, j, i, I0(j), j, i, I1(j), j, j, i, I2(j), j, j, j);
else
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)*g(%u)+J(%u,%u)*g(%u)*g(%u)*g(%u);\n', i, j, i, I1(j), j, j, i, I2(j), j, j, j);
end
else
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u)*g(%u);\n', i, j, i, I0(j), j, i, I2(j), j, j, j);
else
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)*g(%u)*g(%u);\n', i, j, i, I2(j), j, j, j);
end
end
else
if I1(j)
if I0(j)
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)+J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I0(j), j, i, I1(j), j, j);
else
fprintf(fid, ' JAC(%u,%u) = J(%u,%u)*g(%u)*g(%u);\n', i, j, i, I1(j), j, j);
end
else
if I0(j)
fprintf(fid, ' JAC(%u, %u) = J(%u, %u)*g(%u);\n', i, j, i, I0(j), j);
end
end
end
end
end
end
else
for i=1:DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I2(j)
if I1(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u)+J(%u,%u)*2*g(%u)*y(%u);\n', i, n0+n1+n2+j, i, I1(j), j, i, I2(j), j, j);
else
fprintf(fid, ' J(%u,%u) = J(%u,%u)*2*g(%u)*y(%u);\n', i, n0+n1+n2+j, i, I2(j), j, j);
end
else
% Compute the derivatives of the first block of equations (period t)
% with respect to the growth factors.
if purely_backward_model || purely_forward_model
for i=1:DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I1(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u);\n', i, n0+n1+n2+j, i, I1(j), j);
end
end
end
end
end
% Compute the derivatives of the second block of equations (period t+1)
% with respect to the endogenous variables.
if purely_backward_model || purely_forward_model
for i=DynareModel.eq_nbr+1:2*DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I0(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)+J(%u,%u)*y(%u);\n', i, n0+n1+n2+j, i, n0+n1+n2+j, i, I0(j), j);
end
if I1(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)+2*J(%u,%u)*y(%u)*g(%u);\n', i, n0+n1+n2+j, i, n0+n1+n2+j, i, I1(j), j, j);
else
for i=1:DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I2(j)
if I1(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u)+J(%u,%u)*2*g(%u)*y(%u);\n', i, n0+n1+n2+j, i, I1(j), j, i, I2(j), j, j);
else
fprintf(fid, ' J(%u,%u) = J(%u,%u)*2*g(%u)*y(%u);\n', i, n0+n1+n2+j, i, I2(j), j, j);
end
else
if I1(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u);\n', i, n0+n1+n2+j, i, I1(j), j);
end
end
end
end
end
else
for i=DynareModel.eq_nbr+1:2*DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I2(j)
% Compute the derivatives of the second block of equations (period t+1)
% with respect to the endogenous variables.
if purely_backward_model || purely_forward_model
for i=DynareModel.eq_nbr+1:2*DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I0(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)+J(%u,%u)*y(%u);\n', i, n0+n1+n2+j, i, n0+n1+n2+j, i, I0(j), j);
end
if I1(j)
if I0(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u)+2*J(%u,%u)*y(%u)*g(%u)+3*J(%u,%u)*y(%u)*g(%u)*g(%u);\n', i, n0+n1+n2+j, i, I0(j), j, i, I1(j), j, j, i, I2(j), j, j, j);
fprintf(fid, ' J(%u,%u) = J(%u,%u)+2*J(%u,%u)*y(%u)*g(%u);\n', i, n0+n1+n2+j, i, n0+n1+n2+j, i, I1(j), j, j);
end
end
end
else
for i=DynareModel.eq_nbr+1:2*DynareModel.eq_nbr
for j=1:DynareModel.endo_nbr
if I2(j)
if I1(j)
if I0(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u)+2*J(%u,%u)*y(%u)*g(%u)+3*J(%u,%u)*y(%u)*g(%u)*g(%u);\n', i, n0+n1+n2+j, i, I0(j), j, i, I1(j), j, j, i, I2(j), j, j, j);
else
fprintf(fid, ' J(%u,%u) = 2*J(%u,%u)*y(%u)*g(%u)+3*J(%u,%u)*y(%u)*g(%u)*g(%u);\n', i, n0+n1+n2+j, i, I1(j), j, j, i, I2(j), j, j, j);
end
else
fprintf(fid, ' J(%u,%u) = 2*J(%u,%u)*y(%u)*g(%u)+3*J(%u,%u)*y(%u)*g(%u)*g(%u);\n', i, n0+n1+n2+j, i, I1(j), j, j, i, I2(j), j, j, j);
end
else
if I0(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u)+3*J(%u,%u)*y(%u)*g(%u)*g(%u);\n', i, n0+n1+n2+j, i, I0(j), j, i, I2(j), j, j, j);
if I0(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u)+3*J(%u,%u)*y(%u)*g(%u)*g(%u);\n', i, n0+n1+n2+j, i, I0(j), j, i, I2(j), j, j, j);
else
fprintf(fid, ' J(%u,%u) = 3*J(%u,%u)*y(%u)*g(%u)*g(%u);\n', i, n0+n1+n2+j, i, I2(j), j, j, j);
end
end
else
if I1(j)
if I0(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u)+2*J(%u,%u)*y(%u)*g(%u);\n', i, n0+n1+n2+j, i, I0(j), j, i, I1(j), j, j);
else
fprintf(fid, ' J(%u,%u) = 2*J(%u,%u)*y(%u)*g(%u);\n', i, n0+n1+n2+j, i, I1(j), j, j);
end
else
if I0(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u);\n', i, n0+n1+n2+j, i, I0(j), j);
if I1(j)
if I0(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u)+2*J(%u,%u)*y(%u)*g(%u);\n', i, n0+n1+n2+j, i, I0(j), j, i, I1(j), j, j);
else
fprintf(fid, ' J(%u,%u) = 2*J(%u,%u)*y(%u)*g(%u);\n', i, n0+n1+n2+j, i, I1(j), j, j);
end
else
if I0(j)
fprintf(fid, ' J(%u,%u) = J(%u,%u)*y(%u);\n', i, n0+n1+n2+j, i, I0(j), j);
end
end
end
end
end
end
fprintf(fid, ' JAC(:,%u:%u) = J(:,%u:%u);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, n0+n1+n2+1, n0+n1+n2+DynareModel.endo_nbr);
fprintf(fid,'end\n');
fclose(fid);
if nargin>1
if iskeyvalue(varargin)
% Create function in mod namespace.
fid = fopen(sprintf('+%s/bgpfunhardcon.m', DynareModel.fname), 'w');
% Write header.
fprintf(fid, 'function [F, JAC] = bgpfunhardcon(z)\n\n');
fprintf(fid, '%% This file has been generated by dynare (%s).\n\n', datestr(now));
j1 = setdiff(transpose(1:DynareModel.endo_nbr), idy(~isnan(idy)));
j2 = setdiff(transpose(1:DynareModel.endo_nbr), idg(~isnan(idg)));
tmp = sprintf(' %u', [j1; DynareModel.endo_nbr+j2]);
fprintf(fid, 'id = [%s];\n\n', strtrim(tmp));
fprintf(fid, 'Z = NaN(%u, 1);\n\n', 2*DynareModel.endo_nbr);
fprintf(fid, 'Z(id) = z;\n');
for i=1:length(idy)
if ~isnan(idy(i))
fprintf(fid, 'Z(%u) = %s;\n', idy(i), num2str(vly(i)));
end
if ~isnan(idg(i))
fprintf(fid, 'Z(%u) = %s;\n', length(idy)+idg(i), num2str(vlg(i)));
end
end
skipline(1, fid)
fprintf(fid, '[F, JAC] = %s.bgpfun(Z);\n\n', DynareModel.fname);
for i=1:length(idy)
if ~isnan(idy(i))
fprintf(fid, 'JAC(:,%u) = [];\n', idy(i));
end
if ~isnan(idg(i))
fprintf(fid, 'JAC(:,%u) = [];\n', length(idy)+idg(i));
end
end
fclose(fid);
elseif iskeyvalues(varargin)
% Create function in mod namespace.
fid = fopen(sprintf('+%s/bgpfuncon.m', DynareModel.fname), 'w');
% Write header.
fprintf(fid, 'function [F, JAC] = bgpfuncon(z)\n\n');
fprintf(fid, '%% This file has been generated by dynare (%s).\n\n', datestr(now));
%fprintf(fid, 'keyboard\n\n');
j1 = setdiff(transpose(1:DynareModel.endo_nbr), idy(~isnan(idy)));
j2 = setdiff(transpose(1:DynareModel.endo_nbr), idg(~isnan(idg)));
jj = [j1; DynareModel.endo_nbr+j2];
fprintf(fid, 'Z = NaN(%u, 1);\n\n', 2*DynareModel.endo_nbr);
for i=1:length(jj)
j = jj(i);
if isinf(lb(j)) && isinf(ub(j))
fprintf(fid, 'Z(%u) = z(%u);\n', j, i);
elseif isfinite(lb(j)) && isinf(ub(j))
fprintf(fid, 'Z(%u) = %s+exp(z(%u));\n', j, num2str(lb(j), 9), i);
elseif isinf(lb(j)) && isfinite(ub(j))
fprintf(fid, 'Z(%u) = %s-exp(z(%u));\n', j, num2str(ub(j), 9), i);
elseif isfinite(lb(j)) && isfinite(ub(j))
fprintf(fid, 'Z(%u) = %s+%s/(1+exp(-z(%u)));\n', j, num2str(lb(j), 9), num2str(ub(j)-lb(j), 9), i);
end
end
skipline(1, fid)
for i=1:length(idy)
if ~isnan(idy(i))
fprintf(fid, 'Z(%u) = %s;\n', idy(i), num2str(vly(i)));
end
if ~isnan(idg(i))
fprintf(fid, 'Z(%u) = %s;\n', length(idy)+idg(i), num2str(vlg(i)));
end
end
skipline(1, fid)
fprintf(fid, '[F, JAC] = %s.bgpfun(Z);\n\n', DynareModel.fname);
%
for i=1:length(jj)
j = jj(i);
if isinf(lb(j)) && isinf(ub(j))
% Do nothing (no transformation of the input)
elseif isfinite(lb(j)) && isinf(ub(j))
fprintf(fid, 'JAC(:,%u) = JAC(:,%u)*exp(z(%u));\n', j, j, i);
elseif isinf(lb(j)) && isfinite(ub(j))
fprintf(fid, 'JAC(:,%u) = -JAC(:,%u)*exp(z(%u));\n', j, j, i);
elseif isfinite(lb(j)) && isfinite(ub(j))
fprintf(fid, 'tmp = 1/(1+exp(-z(%u)));\n', i);
fprintf(fid, 'JAC(:,%u) = JAC(:,%u)*tmp*(1-tmp)*%s;\n', j, j, num2str(ub(j)-lb(j), 9));
end
end
%
skipline(1, fid)
for i=1:length(idy)
if ~isnan(idy(i))
fprintf(fid, 'JAC(:,%u) = [];\n', idy(i));
end
if ~isnan(idg(i))
fprintf(fid, 'JAC(:,%u) = [];\n', length(idy)+idg(i));
end
end
fclose(fid);
end
end
rehash()
end
fprintf(fid, ' JAC(:,%u:%u) = J(:,%u:%u);\n', DynareModel.endo_nbr+1, 2*DynareModel.endo_nbr, n0+n1+n2+1, n0+n1+n2+DynareModel.endo_nbr);
fprintf(fid,'end\n');
fclose(fid);

View File

@ -0,0 +1,15 @@
function is = iskeyvalue(rowcellarray)
is = true;
if ~iscell(rowcellarray) || ~isrow(rowcellarray) || ~iseven(length(rowcellarray))
is = false;
return
end
if any(~cellfun(@ischar, rowcellarray(1:2:length(rowcellarray))))
is = false;
return
end
if any(~cellfun(@(x) isnumeric(x) & isscalar(x), rowcellarray(2:2:length(rowcellarray))))
is = false;
return
end
end

View File

@ -0,0 +1,19 @@
function is = iskeyvalues(rowcellarray)
is = true;
if ~iscell(rowcellarray) || ~isrow(rowcellarray) || ~iseven(length(rowcellarray))
is = false;
return
end
if any(~cellfun(@ischar, rowcellarray(1:3:length(rowcellarray))))
is = false;
return
end
if any(~cellfun(@(x) isnumeric(x) & isscalar(x), rowcellarray(2:3:length(rowcellarray))))
is = false;
return
end
if any(~cellfun(@(x) isnumeric(x) & isscalar(x), rowcellarray(3:3:length(rowcellarray))))
is = false;
return
end
end

View File

@ -465,6 +465,10 @@ MODFILES = \
observation_trends_and_prefiltering/calib_smoother/Tr_prefilter_loglin_calib_smoother.mod \
observation_trends_and_prefiltering/calib_smoother/Tr_prefil_f_obs_loglin_cal_smoother.mod \
observation_trends_and_prefiltering/ML/Trend_no_prefilter_selected_var.mod \
bgp/solow-1/checkjacobian.mod \
bgp/nk-1/checkjacobian.mod \
bgp/ramsey-1/checkjacobian.mod \
bgp/fs2000/checkjacobian.mod \
bgp/solow-1/solow.mod \
bgp/nk-1/nk.mod \
bgp/ramsey-1/ramsey.mod \

View File

@ -0,0 +1,81 @@
/*
* This file is a modified version of 'fs2000.mod'.
*
* The difference is that, here, the equations are written in non-stationary form, and we test if
* we are able to identify the trends.
*
*/
/*
* Copyright © 2019-2021 Dynare Team
*
* 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
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/
var gM M;
var gA A k c y;
var P; // follows M(-1)/A
var W l d; // follows M(-1)
var R n;
varexo e_a e_m;
parameters alp bet gam mst rho psi del;
alp = 0.33;
bet = 0.99;
gam = 0.003;
mst = 1.011;
rho = 0.7;
psi = 0.787;
del = 0.02;
model;
A = gA*A(-1);
M = gM*M(-1);
gA = exp(gam+e_a);
log(gM) = (1-rho)*log(mst) + rho*log(gM(-1))+e_m;
c+k = k(-1)^alp*(A*n)^(1-alp)+(1-del)*k(-1);
P*c = M;
P/(c(+1)*P(+1))=bet*P(+1)*(alp*k^(alp-1)*(A(+1)*n(+1))^(1-alp)+(1-del))/(c(+2)*P(+2));
(psi/(1-psi))*(c*P/(1-n))=W;
R = P*(1-alp)*k(-1)^alp*A^(1-alp)*n^(-alp)/W;
W = l/n;
M-M(-1)+d = l;
1/(c*P)=bet*R/(c(+1)*P(+1));
y = k(-1)^alp*(A*n)^(1-alp);
end;
verbatim;
bgp.write(M_);
MC = 1000;
maxabsdiff = 0;
for i=1:MC
y = 1+(rand(M_.endo_nbr,1)-.5)*.25;
G = ones(M_.endo_nbr,1)+0.01*randn(M_.endo_nbr,1);
jacobian = fjaco(@checkjacobian.bgpfun, [y;G]);
[Residuals, Jacobian] = checkjacobian.bgpfun([y;G]);
maxabsdiff = max(0, max(abs(jacobian(:)-Jacobian(:))));
end
assert(maxabsdiff<1e-5, 'Analytical jacobian is wrong.')
end;

View File

@ -1,7 +1,8 @@
// --+ options: json=compute +--
/*
* This file is a modified version of 'fs2000.mod'.
*
* The difference is that, here, the equations are written in non-stationary form, and we test if
* The difference is that, here, the equations are written in non-stationary form, and we test if
* we are able to identify the trends.
*
*/
@ -61,22 +62,66 @@ end;
verbatim;
bgp.write(M_);
y = 1+(rand(M_.endo_nbr,1)-.5)*.25;
g = ones(M_.endo_nbr,1);% 1+(rand(M_.endo_nbr,1)-.5)*.1;
if isoctave
options = optimset('Display','iter','Algorithm','levenberg-marquardt','MaxFunEvals',1000000,'MaxIter',100000,'GradObj','on','TolFun',1e-6,'TolX',1e-6);
elseif matlab_ver_less_than('9.0')
% See https://fr.mathworks.com/help/optim/ug/current-and-legacy-option-name-tables.html
options = optimoptions('fsolve','Display','iter','Algorithm','levenberg-marquardt','MaxFunEvals',1000000,'MaxIter',100000,'Jacobian','on','TolFun',1e-6,'TolX',1e-6);
else
options = optimoptions('fsolve','Display','iter','Algorithm','levenberg-marquardt','MaxFunctionEvaluations',1000000,'MaxIterations',100000,'SpecifyObjectiveGradient',true,'FunctionTolerance',1e-6,'StepTolerance',1e-6);
end
[y, fval, exitflag] = fsolve(@fs2000.bgpfun, [y;g], options);
if exitflag<1
error('Solution not found')
end
y(1:M_.orig_endo_nbr)
y(M_.endo_nbr+(1:M_.orig_endo_nbr))
Constraints = {'M', 1, Inf, ...
'A', 1, Inf, ...
'k', 10, 10, ...
'c', 0, Inf, ...
'y', 0, Inf, ...
'P', 10, 10, ...
'W', 0, Inf, ...
'l', 0, Inf, ...
'd', 0, Inf, ...
'n', 0, Inf, ...
'R', 0, Inf, ...
'gM', 1, Inf, ...
'gA', 1, Inf, ...
'G(M)', 1, 1.1, ...
'G(A)', 1, 1.1, ...
'G(k)', 1, 1.1, ...
'G(c)', 1, 1.1, ...
'G(y)', 1, 1.1, ...
'G(P)', 1, 1.1, ...
'G(W)', 1, 1.1, ...
xb 'G(l)', 1, 1.1, ...
'G(d)', 1, 1.1, ...
'G(n)', .9, 1.1, ...
'G(R)', .9, 1.1, ...
'G(gM)', .9, 1.1, ...
'G(gA)', .9, 1.1, ...
};
bgp.write(M_, Constraints{:});
y = ones(M_.endo_nbr,1) + rand(M_.endo_nbr,1)*.1;
G = ones(M_.endo_nbr,1) + rand(M_.endo_nbr,1)*.1;
y = [y;G];
if isoctave
options = optimset('Display','iter','Algorithm','levenberg-marquardt','MaxFunEvals',1000000,'MaxIter',100000,'GradObj','on','TolFun',1e-6,'TolX',1e-6);
elseif matlab_ver_less_than('9.0')
% See https://fr.mathworks.com/help/optim/ug/current-and-legacy-option-name-tables.html
options = optimoptions('fsolve','Display','iter','Algorithm','levenberg-marquardt','MaxFunEvals',1000000,'MaxIter',100000,'Jacobian','on','TolFun',1e-6,'TolX',1e-6);
else
options = optimoptions('fsolve','Display','iter','Algorithm','levenberg-marquardt','MaxFunctionEvaluations',10000000,'MaxIterations',1000000,'SpecifyObjectiveGradient',true,'FunctionTolerance',1e-4,'StepTolerance',1e-6);
end
[y, id, lb, ub] = bgp.transform.out(M_, Constraints, y);
[y, fval, exitflag] = fsolve(@fs2000.bgpfuncon, y, options);
y(1:M_.orig_endo_nbr-2)
y(M_.endo_nbr-2+(1:M_.orig_endo_nbr))
y = bgp.transform.in(M_, Constraints, y, id, lb, ub);
y(1:M_.orig_endo_nbr)
y(M_.endo_nbr+(1:M_.orig_endo_nbr))
if exitflag<1
error('Solution not found')
end
y(1:M_.orig_endo_nbr)
y(M_.endo_nbr+(1:M_.orig_endo_nbr))
end;

View File

@ -0,0 +1,40 @@
var y i pi ;
parameters a1 a2 a3 a4 a5;
a1 = -.5;
a2 = .1;
a3 = .9;
a4 = 1.5;
a5 = 0.5;
model;
y = y(1)*(i/pi(1))^a1;
pi = (y^a2)*(pi(1)^a3);
i = (pi^a4)*(y^a5);
end;
verbatim;
bgp.write(M_);
MC = 1000;
maxabsdiff = 0;
for i=1:MC
y = 1+(rand(3,1)-.5)*.5;
G = 1+(rand(3,1)-.5)*.1;
jacobian = fjaco(@checkjacobian.bgpfun, [y;G]);
[Residuals, Jacobian] = checkjacobian.bgpfun([y;G]);
maxabsdiff = max(0, max(abs(jacobian(:)-Jacobian(:))));
end
assert(maxabsdiff<1e-6, 'Analytical jacobian is wrong.')
end;

View File

@ -27,11 +27,11 @@ verbatim;
% See https://fr.mathworks.com/help/optim/ug/current-and-legacy-option-name-tables.html
options = optimoptions('fsolve','Display','iter','Algorithm','levenberg-marquardt','MaxFunEvals',1000000,'MaxIter',100000,'Jacobian','on','TolFun',1e-8,'TolX',1e-8);
else
options = optimoptions('fsolve','Display','iter','Algorithm','levenberg-marquardt','MaxFunctionEvaluations',1000000,'MaxIterations',100000,'SpecifyObjectiveGradient',true,'FunctionTolerance',1e-8,'StepTolerance',1e-8);
options = optimoptions('fsolve','Display','iter','Algorithm','trust-region-dogleg','MaxFunctionEvaluations',1000000,'MaxIterations',100000,'SpecifyObjectiveGradient',true,'FunctionTolerance',1e-8,'StepTolerance',1e-8);
end
y = 1+(rand(3,1)-.5)*.5;
g = 1+(rand(3,1)-.5)*.1;
[y, fval, exitflag] = fsolve(@nk.bgpfun, [y;g], options);
assert(max(abs(y-1))<1e-9);
assert(max(abs(y-1))<1e-7);
end;

View File

@ -0,0 +1,34 @@
var c k x;
parameters alpha gam delta beta ;
alpha=0.5;
gam=0.5;
delta=0.02;
beta=0.05;
model;
x = x(-1)*1.02;
c + k - x^(1-alpha)*k(-1)^alpha - (1-delta)*k(-1);
c^(-gam) - (1+beta)^(-1)*(alpha*x(+1)^(1-alpha)*k^(alpha-1) + 1 - delta)*c(+1)^(-gam);
end;
verbatim;
bgp.write(M_);
MC = 1000;
maxabsdiff = 0;
for i=1:MC
y = 1+(rand(M_.endo_nbr,1)-.5)*.25;
G = ones(M_.endo_nbr,1)+0.01*randn(M_.endo_nbr,1);
jacobian = fjaco(@checkjacobian.bgpfun, [y;G]);
[Residuals, Jacobian] = checkjacobian.bgpfun([y;G]);
maxabsdiff = max(0, max(abs(jacobian(:)-Jacobian(:))));
end
assert(maxabsdiff<1e-6, 'Analytical jacobian is wrong.')
end;

View File

@ -15,21 +15,28 @@ end;
verbatim;
bgp.write(M_);
if isoctave
options = optimset('Display', 'iter', 'MaxFunEvals', 1000000,'MaxIter',100000,'Jacobian','on','TolFun',1e-7,'TolX',1e-7);
elseif matlab_ver_less_than('9.0')
% See https://fr.mathworks.com/help/optim/ug/current-and-legacy-option-name-tables.html
options = optimoptions('fsolve','Display','iter','Algorithm','levenberg-marquardt','MaxFunEvals',1000000,'MaxIter',100000,'Jacobian','on','TolFun',1e-6,'TolX',1e-6);
else
options = optimoptions('fsolve','Display','iter','Algorithm','levenberg-marquardt','MaxFunctionEvaluations',1000000,'MaxIterations',100000,'SpecifyObjectiveGradient',true,'FunctionTolerance',1e-6,'StepTolerance',1e-6);
end
y = 1+(rand(M_.endo_nbr,1)-.5)*.25;
g = ones(M_.endo_nbr,1);% 1+(rand(M_.endo_nbr,1)-.5)*.1;
[y, fval, exitflag] = fsolve(@ramsey.bgpfun, [y;g], options);
if ~isoctave
% Disable under Octave for the time being, it converges to a solution different
% from the one expected.
assert(max(abs(y(M_.endo_nbr+(1:M_.orig_endo_nbr))-1.02))<1e-6)
end
HardCodedLevels = {'k', 10};
bgp.write(M_, HardCodedLevels{:});
if isoctave
options = optimset('Display', 'iter', 'MaxFunEvals', 1000000,'MaxIter',100000,'Jacobian','on','TolFun',1e-7,'TolX',1e-7);
elseif matlab_ver_less_than('9.0')
% See https://fr.mathworks.com/help/optim/ug/current-and-legacy-option-name-tables.html
options = optimoptions('fsolve','Display','iter','Algorithm','levenberg-marquardt','MaxFunEvals',1000000,'MaxIter',100000,'Jacobian','on','TolFun',1e-6,'TolX',1e-6);
else
options = optimoptions('fsolve','Display','iter','Algorithm','levenberg-marquardt','MaxFunctionEvaluations',1000000,'MaxIterations',100000,'SpecifyObjectiveGradient',true,'FunctionTolerance',1e-6,'StepTolerance',1e-6);
end
y = 1+(rand(M_.endo_nbr,1)-.5)*.25;
G = 1+0.05*rand(M_.endo_nbr,1);
y = [y;G];
[y, id] = bgp.hdl.out(M_, HardCodedLevels, y);
[y, fval, exitflag] = fsolve(@ramsey.bgpfunhardcon, y, options);
y = bgp.hdl.in(M_, HardCodedLevels, y, id);
if ~isoctave
% Disable under Octave for the time being, it converges to a solution different
% from the one expected.
assert(max(abs(y(M_.endo_nbr+(1:M_.orig_endo_nbr))-1.02))<1e-6)
end
end;

View File

@ -0,0 +1,59 @@
// This mod file test the bgp.write function by characterizing the Balanced Growth Path of the Solow model. This is done 10000 times in a Monte Carlo loop
// randomizing the initial guess of the nonlinear solver.
var Efficiency
EfficiencyGrowth
Population
PopulationGrowth
Output
PhysicalCapitalStock ;
varexo e_x
e_n ;
parameters alpha
delta
s
rho_x
rho_n
EfficiencyGrowth_ss
PopulationGrowth_ss ;
alpha = .33;
delta = .02;
s = .20;
rho_x = .90;
rho_n = .95;
EfficiencyGrowth_ss = 1.01;
PopulationGrowth_ss = 1.01;
model(use_dll);
Efficiency = EfficiencyGrowth*Efficiency(-1);
EfficiencyGrowth/EfficiencyGrowth_ss = (EfficiencyGrowth(-1)/EfficiencyGrowth_ss)^(rho_x)*exp(e_x);
Population = PopulationGrowth*Population(-1);
PopulationGrowth/PopulationGrowth_ss = (PopulationGrowth(-1)/PopulationGrowth_ss)^(rho_n)*exp(e_n);
Output = PhysicalCapitalStock(-1)^alpha*(Efficiency*Population)^(1-alpha);
PhysicalCapitalStock = (1-delta)*PhysicalCapitalStock(-1) + s*Output;
end;
verbatim;
bgp.write(M_);
MC = 1000;
maxabsdiff = 0;
for i=1:MC
y = randi([10,1000])+(rand(6,1)-.5)*.2;
y(2) = 1+.05*rand;
y(3) = 1+.05*rand;
G = 1.01*ones(6,1)+.05*randn(6,1);
jacobian = fjaco(@checkjacobian.bgpfun, [y;G]);
[Residuals, Jacobian] = checkjacobian.bgpfun([y;G]);
maxabsdiff = max(0, max(abs(jacobian(:)-Jacobian(:))));
end
assert(maxabsdiff<1e-6, 'Analytical jacobian is wrong.')
end;

View File

@ -27,7 +27,7 @@ rho_n = .95;
EfficiencyGrowth_ss = 1.01;
PopulationGrowth_ss = 1.01;
model;
model(use_dll);
Efficiency = EfficiencyGrowth*Efficiency(-1);
EfficiencyGrowth/EfficiencyGrowth_ss = (EfficiencyGrowth(-1)/EfficiencyGrowth_ss)^(rho_x)*exp(e_x);
Population = PopulationGrowth*Population(-1);
@ -36,43 +36,57 @@ model;
PhysicalCapitalStock = (1-delta)*PhysicalCapitalStock(-1) + s*Output;
end;
if ~isoctave
% The levenberg-marquardt algorithm is not available in octave's
% implementation of fsolve, so we skip this check for Octave
verbatim;
bgp.write(M_);
MC = 10000;
if ~isoctave
% The levenberg-marquardt algorithm is not available in octave's
% implementation of fsolve, so we skip this check for Octave
HardCodedLevels = {'Output', 10, 'Population', 1};
bgp.write(M_, HardCodedLevels{:});
MC = 100;
KY = NaN(MC,1);
GY = NaN(MC,1);
GK = NaN(MC,1);
EG = NaN(MC,1);
if isoctave
options = optimset('Display', 'off', 'MaxFunEvals', 1000000,'MaxIter',100000,'Jacobian','on','TolFun',1e-8,'TolX',1e-8);
elseif matlab_ver_less_than('9.0')
EF = NaN(MC,1);
if matlab_ver_less_than('9.0')
% See https://fr.mathworks.com/help/optim/ug/current-and-legacy-option-name-tables.html
options = optimoptions('fsolve','Display','off','Algorithm','levenberg-marquardt','MaxFunEvals',1000000,'MaxIter',100000,'Jacobian','on','TolFun',1e-8,'TolX',1e-8);
else
options = optimoptions('fsolve','Display','off','Algorithm','levenberg-marquardt','MaxFunctionEvaluations',1000000,'MaxIterations',100000,'SpecifyObjectiveGradient',true,'FunctionTolerance',1e-8,'StepTolerance',1e-8);
options = optimoptions('fsolve','Display','off','Algorithm','trust-region','MaxFunctionEvaluations',1000000,'MaxIterations',100000,'SpecifyObjectiveGradient',true,'FunctionTolerance',1e-10,'StepTolerance',1e-8);
end
reverseStr = '';
for i=1:MC
y = 1+(rand(6,1)-.5)*.2;
g = ones(6,1);
[y, fval, exitflag] = fsolve(@solow.bgpfun, [y;g], options);
if exitflag>0
KY(i) = y(6)/y(5);
GY(i) = y(11);
GK(i) = y(12);
EG(i) = y(2);
end
% Display the progress
percentDone = 100 * i / MC;
msg = sprintf('Percent done: %3.1f', percentDone);
fprintf([reverseStr, msg]);
reverseStr = repmat(sprintf('\b'), 1, length(msg));
y = 10+(rand(6,1)-.5)*.2;
y(2) = 1+.02*rand;
y(4) = 1+.02*rand;
G = ones(6,1)+.05*randn(6,1);
y = [y;G];
[y, id] = bgp.hdl.out(M_, HardCodedLevels, y);
[y, fval, exitflag] = fsolve(@solow.bgpfunhardcon, y, options);
y = bgp.hdl.in(M_, HardCodedLevels, y, id);
if exitflag>0
KY(i) = y(6)/y(5);
GY(i) = y(11);
GK(i) = y(12);
EG(i) = y(2);
EF(i) = y(4);
end
% Display the progress
percentDone = 100 * i / MC;
msg = sprintf('Percent done: %3.1f', percentDone);
fprintf([reverseStr, msg]);
reverseStr = repmat(sprintf('\b'), 1, length(msg));
end
fprintf('\n');
skipline();
% Compute the physical capital stock over output ratio along the BGP as
% a function of the deep parameters...
theoretical_long_run_ratio = s*EfficiencyGrowth_ss*PopulationGrowth_ss/(EfficiencyGrowth_ss*PopulationGrowth_ss-1+delta);
@ -84,15 +98,12 @@ verbatim;
disp(sprintf('mean(K/Y) = %s.', num2str(mu)));
disp(sprintf('var(K/Y) = %s.', num2str(s2)));
disp(sprintf('Number of failures: %u (over %u problems).', sum(isnan(KY)), MC));
assert(abs(mu-theoretical_long_run_ratio)<1e-8);
assert(s2<1e-16);
assert(abs(mean(GY(~isnan(GY)))-EfficiencyGrowth_ss*PopulationGrowth_ss)<1e-8)
assert(var(GY(~isnan(GY)))<1e-16);
assert(abs(mean(GK(~isnan(GK)))-EfficiencyGrowth_ss*PopulationGrowth_ss)<1e-8)
assert(var(GK(~isnan(GK)))<1e-16);
assert(abs(mean(EG(~isnan(EG)))-EfficiencyGrowth_ss)<1e-8)
assert(var(EG(~isnan(EG)))<1e-16);
end;
if (abs(mu-theoretical_long_run_ratio)>1e-6), error('Average long run K/Y ratio is wrong.'), end
if (s2>1e-12), warning('Average long run K/Y ratio is wrong.'), end
dprintf('Proportion of wrong values for GY is %s.', num2str(sum(abs(GY(~isnan(GY))-EfficiencyGrowth_ss*PopulationGrowth_ss)>1e-6)/sum(~isnan(GY))))
dprintf('Proportion of wrong values for GK is %s.', num2str(sum(abs(GK(~isnan(GK))-EfficiencyGrowth_ss*PopulationGrowth_ss)>1e-6)/sum(~isnan(GK))))
dprintf('Proportion of wrong values for EG is %s.', num2str(sum(abs(EG(~isnan(EG))-EfficiencyGrowth_ss)>1e-6)/sum(~isnan(EG))))
dprintf('Proportion of wrong values for EF is %s.', num2str(sum(abs(EF(~isnan(EF))-PopulationGrowth_ss)>1e-6)/sum(~isnan(EF))))
end
end;