2008-02-03 11:28:36 +01:00
|
|
|
/*
|
2018-03-27 17:14:30 +02:00
|
|
|
* Copyright (C) 2003-2018 Dynare Team
|
2008-02-03 11:28:36 +01: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 _MODELTREE_HH
|
|
|
|
#define _MODELTREE_HH
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2009-09-30 17:10:31 +02:00
|
|
|
#include <deque>
|
2008-02-03 11:28:36 +01:00
|
|
|
#include <map>
|
|
|
|
#include <ostream>
|
2018-10-11 11:21:58 +02:00
|
|
|
#include <array>
|
2008-02-03 11:28:36 +01:00
|
|
|
|
2018-10-26 11:44:26 +02:00
|
|
|
#include <boost/filesystem.hpp>
|
|
|
|
|
2008-02-03 11:28:36 +01:00
|
|
|
#include "DataTree.hh"
|
2016-05-12 12:02:34 +02:00
|
|
|
#include "ExtendedPreprocessorTypes.hh"
|
2008-02-03 11:28:36 +01:00
|
|
|
|
2018-11-15 16:39:53 +01:00
|
|
|
// Helper to convert a vector into a tuple
|
|
|
|
template <typename T, size_t... Indices>
|
|
|
|
auto vectorToTupleHelper(const vector<T>& v, index_sequence<Indices...>) {
|
|
|
|
return make_tuple(v[Indices]...);
|
|
|
|
}
|
|
|
|
template <size_t N, typename T>
|
|
|
|
auto vectorToTuple(const vector<T>& v) {
|
|
|
|
assert(v.size() >= N);
|
|
|
|
return vectorToTupleHelper(v, make_index_sequence<N>());
|
|
|
|
}
|
|
|
|
|
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
|
2018-06-04 14:31:26 +02:00
|
|
|
using equation_type_and_normalized_equation_t = vector<pair<EquationType, expr_t >>;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
|
|
|
//! Vector describing variables: max_lag in the block, max_lead in the block
|
2018-06-04 14:31:26 +02:00
|
|
|
using lag_lead_vector_t = vector<pair< int, int>>;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
2018-06-04 14:17:36 +02:00
|
|
|
//! for each block contains pair< pair<Simulation_Type, first_equation>, pair < Block_Size, Recursive_part_Size >>
|
2018-06-04 14:31:26 +02:00
|
|
|
using block_type_firstequation_size_mfs_t = vector<pair< pair< BlockSimulationType, int>, pair<int, int>>>;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
2018-06-04 14:17:36 +02:00
|
|
|
//! for a block contains derivatives pair< pair<block_equation_number, block_variable_number> , pair<lead_lag, expr_t>>
|
2018-06-04 14:31:26 +02:00
|
|
|
using block_derivatives_equation_variable_laglead_nodeid_t = vector< pair<pair<int, int>, pair< int, expr_t >>>;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
|
|
|
//! for all blocks derivatives description
|
2018-06-04 14:07:13 +02:00
|
|
|
using blocks_derivatives_t = vector<block_derivatives_equation_variable_laglead_nodeid_t>;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
2009-04-14 16:39:53 +02:00
|
|
|
//! Shared code for static and dynamic models
|
2008-02-03 11:28:36 +01:00
|
|
|
class ModelTree : public DataTree
|
|
|
|
{
|
2009-12-16 14:21:31 +01:00
|
|
|
friend class DynamicModel;
|
|
|
|
friend class StaticModel;
|
2009-04-14 16:39:53 +02:00
|
|
|
protected:
|
2009-09-30 17:10:31 +02:00
|
|
|
//! Stores declared and generated auxiliary equations
|
2008-02-03 11:28:36 +01:00
|
|
|
vector<BinaryOpNode *> equations;
|
|
|
|
|
2014-01-27 16:41:43 +01:00
|
|
|
//! Stores line numbers of declared equations; -1 means undefined
|
|
|
|
vector<int> equations_lineno;
|
|
|
|
|
2009-09-30 17:10:31 +02:00
|
|
|
//! Only stores generated auxiliary equations, in an order meaningful for evaluation
|
2018-07-27 14:19:59 +02:00
|
|
|
/*! These equations only contain the definition of auxiliary variables, and
|
|
|
|
may diverge from those in the main model (equations), if other model
|
|
|
|
transformations applied subsequently. This is not a problem, since
|
|
|
|
aux_equations is only used for regenerating the values of auxiliaries
|
|
|
|
given the others.
|
|
|
|
|
|
|
|
For example, such a divergence appears when there is an expectation
|
|
|
|
operator in a ramsey model, see
|
|
|
|
tests/optimal_policy/nk_ramsey_expectation.mod */
|
2009-09-30 17:10:31 +02:00
|
|
|
deque<BinaryOpNode *> aux_equations;
|
|
|
|
|
2009-09-02 16:37:59 +02:00
|
|
|
//! Stores equation tags
|
2018-06-04 14:17:36 +02:00
|
|
|
vector<pair<int, pair<string, string>>> equation_tags;
|
2009-09-02 16:37:59 +02:00
|
|
|
|
2018-11-15 16:39:53 +01:00
|
|
|
//! Stores derivatives
|
|
|
|
/*! Index 0 is not used, index 1 contains first derivatives, ...
|
|
|
|
For each derivation order, stores a map whose key is a vector of integer: the
|
|
|
|
first integer is the equation index, the remaining ones are the derivation
|
2018-11-22 14:32:40 +01:00
|
|
|
IDs of variables (in non-decreasing order, to avoid storing symmetric
|
|
|
|
elements several times) */
|
2018-11-15 16:39:53 +01:00
|
|
|
vector<map<vector<int>, expr_t>> derivatives;
|
2012-11-29 18:07:48 +01:00
|
|
|
|
2018-11-15 16:39:53 +01:00
|
|
|
//! Number of non-zero derivatives
|
|
|
|
/*! Index 0 is not used, index 1 contains number of non-zero first
|
|
|
|
derivatives, ... */
|
|
|
|
vector<int> NNZDerivatives;
|
|
|
|
|
|
|
|
//! Derivatives with respect to parameters
|
|
|
|
/*! The key of the outer map is a pair (derivation order w.r.t. endogenous,
|
|
|
|
derivation order w.r.t. parameters). For e.g., { 1, 2 } corresponds to the jacobian
|
|
|
|
differentiated twice w.r.t. to parameters.
|
|
|
|
In inner maps, the vector of integers consists of: the equation index, then
|
2018-11-22 15:41:11 +01:00
|
|
|
the derivation IDs of endogenous (in non-decreasing order),
|
|
|
|
then the IDs of parameters (in non-decreasing order)*/
|
2018-11-15 16:39:53 +01:00
|
|
|
map<pair<int,int>, map<vector<int>, expr_t>> params_derivatives;
|
2012-11-29 18:07:48 +01:00
|
|
|
|
2018-11-16 16:53:07 +01:00
|
|
|
//! Storage for temporary terms in block/bytecode mode
|
2010-09-16 19:00:48 +02:00
|
|
|
temporary_terms_t temporary_terms;
|
2018-11-15 16:39:53 +01:00
|
|
|
|
2018-11-16 16:53:07 +01:00
|
|
|
//! Used model local variables, that will be treated as temporary terms
|
|
|
|
/*! See the comments in ModelTree::computeTemporaryTerms() */
|
2018-05-28 15:50:29 +02:00
|
|
|
map<expr_t, expr_t, ExprNodeLess> temporary_terms_mlv;
|
2018-11-15 16:39:53 +01:00
|
|
|
|
|
|
|
//! Temporary terms for residuals and derivatives
|
|
|
|
/*! Index 0 is temp. terms of residuals, index 1 for first derivatives, ... */
|
|
|
|
vector<temporary_terms_t> temporary_terms_derivatives;
|
2012-11-29 18:07:48 +01:00
|
|
|
|
2018-03-27 17:14:30 +02:00
|
|
|
temporary_terms_idxs_t temporary_terms_idxs;
|
|
|
|
|
2018-11-15 16:39:53 +01:00
|
|
|
//! Temporary terms for parameter derivatives, under a disaggregated form
|
|
|
|
/*! The pair of integers is to be interpreted as in param_derivatives */
|
2018-11-16 18:24:06 +01:00
|
|
|
map<pair<int,int>, temporary_terms_t> params_derivs_temporary_terms;
|
2012-11-29 18:07:48 +01:00
|
|
|
|
2018-05-28 15:23:15 +02:00
|
|
|
temporary_terms_idxs_t params_derivs_temporary_terms_idxs;
|
|
|
|
|
2010-10-15 19:05:16 +02:00
|
|
|
//! Trend variables and their growth factors
|
2013-03-26 16:46:18 +01:00
|
|
|
map<int, expr_t> trend_symbols_map;
|
|
|
|
|
|
|
|
//! for all trends; the boolean is true if this is a log-trend, false otherwise
|
2018-06-04 14:31:26 +02:00
|
|
|
using nonstationary_symbols_map_t = map<int, pair<bool, expr_t>>;
|
2013-03-26 16:46:18 +01:00
|
|
|
|
2010-10-15 19:05:16 +02:00
|
|
|
//! Nonstationary variables and their deflators
|
2013-03-26 16:46:18 +01:00
|
|
|
nonstationary_symbols_map_t nonstationary_symbols_map;
|
2008-02-03 11:28:36 +01:00
|
|
|
|
2011-06-22 11:56:07 +02:00
|
|
|
//! vector of block reordered variables and equations
|
|
|
|
vector<int> equation_reordered, variable_reordered, inv_equation_reordered, inv_variable_reordered;
|
|
|
|
|
|
|
|
//! the file containing the model and the derivatives code
|
|
|
|
ofstream code_file;
|
2018-09-21 17:13:19 +02:00
|
|
|
|
|
|
|
//! Vector indicating if the equation is linear in endogenous variable (true) or not (false)
|
|
|
|
vector<bool> is_equation_linear;
|
2011-06-22 11:56:07 +02:00
|
|
|
|
2018-11-22 14:32:40 +01:00
|
|
|
//! Computes derivatives
|
|
|
|
/*! \param order the derivation order
|
|
|
|
\param vars the derivation IDs w.r.t. which compute the derivatives */
|
|
|
|
void computeDerivatives(int order, const set<int> &vars);
|
2012-11-29 18:07:48 +01:00
|
|
|
//! Computes derivatives of the Jacobian and Hessian w.r. to parameters
|
2016-05-18 12:26:19 +02:00
|
|
|
void computeParamsDerivatives(int paramsDerivsOrder);
|
2008-02-03 11:28:36 +01:00
|
|
|
//! Write derivative of an equation w.r. to a variable
|
2010-09-16 19:00:48 +02:00
|
|
|
void writeDerivative(ostream &output, int eq, int symb_id, int lag, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const;
|
2009-04-20 12:48:54 +02:00
|
|
|
//! Computes temporary terms (for all equations and derivatives)
|
2018-09-25 15:56:52 +02:00
|
|
|
void computeTemporaryTerms(bool is_matlab, bool no_tmp_terms);
|
2012-11-29 18:07:48 +01:00
|
|
|
//! Computes temporary terms for the file containing parameters derivatives
|
|
|
|
void computeParamsDerivativesTemporaryTerms();
|
2017-06-14 07:01:31 +02:00
|
|
|
//! Writes temporary terms
|
2018-11-16 16:53:07 +01:00
|
|
|
void writeTemporaryTerms(const temporary_terms_t &tt, temporary_terms_t &temp_term_union, const temporary_terms_idxs_t &tt_idxs, ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const;
|
2017-02-20 12:18:11 +01:00
|
|
|
void writeJsonTemporaryTerms(const temporary_terms_t &tt, const temporary_terms_t &ttm1, ostream &output, deriv_node_temp_terms_t &tef_terms, string &concat) const;
|
2010-01-22 11:03:29 +01:00
|
|
|
//! Compiles temporary terms
|
2010-07-23 11:20:24 +02:00
|
|
|
void compileTemporaryTerms(ostream &code_file, unsigned int &instruction_number, const temporary_terms_t &tt, map_idx_t map_idx, bool dynamic, bool steady_dynamic) const;
|
2010-01-22 11:03:29 +01:00
|
|
|
//! Adds informations for simulation in a binary file
|
2018-06-27 15:01:31 +02:00
|
|
|
void Write_Inf_To_Bin_File(const string &filename, int &u_count_int, bool &file_open, bool is_two_boundaries, int block_mfs) const;
|
2016-12-30 11:26:56 +01:00
|
|
|
//! Fixes output when there are more than 32 nested parens, Issue #1201
|
2017-01-05 15:19:13 +01:00
|
|
|
void fixNestedParenthesis(ostringstream &output, map<string, string> &tmp_paren_vars, bool &message_printed) const;
|
2016-12-30 11:26:56 +01:00
|
|
|
//! Tests if string contains more than 32 nested parens, Issue #1201
|
|
|
|
bool testNestedParenthesis(const string &str) const;
|
2018-11-16 16:53:07 +01:00
|
|
|
void writeModelLocalVariableTemporaryTerms(temporary_terms_t &temp_term_union,
|
2018-11-16 18:13:34 +01:00
|
|
|
const temporary_terms_idxs_t &tt_idxs,
|
2018-03-27 17:14:30 +02:00
|
|
|
ostream &output, ExprNodeOutputType output_type,
|
|
|
|
deriv_node_temp_terms_t &tef_terms) const;
|
2008-02-03 11:28:36 +01:00
|
|
|
//! Writes model equations
|
|
|
|
void writeModelEquations(ostream &output, ExprNodeOutputType output_type) const;
|
2018-03-27 17:14:30 +02:00
|
|
|
void writeModelEquations(ostream &output, ExprNodeOutputType output_type,
|
2018-05-24 19:29:53 +02:00
|
|
|
const temporary_terms_t &temporary_terms) const;
|
2017-02-02 15:09:43 +01:00
|
|
|
//! Writes JSON model equations
|
2017-02-20 12:18:11 +01:00
|
|
|
//! if residuals = true, we are writing the dynamic/static model.
|
|
|
|
//! Otherwise, just the model equations (with line numbers, no tmp terms)
|
|
|
|
void writeJsonModelEquations(ostream &output, bool residuals) const;
|
|
|
|
void writeJsonModelLocalVariables(ostream &output, deriv_node_temp_terms_t &tef_terms) const;
|
2010-01-22 11:03:29 +01:00
|
|
|
//! Compiles model equations
|
2010-07-23 11:20:24 +02:00
|
|
|
void compileModelEquations(ostream &code_file, unsigned int &instruction_number, const temporary_terms_t &tt, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const;
|
2008-02-03 11:28:36 +01:00
|
|
|
|
2009-04-30 15:14:33 +02:00
|
|
|
//! Writes LaTeX model file
|
2017-08-24 15:35:10 +02:00
|
|
|
void writeLatexModelFile(const string &basename, ExprNodeOutputType output_type, const bool write_equation_tags) const;
|
2009-04-30 15:14:33 +02:00
|
|
|
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Sparse matrix of double to store the values of the Jacobian
|
|
|
|
/*! First index is equation number, second index is endogenous type specific ID */
|
2018-06-04 14:31:26 +02:00
|
|
|
using jacob_map_t = map<pair<int, int>, double>;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
|
|
|
//! Sparse matrix of double to store the values of the Jacobian
|
|
|
|
/*! First index is lag, second index is equation number, third index is endogenous type specific ID */
|
2018-06-04 14:31:26 +02:00
|
|
|
using dynamic_jacob_map_t = map<pair<int, pair<int, int>>, expr_t>;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
|
|
|
//! Normalization of equations
|
|
|
|
/*! Maps endogenous type specific IDs to equation numbers */
|
|
|
|
vector<int> endo2eq;
|
|
|
|
|
|
|
|
//! number of equation in the prologue and in the epilogue
|
|
|
|
unsigned int epilogue, prologue;
|
|
|
|
|
|
|
|
//! for each block contains pair< max_lag, max_lead>
|
2010-09-16 19:00:48 +02:00
|
|
|
lag_lead_vector_t block_lag_lead;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
|
|
|
//! Compute the matching between endogenous and variable using the jacobian contemporaneous_jacobian
|
2009-12-21 11:29:21 +01:00
|
|
|
/*!
|
|
|
|
\param contemporaneous_jacobian Jacobian used as an incidence matrix: all elements declared in the map (even if they are zero), are used as vertices of the incidence matrix
|
|
|
|
\return True if a complete normalization has been achieved
|
|
|
|
*/
|
2010-09-16 19:00:48 +02:00
|
|
|
bool computeNormalization(const jacob_map_t &contemporaneous_jacobian, bool verbose);
|
2009-12-21 11:29:21 +01:00
|
|
|
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Try to compute the matching between endogenous and variable using a decreasing cutoff
|
2009-12-21 11:29:21 +01:00
|
|
|
/*!
|
|
|
|
Applied to the jacobian contemporaneous_jacobian and stop when a matching is found.
|
|
|
|
If no matching is found using a strictly positive cutoff, then a zero cutoff is applied (i.e. use a symbolic normalization); in that case, the method adds zeros in the jacobian matrices to reflect all the edges in the symbolic incidence matrix.
|
|
|
|
If no matching is found with a zero cutoff close to zero an error message is printout.
|
|
|
|
*/
|
2010-09-16 19:00:48 +02:00
|
|
|
void computeNonSingularNormalization(jacob_map_t &contemporaneous_jacobian, double cutoff, jacob_map_t &static_jacobian, dynamic_jacob_map_t &dynamic_jacobian);
|
2018-09-21 17:13:19 +02:00
|
|
|
//! Try to find a natural normalization if all equations are matched to an endogenous variable on the LHS
|
|
|
|
bool computeNaturalNormalization();
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Try to normalized each unnormalized equation (matched endogenous variable only on the LHS)
|
|
|
|
void computeNormalizedEquations(multimap<int, int> &endo2eqs) const;
|
|
|
|
//! Evaluate the jacobian and suppress all the elements below the cutoff
|
2010-09-16 19:00:48 +02:00
|
|
|
void evaluateAndReduceJacobian(const eval_context_t &eval_context, jacob_map_t &contemporaneous_jacobian, jacob_map_t &static_jacobian, dynamic_jacob_map_t &dynamic_jacobian, double cutoff, bool verbose);
|
2018-09-21 17:13:19 +02:00
|
|
|
//! Select and reorder the non linear equations of the model
|
|
|
|
vector<pair<int, int> > select_non_linear_equations_and_variables(vector<bool> is_equation_linear, const dynamic_jacob_map_t &dynamic_jacobian, vector<int> &equation_reordered, vector<int> &variable_reordered,
|
|
|
|
vector<int> &inv_equation_reordered, vector<int> &inv_variable_reordered,
|
|
|
|
lag_lead_vector_t &equation_lag_lead, lag_lead_vector_t &variable_lag_lead,
|
|
|
|
vector<unsigned int> &n_static, vector<unsigned int> &n_forward, vector<unsigned int> &n_backward, vector<unsigned int> &n_mixed);
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Search the equations and variables belonging to the prologue and the epilogue of the model
|
2010-09-16 19:00:48 +02:00
|
|
|
void computePrologueAndEpilogue(const jacob_map_t &static_jacobian, vector<int> &equation_reordered, vector<int> &variable_reordered);
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Determine the type of each equation of model and try to normalized the unnormalized equation using computeNormalizedEquations
|
2018-06-04 14:17:36 +02:00
|
|
|
equation_type_and_normalized_equation_t equationTypeDetermination(const map<pair<int, pair<int, int>>, expr_t> &first_order_endo_derivatives, const vector<int> &Index_Var_IM, const vector<int> &Index_Equ_IM, int mfs) const;
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Compute the block decomposition and for a non-recusive block find the minimum feedback set
|
2018-06-04 14:17:36 +02:00
|
|
|
void computeBlockDecompositionAndFeedbackVariablesForEachBlock(const jacob_map_t &static_jacobian, const dynamic_jacob_map_t &dynamic_jacobian, vector<int> &equation_reordered, vector<int> &variable_reordered, vector<pair<int, int>> &blocks, const equation_type_and_normalized_equation_t &Equation_Type, bool verbose_, bool select_feedback_variable, int mfs, vector<int> &inv_equation_reordered, vector<int> &inv_variable_reordered, lag_lead_vector_t &equation_lag_lead, lag_lead_vector_t &variable_lag_lead_t, vector<unsigned int> &n_static, vector<unsigned int> &n_forward, vector<unsigned int> &n_backward, vector<unsigned int> &n_mixed) const;
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Reduce the number of block merging the same type equation in the prologue and the epilogue and determine the type of each block
|
2018-09-21 17:13:19 +02:00
|
|
|
block_type_firstequation_size_mfs_t reduceBlocksAndTypeDetermination(const dynamic_jacob_map_t &dynamic_jacobian, vector<pair<int, int>> &blocks, const equation_type_and_normalized_equation_t &Equation_Type, const vector<int> &variable_reordered, const vector<int> &equation_reordered, vector<unsigned int> &n_static, vector<unsigned int> &n_forward, vector<unsigned int> &n_backward, vector<unsigned int> &n_mixed, vector<pair< pair<int, int>, pair<int, int>>> &block_col_type, bool linear_decomposition);
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Determine the maximum number of lead and lag for the endogenous variable in a bloc
|
2010-09-16 19:00:48 +02:00
|
|
|
void getVariableLeadLagByBlock(const dynamic_jacob_map_t &dynamic_jacobian, const vector<int> &components_set, int nb_blck_sim, lag_lead_vector_t &equation_lead_lag, lag_lead_vector_t &variable_lead_lag, const vector<int> &equation_reordered, const vector<int> &variable_reordered) const;
|
2018-09-21 17:13:19 +02:00
|
|
|
//! For each equation determine if it is linear or not
|
|
|
|
vector<bool> equationLinear(map<pair<int, pair<int, int> >, expr_t> first_order_endo_derivatives) const;
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Print an abstract of the block structure of the model
|
2018-06-04 14:17:36 +02:00
|
|
|
void printBlockDecomposition(const vector<pair<int, int>> &blocks) const;
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Determine for each block if it is linear or not
|
2010-09-16 19:00:48 +02:00
|
|
|
vector<bool> BlockLinear(const blocks_derivatives_t &blocks_derivatives, const vector<int> &variable_reordered) const;
|
2009-12-16 14:21:31 +01:00
|
|
|
|
|
|
|
//! Determine the simulation type of each block
|
|
|
|
virtual BlockSimulationType getBlockSimulationType(int block_number) const = 0;
|
|
|
|
//! Return the number of blocks
|
|
|
|
virtual unsigned int getNbBlocks() const = 0;
|
|
|
|
//! Return the first equation number of a block
|
|
|
|
virtual unsigned int getBlockFirstEquation(int block_number) const = 0;
|
|
|
|
//! Return the size of the block block_number
|
|
|
|
virtual unsigned int getBlockSize(int block_number) const = 0;
|
2010-07-23 11:20:24 +02:00
|
|
|
//! Return the number of exogenous variable in the block block_number
|
|
|
|
virtual unsigned int getBlockExoSize(int block_number) const = 0;
|
|
|
|
//! Return the number of colums in the jacobian matrix for exogenous variable in the block block_number
|
|
|
|
virtual unsigned int getBlockExoColSize(int block_number) const = 0;
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the number of feedback variable of the block block_number
|
|
|
|
virtual unsigned int getBlockMfs(int block_number) const = 0;
|
|
|
|
//! Return the maximum lag in a block
|
|
|
|
virtual unsigned int getBlockMaxLag(int block_number) const = 0;
|
|
|
|
//! Return the maximum lead in a block
|
|
|
|
virtual unsigned int getBlockMaxLead(int block_number) const = 0;
|
2017-06-14 07:01:31 +02:00
|
|
|
inline void
|
|
|
|
setBlockLeadLag(int block, int max_lag, int max_lead)
|
|
|
|
{
|
2018-06-04 16:36:46 +02:00
|
|
|
block_lag_lead[block] = { max_lag, max_lead };
|
2017-06-14 07:01:31 +02:00
|
|
|
};
|
|
|
|
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the type of equation (equation_number) belonging to the block block_number
|
|
|
|
virtual EquationType getBlockEquationType(int block_number, int equation_number) const = 0;
|
|
|
|
//! Return true if the equation has been normalized
|
|
|
|
virtual bool isBlockEquationRenormalized(int block_number, int equation_number) const = 0;
|
2010-09-16 19:18:45 +02:00
|
|
|
//! Return the expr_t of the equation equation_number belonging to the block block_number
|
|
|
|
virtual expr_t getBlockEquationExpr(int block_number, int equation_number) const = 0;
|
|
|
|
//! Return the expr_t of the renormalized equation equation_number belonging to the block block_number
|
|
|
|
virtual expr_t getBlockEquationRenormalizedExpr(int block_number, int equation_number) const = 0;
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the original number of equation equation_number belonging to the block block_number
|
|
|
|
virtual int getBlockEquationID(int block_number, int equation_number) const = 0;
|
|
|
|
//! Return the original number of variable variable_number belonging to the block block_number
|
|
|
|
virtual int getBlockVariableID(int block_number, int variable_number) const = 0;
|
2010-07-23 11:20:24 +02:00
|
|
|
//! Return the original number of the exogenous variable varexo_number belonging to the block block_number
|
|
|
|
virtual int getBlockVariableExoID(int block_number, int variable_number) const = 0;
|
2009-12-16 14:21:31 +01:00
|
|
|
//! Return the position of equation_number in the block number belonging to the block block_number
|
|
|
|
virtual int getBlockInitialEquationID(int block_number, int equation_number) const = 0;
|
|
|
|
//! Return the position of variable_number in the block number belonging to the block block_number
|
|
|
|
virtual int getBlockInitialVariableID(int block_number, int variable_number) const = 0;
|
2010-07-23 11:20:24 +02:00
|
|
|
//! Return the position of variable_number in the block number belonging to the block block_number
|
|
|
|
virtual int getBlockInitialExogenousID(int block_number, int variable_number) const = 0;
|
|
|
|
//! Return the position of the deterministic exogenous variable_number in the block number belonging to the block block_number
|
|
|
|
virtual int getBlockInitialDetExogenousID(int block_number, int variable_number) const = 0;
|
|
|
|
//! Return the position of the other endogenous variable_number in the block number belonging to the block block_number
|
|
|
|
virtual int getBlockInitialOtherEndogenousID(int block_number, int variable_number) const = 0;
|
2011-06-22 11:56:07 +02:00
|
|
|
//! Initialize equation_reordered & variable_reordered
|
|
|
|
void initializeVariablesAndEquations();
|
2018-10-09 18:27:19 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
//! 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 ModelTree &m);
|
2018-10-26 11:44:26 +02:00
|
|
|
//! Returns the name of the MATLAB architecture given the extension used for MEX files
|
|
|
|
static string matlab_arch(const string &mexext);
|
|
|
|
//! Compiles the MEX file
|
|
|
|
static void compileDll(const string &basename, const string &static_or_dynamic, const string &mexext, const boost::filesystem::path &matlabroot, const boost::filesystem::path &dynareroot);
|
2018-10-09 18:27:19 +02:00
|
|
|
|
2008-02-03 11:28:36 +01:00
|
|
|
public:
|
2018-08-14 14:23:21 +02:00
|
|
|
ModelTree(SymbolTable &symbol_table_arg,
|
|
|
|
NumericalConstants &num_constants_arg,
|
2018-10-09 18:27:19 +02:00
|
|
|
ExternalFunctionsTable &external_functions_table_arg,
|
|
|
|
bool is_dynamic_arg = false);
|
|
|
|
|
|
|
|
ModelTree(const ModelTree &m);
|
|
|
|
ModelTree(ModelTree &&) = delete;
|
|
|
|
ModelTree & operator=(const ModelTree &m);
|
|
|
|
ModelTree & operator=(ModelTree &&) = delete;
|
|
|
|
|
2011-06-22 11:56:07 +02:00
|
|
|
//! Absolute value under which a number is considered to be zero
|
2018-10-04 17:18:27 +02:00
|
|
|
double cutoff{1e-15};
|
2011-06-22 11:56:07 +02:00
|
|
|
//! Compute the minimum feedback set
|
|
|
|
/*! 0 : all endogenous variables are considered as feedback variables
|
|
|
|
1 : the variables belonging to non normalized equation are considered as feedback variables
|
|
|
|
2 : the variables belonging to a non linear equation are considered as feedback variables
|
|
|
|
3 : the variables belonging to a non normalizable non linear equation are considered as feedback variables
|
|
|
|
default value = 0 */
|
2018-10-04 17:18:27 +02:00
|
|
|
int mfs{0};
|
2014-01-27 16:41:43 +01:00
|
|
|
//! Declare a node as an equation of the model; also give its line number
|
|
|
|
void addEquation(expr_t eq, int lineno);
|
2013-04-11 17:07:39 +02:00
|
|
|
//! Declare a node as an equation of the model, also giving its tags
|
2018-06-04 14:17:36 +02:00
|
|
|
void addEquation(expr_t eq, int lineno, const vector<pair<string, string>> &eq_tags);
|
2009-09-30 17:10:31 +02:00
|
|
|
//! Declare a node as an auxiliary equation of the model, adding it at the end of the list of auxiliary equations
|
2010-09-16 19:18:45 +02:00
|
|
|
void addAuxEquation(expr_t eq);
|
2008-10-17 19:21:22 +02:00
|
|
|
//! Returns the number of equations in the model
|
2008-02-03 11:28:36 +01:00
|
|
|
int equation_number() const;
|
2010-10-15 19:05:16 +02:00
|
|
|
//! Adds a trend variable with its growth factor
|
2018-06-04 12:50:53 +02:00
|
|
|
void addTrendVariables(vector<int> trend_vars, expr_t growth_factor) noexcept(false);
|
2013-03-26 16:46:18 +01:00
|
|
|
//! Adds a nonstationary variables with their (common) deflator
|
2018-06-04 12:50:53 +02:00
|
|
|
void addNonstationaryVariables(vector<int> nonstationary_vars, bool log_deflator, expr_t deflator) noexcept(false);
|
2013-10-29 11:47:59 +01:00
|
|
|
//! Is a given variable non-stationary?
|
|
|
|
bool isNonstationary(int symb_id) const;
|
2011-06-22 11:56:07 +02:00
|
|
|
void set_cutoff_to_zero();
|
2011-08-19 15:05:57 +02:00
|
|
|
//! Helper for writing the Jacobian elements in MATLAB and C
|
|
|
|
/*! Writes either (i+1,j+1) or [i+j*no_eq] */
|
|
|
|
void jacobianHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const;
|
|
|
|
//! Helper for writing the sparse Hessian or third derivatives in MATLAB and C
|
2018-11-15 16:39:53 +01:00
|
|
|
/*! If order=2, writes either v2(i+1,j+1) or v2[i+j*NNZDerivatives[2]]
|
|
|
|
If order=3, writes either v3(i+1,j+1) or v3[i+j*NNZDerivatives[3]] */
|
2011-08-19 15:05:57 +02:00
|
|
|
void sparseHelper(int order, ostream &output, int row_nb, int col_nb, ExprNodeOutputType output_type) const;
|
2009-12-16 18:13:23 +01:00
|
|
|
inline static std::string
|
|
|
|
c_Equation_Type(int type)
|
|
|
|
{
|
|
|
|
char c_Equation_Type[4][13] =
|
|
|
|
{
|
|
|
|
"E_UNKNOWN ",
|
|
|
|
"E_EVALUATE ",
|
|
|
|
"E_EVALUATE_S",
|
|
|
|
"E_SOLVE "
|
|
|
|
};
|
|
|
|
return (c_Equation_Type[type]);
|
|
|
|
};
|
|
|
|
|
|
|
|
inline static std::string
|
|
|
|
BlockType0(BlockType type)
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case SIMULTANS:
|
|
|
|
return ("SIMULTANEOUS TIME SEPARABLE ");
|
|
|
|
break;
|
|
|
|
case PROLOGUE:
|
|
|
|
return ("PROLOGUE ");
|
|
|
|
break;
|
|
|
|
case EPILOGUE:
|
|
|
|
return ("EPILOGUE ");
|
|
|
|
break;
|
|
|
|
case SIMULTAN:
|
|
|
|
return ("SIMULTANEOUS TIME UNSEPARABLE");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return ("UNKNOWN ");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
inline static std::string
|
|
|
|
BlockSim(int type)
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case EVALUATE_FORWARD:
|
|
|
|
return ("EVALUATE FORWARD ");
|
|
|
|
break;
|
|
|
|
case EVALUATE_BACKWARD:
|
|
|
|
return ("EVALUATE BACKWARD ");
|
|
|
|
break;
|
|
|
|
case SOLVE_FORWARD_SIMPLE:
|
|
|
|
return ("SOLVE FORWARD SIMPLE ");
|
|
|
|
break;
|
|
|
|
case SOLVE_BACKWARD_SIMPLE:
|
|
|
|
return ("SOLVE BACKWARD SIMPLE ");
|
|
|
|
break;
|
|
|
|
case SOLVE_TWO_BOUNDARIES_SIMPLE:
|
|
|
|
return ("SOLVE TWO BOUNDARIES SIMPLE ");
|
|
|
|
break;
|
|
|
|
case SOLVE_FORWARD_COMPLETE:
|
|
|
|
return ("SOLVE FORWARD COMPLETE ");
|
|
|
|
break;
|
|
|
|
case SOLVE_BACKWARD_COMPLETE:
|
|
|
|
return ("SOLVE BACKWARD COMPLETE ");
|
|
|
|
break;
|
|
|
|
case SOLVE_TWO_BOUNDARIES_COMPLETE:
|
|
|
|
return ("SOLVE TWO BOUNDARIES COMPLETE");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return ("UNKNOWN ");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
2008-02-03 11:28:36 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|