dyn_ols: use AST instead of regex to parse equations

time-shift
Houtan Bastani 2018-11-23 16:21:11 +01:00 committed by Stéphane Adjemia (Scylla)
parent cb4384bb27
commit 44e5a88ddd
Signed by untrusted user who does not match committer: stepan
GPG Key ID: A6D44CB9C64CE77B
3 changed files with 481 additions and 100 deletions

View File

@ -51,6 +51,7 @@ end
%% Get Equation(s)
jsonmodel = loadjson(jsonfile);
ast = jsonmodel.abstract_syntax_tree;
jsonmodel = jsonmodel.model;
if nargin == 1
@ -61,103 +62,137 @@ elseif nargin == 2
(size(fitted_names_dict, 2) == 2 || size(fitted_names_dict, 2) == 3)), ...
'dyn_ols: the second argument must be an Nx2 or Nx3 cell array');
elseif nargin == 3
ast = getEquationsByTags(ast, 'name', eqtags);
jsonmodel = getEquationsByTags(jsonmodel, 'name', eqtags);
end
%% Estimation
M_endo_exo_names_trim = [M_.endo_names; M_.exo_names];
[junk, idxs] = sort(cellfun(@length, M_endo_exo_names_trim), 'descend');
regex = strjoin(M_endo_exo_names_trim(idxs), '|');
mathops = '[\+\*\^\-\/\(\)]';
st = dbstack(1);
varargout = cell(1, 1);
called_from_olsgibbs = false;
if strcmp(st(1).name, 'olsgibbs')
varargout = cell(1, 4);
called_from_olsgibbs = true;
end
for i = 1:length(jsonmodel)
%% Construct regression matrices
rhs_ = strsplit(jsonmodel{i}.rhs, {'+','-','*','/','^','log(','exp(','(',')'});
rhs_(cellfun(@(x) all(isstrprop(x, 'digit')), rhs_)) = [];
vnames = setdiff(rhs_, M_.param_names);
if ~isempty(regexp(jsonmodel{i}.rhs, ...
['(' strjoin(vnames, '\\(\\d+\\)|') '\\(\\d+\\))'], ...
'once'))
error(['dyn_ols: you cannot have leads in equation on line ' ...
jsonmodel{i}.line ': ' jsonmodel{i}.lhs ' = ' jsonmodel{i}.rhs]);
for i = 1:length(ast)
if ~strcmp(ast{i}.AST.node_type, 'BinaryOpNode') ...
|| ~strcmp(ast{i}.AST.op, '=')
ols_error('expecting equation with equal sign', line);
end
pnames = intersect(rhs_, M_.param_names);
vnames = cell(1, length(pnames));
splitstrings = cell(length(pnames), 1);
% Check LHS
if ~strcmp(ast{i}.AST.arg1.node_type, 'VariableNode') ...
&& ~strcmp(ast{i}.AST.arg1.node_type, 'UnaryOpNode')
ols_error('expecting Variable or UnaryOp on LHS', line);
else
if strcmp(ast{i}.AST.arg1.node_type, 'VariableNode') ...
&& (ast{i}.AST.arg1.lag ~= 0 ...
|| ~any(strcmp(ds.name, ast{i}.AST.arg1.name)))
ols_error('the lhs of the equation must be an Variable or UnaryOp with lag == 0 that exists in the dataset', line);
end
if strcmp(ast{i}.AST.arg1.node_type, 'UnaryOpNode') ...
&& (ast{i}.AST.arg1.arg.lag ~= 0 ...
|| ~any(strcmp(ds.name, ast{i}.AST.arg1.arg.name)))
ols_error('the lhs of the equation must be an Variable or UnaryOp with lag == 0 that exists in the dataset', line);
end
end
% Set LHS (Y)
lhssub = dseries();
Y = evalNode(ds, ast{i}.AST.arg1, jsonmodel{i}.line, dseries());
% Set RHS (X)
plus_node = ast{i}.AST.arg2;
last_node_to_parse = [];
residual = '';
X = dseries();
for j = 1:length(pnames)
createdvar = false;
pregex = [...
mathops pnames{j} mathops ...
'|^' pnames{j} mathops ...
'|' mathops pnames{j} '$' ...
];
[startidx, endidx] = regexp(jsonmodel{i}.rhs, pregex, 'start', 'end');
assert(length(startidx) == 1);
if jsonmodel{i}.rhs(startidx) == '*' && jsonmodel{i}.rhs(endidx) == '*'
vnamesl = getStrMoveLeft(jsonmodel{i}.rhs(1:startidx-1));
vnamesr = getStrMoveRight(jsonmodel{i}.rhs(endidx+1:end));
vnames{j} = [vnamesl '*' vnamesr];
splitstrings{j} = [vnamesl '*' pnames{j} '*' vnamesr];
elseif jsonmodel{i}.rhs(startidx) == '*'
vnames{j} = getStrMoveLeft(jsonmodel{i}.rhs(1:startidx-1));
splitstrings{j} = [vnames{j} '*' pnames{j}];
elseif jsonmodel{i}.rhs(endidx) == '*'
vnames{j} = getStrMoveRight(jsonmodel{i}.rhs(endidx+1:end));
splitstrings{j} = [pnames{j} '*' vnames{j}];
if jsonmodel{i}.rhs(startidx) == '-'
vnames{j} = ['-' vnames{j}];
splitstrings{j} = ['-' splitstrings{j}];
end
elseif jsonmodel{i}.rhs(startidx) == '+' ...
|| jsonmodel{i}.rhs(startidx) == '-' ...
|| jsonmodel{i}.rhs(endidx) == '+' ...
|| jsonmodel{i}.rhs(endidx) == '-'
% intercept
createdvar = true;
if any(strcmp(M_endo_exo_names_trim, 'intercept'))
[~, vnames{j}] = fileparts(tempname);
vnames{j} = ['intercept_' vnames{j}];
assert(~any(strcmp(M_endo_exo_names_trim, vnames{j})));
else
vnames{j} = 'intercept';
end
splitstrings{j} = vnames{j};
while ~isempty(plus_node) || ~isempty(last_node_to_parse)
Xtmp = dseries();
if isempty(last_node_to_parse)
[plus_node, node_to_parse, last_node_to_parse] = findNextplus_node(plus_node, jsonmodel{i}.line);
else
error('dyn_ols: Shouldn''t arrive here');
node_to_parse = last_node_to_parse;
last_node_to_parse = [];
end
if createdvar
if jsonmodel{i}.rhs(startidx) == '-'
Xtmp = dseries(-ones(ds.nobs, 1), ds.firstdate, vnames{j});
if strcmp(node_to_parse.node_type, 'VariableNode') || strcmp(node_to_parse.node_type, 'UnaryOpNode')
if strcmp(node_to_parse.node_type, 'VariableNode')
if strcmp(node_to_parse.type, 'parameter')
% Intercept
Xtmp = dseries(ones(ds.nobs, 1), ds.firstdate, node_to_parse.name);
elseif strcmp(node_to_parse.type, 'exogenous') && ~any(strcmp(ds.name, node_to_parse.name))
% Residual if not contained in ds
if isempty(residual)
residual = node_to_parse.name;
else
ols_error(['only one residual allowed per equation; encountered ' residual ' & ' node_to_parse.name], jsonmodel{i}.line);
end
elseif strcmp(node_to_parse.type, 'endogenous') ...
|| (strcmp(node_to_parse.type, 'exogenous') && any(strcmp(ds.name, node_to_parse.name)))
% Subtract VariableNode from LHS
% NB: treat exogenous that exist in ds as endogenous
lhssub = lhssub + evalNode(ds, node_to_parse, jsonmodel{i}.line, dseries());
else
ols_error('unexpected variable type found', jsonmodel{i}.line);
end
else
Xtmp = dseries(ones(ds.nobs, 1), ds.firstdate, vnames{j});
% Subtract UnaryOpNode from LHS
% NB: treat exogenous that exist in ds as endogenous
lhssub = lhssub + evalNode(ds, node_to_parse, jsonmodel{i}.line, dseries());
end
elseif strcmp(node_to_parse.node_type, 'BinaryOpNode') && strcmp(node_to_parse.op, '*')
% Parse param_expr * endog_expr
Xtmp = parseTimesNode(ds, node_to_parse, jsonmodel{i}.line);
if length(Xtmp.name) > 1
% Handle constraits
% Look through Xtmp names for constant
% if found, subtract from LHS
to_remove = [];
for j = 1:length(Xtmp.name)
if ~isnan(str2double(Xtmp.name{j}))
lhssub = lhssub + str2double(Xtmp.name{j}) * Xtmp{j};
to_remove = [to_remove j];
end
% Multiply by -1 now so that it can be added together below
% Otherwise, it would matter which was encountered first,
% a parameter on its own or a linear constraint
Xtmp.(Xtmp.name{j}) = -1 * Xtmp{j};
end
for j = length(to_remove):-1:1
Xtmp = Xtmp.remove(Xtmp.name{j});
end
end
else
Xtmp = eval(regexprep(vnames{j}, regex, 'ds.$&'));
Xtmp.rename_(vnames{j});
end
X = [X Xtmp];
if ~isempty(Xtmp)
to_remove = [];
for j = 1:length(Xtmp.name)
% Handle constraits
idx = find(strcmp(X.name, Xtmp.name{j}));
if ~isempty(idx)
X.(X.name{idx}) = X{idx} + Xtmp{j};
to_remove = [to_remove j];
end
end
for j = length(to_remove):-1:1
Xtmp = Xtmp.remove(Xtmp.name{j});
end
X = [X Xtmp];
end
end
lhssub = getRhsToSubFromLhs(ds, jsonmodel{i}.rhs, regex, splitstrings, pnames);
residuals = setdiff(intersect(rhs_, M_.exo_names), ds.name);
assert(~isempty(residuals), ['No residuals in equation ' num2str(i)]);
assert(length(residuals) == 1, ['More than one residual in equation ' num2str(i)]);
clear residual Xtmp plus_node last_node_to_parse to_remove
Y = eval(regexprep(jsonmodel{i}.lhs, regex, 'ds.$&'));
if ~isempty(lhssub)
Y = Y - lhssub;
Y = Y - lhssub;
%% Check to see if called from Gibbs
st = dbstack(1);
varargout = cell(1, 1);
called_from_olsgibbs = false;
if strcmp(st(1).name, 'olsgibbs')
varargout = cell(1, 4);
called_from_olsgibbs = true;
end
%% Set dates
fp = max(Y.firstobservedperiod, X.firstobservedperiod);
lp = min(Y.lastobservedperiod, X.lastobservedperiod);
if ~isempty(lhssub)
fp = max(fp, lhssub.firstobservedperiod);
lp = min(lp, lhssub.lastobservedperiod);
end
if isfield(jsonmodel{i}, 'tags') ...
&& isfield(jsonmodel{i}.tags, 'sample') ...
&& ~isempty(jsonmodel{i}.tags.sample)
@ -171,7 +206,7 @@ for i = 1:length(jsonmodel)
fp = fsd;
end
if lp < lsd
warning(['The sample over which you want to estimate contains NaNs. '...
warning(['The sample over which you want to estimate contains NaNs. '...
'Adjusting estimation range to end on: ' lp.char])
else
lp = lsd;
@ -179,17 +214,11 @@ for i = 1:length(jsonmodel)
end
Y = Y(fp:lp);
X = X(fp:lp).data;
if ~isempty(lhssub)
lhssub = lhssub(fp:lp);
end
if isfield(jsonmodel{i}, 'tags') && ...
isfield(jsonmodel{i}.tags, 'name')
tag = jsonmodel{i}.tags.('name');
else
tag = ['eq_line_no_' num2str(jsonmodel{i}.line)];
end
pnames = X.name;
X = X(fp:lp).data;
[nobs, nvars] = size(X);
if called_from_olsgibbs
@ -203,9 +232,15 @@ for i = 1:length(jsonmodel)
return
end
if isfield(jsonmodel{i}, 'tags') && ...
isfield(jsonmodel{i}.tags, 'name')
tag = jsonmodel{i}.tags.('name');
else
tag = ['eq_line_no_' num2str(jsonmodel{i}.line)];
end
%% Estimation
% From LeSage, James P. "Applied Econometrics using MATLAB"
oo_.ols.(tag).dof = nobs - nvars;
% Estimated Parameters
@ -214,8 +249,10 @@ for i = 1:length(jsonmodel)
oo_.ols.(tag).beta = r\(q'*Y.data);
oo_.ols.(tag).param_idxs = zeros(length(pnames), 1);
for j = 1:length(pnames)
oo_.ols.(tag).param_idxs(j) = find(strcmp(M_.param_names, pnames{j}));
M_.params(oo_.ols.(tag).param_idxs(j)) = oo_.ols.(tag).beta(j);
if ~strcmp(pnames{j}, 'intercept')
oo_.ols.(tag).param_idxs(j) = find(strcmp(M_.param_names, pnames{j}));
M_.params(oo_.ols.(tag).param_idxs(j)) = oo_.ols.(tag).beta(j);
end
end
% Yhat
@ -233,11 +270,9 @@ for i = 1:length(jsonmodel)
oo_.ols.(tag).resid = Y - oo_.ols.(tag).Yhat;
% Correct Yhat reported back to user
if ~isempty(lhssub)
Y = Y + lhssub;
oo_.ols.(tag).Yhat = oo_.ols.(tag).Yhat + lhssub;
end
Y = Y + lhssub;
oo_.ols.(tag).Yhat = oo_.ols.(tag).Yhat + lhssub;
% Apply correcting function for Yhat if it was passed
if any(idx) ...
&& length(fitted_names_dict(idx, :)) == 3 ...
@ -287,12 +322,169 @@ for i = 1:length(jsonmodel)
sprintf('s^2: %f', oo_.ols.(tag).s2), ...
sprintf('Durbin-Watson: %f', oo_.ols.(tag).dw)};
dyn_table(title, preamble, afterward, vnames, ...
{'Coefficients','t-statistic','Std. Error'}, 4, ...
dyn_table(title, preamble, afterward, pnames, ...
{'Estimates','t-statistic','Std. Error'}, 4, ...
[oo_.ols.(tag).beta oo_.ols.(tag).tstat oo_.ols.(tag).stderr]);
end
end
if ~called_from_olsgibbs
varargout{1} = ds;
if ~called_from_olsgibbs
varargout{1} = ds;
end
end
end
%% Helper Functions
function ols_error(msg, line)
error(['ERROR encountered in `dyn_ols` line ' num2str(line) ': ' msg])
end
function [next_plus_node, node_to_parse, last_node_to_parse] = findNextplus_node(plus_node, line)
% Given an additive entry in the AST, find the next additive entry
% (next_plus_node). Also find the node that will be parsed into
% parameter*endogenous||param||exog|endog (node_to_parse).
% Function used for moving through the AST.
if ~(strcmp(plus_node.node_type, 'BinaryOpNode') && strcmp(plus_node.op, '+'))
ols_error('pairs of nodes must be separated additively', line);
end
next_plus_node = [];
last_node_to_parse = [];
if strcmp(plus_node.arg1.node_type, 'BinaryOpNode') && strcmp(plus_node.arg1.op, '+')
next_plus_node = plus_node.arg1;
node_to_parse = getOlsNode(plus_node.arg2, line);
elseif strcmp(plus_node.arg2.node_type, 'BinaryOpNode') && strcmp(plus_node.arg2.op, '+')
next_plus_node = plus_node.arg2;
node_to_parse = getOlsNode(plus_node.arg1, line);
else
node_to_parse = getOlsNode(plus_node.arg1, line);
last_node_to_parse = getOlsNode(plus_node.arg2, line);
end
end
function node_to_parse = getOlsNode(node, line)
if ~(strcmp(node.node_type, 'BinaryOpNode') && strcmp(node.op, '*')) ...
&& ~strcmp(node.node_type, 'VariableNode') ...
&& ~strcmp(node.node_type, 'UnaryOpNode')
ols_error('couldn''t find node to parse', line);
end
node_to_parse = node;
end
function X = parseTimesNode(ds, node, line)
% Separate the parameter expression from the endogenous expression
assert(strcmp(node.node_type, 'BinaryOpNode') && strcmp(node.op, '*'))
[param, X] = parseTimesNodeHelper(ds, node.arg1, line, {}, dseries());
[param, X] = parseTimesNodeHelper(ds, node.arg2, line, param, X);
X = X.rename(param{1});
for ii = 2:length(param)
X = [X dseries(X{1}.data, X{1}.firstdate, param{ii})];
end
end
function [param, X] = parseTimesNodeHelper(ds, node, line, param, X)
if isOlsParamExpr(node, line)
param = assignParam(param, node, line);
elseif isOlsVarExpr(node, line)
if isempty(X)
X = evalNode(ds, node, line, X);
else
ols_error(['got endog * endog' node.name ' (' node.type ')'], line);
end
else
ols_error('unexpected expression', line);
end
end
function param = assignParam(param, node, line)
if ~isempty(param)
ols_error(['got param * param' node.name ' (' node.type ')'], line);
end
param = assignParamHelper(param, node, line);
end
function param = assignParamHelper(param, node, line)
if strcmp(node.node_type, 'NumConstNode')
param{end+1} = num2str(node.value);
elseif strcmp(node.node_type, 'VariableNode')
param{end+1} = node.name;
elseif strcmp(node.node_type, 'BinaryOpNode')
if ~strcmp(node.op, '-')
ols_error(['got unexpected parameter op ' node.op], line);
end
param = assignParamHelper(param, node.arg1, line);
param = assignParamHelper(param, node.arg2, line);
else
ols_error(['got unexpected node (' node.type ')'], line);
end
end
function tf = isOlsVar(node)
if strcmp(node.node_type, 'VariableNode') ...
&& (strcmp(node.type, 'endogenous') ...
|| (strcmp(node.type, 'exogenous') && any(strcmp(ds.name, node.name))))
tf = true;
elseif strcmp(node.node_type, 'UnaryOpNode') ...
&& (strcmp(node.arg.type, 'endogenous') ...
|| (strcmp(node.arg.type, 'exogenous') && any(strcmp(ds.name, node.arg.name))))
tf = true;
else
tf = false;
end
end
function tf = isOlsVarExpr(node, line)
if strcmp(node.node_type, 'VariableNode') || strcmp(node.node_type, 'UnaryOpNode')
tf = isOlsVar(node);
elseif strcmp(node.node_type, 'BinaryOpNode')
tf = isOlsVarExpr(node.arg1, line) || isOlsVarExpr(node.arg2, line);
else
ols_error(['got unexpected type ' node.node_type], line);
end
end
function X = evalNode(ds, node, line, X)
if strcmp(node.node_type, 'NumConstNode')
X = dseries(str2double(node.value), ds.dates, 'const');
elseif strcmp(node.node_type, 'VariableNode')
if ~(strcmp(node.type, 'endogenous') ...
|| (strcmp(node.type, 'exogenous') && any(strcmp(ds.name, node.name))))
ols_error(['got unexpected type ' node.name ': ' node.type], line);
end
X = ds.(node.name)(node.lag);
elseif strcmp(node.node_type, 'UnaryOpNode')
Xtmp = evalNode(ds, node.arg, line, X);
% Only works if dseries supports . notation for unary op (true for log/diff)
% Otherwise, use: X = eval([node.op '(Xtmp)']);
X = Xtmp.(node.op);
elseif strcmp(node.node_type, 'BinaryOpNode')
Xtmp1 = evalNode(ds, node.arg1, line, X);
Xtmp2 = evalNode(ds, node.arg2, line, X);
X = X + eval(['Xtmp1 ' node.op ' Xtmp2']);
else
ols_error(['got unexpected node type ' node.node_type], line);
end
end
function tf = isOlsParam(node)
if strcmp(node.node_type, 'VariableNode') && strcmp(node.type, 'parameter')
tf = true;
else
tf = false;
end
end
function tf = isOlsParamExpr(node, line)
if strcmp(node.node_type, 'NumConstNode')
tf = true;
elseif strcmp(node.node_type, 'VariableNode')
tf = isOlsParam(node);
elseif strcmp(node.node_type, 'UnaryOpNode')
tf = false;
elseif strcmp(node.node_type, 'BinaryOpNode')
tf = isOlsParamExpr(node.arg1) && isOlsParamExpr(node.arg2);
if tf && ~strcmp(node.op, '-')
ols_error(['got unexpected op ' node.op], line);
end
else
ols_error(['got unexpected type ' node.node_type], line);
end
end

View File

@ -0,0 +1,150 @@
// --+ options: json=compute nopreprocessoroutput stochastic +--
/* REMARK
** ------
**
** You need to have the first line on top of the mod file. The options defined on this line are passed
** to the dynare command (you can add other options, separated by spaces or commas). The option defined
** here is mandatory for the decomposition. It forces Dynare to output another representation of the
** model in JSON file (additionaly to the matlab files) which is used here to manipulate the equations.
*/
var
U2_Q_YED
U2_G_YER
U2_STN
U2_ESTN
U2_EHIC
DE_Q_YED
DE_G_YER
DE_EHIC
;
varexo
res_U2_Q_YED
res_U2_G_YER
res_U2_STN
res_U2_ESTN
res_U2_EHIC
res_DE_Q_YED
res_DE_G_YER
res_DE_EHIC
;
parameters
u2_q_yed_ecm_u2_q_yed_L1
u2_q_yed_ecm_u2_stn_L1
u2_q_yed_u2_g_yer_L1
u2_q_yed_u2_stn_L1
u2_g_yer_ecm_u2_q_yed_L1
u2_g_yer_ecm_u2_stn_L1
u2_g_yer_u2_q_yed_L1
u2_g_yer_u2_g_yer_L1
u2_g_yer_u2_stn_L1
u2_stn_ecm_u2_q_yed_L1
u2_stn_ecm_u2_stn_L1
u2_stn_u2_q_yed_L1
u2_stn_u2_g_yer_L1
u2_estn_u2_estn_L1
u2_ehic_u2_ehic_L1
de_q_yed_ecm_de_q_yed_L1
de_q_yed_ecm_u2_stn_L1
de_q_yed_de_g_yer_L1
de_q_yed_u2_stn_L1
de_g_yer_ecm_de_q_yed_L1
de_g_yer_ecm_u2_stn_L1
de_g_yer_de_q_yed_L1
de_g_yer_de_g_yer_L1
de_g_yer_u2_stn_L1
de_ehic_de_ehic_L1
;
u2_q_yed_ecm_u2_q_yed_L1 = -0.82237516589315 ;
u2_q_yed_ecm_u2_stn_L1 = -0.323715338568976 ;
u2_q_yed_u2_g_yer_L1 = 0.0401361895021084 ;
u2_q_yed_u2_stn_L1 = 0.058397703958446 ;
u2_g_yer_ecm_u2_q_yed_L1 = 0.0189896046977421 ;
u2_g_yer_ecm_u2_stn_L1 = -0.109597659887432 ;
u2_g_yer_u2_q_yed_L1 = 0.0037667967632025 ;
u2_g_yer_u2_g_yer_L1 = 0.480506381923644 ;
u2_g_yer_u2_stn_L1 = -0.0722359286123494 ;
u2_stn_ecm_u2_q_yed_L1 = -0.0438500662608356 ;
u2_stn_ecm_u2_stn_L1 = -0.153283917138772 ;
u2_stn_u2_q_yed_L1 = 0.0328744983772825 ;
u2_stn_u2_g_yer_L1 = 0.292121949736756 ;
u2_estn_u2_estn_L1 = 1 ;
u2_ehic_u2_ehic_L1 = 1 ;
de_q_yed_ecm_de_q_yed_L1 = -0.822375165893149 ;
de_q_yed_ecm_u2_stn_L1 = -0.323715338568977 ;
de_q_yed_de_g_yer_L1 = 0.0401361895021082 ;
de_q_yed_u2_stn_L1 = 0.0583977039584461 ;
de_g_yer_ecm_de_q_yed_L1 = 0.0189896046977422 ;
de_g_yer_ecm_u2_stn_L1 = -0.109597659887433 ;
de_g_yer_de_q_yed_L1 = 0.00376679676320256;
de_g_yer_de_g_yer_L1 = 0.480506381923643 ;
de_g_yer_u2_stn_L1 = -0.0722359286123494 ;
de_ehic_de_ehic_L1 = 1 ;
model(linear);
[name = 'eq1']
diff(U2_Q_YED) = u2_q_yed_ecm_u2_q_yed_L1 * (U2_Q_YED(-1) - U2_EHIC(-1))
+ u2_q_yed_ecm_u2_stn_L1 * (U2_STN(-1) - U2_ESTN(-1))
+ u2_q_yed_u2_g_yer_L1 * diff(U2_G_YER(-1))
+ u2_q_yed_u2_stn_L1 * diff(U2_STN(-1))
+ res_U2_Q_YED ;
[name = 'eq2']
diff(U2_G_YER) = u2_g_yer_ecm_u2_q_yed_L1 * (U2_Q_YED(-1) - U2_EHIC(-1))
+ u2_g_yer_ecm_u2_stn_L1 * (U2_STN(-1) - U2_ESTN(-1))
+ u2_g_yer_u2_q_yed_L1 * diff(U2_Q_YED(-1))
+ u2_g_yer_u2_g_yer_L1 * diff(U2_G_YER(-1))
+ u2_g_yer_u2_stn_L1 * diff(U2_STN(-1))
+ res_U2_G_YER ;
[name = 'eq3']
diff(U2_STN) = u2_stn_ecm_u2_q_yed_L1 * (U2_Q_YED(-1) - U2_EHIC(-1))
+ u2_stn_ecm_u2_stn_L1 * (U2_STN(-1) - U2_ESTN(-1))
+ u2_stn_u2_q_yed_L1 * diff(U2_Q_YED(-1))
+ u2_stn_u2_g_yer_L1 * diff(U2_G_YER(-1))
+ res_U2_STN ;
[name = 'eq4']
U2_ESTN = u2_estn_u2_estn_L1 * U2_ESTN(-1)
+ res_U2_ESTN ;
[name = 'eq5']
U2_EHIC = u2_ehic_u2_ehic_L1 * U2_EHIC(-1)
+ res_U2_EHIC ;
[name = 'eq6']
diff(DE_Q_YED) = de_q_yed_ecm_de_q_yed_L1 * (DE_Q_YED(-1) - DE_EHIC(-1))
+ de_q_yed_ecm_u2_stn_L1 * (U2_STN(-1) - U2_ESTN(-1))
+ de_q_yed_de_g_yer_L1 * diff(DE_G_YER(-1))
+ de_q_yed_u2_stn_L1 * diff(U2_STN(-1))
+ res_DE_Q_YED ;
[name = 'eq7']
diff(DE_G_YER) = de_g_yer_ecm_de_q_yed_L1 * (DE_Q_YED(-1) - DE_EHIC(-1))
+ de_g_yer_ecm_u2_stn_L1 * (U2_STN(-1) - U2_ESTN(-1))
+ de_g_yer_de_q_yed_L1 * diff(DE_Q_YED(-1))
+ de_g_yer_de_g_yer_L1 * diff(DE_G_YER(-1))
+ de_g_yer_u2_stn_L1 * diff(U2_STN(-1))
+ res_DE_G_YER ;
[name = 'eq8']
DE_EHIC = de_ehic_de_ehic_L1 * DE_EHIC(-1)
+ res_DE_EHIC ;
end;
shocks;
var res_U2_Q_YED = 0.005;
var res_U2_G_YER = 0.005;
var res_U2_STN = 0.005;
var res_U2_ESTN = 0.005;
var res_U2_EHIC = 0.005;
var res_DE_Q_YED = 0.005;
var res_DE_G_YER = 0.005;
var res_DE_EHIC = 0.005;
end;

View File

@ -0,0 +1,39 @@
close all
dynare ols.mod;
global options_
options_.noprint = true;
NSIMS = 1000;
calibrated_values = M_.params;
Sigma_e = M_.Sigma_e;
options_.bnlms.set_dynare_seed_to_default = false;
nparampool = length(M_.params);
BETA = zeros(NSIMS, nparampool);
for i=1:NSIMS
i
firstobs = rand(3, length(M_.endo_names));
M_.params = calibrated_values;
M_.Sigma_e = Sigma_e;
simdata = simul_backward_model(dseries(firstobs, dates('1995Q1'), M_.endo_names), 10000);
simdata = simdata(simdata.dates(5001:6000));
names = regexp(simdata.name, 'res\w*');
idxs = find(cellfun(@isempty, names));
dyn_ols(simdata{idxs}, {}, {'eq7'});
BETA(i, :) = M_.params';
end
mean(BETA)' - calibrated_values
for i=1:nparampool
figure
hold on
title(strrep(M_.param_names(i,:), '_', '\_'));
histogram(BETA(:,i),50);
line([calibrated_values(i) calibrated_values(i)], [0 NSIMS/10], 'LineWidth', 2, 'Color', 'r');
hold off
end