diff --git a/matlab/ols/dyn_ols.m b/matlab/ols/dyn_ols.m index 38155466b..a730ecfe3 100644 --- a/matlab/ols/dyn_ols.m +++ b/matlab/ols/dyn_ols.m @@ -41,7 +41,7 @@ assert(isdseries(ds), 'dyn_ols: the first argument must be a dseries'); jsonfile = [M_.fname '_original.json']; if exist(jsonfile, 'file') ~= 2 - error('Could not find %s! Please use the json option (See the Dynare invocation section in the reference manual).', jsonfile); + error('Could not find %s! Please use the json=compute option (See the Dynare invocation section in the reference manual).', jsonfile); end %% Get Equation(s) diff --git a/matlab/ols/pooled_ols.m b/matlab/ols/pooled_ols.m index 0189884ee..38ef18255 100644 --- a/matlab/ols/pooled_ols.m +++ b/matlab/ols/pooled_ols.m @@ -19,7 +19,7 @@ function pooled_ols(ds, param_common, param_regex, overlapping_dates, save_struc % none % % SPECIAL REQUIREMENTS -% dynare must be run with the option: json=parse +% dynare must be run with the option: json=compute % Copyright (C) 2017 Dynare Team % @@ -40,7 +40,7 @@ function pooled_ols(ds, param_common, param_regex, overlapping_dates, save_struc global M_ oo_ -% Check input arguments +%% Check input arguments assert(~isempty(ds) && isdseries(ds), 'The first argument must be a dseries'); if isempty(param_common) && isempty(param_regex) @@ -66,7 +66,7 @@ end %% Read JSON jsonfile = [M_.fname '_original.json']; if exist(jsonfile, 'file') ~= 2 - error('Could not find %s! Please use the json=parse option (See the Dynare invocation section in the reference manual).', jsonfile); + error('Could not find %s! Please use the json=compute option (See the Dynare invocation section in the reference manual).', jsonfile); end jsonmodel = loadjson(jsonfile); @@ -86,127 +86,9 @@ end %% Find parameters and variable names in every equation & Setup estimation matrices M_exo_names_trim = cellstr(M_.exo_names); -M_endo_exo_names_trim = [cellstr(M_.endo_names); M_exo_names_trim]; M_param_names_trim = cellstr(M_.param_names); -regex = strjoin(M_endo_exo_names_trim(:,1), '|'); -mathops = '[\+\*\^\-\/]'; -params = cell(length(rhs),1); -vars = cell(length(rhs),1); -pbeta = {}; -Y = []; -X = []; -startidxs = zeros(length(lhs), 1); -startdates = cell(length(lhs), 1); -enddates = cell(length(lhs), 1); -residnames = cell(length(lhs), 1); -for i = 1:length(lhs) - rhs_ = strsplit(rhs{i}, {'+','-','*','/','^','log(','ln(','log10(','exp(','(',')','diff('}); - rhs_(cellfun(@(x) all(isstrprop(x, 'digit')), rhs_)) = []; - vnames = setdiff(rhs_, M_param_names_trim); - if ~isempty(regexp(rhs{i}, ... - ['(' strjoin(vnames, '\\(\\d+\\)|') '\\(\\d+\\))'], ... - 'once')) - error(['pooled_ols: you cannot have leads in equation on line ' ... - lineno{i} ': ' lhs{i} ' = ' rhs{i}]); - end - - % Find parameters and associated variables - pnames = intersect(rhs_, M_param_names_trim); - pidxs = zeros(length(pnames), 1); - vnames = cell(1, length(pnames)); - splitstrings = cell(length(pnames), 1); - xjdata = dseries; - for j = 1:length(pnames) - createdvar = false; - idx = find(strcmp(pbeta, pnames{j})); - if isempty(idx) - pbeta = [pbeta; pnames{j}]; - pidxs(j) = length(pbeta); - else - pidxs(j) = idx; - end - - pregex = [... - mathops pnames{j} mathops ... - '|^' pnames{j} mathops ... - '|' mathops pnames{j} '$' ... - ]; - [startidx, endidx] = regexp(rhs{i}, pregex, 'start', 'end'); - assert(length(startidx) == 1); - if rhs{i}(startidx) == '*' && rhs{i}(endidx) == '*' - vnames{j} = [getStrMoveLeft(rhs{i}(1:startidx-1)) '*' ... - getStrMoveRight(rhs{i}(endidx+1:end))]; - elseif rhs{i}(startidx) == '*' - vnames{j} = getStrMoveLeft(rhs{i}(1:startidx-1)); - splitstrings{j} = [vnames{j} '*' pnames{j}]; - elseif rhs{i}(endidx) == '*' - vnames{j} = getStrMoveRight(rhs{i}(endidx+1:end)); - splitstrings{j} = [pnames{j} '*' vnames{j}]; - if rhs{i}(startidx) == '-' - vnames{j} = ['-' vnames{j}]; - splitstrings{j} = ['-' splitstrings{j}]; - end - elseif rhs{i}(startidx) == '+' ... - || rhs{i}(startidx) == '-' ... - || rhs{i}(endidx) == '+' ... - || rhs{i}(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}; - else - error('pooled_ols: Shouldn''t arrive here'); - end - if createdvar - xjdatatmp = dseries(ones(ds.nobs, 1), ds.firstdate, vnames{j}); - else - xjdatatmp = eval(regexprep(vnames{j}, regex, 'ds.$&')); - xjdatatmp.rename_(vnames{j}); - end - xjdatatmp.rename_(num2str(j)); - xjdata = [xjdata xjdatatmp]; - end - - lhssub = getRhsToSubFromLhs(ds, rhs{i}, regex, [splitstrings; pnames]); - - residnames{i} = setdiff(intersect(rhs_, M_exo_names_trim), ds.name); - assert(~isempty(residnames{i}), ['No residuals in equation ' num2str(i)]); - assert(length(residnames{i}) == 1, ['More than one residual in equation ' num2str(i)]); - - params{i} = pnames; - vars{i} = [vnames{:}]; - - ydata = eval(regexprep(lhs{i}, regex, 'ds.$&')); - for j = 1:lhssub.vobs - ydata = ydata - lhssub{j}; - end - - if isempty(xjdata) - % AR(1) case - fp = ydata.firstobservedperiod; - lp = ydata.lastobservedperiod; - startidxs(i) = length(Y) + 1; - startdates{i} = fp; - enddates{i} = lp; - Y(startidxs(i):startidxs(i)+lp-fp, 1) = ydata(fp:lp).data; - X(startidxs(i):startidxs(i)+lp-fp, :) = zeros(ydata(fp:lp).nobs, columns(X)); - else - fp = max(ydata.firstobservedperiod, xjdata.firstobservedperiod); - lp = min(ydata.lastobservedperiod, xjdata.lastobservedperiod); - - startidxs(i) = length(Y) + 1; - startdates{i} = fp; - enddates{i} = lp; - Y(startidxs(i):startidxs(i)+lp-fp, 1) = ydata(fp:lp).data; - X(startidxs(i):startidxs(i)+lp-fp, pidxs) = xjdata(fp:lp).data; - end -end +[X, Y, startdates, enddates, startidxs, residnames, pbeta, vars, pidxs] = ... + pooled_sur_common(ds, lhs, rhs, lineno, M_exo_names_trim, M_param_names_trim); if overlapping_dates maxfp = max([startdates{:}]); diff --git a/matlab/ols/pooled_sur_common.m b/matlab/ols/pooled_sur_common.m new file mode 100644 index 000000000..a63272e83 --- /dev/null +++ b/matlab/ols/pooled_sur_common.m @@ -0,0 +1,157 @@ +function [X, Y, startdates, enddates, startidxs, residnames, pbeta, vars, surpidxs] = pooled_sur_common(ds, lhs, rhs, lineno, M_exo_names_trim, M_param_names_trim); + +% +% Code common to sur.m and pooled_ols.m +% +% INPUTS +% none +% +% OUTPUTS +% none +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2017 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 . + +global M_ + +M_endo_exo_names_trim = [cellstr(M_.endo_names); M_exo_names_trim]; +regex = strjoin(M_endo_exo_names_trim(:,1), '|'); +mathops = '[\+\*\^\-\/]'; +params = cell(length(rhs),1); +vars = cell(length(rhs),1); +pbeta = {}; +Y = []; +X = []; +startidxs = zeros(length(lhs), 1); +startdates = cell(length(lhs), 1); +enddates = cell(length(lhs), 1); +residnames = cell(length(lhs), 1); +surpidxs = zeros(M_.param_nbr, 1); +surpidx = 0; +for i = 1:length(lhs) + rhs_ = strsplit(rhs{i}, {'+','-','*','/','^','log(','ln(','log10(','exp(','(',')','diff('}); + rhs_(cellfun(@(x) all(isstrprop(x, 'digit')), rhs_)) = []; + vnames = setdiff(rhs_, M_param_names_trim); + if ~isempty(regexp(rhs{i}, ... + ['(' strjoin(vnames, '\\(\\d+\\)|') '\\(\\d+\\))'], 'once')) + error(['pooled_ols: you cannot have leads in equation on line ' ... + lineno{i} ': ' lhs{i} ' = ' rhs{i}]); + end + + % Find parameters and associated variables + pnames = intersect(rhs_, M_param_names_trim); + pidxs = zeros(length(pnames), 1); + vnames = cell(1, length(pnames)); + splitstrings = cell(length(pnames), 1); + xjdata = dseries; + for j = 1:length(pnames) + createdvar = false; + idx = find(strcmp(pbeta, pnames{j})); + if isempty(idx) + pbeta = [pbeta; pnames{j}]; + pidxs(j) = length(pbeta); + else + pidxs(j) = idx; + end + surpidx = surpidx + 1; + surpidxs(surpidx, 1) = find(strcmp(pnames{j}, M_param_names_trim)); + + pregex = [... + mathops pnames{j} mathops ... + '|^' pnames{j} mathops ... + '|' mathops pnames{j} '$' ... + ]; + [startidx, endidx] = regexp(rhs{i}, pregex, 'start', 'end'); + assert(length(startidx) == 1); + if rhs{i}(startidx) == '*' && rhs{i}(endidx) == '*' + vnames{j} = [getStrMoveLeft(rhs{i}(1:startidx-1)) '*' ... + getStrMoveRight(rhs{i}(endidx+1:end))]; + elseif rhs{i}(startidx) == '*' + vnames{j} = getStrMoveLeft(rhs{i}(1:startidx-1)); + splitstrings{j} = [vnames{j} '*' pnames{j}]; + elseif rhs{i}(endidx) == '*' + vnames{j} = getStrMoveRight(rhs{i}(endidx+1:end)); + splitstrings{j} = [pnames{j} '*' vnames{j}]; + if rhs{i}(startidx) == '-' + vnames{j} = ['-' vnames{j}]; + splitstrings{j} = ['-' splitstrings{j}]; + end + elseif rhs{i}(startidx) == '+' ... + || rhs{i}(startidx) == '-' ... + || rhs{i}(endidx) == '+' ... + || rhs{i}(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}; + else + error('pooled_ols: Shouldn''t arrive here'); + end + if createdvar + xjdatatmp = dseries(ones(ds.nobs, 1), ds.firstdate, vnames{j}); + else + xjdatatmp = eval(regexprep(vnames{j}, regex, 'ds.$&')); + xjdatatmp.rename_(vnames{j}); + end + xjdatatmp.rename_(num2str(j)); + xjdata = [xjdata xjdatatmp]; + end + + lhssub = getRhsToSubFromLhs(ds, rhs{i}, regex, [splitstrings; pnames]); + + residnames{i} = setdiff(intersect(rhs_, M_exo_names_trim), ds.name); + assert(~isempty(residnames{i}), ['No residuals in equation ' num2str(i)]); + assert(length(residnames{i}) == 1, ['More than one residual in equation ' num2str(i)]); + + params{i} = pnames; + vars{i} = vnames; + + ydata = eval(regexprep(lhs{i}, regex, 'ds.$&')); + for j = 1:lhssub.vobs + ydata = ydata - lhssub{j}; + end + + if isempty(xjdata) + % AR(1) case + fp = ydata.firstobservedperiod; + lp = ydata.lastobservedperiod; + startidxs(i) = length(Y) + 1; + startdates{i} = fp; + enddates{i} = lp; + Y(startidxs(i):startidxs(i)+lp-fp, 1) = ydata(fp:lp).data; + X(startidxs(i):startidxs(i)+lp-fp, :) = zeros(ydata(fp:lp).nobs, columns(X)); + else + fp = max(ydata.firstobservedperiod, xjdata.firstobservedperiod); + lp = min(ydata.lastobservedperiod, xjdata.lastobservedperiod); + + startidxs(i) = length(Y) + 1; + startdates{i} = fp; + enddates{i} = lp; + Y(startidxs(i):startidxs(i)+lp-fp, 1) = ydata(fp:lp).data; + X(startidxs(i):startidxs(i)+lp-fp, pidxs) = xjdata(fp:lp).data; + end +end +end \ No newline at end of file diff --git a/matlab/ols/sur.m b/matlab/ols/sur.m index 456605396..75becfe1a 100644 --- a/matlab/ols/sur.m +++ b/matlab/ols/sur.m @@ -9,7 +9,7 @@ function varargout = sur(ds) % none % % SPECIAL REQUIREMENTS -% dynare must be run with the option: json=parse +% dynare must be run with the option: json=compute % Copyright (C) 2017 Dynare Team % @@ -36,7 +36,7 @@ assert(~isempty(ds) && isdseries(ds), 'The first argument must be a dseries'); %% Read JSON jsonfile = [M_.fname '_original.json']; if exist(jsonfile, 'file') ~= 2 - error('Could not find %s! Please use the json=parse option (See the Dynare invocation section in the reference manual).', jsonfile); + error('Could not find %s! Please use the json=compute option (See the Dynare invocation section in the reference manual).', jsonfile); end jsonmodel = loadjson(jsonfile); @@ -45,104 +45,15 @@ jsonmodel = jsonmodel.model; %% Find parameters and variable names in equations and setup estimation matrices M_exo_names_trim = cellstr(M_.exo_names); -M_endo_exo_names_trim = [cellstr(M_.endo_names); M_exo_names_trim]; M_param_names_trim = cellstr(M_.param_names); -regex = strjoin(M_endo_exo_names_trim(:,1), '|'); -mathops = '[\+\*\^\-\/]'; -params = cell(length(rhs),1); -vars = cell(length(rhs),1); -Y = []; -X = []; -startidxs = zeros(length(lhs), 1); -startdates = cell(length(lhs), 1); -enddates = cell(length(lhs), 1); -residnames = cell(length(lhs), 1); -pidxs = zeros(M_.param_nbr, 1); -pidx = 0; -vnamesall = {}; -for i = 1:length(lhs) - rhs_ = strsplit(rhs{i}, {'+','-','*','/','^','log(','ln(','log10(','exp(','(',')','diff('}); - rhs_(cellfun(@(x) all(isstrprop(x, 'digit')), rhs_)) = []; - vnames = setdiff(rhs_, M_param_names_trim); - if ~isempty(regexp(rhs{i}, ... - ['(' strjoin(vnames, '\\(\\d+\\)|') '\\(\\d+\\))'], ... - 'once')) - error(['sur1: you cannot have leads in equation on line ' ... - lineno{i} ': ' lhs{i} ' = ' rhs{i}]); - end +[X, Y, startdates, enddates, startidxs, residnames, pbeta, vars, pidxs] = ... + pooled_sur_common(ds, lhs, rhs, lineno, M_exo_names_trim, M_param_names_trim); - % Find parameters and associated variables - pnames = intersect(rhs_, M_param_names_trim); - vnames = cell(1, length(pnames)); - xjdata = dseries; - for j = 1:length(pnames) - pidx = pidx + 1; - pidxs(pidx, 1) = find(strcmp(pnames{j}, M_param_names_trim)); - createdvar = false; - pregex = [... - mathops pnames{j} mathops ... - '|^' pnames{j} mathops ... - '|' mathops pnames{j} '$' ... - ]; - [startidx, endidx] = regexp(rhs{i}, pregex, 'start', 'end'); - assert(length(startidx) == 1); - if rhs{i}(startidx) == '*' - vnames{j} = getStrMoveLeft(rhs{i}(1:startidx-1)); - elseif rhs{i}(endidx) == '*' - vnames{j} = getStrMoveRight(rhs{i}(endidx+1:end)); - elseif rhs{i}(startidx) == '+' ... - || rhs{i}(startidx) == '-' ... - || rhs{i}(endidx) == '+' ... - || rhs{i}(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 - else - error('sur1: Shouldn''t arrive here'); - end - if createdvar - xjdatatmp = dseries(ones(ds.nobs, 1), ds.firstdate, vnames{j}); - else - xjdatatmp = eval(regexprep(vnames{j}, regex, 'ds.$&')); - xjdatatmp.rename_(vnames{j}); - end - xjdatatmp.rename_(num2str(j)); - xjdata = [xjdata xjdatatmp]; - end - - residuals = intersect(rhs_, cellstr(M_.exo_names)); - for j = 1:length(residuals) - if any(strcmp(residuals{j}, vnames)) - residuals{j} = []; - end - end - idx = ~cellfun(@isempty, residuals); - assert(sum(idx) == 1, ['More than one residual in equation ' num2str(i)]); - residnames{i} = residuals{idx}; - - params{i} = pnames; - vars{i} = vnames; - - ydata = eval(regexprep(lhs{i}, regex, 'ds.$&')); - - fp = max(ydata.firstobservedperiod, xjdata.firstobservedperiod); - lp = min(ydata.lastobservedperiod, xjdata.lastobservedperiod); - - startidxs(i) = length(Y) + 1; - startdates{i} = fp; - enddates{i} = lp; - Y(startidxs(i):startidxs(i)+lp-fp, 1) = ydata(fp:lp).data; - X(startidxs(i):startidxs(i)+lp-fp, end+1:end+size(xjdata(fp:lp).data,2)) = xjdata(fp:lp).data; +if size(X, 2) ~= M_.param_nbr + warning(['Not all parameters were used in model: ' ... + sprintf('%s', strjoin(setdiff(M_param_names_trim, pbeta), ', '))]); end -assert(size(X, 2) == M_.param_nbr, 'Not all parameters were used in model'); - %% Force equations to have the same sample range maxfp = max([startdates{:}]); minlp = min([enddates{:}]); diff --git a/tests/ECB/SUR/run_simulation_test.m b/tests/ECB/SUR/run_simulation_test.m index f514fceb1..6754e2ad3 100644 --- a/tests/ECB/SUR/run_simulation_test.m +++ b/tests/ECB/SUR/run_simulation_test.m @@ -20,7 +20,14 @@ for i=1:NSIMS M_.Sigma_e = Sigma_e; simdata = simul_backward_model(dseries(firstobs, dates('1995Q1'), M_endo_names_trim), 10000); simdata = simdata(simdata.dates(5001:6000)); - sur(simdata); + names=regexp(simdata.name, 'res\w*'); + idxs = []; + for j=1:length(names) + if isempty(names{j}) + idxs = [idxs j]; + end + end + sur(simdata{idxs}); BETA(i, :) = M_.params'; end diff --git a/tests/ECB/pooled_ols/run_simulation_test.m b/tests/ECB/pooled_ols/run_simulation_test.m index 181b03e3b..daad58708 100644 --- a/tests/ECB/pooled_ols/run_simulation_test.m +++ b/tests/ECB/pooled_ols/run_simulation_test.m @@ -26,8 +26,7 @@ for i=1:NSIMS idxs = [idxs j]; end end - simdata = simdata{idxs}; - pooled_ols(simdata, ... + pooled_ols(simdata{idxs}, ... {'de','u2'}, ... {'*_q_yed_ecm_*_q_yed_L1', ... '*_q_yed_ecm_u2_stn_L1', ...