introduce var model table

issue#70
Houtan Bastani 2018-08-21 11:46:59 +02:00
parent 6015b0e57b
commit 539fddc9f6
17 changed files with 615 additions and 313 deletions

View File

@ -380,154 +380,6 @@ PacModelStatement::getPacModelInfoForPacExpectation() const
return { name, aux_model_name, growth_symb_id };
}
VarModelStatement::VarModelStatement(SymbolList symbol_list_arg,
OptionsList options_list_arg,
string name_arg,
const SymbolTable &symbol_table_arg) :
symbol_list(move(symbol_list_arg)),
options_list(move(options_list_arg)),
name{move(name_arg)},
symbol_table(symbol_table_arg)
{
}
void
VarModelStatement::getVarModelInfo(string &var_model_name,
map<string, pair<SymbolList, int>> &var_model_info,
map<string, vector<string>> &var_model_eqtags) const
{
var_model_name = name;
if (symbol_list.empty())
{
auto it = options_list.vector_str_options.find("var.eqtags");
var_model_eqtags[name] = it->second;
}
else
{
auto it = options_list.num_options.find("var.order");
var_model_info[name] = { symbol_list, stoi(it->second) };
}
}
void
VarModelStatement::fillVarModelInfoFromEquations(vector<int> &eqnumber_arg, vector<int> &lhs_arg,
vector<set<pair<int, int>>> &rhs_arg,
vector<bool> &nonstationary_arg,
vector<bool> &diff_arg,
vector<int> &orig_diff_var_arg,
int max_lag_arg)
{
eqnumber = eqnumber_arg;
lhs = lhs_arg;
rhs_by_eq = rhs_arg;
nonstationary = nonstationary_arg;
diff = diff_arg;
orig_diff_var = orig_diff_var_arg;
max_lag = max_lag_arg;
}
void
VarModelStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
{
}
void
VarModelStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
{
options_list.writeOutput(output);
if (!symbol_list.empty())
symbol_list.writeOutput("options_.var.var_list_", output);
output << "M_.var." << name << " = options_.var;" << endl
<< "options_ = rmfield(options_, 'var');" << endl;
output << "M_.var." << name << ".eqn = [";
for (auto it = eqnumber.begin();
it != eqnumber.end(); it++)
{
if (it != eqnumber.begin())
output << " ";
output << *it + 1;
}
output << "];" << endl
<< "M_.var." << name << ".lhs = [";
for (auto it = lhs.begin();
it != lhs.end(); it++)
{
if (it != lhs.begin())
output << " ";
output << symbol_table.getTypeSpecificID(*it) + 1;
}
output << "];" << endl
<< "M_.var." << name << ".max_lag = " << max_lag << ";" << endl
<< "M_.var." << name << ".nonstationary = [";
for (auto it = nonstationary.begin();
it != nonstationary.end(); it++)
{
if (it != nonstationary.begin())
output << " ";
if (*it)
output << "true";
else
output << "false";
}
output << "];" << endl
<< "M_.var." << name << ".diff = [";
for (auto it = diff.begin();
it != diff.end(); it++)
{
if (it != diff.begin())
output << " ";
if (*it)
output << "true";
else
output << "false";
}
output << "];" << endl
<< "M_.var." << name << ".orig_diff_var = [";
for (auto it = orig_diff_var.begin();
it != orig_diff_var.end(); it++)
{
if (it != orig_diff_var.begin())
output << " ";
if (*it == -1)
output << -1;
else
output << symbol_table.getTypeSpecificID(*it) + 1;
}
output << "];" << endl;
int i = 1;
for (auto it = rhs_by_eq.begin();
it != rhs_by_eq.end(); it++, i++)
{
output << "M_.var." << name << ".rhs.vars_at_eq{" << i << "}.var = [";
for (auto it1 = it->begin();
it1 != it->end(); it1++)
{
if (it1 != it->begin())
output << " ";
output << symbol_table.getTypeSpecificID(it1->first) + 1;
}
output << "];" << endl
<< "M_.var." << name << ".rhs.vars_at_eq{" << i << "}.lag = [";
for (auto it1 = it->begin();
it1 != it->end(); it1++)
{
if (it1 != it->begin())
output << " ";
output << it1->second;
}
output << "];" << endl;
}
}
void
VarModelStatement::writeJsonOutput(ostream &output) const
{
output << "{\"statementName\": \"var_model\","
<< "\"model_name\": \"" << name << "\"}";
}
VarEstimationStatement::VarEstimationStatement(OptionsList options_list_arg) :
options_list(move(options_list_arg))
{
@ -2210,9 +2062,10 @@ ModelComparisonStatement::writeJsonOutput(ostream &output) const
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}
TrendComponentModelTable &trend_component_model_table_arg,
VarModelTable &var_model_table_arg) :
model_tree{symbol_table, num_constants, external_functions_table,
trend_component_model_table_arg, var_model_table_arg}
{
}

View File

@ -141,36 +141,6 @@ public:
tuple<string, string, int> getPacModelInfoForPacExpectation() const;
};
class VarModelStatement : public Statement
{
public:
const SymbolList symbol_list;
const OptionsList options_list;
const string name;
private:
const SymbolTable &symbol_table;
vector<int> eqnumber, lhs, orig_diff_var;
vector<set<pair<int, int>>> rhs_by_eq; // rhs by equation
vector<bool> nonstationary, diff;
int max_lag;
public:
VarModelStatement(SymbolList symbol_list_arg,
OptionsList options_list_arg,
string name_arg,
const SymbolTable &symbol_table_arg);
void getVarModelInfo(string &var_model_name,
map<string, pair<SymbolList, int>> &var_model_info,
map<string, vector<string>> &var_model_eqtags) const;
void fillVarModelInfoFromEquations(vector<int> &eqnumber_arg, vector<int> &lhs_arg,
vector<set<pair<int, int>>> &rhs_arg,
vector<bool> &nonstationary_arg,
vector<bool> &diff_arg, vector<int> &orig_diff_var_arg,
int max_lag_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;
};
class VarRestrictionsStatement : public Statement
{
private:
@ -541,7 +511,8 @@ public:
PlannerObjectiveStatement(SymbolTable &symbol_table,
NumericalConstants &num_constants,
ExternalFunctionsTable &external_functions_table,
TrendComponentModelTable &trend_component_model_table_arg);
TrendComponentModelTable &trend_component_model_table_arg,
VarModelTable &var_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

@ -29,11 +29,13 @@
DataTree::DataTree(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg) :
TrendComponentModelTable &trend_component_model_table_arg,
VarModelTable &var_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),
var_model_table(var_model_table_arg),
node_counter(0)
{
Zero = AddNonNegativeConstant("0");

View File

@ -59,6 +59,8 @@ protected:
ExternalFunctionsTable &external_functions_table;
//! A reference to the trend component model table
TrendComponentModelTable &trend_component_model_table;
//! A reference to the VAR model table
VarModelTable &var_model_table;
//! num_constant_id -> NumConstNode
using num_const_node_map_t = map<int, NumConstNode *>;
@ -136,7 +138,8 @@ public:
DataTree(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg);
TrendComponentModelTable &trend_component_model_table_arg,
VarModelTable &var_model_table_arg);
virtual
~DataTree();

View File

@ -34,9 +34,10 @@
DynamicModel::DynamicModel(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_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),
TrendComponentModelTable &trend_component_model_table_arg,
VarModelTable &var_model_table_arg) :
ModelTree(symbol_table_arg, num_constants_arg, external_functions_table_arg,
trend_component_model_table_arg, var_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),
@ -3454,6 +3455,168 @@ DynamicModel::runTrendTest(const eval_context_t &eval_context)
testTrendDerivativesEqualToZero(eval_context);
}
void
DynamicModel::fillVarModelTable() const
{
map<string, vector<int>> 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 = var_model_table.getEqTags();
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 (const auto &it : rhs_set)
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;
}
var_model_table.setEqNums(eqnums);
var_model_table.setLhs(lhsr);
var_model_table.setRhs(rhsr);
var_model_table.setLhsExprT(lhs_expr_tr);
var_model_table.setNonstationary(nonstationaryr);
}
void
DynamicModel::fillVarModelTableFromOrigModel(StaticModel &static_model) const
{
map<string, vector<int>> lags, orig_diff_var;
map<string, vector<bool>> diff;
for (const auto &it : var_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 model 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 model 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;
}
var_model_table.setDiff(diff);
var_model_table.setMaxLags(lags);
var_model_table.setOrigDiffVar(orig_diff_var);
}
void
DynamicModel::fillTrendComponentModelTable() const
{
@ -3530,7 +3693,7 @@ DynamicModel::fillTrendComponentModelTable() const
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;
<< ". A trend component model may only have one endogenous variable on the LHS. " << endl;
exit(EXIT_FAILURE);
}
@ -3538,7 +3701,7 @@ DynamicModel::fillTrendComponentModelTable() const
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. "
<< ". The variable on the LHS of a trend component model may not appear with a lead or a lag. "
<< endl;
exit(EXIT_FAILURE);
}
@ -3555,7 +3718,7 @@ DynamicModel::fillTrendComponentModelTable() const
if (it->second > 0)
{
cerr << "ERROR: in Equation " << eqtag
<< ". A VAR may not have leaded or contemporaneous variables on the RHS. " << endl;
<< ". A trend component model may not have leaded or contemporaneous variables on the RHS. " << endl;
exit(EXIT_FAILURE);
}
rhs.push_back(rhs_set);
@ -3589,7 +3752,7 @@ DynamicModel::fillTrendComponentModelTableFromOrigModel(StaticModel &static_mode
// ensure no leads in equations
if (equations[eqn]->get_arg2()->VarMinLag() <= 0)
{
cerr << "ERROR in VAR Equation (#" << eqn << "). "
cerr << "ERROR in trend component model Equation (#" << eqn << "). "
<< "Leaded exogenous variables "
<< "and leaded or contemporaneous endogenous variables not allowed in VAR"
<< endl;
@ -3621,7 +3784,7 @@ DynamicModel::fillTrendComponentModelTableFromOrigModel(StaticModel &static_mode
if (it.second.size() != lhs.size())
{
cerr << "ERROR: The LHS variables of the VAR are not unique" << endl;
cerr << "ERROR: The LHS variables of the trend component model are not unique" << endl;
exit(EXIT_FAILURE);
}
@ -3640,19 +3803,23 @@ DynamicModel::fillTrendComponentModelTableFromOrigModel(StaticModel &static_mode
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)
DynamicModel::addEquationsForVar()
{
if (var_model_table.empty())
return;
map<string, pair<SymbolList, int>> var_symbol_list_and_order =
var_model_table.getSymbolListAndOrder();
// List of endogenous variables and the minimum lag value that must exist in the model equations
map<string, int> var_endos_and_lags, model_endos_and_lags;
for (map<string, pair<SymbolList, int>>::const_iterator it = var_model_info.begin();
it != var_model_info.end(); it++)
for (const auto & it : var_symbol_list_and_order)
for (auto & equation : equations)
if (equation->isVarModelReferenced(it->first))
if (equation->isVarModelReferenced(it.first))
{
vector<string> symbol_list = it->second.first.get_symbols();
int order = it->second.second;
vector<string> symbol_list = it.second.first.get_symbols();
int order = it.second.second;
for (vector<string>::const_iterator it1 = symbol_list.begin();
it1 != symbol_list.end(); it1++)
if (order > 2)
@ -3666,7 +3833,8 @@ DynamicModel::addEquationsForVar(map<string, pair<SymbolList, int>> &var_model_i
if (var_endos_and_lags.empty())
return;
// Ensure that the minimum lag value exists in the model equations. If not, add an equation for it
// Ensure that the minimum lag value exists in the model equations.
// If not, add an equation for it
for (auto & equation : equations)
equation->getEndosAndMaxLags(model_endos_and_lags);
@ -3690,9 +3858,10 @@ 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;
cout << "Accounting for var_model lags not in model block: added "
<< count << " auxiliary variables and equations." << endl;
}
*/
vector<int>
DynamicModel::getUndiffLHSForPac(const string &aux_model_name,
ExprNode::subst_table_t &diff_subst_table)

View File

@ -250,7 +250,11 @@ private:
void findPacExpectationEquationNumbers(vector<int> &eqnumber) const;
public:
DynamicModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg, TrendComponentModelTable &trend_component_model_table_arg);
DynamicModel(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg,
VarModelTable &var_model_table_arg);
//! Adds a variable node
/*! This implementation allows for non-zero lag */
VariableNode *AddVariable(int symb_id, int lag = 0) override;
@ -304,8 +308,14 @@ public:
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);
//! Fill the Var Model Table
void fillVarModelTable() const;
void fillVarModelTableFromOrigModel(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();
//! Get Pac equation parameter info
void walkPacParameters();
//! Add var_model info to pac_expectation nodes

View File

@ -30,25 +30,26 @@
#include "ComputingTasks.hh"
ModFile::ModFile(WarningConsolidation &warnings_arg)
: 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),
: var_model_table(symbol_table),
trend_component_model_table(symbol_table),
expressions_tree(symbol_table, num_constants, external_functions_table,
trend_component_model_table, var_model_table),
original_model(symbol_table, num_constants, external_functions_table,
trend_component_model_table, var_model_table),
dynamic_model(symbol_table, num_constants, external_functions_table,
trend_component_model_table, var_model_table),
trend_dynamic_model(symbol_table, num_constants, external_functions_table,
trend_component_model_table, var_model_table),
ramsey_FOC_equations_dynamic_model(symbol_table, num_constants, external_functions_table,
trend_component_model_table, var_model_table),
orig_ramsey_dynamic_model(symbol_table, num_constants, external_functions_table,
trend_component_model_table, var_model_table),
static_model(symbol_table, num_constants, external_functions_table,
trend_component_model_table, var_model_table),
steady_state_model(symbol_table, num_constants, external_functions_table,
trend_component_model_table, var_model_table, static_model),
diff_static_model(symbol_table, num_constants, external_functions_table,
trend_component_model_table, var_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)
@ -374,19 +375,21 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
}
// Get all equation tags associated with VARs and Pac Models
string var_model_name;
set<string> eqtags;
map<string, vector<string>> var_model_eq_tags;
map<string, pair<SymbolList, int>> var_model_info_var_expectation;
for (auto const &it : trend_component_model_table.getEqTags())
for (auto &it1 : it.second)
eqtags.insert(it1);
for (auto const &it : var_model_table.getEqTags())
for (auto &it1 : it.second)
eqtags.insert(it1);
if (transform_unary_ops)
dynamic_model.substituteUnaryOps(diff_static_model);
else
// substitute only those unary ops that appear in VAR equations
// substitute only those unary ops that appear in auxiliary model equations
dynamic_model.substituteUnaryOps(diff_static_model, eqtags);
// Create auxiliary variable and equations for Diff operators that appear in VAR equations
@ -396,8 +399,10 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
// Fill Trend Component Model Table
dynamic_model.fillTrendComponentModelTable();
original_model.fillTrendComponentModelTableFromOrigModel(diff_static_model);
dynamic_model.fillVarModelTable();
original_model.fillVarModelTableFromOrigModel(diff_static_model);
// Var Model
// Pac Model
for (auto & statement : statements)
{
auto *pms = dynamic_cast<PacModelStatement *>(statement);
@ -415,10 +420,16 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
lhs = dynamic_model.getUndiffLHSForPac(aux_model_name, diff_subst_table);
nonstationary = trend_component_model_table.getNonstationary(aux_model_name);
}
else if (var_model_table.isExistingVarModelName(aux_model_name))
{
max_lag = var_model_table.getMaxLag(aux_model_name) + 1;
lhs = var_model_table.getLhs(aux_model_name);
nonstationary = var_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;
cerr << "Error: aux_model_name not recognized as VAR model or Trend Component model"
<< endl;
exit(EXIT_FAILURE);
}
pms->fillUndiffedLHS(lhs);
@ -429,10 +440,9 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
dynamic_model.substitutePacExpectation();
}
}
/*
if (!var_model_info_var_expectation.empty())
dynamic_model.addEquationsForVar(var_model_info_var_expectation);
*/
dynamic_model.addEquationsForVar();
if (symbol_table.predeterminedNbr() > 0)
dynamic_model.transformPredeterminedVariables();
@ -507,35 +517,17 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
continue;
auto &model_name = vems->model_name;
/* Find the corresponding VM statement and extract information for it;
ideally we should have a VarModelTable for that purpose */
VarModelStatement *vms = nullptr;
for (auto & statement2 : statements)
if ((vms = dynamic_cast<VarModelStatement *>(statement2))
&& vms->name == vems->var_model_name)
break;
if (!vms)
if (!var_model_table.isExistingVarModelName(vems->var_model_name))
{
cerr << "ERROR: var_expectation_model " << model_name << " refers to nonexistent " << vems->var_model_name << " var_model" << endl;
cerr << "ERROR: var_expectation_model " << model_name
<< " refers to nonexistent " << vems->var_model_name << " var_model" << endl;
exit(EXIT_FAILURE);
}
/* The code below is duplicated further below in this function; but we
can't avoid that until the collecting of information about VARs is
moved *before* lead/lag substitutions (or even better, in checkPass()) */
vector<expr_t> lhs_expr_t;
vector<int> lhs, eqnumber;
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 = trend_component_model_table.getMaxLag(var_model_name);
/* Create auxiliary parameters and the expression to be substituted to
the var_expectations statement */
int max_lag = var_model_table.getMaxLag(vems->var_model_name);
vector<int> lhs = var_model_table.getLhs(vems->var_model_name);
auto subst_expr = dynamic_model.Zero;
for (int lag = 0; lag < max_lag; lag++)
for (auto variable : lhs)
@ -580,35 +572,8 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
dynamic_model.substituteEndoLagGreaterThanTwo(true);
}
/* TODO: most of this should rather be done in checkPass(). Also we should
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);
vector<expr_t> lhs_expr_t;
vector<int> lhs, eqnumber, orig_diff_var;
vector<set<pair<int, int>>> rhs;
vector<bool> nonstationary, diff;
vector<string> eqtags = var_model_eq_tags[var_model_name];
dynamic_model.getVarModelVariablesFromEqTags(eqtags,
eqnumber, lhs, lhs_expr_t, rhs, nonstationary);
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);
@ -1315,10 +1280,18 @@ ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType
output << ", ";
dynamic_model.writeJsonOutput(output);
if (!statements.empty()
|| !var_model_table.empty()
|| !trend_component_model_table.empty())
{
output << ", \"statements\": [";
if (!var_model_table.empty())
{
var_model_table.writeJsonOutput(output);
output << ", ";
}
if (!trend_component_model_table.empty())
{
trend_component_model_table.writeJsonOutput(output);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2017 Dynare Team
* Copyright (C) 2006-2018 Dynare Team
*
* This file is part of Dynare.
*
@ -52,6 +52,8 @@ public:
ExternalFunctionsTable external_functions_table;
//! Numerical constants table
NumericalConstants num_constants;
//! Var Model Table used for storing info about trend component models
VarModelTable var_model_table;
//! Trend Component Model Table used for storing info about trend component models
TrendComponentModelTable trend_component_model_table;
//! Expressions outside model block

View File

@ -1004,9 +1004,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,
TrendComponentModelTable &trend_component_model_table_arg) :
DataTree(symbol_table_arg, num_constants_arg,
external_functions_table_arg, trend_component_model_table_arg),
TrendComponentModelTable &trend_component_model_table_arg,
VarModelTable &var_model_table_arg) :
DataTree(symbol_table_arg, num_constants_arg, external_functions_table_arg,
trend_component_model_table_arg, var_model_table_arg),
cutoff(1e-15),
mfs(0)

View File

@ -324,7 +324,8 @@ public:
ModelTree(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg);
TrendComponentModelTable &trend_component_model_table_arg,
VarModelTable &var_model_table_arg);
//! Absolute value under which a number is considered to be zero
double cutoff;
//! Compute the minimum feedback set

View File

@ -349,7 +349,8 @@ ParsingDriver::declare_or_change_type(SymbolType new_type, const string &name)
auto dm = make_unique<DynamicModel>(mod_file->symbol_table,
mod_file->num_constants,
mod_file->external_functions_table,
mod_file->trend_component_model_table);
mod_file->trend_component_model_table,
mod_file->var_model_table);
mod_file->dynamic_model.updateAfterVariableChange(*dm);
// remove error messages
@ -1444,25 +1445,34 @@ ParsingDriver::trend_component_model()
void
ParsingDriver::var_model()
{
OptionsList::string_options_t::const_iterator it = options_list.string_options.find("var.model_name");
if (it == options_list.string_options.end())
const auto its = options_list.string_options.find("var.model_name");
if (its == options_list.string_options.end())
error("You must pass the model_name option to the var_model statement.");
auto name = it->second;
if (options_list.vector_str_options.find("var.eqtags") != options_list.vector_str_options.end())
if (!symbol_list.empty())
error("You cannot pass a symbol list when passing equation tags to the var_model statement");
else if (options_list.num_options.find("var.order") != options_list.num_options.end())
error("You cannot pass the order option when passing equation tags to the var_model statement");
auto name = its->second;
int order = 0;
const auto itn = options_list.num_options.find("var.order");
if (itn != options_list.num_options.end())
order = stoi(itn->second);
else
if (!symbol_list.empty())
if (options_list.num_options.find("var.order") == options_list.num_options.end())
error("You must pass the order option when passing a symbol list to the var_model statement");
error("You must pass the order option when passing a symbol list to the var_model statement");
mod_file->addStatement(new VarModelStatement(symbol_list, options_list, name, mod_file->symbol_table));
var_map[it->second] = symbol_list.getSymbols();
vector<string> eqtags;
const auto itvs = options_list.vector_str_options.find("var.eqtags");
if (itvs != options_list.vector_str_options.end())
{
eqtags = itvs->second;
if (!symbol_list.empty())
error("You cannot pass a symbol list when passing equation tags to the var_model statement");
else if (itn != options_list.num_options.end())
error("You cannot pass the order option when passing equation tags to the var_model statement");
}
mod_file->var_model_table.addVarModel(name, eqtags, make_pair(symbol_list, order));
symbol_list.clear();
options_list.clear();
var_map[its->second] = symbol_list.getSymbols();
}
void
@ -2071,8 +2081,8 @@ ParsingDriver::begin_planner_objective()
planner_objective_statement = new PlannerObjectiveStatement(mod_file->symbol_table,
mod_file->num_constants,
mod_file->external_functions_table,
mod_file->trend_component_model_table);
mod_file->trend_component_model_table,
mod_file->var_model_table);
set_current_data_tree(&planner_objective_statement->getPlannerObjective());
}

View File

@ -32,9 +32,10 @@
StaticModel::StaticModel(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_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),
TrendComponentModelTable &trend_component_model_table_arg,
VarModelTable &var_model_table_arg) :
ModelTree(symbol_table_arg, num_constants_arg, external_functions_table_arg,
trend_component_model_table_arg, var_model_table_arg),
global_temporary_terms(true)
{
}

View File

@ -163,7 +163,8 @@ public:
StaticModel(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants,
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg);
TrendComponentModelTable &trend_component_model_table_arg,
VarModelTable &var_model_table_arg);
//! Writes information on block decomposition when relevant
void writeOutput(ostream &output, bool block) const;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2017 Dynare Team
* Copyright (C) 2010-2018 Dynare Team
*
* This file is part of Dynare.
*
@ -26,9 +26,10 @@ SteadyStateModel::SteadyStateModel(SymbolTable &symbol_table_arg,
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg,
VarModelTable &var_model_table_arg,
const StaticModel &static_model_arg) :
DataTree(symbol_table_arg, num_constants_arg,
external_functions_table_arg, trend_component_model_table_arg),
DataTree(symbol_table_arg, num_constants_arg, external_functions_table_arg,
trend_component_model_table_arg, var_model_table_arg),
static_model(static_model_arg)
{
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2017 Dynare Team
* Copyright (C) 2010-2018 Dynare Team
*
* This file is part of Dynare.
*
@ -39,6 +39,7 @@ public:
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg,
TrendComponentModelTable &trend_component_model_table_arg,
VarModelTable &var_model_table_arg,
const StaticModel &static_model_arg);
//! Add an expression of the form "var = expr;"
void addDefinition(int symb_id, expr_t expr);

View File

@ -301,3 +301,241 @@ TrendComponentModelTable::writeJsonOutput(ostream &output) const
output << "]}";
}
}
VarModelTable::VarModelTable(SymbolTable &symbol_table_arg) :
symbol_table(symbol_table_arg)
{
}
void
VarModelTable::addVarModel(string name_arg, vector<string> eqtags_arg,
pair<SymbolList, int> symbol_list_and_order_arg)
{
if (isExistingVarModelName(name_arg))
{
cerr << "Error: a VAR model already exists with the name " << name_arg << endl;
exit(EXIT_FAILURE);
}
eqtags[name_arg] = move(eqtags_arg);
symbol_list_and_order[name_arg] = move(symbol_list_and_order_arg);
names.insert(move(name_arg));
}
map<string, pair<SymbolList, int>>
VarModelTable::getSymbolListAndOrder() const
{
return symbol_list_and_order;
}
void
VarModelTable::writeOutput(ostream &output) const
{
for (const auto &name : names)
{
output << "M_.var." << name << ".model_name = '" << name << "';" << endl;
if (!symbol_list_and_order.empty())
{
symbol_list_and_order.at(name).first.writeOutput("M_.var." + name + ".var_list_", output);
output << "M_.var." << name << ".order = "
<< symbol_list_and_order.at(name).second << ";" << endl;
}
output << "M_.var." << name << ".eqtags = {";
for (const auto &it : eqtags.at(name))
output << "'" << it << "'; ";
output << "};" << endl
<< "M_.var." << name << ".eqn = [";
for (auto it : eqnums.at(name))
output << it + 1 << " ";
output << "];" << endl
<< "M_.var." << name << ".lhs = [";
for (auto it : lhs.at(name))
output << symbol_table.getTypeSpecificID(it) + 1 << " ";
output << "];" << endl
<< "M_.var." << name << ".max_lag = [";
for (auto it : max_lags.at(name))
output << it << " ";
output << "];" << endl
<< "M_.var." << name << ".diff = [";
for (const auto &it : diff.at(name))
output << (it ? "true" : "false") << " ";
output << "];" << endl
<< "M_.var." << 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_.var." << name << ".rhs.vars_at_eq{" << i << "}.var = [";
for (const auto &it1 : it)
output << symbol_table.getTypeSpecificID(it1.first) + 1 << " ";
output << "];" << endl
<< "M_.var." << name << ".rhs.vars_at_eq{" << i << "}.lag = [";
for (const auto &it1 : it)
output << it1.second << " ";
output << "];" << endl;
i++;
}
}
}
void
VarModelTable::writeJsonOutput(ostream &output) const
{
for (const auto &name : names)
{
if (name != *(names.begin()))
output << ", ";
output << "{\"statementName\": \"var_model\","
<< "\"model_name\": \"" << name << "\",";
if (symbol_list_and_order.empty())
{
output << "\"eqtags\": [";
for (const auto &it : eqtags.at(name))
{
output << "\"" << it << "\"";
if (&it != &eqtags.at(name).back())
output << ", ";
}
output << "]";
}
else
{
output << "\"order\": \"" << symbol_list_and_order.at(name).second << "\",";
}
output << "}";
}
}
map<string, vector<string>>
VarModelTable::getEqTags() const
{
return eqtags;
}
vector<string>
VarModelTable::getEqTags(const string &name_arg) const
{
checkModelName(name_arg);
return eqtags.find(name_arg)->second;
}
void
VarModelTable::checkModelName(const string &name_arg) const
{
if (!isExistingVarModelName(name_arg))
{
cerr << name_arg
<< " is not a recognized equation tag of a VAR model equation" << endl;
exit(EXIT_FAILURE);
}
}
void
VarModelTable::setEqNums(map<string, vector<int>> eqnums_arg)
{
eqnums = move(eqnums_arg);
}
void
VarModelTable::setLhs(map<string, vector<int>> lhs_arg)
{
lhs = move(lhs_arg);
}
void
VarModelTable::setRhs(map<string, vector<set<pair<int, int>>>> rhs_arg)
{
rhs = move(rhs_arg);
}
void
VarModelTable::setLhsExprT(map<string, vector<expr_t>> lhs_expr_t_arg)
{
lhs_expr_t = move(lhs_expr_t_arg);
}
void
VarModelTable::setNonstationary(map<string, vector<bool>> nonstationary_arg)
{
nonstationary = move(nonstationary_arg);
}
map<string, vector<int>>
VarModelTable::getEqNums() const
{
return eqnums;
}
vector<int>
VarModelTable::getEqNums(const string &name_arg) const
{
checkModelName(name_arg);
return eqnums.find(name_arg)->second;
}
void
VarModelTable::setMaxLags(map<string, vector<int>> max_lags_arg)
{
max_lags = move(max_lags_arg);
}
void
VarModelTable::setDiff(map<string, vector<bool>> diff_arg)
{
diff = move(diff_arg);
}
void
VarModelTable::setOrigDiffVar(map<string, vector<int>> orig_diff_var_arg)
{
orig_diff_var = move(orig_diff_var_arg);
}
vector<int>
VarModelTable::getMaxLags(const string &name_arg) const
{
checkModelName(name_arg);
return max_lags.find(name_arg)->second;
}
int
VarModelTable::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<int>
VarModelTable::getLhs(const string &name_arg) const
{
checkModelName(name_arg);
return lhs.find(name_arg)->second;
}
vector<bool>
VarModelTable::getNonstationary(const string &name_arg) const
{
checkModelName(name_arg);
return nonstationary.find(name_arg)->second;
}
vector<set<pair<int, int>>>
VarModelTable::getRhs(const string &name_arg) const
{
checkModelName(name_arg);
return rhs.find(name_arg)->second;
}
vector<expr_t>
VarModelTable::getLhsExprT(const string &name_arg) const
{
checkModelName(name_arg);
return lhs_expr_t.find(name_arg)->second;
}

View File

@ -101,4 +101,69 @@ TrendComponentModelTable::empty() const
return names.empty();
}
class VarModelTable
{
private:
SymbolTable &symbol_table;
set<string> names;
map<string, pair<SymbolList, int>> symbol_list_and_order;
map<string, vector<string>> eqtags;
map<string, vector<int>> 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:
VarModelTable(SymbolTable &symbol_table_arg);
//! Add a trend component model
void addVarModel(string name, vector<string> eqtags,
pair<SymbolList, int> symbol_list_and_order_arg);
inline bool isExistingVarModelName(const string &name_arg) const;
inline bool empty() const;
map<string, vector<string>> getEqTags() const;
vector<string> getEqTags(const string &name_arg) 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<bool> getNonstationary(const string &name_arg) const;
map<string, pair<SymbolList, int>> getSymbolListAndOrder() const;
vector<set<pair<int, int>>> getRhs(const string &name_arg) const;
vector<expr_t> getLhsExprT(const string &name_arg) const;
void setEqNums(map<string, vector<int>> 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 setNonstationary(map<string, vector<bool>> nonstationary_arg);
void setDiff(map<string, vector<bool>> diff_arg);
void setMaxLags(map<string, vector<int>> max_lags_arg);
void setOrigDiffVar(map<string, vector<int>> orig_diff_var_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;
};
inline bool
VarModelTable::isExistingVarModelName(const string &name_arg) const
{
return names.find(name_arg) == names.end() ? false : true;
}
inline bool
VarModelTable::empty() const
{
return names.empty();
}
#endif