ModelTree.hh 8.79 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
 * Copyright (C) 2003-2008 Dynare Team
 *
 * This file is part of Dynare.
 *
 * Dynare is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Dynare is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _MODELTREE_HH
#define _MODELTREE_HH

using namespace std;

#include <string>
#include <vector>
#include <map>
#include <ostream>

#include "SymbolTable.hh"
#include "NumericalConstants.hh"
#include "DataTree.hh"
#include "BlockTriangular.hh"
#include "SymbolGaussElim.hh"

//! The three in which ModelTree can work
enum ModelTreeMode
  {
    eStandardMode, //!< Standard mode (static and dynamic files in Matlab)
    eSparseMode,  //!< Sparse mode (static file in Matlab, dynamic file in Matlab with block decomposition)
    eDLLMode,      //!< DLL mode (static and dynamic files in C)
    eSparseDLLMode //!< Sparse DLL mode (static file in Matlab, dynamic file in C with block decomposition plus a binary file)
  };

//! Stores a model's equations and derivatives
class ModelTree : public DataTree
{
private:
  //! Stores declared equations
  vector<BinaryOpNode *> equations;

  typedef map<pair<int, int>, NodeID> first_derivatives_type;
  //! First order derivatives
  /*! First index is equation number, second is variable w.r. to which is computed the derivative.
    Only non-null derivatives are stored in the map.
    Variable indexes used are those of the variable_table, before sorting.
  */
  first_derivatives_type first_derivatives;

  typedef map<pair<int, pair<int, int> >, NodeID> second_derivatives_type;
  //! Second order derivatives
  /*! First index is equation number, second and third are variables w.r. to which is computed the derivative.
    Only non-null derivatives are stored in the map.
    Contains only second order derivatives where var1 >= var2 (for obvious symmetry reasons).
    Variable indexes used are those of the variable_table, before sorting.
  */
  second_derivatives_type second_derivatives;

  typedef map<pair<int, pair<int, pair<int, int> > >, NodeID> third_derivatives_type;
  //! Third order derivatives
  /*! First index is equation number, second, third and fourth are variables w.r. to which is computed the derivative.
    Only non-null derivatives are stored in the map.
    Contains only third order derivatives where var1 >= var2 >= var3 (for obvious symmetry reasons).
    Variable indexes used are those of the variable_table, before sorting.
  */
  third_derivatives_type third_derivatives;

  //! Temporary terms (those which will be noted Txxxx)
  temporary_terms_type temporary_terms;
  map_idx_type map_idx;

  //! Computes derivatives of ModelTree
  void derive(int order);
  //! Write derivative of an equation w.r. to a variable
  void writeDerivative(ostream &output, int eq, int symb_id, int lag, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
  //! Write derivative code of an equation w.r. to a variable
  void compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, ExprNodeOutputType output_type, map_idx_type map_idx) const;
  //! Computes temporary terms
  void computeTemporaryTerms(int order);
  void computeTemporaryTermsOrdered(int order, Model_Block *ModelBlock);
  //! Writes temporary terms
  void writeTemporaryTerms(ostream &output, ExprNodeOutputType output_type) const;
  //! Writes model local variables
  /*! No temporary term is used in the output, so that local parameters declarations can be safely put before temporary terms declaration in the output files */
  void writeModelLocalVariables(ostream &output, ExprNodeOutputType output_type) const;
  //! Writes model equations
  void writeModelEquations(ostream &output, ExprNodeOutputType output_type) const;
  //! Writes the static model equations and its derivatives
  /*! \todo handle hessian in C output */
  void writeStaticModel(ostream &StaticOutput) const;
  //! Writes the dynamic model equations and its derivatives
  /*! \todo add third derivatives handling in C output */
  void writeDynamicModel(ostream &DynamicOutput) const;
  //! Writes the Block reordred structure of the model in M output
  void writeModelEquationsOrdered_M(ostream &output, Model_Block *ModelBlock, const string &dynamic_basename) const;
  //! Writes the Block reordred structure of the static model in M output
  void writeModelStaticEquationsOrdered_M(ostream &output, Model_Block *ModelBlock, const string &static_basename) const;
108
  //! Writes the code of the Block reordred structure of the model in virtual machine bytecode
109
110
111
112
113
114
115
116
117
118
119
120
121
  void writeModelEquationsCodeOrdered(const string file_name, const Model_Block *ModelBlock, const string bin_basename, ExprNodeOutputType output_type) const;
  //! Writes static model file (Matlab version)
  void writeStaticMFile(const string &static_basename) const;
  //! Writes static model file (C version)
  void writeStaticCFile(const string &static_basename) const;
  //! Writes static model file when Sparse option is on (Matlab version)
  void writeSparseStaticMFile(const string &static_basename, const string &bin_basename, const int mode) const;
  //! Writes dynamic model file (Matlab version)
  void writeDynamicMFile(const string &dynamic_basename) const;
  //! Writes dynamic model file (C version)
  /*! \todo add third derivatives handling */
  void writeDynamicCFile(const string &dynamic_basename) const;
  //! Writes dynamic model file when SparseDLL option is on
122
  void writeSparseDynamicMFile(const string &dynamic_basename, const string &basename, const int mode) const;
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
  //! 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)
  */
  void evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m);
  void BlockLinear(Model_Block *ModelBlock);
  string reform(string name) const;

  //! Writes either (i+1,j+1) or [i+j*n_i] whether we are in Matlab or C mode
  void matrixHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const;

public:
  ModelTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants);
  //! Mode in which the ModelTree is supposed to work (Matlab, DLL or SparseDLL)
  ModelTreeMode mode;
  //! Absolute value under which a number is considered to be zero
  double cutoff;
  //! The weight of the Markowitz criteria to determine the pivot in the linear solver (simul_NG1 from simulate.cc)
  double markowitz;
  //! Use a graphical and symbolic version of the symbolic gaussian elimination (new_SGE = false) or use direct gaussian elimination (new_SGE = true)
  bool new_SGE;
  //! the file containing the model and the derivatives code
  ofstream code_file;
  //! Declare a node as an equation of the model
  void addEquation(NodeID eq);
  //! Whether dynamic Jacobian (w.r. to endogenous) should be written
  bool computeJacobian;
  //! Whether dynamic Jacobian (w.r. to endogenous and exogenous) should be written
  bool computeJacobianExo;
  //! Whether dynamic Hessian (w.r. to endogenous and exogenous) should be written
  bool computeHessian;
  //! Whether static Hessian (w.r. to endogenous only) should be written
  bool computeStaticHessian;
  //! Whether dynamic third order derivatives (w.r. to endogenous and exogenous) should be written
  bool computeThirdDerivatives;
  //! Execute computations (variable sorting + derivation)
  /*! You must set computeJacobian, computeJacobianExo, computeHessian, computeStaticHessian and computeThirdDerivatives to correct values before calling this function */
  void computingPass(const eval_context_type &eval_context);
  //! Writes model initialization and lead/lag incidence matrix to output
  void writeOutput(ostream &output) const;
  //! Writes static model file
  void writeStaticFile(const string &basename) const;
  //! Writes dynamic model file
  void writeDynamicFile(const string &basename) const;
  //! Complete set to block decompose the model
  BlockTriangular block_triangular;
  //! Adds informations for simulation in a binary file
  void Write_Inf_To_Bin_File(const string &dynamic_basename, const string &bin_basename,
                             const int &num, int &u_count_int, bool &file_open) const;
173
  //! Returns the number of equations in the model
174
175
176
177
  int equation_number() const;
};

#endif