function M_ = update_parameters(varexpectationmodelname, M_, oo_) % function M_ = update_parameters(varexpectationmodelname, M_, oo_) % Updates the VAR expectation reduced form parameters. % % INPUTS % - varexpectationmodelname [string] Name of the pac equation. % - M_ [struct] global structure (model properties) % - oo_ [struct] oo_ global structure (model results) % % OUTPUTS % - M_ [struct] M_ global structure (with updated params field) % % SPECIAL REQUIREMENTS % none % Copyright © 2018-2023 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 . % Check that the first input is a row character array. if ~isrow(varexpectationmodelname)==1 || ~ischar(varexpectationmodelname) error('First input argument must be a row character array!') end % Check that the model exists. if ~isfield(M_.var_expectation, varexpectationmodelname) error('VAR_EXPECTATION_MODEL %s is not defined!', varexpectationmodelname) end % Get the VAR model description varexpectationmodel = M_.var_expectation.(varexpectationmodelname); % Get the name of the associated VAR model and test its existence. if ~isfield(M_.(varexpectationmodel.auxiliary_model_type), varexpectationmodel.auxiliary_model_name) error('Unknown VAR (%s) in VAR_EXPECTATION_MODEL (%s)!', varexpectationmodel.auxiliary_model_name, varexpectationmodelname) end auxmodel = M_.(varexpectationmodel.auxiliary_model_type).(varexpectationmodel.auxiliary_model_name); % Check that we have the values of the VAR matrices. if ~isfield(oo_.(varexpectationmodel.auxiliary_model_type), varexpectationmodel.auxiliary_model_name) error('Auxiliary model %s has to be estimated or calibrated first!', varexpectationmodel.auxiliary_model_name) end auxcalib = oo_.(varexpectationmodel.auxiliary_model_type).(varexpectationmodel.auxiliary_model_name); if ~isfield(auxcalib, 'CompanionMatrix') || any(isnan(auxcalib.CompanionMatrix(:))) message = sprintf('Auxiliary model %s has to be estimated first.', varexpectationmodel.auxiliary_model_name); message = sprintf('%s\nPlease use *get_companion_matrix command first.', message); error(message); end % Set discount factor if isfield(varexpectationmodel, 'discount_value') discountfactor = varexpectationmodel.discount_value; else if isfield(varexpectationmodel, 'discount_index') discountfactor = M_.params(varexpectationmodel.discount_index); else error('This is most likely a bug. Pleasse conntact the Dynare Team.') end end % A discount factor has to be positive. if discountfactor<=0 error('The discount factor must be positive.') end % A discount factor cannot be greater than one. if discountfactor>1 error('The discount cannot be greater than one.') end % Set timeshift if isfield(varexpectationmodel, 'time_shift') timeshift = varexpectationmodel.time_shift; else timeshift = 0; end % Throw an error if timeshift is positive if timeshift>0 error('Option time_shift of the var_expectation command cannot be positive.') end % Set variables_id in VAR model m = length(varexpectationmodel.expr.vars); variables_id_in_var = NaN(m,1); for i = 1:m j = find(strcmp(auxmodel.list_of_variables_in_companion_var, M_.endo_names{varexpectationmodel.expr.vars(i)})); if isempty(j) error('Cannot find variable %s in the companion VAR', M_.endo_names{varexpectationmodel.expr.vars(i)}) else variables_id_in_var(i) = find(strcmp(auxmodel.list_of_variables_in_companion_var, M_.endo_names{varexpectationmodel.expr.vars(i)})); end end if isfield(auxmodel, 'isconstant') && auxmodel.isconstant variables_id_in_var = variables_id_in_var+1; end % Get the horizon parameter. horizon = varexpectationmodel.horizon; % Check the horizon parameter wrong_horizon_parameter = true; if length(horizon)==1 if isnumeric(horizon) if isfinite(horizon) if isint(horizon) if horizon>0 wrong_horizon_parameter = false; end end end end elseif length(horizon)==2 if isnumeric(horizon) if isfinite(horizon(1)) if isint(horizon(1)) if horizon(1)>=0 if isinf(horizon(2)) || (isint(horizon(2)) && horizon(2)>horizon(1)) wrong_horizon_parameter = false; end end end end end end if wrong_horizon_parameter error('horizon must be an integer scalar or an integer vector with two elements.') end % Get the companion matrix CompanionMatrix = auxcalib.CompanionMatrix; % Get the dimension of the problem. n = length(CompanionMatrix); % Set the selection vector alpha = zeros(1, n); alpha(variables_id_in_var) = varexpectationmodel.expr.constants; params_id_in_var = ~isnan(varexpectationmodel.expr.params); alpha(variables_id_in_var(params_id_in_var)) = varexpectationmodel.expr.params(params_id_in_var); if length(horizon)==1 % Compute the reduced form parameters of the (discounted) forecast in period t+horizon(1) if varexpectationmodel.horizon==1 parameters = discountfactor*(alpha*CompanionMatrix); elseif horizon>1 parameters = alpha*mpower(discountfactor*CompanionMatrix, varexpectationmodel.horizon); end if timeshift<0 parameters = parameters*mpower(CompanionMatrix, -timeshift); end else % Compute the reduced form parameters of the discounted sum of forecasts between t+horizon(1) and % t+horizon(2). Not that horzizon(2) need not be finite. if horizon(1)==0 && isinf(horizon(2)) parameters = alpha/(eye(n)-discountfactor*CompanionMatrix); if timeshift<0 parameters = parameters*mpower(CompanionMatrix, -timeshift); end elseif horizon(1)>0 && isinf(horizon(2)) % Define the discounted companion matrix DiscountedCompanionMatrix = discountfactor*CompanionMatrix; % First compute the parameters implied by the discounted sum from h=0 to h=horizon(1)-1 tmp1 = zeros(n); for h=0:horizon(1)-1 tmp1 = tmp1 + mpower(DiscountedCompanionMatrix, h); end tmp1 = alpha*tmp1; if timeshift<0 tmp1 = tmp1*mpower(CompanionMatrix, -timeshift); end % Second compute the parameters implied by the discounted sum from h=0 to h=Inf tmp2 = alpha/(eye(n)-DiscountedCompanionMatrix); if timeshift<0 tmp2 = tmp2*mpower(CompanionMatrix, -timeshift); end % Finally parameters = tmp2-tmp1; elseif isfinite(horizon(2)) % Define the discounted companion matrix DiscountedCompanionMatrix = discountfactor*CompanionMatrix; tmp = zeros(n); for h=horizon(1):horizon(2) tmp = tmp + mpower(DiscountedCompanionMatrix, h); end parameters = alpha*tmp; if timeshift<0 parameters = parameters*mpower(CompanionMatrix, -timeshift); end end end % Update reduced form parameters in M_.params. if isequal(varexpectationmodel.auxiliary_model_type, 'var') if M_.var.(varexpectationmodel.auxiliary_model_name).isconstant M_.params(varexpectationmodel.param_indices) = parameters; else M_.params(varexpectationmodel.param_indices(1)) = .0; M_.params(varexpectationmodel.param_indices(2:end)) = parameters; end else M_.params(varexpectationmodel.param_indices) = parameters; end