Commit 77897d69 authored by houtanb's avatar houtanb
Browse files

expectation conditional on a restricted information set

git-svn-id: https://www.dynare.org/svn/dynare/trunk@3367 ac1d8469-bf42-47a9-8791-bf33cf982152
parent 397d5319
......@@ -426,6 +426,12 @@ DataTree::AddExpectation(int iArg1, NodeID iArg2)
return AddUnaryOp(oExpectation, iArg2, iArg1);
}
NodeID
DataTree::AddExpectation(string *iArg1, NodeID iArg2)
{
return AddUnaryOp(oExpectation, iArg2, 0, *iArg1);
}
NodeID
DataTree::AddEqual(NodeID iArg1, NodeID iArg2)
{
......
......@@ -78,7 +78,7 @@ private:
int node_counter;
inline NodeID AddPossiblyNegativeConstant(double val);
inline NodeID AddUnaryOp(UnaryOpcode op_code, NodeID arg, int arg_exp_info_set = 0);
inline NodeID AddUnaryOp(UnaryOpcode op_code, NodeID arg, int arg_exp_info_set = 0, const string &arg_exp_info_set_name="");
inline NodeID AddBinaryOp(NodeID arg1, BinaryOpcode op_code, NodeID arg2);
inline NodeID AddTrinaryOp(NodeID arg1, TrinaryOpcode op_code, NodeID arg2, NodeID arg3);
......@@ -132,6 +132,8 @@ public:
NodeID AddPower(NodeID iArg1, NodeID iArg2);
//! Adds "E(arg1)(arg2)" to model tree
NodeID AddExpectation(int iArg1, NodeID iArg2);
//! Adds "E(arg1)(arg2)" to model tree
NodeID AddExpectation(string *iArg1, NodeID iArg2);
//! Adds "exp(arg)" to model tree
NodeID AddExp(NodeID iArg1);
//! Adds "log(arg)" to model tree
......@@ -220,7 +222,7 @@ DataTree::AddPossiblyNegativeConstant(double v)
}
inline NodeID
DataTree::AddUnaryOp(UnaryOpcode op_code, NodeID arg, int arg_exp_info_set)
DataTree::AddUnaryOp(UnaryOpcode op_code, NodeID arg, int arg_exp_info_set, const string &arg_exp_info_set_name)
{
// If the node already exists in tree, share it
unary_op_node_map_type::iterator it = unary_op_node_map.find(make_pair(arg, op_code));
......@@ -242,7 +244,7 @@ DataTree::AddUnaryOp(UnaryOpcode op_code, NodeID arg, int arg_exp_info_set)
{
}
}
return new UnaryOpNode(*this, op_code, arg, arg_exp_info_set);
return new UnaryOpNode(*this, op_code, arg, arg_exp_info_set, arg_exp_info_set_name);
}
inline NodeID
......
......@@ -2734,6 +2734,9 @@ DynamicModel::substituteLeadLagInternal(aux_var_t type)
case avExpectation:
cout << "expectation";
break;
case avExpectationRIS:
cout << "expectation conditional on a restricted information set";
break;
}
cout << ": added " << neweqs.size() << " auxiliary variables and equations." << endl;
}
......@@ -2765,7 +2768,7 @@ DynamicModel::substituteExpectation(bool partial_information_model)
// Add the new set of equations at the *beginning* of aux_equations
copy(neweqs.rbegin(), neweqs.rend(), front_inserter(aux_equations));
if (neweqs.size() > 0)
if (subst_table.size() > 0)
{
if (partial_information_model)
cout << "Substitution of Expectation operator: added " << subst_table.size() << " auxiliary variables and " << neweqs.size() << " auxiliary equations." << endl;
......
......@@ -117,7 +117,7 @@ class ParsingDriver;
%token PARAMETERS PARAMETER_SET PARTIAL_INFORMATION PERIODS PLANNER_OBJECTIVE PLOT_CONDITIONAL_FORECAST PLOT_PRIORS PREFILTER PRESAMPLE
%token PRINT PRIOR_MC PRIOR_TRUNC PRIOR_ANALYSIS PRIOR_MODE PRIOR_MEAN POSTERIOR_ANALYSIS POSTERIOR_MODE POSTERIOR_MEAN POSTERIOR_MEDIAN
%token <string_val> QUOTED_STRING
%token QZ_CRITERIUM
%token QZ_CRITERIUM FULL
%token RELATIVE_IRF REPLIC RPLOT SAVE_PARAMS_AND_STEADY_STATE
%token SHOCKS SHOCK_DECOMPOSITION SIGMA_E SIMUL SIMUL_ALGO SIMUL_SEED SMOOTHER STACK_SOLVE_ALGO SOLVE_ALGO
%token STDERR STEADY STOCH_SIMUL
......@@ -162,7 +162,7 @@ class ParsingDriver;
%type <node_val> expression expression_or_empty
%type <node_val> equation hand_side model_var
%type <string_val> signed_float signed_integer prior
%type <string_val> filename symbol
%type <string_val> filename symbol expectation_input
%type <string_val> value value1
%type <string_val> vec_value_1 vec_value
%type <string_val> calib_arg2 range number
......@@ -530,7 +530,7 @@ hand_side : '(' hand_side ')'
{ $$ = driver.add_different($1, $3); }
| hand_side POWER hand_side
{ $$ = driver.add_power($1, $3); }
| EXPECTATION '(' signed_integer ')''(' hand_side ')'
| EXPECTATION '(' expectation_input ')''(' hand_side ')'
{ $$ = driver.add_expectation($3, $6); }
| MINUS hand_side %prec UMINUS
{ $$ = driver.add_uminus($2); }
......@@ -570,6 +570,11 @@ hand_side : '(' hand_side ')'
{ $$ = driver.add_steady_state($3); }
;
expectation_input : signed_integer
| VAROBS { string *varobs = new string("varobs"); $$ = varobs; }
| FULL { string *full = new string("full"); $$ = full; }
;
pound_expression: '#' symbol EQUAL hand_side ';'
{ driver.declare_and_init_model_local_variable($2, $4); };
......
......@@ -463,6 +463,8 @@ int sigma_e = 0;
<DYNARE_STATEMENT,DYNARE_BLOCK>normcdf {return token::NORMCDF;}
<DYNARE_STATEMENT,DYNARE_BLOCK>steady_state {return token::STEADY_STATE;}
<DYNARE_STATEMENT,DYNARE_BLOCK>expectation {return token::EXPECTATION;}
<DYNARE_STATEMENT,DYNARE_BLOCK>varobs {return token::VAROBS;}
<DYNARE_STATEMENT,DYNARE_BLOCK>full {return token::FULL;}
<DYNARE_STATEMENT,DYNARE_BLOCK>nan {return token::NAN_CONSTANT;}
<DYNARE_STATEMENT,DYNARE_BLOCK>inf {return token::INF_CONSTANT;}
......
......@@ -976,10 +976,11 @@ VariableNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOpN
return const_cast<VariableNode *>(this);
}
UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const NodeID arg_arg, const int expectation_information_set_arg) :
UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const NodeID arg_arg, const int expectation_information_set_arg, const string &expectation_information_set_name_arg) :
ExprNode(datatree_arg),
arg(arg_arg),
expectation_information_set(expectation_information_set_arg),
expectation_information_set_name(expectation_information_set_name_arg),
op_code(op_code_arg)
{
// Add myself to the unary op map
......@@ -1697,35 +1698,59 @@ UnaryOpNode::substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNo
case oExpectation:
{
subst_table_t::iterator it = subst_table.find(const_cast<UnaryOpNode *>(this));
if (it != subst_table.end())
return const_cast<VariableNode *>(it->second);
//Arriving here, we need to create an auxiliary variable for this Expectation Operator:
int symb_id = datatree.symbol_table.addExpectationAuxiliaryVar(expectation_information_set, arg->idx); //AUXE_period_arg.idx
//AUX_EXPECT_(LEAD/LAG)_(period)_(arg.idx) OR
//AUX_EXPECT_(info_set_name)_(arg.idx)
int symb_id = datatree.symbol_table.addExpectationAuxiliaryVar(expectation_information_set, arg->idx, expectation_information_set_name);
NodeID newAuxE = datatree.AddVariable(symb_id, 0);
if (partial_information_model && expectation_information_set == 0)
{
//Ensure x is a single variable as opposed to an expression
if (dynamic_cast<VariableNode *>(arg) == NULL)
{
cerr << "ERROR: In Partial Information models, EXPECTATION(0)(X) can only be used when X is a single variable." << endl;
cerr << "ERROR: In Partial Information models, EXPECTATION(";
if (expectation_information_set_name.empty())
cerr << 0;
else
cerr << expectation_information_set_name;
cerr << ")(X) can only be used when X is a single variable." << endl;
exit(EXIT_FAILURE);
}
}
if (!expectation_information_set_name.empty())
{
if (!partial_information_model)
{
cerr << "ERROR: EXPECTATION(" << expectation_information_set_name << ")(X) is only valid in models with partial information." << endl;
exit(EXIT_FAILURE);
}
if (expectation_information_set != 0)
{
cerr << "ERROR: UnaryOpNode::substituteExpectation() should not arrive here. Please inform Dynare Team." << endl;
exit(EXIT_FAILURE);
}
else if (dynamic_cast<VariableNode *>(arg)->get_lag()!=0)
{
cerr << "ERROR: EXPECTATION(" << expectation_information_set_name << ")(X) requres that X be from the current period." << endl;
exit(EXIT_FAILURE);
}
//Will not have nested Expectation operators of this type since we require that X be a single endogenous variable.
//Hence, the newAuxE with lag = 0 is all we need here.
}
else
{
//take care of any nested expectation operators by calling arg->substituteExpectation(.), then decreaseLeadsLags for this oExpectation operator
//arg(lag-period) (holds entire subtree of arg(lag-period)
NodeID substexpr = (arg->substituteExpectation(subst_table, neweqs, partial_information_model))->decreaseLeadsLags(expectation_information_set);
assert(substexpr != NULL);
neweqs.push_back(dynamic_cast<BinaryOpNode *>(datatree.AddEqual(newAuxE, substexpr))); //AUXE_period_arg.idx = arg(lag-period)
newAuxE = datatree.AddVariable(symb_id, expectation_information_set);
}
assert(dynamic_cast<VariableNode *>(newAuxE) != NULL);
subst_table[this] = dynamic_cast<VariableNode *>(newAuxE);
return newAuxE;
......
......@@ -387,6 +387,7 @@ public:
{
return symb_id;
};
int get_lag() const { return lag; };
virtual pair<int, NodeID> normalizeEquation(int symb_id_endo, vector<pair<int, pair<NodeID, NodeID> > > &List_of_Op_RHS) const;
virtual NodeID getChainRuleDerivative(int deriv_id, const map<int, NodeID> &recursive_variables);
virtual int maxEndoLead() const;
......@@ -407,13 +408,15 @@ private:
const NodeID arg;
//! Stores the information set. Only used for expectation operator
const int expectation_information_set;
//! Stores the information set name. Only used for expectation operator
const string expectation_information_set_name;
const UnaryOpcode op_code;
virtual NodeID computeDerivative(int deriv_id);
virtual int cost(const temporary_terms_type &temporary_terms, bool is_matlab) const;
//! Returns the derivative of this node if darg is the derivative of the argument
NodeID composeDerivatives(NodeID darg);
public:
UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const NodeID arg_arg, const int expectation_information_set_arg);
UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const NodeID arg_arg, const int expectation_information_set_arg, const string &expectation_information_set_name_arg);
virtual void prepareForDerivation();
virtual void computeTemporaryTerms(map<NodeID, int> &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
......
......@@ -1465,7 +1465,18 @@ ParsingDriver::add_power(NodeID arg1, NodeID arg2)
NodeID
ParsingDriver::add_expectation(string *arg1, NodeID arg2)
{
NodeID expectationNode = data_tree->AddExpectation(atoi(arg1->c_str()), arg2);
NodeID expectationNode;
if ("varobs"==*arg1 || "full"==*arg1)
if (dynamic_cast<VariableNode *>(arg2) == NULL)
error("EXPECTATION(" + *arg1 + ")(X) can only be used when X is a single variable.");
else
if (mod_file->symbol_table.getType(dynamic_cast<VariableNode *>(arg2)->get_symb_id()) != eEndogenous)
error(mod_file->symbol_table.getName(dynamic_cast<VariableNode *>(arg2)->get_symb_id()) + " is not endogenous.");
else
expectationNode = data_tree->AddExpectation(arg1, arg2);
else
expectationNode = data_tree->AddExpectation(atoi(arg1->c_str()), arg2);
delete arg1;
return expectationNode;
}
......
......@@ -24,6 +24,15 @@
#include "SymbolTable.hh"
AuxVarInfo::AuxVarInfo(int symb_id_arg, aux_var_t type_arg, int orig_symb_id_arg, int orig_lead_lag_arg, string expectation_information_set_name_arg) :
symb_id(symb_id_arg),
type(type_arg),
orig_symb_id(orig_symb_id_arg),
orig_lead_lag(orig_lead_lag_arg),
expectation_information_set_name(expectation_information_set_name_arg)
{
}
SymbolTable::SymbolTable() : frozen(false), size(0)
{
}
......@@ -209,18 +218,21 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
else
for (int i = 0; i < (int) aux_vars.size(); i++)
{
output << "M_.aux_vars(" << i+1 << ").endo_index = " << getTypeSpecificID(aux_vars[i].symb_id)+1 << ";" << endl
<< "M_.aux_vars(" << i+1 << ").type = " << aux_vars[i].type << ";" << endl;
switch (aux_vars[i].type)
output << "M_.aux_vars(" << i+1 << ").endo_index = " << getTypeSpecificID(aux_vars[i].get_symb_id())+1 << ";" << endl
<< "M_.aux_vars(" << i+1 << ").type = " << aux_vars[i].get_type() << ";" << endl;
switch (aux_vars[i].get_type())
{
case avEndoLead:
case avExoLead:
case avExpectation:
break;
case avExpectationRIS:
output << "M_.aux_vars(" << i+1 << ").expectation_information_set_name = '" << aux_vars[i].get_expectation_information_set_name() << "';" << endl;
break;
case avEndoLag:
case avExoLag:
output << "M_.aux_vars(" << i+1 << ").orig_index = " << getTypeSpecificID(aux_vars[i].orig_symb_id)+1 << ";" << endl
<< "M_.aux_vars(" << i+1 << ").orig_lead_lag = " << aux_vars[i].orig_lead_lag << ";" << endl;
output << "M_.aux_vars(" << i+1 << ").orig_index = " << getTypeSpecificID(aux_vars[i].get_orig_symb_id())+1 << ";" << endl
<< "M_.aux_vars(" << i+1 << ").orig_lead_lag = " << aux_vars[i].get_orig_lead_lag() << ";" << endl;
break;
}
}
......@@ -255,10 +267,7 @@ SymbolTable::addLeadAuxiliaryVarInternal(bool endo, int index) throw (FrozenExce
exit(EXIT_FAILURE);
}
AuxVarInfo avi;
avi.symb_id = symb_id;
avi.type = (endo ? avEndoLead : avExoLead);
aux_vars.push_back(avi);
aux_vars.push_back(AuxVarInfo(symb_id, (endo ? avEndoLead : avExoLead), 0, 0, ""));
return symb_id;
}
......@@ -284,12 +293,7 @@ SymbolTable::addLagAuxiliaryVarInternal(bool endo, int orig_symb_id, int orig_le
exit(EXIT_FAILURE);
}
AuxVarInfo avi;
avi.symb_id = symb_id;
avi.type = (endo ? avEndoLag : avExoLag);
avi.orig_symb_id = orig_symb_id;
avi.orig_lead_lag = orig_lead_lag;
aux_vars.push_back(avi);
aux_vars.push_back(AuxVarInfo(symb_id, (endo ? avEndoLag : avExoLag), orig_symb_id, orig_lead_lag, ""));
return symb_id;
}
......@@ -319,12 +323,17 @@ SymbolTable::addExoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag) throw (F
}
int
SymbolTable::addExpectationAuxiliaryVar(int information_set, int index) throw (FrozenException)
SymbolTable::addExpectationAuxiliaryVar(int information_set, int index, const string &information_set_name) throw (FrozenException)
{
ostringstream varname;
varname << "AUX_EXPECT_" << (information_set < 0 ? "LAG" : "LEAD") << "_"
<< abs(information_set) << "_" << index;
int symb_id;
if (information_set_name.empty())
varname << "AUX_EXPECT_" << (information_set < 0 ? "LAG" : "LEAD") << "_"
<< abs(information_set) << "_" << index;
else
varname << "AUX_EXPECT_" << information_set_name << "_" << index;
try
{
symb_id = addSymbol(varname.str(), eEndogenous);
......@@ -335,10 +344,7 @@ SymbolTable::addExpectationAuxiliaryVar(int information_set, int index) throw (F
exit(EXIT_FAILURE);
}
AuxVarInfo avi;
avi.symb_id = symb_id;
avi.type = avExpectation;
aux_vars.push_back(avi);
aux_vars.push_back(AuxVarInfo(symb_id, (information_set_name.empty() ? avExpectation : avExpectationRIS), 0, 0, information_set_name));
return symb_id;
}
......
......@@ -33,20 +33,30 @@ using namespace std;
//! Types of auxiliary variables
enum aux_var_t
{
avEndoLead = 0, //!< Substitute for endo leads >= 2
avEndoLag = 1, //!< Substitute for endo lags >= 2
avExoLead = 2, //!< Substitute for exo leads >= 2
avExoLag = 3, //!< Substitute for exo lags >= 2
avExpectation = 4 //!< Substitute for Expectation Operator
avEndoLead = 0, //!< Substitute for endo leads >= 2
avEndoLag = 1, //!< Substitute for endo lags >= 2
avExoLead = 2, //!< Substitute for exo leads >= 2
avExoLag = 3, //!< Substitute for exo lags >= 2
avExpectation = 4, //!< Substitute for Expectation Operator
avExpectationRIS = 5 //!< Substitute for Expectation Operator Conditional on Restricted Information Set
};
//! Information on some auxiliary variables
struct AuxVarInfo
class AuxVarInfo
{
private:
int symb_id; //!< Symbol ID of the auxiliary variable
aux_var_t type; //!< Its type
int orig_symb_id; //!< Symbol ID of the endo of the original model represented by this aux var. Not used for avEndoLead
int orig_lead_lag; //!< Lead/lag of the endo of the original model represented by this aux var. Not used for avEndoLead
string expectation_information_set_name; //!< Stores 'full' or 'varobs' for avExpectationRIS. Not used otherwise.
public:
AuxVarInfo(int symb_id_arg, aux_var_t type_arg, int orig_symb_id, int orig_lead_lag, string expectation_information_set_name_arg);
int get_symb_id() const { return symb_id; };
aux_var_t get_type() const { return type; };
int get_orig_symb_id() const { return orig_symb_id; };
int get_orig_lead_lag() const { return orig_lead_lag; };
string get_expectation_information_set_name() const { return expectation_information_set_name; };
};
//! Stores the symbol table
......@@ -190,7 +200,7 @@ public:
\param[in] index Used to construct the variable name
\return the symbol ID of the new symbol
*/
int addExpectationAuxiliaryVar(int information_set, int index) throw (FrozenException);
int addExpectationAuxiliaryVar(int information_set, int index, const string &information_set_name) throw (FrozenException);
//! Tests if symbol already exists
inline bool exists(const string &name) const;
//! Get symbol name (by ID)
......
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