Compare commits

...

34 Commits

Author SHA1 Message Date
Sébastien Villemot e32025a76f
Bump major version number 2023-12-21 15:57:59 +01:00
Sébastien Villemot 5fa91a08f6
CI: bump MSYS2 Boost dependency 2023-12-21 11:14:45 +01:00
Sébastien Villemot 520876560d
New matched_irfs and matched_irfs_weights blocks
Closes: #124
2023-12-19 16:10:19 +01:00
Sébastien Villemot f8b2de715c
Drop unused options_.minimal_workspace 2023-12-18 16:24:22 +01:00
Sébastien Villemot 638c49d96e Merge branch 'EP' into 'master'
Remove globals from extended path

See merge request Dynare/preprocessor!99
2023-12-18 10:47:51 +00:00
Sébastien Villemot b6875ebb9d Merge branch 'mj_steadystatemodel' into 'master'
Add steady_state_model_present field to modfile.json

See merge request Dynare/preprocessor!100
2023-12-18 09:57:06 +00:00
MichelJuillard c96d96cfb3 Add steady_state_model_present field to modfile.json 2023-12-18 09:57:06 +00:00
Johannes Pfeifer 1cfce804a6 Perfect foresight: remove globals 2023-12-15 22:24:07 +01:00
Johannes Pfeifer 5a2c099871 EP: output results explicitly as opposed to assignin-statement 2023-12-14 19:53:07 +01:00
Sébastien Villemot 0f397f40af
Rename “dynare_sensitivity” command to “sensitivity”
The old name is still accepted, but will trigger a deprecation warning.
2023-12-14 18:37:10 +01:00
Sébastien Villemot 8d0e8cca5c
Merge branch 'gsa_namespace' of git.dynare.org:JohannesPfeifer/preprocessor
Ref. !96
2023-12-14 18:27:19 +01:00
Sébastien Villemot ba3ab3a234
Merge branch 'sylvester' of git.dynare.org:JohannesPfeifer/preprocessor
Ref. !97
2023-12-14 17:59:54 +01:00
Sébastien Villemot 3dadac8f19
Merge branch 'cond_forecast' of git.dynare.org:JohannesPfeifer/preprocessor
Ref. !98
2023-12-14 17:34:27 +01:00
Sébastien Villemot cf45c77343
Bytecode: simplify various instruction classes 2023-12-14 17:07:06 +01:00
Sébastien Villemot f55019c41e
Bytecode: rename several classes and class members, for consistency and clarity 2023-12-14 16:17:22 +01:00
Sébastien Villemot 22709f8225
Move bytecode stuff into a dedicated namespace, for better code separation 2023-12-14 15:48:22 +01:00
Johannes Pfeifer 1734491b76 conditional_forecast: remove global variables and move to namespace 2023-12-14 11:42:41 +01:00
Johannes Pfeifer cf1c11676b Remove obsolete Sylvester options
dr_block has been removed
2023-12-14 11:36:59 +01:00
Johannes Pfeifer 090945d8a8 Use namespace for identification and sensitivity 2023-12-13 17:51:49 +01:00
Sébastien Villemot 1c10a3acbf
Enable performance-* checks in clang-tidy 2023-12-13 16:30:40 +01:00
Sébastien Villemot cbfad751c8
Remove some unnecessary temporary std::string allocation
Automatically detected by clang-tidy using
performance-inefficient-string-concatenation check.

Several of the detected cases are left unattended, because the syntax is more
elegant as it is, and they are not performance-critical.
2023-12-13 16:29:46 +01:00
Sébastien Villemot b31de3d9a6
Pre-allocate std::vector instances filled from loops
Automatically detected by clang-tidy using
performance-inefficient-vector-operation check.
2023-12-13 16:19:51 +01:00
Sébastien Villemot 22675728aa
No longer call std::move on trivially-copyable types
Automatically detected by clang-tidy with performance-move-const-arg check.

Do not make the modification for Tokenizer::location type, since we have no
guarantee that the type will remain trivially-copyable in the future.
2023-12-13 15:37:07 +01:00
Sébastien Villemot 7cfe226e58
When possible, use a more efficient overload of std::string::find()
Automatically detected by clang-tidy using the performance-faster-string-find
check.
2023-12-13 14:21:11 +01:00
Sébastien Villemot d635aac04a
Turn some loop variables into const references when possible
Automatically detected by clang-tidy using performance-for-range-copy check.
2023-12-13 14:21:09 +01:00
Sébastien Villemot 3d94f1956c
Remove some unneeded object copies
Automatically detected by clang-tidy using performance-unnecessary-value-param
check.
2023-12-13 10:28:54 +01:00
Sébastien Villemot cd86b1895d
Configuration file: new default value for GlobalInitFile option
If the user did not specify the GlobalInitFile option, use global_init.m in configuration
directory if it exists.
2023-12-12 16:01:54 +01:00
Sébastien Villemot 1de83b7b12
Configuration file: simplify handling of GlobalInitFile option
There was some overengineering related to the Hook class.
2023-12-12 15:54:57 +01:00
Sébastien Villemot 328e8eef78
Change default location for configuration file
– under Linux and macOS, use the “dynare” subdirectory of the configuration
  directory specified by the XDG specification
– under Windows, use the “dynare” subdirectory of the Application Data folder

The old location is kept for backward compatibility, with a warning.
2023-12-12 12:28:33 +01:00
Sébastien Villemot 7c83b81623
Turn some configuration-related classes into nested classes 2023-12-11 17:32:30 +01:00
Sébastien Villemot 4389e5320d
Rename files, classes and variables in relation to the configuration file
In particular, makes clearer the distinction between configuration and
configuration file. The former includes information that is not in the
latter (command-line options.)
2023-12-11 17:17:57 +01:00
Sébastien Villemot 7dd125e43a
Remove duplicate definition of expr_t 2023-12-11 14:29:43 +01:00
Sébastien Villemot e4b23fecb0
Update comments in relation to implicit conversion from std::filesystem::path to std::string
There is actually no bug in MinGW. The different behaviour under Windows is
expected, because the implicit conversion there is only to std::wstring.
2023-12-08 18:39:27 +01:00
Sébastien Villemot 4790fa00d8
Remove workaround for bug in MinGW compiler
It would mishandle trailing slashes or backslashes in std::filesystem::path, see
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88881

The bug is now fixed in the version of MinGW in Debian “bookworm” 12.

Ref. Madysson/estimation-codes#11
2023-12-08 18:36:25 +01:00
37 changed files with 1085 additions and 1129 deletions

View File

@ -1,9 +1,8 @@
# TODO: add the following check families:
# - performance-*
# - bugprone-*
# - cppcoreguidelines-
# NB: as of clang-tidy 16, we get several false positives inside boost, notably this one:
# https://github.com/llvm/llvm-project/issues/40486
Checks: 'modernize-*,-modernize-use-trailing-return-type,-clang-diagnostic-unqualified-std-cast-call'
Checks: 'performance-*,modernize-*,-modernize-use-trailing-return-type,-clang-diagnostic-unqualified-std-cast-call'

View File

@ -1,7 +1,7 @@
variables:
TERM: linux
MINGW32_BOOST_VERSION: 1.81.0-7
MINGW64_BOOST_VERSION: 1.81.0-7
MINGW32_BOOST_VERSION: 1.84.0-1
MINGW64_BOOST_VERSION: 1.84.0-1
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'

View File

@ -2,7 +2,7 @@
# It is not used when building Dynare as a whole.
project('dynare-preprocessor', 'cpp',
version : '6-unstable',
version : '7-unstable',
# NB: update C++ standard in .clang-format whenever the following is modified
default_options : [ 'cpp_std=gnu++20', 'warning_level=2' ],
meson_version : '>=0.64.0')

View File

@ -24,7 +24,10 @@
#include "Bytecode.hh"
BytecodeWriter::BytecodeWriter(const filesystem::path& filename)
namespace Bytecode
{
Writer::Writer(const filesystem::path& filename)
{
open(filename, ios::out | ios::binary);
if (!is_open())
@ -35,8 +38,8 @@ BytecodeWriter::BytecodeWriter(const filesystem::path& filename)
}
template<>
BytecodeWriter&
operator<<(BytecodeWriter& code_file, const FCALL_& instr)
Writer&
operator<<(Writer& code_file, const FCALL& instr)
{
code_file.instructions_positions.push_back(code_file.tellp());
@ -44,7 +47,7 @@ operator<<(BytecodeWriter& code_file, const FCALL_& instr)
code_file.write(reinterpret_cast<const char*>(&member), sizeof member);
};
write_member(instr.op_code);
write_member(instr.tag);
write_member(instr.nb_output_arguments);
write_member(instr.nb_input_arguments);
write_member(instr.indx);
@ -65,8 +68,8 @@ operator<<(BytecodeWriter& code_file, const FCALL_& instr)
}
template<>
BytecodeWriter&
operator<<(BytecodeWriter& code_file, const FBEGINBLOCK_& instr)
Writer&
operator<<(Writer& code_file, const FBEGINBLOCK& instr)
{
code_file.instructions_positions.push_back(code_file.tellp());
@ -74,7 +77,7 @@ operator<<(BytecodeWriter& code_file, const FBEGINBLOCK_& instr)
code_file.write(reinterpret_cast<const char*>(&member), sizeof member);
};
write_member(instr.op_code);
write_member(instr.tag);
write_member(instr.size);
write_member(instr.type);
for (int i = 0; i < instr.size; i++)
@ -99,3 +102,5 @@ operator<<(BytecodeWriter& code_file, const FBEGINBLOCK_& instr)
return code_file;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -153,7 +153,8 @@ SimulStatement::writeOutput(ostream& output, [[maybe_unused]] const string& base
options_list_new.erase("datafile");
}
options_list_new.writeOutput(output);
output << "perfect_foresight_setup;" << endl << "perfect_foresight_solver;" << endl;
output << "oo_ = perfect_foresight_setup(M_, options_, oo_);" << endl
<< "[oo_, Simulated_time_series] = perfect_foresight_solver(M_, options_, oo_);" << endl;
}
void
@ -188,7 +189,7 @@ PerfectForesightSetupStatement::writeOutput(ostream& output,
options_list_new.erase("datafile");
}
options_list_new.writeOutput(output);
output << "perfect_foresight_setup;" << endl;
output << "oo_ = perfect_foresight_setup(M_, options_, oo_);" << endl;
}
void
@ -221,7 +222,7 @@ PerfectForesightSolverStatement::writeOutput(ostream& output,
[[maybe_unused]] bool minimal_workspace) const
{
options_list.writeOutput(output);
output << "perfect_foresight_solver;" << endl;
output << "[oo_, Simulated_time_series] = perfect_foresight_solver(M_, options_, oo_);" << endl;
}
void
@ -248,7 +249,7 @@ PerfectForesightWithExpectationErrorsSetupStatement::writeOutput(
[[maybe_unused]] bool minimal_workspace) const
{
options_list.writeOutput(output);
output << "perfect_foresight_with_expectation_errors_setup;" << endl;
output << "oo_ = perfect_foresight_with_expectation_errors_setup(M_, options_, oo_);" << endl;
}
void
@ -282,7 +283,7 @@ PerfectForesightWithExpectationErrorsSolverStatement::writeOutput(
[[maybe_unused]] bool minimal_workspace) const
{
options_list.writeOutput(output);
output << "perfect_foresight_with_expectation_errors_solver;" << endl;
output << "oo_ = perfect_foresight_with_expectation_errors_solver(M_, options_, oo_);" << endl;
}
void
@ -1070,14 +1071,14 @@ EstimationStatement::writeJsonOutput(ostream& output) const
output << "}";
}
DynareSensitivityStatement::DynareSensitivityStatement(OptionsList options_list_arg) :
SensitivityStatement::SensitivityStatement(OptionsList options_list_arg) :
options_list {move(options_list_arg)}
{
}
void
DynareSensitivityStatement::checkPass(ModFileStructure& mod_file_struct,
[[maybe_unused]] WarningConsolidation& warnings)
SensitivityStatement::checkPass(ModFileStructure& mod_file_struct,
[[maybe_unused]] WarningConsolidation& warnings)
{
if (auto opt = options_list.get_if<OptionsList::NumVal>("identification"); opt && *opt == "1")
{
@ -1089,8 +1090,8 @@ DynareSensitivityStatement::checkPass(ModFileStructure& mod_file_struct,
}
void
DynareSensitivityStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename,
[[maybe_unused]] bool minimal_workspace) const
SensitivityStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename,
[[maybe_unused]] bool minimal_workspace) const
{
options_list.writeOutput(output, "options_gsa");
@ -1106,13 +1107,13 @@ DynareSensitivityStatement::writeOutput(ostream& output, [[maybe_unused]] const
if (auto opt = options_list.get_if<OptionsList::SymbolListVal>("graph_format"))
opt->writeOutput("options_.graph_format", output);
output << "dynare_sensitivity(M_,oo_,options_,bayestopt_,estim_params_,options_gsa);" << endl;
output << "gsa.run(M_,oo_,options_,bayestopt_,estim_params_,options_gsa);" << endl;
}
void
DynareSensitivityStatement::writeJsonOutput(ostream& output) const
SensitivityStatement::writeJsonOutput(ostream& output) const
{
output << R"({"statementName": "dynare_sensitivity")";
output << R"({"statementName": "sensitivity")";
if (!options_list.empty())
{
output << ", ";
@ -2941,7 +2942,7 @@ IdentificationStatement::writeOutput(ostream& output, [[maybe_unused]] const str
if (auto opt = options_list.get_if<OptionsList::SymbolListVal>("graph_format"))
opt->writeOutput("options_.graph_format", output);
output << "dynare_identification(M_,oo_,options_,bayestopt_,estim_params_,"
output << "identification.run(M_,oo_,options_,bayestopt_,estim_params_,"
<< "options_ident);" << endl;
}
@ -3331,7 +3332,9 @@ ConditionalForecastStatement::writeOutput(ostream& output, [[maybe_unused]] cons
[[maybe_unused]] bool minimal_workspace) const
{
options_list.writeOutput(output, "options_cond_fcst_");
output << "imcforecast(constrained_paths_, constrained_vars_, options_cond_fcst_);" << endl;
output << "oo_.conditional_forecast=conditional_forecasts.run(M_,options_,"
<< "oo_,bayestopt_,estim_params_,constrained_paths_, constrained_vars_,"
<< "options_cond_fcst_);" << endl;
}
void
@ -3347,10 +3350,9 @@ ConditionalForecastStatement::writeJsonOutput(ostream& output) const
}
PlotConditionalForecastStatement::PlotConditionalForecastStatement(
optional<int> periods_arg, SymbolList symbol_list_arg, const SymbolTable& symbol_table_arg) :
periods {move(periods_arg)},
symbol_list {move(symbol_list_arg)},
symbol_table {symbol_table_arg}
const optional<int>& periods_arg, SymbolList symbol_list_arg,
const SymbolTable& symbol_table_arg) :
periods {periods_arg}, symbol_list {move(symbol_list_arg)}, symbol_table {symbol_table_arg}
{
}
@ -3376,9 +3378,9 @@ PlotConditionalForecastStatement::writeOutput(ostream& output,
{
symbol_list.writeOutput("var_list_", output);
if (periods)
output << "plot_icforecast(var_list_, " << *periods << ",options_,oo_);" << endl;
output << "conditional_forecasts.plot(var_list_, " << *periods << ",options_,oo_);" << endl;
else
output << "plot_icforecast(var_list_,[],options_,oo_);" << endl;
output << "conditional_forecasts.plot(var_list_,[],options_,oo_);" << endl;
}
void
@ -5058,7 +5060,8 @@ ExtendedPathStatement::writeOutput(ostream& output, [[maybe_unused]] const strin
options_list_new.erase("periods");
options_list_new.writeOutput(output);
output << "extended_path([], " << periods << ", [], options_, M_, oo_);" << endl;
output << "[Simulated_time_series, oo_] = extended_path([], " << periods
<< ", [], options_, M_, oo_);" << endl;
}
void
@ -5480,3 +5483,103 @@ ResidStatement::writeJsonOutput(ostream& output) const
}
output << "}";
}
MatchedIrfsStatement::MatchedIrfsStatement(matched_irfs_t values_weights_arg, bool overwrite_arg) :
values_weights {move(values_weights_arg)}, overwrite {overwrite_arg}
{
}
void
MatchedIrfsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename,
[[maybe_unused]] bool minimal_workspace) const
{
if (overwrite)
output << "M_.matched_irfs = {};" << endl;
for (const auto& [key, vec] : values_weights)
{
const auto& [endo, exo] = key;
output << "M_.matched_irfs = [M_.matched_irfs; {'" << endo << "', '" << exo << "', {";
for (const auto& [p1, p2, value, weight] : vec)
{
output << p1 << ":" << p2 << ", ";
value->writeOutput(output);
output << ", ";
weight->writeOutput(output);
output << "; ";
}
output << "}}];" << endl;
}
}
void
MatchedIrfsStatement::writeJsonOutput(ostream& output) const
{
output << R"({"statementName": "matched_irfs")"
<< R"(, "overwrite": )" << boolalpha << overwrite << R"(, "contents": [)";
for (bool printed_something {false}; const auto& [key, vec] : values_weights)
{
if (exchange(printed_something, true))
output << ", ";
const auto& [endo, exo] = key;
output << R"({"var": ")" << endo << R"(", "varexo": ")" << exo
<< R"(", "periods_values_weights": [)";
for (bool printed_something2 {false}; const auto& [p1, p2, value, weight] : vec)
{
if (exchange(printed_something2, true))
output << ", ";
output << R"({"period1": )" << p1 << ", "
<< R"("period2": })" << p2 << ", "
<< R"("value": ")";
value->writeJsonOutput(output, {}, {});
output << R"(", "weight": ")";
weight->writeJsonOutput(output, {}, {});
output << R"("})";
}
output << "]}";
}
output << "]}";
}
MatchedIrfsWeightsStatement::MatchedIrfsWeightsStatement(matched_irfs_weights_t weights_arg,
bool overwrite_arg) :
weights {move(weights_arg)}, overwrite {overwrite_arg}
{
}
void
MatchedIrfsWeightsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename,
[[maybe_unused]] bool minimal_workspace) const
{
if (overwrite)
output << "M_.matched_irfs_weights = {};" << endl;
for (const auto& [key, val] : weights)
{
const auto& [endo1, periods1, exo1, endo2, periods2, exo2] = key;
output << "M_.matched_irfs_weights = [M_.matched_irfs_weights; {'" << endo1 << "', "
<< periods1 << ", '" << exo1 << "', '" << endo2 << "', " << periods2 << ", '" << exo2
<< "', ";
val->writeOutput(output);
output << "}];" << endl;
}
}
void
MatchedIrfsWeightsStatement::writeJsonOutput(ostream& output) const
{
output << R"({"statementName": "matched_irfs_weights")"
<< R"(, "overwrite": )" << boolalpha << overwrite << R"(, "contents": [)";
for (bool printed_something {false}; const auto& [key, val] : weights)
{
const auto& [endo1, periods1, exo1, endo2, periods2, exo2] = key;
if (exchange(printed_something, true))
output << ", ";
output << R"({"endo1": ")" << endo1 << R"(", "periods1": ")" << periods1 << R"(", "exo1": )"
<< exo1 << R"(", "endo2": ")" << endo2 << R"(", "periods2": ")" << periods2
<< R"(", "exo2": )" << exo2 << R"(", "weight": ")";
val->writeJsonOutput(output, {}, {});
output << R"("})";
}
output << "]}";
}

View File

@ -334,13 +334,13 @@ public:
void writeJsonOutput(ostream& output) const override;
};
class DynareSensitivityStatement : public Statement
class SensitivityStatement : public Statement
{
private:
const OptionsList options_list;
public:
explicit DynareSensitivityStatement(OptionsList options_list_arg);
explicit SensitivityStatement(OptionsList options_list_arg);
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;
@ -929,7 +929,7 @@ private:
const SymbolTable& symbol_table;
public:
PlotConditionalForecastStatement(optional<int> periods_arg, SymbolList symbol_list_arg,
PlotConditionalForecastStatement(const optional<int>& periods_arg, SymbolList symbol_list_arg,
const SymbolTable& symbol_table_arg);
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
@ -1332,4 +1332,33 @@ public:
void writeJsonOutput(ostream& output) const override;
};
class MatchedIrfsStatement : public Statement
{
public:
// (endo name, exo name) → vector of (period start, period end, value, weight)
using matched_irfs_t = map<pair<string, string>, vector<tuple<int, int, expr_t, expr_t>>>;
MatchedIrfsStatement(matched_irfs_t values_weights_arg, bool overwrite_arg);
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
private:
const matched_irfs_t values_weights;
const bool overwrite;
};
class MatchedIrfsWeightsStatement : public Statement
{
public:
/* (endo1 name, period index or range for endo1, exo1 name, endo2 name, period index or range for
endo2, exo2 name) weight */
using matched_irfs_weights_t = map<tuple<string, string, string, string, string, string>, expr_t>;
MatchedIrfsWeightsStatement(matched_irfs_weights_t weights_arg, bool overwrite_arg);
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
private:
const matched_irfs_weights_t weights;
const bool overwrite;
};
#endif

View File

@ -20,9 +20,13 @@
#include <fstream>
#include <iostream>
#include <utility>
#include <vector>
#include "ConfigFile.hh"
#ifdef _WIN32
# include <shlobj.h>
#endif
#include "Configuration.hh"
#include "DataTree.hh" // For strsplit()
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
@ -31,19 +35,7 @@
#include <boost/tokenizer.hpp>
#pragma GCC diagnostic pop
using namespace std;
Hook::Hook(string global_init_file_arg)
{
if (global_init_file_arg.empty())
{
cerr << "ERROR: The Hook must have a Global Initialization File argument." << endl;
exit(EXIT_FAILURE);
}
hooks["global_init_file"] = move(global_init_file_arg);
}
Path::Path(vector<string> includepath_arg)
Configuration::Path::Path(vector<string> includepath_arg)
{
if (includepath_arg.empty())
{
@ -53,12 +45,13 @@ Path::Path(vector<string> includepath_arg)
paths["include"] = move(includepath_arg);
}
FollowerNode::FollowerNode(string computerName_arg, string port_arg, int minCpuNbr_arg,
int maxCpuNbr_arg, string userName_arg, string password_arg,
string remoteDrive_arg, string remoteDirectory_arg,
string programPath_arg, string programConfig_arg,
string matlabOctavePath_arg, bool singleCompThread_arg,
int numberOfThreadsPerJob_arg, string operatingSystem_arg) :
Configuration::FollowerNode::FollowerNode(string computerName_arg, string port_arg,
int minCpuNbr_arg, int maxCpuNbr_arg, string userName_arg,
string password_arg, string remoteDrive_arg,
string remoteDirectory_arg, string programPath_arg,
string programConfig_arg, string matlabOctavePath_arg,
bool singleCompThread_arg, int numberOfThreadsPerJob_arg,
string operatingSystem_arg) :
computerName {move(computerName_arg)},
port {move(port_arg)},
minCpuNbr {minCpuNbr_arg},
@ -89,7 +82,8 @@ FollowerNode::FollowerNode(string computerName_arg, string port_arg, int minCpuN
}
}
Cluster::Cluster(member_nodes_t member_nodes_arg) : member_nodes {move(member_nodes_arg)}
Configuration::Cluster::Cluster(member_nodes_t member_nodes_arg) :
member_nodes {move(member_nodes_arg)}
{
if (member_nodes.empty())
{
@ -98,9 +92,9 @@ Cluster::Cluster(member_nodes_t member_nodes_arg) : member_nodes {move(member_no
}
}
ConfigFile::ConfigFile(bool parallel_arg, bool parallel_test_arg,
bool parallel_follower_open_mode_arg, bool parallel_use_psexec_arg,
string cluster_name_arg) :
Configuration::Configuration(bool parallel_arg, bool parallel_test_arg,
bool parallel_follower_open_mode_arg, bool parallel_use_psexec_arg,
string cluster_name_arg) :
parallel {parallel_arg},
parallel_test {parallel_test_arg},
parallel_follower_open_mode {parallel_follower_open_mode_arg},
@ -110,68 +104,63 @@ ConfigFile::ConfigFile(bool parallel_arg, bool parallel_test_arg,
}
void
ConfigFile::getConfigFileInfo(const filesystem::path& config_file)
Configuration::getConfigFileInfo(const filesystem::path& conffile_option,
WarningConsolidation& warnings)
{
using namespace boost;
ifstream configFile;
filesystem::path config_file {conffile_option};
if (config_file.empty())
{
filesystem::path defaultConfigFile;
// Test OS and try to open default file
#if defined(_WIN32) || defined(__CYGWIN32__)
if (auto appdata = getenv("APPDATA"); appdata)
defaultConfigFile = filesystem::path {appdata} / "dynare.ini";
else
{
if (parallel || parallel_test)
cerr << "ERROR: ";
else
cerr << "WARNING: ";
cerr << "APPDATA environment variable not found." << endl;
config_file = findConfigFile("dynare.ini");
if (parallel || parallel_test)
exit(EXIT_FAILURE);
}
if (config_file.empty()) // Try old default location (Dynare ⩽ 5) for backward compatibility
{
filesystem::path old_default_config_file;
#ifdef _WIN32
array<wchar_t, MAX_PATH + 1> appdata;
if (SHGetFolderPathW(nullptr, CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY, nullptr,
SHGFP_TYPE_CURRENT, appdata.data())
== S_OK)
old_default_config_file = filesystem::path {appdata.data()} / "dynare.ini";
#else
if (auto home = getenv("HOME"); home)
defaultConfigFile = filesystem::path {home} / ".dynare";
else
{
if (parallel || parallel_test)
cerr << "ERROR: ";
else
cerr << "WARNING: ";
cerr << "HOME environment variable not found." << endl;
if (parallel || parallel_test)
exit(EXIT_FAILURE);
}
if (auto home = getenv("HOME"); home)
old_default_config_file = filesystem::path {home} / ".dynare";
#endif
configFile.open(defaultConfigFile, fstream::in);
if (!configFile.is_open())
{
if (parallel || parallel_test)
if (!old_default_config_file.empty() && exists(old_default_config_file))
{
cerr << "ERROR: Could not open the default config file ("
<< defaultConfigFile.string() << ")" << endl;
exit(EXIT_FAILURE);
warnings << "WARNING: the location " << old_default_config_file.string()
<< " for the configuration file is obsolete; please see the reference"
<< " manual for the new location." << endl;
config_file = old_default_config_file;
}
else
return;
}
}
else
if (config_file.empty())
{
configFile.open(config_file, fstream::in);
if (!configFile.is_open())
if (parallel || parallel_test)
{
cerr << "ERROR: Couldn't open file " << config_file.string() << endl;
cerr << "ERROR: the parallel or parallel_test option was passed but no configuration "
<< "file was found" << endl;
exit(EXIT_FAILURE);
}
else
return;
}
ifstream configFile;
configFile.open(config_file, fstream::in);
if (!configFile.is_open())
{
cerr << "ERROR: Couldn't open configuration file " << config_file.string() << endl;
exit(EXIT_FAILURE);
}
string name, computerName, port, userName, password, remoteDrive, remoteDirectory, programPath,
programConfig, matlabOctavePath, operatingSystem, global_init_file;
programConfig, matlabOctavePath, operatingSystem;
vector<string> includepath;
int minCpuNbr {0}, maxCpuNbr {0};
int numberOfThreadsPerJob {1};
@ -190,10 +179,7 @@ ConfigFile::getConfigFileInfo(const filesystem::path& config_file)
if (line == "[node]" || line == "[cluster]" || line == "[hooks]" || line == "[paths]")
{
if (!global_init_file.empty())
// we were just in [hooks]
addHooksConfFileElement(global_init_file);
else if (!includepath.empty())
if (!includepath.empty())
// we were just in [paths]
addPathsConfFileElement(includepath);
else
@ -234,8 +220,7 @@ ConfigFile::getConfigFileInfo(const filesystem::path& config_file)
}
name = userName = computerName = port = password = remoteDrive = remoteDirectory
= programPath = programConfig = matlabOctavePath = operatingSystem = global_init_file
= "";
= programPath = programConfig = matlabOctavePath = operatingSystem = "";
includepath.clear();
minCpuNbr = maxCpuNbr = 0;
numberOfThreadsPerJob = 1;
@ -455,9 +440,7 @@ ConfigFile::getConfigFileInfo(const filesystem::path& config_file)
}
}
if (!global_init_file.empty())
addHooksConfFileElement(global_init_file);
else if (!includepath.empty())
if (!includepath.empty())
addPathsConfFileElement(includepath);
else
addParallelConfFileElement(inNode, inCluster, member_nodes, name, computerName, port, minCpuNbr,
@ -469,20 +452,7 @@ ConfigFile::getConfigFileInfo(const filesystem::path& config_file)
}
void
ConfigFile::addHooksConfFileElement(string global_init_file)
{
if (global_init_file.empty())
{
cerr << "ERROR: The global initialization file must be passed to the GlobalInitFile option."
<< endl;
exit(EXIT_FAILURE);
}
else
hooks.emplace_back(move(global_init_file));
}
void
ConfigFile::addPathsConfFileElement(vector<string> includepath)
Configuration::addPathsConfFileElement(vector<string> includepath)
{
if (includepath.empty())
{
@ -494,15 +464,15 @@ ConfigFile::addPathsConfFileElement(vector<string> includepath)
}
void
ConfigFile::addParallelConfFileElement(bool inNode, bool inCluster,
const member_nodes_t& member_nodes, const string& name,
const string& computerName, const string& port,
int minCpuNbr, int maxCpuNbr, const string& userName,
const string& password, const string& remoteDrive,
const string& remoteDirectory, const string& programPath,
const string& programConfig, const string& matlabOctavePath,
bool singleCompThread, int numberOfThreadsPerJob,
const string& operatingSystem)
Configuration::addParallelConfFileElement(bool inNode, bool inCluster,
const member_nodes_t& member_nodes, const string& name,
const string& computerName, const string& port,
int minCpuNbr, int maxCpuNbr, const string& userName,
const string& password, const string& remoteDrive,
const string& remoteDirectory, const string& programPath,
const string& programConfig,
const string& matlabOctavePath, bool singleCompThread,
int numberOfThreadsPerJob, const string& operatingSystem)
{
//! ADD NODE
if (inNode)
@ -546,17 +516,8 @@ ConfigFile::addParallelConfFileElement(bool inNode, bool inCluster,
}
void
ConfigFile::checkPass([[maybe_unused]] WarningConsolidation& warnings) const
Configuration::checkPass([[maybe_unused]] WarningConsolidation& warnings) const
{
for (bool global_init_file_declared {false}; const auto& hook : hooks)
for (const auto& mapit : hook.get_hooks())
if (mapit.first == "global_init_file")
if (exchange(global_init_file_declared, true))
{
cerr << "ERROR: Only one global initialization file may be provided." << endl;
exit(EXIT_FAILURE);
}
if (!parallel && !parallel_test)
return;
@ -684,8 +645,14 @@ ConfigFile::checkPass([[maybe_unused]] WarningConsolidation& warnings) const
}
void
ConfigFile::transformPass()
Configuration::transformPass()
{
/* If the user did not specify the GlobalInitFile option, use global_init.m in configuration
directory if it exists */
if (auto default_global_init_file = findConfigFile("global_init.m");
global_init_file.empty() && !default_global_init_file.empty())
global_init_file = default_global_init_file.string();
if (!parallel && !parallel_test)
return;
@ -711,10 +678,10 @@ ConfigFile::transformPass()
}
vector<filesystem::path>
ConfigFile::getIncludePaths() const
Configuration::getIncludePaths() const
{
vector<filesystem::path> include_paths;
for (auto path : paths)
for (const auto& path : paths)
for (const auto& mapit : path.get_paths())
for (const auto& vecit : mapit.second)
include_paths.emplace_back(vecit);
@ -722,15 +689,14 @@ ConfigFile::getIncludePaths() const
}
void
ConfigFile::writeHooks(ostream& output) const
Configuration::writeHooks(ostream& output) const
{
for (auto hook : hooks)
for (const auto& mapit : hook.get_hooks())
output << "options_." << mapit.first << " = '" << mapit.second << "';" << endl;
if (!global_init_file.empty())
output << "options_.global_init_file = '" << global_init_file << "';" << endl;
}
void
ConfigFile::writeCluster(ostream& output) const
Configuration::writeCluster(ostream& output) const
{
if (!parallel && !parallel_test)
return;
@ -804,7 +770,7 @@ ConfigFile::writeCluster(ostream& output) const
}
void
ConfigFile::writeEndParallel(ostream& output) const
Configuration::writeEndParallel(ostream& output) const
{
if ((!parallel && !parallel_test) || !parallel_follower_open_mode)
return;
@ -813,3 +779,46 @@ ConfigFile::writeEndParallel(ostream& output) const
<< " closeSlave(options_.parallel,options_.parallel_info.RemoteTmpFolder);" << endl
<< "end" << endl;
}
filesystem::path
Configuration::findConfigFile(const string& filename)
{
#ifdef _WIN32
array<wchar_t, MAX_PATH + 1> appdata;
if (SHGetFolderPathW(nullptr, CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY, nullptr, SHGFP_TYPE_CURRENT,
appdata.data())
== S_OK)
{
filesystem::path candidate {filesystem::path {appdata.data()} / "dynare" / filename};
if (exists(candidate))
return candidate;
}
#else
filesystem::path xdg_config_home;
if (auto xdg_config_home_env = getenv("XDG_CONFIG_HOME"); xdg_config_home_env)
xdg_config_home = xdg_config_home_env;
if (auto home = getenv("HOME"); xdg_config_home.empty() && home)
xdg_config_home = filesystem::path {home} / ".config";
if (!xdg_config_home.empty())
{
filesystem::path candidate {xdg_config_home / "dynare" / filename};
if (exists(candidate))
return candidate;
}
string xdg_config_dirs;
if (auto xdg_config_dirs_env = getenv("XDG_CONFIG_DIRS"); xdg_config_dirs_env)
xdg_config_dirs = xdg_config_dirs_env;
if (xdg_config_dirs.empty())
xdg_config_dirs = "/etc/xdg";
for (const auto& dir : DataTree::strsplit(xdg_config_dirs, ':'))
{
filesystem::path candidate {filesystem::path {dir} / "dynare" / filename};
if (exists(candidate))
return candidate;
}
#endif
return {};
}

View File

@ -17,8 +17,8 @@
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_FILE_HH
#define CONFIG_FILE_HH
#ifndef CONFIGURATION_HH
#define CONFIGURATION_HH
#include <filesystem>
#include <map>
@ -28,94 +28,65 @@
using namespace std;
using member_nodes_t = map<string, double>;
class Hook
/* The abstract representation of the configuration.
Merges information from the command-line and from the configuration file. */
class Configuration
{
public:
explicit Hook(string global_init_file_arg);
Configuration(bool parallel_arg, bool parallel_test_arg, bool parallel_follower_open_mode_arg,
bool parallel_use_psexec_arg, string cluster_name);
private:
map<string, string> hooks;
using member_nodes_t = map<string, double>;
public:
[[nodiscard]] map<string, string>
get_hooks() const
class Path
{
return hooks;
public:
explicit Path(vector<string> includepath_arg);
[[nodiscard]] map<string, vector<string>>
get_paths() const
{
return paths;
};
private:
map<string, vector<string>> paths;
};
};
class Path
{
public:
explicit Path(vector<string> includepath_arg);
private:
map<string, vector<string>> paths;
public:
[[nodiscard]] map<string, vector<string>>
get_paths() const
struct FollowerNode
{
return paths;
FollowerNode(string computerName_arg, string port_arg, int minCpuNbr_arg, int maxCpuNbr_arg,
string userName_arg, string password_arg, string remoteDrive_arg,
string remoteDirectory_arg, string programPath_arg, string programConfig_arg,
string matlabOctavePath_arg, bool singleCompThread_arg,
int numberOfThreadsPerJob_arg, string operatingSystem_arg);
const string computerName, port;
int minCpuNbr, maxCpuNbr;
const string userName, password;
const string remoteDrive, remoteDirectory;
const string programPath, programConfig, matlabOctavePath;
const bool singleCompThread;
const int numberOfThreadsPerJob;
const string operatingSystem;
};
};
class FollowerNode
{
friend class ConfigFile;
struct Cluster
{
explicit Cluster(member_nodes_t member_nodes_arg);
member_nodes_t member_nodes;
};
public:
FollowerNode(string computerName_arg, string port_arg, int minCpuNbr_arg, int maxCpuNbr_arg,
string userName_arg, string password_arg, string remoteDrive_arg,
string remoteDirectory_arg, string programPath_arg, string programConfig_arg,
string matlabOctavePath_arg, bool singleCompThread_arg,
int numberOfThreadsPerJob_arg, string operatingSystem_arg);
protected:
const string computerName, port;
int minCpuNbr, maxCpuNbr;
const string userName, password;
const string remoteDrive, remoteDirectory;
const string programPath, programConfig, matlabOctavePath;
const bool singleCompThread;
const int numberOfThreadsPerJob;
const string operatingSystem;
};
class Cluster
{
friend class ConfigFile;
public:
explicit Cluster(member_nodes_t member_nodes_arg);
protected:
member_nodes_t member_nodes;
};
//! The abstract representation of a "config" file
class ConfigFile
{
public:
ConfigFile(bool parallel_arg, bool parallel_test_arg, bool parallel_follower_open_mode_arg,
bool parallel_use_psexec_arg, string cluster_name);
private:
const bool parallel, parallel_test, parallel_follower_open_mode, parallel_use_psexec;
const string cluster_name;
string firstClusterName;
//! Hooks
vector<Hook> hooks;
string global_init_file;
//! Paths
vector<Path> paths;
//! Cluster Table
map<string, Cluster> clusters;
//! Node Map
map<string, FollowerNode> follower_nodes;
//! Add Hooks
void addHooksConfFileElement(string global_init_file);
//! Add Paths
void addPathsConfFileElement(vector<string> includepath);
//! Add a FollowerNode or a Cluster object
@ -127,10 +98,17 @@ private:
const string& programPath, const string& programConfig,
const string& matlabOctavePath, bool singleCompThread,
int numberOfThreadsPerJob, const string& operatingSystem);
/* Given a filename (e.g. dynare.ini), looks for it in the configuration directory:
if under Linux or macOS, look into the dynare subdirectory of the XDG
configuration directories (following the default values and the precedence order specified in
the XDG specification)
if under Windows, look into %APPDATA%\dynare\
The returned path will be empty if the file is not found. */
[[nodiscard]] static filesystem::path findConfigFile(const string& filename);
public:
//! Parse config file
void getConfigFileInfo(const filesystem::path& parallel_config_file);
void getConfigFileInfo(const filesystem::path& conffile_option, WarningConsolidation& warnings);
//! Check Pass
void checkPass(WarningConsolidation& warnings) const;
//! Check Pass

View File

@ -946,10 +946,10 @@ DataTree::strsplit(string_view str, char delim)
}
filesystem::path
DataTree::packageDir(string_view package)
DataTree::packageDir(const string_view& package)
{
filesystem::path d;
for (const auto& it : strsplit(move(package), '.'))
for (const auto& it : strsplit(package, '.'))
d /= "+" + it;
return d;
}

View File

@ -384,7 +384,7 @@ public:
and returns the path to the corresponding filesystem directory.
In practice the package nesting is used for the planner_objective (stored
inside +objective subdir). */
static filesystem::path packageDir(string_view package);
static filesystem::path packageDir(const string_view& package);
};
inline expr_t

View File

@ -164,11 +164,11 @@ DynamicModel::writeDynamicBytecode(const string& basename) const
writeBytecodeBinFile(basename + "/model/bytecode/dynamic.bin",
simulation_type == BlockSimulationType::solveTwoBoundariesComplete)};
BytecodeWriter code_file {basename + "/model/bytecode/dynamic.cod"};
Bytecode::Writer code_file {basename + "/model/bytecode/dynamic.cod"};
// Declare temporary terms
code_file << FDIMT_ {static_cast<int>(temporary_terms_derivatives[0].size()
+ temporary_terms_derivatives[1].size())};
code_file << Bytecode::FDIMT {static_cast<int>(temporary_terms_derivatives[0].size()
+ temporary_terms_derivatives[1].size())};
// Declare the (single) block
vector<int> exo(symbol_table.exo_nbr()), exo_det(symbol_table.exo_det_nbr());
@ -183,19 +183,19 @@ DynamicModel::writeDynamicBytecode(const string& basename) const
vector<int> endo_idx(symbol_table.endo_nbr());
iota(endo_idx.begin(), endo_idx.end(), 0);
code_file << FBEGINBLOCK_ {symbol_table.endo_nbr(),
simulation_type,
0,
symbol_table.endo_nbr(),
endo_idx,
eq_idx,
false,
u_count_int,
jacobian_ncols_endo,
symbol_table.exo_det_nbr(),
symbol_table.exo_nbr(),
exo_det,
exo};
code_file << Bytecode::FBEGINBLOCK {symbol_table.endo_nbr(),
simulation_type,
0,
symbol_table.endo_nbr(),
endo_idx,
eq_idx,
false,
u_count_int,
jacobian_ncols_endo,
symbol_table.exo_det_nbr(),
symbol_table.exo_nbr(),
exo_det,
exo};
writeBytecodeHelper<true>(code_file);
}
@ -203,7 +203,7 @@ DynamicModel::writeDynamicBytecode(const string& basename) const
void
DynamicModel::writeDynamicBlockBytecode(const string& basename) const
{
BytecodeWriter code_file {basename + "/model/bytecode/block/dynamic.cod"};
Bytecode::Writer code_file {basename + "/model/bytecode/block/dynamic.cod"};
const filesystem::path bin_filename {basename + "/model/bytecode/block/dynamic.bin"};
ofstream bin_file {bin_filename, ios::out | ios::binary};
@ -214,7 +214,7 @@ DynamicModel::writeDynamicBlockBytecode(const string& basename) const
}
// Temporary variables declaration
code_file << FDIMT_ {static_cast<int>(blocks_temporary_terms_idxs.size())};
code_file << Bytecode::FDIMT {static_cast<int>(blocks_temporary_terms_idxs.size())};
temporary_terms_t temporary_terms_written;
@ -231,19 +231,19 @@ DynamicModel::writeDynamicBlockBytecode(const string& basename) const
? writeBlockBytecodeBinFile(bin_file, block)
: 0};
code_file << FBEGINBLOCK_ {blocks[block].mfs_size,
simulation_type,
blocks[block].first_equation,
blocks[block].size,
endo_idx_block2orig,
eq_idx_block2orig,
blocks[block].linear,
u_count,
static_cast<int>(blocks_jacob_cols_endo[block].size())};
code_file << Bytecode::FBEGINBLOCK {blocks[block].mfs_size,
simulation_type,
blocks[block].first_equation,
blocks[block].size,
endo_idx_block2orig,
eq_idx_block2orig,
blocks[block].linear,
u_count,
static_cast<int>(blocks_jacob_cols_endo[block].size())};
writeBlockBytecodeHelper<true>(code_file, block, temporary_terms_written);
}
code_file << FEND_ {};
code_file << Bytecode::FEND {};
}
void
@ -302,7 +302,7 @@ string
DynamicModel::reform(const string& name1) const
{
string name = name1;
int pos = name.find(R"(\)", 0);
int pos = name.find('\\', 0);
while (pos >= 0)
{
if (name.substr(pos + 1, 1) != R"(\)")
@ -311,7 +311,7 @@ DynamicModel::reform(const string& name1) const
pos++;
}
pos++;
pos = name.find(R"(\)", pos);
pos = name.find('\\', pos);
}
return name;
}
@ -573,12 +573,12 @@ DynamicModel::parseIncludeExcludeEquations(const string& inc_exc_option_value, b
removeLeadingTrailingWhitespace(line);
if (!line.empty())
{
if (tags.empty() && line.find("=") != string::npos)
if (tags.empty() && line.find('=') != string::npos)
{
tagname_on_first_line = true;
tags += line + "(";
}
else if (line.find("'") != string::npos)
else if (line.find('\'') != string::npos)
tags += line + ",";
else
tags += "'" + line + "',";
@ -1212,7 +1212,7 @@ DynamicModel::updateVarAndTrendModel() const
exit(EXIT_FAILURE);
}
}
trend_var.push_back(move(trend_var_symb_id));
trend_var.push_back(trend_var_symb_id);
}
}
@ -1906,7 +1906,7 @@ DynamicModel::analyzePacEquationStructure(const string& name, map<string, string
exit(EXIT_FAILURE);
}
pac_equation_info[name] = {lhs,
move(optim_share_index),
optim_share_index,
move(ar_params_and_vars),
move(ec_params_and_vars),
move(non_optim_vars_params_and_constants),
@ -3575,14 +3575,15 @@ DynamicModel::fillEvalContext(eval_context_t& eval_context) const
}
void
DynamicModel::addStaticOnlyEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags)
DynamicModel::addStaticOnlyEquation(expr_t eq, const optional<int>& lineno,
map<string, string> eq_tags)
{
auto beq = dynamic_cast<BinaryOpNode*>(eq);
assert(beq && beq->op_code == BinaryOpcode::equal);
static_only_equations_equation_tags.add(static_only_equations.size(), move(eq_tags));
static_only_equations.push_back(beq);
static_only_equations_lineno.push_back(move(lineno));
static_only_equations_lineno.push_back(lineno);
}
size_t
@ -3598,7 +3599,7 @@ DynamicModel::dynamicOnlyEquationsNbr() const
}
void
DynamicModel::addOccbinEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags,
DynamicModel::addOccbinEquation(expr_t eq, const optional<int>& lineno, map<string, string> eq_tags,
const vector<string>& regimes_bind,
const vector<string>& regimes_relax)
{

View File

@ -428,7 +428,7 @@ public:
void replaceMyEquations(DynamicModel& dynamic_model) const;
//! Adds an equation marked as [static]
void addStaticOnlyEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags);
void addStaticOnlyEquation(expr_t eq, const optional<int>& lineno, map<string, string> eq_tags);
//! Returns number of static only equations
size_t staticOnlyEquationsNbr() const;
@ -441,7 +441,7 @@ public:
auxiliary parameters have already been added to the symbol table.
It also assumes that the bind and relax tags have been cleared from
eq_tags. */
void addOccbinEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags,
void addOccbinEquation(expr_t eq, const optional<int>& lineno, map<string, string> eq_tags,
const vector<string>& regimes_bind, const vector<string>& regimes_relax);
//! Writes LaTeX file with the equations of the dynamic model

View File

@ -138,7 +138,7 @@ str_tolower(string s)
%token RELATIVE_IRF REPLIC SIMUL_REPLIC RPLOT SAVE_PARAMS_AND_STEADY_STATE PARAMETER_UNCERTAINTY TARGETS
%token SHOCKS HETEROSKEDASTIC_SHOCKS SHOCK_DECOMPOSITION SHOCK_GROUPS USE_SHOCK_GROUPS SIMUL SIMUL_ALGO SIMUL_SEED ENDOGENOUS_TERMINAL_PERIOD
%token SMOOTHER SMOOTHER2HISTVAL SQUARE_ROOT_SOLVER STACK_SOLVE_ALGO STEADY_STATE_MODEL SOLVE_ALGO SOLVER_PERIODS ROBUST_LIN_SOLVE
%token STDERR STEADY STOCH_SIMUL SYLVESTER SYLVESTER_FIXED_POINT_TOL REGIMES REGIME REALTIME_SHOCK_DECOMPOSITION CONDITIONAL UNCONDITIONAL
%token STDERR STEADY STOCH_SIMUL REGIMES REGIME REALTIME_SHOCK_DECOMPOSITION CONDITIONAL UNCONDITIONAL
%token TEX RAMSEY_MODEL RAMSEY_POLICY RAMSEY_CONSTRAINTS PLANNER_DISCOUNT PLANNER_DISCOUNT_LATEX_NAME
%token DISCRETIONARY_POLICY DISCRETIONARY_TOL EVALUATE_PLANNER_OBJECTIVE
%token OCCBIN_SETUP OCCBIN_SOLVER OCCBIN_WRITE_REGIMES OCCBIN_GRAPH SIMUL_MAXIT LIKELIHOOD_MAXIT SMOOTHER_MAXIT SIMUL_PERIODS LIKELIHOOD_PERIODS SMOOTHER_PERIODS
@ -161,7 +161,7 @@ str_tolower(string s)
%token EXP LOG LN LOG10 SIN COS TAN ASIN ACOS ATAN SINH COSH TANH ASINH ACOSH ATANH ERF ERFC DIFF ADL AUXILIARY_MODEL_NAME
%token SQRT CBRT NORMCDF NORMPDF STEADY_STATE EXPECTATION
/* GSA analysis */
%token DYNARE_SENSITIVITY MORRIS STAB REDFORM PPRIOR PRIOR_RANGE PPOST ILPTAU MORRIS_NLIV
%token SENSITIVITY DYNARE_SENSITIVITY MORRIS STAB REDFORM PPRIOR PRIOR_RANGE PPOST ILPTAU MORRIS_NLIV
%token MORRIS_NTRA NSAM LOAD_REDFORM LOAD_RMSE LOAD_STAB ALPHA2_STAB LOGTRANS_REDFORM THRESHOLD_REDFORM
%token KSSTAT_REDFORM ALPHA2_REDFORM NAMENDO NAMLAGENDO NAMEXO RMSE LIK_ONLY VAR_RMSE PFILT_RMSE ISTART_RMSE
%token ALPHA_RMSE ALPHA2_RMSE
@ -215,7 +215,7 @@ str_tolower(string s)
%token ENDVAL_STEADY STEADY_SOLVE_ALGO STEADY_MAXIT STEADY_TOLF STEADY_TOLX STEADY_MARKOWITZ
%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 FROM_INITVAL_TO_ENDVAL
%token STATIC_MFS RELATIVE_TO_INITVAL
%token STATIC_MFS RELATIVE_TO_INITVAL MATCHED_IRFS MATCHED_IRFS_WEIGHTS WEIGHTS
%token <vector<string>> SYMBOL_VEC
@ -236,7 +236,7 @@ str_tolower(string s)
%type <vector<int>> vec_int_elem vec_int_1 vec_int vec_int_number
%type <PriorDistributions> prior_pdf prior_distribution
%type <pair<expr_t,expr_t>> calibration_range
%type <pair<string,string>> partition_elem subsamples_eq_opt integer_range_w_inf tag_pair
%type <pair<string,string>> partition_elem subsamples_eq_opt integer_range_w_inf tag_pair matched_irfs_elem_var_varexo
%type <vector<pair<string,string>>> partition partition_1 symbol_list_with_tex
%type <vector<map<string, string>>> tag_pair_list_for_selection
%type <map<string, string>> tag_pair_list
@ -251,6 +251,12 @@ str_tolower(string s)
%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 <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
%%
%start statement_list;
@ -326,7 +332,7 @@ statement : parameters
| bvar_forecast
| bvar_irf
| sbvar
| dynare_sensitivity
| sensitivity
| homotopy_setup
| forecast
| load_params_and_steady_state
@ -386,6 +392,8 @@ statement : parameters
| var_remove
| pac_target_info
| resid
| matched_irfs
| matched_irfs_weights
;
dsample : DSAMPLE INT_NUMBER ';'
@ -1654,8 +1662,6 @@ method_of_moments_option : o_add_tiny_number_to_cholesky
| o_simulation_method
| o_simulation_multiple
| o_sub_draws
| o_sylvester
| o_sylvester_fixed_point_tol
| o_taper_steps
| o_tex
| o_use_penalized_objective_for_hessian
@ -1762,8 +1768,6 @@ stoch_simul_primary_options : o_solve_algo
| o_conditional_variance_decomposition
| o_k_order_solver
| o_pruning
| o_sylvester
| o_sylvester_fixed_point_tol
| o_dr
| o_dr_cycle_reduction_tol
| o_dr_logarithmic_reduction_tol
@ -2297,8 +2301,6 @@ estimation_options : o_datafile
| o_cova_compute
| o_irf_shocks
| o_sub_draws
| o_sylvester
| o_sylvester_fixed_point_tol
| o_lyapunov
| o_lyapunov_fixed_point_tol
| o_lyapunov_doubling_tol
@ -3125,70 +3127,80 @@ ms_estimation : MS_ESTIMATION ';'
{ driver.ms_estimation(); }
;
dynare_sensitivity : DYNARE_SENSITIVITY ';'
{ driver.dynare_sensitivity(); }
| DYNARE_SENSITIVITY '(' dynare_sensitivity_options_list ')' ';'
{ driver.dynare_sensitivity(); }
sensitivity : SENSITIVITY ';'
{ driver.sensitivity(); }
| SENSITIVITY '(' sensitivity_options_list ')' ';'
{ driver.sensitivity(); }
| DYNARE_SENSITIVITY ';'
{
driver.warning("The 'dynare_sensitivity' command is deprecated. It has been renamed 'sensitivity'.");
driver.sensitivity();
}
| DYNARE_SENSITIVITY '(' sensitivity_options_list ')' ';'
{
driver.warning("The 'dynare_sensitivity' command is deprecated. It has been renamed 'sensitivity'.");
driver.sensitivity();
}
;
sensitivity_options_list : sensitivity_option COMMA sensitivity_options_list
| sensitivity_option
;
sensitivity_option : o_gsa_identification
| o_gsa_morris
| o_gsa_stab
| o_gsa_redform
| o_gsa_pprior
| o_gsa_prior_range
| o_gsa_ppost
| o_gsa_ilptau
| o_gsa_morris_nliv
| o_gsa_morris_ntra
| o_gsa_nsam
| o_gsa_load_redform
| o_gsa_load_rmse
| o_gsa_load_stab
| o_gsa_alpha2_stab
| o_gsa_logtrans_redform
| o_gsa_ksstat_redform
| o_gsa_alpha2_redform
| o_gsa_rmse
| o_gsa_lik_only
| o_gsa_pfilt_rmse
| o_gsa_istart_rmse
| o_gsa_alpha_rmse
| o_gsa_alpha2_rmse
| o_gsa_threshold_redform
| o_gsa_namendo
| o_gsa_namexo
| o_gsa_namlagendo
| o_gsa_var_rmse
| o_gsa_neighborhood_width
| o_gsa_pvalue_ks
| o_gsa_pvalue_corr
| o_datafile
| o_nobs
| o_first_obs
| o_prefilter
| o_presample
| o_nograph
| o_nodisplay
| o_graph_format
| o_forecasts_conf_sig
| o_mh_conf_sig
| o_loglinear
| o_mode_file
| o_load_ident_files
| o_useautocorr
| o_ar
| o_kalman_algo
| o_lik_init
| o_diffuse_filter
| o_analytic_derivation
| o_analytic_derivation_mode
;
dynare_sensitivity_options_list : dynare_sensitivity_option COMMA dynare_sensitivity_options_list
| dynare_sensitivity_option
;
dynare_sensitivity_option : o_gsa_identification
| o_gsa_morris
| o_gsa_stab
| o_gsa_redform
| o_gsa_pprior
| o_gsa_prior_range
| o_gsa_ppost
| o_gsa_ilptau
| o_gsa_morris_nliv
| o_gsa_morris_ntra
| o_gsa_nsam
| o_gsa_load_redform
| o_gsa_load_rmse
| o_gsa_load_stab
| o_gsa_alpha2_stab
| o_gsa_logtrans_redform
| o_gsa_ksstat_redform
| o_gsa_alpha2_redform
| o_gsa_rmse
| o_gsa_lik_only
| o_gsa_pfilt_rmse
| o_gsa_istart_rmse
| o_gsa_alpha_rmse
| o_gsa_alpha2_rmse
| o_gsa_threshold_redform
| o_gsa_namendo
| o_gsa_namexo
| o_gsa_namlagendo
| o_gsa_var_rmse
| o_gsa_neighborhood_width
| o_gsa_pvalue_ks
| o_gsa_pvalue_corr
| o_datafile
| o_nobs
| o_first_obs
| o_prefilter
| o_presample
| o_nograph
| o_nodisplay
| o_graph_format
| o_forecasts_conf_sig
| o_mh_conf_sig
| o_loglinear
| o_mode_file
| o_load_ident_files
| o_useautocorr
| o_ar
| o_kalman_algo
| o_lik_init
| o_diffuse_filter
| o_analytic_derivation
| o_analytic_derivation_mode
;
shock_decomposition_options_list : shock_decomposition_option COMMA shock_decomposition_options_list
| shock_decomposition_option
;
@ -3544,6 +3556,108 @@ init2shocks_element : symbol symbol ';' { driver.add_init2shocks($1, $2); }
| symbol COMMA symbol ';' { driver.add_init2shocks($1, $3); }
;
matched_irfs : MATCHED_IRFS ';' matched_irfs_list END ';'
{ driver.matched_irfs($3, false); }
| MATCHED_IRFS '(' OVERWRITE ')' ';' matched_irfs_list END ';'
{ driver.matched_irfs($6, true); }
;
matched_irfs_list : matched_irfs_elem
{ $$ = {$1}; }
| matched_irfs_list matched_irfs_elem
{
$$ = $1;
auto [it, success] = $$.insert($2);
if (!success)
driver.error("matched_irfs: the pair endogenous " + $2.first.first + " with exogenous " + $2.first.second + " appears two times");
}
;
matched_irfs_elem : matched_irfs_elem_var_varexo
PERIODS period_list ';'
matched_irfs_elem_values_weights
{
if ($3.size() != $5.first.size())
driver.error("matched_irfs: the 'periods' and 'values' keywords are not followed by the same number of elements");
if ($3.size() != $5.second.size())
driver.error("matched_irfs: the 'periods' and 'values' keywords are not followed by the same number of elements");
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]);
$$ = {$1, v};
}
;
matched_irfs_elem_var_varexo : VAR symbol ';' VAREXO symbol ';'
{
driver.check_symbol_is_endogenous($2);
driver.check_symbol_is_exogenous($5, false);
$$ = {$2, $5};
}
| VAREXO symbol ';' VAR symbol ';'
{
driver.check_symbol_is_endogenous($5);
driver.check_symbol_is_exogenous($2, false);
$$ = {$5, $2};
}
;
matched_irfs_elem_values_weights : VALUES value_list ';'
{
$$ = {$2, vector($2.size(),
driver.add_non_negative_constant("1"))};
}
| VALUES value_list ';' WEIGHTS value_list ';'
{ $$ = {$2, $5}; }
| WEIGHTS value_list ';' VALUES value_list ';'
{ $$ = {$5, $2}; }
;
matched_irfs_weights : MATCHED_IRFS_WEIGHTS ';' matched_irfs_weights_list END ';'
{ driver.matched_irfs_weights($3, false); }
| MATCHED_IRFS_WEIGHTS '(' OVERWRITE ')' ';' matched_irfs_weights_list END ';'
{ driver.matched_irfs_weights($6, true); }
;
matched_irfs_weights_list : matched_irfs_weights_elem
{ $$ = {$1}; }
| matched_irfs_weights_list matched_irfs_weights_elem
{
$$ = $1;
auto [it, success] = $$.insert($2);
if (!success)
driver.error("matched_irfs: the tuple (" + get<0>($2.first)
+ "(" + get<1>($2.first) + ")," + get<2>($2.first)
+ "," + get<3>($2.first) + "(" + get<4>($2.first) + "),"
+ get<5>($2.first) + ") appears two times");
}
;
matched_irfs_weights_elem : matched_irfs_weights_elem_var_varexo COMMA
matched_irfs_weights_elem_var_varexo COMMA
expression ';'
{
$$ = {{get<0>($1), get<1>($1), get<2>($1),
get<0>($3), get<1>($3), get<2>($3)},
$5};
}
;
matched_irfs_weights_elem_var_varexo : symbol '(' INT_NUMBER ')' COMMA symbol
{
driver.check_symbol_is_endogenous($1);
driver.check_symbol_is_exogenous($6, false);
$$ = {$1, $3, $6};
}
| symbol '(' integer_range ')' COMMA symbol
{
driver.check_symbol_is_endogenous($1);
driver.check_symbol_is_exogenous($6, false);
$$ = {$1, $3, $6};
}
;
o_solve_algo : SOLVE_ALGO EQUAL INT_NUMBER { driver.option_num("solve_algo", $3); };
o_stack_solve_algo : STACK_SOLVE_ALGO EQUAL INT_NUMBER { driver.option_num("stack_solve_algo", $3); };
o_robust_lin_solve : ROBUST_LIN_SOLVE { driver.option_num("simul.robust_lin_solve", "true"); };
@ -3818,9 +3932,6 @@ o_partial_information : PARTIAL_INFORMATION { driver.option_num("partial_informa
o_sub_draws: SUB_DRAWS EQUAL INT_NUMBER { driver.option_num("sub_draws", $3); };
o_planner_discount : PLANNER_DISCOUNT EQUAL expression { driver.set_planner_discount($3); };
o_planner_discount_latex_name : PLANNER_DISCOUNT_LATEX_NAME EQUAL TEX_NAME { driver.set_planner_discount_latex_name($3); };
o_sylvester : SYLVESTER EQUAL FIXED_POINT { driver.option_num("sylvester_fp", "true"); }
| SYLVESTER EQUAL DEFAULT { driver.option_num("sylvester_fp", "false"); };
o_sylvester_fixed_point_tol : SYLVESTER_FIXED_POINT_TOL EQUAL non_negative_number { driver.option_num("sylvester_fixed_point_tol", $3); };
o_lyapunov : LYAPUNOV EQUAL FIXED_POINT { driver.option_num("lyapunov_fp", "true"); }
| LYAPUNOV EQUAL DOUBLING { driver.option_num("lyapunov_db", "true"); }
| LYAPUNOV EQUAL SQUARE_ROOT_SOLVER { driver.option_num("lyapunov_srs", "true"); }

View File

@ -155,7 +155,8 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<INITIAL>bvar_density {BEGIN DYNARE_STATEMENT; return token::BVAR_DENSITY; }
<INITIAL>bvar_forecast {BEGIN DYNARE_STATEMENT; return token::BVAR_FORECAST; }
<INITIAL>bvar_irf {BEGIN DYNARE_STATEMENT; return token::BVAR_IRF; }
<INITIAL>dynare_sensitivity {BEGIN DYNARE_STATEMENT; return token::DYNARE_SENSITIVITY;}
<INITIAL>sensitivity {BEGIN DYNARE_STATEMENT; return token::SENSITIVITY;}
<INITIAL>dynare_sensitivity {BEGIN DYNARE_STATEMENT; return token::DYNARE_SENSITIVITY;} // Deprecated
<INITIAL>initval_file {BEGIN DYNARE_STATEMENT; return token::INITVAL_FILE;}
<INITIAL>histval_file {BEGIN DYNARE_STATEMENT; return token::HISTVAL_FILE;}
<INITIAL>forecast {BEGIN DYNARE_STATEMENT; return token::FORECAST;}
@ -232,6 +233,8 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<INITIAL>occbin_constraints {BEGIN DYNARE_BLOCK; return token::OCCBIN_CONSTRAINTS;}
<INITIAL>model_replace {BEGIN DYNARE_BLOCK; return token::MODEL_REPLACE;}
<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;}
/* For the semicolon after an "end" keyword */
<INITIAL>; {return Dynare::parser::token_type (yytext[0]);}
@ -786,6 +789,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
/* Inside a Dynare block */
<DYNARE_BLOCK>var {return token::VAR;}
<DYNARE_BLOCK>varexo {return token::VAREXO;}
<DYNARE_BLOCK>stderr {return token::STDERR;}
<DYNARE_BLOCK>values {return token::VALUES;}
<DYNARE_BLOCK>corr {return token::CORR;}
@ -855,7 +859,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
yylval->build<string>(yytext);
return token::DD;
}
<DYNARE_BLOCK>weights {return token::WEIGHTS;}
/* Inside Dynare statement */
<DYNARE_STATEMENT>solve_algo {return token::SOLVE_ALGO;}
@ -865,13 +869,11 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>robust_lin_solve {return token::ROBUST_LIN_SOLVE;}
<DYNARE_STATEMENT>drop {return token::DROP;}
<DYNARE_STATEMENT>order {return token::ORDER;}
<DYNARE_STATEMENT>sylvester {return token::SYLVESTER;}
<DYNARE_STATEMENT>lyapunov {return token::LYAPUNOV;}
<DYNARE_STATEMENT>dr {
yylval->build<string>(yytext);
return token::DR;
}
<DYNARE_STATEMENT>sylvester_fixed_point_tol {return token::SYLVESTER_FIXED_POINT_TOL;}
<DYNARE_STATEMENT>lyapunov_complex_threshold {return token::LYAPUNOV_COMPLEX_THRESHOLD;}
<DYNARE_STATEMENT>lyapunov_fixed_point_tol {return token::LYAPUNOV_FIXED_POINT_TOL;}
<DYNARE_STATEMENT>lyapunov_doubling_tol {return token::LYAPUNOV_DOUBLING_TOL;}

View File

@ -31,7 +31,7 @@
#include <unistd.h>
#include "ConfigFile.hh"
#include "Configuration.hh"
#include "ExtendedPreprocessorTypes.hh"
#include "ModFile.hh"
#include "ParsingDriver.hh"
@ -53,7 +53,7 @@ usage()
cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [onlyclearglobals] "
"[savemacro[=macro_file]] [onlymacro] [linemacro] [notmpterms] [nolog] [warn_uninit]"
<< " [console] [nograph] [nointeractive] [parallel[=cluster_name]] "
"[conffile=parallel_config_path_and_filename] [parallel_follower_open_mode] "
"[conffile=path_to_config_file] [parallel_follower_open_mode] "
"[parallel_test] [parallel_use_psexec=true|false]"
<< " [-D<variable>[=<value>]] [-I/path] [nostrict] [stochastic] [fast] [minimal_workspace] "
"[compute_xrefs] [output=second|third] [language=matlab|julia]"
@ -142,7 +142,7 @@ main(int argc, char** argv)
bool console = false;
bool nograph = false;
bool nointeractive = false;
filesystem::path parallel_config_file;
filesystem::path conffile;
bool parallel = false;
string cluster_name;
bool parallel_follower_open_mode
@ -234,7 +234,7 @@ main(int argc, char** argv)
cerr << "Incorrect syntax for conffile option" << endl;
usage();
}
parallel_config_file = s.substr(9);
conffile = s.substr(9);
}
else if (s == "parallel_follower_open_mode"
|| s == "parallel_slave_open_mode") // Kept for backward compatibility, see #86
@ -444,9 +444,9 @@ main(int argc, char** argv)
dynareroot = dynareroot.parent_path();
// Construct basename (i.e. remove file extension if there is one)
/* Calling `string()` method on filename because of bug in GCC/MinGW 10.2
(shipped in Debian Bullseye 11), that fails to accept implicit
conversion to string from filename::path. */
/* Calling string() method on filename.stem(): not necessary on GNU/Linux and macOS because there
is an implicit conversion from filesystem:path to string (i.e. basic_string<char>), but needed
on Windows because the implicit conversion is only to wstring (i.e. basic_string<wchar_t>). */
const string basename {filename.stem().string()};
// Forbid some basenames, since they will cause trouble (see preprocessor#62)
@ -461,15 +461,15 @@ main(int argc, char** argv)
WarningConsolidation warnings(no_warn);
// Process config file
ConfigFile config_file(parallel, parallel_test, parallel_follower_open_mode, parallel_use_psexec,
cluster_name);
config_file.getConfigFileInfo(parallel_config_file);
config_file.checkPass(warnings);
config_file.transformPass();
Configuration config {parallel, parallel_test, parallel_follower_open_mode, parallel_use_psexec,
cluster_name};
config.getConfigFileInfo(conffile, warnings);
config.checkPass(warnings);
config.transformPass();
// If Include option was passed to the [paths] block of the config file, add
// it to paths before macroprocessing
for (const auto& it : config_file.getIncludePaths())
for (const auto& it : config.getIncludePaths())
paths.emplace_back(it);
/*
@ -540,7 +540,7 @@ main(int argc, char** argv)
mod_file->writeJuliaOutput(basename);
else
mod_file->writeMOutput(basename, clear_all, clear_global, no_warn, console, nograph,
nointeractive, config_file, check_model_changes, minimal_workspace,
nointeractive, config, check_model_changes, minimal_workspace,
compute_xrefs, mexext, matlabroot, onlymodel, gui, notime);
/* Ensures that workers are not destroyed before they finish compiling.

View File

@ -144,7 +144,7 @@ ExprNode::checkIfTemporaryTermThenWrite(ostream& output, ExprNodeOutputType outp
bool
ExprNode::checkIfTemporaryTermThenWriteBytecode(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs) const
{
@ -163,10 +163,10 @@ ExprNode::checkIfTemporaryTermThenWriteBytecode(
was initially not called with steady_dynamic=true). */
return false;
case ExprNodeBytecodeOutputType::dynamicModel:
code_file << FLDT_ {it2->second};
code_file << Bytecode::FLDT {it2->second};
break;
case ExprNodeBytecodeOutputType::staticModel:
code_file << FLDST_ {it2->second};
code_file << Bytecode::FLDST {it2->second};
break;
case ExprNodeBytecodeOutputType::dynamicAssignmentLHS:
case ExprNodeBytecodeOutputType::staticAssignmentLHS:
@ -267,7 +267,7 @@ ExprNode::writeJsonExternalFunctionOutput([[maybe_unused]] vector<string>& efout
void
ExprNode::writeBytecodeExternalFunctionOutput(
[[maybe_unused]] BytecodeWriter& code_file,
[[maybe_unused]] Bytecode::Writer& code_file,
[[maybe_unused]] ExprNodeBytecodeOutputType output_type,
[[maybe_unused]] const temporary_terms_t& temporary_terms,
[[maybe_unused]] const temporary_terms_idxs_t& temporary_terms_idxs,
@ -556,7 +556,8 @@ NumConstNode::eval([[maybe_unused]] const eval_context_t& eval_context) const no
}
void
NumConstNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
NumConstNode::writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
[[maybe_unused]] const deriv_node_temp_terms_t& tef_terms) const
@ -564,7 +565,7 @@ NumConstNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOut
assert(!isAssignmentLHSBytecodeOutput(output_type));
if (!checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms,
temporary_terms_idxs))
code_file << FLDC_ {datatree.num_constants.getDouble(id)};
code_file << Bytecode::FLDC {datatree.num_constants.getDouble(id)};
}
void
@ -1431,7 +1432,8 @@ VariableNode::eval(const eval_context_t& eval_context) const noexcept(false)
}
void
VariableNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
VariableNode::writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const
@ -1450,19 +1452,19 @@ VariableNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOut
switch (output_type)
{
case ExprNodeBytecodeOutputType::dynamicModel:
code_file << FLDV_ {type, tsid, lag};
code_file << Bytecode::FLDV {type, tsid, lag};
break;
case ExprNodeBytecodeOutputType::staticModel:
code_file << FLDSV_ {type, tsid};
code_file << Bytecode::FLDSV {type, tsid};
break;
case ExprNodeBytecodeOutputType::dynamicSteadyStateOperator:
code_file << FLDVS_ {type, tsid};
code_file << Bytecode::FLDVS {type, tsid};
break;
case ExprNodeBytecodeOutputType::dynamicAssignmentLHS:
code_file << FSTPV_ {type, tsid, lag};
code_file << Bytecode::FSTPV {type, tsid, lag};
break;
case ExprNodeBytecodeOutputType::staticAssignmentLHS:
code_file << FSTPSV_ {type, tsid};
code_file << Bytecode::FSTPSV {type, tsid};
break;
}
}
@ -3160,7 +3162,7 @@ UnaryOpNode::writeJsonExternalFunctionOutput(vector<string>& efout,
}
void
UnaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file,
UnaryOpNode::writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
@ -3250,7 +3252,8 @@ UnaryOpNode::eval(const eval_context_t& eval_context) const noexcept(false)
}
void
UnaryOpNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
UnaryOpNode::writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const
@ -3283,7 +3286,7 @@ UnaryOpNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutp
{
arg->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs,
tef_terms);
code_file << FUNARY_ {op_code};
code_file << Bytecode::FUNARY {op_code};
}
}
@ -4547,7 +4550,8 @@ BinaryOpNode::eval(const eval_context_t& eval_context) const noexcept(false)
}
void
BinaryOpNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
BinaryOpNode::writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const
@ -4558,12 +4562,12 @@ BinaryOpNode::writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOut
return;
if (op_code == BinaryOpcode::powerDeriv)
code_file << FLDC_ {static_cast<double>(powerDerivOrder)};
code_file << Bytecode::FLDC {static_cast<double>(powerDerivOrder)};
arg1->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs,
tef_terms);
arg2->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs,
tef_terms);
code_file << FBINARY_ {op_code};
code_file << Bytecode::FBINARY {op_code};
}
bool
@ -5009,7 +5013,7 @@ BinaryOpNode::writeJsonExternalFunctionOutput(vector<string>& efout,
void
BinaryOpNode::writeBytecodeExternalFunctionOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const
{
@ -5697,7 +5701,7 @@ BinaryOpNode::getPacAREC(
{
// NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage)
auto [vid, lag, pid, constant] = term->matchVariableTimesConstantTimesParam(true);
linear_combination.emplace_back(vid.value(), lag, move(pid), constant);
linear_combination.emplace_back(vid.value(), lag, pid, constant);
}
catch (MatchFailureException& e)
{
@ -6288,7 +6292,7 @@ TrinaryOpNode::eval(const eval_context_t& eval_context) const noexcept(false)
}
void
TrinaryOpNode::writeBytecodeOutput(BytecodeWriter& code_file,
TrinaryOpNode::writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
@ -6305,7 +6309,7 @@ TrinaryOpNode::writeBytecodeOutput(BytecodeWriter& code_file,
tef_terms);
arg3->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs,
tef_terms);
code_file << FTRINARY_ {op_code};
code_file << Bytecode::FTRINARY {op_code};
}
bool
@ -6484,7 +6488,7 @@ TrinaryOpNode::writeJsonExternalFunctionOutput(vector<string>& efout,
void
TrinaryOpNode::writeBytecodeExternalFunctionOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const
{
@ -6917,6 +6921,7 @@ AbstractExternalFunctionNode::computeDerivative(int deriv_id)
{
assert(datatree.external_functions_table.getNargs(symb_id) > 0);
vector<expr_t> dargs;
dargs.reserve(arguments.size());
for (auto argument : arguments)
dargs.push_back(argument->getDerivative(deriv_id));
return composeDerivatives(dargs);
@ -6930,6 +6935,7 @@ AbstractExternalFunctionNode::computeChainRuleDerivative(
{
assert(datatree.external_functions_table.getNargs(symb_id) > 0);
vector<expr_t> dargs;
dargs.reserve(arguments.size());
for (auto argument : arguments)
dargs.push_back(argument->getChainRuleDerivative(deriv_id, recursive_variables,
non_null_chain_rule_derivatives, cache));
@ -6938,7 +6944,7 @@ AbstractExternalFunctionNode::computeChainRuleDerivative(
void
AbstractExternalFunctionNode::writeBytecodeExternalFunctionArguments(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const
{
@ -7405,6 +7411,7 @@ expr_t
AbstractExternalFunctionNode::toStatic(DataTree& static_datatree) const
{
vector<expr_t> static_arguments;
static_arguments.reserve(arguments.size());
for (auto argument : arguments)
static_arguments.push_back(argument->toStatic(static_datatree));
return buildSimilarExternalFunctionNode(static_arguments, static_datatree);
@ -7414,6 +7421,7 @@ expr_t
AbstractExternalFunctionNode::clone(DataTree& alt_datatree) const
{
vector<expr_t> dynamic_arguments;
dynamic_arguments.reserve(arguments.size());
for (auto argument : arguments)
dynamic_arguments.push_back(argument->clone(alt_datatree));
return buildSimilarExternalFunctionNode(dynamic_arguments, alt_datatree);
@ -7423,6 +7431,7 @@ expr_t
ExternalFunctionNode::composeDerivatives(const vector<expr_t>& dargs)
{
vector<expr_t> dNodes;
dNodes.reserve(dargs.size());
for (int i = 0; i < static_cast<int>(dargs.size()); i++)
dNodes.push_back(datatree.AddTimes(
dargs.at(i), datatree.AddFirstDerivExternalFunction(symb_id, arguments, i + 1)));
@ -7432,7 +7441,7 @@ ExternalFunctionNode::composeDerivatives(const vector<expr_t>& dargs)
}
void
ExternalFunctionNode::writeBytecodeOutput(BytecodeWriter& code_file,
ExternalFunctionNode::writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
@ -7451,14 +7460,14 @@ ExternalFunctionNode::writeBytecodeOutput(BytecodeWriter& code_file,
return;
if (!isAssignmentLHSBytecodeOutput(output_type))
code_file << FLDTEF_ {getIndxInTefTerms(symb_id, tef_terms)};
code_file << Bytecode::FLDTEF {getIndxInTefTerms(symb_id, tef_terms)};
else
code_file << FSTPTEF_ {getIndxInTefTerms(symb_id, tef_terms)};
code_file << Bytecode::FSTPTEF {getIndxInTefTerms(symb_id, tef_terms)};
}
void
ExternalFunctionNode::writeBytecodeExternalFunctionOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const
{
@ -7480,26 +7489,26 @@ ExternalFunctionNode::writeBytecodeExternalFunctionOutput(
temporary_terms_idxs, tef_terms);
int nb_output_arguments;
ExternalFunctionCallType call_type;
Bytecode::ExternalFunctionCallType call_type;
if (symb_id == first_deriv_symb_id && symb_id == second_deriv_symb_id)
{
nb_output_arguments = 3;
call_type = ExternalFunctionCallType::levelWithFirstAndSecondDerivative;
call_type = Bytecode::ExternalFunctionCallType::levelWithFirstAndSecondDerivative;
}
else if (symb_id == first_deriv_symb_id)
{
nb_output_arguments = 2;
call_type = ExternalFunctionCallType::levelWithFirstDerivative;
call_type = Bytecode::ExternalFunctionCallType::levelWithFirstDerivative;
}
else
{
nb_output_arguments = 1;
call_type = ExternalFunctionCallType::levelWithoutDerivative;
call_type = Bytecode::ExternalFunctionCallType::levelWithoutDerivative;
}
code_file << FCALL_ {nb_output_arguments, static_cast<int>(arguments.size()),
datatree.symbol_table.getName(symb_id), indx, call_type}
<< FSTPTEF_ {indx};
code_file << Bytecode::FCALL {nb_output_arguments, static_cast<int>(arguments.size()),
datatree.symbol_table.getName(symb_id), indx, call_type}
<< Bytecode::FSTPTEF {indx};
}
}
@ -7715,6 +7724,7 @@ expr_t
FirstDerivExternalFunctionNode::composeDerivatives(const vector<expr_t>& dargs)
{
vector<expr_t> dNodes;
dNodes.reserve(dargs.size());
for (int i = 0; i < static_cast<int>(dargs.size()); i++)
dNodes.push_back(datatree.AddTimes(dargs.at(i), datatree.AddSecondDerivExternalFunction(
symb_id, arguments, inputIndex, i + 1)));
@ -7809,7 +7819,7 @@ FirstDerivExternalFunctionNode::writeOutput(ostream& output, ExprNodeOutputType
void
FirstDerivExternalFunctionNode::writeBytecodeOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const
{
@ -7829,9 +7839,9 @@ FirstDerivExternalFunctionNode::writeBytecodeOutput(
assert(first_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided);
if (!isAssignmentLHSBytecodeOutput(output_type))
code_file << FLDTEFD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex};
code_file << Bytecode::FLDTEFD {getIndxInTefTerms(symb_id, tef_terms), inputIndex};
else
code_file << FSTPTEFD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex};
code_file << Bytecode::FSTPTEFD {getIndxInTefTerms(symb_id, tef_terms), inputIndex};
}
void
@ -7966,7 +7976,7 @@ FirstDerivExternalFunctionNode::writeJsonExternalFunctionOutput(
void
FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const
{
@ -7994,12 +8004,12 @@ FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(
{
int nb_input_arguments {0};
int nb_output_arguments {1};
FCALL_ fcall {nb_output_arguments, nb_input_arguments, "jacob_element", indx,
ExternalFunctionCallType::numericalFirstDerivative};
Bytecode::FCALL fcall {nb_output_arguments, nb_input_arguments, "jacob_element", indx,
Bytecode::ExternalFunctionCallType::numericalFirstDerivative};
fcall.set_arg_func_name(datatree.symbol_table.getName(symb_id));
fcall.set_row(inputIndex);
fcall.set_nb_add_input_arguments(static_cast<int>(arguments.size()));
code_file << fcall << FSTPTEFD_ {indx, inputIndex};
code_file << fcall << Bytecode::FSTPTEFD {indx, inputIndex};
}
else
{
@ -8009,10 +8019,11 @@ FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(
int nb_output_arguments {1};
code_file << FCALL_ {nb_output_arguments, static_cast<int>(arguments.size()),
datatree.symbol_table.getName(first_deriv_symb_id), indx,
ExternalFunctionCallType::separatelyProvidedFirstDerivative}
<< FSTPTEFD_ {indx, inputIndex};
code_file
<< Bytecode::FCALL {nb_output_arguments, static_cast<int>(arguments.size()),
datatree.symbol_table.getName(first_deriv_symb_id), indx,
Bytecode::ExternalFunctionCallType::separatelyProvidedFirstDerivative}
<< Bytecode::FSTPTEFD {indx, inputIndex};
}
}
@ -8313,7 +8324,7 @@ SecondDerivExternalFunctionNode::computeXrefs(EquationInfo& ei) const
void
SecondDerivExternalFunctionNode::writeBytecodeOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const
{
@ -8333,14 +8344,16 @@ SecondDerivExternalFunctionNode::writeBytecodeOutput(
assert(second_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided);
if (!isAssignmentLHSBytecodeOutput(output_type))
code_file << FLDTEFDD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex1, inputIndex2};
code_file << Bytecode::FLDTEFDD {getIndxInTefTerms(symb_id, tef_terms), inputIndex1,
inputIndex2};
else
code_file << FSTPTEFDD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex1, inputIndex2};
code_file << Bytecode::FSTPTEFDD {getIndxInTefTerms(symb_id, tef_terms), inputIndex1,
inputIndex2};
}
void
SecondDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const
{
@ -8366,22 +8379,23 @@ SecondDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(
if (int indx = getIndxInTefTerms(symb_id, tef_terms);
second_deriv_symb_id == ExternalFunctionsTable::IDNotSet)
{
FCALL_ fcall {1, 0, "hess_element", indx,
ExternalFunctionCallType::numericalSecondDerivative};
Bytecode::FCALL fcall {1, 0, "hess_element", indx,
Bytecode::ExternalFunctionCallType::numericalSecondDerivative};
fcall.set_arg_func_name(datatree.symbol_table.getName(symb_id));
fcall.set_row(inputIndex1);
fcall.set_col(inputIndex2);
fcall.set_nb_add_input_arguments(static_cast<int>(arguments.size()));
code_file << fcall << FSTPTEFDD_ {indx, inputIndex1, inputIndex2};
code_file << fcall << Bytecode::FSTPTEFDD {indx, inputIndex1, inputIndex2};
}
else
{
tef_terms[{second_deriv_symb_id, arguments}] = static_cast<int>(tef_terms.size());
code_file << FCALL_ {1, static_cast<int>(arguments.size()),
datatree.symbol_table.getName(second_deriv_symb_id), indx,
ExternalFunctionCallType::separatelyProvidedSecondDerivative}
<< FSTPTEFDD_ {indx, inputIndex1, inputIndex2};
code_file << Bytecode::
FCALL {1, static_cast<int>(arguments.size()),
datatree.symbol_table.getName(second_deriv_symb_id), indx,
Bytecode::ExternalFunctionCallType::separatelyProvidedSecondDerivative}
<< Bytecode::FSTPTEFDD {indx, inputIndex1, inputIndex2};
}
}
@ -8604,7 +8618,7 @@ SubModelNode::collectDynamicVariables([[maybe_unused]] SymbolType type_arg,
void
SubModelNode::writeBytecodeOutput(
[[maybe_unused]] BytecodeWriter& code_file,
[[maybe_unused]] Bytecode::Writer& code_file,
[[maybe_unused]] ExprNodeBytecodeOutputType output_type,
[[maybe_unused]] const temporary_terms_t& temporary_terms,
[[maybe_unused]] const temporary_terms_idxs_t& temporary_terms_idxs,
@ -9102,7 +9116,7 @@ ExprNode::matchVariableTimesConstantTimesParam(bool variable_obligatory) const
matchVTCTPHelper(variable_id, lag, param_id, constant, false);
if (variable_obligatory && !variable_id)
throw MatchFailureException {"No variable in this expression"};
return {move(variable_id), lag, move(param_id), constant};
return {variable_id, lag, param_id, constant};
}
void
@ -9194,7 +9208,7 @@ ExprNode::matchLinearCombinationOfVariables() const
auto [variable_id, lag, param_id, constant]
= term->matchVariableTimesConstantTimesParam(true);
constant *= sign;
result.emplace_back(variable_id.value(), lag, move(param_id), constant);
result.emplace_back(variable_id.value(), lag, param_id, constant);
}
return result;
}

View File

@ -321,7 +321,7 @@ protected:
// Same as above, for the bytecode case
bool
checkIfTemporaryTermThenWriteBytecode(BytecodeWriter& code_file,
checkIfTemporaryTermThenWriteBytecode(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs) const;
@ -488,7 +488,7 @@ public:
bool isdynamic = true) const;
virtual void writeBytecodeExternalFunctionOutput(
BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms, const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const;
@ -537,7 +537,7 @@ public:
[[nodiscard]] virtual double eval(const eval_context_t& eval_context) const noexcept(false) = 0;
// Write output to bytecode file
virtual void writeBytecodeOutput(BytecodeWriter& code_file,
virtual void writeBytecodeOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
@ -995,7 +995,7 @@ public:
void collectVARLHSVariable(set<expr_t>& result) const override;
void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override;
[[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override;
@ -1095,7 +1095,7 @@ public:
void collectVARLHSVariable(set<expr_t>& result) const override;
void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override;
[[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override;
@ -1231,7 +1231,7 @@ public:
const temporary_terms_t& temporary_terms,
deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const override;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file,
void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1240,7 +1240,7 @@ public:
void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override;
static double eval_opcode(UnaryOpcode op_code, double v) noexcept(false);
[[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override;
@ -1376,7 +1376,7 @@ public:
const temporary_terms_t& temporary_terms,
deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const override;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file,
void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1386,7 +1386,7 @@ public:
static double eval_opcode(double v1, BinaryOpcode op_code, double v2,
int derivOrder) noexcept(false);
[[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override;
@ -1569,7 +1569,7 @@ public:
const temporary_terms_t& temporary_terms,
deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const override;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file,
void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1578,7 +1578,7 @@ public:
void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override;
static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) noexcept(false);
[[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override;
@ -1694,7 +1694,7 @@ protected:
void writeJsonExternalFunctionArguments(ostream& output, const temporary_terms_t& temporary_terms,
const deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const;
void writeBytecodeExternalFunctionArguments(BytecodeWriter& code_file,
void writeBytecodeExternalFunctionArguments(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1737,7 +1737,7 @@ public:
deriv_node_temp_terms_t& tef_terms,
bool isdynamic = true) const override
= 0;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file,
void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1746,7 +1746,7 @@ public:
void collectVARLHSVariable(set<expr_t>& result) const override;
void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>>& result) const override;
[[nodiscard]] double eval(const eval_context_t& eval_context) const noexcept(false) override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override
@ -1842,12 +1842,12 @@ public:
const temporary_terms_t& temporary_terms,
deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const override;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file,
void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
deriv_node_temp_terms_t& tef_terms) const override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override;
@ -1877,7 +1877,7 @@ public:
void writeJsonAST(ostream& output) const override;
void writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms,
const deriv_node_temp_terms_t& tef_terms, bool isdynamic) const override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override;
@ -1889,7 +1889,7 @@ public:
const temporary_terms_t& temporary_terms,
deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const override;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file,
void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1922,7 +1922,7 @@ public:
void writeJsonAST(ostream& output) const override;
void writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms,
const deriv_node_temp_terms_t& tef_terms, bool isdynamic) const override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override;
@ -1934,7 +1934,7 @@ public:
const temporary_terms_t& temporary_terms,
deriv_node_temp_terms_t& tef_terms,
bool isdynamic) const override;
void writeBytecodeExternalFunctionOutput(BytecodeWriter& code_file,
void writeBytecodeExternalFunctionOutput(Bytecode::Writer& code_file,
ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
@ -1994,7 +1994,7 @@ public:
expr_t substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, subst_table_t& subst_table,
vector<BinaryOpNode*>& neweqs) const override;
BinaryOpNode* normalizeEquationHelper(const set<expr_t>& contain_var, expr_t rhs) const override;
void writeBytecodeOutput(BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type,
void writeBytecodeOutput(Bytecode::Writer& code_file, ExprNodeBytecodeOutputType output_type,
const temporary_terms_t& temporary_terms,
const temporary_terms_idxs_t& temporary_terms_idxs,
const deriv_node_temp_terms_t& tef_terms) const override;

View File

@ -34,9 +34,9 @@ macroExpandModFile(const filesystem::path& filename, const istream& modfile, boo
stringstream macro_output;
macro::Environment env = macro::Environment();
macro::Driver m;
/* Calling `string()` method on filename because of bug in GCC/MinGW 10.2
(shipped in Debian Bullseye 11), that fails to accept implicit
conversion to string from filename::path. */
/* Calling string() method on filename: not necessary on GNU/Linux and macOS because there is an
implicit conversion from filesystem:path to string (i.e. basic_string<char>), but needed on
Windows because the implicit conversion is only to wstring (i.e. basic_string<wchar_t>). */
m.parse(filename.string(), modfile, debug, defines, env, paths, macro_output);
if (save_macro)
{

View File

@ -27,7 +27,6 @@
#include <filesystem>
#include "ComputingTasks.hh"
#include "ConfigFile.hh"
#include "ModFile.hh"
#include "Shocks.hh"
@ -843,7 +842,7 @@ ModFile::remove_directory_with_matlab_lock(const filesystem::path& dir)
void
ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global, bool no_warn,
bool console, bool nograph, bool nointeractive, const ConfigFile& config_file,
bool console, bool nograph, bool nointeractive, const Configuration& config,
bool check_model_changes, bool minimal_workspace, bool compute_xrefs,
const string& mexext, const filesystem::path& matlabroot, bool onlymodel,
bool gui, bool notime) const
@ -916,12 +915,9 @@ ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global,
<< "% Some global variables initialization" << endl
<< "%" << endl;
if (!onlymodel)
config_file.writeHooks(mOutputFile);
config.writeHooks(mOutputFile);
mOutputFile << "global_initialization;" << endl;
if (minimal_workspace)
mOutputFile << "options_.minimal_workspace = true;" << endl;
if (console)
mOutputFile << "options_.console_mode = true;" << endl << "options_.nodisplay = true;" << endl;
if (nograph)
@ -957,14 +953,16 @@ ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global,
// May be later modified by a shocks block
mOutputFile << "M_.sigma_e_is_diagonal = true;" << endl;
// Initialize M_.det_shocks, M_.surprise_shocks, M_.learnt_shocks, M_.learnt_endval and
// M_.heteroskedastic_shocks
/* Initialize the structures created for several blocks, as part of the implementation of the
overwrite option */
mOutputFile << "M_.det_shocks = [];" << endl
<< "M_.surprise_shocks = [];" << endl
<< "M_.learnt_shocks = [];" << endl
<< "M_.learnt_endval = [];" << 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_weights = {};" << endl;
// NB: options_.{ramsey,discretionary}_policy should rather be fields of M_
mOutputFile << boolalpha << "options_.linear = " << linear << ";" << endl
@ -1002,7 +1000,7 @@ ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global,
}
if (!onlymodel)
config_file.writeCluster(mOutputFile);
config.writeCluster(mOutputFile);
if (bytecode)
mOutputFile << "if exist('bytecode') ~= 3" << endl
@ -1131,7 +1129,7 @@ ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global,
<< "_results.mat'], 'options_mom_', '-append');" << endl
<< "end" << endl;
config_file.writeEndParallel(mOutputFile);
config.writeEndParallel(mOutputFile);
if (!no_warn)
{
@ -1301,6 +1299,9 @@ ModFile::writeJsonOutputParsingCheck(const string& basename, JsonFileOutputType
output << ",";
dynamic_model.writeJsonDynamicModelInfo(output);
}
output << R"(, "steady_state_model": )" << mod_file_struct.steady_state_model_present << endl;
output << "}" << endl;
ostringstream original_model_output;

View File

@ -26,7 +26,7 @@
#include <ostream>
#include <sstream>
#include "ConfigFile.hh"
#include "Configuration.hh"
#include "DynamicModel.hh"
#include "ExtendedPreprocessorTypes.hh"
#include "ExternalFunctionsTable.hh"
@ -176,7 +176,7 @@ public:
\param compute_xrefs if true, equation cross references will be computed
*/
void writeMOutput(const string& basename, bool clear_all, bool clear_global, bool no_warn,
bool console, bool nograph, bool nointeractive, const ConfigFile& config_file,
bool console, bool nograph, bool nointeractive, const Configuration& config,
bool check_model_changes, bool minimal_workspace, bool compute_xrefs,
const string& mexext, const filesystem::path& matlabroot, bool onlymodel,
bool gui, bool notime) const;

View File

@ -529,6 +529,7 @@ Epilogue::writeOutput(ostream& output) const
expr->collectVariables(SymbolType::endogenous, endogs);
vector<string> symbol_list;
symbol_list.reserve(endogs.size());
for (auto symb_id : endogs)
symbol_list.push_back(symbol_table.getName(symb_id));
SymbolList {move(symbol_list)}.writeOutput("M_.epilogue_var_list_", output);

View File

@ -109,7 +109,7 @@ ModelTree::copyHelper(const ModelTree& m)
blocks_derivatives.push_back(v);
}
auto convert_vector_tt = [f](vector<temporary_terms_t> vtt) {
auto convert_vector_tt = [f](const vector<temporary_terms_t>& vtt) {
vector<temporary_terms_t> vtt2;
for (const auto& tt : vtt)
{
@ -1169,7 +1169,7 @@ ModelTree::fixNestedParenthesis(ostringstream& output, map<string, string>& tmp_
if (auto it = tmp_paren_vars.find(val); it == tmp_paren_vars.end())
{
varname = "paren32_tmp_var_" + to_string(i1++);
repstr = repstr + varname + " = " + val + ";\n";
repstr += varname + " = " + val + ";\n";
tmp_paren_vars[val] = varname;
}
else
@ -1182,12 +1182,12 @@ ModelTree::fixNestedParenthesis(ostringstream& output, map<string, string>& tmp_
if (auto it = tmp_paren_vars.find(str1); it == tmp_paren_vars.end())
{
varname = "paren32_tmp_var_" + to_string(i1++);
repstr = repstr + varname + " = " + str1 + ";\n";
repstr += varname + " = " + str1 + ";\n";
}
else
varname = it->second;
str.replace(first_open_paren, matching_paren - first_open_paren + 1, varname);
size_t insertLoc = str.find_last_of("\n", first_open_paren);
size_t insertLoc = str.find_last_of('\n', first_open_paren);
str.insert(insertLoc + 1, repstr);
hit_limit = false;
i = -1;
@ -1394,13 +1394,13 @@ ModelTree::writeLatexModelFile(const string& mod_basename, const string& latex_b
}
void
ModelTree::addEquation(expr_t eq, optional<int> lineno)
ModelTree::addEquation(expr_t eq, const optional<int>& lineno)
{
auto beq = dynamic_cast<BinaryOpNode*>(eq);
assert(beq && beq->op_code == BinaryOpcode::equal);
equations.push_back(beq);
equations_lineno.push_back(move(lineno));
equations_lineno.push_back(lineno);
}
void
@ -1412,10 +1412,10 @@ ModelTree::findConstantEquationsWithoutMcpTag(map<VariableNode*, NumConstNode*>&
}
void
ModelTree::addEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags)
ModelTree::addEquation(expr_t eq, const optional<int>& lineno, map<string, string> eq_tags)
{
equation_tags.add(equations.size(), move(eq_tags));
addEquation(eq, move(lineno));
addEquation(eq, lineno);
}
void
@ -1927,7 +1927,13 @@ ModelTree::initializeMEXCompilationWorkers(int numworkers, const filesystem::pat
cout << "Spawning " << numworkers << " threads for compiling MEX files." << endl;
for (int i {0}; i < numworkers; i++)
mex_compilation_workers.emplace_back([](stop_token stoken) {
/* Passing the stop_token by const reference is ok (and makes clang-tidy happier),
since the std::jthread constructor calls the lambda with the return argument of the
get_stop_token() method, which returns a stop_token by value; hence there is no lifetime
issue. See:
https://stackoverflow.com/questions/72990607/const-stdstop-token-or-just-stdstop-token-as-parameter-for-thread-funct
*/
mex_compilation_workers.emplace_back([](const stop_token& stoken) {
unique_lock<mutex> lk {mex_compilation_mut};
filesystem::path output;
string cmd;

View File

@ -294,9 +294,10 @@ protected:
const string& concat) const;
//! Writes temporary terms in bytecode
template<ExprNodeBytecodeOutputType output_type>
void
writeBytecodeTemporaryTerms(const temporary_terms_t& tt, temporary_terms_t& temporary_terms_union,
BytecodeWriter& code_file, deriv_node_temp_terms_t& tef_terms) const;
void writeBytecodeTemporaryTerms(const temporary_terms_t& tt,
temporary_terms_t& temporary_terms_union,
Bytecode::Writer& code_file,
deriv_node_temp_terms_t& tef_terms) const;
/* Adds information for (non-block) bytecode simulation in a separate .bin
file.
Returns the number of first derivatives w.r.t. endogenous variables */
@ -343,11 +344,11 @@ protected:
// Helper for writing bytecode (without block decomposition)
template<bool dynamic>
void writeBytecodeHelper(BytecodeWriter& code_file) const;
void writeBytecodeHelper(Bytecode::Writer& code_file) const;
// Helper for writing blocks in bytecode
template<bool dynamic>
void writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
void writeBlockBytecodeHelper(Bytecode::Writer& code_file, int block,
temporary_terms_t& temporary_terms_union) const;
// Helper for writing sparse derivatives indices in MATLAB/Octave driver file
@ -387,7 +388,7 @@ protected:
//! Writes model equations in bytecode
template<ExprNodeBytecodeOutputType output_type>
void writeBytecodeModelEquations(BytecodeWriter& code_file,
void writeBytecodeModelEquations(Bytecode::Writer& code_file,
const temporary_terms_t& temporary_terms,
const deriv_node_temp_terms_t& tef_terms) const;
@ -650,9 +651,9 @@ public:
//! Absolute value under which a number is considered to be zero
double cutoff {1e-15};
//! Declare a node as an equation of the model; also give its line number
void addEquation(expr_t eq, optional<int> lineno);
void addEquation(expr_t eq, const optional<int>& lineno);
//! Declare a node as an equation of the model, also giving its tags
void addEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags);
void addEquation(expr_t eq, const optional<int>& lineno, map<string, string> eq_tags);
//! Declare a node as an auxiliary equation of the model, adding it at the end of the list of
//! auxiliary equations
void addAuxEquation(expr_t eq);
@ -1518,7 +1519,7 @@ template<ExprNodeBytecodeOutputType output_type>
void
ModelTree::writeBytecodeTemporaryTerms(const temporary_terms_t& tt,
temporary_terms_t& temporary_terms_union,
BytecodeWriter& code_file,
Bytecode::Writer& code_file,
deriv_node_temp_terms_t& tef_terms) const
{
for (auto it : tt)
@ -1528,16 +1529,16 @@ ModelTree::writeBytecodeTemporaryTerms(const temporary_terms_t& tt,
temporary_terms_idxs, tef_terms);
int idx {temporary_terms_idxs.at(it)};
code_file << FNUMEXPR_ {ExpressionType::TemporaryTerm, idx};
code_file << Bytecode::FNUMEXPR {Bytecode::ExpressionType::TemporaryTerm, idx};
it->writeBytecodeOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs,
tef_terms);
static_assert(output_type == ExprNodeBytecodeOutputType::dynamicModel
|| output_type == ExprNodeBytecodeOutputType::staticModel);
if constexpr (output_type == ExprNodeBytecodeOutputType::dynamicModel)
code_file << FSTPT_ {idx};
code_file << Bytecode::FSTPT {idx};
else
code_file << FSTPST_ {idx};
code_file << Bytecode::FSTPST {idx};
temporary_terms_union.insert(it);
}
@ -1545,7 +1546,7 @@ ModelTree::writeBytecodeTemporaryTerms(const temporary_terms_t& tt,
template<ExprNodeBytecodeOutputType output_type>
void
ModelTree::writeBytecodeModelEquations(BytecodeWriter& code_file,
ModelTree::writeBytecodeModelEquations(Bytecode::Writer& code_file,
const temporary_terms_t& temporary_terms,
const deriv_node_temp_terms_t& tef_terms) const
{
@ -1553,7 +1554,7 @@ ModelTree::writeBytecodeModelEquations(BytecodeWriter& code_file,
{
BinaryOpNode* eq_node {equations[eq]};
expr_t lhs {eq_node->arg1}, rhs {eq_node->arg2};
code_file << FNUMEXPR_ {ExpressionType::ModelEquation, eq};
code_file << Bytecode::FNUMEXPR {Bytecode::ExpressionType::ModelEquation, eq};
// Test if the right hand side of the equation is empty.
double vrhs {1.0};
try
@ -1571,20 +1572,20 @@ ModelTree::writeBytecodeModelEquations(BytecodeWriter& code_file,
rhs->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs,
tef_terms);
code_file << FBINARY_ {BinaryOpcode::minus} << FSTPR_ {eq};
code_file << Bytecode::FBINARY {BinaryOpcode::minus} << Bytecode::FSTPR {eq};
}
else // The right hand side of the equation is empty ⇒ residual=lhs
{
lhs->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs,
tef_terms);
code_file << FSTPR_ {eq};
code_file << Bytecode::FSTPR {eq};
}
}
}
template<bool dynamic>
void
ModelTree::writeBytecodeHelper(BytecodeWriter& code_file) const
ModelTree::writeBytecodeHelper(Bytecode::Writer& code_file) const
{
constexpr ExprNodeBytecodeOutputType output_type {
dynamic ? ExprNodeBytecodeOutputType::dynamicModel : ExprNodeBytecodeOutputType::staticModel};
@ -1596,7 +1597,7 @@ ModelTree::writeBytecodeHelper(BytecodeWriter& code_file) const
code_file, tef_terms);
writeBytecodeModelEquations<output_type>(code_file, temporary_terms_union, tef_terms);
code_file << FENDEQU_ {};
code_file << Bytecode::FENDEQU {};
// Temporary terms for the Jacobian
writeBytecodeTemporaryTerms<output_type>(temporary_terms_derivatives[1], temporary_terms_union,
@ -1604,7 +1605,7 @@ ModelTree::writeBytecodeHelper(BytecodeWriter& code_file) const
// Get the current code_file position and jump if “evaluate” mode
int pos_jmpifeval {code_file.getInstructionCounter()};
code_file << FJMPIFEVAL_ {0}; // Use 0 as jump offset for the time being
code_file << Bytecode::FJMPIFEVAL {0}; // Use 0 as jump offset for the time being
// The Jacobian in “simulate” mode
vector<vector<tuple<int, int, int>>> my_derivatives(symbol_table.endo_nbr());
@ -1618,49 +1619,53 @@ ModelTree::writeBytecodeHelper(BytecodeWriter& code_file) const
int tsid {getTypeSpecificIDByDerivID(deriv_id)};
int lag {getLagByDerivID(deriv_id)};
if constexpr (dynamic)
code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eq, tsid, lag};
code_file << Bytecode::FNUMEXPR {Bytecode::ExpressionType::FirstEndoDerivative, eq,
tsid, lag};
else
code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eq, tsid};
code_file << Bytecode::FNUMEXPR {Bytecode::ExpressionType::FirstEndoDerivative, eq,
tsid};
if (!my_derivatives[eq].size())
my_derivatives[eq].clear();
my_derivatives[eq].emplace_back(tsid, lag, count_u);
d1->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
temporary_terms_idxs, tef_terms);
if constexpr (dynamic)
code_file << FSTPU_ {count_u};
code_file << Bytecode::FSTPU {count_u};
else
code_file << FSTPSU_ {count_u};
code_file << Bytecode::FSTPSU {count_u};
count_u++;
}
}
for (int i {0}; i < symbol_table.endo_nbr(); i++)
{
code_file << FLDR_ {i};
code_file << Bytecode::FLDR {i};
if (my_derivatives[i].size())
{
for (bool first_term {true}; const auto& [tsid, lag, uidx] : my_derivatives[i])
{
if constexpr (dynamic)
code_file << FLDU_ {uidx} << FLDV_ {SymbolType::endogenous, tsid, lag};
code_file << Bytecode::FLDU {uidx}
<< Bytecode::FLDV {SymbolType::endogenous, tsid, lag};
else
code_file << FLDSU_ {uidx} << FLDSV_ {SymbolType::endogenous, tsid};
code_file << FBINARY_ {BinaryOpcode::times};
code_file << Bytecode::FLDSU {uidx}
<< Bytecode::FLDSV {SymbolType::endogenous, tsid};
code_file << Bytecode::FBINARY {BinaryOpcode::times};
if (!exchange(first_term, false))
code_file << FBINARY_ {BinaryOpcode::plus};
code_file << Bytecode::FBINARY {BinaryOpcode::plus};
}
code_file << FBINARY_ {BinaryOpcode::minus};
code_file << Bytecode::FBINARY {BinaryOpcode::minus};
}
if constexpr (dynamic)
code_file << FSTPU_ {i};
code_file << Bytecode::FSTPU {i};
else
code_file << FSTPSU_ {i};
code_file << Bytecode::FSTPSU {i};
}
// Jump unconditionally after the block
int pos_jmp {code_file.getInstructionCounter()};
code_file << FJMP_ {0}; // Use 0 as jump offset for the time being
code_file << Bytecode::FJMP {0}; // Use 0 as jump offset for the time being
// Update jump offset for previous JMPIFEVAL
code_file.overwriteInstruction(pos_jmpifeval, FJMPIFEVAL_ {pos_jmp - pos_jmpifeval});
code_file.overwriteInstruction(pos_jmpifeval, Bytecode::FJMPIFEVAL {pos_jmp - pos_jmpifeval});
// The Jacobian in “evaluate” mode
for (const auto& [indices, d1] : derivatives[1])
@ -1672,28 +1677,28 @@ ModelTree::writeBytecodeHelper(BytecodeWriter& code_file) const
if constexpr (dynamic)
{
ExpressionType expr_type;
Bytecode::ExpressionType expr_type;
switch (type)
{
case SymbolType::endogenous:
expr_type = ExpressionType::FirstEndoDerivative;
expr_type = Bytecode::ExpressionType::FirstEndoDerivative;
break;
case SymbolType::exogenous:
expr_type = ExpressionType::FirstExoDerivative;
expr_type = Bytecode::ExpressionType::FirstExoDerivative;
break;
case SymbolType::exogenousDet:
expr_type = ExpressionType::FirstExodetDerivative;
expr_type = Bytecode::ExpressionType::FirstExodetDerivative;
break;
default:
assert(false);
break;
}
code_file << FNUMEXPR_ {expr_type, eq, tsid, lag};
code_file << Bytecode::FNUMEXPR {expr_type, eq, tsid, lag};
}
else
{
assert(type == SymbolType::endogenous);
code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eq, tsid};
code_file << Bytecode::FNUMEXPR {Bytecode::ExpressionType::FirstEndoDerivative, eq, tsid};
}
d1->writeBytecodeOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs,
@ -1702,22 +1707,22 @@ ModelTree::writeBytecodeHelper(BytecodeWriter& code_file) const
{
// Bytecode MEX uses a separate matrix for exogenous and exodet Jacobians
int jacob_col {type == SymbolType::endogenous ? getJacobianCol(deriv_id, false) : tsid};
code_file << FSTPG3_ {eq, tsid, lag, jacob_col};
code_file << Bytecode::FSTPG3 {eq, tsid, lag, jacob_col};
}
else
code_file << FSTPG2_ {eq, tsid};
code_file << Bytecode::FSTPG2 {eq, tsid};
}
// Update jump offset for previous JMP
int pos_end_block {code_file.getInstructionCounter()};
code_file.overwriteInstruction(pos_jmp, FJMP_ {pos_end_block - pos_jmp - 1});
code_file.overwriteInstruction(pos_jmp, Bytecode::FJMP {pos_end_block - pos_jmp - 1});
code_file << FENDBLOCK_ {} << FEND_ {};
code_file << Bytecode::FENDBLOCK {} << Bytecode::FEND {};
}
template<bool dynamic>
void
ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
ModelTree::writeBlockBytecodeHelper(Bytecode::Writer& code_file, int block,
temporary_terms_t& temporary_terms_union) const
{
constexpr ExprNodeBytecodeOutputType output_type {
@ -1740,13 +1745,14 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
it->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms);
code_file << FNUMEXPR_ {ExpressionType::TemporaryTerm, blocks_temporary_terms_idxs.at(it)};
code_file << Bytecode::FNUMEXPR {Bytecode::ExpressionType::TemporaryTerm,
blocks_temporary_terms_idxs.at(it)};
it->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms);
if constexpr (dynamic)
code_file << FSTPT_ {blocks_temporary_terms_idxs.at(it)};
code_file << Bytecode::FSTPT {blocks_temporary_terms_idxs.at(it)};
else
code_file << FSTPST_ {blocks_temporary_terms_idxs.at(it)};
code_file << Bytecode::FSTPST {blocks_temporary_terms_idxs.at(it)};
temporary_terms_union.insert(it);
}
};
@ -1772,7 +1778,8 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
}
else
assert(equ_type == EquationType::evaluate);
code_file << FNUMEXPR_ {ExpressionType::ModelEquation, getBlockEquationID(block, i)};
code_file << Bytecode::FNUMEXPR {Bytecode::ExpressionType::ModelEquation,
getBlockEquationID(block, i)};
rhs->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms);
lhs->writeBytecodeOutput(code_file, assignment_lhs_output_type, temporary_terms_union,
@ -1787,12 +1794,14 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
[[fallthrough]];
case BlockSimulationType::solveBackwardSimple:
case BlockSimulationType::solveForwardSimple:
code_file << FNUMEXPR_ {ExpressionType::ModelEquation, getBlockEquationID(block, i)};
code_file << Bytecode::FNUMEXPR {Bytecode::ExpressionType::ModelEquation,
getBlockEquationID(block, i)};
lhs->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms);
rhs->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms);
code_file << FBINARY_ {BinaryOpcode::minus} << FSTPR_ {i - block_recursive};
code_file << Bytecode::FBINARY {BinaryOpcode::minus}
<< Bytecode::FSTPR {i - block_recursive};
break;
}
}
@ -1807,11 +1816,11 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
be needed in subsequent blocks. */
write_eq_tt(blocks[block].size);
code_file << FENDEQU_ {};
code_file << Bytecode::FENDEQU {};
// Get the current code_file position and jump if evaluating
int pos_jmpifeval {code_file.getInstructionCounter()};
code_file << FJMPIFEVAL_ {0}; // Use 0 as jump offset for the time being
code_file << Bytecode::FJMPIFEVAL {0}; // Use 0 as jump offset for the time being
/* Write the derivatives for the “simulate” mode (not needed if the block
is of type evaluate backward/forward) */
@ -1825,15 +1834,16 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
{
int eqr {getBlockEquationID(block, 0)};
int varr {getBlockVariableID(block, 0)};
code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eqr, varr, 0};
code_file << Bytecode::FNUMEXPR {Bytecode::ExpressionType::FirstEndoDerivative, eqr,
varr, 0};
// Get contemporaneous derivative of the single variable in the block
if (auto it {blocks_derivatives[block].find({0, 0, 0})};
it != blocks_derivatives[block].end())
it->second->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms);
else
code_file << FLDZ_ {};
code_file << FSTPG_ {0};
code_file << Bytecode::FLDZ {};
code_file << Bytecode::FSTPG {0};
}
break;
@ -1858,13 +1868,14 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
&& (simulation_type == BlockSimulationType::solveForwardComplete
|| simulation_type == BlockSimulationType::solveBackwardComplete))
continue;
code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eqr, varr, lag};
code_file << Bytecode::FNUMEXPR {Bytecode::ExpressionType::FirstEndoDerivative,
eqr, varr, lag};
d1->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms);
if constexpr (dynamic)
code_file << FSTPU_ {count_u};
code_file << Bytecode::FSTPU {count_u};
else
code_file << FSTPSU_ {count_u};
code_file << Bytecode::FSTPSU {count_u};
Uf[eqr].emplace_back(count_u, varr, lag);
count_u++;
}
@ -1872,22 +1883,25 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
for (int i {0}; i < block_size; i++)
if (i >= block_recursive)
{
code_file << FLDR_ {i - block_recursive} << FLDZ_ {};
code_file << Bytecode::FLDR {i - block_recursive} << Bytecode::FLDZ {};
int eqr {getBlockEquationID(block, i)};
for (const auto& [index_u, var, lag] : Uf[eqr])
{
if constexpr (dynamic)
code_file << FLDU_ {index_u} << FLDV_ {SymbolType::endogenous, var, lag};
code_file << Bytecode::FLDU {index_u}
<< Bytecode::FLDV {SymbolType::endogenous, var, lag};
else
code_file << FLDSU_ {index_u} << FLDSV_ {SymbolType::endogenous, var};
code_file << FBINARY_ {BinaryOpcode::times} << FBINARY_ {BinaryOpcode::plus};
code_file << Bytecode::FLDSU {index_u}
<< Bytecode::FLDSV {SymbolType::endogenous, var};
code_file << Bytecode::FBINARY {BinaryOpcode::times}
<< Bytecode::FBINARY {BinaryOpcode::plus};
}
code_file << FBINARY_ {BinaryOpcode::minus};
code_file << Bytecode::FBINARY {BinaryOpcode::minus};
if constexpr (dynamic)
code_file << FSTPU_ {i - block_recursive};
code_file << Bytecode::FSTPU {i - block_recursive};
else
code_file << FSTPSU_ {i - block_recursive};
code_file << Bytecode::FSTPSU {i - block_recursive};
}
}
break;
@ -1898,9 +1912,9 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
// Jump unconditionally after the block
int pos_jmp {code_file.getInstructionCounter()};
code_file << FJMP_ {0}; // Use 0 as jump offset for the time being
code_file << Bytecode::FJMP {0}; // Use 0 as jump offset for the time being
// Update jump offset for previous JMPIFEVAL
code_file.overwriteInstruction(pos_jmpifeval, FJMPIFEVAL_ {pos_jmp - pos_jmpifeval});
code_file.overwriteInstruction(pos_jmpifeval, Bytecode::FJMPIFEVAL {pos_jmp - pos_jmpifeval});
// Write the derivatives for the “evaluate” mode
for (const auto& [indices, d] : blocks_derivatives[block])
@ -1908,22 +1922,24 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block,
const auto& [eq, var, lag] {indices};
int eqr {getBlockEquationID(block, eq)};
int varr {getBlockVariableID(block, var)};
code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eqr, varr, lag};
code_file << Bytecode::FNUMEXPR {Bytecode::ExpressionType::FirstEndoDerivative, eqr, varr,
lag};
d->writeBytecodeOutput(code_file, output_type, temporary_terms_union,
blocks_temporary_terms_idxs, tef_terms);
assert(eq >= block_recursive);
if constexpr (dynamic)
code_file << FSTPG3_ {eq - block_recursive, var, lag,
getBlockJacobianEndoCol(block, var, lag)};
code_file << Bytecode::FSTPG3 {eq - block_recursive, var, lag,
getBlockJacobianEndoCol(block, var, lag)};
else
code_file << FSTPG2_ {eq - block_recursive, getBlockJacobianEndoCol(block, var, lag)};
code_file << Bytecode::FSTPG2 {eq - block_recursive,
getBlockJacobianEndoCol(block, var, lag)};
}
// Update jump offset for previous JMP
int pos_end_block {code_file.getInstructionCounter()};
code_file.overwriteInstruction(pos_jmp, FJMP_ {pos_end_block - pos_jmp - 1});
code_file.overwriteInstruction(pos_jmp, Bytecode::FJMP {pos_end_block - pos_jmp - 1});
code_file << FENDBLOCK_ {};
code_file << Bytecode::FENDBLOCK {};
}
template<bool dynamic>

View File

@ -341,7 +341,7 @@ ParsingDriver::add_inf_constant()
expr_t
ParsingDriver::add_model_variable(const string& name)
{
if (name.find(".") != string::npos)
if (name.find('.') != string::npos)
error(name + " treated as a variable, but it contains a '.'");
check_symbol_existence_in_model_block(name);
@ -456,7 +456,7 @@ ParsingDriver::add_model_variable(int symb_id, int lag)
expr_t
ParsingDriver::add_expression_variable(const string& name)
{
if (name.find(".") != string::npos)
if (name.find('.') != string::npos)
error(name + " treated as a variable, but it contains a '.'");
if (parsing_epilogue && !mod_file->symbol_table.exists(name))
@ -2024,9 +2024,9 @@ ParsingDriver::run_estimation(vector<string> symbol_list)
}
void
ParsingDriver::dynare_sensitivity()
ParsingDriver::sensitivity()
{
mod_file->addStatement(make_unique<DynareSensitivityStatement>(move(options_list)));
mod_file->addStatement(make_unique<SensitivityStatement>(move(options_list)));
options_list.clear();
}
@ -2127,7 +2127,7 @@ ParsingDriver::set_optim_weights(string name, expr_t value)
check_symbol_is_endogenous(name);
if (var_weights.contains(name))
error("optim_weights: " + name + " declared twice");
var_weights[move(name)] = move(value);
var_weights[move(name)] = value;
}
void
@ -2594,8 +2594,8 @@ ParsingDriver::plot_conditional_forecast(const optional<string>& periods,
optional<int> iperiods;
if (periods)
iperiods = stoi(*periods);
mod_file->addStatement(make_unique<PlotConditionalForecastStatement>(
move(iperiods), move(symbol_list), mod_file->symbol_table));
mod_file->addStatement(make_unique<PlotConditionalForecastStatement>(iperiods, move(symbol_list),
mod_file->symbol_table));
}
void
@ -3875,3 +3875,16 @@ ParsingDriver::resid()
mod_file->addStatement(make_unique<ResidStatement>(move(options_list)));
options_list.clear();
}
void
ParsingDriver::matched_irfs(MatchedIrfsStatement::matched_irfs_t values_weights, bool overwrite)
{
mod_file->addStatement(make_unique<MatchedIrfsStatement>(move(values_weights), overwrite));
}
void
ParsingDriver::matched_irfs_weights(MatchedIrfsWeightsStatement::matched_irfs_weights_t weights,
bool overwrite)
{
mod_file->addStatement(make_unique<MatchedIrfsWeightsStatement>(move(weights), overwrite));
}

View File

@ -98,6 +98,7 @@ private:
//! message if it isn't
void check_symbol_is_endogenous_or_exogenous(const string& name, bool allow_exo_det);
public:
//! Checks that a given symbol exists and is a endogenous, and stops with an error message if it
//! isn't
void check_symbol_is_endogenous(const string& name);
@ -106,6 +107,7 @@ private:
//! isn't
void check_symbol_is_exogenous(const string& name, bool allow_exo_det);
private:
//! Checks for symbol existence in model block. If it doesn't exist, an error message is stored to
//! be printed at the end of the model block
void check_symbol_existence_in_model_block(const string& name);
@ -592,8 +594,8 @@ public:
void set_corr_options(string name1, string name2, string subsample_name);
//! Runs estimation process
void run_estimation(vector<string> symbol_list);
//! Runs dynare_sensitivy()
void dynare_sensitivity();
//! Runs sensitivity
void sensitivity();
//! Check that no observed variable has yet be defined
void check_varobs();
//! Add a new observed variable
@ -954,6 +956,11 @@ public:
void set_pac_target_info_component_kind(PacTargetKind kind);
// Add a resid statement
void resid();
// Add a matched_irfs block
void matched_irfs(MatchedIrfsStatement::matched_irfs_t values_weights, bool overwrite);
// Add a matched_irfs_weights block
void matched_irfs_weights(MatchedIrfsWeightsStatement::matched_irfs_weights_t weights,
bool overwrite);
// Returns true iff the string is a legal symbol identifier (see NAME token in lexer)
static bool isSymbolIdentifier(const string& str);
// Given an Occbin regime name, returns the corresponding auxiliary parameter

View File

@ -1,5 +1,5 @@
/*
* Copyright © 2006-2022 Dynare Team
* Copyright © 2006-2023 Dynare Team
*
* This file is part of Dynare.
*
@ -168,7 +168,7 @@ void
OptionsList::writeOutput(ostream& output, const string& option_group) const
{
// Initialize option_group as an empty struct iff the field does not exist!
if (size_t idx = option_group.find_last_of("."); idx != string::npos)
if (size_t idx = option_group.find_last_of('.'); idx != string::npos)
{
output << "if ~isfield(" << option_group.substr(0, idx) << ",'"
<< option_group.substr(idx + 1) << "')" << endl;

View File

@ -131,24 +131,24 @@ StaticModel::writeStaticBytecode(const string& basename) const
// First write the .bin file
int u_count_int {writeBytecodeBinFile(basename + "/model/bytecode/static.bin", false)};
BytecodeWriter code_file {basename + "/model/bytecode/static.cod"};
Bytecode::Writer code_file {basename + "/model/bytecode/static.cod"};
vector<int> eq_idx(equations.size());
iota(eq_idx.begin(), eq_idx.end(), 0);
vector<int> endo_idx(symbol_table.endo_nbr());
iota(endo_idx.begin(), endo_idx.end(), 0);
// Declare temporary terms and the (single) block
code_file << FDIMST_ {static_cast<int>(temporary_terms_derivatives[0].size()
+ temporary_terms_derivatives[1].size())}
<< FBEGINBLOCK_ {symbol_table.endo_nbr(),
BlockSimulationType::solveForwardComplete,
0,
symbol_table.endo_nbr(),
endo_idx,
eq_idx,
false,
u_count_int,
symbol_table.endo_nbr()};
code_file << Bytecode::FDIMST {static_cast<int>(temporary_terms_derivatives[0].size()
+ temporary_terms_derivatives[1].size())}
<< Bytecode::FBEGINBLOCK {symbol_table.endo_nbr(),
BlockSimulationType::solveForwardComplete,
0,
symbol_table.endo_nbr(),
endo_idx,
eq_idx,
false,
u_count_int,
symbol_table.endo_nbr()};
writeBytecodeHelper<false>(code_file);
}
@ -156,7 +156,7 @@ StaticModel::writeStaticBytecode(const string& basename) const
void
StaticModel::writeStaticBlockBytecode(const string& basename) const
{
BytecodeWriter code_file {basename + "/model/bytecode/block/static.cod"};
Bytecode::Writer code_file {basename + "/model/bytecode/block/static.cod"};
const filesystem::path bin_filename {basename + "/model/bytecode/block/static.bin"};
ofstream bin_file {bin_filename, ios::out | ios::binary};
@ -167,7 +167,7 @@ StaticModel::writeStaticBlockBytecode(const string& basename) const
}
// Temporary variables declaration
code_file << FDIMST_ {static_cast<int>(blocks_temporary_terms_idxs.size())};
code_file << Bytecode::FDIMST {static_cast<int>(blocks_temporary_terms_idxs.size())};
temporary_terms_t temporary_terms_written;
@ -181,19 +181,19 @@ StaticModel::writeStaticBlockBytecode(const string& basename) const
? writeBlockBytecodeBinFile(bin_file, block)
: 0};
code_file << FBEGINBLOCK_ {blocks[block].mfs_size,
simulation_type,
blocks[block].first_equation,
block_size,
endo_idx_block2orig,
eq_idx_block2orig,
blocks[block].linear,
u_count,
block_size};
code_file << Bytecode::FBEGINBLOCK {blocks[block].mfs_size,
simulation_type,
blocks[block].first_equation,
block_size,
endo_idx_block2orig,
eq_idx_block2orig,
blocks[block].linear,
u_count,
block_size};
writeBlockBytecodeHelper<false>(code_file, block, temporary_terms_written);
}
code_file << FEND_ {};
code_file << Bytecode::FEND {};
}
void
@ -854,6 +854,7 @@ StaticModel::computeRamseyMultipliersDerivatives(int ramsey_orig_endo_nbr, bool
// Compute derivation IDs of Lagrange multipliers
set<int> mult_symb_ids {symbol_table.getLagrangeMultipliers()};
vector<int> mult_deriv_ids;
mult_deriv_ids.reserve(mult_symb_ids.size());
for (int symb_id : mult_symb_ids)
mult_deriv_ids.push_back(getDerivID(symb_id, 0));

View File

@ -315,13 +315,13 @@ TrendComponentModelTable::writeOutput(const string& basename, ostream& output) c
vector<string> target_eqtags_vec = target_eqtags.at(name);
output << "M_.trend_component." << name << ".target_eqtags = {";
for (auto it : target_eqtags_vec)
for (const auto& it : target_eqtags_vec)
output << "'" << it << "';";
output << "};" << endl;
vector<string> eqtags_vec = eqtags.at(name);
output << "M_.trend_component." << name << ".target_eqn = [";
for (auto it : target_eqtags_vec)
for (const auto& it : target_eqtags_vec)
output << distance(eqtags_vec.begin(), find(eqtags_vec.begin(), eqtags_vec.end(), it)) + 1
<< " ";
output << "];" << endl;
@ -595,7 +595,7 @@ void
VarModelTable::setLhs(map<string, vector<int>> lhs_arg)
{
lhs = move(lhs_arg);
for (auto it : lhs)
for (const auto& it : lhs)
{
vector<int> lhsvec;
for (auto ids : it.second)

View File

@ -585,8 +585,8 @@ SymbolTable::addDiffLeadAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_i
}
int
SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg, optional<int> orig_symb_id,
optional<int> orig_lag) noexcept(false)
SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg, const optional<int>& orig_symb_id,
const optional<int>& orig_lag) noexcept(false)
{
string varname {"AUX_DIFF_" + to_string(index)};
int symb_id;
@ -601,16 +601,15 @@ SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg, optional<int> orig_
exit(EXIT_FAILURE);
}
aux_vars.emplace_back(symb_id, AuxVarType::diff, move(orig_symb_id), move(orig_lag), 0, 0,
expr_arg, "");
aux_vars.emplace_back(symb_id, AuxVarType::diff, orig_symb_id, orig_lag, 0, 0, expr_arg, "");
return symb_id;
}
int
SymbolTable::addUnaryOpAuxiliaryVar(int index, expr_t expr_arg, string unary_op,
optional<int> orig_symb_id,
optional<int> orig_lag) noexcept(false)
const optional<int>& orig_symb_id,
const optional<int>& orig_lag) noexcept(false)
{
string varname {"AUX_UOP_" + to_string(index)};
int symb_id;
@ -625,8 +624,8 @@ SymbolTable::addUnaryOpAuxiliaryVar(int index, expr_t expr_arg, string unary_op,
exit(EXIT_FAILURE);
}
aux_vars.emplace_back(symb_id, AuxVarType::unaryOp, move(orig_symb_id), move(orig_lag), 0, 0,
expr_arg, unary_op);
aux_vars.emplace_back(symb_id, AuxVarType::unaryOp, orig_symb_id, orig_lag, 0, 0, expr_arg,
move(unary_op));
return symb_id;
}

View File

@ -33,8 +33,6 @@
using namespace std;
using expr_t = class ExprNode*;
//! Types of auxiliary variables
enum class AuxVarType
{
@ -299,8 +297,8 @@ public:
diffLead increases it). */
[[nodiscard]] pair<int, int> unrollDiffLeadLagChain(int symb_id, int lag) const noexcept(false);
//! Adds an auxiliary variable when the diff operator is encountered
int addDiffAuxiliaryVar(int index, expr_t expr_arg, optional<int> orig_symb_id = nullopt,
optional<int> orig_lag = nullopt) noexcept(false);
int addDiffAuxiliaryVar(int index, expr_t expr_arg, const optional<int>& orig_symb_id = nullopt,
const optional<int>& orig_lag = nullopt) noexcept(false);
//! Takes care of timing between diff statements
int addDiffLagAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id,
int orig_lag) noexcept(false);
@ -309,8 +307,8 @@ public:
int orig_lead) noexcept(false);
//! An Auxiliary variable for a unary op
int addUnaryOpAuxiliaryVar(int index, expr_t expr_arg, string unary_op,
optional<int> orig_symb_id = nullopt,
optional<int> orig_lag = nullopt) noexcept(false);
const optional<int>& orig_symb_id = nullopt,
const optional<int>& orig_lag = nullopt) noexcept(false);
//! An auxiliary variable for a pac_expectation operator
int addPacExpectationAuxiliaryVar(const string& name, expr_t expr_arg);
//! An auxiliary variable for a pac_target_nonstationary operator

View File

@ -75,10 +75,10 @@ Include::interpret(ostream& output, Environment& env, vector<filesystem::path>&
}
}
Driver m;
/* Calling `string()` method on filename and filename.stem() because of
bug in GCC/MinGW 10.2 (shipped in Debian Bullseye 11), that fails
to accept implicit conversion to string from filename::path. See
https://en.cppreference.com/w/cpp/filesystem/path/native. */
/* Calling string() method on filename: not necessary on GNU/Linux and macOS because there is
an implicit conversion from from filesystem:path to string (i.e. basic_string<char>), but
needed on Windows because the implicit conversion is only to wstring (i.e.
basic_string<wchar_t>). */
m.parse(filename.string(), incfile, false, {}, env, paths, output);
}
catch (StackTrace& ex)
@ -103,20 +103,7 @@ IncludePath::interpret([[maybe_unused]] ostream& output, Environment& env,
StringPtr msp = dynamic_pointer_cast<String>(expr->eval(env));
if (!msp)
throw StackTrace("File name does not evaluate to a string");
#ifdef _WIN32
/* Trim trailing slashes and backslashes in the path. This is a
workaround for a GCC/MinGW bug present in version 10.2
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88881, that affects
gcc-mingw-w64 in Debian Bullseye 11. It is fixed in GCC 10.3, and
thus should be fixed in Debian Bookworm 12.
See Madysson/estimation-codes#11. */
string ipstr = static_cast<string>(*msp);
while (ipstr.size() > 1 && (ipstr.back() == '/' || ipstr.back() == '\\'))
ipstr.pop_back();
path ip {ipstr};
#else
path ip = static_cast<string>(*msp);
#endif
if (!is_directory(ip))
throw StackTrace(ip.string() + " does not evaluate to a valid directory");
if (!exists(ip))

View File

@ -1,5 +1,5 @@
/*
* Copyright © 2019-2022 Dynare Team
* Copyright © 2019-2023 Dynare Team
*
* This file is part of Dynare.
*
@ -25,7 +25,7 @@
using namespace macro;
void
Environment::define(VariablePtr var, ExpressionPtr value)
Environment::define(const VariablePtr& var, const ExpressionPtr& value)
{
string name = var->getName();
if (functions.contains(name))

View File

@ -40,7 +40,7 @@ public:
Environment(const Environment* parent_arg) : parent {parent_arg}
{
}
void define(VariablePtr var, ExpressionPtr value);
void define(const VariablePtr& var, const ExpressionPtr& value);
void define(FunctionPtr func, ExpressionPtr value);
/* The following two functions are not marked [[nodiscard]], because they are used without output
to check whether they return an exception or not. */

View File

@ -640,6 +640,7 @@ BaseTypePtr
Array::eval(Environment& env) const
{
vector<ExpressionPtr> retval;
retval.reserve(arr.size());
for (const auto& it : arr)
retval.emplace_back(it->eval(env));
return make_shared<Array>(retval);
@ -649,6 +650,7 @@ BaseTypePtr
Tuple::eval(Environment& env) const
{
vector<ExpressionPtr> retval;
retval.reserve(tup.size());
for (const auto& it : tup)
retval.emplace_back(it->eval(env));
return make_shared<Tuple>(retval);
@ -1282,7 +1284,7 @@ void
Array::print(ostream& output, bool matlab_output) const noexcept
{
output << (matlab_output ? "{" : "[");
for (bool printed_something {false}; auto e : arr)
for (bool printed_something {false}; const auto& e : arr)
{
if (exchange(printed_something, true))
output << ", ";
@ -1295,7 +1297,7 @@ void
Tuple::print(ostream& output, bool matlab_output) const noexcept
{
output << (matlab_output ? "{" : "(");
for (bool printed_something {false}; auto e : tup)
for (bool printed_something {false}; const auto& e : tup)
{
if (exchange(printed_something, true))
output << ", ";
@ -1308,7 +1310,7 @@ void
Function::printArgs(ostream& output) const noexcept
{
output << "(";
for (bool printed_something {false}; auto e : args)
for (bool printed_something {false}; const auto& e : args)
{
if (exchange(printed_something, true))
output << ", ";

View File

@ -1135,7 +1135,7 @@ private:
public:
UnaryOp(codes::UnaryOp op_code_arg, ExpressionPtr arg_arg, Tokenizer::location location_arg) :
Expression(move(location_arg)), op_code {move(op_code_arg)}, arg {move(arg_arg)}
Expression(move(location_arg)), op_code {op_code_arg}, arg {move(arg_arg)}
{
}
[[nodiscard]] string to_string() const noexcept override;

View File

@ -42,7 +42,7 @@ preprocessor_src = [ 'ComputingTasks.cc',
'ParsingDriver.cc',
'DataTree.cc',
'ModFile.cc',
'ConfigFile.cc',
'Configuration.cc',
'Statement.cc',
'ExprNode.cc',
'VariableDependencyGraph.cc',