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 (52)
Showing with 405 additions and 313 deletions
...@@ -11,9 +11,12 @@ BreakInheritanceList: AfterColon ...@@ -11,9 +11,12 @@ BreakInheritanceList: AfterColon
Cpp11BracedListStyle: true Cpp11BracedListStyle: true
DeriveLineEnding: false DeriveLineEnding: false
IndentPPDirectives: AfterHash IndentPPDirectives: AfterHash
InsertNewlineAtEOF: true
PackConstructorInitializers: NextLine PackConstructorInitializers: NextLine
PPIndentWidth: 1 PPIndentWidth: 1
PointerAlignment: Left PointerAlignment: Left
# RemoveParentheses: ReturnStatement
# RemoveSemicolon: true
SpaceAfterTemplateKeyword: false SpaceAfterTemplateKeyword: false
SpaceBeforeParens: ControlStatements SpaceBeforeParens: ControlStatements
SpaceBeforeCpp11BracedList: true SpaceBeforeCpp11BracedList: true
variables: variables:
TERM: linux 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' 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 # 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' FF_ENABLE_BASH_EXIT_CODE_CHECK: 'true'
...@@ -77,3 +77,16 @@ test_clang_format: ...@@ -77,3 +77,16 @@ test_clang_format:
- meson setup build-clang-format - meson setup build-clang-format
- ninja -C build-clang-format clang-format-check - ninja -C build-clang-format clang-format-check
needs: [] 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
# Meson cross file for creating a WebAssembly version of the preprocessor.
#
# Requires emscripten to be installed.
# Was successfully tested with emscripten 3.1.69 installed through emsdk
# tool, as described on: https://emscripten.org/docs/getting_started/downloads.html
# Don’t forget to source script snippet in current shell before running meson.
#
# Compilation creates a .wasm and .js wrapper under <builddir>/src/
#
# Can be run locally with node.js using:
# node dynare-preprocessor.js file.mod
# NB: a version of node.js is shipped with emscripten (under the node/
# subdirectory), but another version should also work.
[binaries]
cpp = 'em++'
[host_machine]
system = 'emscripten'
# Could be changed to wasm64 if 4GB memory constraint is hit
# Some background: https://v8.dev/blog/4gb-wasm-memory
cpu_family = 'wasm32'
cpu = 'wasm32'
endian = 'little'
[built-in options]
# Never do a debug build, because otherwise the lack of optimisations can
# overflow the memory capacities.
buildtype = 'release'
# The -fexceptions flag (for both compilation and linking) is needed for an
# unknown reason (C++ compilers are supposed to always add exception support).
# The -Wno-unqualified-std-cast-call flag removes many warnings about “move”
# not being qualified with “std::” namespace.
# The -fexperimental-library flag is needed to get std::jthread support (it was
# supposed to no longer be necessary for LLVM 20, but for some reason we still
# need it).
cpp_args = [ '-fexceptions', '-Wno-unqualified-std-cast-call', '-fexperimental-library' ]
# NODERAWFS=1 is needed for accessing the local filesystem
cpp_link_args = [ '-s', 'NODERAWFS=1', '-fexceptions' ]
[properties]
# It’s necessary to use a different copy of Boost than the one under
# /usr/include, because otherwise GCC headers confuse Clang
boost_root = '/tmp/boost_1_86_0'
...@@ -283,7 +283,9 @@ PerfectForesightWithExpectationErrorsSolverStatement::writeOutput( ...@@ -283,7 +283,9 @@ PerfectForesightWithExpectationErrorsSolverStatement::writeOutput(
[[maybe_unused]] bool minimal_workspace) const [[maybe_unused]] bool minimal_workspace) const
{ {
options_list.writeOutput(output); 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 void
...@@ -3713,8 +3715,7 @@ SvarGlobalIdentificationCheckStatement::writeJsonOutput(ostream& output) const ...@@ -3713,8 +3715,7 @@ SvarGlobalIdentificationCheckStatement::writeJsonOutput(ostream& output) const
output << R"({"statementName": "svar_global_identification"})"; output << R"({"statementName": "svar_global_identification"})";
} }
SetTimeStatement::SetTimeStatement(OptionsList options_list_arg) : SetTimeStatement::SetTimeStatement(string period_arg) : period {move(period_arg)}
options_list {move(options_list_arg)}
{ {
} }
...@@ -3722,19 +3723,13 @@ void ...@@ -3722,19 +3723,13 @@ void
SetTimeStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, SetTimeStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename,
[[maybe_unused]] bool minimal_workspace) const [[maybe_unused]] bool minimal_workspace) const
{ {
options_list.writeOutput(output); output << "options_.initial_period = " << period << endl;
} }
void void
SetTimeStatement::writeJsonOutput(ostream& output) const SetTimeStatement::writeJsonOutput(ostream& output) const
{ {
output << R"({"statementName": "set_time")"; output << R"({"statementName": "set_time", "period": ")" << period << R"("})";
if (!options_list.empty())
{
output << ", ";
options_list.writeJsonOutput(output);
}
output << "}";
} }
EstimationDataStatement::EstimationDataStatement(OptionsList options_list_arg) : EstimationDataStatement::EstimationDataStatement(OptionsList options_list_arg) :
...@@ -5347,8 +5342,8 @@ void ...@@ -5347,8 +5342,8 @@ void
ResidStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, ResidStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename,
[[maybe_unused]] bool minimal_workspace) const [[maybe_unused]] bool minimal_workspace) const
{ {
options_list.writeOutput(output, "options_resid_"); options_list.writeOutput(output);
output << "display_static_residuals(M_, options_, oo_, options_resid_);" << endl; output << "display_static_residuals(M_, options_, oo_);" << endl;
} }
void void
......
...@@ -524,7 +524,7 @@ public: ...@@ -524,7 +524,7 @@ public:
blockName() const override blockName() const override
{ {
return "estimated_params"; return "estimated_params";
}; }
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override; void writeJsonOutput(ostream& output) const override;
...@@ -542,7 +542,7 @@ public: ...@@ -542,7 +542,7 @@ public:
blockName() const override blockName() const override
{ {
return "estimated_params_init"; return "estimated_params_init";
}; }
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override; void writeJsonOutput(ostream& output) const override;
...@@ -557,7 +557,7 @@ public: ...@@ -557,7 +557,7 @@ public:
blockName() const override blockName() const override
{ {
return "estimated_params_bounds"; return "estimated_params_bounds";
}; }
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override; void writeJsonOutput(ostream& output) const override;
...@@ -1007,10 +1007,10 @@ public: ...@@ -1007,10 +1007,10 @@ public:
class SetTimeStatement : public Statement class SetTimeStatement : public Statement
{ {
private: private:
const OptionsList options_list; const string period;
public: public:
explicit SetTimeStatement(OptionsList options_list_arg); explicit SetTimeStatement(string period_arg);
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override; void writeJsonOutput(ostream& output) const override;
}; };
......
...@@ -47,7 +47,7 @@ private: ...@@ -47,7 +47,7 @@ private:
get_paths() const get_paths() const
{ {
return paths; return paths;
}; }
private: private:
map<string, vector<string>> paths; map<string, vector<string>> paths;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
#include <ranges>
#include "DataTree.hh" #include "DataTree.hh"
...@@ -69,13 +70,14 @@ DataTree::DataTree(const DataTree& d) : ...@@ -69,13 +70,14 @@ DataTree::DataTree(const DataTree& d) :
// Constants must be initialized first because they are used in some Add* methods // Constants must be initialized first because they are used in some Add* methods
initConstants(); 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) for (const auto& it : d.node_list)
it->clone(*this); it->clone(*this);
assert(node_list.size() == d.node_list.size()); 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& DataTree&
...@@ -804,9 +806,9 @@ DataTree::AddSum(expr_t arg) ...@@ -804,9 +806,9 @@ DataTree::AddSum(expr_t arg)
bool bool
DataTree::isSymbolUsed(int symb_id) const DataTree::isSymbolUsed(int symb_id) const
{ {
for (const auto& [symb_lag, expr] : variable_node_map) if (ranges::any_of(views::keys(variable_node_map),
if (symb_lag.first == symb_id) [=](const auto& symb_lag) { return symb_lag.first == symb_id; }))
return true; return true;
if (local_variables_table.contains(symb_id)) if (local_variables_table.contains(symb_id))
return true; return true;
...@@ -852,18 +854,18 @@ DataTree::addAllParamDerivId([[maybe_unused]] set<int>& deriv_id_set) ...@@ -852,18 +854,18 @@ DataTree::addAllParamDerivId([[maybe_unused]] set<int>& deriv_id_set)
bool bool
DataTree::isUnaryOpUsed(UnaryOpcode opcode) const DataTree::isUnaryOpUsed(UnaryOpcode opcode) const
{ {
return ranges::any_of(unary_op_node_map, return ranges::any_of(views::keys(unary_op_node_map),
[=](const auto& it) { return get<1>(it.first) == opcode; }); [=](const auto& key) { return get<1>(key) == opcode; });
} }
bool bool
DataTree::isUnaryOpUsedOnType(SymbolType type, UnaryOpcode opcode) const DataTree::isUnaryOpUsedOnType(SymbolType type, UnaryOpcode opcode) const
{ {
set<int> var; set<int> var;
for (const auto& it : unary_op_node_map) for (const auto& [key, value] : unary_op_node_map)
if (get<1>(it.first) == opcode) if (get<1>(key) == opcode)
{ {
it.second->collectVariables(type, var); value->collectVariables(type, var);
if (!var.empty()) if (!var.empty())
return true; return true;
} }
...@@ -873,18 +875,18 @@ DataTree::isUnaryOpUsedOnType(SymbolType type, UnaryOpcode opcode) const ...@@ -873,18 +875,18 @@ DataTree::isUnaryOpUsedOnType(SymbolType type, UnaryOpcode opcode) const
bool bool
DataTree::isBinaryOpUsed(BinaryOpcode opcode) const DataTree::isBinaryOpUsed(BinaryOpcode opcode) const
{ {
return ranges::any_of(binary_op_node_map, return ranges::any_of(views::keys(binary_op_node_map),
[=](const auto& it) { return get<2>(it.first) == opcode; }); [=](const auto& key) { return get<2>(key) == opcode; });
} }
bool bool
DataTree::isBinaryOpUsedOnType(SymbolType type, BinaryOpcode opcode) const DataTree::isBinaryOpUsedOnType(SymbolType type, BinaryOpcode opcode) const
{ {
set<int> var; set<int> var;
for (const auto& it : binary_op_node_map) for (const auto& [key, value] : binary_op_node_map)
if (get<2>(it.first) == opcode) if (get<2>(key) == opcode)
{ {
it.second->collectVariables(type, var); value->collectVariables(type, var);
if (!var.empty()) if (!var.empty())
return true; return true;
} }
......
...@@ -367,7 +367,13 @@ public: ...@@ -367,7 +367,13 @@ public:
if (it == local_variables_table.end()) if (it == local_variables_table.end())
throw UnknownLocalVariableException {symb_id}; 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 static void
...@@ -396,7 +402,7 @@ DataTree::AddPossiblyNegativeConstant(double v) ...@@ -396,7 +402,7 @@ DataTree::AddPossiblyNegativeConstant(double v)
if (isnan(v)) if (isnan(v))
return NaN; return NaN;
if (isinf(v)) if (isinf(v))
return (v < 0 ? MinusInfinity : Infinity); return v < 0 ? MinusInfinity : Infinity;
bool neg = false; bool neg = false;
if (v < 0) if (v < 0)
......
/* /*
* Copyright © 2003-2024 Dynare Team * Copyright © 2003-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -731,9 +731,9 @@ DynamicModel::removeEquationsHelper( ...@@ -731,9 +731,9 @@ DynamicModel::removeEquationsHelper(
} }
int n_excl = all_equations.size() - new_equations.size(); int n_excl = all_equations.size() - new_equations.size();
all_equations = new_equations; all_equations = move(new_equations);
all_equations_lineno = new_equations_lineno; all_equations_lineno = move(new_equations_lineno);
all_complementarity_conditions = new_complementarity_conditions; all_complementarity_conditions = move(new_complementarity_conditions);
all_equation_tags.erase(eqs_to_delete_by_number, old_eqn_num_2_new); all_equation_tags.erase(eqs_to_delete_by_number, old_eqn_num_2_new);
...@@ -1043,14 +1043,8 @@ DynamicModel::writeDriverOutput(ostream& output, bool compute_xrefs) const ...@@ -1043,14 +1043,8 @@ DynamicModel::writeDriverOutput(ostream& output, bool compute_xrefs) const
<< (static_only_equations.size() > 0) << ";" << endl; << (static_only_equations.size() > 0) << ";" << endl;
// Say if model contains an external function call // Say if model contains an external function call
bool has_external_function = false; output << "M_.has_external_function = " << boolalpha
for (auto equation : equations) << ranges::any_of(equations, &ExprNode::containsExternalFunction) << ';' << endl;
if (equation->containsExternalFunction())
{
has_external_function = true;
break;
}
output << "M_.has_external_function = " << boolalpha << has_external_function << ';' << endl;
// Compute list of state variables, ordered in block-order // Compute list of state variables, ordered in block-order
vector<int> state_var; vector<int> state_var;
...@@ -1359,8 +1353,7 @@ DynamicModel::fillVarModelTableFromOrigModel() const ...@@ -1359,8 +1353,7 @@ DynamicModel::fillVarModelTableFromOrigModel() const
// save lhs variables // save lhs variables
equations[eqn]->arg1->collectVARLHSVariable(lhs); equations[eqn]->arg1->collectVARLHSVariable(lhs);
equations[eqn]->arg1->countDiffs() > 0 ? diff_vec.push_back(true) diff_vec.push_back(equations[eqn]->arg1->countDiffs() > 0);
: diff_vec.push_back(false);
if (diff_vec.back()) if (diff_vec.back())
{ {
set<pair<int, int>> diff_set; set<pair<int, int>> diff_set;
...@@ -1704,10 +1697,7 @@ DynamicModel::fillTrendComponentModelTableFromOrigModel() const ...@@ -1704,10 +1697,7 @@ DynamicModel::fillTrendComponentModelTableFromOrigModel() const
// save lhs variables // save lhs variables
equations[eqn]->arg1->collectVARLHSVariable(lhs); equations[eqn]->arg1->collectVARLHSVariable(lhs);
if (equations[eqn]->arg1->countDiffs() > 0) diff_vec.push_back(equations[eqn]->arg1->countDiffs() > 0);
diff_vec.push_back(true);
else
diff_vec.push_back(false);
if (diff_vec.back()) if (diff_vec.back())
{ {
set<pair<int, int>> diff_set; set<pair<int, int>> diff_set;
...@@ -1780,7 +1770,7 @@ DynamicModel::getUndiffLHSForPac(const string& aux_model_name, ...@@ -1780,7 +1770,7 @@ DynamicModel::getUndiffLHSForPac(const string& aux_model_name,
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (diff.at(i) != true) if (!diff.at(i))
{ {
cerr << "ERROR: the variable on the LHS of equation #" << eqn cerr << "ERROR: the variable on the LHS of equation #" << eqn
<< " does not have the diff operator applied to it yet you are trying to undiff it." << " does not have the diff operator applied to it yet you are trying to undiff it."
...@@ -1788,7 +1778,6 @@ DynamicModel::getUndiffLHSForPac(const string& aux_model_name, ...@@ -1788,7 +1778,6 @@ DynamicModel::getUndiffLHSForPac(const string& aux_model_name,
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
bool printerr = false;
expr_t node = nullptr; expr_t node = nullptr;
expr_t aux_var = lhs_expr_t.at(i); expr_t aux_var = lhs_expr_t.at(i);
for (const auto& it : diff_subst_table) for (const auto& it : diff_subst_table)
...@@ -1805,11 +1794,8 @@ DynamicModel::getUndiffLHSForPac(const string& aux_model_name, ...@@ -1805,11 +1794,8 @@ DynamicModel::getUndiffLHSForPac(const string& aux_model_name,
} }
node = node->undiff(); node = node->undiff();
auto it1 = diff_subst_table.find(node);
if (it1 == diff_subst_table.end())
printerr = true;
if (printerr) if (auto it1 = diff_subst_table.find(node); it1 == diff_subst_table.end())
{ // we have undiffed something like diff(x), hence x is not in diff_subst_table { // we have undiffed something like diff(x), hence x is not in diff_subst_table
lhs_expr_t.at(i) = node; lhs_expr_t.at(i) = node;
lhs.at(i) = dynamic_cast<VariableNode*>(node)->symb_id; lhs.at(i) = dynamic_cast<VariableNode*>(node)->symb_id;
...@@ -1830,7 +1816,7 @@ DynamicModel::analyzePacEquationStructure(const string& name, map<string, string ...@@ -1830,7 +1816,7 @@ DynamicModel::analyzePacEquationStructure(const string& name, map<string, string
for (auto& equation : equations) for (auto& equation : equations)
if (equation->containsPacExpectation(name)) 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 cerr << "It is not possible to use 'pac_expectation(" << name
<< ")' in several equations." << endl; << ")' in several equations." << endl;
...@@ -1929,6 +1915,13 @@ DynamicModel::analyzePacEquationStructure(const string& name, map<string, string ...@@ -1929,6 +1915,13 @@ DynamicModel::analyzePacEquationStructure(const string& name, map<string, string
move(additive_vars_params_and_constants), move(additive_vars_params_and_constants),
move(optim_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 int
...@@ -3755,18 +3748,18 @@ void ...@@ -3755,18 +3748,18 @@ void
DynamicModel::detrendEquations() DynamicModel::detrendEquations()
{ {
// We go backwards in the list of trend_vars, to deal correctly with I(2) processes // We go backwards in the list of trend_vars, to deal correctly with I(2) processes
for (const auto& it : std::ranges::reverse_view(nonstationary_symbols_map)) for (const auto& [symb_id, deflator] : std::ranges::reverse_view(nonstationary_symbols_map))
{ {
for (auto& equation : equations) for (auto& equation : equations)
{ {
equation = dynamic_cast<BinaryOpNode*>( equation = dynamic_cast<BinaryOpNode*>(
equation->detrend(it.first, it.second.first, it.second.second)); equation->detrend(symb_id, deflator.first, deflator.second));
assert(equation); assert(equation);
} }
for (auto& equation : static_only_equations) for (auto& equation : static_only_equations)
{ {
equation = dynamic_cast<BinaryOpNode*>( equation = dynamic_cast<BinaryOpNode*>(
equation->detrend(it.first, it.second.first, it.second.second)); equation->detrend(symb_id, deflator.first, deflator.second));
assert(equation); assert(equation);
} }
} }
......
...@@ -73,7 +73,8 @@ public: ...@@ -73,7 +73,8 @@ public:
void checkAllRegimesPresent() const noexcept(false); void checkAllRegimesPresent() const noexcept(false);
private: 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: private:
...@@ -713,7 +714,7 @@ public: ...@@ -713,7 +714,7 @@ public:
{ {
return tuple {static_only_equations, static_only_equations_lineno, return tuple {static_only_equations, static_only_equations_lineno,
static_only_complementarity_conditions, static_only_equations_equation_tags}; 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 //! Returns true if a parameter was used in the model block with a lead or lag
bool ParamUsedWithLeadLag() const; bool ParamUsedWithLeadLag() const;
......
This diff is collapsed.
/* -*- C++ -*- */ /* -*- C++ -*- */
/* /*
* Copyright © 2003-2024 Dynare Team * Copyright © 2003-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
%{ %{
#include <cstring>
#include "ParsingDriver.hh" #include "ParsingDriver.hh"
using namespace std; using namespace std;
...@@ -60,7 +59,6 @@ string eofbuff; ...@@ -60,7 +59,6 @@ string eofbuff;
%x VERBATIM_BLOCK %x VERBATIM_BLOCK
%x NATIVE %x NATIVE
%x NATIVE_COMMENT %x NATIVE_COMMENT
%x DATES_STATEMENT
%x LINE1 %x LINE1
%x LINE2 %x LINE2
%x LINE3 %x LINE3
...@@ -70,7 +68,9 @@ string eofbuff; ...@@ -70,7 +68,9 @@ string eofbuff;
#define YY_USER_ACTION location_increment(yylloc, yytext); #define YY_USER_ACTION location_increment(yylloc, yytext);
%} %}
DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) 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]|[sh][12])
%% %%
/* Code put at the beginning of yylex() */ /* Code put at the beginning of yylex() */
...@@ -92,12 +92,12 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -92,12 +92,12 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
} }
/* spaces, tabs and carriage returns are ignored */ /* spaces, tabs and carriage returns are ignored */
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,COMMENT,DATES_STATEMENT,LINE1,LINE2,LINE3>[[:space:]]+ { yylloc->step(); } <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,COMMENT,LINE1,LINE2,LINE3>[[:space:]]+ { yylloc->step(); }
/* Comments */ /* Comments */
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,DATES_STATEMENT>%.* <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK>%.*
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,DATES_STATEMENT>"//".* <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK>"//".*
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,DATES_STATEMENT>"/*" {comment_caller = YY_START; BEGIN COMMENT;} <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK>"/*" {comment_caller = YY_START; BEGIN COMMENT;}
<COMMENT>"*/" {BEGIN comment_caller;} <COMMENT>"*/" {BEGIN comment_caller;}
<COMMENT>. <COMMENT>.
...@@ -236,6 +236,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -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>pac_target_info {BEGIN DYNARE_BLOCK; return token::PAC_TARGET_INFO;}
<INITIAL>matched_irfs {BEGIN DYNARE_BLOCK; return token::MATCHED_IRFS;} <INITIAL>matched_irfs {BEGIN DYNARE_BLOCK; return token::MATCHED_IRFS;}
<INITIAL>matched_irfs_weights {BEGIN DYNARE_BLOCK; return token::MATCHED_IRFS_WEIGHTS;} <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 */ /* For the semicolon after an "end" keyword */
<INITIAL>; {return Dynare::parser::token_type (yytext[0]);} <INITIAL>; {return Dynare::parser::token_type (yytext[0]);}
...@@ -246,7 +247,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -246,7 +247,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>subsamples {return token::SUBSAMPLES;} <DYNARE_STATEMENT>subsamples {return token::SUBSAMPLES;}
<DYNARE_STATEMENT>options {return token::OPTIONS;} <DYNARE_STATEMENT>options {return token::OPTIONS;}
<DYNARE_STATEMENT>prior { <DYNARE_STATEMENT>prior {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::PRIOR; return token::PRIOR;
} }
<INITIAL>std {BEGIN DYNARE_STATEMENT; return token::STD;} <INITIAL>std {BEGIN DYNARE_STATEMENT; return token::STD;}
...@@ -256,24 +257,12 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -256,24 +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>prior_function {BEGIN DYNARE_STATEMENT; return token::PRIOR_FUNCTION;}
<INITIAL>posterior_function {BEGIN DYNARE_STATEMENT; return token::POSTERIOR_FUNCTION;} <INITIAL>posterior_function {BEGIN DYNARE_STATEMENT; return token::POSTERIOR_FUNCTION;}
/* Inside of a Dynare statement */ <DYNARE_STATEMENT,DYNARE_BLOCK>{DATE} {
<DYNARE_STATEMENT>{DATE} { yylval->emplace<string>(yytext);
char* yycopy = strdup(yytext); return token::DATE;
char* uput = yycopy + yyleng; }
unput(')');
unput('\''); /* Inside a Dynare statement */
while (uput > yycopy)
unput(*--uput);
unput('\'');
unput('(');
unput('s');
unput('e');
unput('t');
unput('a');
unput('d');
free( yycopy );
}
<DYNARE_STATEMENT>dates {dates_parens_nb=0; BEGIN DATES_STATEMENT; yylval->build<string>("dates");}
<DYNARE_STATEMENT>file {return token::FILE;} <DYNARE_STATEMENT>file {return token::FILE;}
<DYNARE_STATEMENT>datafile {return token::DATAFILE;} <DYNARE_STATEMENT>datafile {return token::DATAFILE;}
<DYNARE_STATEMENT>dirname {return token::DIRNAME;} <DYNARE_STATEMENT>dirname {return token::DIRNAME;}
...@@ -306,10 +295,10 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -306,10 +295,10 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>posterior_nograph {return token::POSTERIOR_NOGRAPH;} <DYNARE_STATEMENT>posterior_nograph {return token::POSTERIOR_NOGRAPH;}
<DYNARE_STATEMENT>nodisplay {return token::NODISPLAY;} <DYNARE_STATEMENT>nodisplay {return token::NODISPLAY;}
<DYNARE_STATEMENT>graph_format {return token::GRAPH_FORMAT;} <DYNARE_STATEMENT>graph_format {return token::GRAPH_FORMAT;}
<DYNARE_STATEMENT>eps {yylval->build<string>(yytext); return token::EPS;} <DYNARE_STATEMENT>eps {yylval->emplace<string>(yytext); return token::EPS;}
<DYNARE_STATEMENT>pdf {yylval->build<string>(yytext); return token::PDF;} <DYNARE_STATEMENT>pdf {yylval->emplace<string>(yytext); return token::PDF;}
<DYNARE_STATEMENT>fig {yylval->build<string>(yytext); return token::FIG;} <DYNARE_STATEMENT>fig {yylval->emplace<string>(yytext); return token::FIG;}
<DYNARE_STATEMENT>none {yylval->build<string>(yytext); return token::NONE;} <DYNARE_STATEMENT>none {yylval->emplace<string>(yytext); return token::NONE;}
<DYNARE_STATEMENT>print {return token::PRINT;} <DYNARE_STATEMENT>print {return token::PRINT;}
<DYNARE_STATEMENT>noprint {return token::NOPRINT;} <DYNARE_STATEMENT>noprint {return token::NOPRINT;}
<DYNARE_STATEMENT>conf_sig {return token::CONF_SIG;} <DYNARE_STATEMENT>conf_sig {return token::CONF_SIG;}
...@@ -417,6 +406,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -417,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>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>use_univariate_filters_if_singularity_is_detected {return token::USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED;}
<DYNARE_STATEMENT>hybrid {return token::HYBRID;} <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>default {return token::DEFAULT;}
<DYNARE_STATEMENT>init2shocks {return token::INIT2SHOCKS;} <DYNARE_STATEMENT>init2shocks {return token::INIT2SHOCKS;}
...@@ -429,6 +419,10 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -429,6 +419,10 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>kitagawa {return token::KITAGAWA;} <DYNARE_STATEMENT>kitagawa {return token::KITAGAWA;}
<DYNARE_STATEMENT>smooth {return token::SMOOTH;} <DYNARE_STATEMENT>smooth {return token::SMOOTH;}
<DYNARE_STATEMENT>stratified {return token::STRATIFIED;} <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>cpf_weights {return token::CPF_WEIGHTS;}
<DYNARE_STATEMENT>amisanotristani {return token::AMISANOTRISTANI;} <DYNARE_STATEMENT>amisanotristani {return token::AMISANOTRISTANI;}
<DYNARE_STATEMENT>murrayjonesparslow {return token::MURRAYJONESPARSLOW;} <DYNARE_STATEMENT>murrayjonesparslow {return token::MURRAYJONESPARSLOW;}
...@@ -450,43 +444,40 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -450,43 +444,40 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>fsolve_options {return token::FSOLVE_OPTIONS;} <DYNARE_STATEMENT>fsolve_options {return token::FSOLVE_OPTIONS;}
<DYNARE_STATEMENT>alpha { <DYNARE_STATEMENT>alpha {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::ALPHA; return token::ALPHA;
} }
<DYNARE_STATEMENT>beta { <DYNARE_STATEMENT>beta {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::BETA; return token::BETA;
} }
<DYNARE_STATEMENT>gamma { <DYNARE_STATEMENT>gamma {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::GAMMA; return token::GAMMA;
} }
<DYNARE_STATEMENT>inv_gamma { <DYNARE_STATEMENT>inv_gamma {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::INV_GAMMA; return token::INV_GAMMA;
} }
<DYNARE_STATEMENT>inv_gamma1 { <DYNARE_STATEMENT>inv_gamma1 {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::INV_GAMMA1; return token::INV_GAMMA1;
} }
<DYNARE_STATEMENT>inv_gamma2 { <DYNARE_STATEMENT>inv_gamma2 {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::INV_GAMMA2; return token::INV_GAMMA2;
} }
<DYNARE_STATEMENT>dirichlet { <DYNARE_STATEMENT>dirichlet {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::DIRICHLET; return token::DIRICHLET;
} }
<DYNARE_STATEMENT>weibull { <DYNARE_STATEMENT>weibull {return token::WEIBULL;}
yylval->build<string>(yytext);
return token::WEIBULL;
}
<DYNARE_STATEMENT>normal { <DYNARE_STATEMENT>normal {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::NORMAL; return token::NORMAL;
} }
<DYNARE_STATEMENT>uniform { <DYNARE_STATEMENT>uniform {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::UNIFORM; return token::UNIFORM;
} }
<DYNARE_STATEMENT>gsig2_lmdm {return token::GSIG2_LMDM;} <DYNARE_STATEMENT>gsig2_lmdm {return token::GSIG2_LMDM;}
...@@ -497,13 +488,13 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -497,13 +488,13 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>ncsk {return token::NCSK;} <DYNARE_STATEMENT>ncsk {return token::NCSK;}
<DYNARE_STATEMENT>nstd {return token::NSTD;} <DYNARE_STATEMENT>nstd {return token::NSTD;}
<DYNARE_STATEMENT>ninv { <DYNARE_STATEMENT>ninv {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::NINV; return token::NINV;
} }
<DYNARE_STATEMENT>indxparr {return token::INDXPARR;} <DYNARE_STATEMENT>indxparr {return token::INDXPARR;}
<DYNARE_STATEMENT>indxovr {return token::INDXOVR;} <DYNARE_STATEMENT>indxovr {return token::INDXOVR;}
<DYNARE_STATEMENT>aband { <DYNARE_STATEMENT>aband {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::ABAND; return token::ABAND;
} }
<DYNARE_STATEMENT>write_equation_tags {return token::WRITE_EQUATION_TAGS;} <DYNARE_STATEMENT>write_equation_tags {return token::WRITE_EQUATION_TAGS;}
...@@ -520,18 +511,18 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -520,18 +511,18 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>indxgdls {return token::INDXGDLS;} <DYNARE_STATEMENT>indxgdls {return token::INDXGDLS;}
<DYNARE_STATEMENT>eq_ms {return token::EQ_MS;} <DYNARE_STATEMENT>eq_ms {return token::EQ_MS;}
<DYNARE_STATEMENT>cms { <DYNARE_STATEMENT>cms {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::CMS; return token::CMS;
} }
<DYNARE_STATEMENT>ncms { <DYNARE_STATEMENT>ncms {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::NCMS; return token::NCMS;
} }
<DYNARE_STATEMENT>eq_cms {return token::EQ_CMS;} <DYNARE_STATEMENT>eq_cms {return token::EQ_CMS;}
<DYNARE_STATEMENT>tlindx {return token::TLINDX;} <DYNARE_STATEMENT>tlindx {return token::TLINDX;}
<DYNARE_STATEMENT>tlnumber {return token::TLNUMBER;} <DYNARE_STATEMENT>tlnumber {return token::TLNUMBER;}
<DYNARE_STATEMENT>cnum { <DYNARE_STATEMENT>cnum {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::CNUM; return token::CNUM;
} }
<DYNARE_STATEMENT>nodecomposition {return token::NODECOMPOSITION;}; <DYNARE_STATEMENT>nodecomposition {return token::NODECOMPOSITION;};
...@@ -613,18 +604,9 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -613,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>substitute_libs {return token::SUBSTITUTE_LIBS;}
<DYNARE_STATEMENT>compiler {return token::COMPILER;} <DYNARE_STATEMENT>compiler {return token::COMPILER;}
<DYNARE_STATEMENT>instruments {return token::INSTRUMENTS;} <DYNARE_STATEMENT>instruments {return token::INSTRUMENTS;}
<DYNARE_STATEMENT>hessian { <DYNARE_STATEMENT>hessian {return token::HESSIAN;}
yylval->build<string>(yytext); <DYNARE_STATEMENT>prior_variance {return token::PRIOR_VARIANCE;}
return token::HESSIAN; <DYNARE_STATEMENT>identity_matrix {return token::IDENTITY_MATRIX;}
}
<DYNARE_STATEMENT>prior_variance {
yylval->build<string>(yytext);
return token::PRIOR_VARIANCE;
}
<DYNARE_STATEMENT>identity_matrix {
yylval->build<string>(yytext);
return token::IDENTITY_MATRIX;
}
<DYNARE_STATEMENT>mcmc_jumping_covariance {return token::MCMC_JUMPING_COVARIANCE;} <DYNARE_STATEMENT>mcmc_jumping_covariance {return token::MCMC_JUMPING_COVARIANCE;}
/* These four (var, varexo, varexo_det, parameters) are for change_type */ /* These four (var, varexo, varexo_det, parameters) are for change_type */
...@@ -724,14 +706,6 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -724,14 +706,6 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>lmmcp {return token::LMMCP;} <DYNARE_STATEMENT>lmmcp {return token::LMMCP;}
<DYNARE_STATEMENT>additional_optimizer_steps {return token::ADDITIONAL_OPTIMIZER_STEPS;} <DYNARE_STATEMENT>additional_optimizer_steps {return token::ADDITIONAL_OPTIMIZER_STEPS;}
<DYNARE_STATEMENT>bartlett_kernel_lag {return token::BARTLETT_KERNEL_LAG; } <DYNARE_STATEMENT>bartlett_kernel_lag {return token::BARTLETT_KERNEL_LAG; }
<DYNARE_STATEMENT>optimal {
yylval->build<string>(yytext);
return token::OPTIMAL;
}
<DYNARE_STATEMENT>diagonal {
yylval->build<string>(yytext);
return token::DIAGONAL;
}
<DYNARE_STATEMENT>gmm {return token::GMM;} <DYNARE_STATEMENT>gmm {return token::GMM;}
<DYNARE_STATEMENT>smm {return token::SMM;} <DYNARE_STATEMENT>smm {return token::SMM;}
<DYNARE_STATEMENT>irf_matching {return token::IRF_MATCHING;} <DYNARE_STATEMENT>irf_matching {return token::IRF_MATCHING;}
...@@ -777,8 +751,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -777,8 +751,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>non_zero {return token::NON_ZERO;} <DYNARE_STATEMENT>non_zero {return token::NON_ZERO;}
<DYNARE_STATEMENT>\$[^$]*\$ { <DYNARE_STATEMENT>\$[^$]*\$ {
strtok(yytext + 1, "$"); yylval->emplace<string>(yytext + 1).pop_back();
yylval->build<string>(yytext + 1);
return token::TEX_NAME; return token::TEX_NAME;
} }
...@@ -791,16 +764,16 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -791,16 +764,16 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_BLOCK>periods {return token::PERIODS;} <DYNARE_BLOCK>periods {return token::PERIODS;}
<DYNARE_BLOCK>scales {return token::SCALES;} <DYNARE_BLOCK>scales {return token::SCALES;}
<DYNARE_BLOCK>add { <DYNARE_BLOCK>add {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::ADD; return token::ADD;
} }
<DYNARE_BLOCK>multiply { <DYNARE_BLOCK>multiply {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::MULTIPLY; return token::MULTIPLY;
} }
<DYNARE_STATEMENT,DYNARE_BLOCK>cutoff {return token::CUTOFF;} <DYNARE_STATEMENT,DYNARE_BLOCK>cutoff {return token::CUTOFF;}
<DYNARE_STATEMENT,DYNARE_BLOCK>mfs { <DYNARE_STATEMENT,DYNARE_BLOCK>mfs {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::MFS; return token::MFS;
} }
<DYNARE_STATEMENT,DYNARE_BLOCK>static_mfs {return token::STATIC_MFS;} <DYNARE_STATEMENT,DYNARE_BLOCK>static_mfs {return token::STATIC_MFS;}
...@@ -817,19 +790,19 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -817,19 +790,19 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_BLOCK>dsge_prior_weight {return token::DSGE_PRIOR_WEIGHT;} <DYNARE_BLOCK>dsge_prior_weight {return token::DSGE_PRIOR_WEIGHT;}
<DYNARE_BLOCK>surprise {return token::SURPRISE;} <DYNARE_BLOCK>surprise {return token::SURPRISE;}
<DYNARE_BLOCK>bind { <DYNARE_BLOCK>bind {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::BIND; return token::BIND;
} }
<DYNARE_BLOCK>relax { <DYNARE_BLOCK>relax {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::RELAX; return token::RELAX;
} }
<DYNARE_BLOCK>error_bind { <DYNARE_BLOCK>error_bind {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::ERROR_BIND; return token::ERROR_BIND;
} }
<DYNARE_BLOCK>error_relax { <DYNARE_BLOCK>error_relax {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::ERROR_RELAX; return token::ERROR_RELAX;
} }
<DYNARE_BLOCK>relative_to_initval {return token::RELATIVE_TO_INITVAL;} <DYNARE_BLOCK>relative_to_initval {return token::RELATIVE_TO_INITVAL;}
...@@ -843,22 +816,24 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -843,22 +816,24 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_BLOCK,DYNARE_STATEMENT>auxname {return token::AUXNAME;} <DYNARE_BLOCK,DYNARE_STATEMENT>auxname {return token::AUXNAME;}
<DYNARE_BLOCK>auxname_target_nonstationary {return token::AUXNAME_TARGET_NONSTATIONARY;} <DYNARE_BLOCK>auxname_target_nonstationary {return token::AUXNAME_TARGET_NONSTATIONARY;}
<DYNARE_BLOCK,DYNARE_STATEMENT>kind { <DYNARE_BLOCK,DYNARE_STATEMENT>kind {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::KIND; return token::KIND;
} }
<DYNARE_BLOCK,DYNARE_STATEMENT>ll { <DYNARE_BLOCK,DYNARE_STATEMENT>ll {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::LL; return token::LL;
} }
<DYNARE_BLOCK,DYNARE_STATEMENT>dl { <DYNARE_BLOCK,DYNARE_STATEMENT>dl {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::DL; return token::DL;
} }
<DYNARE_BLOCK,DYNARE_STATEMENT>dd { <DYNARE_BLOCK,DYNARE_STATEMENT>dd {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::DD; return token::DD;
} }
<DYNARE_BLOCK>weights {return token::WEIGHTS;} <DYNARE_BLOCK>weights {return token::WEIGHTS;}
<DYNARE_BLOCK>exogenize {return token::EXOGENIZE;}
<DYNARE_BLOCK>endogenize {return token::ENDOGENIZE;}
/* Inside Dynare statement */ /* Inside Dynare statement */
<DYNARE_STATEMENT>solve_algo {return token::SOLVE_ALGO;} <DYNARE_STATEMENT>solve_algo {return token::SOLVE_ALGO;}
...@@ -870,7 +845,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -870,7 +845,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>order {return token::ORDER;} <DYNARE_STATEMENT>order {return token::ORDER;}
<DYNARE_STATEMENT>lyapunov {return token::LYAPUNOV;} <DYNARE_STATEMENT>lyapunov {return token::LYAPUNOV;}
<DYNARE_STATEMENT>dr { <DYNARE_STATEMENT>dr {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::DR; return token::DR;
} }
<DYNARE_STATEMENT>lyapunov_complex_threshold {return token::LYAPUNOV_COMPLEX_THRESHOLD;} <DYNARE_STATEMENT>lyapunov_complex_threshold {return token::LYAPUNOV_COMPLEX_THRESHOLD;}
...@@ -934,11 +909,11 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -934,11 +909,11 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>time_shift {return token::TIME_SHIFT;} <DYNARE_STATEMENT>time_shift {return token::TIME_SHIFT;}
<DYNARE_STATEMENT>structural {return token::STRUCTURAL;} <DYNARE_STATEMENT>structural {return token::STRUCTURAL;}
<DYNARE_STATEMENT>true { <DYNARE_STATEMENT>true {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::TRUE; return token::TRUE;
} }
<DYNARE_STATEMENT>false { <DYNARE_STATEMENT>false {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::FALSE; return token::FALSE;
} }
...@@ -1062,38 +1037,27 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -1062,38 +1037,27 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>use_shock_groups {return token::USE_SHOCK_GROUPS;} <DYNARE_STATEMENT>use_shock_groups {return token::USE_SHOCK_GROUPS;}
<DYNARE_STATEMENT>colormap {return token::COLORMAP;} <DYNARE_STATEMENT>colormap {return token::COLORMAP;}
<DYNARE_STATEMENT,DYNARE_BLOCK>[a-z_][a-z0-9_]* { <DYNARE_STATEMENT,DYNARE_BLOCK>{NAME} {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::NAME; return token::NAME;
} }
<DYNARE_STATEMENT,DYNARE_BLOCK>((([0-9]*\.[0-9]+)|([0-9]+\.))([ed][-+]?[0-9]+)?)|([0-9]+[ed][-+]?[0-9]+) { <DYNARE_STATEMENT,DYNARE_BLOCK>{FLOAT_NUMBER} {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::FLOAT_NUMBER; return token::FLOAT_NUMBER;
} }
<DYNARE_STATEMENT,DYNARE_BLOCK>[0-9]+ { <DYNARE_STATEMENT,DYNARE_BLOCK>[0-9]+ {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::INT_NUMBER; return token::INT_NUMBER;
} }
<DATES_STATEMENT>\( { yylval->as<string>().append(yytext); dates_parens_nb++; }
<DATES_STATEMENT>\) {
yylval->as<string>().append(yytext);
if (--dates_parens_nb == 0)
{
BEGIN DYNARE_STATEMENT;
return token::DATES;
}
}
<DATES_STATEMENT>. { yylval->as<string>().append(yytext); }
<DYNARE_BLOCK>\|e { return token::PIPE_E; } <DYNARE_BLOCK>\|e { return token::PIPE_E; }
<DYNARE_BLOCK>\|x { return token::PIPE_X; } <DYNARE_BLOCK>\|x { return token::PIPE_X; }
<DYNARE_BLOCK>\|p { return token::PIPE_P; } <DYNARE_BLOCK>\|p { return token::PIPE_P; }
<DYNARE_STATEMENT,DYNARE_BLOCK>\'[^\']*\' { <DYNARE_STATEMENT,DYNARE_BLOCK>\'[^\']*\' {
yylval->build<string>(yytext + 1).pop_back(); yylval->emplace<string>(yytext + 1).pop_back();
return token::QUOTED_STRING; return token::QUOTED_STRING;
} }
...@@ -1125,11 +1089,11 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -1125,11 +1089,11 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
element in initval (in which case Dynare recognizes the matrix name as an external element in initval (in which case Dynare recognizes the matrix name as an external
function symbol), and may want to modify the matrix later with Matlab statements. function symbol), and may want to modify the matrix later with Matlab statements.
*/ */
<INITIAL>[a-z_][a-z0-9_]* { <INITIAL>{NAME} {
if (driver.symbol_exists_and_is_not_modfile_local_or_external_function(yytext)) if (driver.symbol_exists_and_is_not_modfile_local_or_external_function(yytext))
{ {
BEGIN DYNARE_STATEMENT; BEGIN DYNARE_STATEMENT;
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::NAME; return token::NAME;
} }
else else
...@@ -1150,7 +1114,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -1150,7 +1114,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
be able to back out of the statement if we realize it's a native statement be able to back out of the statement if we realize it's a native statement
and move to the NATIVE context and move to the NATIVE context
*/ */
<INITIAL>\[([[:space:]]*[a-z_][a-z0-9_]*[[:space:]]*,{1}[[:space:]]*)*([[:space:]]*[a-z_][a-z0-9_]*[[:space:]]*){1}\] { <INITIAL>\[([[:space:]]*{NAME}[[:space:]]*,{1}[[:space:]]*)*([[:space:]]*{NAME}[[:space:]]*){1}\] {
string yytextcpy{yytext}; string yytextcpy{yytext};
yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), '['), yytextcpy.end()); yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), '['), yytextcpy.end());
yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), ']'), yytextcpy.end()); yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), ']'), yytextcpy.end());
...@@ -1174,7 +1138,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -1174,7 +1138,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
if (dynare_statement) if (dynare_statement)
{ {
BEGIN DYNARE_STATEMENT; BEGIN DYNARE_STATEMENT;
yylval->build<vector<string>>(val); yylval->emplace<vector<string>>(val);
return token::SYMBOL_VEC; return token::SYMBOL_VEC;
} }
} }
...@@ -1219,7 +1183,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -1219,7 +1183,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<NATIVE_COMMENT>"*/"[[:space:]]*\n { BEGIN NATIVE; } <NATIVE_COMMENT>"*/"[[:space:]]*\n { BEGIN NATIVE; }
<NATIVE_COMMENT>. <NATIVE_COMMENT>.
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,COMMENT,DATES_STATEMENT,LINE1,LINE2,LINE3,NATIVE_COMMENT><<EOF>> { yyterminate(); } <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,COMMENT,LINE1,LINE2,LINE3,NATIVE_COMMENT><<EOF>> { yyterminate(); }
<*>. { driver.error(*yylloc, "character unrecognized by lexer"); } <*>. { driver.error(*yylloc, "character unrecognized by lexer"); }
%% %%
......
/* /*
* Copyright © 2020-2023 Dynare Team * Copyright © 2020-2025 Dynare Team
* *
* This file is part of Dynare. * 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 ...@@ -74,13 +74,12 @@ EquationTags::erase(const set<int>& eqns, const map<int, int>& old_eqn_num_2_new
eqn_tags.erase(eqn); eqn_tags.erase(eqn);
for (const auto& [oldeqn, neweqn] : old_eqn_num_2_new) for (const auto& [oldeqn, neweqn] : old_eqn_num_2_new)
for (auto& [eqn, tags] : eqn_tags) if (eqn_tags.contains(oldeqn))
if (eqn == oldeqn) {
{ auto tmp = eqn_tags.extract(oldeqn);
auto tmp = eqn_tags.extract(eqn); tmp.key() = neweqn;
tmp.key() = neweqn; eqn_tags.insert(move(tmp));
eqn_tags.insert(move(tmp)); }
}
} }
void void
......
/* /*
* Copyright © 2007-2024 Dynare Team * Copyright © 2007-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -1785,6 +1785,7 @@ VariableNode::maxLead() const ...@@ -1785,6 +1785,7 @@ VariableNode::maxLead() const
case SymbolType::endogenous: case SymbolType::endogenous:
case SymbolType::exogenous: case SymbolType::exogenous:
case SymbolType::exogenousDet: case SymbolType::exogenousDet:
case SymbolType::epilogue:
case SymbolType::heterogeneousEndogenous: case SymbolType::heterogeneousEndogenous:
case SymbolType::heterogeneousExogenous: case SymbolType::heterogeneousExogenous:
return lag; return lag;
...@@ -1803,6 +1804,7 @@ VariableNode::maxLag() const ...@@ -1803,6 +1804,7 @@ VariableNode::maxLag() const
case SymbolType::endogenous: case SymbolType::endogenous:
case SymbolType::exogenous: case SymbolType::exogenous:
case SymbolType::exogenousDet: case SymbolType::exogenousDet:
case SymbolType::epilogue:
case SymbolType::heterogeneousEndogenous: case SymbolType::heterogeneousEndogenous:
case SymbolType::heterogeneousExogenous: case SymbolType::heterogeneousExogenous:
return -lag; return -lag;
...@@ -1945,6 +1947,7 @@ VariableNode::decreaseLeadsLags(int n) const ...@@ -1945,6 +1947,7 @@ VariableNode::decreaseLeadsLags(int n) const
case SymbolType::endogenous: case SymbolType::endogenous:
case SymbolType::exogenous: case SymbolType::exogenous:
case SymbolType::exogenousDet: case SymbolType::exogenousDet:
case SymbolType::epilogue:
case SymbolType::trend: case SymbolType::trend:
case SymbolType::logTrend: case SymbolType::logTrend:
case SymbolType::heterogeneousEndogenous: case SymbolType::heterogeneousEndogenous:
...@@ -2975,10 +2978,8 @@ UnaryOpNode::writeJsonOutput(ostream& output, const temporary_terms_t& temporary ...@@ -2975,10 +2978,8 @@ UnaryOpNode::writeJsonOutput(ostream& output, const temporary_terms_t& temporary
output << "])"; output << "])";
return; return;
case UnaryOpcode::steadyState: case UnaryOpcode::steadyState:
output << "("; output << "STEADY_STATE";
arg->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); break;
output << ")";
return;
case UnaryOpcode::steadyStateParamDeriv: case UnaryOpcode::steadyStateParamDeriv:
{ {
auto varg = dynamic_cast<VariableNode*>(arg); auto varg = dynamic_cast<VariableNode*>(arg);
...@@ -6455,9 +6456,9 @@ TrinaryOpNode::eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v ...@@ -6455,9 +6456,9 @@ TrinaryOpNode::eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v
switch (op_code) switch (op_code)
{ {
case TrinaryOpcode::normcdf: 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: 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 __builtin_unreachable(); // Silence GCC warning
} }
...@@ -6986,9 +6987,9 @@ TrinaryOpNode::isVariableNodeEqualTo([[maybe_unused]] SymbolType type_arg, ...@@ -6986,9 +6987,9 @@ TrinaryOpNode::isVariableNodeEqualTo([[maybe_unused]] SymbolType type_arg,
bool bool
TrinaryOpNode::containsPacExpectation(const string& pac_model_name) const TrinaryOpNode::containsPacExpectation(const string& pac_model_name) const
{ {
return (arg1->containsPacExpectation(pac_model_name) return arg1->containsPacExpectation(pac_model_name)
|| arg2->containsPacExpectation(pac_model_name) || arg2->containsPacExpectation(pac_model_name)
|| arg3->containsPacExpectation(pac_model_name)); || arg3->containsPacExpectation(pac_model_name);
} }
bool bool
...@@ -7904,7 +7905,7 @@ ExternalFunctionNode::sameTefTermPredicate() const ...@@ -7904,7 +7905,7 @@ ExternalFunctionNode::sameTefTermPredicate() const
{ {
return [this](expr_t e) { return [this](expr_t e) {
auto e2 = dynamic_cast<ExternalFunctionNode*>(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;
}; };
} }
...@@ -8242,12 +8243,12 @@ FirstDerivExternalFunctionNode::sameTefTermPredicate() const ...@@ -8242,12 +8243,12 @@ FirstDerivExternalFunctionNode::sameTefTermPredicate() const
if (first_deriv_symb_id == symb_id) if (first_deriv_symb_id == symb_id)
return [this](expr_t e) { return [this](expr_t e) {
auto e2 = dynamic_cast<ExternalFunctionNode*>(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 else
return [this](expr_t e) { return [this](expr_t e) {
auto e2 = dynamic_cast<FirstDerivExternalFunctionNode*>(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;
}; };
} }
...@@ -8597,12 +8598,12 @@ SecondDerivExternalFunctionNode::sameTefTermPredicate() const ...@@ -8597,12 +8598,12 @@ SecondDerivExternalFunctionNode::sameTefTermPredicate() const
if (second_deriv_symb_id == symb_id) if (second_deriv_symb_id == symb_id)
return [this](expr_t e) { return [this](expr_t e) {
auto e2 = dynamic_cast<ExternalFunctionNode*>(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 else
return [this](expr_t e) { return [this](expr_t e) {
auto e2 = dynamic_cast<SecondDerivExternalFunctionNode*>(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;
}; };
} }
...@@ -9488,9 +9489,9 @@ ExprNode::matchParamTimesTargetMinusVariable(int symb_id) const ...@@ -9488,9 +9489,9 @@ ExprNode::matchParamTimesTargetMinusVariable(int symb_id) const
auto& avi = datatree.symbol_table.getAuxVarInfo(target->symb_id); auto& avi = datatree.symbol_table.getAuxVarInfo(target->symb_id);
if (avi.type == AuxVarType::pacTargetNonstationary && target->lag == -1) if (avi.type == AuxVarType::pacTargetNonstationary && target->lag == -1)
return true; return true;
return (avi.type == AuxVarType::unaryOp && avi.unary_op == "log" && avi.orig_symb_id return avi.type == AuxVarType::unaryOp && avi.unary_op == "log" && avi.orig_symb_id
&& !datatree.symbol_table.isAuxiliaryVariable(*avi.orig_symb_id) && !datatree.symbol_table.isAuxiliaryVariable(*avi.orig_symb_id)
&& target->lag + avi.orig_lead_lag.value() == -1); && target->lag + avi.orig_lead_lag.value() == -1;
} }
else else
return target->lag == -1; return target->lag == -1;
...@@ -9569,13 +9570,14 @@ ExprNode::toString() const ...@@ -9569,13 +9570,14 @@ ExprNode::toString() const
} }
tuple<int, expr_t, expr_t> 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"}; throw MatchFailureException {"This expression is not an inequality"};
} }
tuple<int, expr_t, expr_t> tuple<int, expr_t, expr_t>
BinaryOpNode::matchComplementarityCondition() const BinaryOpNode::matchComplementarityCondition(const optional<int>& heterogeneity_dimension) const
{ {
bool is_greater {[&] { bool is_greater {[&] {
switch (op_code) switch (op_code)
...@@ -9593,7 +9595,13 @@ BinaryOpNode::matchComplementarityCondition() const ...@@ -9593,7 +9595,13 @@ BinaryOpNode::matchComplementarityCondition() const
auto match_contemporaneous_endogenous = [&](expr_t e) -> optional<int> { auto match_contemporaneous_endogenous = [&](expr_t e) -> optional<int> {
auto* ve = dynamic_cast<VariableNode*>(e); 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; return ve->symb_id;
else else
return nullopt; return nullopt;
...@@ -9630,11 +9638,11 @@ BinaryOpNode::matchComplementarityCondition() const ...@@ -9630,11 +9638,11 @@ BinaryOpNode::matchComplementarityCondition() const
|| (!is_greater || (!is_greater
&& (barg1->op_code == BinaryOpcode::less && (barg1->op_code == BinaryOpcode::less
|| barg1->op_code == BinaryOpcode::lessEqual))))) || barg1->op_code == BinaryOpcode::lessEqual)))))
throw MatchFailureException {"Complementarity condition does not have the right form"}; throw MatchFailureException {};
auto id = match_contemporaneous_endogenous(barg1->arg2); auto id = match_contemporaneous_endogenous(barg1->arg2);
if (!id) if (!id)
throw MatchFailureException {"Complementarity condition does not have the right form"}; throw MatchFailureException {};
check_bound_constant(barg1->arg1); check_bound_constant(barg1->arg1);
check_bound_constant(arg2); check_bound_constant(arg2);
......
/* /*
* Copyright © 2007-2024 Dynare Team * Copyright © 2007-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -283,7 +283,7 @@ protected: ...@@ -283,7 +283,7 @@ protected:
min_cost(bool is_matlab) min_cost(bool is_matlab)
{ {
return is_matlab ? min_cost_matlab : min_cost_c; return is_matlab ? min_cost_matlab : min_cost_c;
}; }
//! Initializes data member non_null_derivatives //! Initializes data member non_null_derivatives
virtual void prepareForDerivation() = 0; virtual void prepareForDerivation() = 0;
...@@ -943,7 +943,8 @@ public: ...@@ -943,7 +943,8 @@ public:
/* Matches an expression that constitutes a complementarity condition. /* Matches an expression that constitutes a complementarity condition.
If successful, returns a triplet (endo_symb_id, lower_bound, upper_bound). If successful, returns a triplet (endo_symb_id, lower_bound, upper_bound).
Otherwise, throws a MatchFailureException. */ 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. /* Replaces aggregation operators (e.g. SUM()) by new auxiliary variables.
Also declares those aggregation operators in the HeterogeneityTable, so as to Also declares those aggregation operators in the HeterogeneityTable, so as to
...@@ -1519,7 +1520,9 @@ public: ...@@ -1519,7 +1520,9 @@ public:
[[nodiscard]] expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override; [[nodiscard]] expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override;
[[nodiscard]] expr_t substituteAggregationOperators(subst_table_t& subst_table, [[nodiscard]] expr_t substituteAggregationOperators(subst_table_t& subst_table,
vector<BinaryOpNode*>& neweqs) const override; 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 //! Trinary operator node
......
...@@ -90,7 +90,7 @@ public: ...@@ -90,7 +90,7 @@ public:
}; };
void addSummedHeterogeneousEndogenous(int symb_id); void addSummedHeterogeneousEndogenous(int symb_id);
int getSummedHeterogenousEndogenousIndex(int symb_id) const; [[nodiscard]] int getSummedHeterogenousEndogenousIndex(int symb_id) const;
[[nodiscard]] int aggregateEndoSize() const; [[nodiscard]] int aggregateEndoSize() const;
void writeOutput(ostream& output) const; void writeOutput(ostream& output) const;
......
/* /*
* Copyright © 2024 Dynare Team * Copyright © 2024-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -33,14 +33,6 @@ HeterogeneousModel::HeterogeneousModel(SymbolTable& symbol_table_arg, ...@@ -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&
HeterogeneousModel::operator=(const HeterogeneousModel& m) HeterogeneousModel::operator=(const HeterogeneousModel& m)
{ {
...@@ -123,14 +115,7 @@ HeterogeneousModel::computingPass(int derivsOrder, bool no_tmp_terms, bool use_d ...@@ -123,14 +115,7 @@ HeterogeneousModel::computingPass(int derivsOrder, bool no_tmp_terms, bool use_d
computeTemporaryTerms(!use_dll, no_tmp_terms); computeTemporaryTerms(!use_dll, no_tmp_terms);
if (ranges::any_of(complementarity_conditions, [](const auto& x) { return x.has_value(); })) computeMCPEquationsReordering(heterogeneity_dimension);
{
// Implementing it requires modifications in ModelTree::computeMCPEquationsReordering()
cerr << "ERROR: Complementarity conditions are not yet implemented in "
"model(heterogeneity=...) blocks"
<< endl;
exit(EXIT_FAILURE);
}
} }
void void
...@@ -138,6 +123,7 @@ HeterogeneousModel::writeModelFiles(const string& basename, bool julia) const ...@@ -138,6 +123,7 @@ HeterogeneousModel::writeModelFiles(const string& basename, bool julia) const
{ {
assert(!julia); // Not yet implemented assert(!julia); // Not yet implemented
writeSparseModelMFiles<true>(basename, heterogeneity_dimension); writeSparseModelMFiles<true>(basename, heterogeneity_dimension);
writeComplementarityConditionsFile<true>(basename, heterogeneity_dimension);
} }
int int
...@@ -220,10 +206,34 @@ HeterogeneousModel::getDerivID(int symb_id, int lead_lag) const noexcept(false) ...@@ -220,10 +206,34 @@ HeterogeneousModel::getDerivID(int symb_id, int lead_lag) const noexcept(false)
void void
HeterogeneousModel::writeDriverOutput(ostream& output) const HeterogeneousModel::writeDriverOutput(ostream& output) const
{ {
std::vector<int> state_var;
for (int endoID = 0; endoID < symbol_table.het_endo_nbr(heterogeneity_dimension); endoID++)
try
{
getDerivID(symbol_table.getID(SymbolType::heterogeneousEndogenous, endoID,
heterogeneity_dimension),
-1);
if (ranges::find(state_var, endoID) == state_var.end())
state_var.push_back(endoID);
}
catch (UnknownDerivIDException& e)
{
}
output << "M_.heterogeneity(" << heterogeneity_dimension + 1 << ").state_var = [";
for (int it : state_var)
output << it + 1 << " ";
output << "];" << endl;
output << "M_.heterogeneity(" << heterogeneity_dimension + 1 << ").dynamic_tmp_nbr = ["; output << "M_.heterogeneity(" << heterogeneity_dimension + 1 << ").dynamic_tmp_nbr = [";
for (const auto& it : temporary_terms_derivatives) for (const auto& it : temporary_terms_derivatives)
output << it.size() << "; "; output << it.size() << "; ";
output << "];" << endl; output << "];" << endl;
writeDriverSparseIndicesHelper( writeDriverSparseIndicesHelper(
"heterogeneity("s + to_string(heterogeneity_dimension + 1) + ").dynamic", output); "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: ...@@ -35,7 +35,7 @@ public:
ExternalFunctionsTable& external_functions_table_arg, ExternalFunctionsTable& external_functions_table_arg,
HeterogeneityTable& heterogeneity_table_arg, int heterogeneity_dimension_arg); HeterogeneityTable& heterogeneity_table_arg, int heterogeneity_dimension_arg);
HeterogeneousModel(const HeterogeneousModel& m); HeterogeneousModel(const HeterogeneousModel& m) = default;
HeterogeneousModel& operator=(const HeterogeneousModel& m); HeterogeneousModel& operator=(const HeterogeneousModel& m);
void computingPass(int derivsOrder, bool no_tmp_terms, bool use_dll); 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. * This file is part of Dynare.
* *
...@@ -1137,7 +1137,8 @@ ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global, ...@@ -1137,7 +1137,8 @@ ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global,
<< "M_.heteroskedastic_shocks.Qvalue_orig = [];" << endl << "M_.heteroskedastic_shocks.Qvalue_orig = [];" << endl
<< "M_.heteroskedastic_shocks.Qscale_orig = [];" << endl << "M_.heteroskedastic_shocks.Qscale_orig = [];" << endl
<< "M_.matched_irfs = {};" << 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_ // NB: options_.{ramsey,discretionary}_policy should rather be fields of M_
mOutputFile << boolalpha << "options_.linear = " << linear << ";" << endl mOutputFile << boolalpha << "options_.linear = " << linear << ";" << endl
...@@ -1311,8 +1312,8 @@ ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global, ...@@ -1311,8 +1312,8 @@ ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global,
if (!no_warn) if (!no_warn)
{ {
if (warnings.countWarnings() > 0) if (int num_warnings {warnings.numWarnings()}; num_warnings > 0)
mOutputFile << "disp('Note: " << warnings.countWarnings() mOutputFile << "disp('Note: " << num_warnings
<< " warning(s) encountered in the preprocessor')" << endl; << " warning(s) encountered in the preprocessor')" << endl;
mOutputFile << "if ~isempty(lastwarn)" << endl mOutputFile << "if ~isempty(lastwarn)" << endl
......
...@@ -410,10 +410,10 @@ void ...@@ -410,10 +410,10 @@ void
Epilogue::detrend(const map<int, expr_t>& trend_symbols_map, Epilogue::detrend(const map<int, expr_t>& trend_symbols_map,
const nonstationary_symbols_map_t& nonstationary_symbols_map) const nonstationary_symbols_map_t& nonstationary_symbols_map)
{ {
for (const auto& it : ranges::reverse_view(nonstationary_symbols_map)) for (const auto& [symb_id, deflator] : ranges::reverse_view(nonstationary_symbols_map))
for (auto& [symb_id, expr] : dynamic_def_table) for (auto& [symb_id, expr] : dynamic_def_table)
{ {
expr = expr->detrend(it.first, it.second.first, it.second.second); expr = expr->detrend(symb_id, deflator.first, deflator.second);
assert(expr); assert(expr);
} }
......