From eb72df7bc680c51a78b72c3c29f798193d8903d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Karam=C3=A9?= <frederic.karame@univ-lemans.fr> Date: Fri, 16 Nov 2012 11:29:21 +0100 Subject: [PATCH] computes the proposal distribution during the importance sampling step for gaussian-mixture filters. Fix many bugs. --- .../particle/gaussian_mixture_filter_bank.m | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 matlab/particle/gaussian_mixture_filter_bank.m diff --git a/matlab/particle/gaussian_mixture_filter_bank.m b/matlab/particle/gaussian_mixture_filter_bank.m new file mode 100644 index 000000000..9d7f43fc0 --- /dev/null +++ b/matlab/particle/gaussian_mixture_filter_bank.m @@ -0,0 +1,145 @@ +function [StateMuPrior,StateSqrtPPrior,StateWeightsPrior,StateMuPost,StateSqrtPPost,StateWeightsPost] =... + gaussian_mixture_filter_bank(ReducedForm,obs,StateMu,StateSqrtP,StateWeights,... + StructuralShocksMu,StructuralShocksSqrtP,StructuralShocksWeights,... + ObservationShocksMu,ObservationShocksSqrtP,ObservationShocksWeights,... + H,H_lower_triangular_cholesky,normfactO,DynareOptions) +% +% Computes the proposal with a gaussian approximation for importance +% sampling +% This proposal is a gaussian distribution calculated à la Kalman +% +% INPUTS +% reduced_form_model [structure] Matlab's structure describing the reduced form model. +% reduced_form_model.measurement.H [double] (pp x pp) variance matrix of measurement errors. +% reduced_form_model.state.Q [double] (qq x qq) variance matrix of state errors. +% reduced_form_model.state.dr [structure] output of resol.m. +% Y [double] pp*smpl matrix of (detrended) data, where pp is the maximum number of observed variables. +% +% OUTPUTS +% LIK [double] scalar, likelihood +% lik [double] vector, density of observations in each period. +% +% REFERENCES +% +% NOTES +% The vector "lik" is used to evaluate the jacobian of the likelihood. +% Copyright (C) 2009-2012 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/>. + + + +persistent init_flag2 mf0 mf1 %nodes3 weights3 weights_c3 +persistent number_of_state_variables number_of_observed_variables +persistent number_of_structural_innovations + +% Set local state space model (first-order approximation). +ghx = ReducedForm.ghx; +ghu = ReducedForm.ghu; +% Set local state space model (second-order approximation). +ghxx = ReducedForm.ghxx; +ghuu = ReducedForm.ghuu; +ghxu = ReducedForm.ghxu; + +if any(any(isnan(ghx))) || any(any(isnan(ghu))) || any(any(isnan(ghxx))) || any(any(isnan(ghuu))) || any(any(isnan(ghxu))) || ... + any(any(isinf(ghx))) || any(any(isinf(ghu))) || any(any(isinf(ghxx))) || any(any(isinf(ghuu))) || any(any(isinf(ghxu))) ... + any(any(abs(ghx)>1e4)) || any(any(abs(ghu)>1e4)) || any(any(abs(ghxx)>1e4)) || any(any(abs(ghuu)>1e4)) || any(any(abs(ghxu)>1e4)) + ghx + ghu + ghxx + ghuu + ghxu +end + +constant = ReducedForm.constant; +state_variables_steady_state = ReducedForm.state_variables_steady_state; + +% Set persistent variables. +if isempty(init_flag2) + mf0 = ReducedForm.mf0; + mf1 = ReducedForm.mf1; + number_of_state_variables = length(mf0); + number_of_observed_variables = length(mf1); + number_of_structural_innovations = length(ReducedForm.Q); + init_flag2 = 1; +end + +numb = number_of_state_variables+number_of_structural_innovations ; + +if strcmpi(DynareOptions.particle.IS_approximation_method,'quadrature') + [nodes3,weights3] = nwspgr('GQN',numb,DynareOptions.particle.smolyak_accuracy) ; + weights_c3 = weights3 ; +end +if strcmpi(DynareOptions.particle.IS_approximation_method,'cubature') + [nodes3,weights3] = spherical_radial_sigma_points(numb) ; + weights_c3 = weights3 ; +end +if strcmpi(DynareOptions.particle.IS_approximation_method,'unscented') + [nodes3,weights3,weights_c3] = unscented_sigma_points(numb,DynareOptions) ; +end + +epsilon = bsxfun(@plus,StructuralShocksSqrtP*nodes3(:,number_of_state_variables+1:number_of_state_variables+number_of_structural_innovations)',StructuralShocksMu) ; +StateVectors = bsxfun(@plus,StateSqrtP*nodes3(:,1:number_of_state_variables)',StateMu); +%ObservationShocks = bsxfun(@plus,ObservationShocksSqrtP*nodes3(:,1+number_of_state_variables+number_of_structural_innovations:number_of_state_variables+number_of_structural_innovations+number_of_observed_variables)',ObservationShocksMu) ; + +yhat = bsxfun(@minus,StateVectors,state_variables_steady_state) ; +tmp = local_state_space_iteration_2(yhat,epsilon,ghx,ghu,constant,ghxx,ghuu,ghxu,DynareOptions.threads.local_state_space_iteration_2); +PredictedStateMean = tmp(mf0,:)*weights3; +PredictedObservedMean = tmp(mf1,:)*weights3; + +if strcmpi(DynareOptions.particle.IS_approximation_method,'cubature') + PredictedStateMean = sum(PredictedStateMean,2) ; + PredictedObservedMean = sum(PredictedObservedMean,2) ; + dState = (bsxfun(@minus,tmp(mf0,:),PredictedStateMean)').*sqrt(weights3) ; + dObserved = (bsxfun(@minus,tmp(mf1,:),PredictedObservedMean)').*sqrt(weights3); + PredictedStateVariance = dState'*dState; + big_mat = [dObserved dState ; [H_lower_triangular_cholesky zeros(number_of_observed_variables,number_of_state_variables)] ] ; + [mat1,mat] = qr2(big_mat) ; + mat = mat' ; + clear('mat1'); + PredictedObservedVarianceSquareRoot = mat(1:number_of_observed_variables,1:number_of_observed_variables) ; + CovarianceObservedStateSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),1:number_of_observed_variables) ; + StateVectorVarianceSquareRoot = mat(number_of_observed_variables+(1:number_of_state_variables),number_of_observed_variables+(1:number_of_state_variables)) ; + iPredictedObservedVarianceSquareRoot = inv(PredictedObservedVarianceSquareRoot); + iPredictedObservedVariance = iPredictedObservedVarianceSquareRoot'*iPredictedObservedVarianceSquareRoot ; + sqrdet = 1/sqrt(det(iPredictedObservedVariance)) ; + PredictionError = obs - PredictedObservedMean ; + StateVectorMean = PredictedStateMean + CovarianceObservedStateSquareRoot*iPredictedObservedVarianceSquareRoot*PredictionError; +end +if strcmpi(DynareOptions.particle.IS_approximation_method,'quadrature') || ... + strcmpi(DynareOptions.particle.IS_approximation_method,'unscented') + dState = bsxfun(@minus,tmp(mf0,:),PredictedStateMean); + dObserved = bsxfun(@minus,tmp(mf1,:),PredictedObservedMean); + PredictedStateVariance = dState*diag(weights_c3)*dState'; + PredictedObservedVariance = dObserved*diag(weights_c3)*dObserved' + H; + PredictedStateAndObservedCovariance = dState*diag(weights_c3)*dObserved'; + sqrdet = sqrt(det(PredictedObservedVariance)) ; + iPredictedObservedVariance = inv(PredictedObservedVariance); + PredictionError = obs - PredictedObservedMean; + KalmanFilterGain = PredictedStateAndObservedCovariance*iPredictedObservedVariance; + StateVectorMean = PredictedStateMean + KalmanFilterGain*PredictionError; + StateVectorVariance = PredictedStateVariance - KalmanFilterGain*PredictedObservedVariance*KalmanFilterGain'; + StateVectorVariance = .5*(StateVectorVariance+StateVectorVariance'); + StateVectorVarianceSquareRoot = reduced_rank_cholesky(StateVectorVariance)'; +end + +data_lik_GM_g = exp(-0.5*PredictionError'*iPredictedObservedVariance*PredictionError)/abs(normfactO*sqrdet) + 1e-99; +StateMuPrior = PredictedStateMean ; +StateSqrtPPrior = reduced_rank_cholesky(PredictedStateVariance)' ; +StateWeightsPrior = StateWeights*StructuralShocksWeights ; +StateMuPost = StateVectorMean ; +StateSqrtPPost = StateVectorVarianceSquareRoot ; +StateWeightsPost = StateWeightsPrior*ObservationShocksWeights*data_lik_GM_g ; -- GitLab