Commit da74e532 authored by Sébastien Villemot's avatar Sébastien Villemot
Browse files

Preprocessor:

* give the possibility of calibrating measurement errors in the "shocks" blocks (only for observed endogenous variables)
* M_.H is now initialized in the preprocessor
* only one "varobs" statement is now accepted in a MOD file
parent 0281c513
......@@ -1453,7 +1453,10 @@ end;
<refsect2><title>In stochastic context</title>
<para>
For stochastic simulations, the <command>shocks</command> block specifies the non zero elements of the covariance matrix of the shocks.
For stochastic simulations, the <command>shocks</command> block specifies the non zero elements of the covariance matrix of the shocks of exogenous variables.
</para>
<para>
In an estimation context, it is also possible to specify variances and covariances on endogenous variables: in that case, these values are interpreted as the calibration of the measurement errors on these variables.
</para>
<refsect3><title>Example</title>
......@@ -2261,16 +2264,29 @@ stoch_simul(linear,irf=60) y k;
<command>varobs</command> lists the name of observed endogenous variables for the estimation procedure. These variables must be available in the data file (see <xref linkend='estimation'/>).
</para>
<para>
Successive instances of <command>varobs</command> overwrite the list of observed variables. They don't add to the list.
Only one instance of <command>varobs</command> is allowed in a model file. If one needs to declare observed variables in a loop, the macroprocessor can be used as shown in the second example below.
</para>
</refsect1>
<refsect1><title>Example</title>
<informalexample>
<programlisting>
<refsect1><title>Examples</title>
<refsect2><title>Simple example</title>
<informalexample>
<programlisting>
varobs C y rr;
</programlisting>
</informalexample>
</programlisting>
</informalexample>
</refsect2>
<refsect2><title>In a loop</title>
<informalexample>
<programlisting>
varobs
@#for co in countries
GDP_@{co}
@#endfor
;
</programlisting>
</informalexample>
</refsect2>
</refsect1>
</refentry>
......
......@@ -215,9 +215,6 @@ oo_.exo_det_simul = [];
M_.params = [];
% Variance matrix for measurement errors
M_.H = 0;
% BVAR
M_.bvar = [];
......
/*
* Copyright (C) 2003-2009 Dynare Team
* Copyright (C) 2003-2010 Dynare Team
*
* This file is part of Dynare.
*
......@@ -303,17 +303,6 @@ DsampleStatement::writeOutput(ostream &output, const string &basename) const
output << "dsample(" << val1 << ", " << val2 << ");" << endl;
}
VarobsStatement::VarobsStatement(const SymbolList &symbol_list_arg) :
symbol_list(symbol_list_arg)
{
}
void
VarobsStatement::writeOutput(ostream &output, const string &basename) const
{
symbol_list.writeOutput("options_.varobs", output);
}
EstimatedParamsStatement::EstimatedParamsStatement(const vector<EstimationParams> &estim_params_list_arg,
const SymbolTable &symbol_table_arg) :
estim_params_list(estim_params_list_arg),
......@@ -329,8 +318,7 @@ EstimatedParamsStatement::writeOutput(ostream &output, const string &basename) c
<< "estim_params_.var_endo = [];" << endl
<< "estim_params_.corrx = [];" << endl
<< "estim_params_.corrn = [];" << endl
<< "estim_params_.param_vals = [];" << endl
<< "M_.H = 0;" << endl;
<< "estim_params_.param_vals = [];" << endl;
vector<EstimationParams>::const_iterator it;
......
/*
* Copyright (C) 2003-2009 Dynare Team
* Copyright (C) 2003-2010 Dynare Team
*
* This file is part of Dynare.
*
......@@ -164,15 +164,6 @@ public:
virtual void writeOutput(ostream &output, const string &basename) const;
};
class VarobsStatement : public Statement
{
private:
const SymbolList symbol_list;
public:
VarobsStatement(const SymbolList &symbol_list_arg);
virtual void writeOutput(ostream &output, const string &basename) const;
};
class ObservationTrendsStatement : public Statement
{
public:
......
......@@ -1159,7 +1159,15 @@ optim_options : list_optim_option
| optim_options COMMA list_optim_option;
;
varobs : VAROBS symbol_list ';' { driver.set_varobs(); };
varobs : VAROBS { driver.check_varobs(); } varobs_list ';';
varobs_list : varobs_list symbol
{ driver.add_varobs($2); }
| varobs_list COMMA symbol
{ driver.add_varobs($3); }
| symbol
{ driver.add_varobs($1); }
;
observation_trends : OBSERVATION_TRENDS ';' trend_list END { driver.set_trends(); };
......
......@@ -286,6 +286,17 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all
symbol_table.writeOutput(mOutputFile);
// Initialize M_.Sigma_e and M_.H
mOutputFile << "M_.Sigma_e = zeros(" << symbol_table.exo_nbr() << ", "
<< symbol_table.exo_nbr() << ");" << endl;
if (mod_file_struct.calibrated_measurement_errors)
mOutputFile << "M_.H = zeros(" << symbol_table.observedVariablesNbr() << ", "
<< symbol_table.observedVariablesNbr() << ");" << endl;
else
mOutputFile << "M_.H = 0;" << endl;
if (linear == 1)
mOutputFile << "options_.linear = 1;" << endl;
......
......@@ -470,7 +470,8 @@ void
ParsingDriver::add_det_shock(string *var, bool conditional_forecast)
{
check_symbol_existence(*var);
SymbolType type = mod_file->symbol_table.getType(*var);
int symb_id = mod_file->symbol_table.getID(*var);
SymbolType type = mod_file->symbol_table.getType(symb_id);
if (conditional_forecast)
{
......@@ -483,7 +484,7 @@ ParsingDriver::add_det_shock(string *var, bool conditional_forecast)
error("shocks: shocks can only be applied to exogenous variables");
}
if (det_shocks.find(*var) != det_shocks.end())
if (det_shocks.find(symb_id) != det_shocks.end())
error("shocks/conditional_forecast_paths: variable " + *var + " declared twice");
if (det_shocks_periods.size() != det_shocks_values.size())
......@@ -500,7 +501,7 @@ ParsingDriver::add_det_shock(string *var, bool conditional_forecast)
v.push_back(dse);
}
det_shocks[*var] = v;
det_shocks[symb_id] = v;
det_shocks_periods.clear();
det_shocks_values.clear();
......@@ -511,11 +512,17 @@ void
ParsingDriver::add_stderr_shock(string *var, NodeID value)
{
check_symbol_existence(*var);
if (var_shocks.find(*var) != var_shocks.end()
|| std_shocks.find(*var) != std_shocks.end())
int symb_id = mod_file->symbol_table.getID(*var);
SymbolType type = mod_file->symbol_table.getType(symb_id);
if (type != eExogenous && !mod_file->symbol_table.isObservedVariable(symb_id))
error("shocks: standard error can only be specified for exogenous or observed endogenous variables");
if (var_shocks.find(symb_id) != var_shocks.end()
|| std_shocks.find(symb_id) != std_shocks.end())
error("shocks: variance or stderr of shock on " + *var + " declared twice");
std_shocks[*var] = value;
std_shocks[symb_id] = value;
delete var;
}
......@@ -524,11 +531,17 @@ void
ParsingDriver::add_var_shock(string *var, NodeID value)
{
check_symbol_existence(*var);
if (var_shocks.find(*var) != var_shocks.end()
|| std_shocks.find(*var) != std_shocks.end())
int symb_id = mod_file->symbol_table.getID(*var);
SymbolType type = mod_file->symbol_table.getType(symb_id);
if (type != eExogenous && !mod_file->symbol_table.isObservedVariable(symb_id))
error("shocks: variance can only be specified for exogenous or observed endogenous variables");
if (var_shocks.find(symb_id) != var_shocks.end()
|| std_shocks.find(symb_id) != std_shocks.end())
error("shocks: variance or stderr of shock on " + *var + " declared twice");
var_shocks[*var] = value;
var_shocks[symb_id] = value;
delete var;
}
......@@ -538,8 +551,16 @@ ParsingDriver::add_covar_shock(string *var1, string *var2, NodeID value)
{
check_symbol_existence(*var1);
check_symbol_existence(*var2);
int symb_id1 = mod_file->symbol_table.getID(*var1);
int symb_id2 = mod_file->symbol_table.getID(*var2);
pair<string, string> key(*var1, *var2), key_inv(*var2, *var1);
SymbolType type1 = mod_file->symbol_table.getType(symb_id1);
SymbolType type2 = mod_file->symbol_table.getType(symb_id2);
if (!((type1 == eExogenous && type2 == eExogenous)
|| (mod_file->symbol_table.isObservedVariable(symb_id1) && mod_file->symbol_table.isObservedVariable(symb_id2))))
error("shocks: covariance can only be specified for exogenous or observed endogenous variables of same type");
pair<int, int> key(symb_id1, symb_id2), key_inv(symb_id2, symb_id1);
if (covar_shocks.find(key) != covar_shocks.end()
|| covar_shocks.find(key_inv) != covar_shocks.end()
......@@ -559,8 +580,16 @@ ParsingDriver::add_correl_shock(string *var1, string *var2, NodeID value)
{
check_symbol_existence(*var1);
check_symbol_existence(*var2);
int symb_id1 = mod_file->symbol_table.getID(*var1);
int symb_id2 = mod_file->symbol_table.getID(*var2);
SymbolType type1 = mod_file->symbol_table.getType(symb_id1);
SymbolType type2 = mod_file->symbol_table.getType(symb_id2);
if (!((type1 == eExogenous && type2 == eExogenous)
|| (mod_file->symbol_table.isObservedVariable(symb_id1) && mod_file->symbol_table.isObservedVariable(symb_id2))))
error("shocks: correlation can only be specified for exogenous or observed endogenous variables of same type");
pair<string, string> key(*var1, *var2), key_inv(*var2, *var1);
pair<int, int> key(symb_id1, symb_id2), key_inv(symb_id2, symb_id1);
if (covar_shocks.find(key) != covar_shocks.end()
|| covar_shocks.find(key_inv) != covar_shocks.end()
......@@ -933,10 +962,21 @@ ParsingDriver::optim_options_num(string *name, string *value)
}
void
ParsingDriver::set_varobs()
ParsingDriver::check_varobs()
{
mod_file->addStatement(new VarobsStatement(symbol_list));
symbol_list.clear();
if (mod_file->symbol_table.observedVariablesNbr() > 0)
error("varobs: you cannot have several 'varobs' statements in the same MOD file");
}
void
ParsingDriver::add_varobs(string *name)
{
check_symbol_existence(*name);
int symb_id = mod_file->symbol_table.getID(*name);
if (mod_file->symbol_table.getType(symb_id) != eEndogenous)
error("varobs: " + *name + " is not an endogenous variable");
mod_file->symbol_table.addObservedVariable(symb_id);
delete name;
}
void
......
......@@ -337,8 +337,10 @@ public:
void optim_options_string(string *name, string *value);
//! Adds an optimization option (numeric value)
void optim_options_num(string *name, string *value);
//! Prints varops instructions
void set_varobs();
//! Check that no observed variable has yet be defined
void check_varobs();
//! Add a new observed variable
void add_varobs(string *name);
//! Svar_Identification Statement
void end_svar_identification();
//! Svar_Identification Statement: match list of restrictions and equation number with lag
......
/*
* Copyright (C) 2003-2009 Dynare Team
* Copyright (C) 2003-2010 Dynare Team
*
* This file is part of Dynare.
*
......@@ -74,12 +74,6 @@ AbstractShocksStatement::writeDetShocks(ostream &output) const
output << "M_.exo_det_length = " << exo_det_length << ";\n";
}
void
AbstractShocksStatement::checkPass(ModFileStructure &mod_file_struct)
{
mod_file_struct.shocks_present = true;
}
ShocksStatement::ShocksStatement(const det_shocks_type &det_shocks_arg,
const var_and_std_shocks_type &var_shocks_arg,
const var_and_std_shocks_type &std_shocks_arg,
......@@ -113,28 +107,77 @@ ShocksStatement::writeOutput(ostream &output, const string &basename) const
output << "M_.sigma_e_is_diagonal = 1;" << endl;
}
void
ShocksStatement::writeVarOrStdShock(ostream &output, var_and_std_shocks_type::const_iterator &it,
bool stderr) const
{
SymbolType type = symbol_table.getType(it->first);
assert(type == eExogenous || symbol_table.isObservedVariable(it->first));
int id;
if (type == eExogenous)
{
output << "M_.Sigma_e(";
id = symbol_table.getTypeSpecificID(it->first) + 1;
}
else
{
output << "M_.H(";
id = symbol_table.getObservedVariableIndex(it->first) + 1;
}
output << id << ", " << id << ") = ";
if (stderr)
output << "(";
it->second->writeOutput(output);
if (stderr)
output << ")^2";
output << ";" << endl;
}
void
ShocksStatement::writeVarAndStdShocks(ostream &output) const
{
var_and_std_shocks_type::const_iterator it;
for (it = var_shocks.begin(); it != var_shocks.end(); it++)
{
int id = symbol_table.getTypeSpecificID(it->first) + 1;
const NodeID value = it->second;
output << "M_.Sigma_e(" << id << ", " << id << ") = ";
value->writeOutput(output);
output << ";" << endl;
}
writeVarOrStdShock(output, it, false);
for (it = std_shocks.begin(); it != std_shocks.end(); it++)
writeVarOrStdShock(output, it, true);
}
void
ShocksStatement::writeCovarOrCorrShock(ostream &output, covar_and_corr_shocks_type::const_iterator &it,
bool corr) const
{
SymbolType type1 = symbol_table.getType(it->first.first);
SymbolType type2 = symbol_table.getType(it->first.second);
assert((type1 == eExogenous && type2 == eExogenous)
|| (symbol_table.isObservedVariable(it->first.first) && symbol_table.isObservedVariable(it->first.second)));
string matrix;
int id1, id2;
if (type1 == eExogenous)
{
int id = symbol_table.getTypeSpecificID(it->first) + 1;
const NodeID value = it->second;
output << "M_.Sigma_e(" << id << ", " << id << ") = (";
value->writeOutput(output);
output << ")^2;" << endl;
matrix = "M_.Sigma_e";
id1 = symbol_table.getTypeSpecificID(it->first.first) + 1;
id2 = symbol_table.getTypeSpecificID(it->first.second) + 1;
}
else
{
matrix = "M_.H";
id1 = symbol_table.getObservedVariableIndex(it->first.first) + 1;
id2 = symbol_table.getObservedVariableIndex(it->first.second) + 1;
}
output << matrix << "(" << id1 << ", " << id2 << ") = ";
it->second->writeOutput(output);
if (corr)
output << "*sqrt(" << matrix << "(" << id1 << ", " << id1 << ")*"
<< matrix << "(" << id2 << ", " << id2 << "))";
output << ";" << endl
<< matrix << "(" << id2 << ", " << id1 << ") = "
<< matrix << "(" << id1 << ", " << id2 << ");" << endl;
}
void
......@@ -143,27 +186,40 @@ ShocksStatement::writeCovarAndCorrShocks(ostream &output) const
covar_and_corr_shocks_type::const_iterator it;
for (it = covar_shocks.begin(); it != covar_shocks.end(); it++)
{
int id1 = symbol_table.getTypeSpecificID(it->first.first) + 1;
int id2 = symbol_table.getTypeSpecificID(it->first.second) + 1;
const NodeID value = it->second;
output << "M_.Sigma_e(" << id1 << ", " << id2 << ") = ";
value->writeOutput(output);
output << "; M_.Sigma_e(" << id2 << ", " << id1 << ") = M_.Sigma_e("
<< id1 << ", " << id2 << ");\n";
}
writeCovarOrCorrShock(output, it, false);
for (it = corr_shocks.begin(); it != corr_shocks.end(); it++)
{
int id1 = symbol_table.getTypeSpecificID(it->first.first) + 1;
int id2 = symbol_table.getTypeSpecificID(it->first.second) + 1;
const NodeID value = it->second;
output << "M_.Sigma_e(" << id1 << ", " << id2 << ") = ";
value->writeOutput(output);
output << "*sqrt(M_.Sigma_e(" << id1 << ", " << id1 << ")*M_.Sigma_e("
<< id2 << ", " << id2 << ")); M_.Sigma_e(" << id2 << ", "
<< id1 << ") = M_.Sigma_e(" << id1 << ", " << id2 << ");\n";
}
writeCovarOrCorrShock(output, it, true);
}
void
ShocksStatement::checkPass(ModFileStructure &mod_file_struct)
{
// Workaround for trac ticket #35
mod_file_struct.shocks_present = true;
// Determine if there is a calibrated measurement error
for (var_and_std_shocks_type::const_iterator it = var_shocks.begin();
it != var_shocks.end(); it++)
if (symbol_table.isObservedVariable(it->first))
mod_file_struct.calibrated_measurement_errors = true;
for (var_and_std_shocks_type::const_iterator it = std_shocks.begin();
it != std_shocks.end(); it++)
if (symbol_table.isObservedVariable(it->first))
mod_file_struct.calibrated_measurement_errors = true;
for (covar_and_corr_shocks_type::const_iterator it = covar_shocks.begin();
it != covar_shocks.end(); it++)
if (symbol_table.isObservedVariable(it->first.first)
|| symbol_table.isObservedVariable(it->first.second))
mod_file_struct.calibrated_measurement_errors = true;
for (covar_and_corr_shocks_type::const_iterator it = corr_shocks.begin();
it != corr_shocks.end(); it++)
if (symbol_table.isObservedVariable(it->first.first)
|| symbol_table.isObservedVariable(it->first.second))
mod_file_struct.calibrated_measurement_errors = true;
}
MShocksStatement::MShocksStatement(const det_shocks_type &det_shocks_arg,
......@@ -185,6 +241,13 @@ MShocksStatement::writeOutput(ostream &output, const string &basename) const
writeDetShocks(output);
}
void
MShocksStatement::checkPass(ModFileStructure &mod_file_struct)
{
// Workaround for trac ticket #35
mod_file_struct.shocks_present = true;
}
ConditionalForecastPathsStatement::ConditionalForecastPathsStatement(const AbstractShocksStatement::det_shocks_type &paths_arg, const SymbolTable &symbol_table_arg) :
paths(paths_arg),
symbol_table(symbol_table_arg),
......
/*
* Copyright (C) 2003-2008 Dynare Team
* Copyright (C) 2003-2010 Dynare Team
*
* This file is part of Dynare.
*
......@@ -39,9 +39,7 @@ public:
int period2;
NodeID value;
};
typedef map<string, vector<DetShockElement> > det_shocks_type;
//! Workaround for trac ticket #35
virtual void checkPass(ModFileStructure &mod_file_struct);
typedef map<int, vector<DetShockElement> > det_shocks_type;
protected:
//! Is this statement a "mshocks" statement ? (instead of a "shocks" statement)
const bool mshocks;
......@@ -57,12 +55,14 @@ protected:
class ShocksStatement : public AbstractShocksStatement
{
public:
typedef map<string, NodeID> var_and_std_shocks_type;
typedef map<pair<string, string>, NodeID> covar_and_corr_shocks_type;
typedef map<int, NodeID> var_and_std_shocks_type;
typedef map<pair<int, int>, NodeID> covar_and_corr_shocks_type;
private:
const var_and_std_shocks_type var_shocks, std_shocks;
const covar_and_corr_shocks_type covar_shocks, corr_shocks;
void writeVarOrStdShock(ostream &output, var_and_std_shocks_type::const_iterator &it, bool stderr) const;
void writeVarAndStdShocks(ostream &output) const;
void writeCovarOrCorrShock(ostream &output, covar_and_corr_shocks_type::const_iterator &it, bool corr) const;
void writeCovarAndCorrShocks(ostream &output) const;
public:
ShocksStatement(const det_shocks_type &det_shocks_arg,
......@@ -72,6 +72,7 @@ public:
const covar_and_corr_shocks_type &corr_shocks_arg,
const SymbolTable &symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename) const;
virtual void checkPass(ModFileStructure &mod_file_struct);
};
class MShocksStatement : public AbstractShocksStatement
......@@ -80,6 +81,7 @@ public:
MShocksStatement(const det_shocks_type &det_shocks_arg,
const SymbolTable &symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename) const;
virtual void checkPass(ModFileStructure &mod_file_struct);
};
class ConditionalForecastPathsStatement : public Statement
......
/*
* Copyright (C) 2006-2009 Dynare Team
* Copyright (C) 2006-2010 Dynare Team
*
* This file is part of Dynare.
*
......@@ -33,7 +33,8 @@ ModFileStructure::ModFileStructure() :
identification_present(false),
partial_information(false),
shocks_present(false),
k_order_solver(false)
k_order_solver(false),
calibrated_measurement_errors(false)
{
}
......
/*
* Copyright (C) 2006-2009 Dynare Team
* Copyright (C) 2006-2010 Dynare Team
*
* This file is part of Dynare.
*
......@@ -63,6 +63,8 @@ public:
bool shocks_present;
//! Whether the "k_order_solver" option is used (explictly, or implicitly if order >= 3)
bool k_order_solver;
//! Whether there is a calibrated measurement error
bool calibrated_measurement_errors;
};
class Statement
......
/*
* Copyright (C) 2003-2009 Dynare Team
* Copyright (C) 2003-2010 Dynare Team
*
* This file is part of Dynare.
*
......@@ -209,8 +209,6 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
<< "M_.endo_nbr = " << endo_nbr() << ";" << endl
<< "M_.param_nbr = " << param_nbr() << ";" << endl;
output << "M_.Sigma_e = zeros(" << exo_nbr() << ", " << exo_nbr() << ");" << endl;
// Write the auxiliary variable table
output << "M_.orig_endo_nbr = " << endo_nbr() - aux_vars.size() << ";" << endl;
if (aux_vars.size() == 0)
......@@ -245,6 +243,14 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
output << getTypeSpecificID(*it)+1 << " ";
output << "];" << endl;
}
if (observedVariablesNbr() > 0)
{
output << "options_.varobs = [];" << endl;
for (vector<int>::const_iterator it = varobs.begin();
it != varobs.end(); it++)
output << "options_.varobs = strvcat(options_.varobs, '" << getName(*it) << "');" << endl;
}
}
int
......@@ -376,3 +382,33 @@ SymbolTable::predeterminedNbr() const
{
return (predetermined_variables.size());
}
void
SymbolTable::addObservedVariable(int symb_id) throw (UnknownSymbolIDException)
{
if (symb_id < 0 || symb_id >= size)
throw UnknownSymbolIDException(symb_id);
assert(getType(symb_id) == eEndogenous);
varobs.push_back(symb_id);
}
int
SymbolTable::observedVariablesNbr() const
{
return (int) varobs.size();
}
bool
SymbolTable::isObservedVariable(int symb_id) const