2008-02-03 11:28:36 +01:00
/*
2023-02-28 15:33:24 +01:00
* Copyright © 2007 - 2023 Dynare Team
2008-02-03 11:28:36 +01:00
*
* This file is part of Dynare .
*
* Dynare is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* Dynare is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2021-06-09 16:52:20 +02:00
* along with Dynare . If not , see < https : //www.gnu.org/licenses/>.
2008-02-03 11:28:36 +01:00
*/
# ifndef _EXPR_NODE_HH
# define _EXPR_NODE_HH
# include <set>
# include <map>
# include <vector>
2009-07-06 12:36:36 +02:00
# include <ostream>
2018-05-29 17:07:18 +02:00
# include <functional>
2022-05-05 18:39:04 +02:00
# include <optional>
2023-03-23 12:38:44 +01:00
# include <utility>
2023-04-05 14:16:22 +02:00
# include <unordered_map>
2023-04-05 14:53:47 +02:00
# include <unordered_set>
2008-02-03 11:28:36 +01:00
2013-12-30 14:45:17 +01:00
using namespace std ;
2022-06-16 17:52:14 +02:00
# include "CommonEnums.hh"
2010-02-22 17:33:38 +01:00
# include "ExternalFunctionsTable.hh"
2022-06-23 14:28:13 +02:00
# include "Bytecode.hh"
2008-02-03 11:28:36 +01:00
class DataTree ;
2019-01-29 17:29:24 +01:00
class NumConstNode ;
2009-09-30 17:10:31 +02:00
class VariableNode ;
2018-03-02 12:32:01 +01:00
class UnaryOpNode ;
2009-09-30 17:10:31 +02:00
class BinaryOpNode ;
2018-02-07 10:05:32 +01:00
class PacExpectationNode ;
2008-02-03 11:28:36 +01:00
2018-06-04 14:07:13 +02:00
using expr_t = class ExprNode * ;
2008-02-03 11:28:36 +01:00
struct ExprNodeLess ;
//! Type for set of temporary terms
2018-05-28 15:50:29 +02:00
/*! The ExprNodeLess ordering is important for the temporary terms algorithm,
2019-12-20 16:59:30 +01:00
see the definition of ExprNodeLess */
2018-06-04 14:31:26 +02:00
using temporary_terms_t = set < expr_t , ExprNodeLess > ;
2018-03-27 17:14:30 +02:00
/*! Keeps track of array indices of temporary_terms for writing */
2023-04-05 14:53:47 +02:00
using temporary_terms_idxs_t = unordered_map < expr_t , int > ;
2009-04-17 18:26:23 +02:00
2009-04-30 15:14:33 +02:00
//! Type for evaluation contexts
/*! The key is a symbol id. Lags are assumed to be null */
2018-06-04 14:31:26 +02:00
using eval_context_t = map < int , double > ;
2009-04-30 15:14:33 +02:00
2010-03-04 16:40:07 +01:00
//! Type for tracking first/second derivative functions that have already been written as temporary terms
2018-06-04 14:31:26 +02:00
using deriv_node_temp_terms_t = map < pair < int , vector < expr_t > > , int > ;
2010-03-04 16:40:07 +01:00
2019-10-22 14:56:28 +02:00
//! Type for the substitution map used for creating aux. vars for diff and unary_ops
/*! Let ≅ be the equivalence relationship such that two expressions e₁ and e₂
are equivalent iff e ₁ can be obtained from e ₂ by shifting all leads / lags by
the same number of periods ( e . g . x ₋ ₁ + y ₂ ≅ x ₁ + y ₄ ) .
For each equivalence class , we select a representative element , which is
the class member which has no lead and a variable appearing at current
period ( in the previous example , it would be x ₋ ₃ + y ) . ( Obviously , if there
is no variable in the expression , then there is only one element in the
class , and that one is the representative )
Each member of an equivalence class is represented by an integer ,
corresponding to its distance to the representative element ( e . g . x ₋ ₁ + y ₂
has index 2 and x ₁ + y ₄ has index 4 ) . The representative element has index 0
by definition .
The keys in the std : : map are the representative elements of the various
equivalence classes . The values are themselves std : : map that describe the
equivalence class : they associate indices of class members to the
expressions with which they should be substituted . */
using lag_equivalence_table_t = map < expr_t , map < int , expr_t > > ;
2018-02-28 17:33:00 +01:00
2022-07-06 16:44:51 +02:00
//! Possible types of output when writing ExprNode(s) (not used for bytecode)
2018-09-05 18:27:13 +02:00
enum class ExprNodeOutputType
2008-02-03 11:28:36 +01:00
{
2022-09-14 17:07:08 +02:00
matlabStaticModel , //!< Matlab code, static model, legacy representation
matlabDynamicModel , //!< Matlab code, dynamic model, legacy representation
matlabSparseStaticModel , //!< Matlab code, static model, sparse representation
matlabSparseDynamicModel , //!< Matlab code, dynamic model, sparse representation
CDynamicModel , //!< C code, dynamic model, legacy representation
CStaticModel , //!< C code, static model, legacy representation
CSparseDynamicModel , //!< C code, dynamic model, sparse representation
CSparseStaticModel , //!< C code, static model, sparse representation
juliaStaticModel , //!< Julia code, static model, legacy representation
juliaDynamicModel , //!< Julia code, dynamic model, legacy representation
juliaSparseStaticModel , //!< Julia code, static model, sparse representation
juliaSparseDynamicModel , //!< Julia code, dynamic model, sparse representation
2019-12-20 16:59:30 +01:00
matlabOutsideModel , //!< Matlab code, outside model block (for example in initval)
latexStaticModel , //!< LaTeX code, static model
latexDynamicModel , //!< LaTeX code, dynamic model
latexDynamicSteadyStateOperator , //!< LaTeX code, dynamic model, inside a steady state operator
matlabDynamicSteadyStateOperator , //!< Matlab code, dynamic model, inside a steady state operator
CDynamicSteadyStateOperator , //!< C code, dynamic model, inside a steady state operator
juliaDynamicSteadyStateOperator , //!< Julia code, dynamic model, inside a steady state operator
steadyStateFile , //!< Matlab code, in the generated steady state file
juliaSteadyStateFile , //!< Julia code, in the generated steady state file
matlabDseries , //!< Matlab code for dseries
2022-04-01 17:34:18 +02:00
juliaTimeDataFrame , //!< Julia code for TimeDataFrame objects
2021-07-20 12:20:19 +02:00
epilogueFile , //!< Matlab code, in the generated epilogue file
occbinDifferenceFile //!< MATLAB, in the generated occbin_difference file
2008-02-03 11:28:36 +01:00
} ;
2022-07-06 16:44:51 +02:00
// Possible types of output when writing ExprNode(s) in bytecode
enum class ExprNodeBytecodeOutputType
{
dynamicModel ,
staticModel ,
dynamicSteadyStateOperator , // Inside a steady_state operator
dynamicAssignmentLHS , // Assignment of a dynamic variable on the LHS of a (recursive) equation
staticAssignmentLHS // Assignment of a static variable on the LHS of a (recursive) equation
} ;
2022-06-24 14:50:40 +02:00
constexpr bool
2018-09-05 18:27:13 +02:00
isMatlabOutput ( ExprNodeOutputType output_type )
{
return output_type = = ExprNodeOutputType : : matlabStaticModel
| | output_type = = ExprNodeOutputType : : matlabDynamicModel
2022-09-14 17:07:08 +02:00
| | output_type = = ExprNodeOutputType : : matlabSparseStaticModel
| | output_type = = ExprNodeOutputType : : matlabSparseDynamicModel
2018-09-05 18:27:13 +02:00
| | output_type = = ExprNodeOutputType : : matlabOutsideModel
| | output_type = = ExprNodeOutputType : : matlabDynamicSteadyStateOperator
| | output_type = = ExprNodeOutputType : : steadyStateFile
| | output_type = = ExprNodeOutputType : : matlabDseries
2021-07-20 12:20:19 +02:00
| | output_type = = ExprNodeOutputType : : epilogueFile
| | output_type = = ExprNodeOutputType : : occbinDifferenceFile ;
2018-09-05 18:27:13 +02:00
}
2022-06-24 14:50:40 +02:00
constexpr bool
2018-09-05 18:27:13 +02:00
isJuliaOutput ( ExprNodeOutputType output_type )
{
return output_type = = ExprNodeOutputType : : juliaStaticModel
| | output_type = = ExprNodeOutputType : : juliaDynamicModel
2022-09-14 17:07:08 +02:00
| | output_type = = ExprNodeOutputType : : juliaSparseStaticModel
| | output_type = = ExprNodeOutputType : : juliaSparseDynamicModel
2018-09-05 18:27:13 +02:00
| | output_type = = ExprNodeOutputType : : juliaDynamicSteadyStateOperator
2022-04-01 17:34:18 +02:00
| | output_type = = ExprNodeOutputType : : juliaSteadyStateFile
| | output_type = = ExprNodeOutputType : : juliaTimeDataFrame ;
2018-09-05 18:27:13 +02:00
}
2022-06-24 14:50:40 +02:00
constexpr bool
2018-09-05 18:27:13 +02:00
isCOutput ( ExprNodeOutputType output_type )
{
return output_type = = ExprNodeOutputType : : CDynamicModel
| | output_type = = ExprNodeOutputType : : CStaticModel
2022-09-14 17:07:08 +02:00
| | output_type = = ExprNodeOutputType : : CSparseDynamicModel
| | output_type = = ExprNodeOutputType : : CSparseStaticModel
2018-09-05 18:27:13 +02:00
| | output_type = = ExprNodeOutputType : : CDynamicSteadyStateOperator ;
}
2022-06-24 14:50:40 +02:00
constexpr bool
2018-09-05 18:27:13 +02:00
isLatexOutput ( ExprNodeOutputType output_type )
{
return output_type = = ExprNodeOutputType : : latexStaticModel
| | output_type = = ExprNodeOutputType : : latexDynamicModel
| | output_type = = ExprNodeOutputType : : latexDynamicSteadyStateOperator ;
}
2008-02-03 11:28:36 +01:00
2022-07-05 15:04:36 +02:00
constexpr bool
isSteadyStateOperatorOutput ( ExprNodeOutputType output_type )
{
return output_type = = ExprNodeOutputType : : latexDynamicSteadyStateOperator
| | output_type = = ExprNodeOutputType : : matlabDynamicSteadyStateOperator
| | output_type = = ExprNodeOutputType : : CDynamicSteadyStateOperator
| | output_type = = ExprNodeOutputType : : juliaDynamicSteadyStateOperator ;
}
2022-09-14 17:07:08 +02:00
constexpr bool
isSparseModelOutput ( ExprNodeOutputType output_type )
{
return output_type = = ExprNodeOutputType : : matlabSparseStaticModel
| | output_type = = ExprNodeOutputType : : matlabSparseDynamicModel
| | output_type = = ExprNodeOutputType : : juliaSparseStaticModel
| | output_type = = ExprNodeOutputType : : juliaSparseDynamicModel
| | output_type = = ExprNodeOutputType : : CSparseDynamicModel
| | output_type = = ExprNodeOutputType : : CSparseStaticModel ;
}
2022-07-06 16:44:51 +02:00
constexpr bool
isAssignmentLHSBytecodeOutput ( ExprNodeBytecodeOutputType output_type )
{
return output_type = = ExprNodeBytecodeOutputType : : staticAssignmentLHS
| | output_type = = ExprNodeBytecodeOutputType : : dynamicAssignmentLHS ;
}
2015-08-21 16:44:55 +02:00
/* Equal to 1 for Matlab langage or Julia, or to 0 for C language. Not defined for LaTeX.
In Matlab and Julia , array indexes begin at 1 , while they begin at 0 in C */
2022-06-24 14:50:40 +02:00
constexpr int
2019-12-16 19:42:59 +01:00
ARRAY_SUBSCRIPT_OFFSET ( ExprNodeOutputType output_type )
{
return static_cast < int > ( isMatlabOutput ( output_type ) | | isJuliaOutput ( output_type ) ) ;
}
2008-02-03 11:28:36 +01:00
2009-04-30 15:14:33 +02:00
// Left and right array subscript delimiters: '(' and ')' for Matlab, '[' and ']' for C
2022-06-24 14:50:40 +02:00
constexpr char
2019-12-16 19:42:59 +01:00
LEFT_ARRAY_SUBSCRIPT ( ExprNodeOutputType output_type )
{
return isMatlabOutput ( output_type ) ? ' ( ' : ' [ ' ;
}
2022-06-24 14:50:40 +02:00
constexpr char
2019-12-16 19:42:59 +01:00
RIGHT_ARRAY_SUBSCRIPT ( ExprNodeOutputType output_type )
{
return isMatlabOutput ( output_type ) ? ' ) ' : ' ] ' ;
}
2008-02-03 11:28:36 +01:00
2009-04-30 15:14:33 +02:00
// Left and right parentheses
2019-12-16 19:42:59 +01:00
inline string
LEFT_PAR ( ExprNodeOutputType output_type )
{
return isLatexOutput ( output_type ) ? " \\ left( " : " ( " ;
}
inline string
RIGHT_PAR ( ExprNodeOutputType output_type )
{
return isLatexOutput ( output_type ) ? " \\ right) " : " ) " ;
}
2008-02-03 11:28:36 +01:00
//! Base class for expression nodes
2018-02-07 10:05:32 +01:00
class ExprNode
2019-12-20 16:59:30 +01:00
{
friend class DataTree ;
friend class DynamicModel ;
friend class StaticModel ;
friend class ModelTree ;
friend struct ExprNodeLess ;
friend class NumConstNode ;
friend class VariableNode ;
friend class UnaryOpNode ;
friend class BinaryOpNode ;
friend class TrinaryOpNode ;
friend class AbstractExternalFunctionNode ;
friend class VarExpectationNode ;
friend class PacExpectationNode ;
private :
//! Computes derivative w.r. to a derivation ID (but doesn't store it in derivatives map)
/*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */
virtual expr_t computeDerivative ( int deriv_id ) = 0 ;
2022-11-08 12:28:48 +01:00
/* Internal helper for getChainRuleDerivative(), that does the computation
but assumes that the caching of this is handled elsewhere */
2023-04-05 14:16:22 +02:00
virtual expr_t computeChainRuleDerivative ( int deriv_id , const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives , unordered_map < expr_t , map < int , expr_t > > & cache ) = 0 ;
2022-11-08 12:28:48 +01:00
2019-12-20 16:59:30 +01:00
protected :
//! Reference to the enclosing DataTree
DataTree & datatree ;
//! Index number
const int idx ;
//! Is the data member non_null_derivatives initialized ?
bool preparedForDerivation { false } ;
//! Set of derivation IDs with respect to which the derivative is potentially non-null
set < int > non_null_derivatives ;
//! Used for caching of first order derivatives (when non-null)
map < int , expr_t > derivatives ;
constexpr static int min_cost_matlab { 40 * 90 } ;
constexpr static int min_cost_c { 40 * 4 } ;
2022-06-24 14:50:40 +02:00
constexpr static int
2019-12-20 16:59:30 +01:00
min_cost ( bool is_matlab )
{
2022-06-02 10:50:21 +02:00
return is_matlab ? min_cost_matlab : min_cost_c ;
2019-12-20 16:59:30 +01:00
} ;
2023-03-02 16:08:32 +01:00
//! Initializes data member non_null_derivatives
virtual void prepareForDerivation ( ) = 0 ;
2023-03-02 17:49:16 +01:00
/* Computes the derivatives which are potentially non-null, using symbolic a
priori , similarly to prepareForDerivation ( ) , but in a chain rule
derivation context . See getChainRuleDerivation ( ) for the meaning of
“ recursive_variables ” . Note that all non - endogenous variables are
automatically considered to have a zero derivative ( since they ’ re never
used in a chain rule context ) */
2023-04-05 14:16:22 +02:00
virtual void prepareForChainRuleDerivation ( const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives ) const = 0 ;
2023-03-02 17:49:16 +01:00
2019-12-20 16:59:30 +01:00
//! Cost of computing current node
/*! Nodes included in temporary_terms are considered having a null cost */
virtual int cost ( int cost , bool is_matlab ) const ;
2023-04-05 14:53:47 +02:00
virtual int cost ( const vector < vector < unordered_set < expr_t > > > & blocks_temporary_terms , bool is_matlab ) const ;
virtual int cost ( const map < pair < int , int > , unordered_set < expr_t > > & temp_terms_map , bool is_matlab ) const ;
2019-12-20 16:59:30 +01:00
//! For creating equation cross references
struct EquationInfo
{
2022-06-02 10:50:21 +02:00
set < pair < int , int > > param , endo , exo , exo_det ;
2019-12-20 16:59:30 +01:00
} ;
//! If this node is a temporary term, writes its temporary term representation
/*! Returns true if node is a temporary term and has therefore been
written to output */
bool checkIfTemporaryTermThenWrite ( ostream & output , ExprNodeOutputType output_type ,
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ) const ;
2022-06-23 14:28:13 +02:00
// Same as above, for the bytecode case
bool checkIfTemporaryTermThenWriteBytecode ( BytecodeWriter & code_file ,
2022-07-06 16:44:51 +02:00
ExprNodeBytecodeOutputType output_type ,
2022-06-23 14:28:13 +02:00
const temporary_terms_t & temporary_terms ,
2022-07-06 16:44:51 +02:00
const temporary_terms_idxs_t & temporary_terms_idxs ) const ;
2022-06-23 14:28:13 +02:00
2019-12-20 16:59:30 +01:00
// Internal helper for matchVariableTimesConstantTimesParam()
2022-05-16 17:42:24 +02:00
virtual void matchVTCTPHelper ( optional < int > & var_id , int & lag , optional < int > & param_id , double & constant , bool at_denominator ) const ;
2019-12-20 16:59:30 +01:00
/* Computes the representative element and the index under the
lag - equivalence relationship . See the comment above
lag_equivalence_table_t for an explanation of these concepts . */
pair < expr_t , int > getLagEquivalenceClass ( ) const ;
2022-10-18 17:24:51 +02:00
/* Computes the set of all sub-expressions that contain the variable
( symb_id , lag ) .
Note that if a diff operator is encountered :
- diff ( expr ) will be added to the output set if either expr or expr ( - 1 )
contains the variable ;
- the method will be called recursively on expr - expr ( - 1 ) */
virtual void computeSubExprContainingVariable ( int symb_id , int lag , set < expr_t > & contain_var ) const = 0 ;
2019-12-20 16:59:30 +01:00
public :
ExprNode ( DataTree & datatree_arg , int idx_arg ) ;
virtual ~ ExprNode ( ) = default ;
ExprNode ( const ExprNode & ) = delete ;
ExprNode & operator = ( const ExprNode & ) = delete ;
//! Returns derivative w.r. to derivation ID
/*! Uses a symbolic a priori to pre-detect null derivatives, and caches the result for other derivatives (to avoid computing it several times)
For an equal node , returns the derivative of lhs minus rhs */
expr_t getDerivative ( int deriv_id ) ;
2022-11-08 12:28:48 +01:00
/* Computes derivatives by applying the chain rule for some variables.
— “ 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
2023-03-02 17:49:16 +01:00
— “ non_null_chain_rule_derivatives ” is used to store the indices of
variables that are potentially non - null ( using symbolic a priori ) ,
similarly to ExprNode : : non_null_derivatives .
2022-11-08 12:28:48 +01:00
— “ cache ” is used to store already - computed derivatives ( in a map
2023-03-02 17:49:16 +01:00
< expression , deriv_id > → derivative )
NB : always returns zero when “ deriv_id ” corresponds to a non - endogenous
variable ( since such variables are never used in a chain rule context ) .
NB 2 : “ non_null_chain_rule_derivatives ” and “ cache ” are specific to a given
value of “ recursive_variables ” , and thus should not be reused accross
2023-04-05 14:16:22 +02:00
calls that use different values of “ recursive_variables ” .
NB 3 : the use of std : : unordered_map instead of std : : map for caching
purposes improves performance on very very large models ( tens of thousands
of equations ) */
expr_t getChainRuleDerivative ( int deriv_id , const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives , unordered_map < expr_t , map < int , expr_t > > & cache ) ;
2019-12-20 16:59:30 +01:00
//! Returns precedence of node
/*! Equals 100 for constants, variables, unary ops, and temporary terms */
virtual int precedence ( ExprNodeOutputType output_t , const temporary_terms_t & temporary_terms ) const ;
//! Compute temporary terms in this expression
/*!
\ param [ in ] derivOrder the derivation order ( first w . r . t . endo / exo ,
second w . r . t . params )
\ param [ out ] temp_terms_map the computed temporary terms , associated
with their derivation order
\ param [ out ] reference_count a temporary structure , used to count
references to each node ( integer in outer pair is the
reference count , the inner pair is the derivation order )
\ param [ in ] is_matlab whether we are in a MATLAB context , since that
affects the cost of each operator
A node will be marked as a temporary term if it is referenced at least
two times ( i . e . has at least two parents ) , and has a computing cost
( multiplied by reference count ) greater to datatree . min_cost
2023-04-05 14:53:47 +02:00
NB : the use of std : : unordered_map instead of std : : map for caching
purposes improves performance on very large models ( ⩾ 5000 equations )
2019-12-20 16:59:30 +01:00
*/
virtual void computeTemporaryTerms ( const pair < int , int > & derivOrder ,
2023-04-05 14:53:47 +02:00
map < pair < int , int > , unordered_set < expr_t > > & temp_terms_map ,
unordered_map < expr_t , pair < int , pair < int , int > > > & reference_count ,
2019-12-20 16:59:30 +01:00
bool is_matlab ) const ;
2020-05-06 17:13:47 +02:00
//! Compute temporary terms in this expression for block decomposed model
/*!
\ param [ in ] blk the block number
2020-05-13 16:58:19 +02:00
\ param [ in ] eq the equation number ( within the block )
2020-05-06 17:13:47 +02:00
\ param [ out ] blocks_temporary_terms the computed temporary terms , per block
2020-05-13 16:58:19 +02:00
and per equation in the block
2020-05-06 17:13:47 +02:00
\ param [ out ] reference_count a temporary structure , used to count
references to each node ( first integer is the
reference count , second integer is the number of the block in which the
2020-05-13 16:58:19 +02:00
expression first appears , third integer is the equation number within the block )
2020-05-06 17:13:47 +02:00
Same rules as computeTemporaryTerms ( ) for computing cost .
2023-04-05 14:53:47 +02:00
NB : the use of std : : unordered_ { set , map } instead of std : : { set , map } for caching
and output improves performance on very large models ( ⩾ 5000 equations )
2020-05-06 17:13:47 +02:00
*/
2020-05-13 16:58:19 +02:00
virtual void computeBlockTemporaryTerms ( int blk , int eq ,
2023-04-05 14:53:47 +02:00
vector < vector < unordered_set < expr_t > > > & blocks_temporary_terms ,
unordered_map < expr_t , tuple < int , int , int > > & reference_count ) const ;
2020-05-06 17:13:47 +02:00
2019-12-20 16:59:30 +01:00
//! Writes output of node, using a Txxx notation for nodes in temporary_terms, and specifiying the set of already written external functions
/*!
\ param [ in ] output the output stream
\ param [ in ] output_type the type of output ( MATLAB , C , LaTeX . . . )
\ param [ in ] temporary_terms the nodes that are marked as temporary terms
\ param [ in ] a map from temporary_terms to integers indexes ( in the
MATLAB , C or Julia vector of temporary terms ) ; can be empty
when writing MATLAB with block decomposition )
\ param [ in ] tef_terms the set of already written external function nodes
*/
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 ;
//! returns true if the expr node contains an external function
virtual bool containsExternalFunction ( ) const = 0 ;
//! Writes output of node (with no temporary terms and with "outside model" output type)
void writeOutput ( ostream & output ) const ;
//! Writes output of node (with no temporary terms)
void writeOutput ( ostream & output , ExprNodeOutputType output_type ) const ;
//! Writes output of node, using a Txxx notation for nodes in temporary_terms
void writeOutput ( ostream & output , ExprNodeOutputType output_type , const temporary_terms_t & temporary_terms , const temporary_terms_idxs_t & temporary_terms_idxs ) const ;
//! Writes output of node in JSON syntax
virtual void writeJsonOutput ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic = true ) const = 0 ;
2022-01-26 15:16:22 +01:00
// Returns a string representation of the expression, used by the GDB pretty printer
string toString ( ) const ;
2019-12-20 16:59:30 +01:00
//! Writes the Abstract Syntax Tree in JSON
virtual void writeJsonAST ( ostream & output ) const = 0 ;
virtual int precedenceJson ( const temporary_terms_t & temporary_terms ) const ;
//! Writes the output for an external function, ensuring that the external function is called as few times as possible using temporary terms
virtual void writeExternalFunctionOutput ( ostream & output , ExprNodeOutputType output_type ,
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
deriv_node_temp_terms_t & tef_terms ) const ;
//! Write the JSON output of an external function in a string vector
//! Allows the insertion of commas if necessary
virtual void writeJsonExternalFunctionOutput ( vector < string > & efout ,
2017-06-01 19:58:32 +02:00
const temporary_terms_t & temporary_terms ,
2019-12-20 16:59:30 +01:00
deriv_node_temp_terms_t & tef_terms ,
bool isdynamic = true ) const ;
2022-06-23 14:28:13 +02:00
virtual void writeBytecodeExternalFunctionOutput ( BytecodeWriter & code_file ,
2022-07-06 16:44:51 +02:00
ExprNodeBytecodeOutputType output_type ,
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
2022-06-23 14:28:13 +02:00
deriv_node_temp_terms_t & tef_terms ) const ;
2019-12-20 16:59:30 +01:00
//! Computes the set of all variables of a given symbol type in the expression (with information on lags)
/*!
Variables are stored as integer pairs of the form ( symb_id , lag ) .
They are added to the set given in argument .
Note that model local variables are substituted by their expression in the computation
( and added if type_arg = ModelLocalVariable ) .
*/
virtual void collectDynamicVariables ( SymbolType type_arg , set < pair < int , int > > & result ) const = 0 ;
//! Find the maximum lag in a VAR: handles case where LHS is diff
virtual int VarMaxLag ( const set < expr_t > & lhs_lag_equiv ) const = 0 ;
//! Finds LHS variable in a VAR equation
virtual void collectVARLHSVariable ( set < expr_t > & result ) const = 0 ;
//! Computes the set of all variables of a given symbol type in the expression (without information on lags)
/*!
Variables are stored as symb_id .
They are added to the set given in argument .
Note that model local variables are substituted by their expression in the computation
( and added if type_arg = ModelLocalVariable ) .
*/
void collectVariables ( SymbolType type_arg , set < int > & result ) const ;
//! Computes the set of endogenous variables in the expression
/*!
Endogenous are stored as integer pairs of the form ( type_specific_id , lag ) .
They are added to the set given in argument .
Note that model local variables are substituted by their expression in the computation .
*/
2020-09-29 18:20:36 +02:00
void collectEndogenous ( set < pair < int , int > > & result ) const ;
2019-12-20 16:59:30 +01:00
class EvalException
{
} ;
class EvalExternalFunctionException : public EvalException
{
} ;
virtual double eval ( const eval_context_t & eval_context ) const noexcept ( false ) = 0 ;
2022-07-06 16:44:51 +02:00
// Write output to bytecode file
virtual void writeBytecodeOutput ( BytecodeWriter & code_file , ExprNodeBytecodeOutputType 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 ;
2022-05-20 11:43:02 +02:00
2019-12-20 16:59:30 +01:00
//! Creates a static version of this node
/*!
This method duplicates the current node by creating a similar node from which all leads / lags have been stripped ,
adds the result in the static_datatree argument ( and not in the original datatree ) , and returns it .
*/
virtual expr_t toStatic ( DataTree & static_datatree ) const = 0 ;
/*!
Compute cross references for equations
*/
// virtual void computeXrefs(set<int> ¶m, set<int> &endo, set<int> &exo, set<int> &exo_det) const = 0;
virtual void computeXrefs ( EquationInfo & ei ) const = 0 ;
2020-04-02 14:36:26 +02:00
//! Helper for normalization of equations
/*! Normalize the equation this = rhs.
Must be called on a node containing the desired LHS variable .
Returns an equal node of the form : LHS variable = new RHS .
Must be given the set of all subexpressions that contain the desired LHS variable .
Throws a NormallizationFailed ( ) exception if normalization is not possible . */
virtual BinaryOpNode * normalizeEquationHelper ( const set < expr_t > & contain_var , expr_t rhs ) const = 0 ;
class NormalizationFailed { } ;
2019-12-20 16:59:30 +01:00
//! Returns the maximum lead of endogenous in this expression
/*! Always returns a non-negative value */
virtual int maxEndoLead ( ) const = 0 ;
//! Returns the maximum lead of exogenous in this expression
/*! Always returns a non-negative value */
virtual int maxExoLead ( ) const = 0 ;
//! Returns the maximum lag of endogenous in this expression
/*! Always returns a non-negative value */
virtual int maxEndoLag ( ) const = 0 ;
//! Returns the maximum lag of exogenous in this expression
/*! Always returns a non-negative value */
virtual int maxExoLag ( ) const = 0 ;
//! Returns the maximum lead of endo/exo/exodet in this expression
/*! A negative value means that the expression contains only lagged
variables . A value of numeric_limits < int > : : min ( ) means that there is
no variable . */
virtual int maxLead ( ) const = 0 ;
//! Returns the maximum lag of endo/exo/exodet in this expression
/*! A negative value means that the expression contains only leaded
variables . A value of numeric_limits < int > : : min ( ) means that there is
no variable . */
virtual int maxLag ( ) const = 0 ;
//! Returns the maximum lag of endo/exo/exodet, as if diffs were expanded
/*! This function behaves as maxLag(), except that it treats diff()
differently . For e . g . , on diff ( diff ( x ( - 1 ) ) ) , maxLag ( ) returns 1 while
maxLagWithDiffsExpanded ( ) returns 3. */
virtual int maxLagWithDiffsExpanded ( ) const = 0 ;
virtual expr_t undiff ( ) const = 0 ;
//! Returns a new expression where all the leads/lags have been shifted backwards by the same amount
/*!
Only acts on endogenous , exogenous , exogenous det
\ param [ in ] n The number of lags by which to shift
\ return The same expression except that leads / lags have been shifted backwards
*/
virtual expr_t decreaseLeadsLags ( int n ) const = 0 ;
//! Type for the substitution map used in the process of creating auxiliary vars
using subst_table_t = map < const ExprNode * , const VariableNode * > ;
//! Type for the substitution map used in the process of substituting adl expressions
using subst_table_adl_t = map < const ExprNode * , const expr_t > ;
//! Creates auxiliary endo lead variables corresponding to this expression
/*!
If maximum endogenous lead > = 3 , this method will also create intermediary auxiliary var , and will add the equations of the form aux1 = aux2 ( + 1 ) to the substitution table .
\ pre This expression is assumed to have maximum endogenous lead > = 2
\ param [ in , out ] subst_table The table to which new auxiliary variables and their correspondance will be added
\ param [ out ] neweqs Equations to be added to the model to match the creation of auxiliary variables .
\ return The new variable node corresponding to the current expression
*/
VariableNode * createEndoLeadAuxiliaryVarForMyself ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const ;
//! Creates auxiliary exo lead variables corresponding to this expression
/*!
If maximum exogenous lead > = 2 , this method will also create intermediary auxiliary var , and will add the equations of the form aux1 = aux2 ( + 1 ) to the substitution table .
\ pre This expression is assumed to have maximum exogenous lead > = 1
\ param [ in , out ] subst_table The table to which new auxiliary variables and their correspondance will be added
\ param [ out ] neweqs Equations to be added to the model to match the creation of auxiliary variables .
\ return The new variable node corresponding to the current expression
*/
VariableNode * createExoLeadAuxiliaryVarForMyself ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const ;
//! Constructs a new expression where sub-expressions with max endo lead >= 2 have been replaced by auxiliary variables
/*!
\ param [ in , out ] subst_table Map used to store expressions that have already be substituted and their corresponding variable , in order to avoid creating two auxiliary variables for the same sub - expr .
\ param [ out ] neweqs Equations to be added to the model to match the creation of auxiliary variables .
If the method detects a sub - expr which needs to be substituted , two cases are possible :
- if this expr is in the table , then it will use the corresponding variable and return the substituted expression
- if this expr is not in the table , then it will create an auxiliary endogenous variable , add the substitution in the table and return the substituted expression
\ return A new equivalent expression where sub - expressions with max endo lead > = 2 have been replaced by auxiliary variables
*/
virtual expr_t substituteEndoLeadGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const = 0 ;
//! Constructs a new expression where endo variables with max endo lag >= 2 have been replaced by auxiliary variables
/*!
\ param [ in , out ] subst_table Map used to store expressions that have already be substituted and their corresponding variable , in order to avoid creating two auxiliary variables for the same sub - expr .
\ param [ out ] neweqs Equations to be added to the model to match the creation of auxiliary variables .
*/
virtual expr_t substituteEndoLagGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const = 0 ;
//! Constructs a new expression where exogenous variables with a lead have been replaced by auxiliary variables
/*!
\ param [ in , out ] subst_table Map used to store expressions that have already be substituted and their corresponding variable , in order to avoid creating two auxiliary variables for the same sub - expr .
\ param [ out ] neweqs Equations to be added to the model to match the creation of auxiliary variables .
*/
virtual expr_t substituteExoLead ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const = 0 ;
//! Constructs a new expression where exogenous variables with a lag have been replaced by auxiliary variables
/*!
\ param [ in , out ] subst_table Map used to store expressions that have already be substituted and their corresponding variable , in order to avoid creating two auxiliary variables for the same sub - expr .
\ param [ out ] neweqs Equations to be added to the model to match the creation of auxiliary variables .
*/
virtual expr_t substituteExoLag ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const = 0 ;
//! Constructs a new expression where the expectation operator has been replaced by auxiliary variables
/*!
\ param [ in , out ] subst_table Map used to store expressions that have already be substituted and their corresponding variable , in order to avoid creating two auxiliary variables for the same sub - expr .
\ param [ out ] neweqs Equations to be added to the model to match the creation of auxiliary variables .
\ param [ in ] partial_information_model Are we substituting in a partial information model ?
*/
virtual expr_t substituteExpectation ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool partial_information_model ) const = 0 ;
virtual expr_t decreaseLeadsLagsPredeterminedVariables ( ) const = 0 ;
//! 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
/*!
\ param [ in ] subset variables to which to limit the transformation ; transform
all fwrd vars if empty
\ param [ in , out ] subst_table Map used to store mapping between a given
forward variable and the aux var that contains its differentiate
\ param [ out ] neweqs Equations to be added to the model to match the creation of auxiliary variables .
*/
virtual expr_t differentiateForwardVars ( const vector < string > & subset , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const = 0 ;
//! Return true if the nodeID is a numerical constant equal to value and false otherwise
/*!
\ param [ in ] value of the numerical constante
\ param [ out ] the boolean equal to true if NodeId is a constant equal to value
*/
virtual bool isNumConstNodeEqualTo ( double value ) const = 0 ;
//! Returns the maximum number of nested diffs in the expression
virtual int countDiffs ( ) const = 0 ;
//! Return true if the nodeID is a variable withe a type equal to type_arg, a specific variable id aqual to varfiable_id and a lag equal to lag_arg and false otherwise
/*!
\ param [ in ] the type ( type_arg ) , specifique variable id ( variable_id and the lag ( lag_arg )
\ param [ out ] the boolean equal to true if NodeId is the variable
*/
virtual bool isVariableNodeEqualTo ( SymbolType type_arg , int variable_id , int lag_arg ) const = 0 ;
//! Replaces the Trend var with datatree.One
virtual expr_t replaceTrendVar ( ) const = 0 ;
//! Constructs a new expression where the variable indicated by symb_id has been detrended
/*!
\ param [ in ] symb_id indicating the variable to be detrended
\ param [ in ] log_trend indicates if the trend is in log
\ param [ in ] trend indicating the trend
\ return the new binary op pointing to a detrended variable
*/
virtual expr_t detrend ( int symb_id , bool log_trend , expr_t trend ) const = 0 ;
//! Substitute adl operator
virtual expr_t substituteAdl ( ) const = 0 ;
2020-11-10 18:04:05 +01:00
//! Substitute out model-local variables
virtual expr_t substituteModelLocalVariables ( ) const = 0 ;
2019-12-20 16:59:30 +01:00
//! Substitute VarExpectation nodes
virtual expr_t substituteVarExpectation ( const map < string , expr_t > & subst_table ) const = 0 ;
//! Mark diff nodes to be substituted
/*! The various nodes that are equivalent up to a shift of leads/lags are
grouped together in the “ nodes ” table . See the comment above
lag_equivalence_table_t for more details . */
virtual void findDiffNodes ( lag_equivalence_table_t & nodes ) const = 0 ;
//! Substitute diff operator
virtual expr_t substituteDiff ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const = 0 ;
//! Mark unary ops nodes to be substituted
/*! The various nodes that are equivalent up to a shift of leads/lags are
grouped together in the “ nodes ” table . See the comment above
lag_equivalence_table_t for more details . */
virtual void findUnaryOpNodesForAuxVarCreation ( lag_equivalence_table_t & nodes ) const = 0 ;
//! Substitute unary ops nodes
virtual expr_t substituteUnaryOpNodes ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const = 0 ;
//! Substitute pac_expectation operator
virtual expr_t substitutePacExpectation ( const string & name , expr_t subexpr ) = 0 ;
2021-10-26 18:06:26 +02:00
//! Substitute pac_target_nonstationary operator
virtual expr_t substitutePacTargetNonstationary ( const string & name , expr_t subexpr ) = 0 ;
2022-05-05 18:39:04 +02:00
virtual optional < int > findTargetVariable ( int lhs_symb_id ) const = 0 ;
2019-12-20 16:59:30 +01:00
//! Add ExprNodes to the provided datatree
2023-03-22 16:22:18 +01:00
virtual expr_t clone ( DataTree & alt_datatree ) const = 0 ;
2019-12-20 16:59:30 +01:00
//! Move a trend variable with lag/lead to time t by dividing/multiplying by its growth factor
virtual expr_t removeTrendLeadLag ( const map < int , expr_t > & trend_symbols_map ) const = 0 ;
//! Returns true if the expression is in static form (no lead, no lag, no expectation, no STEADY_STATE)
virtual bool isInStaticForm ( ) const = 0 ;
2021-10-26 18:06:26 +02:00
//! Matches a linear combination of variables (endo or exo), where scalars can be constant*parameter
2019-12-20 16:59:30 +01:00
/*! Returns a list of (variable_id, lag, param_id, constant)
corresponding to the terms in the expression . When there is no
2022-05-16 17:42:24 +02:00
parameter in a term , param_id is nullopt .
2019-12-20 16:59:30 +01:00
Can throw a MatchFailureException .
*/
2022-05-16 17:42:24 +02:00
vector < tuple < int , int , optional < int > , double > > matchLinearCombinationOfVariables ( ) const ;
/* Matches a linear combination of variables (endo or exo), where scalars can
be constant * parameter . In addition , there may be one or more scalar terms
( i . e . without a variable ) .
Returns a list of ( variable_id , lag , param_id , constant )
corresponding to the terms in the expression . When there is no
parameter in a term , param_id is nullopt . When the term is scalar ( i . e .
no variable ) , then variable_id is nullopt .
Can throw a MatchFailureException .
*/
vector < tuple < optional < int > , int , optional < int > , double > > matchLinearCombinationOfVariablesPlusConstant ( ) const ;
2019-12-20 16:59:30 +01:00
2022-01-28 17:24:48 +01:00
/* Matches a parameter, times a linear combination of variables (endo or
exo ) , where scalars can be constant * parameters .
The first output argument is the symbol ID of the parameter .
The second output argument is the linear combination , in the same format
as the output of matchLinearCombinationOfVariables ( ) . */
2022-05-16 17:42:24 +02:00
pair < int , vector < tuple < int , int , optional < int > , double > > > matchParamTimesLinearCombinationOfVariables ( ) const ;
2022-01-28 17:24:48 +01:00
2021-10-26 18:06:26 +02:00
/* Matches a linear combination of endogenous, where scalars can be any
constant expression ( i . e . containing no endogenous , no exogenous and no
exogenous deterministic ) . The linear combination can contain constant
terms ( intercept ) .
Returns a pair composed of :
– the terms of the form endogenous * scalar , as a list of ( endo_id , constant expr ) ;
– the sum of all constant ( intercept ) terms */
pair < vector < pair < int , expr_t > > , expr_t > matchLinearCombinationOfEndogenousWithConstant ( ) const ;
2020-07-23 14:45:32 +02:00
/* Matches an expression of the form parameter*(var1-endo2).
endo2 must correspond to symb_id . var1 must be an endogenous or an
2020-07-24 12:28:13 +02:00
exogenous ; it must be of the form X ( - 1 ) or log ( X ( - 1 ) ) or log ( X ) ( - 1 ) ( unary ops aux var ) ,
where X itself is * not * an aux var .
2020-07-23 14:45:32 +02:00
Returns the symbol IDs of the parameter and of var1 .
Throws a MatchFailureException otherwise */
pair < int , int > matchParamTimesTargetMinusVariable ( int symb_id ) const ;
2019-12-20 16:59:30 +01:00
//! Returns true if expression is of the form:
//! param * (endog op endog op ...) + param * (endog op endog op ...) + ...
virtual bool isParamTimesEndogExpr ( ) const = 0 ;
//! Fills the EC matrix structure
void fillErrorCorrectionRow ( int eqn , const vector < int > & nontarget_lhs , const vector < int > & target_lhs ,
2022-01-28 16:38:50 +01:00
map < tuple < int , int > , expr_t > & A0 ,
map < tuple < int , int > , expr_t > & A0star ) const ;
2019-12-20 16:59:30 +01:00
2020-09-29 17:58:41 +02:00
//! Replaces variables found in BinaryOpNode::findConstantEquations() with their constant values
2019-12-20 16:59:30 +01:00
virtual expr_t replaceVarsInEquation ( map < VariableNode * , NumConstNode * > & table ) const = 0 ;
//! Returns true if PacExpectationNode encountered
virtual bool containsPacExpectation ( const string & pac_model_name = " " ) const = 0 ;
2021-10-26 18:06:26 +02:00
//! Returns true if PacTargetNonstationaryNode encountered
virtual bool containsPacTargetNonstationary ( const string & pac_model_name = " " ) const = 0 ;
2019-12-20 16:59:30 +01:00
//! Decompose an expression into its additive terms
/*! Returns a list of terms, with their sign (either 1 or -1, depending
on whether the terms appears with a plus or a minus ) .
The current_sign argument should normally be left to 1.
If current_sign = = - 1 , then all signs are inverted */
virtual void decomposeAdditiveTerms ( vector < pair < expr_t , int > > & terms , int current_sign = 1 ) const ;
2020-10-19 18:26:36 +02:00
//! Decompose an expression into its multiplicative factors
/*! Returns a list of factors, with their exponents (either 1 or -1, depending
on whether the factors appear at the numerator or the denominator ) .
The current_exponent argument should normally be left to 1.
If current_exponent = = - 1 , then all exponents are inverted */
virtual void decomposeMultiplicativeFactors ( vector < pair < expr_t , int > > & factors , int current_exponent = 1 ) const ;
2019-12-20 16:59:30 +01:00
// Matches an expression of the form variable*constant*parameter
/* Returns a tuple (variable_id, lag, param_id, constant).
2022-05-16 17:42:24 +02:00
If ` variable_obligatory ` is true , then the expression must contain a variable .
If present , the variable must be an exogenous or an endogenous . If absent ,
and ` variable_obligatory ` is false , then variable_id is nullopt .
2019-12-20 16:59:30 +01:00
The constant is optional ( in which case 1 is returned ) ; there can be
several multiplicative constants ; constants can also appear at the
denominator ( i . e . after a divide sign ) .
2022-05-16 17:42:24 +02:00
The parameter is optional ( in which case param_id is nullopt ) .
2019-12-20 16:59:30 +01:00
If the expression is not of the expected form , throws a
MatchFailureException
*/
2022-05-16 17:42:24 +02:00
tuple < optional < int > , int , optional < int > , double > matchVariableTimesConstantTimesParam ( bool variable_obligatory ) const ;
2019-12-20 16:59:30 +01:00
2021-10-26 18:06:26 +02:00
/* Matches an expression of the form endogenous*constant where constant is an
expression containing no endogenous , no exogenous and no exogenous deterministic .
Returns ( endo_id , constant expr ) .
Note that it will also match a simple endogenous ( in which case the
constant will of course be equal to one ) . */
virtual pair < int , expr_t > matchEndogenousTimesConstant ( ) const ;
//! Exception thrown when matching fails
2022-07-20 13:22:21 +02:00
struct MatchFailureException
2019-12-20 16:59:30 +01:00
{
const string message ;
} ;
2020-07-28 18:29:45 +02:00
/* Match an expression of the form ∏ x(l)ᵏ, where x are endogenous, as used
in the match_moments block .
For each factor , adds an integer in the 3 vectors in argument ( symb_id in
the first , lag in the second , exponent in the third ) .
Throws a MatchFailureException if not of the right form . */
virtual void matchMatchedMoment ( vector < int > & symb_ids , vector < int > & lags , vector < int > & powers ) const ;
2021-07-07 10:54:04 +02:00
/* Returns true if the expression contains no endogenous, no exogenous and no
exogenous deterministic */
bool isConstant ( ) const ;
2021-07-20 12:10:58 +02:00
// Returns true if the expression contains an exogenous or an exogenous deterministic
bool hasExogenous ( ) const ;
2022-03-30 17:40:01 +02:00
// Substitutes orig_symb_id(±l) with exp(aux_symb_id(±l)) (used for “var(log)”)
virtual expr_t substituteLogTransform ( int orig_symb_id , int aux_symb_id ) const = 0 ;
2018-11-27 18:53:28 +01:00
} ;
2008-02-03 11:28:36 +01:00
//! Object used to compare two nodes (using their indexes)
2018-05-28 15:50:29 +02:00
/*! Note that in this ordering, a subexpression is always less than the
2019-12-20 16:59:30 +01:00
expression from which it is extracted . This property is used extensively in
the temporary terms computations . */
2008-02-03 11:28:36 +01:00
struct ExprNodeLess
{
2009-12-16 18:13:23 +01:00
bool
2010-09-16 19:18:45 +02:00
operator ( ) ( expr_t arg1 , expr_t arg2 ) const
2008-02-03 11:28:36 +01:00
{
return arg1 - > idx < arg2 - > idx ;
}
} ;
//! Numerical constant node
/*! The constant is necessarily non-negative (this is enforced at the NumericalConstants class level) */
class NumConstNode : public ExprNode
{
2018-11-28 14:32:26 +01:00
public :
2008-02-03 11:28:36 +01:00
//! Id from numerical constants table
const int id ;
2018-11-28 14:32:26 +01:00
private :
2018-06-04 12:53:26 +02:00
expr_t computeDerivative ( int deriv_id ) override ;
2023-04-05 14:16:22 +02:00
expr_t computeChainRuleDerivative ( int deriv_id , const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives , unordered_map < expr_t , map < int , expr_t > > & cache ) override ;
2018-11-28 14:18:08 +01:00
protected :
2023-03-02 16:08:32 +01:00
void prepareForDerivation ( ) override ;
2023-04-05 14:16:22 +02:00
void prepareForChainRuleDerivation ( const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives ) const override ;
2022-05-16 17:42:24 +02:00
void matchVTCTPHelper ( optional < int > & var_id , int & lag , optional < int > & param_id , double & constant , bool at_denominator ) const override ;
2022-10-18 17:24:51 +02:00
void computeSubExprContainingVariable ( int symb_id , int lag , set < expr_t > & contain_var ) const override ;
2008-02-03 11:28:36 +01:00
public :
2018-09-05 16:41:33 +02:00
NumConstNode ( DataTree & datatree_arg , int idx_arg , int id_arg ) ;
2018-06-04 12:53:26 +02:00
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 ;
2018-09-18 14:50:31 +02:00
void writeJsonAST ( ostream & output ) const override ;
2019-12-16 19:42:59 +01:00
void writeJsonOutput ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic ) const override ;
2018-06-04 12:53:26 +02:00
bool containsExternalFunction ( ) const override ;
void collectVARLHSVariable ( set < expr_t > & result ) const override ;
2018-06-04 14:17:36 +02:00
void collectDynamicVariables ( SymbolType type_arg , set < pair < int , int > > & result ) const override ;
2018-06-04 12:53:26 +02:00
double eval ( const eval_context_t & eval_context ) const noexcept ( false ) override ;
2022-07-06 16:44:51 +02:00
void writeBytecodeOutput ( BytecodeWriter & code_file , ExprNodeBytecodeOutputType 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 ;
2018-06-04 12:53:26 +02:00
expr_t toStatic ( DataTree & static_datatree ) const override ;
void computeXrefs ( EquationInfo & ei ) const override ;
2020-04-02 14:36:26 +02:00
BinaryOpNode * normalizeEquationHelper ( const set < expr_t > & contain_var , expr_t rhs ) const override ;
2018-06-04 12:53:26 +02:00
int maxEndoLead ( ) const override ;
int maxExoLead ( ) const override ;
int maxEndoLag ( ) const override ;
int maxExoLag ( ) const override ;
int maxLead ( ) const override ;
int maxLag ( ) const override ;
2018-12-05 15:17:00 +01:00
int maxLagWithDiffsExpanded ( ) const override ;
2019-10-22 16:04:24 +02:00
int VarMaxLag ( const set < expr_t > & lhs_lag_equiv ) const override ;
2018-06-04 12:53:26 +02:00
expr_t undiff ( ) const override ;
expr_t decreaseLeadsLags ( int n ) const override ;
expr_t substituteEndoLeadGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
expr_t substituteEndoLagGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteExoLead ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
expr_t substituteExoLag ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteExpectation ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool partial_information_model ) const override ;
expr_t substituteAdl ( ) const override ;
2020-11-10 18:04:05 +01:00
expr_t substituteModelLocalVariables ( ) const override ;
2018-08-01 19:41:44 +02:00
expr_t substituteVarExpectation ( const map < string , expr_t > & subst_table ) const override ;
2019-10-22 14:56:28 +02:00
void findDiffNodes ( lag_equivalence_table_t & nodes ) const override ;
void findUnaryOpNodesForAuxVarCreation ( lag_equivalence_table_t & nodes ) const override ;
2022-05-05 18:39:04 +02:00
optional < int > findTargetVariable ( int lhs_symb_id ) const override ;
2019-10-22 14:56:28 +02:00
expr_t substituteDiff ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteUnaryOpNodes ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
2019-12-20 16:59:30 +01:00
expr_t substitutePacExpectation ( const string & name , expr_t subexpr ) override ;
2021-10-26 18:06:26 +02:00
expr_t substitutePacTargetNonstationary ( const string & name , expr_t subexpr ) override ;
2018-06-04 12:53:26 +02:00
expr_t decreaseLeadsLagsPredeterminedVariables ( ) const override ;
expr_t differentiateForwardVars ( const vector < string > & subset , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
bool isNumConstNodeEqualTo ( double value ) const override ;
int countDiffs ( ) const override ;
bool isVariableNodeEqualTo ( SymbolType type_arg , int variable_id , int lag_arg ) const override ;
expr_t replaceTrendVar ( ) const override ;
expr_t detrend ( int symb_id , bool log_trend , expr_t trend ) const override ;
2023-03-22 16:22:18 +01:00
expr_t clone ( DataTree & alt_datatree ) const override ;
2019-07-05 18:22:02 +02:00
expr_t removeTrendLeadLag ( const map < int , expr_t > & trend_symbols_map ) const override ;
2018-06-04 12:53:26 +02:00
bool isInStaticForm ( ) const override ;
2019-01-29 17:29:24 +01:00
expr_t replaceVarsInEquation ( map < VariableNode * , NumConstNode * > & table ) const override ;
2018-08-09 16:14:40 +02:00
bool containsPacExpectation ( const string & pac_model_name = " " ) const override ;
2021-10-26 18:06:26 +02:00
bool containsPacTargetNonstationary ( const string & pac_model_name = " " ) const override ;
2018-08-09 16:14:40 +02:00
bool isParamTimesEndogExpr ( ) const override ;
2022-03-30 17:40:01 +02:00
expr_t substituteLogTransform ( int orig_symb_id , int aux_symb_id ) const override ;
2008-02-03 11:28:36 +01:00
} ;
//! Symbol or variable node
class VariableNode : public ExprNode
{
2011-01-13 18:08:26 +01:00
friend class UnaryOpNode ;
2018-11-28 14:32:26 +01:00
public :
2008-02-03 11:28:36 +01:00
//! Id from the symbol table
const int symb_id ;
2010-08-19 15:20:54 +02:00
//! A positive value is a lead, a negative is a lag
2008-02-03 11:28:36 +01:00
const int lag ;
2018-11-28 14:32:26 +01:00
private :
2018-06-04 12:53:26 +02:00
expr_t computeDerivative ( int deriv_id ) override ;
2023-04-05 14:16:22 +02:00
expr_t computeChainRuleDerivative ( int deriv_id , const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives , unordered_map < expr_t , map < int , expr_t > > & cache ) override ;
2018-11-28 14:18:08 +01:00
protected :
2023-03-02 16:08:32 +01:00
void prepareForDerivation ( ) override ;
2023-04-05 14:16:22 +02:00
void prepareForChainRuleDerivation ( const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives ) const override ;
2022-05-16 17:42:24 +02:00
void matchVTCTPHelper ( optional < int > & var_id , int & lag , optional < int > & param_id , double & constant , bool at_denominator ) const override ;
2022-10-18 17:24:51 +02:00
void computeSubExprContainingVariable ( int symb_id , int lag , set < expr_t > & contain_var ) const override ;
2008-02-03 11:28:36 +01:00
public :
2018-09-05 16:41:33 +02:00
VariableNode ( DataTree & datatree_arg , int idx_arg , int symb_id_arg , int lag_arg ) ;
2018-06-04 12:53:26 +02:00
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 ;
2018-09-18 14:50:31 +02:00
void writeJsonAST ( ostream & output ) const override ;
2019-12-16 19:42:59 +01:00
void writeJsonOutput ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic ) const override ;
2018-06-04 12:53:26 +02:00
bool containsExternalFunction ( ) const override ;
void collectVARLHSVariable ( set < expr_t > & result ) const override ;
2018-06-04 14:17:36 +02:00
void collectDynamicVariables ( SymbolType type_arg , set < pair < int , int > > & result ) const override ;
2018-06-04 12:53:26 +02:00
double eval ( const eval_context_t & eval_context ) const noexcept ( false ) override ;
2022-07-06 16:44:51 +02:00
void writeBytecodeOutput ( BytecodeWriter & code_file , ExprNodeBytecodeOutputType 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 ;
2018-06-04 12:53:26 +02:00
expr_t toStatic ( DataTree & static_datatree ) const override ;
void computeXrefs ( EquationInfo & ei ) const override ;
2018-10-09 17:50:04 +02:00
SymbolType get_type ( ) const ;
2020-04-02 14:36:26 +02:00
BinaryOpNode * normalizeEquationHelper ( const set < expr_t > & contain_var , expr_t rhs ) const override ;
2018-06-04 12:53:26 +02:00
int maxEndoLead ( ) const override ;
int maxExoLead ( ) const override ;
int maxEndoLag ( ) const override ;
int maxExoLag ( ) const override ;
int maxLead ( ) const override ;
int maxLag ( ) const override ;
2018-12-05 15:17:00 +01:00
int maxLagWithDiffsExpanded ( ) const override ;
2019-10-22 16:04:24 +02:00
int VarMaxLag ( const set < expr_t > & lhs_lag_equiv ) const override ;
2018-06-04 12:53:26 +02:00
expr_t undiff ( ) const override ;
expr_t decreaseLeadsLags ( int n ) const override ;
expr_t substituteEndoLeadGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
expr_t substituteEndoLagGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteExoLead ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
expr_t substituteExoLag ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteExpectation ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool partial_information_model ) const override ;
expr_t substituteAdl ( ) const override ;
2020-11-10 18:04:05 +01:00
expr_t substituteModelLocalVariables ( ) const override ;
2018-08-01 19:41:44 +02:00
expr_t substituteVarExpectation ( const map < string , expr_t > & subst_table ) const override ;
2019-10-22 14:56:28 +02:00
void findDiffNodes ( lag_equivalence_table_t & nodes ) const override ;
void findUnaryOpNodesForAuxVarCreation ( lag_equivalence_table_t & nodes ) const override ;
2022-05-05 18:39:04 +02:00
optional < int > findTargetVariable ( int lhs_symb_id ) const override ;
2019-10-22 14:56:28 +02:00
expr_t substituteDiff ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteUnaryOpNodes ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
2019-12-20 16:59:30 +01:00
expr_t substitutePacExpectation ( const string & name , expr_t subexpr ) override ;
2021-10-26 18:06:26 +02:00
expr_t substitutePacTargetNonstationary ( const string & name , expr_t subexpr ) override ;
2018-06-04 12:53:26 +02:00
expr_t decreaseLeadsLagsPredeterminedVariables ( ) const override ;
expr_t differentiateForwardVars ( const vector < string > & subset , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
bool isNumConstNodeEqualTo ( double value ) const override ;
int countDiffs ( ) const override ;
bool isVariableNodeEqualTo ( SymbolType type_arg , int variable_id , int lag_arg ) const override ;
expr_t replaceTrendVar ( ) const override ;
expr_t detrend ( int symb_id , bool log_trend , expr_t trend ) const override ;
2023-03-22 16:22:18 +01:00
expr_t clone ( DataTree & alt_datatree ) const override ;
2019-07-05 18:22:02 +02:00
expr_t removeTrendLeadLag ( const map < int , expr_t > & trend_symbols_map ) const override ;
2018-06-04 12:53:26 +02:00
bool isInStaticForm ( ) const override ;
2019-01-29 17:29:24 +01:00
expr_t replaceVarsInEquation ( map < VariableNode * , NumConstNode * > & table ) const override ;
2018-08-13 12:12:20 +02:00
bool containsPacExpectation ( const string & pac_model_name = " " ) const override ;
2021-10-26 18:06:26 +02:00
bool containsPacTargetNonstationary ( const string & pac_model_name = " " ) const override ;
2018-08-09 16:14:40 +02:00
bool isParamTimesEndogExpr ( ) const override ;
2020-07-28 18:29:45 +02:00
void matchMatchedMoment ( vector < int > & symb_ids , vector < int > & lags , vector < int > & powers ) const override ;
2021-10-26 18:06:26 +02:00
pair < int , expr_t > matchEndogenousTimesConstant ( ) const override ;
2022-03-30 17:40:01 +02:00
expr_t substituteLogTransform ( int orig_symb_id , int aux_symb_id ) const override ;
2008-02-03 11:28:36 +01:00
} ;
//! Unary operator node
class UnaryOpNode : public ExprNode
{
2018-11-28 14:18:08 +01:00
protected :
2023-03-02 16:08:32 +01:00
void prepareForDerivation ( ) override ;
2023-04-05 14:16:22 +02:00
void prepareForChainRuleDerivation ( const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives ) const override ;
2022-05-16 17:42:24 +02:00
void matchVTCTPHelper ( optional < int > & var_id , int & lag , optional < int > & param_id , double & constant , bool at_denominator ) const override ;
2022-10-18 17:24:51 +02:00
void computeSubExprContainingVariable ( int symb_id , int lag , set < expr_t > & contain_var ) const override ;
2023-03-23 12:38:44 +01:00
// Returns the node obtained by applying a transformation recursively on the argument (in same datatree)
template < typename Callable , typename . . . Args >
expr_t
recurseTransform ( Callable & & op , Args & & . . . args ) const
{
expr_t substarg { invoke ( forward < Callable > ( op ) , arg , forward < Args > ( args ) . . . ) } ;
return buildSimilarUnaryOpNode ( substarg , datatree ) ;
}
2018-11-28 14:32:26 +01:00
public :
2010-09-16 19:18:45 +02:00
const expr_t arg ;
2009-11-06 19:19:52 +01:00
//! Stores the information set. Only used for expectation operator
const int expectation_information_set ;
2018-07-18 16:18:26 +02:00
//! Only used for UnaryOpcode::steadyStateParamDeriv and UnaryOpcode::steadyStateParam2ndDeriv
2011-01-13 18:08:26 +01:00
const int param1_symb_id , param2_symb_id ;
2008-02-03 11:28:36 +01:00
const UnaryOpcode op_code ;
2017-07-03 16:38:44 +02:00
const string adl_param_name ;
2017-07-03 17:21:11 +02:00
const vector < int > adl_lags ;
2018-11-28 14:32:26 +01:00
private :
2018-06-04 12:53:26 +02:00
expr_t computeDerivative ( int deriv_id ) override ;
2023-04-05 14:16:22 +02:00
expr_t computeChainRuleDerivative ( int deriv_id , const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives , unordered_map < expr_t , map < int , expr_t > > & cache ) override ;
2018-06-04 12:53:26 +02:00
int cost ( int cost , bool is_matlab ) const override ;
2023-04-05 14:53:47 +02:00
int cost ( const vector < vector < unordered_set < expr_t > > > & blocks_temporary_terms , bool is_matlab ) const override ;
int cost ( const map < pair < int , int > , unordered_set < expr_t > > & temp_terms_map , bool is_matlab ) const override ;
2009-07-06 11:34:21 +02:00
//! Returns the derivative of this node if darg is the derivative of the argument
2011-01-13 18:08:26 +01:00
expr_t composeDerivatives ( expr_t darg , int deriv_id ) ;
2008-02-03 11:28:36 +01:00
public :
2018-09-05 16:41:33 +02:00
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 ) ;
2018-11-30 12:22:13 +01:00
void computeTemporaryTerms ( const pair < int , int > & derivOrder ,
2023-04-05 14:53:47 +02:00
map < pair < int , int > , unordered_set < expr_t > > & temp_terms_map ,
unordered_map < expr_t , pair < int , pair < int , int > > > & reference_count ,
2018-11-30 12:22:13 +01:00
bool is_matlab ) const override ;
2023-04-05 14:53:47 +02:00
void computeBlockTemporaryTerms ( int blk , int eq , vector < vector < unordered_set < expr_t > > > & blocks_temporary_terms ,
unordered_map < expr_t , tuple < int , int , int > > & reference_count ) const override ;
2018-06-04 12:53:26 +02:00
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 ;
2018-09-18 14:50:31 +02:00
void writeJsonAST ( ostream & output ) const override ;
2019-12-16 19:42:59 +01:00
void writeJsonOutput ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic ) const override ;
2018-06-04 12:53:26 +02:00
bool containsExternalFunction ( ) const override ;
void writeExternalFunctionOutput ( ostream & output , ExprNodeOutputType output_type ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
deriv_node_temp_terms_t & tef_terms ) const override ;
2018-06-04 12:53:26 +02:00
void writeJsonExternalFunctionOutput ( vector < string > & efout ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
deriv_node_temp_terms_t & tef_terms ,
bool isdynamic ) const override ;
2022-06-23 14:28:13 +02:00
void writeBytecodeExternalFunctionOutput ( BytecodeWriter & code_file ,
2022-07-06 16:44:51 +02:00
ExprNodeBytecodeOutputType output_type ,
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
deriv_node_temp_terms_t & tef_terms ) const override ;
2018-06-04 12:53:26 +02:00
void collectVARLHSVariable ( set < expr_t > & result ) const override ;
2018-06-04 14:17:36 +02:00
void collectDynamicVariables ( SymbolType type_arg , set < pair < int , int > > & result ) const override ;
2018-06-04 12:50:53 +02:00
static double eval_opcode ( UnaryOpcode op_code , double v ) noexcept ( false ) ;
2018-06-04 12:53:26 +02:00
double eval ( const eval_context_t & eval_context ) const noexcept ( false ) override ;
2022-07-06 16:44:51 +02:00
void writeBytecodeOutput ( BytecodeWriter & code_file , ExprNodeBytecodeOutputType 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 ;
2018-06-04 12:53:26 +02:00
expr_t toStatic ( DataTree & static_datatree ) const override ;
void computeXrefs ( EquationInfo & ei ) const override ;
2020-04-02 14:36:26 +02:00
BinaryOpNode * normalizeEquationHelper ( const set < expr_t > & contain_var , expr_t rhs ) const override ;
2018-06-04 12:53:26 +02:00
int maxEndoLead ( ) const override ;
int maxExoLead ( ) const override ;
int maxEndoLag ( ) const override ;
int maxExoLag ( ) const override ;
int maxLead ( ) const override ;
int maxLag ( ) const override ;
2018-12-05 15:17:00 +01:00
int maxLagWithDiffsExpanded ( ) const override ;
2019-10-22 16:04:24 +02:00
int VarMaxLag ( const set < expr_t > & lhs_lag_equiv ) const override ;
2018-06-04 12:53:26 +02:00
expr_t undiff ( ) const override ;
expr_t decreaseLeadsLags ( int n ) const override ;
expr_t substituteEndoLeadGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
2009-09-30 17:10:31 +02:00
//! Creates another UnaryOpNode with the same opcode, but with a possibly different datatree and argument
2010-09-16 19:18:45 +02:00
expr_t buildSimilarUnaryOpNode ( expr_t alt_arg , DataTree & alt_datatree ) const ;
2018-06-04 12:53:26 +02:00
expr_t substituteEndoLagGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteExoLead ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
expr_t substituteExoLag ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteExpectation ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool partial_information_model ) const override ;
expr_t substituteAdl ( ) const override ;
2020-11-10 18:04:05 +01:00
expr_t substituteModelLocalVariables ( ) const override ;
2018-08-01 19:41:44 +02:00
expr_t substituteVarExpectation ( const map < string , expr_t > & subst_table ) const override ;
2019-10-22 14:56:28 +02:00
void findDiffNodes ( lag_equivalence_table_t & nodes ) const override ;
2018-06-07 12:53:00 +02:00
bool createAuxVarForUnaryOpNode ( ) const ;
2019-10-22 14:56:28 +02:00
void findUnaryOpNodesForAuxVarCreation ( lag_equivalence_table_t & nodes ) const override ;
2022-05-05 18:39:04 +02:00
optional < int > findTargetVariable ( int lhs_symb_id ) const override ;
2019-10-22 14:56:28 +02:00
expr_t substituteDiff ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteUnaryOpNodes ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
2019-12-20 16:59:30 +01:00
expr_t substitutePacExpectation ( const string & name , expr_t subexpr ) override ;
2021-10-26 18:06:26 +02:00
expr_t substitutePacTargetNonstationary ( const string & name , expr_t subexpr ) override ;
2018-06-04 12:53:26 +02:00
expr_t decreaseLeadsLagsPredeterminedVariables ( ) const override ;
expr_t differentiateForwardVars ( const vector < string > & subset , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
bool isNumConstNodeEqualTo ( double value ) const override ;
int countDiffs ( ) const override ;
bool isVariableNodeEqualTo ( SymbolType type_arg , int variable_id , int lag_arg ) const override ;
expr_t replaceTrendVar ( ) const override ;
expr_t detrend ( int symb_id , bool log_trend , expr_t trend ) const override ;
2023-03-22 16:22:18 +01:00
expr_t clone ( DataTree & alt_datatree ) const override ;
2019-07-05 18:22:02 +02:00
expr_t removeTrendLeadLag ( const map < int , expr_t > & trend_symbols_map ) const override ;
2018-06-04 12:53:26 +02:00
bool isInStaticForm ( ) const override ;
2019-01-29 17:29:24 +01:00
expr_t replaceVarsInEquation ( map < VariableNode * , NumConstNode * > & table ) const override ;
2018-08-13 12:12:20 +02:00
bool containsPacExpectation ( const string & pac_model_name = " " ) const override ;
2021-10-26 18:06:26 +02:00
bool containsPacTargetNonstationary ( const string & pac_model_name = " " ) const override ;
2018-08-09 16:14:40 +02:00
bool isParamTimesEndogExpr ( ) const override ;
2018-11-27 18:53:28 +01:00
void decomposeAdditiveTerms ( vector < pair < expr_t , int > > & terms , int current_sign ) const override ;
2022-03-30 17:40:01 +02:00
expr_t substituteLogTransform ( int orig_symb_id , int aux_symb_id ) const override ;
2008-02-03 11:28:36 +01:00
} ;
//! Binary operator node
class BinaryOpNode : public ExprNode
{
2018-11-28 14:18:08 +01:00
protected :
2023-03-02 16:08:32 +01:00
void prepareForDerivation ( ) override ;
2023-04-05 14:16:22 +02:00
void prepareForChainRuleDerivation ( const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives ) const override ;
2022-05-16 17:42:24 +02:00
void matchVTCTPHelper ( optional < int > & var_id , int & lag , optional < int > & param_id , double & constant , bool at_denominator ) const override ;
2022-10-18 17:24:51 +02:00
void computeSubExprContainingVariable ( int symb_id , int lag , set < expr_t > & contain_var ) const override ;
2018-11-28 14:32:26 +01:00
public :
2010-09-16 19:18:45 +02:00
const expr_t arg1 , arg2 ;
2008-02-03 11:28:36 +01:00
const BinaryOpcode op_code ;
2018-11-28 14:32:26 +01:00
const int powerDerivOrder ;
const string adlparam ;
private :
2018-06-04 12:53:26 +02:00
expr_t computeDerivative ( int deriv_id ) override ;
2023-04-05 14:16:22 +02:00
expr_t computeChainRuleDerivative ( int deriv_id , const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives , unordered_map < expr_t , map < int , expr_t > > & cache ) override ;
2018-06-04 12:53:26 +02:00
int cost ( int cost , bool is_matlab ) const override ;
2023-04-05 14:53:47 +02:00
int cost ( const vector < vector < unordered_set < expr_t > > > & blocks_temporary_terms , bool is_matlab ) const override ;
int cost ( const map < pair < int , int > , unordered_set < expr_t > > & temp_terms_map , bool is_matlab ) const override ;
2009-07-06 11:34:21 +02:00
//! Returns the derivative of this node if darg1 and darg2 are the derivatives of the arguments
2010-09-16 19:18:45 +02:00
expr_t composeDerivatives ( expr_t darg1 , expr_t darg2 ) ;
2023-03-23 12:38:44 +01:00
// Returns the node obtained by applying a transformation recursively on the arguments (in same datatree)
template < typename Callable , typename . . . Args >
expr_t
recurseTransform ( Callable & & op , Args & & . . . args ) const
{
expr_t substarg1 { invoke ( forward < Callable > ( op ) , arg1 , forward < Args > ( args ) . . . ) } ;
expr_t substarg2 { invoke ( forward < Callable > ( op ) , arg2 , forward < Args > ( args ) . . . ) } ;
return buildSimilarBinaryOpNode ( substarg1 , substarg2 , datatree ) ;
}
2008-02-03 11:28:36 +01:00
public :
2018-09-05 16:41:33 +02:00
BinaryOpNode ( DataTree & datatree_arg , int idx_arg , const expr_t arg1_arg ,
2010-12-13 14:07:05 +01:00
BinaryOpcode op_code_arg , const expr_t arg2_arg , int powerDerivOrder ) ;
2018-06-04 12:53:26 +02:00
int precedenceJson ( const temporary_terms_t & temporary_terms ) const override ;
int precedence ( ExprNodeOutputType output_type , const temporary_terms_t & temporary_terms ) const override ;
2018-11-30 12:22:13 +01:00
void computeTemporaryTerms ( const pair < int , int > & derivOrder ,
2023-04-05 14:53:47 +02:00
map < pair < int , int > , unordered_set < expr_t > > & temp_terms_map ,
unordered_map < expr_t , pair < int , pair < int , int > > > & reference_count ,
2018-11-30 12:22:13 +01:00
bool is_matlab ) const override ;
2023-04-05 14:53:47 +02:00
void computeBlockTemporaryTerms ( int blk , int eq , vector < vector < unordered_set < expr_t > > > & blocks_temporary_terms ,
unordered_map < expr_t , tuple < int , int , int > > & reference_count ) const override ;
2018-06-04 12:53:26 +02:00
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 ;
2018-09-18 14:50:31 +02:00
void writeJsonAST ( ostream & output ) const override ;
2019-12-16 19:42:59 +01:00
void writeJsonOutput ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic ) const override ;
2018-06-04 12:53:26 +02:00
bool containsExternalFunction ( ) const override ;
void writeExternalFunctionOutput ( ostream & output , ExprNodeOutputType output_type ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
deriv_node_temp_terms_t & tef_terms ) const override ;
2018-06-04 12:53:26 +02:00
void writeJsonExternalFunctionOutput ( vector < string > & efout ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
deriv_node_temp_terms_t & tef_terms ,
bool isdynamic ) const override ;
2022-06-23 14:28:13 +02:00
void writeBytecodeExternalFunctionOutput ( BytecodeWriter & code_file ,
2022-07-06 16:44:51 +02:00
ExprNodeBytecodeOutputType output_type ,
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
2022-06-23 14:28:13 +02:00
deriv_node_temp_terms_t & tef_terms ) const override ;
2018-06-04 12:53:26 +02:00
void collectVARLHSVariable ( set < expr_t > & result ) const override ;
2018-06-04 14:17:36 +02:00
void collectDynamicVariables ( SymbolType type_arg , set < pair < int , int > > & result ) const override ;
2018-06-04 12:50:53 +02:00
static double eval_opcode ( double v1 , BinaryOpcode op_code , double v2 , int derivOrder ) noexcept ( false ) ;
2018-06-04 12:53:26 +02:00
double eval ( const eval_context_t & eval_context ) const noexcept ( false ) override ;
2022-07-06 16:44:51 +02:00
void writeBytecodeOutput ( BytecodeWriter & code_file , ExprNodeBytecodeOutputType 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 ;
2018-11-27 09:48:59 +01:00
expr_t Compute_RHS ( expr_t arg1 , expr_t arg2 , int op , int op_type ) const ;
2018-06-04 12:53:26 +02:00
expr_t toStatic ( DataTree & static_datatree ) const override ;
void computeXrefs ( EquationInfo & ei ) const override ;
2020-04-02 14:36:26 +02:00
BinaryOpNode * normalizeEquationHelper ( const set < expr_t > & contain_var , expr_t rhs ) const override ;
//! Try to normalize an equation with respect to a given dynamic variable.
/*! Should only be called on Equal nodes. The variable must appear in the equation. */
BinaryOpNode * normalizeEquation ( int symb_id , int lag ) const ;
2018-06-04 12:53:26 +02:00
int maxEndoLead ( ) const override ;
int maxExoLead ( ) const override ;
int maxEndoLag ( ) const override ;
int maxExoLag ( ) const override ;
int maxLead ( ) const override ;
int maxLag ( ) const override ;
2018-12-05 15:17:00 +01:00
int maxLagWithDiffsExpanded ( ) const override ;
2019-10-22 16:04:24 +02:00
int VarMaxLag ( const set < expr_t > & lhs_lag_equiv ) const override ;
2018-06-04 12:53:26 +02:00
expr_t undiff ( ) const override ;
expr_t decreaseLeadsLags ( int n ) const override ;
expr_t substituteEndoLeadGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
2009-09-30 17:10:31 +02:00
//! Creates another BinaryOpNode with the same opcode, but with a possibly different datatree and arguments
2010-09-16 19:18:45 +02:00
expr_t buildSimilarBinaryOpNode ( expr_t alt_arg1 , expr_t alt_arg2 , DataTree & alt_datatree ) const ;
2018-06-04 12:53:26 +02:00
expr_t substituteEndoLagGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteExoLead ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
expr_t substituteExoLag ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteExpectation ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool partial_information_model ) const override ;
expr_t substituteAdl ( ) const override ;
2020-11-10 18:04:05 +01:00
expr_t substituteModelLocalVariables ( ) const override ;
2018-08-01 19:41:44 +02:00
expr_t substituteVarExpectation ( const map < string , expr_t > & subst_table ) const override ;
2019-10-22 14:56:28 +02:00
void findDiffNodes ( lag_equivalence_table_t & nodes ) const override ;
void findUnaryOpNodesForAuxVarCreation ( lag_equivalence_table_t & nodes ) const override ;
2018-09-13 12:21:23 +02:00
bool findTargetVariableHelper1 ( int lhs_symb_id , int rhs_symb_id ) const ;
2022-05-05 18:39:04 +02:00
optional < int > findTargetVariableHelper ( const expr_t arg1 , const expr_t arg2 , int lhs_symb_id ) const ;
optional < int > findTargetVariable ( int lhs_symb_id ) const override ;
2019-10-22 14:56:28 +02:00
expr_t substituteDiff ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteUnaryOpNodes ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
2019-12-20 16:59:30 +01:00
expr_t substitutePacExpectation ( const string & name , expr_t subexpr ) override ;
2021-10-26 18:06:26 +02:00
expr_t substitutePacTargetNonstationary ( const string & name , expr_t subexpr ) override ;
2018-06-04 12:53:26 +02:00
expr_t decreaseLeadsLagsPredeterminedVariables ( ) const override ;
expr_t differentiateForwardVars ( const vector < string > & subset , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
bool isNumConstNodeEqualTo ( double value ) const override ;
int countDiffs ( ) const override ;
bool isVariableNodeEqualTo ( SymbolType type_arg , int variable_id , int lag_arg ) const override ;
expr_t replaceTrendVar ( ) const override ;
expr_t detrend ( int symb_id , bool log_trend , expr_t trend ) const override ;
2023-03-22 16:22:18 +01:00
expr_t clone ( DataTree & alt_datatree ) const override ;
2019-07-05 18:22:02 +02:00
expr_t removeTrendLeadLag ( const map < int , expr_t > & trend_symbols_map ) const override ;
2010-12-13 14:07:05 +01:00
//! Function to write out the oPowerNode in expr_t terms as opposed to writing out the function itself
expr_t unpackPowerDeriv ( ) const ;
2011-03-28 11:19:10 +02:00
//! Returns MULT_i*(lhs-rhs) = 0, creating multiplier MULT_i
2011-03-21 18:40:57 +01:00
expr_t addMultipliersToConstraints ( int i ) ;
//! Returns the non-zero hand-side of an equation (that must have a hand side equal to zero)
expr_t getNonZeroPartofEquation ( ) const ;
2018-06-04 12:53:26 +02:00
bool isInStaticForm ( ) const override ;
2019-03-15 12:27:32 +01:00
void fillAutoregressiveRow ( int eqn , const vector < int > & lhs , map < tuple < int , int , int > , expr_t > & AR ) const ;
2020-09-29 17:58:41 +02:00
//! Finds equations where a variable is equal to a constant
void findConstantEquations ( map < VariableNode * , NumConstNode * > & table ) const ;
2019-01-29 17:29:24 +01:00
expr_t replaceVarsInEquation ( map < VariableNode * , NumConstNode * > & table ) const override ;
2018-08-13 12:12:20 +02:00
bool containsPacExpectation ( const string & pac_model_name = " " ) const override ;
2021-10-26 18:06:26 +02:00
bool containsPacTargetNonstationary ( const string & pac_model_name = " " ) const override ;
2020-07-23 14:45:32 +02:00
/*
ec_params_and_vars :
- 1 st element = feedback force parameter
- 2 nd element = list of terms in the cointegration relationship ( symb_id ,
is target ? , multiplicative scalar ) ; this form theoretically allows for a
linear combination in the cointegration , though for the time being we allow
less than that
2020-09-11 16:45:19 +02:00
ar_params_and_vars : elements are indexed according to lag ( index 0 is lag
1 ) ; each tuple is ( parameter_id , variable_id , variable_lag ) where
variable_lag is * not * the lag order in the AR
( because variable is an AUX_DIFF_LAG )
2020-07-23 14:45:32 +02:00
*/
2019-03-05 10:57:15 +01:00
void getPacAREC ( int lhs_symb_id , int lhs_orig_symb_id ,
2019-03-07 11:31:36 +01:00
pair < int , vector < tuple < int , bool , int > > > & ec_params_and_vars ,
2022-05-16 17:42:24 +02:00
vector < tuple < optional < int > , optional < int > , int > > & ar_params_and_vars ,
vector < tuple < int , int , optional < int > , double > > & additive_vars_params_and_constants ) const ;
2019-02-27 23:12:05 +01:00
//! Finds the share of optimizing agents in the PAC equation,
//! the expr node associated with it,
//! and the expr node associated with the non-optimizing part
2022-06-24 15:45:35 +02:00
tuple < optional < int > , expr_t , expr_t , expr_t > getPacOptimizingShareAndExprNodes ( int lhs_orig_symb_id ) const ;
pair < optional < int > , expr_t > getPacOptimizingShareAndExprNodesHelper ( int lhs_orig_symb_id ) const ;
2020-10-19 18:26:36 +02:00
expr_t getPacNonOptimizingPart ( int optim_share_symb_id ) const ;
2018-08-09 16:14:40 +02:00
bool isParamTimesEndogExpr ( ) const override ;
2018-11-27 18:53:28 +01:00
void decomposeAdditiveTerms ( vector < pair < expr_t , int > > & terms , int current_sign ) const override ;
2020-10-19 18:26:36 +02:00
void decomposeMultiplicativeFactors ( vector < pair < expr_t , int > > & factors , int current_exponent = 1 ) const override ;
2020-07-28 18:29:45 +02:00
void matchMatchedMoment ( vector < int > & symb_ids , vector < int > & lags , vector < int > & powers ) const override ;
2021-10-26 18:06:26 +02:00
pair < int , expr_t > matchEndogenousTimesConstant ( ) const override ;
2022-03-30 17:40:01 +02:00
expr_t substituteLogTransform ( int orig_symb_id , int aux_symb_id ) const override ;
2008-02-03 11:28:36 +01:00
} ;
//! Trinary operator node
class TrinaryOpNode : public ExprNode
{
friend class ModelTree ;
2018-11-28 14:32:26 +01:00
public :
2010-09-16 19:18:45 +02:00
const expr_t arg1 , arg2 , arg3 ;
2008-02-03 11:28:36 +01:00
const TrinaryOpcode op_code ;
2022-10-18 17:24:51 +02:00
protected :
2023-03-02 16:08:32 +01:00
void prepareForDerivation ( ) override ;
2023-04-05 14:16:22 +02:00
void prepareForChainRuleDerivation ( const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives ) const override ;
2022-10-18 17:24:51 +02:00
void computeSubExprContainingVariable ( int symb_id , int lag , set < expr_t > & contain_var ) const override ;
2018-11-28 14:32:26 +01:00
private :
2018-06-04 12:53:26 +02:00
expr_t computeDerivative ( int deriv_id ) override ;
2023-04-05 14:16:22 +02:00
expr_t computeChainRuleDerivative ( int deriv_id , const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives , unordered_map < expr_t , map < int , expr_t > > & cache ) override ;
2018-06-04 12:53:26 +02:00
int cost ( int cost , bool is_matlab ) const override ;
2023-04-05 14:53:47 +02:00
int cost ( const vector < vector < unordered_set < expr_t > > > & blocks_temporary_terms , bool is_matlab ) const override ;
int cost ( const map < pair < int , int > , unordered_set < expr_t > > & temp_terms_map , bool is_matlab ) const override ;
2009-07-06 11:34:21 +02:00
//! Returns the derivative of this node if darg1, darg2 and darg3 are the derivatives of the arguments
2010-09-16 19:18:45 +02:00
expr_t composeDerivatives ( expr_t darg1 , expr_t darg2 , expr_t darg3 ) ;
2023-03-23 12:38:44 +01:00
// Returns the node obtained by applying a transformation recursively on the arguments (in same datatree)
template < typename Callable , typename . . . Args >
expr_t
recurseTransform ( Callable & & op , Args & & . . . args ) const
{
expr_t substarg1 { invoke ( forward < Callable > ( op ) , arg1 , forward < Args > ( args ) . . . ) } ;
expr_t substarg2 { invoke ( forward < Callable > ( op ) , arg2 , forward < Args > ( args ) . . . ) } ;
expr_t substarg3 { invoke ( forward < Callable > ( op ) , arg3 , forward < Args > ( args ) . . . ) } ;
return buildSimilarTrinaryOpNode ( substarg1 , substarg2 , substarg3 , datatree ) ;
}
2008-02-03 11:28:36 +01:00
public :
2018-09-05 16:41:33 +02:00
TrinaryOpNode ( DataTree & datatree_arg , int idx_arg , const expr_t arg1_arg ,
2010-09-16 19:18:45 +02:00
TrinaryOpcode op_code_arg , const expr_t arg2_arg , const expr_t arg3_arg ) ;
2018-06-04 12:53:26 +02:00
int precedence ( ExprNodeOutputType output_type , const temporary_terms_t & temporary_terms ) const override ;
2018-11-30 12:22:13 +01:00
void computeTemporaryTerms ( const pair < int , int > & derivOrder ,
2023-04-05 14:53:47 +02:00
map < pair < int , int > , unordered_set < expr_t > > & temp_terms_map ,
unordered_map < expr_t , pair < int , pair < int , int > > > & reference_count ,
2018-11-30 12:22:13 +01:00
bool is_matlab ) const override ;
2023-04-05 14:53:47 +02:00
void computeBlockTemporaryTerms ( int blk , int eq , vector < vector < unordered_set < expr_t > > > & blocks_temporary_terms ,
unordered_map < expr_t , tuple < int , int , int > > & reference_count ) const override ;
2018-06-04 12:53:26 +02:00
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 ;
2018-09-18 14:50:31 +02:00
void writeJsonAST ( ostream & output ) const override ;
2019-12-16 19:42:59 +01:00
void writeJsonOutput ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic ) const override ;
2018-06-04 12:53:26 +02:00
bool containsExternalFunction ( ) const override ;
void writeExternalFunctionOutput ( ostream & output , ExprNodeOutputType output_type ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
deriv_node_temp_terms_t & tef_terms ) const override ;
2018-06-04 12:53:26 +02:00
void writeJsonExternalFunctionOutput ( vector < string > & efout ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
deriv_node_temp_terms_t & tef_terms ,
bool isdynamic ) const override ;
2022-06-23 14:28:13 +02:00
void writeBytecodeExternalFunctionOutput ( BytecodeWriter & code_file ,
2022-07-06 16:44:51 +02:00
ExprNodeBytecodeOutputType output_type ,
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
2022-06-23 14:28:13 +02:00
deriv_node_temp_terms_t & tef_terms ) const override ;
2018-06-04 12:53:26 +02:00
void collectVARLHSVariable ( set < expr_t > & result ) const override ;
2018-06-04 14:17:36 +02:00
void collectDynamicVariables ( SymbolType type_arg , set < pair < int , int > > & result ) const override ;
2018-06-04 12:50:53 +02:00
static double eval_opcode ( double v1 , TrinaryOpcode op_code , double v2 , double v3 ) noexcept ( false ) ;
2018-06-04 12:53:26 +02:00
double eval ( const eval_context_t & eval_context ) const noexcept ( false ) override ;
2022-07-06 16:44:51 +02:00
void writeBytecodeOutput ( BytecodeWriter & code_file , ExprNodeBytecodeOutputType 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 ;
2018-06-04 12:53:26 +02:00
expr_t toStatic ( DataTree & static_datatree ) const override ;
void computeXrefs ( EquationInfo & ei ) const override ;
2020-04-02 14:36:26 +02:00
BinaryOpNode * normalizeEquationHelper ( const set < expr_t > & contain_var , expr_t rhs ) const override ;
2018-06-04 12:53:26 +02:00
int maxEndoLead ( ) const override ;
int maxExoLead ( ) const override ;
int maxEndoLag ( ) const override ;
int maxExoLag ( ) const override ;
int maxLead ( ) const override ;
int maxLag ( ) const override ;
2018-12-05 15:17:00 +01:00
int maxLagWithDiffsExpanded ( ) const override ;
2019-10-22 16:04:24 +02:00
int VarMaxLag ( const set < expr_t > & lhs_lag_equiv ) const override ;
2018-06-04 12:53:26 +02:00
expr_t undiff ( ) const override ;
expr_t decreaseLeadsLags ( int n ) const override ;
expr_t substituteEndoLeadGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
2009-09-30 17:10:31 +02:00
//! Creates another TrinaryOpNode with the same opcode, but with a possibly different datatree and arguments
2010-09-16 19:18:45 +02:00
expr_t buildSimilarTrinaryOpNode ( expr_t alt_arg1 , expr_t alt_arg2 , expr_t alt_arg3 , DataTree & alt_datatree ) const ;
2018-06-04 12:53:26 +02:00
expr_t substituteEndoLagGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteExoLead ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
expr_t substituteExoLag ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteExpectation ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool partial_information_model ) const override ;
expr_t substituteAdl ( ) const override ;
2020-11-10 18:04:05 +01:00
expr_t substituteModelLocalVariables ( ) const override ;
2018-08-01 19:41:44 +02:00
expr_t substituteVarExpectation ( const map < string , expr_t > & subst_table ) const override ;
2019-10-22 14:56:28 +02:00
void findDiffNodes ( lag_equivalence_table_t & nodes ) const override ;
void findUnaryOpNodesForAuxVarCreation ( lag_equivalence_table_t & nodes ) const override ;
2022-05-05 18:39:04 +02:00
optional < int > findTargetVariable ( int lhs_symb_id ) const override ;
2019-10-22 14:56:28 +02:00
expr_t substituteDiff ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteUnaryOpNodes ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
2019-12-20 16:59:30 +01:00
expr_t substitutePacExpectation ( const string & name , expr_t subexpr ) override ;
2021-10-26 18:06:26 +02:00
expr_t substitutePacTargetNonstationary ( const string & name , expr_t subexpr ) override ;
2018-06-04 12:53:26 +02:00
expr_t decreaseLeadsLagsPredeterminedVariables ( ) const override ;
expr_t differentiateForwardVars ( const vector < string > & subset , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
bool isNumConstNodeEqualTo ( double value ) const override ;
int countDiffs ( ) const override ;
bool isVariableNodeEqualTo ( SymbolType type_arg , int variable_id , int lag_arg ) const override ;
expr_t replaceTrendVar ( ) const override ;
expr_t detrend ( int symb_id , bool log_trend , expr_t trend ) const override ;
2023-03-22 16:22:18 +01:00
expr_t clone ( DataTree & alt_datatree ) const override ;
2019-07-05 18:22:02 +02:00
expr_t removeTrendLeadLag ( const map < int , expr_t > & trend_symbols_map ) const override ;
2018-06-04 12:53:26 +02:00
bool isInStaticForm ( ) const override ;
2019-01-29 17:29:24 +01:00
expr_t replaceVarsInEquation ( map < VariableNode * , NumConstNode * > & table ) const override ;
2018-08-13 12:12:20 +02:00
bool containsPacExpectation ( const string & pac_model_name = " " ) const override ;
2021-10-26 18:06:26 +02:00
bool containsPacTargetNonstationary ( const string & pac_model_name = " " ) const override ;
2018-08-09 16:14:40 +02:00
bool isParamTimesEndogExpr ( ) const override ;
2022-03-30 17:40:01 +02:00
expr_t substituteLogTransform ( int orig_symb_id , int aux_symb_id ) const override ;
2008-02-03 11:28:36 +01:00
} ;
2010-02-22 17:33:38 +01:00
//! External function node
2014-03-13 11:22:00 +01:00
class AbstractExternalFunctionNode : public ExprNode
2008-02-03 11:28:36 +01:00
{
2018-11-28 14:32:26 +01:00
public :
const int symb_id ;
const vector < expr_t > arguments ;
2008-02-03 11:28:36 +01:00
private :
2018-06-04 12:53:26 +02:00
expr_t computeDerivative ( int deriv_id ) override ;
2023-04-05 14:16:22 +02:00
expr_t computeChainRuleDerivative ( int deriv_id , const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives , unordered_map < expr_t , map < int , expr_t > > & cache ) override ;
2014-03-13 11:22:00 +01:00
virtual expr_t composeDerivatives ( const vector < expr_t > & dargs ) = 0 ;
2023-02-28 15:33:24 +01:00
// Computes the maximum of f applied to all arguments (result will always be non-negative)
int maxHelper ( const function < int ( expr_t ) > & f ) const ;
2023-03-23 12:38:44 +01:00
// Returns the node obtained by applying a transformation recursively on the arguments (in same datatree)
template < typename Callable , typename . . . Args >
expr_t
recurseTransform ( Callable & & op , Args & & . . . args ) const
{
vector < expr_t > arguments_subst ;
for ( auto argument : arguments )
arguments_subst . push_back ( invoke ( forward < Callable > ( op ) , argument , forward < Args > ( args ) . . . ) ) ;
return buildSimilarExternalFunctionNode ( arguments_subst , datatree ) ;
}
2010-02-22 17:33:38 +01:00
protected :
2010-03-04 16:40:07 +01:00
//! Thrown when trying to access an unknown entry in external_function_node_map
class UnknownFunctionNameAndArgs
{
} ;
2023-03-02 16:08:32 +01:00
void prepareForDerivation ( ) override ;
2023-04-05 14:16:22 +02:00
void prepareForChainRuleDerivation ( const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives ) const override ;
2010-03-04 16:40:07 +01:00
//! Returns true if the given external function has been written as a temporary term
2018-05-29 11:59:42 +02:00
bool alreadyWrittenAsTefTerm ( int the_symb_id , const deriv_node_temp_terms_t & tef_terms ) const ;
2010-03-04 16:40:07 +01:00
//! Returns the index in the tef_terms map of this external function
2018-06-04 12:50:53 +02:00
int getIndxInTefTerms ( int the_symb_id , const deriv_node_temp_terms_t & tef_terms ) const noexcept ( false ) ;
2010-03-04 16:40:07 +01:00
//! Helper function to write output arguments of any given external function
2018-05-29 11:59:42 +02:00
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 ;
2018-09-18 14:50:31 +02:00
void writeJsonASTExternalFunctionArguments ( ostream & output ) const ;
2019-12-16 19:42:59 +01:00
void writeJsonExternalFunctionArguments ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic ) const ;
2022-07-08 16:00:02 +02:00
void writeBytecodeExternalFunctionArguments ( BytecodeWriter & code_file ,
ExprNodeBytecodeOutputType 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 ;
2018-05-29 17:07:18 +02:00
/*! Returns a predicate that tests whether an other ExprNode is an external
function which is computed by the same external function call ( i . e . it has
the same so - called " Tef " index ) */
virtual function < bool ( expr_t ) > sameTefTermPredicate ( ) const = 0 ;
2022-10-18 17:24:51 +02:00
void computeSubExprContainingVariable ( int symb_id , int lag , set < expr_t > & contain_var ) const override ;
2008-02-03 11:28:36 +01:00
public :
2018-09-05 16:41:33 +02:00
AbstractExternalFunctionNode ( DataTree & datatree_arg , int idx_arg , int symb_id_arg ,
2018-06-04 12:31:07 +02:00
vector < expr_t > arguments_arg ) ;
2018-11-30 12:22:13 +01:00
void computeTemporaryTerms ( const pair < int , int > & derivOrder ,
2023-04-05 14:53:47 +02:00
map < pair < int , int > , unordered_set < expr_t > > & temp_terms_map ,
unordered_map < expr_t , pair < int , pair < int , int > > > & reference_count ,
2018-11-30 12:22:13 +01:00
bool is_matlab ) const override ;
2023-04-05 14:53:47 +02:00
void computeBlockTemporaryTerms ( int blk , int eq , vector < vector < unordered_set < expr_t > > > & blocks_temporary_terms ,
unordered_map < expr_t , tuple < int , int , int > > & reference_count ) const override ;
2018-06-04 12:53:26 +02:00
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 ;
2018-09-18 14:50:31 +02:00
void writeJsonAST ( ostream & output ) const override = 0 ;
2019-12-16 19:42:59 +01:00
void writeJsonOutput ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic = true ) const override = 0 ;
2018-06-04 12:53:26 +02:00
bool containsExternalFunction ( ) const override ;
void writeExternalFunctionOutput ( ostream & output , ExprNodeOutputType output_type ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
deriv_node_temp_terms_t & tef_terms ) const override = 0 ;
2018-06-04 12:53:26 +02:00
void writeJsonExternalFunctionOutput ( vector < string > & efout ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
deriv_node_temp_terms_t & tef_terms ,
bool isdynamic = true ) const override = 0 ;
2022-06-23 14:28:13 +02:00
void writeBytecodeExternalFunctionOutput ( BytecodeWriter & code_file ,
2022-07-06 16:44:51 +02:00
ExprNodeBytecodeOutputType output_type ,
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
2022-06-23 14:28:13 +02:00
deriv_node_temp_terms_t & tef_terms ) const override = 0 ;
2018-06-04 12:53:26 +02:00
void collectVARLHSVariable ( set < expr_t > & result ) const override ;
2018-06-04 14:17:36 +02:00
void collectDynamicVariables ( SymbolType type_arg , set < pair < int , int > > & result ) const override ;
2018-06-04 12:53:26 +02:00
double eval ( const eval_context_t & eval_context ) const noexcept ( false ) override ;
2022-07-06 16:44:51 +02:00
void writeBytecodeOutput ( BytecodeWriter & code_file , ExprNodeBytecodeOutputType 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 ;
2023-03-22 16:04:38 +01:00
expr_t toStatic ( DataTree & static_datatree ) const override ;
2018-06-04 12:53:26 +02:00
void computeXrefs ( EquationInfo & ei ) const override = 0 ;
2020-04-02 14:36:26 +02:00
BinaryOpNode * normalizeEquationHelper ( const set < expr_t > & contain_var , expr_t rhs ) const override ;
2018-06-04 12:53:26 +02:00
int maxEndoLead ( ) const override ;
int maxExoLead ( ) const override ;
int maxEndoLag ( ) const override ;
int maxExoLag ( ) const override ;
int maxLead ( ) const override ;
int maxLag ( ) const override ;
2018-12-05 15:17:00 +01:00
int maxLagWithDiffsExpanded ( ) const override ;
2019-10-22 16:04:24 +02:00
int VarMaxLag ( const set < expr_t > & lhs_lag_equiv ) const override ;
2018-06-04 12:53:26 +02:00
expr_t undiff ( ) const override ;
expr_t decreaseLeadsLags ( int n ) const override ;
expr_t substituteEndoLeadGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
expr_t substituteEndoLagGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteExoLead ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
expr_t substituteExoLag ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteExpectation ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool partial_information_model ) const override ;
expr_t substituteAdl ( ) const override ;
2020-11-10 18:04:05 +01:00
expr_t substituteModelLocalVariables ( ) const override ;
2018-08-01 19:41:44 +02:00
expr_t substituteVarExpectation ( const map < string , expr_t > & subst_table ) const override ;
2019-10-22 14:56:28 +02:00
void findDiffNodes ( lag_equivalence_table_t & nodes ) const override ;
void findUnaryOpNodesForAuxVarCreation ( lag_equivalence_table_t & nodes ) const override ;
2022-05-05 18:39:04 +02:00
optional < int > findTargetVariable ( int lhs_symb_id ) const override ;
2019-10-22 14:56:28 +02:00
expr_t substituteDiff ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteUnaryOpNodes ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
2019-12-20 16:59:30 +01:00
expr_t substitutePacExpectation ( const string & name , expr_t subexpr ) override ;
2021-10-26 18:06:26 +02:00
expr_t substitutePacTargetNonstationary ( const string & name , expr_t subexpr ) override ;
2014-03-13 11:22:00 +01:00
virtual expr_t buildSimilarExternalFunctionNode ( vector < expr_t > & alt_args , DataTree & alt_datatree ) const = 0 ;
2018-06-04 12:53:26 +02:00
expr_t decreaseLeadsLagsPredeterminedVariables ( ) const override ;
expr_t differentiateForwardVars ( const vector < string > & subset , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
bool isNumConstNodeEqualTo ( double value ) const override ;
int countDiffs ( ) const override ;
bool isVariableNodeEqualTo ( SymbolType type_arg , int variable_id , int lag_arg ) const override ;
2020-05-05 20:55:09 +02:00
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 ;
2018-06-04 12:53:26 +02:00
expr_t replaceTrendVar ( ) const override ;
expr_t detrend ( int symb_id , bool log_trend , expr_t trend ) const override ;
2023-03-22 16:22:18 +01:00
expr_t clone ( DataTree & alt_datatree ) const override ;
2019-07-05 18:22:02 +02:00
expr_t removeTrendLeadLag ( const map < int , expr_t > & trend_symbols_map ) const override ;
2018-06-04 12:53:26 +02:00
bool isInStaticForm ( ) const override ;
2019-01-29 17:29:24 +01:00
expr_t replaceVarsInEquation ( map < VariableNode * , NumConstNode * > & table ) const override ;
2018-08-13 12:12:20 +02:00
bool containsPacExpectation ( const string & pac_model_name = " " ) const override ;
2021-10-26 18:06:26 +02:00
bool containsPacTargetNonstationary ( const string & pac_model_name = " " ) const override ;
2018-08-09 16:14:40 +02:00
bool isParamTimesEndogExpr ( ) const override ;
2022-03-30 17:40:01 +02:00
expr_t substituteLogTransform ( int orig_symb_id , int aux_symb_id ) const override ;
2008-02-03 11:28:36 +01:00
} ;
2014-03-13 11:22:00 +01:00
class ExternalFunctionNode : public AbstractExternalFunctionNode
{
2018-05-29 17:07:18 +02:00
friend class FirstDerivExternalFunctionNode ;
friend class SecondDerivExternalFunctionNode ;
2014-03-13 11:22:00 +01:00
private :
2018-06-04 12:53:26 +02:00
expr_t composeDerivatives ( const vector < expr_t > & dargs ) override ;
2018-05-29 17:07:18 +02:00
protected :
function < bool ( expr_t ) > sameTefTermPredicate ( ) const override ;
2014-03-13 11:22:00 +01:00
public :
2018-09-05 16:41:33 +02:00
ExternalFunctionNode ( DataTree & datatree_arg , int idx_arg , int symb_id_arg ,
2014-03-13 11:22:00 +01:00
const vector < expr_t > & arguments_arg ) ;
2018-06-04 12:53:26 +02:00
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 ;
2018-09-18 14:50:31 +02:00
void writeJsonAST ( ostream & output ) const override ;
2019-12-16 19:42:59 +01:00
void writeJsonOutput ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic ) const override ;
2018-06-04 12:53:26 +02:00
void writeExternalFunctionOutput ( ostream & output , ExprNodeOutputType output_type ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
deriv_node_temp_terms_t & tef_terms ) const override ;
2018-06-04 12:53:26 +02:00
void writeJsonExternalFunctionOutput ( vector < string > & efout ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
deriv_node_temp_terms_t & tef_terms ,
bool isdynamic ) const override ;
2022-06-23 14:28:13 +02:00
void writeBytecodeExternalFunctionOutput ( BytecodeWriter & code_file ,
2022-07-06 16:44:51 +02:00
ExprNodeBytecodeOutputType output_type ,
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
2022-06-23 14:28:13 +02:00
deriv_node_temp_terms_t & tef_terms ) const override ;
2022-07-06 16:44:51 +02:00
void writeBytecodeOutput ( BytecodeWriter & code_file , ExprNodeBytecodeOutputType 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 ;
2018-06-04 12:53:26 +02:00
void computeXrefs ( EquationInfo & ei ) const override ;
expr_t buildSimilarExternalFunctionNode ( vector < expr_t > & alt_args , DataTree & alt_datatree ) const override ;
2014-03-13 11:22:00 +01:00
} ;
class FirstDerivExternalFunctionNode : public AbstractExternalFunctionNode
2010-02-22 17:33:38 +01:00
{
2018-11-28 14:32:26 +01:00
public :
2010-02-22 17:33:38 +01:00
const int inputIndex ;
2018-11-28 14:32:26 +01:00
private :
2018-06-04 12:53:26 +02:00
expr_t composeDerivatives ( const vector < expr_t > & dargs ) override ;
2018-05-29 17:07:18 +02:00
protected :
function < bool ( expr_t ) > sameTefTermPredicate ( ) const override ;
2010-02-22 17:33:38 +01:00
public :
2018-09-05 16:41:33 +02:00
FirstDerivExternalFunctionNode ( DataTree & datatree_arg , int idx_arg ,
2010-02-22 17:33:38 +01:00
int top_level_symb_id_arg ,
2010-09-16 19:18:45 +02:00
const vector < expr_t > & arguments_arg ,
2010-02-22 17:33:38 +01:00
int inputIndex_arg ) ;
2018-06-04 12:53:26 +02:00
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 ;
2018-09-18 14:50:31 +02:00
void writeJsonAST ( ostream & output ) const override ;
2019-12-16 19:42:59 +01:00
void writeJsonOutput ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic ) const override ;
2022-07-06 16:44:51 +02:00
void writeBytecodeOutput ( BytecodeWriter & code_file , ExprNodeBytecodeOutputType output_type ,
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
2022-06-23 14:28:13 +02:00
const deriv_node_temp_terms_t & tef_terms ) const override ;
2018-06-04 12:53:26 +02:00
void writeExternalFunctionOutput ( ostream & output , ExprNodeOutputType output_type ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
deriv_node_temp_terms_t & tef_terms ) const override ;
2018-06-04 12:53:26 +02:00
void writeJsonExternalFunctionOutput ( vector < string > & efout ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
deriv_node_temp_terms_t & tef_terms ,
bool isdynamic ) const override ;
2022-06-23 14:28:13 +02:00
void writeBytecodeExternalFunctionOutput ( BytecodeWriter & code_file ,
2022-07-06 16:44:51 +02:00
ExprNodeBytecodeOutputType output_type ,
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
2022-06-23 14:28:13 +02:00
deriv_node_temp_terms_t & tef_terms ) const override ;
2018-06-04 12:53:26 +02:00
void computeXrefs ( EquationInfo & ei ) const override ;
expr_t buildSimilarExternalFunctionNode ( vector < expr_t > & alt_args , DataTree & alt_datatree ) const override ;
2010-02-22 17:33:38 +01:00
} ;
2014-03-13 11:22:00 +01:00
class SecondDerivExternalFunctionNode : public AbstractExternalFunctionNode
2010-02-22 17:33:38 +01:00
{
2018-11-28 14:32:26 +01:00
public :
2010-02-22 17:33:38 +01:00
const int inputIndex1 ;
const int inputIndex2 ;
2018-11-28 14:32:26 +01:00
private :
2018-06-04 12:53:26 +02:00
expr_t composeDerivatives ( const vector < expr_t > & dargs ) override ;
2018-05-29 17:07:18 +02:00
protected :
function < bool ( expr_t ) > sameTefTermPredicate ( ) const override ;
2010-02-22 17:33:38 +01:00
public :
2018-09-05 16:41:33 +02:00
SecondDerivExternalFunctionNode ( DataTree & datatree_arg , int idx_arg ,
2010-02-22 17:33:38 +01:00
int top_level_symb_id_arg ,
2010-09-16 19:18:45 +02:00
const vector < expr_t > & arguments_arg ,
2010-02-22 17:33:38 +01:00
int inputIndex1_arg ,
int inputIndex2_arg ) ;
2018-06-04 12:53:26 +02:00
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 ;
2018-09-18 14:50:31 +02:00
void writeJsonAST ( ostream & output ) const override ;
2019-12-16 19:42:59 +01:00
void writeJsonOutput ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic ) const override ;
2022-07-06 16:44:51 +02:00
void writeBytecodeOutput ( BytecodeWriter & code_file , ExprNodeBytecodeOutputType output_type ,
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
2022-06-23 14:28:13 +02:00
const deriv_node_temp_terms_t & tef_terms ) const override ;
2018-06-04 12:53:26 +02:00
void writeExternalFunctionOutput ( ostream & output , ExprNodeOutputType output_type ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
deriv_node_temp_terms_t & tef_terms ) const override ;
2018-06-04 12:53:26 +02:00
void writeJsonExternalFunctionOutput ( vector < string > & efout ,
2019-12-20 16:59:30 +01:00
const temporary_terms_t & temporary_terms ,
deriv_node_temp_terms_t & tef_terms ,
bool isdynamic ) const override ;
2022-06-23 14:28:13 +02:00
void writeBytecodeExternalFunctionOutput ( BytecodeWriter & code_file ,
2022-07-06 16:44:51 +02:00
ExprNodeBytecodeOutputType output_type ,
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
2022-06-23 14:28:13 +02:00
deriv_node_temp_terms_t & tef_terms ) const override ;
2018-06-04 12:53:26 +02:00
void computeXrefs ( EquationInfo & ei ) const override ;
expr_t buildSimilarExternalFunctionNode ( vector < expr_t > & alt_args , DataTree & alt_datatree ) const override ;
2010-02-22 17:33:38 +01:00
} ;
2021-10-29 12:15:50 +02:00
/* Common superclass for nodes that have the following two characteristics:
– they take a submodel name as an argument
– they will be substituted out in the middle of the transform pass
*/
class SubModelNode : public ExprNode
2016-11-18 16:52:13 +01:00
{
public :
2018-11-28 14:32:26 +01:00
const string model_name ;
2021-10-29 12:15:50 +02:00
SubModelNode ( DataTree & datatree_arg , int idx_arg , string model_name_arg ) ;
2021-10-29 12:55:17 +02:00
void computeTemporaryTerms ( const pair < int , int > & derivOrder ,
2023-04-05 14:53:47 +02:00
map < pair < int , int > , unordered_set < expr_t > > & temp_terms_map ,
unordered_map < expr_t , pair < int , pair < int , int > > > & reference_count ,
2021-10-29 12:55:17 +02:00
bool is_matlab ) const override ;
2023-04-05 14:53:47 +02:00
void computeBlockTemporaryTerms ( int blk , int eq , vector < vector < unordered_set < expr_t > > > & blocks_temporary_terms ,
unordered_map < expr_t , tuple < int , int , int > > & reference_count ) const override ;
2021-10-29 12:15:50 +02:00
expr_t toStatic ( DataTree & static_datatree ) const override ;
expr_t computeDerivative ( int deriv_id ) override ;
2021-10-29 12:55:17 +02:00
int maxEndoLead ( ) const override ;
int maxExoLead ( ) const override ;
int maxEndoLag ( ) const override ;
int maxExoLag ( ) const override ;
int maxLead ( ) const override ;
int maxLag ( ) const override ;
int VarMaxLag ( const set < expr_t > & lhs_lag_equiv ) const override ;
expr_t undiff ( ) const override ;
expr_t decreaseLeadsLags ( int n ) const override ;
int countDiffs ( ) const override ;
expr_t substituteEndoLeadGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
expr_t substituteEndoLagGreaterThanTwo ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteExoLead ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool deterministic_model ) const override ;
expr_t substituteExoLag ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
2021-10-29 12:15:50 +02:00
bool containsExternalFunction ( ) const override ;
double eval ( const eval_context_t & eval_context ) const noexcept ( false ) override ;
void computeXrefs ( EquationInfo & ei ) const override ;
expr_t substituteExpectation ( subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs , bool partial_information_model ) const override ;
expr_t substituteAdl ( ) const override ;
expr_t substituteModelLocalVariables ( ) const override ;
void findDiffNodes ( lag_equivalence_table_t & nodes ) const override ;
void findUnaryOpNodesForAuxVarCreation ( lag_equivalence_table_t & nodes ) const override ;
2022-05-05 18:39:04 +02:00
optional < int > findTargetVariable ( int lhs_symb_id ) const override ;
2021-10-29 12:15:50 +02:00
expr_t substituteDiff ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t substituteUnaryOpNodes ( const lag_equivalence_table_t & nodes , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
BinaryOpNode * normalizeEquationHelper ( const set < expr_t > & contain_var , expr_t rhs ) const override ;
2022-07-06 16:44:51 +02:00
void writeBytecodeOutput ( BytecodeWriter & code_file , ExprNodeBytecodeOutputType output_type ,
const temporary_terms_t & temporary_terms ,
const temporary_terms_idxs_t & temporary_terms_idxs ,
2022-06-23 14:28:13 +02:00
const deriv_node_temp_terms_t & tef_terms ) const override ;
2021-10-29 12:15:50 +02:00
void collectVARLHSVariable ( set < expr_t > & result ) const override ;
void collectDynamicVariables ( SymbolType type_arg , set < pair < int , int > > & result ) const override ;
bool isNumConstNodeEqualTo ( double value ) const override ;
bool isVariableNodeEqualTo ( SymbolType type_arg , int variable_id , int lag_arg ) const override ;
bool isInStaticForm ( ) const override ;
expr_t replaceVarsInEquation ( map < VariableNode * , NumConstNode * > & table ) const override ;
bool isParamTimesEndogExpr ( ) const override ;
2021-10-29 12:55:17 +02:00
expr_t differentiateForwardVars ( const vector < string > & subset , subst_table_t & subst_table , vector < BinaryOpNode * > & neweqs ) const override ;
expr_t decreaseLeadsLagsPredeterminedVariables ( ) const override ;
expr_t replaceTrendVar ( ) const override ;
expr_t detrend ( int symb_id , bool log_trend , expr_t trend ) const override ;
expr_t removeTrendLeadLag ( const map < int , expr_t > & trend_symbols_map ) const override ;
2022-03-30 17:40:01 +02:00
expr_t substituteLogTransform ( int orig_symb_id , int aux_symb_id ) const override ;
2022-10-18 17:24:51 +02:00
protected :
2023-03-02 16:08:32 +01:00
void prepareForDerivation ( ) override ;
2023-04-05 14:16:22 +02:00
void prepareForChainRuleDerivation ( const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives ) const override ;
2022-10-18 17:24:51 +02:00
void computeSubExprContainingVariable ( int symb_id , int lag , set < expr_t > & contain_var ) const override ;
2022-11-08 12:28:48 +01:00
private :
2023-04-05 14:16:22 +02:00
expr_t computeChainRuleDerivative ( int deriv_id , const map < int , BinaryOpNode * > & recursive_variables , unordered_map < expr_t , set < int > > & non_null_chain_rule_derivatives , unordered_map < expr_t , map < int , expr_t > > & cache ) override ;
2021-10-29 12:15:50 +02:00
} ;
class VarExpectationNode : public SubModelNode
{
public :
2018-09-05 16:41:33 +02:00
VarExpectationNode ( DataTree & datatree_arg , int idx_arg , string model_name_arg ) ;
2018-06-04 12:53:26 +02:00
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 ;
2023-03-22 16:22:18 +01:00
expr_t clone ( DataTree & alt_datatree ) const override ;
2018-12-05 15:17:00 +01:00
int maxLagWithDiffsExpanded ( ) const override ;
2018-08-01 19:41:44 +02:00
expr_t substituteVarExpectation ( const map < string , expr_t > & subst_table ) const override ;
2019-12-20 16:59:30 +01:00
expr_t substitutePacExpectation ( const string & name , expr_t subexpr ) override ;
2021-10-26 18:06:26 +02:00
expr_t substitutePacTargetNonstationary ( const string & name , expr_t subexpr ) override ;
2018-08-13 12:12:20 +02:00
bool containsPacExpectation ( const string & pac_model_name = " " ) const override ;
2021-10-26 18:06:26 +02:00
bool containsPacTargetNonstationary ( const string & pac_model_name = " " ) const override ;
2018-09-18 14:50:31 +02:00
void writeJsonAST ( ostream & output ) const override ;
2019-12-16 19:42:59 +01:00
void writeJsonOutput ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic ) const override ;
2018-01-30 16:33:16 +01:00
} ;
2021-10-29 12:15:50 +02:00
class PacExpectationNode : public SubModelNode
2018-01-30 16:33:16 +01:00
{
public :
2018-09-05 16:41:33 +02:00
PacExpectationNode ( DataTree & datatree_arg , int idx_arg , string model_name ) ;
2018-06-04 12:53:26 +02:00
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 ;
2023-03-22 16:22:18 +01:00
expr_t clone ( DataTree & alt_datatree ) const override ;
2018-12-05 15:17:00 +01:00
int maxLagWithDiffsExpanded ( ) const override ;
2018-08-01 19:41:44 +02:00
expr_t substituteVarExpectation ( const map < string , expr_t > & subst_table ) const override ;
2019-12-20 16:59:30 +01:00
expr_t substitutePacExpectation ( const string & name , expr_t subexpr ) override ;
2021-10-26 18:06:26 +02:00
expr_t substitutePacTargetNonstationary ( const string & name , expr_t subexpr ) override ;
bool containsPacExpectation ( const string & pac_model_name = " " ) const override ;
bool containsPacTargetNonstationary ( const string & pac_model_name = " " ) const override ;
void writeJsonAST ( ostream & output ) const override ;
void writeJsonOutput ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic ) const override ;
} ;
class PacTargetNonstationaryNode : public SubModelNode
{
public :
PacTargetNonstationaryNode ( DataTree & datatree_arg , int idx_arg , string model_name ) ;
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 ;
2023-03-22 16:22:18 +01:00
expr_t clone ( DataTree & alt_datatree ) const override ;
2021-10-26 18:06:26 +02:00
int maxLagWithDiffsExpanded ( ) const override ;
expr_t substituteVarExpectation ( const map < string , expr_t > & subst_table ) const override ;
expr_t substitutePacExpectation ( const string & name , expr_t subexpr ) override ;
expr_t substitutePacTargetNonstationary ( const string & name , expr_t subexpr ) override ;
2018-08-13 12:12:20 +02:00
bool containsPacExpectation ( const string & pac_model_name = " " ) const override ;
2021-10-26 18:06:26 +02:00
bool containsPacTargetNonstationary ( const string & pac_model_name = " " ) const override ;
2018-09-18 14:50:31 +02:00
void writeJsonAST ( ostream & output ) const override ;
2019-12-16 19:42:59 +01:00
void writeJsonOutput ( ostream & output , const temporary_terms_t & temporary_terms , const deriv_node_temp_terms_t & tef_terms , bool isdynamic ) const override ;
2016-11-18 16:52:13 +01:00
} ;
2008-02-03 11:28:36 +01:00
# endif