Steady state file: in the presence of 'ramsey_policy', no longer check that the declarations are recursive, and use input vector of steady state file as initial values

time-shift
Sébastien Villemot 2010-05-31 17:43:17 +02:00
parent 4cca2874ae
commit c58312d3b7
4 changed files with 55 additions and 46 deletions

View File

@ -93,6 +93,9 @@ ModFile::checkPass()
it != statements.end(); it++)
(*it)->checkPass(mod_file_struct);
// Check the steady state block
steady_state_model.checkPass(mod_file_struct.ramsey_policy_present);
// If order option has not been set, default to 2
if (!mod_file_struct.order_option)
mod_file_struct.order_option = 2;
@ -441,7 +444,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all
}
// Create steady state file
steady_state_model.writeSteadyStateFile(basename);
steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_policy_present);
cout << "done" << endl;
}

View File

@ -1869,18 +1869,7 @@ ParsingDriver::add_steady_state_model_equal(string *varname, NodeID expr)
if (type != eEndogenous && type != eModFileLocalVariable)
error(*varname + " has incorrect type");
try
{
mod_file->steady_state_model.addDefinition(id, expr);
}
catch(SteadyStateModel::AlreadyDefinedException &e)
{
error(*varname + " has already been defined in the steady state block");
}
catch(SteadyStateModel::UndefinedVariableException &e)
{
error(e.varname + " is not yet initialized at this point");
}
mod_file->steady_state_model.addDefinition(id, expr);
delete varname;
}

View File

@ -28,33 +28,50 @@ SteadyStateModel::SteadyStateModel(SymbolTable &symbol_table_arg, NumericalConst
}
void
SteadyStateModel::addDefinition(int symb_id, NodeID expr) throw (UndefinedVariableException, AlreadyDefinedException)
SteadyStateModel::addDefinition(int symb_id, NodeID expr)
{
assert(symbol_table.getType(symb_id) == eEndogenous
|| symbol_table.getType(symb_id) == eModFileLocalVariable);
// Check that symbol is not already defined
if (find(recursive_order.begin(), recursive_order.end(), symb_id)
!= recursive_order.end())
throw AlreadyDefinedException(symbol_table.getName(symb_id));
// Check that expression has no undefined symbol
set<pair<int, int> > used_symbols;
expr->collectVariables(eEndogenous, used_symbols);
expr->collectVariables(eModFileLocalVariable, used_symbols);
for(set<pair<int, int> >::const_iterator it = used_symbols.begin();
it != used_symbols.end(); it++)
if (find(recursive_order.begin(), recursive_order.end(), it->first)
== recursive_order.end())
throw UndefinedVariableException(symbol_table.getName(it->first));
// Add the variable
recursive_order.push_back(symb_id);
def_table[symb_id] = AddEqual(AddVariable(symb_id), expr);
}
void
SteadyStateModel::writeSteadyStateFile(const string &basename) const
SteadyStateModel::checkPass(bool ramsey_policy) const
{
for (vector<int>::const_iterator it = recursive_order.begin();
it != recursive_order.end(); ++it)
{
// Check that symbol is not already defined
if (find(recursive_order.begin(), it, *it) != it)
{
cerr << "ERROR: in the 'steady_state' block, variable '" << symbol_table.getName(*it) << "' is declared twice" << endl;
exit(EXIT_FAILURE);
}
// Check that expression has no undefined symbol
if (!ramsey_policy)
{
set<pair<int, int> > used_symbols;
NodeID expr = def_table.find(*it)->second;
expr->collectVariables(eEndogenous, used_symbols);
expr->collectVariables(eModFileLocalVariable, used_symbols);
for(set<pair<int, int> >::const_iterator it2 = used_symbols.begin();
it2 != used_symbols.end(); ++it2)
if (find(recursive_order.begin(), it, it2->first) == it
&& *it != it2->first)
{
cerr << "ERROR: in the 'steady_state' block, variable '" << symbol_table.getName(it2->first) << "' is undefined in the declaration of variable '" << symbol_table.getName(*it) << "'" << endl;
exit(EXIT_FAILURE);
}
}
}
}
void
SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_policy) const
{
if (recursive_order.size() == 0)
return;
@ -69,7 +86,12 @@ SteadyStateModel::writeSteadyStateFile(const string &basename) const
exit(EXIT_FAILURE);
}
output << "function [ys_, check_] = " << basename << "_steadystate(ys_orig_, exo_)" << endl
output << "function [ys_, check_] = " << basename << "_steadystate(";
if (ramsey_policy)
output << "ys_";
else
output << "ys_orig_";
output << ", exo_)" << endl
<< "% Steady state generated by Dynare preprocessor" << endl
<< " global M_" << endl
<< " ys_=zeros(" << symbol_table.orig_endo_nbr() << ",1);" << endl;

View File

@ -34,24 +34,19 @@ private:
const StaticModel &static_model;
public:
class AlreadyDefinedException
{
public:
const string &varname;
AlreadyDefinedException(const string &varname_arg) : varname(varname_arg) {}
};
class UndefinedVariableException
{
public:
const string &varname;
UndefinedVariableException(const string &varname_arg) : varname(varname_arg) {}
};
SteadyStateModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants, ExternalFunctionsTable &external_functions_table_arg, const StaticModel &static_model_arg);
//! Add an expression of the form "var = expr;"
void addDefinition(int symb_id, NodeID expr) throw (UndefinedVariableException, AlreadyDefinedException);
void addDefinition(int symb_id, NodeID expr);
//! Checks that definitions are in a recursive order, and that no variable is declared twice
/*!
\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;
//! Write the steady state file
void writeSteadyStateFile(const string &basename) const;
/*!
\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
*/
void writeSteadyStateFile(const string &basename, bool ramsey_policy) const;
};
#endif