diff --git a/doc/dynare.texi b/doc/dynare.texi index e1fd29cb1..d2d751057 100644 --- a/doc/dynare.texi +++ b/doc/dynare.texi @@ -364,7 +364,7 @@ If you want to give a URL, use the address of the Dynare website: @node Software requirements @section Software requirements -Packaged versions of Dynare are available for Windows XP/Vista/Seven, +Packaged versions of Dynare are available for Windows XP/Vista/7/8, @uref{http://www.debian.org,Debian GNU/Linux}, @uref{http://www.ubuntu.com/,Ubuntu} and Mac OS X Leopard/Snow Leopard. Dynare should work on other systems, but some compilation @@ -884,6 +884,7 @@ Declarations of variables and parameters are made with the following commands: @deffn Command var @var{VARIABLE_NAME} [$@var{LATEX_NAME}$]@dots{}; @deffnx Command var (deflator = @var{MODEL_EXPRESSION}) @var{VARIABLE_NAME} [$@var{LATEX_NAME}$]@dots{}; +@deffnx Command var (log_deflator = @var{MODEL_EXPRESSION}) @var{VARIABLE_NAME} [$@var{LATEX_NAME}$]@dots{}; @descriptionhead @@ -910,7 +911,15 @@ trend. The expression used to detrend an endogenous variable. All trend variables, endogenous variables and parameters referenced in @var{MODEL_EXPRESSION} must already have been declared by the -@code{trend_var}, @code{var} and @code{parameters} commands. +@code{trend_var}, @code{log_trend_var}, @code{var} and +@code{parameters} commands. The deflator is assumed to be +multiplicative; for an additive deflator, use @code{log_deflator}. + +@item log_deflator = @var{MODEL_EXPRESSION} +Same as @code{deflator}, except that the deflator is assumed to be +additive instead of multiplicative (or, to put it otherwise, the +declared variable is equal to the log of a variable with a +multiplicative trend). @end table @examplehead @@ -1093,6 +1102,9 @@ model. @xref{Conventions}, for the syntax of @var{MODEL_EXPRESSION} and @var{VARIABLE_NAME}. Optionally it is possible to give a LaTeX name to the variable. +The variable is assumed to have a multiplicative growth trend. For an +additive growth trend, use @code{log_trend_var} instead. + Trend variables are required if the user wants to be able to write a nonstationary model in the @code{model} block. The @code{trend_var} command must appear before the @code{var} command that references the @@ -1117,6 +1129,17 @@ trend_var (growth_factor=gA) A; @end deffn +@deffn Command log_trend_var (log_growth_factor = @var{MODEL_EXPRESSION}) @var{VARIABLE_NAME} [$@var{LATEX_NAME}$]@dots{}; + +@descriptionhead + +Same as @code{trend_var}, except that the variable is supposed to have +an additive trend (or, to put it otherwise, to be equal to the log of +a variable with a multiplicative trend). + +@end deffn + + @node Expressions @section Expressions @@ -7265,7 +7288,7 @@ is @file{$HOME/.dynare}, while on Windows it is @file{%APPDATA%\dynare.ini} (typically @file{C:\Documents and Settings\@var{USERNAME}\Application Data\dynare.ini} under Windows XP, or @file{C:\Users\@var{USERNAME}\AppData\dynare.ini} under Windows -Vista or Windows 7). You can specify a non standard location using the +Vista/7/8). You can specify a non standard location using the @code{conffile} option of the @code{dynare} command (@pxref{Dynare invocation}). diff --git a/preprocessor/CodeInterpreter.hh b/preprocessor/CodeInterpreter.hh index f4b7979d9..f8b591a64 100644 --- a/preprocessor/CodeInterpreter.hh +++ b/preprocessor/CodeInterpreter.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2011 Dynare Team + * Copyright (C) 2007-2013 Dynare Team * * This file is part of Dynare. * @@ -148,7 +148,8 @@ enum SymbolType eModFileLocalVariable = 11, //!< Local variable whose scope is mod file (model excluded) eExternalFunction = 12, //!< External (user-defined) function eTrend = 13, //!< Trend variable - eStatementDeclaredVariable = 14 //!< Local variable assigned within a Statement (see subsample statement for example) + eStatementDeclaredVariable = 14, //!< Local variable assigned within a Statement (see subsample statement for example) + eLogTrend = 15 //!< Log-trend variable }; enum ExpressionType diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc index 6b5f2433a..e4baa26ff 100644 --- a/preprocessor/DynamicModel.cc +++ b/preprocessor/DynamicModel.cc @@ -3532,6 +3532,7 @@ DynamicModel::computeDerivIDs() equations[i]->collectVariables(eExogenousDet, dynvars); equations[i]->collectVariables(eParameter, dynvars); equations[i]->collectVariables(eTrend, dynvars); + equations[i]->collectVariables(eLogTrend, dynvars); } for (set >::const_iterator it = dynvars.begin(); @@ -3657,6 +3658,7 @@ DynamicModel::computeDynJacobianCols(bool jacobianExo) break; case eParameter: case eTrend: + case eLogTrend: // We don't assign a dynamic jacobian column to parameters or trend variables break; default: @@ -3692,21 +3694,21 @@ 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) + if (symbol_table.getType(it->first.first) == eTrend + || symbol_table.getType(it->first.first) == eLogTrend) 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) + if (fabs(nearZero) > ZERO_BAND) { - cerr << "ERROR: the second-order cross partial of equation " << eq + 1 << " w.r.t. trend variable " + cerr << "ERROR: trends not compatible with balanced growth path; 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); @@ -3715,19 +3717,6 @@ DynamicModel::testTrendDerivativesEqualToZero(const eval_context_t &eval_context } } -void -DynamicModel::print_trend_vars() -{ - for (trend_symbols_map_t::const_iterator it = nonstationary_symbols_map.begin(); - it != nonstationary_symbols_map.end(); it++) - { - cout << "it->first:" << symbol_table.getName(it->first) << " "; - it->second->print_deflator(); - cout << endl; - } - -} - void DynamicModel::writeParamsDerivativesFile(const string &basename) const { @@ -4109,11 +4098,11 @@ DynamicModel::transformPredeterminedVariables() void DynamicModel::detrendEquations() { - for (trend_symbols_map_t::const_iterator it = nonstationary_symbols_map.begin(); + for (nonstationary_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(equations[i]->detrend(it->first, it->second)); + BinaryOpNode *substeq = dynamic_cast(equations[i]->detrend(it->first, it->second.first, it->second.second)); assert(substeq != NULL); equations[i] = dynamic_cast(substeq); } diff --git a/preprocessor/DynamicModel.hh b/preprocessor/DynamicModel.hh index eeb8f59b9..8bfde5079 100644 --- a/preprocessor/DynamicModel.hh +++ b/preprocessor/DynamicModel.hh @@ -230,7 +230,6 @@ public: virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException); virtual int getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException); virtual void addAllParamDerivId(set &deriv_id_set); - void print_trend_vars(); //! Returns true indicating that this is a dynamic model virtual bool diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy index 9165dfc64..0648cc470 100644 --- a/preprocessor/DynareBison.yy +++ b/preprocessor/DynareBison.yy @@ -110,7 +110,7 @@ class ParsingDriver; %token INV_GAMMA_PDF INV_GAMMA1_PDF INV_GAMMA2_PDF IRF IRF_SHOCKS %token KALMAN_ALGO KALMAN_TOL SUBSAMPLES OPTIONS %token LABELS LAPLACE LIK_ALGO LIK_INIT LINEAR LOAD_IDENT_FILES LOAD_MH_FILE LOAD_PARAMS_AND_STEADY_STATE LOGLINEAR LYAPUNOV -%token LYAPUNOV_FIXED_POINT_TOL LYAPUNOV_DOUBLING_TOL LYAPUNOV_SQUARE_ROOT_SOLVER_TOL MARKOWITZ MARGINAL_DENSITY MAX MAXIT +%token LYAPUNOV_FIXED_POINT_TOL LYAPUNOV_DOUBLING_TOL LYAPUNOV_SQUARE_ROOT_SOLVER_TOL LOG_DEFLATOR LOG_TREND_VAR LOG_GROWTH_FACTOR MARKOWITZ MARGINAL_DENSITY MAX MAXIT %token MFS MH_DROP MH_INIT_SCALE MH_JSCALE MH_MODE MH_NBLOCKS MH_REPLIC MH_RECOVER MIN MINIMAL_SOLVING_PERIODS SOLVE_MAXIT %token MODE_CHECK MODE_COMPUTE MODE_FILE MODEL MODEL_COMPARISON MODEL_INFO MSHOCKS ABS SIGN %token MODEL_DIAGNOSTICS MODIFIEDHARMONICMEAN MOMENTS_VARENDO DIFFUSE_FILTER SUB_DRAWS @@ -262,6 +262,7 @@ statement : parameters | external_function | steady_state_model | trend_var + | log_trend_var | ms_estimation | ms_simulation | ms_compute_mdd @@ -287,22 +288,42 @@ trend_var : TREND_VAR '(' GROWTH_FACTOR EQUAL { driver.begin_trend(); } hand_sid ; trend_var_list : trend_var_list symbol - { driver.declare_trend_var($2); } + { driver.declare_trend_var(false, $2); } | trend_var_list COMMA symbol - { driver.declare_trend_var($3); } + { driver.declare_trend_var(false, $3); } | symbol - { driver.declare_trend_var($1); } + { driver.declare_trend_var(false, $1); } | trend_var_list symbol TEX_NAME - { driver.declare_trend_var($2, $3); } + { driver.declare_trend_var(false, $2, $3); } | trend_var_list COMMA symbol TEX_NAME - { driver.declare_trend_var($3, $4); } + { driver.declare_trend_var(false, $3, $4); } | symbol TEX_NAME - { driver.declare_trend_var($1, $2); } + { driver.declare_trend_var(false, $1, $2); } ; +log_trend_var : LOG_TREND_VAR '(' LOG_GROWTH_FACTOR EQUAL { driver.begin_trend(); } hand_side ')' log_trend_var_list ';' + { driver.end_trend_var($6); } + ; + +log_trend_var_list : log_trend_var_list symbol + { driver.declare_trend_var(true, $2); } + | log_trend_var_list COMMA symbol + { driver.declare_trend_var(true, $3); } + | symbol + { driver.declare_trend_var(true, $1); } + | log_trend_var_list symbol TEX_NAME + { driver.declare_trend_var(true, $2, $3); } + | log_trend_var_list COMMA symbol TEX_NAME + { driver.declare_trend_var(true, $3, $4); } + | symbol TEX_NAME + { driver.declare_trend_var(true, $1, $2); } + ; + var : VAR var_list ';' | VAR '(' DEFLATOR EQUAL { driver.begin_trend(); } hand_side ')' nonstationary_var_list ';' - { driver.end_nonstationary_var($6); } + { driver.end_nonstationary_var(false, $6); } + | VAR '(' LOG_DEFLATOR EQUAL { driver.begin_trend(); } hand_side ')' nonstationary_var_list ';' + { driver.end_nonstationary_var(true, $6); } ; nonstationary_var_list : nonstationary_var_list symbol diff --git a/preprocessor/DynareFlex.ll b/preprocessor/DynareFlex.ll index a86ab4e4e..755bdbe4a 100644 --- a/preprocessor/DynareFlex.ll +++ b/preprocessor/DynareFlex.ll @@ -103,6 +103,7 @@ string eofbuff; varexo {BEGIN DYNARE_STATEMENT; return token::VAREXO;} varexo_det {BEGIN DYNARE_STATEMENT; return token::VAREXO_DET;} trend_var {BEGIN DYNARE_STATEMENT; return token::TREND_VAR;} +log_trend_var {BEGIN DYNARE_STATEMENT; return token::LOG_TREND_VAR;} predetermined_variables {BEGIN DYNARE_STATEMENT; return token::PREDETERMINED_VARIABLES;} parameters {BEGIN DYNARE_STATEMENT; return token::PARAMETERS;} periods {BEGIN DYNARE_STATEMENT; return token::PERIODS;} @@ -467,7 +468,9 @@ string eofbuff; selected_variables_only {return token::SELECTED_VARIABLES_ONLY; } pruning {return token::PRUNING; } deflator {return token::DEFLATOR;} +log_deflator {return token::LOG_DEFLATOR;} growth_factor {return token::GROWTH_FACTOR;} +log_growth_factor {return token::LOG_GROWTH_FACTOR;} cova_compute {return token::COVA_COMPUTE;} discretionary_tol {return token::DISCRETIONARY_TOL;} analytic_derivation {return token::ANALYTIC_DERIVATION;} diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc index 494507d96..8743cf8ee 100644 --- a/preprocessor/ExprNode.cc +++ b/preprocessor/ExprNode.cc @@ -175,64 +175,6 @@ ExprNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output // Nothing to do } -void -ExprNode::print_deflator() -{ - -} - - -void -VariableNode::print_deflator() -{ - cout << datatree.symbol_table.getName(symb_id); -} - - -void -UnaryOpNode::print_deflator() -{ - arg->print_deflator(); -} - -void -BinaryOpNode::print_deflator() -{ - arg1->print_deflator(); - arg2->print_deflator(); -} - - -void -TrinaryOpNode::print_deflator() -{ - arg1->print_deflator(); - arg2->print_deflator(); - arg3->print_deflator(); -} - - -void -ExternalFunctionNode::print_deflator() -{ - -} - - -void -FirstDerivExternalFunctionNode::print_deflator() -{ - -} - - -void -SecondDerivExternalFunctionNode::print_deflator() -{ - -} - - void ExprNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, @@ -355,12 +297,6 @@ NumConstNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, t temporary_terms_inuse.insert(idx); } -void -NumConstNode::print_deflator() -{ - -} - void NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -528,7 +464,7 @@ NumConstNode::replaceTrendVar() const } expr_t -NumConstNode::detrend(int symb_id, expr_t trend) const +NumConstNode::detrend(int symb_id, bool log_trend, expr_t trend) const { return const_cast(this); } @@ -569,6 +505,7 @@ VariableNode::prepareForDerivation() case eExogenousDet: case eParameter: case eTrend: + case eLogTrend: // 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; @@ -597,6 +534,7 @@ VariableNode::computeDerivative(int deriv_id) case eExogenousDet: case eParameter: case eTrend: + case eLogTrend: if (deriv_id == datatree.getDerivID(symb_id, lag)) return datatree.One; else @@ -649,7 +587,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 == eTrend)) + && (type == eEndogenous || type == eExogenous || type == eExogenousDet || type == eModelLocalVariable || type == eTrend || type == eLogTrend)) { output << "_{t"; if (lag != 0) @@ -821,6 +759,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case eExternalFunction: case eTrend: + case eLogTrend: case eStatementDeclaredVariable: cerr << "Impossible case" << endl; exit(EXIT_FAILURE); @@ -974,6 +913,7 @@ VariableNode::getChainRuleDerivative(int deriv_id, const map &recur case eExogenousDet: case eParameter: case eTrend: + case eLogTrend: if (deriv_id == datatree.getDerivID(symb_id, lag)) return datatree.One; else @@ -1108,6 +1048,7 @@ VariableNode::decreaseLeadsLags(int n) const case eExogenous: case eExogenousDet: case eTrend: + case eLogTrend: return datatree.AddVariable(symb_id, lag-n); case eModelLocalVariable: return datatree.local_variables_table[symb_id]->decreaseLeadsLags(n); @@ -1312,43 +1253,76 @@ VariableNode::replaceTrendVar() const { if (get_type() == eTrend) return datatree.One; + else if (get_type() == eLogTrend) + return datatree.Zero; else return const_cast(this); } expr_t -VariableNode::detrend(int symb_id, expr_t trend) const +VariableNode::detrend(int symb_id, bool log_trend, expr_t trend) const { if (get_symb_id() != symb_id) return const_cast(this); - if (get_lag() == 0) - return datatree.AddTimes(const_cast(this), trend); + if (log_trend) + { + if (get_lag() == 0) + return datatree.AddPlus(const_cast(this), trend); + else + return datatree.AddPlus(const_cast(this), trend->decreaseLeadsLags(-1*get_lag())); + } else - return datatree.AddTimes(const_cast(this), trend->decreaseLeadsLags(-1*get_lag())); + { + if (get_lag() == 0) + return datatree.AddTimes(const_cast(this), trend); + else + return datatree.AddTimes(const_cast(this), trend->decreaseLeadsLags(-1*get_lag())); + } } expr_t VariableNode::removeTrendLeadLag(map trend_symbols_map) const { - if (get_type() != eTrend || get_lag() == 0) + if ((get_type() != eTrend && get_type() != eLogTrend) || get_lag() == 0) return const_cast(this); map::const_iterator it = trend_symbols_map.find(symb_id); expr_t noTrendLeadLagNode = new VariableNode(datatree, it->first, 0); + bool log_trend = get_type() == eLogTrend; + expr_t trend = it->second; + 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); + expr_t growthFactorSequence = trend->decreaseLeadsLags(-1); + if (log_trend) + { + for (int i = 1; i < get_lag(); i++) + growthFactorSequence = datatree.AddPlus(growthFactorSequence, trend->decreaseLeadsLags(-1*(i+1))); + return datatree.AddPlus(noTrendLeadLagNode, growthFactorSequence); + } + else + { + for (int i = 1; i < get_lag(); i++) + growthFactorSequence = datatree.AddTimes(growthFactorSequence, trend->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); + expr_t growthFactorSequence = trend; + if (log_trend) + { + for (int i = 1; i < abs(get_lag()); i++) + growthFactorSequence = datatree.AddPlus(growthFactorSequence, trend->decreaseLeadsLags(i)); + return datatree.AddMinus(noTrendLeadLagNode, growthFactorSequence); + } + else + { + for (int i = 1; i < abs(get_lag()); i++) + growthFactorSequence = datatree.AddTimes(growthFactorSequence, trend->decreaseLeadsLags(i)); + return datatree.AddDivide(noTrendLeadLagNode, growthFactorSequence); + } } } @@ -2433,9 +2407,9 @@ UnaryOpNode::replaceTrendVar() const } expr_t -UnaryOpNode::detrend(int symb_id, expr_t trend) const +UnaryOpNode::detrend(int symb_id, bool log_trend, expr_t trend) const { - expr_t argsubst = arg->detrend(symb_id, trend); + expr_t argsubst = arg->detrend(symb_id, log_trend, trend); return buildSimilarUnaryOpNode(argsubst, datatree); } @@ -3729,10 +3703,10 @@ BinaryOpNode::replaceTrendVar() const } expr_t -BinaryOpNode::detrend(int symb_id, expr_t trend) const +BinaryOpNode::detrend(int symb_id, bool log_trend, expr_t trend) const { - expr_t arg1subst = arg1->detrend(symb_id, trend); - expr_t arg2subst = arg2->detrend(symb_id, trend); + expr_t arg1subst = arg1->detrend(symb_id, log_trend, trend); + expr_t arg2subst = arg2->detrend(symb_id, log_trend, trend); return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); } @@ -4333,11 +4307,11 @@ TrinaryOpNode::replaceTrendVar() const } expr_t -TrinaryOpNode::detrend(int symb_id, expr_t trend) const +TrinaryOpNode::detrend(int symb_id, bool log_trend, 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); + expr_t arg1subst = arg1->detrend(symb_id, log_trend, trend); + expr_t arg2subst = arg2->detrend(symb_id, log_trend, trend); + expr_t arg3subst = arg3->detrend(symb_id, log_trend, trend); return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree); } @@ -4919,11 +4893,11 @@ ExternalFunctionNode::replaceTrendVar() const } expr_t -ExternalFunctionNode::detrend(int symb_id, expr_t trend) const +ExternalFunctionNode::detrend(int symb_id, bool log_trend, expr_t trend) const { vector arguments_subst; for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) - arguments_subst.push_back((*it)->detrend(symb_id, trend)); + arguments_subst.push_back((*it)->detrend(symb_id, log_trend, trend)); return buildSimilarExternalFunctionNode(arguments_subst, datatree); } diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh index 1cf066fd3..47f7155c3 100644 --- a/preprocessor/ExprNode.hh +++ b/preprocessor/ExprNode.hh @@ -284,7 +284,6 @@ public: //! Returns the relative period of the most forward term in this expression /*! A negative value means that the expression contains only lagged variables */ virtual int maxLead() const = 0; - virtual void print_deflator(); //! Returns a new expression where all the leads/lags have been shifted backwards by the same amount /*! @@ -390,10 +389,11 @@ public: //! 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 + \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, expr_t trend) const = 0; + virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const = 0; //! Add ExprNodes to the provided datatree virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const = 0; @@ -453,10 +453,9 @@ public: virtual bool containsEndogenous(void) 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 detrend(int symb_id, bool log_trend, expr_t trend) const; virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; - virtual void print_deflator(); }; //! Symbol or variable node @@ -485,7 +484,6 @@ public: virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; virtual expr_t toStatic(DataTree &static_datatree) const; - virtual void print_deflator(); SymbolType get_type() const { @@ -516,7 +514,7 @@ public: virtual bool containsEndogenous(void) 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 detrend(int symb_id, bool log_trend, expr_t trend) const; virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; }; @@ -557,7 +555,6 @@ public: virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException, EvalExternalFunctionException); virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); - virtual void print_deflator(); virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; //! Returns operand expr_t @@ -593,7 +590,7 @@ public: virtual bool containsEndogenous(void) 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 detrend(int symb_id, bool log_trend, expr_t trend) const; virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; }; @@ -637,7 +634,6 @@ public: virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; virtual expr_t Compute_RHS(expr_t arg1, expr_t arg2, int op, int op_type) const; - virtual void print_deflator(); //! Returns first operand expr_t get_arg1() const @@ -683,7 +679,7 @@ public: virtual bool containsEndogenous(void) 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 detrend(int symb_id, bool log_trend, expr_t trend) const; virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; //! Function to write out the oPowerNode in expr_t terms as opposed to writing out the function itself @@ -738,7 +734,6 @@ public: virtual int maxEndoLag() const; virtual int maxExoLag() const; virtual int maxLead() const; - virtual void print_deflator(); virtual expr_t decreaseLeadsLags(int n) const; virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; //! Creates another TrinaryOpNode with the same opcode, but with a possibly different datatree and arguments @@ -753,7 +748,7 @@ public: virtual bool containsEndogenous(void) 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 detrend(int symb_id, bool log_trend, expr_t trend) const; virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; }; @@ -803,7 +798,6 @@ public: bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; - virtual void print_deflator(); virtual void compile(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; virtual expr_t toStatic(DataTree &static_datatree) const; @@ -828,7 +822,7 @@ public: 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 detrend(int symb_id, bool log_trend, expr_t trend) const; virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; }; @@ -862,7 +856,6 @@ public: bool lhs_rhs, const temporary_terms_t &temporary_terms, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, deriv_node_temp_terms_t &tef_terms) const; - virtual void print_deflator(); }; class SecondDerivExternalFunctionNode : public ExternalFunctionNode @@ -888,7 +881,6 @@ public: virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; - virtual void print_deflator(); }; #endif diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc index 88f326955..b628c9b39 100644 --- a/preprocessor/ModFile.cc +++ b/preprocessor/ModFile.cc @@ -107,7 +107,6 @@ ModFile::addStatementAtFront(Statement *st) void ModFile::checkPass() { - dynamic_model.print_trend_vars(); for (vector::iterator it = statements.begin(); it != statements.end(); it++) (*it)->checkPass(mod_file_struct, warnings); @@ -375,8 +374,8 @@ ModFile::computingPass(bool no_tmp_terms) // Mod file may have no equation (for example in a standalone BVAR estimation) if (dynamic_model.equation_number() > 0) { - /*if (nonstationary_variables) - trend_dynamic_model.runTrendTest(global_eval_context);*/ + if (nonstationary_variables) + trend_dynamic_model.runTrendTest(global_eval_context); // Compute static model and its derivatives dynamic_model.toStatic(static_model); diff --git a/preprocessor/ModelTree.cc b/preprocessor/ModelTree.cc index 501e29586..33584f868 100644 --- a/preprocessor/ModelTree.cc +++ b/preprocessor/ModelTree.cc @@ -1003,19 +1003,14 @@ ModelTree::computeJacobian(const set &vars) for (set::const_iterator it = vars.begin(); it != vars.end(); it++) { - int prev_deriv = NNZDerivatives[0]; - for (int eq = 0; eq < (int) equations.size(); eq++) - { - expr_t d1 = equations[eq]->getDerivative(*it); - if (d1 == Zero) - continue; - first_derivatives[make_pair(eq, *it)] = d1; - ++NNZDerivatives[0]; - } - if (NNZDerivatives[0] == prev_deriv) - { - cout << "the derivatives w.r. to " << symbol_table.getName(*it) << " is always equal to 0\n"; - } + for (int eq = 0; eq < (int) equations.size(); eq++) + { + expr_t d1 = equations[eq]->getDerivative(*it); + if (d1 == Zero) + continue; + first_derivatives[make_pair(eq, *it)] = d1; + ++NNZDerivatives[0]; + } } } @@ -1418,14 +1413,14 @@ ModelTree::addTrendVariables(vector trend_vars, expr_t growth_factor) throw } void -ModelTree::addNonstationaryVariables(vector nonstationary_vars, expr_t deflator) throw (TrendException) +ModelTree::addNonstationaryVariables(vector nonstationary_vars, bool log_deflator, 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_symbols_map[nonstationary_vars.back()] = make_pair(log_deflator, deflator); nonstationary_vars.pop_back(); } } diff --git a/preprocessor/ModelTree.hh b/preprocessor/ModelTree.hh index 079c5564e..e8a7727fa 100644 --- a/preprocessor/ModelTree.hh +++ b/preprocessor/ModelTree.hh @@ -45,9 +45,6 @@ typedef vector< pair, pair< int, expr_t > > > block_derivatives_e //! for all blocks derivatives description typedef vector blocks_derivatives_t; -//! for all trends -typedef map trend_symbols_map_t; - //! Shared code for static and dynamic models class ModelTree : public DataTree { @@ -136,9 +133,13 @@ protected: //! Trend variables and their growth factors - trend_symbols_map_t trend_symbols_map; + map trend_symbols_map; + + //! for all trends; the boolean is true if this is a log-trend, false otherwise + typedef map > nonstationary_symbols_map_t; + //! Nonstationary variables and their deflators - trend_symbols_map_t nonstationary_symbols_map; + nonstationary_symbols_map_t nonstationary_symbols_map; //! vector of block reordered variables and equations vector equation_reordered, variable_reordered, inv_equation_reordered, inv_variable_reordered; @@ -304,8 +305,8 @@ public: int equation_number() const; //! Adds a trend variable with its growth factor void addTrendVariables(vector trend_vars, expr_t growth_factor) throw (TrendException); - //! Adds a nonstationary variable with its deflator - void addNonstationaryVariables(vector nonstationary_vars, expr_t deflator) throw (TrendException); + //! Adds a nonstationary variables with their (common) deflator + void addNonstationaryVariables(vector nonstationary_vars, bool log_deflator, expr_t deflator) throw (TrendException); void set_cutoff_to_zero(); //! Helper for writing the Jacobian elements in MATLAB and C /*! Writes either (i+1,j+1) or [i+j*no_eq] */ diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc index 9e08e9a93..88c1d4436 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/ParsingDriver.cc @@ -204,9 +204,9 @@ ParsingDriver::begin_trend() } void -ParsingDriver::declare_trend_var(string *name, string *tex_name) +ParsingDriver::declare_trend_var(bool log_trend, string *name, string *tex_name) { - declare_symbol(name, eTrend, tex_name); + declare_symbol(name, log_trend ? eLogTrend : eTrend, tex_name); declared_trend_vars.push_back(mod_file->symbol_table.getID(*name)); delete name; if (tex_name != NULL) @@ -339,11 +339,11 @@ ParsingDriver::declare_nonstationary_var(string *name, string *tex_name) } void -ParsingDriver::end_nonstationary_var(expr_t deflator) +ParsingDriver::end_nonstationary_var(bool log_deflator, expr_t deflator) { try { - dynamic_model->addNonstationaryVariables(declared_nonstationary_vars, deflator); + dynamic_model->addNonstationaryVariables(declared_nonstationary_vars, log_deflator, deflator); } catch (DataTree::TrendException &e) { diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh index 34304ee5a..e6a88fe9a 100644 --- a/preprocessor/ParsingDriver.hh +++ b/preprocessor/ParsingDriver.hh @@ -631,13 +631,13 @@ public: //! Switches datatree void begin_trend(); //! Declares a trend variable with its growth factor - void declare_trend_var(string *name, string *tex_name = NULL); + void declare_trend_var(bool log_trend, 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); + void end_nonstationary_var(bool log_deflator, expr_t deflator); //! Add a graph format to the list of formats requested void add_graph_format(const string &name); //! Add the graph_format option to the OptionsList structure diff --git a/preprocessor/SymbolTable.cc b/preprocessor/SymbolTable.cc index a53dc9a27..9778ce2c6 100644 --- a/preprocessor/SymbolTable.cc +++ b/preprocessor/SymbolTable.cc @@ -502,7 +502,7 @@ SymbolTable::getTrendVarIds() const vector trendVars; for (symbol_table_type::const_iterator it = symbol_table.begin(); it != symbol_table.end(); it++) - if (getType(it->second) == eTrend) + if (getType(it->second) == eTrend || getType(it->second) == eLogTrend) trendVars.push_back(it->second); return trendVars; } diff --git a/tests/.gitignore b/tests/.gitignore index 689f72a33..3fd1bd838 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -5,6 +5,7 @@ *.cod *.c *.tex +*.TeX *.jnl *.swp *.dat diff --git a/tests/Makefile.am b/tests/Makefile.am index 909020f8e..5336a43e9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -146,7 +146,9 @@ MODFILES = \ deterministic_simulations/rbc_det4.mod \ deterministic_simulations/rbc_det5.mod \ walsh.mod \ - measurement_errors/fs2000_corr_me_ml_mcmc/fs2000_corr_ME.mod + measurement_errors/fs2000_corr_me_ml_mcmc/fs2000_corr_ME.mod \ + trend_var/fs2000_nonstationary.mod \ + trend_var/fs2000_log_nonstationary.mod XFAIL_MODFILES = ramst_xfail.mod diff --git a/tests/conditional_forecasts/fs2000_cal.mod b/tests/conditional_forecasts/fs2000_cal.mod index 8dd1d09c3..4b63fd554 100644 --- a/tests/conditional_forecasts/fs2000_cal.mod +++ b/tests/conditional_forecasts/fs2000_cal.mod @@ -13,7 +13,6 @@ rho = 0.7; psi = 0.787; del = 0.02; -//model(block, bytecode); model; dA = exp(gam+e_a); log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m; @@ -57,41 +56,18 @@ steady; check; -//stoch_simul(irf=0); +stoch_simul(irf=0); conditional_forecast_paths; -var gp_obs; -periods 1 2:5; -//values 0.05; -//values 0.98 1.00797; -values 0.98 0.99; -//expectation perfect_foresight; var gy_obs; periods 1 2 3:5; -//values 0.01 -0.02 0; -//values 0.85 0.85 0.95; -values 0.95 0.95 0.99; -//expectation perfect_foresight; +values 0.01 -0.02 0; +var gp_obs; +periods 1:5; +values 0.05; end; -options_.stack_solve_algo = 0; -options_.maxit_ = 50; +conditional_forecast(parameter_set=calibration, controlled_varexo=(e_a,e_m)); -error('Test disabled, enters an infinite loop') +plot_conditional_forecast(periods=10) gy_obs gp_obs; -conditional_forecast(parameter_set=calibration, controlled_varexo=(e_m,e_a), simulation_type = deterministic); - -/*shocks; -var e_a; -periods 1 2 3 4 5; -values -0.0109 -0.0122 -0.0137 -0.0154 -0.0173; -var e_m; -periods 1 2 3 4 5; -values -0.1242 -0.0386 -0.0392 -0.0398 -0.0405; -end; -simul(periods=40);*/ -rplot gy_obs; -rplot gp_obs; -//if ~(exist('OCTAVE_VERSION') && octave_ver_less_than('3.4.0')) -//plot_conditional_forecast(periods=10) gy_obs gp_obs; -//end diff --git a/tests/conditional_forecasts/fs2000_est.mod b/tests/conditional_forecasts/fs2000_est.mod index 86522e24b..6f07765f7 100644 --- a/tests/conditional_forecasts/fs2000_est.mod +++ b/tests/conditional_forecasts/fs2000_est.mod @@ -97,8 +97,6 @@ varobs gp_obs gy_obs; options_.solve_tolf = 1e-12; -error('Test disabled, enters an infinite loop') - // Metropolis replications are too few, this is only for testing purpose estimation(order=1,datafile=fsdat_simul,nobs=192,loglinear,mh_replic=10000,mh_nblocks=1,mh_jscale=0.8); diff --git a/tests/trend_var/fs2000_log_nonstationary.mod b/tests/trend_var/fs2000_log_nonstationary.mod new file mode 100644 index 000000000..51d9a7bdc --- /dev/null +++ b/tests/trend_var/fs2000_log_nonstationary.mod @@ -0,0 +1,85 @@ +/* + * This file is a modified version of 'fs2000.mod'. + * + * The difference is that, here, the equations are written in non-stationary form, + * all variables are taken in logs, and Dynare automatically does the detrending. + * + * Also note that "m" and "dA" in 'fs2000.mod' are here called "gM" and "gA" + */ + +/* + * Copyright (C) 2004-2013 Dynare Team + * + * 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 + * along with Dynare. If not, see . + */ + +var gM gA; +log_trend_var(log_growth_factor=gA) A; +log_trend_var(log_growth_factor=gM) M; +var(log_deflator=A) k c y; +var(log_deflator=M(-1)-A) P; +var(log_deflator=M(-1)) W l d; +var R n; +varexo e_a e_m; + +parameters alp bet gam mst rho psi del; + +alp = 0.33; +bet = 0.99; +gam = 0.003; +mst = 1.011; +rho = 0.7; +psi = 0.787; +del = 0.02; + +model; +gA = gam+e_a; +gM = (1-rho)*log(mst) + rho*gM(-1)+e_m; +exp(c)+exp(k) = exp(k(-1))^alp*(exp(A)*exp(n))^(1-alp)+(1-del)*exp(k(-1)); +P+c = M; +P-(c(+1)+P(+1))=log(bet)+P(+1)+log(alp*exp(k)^(alp-1)*(exp(A(+1)+n(+1)))^(1-alp)+(1-del))-(c(+2)+P(+2)); +log(psi/(1-psi))+(c+P-log(1-exp(n)))=W; +R = P+log(1-alp)+alp*k(-1)+(1-alp)*A+(-alp)*n-W; +W = l-n; +exp(M)-exp(M(-1))+exp(d) = exp(l); +-(c+P)=log(bet)+R-(c(+1)+P(+1)); +y = alp*k(-1)+(1-alp)*(A+n); +end; + +initval; +k = log(6); +gM = log(mst); +P = log(2.25); +c = log(0.45); +W = log(4); +R = log(1.02); +d = log(0.85); +n = log(0.19); +l = log(0.86); +y = log(0.6); +gA = gam; +end; + +shocks; +var e_a; stderr 0.014; +var e_m; stderr 0.005; +end; + +steady; + +check; + +stoch_simul; diff --git a/tests/trend_var/fs2000_nonstationary.mod b/tests/trend_var/fs2000_nonstationary.mod new file mode 100644 index 000000000..575e0bb2e --- /dev/null +++ b/tests/trend_var/fs2000_nonstationary.mod @@ -0,0 +1,85 @@ +/* + * This file is a modified version of 'fs2000.mod'. + * + * The difference is that, here, the equations are written in non-stationary form, + * and Dynare automatically does the detrending. + * + * Also note that "m" and "dA" in 'fs2000.mod' are here called "gM" and "gA" + */ + +/* + * Copyright (C) 2004-2010 Dynare Team + * + * 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 + * along with Dynare. If not, see . + */ + +var gM gA; +trend_var(growth_factor=gA) A; +trend_var(growth_factor=gM) M; +var(deflator=A) k c y; +var(deflator=M(-1)/A) P; +var(deflator=M(-1)) W l d; +var R n; +varexo e_a e_m; + +parameters alp bet gam mst rho psi del; + +alp = 0.33; +bet = 0.99; +gam = 0.003; +mst = 1.011; +rho = 0.7; +psi = 0.787; +del = 0.02; + +model; +gA = exp(gam+e_a); +log(gM) = (1-rho)*log(mst) + rho*log(gM(-1))+e_m; +c+k = k(-1)^alp*(A*n)^(1-alp)+(1-del)*k(-1); +P*c = M; +P/(c(+1)*P(+1))=bet*P(+1)*(alp*k^(alp-1)*(A(+1)*n(+1))^(1-alp)+(1-del))/(c(+2)*P(+2)); +(psi/(1-psi))*(c*P/(1-n))=W; +R = P*(1-alp)*k(-1)^alp*A^(1-alp)*n^(-alp)/W; +W = l/n; +M-M(-1)+d = l; +1/(c*P)=bet*R/(c(+1)*P(+1)); +y = k(-1)^alp*(A*n)^(1-alp); +end; + +initval; +k = 6; +gM = mst; +P = 2.25; +c = 0.45; +W = 4; +R = 1.02; +d = 0.85; +n = 0.19; +l = 0.86; +y = 0.6; +gA = exp(gam); +end; + +shocks; +var e_a; stderr 0.014; +var e_m; stderr 0.005; +end; + +steady; + +check; + +stoch_simul;