ExprNode.hh 61 KB
Newer Older
1
/*
Houtan Bastani's avatar
Houtan Bastani committed
2
 * Copyright (C) 2007-2016 Dynare Team
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 *
 * 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 _EXPR_NODE_HH
#define _EXPR_NODE_HH

#include <set>
#include <map>
#include <vector>
26
#include <ostream>
27

28
29
using namespace std;

30
31
#include "SymbolTable.hh"
#include "CodeInterpreter.hh"
32
#include "ExternalFunctionsTable.hh"
33
34

class DataTree;
sebastien's avatar
sebastien committed
35
36
class VariableNode;
class BinaryOpNode;
37

38
typedef class ExprNode *expr_t;
39
40
41
42
43

struct ExprNodeLess;

//! Type for set of temporary terms
/*! They are ordered by index number thanks to ExprNodeLess */
44
typedef set<expr_t, ExprNodeLess> temporary_terms_t;
45

46
//! set of temporary terms used in a block
47
typedef set<int> temporary_terms_inuse_t;
48

49
typedef map<int, int> map_idx_t;
50

51
52
//! Type for evaluation contexts
/*! The key is a symbol id. Lags are assumed to be null */
53
typedef map<int, double> eval_context_t;
54

55
//! Type for tracking first/second derivative functions that have already been written as temporary terms
56
typedef map<pair<int, vector<expr_t> >, int> deriv_node_temp_terms_t;
57

58
59
60
//! Possible types of output when writing ExprNode(s)
enum ExprNodeOutputType
  {
61
62
63
64
65
    oMatlabStaticModel,                           //!< Matlab code, static model
    oMatlabDynamicModel,                          //!< Matlab code, dynamic model
    oMatlabStaticModelSparse,                     //!< Matlab code, static block decomposed model
    oMatlabDynamicModelSparse,                    //!< Matlab code, dynamic block decomposed model
    oCDynamicModel,                               //!< C code, dynamic model
66
    oCDynamic2Model,                              //!< C code, dynamic model, alternative numbering of endogenous variables
67
    oCStaticModel,                                //!< C code, static model
Houtan Bastani's avatar
Houtan Bastani committed
68
    oJuliaStaticModel,                            //!< Julia code, static model
Houtan Bastani's avatar
Houtan Bastani committed
69
    oJuliaDynamicModel,                           //!< Julia code, dynamic model
Houtan Bastani's avatar
Houtan Bastani committed
70
    oMatlabOutsideModel,                          //!< Matlab code, outside model block (for example in initval)
71
72
73
74
75
76
    oLatexStaticModel,                            //!< LaTeX code, static model
    oLatexDynamicModel,                           //!< LaTeX code, dynamic model
    oLatexDynamicSteadyStateOperator,             //!< LaTeX code, dynamic model, inside a steady state operator
    oMatlabDynamicSteadyStateOperator,            //!< Matlab code, dynamic model, inside a steady state operator
    oMatlabDynamicSparseSteadyStateOperator,      //!< Matlab code, dynamic block decomposed model, inside a steady state operator
    oCDynamicSteadyStateOperator,                 //!< C code, dynamic model, inside a steady state operator
Houtan Bastani's avatar
Houtan Bastani committed
77
    oJuliaDynamicSteadyStateOperator,             //!< Julia code, dynamic model, inside a steady state operator
Houtan Bastani's avatar
Houtan Bastani committed
78
79
80
    oSteadyStateFile,                             //!< Matlab code, in the generated steady state file
    oCSteadyStateFile,                            //!< C code, in the generated steady state file
    oJuliaSteadyStateFile                         //!< Julia code, in the generated steady state file
81
82
  };

83
84
85
86
#define IS_MATLAB(output_type) ((output_type) == oMatlabStaticModel     \
                                || (output_type) == oMatlabDynamicModel \
                                || (output_type) == oMatlabOutsideModel \
                                || (output_type) == oMatlabStaticModelSparse \
87
                                || (output_type) == oMatlabDynamicModelSparse \
88
                                || (output_type) == oMatlabDynamicSteadyStateOperator \
89
                                || (output_type) == oMatlabDynamicSparseSteadyStateOperator \
90
                                || (output_type) == oSteadyStateFile)
91

Houtan Bastani's avatar
Houtan Bastani committed
92
93
94
95
#define IS_JULIA(output_type) ((output_type) == oJuliaStaticModel     \
                               || (output_type) == oJuliaDynamicModel  \
                               || (output_type) == oJuliaDynamicSteadyStateOperator)

96
#define IS_C(output_type) ((output_type) == oCDynamicModel \
97
			   || (output_type) == oCDynamic2Model \
98
99
100
			   || (output_type) == oCStaticModel \
			   || (output_type) == oCDynamicSteadyStateOperator \
			   || (output_type) == oCSteadyStateFile)
101
102

#define IS_LATEX(output_type) ((output_type) == oLatexStaticModel       \
103
104
                               || (output_type) == oLatexDynamicModel   \
                               || (output_type) == oLatexDynamicSteadyStateOperator)
105

Houtan Bastani's avatar
Houtan Bastani committed
106
107
108
/* Equal to 1 for Matlab langage or Julia, or to 0 for C language. Not defined for LaTeX.
   In Matlab and Julia, array indexes begin at 1, while they begin at 0 in C */
#define ARRAY_SUBSCRIPT_OFFSET(output_type) ((int) (IS_MATLAB(output_type) || IS_JULIA(output_type)))
109

110
111
112
// Left and right array subscript delimiters: '(' and ')' for Matlab, '[' and ']' for C
#define LEFT_ARRAY_SUBSCRIPT(output_type) (IS_MATLAB(output_type) ? '(' : '[')
#define RIGHT_ARRAY_SUBSCRIPT(output_type) (IS_MATLAB(output_type) ? ')' : ']')
113

114
115
116
// Left and right parentheses
#define LEFT_PAR(output_type) (IS_LATEX(output_type) ? "\\left(" : "(")
#define RIGHT_PAR(output_type) (IS_LATEX(output_type) ? "\\right)" : ")")
117
118
119
120

// Computing cost above which a node can be declared a temporary term
#define MIN_COST_MATLAB (40*90)
#define MIN_COST_C (40*4)
sebastien's avatar
sebastien committed
121
#define MIN_COST(is_matlab) ((is_matlab) ? MIN_COST_MATLAB : MIN_COST_C)
122
123
124
125
126

//! Base class for expression nodes
class ExprNode
{
  friend class DataTree;
sebastien's avatar
sebastien committed
127
  friend class DynamicModel;
128
  friend class StaticModel;
129
  friend class ModelTree;
130
  friend struct ExprNodeLess;
131
132
133
134
135
  friend class NumConstNode;
  friend class VariableNode;
  friend class UnaryOpNode;
  friend class BinaryOpNode;
  friend class TrinaryOpNode;
136
  friend class AbstractExternalFunctionNode;
137
private:
138
  //! Computes derivative w.r. to a derivation ID (but doesn't store it in derivatives map)
139
  /*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */
140
  virtual expr_t computeDerivative(int deriv_id) = 0;
141
142
143
144
145
146
147
148

protected:
  //! Reference to the enclosing DataTree
  DataTree &datatree;

  //! Index number
  int idx;

sebastien's avatar
sebastien committed
149
150
151
  //! Is the data member non_null_derivatives initialized ?
  bool preparedForDerivation;

152
  //! Set of derivation IDs with respect to which the derivative is potentially non-null
153
154
155
  set<int> non_null_derivatives;

  //! Used for caching of first order derivatives (when non-null)
156
  map<int, expr_t> derivatives;
157
158
159

  //! Cost of computing current node
  /*! Nodes included in temporary_terms are considered having a null cost */
160
  virtual int cost(int cost, bool is_matlab) const;
161
  virtual int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const;
162
  virtual int cost(const map<NodeTreeReference, temporary_terms_t> &temp_terms_map, bool is_matlab) const;
163

164
165
166
167
168
169
170
171
172
  //! For creating equation cross references
  struct EquationInfo
  {
    set<int> param;
    set<int> endo;
    set<int> exo;
    set<int> exo_det;
  };

173
174
175
176
public:
  ExprNode(DataTree &datatree_arg);
  virtual ~ExprNode();

sebastien's avatar
sebastien committed
177
178
179
  //! Initializes data member non_null_derivatives
  virtual void prepareForDerivation() = 0;

180
  //! Returns derivative w.r. to derivation ID
181
  /*! Uses a symbolic a priori to pre-detect null derivatives, and caches the result for other derivatives (to avoid computing it several times)
182
    For an equal node, returns the derivative of lhs minus rhs */
183
  expr_t getDerivative(int deriv_id);
184

185
186
187
188
189
  //! Computes derivatives by applying the chain rule for some variables
  /*!
    \param deriv_id The derivation ID with respect to which we are derivating
    \param recursive_variables Contains the derivation ID for which chain rules must be applied. Keys are derivation IDs, values are equations of the form x=f(y) where x is the key variable and x doesn't appear in y
  */
190
  virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables) = 0;
ferhat's avatar
ferhat committed
191

192
193
  //! Returns precedence of node
  /*! Equals 100 for constants, variables, unary ops, and temporary terms */
194
  virtual int precedence(ExprNodeOutputType output_t, const temporary_terms_t &temporary_terms) const;
195
196
197

  //! Fills temporary_terms set, using reference counts
  /*! A node will be marked as a temporary term if it is referenced at least two times (i.e. has at least two parents), and has a computing cost (multiplied by reference count) greater to datatree.min_cost */
Houtan Bastani's avatar
temp    
Houtan Bastani committed
198
  virtual void computeTemporaryTerms(map<expr_t, pair<int, NodeTreeReference> > &reference_count,
199
                                     map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
Houtan Bastani's avatar
temp    
Houtan Bastani committed
200
                                     bool is_matlab, NodeTreeReference tr) const;
201

202
203
204
205
206
207
208
  //! Writes output of node, using a Txxx notation for nodes in temporary_terms, and specifiying the set of already written external functions
  /*!
    \param[in] output the output stream
    \param[in] output_type the type of output (MATLAB, C, LaTeX...)
    \param[in] temporary_terms the nodes that are marked as temporary terms
    \param[in,out] tef_terms the set of already written external function nodes
  */
209
  virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0;
210

211
212
213
  //! returns true if the expr node contains an external function
  virtual bool containsExternalFunction() const = 0;

214
  //! Writes output of node (with no temporary terms and with "outside model" output type)
215
  void writeOutput(ostream &output) const;
216

217
218
219
220
  //! Writes output of node (with no temporary terms)
  void writeOutput(ostream &output, ExprNodeOutputType output_type) const;

  //! Writes output of node, using a Txxx notation for nodes in temporary_terms
221
  void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const;
222
223
224

  //! Writes the output for an external function, ensuring that the external function is called as few times as possible using temporary terms
  virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
225
226
                                           const temporary_terms_t &temporary_terms,
                                           deriv_node_temp_terms_t &tef_terms) const;
227

228
  virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
229
230
231
                                             bool lhs_rhs, const temporary_terms_t &temporary_terms,
                                             const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
                                             deriv_node_temp_terms_t &tef_terms) const;
232

233
  //! Computes the set of all variables of a given symbol type in the expression (with information on lags)
sebastien's avatar
sebastien committed
234
235
236
237
238
239
  /*!
    Variables are stored as integer pairs of the form (symb_id, lag).
    They are added to the set given in argument.
    Note that model local variables are substituted by their expression in the computation
    (and added if type_arg = ModelLocalVariable).
  */
240
241
242
243
244
245
246
247
248
249
  virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const = 0;

  //! Computes the set of all variables of a given symbol type in the expression (without information on lags)
  /*!
    Variables are stored as symb_id.
    They are added to the set given in argument.
    Note that model local variables are substituted by their expression in the computation
    (and added if type_arg = ModelLocalVariable).
  */
  void collectVariables(SymbolType type_arg, set<int> &result) const;
sebastien's avatar
sebastien committed
250

251
  //! Computes the set of endogenous variables in the expression
252
  /*!
253
    Endogenous are stored as integer pairs of the form (type_specific_id, lag).
254
    They are added to the set given in argument.
sebastien's avatar
sebastien committed
255
    Note that model local variables are substituted by their expression in the computation.
256
  */
sebastien's avatar
sebastien committed
257
  virtual void collectEndogenous(set<pair<int, int> > &result) const;
258
259
260

  //! Computes the set of exogenous variables in the expression
  /*!
261
    Exogenous are stored as integer pairs of the form (type_specific_id, lag).
262
    They are added to the set given in argument.
sebastien's avatar
sebastien committed
263
    Note that model local variables are substituted by their expression in the computation.
264
  */
sebastien's avatar
sebastien committed
265
266
  virtual void collectExogenous(set<pair<int, int> > &result) const;

267
  virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const = 0;
268

269
  virtual void computeTemporaryTerms(map<expr_t, int> &reference_count,
270
                                     temporary_terms_t &temporary_terms,
271
                                     map<expr_t, pair<int, int> > &first_occurence,
272
                                     int Curr_block,
273
                                     vector< vector<temporary_terms_t> > &v_temporary_terms,
274
                                     int equation) const;
275
276

  class EvalException
ferhat's avatar
ferhat committed
277

278
279
280
  {
  };

281
282
283
284
285
  class EvalExternalFunctionException : public EvalException

  {
  };

286
  virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) = 0;
287
288
  virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const = 0;
  void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const;
sebastien's avatar
sebastien committed
289
290
291
292
293
  //! Creates a static version of this node
  /*!
    This method duplicates the current node by creating a similar node from which all leads/lags have been stripped,
    adds the result in the static_datatree argument (and not in the original datatree), and returns it.
  */
294
  virtual expr_t toStatic(DataTree &static_datatree) const = 0;
295
296
297
298
299
300

  /*!
    Compute cross references for equations
   */
  //  virtual void computeXrefs(set<int> &param, set<int> &endo, set<int> &exo, set<int> &exo_det) const = 0;
  virtual void computeXrefs(EquationInfo &ei) const = 0;
ferhat's avatar
ferhat committed
301
  //! Try to normalize an equation linear in its endogenous variable
302
  virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const = 0;
sebastien's avatar
sebastien committed
303
304
305
306
307

  //! Returns the maximum lead of endogenous in this expression
  /*! Always returns a non-negative value */
  virtual int maxEndoLead() const = 0;

sebastien's avatar
sebastien committed
308
309
310
311
  //! Returns the maximum lead of exogenous in this expression
  /*! Always returns a non-negative value */
  virtual int maxExoLead() const = 0;

312
313
314
315
316
317
318
319
  //! Returns the maximum lag of endogenous in this expression
  /*! Always returns a non-negative value */
  virtual int maxEndoLag() const = 0;

  //! Returns the maximum lag of exogenous in this expression
  /*! Always returns a non-negative value */
  virtual int maxExoLag() const = 0;

320
321
322
323
  //! Returns the relative period of the most forward term in this expression
  /*! A negative value means that the expression contains only lagged variables */
  virtual int maxLead() const = 0;

sebastien's avatar
sebastien committed
324
325
326
327
328
329
  //! Returns a new expression where all the leads/lags have been shifted backwards by the same amount
  /*!
    Only acts on endogenous, exogenous, exogenous det
    \param[in] n The number of lags by which to shift
    \return The same expression except that leads/lags have been shifted backwards
  */
330
  virtual expr_t decreaseLeadsLags(int n) const = 0;
sebastien's avatar
sebastien committed
331
332
333
334

  //! Type for the substitution map used in the process of creating auxiliary vars for leads >= 2
  typedef map<const ExprNode *, const VariableNode *> subst_table_t;

335
  //! Creates auxiliary endo lead variables corresponding to this expression
336
  /*!
sebastien's avatar
sebastien committed
337
338
339
    If maximum endogenous lead >= 3, this method will also create intermediary auxiliary var, and will add the equations of the form aux1 = aux2(+1) to the substitution table.
    \pre This expression is assumed to have maximum endogenous lead >= 2
    \param[in,out] subst_table The table to which new auxiliary variables and their correspondance will be added
sebastien's avatar
sebastien committed
340
    \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
sebastien's avatar
sebastien committed
341
342
    \return The new variable node corresponding to the current expression
  */
343
  VariableNode *createEndoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
sebastien's avatar
sebastien committed
344

sebastien's avatar
sebastien committed
345
  //! Creates auxiliary exo lead variables corresponding to this expression
346
  /*!
sebastien's avatar
sebastien committed
347
348
349
350
351
352
353
354
    If maximum exogenous lead >= 2, this method will also create intermediary auxiliary var, and will add the equations of the form aux1 = aux2(+1) to the substitution table.
    \pre This expression is assumed to have maximum exogenous lead >= 1
    \param[in,out] subst_table The table to which new auxiliary variables and their correspondance will be added
    \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
    \return The new variable node corresponding to the current expression
  */
  VariableNode *createExoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;

sebastien's avatar
sebastien committed
355
356
357
358
359
360
361
362
363
364
  //! Constructs a new expression where sub-expressions with max endo lead >= 2 have been replaced by auxiliary variables
  /*!
    \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr.
    \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.

    If the method detects a sub-expr which needs to be substituted, two cases are possible:
    - if this expr is in the table, then it will use the corresponding variable and return the substituted expression
    - if this expr is not in the table, then it will create an auxiliary endogenous variable, add the substitution in the table and return the substituted expression

    \return A new equivalent expression where sub-expressions with max endo lead >= 2 have been replaced by auxiliary variables
365
  */
366
  virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const = 0;
sebastien's avatar
sebastien committed
367
368
369
370
371
372

  //! Constructs a new expression where endo variables with max endo lag >= 2 have been replaced by auxiliary variables
  /*!
    \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr.
    \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
  */
373
  virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
374

sebastien's avatar
sebastien committed
375
376
377
378
379
  //! Constructs a new expression where exogenous variables with a lead have been replaced by auxiliary variables
  /*!
    \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr.
    \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
  */
380
  virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const = 0;
sebastien's avatar
sebastien committed
381
  //! Constructs a new expression where exogenous variables with a lag have been replaced by auxiliary variables
382
383
384
385
  /*!
    \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr.
    \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
  */
386
  virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
387
388
389
390
391

  //! Constructs a new expression where the expectation operator has been replaced by auxiliary variables
  /*!
    \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr.
    \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
sebastien's avatar
sebastien committed
392
    \param[in] partial_information_model Are we substituting in a partial information model?
393
  */
394
  virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const = 0;
395

396
  virtual expr_t decreaseLeadsLagsPredeterminedVariables() const = 0;
397

398
399
  //! Constructs a new expression where forward variables (supposed to be at most in t+1) have been replaced by themselves at t, plus a new aux var representing their (time) differentiate
  /*!
400
401
    \param[in] subset variables to which to limit the transformation; transform
    all fwrd vars if empty
402
403
404
405
    \param[in,out] subst_table Map used to store mapping between a given
    forward variable and the aux var that contains its differentiate
    \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
  */
406
  virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
407

408
409
410
411
  //! Return true if the nodeID is a numerical constant equal to value and false otherwise
  /*!
    \param[in] value of the numerical constante
    \param[out] the boolean equal to true if NodeId is a constant equal to value
412
  */
413
414
  virtual bool isNumConstNodeEqualTo(double value) const = 0;

415
416
417
  //! Returns true if the expression contains one or several endogenous variable
  virtual bool containsEndogenous(void) const = 0;

418
419
420
421
  //! Return true if the nodeID is a variable withe a type equal to type_arg, a specific variable id aqual to varfiable_id and a lag equal to lag_arg and false otherwise
  /*!
    \param[in] the type (type_arg), specifique variable id (variable_id and the lag (lag_arg)
    \param[out] the boolean equal to true if NodeId is the variable
422
  */
423
424
  virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const = 0;

425
426
427
428
429
430
  //! Replaces the Trend var with datatree.One
  virtual expr_t replaceTrendVar() const = 0;

  //! Constructs a new expression where the variable indicated by symb_id has been detrended
  /*!
    \param[in] symb_id indicating the variable to be detrended
431
432
433
    \param[in] log_trend indicates if the trend is in log
    \param[in] trend indicating the trend
    \return the new binary op pointing to a detrended variable
434
  */
435
  virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const = 0;
436
437
438
439
440
441

  //! Add ExprNodes to the provided datatree
  virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const = 0;

  //! Move a trend variable with lag/lead to time t by dividing/multiplying by its growth factor
  virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const = 0;
442
443
444

  //! Returns true if the expression is in static form (no lead, no lag, no expectation, no STEADY_STATE)
  virtual bool isInStaticForm() const = 0;
445
446
447

  //! Substitute auxiliary variables by their expression in static model
  virtual expr_t substituteStaticAuxiliaryVariable() const = 0;
448
449
450
451
452
};

//! Object used to compare two nodes (using their indexes)
struct ExprNodeLess
{
453
  bool
454
  operator()(expr_t arg1, expr_t arg2) const
455
456
457
458
459
460
461
462
463
464
465
466
  {
    return arg1->idx < arg2->idx;
  }
};

//! Numerical constant node
/*! The constant is necessarily non-negative (this is enforced at the NumericalConstants class level) */
class NumConstNode : public ExprNode
{
private:
  //! Id from numerical constants table
  const int id;
467
  virtual expr_t computeDerivative(int deriv_id);
468
469
public:
  NumConstNode(DataTree &datatree_arg, int id_arg);
470
471
472
473
474
  int
  get_id() const
  {
    return id;
  };
sebastien's avatar
sebastien committed
475
  virtual void prepareForDerivation();
476
  virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
477
  virtual bool containsExternalFunction() const;
478
  virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
479
  virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
480
  virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException);
481
  virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const;
482
  virtual expr_t toStatic(DataTree &static_datatree) const;
483
  virtual void computeXrefs(EquationInfo &ei) const;
484
485
  virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > >  &List_of_Op_RHS) const;
  virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables);
sebastien's avatar
sebastien committed
486
  virtual int maxEndoLead() const;
sebastien's avatar
sebastien committed
487
  virtual int maxExoLead() const;
488
489
  virtual int maxEndoLag() const;
  virtual int maxExoLag() const;
490
  virtual int maxLead() const;
491
  virtual expr_t decreaseLeadsLags(int n) const;
492
  virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const;
493
  virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
494
  virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const;
495
496
497
  virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
  virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
  virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
498
  virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
499
  virtual bool isNumConstNodeEqualTo(double value) const;
500
  virtual bool containsEndogenous(void) const;
501
  virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
502
  virtual expr_t replaceTrendVar() const;
503
  virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const;
504
505
  virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
  virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
506
  virtual bool isInStaticForm() const;
507
  virtual expr_t substituteStaticAuxiliaryVariable() const;
508
509
510
511
512
};

//! Symbol or variable node
class VariableNode : public ExprNode
{
513
  friend class UnaryOpNode;
514
515
516
private:
  //! Id from the symbol table
  const int symb_id;
517
  const SymbolType type;
518
  //! A positive value is a lead, a negative is a lag
519
  const int lag;
520
  virtual expr_t computeDerivative(int deriv_id);
521
public:
sebastien's avatar
sebastien committed
522
523
  VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg);
  virtual void prepareForDerivation();
524
  virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
525
  virtual bool containsExternalFunction() const;
526
  virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
Houtan Bastani's avatar
temp    
Houtan Bastani committed
527
  virtual void computeTemporaryTerms(map<expr_t, int > &reference_count,
528
                                     temporary_terms_t &temporary_terms,
529
                                     map<expr_t, pair<int, int> > &first_occurence,
530
                                     int Curr_block,
531
                                     vector< vector<temporary_terms_t> > &v_temporary_terms,
532
                                     int equation) const;
533
  virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
534
  virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException);
535
  virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const;
536
  virtual expr_t toStatic(DataTree &static_datatree) const;
537
  virtual void computeXrefs(EquationInfo &ei) const;
538
539
540
541
542
  SymbolType
  get_type() const
  {
    return type;
  };
543
544
545
546
547
  int
  get_symb_id() const
  {
    return symb_id;
  };
548
  int get_lag() const { return lag; };
549
550
  virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > >  &List_of_Op_RHS) const;
  virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables);
sebastien's avatar
sebastien committed
551
  virtual int maxEndoLead() const;
sebastien's avatar
sebastien committed
552
  virtual int maxExoLead() const;
553
554
  virtual int maxEndoLag() const;
  virtual int maxExoLag() const;
555
  virtual int maxLead() const;
556
  virtual expr_t decreaseLeadsLags(int n) const;
557
  virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const;
558
  virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
559
  virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const;
560
561
562
  virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
  virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
  virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
563
  virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
564
  virtual bool isNumConstNodeEqualTo(double value) const;
565
  virtual bool containsEndogenous(void) const;
566
  virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
567
  virtual expr_t replaceTrendVar() const;
568
  virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const;
569
570
  virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
  virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
571
  virtual bool isInStaticForm() const;
572
573
  //! Substitute auxiliary variables by their expression in static model
  virtual expr_t substituteStaticAuxiliaryVariable() const;
574
575
576
577
578
579
};

//! Unary operator node
class UnaryOpNode : public ExprNode
{
private:
580
  const expr_t arg;
sebastien's avatar
sebastien committed
581
582
  //! Stores the information set. Only used for expectation operator
  const int expectation_information_set;
583
584
  //! Only used for oSteadyStateParamDeriv and oSteadyStateParam2ndDeriv
  const int param1_symb_id, param2_symb_id;
585
  const UnaryOpcode op_code;
586
  virtual expr_t computeDerivative(int deriv_id);
587
  virtual int cost(int cost, bool is_matlab) const;
588
  virtual int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const;
589
  virtual int cost(const map<NodeTreeReference, temporary_terms_t> &temp_terms_map, bool is_matlab) const;
590
  //! Returns the derivative of this node if darg is the derivative of the argument
591
  expr_t composeDerivatives(expr_t darg, int deriv_id);
592
public:
593
  UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg);
sebastien's avatar
sebastien committed
594
  virtual void prepareForDerivation();
Houtan Bastani's avatar
temp    
Houtan Bastani committed
595
  virtual void computeTemporaryTerms(map<expr_t, pair<int, NodeTreeReference> > &reference_count,
596
                                     map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
Houtan Bastani's avatar
temp    
Houtan Bastani committed
597
                                     bool is_matlab, NodeTreeReference tr) const;
598
  virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
599
  virtual bool containsExternalFunction() const;
600
  virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
601
602
                                           const temporary_terms_t &temporary_terms,
                                           deriv_node_temp_terms_t &tef_terms) const;
603
604
605
606
  virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
                                             bool lhs_rhs, const temporary_terms_t &temporary_terms,
                                             const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
                                             deriv_node_temp_terms_t &tef_terms) const;
607
  virtual void computeTemporaryTerms(map<expr_t, int> &reference_count,
608
                                     temporary_terms_t &temporary_terms,
609
                                     map<expr_t, pair<int, int> > &first_occurence,
610
                                     int Curr_block,
611
                                     vector< vector<temporary_terms_t> > &v_temporary_terms,
612
                                     int equation) const;
613
  virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
614
  virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
615
616
  static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException, EvalExternalFunctionException);
  virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException);
617
  virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const;
sebastien's avatar
sebastien committed
618
  //! Returns operand
619
  expr_t
620
621
622
623
  get_arg() const
  {
    return (arg);
  };
sebastien's avatar
sebastien committed
624
  //! Returns op code
625
626
627
628
629
  UnaryOpcode
  get_op_code() const
  {
    return (op_code);
  };
630
  virtual expr_t toStatic(DataTree &static_datatree) const;
631
  virtual void computeXrefs(EquationInfo &ei) const;
632
633
  virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > >  &List_of_Op_RHS) const;
  virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables);
sebastien's avatar
sebastien committed
634
  virtual int maxEndoLead() const;
sebastien's avatar
sebastien committed
635
  virtual int maxExoLead() const;
636
637
  virtual int maxEndoLag() const;
  virtual int maxExoLag() const;
638
  virtual int maxLead() const;
639
  virtual expr_t decreaseLeadsLags(int n) const;
640
  virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const;
sebastien's avatar
sebastien committed
641
  //! Creates another UnaryOpNode with the same opcode, but with a possibly different datatree and argument
642
643
  expr_t buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) const;
  virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
644
  virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const;
645
646
647
  virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
  virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
  virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
648
  virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
649
  virtual bool isNumConstNodeEqualTo(double value) const;
650
  virtual bool containsEndogenous(void) const;
651
  virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
652
  virtual expr_t replaceTrendVar() const;
653
  virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const;
654
655
  virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
  virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
656
  virtual bool isInStaticForm() const;
657
658
  //! Substitute auxiliary variables by their expression in static model
  virtual expr_t substituteStaticAuxiliaryVariable() const;
659
660
661
662
663
664
};

//! Binary operator node
class BinaryOpNode : public ExprNode
{
private:
665
  const expr_t arg1, arg2;
666
  const BinaryOpcode op_code;
667
  virtual expr_t computeDerivative(int deriv_id);
668
  virtual int cost(int cost, bool is_matlab) const;
669
  virtual int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const;
670
  virtual int cost(const map<NodeTreeReference, temporary_terms_t> &temp_terms_map, bool is_matlab) const;
671
  //! Returns the derivative of this node if darg1 and darg2 are the derivatives of the arguments
672
  expr_t composeDerivatives(expr_t darg1, expr_t darg2);
673
  const int powerDerivOrder;
674
public:
675
676
  BinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg,
               BinaryOpcode op_code_arg, const expr_t arg2_arg);
677
678
  BinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg,
               BinaryOpcode op_code_arg, const expr_t arg2_arg, int powerDerivOrder);
sebastien's avatar
sebastien committed
679
  virtual void prepareForDerivation();
680
  virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const;
Houtan Bastani's avatar
temp    
Houtan Bastani committed
681
  virtual void computeTemporaryTerms(map<expr_t, pair<int, NodeTreeReference> > &reference_count,
682
                                     map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
Houtan Bastani's avatar
temp    
Houtan Bastani committed
683
                                     bool is_matlab, NodeTreeReference tr) const;
684
  virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
685
  virtual bool containsExternalFunction() const;
686
  virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
687
688
                                           const temporary_terms_t &temporary_terms,
                                           deriv_node_temp_terms_t &tef_terms) const;
689
690
691
692
  virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
                                             bool lhs_rhs, const temporary_terms_t &temporary_terms,
                                             const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
                                             deriv_node_temp_terms_t &tef_terms) const;
693
  virtual void computeTemporaryTerms(map<expr_t, int> &reference_count,
694
                                     temporary_terms_t &temporary_terms,
695
                                     map<expr_t, pair<int, int> > &first_occurence,
696
                                     int Curr_block,
697
                                     vector< vector<temporary_terms_t> > &v_temporary_terms,
698
                                     int equation) const;
699
  virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
700
  virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
701
702
  static double eval_opcode(double v1, BinaryOpcode op_code, double v2, int derivOrder) throw (EvalException, EvalExternalFunctionException);
  virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException);
703
  virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const;
704
  virtual expr_t Compute_RHS(expr_t arg1, expr_t arg2, int op, int op_type) const;
sebastien's avatar
sebastien committed
705
  //! Returns first operand
706
  expr_t
707
708
709
710
  get_arg1() const
  {
    return (arg1);
  };
sebastien's avatar
sebastien committed
711
  //! Returns second operand
712
  expr_t
713
714
715
716
  get_arg2() const
  {
    return (arg2);
  };
sebastien's avatar
sebastien committed
717
  //! Returns op code
718
719
720
721
722
  BinaryOpcode
  get_op_code() const
  {
    return (op_code);
  };
723
724
725
726
727
  int
  get_power_deriv_order() const
  {
    return powerDerivOrder;
  }
728
  virtual expr_t toStatic(DataTree &static_datatree) const;
729
  virtual void computeXrefs(EquationInfo &ei) const;
730
731
  virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > >  &List_of_Op_RHS) const;
  virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables);
sebastien's avatar
sebastien committed
732
  virtual int maxEndoLead() const;
sebastien's avatar
sebastien committed
733
  virtual int maxExoLead() const;
734
735
  virtual int maxEndoLag() const;
  virtual int maxExoLag() const;
736
  virtual int maxLead() const;
737
  virtual expr_t decreaseLeadsLags(int n) const;
738
  virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const;
sebastien's avatar
sebastien committed
739
  //! Creates another BinaryOpNode with the same opcode, but with a possibly different datatree and arguments
740
741
  expr_t buildSimilarBinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, DataTree &alt_datatree) const;
  virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
742
  virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const;
743
744
745
  virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
  virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
  virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
746
  virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
747
  virtual bool isNumConstNodeEqualTo(double value) const;
748
  virtual bool containsEndogenous(void) const;
749
  virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
750
  virtual expr_t replaceTrendVar() const;
751
  virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const;
752
753
  virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
  virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
754
755
  //! Function to write out the oPowerNode in expr_t terms as opposed to writing out the function itself
  expr_t unpackPowerDeriv() const;
Houtan Bastani's avatar
Houtan Bastani committed
756
  //! Returns MULT_i*(lhs-rhs) = 0, creating multiplier MULT_i
757
758
759
  expr_t addMultipliersToConstraints(int i);
  //! Returns the non-zero hand-side of an equation (that must have a hand side equal to zero)
  expr_t getNonZeroPartofEquation() const;
760
  virtual bool isInStaticForm() const;
761
762
763
764
  //! Substitute auxiliary variables by their expression in static model
  virtual expr_t substituteStaticAuxiliaryVariable() const;
  //! Substitute auxiliary variables by their expression in static model auxiliary variable definition
  virtual expr_t substituteStaticAuxiliaryDefinition() const;
765
766
767
768
769
770
771
};

//! Trinary operator node
class TrinaryOpNode : public ExprNode
{
  friend class ModelTree;
private:
772
  const expr_t arg1, arg2, arg3;
773
  const TrinaryOpcode op_code;
774
  virtual expr_t computeDerivative(int deriv_id);
775
  virtual int cost(int cost, bool is_matlab) const;
776
  virtual int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const;
777
  virtual int cost(const map<NodeTreeReference, temporary_terms_t> &temp_terms_map, bool is_matlab) const;
778
  //! Returns the derivative of this node if darg1, darg2 and darg3 are the derivatives of the arguments
779
  expr_t composeDerivatives(expr_t darg1, expr_t darg2, expr_t darg3);
780
public:
781
782
  TrinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg,
                TrinaryOpcode op_code_arg, const expr_t arg2_arg, const expr_t arg3_arg);
sebastien's avatar
sebastien committed
783
  virtual void prepareForDerivation();
784
  virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const;
Houtan Bastani's avatar
temp    
Houtan Bastani committed
785
  virtual void computeTemporaryTerms(map<expr_t, pair<int, NodeTreeReference> > &reference_count,
786
                                     map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
Houtan Bastani's avatar
temp    
Houtan Bastani committed
787
                                     bool is_matlab, NodeTreeReference tr) const;
788
  virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
789
  virtual bool containsExternalFunction() const;
790
  virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
791
792
                                           const temporary_terms_t &temporary_terms,
                                           deriv_node_temp_terms_t &tef_terms) const;
793
794
795
796
  virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
                                             bool lhs_rhs, const temporary_terms_t &temporary_terms,
                                             const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
                                             deriv_node_temp_terms_t &tef_terms) const;
797
  virtual void computeTemporaryTerms(map<expr_t, int> &reference_count,
798
                                     temporary_terms_t &temporary_terms,
799
                                     map<expr_t, pair<int, int> > &first_occurence,
800
                                     int Curr_block,
801
                                     vector< vector<temporary_terms_t> > &v_temporary_terms,
802
                                     int equation) const;
803
  virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
804
  virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
805
806
  static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException, EvalExternalFunctionException);
  virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException);
807
  virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const;
808
  virtual expr_t toStatic(DataTree &static_datatree) const;
809
  virtual void computeXrefs(EquationInfo &ei) const;
810
811
  virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<pair<int, pair<expr_t, expr_t> > >  &List_of_Op_RHS) const;
  virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables);
sebastien's avatar
sebastien committed
812
  virtual int maxEndoLead() const;
sebastien's avatar
sebastien committed
813
  virtual int maxExoLead() const;
814
815
  virtual int maxEndoLag() const;
  virtual int maxExoLag() const;
816
  virtual int maxLead() const;
817
  virtual expr_t decreaseLeadsLags(int n) const;
818
  virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const;
sebastien's avatar
sebastien committed
819
  //! Creates another TrinaryOpNode with the same opcode, but with a possibly different datatree and arguments
820
821
  expr_t buildSimilarTrinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, expr_t alt_arg3, DataTree &alt_datatree) const;
  virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
822
  virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const;
823