parent
24cac29cdf
commit
75f8467803
|
@ -2354,6 +2354,12 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
|
|||
<< equation_tags[i].second.second << "' ;" << endl;
|
||||
output << "};" << endl;
|
||||
|
||||
/* Say if static and dynamic models differ (because of [static] and [dynamic]
|
||||
equation tags) */
|
||||
output << "M_.static_and_dynamic_models_differ = "
|
||||
<< (static_only_equations.size() > 0 ? "1" : "0")
|
||||
<< ";" << endl;
|
||||
|
||||
//In case of sparse model, writes the block_decomposition structure of the model
|
||||
if (block_decomposition)
|
||||
{
|
||||
|
@ -3403,6 +3409,11 @@ DynamicModel::cloneDynamic(DynamicModel &dynamic_model) const
|
|||
for (deque<BinaryOpNode *>::const_iterator it = aux_equations.begin();
|
||||
it != aux_equations.end(); it++)
|
||||
dynamic_model.addAuxEquation((*it)->cloneDynamic(dynamic_model));
|
||||
|
||||
// Convert static_only equations
|
||||
for (vector<BinaryOpNode *>::const_iterator it = static_only_equations.begin();
|
||||
it != static_only_equations.end(); it++)
|
||||
dynamic_model.addStaticOnlyEquation((*it)->cloneDynamic(dynamic_model));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3506,9 +3517,28 @@ DynamicModel::toStatic(StaticModel &static_model) const
|
|||
static_model.AddLocalVariable(it->first, it->second->toStatic(static_model));
|
||||
|
||||
// Convert equations
|
||||
for (vector<BinaryOpNode *>::const_iterator it = equations.begin();
|
||||
it != equations.end(); it++)
|
||||
static_model.addEquation((*it)->toStatic(static_model));
|
||||
int static_only_index = 0;
|
||||
for (int i = 0; i < (int) equations.size(); i++)
|
||||
{
|
||||
// Detect if equation is marked [dynamic]
|
||||
bool is_dynamic_only = false;
|
||||
for (vector<pair<int, pair<string, string> > >::const_iterator it = equation_tags.begin();
|
||||
it != equation_tags.end(); ++it)
|
||||
if (it->first == i && it->second.first == "dynamic")
|
||||
{
|
||||
is_dynamic_only = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// If yes, replace it by an equation marked [static]
|
||||
if (is_dynamic_only)
|
||||
{
|
||||
static_model.addEquation(static_only_equations[static_only_index]->toStatic(static_model));
|
||||
static_only_index++;
|
||||
}
|
||||
else
|
||||
static_model.addEquation(equations[i]->toStatic(static_model));
|
||||
}
|
||||
|
||||
// Convert auxiliary equations
|
||||
for (deque<BinaryOpNode *>::const_iterator it = aux_equations.begin();
|
||||
|
@ -4150,3 +4180,32 @@ DynamicModel::isModelLocalVariableUsed() const
|
|||
}
|
||||
return used_local_vars.size() > 0;
|
||||
}
|
||||
|
||||
void
|
||||
DynamicModel::addStaticOnlyEquation(expr_t eq)
|
||||
{
|
||||
BinaryOpNode *beq = dynamic_cast<BinaryOpNode *>(eq);
|
||||
assert(beq != NULL && beq->get_op_code() == oEqual);
|
||||
|
||||
static_only_equations.push_back(beq);
|
||||
}
|
||||
|
||||
size_t
|
||||
DynamicModel::staticOnlyEquationsNbr() const
|
||||
{
|
||||
return static_only_equations.size();
|
||||
}
|
||||
|
||||
size_t
|
||||
DynamicModel::dynamicOnlyEquationsNbr() const
|
||||
{
|
||||
set<int> eqs;
|
||||
|
||||
for (vector<pair<int, pair<string, string> > >::const_iterator it = equation_tags.begin();
|
||||
it != equation_tags.end(); ++it)
|
||||
if (it->second.first == "dynamic")
|
||||
eqs.insert(it->first);
|
||||
|
||||
return eqs.size();
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@ using namespace std;
|
|||
class DynamicModel : public ModelTree
|
||||
{
|
||||
private:
|
||||
//! Stores equations declared as [static]
|
||||
/*! They will be used in toStatic() to replace equations marked as [dynamic] */
|
||||
vector<BinaryOpNode *> static_only_equations;
|
||||
|
||||
typedef map<pair<int, int>, int> deriv_id_table_t;
|
||||
//! Maps a pair (symbol_id, lag) to a deriv ID
|
||||
deriv_id_table_t deriv_id_table;
|
||||
|
@ -224,6 +228,15 @@ public:
|
|||
//! Replaces the model equations in dynamic_model with those in this model
|
||||
void replaceMyEquations(DynamicModel &dynamic_model) const;
|
||||
|
||||
//! Adds an equation marked as [static]
|
||||
void addStaticOnlyEquation(expr_t eq);
|
||||
|
||||
//! Returns number of static only equations
|
||||
size_t staticOnlyEquationsNbr() const;
|
||||
|
||||
//! Returns number of dynamic only equations
|
||||
size_t dynamicOnlyEquationsNbr() const;
|
||||
|
||||
//! Writes LaTeX file with the equations of the dynamic model
|
||||
void writeLatexFile(const string &basename) const;
|
||||
|
||||
|
|
|
@ -603,6 +603,8 @@ tags_list : tags_list COMMA tag_pair
|
|||
|
||||
tag_pair : NAME EQUAL QUOTED_STRING
|
||||
{ driver.add_equation_tags($1, $3); }
|
||||
| NAME
|
||||
{ driver.add_equation_tags($1, new string()); }
|
||||
;
|
||||
|
||||
hand_side : '(' hand_side ')'
|
||||
|
|
45
ExprNode.cc
45
ExprNode.cc
|
@ -469,6 +469,12 @@ NumConstNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const
|
|||
return const_cast<NumConstNode *>(this);
|
||||
}
|
||||
|
||||
bool
|
||||
NumConstNode::isInStaticForm() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
VariableNode::VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg) :
|
||||
ExprNode(datatree_arg),
|
||||
symb_id(symb_id_arg),
|
||||
|
@ -1314,6 +1320,12 @@ VariableNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
VariableNode::isInStaticForm() const
|
||||
{
|
||||
return lag == 0;
|
||||
}
|
||||
|
||||
UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg) :
|
||||
ExprNode(datatree_arg),
|
||||
arg(arg_arg),
|
||||
|
@ -2322,6 +2334,17 @@ UnaryOpNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const
|
|||
return buildSimilarUnaryOpNode(argsubst, datatree);
|
||||
}
|
||||
|
||||
bool
|
||||
UnaryOpNode::isInStaticForm() const
|
||||
{
|
||||
if (op_code == oSteadyState || op_code == oSteadyStateParamDeriv
|
||||
|| op_code == oSteadyStateParam2ndDeriv
|
||||
|| op_code == oExpectation)
|
||||
return false;
|
||||
else
|
||||
return arg->isInStaticForm();
|
||||
}
|
||||
|
||||
BinaryOpNode::BinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg,
|
||||
BinaryOpcode op_code_arg, const expr_t arg2_arg) :
|
||||
ExprNode(datatree_arg),
|
||||
|
@ -3558,6 +3581,12 @@ BinaryOpNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const
|
|||
return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
|
||||
}
|
||||
|
||||
bool
|
||||
BinaryOpNode::isInStaticForm() const
|
||||
{
|
||||
return arg1->isInStaticForm() && arg2->isInStaticForm();
|
||||
}
|
||||
|
||||
TrinaryOpNode::TrinaryOpNode(DataTree &datatree_arg, const expr_t arg1_arg,
|
||||
TrinaryOpcode op_code_arg, const expr_t arg2_arg, const expr_t arg3_arg) :
|
||||
ExprNode(datatree_arg),
|
||||
|
@ -4155,6 +4184,12 @@ TrinaryOpNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const
|
|||
return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
|
||||
}
|
||||
|
||||
bool
|
||||
TrinaryOpNode::isInStaticForm() const
|
||||
{
|
||||
return arg1->isInStaticForm() && arg2->isInStaticForm() && arg3->isInStaticForm();
|
||||
}
|
||||
|
||||
ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg,
|
||||
int symb_id_arg,
|
||||
const vector<expr_t> &arguments_arg) :
|
||||
|
@ -4732,6 +4767,16 @@ ExternalFunctionNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) con
|
|||
return buildSimilarExternalFunctionNode(arguments_subst, datatree);
|
||||
}
|
||||
|
||||
bool
|
||||
ExternalFunctionNode::isInStaticForm() const
|
||||
{
|
||||
for (vector<expr_t>::const_iterator it = arguments.begin(); it != arguments.end(); ++it)
|
||||
if (!(*it)->isInStaticForm())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FirstDerivExternalFunctionNode::FirstDerivExternalFunctionNode(DataTree &datatree_arg,
|
||||
int top_level_symb_id_arg,
|
||||
const vector<expr_t> &arguments_arg,
|
||||
|
|
11
ExprNode.hh
11
ExprNode.hh
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2012 Dynare Team
|
||||
* Copyright (C) 2007-2013 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -393,6 +393,9 @@ public:
|
|||
|
||||
//! Move a trend variable with lag/lead to time t by dividing/multiplying by its growth factor
|
||||
virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const = 0;
|
||||
|
||||
//! Returns true if the expression is in static form (no lead, no lag, no expectation, no STEADY_STATE)
|
||||
virtual bool isInStaticForm() const = 0;
|
||||
};
|
||||
|
||||
//! Object used to compare two nodes (using their indexes)
|
||||
|
@ -448,6 +451,7 @@ public:
|
|||
virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const;
|
||||
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
|
||||
virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
|
||||
virtual bool isInStaticForm() const;
|
||||
};
|
||||
|
||||
//! Symbol or variable node
|
||||
|
@ -508,6 +512,7 @@ public:
|
|||
virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const;
|
||||
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
|
||||
virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
|
||||
virtual bool isInStaticForm() const;
|
||||
};
|
||||
|
||||
//! Unary operator node
|
||||
|
@ -583,6 +588,7 @@ public:
|
|||
virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const;
|
||||
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
|
||||
virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
|
||||
virtual bool isInStaticForm() const;
|
||||
};
|
||||
|
||||
//! Binary operator node
|
||||
|
@ -677,6 +683,7 @@ public:
|
|||
expr_t addMultipliersToConstraints(int i);
|
||||
//! Returns the non-zero hand-side of an equation (that must have a hand side equal to zero)
|
||||
expr_t getNonZeroPartofEquation() const;
|
||||
virtual bool isInStaticForm() const;
|
||||
};
|
||||
|
||||
//! Trinary operator node
|
||||
|
@ -739,6 +746,7 @@ public:
|
|||
virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const;
|
||||
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
|
||||
virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
|
||||
virtual bool isInStaticForm() const;
|
||||
};
|
||||
|
||||
//! External function node
|
||||
|
@ -812,6 +820,7 @@ public:
|
|||
virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const;
|
||||
virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const;
|
||||
virtual expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const;
|
||||
virtual bool isInStaticForm() const;
|
||||
};
|
||||
|
||||
class FirstDerivExternalFunctionNode : public ExternalFunctionNode
|
||||
|
|
13
ModFile.cc
13
ModFile.cc
|
@ -236,6 +236,19 @@ ModFile::checkPass()
|
|||
<< "(deprecated) or the dsge_var option must be passed to the estimation statement (preferred)." << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (dynamic_model.staticOnlyEquationsNbr() != dynamic_model.dynamicOnlyEquationsNbr())
|
||||
{
|
||||
cerr << "ERROR: the number of equations marked [static] must be equal to the number of equations marked [dynamic]" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (dynamic_model.staticOnlyEquationsNbr() > 0 &&
|
||||
(mod_file_struct.ramsey_policy_present || mod_file_struct.discretionary_policy_present))
|
||||
{
|
||||
cerr << "ERROR: marking equations as [static] or [dynamic] is not possible with ramsey_policy or discretionary_policy" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1385,9 +1385,12 @@ ModelTree::addEquation(expr_t eq)
|
|||
}
|
||||
|
||||
void
|
||||
ModelTree::addEquationTags(int i, const string &key, const string &value)
|
||||
ModelTree::addEquation(expr_t eq, vector<pair<string, string> > &eq_tags)
|
||||
{
|
||||
equation_tags.push_back(make_pair(i, make_pair(key, value)));
|
||||
int n = equation_number();
|
||||
for (size_t i = 0; i < eq_tags.size(); i++)
|
||||
equation_tags.push_back(make_pair(n, eq_tags[i]));
|
||||
addEquation(eq);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -297,8 +297,8 @@ public:
|
|||
int mfs;
|
||||
//! Declare a node as an equation of the model
|
||||
void addEquation(expr_t eq);
|
||||
//! Adds tags to equation number i
|
||||
void addEquationTags(int i, const string &key, const string &value);
|
||||
//! Declare a node as an equation of the model, also giving its tags
|
||||
void addEquation(expr_t eq, vector<pair<string, string> > &eq_tags);
|
||||
//! Declare a node as an auxiliary equation of the model, adding it at the end of the list of auxiliary equations
|
||||
void addAuxEquation(expr_t eq);
|
||||
//! Returns the number of equations in the model
|
||||
|
|
|
@ -249,8 +249,7 @@ ParsingDriver::add_predetermined_variable(string *name)
|
|||
void
|
||||
ParsingDriver::add_equation_tags(string *key, string *value)
|
||||
{
|
||||
int n = model_tree->equation_number();
|
||||
model_tree->addEquationTags(n, *key, *value);
|
||||
eq_tags.push_back(make_pair(*key, *value));
|
||||
delete key;
|
||||
delete value;
|
||||
}
|
||||
|
@ -1933,7 +1932,28 @@ expr_t
|
|||
ParsingDriver::add_model_equal(expr_t arg1, expr_t arg2)
|
||||
{
|
||||
expr_t id = model_tree->AddEqual(arg1, arg2);
|
||||
model_tree->addEquation(id);
|
||||
|
||||
// Detect if the equation is tagged [static]
|
||||
bool is_static_only = false;
|
||||
for (vector<pair<string, string> >::const_iterator it = eq_tags.begin();
|
||||
it != eq_tags.end(); ++it)
|
||||
if (it->first == "static")
|
||||
{
|
||||
is_static_only = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_static_only)
|
||||
{
|
||||
if (!id->isInStaticForm())
|
||||
error("An equation tagged [static] cannot contain leads, lags, expectations or STEADY_STATE operators");
|
||||
|
||||
dynamic_model->addStaticOnlyEquation(id);
|
||||
}
|
||||
else
|
||||
model_tree->addEquation(id, eq_tags);
|
||||
|
||||
eq_tags.clear();
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
|
@ -201,6 +201,8 @@ private:
|
|||
expr_t add_model_variable(int symb_id, int lag);
|
||||
//! For parsing the graph_format option
|
||||
SymbolList graph_formats;
|
||||
//! Temporary storage for equation tags
|
||||
vector<pair<string, string> > eq_tags;
|
||||
|
||||
//! The mod file representation constructed by this ParsingDriver
|
||||
ModFile *mod_file;
|
||||
|
|
Loading…
Reference in New Issue