Only create auxiliary variables for diffs that appear in VAR equations or equations that have pac_expectations in them

Otherwise, substitute the diff (i.e. `diff(x)` -> `x-x(-1)`)
issue#70
Houtan Bastani 2018-06-05 18:38:53 +02:00
parent 27320a07f6
commit a30f8f365e
5 changed files with 115 additions and 15 deletions

View File

@ -5378,18 +5378,38 @@ DynamicModel::substituteAdl()
}
void
DynamicModel::substituteUnaryOps(StaticModel &static_model, set<string> &var_model_eqtags)
DynamicModel::getEquationNumbersFromTags(vector<int> &eqnumbers, set<string> &eqtags) const
{
diff_table_t nodes;
vector<int> eqnumber;
for (auto & eqtag : var_model_eqtags)
for (auto & eqtag : eqtags)
for (const auto & equation_tag : equation_tags)
if (equation_tag.second.first == "name"
&& equation_tag.second.second == eqtag)
{
eqnumber.push_back(equation_tag.first);
eqnumbers.push_back(equation_tag.first);
break;
}
}
void
DynamicModel::findPacExpectationEquationNumbers(vector<int> &eqnumbers) const
{
int i = 0;
for (auto & equation : equations)
{
if (equation->containsPacExpectation())
if (find(eqnumbers.begin(), eqnumbers.end(), i) == eqnumbers.end())
eqnumbers.push_back(i);
i++;
}
}
void
DynamicModel::substituteUnaryOps(StaticModel &static_model, set<string> &var_model_eqtags)
{
diff_table_t nodes;
vector<int> eqnumber;
getEquationNumbersFromTags(eqnumber, var_model_eqtags);
findPacExpectationEquationNumbers(eqnumber);
// Find matching unary ops that may be outside of diffs (i.e., those with different lags)
set<int> used_local_vars;
@ -5430,15 +5450,24 @@ DynamicModel::substituteUnaryOps(StaticModel &static_model, set<string> &var_mod
}
void
DynamicModel::substituteDiff(StaticModel &static_model, ExprNode::subst_table_t &diff_subst_table)
DynamicModel::substituteDiff(StaticModel &static_model, ExprNode::subst_table_t &diff_subst_table, set<string> &var_model_eqtags)
{
// Find diff Nodes
vector<int> eqnumbers;
getEquationNumbersFromTags(eqnumbers, var_model_eqtags);
findPacExpectationEquationNumbers(eqnumbers);
set<int> used_local_vars;
for (int eqnumber : eqnumbers)
equations[eqnumber]->collectVariables(eModelLocalVariable, used_local_vars);
// Only substitute diffs in model local variables that appear in VAR equations
diff_table_t diff_table;
for (auto & it : local_variables_table)
it.second->findDiffNodes(static_model, diff_table);
if (used_local_vars.find(it.first) != used_local_vars.end())
it.second->findDiffNodes(static_model, diff_table);
for (auto & equation : equations)
equation->findDiffNodes(static_model, diff_table);
for (int eqnumber : eqnumbers)
equations[eqnumber]->findDiffNodes(static_model, diff_table);
// Substitute in model local variables
vector<BinaryOpNode *> neweqs;

View File

@ -245,6 +245,10 @@ private:
//! Create a legacy *_dynamic.m file for Matlab/Octave not yet using the temporary terms array interface
void writeDynamicMatlabCompatLayer(const string &name) const;
void getEquationNumbersFromTags(vector<int> &eqnumber, set<string> &eqtags) const;
void findPacExpectationEquationNumbers(vector<int> &eqnumber) const;
public:
DynamicModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_argx);
//! Adds a variable node
@ -423,7 +427,7 @@ public:
void substituteUnaryOps(StaticModel &static_model, set<string> &eq_tags);
//! Substitutes diff operator
void substituteDiff(StaticModel &static_model, ExprNode::subst_table_t &diff_subst_table);
void substituteDiff(StaticModel &static_model, ExprNode::subst_table_t &diff_subst_table, set<string> &var_model_eqtags);
//! 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,

View File

@ -600,6 +600,12 @@ NumConstNode::getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const
{
}
bool
NumConstNode::containsPacExpectation() const
{
return false;
}
bool
NumConstNode::containsEndogenous() const
{
@ -1688,6 +1694,12 @@ VariableNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int la
return false;
}
bool
VariableNode::containsPacExpectation() const
{
return false;
}
bool
VariableNode::containsEndogenous() const
{
@ -3127,8 +3139,11 @@ UnaryOpNode::substituteDiff(DataTree &static_datatree, diff_table_t &diff_table,
auto it = diff_table.find(sthis);
if (it == diff_table.end() || it->second[-arg->maxLag()] != this)
{
cerr << "Internal error encountered. Please report" << endl;
exit(EXIT_FAILURE);
// diff does not appear in VAR equations
// so simply substitute diff(x) with x-x(-1)
expr_t argsubst = arg->substituteDiff(static_datatree, diff_table, subst_table, neweqs);
return dynamic_cast<BinaryOpNode *>(datatree.AddMinus(argsubst,
argsubst->decreaseLeadsLags(1)));
}
int last_arg_max_lag = 0;
@ -3358,6 +3373,12 @@ UnaryOpNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag
return false;
}
bool
UnaryOpNode::containsPacExpectation() const
{
return arg->containsPacExpectation();
}
bool
UnaryOpNode::containsEndogenous() const
{
@ -4955,6 +4976,12 @@ BinaryOpNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int la
return false;
}
bool
BinaryOpNode::containsPacExpectation() const
{
return (arg1->containsPacExpectation() || arg2->containsPacExpectation());
}
bool
BinaryOpNode::containsEndogenous() const
{
@ -5856,6 +5883,12 @@ TrinaryOpNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int l
return false;
}
bool
TrinaryOpNode::containsPacExpectation() const
{
return (arg1->containsPacExpectation() || arg2->containsPacExpectation() || arg3->containsPacExpectation());
}
bool
TrinaryOpNode::containsEndogenous() const
{
@ -6332,6 +6365,16 @@ AbstractExternalFunctionNode::isVariableNodeEqualTo(SymbolType type_arg, int var
return false;
}
bool
AbstractExternalFunctionNode::containsPacExpectation() const
{
bool result = false;
for (auto argument : arguments)
result = result || argument->containsPacExpectation();
return result;
}
bool
AbstractExternalFunctionNode::containsEndogenous() const
{
@ -7838,6 +7881,12 @@ VarExpectationNode::differentiateForwardVars(const vector<string> &subset, subst
return const_cast<VarExpectationNode *>(this);
}
bool
VarExpectationNode::containsPacExpectation() const
{
return false;
}
bool
VarExpectationNode::containsEndogenous() const
{
@ -8280,6 +8329,12 @@ PacExpectationNode::differentiateForwardVars(const vector<string> &subset, subst
return const_cast<PacExpectationNode *>(this);
}
bool
PacExpectationNode::containsPacExpectation() const
{
return true;
}
bool
PacExpectationNode::containsEndogenous() const
{

View File

@ -540,6 +540,9 @@ class ExprNode
//! Fills var_model info for pac_expectation node
virtual void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) = 0;
//! Returns true if PacExpectationNode encountered
virtual bool containsPacExpectation() const = 0;
//! Fills map
virtual void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const = 0;
};
@ -623,6 +626,7 @@ public:
void walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &params_and_vars) const override;
void addParamInfoToPac(pair<int, int> &lhs_arg, set<pair<int, pair<int, int>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg) override;
void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
virtual bool containsPacExpectation() const override;
bool isVarModelReferenced(const string &model_info_name) const override;
void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
expr_t substituteStaticAuxiliaryVariable() const override;
@ -713,6 +717,7 @@ public:
void walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &params_and_vars) const override;
void addParamInfoToPac(pair<int, int> &lhs_arg, set<pair<int, pair<int, int>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg) override;
void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
bool containsPacExpectation() const override;
bool isVarModelReferenced(const string &model_info_name) const override;
void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
//! Substitute auxiliary variables by their expression in static model
@ -827,6 +832,7 @@ public:
void walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &params_and_vars) const override;
void addParamInfoToPac(pair<int, int> &lhs_arg, set<pair<int, pair<int, int>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg) override;
void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
bool containsPacExpectation() const override;
bool isVarModelReferenced(const string &model_info_name) const override;
void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
//! Substitute auxiliary variables by their expression in static model
@ -963,6 +969,7 @@ public:
void walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &params_and_vars) const override;
void addParamInfoToPac(pair<int, int> &lhs_arg, set<pair<int, pair<int, int>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &ar_params_and_vars_arg) override;
void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
bool containsPacExpectation() const override;
bool isVarModelReferenced(const string &model_info_name) const override;
void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
//! Substitute auxiliary variables by their expression in static model
@ -1063,6 +1070,7 @@ public:
void walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &params_and_vars) const override;
void addParamInfoToPac(pair<int, int> &lhs_arg, set<pair<int, pair<int, int>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg) override;
void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
bool containsPacExpectation() const override;
bool isVarModelReferenced(const string &model_info_name) const override;
void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
//! Substitute auxiliary variables by their expression in static model
@ -1175,6 +1183,7 @@ public:
void walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &params_and_vars) const override;
void addParamInfoToPac(pair<int, int> &lhs_arg, set<pair<int, pair<int, int>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg) override;
void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
bool containsPacExpectation() const override;
bool isVarModelReferenced(const string &model_info_name) const override;
void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
//! Substitute auxiliary variables by their expression in static model
@ -1377,6 +1386,7 @@ public:
void walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &params_and_vars) const override;
void addParamInfoToPac(pair<int, int> &lhs_arg, set<pair<int, pair<int, int>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg) override;
void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
bool containsPacExpectation() const override;
bool isVarModelReferenced(const string &model_info_name) const override;
void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
expr_t substituteStaticAuxiliaryVariable() const override;
@ -1462,6 +1472,7 @@ public:
void walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &params_and_vars) const override;
void addParamInfoToPac(pair<int, int> &lhs_arg, set<pair<int, pair<int, int>>> &ec_params_and_vars_arg, set<pair<int, pair<int, int>>> &params_and_vars_arg) override;
void fillPacExpectationVarInfo(string &model_name_arg, vector<int> &lhs_arg, int max_lag_arg, vector<bool> &nonstationary_arg, int growth_symb_id_arg, int equation_number_arg) override;
bool containsPacExpectation() const override;
bool isVarModelReferenced(const string &model_info_name) const override;
void getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const override;
expr_t substituteStaticAuxiliaryVariable() const override;

View File

@ -364,6 +364,7 @@ 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;
@ -383,9 +384,9 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
// substitute only those unary ops that appear in VAR equations
dynamic_model.substituteUnaryOps(diff_static_model, eqtags);
// Create auxiliary variable and equations for Diff operator
// Create auxiliary variable and equations for Diff operators that appear in VAR equations
ExprNode::subst_table_t diff_subst_table;
dynamic_model.substituteDiff(diff_static_model, diff_subst_table);
dynamic_model.substituteDiff(diff_static_model, diff_subst_table, eqtags);
// Var Model
map<string, tuple<vector<int>, vector<expr_t>, vector<bool>, vector<int>, int, vector<bool>, vector<int>>>