Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • normann/preprocessor
  • Dynare/preprocessor
  • FerhatMihoubi/preprocessor
  • MichelJuillard/preprocessor
  • sebastien/preprocessor
  • lnsongxf/preprocessor
  • albop/preprocessor
  • DoraK/preprocessor
  • amg/preprocessor
  • wmutschl/preprocessor
  • JohannesPfeifer/preprocessor
11 results
Show changes
Commits on Source (31)
Showing with 249 additions and 168 deletions
......@@ -11,9 +11,12 @@ BreakInheritanceList: AfterColon
Cpp11BracedListStyle: true
DeriveLineEnding: false
IndentPPDirectives: AfterHash
InsertNewlineAtEOF: true
PackConstructorInitializers: NextLine
PPIndentWidth: 1
PointerAlignment: Left
# RemoveParentheses: ReturnStatement
# RemoveSemicolon: true
SpaceAfterTemplateKeyword: false
SpaceBeforeParens: ControlStatements
SpaceBeforeCpp11BracedList: true
variables:
TERM: linux
MINGW64_BOOST_VERSION: 1.85.0-2
MINGW64_BOOST_VERSION: 1.86.0-7
WGET_OPTIONS: '--no-verbose --no-use-server-timestamps --retry-connrefused --retry-on-host-error'
# To ensure that "false && true" fails, see https://gitlab.com/gitlab-org/gitlab-runner/-/issues/25394#note_412609647
FF_ENABLE_BASH_EXIT_CODE_CHECK: 'true'
......@@ -77,3 +77,16 @@ test_clang_format:
- meson setup build-clang-format
- ninja -C build-clang-format clang-format-check
needs: []
test_clang_tidy:
stage: test
script:
# Hack needed for meson < 1.6.0 which only looks for unversioned clang-tidy
- mkdir -p ~/.local/bin && ln -s /usr/bin/clang-tidy-19 ~/.local/bin/clang-tidy
- export PATH="$HOME/.local/bin:$PATH"
- meson setup build-clang-tidy
# Generate Flex and Bison files
- meson compile -C build-clang-tidy
- ninja -C build-clang-tidy clang-tidy
needs: []
when: manual
......@@ -283,7 +283,9 @@ PerfectForesightWithExpectationErrorsSolverStatement::writeOutput(
[[maybe_unused]] bool minimal_workspace) const
{
options_list.writeOutput(output);
output << "oo_ = perfect_foresight_with_expectation_errors_solver(M_, options_, oo_);" << endl;
output << "[oo_, Simulated_time_series] = perfect_foresight_with_expectation_errors_solver(M_, "
"options_, oo_);"
<< endl;
}
void
......@@ -5340,8 +5342,8 @@ void
ResidStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename,
[[maybe_unused]] bool minimal_workspace) const
{
options_list.writeOutput(output, "options_resid_");
output << "display_static_residuals(M_, options_, oo_, options_resid_);" << endl;
options_list.writeOutput(output);
output << "display_static_residuals(M_, options_, oo_);" << endl;
}
void
......
......@@ -524,7 +524,7 @@ public:
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;
......@@ -542,7 +542,7 @@ public:
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;
......@@ -557,7 +557,7 @@ public:
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;
......
......@@ -47,7 +47,7 @@ private:
get_paths() const
{
return paths;
};
}
private:
map<string, vector<string>> paths;
......
......@@ -70,13 +70,14 @@ DataTree::DataTree(const DataTree& d) :
// Constants must be initialized first because they are used in some Add* methods
initConstants();
// See commment in DataTree::operator=() for the rationale
for (int symb_id : d.local_variables_vector)
local_variables_table[symb_id] = d.local_variables_table.at(symb_id)->clone(*this);
for (const auto& it : d.node_list)
it->clone(*this);
assert(node_list.size() == d.node_list.size());
for (const auto& [symb_id, value] : d.local_variables_table)
local_variables_table[symb_id] = value->clone(*this);
}
DataTree&
......
......@@ -367,7 +367,13 @@ public:
if (it == local_variables_table.end())
throw UnknownLocalVariableException {symb_id};
return it->second->decreaseLeadsLags(-lead_lag);
/* In the following, the case without lead/lag is optimized. It makes a difference on models
with many nested model-local variables, see e.g.
https://forum.dynare.org/t/pre-processing-takes-very-long/26865 */
if (lead_lag == 0)
return it->second;
else
return it->second->decreaseLeadsLags(-lead_lag);
}
static void
......@@ -396,7 +402,7 @@ DataTree::AddPossiblyNegativeConstant(double v)
if (isnan(v))
return NaN;
if (isinf(v))
return (v < 0 ? MinusInfinity : Infinity);
return v < 0 ? MinusInfinity : Infinity;
bool neg = false;
if (v < 0)
......
/*
* Copyright © 2003-2024 Dynare Team
* Copyright © 2003-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -731,9 +731,9 @@ DynamicModel::removeEquationsHelper(
}
int n_excl = all_equations.size() - new_equations.size();
all_equations = new_equations;
all_equations_lineno = new_equations_lineno;
all_complementarity_conditions = new_complementarity_conditions;
all_equations = move(new_equations);
all_equations_lineno = move(new_equations_lineno);
all_complementarity_conditions = move(new_complementarity_conditions);
all_equation_tags.erase(eqs_to_delete_by_number, old_eqn_num_2_new);
......@@ -1816,7 +1816,7 @@ DynamicModel::analyzePacEquationStructure(const string& name, map<string, string
for (auto& equation : equations)
if (equation->containsPacExpectation(name))
{
if (!pac_eq_name[name].empty())
if (pac_eq_name.contains(name))
{
cerr << "It is not possible to use 'pac_expectation(" << name
<< ")' in several equations." << endl;
......@@ -1915,6 +1915,13 @@ DynamicModel::analyzePacEquationStructure(const string& name, map<string, string
move(additive_vars_params_and_constants),
move(optim_additive_vars_params_and_constants)};
}
if (!pac_eq_name.contains(name))
{
cerr << "ERROR: the model does not contain the 'pac_expectation(" << name << ")' operator."
<< endl;
exit(EXIT_FAILURE);
}
}
int
......
......@@ -73,7 +73,8 @@ public:
void checkAllRegimesPresent() const noexcept(false);
private:
pair<vector<string>, vector<string>> convertBitVectorToRegimes(const vector<bool>& r) const;
[[nodiscard]] pair<vector<string>, vector<string>>
convertBitVectorToRegimes(const vector<bool>& r) const;
};
private:
......@@ -713,7 +714,7 @@ public:
{
return tuple {static_only_equations, static_only_equations_lineno,
static_only_complementarity_conditions, static_only_equations_equation_tags};
};
}
//! Returns true if a parameter was used in the model block with a lead or lag
bool ParamUsedWithLeadLag() const;
......
// -*- C++ -*-
/*
* Copyright © 2003-2024 Dynare Team
* Copyright © 2003-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -39,6 +39,7 @@
#include "CommonEnums.hh"
#include "ExprNode.hh"
#include "Shocks.hh"
class ParsingDriver;
}
......@@ -110,7 +111,7 @@ str_tolower(string s)
%token DEFAULT FIXED_POINT FLIP OPT_ALGO COMPILATION_SETUP COMPILER ADD_FLAGS SUBSTITUTE_FLAGS ADD_LIBS SUBSTITUTE_LIBS
%token FORECAST K_ORDER_SOLVER INSTRUMENTS SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN
%token GAMMA_PDF GRAPH GRAPH_FORMAT CONDITIONAL_VARIANCE_DECOMPOSITION NOCHECK STD
%token HISTVAL HISTVAL_FILE HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS HOMOTOPY_FORCE_CONTINUE HP_FILTER HP_NGRID FILTERED_THEORETICAL_MOMENTS_GRID HYBRID ONE_SIDED_HP_FILTER
%token HISTVAL HISTVAL_FILE HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS HOMOTOPY_FORCE_CONTINUE HP_FILTER HP_NGRID FILTERED_THEORETICAL_MOMENTS_GRID HYBRID USE_FIRST_ORDER_SOLUTION ONE_SIDED_HP_FILTER
%token IDENTIFICATION INF_CONSTANT INITVAL INITVAL_FILE BOUNDS JSCALE INIT INFILE INVARS
%token <string> INT_NUMBER
%token CONDITIONAL_LIKELIHOOD
......@@ -172,7 +173,8 @@ str_tolower(string s)
%token VLISTLOG VLISTPER SPECTRAL_DENSITY INIT2SHOCKS
%token RESTRICTION RESTRICTION_FNAME CROSS_RESTRICTIONS NLAGS CONTEMP_REDUCED_FORM REAL_PSEUDO_FORECAST
%token DUMMY_OBS NSTATES INDXSCALESSTATES NO_BAYESIAN_PRIOR SPECIFICATION SIMS_ZHA
%token <string> ALPHA BETA ABAND NINV CMS NCMS CNUM GAMMA INV_GAMMA INV_GAMMA1 INV_GAMMA2 NORMAL UNIFORM EPS PDF FIG DR NONE PRIOR PRIOR_VARIANCE HESSIAN IDENTITY_MATRIX DIRICHLET DIAGONAL OPTIMAL MFS
%token <string> ALPHA BETA ABAND NINV CMS NCMS CNUM GAMMA INV_GAMMA INV_GAMMA1 INV_GAMMA2 NORMAL UNIFORM EPS PDF FIG DR NONE PRIOR DIRICHLET MFS RESIDUAL
%token PRIOR_VARIANCE HESSIAN IDENTITY_MATRIX
%token GSIG2_LMDM Q_DIAG FLAT_PRIOR NCSK NSTD WEIBULL WEIBULL_PDF
%token INDXPARR INDXOVR INDXAP APBAND INDXIMF INDXFORE FOREBAND INDXGFOREHAT INDXGIMFHAT
%token INDXESTIMA INDXGDLS EQ_MS FILTER_COVARIANCE UPDATED_COVARIANCE FILTER_DECOMPOSITION SMOOTHED_STATE_UNCERTAINTY SMOOTHER_REDUX
......@@ -218,7 +220,7 @@ str_tolower(string s)
%token HOMOTOPY_MAX_COMPLETION_SHARE HOMOTOPY_MIN_STEP_SIZE HOMOTOPY_INITIAL_STEP_SIZE HOMOTOPY_STEP_SIZE_INCREASE_SUCCESS_COUNT
%token HOMOTOPY_LINEARIZATION_FALLBACK HOMOTOPY_MARGINAL_LINEARIZATION_FALLBACK HOMOTOPY_EXCLUDE_VAREXO FROM_INITVAL_TO_ENDVAL
%token STATIC_MFS RELATIVE_TO_INITVAL MATCHED_IRFS MATCHED_IRFS_WEIGHTS WEIGHTS PERPENDICULAR
%token HETEROGENEITY HETEROGENEITY_DIMENSION SUM
%token HETEROGENEITY HETEROGENEITY_DIMENSION SUM PERFECT_FORESIGHT_CONTROLLED_PATHS EXOGENIZE ENDOGENIZE
%token <vector<string>> SYMBOL_VEC
......@@ -244,7 +246,8 @@ str_tolower(string s)
%type <vector<map<string, string>>> tag_pair_list_for_selection
%type <map<string, string>> tag_pair_list
%type <tuple<string,string,string,string>> prior_eq_opt options_eq_opt
%type <vector<pair<int, int>>> period_list
%type <AbstractShocksStatement::period_range_t> period_range
%type <vector<AbstractShocksStatement::period_range_t>> period_list
%type <vector<expr_t>> matched_moments_list value_list ramsey_constraints_list
%type <tuple<string, BinaryOpNode*, BinaryOpNode*, expr_t, expr_t>> occbin_constraints_regime
%type <vector<tuple<string, BinaryOpNode*, BinaryOpNode*, expr_t, expr_t>>> occbin_constraints_regimes_list
......@@ -252,14 +255,17 @@ str_tolower(string s)
%type <pair<string, expr_t>> occbin_constraints_regime_option
%type <PacTargetKind> pac_target_kind
%type <vector<tuple<string, string, vector<pair<string, string>>>>> symbol_list_with_tex_and_partition
%type <map<string, variant<bool, string>>> mshocks_options_list
%type <pair<string, variant<bool, string>>> mshocks_option
%type <variant<int, string>> integer_or_date
%type <map<string, variant<bool, variant<int, string>>>> mshocks_options_list
%type <pair<string, variant<bool, variant<int, string>>>> mshocks_option
%type <pair<vector<expr_t>, vector<expr_t>>> matched_irfs_elem_values_weights
%type <pair<pair<string, string>, vector<tuple<int, int, expr_t, expr_t>>>> matched_irfs_elem
%type <map<pair<string, string>, vector<tuple<int, int, expr_t, expr_t>>>> matched_irfs_list
%type <tuple<string, string, string>> matched_irfs_weights_elem_var_varexo
%type <pair<tuple<string, string, string, string, string, string>, expr_t>> matched_irfs_weights_elem
%type <map<tuple<string, string, string, string, string, string>, expr_t>> matched_irfs_weights_list
%type <tuple<string, vector<AbstractShocksStatement::period_range_t>, vector<expr_t>, string>> perfect_foresight_controlled_paths_elem
%type <vector<tuple<string, vector<AbstractShocksStatement::period_range_t>, vector<expr_t>, string>>> perfect_foresight_controlled_paths_list
%%
%start statement_list;
......@@ -381,6 +387,7 @@ statement : parameters
| perfect_foresight_solver
| perfect_foresight_with_expectation_errors_setup
| perfect_foresight_with_expectation_errors_solver
| perfect_foresight_controlled_paths
| prior_function
| posterior_function
| method_of_moments
......@@ -805,11 +812,17 @@ h_options: o_filename
| o_series
;
integer_or_date : INT_NUMBER
{ $$.emplace<int>(stoi($1)); }
| date_expr
{ $$.emplace<string>($1); }
;
endval : ENDVAL ';' endval_list END ';'
{ driver.end_endval(false); }
| ENDVAL '(' ALL_VALUES_REQUIRED ')' ';' endval_list END ';'
{ driver.end_endval(true); }
| ENDVAL '(' LEARNT_IN EQUAL INT_NUMBER ')' ';' endval_list END ';'
| ENDVAL '(' LEARNT_IN EQUAL integer_or_date ')' ';' endval_list END ';'
{ driver.end_endval_learnt_in($5); }
;
......@@ -1218,9 +1231,9 @@ shocks : SHOCKS ';' shock_list END ';' { driver.end_shocks(false); }
| SHOCKS '(' SURPRISE ')' ';' det_shock_list END ';' { driver.end_shocks_surprise(false); }
| SHOCKS '(' SURPRISE COMMA OVERWRITE ')' ';' det_shock_list END ';' { driver.end_shocks_surprise(true); }
| SHOCKS '(' OVERWRITE COMMA SURPRISE ')' ';' det_shock_list END ';' { driver.end_shocks_surprise(true); }
| SHOCKS '(' LEARNT_IN EQUAL INT_NUMBER ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($5, false); }
| SHOCKS '(' LEARNT_IN EQUAL INT_NUMBER COMMA OVERWRITE ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($5, true); }
| SHOCKS '(' OVERWRITE COMMA LEARNT_IN EQUAL INT_NUMBER ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($7, true); }
| SHOCKS '(' LEARNT_IN EQUAL integer_or_date ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($5, false); }
| SHOCKS '(' LEARNT_IN EQUAL integer_or_date COMMA OVERWRITE ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($5, true); }
| SHOCKS '(' OVERWRITE COMMA LEARNT_IN EQUAL integer_or_date ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($7, true); }
| SHOCKS '(' HETEROGENEITY EQUAL symbol ')' ';' stoch_shock_list END ';'
{ driver.end_heterogeneous_shocks($5, false); }
| SHOCKS '(' HETEROGENEITY EQUAL symbol COMMA OVERWRITE ')' ';' stoch_shock_list END ';'
......@@ -1370,7 +1383,7 @@ mshocks : MSHOCKS ';' mshock_list END ';'
alternative in the variant, so that default initialization of the
variant by the [] operator will give false */
if ($3.contains("learnt_in"))
driver.end_mshocks_learnt_in(get<string>($3.at("learnt_in")),
driver.end_mshocks_learnt_in(get<variant<int, string>>($3.at("learnt_in")),
get<bool>($3["overwrite"]),
get<bool>($3["relative_to_initval"]));
else
......@@ -1391,7 +1404,7 @@ mshocks_options_list : mshocks_option
mshocks_option : OVERWRITE
{ $$ = {"overwrite", true}; }
| LEARNT_IN EQUAL INT_NUMBER
| LEARNT_IN EQUAL integer_or_date
{ $$ = {"learnt_in", $3}; }
| RELATIVE_TO_INITVAL
{ $$ = {"relative_to_initval", true}; }
......@@ -1401,48 +1414,38 @@ mshock_list : mshock_list det_shock_elem
| det_shock_elem
;
period_list : period_list COMMA INT_NUMBER
{
$$ = $1;
int p = stoi($3);
$$.emplace_back(p, p);
}
| period_list INT_NUMBER
{
$$ = $1;
int p = stoi($2);
$$.emplace_back(p, p);
}
| period_list COMMA INT_NUMBER ':' INT_NUMBER
period_list : period_range
{ $$ = { $1 }; }
| period_list period_range
{
$$ = $1;
int p1 = stoi($3), p2 = stoi($5);
if (p1 > p2)
driver.error("Can't have first period index greater than second index in range specification");
$$.emplace_back(p1, p2);
$$.emplace_back($2);
}
| period_list INT_NUMBER ':' INT_NUMBER
| period_list COMMA period_range
{
$$ = $1;
int p1 = stoi($2), p2 = stoi($4);
if (p1 > p2)
driver.error("Can't have first period index greater than second index in range specification");
$$.emplace_back(p1, p2);
}
| INT_NUMBER ':' INT_NUMBER
{
int p1 = stoi($1), p2 = stoi($3);
if (p1 > p2)
driver.error("Can't have first period index greater than second index in range specification");
$$ = {{p1, p2}};
}
| INT_NUMBER
{
int p = stoi($1);
$$ = {{p, p}};
$$.emplace_back($3);
}
;
period_range : INT_NUMBER
{
int p = stoi($1);
$$.emplace<pair<int, int>>(p, p);
}
| INT_NUMBER ':' INT_NUMBER
{
int p1 = stoi($1), p2 = stoi($3);
if (p1 > p2)
driver.error("Can't have first period index greater than second index in range specification");
$$.emplace<pair<int, int>>(p1, p2);
}
| date_expr
{ $$.emplace<pair<string, string>>($1, $1); }
| date_expr ':' date_expr
{ $$.emplace<pair<string, string>>($1, $3); }
;
value_list : value_list COMMA '(' expression ')'
{
$$ = $1;
......@@ -1498,6 +1501,7 @@ steady_options : o_solve_algo
| o_steady_tolf
| o_steady_tolx
| o_fsolve_options
| o_non_zero
;
check : CHECK ';'
......@@ -1542,6 +1546,8 @@ perfect_foresight_setup_options_list : perfect_foresight_setup_options_list COMM
perfect_foresight_setup_options : o_periods
| o_datafile
| o_endval_steady
| o_pf_first_simulation_period
| o_pf_last_simulation_period
;
perfect_foresight_solver : PERFECT_FORESIGHT_SOLVER ';'
......@@ -1594,6 +1600,8 @@ perfect_foresight_with_expectation_errors_setup_options_list : perfect_foresight
perfect_foresight_with_expectation_errors_setup_options : o_periods
| o_datafile
| o_pf_first_simulation_period
| o_pf_last_simulation_period
;
perfect_foresight_with_expectation_errors_solver : PERFECT_FORESIGHT_WITH_EXPECTATION_ERRORS_SOLVER ';'
......@@ -1610,6 +1618,31 @@ perfect_foresight_with_expectation_errors_solver_options : o_pfwee_constant_simu
| perfect_foresight_solver_options
;
perfect_foresight_controlled_paths : PERFECT_FORESIGHT_CONTROLLED_PATHS ';' perfect_foresight_controlled_paths_list END ';'
{ driver.perfect_foresight_controlled_paths($3, 1); }
| PERFECT_FORESIGHT_CONTROLLED_PATHS '(' LEARNT_IN EQUAL integer_or_date ')' ';' perfect_foresight_controlled_paths_list END ';'
{ driver.perfect_foresight_controlled_paths($8, $5); }
;
perfect_foresight_controlled_paths_list : perfect_foresight_controlled_paths_list perfect_foresight_controlled_paths_elem
{
$$ = $1;
$$.push_back($2);
}
| perfect_foresight_controlled_paths_elem
{ $$ = { $1 }; }
;
perfect_foresight_controlled_paths_elem : EXOGENIZE symbol ';' PERIODS period_list ';' VALUES value_list ';' ENDOGENIZE symbol ';'
{
driver.check_symbol_is_endogenous($2);
driver.check_symbol_is_exogenous($11, false);
if ($5.size() != $8.size())
driver.error("The number of periods is different from the number of values");
$$ = { $2, $5, $8, $11};
}
;
method_of_moments : METHOD_OF_MOMENTS ';'
{ driver.method_of_moments(); }
| METHOD_OF_MOMENTS '(' method_of_moments_options_list ')' ';'
......@@ -3494,7 +3527,8 @@ extended_path_option : o_periods
| o_solver_periods
| o_extended_path_order
| o_hybrid
| o_lmmcp
| o_use_first_order_solution
| o_lmmcp
;
model_diagnostics : MODEL_DIAGNOSTICS ';'
......@@ -3622,7 +3656,15 @@ matched_irfs_elem : matched_irfs_elem_var_varexo
vector<tuple<int, int, expr_t, expr_t>> v;
v.reserve($3.size());
for (size_t i {0}; i < $3.size(); i++)
v.emplace_back($3[i].first, $3[i].second, $5.first[i], $5.second[i]);
try
{
auto [p1, p2] = get<pair<int, int>>($3[i]);
v.emplace_back(p1, p2, $5.first[i], $5.second[i]);
}
catch (bad_variant_access&)
{
driver.error("matched_irfs: dates are not allowed in the 'periods' keyword");
}
$$ = {$1, v};
}
;
......@@ -3721,6 +3763,7 @@ o_periods : PERIODS EQUAL INT_NUMBER { driver.option_num("periods", $3); };
o_solver_periods : SOLVER_PERIODS EQUAL INT_NUMBER { driver.option_num("ep.periods", $3); };
o_extended_path_order : ORDER EQUAL INT_NUMBER { driver.option_num("ep.stochastic.order", $3); };
o_hybrid : HYBRID { driver.option_num("ep.stochastic.hybrid_order", "2"); };
o_use_first_order_solution : USE_FIRST_ORDER_SOLUTION { driver.option_num("ep.use_first_order_solution_as_initial_guess", "true"); };
o_steady_maxit : MAXIT EQUAL INT_NUMBER { driver.option_num("steady.maxit", $3); };
o_simul_maxit : MAXIT EQUAL INT_NUMBER { driver.option_num("simul.maxit", $3); };
o_bandpass_filter : BANDPASS_FILTER { driver.option_num("bandpass.indicator", "true"); }
......@@ -3796,6 +3839,8 @@ o_first_simulation_period : FIRST_SIMULATION_PERIOD EQUAL INT_NUMBER { driver.op
o_last_simulation_period : LAST_SIMULATION_PERIOD EQUAL INT_NUMBER { driver.option_num("last_simulation_period", $3); }
| LAST_SIMULATION_PERIOD EQUAL date_expr { driver.option_date("last_simulation_period", $3); }
;
o_pf_first_simulation_period : FIRST_SIMULATION_PERIOD EQUAL date_expr { driver.option_date("simul.first_simulation_period", $3); };
o_pf_last_simulation_period : LAST_SIMULATION_PERIOD EQUAL date_expr { driver.option_date("simul.last_simulation_period", $3); };
o_last_obs : LAST_OBS EQUAL INT_NUMBER { driver.option_num("last_obs", $3); };
o_data_last_obs : LAST_OBS EQUAL date_expr { driver.option_date("last_obs", $3); } ;
o_keep_kalman_algo_if_singularity_is_detected : KEEP_KALMAN_ALGO_IF_SINGULARITY_IS_DETECTED { driver.option_num("kalman.keep_kalman_algo_if_singularity_is_detected", "true"); } ;
......@@ -4036,11 +4081,12 @@ o_resampling : RESAMPLING EQUAL SYSTEMATIC
| RESAMPLING EQUAL NONE { driver.option_num("particle.resampling.status.systematic", "false"); driver.option_num("particle.resampling.status.none", "true"); }
| RESAMPLING EQUAL GENERIC { driver.option_num("particle.resampling.status.systematic", "false"); driver.option_num("particle.resampling.status.generic", "true"); };
o_resampling_threshold : RESAMPLING_THRESHOLD EQUAL non_negative_number { driver.option_num("particle.resampling.threshold", $3); };
o_resampling_method : RESAMPLING_METHOD EQUAL KITAGAWA { driver.option_num("particle.resampling.method.kitagawa", "true"); driver.option_num("particle.resampling.method.smooth", "false"); driver.option_num("particle.resampling.smethod.stratified", "false"); }
| RESAMPLING_METHOD EQUAL SMOOTH { driver.option_num("particle.resampling.method.kitagawa", "false"); driver.option_num("particle.resampling.method.smooth", "true"); driver.option_num("particle.resampling.smethod.stratified", "false"); }
| RESAMPLING_METHOD EQUAL STRATIFIED { driver.option_num("particle.resampling.method.kitagawa", "false"); driver.option_num("particle.resampling.method.smooth", "false"); driver.option_num("particle.resampling.method.stratified", "true"); };
o_resampling_method : RESAMPLING_METHOD EQUAL KITAGAWA { driver.option_num("particle.resampling.method.kitagawa", "true"); driver.option_num("particle.resampling.method.smooth", "false"); driver.option_num("particle.resampling.method.stratified", "false"); driver.option_num("particle.resampling.method.residual", "false");}
| RESAMPLING_METHOD EQUAL SMOOTH { driver.option_num("particle.resampling.method.kitagawa", "false"); driver.option_num("particle.resampling.method.smooth", "true"); driver.option_num("particle.resampling.method.stratified", "false"); driver.option_num("particle.resampling.method.residual", "false"); }
| RESAMPLING_METHOD EQUAL STRATIFIED { driver.option_num("particle.resampling.method.kitagawa", "false"); driver.option_num("particle.resampling.method.smooth", "false"); driver.option_num("particle.resampling.method.stratified", "true"); driver.option_num("particle.resampling.method.residual", "false"); };
| RESAMPLING_METHOD EQUAL RESIDUAL { driver.option_num("particle.resampling.method.kitagawa", "false"); driver.option_num("particle.resampling.method.smooth", "false"); driver.option_num("particle.resampling.method.stratified", "false"); driver.option_num("particle.resampling.method.residual", "true"); };
o_cpf_weights : CPF_WEIGHTS EQUAL AMISANOTRISTANI { driver.option_num("particle.cpf_weights_method.amisanotristani", "true"); driver.option_num("particle.cpf_weights_method.murrayjonesparslow", "false"); }
| CPF_WEIGHTS EQUAL MURRAYJONESPARSLOW { driver.option_num("particle.cpf_weights_method.amisanotristani", "false"); driver.option_num("particle.cpf_weights_method.murrayjonesparslow", "true"); };
| CPF_WEIGHTS EQUAL MURRAYJONESPARSLOW { driver.option_num("particle.cpf_weights_method.amisanotristani", "false"); driver.option_num("particle.cpf_weights_method.murrayjonesparslow", "true"); };
o_filter_algorithm : FILTER_ALGORITHM EQUAL symbol { driver.option_str("particle.filter_algorithm", $3); };
o_nonlinear_filter_initialization : NONLINEAR_FILTER_INITIALIZATION EQUAL INT_NUMBER { driver.option_num("particle.initialization", $3); };
o_proposal_approximation : PROPOSAL_APPROXIMATION EQUAL CUBATURE { driver.option_num("particle.proposal_approximation.cubature", "true"); driver.option_num("particle.proposal_approximation.unscented", "false"); driver.option_num("particle.proposal_approximation.montecarlo", "false"); }
......@@ -4309,10 +4355,11 @@ o_analytic_derivation_mode : ANALYTIC_DERIVATION_MODE EQUAL signed_number { driv
o_endogenous_prior : ENDOGENOUS_PRIOR { driver.option_num("endogenous_prior", "true"); }
o_use_univariate_filters_if_singularity_is_detected : USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED EQUAL INT_NUMBER { driver.option_num("use_univariate_filters_if_singularity_is_detected", $3); }
o_mcmc_jumping_covariance : MCMC_JUMPING_COVARIANCE EQUAL HESSIAN
{ driver.option_str("MCMC_jumping_covariance", $3); } | MCMC_JUMPING_COVARIANCE EQUAL PRIOR_VARIANCE
{ driver.option_str("MCMC_jumping_covariance", $3); }
{ driver.option_str("MCMC_jumping_covariance", "hessian"); }
| MCMC_JUMPING_COVARIANCE EQUAL PRIOR_VARIANCE
{ driver.option_str("MCMC_jumping_covariance", "prior_variance"); }
| MCMC_JUMPING_COVARIANCE EQUAL IDENTITY_MATRIX
{ driver.option_str("MCMC_jumping_covariance", $3); }
{ driver.option_str("MCMC_jumping_covariance", "identity_matrix"); }
| MCMC_JUMPING_COVARIANCE EQUAL filename
{ driver.option_str("MCMC_jumping_covariance", $3); }
;
......@@ -4383,7 +4430,7 @@ o_emas_girf : EMAS_GIRF { driver.option_num("irf_opt.ergodic_mean_irf", "true");
o_emas_drop : EMAS_DROP EQUAL INT_NUMBER { driver.option_num("irf_opt.EM.drop", $3); };
o_emas_tolf : EMAS_TOLF EQUAL non_negative_number { driver.option_num("irf_opt.EM.tolf", $3); };
o_emas_max_iter : EMAS_MAX_ITER EQUAL INT_NUMBER { driver.option_num("irf_opt.EM.iter", $3); };
o_non_zero : NON_ZERO { driver.option_num("non_zero", "true"); };
o_non_zero : NON_ZERO { driver.option_num("steady.non_zero", "true"); };
// Some options to "identification"
o_no_identification_strength : NO_IDENTIFICATION_STRENGTH { driver.option_num("no_identification_strength", "true"); };
......@@ -4602,6 +4649,7 @@ symbol : NAME
| ADD
| MULTIPLY
| MFS
| RESIDUAL
;
%%
......
/* -*- C++ -*- */
/*
* Copyright © 2003-2024 Dynare Team
* Copyright © 2003-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -70,7 +70,7 @@ string eofbuff;
NAME [a-z_][a-z0-9_]*
FLOAT_NUMBER ((([0-9]*\.[0-9]+)|([0-9]+\.))([ed][-+]?[0-9]+)?)|([0-9]+[ed][-+]?[0-9]+)
DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]|[sh][12])
%%
/* Code put at the beginning of yylex() */
......@@ -236,6 +236,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<INITIAL>pac_target_info {BEGIN DYNARE_BLOCK; return token::PAC_TARGET_INFO;}
<INITIAL>matched_irfs {BEGIN DYNARE_BLOCK; return token::MATCHED_IRFS;}
<INITIAL>matched_irfs_weights {BEGIN DYNARE_BLOCK; return token::MATCHED_IRFS_WEIGHTS;}
<INITIAL>perfect_foresight_controlled_paths {BEGIN DYNARE_BLOCK; return token::PERFECT_FORESIGHT_CONTROLLED_PATHS;}
/* For the semicolon after an "end" keyword */
<INITIAL>; {return Dynare::parser::token_type (yytext[0]);}
......@@ -256,11 +257,12 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<INITIAL>prior_function {BEGIN DYNARE_STATEMENT; return token::PRIOR_FUNCTION;}
<INITIAL>posterior_function {BEGIN DYNARE_STATEMENT; return token::POSTERIOR_FUNCTION;}
/* Inside of a Dynare statement */
<DYNARE_STATEMENT>{DATE} {
<DYNARE_STATEMENT,DYNARE_BLOCK>{DATE} {
yylval->emplace<string>(yytext);
return token::DATE;
}
/* Inside a Dynare statement */
<DYNARE_STATEMENT>file {return token::FILE;}
<DYNARE_STATEMENT>datafile {return token::DATAFILE;}
<DYNARE_STATEMENT>dirname {return token::DIRNAME;}
......@@ -404,6 +406,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>logarithmic_reduction {return token::LOGARITHMIC_REDUCTION;}
<DYNARE_STATEMENT>use_univariate_filters_if_singularity_is_detected {return token::USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED;}
<DYNARE_STATEMENT>hybrid {return token::HYBRID;}
<DYNARE_STATEMENT>use_first_order_solution {return token::USE_FIRST_ORDER_SOLUTION;}
<DYNARE_STATEMENT>default {return token::DEFAULT;}
<DYNARE_STATEMENT>init2shocks {return token::INIT2SHOCKS;}
......@@ -416,6 +419,10 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>kitagawa {return token::KITAGAWA;}
<DYNARE_STATEMENT>smooth {return token::SMOOTH;}
<DYNARE_STATEMENT>stratified {return token::STRATIFIED;}
<DYNARE_STATEMENT>residual {
yylval->emplace<string>(yytext);
return token::RESIDUAL;
}
<DYNARE_STATEMENT>cpf_weights {return token::CPF_WEIGHTS;}
<DYNARE_STATEMENT>amisanotristani {return token::AMISANOTRISTANI;}
<DYNARE_STATEMENT>murrayjonesparslow {return token::MURRAYJONESPARSLOW;}
......@@ -464,10 +471,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
yylval->emplace<string>(yytext);
return token::DIRICHLET;
}
<DYNARE_STATEMENT>weibull {
yylval->emplace<string>(yytext);
return token::WEIBULL;
}
<DYNARE_STATEMENT>weibull {return token::WEIBULL;}
<DYNARE_STATEMENT>normal {
yylval->emplace<string>(yytext);
return token::NORMAL;
......@@ -600,18 +604,9 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>substitute_libs {return token::SUBSTITUTE_LIBS;}
<DYNARE_STATEMENT>compiler {return token::COMPILER;}
<DYNARE_STATEMENT>instruments {return token::INSTRUMENTS;}
<DYNARE_STATEMENT>hessian {
yylval->emplace<string>(yytext);
return token::HESSIAN;
}
<DYNARE_STATEMENT>prior_variance {
yylval->emplace<string>(yytext);
return token::PRIOR_VARIANCE;
}
<DYNARE_STATEMENT>identity_matrix {
yylval->emplace<string>(yytext);
return token::IDENTITY_MATRIX;
}
<DYNARE_STATEMENT>hessian {return token::HESSIAN;}
<DYNARE_STATEMENT>prior_variance {return token::PRIOR_VARIANCE;}
<DYNARE_STATEMENT>identity_matrix {return token::IDENTITY_MATRIX;}
<DYNARE_STATEMENT>mcmc_jumping_covariance {return token::MCMC_JUMPING_COVARIANCE;}
/* These four (var, varexo, varexo_det, parameters) are for change_type */
......@@ -711,14 +706,6 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>lmmcp {return token::LMMCP;}
<DYNARE_STATEMENT>additional_optimizer_steps {return token::ADDITIONAL_OPTIMIZER_STEPS;}
<DYNARE_STATEMENT>bartlett_kernel_lag {return token::BARTLETT_KERNEL_LAG; }
<DYNARE_STATEMENT>optimal {
yylval->emplace<string>(yytext);
return token::OPTIMAL;
}
<DYNARE_STATEMENT>diagonal {
yylval->emplace<string>(yytext);
return token::DIAGONAL;
}
<DYNARE_STATEMENT>gmm {return token::GMM;}
<DYNARE_STATEMENT>smm {return token::SMM;}
<DYNARE_STATEMENT>irf_matching {return token::IRF_MATCHING;}
......@@ -845,6 +832,8 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
return token::DD;
}
<DYNARE_BLOCK>weights {return token::WEIGHTS;}
<DYNARE_BLOCK>exogenize {return token::EXOGENIZE;}
<DYNARE_BLOCK>endogenize {return token::ENDOGENIZE;}
/* Inside Dynare statement */
<DYNARE_STATEMENT>solve_algo {return token::SOLVE_ALGO;}
......
/*
* Copyright © 2020-2023 Dynare Team
* Copyright © 2020-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -74,13 +74,12 @@ EquationTags::erase(const set<int>& eqns, const map<int, int>& old_eqn_num_2_new
eqn_tags.erase(eqn);
for (const auto& [oldeqn, neweqn] : old_eqn_num_2_new)
for (auto& [eqn, tags] : eqn_tags)
if (eqn == oldeqn)
{
auto tmp = eqn_tags.extract(eqn);
tmp.key() = neweqn;
eqn_tags.insert(move(tmp));
}
if (eqn_tags.contains(oldeqn))
{
auto tmp = eqn_tags.extract(oldeqn);
tmp.key() = neweqn;
eqn_tags.insert(move(tmp));
}
}
void
......
/*
* Copyright © 2007-2024 Dynare Team
* Copyright © 2007-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -2978,10 +2978,8 @@ UnaryOpNode::writeJsonOutput(ostream& output, const temporary_terms_t& temporary
output << "])";
return;
case UnaryOpcode::steadyState:
output << "(";
arg->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic);
output << ")";
return;
output << "STEADY_STATE";
break;
case UnaryOpcode::steadyStateParamDeriv:
{
auto varg = dynamic_cast<VariableNode*>(arg);
......@@ -6458,9 +6456,9 @@ TrinaryOpNode::eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v
switch (op_code)
{
case TrinaryOpcode::normcdf:
return (0.5 * (1 + erf((v1 - v2) / v3 / numbers::sqrt2)));
return 0.5 * (1 + erf((v1 - v2) / v3 / numbers::sqrt2));
case TrinaryOpcode::normpdf:
return (1 / (v3 * sqrt(2 * numbers::pi) * exp(pow((v1 - v2) / v3, 2) / 2)));
return 1 / (v3 * sqrt(2 * numbers::pi) * exp(pow((v1 - v2) / v3, 2) / 2));
}
__builtin_unreachable(); // Silence GCC warning
}
......@@ -6989,9 +6987,9 @@ TrinaryOpNode::isVariableNodeEqualTo([[maybe_unused]] SymbolType type_arg,
bool
TrinaryOpNode::containsPacExpectation(const string& pac_model_name) const
{
return (arg1->containsPacExpectation(pac_model_name)
|| arg2->containsPacExpectation(pac_model_name)
|| arg3->containsPacExpectation(pac_model_name));
return arg1->containsPacExpectation(pac_model_name)
|| arg2->containsPacExpectation(pac_model_name)
|| arg3->containsPacExpectation(pac_model_name);
}
bool
......@@ -7907,7 +7905,7 @@ ExternalFunctionNode::sameTefTermPredicate() const
{
return [this](expr_t e) {
auto e2 = dynamic_cast<ExternalFunctionNode*>(e);
return (e2 != nullptr && e2->symb_id == symb_id && e2->arguments == arguments);
return e2 != nullptr && e2->symb_id == symb_id && e2->arguments == arguments;
};
}
......@@ -8245,12 +8243,12 @@ FirstDerivExternalFunctionNode::sameTefTermPredicate() const
if (first_deriv_symb_id == symb_id)
return [this](expr_t e) {
auto e2 = dynamic_cast<ExternalFunctionNode*>(e);
return (e2 && e2->symb_id == symb_id && e2->arguments == arguments);
return e2 && e2->symb_id == symb_id && e2->arguments == arguments;
};
else
return [this](expr_t e) {
auto e2 = dynamic_cast<FirstDerivExternalFunctionNode*>(e);
return (e2 && e2->symb_id == symb_id && e2->arguments == arguments);
return e2 && e2->symb_id == symb_id && e2->arguments == arguments;
};
}
......@@ -8600,12 +8598,12 @@ SecondDerivExternalFunctionNode::sameTefTermPredicate() const
if (second_deriv_symb_id == symb_id)
return [this](expr_t e) {
auto e2 = dynamic_cast<ExternalFunctionNode*>(e);
return (e2 && e2->symb_id == symb_id && e2->arguments == arguments);
return e2 && e2->symb_id == symb_id && e2->arguments == arguments;
};
else
return [this](expr_t e) {
auto e2 = dynamic_cast<SecondDerivExternalFunctionNode*>(e);
return (e2 && e2->symb_id == symb_id && e2->arguments == arguments);
return e2 && e2->symb_id == symb_id && e2->arguments == arguments;
};
}
......@@ -9491,9 +9489,9 @@ ExprNode::matchParamTimesTargetMinusVariable(int symb_id) const
auto& avi = datatree.symbol_table.getAuxVarInfo(target->symb_id);
if (avi.type == AuxVarType::pacTargetNonstationary && target->lag == -1)
return true;
return (avi.type == AuxVarType::unaryOp && avi.unary_op == "log" && avi.orig_symb_id
&& !datatree.symbol_table.isAuxiliaryVariable(*avi.orig_symb_id)
&& target->lag + avi.orig_lead_lag.value() == -1);
return avi.type == AuxVarType::unaryOp && avi.unary_op == "log" && avi.orig_symb_id
&& !datatree.symbol_table.isAuxiliaryVariable(*avi.orig_symb_id)
&& target->lag + avi.orig_lead_lag.value() == -1;
}
else
return target->lag == -1;
......@@ -9572,13 +9570,14 @@ ExprNode::toString() const
}
tuple<int, expr_t, expr_t>
ExprNode::matchComplementarityCondition() const
ExprNode::matchComplementarityCondition(
[[maybe_unused]] const optional<int>& heterogeneity_dimension) const
{
throw MatchFailureException {"This expression is not an inequality"};
}
tuple<int, expr_t, expr_t>
BinaryOpNode::matchComplementarityCondition() const
BinaryOpNode::matchComplementarityCondition(const optional<int>& heterogeneity_dimension) const
{
bool is_greater {[&] {
switch (op_code)
......@@ -9596,7 +9595,13 @@ BinaryOpNode::matchComplementarityCondition() const
auto match_contemporaneous_endogenous = [&](expr_t e) -> optional<int> {
auto* ve = dynamic_cast<VariableNode*>(e);
if (ve && ve->lag == 0 && datatree.symbol_table.getType(ve->symb_id) == SymbolType::endogenous)
if (ve && ve->lag == 0
&& ((!heterogeneity_dimension
&& datatree.symbol_table.getType(ve->symb_id) == SymbolType::endogenous)
|| (heterogeneity_dimension
&& datatree.symbol_table.getType(ve->symb_id) == SymbolType::heterogeneousEndogenous
&& datatree.symbol_table.getHeterogeneityDimension(ve->symb_id)
== *heterogeneity_dimension)))
return ve->symb_id;
else
return nullopt;
......@@ -9633,11 +9638,11 @@ BinaryOpNode::matchComplementarityCondition() const
|| (!is_greater
&& (barg1->op_code == BinaryOpcode::less
|| barg1->op_code == BinaryOpcode::lessEqual)))))
throw MatchFailureException {"Complementarity condition does not have the right form"};
throw MatchFailureException {};
auto id = match_contemporaneous_endogenous(barg1->arg2);
if (!id)
throw MatchFailureException {"Complementarity condition does not have the right form"};
throw MatchFailureException {};
check_bound_constant(barg1->arg1);
check_bound_constant(arg2);
......
/*
* Copyright © 2007-2024 Dynare Team
* Copyright © 2007-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -283,7 +283,7 @@ protected:
min_cost(bool is_matlab)
{
return is_matlab ? min_cost_matlab : min_cost_c;
};
}
//! Initializes data member non_null_derivatives
virtual void prepareForDerivation() = 0;
......@@ -943,7 +943,8 @@ public:
/* Matches an expression that constitutes a complementarity condition.
If successful, returns a triplet (endo_symb_id, lower_bound, upper_bound).
Otherwise, throws a MatchFailureException. */
[[nodiscard]] virtual tuple<int, expr_t, expr_t> matchComplementarityCondition() const;
[[nodiscard]] virtual tuple<int, expr_t, expr_t>
matchComplementarityCondition(const optional<int>& heterogeneity_dimension = nullopt) const;
/* Replaces aggregation operators (e.g. SUM()) by new auxiliary variables.
Also declares those aggregation operators in the HeterogeneityTable, so as to
......@@ -1519,7 +1520,9 @@ public:
[[nodiscard]] expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override;
[[nodiscard]] expr_t substituteAggregationOperators(subst_table_t& subst_table,
vector<BinaryOpNode*>& neweqs) const override;
[[nodiscard]] tuple<int, expr_t, expr_t> matchComplementarityCondition() const override;
[[nodiscard]] tuple<int, expr_t, expr_t>
matchComplementarityCondition(const optional<int>& heterogeneity_dimension
= nullopt) const override;
};
//! Trinary operator node
......
......@@ -90,7 +90,7 @@ public:
};
void addSummedHeterogeneousEndogenous(int symb_id);
int getSummedHeterogenousEndogenousIndex(int symb_id) const;
[[nodiscard]] int getSummedHeterogenousEndogenousIndex(int symb_id) const;
[[nodiscard]] int aggregateEndoSize() const;
void writeOutput(ostream& output) const;
......
/*
* Copyright © 2024 Dynare Team
* Copyright © 2024-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -33,14 +33,6 @@ HeterogeneousModel::HeterogeneousModel(SymbolTable& symbol_table_arg,
{
}
HeterogeneousModel::HeterogeneousModel(const HeterogeneousModel& m) :
ModelTree {m},
heterogeneity_dimension {m.heterogeneity_dimension},
deriv_id_table {m.deriv_id_table},
inv_deriv_id_table {m.inv_deriv_id_table}
{
}
HeterogeneousModel&
HeterogeneousModel::operator=(const HeterogeneousModel& m)
{
......@@ -123,14 +115,7 @@ HeterogeneousModel::computingPass(int derivsOrder, bool no_tmp_terms, bool use_d
computeTemporaryTerms(!use_dll, no_tmp_terms);
if (ranges::any_of(complementarity_conditions, [](const auto& x) { return x.has_value(); }))
{
// Implementing it requires modifications in ModelTree::computeMCPEquationsReordering()
cerr << "ERROR: Complementarity conditions are not yet implemented in "
"model(heterogeneity=...) blocks"
<< endl;
exit(EXIT_FAILURE);
}
computeMCPEquationsReordering(heterogeneity_dimension);
}
void
......@@ -138,6 +123,7 @@ HeterogeneousModel::writeModelFiles(const string& basename, bool julia) const
{
assert(!julia); // Not yet implemented
writeSparseModelMFiles<true>(basename, heterogeneity_dimension);
writeComplementarityConditionsFile<true>(basename, heterogeneity_dimension);
}
int
......@@ -245,4 +231,9 @@ HeterogeneousModel::writeDriverOutput(ostream& output) const
output << "];" << endl;
writeDriverSparseIndicesHelper(
"heterogeneity("s + to_string(heterogeneity_dimension + 1) + ").dynamic", output);
output << "M_.heterogeneity(" << heterogeneity_dimension + 1
<< ").dynamic_mcp_equations_reordering = [";
for (auto i : mcp_equations_reordering)
output << i + 1 << "; ";
output << "];" << endl;
}
......@@ -35,7 +35,7 @@ public:
ExternalFunctionsTable& external_functions_table_arg,
HeterogeneityTable& heterogeneity_table_arg, int heterogeneity_dimension_arg);
HeterogeneousModel(const HeterogeneousModel& m);
HeterogeneousModel(const HeterogeneousModel& m) = default;
HeterogeneousModel& operator=(const HeterogeneousModel& m);
void computingPass(int derivsOrder, bool no_tmp_terms, bool use_dll);
......
/*
* Copyright © 2006-2024 Dynare Team
* Copyright © 2006-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -1137,7 +1137,8 @@ ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global,
<< "M_.heteroskedastic_shocks.Qvalue_orig = [];" << endl
<< "M_.heteroskedastic_shocks.Qscale_orig = [];" << endl
<< "M_.matched_irfs = {};" << endl
<< "M_.matched_irfs_weights = {};" << endl;
<< "M_.matched_irfs_weights = {};" << endl
<< "M_.perfect_foresight_controlled_paths = [];" << endl;
// NB: options_.{ramsey,discretionary}_policy should rather be fields of M_
mOutputFile << boolalpha << "options_.linear = " << linear << ";" << endl
......
/*
* Copyright © 2010-2024 Dynare Team
* Copyright © 2010-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -62,6 +62,17 @@ protected:
{
return "original Ramsey model";
}
int
getJacobianCol(int deriv_id, [[maybe_unused]] bool sparse) const override
{
/* Override the DynamicModel method by returning a dummy Jacobian column number.
The override is necessary because the method from DynamicModel fails with
endos with lag/lead greater than 1 or exos with a lag/lead, while substitutions
are by definition not done for an original model.
In particular, this fixes dynare#1960 (equation derivatives are computed for models declared
as linear, to check whether they are truly linear). */
return deriv_id;
}
};
class SteadyStateModel : public DataTree
......
/*
* Copyright © 2003-2024 Dynare Team
* Copyright © 2003-2025 Dynare Team
*
* This file is part of Dynare.
*
......@@ -895,7 +895,7 @@ ModelTree::determineLinearBlocks()
int
ModelTree::equation_number() const
{
return (equations.size());
return equations.size();
}
void
......@@ -1398,8 +1398,7 @@ ModelTree::writeLatexModelFile(const string& mod_basename, const string& latex_b
content_output << endl << R"(\end{dmath})" << endl;
}
output << R"(\include{)" << latex_basename + "_content"
<< "}" << endl
output << R"(\include{)" << latex_basename + "_content" << "}" << endl
<< R"(\end{document})" << endl;
output.close();
......@@ -2119,11 +2118,13 @@ ModelTree::writeAuxVarRecursiveDefinitions(ostream& output, ExprNodeOutputType o
}
void
ModelTree::computeMCPEquationsReordering()
ModelTree::computeMCPEquationsReordering(const optional<int>& heterogeneous_dimension)
{
/* Optimal policy models (discretionary, or Ramsey before computing FOCs) do not have as many
equations as variables. Do not even try to compute the reordering. */
if (static_cast<int>(equations.size()) != symbol_table.endo_nbr())
if (static_cast<int>(equations.size())
!= (heterogeneous_dimension ? symbol_table.het_endo_nbr(*heterogeneous_dimension)
: symbol_table.endo_nbr()))
return;
assert(equations.size() == complementarity_conditions.size());
......