Compare commits
32 Commits
Author | SHA1 | Date |
---|---|---|
Sébastien Villemot | 5d0ad3f666 | |
Sébastien Villemot | f44155d43a | |
Sébastien Villemot | 4deb397d18 | |
Johannes Pfeifer | 1341963d32 | |
Sébastien Villemot | 7fff5c4c30 | |
Sébastien Villemot | f257b96060 | |
Sébastien Villemot | cac24dad7e | |
Sébastien Villemot | ced586febf | |
Sébastien Villemot | bdbafdc34c | |
Sébastien Villemot | 008a0dbb9e | |
Sébastien Villemot | 0c1a9fa916 | |
Sébastien Villemot | a2977dd07c | |
Sébastien Villemot | 67b8ef1a19 | |
Sébastien Villemot | 8e7dd47a16 | |
Sébastien Villemot | c63d08007c | |
Sébastien Villemot | ff564cbc9a | |
Sébastien Villemot | d430f47616 | |
Sébastien Villemot | 990cee70c2 | |
Johannes Pfeifer | dfed3e98ab | |
Sébastien Villemot | 784b2d6d40 | |
Johannes Pfeifer | 0ccb986da8 | |
Sébastien Villemot | d03b74469a | |
Sébastien Villemot | 37b38b46cc | |
Sébastien Villemot | b1a0ebf513 | |
Sébastien Villemot | 79efd2ec17 | |
Sébastien Villemot | 04e42fa821 | |
Sébastien Villemot | ce43e91b57 | |
Sébastien Villemot | d528467234 | |
Johannes Pfeifer | 4f8713134f | |
Stéphane Adjemian (Charybdis) | 2f2e02e007 | |
Stéphane Adjemian | 0bbba398a1 | |
Sébastien Villemot | 0a6b71a375 |
|
@ -1,6 +1,6 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
dnl Copyright © 2009-2019 Dynare Team
|
||||
dnl Copyright © 2009-2021 Dynare Team
|
||||
dnl
|
||||
dnl This file is part of Dynare.
|
||||
dnl
|
||||
|
@ -18,7 +18,7 @@ dnl You should have received a copy of the GNU General Public License
|
|||
dnl along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
AC_PREREQ([2.62])
|
||||
AC_INIT([dynare-preprocessor], [4.7-unstable])
|
||||
AC_INIT([dynare-preprocessor], [5.0])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_SRCDIR([src/DynareMain.cc])
|
||||
AM_INIT_AUTOMAKE([1.11 -Wall -Wno-portability foreign no-dist-gzip dist-xz tar-pax])
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -335,16 +337,12 @@ PacModelStatement::PacModelStatement(string name_arg,
|
|||
string aux_model_name_arg,
|
||||
string discount_arg,
|
||||
expr_t growth_arg,
|
||||
double steady_state_growth_rate_number_arg,
|
||||
int steady_state_growth_rate_symb_id_arg,
|
||||
const SymbolTable &symbol_table_arg) :
|
||||
name{move(name_arg)},
|
||||
aux_model_name{move(aux_model_name_arg)},
|
||||
discount{move(discount_arg)},
|
||||
growth{growth_arg},
|
||||
original_growth{growth_arg},
|
||||
steady_state_growth_rate_number{steady_state_growth_rate_number_arg},
|
||||
steady_state_growth_rate_symb_id{steady_state_growth_rate_symb_id_arg},
|
||||
symbol_table{symbol_table_arg}
|
||||
{
|
||||
}
|
||||
|
@ -386,12 +384,6 @@ PacModelStatement::writeOutput(ostream &output, const string &basename, bool min
|
|||
{
|
||||
output << "M_.pac." << name << ".auxiliary_model_name = '" << aux_model_name << "';" << endl
|
||||
<< "M_.pac." << name << ".discount_index = " << symbol_table.getTypeSpecificID(discount) + 1 << ";" << endl;
|
||||
if (steady_state_growth_rate_symb_id < 0 && steady_state_growth_rate_number > 0)
|
||||
output << "M_.pac." << name << ".steady_state_growth_rate = "
|
||||
<< steady_state_growth_rate_number << ";" << endl;
|
||||
else if (steady_state_growth_rate_symb_id >= 0)
|
||||
output << "M_.pac." << name << ".steady_state_growth_rate = "
|
||||
<< symbol_table.getTypeSpecificID(steady_state_growth_rate_symb_id) + 1 << ";" << endl;
|
||||
|
||||
if (growth)
|
||||
{
|
||||
|
@ -676,7 +668,7 @@ RamseyConstraintsStatement::RamseyConstraintsStatement(const SymbolTable &symbol
|
|||
void
|
||||
RamseyConstraintsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
|
||||
{
|
||||
if (!mod_file_struct.ramsey_model_present || !mod_file_struct.ramsey_policy_present)
|
||||
if (!mod_file_struct.ramsey_model_present && !mod_file_struct.ramsey_policy_present)
|
||||
cerr << "ramsey_constraints: can only be used with ramsey_model or ramsey_policy" << endl;
|
||||
}
|
||||
|
||||
|
@ -1003,7 +995,7 @@ void
|
|||
OccbinWriteRegimesStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
|
||||
{
|
||||
options_list.writeOutput(output, "options_.occbin");
|
||||
output << "occbin.write_regimes_to_xls(oo_.occbin.regime_history, M_, options_);" << endl;
|
||||
output << "occbin.write_regimes_to_xls(oo_.occbin, M_, options_);" << endl;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1362,16 +1354,94 @@ DsampleStatement::writeJsonOutput(ostream &output) const
|
|||
<< R"("value2": )" << val2 << "}";
|
||||
}
|
||||
|
||||
EstimatedParamsStatement::EstimatedParamsStatement(vector<EstimationParams> estim_params_list_arg,
|
||||
const SymbolTable &symbol_table_arg) :
|
||||
AbstractEstimatedParamsStatement::AbstractEstimatedParamsStatement(vector<EstimationParams> estim_params_list_arg,
|
||||
const SymbolTable &symbol_table_arg) :
|
||||
estim_params_list{move(estim_params_list_arg)},
|
||||
symbol_table{symbol_table_arg}
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AbstractEstimatedParamsStatement::commonCheckPass() const
|
||||
{
|
||||
// Check that no parameter/endogenous is declared twice in the block
|
||||
set<string> already_declared;
|
||||
set<pair<string, string>> already_declared_corr;
|
||||
for (const auto &it : estim_params_list)
|
||||
{
|
||||
if (it.type == 3) // Correlation
|
||||
{
|
||||
// Use lexical ordering for the pair of symbols
|
||||
auto x = it.name < it.name2 ? make_pair(it.name, it.name2) : make_pair(it.name2, it.name);
|
||||
|
||||
if (already_declared_corr.find(x) == already_declared_corr.end())
|
||||
already_declared_corr.insert(x);
|
||||
else
|
||||
{
|
||||
cerr << "ERROR: in `" << blockName() << "' block, the correlation between " << it.name << " and " << it.name2 << " is declared twice." << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (already_declared.find(it.name) == already_declared.end())
|
||||
already_declared.insert(it.name);
|
||||
else
|
||||
{
|
||||
cerr << "ERROR: in `" << blockName() << "' block, the symbol " << it.name << " is declared twice." << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that a parameter declared in this block is not used in expressions
|
||||
associated to other parameters in the same block (see issue #77) */
|
||||
// First compute the symbol IDs of parameters declared in this block
|
||||
set<int> declared_params;
|
||||
for (const string &name : already_declared)
|
||||
if (name != "dsge_prior_weight")
|
||||
declared_params.insert(symbol_table.getID(name));
|
||||
// Then look for (apparently) recursive definitions
|
||||
for (const auto &it : estim_params_list)
|
||||
{
|
||||
set<int> used_params;
|
||||
it.init_val->collectVariables(SymbolType::parameter, used_params);
|
||||
it.low_bound->collectVariables(SymbolType::parameter, used_params);
|
||||
it.up_bound->collectVariables(SymbolType::parameter, used_params);
|
||||
it.mean->collectVariables(SymbolType::parameter, used_params);
|
||||
it.std->collectVariables(SymbolType::parameter, used_params);
|
||||
it.p3->collectVariables(SymbolType::parameter, used_params);
|
||||
it.p4->collectVariables(SymbolType::parameter, used_params);
|
||||
it.jscale->collectVariables(SymbolType::parameter, used_params);
|
||||
vector<int> intersect;
|
||||
set_intersection(declared_params.begin(), declared_params.end(),
|
||||
used_params.begin(), used_params.end(),
|
||||
back_inserter(intersect));
|
||||
if (intersect.size() > 0)
|
||||
{
|
||||
cerr << "ERROR: in `" << blockName() << "' block, the value of estimated parameter "
|
||||
<< symbol_table.getName(intersect[0]) << " is used in the declaration for ";
|
||||
if (it.type == 3)
|
||||
cerr << "correlation between " << it.name << " and " << it.name2;
|
||||
else // either a parameter, the stderr of an exo, or the measurement error of an endo
|
||||
cerr << "symbol " << it.name;
|
||||
cerr << ". This behaviour is undefined." << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EstimatedParamsStatement::EstimatedParamsStatement(vector<EstimationParams> estim_params_list_arg,
|
||||
const SymbolTable &symbol_table_arg) :
|
||||
AbstractEstimatedParamsStatement(move(estim_params_list_arg), symbol_table_arg)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
EstimatedParamsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
|
||||
{
|
||||
commonCheckPass();
|
||||
|
||||
for (const auto &it : estim_params_list)
|
||||
{
|
||||
if (it.name == "dsge_prior_weight")
|
||||
|
@ -1394,36 +1464,6 @@ EstimatedParamsStatement::checkPass(ModFileStructure &mod_file_struct, WarningCo
|
|||
}
|
||||
}
|
||||
|
||||
// Check that no parameter/endogenous is declared twice in the block
|
||||
set<string> already_declared;
|
||||
set<pair<string, string>> already_declared_corr;
|
||||
for (const auto &it : estim_params_list)
|
||||
{
|
||||
if (it.type == 3) // Correlation
|
||||
{
|
||||
// Use lexical ordering for the pair of symbols
|
||||
auto x = it.name < it.name2 ? pair(it.name, it.name2) : pair(it.name2, it.name);
|
||||
|
||||
if (already_declared_corr.find(x) == already_declared_corr.end())
|
||||
already_declared_corr.insert(x);
|
||||
else
|
||||
{
|
||||
cerr << "ERROR: in `estimated_params' block, the correlation between " << it.name << " and " << it.name2 << " is declared twice." << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (already_declared.find(it.name) == already_declared.end())
|
||||
already_declared.insert(it.name);
|
||||
else
|
||||
{
|
||||
cerr << "ERROR: in `estimated_params' block, the symbol " << it.name << " is declared twice." << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in mod_file_struct.estimated_parameters (related to #469)
|
||||
for (const auto &it : estim_params_list)
|
||||
if (it.type == 2 && it.name != "dsge_prior_weight")
|
||||
|
@ -1537,8 +1577,7 @@ EstimatedParamsStatement::writeJsonOutput(ostream &output) const
|
|||
EstimatedParamsInitStatement::EstimatedParamsInitStatement(vector<EstimationParams> estim_params_list_arg,
|
||||
const SymbolTable &symbol_table_arg,
|
||||
const bool use_calibration_arg) :
|
||||
estim_params_list{move(estim_params_list_arg)},
|
||||
symbol_table{symbol_table_arg},
|
||||
AbstractEstimatedParamsStatement(move(estim_params_list_arg), symbol_table_arg),
|
||||
use_calibration{use_calibration_arg}
|
||||
{
|
||||
}
|
||||
|
@ -1546,6 +1585,8 @@ EstimatedParamsInitStatement::EstimatedParamsInitStatement(vector<EstimationPara
|
|||
void
|
||||
EstimatedParamsInitStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
|
||||
{
|
||||
commonCheckPass();
|
||||
|
||||
if (use_calibration)
|
||||
mod_file_struct.estim_params_use_calib = true;
|
||||
}
|
||||
|
@ -1675,11 +1716,16 @@ EstimatedParamsInitStatement::writeJsonOutput(ostream &output) const
|
|||
|
||||
EstimatedParamsBoundsStatement::EstimatedParamsBoundsStatement(vector<EstimationParams> estim_params_list_arg,
|
||||
const SymbolTable &symbol_table_arg) :
|
||||
estim_params_list{move(estim_params_list_arg)},
|
||||
symbol_table{symbol_table_arg}
|
||||
AbstractEstimatedParamsStatement(move(estim_params_list_arg), symbol_table_arg)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
EstimatedParamsBoundsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
|
||||
{
|
||||
commonCheckPass();
|
||||
}
|
||||
|
||||
void
|
||||
EstimatedParamsBoundsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
|
||||
{
|
||||
|
@ -2346,7 +2392,7 @@ PlannerObjectiveStatement::checkPass(ModFileStructure &mod_file_struct, WarningC
|
|||
assert(model_tree.equation_number() == 1);
|
||||
if (model_tree.exoPresentInEqs())
|
||||
{
|
||||
cerr << "ERROR: You cannot include exogenous variables in the planner objective. Please "
|
||||
cerr << "ERROR: You cannot include exogenous variables (or variables of undeclared type) in the planner objective. Please "
|
||||
<< "define an auxiliary endogenous variable like eps_aux=epsilon and use it instead "
|
||||
<< "of the varexo." << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -4965,7 +5011,7 @@ MethodOfMomentsStatement::writeOutput(ostream &output, const string &basename, b
|
|||
{
|
||||
options_list.writeOutput(output, "options_mom_");
|
||||
|
||||
output << "[oo_, options_mom_, M_] = method_of_moments(bayestopt_, options_, oo_, estim_params_, M_, options_mom_);" << endl;
|
||||
output << "[oo_, options_mom_, M_] = mom.run(bayestopt_, options_, oo_, estim_params_, M_, options_mom_);" << endl;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -146,8 +146,6 @@ public:
|
|||
const string name, aux_model_name, discount;
|
||||
expr_t growth, original_growth;
|
||||
private:
|
||||
const double steady_state_growth_rate_number;
|
||||
const int steady_state_growth_rate_symb_id;
|
||||
const SymbolTable &symbol_table;
|
||||
vector<tuple<int, int, int, double>> growth_info;
|
||||
public:
|
||||
|
@ -155,8 +153,6 @@ public:
|
|||
string aux_model_name_arg,
|
||||
string discount_arg,
|
||||
expr_t growth_arg,
|
||||
double steady_state_growth_rate_number_arg,
|
||||
int steady_state_growth_rate_symb_id_arg,
|
||||
const SymbolTable &symbol_table_arg);
|
||||
void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override;
|
||||
void overwriteGrowth(expr_t new_growth);
|
||||
|
@ -511,42 +507,50 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class EstimatedParamsStatement : public Statement
|
||||
class AbstractEstimatedParamsStatement : public Statement
|
||||
{
|
||||
private:
|
||||
protected:
|
||||
const vector<EstimationParams> estim_params_list;
|
||||
const SymbolTable &symbol_table;
|
||||
AbstractEstimatedParamsStatement(vector<EstimationParams> estim_params_list_arg,
|
||||
const SymbolTable &symbol_table_arg);
|
||||
virtual string blockName() const = 0;
|
||||
// Part of the check pass that is common to the three estimated_params* blocks
|
||||
void commonCheckPass() const;
|
||||
};
|
||||
|
||||
class EstimatedParamsStatement : public AbstractEstimatedParamsStatement
|
||||
{
|
||||
public:
|
||||
EstimatedParamsStatement(vector<EstimationParams> estim_params_list_arg,
|
||||
const SymbolTable &symbol_table_arg);
|
||||
string blockName() const override { return "estimated_params"; };
|
||||
void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override;
|
||||
void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
|
||||
void writeJsonOutput(ostream &output) const override;
|
||||
};
|
||||
|
||||
class EstimatedParamsInitStatement : public Statement
|
||||
class EstimatedParamsInitStatement : public AbstractEstimatedParamsStatement
|
||||
{
|
||||
private:
|
||||
const vector<EstimationParams> estim_params_list;
|
||||
const SymbolTable &symbol_table;
|
||||
const bool use_calibration;
|
||||
public:
|
||||
EstimatedParamsInitStatement(vector<EstimationParams> estim_params_list_arg,
|
||||
const SymbolTable &symbol_table_arg,
|
||||
const bool use_calibration_arg);
|
||||
string blockName() const override { return "estimated_params_init"; };
|
||||
void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override;
|
||||
void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
|
||||
void writeJsonOutput(ostream &output) const override;
|
||||
};
|
||||
|
||||
class EstimatedParamsBoundsStatement : public Statement
|
||||
class EstimatedParamsBoundsStatement : public AbstractEstimatedParamsStatement
|
||||
{
|
||||
private:
|
||||
const vector<EstimationParams> estim_params_list;
|
||||
const SymbolTable &symbol_table;
|
||||
public:
|
||||
EstimatedParamsBoundsStatement(vector<EstimationParams> estim_params_list_arg,
|
||||
const SymbolTable &symbol_table_arg);
|
||||
string blockName() const override { return "estimated_params_bounds"; };
|
||||
void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override;
|
||||
void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
|
||||
void writeJsonOutput(ostream &output) const override;
|
||||
};
|
||||
|
|
|
@ -114,6 +114,7 @@ DynamicModel::DynamicModel(const DynamicModel &m) :
|
|||
pac_h1_indices{m.pac_h1_indices},
|
||||
pac_mce_z1_symb_ids{m.pac_mce_z1_symb_ids},
|
||||
pac_eqtag_and_lag{m.pac_eqtag_and_lag},
|
||||
pac_growth_neutrality_params{m.pac_growth_neutrality_params},
|
||||
pac_model_info{m.pac_model_info},
|
||||
pac_equation_info{m.pac_equation_info}
|
||||
{
|
||||
|
@ -178,6 +179,7 @@ DynamicModel::operator=(const DynamicModel &m)
|
|||
pac_mce_z1_symb_ids = m.pac_mce_z1_symb_ids;
|
||||
pac_eqtag_and_lag = m.pac_eqtag_and_lag;
|
||||
pac_expectation_substitution.clear();
|
||||
pac_growth_neutrality_params = m.pac_growth_neutrality_params;
|
||||
pac_model_info = m.pac_model_info;
|
||||
pac_equation_info = m.pac_equation_info;
|
||||
|
||||
|
@ -3033,20 +3035,19 @@ DynamicModel::writeDriverOutput(ostream &output, const string &basename, bool bl
|
|||
output << "];" << endl;
|
||||
}
|
||||
|
||||
for (auto &it : pac_model_info)
|
||||
for (auto &[model, growth_neutrality_param_index] : pac_growth_neutrality_params)
|
||||
output << "M_.pac." << model << ".growth_neutrality_param_index = "
|
||||
<< symbol_table.getTypeSpecificID(growth_neutrality_param_index) + 1 << ";" << endl;
|
||||
|
||||
for (auto &[model, values] : pac_model_info)
|
||||
{
|
||||
vector<int> lhs = get<0>(it.second);
|
||||
output << "M_.pac." << it.first << ".lhs = [";
|
||||
auto &[lhs, aux_model_type] = values;
|
||||
output << "M_.pac." << model << ".lhs = [";
|
||||
for (auto it : lhs)
|
||||
output << it + 1 << " ";
|
||||
output << "];" << endl;
|
||||
|
||||
if (int growth_param_index = get<1>(it.second);
|
||||
growth_param_index >= 0)
|
||||
output << "M_.pac." << it.first << ".growth_neutrality_param_index = "
|
||||
<< symbol_table.getTypeSpecificID(growth_param_index) + 1 << ";" << endl;
|
||||
|
||||
output << "M_.pac." << it.first << ".auxiliary_model_type = '" << get<2>(it.second) << "';" << endl;
|
||||
output << "M_.pac." << model << ".auxiliary_model_type = '" << aux_model_type << "';" << endl;
|
||||
}
|
||||
|
||||
for (auto &pit : pac_equation_info)
|
||||
|
@ -4066,7 +4067,8 @@ DynamicModel::declarePacModelConsistentExpectationEndogs(const string &name)
|
|||
void
|
||||
DynamicModel::addPacModelConsistentExpectationEquation(const string &name, int discount_symb_id,
|
||||
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
|
||||
ExprNode::subst_table_t &diff_subst_table)
|
||||
ExprNode::subst_table_t &diff_subst_table,
|
||||
expr_t growth)
|
||||
{
|
||||
int pac_target_symb_id;
|
||||
try
|
||||
|
@ -4189,11 +4191,31 @@ DynamicModel::addPacModelConsistentExpectationEquation(const string &name, int d
|
|||
AddMinus(AddTimes(A, AddMinus(const_cast<VariableNode *>(target_base_diff_node), fs)), fp));
|
||||
addEquation(neweq, -1);
|
||||
neqs++;
|
||||
pac_expectation_substitution[{name, eqtag}] = AddVariable(mce_z1_symb_id);
|
||||
/* The growth correction term is not added to the definition of Z₁
|
||||
because the latter is recursive. Rather put it at the level of the
|
||||
substition of pac_expectation operator. */
|
||||
expr_t growth_correction = growth ? AddTimes(AddVariable(pac_growth_neutrality_params.at(name)), growth) : Zero;
|
||||
pac_expectation_substitution[{name, eqtag}] = AddPlus(AddVariable(mce_z1_symb_id), growth_correction);
|
||||
}
|
||||
cout << "Pac Model Consistent Expectation: added " << neqs << " auxiliary variables and equations for model " << name << "." << endl;
|
||||
}
|
||||
|
||||
void
|
||||
DynamicModel::createPacGrowthNeutralityParameter(const string &pac_model_name)
|
||||
{
|
||||
string param_name = pac_model_name + "_pac_growth_neutrality_correction";
|
||||
try
|
||||
{
|
||||
int param_idx = symbol_table.addSymbol(param_name, SymbolType::parameter);
|
||||
pac_growth_neutrality_params[pac_model_name] = param_idx;
|
||||
}
|
||||
catch (SymbolTable::AlreadyDeclaredException)
|
||||
{
|
||||
cerr << "The parameter '" << param_name << "' conflicts with the auxiliary parameter that will be generated for the growth neutrality correction of the '" << pac_model_name << "' PAC model. Please rename that parameter." << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DynamicModel::fillPacModelInfo(const string &pac_model_name,
|
||||
vector<int> lhs,
|
||||
|
@ -4208,12 +4230,6 @@ DynamicModel::fillPacModelInfo(const string &pac_model_name,
|
|||
bool stationary_vars_present = any_of(nonstationary.begin(), nonstationary.end(), logical_not<bool>());
|
||||
bool nonstationary_vars_present = any_of(nonstationary.begin(), nonstationary.end(), [](bool b) { return b; }); // FIXME: use std::identity instead of an anonymous function when we upgrade to C++20
|
||||
|
||||
int growth_param_index = -1;
|
||||
if (growth)
|
||||
growth_param_index = symbol_table.addSymbol(pac_model_name
|
||||
+"_pac_growth_neutrality_correction",
|
||||
SymbolType::parameter);
|
||||
|
||||
for (auto pac_models_and_eqtags : pac_eqtag_and_lag)
|
||||
{
|
||||
if (pac_models_and_eqtags.first.first != pac_model_name)
|
||||
|
@ -4276,12 +4292,15 @@ DynamicModel::fillPacModelInfo(const string &pac_model_name,
|
|||
}
|
||||
|
||||
if (growth)
|
||||
subExpr = AddPlus(subExpr,
|
||||
AddTimes(AddVariable(growth_param_index), growth));
|
||||
{
|
||||
int growth_param_index = pac_growth_neutrality_params.at(pac_model_name);
|
||||
subExpr = AddPlus(subExpr,
|
||||
AddTimes(AddVariable(growth_param_index), growth));
|
||||
}
|
||||
|
||||
pac_expectation_substitution[{pac_model_name, eqtag}] = subExpr;
|
||||
}
|
||||
pac_model_info[pac_model_name] = {move(lhs), growth_param_index, move(aux_model_type)};
|
||||
pac_model_info[pac_model_name] = {move(lhs), move(aux_model_type)};
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4904,6 +4923,8 @@ DynamicModel::findUnusedEndogenous()
|
|||
set<int> usedEndo, unusedEndo;
|
||||
for (auto &equation : equations)
|
||||
equation->collectVariables(SymbolType::endogenous, usedEndo);
|
||||
for (auto &equation : static_only_equations)
|
||||
equation->collectVariables(SymbolType::endogenous, usedEndo);
|
||||
set<int> allEndo = symbol_table.getEndogenous();
|
||||
set_difference(allEndo.begin(), allEndo.end(),
|
||||
usedEndo.begin(), usedEndo.end(),
|
||||
|
@ -4917,6 +4938,8 @@ DynamicModel::findUnusedExogenous()
|
|||
set<int> usedExo, unusedExo, unobservedExo;
|
||||
for (auto &equation : equations)
|
||||
equation->collectVariables(SymbolType::exogenous, usedExo);
|
||||
for (auto &equation : static_only_equations)
|
||||
equation->collectVariables(SymbolType::exogenous, usedExo);
|
||||
set<int> observedExo = symbol_table.getObservedExogenous();
|
||||
set<int> allExo = symbol_table.getExogenous();
|
||||
set_difference(allExo.begin(), allExo.end(),
|
||||
|
@ -5658,6 +5681,9 @@ DynamicModel::substituteModelLocalVariables()
|
|||
for (auto &equation : equations)
|
||||
equation = dynamic_cast<BinaryOpNode *>(equation->substituteModelLocalVariables());
|
||||
|
||||
for (auto &equation : static_only_equations)
|
||||
equation = dynamic_cast<BinaryOpNode *>(equation->substituteModelLocalVariables());
|
||||
|
||||
/* We can’t clear local_variables_table at this point, because in case of
|
||||
ramsey_policy, the original model is saved via DynamicModel::operator=()
|
||||
before computing the FOC. But since DataTree::operator=() clones all
|
||||
|
@ -5869,18 +5895,28 @@ DynamicModel::detrendEquations()
|
|||
// We go backwards in the list of trend_vars, to deal correctly with I(2) processes
|
||||
for (auto it = nonstationary_symbols_map.crbegin();
|
||||
it != nonstationary_symbols_map.crend(); ++it)
|
||||
for (auto &equation : equations)
|
||||
{
|
||||
auto substeq = dynamic_cast<BinaryOpNode *>(equation->detrend(it->first, it->second.first, it->second.second));
|
||||
assert(substeq);
|
||||
equation = dynamic_cast<BinaryOpNode *>(substeq);
|
||||
}
|
||||
{
|
||||
for (auto &equation : equations)
|
||||
{
|
||||
equation = dynamic_cast<BinaryOpNode *>(equation->detrend(it->first, it->second.first, it->second.second));
|
||||
assert(equation);
|
||||
}
|
||||
for (auto &equation : static_only_equations)
|
||||
{
|
||||
equation = dynamic_cast<BinaryOpNode *>(equation->detrend(it->first, it->second.first, it->second.second));
|
||||
assert(equation);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &equation : equations)
|
||||
{
|
||||
auto substeq = dynamic_cast<BinaryOpNode *>(equation->removeTrendLeadLag(trend_symbols_map));
|
||||
assert(substeq);
|
||||
equation = dynamic_cast<BinaryOpNode *>(substeq);
|
||||
equation = dynamic_cast<BinaryOpNode *>(equation->removeTrendLeadLag(trend_symbols_map));
|
||||
assert(equation);
|
||||
}
|
||||
for (auto &equation : static_only_equations)
|
||||
{
|
||||
equation = dynamic_cast<BinaryOpNode *>(equation->removeTrendLeadLag(trend_symbols_map));
|
||||
assert(equation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5889,9 +5925,13 @@ DynamicModel::removeTrendVariableFromEquations()
|
|||
{
|
||||
for (auto &equation : equations)
|
||||
{
|
||||
auto substeq = dynamic_cast<BinaryOpNode *>(equation->replaceTrendVar());
|
||||
assert(substeq);
|
||||
equation = dynamic_cast<BinaryOpNode *>(substeq);
|
||||
equation = dynamic_cast<BinaryOpNode *>(equation->replaceTrendVar());
|
||||
assert(equation);
|
||||
}
|
||||
for (auto &equation : static_only_equations)
|
||||
{
|
||||
equation = dynamic_cast<BinaryOpNode *>(equation->replaceTrendVar());
|
||||
assert(equation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -134,13 +134,16 @@ private:
|
|||
//! Store lag info for pac equations
|
||||
//! (pac_model_name, equation_tag) -> (standardized_eqtag, lag)
|
||||
map<pair<string, string>, pair<string, int>> pac_eqtag_and_lag;
|
||||
// Store indices for growth neutrality parameters
|
||||
// pac_model_name -> growth_param_index
|
||||
map<string, int> pac_growth_neutrality_params;
|
||||
|
||||
//! (pac_model_name, equation_tag) -> expr_t
|
||||
map<pair<string, string>, expr_t> pac_expectation_substitution;
|
||||
|
||||
//! Store info about pac models:
|
||||
//! pac_model_name -> (lhsvars, growth_param_index, aux_model_type)
|
||||
map<string, tuple<vector<int>, int, string>> pac_model_info;
|
||||
//! Store info about backward PAC models:
|
||||
//! pac_model_name -> (lhsvars, aux_model_type)
|
||||
map<string, pair<vector<int>, string>> pac_model_info;
|
||||
|
||||
//! Store info about pac models specific to the equation they appear in
|
||||
//! (pac_model_name, standardized_eqtag) ->
|
||||
|
@ -414,7 +417,14 @@ public:
|
|||
|
||||
//! Get Pac equation parameter info
|
||||
map<pair<string, string>, pair<string, int>> walkPacParameters(const string &name);
|
||||
|
||||
// Create the growth neutrality parameter of a given PAC model (when the
|
||||
// “growth” option has been passed)
|
||||
void createPacGrowthNeutralityParameter(const string &pac_model_name);
|
||||
|
||||
//! Add var_model info to pac_expectation nodes
|
||||
// Must be called after createPacGrowthNeutralityParameter() has been called
|
||||
// on the relevant models
|
||||
void fillPacModelInfo(const string &pac_model_name,
|
||||
vector<int> lhs,
|
||||
int max_lag,
|
||||
|
@ -572,7 +582,7 @@ public:
|
|||
//! Add model consistent expectation equation for pac model
|
||||
void addPacModelConsistentExpectationEquation(const string &name, int discount,
|
||||
const map<pair<string, string>, pair<string, int>> &eqtag_and_lag,
|
||||
ExprNode::subst_table_t &diff_subst_table);
|
||||
ExprNode::subst_table_t &diff_subst_table, expr_t growth);
|
||||
|
||||
//! Table to undiff LHS variables for pac vector z
|
||||
vector<int> getUndiffLHSForPac(const string &aux_model_name,
|
||||
|
|
|
@ -96,7 +96,7 @@ class ParsingDriver;
|
|||
%token LAPLACE LIK_ALGO LIK_INIT LINEAR LINEAR_DECOMPOSITION LOAD_IDENT_FILES LOAD_MH_FILE LOAD_RESULTS_AFTER_LOAD_MH LOAD_PARAMS_AND_STEADY_STATE LOGLINEAR LOGDATA LYAPUNOV LINEAR_APPROXIMATION
|
||||
%token LYAPUNOV_COMPLEX_THRESHOLD LYAPUNOV_FIXED_POINT_TOL LYAPUNOV_DOUBLING_TOL LOG_DEFLATOR LOG_TREND_VAR LOG_GROWTH_FACTOR
|
||||
%token MATCHED_MOMENTS MARKOWITZ MARGINAL_DENSITY MAX MAXIT
|
||||
%token MFS MH_CONF_SIG MH_DROP MH_INIT_SCALE MH_JSCALE MH_TUNE_JSCALE MH_TUNE_GUESS MH_MODE MH_NBLOCKS MH_REPLIC MH_RECOVER MH_INITIALIZE_FROM_PREVIOUS_MCMC MH_INITIALIZE_FROM_PREVIOUS_MCMC_DIRECTORY MH_INITIALIZE_FROM_PREVIOUS_MCMC_RECORD MH_INITIALIZE_FROM_PREVIOUS_MCMC_PRIOR
|
||||
%token MFS MH_CONF_SIG MH_DROP MH_INIT_SCALE MH_JSCALE MH_TUNE_JSCALE MH_TUNE_GUESS MH_POSTERIOR_MODE_ESTIMATION MH_NBLOCKS MH_REPLIC MH_RECOVER MH_INITIALIZE_FROM_PREVIOUS_MCMC MH_INITIALIZE_FROM_PREVIOUS_MCMC_DIRECTORY MH_INITIALIZE_FROM_PREVIOUS_MCMC_RECORD MH_INITIALIZE_FROM_PREVIOUS_MCMC_PRIOR
|
||||
%token POSTERIOR_MAX_SUBSAMPLE_DRAWS MIN MINIMAL_SOLVING_PERIODS
|
||||
%token MODE_CHECK MODE_CHECK_NEIGHBOURHOOD_SIZE MODE_CHECK_SYMMETRIC_PLOTS MODE_CHECK_NUMBER_OF_POINTS MODE_COMPUTE MODE_FILE MODEL MODEL_COMPARISON MODEL_INFO MSHOCKS ABS SIGN
|
||||
%token MODEL_DIAGNOSTICS MODIFIEDHARMONICMEAN MOMENTS_VARENDO CONTEMPORANEOUS_CORRELATION DIFFUSE_FILTER SUB_DRAWS TAPER_STEPS GEWEKE_INTERVAL RAFTERY_LEWIS_QRS RAFTERY_LEWIS_DIAGNOSTICS MCMC_JUMPING_COVARIANCE MOMENT_CALIBRATION
|
||||
|
@ -120,10 +120,11 @@ class ParsingDriver;
|
|||
%token STDERR STEADY STOCH_SIMUL SYLVESTER SYLVESTER_FIXED_POINT_TOL REGIMES REGIME REALTIME_SHOCK_DECOMPOSITION CONDITIONAL UNCONDITIONAL
|
||||
%token TEX RAMSEY_MODEL RAMSEY_POLICY RAMSEY_CONSTRAINTS PLANNER_DISCOUNT PLANNER_DISCOUNT_LATEX_NAME
|
||||
%token DISCRETIONARY_POLICY DISCRETIONARY_TOL EVALUATE_PLANNER_OBJECTIVE
|
||||
%token OCCBIN_SETUP OCCBIN_SOLVER OCCBIN_WRITE_REGIMES OCCBIN_GRAPH SIMUL_MAXIT SMOOTHER_MAXIT SIMUL_PERIODS SMOOTHER_PERIODS SIMUL_CURB_RETRENCH SMOOTHER_CURB_RETRENCH SIMUL_CHECK_AHEAD_PERIODS SMOOTHER_CHECK_AHEAD_PERIODS
|
||||
%token SIMUL_DEBUG SMOOTHER_DEBUG
|
||||
%token OCCBIN_SETUP OCCBIN_SOLVER OCCBIN_WRITE_REGIMES OCCBIN_GRAPH SIMUL_MAXIT LIKELIHOOD_MAXIT SMOOTHER_MAXIT SIMUL_PERIODS LIKELIHOOD_PERIODS SMOOTHER_PERIODS
|
||||
%token SIMUL_CURB_RETRENCH LIKELIHOOD_CURB_RETRENCH SMOOTHER_CURB_RETRENCH SIMUL_CHECK_AHEAD_PERIODS LIKELIHOOD_CHECK_AHEAD_PERIODS SMOOTHER_CHECK_AHEAD_PERIODS
|
||||
%token SIMUL_DEBUG SMOOTHER_DEBUG SIMUL_PERIODIC_SOLUTION LIKELIHOOD_PERIODIC_SOLUTION SMOOTHER_PERIODIC_SOLUTION
|
||||
%token LIKELIHOOD_INVERSION_FILTER SMOOTHER_INVERSION_FILTER FILTER_USE_RELEXATION
|
||||
%token LIKELIHOOD_PIECEWISE_KALMAN_FILTER SMOOTHER_PIECEWISE_KALMAN_FILTER
|
||||
%token LIKELIHOOD_PIECEWISE_KALMAN_FILTER SMOOTHER_PIECEWISE_KALMAN_FILTER LIKELIHOOD_MAX_KALMAN_ITERATIONS
|
||||
%token <string> TEX_NAME TRUE BIND RELAX ERROR_BIND ERROR_RELAX
|
||||
%token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL USEAUTOCORR GSA_SAMPLE_FILE USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED
|
||||
%token VALUES SCALES VAR VAREXO VAREXO_DET VARIABLE VAROBS VAREXOBS PREDETERMINED_VARIABLES VAR_EXPECTATION VAR_EXPECTATION_MODEL PLOT_SHOCK_DECOMPOSITION MODEL_LOCAL_VARIABLE
|
||||
|
@ -177,7 +178,7 @@ class ParsingDriver;
|
|||
%token METHOD_OF_MOMENTS MOM_METHOD
|
||||
%token BARTLETT_KERNEL_LAG WEIGHTING_MATRIX WEIGHTING_MATRIX_SCALING_FACTOR ANALYTIC_STANDARD_ERRORS ANALYTIC_JACOBIAN PENALIZED_ESTIMATOR VERBOSE
|
||||
%token SIMULATION_MULTIPLE MOM_SEED SEED BOUNDED_SHOCK_SUPPORT ADDITIONAL_OPTIMIZER_STEPS MOM_SE_TOLX SE_TOLX MOM_BURNIN BURNIN
|
||||
%token EQTAGS STEADY_STATE_GROWTH
|
||||
%token EQTAGS
|
||||
%token ANALYTICAL_GIRF IRF_IN_PERCENT EMAS_GIRF EMAS_DROP EMAS_TOLF EMAS_MAX_ITER
|
||||
%token NO_IDENTIFICATION_STRENGTH NO_IDENTIFICATION_REDUCEDFORM NO_IDENTIFICATION_MOMENTS
|
||||
%token NO_IDENTIFICATION_MINIMAL NO_IDENTIFICATION_SPECTRUM NORMALIZE_JACOBIANS GRID_NBR
|
||||
|
@ -428,7 +429,6 @@ pac_model_options : o_pac_name
|
|||
| o_pac_aux_model_name
|
||||
| o_pac_discount
|
||||
| o_pac_growth
|
||||
| o_pac_steady_state_growth
|
||||
;
|
||||
|
||||
var_expectation_model : VAR_EXPECTATION_MODEL '(' var_expectation_model_options_list ')' ';'
|
||||
|
@ -2085,7 +2085,7 @@ estimation_options : o_datafile
|
|||
| o_mode_check_symmetric_plots
|
||||
| o_mode_check_number_of_points
|
||||
| o_prior_trunc
|
||||
| o_mh_mode
|
||||
| o_mh_posterior_mode_estimation
|
||||
| o_mh_nblocks
|
||||
| o_load_mh_file
|
||||
| o_load_results_after_load_mh
|
||||
|
@ -2470,15 +2470,23 @@ occbin_setup_option : o_occbin_simul_periods
|
|||
| o_occbin_simul_maxit
|
||||
| o_occbin_simul_curb_retrench
|
||||
| o_occbin_simul_check_ahead_periods
|
||||
| o_occbin_simul_periodic_solution
|
||||
| o_occbin_simul_debug
|
||||
| o_occbin_likelihood_periods
|
||||
| o_occbin_likelihood_maxit
|
||||
| o_occbin_likelihood_curb_retrench
|
||||
| o_occbin_likelihood_check_ahead_periods
|
||||
| o_occbin_likelihood_periodic_solution
|
||||
| o_occbin_likelihood_max_kalman_iterations
|
||||
| o_occbin_likelihood_inversion_filter
|
||||
| o_occbin_likelihood_piecewise_kalman_filter
|
||||
| o_occbin_smoother_inversion_filter
|
||||
| o_occbin_smoother_piecewise_kalman_filter
|
||||
| o_occbin_smoother_periods
|
||||
| o_occbin_smoother_maxit
|
||||
| o_occbin_smoother_curb_retrench
|
||||
| o_occbin_smoother_check_ahead_periods
|
||||
| o_occbin_smoother_periodic_solution
|
||||
| o_occbin_smoother_inversion_filter
|
||||
| o_occbin_smoother_piecewise_kalman_filter
|
||||
| o_occbin_smoother_debug
|
||||
| o_occbin_filter_use_relaxation
|
||||
;
|
||||
|
@ -2499,7 +2507,8 @@ occbin_solver_option : o_occbin_simul_periods
|
|||
| o_occbin_simul_curb_retrench
|
||||
| o_occbin_simul_check_ahead_periods
|
||||
| o_occbin_simul_debug
|
||||
;
|
||||
| o_occbin_simul_periodic_solution
|
||||
;
|
||||
|
||||
occbin_write_regimes : OCCBIN_WRITE_REGIMES ';'
|
||||
{ driver.occbin_write_regimes(); }
|
||||
|
@ -2512,6 +2521,8 @@ occbin_write_regimes_options_list : occbin_write_regimes_option COMMA occbin_wri
|
|||
|
||||
occbin_write_regimes_option : o_occbin_write_regimes_periods
|
||||
| o_occbin_write_regimes_filename
|
||||
| o_occbin_write_regimes_smoother
|
||||
| o_occbin_write_regimes_simul
|
||||
;
|
||||
|
||||
occbin_graph : OCCBIN_GRAPH ';'
|
||||
|
@ -3399,9 +3410,6 @@ o_pac_name : MODEL_NAME EQUAL symbol { driver.option_str("pac.model_name", $3);
|
|||
o_pac_aux_model_name : AUXILIARY_MODEL_NAME EQUAL symbol { driver.option_str("pac.aux_model_name", $3); };
|
||||
o_pac_discount : DISCOUNT EQUAL symbol { driver.option_str("pac.discount", $3); };
|
||||
o_pac_growth : GROWTH { driver.begin_pac_growth(); } EQUAL hand_side { driver.set_pac_growth($4); };
|
||||
o_pac_steady_state_growth : STEADY_STATE_GROWTH EQUAL signed_number { driver.set_pac_steady_state_growth($3); }
|
||||
| STEADY_STATE_GROWTH EQUAL symbol { driver.set_pac_steady_state_growth($3); }
|
||||
;
|
||||
o_var_name : MODEL_NAME EQUAL symbol { driver.option_str("var.model_name", $3); };
|
||||
o_series : SERIES EQUAL symbol { driver.option_str("series", $3); };
|
||||
o_datafile : DATAFILE EQUAL filename { driver.option_str("datafile", $3); };
|
||||
|
@ -3549,7 +3557,7 @@ o_mode_check_neighbourhood_size : MODE_CHECK_NEIGHBOURHOOD_SIZE EQUAL signed_num
|
|||
o_mode_check_number_of_points : MODE_CHECK_NUMBER_OF_POINTS EQUAL INT_NUMBER { driver.option_num("mode_check.number_of_points", $3); };
|
||||
o_mode_check_symmetric_plots : MODE_CHECK_SYMMETRIC_PLOTS EQUAL INT_NUMBER { driver.option_num("mode_check.symmetric_plots", $3); };
|
||||
o_prior_trunc : PRIOR_TRUNC EQUAL non_negative_number { driver.option_num("prior_trunc", $3); };
|
||||
o_mh_mode : MH_MODE EQUAL INT_NUMBER { driver.option_num("mh_mode", $3); };
|
||||
o_mh_posterior_mode_estimation : MH_POSTERIOR_MODE_ESTIMATION { driver.option_num("mh_posterior_mode_estimation", "true"); };
|
||||
o_mh_nblocks : MH_NBLOCKS EQUAL INT_NUMBER { driver.option_num("mh_nblck", $3); };
|
||||
o_load_mh_file : LOAD_MH_FILE { driver.option_num("load_mh_file", "true"); };
|
||||
o_load_results_after_load_mh : LOAD_RESULTS_AFTER_LOAD_MH { driver.option_num("load_results_after_load_mh", "true"); };
|
||||
|
@ -4033,18 +4041,26 @@ o_occbin_simul_periods : SIMUL_PERIODS EQUAL INT_NUMBER { driver.option_num("sim
|
|||
o_occbin_simul_curb_retrench : SIMUL_CURB_RETRENCH { driver.option_num("simul.curb_retrench", "true"); };
|
||||
o_occbin_simul_check_ahead_periods : SIMUL_CHECK_AHEAD_PERIODS EQUAL INT_NUMBER { driver.option_num("simul.check_ahead_periods", $3); };
|
||||
o_occbin_simul_debug : SIMUL_DEBUG { driver.option_num("simul.debug", "true"); };
|
||||
o_occbin_simul_periodic_solution : SIMUL_PERIODIC_SOLUTION { driver.option_num("simul.periodic_solution", "true"); };
|
||||
|
||||
// Some options to "occbin_setup"
|
||||
o_occbin_likelihood_inversion_filter : LIKELIHOOD_INVERSION_FILTER { driver.option_num("likelihood.inversion_filter", "true"); };
|
||||
o_occbin_likelihood_piecewise_kalman_filter : LIKELIHOOD_PIECEWISE_KALMAN_FILTER { driver.option_num("likelihood.inversion_filter", "false"); };
|
||||
o_occbin_likelihood_maxit : LIKELIHOOD_MAXIT EQUAL INT_NUMBER { driver.option_num("likelihood.maxit", $3); };
|
||||
o_occbin_likelihood_periods : LIKELIHOOD_PERIODS EQUAL INT_NUMBER { driver.option_num("likelihood.periods", $3); };
|
||||
o_occbin_likelihood_curb_retrench : LIKELIHOOD_CURB_RETRENCH { driver.option_num("likelihood.curb_retrench", "true"); };
|
||||
o_occbin_likelihood_check_ahead_periods : LIKELIHOOD_CHECK_AHEAD_PERIODS EQUAL INT_NUMBER { driver.option_num("likelihood.check_ahead_periods", $3); };
|
||||
o_occbin_likelihood_periodic_solution : LIKELIHOOD_PERIODIC_SOLUTION { driver.option_num("likelihood.periodic_solution", "true"); };
|
||||
o_occbin_likelihood_max_kalman_iterations : LIKELIHOOD_MAX_KALMAN_ITERATIONS EQUAL INT_NUMBER { driver.option_num("likelihood.max_number_of_iterations", $3); };
|
||||
o_occbin_smoother_inversion_filter : SMOOTHER_INVERSION_FILTER { driver.option_num("smoother.inversion_filter", "true"); };
|
||||
o_occbin_smoother_piecewise_kalman_filter : SMOOTHER_PIECEWISE_KALMAN_FILTER { driver.option_num("smoother.inversion_filter", "false"); };
|
||||
o_occbin_filter_use_relaxation : FILTER_USE_RELEXATION { driver.option_num("filter.use_relaxation", "true"); };
|
||||
o_occbin_smoother_maxit : SMOOTHER_MAXIT EQUAL INT_NUMBER { driver.option_num("smoother.maxit", $3); };
|
||||
o_occbin_smoother_periods : SMOOTHER_PERIODS EQUAL INT_NUMBER { driver.option_num("smoother.periods", $3); };
|
||||
o_occbin_smoother_curb_retrench : SMOOTHER_CURB_RETRENCH { driver.option_num("smoother.curb_retrench", "true"); };
|
||||
o_occbin_smoother_check_ahead_periods : SMOOTHER_CHECK_AHEAD_PERIODS EQUAL INT_NUMBER { driver.option_num("smoother.check_ahead_periods", $3); };
|
||||
o_occbin_smoother_debug : SMOOTHER_DEBUG { driver.option_num("smoother.debug", "true"); };
|
||||
o_occbin_smoother_periodic_solution : SMOOTHER_PERIODIC_SOLUTION { driver.option_num("smoother.periodic_solution", "true"); };
|
||||
o_occbin_filter_use_relaxation : FILTER_USE_RELEXATION { driver.option_num("filter.use_relaxation", "true"); };
|
||||
|
||||
// Some options to "occbin_write_regimes"
|
||||
o_occbin_write_regimes_periods : PERIODS EQUAL vec_int
|
||||
|
@ -4052,6 +4068,8 @@ o_occbin_write_regimes_periods : PERIODS EQUAL vec_int
|
|||
| PERIODS EQUAL vec_int_number
|
||||
{ driver.option_vec_int("write_regimes.periods", $3); }
|
||||
o_occbin_write_regimes_filename : FILENAME EQUAL filename { driver.option_str("write_regimes.filename", $3); };
|
||||
o_occbin_write_regimes_smoother : SMOOTHER { driver.option_str("write_regimes.type", "smoother"); };
|
||||
o_occbin_write_regimes_simul : SIMUL { driver.option_str("write_regimes.type", "simul"); };
|
||||
|
||||
// Some options to "occbin_graph"
|
||||
o_occbin_graph_noconstant : NOCONSTANT { driver.option_num("graph.steady_state", "false"); };
|
||||
|
|
|
@ -329,7 +329,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
|
|||
<DYNARE_STATEMENT>mode_check_symmetric_plots {return token::MODE_CHECK_SYMMETRIC_PLOTS;}
|
||||
<DYNARE_STATEMENT>mode_check_number_of_points {return token::MODE_CHECK_NUMBER_OF_POINTS;}
|
||||
<DYNARE_STATEMENT>prior_trunc {return token::PRIOR_TRUNC;}
|
||||
<DYNARE_STATEMENT>mh_mode {return token::MH_MODE;}
|
||||
<DYNARE_STATEMENT>mh_posterior_mode_estimation {return token::MH_POSTERIOR_MODE_ESTIMATION;}
|
||||
<DYNARE_STATEMENT>mh_nblocks {return token::MH_NBLOCKS;}
|
||||
<DYNARE_STATEMENT>load_mh_file {return token::LOAD_MH_FILE;}
|
||||
<DYNARE_STATEMENT>load_results_after_load_mh {return token::LOAD_RESULTS_AFTER_LOAD_MH;}
|
||||
|
@ -565,16 +565,25 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
|
|||
<DYNARE_STATEMENT>max_repeated_optimization_runs {return token::MAX_REPEATED_OPTIMIZATION_RUNS;}
|
||||
<DYNARE_STATEMENT>maxit {return token::MAXIT;}
|
||||
<DYNARE_STATEMENT>simul_maxit {return token::SIMUL_MAXIT;}
|
||||
<DYNARE_STATEMENT>likelihood_maxit {return token::LIKELIHOOD_MAXIT;}
|
||||
<DYNARE_STATEMENT>smoother_maxit {return token::SMOOTHER_MAXIT;}
|
||||
<DYNARE_STATEMENT>simul_periods {return token::SIMUL_PERIODS;}
|
||||
<DYNARE_STATEMENT>likelihood_periods {return token::LIKELIHOOD_PERIODS;}
|
||||
<DYNARE_STATEMENT>smoother_periods {return token::SMOOTHER_PERIODS;}
|
||||
<DYNARE_STATEMENT>simul_curb_retrench {return token::SIMUL_CURB_RETRENCH;}
|
||||
<DYNARE_STATEMENT>likelihood_curb_retrench {return token::LIKELIHOOD_CURB_RETRENCH;}
|
||||
<DYNARE_STATEMENT>smoother_curb_retrench {return token::SMOOTHER_CURB_RETRENCH;}
|
||||
<DYNARE_STATEMENT>simul_check_ahead_periods {return token::SIMUL_CHECK_AHEAD_PERIODS;}
|
||||
<DYNARE_STATEMENT>likelihood_check_ahead_periods {return token::LIKELIHOOD_CHECK_AHEAD_PERIODS;}
|
||||
<DYNARE_STATEMENT>smoother_check_ahead_periods {return token::SMOOTHER_CHECK_AHEAD_PERIODS;}
|
||||
<DYNARE_STATEMENT>simul_debug {return token::SIMUL_DEBUG;}
|
||||
<DYNARE_STATEMENT>smoother_debug {return token::SMOOTHER_DEBUG;}
|
||||
<DYNARE_STATEMENT>simul_periodic_solution {return token::SIMUL_PERIODIC_SOLUTION;}
|
||||
<DYNARE_STATEMENT>likelihood_periodic_solution {return token::LIKELIHOOD_PERIODIC_SOLUTION;}
|
||||
<DYNARE_STATEMENT>smoother_periodic_solution {return token::SMOOTHER_PERIODIC_SOLUTION;}
|
||||
<DYNARE_STATEMENT>likelihood_inversion_filter {return token::LIKELIHOOD_INVERSION_FILTER;}
|
||||
<DYNARE_STATEMENT>likelihood_piecewise_kalman_filter {return token::LIKELIHOOD_PIECEWISE_KALMAN_FILTER;}
|
||||
<DYNARE_STATEMENT>likelihood_max_kalman_iterations {return token::LIKELIHOOD_MAX_KALMAN_ITERATIONS;}
|
||||
<DYNARE_STATEMENT>smoother_inversion_filter {return token::SMOOTHER_INVERSION_FILTER;}
|
||||
<DYNARE_STATEMENT>smoother_piecewise_kalman_filter {return token::SMOOTHER_PIECEWISE_KALMAN_FILTER;}
|
||||
<DYNARE_STATEMENT>filter_use_relaxation {return token::FILTER_USE_RELEXATION;}
|
||||
|
@ -924,7 +933,6 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
|
|||
<DYNARE_BLOCK>var_expectation {return token::VAR_EXPECTATION;}
|
||||
<DYNARE_BLOCK>pac_expectation {return token::PAC_EXPECTATION;}
|
||||
<DYNARE_STATEMENT>discount {return token::DISCOUNT;}
|
||||
<DYNARE_STATEMENT>steady_state_growth {return token::STEADY_STATE_GROWTH;}
|
||||
<DYNARE_STATEMENT,DYNARE_BLOCK>varobs {return token::VAROBS;}
|
||||
<DYNARE_STATEMENT,DYNARE_BLOCK>varexobs {return token::VAREXOBS;}
|
||||
<DYNARE_STATEMENT,DYNARE_BLOCK>nan {return token::NAN_CONSTANT;}
|
||||
|
|
|
@ -4475,15 +4475,25 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
case BinaryOpcode::times:
|
||||
if (isLatexOutput(output_type))
|
||||
output << R"(\, )";
|
||||
else if (output_type == ExprNodeOutputType::occbinDifferenceFile)
|
||||
output << ".*"; // This file operates on vectors, see dynare#1826
|
||||
else
|
||||
output << "*";
|
||||
break;
|
||||
case BinaryOpcode::divide:
|
||||
if (!isLatexOutput(output_type))
|
||||
output << "/";
|
||||
{
|
||||
if (output_type == ExprNodeOutputType::occbinDifferenceFile)
|
||||
output << "./"; // This file operates on vectors, see dynare#1826
|
||||
else
|
||||
output << "/";
|
||||
}
|
||||
break;
|
||||
case BinaryOpcode::power:
|
||||
output << "^";
|
||||
if (output_type == ExprNodeOutputType::occbinDifferenceFile)
|
||||
output << ".^"; // This file operates on vectors, see dynare#1826
|
||||
else
|
||||
output << "^";
|
||||
break;
|
||||
case BinaryOpcode::less:
|
||||
output << "<";
|
||||
|
@ -5469,10 +5479,13 @@ BinaryOpNode::findConstantEquations(map<VariableNode *, NumConstNode *> &table)
|
|||
{
|
||||
if (op_code == BinaryOpcode::equal)
|
||||
{
|
||||
if (dynamic_cast<VariableNode *>(arg1) && dynamic_cast<NumConstNode *>(arg2))
|
||||
table[dynamic_cast<VariableNode *>(arg1)] = dynamic_cast<NumConstNode *>(arg2);
|
||||
else if (dynamic_cast<VariableNode *>(arg2) && dynamic_cast<NumConstNode *>(arg1))
|
||||
table[dynamic_cast<VariableNode *>(arg2)] = dynamic_cast<NumConstNode *>(arg1);
|
||||
// The variable must be contemporaneous (see #83)
|
||||
if (auto varg1 = dynamic_cast<VariableNode *>(arg1);
|
||||
varg1 && varg1->lag == 0 && dynamic_cast<NumConstNode *>(arg2))
|
||||
table[varg1] = dynamic_cast<NumConstNode *>(arg2);
|
||||
else if (auto varg2 = dynamic_cast<VariableNode *>(arg2);
|
||||
varg2 && varg2->lag == 0 && dynamic_cast<NumConstNode *>(arg1))
|
||||
table[varg2] = dynamic_cast<NumConstNode *>(arg1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,10 +50,22 @@ macroExpandModFile(const string &filename, const string &basename, const istream
|
|||
string str(macro_output.str());
|
||||
if (!line_macro)
|
||||
{
|
||||
str = regex_replace(str, regex(R"((^|\n)\s*@#line.*)"), "");
|
||||
auto compareNewline = [](char i, char j) { return i == '\n' && j == '\n'; };
|
||||
str.erase(0, str.find_first_not_of('\n'));
|
||||
str.erase(unique(str.begin(), str.end(), compareNewline), str.end());
|
||||
/* Remove the @#line directives.
|
||||
Unfortunately GCC 11 does not yet support std::regex::multiline
|
||||
(despite it being in the C++17 standard), so we are forced to use
|
||||
a trick to emulate the “usual” behaviour of the caret ^;
|
||||
here, the latter only matches the beginning of file.
|
||||
This also means that we are forced to remove the EOL before the
|
||||
@#line, and not the one after it (matching the EOL before and the
|
||||
EOL after in the same regexp does not work). */
|
||||
str = regex_replace(str, regex(R"((^|\r?\n)@#line.*)"), "");
|
||||
/* Remove the EOLs at the beginning of the output, the first one
|
||||
being a remnant of the first @#line directive. */
|
||||
str = regex_replace(str, regex(R"(^(\r?\n)+)"), "");
|
||||
/* Replace sequences of several newlines by a single newline (in
|
||||
both LF and CR+LF conventions). */
|
||||
str = regex_replace(str, regex(R"(\n{2,})"), "\n");
|
||||
str = regex_replace(str, regex(R"((\r\n){2,})"), "\r\n");
|
||||
}
|
||||
macro_output_file << str;
|
||||
macro_output_file.close();
|
||||
|
|
|
@ -484,10 +484,14 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool
|
|||
cerr << "Error: aux_model_name not recognized as VAR model or Trend Component model" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (pms->growth)
|
||||
dynamic_model.createPacGrowthNeutralityParameter(pms->name);
|
||||
|
||||
auto eqtag_and_lag = dynamic_model.walkPacParameters(pms->name);
|
||||
if (pms->aux_model_name.empty())
|
||||
dynamic_model.addPacModelConsistentExpectationEquation(pms->name, symbol_table.getID(pms->discount),
|
||||
eqtag_and_lag, diff_subst_table);
|
||||
eqtag_and_lag, diff_subst_table,
|
||||
pms->growth);
|
||||
else
|
||||
dynamic_model.fillPacModelInfo(pms->name, lhs, max_lag, aux_model_type,
|
||||
eqtag_and_lag, nonstationary, pms->growth);
|
||||
|
|
|
@ -1566,9 +1566,6 @@ ModelTree::includeExcludeEquations(set<pair<string, string>> &eqs, bool exclude_
|
|||
else
|
||||
++it;
|
||||
|
||||
if (tag_eqns.empty())
|
||||
return excluded_vars;
|
||||
|
||||
set<int> eqns;
|
||||
if (exclude_eqs)
|
||||
eqns = tag_eqns;
|
||||
|
@ -1594,7 +1591,7 @@ ModelTree::includeExcludeEquations(set<pair<string, string>> &eqs, bool exclude_
|
|||
excluded_vars.push_back(result.begin()->first);
|
||||
else
|
||||
{
|
||||
cerr << "ERROR: Equation " << i
|
||||
cerr << "ERROR: Equation " << i+1
|
||||
<< " has been excluded but does not have a single variable on LHS or `endogenous` tag" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -1895,6 +1892,36 @@ ModelTree::matlab_arch(const string &mexext)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
string
|
||||
ModelTree::findGccOnMacos()
|
||||
{
|
||||
const string macos_gcc_version{"11"}; // doc/manual/source/installation-and-configuration.rst
|
||||
// should be updated when this is changed
|
||||
char dynare_preprocessor_path[PATH_MAX];
|
||||
uint32_t size = PATH_MAX;
|
||||
string local_gcc_path;
|
||||
if (_NSGetExecutablePath(dynare_preprocessor_path, &size) == 0)
|
||||
{
|
||||
string s = dynare_preprocessor_path;
|
||||
local_gcc_path = s.substr(0, s.find_last_of("/")) + "/../.brew/bin/gcc-" + macos_gcc_version;
|
||||
}
|
||||
|
||||
if (filesystem::exists(local_gcc_path))
|
||||
return local_gcc_path;
|
||||
else if (string global_gcc_path = "/usr/local/bin/gcc-" + macos_gcc_version;
|
||||
filesystem::exists(global_gcc_path))
|
||||
return global_gcc_path;
|
||||
else
|
||||
{
|
||||
cerr << "ERROR: You must install gcc-" << macos_gcc_version
|
||||
<< " on your system before using the `use_dll` option of Dynare. "
|
||||
<< "If using MATLAB, you can do this via the Dynare installation package. If using Octave, you should run `brew install gcc-" << macos_gcc_version << "` in a terminal." << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
ModelTree::compileMEX(const string &basename, const string &funcname, const string &mexext, const vector<filesystem::path> &src_files, const filesystem::path &matlabroot, const filesystem::path &dynareroot) const
|
||||
{
|
||||
|
@ -1915,6 +1942,22 @@ ModelTree::compileMEX(const string &basename, const string &funcname, const stri
|
|||
// Octave
|
||||
compiler = matlabroot / "bin" / "mkoctfile";
|
||||
flags << "--mex";
|
||||
#ifdef __APPLE__
|
||||
/* On macOS, enforce GCC, otherwise Clang will be used, and it does not
|
||||
accept our custom optimization flags (see dynare#1797) */
|
||||
string gcc_path = findGccOnMacos();
|
||||
if (setenv("CC", gcc_path.c_str(), 1) != 0)
|
||||
{
|
||||
cerr << "Can't set CC environment variable" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// We also define CXX, because that is used for linking
|
||||
if (setenv("CXX", gcc_path.c_str(), 1) != 0)
|
||||
{
|
||||
cerr << "Can't set CXX environment variable" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1941,6 +1984,9 @@ ModelTree::compileMEX(const string &basename, const string &funcname, const stri
|
|||
// Put the MinGW environment shipped with Dynare in the path
|
||||
auto mingwpath = dynareroot / "mingw64" / "bin";
|
||||
string newpath = "PATH=" + mingwpath.string() + ';' + string{getenv("PATH")};
|
||||
/* We can’t use setenv() since it is not available on MinGW. Note
|
||||
that putenv() seems to make a copy of the string on MinGW, contrary
|
||||
to what is done on GNU/Linux and macOS. */
|
||||
if (putenv(const_cast<char *>(newpath.c_str())) != 0)
|
||||
{
|
||||
cerr << "Can't set PATH" << endl;
|
||||
|
@ -1950,26 +1996,7 @@ ModelTree::compileMEX(const string &basename, const string &funcname, const stri
|
|||
#ifdef __APPLE__
|
||||
else if (mexext == "mexmaci64")
|
||||
{
|
||||
// macOS
|
||||
char dynare_m_path[PATH_MAX];
|
||||
uint32_t size = PATH_MAX;
|
||||
string gcc_relative_path;
|
||||
if (_NSGetExecutablePath(dynare_m_path, &size) == 0)
|
||||
{
|
||||
string str = dynare_m_path;
|
||||
gcc_relative_path = str.substr(0, str.find_last_of("/")) + "/../.brew/bin/gcc-11";
|
||||
}
|
||||
|
||||
if (filesystem::exists(gcc_relative_path))
|
||||
compiler = gcc_relative_path;
|
||||
else if (filesystem::exists("/usr/local/bin/gcc-11"))
|
||||
compiler = "/usr/local/bin/gcc-11";
|
||||
else
|
||||
{
|
||||
cerr << "ERROR: You must install gcc-11 on your system before using the `use_dll` option of Dynare. "
|
||||
<< "You can do this via the Dynare installation package." << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
compiler = findGccOnMacos();
|
||||
flags << " -fno-common -Wl,-twolevel_namespace -undefined error -bundle";
|
||||
libs += " -lm";
|
||||
}
|
||||
|
|
|
@ -398,6 +398,10 @@ private:
|
|||
void copyHelper(const ModelTree &m);
|
||||
//! Returns the name of the MATLAB architecture given the extension used for MEX files
|
||||
static string matlab_arch(const string &mexext);
|
||||
#ifdef __APPLE__
|
||||
//! Finds a suitable GCC compiler on macOS
|
||||
static string findGccOnMacos();
|
||||
#endif
|
||||
//! Compiles a MEX file
|
||||
void compileMEX(const string &basename, const string &funcname, const string &mexext, const vector<filesystem::path> &src_files, const filesystem::path &matlabroot, const filesystem::path &dynareroot) const;
|
||||
|
||||
|
|
|
@ -132,6 +132,9 @@ InitOrEndValStatement::writeInitValues(ostream &output) const
|
|||
{
|
||||
for (auto [symb_id, value] : init_values)
|
||||
{
|
||||
if (symbol_table.getType(symb_id) == SymbolType::unusedEndogenous) // See #82
|
||||
continue;
|
||||
|
||||
SymbolType type = symbol_table.getType(symb_id);
|
||||
int tsid = symbol_table.getTypeSpecificID(symb_id) + 1;
|
||||
|
||||
|
@ -167,9 +170,11 @@ InitOrEndValStatement::writeJsonInitValues(ostream &output) const
|
|||
for (auto it = init_values.begin();
|
||||
it != init_values.end(); ++it)
|
||||
{
|
||||
auto [symb_id, value] = *it;
|
||||
if (symbol_table.getType(symb_id) == SymbolType::unusedEndogenous) // See #82
|
||||
continue;
|
||||
if (it != init_values.begin())
|
||||
output << ", ";
|
||||
auto [symb_id, value] = *it;
|
||||
output << R"({"name": ")" << symbol_table.getName(symb_id) << R"(", )" << R"("value": ")";
|
||||
value->writeJsonOutput(output, {}, {});
|
||||
output << R"("})";
|
||||
|
@ -363,6 +368,8 @@ HistValStatement::writeOutput(ostream &output, const string &basename, bool mini
|
|||
for (const auto &[key, value] : hist_values)
|
||||
{
|
||||
auto [symb_id, lag] = key;
|
||||
if (symbol_table.getType(symb_id) == SymbolType::unusedEndogenous) // See #82
|
||||
continue;
|
||||
|
||||
output << "M_.histval_dseries{'" << symbol_table.getName(symb_id) << "'}(dates('" << lag << "Y'))=";
|
||||
value->writeOutput(output);
|
||||
|
@ -389,6 +396,8 @@ HistValStatement::writeJsonOutput(ostream &output) const
|
|||
it != hist_values.end(); ++it)
|
||||
{
|
||||
auto [symb_id, lag] = it->first;
|
||||
if (symbol_table.getType(symb_id) == SymbolType::unusedEndogenous) // See #82
|
||||
continue;
|
||||
if (it != hist_values.begin())
|
||||
output << ", ";
|
||||
output << R"({ "name": ")" << symbol_table.getName(symb_id) << R"(")"
|
||||
|
|
|
@ -321,8 +321,9 @@ ParsingDriver::add_model_variable(const string &name)
|
|||
}
|
||||
catch (SymbolTable::UnknownSymbolNameException &e)
|
||||
{
|
||||
// Declare variable as exogenous to continue parsing
|
||||
// processing will end at end of model block if nostrict option was not passed
|
||||
/* Declare variable as exogenous to continue parsing. Processing will end
|
||||
at end of model block (or planner_objective statement) if nostrict
|
||||
option was not passed. */
|
||||
declare_exogenous(name);
|
||||
undeclared_model_vars.insert(name);
|
||||
symb_id = mod_file->symbol_table.getID(name);
|
||||
|
@ -785,6 +786,7 @@ ParsingDriver::end_model()
|
|||
exit_after_write = true;
|
||||
cerr << it.second << endl;
|
||||
}
|
||||
undeclared_model_variable_errors.clear();
|
||||
|
||||
if (exit_after_write)
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -2022,6 +2024,21 @@ ParsingDriver::end_planner_objective(expr_t expr)
|
|||
|
||||
mod_file->addStatement(make_unique<PlannerObjectiveStatement>(*planner_objective));
|
||||
|
||||
// Handle undeclared variables (see #81)
|
||||
bool exit_after_write = false;
|
||||
if (undeclared_model_variable_errors.size() > 0)
|
||||
for (auto &it : undeclared_model_variable_errors)
|
||||
if (nostrict)
|
||||
warning(it.second);
|
||||
else
|
||||
{
|
||||
exit_after_write = true;
|
||||
cerr << it.second << endl;
|
||||
}
|
||||
undeclared_model_variable_errors.clear();
|
||||
if (exit_after_write)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
reset_data_tree();
|
||||
}
|
||||
|
||||
|
@ -2038,6 +2055,12 @@ ParsingDriver::ramsey_model()
|
|||
else if (planner_discount)
|
||||
error("ramsey_model: the 'planner_discount' option cannot be used when the 'optimal_policy_discount_factor' parameter is explicitly declared.");
|
||||
|
||||
// Check that instruments are declared endogenous (#72)
|
||||
if (auto it = options_list.symbol_list_options.find("instruments");
|
||||
it != options_list.symbol_list_options.end())
|
||||
for (const auto &s : it->second.getSymbols())
|
||||
check_symbol_is_endogenous(s);
|
||||
|
||||
mod_file->addStatement(make_unique<RamseyModelStatement>(options_list));
|
||||
options_list.clear();
|
||||
planner_discount = nullptr;
|
||||
|
@ -2059,6 +2082,12 @@ ParsingDriver::ramsey_policy()
|
|||
else if (planner_discount)
|
||||
error("ramsey_policy: the 'planner_discount' option cannot be used when the 'optimal_policy_discount_factor' parameter is explicitly declared.");
|
||||
|
||||
// Check that instruments are declared endogenous (#72)
|
||||
if (auto it = options_list.symbol_list_options.find("instruments");
|
||||
it != options_list.symbol_list_options.end())
|
||||
for (const auto &s : it->second.getSymbols())
|
||||
check_symbol_is_endogenous(s);
|
||||
|
||||
mod_file->addStatement(make_unique<RamseyPolicyStatement>(mod_file->symbol_table,
|
||||
symbol_list, options_list));
|
||||
options_list.clear();
|
||||
|
@ -2114,6 +2143,12 @@ ParsingDriver::discretionary_policy()
|
|||
planner_discount = data_tree->One;
|
||||
init_param("optimal_policy_discount_factor", planner_discount);
|
||||
|
||||
// Check that instruments are declared endogenous (#72)
|
||||
if (auto it = options_list.symbol_list_options.find("instruments");
|
||||
it != options_list.symbol_list_options.end())
|
||||
for (const auto &s : it->second.getSymbols())
|
||||
check_symbol_is_endogenous(s);
|
||||
|
||||
mod_file->addStatement(make_unique<DiscretionaryPolicyStatement>(symbol_list, options_list));
|
||||
symbol_list.clear();
|
||||
options_list.clear();
|
||||
|
@ -2562,12 +2597,12 @@ ParsingDriver::add_var_expectation(const string &model_name)
|
|||
}
|
||||
|
||||
expr_t
|
||||
ParsingDriver::add_pac_expectation(const string &var_model_name)
|
||||
ParsingDriver::add_pac_expectation(const string &model_name)
|
||||
{
|
||||
if (data_tree == occbin_constraints_tree.get())
|
||||
error("The 'var_expectation' operator is forbidden in 'occbin_constraints'.");
|
||||
error("The 'pac_expectation' operator is forbidden in 'occbin_constraints'.");
|
||||
|
||||
return data_tree->AddPacExpectation(var_model_name);
|
||||
return data_tree->AddPacExpectation(model_name);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2581,8 +2616,6 @@ ParsingDriver::begin_pac_model()
|
|||
{
|
||||
parsing_pac_model = true;
|
||||
pac_growth = nullptr;
|
||||
pac_steady_state_growth_rate_number = -1;
|
||||
pac_steady_state_growth_rate_symb_id = -1;
|
||||
options_list.clear();
|
||||
}
|
||||
|
||||
|
@ -2594,53 +2627,19 @@ ParsingDriver::pac_model()
|
|||
error("You must pass the model_name option to the pac_model statement.");
|
||||
auto name = it->second;
|
||||
|
||||
bool pac_growth_is_param = false;
|
||||
if (pac_growth && dynamic_cast<VariableNode *>(pac_growth))
|
||||
{
|
||||
set<int> params;
|
||||
pac_growth->collectVariables(SymbolType::parameter, params);
|
||||
if (params.size() == 1)
|
||||
pac_growth_is_param = true;
|
||||
pac_growth->collectVariables(SymbolType::endogenous, params);
|
||||
pac_growth->collectVariables(SymbolType::exogenous, params);
|
||||
if (params.size() != 1)
|
||||
pac_growth_is_param = false;
|
||||
}
|
||||
|
||||
string aux_model_name;
|
||||
it = options_list.string_options.find("pac.aux_model_name");
|
||||
if (it != options_list.string_options.end())
|
||||
{
|
||||
aux_model_name = it->second;
|
||||
if (pac_steady_state_growth_rate_number >= 0 || pac_steady_state_growth_rate_symb_id >= 0)
|
||||
{
|
||||
pac_steady_state_growth_rate_number = -1;
|
||||
pac_steady_state_growth_rate_symb_id = -1;
|
||||
warning("when aux_model_name is used in the pac_model statement, steady_state_growth is ignored");
|
||||
}
|
||||
}
|
||||
else
|
||||
if (pac_growth_is_param
|
||||
&& (pac_steady_state_growth_rate_number >= 0 || pac_steady_state_growth_rate_symb_id >= 0))
|
||||
warning("If growth option is constant, steady_state_growth is ignored");
|
||||
else if (pac_growth && !pac_growth_is_param
|
||||
&& pac_steady_state_growth_rate_number < 0
|
||||
&& pac_steady_state_growth_rate_symb_id < 0)
|
||||
error("The steady state growth rate of the target must be provided (steady_state_growth option) if option growth is not constant");
|
||||
|
||||
if (pac_steady_state_growth_rate_symb_id >= 0
|
||||
&& mod_file->symbol_table.getType(pac_steady_state_growth_rate_symb_id) != SymbolType::parameter)
|
||||
error("pac_model: steady_state_growth accepts either a number or a parameter");
|
||||
aux_model_name = it->second;
|
||||
|
||||
it = options_list.string_options.find("pac.discount");
|
||||
if (it == options_list.string_options.end())
|
||||
error("You must pass the discount option to the pac_model statement.");
|
||||
auto discount = it->second;
|
||||
check_symbol_is_parameter(discount);
|
||||
|
||||
mod_file->addStatement(make_unique<PacModelStatement>(name, aux_model_name, discount,
|
||||
pac_growth,
|
||||
pac_steady_state_growth_rate_number,
|
||||
pac_steady_state_growth_rate_symb_id,
|
||||
mod_file->symbol_table));
|
||||
parsing_pac_model = false;
|
||||
}
|
||||
|
@ -2652,21 +2651,6 @@ ParsingDriver::set_pac_growth(expr_t pac_growth_arg)
|
|||
reset_data_tree();
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::set_pac_steady_state_growth(const string &name_or_number)
|
||||
{
|
||||
try
|
||||
{
|
||||
pac_steady_state_growth_rate_number = stod(name_or_number);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (!mod_file->symbol_table.exists(name_or_number))
|
||||
error("Unknown symbol used in pac_steady_state_growth option: " + name_or_number + "\n");
|
||||
pac_steady_state_growth_rate_symb_id = mod_file->symbol_table.getID(name_or_number);
|
||||
}
|
||||
}
|
||||
|
||||
expr_t
|
||||
ParsingDriver::add_exp(expr_t arg1)
|
||||
{
|
||||
|
|
|
@ -75,7 +75,7 @@ public:
|
|||
string filename;
|
||||
|
||||
//! Increment the location counter given a token
|
||||
void location_increment(Dynare::parser::location_type *yylloc, const char *yytext);
|
||||
static void location_increment(Dynare::parser::location_type *yylloc, const char *yytext);
|
||||
|
||||
//! Count parens in dates statement
|
||||
int dates_parens_nb;
|
||||
|
@ -257,8 +257,6 @@ private:
|
|||
|
||||
//! Temporary storage for growth declared in pac_model
|
||||
expr_t pac_growth;
|
||||
double pac_steady_state_growth_rate_number = -1;
|
||||
int pac_steady_state_growth_rate_symb_id = -1;
|
||||
|
||||
bool nostrict;
|
||||
|
||||
|
@ -740,15 +738,13 @@ public:
|
|||
//! Writes token "VAR_EXPECTATION(model_name)" to model tree
|
||||
expr_t add_var_expectation(const string &model_name);
|
||||
//! Writes token "PAC_EXPECTATION(model_name, discount, growth)" to model tree
|
||||
expr_t add_pac_expectation(const string &var_model_name);
|
||||
expr_t add_pac_expectation(const string &model_name);
|
||||
//! Creates pac_model statement
|
||||
void begin_pac_growth();
|
||||
void begin_pac_model();
|
||||
void pac_model();
|
||||
//! Adds growth for pac
|
||||
void set_pac_growth(expr_t pac_growth_arg);
|
||||
//! Adds steady state growth for pac
|
||||
void set_pac_steady_state_growth(const string &name_or_number);
|
||||
//! Writes token "diff(arg1)" to model tree
|
||||
expr_t add_diff(expr_t arg1);
|
||||
//! Writes token "adl(arg1, lag)" to model tree
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2019-2020 Dynare Team
|
||||
* Copyright © 2019-2021 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -56,6 +56,7 @@ namespace macro
|
|||
Tokenizer::parser::token_type lex(Tokenizer::parser::semantic_type *yylval,
|
||||
Tokenizer::parser::location_type *yylloc,
|
||||
macro::Driver &driver);
|
||||
static void location_increment(Tokenizer::parser::location_type *yylloc, const char *yytext);
|
||||
};
|
||||
|
||||
//! Implements the macro expansion using a Flex scanner and a Bison parser
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// -*- C++ -*-
|
||||
/*
|
||||
* Copyright © 2019-2020 Dynare Team
|
||||
* Copyright © 2019-2021 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -89,7 +89,8 @@ using namespace macro;
|
|||
%precedence CAST
|
||||
%nonassoc POWER
|
||||
|
||||
%token <string> NAME TEXT QUOTED_STRING NUMBER EOL
|
||||
%token EOL
|
||||
%token <string> NAME TEXT QUOTED_STRING NUMBER
|
||||
|
||||
%type <DirectivePtr> statement
|
||||
%type <DirectivePtr> directive directive_one_line directive_multiline for if ifdef ifndef text eval
|
||||
|
@ -284,7 +285,7 @@ else : else_begin EOL
|
|||
text : TEXT
|
||||
{ $$ = make_shared<TextNode>($1, @$); }
|
||||
| EOL
|
||||
{ $$ = make_shared<TextNode>($1, @$); }
|
||||
{ $$ = make_shared<TextNode>("\n", @$); }
|
||||
;
|
||||
|
||||
eval : BEGIN_EVAL expr END_EVAL
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- C++ -*- */
|
||||
/*
|
||||
* Copyright © 2019 Dynare Team
|
||||
* Copyright © 2019-2021 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
|
@ -50,7 +50,7 @@ using token = Tokenizer::parser::token;
|
|||
|
||||
%{
|
||||
// Increments location counter for every token read
|
||||
# define YY_USER_ACTION yylloc->columns(yyleng);
|
||||
#define YY_USER_ACTION location_increment(yylloc, yytext);
|
||||
%}
|
||||
|
||||
SPC [ \t]+
|
||||
|
@ -175,24 +175,15 @@ CONT \\\\{SPC}*
|
|||
}
|
||||
|
||||
<expr,eval>{SPC}+ { }
|
||||
<eval>{EOL}+ { yylloc->lines(yyleng); yylloc->lines(yyleng); }
|
||||
<eval>{EOL}+ { }
|
||||
<eval>\} { BEGIN(INITIAL); return token::END_EVAL; }
|
||||
|
||||
<expr,end_line>{CONT}("//".*)?{SPC}*{EOL} { yylloc->lines(1); yylloc->step(); }
|
||||
<expr,end_line>{SPC}*("//".*)?{EOL} {
|
||||
yylval->build<string>("\n");
|
||||
yylloc->lines(1);
|
||||
BEGIN(INITIAL);
|
||||
return token::EOL;
|
||||
}
|
||||
<expr,end_line>{CONT}("//".*)?{SPC}*{EOL} { yylloc->step(); }
|
||||
<expr,end_line>{SPC}*("//".*)?{EOL} { BEGIN(INITIAL); return token::EOL; }
|
||||
|
||||
<INITIAL>^{SPC}*@#{SPC}* { BEGIN(directive); }
|
||||
<INITIAL>@\{ { BEGIN(eval); return token::BEGIN_EVAL; }
|
||||
<INITIAL>{SPC}*{EOL} {
|
||||
yylval->build<string>(yytext);
|
||||
yylloc->lines(1);
|
||||
return token::EOL;
|
||||
}
|
||||
<INITIAL>{EOL} { return token::EOL; }
|
||||
<INITIAL><<EOF>> { yyterminate(); }
|
||||
|
||||
<directive,expr,eval,end_line><<EOF>> { driver.error(*yylloc, "unexpected end of file"); }
|
||||
|
@ -202,6 +193,16 @@ CONT \\\\{SPC}*
|
|||
|
||||
%%
|
||||
|
||||
void
|
||||
TokenizerFlex::location_increment(Tokenizer::parser::location_type *yylloc, const char *yytext)
|
||||
{
|
||||
while (*yytext != 0)
|
||||
if (*yytext++ == '\n')
|
||||
yylloc->lines(1);
|
||||
else
|
||||
yylloc->columns(1);
|
||||
}
|
||||
|
||||
/* This implementation of TokenizerFlexLexer::yylex() is required to fill the
|
||||
* vtable of the class TokenizerFlexLexer. We define the scanner's main yylex
|
||||
* function via YY_DECL to reside in the TokenizerFlex class instead. */
|
||||
|
|
Loading…
Reference in New Issue