Verified Commit 240aba67 authored by Houtan Bastani's avatar Houtan Bastani
Browse files

move pac info out of pac expectation node

parent 34756833
Pipeline #850 passed with stage
in 1 minute and 21 seconds
......@@ -300,22 +300,17 @@ PacModelStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolida
}
}
void
PacModelStatement::fillUndiffedLHS(vector<int> &lhs_arg)
{
lhs = lhs_arg;
}
void
PacModelStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
{
output << "M_.pac." << name << ".auxiliary_model_name = '" << aux_model_name << "';" << endl
<< "M_.pac." << name << ".discount_index = " << symbol_table.getTypeSpecificID(discount) + 1 << ";" << endl
<< "M_.pac." << name << ".steady_state_growth_rate = ";
if (steady_state_growth_rate_symb_id < 0)
output << steady_state_growth_rate_number << ";" << endl;
else
output << symbol_table.getTypeSpecificID(steady_state_growth_rate_symb_id) + 1 << ";" << endl;
<< "M_.pac." << name << ".discount_index = " << symbol_table.getTypeSpecificID(discount) + 1 << ";" << endl;
if (steady_state_growth_rate_symb_id < 0 && steady_state_growth_rate_number > 0)
output << "M_.pac." << name << ".steady_state_growth_rate = "
<< steady_state_growth_rate_number << ";" << endl;
else if (steady_state_growth_rate_symb_id >= 0)
output << "M_.pac." << name << ".steady_state_growth_rate = "
<< symbol_table.getTypeSpecificID(steady_state_growth_rate_symb_id) + 1 << ";" << endl;
if (growth_symb_id >= 0)
{
......@@ -364,14 +359,6 @@ PacModelStatement::writeOutput(ostream &output, const string &basename, bool min
}
}
}
output << "M_.pac." << name << ".lhs = [";
for (auto it = lhs.begin(); it !=lhs.end(); it++)
{
if (it != lhs.begin())
output << " ";
output << *it + 1;
}
output << "];" << endl;
}
void
......
......@@ -156,7 +156,6 @@ public:
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);
};
class VarRestrictionsStatement : public Statement
......
......@@ -85,9 +85,6 @@ DynamicModel::copyHelper(const DynamicModel &m)
derivative_exo.push_back(convert_derivative_t(it));
for (const auto &it : m.derivative_exo_det)
derivative_exo_det.push_back(convert_derivative_t(it));
for (const auto &it : m.pac_expectation_info)
pac_expectation_info.insert(dynamic_cast<const PacExpectationNode *>(f(it)));
}
......@@ -231,8 +228,6 @@ DynamicModel::operator=(const DynamicModel &m)
equation_block = m.equation_block;
var_expectation_functions_to_write = m.var_expectation_functions_to_write;
pac_expectation_info.clear();
endo_max_leadlag_block = m.endo_max_leadlag_block;
other_endo_max_leadlag_block = m.other_endo_max_leadlag_block;
exo_max_leadlag_block = m.exo_max_leadlag_block;
......@@ -3633,11 +3628,6 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
for (auto & it : pac_eqtag_and_lag)
output << modstruct << "pac." << it.first.first << ".equations." << it.second.first << ".max_lag = " << it.second.second << ";" << endl;
map <string, vector<pair<string, string>> > mymap;
mymap.insert(pair<string,vector<pair<string,string>> >("A", vector<pair<string,string>>()));
mymap["A"].push_back(make_pair("A","BB"));
mymap["A"].push_back(make_pair("C", "DD"));
// Write Pac equation tag info
map<string, vector<pair<string, string>>> for_writing;
for (auto & it : pac_eqtag_and_lag)
......@@ -3655,9 +3645,98 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
output << "];" << endl;
}
// Write PacExpectationInfo
for (auto it : pac_expectation_info)
it->ExprNode::writeOutput(output, ExprNodeOutputType::matlabDynamicModel);
for (auto & it : pac_model_info)
{
int growth_param_index = get<6>(it.second);
if (growth_param_index >= 0)
output << modstruct << "pac." << it.first << ".growth_neutrality_param_index = "
<< symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl;
vector<int> lhs = get<0>(it.second);
output << modstruct << "pac." << it.first << ".lhs = [";
for (auto it : lhs)
output << it + 1 << " ";
output << "];" << endl;
}
for (auto & pit : pac_equation_info)
{
pair<int, int> lhs_pac_var;
int optim_share_index;
set<pair<int, pair<int, int>>> ar_params_and_vars;
pair<int, pair<vector<int>, vector<bool>>> ec_params_and_vars;
vector<tuple<int, int, int, double>> non_optim_vars_params_and_constants;
tie(lhs_pac_var, optim_share_index, ar_params_and_vars, ec_params_and_vars, non_optim_vars_params_and_constants) = pit.second;
string substruct = pit.first.first + ".equations." + pit.first.second + ".";
output << "M_.pac." << substruct << "lhs_var = "
<< symbol_table.getTypeSpecificID(lhs_pac_var.first) + 1 << ";" << endl;
if (optim_share_index >= 0)
output << "M_.pac." << substruct << "share_of_optimizing_agents_index = "
<< symbol_table.getTypeSpecificID(optim_share_index) + 1 << ";" << endl;
output << "M_.pac." << substruct << "ec.params = "
<< symbol_table.getTypeSpecificID(ec_params_and_vars.first) + 1 << ";" << endl
<< "M_.pac." << substruct << "ec.vars = [";
for (auto it : ec_params_and_vars.second.first)
output << symbol_table.getTypeSpecificID(it) + 1 << " ";
output << "];" << endl
<< "M_.pac." << substruct << "ec.isendo = [";
for (auto it : ec_params_and_vars.second.second)
output << (it ? "true" : "false") << " ";
output << "];" << endl
<< "M_.pac." << substruct << "ar.params = [";
for (auto & it : ar_params_and_vars)
output << symbol_table.getTypeSpecificID(it.first) + 1 << " ";
output << "];" << endl
<< "M_.pac." << substruct << "ar.vars = [";
for (auto & it : ar_params_and_vars)
output << symbol_table.getTypeSpecificID(it.second.first) + 1 << " ";
output << "];" << endl
<< "M_.pac." << substruct << "ar.lags = [";
for (auto & it : ar_params_and_vars)
output << it.second.second << " ";
output << "];" << endl;
if (!non_optim_vars_params_and_constants.empty())
{
output << "M_.pac." << substruct << "non_optimizing_behavior.params = [";
for (auto & it : non_optim_vars_params_and_constants)
if (get<2>(it) >= 0)
output << symbol_table.getTypeSpecificID(get<2>(it)) + 1 << " ";
else
output << "NaN ";
output << "];" << endl
<< "M_.pac." << substruct << "non_optimizing_behavior.vars = [";
for (auto & it : non_optim_vars_params_and_constants)
output << symbol_table.getTypeSpecificID(get<0>(it)) + 1 << " ";
output << "];" << endl
<< "M_.pac." << substruct << "non_optimizing_behavior.lags = [";
for (auto & it : non_optim_vars_params_and_constants)
output << get<1>(it) << " ";
output << "];" << endl
<< "M_.pac." << substruct << "non_optimizing_behavior.scaling_factor = [";
for (auto & it : non_optim_vars_params_and_constants)
output << get<3>(it) << " ";
output << "];" << endl;
}
}
for (auto & it : pac_h0_indices)
{
output << "M_.pac." << it.first.first << ".equations." << it.first.second << ".h0_param_indices = [";
for (auto it1 : it.second)
output << symbol_table.getTypeSpecificID(it1) + 1 << " ";
output << "];" << endl;
}
for (auto & it : pac_h1_indices)
{
output << "M_.pac." << it.first.first << ".equations." << it.first.second << ".h1_param_indices = [";
for (auto it1 : it.second)
output << symbol_table.getTypeSpecificID(it1) + 1 << " ";
output << "];" << endl;
}
}
map<tuple<int, int, int>, expr_t>
......@@ -4297,7 +4376,9 @@ DynamicModel::walkPacParameters(const string &name, map<pair<string, string>, pa
set<int> optim_share;
expr_t optim_part = nullptr;
expr_t non_optim_part = nullptr;
equation->getPacLHS(lhs);
set<pair<int, int>> lhss;
equation->arg1->collectDynamicVariables(SymbolType::endogenous, lhss);
lhs = *(lhss.begin());
int lhs_orig_symb_id = lhs.first;
if (symbol_table.isAuxiliaryVariable(lhs_orig_symb_id))
try
......@@ -4342,12 +4423,20 @@ DynamicModel::walkPacParameters(const string &name, map<pair<string, string>, pa
cerr << "Every equation with a pac expectation must have been assigned an equation tag name" << endl;
exit(EXIT_FAILURE);
}
if (lhs.first == -1)
{
cerr << "walkPacParameters: error obtaining LHS varibale." << endl;
exit(EXIT_FAILURE);
}
if (ec_params_and_vars.second.first.empty() || ar_params_and_vars.empty())
{
cerr << "walkPacParameters: error obtaining RHS parameters." << endl;
exit(EXIT_FAILURE);
}
string eq = "eq" + to_string(i++);
equation->addParamInfoToPac(eq,
lhs,
optim_share_index,
ec_params_and_vars, ar_params_and_vars,
non_optim_vars_params_and_constants);
pac_equation_info[make_pair(name, eq)] = make_tuple(lhs, optim_share_index,
ar_params_and_vars, ec_params_and_vars,
non_optim_vars_params_and_constants);
eqtag_and_lag[make_pair(name, eqtag)] = make_pair(eq, 0);
}
}
......@@ -4388,7 +4477,9 @@ DynamicModel::getPacTargetSymbId(const string &pac_model_name) const
if (equation->containsPacExpectation(pac_model_name))
{
pair<int, int> lhs (-1, -1);
equation->getPacLHS(lhs);
set<pair<int, int>> lhss;
equation->arg1->collectDynamicVariables(SymbolType::endogenous, lhss);
lhs = *(lhss.begin());
int lhs_symb_id = lhs.first;
int lhs_orig_symb_id = lhs_symb_id;
if (symbol_table.isAuxiliaryVariable(lhs_symb_id))
......@@ -4405,17 +4496,19 @@ DynamicModel::getPacTargetSymbId(const string &pac_model_name) const
}
void
DynamicModel::addPacModelConsistentExpectationEquation(const string & name, int pac_target_symb_id,
int discount_symb_id, const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
DynamicModel::addPacModelConsistentExpectationEquation(const string & name, int discount_symb_id,
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
ExprNode::subst_table_t &diff_subst_table)
{
int pac_target_symb_id = getPacTargetSymbId(name);
pac_eqtag_and_lag.insert(eqtag_and_lag.begin(), eqtag_and_lag.end());
int neqs = 0;
for (auto & it : eqtag_and_lag)
{
string eqtag = it.second.first;
string eqtag = it.first.second;
string standard_eqtag = it.second.first;
int pac_max_lag_m = it.second.second;
string append_to_name = name + "_" + eqtag;
string append_to_name = name + "_" + standard_eqtag;
int mce_z1_symb_id;
try
{
......@@ -4435,7 +4528,7 @@ DynamicModel::addPacModelConsistentExpectationEquation(const string & name, int
{
int alpha_i_symb_id = symbol_table.addSymbol("mce_alpha_" + append_to_name + "_" + to_string(i),
SymbolType::parameter);
pac_mce_alpha_symb_ids[make_pair(name, eqtag)].push_back(alpha_i_symb_id);
pac_mce_alpha_symb_ids[make_pair(name, standard_eqtag)].push_back(alpha_i_symb_id);
A = AddPlus(A, AddVariable(alpha_i_symb_id));
fp = AddPlus(fp,
AddTimes(AddTimes(AddVariable(alpha_i_symb_id),
......@@ -4503,46 +4596,106 @@ DynamicModel::addPacModelConsistentExpectationEquation(const string & name, int
addEquation(AddEqual(AddVariable(mce_z1_symb_id),
AddMinus(AddTimes(A, AddMinus((expr_t) target_base_diff_node, fs)), fp)), -1);
neqs++;
pac_mce_z1_symb_ids[make_pair(name, eqtag)] = mce_z1_symb_id;
pac_mce_z1_symb_ids[make_pair(name, standard_eqtag)] = mce_z1_symb_id;
pac_expectation_substitution[make_pair(name, eqtag)] = AddVariable(mce_z1_symb_id);
}
cout << "Pac Model Consistent Expectation: added " << neqs << " auxiliary variables and equations." << endl;
}
void
DynamicModel::fillPacExpectationVarInfo(const string &pac_model_name,
vector<int> &lhs,
int max_lag,
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
const vector<bool> &nonstationary,
int growth_symb_id, int growth_lag)
DynamicModel::fillPacModelInfo(const string &pac_model_name,
vector<int> &lhs,
int max_lag,
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
const vector<bool> &nonstationary,
int growth_symb_id, int growth_lag)
{
pac_eqtag_and_lag.insert(eqtag_and_lag.begin(), eqtag_and_lag.end());
for (size_t i = 0; i < equations.size(); i++)
equations[i]->fillPacExpectationVarInfo(pac_model_name, lhs, max_lag,
nonstationary, growth_symb_id, growth_lag, i);
}
void
DynamicModel::substitutePacExpectation(const string & name)
{
map<const PacExpectationNode *, const BinaryOpNode *> subst_table;
for (auto & it : local_variables_table)
it.second = pac_mce_z1_symb_ids.empty() ?
it.second->substitutePacExpectation(name, subst_table) :
it.second->substitutePacExpectation(name, pac_mce_z1_symb_ids, subst_table);
bool stationary_vars_present = false;
bool nonstationary_vars_present = false;
for (auto it : nonstationary)
if (nonstationary_vars_present && stationary_vars_present)
break;
else
if (it)
nonstationary_vars_present = true;
else
stationary_vars_present = true;
for (auto & equation : equations)
int growth_param_index = -1;
if (growth_symb_id >= 0)
growth_param_index = symbol_table.addSymbol(pac_model_name +
"_pac_growth_neutrality_correction",
SymbolType::parameter);
for (auto pac_models_and_eqtags : pac_eqtag_and_lag)
{
auto *substeq = pac_mce_z1_symb_ids.empty() ?
dynamic_cast<BinaryOpNode *>(equation->substitutePacExpectation(name, subst_table)) :
dynamic_cast<BinaryOpNode *>(equation->substitutePacExpectation(name, pac_mce_z1_symb_ids, subst_table));
assert(substeq != nullptr);
equation = substeq;
if (pac_models_and_eqtags.first.first != pac_model_name)
continue;
string eqtag = pac_models_and_eqtags.first.second;
string standard_eqtag = pac_models_and_eqtags.second.first;
expr_t subExpr = Zero;
if (stationary_vars_present)
for (int i = 1; i < max_lag + 1; i++)
for (auto lhsit : lhs)
{
stringstream param_name_h0;
param_name_h0 << "h0_" << pac_model_name
<< "_" << standard_eqtag
<< "_var_" << symbol_table.getName(lhsit)
<< "_lag_" << i;
int new_param_symb_id = symbol_table.addSymbol(param_name_h0.str(), SymbolType::parameter);
pac_h0_indices[make_pair(pac_model_name, standard_eqtag)].push_back(new_param_symb_id);
subExpr = AddPlus(subExpr,
AddTimes(AddVariable(new_param_symb_id),
AddVariable(lhsit, -i)));
}
if (nonstationary_vars_present)
for (int i = 1; i < max_lag + 1; i++)
for (auto lhsit : lhs)
{
stringstream param_name_h1;
param_name_h1 << "h1_" << pac_model_name
<< "_" << standard_eqtag
<< "_var_" << symbol_table.getName(lhsit)
<< "_lag_" << i;
int new_param_symb_id = symbol_table.addSymbol(param_name_h1.str(), SymbolType::parameter);
pac_h1_indices[make_pair(pac_model_name, standard_eqtag)].push_back(new_param_symb_id);
subExpr = AddPlus(subExpr,
AddTimes(AddVariable(new_param_symb_id),
AddVariable(lhsit, -i)));
}
if (growth_symb_id >= 0)
subExpr = AddPlus(subExpr,
AddTimes(AddVariable(growth_param_index),
AddVariable(growth_symb_id, growth_lag)));
pac_expectation_substitution[make_pair(pac_model_name, eqtag)] = subExpr;
}
for (map<const PacExpectationNode *, const BinaryOpNode *>::const_iterator it = subst_table.begin();
it != subst_table.end(); it++)
pac_expectation_info.insert(const_cast<PacExpectationNode *>(it->first));
pac_model_info[pac_model_name] = make_tuple(lhs, max_lag,
nonstationary_vars_present, stationary_vars_present,
growth_symb_id, growth_lag, growth_param_index);
}
void
DynamicModel::substitutePacExpectation(const string & pac_model_name)
{
for (auto & it : pac_expectation_substitution)
if (it.first.first == pac_model_name)
for (auto & equation : equations)
for (auto & tag : equation_tags)
if (tag.first == (&equation - &equations[0]))
if (tag.second.first == "name" && tag.second.second == it.first.second)
{
auto *substeq = dynamic_cast<BinaryOpNode *>(equation->substitutePacExpectation(pac_model_name, it.second));
assert(substeq != nullptr);
equation = substeq;
break;
}
}
void
......
......@@ -233,9 +233,6 @@ private:
//! Used for var_expectation and var_model
map<string, set<int>> var_expectation_functions_to_write;
//! Used for pac_expectation operator
set<const PacExpectationNode *> pac_expectation_info; // PacExpectationNode pointers
//!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous
vector<pair<int, int>> endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block;
......@@ -346,15 +343,15 @@ public:
//! Get Pac equation parameter info
void walkPacParameters(const string &name, map<pair<string, string>, pair<string, int>> &eqtag_and_lag);
//! Add var_model info to pac_expectation nodes
void fillPacExpectationVarInfo(const string &pac_model_name,
vector<int> &lhs,
int max_lag,
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
const vector<bool> &nonstationary,
int growth_symb_id, int growth_lag);
void fillPacModelInfo(const string &pac_model_name,
vector<int> &lhs,
int max_lag,
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
const vector<bool> &nonstationary,
int growth_symb_id, int growth_lag);
//! Substitutes pac_expectation operator with expectation based on auxiliary model
void substitutePacExpectation(const string & name);
void substitutePacExpectation(const string & pac_model_name);
//! Adds informations for simulation in a binary file
void Write_Inf_To_Bin_File_Block(const string &basename,
......@@ -458,15 +455,36 @@ public:
int getPacTargetSymbId(const string &pac_model_name) const;
//! Add model consistent expectation equation for pac model
void addPacModelConsistentExpectationEquation(const string & name, int pac_target_symb_id, int discount, const map<pair<string, string>, pair<string, int>> &eqtag_and_lag, ExprNode::subst_table_t &diff_subst_table);
void addPacModelConsistentExpectationEquation(const string & name, int discount,
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
ExprNode::subst_table_t &diff_subst_table);
//! store symb_ids for alphas created in addPacModelConsistentExpectationEquation
//! (pac_model_name, standardized_eqtag) -> mce_alpha_symb_id
map<pair<string, string>, vector<int>> pac_mce_alpha_symb_ids;
//! store symb_ids for h0, h1 parameters
//! (pac_model_name, standardized_eqtag) -> parameter symb_ids
map<pair<string, string>, vector<int>> pac_h0_indices, pac_h1_indices;
//! store symb_ids for z1s created in addPacModelConsistentExpectationEquation
//! (pac_model_name, standardized_eqtag) -> mce_z1_symb_id
map<pair<string, string>, int> pac_mce_z1_symb_ids;
//! Store lag info for pac equations
//! (pac_model_name, equation_tag) -> (standardized_eqtag, lag)
map<pair<string, string>, pair<string, int>> pac_eqtag_and_lag;
//! (pac_model_name, equation_tag) -> expr_t
map<pair<string, string>, expr_t> pac_expectation_substitution;
//! Store info about pac models:
//! pac_model_name -> (lhsvars, max_lag, nonstationary_vars_present, stationary_vars_present, growth_symb_id, growth_lag, growth_param_index)
map<string, tuple<vector<int>, int, bool, bool, int, int, int>> pac_model_info;
//! Store info about pac models specific to the equation they appear in
//! (pac_model_name, standardized_eqtag) ->
//! (lhs, optim_share_index, ar_params_and_vars, ec_params_and_vars, non_optim_vars_params_and_constants)
map<pair<string, string>,
tuple<pair<int, int>, int, set<pair<int, pair<int, int>>>, pair<int, pair<vector<int>, vector<bool>>>, vector<tuple<int, int, int, double>>>> pac_equation_info;
//! Table to undiff LHS variables for pac vector z
vector<int> getUndiffLHSForPac(const string &aux_model_name,
ExprNode::subst_table_t &diff_subst_table) const;
......
This diff is collapsed.
This diff is collapsed.
......@@ -442,20 +442,15 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
cerr << "Error: aux_model_name not recognized as VAR model or Trend Component model" << endl;
exit(EXIT_FAILURE);
}
pms->fillUndiffedLHS(lhs);
map<pair<string, string>, pair<string, int>> eqtag_and_lag;
dynamic_model.walkPacParameters(pms->name, eqtag_and_lag);
original_model.getPacMaxLag(pms->name, eqtag_and_lag);
if (pms->aux_model_name == "")
{
int pac_target_symb_id = dynamic_model.getPacTargetSymbId(pms->name);
dynamic_model.addPacModelConsistentExpectationEquation(pms->name, pac_target_symb_id,
symbol_table.getID(pms->discount), eqtag_and_lag,
diff_subst_table);
}
dynamic_model.addPacModelConsistentExpectationEquation(pms->name, symbol_table.getID(pms->discount),
eqtag_and_lag, diff_subst_table);
else
dynamic_model.fillPacExpectationVarInfo(pms->name, lhs, max_lag,
eqtag_and_lag, nonstationary, pms->growth_symb_id, pms->growth_lag);
dynamic_model.fillPacModelInfo(pms->name, lhs, max_lag,
eqtag_and_lag, nonstationary, pms->growth_symb_id, pms->growth_lag);
dynamic_model.substitutePacExpectation(pms->name);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment