Commit 894155be authored by Houtan Bastani's avatar Houtan Bastani
Browse files

trend_var, growth_factor, deflator: stationarize a nonstationary model and test

parent bcc590aa
......@@ -417,6 +417,7 @@ dynare ramst.mod savemacro
<listitem><para><xref linkend='parameters'/></para></listitem>
<listitem><para><xref linkend='change_type'/></para></listitem>
<listitem><para><xref linkend='predetermined_variables'/></para></listitem>
<listitem><para><xref linkend='trend_var'/></para></listitem>
</itemizedlist>
<refentry id="var">
......@@ -432,6 +433,11 @@ dynare ramst.mod savemacro
<refsynopsisdiv>
<cmdsynopsis>
<command>var</command>
<arg>
<arg choice="plain">(</arg>
<arg choice="req"><option>deflator</option> = <replaceable>MODEL_EXPRESSION</replaceable></arg>
<arg choice="plain">)</arg>
</arg>
<arg choice="plain">
<replaceable>VARIABLE_NAME</replaceable>
<arg>$<replaceable>LATEX_NAME</replaceable>$</arg>
......@@ -446,15 +452,26 @@ dynare ramst.mod savemacro
<refsect1><title>Description</title>
<para>
This required command declares the endogenous variables in the model. See <xref linkend="conventions"/> for the syntax of <replaceable>VARIABLE_NAME</replaceable>. Optionally it is possible to give a LaTeX name to the variable.
This required command declares the endogenous variables in the model. See <xref linkend="conventions"/> for the syntax of <replaceable>VARIABLE_NAME</replaceable> and <replaceable>MODEL_EXPRESSION</replaceable>. Optionally it is possible to give a LaTeX name to the variable or, if it nonstationary, provide information regarding its deflator.
</para>
<para><command>var</command> commands can appear several times in the file and Dynare will concatenate them.</para>
</refsect1>
<refsect1><title>Options</title>
<para>If the model is nonstationary and is to be written as such in the <command>model</command> block, Dynare will need the trend deflator for the appropriate endogenous variables in order to stationarize the model. The trend deflator must be provided alongside the variables that follow this trend.</para>
<variablelist>
<varlistentry>
<term><option>deflator = <replaceable>MODEL_EXPRESSION</replaceable></option></term>
<listitem><para>The expression used to detrend an endogenous variable. All trend variables, endogenous variables and parameters referenced in <replaceable>MODEL_EXPRESSION</replaceable> must already have been declared by the <command>trend_var</command>, <command>var</command> and <command>parameters</command> commands.</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>Example</title>
<informalexample>
<programlisting>
var c gnp q1 q2;
var(deflator=A) i b;
</programlisting>
</informalexample>
</refsect1>
......@@ -724,6 +741,61 @@ end;
</refsect1>
</refentry>
<refentry id="trend_var">
<refmeta>
<refentrytitle>trend_var</refentrytitle>
</refmeta>
<refnamediv>
<refname>trend_var</refname>
<refpurpose>declares trend variables</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>trend_var</command>
<arg choice="plain">
<arg choice="plain">(</arg>
<arg choice="req"><option>growth_factor</option> = <replaceable>MODEL_EXPRESSION</replaceable></arg>
<arg choice="plain">)</arg>
</arg>
<arg choice="plain">
<replaceable>VARIABLE_NAME</replaceable>
<arg>$<replaceable>LATEX_NAME</replaceable>$</arg>
</arg>
<arg rep="repeat"><arg>,</arg>
<replaceable>VARIABLE_NAME</replaceable>
<arg>$<replaceable>LATEX_NAME</replaceable>$</arg>
</arg>
<arg choice="plain">;</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>This optional command declares the trend variables in the model. See <xref linkend="conventions"/> for the syntax of <replaceable>MODEL_EXPRESSION</replaceable> and <replaceable>VARIABLE_NAME</replaceable>. Optionally it is possible to give a LaTeX name to the variable.</para>
<para>Trend variables are required if the user wants to be able to write a nonstationary model in the <command>model</command> block. The <command>trend_var</command> command must appear before the <command>var</command> command that references the trend variable.</para>
<para><command>trend_var</command> commands can appear several times in the file and Dynare will concatenate them.</para>
</refsect1>
<refsect1><title>Options</title>
<para>If the model is nonstationary and is to be written as such in the <command>model</command> block, Dynare will need the growth factor of every trend variable in order to stationarize the model. The growth factor must be provided within the declaration of the trend variable.</para>
<variablelist>
<varlistentry>
<term><option>growth_factor = <replaceable>MODEL_EXPRESSION</replaceable></option></term>
<listitem><para>The growth factor of the trend variable. All endogenous variables and parameters referenced in <replaceable>MODEL_EXPRESSION</replaceable> must already have been declared by the <command>var</command> and <command>parameters</command> commands.</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>Example</title>
<informalexample>
<programlisting>
trend_var (growth_factor=gA) A;
</programlisting>
</informalexample>
</refsect1>
</refentry>
</sect1>
<sect1 id="expressions"><title>Expressions</title>
......@@ -1380,7 +1452,6 @@ end;
</refentry>
</sect1>
<sect1 id="sec_shocks"><title>Shocks on exogenous variables</title>
<para>
In a deterministic context, when one wants to study the transition of one equilibrium position to another, it is equivalent to analyze the consequences of a permanent shock and this in done in Dynare through the proper use of <xref linkend='initval'/> and <xref linkend='endval'/>.
......
......@@ -136,7 +136,8 @@ enum SymbolType
eParameter = 4, //!< Parameter
eModelLocalVariable = 10, //!< Local variable whose scope is model (pound expression)
eModFileLocalVariable = 11, //!< Local variable whose scope is mod file (model excluded)
eExternalFunction = 12 //!< External (user-defined) function
eExternalFunction = 12, //!< External (user-defined) function
eTrend = 13 //!< Trend variable
};
enum ExpressionType
......
......@@ -213,6 +213,16 @@ public:
{
};
//! Raised when a trend is declared twice
class TrendException
{
public:
string name;
TrendException(const string &name_arg) : name(name_arg)
{
}
};
//! Returns the derivation ID, or throws an exception if the derivation ID does not exist
virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException);
//! Returns the column of the dynamic Jacobian associated to a derivation ID
......
......@@ -2411,6 +2411,13 @@ DynamicModel::collect_first_order_derivatives_endogenous()
return endo_derivatives;
}
void
DynamicModel::runTrendTest(const eval_context_t &eval_context)
{
computeDerivIDs();
testTrendDerivativesEqualToZero(eval_context);
}
void
DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, bool paramsDerivatives,
const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode)
......@@ -2832,6 +2839,29 @@ DynamicModel::writeDynamicFile(const string &basename, bool block, bool bytecode
writeDynamicMFile(t_basename);
}
void
DynamicModel::cloneDynamic(DynamicModel &dynamic_model) const
{
/* Ensure that we are using the same symbol table, because at many places we manipulate
symbol IDs rather than strings */
assert(&symbol_table == &dynamic_model.symbol_table);
// Convert model local variables (need to be done first)
for (map<int, expr_t>::const_iterator it = local_variables_table.begin();
it != local_variables_table.end(); it++)
dynamic_model.AddLocalVariable(it->first, it->second->cloneDynamic(dynamic_model));
// Convert equations
for (vector<BinaryOpNode *>::const_iterator it = equations.begin();
it != equations.end(); it++)
dynamic_model.addEquation((*it)->cloneDynamic(dynamic_model));
// Convert auxiliary equations
for (deque<BinaryOpNode *>::const_iterator it = aux_equations.begin();
it != aux_equations.end(); it++)
dynamic_model.addAuxEquation((*it)->cloneDynamic(dynamic_model));
}
void
DynamicModel::toStatic(StaticModel &static_model) const
{
......@@ -2870,6 +2900,7 @@ DynamicModel::computeDerivIDs()
equations[i]->collectVariables(eExogenous, dynvars);
equations[i]->collectVariables(eExogenousDet, dynvars);
equations[i]->collectVariables(eParameter, dynvars);
equations[i]->collectVariables(eTrend, dynvars);
}
for (set<pair<int, int> >::const_iterator it = dynvars.begin();
......@@ -2982,7 +3013,8 @@ DynamicModel::computeDynJacobianCols(bool jacobianExo)
dyn_jacobian_cols_table[deriv_id] = dynJacobianColsNbr + symbol_table.exo_nbr() + tsid;
break;
case eParameter:
// We don't assign a dynamic jacobian column to parameters
case eTrend:
// We don't assign a dynamic jacobian column to parameters or trend variables
break;
default:
// Shut up GCC
......@@ -3012,6 +3044,34 @@ DynamicModel::getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDExcepti
return it->second;
}
void
DynamicModel::testTrendDerivativesEqualToZero(const eval_context_t &eval_context)
{
for (deriv_id_table_t::const_iterator it = deriv_id_table.begin();
it != deriv_id_table.end(); it++)
if (symbol_table.getType(it->first.first) == eTrend)
for (int eq = 0; eq < (int) equations.size(); eq++)
{
expr_t testeq = AddLog(AddMinus(equations[eq]->get_arg1(), // F: a = b -> ln(a - b)
equations[eq]->get_arg2()));
assert(testeq != NULL);
testeq = testeq->getDerivative(it->second); // d F / d Trend
for (deriv_id_table_t::const_iterator endogit = deriv_id_table.begin();
endogit != deriv_id_table.end(); endogit++)
if (symbol_table.getType(endogit->first.first) == eEndogenous)
{
double nearZero = testeq->getDerivative(endogit->second)->eval(eval_context); // eval d F / d Trend d Endog
if (nearZero < -ZERO_BAND || nearZero > ZERO_BAND)
{
cerr << "ERROR: the second-order cross partial of equation " << eq + 1 << " w.r.t. trend variable "
<< symbol_table.getName(it->first.first) << " and endogenous variable "
<< symbol_table.getName(endogit->first.first) << " is not null. " << endl;
exit(EXIT_FAILURE);
}
}
}
}
void
DynamicModel::computeParamsDerivatives()
{
......@@ -3467,6 +3527,37 @@ DynamicModel::transformPredeterminedVariables()
}
}
void
DynamicModel::detrendEquations()
{
for (trend_symbols_map_t::const_iterator it = nonstationary_symbols_map.begin();
it != nonstationary_symbols_map.end(); it++)
for (int i = 0; i < (int) equations.size(); i++)
{
BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->detrend(it->first, it->second));
assert(substeq != NULL);
equations[i] = dynamic_cast<BinaryOpNode *>(substeq);
}
for (int i = 0; i < (int) equations.size(); i++)
{
BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->removeTrendLeadLag(trend_symbols_map));
assert(substeq != NULL);
equations[i] = dynamic_cast<BinaryOpNode *>(substeq);
}
}
void
DynamicModel::removeTrendVariableFromEquations()
{
for (int i = 0; i < (int) equations.size(); i++)
{
BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->replaceTrendVar());
assert(substeq != NULL);
equations[i] = dynamic_cast<BinaryOpNode *>(substeq);
}
}
void
DynamicModel::fillEvalContext(eval_context_t &eval_context) const
{
......@@ -3503,4 +3594,10 @@ DynamicModel::fillEvalContext(eval_context_t &eval_context) const
// Do nothing
}
}
//Third, trend variables
vector <int> trendVars = symbol_table.getTrendVarIds();
for (vector <int>::const_iterator it = trendVars.begin();
it != trendVars.end(); it++)
eval_context[*it] = 2; //not <= 0 bc of log, not 1 bc of powers
}
......@@ -21,6 +21,7 @@
#define _DYNAMICMODEL_HH
using namespace std;
#define ZERO_BAND 1e-8
#include <fstream>
......@@ -156,6 +157,8 @@ private:
void computeDynJacobianCols(bool jacobianExo);
//! Computes derivatives of the Jacobian w.r. to parameters
void computeParamsDerivatives();
//! Computes derivatives of the Jacobian w.r. to trend vars and tests that they are equal to zero
void testTrendDerivativesEqualToZero(const eval_context_t &eval_context);
//! Computes temporary terms for the file containing parameters derivatives
void computeParamsDerivativesTemporaryTerms();
//! Collect only the first derivatives
......@@ -278,6 +281,10 @@ public:
/*! It assumes that the static model given in argument has just been allocated */
void toStatic(StaticModel &static_model) const;
//! Copies a dynamic model (only the equations)
/*! It assumes that the dynamic model given in argument has just been allocated */
void cloneDynamic(DynamicModel &dynamic_model) const;
//! Writes LaTeX file with the equations of the dynamic model
void writeLatexFile(const string &basename) const;
......@@ -294,6 +301,9 @@ public:
return true;
};
//! Drive test of detrended equations
void runTrendTest(const eval_context_t &eval_context);
//! Transforms the model by removing all leads greater or equal than 2 on endos
/*! Note that this can create new lags on endos and exos */
void substituteEndoLeadGreaterThanTwo(bool deterministic_model);
......@@ -314,6 +324,12 @@ public:
//! Transforms the model by decreasing the lead/lag of predetermined variables in model equations by one
void transformPredeterminedVariables();
//! Transforms the model by removing trends specified by the user
void detrendEquations();
//! Transforms the model by replacing trend variables with a 1
void removeTrendVariableFromEquations();
//! Fills eval context with values of model local variables and auxiliary variables
void fillEvalContext(eval_context_t &eval_context) const;
......
......@@ -154,7 +154,7 @@ class ParsingDriver;
%token COMPUTE_MDD COMPUTE_PROBABILITIES PRINT_DRAWS N_DRAWS THINNING_FACTOR PROPOSAL_DRAWS MARKOV_FILE
%token MHM_FILE OUTPUT_FILE_TAG DRAWS_NBR_BURN_IN_1 DRAWS_NBR_BURN_IN_2 DRAWS_NBR_MEAN_VAR_ESTIMATE
%token DRAWS_NBR_MODIFIED_HARMONIC_MEAN DIRICHLET_SCALE
%token SBVAR MS_SBVAR
%token SBVAR MS_SBVAR TREND_VAR DEFLATOR GROWTH_FACTOR
%token SVAR_IDENTIFICATION EQUATION EXCLUSION LAG UPPER_CHOLESKY LOWER_CHOLESKY
%token MARKOV_SWITCHING CHAIN STATE DURATION NUMBER_OF_STATES
%token SVAR COEFFICIENTS VARIANCES CONSTANTS EQUATIONS
......@@ -241,6 +241,7 @@ statement : parameters
| svar
| external_function
| steady_state_model
| trend_var
;
dsample : DSAMPLE INT_NUMBER ';'
......@@ -251,7 +252,42 @@ dsample : DSAMPLE INT_NUMBER ';'
rplot : RPLOT symbol_list ';' { driver.rplot(); };
var : VAR var_list ';';
trend_var : TREND_VAR '(' GROWTH_FACTOR EQUAL { driver.begin_trend(); } hand_side ')' trend_var_list ';'
{ driver.end_trend_var($6); }
;
trend_var_list : trend_var_list symbol
{ driver.declare_trend_var($2); }
| trend_var_list COMMA symbol
{ driver.declare_trend_var($3); }
| symbol
{ driver.declare_trend_var($1); }
| trend_var_list symbol TEX_NAME
{ driver.declare_trend_var($2, $3); }
| trend_var_list COMMA symbol TEX_NAME
{ driver.declare_trend_var($3, $4); }
| symbol TEX_NAME
{ driver.declare_trend_var($1, $2); }
;
var : VAR var_list ';'
| VAR '(' DEFLATOR EQUAL { driver.begin_trend(); } hand_side ')' nonstationary_var_list ';'
{ driver.end_nonstationary_var($6); }
;
nonstationary_var_list : nonstationary_var_list symbol
{ driver.declare_nonstationary_var($2); }
| nonstationary_var_list COMMA symbol
{ driver.declare_nonstationary_var($3); }
| symbol
{ driver.declare_nonstationary_var($1); }
| nonstationary_var_list symbol TEX_NAME
{ driver.declare_nonstationary_var($2, $3); }
| nonstationary_var_list COMMA symbol TEX_NAME
{ driver.declare_nonstationary_var($3, $4); }
| symbol TEX_NAME
{ driver.declare_nonstationary_var($1, $2); }
;
varexo : VAREXO varexo_list ';';
......@@ -702,7 +738,6 @@ period_list : period_list COMMA INT_NUMBER
{ driver.add_period($1); }
;
sigma_e : SIGMA_E EQUAL '[' triangular_matrix ']' ';' { driver.do_sigma_e(); };
value_list
......
......@@ -102,6 +102,7 @@ string eofbuff;
<INITIAL>var {BEGIN DYNARE_STATEMENT; return token::VAR;}
<INITIAL>varexo {BEGIN DYNARE_STATEMENT; return token::VAREXO;}
<INITIAL>varexo_det {BEGIN DYNARE_STATEMENT; return token::VAREXO_DET;}
<INITIAL>trend_var {BEGIN DYNARE_STATEMENT; return token::TREND_VAR;}
<INITIAL>predetermined_variables {BEGIN DYNARE_STATEMENT; return token::PREDETERMINED_VARIABLES;}
<INITIAL>parameters {BEGIN DYNARE_STATEMENT; return token::PARAMETERS;}
<INITIAL>periods {BEGIN DYNARE_STATEMENT; return token::PERIODS;}
......@@ -360,7 +361,9 @@ string eofbuff;
<DYNARE_STATEMENT>filter_covariance {return token::FILTER_COVARIANCE; }
<DYNARE_STATEMENT>filter_decomposition {return token::FILTER_DECOMPOSITION; }
<DYNARE_STATEMENT>selected_variables_only {return token::SELECTED_VARIABLES_ONLY; }
<DYNARE_STATEMENT>pruning {return token::PRUNING; };
<DYNARE_STATEMENT>pruning {return token::PRUNING; }
<DYNARE_STATEMENT>deflator {return token::DEFLATOR;}
<DYNARE_STATEMENT>growth_factor {return token::GROWTH_FACTOR;}
<DYNARE_STATEMENT>[\$][^$]*[\$] {
strtok(yytext+1, "$");
......
......@@ -329,6 +329,12 @@ NumConstNode::toStatic(DataTree &static_datatree) const
return static_datatree.AddNumConstant(datatree.num_constants.get(id));
}
expr_t
NumConstNode::cloneDynamic(DataTree &dynamic_datatree) const
{
return dynamic_datatree.AddNumConstant(datatree.num_constants.get(id));
}
int
NumConstNode::maxEndoLead() const
{
......@@ -424,6 +430,24 @@ NumConstNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int la
return false;
}
expr_t
NumConstNode::replaceTrendVar() const
{
return const_cast<NumConstNode *>(this);
}
expr_t
NumConstNode::detrend(int symb_id, expr_t trend) const
{
return const_cast<NumConstNode *>(this);
}
expr_t
NumConstNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const
{
return const_cast<NumConstNode *>(this);
}
void
VariableNode::prepareForDerivation()
{
......@@ -439,6 +463,7 @@ VariableNode::prepareForDerivation()
case eExogenous:
case eExogenousDet:
case eParameter:
case eTrend:
// For a variable or a parameter, the only non-null derivative is with respect to itself
non_null_derivatives.insert(datatree.getDerivID(symb_id, lag));
break;
......@@ -465,6 +490,7 @@ VariableNode::computeDerivative(int deriv_id)
case eExogenous:
case eExogenousDet:
case eParameter:
case eTrend:
if (deriv_id == datatree.getDerivID(symb_id, lag))
return datatree.One;
else
......@@ -514,7 +540,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
output << "\\bar{";
output << datatree.symbol_table.getTeXName(symb_id);
if (output_type == oLatexDynamicModel
&& (type == eEndogenous || type == eExogenous || type == eExogenousDet || type == eModelLocalVariable))
&& (type == eEndogenous || type == eExogenous || type == eExogenousDet || type == eModelLocalVariable || type == eTrend))
{
output << "_{t";
if (lag != 0)
......@@ -677,6 +703,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
break;
case eExternalFunction:
case eTrend:
cerr << "Impossible case" << endl;
exit(EXIT_FAILURE);
}
......@@ -812,6 +839,7 @@ VariableNode::getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recur
case eExogenous:
case eExogenousDet:
case eParameter:
case eTrend:
if (deriv_id == datatree.getDerivID(symb_id, lag))
return datatree.One;
else
......@@ -856,6 +884,12 @@ VariableNode::toStatic(DataTree &static_datatree) const
return static_datatree.AddVariable(symb_id);
}
expr_t
VariableNode::cloneDynamic(DataTree &dynamic_datatree) const
{
return dynamic_datatree.AddVariable(symb_id, lag);
}
int
VariableNode::maxEndoLead() const
{
......@@ -920,6 +954,7 @@ VariableNode::decreaseLeadsLags(int n) const
case eEndogenous:
case eExogenous:
case eExogenousDet:
case eTrend:
return datatree.AddVariable(symb_id, lag-n);
case eModelLocalVariable:
return datatree.local_variables_table[symb_id]->decreaseLeadsLags(n);
......@@ -1104,6 +1139,51 @@ VariableNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int la
return false;
}
expr_t
VariableNode::replaceTrendVar() const
{
if (get_type() == eTrend)
return datatree.One;
else
return const_cast<VariableNode *>(this);
}
expr_t
VariableNode::detrend(int symb_id, expr_t trend) const
{
if (get_symb_id() != symb_id)
return const_cast<VariableNode *>(this);
if (get_lag() == 0)
return datatree.AddTimes(const_cast<VariableNode *>(this), trend);
else
return datatree.AddTimes(const_cast<VariableNode *>(this), trend->decreaseLeadsLags(-1*get_lag()));
}
expr_t
VariableNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const
{
if (get_type() != eTrend || get_lag() == 0)
return const_cast<VariableNode *>(this);
map<int, expr_t>::const_iterator it = trend_symbols_map.find(symb_id);
expr_t noTrendLeadLagNode = new VariableNode(datatree, it->first, 0);
if (get_lag() > 0)
{
expr_t growthFactorSequence = it->second->decreaseLeadsLags(-1);
for (int i=1; i<get_lag(); i++)
growthFactorSequence = datatree.AddTimes(growthFactorSequence, it->second->decreaseLeadsLags(-1*(i+1)));
return datatree.AddTimes(noTrendLeadLagNode, growthFactorSequence);
}
else //get_lag < 0
{
expr_t growthFactorSequence = it->second;
for (int i=1; i<abs(get_lag()); i++)
growthFactorSequence = datatree.AddTimes(growthFactorSequence, it->second->decreaseLeadsLags(i));
return datatree.AddDivide(noTrendLeadLagNode, growthFactorSequence);
}
}
UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, const int expectation_information_set_arg, const string &expectation_information_set_name_arg) :
ExprNode(datatree_arg),
arg(arg_arg),
......@@ -1779,6 +1859,13 @@ UnaryOpNode::toStatic(DataTree &static_datatree) const
return buildSimilarUnaryOpNode(sarg, static_datatree);
}
expr_t
UnaryOpNode::cloneDynamic(DataTree &dynamic_datatree) const
{
expr_t substarg = arg->cloneDynamic(dynamic_datatree);
return buildSimilarUnaryOpNode(substarg, dynamic_datatree);
}
int
UnaryOpNode::maxEndoLead() const
{
......@@ -1948,6 +2035,27 @@ UnaryOpNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag
return false;
}
expr_t
UnaryOpNode::replaceTrendVar() const
{
expr_t argsubst = arg->replaceTrendVar();
return buildSimilarUnaryOpNode(argsubst, datatree);
}
expr_t
UnaryOpNode::detrend(int symb_id, expr_t trend) const
{
expr_t argsubst = arg->detrend(symb_id, trend);
return buildSimilarUnaryOpNode(argsubst, datatree);
}
expr_t
UnaryOpNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const
{
expr_t argsubst = arg->removeTrendLeadLag(trend_symbols_map);
return buildSimilarUnaryOpNode(argsubst, datatree);
}
BinaryOpNode::BinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg,
BinaryOpcode op_code_arg, const expr_t arg2_arg) :
ExprNode(datatree_arg),
......@@ -2817,6 +2925,14 @@ BinaryOpNode::toStatic(DataTree &static_datatree) const
return buildSimilarBinaryOpNode(sarg1, sarg2, static_datatree);
}
expr_t
BinaryOpNode::cloneDynamic(DataTree &dynamic_datatree) const
{
expr_t substarg1 = arg1->cloneDynamic(dynamic_datatree);