Commit af732433 authored by sebastien's avatar sebastien
Browse files

predetermined_variables:

* reworked a little bit the implementation
* documented the command in the reference manual
* added a test


git-svn-id: https://www.dynare.org/svn/dynare/trunk@3143 ac1d8469-bf42-47a9-8791-bf33cf982152
parent d17b813c
......@@ -378,6 +378,7 @@ In the description of Dynare commands, the following conventions are observed:
<listitem><para><xref linkend='varexo_det'/></para></listitem>
<listitem><para><xref linkend='parameters'/></para></listitem>
<listitem><para><xref linkend='change_type'/></para></listitem>
<listitem><para><xref linkend='predetermined_variables'/></para></listitem>
</itemizedlist>
<refentry id="var">
......@@ -610,6 +611,81 @@ change_type(parameters) y, w;
</refsect1>
</refentry>
<refentry id="predetermined_variables">
<refmeta>
<refentrytitle>predetermined_variables</refentrytitle>
</refmeta>
<refnamediv>
<refname>predetermined_variables</refname>
<refpurpose>declare some endogenous variables as predetermined</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>predetermined_variables</command>
<arg choice="plain"><replaceable>VARIABLE_NAME</replaceable></arg>
<arg rep="repeat"><replaceable>VARIABLE_NAME</replaceable></arg>
<arg choice="plain">;</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
In Dynare, the default convention is that the timing of a variable reflects when this variable is decided. The typical example is for capital stock: since the capital stock used at current period is actually decided at the previous period, then the capital stock entering the production function is <literal>k(-1)</literal>, and the law of motion of capital must be written:
<programlisting>
k = i + (1-delta)*k(-1)
</programlisting>
</para>
<para>Put another way, for stock variables, the default in Dynare is to use a
“stock at the end of the period” concept, instead of a “stock at the beginning of the period”
convention.</para>
<para>The <command>predetermined_variables</command> is used to change that convention. The endogenous variables declared as predetermined variables are supposed to be decided one period ahead of all other endogenous variables. For stock variables, they are supposed
to follow a “stock at the beginning of the period”
convention.</para>
</refsect1>
<refsect1><title>Example</title>
<informalexample>
<para>The following two program snippets are strictly equivalent.</para>
<formalpara><title>Using default Dynare timing convention:</title>
<para>
<programlisting>
var y, k, i;
...
model;
y = k(-1)^alpha;
k = i + (1-delta)*k(-1);
...
end;
</programlisting>
</para>
</formalpara>
<formalpara><title>Using the alternative timing convention:</title>
<para>
<programlisting>
var y, k, i;
predetermined_variables k;
...
model;
y = k^alpha;
k(+1) = i + (1-delta)*k;
...
end;
</programlisting>
</para>
</formalpara>
</informalexample>
</refsect1>
</refentry>
</sect1>
<sect1 id="expressions"><title>Expressions</title>
......
......@@ -1995,15 +1995,6 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll) const
void
DynamicModel::writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll) const
{
// Write list of predetermined variables in M_.predetermined_variables
if (predetermined_variables_vec.size() > 0)
{
output << "M_.predetermined_variables = '';" << endl;
for(vector <string>::const_iterator it = predetermined_variables_vec.begin();
it != predetermined_variables_vec.end(); it++)
output << "M_.predetermined_variables = strvcat(M_.predetermined_variables, '" << *it << "');" << endl;
}
/* Writing initialisation for M_.lead_lag_incidence matrix
M_.lead_lag_incidence is a matrix with as many columns as there are
endogenous variables and as many rows as there are periods in the
......@@ -3090,34 +3081,11 @@ DynamicModel::substituteExpectation(bool partial_information_model)
void
DynamicModel::transformPredeterminedVariables()
{
for(vector <string>::const_iterator it = predetermined_variables_vec.begin();
it != predetermined_variables_vec.end(); it++)
for(int i = 0; i < (int) equations.size(); i++)
{
try
{
if(symbol_table.getType(*it)!=eEndogenous)
{
cerr << "Error: You must declare predetermined variable " << *it << " as an endogenous variable." << endl;
exit(EXIT_FAILURE);
}
}
catch(SymbolTable::UnknownSymbolNameException &e)
{
cerr << "Error: predetermind variable " << *it << " has not been declared." << endl;
exit(EXIT_FAILURE);
}
catch(...)
{
cerr << "error in DynamicModel::transformPredeterminedVariables(), should not arrive here" << endl;
exit(EXIT_FAILURE);
}
for(int i = 0; i < (int) equations.size(); i++)
{
BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->decreaseLeadsLagsPredeterminedVariables(*it));
assert(substeq != NULL);
equations[i] = substeq;
}
BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->decreaseLeadsLagsPredeterminedVariables());
assert(substeq != NULL);
equations[i] = substeq;
}
}
......
......@@ -165,8 +165,6 @@ public:
int mfs;
//! the file containing the model and the derivatives code
ofstream code_file;
//! Stores variables declared to be predetermined by "predetermined_variables" statement
vector<string> predetermined_variables_vec;
//! Execute computations (variable sorting + derivation)
/*!
\param jacobianExo whether derivatives w.r. to exo and exo_det should be in the Jacobian (derivatives w.r. to endo are always computed)
......
......@@ -319,9 +319,9 @@ NumConstNode::decreaseLeadsLags(int n) const
}
NodeID
NumConstNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
NumConstNode::decreaseLeadsLagsPredeterminedVariables() const
{
return decreaseLeadsLags(1);
return const_cast<NumConstNode *>(this);
}
NodeID
......@@ -831,9 +831,9 @@ VariableNode::decreaseLeadsLags(int n) const
}
NodeID
VariableNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
VariableNode::decreaseLeadsLagsPredeterminedVariables() const
{
if(datatree.symbol_table.getName(symb_id).compare(pv_name)==0)
if (datatree.symbol_table.isPredetermined(symb_id))
return decreaseLeadsLags(1);
else
return const_cast<VariableNode *>(this);
......@@ -1641,9 +1641,9 @@ UnaryOpNode::decreaseLeadsLags(int n) const
}
NodeID
UnaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
UnaryOpNode::decreaseLeadsLagsPredeterminedVariables() const
{
NodeID argsubst = arg->decreaseLeadsLagsPredeterminedVariables(pv_name);
NodeID argsubst = arg->decreaseLeadsLagsPredeterminedVariables();
return buildSimilarUnaryOpNode(argsubst, datatree);
}
......@@ -2626,10 +2626,10 @@ BinaryOpNode::decreaseLeadsLags(int n) const
}
NodeID
BinaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
BinaryOpNode::decreaseLeadsLagsPredeterminedVariables() const
{
NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(pv_name);
NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(pv_name);
NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables();
NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables();
return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
}
......@@ -3097,11 +3097,11 @@ TrinaryOpNode::decreaseLeadsLags(int n) const
}
NodeID
TrinaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
TrinaryOpNode::decreaseLeadsLagsPredeterminedVariables() const
{
NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(pv_name);
NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(pv_name);
NodeID arg3subst = arg3->decreaseLeadsLagsPredeterminedVariables(pv_name);
NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables();
NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables();
NodeID arg3subst = arg3->decreaseLeadsLagsPredeterminedVariables();
return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
}
......@@ -3309,7 +3309,7 @@ UnknownFunctionNode::decreaseLeadsLags(int n) const
}
NodeID
UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables() const
{
cerr << "UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables: not implemented!" << endl;
exit(EXIT_FAILURE);
......
......@@ -304,7 +304,7 @@ public:
*/
virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const = 0;
virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const = 0;
virtual NodeID decreaseLeadsLagsPredeterminedVariables() const = 0;
};
......@@ -345,7 +345,7 @@ public:
virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
};
//! Symbol or variable node
......@@ -384,7 +384,7 @@ public:
virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
};
//! Unary operator node
......@@ -433,7 +433,7 @@ public:
virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
};
//! Binary operator node
......@@ -485,7 +485,7 @@ public:
virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
};
//! Trinary operator node
......@@ -531,7 +531,7 @@ public:
virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
};
//! Unknown function node
......@@ -569,7 +569,7 @@ public:
virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
virtual NodeID decreaseLeadsLagsPredeterminedVariables() const;
};
#endif
......@@ -134,7 +134,8 @@ ModFile::checkPass()
void
ModFile::transformPass()
{
dynamic_model.transformPredeterminedVariables();
if (symbol_table.predeterminedNbr() > 0)
dynamic_model.transformPredeterminedVariables();
if (mod_file_struct.stoch_simul_present
|| mod_file_struct.estimation_present
......
......@@ -147,7 +147,18 @@ ParsingDriver::declare_parameter(string *name, string *tex_name)
void
ParsingDriver::add_predetermined_variable(string *name)
{
mod_file->dynamic_model.predetermined_variables_vec.push_back(*name);
try
{
int symb_id = mod_file->symbol_table.getID(*name);
if (mod_file->symbol_table.getType(symb_id) != eEndogenous)
error("Predetermined variables must be endogenous variables");
mod_file->symbol_table.markPredetermined(symb_id);
}
catch(SymbolTable::UnknownSymbolNameException &e)
{
error("Undeclared symbol name: " + *name);
}
delete name;
}
......
......@@ -20,6 +20,7 @@
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cassert>
#include "SymbolTable.hh"
......@@ -218,6 +219,15 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
break;
}
}
if (predeterminedNbr() > 0)
{
output << "M_.predetermined_variables = [ ";
for(set<int>::const_iterator it = predetermined_variables.begin();
it != predetermined_variables.end(); it++)
output << getTypeSpecificID(*it) << " ";
output << "];" << endl;
}
}
int
......@@ -326,3 +336,31 @@ SymbolTable::addExpectationAuxiliaryVar(int arg1, int arg2) throw (FrozenExcepti
return symb_id;
}
void
SymbolTable::markPredetermined(int symb_id) throw (UnknownSymbolIDException, FrozenException)
{
if (symb_id < 0 || symb_id >= size)
throw UnknownSymbolIDException(symb_id);
if (frozen)
throw FrozenException();
assert(getType(symb_id) == eEndogenous);
predetermined_variables.insert(symb_id);
}
bool
SymbolTable::isPredetermined(int symb_id) const throw (UnknownSymbolIDException)
{
if (symb_id < 0 || symb_id >= size)
throw UnknownSymbolIDException(symb_id);
return(predetermined_variables.find(symb_id) != predetermined_variables.end());
}
int
SymbolTable::predeterminedNbr() const
{
return(predetermined_variables.size());
}
......@@ -25,6 +25,7 @@ using namespace std;
#include <map>
#include <string>
#include <vector>
#include <set>
#include <ostream>
#include "CodeInterpreter.hh"
......@@ -92,6 +93,9 @@ private:
//! Information about auxiliary variables
vector<AuxVarInfo> aux_vars;
//! Stores the predetermined variables (by symbol IDs)
set<int> predetermined_variables;
public:
SymbolTable();
//! Thrown when trying to access an unknown symbol (by name)
......@@ -211,6 +215,12 @@ public:
inline int maxID();
//! Write output of this class
void writeOutput(ostream &output) const throw (NotYetFrozenException);
//! Mark a symbol as predetermined variable
void markPredetermined(int symb_id) throw (UnknownSymbolIDException, FrozenException);
//! Test if a given symbol is a predetermined variable
bool isPredetermined(int symb_id) const throw (UnknownSymbolIDException);
//! Return the number of predetermined variables
int predeterminedNbr() const;
};
inline bool
......
......@@ -9,6 +9,7 @@ OCTAVE_MODS = \
ramsey.mod \
ramst_initval_file.mod \
example1_varexo_det.mod \
predetermined_variables.mod \
arima/mod1.mod \
arima/mod1a.mod \
arima/mod2.mod \
......
var c k i;
varexo x;
parameters alph gam delt bet aa;
alph=0.5;
gam=0.5;
delt=0.02;
bet=0.05;
aa=0.5;
predetermined_variables k;
model;
c + i = aa*x*k^alph;
c^(-gam) - (1+bet)^(-1)*(aa*alph*x(+1)*k(+1)^(alph-1) + 1 - delt)*c(+1)^(-gam);
k(+1) = (1-delt)*k + i;
end;
initval;
x = 1;
k = ((delt+bet)/(1.0*aa*alph))^(1/(alph-1));
c = aa*k^alph-delt*k;
i = delt*k;
end;
write_latex_dynamic_model;
steady;
check;
shocks;
var x;
periods 1;
values 1.2;
end;
simul(periods=200);
rplot c;
rplot k;
Markdown is supported
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