Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

preprocessor: remove extra exogenous variables. closes #841

  • Loading branch information...
houtanb committed Aug 24, 2015
1 parent d280cbf commit c6e8a8b4729dcac93f22b02103b71596f26ec19e
@@ -3361,6 +3361,14 @@ DynamicModel::cloneDynamic(DynamicModel &dynamic_model) const
static_only_equations_lineno[i]);
}

void
DynamicModel::markUsedVarsInModel() const
{
for (vector<BinaryOpNode *>::const_iterator it = equations.begin();
it != equations.end(); it++)
(*it)->markUsedVars();
}

void
DynamicModel::replaceMyEquations(DynamicModel &dynamic_model) const
{
@@ -3518,17 +3526,10 @@ DynamicModel::findUnusedEndogenous()
return unusedEndo;
}

set<int>
vector<int>
DynamicModel::findUnusedExogenous()
{
set<int> usedExo, unusedExo;
for (int i = 0; i < (int) equations.size(); i++)
equations[i]->collectVariables(eExogenous, usedExo);
set<int> allExo = symbol_table.getExogenous();
set_difference(allExo.begin(), allExo.end(),
usedExo.begin(), usedExo.end(),
inserter(unusedExo, unusedExo.begin()));
return unusedExo;
return symbol_table.getUnusedExo();
}

void
@@ -230,7 +230,7 @@ public:
//! Find endogenous variables not used in model
set<int> findUnusedEndogenous();
//! Find exogenous variables not used in model
set<int> findUnusedExogenous();
vector<int> findUnusedExogenous();

//! Copies a dynamic model (only the equations)
/*! It assumes that the dynamic model given in argument has just been allocated */
@@ -241,6 +241,9 @@ public:
//! Replaces the model equations in dynamic_model with those in this model
void replaceMyEquations(DynamicModel &dynamic_model) const;

//! Mark variables/params used in model in the symbol table
void markUsedVarsInModel() const;

//! Adds an equation marked as [static]
void addStaticOnlyEquation(expr_t eq, int lineno);

@@ -335,6 +335,11 @@ NumConstNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> >
{
}

void
NumConstNode::markUsedVars() const
{
}

pair<int, expr_t >
NumConstNode::normalizeEquation(int var_endo, vector<pair<int, pair<expr_t, expr_t> > > &List_of_Op_RHS) const
{
@@ -898,6 +903,12 @@ VariableNode::computeTemporaryTerms(map<expr_t, int> &reference_count,
datatree.local_variables_table[symb_id]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation);
}

void
VariableNode::markUsedVars() const
{
datatree.symbol_table.markAsUsed(symb_id);
}

void
VariableNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const
{
@@ -2036,6 +2047,12 @@ UnaryOpNode::compile(ostream &CompileCode, unsigned int &instruction_number,
}
}

void
UnaryOpNode::markUsedVars() const
{
arg->markUsedVars();
}

void
UnaryOpNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const
{
@@ -3114,6 +3131,13 @@ BinaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &
dynamic, steady_dynamic, tef_terms);
}

void
BinaryOpNode::markUsedVars() const
{
arg1->markUsedVars();
arg2->markUsedVars();
}

void
BinaryOpNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const
{
@@ -4092,6 +4116,14 @@ TrinaryOpNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int
dynamic, steady_dynamic, tef_terms);
}

void
TrinaryOpNode::markUsedVars() const
{
arg1->markUsedVars();
arg2->markUsedVars();
arg3->markUsedVars();
}

void
TrinaryOpNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const
{
@@ -4390,6 +4422,14 @@ AbstractExternalFunctionNode::compileExternalFunctionArguments(ostream &CompileC
return (arguments.size());
}

void
AbstractExternalFunctionNode::markUsedVars() const
{
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
(*it)->markUsedVars();
}

void
AbstractExternalFunctionNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const
{
@@ -211,6 +211,9 @@ public:
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
deriv_node_temp_terms_t &tef_terms) const;

//! Marks variables as used in the symbol table
virtual void markUsedVars() const = 0;

//! Computes the set of all variables of a given symbol type in the expression (with information on lags)
/*!
Variables are stored as integer pairs of the form (symb_id, lag).
@@ -447,6 +450,7 @@ public:
virtual void prepareForDerivation();
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void markUsedVars() const;
virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException);
@@ -493,6 +497,7 @@ public:
virtual void prepareForDerivation();
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void markUsedVars() const;
virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void computeTemporaryTerms(map<expr_t, int> &reference_count,
temporary_terms_t &temporary_terms,
@@ -573,6 +578,7 @@ public:
int Curr_block,
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const;
virtual void markUsedVars() const;
virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException, EvalExternalFunctionException);
@@ -652,6 +658,7 @@ public:
int Curr_block,
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const;
virtual void markUsedVars() const;
virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
static double eval_opcode(double v1, BinaryOpcode op_code, double v2, int derivOrder) throw (EvalException, EvalExternalFunctionException);
@@ -747,6 +754,7 @@ public:
int Curr_block,
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const;
virtual void markUsedVars() const;
virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException, EvalExternalFunctionException);
@@ -819,6 +827,7 @@ public:
int Curr_block,
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const = 0;
virtual void markUsedVars() const;
virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException);
@@ -291,28 +291,30 @@ ModFile::checkPass()
cerr << ") also appear in the expressions defining the variance/covariance matrix of shocks; this is not allowed." << endl;
exit(EXIT_FAILURE);
}
}

void
ModFile::transformPass(bool nostrict)
{
// Save the original model (must be done before any model transformations by preprocessor)
dynamic_model.cloneDynamic(original_model);

// Check if some exogenous is not used in the model block
set<int> unusedExo = dynamic_model.findUnusedExogenous();
dynamic_model.markUsedVarsInModel();
// Check an exogenous variable is not used in the model block
vector<int> unusedExo = dynamic_model.findUnusedExogenous();
if (unusedExo.size() > 0)
{
warnings << "WARNING: some exogenous (";
for (set<int>::const_iterator it = unusedExo.begin();
warnings << "WARNING: the following exogenous variables are declared "
<< "but not used in the model and will be removed: ";
for (vector<int>::const_iterator it = unusedExo.begin();
it != unusedExo.end(); )
{
warnings << symbol_table.getName(*it);
if (++it != unusedExo.end())
warnings << ", ";
}
warnings << ") are declared but not used in the model. This may lead to crashes or unexpected behaviour." << endl;
warnings << endl;
}
}

void
ModFile::transformPass(bool nostrict)
{
// Save the original model (must be done before any model transformations by preprocessor)
dynamic_model.cloneDynamic(original_model);

if (nostrict)
{
@@ -78,6 +78,7 @@ SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_na
name_table.push_back(name);
tex_name_table.push_back(final_tex_name);
long_name_table.push_back(final_long_name);
used_in_model.push_back(false);

return id;
}
@@ -106,8 +107,13 @@ SymbolTable::freeze() throw (FrozenException)
endo_ids.push_back(i);
break;
case eExogenous:
tsi = exo_ids.size();
exo_ids.push_back(i);
if (!used_in_model[i])
tsi = -1;
else
{
tsi = exo_ids.size();
exo_ids.push_back(i);
}
break;
case eExogenousDet:
tsi = exo_det_ids.size();
@@ -137,6 +143,16 @@ SymbolTable::changeType(int id, SymbolType newtype) throw (UnknownSymbolIDExcept
type_table[id] = newtype;
}

vector<int>
SymbolTable::getUnusedExo() const throw (NotYetFrozenException)
{
vector<int> unusedExo;
for (int i = 0; i < used_in_model.size(); i++)
if (!used_in_model[i] && getType(i) == eExogenous)
unusedExo.push_back(i);
return unusedExo;
}

int
SymbolTable::getID(SymbolType type, int tsid) const throw (UnknownTypeSpecificIDException, NotYetFrozenException)
{
@@ -98,6 +98,8 @@ private:
vector<string> long_name_table;
//! Maps IDs to types
vector<SymbolType> type_table;
//! Maps IDs to whether or not they're used in the model block
vector<bool> used_in_model;

//! Maps symbol IDs to type specific IDs
vector<int> type_specific_ids;
@@ -269,6 +271,10 @@ public:
inline int getTypeSpecificID(int id) const throw (UnknownSymbolIDException, NotYetFrozenException);
//! Get type specific ID (by symbol name)
inline int getTypeSpecificID(const string &name) const throw (UnknownSymbolNameException, NotYetFrozenException);
//! Mark the given symbol as used in the model
inline void markAsUsed(int id) throw (FrozenException);
//! Return a vector of unused exogenous variables
vector<int> getUnusedExo() const throw (NotYetFrozenException);
//! Get number of endogenous variables
inline int endo_nbr() const throw (NotYetFrozenException);
//! Get number of exogenous variables
@@ -371,6 +377,15 @@ SymbolTable::getID(const string &name) const throw (UnknownSymbolNameException)
throw UnknownSymbolNameException(name);
}

inline void
SymbolTable::markAsUsed(int id) throw (FrozenException)
{
if (frozen)
throw FrozenException();

used_in_model[id] = true;
}

inline int
SymbolTable::getTypeSpecificID(int id) const throw (UnknownSymbolIDException, NotYetFrozenException)
{
@@ -380,6 +395,13 @@ SymbolTable::getTypeSpecificID(int id) const throw (UnknownSymbolIDException, No
if (id < 0 || id >= size)
throw UnknownSymbolIDException(id);

if (type_specific_ids[id] < 0 && getType(id) == eExogenous)
{
cerr << "Error: You tried to access an exogenous variable that was not used in the model block: "
<< getName(id) << endl;
exit(EXIT_FAILURE);
}

return type_specific_ids[id];
}

0 comments on commit c6e8a8b

Please sign in to comment.
You can’t perform that action at this time.