1 /*
2 * Copyright © 2007-2019 Dynare Team
3 *
4 * This file is part of Dynare.
5 *
6 * Dynare is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Dynare is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Dynare. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef _EXPR_NODE_HH
21 #define _EXPR_NODE_HH
22
23 #include <set>
24 #include <map>
25 #include <vector>
26 #include <ostream>
27 #include <functional>
28
29 using namespace std;
30
31 #include "CodeInterpreter.hh"
32 #include "ExternalFunctionsTable.hh"
33
34 class DataTree;
35 class NumConstNode;
36 class VariableNode;
37 class UnaryOpNode;
38 class BinaryOpNode;
39 class PacExpectationNode;
40
41 using expr_t = class ExprNode *;
42
43 struct ExprNodeLess;
44
45 //! Type for set of temporary terms
46 /*! The ExprNodeLess ordering is important for the temporary terms algorithm,
47 see the definition of ExprNodeLess */
48 using temporary_terms_t = set<expr_t, ExprNodeLess>;
49 /*! Keeps track of array indices of temporary_terms for writing */
50 using temporary_terms_idxs_t = map<expr_t, int>;
51
52 //! set of temporary terms used in a block
53 using temporary_terms_inuse_t = set<int>;
54
55 using map_idx_t = map<int, int>;
56
57 //! Type for evaluation contexts
58 /*! The key is a symbol id. Lags are assumed to be null */
59 using eval_context_t = map<int, double>;
60
61 //! Type for tracking first/second derivative functions that have already been written as temporary terms
62 using deriv_node_temp_terms_t = map<pair<int, vector<expr_t>>, int>;
63
64 //! Type for the substitution map used for creating aux. vars for diff and unary_ops
65 /*! Let ≅ be the equivalence relationship such that two expressions e₁ and e₂
66 are equivalent iff e₁ can be obtained from e₂ by shifting all leads/lags by
67 the same number of periods (e.g. x₋₁+y₂≅x₁+y₄).
68
69 For each equivalence class, we select a representative element, which is
70 the class member which has no lead and a variable appearing at current
71 period (in the previous example, it would be x₋₃+y). (Obviously, if there
72 is no variable in the expression, then there is only one element in the
73 class, and that one is the representative)
74
75 Each member of an equivalence class is represented by an integer,
76 corresponding to its distance to the representative element (e.g. x₋₁+y₂
77 has index 2 and x₁+y₄ has index 4). The representative element has index 0
78 by definition.
79
80 The keys in the std::map are the representative elements of the various
81 equivalence classes. The values are themselves std::map that describe the
82 equivalence class: they associate indices of class members to the
83 expressions with which they should be substituted. */
84 using lag_equivalence_table_t = map<expr_t, map<int, expr_t>>;
85
86 //! Possible types of output when writing ExprNode(s)
87 enum class ExprNodeOutputType
88 {
89 matlabStaticModel, //!< Matlab code, static model
90 matlabDynamicModel, //!< Matlab code, dynamic model
91 matlabStaticModelSparse, //!< Matlab code, static block decomposed model
92 matlabDynamicModelSparse, //!< Matlab code, dynamic block decomposed model
93 CDynamicModel, //!< C code, dynamic model
94 CStaticModel, //!< C code, static model
95 juliaStaticModel, //!< Julia code, static model
96 juliaDynamicModel, //!< Julia code, dynamic model
97 matlabOutsideModel, //!< Matlab code, outside model block (for example in initval)
98 latexStaticModel, //!< LaTeX code, static model
99 latexDynamicModel, //!< LaTeX code, dynamic model
100 latexDynamicSteadyStateOperator, //!< LaTeX code, dynamic model, inside a steady state operator
101 matlabDynamicSteadyStateOperator, //!< Matlab code, dynamic model, inside a steady state operator
102 matlabDynamicSparseSteadyStateOperator, //!< Matlab code, dynamic block decomposed model, inside a steady state operator
103 CDynamicSteadyStateOperator, //!< C code, dynamic model, inside a steady state operator
104 juliaDynamicSteadyStateOperator, //!< Julia code, dynamic model, inside a steady state operator
105 steadyStateFile, //!< Matlab code, in the generated steady state file
106 juliaSteadyStateFile, //!< Julia code, in the generated steady state file
107 matlabDseries, //!< Matlab code for dseries
108 epilogueFile //!< Matlab code, in the generated epilogue file
109 };
110
111 inline bool
isMatlabOutput(ExprNodeOutputType output_type)112 isMatlabOutput(ExprNodeOutputType output_type)
113 {
114 return output_type == ExprNodeOutputType::matlabStaticModel
115 || output_type == ExprNodeOutputType::matlabDynamicModel
116 || output_type == ExprNodeOutputType::matlabOutsideModel
117 || output_type == ExprNodeOutputType::matlabStaticModelSparse
118 || output_type == ExprNodeOutputType::matlabDynamicModelSparse
119 || output_type == ExprNodeOutputType::matlabDynamicSteadyStateOperator
120 || output_type == ExprNodeOutputType::matlabDynamicSparseSteadyStateOperator
121 || output_type == ExprNodeOutputType::steadyStateFile
122 || output_type == ExprNodeOutputType::matlabDseries
123 || output_type == ExprNodeOutputType::epilogueFile;
124 }
125
126 inline bool
isJuliaOutput(ExprNodeOutputType output_type)127 isJuliaOutput(ExprNodeOutputType output_type)
128 {
129 return output_type == ExprNodeOutputType::juliaStaticModel
130 || output_type == ExprNodeOutputType::juliaDynamicModel
131 || output_type == ExprNodeOutputType::juliaDynamicSteadyStateOperator
132 || output_type == ExprNodeOutputType::juliaSteadyStateFile;
133 }
134
135 inline bool
isCOutput(ExprNodeOutputType output_type)136 isCOutput(ExprNodeOutputType output_type)
137 {
138 return output_type == ExprNodeOutputType::CDynamicModel
139 || output_type == ExprNodeOutputType::CStaticModel
140 || output_type == ExprNodeOutputType::CDynamicSteadyStateOperator;
141 }
142
143 inline bool
isLatexOutput(ExprNodeOutputType output_type)144 isLatexOutput(ExprNodeOutputType output_type)
145 {
146 return output_type == ExprNodeOutputType::latexStaticModel
147 || output_type == ExprNodeOutputType::latexDynamicModel
148 || output_type == ExprNodeOutputType::latexDynamicSteadyStateOperator;
149 }
150
151 /* Equal to 1 for Matlab langage or Julia, or to 0 for C language. Not defined for LaTeX.
152 In Matlab and Julia, array indexes begin at 1, while they begin at 0 in C */
153 inline int
ARRAY_SUBSCRIPT_OFFSET(ExprNodeOutputType output_type)154 ARRAY_SUBSCRIPT_OFFSET(ExprNodeOutputType output_type)
155 {
156 return static_cast<int>(isMatlabOutput(output_type) || isJuliaOutput(output_type));
157 }
158
159 // Left and right array subscript delimiters: '(' and ')' for Matlab, '[' and ']' for C
160 inline char
LEFT_ARRAY_SUBSCRIPT(ExprNodeOutputType output_type)161 LEFT_ARRAY_SUBSCRIPT(ExprNodeOutputType output_type)
162 {
163 return isMatlabOutput(output_type) ? '(' : '[';
164 }
165
166 inline char
RIGHT_ARRAY_SUBSCRIPT(ExprNodeOutputType output_type)167 RIGHT_ARRAY_SUBSCRIPT(ExprNodeOutputType output_type)
168 {
169 return isMatlabOutput(output_type) ? ')' : ']';
170 }
171
172 // Left and right parentheses
173 inline string
LEFT_PAR(ExprNodeOutputType output_type)174 LEFT_PAR(ExprNodeOutputType output_type)
175 {
176 return isLatexOutput(output_type) ? "\\left(" : "(";
177 }
178
179 inline string
RIGHT_PAR(ExprNodeOutputType output_type)180 RIGHT_PAR(ExprNodeOutputType output_type)
181 {
182 return isLatexOutput(output_type) ? "\\right)" : ")";
183 }
184
185 //! Base class for expression nodes
186 class ExprNode
187 {
188 friend class DataTree;
189 friend class DynamicModel;
190 friend class StaticModel;
191 friend class ModelTree;
192 friend struct ExprNodeLess;
193 friend class NumConstNode;
194 friend class VariableNode;
195 friend class UnaryOpNode;
196 friend class BinaryOpNode;
197 friend class TrinaryOpNode;
198 friend class AbstractExternalFunctionNode;
199 friend class VarExpectationNode;
200 friend class PacExpectationNode;
201 private:
202 //! Computes derivative w.r. to a derivation ID (but doesn't store it in derivatives map)
203 /*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */
204 virtual expr_t computeDerivative(int deriv_id) = 0;
205
206 protected:
207 //! Reference to the enclosing DataTree
208 DataTree &datatree;
209
210 //! Index number
211 const int idx;
212
213 //! Is the data member non_null_derivatives initialized ?
214 bool preparedForDerivation{false};
215
216 //! Set of derivation IDs with respect to which the derivative is potentially non-null
217 set<int> non_null_derivatives;
218
219 //! Used for caching of first order derivatives (when non-null)
220 map<int, expr_t> derivatives;
221
222 constexpr static int min_cost_matlab{40*90};
223 constexpr static int min_cost_c{40*4};
224 inline static int
min_cost(bool is_matlab)225 min_cost(bool is_matlab)
226 {
227 return (is_matlab ? min_cost_matlab : min_cost_c);
228 };
229
230 //! Cost of computing current node
231 /*! Nodes included in temporary_terms are considered having a null cost */
232 virtual int cost(int cost, bool is_matlab) const;
233 virtual int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const;
234 virtual int cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map, bool is_matlab) const;
235
236 //! For creating equation cross references
237 struct EquationInfo
238 {
239 set<pair<int, int>> param;
240 set<pair<int, int>> endo;
241 set<pair<int, int>> exo;
242 set<pair<int, int>> exo_det;
243 };
244
245 //! If this node is a temporary term, writes its temporary term representation
246 /*! Returns true if node is a temporary term and has therefore been
247 written to output*/
248 bool checkIfTemporaryTermThenWrite(ostream &output, ExprNodeOutputType output_type,
249 const temporary_terms_t &temporary_terms,
250 const temporary_terms_idxs_t &temporary_terms_idxs) const;
251
252 // Internal helper for matchVariableTimesConstantTimesParam()
253 virtual void matchVTCTPHelper(int &var_id, int &lag, int ¶m_id, double &constant, bool at_denominator) const;
254
255 /* Computes the representative element and the index under the
256 lag-equivalence relationship. See the comment above
257 lag_equivalence_table_t for an explanation of these concepts. */
258 pair<expr_t, int> getLagEquivalenceClass() const;
259
260 public:
261 ExprNode(DataTree &datatree_arg, int idx_arg);
262 virtual ~ExprNode() = default;
263
264 ExprNode(const ExprNode &) = delete;
265 ExprNode(ExprNode &&) = delete;
266 ExprNode &operator=(const ExprNode &) = delete;
267 ExprNode &operator=(ExprNode &&) = delete;
268
269 //! Initializes data member non_null_derivatives
270 virtual void prepareForDerivation() = 0;
271
272 //! Returns derivative w.r. to derivation ID
273 /*! Uses a symbolic a priori to pre-detect null derivatives, and caches the result for other derivatives (to avoid computing it several times)
274 For an equal node, returns the derivative of lhs minus rhs */
275 expr_t getDerivative(int deriv_id);
276
277 //! Computes derivatives by applying the chain rule for some variables
278 /*!
279 \param deriv_id The derivation ID with respect to which we are derivating
280 \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
281 */
282 virtual expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables) = 0;
283
284 //! Returns precedence of node
285 /*! Equals 100 for constants, variables, unary ops, and temporary terms */
286 virtual int precedence(ExprNodeOutputType output_t, const temporary_terms_t &temporary_terms) const;
287
288 //! Compute temporary terms in this expression
289 /*!
290 \param[in] derivOrder the derivation order (first w.r.t. endo/exo,
291 second w.r.t. params)
292 \param[out] temp_terms_map the computed temporary terms, associated
293 with their derivation order
294 \param[out] reference_count a temporary structure, used to count
295 references to each node (integer in outer pair is the
296 reference count, the inner pair is the derivation order)
297 \param[in] is_matlab whether we are in a MATLAB context, since that
298 affects the cost of each operator
299
300 A node will be marked as a temporary term if it is referenced at least
301 two times (i.e. has at least two parents), and has a computing cost
302 (multiplied by reference count) greater to datatree.min_cost
303 */
304 virtual void computeTemporaryTerms(const pair<int, int> &derivOrder,
305 map<pair<int, int>, temporary_terms_t> &temp_terms_map,
306 map<expr_t, pair<int, pair<int, int>>> &reference_count,
307 bool is_matlab) const;
308
309 //! Writes output of node, using a Txxx notation for nodes in temporary_terms, and specifiying the set of already written external functions
310 /*!
311 \param[in] output the output stream
312 \param[in] output_type the type of output (MATLAB, C, LaTeX...)
313 \param[in] temporary_terms the nodes that are marked as temporary terms
314 \param[in] a map from temporary_terms to integers indexes (in the
315 MATLAB, C or Julia vector of temporary terms); can be empty
316 when writing MATLAB with block decomposition)
317 \param[in] tef_terms the set of already written external function nodes
318 */
319 virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const = 0;
320
321 //! returns true if the expr node contains an external function
322 virtual bool containsExternalFunction() const = 0;
323
324 //! Writes output of node (with no temporary terms and with "outside model" output type)
325 void writeOutput(ostream &output) const;
326
327 //! Writes output of node (with no temporary terms)
328 void writeOutput(ostream &output, ExprNodeOutputType output_type) const;
329
330 //! Writes output of node, using a Txxx notation for nodes in temporary_terms
331 void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs) const;
332
333 //! Writes output of node in JSON syntax
334 virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic = true) const = 0;
335
336 //! Writes the Abstract Syntax Tree in JSON
337 virtual void writeJsonAST(ostream &output) const = 0;
338
339 virtual int precedenceJson(const temporary_terms_t &temporary_terms) const;
340
341 //! Writes the output for an external function, ensuring that the external function is called as few times as possible using temporary terms
342 virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
343 const temporary_terms_t &temporary_terms,
344 const temporary_terms_idxs_t &temporary_terms_idxs,
345 deriv_node_temp_terms_t &tef_terms) const;
346
347 //! Write the JSON output of an external function in a string vector
348 //! Allows the insertion of commas if necessary
349 virtual void writeJsonExternalFunctionOutput(vector<string> &efout,
350 const temporary_terms_t &temporary_terms,
351 deriv_node_temp_terms_t &tef_terms,
352 bool isdynamic = true) const;
353
354 virtual void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
355 bool lhs_rhs, const temporary_terms_t &temporary_terms,
356 const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
357 deriv_node_temp_terms_t &tef_terms) const;
358
359 //! Computes the set of all variables of a given symbol type in the expression (with information on lags)
360 /*!
361 Variables are stored as integer pairs of the form (symb_id, lag).
362 They are added to the set given in argument.
363 Note that model local variables are substituted by their expression in the computation
364 (and added if type_arg = ModelLocalVariable).
365 */
366 virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const = 0;
367
368 //! Find lowest lag for VAR
369 virtual int VarMinLag() const = 0;
370
371 //! Find the maximum lag in a VAR: handles case where LHS is diff
372 virtual int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const = 0;
373
374 //! Finds LHS variable in a VAR equation
375 virtual void collectVARLHSVariable(set<expr_t> &result) const = 0;
376
377 //! Computes the set of all variables of a given symbol type in the expression (without information on lags)
378 /*!
379 Variables are stored as symb_id.
380 They are added to the set given in argument.
381 Note that model local variables are substituted by their expression in the computation
382 (and added if type_arg = ModelLocalVariable).
383 */
384 void collectVariables(SymbolType type_arg, set<int> &result) const;
385
386 //! Computes the set of endogenous variables in the expression
387 /*!
388 Endogenous are stored as integer pairs of the form (type_specific_id, lag).
389 They are added to the set given in argument.
390 Note that model local variables are substituted by their expression in the computation.
391 */
392 virtual void collectEndogenous(set<pair<int, int>> &result) const;
393
394 //! Computes the set of exogenous variables in the expression
395 /*!
396 Exogenous are stored as integer pairs of the form (type_specific_id, lag).
397 They are added to the set given in argument.
398 Note that model local variables are substituted by their expression in the computation.
399 */
400 virtual void collectExogenous(set<pair<int, int>> &result) const;
401
402 virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const = 0;
403
404 virtual void computeTemporaryTerms(map<expr_t, int> &reference_count,
405 temporary_terms_t &temporary_terms,
406 map<expr_t, pair<int, int>> &first_occurence,
407 int Curr_block,
408 vector< vector<temporary_terms_t>> &v_temporary_terms,
409 int equation) const;
410
411 class EvalException
412 {
413 };
414
415 class EvalExternalFunctionException : public EvalException
416 {
417 };
418
419 virtual double eval(const eval_context_t &eval_context) const noexcept(false) = 0;
420 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, const deriv_node_temp_terms_t &tef_terms) const = 0;
421 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;
422 //! Creates a static version of this node
423 /*!
424 This method duplicates the current node by creating a similar node from which all leads/lags have been stripped,
425 adds the result in the static_datatree argument (and not in the original datatree), and returns it.
426 */
427 virtual expr_t toStatic(DataTree &static_datatree) const = 0;
428
429 /*!
430 Compute cross references for equations
431 */
432 // virtual void computeXrefs(set<int> ¶m, set<int> &endo, set<int> &exo, set<int> &exo_det) const = 0;
433 virtual void computeXrefs(EquationInfo &ei) const = 0;
434 //! Try to normalize an equation linear in its endogenous variable
435 virtual pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<tuple<int, expr_t, expr_t>> &List_of_Op_RHS) const = 0;
436
437 //! Returns the maximum lead of endogenous in this expression
438 /*! Always returns a non-negative value */
439 virtual int maxEndoLead() const = 0;
440
441 //! Returns the maximum lead of exogenous in this expression
442 /*! Always returns a non-negative value */
443 virtual int maxExoLead() const = 0;
444
445 //! Returns the maximum lag of endogenous in this expression
446 /*! Always returns a non-negative value */
447 virtual int maxEndoLag() const = 0;
448
449 //! Returns the maximum lag of exogenous in this expression
450 /*! Always returns a non-negative value */
451 virtual int maxExoLag() const = 0;
452
453 //! Returns the maximum lead of endo/exo/exodet in this expression
454 /*! A negative value means that the expression contains only lagged
455 variables. A value of numeric_limits<int>::min() means that there is
456 no variable. */
457 virtual int maxLead() const = 0;
458
459 //! Returns the maximum lag of endo/exo/exodet in this expression
460 /*! A negative value means that the expression contains only leaded
461 variables. A value of numeric_limits<int>::min() means that there is
462 no variable. */
463 virtual int maxLag() const = 0;
464
465 //! Returns the maximum lag of endo/exo/exodet, as if diffs were expanded
466 /*! This function behaves as maxLag(), except that it treats diff()
467 differently. For e.g., on diff(diff(x(-1))), maxLag() returns 1 while
468 maxLagWithDiffsExpanded() returns 3. */
469 virtual int maxLagWithDiffsExpanded() const = 0;
470
471 //! Get Max lag of var associated with Pac model
472 //! Takes account of undiffed LHS variables in calculating the max lag
473 virtual int PacMaxLag(int lhs_symb_id) const = 0;
474
475 //! Get the target variable of the PAC model
476 virtual int getPacTargetSymbId(int lhs_symb_id, int undiff_lhs_symb_id) const = 0;
477
478 virtual expr_t undiff() const = 0;
479
480 //! Returns a new expression where all the leads/lags have been shifted backwards by the same amount
481 /*!
482 Only acts on endogenous, exogenous, exogenous det
483 \param[in] n The number of lags by which to shift
484 \return The same expression except that leads/lags have been shifted backwards
485 */
486 virtual expr_t decreaseLeadsLags(int n) const = 0;
487
488 //! Type for the substitution map used in the process of creating auxiliary vars
489 using subst_table_t = map<const ExprNode *, const VariableNode *>;
490
491 //! Type for the substitution map used in the process of substituting adl expressions
492 using subst_table_adl_t = map<const ExprNode *, const expr_t>;
493
494 //! Creates auxiliary endo lead variables corresponding to this expression
495 /*!
496 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.
497 \pre This expression is assumed to have maximum endogenous lead >= 2
498 \param[in,out] subst_table The table to which new auxiliary variables and their correspondance will be added
499 \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
500 \return The new variable node corresponding to the current expression
501 */
502 VariableNode *createEndoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
503
504 //! Creates auxiliary exo lead variables corresponding to this expression
505 /*!
506 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.
507 \pre This expression is assumed to have maximum exogenous lead >= 1
508 \param[in,out] subst_table The table to which new auxiliary variables and their correspondance will be added
509 \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
510 \return The new variable node corresponding to the current expression
511 */
512 VariableNode *createExoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
513
514 //! Constructs a new expression where sub-expressions with max endo lead >= 2 have been replaced by auxiliary variables
515 /*!
516 \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.
517 \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
518
519 If the method detects a sub-expr which needs to be substituted, two cases are possible:
520 - if this expr is in the table, then it will use the corresponding variable and return the substituted expression
521 - 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
522
523 \return A new equivalent expression where sub-expressions with max endo lead >= 2 have been replaced by auxiliary variables
524 */
525 virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const = 0;
526
527 //! Constructs a new expression where endo variables with max endo lag >= 2 have been replaced by auxiliary variables
528 /*!
529 \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.
530 \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
531 */
532 virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
533
534 //! Constructs a new expression where exogenous variables with a lead have been replaced by auxiliary variables
535 /*!
536 \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.
537 \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
538 */
539 virtual expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const = 0;
540 //! Constructs a new expression where exogenous variables with a lag have been replaced by auxiliary variables
541 /*!
542 \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.
543 \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
544 */
545 virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
546
547 //! Constructs a new expression where the expectation operator has been replaced by auxiliary variables
548 /*!
549 \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.
550 \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
551 \param[in] partial_information_model Are we substituting in a partial information model?
552 */
553 virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const = 0;
554
555 virtual expr_t decreaseLeadsLagsPredeterminedVariables() const = 0;
556
557 //! 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
558 /*!
559 \param[in] subset variables to which to limit the transformation; transform
560 all fwrd vars if empty
561 \param[in,out] subst_table Map used to store mapping between a given
562 forward variable and the aux var that contains its differentiate
563 \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
564 */
565 virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
566
567 //! Return true if the nodeID is a numerical constant equal to value and false otherwise
568 /*!
569 \param[in] value of the numerical constante
570 \param[out] the boolean equal to true if NodeId is a constant equal to value
571 */
572 virtual bool isNumConstNodeEqualTo(double value) const = 0;
573
574 //! Returns true if the expression contains one or several endogenous variable
575 virtual bool containsEndogenous() const = 0;
576
577 //! Returns true if the expression contains one or several exogenous variable
578 virtual bool containsExogenous() const = 0;
579
580 //! Returns the maximum number of nested diffs in the expression
581 virtual int countDiffs() const = 0;
582
583 //! 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
584 /*!
585 \param[in] the type (type_arg), specifique variable id (variable_id and the lag (lag_arg)
586 \param[out] the boolean equal to true if NodeId is the variable
587 */
588 virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const = 0;
589
590 //! Replaces the Trend var with datatree.One
591 virtual expr_t replaceTrendVar() const = 0;
592
593 //! Constructs a new expression where the variable indicated by symb_id has been detrended
594 /*!
595 \param[in] symb_id indicating the variable to be detrended
596 \param[in] log_trend indicates if the trend is in log
597 \param[in] trend indicating the trend
598 \return the new binary op pointing to a detrended variable
599 */
600 virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const = 0;
601
602 //! Substitute adl operator
603 virtual expr_t substituteAdl() const = 0;
604
605 //! Substitute VarExpectation nodes
606 virtual expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const = 0;
607
608 //! Mark diff nodes to be substituted
609 /*! The various nodes that are equivalent up to a shift of leads/lags are
610 grouped together in the “nodes” table. See the comment above
611 lag_equivalence_table_t for more details. */
612 virtual void findDiffNodes(lag_equivalence_table_t &nodes) const = 0;
613 //! Substitute diff operator
614 virtual expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
615
616 //! Mark unary ops nodes to be substituted
617 /*! The various nodes that are equivalent up to a shift of leads/lags are
618 grouped together in the “nodes” table. See the comment above
619 lag_equivalence_table_t for more details. */
620 virtual void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const = 0;
621 //! Substitute unary ops nodes
622 virtual expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
623
624 //! Substitute pac_expectation operator
625 virtual expr_t substitutePacExpectation(const string &name, expr_t subexpr) = 0;
626
627 virtual int findTargetVariable(int lhs_symb_id) const = 0;
628
629 //! Add ExprNodes to the provided datatree
630 virtual expr_t clone(DataTree &datatree) const = 0;
631
632 //! Move a trend variable with lag/lead to time t by dividing/multiplying by its growth factor
633 virtual expr_t removeTrendLeadLag(const map<int, expr_t> &trend_symbols_map) const = 0;
634
635 //! Returns true if the expression is in static form (no lead, no lag, no expectation, no STEADY_STATE)
636 virtual bool isInStaticForm() const = 0;
637
638 //! Substitute auxiliary variables by their expression in static model
639 virtual expr_t substituteStaticAuxiliaryVariable() const = 0;
640
641 //! Returns true if model_info_name is referenced by a VarExpectationNode
642 virtual bool isVarModelReferenced(const string &model_info_name) const = 0;
643
644 //! Matches a linear combination of variables, where scalars can be constant*parameter
645 /*! Returns a list of (variable_id, lag, param_id, constant)
646 corresponding to the terms in the expression. When there is no
647 parameter in a term, param_id == -1.
648 Can throw a MatchFailureException.
649 if `variable_obligatory_in_each_term` is true, then every part of the linear combination must contain a variable;
650 otherwise, if `variable_obligatory_in_each_term`, then any linear combination of constant/variable/param is matched
651 */
652 vector<tuple<int, int, int, double>> matchLinearCombinationOfVariables(bool variable_obligatory_in_each_term = true) const;
653
654 pair<int, vector<tuple<int, int, int, double>>> matchParamTimesLinearCombinationOfVariables() const;
655
656 //! Returns true if expression is of the form:
657 //! param * (endog op endog op ...) + param * (endog op endog op ...) + ...
658 virtual bool isParamTimesEndogExpr() const = 0;
659
660 //! Fills the EC matrix structure
661 void fillErrorCorrectionRow(int eqn, const vector<int> &nontarget_lhs, const vector<int> &target_lhs,
662 map<tuple<int, int, int>, expr_t> &A0,
663 map<tuple<int, int, int>, expr_t> &A0star) const;
664
665 //! Finds equations where a variable is equal to a constant
666 virtual void findConstantEquations(map<VariableNode *, NumConstNode *> &table) const = 0;
667
668 //! Replaces variables found in findConstantEquations() with their constant values
669 virtual expr_t replaceVarsInEquation(map<VariableNode *, NumConstNode *> &table) const = 0;
670
671 //! Returns true if PacExpectationNode encountered
672 virtual bool containsPacExpectation(const string &pac_model_name = "") const = 0;
673
674 //! Fills map
675 virtual void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const = 0;
676
677 //! Decompose an expression into its additive terms
678 /*! Returns a list of terms, with their sign (either 1 or -1, depending
679 on whether the terms appears with a plus or a minus).
680 The current_sign argument should normally be left to 1.
681 If current_sign == -1, then all signs are inverted */
682 virtual void decomposeAdditiveTerms(vector<pair<expr_t, int>> &terms, int current_sign = 1) const;
683
684 // Matches an expression of the form variable*constant*parameter
685 /* Returns a tuple (variable_id, lag, param_id, constant).
686 The variable must be an exogenous or an endogenous.
687 The constant is optional (in which case 1 is returned); there can be
688 several multiplicative constants; constants can also appear at the
689 denominator (i.e. after a divide sign).
690 The parameter is optional (in which case param_id == -1).
691 If the expression is not of the expected form, throws a
692 MatchFailureException
693 if `variable_obligatory` is true, then the linear combination must contain a variable;
694 otherwise, if `variable_obligatory`, then an expression is matched that has any mix of constant/variable/param
695 */
696 tuple<int, int, int, double> matchVariableTimesConstantTimesParam(bool variable_obligatory = true) const;
697
698 //! Exception thrown by matchVariableTimesConstantTimesParam when matching fails
699 class MatchFailureException
700 {
701 public:
702 const string message;
MatchFailureException(string message_arg)703 MatchFailureException(string message_arg) : message{move(message_arg)}
704 {
705 };
706 };
707 };
708
709 //! Object used to compare two nodes (using their indexes)
710 /*! Note that in this ordering, a subexpression is always less than the
711 expression from which it is extracted. This property is used extensively in
712 the temporary terms computations. */
713 struct ExprNodeLess
714 {
715 bool
operator ()ExprNodeLess716 operator()(expr_t arg1, expr_t arg2) const
717 {
718 return arg1->idx < arg2->idx;
719 }
720 };
721
722 //! Numerical constant node
723 /*! The constant is necessarily non-negative (this is enforced at the NumericalConstants class level) */
724 class NumConstNode : public ExprNode
725 {
726 public:
727 //! Id from numerical constants table
728 const int id;
729 private:
730 expr_t computeDerivative(int deriv_id) override;
731 protected:
732 void matchVTCTPHelper(int &var_id, int &lag, int ¶m_id, double &constant, bool at_denominator) const override;
733 public:
734 NumConstNode(DataTree &datatree_arg, int idx_arg, int id_arg);
735 void prepareForDerivation() override;
736 void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override;
737 void writeJsonAST(ostream &output) const override;
738 void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override;
739 bool containsExternalFunction() const override;
740 void collectVARLHSVariable(set<expr_t> &result) const override;
741 void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override;
742 void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const override;
743 double eval(const eval_context_t &eval_context) const noexcept(false) override;
744 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 deriv_node_temp_terms_t &tef_terms) const override;
745 expr_t toStatic(DataTree &static_datatree) const override;
746 void computeXrefs(EquationInfo &ei) const override;
747 pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<tuple<int, expr_t, expr_t>> &List_of_Op_RHS) const override;
748 expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables) override;
749 int maxEndoLead() const override;
750 int maxExoLead() const override;
751 int maxEndoLag() const override;
752 int maxExoLag() const override;
753 int maxLead() const override;
754 int maxLag() const override;
755 int maxLagWithDiffsExpanded() const override;
756 int VarMinLag() const override;
757 int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override;
758 int PacMaxLag(int lhs_symb_id) const override;
759 int getPacTargetSymbId(int lhs_symb_id, int undiff_lhs_symb_id) const override;
760 expr_t undiff() const override;
761 expr_t decreaseLeadsLags(int n) const override;
762 expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
763 expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
764 expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
765 expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
766 expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
767 expr_t substituteAdl() const override;
768 expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
769 void findDiffNodes(lag_equivalence_table_t &nodes) const override;
770 void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override;
771 int findTargetVariable(int lhs_symb_id) const override;
772 expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
773 expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
774 expr_t substitutePacExpectation(const string &name, expr_t subexpr) override;
775 expr_t decreaseLeadsLagsPredeterminedVariables() const override;
776 expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
777 bool isNumConstNodeEqualTo(double value) const override;
778 bool containsEndogenous() const override;
779 bool containsExogenous() const override;
780 int countDiffs() const override;
781 bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override;
782 expr_t replaceTrendVar() const override;
783 expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override;
784 expr_t clone(DataTree &datatree) const override;
785 expr_t removeTrendLeadLag(const map<int, expr_t> &trend_symbols_map) const override;
786 bool isInStaticForm() const override;
787 void findConstantEquations(map<VariableNode *, NumConstNode *> &table) const override;
788 expr_t replaceVarsInEquation(map<VariableNode *, NumConstNode *> &table) const override;
789 bool containsPacExpectation(const string &pac_model_name = "") const override;
790 bool isParamTimesEndogExpr() const override;
791 bool isVarModelReferenced(const string &model_info_name) const override;
792 void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
793 expr_t substituteStaticAuxiliaryVariable() const override;
794 };
795
796 //! Symbol or variable node
797 class VariableNode : public ExprNode
798 {
799 friend class UnaryOpNode;
800 public:
801 //! Id from the symbol table
802 const int symb_id;
803 //! A positive value is a lead, a negative is a lag
804 const int lag;
805 private:
806 expr_t computeDerivative(int deriv_id) override;
807 protected:
808 void matchVTCTPHelper(int &var_id, int &lag, int ¶m_id, double &constant, bool at_denominator) const override;
809 public:
810 VariableNode(DataTree &datatree_arg, int idx_arg, int symb_id_arg, int lag_arg);
811 void prepareForDerivation() override;
812 void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override;
813 void writeJsonAST(ostream &output) const override;
814 void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override;
815 bool containsExternalFunction() const override;
816 void collectVARLHSVariable(set<expr_t> &result) const override;
817 void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override;
818 void computeTemporaryTerms(map<expr_t, int > &reference_count,
819 temporary_terms_t &temporary_terms,
820 map<expr_t, pair<int, int>> &first_occurence,
821 int Curr_block,
822 vector< vector<temporary_terms_t>> &v_temporary_terms,
823 int equation) const override;
824 void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const override;
825 double eval(const eval_context_t &eval_context) const noexcept(false) override;
826 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 deriv_node_temp_terms_t &tef_terms) const override;
827 expr_t toStatic(DataTree &static_datatree) const override;
828 void computeXrefs(EquationInfo &ei) const override;
829 SymbolType get_type() const;
830 pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<tuple<int, expr_t, expr_t>> &List_of_Op_RHS) const override;
831 expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables) override;
832 int maxEndoLead() const override;
833 int maxExoLead() const override;
834 int maxEndoLag() const override;
835 int maxExoLag() const override;
836 int maxLead() const override;
837 int maxLag() const override;
838 int maxLagWithDiffsExpanded() const override;
839 int VarMinLag() const override;
840 int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override;
841 int PacMaxLag(int lhs_symb_id) const override;
842 int getPacTargetSymbId(int lhs_symb_id, int undiff_lhs_symb_id) const override;
843 expr_t undiff() const override;
844 expr_t decreaseLeadsLags(int n) const override;
845 expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
846 expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
847 expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
848 expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
849 expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
850 expr_t substituteAdl() const override;
851 expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
852 void findDiffNodes(lag_equivalence_table_t &nodes) const override;
853 void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override;
854 int findTargetVariable(int lhs_symb_id) const override;
855 expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
856 expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
857 expr_t substitutePacExpectation(const string &name, expr_t subexpr) override;
858 expr_t decreaseLeadsLagsPredeterminedVariables() const override;
859 expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
860 bool isNumConstNodeEqualTo(double value) const override;
861 bool containsEndogenous() const override;
862 bool containsExogenous() const override;
863 int countDiffs() const override;
864 bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override;
865 expr_t replaceTrendVar() const override;
866 expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override;
867 expr_t clone(DataTree &datatree) const override;
868 expr_t removeTrendLeadLag(const map<int, expr_t> &trend_symbols_map) const override;
869 bool isInStaticForm() const override;
870 void findConstantEquations(map<VariableNode *, NumConstNode *> &table) const override;
871 expr_t replaceVarsInEquation(map<VariableNode *, NumConstNode *> &table) const override;
872 bool containsPacExpectation(const string &pac_model_name = "") const override;
873 bool isParamTimesEndogExpr() const override;
874 bool isVarModelReferenced(const string &model_info_name) const override;
875 void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
876 //! Substitute auxiliary variables by their expression in static model
877 expr_t substituteStaticAuxiliaryVariable() const override;
878 };
879
880 //! Unary operator node
881 class UnaryOpNode : public ExprNode
882 {
883 protected:
884 void matchVTCTPHelper(int &var_id, int &lag, int ¶m_id, double &constant, bool at_denominator) const override;
885 public:
886 const expr_t arg;
887 //! Stores the information set. Only used for expectation operator
888 const int expectation_information_set;
889 //! Only used for UnaryOpcode::steadyStateParamDeriv and UnaryOpcode::steadyStateParam2ndDeriv
890 const int param1_symb_id, param2_symb_id;
891 const UnaryOpcode op_code;
892 const string adl_param_name;
893 const vector<int> adl_lags;
894 private:
895 expr_t computeDerivative(int deriv_id) override;
896 int cost(int cost, bool is_matlab) const override;
897 int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const override;
898 int cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map, bool is_matlab) const override;
899 //! Returns the derivative of this node if darg is the derivative of the argument
900 expr_t composeDerivatives(expr_t darg, int deriv_id);
901 public:
902 UnaryOpNode(DataTree &datatree_arg, int idx_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, string adl_param_name_arg, vector<int> adl_lags_arg);
903 void prepareForDerivation() override;
904 void computeTemporaryTerms(const pair<int, int> &derivOrder,
905 map<pair<int, int>, temporary_terms_t> &temp_terms_map,
906 map<expr_t, pair<int, pair<int, int>>> &reference_count,
907 bool is_matlab) const override;
908 void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override;
909 void writeJsonAST(ostream &output) const override;
910 void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override;
911 bool containsExternalFunction() const override;
912 void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
913 const temporary_terms_t &temporary_terms,
914 const temporary_terms_idxs_t &temporary_terms_idxs,
915 deriv_node_temp_terms_t &tef_terms) const override;
916 void writeJsonExternalFunctionOutput(vector<string> &efout,
917 const temporary_terms_t &temporary_terms,
918 deriv_node_temp_terms_t &tef_terms,
919 bool isdynamic) const override;
920 void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
921 bool lhs_rhs, const temporary_terms_t &temporary_terms,
922 const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
923 deriv_node_temp_terms_t &tef_terms) const override;
924 void computeTemporaryTerms(map<expr_t, int> &reference_count,
925 temporary_terms_t &temporary_terms,
926 map<expr_t, pair<int, int>> &first_occurence,
927 int Curr_block,
928 vector< vector<temporary_terms_t>> &v_temporary_terms,
929 int equation) const override;
930 void collectVARLHSVariable(set<expr_t> &result) const override;
931 void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override;
932 void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const override;
933 static double eval_opcode(UnaryOpcode op_code, double v) noexcept(false);
934 double eval(const eval_context_t &eval_context) const noexcept(false) override;
935 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 deriv_node_temp_terms_t &tef_terms) const override;
936 expr_t toStatic(DataTree &static_datatree) const override;
937 void computeXrefs(EquationInfo &ei) const override;
938 pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<tuple<int, expr_t, expr_t>> &List_of_Op_RHS) const override;
939 expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables) override;
940 int maxEndoLead() const override;
941 int maxExoLead() const override;
942 int maxEndoLag() const override;
943 int maxExoLag() const override;
944 int maxLead() const override;
945 int maxLag() const override;
946 int maxLagWithDiffsExpanded() const override;
947 int VarMinLag() const override;
948 int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override;
949 int PacMaxLag(int lhs_symb_id) const override;
950 int getPacTargetSymbId(int lhs_symb_id, int undiff_lhs_symb_id) const override;
951 expr_t undiff() const override;
952 expr_t decreaseLeadsLags(int n) const override;
953 expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
954 //! Creates another UnaryOpNode with the same opcode, but with a possibly different datatree and argument
955 expr_t buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) const;
956 expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
957 expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
958 expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
959 expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
960 expr_t substituteAdl() const override;
961 expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
962 void findDiffNodes(lag_equivalence_table_t &nodes) const override;
963 bool createAuxVarForUnaryOpNode() const;
964 void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override;
965 int findTargetVariable(int lhs_symb_id) const override;
966 expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
967 expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
968 expr_t substitutePacExpectation(const string &name, expr_t subexpr) override;
969 expr_t decreaseLeadsLagsPredeterminedVariables() const override;
970 expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
971 bool isNumConstNodeEqualTo(double value) const override;
972 bool containsEndogenous() const override;
973 bool containsExogenous() const override;
974 int countDiffs() const override;
975 bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override;
976 expr_t replaceTrendVar() const override;
977 expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override;
978 expr_t clone(DataTree &datatree) const override;
979 expr_t removeTrendLeadLag(const map<int, expr_t> &trend_symbols_map) const override;
980 bool isInStaticForm() const override;
981 void findConstantEquations(map<VariableNode *, NumConstNode *> &table) const override;
982 expr_t replaceVarsInEquation(map<VariableNode *, NumConstNode *> &table) const override;
983 bool containsPacExpectation(const string &pac_model_name = "") const override;
984 bool isParamTimesEndogExpr() const override;
985 bool isVarModelReferenced(const string &model_info_name) const override;
986 void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
987 //! Substitute auxiliary variables by their expression in static model
988 expr_t substituteStaticAuxiliaryVariable() const override;
989 void decomposeAdditiveTerms(vector<pair<expr_t, int>> &terms, int current_sign) const override;
990 };
991
992 //! Binary operator node
993 class BinaryOpNode : public ExprNode
994 {
995 protected:
996 void matchVTCTPHelper(int &var_id, int &lag, int ¶m_id, double &constant, bool at_denominator) const override;
997 public:
998 const expr_t arg1, arg2;
999 const BinaryOpcode op_code;
1000 const int powerDerivOrder;
1001 const string adlparam;
1002 private:
1003 expr_t computeDerivative(int deriv_id) override;
1004 int cost(int cost, bool is_matlab) const override;
1005 int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const override;
1006 int cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map, bool is_matlab) const override;
1007 //! Returns the derivative of this node if darg1 and darg2 are the derivatives of the arguments
1008 expr_t composeDerivatives(expr_t darg1, expr_t darg2);
1009 public:
1010 BinaryOpNode(DataTree &datatree_arg, int idx_arg, const expr_t arg1_arg,
1011 BinaryOpcode op_code_arg, const expr_t arg2_arg, int powerDerivOrder);
1012 void prepareForDerivation() override;
1013 int precedenceJson(const temporary_terms_t &temporary_terms) const override;
1014 int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const override;
1015 void computeTemporaryTerms(const pair<int, int> &derivOrder,
1016 map<pair<int, int>, temporary_terms_t> &temp_terms_map,
1017 map<expr_t, pair<int, pair<int, int>>> &reference_count,
1018 bool is_matlab) const override;
1019 void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override;
1020 void writeJsonAST(ostream &output) const override;
1021 void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override;
1022 bool containsExternalFunction() const override;
1023 void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
1024 const temporary_terms_t &temporary_terms,
1025 const temporary_terms_idxs_t &temporary_terms_idxs,
1026 deriv_node_temp_terms_t &tef_terms) const override;
1027 void writeJsonExternalFunctionOutput(vector<string> &efout,
1028 const temporary_terms_t &temporary_terms,
1029 deriv_node_temp_terms_t &tef_terms,
1030 bool isdynamic) const override;
1031 void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
1032 bool lhs_rhs, const temporary_terms_t &temporary_terms,
1033 const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
1034 deriv_node_temp_terms_t &tef_terms) const override;
1035 void computeTemporaryTerms(map<expr_t, int> &reference_count,
1036 temporary_terms_t &temporary_terms,
1037 map<expr_t, pair<int, int>> &first_occurence,
1038 int Curr_block,
1039 vector< vector<temporary_terms_t>> &v_temporary_terms,
1040 int equation) const override;
1041 void collectVARLHSVariable(set<expr_t> &result) const override;
1042 void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override;
1043 void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const override;
1044 static double eval_opcode(double v1, BinaryOpcode op_code, double v2, int derivOrder) noexcept(false);
1045 double eval(const eval_context_t &eval_context) const noexcept(false) override;
1046 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 deriv_node_temp_terms_t &tef_terms) const override;
1047 expr_t Compute_RHS(expr_t arg1, expr_t arg2, int op, int op_type) const;
1048 expr_t toStatic(DataTree &static_datatree) const override;
1049 void computeXrefs(EquationInfo &ei) const override;
1050 pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<tuple<int, expr_t, expr_t>> &List_of_Op_RHS) const override;
1051 expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables) override;
1052 int maxEndoLead() const override;
1053 int maxExoLead() const override;
1054 int maxEndoLag() const override;
1055 int maxExoLag() const override;
1056 int maxLead() const override;
1057 int maxLag() const override;
1058 int maxLagWithDiffsExpanded() const override;
1059 int VarMinLag() const override;
1060 int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override;
1061 int PacMaxLag(int lhs_symb_id) const override;
1062 int getPacTargetSymbIdHelper(int lhs_symb_id, int undiff_lhs_symb_id, const set<pair<int, int>> &endogs) const;
1063 int getPacTargetSymbId(int lhs_symb_id, int undiff_lhs_symb_id) const override;
1064 expr_t undiff() const override;
1065 expr_t decreaseLeadsLags(int n) const override;
1066 expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
1067 //! Creates another BinaryOpNode with the same opcode, but with a possibly different datatree and arguments
1068 expr_t buildSimilarBinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, DataTree &alt_datatree) const;
1069 expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1070 expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
1071 expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1072 expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
1073 expr_t substituteAdl() const override;
1074 expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
1075 void findDiffNodes(lag_equivalence_table_t &nodes) const override;
1076 void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override;
1077 bool findTargetVariableHelper1(int lhs_symb_id, int rhs_symb_id) const;
1078 int findTargetVariableHelper(const expr_t arg1, const expr_t arg2, int lhs_symb_id) const;
1079 int findTargetVariable(int lhs_symb_id) const override;
1080 expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1081 expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1082 expr_t substitutePacExpectation(const string &name, expr_t subexpr) override;
1083 expr_t decreaseLeadsLagsPredeterminedVariables() const override;
1084 expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1085 bool isNumConstNodeEqualTo(double value) const override;
1086 bool containsEndogenous() const override;
1087 bool containsExogenous() const override;
1088 int countDiffs() const override;
1089 bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override;
1090 expr_t replaceTrendVar() const override;
1091 expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override;
1092 expr_t clone(DataTree &datatree) const override;
1093 expr_t removeTrendLeadLag(const map<int, expr_t> &trend_symbols_map) const override;
1094 //! Function to write out the oPowerNode in expr_t terms as opposed to writing out the function itself
1095 expr_t unpackPowerDeriv() const;
1096 //! Returns MULT_i*(lhs-rhs) = 0, creating multiplier MULT_i
1097 expr_t addMultipliersToConstraints(int i);
1098 //! Returns the non-zero hand-side of an equation (that must have a hand side equal to zero)
1099 expr_t getNonZeroPartofEquation() const;
1100 bool isInStaticForm() const override;
1101 void fillAutoregressiveRow(int eqn, const vector<int> &lhs, map<tuple<int, int, int>, expr_t> &AR) const;
1102 void findConstantEquations(map<VariableNode *, NumConstNode *> &table) const override;
1103 expr_t replaceVarsInEquation(map<VariableNode *, NumConstNode *> &table) const override;
1104 bool containsPacExpectation(const string &pac_model_name = "") const override;
1105 pair<int, vector<tuple<int, bool, int>>> getPacEC(BinaryOpNode *bopn, int lhs_symb_id, int lhs_orig_symb_id) const;
1106 void getPacAREC(int lhs_symb_id, int lhs_orig_symb_id,
1107 pair<int, vector<tuple<int, bool, int>>> &ec_params_and_vars,
1108 set<pair<int, pair<int, int>>> &ar_params_and_vars,
1109 vector<tuple<int, int, int, double>> &additive_vars_params_and_constants) const;
1110
1111 //! Finds the share of optimizing agents in the PAC equation,
1112 //! the expr node associated with it,
1113 //! and the expr node associated with the non-optimizing part
1114 tuple<int, expr_t, expr_t, expr_t> getPacOptimizingShareAndExprNodes(int lhs_symb_id, int lhs_orig_symb_id) const;
1115 pair<int, expr_t> getPacOptimizingShareAndExprNodesHelper(BinaryOpNode *bopn, int lhs_symb_id, int lhs_orig_symb_id) const;
1116 expr_t getPacNonOptimizingPart(BinaryOpNode *bopn, int optim_share) const;
1117 bool getPacNonOptimizingPartHelper(BinaryOpNode *bopn, int optim_share) const;
1118 bool isParamTimesEndogExpr() const override;
1119 bool isVarModelReferenced(const string &model_info_name) const override;
1120 void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
1121 //! Substitute auxiliary variables by their expression in static model
1122 expr_t substituteStaticAuxiliaryVariable() const override;
1123 //! Substitute auxiliary variables by their expression in static model auxiliary variable definition
1124 expr_t substituteStaticAuxiliaryDefinition() const;
1125 void decomposeAdditiveTerms(vector<pair<expr_t, int>> &terms, int current_sign) const override;
1126 };
1127
1128 //! Trinary operator node
1129 class TrinaryOpNode : public ExprNode
1130 {
1131 friend class ModelTree;
1132 public:
1133 const expr_t arg1, arg2, arg3;
1134 const TrinaryOpcode op_code;
1135 private:
1136 expr_t computeDerivative(int deriv_id) override;
1137 int cost(int cost, bool is_matlab) const override;
1138 int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const override;
1139 int cost(const map<pair<int, int>, temporary_terms_t> &temp_terms_map, bool is_matlab) const override;
1140 //! Returns the derivative of this node if darg1, darg2 and darg3 are the derivatives of the arguments
1141 expr_t composeDerivatives(expr_t darg1, expr_t darg2, expr_t darg3);
1142 public:
1143 TrinaryOpNode(DataTree &datatree_arg, int idx_arg, const expr_t arg1_arg,
1144 TrinaryOpcode op_code_arg, const expr_t arg2_arg, const expr_t arg3_arg);
1145 void prepareForDerivation() override;
1146 int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const override;
1147 void computeTemporaryTerms(const pair<int, int> &derivOrder,
1148 map<pair<int, int>, temporary_terms_t> &temp_terms_map,
1149 map<expr_t, pair<int, pair<int, int>>> &reference_count,
1150 bool is_matlab) const override;
1151 void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override;
1152 void writeJsonAST(ostream &output) const override;
1153 void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override;
1154 bool containsExternalFunction() const override;
1155 void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
1156 const temporary_terms_t &temporary_terms,
1157 const temporary_terms_idxs_t &temporary_terms_idxs,
1158 deriv_node_temp_terms_t &tef_terms) const override;
1159 void writeJsonExternalFunctionOutput(vector<string> &efout,
1160 const temporary_terms_t &temporary_terms,
1161 deriv_node_temp_terms_t &tef_terms,
1162 bool isdynamic) const override;
1163 void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
1164 bool lhs_rhs, const temporary_terms_t &temporary_terms,
1165 const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
1166 deriv_node_temp_terms_t &tef_terms) const override;
1167 void computeTemporaryTerms(map<expr_t, int> &reference_count,
1168 temporary_terms_t &temporary_terms,
1169 map<expr_t, pair<int, int>> &first_occurence,
1170 int Curr_block,
1171 vector< vector<temporary_terms_t>> &v_temporary_terms,
1172 int equation) const override;
1173 void collectVARLHSVariable(set<expr_t> &result) const override;
1174 void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override;
1175 void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const override;
1176 static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) noexcept(false);
1177 double eval(const eval_context_t &eval_context) const noexcept(false) override;
1178 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 deriv_node_temp_terms_t &tef_terms) const override;
1179 expr_t toStatic(DataTree &static_datatree) const override;
1180 void computeXrefs(EquationInfo &ei) const override;
1181 pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<tuple<int, expr_t, expr_t>> &List_of_Op_RHS) const override;
1182 expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables) override;
1183 int maxEndoLead() const override;
1184 int maxExoLead() const override;
1185 int maxEndoLag() const override;
1186 int maxExoLag() const override;
1187 int maxLead() const override;
1188 int maxLag() const override;
1189 int maxLagWithDiffsExpanded() const override;
1190 int VarMinLag() const override;
1191 int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override;
1192 int PacMaxLag(int lhs_symb_id) const override;
1193 int getPacTargetSymbId(int lhs_symb_id, int undiff_lhs_symb_id) const override;
1194 expr_t undiff() const override;
1195 expr_t decreaseLeadsLags(int n) const override;
1196 expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
1197 //! Creates another TrinaryOpNode with the same opcode, but with a possibly different datatree and arguments
1198 expr_t buildSimilarTrinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, expr_t alt_arg3, DataTree &alt_datatree) const;
1199 expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1200 expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
1201 expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1202 expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
1203 expr_t substituteAdl() const override;
1204 expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
1205 void findDiffNodes(lag_equivalence_table_t &nodes) const override;
1206 void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override;
1207 int findTargetVariable(int lhs_symb_id) const override;
1208 expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1209 expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1210 expr_t substitutePacExpectation(const string &name, expr_t subexpr) override;
1211 expr_t decreaseLeadsLagsPredeterminedVariables() const override;
1212 expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1213 bool isNumConstNodeEqualTo(double value) const override;
1214 bool containsEndogenous() const override;
1215 bool containsExogenous() const override;
1216 int countDiffs() const override;
1217 bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override;
1218 expr_t replaceTrendVar() const override;
1219 expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override;
1220 expr_t clone(DataTree &datatree) const override;
1221 expr_t removeTrendLeadLag(const map<int, expr_t> &trend_symbols_map) const override;
1222 bool isInStaticForm() const override;
1223 void findConstantEquations(map<VariableNode *, NumConstNode *> &table) const override;
1224 expr_t replaceVarsInEquation(map<VariableNode *, NumConstNode *> &table) const override;
1225 bool containsPacExpectation(const string &pac_model_name = "") const override;
1226 bool isParamTimesEndogExpr() const override;
1227 bool isVarModelReferenced(const string &model_info_name) const override;
1228 void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
1229 //! Substitute auxiliary variables by their expression in static model
1230 expr_t substituteStaticAuxiliaryVariable() const override;
1231 };
1232
1233 //! External function node
1234 class AbstractExternalFunctionNode : public ExprNode
1235 {
1236 public:
1237 const int symb_id;
1238 const vector<expr_t> arguments;
1239 private:
1240 expr_t computeDerivative(int deriv_id) override;
1241 virtual expr_t composeDerivatives(const vector<expr_t> &dargs) = 0;
1242 protected:
1243 //! Thrown when trying to access an unknown entry in external_function_node_map
1244 class UnknownFunctionNameAndArgs
1245 {
1246 };
1247 //! Returns true if the given external function has been written as a temporary term
1248 bool alreadyWrittenAsTefTerm(int the_symb_id, const deriv_node_temp_terms_t &tef_terms) const;
1249 //! Returns the index in the tef_terms map of this external function
1250 int getIndxInTefTerms(int the_symb_id, const deriv_node_temp_terms_t &tef_terms) const noexcept(false);
1251 //! Helper function to write output arguments of any given external function
1252 void writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const;
1253 void writeJsonASTExternalFunctionArguments(ostream &output) const;
1254 void writeJsonExternalFunctionArguments(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const;
1255 /*! Returns a predicate that tests whether an other ExprNode is an external
1256 function which is computed by the same external function call (i.e. it has
1257 the same so-called "Tef" index) */
1258 virtual function<bool (expr_t)> sameTefTermPredicate() const = 0;
1259 public:
1260 AbstractExternalFunctionNode(DataTree &datatree_arg, int idx_arg, int symb_id_arg,
1261 vector<expr_t> arguments_arg);
1262 void prepareForDerivation() override;
1263 void computeTemporaryTerms(const pair<int, int> &derivOrder,
1264 map<pair<int, int>, temporary_terms_t> &temp_terms_map,
1265 map<expr_t, pair<int, pair<int, int>>> &reference_count,
1266 bool is_matlab) const override;
1267 void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override = 0;
1268 void writeJsonAST(ostream &output) const override = 0;
1269 void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic = true) const override = 0;
1270 bool containsExternalFunction() const override;
1271 void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
1272 const temporary_terms_t &temporary_terms,
1273 const temporary_terms_idxs_t &temporary_terms_idxs,
1274 deriv_node_temp_terms_t &tef_terms) const override = 0;
1275 void writeJsonExternalFunctionOutput(vector<string> &efout,
1276 const temporary_terms_t &temporary_terms,
1277 deriv_node_temp_terms_t &tef_terms,
1278 bool isdynamic = true) const override = 0;
1279 void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
1280 bool lhs_rhs, const temporary_terms_t &temporary_terms,
1281 const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
1282 deriv_node_temp_terms_t &tef_terms) const override = 0;
1283 void computeTemporaryTerms(map<expr_t, int> &reference_count,
1284 temporary_terms_t &temporary_terms,
1285 map<expr_t, pair<int, int>> &first_occurence,
1286 int Curr_block,
1287 vector< vector<temporary_terms_t>> &v_temporary_terms,
1288 int equation) const override = 0;
1289 void collectVARLHSVariable(set<expr_t> &result) const override;
1290 void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override;
1291 void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const override;
1292 double eval(const eval_context_t &eval_context) const noexcept(false) override;
1293 unsigned int compileExternalFunctionArguments(ostream &CompileCode, unsigned int &instruction_number,
1294 bool lhs_rhs, const temporary_terms_t &temporary_terms,
1295 const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
1296 const deriv_node_temp_terms_t &tef_terms) const;
1297
1298 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 deriv_node_temp_terms_t &tef_terms) const override = 0;
1299 expr_t toStatic(DataTree &static_datatree) const override = 0;
1300 void computeXrefs(EquationInfo &ei) const override = 0;
1301 pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<tuple<int, expr_t, expr_t>> &List_of_Op_RHS) const override;
1302 expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables) override;
1303 int maxEndoLead() const override;
1304 int maxExoLead() const override;
1305 int maxEndoLag() const override;
1306 int maxExoLag() const override;
1307 int maxLead() const override;
1308 int maxLag() const override;
1309 int maxLagWithDiffsExpanded() const override;
1310 int VarMinLag() const override;
1311 int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override;
1312 int PacMaxLag(int lhs_symb_id) const override;
1313 int getPacTargetSymbId(int lhs_symb_id, int undiff_lhs_symb_id) const override;
1314 expr_t undiff() const override;
1315 expr_t decreaseLeadsLags(int n) const override;
1316 expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
1317 expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1318 expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
1319 expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1320 expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
1321 expr_t substituteAdl() const override;
1322 expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
1323 void findDiffNodes(lag_equivalence_table_t &nodes) const override;
1324 void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override;
1325 int findTargetVariable(int lhs_symb_id) const override;
1326 expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1327 expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1328 expr_t substitutePacExpectation(const string &name, expr_t subexpr) override;
1329 virtual expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const = 0;
1330 expr_t decreaseLeadsLagsPredeterminedVariables() const override;
1331 expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1332 bool isNumConstNodeEqualTo(double value) const override;
1333 bool containsEndogenous() const override;
1334 bool containsExogenous() const override;
1335 int countDiffs() const override;
1336 bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override;
1337 void writePrhs(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms, const string &ending) const;
1338 expr_t replaceTrendVar() const override;
1339 expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override;
1340 expr_t clone(DataTree &datatree) const override = 0;
1341 expr_t removeTrendLeadLag(const map<int, expr_t> &trend_symbols_map) const override;
1342 bool isInStaticForm() const override;
1343 void findConstantEquations(map<VariableNode *, NumConstNode *> &table) const override;
1344 expr_t replaceVarsInEquation(map<VariableNode *, NumConstNode *> &table) const override;
1345 bool containsPacExpectation(const string &pac_model_name = "") const override;
1346 bool isParamTimesEndogExpr() const override;
1347 bool isVarModelReferenced(const string &model_info_name) const override;
1348 void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
1349 //! Substitute auxiliary variables by their expression in static model
1350 expr_t substituteStaticAuxiliaryVariable() const override;
1351 };
1352
1353 class ExternalFunctionNode : public AbstractExternalFunctionNode
1354 {
1355 friend class FirstDerivExternalFunctionNode;
1356 friend class SecondDerivExternalFunctionNode;
1357 private:
1358 expr_t composeDerivatives(const vector<expr_t> &dargs) override;
1359 protected:
1360 function<bool (expr_t)> sameTefTermPredicate() const override;
1361 public:
1362 ExternalFunctionNode(DataTree &datatree_arg, int idx_arg, int symb_id_arg,
1363 const vector<expr_t> &arguments_arg);
1364 void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override;
1365 void writeJsonAST(ostream &output) const override;
1366 void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override;
1367 void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
1368 const temporary_terms_t &temporary_terms,
1369 const temporary_terms_idxs_t &temporary_terms_idxs,
1370 deriv_node_temp_terms_t &tef_terms) const override;
1371 void writeJsonExternalFunctionOutput(vector<string> &efout,
1372 const temporary_terms_t &temporary_terms,
1373 deriv_node_temp_terms_t &tef_terms,
1374 bool isdynamic) const override;
1375 void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
1376 bool lhs_rhs, const temporary_terms_t &temporary_terms,
1377 const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
1378 deriv_node_temp_terms_t &tef_terms) const override;
1379 void computeTemporaryTerms(map<expr_t, int> &reference_count,
1380 temporary_terms_t &temporary_terms,
1381 map<expr_t, pair<int, int>> &first_occurence,
1382 int Curr_block,
1383 vector< vector<temporary_terms_t>> &v_temporary_terms,
1384 int equation) const override;
1385 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 deriv_node_temp_terms_t &tef_terms) const override;
1386 expr_t toStatic(DataTree &static_datatree) const override;
1387 void computeXrefs(EquationInfo &ei) const override;
1388 expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const override;
1389 expr_t clone(DataTree &datatree) const override;
1390 };
1391
1392 class FirstDerivExternalFunctionNode : public AbstractExternalFunctionNode
1393 {
1394 public:
1395 const int inputIndex;
1396 private:
1397 expr_t composeDerivatives(const vector<expr_t> &dargs) override;
1398 protected:
1399 function<bool (expr_t)> sameTefTermPredicate() const override;
1400 public:
1401 FirstDerivExternalFunctionNode(DataTree &datatree_arg, int idx_arg,
1402 int top_level_symb_id_arg,
1403 const vector<expr_t> &arguments_arg,
1404 int inputIndex_arg);
1405 void computeTemporaryTerms(map<expr_t, int> &reference_count,
1406 temporary_terms_t &temporary_terms,
1407 map<expr_t, pair<int, int>> &first_occurence,
1408 int Curr_block,
1409 vector< vector<temporary_terms_t>> &v_temporary_terms,
1410 int equation) const override;
1411 void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override;
1412 void writeJsonAST(ostream &output) const override;
1413 void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override;
1414 void compile(ostream &CompileCode, unsigned int &instruction_number,
1415 bool lhs_rhs, const temporary_terms_t &temporary_terms,
1416 const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
1417 const deriv_node_temp_terms_t &tef_terms) const override;
1418 void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
1419 const temporary_terms_t &temporary_terms,
1420 const temporary_terms_idxs_t &temporary_terms_idxs,
1421 deriv_node_temp_terms_t &tef_terms) const override;
1422 void writeJsonExternalFunctionOutput(vector<string> &efout,
1423 const temporary_terms_t &temporary_terms,
1424 deriv_node_temp_terms_t &tef_terms,
1425 bool isdynamic) const override;
1426 void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
1427 bool lhs_rhs, const temporary_terms_t &temporary_terms,
1428 const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
1429 deriv_node_temp_terms_t &tef_terms) const override;
1430 expr_t toStatic(DataTree &static_datatree) const override;
1431 void computeXrefs(EquationInfo &ei) const override;
1432 expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const override;
1433 expr_t clone(DataTree &datatree) const override;
1434 };
1435
1436 class SecondDerivExternalFunctionNode : public AbstractExternalFunctionNode
1437 {
1438 public:
1439 const int inputIndex1;
1440 const int inputIndex2;
1441 private:
1442 expr_t composeDerivatives(const vector<expr_t> &dargs) override;
1443 protected:
1444 function<bool (expr_t)> sameTefTermPredicate() const override;
1445 public:
1446 SecondDerivExternalFunctionNode(DataTree &datatree_arg, int idx_arg,
1447 int top_level_symb_id_arg,
1448 const vector<expr_t> &arguments_arg,
1449 int inputIndex1_arg,
1450 int inputIndex2_arg);
1451 void computeTemporaryTerms(map<expr_t, int> &reference_count,
1452 temporary_terms_t &temporary_terms,
1453 map<expr_t, pair<int, int>> &first_occurence,
1454 int Curr_block,
1455 vector< vector<temporary_terms_t>> &v_temporary_terms,
1456 int equation) const override;
1457 void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override;
1458 void writeJsonAST(ostream &output) const override;
1459 void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override;
1460 void compile(ostream &CompileCode, unsigned int &instruction_number,
1461 bool lhs_rhs, const temporary_terms_t &temporary_terms,
1462 const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
1463 const deriv_node_temp_terms_t &tef_terms) const override;
1464 void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
1465 const temporary_terms_t &temporary_terms,
1466 const temporary_terms_idxs_t &temporary_terms_idxs,
1467 deriv_node_temp_terms_t &tef_terms) const override;
1468 void writeJsonExternalFunctionOutput(vector<string> &efout,
1469 const temporary_terms_t &temporary_terms,
1470 deriv_node_temp_terms_t &tef_terms,
1471 bool isdynamic) const override;
1472 void compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number,
1473 bool lhs_rhs, const temporary_terms_t &temporary_terms,
1474 const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
1475 deriv_node_temp_terms_t &tef_terms) const override;
1476 expr_t toStatic(DataTree &static_datatree) const override;
1477 void computeXrefs(EquationInfo &ei) const override;
1478 expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const override;
1479 expr_t clone(DataTree &datatree) const override;
1480 };
1481
1482 class VarExpectationNode : public ExprNode
1483 {
1484 public:
1485 const string model_name;
1486 VarExpectationNode(DataTree &datatree_arg, int idx_arg, string model_name_arg);
1487 void computeTemporaryTerms(const pair<int, int> &derivOrder,
1488 map<pair<int, int>, temporary_terms_t> &temp_terms_map,
1489 map<expr_t, pair<int, pair<int, int>>> &reference_count,
1490 bool is_matlab) const override;
1491 void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override;
1492 void computeTemporaryTerms(map<expr_t, int> &reference_count,
1493 temporary_terms_t &temporary_terms,
1494 map<expr_t, pair<int, int>> &first_occurence,
1495 int Curr_block,
1496 vector< vector<temporary_terms_t>> &v_temporary_terms,
1497 int equation) const override;
1498 expr_t toStatic(DataTree &static_datatree) const override;
1499 expr_t clone(DataTree &datatree) const override;
1500 int maxEndoLead() const override;
1501 int maxExoLead() const override;
1502 int maxEndoLag() const override;
1503 int maxExoLag() const override;
1504 int maxLead() const override;
1505 int maxLag() const override;
1506 int maxLagWithDiffsExpanded() const override;
1507 int VarMinLag() const override;
1508 int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override;
1509 int PacMaxLag(int lhs_symb_id) const override;
1510 int getPacTargetSymbId(int lhs_symb_id, int undiff_lhs_symb_id) const override;
1511 expr_t undiff() const override;
1512 expr_t decreaseLeadsLags(int n) const override;
1513 void prepareForDerivation() override;
1514 expr_t computeDerivative(int deriv_id) override;
1515 expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables) override;
1516 bool containsExternalFunction() const override;
1517 double eval(const eval_context_t &eval_context) const noexcept(false) override;
1518 void computeXrefs(EquationInfo &ei) const override;
1519 expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
1520 expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1521 expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
1522 expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1523 expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
1524 expr_t substituteAdl() const override;
1525 expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
1526 void findDiffNodes(lag_equivalence_table_t &nodes) const override;
1527 void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override;
1528 int findTargetVariable(int lhs_symb_id) const override;
1529 expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1530 expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1531 expr_t substitutePacExpectation(const string &name, expr_t subexpr) override;
1532 pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<tuple<int, expr_t, expr_t>> &List_of_Op_RHS) const override;
1533 void compile(ostream &CompileCode, unsigned int &instruction_number,
1534 bool lhs_rhs, const temporary_terms_t &temporary_terms,
1535 const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
1536 const deriv_node_temp_terms_t &tef_terms) const override;
1537 void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const override;
1538 void collectVARLHSVariable(set<expr_t> &result) const override;
1539 void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override;
1540 bool containsEndogenous() const override;
1541 bool containsExogenous() const override;
1542 int countDiffs() const override;
1543 bool isNumConstNodeEqualTo(double value) const override;
1544 expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1545 expr_t decreaseLeadsLagsPredeterminedVariables() const override;
1546 bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override;
1547 expr_t replaceTrendVar() const override;
1548 expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override;
1549 expr_t removeTrendLeadLag(const map<int, expr_t> &trend_symbols_map) const override;
1550 bool isInStaticForm() const override;
1551 void findConstantEquations(map<VariableNode *, NumConstNode *> &table) const override;
1552 expr_t replaceVarsInEquation(map<VariableNode *, NumConstNode *> &table) const override;
1553 bool containsPacExpectation(const string &pac_model_name = "") const override;
1554 bool isParamTimesEndogExpr() const override;
1555 bool isVarModelReferenced(const string &model_info_name) const override;
1556 void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
1557 expr_t substituteStaticAuxiliaryVariable() const override;
1558 void writeJsonAST(ostream &output) const override;
1559 void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override;
1560 };
1561
1562 class PacExpectationNode : public ExprNode
1563 {
1564 public:
1565 const string model_name;
1566 public:
1567 PacExpectationNode(DataTree &datatree_arg, int idx_arg, string model_name);
1568 void computeTemporaryTerms(const pair<int, int> &derivOrder,
1569 map<pair<int, int>, temporary_terms_t> &temp_terms_map,
1570 map<expr_t, pair<int, pair<int, int>>> &reference_count,
1571 bool is_matlab) const override;
1572 void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override;
1573 void computeTemporaryTerms(map<expr_t, int> &reference_count,
1574 temporary_terms_t &temporary_terms,
1575 map<expr_t, pair<int, int>> &first_occurence,
1576 int Curr_block,
1577 vector< vector<temporary_terms_t>> &v_temporary_terms,
1578 int equation) const override;
1579 expr_t toStatic(DataTree &static_datatree) const override;
1580 expr_t clone(DataTree &datatree) const override;
1581 int maxEndoLead() const override;
1582 int maxExoLead() const override;
1583 int maxEndoLag() const override;
1584 int maxExoLag() const override;
1585 int maxLead() const override;
1586 int maxLag() const override;
1587 int maxLagWithDiffsExpanded() const override;
1588 int VarMinLag() const override;
1589 int VarMaxLag(const set<expr_t> &lhs_lag_equiv) const override;
1590 int PacMaxLag(int lhs_symb_id) const override;
1591 int getPacTargetSymbId(int lhs_symb_id, int undiff_lhs_symb_id) const override;
1592 expr_t undiff() const override;
1593 expr_t decreaseLeadsLags(int n) const override;
1594 void prepareForDerivation() override;
1595 expr_t computeDerivative(int deriv_id) override;
1596 expr_t getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables) override;
1597 bool containsExternalFunction() const override;
1598 double eval(const eval_context_t &eval_context) const noexcept(false) override;
1599 void computeXrefs(EquationInfo &ei) const override;
1600 expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
1601 expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1602 expr_t substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const override;
1603 expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1604 expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
1605 expr_t substituteAdl() const override;
1606 expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
1607 void findDiffNodes(lag_equivalence_table_t &nodes) const override;
1608 void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override;
1609 int findTargetVariable(int lhs_symb_id) const override;
1610 expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1611 expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1612 expr_t substitutePacExpectation(const string &name, expr_t subexpr) override;
1613 pair<int, expr_t> normalizeEquation(int symb_id_endo, vector<tuple<int, expr_t, expr_t>> &List_of_Op_RHS) const override;
1614 void compile(ostream &CompileCode, unsigned int &instruction_number,
1615 bool lhs_rhs, const temporary_terms_t &temporary_terms,
1616 const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
1617 const deriv_node_temp_terms_t &tef_terms) const override;
1618 void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const override;
1619 void collectVARLHSVariable(set<expr_t> &result) const override;
1620 void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override;
1621 bool containsEndogenous() const override;
1622 bool containsExogenous() const override;
1623 int countDiffs() const override;
1624 bool isNumConstNodeEqualTo(double value) const override;
1625 expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
1626 expr_t decreaseLeadsLagsPredeterminedVariables() const override;
1627 bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override;
1628 expr_t replaceTrendVar() const override;
1629 expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override;
1630 expr_t removeTrendLeadLag(const map<int, expr_t> &trend_symbols_map) const override;
1631 bool isInStaticForm() const override;
1632 void findConstantEquations(map<VariableNode *, NumConstNode *> &table) const override;
1633 expr_t replaceVarsInEquation(map<VariableNode *, NumConstNode *> &table) const override;
1634 bool containsPacExpectation(const string &pac_model_name = "") const override;
1635 bool isParamTimesEndogExpr() const override;
1636 bool isVarModelReferenced(const string &model_info_name) const override;
1637 void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
1638 expr_t substituteStaticAuxiliaryVariable() const override;
1639 void writeJsonAST(ostream &output) const override;
1640 void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override;
1641 };
1642
1643 #endif
1644