Occbin: the +<basename>/occbin_difference.m file is now generated by the preprocessor

Some fields have also changed under M_.occbin.

Ref. #569
var-model-with-constant
Sébastien Villemot 2021-07-20 12:35:15 +02:00
parent d5c35e3664
commit 229282a1c4
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
19 changed files with 47 additions and 369 deletions

View File

@ -46,10 +46,8 @@ Files: matlab/+occbin/make_chart.m
matlab/+occbin/mkdata.m
matlab/+occbin/mkdatap_anticipated_2constraints_dyn.m
matlab/+occbin/mkdatap_anticipated_dyn.m
matlab/+occbin/process_constraint.m
matlab/+occbin/solve_one_constraint.m
matlab/+occbin/solve_two_constraints.m
matlab/+occbin/tokenize.m
Copyright: none
License: public-domain-occbin
Original authors: Luca Guerrieri and Matteo Iacoviello

View File

@ -108,12 +108,10 @@ opts_simul.periods = options_.occbin.smoother.periods;
opts_simul.check_ahead_periods = options_.occbin.smoother.check_ahead_periods;
opts_simul.full_output = options_.occbin.smoother.full_output;
opts_simul.piecewise_only = options_.occbin.smoother.piecewise_only;
constraints = M_.occbin.constraint;
% init_mode = options_.occbin.smoother.init_mode; % 0 = standard; 1 = unconditional frcsts zero shocks+smoothed states in each period
% init_mode = 0;
occbin_options = struct();
occbin_options.constraints = constraints;
occbin_options.first_period_occbin_update = options_.occbin.smoother.first_period_occbin_update;
occbin_options.opts_regime = opts_simul; % this builds the opts_simul options field needed by occbin.solver
occbin_options.opts_regime.binding_indicator = options_.occbin.likelihood.init_binding_indicator;
@ -207,7 +205,7 @@ while is_changed && maxiter>iter && ~is_periodic
opts_regime.regime_history = regime_history;
[TT, RR, CC, regime_history] = occbin.check_regimes(TT, RR, CC, opts_regime, M_, oo_, options_);
is_changed = ~isequal(regime_history0(iter,:),regime_history);
if length(constraints)==2
if M_.occbin.constraint_nbr==2
for k=1:size(regime_history0,2)
isdiff_regime(k,1) = ~isequal(regime_history0(end,k).regime1,regime_history(k).regime1);
isdiff_start(k,1) = ~isequal(regime_history0(end,k).regimestart1,regime_history(k).regimestart1);
@ -257,7 +255,7 @@ while is_changed && maxiter>iter && ~is_periodic
regime_new = regime_;
start_ = regime_;
start_new = regime_;
if length(constraints)==2
if M_.occbin.constraint_nbr==2
indx_init_1 = find(isdiff_(:,1));
if ~isempty(indx_init_1)
qq={regime_history0(end,indx_init_1).regime1}';

View File

@ -40,9 +40,8 @@ gend = size(binding_indicator,1);
if gend ==0
gend = length(regime_history)+1;
end
number_of_constraints = length(M_.occbin.constraint);
if number_of_constraints==1
if M_.occbin.constraint_nbr==1
base_regime.regime = 0;
base_regime.regimestart = 1;
else
@ -71,7 +70,7 @@ opts_simul.piecewise_only=1;
for tp=1:gend-1
change_it = 0;
if ~isempty(binding_indicator)
if number_of_constraints==1
if M_.occbin.constraint_nbr==1
if regime_history(tp).regime(1) > binding_indicator(tp+1,1)
regime_history(tp).regime = [0 regime_history(tp).regime];
regime_history(tp).regimestart = [1 regime_history(tp).regimestart+1];
@ -123,7 +122,7 @@ for tp=1:gend-1
RR(:,:,tp+1) = RR(:,:,jt);
CC(:,tp+1) = CC(:,jt);
else
if number_of_constraints==1
if M_.occbin.constraint_nbr==1
nperi = max(regime_history(tp).regimestart);
else
nperi = max([regime_history(tp).regimestart1 regime_history(tp).regimestart2]);

View File

@ -1,57 +0,0 @@
function M_ = get_info(M_)
%function M_ = get_info(M_)
% Parses constraint to clean spaces and provide information on endogenous variables
% involved in constraints
%
% INPUTS
% - M_ [struct] Definition of the model.
%
% OUTPUTS
% - M_ [struct] Definition of the model.
% Copyright (C) 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/>.
delimiters = char(',',';','(',')','+','-','^','*','/','>','<','=');
iwish=0;
indx_=[];
wish_list='';
M_.occbin.constraint_nbr=length(M_.occbin.constraint);
for k=1:M_.occbin.constraint_nbr
%get rid of redundant spaces;
M_.occbin.constraint(k).bind=strrep(M_.occbin.constraint(k).bind,' ','');
M_.occbin.constraint(k).relax=strrep(M_.occbin.constraint(k).relax,' ','');
bind_clean = occbin.tokenize(M_.occbin.constraint(k).bind,delimiters);
relax_clean = occbin.tokenize(M_.occbin.constraint(k).relax,delimiters);
for j=1:M_.endo_nbr
tmp=ismember(M_.endo_names{j},bind_clean);
tmp1=ismember(M_.endo_names{j},relax_clean);
if tmp || tmp1
iwish = iwish+1;
indx_(iwish)=j;
if iwish>1
wish_list = char(wish_list,M_.endo_names{j});
else
wish_list = M_.endo_names{j};
end
end
end
end
M_.occbin.wish_list.endo = wish_list;
M_.occbin.wish_list.iendo = indx_;
end

View File

@ -1,75 +0,0 @@
function [M_, oo_, options_] = initialize(M_,oo_,options_)
% function [M_, oo_, options_] = initialize(M_,oo_,options_)
% Initializes run of Occbin: sets default options, parses constraints, creates
% eval_difference-file
%
% INPUT:
% - M_ [structure] Matlab's structure describing the model
% - oo_ [structure] Matlab's structure containing the results
% - options_ [structure] Matlab's structure containing the options
%
% OUTPUT:
% - M_ [structure] Matlab's structure describing the model
% - oo_ [structure] Matlab's structure containing the results
% - options_ [structure] Matlab's structure containing the options
% Copyright (C) 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/>.
options_.occbin = struct();
options_.occbin = occbin.set_default_options(options_.occbin, M_);
oo_.dr=set_state_space(oo_.dr,M_,options_);
M_ = occbin.get_info(M_);
if M_.occbin.constraint_nbr>2
error('Occbin: Only up to two constraints are supported')
end
for k=1:M_.occbin.constraint_nbr
M_.occbin.constraint(k).bind_difference = occbin.process_constraint(M_.occbin.constraint(k).bind,'_difference',M_.endo_names,false,M_.param_names);
M_.occbin.constraint(k).bind_error = occbin.process_error_constraint(M_.occbin.constraint(k).bind_difference);
if isempty(M_.occbin.constraint(k).relax)
M_.occbin.constraint(k).relax_difference = ['~binding.constraint_',int2str(k)];
else
M_.occbin.constraint(k).relax_difference = occbin.process_constraint(M_.occbin.constraint(k).relax,'_difference',M_.endo_names,false,M_.param_names);
end
M_.occbin.constraint(k).relax_error = occbin.process_error_constraint(M_.occbin.constraint(k).relax_difference);
M_.occbin.constraint(k).pswitch_index = strmatch(M_.occbin.constraint(k).pswitch,M_.param_names);
end
nwishes_ = size(M_.occbin.wish_list.endo,1);
fid = fopen(['+' M_.fname '/eval_difference.m'],'w+');
fprintf(fid,'function [binding, relax, err]=eval_difference(zdatalinear_,M_,ys);\n');
for i_indx_=1:nwishes_
fprintf(fid,'%s_difference=zdatalinear_(:,%i);\r\n',deblank(M_.occbin.wish_list.endo(i_indx_,:)),M_.occbin.wish_list.iendo(i_indx_));
end
for k=1:M_.occbin.constraint_nbr
fprintf(fid,'binding.constraint_%i = %s;\r\n',k,M_.occbin.constraint(k).bind_difference);
fprintf(fid,'relax.constraint_%i = %s;\r\n',k,M_.occbin.constraint(k).relax_difference);
% fprintf(fid,'try\r\n');
fprintf(fid,' err.binding_constraint_%i = abs(%s);\r\n',k,M_.occbin.constraint(k).bind_error);
fprintf(fid,' err.relax_constraint_%i = abs(%s);\r\n',k,M_.occbin.constraint(k).relax_error);
% fprintf(fid,'catch\r\n');
%
% fprintf(fid,' err.newviolvecbool_%i = nan(size(err.newviolvecbool_%i));\r\n',k,k);
% fprintf(fid,' err.relaxconstraint_%i = nan(size(err.relaxconstraint_%i));\r\n',k,k);
% fprintf(fid,'end\r\n');
end
fclose(fid);

View File

@ -66,9 +66,8 @@ sto.a1=a1;
sto.P=P;
sto.P1=P1;
number_constr = length(M_.occbin.constraint);
base_regime = struct();
if number_constr==1
if M_.occbin.constraint_nbr==1
base_regime.regime = 0;
base_regime.regimestart = 1;
else
@ -125,14 +124,14 @@ options_.occbin.simul=opts_simul;
[~, out, ss] = occbin.solver(M_,oo_,options_);
regimes_ = out.regime_history;
if number_constr==1
if M_.occbin.constraint_nbr==1
myregime = [regimes_.regime];
else
myregime = [regimes_.regime1 regimes_.regime2];
end
etahat_hist = {etahat};
regime_hist = {regimes0(1)};
if number_constr==1
if M_.occbin.constraint_nbr==1
regime_end = regimes0(1).regimestart(end);
end
lik_hist=lik;
@ -149,14 +148,14 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
while ~isequal(regimes_(1),regimes0(1)) && ~is_periodic && ~out.error_flag && niter<=options_.occbin.likelihood.max_number_of_iterations
niter=niter+1;
oldstart=1;
if number_constr==1 && length(regimes0(1).regimestart)>1
if M_.occbin.constraint_nbr==1 && length(regimes0(1).regimestart)>1
oldstart = regimes0(1).regimestart(end);
end
newstart=1;
if number_constr==1 && length(regimes_(1).regimestart)>1
if M_.occbin.constraint_nbr==1 && length(regimes_(1).regimestart)>1
newstart = regimes_(1).regimestart(end);
end
if number_constr==1 && (newstart-oldstart)>2 && options_.occbin.filter.use_relaxation
if M_.occbin.constraint_nbr==1 && (newstart-oldstart)>2 && options_.occbin.filter.use_relaxation
regimestart = max(oldstart+2,round(0.5*(newstart+oldstart)));
regimestart = min(regimestart,oldstart+4);
if regimestart<=regimes_(1).regimestart(end-1)
@ -181,7 +180,7 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
end
newguess=0;
regime_hist(niter) = {regimes_(1)};
if number_constr==1
if M_.occbin.constraint_nbr==1
regime_end(niter) = regimes_(1).regimestart(end);
end
[a, a1, P, P1, v, alphahat, etahat, lik] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood);
@ -196,7 +195,7 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
opts_simul.endo_init = alphahat(oo_.dr.inv_order_var,1);
end
% opts_simul.init_regime=regimes_(1);
if number_constr==1
if M_.occbin.constraint_nbr==1
myregimestart = [regimes_.regimestart];
else
myregimestart = [regimes_.regimestart1 regimes_.regimestart2];
@ -212,7 +211,7 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
end
is_periodic = any(is_periodic);
if is_periodic
if nguess<3 && number_constr==1
if nguess<3 && M_.occbin.constraint_nbr==1
newguess=1;
is_periodic=0;
nguess=nguess+1;
@ -240,7 +239,7 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
regimes_ = regimes0;
% force projection conditional on previous regime
opts_simul.init_regime=regimes0(1);
if number_constr==1
if M_.occbin.constraint_nbr==1
myregimestart = [regimes0.regimestart];
else
myregimestart = [regimes0.regimestart1 regimes0.regimestart2];
@ -258,7 +257,7 @@ end
error_flag = out.error_flag;
if ~error_flag && niter>options_.occbin.likelihood.max_number_of_iterations && ~isequal(regimes_(1),regimes0(1))
error_flag = 1;
if number_constr==1 % try some other regime
if M_.occbin.constraint_nbr==1 % try some other regime
[ll, il]=sort(lik_hist);
[ll, il]=sort(regime_end);
rr=regime_hist(il(2:3));
@ -294,7 +293,7 @@ if ~error_flag && niter>options_.occbin.likelihood.max_number_of_iterations && ~
opts_simul.endo_init = alphahat(oo_.dr.inv_order_var,1);
end
% opts_simul.init_regime=regimes_(1);
if number_constr==1
if M_.occbin.constraint_nbr==1
myregimestart = [regimes_.regimestart];
else
myregimestart = [regimes_.regimestart1 regimes_.regimestart2];

View File

@ -74,9 +74,8 @@ if isempty(nk)
end
nk=max(nk,1);
number_constr = length(M_.occbin.constraint);
opts_simul = occbin_options.opts_regime;base_regime = struct();
if number_constr==1
if M_.occbin.constraint_nbr==1
base_regime.regime = 0;
base_regime.regimestart = 1;
else
@ -124,13 +123,13 @@ options_.occbin.simul=opts_simul;
[~, out, ss] = occbin.solver(M_,oo_,options_);
regimes_ = out.regime_history;
if number_constr==1
if M_.occbin.constraint_nbr==1
myregime = [regimes_.regime];
else
myregime = [regimes_.regime1 regimes_.regime2];
end
regime_hist = {regimes0};
if number_constr==1
if M_.occbin.constraint_nbr==1
regime_end = regimes0(1).regimestart(end);
end
niter=1;
@ -146,14 +145,14 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
while ~isequal(regimes_(1),regimes0(1)) && ~is_periodic && ~out.error_flag && niter<=options_.occbin.likelihood.max_number_of_iterations
niter=niter+1;
newstart=1;
if number_constr==1 && length(regimes_(1).regimestart)>1
if M_.occbin.constraint_nbr==1 && length(regimes_(1).regimestart)>1
newstart = regimes_(1).regimestart(end);
end
oldstart=1;
if number_constr==1 && length(regimes0(1).regimestart)>1
if M_.occbin.constraint_nbr==1 && length(regimes0(1).regimestart)>1
oldstart = regimes0(1).regimestart(end);
end
if number_constr==1 && (newstart-oldstart)>2 && options_.occbin.filter.use_relaxation
if M_.occbin.constraint_nbr==1 && (newstart-oldstart)>2 && options_.occbin.filter.use_relaxation
regimestart = max(oldstart+2,round(0.5*(newstart+oldstart)));
regimestart = min(regimestart,oldstart+4);
if regimestart<=regimes_(1).regimestart(end-1)
@ -182,7 +181,7 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
end
newguess=0;
regime_hist(niter) = {regimes_};
if number_constr==1
if M_.occbin.constraint_nbr==1
regime_end(niter) = regimes_(1).regimestart(end);
end
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
@ -201,7 +200,7 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
end
% end
% opts_simul.init_regime=regimes_(1); %% why don't we use this ???
if number_constr==1
if M_.occbin.constraint_nbr==1
myregimestart = [regimes_.regimestart];
else
myregimestart = [regimes_.regimestart1 regimes_.regimestart2];
@ -217,7 +216,7 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
end
is_periodic = any(is_periodic);
if is_periodic
if nguess<3 && number_constr==1
if nguess<3 && M_.occbin.constraint_nbr==1
newguess=1;
is_periodic=0;
nguess=nguess+1;
@ -245,7 +244,7 @@ if any(myregime) || ~isequal(regimes_(1),regimes0(1))
regimes_ = regimes0;
% force projection conditional on previous regime
opts_simul.init_regime=regimes0(1);
if number_constr==1
if M_.occbin.constraint_nbr==1
myregimestart = [regimes0.regimestart];
else
myregimestart = [regimes0.regimestart1 regimes0.regimestart2];
@ -264,7 +263,7 @@ error_flag = out.error_flag;
if error_flag==0 && niter>options_.occbin.likelihood.max_number_of_iterations && ~isequal(regimes_(1),regimes0(1)) %fixed point algorithm did not converge
error_flag = 1;
if number_constr==1
if M_.occbin.constraint_nbr==1
% try some other regime before giving up
[ll, il]=sort(regime_end);
rr=regime_hist(il(2:3));
@ -290,7 +289,7 @@ if error_flag==0 && niter>options_.occbin.likelihood.max_number_of_iterations &&
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
opts_simul.SHOCKS(1,:) = etahat(:,2)';
opts_simul.endo_init = alphahat(oo_.dr.inv_order_var,1);
if number_constr==1
if M_.occbin.constraint_nbr==1
myregimestart = [regimes_.regimestart];
else
myregimestart = [regimes_.regimestart1 regimes_.regimestart2];
@ -389,4 +388,4 @@ while t > 1
ri = T'*ri; % KD (2003), eq. (23), equation for r_{t-1,p_{t-1}}
end
end
end

View File

@ -1,81 +0,0 @@
function constraint_parsed = process_constraint(constraint,suffix,endo_names,invert_switch,param_names)
%function constraint_parsed = process_constraint(constraint,suffix,endo_names,invert_switch,param_names)
% Processes constraints for use in Occbin, appending endogenous variables
% with suffix and replacing parameters by their value in M_.params
%
% INPUTS
% - constraint [char] constraint to be parsed
% - suffix [char] suffix to be appended
% - endo_names [cell] names of endogenous variables
% - invert_switch [bool] if true, invert direction of the inequality constraint
% - param_names [cell] names of parameters
%
% OUTPUTS
% - constraint_parsed [char] parsed constraint
% Original authors: Luca Guerrieri and Matteo Iacoviello
% Original file downloaded from:
% https://www.matteoiacoviello.com/research_files/occbin_20140630.zip
% Adapted for Dynare by Dynare Team.
%
% This code is in the public domain and may be used freely.
% However the authors would appreciate acknowledgement of the source by
% citation of any of the following papers:
%
% Luca Guerrieri and Matteo Iacoviello (2015): "OccBin: A toolkit for solving
% dynamic models with occasionally binding constraints easily"
% Journal of Monetary Economics 70, 22-38
% create a list of delimiters that can separate parameters and endogenoous
% variables in the string that expresses the constraint
delimiters = char(',',';','(',')','+','-','^','*','/','>','<','=');
% split the string that holds the constraint into tokens
tokens = occbin.tokenize(constraint,delimiters);
ntokens = length(tokens);
endo_ss=strcat(endo_names,repmat('_ss',length(endo_names),1));
% search for tokens that match the list of endogenous variables
for i=1:ntokens
valid_token=0;
if ~isempty(find(strcmp(tokens(i),delimiters)))
% if the invert_switch is true
% reverse the direction of the inequality
if invert_switch
if strcmp(tokens(i),cellstr('>'))
tokens(i) = cellstr('<');
elseif strcmp(tokens(i),cellstr('<'))
tokens(i) = cellstr('>');
end
end
valid_token=1;
continue;
end
if ~isempty(find(strcmp(tokens(i),endo_names)))
% when there is a match with an endogenous variable append the suffix
tokens(i) = cellstr([char(tokens(i)),suffix]);
valid_token=1;
continue;
end
par_index=find(strcmp(tokens(i),param_names));
if ~isempty(par_index)
tokens(i) = {['M_.params(',num2str(par_index),')']};
valid_token=1;
continue;
end
ss_index=find(strcmp(tokens(i),endo_ss));
if ~isempty(ss_index)
tokens(i) = {['ys(',num2str(ss_index),')']};
valid_token=1;
continue;
end
if isnan(str2double(tokens(i)))
error('Occbin: Constraint %s contains the uninterpretable token %s', constraint, tokens{i});
end
end
% reassemble the tokens to create a string that expresses the constraint
constraint_parsed = regexprep(strjoin(tokens),' ','');

View File

@ -1,35 +0,0 @@
function error_parsed = process_error_constraint(constraint)
% function constraint1 = process_error_constraint(constraint)
% Constructs a string with the constraint error, i.e. by how much it is violated
% INPUTS
% - constraint [char] constraint to be parsed
%
% OUTPUTS
% - error_parsed [char] parsed constraint
% Copyright (C) 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/>.
error_parsed = constraint;
error_parsed=regexprep(error_parsed,'=','');
num = length(regexp(error_parsed,'>'))+length(regexp(error_parsed,'<'));
error_parsed=regexprep(error_parsed,'>','-(');
error_parsed=regexprep(error_parsed,'<','-(');
for k=1:num
error_parsed=[error_parsed ')'];
end

View File

@ -76,7 +76,7 @@ if solve_DM
[DM.Cbarmat, DM.Bbarmat, DM.Abarmat, DM.Jbarmat] = occbin.get_deriv(M_base,data.ys);
Mstar_= M_base;
Mstar_.params(M_.occbin.constraint(1).pswitch_index)= 1;
Mstar_.params(M_.occbin.pswitch(1))= 1;
[DM.Cstarbarmat, DM.Bstarbarmat, DM.Astarbarmat, DM.Jstarbarmat, DM.Dstarbarmat] = occbin.get_deriv(Mstar_,data.ys);
[DM.decrulea,DM.decruleb]=occbin.get_pq(dr_base);
@ -167,7 +167,7 @@ for shock_period = 1:n_shocks_periods
regime_start(end)-1,binding_indicator,...
data.exo_pos,data.shocks_sequence(shock_period,:),endo_init,update_flag);
[binding, relax, err]=feval([M_.fname,'.eval_difference'],zdatalinear_,M_,dr_base.ys);
[binding, relax, err]=feval([M_.fname,'.occbin_difference'],zdatalinear_,M_.params,dr_base.ys);
% check if changes to the hypothesis of the duration for each
% regime
@ -294,4 +294,4 @@ end
if opts_simul_.waitbar
dyn_waitbar_close(hh);
end
end

View File

@ -70,16 +70,16 @@ if solve_DM %recompute solution matrices
[DM.Cbarmat ,DM.Bbarmat, DM.Abarmat, DM.Jbarmat] = occbin.get_deriv(M00_,data.ys);
M10_ = M00_;
M10_.params(strmatch(M_.occbin.constraint(1).pswitch,M00_.param_names,'exact'))= 1;
M10_.params(strmatch(M_.params(M_.occbin.pswitch(1)),M00_.param_names,'exact'))= 1;
[DM.Cbarmat10, DM.Bbarmat10, DM.Abarmat10, DM.Jbarmat10, DM.Dbarmat10] = occbin.get_deriv(M10_,data.ys);
M01_ = M00_;
M01_.params(strmatch(M_.occbin.constraint(2).pswitch,M00_.param_names,'exact'))= 1;
M01_.params(strmatch(M_.params(M_.occbin.pswitch(2)),M00_.param_names,'exact'))= 1;
[DM.Cbarmat01, DM.Bbarmat01, DM.Abarmat01, DM.Jbarmat01, DM.Dbarmat01] = occbin.get_deriv(M01_,data.ys);
M11_ = M00_;
M11_.params(M_.occbin.constraint(1).pswitch_index)= 1;
M11_.params(M_.occbin.constraint(2).pswitch_index)= 1;
M11_.params(M_.occbin.pswitch(1))= 1;
M11_.params(M_.occbin.pswitch(2))= 1;
[DM.Cbarmat11, DM.Bbarmat11, DM.Abarmat11, DM.Jbarmat11, DM.Dbarmat11] = occbin.get_deriv(M11_,data.ys);
[DM.decrulea,DM.decruleb]=occbin.get_pq(dr);
@ -183,7 +183,7 @@ for shock_period = 1:n_shocks_periods
binding_indicator,...
data.exo_pos,data.shocks_sequence(shock_period,:),endo_init, update_flag);
[binding, relax, err]=feval([M_.fname,'.eval_difference'],zdatalinear_,M_,dr.ys);
[binding, relax, err]=feval([M_.fname,'.occbin_difference'],zdatalinear_,M_.params,dr.ys);
binding_constraint_new=[binding.constraint_1;binding.constraint_2];
relaxed_constraint_new = [relax.constraint_1;relax.constraint_2];
@ -318,4 +318,4 @@ end
if opts_simul_.waitbar
dyn_waitbar_close(hh);
end
end

View File

@ -1,66 +0,0 @@
function tokens = tokenize(source,delimiter)
%function tokens = tokenize(source,delimiter)
% Breaks down strings into its components (tokens)
% INPUTS
% - source [string] string to be broken into tokens
% - delimiter [char array] single character delimiters
%
% OUTPUTS:
% -tokens [cell] array containing the tokens
% Original authors: Luca Guerrieri and Matteo Iacoviello
% Original file downloaded from:
% https://www.matteoiacoviello.com/research_files/occbin_20140630.zip
% Adapted for Dynare by Dynare Team.
%
% This code is in the public domain and may be used freely.
% However the authors would appreciate acknowledgement of the source by
% citation of any of the following papers:
%
% Luca Guerrieri and Matteo Iacoviello (2015): "OccBin: A toolkit for solving
% dynamic models with occasionally binding constraints easily"
% Journal of Monetary Economics 70, 22-38
posdelims = [];
% assumes that delimiter cannot be in the first position or the last position
ndelimiters = size(delimiter,1);
for i=1:ndelimiters
newpositions = strfind(source,delimiter(i,:));
if ~isempty(newpositions)
posdelims =[posdelims, newpositions];
end
end
% reorder posdelims in ascending order
posdelims = sort(posdelims);
if isempty(posdelims)
tokens = cellstr(source);
else
ndelims = length(posdelims);
% build positions for substrings
delims = zeros(ndelims+1,2);
for i=1:ndelims+1
if i==1
if posdelims(1) == 1
tokens = cellstr(source(1));
else
delims(i,:) = [1,posdelims(i)-1];
tokens = cellstr(source([delims(i,1):delims(i,2)]));
tokens = [tokens, source(posdelims(i))];
end
elseif i==ndelims+1
if (posdelims(i-1) < length(source))
delims(i,:) = [posdelims(i-1)+1,length(source)];
tokens = [tokens, cellstr(source([delims(i,1):delims(i,2)]))];
end
else
if posdelims(i)>posdelims(i-1)+1
delims(i,:) = [posdelims(i-1)+1,posdelims(i)-1];
tokens = [tokens, cellstr(source([delims(i,1):delims(i,2)]))];
end
tokens = [tokens, source(posdelims(i))];
end
end
end

View File

@ -969,7 +969,6 @@ occbin_options.opts_simul.periods = DynareOptions.occbin.likelihood.periods;
occbin_options.opts_simul.check_ahead_periods = DynareOptions.occbin.likelihood.check_ahead_periods;
occbin_options.opts_simul.periodic_solution = DynareOptions.occbin.likelihood.periodic_solution;
occbin_options.opts_simul.restrict_state_space = DynareOptions.occbin.likelihood.restrict_state_space;
occbin_options.constraints = Model.occbin.constraint;
occbin_options.opts_simul.full_output = DynareOptions.occbin.likelihood.full_output;
occbin_options.opts_simul.piecewise_only = DynareOptions.occbin.likelihood.piecewise_only;

View File

@ -107,7 +107,7 @@ if occbin_.status
opts_regime.binding_indicator = occbin_options.opts_simul.init_binding_indicator;
first_period_occbin_update = max(t+1,options_.occbin.likelihood.first_period_occbin_update);
if isempty(opts_regime.binding_indicator) && isempty(opts_regime.regime_history)
opts_regime.binding_indicator=zeros(last+2,length(M_.occbin.constraint));
opts_regime.binding_indicator=zeros(last+2,M_.occbin.constraint_nbr);
end
[~, ~, ~, regimes_] = occbin.check_regimes([], [], [], opts_regime, M_, oo_, options_);
if length(occbin_.info)>4

View File

@ -168,7 +168,7 @@ else
if isfield(opts_regime,'regime_history') && ~isempty(opts_regime.regime_history)
opts_regime.regime_history=[opts_regime.regime_history(1) opts_regime.regime_history];
else
opts_regime.binding_indicator=zeros(smpl+2,length(M_.occbin.constraint));
opts_regime.binding_indicator=zeros(smpl+2,M_.occbin.constraint_nbr);
end
occbin_options.opts_regime = opts_regime;
[~, ~, ~, regimes_] = occbin.check_regimes([], [], [], opts_regime, M_, oo_, options_);

@ -1 +1 @@
Subproject commit 08ac455fcddd032058738669ed6a84fda9c76e05
Subproject commit 81d4fd5d83c08da2403a8faf3d2a006d3ab4bb1e

View File

@ -26,8 +26,8 @@ y_hat = log(y) - log(steady_state(y));
end;
occbin_constraints;
% name 'relax_borrcon'; bind lb<-lb_ss; relax b>M*y; error_bind abs(lb+lb_ss); error_relax abs(b-M*y);
name 'relax_borrcon'; bind lb<-lb_ss; relax b>M*y;
name 'relax_borrcon'; bind lb<-STEADY_STATE(lb); relax b>M*y; error_bind abs(lb+STEADY_STATE(lb)); error_relax abs(b-M*y);
%name 'relax_borrcon'; bind lb<-STEADY_STATE(lb); relax b>M*y;
end;
steady_state_model;
@ -50,4 +50,4 @@ shocks;
var u; stderr SIGMA;
end;
@#include "borrcon_common.inc"
@#include "borrcon_common.inc"

View File

@ -27,7 +27,7 @@ y_hat = log(y) - log(steady_state(y));
end;
occbin_constraints;
name 'relax_borrcon'; bind lb<-lb_ss; relax b>M*y; error_bind abs(lb+lb_ss); error_relax abs(b-M*y);
name 'relax_borrcon'; bind lb<-STEADY_STATE(lb); relax b>M*y; error_bind abs(lb+STEADY_STATE(lb)); error_relax abs(b-M*y);
end;
steady_state_model;
@ -55,4 +55,4 @@ end;
orig_results=load('borrcon_results.mat');
if max(max(abs(oo_.occbin.piecewise-orig_results.oo_.occbin.piecewise)))>1e-10
error('Results do not match')
end
end

0
tests/occbin/model_irrcap_twoconstraints/dynrbc.mod Executable file → Normal file
View File