ms-sbvar: introduced more general restriction syntax for

identification; added an example; still necessary to add error message
when restrictions are invalid
issue#70
Michel Juillard 2011-10-10 11:45:55 +02:00
parent 9ddeba3c13
commit 4befcde035
6 changed files with 233 additions and 54 deletions

View File

@ -1162,12 +1162,12 @@ PlotConditionalForecastStatement::writeOutput(ostream &output, const string &bas
output << "plot_icforecast(var_list_, " << periods << ");" << endl;
}
SvarIdentificationStatement::SvarIdentificationStatement(const svar_identification_exclusion_t &exclusion_arg,
SvarIdentificationStatement::SvarIdentificationStatement(const svar_identification_restrictions_t &restrictions_arg,
const bool &upper_cholesky_present_arg,
const bool &lower_cholesky_present_arg,
const bool &constants_exclusion_present_arg,
const SymbolTable &symbol_table_arg) :
exclusion(exclusion_arg),
restrictions(restrictions_arg),
upper_cholesky_present(upper_cholesky_present_arg),
lower_cholesky_present(lower_cholesky_present_arg),
constants_exclusion_present(constants_exclusion_present_arg),
@ -1179,9 +1179,9 @@ int
SvarIdentificationStatement::getMaxLag() const
{
int max_lag = 0;
for (svar_identification_exclusion_t::const_iterator it = exclusion.begin(); it != exclusion.end(); it++)
if (it->first.first > max_lag)
max_lag = it->first.first;
for (svar_identification_restrictions_t::const_iterator it = restrictions.begin(); it != restrictions.end(); it++)
if (it->lag > max_lag)
max_lag = it->lag;
return max_lag;
}
@ -1252,45 +1252,69 @@ SvarIdentificationStatement::writeOutput(ostream &output, const string &basename
output << "options_.ms.Qi = cell(" << n << ",1);" << endl;
output << "options_.ms.Ri = cell(" << n << ",1);" << endl;
vector<int> rows(n);
fill(rows.begin(),rows.end(),1);
// vector<int> rows(n);
// fill(rows.begin(),rows.end(),1);
for (svar_identification_exclusion_t::const_iterator it = exclusion.begin(); it != exclusion.end(); it++)
for (svar_identification_restrictions_t::const_iterator it = restrictions.begin(); it != restrictions.end(); it++)
{
for (unsigned int h = 0; h < it->second.size(); h++)
{
int j = it->second.at(h) + 1;
int i = it->first.second;
int lag = it->first.first;
if (j < 1 || j > n || (int) h+1 > n || i < 1)
{
cerr << "SvarIdentificationStatement::writeOutput() Should not arrive here (2). Please report this to the Dynare Team." << endl;
exit(EXIT_FAILURE);
}
if (i > n)
{
cerr << "ERROR: equation number " << i << " is greater than the number of endogenous variables, " << n << "." << endl;
exit(EXIT_FAILURE);
}
if (it->lag == 0)
{
output << "options_.ms.Qi{" << it->equation << "}(" << it->restriction_nbr << ", " << it->variable << ") = ";
it->value->writeOutput(output);
output << ";" << endl;
}
else if (it->lag > 0)
{
int col = (it->lag-1)*n+it->variable;
if (col > k)
{
cerr << "ERROR: lag =" << it->lag << ", num endog vars = " << n << "current endog var index = " << it->variable << ". Index "
<< "out of bounds. If the above does not represent a logical error, please report this to the Dyanre Team." << endl;
}
output << "options_.ms.Ri{" << it->equation << "}(" << it->restriction_nbr << ", " << col << ") = ";
it->value->writeOutput(output);
output << ";" << endl;
}
else
{
cerr << "SvarIdentificationStatement::writeOutput() Should not arrive here (3). Please report this to the Dynare Team." << endl;
exit(EXIT_FAILURE);
}
// for (unsigned int h = 0; h < it->second.size(); h++)
// {
// int j = it->second.at(h) + 1;
// int i = it->first.second;
// int lag = it->first.first;
// if (j < 1 || j > n || (int) h+1 > n || i < 1)
// {
// cerr << "SvarIdentificationStatement::writeOutput() Should not arrive here (2). Please report this to the Dynare Team." << endl;
// exit(EXIT_FAILURE);
// }
// if (i > n)
// {
// cerr << "ERROR: equation number " << i << " is greater than the number of endogenous variables, " << n << "." << endl;
// exit(EXIT_FAILURE);
// }
if (lag == 0)
output << "options_.ms.Qi{" << i << "}(" << h+1 << ", " << j << ") = 1;" << endl;
else if (lag > 0)
{
if ((lag-1)*n+j > k)
{
cerr << "ERROR: lag =" << lag << ", num endog vars = " << n << "current endog var index = " << j << ". Index "
<< "out of bounds. If the above does not represent a logical error, please report this to the Dyanre Team." << endl;
}
output << "options_.ms.Ri{" << i << "}(" << rows[i-1] << ", " << (lag-1)*n+j << ") = 1;" << endl;
rows[i-1]++;
}
else
{
cerr << "SvarIdentificationStatement::writeOutput() Should not arrive here (3). Please report this to the Dynare Team." << endl;
exit(EXIT_FAILURE);
}
}
// if (lag == 0)
// output << "options_.ms.Qi{" << i << "}(" << h+1 << ", " << j << ") = 1;" << endl;
// else if (lag > 0)
// {
// if ((lag-1)*n+j > k)
// {
// cerr << "ERROR: lag =" << lag << ", num endog vars = " << n << "current endog var index = " << j << ". Index "
// << "out of bounds. If the above does not represent a logical error, please report this to the Dyanre Team." << endl;
// }
// output << "options_.ms.Ri{" << i << "}(" << rows[i-1] << ", " << (lag-1)*n+j << ") = 1;" << endl;
// rows[i-1]++;
// }
// else
// {
// cerr << "SvarIdentificationStatement::writeOutput() Should not arrive here (3). Please report this to the Dynare Team." << endl;
// exit(EXIT_FAILURE);
// }
// }
}
}
}

View File

@ -512,16 +512,26 @@ public:
class SvarIdentificationStatement : public Statement
{
public:
typedef map<pair<int, int>, vector<int> > svar_identification_exclusion_t;
// typedef map<pair<int, int>, vector<int> > svar_identification_exclusion_t;
struct svar_identification_restriction
{
int equation;
int restriction_nbr;
int lag;
int variable;
expr_t value;
};
typedef vector< svar_identification_restriction > svar_identification_restrictions_t;
private:
const svar_identification_exclusion_t exclusion;
const svar_identification_restrictions_t restrictions;
const bool upper_cholesky_present;
const bool lower_cholesky_present;
const bool constants_exclusion_present;
const SymbolTable &symbol_table;
int getMaxLag() const;
public:
SvarIdentificationStatement(const svar_identification_exclusion_t &exclusion_arg,
SvarIdentificationStatement(const svar_identification_restrictions_t &restrictions_arg,
const bool &upper_cholesky_present_arg,
const bool &lower_cholesky_present_arg,
const bool &constants_exclusion_present_arg,

View File

@ -144,8 +144,8 @@ class ParsingDriver;
/* end of GSA analysis*/
%token FREQ INITIAL_YEAR INITIAL_SUBPERIOD FINAL_YEAR FINAL_SUBPERIOD DATA VLIST LOG_VAR PERCENT_VAR
%token VLISTLOG VLISTPER
%token RESTRICTIONS RESTRICTION_FNAME CROSS_RESTRICTIONS NLAGS CONTEMP_REDUCED_FORM REAL_PSEUDO_FORECAST NONE
%token DUMMY_OBS NSTATES INDXSCALESSTATES NO_BAYESIAN_PRIOR SPECIFICATION SIMS_ZHA
%token RESTRICTION RESTRICTIONS RESTRICTION_FNAME CROSS_RESTRICTIONS NLAGS CONTEMP_REDUCED_FORM REAL_PSEUDO_FORECAST
%token NONE DUMMY_OBS NSTATES INDXSCALESSTATES NO_BAYESIAN_PRIOR SPECIFICATION SIMS_ZHA
%token <string_val> ALPHA BETA ABAND NINV CMS NCMS CNUM
%token GSIG2_LMDM Q_DIAG FLAT_PRIOR NCSK NSTD
%token INDXPARR INDXOVR INDXAP APBAND INDXIMF IMFBAND INDXFORE FOREBAND INDXGFOREHAT INDXGIMFHAT
@ -156,7 +156,7 @@ class ParsingDriver;
%token MS_ESTIMATION MS_SIMULATION MS_COMPUTE_MDD MS_COMPUTE_PROBABILITIES MS_FORECAST
%token SVAR_IDENTIFICATION EQUATION EXCLUSION LAG UPPER_CHOLESKY LOWER_CHOLESKY MONTHLY QUARTERLY
%token MARKOV_SWITCHING CHAIN STATE DURATION NUMBER_OF_STATES
%token SVAR COEFFICIENTS VARIANCES CONSTANTS EQUATIONS
%token SVAR COEFF COEFFICIENTS VARIANCES CONSTANTS EQUATIONS
%token EXTERNAL_FUNCTION EXT_FUNC_NAME EXT_FUNC_NARGS FIRST_DERIV_PROVIDED SECOND_DERIV_PROVIDED
%token SELECTED_VARIABLES_ONLY COVA_COMPUTE SIMULATION_FILE_TAG FILE_TAG
%token NO_ERROR_BANDS ERROR_BAND_PERCENTILES SHOCKS_PER_PARAMETER NO_CREATE_INIT
@ -688,6 +688,11 @@ svar_identification_elem : EXCLUSION LAG INT_NUMBER ';' svar_equation_list
{ driver.combine_lag_and_restriction($3); }
| EXCLUSION CONSTANTS ';'
{ driver.add_constants_exclusion(); }
| RESTRICTION EQUATION INT_NUMBER COMMA
{ driver.add_restriction_equation_nbr($3);}
restriction_expression EQUAL
{driver.add_restriction_equal();}
restriction_expression ';'
| UPPER_CHOLESKY ';'
{ driver.add_upper_cholesky(); }
| LOWER_CHOLESKY ';'
@ -706,6 +711,17 @@ svar_var_list : svar_var_list COMMA symbol
{ driver.add_in_svar_restriction_symbols($1); }
;
restriction_expression : COEFF '(' symbol COMMA INT_NUMBER ')'
{ driver.add_positive_restriction_element($3,$5);}
| expression
| MINUS COEFF '(' symbol COMMA INT_NUMBER ')'
{ driver.add_negative_restriction_element($4,$6);}
| expression TIMES COEFF '(' symbol COMMA INT_NUMBER ')'
{ driver.add_positive_restriction_element($1,$5,$7);}
| MINUS expression COEFF TIMES '(' symbol COMMA INT_NUMBER ')'
{ driver.add_negative_restriction_element($2,$6,$8);}
markov_switching : MARKOV_SWITCHING '(' ms_options_list ')' ';'
{ driver.markov_switching(); }
;

View File

@ -426,6 +426,7 @@ string eofbuff;
<DYNARE_BLOCK>autocorr {return token::AUTOCORR;}
<DYNARE_BLOCK>restrictions {return token::RESTRICTIONS;}
<DYNARE_BLOCK>restriction {return token::RESTRICTION;}
/* Inside Dynare statement */
<DYNARE_STATEMENT>solve_algo {return token::SOLVE_ALGO;}
@ -454,6 +455,7 @@ string eofbuff;
<DYNARE_BLOCK>equation {return token::EQUATION;}
<DYNARE_BLOCK>exclusion {return token::EXCLUSION;}
<DYNARE_BLOCK>lag {return token::LAG;}
<DYNARE_BLOCK>coeff {return token::COEFF;}
<DYNARE_STATEMENT,DYNARE_BLOCK>upper_cholesky {return token::UPPER_CHOLESKY;}
<DYNARE_STATEMENT,DYNARE_BLOCK>lower_cholesky {return token::LOWER_CHOLESKY;}
<DYNARE_STATEMENT>chain {return token::CHAIN;}

View File

@ -752,14 +752,15 @@ ParsingDriver::begin_svar_identification()
void
ParsingDriver::end_svar_identification()
{
mod_file->addStatement(new SvarIdentificationStatement(svar_ident_exclusion_values,
mod_file->addStatement(new SvarIdentificationStatement(svar_ident_restrictions,
svar_upper_cholesky,
svar_lower_cholesky,
svar_constants_exclusion,
mod_file->symbol_table));
svar_restriction_symbols.clear();
svar_equation_restrictions.clear();
svar_ident_exclusion_values.clear();
svar_ident_restrictions.clear();
svar_restriction_nbr.clear();
}
void
@ -767,14 +768,25 @@ ParsingDriver::combine_lag_and_restriction(string *lag)
{
int current_lag = atoi(lag->c_str());
for (SvarIdentificationStatement::svar_identification_exclusion_t::const_iterator it = svar_ident_exclusion_values.begin();
it != svar_ident_exclusion_values.end(); it++)
if (it->first.first == current_lag)
for (SvarIdentificationStatement::svar_identification_restrictions_t::const_iterator it = svar_ident_restrictions.begin();
it != svar_ident_restrictions.end(); it++)
if (it->lag == current_lag)
error("lag " + *lag + " used more than once.");
for (map<int, vector<int> >::const_iterator it = svar_equation_restrictions.begin();
it != svar_equation_restrictions.end(); it++)
svar_ident_exclusion_values[make_pair(current_lag, it->first)] = it->second;
for (vector<int>::const_iterator it1 = it->second.begin();
it1 != it->second.end(); it1++)
{
SvarIdentificationStatement::svar_identification_restriction new_restriction;
new_restriction.equation = it->first;
new_restriction.restriction_nbr = ++svar_restriction_nbr[it->first];
new_restriction.lag = current_lag;
new_restriction.variable = *it1;
new_restriction.value = data_tree->One;
svar_ident_restrictions.push_back(new_restriction);
}
// svar_ident_exclusion_values[make_pair(current_lag, it->first)] = it->second;
svar_upper_cholesky = false;
svar_lower_cholesky = false;
@ -813,6 +825,102 @@ ParsingDriver::add_in_svar_restriction_symbols(string *tmp_var)
delete tmp_var;
}
void
ParsingDriver::add_restriction_equation_nbr(string *eq_nbr)
{
svar_equation_nbr = atoi(eq_nbr->c_str());
++svar_restriction_nbr[svar_equation_nbr];
svar_left_handside = true;
}
void
ParsingDriver::add_restriction_equal()
{
if (svar_left_handside)
svar_left_handside = false;
else
error("svar_identification: there are more than one EQUAL sign in a restriction equation");
}
void
ParsingDriver::add_positive_restriction_element(expr_t value, string *variable, string *lag)
{
check_symbol_existence(*variable);
int symb_id = mod_file->symbol_table.getID(*variable);
// if the expression is not on the left handside, change its sign
if (!svar_left_handside)
value = add_uminus(value);
SvarIdentificationStatement::svar_identification_restriction new_restriction;
new_restriction.equation = svar_equation_nbr;
new_restriction.restriction_nbr = svar_restriction_nbr[svar_equation_nbr];
new_restriction.lag = atoi(lag->c_str());
new_restriction.variable = symb_id;
new_restriction.value = value;
svar_ident_restrictions.push_back(new_restriction);
}
void
ParsingDriver::add_positive_restriction_element(string *variable, string *lag)
{
check_symbol_existence(*variable);
int symb_id = mod_file->symbol_table.getID(*variable);
expr_t value(data_tree->One);
// if the expression is not on the left handside, change its sign
if (!svar_left_handside)
value = add_uminus(value);
SvarIdentificationStatement::svar_identification_restriction new_restriction;
new_restriction.equation = svar_equation_nbr;
new_restriction.lag = atoi(lag->c_str());
new_restriction.variable = symb_id;
new_restriction.value = value;
svar_ident_restrictions.push_back(new_restriction);
}
void
ParsingDriver::add_negative_restriction_element(expr_t value, string *variable, string *lag)
{
check_symbol_existence(*variable);
int symb_id = mod_file->symbol_table.getID(*variable);
// if the expression is on the left handside, change its sign
if (svar_left_handside)
value = add_uminus(value);
SvarIdentificationStatement::svar_identification_restriction new_restriction;
new_restriction.equation = svar_equation_nbr;
new_restriction.lag = atoi(lag->c_str());
new_restriction.variable = symb_id;
new_restriction.value = value;
svar_ident_restrictions.push_back(new_restriction);
}
void
ParsingDriver::add_negative_restriction_element(string *variable, string *lag)
{
check_symbol_existence(*variable);
int symb_id = mod_file->symbol_table.getID(*variable);
expr_t value(data_tree->One);
// if the expression is on the left handside, change its sign
if (svar_left_handside)
value = add_uminus(value);
SvarIdentificationStatement::svar_identification_restriction new_restriction;
new_restriction.equation = svar_equation_nbr;
new_restriction.lag = atoi(lag->c_str());
new_restriction.variable = symb_id;
new_restriction.value = value;
svar_ident_restrictions.push_back(new_restriction);
}
void
ParsingDriver::add_upper_cholesky()
{

View File

@ -141,7 +141,7 @@ private:
//! Temporary storage for homotopy_setup blocks
HomotopyStatement::homotopy_values_t homotopy_values;
//! Temporary storage for svar_identification blocks
SvarIdentificationStatement::svar_identification_exclusion_t svar_ident_exclusion_values;
SvarIdentificationStatement::svar_identification_restrictions_t svar_ident_restrictions;
//! Temporary storage for mapping the equation number to the restrictions within an svar_identification block
map<int, vector<int> > svar_equation_restrictions;
//! Temporary storage for restrictions in an equation within an svar_identification block
@ -152,6 +152,12 @@ private:
bool svar_upper_cholesky;
//! Temporary storage for lower cholesky within an svar_identification block
bool svar_lower_cholesky;
//! Temporary storage for equation number for a restriction within an svar_identification block
int svar_equation_nbr;
//! Temporary storage for left/right handside of a restriction equation within an svar_identificaton block
bool svar_left_handside;
//! Temporary storage for current restriction number in svar_identification block
map<int,int> svar_restriction_nbr;
//! Temporary storage for argument list of external function
stack<vector<expr_t> > stack_external_function_args;
@ -170,6 +176,7 @@ private:
//! The mod file representation constructed by this ParsingDriver
ModFile *mod_file;
public:
//! Starts parsing, and constructs the MOD file representation
/*! The returned pointer should be deleted after use */
@ -358,6 +365,18 @@ public:
void add_in_svar_restriction_symbols(string *name);
//! Svar_Identification Statement: add exclusions of constants
void add_constants_exclusion();
//! Svar_Identification Statment: add equation number for following restriction equations
void add_restriction_equation_nbr(string *eq_nbr);
//! Svar_Identification Statment: record presence of equal sign
void add_restriction_equal();
//! Svar_Idenditification Statmenet: add coefficient of a linear restriction (positive value)
void add_positive_restriction_element(expr_t value, string *variable, string *lag);
//! Svar_Idenditification Statmenet: add unit coefficient of a linear restriction
void add_positive_restriction_element(string *variable, string *lag);
//! Svar_Idenditification Statmenet: add coefficient of a linear restriction (negative value)
void add_negative_restriction_element(expr_t value, string *variable, string *lag);
//! Svar_Idenditification Statmenet: add negative unit coefficient of a linear restriction
void add_negative_restriction_element(string *variable, string *lag);
//! Svar_Identification Statement: restriction of form upper cholesky
void add_upper_cholesky();
//! Svar_Identification Statement: restriction of form lower cholesky