2009-04-14 16:39:53 +02:00
|
|
|
/*
|
2019-04-16 11:35:31 +02:00
|
|
|
* Copyright © 2003-2019 Dynare Team
|
2009-04-14 16:39:53 +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/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _DYNAMICMODEL_HH
|
|
|
|
#define _DYNAMICMODEL_HH
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
2009-07-06 12:36:36 +02:00
|
|
|
#include <fstream>
|
2019-04-04 17:01:37 +02:00
|
|
|
#include <filesystem>
|
2018-10-26 11:44:26 +02:00
|
|
|
|
2009-04-14 16:39:53 +02:00
|
|
|
#include "StaticModel.hh"
|
|
|
|
|
|
|
|
//! Stores a dynamic model
|
|
|
|
class DynamicModel : public ModelTree
|
|
|
|
{
|
2018-09-14 17:04:06 +02:00
|
|
|
public:
|
|
|
|
//! A reference to the trend component model table
|
|
|
|
TrendComponentModelTable &trend_component_model_table;
|
|
|
|
//! A reference to the VAR model table
|
|
|
|
VarModelTable &var_model_table;
|
2019-11-14 17:51:16 +01:00
|
|
|
/* Used in the balanced growth test, for determining whether the
|
|
|
|
cross-derivative of a given equation, w.r.t. an endogenous and a trend
|
|
|
|
variable is zero. Controlled by option “balanced_growth_test_tol” of the
|
|
|
|
“model” block. The default should not be too small (see dynare#1389). */
|
|
|
|
double balanced_growth_test_tol{1e-6};
|
2009-04-14 16:39:53 +02:00
|
|
|
private:
|
2019-11-14 17:51:16 +01:00
|
|
|
/* Used in the balanced growth test, for skipping equations where the test
|
|
|
|
cannot be performed (i.e. when LHS=RHS at the initial values). Should not
|
|
|
|
be too large, otherwise the test becomes less powerful. */
|
2018-07-17 16:32:00 +02:00
|
|
|
constexpr static double zero_band{1e-8};
|
|
|
|
|
2013-04-11 17:07:39 +02:00
|
|
|
//! Stores equations declared as [static]
|
2018-10-10 17:08:54 +02:00
|
|
|
/*! They will be used in the conversion to StaticModel to replace equations marked as [dynamic] */
|
2013-04-11 17:07:39 +02:00
|
|
|
vector<BinaryOpNode *> static_only_equations;
|
|
|
|
|
2014-01-27 16:41:43 +01:00
|
|
|
//! Stores line numbers of equations declared as [static]
|
|
|
|
vector<int> static_only_equations_lineno;
|
|
|
|
|
2017-08-24 15:35:10 +02:00
|
|
|
//! Stores the equation tags of equations declared as [static]
|
2018-06-04 14:17:36 +02:00
|
|
|
vector<vector<pair<string, string>>> static_only_equations_equation_tags;
|
2017-08-24 15:35:10 +02:00
|
|
|
|
2019-11-18 17:13:49 +01:00
|
|
|
//! Stores mapping from equation tags to equation number
|
|
|
|
multimap<pair<string, string>, int> static_only_equation_tags_xref;
|
|
|
|
|
2018-06-04 14:31:26 +02:00
|
|
|
using deriv_id_table_t = map<pair<int, int>, int>;
|
2009-04-17 18:26:23 +02:00
|
|
|
//! Maps a pair (symbol_id, lag) to a deriv ID
|
|
|
|
deriv_id_table_t deriv_id_table;
|
|
|
|
//! Maps a deriv ID to a pair (symbol_id, lag)
|
2018-06-04 14:17:36 +02:00
|
|
|
vector<pair<int, int>> inv_deriv_id_table;
|
2009-04-17 18:26:23 +02:00
|
|
|
|
|
|
|
//! Maps a deriv_id to the column index of the dynamic Jacobian
|
|
|
|
/*! Contains only endogenous, exogenous and exogenous deterministic */
|
|
|
|
map<int, int> dyn_jacobian_cols_table;
|
|
|
|
|
|
|
|
//! Maximum lag and lead over all types of variables (positive values)
|
2009-09-30 17:10:31 +02:00
|
|
|
/*! Set by computeDerivIDs() */
|
2018-10-04 17:18:27 +02:00
|
|
|
int max_lag{0}, max_lead{0};
|
2009-04-17 18:26:23 +02:00
|
|
|
//! Maximum lag and lead over endogenous variables (positive values)
|
2009-09-30 17:10:31 +02:00
|
|
|
/*! Set by computeDerivIDs() */
|
2018-10-04 17:18:27 +02:00
|
|
|
int max_endo_lag{0}, max_endo_lead{0};
|
2009-04-17 18:26:23 +02:00
|
|
|
//! Maximum lag and lead over exogenous variables (positive values)
|
2009-09-30 17:10:31 +02:00
|
|
|
/*! Set by computeDerivIDs() */
|
2018-10-04 17:18:27 +02:00
|
|
|
int max_exo_lag{0}, max_exo_lead{0};
|
2009-04-17 18:26:23 +02:00
|
|
|
//! Maximum lag and lead over deterministic exogenous variables (positive values)
|
2009-09-30 17:10:31 +02:00
|
|
|
/*! Set by computeDerivIDs() */
|
2018-10-04 17:18:27 +02:00
|
|
|
int max_exo_det_lag{0}, max_exo_det_lead{0};
|
2017-07-27 18:33:19 +02:00
|
|
|
//! Maximum lag and lead over all types of variables (positive values) of original model
|
2018-12-11 17:26:50 +01:00
|
|
|
int max_lag_orig{0}, max_lead_orig{0}, max_lag_with_diffs_expanded_orig{0};
|
2017-07-27 18:33:19 +02:00
|
|
|
//! Maximum lag and lead over endogenous variables (positive values) of original model
|
2018-10-04 17:18:27 +02:00
|
|
|
int max_endo_lag_orig{0}, max_endo_lead_orig{0};
|
2017-07-27 18:33:19 +02:00
|
|
|
//! Maximum lag and lead over exogenous variables (positive values) of original model
|
2018-10-04 17:18:27 +02:00
|
|
|
int max_exo_lag_orig{0}, max_exo_lead_orig{0};
|
2017-07-27 18:33:19 +02:00
|
|
|
//! Maximum lag and lead over deterministic exogenous variables (positive values) of original model
|
2018-10-04 17:18:27 +02:00
|
|
|
int max_exo_det_lag_orig{0}, max_exo_det_lead_orig{0};
|
2009-04-17 18:26:23 +02:00
|
|
|
|
2017-03-06 16:34:08 +01:00
|
|
|
//! Cross reference information
|
|
|
|
map<int, ExprNode::EquationInfo> xrefs;
|
2018-06-04 14:17:36 +02:00
|
|
|
map<pair<int, int>, set<int>> xref_param;
|
|
|
|
map<pair<int, int>, set<int>> xref_endo;
|
|
|
|
map<pair<int, int>, set<int>> xref_exo;
|
|
|
|
map<pair<int, int>, set<int>> xref_exo_det;
|
2017-03-06 16:34:08 +01:00
|
|
|
|
2018-01-11 12:55:36 +01:00
|
|
|
//! Nonzero equations in the Hessian
|
2019-12-13 17:15:03 +01:00
|
|
|
set<int> nonzero_hessian_eqs;
|
|
|
|
//! Whether the hessian has actually been computed
|
|
|
|
bool hessian_computed{false};
|
2018-01-11 12:55:36 +01:00
|
|
|
|
2009-04-20 12:48:54 +02:00
|
|
|
//! Number of columns of dynamic jacobian
|
2009-09-30 17:10:31 +02:00
|
|
|
/*! Set by computeDerivID()s and computeDynJacobianCols() */
|
2018-10-04 17:18:27 +02:00
|
|
|
int dynJacobianColsNbr{0};
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Temporary terms for block decomposed models
|
2019-12-16 19:42:59 +01:00
|
|
|
vector<vector<temporary_terms_t>> v_temporary_terms;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
2010-09-16 19:00:48 +02:00
|
|
|
vector<temporary_terms_inuse_t> v_temporary_terms_inuse;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
2019-10-16 17:34:27 +02:00
|
|
|
//! Creates mapping for variables and equations they are present in
|
|
|
|
map<int, set<int>> variableMapping;
|
|
|
|
|
2018-11-23 17:19:59 +01:00
|
|
|
//! Store the derivatives or the chainrule derivatives:map<tuple<equation, variable, lead_lag>, expr_t>
|
|
|
|
using first_chain_rule_derivatives_t = map<tuple<int, int, int>, expr_t>;
|
2010-09-16 19:00:48 +02:00
|
|
|
first_chain_rule_derivatives_t first_chain_rule_derivatives;
|
2015-12-01 11:41:55 +01:00
|
|
|
|
2009-04-14 16:39:53 +02:00
|
|
|
//! Writes dynamic model file (Matlab version)
|
2018-06-27 15:01:31 +02:00
|
|
|
void writeDynamicMFile(const string &basename) const;
|
2015-07-27 17:02:51 +02:00
|
|
|
//! Writes dynamic model file (Julia version)
|
|
|
|
void writeDynamicJuliaFile(const string &dynamic_basename) const;
|
2009-04-14 16:39:53 +02:00
|
|
|
//! Writes dynamic model file (C version)
|
|
|
|
/*! \todo add third derivatives handling */
|
2019-12-16 19:42:59 +01:00
|
|
|
void writeDynamicCFile(const string &basename, int order) const;
|
2009-04-14 16:39:53 +02:00
|
|
|
//! Writes dynamic model file when SparseDLL option is on
|
2018-06-27 15:01:31 +02:00
|
|
|
void writeSparseDynamicMFile(const string &basename) const;
|
2009-04-14 16:39:53 +02:00
|
|
|
//! Writes the dynamic model equations and its derivatives
|
|
|
|
/*! \todo add third derivatives handling in C output */
|
2015-07-27 17:02:51 +02:00
|
|
|
void writeDynamicModel(ostream &DynamicOutput, bool use_dll, bool julia) const;
|
2018-06-27 15:01:31 +02:00
|
|
|
void writeDynamicModel(const string &basename, bool use_dll, bool julia) const;
|
|
|
|
void writeDynamicModel(const string &basename, ostream &DynamicOutput, bool use_dll, bool julia) const;
|
2009-04-14 16:39:53 +02:00
|
|
|
//! Writes the Block reordred structure of the model in M output
|
2018-06-27 15:01:31 +02:00
|
|
|
void writeModelEquationsOrdered_M(const string &basename) const;
|
2009-04-14 16:39:53 +02:00
|
|
|
//! Writes the code of the Block reordred structure of the model in virtual machine bytecode
|
2019-12-16 19:42:59 +01:00
|
|
|
void writeModelEquationsCode_Block(const string &basename, const map_idx_t &map_idx, bool linear_decomposition) const;
|
2010-01-22 11:03:29 +01:00
|
|
|
//! Writes the code of the model in virtual machine bytecode
|
2018-06-27 15:01:31 +02:00
|
|
|
void writeModelEquationsCode(const string &basename, const map_idx_t &map_idx) const;
|
2010-01-22 11:03:29 +01:00
|
|
|
|
2019-12-16 19:42:59 +01:00
|
|
|
void writeSetAuxiliaryVariables(const string &basename, bool julia) const;
|
2018-03-02 17:50:35 +01:00
|
|
|
void writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const;
|
|
|
|
|
2009-04-14 16:39:53 +02:00
|
|
|
//! Computes jacobian and prepares for equation normalization
|
|
|
|
/*! Using values from initval/endval blocks and parameter initializations:
|
|
|
|
- computes the jacobian for the model w.r. to contemporaneous variables
|
|
|
|
- removes edges of the incidence matrix when derivative w.r. to the corresponding variable is too close to zero (below the cutoff)
|
|
|
|
*/
|
2010-09-16 19:00:48 +02:00
|
|
|
//void evaluateJacobian(const eval_context_t &eval_context, jacob_map *j_m, bool dynamic);
|
2009-12-16 14:21:31 +01:00
|
|
|
|
|
|
|
//! return a map on the block jacobian
|
2018-11-23 17:19:59 +01:00
|
|
|
map<tuple<int, int, int, int, int>, int> get_Derivatives(int block);
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Computes chain rule derivatives of the Jacobian w.r. to endogenous variables
|
2010-09-16 19:00:48 +02:00
|
|
|
void computeChainRuleJacobian(blocks_derivatives_t &blocks_derivatives);
|
2009-12-16 14:21:31 +01:00
|
|
|
|
2019-12-16 19:42:59 +01:00
|
|
|
string reform(const string &name) const;
|
2010-09-16 19:00:48 +02:00
|
|
|
map_idx_t map_idx;
|
2009-04-14 16:39:53 +02:00
|
|
|
|
2010-01-22 11:03:29 +01:00
|
|
|
//! sorts the temporary terms in the blocks order
|
2009-12-16 14:21:31 +01:00
|
|
|
void computeTemporaryTermsOrdered();
|
2010-01-22 11:03:29 +01:00
|
|
|
|
|
|
|
//! creates a mapping from the index of temporary terms to a natural index
|
|
|
|
void computeTemporaryTermsMapping();
|
2009-04-14 16:39:53 +02:00
|
|
|
//! Write derivative code of an equation w.r. to a variable
|
2010-07-23 11:20:24 +02:00
|
|
|
void compileDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int symb_id, int lag, const map_idx_t &map_idx) const;
|
2009-07-21 17:50:12 +02:00
|
|
|
//! Write chain rule derivative code of an equation w.r. to a variable
|
2010-07-23 11:20:24 +02:00
|
|
|
void compileChainRuleDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int var, int lag, const map_idx_t &map_idx) const;
|
2009-04-14 16:39:53 +02:00
|
|
|
|
2009-04-17 18:26:23 +02:00
|
|
|
//! Get the type corresponding to a derivation ID
|
2018-06-04 12:53:26 +02:00
|
|
|
SymbolType getTypeByDerivID(int deriv_id) const noexcept(false) override;
|
2009-04-17 18:26:23 +02:00
|
|
|
//! Get the lag corresponding to a derivation ID
|
2018-06-04 12:53:26 +02:00
|
|
|
int getLagByDerivID(int deriv_id) const noexcept(false) override;
|
2009-04-17 18:26:23 +02:00
|
|
|
//! Get the symbol ID corresponding to a derivation ID
|
2018-06-04 12:53:26 +02:00
|
|
|
int getSymbIDByDerivID(int deriv_id) const noexcept(false) override;
|
2009-04-17 18:26:23 +02:00
|
|
|
//! Compute the column indices of the dynamic Jacobian
|
2009-04-20 12:48:54 +02:00
|
|
|
void computeDynJacobianCols(bool jacobianExo);
|
2010-10-15 19:05:16 +02:00
|
|
|
//! Computes derivatives of the Jacobian w.r. to trend vars and tests that they are equal to zero
|
|
|
|
void testTrendDerivativesEqualToZero(const eval_context_t &eval_context);
|
2009-05-16 00:41:51 +02:00
|
|
|
//! Collect only the first derivatives
|
2018-11-23 17:19:59 +01:00
|
|
|
map<tuple<int, int, int>, expr_t> collect_first_order_derivatives_endogenous();
|
2009-05-13 01:03:40 +02:00
|
|
|
|
2009-09-30 17:10:31 +02:00
|
|
|
//! Allocates the derivation IDs for all dynamic variables of the model
|
|
|
|
/*! Also computes max_{endo,exo}_{lead_lag}, and initializes dynJacobianColsNbr to the number of dynamic endos */
|
|
|
|
void computeDerivIDs();
|
|
|
|
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Collecte the derivatives w.r. to endogenous of the block, to endogenous of previouys blocks and to exogenous
|
|
|
|
void collect_block_first_order_derivatives();
|
|
|
|
|
2010-07-23 11:20:24 +02:00
|
|
|
//! Collecte the informations about exogenous, deterministic exogenous and endogenous from the previous block for each block
|
|
|
|
void collectBlockVariables();
|
|
|
|
|
2009-10-07 16:07:13 +02:00
|
|
|
//! Factorized code for substitutions of leads/lags
|
2013-05-17 16:51:34 +02:00
|
|
|
/*! \param[in] type determines which type of variables is concerned
|
|
|
|
\param[in] deterministic_model whether we are in a deterministic model (only for exogenous leads/lags)
|
|
|
|
\param[in] subset variables to which to apply the transformation (only for diff of forward vars)
|
|
|
|
*/
|
2018-12-20 17:04:28 +01:00
|
|
|
void substituteLeadLagInternal(AuxVarType type, bool deterministic_model, const vector<string> &subset);
|
2009-07-10 17:37:51 +02:00
|
|
|
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Indicate if the temporary terms are computed for the overall model (true) or not (false). Default value true
|
2018-10-04 17:18:27 +02:00
|
|
|
bool global_temporary_terms{true};
|
2009-12-16 14:21:31 +01:00
|
|
|
|
2010-09-16 19:18:45 +02:00
|
|
|
//! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a expr_t on the new normalized equation
|
2010-09-16 19:00:48 +02:00
|
|
|
equation_type_and_normalized_equation_t equation_type_and_normalized_equation;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
2018-06-04 14:17:36 +02:00
|
|
|
//! for each block contains pair< Simulation_Type, pair < Block_Size, Recursive_part_Size >>
|
2010-09-16 19:00:48 +02:00
|
|
|
block_type_firstequation_size_mfs_t block_type_firstequation_size_mfs;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
|
|
|
//! for all blocks derivatives description
|
2010-09-16 19:00:48 +02:00
|
|
|
blocks_derivatives_t blocks_derivatives;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
|
|
|
//! The jacobian without the elements below the cutoff
|
2010-09-16 19:00:48 +02:00
|
|
|
dynamic_jacob_map_t dynamic_jacobian;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
|
|
|
//! Vector indicating if the block is linear in endogenous variable (true) or not (false)
|
|
|
|
vector<bool> blocks_linear;
|
|
|
|
|
2018-11-23 17:19:59 +01:00
|
|
|
//! Map the derivatives for a block tuple<lag, eq, var>
|
|
|
|
using derivative_t = map<tuple<int, int, int>, expr_t>;
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Vector of derivative for each blocks
|
2010-09-16 19:00:48 +02:00
|
|
|
vector<derivative_t> derivative_endo, derivative_other_endo, derivative_exo, derivative_exo_det;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
2010-07-23 11:20:24 +02:00
|
|
|
//!List for each block and for each lag-lead all the other endogenous variables and exogenous variables
|
2018-06-04 14:07:13 +02:00
|
|
|
using var_t = set<int>;
|
2018-06-04 14:31:26 +02:00
|
|
|
using lag_var_t = map<int, var_t>;
|
2010-09-16 19:00:48 +02:00
|
|
|
vector<lag_var_t> other_endo_block, exo_block, exo_det_block;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
2010-07-23 11:20:24 +02:00
|
|
|
//!List for each block the exogenous variables
|
2018-06-04 14:17:36 +02:00
|
|
|
vector<pair<var_t, int>> block_var_exo;
|
2010-07-23 11:20:24 +02:00
|
|
|
|
2018-06-04 14:17:36 +02:00
|
|
|
map< int, map<int, int>> block_exo_index, block_det_exo_index, block_other_endo_index;
|
2010-07-23 11:20:24 +02:00
|
|
|
|
|
|
|
//! for each block described the number of static, forward, backward and mixed variables in the block
|
2018-11-23 17:19:59 +01:00
|
|
|
/*! tuple<static, forward, backward, mixed> */
|
|
|
|
vector<tuple<int, int, int, int>> block_col_type;
|
2010-07-23 11:20:24 +02:00
|
|
|
|
2017-03-06 16:34:08 +01:00
|
|
|
//! Help computeXrefs to compute the reverse references (i.e. param->eqs, endo->eqs, etc)
|
2018-06-04 14:17:36 +02:00
|
|
|
void computeRevXref(map<pair<int, int>, set<int>> &xrefset, const set<pair<int, int>> &eiref, int eqn);
|
2017-03-06 16:34:08 +01:00
|
|
|
|
|
|
|
//! Write reverse cross references
|
2018-06-04 14:17:36 +02:00
|
|
|
void writeRevXrefs(ostream &output, const map<pair<int, int>, set<int>> &xrefmap, const string &type) const;
|
2017-03-06 16:34:08 +01:00
|
|
|
|
2010-07-23 11:20:24 +02:00
|
|
|
//! List for each variable its block number and its maximum lag and lead inside the block
|
2018-11-23 17:19:59 +01:00
|
|
|
vector<tuple<int, int, int>> variable_block_lead_lag;
|
2010-07-23 11:20:24 +02:00
|
|
|
//! List for each equation its block number
|
|
|
|
vector<int> equation_block;
|
|
|
|
|
2016-11-21 18:00:46 +01:00
|
|
|
//! Used for var_expectation and var_model
|
2018-06-04 14:17:36 +02:00
|
|
|
map<string, set<int>> var_expectation_functions_to_write;
|
2016-11-21 18:00:46 +01:00
|
|
|
|
2009-12-16 14:21:31 +01:00
|
|
|
//!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous
|
2018-06-04 14:17:36 +02:00
|
|
|
vector<pair<int, int>> endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
2018-03-27 17:14:30 +02:00
|
|
|
void writeWrapperFunctions(const string &name, const string &ending) const;
|
2018-06-27 15:01:31 +02:00
|
|
|
void writeDynamicModelHelper(const string &basename,
|
|
|
|
const string &name, const string &retvalname,
|
2018-03-27 17:14:30 +02:00
|
|
|
const string &name_tt, size_t ttlen,
|
|
|
|
const string &previous_tt_name,
|
|
|
|
const ostringstream &init_s,
|
|
|
|
const ostringstream &end_s,
|
|
|
|
const ostringstream &s, const ostringstream &s_tt) const;
|
|
|
|
|
2018-05-23 16:10:26 +02:00
|
|
|
//! Create a legacy *_dynamic.m file for Matlab/Octave not yet using the temporary terms array interface
|
2018-06-27 15:01:31 +02:00
|
|
|
void writeDynamicMatlabCompatLayer(const string &basename) const;
|
2018-05-23 16:10:26 +02:00
|
|
|
|
2019-08-19 14:51:21 +02:00
|
|
|
vector<int> getEquationNumbersFromTags(const set<string> &eqtags) const;
|
2018-06-05 18:38:53 +02:00
|
|
|
|
|
|
|
void findPacExpectationEquationNumbers(vector<int> &eqnumber) const;
|
|
|
|
|
2018-10-09 18:27:19 +02:00
|
|
|
//! Internal helper for the copy constructor and assignment operator
|
|
|
|
/*! Copies all the structures that contain ExprNode*, by the converting the
|
|
|
|
pointers into their equivalent in the new tree */
|
|
|
|
void copyHelper(const DynamicModel &m);
|
|
|
|
|
2019-11-18 17:13:49 +01:00
|
|
|
// Internal helper functions for includeExcludeEquations()
|
|
|
|
/*! Handles parsing of argument passed to exclude_eqs/include_eqs*/
|
|
|
|
/*
|
|
|
|
Expects command line arguments of the form:
|
|
|
|
* filename.txt
|
|
|
|
* eq1
|
|
|
|
* ['eq 1', 'eq 2']
|
|
|
|
* [tagname='eq 1']
|
|
|
|
* [tagname=('eq 1', 'eq 2')]
|
|
|
|
If argument is a file, the file should be formatted as:
|
|
|
|
eq 1
|
|
|
|
eq 2
|
|
|
|
OR
|
|
|
|
tagname=
|
|
|
|
X
|
|
|
|
Y
|
|
|
|
*/
|
2019-12-20 16:59:30 +01:00
|
|
|
void parseIncludeExcludeEquations(const string &inc_exc_eq_tags, set<pair<string, string>> &eq_tag_set, bool exclude_eqs);
|
2019-11-18 17:13:49 +01:00
|
|
|
|
|
|
|
// General function that removes leading/trailing whitespace from a string
|
2019-12-20 16:59:30 +01:00
|
|
|
inline void
|
|
|
|
removeLeadingTrailingWhitespace(string &str)
|
2019-11-18 17:13:49 +01:00
|
|
|
{
|
|
|
|
str.erase(0, str.find_first_not_of("\t\n\v\f\r "));
|
|
|
|
str.erase(str.find_last_not_of("\t\n\v\f\r ") + 1);
|
|
|
|
}
|
|
|
|
|
2009-04-14 16:39:53 +02:00
|
|
|
public:
|
2018-08-21 11:46:59 +02:00
|
|
|
DynamicModel(SymbolTable &symbol_table_arg,
|
|
|
|
NumericalConstants &num_constants_arg,
|
|
|
|
ExternalFunctionsTable &external_functions_table_arg,
|
|
|
|
TrendComponentModelTable &trend_component_model_table_arg,
|
|
|
|
VarModelTable &var_model_table_arg);
|
2018-10-09 18:27:19 +02:00
|
|
|
|
|
|
|
DynamicModel(const DynamicModel &m);
|
|
|
|
DynamicModel(DynamicModel &&) = delete;
|
2019-12-20 16:59:30 +01:00
|
|
|
DynamicModel &operator=(const DynamicModel &m);
|
|
|
|
DynamicModel &operator=(DynamicModel &&) = delete;
|
2017-03-06 16:34:08 +01:00
|
|
|
|
|
|
|
//! Compute cross references
|
|
|
|
void computeXrefs();
|
|
|
|
|
|
|
|
//! Write cross references
|
|
|
|
void writeXrefs(ostream &output) const;
|
|
|
|
|
2009-04-14 16:39:53 +02:00
|
|
|
//! Execute computations (variable sorting + derivation)
|
2009-04-20 12:48:54 +02:00
|
|
|
/*!
|
|
|
|
\param jacobianExo whether derivatives w.r. to exo and exo_det should be in the Jacobian (derivatives w.r. to endo are always computed)
|
2018-11-22 14:32:40 +01:00
|
|
|
\param derivsOrder order of derivatives w.r. to exo, exo_det and endo should be computed (implies jacobianExo = true when order >= 2)
|
2016-05-18 12:26:19 +02:00
|
|
|
\param paramsDerivsOrder order of derivatives w.r. to a pair (endo/exo/exo_det, parameter) to be computed (>0 implies jacobianExo = true)
|
2009-04-20 12:48:54 +02:00
|
|
|
\param eval_context evaluation context for normalization
|
|
|
|
\param no_tmp_terms if true, no temporary terms will be computed in the dynamic files
|
|
|
|
*/
|
2018-11-22 14:32:40 +01:00
|
|
|
void computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsOrder,
|
2018-12-20 17:04:28 +01:00
|
|
|
const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode, bool linear_decomposition);
|
2009-04-14 16:39:53 +02:00
|
|
|
//! Writes model initialization and lead/lag incidence matrix to output
|
2018-09-21 17:13:19 +02:00
|
|
|
void writeOutput(ostream &output, const string &basename, bool block, bool linear_decomposition, bool byte_code, bool use_dll, int order, bool estimation_present, bool compute_xrefs, bool julia) const;
|
2009-09-02 15:36:56 +02:00
|
|
|
|
2018-09-18 14:50:31 +02:00
|
|
|
//! Write JSON AST
|
|
|
|
void writeJsonAST(ostream &output) const;
|
|
|
|
|
2019-10-16 17:34:27 +02:00
|
|
|
//! Write JSON variable mapping
|
|
|
|
void writeJsonVariableMapping(ostream &output) const;
|
|
|
|
|
2017-02-02 15:09:43 +01:00
|
|
|
//! Write JSON Output
|
|
|
|
void writeJsonOutput(ostream &output) const;
|
|
|
|
|
2017-06-23 14:20:48 +02:00
|
|
|
//! Write JSON Output representation of original dynamic model
|
|
|
|
void writeJsonOriginalModelOutput(ostream &output) const;
|
|
|
|
|
2017-06-28 17:11:24 +02:00
|
|
|
//! Write JSON Output representation of model info (useful stuff from M_)
|
|
|
|
void writeJsonDynamicModelInfo(ostream &output) const;
|
|
|
|
|
2017-02-20 12:18:11 +01:00
|
|
|
//! Write JSON Output representation of dynamic model after computing pass
|
2017-03-02 18:34:18 +01:00
|
|
|
void writeJsonComputingPassOutput(ostream &output, bool writeDetails) const;
|
2017-02-20 12:18:11 +01:00
|
|
|
|
|
|
|
//! Write JSON prams derivatives file
|
2017-03-02 18:34:18 +01:00
|
|
|
void writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) const;
|
2017-02-20 12:18:11 +01:00
|
|
|
|
2017-03-10 17:23:35 +01:00
|
|
|
//! Write cross reference output if the xref maps have been filed
|
|
|
|
void writeJsonXrefs(ostream &output) const;
|
2018-06-04 14:17:36 +02:00
|
|
|
void writeJsonXrefsHelper(ostream &output, const map<pair<int, int>, set<int>> &xrefs) const;
|
2017-03-10 17:23:35 +01:00
|
|
|
|
2018-01-11 12:55:36 +01:00
|
|
|
//! Print equations that have non-zero second derivatives
|
|
|
|
void printNonZeroHessianEquations(ostream &output) const;
|
2016-07-25 19:43:34 +02:00
|
|
|
|
2019-12-13 17:15:03 +01:00
|
|
|
//! Tells whether Hessian has been computed
|
|
|
|
/*! This is needed to know whether no non-zero equation in Hessian means a
|
2019-12-20 16:59:30 +01:00
|
|
|
zero Hessian or Hessian not computed */
|
|
|
|
inline bool
|
|
|
|
isHessianComputed() const
|
2019-12-13 17:15:03 +01:00
|
|
|
{
|
|
|
|
return hessian_computed;
|
|
|
|
}
|
|
|
|
//! Returns equations that have non-zero second derivatives
|
2019-12-20 16:59:30 +01:00
|
|
|
inline set<int>
|
|
|
|
getNonZeroHessianEquations() const
|
2019-12-13 17:15:03 +01:00
|
|
|
{
|
|
|
|
return nonzero_hessian_eqs;
|
|
|
|
}
|
2016-07-27 21:01:54 +02:00
|
|
|
|
2019-03-14 17:20:45 +01:00
|
|
|
//! Fill Autoregressive Matrix for var_model
|
2019-03-15 12:27:32 +01:00
|
|
|
map<string, map<tuple<int, int, int>, expr_t>> fillAutoregressiveMatrix(bool is_var) const;
|
2018-09-06 17:53:07 +02:00
|
|
|
|
2018-09-10 17:13:51 +02:00
|
|
|
//! Fill Error Component Matrix for trend_component_model
|
2019-08-19 14:51:21 +02:00
|
|
|
/*! Returns a pair (A0r, A0starr) */
|
|
|
|
pair<map<string, map<tuple<int, int, int>, expr_t>>, map<string, map<tuple<int, int, int>, expr_t>>> fillErrorComponentMatrix(const ExprNode::subst_table_t &diff_subst_table) const;
|
2018-09-10 17:13:51 +02:00
|
|
|
|
2018-08-14 14:23:21 +02:00
|
|
|
//! Fill the Trend Component Model Table
|
|
|
|
void fillTrendComponentModelTable() const;
|
2019-10-22 16:04:24 +02:00
|
|
|
void fillTrendComponentModelTableFromOrigModel() const;
|
2019-08-19 14:51:21 +02:00
|
|
|
void fillTrendComponentmodelTableAREC(const ExprNode::subst_table_t &diff_subst_table) const;
|
2018-02-08 13:07:15 +01:00
|
|
|
|
2018-08-21 11:46:59 +02:00
|
|
|
//! Fill the Var Model Table
|
|
|
|
void fillVarModelTable() const;
|
2019-10-22 16:04:24 +02:00
|
|
|
void fillVarModelTableFromOrigModel() const;
|
2018-08-21 11:46:59 +02:00
|
|
|
|
2018-08-23 13:56:58 +02:00
|
|
|
//! Update the rhs references in the var model and trend component tables
|
2018-09-03 15:05:30 +02:00
|
|
|
//! after substitution of auxiliary variables and find the trend variables
|
|
|
|
//! in the trend_component model
|
|
|
|
void updateVarAndTrendModel() const;
|
2018-08-23 13:56:58 +02:00
|
|
|
|
2018-08-21 11:46:59 +02:00
|
|
|
//! Add aux equations (and aux variables) for variables declared in var_model
|
|
|
|
//! at max order if they don't already exist
|
|
|
|
void addEquationsForVar();
|
|
|
|
|
2018-02-12 17:37:53 +01:00
|
|
|
//! Get Pac equation parameter info
|
2019-08-19 14:51:21 +02:00
|
|
|
map<pair<string, string>, pair<string, int>> walkPacParameters(const string &name);
|
2018-01-30 16:33:16 +01:00
|
|
|
//! Add var_model info to pac_expectation nodes
|
2019-02-20 12:59:55 +01:00
|
|
|
void fillPacModelInfo(const string &pac_model_name,
|
2019-02-20 16:38:44 +01:00
|
|
|
vector<int> lhs,
|
2019-02-20 12:59:55 +01:00
|
|
|
int max_lag,
|
2019-02-20 16:42:22 +01:00
|
|
|
string aux_model_type,
|
2019-02-20 12:59:55 +01:00
|
|
|
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
|
|
|
|
const vector<bool> &nonstationary,
|
2019-05-13 17:43:16 +02:00
|
|
|
expr_t growth);
|
2018-03-28 18:46:15 +02:00
|
|
|
|
2019-02-15 12:52:46 +01:00
|
|
|
//! Substitutes pac_expectation operator with expectation based on auxiliary model
|
2019-12-20 16:59:30 +01:00
|
|
|
void substitutePacExpectation(const string &pac_model_name);
|
2019-02-15 12:52:46 +01:00
|
|
|
|
2009-04-14 16:39:53 +02:00
|
|
|
//! Adds informations for simulation in a binary file
|
2018-06-27 15:01:31 +02:00
|
|
|
void Write_Inf_To_Bin_File_Block(const string &basename,
|
2019-12-16 19:42:59 +01:00
|
|
|
int num, int &u_count_int, bool &file_open, bool is_two_boundaries, bool linear_decomposition) const;
|
2009-04-14 16:39:53 +02:00
|
|
|
//! Writes dynamic model file
|
2019-04-04 17:01:37 +02:00
|
|
|
void writeDynamicFile(const string &basename, bool block, bool linear_decomposition, bool bytecode, bool use_dll, const string &mexext, const filesystem::path &matlabroot, const filesystem::path &dynareroot, int order, bool julia) const;
|
2009-04-20 15:58:15 +02:00
|
|
|
//! Writes file containing parameters derivatives
|
2015-07-28 14:59:55 +02:00
|
|
|
void writeParamsDerivativesFile(const string &basename, bool julia) const;
|
2014-05-09 10:02:05 +02:00
|
|
|
|
2019-05-03 19:24:55 +02:00
|
|
|
//! Writes file containing coordinates of non-zero elements in the Jacobian
|
2019-06-18 15:33:56 +02:00
|
|
|
/*! Used by the perfect_foresight_problem MEX */
|
2019-05-03 19:24:55 +02:00
|
|
|
void writeDynamicJacobianNonZeroElts(const string &basename) const;
|
|
|
|
|
2018-09-21 17:13:19 +02:00
|
|
|
//! Converts to nonlinear model (only the equations)
|
|
|
|
/*! It assumes that the nonlinear model given in argument has just been allocated */
|
|
|
|
void toNonlinearPart(DynamicModel &non_linear_equations_dynamic_model) const;
|
|
|
|
|
2019-10-16 17:34:27 +02:00
|
|
|
//! Creates mapping for variables and equations they are present in
|
|
|
|
void createVariableMapping(int orig_eq_nbr);
|
|
|
|
|
|
|
|
//! Expands equation tags with default equation names (available "name" tag or LHS variable or equation ID)
|
|
|
|
void expandEqTags();
|
|
|
|
|
2013-09-13 20:37:31 +02:00
|
|
|
//! Find endogenous variables not used in model
|
2013-11-29 15:32:49 +01:00
|
|
|
set<int> findUnusedEndogenous();
|
2013-11-29 16:03:15 +01:00
|
|
|
//! Find exogenous variables not used in model
|
|
|
|
set<int> findUnusedExogenous();
|
2013-09-13 20:37:31 +02:00
|
|
|
|
2017-07-27 18:33:19 +02:00
|
|
|
//! Set the max leads/lags of the original model
|
|
|
|
void setLeadsLagsOrig();
|
|
|
|
|
2019-11-18 17:13:49 +01:00
|
|
|
//! Removes equations from the model according to name tags
|
2019-12-20 16:59:30 +01:00
|
|
|
void includeExcludeEquations(const string &eqs, bool exclude_eqs);
|
2019-11-18 17:13:49 +01:00
|
|
|
|
2011-03-21 18:40:57 +01:00
|
|
|
//! Replaces model equations with derivatives of Lagrangian w.r.t. endogenous
|
2018-12-20 17:04:28 +01:00
|
|
|
void computeRamseyPolicyFOCs(const StaticModel &static_model);
|
2011-03-28 11:19:10 +02:00
|
|
|
//! Replaces the model equations in dynamic_model with those in this model
|
2011-03-21 18:40:57 +01:00
|
|
|
void replaceMyEquations(DynamicModel &dynamic_model) const;
|
|
|
|
|
2013-04-11 17:07:39 +02:00
|
|
|
//! Adds an equation marked as [static]
|
2018-06-04 14:17:36 +02:00
|
|
|
void addStaticOnlyEquation(expr_t eq, int lineno, const vector<pair<string, string>> &eq_tags);
|
2013-04-11 17:07:39 +02:00
|
|
|
|
|
|
|
//! Returns number of static only equations
|
|
|
|
size_t staticOnlyEquationsNbr() const;
|
2017-06-01 19:58:32 +02:00
|
|
|
|
2013-04-11 17:07:39 +02:00
|
|
|
//! Returns number of dynamic only equations
|
|
|
|
size_t dynamicOnlyEquationsNbr() const;
|
|
|
|
|
2009-04-30 15:14:33 +02:00
|
|
|
//! Writes LaTeX file with the equations of the dynamic model
|
2019-12-16 19:42:59 +01:00
|
|
|
void writeLatexFile(const string &basename, bool write_equation_tags) const;
|
2009-04-30 15:14:33 +02:00
|
|
|
|
2015-02-16 08:31:30 +01:00
|
|
|
//! Writes LaTeX file with the equations of the dynamic model (for the original model)
|
2019-12-16 19:42:59 +01:00
|
|
|
void writeLatexOriginalFile(const string &basename, bool write_equation_tags) const;
|
2015-02-16 08:31:30 +01:00
|
|
|
|
2018-06-04 12:53:26 +02:00
|
|
|
int getDerivID(int symb_id, int lag) const noexcept(false) override;
|
|
|
|
int getDynJacobianCol(int deriv_id) const noexcept(false) override;
|
|
|
|
void addAllParamDerivId(set<int> &deriv_id_set) override;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
2009-09-10 22:09:16 +02:00
|
|
|
//! Returns true indicating that this is a dynamic model
|
2018-06-04 12:53:26 +02:00
|
|
|
bool
|
|
|
|
isDynamic() const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
};
|
2009-09-30 17:10:31 +02:00
|
|
|
|
2010-10-15 19:05:16 +02:00
|
|
|
//! Drive test of detrended equations
|
|
|
|
void runTrendTest(const eval_context_t &eval_context);
|
|
|
|
|
2009-10-07 16:07:13 +02:00
|
|
|
//! Transforms the model by removing all leads greater or equal than 2 on endos
|
2009-10-07 18:34:42 +02:00
|
|
|
/*! Note that this can create new lags on endos and exos */
|
2018-12-20 17:04:28 +01:00
|
|
|
void substituteEndoLeadGreaterThanTwo(bool deterministic_model);
|
2009-09-30 17:10:31 +02:00
|
|
|
|
2009-10-07 16:07:13 +02:00
|
|
|
//! Transforms the model by removing all lags greater or equal than 2 on endos
|
2018-12-20 17:04:28 +01:00
|
|
|
void substituteEndoLagGreaterThanTwo(bool deterministic_model);
|
2009-10-07 16:07:13 +02:00
|
|
|
|
2009-10-07 18:34:42 +02:00
|
|
|
//! Transforms the model by removing all leads on exos
|
|
|
|
/*! Note that this can create new lags on endos and exos */
|
2018-12-20 17:04:28 +01:00
|
|
|
void substituteExoLead(bool deterministic_model);
|
2009-10-07 18:34:42 +02:00
|
|
|
|
|
|
|
//! Transforms the model by removing all lags on exos
|
2018-12-20 17:04:28 +01:00
|
|
|
void substituteExoLag(bool deterministic_model);
|
2009-09-30 17:10:31 +02:00
|
|
|
|
2018-07-18 16:18:26 +02:00
|
|
|
//! Transforms the model by removing all UnaryOpcode::expectation
|
2018-12-20 17:04:28 +01:00
|
|
|
void substituteExpectation(bool partial_information_model);
|
2009-10-29 18:16:10 +01:00
|
|
|
|
2009-11-07 19:37:11 +01:00
|
|
|
//! Transforms the model by decreasing the lead/lag of predetermined variables in model equations by one
|
|
|
|
void transformPredeterminedVariables();
|
|
|
|
|
2010-10-15 19:05:16 +02:00
|
|
|
//! Transforms the model by removing trends specified by the user
|
|
|
|
void detrendEquations();
|
|
|
|
|
2019-12-20 16:59:30 +01:00
|
|
|
inline const nonstationary_symbols_map_t &
|
|
|
|
getNonstationarySymbolsMap() const
|
2019-12-04 15:48:33 +01:00
|
|
|
{
|
|
|
|
return nonstationary_symbols_map;
|
|
|
|
}
|
|
|
|
|
2019-12-20 16:59:30 +01:00
|
|
|
inline const map<int, expr_t> &
|
|
|
|
getTrendSymbolsMap() const
|
2019-12-04 15:48:33 +01:00
|
|
|
{
|
|
|
|
return trend_symbols_map;
|
|
|
|
}
|
|
|
|
|
2018-01-30 10:06:56 +01:00
|
|
|
//! Substitutes adl operator
|
|
|
|
void substituteAdl();
|
|
|
|
|
2018-06-07 12:53:00 +02:00
|
|
|
//! Creates aux vars for all unary operators
|
2019-10-22 14:56:28 +02:00
|
|
|
pair<lag_equivalence_table_t, ExprNode::subst_table_t> substituteUnaryOps();
|
2018-06-07 12:53:00 +02:00
|
|
|
|
2019-08-19 18:22:55 +02:00
|
|
|
//! Creates aux vars for unary operators in certain equations: originally implemented for support of VARs
|
2019-10-22 14:56:28 +02:00
|
|
|
pair<lag_equivalence_table_t, ExprNode::subst_table_t> substituteUnaryOps(const set<string> &eq_tags);
|
2018-05-30 16:48:08 +02:00
|
|
|
|
2019-08-19 18:22:55 +02:00
|
|
|
//! Creates aux vars for unary operators in certain equations: originally implemented for support of VARs
|
2019-10-22 14:56:28 +02:00
|
|
|
pair<lag_equivalence_table_t, ExprNode::subst_table_t> substituteUnaryOps(const vector<int> &eqnumbers);
|
2018-06-07 12:53:00 +02:00
|
|
|
|
2018-01-30 10:06:56 +01:00
|
|
|
//! Substitutes diff operator
|
2019-10-22 14:56:28 +02:00
|
|
|
pair<lag_equivalence_table_t, ExprNode::subst_table_t> substituteDiff(vector<expr_t> &pac_growth);
|
2018-03-28 18:46:15 +02:00
|
|
|
|
2018-08-01 19:41:44 +02:00
|
|
|
//! Substitute VarExpectation operators
|
|
|
|
void substituteVarExpectation(const map<string, expr_t> &subst_table);
|
|
|
|
|
2018-08-13 12:12:20 +02:00
|
|
|
//! Return max lag of pac equation
|
2019-02-19 16:36:10 +01:00
|
|
|
void getPacMaxLag(const string &pac_model_name, map<pair<string, string>, pair<string, int>> &eqtag_and_lag) const;
|
2018-08-13 12:12:20 +02:00
|
|
|
|
2019-02-15 12:52:46 +01:00
|
|
|
//! Return target of the pac equation
|
|
|
|
int getPacTargetSymbId(const string &pac_model_name) const;
|
|
|
|
|
2019-02-25 15:29:46 +01:00
|
|
|
//! Declare Z1 variables before creating aux vars so it comes right after the endo names declared by the user
|
|
|
|
void declarePacModelConsistentExpectationEndogs(const string &name);
|
|
|
|
|
2019-02-15 12:52:46 +01:00
|
|
|
//! Add model consistent expectation equation for pac model
|
2019-12-20 16:59:30 +01:00
|
|
|
void addPacModelConsistentExpectationEquation(const string &name, int discount,
|
2019-02-20 12:59:55 +01:00
|
|
|
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
|
|
|
|
ExprNode::subst_table_t &diff_subst_table);
|
2019-02-15 12:52:46 +01:00
|
|
|
|
|
|
|
//! store symb_ids for alphas created in addPacModelConsistentExpectationEquation
|
2019-02-20 12:59:55 +01:00
|
|
|
//! (pac_model_name, standardized_eqtag) -> mce_alpha_symb_id
|
2019-02-19 16:36:10 +01:00
|
|
|
map<pair<string, string>, vector<int>> pac_mce_alpha_symb_ids;
|
2019-02-20 12:59:55 +01:00
|
|
|
//! store symb_ids for h0, h1 parameters
|
|
|
|
//! (pac_model_name, standardized_eqtag) -> parameter symb_ids
|
|
|
|
map<pair<string, string>, vector<int>> pac_h0_indices, pac_h1_indices;
|
2019-02-19 16:36:10 +01:00
|
|
|
//! store symb_ids for z1s created in addPacModelConsistentExpectationEquation
|
2019-02-20 12:59:55 +01:00
|
|
|
//! (pac_model_name, standardized_eqtag) -> mce_z1_symb_id
|
2019-02-19 16:36:10 +01:00
|
|
|
map<pair<string, string>, int> pac_mce_z1_symb_ids;
|
|
|
|
//! Store lag info for pac equations
|
2019-02-20 12:59:55 +01:00
|
|
|
//! (pac_model_name, equation_tag) -> (standardized_eqtag, lag)
|
2019-02-19 16:36:10 +01:00
|
|
|
map<pair<string, string>, pair<string, int>> pac_eqtag_and_lag;
|
2019-02-15 12:52:46 +01:00
|
|
|
|
2019-02-20 12:59:55 +01:00
|
|
|
//! (pac_model_name, equation_tag) -> expr_t
|
|
|
|
map<pair<string, string>, expr_t> pac_expectation_substitution;
|
|
|
|
|
|
|
|
//! Store info about pac models:
|
2019-02-20 16:42:22 +01:00
|
|
|
//! pac_model_name -> (lhsvars, growth_param_index, aux_model_type)
|
|
|
|
map<string, tuple<vector<int>, int, string>> pac_model_info;
|
2019-02-20 12:59:55 +01:00
|
|
|
|
|
|
|
//! Store info about pac models specific to the equation they appear in
|
|
|
|
//! (pac_model_name, standardized_eqtag) ->
|
2019-03-08 12:05:48 +01:00
|
|
|
//! (lhs, optim_share_index, ar_params_and_vars, ec_params_and_vars, non_optim_vars_params_and_constants, additive_vars_params_and_constants, optim_additive_vars_params_and_constants)
|
2019-02-20 12:59:55 +01:00
|
|
|
map<pair<string, string>,
|
2019-03-07 12:35:30 +01:00
|
|
|
tuple<pair<int, int>, int, set<pair<int, pair<int, int>>>, pair<int, vector<tuple<int, bool, int>>>, vector<tuple<int, int, int, double>>, vector<tuple<int, int, int, double>>, vector<tuple<int, int, int, double>>>> pac_equation_info;
|
2019-02-20 12:59:55 +01:00
|
|
|
|
2018-03-28 18:46:15 +02:00
|
|
|
//! Table to undiff LHS variables for pac vector z
|
2018-08-14 14:23:21 +02:00
|
|
|
vector<int> getUndiffLHSForPac(const string &aux_model_name,
|
2019-08-19 14:51:21 +02:00
|
|
|
const ExprNode::subst_table_t &diff_subst_table) const;
|
2017-06-12 14:56:44 +02:00
|
|
|
|
2010-10-15 19:05:16 +02:00
|
|
|
//! Transforms the model by replacing trend variables with a 1
|
|
|
|
void removeTrendVariableFromEquations();
|
|
|
|
|
2013-04-25 18:09:31 +02:00
|
|
|
//! Transforms the model by creating aux vars for the diff of forward vars
|
2013-05-17 16:51:34 +02:00
|
|
|
/*! If subset is empty, does the transformation for all fwrd vars; otherwise
|
2017-06-01 19:58:32 +02:00
|
|
|
restrict it to the vars in subset */
|
2018-12-20 17:04:28 +01:00
|
|
|
void differentiateForwardVars(const vector<string> &subset);
|
2013-04-25 18:09:31 +02:00
|
|
|
|
2009-09-30 17:10:31 +02:00
|
|
|
//! Fills eval context with values of model local variables and auxiliary variables
|
2010-09-16 19:00:48 +02:00
|
|
|
void fillEvalContext(eval_context_t &eval_context) const;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
2019-12-20 16:59:30 +01:00
|
|
|
auto
|
|
|
|
getStaticOnlyEquationsInfo() const
|
|
|
|
{
|
|
|
|
return tuple(static_only_equations, static_only_equations_lineno, static_only_equations_equation_tags);
|
|
|
|
};
|
2018-10-10 17:08:54 +02:00
|
|
|
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the number of blocks
|
2018-06-04 12:53:26 +02:00
|
|
|
unsigned int
|
|
|
|
getNbBlocks() const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return block_type_firstequation_size_mfs.size();
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Determine the simulation type of each block
|
2018-06-04 12:53:26 +02:00
|
|
|
BlockSimulationType
|
|
|
|
getBlockSimulationType(int block_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return get<0>(block_type_firstequation_size_mfs[block_number]);
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the first equation number of a block
|
2018-06-04 12:53:26 +02:00
|
|
|
unsigned int
|
|
|
|
getBlockFirstEquation(int block_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return get<1>(block_type_firstequation_size_mfs[block_number]);
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the size of the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
unsigned int
|
|
|
|
getBlockSize(int block_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return get<2>(block_type_firstequation_size_mfs[block_number]);
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2010-07-23 11:20:24 +02:00
|
|
|
//! Return the number of exogenous variable in the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
unsigned int
|
|
|
|
getBlockExoSize(int block_number) const override
|
2010-07-23 11:20:24 +02:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return block_var_exo[block_number].first.size();
|
2010-07-23 11:20:24 +02:00
|
|
|
};
|
|
|
|
//! Return the number of colums in the jacobian matrix for exogenous variable in the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
unsigned int
|
|
|
|
getBlockExoColSize(int block_number) const override
|
2010-07-23 11:20:24 +02:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return block_var_exo[block_number].second;
|
2010-07-23 11:20:24 +02:00
|
|
|
};
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the number of feedback variable of the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
unsigned int
|
|
|
|
getBlockMfs(int block_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return get<3>(block_type_firstequation_size_mfs[block_number]);
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the maximum lag in a block
|
2018-06-04 12:53:26 +02:00
|
|
|
unsigned int
|
|
|
|
getBlockMaxLag(int block_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return block_lag_lead[block_number].first;
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the maximum lead in a block
|
2018-06-04 12:53:26 +02:00
|
|
|
unsigned int
|
|
|
|
getBlockMaxLead(int block_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return block_lag_lead[block_number].second;
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the type of equation (equation_number) belonging to the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
EquationType
|
|
|
|
getBlockEquationType(int block_number, int equation_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return equation_type_and_normalized_equation[equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].first;
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return true if the equation has been normalized
|
2018-06-04 12:53:26 +02:00
|
|
|
bool
|
|
|
|
isBlockEquationRenormalized(int block_number, int equation_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return equation_type_and_normalized_equation[equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].first == E_EVALUATE_S;
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2010-09-16 19:18:45 +02:00
|
|
|
//! Return the expr_t of the equation equation_number belonging to the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
expr_t
|
|
|
|
getBlockEquationExpr(int block_number, int equation_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return equations[equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]];
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2010-09-16 19:18:45 +02:00
|
|
|
//! Return the expr_t of the renormalized equation equation_number belonging to the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
expr_t
|
|
|
|
getBlockEquationRenormalizedExpr(int block_number, int equation_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return equation_type_and_normalized_equation[equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number]].second;
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the original number of equation equation_number belonging to the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
int
|
|
|
|
getBlockEquationID(int block_number, int equation_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return equation_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+equation_number];
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the original number of variable variable_number belonging to the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
int
|
|
|
|
getBlockVariableID(int block_number, int variable_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return variable_reordered[get<1>(block_type_firstequation_size_mfs[block_number])+variable_number];
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2010-07-23 11:20:24 +02:00
|
|
|
//! Return the original number of the exogenous variable varexo_number belonging to the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
int
|
|
|
|
getBlockVariableExoID(int block_number, int variable_number) const override
|
2010-07-23 11:20:24 +02:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return exo_block[block_number].find(variable_number)->first;
|
2010-07-23 11:20:24 +02:00
|
|
|
};
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the position of equation_number in the block number belonging to the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
int
|
|
|
|
getBlockInitialEquationID(int block_number, int equation_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return static_cast<int>(inv_equation_reordered[equation_number]) - static_cast<int>(get<1>(block_type_firstequation_size_mfs[block_number]));
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the position of variable_number in the block number belonging to the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
int
|
|
|
|
getBlockInitialVariableID(int block_number, int variable_number) const override
|
2009-12-16 18:13:23 +01:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return static_cast<int>(inv_variable_reordered[variable_number]) - static_cast<int>(get<1>(block_type_firstequation_size_mfs[block_number]));
|
2009-12-16 18:13:23 +01:00
|
|
|
};
|
2010-07-23 11:20:24 +02:00
|
|
|
//! Return the block number containing the endogenous variable variable_number
|
|
|
|
int
|
|
|
|
getBlockVariableID(int variable_number) const
|
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return get<0>(variable_block_lead_lag[variable_number]);
|
2010-07-23 11:20:24 +02:00
|
|
|
};
|
|
|
|
//! Return the position of the exogenous variable_number in the block number belonging to the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
int
|
|
|
|
getBlockInitialExogenousID(int block_number, int variable_number) const override
|
2010-07-23 11:20:24 +02:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
if (auto it = block_exo_index.find(block_number);
|
|
|
|
it != block_exo_index.end())
|
2010-07-23 11:20:24 +02:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
if (auto it1 = it->second.find(variable_number);
|
|
|
|
it1 != it->second.end())
|
2010-07-23 11:20:24 +02:00
|
|
|
return it1->second;
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
2019-12-16 19:42:59 +01:00
|
|
|
return -1;
|
2010-07-23 11:20:24 +02:00
|
|
|
};
|
|
|
|
//! Return the position of the deterministic exogenous variable_number in the block number belonging to the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
int
|
|
|
|
getBlockInitialDetExogenousID(int block_number, int variable_number) const override
|
2010-07-23 11:20:24 +02:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
if (auto it = block_det_exo_index.find(block_number);
|
|
|
|
it != block_det_exo_index.end())
|
2010-07-23 11:20:24 +02:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
if (auto it1 = it->second.find(variable_number);
|
|
|
|
it1 != it->second.end())
|
2010-07-23 11:20:24 +02:00
|
|
|
return it1->second;
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
2019-12-16 19:42:59 +01:00
|
|
|
return -1;
|
2010-07-23 11:20:24 +02:00
|
|
|
};
|
|
|
|
//! Return the position of the other endogenous variable_number in the block number belonging to the block block_number
|
2018-06-04 12:53:26 +02:00
|
|
|
int
|
|
|
|
getBlockInitialOtherEndogenousID(int block_number, int variable_number) const override
|
2010-07-23 11:20:24 +02:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
if (auto it = block_other_endo_index.find(block_number);
|
|
|
|
it != block_other_endo_index.end())
|
2010-07-23 11:20:24 +02:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
if (auto it1 = it->second.find(variable_number);
|
|
|
|
it1 != it->second.end())
|
2010-07-23 11:20:24 +02:00
|
|
|
return it1->second;
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
2019-12-16 19:42:59 +01:00
|
|
|
return -1;
|
2010-07-23 11:20:24 +02:00
|
|
|
};
|
2011-10-14 14:35:32 +02:00
|
|
|
bool isModelLocalVariableUsed() const;
|
2014-04-24 20:54:38 +02:00
|
|
|
|
2015-07-30 14:40:03 +02:00
|
|
|
//! Returns true if a parameter was used in the model block with a lead or lag
|
|
|
|
bool ParamUsedWithLeadLag() const;
|
|
|
|
|
2018-09-25 19:15:22 +02:00
|
|
|
bool isChecksumMatching(const string &basename, bool block) const;
|
2009-04-14 16:39:53 +02:00
|
|
|
};
|
|
|
|
|
2017-06-01 19:58:32 +02:00
|
|
|
//! Classes to re-order derivatives for various sparse storage formats
|
2013-10-13 17:49:10 +02:00
|
|
|
class derivative
|
2013-09-17 15:11:57 +02:00
|
|
|
{
|
|
|
|
public:
|
2013-10-13 17:49:10 +02:00
|
|
|
long unsigned int linear_address;
|
|
|
|
long unsigned int col_nbr;
|
|
|
|
unsigned int row_nbr;
|
|
|
|
expr_t value;
|
2017-06-01 19:58:32 +02:00
|
|
|
derivative(long unsigned int arg1, long unsigned int arg2, int arg3, expr_t arg4) :
|
|
|
|
linear_address(arg1), col_nbr(arg2), row_nbr(arg3), value(arg4)
|
|
|
|
{
|
|
|
|
};
|
2013-10-13 17:49:10 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class derivative_less_than
|
|
|
|
{
|
|
|
|
public:
|
2017-06-01 19:58:32 +02:00
|
|
|
bool
|
|
|
|
operator()(const derivative &d1, const derivative &d2) const
|
2013-10-13 17:49:10 +02:00
|
|
|
{
|
|
|
|
return d1.linear_address < d2.linear_address;
|
|
|
|
}
|
2013-09-17 15:11:57 +02:00
|
|
|
};
|
2009-04-14 16:39:53 +02:00
|
|
|
#endif
|