2011-09-22 11:17:31 +02:00
|
|
|
function [fval,exit_flag,info,PHI,SIGMAu,iXX,prior] = DsgeVarLikelihood(xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults)
|
|
|
|
% Evaluates the posterior kernel of the bvar-dsge model.
|
|
|
|
%
|
|
|
|
% INPUTS
|
2009-05-12 13:38:06 +02:00
|
|
|
% o xparam1 [double] Vector of model's parameters.
|
|
|
|
% o gend [integer] Number of observations (without conditionning observations for the lags).
|
2011-09-22 11:17:31 +02:00
|
|
|
%
|
|
|
|
% OUTPUTS
|
2009-05-12 13:38:06 +02:00
|
|
|
% o fval [double] Value of the posterior kernel at xparam1.
|
|
|
|
% o cost_flag [integer] Zero if the function returns a penalty, one otherwise.
|
|
|
|
% o info [integer] Vector of informations about the penalty.
|
|
|
|
% o PHI [double] Stacked BVAR-DSGE autoregressive matrices (at the mode associated to xparam1).
|
|
|
|
% o SIGMAu [double] Covariance matrix of the BVAR-DSGE (at the mode associated to xparam1).
|
|
|
|
% o iXX [double] inv(X'X).
|
2011-09-22 11:17:31 +02:00
|
|
|
% o prior [double] a matlab structure describing the dsge-var prior.
|
2009-05-12 13:38:06 +02:00
|
|
|
%
|
|
|
|
% SPECIAL REQUIREMENTS
|
|
|
|
% None.
|
|
|
|
|
2011-02-04 17:27:33 +01:00
|
|
|
% Copyright (C) 2006-2011 Dynare Team
|
2009-05-12 13:38:06 +02:00
|
|
|
%
|
|
|
|
% 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/>.
|
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
% Declaration of the persistent variables.
|
|
|
|
persistent penalty dsge_prior_weight_idx
|
|
|
|
|
|
|
|
% Initialization of the penalty
|
|
|
|
if ~nargin || isempty(penalty)
|
|
|
|
penalty = 1e8;
|
|
|
|
if ~nargin, return, end
|
|
|
|
end
|
|
|
|
if nargin==1
|
|
|
|
penalty = xparam1;
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
% Initialization of of the index for parameter dsge_prior_weight in Model.params.
|
|
|
|
if isempty(dsge_prior_weight_idx)
|
|
|
|
dsge_prior_weight_idx = strmatch('dsge_prior_weight',Model.param_names);
|
|
|
|
end
|
|
|
|
|
|
|
|
% Get the number of estimated (dsge) parameters.
|
|
|
|
ns = EstimatedParameters.nvx + ...
|
|
|
|
EstimatedParameters.nvn + ...
|
|
|
|
EstimatedParameters.ncx + ...
|
|
|
|
EstimatedParameters.ncn;
|
|
|
|
nx = ns + EstimatedParameters.np;
|
2009-05-12 13:38:06 +02:00
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
% Get the number of observed variables in the VAR model.
|
|
|
|
NumberOfObservedVariables = DynareDataset.info.nvobs;
|
2009-05-12 13:38:06 +02:00
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
% Get the number of lags in the VAR model.
|
|
|
|
NumberOfLags = DynareOptions.dsge_varlag;
|
|
|
|
|
|
|
|
% Get the number of parameters in the VAR model.
|
2009-05-12 13:38:06 +02:00
|
|
|
NumberOfParameters = NumberOfObservedVariables*NumberOfLags ;
|
2011-09-22 11:17:31 +02:00
|
|
|
if ~DynareOptions.noconstant
|
2009-05-12 13:38:06 +02:00
|
|
|
NumberOfParameters = NumberOfParameters + 1;
|
|
|
|
end
|
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
% Get empirical second order moments for the observed variables.
|
2009-05-12 13:38:06 +02:00
|
|
|
mYY = evalin('base', 'mYY');
|
|
|
|
mYX = evalin('base', 'mYX');
|
|
|
|
mXY = evalin('base', 'mXY');
|
|
|
|
mXX = evalin('base', 'mXX');
|
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
% Initialize some of the output arguments.
|
2009-05-12 13:38:06 +02:00
|
|
|
fval = [];
|
2011-09-22 11:17:31 +02:00
|
|
|
exit_flag = 1;
|
2009-05-12 13:38:06 +02:00
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
% Return, with endogenous penalty, if some dsge-parameters are smaller than the lower bound of the prior domain.
|
|
|
|
if DynareOptions.mode_compute ~= 1 && any(xparam1 < BayesInfo.lb)
|
|
|
|
k = find(xparam1 < BayesInfo.lb);
|
|
|
|
fval = penalty+sum((BayesInfo.lb(k)-xparam1(k)).^2);
|
|
|
|
exit_flag = 0;
|
2009-05-12 13:38:06 +02:00
|
|
|
info = 41;
|
|
|
|
return;
|
|
|
|
end
|
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
% Return, with endogenous penalty, if some dsge-parameters are greater than the upper bound of the prior domain.
|
|
|
|
if DynareOptions.mode_compute ~= 1 && any(xparam1 > BayesInfo.ub)
|
|
|
|
k = find(xparam1 > BayesInfo.ub);
|
|
|
|
fval = penalty+sum((xparam1(k)-BayesInfo.ub(k)).^2);
|
|
|
|
exit_flag = 0;
|
2009-05-12 13:38:06 +02:00
|
|
|
info = 42;
|
|
|
|
return;
|
|
|
|
end
|
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
% Get the variance of each structural innovation.
|
|
|
|
Q = Model.Sigma_e;
|
|
|
|
for i=1:EstimatedParameters.nvx
|
|
|
|
k = EstimatedParameters.var_exo(i,1);
|
2009-05-12 13:38:06 +02:00
|
|
|
Q(k,k) = xparam1(i)*xparam1(i);
|
|
|
|
end
|
2011-09-22 11:17:31 +02:00
|
|
|
offset = EstimatedParameters.nvx;
|
|
|
|
|
|
|
|
% Check that the user does not estimate measurment errors.
|
|
|
|
% TODO Check that the user does not declare non estimated measurement errors...
|
|
|
|
if EstimatedParameters.nvn
|
2010-06-24 12:53:10 +02:00
|
|
|
disp('DsgeVarLikelihood :: Measurement errors are not implemented!')
|
2009-05-12 13:38:06 +02:00
|
|
|
return
|
2011-09-22 11:17:31 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
% Check that the user does not estimate off diagonal elements in the covariance matrix of the structural innovation.
|
|
|
|
% TODO Check that Q is a diagonal matrix...
|
|
|
|
if EstimatedParameters.ncx
|
2009-05-12 13:38:06 +02:00
|
|
|
disp('DsgeVarLikelihood :: Correlated structural innovations are not implemented!')
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
% Update Model.params and Model.Sigma_e.
|
|
|
|
Model.params(EstimatedParameters.param_vals(:,1)) = xparam1(offset+1:end);
|
|
|
|
Model.Sigma_e = Q;
|
|
|
|
|
|
|
|
% Get the weight of the dsge prior.
|
|
|
|
dsge_prior_weight = Model.params(dsge_prior_weight_idx);
|
2009-05-12 13:38:06 +02:00
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
% Is the dsge prior proper?
|
|
|
|
if dsge_prior_weight<(NumberOfParameters+NumberOfObservedVariables)/DynareDataset.info.ntobs;
|
|
|
|
fval = penalty+abs(DynareDataset.info.ntobs*dsge_prior_weight-(NumberOfParameters+NumberOfObservedVariables));
|
|
|
|
exit_flag = 0;
|
2009-05-12 13:38:06 +02:00
|
|
|
info = 51;
|
2011-09-22 11:17:31 +02:00
|
|
|
return
|
2009-05-12 13:38:06 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
%------------------------------------------------------------------------------
|
|
|
|
% 2. call model setup & reduction program
|
|
|
|
%------------------------------------------------------------------------------
|
2011-01-26 13:50:11 +01:00
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
% Solve the Dsge model and get the matrices of the reduced form solution. T and R are the matrices of the
|
|
|
|
% state equation
|
|
|
|
[T,R,SteadyState,info,Model,DynareOptions,DynareResults] = dynare_resolve(Model,DynareOptions,DynareResults,'restrict');
|
|
|
|
|
|
|
|
% Return, with endogenous penalty when possible, if dynare_resolve issues an error code (defined in resol).
|
2009-05-12 13:38:06 +02:00
|
|
|
if info(1) == 1 || info(1) == 2 || info(1) == 5
|
2011-09-22 11:17:31 +02:00
|
|
|
fval = penalty+1;
|
|
|
|
info = info(1);
|
|
|
|
exit_flag = 0;
|
2009-05-12 13:38:06 +02:00
|
|
|
return
|
|
|
|
elseif info(1) == 3 || info(1) == 4 || info(1) == 19 || info(1) == 20 || info(1) == 21
|
2011-09-22 11:17:31 +02:00
|
|
|
fval = penalty+info(2);
|
|
|
|
info = info(1);
|
|
|
|
exit_flag = 0;
|
2009-05-12 13:38:06 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
% Define the mean/steady state vector.
|
|
|
|
if ~DynareOptions.noconstant
|
|
|
|
if DynareOptions.loglinear
|
|
|
|
constant = transpose(log(SteadyState(BayesInfo.mfys)));
|
2009-05-12 13:38:06 +02:00
|
|
|
else
|
2011-09-22 11:17:31 +02:00
|
|
|
constant = transpose(SteadyState(BayesInfo.mfys));
|
|
|
|
end
|
2009-05-12 13:38:06 +02:00
|
|
|
else
|
|
|
|
constant = zeros(1,NumberOfObservedVariables);
|
|
|
|
end
|
2011-09-22 11:17:31 +02:00
|
|
|
|
|
|
|
% Dsge-VAR with deterministic trends is not implemented
|
|
|
|
if BayesInfo.with_trend == 1
|
|
|
|
error('DsgeVarLikelihood :: Linear trend is not yet implemented!')
|
2009-05-12 13:38:06 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
%------------------------------------------------------------------------------
|
|
|
|
% 3. theoretical moments (second order)
|
|
|
|
%------------------------------------------------------------------------------
|
2011-09-22 11:17:31 +02:00
|
|
|
|
|
|
|
% Compute the theoretical second order moments
|
|
|
|
tmp0 = lyapunov_symm(T,R*Q*R',DynareOptions.qz_criterium,DynareOptions.lyapunov_complex_threshold);
|
|
|
|
mf = BayesInfo.mf1;
|
2009-05-12 13:38:06 +02:00
|
|
|
|
|
|
|
% Get the non centered second order moments
|
2011-09-22 11:17:31 +02:00
|
|
|
TheoreticalAutoCovarianceOfTheObservedVariables = zeros(NumberOfObservedVariables,NumberOfObservedVariables,NumberOfLags+1);
|
2009-05-12 13:38:06 +02:00
|
|
|
TheoreticalAutoCovarianceOfTheObservedVariables(:,:,1) = tmp0(mf,mf)+constant'*constant;
|
|
|
|
for lag = 1:NumberOfLags
|
2009-12-16 18:17:34 +01:00
|
|
|
tmp0 = T*tmp0;
|
2011-09-22 11:17:31 +02:00
|
|
|
TheoreticalAutoCovarianceOfTheObservedVariables(:,:,lag+1) = tmp0(mf,mf) + constant'*constant;
|
2009-05-12 13:38:06 +02:00
|
|
|
end
|
2011-09-22 11:17:31 +02:00
|
|
|
|
2009-05-12 13:38:06 +02:00
|
|
|
% Build the theoretical "covariance" between Y and X
|
|
|
|
GYX = zeros(NumberOfObservedVariables,NumberOfParameters);
|
|
|
|
for i=1:NumberOfLags
|
2011-09-22 11:17:31 +02:00
|
|
|
GYX(:,(i-1)*NumberOfObservedVariables+1:i*NumberOfObservedVariables) = TheoreticalAutoCovarianceOfTheObservedVariables(:,:,i+1);
|
2009-05-12 13:38:06 +02:00
|
|
|
end
|
2011-09-22 11:17:31 +02:00
|
|
|
if ~DynareOptions.noconstant
|
2009-05-12 13:38:06 +02:00
|
|
|
GYX(:,end) = constant';
|
|
|
|
end
|
2011-09-22 11:17:31 +02:00
|
|
|
|
2009-05-12 13:38:06 +02:00
|
|
|
% Build the theoretical "covariance" between X and X
|
2011-09-22 11:17:31 +02:00
|
|
|
GXX = kron(eye(NumberOfLags), TheoreticalAutoCovarianceOfTheObservedVariables(:,:,1));
|
2009-05-12 13:38:06 +02:00
|
|
|
for i = 1:NumberOfLags-1
|
2011-09-22 11:17:31 +02:00
|
|
|
tmp1 = diag(ones(NumberOfLags-i,1),i);
|
2009-05-12 13:38:06 +02:00
|
|
|
tmp2 = diag(ones(NumberOfLags-i,1),-i);
|
|
|
|
GXX = GXX + kron(tmp1,TheoreticalAutoCovarianceOfTheObservedVariables(:,:,i+1));
|
|
|
|
GXX = GXX + kron(tmp2,TheoreticalAutoCovarianceOfTheObservedVariables(:,:,i+1)');
|
|
|
|
end
|
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
if ~DynareOptions.noconstant
|
2009-05-12 13:38:06 +02:00
|
|
|
% Add one row and one column to GXX
|
|
|
|
GXX = [GXX , kron(ones(NumberOfLags,1),constant') ; [ kron(ones(1,NumberOfLags),constant) , 1] ];
|
|
|
|
end
|
|
|
|
|
|
|
|
GYY = TheoreticalAutoCovarianceOfTheObservedVariables(:,:,1);
|
|
|
|
|
|
|
|
assignin('base','GYY',GYY);
|
|
|
|
assignin('base','GXX',GXX);
|
|
|
|
assignin('base','GYX',GYX);
|
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
if ~isinf(dsge_prior_weight)% Evaluation of the likelihood of the dsge-var model when the dsge prior weight is finite.
|
|
|
|
tmp0 = dsge_prior_weight*DynareDataset.info.ntobs*TheoreticalAutoCovarianceOfTheObservedVariables(:,:,1) + mYY ;
|
|
|
|
tmp1 = dsge_prior_weight*DynareDataset.info.ntobs*GYX + mYX;
|
|
|
|
tmp2 = inv(dsge_prior_weight*DynareDataset.info.ntobs*GXX+mXX);
|
2009-12-16 18:17:34 +01:00
|
|
|
SIGMAu = tmp0 - tmp1*tmp2*tmp1'; clear('tmp0');
|
|
|
|
if ~ispd(SIGMAu)
|
|
|
|
v = diag(SIGMAu);
|
|
|
|
k = find(v<0);
|
2011-09-22 11:17:31 +02:00
|
|
|
fval = penalty + sum(v(k).^2);
|
2009-12-16 18:17:34 +01:00
|
|
|
info = 52;
|
2011-09-22 11:17:31 +02:00
|
|
|
exit_flag = 0;
|
2009-12-16 18:17:34 +01:00
|
|
|
return;
|
|
|
|
end
|
2011-09-22 11:17:31 +02:00
|
|
|
SIGMAu = SIGMAu / (DynareDataset.info.ntobs*(1+dsge_prior_weight));
|
2009-12-16 18:17:34 +01:00
|
|
|
PHI = tmp2*tmp1'; clear('tmp1');
|
2011-09-22 11:17:31 +02:00
|
|
|
prodlng1 = sum(gammaln(.5*((1+dsge_prior_weight)*DynareDataset.info.ntobs- ...
|
2009-12-16 18:17:34 +01:00
|
|
|
NumberOfObservedVariables*NumberOfLags ...
|
|
|
|
+1-(1:NumberOfObservedVariables)')));
|
2011-09-22 11:17:31 +02:00
|
|
|
prodlng2 = sum(gammaln(.5*(dsge_prior_weight*DynareDataset.info.ntobs- ...
|
2009-12-16 18:17:34 +01:00
|
|
|
NumberOfObservedVariables*NumberOfLags ...
|
2011-09-22 11:17:31 +02:00
|
|
|
+1-(1:NumberOfObservedVariables)')));
|
|
|
|
lik = .5*NumberOfObservedVariables*log(det(dsge_prior_weight*DynareDataset.info.ntobs*GXX+mXX)) ...
|
|
|
|
+ .5*((dsge_prior_weight+1)*DynareDataset.info.ntobs-NumberOfParameters)*log(det((dsge_prior_weight+1)*DynareDataset.info.ntobs*SIGMAu)) ...
|
|
|
|
- .5*NumberOfObservedVariables*log(det(dsge_prior_weight*DynareDataset.info.ntobs*GXX)) ...
|
|
|
|
- .5*(dsge_prior_weight*DynareDataset.info.ntobs-NumberOfParameters)*log(det(dsge_prior_weight*DynareDataset.info.ntobs*(GYY-GYX*inv(GXX)*GYX'))) ...
|
|
|
|
+ .5*NumberOfObservedVariables*DynareDataset.info.ntobs*log(2*pi) ...
|
|
|
|
- .5*log(2)*NumberOfObservedVariables*((dsge_prior_weight+1)*DynareDataset.info.ntobs-NumberOfParameters) ...
|
|
|
|
+ .5*log(2)*NumberOfObservedVariables*(dsge_prior_weight*DynareDataset.info.ntobs-NumberOfParameters) ...
|
2009-12-16 18:17:34 +01:00
|
|
|
- prodlng1 + prodlng2;
|
2011-09-22 11:17:31 +02:00
|
|
|
else% Evaluation of the likelihood of the dsge-var model when the dsge prior weight is infinite.
|
2009-12-16 18:17:34 +01:00
|
|
|
iGXX = inv(GXX);
|
|
|
|
SIGMAu = GYY - GYX*iGXX*transpose(GYX);
|
|
|
|
PHI = iGXX*transpose(GYX);
|
2011-09-22 11:17:31 +02:00
|
|
|
lik = DynareDataset.info.ntobs * ( log(det(SIGMAu)) + NumberOfObservedVariables*log(2*pi) + ...
|
|
|
|
trace(inv(SIGMAu)*(mYY - transpose(mYX*PHI) - mYX*PHI + transpose(PHI)*mXX*PHI)/DynareDataset.info.ntobs));
|
2009-12-16 18:17:34 +01:00
|
|
|
lik = .5*lik;% Minus likelihood
|
2011-09-22 11:17:31 +02:00
|
|
|
end
|
2009-05-12 13:38:06 +02:00
|
|
|
|
2011-09-22 11:17:31 +02:00
|
|
|
% Add the (logged) prior density for the dsge-parameters.
|
|
|
|
lnprior = priordens(xparam1,BayesInfo.pshape,BayesInfo.p6,BayesInfo.p7,BayesInfo.p3,BayesInfo.p4);
|
2009-05-12 13:38:06 +02:00
|
|
|
fval = (lik-lnprior);
|
|
|
|
|
|
|
|
if (nargout == 6)
|
|
|
|
if isinf(dsge_prior_weight)
|
|
|
|
iXX = iGXX;
|
|
|
|
else
|
|
|
|
iXX = tmp2;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if (nargout==7)
|
|
|
|
if isinf(dsge_prior_weight)
|
|
|
|
iXX = iGXX;
|
|
|
|
else
|
|
|
|
iXX = tmp2;
|
|
|
|
end
|
2011-09-22 11:17:31 +02:00
|
|
|
iGXX = inv(GXX);
|
2009-05-12 13:38:06 +02:00
|
|
|
prior.SIGMAstar = GYY - GYX*iGXX*GYX';
|
|
|
|
prior.PHIstar = iGXX*transpose(GYX);
|
2011-09-22 11:17:31 +02:00
|
|
|
prior.ArtificialSampleSize = fix(dsge_prior_weight*DynareDataset.info.ntobs);
|
2009-05-12 13:38:06 +02:00
|
|
|
prior.DF = prior.ArtificialSampleSize - NumberOfParameters - NumberOfObservedVariables;
|
|
|
|
prior.iGXX = iGXX;
|
2007-10-03 16:40:43 +02:00
|
|
|
end
|