diff --git a/matlab/dyn_risky_steadystate_solver.m b/matlab/dyn_risky_steadystate_solver.m index fc559af49bff666afacef8668b7afd3e04e7922b..dd6ad0832298b2842ac5336763e75f99fd37ae85 100644 --- a/matlab/dyn_risky_steadystate_solver.m +++ b/matlab/dyn_risky_steadystate_solver.m @@ -86,8 +86,6 @@ order_var = dr.order_var; endo_nbr = M.endo_nbr; exo_nbr = M.exo_nbr; -M.var_order_endo_names = M.endo_names(dr.order_var); - [~,dr.i_fwrd_g,i_fwrd_f] = find(lead_lag_incidence(3,order_var)); dr.i_fwrd_f = i_fwrd_f; nd = nnz(lead_lag_incidence) + M.exo_nbr; @@ -508,7 +506,6 @@ M_np.endo_names = M.endo_names(v_np); dr_np = struct(); dr_np = set_state_space(dr_np,M_np,options); pm.dr_np = dr_np; -M_np.var_order_endo_names = M_np.endo_names(dr_np.order_var); pm.M_np = M_np; pm.i_fwrd_g = find(lead_lag_incidence_np(lead_index,dr_np.order_var)'); diff --git a/matlab/k_order_pert.m b/matlab/k_order_pert.m index 0fb758448a29117f4166b99b9d06c459bd39bae9..44e40c53ea866caa5b556304311ae76a92736000 100644 --- a/matlab/k_order_pert.m +++ b/matlab/k_order_pert.m @@ -20,8 +20,6 @@ function [dr,info] = k_order_pert(dr,M,options) info = 0; -M.var_order_endo_names = M.endo_names(dr.order_var); - order = options.order; if order>1 && options.loglinear diff --git a/mex/sources/k_order_perturbation/k_ord_dynare.cc b/mex/sources/k_order_perturbation/k_ord_dynare.cc index 744bc0519f2635b2d547da0397b726a42852ee6c..a4f5c5104addb7170f899cd15eb05a6a02a249e0 100644 --- a/mex/sources/k_order_perturbation/k_ord_dynare.cc +++ b/mex/sources/k_order_perturbation/k_ord_dynare.cc @@ -25,14 +25,13 @@ #include <utility> - KordpDynare::KordpDynare(const std::vector<std::string> &endo, const std::vector<std::string> &exo, int nexog, int npar, Vector &ysteady, TwoDMatrix &vcov, Vector &inParams, int nstat, int npred, int nforw, int nboth, const Vector &nnzd, int nsteps, int norder, Journal &jr, std::unique_ptr<DynamicModelAC> dynamicModelFile_arg, - const std::vector<int> &var_order, const TwoDMatrix &llincidence, + const std::vector<int> &dr_order, const TwoDMatrix &llincidence, std::unique_ptr<TwoDMatrix> g1_arg, std::unique_ptr<TwoDMatrix> g2_arg, std::unique_ptr<TwoDMatrix> g3_arg) : nStat{nstat}, nBoth{nboth}, nPred{npred}, nForw{nforw}, nExog{nexog}, nPar{npar}, @@ -44,7 +43,7 @@ KordpDynare::KordpDynare(const std::vector<std::string> &endo, g1p{std::move(g1_arg)}, g2p{std::move(g2_arg)}, g3p{std::move(g3_arg)}, dynamicModelFile{std::move(dynamicModelFile_arg)} { - computeJacobianPermutation(var_order); + computeJacobianPermutation(dr_order); } void @@ -195,63 +194,56 @@ KordpDynare::LLxSteady(const Vector &yS, Vector &llxSteady) llxSteady[static_cast<int>(ll_Incidence.get(ll_row, i))-1] = yS[i]; } -/************************************ - * Reorder DynareJacobianIndices of variables in a vector according to - * given int * varOrder together with lead & lag incidence matrix and - * any the extra columns for exogenous vars, and then, - * reorders its blocks given by the varOrder and the Dynare++ expectations: - - * extra nboth+ npred (t-1) lags - * varOrder - static: - pred - both - forward - * extra both + nforw (t+1) leads, and - * extra exogen - - * so to match the jacobian organisation expected by the Appoximation class - both + nforw (t+1) leads - static - pred - both - forward - nboth+ npred (t-1) lags - exogen -************************************/ - +/* + Computes mapping between Dynare and Dynare++ orderings of the (dynamic) + variable indices in derivatives. + + If one defines: + – y (resp. x) as the vector of all endogenous (size nY), in DR-order (resp. + declaration order) + – y⁻ (resp. x⁻) as the vector of endogenous that appear at previous period (size nYs), + in DR-order (resp. declaration order) + – y⁺ (resp. x⁺) as the vector of endogenous that appear at future period (size nYss) in + DR-order (resp. declaration order) + – u as the vector of exogenous (size nExog) + + In Dynare, the ordering is (x⁻, x, x⁺, u). + In Dynare++, the ordering is (y⁺, y, y⁻, u). + + dr_order is typically equal to M_.order_var. +*/ void -KordpDynare::computeJacobianPermutation(const std::vector<int> &var_order) +KordpDynare::computeJacobianPermutation(const std::vector<int> &dr_order) { + // Compute restricted inverse DR-orderings: x⁻→y⁻ and x⁺→y⁺ + std::vector<int> dr_inv_order_forw(nBoth+nForw), dr_inv_order_pred(nBoth+nPred); + std::iota(dr_inv_order_forw.begin(), dr_inv_order_forw.end(), 0); + std::sort(dr_inv_order_forw.begin(), dr_inv_order_forw.end(), + [&](int i, int j) { return dr_order[nStat+nPred+i] < dr_order[nStat+nPred+j]; }); + std::iota(dr_inv_order_pred.begin(), dr_inv_order_pred.end(), 0); + std::sort(dr_inv_order_pred.begin(), dr_inv_order_pred.end(), + [&](int i, int j) { return dr_order[nStat+i] < dr_order[nStat+j]; }); + + // Compute restricted DR-orderings: y⁻→x⁻ and y⁺→x⁺ + std::vector<int> dr_order_forw(nBoth+nForw), dr_order_pred(nBoth+nPred); + for (int i = 0; i < nBoth+nForw; i++) + dr_order_forw[dr_inv_order_forw[i]] = i; + for (int i = 0; i < nBoth+nPred; i++) + dr_order_pred[dr_inv_order_pred[i]] = i; + + // Compute Dynare++ → Dynare ordering dynppToDyn.resize(nJcols); - // create temporary square 2D matrix size nEndo×nEndo (sparse) - // for the lag, current and lead blocks of the jacobian - std::vector<int> tmp(nY); - int rjoff = nJcols-nExog-1; - - for (int ll_row = 0; ll_row < ll_Incidence.nrows(); ll_row++) - { - // reorder in orde-var order & populate temporary nEndo (sparse) vector with - // the lag, current and lead blocks of the jacobian respectively - for (int i = 0; i < nY; i++) - tmp[i] = static_cast<int>(ll_Incidence.get(ll_row, var_order[i]-1)); - // write the reordered blocks back to the jacobian - // in reverse order - for (int j = nY-1; j >= 0; j--) - if (tmp[j]) - { - dynppToDyn[rjoff] = tmp[j]-1; - rjoff--; - if (rjoff < 0) - break; - } - } - - //add the indices for the nExog exogenous jacobians - for (int j = nJcols-nExog; j < nJcols; j++) - dynppToDyn[j] = j; - - // Compute reverse ordering + int j = 0; + for (; j < nYss; j++) + dynppToDyn[j] = dr_order_forw[j]+nYs+nY; // Forward variables + for (; j < nYss+nY; j++) + dynppToDyn[j] = dr_order[j-nYss]+nYs; // Variables in current period + for (; j < nYss+nY+nYs; j++) + dynppToDyn[j] = dr_order_pred[j-nY-nYss]; // Predetermined variables + for (; j < nJcols; j++) + dynppToDyn[j] = j; // Exogenous + + // Compute Dynare → Dynare++ ordering dynToDynpp.resize(nJcols); for (int i = 0; i < nJcols; i++) dynToDynpp[dynppToDyn[i]] = i; diff --git a/mex/sources/k_order_perturbation/k_order_perturbation.cc b/mex/sources/k_order_perturbation/k_order_perturbation.cc index 438eba56fff4449d4582d7a8bcb494c495547644..5342ba419817ab0a95c4d263af2df7665996d395 100644 --- a/mex/sources/k_order_perturbation/k_order_perturbation.cc +++ b/mex/sources/k_order_perturbation/k_order_perturbation.cc @@ -136,14 +136,12 @@ extern "C" { const int nPar = static_cast<int>(mxGetScalar(mxFldp)); mxFldp = mxGetField(dr, 0, "order_var"); - auto dparams = mxGetPr(mxFldp); npar = static_cast<int>(mxGetM(mxFldp)); if (npar != nEndo) DYN_MEX_FUNC_ERR_MSG_TXT("Incorrect number of input var_order vars."); - - std::vector<int> var_order_vp(nEndo); - for (int v = 0; v < nEndo; v++) - var_order_vp[v] = static_cast<int>(*(dparams++)); + std::vector<int> dr_order(nEndo); + std::transform(mxGetPr(mxFldp), mxGetPr(mxFldp)+npar, dr_order.begin(), + [](double x) { return static_cast<int>(x)-1; }); // the lag, current and lead blocks of the jacobian respectively mxFldp = mxGetField(M_, 0, "lead_lag_incidence"); @@ -160,7 +158,7 @@ extern "C" { if (NNZD[kOrder-1] == -1) DYN_MEX_FUNC_ERR_MSG_TXT("The derivatives were not computed for the required order. Make sure that you used the right order option inside the 'stoch_simul' command"); - mxFldp = mxGetField(M_, 0, "var_order_endo_names"); + mxFldp = mxGetField(M_, 0, "endo_names"); std::vector<std::string> endoNames = DynareMxArrayToString(mxFldp); mxFldp = mxGetField(M_, 0, "exo_names"); @@ -212,7 +210,7 @@ extern "C" { KordpDynare dynare(endoNames, exoNames, nExog, nPar, ySteady, vCov, modParams, nStat, nPred, nForw, nBoth, NNZD, nSteps, kOrder, journal, std::move(dynamicModelFile), - var_order_vp, llincidence, + dr_order, llincidence, std::move(g1m), std::move(g2m), std::move(g3m)); // construct main K-order approximation class