preprocessor:
* fixed a bug with EXPECTATION operator: now handle model local variables * substitute EXPECTATION operator even in deterministic models (for avoiding crashes, even if use of this operator doesn't make sense there) * forbid the use of EXPECTATION and STEADY_STEATE outside model block * minor implementation changes in EXPECTATION and STEADY_STATE operators reference manual: * documented EXPECTATION and STEADY_STATE operators * added a note in write_latex_{static,dynamic}_model commands documentation about auxiliary variables and other model transformations git-svn-id: https://www.dynare.org/svn/dynare/trunk@3145 ac1d8469-bf42-47a9-8791-bf33cf982152time-shift
parent
09f1b60e22
commit
76e691c651
|
@ -729,6 +729,12 @@ end;
|
|||
<listitem><para>binary comparison operators (which evaluate to either <literal>0</literal> or <literal>1</literal>): <literal><</literal>, <literal>></literal>, <literal><=</literal>, <literal>>=</literal>, <literal>==</literal>, <literal>!=</literal></para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>The following operators are allowed in <replaceable>MODEL_EXPRESSION</replaceable>:
|
||||
<itemizedlist>
|
||||
<listitem><para>steady state operator: <literal>STEADY_STATE(</literal><replaceable>MODEL_EXPRESSION</replaceable><literal>)</literal>. This operator is used to take the value of the enclosed expression at the steady state. A typical usage is in the Taylor rule, where you may want to use the value of GDP at steady state to compute the output gap.</para></listitem>
|
||||
<listitem id="expectation_operator"><para>expectation operator: <literal>EXPECTATION(</literal><replaceable>INTEGER</replaceable><literal>)(</literal><replaceable>MODEL_EXPRESSION</replaceable><literal>)</literal>. This operator is used to take the expectation of some expression using a different information set than the information available at current period. For example, <literal>EXPECTATION(-1)(x(+1))</literal> is equal to the expected value of variable <literal>x</literal> at next period, using the information set available at the previous period. In practice, Dynare solves this by creating an auxiliary variable equal to <literal>AUX = x(+2)</literal>, and by replacing the expectation operator by <literal>AUX(-1)</literal>. Note that a value of <literal>0</literal> for the time shift component is reserved for partial information models (not yet fully implemented).</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2><title>Functions</title>
|
||||
|
@ -914,6 +920,16 @@ end;
|
|||
</para>
|
||||
<para>If LaTeX names were given for variables and parameters (see <xref linkend="var"/>, <xref linkend="varexo"/>, <xref linkend="varexo_det"/>, <xref linkend="parameters"/>), then those will be used; otherwise, the plain text names will be used.</para>
|
||||
<para>Time subscripts (<literal>t</literal>, <literal>t+1</literal>, <literal>t-1</literal>, ...) will be appended to the variable names, as LaTeX subscripts.</para>
|
||||
|
||||
<para>
|
||||
Note that the model written in the TeX file will differ from the model declared by the user in the following dimensions:
|
||||
<itemizedlist>
|
||||
<listitem><para>the timing convention of <xref linkend="predetermined_variables"/> will have been changed to the default Dynare timing convention; in other words, variables declared as predetermined will be lagged on period back,</para></listitem>
|
||||
<listitem><para>the <link linkend="expectation_operator">expectation operators</link> will have been removed, replaced by auxiliary variables and new equations as explained in the documentation of the operator,</para></listitem>
|
||||
<listitem><para>for stochastic models, variables with leads or lags greater or equal than two will have been removed, replaced by new auxiliary variables and equations.</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
||||
|
@ -937,6 +953,9 @@ end;
|
|||
<para>If your <filename class="extension">.mod</filename> file is <filename><replaceable>FILENAME</replaceable>.mod</filename>, then Dynare will create a file called <filename><replaceable>FILENAME</replaceable>_static.tex</filename>, containing the list of all the equations of the steady state model.
|
||||
</para>
|
||||
<para>If LaTeX names were given for variables and parameters (see <xref linkend="var"/>, <xref linkend="varexo"/>, <xref linkend="varexo_det"/>, <xref linkend="parameters"/>), then those will be used; otherwise, the plain text names will be used.</para>
|
||||
<para>
|
||||
Note that the model written in the TeX file will differ from the model declared by the user in the some dimensions, see <xref linkend="write_latex_dynamic_model"/>.
|
||||
</para>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
||||
|
|
|
@ -39,8 +39,6 @@ DataTree::DataTree(SymbolTable &symbol_table_arg, NumericalConstants &num_consta
|
|||
MinusInfinity = AddUMinus(Infinity);
|
||||
|
||||
Pi = AddNumConstant("3.141592653589793");
|
||||
|
||||
steady_state_found = false;
|
||||
}
|
||||
|
||||
DataTree::~DataTree()
|
||||
|
@ -418,7 +416,6 @@ DataTree::AddNormcdf(NodeID iArg1, NodeID iArg2, NodeID iArg3)
|
|||
NodeID
|
||||
DataTree::AddSteadyState(NodeID iArg1)
|
||||
{
|
||||
steady_state_found = true;
|
||||
return AddUnaryOp(oSteadyState, iArg1);
|
||||
}
|
||||
|
||||
|
@ -484,3 +481,14 @@ DataTree::getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException)
|
|||
{
|
||||
throw UnknownDerivIDException();
|
||||
}
|
||||
|
||||
bool
|
||||
DataTree::containsSteadyStateOperator() const
|
||||
{
|
||||
for(unary_op_node_map_type::const_iterator it = unary_op_node_map.begin();
|
||||
it != unary_op_node_map.end(); it++)
|
||||
if (it->first.second == oSteadyState)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -54,22 +54,22 @@ protected:
|
|||
//! Pair (symbol_id, lag) used as key
|
||||
typedef map<pair<int, int>, VariableNode *> variable_node_map_type;
|
||||
variable_node_map_type variable_node_map;
|
||||
typedef map<pair<NodeID, int>, UnaryOpNode *> unary_op_node_map_type;
|
||||
typedef map<pair<NodeID, UnaryOpcode>, UnaryOpNode *> unary_op_node_map_type;
|
||||
unary_op_node_map_type unary_op_node_map;
|
||||
typedef map<pair<pair<NodeID, NodeID>, int>, BinaryOpNode *> binary_op_node_map_type;
|
||||
typedef map<pair<pair<NodeID, NodeID>, BinaryOpcode>, BinaryOpNode *> binary_op_node_map_type;
|
||||
binary_op_node_map_type binary_op_node_map;
|
||||
typedef map<pair<pair<pair<NodeID, NodeID>,NodeID>, int>, TrinaryOpNode *> trinary_op_node_map_type;
|
||||
typedef map<pair<pair<pair<NodeID, NodeID>,NodeID>, TrinaryOpcode>, TrinaryOpNode *> trinary_op_node_map_type;
|
||||
trinary_op_node_map_type trinary_op_node_map;
|
||||
|
||||
//! Stores local variables value (maps symbol ID to corresponding node)
|
||||
map<int, NodeID> local_variables_table;
|
||||
|
||||
//! true when oSteadyState is encountered in a dynamic model
|
||||
bool steady_state_found;
|
||||
|
||||
//! Internal implementation of AddVariable(), without the check on the lag
|
||||
VariableNode *AddVariableInternal(int symb_id, int lag);
|
||||
|
||||
//! Is there a steady state operator in the tree?
|
||||
bool containsSteadyStateOperator() const;
|
||||
|
||||
private:
|
||||
typedef list<NodeID> node_list_type;
|
||||
//! The list of nodes
|
||||
|
@ -180,8 +180,6 @@ public:
|
|||
//! Checks if a given symbol is used somewhere in the data tree
|
||||
bool isSymbolUsed(int symb_id) const;
|
||||
//! Thrown when trying to access an unknown variable by deriv_id
|
||||
bool containsSteadyStateOperator() const { return steady_state_found; };
|
||||
//! Thrown when trying to access an unknown variable by deriv_id
|
||||
class UnknownDerivIDException
|
||||
{
|
||||
};
|
||||
|
|
|
@ -3051,10 +3051,10 @@ DynamicModel::substituteExpectation(bool partial_information_model)
|
|||
ExprNode::subst_table_t subst_table;
|
||||
vector<BinaryOpNode *> neweqs;
|
||||
|
||||
// Substitute in model binary op node map
|
||||
for(unary_op_node_map_type::reverse_iterator it = unary_op_node_map.rbegin();
|
||||
it != unary_op_node_map.rend(); it++)
|
||||
it->second->substituteExpectation(subst_table, neweqs, partial_information_model);
|
||||
// Substitute in model local variables
|
||||
for(map<int, NodeID>::iterator it = local_variables_table.begin();
|
||||
it != local_variables_table.end(); it++)
|
||||
it->second = it->second->substituteExpectation(subst_table, neweqs, partial_information_model);
|
||||
|
||||
// Substitute in equations
|
||||
for(int i = 0; i < (int) equations.size(); i++)
|
||||
|
@ -3072,10 +3072,12 @@ DynamicModel::substituteExpectation(bool partial_information_model)
|
|||
copy(neweqs.rbegin(), neweqs.rend(), front_inserter(aux_equations));
|
||||
|
||||
if (neweqs.size() > 0)
|
||||
if (partial_information_model)
|
||||
cout << "Substitution of Expectation operator: added " << subst_table.size() << " auxiliary variables and " << neweqs.size() << " auxiliary equations." << endl;
|
||||
else
|
||||
cout << "Substitution of Expectation operator: added " << neweqs.size() << " auxiliary variables and equations." << endl;
|
||||
{
|
||||
if (partial_information_model)
|
||||
cout << "Substitution of Expectation operator: added " << subst_table.size() << " auxiliary variables and " << neweqs.size() << " auxiliary equations." << endl;
|
||||
else
|
||||
cout << "Substitution of Expectation operator: added " << neweqs.size() << " auxiliary variables and equations." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -375,8 +375,6 @@ expression : '(' expression ')'
|
|||
{ $$ = driver.add_equal_equal($1, $3); }
|
||||
| expression EXCLAMATION_EQUAL expression
|
||||
{ $$ = driver.add_different($1, $3); }
|
||||
| EXPECTATION '(' signed_integer ')''(' expression ')'
|
||||
{ $$ = driver.add_expectation($3, $6); }
|
||||
| MINUS expression %prec UMINUS
|
||||
{ $$ = driver.add_uminus($2); }
|
||||
| PLUS expression %prec UPLUS
|
||||
|
@ -413,8 +411,6 @@ expression : '(' expression ')'
|
|||
{ $$ = driver.add_normcdf($3, $5, $7); }
|
||||
| NORMCDF '(' expression ')'
|
||||
{ $$ = driver.add_normcdf($3); }
|
||||
| STEADY_STATE '(' expression ')'
|
||||
{ $$ = driver.add_steady_state($3); }
|
||||
| NAN_CONSTANT
|
||||
{ $$ = driver.add_nan_constant(); }
|
||||
| INF_CONSTANT
|
||||
|
|
|
@ -1704,45 +1704,41 @@ UnaryOpNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNo
|
|||
{
|
||||
subst_table_t::iterator it = subst_table.find(const_cast<UnaryOpNode *>(this));
|
||||
|
||||
//This if statement should evaluate to true when substituting Exp operators out of equations in second pass
|
||||
if (it != subst_table.end())
|
||||
return const_cast<VariableNode *>(it->second);
|
||||
|
||||
//Arriving here, we need to create an auxiliary variable for this Expectation Operator:
|
||||
int symb_id = datatree.symbol_table.addExpectationAuxiliaryVar(expectation_information_set, arg->idx); //AUXE_period_arg.idx
|
||||
NodeID newAuxE = datatree.AddVariable(symb_id, 0);
|
||||
assert(dynamic_cast<VariableNode *>(newAuxE) != NULL);
|
||||
|
||||
if (partial_information_model && expectation_information_set==0)
|
||||
{
|
||||
//Ensure x is a single variable as opposed to an expression
|
||||
if (dynamic_cast<VariableNode *>(arg) == NULL)
|
||||
{
|
||||
cerr << "In Partial Information models, EXPECTATION(0)(X) can only be used when X is a single variable." << endl;
|
||||
cerr << "ERROR: In Partial Information models, EXPECTATION(0)(X) can only be used when X is a single variable." << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//take care of any nested expectation operators by calling arg->substituteExpectation(.), then decreaseLeadsLags for this oExp operator
|
||||
//take care of any nested expectation operators by calling arg->substituteExpectation(.), then decreaseLeadsLags for this oExpectation operator
|
||||
//arg(lag-period) (holds entire subtree of arg(lag-period)
|
||||
NodeID substexpr = (arg->substituteExpectation(subst_table, neweqs, partial_information_model))->decreaseLeadsLags(expectation_information_set);
|
||||
assert(substexpr != NULL);
|
||||
|
||||
neweqs.push_back(dynamic_cast<BinaryOpNode *>(datatree.AddEqual(newAuxE, substexpr))); //AUXE_period_arg.idx = arg(lag-period)
|
||||
|
||||
newAuxE = newAuxE->decreaseLeadsLags(-1*expectation_information_set);
|
||||
assert(dynamic_cast<VariableNode *>(newAuxE) != NULL);
|
||||
newAuxE = datatree.AddVariable(symb_id, expectation_information_set);
|
||||
}
|
||||
|
||||
assert(dynamic_cast<VariableNode *>(newAuxE) != NULL);
|
||||
subst_table[this] = dynamic_cast<VariableNode *>(newAuxE);
|
||||
return newAuxE;
|
||||
}
|
||||
default:
|
||||
{
|
||||
NodeID argsubst = arg->substituteExpectation(subst_table, neweqs, partial_information_model);
|
||||
return buildSimilarUnaryOpNode(argsubst, datatree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -301,6 +301,7 @@ public:
|
|||
/*!
|
||||
\param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr.
|
||||
\param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
|
||||
\param[in] partial_information_model Are we substituting in a partial information model?
|
||||
*/
|
||||
virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const = 0;
|
||||
|
||||
|
|
|
@ -137,14 +137,14 @@ ModFile::transformPass()
|
|||
if (symbol_table.predeterminedNbr() > 0)
|
||||
dynamic_model.transformPredeterminedVariables();
|
||||
|
||||
// Create auxiliary vars for Expectation operator
|
||||
dynamic_model.substituteExpectation(mod_file_struct.partial_information);
|
||||
|
||||
if (mod_file_struct.stoch_simul_present
|
||||
|| mod_file_struct.estimation_present
|
||||
|| mod_file_struct.osr_present
|
||||
|| mod_file_struct.ramsey_policy_present)
|
||||
{
|
||||
// In stochastic models, create auxiliary vars for Expecatation operator
|
||||
dynamic_model.substituteExpectation(mod_file_struct.partial_information);
|
||||
|
||||
// In stochastic models, create auxiliary vars for leads and lags greater than 2
|
||||
dynamic_model.substituteEndoLeadGreaterThanTwo();
|
||||
dynamic_model.substituteExoLead();
|
||||
|
|
|
@ -211,6 +211,7 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
|
|||
{
|
||||
case avEndoLead:
|
||||
case avExoLead:
|
||||
case avExpectation:
|
||||
break;
|
||||
case avEndoLag:
|
||||
case avExoLag:
|
||||
|
@ -314,10 +315,11 @@ SymbolTable::addExoLagAuxiliaryVar(int orig_symb_id, int orig_lag) throw (Frozen
|
|||
}
|
||||
|
||||
int
|
||||
SymbolTable::addExpectationAuxiliaryVar(int arg1, int arg2) throw (FrozenException)
|
||||
SymbolTable::addExpectationAuxiliaryVar(int information_set, int index) throw (FrozenException)
|
||||
{
|
||||
ostringstream varname;
|
||||
varname << "AUXE_" << arg1 << "_" << arg2;
|
||||
varname << "AUX_EXPECT_" << (information_set < 0 ? "LAG" : "LEAD") << "_"
|
||||
<< abs(information_set) << "_" << index;
|
||||
int symb_id;
|
||||
try
|
||||
{
|
||||
|
|
|
@ -176,11 +176,13 @@ public:
|
|||
\param[in] orig_lag lag value such that this new variable will be equivalent to orig_symb_id(orig_lag)
|
||||
\return the symbol ID of the new symbol */
|
||||
int addExoLagAuxiliaryVar(int orig_symb_id, int orig_lag) throw (FrozenException);
|
||||
//! Adds an auxiliary variable for the expectations operator
|
||||
//! Adds an auxiliary variable for the expectation operator
|
||||
/*!
|
||||
\param[in] indeces Used to construct the variable name
|
||||
\return the symbol ID of the new symbol */
|
||||
int addExpectationAuxiliaryVar(int arg1, int arg2) throw (FrozenException);
|
||||
\param[in] information_set information set (possibly negative) of the expectation operator
|
||||
\param[in] index Used to construct the variable name
|
||||
\return the symbol ID of the new symbol
|
||||
*/
|
||||
int addExpectationAuxiliaryVar(int information_set, int index) throw (FrozenException);
|
||||
//! Tests if symbol already exists
|
||||
inline bool exists(const string &name) const;
|
||||
//! Get symbol name (by ID)
|
||||
|
|
Loading…
Reference in New Issue