2008-02-03 11:28:36 +01:00
/*
2013-01-11 17:27:19 +01:00
* Copyright ( C ) 2003 - 2013 Dynare Team
2008-02-03 11:28:36 +01:00
*
* This file is part of Dynare .
*
* Dynare is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* Dynare is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with Dynare . If not , see < http : //www.gnu.org/licenses/>.
*/
2009-10-16 19:23:57 +02:00
# include <cassert>
# include <cstdlib>
2008-02-03 11:28:36 +01:00
# include <iostream>
# include "Shocks.hh"
AbstractShocksStatement : : AbstractShocksStatement ( bool mshocks_arg ,
2010-09-16 19:00:48 +02:00
const det_shocks_t & det_shocks_arg ,
2009-01-23 11:59:37 +01:00
const SymbolTable & symbol_table_arg ) :
2008-02-03 11:28:36 +01:00
mshocks ( mshocks_arg ) ,
det_shocks ( det_shocks_arg ) ,
symbol_table ( symbol_table_arg )
{
}
void
AbstractShocksStatement : : writeDetShocks ( ostream & output ) const
{
int exo_det_length = 0 ;
2010-09-16 19:00:48 +02:00
for ( det_shocks_t : : const_iterator it = det_shocks . begin ( ) ;
2009-12-16 18:13:23 +01:00
it ! = det_shocks . end ( ) ; it + + )
2008-02-03 11:28:36 +01:00
{
2009-02-27 13:19:25 +01:00
int id = symbol_table . getTypeSpecificID ( it - > first ) + 1 ;
2008-02-03 11:28:36 +01:00
bool exo_det = ( symbol_table . getType ( it - > first ) = = eExogenousDet ) ;
int set_shocks_index = ( ( int ) mshocks ) + 2 * ( ( int ) exo_det ) ;
2013-12-31 01:57:30 +01:00
for ( size_t i = 0 ; i < it - > second . size ( ) ; i + + )
2008-02-03 11:28:36 +01:00
{
2013-12-31 01:57:30 +01:00
const int & period1 = it - > second [ i ] . period1 ;
const int & period2 = it - > second [ i ] . period2 ;
const expr_t value = it - > second [ i ] . value ;
2008-02-03 11:28:36 +01:00
if ( period1 = = period2 )
{
output < < " set_shocks( " < < set_shocks_index < < " , " < < period1
< < " , " < < id < < " , " ;
value - > writeOutput ( output ) ;
output < < " ); " < < endl ;
}
else
{
output < < " set_shocks( " < < set_shocks_index < < " , " < < period1
< < " : " < < period2 < < " , " < < id < < " , " ;
value - > writeOutput ( output ) ;
output < < " ); " < < endl ;
}
if ( exo_det & & ( period2 > exo_det_length ) )
exo_det_length = period2 ;
}
}
output < < " M_.exo_det_length = " < < exo_det_length < < " ; \n " ;
}
2010-09-16 19:00:48 +02:00
ShocksStatement : : ShocksStatement ( const det_shocks_t & det_shocks_arg ,
const var_and_std_shocks_t & var_shocks_arg ,
const var_and_std_shocks_t & std_shocks_arg ,
const covar_and_corr_shocks_t & covar_shocks_arg ,
const covar_and_corr_shocks_t & corr_shocks_arg ,
2009-10-29 18:16:10 +01:00
const SymbolTable & symbol_table_arg ) :
AbstractShocksStatement ( false , det_shocks_arg , symbol_table_arg ) ,
var_shocks ( var_shocks_arg ) ,
std_shocks ( std_shocks_arg ) ,
covar_shocks ( covar_shocks_arg ) ,
corr_shocks ( corr_shocks_arg )
{
}
void
ShocksStatement : : writeOutput ( ostream & output , const string & basename ) const
{
output < < " % " < < endl
< < " % SHOCKS instructions " < < endl
< < " % " < < endl ;
// Write instruction that initializes a shock
output < < " make_ex_; " < < endl ;
writeDetShocks ( output ) ;
writeVarAndStdShocks ( output ) ;
writeCovarAndCorrShocks ( output ) ;
if ( covar_shocks . size ( ) + corr_shocks . size ( ) > 0 )
output < < " M_.sigma_e_is_diagonal = 0; " < < endl ;
else
output < < " M_.sigma_e_is_diagonal = 1; " < < endl ;
}
2010-04-14 15:03:41 +02:00
void
2010-09-16 19:00:48 +02:00
ShocksStatement : : writeVarOrStdShock ( ostream & output , var_and_std_shocks_t : : const_iterator & it ,
2010-04-15 17:46:05 +02:00
bool stddev ) const
2010-04-14 15:03:41 +02:00
{
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 < < " ) = " ;
2010-04-15 17:46:05 +02:00
if ( stddev )
2010-04-14 15:03:41 +02:00
output < < " ( " ;
it - > second - > writeOutput ( output ) ;
2010-04-15 17:46:05 +02:00
if ( stddev )
2010-04-14 15:03:41 +02:00
output < < " )^2 " ;
output < < " ; " < < endl ;
}
2009-10-29 18:16:10 +01:00
void
ShocksStatement : : writeVarAndStdShocks ( ostream & output ) const
2008-02-03 11:28:36 +01:00
{
2010-09-16 19:00:48 +02:00
var_and_std_shocks_t : : const_iterator it ;
2008-02-03 11:28:36 +01:00
2009-12-16 18:13:23 +01:00
for ( it = var_shocks . begin ( ) ; it ! = var_shocks . end ( ) ; it + + )
2010-04-14 15:03:41 +02:00
writeVarOrStdShock ( output , it , false ) ;
2008-02-03 11:28:36 +01:00
2009-12-16 18:13:23 +01:00
for ( it = std_shocks . begin ( ) ; it ! = std_shocks . end ( ) ; it + + )
2010-04-14 15:03:41 +02:00
writeVarOrStdShock ( output , it , true ) ;
}
void
2010-09-16 19:00:48 +02:00
ShocksStatement : : writeCovarOrCorrShock ( ostream & output , covar_and_corr_shocks_t : : const_iterator & it ,
2010-04-14 15:03:41 +02:00
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 ) ) ) ;
2013-10-28 15:29:41 +01:00
string matrix , corr_matrix ;
2010-04-14 15:03:41 +02:00
int id1 , id2 ;
if ( type1 = = eExogenous )
2008-02-03 11:28:36 +01:00
{
2010-04-14 15:03:41 +02:00
matrix = " M_.Sigma_e " ;
2013-10-28 15:29:41 +01:00
corr_matrix = " M_.Correlation_matrix " ;
2010-04-14 15:03:41 +02:00
id1 = symbol_table . getTypeSpecificID ( it - > first . first ) + 1 ;
id2 = symbol_table . getTypeSpecificID ( it - > first . second ) + 1 ;
}
else
{
matrix = " M_.H " ;
2013-10-28 15:29:41 +01:00
corr_matrix = " M_.Correlation_matrix_ME " ;
2010-04-14 15:03:41 +02:00
id1 = symbol_table . getObservedVariableIndex ( it - > first . first ) + 1 ;
id2 = symbol_table . getObservedVariableIndex ( it - > first . second ) + 1 ;
2008-02-03 11:28:36 +01:00
}
2010-04-14 15:03:41 +02:00
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 ;
2013-10-28 15:29:41 +01:00
if ( corr )
{
output < < corr_matrix < < " ( " < < id1 < < " , " < < id2 < < " ) = " ;
it - > second - > writeOutput ( output ) ;
output < < " ; " < < endl
< < corr_matrix < < " ( " < < id2 < < " , " < < id1 < < " ) = "
< < corr_matrix < < " ( " < < id1 < < " , " < < id2 < < " ); " < < endl ;
}
2008-02-03 11:28:36 +01:00
}
void
2009-10-29 18:16:10 +01:00
ShocksStatement : : writeCovarAndCorrShocks ( ostream & output ) const
2008-02-03 11:28:36 +01:00
{
2010-09-16 19:00:48 +02:00
covar_and_corr_shocks_t : : const_iterator it ;
2008-02-03 11:28:36 +01:00
2009-12-16 18:13:23 +01:00
for ( it = covar_shocks . begin ( ) ; it ! = covar_shocks . end ( ) ; it + + )
2010-04-14 15:03:41 +02:00
writeCovarOrCorrShock ( output , it , false ) ;
2008-02-03 11:28:36 +01:00
2009-12-16 18:13:23 +01:00
for ( it = corr_shocks . begin ( ) ; it ! = corr_shocks . end ( ) ; it + + )
2010-04-14 15:03:41 +02:00
writeCovarOrCorrShock ( output , it , true ) ;
}
void
2012-02-02 21:10:47 +01:00
ShocksStatement : : checkPass ( ModFileStructure & mod_file_struct , WarningConsolidation & warnings )
2010-04-14 15:03:41 +02:00
{
// Workaround for trac ticket #35
2012-07-30 17:01:20 +02:00
mod_file_struct . shocks_present_but_simul_not_yet = true ;
2010-04-14 15:03:41 +02:00
2013-08-27 10:38:54 +02:00
/* Error out if variables are not of the right type. This must be done here
and not at parsing time ( see # 448 ) .
Also Determine if there is a calibrated measurement error */
2010-09-16 19:00:48 +02:00
for ( var_and_std_shocks_t : : const_iterator it = var_shocks . begin ( ) ;
2010-04-14 15:03:41 +02:00
it ! = var_shocks . end ( ) ; it + + )
2013-08-27 10:38:54 +02:00
{
if ( symbol_table . getType ( it - > first ) ! = eExogenous
& & ! symbol_table . isObservedVariable ( it - > first ) )
{
cerr < < " shocks: setting a variance on ' "
< < symbol_table . getName ( it - > first ) < < " ' is not allowed, because it is neither an exogenous variable nor an observed endogenous variable " < < endl ;
exit ( EXIT_FAILURE ) ;
}
if ( symbol_table . isObservedVariable ( it - > first ) )
mod_file_struct . calibrated_measurement_errors = true ;
}
2010-04-14 15:03:41 +02:00
2010-09-16 19:00:48 +02:00
for ( var_and_std_shocks_t : : const_iterator it = std_shocks . begin ( ) ;
2010-04-14 15:03:41 +02:00
it ! = std_shocks . end ( ) ; it + + )
2013-08-27 10:38:54 +02:00
{
if ( symbol_table . getType ( it - > first ) ! = eExogenous
& & ! symbol_table . isObservedVariable ( it - > first ) )
{
cerr < < " shocks: setting a standard error on ' "
< < symbol_table . getName ( it - > first ) < < " ' is not allowed, because it is neither an exogenous variable nor an observed endogenous variable " < < endl ;
exit ( EXIT_FAILURE ) ;
}
if ( symbol_table . isObservedVariable ( it - > first ) )
mod_file_struct . calibrated_measurement_errors = true ;
}
2010-04-14 15:03:41 +02:00
2010-09-16 19:00:48 +02:00
for ( covar_and_corr_shocks_t : : const_iterator it = covar_shocks . begin ( ) ;
2010-04-14 15:03:41 +02:00
it ! = covar_shocks . end ( ) ; it + + )
2013-08-27 10:38:54 +02:00
{
int symb_id1 = it - > first . first ;
int symb_id2 = it - > first . second ;
if ( ! ( ( symbol_table . getType ( symb_id1 ) = = eExogenous
& & symbol_table . getType ( symb_id2 ) = = eExogenous )
| | ( symbol_table . isObservedVariable ( symb_id1 )
& & symbol_table . isObservedVariable ( symb_id2 ) ) ) )
{
cerr < < " shocks: setting a covariance between ' "
< < symbol_table . getName ( symb_id1 ) < < " ' and ' "
< < symbol_table . getName ( symb_id2 ) < < " 'is not allowed; covariances can only be specified for exogenous or observed endogenous variables of same type " < < endl ;
exit ( EXIT_FAILURE ) ;
}
if ( symbol_table . isObservedVariable ( symb_id1 )
| | symbol_table . isObservedVariable ( symb_id2 ) )
mod_file_struct . calibrated_measurement_errors = true ;
}
2010-04-14 15:03:41 +02:00
2010-09-16 19:00:48 +02:00
for ( covar_and_corr_shocks_t : : const_iterator it = corr_shocks . begin ( ) ;
2010-04-14 15:03:41 +02:00
it ! = corr_shocks . end ( ) ; it + + )
2013-08-27 10:38:54 +02:00
{
int symb_id1 = it - > first . first ;
int symb_id2 = it - > first . second ;
if ( ! ( ( symbol_table . getType ( symb_id1 ) = = eExogenous
& & symbol_table . getType ( symb_id2 ) = = eExogenous )
| | ( symbol_table . isObservedVariable ( symb_id1 )
& & symbol_table . isObservedVariable ( symb_id2 ) ) ) )
{
cerr < < " shocks: setting a correlation between ' "
< < symbol_table . getName ( symb_id1 ) < < " ' and ' "
< < symbol_table . getName ( symb_id2 ) < < " 'is not allowed; correlations can only be specified for exogenous or observed endogenous variables of same type " < < endl ;
exit ( EXIT_FAILURE ) ;
}
if ( symbol_table . isObservedVariable ( it - > first . first )
| | symbol_table . isObservedVariable ( it - > first . second ) )
mod_file_struct . calibrated_measurement_errors = true ;
}
2013-11-29 14:50:58 +01:00
// Fill in mod_file_struct.parameters_with_shocks_values (related to #469)
for ( var_and_std_shocks_t : : const_iterator it = var_shocks . begin ( ) ;
it ! = var_shocks . end ( ) ; + + it )
2013-11-29 15:32:49 +01:00
it - > second - > collectVariables ( eParameter , mod_file_struct . parameters_within_shocks_values ) ;
2013-11-29 14:50:58 +01:00
for ( var_and_std_shocks_t : : const_iterator it = std_shocks . begin ( ) ;
it ! = std_shocks . end ( ) ; + + it )
2013-11-29 15:32:49 +01:00
it - > second - > collectVariables ( eParameter , mod_file_struct . parameters_within_shocks_values ) ;
2013-11-29 14:50:58 +01:00
for ( covar_and_corr_shocks_t : : const_iterator it = covar_shocks . begin ( ) ;
it ! = covar_shocks . end ( ) ; + + it )
2013-11-29 15:32:49 +01:00
it - > second - > collectVariables ( eParameter , mod_file_struct . parameters_within_shocks_values ) ;
2013-11-29 14:50:58 +01:00
for ( covar_and_corr_shocks_t : : const_iterator it = corr_shocks . begin ( ) ;
it ! = corr_shocks . end ( ) ; + + it )
2013-11-29 15:32:49 +01:00
it - > second - > collectVariables ( eParameter , mod_file_struct . parameters_within_shocks_values ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:00:48 +02:00
MShocksStatement : : MShocksStatement ( const det_shocks_t & det_shocks_arg ,
2008-02-03 11:28:36 +01:00
const SymbolTable & symbol_table_arg ) :
2009-10-29 18:16:10 +01:00
AbstractShocksStatement ( true , det_shocks_arg , symbol_table_arg )
2008-02-03 11:28:36 +01:00
{
}
void
MShocksStatement : : writeOutput ( ostream & output , const string & basename ) const
{
2008-06-16 18:33:28 +02:00
output < < " % " < < endl
2009-10-29 18:16:10 +01:00
< < " % MSHOCKS instructions " < < endl
2008-06-16 18:33:28 +02:00
< < " % " < < endl ;
2008-02-03 11:28:36 +01:00
// Write instruction that initializes a shock
2008-06-16 18:33:28 +02:00
output < < " make_ex_; " < < endl ;
2008-02-03 11:28:36 +01:00
writeDetShocks ( output ) ;
}
2009-10-16 19:23:57 +02:00
2010-04-14 15:03:41 +02:00
void
2012-02-02 21:10:47 +01:00
MShocksStatement : : checkPass ( ModFileStructure & mod_file_struct , WarningConsolidation & warnings )
2010-04-14 15:03:41 +02:00
{
// Workaround for trac ticket #35
2012-07-30 17:01:20 +02:00
mod_file_struct . shocks_present_but_simul_not_yet = true ;
2010-04-14 15:03:41 +02:00
}
2013-11-20 12:17:07 +01:00
ConditionalForecastPathsStatement : : ConditionalForecastPathsStatement ( const AbstractShocksStatement : : det_shocks_t & paths_arg ) :
2009-10-16 19:23:57 +02:00
paths ( paths_arg ) ,
path_length ( - 1 )
{
}
void
2012-02-02 21:10:47 +01:00
ConditionalForecastPathsStatement : : checkPass ( ModFileStructure & mod_file_struct , WarningConsolidation & warnings )
2009-10-16 19:23:57 +02:00
{
2010-09-16 19:00:48 +02:00
for ( AbstractShocksStatement : : det_shocks_t : : const_iterator it = paths . begin ( ) ;
2009-12-16 18:13:23 +01:00
it ! = paths . end ( ) ; it + + )
2009-10-16 19:23:57 +02:00
{
int this_path_length = 0 ;
2013-12-31 01:57:30 +01:00
const vector < AbstractShocksStatement : : DetShockElement > & elems = it - > second ;
2009-12-16 18:13:23 +01:00
for ( int i = 0 ; i < ( int ) elems . size ( ) ; i + + )
2009-10-16 19:23:57 +02:00
// Period1 < Period2, as enforced in ParsingDriver::add_period()
this_path_length = max ( this_path_length , elems [ i ] . period2 ) ;
if ( path_length = = - 1 )
path_length = this_path_length ;
else if ( path_length ! = this_path_length )
{
cerr < < " conditional_forecast_paths: all constrained paths must have the same length! " < < endl ;
exit ( EXIT_FAILURE ) ;
}
}
}
void
ConditionalForecastPathsStatement : : writeOutput ( ostream & output , const string & basename ) const
{
assert ( path_length > 0 ) ;
output < < " constrained_vars_ = []; " < < endl
< < " constrained_paths_ = zeros( " < < paths . size ( ) < < " , " < < path_length < < " ); " < < endl ;
int k = 1 ;
2010-09-16 19:00:48 +02:00
for ( AbstractShocksStatement : : det_shocks_t : : const_iterator it = paths . begin ( ) ;
2009-12-16 18:13:23 +01:00
it ! = paths . end ( ) ; it + + )
2009-10-16 19:23:57 +02:00
{
2010-09-26 13:42:41 +02:00
if ( it = = paths . begin ( ) )
2013-01-11 17:27:19 +01:00
{
output < < " constrained_vars_ = " < < it - > first + 1 < < " ; " < < endl ;
}
2010-09-26 13:42:41 +02:00
else
2013-01-11 17:27:19 +01:00
{
output < < " constrained_vars_ = [constrained_vars_; " < < it - > first + 1 < < " ]; " < < endl ;
}
2010-09-26 13:42:41 +02:00
2013-12-31 01:57:30 +01:00
const vector < AbstractShocksStatement : : DetShockElement > & elems = it - > second ;
2009-12-16 18:13:23 +01:00
for ( int i = 0 ; i < ( int ) elems . size ( ) ; i + + )
for ( int j = elems [ i ] . period1 ; j < = elems [ i ] . period2 ; j + + )
2009-10-16 19:23:57 +02:00
{
output < < " constrained_paths_( " < < k < < " , " < < j < < " )= " ;
elems [ i ] . value - > writeOutput ( output ) ;
output < < " ; " < < endl ;
}
k + + ;
}
}