local_state_space_iteration_k MEX: fix bug in output
In its output, the MEX was returning values for all endogenous variables, but it was used in a context where only the variables from oo_.dr.restrict_var_list were expected (as is done with local_state_space_iteration_2 MEX). This commit fixes this discrepancy, and also fixes the test that was checking that both MEX are returning the same output. Closes: #1768time-shift
parent
4c15bce48e
commit
c9eb6920c9
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright © 2019 Dynare Team
|
* Copyright © 2019-2021 Dynare Team
|
||||||
*
|
*
|
||||||
* This file is part of Dynare.
|
* This file is part of Dynare.
|
||||||
*
|
*
|
||||||
|
@ -41,15 +41,16 @@ struct ParticleWorker : public sthread::detach_thread
|
||||||
const ConstGeneralMatrix &yhat, ε
|
const ConstGeneralMatrix &yhat, ε
|
||||||
const Vector &ys_reordered;
|
const Vector &ys_reordered;
|
||||||
const UnfoldDecisionRule &dr;
|
const UnfoldDecisionRule &dr;
|
||||||
|
const ConstVector &restrict_var_list;
|
||||||
GeneralMatrix &ynext;
|
GeneralMatrix &ynext;
|
||||||
|
|
||||||
ParticleWorker(int npred_both_arg, int exo_nbr_arg, std::pair<size_t, size_t> particle_range_arg,
|
ParticleWorker(int npred_both_arg, int exo_nbr_arg, std::pair<size_t, size_t> particle_range_arg,
|
||||||
const ConstGeneralMatrix &yhat_arg, const ConstGeneralMatrix &epsilon_arg,
|
const ConstGeneralMatrix &yhat_arg, const ConstGeneralMatrix &epsilon_arg,
|
||||||
const Vector &ys_reordered_arg, const UnfoldDecisionRule &dr_arg,
|
const Vector &ys_reordered_arg, const UnfoldDecisionRule &dr_arg,
|
||||||
GeneralMatrix &ynext_arg)
|
const ConstVector &restrict_var_list_arg, GeneralMatrix &ynext_arg)
|
||||||
: npred_both{npred_both_arg}, exo_nbr{exo_nbr_arg}, particle_range{std::move(particle_range_arg)},
|
: npred_both{npred_both_arg}, exo_nbr{exo_nbr_arg}, particle_range{std::move(particle_range_arg)},
|
||||||
yhat{yhat_arg}, epsilon{epsilon_arg}, ys_reordered{ys_reordered_arg}, dr{dr_arg},
|
yhat{yhat_arg}, epsilon{epsilon_arg}, ys_reordered{ys_reordered_arg}, dr{dr_arg},
|
||||||
ynext{ynext_arg}
|
restrict_var_list{restrict_var_list_arg}, ynext{ynext_arg}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
|
@ -58,16 +59,22 @@ struct ParticleWorker : public sthread::detach_thread
|
||||||
Vector dyu(npred_both+exo_nbr);
|
Vector dyu(npred_both+exo_nbr);
|
||||||
Vector dy(dyu, 0, npred_both);
|
Vector dy(dyu, 0, npred_both);
|
||||||
Vector u(dyu, npred_both, exo_nbr);
|
Vector u(dyu, npred_both, exo_nbr);
|
||||||
|
Vector ynext_col_allvars(ys_reordered.length());
|
||||||
|
|
||||||
for (size_t i = particle_range.first; i < particle_range.second; i++)
|
for (size_t i = particle_range.first; i < particle_range.second; i++)
|
||||||
{
|
{
|
||||||
dy = yhat.getCol(i);
|
dy = yhat.getCol(i);
|
||||||
u = epsilon.getCol(i);
|
u = epsilon.getCol(i);
|
||||||
|
|
||||||
|
dr.eval(DecisionRule::emethod::horner, ynext_col_allvars, dyu);
|
||||||
|
|
||||||
|
ynext_col_allvars.add(1.0, ys_reordered);
|
||||||
|
|
||||||
|
/* Select only the variables in restrict_var_list, and copy back to the
|
||||||
|
result matrix */
|
||||||
Vector ynext_col{ynext.getCol(i)};
|
Vector ynext_col{ynext.getCol(i)};
|
||||||
|
for (int j = 0; j < restrict_var_list.length(); j++)
|
||||||
dr.eval(DecisionRule::emethod::horner, ynext_col, dyu);
|
ynext_col[j] = ynext_col_allvars[restrict_var_list[j]-1];
|
||||||
|
|
||||||
ynext_col.add(1.0, ys_reordered);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -107,6 +114,9 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
const mxArray *ys_mx = mxGetField(dr_mx, 0, "ys");
|
const mxArray *ys_mx = mxGetField(dr_mx, 0, "ys");
|
||||||
if (!ys_mx || !mxIsDouble(ys_mx) || mxGetNumberOfElements(ys_mx) != static_cast<size_t>(endo_nbr))
|
if (!ys_mx || !mxIsDouble(ys_mx) || mxGetNumberOfElements(ys_mx) != static_cast<size_t>(endo_nbr))
|
||||||
mexErrMsgTxt("Field dr.ys should be a double precision vector with endo_nbr elements");
|
mexErrMsgTxt("Field dr.ys should be a double precision vector with endo_nbr elements");
|
||||||
|
const mxArray *restrict_var_list_mx = mxGetField(dr_mx, 0, "restrict_var_list");
|
||||||
|
if (!(restrict_var_list_mx && mxIsDouble(restrict_var_list_mx)))
|
||||||
|
mexErrMsgTxt("Field dr.restrict_var_list should be a double precision vector");
|
||||||
|
|
||||||
size_t nparticles = mxGetN(yhat_mx);
|
size_t nparticles = mxGetN(yhat_mx);
|
||||||
if (mxGetN(epsilon_mx) != nparticles)
|
if (mxGetN(epsilon_mx) != nparticles)
|
||||||
|
@ -125,6 +135,7 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
ConstGeneralMatrix epsilon{epsilon_mx};
|
ConstGeneralMatrix epsilon{epsilon_mx};
|
||||||
ConstVector ys{ys_mx};
|
ConstVector ys{ys_mx};
|
||||||
const double *order_var = mxGetPr(order_var_mx);
|
const double *order_var = mxGetPr(order_var_mx);
|
||||||
|
ConstVector restrict_var_list{restrict_var_list_mx};
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -163,7 +174,7 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
exo_nbr, ys_reordered);
|
exo_nbr, ys_reordered);
|
||||||
|
|
||||||
// Create the result matrix
|
// Create the result matrix
|
||||||
plhs[0] = mxCreateDoubleMatrix(endo_nbr, nparticles, mxREAL);
|
plhs[0] = mxCreateDoubleMatrix(restrict_var_list.length(), nparticles, mxREAL);
|
||||||
GeneralMatrix ynext{plhs[0]};
|
GeneralMatrix ynext{plhs[0]};
|
||||||
|
|
||||||
// Run the real job in parallel
|
// Run the real job in parallel
|
||||||
|
@ -174,6 +185,7 @@ mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
for (size_t i = 0; i < nparticles; i += part_by_thread)
|
for (size_t i = 0; i < nparticles; i += part_by_thread)
|
||||||
group.insert(std::make_unique<ParticleWorker>(npred+nboth, exo_nbr,
|
group.insert(std::make_unique<ParticleWorker>(npred+nboth, exo_nbr,
|
||||||
std::make_pair(i, std::min(i+part_by_thread, nparticles)),
|
std::make_pair(i, std::min(i+part_by_thread, nparticles)),
|
||||||
yhat, epsilon, ys_reordered, dr, ynext));
|
yhat, epsilon, ys_reordered, dr, restrict_var_list,
|
||||||
|
ynext));
|
||||||
group.run();
|
group.run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -825,6 +825,10 @@ discretionary_policy/dennis_1_estim.o.trs: discretionary_policy/dennis_1.o.trs
|
||||||
discretionary_policy/Gali_2015_chapter_3_nonlinear.m.trs: discretionary_policy/Gali_2015_chapter_3.m.trs
|
discretionary_policy/Gali_2015_chapter_3_nonlinear.m.trs: discretionary_policy/Gali_2015_chapter_3.m.trs
|
||||||
discretionary_policy/Gali_2015_chapter_3_nonlinear.o.trs: discretionary_policy/Gali_2015_chapter_3.o.trs
|
discretionary_policy/Gali_2015_chapter_3_nonlinear.o.trs: discretionary_policy/Gali_2015_chapter_3.o.trs
|
||||||
|
|
||||||
|
particle/local_state_space_iteration_k_test.m.trs: particle/first_spec.m.trs
|
||||||
|
particle/local_state_space_iteration_k_test.o.trs: particle/first_spec.o.trs
|
||||||
|
|
||||||
|
|
||||||
observation_trends_and_prefiltering/MCMC: m/observation_trends_and_prefiltering/MCMC o/observation_trends_and_prefiltering/MCMC
|
observation_trends_and_prefiltering/MCMC: m/observation_trends_and_prefiltering/MCMC o/observation_trends_and_prefiltering/MCMC
|
||||||
m/observation_trends_and_prefiltering/MCMC: $(patsubst %.mod, %.m.trs, $(filter observation_trends_and_prefiltering/MCMC/%.mod, $(MODFILES)))
|
m/observation_trends_and_prefiltering/MCMC: $(patsubst %.mod, %.m.trs, $(filter observation_trends_and_prefiltering/MCMC/%.mod, $(MODFILES)))
|
||||||
o/observation_trends_and_prefiltering/MCMC: $(patsubst %.mod, %.o.trs, $(filter observation_trends_and_prefiltering/MCMC/%.mod, $(MODFILES)))
|
o/observation_trends_and_prefiltering/MCMC: $(patsubst %.mod, %.o.trs, $(filter observation_trends_and_prefiltering/MCMC/%.mod, $(MODFILES)))
|
||||||
|
|
|
@ -1,51 +1,29 @@
|
||||||
/*
|
/*
|
||||||
Tests that local_state_space_iteration_2 and local_state_space_iteration_k
|
Tests that local_state_space_iteration_2 and local_state_space_iteration_k
|
||||||
(for k=2) return the same results.
|
(for k=2) return the same results.
|
||||||
|
|
||||||
|
This file must be run after first_spec.mod (both are based on the same model).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var y, k, a, h, b, c;
|
@#include "first_spec_common.inc"
|
||||||
varexo e, u;
|
|
||||||
|
|
||||||
parameters beta, rho, alpha, delta, theta, psi, tau;
|
varobs q ca;
|
||||||
|
|
||||||
alpha = 0.36;
|
|
||||||
rho = 0.95;
|
|
||||||
tau = 0.025;
|
|
||||||
beta = 0.99;
|
|
||||||
delta = 0.025;
|
|
||||||
psi = 0;
|
|
||||||
theta = 2.95;
|
|
||||||
|
|
||||||
phi = 0.1;
|
|
||||||
|
|
||||||
model;
|
|
||||||
c*theta*h^(1+psi)=(1-alpha)*y;
|
|
||||||
k = beta*(((exp(b)*c)/(exp(b(+1))*c(+1)))
|
|
||||||
*(exp(b(+1))*alpha*y(+1)+(1-delta)*k));
|
|
||||||
y = exp(a)*(k(-1)^alpha)*(h^(1-alpha));
|
|
||||||
k = exp(b)*(y-c)+(1-delta)*k(-1);
|
|
||||||
a = rho*a(-1)+tau*b(-1) + e;
|
|
||||||
b = tau*a(-1)+rho*b(-1) + u;
|
|
||||||
end;
|
|
||||||
|
|
||||||
initval;
|
|
||||||
y = 1.08068253095672;
|
|
||||||
c = 0.80359242014163;
|
|
||||||
h = 0.29175631001732;
|
|
||||||
k = 11.08360443260358;
|
|
||||||
a = 0;
|
|
||||||
b = 0;
|
|
||||||
e = 0;
|
|
||||||
u = 0;
|
|
||||||
end;
|
|
||||||
|
|
||||||
shocks;
|
shocks;
|
||||||
var e; stderr 0.009;
|
var eeps = 0.04^2;
|
||||||
var u; stderr 0.009;
|
var nnu = 0.03^2;
|
||||||
var e, u = phi*0.009*0.009;
|
var q = 0.01^2;
|
||||||
|
var ca = 0.01^2;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
stoch_simul(order=2, irf=0, k_order_solver);
|
// Initialize various structures
|
||||||
|
estimation(datafile='my_data.mat',order=2,mode_compute=0,mh_replic=0,filter_algorithm=sis,nonlinear_filter_initialization=2
|
||||||
|
,cova_compute=0 %tell program that no covariance matrix was computed
|
||||||
|
);
|
||||||
|
|
||||||
|
stoch_simul(order=2, periods=200, irf=0, k_order_solver);
|
||||||
|
|
||||||
|
// Really perform the test
|
||||||
|
|
||||||
nparticles = 100;
|
nparticles = 100;
|
||||||
|
|
||||||
|
@ -57,7 +35,16 @@ epsilon = chol(M_.Sigma_e)*randn(M_.exo_nbr, nparticles);
|
||||||
|
|
||||||
dr = oo_.dr;
|
dr = oo_.dr;
|
||||||
|
|
||||||
tStart1 = tic; for i=1:10000, ynext1 = local_state_space_iteration_2(yhat, epsilon, dr.ghx, dr.ghu, dr.ys(dr.order_var)+0.5*dr.ghs2, dr.ghxx, dr.ghuu, dr.ghxu, 1); end, tElapsed1 = toc(tStart1);
|
// “rf” stands for “Reduced Form”
|
||||||
|
rf_ghx = dr.ghx(dr.restrict_var_list, :);
|
||||||
|
rf_ghu = dr.ghu(dr.restrict_var_list, :);
|
||||||
|
rf_constant = dr.ys(dr.order_var)+0.5*dr.ghs2;
|
||||||
|
rf_constant = rf_constant(dr.restrict_var_list, :);
|
||||||
|
rf_ghxx = dr.ghxx(dr.restrict_var_list, :);
|
||||||
|
rf_ghuu = dr.ghuu(dr.restrict_var_list, :);
|
||||||
|
rf_ghxu = dr.ghxu(dr.restrict_var_list, :);
|
||||||
|
|
||||||
|
tStart1 = tic; for i=1:10000, ynext1 = local_state_space_iteration_2(yhat, epsilon, rf_ghx, rf_ghu, rf_constant, rf_ghxx, rf_ghuu, rf_ghxu, 1); end, tElapsed1 = toc(tStart1);
|
||||||
|
|
||||||
tStart2 = tic; for i=1:10000, ynext2 = local_state_space_iteration_k(yhat, epsilon, dr, M_, options_); end, tElapsed2 = toc(tStart2);
|
tStart2 = tic; for i=1:10000, ynext2 = local_state_space_iteration_k(yhat, epsilon, dr, M_, options_); end, tElapsed2 = toc(tStart2);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue