New var_expectation_model statement and re-design of var_expectation operator

Given a previously declared var_model, the var_expectation_model statement is
used to declare a way of forming expectations with this VAR (possibly using a
finite or infinite discounted sum). The var_expectation operator now takes a
single argument, the name of the var_expectation_model.

For the moment, this only works when the var_model is using equations
explicitly declared in the model block.
issue#70
Sébastien Villemot 2018-08-01 19:41:44 +02:00
parent 8a03532c78
commit f3c2a1bf87
13 changed files with 387 additions and 232 deletions

View File

@ -528,30 +528,6 @@ VarModelStatement::writeJsonOutput(ostream &output) const
<< "\"model_name\": \"" << name << "\"}";
}
void
VarModelStatement::createVarModelMFunction(ostream &output, const map<string, set<int>> &var_expectation_functions_to_write) const
{
if (var_expectation_functions_to_write.find(name) == var_expectation_functions_to_write.end())
return;
stringstream ss;
set<int> horizons = var_expectation_functions_to_write.find(name)->second;
for (auto it = horizons.begin(); it != horizons.end(); it++)
{
if (it != horizons.begin())
ss << " ";
ss << *it;
}
output << "writeVarExpectationFunction('" << name << "', ";
if (horizons.size() > 1)
output << "[";
output << ss.rdbuf();
if (horizons.size() > 1)
output << "]";
output << ");" << endl;
}
VarEstimationStatement::VarEstimationStatement(OptionsList options_list_arg) :
options_list(move(options_list_arg))
{
@ -5017,3 +4993,45 @@ GenerateIRFsStatement::writeJsonOutput(ostream &output) const
}
output << "}";
}
VarExpectationModelStatement::VarExpectationModelStatement(string model_name_arg, string variable_arg, string var_model_name_arg,
string horizon_arg, expr_t discount_arg, const SymbolTable &symbol_table_arg) :
model_name{move(model_name_arg)}, variable{move(variable_arg)},
var_model_name{move(var_model_name_arg)}, horizon{move(horizon_arg)},
discount{discount_arg}, symbol_table{symbol_table_arg}
{
}
void
VarExpectationModelStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
{
string mstruct = "M_.var_expectation." + model_name;
output << mstruct << ".var_model_name = '" << var_model_name << "';" << endl
<< mstruct << ".horizon = " << horizon << ';' << endl;
auto disc_var = dynamic_cast<const VariableNode *>(discount);
if (disc_var)
output << mstruct << ".discount_index = " << disc_var->get_symb_id() << ';' << endl;
else
{
output << mstruct << ".discount_value = ";
discount->writeOutput(output);
output << ';' << endl;
}
output << mstruct << ".param_indices = [ ";
for (int param_id : aux_params_ids)
output << symbol_table.getTypeSpecificID(param_id) << ' ';
output << "];" << endl;
}
void
VarExpectationModelStatement::writeJsonOutput(ostream &output) const
{
output << "{\"statementName\": \"var_expectation_model\","
<< "\"model_name\": \"" << model_name << "\", "
<< "\"variable\": \"" << variable << "\", "
<< "\"var_model_name\": \"" << var_model_name << "\", "
<< "\"horizon\": \"" << horizon << "\", "
<< "\"discount\": \"";
discount->writeOutput(output);
output << "\"}";
}

View File

@ -145,10 +145,11 @@ public:
class VarModelStatement : public Statement
{
private:
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
@ -170,7 +171,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 createVarModelMFunction(ostream &output, const map<string, set<int>> &var_expectation_functions_to_write) const;
};
class VarRestrictionsStatement : public Statement
@ -1209,4 +1209,20 @@ public:
void writeJsonOutput(ostream &output) const override;
};
class VarExpectationModelStatement : public Statement
{
public:
const string model_name, variable, var_model_name, horizon;
const expr_t discount;
const SymbolTable &symbol_table;
// List of generated auxiliary param ids, in variable-major order
vector<int> aux_params_ids; // TODO: move this to some new VarModelTable object
public:
VarExpectationModelStatement(string model_name_arg, string variable_arg, string var_model_name_arg,
string horizon_arg, expr_t discount_arg, const SymbolTable &symbol_table_arg);
void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream &output) const override;
};
#endif

View File

@ -505,15 +505,13 @@ DataTree::AddExpectation(int iArg1, expr_t iArg2)
}
expr_t
DataTree::AddVarExpectation(const int symb_id, const int forecast_horizon, const string &model_name)
DataTree::AddVarExpectation(const string &model_name)
{
assert(symbol_table.getType(symb_id) == SymbolType::endogenous);
auto it = var_expectation_node_map.find({ model_name, symb_id, forecast_horizon });
auto it = var_expectation_node_map.find(model_name);
if (it != var_expectation_node_map.end())
return it->second;
return new VarExpectationNode(*this, symb_id, forecast_horizon, model_name);
return new VarExpectationNode(*this, model_name);
}
expr_t

View File

@ -82,7 +82,7 @@ protected:
external_function_node_map_t external_function_node_map;
// (model_name, symb_id, forecast_horizon) -> VarExpectationNode
using var_expectation_node_map_t = map<tuple<string, int, int>, VarExpectationNode *>;
using var_expectation_node_map_t = map<string, VarExpectationNode *>;
var_expectation_node_map_t var_expectation_node_map;
// model_name -> PacExpectationNode
@ -242,8 +242,8 @@ public:
expr_t AddSteadyStateParam2ndDeriv(expr_t iArg1, int param1_symb_id, int param2_symb_id);
//! Adds "arg1=arg2" to model tree
expr_t AddEqual(expr_t iArg1, expr_t iArg2);
//! Adds "var_expectation(arg1, arg2, model_name=arg3)" to model tree
expr_t AddVarExpectation(const int symb_id, const int forecast_horizon, const string &model_name);
//! Adds "var_expectation(model_name)" to model tree
expr_t AddVarExpectation(const string &model_name);
//! Adds pac_expectation command to model tree
expr_t AddPacExpectation(const string &model_name);
//! Adds a model local variable with its value

View File

@ -1515,34 +1515,6 @@ DynamicModel::writeDynamicMFile(const string &basename) const
writeDynamicModel(basename, false, false);
}
void
DynamicModel::fillVarExpectationFunctionsToWrite()
{
for (auto &it : var_expectation_node_map)
var_expectation_functions_to_write[get<0>(it.first)].insert(get<2>(it.first));
}
map<string, set<int>>
DynamicModel::getVarExpectationFunctionsToWrite() const
{
return var_expectation_functions_to_write;
}
void
DynamicModel::writeVarExpectationCalls(ostream &output) const
{
for (const auto & it : var_expectation_functions_to_write)
{
int i = 0;
output << "dynamic_var_forecast_" << it.first << " = "
<< "var_forecast_" << it.first << "(y);" << endl;
for (auto it1 = it.second.begin(); it1 != it.second.end(); it1++)
output << "dynamic_var_forecast_" << it.first << "_" << *it1 << " = "
<< "dynamic_var_forecast_" << it.first << "(" << ++i << ", :);" << endl;
}
}
void
DynamicModel::writeDynamicJuliaFile(const string &basename) const
{
@ -3628,13 +3600,6 @@ DynamicModel::getVarLhsDiffAndInfo(vector<int> &eqnumber, vector<bool> &diff,
}
}
void
DynamicModel::setVarExpectationIndices(map<string, pair<SymbolList, int>> &var_model_info)
{
for (auto & equation : equations)
equation->setVarExpectationIndex(var_model_info);
}
void
DynamicModel::addEquationsForVar(map<string, pair<SymbolList, int>> &var_model_info)
{
@ -6220,3 +6185,10 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
<< ", " << third_derivs1_output.str()
<< "}";
}
void
DynamicModel::substituteVarExpectation(const map<string, expr_t> &subst_table)
{
for (auto & equation : equations)
equation = dynamic_cast<BinaryOpNode *>(equation->substituteVarExpectation(subst_table));
}

View File

@ -100,8 +100,6 @@ private:
void writeDynamicMFile(const string &basename) const;
//! Writes dynamic model file (Julia version)
void writeDynamicJuliaFile(const string &dynamic_basename) const;
//! Write Var Expectation calls
void writeVarExpectationCalls(ostream &output) const;
//! Writes dynamic model file (C version)
/*! \todo add third derivatives handling */
void writeDynamicCFile(const string &basename, const int order) const;
@ -320,8 +318,6 @@ public:
void getVarLhsDiffAndInfo(vector<int> &eqnumber, vector<bool> &diff,
vector<int> &orig_diff_var) const;
//! Set indices for var expectation in dynamic model file
void setVarExpectationIndices(map<string, pair<SymbolList, int>> &var_model_info);
//! 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);
//! Get Pac equation parameter info
@ -435,16 +431,13 @@ public:
//! Substitutes diff operator
void substituteDiff(StaticModel &static_model, ExprNode::subst_table_t &diff_subst_table);
//! Substitute VarExpectation operators
void substituteVarExpectation(const map<string, expr_t> &subst_table);
//! 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);
//! Fill var_expectation_functions_to_write
void fillVarExpectationFunctionsToWrite();
//! Get var_expectation_functions_to_write
map<string, set<int>> getVarExpectationFunctionsToWrite() const;
//! Transforms the model by replacing trend variables with a 1
void removeTrendVariableFromEquations();

View File

@ -118,7 +118,7 @@ class ParsingDriver;
%token TEX RAMSEY_MODEL RAMSEY_POLICY RAMSEY_CONSTRAINTS PLANNER_DISCOUNT DISCRETIONARY_POLICY DISCRETIONARY_TOL
%token <string> TEX_NAME
%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 VAROBS VAREXOBS PREDETERMINED_VARIABLES VAR_EXPECTATION PLOT_SHOCK_DECOMPOSITION MODEL_LOCAL_VARIABLE
%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
%left EQUAL_EQUAL EXCLAMATION_EQUAL
@ -175,8 +175,9 @@ class ParsingDriver;
%type <string> filename symbol vec_of_vec_value vec_value_list date_expr number
%type <string> vec_value_1 vec_value signed_inf signed_number_w_inf
%type <string> range vec_value_w_inf vec_value_1_w_inf
%type <string> integer_range signed_integer_range sub_sampling_options list_sub_sampling_option
%type <pair<string,string>> named_var_elem subsamples_eq_opt calibration_range
%type <string> integer_range signed_integer_range
%type <string> sub_sampling_options list_sub_sampling_option
%type <pair<string,string>> named_var_elem subsamples_eq_opt calibration_range integer_range_w_inf
%type <vector<pair<string,string>>> named_var named_var_1
%type <SymbolType> change_type_arg
%type <vector<string>> vec_str vec_str_1
@ -298,6 +299,7 @@ statement : parameters
| gmm_estimation
| smm_estimation
| shock_groups
| var_expectation_model
;
dsample : DSAMPLE INT_NUMBER ';'
@ -386,6 +388,29 @@ pac_model_options : o_pac_name
{ driver.pac_model_undiff($3, $5); }
;
var_expectation_model : VAR_EXPECTATION_MODEL '(' var_expectation_model_options_list ')' ';'
{ driver.var_expectation_model(); }
;
var_expectation_model_options_list : var_expectation_model_option
| var_expectation_model_options_list COMMA var_expectation_model_option
;
var_expectation_model_option : VARIABLE EQUAL symbol
{ driver.option_str("variable", $3); }
| VAR_MODEL_NAME EQUAL symbol
{ driver.option_str("var_model_name", $3); }
| HORIZON EQUAL INT_NUMBER
{ driver.option_num("horizon", $3); }
| HORIZON EQUAL integer_range_w_inf
{ driver.option_num("horizon", "[ " + $3.first + ' ' + $3.second + " ]"); }
| MODEL_NAME EQUAL symbol
{ driver.option_str("model_name", $3); }
| DISCOUNT EQUAL expression
{ driver.var_expectation_model_discount = $3; }
;
restrictions : RESTRICTIONS '(' symbol ')' ';' { driver.begin_VAR_restrictions(); }
restrictions_list END ';' { driver.end_VAR_restrictions($3); }
;
@ -912,10 +937,8 @@ hand_side : '(' hand_side ')'
{ $$ = driver.add_power($1, $3); }
| EXPECTATION '(' signed_integer ')''(' hand_side ')'
{ $$ = driver.add_expectation($3, $6); }
| VAR_EXPECTATION '(' symbol COMMA MODEL_NAME EQUAL NAME ')'
{ $$ = driver.add_var_expectation($3, "1", $7); }
| VAR_EXPECTATION '(' symbol COMMA INT_NUMBER COMMA MODEL_NAME EQUAL NAME ')'
{ $$ = driver.add_var_expectation($3, $5, $9); }
| VAR_EXPECTATION '(' symbol ')'
{ $$ = driver.add_var_expectation($3); }
| PAC_EXPECTATION '(' symbol ')'
{ $$ = driver.add_pac_expectation($3); }
| MINUS hand_side %prec UMINUS
@ -3650,6 +3673,12 @@ range : symbol ':' symbol
integer_range : INT_NUMBER ':' INT_NUMBER
{ $$ = $1 + ':' + $3; }
integer_range_w_inf : INT_NUMBER ':' INT_NUMBER
{ $$ = make_pair($1, $3); }
| INT_NUMBER ':' INF_CONSTANT
{ $$ = make_pair($1, "Inf"); }
;
signed_integer_range : signed_integer ':' signed_integer
{ $$ = $1 + ':' + $3; }
| MINUS '(' signed_integer ':' signed_integer ')'

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>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;}
<INITIAL>Sigma_e {BEGIN DYNARE_STATEMENT; sigma_e = 1; return token::SIGMA_E;}
@ -675,6 +676,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>emas_drop {return token::EMAS_DROP; }
<DYNARE_STATEMENT>emas_tolf {return token::EMAS_TOLF; }
<DYNARE_STATEMENT>emas_max_iter {return token::EMAS_MAX_ITER; }
<DYNARE_STATEMENT>variable {return token::VARIABLE;}
<DYNARE_STATEMENT>[\$][^$]*[\$] {
strtok(yytext+1, "$");

View File

@ -547,6 +547,12 @@ NumConstNode::substituteAdl() const
return const_cast<NumConstNode *>(this);
}
expr_t
NumConstNode::substituteVarExpectation(const map<string, expr_t> &subst_table) const
{
return const_cast<NumConstNode *>(this);
}
void
NumConstNode::findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const
{
@ -643,11 +649,6 @@ NumConstNode::isInStaticForm() const
return true;
}
void
NumConstNode::setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info)
{
}
void
NumConstNode::walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &ar_params_and_vars) const
{
@ -1419,6 +1420,12 @@ VariableNode::substituteAdl() const
return const_cast<VariableNode *>(this);
}
expr_t
VariableNode::substituteVarExpectation(const map<string, expr_t> &subst_table) const
{
return const_cast<VariableNode *>(this);
}
void
VariableNode::findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const
{
@ -1793,11 +1800,6 @@ VariableNode::isInStaticForm() const
return lag == 0;
}
void
VariableNode::setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info)
{
}
void
VariableNode::walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &ar_params_and_vars) const
{
@ -3009,6 +3011,13 @@ UnaryOpNode::substituteAdl() const
return retval;
}
expr_t
UnaryOpNode::substituteVarExpectation(const map<string, expr_t> &subst_table) const
{
expr_t argsubst = arg->substituteVarExpectation(subst_table);
return buildSimilarUnaryOpNode(argsubst, datatree);
}
int
UnaryOpNode::countDiffs() const
{
@ -3390,12 +3399,6 @@ UnaryOpNode::isInStaticForm() const
return arg->isInStaticForm();
}
void
UnaryOpNode::setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info)
{
arg->setVarExpectationIndex(var_model_info);
}
void
UnaryOpNode::walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &ar_params_and_vars) const
{
@ -4870,6 +4873,15 @@ BinaryOpNode::substituteAdl() const
return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
}
expr_t
BinaryOpNode::substituteVarExpectation(const map<string, expr_t> &subst_table) const
{
expr_t arg1subst = arg1->substituteVarExpectation(subst_table);
expr_t arg2subst = arg2->substituteVarExpectation(subst_table);
return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
}
void
BinaryOpNode::findUnaryOpNodesForAuxVarCreation(DataTree &static_datatree, diff_table_t &nodes) const
{
@ -4991,13 +5003,6 @@ BinaryOpNode::isInStaticForm() const
return arg1->isInStaticForm() && arg2->isInStaticForm();
}
void
BinaryOpNode::setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info)
{
arg1->setVarExpectationIndex(var_model_info);
arg2->setVarExpectationIndex(var_model_info);
}
void
BinaryOpNode::walkPacParametersHelper(const expr_t arg1, const expr_t arg2,
pair<int, int> &lhs,
@ -5779,6 +5784,16 @@ TrinaryOpNode::substituteAdl() const
return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
}
expr_t
TrinaryOpNode::substituteVarExpectation(const map<string, expr_t> &subst_table) const
{
expr_t arg1subst = arg1->substituteVarExpectation(subst_table);
expr_t arg2subst = arg2->substituteVarExpectation(subst_table);
expr_t arg3subst = arg3->substituteVarExpectation(subst_table);
return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
}
void
TrinaryOpNode::findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const
{
@ -5901,14 +5916,6 @@ TrinaryOpNode::isInStaticForm() const
return arg1->isInStaticForm() && arg2->isInStaticForm() && arg3->isInStaticForm();
}
void
TrinaryOpNode::setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info)
{
arg1->setVarExpectationIndex(var_model_info);
arg2->setVarExpectationIndex(var_model_info);
arg3->setVarExpectationIndex(var_model_info);
}
void
TrinaryOpNode::walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &ar_params_and_vars) const
{
@ -6214,6 +6221,15 @@ AbstractExternalFunctionNode::substituteAdl() const
return buildSimilarExternalFunctionNode(arguments_subst, datatree);
}
expr_t
AbstractExternalFunctionNode::substituteVarExpectation(const map<string, expr_t> &subst_table) const
{
vector<expr_t> arguments_subst;
for (auto argument : arguments)
arguments_subst.push_back(argument->substituteVarExpectation(subst_table));
return buildSimilarExternalFunctionNode(arguments_subst, datatree);
}
void
AbstractExternalFunctionNode::findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const
{
@ -6398,13 +6414,6 @@ AbstractExternalFunctionNode::isInStaticForm() const
return true;
}
void
AbstractExternalFunctionNode::setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info)
{
for (auto argument : arguments)
argument->setVarExpectationIndex(var_model_info);
}
void
AbstractExternalFunctionNode::walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &ar_params_and_vars) const
{
@ -7564,16 +7573,11 @@ SecondDerivExternalFunctionNode::sameTefTermPredicate() const
}
VarExpectationNode::VarExpectationNode(DataTree &datatree_arg,
int symb_id_arg,
int forecast_horizon_arg,
const string &model_name_arg) :
string model_name_arg) :
ExprNode(datatree_arg),
symb_id(symb_id_arg),
forecast_horizon(forecast_horizon_arg),
model_name(model_name_arg),
yidx(-1)
model_name{move(model_name_arg)}
{
datatree.var_expectation_node_map[{ model_name, symb_id, forecast_horizon }] = this;
datatree.var_expectation_node_map[model_name] = this;
}
void
@ -7581,7 +7585,8 @@ VarExpectationNode::computeTemporaryTerms(map<expr_t, pair<int, NodeTreeReferenc
map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
bool is_matlab, NodeTreeReference tr) const
{
temp_terms_map[tr].insert(const_cast<VarExpectationNode *>(this));
cerr << "VarExpectationNode::computeTemporaryTerms not implemented." << endl;
exit(EXIT_FAILURE);
}
void
@ -7592,22 +7597,21 @@ VarExpectationNode::computeTemporaryTerms(map<expr_t, int> &reference_count,
vector< vector<temporary_terms_t>> &v_temporary_terms,
int equation) const
{
expr_t this2 = const_cast<VarExpectationNode *>(this);
temporary_terms.insert(this2);
first_occurence[this2] = { Curr_block, equation };
v_temporary_terms[Curr_block][equation].insert(this2);
cerr << "VarExpectationNode::computeTemporaryTerms not implemented." << endl;
exit(EXIT_FAILURE);
}
expr_t
VarExpectationNode::toStatic(DataTree &static_datatree) const
{
return static_datatree.AddVariable(symb_id);
cerr << "VarExpectationNode::toStatic not implemented." << endl;
exit(EXIT_FAILURE);
}
expr_t
VarExpectationNode::cloneDynamic(DataTree &dynamic_datatree) const
{
return dynamic_datatree.AddVarExpectation(symb_id, forecast_horizon, model_name);
return dynamic_datatree.AddVarExpectation(model_name);
}
void
@ -7620,101 +7624,110 @@ VarExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
if (IS_LATEX(output_type))
{
output << "VAR_" << model_name << LEFT_PAR(output_type)
<< datatree.symbol_table.getTeXName(symb_id)
<< "_{t+" << forecast_horizon << "}" << RIGHT_PAR(output_type);
output << "VAR_EXPECTATION(" << model_name << ')';
return;
}
if (checkIfTemporaryTermThenWrite(output, output_type, temporary_terms, temporary_terms_idxs))
return;
output << "dynamic_var_forecast_" << model_name << "_" << forecast_horizon << "(" << yidx + 1 << ")";
cerr << "VarExpectationNode::writeOutput not implemented for non-LaTeX." << endl;
exit(EXIT_FAILURE);
}
int
VarExpectationNode::maxEndoLead() const
{
return 0;
cerr << "VarExpectationNode::maxEndoLead not implemented." << endl;
exit(EXIT_FAILURE);
}
int
VarExpectationNode::maxExoLead() const
{
return 0;
cerr << "VarExpectationNode::maxExoLead not implemented." << endl;
exit(EXIT_FAILURE);
}
int
VarExpectationNode::maxEndoLag() const
{
return 0;
cerr << "VarExpectationNode::maxEndoLead not implemented." << endl;
exit(EXIT_FAILURE);
}
int
VarExpectationNode::maxExoLag() const
{
return 0;
cerr << "VarExpectationNode::maxExoLead not implemented." << endl;
exit(EXIT_FAILURE);
}
int
VarExpectationNode::maxLead() const
{
return 0;
cerr << "VarExpectationNode::maxLead not implemented." << endl;
exit(EXIT_FAILURE);
}
int
VarExpectationNode::maxLag() const
{
return 0;
cerr << "VarExpectationNode::maxLag not implemented." << endl;
exit(EXIT_FAILURE);
}
expr_t
VarExpectationNode::undiff() const
{
return const_cast<VarExpectationNode *>(this);
cerr << "VarExpectationNode::undiff not implemented." << endl;
exit(EXIT_FAILURE);
}
int
VarExpectationNode::VarMinLag() const
{
return 1;
cerr << "VarExpectationNode::VarMinLag not implemented." << endl;
exit(EXIT_FAILURE);
}
int
VarExpectationNode::VarMaxLag(DataTree &static_datatree, set<expr_t> &static_lhs) const
{
return 0;
cerr << "VarExpectationNode::VarMaxLag not implemented." << endl;
exit(EXIT_FAILURE);
}
int
VarExpectationNode::PacMaxLag(vector<int> &lhs) const
{
return 0;
cerr << "VarExpectationNode::PacMaxLag not implemented." << endl;
exit(EXIT_FAILURE);
}
expr_t
VarExpectationNode::decreaseLeadsLags(int n) const
{
return const_cast<VarExpectationNode *>(this);
cerr << "VarExpectationNode::decreaseLeadsLags not implemented." << endl;
exit(EXIT_FAILURE);
}
void
VarExpectationNode::prepareForDerivation()
{
preparedForDerivation = true;
// Come back
cerr << "VarExpectationNode::prepareForDerivation not implemented." << endl;
exit(EXIT_FAILURE);
}
expr_t
VarExpectationNode::computeDerivative(int deriv_id)
{
return datatree.Zero;
cerr << "VarExpectationNode::computeDerivative not implemented." << endl;
exit(EXIT_FAILURE);
}
expr_t
VarExpectationNode::getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recursive_variables)
{
return datatree.Zero;
cerr << "VarExpectationNode::getChainRuleDerivative not implemented." << endl;
exit(EXIT_FAILURE);
}
bool
@ -7726,17 +7739,14 @@ VarExpectationNode::containsExternalFunction() const
double
VarExpectationNode::eval(const eval_context_t &eval_context) const noexcept(false)
{
auto it = eval_context.find(symb_id);
if (it == eval_context.end())
throw EvalException();
return it->second;
throw EvalException();
}
int
VarExpectationNode::countDiffs() const
{
return 0;
cerr << "VarExpectationNode::countDiffs not implemented." << endl;
exit(EXIT_FAILURE);
}
void
@ -7759,9 +7769,8 @@ VarExpectationNode::collectDynamicVariables(SymbolType type_arg, set<pair<int, i
void
VarExpectationNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const
{
auto it = temporary_terms.find(const_cast<VarExpectationNode *>(this));
if (it != temporary_terms.end())
temporary_terms_inuse.insert(idx);
cerr << "VarExpectationNode::collectTemporary_terms not implemented." << endl;
exit(EXIT_FAILURE);
}
void
@ -7777,31 +7786,36 @@ VarExpectationNode::compile(ostream &CompileCode, unsigned int &instruction_numb
pair<int, expr_t >
VarExpectationNode::normalizeEquation(int var_endo, vector<pair<int, pair<expr_t, expr_t>>> &List_of_Op_RHS) const
{
return { 0, datatree.AddVariableInternal(symb_id, 0) };
cerr << "VarExpectationNode::normalizeEquation not implemented." << endl;
exit(EXIT_FAILURE);
}
expr_t
VarExpectationNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const
{
return const_cast<VarExpectationNode *>(this);
cerr << "VarExpectationNode::substituteEndoLeadGreaterThanTwo not implemented." << endl;
exit(EXIT_FAILURE);
}
expr_t
VarExpectationNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
return const_cast<VarExpectationNode *>(this);
cerr << "VarExpectationNode::substituteEndoLagGreaterThanTwo not implemented." << endl;
exit(EXIT_FAILURE);
}
expr_t
VarExpectationNode::substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool deterministic_model) const
{
return const_cast<VarExpectationNode *>(this);
cerr << "VarExpectationNode::substituteExoLead not implemented." << endl;
exit(EXIT_FAILURE);
}
expr_t
VarExpectationNode::substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
return const_cast<VarExpectationNode *>(this);
cerr << "VarExpectationNode::substituteExoLag not implemented." << endl;
exit(EXIT_FAILURE);
}
expr_t
@ -7816,6 +7830,18 @@ VarExpectationNode::substituteAdl() const
return const_cast<VarExpectationNode *>(this);
}
expr_t
VarExpectationNode::substituteVarExpectation(const map<string, expr_t> &subst_table) const
{
auto it = subst_table.find(model_name);
if (it == subst_table.end())
{
cerr << "ERROR: unknown model '" << model_name << "' used in var_expectation expression" << endl;
exit(EXIT_FAILURE);
}
return it->second;
}
void
VarExpectationNode::findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const
{
@ -7848,7 +7874,8 @@ VarExpectationNode::substitutePacExpectation(map<const PacExpectationNode *, con
expr_t
VarExpectationNode::differentiateForwardVars(const vector<string> &subset, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
{
return const_cast<VarExpectationNode *>(this);
cerr << "VarExpectationNode::differentiateForwardVars not implemented." << endl;
exit(EXIT_FAILURE);
}
bool
@ -7860,13 +7887,15 @@ VarExpectationNode::containsPacExpectation() const
bool
VarExpectationNode::containsEndogenous() const
{
return true;
cerr << "VarExpectationNode::containsEndogenous not implemented." << endl;
exit(EXIT_FAILURE);
}
bool
VarExpectationNode::containsExogenous() const
{
return false;
cerr << "VarExpectationNode::containsExogenous not implemented." << endl;
exit(EXIT_FAILURE);
}
bool
@ -7878,7 +7907,8 @@ VarExpectationNode::isNumConstNodeEqualTo(double value) const
expr_t
VarExpectationNode::decreaseLeadsLagsPredeterminedVariables() const
{
return const_cast<VarExpectationNode *>(this);
cerr << "VarExpectationNode::decreaseLeadsLagsPredeterminedVariables not implemented." << endl;
exit(EXIT_FAILURE);
}
bool
@ -7890,31 +7920,37 @@ VarExpectationNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id,
expr_t
VarExpectationNode::replaceTrendVar() const
{
return const_cast<VarExpectationNode *>(this);
cerr << "VarExpectationNode::replaceTrendVar not implemented." << endl;
exit(EXIT_FAILURE);
}
expr_t
VarExpectationNode::detrend(int symb_id, bool log_trend, expr_t trend) const
{
return const_cast<VarExpectationNode *>(this);
cerr << "VarExpectationNode::detrend not implemented." << endl;
exit(EXIT_FAILURE);
}
expr_t
VarExpectationNode::removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const
{
return const_cast<VarExpectationNode *>(this);
cerr << "VarExpectationNode::removeTrendLeadLag not implemented." << endl;
exit(EXIT_FAILURE);
}
bool
VarExpectationNode::isInStaticForm() const
{
return false;
cerr << "VarExpectationNode::isInStaticForm not implemented." << endl;
exit(EXIT_FAILURE);
}
bool
VarExpectationNode::isVarModelReferenced(const string &model_info_name) const
{
return model_name == model_info_name;
/* TODO: should check here whether the var_expectation_model is equal to the
argument; we probably need a VarModelTable class to do that elegantly */
return false;
}
void
@ -7922,13 +7958,6 @@ VarExpectationNode::getEndosAndMaxLags(map<string, int> &model_endos_and_lags) c
{
}
void
VarExpectationNode::setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info)
{
vector<string> vs = var_model_info[model_name].first.get_symbols();
yidx = find(vs.begin(), vs.end(), datatree.symbol_table.getName(symb_id)) - vs.begin();
}
void
VarExpectationNode::walkPacParameters(bool &pac_encountered, pair<int, int> &lhs, set<pair<int, pair<int, int>>> &ec_params_and_vars, set<pair<int, pair<int, int>>> &ar_params_and_vars) const
{
@ -7956,12 +7985,7 @@ VarExpectationNode::writeJsonOutput(ostream &output,
const deriv_node_temp_terms_t &tef_terms,
const bool isdynamic) const
{
output << "var_expectation("
<< "forecast_horizon = " << forecast_horizon
<< ", name = " << datatree.symbol_table.getName(symb_id)
<< ", model_name = " << model_name
<< ", yindex = " << yidx
<< ")";
output << "var_expectation(" << model_name << ')';
}
PacExpectationNode::PacExpectationNode(DataTree &datatree_arg,
@ -8271,6 +8295,12 @@ PacExpectationNode::substituteAdl() const
return const_cast<PacExpectationNode *>(this);
}
expr_t
PacExpectationNode::substituteVarExpectation(const map<string, expr_t> &subst_table) const
{
return const_cast<PacExpectationNode *>(this);
}
void
PacExpectationNode::findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const
{
@ -8371,11 +8401,6 @@ PacExpectationNode::getEndosAndMaxLags(map<string, int> &model_endos_and_lags) c
{
}
void
PacExpectationNode::setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info)
{
}
expr_t
PacExpectationNode::substituteStaticAuxiliaryVariable() const
{

View File

@ -499,6 +499,9 @@ class ExprNode
//! Substitute adl operator
virtual expr_t substituteAdl() const = 0;
//! Substitute VarExpectation nodes
virtual expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const = 0;
//! Substitute diff operator
virtual void findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const = 0;
virtual void findUnaryOpNodesForAuxVarCreation(DataTree &static_datatree, diff_table_t &nodes) const = 0;
@ -520,9 +523,6 @@ class ExprNode
//! Substitute auxiliary variables by their expression in static model
virtual expr_t substituteStaticAuxiliaryVariable() const = 0;
//! Add index information for var_model variables
virtual void setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info) = 0;
//! Returns true if model_info_name is referenced by a VarExpectationNode
virtual bool isVarModelReferenced(const string &model_info_name) const = 0;
@ -600,6 +600,7 @@ public:
expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
expr_t substituteAdl() const override;
expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
void findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const override;
void findUnaryOpNodesForAuxVarCreation(DataTree &static_datatree, diff_table_t &nodes) const override;
expr_t substituteDiff(DataTree &static_datatree, diff_table_t &diff_table, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
@ -617,7 +618,6 @@ public:
expr_t cloneDynamic(DataTree &dynamic_datatree) const override;
expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
bool isInStaticForm() const override;
void setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info) override;
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;
@ -691,6 +691,7 @@ public:
expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
expr_t substituteAdl() const override;
expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
void findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const override;
void findUnaryOpNodesForAuxVarCreation(DataTree &static_datatree, diff_table_t &nodes) const override;
expr_t substituteDiff(DataTree &static_datatree, diff_table_t &diff_table, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
@ -708,7 +709,6 @@ public:
expr_t cloneDynamic(DataTree &dynamic_datatree) const override;
expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
bool isInStaticForm() const override;
void setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info) override;
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;
@ -805,6 +805,7 @@ public:
expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
expr_t substituteAdl() const override;
expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
void findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const override;
bool createAuxVarForUnaryOpNode() const;
void findUnaryOpNodesForAuxVarCreation(DataTree &static_datatree, diff_table_t &nodes) const override;
@ -823,7 +824,6 @@ public:
expr_t cloneDynamic(DataTree &dynamic_datatree) const override;
expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
bool isInStaticForm() const override;
void setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info) override;
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;
@ -937,6 +937,7 @@ public:
expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
expr_t substituteAdl() const override;
expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
void findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const override;
void findUnaryOpNodesForAuxVarCreation(DataTree &static_datatree, diff_table_t &nodes) const override;
expr_t substituteDiff(DataTree &static_datatree, diff_table_t &diff_table, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
@ -960,7 +961,6 @@ public:
//! Returns the non-zero hand-side of an equation (that must have a hand side equal to zero)
expr_t getNonZeroPartofEquation() const;
bool isInStaticForm() const override;
void setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info) override;
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;
@ -1044,6 +1044,7 @@ public:
expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
expr_t substituteAdl() const override;
expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
void findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const override;
void findUnaryOpNodesForAuxVarCreation(DataTree &static_datatree, diff_table_t &nodes) const override;
expr_t substituteDiff(DataTree &static_datatree, diff_table_t &diff_table, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
@ -1061,7 +1062,6 @@ public:
expr_t cloneDynamic(DataTree &dynamic_datatree) const override;
expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
bool isInStaticForm() const override;
void setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info) override;
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;
@ -1155,6 +1155,7 @@ public:
expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
expr_t substituteAdl() const override;
expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
void findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const override;
void findUnaryOpNodesForAuxVarCreation(DataTree &static_datatree, diff_table_t &nodes) const override;
expr_t substituteDiff(DataTree &static_datatree, diff_table_t &diff_table, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
@ -1174,7 +1175,6 @@ public:
expr_t cloneDynamic(DataTree &dynamic_datatree) const override = 0;
expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
bool isInStaticForm() const override;
void setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info) override;
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;
@ -1312,12 +1312,9 @@ public:
class VarExpectationNode : public ExprNode
{
private:
const int symb_id;
const int forecast_horizon;
const string &model_name;
int yidx;
const string model_name;
public:
VarExpectationNode(DataTree &datatree_arg, int symb_id_arg, int forecast_horizon_arg, const string &model_name);
VarExpectationNode(DataTree &datatree_arg, string model_name_arg);
void computeTemporaryTerms(map<expr_t, pair<int, NodeTreeReference>> &reference_count,
map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
bool is_matlab, NodeTreeReference tr) const override;
@ -1353,6 +1350,7 @@ public:
expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
expr_t substituteAdl() const override;
expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
void findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const override;
void findUnaryOpNodesForAuxVarCreation(DataTree &static_datatree, diff_table_t &nodes) const override;
expr_t substituteDiff(DataTree &static_datatree, diff_table_t &diff_table, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
@ -1377,7 +1375,6 @@ public:
expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override;
expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
bool isInStaticForm() const override;
void setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info) override;
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;
@ -1439,6 +1436,7 @@ public:
expr_t substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
expr_t substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const override;
expr_t substituteAdl() const override;
expr_t substituteVarExpectation(const map<string, expr_t> &subst_table) const override;
void findDiffNodes(DataTree &static_datatree, diff_table_t &diff_table) const override;
void findUnaryOpNodesForAuxVarCreation(DataTree &static_datatree, diff_table_t &nodes) const override;
expr_t substituteDiff(DataTree &static_datatree, diff_table_t &diff_table, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override;
@ -1463,7 +1461,6 @@ public:
expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override;
expr_t removeTrendLeadLag(map<int, expr_t> trend_symbols_map) const override;
bool isInStaticForm() const override;
void setVarExpectationIndex(map<string, pair<SymbolList, int>> &var_model_info) override;
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;

View File

@ -444,11 +444,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
}
if (!var_model_info_var_expectation.empty())
{
dynamic_model.setVarExpectationIndices(var_model_info_var_expectation);
dynamic_model.addEquationsForVar(var_model_info_var_expectation);
}
dynamic_model.fillVarExpectationFunctionsToWrite();
dynamic_model.addEquationsForVar(var_model_info_var_expectation);
if (symbol_table.predeterminedNbr() > 0)
dynamic_model.transformPredeterminedVariables();
@ -511,6 +507,69 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const
exit(EXIT_FAILURE);
}
/* Handle var_expectation_model statements: collect information about them,
create the new corresponding parameters, and the expressions to replace
the var_expectation statements.
TODO: move information collection to checkPass(), within a new
VarModelTable class */
map<string, expr_t> var_expectation_subst_table;
for (auto & statement : statements)
{
auto vems = dynamic_cast<VarExpectationModelStatement *>(statement);
if (!vems)
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)
{
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{original_model.getVarMaxLag(diff_static_model, eqnumber)};
/* Create auxiliary parameters and the expression to be substituted to
the var_expectations statement */
auto subst_expr = dynamic_model.Zero;
for (int lag = 1; lag <= max_lag; lag++)
for (auto variable : lhs)
{
string param_name = "var_expectation_model_" + model_name + '_' + symbol_table.getName(variable) + '_' + to_string(lag);
int new_param_id = symbol_table.addSymbol(param_name, SymbolType::parameter);
vems->aux_params_ids.push_back(new_param_id);
subst_expr = dynamic_model.AddPlus(subst_expr,
dynamic_model.AddTimes(dynamic_model.AddVariable(new_param_id),
dynamic_model.AddVariable(variable, -lag)));
}
if (var_expectation_subst_table.find(model_name) != var_expectation_subst_table.end())
{
cerr << "ERROR: model name '" << model_name << "' is used by several var_expectation_model statements" << endl;
exit(EXIT_FAILURE);
}
var_expectation_subst_table[model_name] = subst_expr;
}
// And finally perform the substitutions
dynamic_model.substituteVarExpectation(var_expectation_subst_table);
if (mod_file_struct.stoch_simul_present
|| mod_file_struct.estimation_present
|| mod_file_struct.osr_present
@ -532,6 +591,10 @@ 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 */
for (auto & statement : statements)
{
auto *vms = dynamic_cast<VarModelStatement *>(statement);
@ -997,11 +1060,6 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
auto *lpass = dynamic_cast<LoadParamsAndSteadyStateStatement *>(statement);
if (lpass && !no_static)
static_model.writeAuxVarInitval(mOutputFile, oMatlabOutsideModel);
// Special treatement for Var Models
auto *vms = dynamic_cast<VarModelStatement *>(statement);
if (vms != nullptr)
vms->createVarModelMFunction(mOutputFile, dynamic_model.getVarExpectationFunctionsToWrite());
}
mOutputFile << "save('" << basename << "_results.mat', 'oo_', 'M_', 'options_');" << endl

View File

@ -2508,9 +2508,9 @@ ParsingDriver::add_expectation(const string &arg1, expr_t arg2)
}
expr_t
ParsingDriver::add_var_expectation(const string &arg1, const string &arg2, const string &arg3)
ParsingDriver::add_var_expectation(const string &model_name)
{
return data_tree->AddVarExpectation(mod_file->symbol_table.getID(arg1), stoi(arg2), arg3);
return data_tree->AddVarExpectation(model_name);
}
expr_t
@ -3228,3 +3228,45 @@ ParsingDriver::end_shock_groups(const string &name)
mod_file->addStatement(new ShockGroupsStatement(shock_groups, name));
shock_groups.clear();
}
void
ParsingDriver::var_expectation_model()
{
auto it = options_list.string_options.find("variable");
if (it == options_list.string_options.end())
error("You must pass the variable option to the var_expectation_model statement.");
auto variable = it->second;
check_symbol_is_endogenous(variable);
it = options_list.string_options.find("var_model_name");
if (it == options_list.string_options.end())
error("You must pass the var_model_name option to the var_expectation_model statement.");
auto var_model_name = it->second;
it = options_list.string_options.find("model_name");
if (it == options_list.string_options.end())
error("You must pass the model_name option to the var_expectation_model statement.");
auto model_name = it->second;
it = options_list.num_options.find("horizon");
if (it == options_list.num_options.end())
error("You must pass the horizon option to the var_expectation_model statement.");
auto horizon = it->second;
if (var_expectation_model_discount)
{
VariableNode *var;
if (!dynamic_cast<NumConstNode *>(var_expectation_model_discount)
&& !((var = dynamic_cast<VariableNode *>(var_expectation_model_discount))
&& var->get_type() == SymbolType::parameter))
error("The discount factor must be a constant expression or a parameter");
}
else
var_expectation_model_discount = data_tree->One;
mod_file->addStatement(new VarExpectationModelStatement(model_name, variable, var_model_name, horizon,
var_expectation_model_discount, mod_file->symbol_table));
options_list.clear();
var_expectation_model_discount = nullptr;
}

View File

@ -297,6 +297,9 @@ public:
map<pair<int, int>, double> covariance_number_restriction;
map<pair<int, int>, pair<int, int>> covariance_pair_restriction;
//! Temporary storage for discount option of VAR_EXPECTATION_MODEL
expr_t var_expectation_model_discount{nullptr};
//! Error handler with explicit location
void error(const Dynare::parser::location_type &l, const string &m) __attribute__ ((noreturn));
//! Error handler using saved location
@ -688,8 +691,8 @@ public:
expr_t add_power(expr_t arg1, expr_t arg2);
//! Writes token "E(arg1)(arg2)" to model tree
expr_t add_expectation(const string &arg1, expr_t arg2);
//! Writes token "VAR_EXPECTATION(arg1, arg2, arg3)" to model tree
expr_t add_var_expectation(const string &arg1, const string &arg2, const string &arg3);
//! Writes token "VAR_EXPECTATION(model_name)" to model tree
expr_t add_var_expectation(const string &model_name);
//! Writes token "PAC_EXPECTATION(model_name, discount, growth)" to model tree
expr_t add_pac_expectation(const string &var_model_name);
//! Creates pac_model statement
@ -836,6 +839,8 @@ public:
void gmm_estimation();
//! SMM Estimation statement
void smm_estimation();
//! Add a var_expectation_model statement
void var_expectation_model();
};
#endif // ! PARSING_DRIVER_HH