function [dr,info,M_,options_,oo_] = dr1_sparse(dr,task,M_,options_,oo_) % Computes the reduced form solution of a rational expectation model (first or second order % approximation of the stochastic model around the deterministic steady state). % % INPUTS % dr [matlab structure] Decision rules for stochastic simulations. % task [integer] if task = 0 then dr1 computes decision rules. % if task = 1 then dr1 computes eigenvalues. % M_ [matlab structure] Definition of the model. % options_ [matlab structure] Global options. % oo_ [matlab structure] Results % % OUTPUTS % dr [matlab structure] Decision rules for stochastic simulations. % info [integer] info=1: the model doesn't define current variables uniquely % info=2: problem in mjdgges.dll info(2) contains error code. % info=3: BK order condition not satisfied info(2) contains "distance" % absence of stable trajectory. % info=4: BK order condition not satisfied info(2) contains "distance" % indeterminacy. % info=5: BK rank condition not satisfied. % M_ [matlab structure] % options_ [matlab structure] % oo_ [matlab structure] % % ALGORITHM % ... % % SPECIAL REQUIREMENTS % none. % % Copyright (C) 1996-2009 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 . info = 0; options_ = set_default_option(options_,'loglinear',0); options_ = set_default_option(options_,'noprint',0); options_ = set_default_option(options_,'olr',0); options_ = set_default_option(options_,'olr_beta',1); options_ = set_default_option(options_,'qz_criterium',1.000001); xlen = M_.maximum_endo_lead + M_.maximum_endo_lag + 1; klen = M_.maximum_endo_lag + M_.maximum_endo_lead + 1; iyv = M_.lead_lag_incidence'; iyv = iyv(:); iyr0 = find(iyv) ; it_ = M_.maximum_lag + 1 ; if M_.exo_nbr == 0 oo_.exo_steady_state = [] ; end % expanding system for Optimal Linear Regulator if options_.ramsey_policy if isfield(M_,'orig_model') orig_model = M_.orig_model; M_.endo_nbr = orig_model.endo_nbr; M_.orig_endo_nbr = orig_model.orig_endo_nbr; M_.aux_vars = orig_model.aux_vars; M_.endo_names = orig_model.endo_names; M_.lead_lag_incidence = orig_model.lead_lag_incidence; M_.maximum_lead = orig_model.maximum_lead; M_.maximum_endo_lead = orig_model.maximum_endo_lead; M_.maximum_lag = orig_model.maximum_lag; M_.maximum_endo_lag = orig_model.maximum_endo_lag; end old_solve_algo = options_.solve_algo; % options_.solve_algo = 1; oo_.steady_state = dynare_solve('dyn_ramsey_static_',oo_.steady_state,0,M_,options_,oo_,it_); options_.solve_algo = old_solve_algo; [junk,junk,multbar] = dyn_ramsey_static_(oo_.steady_state,M_,options_,oo_,it_); [jacobia_,M_] = dyn_ramsey_dynamic_(oo_.steady_state,multbar,M_,options_,oo_,it_); klen = M_.maximum_lag + M_.maximum_lead + 1; dr.ys = [oo_.steady_state;zeros(M_.exo_nbr,1);multbar]; % $$$ if options_.ramsey_policy == 2 % $$$ mask = M_.orig_model.lead_lag_incidence ~= 0; % $$$ incidence_submatrix = M_.lead_lag_incidence(M_.orig_model.maximum_lead+(1:size(mask,1)),1:M_.orig_model.endo_nbr); % $$$ k = nonzeros((incidence_submatrix.*mask)'); % $$$ nl = nnz(M_.lead_lag_incidence); % $$$ k = [k; nl+(1:M_.exo_nbr)']; % $$$ kk = reshape(1:(nl+M_.exo_nbr)^2,nl+M_.exo_nbr,nl+M_.exo_nbr); % $$$ kk2 = kk(k,k); % $$$ % $$$ k1 = find(M_.orig_model.lead_lag_incidence'); % $$$ y = repmat(oo_.dr.ys(1:M_.orig_model.endo_nbr),1,M_.orig_model.maximum_lag+M_.orig_model.maximum_lead+1); % $$$ [f,fJ,fh] = feval([M_.fname '_dynamic'],y(k1),zeros(1,M_.exo_nbr), M_.params, it_); % $$$ % $$$ % looking for dynamic variables that are both in the original model % $$$ % and in the optimal policy model % $$$ k1 = k1+nnz(M_.lead_lag_incidence(1:M_.orig_model.maximum_lead,1:M_.orig_model.endo_nbr)); % $$$ hessian = sparse([],[],[],size(jacobia_,1),(nl+M_.exo_nbr)^2,nnz(fh)); % $$$ hessian(M_.orig_model.endo_nbr+(1:size(fh,1)),kk2) = fh; % $$$ options_.order = 2; % $$$ elseif options_.ramsey_policy == 3 % $$$ maxlag1 = M_.orig_model.maximum_lag; % $$$ maxlead1 = M_.orig_model.maximum_lead; % $$$ endo_nbr1 = M_.orig_model.endo_nbr; % $$$ lead_lag_incidence1 = M_.orig_model.lead_lag_incidence; % $$$ y = repmat(oo_.dr.ys(1:M_.orig_model.endo_nbr),1,M_.orig_model.maximum_lag+M_.orig_model.maximum_lead+1); % $$$ k1 = find(M_.orig_model.lead_lag_incidence'); % $$$ [f,fj,fh] = feval([M_.fname '_dynamic'],y(k1),zeros(1,M_.exo_nbr), M_.params, it_); % $$$ nrj = size(fj,1); % $$$ % $$$ iy = M_.lead_lag_incidence; % $$$ kstate = oo_.dr.kstate; % $$$ inv_order_var = oo_.dr.inv_order_var; % $$$ offset = 0; % $$$ i3 = zeros(0,1); % $$$ i4 = find(kstate(:,2) <= M_.maximum_lag+1); % $$$ kstate1 = kstate(i4,:); % $$$ kk2 = zeros(0,1); % $$$ % lagged variables % $$$ for i=2:M_.maximum_lag + 1 % $$$ i1 = find(kstate(:,2) == i); % $$$ k1 = kstate(i1,:); % $$$ i2 = find(oo_.dr.order_var(k1(:,1)) <= M_.orig_model.endo_nbr); % $$$ i3 = [i3; i2+offset]; % $$$ offset = offset + size(k1,1); % $$$ i4 = find(kstate1(:,2) == i); % $$$ kk2 = [kk2; i4]; % $$$ end % $$$ i2 = find(oo_.dr.order_var(k1(:,1)) > M_.orig_model.endo_nbr); % $$$ j2 = k1(i2,1); % $$$ nj2 = length(j2); % $$$ k2 = offset+(1:nj2)'; % $$$ offset = offset + length(i2); % $$$ i3 = [i3; ... % $$$ find(M_.orig_model.lead_lag_incidence(M_.orig_model.maximum_lag+1:end,:)')+offset]; % $$$ i3 = [i3; (1:M_.exo_nbr)'+length(i3)]; % $$$ ni3 = length(i3); % $$$ nrfj = size(fj,1); % $$$ jacobia_ = zeros(nrfj+length(j2),ni3); % $$$ jacobia_(1:nrfj,i3) = fj; % $$$ jacobia_(nrfj+(1:nj2),1:size(oo_.dr.ghx,2)) = oo_.dr.ghx(j2,:); % $$$ jacobia_(nrfj+(1:nj2),k2) = eye(nj2); % $$$ kk1 = reshape(1:ni3^2,ni3,ni3); % $$$ hessian = zeros(nrfj+length(j2),ni3^2); % $$$ hessian(1:nrfj,kk1(i3,i3)) = fh; % $$$ % $$$ k = find(any(M_.lead_lag_incidence(1:M_.maximum_lag, ... % $$$ M_.orig_model.endo_nbr+1:end))); % $$$ if maxlead1 > maxlag1 % $$$ M_.lead_lag_incidence = [ [zeros(maxlead1-maxlag1,endo_nbr1); ... % $$$ lead_lag_incidence1] ... % $$$ [M_.lead_lag_incidence(M_.maximum_lag+(1:maxlead1), ... % $$$ k); zeros(maxlead1,length(k))]]; % $$$ elseif maxlag1 > maxlead1 % $$$ M_.lead_lag_incidence = [ [lead_lag_incidence1; zeros(maxlag1- ... % $$$ maxlead1,endo_nbr1);] ... % $$$ [M_.lead_lag_incidence(M_.maximum_lag+(1:maxlead1), ... % $$$ k); zeros(maxlead1,length(k))]]; % $$$ else % maxlag1 == maxlead1 % $$$ M_.lead_lag_incidence = [ lead_lag_incidence1 % $$$ [M_.lead_lag_incidence(M_.maximum_lag+(1:maxlead1), ... % $$$ k); zeros(maxlead1,length(k))]]; % $$$ end % $$$ M_.maximum_lag = max(maxlead1,maxlag1); % $$$ M_.maximum_endo_lag = M_.maximum_lag; % $$$ M_.maximum_lead = M_.maximum_lag; % $$$ M_.maximum_endo_lead = M_.maximum_lag; % $$$ % $$$ M_.endo_names = strvcat(M_.orig_model.endo_names, M_.endo_names(endo_nbr1+k,:)); % $$$ M_.endo_nbr = endo_nbr1+length(k); % $$$ end else klen = M_.maximum_lag + M_.maximum_lead + 1; iyv = M_.lead_lag_incidence'; iyv = iyv(:); iyr0 = find(iyv) ; it_ = M_.maximum_lag + 1 ; if M_.exo_nbr == 0 oo_.exo_steady_state = [] ; end it_ = M_.maximum_lag + 1; z = repmat(dr.ys,1,klen); z = z(iyr0) ; if options_.model_mode==0 || options_.model_mode == 2 if options_.order == 1 [junk,jacobia_] = feval([M_.fname '_dynamic'],z,[oo_.exo_simul ... oo_.exo_det_simul], M_.params, it_); hessian = 0; elseif options_.order == 2 [junk,jacobia_,hessian] = feval([M_.fname '_dynamic'],z,... [oo_.exo_simul ... oo_.exo_det_simul], M_.params, it_); end dr=set_state_space(dr,M_); if options_.debug save([M_.fname '_debug.mat'],'jacobia_') end [dr,info,M_,options_,oo_] = dr11_sparse(dr,task,M_,options_,oo_, jacobia_, hessian); dr.nyf = nnz(dr.kstate(:,2)>M_.maximum_lag+1); elseif options_.model_mode==1 if options_.order == 1 [junk,derivate] = feval([M_.fname '_dynamic'],ones(M_.maximum_lag+M_.maximum_lead+1,1)*dr.ys',[oo_.exo_simul ... oo_.exo_det_simul], M_.params, it_); %full(jacobia_) dr.eigval = []; dr.nyf = 0; dr.rank = 0; first_col_exo = M_.endo_nbr * (M_.maximum_endo_lag + M_.maximum_endo_lead + 1); for i=1:length(M_.block_structure.block) %disp(['block = ' int2str(i)]); M_.block_structure.block(i).dr.Null=0; M_.block_structure.block(i).dr=set_state_space(M_.block_structure.block(i).dr,M_.block_structure.block(i)); col_selector=repmat(M_.block_structure.block(i).variable,1,M_.block_structure.block(i).maximum_endo_lag+M_.block_structure.block(i).maximum_endo_lead+1)+kron([M_.maximum_endo_lag-M_.block_structure.block(i).maximum_endo_lag:M_.maximum_endo_lag+M_.block_structure.block(i).maximum_endo_lead],M_.endo_nbr*ones(1,M_.block_structure.block(i).endo_nbr)); row_selector = M_.block_structure.block(i).equation; %jcb_=jacobia_(row_selector,col_selector); jcb_=derivate(i).g1; %disp('jcb_'); %full(jcb_) %M_.block_structure.block(i).lead_lag_incidence' jcb_ = jcb_(:,find(M_.block_structure.block(i).lead_lag_incidence')) ; if M_.block_structure.block(i).exo_nbr>0 col_selector = [ first_col_exo + ... repmat(M_.block_structure.block(i).exogenous,1,M_.block_structure.block(i).maximum_exo_lag+M_.block_structure.block(i).maximum_exo_lead+1)+kron([M_.maximum_exo_lag-M_.block_structure.block(i).maximum_exo_lag:M_.maximum_exo_lag+M_.block_structure.block(i).maximum_exo_lead],M_.exo_nbr*ones(1,M_.block_structure.block(i).exo_nbr))]; end %derivate(i).g1 %derivate(i).g1_x %col_selector %jcb_ = [ jcb_ jacobia_(row_selector,col_selector)]; jcb_ = [ jcb_ derivate(i).g1_x]; %full(jcb_) hss_=0; %hessian(M_.block_structure.block(i).equation,M_.block_structure.block(i).variable); dra = M_.block_structure.block(i).dr; %M_.block_structure.block(i).exo_nbr=M_.exo_nbr; [dra ,info,M_.block_structure.block(i),options_,oo_] = dr11_sparse(dra ,task,M_.block_structure.block(i),options_,oo_, jcb_, hss_); M_.block_structure.block(i).dr = dra; dr.eigval = [dr.eigval; dra.eigval]; nyf = nnz(dra.kstate(:,2)>M_.block_structure.block(i).maximum_endo_lag+1); n_explod = nnz(abs(dra.eigval) > options_.qz_criterium); if nyf ~= n_explod disp(['EIGENVALUES in block ' int2str(i) ':']); [m_lambda,ii]=sort(abs(dra.eigval)); disp(sprintf('%16s %16s %16s\n','Modulus','Real','Imaginary')) z=[m_lambda real(dra.eigval(ii)) imag(dra.eigval(ii))]'; disp(sprintf('%16.4g %16.4g %16.4g\n',z)) disp(['The rank condition is not satisfy in block ' int2str(i) ' :']); disp([' ' int2str(nyf) ' forward-looking variable(s) for ' ... int2str(n_explod) ' eigenvalue(s) larger than 1 in modulus']); end dr.nyf = dr.nyf + nyf; dr.rank = dr.rank + dra.rank; end; end end end