Remove some limitations of steady state model:
- allow recursive definitions (Closes #554) - allow a variable to be defined twice, simply emit a warning (Ref #556)time-shift
parent
711a4f62a2
commit
8fddca92a2
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2013 Dynare Team
|
* Copyright (C) 2006-2014 Dynare Team
|
||||||
*
|
*
|
||||||
* This file is part of Dynare.
|
* This file is part of Dynare.
|
||||||
*
|
*
|
||||||
|
@ -113,7 +113,7 @@ ModFile::checkPass()
|
||||||
(*it)->checkPass(mod_file_struct, warnings);
|
(*it)->checkPass(mod_file_struct, warnings);
|
||||||
|
|
||||||
// Check the steady state block
|
// Check the steady state block
|
||||||
steady_state_model.checkPass(mod_file_struct.ramsey_policy_present);
|
steady_state_model.checkPass(mod_file_struct.ramsey_policy_present, warnings);
|
||||||
|
|
||||||
// If order option has not been set, default to 2
|
// If order option has not been set, default to 2
|
||||||
if (!mod_file_struct.order_option)
|
if (!mod_file_struct.order_option)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010-2011 Dynare Team
|
* Copyright (C) 2010-2014 Dynare Team
|
||||||
*
|
*
|
||||||
* This file is part of Dynare.
|
* This file is part of Dynare.
|
||||||
*
|
*
|
||||||
|
@ -39,8 +39,7 @@ SteadyStateModel::addDefinition(int symb_id, expr_t expr)
|
||||||
// Add the variable
|
// Add the variable
|
||||||
vector<int> v;
|
vector<int> v;
|
||||||
v.push_back(symb_id);
|
v.push_back(symb_id);
|
||||||
recursive_order.push_back(v);
|
def_table.push_back(make_pair(v, expr));
|
||||||
def_table[v] = expr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -53,33 +52,32 @@ SteadyStateModel::addMultipleDefinitions(const vector<int> &symb_ids, expr_t exp
|
||||||
|| symbol_table.getType(symb_ids[i]) == eModFileLocalVariable
|
|| symbol_table.getType(symb_ids[i]) == eModFileLocalVariable
|
||||||
|| symbol_table.getType(symb_ids[i]) == eParameter);
|
|| symbol_table.getType(symb_ids[i]) == eParameter);
|
||||||
}
|
}
|
||||||
recursive_order.push_back(symb_ids);
|
def_table.push_back(make_pair(symb_ids, expr));
|
||||||
def_table[symb_ids] = expr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SteadyStateModel::checkPass(bool ramsey_policy) const
|
SteadyStateModel::checkPass(bool ramsey_policy, WarningConsolidation &warnings) const
|
||||||
{
|
{
|
||||||
|
if (ramsey_policy)
|
||||||
|
return;
|
||||||
|
|
||||||
vector<int> so_far_defined;
|
vector<int> so_far_defined;
|
||||||
|
|
||||||
for (size_t i = 0; i < recursive_order.size(); i++)
|
for (size_t i = 0; i < def_table.size(); i++)
|
||||||
{
|
{
|
||||||
const vector<int> &symb_ids = recursive_order[i];
|
const vector<int> &symb_ids = def_table[i].first;
|
||||||
|
|
||||||
// Check that symbols are not already defined
|
// Check that symbols are not already defined
|
||||||
for (size_t j = 0; j < symb_ids.size(); j++)
|
for (size_t j = 0; j < symb_ids.size(); j++)
|
||||||
if (find(so_far_defined.begin(), so_far_defined.end(), symb_ids[j])
|
if (find(so_far_defined.begin(), so_far_defined.end(), symb_ids[j])
|
||||||
!= so_far_defined.end())
|
!= so_far_defined.end())
|
||||||
{
|
warnings << "WARNING: in the 'steady_state_model' block, variable '" << symbol_table.getName(symb_ids[j]) << "' is declared twice" << endl;
|
||||||
cerr << "ERROR: in the 'steady_state' block, variable '" << symbol_table.getName(symb_ids[j]) << "' is declared twice" << endl;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that expression has no undefined symbol
|
// Check that expression has no undefined symbol
|
||||||
if (!ramsey_policy)
|
if (!ramsey_policy)
|
||||||
{
|
{
|
||||||
set<int> used_symbols;
|
set<int> used_symbols;
|
||||||
expr_t expr = def_table.find(symb_ids)->second;
|
const expr_t &expr = def_table[i].second;
|
||||||
expr->collectVariables(eEndogenous, used_symbols);
|
expr->collectVariables(eEndogenous, used_symbols);
|
||||||
expr->collectVariables(eModFileLocalVariable, used_symbols);
|
expr->collectVariables(eModFileLocalVariable, used_symbols);
|
||||||
for (set<int>::const_iterator it = used_symbols.begin();
|
for (set<int>::const_iterator it = used_symbols.begin();
|
||||||
|
@ -87,7 +85,7 @@ SteadyStateModel::checkPass(bool ramsey_policy) const
|
||||||
if (find(so_far_defined.begin(), so_far_defined.end(), *it)
|
if (find(so_far_defined.begin(), so_far_defined.end(), *it)
|
||||||
== so_far_defined.end())
|
== so_far_defined.end())
|
||||||
{
|
{
|
||||||
cerr << "ERROR: in the 'steady_state' block, variable '" << symbol_table.getName(*it)
|
cerr << "ERROR: in the 'steady_state_model' block, variable '" << symbol_table.getName(*it)
|
||||||
<< "' is undefined in the declaration of variable '" << symbol_table.getName(symb_ids[0]) << "'" << endl;
|
<< "' is undefined in the declaration of variable '" << symbol_table.getName(symb_ids[0]) << "'" << endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -100,7 +98,7 @@ SteadyStateModel::checkPass(bool ramsey_policy) const
|
||||||
void
|
void
|
||||||
SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_policy) const
|
SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_policy) const
|
||||||
{
|
{
|
||||||
if (recursive_order.size() == 0)
|
if (def_table.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string filename = basename + "_steadystate2.m";
|
string filename = basename + "_steadystate2.m";
|
||||||
|
@ -118,9 +116,9 @@ SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_polic
|
||||||
<< "% Steady state generated by Dynare preprocessor" << endl
|
<< "% Steady state generated by Dynare preprocessor" << endl
|
||||||
<< " info = 0;" << endl;
|
<< " info = 0;" << endl;
|
||||||
|
|
||||||
for (size_t i = 0; i < recursive_order.size(); i++)
|
for (size_t i = 0; i < def_table.size(); i++)
|
||||||
{
|
{
|
||||||
const vector<int> &symb_ids = recursive_order[i];
|
const vector<int> &symb_ids = def_table[i].first;
|
||||||
output << " ";
|
output << " ";
|
||||||
if (symb_ids.size() > 1)
|
if (symb_ids.size() > 1)
|
||||||
output << "[";
|
output << "[";
|
||||||
|
@ -136,7 +134,7 @@ SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_polic
|
||||||
output << "]";
|
output << "]";
|
||||||
|
|
||||||
output << "=";
|
output << "=";
|
||||||
def_table.find(symb_ids)->second->writeOutput(output, oSteadyStateFile);
|
def_table[i].second->writeOutput(output, oSteadyStateFile);
|
||||||
output << ";" << endl;
|
output << ";" << endl;
|
||||||
}
|
}
|
||||||
output << " % Auxiliary equations" << endl;
|
output << " % Auxiliary equations" << endl;
|
||||||
|
@ -169,16 +167,16 @@ SteadyStateModel::writeSteadyStateFileCC(const string &basename, bool ramsey_pol
|
||||||
<< "{" << endl
|
<< "{" << endl
|
||||||
<< " *info = 0;" << endl;
|
<< " *info = 0;" << endl;
|
||||||
|
|
||||||
if (recursive_order.size() == 0)
|
if (def_table.size() == 0)
|
||||||
{
|
{
|
||||||
output << " return;" << endl
|
output << " return;" << endl
|
||||||
<< "}" << endl;
|
<< "}" << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < recursive_order.size(); i++)
|
for (size_t i = 0; i < def_table.size(); i++)
|
||||||
{
|
{
|
||||||
const vector<int> &symb_ids = recursive_order[i];
|
const vector<int> &symb_ids = def_table[i].first;
|
||||||
output << " ";
|
output << " ";
|
||||||
if (symb_ids.size() > 1)
|
if (symb_ids.size() > 1)
|
||||||
std::cout << "Error: in C, multiple returns are not permitted in steady_state_model" << std::endl;
|
std::cout << "Error: in C, multiple returns are not permitted in steady_state_model" << std::endl;
|
||||||
|
@ -188,7 +186,7 @@ SteadyStateModel::writeSteadyStateFileCC(const string &basename, bool ramsey_pol
|
||||||
output << "double ";
|
output << "double ";
|
||||||
dynamic_cast<ExprNode *>(it->second)->writeOutput(output, oCSteadyStateFile);
|
dynamic_cast<ExprNode *>(it->second)->writeOutput(output, oCSteadyStateFile);
|
||||||
output << "=";
|
output << "=";
|
||||||
def_table.find(symb_ids)->second->writeOutput(output, oCSteadyStateFile);
|
def_table[i].second->writeOutput(output, oCSteadyStateFile);
|
||||||
output << ";" << endl;
|
output << ";" << endl;
|
||||||
}
|
}
|
||||||
output << " // Auxiliary equations" << endl;
|
output << " // Auxiliary equations" << endl;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010-2011 Dynare Team
|
* Copyright (C) 2010-2014 Dynare Team
|
||||||
*
|
*
|
||||||
* This file is part of Dynare.
|
* This file is part of Dynare.
|
||||||
*
|
*
|
||||||
|
@ -22,13 +22,13 @@
|
||||||
|
|
||||||
#include "DataTree.hh"
|
#include "DataTree.hh"
|
||||||
#include "StaticModel.hh"
|
#include "StaticModel.hh"
|
||||||
|
#include "WarningConsolidation.hh"
|
||||||
|
|
||||||
class SteadyStateModel : public DataTree
|
class SteadyStateModel : public DataTree
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
//! Associates a set of symbol IDs (the variable(s) assigned in a given statement) to an expression (their assigned value)
|
//! Associates a set of symbol IDs (the variable(s) assigned in a given statement) to an expression (their assigned value)
|
||||||
map<vector<int>, expr_t> def_table;
|
vector<pair<vector<int>, expr_t> > def_table;
|
||||||
vector<vector<int> > recursive_order;
|
|
||||||
|
|
||||||
//! Reference to static model (for writing auxiliary equations)
|
//! Reference to static model (for writing auxiliary equations)
|
||||||
const StaticModel &static_model;
|
const StaticModel &static_model;
|
||||||
|
@ -43,7 +43,7 @@ public:
|
||||||
/*!
|
/*!
|
||||||
\param[in] ramsey_policy Is there a ramsey_policy statement in the MOD file? If yes, then disable the check on the recursivity of the declarations
|
\param[in] ramsey_policy Is there a ramsey_policy statement in the MOD file? If yes, then disable the check on the recursivity of the declarations
|
||||||
*/
|
*/
|
||||||
void checkPass(bool ramsey_policy) const;
|
void checkPass(bool ramsey_policy, WarningConsolidation &warnings) const;
|
||||||
//! Write the steady state file
|
//! Write the steady state file
|
||||||
/*!
|
/*!
|
||||||
\param[in] ramsey_policy Is there a ramsey_policy statement in the MOD file? If yes, then use the "ys" in argument of the steady state file as initial values
|
\param[in] ramsey_policy Is there a ramsey_policy statement in the MOD file? If yes, then use the "ys" in argument of the steady state file as initial values
|
||||||
|
|
Loading…
Reference in New Issue