StaticModel.hh 13.3 KB
Newer Older
sebastien's avatar
sebastien committed
1
/*
2
 * Copyright (C) 2003-2010 Dynare Team
sebastien's avatar
sebastien committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 * 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/>.
 */

20 21 22 23 24 25
#ifndef _STATIC_MODEL_HH
#define _STATIC_MODEL_HH

using namespace std;

#include <fstream>
sebastien's avatar
sebastien committed
26 27 28

#include "ModelTree.hh"

29
//! Stores a static model, as derived from the "model" block when leads and lags have been removed
sebastien's avatar
sebastien committed
30 31 32
class StaticModel : public ModelTree
{
private:
33 34 35 36 37
  typedef map<pair<int, int>, int> deriv_id_table_t;
  //! 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)
  vector<pair<int, int> > inv_deriv_id_table;
38

39 40
  //! Temporary terms for the file containing parameters dervicatives
  temporary_terms_type params_derivs_temporary_terms;
41

42 43
  //! Temporary terms for block decomposed models
  vector<vector<temporary_terms_type> > v_temporary_terms;
44

45
  vector<temporary_terms_inuse_type> v_temporary_terms_inuse;
46

47 48
  typedef map< pair< int, pair< int, int> >, NodeID> first_chain_rule_derivatives_type;
  first_chain_rule_derivatives_type first_chain_rule_derivatives;
49

50
  //! Writes static model file (standard Matlab version)
51 52 53 54
  void writeStaticMFile(const string &static_basename) const;

  //! Writes the static function calling the block to solve (Matlab version)
  void writeStaticBlockMFSFile(const string &basename) const;
sebastien's avatar
sebastien committed
55

56 57 58
  //! Writes static model file (C version)
  /*! \todo add third derivatives handling */
  void writeStaticCFile(const string &static_basename) const;
59

60 61
  //! Writes the Block reordred structure of the model in M output
  void writeModelEquationsOrdered_M(const string &dynamic_basename) const;
62

63
  //! Writes the code of the Block reordred structure of the model in virtual machine bytecode
64 65 66 67 68
  void writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_type map_idx) const;

  //! Writes the code of the model in virtual machine bytecode
  void writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_type map_idx) const;

69

70 71 72 73 74 75
  //! 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, bool dynamic);
76

77
  map_idx_type map_idx;
sebastien's avatar
sebastien committed
78

79
  //! sorts the temporary terms in the blocks order
80
  void computeTemporaryTermsOrdered();
81 82 83
  //! creates a mapping from the index of temporary terms to a natural index
  void computeTemporaryTermsMapping();

84
  //! Write derivative code of an equation w.r. to a variable
sebastien's avatar
sebastien committed
85
  void compileDerivative(ofstream &code_file, int eq, int symb_id, map_idx_type &map_idx) const;
86 87
  //! Write chain rule derivative code of an equation w.r. to a variable
  void compileChainRuleDerivative(ofstream &code_file, int eq, int var, int lag, map_idx_type &map_idx) const;
88

89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 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
  //! Get the type corresponding to a derivation ID
  virtual SymbolType getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException);
  //! Get the lag corresponding to a derivation ID
  virtual int getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException);
  //! Get the symbol ID corresponding to a derivation ID
  virtual int getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException);
  //! Compute the column indices of the static Jacobian
  void computeStatJacobianCols();
  //! return a map on the block jacobian
  map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> get_Derivatives(int block);
  //! Computes chain rule derivatives of the Jacobian w.r. to endogenous variables
  void computeChainRuleJacobian(t_blocks_derivatives &blocks_derivatives);
  //! Collect only the first derivatives
  map<pair<int, pair<int, int> >, NodeID> collect_first_order_derivatives_endogenous();

  //! 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 elements in MATLAB and C
  /*! Writes either (i+1,j+1) or [i+j*NNZDerivatives[1]] */
  void hessianHelper(ostream &output, int row_nb, int col_nb, ExprNodeOutputType output_type) const;

  //! Write chain rule derivative of a recursive equation w.r. to a variable
  void writeChainRuleDerivative(ostream &output, int eq, int var, int lag, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;

  //! Collecte the derivatives w.r. to endogenous of the block, to endogenous of previouys blocks and to exogenous
  void collect_block_first_order_derivatives();

protected:
  //! Indicate if the temporary terms are computed for the overall model (true) or not (false). Default value true
  bool global_temporary_terms;

  //! vector of block reordered variables and equations
  vector<int> equation_reordered, variable_reordered, inv_equation_reordered, inv_variable_reordered;

  //! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a NodeID on the new normalized equation
  t_equation_type_and_normalized_equation equation_type_and_normalized_equation;

  //! for each block contains pair< Simulation_Type, pair < Block_Size, Recursive_part_Size > >
  t_block_type_firstequation_size_mfs block_type_firstequation_size_mfs;

  //! for all blocks derivatives description
  t_blocks_derivatives blocks_derivatives;

  //! The jacobian without the elements below the cutoff
  dynamic_jacob_map dynamic_jacobian;

  //! Vector indicating if the block is linear in endogenous variable (true) or not (false)
  vector<bool> blocks_linear;

  //! Map the derivatives for a block pair<lag, make_pair(make_pair(eq, var)), NodeID>
  typedef map<pair< int, pair<int, int> >, NodeID> t_derivative;
  //! Vector of derivative for each blocks
  vector<t_derivative> derivative_endo, derivative_other_endo, derivative_exo, derivative_exo_det;

  //!List for each block and for each lag-leag all the other endogenous variables and exogenous variables
  typedef set<int> t_var;
  typedef map<int, t_var> t_lag_var;
  vector<t_lag_var> other_endo_block, exo_block, exo_det_block;

  //!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous
  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;
152

sebastien's avatar
sebastien committed
153
public:
154
  StaticModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants, ExternalFunctionsTable &external_functions_table_arg);
155 156

  //! Writes information on block decomposition when relevant
157
  void writeOutput(ostream &output, bool block) const;
158

159 160 161 162
  //! Absolute value under which a number is considered to be zero
  double cutoff;
  //! Compute the minimum feedback set in the static model:
  /*!   0 : all endogenous variables are considered as feedback variables
163 164 165
    1 : the variables belonging to a non linear equation are considered as feedback variables
    2 : the variables belonging to a non normalizable non linear equation are considered as feedback variables
    default value = 0 */
166 167 168 169 170 171 172 173 174 175 176 177
  int mfs;
  //! the file containing the model and the derivatives code
  ofstream code_file;
  //! Execute computations (variable sorting + derivation)
  /*!
    \param jacobianExo whether derivatives w.r. to exo and exo_det should be in the Jacobian (derivatives w.r. to endo are always computed)
    \param hessian whether 2nd derivatives w.r. to exo, exo_det and endo should be computed (implies jacobianExo = true)
    \param thirdDerivatives whether 3rd derivatives w.r. to endo/exo/exo_det should be computed (implies jacobianExo = true)
    \param paramsDerivatives whether 2nd derivatives w.r. to a pair (endo/exo/exo_det, parameter) should be computed (implies jacobianExo = true)
    \param eval_context evaluation context for normalization
    \param no_tmp_terms if true, no temporary terms will be computed in the static files
  */
178
  void computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool hessian, bool block, bool bytecode);
179

180 181
  //! Adds informations for simulation in a binary file for a block decomposed model
  void Write_Inf_To_Bin_File_Block(const string &static_basename, const string &bin_basename, const int &num,
182 183
                             int &u_count_int, bool &file_open) const;

sebastien's avatar
sebastien committed
184
  //! Writes static model file
185
  void writeStaticFile(const string &basename, bool block, bool bytecode) const;
186

187 188 189
  //! Writes LaTeX file with the equations of the static model
  void writeLatexFile(const string &basename) const;

sebastien's avatar
sebastien committed
190 191 192
  //! Writes initializations in oo_.steady_state for the auxiliary variables
  void writeAuxVarInitval(ostream &output) const;

193 194 195
  //! Initialize equation_reordered & variable_reordered
  void initializeVariablesAndEquations();

196
  virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException);
197 198

  //! Return the number of blocks
199 200 201 202 203
  virtual unsigned int
  getNbBlocks() const
  {
    return (block_type_firstequation_size_mfs.size());
  };
204
  //! Determine the simulation type of each block
205 206 207 208 209
  virtual BlockSimulationType
  getBlockSimulationType(int block_number) const
  {
    return (block_type_firstequation_size_mfs[block_number].first.first);
  };
210
  //! Return the first equation number of a block
211 212 213 214 215
  virtual unsigned int
  getBlockFirstEquation(int block_number) const
  {
    return (block_type_firstequation_size_mfs[block_number].first.second);
  };
216
  //! Return the size of the block block_number
217 218 219 220 221
  virtual unsigned int
  getBlockSize(int block_number) const
  {
    return (block_type_firstequation_size_mfs[block_number].second.first);
  };
222
  //! Return the number of feedback variable of the block block_number
223 224 225 226 227
  virtual unsigned int
  getBlockMfs(int block_number) const
  {
    return (block_type_firstequation_size_mfs[block_number].second.second);
  };
228
  //! Return the maximum lag in a block
229 230 231 232 233
  virtual unsigned int
  getBlockMaxLag(int block_number) const
  {
    return (block_lag_lead[block_number].first);
  };
234
  //! Return the maximum lead in a block
235 236 237 238 239
  virtual unsigned int
  getBlockMaxLead(int block_number) const
  {
    return (block_lag_lead[block_number].second);
  };
240
  //! Return the type of equation (equation_number) belonging to the block block_number
241 242 243 244 245
  virtual EquationType
  getBlockEquationType(int block_number, int equation_number) const
  {
    return (equation_type_and_normalized_equation[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]].first);
  };
246
  //! Return true if the equation has been normalized
247 248 249 250 251
  virtual bool
  isBlockEquationRenormalized(int block_number, int equation_number) const
  {
    return (equation_type_and_normalized_equation[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]].first == E_EVALUATE_S);
  };
252
  //! Return the NodeID of the equation equation_number belonging to the block block_number
253 254 255 256 257
  virtual NodeID
  getBlockEquationNodeID(int block_number, int equation_number) const
  {
    return (equations[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]]);
  };
258
  //! Return the NodeID of the renormalized equation equation_number belonging to the block block_number
259 260 261 262 263
  virtual NodeID
  getBlockEquationRenormalizedNodeID(int block_number, int equation_number) const
  {
    return (equation_type_and_normalized_equation[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]].second);
  };
264
  //! Return the original number of equation equation_number belonging to the block block_number
265 266 267 268 269
  virtual int
  getBlockEquationID(int block_number, int equation_number) const
  {
    return (equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]);
  };
270
  //! Return the original number of variable variable_number belonging to the block block_number
271 272 273 274 275
  virtual int
  getBlockVariableID(int block_number, int variable_number) const
  {
    return (variable_reordered[block_type_firstequation_size_mfs[block_number].first.second+variable_number]);
  };
276
  //! Return the position of equation_number in the block number belonging to the block block_number
277 278 279 280 281
  virtual int
  getBlockInitialEquationID(int block_number, int equation_number) const
  {
    return ((int) inv_equation_reordered[equation_number] - (int) block_type_firstequation_size_mfs[block_number].first.second);
  };
282
  //! Return the position of variable_number in the block number belonging to the block block_number
283 284 285 286 287
  virtual int
  getBlockInitialVariableID(int block_number, int variable_number) const
  {
    return ((int) inv_variable_reordered[variable_number] - (int) block_type_firstequation_size_mfs[block_number].first.second);
  };
288

sebastien's avatar
sebastien committed
289 290 291
};

#endif