339 lines
13 KiB
C++
339 lines
13 KiB
C++
/*
|
|
* Copyright © 2006-2023 Dynare Team
|
|
*
|
|
* 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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef STATEMENT_HH
|
|
#define STATEMENT_HH
|
|
|
|
#include <map>
|
|
#include <optional>
|
|
#include <ostream>
|
|
#include <set>
|
|
#include <string>
|
|
#include <variant>
|
|
|
|
#include "SymbolList.hh"
|
|
#include "WarningConsolidation.hh"
|
|
|
|
struct ModFileStructure
|
|
{
|
|
//! Whether check is present
|
|
bool check_present {false};
|
|
//! Whether steady is present
|
|
bool steady_present {false};
|
|
//! Whether a perfect_foresight_solver/simul statement is present
|
|
bool perfect_foresight_solver_present {false};
|
|
//! Whether a perfect_foresight_with_expectation_errors_solver statement is present
|
|
bool perfect_foresight_with_expectation_errors_solver_present {false};
|
|
//! Whether a stoch_simul statement is present
|
|
bool stoch_simul_present {false};
|
|
//! Whether an estimation statement is present
|
|
bool estimation_present {false};
|
|
//! Whether an osr statement is present
|
|
bool osr_present {false};
|
|
//! Whether an osr params statement is present
|
|
bool osr_params_present {false};
|
|
//! Whether an optim weight statement is present
|
|
bool optim_weights_present {false};
|
|
//! Whether a ramsey_model statement is present
|
|
bool ramsey_model_present {false};
|
|
//! Whether a discretionary_objective statement is present
|
|
bool discretionary_policy_present {false};
|
|
//! Whether a planner_objective statement is present
|
|
bool planner_objective_present {false};
|
|
//! Whether an extended_path statement is present
|
|
bool extended_path_present {false};
|
|
//! The value of the "order" option of stoch_simul, estimation, osr, ramsey_policy
|
|
//! Derivation order
|
|
/*! First initialized to zero. If user sets order option somewhere in the MOD file, it will be
|
|
* equal to the maximum of order options. Otherwise will default to 2 */
|
|
int order_option {0};
|
|
//! Whether a bvar_density, bvar_forecast, sbvar, ms_sbvar statement is present
|
|
bool bvar_present {false};
|
|
//! Whether an svar_identification statement is present
|
|
bool svar_identification_present {false};
|
|
//! Whether an identification statement is present or the identification option of
|
|
//! dynare_sensitivity statement is equal to one
|
|
bool identification_present {false};
|
|
//! The maximum of the “order” option in identification statements
|
|
int identification_order {0};
|
|
//! Whether a sensitivity statement is present
|
|
bool sensitivity_present {false};
|
|
//! Whether the option analytic_derivation is given to estimation
|
|
bool estimation_analytic_derivation {false};
|
|
//! Whether the option analytic_derivation is given to osr
|
|
bool osr_analytic_derivation {false};
|
|
//! Whether the option partial_information is given to stoch_simul/estimation/osr/ramsey_policy
|
|
bool partial_information {false};
|
|
//! Whether the "k_order_solver" option is used (explictly, or implicitly if order >= 3)
|
|
bool k_order_solver {false};
|
|
//! Whether an method_of_moments statement is present
|
|
bool mom_estimation_present {false};
|
|
//! Whether an GMM-option is present
|
|
bool GMM_present {false};
|
|
//! Whether an analytic_standard_errors-option is present
|
|
bool analytic_standard_errors_present {false};
|
|
//! Whether an analytic_jacobian-option is present
|
|
bool analytic_jacobian_present {false};
|
|
//! The maximum of the “order” option in method_of_moments statements
|
|
int mom_order {0};
|
|
//! Whether there is a calibrated measurement error
|
|
bool calibrated_measurement_errors {false};
|
|
//! Whether dsge_prior_weight was initialized as a parameter
|
|
bool dsge_prior_weight_initialized;
|
|
//! Whether dsge_prior_weight is in the estimated_params block
|
|
bool dsge_prior_weight_in_estimated_params {false};
|
|
//! Whether there is a dsge_var, with calibrated prior weight
|
|
string dsge_var_calibrated;
|
|
//! Whether there is a dsge_var, with prior weight that must be estimated
|
|
bool dsge_var_estimated {false};
|
|
//! Whether there is a bayesian_irf option passed to the estimation statement
|
|
bool bayesian_irf_present {false};
|
|
//! Whether there is a data statement present
|
|
bool estimation_data_statement_present {false};
|
|
//! Last chain number for Markov Switching statement2
|
|
int last_markov_switching_chain {0};
|
|
//! Whether a calib_smoother statement is present
|
|
bool calib_smoother_present {false};
|
|
//! Whether there is an estimated_params_init with use_calibration
|
|
bool estim_params_use_calib {false};
|
|
//! Set of parameters used within shocks blocks, inside the expressions
|
|
//! defining the values of covariances (stored as symbol ids)
|
|
set<int> parameters_within_shocks_values;
|
|
//! Set of estimated parameters (stored as symbol ids)
|
|
set<int> estimated_parameters;
|
|
//! Whether there is a prior statement present
|
|
bool prior_statement_present {false};
|
|
//! Whether there is a std prior statement present
|
|
bool std_prior_statement_present {false};
|
|
//! Whether there is a corr prior statement present
|
|
bool corr_prior_statement_present {false};
|
|
//! Whether there is a options statement present
|
|
bool options_statement_present {false};
|
|
//! Whether there is a std options statement present
|
|
bool std_options_statement_present {false};
|
|
//! Whether there is a corr options statement present
|
|
bool corr_options_statement_present {false};
|
|
//! Whether a Markov Switching DSGE is present
|
|
bool ms_dsge_present {false};
|
|
/* The number of equations in the model present just before adding the
|
|
Lagrange multipliers and computing the Ramsey FOC; it is by construction
|
|
equal to the number of Lagrange multipliers that will be added by the
|
|
process of computing the FOCs. May be greater than the number of equations
|
|
written by the user, because some auxiliary variables may have already
|
|
been added. */
|
|
int ramsey_orig_eq_nbr {0};
|
|
/* The number of endogenous variables in the model present just before adding
|
|
the Lagrange multipliers and computing the Ramsey FOC; it is by
|
|
construction equal to the number of equations that will be added by the
|
|
process of computing the FOCs. May be greater than the number of
|
|
endogenous declared by the user, because some auxiliary variables may have
|
|
already been added. */
|
|
int ramsey_orig_endo_nbr {0};
|
|
//! Whether there was a steady_state_model block
|
|
bool steady_state_model_present {false};
|
|
//! Whether there is a write_latex_steady_state_model statement present
|
|
bool write_latex_steady_state_model_present {false};
|
|
//! Pac growth and discount
|
|
set<int> pac_params;
|
|
//! Instruments if ramsey_model, ramsey_policy or discretionary_policy is present
|
|
SymbolList instruments;
|
|
/* Whether any of shock_decomposition, realtime_shock_decomposition and
|
|
initial_condition_decomposition has the “with_epilogue” option */
|
|
bool with_epilogue_option {false};
|
|
/* Lists symbol IDs of parameters that appear in a “planner_discount” option.
|
|
See dynare#1173 for more details. */
|
|
set<int> parameters_in_planner_discount;
|
|
// Whether an endval block (without the learnt_it=… option) appears
|
|
bool endval_present {false};
|
|
// Whether a shocks(surprise) block appears
|
|
bool shocks_surprise_present {false};
|
|
// Whether a shocks(learnt_in=…) block appears
|
|
bool shocks_learnt_in_present {false};
|
|
// Whether an endval(learnt_in=…) block appears
|
|
bool endval_learnt_in_present {false};
|
|
// Whether an occbin_constraints block appears
|
|
bool occbin_constraints_present {false};
|
|
// Whether a ramsey_constraints block appears
|
|
bool ramsey_constraints_present {false};
|
|
};
|
|
|
|
class Statement
|
|
{
|
|
public:
|
|
Statement() = default;
|
|
virtual ~Statement() = default;
|
|
|
|
Statement(const Statement&) = delete;
|
|
Statement& operator=(const Statement&) = delete;
|
|
|
|
//! Do some internal check, and fill the ModFileStructure class
|
|
/*! Don't forget to update ComputingTasks.hh, Shocks.hh and
|
|
NumericalInitialization.hh if you modify the signature of this
|
|
method. Otherwise the default implementation (i.e. a no-op) will apply and
|
|
some checks won't be run. */
|
|
virtual void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings);
|
|
virtual void computingPass(const ModFileStructure& mod_file_struct);
|
|
//! Write Matlab output code
|
|
/*!
|
|
\param output is the output stream of the main matlab file
|
|
\param basename is the name of the modfile (without extension) which can be used to build
|
|
auxiliary files
|
|
*/
|
|
virtual void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const
|
|
= 0;
|
|
virtual void writeJsonOutput(ostream& output) const = 0;
|
|
};
|
|
|
|
class NativeStatement : public Statement
|
|
{
|
|
private:
|
|
const string native_statement;
|
|
|
|
public:
|
|
explicit NativeStatement(string native_statement_arg);
|
|
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
|
|
void writeJsonOutput(ostream& output) const override;
|
|
};
|
|
|
|
class VerbatimStatement : public Statement
|
|
{
|
|
private:
|
|
const string verbatim_statement;
|
|
|
|
public:
|
|
explicit VerbatimStatement(string verbatim_statement_arg);
|
|
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
|
|
void writeJsonOutput(ostream& output) const override;
|
|
};
|
|
|
|
/* Stores a list of named options with their values.
|
|
The values are stored using an std::variant; see the “options” data member
|
|
for the list of available types. */
|
|
class OptionsList
|
|
{
|
|
public:
|
|
// Some types to lift ambiguities
|
|
struct NumVal : string
|
|
{
|
|
};
|
|
struct StringVal : string
|
|
{
|
|
};
|
|
struct DateVal : string
|
|
{
|
|
};
|
|
struct SymbolListVal : SymbolList
|
|
{
|
|
/* This one is needed because vector<string> implicitly converts to
|
|
SymbolList. Otherwise adding a vector<string> to the variant would add a
|
|
SymbolList, which is probably not the intended meaning. */
|
|
};
|
|
struct VecStrVal : vector<string>
|
|
{
|
|
};
|
|
struct VecCellStrVal : vector<string>
|
|
{
|
|
};
|
|
struct VecValueVal : vector<string>
|
|
{
|
|
};
|
|
|
|
[[nodiscard]] bool empty() const;
|
|
void clear();
|
|
// Whether there is an option with that name that has been given a value
|
|
[[nodiscard]] bool contains(const string& name) const;
|
|
// Erase the option with that name
|
|
void erase(const string& name);
|
|
|
|
/* Declares an option with a name and value. Overwrite any previous value for
|
|
that name. */
|
|
template<class T>
|
|
void
|
|
set(string name, T&& val)
|
|
{
|
|
options.insert_or_assign(move(name), forward<T>(val));
|
|
}
|
|
|
|
struct UnknownOptionException
|
|
{
|
|
const string name;
|
|
UnknownOptionException(string name_arg) : name {move(name_arg)}
|
|
{
|
|
}
|
|
};
|
|
|
|
/* Retrieves the value of the option with that name.
|
|
Throws UnknownOptionException if there is no option with that name.
|
|
Throws bad_variant_access if the option has a value of a different type. */
|
|
template<class T>
|
|
T
|
|
get(const string& name) const
|
|
{
|
|
auto it = options.find(name);
|
|
if (it != options.end())
|
|
return std::get<T>(it->second);
|
|
else
|
|
throw UnknownOptionException {name};
|
|
}
|
|
|
|
/* Retrieves the value of the option with that name.
|
|
Returns nullopt if there is no option with that name.
|
|
Throws bad_variant_access if the option has a value of a different type. */
|
|
template<class T>
|
|
optional<T>
|
|
get_if(const string& name) const
|
|
{
|
|
auto it = options.find(name);
|
|
if (it != options.end())
|
|
return std::get<T>(it->second);
|
|
else
|
|
return nullopt;
|
|
}
|
|
|
|
/* Applies a variant visitor to the value of the option with that name.
|
|
Throws UnknownOptionException if there is no option with that name. */
|
|
template<class Visitor>
|
|
decltype(auto)
|
|
visit(const string& name, Visitor&& vis) const
|
|
{
|
|
auto it = options.find(name);
|
|
if (it != options.end())
|
|
return std::visit(forward<Visitor>(vis), it->second);
|
|
else
|
|
throw UnknownOptionException {name};
|
|
}
|
|
|
|
void writeOutput(ostream& output) const;
|
|
void writeOutput(ostream& output, const string& option_group) const;
|
|
void writeJsonOutput(ostream& output) const;
|
|
|
|
private:
|
|
// pair<string, string> corresponds to a pair of numerical values
|
|
// vector<vector<string>> corresponds to a vector of vectors of numerical values
|
|
map<string, variant<NumVal, pair<string, string>, StringVal, DateVal, SymbolListVal, vector<int>,
|
|
VecStrVal, VecCellStrVal, VecValueVal, vector<vector<string>>>>
|
|
options;
|
|
void writeOutputCommon(ostream& output, const string& option_group) const;
|
|
// Helper constant for visitors
|
|
template<class>
|
|
static constexpr bool always_false_v {false};
|
|
};
|
|
|
|
#endif
|