trend_var, growth_factor, deflator: stationarize a nonstationary model and test
parent
0782dd57e3
commit
a7fc3361ac
|
@ -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
|
||||
|
|
10
DataTree.hh
10
DataTree.hh
|
@ -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, "$");
|
||||
|
|
216
ExprNode.cc
216
ExprNode.cc
|
@ -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);
|
||||
expr_t substarg2 = arg2->cloneDynamic(dynamic_datatree);
|
||||
return buildSimilarBinaryOpNode(substarg1, substarg2, dynamic_datatree);
|
||||
}
|
||||
|
||||
int
|
||||
BinaryOpNode::maxEndoLead() const
|
||||
{
|
||||
|
@ -2899,7 +3015,6 @@ BinaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vecto
|
|||
return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
expr_t
|
||||
|
@ -2982,6 +3097,30 @@ BinaryOpNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int la
|
|||
return false;
|
||||
}
|
||||
|
||||
expr_t
|
||||
BinaryOpNode::replaceTrendVar() const
|
||||
{
|
||||
expr_t arg1subst = arg1->replaceTrendVar();
|
||||
expr_t arg2subst = arg2->replaceTrendVar();
|
||||
return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
|
||||
}
|
||||
|
||||
expr_t
|
||||
BinaryOpNode::detrend(int symb_id, expr_t trend) const
|
||||
{
|
||||
expr_t arg1subst = arg1->detrend(symb_id, trend);
|
||||
expr_t arg2subst = arg2->detrend(symb_id, trend);
|
||||
return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
|
||||
}
|
||||
|
||||
expr_t
|
||||
BinaryOpNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const
|
||||
{
|
||||
expr_t arg1subst = arg1->removeTrendLeadLag(trend_symbols_map);
|
||||
expr_t arg2subst = arg2->removeTrendLeadLag(trend_symbols_map);
|
||||
return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
|
||||
}
|
||||
|
||||
TrinaryOpNode::TrinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg,
|
||||
TrinaryOpcode op_code_arg, const expr_t arg2_arg, const expr_t arg3_arg) :
|
||||
ExprNode(datatree_arg),
|
||||
|
@ -3403,6 +3542,15 @@ TrinaryOpNode::toStatic(DataTree &static_datatree) const
|
|||
return buildSimilarTrinaryOpNode(sarg1, sarg2, sarg3, static_datatree);
|
||||
}
|
||||
|
||||
expr_t
|
||||
TrinaryOpNode::cloneDynamic(DataTree &dynamic_datatree) const
|
||||
{
|
||||
expr_t substarg1 = arg1->cloneDynamic(dynamic_datatree);
|
||||
expr_t substarg2 = arg2->cloneDynamic(dynamic_datatree);
|
||||
expr_t substarg3 = arg3->cloneDynamic(dynamic_datatree);
|
||||
return buildSimilarTrinaryOpNode(substarg1, substarg2, substarg3, dynamic_datatree);
|
||||
}
|
||||
|
||||
int
|
||||
TrinaryOpNode::maxEndoLead() const
|
||||
{
|
||||
|
@ -3516,6 +3664,33 @@ TrinaryOpNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int l
|
|||
return false;
|
||||
}
|
||||
|
||||
expr_t
|
||||
TrinaryOpNode::replaceTrendVar() const
|
||||
{
|
||||
expr_t arg1subst = arg1->replaceTrendVar();
|
||||
expr_t arg2subst = arg2->replaceTrendVar();
|
||||
expr_t arg3subst = arg3->replaceTrendVar();
|
||||
return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
|
||||
}
|
||||
|
||||
expr_t
|
||||
TrinaryOpNode::detrend(int symb_id, expr_t trend) const
|
||||
{
|
||||
expr_t arg1subst = arg1->detrend(symb_id, trend);
|
||||
expr_t arg2subst = arg2->detrend(symb_id, trend);
|
||||
expr_t arg3subst = arg3->detrend(symb_id, trend);
|
||||
return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
|
||||
}
|
||||
|
||||
expr_t
|
||||
TrinaryOpNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const
|
||||
{
|
||||
expr_t arg1subst = arg1->removeTrendLeadLag(trend_symbols_map);
|
||||
expr_t arg2subst = arg2->removeTrendLeadLag(trend_symbols_map);
|
||||
expr_t arg3subst = arg3->removeTrendLeadLag(trend_symbols_map);
|
||||
return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
|
||||
}
|
||||
|
||||
ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg,
|
||||
int symb_id_arg,
|
||||
const vector<expr_t> &arguments_arg) :
|
||||
|
@ -3797,6 +3972,16 @@ ExternalFunctionNode::toStatic(DataTree &static_datatree) const
|
|||
return static_datatree.AddExternalFunction(symb_id, static_arguments);
|
||||
}
|
||||
|
||||
expr_t
|
||||
ExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const
|
||||
{
|
||||
vector<expr_t> dynamic_arguments;
|
||||
for (vector<expr_t>::const_iterator it = arguments.begin();
|
||||
it != arguments.end(); it++)
|
||||
dynamic_arguments.push_back((*it)->cloneDynamic(dynamic_datatree));
|
||||
return dynamic_datatree.AddExternalFunction(symb_id, dynamic_arguments);
|
||||
}
|
||||
|
||||
int
|
||||
ExternalFunctionNode::maxEndoLead() const
|
||||
{
|
||||
|
@ -3936,6 +4121,33 @@ ExternalFunctionNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id
|
|||
return false;
|
||||
}
|
||||
|
||||
expr_t
|
||||
ExternalFunctionNode::replaceTrendVar() const
|
||||
{
|
||||
vector<expr_t> arguments_subst;
|
||||
for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++)
|
||||
arguments_subst.push_back((*it)->replaceTrendVar());
|
||||
return buildSimilarExternalFunctionNode(arguments_subst, datatree);
|
||||
}
|
||||
|
||||
expr_t
|
||||
ExternalFunctionNode::detrend(int symb_id, expr_t trend) const
|
||||
{
|
||||
vector<expr_t> arguments_subst;
|
||||
for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++)
|
||||
arguments_subst.push_back((*it)->detrend(symb_id, trend));
|
||||
return buildSimilarExternalFunctionNode(arguments_subst, datatree);
|
||||
}
|
||||
|
||||
expr_t
|
||||
ExternalFunctionNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const
|
||||
{
|
||||
vector<expr_t> arguments_subst;
|
||||
for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++)
|
||||
arguments_subst.push_back((*it)->removeTrendLeadLag(trend_symbols_map));
|
||||
return buildSimilarExternalFunctionNode(arguments_subst, datatree);
|
||||
}
|
||||
|
||||
FirstDerivExternalFunctionNode::FirstDerivExternalFunctionNode(DataTree &datatree_arg,
|
||||
int top_level_symb_id_arg,
|
||||
const vector<expr_t> &arguments_arg,
|
||||
|
|
40
ExprNode.hh
40
ExprNode.hh
|
@ -356,6 +356,22 @@ public:
|
|||
*/
|
||||
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] expr_t indicating the trend
|
||||
\param[out] expr_t the new binary op pointing to a detrended variable
|
||||
*/
|
||||
virtual expr_t detrend(int symb_id, expr_t trend) const = 0;
|
||||
|
||||
//! Add ExprNodes to the provided datatree
|
||||
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const = 0;
|
||||
|
||||
//! Move a trend variable with lag/lead to time t by dividing/multiplying by its growth factor
|
||||
virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const = 0;
|
||||
};
|
||||
|
||||
//! Object used to compare two nodes (using their indexes)
|
||||
|
@ -405,6 +421,10 @@ public:
|
|||
virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
|
||||
virtual bool isNumConstNodeEqualTo(double value) const;
|
||||
virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
|
||||
virtual expr_t replaceTrendVar() const;
|
||||
virtual expr_t detrend(int symb_id, expr_t trend) const;
|
||||
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
|
||||
virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
|
||||
};
|
||||
|
||||
//! Symbol or variable node
|
||||
|
@ -458,6 +478,10 @@ public:
|
|||
virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
|
||||
virtual bool isNumConstNodeEqualTo(double value) const;
|
||||
virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
|
||||
virtual expr_t replaceTrendVar() const;
|
||||
virtual expr_t detrend(int symb_id, expr_t trend) const;
|
||||
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
|
||||
virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
|
||||
};
|
||||
|
||||
//! Unary operator node
|
||||
|
@ -523,6 +547,10 @@ public:
|
|||
virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
|
||||
virtual bool isNumConstNodeEqualTo(double value) const;
|
||||
virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
|
||||
virtual expr_t replaceTrendVar() const;
|
||||
virtual expr_t detrend(int symb_id, expr_t trend) const;
|
||||
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
|
||||
virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
|
||||
};
|
||||
|
||||
//! Binary operator node
|
||||
|
@ -593,6 +621,10 @@ public:
|
|||
virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
|
||||
virtual bool isNumConstNodeEqualTo(double value) const;
|
||||
virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
|
||||
virtual expr_t replaceTrendVar() const;
|
||||
virtual expr_t detrend(int symb_id, expr_t trend) const;
|
||||
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
|
||||
virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
|
||||
};
|
||||
|
||||
//! Trinary operator node
|
||||
|
@ -645,6 +677,10 @@ public:
|
|||
virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
|
||||
virtual bool isNumConstNodeEqualTo(double value) const;
|
||||
virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
|
||||
virtual expr_t replaceTrendVar() const;
|
||||
virtual expr_t detrend(int symb_id, expr_t trend) const;
|
||||
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
|
||||
virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
|
||||
};
|
||||
|
||||
//! External function node
|
||||
|
@ -703,6 +739,10 @@ public:
|
|||
virtual bool isNumConstNodeEqualTo(double value) const;
|
||||
virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
|
||||
virtual void writePrhs(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms, const string &ending) const;
|
||||
virtual expr_t replaceTrendVar() const;
|
||||
virtual expr_t detrend(int symb_id, expr_t trend) const;
|
||||
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
|
||||
virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
|
||||
};
|
||||
|
||||
class FirstDerivExternalFunctionNode : public ExternalFunctionNode
|
||||
|
|
13
ModFile.cc
13
ModFile.cc
|
@ -25,10 +25,11 @@
|
|||
|
||||
ModFile::ModFile() : expressions_tree(symbol_table, num_constants, external_functions_table),
|
||||
dynamic_model(symbol_table, num_constants, external_functions_table),
|
||||
trend_dynamic_model(symbol_table, num_constants, external_functions_table),
|
||||
static_model(symbol_table, num_constants, external_functions_table),
|
||||
steady_state_model(symbol_table, num_constants, external_functions_table, static_model),
|
||||
linear(false), block(false), byte_code(false),
|
||||
use_dll(false), no_static(false)
|
||||
use_dll(false), no_static(false), nonstationary_variables(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -212,6 +213,13 @@ ModFile::transformPass()
|
|||
if (symbol_table.predeterminedNbr() > 0)
|
||||
dynamic_model.transformPredeterminedVariables();
|
||||
|
||||
if (nonstationary_variables)
|
||||
{
|
||||
dynamic_model.detrendEquations();
|
||||
dynamic_model.cloneDynamic(trend_dynamic_model);
|
||||
dynamic_model.removeTrendVariableFromEquations();
|
||||
}
|
||||
|
||||
// Create auxiliary vars for Expectation operator
|
||||
dynamic_model.substituteExpectation(mod_file_struct.partial_information);
|
||||
|
||||
|
@ -295,6 +303,9 @@ ModFile::computingPass(bool no_tmp_terms)
|
|||
|| mod_file_struct.ramsey_policy_present || mod_file_struct.identification_present;
|
||||
if (dynamic_model.equation_number() > 0)
|
||||
{
|
||||
if (nonstationary_variables)
|
||||
trend_dynamic_model.runTrendTest(global_eval_context);
|
||||
|
||||
// Compute static model and its derivatives
|
||||
dynamic_model.toStatic(static_model);
|
||||
if(!no_static)
|
||||
|
|
|
@ -50,6 +50,8 @@ public:
|
|||
DataTree expressions_tree;
|
||||
//! Dynamic model, as declared in the "model" block
|
||||
DynamicModel dynamic_model;
|
||||
//! A copy of Dynamic model, for testing trends declared by user
|
||||
DynamicModel trend_dynamic_model;
|
||||
//! Static model, as derived from the "model" block when leads and lags have been removed
|
||||
StaticModel static_model;
|
||||
//! Static model, as declared in the "steady_state_model" block if present
|
||||
|
@ -69,6 +71,9 @@ public:
|
|||
//! Is the static model have to computed (no_static=false) or not (no_static=true). Option of 'model'
|
||||
bool no_static;
|
||||
|
||||
//! Are nonstationary variables present ?
|
||||
bool nonstationary_variables;
|
||||
|
||||
//! Global evaluation context
|
||||
/*! Filled using initval blocks and parameters initializations */
|
||||
eval_context_t global_eval_context;
|
||||
|
|
26
ModelTree.cc
26
ModelTree.cc
|
@ -1362,3 +1362,29 @@ ModelTree::addAuxEquation(expr_t eq)
|
|||
|
||||
aux_equations.push_back(beq);
|
||||
}
|
||||
|
||||
void
|
||||
ModelTree::addTrendVariables(vector<int> trend_vars, expr_t growth_factor) throw (TrendException)
|
||||
{
|
||||
while (!trend_vars.empty())
|
||||
if (trend_symbols_map.find(trend_vars.back()) != trend_symbols_map.end())
|
||||
throw TrendException(symbol_table.getName(trend_vars.back()));
|
||||
else
|
||||
{
|
||||
trend_symbols_map[trend_vars.back()] = growth_factor;
|
||||
trend_vars.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ModelTree::addNonstationaryVariables(vector<int> nonstationary_vars, expr_t deflator) throw (TrendException)
|
||||
{
|
||||
while (!nonstationary_vars.empty())
|
||||
if (nonstationary_symbols_map.find(nonstationary_vars.back()) != nonstationary_symbols_map.end())
|
||||
throw TrendException(symbol_table.getName(nonstationary_vars.back()));
|
||||
else
|
||||
{
|
||||
nonstationary_symbols_map[nonstationary_vars.back()] = deflator;
|
||||
nonstationary_vars.pop_back();
|
||||
}
|
||||
}
|
||||
|
|
12
ModelTree.hh
12
ModelTree.hh
|
@ -45,12 +45,14 @@ typedef vector< pair<pair<int, int>, pair< int, expr_t > > > block_derivatives_e
|
|||
//! for all blocks derivatives description
|
||||
typedef vector<block_derivatives_equation_variable_laglead_nodeid_t> blocks_derivatives_t;
|
||||
|
||||
//! for all trends
|
||||
typedef map<int, expr_t> trend_symbols_map_t;
|
||||
|
||||
//! Shared code for static and dynamic models
|
||||
class ModelTree : public DataTree
|
||||
{
|
||||
friend class DynamicModel;
|
||||
friend class StaticModel;
|
||||
|
||||
protected:
|
||||
//! Stores declared and generated auxiliary equations
|
||||
vector<BinaryOpNode *> equations;
|
||||
|
@ -92,6 +94,10 @@ protected:
|
|||
|
||||
//! Temporary terms (those which will be noted Txxxx)
|
||||
temporary_terms_t temporary_terms;
|
||||
//! Trend variables and their growth factors
|
||||
trend_symbols_map_t trend_symbols_map;
|
||||
//! Nonstationary variables and their deflators
|
||||
trend_symbols_map_t nonstationary_symbols_map;
|
||||
|
||||
//! Computes 1st derivatives
|
||||
/*! \param vars the derivation IDs w.r. to which compute the derivatives */
|
||||
|
@ -233,6 +239,10 @@ public:
|
|||
void addAuxEquation(expr_t eq);
|
||||
//! Returns the number of equations in the model
|
||||
int equation_number() const;
|
||||
//! Adds a trend variable with its growth factor
|
||||
void addTrendVariables(vector<int> trend_vars, expr_t growth_factor) throw (TrendException);
|
||||
//! Adds a nonstationary variable with its deflator
|
||||
void addNonstationaryVariables(vector<int> nonstationary_vars, expr_t deflator) throw (TrendException);
|
||||
|
||||
inline static std::string
|
||||
c_Equation_Type(int type)
|
||||
|
|
|
@ -164,6 +164,37 @@ ParsingDriver::declare_parameter(string *name, string *tex_name)
|
|||
delete tex_name;
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::begin_trend()
|
||||
{
|
||||
set_current_data_tree(&mod_file->dynamic_model);
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::declare_trend_var(string *name, string *tex_name)
|
||||
{
|
||||
declare_symbol(name, eTrend, tex_name);
|
||||
declared_trend_vars.push_back(mod_file->symbol_table.getID(*name));
|
||||
delete name;
|
||||
if (tex_name != NULL)
|
||||
delete tex_name;
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::end_trend_var(expr_t growth_factor)
|
||||
{
|
||||
try
|
||||
{
|
||||
dynamic_model->addTrendVariables(declared_trend_vars, growth_factor);
|
||||
}
|
||||
catch (DataTree::TrendException &e)
|
||||
{
|
||||
error("Trend variable " + e.name + " was declared twice.");
|
||||
}
|
||||
declared_trend_vars.clear();
|
||||
reset_data_tree();
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::add_predetermined_variable(string *name)
|
||||
{
|
||||
|
@ -260,6 +291,32 @@ ParsingDriver::add_expression_variable(string *name)
|
|||
return id;
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::declare_nonstationary_var(string *name, string *tex_name)
|
||||
{
|
||||
declare_endogenous(new string(*name), tex_name);
|
||||
declared_nonstationary_vars.push_back(mod_file->symbol_table.getID(*name));
|
||||
mod_file->nonstationary_variables = true;
|
||||
delete name;
|
||||
if (tex_name != NULL)
|
||||
delete tex_name;
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::end_nonstationary_var(expr_t deflator)
|
||||
{
|
||||
try
|
||||
{
|
||||
dynamic_model->addNonstationaryVariables(declared_nonstationary_vars, deflator);
|
||||
}
|
||||
catch (DataTree::TrendException &e)
|
||||
{
|
||||
error("Variable " + e.name + " was listed more than once as following a trend.");
|
||||
}
|
||||
declared_nonstationary_vars.clear();
|
||||
reset_data_tree();
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::periods(string *periods)
|
||||
{
|
||||
|
|
|
@ -163,6 +163,10 @@ private:
|
|||
int current_external_function_id;
|
||||
//! Temporary storage for option list provided to external_function()
|
||||
ExternalFunctionsTable::external_function_options current_external_function_options;
|
||||
//! Temporary storage for declaring trend variables
|
||||
vector<int> declared_trend_vars;
|
||||
//! Temporary storage for declaring nonstationary variables
|
||||
vector<int> declared_nonstationary_vars;
|
||||
//! reset the values for temporary storage
|
||||
void reset_current_external_function_options();
|
||||
//! Adds a model lagged variable to ModelTree and VariableTable
|
||||
|
@ -502,6 +506,16 @@ public:
|
|||
void begin_steady_state_model();
|
||||
//! Add an assignment equation in steady_state_model block
|
||||
void add_steady_state_model_equal(string *varname, expr_t expr);
|
||||
//! Switches datatree
|
||||
void begin_trend();
|
||||
//! Declares a trend variable with its growth factor
|
||||
void declare_trend_var(string *name, string *tex_name = NULL);
|
||||
//! Ends declaration of trend variable
|
||||
void end_trend_var(expr_t growth_factor);
|
||||
//! Declares a nonstationary variable with its deflator
|
||||
void declare_nonstationary_var(string *name, string *tex_name = NULL);
|
||||
//! Ends declaration of nonstationary variable
|
||||
void end_nonstationary_var(expr_t deflator);
|
||||
};
|
||||
|
||||
#endif // ! PARSING_DRIVER_HH
|
||||
|
|
|
@ -433,3 +433,14 @@ SymbolTable::getObservedVariableIndex(int symb_id) const
|
|||
assert(it != varobs.end());
|
||||
return (int) (it - varobs.begin());
|
||||
}
|
||||
|
||||
vector <int>
|
||||
SymbolTable::getTrendVarIds() const
|
||||
{
|
||||
vector <int> trendVars;
|
||||
for (symbol_table_type::const_iterator it = symbol_table.begin();
|
||||
it != symbol_table.end(); it++)
|
||||
if (getType(it->second) == eTrend)
|
||||
trendVars.push_back(it->second);
|
||||
return trendVars;
|
||||
}
|
||||
|
|
|
@ -261,6 +261,7 @@ public:
|
|||
bool isObservedVariable(int symb_id) const;
|
||||
//! Return the index of a given observed variable in the vector of all observed variables
|
||||
int getObservedVariableIndex(int symb_id) const;
|
||||
vector <int> getTrendVarIds() const;
|
||||
};
|
||||
|
||||
inline bool
|
||||
|
|
Loading…
Reference in New Issue