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.
|
||||
*
|
||||
|
@ -113,7 +113,7 @@ ModFile::checkPass()
|
|||
(*it)->checkPass(mod_file_struct, warnings);
|
||||
|
||||
// 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 (!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.
|
||||
*
|
||||
|
@ -39,8 +39,7 @@ SteadyStateModel::addDefinition(int symb_id, expr_t expr)
|
|||
// Add the variable
|
||||
vector<int> v;
|
||||
v.push_back(symb_id);
|
||||
recursive_order.push_back(v);
|
||||
def_table[v] = expr;
|
||||
def_table.push_back(make_pair(v, expr));
|
||||
}
|
||||
|
||||
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]) == eParameter);
|
||||
}
|
||||
recursive_order.push_back(symb_ids);
|
||||
def_table[symb_ids] = expr;
|
||||
def_table.push_back(make_pair(symb_ids, expr));
|
||||
}
|
||||
|
||||
void
|
||||
SteadyStateModel::checkPass(bool ramsey_policy) const
|
||||
SteadyStateModel::checkPass(bool ramsey_policy, WarningConsolidation &warnings) const
|
||||
{
|
||||
if (ramsey_policy)
|
||||
return;
|
||||
|
||||
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
|
||||
for (size_t j = 0; j < symb_ids.size(); j++)
|
||||
if (find(so_far_defined.begin(), so_far_defined.end(), symb_ids[j])
|
||||
!= so_far_defined.end())
|
||||
{
|
||||
cerr << "ERROR: in the 'steady_state' block, variable '" << symbol_table.getName(symb_ids[j]) << "' is declared twice" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
warnings << "WARNING: in the 'steady_state_model' block, variable '" << symbol_table.getName(symb_ids[j]) << "' is declared twice" << endl;
|
||||
|
||||
// Check that expression has no undefined symbol
|
||||
if (!ramsey_policy)
|
||||
{
|
||||
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(eModFileLocalVariable, used_symbols);
|
||||
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)
|
||||
== 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;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -100,7 +98,7 @@ SteadyStateModel::checkPass(bool ramsey_policy) const
|
|||
void
|
||||
SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_policy) const
|
||||
{
|
||||
if (recursive_order.size() == 0)
|
||||
if (def_table.size() == 0)
|
||||
return;
|
||||
|
||||
string filename = basename + "_steadystate2.m";
|
||||
|
@ -118,9 +116,9 @@ SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_polic
|
|||
<< "% Steady state generated by Dynare preprocessor" << 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 << " ";
|
||||
if (symb_ids.size() > 1)
|
||||
output << "[";
|
||||
|
@ -136,7 +134,7 @@ SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_polic
|
|||
output << "]";
|
||||
|
||||
output << "=";
|
||||
def_table.find(symb_ids)->second->writeOutput(output, oSteadyStateFile);
|
||||
def_table[i].second->writeOutput(output, oSteadyStateFile);
|
||||
output << ";" << endl;
|
||||
}
|
||||
output << " % Auxiliary equations" << endl;
|
||||
|
@ -169,16 +167,16 @@ SteadyStateModel::writeSteadyStateFileCC(const string &basename, bool ramsey_pol
|
|||
<< "{" << endl
|
||||
<< " *info = 0;" << endl;
|
||||
|
||||
if (recursive_order.size() == 0)
|
||||
if (def_table.size() == 0)
|
||||
{
|
||||
output << " return;" << endl
|
||||
<< "}" << endl;
|
||||
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 << " ";
|
||||
if (symb_ids.size() > 1)
|
||||
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 ";
|
||||
dynamic_cast<ExprNode *>(it->second)->writeOutput(output, oCSteadyStateFile);
|
||||
output << "=";
|
||||
def_table.find(symb_ids)->second->writeOutput(output, oCSteadyStateFile);
|
||||
def_table[i].second->writeOutput(output, oCSteadyStateFile);
|
||||
output << ";" << 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.
|
||||
*
|
||||
|
@ -22,13 +22,13 @@
|
|||
|
||||
#include "DataTree.hh"
|
||||
#include "StaticModel.hh"
|
||||
#include "WarningConsolidation.hh"
|
||||
|
||||
class SteadyStateModel : public DataTree
|
||||
{
|
||||
private:
|
||||
//! 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<vector<int> > recursive_order;
|
||||
vector<pair<vector<int>, expr_t> > def_table;
|
||||
|
||||
//! Reference to static model (for writing auxiliary equations)
|
||||
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
|
||||
*/
|
||||
void checkPass(bool ramsey_policy) const;
|
||||
void checkPass(bool ramsey_policy, WarningConsolidation &warnings) const;
|
||||
//! 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
|
||||
|
|
Loading…
Reference in New Issue