Commit 7bbe1217 authored by Sébastien Villemot's avatar Sébastien Villemot
Browse files

Possibility of restricting differentiate_forward_vars to some variables

Closes #351
parent 921e7fda
......@@ -1609,6 +1609,7 @@ Don't create the static model file. This can be useful for models which
don't have a steady state.
@item differentiate_forward_vars
@itemx differentiate_forward_vars = ( @var{VARIABLE_NAME} [@var{VARIABLE_NAME} @dots{}] )
Tells Dynare to create a new auxiliary variable for each endogenous
variable that appears with a lead, such that the new variable is the
time differentiate of the original one. More precisely, if the model
......@@ -1616,6 +1617,11 @@ contains @code{x(+1)}, then a variable @code{AUX_DIFF_VAR} will be
created such that @code{AUX_DIFF_VAR=x-x(-1)}, and @code{x(+1)} will
be replaced with @code{x+AUX_DIFF_VAR(+1)}.
The transformation is applied to all endogenous variables with a lead
if the option is given without a list of variables. If there is a
list, the transformation is restricted to endogenous with a lead that
also appear in the list.
This option can useful for some deterministic simulations where
convergence is hard to obtain. Bad values for terminal conditions in
the case of very persistent dynamics or permanent shocks can hinder
......
......@@ -3924,29 +3924,29 @@ DynamicModel::writeLatexFile(const string &basename) const
void
DynamicModel::substituteEndoLeadGreaterThanTwo(bool deterministic_model)
{
substituteLeadLagInternal(avEndoLead, deterministic_model);
substituteLeadLagInternal(avEndoLead, deterministic_model, vector<string>());
}
void
DynamicModel::substituteEndoLagGreaterThanTwo(bool deterministic_model)
{
substituteLeadLagInternal(avEndoLag, deterministic_model);
substituteLeadLagInternal(avEndoLag, deterministic_model, vector<string>());
}
void
DynamicModel::substituteExoLead(bool deterministic_model)
{
substituteLeadLagInternal(avExoLead, deterministic_model);
substituteLeadLagInternal(avExoLead, deterministic_model, vector<string>());
}
void
DynamicModel::substituteExoLag(bool deterministic_model)
{
substituteLeadLagInternal(avExoLag, deterministic_model);
substituteLeadLagInternal(avExoLag, deterministic_model, vector<string>());
}
void
DynamicModel::substituteLeadLagInternal(aux_var_t type, bool deterministic_model)
DynamicModel::substituteLeadLagInternal(aux_var_t type, bool deterministic_model, const vector<string> &subset)
{
ExprNode::subst_table_t subst_table;
vector<BinaryOpNode *> neweqs;
......@@ -3976,7 +3976,7 @@ DynamicModel::substituteLeadLagInternal(aux_var_t type, bool deterministic_model
subst = value->substituteExoLag(subst_table, neweqs);
break;
case avDiffForward:
subst = value->differentiateForwardVars(subst_table, neweqs);
subst = value->differentiateForwardVars(subset, subst_table, neweqs);
break;
default:
cerr << "DynamicModel::substituteLeadLagInternal: impossible case" << endl;
......@@ -4004,7 +4004,7 @@ DynamicModel::substituteLeadLagInternal(aux_var_t type, bool deterministic_model
subst = equations[i]->substituteExoLag(subst_table, neweqs);
break;
case avDiffForward:
subst = equations[i]->differentiateForwardVars(subst_table, neweqs);
subst = equations[i]->differentiateForwardVars(subset, subst_table, neweqs);
break;
default:
cerr << "DynamicModel::substituteLeadLagInternal: impossible case" << endl;
......@@ -4134,9 +4134,9 @@ DynamicModel::removeTrendVariableFromEquations()
}
void
DynamicModel::differentiateForwardVars()
DynamicModel::differentiateForwardVars(const vector<string> &subset)
{
substituteLeadLagInternal(avDiffForward, true);
substituteLeadLagInternal(avDiffForward, true, subset);
}
void
......
......@@ -139,8 +139,11 @@ private:
void collectBlockVariables();
//! Factorized code for substitutions of leads/lags
/*! \param[in] type determines which type of variables is concerned */
void substituteLeadLagInternal(aux_var_t type, bool deterministic_model);
/*! \param[in] type determines which type of variables is concerned
\param[in] deterministic_model whether we are in a deterministic model (only for exogenous leads/lags)
\param[in] subset variables to which to apply the transformation (only for diff of forward vars)
*/
void substituteLeadLagInternal(aux_var_t type, bool deterministic_model, const vector<string> &subset);
private:
//! Indicate if the temporary terms are computed for the overall model (true) or not (false). Default value true
......@@ -281,7 +284,9 @@ public:
void removeTrendVariableFromEquations();
//! Transforms the model by creating aux vars for the diff of forward vars
void differentiateForwardVars();
/*! If subset is empty, does the transformation for all fwrd vars; otherwise
restrict it to the vars in subset */
void differentiateForwardVars(const vector<string> &subset);
//! Fills eval context with values of model local variables and auxiliary variables
void fillEvalContext(eval_context_t &eval_context) const;
......
......@@ -568,7 +568,8 @@ model_options : BLOCK { driver.block(); }
| BYTECODE { driver.byte_code(); }
| USE_DLL { driver.use_dll(); }
| NO_STATIC { driver.no_static();}
| DIFFERENTIATE_FORWARD_VARS { driver.differentiate_forward_vars(); }
| DIFFERENTIATE_FORWARD_VARS { driver.differentiate_forward_vars_all(); }
| DIFFERENTIATE_FORWARD_VARS EQUAL '(' symbol_list ')' { driver.differentiate_forward_vars_some(); }
| o_linear
;
......
......@@ -431,7 +431,7 @@ NumConstNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOpN
}
expr_t
NumConstNode::differentiateForwardVars(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
NumConstNode::differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
return const_cast<NumConstNode *>(this);
}
......@@ -1225,14 +1225,16 @@ VariableNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOpN
}
expr_t
VariableNode::differentiateForwardVars(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
VariableNode::differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
expr_t value;
switch (type)
{
case eEndogenous:
assert(lag <= 1);
if (lag <= 0)
if (lag <= 0
|| (subset.size() > 0
&& find(subset.begin(), subset.end(), datatree.symbol_table.getName(symb_id)) == subset.end()))
return const_cast<VariableNode *>(this);
else
{
......@@ -1255,7 +1257,7 @@ VariableNode::differentiateForwardVars(subst_table_t &subst_table, vector<Binary
if (value->maxEndoLead() <= 0)
return const_cast<VariableNode *>(this);
else
return value->differentiateForwardVars(subst_table, neweqs);
return value->differentiateForwardVars(subset, subst_table, neweqs);
default:
return const_cast<VariableNode *>(this);
}
......@@ -2339,9 +2341,9 @@ UnaryOpNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNo
}
expr_t
UnaryOpNode::differentiateForwardVars(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
UnaryOpNode::differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
expr_t argsubst = arg->differentiateForwardVars(subst_table, neweqs);
expr_t argsubst = arg->differentiateForwardVars(subset, subst_table, neweqs);
return buildSimilarUnaryOpNode(argsubst, datatree);
}
......@@ -3583,10 +3585,10 @@ BinaryOpNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOpN
expr_t
BinaryOpNode::differentiateForwardVars(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
BinaryOpNode::differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
expr_t arg1subst = arg1->differentiateForwardVars(subst_table, neweqs);
expr_t arg2subst = arg2->differentiateForwardVars(subst_table, neweqs);
expr_t arg1subst = arg1->differentiateForwardVars(subset, subst_table, neweqs);
expr_t arg2subst = arg2->differentiateForwardVars(subset, subst_table, neweqs);
return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
}
......@@ -4200,11 +4202,11 @@ TrinaryOpNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOp
expr_t
TrinaryOpNode::differentiateForwardVars(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
TrinaryOpNode::differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
expr_t arg1subst = arg1->differentiateForwardVars(subst_table, neweqs);
expr_t arg2subst = arg2->differentiateForwardVars(subst_table, neweqs);
expr_t arg3subst = arg3->differentiateForwardVars(subst_table, neweqs);
expr_t arg1subst = arg1->differentiateForwardVars(subset, subst_table, neweqs);
expr_t arg2subst = arg2->differentiateForwardVars(subset, subst_table, neweqs);
expr_t arg3subst = arg3->differentiateForwardVars(subset, subst_table, neweqs);
return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
}
......@@ -4765,11 +4767,11 @@ ExternalFunctionNode::substituteExpectation(subst_table_t &subst_table, vector<B
}
expr_t
ExternalFunctionNode::differentiateForwardVars(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
ExternalFunctionNode::differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
vector<expr_t> arguments_subst;
for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); it++)
arguments_subst.push_back((*it)->differentiateForwardVars(subst_table, neweqs));
arguments_subst.push_back((*it)->differentiateForwardVars(subset, subst_table, neweqs));
return buildSimilarExternalFunctionNode(arguments_subst, datatree);
}
......
......@@ -361,11 +361,13 @@ public:
//! Constructs a new expression where forward variables (supposed to be at most in t+1) have been replaced by themselves at t, plus a new aux var representing their (time) differentiate
/*!
\param[in] subset variables to which to limit the transformation; transform
all fwrd vars if empty
\param[in,out] subst_table Map used to store mapping between a given
forward variable and the aux var that contains its differentiate
\param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
*/
virtual expr_t differentiateForwardVars(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const = 0;
//! Return true if the nodeID is a numerical constant equal to value and false otherwise
/*!
......@@ -452,7 +454,7 @@ public:
virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
virtual expr_t differentiateForwardVars(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual bool isNumConstNodeEqualTo(double value) const;
virtual bool containsEndogenous(void) const;
virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
......@@ -514,7 +516,7 @@ public:
virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
virtual expr_t differentiateForwardVars(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual bool isNumConstNodeEqualTo(double value) const;
virtual bool containsEndogenous(void) const;
virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
......@@ -591,7 +593,7 @@ public:
virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
virtual expr_t differentiateForwardVars(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual bool isNumConstNodeEqualTo(double value) const;
virtual bool containsEndogenous(void) const;
virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
......@@ -681,7 +683,7 @@ public:
virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
virtual expr_t differentiateForwardVars(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual bool isNumConstNodeEqualTo(double value) const;
virtual bool containsEndogenous(void) const;
virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
......@@ -751,7 +753,7 @@ public:
virtual expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
virtual expr_t differentiateForwardVars(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual bool isNumConstNodeEqualTo(double value) const;
virtual bool containsEndogenous(void) const;
virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
......@@ -825,7 +827,7 @@ public:
virtual expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
virtual expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const;
virtual expr_t decreaseLeadsLagsPredeterminedVariables() const;
virtual expr_t differentiateForwardVars(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual expr_t differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual bool isNumConstNodeEqualTo(double value) const;
virtual bool containsEndogenous(void) const;
virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const;
......
......@@ -322,7 +322,7 @@ ModFile::transformPass()
}
if (differentiate_forward_vars)
dynamic_model.differentiateForwardVars();
dynamic_model.differentiateForwardVars(differentiate_forward_vars_subset);
if (mod_file_struct.dsge_var_estimated || !mod_file_struct.dsge_var_calibrated.empty())
try
......
......@@ -78,6 +78,12 @@ public:
//! Is the 'differentiate_forward_vars' option used?
bool differentiate_forward_vars;
/*! If the 'differentiate_forward_vars' option is used, contains the set of
endogenous with respect to which to do the transformation;
if empty, means that the transformation must be applied to all endos
with a lead */
vector<string> differentiate_forward_vars_subset;
//! Are nonstationary variables present ?
bool nonstationary_variables;
......
......@@ -494,11 +494,26 @@ ParsingDriver::byte_code()
}
void
ParsingDriver::differentiate_forward_vars()
ParsingDriver::differentiate_forward_vars_all()
{
mod_file->differentiate_forward_vars = true;
}
void
ParsingDriver::differentiate_forward_vars_some()
{
mod_file->differentiate_forward_vars = true;
mod_file->differentiate_forward_vars_subset = symbol_list.get_symbols();
for (vector<string>::const_iterator it = mod_file->differentiate_forward_vars_subset.begin();
it != mod_file->differentiate_forward_vars_subset.end(); ++it)
{
check_symbol_existence(*it);
if (mod_file->symbol_table.getType(*it) != eEndogenous)
error("Symbol " + *it + " is not an endogenous");
}
symbol_list.clear();
}
void
ParsingDriver::cutoff(string *value)
{
......
......@@ -245,8 +245,10 @@ public:
void byte_code();
//! the static model is not computed
void no_static();
//! the differentiate_forward_vars option is enabled
void differentiate_forward_vars();
//! the differentiate_forward_vars option is enabled (for all vars)
void differentiate_forward_vars_all();
//! the differentiate_forward_vars option is enabled (for a subset of vars)
void differentiate_forward_vars_some();
//! cutoff option of model block
void cutoff(string *value);
//! mfs option of model block
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment