Unverified Commit b70d99d1 authored by MichelJuillard's avatar MichelJuillard Committed by Sébastien Villemot

Refactoring of initval_file and histval_file

initval_file and hisvfal_file are now more flexible and have functionalities
similar to option datafile in estimation.

Closes: #1671
parent fc2e6ef8
This diff is collapsed.
......@@ -92,6 +92,7 @@ oo_.dr = [];
oo_.exo_steady_state = [];
oo_.exo_det_steady_state = [];
oo_.exo_det_simul = [];
oo_.initval_series = dseries();
oo_.gui.ran_estimation = false;
oo_.gui.ran_stoch_simul = false;
......
function histvalf(fname)
%function histvalf(fname)
function [endo_histval, exo_histval, exo_det_histval] = histvalf(M, options)
%function [endo_histval, exo_histval, exo_det_histval] = histvalf(M, options)
% Sets initial values for simulation using values contained in `fname`, a
% file possibly created by a call to `smoother2histval`
%
......@@ -13,7 +13,7 @@ function histvalf(fname)
% none
% Copyright (C) 2014-2019 Dynare Team
% Copyright (C) 2014-2020 Dynare Team
%
% This file is part of Dynare.
%
......@@ -30,72 +30,41 @@ function histvalf(fname)
% 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_ ex0_
if ~exist(fname, 'file')
error(['Can''t find datafile: ' fname ]);
if ~isfield(options, 'nobs') || isempty(options.nobs)
options.nobs = M.orig_maximum_lag;
end
M_.endo_histval = repmat(oo_.steady_state, 1, M_.maximum_endo_lag);
% Also fill in oo_.exo_simul: necessary if we are in deterministic context,
% since aux vars for lagged exo are not created in this case
if isempty(oo_.exo_simul)
if isempty(ex0_)
oo_.exo_simul = repmat(oo_.exo_steady_state',M_.maximum_lag,1);
if ~isfield(options, 'first_obs') || isempty(options.first_obs)
if isfield(options, 'first_simulation_period')
options.first_obs = options.first_simulation_period ...
- options.nobs;
else
oo_.exo_simul = repmat(ex0_',M_.maximum_lag,1);
options.first_obs = 1;
end
elseif isfield(options, 'first_simulation_period')
nobs = options.first_simulation_period - opions_.first_obs;
if options.nobs ~= nobs
error(sprintf(['HISTVALF: first_obs = %d and', ...
' first_simulation_period = %d', ...
' don''t provide for the number of' ...
' lags in the model.'], ...
options.first_obs, ...
options.first_simulation_period))
end
end
S = load(fname);
outvars = fieldnames(S);
series = histvalf_initvalf('HISTVAL', M, options);
% capture the difference between stochastic and
% perfect foresight setup
k = M.orig_maximum_lag - M.maximum_lag + 1;
endo_histval = series{M.endo_names{:}}.data(k:end, :)';
for i = 1:length(outvars)
ov_ = outvars{i};
if ov_(end) == '_'
ov = ov_(1:end-1);
j = strmatch(ov, M_.endo_names, 'exact');
if isempty(j)
warning(['smoother2histval: output variable ' ov ' does not exist.'])
end
else
% Lagged endogenous or exogenous, search through aux vars
undidx = find(ov_ == '_', 1, 'last'); % Index of last underscore in name
ov = ov_(1:(undidx-1));
lead_lag = ov_((undidx+1):end);
lead_lag = regexprep(lead_lag,'l','-');
lead_lag = str2num(lead_lag);
j = [];
for i = 1:length(M_.aux_vars)
if M_.aux_vars(i).type ~= 1 && M_.aux_vars(i).type ~= 3
continue
end
if M_.aux_vars(i).type == 1
% Endogenous
orig_var = M_.endo_names{M_.aux_vars(i).orig_index};
else
% Exogenous
orig_var = M_.exo_names{M_.aux_vars(i).orig_index};
end
if strcmp(orig_var, ov) && M_.aux_vars(i).orig_lead_lag == lead_lag
j = M_.aux_vars(i).endo_index;
end
end
if isempty(j)
% There is no aux var corresponding to (orig_var, lead_lag).
% If this is an exogenous variable, then it means we should put
% the value in oo_.exo_simul (we are probably in deterministic
% context).
k = strmatch(ov, M_.exo_names);
if isempty(k)
warning(['smoother2histval: output variable ' ov '(' lead_lag ') does not exist.'])
else
oo_.exo_simul((M_.maximum_lag-M_.maximum_endo_lag+1):M_.maximum_lag, k) = S.(ov_);
end
continue
end
end
M_.endo_histval(j, :) = S.(ov_);
exo_histval = [];
if M.exo_nbr
exo_histval = series{M.exo_names{:}}.data(k:end, :)';
end
exo_det_histval = [];
if M.exo_det_nbr
exo_det_histval = series{M.exo_names{:}}.data(k:end, :)';
end
function series = histvalf_initvalf(caller, M, options)
% function initvalf(M)
%
% handles options for histvalf_initvalf() and initvalf()
%
% INPUTS
% caller: string, name of calling function
% M: model structure
% options: options specific to initivalf
%
% OUTPUTS
% series: dseries containing selected data from a file or a dseries
%
% Copyright (C) 2003-2020 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 <http://www.gnu.org/licenses/>.
% dseries
if isfield(options, 'series')
series = options.series;
dseries_ispresent = true;
else
dseries_ispresent = false;
end
% file
datafile = '';
if isfield(options, 'filename')
warning([caller, '_FILE: option FILENAME is deprecated, please use', ...
' option DATAFILE'])
if dseries_ispresent
error([caller, '_FILE: you can''t use option FILENAME and option SERIES', ...
' at the same time'])
end
if isfield(options, 'datafile')
error([caller, '_FILE: you can''t use option DATAFILE and option FILENAME', ...
' at the same time'])
end
datafile = options.filename;
end
if isfield(options, 'datafile')
if dseries_ispresent
error([caller, '_FILE: you can''t use option DATAFILE and option SERIES', ...
' at the same time'])
end
datafile = options.datafile;
end
if datafile
[directory,basename,extension] = fileparts(datafile);
% Auto-detect extension if not provided
if isempty(extension)
if exist([basename '.m'],'file')
extension = '.m';
elseif exist([basename '.mat'],'file')
extension = '.mat';
elseif exist([basename '.xls'],'file')
extension = '.xls';
elseif exist([basename '.xlsx'],'file')
extension = '.xlsx';
else
error([caller, '_FILE: Can''t find datafile: ' basename '.{m,mat,xls,xlsx}']);
end
end
fullname = [basename extension];
series = dseries(fullname);
end
% checking that all variable are present
error_flag = false;
for i = 1:M.orig_endo_nbr
if ~series.exist(M.endo_names{i})
disp(sprintf('%s_FILE: endogenous variable %s is missing', ...
caller, M.endo_names{i}))
error_flag = true;
end
end
for i = 1:M.exo_nbr
if ~series.exist(M.exo_names{i})
disp(sprintf('%s_FILE: exogenous variable %s is missing', ...
caller, M.exo_names{i}))
error_flag = true;
end
end
for i = 1:M.exo_det_nbr
if ~series.exist(M.exo_det_names{i})
disp(sprintf('%s_FILE: exo_det variable %s is missing', ...
caller, M.exo_det_names{i}))
error_flag = true;
end
end
if error_flag
error([caller, '_FILE: some variables are missing'])
end
if exist(sprintf('+%s/dynamic_set_auxiliary_series', M.fname), 'file')
series = feval(sprintf('%s.dynamic_set_auxiliary_series', M.fname), series, M.params);
end
% selecting observations
if isfield(options, 'nobs')
nobs = options.nobs;
else
nobs = 0;
end
periods = series.dates;
nobs0 = series.nobs;
first_obs_ispresent = false;
last_obs_ispresent = false;
if isfield(options, 'first_obs')
i = options.first_obs;
if i < 1
error([caller, '_FILE: the first requested period is before available', ...
' data.'])
elseif i > nobs0
error([caller, '_FILE: the first requested period is after available', ...
' data.'])
end
first_obs = periods(i);
if nobs > 0
last_obs = first_obs + nobs - 1;
last_obs_ispresent = true;
end
first_obs_ispresent = true;
elseif isfield(options, 'firstobs')
first_obs = options.firstobs;
if nobs > 0
last_obs = first_obs + nobs - 1;
last_obs_ispresent = true;
end
first_obs_ispresent = true;
end
if last_obs_ispresent
if isfield(options, 'last_obs')
i = options.last_obs;
if i < 1
error([caller, '_FILE: the last requested period is before available', ...
' data.'])
elseif i > nobs0
error([caller, '_FILE: the last requested period is after available', ...
' data.'])
end
if last_obs ~= periods(i)
error([caller, '_FILE: FIST_OBS, LAST_OBS and NOBS contain', ...
' inconsistent information. Use only two of these', ...
' options.'])
end
elseif isfield(options, 'lastobs')
if last_obs ~= options.lastobs
error([caller, '_FILE: FIST_OBS, LAST_OBS and NOBS contain', ...
' inconsistent information. Use only two of these', ...
' options.'])
end
end
elseif isfield(options, 'last_obs')
i = options.last_obs;
if i < 1
error([caller, '_FILE: the last requested period is before available', ...
' data.'])
elseif i > nobs0
error([caller, '_FILE: the last requested period is after available', ...
' data.'])
end
last_obs = periods(i);
if nobs > 0
first_obs = last_obs - nobs + 1;
first_obs_ispresent = true;
end
last_obs_ispresent = true;
elseif isfield(options, 'lastobs')
last_obs = options.lastobs;
if nobs > 0
first_obs = last_obs - nobs + 1;
first_obs_ispresent = true;
end
last_obs_ispresent = true;
end
if ~first_obs_ispresent
first_obs = periods(1);
end
if ~last_obs_ispresent
if nobs > 0
last_obs = first_obs + nobs - 1;
else
last_obs = periods(end);
end
end
if first_obs < series.init
error([caller, '_FILE: the first requested period is before available', ...
' data.'])
elseif last_obs > series.last
error([caller, '_FILE: the last requested period is after available', ...
' data.'])
else
series = series(first_obs:last_obs);
end
function initvalf(fname_)
% function initvalf(fname_)
function series = initvalf(M, options)
% function initvalf(M)
%
% Reads an initial path from the 'fname_' file for exogenous and endogenous variables
% handles options for histvalf() and initvalf()
%
% INPUTS
% fname_: name of the function or file containing the data
% caller: string, name of calling function
% M: model structure
% options: options specific to initivalf
%
% OUTPUTS
% none
% series: dseries containing selected data from a file or a dseries
%
% SPECIAL REQUIREMENTS
% All variables local to this function have an underscore appended to
% their name, to minimize clashes with model variables loaded by this function.
% Copyright (C) 2003-2018 Dynare Team
% Copyright (C) 2003-2020 Dynare Team
%
% This file is part of Dynare.
%
......@@ -30,81 +29,6 @@ function initvalf(fname_)
% 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_ options_
series = histvalf_initvalf('INITVALF', M, options);
series_ = 1;
[directory,basename,extension] = fileparts(fname_);
% Auto-detect extension if not provided
if isempty(extension)
if exist([basename '.m'],'file')
extension = '.m';
elseif exist([basename '.mat'],'file')
extension = '.mat';
elseif exist([basename '.xls'],'file')
extension = '.xls';
elseif exist([basename '.xlsx'],'file')
extension = '.xlsx';
else
error(['Can''t find datafile: ' basename '.{m,mat,xls,xlsx}']);
end
end
fullname = [basename extension];
if ~exist(fullname)
error(['Can''t find datafile: ' fullname ]);
end
switch (extension)
case '.m'
eval(basename);
case '.mat'
load(basename);
case { '.xls', '.xlsx' }
[data_,names_v_]=xlsread(fullname); % Octave needs the extension explicitly
series_=0;
otherwise
error(['Unsupported extension for datafile: ' extension])
end
options_.initval_file = true;
oo_.endo_simul = [];
oo_.exo_simul = [];
for i_=1:length(M_.endo_names)
if series_ == 1
x_ = eval(M_.endo_names{i_});
if size(x_,2)>size(x_,1) %oo_.endo_simul must be collection of row vectors
oo_.endo_simul = [oo_.endo_simul; x_];
else %transpose if column vector
oo_.endo_simul = [oo_.endo_simul; x_'];
end
else
k_ = strmatch(M_.endo_names{i_}, names_v_, 'exact');
if isempty(k_)
error(['INITVAL_FILE: ' M_.endo_names{i_} ' not found'])
end
x_ = data_(:,k_);
oo_.endo_simul = [oo_.endo_simul; x_'];
end
end
for i_=1:length(M_.exo_names)
if series_ == 1
x_ = eval(M_.exo_names{i_});
if size(x_,2)>size(x_,1) %oo_.endo_simul must be collection of row vectors
oo_.exo_simul = [oo_.exo_simul x_'];
else %if column vector
oo_.exo_simul = [oo_.exo_simul x_];
end
else
k_ = strmatch(M_.exo_names{i_}, names_v_, 'exact');
if isempty(k_)
error(['INITVAL_FILE: ' M_.exo_names{i_} ' not found'])
end
x_ = data_(:,k_);
oo_.exo_simul = [oo_.exo_simul x_];
end
end
......@@ -41,17 +41,33 @@ if M_.exo_det_nbr > 1 && isempty(oo_.exo_det_steady_state)
end
% Initialize oo_.exo_simul
if isempty(M_.exo_histval)
if isempty(ex0_)
oo_.exo_simul = repmat(oo_.exo_steady_state',M_.maximum_lag+options_.periods+M_.maximum_lead,1);
if isempty(oo_.initval_series)
if isempty(M_.exo_histval)
if isempty(ex0_)
oo_.exo_simul = repmat(oo_.exo_steady_state',M_.maximum_lag+options_.periods+M_.maximum_lead,1);
else
oo_.exo_simul = [ repmat(ex0_',M_.maximum_lag,1) ; repmat(oo_.exo_steady_state',options_.periods+M_.maximum_lead,1) ];
end
else
oo_.exo_simul = [ repmat(ex0_',M_.maximum_lag,1) ; repmat(oo_.exo_steady_state',options_.periods+M_.maximum_lead,1) ];
if isempty(ex0_)
oo_.exo_simul = [M_.exo_histval'; repmat(oo_.exo_steady_state',options_.periods+M_.maximum_lead,1)];
else
error('histval and endval cannot be used simultaneously')
end
end
else
if isempty(ex0_)
oo_.exo_simul = [M_.exo_histval'; repmat(oo_.exo_steady_state',options_.periods+M_.maximum_lead,1)];
else
error('histval and endval cannot be used simultaneously')
elseif M_.exo_nbr > 0
x = oo_.initval_series{M_.exo_names{:}}.data;
oo_.exo_simul = x(1:M_.maximum_lag + options_.periods + M_.maximum_lead,:);
if ~isempty(M_.exo_histval)
oo_.exo_simul(1:M_.maximum_lag, :) ...
= M_.exo_histval(:, 1:M_.maximum_lag)';
end
elseif M_.exo_det_nbr > 0
x_det = oo_.initval_series{M_.exo_det_names{:}}.data;
oo_.exo_det_simul = x_det(1:M_.maximum_lag + options_.periods + M_.maximum_lead,:);
if ~isempty(M_.exo_det_histval)
oo_.exo_det_simul(1:M_.maximum_lag, :) ...
= M_.exo_det_histval(:, 1:M_.maximum_lag)';
end
end
......
......@@ -45,18 +45,31 @@ if isempty(oo_.steady_state)
oo_.steady_state = zeros(M_.endo_nbr,1);
end
if isempty(M_.endo_histval)
if isempty(ys0_)
oo_.endo_simul = repmat(oo_.steady_state, 1, M_.maximum_lag+options_.periods+M_.maximum_lead);
if isempty(oo_.initval_series)
if isempty(M_.endo_histval)
if isempty(ys0_)
oo_.endo_simul = repmat(oo_.steady_state, 1, M_.maximum_lag+options_.periods+M_.maximum_lead);
else
oo_.endo_simul = [repmat(ys0_, 1, M_.maximum_lag) repmat(oo_.steady_state, 1,options_.periods+M_.maximum_lead)];
end
else
oo_.endo_simul = [repmat(ys0_, 1, M_.maximum_lag) repmat(oo_.steady_state, 1,options_.periods+M_.maximum_lead)];
if ~isempty(ys0_)
error('histval and endval cannot be used simultaneously')
end
% the first NaNs take care of the case where there are lags > 1 on
% exogenous variables
oo_.endo_simul = [M_.endo_histval ...
repmat(oo_.steady_state, 1, options_.periods+M_.maximum_lead)];
end
else
if ~isempty(ys0_)
error('histval and endval cannot be used simultaneously')
y = oo_.initval_series{M_.endo_names{:}}.data;
oo_.endo_simul = y(1:M_.maximum_lag + options_.periods + ...
M_.maximum_lead, :)';
if ~isempty(M_.endo_histval)
if ~isempty(ys0_)
error('histval and endval cannot be used simultaneously')
end
oo_.endo_simul(:,1:M_.maximum_lag) ...
= M_.endo_histval(:, 1:M_.maximum_lag);
end
% the first NaNs take care of the case where there are lags > 1 on
% exogenous variables
oo_.endo_simul = [M_.endo_histval ...
repmat(oo_.steady_state, 1, options_.periods+M_.maximum_lead)];
end
end
\ No newline at end of file
......@@ -64,7 +64,6 @@ if ~isempty(M_.det_shocks) && options_.periods<max([M_.det_shocks.periods])
error('PERFECT_FORESIGHT_SETUP: Please check the declaration of the shocks or increase the value of the periods option.')
end
if ~options_.initval_file
oo_ = make_ex_(M_,options_,oo_);
oo_ = make_y_(M_,options_,oo_);
end
oo_ = make_ex_(M_,options_,oo_);
oo_ = make_y_(M_,options_,oo_);
......@@ -119,7 +119,9 @@ if options.endogenous_terminal_period
end
if stop
if any(any(isnan(endogenousvariables))) || any(any(isinf(endogenousvariables)))
% initial or terminal observations may contain
% harmless NaN or Inf. We test only values computed above
if any(any(isnan(y))) || any(any(isinf(y)))
info.status = false;% NaN or Inf occurred
info.error = err;
info.iterations = iter;
......
......@@ -163,13 +163,15 @@ end
% Initialize outputs
if ~isfield(opts, 'outfile')
% Output to M_.endo_histval
M_.endo_histval = repmat(oo_.steady_state, 1, M_.maximum_endo_lag);
M_.endo_histval = repmat(oo_.steady_state, 1, M_.maximum_lag);
else
% Output to a file
o = struct();
o = dseries();
end
% Handle all endogenous variables to be copied
data = zeros(M_.orig_maximum_endo_lag, length(invars));
k = M_.orig_maximum_endo_lag - M_.maximum_endo_lag + 1: M_.orig_maximum_lag
for i = 1:length(invars)
if isempty(strmatch(invars{i}, M_.endo_names))
% Skip exogenous
......@@ -177,61 +179,68 @@ for i = 1:length(invars)
end
s = smoothedvars.(invars{i});
j = strmatch(invars{i}, M_.endo_names, 'exact');
v = s((period-M_.maximum_endo_lag+1):period);% + steady_state(j);
v = s((period-M_.orig_maximum_endo_lag+1):period);% + steady_state(j);
if ~isfield(opts, 'outfile')
j = strmatch(outvars{i}, M_.endo_names, 'exact');
if isempty(j)
error(['smoother2histval: output variable ' outvars{i} ' does not exist.'])
else
M_.endo_histval(j, :) = v;
M_.endo_histval(j, :) = v(k);
end
else
% When saving to a file, x(-1) is in the variable called "x_"
o.([ outvars{i} '_' ]) = v;
data(:, i) = v';
end
end
% Handle auxiliary variables for lags (both on endogenous and exogenous)
for i = 1:length(M_.aux_vars)
if ~ ismember(M_.endo_names{M_.aux_vars(i).endo_index},invars)
if M_.aux_vars(i).type ~= 1 && M_.aux_vars(i).type ~= 3
continue
end
if M_.aux_vars(i).type == 1
% Endogenous
orig_var = M_.endo_names{M_.aux_vars(i).orig_index};
else
% Exogenous
orig_var = M_.exo_names{M_.aux_vars(i).orig_index};
end
[m, k] = ismember(orig_var, outvars);
if m
if ~isempty(strmatch(invars{k}, M_.endo_names))
s = smoothedvars.(invars{k});
else
s = smoothedshocks.(invars{k});
end
l = M_.aux_vars(i).orig_lead_lag;
if period-M_.maximum_endo_lag+1+l < 1
error('The period that you indicated is too small to construct initial conditions')
end
j = M_.aux_vars(i).endo_index;
v = s((period-M_.maximum_endo_lag+1+l):(period+l)); %+steady_state(j);
if ~isfield(opts, 'outfile')
M_.endo_histval(j, :) = v;
else
% When saving to a file, x(-2) is in the variable called "x_l2"
lead_lag = num2str(l);
lead_lag = regexprep(lead_lag, '-', 'l');
o.([ orig_var '_' lead_lag ]) = v;
end
end
end
if isfield(opts, 'outfile')
o = dseries(data, '1Y', invars);
end
% $$$ % Handle auxiliary variables for lags (both on endogenous and exogenous)
% $$$ for i = 1:length(M_.aux_vars)
% $$$ if ~ ismember(M_.endo_names{M_.aux_vars(i).endo_index},invars)
% $$$ if M_.aux_vars(i).type ~= 1 && M_.aux_vars(i).type ~= 3
% $$$ continue
% $$$ end
% $$$ if M_.aux_vars(i).type == 1
% $$$ % Endogenous
% $$$ orig_var = M_.endo_names{M_.aux_vars(i).orig_index};
% $$$ else
% $$$ % Exogenous