Commit c84df1aa authored by sebastien's avatar sebastien
Browse files

preprocessor: in stochastic mode, create auxiliary variables for exogenous with non-zero lead/lag


git-svn-id: https://www.dynare.org/svn/dynare/trunk@3026 ac1d8469-bf42-47a9-8791-bf33cf982152
parent f7d69ff5
......@@ -2831,37 +2831,25 @@ DynamicModel::hessianHelper(ostream &output, int row_nb, int col_nb, ExprNodeOut
}
void
DynamicModel::substituteLeadGreaterThanTwo()
DynamicModel::substituteEndoLeadGreaterThanTwo()
{
ExprNode::subst_table_t subst_table;
vector<BinaryOpNode *> neweqs;
// Substitute in model local variables
for(map<int, NodeID>::iterator it = local_variables_table.begin();
it != local_variables_table.end(); it++)
it->second = it->second->substituteLeadGreaterThanTwo(subst_table, neweqs);
// Substitute in equations
for(int i = 0; i < (int) equations.size(); i++)
{
BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->substituteLeadGreaterThanTwo(subst_table, neweqs));
assert(substeq != NULL);
equations[i] = substeq;
}
// Add new equations
for(int i = 0; i < (int) neweqs.size(); i++)
addEquation(neweqs[i]);
substituteLeadLagInternal(0);
}
// Add the new set of equations at the *beginning* of aux_equations
copy(neweqs.rbegin(), neweqs.rend(), front_inserter(aux_equations));
void
DynamicModel::substituteEndoLagGreaterThanTwo()
{
substituteLeadLagInternal(1);
}
if (neweqs.size() > 0)
cout << "Substitution of leads >= 2: added " << neweqs.size() << " auxiliary variables and equations." << endl;
void
DynamicModel::substituteExoLeadLag()
{
substituteLeadLagInternal(2);
}
void
DynamicModel::substituteLagGreaterThanTwo()
DynamicModel::substituteLeadLagInternal(int vars)
{
ExprNode::subst_table_t subst_table;
vector<BinaryOpNode *> neweqs;
......@@ -2869,25 +2857,68 @@ DynamicModel::substituteLagGreaterThanTwo()
// Substitute in model local variables
for(map<int, NodeID>::iterator it = local_variables_table.begin();
it != local_variables_table.end(); it++)
it->second = it->second->substituteLagGreaterThanTwo(subst_table, neweqs);
{
NodeID subst;
switch(vars)
{
case 0:
subst = it->second->substituteEndoLeadGreaterThanTwo(subst_table, neweqs);
break;
case 1:
subst = it->second->substituteEndoLagGreaterThanTwo(subst_table, neweqs);
break;
case 2:
subst = it->second->substituteExoLeadLag(subst_table, neweqs);
break;
}
it->second = subst;
}
// Substitute in equations
for(int i = 0; i < (int) equations.size(); i++)
{
BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->substituteLagGreaterThanTwo(subst_table, neweqs));
NodeID subst;
switch(vars)
{
case 0:
subst = equations[i]->substituteEndoLeadGreaterThanTwo(subst_table, neweqs);
break;
case 1:
subst = equations[i]->substituteEndoLagGreaterThanTwo(subst_table, neweqs);
break;
case 2:
subst = equations[i]->substituteExoLeadLag(subst_table, neweqs);
break;
}
BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(subst);
assert(substeq != NULL);
equations[i] = substeq;
}
// Add new equations
for(int i = 0; i < (int) neweqs.size(); i++)
addEquation(neweqs[i]);
addEquation(neweqs[i]);
// Add the new set of equations at the *beginning* of aux_equations
copy(neweqs.rbegin(), neweqs.rend(), front_inserter(aux_equations));
if (neweqs.size() > 0)
cout << "Substitution of lags >= 2: added " << neweqs.size() << " auxiliary variables and equations." << endl;
{
cout << "Substitution of ";
switch(vars)
{
case 0:
cout << "endo leads >= 2";
break;
case 1:
cout << "endo lags >= 2";
break;
case 2:
cout << "exo leads/lags >= 2";
break;
}
cout << ": added " << neweqs.size() << " auxiliary variables and equations." << endl;
}
}
void
......
......@@ -144,6 +144,9 @@ private:
//! Write chain rule derivative of a recursive equation w.r. to a variable
void writeChainRuleDerivative(ostream &output, int eq, int var, int lag, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
//! Factorized code for substitutions of leads/lags
/*! \param[in] vars 0 for endo leads, 1 for endo lags, 2 for exo */
void substituteLeadLagInternal(int vars);
public:
DynamicModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants);
......@@ -199,11 +202,14 @@ public:
//! Returns true indicating that this is a dynamic model
virtual bool isDynamic() const { return true; };
//! Transforms the model by removing all leads greater or equal than 2
void substituteLeadGreaterThanTwo();
//! Transforms the model by removing all leads greater or equal than 2 on endos
void substituteEndoLeadGreaterThanTwo();
//! Transforms the model by removing all lags greater or equal than 2
void substituteLagGreaterThanTwo();
//! Transforms the model by removing all lags greater or equal than 2 on endos
void substituteEndoLagGreaterThanTwo();
//! Transforms the model by removing all leads and lags on exos
void substituteExoLeadLag();
//! Fills eval context with values of model local variables and auxiliary variables
void fillEvalContext(eval_context_type &eval_context) const;
......
......@@ -148,7 +148,7 @@ ExprNode::writeOutput(ostream &output)
}
VariableNode *
ExprNode::createLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
ExprNode::createEndoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
int n = maxEndoLead();
assert(n >= 2);
......@@ -168,7 +168,7 @@ ExprNode::createLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector<Bin
it = subst_table.find(orig_expr);
if (it == subst_table.end())
{
int symb_id = datatree.symbol_table.addLeadAuxiliaryVar(orig_expr->idx);
int symb_id = datatree.symbol_table.addEndoLeadAuxiliaryVar(orig_expr->idx);
neweqs.push_back(dynamic_cast<BinaryOpNode *>(datatree.AddEqual(datatree.AddVariable(symb_id, 0), substexpr)));
substexpr = datatree.AddVariable(symb_id, +1);
assert(dynamic_cast<VariableNode *>(substexpr) != NULL);
......@@ -278,13 +278,19 @@ NumConstNode::decreaseLeadsLags(int n) const
}
NodeID
NumConstNode::substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
NumConstNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
return const_cast<NumConstNode *>(this);
}
NodeID
NumConstNode::substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
NumConstNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
return const_cast<NumConstNode *>(this);
}
NodeID
NumConstNode::substituteExoLeadLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
return const_cast<NumConstNode *>(this);
}
......@@ -766,7 +772,7 @@ VariableNode::decreaseLeadsLags(int n) const
}
NodeID
VariableNode::substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
VariableNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
NodeID value;
switch(type)
......@@ -775,20 +781,20 @@ VariableNode::substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<Bi
if (lag <= 1)
return const_cast<VariableNode *>(this);
else
return createLeadAuxiliaryVarForMyself(subst_table, neweqs);
return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs);
case eModelLocalVariable:
value = datatree.local_variables_table[symb_id];
if (value->maxEndoLead() <= 1)
return const_cast<VariableNode *>(this);
else
return value->substituteLeadGreaterThanTwo(subst_table, neweqs);
return value->substituteEndoLeadGreaterThanTwo(subst_table, neweqs);
default:
return const_cast<VariableNode *>(this);
}
}
NodeID
VariableNode::substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
VariableNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
VariableNode *substexpr;
subst_table_t::const_iterator it;
......@@ -814,7 +820,7 @@ VariableNode::substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<Bin
it = subst_table.find(orig_expr);
if (it == subst_table.end())
{
int aux_symb_id = datatree.symbol_table.addLagAuxiliaryVar(symb_id, cur_lag+1);
int aux_symb_id = datatree.symbol_table.addEndoLagAuxiliaryVar(symb_id, cur_lag+1);
neweqs.push_back(dynamic_cast<BinaryOpNode *>(datatree.AddEqual(datatree.AddVariable(aux_symb_id, 0), substexpr)));
substexpr = datatree.AddVariable(aux_symb_id, -1);
subst_table[orig_expr] = substexpr;
......@@ -827,7 +833,81 @@ VariableNode::substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<Bin
return substexpr;
case eModelLocalVariable:
return datatree.local_variables_table[symb_id]->substituteLagGreaterThanTwo(subst_table, neweqs);
return datatree.local_variables_table[symb_id]->substituteEndoLagGreaterThanTwo(subst_table, neweqs);
default:
return const_cast<VariableNode *>(this);
}
}
NodeID
VariableNode::substituteExoLeadLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
VariableNode *substexpr;
subst_table_t::const_iterator it;
int cur_lag;
switch(type)
{
case eExogenous:
if (lag == 0)
return const_cast<VariableNode *>(this);
it = subst_table.find(this);
if (it != subst_table.end())
return const_cast<VariableNode *>(it->second);
if (lag < 0)
{
substexpr = datatree.AddVariable(symb_id, 0);
cur_lag = -1;
// Each iteration tries to create an auxvar such that auxvar(-1)=curvar(cur_lag)
// At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an auxvar) equivalent to curvar(cur_lag+1) (resp. curvar(cur_lag))
while(cur_lag >= lag)
{
VariableNode *orig_expr = datatree.AddVariable(symb_id, cur_lag);
it = subst_table.find(orig_expr);
if (it == subst_table.end())
{
int aux_symb_id = datatree.symbol_table.addExoLagAuxiliaryVar(symb_id, cur_lag+1);
neweqs.push_back(dynamic_cast<BinaryOpNode *>(datatree.AddEqual(datatree.AddVariable(aux_symb_id, 0), substexpr)));
substexpr = datatree.AddVariable(aux_symb_id, -1);
subst_table[orig_expr] = substexpr;
}
else
substexpr = const_cast<VariableNode *>(it->second);
cur_lag--;
}
return substexpr;
}
else
{
substexpr = datatree.AddVariable(symb_id, 0);
cur_lag = +1;
// Each iteration tries to create an auxvar such that auxvar(+1)=curvar(cur_lag)
// At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an auxvar) equivalent to curvar(cur_lag-1) (resp. curvar(cur_lag))
while(cur_lag <= lag)
{
VariableNode *orig_expr = datatree.AddVariable(symb_id, cur_lag);
it = subst_table.find(orig_expr);
if (it == subst_table.end())
{
int aux_symb_id = datatree.symbol_table.addExoLeadAuxiliaryVar(symb_id, cur_lag-1);
neweqs.push_back(dynamic_cast<BinaryOpNode *>(datatree.AddEqual(datatree.AddVariable(aux_symb_id, 0), substexpr)));
substexpr = datatree.AddVariable(aux_symb_id, +1);
subst_table[orig_expr] = substexpr;
}
else
substexpr = const_cast<VariableNode *>(it->second);
cur_lag++;
}
return substexpr;
}
case eModelLocalVariable:
return datatree.local_variables_table[symb_id]->substituteExoLeadLag(subst_table, neweqs);
default:
return const_cast<VariableNode *>(this);
}
......@@ -1471,26 +1551,33 @@ UnaryOpNode::decreaseLeadsLags(int n) const
}
NodeID
UnaryOpNode::substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
UnaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
if (op_code == oUminus)
{
NodeID argsubst = arg->substituteLeadGreaterThanTwo(subst_table, neweqs);
NodeID argsubst = arg->substituteEndoLeadGreaterThanTwo(subst_table, neweqs);
return buildSimilarUnaryOpNode(argsubst, datatree);
}
else
{
if (maxEndoLead() >= 2)
return createLeadAuxiliaryVarForMyself(subst_table, neweqs);
return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs);
else
return const_cast<UnaryOpNode *>(this);
}
}
NodeID
UnaryOpNode::substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
UnaryOpNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
NodeID argsubst = arg->substituteEndoLagGreaterThanTwo(subst_table, neweqs);
return buildSimilarUnaryOpNode(argsubst, datatree);
}
NodeID
UnaryOpNode::substituteExoLeadLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
NodeID argsubst = arg->substituteLagGreaterThanTwo(subst_table, neweqs);
NodeID argsubst = arg->substituteExoLeadLag(subst_table, neweqs);
return buildSimilarUnaryOpNode(argsubst, datatree);
}
......@@ -2365,7 +2452,7 @@ BinaryOpNode::decreaseLeadsLags(int n) const
}
NodeID
BinaryOpNode::substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
BinaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
NodeID arg1subst, arg2subst;
int maxlead1 = arg1->maxEndoLead(), maxlead2 = arg2->maxEndoLead();
......@@ -2378,32 +2465,40 @@ BinaryOpNode::substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<Bi
case oPlus:
case oMinus:
case oEqual:
arg1subst = maxlead1 >= 2 ? arg1->substituteLeadGreaterThanTwo(subst_table, neweqs) : arg1;
arg2subst = maxlead2 >= 2 ? arg2->substituteLeadGreaterThanTwo(subst_table, neweqs) : arg2;
arg1subst = maxlead1 >= 2 ? arg1->substituteEndoLeadGreaterThanTwo(subst_table, neweqs) : arg1;
arg2subst = maxlead2 >= 2 ? arg2->substituteEndoLeadGreaterThanTwo(subst_table, neweqs) : arg2;
return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
case oTimes:
case oDivide:
if (maxlead1 >= 2 && maxlead2 == 0)
{
arg1subst = arg1->substituteLeadGreaterThanTwo(subst_table, neweqs);
arg1subst = arg1->substituteEndoLeadGreaterThanTwo(subst_table, neweqs);
return buildSimilarBinaryOpNode(arg1subst, arg2, datatree);
}
if (maxlead1 == 0 && maxlead2 >= 2 && op_code == oTimes)
{
arg2subst = arg2->substituteLeadGreaterThanTwo(subst_table, neweqs);
arg2subst = arg2->substituteEndoLeadGreaterThanTwo(subst_table, neweqs);
return buildSimilarBinaryOpNode(arg1, arg2subst, datatree);
}
return createLeadAuxiliaryVarForMyself(subst_table, neweqs);
return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs);
default:
return createLeadAuxiliaryVarForMyself(subst_table, neweqs);
return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs);
}
}
NodeID
BinaryOpNode::substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
BinaryOpNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
NodeID arg1subst = arg1->substituteEndoLagGreaterThanTwo(subst_table, neweqs);
NodeID arg2subst = arg2->substituteEndoLagGreaterThanTwo(subst_table, neweqs);
return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
}
NodeID
BinaryOpNode::substituteExoLeadLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
NodeID arg1subst = arg1->substituteLagGreaterThanTwo(subst_table, neweqs);
NodeID arg2subst = arg2->substituteLagGreaterThanTwo(subst_table, neweqs);
NodeID arg1subst = arg1->substituteExoLeadLag(subst_table, neweqs);
NodeID arg2subst = arg2->substituteExoLeadLag(subst_table, neweqs);
return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
}
......@@ -2766,20 +2861,29 @@ TrinaryOpNode::decreaseLeadsLags(int n) const
}
NodeID
TrinaryOpNode::substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
TrinaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
if (maxEndoLead() < 2)
return const_cast<TrinaryOpNode *>(this);
else
return createLeadAuxiliaryVarForMyself(subst_table, neweqs);
return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs);
}
NodeID
TrinaryOpNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
NodeID arg1subst = arg1->substituteEndoLagGreaterThanTwo(subst_table, neweqs);
NodeID arg2subst = arg2->substituteEndoLagGreaterThanTwo(subst_table, neweqs);
NodeID arg3subst = arg3->substituteEndoLagGreaterThanTwo(subst_table, neweqs);
return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
}
NodeID
TrinaryOpNode::substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
TrinaryOpNode::substituteExoLeadLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
NodeID arg1subst = arg1->substituteLagGreaterThanTwo(subst_table, neweqs);
NodeID arg2subst = arg2->substituteLagGreaterThanTwo(subst_table, neweqs);
NodeID arg3subst = arg3->substituteLagGreaterThanTwo(subst_table, neweqs);
NodeID arg1subst = arg1->substituteExoLeadLag(subst_table, neweqs);
NodeID arg2subst = arg2->substituteExoLeadLag(subst_table, neweqs);
NodeID arg3subst = arg3->substituteExoLeadLag(subst_table, neweqs);
return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
}
......@@ -2932,15 +3036,22 @@ UnknownFunctionNode::decreaseLeadsLags(int n) const
}
NodeID
UnknownFunctionNode::substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
UnknownFunctionNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
cerr << "UnknownFunctionNode::substituteEndoLeadGreaterThanTwo: not implemented!" << endl;
exit(EXIT_FAILURE);
}
NodeID
UnknownFunctionNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
cerr << "UnknownFunctionNode::substituteLeadGreaterThanTwo: not implemented!" << endl;
cerr << "UnknownFunctionNode::substituteEndoLagGreaterThanTwo: not implemented!" << endl;
exit(EXIT_FAILURE);
}
NodeID
UnknownFunctionNode::substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
UnknownFunctionNode::substituteExoLeadLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
cerr << "UnknownFunctionNode::substituteLagGreaterThanTwo: not implemented!" << endl;
cerr << "UnknownFunctionNode::substituteExoLeadLag: not implemented!" << endl;
exit(EXIT_FAILURE);
}
......@@ -240,14 +240,14 @@ public:
//! Type for the substitution map used in the process of creating auxiliary vars for leads >= 2
typedef map<const ExprNode *, const VariableNode *> subst_table_t;
//! Creates auxiliary lead variables corresponding to this expression
//! 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
\return The new variable node corresponding to the current expression
*/
VariableNode *createLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
VariableNode *createEndoLeadAuxiliaryVarForMyself(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
/*!
......@@ -260,14 +260,21 @@ public:
\return A new equivalent expression where sub-expressions with max endo lead >= 2 have been replaced by auxiliary variables
*/
virtual NodeID substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
virtual NodeID substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) 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 NodeID substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
virtual NodeID substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
//! Constructs a new expression where endo variables with max exo lag >= 2 or max exo 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 NodeID substituteExoLeadLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
};
//! Object used to compare two nodes (using their indexes)
......@@ -300,8 +307,9 @@ public:
virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables);
virtual int maxEndoLead() const;
virtual NodeID decreaseLeadsLags(int n) const;
virtual NodeID substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExoLeadLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
};
//! Symbol or variable node
......@@ -334,8 +342,9 @@ public:
virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables);
virtual int maxEndoLead() const;
virtual NodeID decreaseLeadsLags(int n) const;
virtual NodeID substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExoLeadLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
};
//! Unary operator node
......@@ -374,10 +383,11 @@ public:
virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables);
virtual int maxEndoLead() const;
virtual NodeID decreaseLeadsLags(int n) const;
virtual NodeID substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
//! Creates another UnaryOpNode with the same opcode, but with a possibly different datatree and argument
NodeID buildSimilarUnaryOpNode(NodeID alt_arg, DataTree &alt_datatree) const;
virtual NodeID substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExoLeadLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
};
//! Binary operator node
......@@ -421,10 +431,11 @@ public:
virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables);
virtual int maxEndoLead() const;
virtual NodeID decreaseLeadsLags(int n) const;
virtual NodeID substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
//! Creates another BinaryOpNode with the same opcode, but with a possibly different datatree and arguments
NodeID buildSimilarBinaryOpNode(NodeID alt_arg1, NodeID alt_arg2, DataTree &alt_datatree) const;
virtual NodeID substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExoLeadLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
};
//! Trinary operator node
......@@ -462,10 +473,11 @@ public:
virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables);
virtual int maxEndoLead() const;
virtual NodeID decreaseLeadsLags(int n) const;
virtual NodeID substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
//! Creates another TrinaryOpNode with the same opcode, but with a possibly different datatree and arguments
NodeID buildSimilarTrinaryOpNode(NodeID alt_arg1, NodeID alt_arg2, NodeID alt_arg3, DataTree &alt_datatree) const;
virtual NodeID substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExoLeadLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
};
//! Unknown function node
......@@ -497,8 +509,9 @@ public:
virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables);
virtual int maxEndoLead() const;
virtual NodeID decreaseLeadsLags(int n) const;
virtual NodeID substituteLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExoLeadLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
};
#endif
......@@ -141,8 +141,9 @@ ModFile::transformPass()
|| mod_file_struct.osr_present
|| mod_file_struct.ramsey_policy_present)
{
dynamic_model.substituteLeadGreaterThanTwo();
dynamic_model.substituteLagGreaterThanTwo();
dynamic_model.substituteEndoLeadGreaterThanTwo();