introduce epilogue block
parent
e3550a8fc0
commit
9f0c30740e
|
@ -152,7 +152,10 @@ enum class SymbolType
|
|||
statementDeclaredVariable = 14, //!< Local variable assigned within a Statement (see subsample statement for example)
|
||||
logTrend = 15, //!< Log-trend variable
|
||||
unusedEndogenous = 16,
|
||||
endogenousVAR = 17 //!< Variables declared in a var_model statement
|
||||
endogenousVAR = 17, //!< Variables declared in a var_model statement
|
||||
endogenousEpilogue = 18, //!< Endogenous Variables used in the epilogue block
|
||||
exogenousEpilogue = 19, //!< Variables used in the epilogue block
|
||||
parameterEpilogue = 20 //!< Variables used in the epilogue block
|
||||
};
|
||||
|
||||
enum ExpressionType
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "Statement.hh"
|
||||
#include "StaticModel.hh"
|
||||
#include "DynamicModel.hh"
|
||||
#include "SteadyStateModel.hh"
|
||||
#include "ModelEquationBlock.hh"
|
||||
|
||||
class SteadyStatement : public Statement
|
||||
{
|
||||
|
|
|
@ -148,7 +148,7 @@ class ParsingDriver;
|
|||
%token SBVAR TREND_VAR DEFLATOR GROWTH_FACTOR MS_IRF MS_VARIANCE_DECOMPOSITION GROWTH
|
||||
%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 DURATION NUMBER_OF_REGIMES NUMBER_OF_LAGS
|
||||
%token MARKOV_SWITCHING CHAIN DURATION NUMBER_OF_REGIMES NUMBER_OF_LAGS EPILOGUE
|
||||
%token SVAR SVAR_GLOBAL_IDENTIFICATION_CHECK 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
|
||||
|
@ -221,6 +221,7 @@ statement : parameters
|
|||
| estimated_params_init
|
||||
| set_time
|
||||
| data
|
||||
| epilogue
|
||||
| var_model
|
||||
| pac_model
|
||||
| trend_component_model
|
||||
|
@ -348,6 +349,7 @@ log_trend_var_list : log_trend_var_list symbol
|
|||
;
|
||||
|
||||
var : VAR var_list ';'
|
||||
| VAR '(' EPILOGUE ')' epilogue_var_list ';'
|
||||
| VAR '(' DEFLATOR EQUAL { driver.begin_trend(); } hand_side ')' nonstationary_var_list ';'
|
||||
{ driver.end_nonstationary_var(false, $6); }
|
||||
| VAR '(' LOG_DEFLATOR EQUAL { driver.begin_trend(); } hand_side ')' nonstationary_var_list ';'
|
||||
|
@ -537,13 +539,17 @@ nonstationary_var_list : nonstationary_var_list symbol
|
|||
{ driver.declare_nonstationary_var($1, $2, $3); }
|
||||
;
|
||||
|
||||
varexo : VAREXO varexo_list ';';
|
||||
varexo : VAREXO varexo_list ';'
|
||||
| VAREXO '(' EPILOGUE ')' epilogue_varexo_list ';'
|
||||
;
|
||||
|
||||
varexo_det : VAREXO_DET varexo_det_list ';';
|
||||
|
||||
predetermined_variables : PREDETERMINED_VARIABLES predetermined_variables_list ';';
|
||||
|
||||
parameters : PARAMETERS parameter_list ';';
|
||||
| PARAMETERS '(' EPILOGUE ')' epilogue_parameter_list ';';
|
||||
;
|
||||
|
||||
model_local_variable : MODEL_LOCAL_VARIABLE model_local_variable_list ';';
|
||||
|
||||
|
@ -598,6 +604,32 @@ var_list : var_list symbol
|
|||
{ driver.declare_endogenous($1, $2, $3); }
|
||||
;
|
||||
|
||||
epilogue_var_list : epilogue_var_list symbol
|
||||
{ driver.declare_epilogue_endogenous($2); }
|
||||
| epilogue_var_list COMMA symbol
|
||||
{ driver.declare_epilogue_endogenous($3); }
|
||||
| symbol
|
||||
{ driver.declare_epilogue_endogenous($1); }
|
||||
| epilogue_var_list symbol named_var
|
||||
{ driver.declare_epilogue_endogenous($2, "", $3); }
|
||||
| epilogue_var_list COMMA symbol named_var
|
||||
{ driver.declare_epilogue_endogenous($3, "", $4); }
|
||||
| symbol named_var
|
||||
{ driver.declare_epilogue_endogenous($1, "", $2); }
|
||||
| epilogue_var_list symbol TEX_NAME
|
||||
{ driver.declare_epilogue_endogenous($2, $3); }
|
||||
| epilogue_var_list COMMA symbol TEX_NAME
|
||||
{ driver.declare_epilogue_endogenous($3, $4); }
|
||||
| symbol TEX_NAME
|
||||
{ driver.declare_epilogue_endogenous($1, $2); }
|
||||
| epilogue_var_list symbol TEX_NAME named_var
|
||||
{ driver.declare_epilogue_endogenous($2, $3, $4); }
|
||||
| epilogue_var_list COMMA symbol TEX_NAME named_var
|
||||
{ driver.declare_epilogue_endogenous($3, $4, $5); }
|
||||
| symbol TEX_NAME named_var
|
||||
{ driver.declare_epilogue_endogenous($1, $2, $3); }
|
||||
;
|
||||
|
||||
varexo_list : varexo_list symbol
|
||||
{ driver.declare_exogenous($2); }
|
||||
| varexo_list COMMA symbol
|
||||
|
@ -650,6 +682,32 @@ varexo_det_list : varexo_det_list symbol
|
|||
{ driver.declare_exogenous_det($1, $2, $3); }
|
||||
;
|
||||
|
||||
epilogue_varexo_list : epilogue_varexo_list symbol
|
||||
{ driver.declare_epilogue_exogenous($2); }
|
||||
| epilogue_varexo_list COMMA symbol
|
||||
{ driver.declare_epilogue_exogenous($3); }
|
||||
| symbol
|
||||
{ driver.declare_epilogue_exogenous($1); }
|
||||
| epilogue_varexo_list symbol named_var
|
||||
{ driver.declare_epilogue_exogenous($2, "", $3); }
|
||||
| epilogue_varexo_list COMMA symbol named_var
|
||||
{ driver.declare_epilogue_exogenous($3, "", $4); }
|
||||
| symbol named_var
|
||||
{ driver.declare_epilogue_exogenous($1, "", $2); }
|
||||
| epilogue_varexo_list symbol TEX_NAME
|
||||
{ driver.declare_epilogue_exogenous($2, $3); }
|
||||
| epilogue_varexo_list COMMA symbol TEX_NAME
|
||||
{ driver.declare_epilogue_exogenous($3, $4); }
|
||||
| symbol TEX_NAME
|
||||
{ driver.declare_epilogue_exogenous($1, $2); }
|
||||
| epilogue_varexo_list symbol TEX_NAME named_var
|
||||
{ driver.declare_epilogue_exogenous($2, $3, $4); }
|
||||
| epilogue_varexo_list COMMA symbol TEX_NAME named_var
|
||||
{ driver.declare_epilogue_exogenous($3, $4, $5); }
|
||||
| symbol TEX_NAME named_var
|
||||
{ driver.declare_epilogue_exogenous($1, $2, $3); }
|
||||
;
|
||||
|
||||
parameter_list : parameter_list symbol
|
||||
{ driver.declare_parameter($2); }
|
||||
| parameter_list COMMA symbol
|
||||
|
@ -676,6 +734,32 @@ parameter_list : parameter_list symbol
|
|||
{ driver.declare_parameter($1, $2, $3); }
|
||||
;
|
||||
|
||||
epilogue_parameter_list : epilogue_parameter_list symbol
|
||||
{ driver.declare_parameter($2); }
|
||||
| epilogue_parameter_list COMMA symbol
|
||||
{ driver.declare_parameter($3); }
|
||||
| symbol
|
||||
{ driver.declare_parameter($1); }
|
||||
| epilogue_parameter_list symbol named_var
|
||||
{ driver.declare_parameter($2, "", $3); }
|
||||
| epilogue_parameter_list COMMA symbol named_var
|
||||
{ driver.declare_parameter($3, "", $4); }
|
||||
| symbol named_var
|
||||
{ driver.declare_parameter($1, "", $2); }
|
||||
| epilogue_parameter_list symbol TEX_NAME
|
||||
{ driver.declare_parameter($2, $3); }
|
||||
| epilogue_parameter_list COMMA symbol TEX_NAME
|
||||
{ driver.declare_parameter($3, $4); }
|
||||
| symbol TEX_NAME
|
||||
{ driver.declare_parameter($1, $2); }
|
||||
| epilogue_parameter_list symbol TEX_NAME named_var
|
||||
{ driver.declare_parameter($2, $3, $4); }
|
||||
| epilogue_parameter_list COMMA symbol TEX_NAME named_var
|
||||
{ driver.declare_parameter($3, $4, $5); }
|
||||
| symbol TEX_NAME named_var
|
||||
{ driver.declare_parameter($1, $2, $3); }
|
||||
;
|
||||
|
||||
predetermined_variables_list : predetermined_variables_list symbol
|
||||
{ driver.add_predetermined_variable($2); }
|
||||
| predetermined_variables_list COMMA symbol
|
||||
|
@ -864,6 +948,18 @@ histval_file : HISTVAL_FILE '(' FILENAME EQUAL filename ')' ';'
|
|||
{ driver.histval_file($5); }
|
||||
;
|
||||
|
||||
epilogue : EPILOGUE ';' { driver.begin_epilogue(); }
|
||||
epilogue_equation_list END ';' { driver.end_epilogue(); }
|
||||
;
|
||||
|
||||
epilogue_equation_list : epilogue_equation_list epilogue_equation
|
||||
| epilogue_equation
|
||||
;
|
||||
|
||||
epilogue_equation : symbol EQUAL expression ';'
|
||||
{ driver.add_epilogue_equal($1, $3); }
|
||||
;
|
||||
|
||||
model_options : BLOCK { driver.block(); }
|
||||
| o_cutoff
|
||||
| o_mfs
|
||||
|
|
|
@ -204,6 +204,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>shock_groups {BEGIN DYNARE_BLOCK; return token::SHOCK_GROUPS;}
|
||||
<INITIAL>mshocks {BEGIN DYNARE_BLOCK; return token::MSHOCKS;}
|
||||
<INITIAL>estimated_params {BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS;}
|
||||
<INITIAL>epilogue {BEGIN DYNARE_BLOCK; return token::EPILOGUE;}
|
||||
/* priors is an alias for estimated_params */
|
||||
<INITIAL>priors {BEGIN DYNARE_BLOCK;return token::ESTIMATED_PARAMS;}
|
||||
<INITIAL>estimated_params_init {BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS_INIT;}
|
||||
|
@ -629,6 +630,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>save_draws {return token::SAVE_DRAWS; }
|
||||
<DYNARE_STATEMENT>deflator {return token::DEFLATOR;}
|
||||
<DYNARE_STATEMENT>log_deflator {return token::LOG_DEFLATOR;}
|
||||
<DYNARE_STATEMENT>epilogue {return token::EPILOGUE;}
|
||||
<DYNARE_STATEMENT>growth_factor {return token::GROWTH_FACTOR;}
|
||||
<DYNARE_STATEMENT>log_growth_factor {return token::LOG_GROWTH_FACTOR;}
|
||||
<DYNARE_STATEMENT>growth {return token::GROWTH;}
|
||||
|
|
|
@ -748,6 +748,9 @@ VariableNode::prepareForDerivation()
|
|||
break;
|
||||
case SymbolType::externalFunction:
|
||||
case SymbolType::endogenousVAR:
|
||||
case SymbolType::endogenousEpilogue:
|
||||
case SymbolType::exogenousEpilogue:
|
||||
case SymbolType::parameterEpilogue:
|
||||
cerr << "VariableNode::prepareForDerivation: impossible case" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -781,7 +784,10 @@ VariableNode::computeDerivative(int deriv_id)
|
|||
exit(EXIT_FAILURE);
|
||||
case SymbolType::externalFunction:
|
||||
case SymbolType::endogenousVAR:
|
||||
cerr << "Impossible case!" << endl;
|
||||
case SymbolType::endogenousEpilogue:
|
||||
case SymbolType::exogenousEpilogue:
|
||||
case SymbolType::parameterEpilogue:
|
||||
cerr << "VariableNode::computeDerivative: Impossible case!" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// Suppress GCC warning
|
||||
|
@ -857,6 +863,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
switch (type)
|
||||
{
|
||||
case SymbolType::parameter:
|
||||
case SymbolType::parameterEpilogue:
|
||||
if (output_type == oMatlabOutsideModel)
|
||||
output << "M_.params" << "(" << tsid + 1 << ")";
|
||||
else
|
||||
|
@ -927,6 +934,13 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
if (lag != 0)
|
||||
output << LEFT_ARRAY_SUBSCRIPT(output_type) << lag << RIGHT_ARRAY_SUBSCRIPT(output_type);
|
||||
break;
|
||||
case oEpilogueFile:
|
||||
output << datatree.symbol_table.getName(symb_id)
|
||||
<< LEFT_ARRAY_SUBSCRIPT(output_type) << "epilogue_it__";
|
||||
if (lag != 0)
|
||||
output << lag;
|
||||
output << RIGHT_ARRAY_SUBSCRIPT(output_type);
|
||||
break;
|
||||
default:
|
||||
cerr << "VariableNode::writeOutput: should not reach this point" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -980,6 +994,13 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
if (lag != 0)
|
||||
output << LEFT_ARRAY_SUBSCRIPT(output_type) << lag << RIGHT_ARRAY_SUBSCRIPT(output_type);
|
||||
break;
|
||||
case oEpilogueFile:
|
||||
output << datatree.symbol_table.getName(symb_id)
|
||||
<< LEFT_ARRAY_SUBSCRIPT(output_type) << "epilogue_it__";
|
||||
if (lag != 0)
|
||||
output << lag;
|
||||
output << RIGHT_ARRAY_SUBSCRIPT(output_type);
|
||||
break;
|
||||
default:
|
||||
cerr << "VariableNode::writeOutput: should not reach this point" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -1033,19 +1054,33 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
if (lag != 0)
|
||||
output << LEFT_ARRAY_SUBSCRIPT(output_type) << lag << RIGHT_ARRAY_SUBSCRIPT(output_type);
|
||||
break;
|
||||
case oEpilogueFile:
|
||||
output << datatree.symbol_table.getName(symb_id)
|
||||
<< LEFT_ARRAY_SUBSCRIPT(output_type) << "epilogue_it__";
|
||||
if (lag != 0)
|
||||
output << lag;
|
||||
output << RIGHT_ARRAY_SUBSCRIPT(output_type);
|
||||
break;
|
||||
default:
|
||||
cerr << "VariableNode::writeOutput: should not reach this point" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
case SymbolType::endogenousEpilogue:
|
||||
case SymbolType::exogenousEpilogue:
|
||||
output << datatree.symbol_table.getName(symb_id)
|
||||
<< LEFT_ARRAY_SUBSCRIPT(output_type) << "epilogue_it__";
|
||||
if (lag != 0)
|
||||
output << lag;
|
||||
output << RIGHT_ARRAY_SUBSCRIPT(output_type);
|
||||
break;
|
||||
case SymbolType::externalFunction:
|
||||
case SymbolType::trend:
|
||||
case SymbolType::logTrend:
|
||||
case SymbolType::statementDeclaredVariable:
|
||||
case SymbolType::unusedEndogenous:
|
||||
case SymbolType::endogenousVAR:
|
||||
cerr << "Impossible case" << endl;
|
||||
cerr << "VariableNode::writeOutput: Impossible case" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
@ -1264,7 +1299,10 @@ VariableNode::getChainRuleDerivative(int deriv_id, const map<int, expr_t> &recur
|
|||
exit(EXIT_FAILURE);
|
||||
case SymbolType::externalFunction:
|
||||
case SymbolType::endogenousVAR:
|
||||
cerr << "Impossible case!" << endl;
|
||||
case SymbolType::endogenousEpilogue:
|
||||
case SymbolType::exogenousEpilogue:
|
||||
case SymbolType::parameterEpilogue:
|
||||
cerr << "VariableNode::getChainRuleDerivative: Impossible case" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// Suppress GCC warning
|
||||
|
@ -1302,6 +1340,9 @@ VariableNode::computeXrefs(EquationInfo &ei) const
|
|||
case SymbolType::unusedEndogenous:
|
||||
case SymbolType::externalFunction:
|
||||
case SymbolType::endogenousVAR:
|
||||
case SymbolType::endogenousEpilogue:
|
||||
case SymbolType::exogenousEpilogue:
|
||||
case SymbolType::parameterEpilogue:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -6705,6 +6746,7 @@ AbstractExternalFunctionNode::getIndxInTefTerms(int the_symb_id, const deriv_nod
|
|||
auto it = tef_terms.find({ the_symb_id, arguments });
|
||||
if (it != tef_terms.end())
|
||||
return it->second;
|
||||
cout << endl << endl << tef_terms.size() << "." <<the_symb_id << endl << endl;
|
||||
throw UnknownFunctionNameAndArgs();
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,8 @@ enum ExprNodeOutputType
|
|||
oJuliaDynamicSteadyStateOperator, //!< Julia code, dynamic model, inside a steady state operator
|
||||
oSteadyStateFile, //!< Matlab code, in the generated steady state file
|
||||
oJuliaSteadyStateFile, //!< Julia code, in the generated steady state file
|
||||
oMatlabDseries //!< Matlab code for dseries
|
||||
oMatlabDseries, //!< Matlab code for dseries
|
||||
oEpilogueFile //!< Matlab code, in the generated epilogue file
|
||||
};
|
||||
|
||||
#define IS_MATLAB(output_type) ((output_type) == oMatlabStaticModel \
|
||||
|
@ -98,7 +99,8 @@ enum ExprNodeOutputType
|
|||
|| (output_type) == oMatlabDynamicSteadyStateOperator \
|
||||
|| (output_type) == oMatlabDynamicSparseSteadyStateOperator \
|
||||
|| (output_type) == oSteadyStateFile \
|
||||
|| (output_type) == oMatlabDseries)
|
||||
|| (output_type) == oMatlabDseries \
|
||||
|| (output_type) == oEpilogueFile)
|
||||
|
||||
#define IS_JULIA(output_type) ((output_type) == oJuliaStaticModel \
|
||||
|| (output_type) == oJuliaDynamicModel \
|
||||
|
|
|
@ -48,8 +48,8 @@ dynare_m_SOURCES = \
|
|||
CodeInterpreter.hh \
|
||||
ExternalFunctionsTable.cc \
|
||||
ExternalFunctionsTable.hh \
|
||||
SteadyStateModel.hh \
|
||||
SteadyStateModel.cc \
|
||||
ModelEquationBlock.hh \
|
||||
ModelEquationBlock.cc \
|
||||
WarningConsolidation.hh \
|
||||
WarningConsolidation.cc \
|
||||
ExtendedPreprocessorTypes.hh \
|
||||
|
|
|
@ -44,6 +44,8 @@ ModFile::ModFile(WarningConsolidation &warnings_arg)
|
|||
trend_component_model_table, var_model_table),
|
||||
orig_ramsey_dynamic_model(symbol_table, num_constants, external_functions_table,
|
||||
trend_component_model_table, var_model_table),
|
||||
epilogue(symbol_table, num_constants, external_functions_table,
|
||||
trend_component_model_table, var_model_table),
|
||||
static_model(symbol_table, num_constants, external_functions_table,
|
||||
trend_component_model_table, var_model_table),
|
||||
steady_state_model(symbol_table, num_constants, external_functions_table,
|
||||
|
@ -127,6 +129,9 @@ ModFile::checkPass(bool nostrict, bool stochastic)
|
|||
// Check the steady state block
|
||||
steady_state_model.checkPass(mod_file_struct, warnings);
|
||||
|
||||
// Check epilogue block
|
||||
epilogue.checkPass(warnings);
|
||||
|
||||
if (mod_file_struct.write_latex_steady_state_model_present &&
|
||||
!mod_file_struct.steady_state_model_present)
|
||||
{
|
||||
|
@ -767,6 +772,8 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_deri
|
|||
|
||||
for (auto & statement : statements)
|
||||
statement->computingPass();
|
||||
|
||||
epilogue.computingPass(true, true, false, 0, global_eval_context, true, false, false, false, true);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1074,6 +1081,9 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
|
|||
|
||||
// Create steady state file
|
||||
steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present, false);
|
||||
|
||||
// Create epilogue file
|
||||
epilogue.writeEpilogueFile(basename);
|
||||
}
|
||||
|
||||
if (!nopreprocessoroutput)
|
||||
|
|
|
@ -32,7 +32,7 @@ using namespace std;
|
|||
#include "NumericalInitialization.hh"
|
||||
#include "StaticModel.hh"
|
||||
#include "DynamicModel.hh"
|
||||
#include "SteadyStateModel.hh"
|
||||
#include "ModelEquationBlock.hh"
|
||||
#include "Statement.hh"
|
||||
#include "ExternalFunctionsTable.hh"
|
||||
#include "ConfigFile.hh"
|
||||
|
@ -68,6 +68,8 @@ public:
|
|||
DynamicModel ramsey_FOC_equations_dynamic_model;
|
||||
//! A copy of the original model, used to test model linearity under ramsey problem
|
||||
DynamicModel orig_ramsey_dynamic_model;
|
||||
//! Epilogue model, as declared in the "epilogue" block
|
||||
Epilogue epilogue;
|
||||
//! Static model, as derived from the "model" block when leads and lags have been removed
|
||||
StaticModel static_model;
|
||||
//! Static model, as declared in the "steady_state_model" block if present
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
#include "SteadyStateModel.hh"
|
||||
#include "ModelEquationBlock.hh"
|
||||
|
||||
SteadyStateModel::SteadyStateModel(SymbolTable &symbol_table_arg,
|
||||
NumericalConstants &num_constants_arg,
|
||||
|
@ -269,3 +269,109 @@ SteadyStateModel::writeJsonSteadyStateFile(ostream &output, bool transformComput
|
|||
|
||||
output << "]}";
|
||||
}
|
||||
|
||||
Epilogue::Epilogue(SymbolTable &symbol_table_arg,
|
||||
NumericalConstants &num_constants_arg,
|
||||
ExternalFunctionsTable &external_functions_table_arg,
|
||||
TrendComponentModelTable &trend_component_model_table_arg,
|
||||
VarModelTable &var_model_table_arg) :
|
||||
DynamicModel(symbol_table_arg, num_constants_arg, external_functions_table_arg,
|
||||
trend_component_model_table_arg, var_model_table_arg)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Epilogue::addDefinition(int symb_id, expr_t expr)
|
||||
{
|
||||
AddVariable(symb_id); // Create the variable node to be used in write method
|
||||
def_table.emplace_back(symb_id, expr);
|
||||
endogs.emplace(symb_id);
|
||||
expr->collectVariables(SymbolType::endogenous, exogs);
|
||||
expr->collectVariables(SymbolType::exogenous, exogs);
|
||||
expr->collectVariables(SymbolType::endogenousEpilogue, exogs);
|
||||
expr->collectVariables(SymbolType::exogenousEpilogue, exogs);
|
||||
for (auto it : endogs)
|
||||
exogs.erase(it);
|
||||
}
|
||||
|
||||
void
|
||||
Epilogue::checkPass(WarningConsolidation &warnings) const
|
||||
{
|
||||
if (def_table.size() == 0)
|
||||
return;
|
||||
|
||||
vector<int> so_far_defined;
|
||||
for (const auto & it : def_table)
|
||||
{
|
||||
if (find(so_far_defined.begin(), so_far_defined.end(), it.first) != so_far_defined.end())
|
||||
{
|
||||
cerr << "WARNING: in the 'epilogue' block, variable '" << symbol_table.getName(it.first)
|
||||
<< "' is declared twice" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
so_far_defined.push_back(it.first);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Epilogue::writeEpilogueFile(const string &basename) const
|
||||
{
|
||||
if (def_table.size() == 0)
|
||||
return;
|
||||
|
||||
string filename = packageDir(basename) + "/epilogue.m";
|
||||
ofstream output;
|
||||
output.open(filename, ios::out | ios::binary);
|
||||
if (!output.is_open())
|
||||
{
|
||||
cerr << "ERROR: Can't open file " << filename << " for writing" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ExprNodeOutputType output_type = oEpilogueFile;
|
||||
output << "function ds = epilogue(params, ds)" << endl
|
||||
<< "% function ds = epilogue(params, ds)" << endl
|
||||
<< "% Epilogue file generated by Dynare preprocessor" << endl << endl
|
||||
<< "epilogue_ds_first_date__ = ds.firstdate;" << endl
|
||||
<< "epilogue_loop_begin_idx__ = lastdate(ds) - ds.lastobservedperiod;" << endl
|
||||
<< "epilogue_loop_end_idx__ = lastdate(ds) - firstdate(ds) + 1;" << endl << endl;
|
||||
|
||||
output << "% endogenous" << endl;
|
||||
for (auto symb_id : endogs)
|
||||
output << symbol_table.getName(symb_id) << " = ds." << symbol_table.getName(symb_id) << ".data;" << endl;
|
||||
output << endl
|
||||
<< "% exogenous" << endl;
|
||||
for (auto symb_id : exogs)
|
||||
output << symbol_table.getName(symb_id) << " = ds." << symbol_table.getName(symb_id) << ".data;" << endl;
|
||||
output << endl
|
||||
<< "for epilogue_it__ = epilogue_loop_begin_idx__::epilogue_loop_end_idx__" << endl;
|
||||
|
||||
deriv_node_temp_terms_t tef_terms;
|
||||
temporary_terms_t temporary_terms;
|
||||
temporary_terms_idxs_t temporary_terms_idxs;
|
||||
for (const auto & it : def_table)
|
||||
if (it.second->containsExternalFunction())
|
||||
{
|
||||
output << " ";
|
||||
it.second->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms);
|
||||
}
|
||||
output << endl;
|
||||
for (const auto & it : def_table)
|
||||
{
|
||||
auto node = variable_node_map.find({ it.first, 0 });
|
||||
assert(node != variable_node_map.end());
|
||||
|
||||
output << " ";
|
||||
dynamic_cast<ExprNode *>(node->second)->writeOutput(output, output_type);
|
||||
output << " = ";
|
||||
it.second->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms);
|
||||
output << ";" << endl;
|
||||
}
|
||||
output << "end" << endl << endl;
|
||||
for (auto symb_id : endogs)
|
||||
output << "ds." << symbol_table.getName(symb_id) << " = dseries(" << symbol_table.getName(symb_id)
|
||||
<< ", epilogue_ds_first_date__);" << endl;
|
||||
output << endl
|
||||
<< "end" << endl;
|
||||
output.close();
|
||||
}
|
|
@ -23,6 +23,7 @@
|
|||
#include "DataTree.hh"
|
||||
#include "Statement.hh"
|
||||
#include "StaticModel.hh"
|
||||
#include "DynamicModel.hh"
|
||||
#include "WarningConsolidation.hh"
|
||||
|
||||
class SteadyStateModel : public DataTree
|
||||
|
@ -61,4 +62,31 @@ public:
|
|||
void writeJsonSteadyStateFile(ostream &output, bool transformComputingPass) const;
|
||||
};
|
||||
|
||||
class Epilogue : public DynamicModel
|
||||
{
|
||||
private:
|
||||
//! Associates a set of symbol IDs (the variable(s) assigned in a given statement) to an expression (their assigned value)
|
||||
vector<pair<int, expr_t>> def_table;
|
||||
|
||||
//! List of variables found in block
|
||||
set<int> endogs;
|
||||
set<int> exogs;
|
||||
public:
|
||||
Epilogue(SymbolTable &symbol_table_arg,
|
||||
NumericalConstants &num_constants_arg,
|
||||
ExternalFunctionsTable &external_functions_table_arg,
|
||||
TrendComponentModelTable &trend_component_model_table_arg,
|
||||
VarModelTable &var_model_table_arg);
|
||||
|
||||
//! Add an expression of the form "var = expr;"
|
||||
void addDefinition(int symb_id, expr_t expr);
|
||||
|
||||
//! Checks that no variable is declared twice
|
||||
void checkPass(WarningConsolidation &warnings) const;
|
||||
|
||||
//! Write the steady state file
|
||||
void writeEpilogueFile(const string &basename) const;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -201,6 +201,14 @@ ParsingDriver::declare_endogenous(const string &name, const string &tex_name, co
|
|||
declare_symbol(name, SymbolType::endogenous, tex_name, partition_value);
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::declare_epilogue_endogenous(const string &name,
|
||||
const string &tex_name,
|
||||
const vector<pair<string, string>> &partition_value)
|
||||
{
|
||||
declare_symbol(name, SymbolType::endogenousEpilogue, tex_name, partition_value);
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::declare_var_endogenous(const string &name)
|
||||
{
|
||||
|
@ -230,12 +238,28 @@ ParsingDriver::declare_exogenous_det(const string &name, const string &tex_name,
|
|||
declare_symbol(name, SymbolType::exogenousDet, tex_name, partition_value);
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::declare_epilogue_exogenous(const string &name,
|
||||
const string &tex_name,
|
||||
const vector<pair<string, string>> &partition_value)
|
||||
{
|
||||
declare_symbol(name, SymbolType::exogenousEpilogue, tex_name, partition_value);
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::declare_parameter(const string &name, const string &tex_name, const vector<pair<string, string>> &partition_value)
|
||||
{
|
||||
declare_symbol(name, SymbolType::parameter, tex_name, partition_value);
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::declare_epilogue_parameter(const string &name,
|
||||
const string &tex_name,
|
||||
const vector<pair<string, string>> &partition_value)
|
||||
{
|
||||
declare_symbol(name, SymbolType::parameterEpilogue, tex_name, partition_value);
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::declare_statement_local_variable(const string &name)
|
||||
{
|
||||
|
@ -414,6 +438,9 @@ ParsingDriver::add_model_variable(int symb_id, int lag)
|
|||
expr_t
|
||||
ParsingDriver::add_expression_variable(const string &name)
|
||||
{
|
||||
if (parsing_epilogue && !mod_file->symbol_table.exists(name))
|
||||
error("Variable " + name + " used in the epilogue block but was not declared.");
|
||||
|
||||
// If symbol doesn't exist, then declare it as a mod file local variable
|
||||
if (!mod_file->symbol_table.exists(name))
|
||||
mod_file->symbol_table.addSymbol(name, SymbolType::modFileLocalVariable);
|
||||
|
@ -817,6 +844,35 @@ ParsingDriver::end_homotopy()
|
|||
homotopy_values.clear();
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::begin_epilogue()
|
||||
{
|
||||
parsing_epilogue = true;
|
||||
set_current_data_tree(&mod_file->epilogue);
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::end_epilogue()
|
||||
{
|
||||
parsing_epilogue = false;
|
||||
reset_data_tree();
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::add_epilogue_equal(const string &varname, expr_t expr)
|
||||
{
|
||||
int id;
|
||||
try
|
||||
{
|
||||
id = mod_file->symbol_table.getID(varname);
|
||||
}
|
||||
catch (SymbolTable::UnknownSymbolNameException &e)
|
||||
{
|
||||
error("Variable " + varname + " used in the epilogue block but was not declared.");
|
||||
}
|
||||
mod_file->epilogue.addDefinition(id, expr);
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::begin_model()
|
||||
{
|
||||
|
@ -2887,7 +2943,7 @@ ParsingDriver::add_model_var_or_external_function(const string &function_name, b
|
|||
expr_t nid;
|
||||
if (mod_file->symbol_table.exists(function_name))
|
||||
if (mod_file->symbol_table.getType(function_name) != SymbolType::externalFunction)
|
||||
if (!in_model_block)
|
||||
if (!in_model_block && !parsing_epilogue)
|
||||
{
|
||||
if (stack_external_function_args.top().size() > 0)
|
||||
error(string("Symbol ") + function_name + string(" cannot take arguments."));
|
||||
|
@ -2915,7 +2971,7 @@ ParsingDriver::add_model_var_or_external_function(const string &function_name, b
|
|||
if (!mod_file->external_functions_table.exists(symb_id))
|
||||
error("Using a derivative of an external function (" + function_name + ") in the model block is currently not allowed.");
|
||||
|
||||
if (in_model_block)
|
||||
if (in_model_block || parsing_epilogue)
|
||||
if (mod_file->external_functions_table.getNargs(symb_id) == eExtFunNotSet)
|
||||
error("Before using " + function_name
|
||||
+"() in the model block, you must first declare it via the external_function() statement");
|
||||
|
@ -2925,6 +2981,9 @@ ParsingDriver::add_model_var_or_external_function(const string &function_name, b
|
|||
}
|
||||
else
|
||||
{ //First time encountering this external function i.e., not previously declared or encountered
|
||||
if (parsing_epilogue)
|
||||
error("Variable " + function_name + " used in the epilogue block but was not declared.");
|
||||
|
||||
if (in_model_block)
|
||||
{
|
||||
// Continue processing, noting that it was not declared
|
||||
|
|
|
@ -259,8 +259,12 @@ private:
|
|||
//! Used by VAR restrictions
|
||||
void clear_VAR_storage();
|
||||
|
||||
//! True when parsing the epilogue block
|
||||
bool parsing_epilogue;
|
||||
|
||||
public:
|
||||
ParsingDriver(WarningConsolidation &warnings_arg, bool nostrict_arg) : warnings(warnings_arg), nostrict(nostrict_arg) { };
|
||||
ParsingDriver(WarningConsolidation &warnings_arg, bool nostrict_arg) :
|
||||
warnings(warnings_arg), nostrict(nostrict_arg), parsing_epilogue(false) { };
|
||||
|
||||
//! Starts parsing, and constructs the MOD file representation
|
||||
unique_ptr<ModFile> parse(istream &in, bool debug);
|
||||
|
@ -335,12 +339,18 @@ public:
|
|||
void initval_file(const string &filename);
|
||||
//! Declares an endogenous variable
|
||||
void declare_endogenous(const string &name, const string &tex_name = "", const vector<pair<string, string>> &partition_value = {});
|
||||
//! Declares an endogenous variable in the epilogue block
|
||||
void declare_epilogue_endogenous(const string &name, const string &tex_name = "", const vector<pair<string, string>> &partition_value = {});
|
||||
//! Declares an exogenous variable
|
||||
void declare_exogenous(const string &name, const string &tex_name = "", const vector<pair<string, string>> &partition_value = {});
|
||||
//! Declares an exogenous variable in the epilogue block
|
||||
void declare_epilogue_exogenous(const string &name, const string &tex_name = "", const vector<pair<string, string>> &partition_value = {});
|
||||
//! Declares an exogenous deterministic variable
|
||||
void declare_exogenous_det(const string &name, const string &tex_name = "", const vector<pair<string, string>> &partition_value = {});
|
||||
//! Declares a parameter
|
||||
void declare_parameter(const string &name, const string &tex_name = "", const vector<pair<string, string>> &partition_value = {});
|
||||
//! Declare a parameter in the epilogue block
|
||||
void declare_epilogue_parameter(const string &name, const string &tex_name = "", const vector<pair<string, string>> &partition_value = {});
|
||||
//! Declares a VAR variable and adds to symbol_list
|
||||
void declare_var_endogenous(const string &name);
|
||||
//! Declares a model local variable
|
||||
|
@ -402,6 +412,12 @@ public:
|
|||
void end_histval(bool all_values_required);
|
||||
//! Writes end of an homotopy_setup block
|
||||
void end_homotopy();
|
||||
//! Begin epilogue block
|
||||
void begin_epilogue();
|
||||
//! Endepilogue block
|
||||
void end_epilogue();
|
||||
//! Add equation in epilogue block
|
||||
void add_epilogue_equal(const string &varname, expr_t expr);
|
||||
//! Begin a model block
|
||||
void begin_model();
|
||||
//! End a model block, printing errors that were encountered in parsing
|
||||
|
|
Loading…
Reference in New Issue