pac growth: allow linear combination
parent
33c2f9b88b
commit
a0f74f5c16
|
@ -275,66 +275,25 @@ PacModelStatement::PacModelStatement(string name_arg,
|
||||||
original_growth{growth_arg},
|
original_growth{growth_arg},
|
||||||
steady_state_growth_rate_number{steady_state_growth_rate_number_arg},
|
steady_state_growth_rate_number{steady_state_growth_rate_number_arg},
|
||||||
steady_state_growth_rate_symb_id{steady_state_growth_rate_symb_id_arg},
|
steady_state_growth_rate_symb_id{steady_state_growth_rate_symb_id_arg},
|
||||||
symbol_table{symbol_table_arg},
|
symbol_table{symbol_table_arg}
|
||||||
growth_symb_id{-1},
|
|
||||||
growth_lag{0}
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
PacModelStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
|
|
||||||
{
|
|
||||||
if (growth == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto *vn = dynamic_cast<VariableNode *>(growth);
|
|
||||||
if (vn != nullptr)
|
|
||||||
{
|
|
||||||
mod_file_struct.pac_params.insert(vn->symb_id);
|
|
||||||
mod_file_struct.pac_params.insert(vn->lag);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *uon = dynamic_cast<UnaryOpNode *>(growth);
|
|
||||||
if (uon != nullptr)
|
|
||||||
if (uon->op_code == UnaryOpcode::diff)
|
|
||||||
{
|
|
||||||
auto *uonvn = dynamic_cast<VariableNode *>(uon->arg);
|
|
||||||
auto *uon1 = dynamic_cast<UnaryOpNode *>(uon->arg);
|
|
||||||
while (uonvn == nullptr && uon1 != nullptr)
|
|
||||||
{
|
|
||||||
uonvn = dynamic_cast<VariableNode *>(uon1->arg);
|
|
||||||
uon1 = dynamic_cast<UnaryOpNode *>(uon1->arg);
|
|
||||||
}
|
|
||||||
if (uonvn == nullptr)
|
|
||||||
{
|
|
||||||
cerr << "Pac growth parameter must be either a variable or a diff unary op of a variable" << endl;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
mod_file_struct.pac_params.insert(uonvn->symb_id);
|
|
||||||
mod_file_struct.pac_params.insert(uonvn->lag);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vn == nullptr && uon == nullptr)
|
|
||||||
{
|
|
||||||
cerr << "Pac growth parameter must be either a variable or a diff unary op of a variable" << endl;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PacModelStatement::overwriteGrowth(expr_t new_growth)
|
PacModelStatement::overwriteGrowth(expr_t new_growth)
|
||||||
{
|
{
|
||||||
if (new_growth == nullptr || growth == nullptr)
|
if (new_growth == nullptr || growth == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
growth = new_growth;
|
growth = new_growth;
|
||||||
auto *vn = dynamic_cast<VariableNode *>(growth);
|
try
|
||||||
if (vn == nullptr)
|
|
||||||
{
|
{
|
||||||
cerr << "PacModelStatement::overwriteGrowth: Internal Dynare error: should not arrive here" << endl;
|
growth_info = growth->matchLinearCombinationOfVariables();
|
||||||
|
}
|
||||||
|
catch (ExprNode::MatchFailureException &e)
|
||||||
|
{
|
||||||
|
cerr << "Pac growth must be a linear combination of varibles" << endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
growth_symb_id = vn->symb_id;
|
|
||||||
growth_lag = vn->lag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -349,8 +308,20 @@ PacModelStatement::writeOutput(ostream &output, const string &basename, bool min
|
||||||
output << "M_.pac." << name << ".steady_state_growth_rate = "
|
output << "M_.pac." << name << ".steady_state_growth_rate = "
|
||||||
<< symbol_table.getTypeSpecificID(steady_state_growth_rate_symb_id) + 1 << ";" << endl;
|
<< symbol_table.getTypeSpecificID(steady_state_growth_rate_symb_id) + 1 << ";" << endl;
|
||||||
|
|
||||||
if (growth_symb_id >= 0)
|
size_t nlc = growth_info.size();
|
||||||
|
output << "M_.pac." << name << ".growth_index = repmat(-1, " << nlc << ", 1);" << endl
|
||||||
|
<< "M_.pac." << name << ".growth_lag = zeros(" << nlc << ", 1);" << endl
|
||||||
|
<< "M_.pac." << name << ".growth_param_id = repmat(-1, " << nlc << ", 1);" << endl
|
||||||
|
<< "M_.pac." << name << ".growth_constant = zeros(" << nlc << ", 1);" << endl
|
||||||
|
<< "M_.pac." << name << ".growth_type = repmat({''}, " << nlc << ", 1);" << endl
|
||||||
|
<< "M_.pac." << name << ".growth_part_str = repmat({''}, " << nlc << ", 1);" << endl;
|
||||||
|
int i = 0;
|
||||||
|
for (auto & it : growth_info)
|
||||||
{
|
{
|
||||||
|
i++;
|
||||||
|
int growth_symb_id, growth_lag, param_id = -1;
|
||||||
|
double constant = 0;
|
||||||
|
tie(growth_symb_id, growth_lag, param_id, constant) = it;
|
||||||
string growth_type;
|
string growth_type;
|
||||||
switch (symbol_table.getType(growth_symb_id))
|
switch (symbol_table.getType(growth_symb_id))
|
||||||
{
|
{
|
||||||
|
@ -372,12 +343,8 @@ PacModelStatement::writeOutput(ostream &output, const string &basename, bool min
|
||||||
{
|
{
|
||||||
// case when this is not the highest lag of the growth variable
|
// case when this is not the highest lag of the growth variable
|
||||||
int aux_symb_id = symbol_table.searchAuxiliaryVars(growth_symb_id, growth_lag);
|
int aux_symb_id = symbol_table.searchAuxiliaryVars(growth_symb_id, growth_lag);
|
||||||
output << "M_.pac." << name << ".growth_index = " << symbol_table.getTypeSpecificID(aux_symb_id) + 1 << ";" << endl
|
output << "M_.pac." << name << ".growth_index(" << i << ") = " << symbol_table.getTypeSpecificID(aux_symb_id) + 1 << ";" << endl
|
||||||
<< "M_.pac." << name << ".growth_lag = 0;" << endl
|
<< "M_.pac." << name << ".growth_lag(" << i << ") = 0;" << endl;
|
||||||
<< "M_.pac." << name << ".growth_type = '" << growth_type << "';" << endl
|
|
||||||
<< "M_.pac." << name << ".growth_str = '";
|
|
||||||
original_growth->writeJsonOutput(output, {}, {}, true);
|
|
||||||
output << "';" << endl;
|
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
@ -386,26 +353,26 @@ PacModelStatement::writeOutput(ostream &output, const string &basename, bool min
|
||||||
// case when this is the highest lag of the growth variable
|
// case when this is the highest lag of the growth variable
|
||||||
int tmp_growth_lag = growth_lag + 1;
|
int tmp_growth_lag = growth_lag + 1;
|
||||||
int aux_symb_id = symbol_table.searchAuxiliaryVars(growth_symb_id, tmp_growth_lag);
|
int aux_symb_id = symbol_table.searchAuxiliaryVars(growth_symb_id, tmp_growth_lag);
|
||||||
output << "M_.pac." << name << ".growth_index = " << symbol_table.getTypeSpecificID(aux_symb_id) + 1 << ";" << endl
|
output << "M_.pac." << name << ".growth_index(" << i << ") = " << symbol_table.getTypeSpecificID(aux_symb_id) + 1 << ";" << endl
|
||||||
<< "M_.pac." << name << ".growth_lag = -1;" << endl
|
<< "M_.pac." << name << ".growth_lag(" << i << ") = -1;" << endl;
|
||||||
<< "M_.pac." << name << ".growth_type = '" << growth_type << "';" << endl
|
|
||||||
<< "M_.pac." << name << ".growth_str = '";
|
|
||||||
original_growth->writeJsonOutput(output, {}, {}, true);
|
|
||||||
output << "';" << endl;
|
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
// case when there is no aux var for the variable
|
// case when there is no aux var for the variable
|
||||||
output << "M_.pac." << name << ".growth_index = " << symbol_table.getTypeSpecificID(growth_symb_id) + 1 << ";" << endl
|
output << "M_.pac." << name << ".growth_index(" << i << ") = " << symbol_table.getTypeSpecificID(growth_symb_id) + 1 << ";" << endl
|
||||||
<< "M_.pac." << name << ".growth_lag = " << growth_lag << ";" << endl
|
<< "M_.pac." << name << ".growth_lag(" << i << ") = " << growth_lag << ";" << endl;
|
||||||
<< "M_.pac." << name << ".growth_type = '" << growth_type << "';" << endl
|
}
|
||||||
<< "M_.pac." << name << ".growth_str = '";
|
}
|
||||||
|
|
||||||
|
output << "M_.pac." << name << ".growth_param_id(" << i << ") = "
|
||||||
|
<< (param_id == -1 ? -1 : symbol_table.getTypeSpecificID(param_id)) + 1 << ";" << endl
|
||||||
|
<< "M_.pac." << name << ".growth_constant(" << i << ") = " << constant << ";" << endl
|
||||||
|
<< "M_.pac." << name << ".growth_type{" << i << "} = '" << growth_type << "';" << endl;
|
||||||
|
}
|
||||||
|
output << "M_.pac." << name << ".growth_str = '";
|
||||||
original_growth->writeJsonOutput(output, {}, {}, true);
|
original_growth->writeJsonOutput(output, {}, {}, true);
|
||||||
output << "';" << endl;
|
output << "';" << endl;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PacModelStatement::writeJsonOutput(ostream &output) const
|
PacModelStatement::writeJsonOutput(ostream &output) const
|
||||||
|
@ -413,35 +380,10 @@ PacModelStatement::writeJsonOutput(ostream &output) const
|
||||||
output << R"({"statementName": "pac_model",)"
|
output << R"({"statementName": "pac_model",)"
|
||||||
<< R"("model_name": ")" << name << R"(",)"
|
<< R"("model_name": ")" << name << R"(",)"
|
||||||
<< R"("auxiliary_model_name": ")" << aux_model_name << R"(",)"
|
<< R"("auxiliary_model_name": ")" << aux_model_name << R"(",)"
|
||||||
<< R"("discount_index": )" << symbol_table.getTypeSpecificID(discount) + 1;
|
<< R"("discount_index": )" << symbol_table.getTypeSpecificID(discount) + 1
|
||||||
|
|
||||||
if (growth_symb_id >= 0)
|
|
||||||
{
|
|
||||||
string growth_type;
|
|
||||||
switch (symbol_table.getType(growth_symb_id))
|
|
||||||
{
|
|
||||||
case SymbolType::endogenous:
|
|
||||||
growth_type = "endogenous";
|
|
||||||
break;
|
|
||||||
case SymbolType::exogenous:
|
|
||||||
growth_type = "exogenous";
|
|
||||||
break;
|
|
||||||
case SymbolType::parameter:
|
|
||||||
growth_type = "parameter";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
output << ","
|
|
||||||
<< R"("growth_index": )" << symbol_table.getTypeSpecificID(growth_symb_id) + 1 << ","
|
|
||||||
<< R"("growth_lag": )" << growth_lag << ","
|
|
||||||
<< R"("growth_type": ")" << growth_type << R"(",)" << endl
|
|
||||||
<< R"("growth_str": ")";
|
<< R"("growth_str": ")";
|
||||||
original_growth->writeJsonOutput(output, {}, {}, true);
|
original_growth->writeJsonOutput(output, {}, {}, true);
|
||||||
output << R"(")" << endl;
|
output << R"("})" << endl;
|
||||||
}
|
|
||||||
output << "}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VarEstimationStatement::VarEstimationStatement(OptionsList options_list_arg) :
|
VarEstimationStatement::VarEstimationStatement(OptionsList options_list_arg) :
|
||||||
|
|
|
@ -143,9 +143,8 @@ private:
|
||||||
const double steady_state_growth_rate_number;
|
const double steady_state_growth_rate_number;
|
||||||
const int steady_state_growth_rate_symb_id;
|
const int steady_state_growth_rate_symb_id;
|
||||||
const SymbolTable &symbol_table;
|
const SymbolTable &symbol_table;
|
||||||
|
vector<tuple<int, int, int, double>> growth_info;
|
||||||
public:
|
public:
|
||||||
int growth_symb_id;
|
|
||||||
int growth_lag;
|
|
||||||
PacModelStatement(string name_arg,
|
PacModelStatement(string name_arg,
|
||||||
string aux_model_name_arg,
|
string aux_model_name_arg,
|
||||||
string discount_arg,
|
string discount_arg,
|
||||||
|
@ -153,7 +152,6 @@ public:
|
||||||
double steady_state_growth_rate_number_arg,
|
double steady_state_growth_rate_number_arg,
|
||||||
int steady_state_growth_rate_symb_id_arg,
|
int steady_state_growth_rate_symb_id_arg,
|
||||||
const SymbolTable &symbol_table_arg);
|
const SymbolTable &symbol_table_arg);
|
||||||
void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override;
|
|
||||||
void overwriteGrowth(expr_t new_growth);
|
void overwriteGrowth(expr_t new_growth);
|
||||||
void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
|
void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
|
||||||
void writeJsonOutput(ostream &output) const override;
|
void writeJsonOutput(ostream &output) const override;
|
||||||
|
|
|
@ -4729,7 +4729,7 @@ DynamicModel::fillPacModelInfo(const string &pac_model_name,
|
||||||
string aux_model_type,
|
string aux_model_type,
|
||||||
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
|
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
|
||||||
const vector<bool> &nonstationary,
|
const vector<bool> &nonstationary,
|
||||||
int growth_symb_id, int growth_lag)
|
expr_t growth)
|
||||||
{
|
{
|
||||||
pac_eqtag_and_lag.insert(eqtag_and_lag.begin(), eqtag_and_lag.end());
|
pac_eqtag_and_lag.insert(eqtag_and_lag.begin(), eqtag_and_lag.end());
|
||||||
|
|
||||||
|
@ -4745,7 +4745,7 @@ DynamicModel::fillPacModelInfo(const string &pac_model_name,
|
||||||
stationary_vars_present = true;
|
stationary_vars_present = true;
|
||||||
|
|
||||||
int growth_param_index = -1;
|
int growth_param_index = -1;
|
||||||
if (growth_symb_id >= 0)
|
if (growth != nullptr)
|
||||||
growth_param_index = symbol_table.addSymbol(pac_model_name +
|
growth_param_index = symbol_table.addSymbol(pac_model_name +
|
||||||
"_pac_growth_neutrality_correction",
|
"_pac_growth_neutrality_correction",
|
||||||
SymbolType::parameter);
|
SymbolType::parameter);
|
||||||
|
@ -4789,10 +4789,9 @@ DynamicModel::fillPacModelInfo(const string &pac_model_name,
|
||||||
AddVariable(lhsit, -i)));
|
AddVariable(lhsit, -i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (growth_symb_id >= 0)
|
if (growth != nullptr)
|
||||||
subExpr = AddPlus(subExpr,
|
subExpr = AddPlus(subExpr,
|
||||||
AddTimes(AddVariable(growth_param_index),
|
AddTimes(AddVariable(growth_param_index), growth));
|
||||||
AddVariable(growth_symb_id, growth_lag)));
|
|
||||||
|
|
||||||
pac_expectation_substitution[{pac_model_name, eqtag}] = subExpr;
|
pac_expectation_substitution[{pac_model_name, eqtag}] = subExpr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -352,7 +352,7 @@ public:
|
||||||
string aux_model_type,
|
string aux_model_type,
|
||||||
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
|
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
|
||||||
const vector<bool> &nonstationary,
|
const vector<bool> &nonstationary,
|
||||||
int growth_symb_id, int growth_lag);
|
expr_t growth);
|
||||||
|
|
||||||
//! Substitutes pac_expectation operator with expectation based on auxiliary model
|
//! Substitutes pac_expectation operator with expectation based on auxiliary model
|
||||||
void substitutePacExpectation(const string & pac_model_name);
|
void substitutePacExpectation(const string & pac_model_name);
|
||||||
|
|
|
@ -471,7 +471,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
|
||||||
eqtag_and_lag, diff_subst_table);
|
eqtag_and_lag, diff_subst_table);
|
||||||
else
|
else
|
||||||
dynamic_model.fillPacModelInfo(pms->name, lhs, max_lag, aux_model_type,
|
dynamic_model.fillPacModelInfo(pms->name, lhs, max_lag, aux_model_type,
|
||||||
eqtag_and_lag, nonstationary, pms->growth_symb_id, pms->growth_lag);
|
eqtag_and_lag, nonstationary, pms->growth);
|
||||||
dynamic_model.substitutePacExpectation(pms->name);
|
dynamic_model.substitutePacExpectation(pms->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue