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

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 29 30 31 32

#include "ModelTree.hh"

//! Stores a static model
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 64
  //! Writes the code of the Block reordred structure of the model in virtual machine bytecode
  void writeModelEquationsCodeOrdered(const string file_name, const string bin_basename, map_idx_type map_idx) const;
65

66 67 68 69 70 71
  //! 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);
72

73
  map_idx_type map_idx;
sebastien's avatar
sebastien committed
74

75 76
  void computeTemporaryTermsOrdered();
  //! Write derivative code of an equation w.r. to a variable
sebastien's avatar
sebastien committed
77
  void compileDerivative(ofstream &code_file, int eq, int symb_id, map_idx_type &map_idx) const;
78 79
  //! 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;
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 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
  //! 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;
144

sebastien's avatar
sebastien committed
145 146
public:
  StaticModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants);
147 148

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

151 152 153 154
  //! 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
155 156 157
    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 */
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
  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
  */
  void computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool hessian, bool block);

  //! Adds informations for simulation in a binary file
  void Write_Inf_To_Bin_File(const string &static_basename, const string &bin_basename, const int &num,
                             int &u_count_int, bool &file_open) const;

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

179 180 181
  //! Writes LaTeX file with the equations of the static model
  void writeLatexFile(const string &basename) const;

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

185
  virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException);
186 187

  //! Return the number of blocks
188 189 190 191 192
  virtual unsigned int
  getNbBlocks() const
  {
    return (block_type_firstequation_size_mfs.size());
  };
193
  //! Determine the simulation type of each block
194 195 196 197 198
  virtual BlockSimulationType
  getBlockSimulationType(int block_number) const
  {
    return (block_type_firstequation_size_mfs[block_number].first.first);
  };
199
  //! Return the first equation number of a block
200 201 202 203 204
  virtual unsigned int
  getBlockFirstEquation(int block_number) const
  {
    return (block_type_firstequation_size_mfs[block_number].first.second);
  };
205
  //! Return the size of the block block_number
206 207 208 209 210
  virtual unsigned int
  getBlockSize(int block_number) const
  {
    return (block_type_firstequation_size_mfs[block_number].second.first);
  };
211
  //! Return the number of feedback variable of the block block_number
212 213 214 215 216
  virtual unsigned int
  getBlockMfs(int block_number) const
  {
    return (block_type_firstequation_size_mfs[block_number].second.second);
  };
217
  //! Return the maximum lag in a block
218 219 220 221 222
  virtual unsigned int
  getBlockMaxLag(int block_number) const
  {
    return (block_lag_lead[block_number].first);
  };
223
  //! Return the maximum lead in a block
224 225 226 227 228
  virtual unsigned int
  getBlockMaxLead(int block_number) const
  {
    return (block_lag_lead[block_number].second);
  };
229
  //! Return the type of equation (equation_number) belonging to the block block_number
230 231 232 233 234
  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);
  };
235
  //! Return true if the equation has been normalized
236 237 238 239 240
  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);
  };
241
  //! Return the NodeID of the equation equation_number belonging to the block block_number
242 243 244 245 246
  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]]);
  };
247
  //! Return the NodeID of the renormalized equation equation_number belonging to the block block_number
248 249 250 251 252
  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);
  };
253
  //! Return the original number of equation equation_number belonging to the block block_number
254 255 256 257 258
  virtual int
  getBlockEquationID(int block_number, int equation_number) const
  {
    return (equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]);
  };
259
  //! Return the original number of variable variable_number belonging to the block block_number
260 261 262 263 264
  virtual int
  getBlockVariableID(int block_number, int variable_number) const
  {
    return (variable_reordered[block_type_firstequation_size_mfs[block_number].first.second+variable_number]);
  };
265
  //! Return the position of equation_number in the block number belonging to the block block_number
266 267 268 269 270
  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);
  };
271
  //! Return the position of variable_number in the block number belonging to the block block_number
272 273 274 275 276
  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);
  };
277

sebastien's avatar
sebastien committed
278 279 280
};

#endif