trend_component_model statement

issue#70
Houtan Bastani 2018-08-14 14:23:21 +02:00
parent 618147a126
commit afe0e475b1
21 changed files with 783 additions and 326 deletions

View File

@ -258,16 +258,14 @@ PriorPosteriorFunctionStatement::writeJsonOutput(ostream &output) const
}
PacModelStatement::PacModelStatement(string name_arg,
string var_name_arg,
string aux_model_name_arg,
string discount_arg,
string growth_arg,
map<string, int> undiff_arg,
const SymbolTable &symbol_table_arg) :
name{move(name_arg)},
var_name{move(var_name_arg)},
aux_model_name{move(aux_model_name_arg)},
discount{move(discount_arg)},
growth{move(growth_arg)},
undiff{move(undiff_arg)},
symbol_table{symbol_table_arg}
{
}
@ -289,7 +287,7 @@ PacModelStatement::fillUndiffedLHS(vector<int> &lhs_arg)
void
PacModelStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
{
output << "M_.pac." << name << ".var_model_name = '" << var_name << "';" << endl
output << "M_.pac." << name << ".auxiliary_model_name = '" << aux_model_name << "';" << endl
<< "M_.pac." << name << ".discount_index = " << symbol_table.getTypeSpecificID(discount) + 1 << ";" << endl;
if (!growth.empty())
@ -320,7 +318,8 @@ PacModelStatement::writeOutput(ostream &output, const string &basename, bool min
output << " ";
output << *it + 1;
}
output << "];" << endl
output << "];" << endl;
/*
<< "M_.pac." << name << ".undiff_eqtags = {";
for (auto it = undiff.begin(); it != undiff.end(); it++)
{
@ -337,6 +336,7 @@ PacModelStatement::writeOutput(ostream &output, const string &basename, bool min
output << it->second;
}
output << "];" << endl;
*/
}
void
@ -344,7 +344,7 @@ PacModelStatement::writeJsonOutput(ostream &output) const
{
output << "{\"statementName\": \"pac_model\","
<< "\"model_name\": \"" << name << "\","
<< "\"var_model_name\": \"" << var_name << "\","
<< "\"auxiliary_model_name\": \"" << aux_model_name << "\","
<< "\"discount_index\": " << symbol_table.getTypeSpecificID(discount) + 1;
if (!growth.empty())
@ -371,13 +371,13 @@ PacModelStatement::writeJsonOutput(ostream &output) const
output << "}";
}
void
PacModelStatement::getPacModelInfoForPacExpectation(tuple<string, string, string, int, map<string, int>> &pac_model_info) const
tuple<string, string, int>
PacModelStatement::getPacModelInfoForPacExpectation() const
{
int growth_symb_id = -1;
if (!growth.empty())
growth_symb_id = symbol_table.getID(growth);
pac_model_info = { name, var_name, discount, growth_symb_id, undiff };
return { name, aux_model_name, growth_symb_id };
}
VarModelStatement::VarModelStatement(SymbolList symbol_list_arg,
@ -2207,8 +2207,12 @@ ModelComparisonStatement::writeJsonOutput(ostream &output) const
output << "}";
}
PlannerObjectiveStatement::PlannerObjectiveStatement(SymbolTable &symbol_table, NumericalConstants &num_constants, ExternalFunctionsTable &external_functions_table) :
model_tree{symbol_table, num_constants, external_functions_table}
PlannerObjectiveStatement::PlannerObjectiveStatement(SymbolTable &symbol_table,
NumericalConstants &num_constants,
ExternalFunctionsTable &external_functions_table,
TrendComponentModelTable &trend_component_model_table_arg) :
model_tree{symbol_table, num_constants,
external_functions_table, trend_component_model_table_arg}
{
}

View File

@ -123,24 +123,22 @@ class PacModelStatement : public Statement
{
private:
const string name;
const string var_name;
const string aux_model_name;
const string discount;
const string growth;
const map<string, int> undiff;
const SymbolTable &symbol_table;
vector<int> lhs;
public:
PacModelStatement(string name_arg,
string var_name_arg,
string aux_model_name_arg,
string discount_arg,
string growth_arg,
map<string, int> undiff_arg,
const SymbolTable &symbol_table_arg);
void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override;
void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream &output) const override;
void fillUndiffedLHS(vector<int> &lhs);
void getPacModelInfoForPacExpectation(tuple<string, string, string, int, map<string, int>> &pac_model_info) const;
tuple<string, string, int> getPacModelInfoForPacExpectation() const;
};
class VarModelStatement : public Statement
@ -542,7 +540,8 @@ private:
public:
PlannerObjectiveStatement(SymbolTable &symbol_table,
NumericalConstants &num_constants,
ExternalFunctionsTable &external_functions_table);
ExternalFunctionsTable &external_functions_table,
TrendComponentModelTable &trend_component_model_table_arg);
/*! \todo check there are only endogenous variables at the current period in the objective
(no exogenous, no lead/lag) */
void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override;

View File

@ -28,10 +28,12 @@
DataTree::DataTree(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg) :
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg) :
symbol_table(symbol_table_arg),
num_constants(num_constants_arg),
external_functions_table(external_functions_table_arg),
trend_component_model_table(trend_component_model_table_arg),
node_counter(0)
{
Zero = AddNonNegativeConstant("0");

View File

@ -34,6 +34,7 @@ using namespace std;
#include "NumericalConstants.hh"
#include "ExternalFunctionsTable.hh"
#include "ExprNode.hh"
#include "SubModel.hh"
class DataTree
{
@ -56,6 +57,8 @@ protected:
NumericalConstants &num_constants;
//! A reference to the external functions table
ExternalFunctionsTable &external_functions_table;
//! A reference to the trend component model table
TrendComponentModelTable &trend_component_model_table;
//! num_constant_id -> NumConstNode
using num_const_node_map_t = map<int, NumConstNode *>;
@ -130,7 +133,10 @@ private:
inline expr_t AddTrinaryOp(expr_t arg1, TrinaryOpcode op_code, expr_t arg2, expr_t arg3);
public:
DataTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg);
DataTree(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg);
virtual
~DataTree();

View File

@ -33,8 +33,10 @@
DynamicModel::DynamicModel(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg) :
ModelTree(symbol_table_arg, num_constants_arg, external_functions_table_arg),
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg) :
ModelTree(symbol_table_arg, num_constants_arg,
external_functions_table_arg, trend_component_model_table_arg),
max_lag(0), max_lead(0),
max_endo_lag(0), max_endo_lead(0),
max_exo_lag(0), max_exo_lead(0),
@ -3453,153 +3455,192 @@ DynamicModel::runTrendTest(const eval_context_t &eval_context)
}
void
DynamicModel::getVarModelVariablesFromEqTags(vector<string> &var_model_eqtags,
vector<int> &eqnumber,
vector<int> &lhs,
vector<expr_t> &lhs_expr_t,
vector<set<pair<int, int>>> &rhs,
vector<bool> &nonstationary) const
DynamicModel::fillTrendComponentModelTable() const
{
for (vector<string>::const_iterator itvareqs = var_model_eqtags.begin();
itvareqs != var_model_eqtags.end(); itvareqs++)
map<string, vector<int>> eqnums, trend_eqnums, lhsr;
map<string, vector<expr_t>> lhs_expr_tr;
map<string, vector<bool>> nonstationaryr;
map<string, vector<set<pair<int, int>>>> rhsr;
map<string, vector<string>> eqtags = trend_component_model_table.getEqTags();
map<string, vector<string>> trend_eqtags = trend_component_model_table.getTrendEqTags();
for (const auto &it : trend_eqtags)
{
int eqn = -1;
set<pair<int, int>> lhs_set, lhs_tmp_set, rhs_set;
string eqtag (*itvareqs);
for (const auto & equation_tag : equation_tags)
if (equation_tag.second.first == "name"
&& equation_tag.second.second == eqtag)
{
eqn = equation_tag.first;
break;
}
if (eqn == -1)
vector<int> trend_eqnumber;
for (const auto &eqtag : it.second)
{
cerr << "ERROR: equation tag '" << eqtag << "' not found" << endl;
exit(EXIT_FAILURE);
}
int eqn = -1;
for (const auto &equation_tag : equation_tags)
if (equation_tag.second.first == "name"
&& equation_tag.second.second == eqtag)
{
eqn = equation_tag.first;
break;
}
bool nonstationary_bool = false;
for (const auto & equation_tag : equation_tags)
if (equation_tag.first == eqn)
if (equation_tag.second.first == "data_type"
&& equation_tag.second.second == "nonstationary")
if (eqn == -1)
{
nonstationary_bool = true;
break;
}
nonstationary.push_back(nonstationary_bool);
equations[eqn]->get_arg1()->collectDynamicVariables(SymbolType::endogenous, lhs_set);
equations[eqn]->get_arg1()->collectDynamicVariables(SymbolType::exogenous, lhs_tmp_set);
equations[eqn]->get_arg1()->collectDynamicVariables(SymbolType::parameter, lhs_tmp_set);
if (lhs_set.size() != 1 || !lhs_tmp_set.empty())
{
cerr << "ERROR: in Equation " << eqtag
<< ". A VAR may only have one endogenous variable on the LHS. " << endl;
exit(EXIT_FAILURE);
}
auto it = lhs_set.begin();
if (it->second != 0)
{
cerr << "ERROR: in Equation " << eqtag
<< ". The variable on the LHS of a VAR may not appear with a lead or a lag. "
<< endl;
exit(EXIT_FAILURE);
}
eqnumber.push_back(eqn);
lhs.push_back(it->first);
lhs_set.clear();
set<expr_t> lhs_expr_t_set;
equations[eqn]->get_arg1()->collectVARLHSVariable(lhs_expr_t_set);
lhs_expr_t.push_back(*(lhs_expr_t_set.begin()));
equations[eqn]->get_arg2()->collectDynamicVariables(SymbolType::endogenous, rhs_set);
for (it = rhs_set.begin(); it != rhs_set.end(); it++)
if (it->second > 0)
{
cerr << "ERROR: in Equation " << eqtag
<< ". A VAR may not have leaded or contemporaneous variables on the RHS. " << endl;
exit(EXIT_FAILURE);
}
rhs.push_back(rhs_set);
}
}
void
DynamicModel::checkVarMinLag(vector<int> &eqnumber) const
{
int eqn = 1;
for (vector<int>::const_iterator it = eqnumber.begin();
it != eqnumber.end(); it++, eqn++)
{
int min_lag = -1;
min_lag = equations[*it]->get_arg2()->VarMinLag();
if (min_lag <= 0)
{
cerr << "ERROR in VAR Equation #" << eqn << ". "
<< "Leaded exogenous variables and leaded or contemporaneous endogenous variables not allowed in VAR";
exit(EXIT_FAILURE);
}
}
}
int
DynamicModel::getVarMaxLag(StaticModel &static_model, vector<int> &eqnumber) const
{
set<expr_t> lhs;
for (vector<int>::const_iterator it = eqnumber.begin();
it != eqnumber.end(); it++)
equations[*it]->get_arg1()->collectVARLHSVariable(lhs);
if (eqnumber.size() != lhs.size())
{
cerr << "The LHS variables of the VAR are not unique" << endl;
exit(EXIT_FAILURE);
}
set<expr_t> lhs_static;
for(auto lh : lhs)
lhs_static.insert(lh->toStatic(static_model));
int max_lag = 0;
for (vector<int>::const_iterator it = eqnumber.begin();
it != eqnumber.end(); it++)
max_lag = max(max_lag,
equations[*it]->get_arg2()->VarMaxLag(static_model, lhs_static));
return max_lag;
}
void
DynamicModel::getVarLhsDiffAndInfo(vector<int> &eqnumber, vector<bool> &diff,
vector<int> &orig_diff_var) const
{
for (vector<int>::const_iterator it = eqnumber.begin();
it != eqnumber.end(); it++)
{
equations[*it]->get_arg1()->countDiffs() > 0 ? diff.push_back(true) : diff.push_back(false);
if (diff.back())
{
set<pair<int, int>> diff_set;
equations[*it]->get_arg1()->collectDynamicVariables(SymbolType::endogenous, diff_set);
if (diff_set.size() != 1)
{
cerr << "ERROR: problem getting variable for LHS diff operator in equation " << *it << endl;
cerr << "ERROR: trend equation tag '" << eqtag << "' not found" << endl;
exit(EXIT_FAILURE);
}
orig_diff_var.push_back(diff_set.begin()->first);
trend_eqnumber.push_back(eqn);
}
else
orig_diff_var.push_back(-1);
trend_eqnums[it.first] = trend_eqnumber;
}
for (const auto &it : eqtags)
{
vector<int> eqnumber, lhs;
vector<expr_t> lhs_expr_t;
vector<set<pair<int, int>>> rhs;
vector<bool> nonstationary;
for (const auto &eqtag : it.second)
{
int eqn = -1;
set<pair<int, int>> lhs_set, lhs_tmp_set, rhs_set;
for (const auto &equation_tag : equation_tags)
if (equation_tag.second.first == "name"
&& equation_tag.second.second == eqtag)
{
eqn = equation_tag.first;
break;
}
if (eqn == -1)
{
cerr << "ERROR: equation tag '" << eqtag << "' not found" << endl;
exit(EXIT_FAILURE);
}
bool nonstationary_bool = false;
for (const auto &equation_tag : equation_tags)
if (equation_tag.first == eqn)
if (equation_tag.second.first == "data_type"
&& equation_tag.second.second == "nonstationary")
{
nonstationary_bool = true;
break;
}
nonstationary.push_back(nonstationary_bool);
equations[eqn]->get_arg1()->collectDynamicVariables(SymbolType::endogenous, lhs_set);
equations[eqn]->get_arg1()->collectDynamicVariables(SymbolType::exogenous, lhs_tmp_set);
equations[eqn]->get_arg1()->collectDynamicVariables(SymbolType::parameter, lhs_tmp_set);
if (lhs_set.size() != 1 || !lhs_tmp_set.empty())
{
cerr << "ERROR: in Equation " << eqtag
<< ". A VAR may only have one endogenous variable on the LHS. " << endl;
exit(EXIT_FAILURE);
}
auto it = lhs_set.begin();
if (it->second != 0)
{
cerr << "ERROR: in Equation " << eqtag
<< ". The variable on the LHS of a VAR may not appear with a lead or a lag. "
<< endl;
exit(EXIT_FAILURE);
}
eqnumber.push_back(eqn);
lhs.push_back(it->first);
lhs_set.clear();
set<expr_t> lhs_expr_t_set;
equations[eqn]->get_arg1()->collectVARLHSVariable(lhs_expr_t_set);
lhs_expr_t.push_back(*(lhs_expr_t_set.begin()));
equations[eqn]->get_arg2()->collectDynamicVariables(SymbolType::endogenous, rhs_set);
for (it = rhs_set.begin(); it != rhs_set.end(); it++)
if (it->second > 0)
{
cerr << "ERROR: in Equation " << eqtag
<< ". A VAR may not have leaded or contemporaneous variables on the RHS. " << endl;
exit(EXIT_FAILURE);
}
rhs.push_back(rhs_set);
}
eqnums[it.first] = eqnumber;
lhsr[it.first] = lhs;
lhs_expr_tr[it.first] = lhs_expr_t;
rhsr[it.first] = rhs;
nonstationaryr[it.first] = nonstationary;
}
trend_component_model_table.setEqNums(eqnums);
trend_component_model_table.setTrendEqNums(trend_eqnums);
trend_component_model_table.setLhs(lhsr);
trend_component_model_table.setRhs(rhsr);
trend_component_model_table.setLhsExprT(lhs_expr_tr);
trend_component_model_table.setNonstationary(nonstationaryr);
}
void
DynamicModel::fillTrendComponentModelTableFromOrigModel(StaticModel &static_model) const
{
map<string, vector<int>> lags, orig_diff_var;
map<string, vector<bool>> diff;
for (const auto &it : trend_component_model_table.getEqNums())
{
set<expr_t> lhs;
vector<int> orig_diff_var_vec;
vector<bool> diff_vec;
for (auto eqn : it.second)
{
// ensure no leads in equations
if (equations[eqn]->get_arg2()->VarMinLag() <= 0)
{
cerr << "ERROR in VAR Equation (#" << eqn << "). "
<< "Leaded exogenous variables "
<< "and leaded or contemporaneous endogenous variables not allowed in VAR"
<< endl;
exit(EXIT_FAILURE);
}
// save lhs variables
equations[eqn]->get_arg1()->collectVARLHSVariable(lhs);
equations[eqn]->get_arg1()->countDiffs() > 0 ?
diff_vec.push_back(true) : diff_vec.push_back(false);
if (diff_vec.back())
{
set<pair<int, int>> diff_set;
equations[eqn]->get_arg1()->collectDynamicVariables(SymbolType::endogenous, diff_set);
if (diff_set.size() != 1)
{
cerr << "ERROR: problem getting variable for LHS diff operator in equation "
<< eqn << endl;
exit(EXIT_FAILURE);
}
orig_diff_var_vec.push_back(diff_set.begin()->first);
}
else
orig_diff_var_vec.push_back(-1);
}
if (it.second.size() != lhs.size())
{
cerr << "ERROR: The LHS variables of the VAR are not unique" << endl;
exit(EXIT_FAILURE);
}
set<expr_t> lhs_static;
for(const auto &lh : lhs)
lhs_static.insert(lh->toStatic(static_model));
vector<int> max_lag;
for (auto eqn : it.second)
max_lag.push_back(equations[eqn]->get_arg2()->VarMaxLag(static_model, lhs_static));
lags[it.first] = max_lag;
diff[it.first] = diff_vec;
orig_diff_var[it.first] = orig_diff_var_vec;
}
trend_component_model_table.setDiff(diff);
trend_component_model_table.setMaxLags(lags);
trend_component_model_table.setOrigDiffVar(orig_diff_var);
}
/*
void
DynamicModel::addEquationsForVar(map<string, pair<SymbolList, int>> &var_model_info)
{
@ -3651,34 +3692,20 @@ DynamicModel::addEquationsForVar(map<string, pair<SymbolList, int>> &var_model_i
if (count > 0)
cout << "Accounting for var_model lags not in model block: added " << count << " auxiliary variables and equations." << endl;
}
void
DynamicModel::getUndiffLHSForPac(vector<int> &lhs, vector<expr_t> &lhs_expr_t, vector<bool> &diff, vector<int> &orig_diff_var,
vector<int> &eqnumber, map<string, int> &undiff, ExprNode::subst_table_t &diff_subst_table)
*/
vector<int>
DynamicModel::getUndiffLHSForPac(const string &aux_model_name,
ExprNode::subst_table_t &diff_subst_table)
{
if (undiff.empty())
return;
vector<expr_t> lhs_expr_t = trend_component_model_table.getLhsExprT(aux_model_name);
vector<int> lhs = trend_component_model_table.getLhs(aux_model_name);
vector<bool> diff = trend_component_model_table.getDiff(aux_model_name);
vector<int> orig_diff_var = trend_component_model_table.getOrigDiffVar(aux_model_name);
vector<int> eqnumber = trend_component_model_table.getEqNums(aux_model_name);
vector<int> nontrend_eqnums = trend_component_model_table.getNonTrendEqNums(aux_model_name);
for (map<string, int>::const_iterator it = undiff.begin();
it != undiff.end(); it++)
for (auto eqn : nontrend_eqnums)
{
int eqn = -1;
string eqtag (it->first);
for (vector<pair<int, pair<string, string>>>::const_iterator iteqtag =
equation_tags.begin(); iteqtag != equation_tags.end(); iteqtag++)
if (iteqtag->second.first == "name"
&& iteqtag->second.second == eqtag)
{
eqn = iteqtag->first;
break;
}
if (eqn == -1)
{
cerr << "ERROR: undiff equation tag '" << eqtag << "' not found" << endl;
exit(EXIT_FAILURE);
}
int i = 0;
for (vector<int>::const_iterator it1 = eqnumber.begin();
it1 != eqnumber.end(); it1++, i++)
@ -3693,9 +3720,9 @@ DynamicModel::getUndiffLHSForPac(vector<int> &lhs, vector<expr_t> &lhs_expr_t, v
if (diff.at(i) != true)
{
cerr << "ERROR: the variable on the LHS of equation #" << eqn << " (VAR equation #" << i
<< " with equation tag '" << eqtag
<< "') does not have the diff operator applied to it yet you are trying to undiff it." << endl;
cerr << "ERROR: the variable on the LHS of equation #" << eqn
<< " does not have the diff operator applied to it yet you are trying to undiff it."
<< endl;
exit(EXIT_FAILURE);
}
@ -3716,20 +3743,10 @@ DynamicModel::getUndiffLHSForPac(vector<int> &lhs, vector<expr_t> &lhs_expr_t, v
exit(EXIT_FAILURE);
}
for (int j = it->second; j > 0; j--)
if (printerr)
{
cerr << "You are undiffing the LHS of equation #" << eqn << " "
<< it->second << " times but it has only been diffed " << j << " time(s)" << endl;
exit(EXIT_FAILURE);
}
else
{
node = node->undiff();
it1 = diff_subst_table.find(node);
if (it1 == diff_subst_table.end())
printerr = true;
}
node = node->undiff();
it1 = diff_subst_table.find(node);
if (it1 == diff_subst_table.end())
printerr = true;
if (printerr)
{ // we have undiffed something like diff(x), hence x is not in diff_subst_table
@ -3742,6 +3759,7 @@ DynamicModel::getUndiffLHSForPac(vector<int> &lhs, vector<expr_t> &lhs_expr_t, v
lhs.at(i) = const_cast<VariableNode *>(it1->second)->get_symb_id();
}
}
return lhs;
}
void
@ -3807,7 +3825,8 @@ DynamicModel::fillPacExpectationVarInfo(string &pac_model_name,
int growth_symb_id)
{
for (size_t i = 0; i < equations.size(); i++)
equations[i]->fillPacExpectationVarInfo(pac_model_name, lhs, max_lag, pac_max_lag, nonstationary, growth_symb_id, i);
equations[i]->fillPacExpectationVarInfo(pac_model_name, lhs, max_lag,
pac_max_lag, nonstationary, growth_symb_id, i);
}
void

View File

@ -250,7 +250,7 @@ private:
void findPacExpectationEquationNumbers(vector<int> &eqnumber) const;
public:
DynamicModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg);
DynamicModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg, TrendComponentModelTable &trend_component_model_table_arg);
//! Adds a variable node
/*! This implementation allows for non-zero lag */
VariableNode *AddVariable(int symb_id, int lag = 0) override;
@ -300,26 +300,12 @@ public:
//! Set the equations that have non-zero second derivatives
void setNonZeroHessianEquations(map<int, string> &eqs);
//! Get equation info associated with equation tags from var_model
void getVarModelVariablesFromEqTags(vector<string> &var_model_eqtags,
vector<int> &eqnumber,
vector<int> &lhs,
vector<expr_t> &lhs_expr_t,
vector<set<pair<int, int>>> &rhs,
vector<bool> &nonstationary) const;
//! Returns the max lag of the VAR
void checkVarMinLag(vector<int> &eqnumber) const;
//! Returns the max lag of the VAR
int getVarMaxLag(StaticModel &static_model, vector<int> &eqnumber) const;
// Get equtaino information on diff operator and max lag info
void getVarLhsDiffAndInfo(vector<int> &eqnumber, vector<bool> &diff,
vector<int> &orig_diff_var) const;
//! Fill the Trend Component Model Table
void fillTrendComponentModelTable() const;
void fillTrendComponentModelTableFromOrigModel(StaticModel &static_model) const;
//! Add aux equations (and aux variables) for variables declared in var_model at max order if they don't already exist
void addEquationsForVar(map<string, pair<SymbolList, int>> &var_model_info);
// void addEquationsForVar(map<string, pair<SymbolList, int>> &var_model_info);
//! Get Pac equation parameter info
void walkPacParameters();
//! Add var_model info to pac_expectation nodes
@ -439,8 +425,8 @@ public:
int getPacMaxLag(const string &pac_model_name) const;
//! Table to undiff LHS variables for pac vector z
void getUndiffLHSForPac(vector<int> &lhs, vector<expr_t> &lhs_expr_t, vector<bool> &diff, vector<int> &orig_diff_var,
vector<int> &eqnumber, map<string, int> &undiff, ExprNode::subst_table_t &diff_subst_table);
vector<int> getUndiffLHSForPac(const string &aux_model_name,
ExprNode::subst_table_t &diff_subst_table);
//! Transforms the model by replacing trend variables with a 1
void removeTrendVariableFromEquations();

View File

@ -111,7 +111,7 @@ class ParsingDriver;
%token PRINT PRIOR_MC PRIOR_TRUNC PRIOR_MODE PRIOR_MEAN POSTERIOR_MODE POSTERIOR_MEAN POSTERIOR_MEDIAN MLE_MODE PRUNING
%token <string> QUOTED_STRING
%token QZ_CRITERIUM QZ_ZERO_THRESHOLD DSGE_VAR DSGE_VARLAG DSGE_PRIOR_WEIGHT TRUNCATE PIPE_E PIPE_X PIPE_P
%token RELATIVE_IRF REPLIC SIMUL_REPLIC RPLOT SAVE_PARAMS_AND_STEADY_STATE PARAMETER_UNCERTAINTY
%token RELATIVE_IRF REPLIC SIMUL_REPLIC RPLOT SAVE_PARAMS_AND_STEADY_STATE PARAMETER_UNCERTAINTY TRENDS
%token SHOCKS SHOCK_DECOMPOSITION SHOCK_GROUPS USE_SHOCK_GROUPS SIGMA_E SIMUL SIMUL_ALGO SIMUL_SEED ENDOGENOUS_TERMINAL_PERIOD
%token SMOOTHER SMOOTHER2HISTVAL SQUARE_ROOT_SOLVER STACK_SOLVE_ALGO STEADY_STATE_MODEL SOLVE_ALGO SOLVER_PERIODS ROBUST_LIN_SOLVE
%token STDERR STEADY STOCH_SIMUL SYLVESTER SYLVESTER_FIXED_POINT_TOL REGIMES REGIME REALTIME_SHOCK_DECOMPOSITION
@ -120,14 +120,14 @@ class ParsingDriver;
%token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL USEAUTOCORR GSA_SAMPLE_FILE USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED
%token VALUES VAR VAREXO VAREXO_DET VARIABLE VAROBS VAREXOBS PREDETERMINED_VARIABLES VAR_EXPECTATION VAR_EXPECTATION_MODEL PLOT_SHOCK_DECOMPOSITION MODEL_LOCAL_VARIABLE
%token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL WRITE_LATEX_ORIGINAL_MODEL CROSSEQUATIONS COVARIANCE WRITE_LATEX_STEADY_STATE_MODEL
%token XLS_SHEET XLS_RANGE LMMCP OCCBIN BANDPASS_FILTER COLORMAP VAR_MODEL PAC_MODEL QOQ YOY AOA UNDIFF PAC_EXPECTATION
%token XLS_SHEET XLS_RANGE LMMCP OCCBIN BANDPASS_FILTER COLORMAP VAR_MODEL PAC_MODEL QOQ YOY AOA UNDIFF PAC_EXPECTATION TREND_COMPONENT_MODEL
%left EQUAL_EQUAL EXCLAMATION_EQUAL
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
%left PLUS MINUS
%left TIMES DIVIDE
%precedence UMINUS UPLUS
%nonassoc POWER
%token EXP LOG LN LOG10 SIN COS TAN ASIN ACOS ATAN ERF DIFF ADL
%token EXP LOG LN LOG10 SIN COS TAN ASIN ACOS ATAN ERF DIFF ADL AUXILIARY_MODEL_NAME
%token SQRT NORMCDF NORMPDF STEADY_STATE EXPECTATION VAR_ESTIMATION
/* GSA analysis */
%token DYNARE_SENSITIVITY MORRIS STAB REDFORM PPRIOR PRIOR_RANGE PPOST ILPTAU MORRIS_NLIV
@ -223,6 +223,7 @@ statement : parameters
| data
| var_model
| pac_model
| trend_component_model
| restrictions
| prior
| prior_eq
@ -374,6 +375,18 @@ var_model_options : o_var_name
| o_var_eq_tags
;
trend_component_model : TREND_COMPONENT_MODEL '(' trend_component_model_options_list ')' ';' { driver.trend_component_model(); }
;
trend_component_model_options_list : trend_component_model_options_list COMMA trend_component_model_options
| trend_component_model_options
;
trend_component_model_options : o_trend_component_model_name
| o_trend_component_model_trends
| o_trend_component_model_eq_tags
;
pac_model : PAC_MODEL '(' pac_model_options_list ')' ';' { driver.pac_model(); } ;
pac_model_options_list : pac_model_options_list COMMA pac_model_options
@ -381,11 +394,9 @@ pac_model_options_list : pac_model_options_list COMMA pac_model_options
;
pac_model_options : o_pac_name
| o_pac_var_name
| o_pac_aux_model_name
| o_pac_discount
| o_pac_growth
| UNDIFF '(' QUOTED_STRING COMMA INT_NUMBER ')'
{ driver.pac_model_undiff($3, $5); }
;
var_expectation_model : VAR_EXPECTATION_MODEL '(' var_expectation_model_options_list ')' ';'
@ -3084,7 +3095,7 @@ o_qz_criterium : QZ_CRITERIUM EQUAL non_negative_number { driver.option_num("qz_
o_qz_zero_threshold : QZ_ZERO_THRESHOLD EQUAL non_negative_number { driver.option_num("qz_zero_threshold", $3); };
o_file : FILE EQUAL filename { driver.option_str("file", $3); };
o_pac_name : MODEL_NAME EQUAL symbol { driver.option_str("pac.model_name", $3); };
o_pac_var_name : VAR_MODEL_NAME EQUAL symbol { driver.option_str("pac.var_model_name", $3); };
o_pac_aux_model_name : AUXILIARY_MODEL_NAME EQUAL symbol { driver.option_str("pac.aux_model_name", $3); };
o_pac_discount : DISCOUNT EQUAL symbol { driver.option_str("pac.discount", $3); };
o_pac_growth : GROWTH EQUAL symbol { driver.option_str("pac.growth", $3); };
o_var_name : MODEL_NAME EQUAL symbol { driver.option_str("var.model_name", $3); };
@ -3101,6 +3112,9 @@ o_nobs : NOBS EQUAL vec_int
| NOBS EQUAL vec_int_number
{ driver.option_vec_int("nobs", $3); }
;
o_trend_component_model_name : MODEL_NAME EQUAL symbol { driver.option_str("trend_component.name", $3); };
o_trend_component_model_trends : TRENDS EQUAL vec_str { driver.option_vec_str("trend_component.trends", $3); }
o_trend_component_model_eq_tags : EQTAGS EQUAL vec_str { driver.option_vec_str("trend_component.eqtags", $3); }
o_conditional_variance_decomposition : CONDITIONAL_VARIANCE_DECOMPOSITION EQUAL vec_int
{ driver.option_vec_int("conditional_variance_decomposition", $3); }
| CONDITIONAL_VARIANCE_DECOMPOSITION EQUAL vec_int_number

View File

@ -141,6 +141,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<INITIAL>simul {BEGIN DYNARE_STATEMENT; return token::SIMUL;}
<INITIAL>stoch_simul {BEGIN DYNARE_STATEMENT; return token::STOCH_SIMUL;}
<INITIAL>var_model {BEGIN DYNARE_STATEMENT; return token::VAR_MODEL;}
<INITIAL>trend_component_model {BEGIN DYNARE_STATEMENT; return token::TREND_COMPONENT_MODEL;}
<INITIAL>var_expectation_model {BEGIN DYNARE_STATEMENT; return token::VAR_EXPECTATION_MODEL;}
<INITIAL>pac_model {BEGIN DYNARE_STATEMENT; return token::PAC_MODEL;}
<INITIAL>dsample {BEGIN DYNARE_STATEMENT; return token::DSAMPLE;}
@ -348,6 +349,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>periods {return token::PERIODS;}
<DYNARE_STATEMENT,DYNARE_BLOCK>model_name {return token::MODEL_NAME;}
<DYNARE_STATEMENT>var_model_name {return token::VAR_MODEL_NAME;}
<DYNARE_STATEMENT>auxiliary_model_name {return token::AUXILIARY_MODEL_NAME;}
<DYNARE_STATEMENT>endogenous_terminal_period {return token::ENDOGENOUS_TERMINAL_PERIOD;}
<DYNARE_STATEMENT>sub_draws {return token::SUB_DRAWS;}
<DYNARE_STATEMENT>minimal_solving_periods {return token::MINIMAL_SOLVING_PERIODS;}
@ -487,6 +489,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
}
<DYNARE_STATEMENT>write_equation_tags {return token::WRITE_EQUATION_TAGS;}
<DYNARE_STATEMENT>eqtags {return token::EQTAGS;}
<DYNARE_STATEMENT>trends {return token::TRENDS;}
<DYNARE_STATEMENT>indxap {return token::INDXAP;}
<DYNARE_STATEMENT>apband {return token::APBAND;}
<DYNARE_STATEMENT>indximf {return token::INDXIMF;}

View File

@ -52,7 +52,9 @@ dynare_m_SOURCES = \
SteadyStateModel.cc \
WarningConsolidation.hh \
WarningConsolidation.cc \
ExtendedPreprocessorTypes.hh
ExtendedPreprocessorTypes.hh \
SubModel.cc \
SubModel.hh
ACLOCAL_AMFLAGS = -I m4

View File

@ -30,15 +30,25 @@
#include "ComputingTasks.hh"
ModFile::ModFile(WarningConsolidation &warnings_arg)
: expressions_tree(symbol_table, num_constants, external_functions_table),
original_model(symbol_table, num_constants, external_functions_table),
dynamic_model(symbol_table, num_constants, external_functions_table),
trend_dynamic_model(symbol_table, num_constants, external_functions_table),
ramsey_FOC_equations_dynamic_model(symbol_table, num_constants, external_functions_table),
orig_ramsey_dynamic_model(symbol_table, num_constants, external_functions_table),
static_model(symbol_table, num_constants, external_functions_table),
steady_state_model(symbol_table, num_constants, external_functions_table, static_model),
diff_static_model(symbol_table, num_constants, external_functions_table),
: trend_component_model_table(symbol_table),
expressions_tree(symbol_table, num_constants,
external_functions_table, trend_component_model_table),
original_model(symbol_table, num_constants,
external_functions_table, trend_component_model_table),
dynamic_model(symbol_table, num_constants,
external_functions_table, trend_component_model_table),
trend_dynamic_model(symbol_table, num_constants,
external_functions_table, trend_component_model_table),
ramsey_FOC_equations_dynamic_model(symbol_table, num_constants,
external_functions_table, trend_component_model_table),
orig_ramsey_dynamic_model(symbol_table, num_constants,
external_functions_table, trend_component_model_table),
static_model(symbol_table, num_constants,
external_functions_table, trend_component_model_table),
steady_state_model(symbol_table, num_constants,
external_functions_table, trend_component_model_table, static_model),
diff_static_model(symbol_table, num_constants,
external_functions_table, trend_component_model_table),
linear(false), block(false), byte_code(false), use_dll(false), no_static(false),
differentiate_forward_vars(false), nonstationary_variables(false),
param_used_with_lead_lag(false), warnings(warnings_arg)
@ -368,16 +378,10 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
set<string> eqtags;
map<string, vector<string>> var_model_eq_tags;
map<string, pair<SymbolList, int>> var_model_info_var_expectation;
for (auto & statement : statements)
{
auto *vms = dynamic_cast<VarModelStatement *>(statement);
if (vms != nullptr)
{
vms->getVarModelInfo(var_model_name, var_model_info_var_expectation, var_model_eq_tags);
for (auto & eqtag : var_model_eq_tags[var_model_name])
eqtags.insert(eqtag);
}
}
for (auto const &it : trend_component_model_table.getEqTags())
for (auto &it1 : it.second)
eqtags.insert(it1);
if (transform_unary_ops)
dynamic_model.substituteUnaryOps(diff_static_model);
@ -389,64 +393,46 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
ExprNode::subst_table_t diff_subst_table;
dynamic_model.substituteDiff(diff_static_model, diff_subst_table);
// Fill Trend Component Model Table
dynamic_model.fillTrendComponentModelTable();
original_model.fillTrendComponentModelTableFromOrigModel(diff_static_model);
// Var Model
map<string, tuple<vector<int>, vector<expr_t>, vector<bool>, vector<int>, int, vector<bool>, vector<int>>>
var_model_info_pac_expectation;
for (auto & statement : statements)
{
int max_lag;
string var_model_name;
vector<string> eqtags;
vector<expr_t> lhs_expr_t;
vector<bool> nonstationary, diff;
vector<int> lhs, eqnumber, orig_diff_var;
auto *vms = dynamic_cast<VarModelStatement *>(statement);
if (vms != nullptr)
{
vector<set<pair<int, int>>> rhs;
vms->getVarModelInfo(var_model_name, var_model_info_var_expectation, var_model_eq_tags);
eqtags = var_model_eq_tags[var_model_name];
dynamic_model.getVarModelVariablesFromEqTags(eqtags,
eqnumber, lhs, lhs_expr_t, rhs, nonstationary);
original_model.checkVarMinLag(eqnumber);
max_lag = original_model.getVarMaxLag(diff_static_model, eqnumber);
original_model.getVarLhsDiffAndInfo(eqnumber, diff, orig_diff_var);
vms->fillVarModelInfoFromEquations(eqnumber, lhs, rhs, nonstationary,
diff, orig_diff_var, max_lag);
var_model_info_pac_expectation[var_model_name] =
{ lhs, lhs_expr_t, diff, orig_diff_var, max_lag, nonstationary, eqnumber };
}
auto *pms = dynamic_cast<PacModelStatement *>(statement);
if (pms != nullptr)
{
int growth_symb_id;
string pac_model_name;
map<string, int> undiff;
tuple<string, string, string, int, map<string, int>> pac_model_info_pac_expectation;
pms->getPacModelInfoForPacExpectation(pac_model_info_pac_expectation);
tie ( pac_model_name, var_model_name, ignore, growth_symb_id, undiff ) = pac_model_info_pac_expectation;
eqtags = var_model_eq_tags[var_model_name];
if (!eqtags.empty())
vector<int> lhs;
vector<bool> nonstationary;
int growth_symb_id, max_lag;
string aux_model_name, pac_model_name;
tie ( pac_model_name, aux_model_name, growth_symb_id ) =
pms->getPacModelInfoForPacExpectation();
if (trend_component_model_table.isExistingTrendComponentModelName(aux_model_name))
{
tie ( lhs, lhs_expr_t, diff, orig_diff_var, max_lag, nonstationary, eqnumber ) =
var_model_info_pac_expectation[var_model_name];
if (!undiff.empty())
{
dynamic_model.getUndiffLHSForPac(lhs, lhs_expr_t, diff, orig_diff_var, eqnumber, undiff, diff_subst_table);
max_lag++;
}
pms->fillUndiffedLHS(lhs);
dynamic_model.walkPacParameters();
int pac_max_lag = original_model.getPacMaxLag(pac_model_name);
dynamic_model.fillPacExpectationVarInfo(pac_model_name, lhs, max_lag, pac_max_lag, nonstationary, growth_symb_id);
dynamic_model.substitutePacExpectation();
max_lag = trend_component_model_table.getMaxLag(aux_model_name) + 1;
lhs = dynamic_model.getUndiffLHSForPac(aux_model_name, diff_subst_table);
nonstationary = trend_component_model_table.getNonstationary(aux_model_name);
}
else
{
// get var_model lhs and max_lag; for now stop with error
cerr << "ERROR: var_models not yet supported for use with pac_model" << endl;
exit(EXIT_FAILURE);
}
pms->fillUndiffedLHS(lhs);
dynamic_model.walkPacParameters();
int pac_max_lag = original_model.getPacMaxLag(pac_model_name);
dynamic_model.fillPacExpectationVarInfo(pac_model_name, lhs, max_lag,
pac_max_lag, nonstationary, growth_symb_id);
dynamic_model.substitutePacExpectation();
}
}
/*
if (!var_model_info_var_expectation.empty())
dynamic_model.addEquationsForVar(var_model_info_var_expectation);
*/
if (symbol_table.predeterminedNbr() > 0)
dynamic_model.transformPredeterminedVariables();
@ -542,9 +528,11 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
vector<set<pair<int, int>>> rhs;
vector<bool> nonstationary;
vector<string> eqtags{var_model_eq_tags[var_model_name]};
/*
dynamic_model.getVarModelVariablesFromEqTags(eqtags,
eqnumber, lhs, lhs_expr_t, rhs, nonstationary);
int max_lag{original_model.getVarMaxLag(diff_static_model, eqnumber)};
*/
int max_lag = trend_component_model_table.getMaxLag(var_model_name);
/* Create auxiliary parameters and the expression to be substituted to
the var_expectations statement */
@ -596,13 +584,15 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
probably add a VarModelTable class (similar to SymbolTable) for storing all
this information about VAR models, instead of putting it inside the
Statement(s) classes */
dynamic_model.fillTrendComponentModelTable();
/*
for (auto & statement : statements)
{
auto *vms = dynamic_cast<VarModelStatement *>(statement);
if (vms != nullptr)
{
string var_model_name;
vms->getVarModelInfo(var_model_name, var_model_info_var_expectation, var_model_eq_tags);
//vms->getVarModelInfo(var_model_name, var_model_info_var_expectation, var_model_eq_tags);
vector<expr_t> lhs_expr_t;
vector<int> lhs, eqnumber, orig_diff_var;
vector<set<pair<int, int>>> rhs;
@ -610,13 +600,15 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
vector<string> eqtags = var_model_eq_tags[var_model_name];
dynamic_model.getVarModelVariablesFromEqTags(eqtags,
eqnumber, lhs, lhs_expr_t, rhs, nonstationary);
int max_lag = original_model.getVarMaxLag(diff_static_model, eqnumber);
original_model.getVarLhsDiffAndInfo(eqnumber, diff, orig_diff_var);
int max_lag = trend_component_model_table.getMaxLag(var_model_name);
// int max_lag = original_model.getVarMaxLag(diff_static_model, eqnumber);
//original_model.getVarLhsDiffAndInfo(eqnumber, diff, orig_diff_var);
vms->fillVarModelInfoFromEquations(eqnumber, lhs, rhs, nonstationary,
diff, orig_diff_var, max_lag);
}
}
*/
if (differentiate_forward_vars)
dynamic_model.differentiateForwardVars(differentiate_forward_vars_subset);
@ -911,6 +903,8 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
symbol_table.writeOutput(mOutputFile);
trend_component_model_table.writeOutput(mOutputFile);
// Initialize M_.Sigma_e, M_.Correlation_matrix, M_.H, and M_.Correlation_matrix_ME
mOutputFile << "M_.Sigma_e = zeros(" << symbol_table.exo_nbr() << ", "
<< symbol_table.exo_nbr() << ");" << endl

View File

@ -38,6 +38,7 @@ using namespace std;
#include "ConfigFile.hh"
#include "WarningConsolidation.hh"
#include "ExtendedPreprocessorTypes.hh"
#include "SubModel.hh"
//! The abstract representation of a "mod" file
class ModFile
@ -51,6 +52,8 @@ public:
ExternalFunctionsTable external_functions_table;
//! Numerical constants table
NumericalConstants num_constants;
//! Trend Component Model Table used for storing info about trend component models
TrendComponentModelTable trend_component_model_table;
//! Expressions outside model block
DataTree expressions_tree;
//! Original model, as declared in the "model" block, that won't be modified by the preprocessor
@ -69,6 +72,7 @@ public:
SteadyStateModel steady_state_model;
//! Static model used for mapping arguments of diff operator
StaticModel diff_static_model;
//! Option linear
bool linear;

View File

@ -1003,8 +1003,10 @@ ModelTree::BlockLinear(const blocks_derivatives_t &blocks_derivatives, const vec
ModelTree::ModelTree(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg) :
DataTree(symbol_table_arg, num_constants_arg, external_functions_table_arg),
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg) :
DataTree(symbol_table_arg, num_constants_arg,
external_functions_table_arg, trend_component_model_table_arg),
cutoff(1e-15),
mfs(0)

View File

@ -321,7 +321,10 @@ protected:
//! Initialize equation_reordered & variable_reordered
void initializeVariablesAndEquations();
public:
ModelTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg);
ModelTree(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg);
//! Absolute value under which a number is considered to be zero
double cutoff;
//! Compute the minimum feedback set

View File

@ -348,7 +348,8 @@ ParsingDriver::declare_or_change_type(SymbolType new_type, const string &name)
// change in equations in ModelTree
auto dm = make_unique<DynamicModel>(mod_file->symbol_table,
mod_file->num_constants,
mod_file->external_functions_table);
mod_file->external_functions_table,
mod_file->trend_component_model_table);
mod_file->dynamic_model.updateAfterVariableChange(*dm);
// remove error messages
@ -1418,6 +1419,30 @@ ParsingDriver::stoch_simul()
options_list.clear();
}
void
ParsingDriver::trend_component_model()
{
OptionsList::string_options_t::const_iterator it =
options_list.string_options.find("trend_component.name");
if (it == options_list.string_options.end())
error("You must pass the model_name option to the trend_component_model statement.");
auto name = it->second;
OptionsList::vec_str_options_t::const_iterator it1 =
options_list.vector_str_options.find("trend_component.eqtags");
if (it1 == options_list.vector_str_options.end())
error("You must pass the eqtags option to the trend_component_model statement.");
auto eqtags = it1->second;
it1 = options_list.vector_str_options.find("trend_component.trends");
if (it1 == options_list.vector_str_options.end())
error("You must pass the trends option to the trend_component_model statement.");
auto trends = it1->second;
mod_file->trend_component_model_table.addTrendComponentModel(name, eqtags, trends);
options_list.clear();
}
void
ParsingDriver::var_model()
{
@ -2045,7 +2070,10 @@ ParsingDriver::run_model_comparison()
void
ParsingDriver::begin_planner_objective()
{
planner_objective_statement = new PlannerObjectiveStatement(mod_file->symbol_table, mod_file->num_constants, mod_file->external_functions_table);
planner_objective_statement = new PlannerObjectiveStatement(mod_file->symbol_table,
mod_file->num_constants,
mod_file->external_functions_table,
mod_file->trend_component_model_table);
set_current_data_tree(&planner_objective_statement->getPlannerObjective());
}
@ -2527,10 +2555,10 @@ ParsingDriver::pac_model()
error("You must pass the model_name option to the pac_model statement.");
auto name = it->second;
it = options_list.string_options.find("pac.var_model_name");
it = options_list.string_options.find("pac.aux_model_name");
if (it == options_list.string_options.end())
error("You must pass the var_model_name option to the pac_model statement.");
auto var_name = it->second;
error("You must pass the auxiliary_model_name option to the pac_model statement.");
auto aux_model_name = it->second;
it = options_list.string_options.find("pac.discount");
if (it == options_list.string_options.end())
@ -2542,17 +2570,11 @@ ParsingDriver::pac_model()
if (it != options_list.string_options.end())
growth = it->second;
mod_file->addStatement(new PacModelStatement(name, var_name, discount, growth, pac_undiff, mod_file->symbol_table));
mod_file->addStatement(new PacModelStatement(name, aux_model_name, discount, growth,
mod_file->symbol_table));
symbol_list.clear();
options_list.clear();
pac_undiff.clear();
}
void
ParsingDriver::pac_model_undiff(string eqtag, const string &order)
{
pac_undiff[move(eqtag)] = stoi(order);
}
expr_t

View File

@ -242,8 +242,6 @@ private:
SymbolList graph_formats;
//! Temporary storage for equation tags
vector<pair<string, string>> eq_tags;
//! Temporary storage for pac statement undiff option
map<string, int> pac_undiff;
//! Map Var name to variables
map<string, vector<string>> var_map;
@ -463,6 +461,8 @@ public:
void rplot();
//! Writes a stock_simul command
void stoch_simul();
//! Writes a trend component command
void trend_component_model();
//! Writes a var (vector autoregression) command
void var_model();
//! Writes a simul command
@ -697,8 +697,6 @@ public:
expr_t add_pac_expectation(const string &var_model_name);
//! Creates pac_model statement
void pac_model();
//! Add undiff option for pac_model statement
void pac_model_undiff(string eqtag, const string &order);
//! Writes token "diff(arg1)" to model tree
expr_t add_diff(expr_t arg1);
//! Writes token "adl(arg1, lag)" to model tree

View File

@ -31,8 +31,10 @@
StaticModel::StaticModel(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg) :
ModelTree(symbol_table_arg, num_constants_arg, external_functions_table_arg),
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg) :
ModelTree(symbol_table_arg, num_constants_arg,
external_functions_table_arg, trend_component_model_table_arg),
global_temporary_terms(true)
{
}

View File

@ -160,7 +160,10 @@ protected:
void writeStaticModel(ostream &DynamicOutput, bool use_dll, bool julia) const;
void writeStaticModel(const string &dynamic_basename, bool use_dll, bool julia) const;
public:
StaticModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants, ExternalFunctionsTable &external_functions_table_arg);
StaticModel(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants,
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg);
//! Writes information on block decomposition when relevant
void writeOutput(ostream &output, bool block) const;

View File

@ -22,8 +22,14 @@
#include "SteadyStateModel.hh"
SteadyStateModel::SteadyStateModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg, const StaticModel &static_model_arg) :
DataTree(symbol_table_arg, num_constants_arg, external_functions_table_arg), static_model(static_model_arg)
SteadyStateModel::SteadyStateModel(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg,
const StaticModel &static_model_arg) :
DataTree(symbol_table_arg, num_constants_arg,
external_functions_table_arg, trend_component_model_table_arg),
static_model(static_model_arg)
{
}

View File

@ -35,7 +35,11 @@ private:
const StaticModel &static_model;
public:
SteadyStateModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg, const StaticModel &static_model_arg);
SteadyStateModel(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg,
const StaticModel &static_model_arg);
//! Add an expression of the form "var = expr;"
void addDefinition(int symb_id, expr_t expr);
//! Add an expression of the form "[ var1, var2, ... ] = expr;"

288
src/SubModel.cc Normal file
View File

@ -0,0 +1,288 @@
/*
* Copyright (C) 2018 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include "SubModel.hh"
TrendComponentModelTable::TrendComponentModelTable(SymbolTable &symbol_table_arg) :
symbol_table(symbol_table_arg)
{
}
void
TrendComponentModelTable::addTrendComponentModel(string name_arg,
vector<string> eqtags_arg,
vector<string> trend_eqtags_arg)
{
if (isExistingTrendComponentModelName(name_arg))
{
cerr << "Error: a trend component model already exists with the name " << name_arg << endl;
exit(EXIT_FAILURE);
}
eqtags[name_arg] = move(eqtags_arg);
trend_eqtags[name_arg] = move(trend_eqtags_arg);
names.insert(move(name_arg));
}
void
TrendComponentModelTable::setEqNums(map<string, vector<int>> eqnums_arg)
{
eqnums = move(eqnums_arg);
setUndiffEqnums();
}
void
TrendComponentModelTable::setTrendEqNums(map<string, vector<int>> trend_eqnums_arg)
{
trend_eqnums = move(trend_eqnums_arg);
setUndiffEqnums();
}
void
TrendComponentModelTable::setUndiffEqnums()
{
if (!nontrend_eqnums.empty() || eqnums.empty() || trend_eqnums.empty())
return;
for (const auto &it : eqnums)
{
vector<int> nontrend_vec;
for (auto eq : it.second)
if (find(trend_eqnums[it.first].begin(), trend_eqnums[it.first].end(), eq)
== trend_eqnums[it.first].end())
nontrend_vec.push_back(eq);
nontrend_eqnums[it.first] = nontrend_vec;
}
}
void
TrendComponentModelTable::setNonstationary(map<string, vector<bool>> nonstationary_arg)
{
nonstationary = move(nonstationary_arg);
}
void
TrendComponentModelTable::setLhs(map<string, vector<int>> lhs_arg)
{
lhs = move(lhs_arg);
}
void
TrendComponentModelTable::setRhs(map<string, vector<set<pair<int, int>>>> rhs_arg)
{
rhs = move(rhs_arg);
}
void
TrendComponentModelTable::setLhsExprT(map<string, vector<expr_t>> lhs_expr_t_arg)
{
lhs_expr_t = move(lhs_expr_t_arg);
}
void
TrendComponentModelTable::setMaxLags(map<string, vector<int>> max_lags_arg)
{
max_lags = move(max_lags_arg);
}
void
TrendComponentModelTable::setDiff(map<string, vector<bool>> diff_arg)
{
diff = move(diff_arg);
}
void
TrendComponentModelTable::setOrigDiffVar(map<string, vector<int>> orig_diff_var_arg)
{
orig_diff_var = move(orig_diff_var_arg);
}
map<string, vector<string>>
TrendComponentModelTable::getEqTags() const
{
return eqtags;
}
vector<string>
TrendComponentModelTable::getEqTags(const string &name_arg) const
{
checkModelName(name_arg);
return eqtags.find(name_arg)->second;
}
void
TrendComponentModelTable::checkModelName(const string &name_arg) const
{
if (!isExistingTrendComponentModelName(name_arg))
{
cerr << name_arg
<< " is not a recognized equation tag of a trend component model equation" << endl;
exit(EXIT_FAILURE);
}
}
vector<bool>
TrendComponentModelTable::getNonstationary(const string &name_arg) const
{
checkModelName(name_arg);
return nonstationary.find(name_arg)->second;
}
vector<int>
TrendComponentModelTable::getLhs(const string &name_arg) const
{
checkModelName(name_arg);
return lhs.find(name_arg)->second;
}
vector<expr_t>
TrendComponentModelTable::getLhsExprT(const string &name_arg) const
{
checkModelName(name_arg);
return lhs_expr_t.find(name_arg)->second;
}
map<string, vector<string>>
TrendComponentModelTable::getTrendEqTags() const
{
return trend_eqtags;
}
map<string, vector<int>>
TrendComponentModelTable::getEqNums() const
{
return eqnums;
}
vector<int>
TrendComponentModelTable::getNonTrendEqNums(const string &name_arg) const
{
checkModelName(name_arg);
return nontrend_eqnums.find(name_arg)->second;
}
vector<int>
TrendComponentModelTable::getEqNums(const string &name_arg) const
{
checkModelName(name_arg);
return eqnums.find(name_arg)->second;
}
vector<int>
TrendComponentModelTable::getMaxLags(const string &name_arg) const
{
checkModelName(name_arg);
return max_lags.find(name_arg)->second;
}
int
TrendComponentModelTable::getMaxLag(const string &name_arg) const
{
int max_lag_int = 0;
for (auto it : getMaxLags(name_arg))
max_lag_int = max(max_lag_int, it);
return max_lag_int;
}
vector<bool>
TrendComponentModelTable::getDiff(const string &name_arg) const
{
checkModelName(name_arg);
return diff.find(name_arg)->second;
}
vector<int>
TrendComponentModelTable::getOrigDiffVar(const string &name_arg) const
{
checkModelName(name_arg);
return orig_diff_var.find(name_arg)->second;
}
void
TrendComponentModelTable::writeOutput(ostream &output) const
{
for (const auto &name : names)
{
output << "M_.trend_component." << name << ".model_name = '" << name << "'" << endl
<< "M_.trend_component." << name << ".eqtags = {";
for (const auto &it : eqtags.at(name))
output << "'" << it << "'; ";
output << "};" << endl
<< "M_.trend_component." << name << ".eqn = [";
for (auto it : eqnums.at(name))
output << it + 1 << " ";
output << "];" << endl
<< "M_.trend_component." << name << ".trend_eqn = [";
for (auto it : trend_eqnums.at(name))
output << it + 1 << " ";
output << "];" << endl
<< "M_.trend_component." << name << ".trends = [";
for (auto it : eqnums.at(name))
if (find(trend_eqnums.at(name).begin(), trend_eqnums.at(name).end(), it)
== trend_eqnums.at(name).end())
output << "false ";
else
output << "true ";
output << "];" << endl
<< "M_.trend_component." << name << ".lhs = [";
for (auto it : lhs.at(name))
output << symbol_table.getTypeSpecificID(it) + 1 << " ";
output << "];" << endl
<< "M_.trend_component." << name << ".max_lag = [";
for (auto it : max_lags.at(name))
output << it << " ";
output << "];" << endl
<< "M_.trend_component." << name << ".diff = [";
for (const auto &it : diff.at(name))
output << (it ? "true" : "false") << " ";
output << "];" << endl
<< "M_.trend_component." << name << ".orig_diff_var = [";
for (auto it : orig_diff_var.at(name))
output << (it >= 0 ? symbol_table.getTypeSpecificID(it) + 1 : -1) << " ";
output << "];" << endl;
int i = 1;
for (const auto &it : rhs.at(name))
{
output << "M_.trend_component." << name << ".rhs.vars_at_eq{" << i << "}.var = [";
for (const auto &it1 : it)
output << symbol_table.getTypeSpecificID(it1.first) + 1 << " ";
output << "];" << endl
<< "M_.trend_component." << name << ".rhs.vars_at_eq{" << i << "}.lag = [";
for (const auto &it1 : it)
output << it1.second << " ";
output << "];" << endl;
i++;
}
}
}
void
TrendComponentModelTable::writeJsonOutput(ostream &output) const
{
for (const auto &name : names)
{
if (name != *(names.begin()))
output << ", ";
output << "{\"statementName\": \"trend_component_model\","
<< "\"model_name\": \"" << name << "\"}";
}
}

96
src/SubModel.hh Normal file
View File

@ -0,0 +1,96 @@
/*
* Copyright (C) 2018 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SUBMODEL_HH
#define _SUBMODEL_HH
#include <set>
#include <map>
#include <vector>
#include <iostream>
#include "ExprNode.hh"
#include "SymbolTable.hh"
using namespace std;
//! A table with all Trend Component Models in the .mod file
/*!
The unique name of the trend component model is the identifier
*/
class TrendComponentModelTable
{
private:
SymbolTable &symbol_table;
set<string> names;
map<string, vector<string>> eqtags, trend_eqtags;
map<string, vector<int>> eqnums, trend_eqnums, nontrend_eqnums, max_lags, lhs, orig_diff_var;
map<string, vector<set<pair<int, int>>>> rhs;
map<string, vector<bool>> diff, nonstationary;
map<string, vector<expr_t>> lhs_expr_t;
public:
TrendComponentModelTable(SymbolTable &symbol_table_arg);
//! Add a trend component model
void addTrendComponentModel(string name, vector<string> eqtags, vector<string> trend_eqtags);
inline bool isExistingTrendComponentModelName(const string &name_arg) const;
map<string, vector<string>> getEqTags() const;
vector<string> getEqTags(const string &name_arg) const;
map<string, vector<string>> getTrendEqTags() const;
map<string, vector<int>> getEqNums() const;
vector<int> getEqNums(const string &name_arg) const;
vector<int> getMaxLags(const string &name_arg) const;
int getMaxLag(const string &name_arg) const;
vector<int> getLhs(const string &name_arg) const;
vector<expr_t> getLhsExprT(const string &name_arg) const;
vector<bool> getDiff(const string &name_arg) const;
vector<int> getOrigDiffVar(const string &name_arg) const;
vector<int> getNonTrendEqNums(const string &name_arg) const;
vector<bool> getNonstationary(const string &name_arg) const;
void setEqNums(map<string, vector<int>> eqnums_arg);
void setTrendEqNums(map<string, vector<int>> trend_eqnums_arg);
void setLhs(map<string, vector<int>> lhs_arg);
void setRhs(map<string, vector<set<pair<int, int>>>> rhs_arg);
void setLhsExprT(map<string, vector<expr_t>> lhs_expr_t_arg);
void setMaxLags(map<string, vector<int>> max_lags_arg);
void setDiff(map<string, vector<bool>> diff_arg);
void setOrigDiffVar(map<string, vector<int>> orig_diff_var_arg);
void setNonstationary(map<string, vector<bool>> nonstationary_arg);
//! Write output of this class
void writeOutput(ostream &output) const;
//! Write JSON Output
void writeJsonOutput(ostream &output) const;
private:
void checkModelName(const string &name_arg) const;
void setUndiffEqnums();
};
inline bool
TrendComponentModelTable::isExistingTrendComponentModelName(const string &name_arg) const
{
return names.find(name_arg) == names.end() ? false : true;
}
#endif