From d463607e9071016a13d6265db9b4fe987987de48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Thu, 30 Nov 2023 15:28:57 +0100 Subject: [PATCH] Reformat C++ source code using clang-format 15 --- src/Bytecode.cc | 30 +- src/Bytecode.hh | 500 ++-- src/CommonEnums.hh | 211 +- src/ComputingTasks.cc | 2289 +++++++-------- src/ComputingTasks.hh | 911 +++--- src/ConfigFile.cc | 569 ++-- src/ConfigFile.hh | 40 +- src/DataTree.cc | 193 +- src/DataTree.hh | 153 +- src/DynamicModel.cc | 1651 ++++++----- src/DynamicModel.hh | 564 ++-- src/DynareMain.cc | 107 +- src/EquationTags.cc | 70 +- src/EquationTags.hh | 29 +- src/ExprNode.cc | 3268 ++++++++++++---------- src/ExprNode.hh | 1669 ++++++----- src/ExtendedPreprocessorTypes.hh | 40 +- src/ExternalFunctionsTable.cc | 39 +- src/ExternalFunctionsTable.hh | 25 +- src/MacroExpandModFile.cc | 15 +- src/ModFile.cc | 587 ++-- src/ModFile.hh | 87 +- src/ModelEquationBlock.cc | 225 +- src/ModelEquationBlock.hh | 85 +- src/ModelTree.cc | 760 ++--- src/ModelTree.hh | 1756 ++++++------ src/NumericalConstants.cc | 7 +- src/NumericalConstants.hh | 5 +- src/NumericalInitialization.cc | 265 +- src/NumericalInitialization.hh | 131 +- src/ParsingDriver.cc | 1046 +++---- src/ParsingDriver.hh | 386 +-- src/Shocks.cc | 454 ++- src/Shocks.hh | 171 +- src/Statement.cc | 315 ++- src/Statement.hh | 174 +- src/StaticModel.cc | 507 ++-- src/StaticModel.hh | 287 +- src/SubModel.cc | 848 +++--- src/SubModel.hh | 198 +- src/SymbolList.cc | 43 +- src/SymbolList.hh | 18 +- src/SymbolTable.cc | 471 ++-- src/SymbolTable.hh | 176 +- src/VariableDependencyGraph.cc | 37 +- src/VariableDependencyGraph.hh | 35 +- src/WarningConsolidation.cc | 22 +- src/WarningConsolidation.hh | 18 +- src/macro/Directives.cc | 88 +- src/macro/Directives.hh | 331 ++- src/macro/Driver.cc | 13 +- src/macro/Driver.hh | 151 +- src/macro/Environment.cc | 38 +- src/macro/Environment.hh | 75 +- src/macro/Expressions.cc | 323 +-- src/macro/Expressions.hh | 1739 ++++++++---- src/macro/ForwardDeclarationsAndEnums.hh | 220 +- 57 files changed, 13381 insertions(+), 11084 deletions(-) diff --git a/src/Bytecode.cc b/src/Bytecode.cc index 8de86ff5..d4b83823 100644 --- a/src/Bytecode.cc +++ b/src/Bytecode.cc @@ -17,14 +17,14 @@ * along with Dynare. If not, see . */ -#include -#include -#include #include +#include +#include +#include #include "Bytecode.hh" -BytecodeWriter::BytecodeWriter(const filesystem::path &filename) +BytecodeWriter::BytecodeWriter(const filesystem::path& filename) { open(filename, ios::out | ios::binary); if (!is_open()) @@ -35,14 +35,13 @@ BytecodeWriter::BytecodeWriter(const filesystem::path &filename) } template<> -BytecodeWriter & -operator<<(BytecodeWriter &code_file, const FCALL_ &instr) +BytecodeWriter& +operator<<(BytecodeWriter& code_file, const FCALL_& instr) { code_file.instructions_positions.push_back(code_file.tellp()); - auto write_member = [&code_file](const auto &member) - { - code_file.write(reinterpret_cast(&member), sizeof member); + auto write_member = [&code_file](const auto& member) { + code_file.write(reinterpret_cast(&member), sizeof member); }; write_member(instr.op_code); @@ -56,24 +55,23 @@ operator<<(BytecodeWriter &code_file, const FCALL_ &instr) int size = static_cast(instr.func_name.size()); write_member(size); - code_file.write(instr.func_name.c_str(), size+1); + code_file.write(instr.func_name.c_str(), size + 1); size = static_cast(instr.arg_func_name.size()); write_member(size); - code_file.write(instr.arg_func_name.c_str(), size+1); + code_file.write(instr.arg_func_name.c_str(), size + 1); return code_file; } template<> -BytecodeWriter & -operator<<(BytecodeWriter &code_file, const FBEGINBLOCK_ &instr) +BytecodeWriter& +operator<<(BytecodeWriter& code_file, const FBEGINBLOCK_& instr) { code_file.instructions_positions.push_back(code_file.tellp()); - auto write_member = [&code_file](const auto &member) - { - code_file.write(reinterpret_cast(&member), sizeof member); + auto write_member = [&code_file](const auto& member) { + code_file.write(reinterpret_cast(&member), sizeof member); }; write_member(instr.op_code); diff --git a/src/Bytecode.hh b/src/Bytecode.hh index dff9cba3..c89b6ece 100644 --- a/src/Bytecode.hh +++ b/src/Bytecode.hh @@ -20,12 +20,12 @@ #ifndef _BYTECODE_HH #define _BYTECODE_HH -#include -#include -#include -#include #include +#include +#include #include +#include +#include #include "CommonEnums.hh" @@ -33,77 +33,91 @@ using namespace std; // The different opcodes of bytecode enum class Tags - { - FLDZ, // Loads a zero onto the stack - FLDC, // Loads a constant term onto the stack +{ + FLDZ, // Loads a zero onto the stack + FLDC, // Loads a constant term onto the stack - FDIMT, // Defines the number of temporary terms - dynamic context (the period has to be indicated) - FDIMST, // Defines the number of temporary terms - static context (the period hasn’t to be indicated) - FLDT, // Loads a temporary term onto the stack - dynamic context (the period has to be indicated) - FLDST, // Loads a temporary term onto the stack - static context (the period hasn’t to be indicated) - FSTPT, // Stores a temporary term from the stack - dynamic context (the period has to be indicated) - FSTPST, // Stores a temporary term from the stack - static context (the period hasn’t to be indicated) + FDIMT, // Defines the number of temporary terms - dynamic context (the period has to be indicated) + FDIMST, // Defines the number of temporary terms - static context (the period hasn’t to be + // indicated) + FLDT, // Loads a temporary term onto the stack - dynamic context (the period has to be indicated) + FLDST, // Loads a temporary term onto the stack - static context (the period hasn’t to be + // indicated) + FSTPT, // Stores a temporary term from the stack - dynamic context (the period has to be + // indicated) + FSTPST, // Stores a temporary term from the stack - static context (the period hasn’t to be + // indicated) - FLDU, // Loads an element of the vector U onto the stack - dynamic context (the period has to be indicated) - FLDSU, // Loads an element of the vector U onto the stack - static context (the period hasn’t to be indicated) - FSTPU, // Stores an element of the vector U from the stack - dynamic context (the period has to be indicated) - FSTPSU, // Stores an element of the vector U from the stack - static context (the period hasn’t to be indicated) + FLDU, // Loads an element of the vector U onto the stack - dynamic context (the period has to be + // indicated) + FLDSU, // Loads an element of the vector U onto the stack - static context (the period hasn’t to + // be indicated) + FSTPU, // Stores an element of the vector U from the stack - dynamic context (the period has to be + // indicated) + FSTPSU, // Stores an element of the vector U from the stack - static context (the period hasn’t to + // be indicated) - FLDV, // Loads a variable (described in SymbolType) onto the stack - dynamic context (the period has to be indicated) - FLDSV, // Loads a variable (described in SymbolType) onto the stack - static context (the period hasn’t to be indicated) - FLDVS, // Loads a variable (described in SymbolType) onto the stack - dynamic context but inside the STEADY_STATE operator (the period hasn’t to be indicated) - FSTPV, // Stores a variable (described in SymbolType) from the stack - dynamic context (the period has to be indicated) - FSTPSV, // Stores a variable (described in SymbolType) from the stack - static context (the period hasn’t to be indicated) + FLDV, // Loads a variable (described in SymbolType) onto the stack - dynamic context (the period + // has to be indicated) + FLDSV, // Loads a variable (described in SymbolType) onto the stack - static context (the period + // hasn’t to be indicated) + FLDVS, // Loads a variable (described in SymbolType) onto the stack - dynamic context but inside + // the STEADY_STATE operator (the period hasn’t to be indicated) + FSTPV, // Stores a variable (described in SymbolType) from the stack - dynamic context (the period + // has to be indicated) + FSTPSV, // Stores a variable (described in SymbolType) from the stack - static context (the period + // hasn’t to be indicated) - FLDR, // Loads a residual onto the stack - FSTPR, // Stores a residual from the stack + FLDR, // Loads a residual onto the stack + FSTPR, // Stores a residual from the stack - FSTPG, // Stores a derivative from the stack - FSTPG2, // Stores a derivative matrix for a static model from the stack - FSTPG3, // Stores a derivative matrix for a dynamic model from the stack + FSTPG, // Stores a derivative from the stack + FSTPG2, // Stores a derivative matrix for a static model from the stack + FSTPG3, // Stores a derivative matrix for a dynamic model from the stack - FUNARY, // A unary operator - FBINARY, // A binary operator - FTRINARY, // A trinary operator + FUNARY, // A unary operator + FBINARY, // A binary operator + FTRINARY, // A trinary operator - FJMPIFEVAL, // Jump if evaluate = true - FJMP, // Jump + FJMPIFEVAL, // Jump if evaluate = true + FJMP, // Jump - FBEGINBLOCK, // Marks the beginning of a model block - FENDBLOCK, // Marks the end of a model block - FENDEQU, // Marks the last equation of the block; for a block that has to be solved, the derivatives appear just after this flag - FEND, // Marks the end of the model code + FBEGINBLOCK, // Marks the beginning of a model block + FENDBLOCK, // Marks the end of a model block + FENDEQU, // Marks the last equation of the block; for a block that has to be solved, the + // derivatives appear just after this flag + FEND, // Marks the end of the model code - FNUMEXPR, // Stores the expression type and references + FNUMEXPR, // Stores the expression type and references - FCALL, // Call an external function - FLDTEF, // Loads the result of an external function onto the stack - FSTPTEF, // Stores the result of an external function from the stack - FLDTEFD, // Loads the result of the 1st derivative of an external function onto the stack - FSTPTEFD, // Stores the result of the 1st derivative of an external function from the stack - FLDTEFDD, // Loads the result of the 2nd derivative of an external function onto the stack - FSTPTEFDD // Stores the result of the 2nd derivative of an external function from the stack - }; + FCALL, // Call an external function + FLDTEF, // Loads the result of an external function onto the stack + FSTPTEF, // Stores the result of an external function from the stack + FLDTEFD, // Loads the result of the 1st derivative of an external function onto the stack + FSTPTEFD, // Stores the result of the 1st derivative of an external function from the stack + FLDTEFDD, // Loads the result of the 2nd derivative of an external function onto the stack + FSTPTEFDD // Stores the result of the 2nd derivative of an external function from the stack +}; enum class ExpressionType - { - TemporaryTerm, - ModelEquation, - FirstEndoDerivative, - FirstExoDerivative, - FirstExodetDerivative, - }; +{ + TemporaryTerm, + ModelEquation, + FirstEndoDerivative, + FirstExoDerivative, + FirstExodetDerivative, +}; enum class ExternalFunctionCallType - { - levelWithoutDerivative, - levelWithFirstDerivative, - levelWithFirstAndSecondDerivative, - separatelyProvidedFirstDerivative, - numericalFirstDerivative, - separatelyProvidedSecondDerivative, - numericalSecondDerivative - }; +{ + levelWithoutDerivative, + levelWithFirstDerivative, + levelWithFirstAndSecondDerivative, + separatelyProvidedFirstDerivative, + numericalFirstDerivative, + separatelyProvidedSecondDerivative, + numericalSecondDerivative +}; struct Block_contain_type { @@ -115,10 +129,10 @@ class BytecodeWriter; struct BytecodeInstruction { const Tags op_code; - explicit BytecodeInstruction(Tags op_code_arg) : - op_code {op_code_arg} + explicit BytecodeInstruction(Tags op_code_arg) : op_code {op_code_arg} { } + protected: /* This is a base class, so the destructor should be either public+virtual or protected+non-virtual. We opt for the latter, because otherwise this class @@ -133,11 +147,13 @@ class TagWithOneArgument : public BytecodeInstruction { protected: T1 arg1; + public: - TagWithOneArgument(Tags op_code_arg, T1 arg_arg1) : BytecodeInstruction{op_code_arg}, - arg1{arg_arg1} + TagWithOneArgument(Tags op_code_arg, T1 arg_arg1) : + BytecodeInstruction {op_code_arg}, arg1 {arg_arg1} { - }; + } + protected: // See BytecodeInstruction destructor for the rationale ~TagWithOneArgument() = default; @@ -149,11 +165,13 @@ class TagWithTwoArguments : public BytecodeInstruction protected: T1 arg1; T2 arg2; + public: TagWithTwoArguments(Tags op_code_arg, T1 arg_arg1, T2 arg_arg2) : - BytecodeInstruction{op_code_arg}, arg1{arg_arg1}, arg2{arg_arg2} + BytecodeInstruction {op_code_arg}, arg1 {arg_arg1}, arg2 {arg_arg2} { - }; + } + protected: // See BytecodeInstruction destructor for the rationale ~TagWithTwoArguments() = default; @@ -166,11 +184,13 @@ protected: T1 arg1; T2 arg2; T3 arg3; + public: TagWithThreeArguments(Tags op_code_arg, T1 arg_arg1, T2 arg_arg2, T3 arg_arg3) : - BytecodeInstruction{op_code_arg}, arg1{arg_arg1}, arg2{arg_arg2}, arg3{arg_arg3} + BytecodeInstruction {op_code_arg}, arg1 {arg_arg1}, arg2 {arg_arg2}, arg3 {arg_arg3} { - }; + } + protected: // See BytecodeInstruction destructor for the rationale ~TagWithThreeArguments() = default; @@ -184,12 +204,17 @@ protected: T2 arg2; T3 arg3; T4 arg4; + public: TagWithFourArguments(Tags op_code_arg, T1 arg_arg1, T2 arg_arg2, T3 arg_arg3, T4 arg_arg4) : - BytecodeInstruction{op_code_arg}, arg1{arg_arg1}, arg2{arg_arg2}, - arg3{move(arg_arg3)}, arg4{arg_arg4} + BytecodeInstruction {op_code_arg}, + arg1 {arg_arg1}, + arg2 {arg_arg2}, + arg3 {move(arg_arg3)}, + arg4 {arg_arg4} { - }; + } + protected: // See BytecodeInstruction destructor for the rationale ~TagWithFourArguments() = default; @@ -198,41 +223,41 @@ protected: class FLDZ_ final : public BytecodeInstruction { public: - FLDZ_() : BytecodeInstruction{Tags::FLDZ} + FLDZ_() : BytecodeInstruction {Tags::FLDZ} { - }; + } }; class FEND_ final : public BytecodeInstruction { public: - FEND_() : BytecodeInstruction{Tags::FEND} + FEND_() : BytecodeInstruction {Tags::FEND} { - }; + } }; class FENDBLOCK_ final : public BytecodeInstruction { public: - FENDBLOCK_() : BytecodeInstruction{Tags::FENDBLOCK} + FENDBLOCK_() : BytecodeInstruction {Tags::FENDBLOCK} { - }; + } }; class FENDEQU_ final : public BytecodeInstruction { public: - FENDEQU_() : BytecodeInstruction{Tags::FENDEQU} + FENDEQU_() : BytecodeInstruction {Tags::FENDEQU} { - }; + } }; class FDIMT_ final : public TagWithOneArgument { public: - explicit FDIMT_(int size_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FDIMT, size_arg} + explicit FDIMT_(int size_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FDIMT, size_arg} { - }; + } int get_size() { @@ -243,9 +268,9 @@ public: class FDIMST_ final : public TagWithOneArgument { public: - explicit FDIMST_(int size_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FDIMST, size_arg} + explicit FDIMST_(int size_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FDIMST, size_arg} { - }; + } int get_size() { @@ -256,9 +281,9 @@ public: class FLDC_ final : public TagWithOneArgument { public: - explicit FLDC_(double value_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FLDC, value_arg} + explicit FLDC_(double value_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FLDC, value_arg} { - }; + } double get_value() { @@ -269,9 +294,9 @@ public: class FLDU_ final : public TagWithOneArgument { public: - explicit FLDU_(int pos_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FLDU, pos_arg} + explicit FLDU_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FLDU, pos_arg} { - }; + } int get_pos() { @@ -282,9 +307,9 @@ public: class FLDSU_ final : public TagWithOneArgument { public: - explicit FLDSU_(int pos_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FLDSU, pos_arg} + explicit FLDSU_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FLDSU, pos_arg} { - }; + } int get_pos() { @@ -295,9 +320,9 @@ public: class FLDR_ final : public TagWithOneArgument { public: - explicit FLDR_(int pos_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FLDR, pos_arg} + explicit FLDR_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FLDR, pos_arg} { - }; + } int get_pos() { @@ -308,9 +333,9 @@ public: class FLDT_ final : public TagWithOneArgument { public: - explicit FLDT_(int pos_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FLDT, pos_arg} + explicit FLDT_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FLDT, pos_arg} { - }; + } int get_pos() { @@ -321,9 +346,9 @@ public: class FLDST_ final : public TagWithOneArgument { public: - explicit FLDST_(int pos_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FLDST, pos_arg} + explicit FLDST_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FLDST, pos_arg} { - }; + } int get_pos() { @@ -334,9 +359,9 @@ public: class FSTPT_ final : public TagWithOneArgument { public: - explicit FSTPT_(int pos_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FSTPT, pos_arg} + explicit FSTPT_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPT, pos_arg} { - }; + } int get_pos() { @@ -347,9 +372,9 @@ public: class FSTPST_ final : public TagWithOneArgument { public: - explicit FSTPST_(int pos_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FSTPST, pos_arg} + explicit FSTPST_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPST, pos_arg} { - }; + } int get_pos() { @@ -360,9 +385,9 @@ public: class FSTPR_ final : public TagWithOneArgument { public: - explicit FSTPR_(int pos_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FSTPR, pos_arg} + explicit FSTPR_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPR, pos_arg} { - }; + } int get_pos() { @@ -373,9 +398,9 @@ public: class FSTPU_ final : public TagWithOneArgument { public: - explicit FSTPU_(int pos_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FSTPU, pos_arg} + explicit FSTPU_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPU, pos_arg} { - }; + } int get_pos() { @@ -386,9 +411,9 @@ public: class FSTPSU_ final : public TagWithOneArgument { public: - explicit FSTPSU_(int pos_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FSTPSU, pos_arg} + explicit FSTPSU_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPSU, pos_arg} { - }; + } int get_pos() { @@ -399,9 +424,9 @@ public: class FSTPG_ final : public TagWithOneArgument { public: - explicit FSTPG_(int pos_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FSTPG, pos_arg} + explicit FSTPG_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPG, pos_arg} { - }; + } int get_pos() { @@ -412,9 +437,10 @@ public: class FSTPG2_ final : public TagWithTwoArguments { public: - FSTPG2_(int row_arg, int col_arg) : TagWithTwoArguments::TagWithTwoArguments{Tags::FSTPG2, row_arg, col_arg} + FSTPG2_(int row_arg, int col_arg) : + TagWithTwoArguments::TagWithTwoArguments {Tags::FSTPG2, row_arg, col_arg} { - }; + } int get_row() { @@ -430,9 +456,11 @@ public: class FSTPG3_ final : public TagWithFourArguments { public: - FSTPG3_(int row_arg, int col_arg, int lag_arg, int col_pos_arg) : TagWithFourArguments::TagWithFourArguments{Tags::FSTPG3, row_arg, col_arg, lag_arg, col_pos_arg} + FSTPG3_(int row_arg, int col_arg, int lag_arg, int col_pos_arg) : + TagWithFourArguments::TagWithFourArguments {Tags::FSTPG3, row_arg, col_arg, lag_arg, + col_pos_arg} { - }; + } int get_row() { @@ -458,9 +486,10 @@ public: class FUNARY_ final : public TagWithOneArgument { public: - explicit FUNARY_(UnaryOpcode op_type_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FUNARY, op_type_arg} + explicit FUNARY_(UnaryOpcode op_type_arg) : + TagWithOneArgument::TagWithOneArgument {Tags::FUNARY, op_type_arg} { - }; + } UnaryOpcode get_op_type() { @@ -471,9 +500,10 @@ public: class FBINARY_ final : public TagWithOneArgument { public: - explicit FBINARY_(BinaryOpcode op_type_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FBINARY, op_type_arg} + explicit FBINARY_(BinaryOpcode op_type_arg) : + TagWithOneArgument::TagWithOneArgument {Tags::FBINARY, op_type_arg} { - }; + } BinaryOpcode get_op_type() { @@ -484,9 +514,10 @@ public: class FTRINARY_ final : public TagWithOneArgument { public: - explicit FTRINARY_(TrinaryOpcode op_type_arg) : TagWithOneArgument::TagWithOneArgument{Tags::FTRINARY, op_type_arg} + explicit FTRINARY_(TrinaryOpcode op_type_arg) : + TagWithOneArgument::TagWithOneArgument {Tags::FTRINARY, op_type_arg} { - }; + } TrinaryOpcode get_op_type() { @@ -497,9 +528,10 @@ public: class FJMPIFEVAL_ final : public TagWithOneArgument { public: - explicit FJMPIFEVAL_(int arg_pos) : TagWithOneArgument::TagWithOneArgument{Tags::FJMPIFEVAL, arg_pos} + explicit FJMPIFEVAL_(int arg_pos) : + TagWithOneArgument::TagWithOneArgument {Tags::FJMPIFEVAL, arg_pos} { - }; + } int get_pos() { @@ -510,9 +542,9 @@ public: class FJMP_ final : public TagWithOneArgument { public: - explicit FJMP_(int arg_pos) : TagWithOneArgument::TagWithOneArgument{Tags::FJMP, arg_pos} + explicit FJMP_(int arg_pos) : TagWithOneArgument::TagWithOneArgument {Tags::FJMP, arg_pos} { - }; + } int get_pos() { @@ -523,9 +555,9 @@ public: class FLDTEF_ final : public TagWithOneArgument { public: - explicit FLDTEF_(int number) : TagWithOneArgument::TagWithOneArgument{Tags::FLDTEF, number} + explicit FLDTEF_(int number) : TagWithOneArgument::TagWithOneArgument {Tags::FLDTEF, number} { - }; + } int get_number() { @@ -536,9 +568,9 @@ public: class FSTPTEF_ final : public TagWithOneArgument { public: - explicit FSTPTEF_(int number) : TagWithOneArgument::TagWithOneArgument{Tags::FSTPTEF, number} + explicit FSTPTEF_(int number) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPTEF, number} { - }; + } int get_number() { @@ -549,9 +581,9 @@ public: class FLDTEFD_ final : public TagWithTwoArguments { public: - FLDTEFD_(int indx, int row) : TagWithTwoArguments::TagWithTwoArguments{Tags::FLDTEFD, indx, row} + FLDTEFD_(int indx, int row) : TagWithTwoArguments::TagWithTwoArguments {Tags::FLDTEFD, indx, row} { - }; + } int get_indx() { @@ -567,9 +599,10 @@ public: class FSTPTEFD_ final : public TagWithTwoArguments { public: - FSTPTEFD_(int indx, int row) : TagWithTwoArguments::TagWithTwoArguments{Tags::FSTPTEFD, indx, row} + FSTPTEFD_(int indx, int row) : + TagWithTwoArguments::TagWithTwoArguments {Tags::FSTPTEFD, indx, row} { - }; + } int get_indx() { @@ -585,9 +618,10 @@ public: class FLDTEFDD_ final : public TagWithThreeArguments { public: - FLDTEFDD_(int indx, int row, int col) : TagWithThreeArguments::TagWithThreeArguments{Tags::FLDTEFDD, indx, row, col} + FLDTEFDD_(int indx, int row, int col) : + TagWithThreeArguments::TagWithThreeArguments {Tags::FLDTEFDD, indx, row, col} { - }; + } int get_indx() { @@ -608,9 +642,10 @@ public: class FSTPTEFDD_ final : public TagWithThreeArguments { public: - FSTPTEFDD_(int indx, int row, int col) : TagWithThreeArguments::TagWithThreeArguments{Tags::FSTPTEF, indx, row, col} + FSTPTEFDD_(int indx, int row, int col) : + TagWithThreeArguments::TagWithThreeArguments {Tags::FSTPTEF, indx, row, col} { - }; + } int get_indx() { @@ -631,9 +666,10 @@ public: class FLDVS_ final : public TagWithTwoArguments { public: - FLDVS_(SymbolType type_arg, int pos_arg) : TagWithTwoArguments::TagWithTwoArguments{Tags::FLDVS, type_arg, pos_arg} + FLDVS_(SymbolType type_arg, int pos_arg) : + TagWithTwoArguments::TagWithTwoArguments {Tags::FLDVS, type_arg, pos_arg} { - }; + } SymbolType get_type() { @@ -649,9 +685,10 @@ public: class FLDSV_ final : public TagWithTwoArguments { public: - FLDSV_(SymbolType type_arg, int pos_arg) : TagWithTwoArguments::TagWithTwoArguments{Tags::FLDSV, type_arg, pos_arg} + FLDSV_(SymbolType type_arg, int pos_arg) : + TagWithTwoArguments::TagWithTwoArguments {Tags::FLDSV, type_arg, pos_arg} { - }; + } SymbolType get_type() { @@ -667,9 +704,10 @@ public: class FSTPSV_ final : public TagWithTwoArguments { public: - FSTPSV_(SymbolType type_arg, int pos_arg) : TagWithTwoArguments::TagWithTwoArguments{Tags::FSTPSV, type_arg, pos_arg} + FSTPSV_(SymbolType type_arg, int pos_arg) : + TagWithTwoArguments::TagWithTwoArguments {Tags::FSTPSV, type_arg, pos_arg} { - }; + } SymbolType get_type() { @@ -686,9 +724,9 @@ class FLDV_ final : public TagWithThreeArguments { public: FLDV_(SymbolType type_arg, int pos_arg, int lead_lag_arg) : - TagWithThreeArguments::TagWithThreeArguments{Tags::FLDV, type_arg, pos_arg, lead_lag_arg} + TagWithThreeArguments::TagWithThreeArguments {Tags::FLDV, type_arg, pos_arg, lead_lag_arg} { - }; + } SymbolType get_type() { @@ -710,9 +748,9 @@ class FSTPV_ final : public TagWithThreeArguments { public: FSTPV_(SymbolType type_arg, int pos_arg, int lead_lag_arg) : - TagWithThreeArguments::TagWithThreeArguments{Tags::FSTPV, type_arg, pos_arg, lead_lag_arg} + TagWithThreeArguments::TagWithThreeArguments {Tags::FSTPV, type_arg, pos_arg, lead_lag_arg} { - }; + } SymbolType get_type() { @@ -733,32 +771,33 @@ public: class FCALL_ final : public BytecodeInstruction { template - friend BytecodeWriter &operator<<(BytecodeWriter &code_file, const B &instr); + friend BytecodeWriter& operator<<(BytecodeWriter& code_file, const B& instr); + private: int nb_output_arguments, nb_input_arguments, indx; string func_name; string arg_func_name; - int add_input_arguments{0}, row{0}, col{0}; + int add_input_arguments {0}, row {0}, col {0}; ExternalFunctionCallType call_type; + public: - FCALL_(int nb_output_arguments_arg, int nb_input_arguments_arg, string func_name_arg, int indx_arg, ExternalFunctionCallType call_type_arg) : - BytecodeInstruction{Tags::FCALL}, - nb_output_arguments{nb_output_arguments_arg}, - nb_input_arguments{nb_input_arguments_arg}, - indx{indx_arg}, - func_name{move(func_name_arg)}, - call_type{call_type_arg} + FCALL_(int nb_output_arguments_arg, int nb_input_arguments_arg, string func_name_arg, + int indx_arg, ExternalFunctionCallType call_type_arg) : + BytecodeInstruction {Tags::FCALL}, + nb_output_arguments {nb_output_arguments_arg}, + nb_input_arguments {nb_input_arguments_arg}, + indx {indx_arg}, + func_name {move(func_name_arg)}, + call_type {call_type_arg} { - }; + } /* Deserializing constructor. Updates the code pointer to point beyond the bytes read. */ - FCALL_(char *&code) : - BytecodeInstruction{Tags::FCALL} + FCALL_(char*& code) : BytecodeInstruction {Tags::FCALL} { code += sizeof(op_code); - auto read_member = [&code](auto &member) - { + auto read_member = [&code](auto& member) { member = *reinterpret_cast>(code); code += sizeof member; }; @@ -774,17 +813,17 @@ public: int size; read_member(size); func_name = code; - code += size+1; + code += size + 1; read_member(size); arg_func_name = code; - code += size+1; + code += size + 1; } string get_function_name() { - //printf("get_function_name => func_name=%s\n",func_name.c_str());fflush(stdout); + // printf("get_function_name => func_name=%s\n",func_name.c_str());fflush(stdout); return func_name; }; int @@ -853,34 +892,36 @@ class FNUMEXPR_ final : public BytecodeInstruction { private: ExpressionType expression_type; - int equation; // Equation number (non-block-specific) (or temporary term number for ExpressionType::TemporaryTerm) + int equation; // Equation number (non-block-specific) (or temporary term number for + // ExpressionType::TemporaryTerm) int dvariable1; // For derivatives, type-specific ID of the derivation variable - int lag1; // For derivatives, lead/lag of the derivation variable + int lag1; // For derivatives, lead/lag of the derivation variable public: FNUMEXPR_(const ExpressionType expression_type_arg, int equation_arg) : - BytecodeInstruction{Tags::FNUMEXPR}, - expression_type{expression_type_arg}, - equation{equation_arg}, - dvariable1{0}, - lag1{0} + BytecodeInstruction {Tags::FNUMEXPR}, + expression_type {expression_type_arg}, + equation {equation_arg}, + dvariable1 {0}, + lag1 {0} { - }; + } FNUMEXPR_(const ExpressionType expression_type_arg, int equation_arg, int dvariable1_arg) : - BytecodeInstruction{Tags::FNUMEXPR}, - expression_type{expression_type_arg}, - equation{equation_arg}, - dvariable1{dvariable1_arg}, - lag1{0} + BytecodeInstruction {Tags::FNUMEXPR}, + expression_type {expression_type_arg}, + equation {equation_arg}, + dvariable1 {dvariable1_arg}, + lag1 {0} { - }; - FNUMEXPR_(const ExpressionType expression_type_arg, int equation_arg, int dvariable1_arg, int lag1_arg) : - BytecodeInstruction{Tags::FNUMEXPR}, - expression_type{expression_type_arg}, - equation{equation_arg}, - dvariable1{dvariable1_arg}, - lag1{lag1_arg} + } + FNUMEXPR_(const ExpressionType expression_type_arg, int equation_arg, int dvariable1_arg, + int lag1_arg) : + BytecodeInstruction {Tags::FNUMEXPR}, + expression_type {expression_type_arg}, + equation {equation_arg}, + dvariable1 {dvariable1_arg}, + lag1 {lag1_arg} { - }; + } ExpressionType get_expression_type() { @@ -906,67 +947,70 @@ public: class FBEGINBLOCK_ final : public BytecodeInstruction { template - friend BytecodeWriter &operator<<(BytecodeWriter &code_file, const B &instr); + friend BytecodeWriter& operator<<(BytecodeWriter& code_file, const B& instr); + private: - int size{0}; + int size {0}; BlockSimulationType type; vector variable; vector equation; vector exogenous; vector det_exogenous; - bool is_linear{false}; + bool is_linear {false}; vector Block_Contain_; - int u_count_int{0}; - int nb_col_jacob{0}; + int u_count_int {0}; + int nb_col_jacob {0}; int det_exo_size, exo_size; + public: /* Constructor when derivatives w.r.t. exogenous are present (only makes sense when there is no block-decomposition, since there is no provision for derivatives w.r.t. endogenous not belonging to the block) */ FBEGINBLOCK_(int size_arg, BlockSimulationType type_arg, int first_element, int block_size, - const vector &variable_arg, const vector &equation_arg, - bool is_linear_arg, int u_count_int_arg, int nb_col_jacob_arg, - int det_exo_size_arg, int exo_size_arg, + const vector& variable_arg, const vector& equation_arg, bool is_linear_arg, + int u_count_int_arg, int nb_col_jacob_arg, int det_exo_size_arg, int exo_size_arg, vector det_exogenous_arg, vector exogenous_arg) : - BytecodeInstruction{Tags::FBEGINBLOCK}, - size{size_arg}, - type{type_arg}, - variable{variable_arg.begin()+first_element, variable_arg.begin()+(first_element+block_size)}, - equation{equation_arg.begin()+first_element, equation_arg.begin()+(first_element+block_size)}, - exogenous{move(exogenous_arg)}, - det_exogenous{move(det_exogenous_arg)}, - is_linear{is_linear_arg}, - u_count_int{u_count_int_arg}, - nb_col_jacob{nb_col_jacob_arg}, - det_exo_size{det_exo_size_arg}, - exo_size{exo_size_arg} + BytecodeInstruction {Tags::FBEGINBLOCK}, + size {size_arg}, + type {type_arg}, + variable {variable_arg.begin() + first_element, + variable_arg.begin() + (first_element + block_size)}, + equation {equation_arg.begin() + first_element, + equation_arg.begin() + (first_element + block_size)}, + exogenous {move(exogenous_arg)}, + det_exogenous {move(det_exogenous_arg)}, + is_linear {is_linear_arg}, + u_count_int {u_count_int_arg}, + nb_col_jacob {nb_col_jacob_arg}, + det_exo_size {det_exo_size_arg}, + exo_size {exo_size_arg} { } // Constructor when derivatives w.r.t. exogenous are absent FBEGINBLOCK_(int size_arg, BlockSimulationType type_arg, int first_element, int block_size, - const vector &variable_arg, const vector &equation_arg, - bool is_linear_arg, int u_count_int_arg, int nb_col_jacob_arg) : - BytecodeInstruction{Tags::FBEGINBLOCK}, - size{size_arg}, - type{type_arg}, - variable{variable_arg.begin()+first_element, variable_arg.begin()+(first_element+block_size)}, - equation{equation_arg.begin()+first_element, equation_arg.begin()+(first_element+block_size)}, - is_linear{is_linear_arg}, - u_count_int{u_count_int_arg}, - nb_col_jacob{nb_col_jacob_arg}, - det_exo_size{0}, - exo_size{0} + const vector& variable_arg, const vector& equation_arg, bool is_linear_arg, + int u_count_int_arg, int nb_col_jacob_arg) : + BytecodeInstruction {Tags::FBEGINBLOCK}, + size {size_arg}, + type {type_arg}, + variable {variable_arg.begin() + first_element, + variable_arg.begin() + (first_element + block_size)}, + equation {equation_arg.begin() + first_element, + equation_arg.begin() + (first_element + block_size)}, + is_linear {is_linear_arg}, + u_count_int {u_count_int_arg}, + nb_col_jacob {nb_col_jacob_arg}, + det_exo_size {0}, + exo_size {0} { } /* Deserializing constructor. Updates the code pointer to point beyond the bytes read. */ - FBEGINBLOCK_(char *&code) : - BytecodeInstruction{Tags::FBEGINBLOCK} + FBEGINBLOCK_(char*& code) : BytecodeInstruction {Tags::FBEGINBLOCK} { code += sizeof(op_code); - auto read_member = [&code](auto &member) - { + auto read_member = [&code](auto& member) { member = *reinterpret_cast>(code); code += sizeof member; }; @@ -1062,12 +1106,14 @@ public: class BytecodeWriter : private ofstream { template - friend BytecodeWriter &operator<<(BytecodeWriter &code_file, const B &instr); + friend BytecodeWriter& operator<<(BytecodeWriter& code_file, const B& instr); + private: // Stores the positions of all instructions in the byte stream vector instructions_positions; + public: - BytecodeWriter(const filesystem::path &filename); + BytecodeWriter(const filesystem::path& filename); // Returns the number of the next instruction to be written int getInstructionCounter() const @@ -1079,7 +1125,7 @@ public: occupies exactly as many bytes as the former one. */ template void - overwriteInstruction(int instruction_number, const B &new_instruction) + overwriteInstruction(int instruction_number, const B& new_instruction) { seekp(instructions_positions.at(instruction_number)); *this << new_instruction; @@ -1091,18 +1137,18 @@ public: // Overloads of operator<< for writing bytecode instructions template -BytecodeWriter & -operator<<(BytecodeWriter &code_file, const B &instr) +BytecodeWriter& +operator<<(BytecodeWriter& code_file, const B& instr) { code_file.instructions_positions.push_back(code_file.tellp()); - code_file.write(reinterpret_cast(&instr), sizeof(B)); + code_file.write(reinterpret_cast(&instr), sizeof(B)); return code_file; } template<> -BytecodeWriter &operator<<(BytecodeWriter &code_file, const FCALL_ &instr); +BytecodeWriter& operator<<(BytecodeWriter& code_file, const FCALL_& instr); template<> -BytecodeWriter &operator<<(BytecodeWriter &code_file, const FBEGINBLOCK_ &instr); +BytecodeWriter& operator<<(BytecodeWriter& code_file, const FBEGINBLOCK_& instr); #endif // _BYTECODE_HH diff --git a/src/CommonEnums.hh b/src/CommonEnums.hh index c4ad7a6c..7cd13f66 100644 --- a/src/CommonEnums.hh +++ b/src/CommonEnums.hh @@ -21,127 +21,134 @@ #define _COMMON_ENUMS_HH //! Enumeration of possible symbol types -/*! Warning: do not to change existing values for 0 to 4: the values matter for homotopy_setup command */ +/*! Warning: do not to change existing values for 0 to 4: the values matter for homotopy_setup + * command */ enum class SymbolType - { - endogenous = 0, //!< Endogenous - exogenous = 1, //!< Exogenous - exogenousDet = 2, //!< Exogenous deterministic - parameter = 4, //!< Parameter - modelLocalVariable = 10, //!< Local variable whose scope is model (pound expression) - modFileLocalVariable = 11, //!< Local variable whose scope is mod file (model excluded) - externalFunction = 12, //!< External (user-defined) function - trend = 13, //!< Trend variable - statementDeclaredVariable = 14, //!< Local variable assigned within a Statement (see subsample statement for example) - logTrend = 15, //!< Log-trend variable - unusedEndogenous = 16, //!< Type to mark unused endogenous variables when `nostrict` option is passed +{ + endogenous = 0, //!< Endogenous + exogenous = 1, //!< Exogenous + exogenousDet = 2, //!< Exogenous deterministic + parameter = 4, //!< Parameter + modelLocalVariable = 10, //!< Local variable whose scope is model (pound expression) + modFileLocalVariable = 11, //!< Local variable whose scope is mod file (model excluded) + externalFunction = 12, //!< External (user-defined) function + trend = 13, //!< Trend variable + statementDeclaredVariable + = 14, //!< Local variable assigned within a Statement (see subsample statement for example) + logTrend = 15, //!< Log-trend variable + unusedEndogenous + = 16, //!< Type to mark unused endogenous variables when `nostrict` option is passed - // Value 17 is unused for the time being (but could be reused) + // Value 17 is unused for the time being (but could be reused) - epilogue = 18, //!< Variables created in epilogue block - excludedVariable = 19 //!< Variable excluded via model_remove/var_remove/include_eqs/exclude_eqs - }; + epilogue = 18, //!< Variables created in epilogue block + excludedVariable = 19 //!< Variable excluded via model_remove/var_remove/include_eqs/exclude_eqs +}; enum class UnaryOpcode - { - uminus, - exp, - log, - log10, - cos, - sin, - tan, - acos, - asin, - atan, - cosh, - sinh, - tanh, - acosh, - asinh, - atanh, - sqrt, - cbrt, - abs, - sign, - steadyState, - steadyStateParamDeriv, // for the derivative of the STEADY_STATE operator w.r.t. to a parameter - steadyStateParam2ndDeriv, // for the 2nd derivative of the STEADY_STATE operator w.r.t. to a parameter - expectation, - erf, - erfc, - diff, - adl - }; +{ + uminus, + exp, + log, + log10, + cos, + sin, + tan, + acos, + asin, + atan, + cosh, + sinh, + tanh, + acosh, + asinh, + atanh, + sqrt, + cbrt, + abs, + sign, + steadyState, + steadyStateParamDeriv, // for the derivative of the STEADY_STATE operator w.r.t. to a parameter + steadyStateParam2ndDeriv, // for the 2nd derivative of the STEADY_STATE operator w.r.t. to a + // parameter + expectation, + erf, + erfc, + diff, + adl +}; enum class BinaryOpcode - { - plus, - minus, - times, - divide, - power, - powerDeriv, // for the derivative of the power function (see trac ticket #78) - equal, - max, - min, - less, - greater, - lessEqual, - greaterEqual, - equalEqual, - different - }; +{ + plus, + minus, + times, + divide, + power, + powerDeriv, // for the derivative of the power function (see trac ticket #78) + equal, + max, + min, + less, + greater, + lessEqual, + greaterEqual, + equalEqual, + different +}; // Small number value used when evaluating powerDeriv opcodes. // Put here instead of inside BinaryOpNode class, because needed by bytecode MEX. -constexpr double power_deriv_near_zero{1e-12}; +constexpr double power_deriv_near_zero {1e-12}; enum class TrinaryOpcode - { - normcdf, - normpdf - }; +{ + normcdf, + normpdf +}; enum class PriorDistributions - { - noShape = 0, - beta = 1, - gamma = 2, - normal = 3, - invGamma = 4, - invGamma1 = 4, - uniform = 5, - invGamma2 = 6, - dirichlet = 7, - weibull = 8 - }; +{ + noShape = 0, + beta = 1, + gamma = 2, + normal = 3, + invGamma = 4, + invGamma1 = 4, + uniform = 5, + invGamma2 = 6, + dirichlet = 7, + weibull = 8 +}; enum class EquationType - { - evaluate, //!< Simple evaluation, normalized variable on left-hand side (written as such by the user) - evaluateRenormalized, //!< Simple evaluation, normalized variable on left-hand side (normalization computed by the preprocessor) - solve //!< No simple evaluation of the equation, it has to be solved - }; +{ + evaluate, //!< Simple evaluation, normalized variable on left-hand side (written as such by the + //!< user) + evaluateRenormalized, //!< Simple evaluation, normalized variable on left-hand side (normalization + //!< computed by the preprocessor) + solve //!< No simple evaluation of the equation, it has to be solved +}; enum class BlockSimulationType - { - evaluateForward = 1, //!< Simple evaluation, normalized variable on left-hand side, forward - evaluateBackward, //!< Simple evaluation, normalized variable on left-hand side, backward - solveForwardSimple, //!< Block of one equation, newton solver needed, forward - solveBackwardSimple, //!< Block of one equation, newton solver needed, backward - solveTwoBoundariesSimple, //!< Block of one equation, Newton solver needed, forward and backward - solveForwardComplete, //!< Block of several equations, Newton solver needed, forward - solveBackwardComplete, //!< Block of several equations, Newton solver needed, backward - solveTwoBoundariesComplete //!< Block of several equations, Newton solver needed, forward and backwar - }; +{ + evaluateForward = 1, //!< Simple evaluation, normalized variable on left-hand side, forward + evaluateBackward, //!< Simple evaluation, normalized variable on left-hand side, backward + solveForwardSimple, //!< Block of one equation, newton solver needed, forward + solveBackwardSimple, //!< Block of one equation, newton solver needed, backward + solveTwoBoundariesSimple, //!< Block of one equation, Newton solver needed, forward and backward + solveForwardComplete, //!< Block of several equations, Newton solver needed, forward + solveBackwardComplete, //!< Block of several equations, Newton solver needed, backward + solveTwoBoundariesComplete //!< Block of several equations, Newton solver needed, forward and + //!< backwar +}; enum class PacTargetKind - { - unspecified, // Must be the first one, because it’s the default initializer - ll, - dl, - dd - }; +{ + unspecified, // Must be the first one, because it’s the default initializer + ll, + dl, + dd +}; #endif // _COMMON_ENUMS_HH diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc index 52b5f2b3..aabcb5fb 100644 --- a/src/ComputingTasks.cc +++ b/src/ComputingTasks.cc @@ -17,42 +17,42 @@ * along with Dynare. If not, see . */ +#include #include #include -#include -#include #include +#include using namespace std; #include "ComputingTasks.hh" -#include "Statement.hh" #include "ParsingDriver.hh" +#include "Statement.hh" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" -#include #include +#include #include #pragma GCC diagnostic pop -#include #include +#include SteadyStatement::SteadyStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -SteadyStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +SteadyStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.steady_present = true; } void -SteadyStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +SteadyStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); @@ -60,7 +60,7 @@ SteadyStatement::writeOutput(ostream &output, [[maybe_unused]] const string &bas } void -SteadyStatement::writeJsonOutput(ostream &output) const +SteadyStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "steady")"; if (!options_list.empty()) @@ -71,13 +71,12 @@ SteadyStatement::writeJsonOutput(ostream &output) const output << "}"; } -CheckStatement::CheckStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} +CheckStatement::CheckStatement(OptionsList options_list_arg) : options_list {move(options_list_arg)} { } void -CheckStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +CheckStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); @@ -85,14 +84,14 @@ CheckStatement::writeOutput(ostream &output, [[maybe_unused]] const string &base } void -CheckStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +CheckStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.check_present = true; } void -CheckStatement::writeJsonOutput(ostream &output) const +CheckStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "check")"; if (!options_list.empty()) @@ -104,12 +103,12 @@ CheckStatement::writeJsonOutput(ostream &output) const } ModelInfoStatement::ModelInfoStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -ModelInfoStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +ModelInfoStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output, "options_model_info_"); @@ -117,7 +116,7 @@ ModelInfoStatement::writeOutput(ostream &output, [[maybe_unused]] const string & } void -ModelInfoStatement::writeJsonOutput(ostream &output) const +ModelInfoStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "model_info")"; if (!options_list.empty()) @@ -128,20 +127,19 @@ ModelInfoStatement::writeJsonOutput(ostream &output) const output << "}"; } -SimulStatement::SimulStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} +SimulStatement::SimulStatement(OptionsList options_list_arg) : options_list {move(options_list_arg)} { } void -SimulStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +SimulStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.perfect_foresight_solver_present = true; } void -SimulStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +SimulStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { // Translate the “datafile” option into “initval_file” (see dynare#1663) @@ -155,12 +153,11 @@ 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 << "perfect_foresight_setup;" << endl << "perfect_foresight_solver;" << endl; } void -SimulStatement::writeJsonOutput(ostream &output) const +SimulStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "simul")"; if (!options_list.empty()) @@ -172,12 +169,13 @@ SimulStatement::writeJsonOutput(ostream &output) const } PerfectForesightSetupStatement::PerfectForesightSetupStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -PerfectForesightSetupStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +PerfectForesightSetupStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { auto options_list_new = options_list; // Need a copy, because of const @@ -194,7 +192,7 @@ PerfectForesightSetupStatement::writeOutput(ostream &output, [[maybe_unused]] co } void -PerfectForesightSetupStatement::writeJsonOutput(ostream &output) const +PerfectForesightSetupStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "perfect_foresight_setup")"; if (!options_list.empty()) @@ -206,19 +204,20 @@ PerfectForesightSetupStatement::writeJsonOutput(ostream &output) const } PerfectForesightSolverStatement::PerfectForesightSolverStatement(OptionsList options_list_arg) : - options_list(move(options_list_arg)) + options_list(move(options_list_arg)) { } void -PerfectForesightSolverStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +PerfectForesightSolverStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.perfect_foresight_solver_present = true; } void -PerfectForesightSolverStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +PerfectForesightSolverStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); @@ -226,7 +225,7 @@ PerfectForesightSolverStatement::writeOutput(ostream &output, [[maybe_unused]] c } void -PerfectForesightSolverStatement::writeJsonOutput(ostream &output) const +PerfectForesightSolverStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "perfect_foresight_solver")"; if (!options_list.empty()) @@ -237,22 +236,23 @@ PerfectForesightSolverStatement::writeJsonOutput(ostream &output) const output << "}"; } -PerfectForesightWithExpectationErrorsSetupStatement::PerfectForesightWithExpectationErrorsSetupStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} +PerfectForesightWithExpectationErrorsSetupStatement:: + PerfectForesightWithExpectationErrorsSetupStatement(OptionsList options_list_arg) : + options_list {move(options_list_arg)} { } void -PerfectForesightWithExpectationErrorsSetupStatement::writeOutput(ostream &output, - [[maybe_unused]] const string &basename, - [[maybe_unused]] bool minimal_workspace) const +PerfectForesightWithExpectationErrorsSetupStatement::writeOutput( + ostream& output, [[maybe_unused]] const string& basename, + [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); output << "perfect_foresight_with_expectation_errors_setup;" << endl; } void -PerfectForesightWithExpectationErrorsSetupStatement::writeJsonOutput(ostream &output) const +PerfectForesightWithExpectationErrorsSetupStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "perfect_foresight_with_expectation_errors_setup")"; if (!options_list.empty()) @@ -263,29 +263,30 @@ PerfectForesightWithExpectationErrorsSetupStatement::writeJsonOutput(ostream &ou output << "}"; } -PerfectForesightWithExpectationErrorsSolverStatement::PerfectForesightWithExpectationErrorsSolverStatement(OptionsList options_list_arg) : - options_list(move(options_list_arg)) +PerfectForesightWithExpectationErrorsSolverStatement:: + PerfectForesightWithExpectationErrorsSolverStatement(OptionsList options_list_arg) : + options_list(move(options_list_arg)) { } void -PerfectForesightWithExpectationErrorsSolverStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +PerfectForesightWithExpectationErrorsSolverStatement::checkPass( + ModFileStructure& mod_file_struct, [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.perfect_foresight_with_expectation_errors_solver_present = true; } void -PerfectForesightWithExpectationErrorsSolverStatement::writeOutput(ostream &output, - [[maybe_unused]] const string &basename, - [[maybe_unused]] bool minimal_workspace) const +PerfectForesightWithExpectationErrorsSolverStatement::writeOutput( + ostream& output, [[maybe_unused]] const string& basename, + [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); output << "perfect_foresight_with_expectation_errors_solver;" << endl; } void -PerfectForesightWithExpectationErrorsSolverStatement::writeJsonOutput(ostream &output) const +PerfectForesightWithExpectationErrorsSolverStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "perfect_foresight_with_expectation_errors_solver")"; if (!options_list.empty()) @@ -298,26 +299,26 @@ PerfectForesightWithExpectationErrorsSolverStatement::writeJsonOutput(ostream &o PriorPosteriorFunctionStatement::PriorPosteriorFunctionStatement(const bool prior_func_arg, OptionsList options_list_arg) : - prior_func{prior_func_arg}, - options_list{move(options_list_arg)} + prior_func {prior_func_arg}, options_list {move(options_list_arg)} { } void -PriorPosteriorFunctionStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +PriorPosteriorFunctionStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { - if (auto opt = options_list.get_if("function"); - !opt || opt->empty()) + if (auto opt = options_list.get_if("function"); !opt || opt->empty()) { - cerr << "ERROR: both the 'prior_function' and 'posterior_function' commands require the 'function' option" + cerr << "ERROR: both the 'prior_function' and 'posterior_function' commands require the " + "'function' option" << endl; exit(EXIT_FAILURE); } } void -PriorPosteriorFunctionStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +PriorPosteriorFunctionStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); @@ -330,7 +331,7 @@ PriorPosteriorFunctionStatement::writeOutput(ostream &output, [[maybe_unused]] c } void -PriorPosteriorFunctionStatement::writeJsonOutput(ostream &output) const +PriorPosteriorFunctionStatement::writeJsonOutput(ostream& output) const { string type = prior_func ? "prior" : "posterior"; output << R"({"statementName": "prior_posterior_function", "type": ")" << type << R"(")"; @@ -343,15 +344,15 @@ PriorPosteriorFunctionStatement::writeJsonOutput(ostream &output) const } StochSimulStatement::StochSimulStatement(SymbolList symbol_list_arg, OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - options_list{move(options_list_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, + options_list {move(options_list_arg)}, + symbol_table {symbol_table_arg} { } void -StochSimulStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +StochSimulStatement::checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) { mod_file_struct.stoch_simul_present = true; @@ -381,9 +382,9 @@ StochSimulStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsoli try { - symbol_list.checkPass(warnings, { SymbolType::endogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: stoch_simul: " << e.message << endl; exit(EXIT_FAILURE); @@ -391,7 +392,7 @@ StochSimulStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsoli } void -StochSimulStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +StochSimulStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { // Ensure that order 3 implies k_order (#844) @@ -406,7 +407,7 @@ StochSimulStatement::writeOutput(ostream &output, [[maybe_unused]] const string } void -StochSimulStatement::writeJsonOutput(ostream &output) const +StochSimulStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "stoch_simul")"; if (!options_list.empty()) @@ -423,22 +424,22 @@ StochSimulStatement::writeJsonOutput(ostream &output) const } ForecastStatement::ForecastStatement(SymbolList symbol_list_arg, OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - options_list{move(options_list_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, + options_list {move(options_list_arg)}, + symbol_table {symbol_table_arg} { } void -ForecastStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - WarningConsolidation &warnings) +ForecastStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + WarningConsolidation& warnings) { try { - symbol_list.checkPass(warnings, { SymbolType::endogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: forecast: " << e.message << endl; exit(EXIT_FAILURE); @@ -446,7 +447,7 @@ ForecastStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, } void -ForecastStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +ForecastStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); @@ -455,7 +456,7 @@ ForecastStatement::writeOutput(ostream &output, [[maybe_unused]] const string &b } void -ForecastStatement::writeJsonOutput(ostream &output) const +ForecastStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "forecast")"; if (!options_list.empty()) @@ -472,13 +473,13 @@ ForecastStatement::writeJsonOutput(ostream &output) const } RamseyModelStatement::RamseyModelStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -RamseyModelStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +RamseyModelStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.ramsey_model_present = true; @@ -488,14 +489,14 @@ RamseyModelStatement::checkPass(ModFileStructure &mod_file_struct, } void -RamseyModelStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +RamseyModelStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); } void -RamseyModelStatement::writeJsonOutput(ostream &output) const +RamseyModelStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "ramsey_model")"; if (!options_list.empty()) @@ -506,26 +507,25 @@ RamseyModelStatement::writeJsonOutput(ostream &output) const output << "}"; } -RamseyConstraintsStatement::RamseyConstraintsStatement(const SymbolTable &symbol_table_arg, constraints_t constraints_arg) : - symbol_table{symbol_table_arg}, - constraints{move(constraints_arg)} +RamseyConstraintsStatement::RamseyConstraintsStatement(const SymbolTable& symbol_table_arg, + constraints_t constraints_arg) : + symbol_table {symbol_table_arg}, constraints {move(constraints_arg)} { } void -RamseyConstraintsStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +RamseyConstraintsStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.ramsey_constraints_present = true; } void -RamseyConstraintsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +RamseyConstraintsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "M_.ramsey_model_constraints = {" << endl; - for (bool printed_something{false}; - const auto &it : constraints) + for (bool printed_something {false}; const auto& it : constraints) { if (exchange(printed_something, true)) output << ", "; @@ -556,12 +556,11 @@ RamseyConstraintsStatement::writeOutput(ostream &output, [[maybe_unused]] const } void -RamseyConstraintsStatement::writeJsonOutput(ostream &output) const +RamseyConstraintsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "ramsey_constraints")" << R"(, "ramsey_model_constraints": [)" << endl; - for (bool printed_something{false}; - const auto &it : constraints) + for (bool printed_something {false}; const auto& it : constraints) { if (exchange(printed_something, true)) output << ", "; @@ -594,15 +593,15 @@ RamseyConstraintsStatement::writeJsonOutput(ostream &output) const RamseyPolicyStatement::RamseyPolicyStatement(SymbolList symbol_list_arg, OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - options_list{move(options_list_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, + options_list {move(options_list_arg)}, + symbol_table {symbol_table_arg} { } void -RamseyPolicyStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +RamseyPolicyStatement::checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) { // Copied from RamseyModelStatement::checkPass() mod_file_struct.ramsey_model_present = true; @@ -636,9 +635,9 @@ RamseyPolicyStatement::checkPass(ModFileStructure &mod_file_struct, WarningConso try { - symbol_list.checkPass(warnings, { SymbolType::endogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: ramsey_policy: " << e.message << endl; exit(EXIT_FAILURE); @@ -646,7 +645,7 @@ RamseyPolicyStatement::checkPass(ModFileStructure &mod_file_struct, WarningConso } void -RamseyPolicyStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +RamseyPolicyStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { // Ensure that order 3 implies k_order (#844) @@ -663,7 +662,7 @@ RamseyPolicyStatement::writeOutput(ostream &output, [[maybe_unused]] const strin } void -RamseyPolicyStatement::writeJsonOutput(ostream &output) const +RamseyPolicyStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "ramsey_policy")"; if (!options_list.empty()) @@ -680,13 +679,13 @@ RamseyPolicyStatement::writeJsonOutput(ostream &output) const } EvaluatePlannerObjectiveStatement::EvaluatePlannerObjectiveStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -EvaluatePlannerObjectiveStatement::writeOutput(ostream &output, - [[maybe_unused]] const string &basename, +EvaluatePlannerObjectiveStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); @@ -694,7 +693,7 @@ EvaluatePlannerObjectiveStatement::writeOutput(ostream &output, } void -EvaluatePlannerObjectiveStatement::writeJsonOutput(ostream &output) const +EvaluatePlannerObjectiveStatement::writeJsonOutput(ostream& output) const { if (!options_list.empty()) { @@ -706,15 +705,16 @@ EvaluatePlannerObjectiveStatement::writeJsonOutput(ostream &output) const DiscretionaryPolicyStatement::DiscretionaryPolicyStatement(SymbolList symbol_list_arg, OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - options_list{move(options_list_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, + options_list {move(options_list_arg)}, + symbol_table {symbol_table_arg} { } void -DiscretionaryPolicyStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +DiscretionaryPolicyStatement::checkPass(ModFileStructure& mod_file_struct, + WarningConsolidation& warnings) { mod_file_struct.discretionary_policy_present = true; @@ -754,9 +754,9 @@ DiscretionaryPolicyStatement::checkPass(ModFileStructure &mod_file_struct, Warni try { - symbol_list.checkPass(warnings, { SymbolType::endogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: discretionary_policy: " << e.message << endl; exit(EXIT_FAILURE); @@ -764,7 +764,7 @@ DiscretionaryPolicyStatement::checkPass(ModFileStructure &mod_file_struct, Warni } void -DiscretionaryPolicyStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +DiscretionaryPolicyStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { // Ensure that order 3 implies k_order (#844) @@ -775,11 +775,12 @@ DiscretionaryPolicyStatement::writeOutput(ostream &output, [[maybe_unused]] cons options_list.writeOutput(output); symbol_list.writeOutput("var_list_", output); - output << "[info, oo_, options_, M_] = discretionary_policy(M_, options_, oo_, var_list_);" << endl; + output << "[info, oo_, options_, M_] = discretionary_policy(M_, options_, oo_, var_list_);" + << endl; } void -DiscretionaryPolicyStatement::writeJsonOutput(ostream &output) const +DiscretionaryPolicyStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "discretionary_policy")"; if (!options_list.empty()) @@ -796,20 +797,20 @@ DiscretionaryPolicyStatement::writeJsonOutput(ostream &output) const } OccbinSetupStatement::OccbinSetupStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -OccbinSetupStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +OccbinSetupStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output, "options_occbin_"); - output << "[M_, options_] = occbin.setup(M_, options_, options_occbin_);" << endl; + output << "[M_, options_] = occbin.setup(M_, options_, options_occbin_);" << endl; } void -OccbinSetupStatement::writeJsonOutput(ostream &output) const +OccbinSetupStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "occbin_setup")"; if (!options_list.empty()) @@ -821,20 +822,22 @@ OccbinSetupStatement::writeJsonOutput(ostream &output) const } OccbinSolverStatement::OccbinSolverStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -OccbinSolverStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +OccbinSolverStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output, "options_.occbin"); - output << "[oo_.dr, oo_.occbin.simul]= occbin.solver(M_, options_, oo_.dr , oo_.steady_state, oo_.exo_steady_state, oo_.exo_det_steady_state);" << endl; + output << "[oo_.dr, oo_.occbin.simul]= occbin.solver(M_, options_, oo_.dr , oo_.steady_state, " + "oo_.exo_steady_state, oo_.exo_det_steady_state);" + << endl; } void -OccbinSolverStatement::writeJsonOutput(ostream &output) const +OccbinSolverStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "occbin_solver")"; if (!options_list.empty()) @@ -846,20 +849,20 @@ OccbinSolverStatement::writeJsonOutput(ostream &output) const } OccbinWriteRegimesStatement::OccbinWriteRegimesStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -OccbinWriteRegimesStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +OccbinWriteRegimesStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output, "options_.occbin"); - output << "occbin.write_regimes_to_xls(oo_.occbin, M_, options_);" << endl; + output << "occbin.write_regimes_to_xls(oo_.occbin, M_, options_);" << endl; } void -OccbinWriteRegimesStatement::writeJsonOutput(ostream &output) const +OccbinWriteRegimesStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "occbin_write_regimes_xls")"; if (!options_list.empty()) @@ -872,13 +875,12 @@ OccbinWriteRegimesStatement::writeJsonOutput(ostream &output) const OccbinGraphStatement::OccbinGraphStatement(SymbolList symbol_list_arg, OptionsList options_list_arg) : - symbol_list{move(symbol_list_arg)}, - options_list{move(options_list_arg)} + symbol_list {move(symbol_list_arg)}, options_list {move(options_list_arg)} { } void -OccbinGraphStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +OccbinGraphStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { symbol_list.writeOutput("var_list_", output); @@ -887,7 +889,7 @@ OccbinGraphStatement::writeOutput(ostream &output, [[maybe_unused]] const string } void -OccbinGraphStatement::writeJsonOutput(ostream &output) const +OccbinGraphStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "occbin_graph")"; if (!options_list.empty()) @@ -903,17 +905,16 @@ OccbinGraphStatement::writeJsonOutput(ostream &output) const output << "}"; } -EstimationStatement::EstimationStatement(const SymbolTable &symbol_table_arg, - SymbolList symbol_list_arg, - OptionsList options_list_arg) : - symbol_table{symbol_table_arg}, - symbol_list{move(symbol_list_arg)}, - options_list{move(options_list_arg)} +EstimationStatement::EstimationStatement(const SymbolTable& symbol_table_arg, + SymbolList symbol_list_arg, OptionsList options_list_arg) : + symbol_table {symbol_table_arg}, + symbol_list {move(symbol_list_arg)}, + options_list {move(options_list_arg)} { } void -EstimationStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +EstimationStatement::checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) { mod_file_struct.estimation_present = true; @@ -939,46 +940,44 @@ EstimationStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsoli mod_file_struct.estimation_analytic_derivation = true; if (options_list.contains("dsge_var")) - options_list.visit("dsge_var", [&](const T &v) - { - if constexpr(is_same_v) - mod_file_struct.dsge_var_estimated = true; - else if constexpr(is_same_v) - mod_file_struct.dsge_var_calibrated = v; - }); + options_list.visit("dsge_var", [&](const T& v) { + if constexpr (is_same_v) + mod_file_struct.dsge_var_estimated = true; + else if constexpr (is_same_v) + mod_file_struct.dsge_var_calibrated = v; + }); // Fill in mod_file_struct.bayesian_irf_present - if (auto opt = options_list.get_if("bayesian_irf"); - opt && *opt == "true") + if (auto opt = options_list.get_if("bayesian_irf"); opt && *opt == "true") mod_file_struct.bayesian_irf_present = true; if (options_list.contains("dsge_varlag")) - if (mod_file_struct.dsge_var_calibrated.empty() - && !mod_file_struct.dsge_var_estimated) + if (mod_file_struct.dsge_var_calibrated.empty() && !mod_file_struct.dsge_var_estimated) { cerr << "ERROR: The estimation statement requires a dsge_var option to be passed " << "if the dsge_varlag option is passed." << endl; exit(EXIT_FAILURE); } - if (!mod_file_struct.dsge_var_calibrated.empty() - && mod_file_struct.dsge_var_estimated) + if (!mod_file_struct.dsge_var_calibrated.empty() && mod_file_struct.dsge_var_estimated) { cerr << "ERROR: An estimation statement cannot take more than one dsge_var option." << endl; exit(EXIT_FAILURE); } - if (!options_list.contains("datafile") - && !mod_file_struct.estimation_data_statement_present) + if (!options_list.contains("datafile") && !mod_file_struct.estimation_data_statement_present) { - cerr << "ERROR: The estimation statement requires a data file to be supplied via the datafile option." << endl; + cerr << "ERROR: The estimation statement requires a data file to be supplied via the " + "datafile option." + << endl; exit(EXIT_FAILURE); } - if (options_list.contains("mode_file") - && mod_file_struct.estim_params_use_calib) + if (options_list.contains("mode_file") && mod_file_struct.estim_params_use_calib) { - cerr << "ERROR: The mode_file option of the estimation statement is incompatible with the use_calibration option of the estimated_params_init block." << endl; + cerr << "ERROR: The mode_file option of the estimation statement is incompatible with the " + "use_calibration option of the estimated_params_init block." + << endl; exit(EXIT_FAILURE); } @@ -987,16 +986,19 @@ EstimationStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsoli { if (options_list.contains("mh_jscale")) { - cerr << "ERROR: The mh_tune_jscale and mh_jscale options of the estimation statement are incompatible." << endl; + cerr << "ERROR: The mh_tune_jscale and mh_jscale options of the estimation statement are " + "incompatible." + << endl; exit(EXIT_FAILURE); } } else if (options_list.contains("mh_tune_jscale.guess")) { - cerr << "ERROR: The option mh_tune_guess in estimation statement cannot be used without option mh_tune_jscale." << endl; + cerr << "ERROR: The option mh_tune_guess in estimation statement cannot be used without " + "option mh_tune_jscale." + << endl; exit(EXIT_FAILURE); } - /* Check that we are not trying to estimate a parameter appearing in the planner discount factor (see dynare#1173) */ @@ -1010,15 +1012,17 @@ EstimationStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsoli { cerr << "ERROR: It is not possible to estimate a parameter (" << symbol_table.getName(estimated_params_in_planner_discount[0]) - << ") that appears in the discount factor of the planner (i.e. in the 'planner_discount' option)." << endl; + << ") that appears in the discount factor of the planner (i.e. in the " + "'planner_discount' option)." + << endl; exit(EXIT_FAILURE); } try { - symbol_list.checkPass(warnings, { SymbolType::endogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: estimation: " << e.message << endl; exit(EXIT_FAILURE); @@ -1026,17 +1030,15 @@ EstimationStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsoli } void -EstimationStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +EstimationStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); // Special treatment for order option and particle filter - if (auto opt = options_list.get_if("order"); - !opt) + if (auto opt = options_list.get_if("order"); !opt) output << "options_.order = 1;" << endl; - else if (int order {stoi(*opt)}; - order >= 2) + else if (int order {stoi(*opt)}; order >= 2) { output << "options_.particle.status = true;" << endl; if (order > 2) @@ -1044,8 +1046,7 @@ EstimationStatement::writeOutput(ostream &output, [[maybe_unused]] const string } // Do not check for the steady state in diffuse filter mode (#400) - if (auto opt = options_list.get_if("diffuse_filter"); - opt && *opt == "true") + if (auto opt = options_list.get_if("diffuse_filter"); opt && *opt == "true") output << "options_.steadystate.nocheck = true;" << endl; symbol_list.writeOutput("var_list_", output); @@ -1053,7 +1054,7 @@ EstimationStatement::writeOutput(ostream &output, [[maybe_unused]] const string } void -EstimationStatement::writeJsonOutput(ostream &output) const +EstimationStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "estimation")"; if (!options_list.empty()) @@ -1070,16 +1071,15 @@ EstimationStatement::writeJsonOutput(ostream &output) const } DynareSensitivityStatement::DynareSensitivityStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -DynareSensitivityStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +DynareSensitivityStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { - if (auto opt = options_list.get_if("identification"); - opt && *opt == "1") + if (auto opt = options_list.get_if("identification"); opt && *opt == "1") { mod_file_struct.identification_present = true; // The following triggers 3rd order derivatives, see preprocessor#40 @@ -1089,7 +1089,7 @@ DynareSensitivityStatement::checkPass(ModFileStructure &mod_file_struct, } void -DynareSensitivityStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +DynareSensitivityStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output, "options_gsa"); @@ -1110,7 +1110,7 @@ DynareSensitivityStatement::writeOutput(ostream &output, [[maybe_unused]] const } void -DynareSensitivityStatement::writeJsonOutput(ostream &output) const +DynareSensitivityStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "dynare_sensitivity")"; if (!options_list.empty()) @@ -1121,22 +1121,21 @@ DynareSensitivityStatement::writeJsonOutput(ostream &output) const output << "}"; } -RplotStatement::RplotStatement(SymbolList symbol_list_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - symbol_table{symbol_table_arg} +RplotStatement::RplotStatement(SymbolList symbol_list_arg, const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, symbol_table {symbol_table_arg} { } void -RplotStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - WarningConsolidation &warnings) +RplotStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + WarningConsolidation& warnings) { try { - symbol_list.checkPass(warnings, { SymbolType::endogenous, SymbolType::exogenous}, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous, SymbolType::exogenous}, + symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: rplot: " << e.message << endl; exit(EXIT_FAILURE); @@ -1144,7 +1143,7 @@ RplotStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, } void -RplotStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +RplotStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { symbol_list.writeOutput("var_list_", output); @@ -1152,7 +1151,7 @@ RplotStatement::writeOutput(ostream &output, [[maybe_unused]] const string &base } void -RplotStatement::writeJsonOutput(ostream &output) const +RplotStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "rplot")"; if (!symbol_list.empty()) @@ -1164,31 +1163,30 @@ RplotStatement::writeJsonOutput(ostream &output) const } void -UnitRootVarsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +UnitRootVarsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { - output << "options_.diffuse_filter = 1;" << endl - << "options_.steadystate.nocheck = 1;" << endl; + output << "options_.diffuse_filter = 1;" << endl << "options_.steadystate.nocheck = 1;" << endl; } void -UnitRootVarsStatement::writeJsonOutput(ostream &output) const +UnitRootVarsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "unit_root_vars", )" << R"("diffuse_filter": 1, )" << R"("steady_state.nocheck": 1})"; } -DsampleStatement::DsampleStatement(int val1_arg) : val1{val1_arg}, val2{-1} +DsampleStatement::DsampleStatement(int val1_arg) : val1 {val1_arg}, val2 {-1} { } -DsampleStatement::DsampleStatement(int val1_arg, int val2_arg) : val1{val1_arg}, val2{val2_arg} +DsampleStatement::DsampleStatement(int val1_arg, int val2_arg) : val1 {val1_arg}, val2 {val2_arg} { } void -DsampleStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +DsampleStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { if (val2 < 0) @@ -1198,17 +1196,16 @@ DsampleStatement::writeOutput(ostream &output, [[maybe_unused]] const string &ba } void -DsampleStatement::writeJsonOutput(ostream &output) const +DsampleStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "dsample", )" << R"("value1": )" << val1 << ", " << R"("value2": )" << val2 << "}"; } -AbstractEstimatedParamsStatement::AbstractEstimatedParamsStatement(vector estim_params_list_arg, - const SymbolTable &symbol_table_arg) : - estim_params_list{move(estim_params_list_arg)}, - symbol_table{symbol_table_arg} +AbstractEstimatedParamsStatement::AbstractEstimatedParamsStatement( + vector estim_params_list_arg, const SymbolTable& symbol_table_arg) : + estim_params_list {move(estim_params_list_arg)}, symbol_table {symbol_table_arg} { } @@ -1220,16 +1217,17 @@ AbstractEstimatedParamsStatement::commonCheckPass() const concatenated blocks that is implemented in the writeOutput() method. */ set already_declared; set> already_declared_corr; - for (const auto &it : estim_params_list) + for (const auto& it : estim_params_list) { if (it.type == 3) // Correlation { // Use lexical ordering for the pair of symbols - auto x = it.name < it.name2 ? pair{it.name, it.name2} : pair{it.name2, it.name}; + auto x = it.name < it.name2 ? pair {it.name, it.name2} : pair {it.name2, it.name}; if (already_declared_corr.contains(x)) { - cerr << "ERROR: in `" << blockName() << "' block, the correlation between " << it.name << " and " << it.name2 << " is declared twice." << endl; + cerr << "ERROR: in `" << blockName() << "' block, the correlation between " << it.name + << " and " << it.name2 << " is declared twice." << endl; exit(EXIT_FAILURE); } else @@ -1239,7 +1237,8 @@ AbstractEstimatedParamsStatement::commonCheckPass() const { if (already_declared.contains(it.name)) { - cerr << "ERROR: in `" << blockName() << "' block, the symbol " << it.name << " is declared twice." << endl; + cerr << "ERROR: in `" << blockName() << "' block, the symbol " << it.name + << " is declared twice." << endl; exit(EXIT_FAILURE); } else @@ -1251,11 +1250,11 @@ AbstractEstimatedParamsStatement::commonCheckPass() const associated to other parameters in the same block (see issue #77) */ // First compute the symbol IDs of parameters declared in this block set declared_params; - for (const string &name : already_declared) + for (const string& name : already_declared) if (name != "dsge_prior_weight") declared_params.insert(symbol_table.getID(name)); // Then look for (apparently) recursive definitions - for (const auto &it : estim_params_list) + for (const auto& it : estim_params_list) { set used_params; it.init_val->collectVariables(SymbolType::parameter, used_params); @@ -1267,9 +1266,8 @@ AbstractEstimatedParamsStatement::commonCheckPass() const it.p4->collectVariables(SymbolType::parameter, used_params); it.jscale->collectVariables(SymbolType::parameter, used_params); vector intersect; - set_intersection(declared_params.begin(), declared_params.end(), - used_params.begin(), used_params.end(), - back_inserter(intersect)); + set_intersection(declared_params.begin(), declared_params.end(), used_params.begin(), + used_params.end(), back_inserter(intersect)); if (intersect.size() > 0) { cerr << "ERROR: in `" << blockName() << "' block, the value of estimated parameter " @@ -1285,20 +1283,20 @@ AbstractEstimatedParamsStatement::commonCheckPass() const } EstimatedParamsStatement::EstimatedParamsStatement(vector estim_params_list_arg, - const SymbolTable &symbol_table_arg, + const SymbolTable& symbol_table_arg, bool overwrite_arg) : - AbstractEstimatedParamsStatement(move(estim_params_list_arg), symbol_table_arg), - overwrite{overwrite_arg} + AbstractEstimatedParamsStatement(move(estim_params_list_arg), symbol_table_arg), + overwrite {overwrite_arg} { } void -EstimatedParamsStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +EstimatedParamsStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { commonCheckPass(); - for (const auto &it : estim_params_list) + for (const auto& it : estim_params_list) { if (it.name == "dsge_prior_weight") mod_file_struct.dsge_prior_weight_in_estimated_params = true; @@ -1307,27 +1305,28 @@ EstimatedParamsStatement::checkPass(ModFileStructure &mod_file_struct, if (it.prior == PriorDistributions::beta) try { - if (it.mean->eval(eval_context_t()) == 0.5 - && it.std->eval(eval_context_t()) == 0.5) + if (it.mean->eval(eval_context_t()) == 0.5 && it.std->eval(eval_context_t()) == 0.5) { - cerr << "ERROR: The prior density is not defined for the beta distribution when the mean = standard deviation = 0.5." << endl; + cerr << "ERROR: The prior density is not defined for the beta distribution when " + "the mean = standard deviation = 0.5." + << endl; exit(EXIT_FAILURE); } } - catch (ExprNode::EvalException &e) + catch (ExprNode::EvalException& e) { // We don't have enough information to compute the numerical value, skip the test } } // Fill in mod_file_struct.estimated_parameters (related to #469) - for (const auto &it : estim_params_list) + for (const auto& it : estim_params_list) if (it.type == 2 && it.name != "dsge_prior_weight") mod_file_struct.estimated_parameters.insert(symbol_table.getID(it.name)); } void -EstimatedParamsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +EstimatedParamsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { string indent; @@ -1347,12 +1346,14 @@ EstimatedParamsStatement::writeOutput(ostream &output, [[maybe_unused]] const st /* Note that we verify that parameters are not declared twice across concatenated blocks, because this case is not covered by the check implemented in AbstractEstimatedParamsStatement::commonCheckPass() */ - for (const auto &it : estim_params_list) + for (const auto& it : estim_params_list) { int tsid = symbol_table.getTypeSpecificID(it.name) + 1; int tsid2; SymbolType symb_type = symbol_table.getType(it.name); - string errmsg = " has been specified twice in two concatenated ''estimated_params'' blocks. Depending on your intention, you may want to use the ''overwrite'' option or an ''estimated_params_remove'' block."; + string errmsg = " has been specified twice in two concatenated ''estimated_params'' blocks. " + "Depending on your intention, you may want to use the ''overwrite'' option " + "or an ''estimated_params_remove'' block."; switch (it.type) { @@ -1364,7 +1365,8 @@ EstimatedParamsStatement::writeOutput(ostream &output, [[maybe_unused]] const st << "estim_params_.var_exo = [estim_params_.var_exo; "; else if (symb_type == SymbolType::endogenous) output << "if ~isempty(find(estim_params_.var_endo(:,1)==" << tsid << "))" << endl - << " error('The standard deviation of the measurement error for " << it.name << errmsg << "')" << endl + << " error('The standard deviation of the measurement error for " << it.name + << errmsg << "')" << endl << "end" << endl << "estim_params_.var_endo = [estim_params_.var_endo; "; output << tsid; @@ -1373,24 +1375,29 @@ EstimatedParamsStatement::writeOutput(ostream &output, [[maybe_unused]] const st output << "if ~isempty(find(estim_params_.param_vals(:,1)==" << tsid << "))" << endl << " error('Parameter " << it.name << errmsg << "')" << endl << "end" << endl - << "estim_params_.param_vals = [estim_params_.param_vals; " - << tsid; + << "estim_params_.param_vals = [estim_params_.param_vals; " << tsid; break; case 3: tsid2 = symbol_table.getTypeSpecificID(it.name2) + 1; if (symb_type == SymbolType::exogenous) - output << "if ~isempty(find((estim_params_.corrx(:,1)==" << tsid << " & estim_params_.corrx(:,2)==" << tsid2 << ") | " - << "(estim_params_.corrx(:,2)==" << tsid << " & estim_params_.corrx(:,1)==" << tsid2 << ")))" << endl - << " error('The correlation between " << it.name << " and " << it.name2 << errmsg << "')" << endl + output << "if ~isempty(find((estim_params_.corrx(:,1)==" << tsid + << " & estim_params_.corrx(:,2)==" << tsid2 << ") | " + << "(estim_params_.corrx(:,2)==" << tsid + << " & estim_params_.corrx(:,1)==" << tsid2 << ")))" << endl + << " error('The correlation between " << it.name << " and " << it.name2 + << errmsg << "')" << endl << "end" << endl << "estim_params_.corrx = [estim_params_.corrx; "; else if (symb_type == SymbolType::endogenous) - output << "if ~isempty(find((estim_params_.corrn(:,1)==" << tsid << " & estim_params_.corrn(:,2)==" << tsid2 << ") | " - << "(estim_params_.corrn(:,2)==" << tsid << " & estim_params_.corrn(:,1)==" << tsid2 << ")))" << endl - << " error('The correlation between measurement errors on " << it.name << " and " << it.name2 << errmsg << "')" << endl + output << "if ~isempty(find((estim_params_.corrn(:,1)==" << tsid + << " & estim_params_.corrn(:,2)==" << tsid2 << ") | " + << "(estim_params_.corrn(:,2)==" << tsid + << " & estim_params_.corrn(:,1)==" << tsid2 << ")))" << endl + << " error('The correlation between measurement errors on " << it.name + << " and " << it.name2 << errmsg << "')" << endl << "end" << endl << "estim_params_.corrn = [estim_params_.corrn; "; - output << tsid << ", " << symbol_table.getTypeSpecificID(it.name2)+1; + output << tsid << ", " << symbol_table.getTypeSpecificID(it.name2) + 1; break; } output << ", "; @@ -1399,8 +1406,7 @@ EstimatedParamsStatement::writeOutput(ostream &output, [[maybe_unused]] const st it.low_bound->writeOutput(output); output << ", "; it.up_bound->writeOutput(output); - output << ", " - << static_cast(it.prior) << ", "; + output << ", " << static_cast(it.prior) << ", "; it.mean->writeOutput(output); output << ", "; it.std->writeOutput(output); @@ -1415,12 +1421,11 @@ EstimatedParamsStatement::writeOutput(ostream &output, [[maybe_unused]] const st } void -EstimatedParamsStatement::writeJsonOutput(ostream &output) const +EstimatedParamsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "estimated_params", )" << R"("params": [)"; - for (bool printed_something{false}; - const auto &it : estim_params_list) + for (bool printed_something {false}; const auto& it : estim_params_list) { if (exchange(printed_something, true)) output << ", "; @@ -1445,9 +1450,7 @@ EstimatedParamsStatement::writeJsonOutput(ostream &output) const it.low_bound->writeJsonOutput(output, {}, {}); output << R"(", "upper_bound": ")"; it.up_bound->writeJsonOutput(output, {}, {}); - output << R"(", "prior_distribution": )" - << static_cast(it.prior) - << R"(, "mean": ")"; + output << R"(", "prior_distribution": )" << static_cast(it.prior) << R"(, "mean": ")"; it.mean->writeJsonOutput(output, {}, {}); output << R"(", "std": ")"; it.std->writeJsonOutput(output, {}, {}); @@ -1463,17 +1466,17 @@ EstimatedParamsStatement::writeJsonOutput(ostream &output) const << "}"; } -EstimatedParamsInitStatement::EstimatedParamsInitStatement(vector estim_params_list_arg, - const SymbolTable &symbol_table_arg, - const bool use_calibration_arg) : - AbstractEstimatedParamsStatement(move(estim_params_list_arg), symbol_table_arg), - use_calibration{use_calibration_arg} +EstimatedParamsInitStatement::EstimatedParamsInitStatement( + vector estim_params_list_arg, const SymbolTable& symbol_table_arg, + const bool use_calibration_arg) : + AbstractEstimatedParamsStatement(move(estim_params_list_arg), symbol_table_arg), + use_calibration {use_calibration_arg} { } void -EstimatedParamsInitStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +EstimatedParamsInitStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { commonCheckPass(); @@ -1482,7 +1485,7 @@ EstimatedParamsInitStatement::checkPass(ModFileStructure &mod_file_struct, } void -EstimatedParamsInitStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +EstimatedParamsInitStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { if (use_calibration) @@ -1490,7 +1493,7 @@ EstimatedParamsInitStatement::writeOutput(ostream &output, [[maybe_unused]] cons bool skipline = false; - for (const auto &it : estim_params_list) + for (const auto& it : estim_params_list) { int tsid = symbol_table.getTypeSpecificID(it.name) + 1; SymbolType symb_type = symbol_table.getType(it.name); @@ -1501,37 +1504,38 @@ EstimatedParamsInitStatement::writeOutput(ostream &output, [[maybe_unused]] cons { output << "tmp1 = find(estim_params_.var_exo(:,1)==" << tsid << ");" << endl << "if isempty(tmp1)" << endl - << " disp(sprintf('The standard deviation of %s is not estimated (the value provided in estimated_params_init is not used).', M_.exo_names{" << tsid << "}))" << endl; + << " disp(sprintf('The standard deviation of %s is not estimated (the " + "value provided in estimated_params_init is not used).', M_.exo_names{" + << tsid << "}))" << endl; skipline = true; - output << "else" << endl - << " estim_params_.var_exo(tmp1,2) = "; + output << "else" << endl << " estim_params_.var_exo(tmp1,2) = "; it.init_val->writeOutput(output); - output << ";" << endl - << "end" << endl; + output << ";" << endl << "end" << endl; } else if (symb_type == SymbolType::endogenous) { output << "tmp1 = find(estim_params_.var_endo(:,1)==" << tsid << ");" << endl << "if isempty(tmp1)" << endl - << " disp(sprintf('The standard deviation of the measurement error on %s is not estimated (the value provided in estimated_params_init is not used).', M_.endo_names{" << tsid << "}))" << endl; + << " disp(sprintf('The standard deviation of the measurement error on %s " + "is not estimated (the value provided in estimated_params_init is not " + "used).', M_.endo_names{" + << tsid << "}))" << endl; skipline = true; - output << "else" << endl - << " estim_params_.var_endo(tmp1,2) = "; + output << "else" << endl << " estim_params_.var_endo(tmp1,2) = "; it.init_val->writeOutput(output); - output << ";" << endl - << "end" << endl; + output << ";" << endl << "end" << endl; } else if (symb_type == SymbolType::parameter) { output << "tmp1 = find(estim_params_.param_vals(:,1)==" << tsid << ");" << endl << "if isempty(tmp1)" << endl - << " disp(sprintf('Parameter %s is not estimated (the value provided in estimated_params_init is not used).', M_.param_names{" << tsid << "}))" << endl; + << " disp(sprintf('Parameter %s is not estimated (the value provided in " + "estimated_params_init is not used).', M_.param_names{" + << tsid << "}))" << endl; skipline = true; - output << "else" << endl - << " estim_params_.param_vals(tmp1,2) = "; + output << "else" << endl << " estim_params_.param_vals(tmp1,2) = "; it.init_val->writeOutput(output); - output << ";" << endl - << "end" << endl; + output << ";" << endl << "end" << endl; } } else @@ -1539,31 +1543,34 @@ EstimatedParamsInitStatement::writeOutput(ostream &output, [[maybe_unused]] cons int tsid2 = symbol_table.getTypeSpecificID(it.name2) + 1; if (symb_type == SymbolType::exogenous) { - output << "tmp1 = find((estim_params_.corrx(:,1)==" << tsid << " & estim_params_.corrx(:,2)==" << tsid2 << ") | " - << "(estim_params_.corrx(:,2)==" << tsid << " & estim_params_.corrx(:,1)==" << tsid2 << "));" << endl + output << "tmp1 = find((estim_params_.corrx(:,1)==" << tsid + << " & estim_params_.corrx(:,2)==" << tsid2 << ") | " + << "(estim_params_.corrx(:,2)==" << tsid + << " & estim_params_.corrx(:,1)==" << tsid2 << "));" << endl << "if isempty(tmp1)" << endl - << " disp(sprintf('The correlation between %s and %s is not estimated (the value provided in estimated_params_init is not used).', M_.exo_names{" + << " disp(sprintf('The correlation between %s and %s is not estimated (the " + "value provided in estimated_params_init is not used).', M_.exo_names{" << tsid << "}, M_.exo_names{" << tsid2 << "}))" << endl; skipline = true; - output << "else" << endl - << " estim_params_.corrx(tmp1,3) = "; + output << "else" << endl << " estim_params_.corrx(tmp1,3) = "; it.init_val->writeOutput(output); - output << ";" << endl - << "end" << endl; + output << ";" << endl << "end" << endl; } else if (symb_type == SymbolType::endogenous) { - output << "tmp1 = find((estim_params_.corrn(:,1)==" << tsid << " & estim_params_.corrn(:,2)==" << tsid2 << ") | " - << "(estim_params_.corrn(:,2)==" << tsid << " & estim_params_.corrn(:,1)==" << tsid2 << "));" << endl + output << "tmp1 = find((estim_params_.corrn(:,1)==" << tsid + << " & estim_params_.corrn(:,2)==" << tsid2 << ") | " + << "(estim_params_.corrn(:,2)==" << tsid + << " & estim_params_.corrn(:,1)==" << tsid2 << "));" << endl << "if isempty(tmp1)" << endl - << " disp(sprintf('The correlation between measurement errors on %s and %s is not estimated (the value provided in estimated_params_init is not used).', M_.endo_names{" + << " disp(sprintf('The correlation between measurement errors on %s and %s " + "is not estimated (the value provided in estimated_params_init is not " + "used).', M_.endo_names{" << tsid << "}, M_.endo_names{" << tsid2 << "}))" << endl; skipline = true; - output << "else" << endl - << " estim_params_.corrn(tmp1,3) = "; + output << "else" << endl << " estim_params_.corrn(tmp1,3) = "; it.init_val->writeOutput(output); - output << ";" << endl - << "end" << endl; + output << ";" << endl << "end" << endl; } } } @@ -1572,7 +1579,7 @@ EstimatedParamsInitStatement::writeOutput(ostream &output, [[maybe_unused]] cons } void -EstimatedParamsInitStatement::writeJsonOutput(ostream &output) const +EstimatedParamsInitStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "estimated_params_init")"; @@ -1580,8 +1587,7 @@ EstimatedParamsInitStatement::writeJsonOutput(ostream &output) const output << R"(, "use_calibration_initialization": 1)"; output << R"(, "params": [)"; - for (bool printed_something{false}; - const auto &it : estim_params_list) + for (bool printed_something {false}; const auto& it : estim_params_list) { if (exchange(printed_something, true)) output << ", "; @@ -1607,24 +1613,25 @@ EstimatedParamsInitStatement::writeJsonOutput(ostream &output) const << "}"; } -EstimatedParamsBoundsStatement::EstimatedParamsBoundsStatement(vector estim_params_list_arg, - const SymbolTable &symbol_table_arg) : - AbstractEstimatedParamsStatement(move(estim_params_list_arg), symbol_table_arg) +EstimatedParamsBoundsStatement::EstimatedParamsBoundsStatement( + vector estim_params_list_arg, const SymbolTable& symbol_table_arg) : + AbstractEstimatedParamsStatement(move(estim_params_list_arg), symbol_table_arg) { } void -EstimatedParamsBoundsStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +EstimatedParamsBoundsStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { commonCheckPass(); } void -EstimatedParamsBoundsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +EstimatedParamsBoundsStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { - for (const auto &it : estim_params_list) + for (const auto& it : estim_params_list) { int tsid = symbol_table.getTypeSpecificID(it.name) + 1; SymbolType symb_type = symbol_table.getType(it.name); @@ -1636,8 +1643,7 @@ EstimatedParamsBoundsStatement::writeOutput(ostream &output, [[maybe_unused]] co output << "tmp1 = find(estim_params_.var_exo(:,1)==" << tsid << ");" << endl << "estim_params_.var_exo(tmp1,3) = "; it.low_bound->writeOutput(output); - output << ";" << endl - << "estim_params_.var_exo(tmp1,4) = "; + output << ";" << endl << "estim_params_.var_exo(tmp1,4) = "; it.up_bound->writeOutput(output); output << ";" << endl; } @@ -1646,8 +1652,7 @@ EstimatedParamsBoundsStatement::writeOutput(ostream &output, [[maybe_unused]] co output << "tmp1 = find(estim_params_.var_endo(:,1)==" << tsid << ");" << endl << "estim_params_.var_endo(tmp1,3) = "; it.low_bound->writeOutput(output); - output << ";" << endl - << "estim_params_.var_endo(tmp1,4) = "; + output << ";" << endl << "estim_params_.var_endo(tmp1,4) = "; it.up_bound->writeOutput(output); output << ";" << endl; } @@ -1656,8 +1661,7 @@ EstimatedParamsBoundsStatement::writeOutput(ostream &output, [[maybe_unused]] co output << "tmp1 = find(estim_params_.param_vals(:,1)==" << tsid << ");" << endl << "estim_params_.param_vals(tmp1,3) = "; it.low_bound->writeOutput(output); - output << ";" << endl - << "estim_params_.param_vals(tmp1,4) = "; + output << ";" << endl << "estim_params_.param_vals(tmp1,4) = "; it.up_bound->writeOutput(output); output << ";" << endl; } @@ -1667,23 +1671,25 @@ EstimatedParamsBoundsStatement::writeOutput(ostream &output, [[maybe_unused]] co int tsid2 = symbol_table.getTypeSpecificID(it.name2) + 1; if (symb_type == SymbolType::exogenous) { - output << "tmp1 = find((estim_params_.corrx(:,1)==" << tsid << " & estim_params_.corrx(:,2)==" << tsid2 << ") | " - << "(estim_params_.corrx(:,2)==" << tsid << " & estim_params_.corrx(:,1)==" << tsid2 << "));" << endl + output << "tmp1 = find((estim_params_.corrx(:,1)==" << tsid + << " & estim_params_.corrx(:,2)==" << tsid2 << ") | " + << "(estim_params_.corrx(:,2)==" << tsid + << " & estim_params_.corrx(:,1)==" << tsid2 << "));" << endl << "estim_params_.corrx(tmp1,4) = "; it.low_bound->writeOutput(output); - output << ";" << endl - << "estim_params_.corrx(tmp1,5) = "; + output << ";" << endl << "estim_params_.corrx(tmp1,5) = "; it.up_bound->writeOutput(output); output << ";" << endl; } else if (symb_type == SymbolType::endogenous) { - output << "tmp1 = find((estim_params_.corrn(:,1)==" << tsid << " & estim_params_.corrn(:,2)==" << tsid2 << ") | " - << "(estim_params_.corrn(:,2)==" << tsid << " & estim_params_.corrn(:,1)==" << tsid2 << "));" << endl + output << "tmp1 = find((estim_params_.corrn(:,1)==" << tsid + << " & estim_params_.corrn(:,2)==" << tsid2 << ") | " + << "(estim_params_.corrn(:,2)==" << tsid + << " & estim_params_.corrn(:,1)==" << tsid2 << "));" << endl << "estim_params_.corrn(tmp1,4) = "; it.low_bound->writeOutput(output); - output << ";" << endl - << "estim_params_.corrn(tmp1,5) = "; + output << ";" << endl << "estim_params_.corrn(tmp1,5) = "; it.up_bound->writeOutput(output); output << ";" << endl; } @@ -1692,13 +1698,12 @@ EstimatedParamsBoundsStatement::writeOutput(ostream &output, [[maybe_unused]] co } void -EstimatedParamsBoundsStatement::writeJsonOutput(ostream &output) const +EstimatedParamsBoundsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "estimated_params_bounds", )" << R"("params": [)"; - for (bool printed_something{false}; - const auto &it : estim_params_list) + for (bool printed_something {false}; const auto& it : estim_params_list) { if (exchange(printed_something, true)) output << ", "; @@ -1726,18 +1731,18 @@ EstimatedParamsBoundsStatement::writeJsonOutput(ostream &output) const << "}"; } -EstimatedParamsRemoveStatement::EstimatedParamsRemoveStatement(vector estim_params_list_arg, - const SymbolTable &symbol_table_arg) : - estim_params_list{move(estim_params_list_arg)}, - symbol_table{symbol_table_arg} +EstimatedParamsRemoveStatement::EstimatedParamsRemoveStatement( + vector estim_params_list_arg, const SymbolTable& symbol_table_arg) : + estim_params_list {move(estim_params_list_arg)}, symbol_table {symbol_table_arg} { } void -EstimatedParamsRemoveStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +EstimatedParamsRemoveStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { - for (const auto &it : estim_params_list) + for (const auto& it : estim_params_list) { int tsid = symbol_table.getTypeSpecificID(it.name) + 1; SymbolType symb_type = symbol_table.getType(it.name); @@ -1747,42 +1752,54 @@ EstimatedParamsRemoveStatement::writeOutput(ostream &output, [[maybe_unused]] co if (symb_type == SymbolType::exogenous) output << "tmp1 = find(estim_params_.var_exo(:,1)==" << tsid << ");" << endl << "if isempty(tmp1)" << endl - << " error(sprintf('estimated_params_remove: the standard deviation of %s is not estimated.', M_.exo_names{" << tsid << "}))" << endl + << " error(sprintf('estimated_params_remove: the standard deviation of %s is " + "not estimated.', M_.exo_names{" + << tsid << "}))" << endl << "else" << endl << " estim_params_.var_exo(tmp1,:) = [];" << "end" << endl; else if (symb_type == SymbolType::endogenous) output << "tmp1 = find(estim_params_.var_endo(:,1)==" << tsid << ");" << endl << "if isempty(tmp1)" << endl - << " error(sprintf('estimated_params_remove: the standard deviation of the measurement error on %s is not estimated.', M_.endo_names{" << tsid << "}))" << endl + << " error(sprintf('estimated_params_remove: the standard deviation of the " + "measurement error on %s is not estimated.', M_.endo_names{" + << tsid << "}))" << endl << "else" << endl << " estim_params_.var_endo(tmp1,:) = [];" << "end" << endl; else if (symb_type == SymbolType::parameter) - output << "tmp1 = find(estim_params_.param_vals(:,1)==" << tsid << ");" << endl - << "if isempty(tmp1)" << endl - << " error(sprintf('estimated_params_remove: parameter %s is not estimated.', M_.param_names{" << tsid << "}))" << endl - << "else" << endl - << " estim_params_.param_vals(tmp1,:) = [];" - << "end" << endl; + output << "tmp1 = find(estim_params_.param_vals(:,1)==" << tsid << ");" << endl + << "if isempty(tmp1)" << endl + << " error(sprintf('estimated_params_remove: parameter %s is not " + "estimated.', M_.param_names{" + << tsid << "}))" << endl + << "else" << endl + << " estim_params_.param_vals(tmp1,:) = [];" + << "end" << endl; } else { int tsid2 = symbol_table.getTypeSpecificID(it.name2) + 1; if (symb_type == SymbolType::exogenous) - output << "tmp1 = find((estim_params_.corrx(:,1)==" << tsid << " & estim_params_.corrx(:,2)==" << tsid2 << ") | " - << "(estim_params_.corrx(:,2)==" << tsid << " & estim_params_.corrx(:,1)==" << tsid2 << "));" << endl - << "if isempty(tmp1)" << endl - << " error(sprintf('estimated_params_remove: the correlation between %s and %s is not estimated.', M_.exo_names{" - << tsid << "}, M_.exo_names{" << tsid2 << "}))" << endl - << "else" << endl - << " estim_params_.corrx(tmp1,:) = [];" - << "end" << endl; - else if (symb_type == SymbolType::endogenous) - output << "tmp1 = find((estim_params_.corrn(:,1)==" << tsid << " & estim_params_.corrn(:,2)==" << tsid2 << ") | " - << "(estim_params_.corrn(:,2)==" << tsid << " & estim_params_.corrn(:,1)==" << tsid2 << "));" << endl + output << "tmp1 = find((estim_params_.corrx(:,1)==" << tsid + << " & estim_params_.corrx(:,2)==" << tsid2 << ") | " + << "(estim_params_.corrx(:,2)==" << tsid + << " & estim_params_.corrx(:,1)==" << tsid2 << "));" << endl << "if isempty(tmp1)" << endl - << " error(sprintf('estimated_params_remove: the correlation between measurement errors on %s and %s is not estimated.', M_.endo_names{" + << " error(sprintf('estimated_params_remove: the correlation between %s and " + "%s is not estimated.', M_.exo_names{" + << tsid << "}, M_.exo_names{" << tsid2 << "}))" << endl + << "else" << endl + << " estim_params_.corrx(tmp1,:) = [];" + << "end" << endl; + else if (symb_type == SymbolType::endogenous) + output << "tmp1 = find((estim_params_.corrn(:,1)==" << tsid + << " & estim_params_.corrn(:,2)==" << tsid2 << ") | " + << "(estim_params_.corrn(:,2)==" << tsid + << " & estim_params_.corrn(:,1)==" << tsid2 << "));" << endl + << "if isempty(tmp1)" << endl + << " error(sprintf('estimated_params_remove: the correlation between " + "measurement errors on %s and %s is not estimated.', M_.endo_names{" << tsid << "}, M_.endo_names{" << tsid2 << "}))" << endl << "else" << endl << " estim_params_.corrn(tmp1,:) = [];" @@ -1792,13 +1809,12 @@ EstimatedParamsRemoveStatement::writeOutput(ostream &output, [[maybe_unused]] co } void -EstimatedParamsRemoveStatement::writeJsonOutput(ostream &output) const +EstimatedParamsRemoveStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "estimated_params_remove", )" << R"("params": [)"; - for (bool printed_something{false}; - const auto &it : estim_params_list) + for (bool printed_something {false}; const auto& it : estim_params_list) { if (exchange(printed_something, true)) output << ", "; @@ -1823,39 +1839,39 @@ EstimatedParamsRemoveStatement::writeJsonOutput(ostream &output) const } DeterministicTrendsStatement::DeterministicTrendsStatement(trend_elements_t trend_elements_arg, - const SymbolTable &symbol_table_arg) : - trend_elements{move(trend_elements_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + trend_elements {move(trend_elements_arg)}, symbol_table {symbol_table_arg} { } void -DeterministicTrendsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +DeterministicTrendsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "options_.trend_coeff = {};" << endl; - for (const auto &trend_element : trend_elements) + for (const auto& trend_element : trend_elements) { SymbolType type = symbol_table.getType(trend_element.first); if (type == SymbolType::endogenous) { - output << "tmp1 = strmatch('" << trend_element.first << "',M_.endogenous_names,'exact');" << endl; + output << "tmp1 = strmatch('" << trend_element.first << "',M_.endogenous_names,'exact');" + << endl; output << "options_.deterministic_trend_coeffs{tmp1} = '"; trend_element.second->writeOutput(output); output << "';" << endl; } else - cerr << "Warning : Non-variable symbol used in deterministic_trends: " << trend_element.first << endl; + cerr << "Warning : Non-variable symbol used in deterministic_trends: " + << trend_element.first << endl; } } void -DeterministicTrendsStatement::writeJsonOutput(ostream &output) const +DeterministicTrendsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "deterministic_trends", )" << R"("trends" : {)"; - for (bool printed_something{false}; - const auto &trend_element : trend_elements) + for (bool printed_something {false}; const auto& trend_element : trend_elements) { if (symbol_table.getType(trend_element.first) == SymbolType::endogenous) { @@ -1866,46 +1882,47 @@ DeterministicTrendsStatement::writeJsonOutput(ostream &output) const output << R"(")" << endl; } else - cerr << "Warning : Non-variable symbol used in deterministic_trends: " << trend_element.first << endl; + cerr << "Warning : Non-variable symbol used in deterministic_trends: " + << trend_element.first << endl; } output << "}" << "}"; } ObservationTrendsStatement::ObservationTrendsStatement(trend_elements_t trend_elements_arg, - const SymbolTable &symbol_table_arg) : - trend_elements{move(trend_elements_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + trend_elements {move(trend_elements_arg)}, symbol_table {symbol_table_arg} { } void -ObservationTrendsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +ObservationTrendsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "options_.trend_coeff = {};" << endl; - for (const auto &trend_element : trend_elements) + for (const auto& trend_element : trend_elements) { SymbolType type = symbol_table.getType(trend_element.first); if (type == SymbolType::endogenous) { - output << "tmp1 = strmatch('" << trend_element.first << "',options_.varobs,'exact');" << endl; + output << "tmp1 = strmatch('" << trend_element.first << "',options_.varobs,'exact');" + << endl; output << "options_.trend_coeffs{tmp1} = '"; trend_element.second->writeOutput(output); output << "';" << endl; } else - cerr << "Warning : Non-variable symbol used in observation_trends: " << trend_element.first << endl; + cerr << "Warning : Non-variable symbol used in observation_trends: " << trend_element.first + << endl; } } void -ObservationTrendsStatement::writeJsonOutput(ostream &output) const +ObservationTrendsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "observation_trends", )" << R"("trends" : {)"; - for (bool printed_something{false}; - const auto &trend_element : trend_elements) + for (bool printed_something {false}; const auto& trend_element : trend_elements) { if (symbol_table.getType(trend_element.first) == SymbolType::endogenous) { @@ -1916,25 +1933,27 @@ ObservationTrendsStatement::writeJsonOutput(ostream &output) const output << R"(")" << endl; } else - cerr << "Warning : Non-variable symbol used in observation_trends: " << trend_element.first << endl; + cerr << "Warning : Non-variable symbol used in observation_trends: " << trend_element.first + << endl; } output << "}" << "}"; } -FilterInitialStateStatement::FilterInitialStateStatement(filter_initial_state_elements_t filter_initial_state_elements_arg, - const SymbolTable &symbol_table_arg) : - filter_initial_state_elements{move(filter_initial_state_elements_arg)}, - symbol_table{symbol_table_arg} +FilterInitialStateStatement::FilterInitialStateStatement( + filter_initial_state_elements_t filter_initial_state_elements_arg, + const SymbolTable& symbol_table_arg) : + filter_initial_state_elements {move(filter_initial_state_elements_arg)}, + symbol_table {symbol_table_arg} { } void -FilterInitialStateStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +FilterInitialStateStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "M_.filter_initial_state = cell(M_.endo_nbr, 2);" << endl; - for (const auto &[key, val] : filter_initial_state_elements) + for (const auto& [key, val] : filter_initial_state_elements) { auto [symb_id, lag] = key; SymbolType type = symbol_table.getType(symb_id); @@ -1946,7 +1965,7 @@ FilterInitialStateStatement::writeOutput(ostream &output, [[maybe_unused]] const // This function call must remain the 1st statement in this block symb_id = symbol_table.searchAuxiliaryVars(symb_id, lag); } - catch (SymbolTable::SearchFailedException &e) + catch (SymbolTable::SearchFailedException& e) { if (type == SymbolType::endogenous) { @@ -1958,8 +1977,7 @@ FilterInitialStateStatement::writeOutput(ostream &output, [[maybe_unused]] const } } - output << "M_.filter_initial_state(" - << symbol_table.getTypeSpecificID(symb_id) + 1 + output << "M_.filter_initial_state(" << symbol_table.getTypeSpecificID(symb_id) + 1 << ",:) = {'" << symbol_table.getName(symb_id) << "', '"; val->writeOutput(output); output << ";'};" << endl; @@ -1967,19 +1985,17 @@ FilterInitialStateStatement::writeOutput(ostream &output, [[maybe_unused]] const } void -FilterInitialStateStatement::writeJsonOutput(ostream &output) const +FilterInitialStateStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "filter_initial_state", )" << R"("states": [)"; - for (bool printed_something{false}; - const auto &[key, val] : filter_initial_state_elements) + for (bool printed_something {false}; const auto& [key, val] : filter_initial_state_elements) { if (exchange(printed_something, true)) output << ", "; - auto &[symb_id, lag] = key; - output << R"({ "var": ")" << symbol_table.getName(symb_id) - << R"(", "lag": )" << lag + auto& [symb_id, lag] = key; + output << R"({ "var": ")" << symbol_table.getName(symb_id) << R"(", "lag": )" << lag << R"(, "value": ")"; val->writeJsonOutput(output, {}, {}); output << R"(" })"; @@ -1987,14 +2003,14 @@ FilterInitialStateStatement::writeJsonOutput(ostream &output) const output << "] }"; } -OsrParamsStatement::OsrParamsStatement(SymbolList symbol_list_arg, const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - symbol_table{symbol_table_arg} +OsrParamsStatement::OsrParamsStatement(SymbolList symbol_list_arg, + const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, symbol_table {symbol_table_arg} { } void -OsrParamsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +OsrParamsStatement::checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) { if (mod_file_struct.osr_params_present) cerr << "WARNING: You have more than one osr_params statement in the .mod file." << endl; @@ -2002,9 +2018,9 @@ OsrParamsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolid try { - symbol_list.checkPass(warnings, { SymbolType::parameter }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::parameter}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: osr: " << e.message << endl; exit(EXIT_FAILURE); @@ -2012,19 +2028,19 @@ OsrParamsStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolid } void -OsrParamsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +OsrParamsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { symbol_list.writeOutput("M_.osr.param_names", output); output << "M_.osr.param_names = cellstr(M_.osr.param_names);" << endl << "M_.osr.param_indices = zeros(length(M_.osr.param_names), 1);" << endl; - for (int i{0}; - auto &symbol : symbol_list.getSymbols()) - output << "M_.osr.param_indices(" << ++i <<") = " << symbol_table.getTypeSpecificID(symbol) + 1 << ";" << endl; + for (int i {0}; auto& symbol : symbol_list.getSymbols()) + output << "M_.osr.param_indices(" << ++i << ") = " << symbol_table.getTypeSpecificID(symbol) + 1 + << ";" << endl; } void -OsrParamsStatement::writeJsonOutput(ostream &output) const +OsrParamsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "osr_params")"; if (!symbol_list.empty()) @@ -2036,29 +2052,32 @@ OsrParamsStatement::writeJsonOutput(ostream &output) const } OsrParamsBoundsStatement::OsrParamsBoundsStatement(vector osr_params_list_arg) : - osr_params_list{move(osr_params_list_arg)} + osr_params_list {move(osr_params_list_arg)} { } void -OsrParamsBoundsStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +OsrParamsBoundsStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { if (!mod_file_struct.osr_params_present) { - cerr << "ERROR: you must have an osr_params statement before the osr_params_bounds block." << endl; + cerr << "ERROR: you must have an osr_params statement before the osr_params_bounds block." + << endl; exit(EXIT_FAILURE); } } void -OsrParamsBoundsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +OsrParamsBoundsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { - output << "M_.osr.param_bounds = [-inf(length(M_.osr.param_names), 1), inf(length(M_.osr.param_names), 1)];" << endl; + output << "M_.osr.param_bounds = [-inf(length(M_.osr.param_names), 1), " + "inf(length(M_.osr.param_names), 1)];" + << endl; - for (const auto &it : osr_params_list) + for (const auto& it : osr_params_list) { output << "M_.osr.param_bounds(strcmp(M_.osr.param_names, '" << it.name << "'), :) = ["; it.low_bound->writeOutput(output); @@ -2069,12 +2088,11 @@ OsrParamsBoundsStatement::writeOutput(ostream &output, [[maybe_unused]] const st } void -OsrParamsBoundsStatement::writeJsonOutput(ostream &output) const +OsrParamsBoundsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "osr_params_bounds")" << R"(, "bounds": [)"; - for (bool printed_something{false}; - const auto &it : osr_params_list) + for (bool printed_something {false}; const auto& it : osr_params_list) { if (exchange(printed_something, true)) output << ", "; @@ -2091,15 +2109,15 @@ OsrParamsBoundsStatement::writeJsonOutput(ostream &output) const } OsrStatement::OsrStatement(SymbolList symbol_list_arg, OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - options_list{move(options_list_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, + options_list {move(options_list_arg)}, + symbol_table {symbol_table_arg} { } void -OsrStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +OsrStatement::checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) { mod_file_struct.osr_present = true; @@ -2117,7 +2135,6 @@ OsrStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation opt && *opt == "1") mod_file_struct.osr_analytic_derivation = true; - // Option k_order_solver (implicit when order >= 3) if (auto opt = options_list.get_if("k_order_solver"); (opt && *opt == "true") || mod_file_struct.order_option >= 3) @@ -2125,9 +2142,9 @@ OsrStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation try { - symbol_list.checkPass(warnings, { SymbolType::endogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: osr: " << e.message << endl; exit(EXIT_FAILURE); @@ -2135,7 +2152,7 @@ OsrStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation } void -OsrStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +OsrStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { // Ensure that order 3 implies k_order (#844) @@ -2146,11 +2163,13 @@ OsrStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basena options_list.writeOutput(output); symbol_list.writeOutput("var_list_", output); - output << "[info, oo_, options_, M_] = osr.run(M_, options_, oo_, var_list_,M_.osr.param_names,M_.osr.variable_indices,M_.osr.variable_weights);" << endl; + output << "[info, oo_, options_, M_] = osr.run(M_, options_, oo_, " + "var_list_,M_.osr.param_names,M_.osr.variable_indices,M_.osr.variable_weights);" + << endl; } void -OsrStatement::writeJsonOutput(ostream &output) const +OsrStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "osr")"; if (!options_list.empty()) @@ -2168,31 +2187,32 @@ OsrStatement::writeJsonOutput(ostream &output) const OptimWeightsStatement::OptimWeightsStatement(var_weights_t var_weights_arg, covar_weights_t covar_weights_arg, - const SymbolTable &symbol_table_arg) : - var_weights{move(var_weights_arg)}, - covar_weights{move(covar_weights_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + var_weights {move(var_weights_arg)}, + covar_weights {move(covar_weights_arg)}, + symbol_table {symbol_table_arg} { } void -OptimWeightsStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +OptimWeightsStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.optim_weights_present = true; } void -OptimWeightsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +OptimWeightsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "%" << endl << "% OPTIM_WEIGHTS" << endl << "%" << endl << "M_.osr.variable_weights = sparse(M_.endo_nbr,M_.endo_nbr);" << endl - << "M_.osr.variable_indices = [];" << endl << endl; + << "M_.osr.variable_indices = [];" << endl + << endl; - for (const auto & [name, value] : var_weights) + for (const auto& [name, value] : var_weights) { int id = symbol_table.getTypeSpecificID(name) + 1; output << "M_.osr.variable_weights(" << id << "," << id << ") = "; @@ -2201,24 +2221,25 @@ OptimWeightsStatement::writeOutput(ostream &output, [[maybe_unused]] const strin output << "M_.osr.variable_indices = [M_.osr.variable_indices; " << id << "];" << endl; } - for (const auto & [names, value] : covar_weights) + for (const auto& [names, value] : covar_weights) { int id1 = symbol_table.getTypeSpecificID(names.first) + 1; int id2 = symbol_table.getTypeSpecificID(names.second) + 1; output << "M_.osr.variable_weights(" << id1 << "," << id2 << ") = "; value->writeOutput(output); output << ";" << endl; - output << "M_.osr.variable_indices = [M_.osr.variable_indices; " << id1 << "; " << id2 << "];" << endl; + output << "M_.osr.variable_indices = [M_.osr.variable_indices; " << id1 << "; " << id2 << "];" + << endl; } } void -OptimWeightsStatement::writeJsonOutput(ostream &output) const +OptimWeightsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "optim_weights", )" << R"("weights": [)"; - bool printed_something{false}; - for (const auto &[name, value] : var_weights) + bool printed_something {false}; + for (const auto& [name, value] : var_weights) { if (exchange(printed_something, true)) output << ", "; @@ -2228,7 +2249,7 @@ OptimWeightsStatement::writeJsonOutput(ostream &output) const output << R"("})"; } - for (const auto &[names, value] : covar_weights) + for (const auto& [names, value] : covar_weights) { if (exchange(printed_something, true)) output << ", "; @@ -2242,22 +2263,23 @@ OptimWeightsStatement::writeJsonOutput(ostream &output) const } DynaSaveStatement::DynaSaveStatement(SymbolList symbol_list_arg, string filename_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - filename{move(filename_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, + filename {move(filename_arg)}, + symbol_table {symbol_table_arg} { } void -DynaSaveStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - WarningConsolidation &warnings) +DynaSaveStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + WarningConsolidation& warnings) { try { - symbol_list.checkPass(warnings, { SymbolType::endogenous, SymbolType::exogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous, SymbolType::exogenous}, + symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: dynasave: " << e.message << endl; exit(EXIT_FAILURE); @@ -2265,16 +2287,15 @@ DynaSaveStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, } void -DynaSaveStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +DynaSaveStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { symbol_list.writeOutput("var_list_", output); - output << "dynasave('" << filename - << "',var_list_);" << endl; + output << "dynasave('" << filename << "',var_list_);" << endl; } void -DynaSaveStatement::writeJsonOutput(ostream &output) const +DynaSaveStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "dynasave", )" << R"("filename": ")" << filename << R"(")"; @@ -2287,22 +2308,23 @@ DynaSaveStatement::writeJsonOutput(ostream &output) const } DynaTypeStatement::DynaTypeStatement(SymbolList symbol_list_arg, string filename_arg, - const SymbolTable &symbol_table_arg) : - symbol_list(move(symbol_list_arg)), - filename(move(filename_arg)), - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + symbol_list(move(symbol_list_arg)), + filename(move(filename_arg)), + symbol_table {symbol_table_arg} { } void -DynaTypeStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - WarningConsolidation &warnings) +DynaTypeStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + WarningConsolidation& warnings) { try { - symbol_list.checkPass(warnings, { SymbolType::endogenous, SymbolType::exogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous, SymbolType::exogenous}, + symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: dynatype: " << e.message << endl; exit(EXIT_FAILURE); @@ -2310,16 +2332,15 @@ DynaTypeStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, } void -DynaTypeStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +DynaTypeStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { symbol_list.writeOutput("var_list_", output); - output << "dynatype('" << filename - << "',var_list_);" << endl; + output << "dynatype('" << filename << "',var_list_);" << endl; } void -DynaTypeStatement::writeJsonOutput(ostream &output) const +DynaTypeStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "dynatype", )" << R"("filename": ")" << filename << R"(")"; @@ -2333,21 +2354,19 @@ DynaTypeStatement::writeJsonOutput(ostream &output) const ModelComparisonStatement::ModelComparisonStatement(filename_list_t filename_list_arg, OptionsList options_list_arg) : - filename_list{move(filename_list_arg)}, - options_list{move(options_list_arg)} + filename_list {move(filename_list_arg)}, options_list {move(options_list_arg)} { } void -ModelComparisonStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +ModelComparisonStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); - output << "ModelNames_ = {};" << endl - << "ModelPriors_ = [];" << endl; + output << "ModelNames_ = {};" << endl << "ModelPriors_ = [];" << endl; - for (const auto &[name, prior] : filename_list) + for (const auto& [name, prior] : filename_list) output << "ModelNames_ = { ModelNames_{:} '" << name << "'};" << endl << "ModelPriors_ = [ ModelPriors_ ; " << prior << "];" << endl; @@ -2355,14 +2374,13 @@ ModelComparisonStatement::writeOutput(ostream &output, [[maybe_unused]] const st } void -ModelComparisonStatement::writeJsonOutput(ostream &output) const +ModelComparisonStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "model_comparison")"; if (!filename_list.empty()) output << R"(, "filename_list": {)"; - for (bool printed_something{false}; - const auto &[name, prior] : filename_list) + for (bool printed_something {false}; const auto& [name, prior] : filename_list) { if (exchange(printed_something, true)) output << ", "; @@ -2382,19 +2400,20 @@ ModelComparisonStatement::writeJsonOutput(ostream &output) const output << "}"; } -PlannerObjectiveStatement::PlannerObjectiveStatement(const PlannerObjective &model_tree_arg) : - model_tree{model_tree_arg} +PlannerObjectiveStatement::PlannerObjectiveStatement(const PlannerObjective& model_tree_arg) : + model_tree {model_tree_arg} { } void -PlannerObjectiveStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +PlannerObjectiveStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { assert(model_tree.equation_number() == 1); if (model_tree.exoPresentInEqs()) { - cerr << "ERROR: You cannot include exogenous variables (or variables of undeclared type) in the planner objective. Please " + cerr << "ERROR: You cannot include exogenous variables (or variables of undeclared type) in " + "the planner objective. Please " << "define an auxiliary endogenous variable like eps_aux=epsilon and use it instead " << "of the varexo." << endl; exit(EXIT_FAILURE); @@ -2402,36 +2421,36 @@ PlannerObjectiveStatement::checkPass(ModFileStructure &mod_file_struct, mod_file_struct.planner_objective_present = true; } -const PlannerObjective & +const PlannerObjective& PlannerObjectiveStatement::getPlannerObjective() const { return model_tree; } void -PlannerObjectiveStatement::computingPass(const ModFileStructure &mod_file_struct) +PlannerObjectiveStatement::computingPass(const ModFileStructure& mod_file_struct) { model_tree.computingPass(max(3, mod_file_struct.order_option), 0, {}, false, false, false); computing_pass_called = true; } void -PlannerObjectiveStatement::writeOutput(ostream &output, const string &basename, +PlannerObjectiveStatement::writeOutput(ostream& output, const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "M_.NNZDerivatives_objective = ["; - for (int i=1; i < static_cast(model_tree.getNNZDerivatives().size()); i++) - output << (i > model_tree.getComputedDerivsOrder() ? -1 : model_tree.getNNZDerivatives()[i]) << ";"; - output << "];" << endl - << "M_.objective_tmp_nbr = ["; - for (const auto &temporary_terms_derivative : model_tree.getTemporaryTermsDerivatives()) + for (int i = 1; i < static_cast(model_tree.getNNZDerivatives().size()); i++) + output << (i > model_tree.getComputedDerivsOrder() ? -1 : model_tree.getNNZDerivatives()[i]) + << ";"; + output << "];" << endl << "M_.objective_tmp_nbr = ["; + for (const auto& temporary_terms_derivative : model_tree.getTemporaryTermsDerivatives()) output << temporary_terms_derivative.size() << "; "; output << "];" << endl; model_tree.writeStaticFile(basename + ".objective", false, "", {}, false); } void -PlannerObjectiveStatement::writeJsonOutput(ostream &output) const +PlannerObjectiveStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "planner_objective")" << ", "; @@ -2444,20 +2463,19 @@ PlannerObjectiveStatement::writeJsonOutput(ostream &output) const } BVARDensityStatement::BVARDensityStatement(int maxnlags_arg, OptionsList options_list_arg) : - maxnlags{maxnlags_arg}, - options_list{move(options_list_arg)} + maxnlags {maxnlags_arg}, options_list {move(options_list_arg)} { } void -BVARDensityStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +BVARDensityStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.bvar_present = true; } void -BVARDensityStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +BVARDensityStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); @@ -2465,7 +2483,7 @@ BVARDensityStatement::writeOutput(ostream &output, [[maybe_unused]] const string } void -BVARDensityStatement::writeJsonOutput(ostream &output) const +BVARDensityStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "bvar_density")"; if (!options_list.empty()) @@ -2477,20 +2495,19 @@ BVARDensityStatement::writeJsonOutput(ostream &output) const } BVARForecastStatement::BVARForecastStatement(int nlags_arg, OptionsList options_list_arg) : - nlags{nlags_arg}, - options_list{move(options_list_arg)} + nlags {nlags_arg}, options_list {move(options_list_arg)} { } void -BVARForecastStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +BVARForecastStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.bvar_present = true; } void -BVARForecastStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +BVARForecastStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); @@ -2498,7 +2515,7 @@ BVARForecastStatement::writeOutput(ostream &output, [[maybe_unused]] const strin } void -BVARForecastStatement::writeJsonOutput(ostream &output) const +BVARForecastStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "bvar_forecast")"; if (!options_list.empty()) @@ -2510,46 +2527,44 @@ BVARForecastStatement::writeJsonOutput(ostream &output) const } BVARIRFStatement::BVARIRFStatement(int nirf_arg, string identificationname_arg) : - nirf{nirf_arg}, - identificationname{move(identificationname_arg)} + nirf {nirf_arg}, identificationname {move(identificationname_arg)} { } void -BVARIRFStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +BVARIRFStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.bvar_present = true; } void -BVARIRFStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +BVARIRFStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "bvar.irf(" << nirf << ",'" << identificationname << "');" << endl; } void -BVARIRFStatement::writeJsonOutput(ostream &output) const +BVARIRFStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "bvar_irf")"; output << "}"; } -SBVARStatement::SBVARStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} +SBVARStatement::SBVARStatement(OptionsList options_list_arg) : options_list {move(options_list_arg)} { } void -SBVARStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +SBVARStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.bvar_present = true; } void -SBVARStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +SBVARStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); @@ -2557,7 +2572,7 @@ SBVARStatement::writeOutput(ostream &output, [[maybe_unused]] const string &base } void -SBVARStatement::writeJsonOutput(ostream &output) const +SBVARStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "sbvar")"; if (!options_list.empty()) @@ -2569,19 +2584,18 @@ SBVARStatement::writeJsonOutput(ostream &output) const } MSSBVAREstimationStatement::MSSBVAREstimationStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -MSSBVAREstimationStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +MSSBVAREstimationStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.bvar_present = true; if (!options_list.contains("ms.create_init") - && (!options_list.contains("datafile") - || !options_list.contains("ms.initial_year"))) + && (!options_list.contains("datafile") || !options_list.contains("ms.initial_year"))) { cerr << "ERROR: If you do not pass no_create_init to ms_estimation, " << "you must pass the datafile and initial_year options." << endl; @@ -2590,7 +2604,7 @@ MSSBVAREstimationStatement::checkPass(ModFileStructure &mod_file_struct, } void -MSSBVAREstimationStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +MSSBVAREstimationStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl @@ -2600,7 +2614,7 @@ MSSBVAREstimationStatement::writeOutput(ostream &output, [[maybe_unused]] const } void -MSSBVAREstimationStatement::writeJsonOutput(ostream &output) const +MSSBVAREstimationStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "ms_sbvar_estimation")"; if (!options_list.empty()) @@ -2612,27 +2626,26 @@ MSSBVAREstimationStatement::writeJsonOutput(ostream &output) const } MSSBVARSimulationStatement::MSSBVARSimulationStatement(OptionsList options_list_arg) : - options_list(move(options_list_arg)) + options_list(move(options_list_arg)) { } void -MSSBVARSimulationStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +MSSBVARSimulationStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.bvar_present = true; } void -MSSBVARSimulationStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +MSSBVARSimulationStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl; options_list.writeOutput(output); // Redeclare drop option if necessary - if ((options_list.contains("ms.mh_replic") - || options_list.contains("ms.thinning_factor")) + if ((options_list.contains("ms.mh_replic") || options_list.contains("ms.thinning_factor")) && !options_list.contains("ms.drop")) output << "options_.ms.drop = 0.1*options_.ms.mh_replic*options_.ms.thinning_factor;" << endl; @@ -2640,7 +2653,7 @@ MSSBVARSimulationStatement::writeOutput(ostream &output, [[maybe_unused]] const } void -MSSBVARSimulationStatement::writeJsonOutput(ostream &output) const +MSSBVARSimulationStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "ms_sbvar_simulation")"; if (!options_list.empty()) @@ -2652,19 +2665,19 @@ MSSBVARSimulationStatement::writeJsonOutput(ostream &output) const } MSSBVARComputeMDDStatement::MSSBVARComputeMDDStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -MSSBVARComputeMDDStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +MSSBVARComputeMDDStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.bvar_present = true; } void -MSSBVARComputeMDDStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +MSSBVARComputeMDDStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl; @@ -2673,7 +2686,7 @@ MSSBVARComputeMDDStatement::writeOutput(ostream &output, [[maybe_unused]] const } void -MSSBVARComputeMDDStatement::writeJsonOutput(ostream &output) const +MSSBVARComputeMDDStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "ms_sbvar_compute_mdd")"; if (!options_list.empty()) @@ -2684,14 +2697,15 @@ MSSBVARComputeMDDStatement::writeJsonOutput(ostream &output) const output << "}"; } -MSSBVARComputeProbabilitiesStatement::MSSBVARComputeProbabilitiesStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} +MSSBVARComputeProbabilitiesStatement::MSSBVARComputeProbabilitiesStatement( + OptionsList options_list_arg) : + options_list {move(options_list_arg)} { } void -MSSBVARComputeProbabilitiesStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +MSSBVARComputeProbabilitiesStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.bvar_present = true; @@ -2705,8 +2719,8 @@ MSSBVARComputeProbabilitiesStatement::checkPass(ModFileStructure &mod_file_struc } void -MSSBVARComputeProbabilitiesStatement::writeOutput(ostream &output, - [[maybe_unused]] const string &basename, +MSSBVARComputeProbabilitiesStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl; @@ -2715,7 +2729,7 @@ MSSBVARComputeProbabilitiesStatement::writeOutput(ostream &output, } void -MSSBVARComputeProbabilitiesStatement::writeJsonOutput(ostream &output) const +MSSBVARComputeProbabilitiesStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "ms_sbvar_compute_probabilities")"; if (!options_list.empty()) @@ -2727,15 +2741,15 @@ MSSBVARComputeProbabilitiesStatement::writeJsonOutput(ostream &output) const } MSSBVARIrfStatement::MSSBVARIrfStatement(SymbolList symbol_list_arg, OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - options_list{move(options_list_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, + options_list {move(options_list_arg)}, + symbol_table {symbol_table_arg} { } void -MSSBVARIrfStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +MSSBVARIrfStatement::checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) { mod_file_struct.bvar_present = true; @@ -2743,8 +2757,7 @@ MSSBVARIrfStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsoli regimes_present = options_list.contains("ms.regimes"), filtered_probabilities_present = options_list.contains("ms.filtered_probabilities"); (filtered_probabilities_present && regime_present) - || (filtered_probabilities_present && regimes_present) - || (regimes_present && regime_present)) + || (filtered_probabilities_present && regimes_present) || (regimes_present && regime_present)) { cerr << "ERROR: You may only pass one of regime, regimes and " << "filtered_probabilities to ms_irf" << endl; @@ -2753,9 +2766,9 @@ MSSBVARIrfStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsoli try { - symbol_list.checkPass(warnings, { SymbolType::endogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: ms_irf: " << e.message << endl; exit(EXIT_FAILURE); @@ -2763,7 +2776,7 @@ MSSBVARIrfStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsoli } void -MSSBVARIrfStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +MSSBVARIrfStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl; @@ -2773,7 +2786,7 @@ MSSBVARIrfStatement::writeOutput(ostream &output, [[maybe_unused]] const string } void -MSSBVARIrfStatement::writeJsonOutput(ostream &output) const +MSSBVARIrfStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "ms_sbvar_irf")"; if (!options_list.empty()) @@ -2790,18 +2803,17 @@ MSSBVARIrfStatement::writeJsonOutput(ostream &output) const } MSSBVARForecastStatement::MSSBVARForecastStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -MSSBVARForecastStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +MSSBVARForecastStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.bvar_present = true; - if (options_list.contains("ms.regimes") - && options_list.contains("ms.regime")) + if (options_list.contains("ms.regimes") && options_list.contains("ms.regime")) { cerr << "ERROR: You may only pass one of regime and regimes to ms_forecast" << endl; exit(EXIT_FAILURE); @@ -2809,7 +2821,7 @@ MSSBVARForecastStatement::checkPass(ModFileStructure &mod_file_struct, } void -MSSBVARForecastStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +MSSBVARForecastStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl; @@ -2818,7 +2830,7 @@ MSSBVARForecastStatement::writeOutput(ostream &output, [[maybe_unused]] const st } void -MSSBVARForecastStatement::writeJsonOutput(ostream &output) const +MSSBVARForecastStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "ms_sbvar_forecast")"; if (!options_list.empty()) @@ -2829,14 +2841,15 @@ MSSBVARForecastStatement::writeJsonOutput(ostream &output) const output << "}"; } -MSSBVARVarianceDecompositionStatement::MSSBVARVarianceDecompositionStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} +MSSBVARVarianceDecompositionStatement::MSSBVARVarianceDecompositionStatement( + OptionsList options_list_arg) : + options_list {move(options_list_arg)} { } void -MSSBVARVarianceDecompositionStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +MSSBVARVarianceDecompositionStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.bvar_present = true; @@ -2844,8 +2857,7 @@ MSSBVARVarianceDecompositionStatement::checkPass(ModFileStructure &mod_file_stru regimes_present = options_list.contains("ms.regimes"), filtered_probabilities_present = options_list.contains("ms.filtered_probabilities"); (filtered_probabilities_present && regime_present) - || (filtered_probabilities_present && regimes_present) - || (regimes_present && regime_present)) + || (filtered_probabilities_present && regimes_present) || (regimes_present && regime_present)) { cerr << "ERROR: You may only pass one of regime, regimes and " << "filtered_probabilities to ms_variance_decomposition" << endl; @@ -2854,8 +2866,8 @@ MSSBVARVarianceDecompositionStatement::checkPass(ModFileStructure &mod_file_stru } void -MSSBVARVarianceDecompositionStatement::writeOutput(ostream &output, - [[maybe_unused]] const string &basename, +MSSBVARVarianceDecompositionStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "options_ = initialize_ms_sbvar_options(M_, options_);" << endl; @@ -2864,7 +2876,7 @@ MSSBVARVarianceDecompositionStatement::writeOutput(ostream &output, } void -MSSBVARVarianceDecompositionStatement::writeJsonOutput(ostream &output) const +MSSBVARVarianceDecompositionStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "ms_sbvar_variance_decomposition")"; if (!options_list.empty()) @@ -2875,20 +2887,21 @@ MSSBVARVarianceDecompositionStatement::writeJsonOutput(ostream &output) const output << "}"; } -IdentificationStatement::IdentificationStatement(OptionsList options_list_arg) - : options_list{move(options_list_arg)} +IdentificationStatement::IdentificationStatement(OptionsList options_list_arg) : + options_list {move(options_list_arg)} { if (auto opt = options_list.get_if("max_dim_cova_group"); opt && stoi(*opt) == 0) { - cerr << "ERROR: The max_dim_cova_group option to identification only accepts integers > 0." << endl; + cerr << "ERROR: The max_dim_cova_group option to identification only accepts integers > 0." + << endl; exit(EXIT_FAILURE); } } void -IdentificationStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +IdentificationStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.identification_present = true; @@ -2897,19 +2910,21 @@ IdentificationStatement::checkPass(ModFileStructure &mod_file_struct, int order = stoi(*opt); if (order < 1 || order > 3) { - cerr << "ERROR: the order option of identification command must be between 1 and 3" << endl; + cerr << "ERROR: the order option of identification command must be between 1 and 3" + << endl; exit(EXIT_FAILURE); } mod_file_struct.identification_order = max(mod_file_struct.identification_order, order); } else - // The default value for order is 1 (which triggers 2nd order dynamic derivatives, see preprocessor#40) + // The default value for order is 1 (which triggers 2nd order dynamic derivatives, see + // preprocessor#40) mod_file_struct.identification_order = max(mod_file_struct.identification_order, 1); } void -IdentificationStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +IdentificationStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output, "options_ident"); @@ -2930,7 +2945,7 @@ IdentificationStatement::writeOutput(ostream &output, [[maybe_unused]] const str } void -IdentificationStatement::writeJsonOutput(ostream &output) const +IdentificationStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "identification")"; if (!options_list.empty()) @@ -2941,100 +2956,105 @@ IdentificationStatement::writeJsonOutput(ostream &output) const output << "}"; } -WriteLatexDynamicModelStatement::WriteLatexDynamicModelStatement(const DynamicModel &dynamic_model_arg, bool write_equation_tags_arg) : - dynamic_model{dynamic_model_arg}, - write_equation_tags{write_equation_tags_arg} +WriteLatexDynamicModelStatement::WriteLatexDynamicModelStatement( + const DynamicModel& dynamic_model_arg, bool write_equation_tags_arg) : + dynamic_model {dynamic_model_arg}, write_equation_tags {write_equation_tags_arg} { } void -WriteLatexDynamicModelStatement::writeOutput([[maybe_unused]] ostream &output, const string &basename, +WriteLatexDynamicModelStatement::writeOutput([[maybe_unused]] ostream& output, + const string& basename, [[maybe_unused]] bool minimal_workspace) const { dynamic_model.writeLatexFile(basename, write_equation_tags); } void -WriteLatexDynamicModelStatement::writeJsonOutput(ostream &output) const +WriteLatexDynamicModelStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "write_latex_dynamic_model"})"; } -WriteLatexStaticModelStatement::WriteLatexStaticModelStatement(const StaticModel &static_model_arg, bool write_equation_tags_arg) : - static_model(static_model_arg), - write_equation_tags(write_equation_tags_arg) +WriteLatexStaticModelStatement::WriteLatexStaticModelStatement(const StaticModel& static_model_arg, + bool write_equation_tags_arg) : + static_model(static_model_arg), write_equation_tags(write_equation_tags_arg) { } void -WriteLatexStaticModelStatement::writeOutput([[maybe_unused]] ostream &output, const string &basename, +WriteLatexStaticModelStatement::writeOutput([[maybe_unused]] ostream& output, + const string& basename, [[maybe_unused]] bool minimal_workspace) const { static_model.writeLatexFile(basename, write_equation_tags); } void -WriteLatexStaticModelStatement::writeJsonOutput(ostream &output) const +WriteLatexStaticModelStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "write_latex_static_model"})"; } -WriteLatexOriginalModelStatement::WriteLatexOriginalModelStatement(const DynamicModel &original_model_arg, bool write_equation_tags_arg) : - original_model{original_model_arg}, - write_equation_tags{write_equation_tags_arg} +WriteLatexOriginalModelStatement::WriteLatexOriginalModelStatement( + const DynamicModel& original_model_arg, bool write_equation_tags_arg) : + original_model {original_model_arg}, write_equation_tags {write_equation_tags_arg} { } void -WriteLatexOriginalModelStatement::writeOutput([[maybe_unused]] ostream &output, const string &basename, +WriteLatexOriginalModelStatement::writeOutput([[maybe_unused]] ostream& output, + const string& basename, [[maybe_unused]] bool minimal_workspace) const { original_model.writeLatexOriginalFile(basename, write_equation_tags); } void -WriteLatexOriginalModelStatement::writeJsonOutput(ostream &output) const +WriteLatexOriginalModelStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "write_latex_original_model"})"; } -WriteLatexSteadyStateModelStatement::WriteLatexSteadyStateModelStatement(const SteadyStateModel &steady_state_model_arg) : - steady_state_model{steady_state_model_arg} +WriteLatexSteadyStateModelStatement::WriteLatexSteadyStateModelStatement( + const SteadyStateModel& steady_state_model_arg) : + steady_state_model {steady_state_model_arg} { } void -WriteLatexSteadyStateModelStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +WriteLatexSteadyStateModelStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.write_latex_steady_state_model_present = true; } void -WriteLatexSteadyStateModelStatement::writeOutput([[maybe_unused]] ostream &output, - const string &basename, +WriteLatexSteadyStateModelStatement::writeOutput([[maybe_unused]] ostream& output, + const string& basename, [[maybe_unused]] bool minimal_workspace) const { steady_state_model.writeLatexSteadyStateFile(basename); } void -WriteLatexSteadyStateModelStatement::writeJsonOutput(ostream &output) const +WriteLatexSteadyStateModelStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "write_latex_steady_state_model"})"; } ShockDecompositionStatement::ShockDecompositionStatement(SymbolList symbol_list_arg, OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - options_list{move(options_list_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, + options_list {move(options_list_arg)}, + symbol_table {symbol_table_arg} { } void -ShockDecompositionStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +ShockDecompositionStatement::checkPass(ModFileStructure& mod_file_struct, + WarningConsolidation& warnings) { if (auto opt = options_list.get_if("shock_decomp.with_epilogue"); opt && *opt == "true") @@ -3042,9 +3062,9 @@ ShockDecompositionStatement::checkPass(ModFileStructure &mod_file_struct, Warnin try { - symbol_list.checkPass(warnings, { SymbolType::endogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: shock_decomposition: " << e.message << endl; exit(EXIT_FAILURE); @@ -3052,16 +3072,17 @@ ShockDecompositionStatement::checkPass(ModFileStructure &mod_file_struct, Warnin } void -ShockDecompositionStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +ShockDecompositionStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); symbol_list.writeOutput("var_list_", output); - output << "oo_ = shock_decomposition(M_,oo_,options_,var_list_,bayestopt_,estim_params_);" << endl; + output << "oo_ = shock_decomposition(M_,oo_,options_,var_list_,bayestopt_,estim_params_);" + << endl; } void -ShockDecompositionStatement::writeJsonOutput(ostream &output) const +ShockDecompositionStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "shock_decomposition")"; if (!options_list.empty()) @@ -3077,17 +3098,17 @@ ShockDecompositionStatement::writeJsonOutput(ostream &output) const output << "}"; } -RealtimeShockDecompositionStatement::RealtimeShockDecompositionStatement(SymbolList symbol_list_arg, - OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - options_list{move(options_list_arg)}, - symbol_table{symbol_table_arg} +RealtimeShockDecompositionStatement::RealtimeShockDecompositionStatement( + SymbolList symbol_list_arg, OptionsList options_list_arg, const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, + options_list {move(options_list_arg)}, + symbol_table {symbol_table_arg} { } void -RealtimeShockDecompositionStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +RealtimeShockDecompositionStatement::checkPass(ModFileStructure& mod_file_struct, + WarningConsolidation& warnings) { if (auto opt = options_list.get_if("shock_decomp.with_epilogue"); opt && *opt == "true") @@ -3095,9 +3116,9 @@ RealtimeShockDecompositionStatement::checkPass(ModFileStructure &mod_file_struct try { - symbol_list.checkPass(warnings, { SymbolType::endogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: realtime_shock_decomposition: " << e.message << endl; exit(EXIT_FAILURE); @@ -3105,17 +3126,19 @@ RealtimeShockDecompositionStatement::checkPass(ModFileStructure &mod_file_struct } void -RealtimeShockDecompositionStatement::writeOutput(ostream &output, - [[maybe_unused]] const string &basename, +RealtimeShockDecompositionStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); symbol_list.writeOutput("var_list_", output); - output << "oo_ = realtime_shock_decomposition(M_,oo_,options_,var_list_,bayestopt_,estim_params_);" << endl; + output + << "oo_ = realtime_shock_decomposition(M_,oo_,options_,var_list_,bayestopt_,estim_params_);" + << endl; } void -RealtimeShockDecompositionStatement::writeJsonOutput(ostream &output) const +RealtimeShockDecompositionStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "realtime_shock_decomposition")"; if (!options_list.empty()) @@ -3131,24 +3154,23 @@ RealtimeShockDecompositionStatement::writeJsonOutput(ostream &output) const output << "}"; } -PlotShockDecompositionStatement::PlotShockDecompositionStatement(SymbolList symbol_list_arg, - OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - options_list{move(options_list_arg)}, - symbol_table{symbol_table_arg} +PlotShockDecompositionStatement::PlotShockDecompositionStatement( + SymbolList symbol_list_arg, OptionsList options_list_arg, const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, + options_list {move(options_list_arg)}, + symbol_table {symbol_table_arg} { } void -PlotShockDecompositionStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - WarningConsolidation &warnings) +PlotShockDecompositionStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + WarningConsolidation& warnings) { try { - symbol_list.checkPass(warnings, { SymbolType::endogenous, SymbolType::epilogue }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous, SymbolType::epilogue}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: plot_shock_decomposition: " << e.message << endl; exit(EXIT_FAILURE); @@ -3156,7 +3178,8 @@ PlotShockDecompositionStatement::checkPass([[maybe_unused]] ModFileStructure &mo } void -PlotShockDecompositionStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +PlotShockDecompositionStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "options_ = set_default_plot_shock_decomposition_options(options_);" << endl; @@ -3166,7 +3189,7 @@ PlotShockDecompositionStatement::writeOutput(ostream &output, [[maybe_unused]] c } void -PlotShockDecompositionStatement::writeJsonOutput(ostream &output) const +PlotShockDecompositionStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "plot_shock_decomposition")"; if (!options_list.empty()) @@ -3182,17 +3205,17 @@ PlotShockDecompositionStatement::writeJsonOutput(ostream &output) const output << "}"; } -InitialConditionDecompositionStatement::InitialConditionDecompositionStatement(SymbolList symbol_list_arg, - OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - options_list{move(options_list_arg)}, - symbol_table{symbol_table_arg} +InitialConditionDecompositionStatement::InitialConditionDecompositionStatement( + SymbolList symbol_list_arg, OptionsList options_list_arg, const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, + options_list {move(options_list_arg)}, + symbol_table {symbol_table_arg} { } void -InitialConditionDecompositionStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +InitialConditionDecompositionStatement::checkPass(ModFileStructure& mod_file_struct, + WarningConsolidation& warnings) { if (auto opt = options_list.get_if("initial_condition_decomp.with_epilogue"); opt && *opt == "true") @@ -3200,9 +3223,9 @@ InitialConditionDecompositionStatement::checkPass(ModFileStructure &mod_file_str try { - symbol_list.checkPass(warnings, { SymbolType::endogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: initial_condition_decomposition: " << e.message << endl; exit(EXIT_FAILURE); @@ -3210,18 +3233,20 @@ InitialConditionDecompositionStatement::checkPass(ModFileStructure &mod_file_str } void -InitialConditionDecompositionStatement::writeOutput(ostream &output, - [[maybe_unused]] const string &basename, +InitialConditionDecompositionStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "options_ = set_default_initial_condition_decomposition_options(options_);" << endl; options_list.writeOutput(output); symbol_list.writeOutput("var_list_", output); - output << "oo_ = initial_condition_decomposition(M_, oo_, options_, var_list_, bayestopt_, estim_params_);" << endl; + output << "oo_ = initial_condition_decomposition(M_, oo_, options_, var_list_, bayestopt_, " + "estim_params_);" + << endl; } void -InitialConditionDecompositionStatement::writeJsonOutput(ostream &output) const +InitialConditionDecompositionStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "initial_condition_decomposition")"; if (!options_list.empty()) @@ -3237,22 +3262,21 @@ InitialConditionDecompositionStatement::writeJsonOutput(ostream &output) const output << "}"; } -SqueezeShockDecompositionStatement::SqueezeShockDecompositionStatement(SymbolList symbol_list_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - symbol_table{symbol_table_arg} +SqueezeShockDecompositionStatement::SqueezeShockDecompositionStatement( + SymbolList symbol_list_arg, const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, symbol_table {symbol_table_arg} { } void -SqueezeShockDecompositionStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - WarningConsolidation &warnings) +SqueezeShockDecompositionStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + WarningConsolidation& warnings) { try { - symbol_list.checkPass(warnings, { SymbolType::endogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: squeeze_shock_decomposition: " << e.message << endl; exit(EXIT_FAILURE); @@ -3260,8 +3284,8 @@ SqueezeShockDecompositionStatement::checkPass([[maybe_unused]] ModFileStructure } void -SqueezeShockDecompositionStatement::writeOutput(ostream &output, - [[maybe_unused]] const string &basename, +SqueezeShockDecompositionStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { if (symbol_list.empty()) @@ -3274,7 +3298,7 @@ SqueezeShockDecompositionStatement::writeOutput(ostream &output, } void -SqueezeShockDecompositionStatement::writeJsonOutput(ostream &output) const +SqueezeShockDecompositionStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "squeeze_shock_decomposition")"; if (!symbol_list.empty()) @@ -3286,13 +3310,13 @@ SqueezeShockDecompositionStatement::writeJsonOutput(ostream &output) const } ConditionalForecastStatement::ConditionalForecastStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -ConditionalForecastStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +ConditionalForecastStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { if (!options_list.contains("parameter_set")) { @@ -3302,7 +3326,7 @@ ConditionalForecastStatement::checkPass([[maybe_unused]] ModFileStructure &mod_f } void -ConditionalForecastStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +ConditionalForecastStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output, "options_cond_fcst_"); @@ -3310,7 +3334,7 @@ ConditionalForecastStatement::writeOutput(ostream &output, [[maybe_unused]] cons } void -ConditionalForecastStatement::writeJsonOutput(ostream &output) const +ConditionalForecastStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "conditional_forecast")"; if (!options_list.empty()) @@ -3321,24 +3345,23 @@ ConditionalForecastStatement::writeJsonOutput(ostream &output) const output << "}"; } -PlotConditionalForecastStatement::PlotConditionalForecastStatement(optional 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} +PlotConditionalForecastStatement::PlotConditionalForecastStatement( + optional 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} { } void -PlotConditionalForecastStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - WarningConsolidation &warnings) +PlotConditionalForecastStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + WarningConsolidation& warnings) { try { - symbol_list.checkPass(warnings, { SymbolType::endogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: plot_conditional_forecast: " << e.message << endl; exit(EXIT_FAILURE); @@ -3346,7 +3369,8 @@ PlotConditionalForecastStatement::checkPass([[maybe_unused]] ModFileStructure &m } void -PlotConditionalForecastStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +PlotConditionalForecastStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { symbol_list.writeOutput("var_list_", output); @@ -3357,7 +3381,7 @@ PlotConditionalForecastStatement::writeOutput(ostream &output, [[maybe_unused]] } void -PlotConditionalForecastStatement::writeJsonOutput(ostream &output) const +PlotConditionalForecastStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "plot_conditional_forecast")"; if (periods) @@ -3370,16 +3394,15 @@ PlotConditionalForecastStatement::writeJsonOutput(ostream &output) const output << "}"; } -SvarIdentificationStatement::SvarIdentificationStatement(svar_identification_restrictions_t restrictions_arg, - bool upper_cholesky_present_arg, - bool lower_cholesky_present_arg, - bool constants_exclusion_present_arg, - const SymbolTable &symbol_table_arg) : - restrictions{move(restrictions_arg)}, - upper_cholesky_present{upper_cholesky_present_arg}, - lower_cholesky_present{lower_cholesky_present_arg}, - constants_exclusion_present{constants_exclusion_present_arg}, - symbol_table{symbol_table_arg} +SvarIdentificationStatement::SvarIdentificationStatement( + svar_identification_restrictions_t restrictions_arg, bool upper_cholesky_present_arg, + bool lower_cholesky_present_arg, bool constants_exclusion_present_arg, + const SymbolTable& symbol_table_arg) : + restrictions {move(restrictions_arg)}, + upper_cholesky_present {upper_cholesky_present_arg}, + lower_cholesky_present {lower_cholesky_present_arg}, + constants_exclusion_present {constants_exclusion_present_arg}, + symbol_table {symbol_table_arg} { } @@ -3387,15 +3410,15 @@ int SvarIdentificationStatement::getMaxLag() const { int max_lag = 0; - for (const auto &restriction : restrictions) + for (const auto& restriction : restrictions) max_lag = max(restriction.lag, max_lag); return max_lag; } void -SvarIdentificationStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +SvarIdentificationStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { // no equations OK with Svar Identification mod_file_struct.bvar_present = true; @@ -3416,13 +3439,11 @@ SvarIdentificationStatement::checkPass(ModFileStructure &mod_file_struct, } void -SvarIdentificationStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +SvarIdentificationStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { assert(!(upper_cholesky_present && lower_cholesky_present)); - output << "%" << endl - << "% SVAR IDENTIFICATION" << endl - << "%" << endl; + output << "%" << endl << "% SVAR IDENTIFICATION" << endl << "%" << endl; if (upper_cholesky_present) output << "options_.ms.upper_cholesky=1;" << endl; @@ -3438,12 +3459,11 @@ SvarIdentificationStatement::writeOutput(ostream &output, [[maybe_unused]] const int n = symbol_table.endo_nbr(); int m = 1; // this is the constant, not the shocks int r = getMaxLag(); - int k = r*n+m; + int k = r * n + m; if (k < 1) { - cerr << "ERROR: lag = " << r - << ", number of endogenous variables = " << n + cerr << "ERROR: lag = " << r << ", number of endogenous variables = " << n << ", number of exogenous variables = " << m << ". If this is not a logical error in the specification" << " of the .mod file, please report it to the Dynare Team." << endl; @@ -3451,28 +3471,35 @@ SvarIdentificationStatement::writeOutput(ostream &output, [[maybe_unused]] const } if (n < 1) { - cerr << "ERROR: Number of endogenous variables = " << n << "< 1. If this is not a logical " - << "error in the specification of the .mod file, please report it to the Dynare Team." << endl; + cerr + << "ERROR: Number of endogenous variables = " << n << "< 1. If this is not a logical " + << "error in the specification of the .mod file, please report it to the Dynare Team." + << endl; exit(EXIT_FAILURE); } output << "options_.ms.Qi = cell(" << n << ",1);" << endl << "options_.ms.Ri = cell(" << n << ",1);" << endl; - for (auto &it : restrictions) + for (auto& it : restrictions) { assert(it.lag >= 0); if (it.lag == 0) - output << "options_.ms.Qi{" << it.equation << "}(" << it.restriction_nbr << ", " << it.variable + 1 << ") = "; + output << "options_.ms.Qi{" << it.equation << "}(" << it.restriction_nbr << ", " + << it.variable + 1 << ") = "; else { - int col = (it.lag-1)*n+it.variable+1; + int col = (it.lag - 1) * n + it.variable + 1; if (col > k) { - cerr << "ERROR: lag =" << it.lag << ", num endog vars = " << n << "current endog var index = " << it.variable << ". Index " - << "out of bounds. If the above does not represent a logical error, please report this to the Dynare Team." << endl; + cerr << "ERROR: lag =" << it.lag << ", num endog vars = " << n + << "current endog var index = " << it.variable << ". Index " + << "out of bounds. If the above does not represent a logical error, please " + "report this to the Dynare Team." + << endl; exit(EXIT_FAILURE); } - output << "options_.ms.Ri{" << it.equation << "}(" << it.restriction_nbr << ", " << col << ") = "; + output << "options_.ms.Ri{" << it.equation << "}(" << it.restriction_nbr << ", " + << col << ") = "; } it.value->writeOutput(output); output << ";" << endl; @@ -3482,7 +3509,7 @@ SvarIdentificationStatement::writeOutput(ostream &output, [[maybe_unused]] const } void -SvarIdentificationStatement::writeJsonOutput(ostream &output) const +SvarIdentificationStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "svar_identification")"; @@ -3497,11 +3524,9 @@ SvarIdentificationStatement::writeJsonOutput(ostream &output) const if (!upper_cholesky_present && !lower_cholesky_present) { - output << R"(, "nlags": )" << getMaxLag() - << R"(, "restrictions": [)"; + output << R"(, "nlags": )" << getMaxLag() << R"(, "restrictions": [)"; - for (bool printed_something{false}; - const auto &it : restrictions) + for (bool printed_something {false}; const auto& it : restrictions) { if (exchange(printed_something, true)) output << ", "; @@ -3519,18 +3544,19 @@ SvarIdentificationStatement::writeJsonOutput(ostream &output) const } MarkovSwitchingStatement::MarkovSwitchingStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { if (auto opt = options_list.get_if>>("ms.restrictions")) { int num_regimes {stoi(options_list.get("ms.number_of_regimes"))}; - for (const vector &restriction : *opt) + for (const vector& restriction : *opt) { if (restriction.size() != 3) { - cerr << "ERROR: restrictions in the subsample statement must be specified in the form " - << "[current_period_regime, next_period_regime, transition_probability]" << endl; + cerr + << "ERROR: restrictions in the subsample statement must be specified in the form " + << "[current_period_regime, next_period_regime, transition_probability]" << endl; exit(EXIT_FAILURE); } @@ -3541,11 +3567,12 @@ MarkovSwitchingStatement::MarkovSwitchingStatement(OptionsList options_list_arg) if (from_regime > num_regimes || to_regime > num_regimes) { cerr << "ERROR: the regimes specified in the restrictions option must be " - << "<= the number of regimes specified in the number_of_regimes option" << endl; + << "<= the number of regimes specified in the number_of_regimes option" + << endl; exit(EXIT_FAILURE); } - if (restriction_map.contains({ from_regime, to_regime })) + if (restriction_map.contains({from_regime, to_regime})) { cerr << "ERROR: two restrictions were given for: " << from_regime << ", " << to_regime << endl; @@ -3559,9 +3586,9 @@ MarkovSwitchingStatement::MarkovSwitchingStatement(OptionsList options_list_arg) << " must be less than 1" << endl; exit(EXIT_FAILURE); } - restriction_map[{ from_regime, to_regime }] = transition_probability; + restriction_map[{from_regime, to_regime}] = transition_probability; } - catch (const invalid_argument &) + catch (const invalid_argument&) { cerr << "ERROR: The first two arguments for a restriction must be integers " << "specifying the regime and the last must be a floating point specifying the " @@ -3573,8 +3600,8 @@ MarkovSwitchingStatement::MarkovSwitchingStatement(OptionsList options_list_arg) } void -MarkovSwitchingStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +MarkovSwitchingStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { int chainNumber {stoi(options_list.get("ms.chain"))}; if (++mod_file_struct.last_markov_switching_chain != chainNumber) @@ -3593,10 +3620,10 @@ MarkovSwitchingStatement::checkPass(ModFileStructure &mod_file_struct, vector all_restrictions_in_col(num_regimes, true); for (int row = 0; row < num_regimes; row++) for (int col = 0; col < num_regimes; col++) - if (restriction_map.contains({ row+1, col+1 })) + if (restriction_map.contains({row + 1, col + 1})) { - row_trans_prob_sum[row] += restriction_map[{ row+1, col+1 }]; - col_trans_prob_sum[col] += restriction_map[{ row+1, col+1 }]; + row_trans_prob_sum[row] += restriction_map[{row + 1, col + 1}]; + col_trans_prob_sum[col] += restriction_map[{row + 1, col + 1}]; } else { @@ -3645,7 +3672,7 @@ MarkovSwitchingStatement::checkPass(ModFileStructure &mod_file_struct, } void -MarkovSwitchingStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +MarkovSwitchingStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { string chainNumber {options_list.get("ms.chain")}; @@ -3653,54 +3680,51 @@ MarkovSwitchingStatement::writeOutput(ostream &output, [[maybe_unused]] const st assert(options_list.contains("ms.duration")); output << "options_.ms.duration = "; - bool isDurationAVec { options_list.visit("ms.duration", - [&](const T &v) -> bool - { - if constexpr(is_same_v) - { - output << "["; - for (bool printed_something{false}; - const auto &it : v) - { - if (exchange(printed_something, true)) - output << ", "; - output << it; - } - output << "]"; - return true; - } - else if constexpr(is_same_v) - { - output << v; - return false; - } - else - { - cerr << "MarkovSwitchingStatement::writeOutput: incorrect value type for 'ms.duration' option" << endl; - exit(EXIT_FAILURE); - } - }) }; + bool isDurationAVec {options_list.visit("ms.duration", [&](const T& v) -> bool { + if constexpr (is_same_v) + { + output << "["; + for (bool printed_something {false}; const auto& it : v) + { + if (exchange(printed_something, true)) + output << ", "; + output << it; + } + output << "]"; + return true; + } + else if constexpr (is_same_v) + { + output << v; + return false; + } + else + { + cerr << "MarkovSwitchingStatement::writeOutput: incorrect value type for 'ms.duration' " + "option" + << endl; + exit(EXIT_FAILURE); + } + })}; output << ";" << endl; int NOR {stoi(options_list.get("ms.number_of_regimes"))}; for (int i {0}; i < NOR; i++) { - output << "options_.ms.ms_chain(" << chainNumber << ").regime(" - << i+1 << ").duration = options_.ms.duration"; + output << "options_.ms.ms_chain(" << chainNumber << ").regime(" << i + 1 + << ").duration = options_.ms.duration"; if (isDurationAVec) - output << "(" << i+1 << ")"; + output << "(" << i + 1 << ")"; output << ";" << endl; } - for (int restrictions_index{0}; - const auto &[regimes, prob] : restriction_map) - output << "options_.ms.ms_chain(" << chainNumber << ").restrictions(" - << ++restrictions_index << ") = {[" << regimes.first << ", " - << regimes.second << ", " << prob << "]};" << endl; + for (int restrictions_index {0}; const auto& [regimes, prob] : restriction_map) + output << "options_.ms.ms_chain(" << chainNumber << ").restrictions(" << ++restrictions_index + << ") = {[" << regimes.first << ", " << regimes.second << ", " << prob << "]};" << endl; } void -MarkovSwitchingStatement::writeJsonOutput(ostream &output) const +MarkovSwitchingStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "markov_switching")"; if (!options_list.empty()) @@ -3711,40 +3735,36 @@ MarkovSwitchingStatement::writeJsonOutput(ostream &output) const if (!restriction_map.empty()) output << ", {"; - for (bool printed_something{false}; - const auto &[regimes, prob] : restriction_map) + for (bool printed_something {false}; const auto& [regimes, prob] : restriction_map) { if (exchange(printed_something, true)) output << ", "; - output << R"({"current_period_regime": )" << regimes.first - << R"(, "next_period_regime": )" << regimes.second - << R"(, "transition_probability": )"<< prob - << "}"; + output << R"({"current_period_regime": )" << regimes.first << R"(, "next_period_regime": )" + << regimes.second << R"(, "transition_probability": )" << prob << "}"; } if (!restriction_map.empty()) output << "}"; output << "}"; } -SvarStatement::SvarStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} +SvarStatement::SvarStatement(OptionsList options_list_arg) : options_list {move(options_list_arg)} { } void -SvarStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +SvarStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { bool has_coefficients = options_list.contains("ms.coefficients"), - has_variances = options_list.contains("ms.variances"), - has_constants = options_list.contains("ms.constants"); + has_variances = options_list.contains("ms.variances"), + has_constants = options_list.contains("ms.constants"); assert((has_coefficients && !has_variances && !has_constants) || (!has_coefficients && has_variances && !has_constants) || (!has_coefficients && !has_variances && has_constants)); } void -SvarStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +SvarStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "options_.ms.ms_chain(" << options_list.get("ms.chain") << ")"; @@ -3775,7 +3795,7 @@ SvarStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basen } void -SvarStatement::writeJsonOutput(ostream &output) const +SvarStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "svar")"; if (!options_list.empty()) @@ -3787,33 +3807,33 @@ SvarStatement::writeJsonOutput(ostream &output) const } void -SvarGlobalIdentificationCheckStatement::writeOutput(ostream &output, - [[maybe_unused]] const string &basename, +SvarGlobalIdentificationCheckStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "svar_global_identification_check(options_);" << std::endl; } void -SvarGlobalIdentificationCheckStatement::writeJsonOutput(ostream &output) const +SvarGlobalIdentificationCheckStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "svar_global_identification"})"; } SetTimeStatement::SetTimeStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -SetTimeStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +SetTimeStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); } void -SetTimeStatement::writeJsonOutput(ostream &output) const +SetTimeStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "set_time")"; if (!options_list.empty()) @@ -3825,25 +3845,25 @@ SetTimeStatement::writeJsonOutput(ostream &output) const } EstimationDataStatement::EstimationDataStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -EstimationDataStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +EstimationDataStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.estimation_data_statement_present = true; if (auto opt = options_list.get_if("nobs")) if (stoi(*opt) <= 0) { - cerr << "ERROR: The nobs option of the data statement only accepts positive integers." << endl; + cerr << "ERROR: The nobs option of the data statement only accepts positive integers." + << endl; exit(EXIT_FAILURE); } - bool has_file = options_list.contains("file"), - has_series = options_list.contains("series"); + bool has_file = options_list.contains("file"), has_series = options_list.contains("series"); if (!has_file && !has_series) { cerr << "ERROR: The file or series option must be passed to the data statement." << endl; @@ -3851,20 +3871,22 @@ EstimationDataStatement::checkPass(ModFileStructure &mod_file_struct, } if (has_file && has_series) { - cerr << "ERROR: The file and series options cannot be used simultaneously in the data statement." << endl; + cerr << "ERROR: The file and series options cannot be used simultaneously in the data " + "statement." + << endl; exit(EXIT_FAILURE); } } void -EstimationDataStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +EstimationDataStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output, "options_.dataset"); } void -EstimationDataStatement::writeJsonOutput(ostream &output) const +EstimationDataStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "estimation_data")"; if (!options_list.empty()) @@ -3875,24 +3897,22 @@ EstimationDataStatement::writeJsonOutput(ostream &output) const output << "}"; } -SubsamplesStatement::SubsamplesStatement(string name1_arg, - string name2_arg, +SubsamplesStatement::SubsamplesStatement(string name1_arg, string name2_arg, subsample_declaration_map_t subsample_declaration_map_arg, - const SymbolTable &symbol_table_arg) : - name1{move(name1_arg)}, - name2{move(name2_arg)}, - subsample_declaration_map{move(subsample_declaration_map_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + name1 {move(name1_arg)}, + name2 {move(name2_arg)}, + subsample_declaration_map {move(subsample_declaration_map_arg)}, + symbol_table {symbol_table_arg} { } void -SubsamplesStatement::writeOutput(ostream &output, - [[maybe_unused]] const string &basename, +SubsamplesStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { - output << "subsamples_indx = get_new_or_existing_ei_index('subsamples_index', '" - << name1 << "','" << name2 << "');" << endl + output << "subsamples_indx = get_new_or_existing_ei_index('subsamples_index', '" << name1 << "','" + << name2 << "');" << endl << "estimation_info.subsamples_index(subsamples_indx) = {'" << name1; if (!name2.empty()) output << ":" << name2; @@ -3900,15 +3920,14 @@ SubsamplesStatement::writeOutput(ostream &output, << "estimation_info.subsamples(subsamples_indx).range = {};" << endl << "estimation_info.subsamples(subsamples_indx).range_index = {};" << endl; - for (int map_indx{1}; - const auto &[range, dates] : subsample_declaration_map) + for (int map_indx {1}; const auto& [range, dates] : subsample_declaration_map) { output << "estimation_info.subsamples(subsamples_indx).range_index(" << map_indx << ") = {'" << range << "'};" << endl - << "estimation_info.subsamples(subsamples_indx).range(" << map_indx << ").date1 = " - << dates.first << ";" << endl - << "estimation_info.subsamples(subsamples_indx).range(" << map_indx << ").date2 = " - << dates.second << ";" << endl; + << "estimation_info.subsamples(subsamples_indx).range(" << map_indx + << ").date1 = " << dates.first << ";" << endl + << "estimation_info.subsamples(subsamples_indx).range(" << map_indx + << ").date2 = " << dates.second << ";" << endl; map_indx++; } @@ -3935,8 +3954,7 @@ SubsamplesStatement::writeOutput(ostream &output, if (!name2.empty()) output << "_corr"; - output << "_prior_index', '" - << name1 << "', '"; + output << "_prior_index', '" << name1 << "', '"; if (!name2.empty()) output << name2; output << "');" << endl; @@ -3952,12 +3970,13 @@ SubsamplesStatement::writeOutput(ostream &output, output << lhs_field << "(eifind).subsample_prior = estimation_info.empty_prior;" << endl << lhs_field << "(eifind).subsample_prior(1:" << subsample_declaration_map.size() << ") = estimation_info.empty_prior;" << endl - << lhs_field << "(eifind).range_index = estimation_info.subsamples(subsamples_indx).range_index;" + << lhs_field + << "(eifind).range_index = estimation_info.subsamples(subsamples_indx).range_index;" << endl; } void -SubsamplesStatement::writeJsonOutput(ostream &output) const +SubsamplesStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "subsamples")" << R"(, "name1": ")" << name1 << R"(")"; @@ -3965,8 +3984,7 @@ SubsamplesStatement::writeJsonOutput(ostream &output) const output << R"(, "name2": ")" << name2 << R"(")"; output << R"(, "declarations": {)"; - for (bool printed_something{false}; - const auto &[range, dates] : subsample_declaration_map) + for (bool printed_something {false}; const auto& [range, dates] : subsample_declaration_map) { if (exchange(printed_something, true)) output << ","; @@ -3980,32 +3998,31 @@ SubsamplesStatement::writeJsonOutput(ostream &output) const << "}"; } -SubsamplesEqualStatement::SubsamplesEqualStatement(string to_name1_arg, - string to_name2_arg, - string from_name1_arg, - string from_name2_arg, - const SymbolTable &symbol_table_arg) : - to_name1{move(to_name1_arg)}, - to_name2{move(to_name2_arg)}, - from_name1{move(from_name1_arg)}, - from_name2{move(from_name2_arg)}, - symbol_table{symbol_table_arg} +SubsamplesEqualStatement::SubsamplesEqualStatement(string to_name1_arg, string to_name2_arg, + string from_name1_arg, string from_name2_arg, + const SymbolTable& symbol_table_arg) : + to_name1 {move(to_name1_arg)}, + to_name2 {move(to_name2_arg)}, + from_name1 {move(from_name1_arg)}, + from_name2 {move(from_name2_arg)}, + symbol_table {symbol_table_arg} { } void -SubsamplesEqualStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +SubsamplesEqualStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { - output << "subsamples_to_indx = get_new_or_existing_ei_index('subsamples_index', '" - << to_name1 << "','" << to_name2 << "');" << endl + output << "subsamples_to_indx = get_new_or_existing_ei_index('subsamples_index', '" << to_name1 + << "','" << to_name2 << "');" << endl << "estimation_info.subsamples_index(subsamples_to_indx) = {'" << to_name1; if (!to_name2.empty()) output << ":" << to_name2; output << "'};" << endl - << "subsamples_from_indx = get_existing_subsamples_indx('" << from_name1 << "','" << from_name2 << "');" - << endl - << "estimation_info.subsamples(subsamples_to_indx) = estimation_info.subsamples(subsamples_from_indx);" + << "subsamples_from_indx = get_existing_subsamples_indx('" << from_name1 << "','" + << from_name2 << "');" << endl + << "estimation_info.subsamples(subsamples_to_indx) = " + "estimation_info.subsamples(subsamples_from_indx);" << endl; // Initialize associated subsample substructures in estimation_info @@ -4031,8 +4048,7 @@ SubsamplesEqualStatement::writeOutput(ostream &output, [[maybe_unused]] const st if (!to_name2.empty()) output << "_corr"; - output << "_prior_index', '" - << to_name1 << "', '"; + output << "_prior_index', '" << to_name1 << "', '"; if (!to_name2.empty()) output << to_name2; output << "');" << endl; @@ -4046,14 +4062,17 @@ SubsamplesEqualStatement::writeOutput(ostream &output, [[maybe_unused]] const st output << "'};" << endl; output << lhs_field << "(eifind).subsample_prior = estimation_info.empty_prior;" << endl - << lhs_field << "(eifind).subsample_prior(1:size(estimation_info.subsamples(subsamples_to_indx).range_index,2)) = estimation_info.empty_prior;" + << lhs_field + << "(eifind).subsample_prior(1:size(estimation_info.subsamples(subsamples_to_indx).range_" + "index,2)) = estimation_info.empty_prior;" << endl - << lhs_field << "(eifind).range_index = estimation_info.subsamples(subsamples_to_indx).range_index;" + << lhs_field + << "(eifind).range_index = estimation_info.subsamples(subsamples_to_indx).range_index;" << endl; } void -SubsamplesEqualStatement::writeJsonOutput(ostream &output) const +SubsamplesEqualStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "subsamples_equal")" << R"(, "to_name1": ")" << to_name1 << R"(")"; @@ -4068,15 +4087,15 @@ SubsamplesEqualStatement::writeJsonOutput(ostream &output) const JointPriorStatement::JointPriorStatement(vector joint_parameters_arg, PriorDistributions prior_shape_arg, OptionsList options_list_arg) : - joint_parameters{move(joint_parameters_arg)}, - prior_shape{prior_shape_arg}, - options_list{move(options_list_arg)} + joint_parameters {move(joint_parameters_arg)}, + prior_shape {prior_shape_arg}, + options_list {move(options_list_arg)} { } void -JointPriorStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +JointPriorStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { if (joint_parameters.size() < 2) { @@ -4096,8 +4115,7 @@ JointPriorStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struc exit(EXIT_FAILURE); } - if (auto opt = options_list.get_if("domain"); - opt && opt->size() != 4) + if (auto opt = options_list.get_if("domain"); opt && opt->size() != 4) { cerr << "ERROR: You must pass exactly four values to the domain option." << endl; exit(EXIT_FAILURE); @@ -4105,18 +4123,20 @@ JointPriorStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struc } void -JointPriorStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +JointPriorStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { - for (const auto &joint_parameter : joint_parameters) + for (const auto& joint_parameter : joint_parameters) output << "eifind = get_new_or_existing_ei_index('joint_parameter_prior_index', '" << joint_parameter << "', '');" << endl - << "estimation_info.joint_parameter_prior_index(eifind) = {'" << joint_parameter << "'};" << endl; + << "estimation_info.joint_parameter_prior_index(eifind) = {'" << joint_parameter << "'};" + << endl; output << "key = {["; - for (const auto &joint_parameter : joint_parameters) - output << "get_new_or_existing_ei_index('joint_parameter_prior_index', '" << joint_parameter << "', '') ..." - << endl << " "; + for (const auto& joint_parameter : joint_parameters) + output << "get_new_or_existing_ei_index('joint_parameter_prior_index', '" << joint_parameter + << "', '') ..." << endl + << " "; output << "]};" << endl; string lhs_field("estimation_info.joint_parameter_tmp"); @@ -4146,69 +4166,67 @@ JointPriorStatement::writeOutput(ostream &output, [[maybe_unused]] const string << " " << lhs_field << ".stdev , ..." << endl << " " << lhs_field << ".truncate , ..." << endl << " " << lhs_field << ".variance];" << endl - << "estimation_info.joint_parameter = [estimation_info.joint_parameter; estimation_info.joint_parameter_tmp];" << endl + << "estimation_info.joint_parameter = [estimation_info.joint_parameter; " + "estimation_info.joint_parameter_tmp];" + << endl << "estimation_info=rmfield(estimation_info, 'joint_parameter_tmp');" << endl; } void -JointPriorStatement::writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const +JointPriorStatement::writeOutputHelper(ostream& output, const string& field, + const string& lhs_field) const { output << lhs_field << "." << field << " = {"; if (options_list.contains(field)) - options_list.visit(field, [&](const T &v) - { - if constexpr(is_same_v) - output << v; - else if constexpr(is_same_v) - { - output << "["; - for (bool printed_something{false}; - const auto &it2 : v) - { - if (exchange(printed_something, true)) - output << ", "; - output << it2; - } - output << "]"; - } - else if constexpr(is_same_v>>) - { - output << "{"; - for (bool printed_something{false}; - const auto &it2 : v) - { - if (exchange(printed_something, true)) - output << ", "; - output << "["; - for (bool printed_something2{false}; - const auto &it3 : it2) - { - if (exchange(printed_something2, true)) - output << ", "; - output << it3; - } - output << "]"; - } - output << "}"; - } - else - { - cerr << "JointPriorStatement::writeOutputHelper: unhandled alternative" << endl; - exit(EXIT_FAILURE); - } - }); + options_list.visit(field, [&](const T& v) { + if constexpr (is_same_v) + output << v; + else if constexpr (is_same_v) + { + output << "["; + for (bool printed_something {false}; const auto& it2 : v) + { + if (exchange(printed_something, true)) + output << ", "; + output << it2; + } + output << "]"; + } + else if constexpr (is_same_v>>) + { + output << "{"; + for (bool printed_something {false}; const auto& it2 : v) + { + if (exchange(printed_something, true)) + output << ", "; + output << "["; + for (bool printed_something2 {false}; const auto& it3 : it2) + { + if (exchange(printed_something2, true)) + output << ", "; + output << it3; + } + output << "]"; + } + output << "}"; + } + else + { + cerr << "JointPriorStatement::writeOutputHelper: unhandled alternative" << endl; + exit(EXIT_FAILURE); + } + }); else output << "{}"; output << "};" << endl; } void -JointPriorStatement::writeJsonOutput(ostream &output) const +JointPriorStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "joint_prior")" << R"(, "key": [)"; - for (bool printed_something{false}; - const auto &it : joint_parameters) + for (bool printed_something {false}; const auto& it : joint_parameters) { if (exchange(printed_something, true)) output << ", "; @@ -4256,22 +4274,20 @@ JointPriorStatement::writeJsonOutput(ostream &output) const output << "}"; } -BasicPriorStatement::BasicPriorStatement(string name_arg, - string subsample_name_arg, - PriorDistributions prior_shape_arg, - expr_t variance_arg, +BasicPriorStatement::BasicPriorStatement(string name_arg, string subsample_name_arg, + PriorDistributions prior_shape_arg, expr_t variance_arg, OptionsList options_list_arg) : - name{move(name_arg)}, - subsample_name{move(subsample_name_arg)}, - prior_shape{prior_shape_arg}, - variance{variance_arg}, - options_list{move(options_list_arg)} + name {move(name_arg)}, + subsample_name {move(subsample_name_arg)}, + prior_shape {prior_shape_arg}, + variance {variance_arg}, + options_list {move(options_list_arg)} { } void -BasicPriorStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +BasicPriorStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { if (prior_shape == PriorDistributions::noShape) { @@ -4288,12 +4304,12 @@ BasicPriorStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struc if (bool has_stdev = options_list.contains("stdev"); (!has_stdev && !variance) || (has_stdev && variance)) { - cerr << "ERROR: You must pass exactly one of stdev and variance to the prior statement." << endl; + cerr << "ERROR: You must pass exactly one of stdev and variance to the prior statement." + << endl; exit(EXIT_FAILURE); } - if (auto opt = options_list.get_if("domain"); - opt && opt->size() != 2) + if (auto opt = options_list.get_if("domain"); opt && opt->size() != 2) { cerr << "ERROR: You must pass exactly two values to the domain option." << endl; exit(EXIT_FAILURE); @@ -4309,7 +4325,7 @@ BasicPriorStatement::is_structural_innovation(const SymbolType symb_type) const } void -BasicPriorStatement::get_base_name(const SymbolType symb_type, string &lhs_field) const +BasicPriorStatement::get_base_name(const SymbolType symb_type, string& lhs_field) const { if (symb_type == SymbolType::exogenous) lhs_field = "structural_innovation"; @@ -4318,7 +4334,7 @@ BasicPriorStatement::get_base_name(const SymbolType symb_type, string &lhs_field } void -BasicPriorStatement::writeCommonOutput(ostream &output, const string &lhs_field) const +BasicPriorStatement::writeCommonOutput(ostream& output, const string& lhs_field) const { output << lhs_field << " = estimation_info.empty_prior;" << endl; @@ -4344,33 +4360,35 @@ BasicPriorStatement::writeCommonOutput(ostream &output, const string &lhs_field) } void -BasicPriorStatement::writeCommonOutputHelper(ostream &output, const string &field, const string &lhs_field) const +BasicPriorStatement::writeCommonOutputHelper(ostream& output, const string& field, + const string& lhs_field) const { if (options_list.contains(field)) - options_list.visit(field, [&](const T &v) - { - if constexpr(is_same_v) - output << lhs_field << "." << field << " = "<< v << ";" << endl; - // TODO: handle other variant types - }); + options_list.visit(field, [&](const T& v) { + if constexpr (is_same_v) + output << lhs_field << "." << field << " = " << v << ";" << endl; + // TODO: handle other variant types + }); } void -BasicPriorStatement::writePriorOutput(ostream &output, string &lhs_field, const string &name2) const +BasicPriorStatement::writePriorOutput(ostream& output, string& lhs_field, const string& name2) const { if (subsample_name.empty()) lhs_field += ".prior(1)"; else { - output << "subsamples_indx = get_existing_subsamples_indx('" << name << "','" << name2 << "');" << endl - << "eisind = get_subsamples_range_indx(subsamples_indx, '" << subsample_name << "');" << endl; + output << "subsamples_indx = get_existing_subsamples_indx('" << name << "','" << name2 + << "');" << endl + << "eisind = get_subsamples_range_indx(subsamples_indx, '" << subsample_name << "');" + << endl; lhs_field += ".subsample_prior(eisind)"; } writeCommonOutput(output, lhs_field); } void -BasicPriorStatement::writeJsonPriorOutput(ostream &output) const +BasicPriorStatement::writeJsonPriorOutput(ostream& output) const { output << R"(, "name": ")" << name << R"(")" << R"(, "subsample": ")" << subsample_name << R"(")" @@ -4390,7 +4408,7 @@ BasicPriorStatement::writeJsonPriorOutput(ostream &output) const } void -BasicPriorStatement::writeJsonShape(ostream &output) const +BasicPriorStatement::writeJsonShape(ostream& output) const { output << R"("shape": )"; switch (prior_shape) @@ -4424,53 +4442,51 @@ BasicPriorStatement::writeJsonShape(ostream &output) const } } -PriorStatement::PriorStatement(string name_arg, - string subsample_name_arg, - PriorDistributions prior_shape_arg, - expr_t variance_arg, +PriorStatement::PriorStatement(string name_arg, string subsample_name_arg, + PriorDistributions prior_shape_arg, expr_t variance_arg, OptionsList options_list_arg) : - BasicPriorStatement{move(name_arg), move(subsample_name_arg), prior_shape_arg, variance_arg, move(options_list_arg)} + BasicPriorStatement {move(name_arg), move(subsample_name_arg), prior_shape_arg, variance_arg, + move(options_list_arg)} { } void -PriorStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +PriorStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { string lhs_field = "estimation_info.parameter(eifind)"; - output << "eifind = get_new_or_existing_ei_index('parameter_prior_index', '" - << name << "', '');" << endl + output << "eifind = get_new_or_existing_ei_index('parameter_prior_index', '" << name << "', '');" + << endl << "estimation_info.parameter_prior_index(eifind) = {'" << name << "'};" << endl; writePriorOutput(output, lhs_field, ""); } void -PriorStatement::writeJsonOutput(ostream &output) const +PriorStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "prior")"; writeJsonPriorOutput(output); output << "}"; } -StdPriorStatement::StdPriorStatement(string name_arg, - string subsample_name_arg, - PriorDistributions prior_shape_arg, - expr_t variance_arg, +StdPriorStatement::StdPriorStatement(string name_arg, string subsample_name_arg, + PriorDistributions prior_shape_arg, expr_t variance_arg, OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - BasicPriorStatement{move(name_arg), move(subsample_name_arg), prior_shape_arg, variance_arg, move(options_list_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + BasicPriorStatement {move(name_arg), move(subsample_name_arg), prior_shape_arg, variance_arg, + move(options_list_arg)}, + symbol_table {symbol_table_arg} { } void -StdPriorStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +StdPriorStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { string lhs_field; get_base_name(symbol_table.getType(name), lhs_field); - output << "eifind = get_new_or_existing_ei_index('" << lhs_field << "_prior_index', '" - << name << "', '');" << endl + output << "eifind = get_new_or_existing_ei_index('" << lhs_field << "_prior_index', '" << name + << "', '');" << endl << "estimation_info." << lhs_field << "_prior_index(eifind) = {'" << name << "'};" << endl; lhs_field = "estimation_info." + lhs_field + "(eifind)"; @@ -4478,7 +4494,7 @@ StdPriorStatement::writeOutput(ostream &output, [[maybe_unused]] const string &b } void -StdPriorStatement::writeJsonOutput(ostream &output) const +StdPriorStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "std_prior")"; writeJsonPriorOutput(output); @@ -4487,18 +4503,18 @@ StdPriorStatement::writeJsonOutput(ostream &output) const CorrPriorStatement::CorrPriorStatement(string name_arg1, string name_arg2, string subsample_name_arg, - PriorDistributions prior_shape_arg, - expr_t variance_arg, + PriorDistributions prior_shape_arg, expr_t variance_arg, OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - BasicPriorStatement{move(name_arg1), move(subsample_name_arg), prior_shape_arg, variance_arg, move(options_list_arg)}, - name1{move(name_arg2)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + BasicPriorStatement {move(name_arg1), move(subsample_name_arg), prior_shape_arg, variance_arg, + move(options_list_arg)}, + name1 {move(name_arg2)}, + symbol_table {symbol_table_arg} { } void -CorrPriorStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +CorrPriorStatement::checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) { BasicPriorStatement::checkPass(mod_file_struct, warnings); if (symbol_table.getType(name) != symbol_table.getType(name1)) @@ -4511,7 +4527,7 @@ CorrPriorStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolid } void -CorrPriorStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +CorrPriorStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { string lhs_field; @@ -4519,15 +4535,15 @@ CorrPriorStatement::writeOutput(ostream &output, [[maybe_unused]] const string & output << "eifind = get_new_or_existing_ei_index('" << lhs_field << "_corr_prior_index', '" << name << "', '" << name1 << "');" << endl - << "estimation_info." << lhs_field << "_corr_prior_index(eifind) = {'" - << name << ":" << name1 << "'};" << endl; + << "estimation_info." << lhs_field << "_corr_prior_index(eifind) = {'" << name << ":" + << name1 << "'};" << endl; lhs_field = "estimation_info." + lhs_field + "_corr(eifind)"; writePriorOutput(output, lhs_field, name1); } void -CorrPriorStatement::writeJsonOutput(ostream &output) const +CorrPriorStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "corr_prior")" << R"(, "name2": ")" << name1 << R"(")"; @@ -4535,33 +4551,31 @@ CorrPriorStatement::writeJsonOutput(ostream &output) const output << "}"; } -PriorEqualStatement::PriorEqualStatement(string to_declaration_type_arg, - string to_name1_arg, - string to_name2_arg, - string to_subsample_name_arg, - string from_declaration_type_arg, - string from_name1_arg, - string from_name2_arg, - string from_subsample_name_arg, - const SymbolTable &symbol_table_arg) : - to_declaration_type{move(to_declaration_type_arg)}, - to_name1{move(to_name1_arg)}, - to_name2{move(to_name2_arg)}, - to_subsample_name{move(to_subsample_name_arg)}, - from_declaration_type{move(from_declaration_type_arg)}, - from_name1{move(from_name1_arg)}, - from_name2{move(from_name2_arg)}, - from_subsample_name{move(from_subsample_name_arg)}, - symbol_table{symbol_table_arg} +PriorEqualStatement::PriorEqualStatement(string to_declaration_type_arg, string to_name1_arg, + string to_name2_arg, string to_subsample_name_arg, + string from_declaration_type_arg, string from_name1_arg, + string from_name2_arg, string from_subsample_name_arg, + const SymbolTable& symbol_table_arg) : + to_declaration_type {move(to_declaration_type_arg)}, + to_name1 {move(to_name1_arg)}, + to_name2 {move(to_name2_arg)}, + to_subsample_name {move(to_subsample_name_arg)}, + from_declaration_type {move(from_declaration_type_arg)}, + from_name1 {move(from_name1_arg)}, + from_name2 {move(from_name2_arg)}, + from_subsample_name {move(from_subsample_name_arg)}, + symbol_table {symbol_table_arg} { } void -PriorEqualStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +PriorEqualStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { - if ((to_declaration_type != "par" && to_declaration_type != "std" && to_declaration_type != "corr") - || (from_declaration_type != "par" && from_declaration_type != "std" && from_declaration_type != "corr")) + if ((to_declaration_type != "par" && to_declaration_type != "std" + && to_declaration_type != "corr") + || (from_declaration_type != "par" && from_declaration_type != "std" + && from_declaration_type != "corr")) { cerr << "Internal Dynare Error" << endl; exit(EXIT_FAILURE); @@ -4569,7 +4583,7 @@ PriorEqualStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struc } void -PriorEqualStatement::get_base_name(const SymbolType symb_type, string &lhs_field) const +PriorEqualStatement::get_base_name(const SymbolType symb_type, string& lhs_field) const { if (symb_type == SymbolType::exogenous) lhs_field = "structural_innovation"; @@ -4578,7 +4592,7 @@ PriorEqualStatement::get_base_name(const SymbolType symb_type, string &lhs_field } void -PriorEqualStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +PriorEqualStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { string lhs_field, rhs_field; @@ -4600,9 +4614,9 @@ PriorEqualStatement::writeOutput(ostream &output, [[maybe_unused]] const string rhs_field += "_corr"; output << "ei_to_ind = get_new_or_existing_ei_index('" << lhs_field << "_prior_index', '" - << to_name1 << "', '" << to_name2<< "');" << endl + << to_name1 << "', '" << to_name2 << "');" << endl << "ei_from_ind = get_new_or_existing_ei_index('" << rhs_field << "_prior_index', '" - << from_name1 << "', '" << from_name2<< "');" << endl + << from_name1 << "', '" << from_name2 << "');" << endl << "estimation_info." << lhs_field << "_prior_index(ei_to_ind) = {'" << to_name1; if (to_declaration_type == "corr") @@ -4622,8 +4636,10 @@ PriorEqualStatement::writeOutput(ostream &output, [[maybe_unused]] const string lhs_field += ".prior"; else { - output << "subsamples_to_indx = get_existing_subsamples_indx('" << to_name1 << "','" << to_name2 << "');" << endl - << "ei_to_ss_ind = get_subsamples_range_indx(subsamples_to_indx, '" << to_subsample_name << "');" << endl; + output << "subsamples_to_indx = get_existing_subsamples_indx('" << to_name1 << "','" + << to_name2 << "');" << endl + << "ei_to_ss_ind = get_subsamples_range_indx(subsamples_to_indx, '" + << to_subsample_name << "');" << endl; lhs_field += ".subsample_prior(ei_to_ss_ind)"; } @@ -4631,8 +4647,10 @@ PriorEqualStatement::writeOutput(ostream &output, [[maybe_unused]] const string rhs_field += ".prior"; else { - output << "subsamples_from_indx = get_existing_subsamples_indx('" << from_name1 << "','" << from_name2 << "');" << endl - << "ei_from_ss_ind = get_subsamples_range_indx(subsamples_from_indx, '" << from_subsample_name << "');" << endl; + output << "subsamples_from_indx = get_existing_subsamples_indx('" << from_name1 << "','" + << from_name2 << "');" << endl + << "ei_from_ss_ind = get_subsamples_range_indx(subsamples_from_indx, '" + << from_subsample_name << "');" << endl; rhs_field += ".subsample_prior(ei_from_ss_ind)"; } @@ -4640,7 +4658,7 @@ PriorEqualStatement::writeOutput(ostream &output, [[maybe_unused]] const string } void -PriorEqualStatement::writeJsonOutput(ostream &output) const +PriorEqualStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "prior_equal")" << R"(, "to_name1": ")" << to_name1 << R"(")"; @@ -4654,12 +4672,11 @@ PriorEqualStatement::writeJsonOutput(ostream &output) const << "}"; } -BasicOptionsStatement::BasicOptionsStatement(string name_arg, - string subsample_name_arg, +BasicOptionsStatement::BasicOptionsStatement(string name_arg, string subsample_name_arg, OptionsList options_list_arg) : - name{move(name_arg)}, - subsample_name{move(subsample_name_arg)}, - options_list{move(options_list_arg)} + name {move(name_arg)}, + subsample_name {move(subsample_name_arg)}, + options_list {move(options_list_arg)} { } @@ -4670,7 +4687,7 @@ BasicOptionsStatement::is_structural_innovation(const SymbolType symb_type) cons } void -BasicOptionsStatement::get_base_name(const SymbolType symb_type, string &lhs_field) const +BasicOptionsStatement::get_base_name(const SymbolType symb_type, string& lhs_field) const { if (symb_type == SymbolType::exogenous) lhs_field = "structural_innovation"; @@ -4679,7 +4696,7 @@ BasicOptionsStatement::get_base_name(const SymbolType symb_type, string &lhs_fie } void -BasicOptionsStatement::writeCommonOutput(ostream &output, const string &lhs_field) const +BasicOptionsStatement::writeCommonOutput(ostream& output, const string& lhs_field) const { output << lhs_field << " = estimation_info.empty_options;" << endl; @@ -4689,33 +4706,36 @@ BasicOptionsStatement::writeCommonOutput(ostream &output, const string &lhs_fiel } void -BasicOptionsStatement::writeCommonOutputHelper(ostream &output, const string &field, const string &lhs_field) const +BasicOptionsStatement::writeCommonOutputHelper(ostream& output, const string& field, + const string& lhs_field) const { if (options_list.contains(field)) - options_list.visit(field, [&](const T &v) - { - if constexpr(is_same_v) - output << lhs_field << "." << field << " = "<< v << ";" << endl; - // TODO: handle other variant types - }); + options_list.visit(field, [&](const T& v) { + if constexpr (is_same_v) + output << lhs_field << "." << field << " = " << v << ";" << endl; + // TODO: handle other variant types + }); } void -BasicOptionsStatement::writeOptionsOutput(ostream &output, string &lhs_field, const string &name2) const +BasicOptionsStatement::writeOptionsOutput(ostream& output, string& lhs_field, + const string& name2) const { if (subsample_name.empty()) lhs_field += ".options(1)"; else { - output << "subsamples_indx = get_existing_subsamples_indx('" << name << "','" << name2 << "');" << endl - << "eisind = get_subsamples_range_indx(subsamples_indx, '" << subsample_name << "');" << endl; + output << "subsamples_indx = get_existing_subsamples_indx('" << name << "','" << name2 + << "');" << endl + << "eisind = get_subsamples_range_indx(subsamples_indx, '" << subsample_name << "');" + << endl; lhs_field += ".subsample_options(eisind)"; } writeCommonOutput(output, lhs_field); } void -BasicOptionsStatement::writeJsonOptionsOutput(ostream &output) const +BasicOptionsStatement::writeJsonOptionsOutput(ostream& output) const { output << R"(, "name": ")" << name << R"(")"; if (!subsample_name.empty()) @@ -4727,57 +4747,56 @@ BasicOptionsStatement::writeJsonOptionsOutput(ostream &output) const } } -OptionsStatement::OptionsStatement(string name_arg, - string subsample_name_arg, +OptionsStatement::OptionsStatement(string name_arg, string subsample_name_arg, OptionsList options_list_arg) : - BasicOptionsStatement{move(name_arg), move(subsample_name_arg), move(options_list_arg)} + BasicOptionsStatement {move(name_arg), move(subsample_name_arg), move(options_list_arg)} { } void -OptionsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +OptionsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { string lhs_field = "estimation_info.parameter(eifind)"; - output << "eifind = get_new_or_existing_ei_index('parameter_options_index', '" - << name << "', '');" << endl + output << "eifind = get_new_or_existing_ei_index('parameter_options_index', '" << name + << "', '');" << endl << "estimation_info.parameter_options_index(eifind) = {'" << name << "'};" << endl; writeOptionsOutput(output, lhs_field, ""); } void -OptionsStatement::writeJsonOutput(ostream &output) const +OptionsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "options")"; writeJsonOptionsOutput(output); output << "}"; } -StdOptionsStatement::StdOptionsStatement(string name_arg, - string subsample_name_arg, +StdOptionsStatement::StdOptionsStatement(string name_arg, string subsample_name_arg, OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - BasicOptionsStatement{move(name_arg), move(subsample_name_arg), move(options_list_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + BasicOptionsStatement {move(name_arg), move(subsample_name_arg), move(options_list_arg)}, + symbol_table {symbol_table_arg} { } void -StdOptionsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +StdOptionsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { string lhs_field; get_base_name(symbol_table.getType(name), lhs_field); - output << "eifind = get_new_or_existing_ei_index('" << lhs_field << "_options_index', '" - << name << "', '');" << endl - << "estimation_info." << lhs_field << "_options_index(eifind) = {'" << name << "'};" << endl; + output << "eifind = get_new_or_existing_ei_index('" << lhs_field << "_options_index', '" << name + << "', '');" << endl + << "estimation_info." << lhs_field << "_options_index(eifind) = {'" << name << "'};" + << endl; lhs_field = "estimation_info." + lhs_field + "(eifind)"; writeOptionsOutput(output, lhs_field, ""); } void -StdOptionsStatement::writeJsonOutput(ostream &output) const +StdOptionsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "std_options")"; writeJsonOptionsOutput(output); @@ -4785,18 +4804,17 @@ StdOptionsStatement::writeJsonOutput(ostream &output) const } CorrOptionsStatement::CorrOptionsStatement(string name_arg1, string name_arg2, - string subsample_name_arg, - OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - BasicOptionsStatement{move(name_arg1), move(subsample_name_arg), move(options_list_arg)}, - name1{move(name_arg2)}, - symbol_table{symbol_table_arg} + string subsample_name_arg, OptionsList options_list_arg, + const SymbolTable& symbol_table_arg) : + BasicOptionsStatement {move(name_arg1), move(subsample_name_arg), move(options_list_arg)}, + name1 {move(name_arg2)}, + symbol_table {symbol_table_arg} { } void -CorrOptionsStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +CorrOptionsStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { if (symbol_table.getType(name) != symbol_table.getType(name1)) { @@ -4808,7 +4826,7 @@ CorrOptionsStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_stru } void -CorrOptionsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +CorrOptionsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { string lhs_field; @@ -4816,15 +4834,15 @@ CorrOptionsStatement::writeOutput(ostream &output, [[maybe_unused]] const string output << "eifind = get_new_or_existing_ei_index('" << lhs_field << "_corr_options_index', '" << name << "', '" << name1 << "');" << endl - << "estimation_info." << lhs_field << "_corr_options_index(eifind) = {'" - << name << ":" << name1 << "'};" << endl; + << "estimation_info." << lhs_field << "_corr_options_index(eifind) = {'" << name << ":" + << name1 << "'};" << endl; lhs_field = "estimation_info." + lhs_field + "_corr(eifind)"; writeOptionsOutput(output, lhs_field, name1); } void -CorrOptionsStatement::writeJsonOutput(ostream &output) const +CorrOptionsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "corr_options")" << R"(, "name2": ")" << name1 << R"(")"; @@ -4832,33 +4850,32 @@ CorrOptionsStatement::writeJsonOutput(ostream &output) const output << "}"; } -OptionsEqualStatement::OptionsEqualStatement(string to_declaration_type_arg, - string to_name1_arg, - string to_name2_arg, - string to_subsample_name_arg, +OptionsEqualStatement::OptionsEqualStatement(string to_declaration_type_arg, string to_name1_arg, + string to_name2_arg, string to_subsample_name_arg, string from_declaration_type_arg, - string from_name1_arg, - string from_name2_arg, + string from_name1_arg, string from_name2_arg, string from_subsample_name_arg, - const SymbolTable &symbol_table_arg) : - to_declaration_type{move(to_declaration_type_arg)}, - to_name1{move(to_name1_arg)}, - to_name2{move(to_name2_arg)}, - to_subsample_name{move(to_subsample_name_arg)}, - from_declaration_type{move(from_declaration_type_arg)}, - from_name1{move(from_name1_arg)}, - from_name2{move(from_name2_arg)}, - from_subsample_name{move(from_subsample_name_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + to_declaration_type {move(to_declaration_type_arg)}, + to_name1 {move(to_name1_arg)}, + to_name2 {move(to_name2_arg)}, + to_subsample_name {move(to_subsample_name_arg)}, + from_declaration_type {move(from_declaration_type_arg)}, + from_name1 {move(from_name1_arg)}, + from_name2 {move(from_name2_arg)}, + from_subsample_name {move(from_subsample_name_arg)}, + symbol_table {symbol_table_arg} { } void -OptionsEqualStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +OptionsEqualStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { - if ((to_declaration_type != "par" && to_declaration_type != "std" && to_declaration_type != "corr") - || (from_declaration_type != "par" && from_declaration_type != "std" && from_declaration_type != "corr")) + if ((to_declaration_type != "par" && to_declaration_type != "std" + && to_declaration_type != "corr") + || (from_declaration_type != "par" && from_declaration_type != "std" + && from_declaration_type != "corr")) { cerr << "Internal Dynare Error" << endl; exit(EXIT_FAILURE); @@ -4866,7 +4883,7 @@ OptionsEqualStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_str } void -OptionsEqualStatement::writeJsonOutput(ostream &output) const +OptionsEqualStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "options_equal")" << R"(, "to_name1": ")" << to_name1 << R"(")"; @@ -4881,7 +4898,7 @@ OptionsEqualStatement::writeJsonOutput(ostream &output) const } void -OptionsEqualStatement::get_base_name(const SymbolType symb_type, string &lhs_field) const +OptionsEqualStatement::get_base_name(const SymbolType symb_type, string& lhs_field) const { if (symb_type == SymbolType::exogenous) lhs_field = "structural_innovation"; @@ -4890,7 +4907,7 @@ OptionsEqualStatement::get_base_name(const SymbolType symb_type, string &lhs_fie } void -OptionsEqualStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +OptionsEqualStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { string lhs_field, rhs_field; @@ -4912,9 +4929,9 @@ OptionsEqualStatement::writeOutput(ostream &output, [[maybe_unused]] const strin rhs_field += "_corr"; output << "ei_to_ind = get_new_or_existing_ei_index('" << lhs_field << "_options_index', '" - << to_name1 << "', '" << to_name2<< "');" << endl + << to_name1 << "', '" << to_name2 << "');" << endl << "ei_from_ind = get_new_or_existing_ei_index('" << rhs_field << "_options_index', '" - << from_name1 << "', '" << from_name2<< "');" << endl + << from_name1 << "', '" << from_name2 << "');" << endl << "estimation_info." << lhs_field << "_options_index(ei_to_ind) = {'" << to_name1; if (to_declaration_type == "corr") @@ -4934,8 +4951,10 @@ OptionsEqualStatement::writeOutput(ostream &output, [[maybe_unused]] const strin lhs_field += ".options"; else { - output << "subsamples_to_indx = get_existing_subsamples_indx('" << to_name1 << "','" << to_name2 << "');" << endl - << "ei_to_ss_ind = get_subsamples_range_indx(subsamples_to_indx, '" << to_subsample_name << "');" << endl; + output << "subsamples_to_indx = get_existing_subsamples_indx('" << to_name1 << "','" + << to_name2 << "');" << endl + << "ei_to_ss_ind = get_subsamples_range_indx(subsamples_to_indx, '" + << to_subsample_name << "');" << endl; lhs_field += ".subsample_options(ei_to_ss_ind)"; } @@ -4943,8 +4962,10 @@ OptionsEqualStatement::writeOutput(ostream &output, [[maybe_unused]] const strin rhs_field += ".options"; else { - output << "subsamples_from_indx = get_existing_subsamples_indx('" << from_name1 << "','" << from_name2 << "');" << endl - << "ei_from_ss_ind = get_subsamples_range_indx(subsamples_from_indx, '" << from_subsample_name << "');" << endl; + output << "subsamples_from_indx = get_existing_subsamples_indx('" << from_name1 << "','" + << from_name2 << "');" << endl + << "ei_from_ss_ind = get_subsamples_range_indx(subsamples_from_indx, '" + << from_subsample_name << "');" << endl; rhs_field += ".subsample_options(ei_from_ss_ind)"; } @@ -4953,22 +4974,22 @@ OptionsEqualStatement::writeOutput(ostream &output, [[maybe_unused]] const strin CalibSmootherStatement::CalibSmootherStatement(SymbolList symbol_list_arg, OptionsList options_list_arg, - const SymbolTable &symbol_table_arg) : - symbol_list{move(symbol_list_arg)}, - options_list{move(options_list_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + symbol_list {move(symbol_list_arg)}, + options_list {move(options_list_arg)}, + symbol_table {symbol_table_arg} { } void -CalibSmootherStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) +CalibSmootherStatement::checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) { mod_file_struct.calib_smoother_present = true; try { - symbol_list.checkPass(warnings, { SymbolType::endogenous }, symbol_table); + symbol_list.checkPass(warnings, {SymbolType::endogenous}, symbol_table); } - catch (SymbolList::SymbolListException &e) + catch (SymbolList::SymbolListException& e) { cerr << "ERROR: calib_smoother: " << e.message << endl; exit(EXIT_FAILURE); @@ -4976,7 +4997,7 @@ CalibSmootherStatement::checkPass(ModFileStructure &mod_file_struct, WarningCons } void -CalibSmootherStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +CalibSmootherStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); @@ -4985,11 +5006,13 @@ CalibSmootherStatement::writeOutput(ostream &output, [[maybe_unused]] const stri symbol_list.writeOutput("var_list_", output); output << "options_.smoother = true;" << endl << "options_.order = 1;" << endl - << "[oo_, M_, options_, bayestopt_] = evaluate_smoother(options_.parameter_set, var_list_, M_, oo_, options_, bayestopt_, estim_params_);" << endl; + << "[oo_, M_, options_, bayestopt_] = evaluate_smoother(options_.parameter_set, " + "var_list_, M_, oo_, options_, bayestopt_, estim_params_);" + << endl; } void -CalibSmootherStatement::writeJsonOutput(ostream &output) const +CalibSmootherStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "calib_smoother")"; if (!options_list.empty()) @@ -5005,14 +5028,14 @@ CalibSmootherStatement::writeJsonOutput(ostream &output) const output << "}"; } -ExtendedPathStatement::ExtendedPathStatement(OptionsList options_list_arg) - : options_list{move(options_list_arg)} +ExtendedPathStatement::ExtendedPathStatement(OptionsList options_list_arg) : + options_list {move(options_list_arg)} { } void -ExtendedPathStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +ExtendedPathStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.extended_path_present = true; @@ -5024,7 +5047,7 @@ ExtendedPathStatement::checkPass(ModFileStructure &mod_file_struct, } void -ExtendedPathStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +ExtendedPathStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { // Beware: options do not have the same name in the interface and in the M code... @@ -5038,7 +5061,7 @@ ExtendedPathStatement::writeOutput(ostream &output, [[maybe_unused]] const strin } void -ExtendedPathStatement::writeJsonOutput(ostream &output) const +ExtendedPathStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "extended_path")"; if (!options_list.empty()) @@ -5050,25 +5073,25 @@ ExtendedPathStatement::writeJsonOutput(ostream &output) const } void -ModelDiagnosticsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +ModelDiagnosticsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "model_diagnostics(M_,options_,oo_);" << endl; } void -ModelDiagnosticsStatement::writeJsonOutput(ostream &output) const +ModelDiagnosticsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "model_diagnostics"})"; } Smoother2histvalStatement::Smoother2histvalStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -Smoother2histvalStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +Smoother2histvalStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output, "options_smoother2histval"); @@ -5076,7 +5099,7 @@ Smoother2histvalStatement::writeOutput(ostream &output, [[maybe_unused]] const s } void -Smoother2histvalStatement::writeJsonOutput(ostream &output) const +Smoother2histvalStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "smoother_2_histval")"; if (!options_list.empty()) @@ -5088,13 +5111,13 @@ Smoother2histvalStatement::writeJsonOutput(ostream &output) const } MethodOfMomentsStatement::MethodOfMomentsStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -MethodOfMomentsStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +MethodOfMomentsStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.mom_estimation_present = true; // Fill in option_order of mod_file_struct @@ -5111,17 +5134,22 @@ MethodOfMomentsStatement::checkPass(ModFileStructure &mod_file_struct, if (!options_list.contains("mom.mom_method")) { - cerr << "ERROR: The 'method_of_moments' statement requires a method to be supplied via the 'mom_method' option. Possible values are 'GMM', 'SMM', or 'IRF_MATCHING'." << endl; + cerr << "ERROR: The 'method_of_moments' statement requires a method to be supplied via the " + "'mom_method' option. Possible values are 'GMM', 'SMM', or 'IRF_MATCHING'." + << endl; exit(EXIT_FAILURE); } auto mom_method_value = options_list.get_if("mom.mom_method"); - if ((mom_method_value == "GMM" || mom_method_value == "SMM") && !options_list.contains("datafile")) + if ((mom_method_value == "GMM" || mom_method_value == "SMM") + && !options_list.contains("datafile")) { - cerr << "ERROR: The 'method_of_moments' statement requires a data file to be supplied via the 'datafile' option." << endl; + cerr << "ERROR: The 'method_of_moments' statement requires a data file to be supplied via " + "the 'datafile' option." + << endl; exit(EXIT_FAILURE); } - + if (auto opt = options_list.get_if("mom.mom_method"); opt && *opt == "GMM") mod_file_struct.GMM_present = true; @@ -5135,7 +5163,7 @@ MethodOfMomentsStatement::checkPass(ModFileStructure &mod_file_struct, cerr << "ERROR: The analytic_standard_errors statement requires the GMM option." << endl; exit(EXIT_FAILURE); } - + if (auto opt = options_list.get_if("mom.analytic_jacobian"); opt && *opt == "true") mod_file_struct.analytic_jacobian_present = true; @@ -5148,16 +5176,18 @@ MethodOfMomentsStatement::checkPass(ModFileStructure &mod_file_struct, } void -MethodOfMomentsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +MethodOfMomentsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output, "options_mom_"); - output << "[oo_, options_mom_, M_] = mom.run(bayestopt_, options_, oo_, estim_params_, M_, options_mom_);" << endl; + output << "[oo_, options_mom_, M_] = mom.run(bayestopt_, options_, oo_, estim_params_, M_, " + "options_mom_);" + << endl; } void -MethodOfMomentsStatement::writeJsonOutput(ostream &output) const +MethodOfMomentsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "method_of_moments")"; if (!options_list.empty()) @@ -5168,18 +5198,17 @@ MethodOfMomentsStatement::writeJsonOutput(ostream &output) const output << "}"; } - -GenerateIRFsStatement::GenerateIRFsStatement(OptionsList options_list_arg, - vector generate_irf_names_arg, - vector> generate_irf_elements_arg) : - options_list{move(options_list_arg)}, - generate_irf_names{move(generate_irf_names_arg)}, - generate_irf_elements{move(generate_irf_elements_arg)} +GenerateIRFsStatement::GenerateIRFsStatement( + OptionsList options_list_arg, vector generate_irf_names_arg, + vector> generate_irf_elements_arg) : + options_list {move(options_list_arg)}, + generate_irf_names {move(generate_irf_names_arg)}, + generate_irf_elements {move(generate_irf_elements_arg)} { } void -GenerateIRFsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +GenerateIRFsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); @@ -5188,22 +5217,21 @@ GenerateIRFsStatement::writeOutput(ostream &output, [[maybe_unused]] const strin return; output << "options_.irf_opt.irf_shock_graphtitles = { "; - for (const auto &generate_irf_name : generate_irf_names) + for (const auto& generate_irf_name : generate_irf_names) output << "'" << generate_irf_name << "'; "; output << "};" << endl; - output << "options_.irf_opt.irf_shocks = zeros(M_.exo_nbr, " - << generate_irf_names.size() << ");" << endl; + output << "options_.irf_opt.irf_shocks = zeros(M_.exo_nbr, " << generate_irf_names.size() << ");" + << endl; for (size_t i = 0; i < generate_irf_names.size(); i++) - for (auto &[exo_name, exo_value] : generate_irf_elements[i]) - output << "options_.irf_opt.irf_shocks(M_.exo_names == '" - << exo_name << "', " << i + 1 << ") = " - << exo_value << ";" << endl; + for (auto& [exo_name, exo_value] : generate_irf_elements[i]) + output << "options_.irf_opt.irf_shocks(M_.exo_names == '" << exo_name << "', " << i + 1 + << ") = " << exo_value << ";" << endl; } void -GenerateIRFsStatement::writeJsonOutput(ostream &output) const +GenerateIRFsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "generate_irfs")"; if (!options_list.empty()) @@ -5218,8 +5246,8 @@ GenerateIRFsStatement::writeJsonOutput(ostream &output) const for (size_t i = 0; i < generate_irf_names.size(); i++) { output << R"({"name": ")" << generate_irf_names[i] << R"(", "shocks": [)"; - for (bool printed_something{false}; - auto &[exo_name, exo_value] : generate_irf_elements[i]) + for (bool printed_something {false}; + auto& [exo_name, exo_value] : generate_irf_elements[i]) { if (exchange(printed_something, true)) output << ", "; @@ -5235,22 +5263,23 @@ GenerateIRFsStatement::writeJsonOutput(ostream &output) const output << "}"; } -MatchedMomentsStatement::MatchedMomentsStatement(const SymbolTable &symbol_table_arg, - vector, vector, vector>> moments_arg) : - symbol_table{symbol_table_arg}, moments{move(moments_arg)} +MatchedMomentsStatement::MatchedMomentsStatement( + const SymbolTable& symbol_table_arg, + vector, vector, vector>> moments_arg) : + symbol_table {symbol_table_arg}, moments {move(moments_arg)} { } void -MatchedMomentsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +MatchedMomentsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "M_.matched_moments = {" << endl; - for (const auto &[symb_ids, lags, powers] : moments) + for (const auto& [symb_ids, lags, powers] : moments) { output << " ["; for (int s : symb_ids) - output << symbol_table.getTypeSpecificID(s)+1 << ','; + output << symbol_table.getTypeSpecificID(s) + 1 << ','; output << "], ["; for (int l : lags) output << l << ','; @@ -5263,33 +5292,29 @@ MatchedMomentsStatement::writeOutput(ostream &output, [[maybe_unused]] const str } void -MatchedMomentsStatement::writeJsonOutput(ostream &output) const +MatchedMomentsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "matched_moments", "moments": [)" << endl; - for (bool printed_something{false}; - const auto &[symb_ids, lags, powers] : moments) + for (bool printed_something {false}; const auto& [symb_ids, lags, powers] : moments) { if (exchange(printed_something, true)) output << ','; output << R"( { "endos": [)"; - for (bool printed_something2{false}; - int s : symb_ids) + for (bool printed_something2 {false}; int s : symb_ids) { if (exchange(printed_something2, true)) output << ','; - output << symbol_table.getTypeSpecificID(s)+1; + output << symbol_table.getTypeSpecificID(s) + 1; } output << R"(], "lags": [)"; - for (bool printed_something2{false}; - int l : lags) + for (bool printed_something2 {false}; int l : lags) { if (exchange(printed_something2, true)) output << ','; output << l; } output << R"(], "powers": [)"; - for (bool printed_something2{false}; - int p : powers) + for (bool printed_something2 {false}; int p : powers) { if (exchange(printed_something2, true)) output << ','; @@ -5300,15 +5325,16 @@ MatchedMomentsStatement::writeJsonOutput(ostream &output) const output << "]}" << endl; } -OccbinConstraintsStatement::OccbinConstraintsStatement(const DataTree &data_tree_arg, - vector> constraints_arg) - : data_tree{data_tree_arg}, constraints{move(constraints_arg)} +OccbinConstraintsStatement::OccbinConstraintsStatement( + const DataTree& data_tree_arg, + vector> constraints_arg) : + data_tree {data_tree_arg}, constraints {move(constraints_arg)} { } void -OccbinConstraintsStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +OccbinConstraintsStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { if (mod_file_struct.occbin_constraints_present) { @@ -5317,46 +5343,51 @@ OccbinConstraintsStatement::checkPass(ModFileStructure &mod_file_struct, } if (constraints.size() > 2) { - cerr << "ERROR: only up to two constraints are supported in 'occbin_constraints' block" << endl; + cerr << "ERROR: only up to two constraints are supported in 'occbin_constraints' block" + << endl; exit(EXIT_FAILURE); } mod_file_struct.occbin_constraints_present = true; } void -OccbinConstraintsStatement::writeOutput(ostream &output, const string &basename, +OccbinConstraintsStatement::writeOutput(ostream& output, const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "M_.occbin.constraint_nbr = " << constraints.size() << ';' << endl << "M_.occbin.pswitch = [" << endl; - for (const auto &[name, bind, relax, error_bind, error_relax] : constraints) - output << data_tree.symbol_table.getTypeSpecificID(ParsingDriver::buildOccbinBindParamName(name)) + 1 << ' '; + for (const auto& [name, bind, relax, error_bind, error_relax] : constraints) + output << data_tree.symbol_table.getTypeSpecificID( + ParsingDriver::buildOccbinBindParamName(name)) + + 1 + << ' '; output << "];" << endl << "options_.occbin = struct();" << endl << "options_.occbin = occbin.set_default_options(options_.occbin, M_);" << endl - << "oo_.dr=set_state_space(oo_.dr,M_);" << endl; + << "oo_.dr=set_state_space(oo_.dr,M_);" << endl; filesystem::path filename {"+" + basename + "/occbin_difference.m"}; - ofstream diff_output{filename, ios::out | ios::binary}; + ofstream diff_output {filename, ios::out | ios::binary}; if (!diff_output.is_open()) { cerr << "Error: Can't open file " << filename.string() << " for writing" << endl; exit(EXIT_FAILURE); } - diff_output << "function [binding, relax, err] = occbin_difference(zdatalinear, params, steady_state)" << endl; - for (int idx{1}; - const auto &[name, bind, relax, error_bind, error_relax] : constraints) + diff_output + << "function [binding, relax, err] = occbin_difference(zdatalinear, params, steady_state)" + << endl; + for (int idx {1}; const auto& [name, bind, relax, error_bind, error_relax] : constraints) { diff_output << "binding.constraint_" << idx << " = "; - dynamic_cast(bind)->writeOutput(diff_output, ExprNodeOutputType::occbinDifferenceFile); - diff_output << ';' << endl - << "relax.constraint_" << idx << " = "; + dynamic_cast(bind)->writeOutput(diff_output, + ExprNodeOutputType::occbinDifferenceFile); + diff_output << ';' << endl << "relax.constraint_" << idx << " = "; if (relax) - dynamic_cast(relax)->writeOutput(diff_output, ExprNodeOutputType::occbinDifferenceFile); + dynamic_cast(relax)->writeOutput(diff_output, + ExprNodeOutputType::occbinDifferenceFile); else diff_output << "~binding.constraint_" << idx; - diff_output << ';' << endl - << "err.binding_constraint_" << idx << " = "; + diff_output << ';' << endl << "err.binding_constraint_" << idx << " = "; if (error_bind) error_bind->writeOutput(diff_output, ExprNodeOutputType::occbinDifferenceFile); else @@ -5367,8 +5398,7 @@ OccbinConstraintsStatement::writeOutput(ostream &output, const string &basename, bind->arg2->writeOutput(diff_output, ExprNodeOutputType::occbinDifferenceFile); diff_output << "))"; } - diff_output << ';' << endl - << "err.relax_constraint_" << idx << " = "; + diff_output << ';' << endl << "err.relax_constraint_" << idx << " = "; if (error_relax) error_relax->writeOutput(diff_output, ExprNodeOutputType::occbinDifferenceFile); else if (relax) @@ -5402,19 +5432,19 @@ OccbinConstraintsStatement::writeOutput(ostream &output, const string &basename, } void -OccbinConstraintsStatement::writeJsonOutput(ostream &output) const +OccbinConstraintsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "occbin_constraints", "constraints": [)" << endl; - for (bool printed_something{false}; - const auto &[name, bind, relax, error_bind, error_relax] : constraints) + for (bool printed_something {false}; + const auto& [name, bind, relax, error_bind, error_relax] : constraints) { if (exchange(printed_something, true)) output << ','; output << R"({ "name": ")" << name << R"(", "bind": ")"; - dynamic_cast(bind)->writeJsonOutput(output, {}, {}); + dynamic_cast(bind)->writeJsonOutput(output, {}, {}); output << R"(", "relax": ")"; if (relax) - dynamic_cast(relax)->writeJsonOutput(output, {}, {}); + dynamic_cast(relax)->writeJsonOutput(output, {}, {}); output << R"(", "error_bind": ")"; if (error_bind) error_bind->writeJsonOutput(output, {}, {}); @@ -5426,13 +5456,12 @@ OccbinConstraintsStatement::writeJsonOutput(ostream &output) const output << "]}" << endl; } -ResidStatement::ResidStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} +ResidStatement::ResidStatement(OptionsList options_list_arg) : options_list {move(options_list_arg)} { } void -ResidStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +ResidStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output, "options_resid_"); @@ -5440,7 +5469,7 @@ ResidStatement::writeOutput(ostream &output, [[maybe_unused]] const string &base } void -ResidStatement::writeJsonOutput(ostream &output) const +ResidStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "resid")"; if (!options_list.empty()) diff --git a/src/ComputingTasks.hh b/src/ComputingTasks.hh index 16569217..acd551eb 100644 --- a/src/ComputingTasks.hh +++ b/src/ComputingTasks.hh @@ -20,89 +20,96 @@ #ifndef _COMPUTINGTASKS_HH #define _COMPUTINGTASKS_HH -#include #include +#include -#include "SymbolList.hh" -#include "SymbolTable.hh" -#include "Statement.hh" -#include "StaticModel.hh" #include "DynamicModel.hh" #include "ModelEquationBlock.hh" +#include "Statement.hh" +#include "StaticModel.hh" +#include "SymbolList.hh" +#include "SymbolTable.hh" class SteadyStatement : public Statement { private: const OptionsList options_list; + public: explicit SteadyStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class CheckStatement : public Statement { private: const OptionsList options_list; + public: explicit CheckStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class SimulStatement : public Statement { private: const OptionsList options_list; + public: explicit SimulStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class PerfectForesightSetupStatement : public Statement { private: const OptionsList options_list; + public: explicit PerfectForesightSetupStatement(OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class PerfectForesightSolverStatement : public Statement { private: const OptionsList options_list; + public: explicit PerfectForesightSolverStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class PerfectForesightWithExpectationErrorsSetupStatement : public Statement { private: const OptionsList options_list; + public: explicit PerfectForesightWithExpectationErrorsSetupStatement(OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class PerfectForesightWithExpectationErrorsSolverStatement : public Statement { private: const OptionsList options_list; + public: explicit PerfectForesightWithExpectationErrorsSolverStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class PriorPosteriorFunctionStatement : public Statement @@ -110,21 +117,23 @@ class PriorPosteriorFunctionStatement : public Statement private: const bool prior_func; const OptionsList options_list; + public: PriorPosteriorFunctionStatement(const bool prior_func_arg, 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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class ModelInfoStatement : public Statement { private: const OptionsList options_list; + public: explicit ModelInfoStatement(OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class StochSimulStatement : public Statement @@ -132,13 +141,14 @@ class StochSimulStatement : public Statement private: const SymbolList symbol_list; const OptionsList options_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: StochSimulStatement(SymbolList symbol_list_arg, OptionsList options_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class ForecastStatement : public Statement @@ -146,24 +156,26 @@ class ForecastStatement : public Statement private: const SymbolList symbol_list; const OptionsList options_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: ForecastStatement(SymbolList symbol_list_arg, OptionsList options_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class RamseyModelStatement : public Statement { private: const OptionsList options_list; + public: explicit RamseyModelStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class RamseyConstraintsStatement : public Statement @@ -176,14 +188,16 @@ public: expr_t expression; }; using constraints_t = vector; + private: - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; const constraints_t constraints; + public: - RamseyConstraintsStatement(const SymbolTable &symbol_table_arg, constraints_t constraints_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; + RamseyConstraintsStatement(const SymbolTable& symbol_table_arg, constraints_t constraints_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; }; class RamseyPolicyStatement : public Statement @@ -191,53 +205,58 @@ class RamseyPolicyStatement : public Statement private: const SymbolList symbol_list; const OptionsList options_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: RamseyPolicyStatement(SymbolList symbol_list_arg, OptionsList options_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class EvaluatePlannerObjectiveStatement : public Statement { private: const OptionsList options_list; + public: explicit EvaluatePlannerObjectiveStatement(OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class OccbinSetupStatement : public Statement { private: const OptionsList options_list; + public: explicit OccbinSetupStatement(OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class OccbinSolverStatement : public Statement { private: const OptionsList options_list; + public: explicit OccbinSolverStatement(OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class OccbinWriteRegimesStatement : public Statement { private: const OptionsList options_list; + public: explicit OccbinWriteRegimesStatement(OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class OccbinGraphStatement : public Statement @@ -245,11 +264,11 @@ class OccbinGraphStatement : public Statement private: const SymbolList symbol_list; const OptionsList options_list; + public: - OccbinGraphStatement(SymbolList symbol_list_arg, - OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + OccbinGraphStatement(SymbolList symbol_list_arg, OptionsList options_list_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class DiscretionaryPolicyStatement : public Statement @@ -257,123 +276,134 @@ class DiscretionaryPolicyStatement : public Statement private: const SymbolList symbol_list; const OptionsList options_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: DiscretionaryPolicyStatement(SymbolList symbol_list_arg, OptionsList options_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class RplotStatement : public Statement { private: const SymbolList symbol_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: - RplotStatement(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; - void writeJsonOutput(ostream &output) const override; + RplotStatement(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; + void writeJsonOutput(ostream& output) const override; }; class UnitRootVarsStatement : public Statement { public: - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class DsampleStatement : public Statement { private: const int val1, val2; + public: explicit DsampleStatement(int val1_arg); DsampleStatement(int val1_arg, int val2_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class EstimationStatement : public Statement { private: - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; const SymbolList symbol_list; const OptionsList options_list; + public: - EstimationStatement(const SymbolTable &symbol_table_arg, - SymbolList symbol_list_arg, + EstimationStatement(const SymbolTable& symbol_table_arg, SymbolList symbol_list_arg, 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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class DynareSensitivityStatement : public Statement { private: const OptionsList options_list; + public: explicit DynareSensitivityStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class ObservationTrendsStatement : public Statement { public: using trend_elements_t = map; + private: const trend_elements_t trend_elements; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: ObservationTrendsStatement(trend_elements_t trend_elements_arg, - const SymbolTable &symbol_table_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + const SymbolTable& symbol_table_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class DeterministicTrendsStatement : public Statement { public: using trend_elements_t = map; + private: const trend_elements_t trend_elements; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: DeterministicTrendsStatement(trend_elements_t trend_elements_arg, - const SymbolTable &symbol_table_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + const SymbolTable& symbol_table_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class FilterInitialStateStatement : public Statement { public: using filter_initial_state_elements_t = map, expr_t>; + private: const filter_initial_state_elements_t filter_initial_state_elements; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: FilterInitialStateStatement(filter_initial_state_elements_t filter_initial_state_elements_arg, - const SymbolTable &symbol_table_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + const SymbolTable& symbol_table_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class OsrParamsStatement : public Statement { private: const SymbolList symbol_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: - OsrParamsStatement(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; - void writeJsonOutput(ostream &output) const override; + OsrParamsStatement(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; + void writeJsonOutput(ostream& output) const override; }; class OsrStatement : public Statement @@ -381,13 +411,14 @@ class OsrStatement : public Statement private: const SymbolList symbol_list; const OptionsList options_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: OsrStatement(SymbolList symbol_list_arg, OptionsList options_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; //! Temporary structure used when parsing estimation_params* statements @@ -398,7 +429,7 @@ public: expr_t low_bound, up_bound; void - init(const DataTree &datatree) + init(const DataTree& datatree) { name = ""; low_bound = datatree.MinusInfinity; @@ -410,11 +441,12 @@ class OsrParamsBoundsStatement : public Statement { private: const vector osr_params_list; + public: explicit OsrParamsBoundsStatement(vector osr_params_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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class DynaTypeStatement : public Statement @@ -422,13 +454,14 @@ class DynaTypeStatement : public Statement private: const SymbolList symbol_list; const string filename; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: DynaTypeStatement(SymbolList symbol_list_arg, string filename_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class DynaSaveStatement : public Statement @@ -436,27 +469,29 @@ class DynaSaveStatement : public Statement private: const SymbolList symbol_list; const string filename; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: DynaSaveStatement(SymbolList symbol_list_arg, string filename_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class ModelComparisonStatement : public Statement { public: using filename_list_t = vector>; + private: filename_list_t filename_list; OptionsList options_list; + public: - ModelComparisonStatement(filename_list_t filename_list_arg, - OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + ModelComparisonStatement(filename_list_t filename_list_arg, OptionsList options_list_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; //! Temporary structure used when parsing estimation_params* statements @@ -469,7 +504,7 @@ public: expr_t init_val, low_bound, up_bound, mean, std, p3, p4, jscale; void - init(const DataTree &datatree) + init(const DataTree& datatree) { type = 0; name = ""; @@ -490,9 +525,9 @@ class AbstractEstimatedParamsStatement : public Statement { protected: const vector estim_params_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; AbstractEstimatedParamsStatement(vector estim_params_list_arg, - const SymbolTable &symbol_table_arg); + const SymbolTable& symbol_table_arg); virtual string blockName() const = 0; // Part of the check pass that is common to the three estimated_params{,_init,bounds} blocks void commonCheckPass() const; @@ -502,39 +537,51 @@ class EstimatedParamsStatement : public AbstractEstimatedParamsStatement { private: const bool overwrite; + public: EstimatedParamsStatement(vector estim_params_list_arg, - const SymbolTable &symbol_table_arg, - bool overwrite_arg); - string blockName() const override { return "estimated_params"; }; - void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override; - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + const SymbolTable& symbol_table_arg, bool overwrite_arg); + string + blockName() const override + { + return "estimated_params"; + }; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class EstimatedParamsInitStatement : public AbstractEstimatedParamsStatement { private: const bool use_calibration; + public: EstimatedParamsInitStatement(vector estim_params_list_arg, - const SymbolTable &symbol_table_arg, - const bool use_calibration_arg); - string blockName() const override { return "estimated_params_init"; }; - void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override; - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + const SymbolTable& symbol_table_arg, const bool use_calibration_arg); + string + blockName() const override + { + return "estimated_params_init"; + }; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class EstimatedParamsBoundsStatement : public AbstractEstimatedParamsStatement { public: EstimatedParamsBoundsStatement(vector estim_params_list_arg, - const SymbolTable &symbol_table_arg); - string blockName() const override { return "estimated_params_bounds"; }; - void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override; - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + const SymbolTable& symbol_table_arg); + string + blockName() const override + { + return "estimated_params_bounds"; + }; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class EstimatedParamsRemoveStatement : public Statement @@ -542,11 +589,11 @@ class EstimatedParamsRemoveStatement : public Statement public: // Only the type, name and name2 fields of EstimationParams are used const vector estim_params_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; EstimatedParamsRemoveStatement(vector estim_params_list_arg, - const SymbolTable &symbol_table_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + const SymbolTable& symbol_table_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class OptimWeightsStatement : public Statement @@ -554,35 +601,37 @@ class OptimWeightsStatement : public Statement public: using var_weights_t = map; using covar_weights_t = map, expr_t>; + private: const var_weights_t var_weights; const covar_weights_t covar_weights; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: - OptimWeightsStatement(var_weights_t var_weights_arg, - covar_weights_t covar_weights_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; - void writeJsonOutput(ostream &output) const override; + OptimWeightsStatement(var_weights_t var_weights_arg, covar_weights_t covar_weights_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; + void writeJsonOutput(ostream& output) const override; }; class PlannerObjectiveStatement : public Statement { private: PlannerObjective model_tree; - bool computing_pass_called{false}; + bool computing_pass_called {false}; + public: - explicit PlannerObjectiveStatement(const PlannerObjective &model_tree_arg); + explicit PlannerObjectiveStatement(const PlannerObjective& model_tree_arg); /*! \todo check there are only endogenous variables at the current period in the objective (no exogenous, no lead/lag) */ - void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; /*! \todo allow for the possibility of disabling temporary terms */ - void computingPass(const ModFileStructure &mod_file_struct) override; - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void computingPass(const ModFileStructure& mod_file_struct) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; //! Return a reference the Planner Objective model tree - const PlannerObjective &getPlannerObjective() const; + const PlannerObjective& getPlannerObjective() const; }; class BVARDensityStatement : public Statement @@ -590,11 +639,12 @@ class BVARDensityStatement : public Statement private: const int maxnlags; const OptionsList options_list; + public: BVARDensityStatement(int maxnlags_arg, 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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class BVARForecastStatement : public Statement @@ -602,11 +652,12 @@ class BVARForecastStatement : public Statement private: const int nlags; const OptionsList options_list; + public: BVARForecastStatement(int nlags_arg, 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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class BVARIRFStatement : public Statement @@ -614,66 +665,72 @@ class BVARIRFStatement : public Statement private: const int nirf; const string identificationname; + public: BVARIRFStatement(int nirf_arg, string identificationname_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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class SBVARStatement : public Statement { private: const OptionsList options_list; + public: explicit SBVARStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class MSSBVAREstimationStatement : public Statement { private: const OptionsList options_list; + public: explicit MSSBVAREstimationStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class MSSBVARSimulationStatement : public Statement { private: const OptionsList options_list; + public: explicit MSSBVARSimulationStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class MSSBVARComputeMDDStatement : public Statement { private: const OptionsList options_list; + public: explicit MSSBVARComputeMDDStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class MSSBVARComputeProbabilitiesStatement : public Statement { private: const OptionsList options_list; + public: explicit MSSBVARComputeProbabilitiesStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class MSSBVARIrfStatement : public Statement @@ -681,90 +738,100 @@ class MSSBVARIrfStatement : public Statement private: const SymbolList symbol_list; const OptionsList options_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: MSSBVARIrfStatement(SymbolList symbol_list_arg, OptionsList options_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class MSSBVARForecastStatement : public Statement { private: const OptionsList options_list; + public: explicit MSSBVARForecastStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class MSSBVARVarianceDecompositionStatement : public Statement { private: const OptionsList options_list; + public: explicit MSSBVARVarianceDecompositionStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class IdentificationStatement : public Statement { private: OptionsList options_list; + public: explicit IdentificationStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class WriteLatexDynamicModelStatement : public Statement { private: - const DynamicModel &dynamic_model; + const DynamicModel& dynamic_model; const bool write_equation_tags; + public: - WriteLatexDynamicModelStatement(const DynamicModel &dynamic_model_arg, bool write_equation_tags_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + WriteLatexDynamicModelStatement(const DynamicModel& dynamic_model_arg, + bool write_equation_tags_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class WriteLatexStaticModelStatement : public Statement { private: - const StaticModel &static_model; + const StaticModel& static_model; const bool write_equation_tags; + public: - WriteLatexStaticModelStatement(const StaticModel &static_model_arg, bool write_equation_tags_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + WriteLatexStaticModelStatement(const StaticModel& static_model_arg, bool write_equation_tags_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class WriteLatexOriginalModelStatement : public Statement { private: - const DynamicModel &original_model; + const DynamicModel& original_model; const bool write_equation_tags; + public: - WriteLatexOriginalModelStatement(const DynamicModel &original_model_arg, bool write_equation_tags_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + WriteLatexOriginalModelStatement(const DynamicModel& original_model_arg, + bool write_equation_tags_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class WriteLatexSteadyStateModelStatement : public Statement { private: - const SteadyStateModel &steady_state_model; + const SteadyStateModel& steady_state_model; + public: - explicit WriteLatexSteadyStateModelStatement(const SteadyStateModel &steady_state_model_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; + explicit WriteLatexSteadyStateModelStatement(const SteadyStateModel& steady_state_model_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; }; class ShockDecompositionStatement : public Statement @@ -772,13 +839,14 @@ class ShockDecompositionStatement : public Statement private: const SymbolList symbol_list; const OptionsList options_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: ShockDecompositionStatement(SymbolList symbol_list_arg, OptionsList options_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class RealtimeShockDecompositionStatement : public Statement @@ -786,13 +854,14 @@ class RealtimeShockDecompositionStatement : public Statement private: const SymbolList symbol_list; const OptionsList options_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: RealtimeShockDecompositionStatement(SymbolList symbol_list_arg, OptionsList options_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class PlotShockDecompositionStatement : public Statement @@ -800,13 +869,14 @@ class PlotShockDecompositionStatement : public Statement private: const SymbolList symbol_list; const OptionsList options_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: PlotShockDecompositionStatement(SymbolList symbol_list_arg, OptionsList options_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class InitialConditionDecompositionStatement : public Statement @@ -814,37 +884,40 @@ class InitialConditionDecompositionStatement : public Statement private: const SymbolList symbol_list; const OptionsList options_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: InitialConditionDecompositionStatement(SymbolList symbol_list_arg, OptionsList options_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class SqueezeShockDecompositionStatement : public Statement { private: const SymbolList symbol_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: SqueezeShockDecompositionStatement(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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class ConditionalForecastStatement : public Statement { private: const OptionsList options_list; + public: explicit ConditionalForecastStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class PlotConditionalForecastStatement : public Statement @@ -852,13 +925,14 @@ class PlotConditionalForecastStatement : public Statement private: const optional periods; // The user is allowed not to declare periods const SymbolList symbol_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: PlotConditionalForecastStatement(optional 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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class CalibSmootherStatement : public Statement @@ -866,24 +940,26 @@ class CalibSmootherStatement : public Statement private: const SymbolList symbol_list; const OptionsList options_list; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: CalibSmootherStatement(SymbolList symbol_list_arg, OptionsList options_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class ExtendedPathStatement : public Statement { private: const OptionsList options_list; + public: explicit ExtendedPathStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class SvarIdentificationStatement : public Statement @@ -900,20 +976,21 @@ public: }; using svar_identification_restrictions_t = vector; + private: const svar_identification_restrictions_t restrictions; const bool upper_cholesky_present, lower_cholesky_present, constants_exclusion_present; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; int getMaxLag() const; + public: SvarIdentificationStatement(svar_identification_restrictions_t restrictions_arg, - bool upper_cholesky_present_arg, - bool lower_cholesky_present_arg, + bool upper_cholesky_present_arg, bool lower_cholesky_present_arg, bool constants_exclusion_present_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; class MarkovSwitchingStatement : public Statement @@ -921,50 +998,54 @@ class MarkovSwitchingStatement : public Statement private: const OptionsList options_list; map, double> restriction_map; + public: explicit MarkovSwitchingStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class SvarStatement : public Statement { private: const OptionsList options_list; + public: explicit SvarStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class SvarGlobalIdentificationCheckStatement : public Statement { public: - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class SetTimeStatement : public Statement { private: const OptionsList options_list; + public: explicit SetTimeStatement(OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class EstimationDataStatement : public Statement { private: const OptionsList options_list; + public: explicit EstimationDataStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class SubsamplesStatement : public Statement @@ -972,32 +1053,31 @@ class SubsamplesStatement : public Statement public: //! Storage for declaring subsamples: map using subsample_declaration_map_t = map>; + private: const string name1, name2; const subsample_declaration_map_t subsample_declaration_map; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: - SubsamplesStatement(string name1_arg, - string name2_arg, + SubsamplesStatement(string name1_arg, string name2_arg, subsample_declaration_map_t subsample_declaration_map_arg, - const SymbolTable &symbol_table_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + const SymbolTable& symbol_table_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class SubsamplesEqualStatement : public Statement { private: const string to_name1, to_name2, from_name1, from_name2; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: - SubsamplesEqualStatement(string to_name1_arg, - string to_name2_arg, - string from_name1_arg, - string from_name2_arg, - const SymbolTable &symbol_table_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + SubsamplesEqualStatement(string to_name1_arg, string to_name2_arg, string from_name1_arg, + string from_name2_arg, const SymbolTable& symbol_table_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class JointPriorStatement : public Statement @@ -1006,14 +1086,14 @@ private: const vector joint_parameters; const PriorDistributions prior_shape; const OptionsList options_list; - void writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const; + void writeOutputHelper(ostream& output, const string& field, const string& lhs_field) const; + public: - JointPriorStatement(vector joint_parameters_arg, - PriorDistributions prior_shape_arg, + JointPriorStatement(vector joint_parameters_arg, PriorDistributions prior_shape_arg, 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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class BasicPriorStatement : public Statement @@ -1023,68 +1103,58 @@ protected: const PriorDistributions prior_shape; const expr_t variance; const OptionsList options_list; - BasicPriorStatement(string name_arg, - string subsample_name_arg, - PriorDistributions prior_shape_arg, - expr_t variance_arg, + BasicPriorStatement(string name_arg, string subsample_name_arg, + PriorDistributions prior_shape_arg, expr_t variance_arg, OptionsList options_list_arg); - void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override; - void get_base_name(const SymbolType symb_type, string &lhs_field) const; - void writeCommonOutput(ostream &output, const string &lhs_field) const; - void writeCommonOutputHelper(ostream &output, const string &field, const string &lhs_field) const; - void writePriorOutput(ostream &output, string &lhs_field, const string &name2) const; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void get_base_name(const SymbolType symb_type, string& lhs_field) const; + void writeCommonOutput(ostream& output, const string& lhs_field) const; + void writeCommonOutputHelper(ostream& output, const string& field, const string& lhs_field) const; + void writePriorOutput(ostream& output, string& lhs_field, const string& name2) const; bool is_structural_innovation(const SymbolType symb_type) const; - void writePriorIndex(ostream &output, const string &lhs_field) const; - void writeVarianceOption(ostream &output, const string &lhs_field) const; - void writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const; - void writeShape(ostream &output, const string &lhs_field) const; - void writeJsonShape(ostream &output) const; - void writeJsonPriorOutput(ostream &output) const; + void writePriorIndex(ostream& output, const string& lhs_field) const; + void writeVarianceOption(ostream& output, const string& lhs_field) const; + void writeOutputHelper(ostream& output, const string& field, const string& lhs_field) const; + void writeShape(ostream& output, const string& lhs_field) const; + void writeJsonShape(ostream& output) const; + void writeJsonPriorOutput(ostream& output) const; }; class PriorStatement : public BasicPriorStatement { public: - PriorStatement(string name_arg, - string subsample_name_arg, - PriorDistributions prior_shape_arg, - expr_t variance_arg, - OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + PriorStatement(string name_arg, string subsample_name_arg, PriorDistributions prior_shape_arg, + expr_t variance_arg, OptionsList options_list_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class StdPriorStatement : public BasicPriorStatement { private: - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: - StdPriorStatement(string name_arg, - string subsample_name_arg, - PriorDistributions prior_shape_arg, - expr_t variance_arg, - OptionsList options_list_arg, - const SymbolTable &symbol_table_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + StdPriorStatement(string name_arg, string subsample_name_arg, PriorDistributions prior_shape_arg, + expr_t variance_arg, OptionsList options_list_arg, + const SymbolTable& symbol_table_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class CorrPriorStatement : public BasicPriorStatement { private: const string name1; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: - CorrPriorStatement(string name_arg1, - string name_arg2, - string subsample_name_arg, - PriorDistributions prior_shape_arg, - expr_t variance_arg, - OptionsList options_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; - void writeJsonOutput(ostream &output) const override; + CorrPriorStatement(string name_arg1, string name_arg2, string subsample_name_arg, + PriorDistributions prior_shape_arg, expr_t variance_arg, + OptionsList options_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; + void writeJsonOutput(ostream& output) const override; }; class PriorEqualStatement : public Statement @@ -1092,21 +1162,17 @@ class PriorEqualStatement : public Statement private: const string to_declaration_type, to_name1, to_name2, to_subsample_name; const string from_declaration_type, from_name1, from_name2, from_subsample_name; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: - PriorEqualStatement(string to_declaration_type_arg, - string to_name1_arg, - string to_name2_arg, - string to_subsample_name_arg, - string from_declaration_type_arg, - string from_name1_arg, - string from_name2_arg, - string from_subsample_name_arg, - const SymbolTable &symbol_table_arg); - void get_base_name(const SymbolType symb_type, string &lhs_field) const; - 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; + PriorEqualStatement(string to_declaration_type_arg, string to_name1_arg, string to_name2_arg, + string to_subsample_name_arg, string from_declaration_type_arg, + string from_name1_arg, string from_name2_arg, string from_subsample_name_arg, + const SymbolTable& symbol_table_arg); + void get_base_name(const SymbolType symb_type, string& lhs_field) const; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class BasicOptionsStatement : public Statement @@ -1114,53 +1180,49 @@ class BasicOptionsStatement : public Statement protected: const string name, subsample_name; const OptionsList options_list; - BasicOptionsStatement(string name_arg, - string subsample_name_arg, - OptionsList options_list_arg); - void get_base_name(const SymbolType symb_type, string &lhs_field) const; - void writeOptionsOutput(ostream &output, string &lhs_field, const string &name2) const; - void writeCommonOutput(ostream &output, const string &lhs_field) const; - void writeCommonOutputHelper(ostream &output, const string &field, const string &lhs_field) const; + BasicOptionsStatement(string name_arg, string subsample_name_arg, OptionsList options_list_arg); + void get_base_name(const SymbolType symb_type, string& lhs_field) const; + void writeOptionsOutput(ostream& output, string& lhs_field, const string& name2) const; + void writeCommonOutput(ostream& output, const string& lhs_field) const; + void writeCommonOutputHelper(ostream& output, const string& field, const string& lhs_field) const; bool is_structural_innovation(const SymbolType symb_type) const; - void writeOptionsIndex(ostream &output, const string &lhs_field) const; - void writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const; - void writeJsonOptionsOutput(ostream &output) const; + void writeOptionsIndex(ostream& output, const string& lhs_field) const; + void writeOutputHelper(ostream& output, const string& field, const string& lhs_field) const; + void writeJsonOptionsOutput(ostream& output) const; }; class OptionsStatement : public BasicOptionsStatement { public: OptionsStatement(string name_arg, string subsample_name_arg, OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class StdOptionsStatement : public BasicOptionsStatement { private: - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: - StdOptionsStatement(string name_arg, - string subsample_name_arg, - OptionsList options_list_arg, - const SymbolTable &symbol_table_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + StdOptionsStatement(string name_arg, string subsample_name_arg, OptionsList options_list_arg, + const SymbolTable& symbol_table_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class CorrOptionsStatement : public BasicOptionsStatement { private: const string name1; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: - CorrOptionsStatement(string name_arg1, string name_arg2, - string subsample_name_arg, - OptionsList options_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; - void writeJsonOutput(ostream &output) const override; + CorrOptionsStatement(string name_arg1, string name_arg2, string subsample_name_arg, + OptionsList options_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; + void writeJsonOutput(ostream& output) const override; }; class OptionsEqualStatement : public Statement @@ -1168,49 +1230,47 @@ class OptionsEqualStatement : public Statement private: const string to_declaration_type, to_name1, to_name2, to_subsample_name; const string from_declaration_type, from_name1, from_name2, from_subsample_name; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: - OptionsEqualStatement(string to_declaration_type_arg, - string to_name1_arg, - string to_name2_arg, - string to_subsample_name_arg, - string from_declaration_type_arg, - string from_name1_arg, - string from_name2_arg, - string from_subsample_name_arg, - const SymbolTable &symbol_table_arg); - void get_base_name(const SymbolType symb_type, string &lhs_field) const; - 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; + OptionsEqualStatement(string to_declaration_type_arg, string to_name1_arg, string to_name2_arg, + string to_subsample_name_arg, string from_declaration_type_arg, + string from_name1_arg, string from_name2_arg, + string from_subsample_name_arg, const SymbolTable& symbol_table_arg); + void get_base_name(const SymbolType symb_type, string& lhs_field) const; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class ModelDiagnosticsStatement : public Statement { public: - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class Smoother2histvalStatement : public Statement { private: const OptionsList options_list; + public: explicit Smoother2histvalStatement(OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class MethodOfMomentsStatement : public Statement { -private: +private: const OptionsList options_list; + public: explicit MethodOfMomentsStatement(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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class GenerateIRFsStatement : public Statement @@ -1220,50 +1280,55 @@ private: const OptionsList options_list; const vector generate_irf_names; const vector> generate_irf_elements; + public: - GenerateIRFsStatement(OptionsList options_list_arg, - vector generate_irf_names_arg, + GenerateIRFsStatement(OptionsList options_list_arg, vector generate_irf_names_arg, vector> generate_irf_elements_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class MatchedMomentsStatement : public Statement { private: - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: /* Each moment is represented by a three vectors: symb_ids, lags, powers. See the definition of ExprNode::matchMatchedMoment() for more details */ const vector, vector, vector>> moments; - MatchedMomentsStatement(const SymbolTable &symbol_table_arg, + MatchedMomentsStatement(const SymbolTable& symbol_table_arg, vector, vector, vector>> moments_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class OccbinConstraintsStatement : public Statement { private: DataTree data_tree; + public: - // The tuple is (name, bind, relax, error_bind, error_relax) (where relax and error_{bind,relax} can be nullptr) - const vector> constraints; - OccbinConstraintsStatement(const DataTree &data_tree_arg, - vector> constraints_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; + // The tuple is (name, bind, relax, error_bind, error_relax) (where relax and error_{bind,relax} + // can be nullptr) + const vector> constraints; + OccbinConstraintsStatement( + const DataTree& data_tree_arg, + vector> constraints_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; }; class ResidStatement : public Statement { private: const OptionsList options_list; + public: explicit ResidStatement(OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; #endif diff --git a/src/ConfigFile.cc b/src/ConfigFile.cc index 2b40cce7..5b938d6d 100644 --- a/src/ConfigFile.cc +++ b/src/ConfigFile.cc @@ -17,8 +17,8 @@ * along with Dynare. If not, see . */ -#include #include +#include #include #include @@ -26,8 +26,8 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" -#include #include +#include #include #pragma GCC diagnostic pop @@ -53,24 +53,26 @@ Path::Path(vector 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, +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}, - maxCpuNbr{maxCpuNbr_arg}, - userName{move(userName_arg)}, - password{move(password_arg)}, - remoteDrive{move(remoteDrive_arg)}, - remoteDirectory{move(remoteDirectory_arg)}, - programPath{move(programPath_arg)}, - programConfig{move(programConfig_arg)}, - matlabOctavePath{move(matlabOctavePath_arg)}, - singleCompThread{singleCompThread_arg}, - numberOfThreadsPerJob{numberOfThreadsPerJob_arg}, - operatingSystem{move(operatingSystem_arg)} + computerName {move(computerName_arg)}, + port {move(port_arg)}, + minCpuNbr {minCpuNbr_arg}, + maxCpuNbr {maxCpuNbr_arg}, + userName {move(userName_arg)}, + password {move(password_arg)}, + remoteDrive {move(remoteDrive_arg)}, + remoteDirectory {move(remoteDirectory_arg)}, + programPath {move(programPath_arg)}, + programConfig {move(programConfig_arg)}, + matlabOctavePath {move(matlabOctavePath_arg)}, + singleCompThread {singleCompThread_arg}, + numberOfThreadsPerJob {numberOfThreadsPerJob_arg}, + operatingSystem {move(operatingSystem_arg)} { if (computerName.empty()) { @@ -81,13 +83,13 @@ FollowerNode::FollowerNode(string computerName_arg, string port_arg, int minCpuN if (!operatingSystem.empty()) if (operatingSystem != "windows" && operatingSystem != "unix") { - cerr << "ERROR: The OperatingSystem must be either 'unix' or 'windows' (Case Sensitive)." << endl; + cerr << "ERROR: The OperatingSystem must be either 'unix' or 'windows' (Case Sensitive)." + << endl; exit(EXIT_FAILURE); } } -Cluster::Cluster(member_nodes_t member_nodes_arg) : - member_nodes{move(member_nodes_arg)} +Cluster::Cluster(member_nodes_t member_nodes_arg) : member_nodes {move(member_nodes_arg)} { if (member_nodes.empty()) { @@ -99,15 +101,16 @@ Cluster::Cluster(member_nodes_t member_nodes_arg) : ConfigFile::ConfigFile(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}, - parallel_use_psexec{parallel_use_psexec_arg}, - cluster_name{move(cluster_name_arg)} + parallel {parallel_arg}, + parallel_test {parallel_test_arg}, + parallel_follower_open_mode {parallel_follower_open_mode_arg}, + parallel_use_psexec {parallel_use_psexec_arg}, + cluster_name {move(cluster_name_arg)} { } void -ConfigFile::getConfigFileInfo(const filesystem::path &config_file) +ConfigFile::getConfigFileInfo(const filesystem::path& config_file) { using namespace boost; ifstream configFile; @@ -117,9 +120,8 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file) 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"; + if (auto appdata = getenv("APPDATA"); appdata) + defaultConfigFile = filesystem::path {appdata} / "dynare.ini"; else { if (parallel || parallel_test) @@ -132,9 +134,8 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file) exit(EXIT_FAILURE); } #else - if (auto home = getenv("HOME"); - home) - defaultConfigFile = filesystem::path{home} / ".dynare"; + if (auto home = getenv("HOME"); home) + defaultConfigFile = filesystem::path {home} / ".dynare"; else { if (parallel || parallel_test) @@ -151,7 +152,8 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file) { if (parallel || parallel_test) { - cerr << "ERROR: Could not open the default config file (" << defaultConfigFile.string() << ")" << endl; + cerr << "ERROR: Could not open the default config file (" + << defaultConfigFile.string() << ")" << endl; exit(EXIT_FAILURE); } else @@ -163,21 +165,21 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file) configFile.open(config_file, fstream::in); if (!configFile.is_open()) { - cerr << "ERROR: Couldn't open file " << config_file.string() << endl;; + cerr << "ERROR: Couldn't open file " << config_file.string() << endl; + ; exit(EXIT_FAILURE); } } - string name, computerName, port, userName, password, remoteDrive, - remoteDirectory, programPath, programConfig, matlabOctavePath, - operatingSystem, global_init_file; + string name, computerName, port, userName, password, remoteDrive, remoteDirectory, programPath, + programConfig, matlabOctavePath, operatingSystem, global_init_file; vector includepath; - int minCpuNbr{0}, maxCpuNbr{0}; - int numberOfThreadsPerJob{1}; - bool singleCompThread{false}; + int minCpuNbr {0}, maxCpuNbr {0}; + int numberOfThreadsPerJob {1}; + bool singleCompThread {false}; member_nodes_t member_nodes; - bool inHooks{false}, inNode{false}, inCluster{false}, inPaths{false}; + bool inHooks {false}, inNode {false}, inCluster {false}, inPaths {false}; while (configFile.good()) { @@ -187,10 +189,7 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file) if (line.empty() || !line.compare(0, 1, "#")) continue; - if (line == "[node]" - || line == "[cluster]" - || line == "[hooks]" - || line == "[paths]") + if (line == "[node]" || line == "[cluster]" || line == "[hooks]" || line == "[paths]") { if (!global_init_file.empty()) // we were just in [hooks] @@ -200,11 +199,10 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file) addPathsConfFileElement(includepath); else // we were just in [node] or [cluster] - addParallelConfFileElement(inNode, inCluster, member_nodes, name, - computerName, port, minCpuNbr, maxCpuNbr, userName, - password, remoteDrive, remoteDirectory, - programPath, programConfig, matlabOctavePath, singleCompThread, - numberOfThreadsPerJob, operatingSystem); + addParallelConfFileElement( + inNode, inCluster, member_nodes, name, computerName, port, minCpuNbr, maxCpuNbr, + userName, password, remoteDrive, remoteDirectory, programPath, programConfig, + matlabOctavePath, singleCompThread, numberOfThreadsPerJob, operatingSystem); //! Reset communication vars / option defaults if (line == "[hooks]") @@ -236,9 +234,9 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file) inPaths = false; } - name = userName = computerName = port = password = remoteDrive - = remoteDirectory = programPath = programConfig = matlabOctavePath - = operatingSystem = global_init_file = ""; + name = userName = computerName = port = password = remoteDrive = remoteDirectory + = programPath = programConfig = matlabOctavePath = operatingSystem = global_init_file + = ""; includepath.clear(); minCpuNbr = maxCpuNbr = 0; numberOfThreadsPerJob = 1; @@ -251,7 +249,8 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file) split(tokenizedLine, line, is_any_of("=")); if (tokenizedLine.size() != 2) { - cerr << "ERROR (in config file): Options should be formatted as 'option = value'." << endl; + cerr << "ERROR (in config file): Options should be formatted as 'option = value'." + << endl; exit(EXIT_FAILURE); } trim(tokenizedLine.front()); @@ -263,12 +262,15 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file) global_init_file = tokenizedLine.back(); else { - cerr << "ERROR: May not have more than one GlobalInitFile option in [hooks] block." << endl; + cerr + << "ERROR: May not have more than one GlobalInitFile option in [hooks] block." + << endl; exit(EXIT_FAILURE); } else { - cerr << "ERROR: Unrecognized option " << tokenizedLine.front() << " in [hooks] block." << endl; + cerr << "ERROR: Unrecognized option " << tokenizedLine.front() + << " in [hooks] block." << endl; exit(EXIT_FAILURE); } else if (inPaths) @@ -277,7 +279,7 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file) { vector tokenizedPath; split(tokenizedPath, tokenizedLine.back(), is_any_of(":"), token_compress_on); - for (auto &it : tokenizedPath) + for (auto& it : tokenizedPath) if (!it.empty()) { trim(it); @@ -286,162 +288,171 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file) } else { - cerr << "ERROR: May not have more than one Include option in [paths] block." << endl; + cerr << "ERROR: May not have more than one Include option in [paths] block." + << endl; exit(EXIT_FAILURE); } else { - cerr << "ERROR: Unrecognized option " << tokenizedLine.front() << " in [paths] block." << endl; + cerr << "ERROR: Unrecognized option " << tokenizedLine.front() + << " in [paths] block." << endl; exit(EXIT_FAILURE); } - else - if (tokenizedLine.front() == "Name") - name = tokenizedLine.back(); - else if (tokenizedLine.front() == "CPUnbr") - { - vector tokenizedCpuNbr; - split(tokenizedCpuNbr, tokenizedLine.back(), is_any_of(":")); - try - { - if (tokenizedCpuNbr.size() == 1) - { - minCpuNbr = 1; - maxCpuNbr = stoi(tokenizedCpuNbr.front()); - } - else if (tokenizedCpuNbr.size() == 2 - && tokenizedCpuNbr[0].at(0) == '[' - && tokenizedCpuNbr[1].at(tokenizedCpuNbr[1].size()-1) == ']') - { - tokenizedCpuNbr[0].erase(0, 1); - tokenizedCpuNbr[1].erase(tokenizedCpuNbr[1].size()-1, 1); - minCpuNbr = stoi(tokenizedCpuNbr[0]); - maxCpuNbr = stoi(tokenizedCpuNbr[1]); - } - } - catch (const invalid_argument &) - { - cerr << "ERROR: Could not convert value to integer for CPUnbr." << endl; - exit(EXIT_FAILURE); - } - - if (minCpuNbr <= 0 || maxCpuNbr <= 0) - { - cerr << "ERROR: Syntax for the CPUnbr option is as follows:" << endl - << " 1) CPUnbr = " << endl - << " or 2) CPUnbr = [:]" << endl - << " where is an Integer > 0." << endl; - exit(EXIT_FAILURE); - } - - minCpuNbr--; - maxCpuNbr--; - if (minCpuNbr > maxCpuNbr) - { - int tmp = maxCpuNbr; - maxCpuNbr = minCpuNbr; - minCpuNbr = tmp; - } - } - else if (tokenizedLine.front() == "Port") - port = tokenizedLine.back(); - else if (tokenizedLine.front() == "ComputerName") - computerName = tokenizedLine.back(); - else if (tokenizedLine.front() == "UserName") - userName = tokenizedLine.back(); - else if (tokenizedLine.front() == "Password") - password = tokenizedLine.back(); - else if (tokenizedLine.front() == "RemoteDrive") - remoteDrive = tokenizedLine.back(); - else if (tokenizedLine.front() == "RemoteDirectory") - remoteDirectory = tokenizedLine.back(); - else if (tokenizedLine.front() == "DynarePath" - || tokenizedLine.front() == "ProgramPath") - programPath = tokenizedLine.back(); - else if (tokenizedLine.front() == "ProgramConfig") - programConfig = tokenizedLine.back(); - else if (tokenizedLine.front() == "MatlabOctavePath") - matlabOctavePath = tokenizedLine.back(); - else if (tokenizedLine.front() == "NumberOfThreadsPerJob") - numberOfThreadsPerJob = stoi(tokenizedLine.back()); - else if (tokenizedLine.front() == "SingleCompThread") - if (tokenizedLine.back() == "true") - singleCompThread = true; - else if (tokenizedLine.back() == "false") - singleCompThread = false; - else + else if (tokenizedLine.front() == "Name") + name = tokenizedLine.back(); + else if (tokenizedLine.front() == "CPUnbr") + { + vector tokenizedCpuNbr; + split(tokenizedCpuNbr, tokenizedLine.back(), is_any_of(":")); + try { - cerr << "ERROR (in config file): The value passed to SingleCompThread may only be 'true' or 'false'." << endl; + if (tokenizedCpuNbr.size() == 1) + { + minCpuNbr = 1; + maxCpuNbr = stoi(tokenizedCpuNbr.front()); + } + else if (tokenizedCpuNbr.size() == 2 && tokenizedCpuNbr[0].at(0) == '[' + && tokenizedCpuNbr[1].at(tokenizedCpuNbr[1].size() - 1) == ']') + { + tokenizedCpuNbr[0].erase(0, 1); + tokenizedCpuNbr[1].erase(tokenizedCpuNbr[1].size() - 1, 1); + minCpuNbr = stoi(tokenizedCpuNbr[0]); + maxCpuNbr = stoi(tokenizedCpuNbr[1]); + } + } + catch (const invalid_argument&) + { + cerr << "ERROR: Could not convert value to integer for CPUnbr." << endl; exit(EXIT_FAILURE); } - else if (tokenizedLine.front() == "OperatingSystem") - operatingSystem = tokenizedLine.back(); - else if (tokenizedLine.front() == "Members") - { - char_separator sep(" ,;", "()", drop_empty_tokens); - tokenizer tokens(tokenizedLine.back(), sep); - string node_name; - for (bool begin_weight{false}; - const auto &token : tokens) - { - if (token == "(") - { - begin_weight = true; - continue; - } - else if (token == ")") - { - node_name.clear(); - begin_weight = false; - continue; - } - if (!begin_weight) - { - if (!node_name.empty()) - { - if (member_nodes.contains(node_name)) - { - cerr << "ERROR (in config file): Node entered twice in specification of cluster." << endl; - exit(EXIT_FAILURE); - } - else - member_nodes[node_name] = 1.0; - } - node_name = token; - } - else - try + if (minCpuNbr <= 0 || maxCpuNbr <= 0) + { + cerr << "ERROR: Syntax for the CPUnbr option is as follows:" << endl + << " 1) CPUnbr = " << endl + << " or 2) CPUnbr = [:]" << endl + << " where is an Integer > 0." << endl; + exit(EXIT_FAILURE); + } + + minCpuNbr--; + maxCpuNbr--; + if (minCpuNbr > maxCpuNbr) + { + int tmp = maxCpuNbr; + maxCpuNbr = minCpuNbr; + minCpuNbr = tmp; + } + } + else if (tokenizedLine.front() == "Port") + port = tokenizedLine.back(); + else if (tokenizedLine.front() == "ComputerName") + computerName = tokenizedLine.back(); + else if (tokenizedLine.front() == "UserName") + userName = tokenizedLine.back(); + else if (tokenizedLine.front() == "Password") + password = tokenizedLine.back(); + else if (tokenizedLine.front() == "RemoteDrive") + remoteDrive = tokenizedLine.back(); + else if (tokenizedLine.front() == "RemoteDirectory") + remoteDirectory = tokenizedLine.back(); + else if (tokenizedLine.front() == "DynarePath" || tokenizedLine.front() == "ProgramPath") + programPath = tokenizedLine.back(); + else if (tokenizedLine.front() == "ProgramConfig") + programConfig = tokenizedLine.back(); + else if (tokenizedLine.front() == "MatlabOctavePath") + matlabOctavePath = tokenizedLine.back(); + else if (tokenizedLine.front() == "NumberOfThreadsPerJob") + numberOfThreadsPerJob = stoi(tokenizedLine.back()); + else if (tokenizedLine.front() == "SingleCompThread") + if (tokenizedLine.back() == "true") + singleCompThread = true; + else if (tokenizedLine.back() == "false") + singleCompThread = false; + else + { + cerr << "ERROR (in config file): The value passed to SingleCompThread may only be " + "'true' or 'false'." + << endl; + exit(EXIT_FAILURE); + } + else if (tokenizedLine.front() == "OperatingSystem") + operatingSystem = tokenizedLine.back(); + else if (tokenizedLine.front() == "Members") + { + char_separator sep(" ,;", "()", drop_empty_tokens); + tokenizer tokens(tokenizedLine.back(), sep); + string node_name; + for (bool begin_weight {false}; const auto& token : tokens) + { + if (token == "(") + { + begin_weight = true; + continue; + } + else if (token == ")") + { + node_name.clear(); + begin_weight = false; + continue; + } + + if (!begin_weight) + { + if (!node_name.empty()) { - auto weight = stod(token); - if (weight <= 0) + if (member_nodes.contains(node_name)) { - cerr << "ERROR (in config file): Misspecification of weights passed to Members option." << endl; + cerr << "ERROR (in config file): Node entered twice in specification " + "of cluster." + << endl; exit(EXIT_FAILURE); } - member_nodes[node_name] = weight; + else + member_nodes[node_name] = 1.0; } - catch (const invalid_argument &) - { - cerr << "ERROR (in config file): Misspecification of weights passed to Members option." << endl; - exit(EXIT_FAILURE); - } - } - if (!node_name.empty()) - { - if (!member_nodes.contains(node_name)) - member_nodes[node_name] = 1.0; - else + node_name = token; + } + else + try { - cerr << "ERROR (in config file): Node entered twice in specification of cluster." << endl; + auto weight = stod(token); + if (weight <= 0) + { + cerr << "ERROR (in config file): Misspecification of weights passed to " + "Members option." + << endl; + exit(EXIT_FAILURE); + } + member_nodes[node_name] = weight; + } + catch (const invalid_argument&) + { + cerr << "ERROR (in config file): Misspecification of weights passed to " + "Members option." + << endl; exit(EXIT_FAILURE); } - } - } - else - { - cerr << "ERROR (in config file): Option " << tokenizedLine.front() << " is invalid." << endl; - exit(EXIT_FAILURE); - } + } + if (!node_name.empty()) + { + if (!member_nodes.contains(node_name)) + member_nodes[node_name] = 1.0; + else + { + cerr << "ERROR (in config file): Node entered twice in specification of " + "cluster." + << endl; + exit(EXIT_FAILURE); + } + } + } + else + { + cerr << "ERROR (in config file): Option " << tokenizedLine.front() << " is invalid." + << endl; + exit(EXIT_FAILURE); + } } } @@ -450,9 +461,8 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file) else if (!includepath.empty()) addPathsConfFileElement(includepath); else - addParallelConfFileElement(inNode, inCluster, member_nodes, name, - computerName, port, minCpuNbr, maxCpuNbr, userName, - password, remoteDrive, remoteDirectory, + addParallelConfFileElement(inNode, inCluster, member_nodes, name, computerName, port, minCpuNbr, + maxCpuNbr, userName, password, remoteDrive, remoteDirectory, programPath, programConfig, matlabOctavePath, singleCompThread, numberOfThreadsPerJob, operatingSystem); @@ -464,7 +474,8 @@ 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; + cerr << "ERROR: The global initialization file must be passed to the GlobalInitFile option." + << endl; exit(EXIT_FAILURE); } else @@ -484,12 +495,15 @@ ConfigFile::addPathsConfFileElement(vector 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) +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) { //! ADD NODE if (inNode) @@ -498,24 +512,22 @@ ConfigFile::addParallelConfFileElement(bool inNode, bool inCluster, const member cerr << "Invalid option passed to [node]." << endl; exit(EXIT_FAILURE); } + else if (name.empty() || follower_nodes.contains(name)) + { + cerr << "ERROR: Every node must be assigned a unique name." << endl; + exit(EXIT_FAILURE); + } else - if (name.empty() || follower_nodes.contains(name)) - { - cerr << "ERROR: Every node must be assigned a unique name." << endl; - exit(EXIT_FAILURE); - } - else - follower_nodes.try_emplace(name, computerName, port, minCpuNbr, maxCpuNbr, userName, - password, remoteDrive, remoteDirectory, programPath, programConfig, - matlabOctavePath, singleCompThread, numberOfThreadsPerJob, - operatingSystem); + follower_nodes.try_emplace(name, computerName, port, minCpuNbr, maxCpuNbr, userName, password, + remoteDrive, remoteDirectory, programPath, programConfig, + matlabOctavePath, singleCompThread, numberOfThreadsPerJob, + operatingSystem); //! ADD CLUSTER else if (inCluster) { - if (minCpuNbr > 0 || maxCpuNbr > 0 || !userName.empty() - || !password.empty() || !remoteDrive.empty() || !remoteDirectory.empty() - || !programPath.empty() || !programConfig.empty() - || !matlabOctavePath.empty() || !operatingSystem.empty()) + if (minCpuNbr > 0 || maxCpuNbr > 0 || !userName.empty() || !password.empty() + || !remoteDrive.empty() || !remoteDirectory.empty() || !programPath.empty() + || !programConfig.empty() || !matlabOctavePath.empty() || !operatingSystem.empty()) { cerr << "Invalid option passed to [cluster]." << endl; exit(EXIT_FAILURE); @@ -535,11 +547,10 @@ ConfigFile::addParallelConfFileElement(bool inNode, bool inCluster, const member } void -ConfigFile::checkPass([[maybe_unused]] WarningConsolidation &warnings) const +ConfigFile::checkPass([[maybe_unused]] WarningConsolidation& warnings) const { - for (bool global_init_file_declared{false}; - const auto &hook : hooks) - for (const auto &mapit : hook.get_hooks()) + 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)) { @@ -557,10 +568,10 @@ ConfigFile::checkPass([[maybe_unused]] WarningConsolidation &warnings) const exit(EXIT_FAILURE); } - for (const auto &follower_node : follower_nodes) + for (const auto& follower_node : follower_nodes) { #if !defined(_WIN32) && !defined(__CYGWIN32__) - //For Linux/Mac, check that cpuNbr starts at 0 + // For Linux/Mac, check that cpuNbr starts at 0 if (follower_node.second.minCpuNbr != 0) warnings << "WARNING: On Unix-based operating systems, you cannot specify the CPU that is " << "used in parallel processing. This will be adjusted for you such that the " @@ -571,21 +582,24 @@ ConfigFile::checkPass([[maybe_unused]] WarningConsolidation &warnings) const { stoi(follower_node.second.port); } - catch (const invalid_argument &) + catch (const invalid_argument&) { - cerr << "ERROR (node " << follower_node.first << "): the port must be an integer." << endl; + cerr << "ERROR (node " << follower_node.first << "): the port must be an integer." + << endl; exit(EXIT_FAILURE); } if (follower_node.second.computerName == "localhost") // We are working locally { if (!follower_node.second.remoteDrive.empty()) { - cerr << "ERROR (node " << follower_node.first << "): the RemoteDrive option may not be passed for a local node." << endl; + cerr << "ERROR (node " << follower_node.first + << "): the RemoteDrive option may not be passed for a local node." << endl; exit(EXIT_FAILURE); } if (!follower_node.second.remoteDirectory.empty()) { - cerr << "ERROR (node " << follower_node.first << "): the RemoteDirectory option may not be passed for a local node." << endl; + cerr << "ERROR (node " << follower_node.first + << "): the RemoteDirectory option may not be passed for a local node." << endl; exit(EXIT_FAILURE); } } @@ -593,19 +607,26 @@ ConfigFile::checkPass([[maybe_unused]] WarningConsolidation &warnings) const { if (follower_node.second.userName.empty()) { - cerr << "ERROR (node " << follower_node.first << "): the UserName option must be passed for every remote node." << endl; + cerr << "ERROR (node " << follower_node.first + << "): the UserName option must be passed for every remote node." << endl; exit(EXIT_FAILURE); } if (follower_node.second.operatingSystem == "windows") { if (follower_node.second.password.empty()) { - cerr << "ERROR (node " << follower_node.first << "): the Password option must be passed under Windows for every remote node." << endl; + cerr << "ERROR (node " << follower_node.first + << "): the Password option must be passed under Windows for every remote " + "node." + << endl; exit(EXIT_FAILURE); } if (follower_node.second.remoteDrive.empty()) { - cerr << "ERROR (node " << follower_node.first << "): the RemoteDrive option must be passed under Windows for every remote node." << endl; + cerr << "ERROR (node " << follower_node.first + << "): the RemoteDrive option must be passed under Windows for every remote " + "node." + << endl; exit(EXIT_FAILURE); } } @@ -614,19 +635,26 @@ ConfigFile::checkPass([[maybe_unused]] WarningConsolidation &warnings) const { if (follower_node.second.password.empty()) { - cerr << "ERROR (node " << follower_node.first << "): the Password option must be passed under Windows for every remote node." << endl; + cerr << "ERROR (node " << follower_node.first + << "): the Password option must be passed under Windows for every remote " + "node." + << endl; exit(EXIT_FAILURE); } if (follower_node.second.remoteDrive.empty()) { - cerr << "ERROR (node " << follower_node.first << "): the RemoteDrive option must be passed under Windows for every remote node." << endl; + cerr << "ERROR (node " << follower_node.first + << "): the RemoteDrive option must be passed under Windows for every remote " + "node." + << endl; exit(EXIT_FAILURE); } } #endif if (follower_node.second.remoteDirectory.empty()) { - cerr << "ERROR (node " << follower_node.first << "): the RemoteDirectory must be specified for every remote node." << endl; + cerr << "ERROR (node " << follower_node.first + << "): the RemoteDirectory must be specified for every remote node." << endl; exit(EXIT_FAILURE); } } @@ -641,15 +669,17 @@ ConfigFile::checkPass([[maybe_unused]] WarningConsolidation &warnings) const if (!cluster_name.empty() && !clusters.contains(cluster_name)) { - cerr << "ERROR: Cluster Name " << cluster_name << " was not found in the config file." << endl; + cerr << "ERROR: Cluster Name " << cluster_name << " was not found in the config file." + << endl; exit(EXIT_FAILURE); } - for (const auto &cluster : clusters) - for (const auto &itmn : cluster.second.member_nodes) + for (const auto& cluster : clusters) + for (const auto& itmn : cluster.second.member_nodes) if (!follower_nodes.contains(itmn.first)) { - cerr << "Error: node " << itmn.first << " specified in cluster " << cluster.first << " was not found" << endl; + cerr << "Error: node " << itmn.first << " specified in cluster " << cluster.first + << " was not found" << endl; exit(EXIT_FAILURE); } } @@ -661,8 +691,8 @@ ConfigFile::transformPass() return; #if !defined(_WIN32) && !defined(__CYGWIN32__) - //For Linux/Mac, check that cpuNbr starts at 0 - for (auto &it : follower_nodes) + // For Linux/Mac, check that cpuNbr starts at 0 + for (auto& it : follower_nodes) if (it.second.minCpuNbr != 0) { it.second.maxCpuNbr = it.second.maxCpuNbr - it.second.minCpuNbr; @@ -670,13 +700,14 @@ ConfigFile::transformPass() } #endif - auto cluster_it = cluster_name.empty() ? clusters.find(firstClusterName) : clusters.find(cluster_name); + auto cluster_it + = cluster_name.empty() ? clusters.find(firstClusterName) : clusters.find(cluster_name); - double weight_denominator{0.0}; - for (const auto &it : cluster_it->second.member_nodes) + double weight_denominator {0.0}; + for (const auto& it : cluster_it->second.member_nodes) weight_denominator += it.second; - for (auto &member_node : cluster_it->second.member_nodes) + for (auto& member_node : cluster_it->second.member_nodes) member_node.second /= weight_denominator; } @@ -685,33 +716,33 @@ ConfigFile::getIncludePaths() const { vector include_paths; for (auto path : paths) - for (const auto &mapit : path.get_paths()) - for (const auto &vecit : mapit.second) + for (const auto& mapit : path.get_paths()) + for (const auto& vecit : mapit.second) include_paths.emplace_back(vecit); return include_paths; } void -ConfigFile::writeHooks(ostream &output) const +ConfigFile::writeHooks(ostream& output) const { for (auto hook : hooks) - for (const auto &mapit : hook.get_hooks()) + for (const auto& mapit : hook.get_hooks()) output << "options_." << mapit.first << " = '" << mapit.second << "';" << endl; } void -ConfigFile::writeCluster(ostream &output) const +ConfigFile::writeCluster(ostream& output) const { if (!parallel && !parallel_test) return; - auto cluster_it = cluster_name.empty() ? clusters.find(firstClusterName) : clusters.find(cluster_name); + auto cluster_it + = cluster_name.empty() ? clusters.find(firstClusterName) : clusters.find(cluster_name); - for (int i{1}; - const auto &follower_node : follower_nodes) + for (int i {1}; const auto& follower_node : follower_nodes) { bool follower_node_in_member_nodes = false; - for (const auto &itmn : cluster_it->second.member_nodes) + for (const auto& itmn : cluster_it->second.member_nodes) if (follower_node.first == itmn.first) follower_node_in_member_nodes = true; @@ -730,17 +761,20 @@ ConfigFile::writeCluster(ostream &output) const output << "'ComputerName', '" << follower_node.second.computerName << "', " << "'Port', '" << follower_node.second.port << "', " - << "'CPUnbr', [" << follower_node.second.minCpuNbr << ":" << follower_node.second.maxCpuNbr << "], " + << "'CPUnbr', [" << follower_node.second.minCpuNbr << ":" + << follower_node.second.maxCpuNbr << "], " << "'UserName', '" << follower_node.second.userName << "', " << "'Password', '" << follower_node.second.password << "', " << "'RemoteDrive', '" << follower_node.second.remoteDrive << "', " - << "'RemoteDirectory', '" << follower_node.second.remoteDirectory << "', " - // The following should be switched back to “ProgramPath” once we move to Dragonfly + << "'RemoteDirectory', '" << follower_node.second.remoteDirectory + << "', " + // The following should be switched back to “ProgramPath” once we move to Dragonfly << "'DynarePath', '" << follower_node.second.programPath << "', " << "'ProgramConfig', '" << follower_node.second.programConfig << "', " << "'MatlabOctavePath', '" << follower_node.second.matlabOctavePath << "', " << "'OperatingSystem', '" << follower_node.second.operatingSystem << "', " - << "'NodeWeight', '" << cluster_it->second.member_nodes.at(follower_node.first) << "', " + << "'NodeWeight', '" << cluster_it->second.member_nodes.at(follower_node.first) + << "', " << "'NumberOfThreadsPerJob', " << follower_node.second.numberOfThreadsPerJob << ", "; if (follower_node.second.singleCompThread) @@ -749,7 +783,8 @@ ConfigFile::writeCluster(ostream &output) const output << "'SingleCompThread', 'false');" << endl; } - // Default values for the following two are both in DynareMain.cc and matlab/default_option_values.m + // Default values for the following two are both in DynareMain.cc and + // matlab/default_option_values.m if (parallel_follower_open_mode) output << "options_.parallel_info.leaveSlaveOpen = 1;" << endl; if (!parallel_use_psexec) @@ -759,14 +794,18 @@ ConfigFile::writeCluster(ostream &output) const output << "InitializeComputationalEnvironment();" << endl; if (parallel_test) - output << "ErrorCode = AnalyseComputationalEnvironment(options_.parallel, options_.parallel_info);" << endl - << "disp(['AnalyseComputationalEnvironment returned with Error Code: ' num2str(ErrorCode)]);" << endl - << "diary off;" << endl - << "return;" << endl; + output + << "ErrorCode = AnalyseComputationalEnvironment(options_.parallel, options_.parallel_info);" + << endl + << "disp(['AnalyseComputationalEnvironment returned with Error Code: ' " + "num2str(ErrorCode)]);" + << endl + << "diary off;" << endl + << "return;" << endl; } void -ConfigFile::writeEndParallel(ostream &output) const +ConfigFile::writeEndParallel(ostream& output) const { if ((!parallel && !parallel_test) || !parallel_follower_open_mode) return; diff --git a/src/ConfigFile.hh b/src/ConfigFile.hh index 75eae753..fe583893 100644 --- a/src/ConfigFile.hh +++ b/src/ConfigFile.hh @@ -20,9 +20,9 @@ #ifndef _CONFIG_FILE_HH #define _CONFIG_FILE_HH +#include #include #include -#include #include "WarningConsolidation.hh" @@ -34,8 +34,10 @@ class Hook { public: explicit Hook(string global_init_file_arg); + private: map hooks; + public: map get_hooks() const @@ -48,8 +50,10 @@ class Path { public: explicit Path(vector includepath_arg); + private: map> paths; + public: map> get_paths() const @@ -61,10 +65,12 @@ public: class FollowerNode { friend class ConfigFile; + 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, + 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: @@ -81,6 +87,7 @@ protected: class Cluster { friend class ConfigFile; + public: explicit Cluster(member_nodes_t member_nodes_arg); @@ -112,27 +119,30 @@ private: //! Add Paths void addPathsConfFileElement(vector includepath); //! Add a FollowerNode or a Cluster object - void 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); + void 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); + public: //! Parse config file - void getConfigFileInfo(const filesystem::path ¶llel_config_file); + void getConfigFileInfo(const filesystem::path& parallel_config_file); //! Check Pass - void checkPass(WarningConsolidation &warnings) const; + void checkPass(WarningConsolidation& warnings) const; //! Check Pass void transformPass(); //! Get Path Info vector getIncludePaths() const; //! Write any hooks - void writeHooks(ostream &output) const; + void writeHooks(ostream& output) const; //! Create options_.parallel structure, write options - void writeCluster(ostream &output) const; + void writeCluster(ostream& output) const; //! Close follower nodes if needed - void writeEndParallel(ostream &output) const; + void writeEndParallel(ostream& output) const; }; #endif // ! CONFIG_FILE_HH diff --git a/src/DataTree.cc b/src/DataTree.cc index 72f872fe..5b3c2df0 100644 --- a/src/DataTree.cc +++ b/src/DataTree.cc @@ -17,13 +17,13 @@ * along with Dynare. If not, see . */ -#include -#include -#include #include -#include +#include +#include #include #include +#include +#include #include "DataTree.hh" @@ -46,39 +46,37 @@ DataTree::initConstants() Pi = AddNonNegativeConstant("3.141592653589793"); } -DataTree::DataTree(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg, - bool is_dynamic_arg) : - symbol_table{symbol_table_arg}, - num_constants{num_constants_arg}, - external_functions_table{external_functions_table_arg}, - is_dynamic{is_dynamic_arg} +DataTree::DataTree(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg, bool is_dynamic_arg) : + symbol_table {symbol_table_arg}, + num_constants {num_constants_arg}, + external_functions_table {external_functions_table_arg}, + is_dynamic {is_dynamic_arg} { initConstants(); } -DataTree::DataTree(const DataTree &d) : - symbol_table{d.symbol_table}, - num_constants{d.num_constants}, - external_functions_table{d.external_functions_table}, - is_dynamic{d.is_dynamic}, - local_variables_vector{d.local_variables_vector} +DataTree::DataTree(const DataTree& d) : + symbol_table {d.symbol_table}, + num_constants {d.num_constants}, + external_functions_table {d.external_functions_table}, + is_dynamic {d.is_dynamic}, + local_variables_vector {d.local_variables_vector} { // Constants must be initialized first because they are used in some Add* methods initConstants(); - for (const auto &it : d.node_list) + for (const auto& it : d.node_list) it->clone(*this); assert(node_list.size() == d.node_list.size()); - for (const auto &[symb_id, value] : d.local_variables_table) + for (const auto& [symb_id, value] : d.local_variables_table) local_variables_table[symb_id] = value->clone(*this); } -DataTree & -DataTree::operator=(const DataTree &d) +DataTree& +DataTree::operator=(const DataTree& d) { assert(&symbol_table == &d.symbol_table); assert(&num_constants == &d.num_constants); @@ -110,7 +108,7 @@ DataTree::operator=(const DataTree &d) for (int symb_id : d.local_variables_vector) local_variables_table[symb_id] = d.local_variables_table.at(symb_id)->clone(*this); - for (const auto &it : d.node_list) + for (const auto& it : d.node_list) it->clone(*this); assert(node_list.size() == d.node_list.size()); @@ -120,13 +118,12 @@ DataTree::operator=(const DataTree &d) return *this; } -NumConstNode * -DataTree::AddNonNegativeConstant(const string &value) +NumConstNode* +DataTree::AddNonNegativeConstant(const string& value) { int id = num_constants.AddNonNegativeConstant(value); - if (auto it = num_const_node_map.find(id); - it != num_const_node_map.end()) + if (auto it = num_const_node_map.find(id); it != num_const_node_map.end()) return it->second; auto sp = make_unique(*this, node_list.size(), id); @@ -136,7 +133,7 @@ DataTree::AddNonNegativeConstant(const string &value) return p; } -VariableNode * +VariableNode* DataTree::AddVariable(int symb_id, int lag) { if (lag != 0 && !is_dynamic) @@ -145,24 +142,24 @@ DataTree::AddVariable(int symb_id, int lag) exit(EXIT_FAILURE); } - if (auto it = variable_node_map.find({ symb_id, lag }); - it != variable_node_map.end()) + if (auto it = variable_node_map.find({symb_id, lag}); it != variable_node_map.end()) return it->second; auto sp = make_unique(*this, node_list.size(), symb_id, lag); auto p = sp.get(); node_list.push_back(move(sp)); - variable_node_map.try_emplace({ symb_id, lag }, p); + variable_node_map.try_emplace({symb_id, lag}, p); return p; } -VariableNode * +VariableNode* DataTree::getVariable(int symb_id, int lag) const { - auto it = variable_node_map.find({ symb_id, lag }); + auto it = variable_node_map.find({symb_id, lag}); if (it == variable_node_map.end()) { - cerr << "DataTree::getVariable: unknown variable node for symb_id=" << symb_id << " and lag=" << lag << endl; + cerr << "DataTree::getVariable: unknown variable node for symb_id=" << symb_id + << " and lag=" << lag << endl; exit(EXIT_FAILURE); } return it->second; @@ -171,7 +168,7 @@ DataTree::getVariable(int symb_id, int lag) const bool DataTree::ParamUsedWithLeadLagInternal() const { - for (const auto &[symb_lag, expr] : variable_node_map) + for (const auto& [symb_lag, expr] : variable_node_map) if (symbol_table.getType(symb_lag.first) == SymbolType::parameter && symb_lag.second != 0) return true; return false; @@ -187,22 +184,22 @@ DataTree::AddPlus(expr_t iArg1, expr_t iArg2) return iArg2; // Simplify x+(-y) in x-y - if (auto uarg2 = dynamic_cast(iArg2); + if (auto uarg2 = dynamic_cast(iArg2); uarg2 && uarg2->op_code == UnaryOpcode::uminus) return AddMinus(iArg1, uarg2->arg); // Simplify (-x)+y in y-x - if (auto uarg1 = dynamic_cast(iArg1); + if (auto uarg1 = dynamic_cast(iArg1); uarg1 && uarg1->op_code == UnaryOpcode::uminus) return AddMinus(iArg2, uarg1->arg); // Simplify (x-y)+y in x - if (auto barg1 = dynamic_cast(iArg1); + if (auto barg1 = dynamic_cast(iArg1); barg1 && barg1->op_code == BinaryOpcode::minus && barg1->arg2 == iArg2) return barg1->arg1; // Simplify y+(x-y) in x - if (auto barg2 = dynamic_cast(iArg2); + if (auto barg2 = dynamic_cast(iArg2); barg2 && barg2->op_code == BinaryOpcode::minus && barg2->arg2 == iArg1) return barg2->arg1; @@ -226,12 +223,12 @@ DataTree::AddMinus(expr_t iArg1, expr_t iArg2) return Zero; // Simplify x-(-y) in x+y - if (auto uarg2 = dynamic_cast(iArg2); + if (auto uarg2 = dynamic_cast(iArg2); uarg2 && uarg2->op_code == UnaryOpcode::uminus) return AddPlus(iArg1, uarg2->arg); // Simplify (x+y)-y and (y+x)-y in x - if (auto barg1 = dynamic_cast(iArg1); + if (auto barg1 = dynamic_cast(iArg1); barg1 && barg1->op_code == BinaryOpcode::plus) { if (barg1->arg2 == iArg2) @@ -250,8 +247,7 @@ DataTree::AddUMinus(expr_t iArg1) return Zero; // Simplify -(-x) in x - if (auto uarg = dynamic_cast(iArg1); - uarg && uarg->op_code == UnaryOpcode::uminus) + if (auto uarg = dynamic_cast(iArg1); uarg && uarg->op_code == UnaryOpcode::uminus) return uarg->arg; return AddUnaryOp(UnaryOpcode::uminus, iArg1); @@ -276,12 +272,12 @@ DataTree::AddTimes(expr_t iArg1, expr_t iArg2) return AddUMinus(iArg1); // Simplify (x/y)*y in x - if (auto barg1 = dynamic_cast(iArg1); + if (auto barg1 = dynamic_cast(iArg1); barg1 && barg1->op_code == BinaryOpcode::divide && barg1->arg2 == iArg2) return barg1->arg1; // Simplify y*(x/y) in x - if (auto barg2 = dynamic_cast(iArg2); + if (auto barg2 = dynamic_cast(iArg2); barg2 && barg2->op_code == BinaryOpcode::divide && barg2->arg2 == iArg1) return barg2->arg1; @@ -312,12 +308,12 @@ DataTree::AddDivide(expr_t iArg1, expr_t iArg2) noexcept(false) return One; // Simplify x/(1/y) in x*y - if (auto barg2 = dynamic_cast(iArg2); + if (auto barg2 = dynamic_cast(iArg2); barg2 && barg2->op_code == BinaryOpcode::divide && barg2->arg1 == One) return AddTimes(iArg1, barg2->arg2); // Simplify (x*y)/y and (y*x)/y in x - if (auto barg1 = dynamic_cast(iArg1); + if (auto barg1 = dynamic_cast(iArg1); barg1 && barg1->op_code == BinaryOpcode::times) { if (barg1->arg2 == iArg2) @@ -401,7 +397,7 @@ DataTree::AddDiff(expr_t iArg1) } expr_t -DataTree::AddAdl(expr_t iArg1, const string &name, const vector &lags) +DataTree::AddAdl(expr_t iArg1, const string& name, const vector& lags) { return AddUnaryOp(UnaryOpcode::adl, iArg1, 0, 0, 0, name, lags); } @@ -428,7 +424,7 @@ DataTree::AddLog(expr_t iArg1) } // Simplify log(1/x) in −log(x) - if (auto barg1 = dynamic_cast(iArg1); + if (auto barg1 = dynamic_cast(iArg1); barg1 && barg1->op_code == BinaryOpcode::divide && barg1->arg1 == One) return AddUMinus(AddLog(barg1->arg2)); @@ -448,7 +444,7 @@ DataTree::AddLog10(expr_t iArg1) } // Simplify log₁₀(1/x) in −log₁₀(x) - if (auto barg1 = dynamic_cast(iArg1); + if (auto barg1 = dynamic_cast(iArg1); barg1 && barg1->op_code == BinaryOpcode::divide && barg1->arg1 == One) return AddUMinus(AddLog10(barg1->arg2)); @@ -668,7 +664,8 @@ DataTree::AddSteadyStateParamDeriv(expr_t iArg1, int param_symb_id) expr_t DataTree::AddSteadyStateParam2ndDeriv(expr_t iArg1, int param1_symb_id, int param2_symb_id) { - return AddUnaryOp(UnaryOpcode::steadyStateParam2ndDeriv, iArg1, 0, param1_symb_id, param2_symb_id); + return AddUnaryOp(UnaryOpcode::steadyStateParam2ndDeriv, iArg1, 0, param1_symb_id, + param2_symb_id); } expr_t @@ -678,10 +675,9 @@ DataTree::AddExpectation(int iArg1, expr_t iArg2) } expr_t -DataTree::AddVarExpectation(const string &model_name) +DataTree::AddVarExpectation(const string& model_name) { - if (auto it = var_expectation_node_map.find(model_name); - it != var_expectation_node_map.end()) + if (auto it = var_expectation_node_map.find(model_name); it != var_expectation_node_map.end()) return it->second; auto sp = make_unique(*this, node_list.size(), model_name); @@ -692,10 +688,9 @@ DataTree::AddVarExpectation(const string &model_name) } expr_t -DataTree::AddPacExpectation(const string &model_name) +DataTree::AddPacExpectation(const string& model_name) { - if (auto it = pac_expectation_node_map.find(model_name); - it != pac_expectation_node_map.end()) + if (auto it = pac_expectation_node_map.find(model_name); it != pac_expectation_node_map.end()) return it->second; auto sp = make_unique(*this, node_list.size(), model_name); @@ -706,7 +701,7 @@ DataTree::AddPacExpectation(const string &model_name) } expr_t -DataTree::AddPacTargetNonstationary(const string &model_name) +DataTree::AddPacTargetNonstationary(const string& model_name) { if (auto it = pac_target_nonstationary_node_map.find(model_name); it != pac_target_nonstationary_node_map.end()) @@ -719,12 +714,12 @@ DataTree::AddPacTargetNonstationary(const string &model_name) return p; } -BinaryOpNode * +BinaryOpNode* DataTree::AddEqual(expr_t iArg1, expr_t iArg2) { /* We know that we can safely cast to BinaryOpNode because BinaryOpCode::equal can never be reduced to a constant. */ - return dynamic_cast(AddBinaryOp(iArg1, BinaryOpcode::equal, iArg2)); + return dynamic_cast(AddBinaryOp(iArg1, BinaryOpcode::equal, iArg2)); } void @@ -734,65 +729,72 @@ DataTree::AddLocalVariable(int symb_id, expr_t value) noexcept(false) // Throw an exception if symbol already declared if (local_variables_table.contains(symb_id)) - throw LocalVariableException{symbol_table.getName(symb_id)}; + throw LocalVariableException {symbol_table.getName(symb_id)}; local_variables_table.emplace(symb_id, value); local_variables_vector.push_back(symb_id); } expr_t -DataTree::AddExternalFunction(int symb_id, const vector &arguments) +DataTree::AddExternalFunction(int symb_id, const vector& arguments) { assert(symbol_table.getType(symb_id) == SymbolType::externalFunction); - if (auto it = external_function_node_map.find({ arguments, symb_id }); + if (auto it = external_function_node_map.find({arguments, symb_id}); it != external_function_node_map.end()) return it->second; auto sp = make_unique(*this, node_list.size(), symb_id, arguments); auto p = sp.get(); node_list.push_back(move(sp)); - external_function_node_map.try_emplace({ arguments, symb_id }, p); + external_function_node_map.try_emplace({arguments, symb_id}, p); return p; } expr_t -DataTree::AddFirstDerivExternalFunction(int top_level_symb_id, const vector &arguments, int input_index) +DataTree::AddFirstDerivExternalFunction(int top_level_symb_id, const vector& arguments, + int input_index) { assert(symbol_table.getType(top_level_symb_id) == SymbolType::externalFunction); - if (auto it = first_deriv_external_function_node_map.find({ arguments, input_index, top_level_symb_id }); + if (auto it + = first_deriv_external_function_node_map.find({arguments, input_index, top_level_symb_id}); it != first_deriv_external_function_node_map.end()) return it->second; - auto sp = make_unique(*this, node_list.size(), top_level_symb_id, arguments, input_index); + auto sp = make_unique(*this, node_list.size(), top_level_symb_id, + arguments, input_index); auto p = sp.get(); node_list.push_back(move(sp)); - first_deriv_external_function_node_map.try_emplace({ arguments, input_index, top_level_symb_id }, p); + first_deriv_external_function_node_map.try_emplace({arguments, input_index, top_level_symb_id}, + p); return p; } expr_t -DataTree::AddSecondDerivExternalFunction(int top_level_symb_id, const vector &arguments, int input_index1, int input_index2) +DataTree::AddSecondDerivExternalFunction(int top_level_symb_id, const vector& arguments, + int input_index1, int input_index2) { assert(symbol_table.getType(top_level_symb_id) == SymbolType::externalFunction); - if (auto it = second_deriv_external_function_node_map.find({ arguments, input_index1, input_index2, - top_level_symb_id }); - it != second_deriv_external_function_node_map.end()) + if (auto it = second_deriv_external_function_node_map.find( + {arguments, input_index1, input_index2, top_level_symb_id}); + it != second_deriv_external_function_node_map.end()) return it->second; - auto sp = make_unique(*this, node_list.size(), top_level_symb_id, arguments, input_index1, input_index2); + auto sp = make_unique(*this, node_list.size(), top_level_symb_id, + arguments, input_index1, input_index2); auto p = sp.get(); node_list.push_back(move(sp)); - second_deriv_external_function_node_map.try_emplace({ arguments, input_index1, input_index2, top_level_symb_id }, p); + second_deriv_external_function_node_map.try_emplace( + {arguments, input_index1, input_index2, top_level_symb_id}, p); return p; } bool DataTree::isSymbolUsed(int symb_id) const { - for (const auto &[symb_lag, expr] : variable_node_map) + for (const auto& [symb_lag, expr] : variable_node_map) if (symb_lag.first == symb_id) return true; @@ -833,7 +835,7 @@ DataTree::getTypeSpecificIDByDerivID([[maybe_unused]] int deriv_id) const } void -DataTree::addAllParamDerivId([[maybe_unused]] set &deriv_id_set) +DataTree::addAllParamDerivId([[maybe_unused]] set& deriv_id_set) { } @@ -841,14 +843,14 @@ bool DataTree::isUnaryOpUsed(UnaryOpcode opcode) const { return any_of(unary_op_node_map.begin(), unary_op_node_map.end(), - [=](const auto &it) { return get<1>(it.first) == opcode; }); + [=](const auto& it) { return get<1>(it.first) == opcode; }); } bool DataTree::isUnaryOpUsedOnType(SymbolType type, UnaryOpcode opcode) const { set var; - for (const auto &it : unary_op_node_map) + for (const auto& it : unary_op_node_map) if (get<1>(it.first) == opcode) { it.second->collectVariables(type, var); @@ -862,14 +864,14 @@ bool DataTree::isBinaryOpUsed(BinaryOpcode opcode) const { return any_of(binary_op_node_map.begin(), binary_op_node_map.end(), - [=](const auto &it) { return get<2>(it.first) == opcode; }); + [=](const auto& it) { return get<2>(it.first) == opcode; }); } bool DataTree::isBinaryOpUsedOnType(SymbolType type, BinaryOpcode opcode) const { set var; - for (const auto &it : binary_op_node_map) + for (const auto& it : binary_op_node_map) if (get<2>(it.first) == opcode) { it.second->collectVariables(type, var); @@ -883,21 +885,23 @@ int DataTree::minLagForSymbol(int symb_id) const { int r = 0; - for (const auto &[symb_lag, expr] : variable_node_map) + for (const auto& [symb_lag, expr] : variable_node_map) if (symb_lag.first == symb_id) r = min(r, symb_lag.second); return r; } void -DataTree::writeCHelpersDefinition(ostream &output) const +DataTree::writeCHelpersDefinition(ostream& output) const { if (isBinaryOpUsed(BinaryOpcode::powerDeriv)) output << "// The k-th derivative of x^p" << endl << "inline double" << endl << "getPowerDeriv(double x, double p, int k)" << endl << "{" << endl - << " if (fabs(x) < " << power_deriv_near_zero << " && p > 0 && k > p && fabs(p-nearbyint(p)) < " << power_deriv_near_zero << ')' << endl + << " if (fabs(x) < " << power_deriv_near_zero + << " && p > 0 && k > p && fabs(p-nearbyint(p)) < " << power_deriv_near_zero << ')' + << endl << " return 0.0;" << endl << " else" << endl << " {" << endl @@ -917,7 +921,7 @@ DataTree::writeCHelpersDefinition(ostream &output) const } void -DataTree::writeCHelpersDeclaration(ostream &output) const +DataTree::writeCHelpersDeclaration(ostream& output) const { if (isBinaryOpUsed(BinaryOpcode::powerDeriv)) output << "extern inline double getPowerDeriv(double x, double p, int k);" << endl; @@ -932,12 +936,11 @@ DataTree::strsplit(string_view str, char delim) while (true) { size_t idx {str.find(delim)}; - if (auto sub {str.substr(0, idx)}; - !sub.empty()) + if (auto sub {str.substr(0, idx)}; !sub.empty()) result.emplace_back(sub); if (idx == string_view::npos) break; - str.remove_prefix(idx+1); + str.remove_prefix(idx + 1); } return result; } @@ -946,30 +949,30 @@ filesystem::path DataTree::packageDir(string_view package) { filesystem::path d; - for (const auto &it : strsplit(move(package), '.')) + for (const auto& it : strsplit(move(package), '.')) d /= "+" + it; return d; } void -DataTree::writeToFileIfModified(stringstream &new_contents, const filesystem::path &filename) +DataTree::writeToFileIfModified(stringstream& new_contents, const filesystem::path& filename) { - ifstream old_file{filename, ios::in | ios::binary}; + ifstream old_file {filename, ios::in | ios::binary}; if (old_file.is_open() - && equal(istreambuf_iterator{old_file}, istreambuf_iterator{}, - istreambuf_iterator{new_contents}, istreambuf_iterator{})) + && equal(istreambuf_iterator {old_file}, istreambuf_iterator {}, + istreambuf_iterator {new_contents}, istreambuf_iterator {})) return; old_file.close(); new_contents.seekg(0); - ofstream new_file{filename, ios::out | ios::binary}; + ofstream new_file {filename, ios::out | ios::binary}; if (!new_file.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; exit(EXIT_FAILURE); } - copy(istreambuf_iterator{new_contents}, istreambuf_iterator{}, - ostreambuf_iterator{new_file}); + copy(istreambuf_iterator {new_contents}, istreambuf_iterator {}, + ostreambuf_iterator {new_file}); new_file.close(); } diff --git a/src/DataTree.hh b/src/DataTree.hh index 74e2916d..56bec998 100644 --- a/src/DataTree.hh +++ b/src/DataTree.hh @@ -20,22 +20,22 @@ #ifndef _DATATREE_HH #define _DATATREE_HH -#include -#include -#include -#include -#include #include -#include -#include #include +#include +#include +#include +#include +#include #include +#include +#include -#include "SymbolTable.hh" -#include "NumericalConstants.hh" -#include "ExternalFunctionsTable.hh" #include "ExprNode.hh" +#include "ExternalFunctionsTable.hh" +#include "NumericalConstants.hh" #include "SubModel.hh" +#include "SymbolTable.hh" using namespace std; @@ -43,57 +43,61 @@ class DataTree { public: //! A reference to the symbol table - SymbolTable &symbol_table; + SymbolTable& symbol_table; //! Reference to numerical constants table - NumericalConstants &num_constants; + NumericalConstants& num_constants; //! A reference to the external functions table - ExternalFunctionsTable &external_functions_table; + ExternalFunctionsTable& external_functions_table; //! Is it possible to use leads/lags on variable nodes? const bool is_dynamic; private: //! num_constant_id -> NumConstNode - using num_const_node_map_t = map; + using num_const_node_map_t = map; num_const_node_map_t num_const_node_map; //! (symbol_id, lag) -> VariableNode - using variable_node_map_t = map, VariableNode *>; + using variable_node_map_t = map, VariableNode*>; variable_node_map_t variable_node_map; - //! (arg, op_code, arg_exp_info_set, param1_symb_id, param2_symb_id, adl_param_name, adl_lags) -> UnaryOpNode - using unary_op_node_map_t = map>, UnaryOpNode *>; + //! (arg, op_code, arg_exp_info_set, param1_symb_id, param2_symb_id, adl_param_name, adl_lags) -> + //! UnaryOpNode + using unary_op_node_map_t + = map>, UnaryOpNode*>; unary_op_node_map_t unary_op_node_map; //! ( arg1, arg2, opCode, order of Power Derivative) -> BinaryOpNode - using binary_op_node_map_t = map, BinaryOpNode *>; + using binary_op_node_map_t = map, BinaryOpNode*>; binary_op_node_map_t binary_op_node_map; //! ( arg1, arg2, arg3, opCode) -> TrinaryOpNode - using trinary_op_node_map_t = map, TrinaryOpNode *>; + using trinary_op_node_map_t = map, TrinaryOpNode*>; trinary_op_node_map_t trinary_op_node_map; // (arguments, symb_id) -> ExternalFunctionNode - using external_function_node_map_t = map, int>, ExternalFunctionNode *>; + using external_function_node_map_t = map, int>, ExternalFunctionNode*>; external_function_node_map_t external_function_node_map; // (model_name, symb_id, forecast_horizon) -> VarExpectationNode - using var_expectation_node_map_t = map; + using var_expectation_node_map_t = map; var_expectation_node_map_t var_expectation_node_map; // model_name -> PacExpectationNode - using pac_expectation_node_map_t = map; + using pac_expectation_node_map_t = map; pac_expectation_node_map_t pac_expectation_node_map; // model_name -> PacTargetNonstationaryNode - using pac_target_nonstationary_node_map_t = map; + using pac_target_nonstationary_node_map_t = map; pac_target_nonstationary_node_map_t pac_target_nonstationary_node_map; // (arguments, deriv_idx, symb_id) -> FirstDerivExternalFunctionNode - using first_deriv_external_function_node_map_t = map, int, int>, FirstDerivExternalFunctionNode *>; + using first_deriv_external_function_node_map_t + = map, int, int>, FirstDerivExternalFunctionNode*>; first_deriv_external_function_node_map_t first_deriv_external_function_node_map; // (arguments, deriv_idx1, deriv_idx2, symb_id) -> SecondDerivExternalFunctionNode - using second_deriv_external_function_node_map_t = map, int, int, int>, SecondDerivExternalFunctionNode *>; + using second_deriv_external_function_node_map_t + = map, int, int, int>, SecondDerivExternalFunctionNode*>; second_deriv_external_function_node_map_t second_deriv_external_function_node_map; // Flag to disable simplifications related to commutativity of addition and multiplication @@ -102,7 +106,8 @@ private: protected: //! Stores local variables value (maps symbol ID to corresponding node) map local_variables_table; - //! Stores the order of appearance of local variables in the model block. Needed following change in #563 + //! Stores the order of appearance of local variables in the model block. Needed following change + //! in #563 vector local_variables_vector; //! Internal implementation of ParamUsedWithLeadLag() @@ -111,31 +116,33 @@ protected: /* Writes the contents of “new_contents” to the file “filename”. However, if the file already exists and would not be modified by this operation, then do nothing. */ - static void writeToFileIfModified(stringstream &new_contents, const filesystem::path &filename); + static void writeToFileIfModified(stringstream& new_contents, const filesystem::path& filename); private: - constexpr static int constants_precision{16}; + constexpr static int constants_precision {16}; //! The list of nodes vector> node_list; - inline expr_t AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set = 0, int param1_symb_id = 0, int param2_symb_id = 0, const string &adl_param_name = "", const vector &adl_lags = vector()); - inline expr_t AddBinaryOp(expr_t arg1, BinaryOpcode op_code, expr_t arg2, int powerDerivOrder = 0); + inline expr_t AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set = 0, + int param1_symb_id = 0, int param2_symb_id = 0, + const string& adl_param_name = "", + const vector& adl_lags = vector()); + inline expr_t AddBinaryOp(expr_t arg1, BinaryOpcode op_code, expr_t arg2, + int powerDerivOrder = 0); inline expr_t AddTrinaryOp(expr_t arg1, TrinaryOpcode op_code, expr_t arg2, expr_t arg3); //! Initializes the predefined constants, used only from the constructors void initConstants(); public: - DataTree(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg, - bool is_static_args = false); + DataTree(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg, bool is_static_args = false); virtual ~DataTree() = default; - DataTree(const DataTree &d); - DataTree &operator=(const DataTree &d); + DataTree(const DataTree& d); + DataTree& operator=(const DataTree& d); //! Some predefined constants NumConstNode *Zero, *One, *Two, *Three, *NaN, *Infinity, *Pi; @@ -153,13 +160,13 @@ public: inline expr_t AddPossiblyNegativeConstant(double val); //! Adds a non-negative numerical constant (possibly Inf or NaN) - NumConstNode *AddNonNegativeConstant(const string &value); + NumConstNode* AddNonNegativeConstant(const string& value); //! Adds a variable - VariableNode *AddVariable(int symb_id, int lag = 0); + VariableNode* AddVariable(int symb_id, int lag = 0); //! Gets a variable /*! Same as AddVariable, except that it fails if the variable node has not already been created */ - VariableNode *getVariable(int symb_id, int lag = 0) const; + VariableNode* getVariable(int symb_id, int lag = 0) const; //! Adds "arg1+arg2" to model tree expr_t AddPlus(expr_t iArg1, expr_t iArg2); //! Adds "arg1-arg2" to model tree @@ -191,7 +198,7 @@ public: //! Adds "diff(arg)" to model tree expr_t AddDiff(expr_t iArg1); //! Adds "adl(arg1, name, lag/lags)" to model tree - expr_t AddAdl(expr_t iArg1, const string &name, const vector &lags); + expr_t AddAdl(expr_t iArg1, const string& name, const vector& lags); //! Adds "exp(arg)" to model tree expr_t AddExp(expr_t iArg1); //! Adds "log(arg)" to model tree @@ -249,21 +256,23 @@ public: //! Add 2nd derivative of steady state w.r.t. parameter to model tree expr_t AddSteadyStateParam2ndDeriv(expr_t iArg1, int param1_symb_id, int param2_symb_id); //! Adds "arg1=arg2" to model tree - BinaryOpNode *AddEqual(expr_t iArg1, expr_t iArg2); + BinaryOpNode* AddEqual(expr_t iArg1, expr_t iArg2); //! Adds "var_expectation(model_name)" to model tree - expr_t AddVarExpectation(const string &model_name); + expr_t AddVarExpectation(const string& model_name); //! Adds pac_expectation command to model tree - expr_t AddPacExpectation(const string &model_name); + expr_t AddPacExpectation(const string& model_name); //! Adds a pac_target_nonstationary node to model tree - expr_t AddPacTargetNonstationary(const string &model_name); + expr_t AddPacTargetNonstationary(const string& model_name); //! Adds a model local variable with its value void AddLocalVariable(int symb_id, expr_t value) noexcept(false); //! Adds an external function node - expr_t AddExternalFunction(int symb_id, const vector &arguments); + expr_t AddExternalFunction(int symb_id, const vector& arguments); //! Adds an external function node for the first derivative of an external function - expr_t AddFirstDerivExternalFunction(int top_level_symb_id, const vector &arguments, int input_index); + expr_t AddFirstDerivExternalFunction(int top_level_symb_id, const vector& arguments, + int input_index); //! Adds an external function node for the second derivative of an external function - expr_t AddSecondDerivExternalFunction(int top_level_symb_id, const vector &arguments, int input_index1, int input_index2); + expr_t AddSecondDerivExternalFunction(int top_level_symb_id, const vector& arguments, + int input_index1, int input_index2); //! Checks if a given symbol is used somewhere in the data tree bool isSymbolUsed(int symb_id) const; //! Checks if a given unary op is used somewhere in the data tree @@ -274,18 +283,19 @@ public: bool isBinaryOpUsed(BinaryOpcode opcode) const; //! Checks if a given binary op is used somewhere in the data tree on an endogenous variable bool isBinaryOpUsedOnType(SymbolType type, BinaryOpcode opcode) const; - //! Returns the minimum lag (as a negative number) of the given symbol in the whole data tree (and not only in the equations !!) + //! Returns the minimum lag (as a negative number) of the given symbol in the whole data tree (and + //! not only in the equations !!) /*! Returns 0 if the symbol is not used */ int minLagForSymbol(int symb_id) const; /* Writes definitions of C function helpers (getPowerDeriv(), sign()) as inline functions */ - void writeCHelpersDefinition(ostream &output) const; + void writeCHelpersDefinition(ostream& output) const; /* Writes declarations of C function helpers (getPowerDeriv(), sign()) as extern inline (external definition). Those need to be included in exactly one translation unit. That external definition will be used or not, depending on the optimization decision by the compiler. See https://en.cppreference.com/w/c/language/inline */ - void writeCHelpersDeclaration(ostream &output) const; + void writeCHelpersDeclaration(ostream& output) const; //! Thrown when trying to access an unknown variable by deriv_id class UnknownDerivIDException { @@ -333,9 +343,10 @@ public: } //! Adds to the set all the deriv IDs corresponding to parameters - virtual void addAllParamDerivId(set &deriv_id_set); + virtual void addAllParamDerivId(set& deriv_id_set); - //! Returns bool indicating whether DataTree represents a Dynamic Model (returns true in DynamicModel.hh) + //! Returns bool indicating whether DataTree represents a Dynamic Model (returns true in + //! DynamicModel.hh) virtual bool isDynamic() const { @@ -353,7 +364,7 @@ public: { auto it = local_variables_table.find(symb_id); if (it == local_variables_table.end()) - throw UnknownLocalVariableException{symb_id}; + throw UnknownLocalVariableException {symb_id}; return it->second; } @@ -404,17 +415,19 @@ DataTree::AddPossiblyNegativeConstant(double v) } inline expr_t -DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int param1_symb_id, int param2_symb_id, const string &adl_param_name, const vector &adl_lags) +DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int param1_symb_id, + int param2_symb_id, const string& adl_param_name, const vector& adl_lags) { // If the node already exists in tree, share it - if (auto it = unary_op_node_map.find({ arg, op_code, arg_exp_info_set, param1_symb_id, param2_symb_id, adl_param_name, adl_lags }); + if (auto it = unary_op_node_map.find({arg, op_code, arg_exp_info_set, param1_symb_id, + param2_symb_id, adl_param_name, adl_lags}); it != unary_op_node_map.end()) return it->second; // Try to reduce to a constant - // Case where arg is a constant and op_code == UnaryOpcode::uminus (i.e. we're adding a negative constant) is skipped - if (auto carg = dynamic_cast(arg); - op_code != UnaryOpcode::uminus || !carg) + // Case where arg is a constant and op_code == UnaryOpcode::uminus (i.e. we're adding a negative + // constant) is skipped + if (auto carg = dynamic_cast(arg); op_code != UnaryOpcode::uminus || !carg) { try { @@ -422,22 +435,25 @@ DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int double val = UnaryOpNode::eval_opcode(op_code, argval); return AddPossiblyNegativeConstant(val); } - catch (ExprNode::EvalException &e) + catch (ExprNode::EvalException& e) { } } - auto sp = make_unique(*this, node_list.size(), op_code, arg, arg_exp_info_set, param1_symb_id, param2_symb_id, adl_param_name, adl_lags); + auto sp = make_unique(*this, node_list.size(), op_code, arg, arg_exp_info_set, + param1_symb_id, param2_symb_id, adl_param_name, adl_lags); auto p = sp.get(); node_list.push_back(move(sp)); - unary_op_node_map.try_emplace({ arg, op_code, arg_exp_info_set, param1_symb_id, param2_symb_id, adl_param_name, adl_lags }, p); + unary_op_node_map.try_emplace( + {arg, op_code, arg_exp_info_set, param1_symb_id, param2_symb_id, adl_param_name, adl_lags}, + p); return p; } inline expr_t DataTree::AddBinaryOp(expr_t arg1, BinaryOpcode op_code, expr_t arg2, int powerDerivOrder) { - if (auto it = binary_op_node_map.find({ arg1, arg2, op_code, powerDerivOrder }); + if (auto it = binary_op_node_map.find({arg1, arg2, op_code, powerDerivOrder}); it != binary_op_node_map.end()) return it->second; @@ -449,21 +465,22 @@ DataTree::AddBinaryOp(expr_t arg1, BinaryOpcode op_code, expr_t arg2, int powerD double val = BinaryOpNode::eval_opcode(argval1, op_code, argval2, powerDerivOrder); return AddPossiblyNegativeConstant(val); } - catch (ExprNode::EvalException &e) + catch (ExprNode::EvalException& e) { } - auto sp = make_unique(*this, node_list.size(), arg1, op_code, arg2, powerDerivOrder); + auto sp + = make_unique(*this, node_list.size(), arg1, op_code, arg2, powerDerivOrder); auto p = sp.get(); node_list.push_back(move(sp)); - binary_op_node_map.try_emplace({ arg1, arg2, op_code, powerDerivOrder }, p); + binary_op_node_map.try_emplace({arg1, arg2, op_code, powerDerivOrder}, p); return p; } inline expr_t DataTree::AddTrinaryOp(expr_t arg1, TrinaryOpcode op_code, expr_t arg2, expr_t arg3) { - if (auto it = trinary_op_node_map.find({ arg1, arg2, arg3, op_code }); + if (auto it = trinary_op_node_map.find({arg1, arg2, arg3, op_code}); it != trinary_op_node_map.end()) return it->second; @@ -476,14 +493,14 @@ DataTree::AddTrinaryOp(expr_t arg1, TrinaryOpcode op_code, expr_t arg2, expr_t a double val = TrinaryOpNode::eval_opcode(argval1, op_code, argval2, argval3); return AddPossiblyNegativeConstant(val); } - catch (ExprNode::EvalException &e) + catch (ExprNode::EvalException& e) { } auto sp = make_unique(*this, node_list.size(), arg1, op_code, arg2, arg3); auto p = sp.get(); node_list.push_back(move(sp)); - trinary_op_node_map.try_emplace({ arg1, arg2, arg3, op_code }, p); + trinary_op_node_map.try_emplace({arg1, arg2, arg3, op_code}, p); return p; } diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index c68c12f4..a48e5502 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -17,11 +17,11 @@ * along with Dynare. If not, see . */ -#include +#include +#include #include #include -#include -#include +#include #include #include #include @@ -31,70 +31,69 @@ #include "ParsingDriver.hh" void -DynamicModel::copyHelper(const DynamicModel &m) +DynamicModel::copyHelper(const DynamicModel& m) { - auto f = [this](const ExprNode *e) { return e->clone(*this); }; + auto f = [this](const ExprNode* e) { return e->clone(*this); }; - for (const auto &it : m.static_only_equations) - static_only_equations.push_back(dynamic_cast(f(it))); + for (const auto& it : m.static_only_equations) + static_only_equations.push_back(dynamic_cast(f(it))); } -DynamicModel::DynamicModel(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg, - TrendComponentModelTable &trend_component_model_table_arg, - VarModelTable &var_model_table_arg) : - ModelTree{symbol_table_arg, num_constants_arg, external_functions_table_arg, true}, - trend_component_model_table{trend_component_model_table_arg}, - var_model_table{var_model_table_arg} +DynamicModel::DynamicModel(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg, + TrendComponentModelTable& trend_component_model_table_arg, + VarModelTable& var_model_table_arg) : + ModelTree {symbol_table_arg, num_constants_arg, external_functions_table_arg, true}, + trend_component_model_table {trend_component_model_table_arg}, + var_model_table {var_model_table_arg} { } -DynamicModel::DynamicModel(const DynamicModel &m) : - ModelTree{m}, - trend_component_model_table{m.trend_component_model_table}, - var_model_table{m.var_model_table}, - balanced_growth_test_tol{m.balanced_growth_test_tol}, - static_only_equations_lineno{m.static_only_equations_lineno}, - static_only_equations_equation_tags{m.static_only_equations_equation_tags}, - deriv_id_table{m.deriv_id_table}, - inv_deriv_id_table{m.inv_deriv_id_table}, - dyn_jacobian_cols_table{m.dyn_jacobian_cols_table}, - dyn_jacobian_ncols{m.dyn_jacobian_ncols}, - max_lag{m.max_lag}, - max_lead{m.max_lead}, - max_endo_lag{m.max_endo_lag}, - max_endo_lead{m.max_endo_lead}, - max_exo_lag{m.max_exo_lag}, - max_exo_lead{m.max_exo_lead}, - max_exo_det_lag{m.max_exo_det_lag}, - max_exo_det_lead{m.max_exo_det_lead}, - max_lag_orig{m.max_lag_orig}, - max_lead_orig{m.max_lead_orig}, - max_lag_with_diffs_expanded_orig{m.max_lag_with_diffs_expanded_orig}, - max_endo_lag_orig{m.max_endo_lag_orig}, - max_endo_lead_orig{m.max_endo_lead_orig}, - max_exo_lag_orig{m.max_exo_lag_orig}, - max_exo_lead_orig{m.max_exo_lead_orig}, - max_exo_det_lag_orig{m.max_exo_det_lag_orig}, - max_exo_det_lead_orig{m.max_exo_det_lead_orig}, - xrefs{m.xrefs}, - xref_param{m.xref_param}, - xref_endo{m.xref_endo}, - xref_exo{m.xref_exo}, - xref_exo_det{m.xref_exo_det}, - nonzero_hessian_eqs{m.nonzero_hessian_eqs}, - variableMapping{m.variableMapping}, - blocks_jacob_cols_endo{m.blocks_jacob_cols_endo}, - var_expectation_functions_to_write{m.var_expectation_functions_to_write}, - mfs{m.mfs}, - static_mfs{m.static_mfs} +DynamicModel::DynamicModel(const DynamicModel& m) : + ModelTree {m}, + trend_component_model_table {m.trend_component_model_table}, + var_model_table {m.var_model_table}, + balanced_growth_test_tol {m.balanced_growth_test_tol}, + static_only_equations_lineno {m.static_only_equations_lineno}, + static_only_equations_equation_tags {m.static_only_equations_equation_tags}, + deriv_id_table {m.deriv_id_table}, + inv_deriv_id_table {m.inv_deriv_id_table}, + dyn_jacobian_cols_table {m.dyn_jacobian_cols_table}, + dyn_jacobian_ncols {m.dyn_jacobian_ncols}, + max_lag {m.max_lag}, + max_lead {m.max_lead}, + max_endo_lag {m.max_endo_lag}, + max_endo_lead {m.max_endo_lead}, + max_exo_lag {m.max_exo_lag}, + max_exo_lead {m.max_exo_lead}, + max_exo_det_lag {m.max_exo_det_lag}, + max_exo_det_lead {m.max_exo_det_lead}, + max_lag_orig {m.max_lag_orig}, + max_lead_orig {m.max_lead_orig}, + max_lag_with_diffs_expanded_orig {m.max_lag_with_diffs_expanded_orig}, + max_endo_lag_orig {m.max_endo_lag_orig}, + max_endo_lead_orig {m.max_endo_lead_orig}, + max_exo_lag_orig {m.max_exo_lag_orig}, + max_exo_lead_orig {m.max_exo_lead_orig}, + max_exo_det_lag_orig {m.max_exo_det_lag_orig}, + max_exo_det_lead_orig {m.max_exo_det_lead_orig}, + xrefs {m.xrefs}, + xref_param {m.xref_param}, + xref_endo {m.xref_endo}, + xref_exo {m.xref_exo}, + xref_exo_det {m.xref_exo_det}, + nonzero_hessian_eqs {m.nonzero_hessian_eqs}, + variableMapping {m.variableMapping}, + blocks_jacob_cols_endo {m.blocks_jacob_cols_endo}, + var_expectation_functions_to_write {m.var_expectation_functions_to_write}, + mfs {m.mfs}, + static_mfs {m.static_mfs} { copyHelper(m); } -DynamicModel & -DynamicModel::operator=(const DynamicModel &m) +DynamicModel& +DynamicModel::operator=(const DynamicModel& m) { ModelTree::operator=(m); @@ -144,7 +143,7 @@ DynamicModel::operator=(const DynamicModel &m) } void -DynamicModel::writeDynamicBytecode(const string &basename) const +DynamicModel::writeDynamicBytecode(const string& basename) const { /* Bytecode only works when there are with as many endogenous as equations. (e.g. the constructor of FBEGINBLOCK_ makes this assumption) */ @@ -160,49 +159,48 @@ DynamicModel::writeDynamicBytecode(const string &basename) const simulation_type = BlockSimulationType::solveBackwardComplete; // First write the .bin file - int u_count_int { writeBytecodeBinFile(basename + "/model/bytecode/dynamic.bin", - simulation_type == BlockSimulationType::solveTwoBoundariesComplete) }; + int u_count_int { + writeBytecodeBinFile(basename + "/model/bytecode/dynamic.bin", + simulation_type == BlockSimulationType::solveTwoBoundariesComplete)}; BytecodeWriter code_file {basename + "/model/bytecode/dynamic.cod"}; // Declare temporary terms - code_file << FDIMT_{static_cast(temporary_terms_derivatives[0].size() - + temporary_terms_derivatives[1].size())}; + code_file << FDIMT_ {static_cast(temporary_terms_derivatives[0].size() + + temporary_terms_derivatives[1].size())}; // Declare the (single) block vector exo(symbol_table.exo_nbr()), exo_det(symbol_table.exo_det_nbr()); iota(exo.begin(), exo.end(), 0); iota(exo_det.begin(), exo_det.end(), 0); - int jacobian_ncols_endo - { static_cast(count_if(dyn_jacobian_cols_table.begin(), dyn_jacobian_cols_table.end(), - [this](const auto &v) - { return getTypeByDerivID(v.first) == SymbolType::endogenous; })) - }; + int jacobian_ncols_endo {static_cast(count_if( + dyn_jacobian_cols_table.begin(), dyn_jacobian_cols_table.end(), + [this](const auto& v) { return getTypeByDerivID(v.first) == SymbolType::endogenous; }))}; vector eq_idx(equations.size()); iota(eq_idx.begin(), eq_idx.end(), 0); vector 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 << 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(code_file); } void -DynamicModel::writeDynamicBlockBytecode(const string &basename) const +DynamicModel::writeDynamicBlockBytecode(const string& basename) const { BytecodeWriter code_file {basename + "/model/bytecode/block/dynamic.cod"}; @@ -215,7 +213,7 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const } // Temporary variables declaration - code_file << FDIMT_{static_cast(blocks_temporary_terms_idxs.size())}; + code_file << FDIMT_ {static_cast(blocks_temporary_terms_idxs.size())}; temporary_terms_t temporary_terms_written; @@ -225,54 +223,57 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const // Write section of .bin file except for evaluate blocks and solve simple blocks const int u_count {simulation_type == BlockSimulationType::solveTwoBoundariesSimple - || simulation_type == BlockSimulationType::solveTwoBoundariesComplete - || simulation_type == BlockSimulationType::solveBackwardComplete - || simulation_type == BlockSimulationType::solveForwardComplete - ? writeBlockBytecodeBinFile(bin_file, block) - : 0}; + || simulation_type + == BlockSimulationType::solveTwoBoundariesComplete + || simulation_type == BlockSimulationType::solveBackwardComplete + || simulation_type == BlockSimulationType::solveForwardComplete + ? 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(blocks_jacob_cols_endo[block].size())}; + 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(blocks_jacob_cols_endo[block].size())}; writeBlockBytecodeHelper(code_file, block, temporary_terms_written); } - code_file << FEND_{}; + code_file << FEND_ {}; } void -DynamicModel::writeDynamicMFile(const string &basename) const +DynamicModel::writeDynamicMFile(const string& basename) const { auto [d_output, tt_output] = writeModelFileHelper(); ostringstream init_output, end_output; init_output << "residual = zeros(" << equations.size() << ", 1);"; writeDynamicMFileHelper(basename, "dynamic_resid", "residual", "dynamic_resid_tt", - temporary_terms_derivatives[0].size(), - "", init_output, end_output, d_output[0], tt_output[0]); + temporary_terms_derivatives[0].size(), "", init_output, end_output, + d_output[0], tt_output[0]); init_output.str(""); init_output << "g1 = zeros(" << equations.size() << ", " << getJacobianColsNbr(false) << ");"; writeDynamicMFileHelper(basename, "dynamic_g1", "g1", "dynamic_g1_tt", - temporary_terms_derivatives[0].size() + temporary_terms_derivatives[1].size(), + temporary_terms_derivatives[0].size() + + temporary_terms_derivatives[1].size(), "dynamic_resid_tt", init_output, end_output, d_output[1], tt_output[1]); writeDynamicMWrapperFunction(basename, "g1"); // For order ≥ 2 - int ncols{getJacobianColsNbr(false)}; - int ntt { static_cast(temporary_terms_derivatives[0].size() + temporary_terms_derivatives[1].size())}; - for (size_t i{2}; i < derivatives.size(); i++) + int ncols {getJacobianColsNbr(false)}; + int ntt {static_cast(temporary_terms_derivatives[0].size() + + temporary_terms_derivatives[1].size())}; + for (size_t i {2}; i < derivatives.size(); i++) { ncols *= getJacobianColsNbr(false); ntt += temporary_terms_derivatives[i].size(); - string gname{"g" + to_string(i)}; - string gprevname{"g" + to_string(i-1)}; + string gname {"g" + to_string(i)}; + string gprevname {"g" + to_string(i - 1)}; init_output.str(""); end_output.str(""); @@ -281,15 +282,14 @@ DynamicModel::writeDynamicMFile(const string &basename) const init_output << gname << "_i = zeros(" << NNZDerivatives[i] << ",1);" << endl << gname << "_j = zeros(" << NNZDerivatives[i] << ",1);" << endl << gname << "_v = zeros(" << NNZDerivatives[i] << ",1);" << endl; - end_output << gname << " = sparse(" - << gname << "_i," << gname << "_j," << gname << "_v," + end_output << gname << " = sparse(" << gname << "_i," << gname << "_j," << gname << "_v," << equations.size() << "," << ncols << ");"; } else init_output << gname << " = sparse([],[],[]," << equations.size() << "," << ncols << ");"; writeDynamicMFileHelper(basename, "dynamic_" + gname, gname, "dynamic_" + gname + "_tt", ntt, - "dynamic_" + gprevname + "_tt", init_output, end_output, - d_output[i], tt_output[i]); + "dynamic_" + gprevname + "_tt", init_output, end_output, d_output[i], + tt_output[i]); if (i <= 3) writeDynamicMWrapperFunction(basename, gname); } @@ -298,7 +298,7 @@ DynamicModel::writeDynamicMFile(const string &basename) const } string -DynamicModel::reform(const string &name1) const +DynamicModel::reform(const string& name1) const { string name = name1; int pos = name.find(R"(\)", 0); @@ -316,12 +316,11 @@ DynamicModel::reform(const string &name1) const } void -DynamicModel::printNonZeroHessianEquations(ostream &output) const +DynamicModel::printNonZeroHessianEquations(ostream& output) const { if (nonzero_hessian_eqs.size() != 1) output << "["; - for (bool printed_something{false}; - int it : nonzero_hessian_eqs) + for (bool printed_something {false}; int it : nonzero_hessian_eqs) { if (exchange(printed_something, true)) output << " "; @@ -332,7 +331,7 @@ DynamicModel::printNonZeroHessianEquations(ostream &output) const } void -DynamicModel::writeDynamicMWrapperFunction(const string &basename, const string &ending) const +DynamicModel::writeDynamicMWrapperFunction(const string& basename, const string& ending) const { string name; if (ending == "g1") @@ -343,7 +342,7 @@ DynamicModel::writeDynamicMWrapperFunction(const string &basename, const string name = "dynamic_resid_g1_g2_g3"; filesystem::path filename {packageDir(basename) / (name + ".m")}; - ofstream output{filename, ios::out | ios::binary}; + ofstream output {filename, ios::out | ios::binary}; if (!output.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; @@ -351,47 +350,59 @@ DynamicModel::writeDynamicMWrapperFunction(const string &basename, const string } if (ending == "g1") - output << "function [residual, g1] = " << name << "(T, y, x, params, steady_state, it_, T_flag)" << endl - << "% function [residual, g1] = " << name << "(T, y, x, params, steady_state, it_, T_flag)" << endl; + output << "function [residual, g1] = " << name << "(T, y, x, params, steady_state, it_, T_flag)" + << endl + << "% function [residual, g1] = " << name + << "(T, y, x, params, steady_state, it_, T_flag)" << endl; else if (ending == "g2") - output << "function [residual, g1, g2] = " << name << "(T, y, x, params, steady_state, it_, T_flag)" << endl - << "% function [residual, g1, g2] = " << name << "(T, y, x, params, steady_state, it_, T_flag)" << endl; + output << "function [residual, g1, g2] = " << name + << "(T, y, x, params, steady_state, it_, T_flag)" << endl + << "% function [residual, g1, g2] = " << name + << "(T, y, x, params, steady_state, it_, T_flag)" << endl; else if (ending == "g3") - output << "function [residual, g1, g2, g3] = " << name << "(T, y, x, params, steady_state, it_, T_flag)" << endl - << "% function [residual, g1, g2, g3] = " << name << "(T, y, x, params, steady_state, it_, T_flag)" << endl; + output << "function [residual, g1, g2, g3] = " << name + << "(T, y, x, params, steady_state, it_, T_flag)" << endl + << "% function [residual, g1, g2, g3] = " << name + << "(T, y, x, params, steady_state, it_, T_flag)" << endl; output << "%" << endl << "% Wrapper function automatically created by Dynare" << endl << "%" << endl << endl << " if T_flag" << endl - << " T = " << basename << ".dynamic_" << ending << "_tt(T, y, x, params, steady_state, it_);" << endl + << " T = " << basename << ".dynamic_" << ending + << "_tt(T, y, x, params, steady_state, it_);" << endl << " end" << endl; if (ending == "g1") - output << " residual = " << basename << ".dynamic_resid(T, y, x, params, steady_state, it_, false);" << endl - << " g1 = " << basename << ".dynamic_g1(T, y, x, params, steady_state, it_, false);" << endl; + output << " residual = " << basename + << ".dynamic_resid(T, y, x, params, steady_state, it_, false);" << endl + << " g1 = " << basename + << ".dynamic_g1(T, y, x, params, steady_state, it_, false);" << endl; else if (ending == "g2") - output << " [residual, g1] = " << basename << ".dynamic_resid_g1(T, y, x, params, steady_state, it_, false);" << endl - << " g2 = " << basename << ".dynamic_g2(T, y, x, params, steady_state, it_, false);" << endl; + output << " [residual, g1] = " << basename + << ".dynamic_resid_g1(T, y, x, params, steady_state, it_, false);" << endl + << " g2 = " << basename + << ".dynamic_g2(T, y, x, params, steady_state, it_, false);" << endl; else if (ending == "g3") - output << " [residual, g1, g2] = " << basename << ".dynamic_resid_g1_g2(T, y, x, params, steady_state, it_, false);" << endl - << " g3 = " << basename << ".dynamic_g3(T, y, x, params, steady_state, it_, false);" << endl; + output << " [residual, g1, g2] = " << basename + << ".dynamic_resid_g1_g2(T, y, x, params, steady_state, it_, false);" << endl + << " g3 = " << basename + << ".dynamic_g3(T, y, x, params, steady_state, it_, false);" << endl; output << endl << "end" << endl; output.close(); } void -DynamicModel::writeDynamicMFileHelper(const string &basename, - const string &name, const string &retvalname, - const string &name_tt, size_t ttlen, - const string &previous_tt_name, - const ostringstream &init_s, const ostringstream &end_s, - const ostringstream &s, const ostringstream &s_tt) const +DynamicModel::writeDynamicMFileHelper(const string& basename, const string& name, + const string& retvalname, const string& name_tt, size_t ttlen, + const string& previous_tt_name, const ostringstream& init_s, + const ostringstream& end_s, const ostringstream& s, + const ostringstream& s_tt) const { filesystem::path filename {packageDir(basename) / (name_tt + ".m")}; - ofstream output{filename, ios::out | ios::binary}; + ofstream output {filename, ios::out | ios::binary}; if (!output.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; @@ -404,27 +415,43 @@ DynamicModel::writeDynamicMFileHelper(const string &basename, << "% File created by Dynare Preprocessor from .mod file" << endl << "%" << endl << "% Inputs:" << endl - << "% T [#temp variables by 1] double vector of temporary terms to be filled by function" << endl - << "% y [#dynamic variables by 1] double vector of endogenous variables in the order stored" << endl - << "% in M_.lead_lag_incidence; see the Manual" << endl - << "% x [nperiods by M_.exo_nbr] double matrix of exogenous variables (in declaration order)" << endl - << "% for all simulation periods" << endl - << "% steady_state [M_.endo_nbr by 1] double vector of steady state values" << endl - << "% params [M_.param_nbr by 1] double vector of parameter values in declaration order" << endl - << "% it_ scalar double time period for exogenous variables for which" << endl + << "% T [#temp variables by 1] double vector of temporary terms to be " + "filled by function" + << endl + << "% y [#dynamic variables by 1] double vector of endogenous variables " + "in the order stored" + << endl + << "% in M_.lead_lag_incidence; see " + "the Manual" + << endl + << "% x [nperiods by M_.exo_nbr] double matrix of exogenous variables " + "(in declaration order)" + << endl + << "% for all simulation periods" + << endl + << "% steady_state [M_.endo_nbr by 1] double vector of steady state values" + << endl + << "% params [M_.param_nbr by 1] double vector of parameter values in " + "declaration order" + << endl + << "% it_ scalar double time period for exogenous " + "variables for which" + << endl << "% to evaluate the model" << endl << "%" << endl << "% Output:" << endl << "% T [#temp variables by 1] double vector of temporary terms" << endl - << "%" << endl << endl + << "%" << endl + << endl << "assert(length(T) >= " << ttlen << ");" << endl << endl; if (!previous_tt_name.empty()) - output << "T = " << basename << "." << previous_tt_name << "(T, y, x, params, steady_state, it_);" << endl << endl; + output << "T = " << basename << "." << previous_tt_name + << "(T, y, x, params, steady_state, it_);" << endl + << endl; - output << s_tt.str() << endl - << "end" << endl; + output << s_tt.str() << endl << "end" << endl; output.close(); filename = packageDir(basename) / (name + ".m"); @@ -435,61 +462,84 @@ DynamicModel::writeDynamicMFileHelper(const string &basename, exit(EXIT_FAILURE); } - output << "function " << retvalname << " = " << name << "(T, y, x, params, steady_state, it_, T_flag)" << endl - << "% function " << retvalname << " = " << name << "(T, y, x, params, steady_state, it_, T_flag)" << endl + output << "function " << retvalname << " = " << name + << "(T, y, x, params, steady_state, it_, T_flag)" << endl + << "% function " << retvalname << " = " << name + << "(T, y, x, params, steady_state, it_, T_flag)" << endl << "%" << endl << "% File created by Dynare Preprocessor from .mod file" << endl << "%" << endl << "% Inputs:" << endl - << "% T [#temp variables by 1] double vector of temporary terms to be filled by function" << endl - << "% y [#dynamic variables by 1] double vector of endogenous variables in the order stored" << endl - << "% in M_.lead_lag_incidence; see the Manual" << endl - << "% x [nperiods by M_.exo_nbr] double matrix of exogenous variables (in declaration order)" << endl - << "% for all simulation periods" << endl - << "% steady_state [M_.endo_nbr by 1] double vector of steady state values" << endl - << "% params [M_.param_nbr by 1] double vector of parameter values in declaration order" << endl - << "% it_ scalar double time period for exogenous variables for which" << endl + << "% T [#temp variables by 1] double vector of temporary terms to be " + "filled by function" + << endl + << "% y [#dynamic variables by 1] double vector of endogenous variables " + "in the order stored" + << endl + << "% in M_.lead_lag_incidence; see " + "the Manual" + << endl + << "% x [nperiods by M_.exo_nbr] double matrix of exogenous variables " + "(in declaration order)" + << endl + << "% for all simulation periods" + << endl + << "% steady_state [M_.endo_nbr by 1] double vector of steady state values" + << endl + << "% params [M_.param_nbr by 1] double vector of parameter values in " + "declaration order" + << endl + << "% it_ scalar double time period for exogenous " + "variables for which" + << endl << "% to evaluate the model" << endl - << "% T_flag boolean boolean flag saying whether or not to calculate temporary terms" << endl + << "% T_flag boolean boolean flag saying whether or not to " + "calculate temporary terms" + << endl << "%" << endl << "% Output:" << endl << "% " << retvalname << endl - << "%" << endl << endl; + << "%" << endl + << endl; if (!name_tt.empty()) output << "if T_flag" << endl - << " T = " << basename << "." << name_tt << "(T, y, x, params, steady_state, it_);" << endl + << " T = " << basename << "." << name_tt << "(T, y, x, params, steady_state, it_);" + << endl << "end" << endl; - output << init_s.str() << endl - << s.str() - << end_s.str() << endl - << "end" << endl; + output << init_s.str() << endl << s.str() << end_s.str() << endl << "end" << endl; output.close(); } void -DynamicModel::writeDynamicMCompatFile(const string &basename) const +DynamicModel::writeDynamicMCompatFile(const string& basename) const { filesystem::path filename {packageDir(basename) / "dynamic.m"}; - ofstream output{filename, ios::out | ios::binary}; + ofstream output {filename, ios::out | ios::binary}; if (!output.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; exit(EXIT_FAILURE); } - int ntt { static_cast(temporary_terms_derivatives[0].size() + temporary_terms_derivatives[1].size() + temporary_terms_derivatives[2].size() + temporary_terms_derivatives[3].size()) }; + int ntt {static_cast( + temporary_terms_derivatives[0].size() + temporary_terms_derivatives[1].size() + + temporary_terms_derivatives[2].size() + temporary_terms_derivatives[3].size())}; output << "function [residual, g1, g2, g3] = dynamic(y, x, params, steady_state, it_)" << endl << " T = NaN(" << ntt << ", 1);" << endl << " if nargout <= 1" << endl - << " residual = " << basename << ".dynamic_resid(T, y, x, params, steady_state, it_, true);" << endl + << " residual = " << basename + << ".dynamic_resid(T, y, x, params, steady_state, it_, true);" << endl << " elseif nargout == 2" << endl - << " [residual, g1] = " << basename << ".dynamic_resid_g1(T, y, x, params, steady_state, it_, true);" << endl + << " [residual, g1] = " << basename + << ".dynamic_resid_g1(T, y, x, params, steady_state, it_, true);" << endl << " elseif nargout == 3" << endl - << " [residual, g1, g2] = " << basename << ".dynamic_resid_g1_g2(T, y, x, params, steady_state, it_, true);" << endl + << " [residual, g1, g2] = " << basename + << ".dynamic_resid_g1_g2(T, y, x, params, steady_state, it_, true);" << endl << " else" << endl - << " [residual, g1, g2, g3] = " << basename << ".dynamic_resid_g1_g2_g3(T, y, x, params, steady_state, it_, true);" << endl + << " [residual, g1, g2, g3] = " << basename + << ".dynamic_resid_g1_g2_g3(T, y, x, params, steady_state, it_, true);" << endl << " end" << endl << "end" << endl; @@ -497,10 +547,9 @@ DynamicModel::writeDynamicMCompatFile(const string &basename) const } vector> -DynamicModel::parseIncludeExcludeEquations(const string &inc_exc_option_value, bool exclude_eqs) +DynamicModel::parseIncludeExcludeEquations(const string& inc_exc_option_value, bool exclude_eqs) { - auto removeLeadingTrailingWhitespace = [](string &str) - { + auto removeLeadingTrailingWhitespace = [](string& str) { str.erase(0, str.find_first_not_of("\t\n\v\f\r ")); str.erase(str.find_last_not_of("\t\n\v\f\r ") + 1); }; @@ -537,7 +586,7 @@ DynamicModel::parseIncludeExcludeEquations(const string &inc_exc_option_value, b if (!tags.empty()) { - tags = tags.substr(0, tags.size()-1); + tags = tags.substr(0, tags.size() - 1); if (tagname_on_first_line) tags += ")"; } @@ -570,13 +619,14 @@ DynamicModel::parseIncludeExcludeEquations(const string &inc_exc_option_value, b tags = tags.substr(1, tags.length() - 2); removeLeadingTrailingWhitespace(tags); } - tagname = tagname.substr(0, tagname.size()-1); + tagname = tagname.substr(0, tagname.size() - 1); removeLeadingTrailingWhitespace(tagname); } string quote_regex = "'[^']+'"; string non_quote_regex = R"([^,\s]+)"; - regex r(R"((\s*)" + quote_regex + "|" + non_quote_regex + R"(\s*)(,\s*()" + quote_regex + "|" + non_quote_regex + R"()\s*)*)"); + regex r(R"((\s*)" + quote_regex + "|" + non_quote_regex + R"(\s*)(,\s*()" + quote_regex + "|" + + non_quote_regex + R"()\s*)*)"); if (!regex_match(tags, r)) { cerr << "ERROR: " << (exclude_eqs ? "exclude_eqs" : "include_eqs") @@ -586,8 +636,7 @@ DynamicModel::parseIncludeExcludeEquations(const string &inc_exc_option_value, b vector> eq_tag_set; regex s(quote_regex + "|" + non_quote_regex); - for (auto it = sregex_iterator(tags.begin(), tags.end(), s); - it != sregex_iterator(); ++it) + for (auto it = sregex_iterator(tags.begin(), tags.end(), s); it != sregex_iterator(); ++it) { string_view str {it->str()}; if (str.front() == '\'' && str.back() == '\'') @@ -595,17 +644,17 @@ DynamicModel::parseIncludeExcludeEquations(const string &inc_exc_option_value, b str.remove_prefix(1); str.remove_suffix(1); } - eq_tag_set.push_back({ { tagname, string{str} } }); + eq_tag_set.push_back({{tagname, string {str}}}); } return eq_tag_set; } vector -DynamicModel::removeEquationsHelper(set> &listed_eqs_by_tag, bool exclude_eqs, +DynamicModel::removeEquationsHelper(set>& listed_eqs_by_tag, bool exclude_eqs, bool excluded_vars_change_type, - vector &all_equations, - vector> &all_equations_lineno, - EquationTags &all_equation_tags, bool static_equations) const + vector& all_equations, + vector>& all_equations_lineno, + EquationTags& all_equation_tags, bool static_equations) const { if (all_equations.empty()) return {}; @@ -616,8 +665,7 @@ DynamicModel::removeEquationsHelper(set> &listed_eqs_by_tag, the caller knows which tag pairs have not been handled. */ set listed_eqs_by_number; for (auto it = listed_eqs_by_tag.begin(); it != listed_eqs_by_tag.end();) - if (auto tmp = all_equation_tags.getEqnsByTags(*it); - !tmp.empty()) + if (auto tmp = all_equation_tags.getEqnsByTags(*it); !tmp.empty()) { listed_eqs_by_number.insert(tmp.begin(), tmp.end()); it = listed_eqs_by_tag.erase(it); @@ -635,7 +683,7 @@ DynamicModel::removeEquationsHelper(set> &listed_eqs_by_tag, eqs_to_delete_by_number.insert(i); // remove from equations, equations_lineno, equation_tags - vector new_equations; + vector new_equations; vector> new_equations_lineno; map old_eqn_num_2_new; vector excluded_vars; @@ -654,8 +702,10 @@ DynamicModel::removeEquationsHelper(set> &listed_eqs_by_tag, excluded_vars.push_back(*result.begin()); else { - cerr << "ERROR: Equation " << i+1 - << " has been excluded but it does not have a single variable on its left-hand side or an `endogenous` tag" << endl; + cerr << "ERROR: Equation " << i + 1 + << " has been excluded but it does not have a single variable on its " + "left-hand side or an `endogenous` tag" + << endl; exit(EXIT_FAILURE); } } @@ -676,31 +726,34 @@ DynamicModel::removeEquationsHelper(set> &listed_eqs_by_tag, if (!static_equations) for (size_t i = 0; i < excluded_vars.size(); i++) - for (size_t j = i+1; j < excluded_vars.size(); j++) + for (size_t j = i + 1; j < excluded_vars.size(); j++) if (excluded_vars[i] == excluded_vars[j]) { cerr << "ERROR: Variable " << symbol_table.getName(i) << " was excluded twice" - << " via a model_remove or model_replace statement, or via the include_eqs or exclude_eqs option" << endl; + << " via a model_remove or model_replace statement, or via the include_eqs or " + "exclude_eqs option" + << endl; exit(EXIT_FAILURE); } - cout << "Excluded " << n_excl << (static_equations ? " static " : " dynamic ") - << "equation" << (n_excl > 1 ? "s" : "") << " via model_remove or model_replace statement, or via include_eqs or exclude_eqs option" << endl; + cout << "Excluded " << n_excl << (static_equations ? " static " : " dynamic ") << "equation" + << (n_excl > 1 ? "s" : "") + << " via model_remove or model_replace statement, or via include_eqs or exclude_eqs option" + << endl; return excluded_vars; } void -DynamicModel::removeEquations(const vector> &listed_eqs_by_tag, bool exclude_eqs, - bool excluded_vars_change_type) +DynamicModel::removeEquations(const vector>& listed_eqs_by_tag, + bool exclude_eqs, bool excluded_vars_change_type) { /* Convert the const vector to a (mutable) set */ set listed_eqs_by_tag2(listed_eqs_by_tag.begin(), listed_eqs_by_tag.end()); - vector excluded_vars = removeEquationsHelper(listed_eqs_by_tag2, exclude_eqs, - excluded_vars_change_type, - equations, equations_lineno, - equation_tags, false); + vector excluded_vars + = removeEquationsHelper(listed_eqs_by_tag2, exclude_eqs, excluded_vars_change_type, equations, + equations_lineno, equation_tags, false); // Ignore output because variables are not excluded when equations marked 'static' are excluded removeEquationsHelper(listed_eqs_by_tag2, exclude_eqs, excluded_vars_change_type, @@ -709,14 +762,16 @@ DynamicModel::removeEquations(const vector> &listed_eqs_by_t if (!listed_eqs_by_tag2.empty()) { - cerr << "ERROR: model_remove/model_replace/exclude_eqs/include_eqs: The equations specified by" << endl; - for (const auto &m : listed_eqs_by_tag) + cerr + << "ERROR: model_remove/model_replace/exclude_eqs/include_eqs: The equations specified by" + << endl; + for (const auto& m : listed_eqs_by_tag) { cerr << " "; if (m.size() > 1) cerr << "[ "; bool first_printed {false}; - for (const auto &[tagname, tagvalue] : m) + for (const auto& [tagname, tagvalue] : m) { if (exchange(first_printed, true)) cerr << ", "; @@ -746,18 +801,24 @@ DynamicModel::removeEquations(const vector> &listed_eqs_by_t if (eqn_vars.contains(ev)) { symbol_table.changeType(ev, SymbolType::exogenous); - cerr << "Variable '" << symbol_table.getName(ev) << "' turned into an exogenous, as its defining equation has been removed (but it still appears in an equation)" << endl; + cerr << "Variable '" << symbol_table.getName(ev) + << "' turned into an exogenous, as its defining equation has been removed (but it " + "still appears in an equation)" + << endl; } else { symbol_table.changeType(ev, SymbolType::excludedVariable); - cerr << "Variable '" << symbol_table.getName(ev) << "' has been excluded from the model, as its defining equation has been removed and it appears nowhere else" << endl; + cerr << "Variable '" << symbol_table.getName(ev) + << "' has been excluded from the model, as its defining equation has been removed " + "and it appears nowhere else" + << endl; } } } void -DynamicModel::includeExcludeEquations(const string &inc_exc_option_value, bool exclude_eqs) +DynamicModel::includeExcludeEquations(const string& inc_exc_option_value, bool exclude_eqs) { if (inc_exc_option_value.empty()) return; @@ -771,37 +832,46 @@ DynamicModel::includeExcludeEquations(const string &inc_exc_option_value, bool e ModFile::transformPass(), so we must do the check again */ if (staticOnlyEquationsNbr() != dynamicOnlyEquationsNbr()) { - cerr << "ERROR: exclude_eqs/include_eqs: You must remove the same number of equations marked `static` as equations marked `dynamic`." << endl; + cerr << "ERROR: exclude_eqs/include_eqs: You must remove the same number of equations marked " + "`static` as equations marked `dynamic`." + << endl; exit(EXIT_FAILURE); } } void -DynamicModel::writeBlockDriverOutput(ostream &output) const +DynamicModel::writeBlockDriverOutput(ostream& output) const { - output << "M_.block_structure.time_recursive = " << boolalpha << time_recursive_block_decomposition << ";" << endl; + output << "M_.block_structure.time_recursive = " << boolalpha + << time_recursive_block_decomposition << ";" << endl; for (int blk = 0; blk < static_cast(blocks.size()); blk++) { int block_size = blocks[blk].size; - output << "M_.block_structure.block(" << blk+1 << ").Simulation_Type = " << static_cast(blocks[blk].simulation_type) << ";" << endl - << "M_.block_structure.block(" << blk+1 << ").endo_nbr = " << block_size << ";" << endl - << "M_.block_structure.block(" << blk+1 << ").mfs = " << blocks[blk].mfs_size << ";" << endl - << "M_.block_structure.block(" << blk+1 << ").equation = ["; + output << "M_.block_structure.block(" << blk + 1 + << ").Simulation_Type = " << static_cast(blocks[blk].simulation_type) << ";" + << endl + << "M_.block_structure.block(" << blk + 1 << ").endo_nbr = " << block_size << ";" + << endl + << "M_.block_structure.block(" << blk + 1 << ").mfs = " << blocks[blk].mfs_size << ";" + << endl + << "M_.block_structure.block(" << blk + 1 << ").equation = ["; for (int eq = 0; eq < block_size; eq++) - output << " " << getBlockEquationID(blk, eq)+1; - output << "];" << endl - << "M_.block_structure.block(" << blk+1 << ").variable = ["; + output << " " << getBlockEquationID(blk, eq) + 1; + output << "];" << endl << "M_.block_structure.block(" << blk + 1 << ").variable = ["; for (int var = 0; var < block_size; var++) - output << " " << getBlockVariableID(blk, var)+1; + output << " " << getBlockVariableID(blk, var) + 1; output << "];" << endl - << "M_.block_structure.block(" << blk+1 << ").is_linear = " << boolalpha << blocks[blk].linear << ';' << endl - << "M_.block_structure.block(" << blk+1 << ").NNZDerivatives = " << blocks_derivatives[blk].size() << ';' << endl - << "M_.block_structure.block(" << blk+1 << ").bytecode_jacob_cols_to_sparse = ["; - const bool one_boundary {blocks[blk].simulation_type == BlockSimulationType::solveBackwardSimple - || blocks[blk].simulation_type == BlockSimulationType::solveForwardSimple - || blocks[blk].simulation_type == BlockSimulationType::solveBackwardComplete - || blocks[blk].simulation_type == BlockSimulationType::solveForwardComplete}; + << "M_.block_structure.block(" << blk + 1 << ").is_linear = " << boolalpha + << blocks[blk].linear << ';' << endl + << "M_.block_structure.block(" << blk + 1 + << ").NNZDerivatives = " << blocks_derivatives[blk].size() << ';' << endl + << "M_.block_structure.block(" << blk + 1 << ").bytecode_jacob_cols_to_sparse = ["; + const bool one_boundary { + blocks[blk].simulation_type == BlockSimulationType::solveBackwardSimple + || blocks[blk].simulation_type == BlockSimulationType::solveForwardSimple + || blocks[blk].simulation_type == BlockSimulationType::solveBackwardComplete + || blocks[blk].simulation_type == BlockSimulationType::solveForwardComplete}; /* bytecode_jacob_cols_to_sparse is an array that maps column indices in the Jacobian returned by bytecode MEX in evaluate mode (which only contains nonzero columns, but also incorporate recursive variables), @@ -810,17 +880,21 @@ DynamicModel::writeBlockDriverOutput(ostream &output) const blocks). Columns unused in the sparse representation are indicated by a zero. */ vector bytecode_jacob_cols_to_sparse(blocks_jacob_cols_endo[blk].size()); - for (auto &[key, index] : blocks_jacob_cols_endo[blk]) + for (auto& [key, index] : blocks_jacob_cols_endo[blk]) { auto [var, lag] {key}; - if (var >= blocks[blk].getRecursiveSize() // NB: this check can be removed once Jacobian no longer contains columns for derivatives w.r.t. recursive variables + if (var >= blocks[blk].getRecursiveSize() // NB: this check can be removed once Jacobian + // no longer contains columns for derivatives + // w.r.t. recursive variables && !(one_boundary && lag != 0)) - bytecode_jacob_cols_to_sparse[index] = static_cast(!one_boundary)*(lag+1)*blocks[blk].mfs_size + var - blocks[blk].getRecursiveSize(); + bytecode_jacob_cols_to_sparse[index] + = static_cast(!one_boundary) * (lag + 1) * blocks[blk].mfs_size + var + - blocks[blk].getRecursiveSize(); else bytecode_jacob_cols_to_sparse[index] = -1; } for (int i : bytecode_jacob_cols_to_sparse) - output << i+1 << " "; + output << i + 1 << " "; output << "];" << endl; } @@ -828,36 +902,37 @@ DynamicModel::writeBlockDriverOutput(ostream &output) const output << "M_.block_structure.variable_reordered = ["; for (int i = 0; i < symbol_table.endo_nbr(); i++) - output << " " << endo_idx_block2orig[i]+1; - output << "];" << endl - << "M_.block_structure.equation_reordered = ["; + output << " " << endo_idx_block2orig[i] + 1; + output << "];" << endl << "M_.block_structure.equation_reordered = ["; for (int i = 0; i < symbol_table.endo_nbr(); i++) - output << " " << eq_idx_block2orig[i]+1; + output << " " << eq_idx_block2orig[i] + 1; output << "];" << endl; map>> lag_row_incidence; - for (const auto &[indices, d1] : derivatives[1]) - if (int deriv_id = indices[1]; - getTypeByDerivID(deriv_id) == SymbolType::endogenous) + for (const auto& [indices, d1] : derivatives[1]) + if (int deriv_id = indices[1]; getTypeByDerivID(deriv_id) == SymbolType::endogenous) { int eq = indices[0]; - int var { getTypeSpecificIDByDerivID(deriv_id) }; + int var {getTypeSpecificIDByDerivID(deriv_id)}; int lag = getLagByDerivID(deriv_id); - lag_row_incidence[lag].insert({ eq, var }); + lag_row_incidence[lag].insert({eq, var}); } for (auto [lag, eq_var_set] : lag_row_incidence) { - output << "M_.block_structure.incidence(" << max_endo_lag+lag+1 << ").lead_lag = " << lag << ";" << endl - << "M_.block_structure.incidence(" << max_endo_lag+lag+1 << ").sparse_IM = [" << endl; + output << "M_.block_structure.incidence(" << max_endo_lag + lag + 1 << ").lead_lag = " << lag + << ";" << endl + << "M_.block_structure.incidence(" << max_endo_lag + lag + 1 << ").sparse_IM = [" + << endl; for (auto [eq, var] : eq_var_set) - output << " " << eq+1 << " " << var+1 << ";" << endl; + output << " " << eq + 1 << " " << var + 1 << ";" << endl; output << "];" << endl; } - output << "M_.block_structure.dyn_tmp_nbr = " << blocks_temporary_terms_idxs.size() << ';' << endl; + output << "M_.block_structure.dyn_tmp_nbr = " << blocks_temporary_terms_idxs.size() << ';' + << endl; } void -DynamicModel::writeDriverOutput(ostream &output, bool compute_xrefs) const +DynamicModel::writeDriverOutput(ostream& output, bool compute_xrefs) const { /* Writing initialisation for M_.lead_lag_incidence matrix M_.lead_lag_incidence is a matrix with as many columns as there are @@ -876,20 +951,15 @@ DynamicModel::writeDriverOutput(ostream &output, bool compute_xrefs) const << "M_.orig_maximum_exo_det_lead = " << max_exo_det_lead_orig << ";" << endl << "M_.orig_maximum_lag = " << max_lag_orig << ";" << endl << "M_.orig_maximum_lead = " << max_lead_orig << ";" << endl - << "M_.orig_maximum_lag_with_diffs_expanded = " << max_lag_with_diffs_expanded_orig << ";" << endl + << "M_.orig_maximum_lag_with_diffs_expanded = " << max_lag_with_diffs_expanded_orig << ";" + << endl << "M_.lead_lag_incidence = ["; // Loop on endogenous variables - int nstatic = 0, - nfwrd = 0, - npred = 0, - nboth = 0; + int nstatic = 0, nfwrd = 0, npred = 0, nboth = 0; for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++) { output << endl; - int sstatic = 1, - sfwrd = 0, - spred = 0, - sboth = 0; + int sstatic = 1, sfwrd = 0, spred = 0, sboth = 0; // Loop on periods for (int lag = -max_endo_lag; lag <= max_endo_lead; lag++) { @@ -917,7 +987,7 @@ DynamicModel::writeDriverOutput(ostream &output, bool compute_xrefs) const } } } - catch (UnknownDerivIDException &e) + catch (UnknownDerivIDException& e) { output << " 0"; } @@ -930,14 +1000,14 @@ DynamicModel::writeDriverOutput(ostream &output, bool compute_xrefs) const } output << "]';" << endl << "M_.nstatic = " << nstatic << ";" << endl - << "M_.nfwrd = " << nfwrd << ";" << endl - << "M_.npred = " << npred << ";" << endl - << "M_.nboth = " << nboth << ";" << endl - << "M_.nsfwrd = " << nfwrd+nboth << ";" << endl - << "M_.nspred = " << npred+nboth << ";" << endl - << "M_.ndynamic = " << npred+nboth+nfwrd << ";" << endl + << "M_.nfwrd = " << nfwrd << ";" << endl + << "M_.npred = " << npred << ";" << endl + << "M_.nboth = " << nboth << ";" << endl + << "M_.nsfwrd = " << nfwrd + nboth << ";" << endl + << "M_.nspred = " << npred + nboth << ";" << endl + << "M_.ndynamic = " << npred + nboth + nfwrd << ";" << endl << "M_.dynamic_tmp_nbr = ["; - for (const auto &tts : temporary_terms_derivatives) + for (const auto& tts : temporary_terms_derivatives) output << tts.size() << "; "; output << "];" << endl; @@ -945,7 +1015,7 @@ DynamicModel::writeDriverOutput(ostream &output, bool compute_xrefs) const equation_tags.writeOutput(output); // Write mapping for variables and equations they are present in - for (const auto &variable : variableMapping) + for (const auto& variable : variableMapping) { output << "M_.mapping." << symbol_table.getName(variable.first) << ".eqidx = ["; for (auto equation : variable.second) @@ -955,9 +1025,8 @@ DynamicModel::writeDriverOutput(ostream &output, bool compute_xrefs) const /* Say if static and dynamic models differ (because of [static] and [dynamic] equation tags) */ - output << "M_.static_and_dynamic_models_differ = " - << boolalpha << (static_only_equations.size() > 0) - << ";" << endl; + output << "M_.static_and_dynamic_models_differ = " << boolalpha + << (static_only_equations.size() > 0) << ";" << endl; // Say if model contains an external function call bool has_external_function = false; @@ -967,8 +1036,7 @@ DynamicModel::writeDriverOutput(ostream &output, bool compute_xrefs) const has_external_function = true; break; } - output << "M_.has_external_function = " << boolalpha << has_external_function - << ';' << endl; + output << "M_.has_external_function = " << boolalpha << has_external_function << ';' << endl; // Compute list of state variables, ordered in block-order vector state_var; @@ -978,10 +1046,11 @@ DynamicModel::writeDriverOutput(ostream &output, bool compute_xrefs) const try { getDerivID(symbol_table.getID(SymbolType::endogenous, endo_idx_block2orig[endoID]), lag); - if (find(state_var.begin(), state_var.end(), endo_idx_block2orig[endoID]) == state_var.end()) + if (find(state_var.begin(), state_var.end(), endo_idx_block2orig[endoID]) + == state_var.end()) state_var.push_back(endo_idx_block2orig[endoID]); } - catch (UnknownDerivIDException &e) + catch (UnknownDerivIDException& e) { } @@ -991,7 +1060,7 @@ DynamicModel::writeDriverOutput(ostream &output, bool compute_xrefs) const output << "M_.state_var = ["; for (int it : state_var) - output << it+1 << " "; + output << it + 1 << " "; output << "];" << endl; // Writing initialization for some other variables @@ -1010,28 +1079,33 @@ DynamicModel::writeDriverOutput(ostream &output, bool compute_xrefs) const { output << "M_.maximum_exo_det_lag = " << max_exo_det_lag << ";" << endl << "M_.maximum_exo_det_lead = " << max_exo_det_lead << ";" << endl - << "oo_.exo_det_steady_state = zeros(" << symbol_table.exo_det_nbr() << ", 1);" << endl; + << "oo_.exo_det_steady_state = zeros(" << symbol_table.exo_det_nbr() << ", 1);" + << endl; } - output << "M_.params = " << "NaN(" << symbol_table.param_nbr() << ", 1);" << endl; + output << "M_.params = " + << "NaN(" << symbol_table.param_nbr() << ", 1);" << endl; string empty_cell = "cell(" + to_string(symbol_table.endo_nbr()) + ", 1)"; - output << "M_.endo_trends = struct('deflator', " << empty_cell - << ", 'log_deflator', " << empty_cell << ", 'growth_factor', " << empty_cell - << ", 'log_growth_factor', " << empty_cell << ");" << endl; + output << "M_.endo_trends = struct('deflator', " << empty_cell << ", 'log_deflator', " + << empty_cell << ", 'growth_factor', " << empty_cell << ", 'log_growth_factor', " + << empty_cell << ");" << endl; for (int i = 0; i < symbol_table.endo_nbr(); i++) { int symb_id = symbol_table.getID(SymbolType::endogenous, i); if (auto it = nonstationary_symbols_map.find(symb_id); it != nonstationary_symbols_map.end()) { auto [is_log, deflator] = it->second; - output << "M_.endo_trends(" << i+1 << ")." - << (is_log ? "log_deflator" : "deflator") << " = '"; + output << "M_.endo_trends(" << i + 1 << ")." << (is_log ? "log_deflator" : "deflator") + << " = '"; deflator->writeJsonOutput(output, {}, {}); output << "';" << endl; - auto growth_factor = const_cast(this)->AddDivide(deflator, deflator->decreaseLeadsLags(1))->removeTrendLeadLag(trend_symbols_map)->replaceTrendVar(); - output << "M_.endo_trends(" << i+1 << ")." + auto growth_factor = const_cast(this) + ->AddDivide(deflator, deflator->decreaseLeadsLags(1)) + ->removeTrendLeadLag(trend_symbols_map) + ->replaceTrendVar(); + output << "M_.endo_trends(" << i + 1 << ")." << (is_log ? "log_growth_factor" : "growth_factor") << " = '"; growth_factor->writeJsonOutput(output, {}, {}); output << "';" << endl; @@ -1062,7 +1136,7 @@ DynamicModel::writeDriverOutput(ostream &output, bool compute_xrefs) const } void -DynamicModel::runTrendTest(const eval_context_t &eval_context) +DynamicModel::runTrendTest(const eval_context_t& eval_context) { computeDerivIDs(); testTrendDerivativesEqualToZero(eval_context); @@ -1071,12 +1145,12 @@ DynamicModel::runTrendTest(const eval_context_t &eval_context) void DynamicModel::updateVarAndTrendModel() const { - for (bool var : { true, false }) + for (bool var : {true, false}) { map>> trend_varr; map>>> rhsr; - for (const auto &[model_name, eqns] : (var ? var_model_table.getEqNums() - : trend_component_model_table.getEqNums())) + for (const auto& [model_name, eqns] : + (var ? var_model_table.getEqNums() : trend_component_model_table.getEqNums())) { vector lhs, trend_lhs; vector> trend_var; @@ -1115,21 +1189,25 @@ DynamicModel::updateVarAndTrendModel() const catch (...) { } - optional trend_var_symb_id = equations[eqn]->arg2->findTargetVariable(lhs_symb_id); + optional trend_var_symb_id + = equations[eqn]->arg2->findTargetVariable(lhs_symb_id); if (trend_var_symb_id) { if (symbol_table.isDiffAuxiliaryVariable(*trend_var_symb_id)) try { - trend_var_symb_id = symbol_table.getOrigSymbIdForAuxVar(*trend_var_symb_id); + trend_var_symb_id + = symbol_table.getOrigSymbIdForAuxVar(*trend_var_symb_id); } catch (...) { } - if (find(trend_lhs.begin(), trend_lhs.end(), *trend_var_symb_id) == trend_lhs.end()) + if (find(trend_lhs.begin(), trend_lhs.end(), *trend_var_symb_id) + == trend_lhs.end()) { cerr << "ERROR: trend found in trend_component equation #" << eqn << " (" - << symbol_table.getName(*trend_var_symb_id) << ") does not correspond to a trend equation" << endl; + << symbol_table.getName(*trend_var_symb_id) + << ") does not correspond to a trend equation" << endl; exit(EXIT_FAILURE); } } @@ -1159,16 +1237,16 @@ DynamicModel::fillVarModelTable() const map> lhs_expr_tr; map>>> rhsr; - for (const auto &[model_name, eqtags] : var_model_table.getEqTags()) + for (const auto& [model_name, eqtags] : var_model_table.getEqTags()) { vector eqnumber, lhs; vector lhs_expr_t; vector>> rhs; - for (const auto &eqtag : eqtags) + for (const auto& eqtag : eqtags) { set> lhs_set, lhs_tmp_set, rhs_set; - optional eqn { equation_tags.getEqnByTag("name", eqtag) }; + optional eqn {equation_tags.getEqnByTag("name", eqtag)}; if (!eqn) { cerr << "ERROR: no equation is named '" << eqtag << "'" << endl; @@ -1222,7 +1300,7 @@ DynamicModel::fillVarModelTableFromOrigModel() const map> lags; map>> orig_diff_var; map> diff; - for (const auto &[model_name, eqns] : var_model_table.getEqNums()) + for (const auto& [model_name, eqns] : var_model_table.getEqNums()) { set lhs; vector> orig_diff_var_vec; @@ -1230,37 +1308,42 @@ DynamicModel::fillVarModelTableFromOrigModel() const for (auto eqn : eqns) { // Perform some sanity checks on the RHS - optional eqtag { equation_tags.getTagValueByEqnAndKey(eqn, "name") }; + optional eqtag {equation_tags.getTagValueByEqnAndKey(eqn, "name")}; set> rhs_endo_set, rhs_exo_set; equations[eqn]->arg2->collectDynamicVariables(SymbolType::endogenous, rhs_endo_set); - for (const auto &[symb_id, lag] : rhs_endo_set) + for (const auto& [symb_id, lag] : rhs_endo_set) if (lag > 0) { - cerr << "ERROR: in Equation " << eqtag.value_or(to_string(eqn+1)) - << ". A VAR model may not have leaded endogenous variables on the RHS. " << endl; + cerr << "ERROR: in Equation " << eqtag.value_or(to_string(eqn + 1)) + << ". A VAR model may not have leaded endogenous variables on the RHS. " + << endl; exit(EXIT_FAILURE); } else if (!var_model_table.getStructural().at(model_name) && lag == 0) { - cerr << "ERROR: in Equation " << eqtag.value_or(to_string(eqn+1)) - << ". A non-structural VAR model may not have contemporaneous endogenous variables on the RHS. " << endl; + cerr << "ERROR: in Equation " << eqtag.value_or(to_string(eqn + 1)) + << ". A non-structural VAR model may not have contemporaneous endogenous " + "variables on the RHS. " + << endl; exit(EXIT_FAILURE); } equations[eqn]->arg2->collectDynamicVariables(SymbolType::exogenous, rhs_exo_set); - for (const auto &[symb_id, lag] : rhs_exo_set) + for (const auto& [symb_id, lag] : rhs_exo_set) if (lag != 0) { - cerr << "ERROR: in Equation " << eqtag.value_or(to_string(eqn+1)) - << ". A VAR model may not have lagged or leaded exogenous variables on the RHS. " << endl; + cerr << "ERROR: in Equation " << eqtag.value_or(to_string(eqn + 1)) + << ". A VAR model may not have lagged or leaded exogenous variables on the " + "RHS. " + << endl; exit(EXIT_FAILURE); } // save lhs variables equations[eqn]->arg1->collectVARLHSVariable(lhs); - equations[eqn]->arg1->countDiffs() > 0 ? - diff_vec.push_back(true) : diff_vec.push_back(false); + equations[eqn]->arg1->countDiffs() > 0 ? diff_vec.push_back(true) + : diff_vec.push_back(false); if (diff_vec.back()) { set> diff_set; @@ -1276,7 +1359,6 @@ DynamicModel::fillVarModelTableFromOrigModel() const } else orig_diff_var_vec.push_back(nullopt); - } if (eqns.size() != lhs.size()) @@ -1286,7 +1368,7 @@ DynamicModel::fillVarModelTableFromOrigModel() const } set lhs_lag_equiv; - for (const auto &lh : lhs) + for (const auto& lh : lhs) { auto [lag_equiv_repr, index] = lh->getLagEquivalenceClass(); lhs_lag_equiv.insert(lag_equiv_repr); @@ -1310,15 +1392,14 @@ DynamicModel::getVARDerivIDs(int lhs_symb_id, int lead_lag) const vector deriv_ids; // First directly look for the variable itself - if (auto it = deriv_id_table.find({ lhs_symb_id, lead_lag }); - it != deriv_id_table.end()) + if (auto it = deriv_id_table.find({lhs_symb_id, lead_lag}); it != deriv_id_table.end()) deriv_ids.push_back(it->second); // Then go through auxiliary variables - for (auto &[key, deriv_id2] : deriv_id_table) + for (auto& [key, deriv_id2] : deriv_id_table) { auto [symb_id2, lead_lag2] = key; - const AuxVarInfo *avi; + const AuxVarInfo* avi; try { avi = &symbol_table.getAuxVarInfo(symb_id2); @@ -1362,16 +1443,16 @@ DynamicModel::fillVarModelTableMatrices() map, expr_t>> AR; map, expr_t>> A0; map> constants; - for (const auto &[model_name, eqns] : var_model_table.getEqNums()) + for (const auto& [model_name, eqns] : var_model_table.getEqNums()) { - const vector &lhs = var_model_table.getLhs(model_name); + const vector& lhs = var_model_table.getLhs(model_name); int max_lag = var_model_table.getMaxLag(model_name); for (auto lhs_symb_id : lhs) { // Fill autoregressive matrix (AR) for (int lag = 1; lag <= max_lag; lag++) { - vector deriv_ids = getVARDerivIDs(lhs_symb_id, -lag);; + vector deriv_ids = getVARDerivIDs(lhs_symb_id, -lag); for (size_t i = 0; i < eqns.size(); i++) { expr_t d = Zero; @@ -1381,11 +1462,14 @@ DynamicModel::fillVarModelTableMatrices() { if (!d->isConstant()) { - cerr << "ERROR: Equation " << equation_tags.getTagValueByEqnAndKey(eqns[i], "name").value_or(to_string(eqns[i]+1)) << " is not linear" << endl; + cerr << "ERROR: Equation " + << equation_tags.getTagValueByEqnAndKey(eqns[i], "name") + .value_or(to_string(eqns[i] + 1)) + << " is not linear" << endl; exit(EXIT_FAILURE); } - AR[model_name][{ i, lag, lhs_symb_id }] = AddUMinus(d); + AR[model_name][{i, lag, lhs_symb_id}] = AddUMinus(d); } } } @@ -1399,11 +1483,14 @@ DynamicModel::fillVarModelTableMatrices() { if (!d->isConstant()) { - cerr << "ERROR: Equation " << equation_tags.getTagValueByEqnAndKey(eqns[i], "name").value_or(to_string(eqns[i]+1)) << " is not linear" << endl; + cerr << "ERROR: Equation " + << equation_tags.getTagValueByEqnAndKey(eqns[i], "name") + .value_or(to_string(eqns[i] + 1)) + << " is not linear" << endl; exit(EXIT_FAILURE); } - A0[model_name][{ i, lhs_symb_id }] = d; + A0[model_name][{i, lhs_symb_id}] = d; } } @@ -1413,8 +1500,10 @@ DynamicModel::fillVarModelTableMatrices() for (size_t i = 0; i < eqns.size(); i++) { auto rhs = equations[eqns[i]]->arg2; - map subst_table; - auto rhs_vars = var_model_table.getRhs(model_name)[i]; // All the (transformed) endogenous on RHS, as computed by updateVarAndTrendModel() + map subst_table; + auto rhs_vars = var_model_table.getRhs( + model_name)[i]; // All the (transformed) endogenous on RHS, as computed by + // updateVarAndTrendModel() rhs->collectDynamicVariables(SymbolType::exogenous, rhs_vars); // Add exos for (auto [symb_id, lag] : rhs_vars) subst_table[AddVariable(symb_id, lag)] = Zero; @@ -1433,14 +1522,13 @@ map, expr_t>> DynamicModel::computeAutoregressiveMatrices() const { map, expr_t>> ARr; - for (const auto &[model_name, eqns] : trend_component_model_table.getNonTargetEqNums()) + for (const auto& [model_name, eqns] : trend_component_model_table.getNonTargetEqNums()) { map, expr_t> AR; - const vector &lhs = trend_component_model_table.getNonTargetLhs(model_name); - for (int i{0}; - auto eqn : eqns) + const vector& lhs = trend_component_model_table.getNonTargetLhs(model_name); + for (int i {0}; auto eqn : eqns) { - auto bopn = dynamic_cast(equations[eqn]->arg2); + auto bopn = dynamic_cast(equations[eqn]->arg2); bopn->fillAutoregressiveRow(i++, lhs, AR); } ARr[model_name] = AR; @@ -1454,12 +1542,12 @@ DynamicModel::fillTrendComponentModelTable() const map> eqnums, trend_eqnums, lhsr; map> lhs_expr_tr; map>>> rhsr; - for (const auto &[model_name, eqtags] : trend_component_model_table.getTargetEqTags()) + for (const auto& [model_name, eqtags] : trend_component_model_table.getTargetEqTags()) { vector trend_eqnumber; - for (const auto &eqtag : eqtags) + for (const auto& eqtag : eqtags) { - optional eqn { equation_tags.getEqnByTag("name", eqtag) }; + optional eqn {equation_tags.getEqnByTag("name", eqtag)}; if (!eqn) { cerr << "ERROR: no equation is named '" << eqtag << "'" << endl; @@ -1470,16 +1558,16 @@ DynamicModel::fillTrendComponentModelTable() const trend_eqnums[model_name] = trend_eqnumber; } - for (const auto &[model_name, eqtags] : trend_component_model_table.getEqTags()) + for (const auto& [model_name, eqtags] : trend_component_model_table.getEqTags()) { vector eqnumber, lhs; vector lhs_expr_t; vector>> rhs; - for (const auto &eqtag : eqtags) + for (const auto& eqtag : eqtags) { set> lhs_set, lhs_tmp_set, rhs_set; - optional eqn { equation_tags.getEqnByTag("name", eqtag) }; + optional eqn {equation_tags.getEqnByTag("name", eqtag)}; if (!eqn) { cerr << "ERROR: no equation is named '" << eqtag << "'" << endl; @@ -1493,7 +1581,8 @@ DynamicModel::fillTrendComponentModelTable() const if (lhs_set.size() != 1 || !lhs_tmp_set.empty()) { cerr << "ERROR: in Equation " << eqtag - << ". A trend component model may only have one endogenous variable on the LHS. " << endl; + << ". A trend component model may only have one endogenous variable on the LHS. " + << endl; exit(EXIT_FAILURE); } @@ -1501,7 +1590,8 @@ DynamicModel::fillTrendComponentModelTable() const if (itlhs->second != 0) { cerr << "ERROR: in Equation " << eqtag - << ". The variable on the LHS of a trend component model may not appear with a lead or a lag. " + << ". The variable on the LHS of a trend component model may not appear with a " + "lead or a lag. " << endl; exit(EXIT_FAILURE); } @@ -1522,15 +1612,16 @@ DynamicModel::fillTrendComponentModelTable() const rhsr[model_name] = rhs; } trend_component_model_table.setRhs(move(rhsr)); - trend_component_model_table.setVals(move(eqnums), move(trend_eqnums), move(lhsr), move(lhs_expr_tr)); + trend_component_model_table.setVals(move(eqnums), move(trend_eqnums), move(lhsr), + move(lhs_expr_tr)); } pair, expr_t>>, map, expr_t>>> -DynamicModel::computeErrorComponentMatrices(const ExprNode::subst_table_t &diff_subst_table) const +DynamicModel::computeErrorComponentMatrices(const ExprNode::subst_table_t& diff_subst_table) const { map, expr_t>> A0r, A0starr; - for (const auto &[model_name, eqns] : trend_component_model_table.getEqNums()) + for (const auto& [model_name, eqns] : trend_component_model_table.getEqNums()) { map, expr_t> A0, A0star; vector target_lhs = trend_component_model_table.getTargetLhs(model_name); @@ -1538,23 +1629,22 @@ DynamicModel::computeErrorComponentMatrices(const ExprNode::subst_table_t &diff_ vector undiff_nontarget_lhs = getUndiffLHSForPac(model_name, diff_subst_table); vector parsed_undiff_nontarget_lhs; - for (int i{0}; - auto eqn : eqns) + for (int i {0}; auto eqn : eqns) { if (find(nontarget_eqnums.begin(), nontarget_eqnums.end(), eqn) != nontarget_eqnums.end()) parsed_undiff_nontarget_lhs.push_back(undiff_nontarget_lhs.at(i)); i++; } - for (int i{0}; - auto eqn : eqns) + for (int i {0}; auto eqn : eqns) if (find(nontarget_eqnums.begin(), nontarget_eqnums.end(), eqn) != nontarget_eqnums.end()) - equations[eqn]->arg2->fillErrorCorrectionRow(i++, parsed_undiff_nontarget_lhs, target_lhs, A0, A0star); + equations[eqn]->arg2->fillErrorCorrectionRow(i++, parsed_undiff_nontarget_lhs, target_lhs, + A0, A0star); A0r[model_name] = A0; A0starr[model_name] = A0star; } - return { A0r, A0starr }; + return {A0r, A0starr}; } void @@ -1563,7 +1653,7 @@ DynamicModel::fillTrendComponentModelTableFromOrigModel() const map> lags; map>> orig_diff_var; map> diff; - for (const auto &[model_name, eqns] : trend_component_model_table.getEqNums()) + for (const auto& [model_name, eqns] : trend_component_model_table.getEqNums()) { set lhs; vector> orig_diff_var_vec; @@ -1571,22 +1661,26 @@ DynamicModel::fillTrendComponentModelTableFromOrigModel() const for (auto eqn : eqns) { // Perform some sanity checks on the RHS - optional eqtag { equation_tags.getTagValueByEqnAndKey(eqn, "name") }; + optional eqtag {equation_tags.getTagValueByEqnAndKey(eqn, "name")}; set> rhs_endo_set, rhs_exo_set; equations[eqn]->arg2->collectDynamicVariables(SymbolType::endogenous, rhs_endo_set); - for (const auto &[symb_id, lag] : rhs_endo_set) + for (const auto& [symb_id, lag] : rhs_endo_set) if (lag >= 0) { - cerr << "ERROR: in Equation " << eqtag.value_or(to_string(eqn+1)) - << ". A trend component model may not have leaded or contemporaneous endogenous variables on the RHS. " << endl; + cerr << "ERROR: in Equation " << eqtag.value_or(to_string(eqn + 1)) + << ". A trend component model may not have leaded or contemporaneous " + "endogenous variables on the RHS. " + << endl; exit(EXIT_FAILURE); } equations[eqn]->arg2->collectDynamicVariables(SymbolType::exogenous, rhs_exo_set); - for (const auto &[symb_id, lag] : rhs_exo_set) + for (const auto& [symb_id, lag] : rhs_exo_set) if (lag != 0) { - cerr << "ERROR: in Equation " << eqtag.value_or(to_string(eqn+1)) - << ". A trend component model may not have lagged or leaded exogenous variables on the RHS. " << endl; + cerr << "ERROR: in Equation " << eqtag.value_or(to_string(eqn + 1)) + << ". A trend component model may not have lagged or leaded exogenous " + "variables on the RHS. " + << endl; exit(EXIT_FAILURE); } @@ -1621,7 +1715,7 @@ DynamicModel::fillTrendComponentModelTableFromOrigModel() const } set lhs_lag_equiv; - for (const auto &lh : lhs) + for (const auto& lh : lhs) { auto [lag_equiv_repr, index] = lh->getLagEquivalenceClass(); lhs_lag_equiv.insert(lag_equiv_repr); @@ -1640,7 +1734,8 @@ DynamicModel::fillTrendComponentModelTableFromOrigModel() const } void -DynamicModel::fillTrendComponentModelTableAREC(const ExprNode::subst_table_t &diff_subst_table) const +DynamicModel::fillTrendComponentModelTableAREC( + const ExprNode::subst_table_t& diff_subst_table) const { auto ARr = computeAutoregressiveMatrices(); trend_component_model_table.setAR(move(ARr)); @@ -1649,8 +1744,8 @@ DynamicModel::fillTrendComponentModelTableAREC(const ExprNode::subst_table_t &di } vector -DynamicModel::getUndiffLHSForPac(const string &aux_model_name, - const ExprNode::subst_table_t &diff_subst_table) const +DynamicModel::getUndiffLHSForPac(const string& aux_model_name, + const ExprNode::subst_table_t& diff_subst_table) const { vector lhs_expr_t = trend_component_model_table.getLhsExprT(aux_model_name); vector lhs = trend_component_model_table.getLhs(aux_model_name); @@ -1679,7 +1774,7 @@ DynamicModel::getUndiffLHSForPac(const string &aux_model_name, bool printerr = false; expr_t node = nullptr; expr_t aux_var = lhs_expr_t.at(i); - for (const auto &it : diff_subst_table) + for (const auto& it : diff_subst_table) if (it.second == aux_var) { node = const_cast(it.first); @@ -1700,32 +1795,37 @@ DynamicModel::getUndiffLHSForPac(const string &aux_model_name, if (printerr) { // we have undiffed something like diff(x), hence x is not in diff_subst_table lhs_expr_t.at(i) = node; - lhs.at(i) = dynamic_cast(node)->symb_id; + lhs.at(i) = dynamic_cast(node)->symb_id; } else { lhs_expr_t.at(i) = const_cast(it1->first); - lhs.at(i) = const_cast(it1->second)->symb_id; + lhs.at(i) = const_cast(it1->second)->symb_id; } } return lhs; } void -DynamicModel::analyzePacEquationStructure(const string &name, map &pac_eq_name, PacModelTable::equation_info_t &pac_equation_info) +DynamicModel::analyzePacEquationStructure(const string& name, map& pac_eq_name, + PacModelTable::equation_info_t& pac_equation_info) { - for (auto &equation : equations) + for (auto& equation : equations) if (equation->containsPacExpectation(name)) { if (!pac_eq_name[name].empty()) { - cerr << "It is not possible to use 'pac_expectation(" << name << ")' in several equations." << endl; + cerr << "It is not possible to use 'pac_expectation(" << name + << ")' in several equations." << endl; exit(EXIT_FAILURE); } - optional eqn { equation_tags.getTagValueByEqnAndKey(&equation - &equations[0], "name") }; + optional eqn { + equation_tags.getTagValueByEqnAndKey(&equation - &equations[0], "name")}; if (!eqn) { - cerr << "Every equation with a 'pac_expectation' operator must have been assigned an equation tag name" << endl; + cerr << "Every equation with a 'pac_expectation' operator must have been assigned an " + "equation tag name" + << endl; exit(EXIT_FAILURE); } pac_eq_name[name] = *eqn; @@ -1744,44 +1844,49 @@ DynamicModel::analyzePacEquationStructure(const string &name, map(equation->arg2); + auto arg2 = dynamic_cast(equation->arg2); if (!arg2) { cerr << "Pac equation in incorrect format" << endl; exit(EXIT_FAILURE); } auto [optim_share_index, optim_part, non_optim_part, additive_part] - = arg2->getPacOptimizingShareAndExprNodes(lhs_orig_symb_id); + = arg2->getPacOptimizingShareAndExprNodes(lhs_orig_symb_id); pair>> ec_params_and_vars; vector, optional, int>> ar_params_and_vars; - vector, double>> non_optim_vars_params_and_constants, optim_additive_vars_params_and_constants, additive_vars_params_and_constants; + vector, double>> non_optim_vars_params_and_constants, + optim_additive_vars_params_and_constants, additive_vars_params_and_constants; if (!optim_part) { - auto bopn = dynamic_cast(equation->arg2); + auto bopn = dynamic_cast(equation->arg2); if (!bopn) { cerr << "Error in PAC equation" << endl; exit(EXIT_FAILURE); } - bopn->getPacAREC(lhs_symb_id, lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars, additive_vars_params_and_constants); + bopn->getPacAREC(lhs_symb_id, lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars, + additive_vars_params_and_constants); } else { - auto bopn = dynamic_cast(optim_part); + auto bopn = dynamic_cast(optim_part); if (!bopn) { cerr << "Error in PAC equation" << endl; exit(EXIT_FAILURE); } - bopn->getPacAREC(lhs_symb_id, lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars, optim_additive_vars_params_and_constants); + bopn->getPacAREC(lhs_symb_id, lhs_orig_symb_id, ec_params_and_vars, ar_params_and_vars, + optim_additive_vars_params_and_constants); try { - non_optim_vars_params_and_constants = non_optim_part->matchLinearCombinationOfVariables(); + non_optim_vars_params_and_constants + = non_optim_part->matchLinearCombinationOfVariables(); if (additive_part) - additive_vars_params_and_constants = additive_part->matchLinearCombinationOfVariables(); + additive_vars_params_and_constants + = additive_part->matchLinearCombinationOfVariables(); } - catch (ExprNode::MatchFailureException &e) + catch (ExprNode::MatchFailureException& e) { cerr << "Error in parsing non-optimizing agents or additive part of PAC equation: " << e.message << endl; @@ -1799,16 +1904,18 @@ DynamicModel::analyzePacEquationStructure(const string &name, mapcontainsPacExpectation(pac_model_name)) @@ -1816,16 +1923,17 @@ DynamicModel::getPacTargetSymbId(const string &pac_model_name) const set> lhss; equation->arg1->collectDynamicVariables(SymbolType::endogenous, lhss); if (lhss.size() != 1) - throw PacTargetNotIdentifiedException{pac_model_name, "LHS must contain a single endogenous"}; + throw PacTargetNotIdentifiedException {pac_model_name, + "LHS must contain a single endogenous"}; int lhs_symb_id = lhss.begin()->first; if (!symbol_table.isDiffAuxiliaryVariable(lhs_symb_id)) - throw PacTargetNotIdentifiedException{pac_model_name, "LHS must be a diff operator"}; + throw PacTargetNotIdentifiedException {pac_model_name, "LHS must be a diff operator"}; int undiff_lhs_symb_id = symbol_table.getOrigSymbIdForAuxVar(lhs_symb_id); - auto barg2 = dynamic_cast(equation->arg2); + auto barg2 = dynamic_cast(equation->arg2); if (!barg2) - throw PacTargetNotIdentifiedException{pac_model_name, "RHS must be a binary operator"}; + throw PacTargetNotIdentifiedException {pac_model_name, "RHS must be a binary operator"}; auto [optim_share_index, optim_part, non_optim_part, additive_part] - = barg2->getPacOptimizingShareAndExprNodes(undiff_lhs_symb_id); + = barg2->getPacOptimizingShareAndExprNodes(undiff_lhs_symb_id); /* If there is an optimization part, restrict the search to that part, since it contains the MCE . */ expr_t mce = optim_part ? optim_part : equation->arg2; @@ -1835,34 +1943,33 @@ DynamicModel::getPacTargetSymbId(const string &pac_model_name) const for (auto [term, sign] : terms) try { - auto [param_id, target_id] = term->matchParamTimesTargetMinusVariable(undiff_lhs_symb_id); + auto [param_id, target_id] + = term->matchParamTimesTargetMinusVariable(undiff_lhs_symb_id); return target_id; } - catch (ExprNode::MatchFailureException &) + catch (ExprNode::MatchFailureException&) { } - throw PacTargetNotIdentifiedException{pac_model_name, "No term of the form parameter*(target-LHS_level)"}; + throw PacTargetNotIdentifiedException {pac_model_name, + "No term of the form parameter*(target-LHS_level)"}; } - throw PacTargetNotIdentifiedException{pac_model_name, "No equation with the corresponding pac_expectation operator"}; + throw PacTargetNotIdentifiedException { + pac_model_name, "No equation with the corresponding pac_expectation operator"}; } void -DynamicModel::computePacModelConsistentExpectationSubstitution(const string &name, - int discount_symb_id, - int pac_eq_max_lag, - expr_t growth_correction_term, - string auxname, - ExprNode::subst_table_t &diff_subst_table, - map &pac_aux_var_symb_ids, - map> &pac_aux_param_symb_ids, - map &pac_expectation_substitution) +DynamicModel::computePacModelConsistentExpectationSubstitution( + const string& name, int discount_symb_id, int pac_eq_max_lag, expr_t growth_correction_term, + string auxname, ExprNode::subst_table_t& diff_subst_table, + map& pac_aux_var_symb_ids, map>& pac_aux_param_symb_ids, + map& pac_expectation_substitution) { int pac_target_symb_id; try { pac_target_symb_id = getPacTargetSymbId(name); } - catch (PacTargetNotIdentifiedException &e) + catch (PacTargetNotIdentifiedException& e) { cerr << "Can't identify target for PAC model " << name << ": " << e.message; exit(EXIT_FAILURE); @@ -1878,7 +1985,7 @@ DynamicModel::computePacModelConsistentExpectationSubstitution(const string &nam expr_t A = One; expr_t fp = Zero; expr_t beta = AddVariable(discount_symb_id); - for (int i = 1; i <= pac_eq_max_lag+1; i++) + for (int i = 1; i <= pac_eq_max_lag + 1; i++) { string param_name = "mce_alpha_" + name + "_" + to_string(i); try @@ -1886,53 +1993,51 @@ DynamicModel::computePacModelConsistentExpectationSubstitution(const string &nam int alpha_i_symb_id = symbol_table.addSymbol(param_name, SymbolType::parameter); pac_aux_param_symb_ids[name].push_back(alpha_i_symb_id); A = AddPlus(A, AddVariable(alpha_i_symb_id)); - fp = AddPlus(fp, - AddTimes(AddTimes(AddVariable(alpha_i_symb_id), - AddPower(beta, AddPossiblyNegativeConstant(i))), - AddVariable(mce_z1_symb_id, i))); + fp = AddPlus(fp, AddTimes(AddTimes(AddVariable(alpha_i_symb_id), + AddPower(beta, AddPossiblyNegativeConstant(i))), + AddVariable(mce_z1_symb_id, i))); } - catch (SymbolTable::AlreadyDeclaredException &e) + catch (SymbolTable::AlreadyDeclaredException& e) { - cerr << "The variable/parameter '" << param_name << "' conflicts with a parameter that will be generated for the '" << name << "' PAC model. Please rename it." << endl; + cerr << "The variable/parameter '" << param_name + << "' conflicts with a parameter that will be generated for the '" << name + << "' PAC model. Please rename it." << endl; exit(EXIT_FAILURE); } } // Add diff nodes and eqs for pac_target_symb_id - const VariableNode *target_base_diff_node; - auto create_target_lag = [&](int lag) - { + const VariableNode* target_base_diff_node; + auto create_target_lag = [&](int lag) { if (symbol_table.isAuxiliaryVariable(pac_target_symb_id)) // We know it is a log, see ExprNode::matchParamTimesTargetMinusVariable() return AddLog(AddVariable(symbol_table.getOrigSymbIdForAuxVar(pac_target_symb_id), lag)); else - return dynamic_cast(AddVariable(pac_target_symb_id, lag)); + return dynamic_cast(AddVariable(pac_target_symb_id, lag)); }; expr_t diff_node_to_search = AddDiff(create_target_lag(0)); - if (auto sit = diff_subst_table.find(diff_node_to_search); - sit != diff_subst_table.end()) + if (auto sit = diff_subst_table.find(diff_node_to_search); sit != diff_subst_table.end()) target_base_diff_node = sit->second; else { int symb_id = symbol_table.addDiffAuxiliaryVar(diff_node_to_search->idx, diff_node_to_search); target_base_diff_node = AddVariable(symb_id); - auto neweq = AddEqual(const_cast(target_base_diff_node), - AddMinus(create_target_lag(0), - create_target_lag(-1))); + auto neweq = AddEqual(const_cast(target_base_diff_node), + AddMinus(create_target_lag(0), create_target_lag(-1))); addEquation(neweq, nullopt); addAuxEquation(neweq); neqs++; } - map target_aux_var_to_add; - const VariableNode *last_aux_var = target_base_diff_node; + map target_aux_var_to_add; + const VariableNode* last_aux_var = target_base_diff_node; for (int i = 1; i <= pac_eq_max_lag; i++, neqs++) { expr_t this_diff_node = AddDiff(create_target_lag(i)); int symb_id = symbol_table.addDiffLeadAuxiliaryVar(this_diff_node->idx, this_diff_node, last_aux_var->symb_id, 1); - VariableNode *current_aux_var = AddVariable(symb_id); + VariableNode* current_aux_var = AddVariable(symb_id); auto neweq = AddEqual(current_aux_var, AddVariable(last_aux_var->symb_id, 1)); addEquation(neweq, nullopt); addAuxEquation(neweq); @@ -1944,7 +2049,7 @@ DynamicModel::computePacModelConsistentExpectationSubstitution(const string &nam for (int k = 1; k <= pac_eq_max_lag; k++) { expr_t ssum = Zero; - for (int j = k+1; j <= pac_eq_max_lag+1; j++) + for (int j = k + 1; j <= pac_eq_max_lag + 1; j++) { int alpha_j_symb_id = -1; string param_name = "mce_alpha_" + name + "_" + to_string(j); @@ -1952,23 +2057,25 @@ DynamicModel::computePacModelConsistentExpectationSubstitution(const string &nam { alpha_j_symb_id = symbol_table.getID(param_name); } - catch (SymbolTable::UnknownSymbolNameException &e) + catch (SymbolTable::UnknownSymbolNameException& e) { alpha_j_symb_id = symbol_table.addSymbol(param_name, SymbolType::parameter); } - ssum = AddPlus(ssum, - AddTimes(AddVariable(alpha_j_symb_id), AddPower(beta, AddPossiblyNegativeConstant(j)))); + ssum = AddPlus(ssum, AddTimes(AddVariable(alpha_j_symb_id), + AddPower(beta, AddPossiblyNegativeConstant(j)))); } fs = AddPlus(fs, AddTimes(ssum, target_aux_var_to_add[k])); } - auto neweq = AddEqual(AddVariable(mce_z1_symb_id), - AddMinus(AddTimes(A, AddMinus(const_cast(target_base_diff_node), fs)), fp)); + auto neweq = AddEqual( + AddVariable(mce_z1_symb_id), + AddMinus(AddTimes(A, AddMinus(const_cast(target_base_diff_node), fs)), fp)); addEquation(neweq, nullopt); /* This equation is not added to the list of auxiliary equations, because it is recursive, and this would in particular break dynamic_set_auxiliary_series.m */ neqs++; - cout << "PAC Model Consistent Expectation: added " << neqs << " auxiliary variables and equations for model " << name << "." << endl; + cout << "PAC Model Consistent Expectation: added " << neqs + << " auxiliary variables and equations for model " << name << "." << endl; /* The growth correction term is not added to the definition of Z₁ because the latter is recursive. Rather put it at the level of the @@ -1977,25 +2084,22 @@ DynamicModel::computePacModelConsistentExpectationSubstitution(const string &nam } void -DynamicModel::computePacBackwardExpectationSubstitution(const string &name, - const vector &lhs, - int max_lag, - const string &aux_model_type, - expr_t growth_correction_term, - string auxname, - map &pac_aux_var_symb_ids, - map> &pac_aux_param_symb_ids, - map &pac_expectation_substitution) +DynamicModel::computePacBackwardExpectationSubstitution( + const string& name, const vector& lhs, int max_lag, const string& aux_model_type, + expr_t growth_correction_term, string auxname, map& pac_aux_var_symb_ids, + map>& pac_aux_param_symb_ids, + map& pac_expectation_substitution) { - auto create_aux_param = [&](const string ¶m_name) - { + auto create_aux_param = [&](const string& param_name) { try { return symbol_table.addSymbol(param_name, SymbolType::parameter); } catch (SymbolTable::AlreadyDeclaredException) { - cerr << "ERROR: the variable/parameter '" << param_name << "' conflicts with some auxiliary parameter that will be generated for the '" << name << "' PAC model. Please rename that parameter." << endl; + cerr << "ERROR: the variable/parameter '" << param_name + << "' conflicts with some auxiliary parameter that will be generated for the '" << name + << "' PAC model. Please rename that parameter." << endl; exit(EXIT_FAILURE); } }; @@ -2012,13 +2116,11 @@ DynamicModel::computePacBackwardExpectationSubstitution(const string &name, for (int i = 1; i < max_lag + 1; i++) for (auto lhsit : lhs) { - int new_param_symb_id = create_aux_param("h_" + name + "_var_" - + symbol_table.getName(lhsit) + int new_param_symb_id = create_aux_param("h_" + name + "_var_" + symbol_table.getName(lhsit) + "_lag_" + to_string(i)); pac_aux_param_symb_ids[name].push_back(new_param_symb_id); - subExpr = AddPlus(subExpr, - AddTimes(AddVariable(new_param_symb_id), - AddVariable(lhsit, -i))); + subExpr + = AddPlus(subExpr, AddTimes(AddVariable(new_param_symb_id), AddVariable(lhsit, -i))); } subExpr = AddPlus(subExpr, growth_correction_term); @@ -2034,30 +2136,30 @@ DynamicModel::computePacBackwardExpectationSubstitution(const string &name, } void -DynamicModel::computePacBackwardExpectationSubstitutionWithComponents(const string &name, - const vector &lhs, - int max_lag, - const string &aux_model_type, - vector &pac_target_components, - map &pac_expectation_substitution) +DynamicModel::computePacBackwardExpectationSubstitutionWithComponents( + const string& name, const vector& lhs, int max_lag, const string& aux_model_type, + vector& pac_target_components, + map& pac_expectation_substitution) { - auto create_aux_param = [&](const string ¶m_name) - { + auto create_aux_param = [&](const string& param_name) { try { return symbol_table.addSymbol(param_name, SymbolType::parameter); } catch (SymbolTable::AlreadyDeclaredException) { - cerr << "ERROR: the variable/parameter '" << param_name << "' conflicts with some auxiliary parameter that will be generated for the '" << name << "' PAC model. Please rename that parameter." << endl; + cerr << "ERROR: the variable/parameter '" << param_name + << "' conflicts with some auxiliary parameter that will be generated for the '" << name + << "' PAC model. Please rename that parameter." << endl; exit(EXIT_FAILURE); } }; expr_t substexpr = Zero; - for (int component_idx{1}; - auto &[component, growth, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth, growth_info] : pac_target_components) + for (int component_idx {1}; + auto& [component, growth, auxname, kind, coeff, growth_neutrality_param, h_indices, + original_growth, growth_info] : pac_target_components) { string name_component = name + "_component" + to_string(component_idx); @@ -2074,16 +2176,19 @@ DynamicModel::computePacBackwardExpectationSubstitutionWithComponents(const stri for (int i = 1; i < max_lag + 1; i++) for (auto lhsit : lhs) { - int new_param_symb_id = create_aux_param("h_" + name_component + "_var_" + symbol_table.getName(lhsit) + "_lag_" + to_string(i)); + int new_param_symb_id + = create_aux_param("h_" + name_component + "_var_" + symbol_table.getName(lhsit) + + "_lag_" + to_string(i)); h_indices.push_back(new_param_symb_id); - auxdef = AddPlus(auxdef, AddTimes(AddVariable(new_param_symb_id), - AddVariable(lhsit, -i))); + auxdef + = AddPlus(auxdef, AddTimes(AddVariable(new_param_symb_id), AddVariable(lhsit, -i))); } // If needed, add the growth neutrality correction for this component if (growth) { - growth_neutrality_param = create_aux_param(name_component + "_pac_growth_neutrality_correction"); + growth_neutrality_param + = create_aux_param(name_component + "_pac_growth_neutrality_correction"); auxdef = AddPlus(auxdef, AddTimes(growth, AddVariable(growth_neutrality_param))); } else @@ -2108,28 +2213,31 @@ DynamicModel::computePacBackwardExpectationSubstitutionWithComponents(const stri } void -DynamicModel::substitutePacExpectation(const map &pac_expectation_substitution, - const map &pac_eq_name) +DynamicModel::substitutePacExpectation(const map& pac_expectation_substitution, + const map& pac_eq_name) { - for (auto &[model_name, substexpr] : pac_expectation_substitution) + for (auto& [model_name, substexpr] : pac_expectation_substitution) { - optional eq { equation_tags.getEqnByTag("name", pac_eq_name.at(model_name)) }; - auto substeq = dynamic_cast(equations[eq.value()]->substitutePacExpectation(model_name, substexpr)); + optional eq {equation_tags.getEqnByTag("name", pac_eq_name.at(model_name))}; + auto substeq = dynamic_cast( + equations[eq.value()]->substitutePacExpectation(model_name, substexpr)); assert(substeq); equations[eq.value()] = substeq; } } void -DynamicModel::substitutePacTargetNonstationary(const string &pac_model_name, expr_t substexpr) +DynamicModel::substitutePacTargetNonstationary(const string& pac_model_name, expr_t substexpr) { - for (auto &eq : equations) - eq = dynamic_cast(eq->substitutePacTargetNonstationary(pac_model_name, substexpr)); + for (auto& eq : equations) + eq = dynamic_cast( + eq->substitutePacTargetNonstationary(pac_model_name, substexpr)); } void -DynamicModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_context_t &eval_context, - bool no_tmp_terms, bool block, bool use_dll) +DynamicModel::computingPass(int derivsOrder, int paramsDerivsOrder, + const eval_context_t& eval_context, bool no_tmp_terms, bool block, + bool use_dll) { initializeVariablesAndEquations(); @@ -2149,18 +2257,19 @@ DynamicModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_c We only do the check for the legacy representation, since the sparse representation is not affected by this problem (TODO: thus the check can be removed once the legacy representation is dropped). */ - if (log2(getJacobianColsNbr(false))*derivsOrder >= numeric_limits::digits) + if (log2(getJacobianColsNbr(false)) * derivsOrder >= numeric_limits::digits) { - cerr << "ERROR: The derivatives matrix of the " << modelClassName() << " is too large. Please decrease the approximation order." << endl; + cerr << "ERROR: The derivatives matrix of the " << modelClassName() + << " is too large. Please decrease the approximation order." << endl; exit(EXIT_FAILURE); } // Compute derivatives w.r. to all endogenous, exogenous and exogenous deterministic set vars; - for (auto &[symb_lag, deriv_id] : deriv_id_table) - if (SymbolType type = symbol_table.getType(symb_lag.first); - type == SymbolType::endogenous || type == SymbolType::exogenous - || type == SymbolType::exogenousDet) + for (auto& [symb_lag, deriv_id] : deriv_id_table) + if (SymbolType type = symbol_table.getType(symb_lag.first); type == SymbolType::endogenous + || type == SymbolType::exogenous + || type == SymbolType::exogenousDet) vars.insert(deriv_id); // Launch computations @@ -2169,12 +2278,13 @@ DynamicModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_c computeDerivatives(derivsOrder, vars); if (derivsOrder > 1) - for (const auto &[indices, d2] : derivatives[2]) + for (const auto& [indices, d2] : derivatives[2]) nonzero_hessian_eqs.insert(indices[0]); if (paramsDerivsOrder > 0) { - cout << "Computing " << modelClassName() << " derivatives w.r.t. parameters (order " << paramsDerivsOrder << ")." << endl; + cout << "Computing " << modelClassName() << " derivatives w.r.t. parameters (order " + << paramsDerivsOrder << ")." << endl; computeParamsDerivatives(paramsDerivsOrder); } @@ -2204,16 +2314,14 @@ DynamicModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_c void DynamicModel::computeXrefs() { - for (int i{0}; - auto &equation : equations) + for (int i {0}; auto& equation : equations) { ExprNode::EquationInfo ei; equation->computeXrefs(ei); xrefs[i++] = ei; } - for (int i{0}; - const auto &[eq, eqinfo] : xrefs) + for (int i {0}; const auto& [eq, eqinfo] : xrefs) { computeRevXref(xref_param, eqinfo.param, i); computeRevXref(xref_endo, eqinfo.endo, i); @@ -2224,9 +2332,10 @@ DynamicModel::computeXrefs() } void -DynamicModel::computeRevXref(map, set> &xrefset, const set> &eiref, int eqn) +DynamicModel::computeRevXref(map, set>& xrefset, + const set>& eiref, int eqn) { - for (const auto &it : eiref) + for (const auto& it : eiref) { set eq; if (xrefset.contains(it)) @@ -2237,33 +2346,35 @@ DynamicModel::computeRevXref(map, set> &xrefset, const set

, set> &xrefmap, const string &type) const +DynamicModel::writeRevXrefs(ostream& output, const map, set>& xrefmap, + const string& type) const { - for (int last_tsid{-1}; - const auto &[key, eqs] : xrefmap) + for (int last_tsid {-1}; const auto& [key, eqs] : xrefmap) { - auto &[id, lag] = key; + auto& [id, lag] = key; int tsid = symbol_table.getTypeSpecificID(id) + 1; output << "M_.xref2." << type << "{" << tsid << "} = [ "; if (last_tsid == tsid) @@ -2297,12 +2408,11 @@ DynamicModel::writeRevXrefs(ostream &output, const map, set> if (type == "param") output << eq + 1 << " "; else - output << "struct('shift', " << lag << ", 'eq', " << eq+1 << ");"; + output << "struct('shift', " << lag << ", 'eq', " << eq + 1 << ");"; output << "];" << endl; } } - map, DynamicModel::BlockDerivativeType> DynamicModel::determineBlockDerivativesType(int blk) { @@ -2310,32 +2420,30 @@ DynamicModel::determineBlockDerivativesType(int blk) int size = blocks[blk].size; int nb_recursive = blocks[blk].getRecursiveSize(); for (int lag {time_recursive_block_decomposition ? 0 : -blocks[blk].max_endo_lag}; - lag <= (time_recursive_block_decomposition ? 0 : blocks[blk].max_endo_lead); - lag++) + lag <= (time_recursive_block_decomposition ? 0 : blocks[blk].max_endo_lead); lag++) for (int eq = 0; eq < size; eq++) { set> endos_and_lags; int eq_orig = getBlockEquationID(blk, eq); equations[eq_orig]->collectEndogenous(endos_and_lags); for (int var = 0; var < size; var++) - if (int var_orig = getBlockVariableID(blk, var); - endos_and_lags.contains({ var_orig, lag })) + if (int var_orig = getBlockVariableID(blk, var); endos_and_lags.contains({var_orig, lag})) { if (getBlockEquationType(blk, eq) == EquationType::evaluateRenormalized && eq < nb_recursive) /* It’s a normalized recursive equation, we have to recompute the derivative using the chain rule */ - derivType[{ lag, eq, var }] = BlockDerivativeType::normalizedChainRule; - else if (!derivType.contains({ lag, eq, var })) - derivType[{ lag, eq, var }] = BlockDerivativeType::standard; + derivType[{lag, eq, var}] = BlockDerivativeType::normalizedChainRule; + else if (!derivType.contains({lag, eq, var})) + derivType[{lag, eq, var}] = BlockDerivativeType::standard; if (var < nb_recursive) for (int feedback_var = nb_recursive; feedback_var < size; feedback_var++) - if (derivType.contains({ lag, var, feedback_var })) + if (derivType.contains({lag, var, feedback_var})) /* A new derivative needs to be computed using the chain rule (a feedback variable appears in the recursive equation defining the current variable) */ - derivType[{ lag, eq, feedback_var }] = BlockDerivativeType::chainRule; + derivType[{lag, eq, feedback_var}] = BlockDerivativeType::chainRule; } } return derivType; @@ -2344,7 +2452,7 @@ DynamicModel::determineBlockDerivativesType(int blk) void DynamicModel::computeChainRuleJacobian() { - size_t nb_blocks { blocks.size() }; + size_t nb_blocks {blocks.size()}; blocks_derivatives.resize(nb_blocks); blocks_jacobian_sparse_column_major_order.resize(nb_blocks); @@ -2353,14 +2461,15 @@ DynamicModel::computeChainRuleJacobian() for (int blk {0}; blk < static_cast(nb_blocks); blk++) { int nb_recursives = blocks[blk].getRecursiveSize(); - int mfs_size { blocks[blk].mfs_size }; - BlockSimulationType simulation_type { blocks[blk].simulation_type }; + int mfs_size {blocks[blk].mfs_size}; + BlockSimulationType simulation_type {blocks[blk].simulation_type}; // Create a map from recursive vars to their defining (normalized) equation - map recursive_vars; + map recursive_vars; for (int i = 0; i < nb_recursives; i++) { - int deriv_id = getDerivID(symbol_table.getID(SymbolType::endogenous, getBlockVariableID(blk, i)), 0); + int deriv_id = getDerivID( + symbol_table.getID(SymbolType::endogenous, getBlockVariableID(blk, i)), 0); if (getBlockEquationType(blk, i) == EquationType::evaluateRenormalized) recursive_vars[deriv_id] = getBlockEquationRenormalizedExpr(blk, i); else @@ -2370,31 +2479,34 @@ DynamicModel::computeChainRuleJacobian() // Compute the block derivatives unordered_map> non_null_chain_rule_derivatives; unordered_map> chain_rule_deriv_cache; - for (const auto &[indices, derivType] : determineBlockDerivativesType(blk)) + for (const auto& [indices, derivType] : determineBlockDerivativesType(blk)) { auto [lag, eq, var] = indices; int eq_orig = getBlockEquationID(blk, eq), var_orig = getBlockVariableID(blk, var); int deriv_id = getDerivID(symbol_table.getID(SymbolType::endogenous, var_orig), lag); - expr_t d{nullptr}; + expr_t d {nullptr}; switch (derivType) { case BlockDerivativeType::standard: - if (auto it = derivatives[1].find({ eq_orig, deriv_id }); - it != derivatives[1].end()) + if (auto it = derivatives[1].find({eq_orig, deriv_id}); it != derivatives[1].end()) d = it->second; else d = Zero; break; case BlockDerivativeType::chainRule: - d = equations[eq_orig]->getChainRuleDerivative(deriv_id, recursive_vars, non_null_chain_rule_derivatives, chain_rule_deriv_cache); + d = equations[eq_orig]->getChainRuleDerivative(deriv_id, recursive_vars, + non_null_chain_rule_derivatives, + chain_rule_deriv_cache); break; case BlockDerivativeType::normalizedChainRule: - d = equation_type_and_normalized_equation[eq_orig].second->getChainRuleDerivative(deriv_id, recursive_vars, non_null_chain_rule_derivatives, chain_rule_deriv_cache); + d = equation_type_and_normalized_equation[eq_orig].second->getChainRuleDerivative( + deriv_id, recursive_vars, non_null_chain_rule_derivatives, + chain_rule_deriv_cache); break; } if (d != Zero && eq >= nb_recursives) - blocks_derivatives[blk][{ eq, var, lag }] = d; + blocks_derivatives[blk][{eq, var, lag}] = d; } // Compute the sparse representation of the Jacobian @@ -2405,14 +2517,18 @@ DynamicModel::computeChainRuleJacobian() || simulation_type == BlockSimulationType::solveForwardSimple || simulation_type == BlockSimulationType::solveBackwardComplete || simulation_type == BlockSimulationType::solveForwardComplete}; - for (const auto &[indices, d1] : blocks_derivatives[blk]) + for (const auto& [indices, d1] : blocks_derivatives[blk]) { - auto &[eq, var, lag] { indices }; + auto& [eq, var, lag] {indices}; assert(lag >= -1 && lag <= 1 && eq >= nb_recursives); if (var >= nb_recursives && !(one_boundary && lag != 0)) - blocks_jacobian_sparse_column_major_order[blk].try_emplace({eq-nb_recursives, var-nb_recursives+static_cast(!one_boundary)*(lag+1)*mfs_size}, d1); + blocks_jacobian_sparse_column_major_order[blk].try_emplace( + {eq - nb_recursives, + var - nb_recursives + static_cast(!one_boundary) * (lag + 1) * mfs_size}, + d1); } - blocks_jacobian_sparse_colptr[blk] = computeCSCColPtr(blocks_jacobian_sparse_column_major_order[blk], (one_boundary ? 1 : 3)*mfs_size); + blocks_jacobian_sparse_colptr[blk] = computeCSCColPtr( + blocks_jacobian_sparse_column_major_order[blk], (one_boundary ? 1 : 3) * mfs_size); } } } @@ -2420,33 +2536,32 @@ DynamicModel::computeChainRuleJacobian() void DynamicModel::computeBlockDynJacobianCols() { - size_t nb_blocks { blocks.size() }; + size_t nb_blocks {blocks.size()}; // Structure used for lexicographic ordering over (lag, var ID) vector>> dynamic_endo(nb_blocks); - for (auto & [indices, d1] : derivatives[1]) + for (auto& [indices, d1] : derivatives[1]) { - auto [eq_orig, deriv_id] { vectorToTuple<2>(indices) }; - int block_eq { eq2block[eq_orig] }; - int var { getTypeSpecificIDByDerivID(deriv_id) }; - int lag { getLagByDerivID(deriv_id) }; - if (getTypeByDerivID(deriv_id) == SymbolType::endogenous - && block_eq == endo2block[var]) + auto [eq_orig, deriv_id] {vectorToTuple<2>(indices)}; + int block_eq {eq2block[eq_orig]}; + int var {getTypeSpecificIDByDerivID(deriv_id)}; + int lag {getLagByDerivID(deriv_id)}; + if (getTypeByDerivID(deriv_id) == SymbolType::endogenous && block_eq == endo2block[var]) dynamic_endo[block_eq].emplace(lag, getBlockInitialVariableID(block_eq, var)); } // Compute Jacobian column indices blocks_jacob_cols_endo.resize(nb_blocks); for (size_t blk {0}; blk < nb_blocks; blk++) - for (int index{0}; - auto [lag, var] : dynamic_endo[blk]) - blocks_jacob_cols_endo[blk][{ var, lag }] = index++; + for (int index {0}; auto [lag, var] : dynamic_endo[blk]) + blocks_jacob_cols_endo[blk][{var, lag}] = index++; } void -DynamicModel::writeDynamicFile(const string &basename, bool use_dll, const string &mexext, const filesystem::path &matlabroot, bool julia) const +DynamicModel::writeDynamicFile(const string& basename, bool use_dll, const string& mexext, + const filesystem::path& matlabroot, bool julia) const { - filesystem::path model_dir{basename}; + filesystem::path model_dir {basename}; model_dir /= "model"; if (use_dll) { @@ -2511,7 +2626,7 @@ DynamicModel::clearEquations() } void -DynamicModel::replaceMyEquations(DynamicModel &dynamic_model) const +DynamicModel::replaceMyEquations(DynamicModel& dynamic_model) const { dynamic_model.clearEquations(); @@ -2522,7 +2637,7 @@ DynamicModel::replaceMyEquations(DynamicModel &dynamic_model) const } int -DynamicModel::computeRamseyPolicyFOCs(const StaticModel &static_model) +DynamicModel::computeRamseyPolicyFOCs(const StaticModel& static_model) { cout << "Ramsey Problem: added " << equations.size() << " multipliers." << endl; @@ -2530,7 +2645,7 @@ DynamicModel::computeRamseyPolicyFOCs(const StaticModel &static_model) // equation[i]->lhs = rhs becomes equation[i]->MULT_(i+1)*(lhs-rhs) = 0 for (int i {0}; i < static_cast(equations.size()); i++) { - auto substeq = dynamic_cast(equations[i]->addMultipliersToConstraints(i)); + auto substeq = dynamic_cast(equations[i]->addMultipliersToConstraints(i)); assert(substeq); equations[i] = substeq; } @@ -2543,10 +2658,10 @@ DynamicModel::computeRamseyPolicyFOCs(const StaticModel &static_model) set> dynvars; int max_eq_lead = 0; int max_eq_lag = 0; - for (auto &equation : equations) + for (auto& equation : equations) equation->collectDynamicVariables(SymbolType::endogenous, dynvars); - for (const auto &[symb_id, lag] : dynvars) + for (const auto& [symb_id, lag] : dynvars) { max_eq_lead = max(lag, max_eq_lead); max_eq_lag = max(-lag, max_eq_lag); @@ -2573,8 +2688,10 @@ DynamicModel::computeRamseyPolicyFOCs(const StaticModel &static_model) else dfpower = AddMinus(Zero, AddNonNegativeConstant(lagstream.str())); - lagrangian = AddPlus(AddTimes(AddPower(discount_factor_node, dfpower), - equations[i]->getNonZeroPartofEquation()->decreaseLeadsLags(lag)), lagrangian); + lagrangian + = AddPlus(AddTimes(AddPower(discount_factor_node, dfpower), + equations[i]->getNonZeroPartofEquation()->decreaseLeadsLags(lag)), + lagrangian); } // Save line numbers and tags, see below @@ -2597,18 +2714,18 @@ DynamicModel::computeRamseyPolicyFOCs(const StaticModel &static_model) vector> neweqs_lineno; map> neweqs_tags; int orig_endo_nbr {0}; - for (auto &[symb_id_and_lag, deriv_id] : deriv_id_table) + for (auto& [symb_id_and_lag, deriv_id] : deriv_id_table) { - auto &[symb_id, lag] = symb_id_and_lag; + auto& [symb_id, lag] = symb_id_and_lag; if (symbol_table.getType(symb_id) == SymbolType::endogenous && lag == 0) { - neweqs.push_back(AddEqual(equations[0]->getNonZeroPartofEquation()->getDerivative(deriv_id), Zero)); - if (optional i = symbol_table.getEquationNumberForMultiplier(symb_id); - i) + neweqs.push_back( + AddEqual(equations[0]->getNonZeroPartofEquation()->getDerivative(deriv_id), Zero)); + if (optional i = symbol_table.getEquationNumberForMultiplier(symb_id); i) { // This is a derivative w.r.t. a Lagrange multiplier neweqs_lineno.push_back(old_equations_lineno[*i]); - neweqs_tags[neweqs.size()-1] = old_equation_tags.getTagsByEqn(*i); + neweqs_tags[neweqs.size() - 1] = old_equation_tags.getTagsByEqn(*i); } else { @@ -2652,15 +2769,16 @@ DynamicModel::expandEqTags() for (int eq = 0; eq < static_cast(equations.size()); eq++) if (!existing_tags.contains(eq)) { - if (auto lhs_expr = dynamic_cast(equations[eq]->arg1); - lhs_expr - && !equation_tags.exists("name", symbol_table.getName(lhs_expr->symb_id))) + if (auto lhs_expr = dynamic_cast(equations[eq]->arg1); + lhs_expr && !equation_tags.exists("name", symbol_table.getName(lhs_expr->symb_id))) equation_tags.add(eq, "name", symbol_table.getName(lhs_expr->symb_id)); - else if (!equation_tags.exists("name", to_string(eq+1))) - equation_tags.add(eq, "name", to_string(eq+1)); + else if (!equation_tags.exists("name", to_string(eq + 1))) + equation_tags.add(eq, "name", to_string(eq + 1)); else { - cerr << "Error creating default equation tag: cannot assign default tag to equation number " << eq+1 << " because it is already in use" << endl; + cerr << "Error creating default equation tag: cannot assign default tag to equation " + "number " + << eq + 1 << " because it is already in use" << endl; exit(EXIT_FAILURE); } } @@ -2670,13 +2788,12 @@ set DynamicModel::findUnusedEndogenous() { set usedEndo, unusedEndo; - for (auto &equation : equations) + for (auto& equation : equations) equation->collectVariables(SymbolType::endogenous, usedEndo); - for (auto &equation : static_only_equations) + for (auto& equation : static_only_equations) equation->collectVariables(SymbolType::endogenous, usedEndo); set allEndo = symbol_table.getEndogenous(); - set_difference(allEndo.begin(), allEndo.end(), - usedEndo.begin(), usedEndo.end(), + set_difference(allEndo.begin(), allEndo.end(), usedEndo.begin(), usedEndo.end(), inserter(unusedEndo, unusedEndo.begin())); return unusedEndo; } @@ -2685,17 +2802,15 @@ set DynamicModel::findUnusedExogenous() { set usedExo, unusedExo, unobservedExo; - for (auto &equation : equations) + for (auto& equation : equations) equation->collectVariables(SymbolType::exogenous, usedExo); - for (auto &equation : static_only_equations) + for (auto& equation : static_only_equations) equation->collectVariables(SymbolType::exogenous, usedExo); set observedExo = symbol_table.getObservedExogenous(); set allExo = symbol_table.getExogenous(); - set_difference(allExo.begin(), allExo.end(), - observedExo.begin(), observedExo.end(), + set_difference(allExo.begin(), allExo.end(), observedExo.begin(), observedExo.end(), inserter(unobservedExo, unobservedExo.begin())); - set_difference(unobservedExo.begin(), unobservedExo.end(), - usedExo.begin(), usedExo.end(), + set_difference(unobservedExo.begin(), unobservedExo.end(), usedExo.begin(), usedExo.end(), inserter(unusedExo, unusedExo.begin())); return unusedExo; } @@ -2705,17 +2820,17 @@ DynamicModel::setLeadsLagsOrig() { set> dynvars; - for (auto &equation : equations) + for (auto& equation : equations) { equation->collectDynamicVariables(SymbolType::endogenous, dynvars); equation->collectDynamicVariables(SymbolType::exogenous, dynvars); equation->collectDynamicVariables(SymbolType::exogenousDet, dynvars); - max_lag_with_diffs_expanded_orig = max(equation->maxLagWithDiffsExpanded(), - max_lag_with_diffs_expanded_orig); + max_lag_with_diffs_expanded_orig + = max(equation->maxLagWithDiffsExpanded(), max_lag_with_diffs_expanded_orig); } - for (const auto &[symb_id, lag] : dynvars) + for (const auto& [symb_id, lag] : dynvars) { SymbolType type = symbol_table.getType(symb_id); @@ -2747,7 +2862,7 @@ DynamicModel::computeDerivIDs() { set> dynvars; - for (auto &equation : equations) + for (auto& equation : equations) { equation->collectDynamicVariables(SymbolType::endogenous, dynvars); equation->collectDynamicVariables(SymbolType::exogenous, dynvars); @@ -2757,7 +2872,7 @@ DynamicModel::computeDerivIDs() equation->collectDynamicVariables(SymbolType::logTrend, dynvars); } - for (const auto &[symb_id, lag] : dynvars) + for (const auto& [symb_id, lag] : dynvars) { SymbolType type = symbol_table.getType(symb_id); @@ -2831,15 +2946,14 @@ DynamicModel::getTypeSpecificIDByDerivID(int deriv_id) const int DynamicModel::getDerivID(int symb_id, int lag) const noexcept(false) { - if (auto it = deriv_id_table.find({ symb_id, lag }); - it == deriv_id_table.end()) + if (auto it = deriv_id_table.find({symb_id, lag}); it == deriv_id_table.end()) throw UnknownDerivIDException(); else return it->second; } void -DynamicModel::addAllParamDerivId(set &deriv_id_set) +DynamicModel::addAllParamDerivId(set& deriv_id_set) { for (size_t i = 0; i < inv_deriv_id_table.size(); i++) if (symbol_table.getType(inv_deriv_id_table[i].first) == SymbolType::parameter) @@ -2849,26 +2963,25 @@ DynamicModel::addAllParamDerivId(set &deriv_id_set) void DynamicModel::computeDynJacobianCols() { - // Sort the dynamic endogenous variables by lexicographic order over (lag, type_specific_symbol_id) + // Sort the dynamic endogenous variables by lexicographic order over (lag, + // type_specific_symbol_id) map, int> ordered_dyn_endo; - for (const auto &[symb_lag, deriv_id] : deriv_id_table) - if (const auto &[symb_id, lag] = symb_lag; + for (const auto& [symb_lag, deriv_id] : deriv_id_table) + if (const auto& [symb_id, lag] = symb_lag; symbol_table.getType(symb_id) == SymbolType::endogenous) - ordered_dyn_endo[{ lag, symbol_table.getTypeSpecificID(symb_id) }] = deriv_id; + ordered_dyn_endo[{lag, symbol_table.getTypeSpecificID(symb_id)}] = deriv_id; // Fill the dynamic jacobian columns for endogenous (legacy representation) - for (int sorted_id{0}; - const auto &[ignore, deriv_id] : ordered_dyn_endo) + for (int sorted_id {0}; const auto& [ignore, deriv_id] : ordered_dyn_endo) dyn_jacobian_cols_table[deriv_id] = sorted_id++; /* Fill the dynamic columns for exogenous and exogenous deterministic (legacy representation) */ - for (const auto &[symb_lag, deriv_id] : deriv_id_table) + for (const auto& [symb_lag, deriv_id] : deriv_id_table) { - int symb_id{symb_lag.first}; - int tsid{symbol_table.getTypeSpecificID(symb_id)}; // At this point, there is no trend_var - if (SymbolType type{symbol_table.getType(symb_id)}; - type == SymbolType::exogenous) + int symb_id {symb_lag.first}; + int tsid {symbol_table.getTypeSpecificID(symb_id)}; // At this point, there is no trend_var + if (SymbolType type {symbol_table.getType(symb_id)}; type == SymbolType::exogenous) dyn_jacobian_cols_table[deriv_id] = ordered_dyn_endo.size() + tsid; else if (type == SymbolType::exogenousDet) dyn_jacobian_cols_table[deriv_id] = ordered_dyn_endo.size() + symbol_table.exo_nbr() + tsid; @@ -2876,40 +2989,46 @@ DynamicModel::computeDynJacobianCols() /* NB: the following could differ from dyn_jacobian_cols_table.size() if there are unused exogenous (and “nostrict” option is given) */ - dyn_jacobian_ncols = ordered_dyn_endo.size() + symbol_table.exo_nbr() + symbol_table.exo_det_nbr(); + dyn_jacobian_ncols + = ordered_dyn_endo.size() + symbol_table.exo_nbr() + symbol_table.exo_det_nbr(); } void -DynamicModel::testTrendDerivativesEqualToZero(const eval_context_t &eval_context) +DynamicModel::testTrendDerivativesEqualToZero(const eval_context_t& eval_context) { - for (auto &[symb_lag1, deriv_id1] : deriv_id_table) - if (auto &[symb_id1, lag1] = symb_lag1; + for (auto& [symb_lag1, deriv_id1] : deriv_id_table) + if (auto& [symb_id1, lag1] = symb_lag1; symbol_table.getType(symb_id1) == SymbolType::trend || symbol_table.getType(symb_id1) == SymbolType::logTrend) for (int eq = 0; eq < static_cast(equations.size()); eq++) { - expr_t homogeneq = AddMinus(equations[eq]->arg1, - equations[eq]->arg2); + expr_t homogeneq = AddMinus(equations[eq]->arg1, equations[eq]->arg2); // Do not run the test if the term inside the log is zero if (fabs(homogeneq->eval(eval_context)) > zero_band) { - expr_t testeq = AddLog(homogeneq); // F = log(lhs-rhs) + expr_t testeq = AddLog(homogeneq); // F = log(lhs-rhs) testeq = testeq->getDerivative(deriv_id1); // d F / d Trend - for (auto &[symb_lag2, deriv_id2] : deriv_id_table) - if (auto &[symb_id2, lag2] = symb_lag2; + for (auto& [symb_lag2, deriv_id2] : deriv_id_table) + if (auto& [symb_id2, lag2] = symb_lag2; symbol_table.getType(symb_id2) == SymbolType::endogenous) { - double nearZero = testeq->getDerivative(deriv_id2)->eval(eval_context); // eval d F / d Trend d Endog + double nearZero = testeq->getDerivative(deriv_id2)->eval( + eval_context); // eval d F / d Trend d Endog if (fabs(nearZero) > balanced_growth_test_tol) { - cerr << "ERROR: trends not compatible with balanced growth path; the second-order cross partial of equation " << eq + 1; + cerr << "ERROR: trends not compatible with balanced growth path; the " + "second-order cross partial of equation " + << eq + 1; if (equations_lineno[eq]) cerr << " (line " << *equations_lineno[eq] << ") "; - cerr << "w.r.t. trend variable " - << symbol_table.getName(symb_id1) << " and endogenous variable " - << symbol_table.getName(symb_id2) << " is not null (abs. value = " - << fabs(nearZero) << "). If you are confident that your trends are correctly specified, you can raise the value of option 'balanced_growth_test_tol' in the 'model' block." << endl; + cerr << "w.r.t. trend variable " << symbol_table.getName(symb_id1) + << " and endogenous variable " << symbol_table.getName(symb_id2) + << " is not null (abs. value = " << fabs(nearZero) + << "). If you are confident that your trends are correctly specified, " + "you can raise the value of option 'balanced_growth_test_tol' in " + "the 'model' block." + << endl; exit(EXIT_FAILURE); } } @@ -2918,15 +3037,17 @@ DynamicModel::testTrendDerivativesEqualToZero(const eval_context_t &eval_context } void -DynamicModel::writeLatexFile(const string &basename, bool write_equation_tags) const +DynamicModel::writeLatexFile(const string& basename, bool write_equation_tags) const { - writeLatexModelFile(basename, "dynamic", ExprNodeOutputType::latexDynamicModel, write_equation_tags); + writeLatexModelFile(basename, "dynamic", ExprNodeOutputType::latexDynamicModel, + write_equation_tags); } void -DynamicModel::writeLatexOriginalFile(const string &basename, bool write_equation_tags) const +DynamicModel::writeLatexOriginalFile(const string& basename, bool write_equation_tags) const { - writeLatexModelFile(basename, "original", ExprNodeOutputType::latexDynamicModel, write_equation_tags); + writeLatexModelFile(basename, "original", ExprNodeOutputType::latexDynamicModel, + write_equation_tags); } void @@ -2954,14 +3075,15 @@ DynamicModel::substituteExoLag(bool deterministic_model) } void -DynamicModel::substituteLeadLagInternal(AuxVarType type, bool deterministic_model, const vector &subset) +DynamicModel::substituteLeadLagInternal(AuxVarType type, bool deterministic_model, + const vector& subset) { ExprNode::subst_table_t subst_table; - vector neweqs; + vector neweqs; // Substitute in used model local variables set used_local_vars; - for (auto &equation : equations) + for (auto& equation : equations) equation->collectVariables(SymbolType::modelLocalVariable, used_local_vars); for (int used_local_var : used_local_vars) @@ -2993,13 +3115,14 @@ DynamicModel::substituteLeadLagInternal(AuxVarType type, bool deterministic_mode } // Substitute in equations - for (auto &equation : equations) + for (auto& equation : equations) { expr_t subst; switch (type) { case AuxVarType::endoLead: - subst = equation->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); + subst = equation->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, + deterministic_model); break; case AuxVarType::endoLag: subst = equation->substituteEndoLagGreaterThanTwo(subst_table, neweqs); @@ -3017,13 +3140,13 @@ DynamicModel::substituteLeadLagInternal(AuxVarType type, bool deterministic_mode cerr << "DynamicModel::substituteLeadLagInternal: impossible case" << endl; exit(EXIT_FAILURE); } - auto substeq = dynamic_cast(subst); + auto substeq = dynamic_cast(subst); assert(substeq); equation = substeq; } // Add new equations - for (auto &neweq : neweqs) + for (auto& neweq : neweqs) { addEquation(neweq, nullopt); addAuxEquation(neweq); @@ -3067,24 +3190,24 @@ DynamicModel::substituteAdl() definitions here, instead of doing it at the ExprNode method level, because otherwise this would substitute MLV in the original model (see #65). */ - for (auto &[id, definition] : local_variables_table) + for (auto& [id, definition] : local_variables_table) definition = definition->substituteAdl(); - for (auto &equation : equations) - equation = dynamic_cast(equation->substituteAdl()); + for (auto& equation : equations) + equation = dynamic_cast(equation->substituteAdl()); - for (auto &equation : static_only_equations) - equation = dynamic_cast(equation->substituteAdl()); + for (auto& equation : static_only_equations) + equation = dynamic_cast(equation->substituteAdl()); } void DynamicModel::substituteModelLocalVariables() { - for (auto &equation : equations) - equation = dynamic_cast(equation->substituteModelLocalVariables()); + for (auto& equation : equations) + equation = dynamic_cast(equation->substituteModelLocalVariables()); - for (auto &equation : static_only_equations) - equation = dynamic_cast(equation->substituteModelLocalVariables()); + for (auto& equation : static_only_equations) + equation = dynamic_cast(equation->substituteModelLocalVariables()); /* We can’t clear local_variables_table at this point, because in case of ramsey_policy, the original model is saved via DynamicModel::operator=() @@ -3095,10 +3218,10 @@ DynamicModel::substituteModelLocalVariables() } set -DynamicModel::getEquationNumbersFromTags(const set &eqtags) const +DynamicModel::getEquationNumbersFromTags(const set& eqtags) const { set eqnumbers; - for (auto &eqtag : eqtags) + for (auto& eqtag : eqtags) { set tmp = equation_tags.getEqnsByTag("name", eqtag); if (tmp.empty()) @@ -3115,8 +3238,7 @@ set DynamicModel::findPacExpectationEquationNumbers() const { set eqnumbers; - for (int i{0}; - auto &equation : equations) + for (int i {0}; auto& equation : equations) { if (equation->containsPacExpectation()) eqnumbers.insert(i); @@ -3126,15 +3248,19 @@ DynamicModel::findPacExpectationEquationNumbers() const } pair -DynamicModel::substituteUnaryOps(VarExpectationModelTable &var_expectation_model_table, PacModelTable &pac_model_table) +DynamicModel::substituteUnaryOps(VarExpectationModelTable& var_expectation_model_table, + PacModelTable& pac_model_table) { vector eqnumbers(equations.size()); iota(eqnumbers.begin(), eqnumbers.end(), 0); - return substituteUnaryOps({ eqnumbers.begin(), eqnumbers.end() }, var_expectation_model_table, pac_model_table); + return substituteUnaryOps({eqnumbers.begin(), eqnumbers.end()}, var_expectation_model_table, + pac_model_table); } pair -DynamicModel::substituteUnaryOps(const set &eqnumbers, VarExpectationModelTable &var_expectation_model_table, PacModelTable &pac_model_table) +DynamicModel::substituteUnaryOps(const set& eqnumbers, + VarExpectationModelTable& var_expectation_model_table, + PacModelTable& pac_model_table) { lag_equivalence_table_t nodes; ExprNode::subst_table_t subst_table; @@ -3151,15 +3277,16 @@ DynamicModel::substituteUnaryOps(const set &eqnumbers, VarExpectationModelT equations[eqnumber]->findUnaryOpNodesForAuxVarCreation(nodes); // Substitute in model local variables - vector neweqs; + vector neweqs; for (int mlv : used_local_vars) - local_variables_table[mlv] = local_variables_table[mlv]->substituteUnaryOpNodes(nodes, subst_table, neweqs); + local_variables_table[mlv] + = local_variables_table[mlv]->substituteUnaryOpNodes(nodes, subst_table, neweqs); // Substitute in equations for (int eq : eqnumbers) { - auto substeq = dynamic_cast(equations[eq]-> - substituteUnaryOpNodes(nodes, subst_table, neweqs)); + auto substeq = dynamic_cast( + equations[eq]->substituteUnaryOpNodes(nodes, subst_table, neweqs)); assert(substeq); equations[eq] = substeq; } @@ -3170,20 +3297,22 @@ DynamicModel::substituteUnaryOps(const set &eqnumbers, VarExpectationModelT pac_model_table.substituteUnaryOpsInGrowth(nodes, subst_table, neweqs); // Add new equations - for (auto &neweq : neweqs) + for (auto& neweq : neweqs) { addEquation(neweq, nullopt); addAuxEquation(neweq); } if (subst_table.size() > 0) - cout << "Substitution of Unary Ops: added " << neweqs.size() << " auxiliary variables and equations." << endl; + cout << "Substitution of Unary Ops: added " << neweqs.size() + << " auxiliary variables and equations." << endl; - return { nodes, subst_table }; + return {nodes, subst_table}; } pair -DynamicModel::substituteDiff(VarExpectationModelTable &var_expectation_model_table, PacModelTable &pac_model_table) +DynamicModel::substituteDiff(VarExpectationModelTable& var_expectation_model_table, + PacModelTable& pac_model_table) { /* Note: at this point, we know that there is no diff operator with a lead, because they have been expanded by DataTree::AddDiff(). @@ -3197,7 +3326,7 @@ DynamicModel::substituteDiff(VarExpectationModelTable &var_expectation_model_tab set used_local_vars; for (auto equation : equations) equation->collectVariables(SymbolType::modelLocalVariable, used_local_vars); - for (auto &[symb_id, expr] : local_variables_table) + for (auto& [symb_id, expr] : local_variables_table) if (used_local_vars.contains(symb_id)) expr->findDiffNodes(diff_nodes); @@ -3208,15 +3337,15 @@ DynamicModel::substituteDiff(VarExpectationModelTable &var_expectation_model_tab pac_model_table.findDiffNodesInGrowth(diff_nodes); // Substitute in model local variables - vector neweqs; - for (auto &[symb_id, expr] : local_variables_table) + vector neweqs; + for (auto& [symb_id, expr] : local_variables_table) expr = expr->substituteDiff(diff_nodes, diff_subst_table, neweqs); // Substitute in equations - for (auto &equation : equations) + for (auto& equation : equations) { - auto substeq = dynamic_cast(equation-> - substituteDiff(diff_nodes, diff_subst_table, neweqs)); + auto substeq = dynamic_cast( + equation->substituteDiff(diff_nodes, diff_subst_table, neweqs)); assert(substeq); equation = substeq; } @@ -3232,25 +3361,27 @@ DynamicModel::substituteDiff(VarExpectationModelTable &var_expectation_model_tab } if (diff_subst_table.size() > 0) - cout << "Substitution of Diff operator: added " << neweqs.size() << " auxiliary variables and equations." << endl; + cout << "Substitution of Diff operator: added " << neweqs.size() + << " auxiliary variables and equations." << endl; - return { diff_nodes, diff_subst_table }; + return {diff_nodes, diff_subst_table}; } void DynamicModel::substituteExpectation(bool partial_information_model) { ExprNode::subst_table_t subst_table; - vector neweqs; + vector neweqs; // Substitute in model local variables - for (auto &[symb_id, expr] : local_variables_table) + for (auto& [symb_id, expr] : local_variables_table) expr = expr->substituteExpectation(subst_table, neweqs, partial_information_model); // Substitute in equations - for (auto &equation : equations) + for (auto& equation : equations) { - equation = dynamic_cast(equation->substituteExpectation(subst_table, neweqs, partial_information_model)); + equation = dynamic_cast( + equation->substituteExpectation(subst_table, neweqs, partial_information_model)); assert(equation); } @@ -3267,21 +3398,23 @@ DynamicModel::substituteExpectation(bool partial_information_model) if (subst_table.size() > 0) { if (partial_information_model) - cout << "Substitution of Expectation operator: added " << subst_table.size() << " auxiliary variables and " << neweqs.size() << " auxiliary equations." << endl; + cout << "Substitution of Expectation operator: added " << subst_table.size() + << " auxiliary variables and " << neweqs.size() << " auxiliary equations." << endl; else - cout << "Substitution of Expectation operator: added " << neweqs.size() << " auxiliary variables and equations." << endl; + cout << "Substitution of Expectation operator: added " << neweqs.size() + << " auxiliary variables and equations." << endl; } } void DynamicModel::transformPredeterminedVariables() { - for (auto &[id, definition] : local_variables_table) + for (auto& [id, definition] : local_variables_table) definition = definition->decreaseLeadsLagsPredeterminedVariables(); - for (auto &equation : equations) + for (auto& equation : equations) { - equation = dynamic_cast(equation->decreaseLeadsLagsPredeterminedVariables()); + equation = dynamic_cast(equation->decreaseLeadsLagsPredeterminedVariables()); assert(equation); } @@ -3296,14 +3429,16 @@ DynamicModel::substituteLogTransform() expr_t aux_def = AddLog(AddVariable(symb_id)); int aux_symb_id = symbol_table.addLogTransformAuxiliaryVar(symb_id, 0, aux_def); - for (auto &[id, definition] : local_variables_table) + for (auto& [id, definition] : local_variables_table) definition = definition->substituteLogTransform(symb_id, aux_symb_id); - for (auto &equation : equations) - equation = dynamic_cast(equation->substituteLogTransform(symb_id, aux_symb_id)); + for (auto& equation : equations) + equation + = dynamic_cast(equation->substituteLogTransform(symb_id, aux_symb_id)); - for (auto &equation : static_only_equations) - equation = dynamic_cast(equation->substituteLogTransform(symb_id, aux_symb_id)); + for (auto& equation : static_only_equations) + equation + = dynamic_cast(equation->substituteLogTransform(symb_id, aux_symb_id)); /* We add the following new equations: @@ -3319,27 +3454,26 @@ DynamicModel::substituteLogTransform() block of type “evaluate”, or maybe even the epilogue) */ addAuxEquation(AddEqual(AddVariable(aux_symb_id), aux_def)); - addEquation(AddEqual(AddVariable(symb_id), AddExp(AddVariable(aux_symb_id))), - nullopt, {}); + addEquation(AddEqual(AddVariable(symb_id), AddExp(AddVariable(aux_symb_id))), nullopt, {}); } } void -DynamicModel::checkNoWithLogTransform(const set &eqnumbers) +DynamicModel::checkNoWithLogTransform(const set& eqnumbers) { set endos; for (int eq : eqnumbers) equations[eq]->collectVariables(SymbolType::endogenous, endos); - const set &with_log_transform = symbol_table.getVariablesWithLogTransform(); + const set& with_log_transform = symbol_table.getVariablesWithLogTransform(); vector intersect; - set_intersection(endos.begin(), endos.end(), - with_log_transform.begin(), with_log_transform.end(), + set_intersection(endos.begin(), endos.end(), with_log_transform.begin(), with_log_transform.end(), back_inserter(intersect)); if (!intersect.empty()) { - cerr << "ERROR: the following variables are declared with var(log) and therefore cannot appear in a VAR/TCM/PAC equation: "; + cerr << "ERROR: the following variables are declared with var(log) and therefore cannot " + "appear in a VAR/TCM/PAC equation: "; for (int symb_id : intersect) cerr << symbol_table.getName(symb_id) << " "; cerr << endl; @@ -3351,29 +3485,30 @@ void DynamicModel::detrendEquations() { // We go backwards in the list of trend_vars, to deal correctly with I(2) processes - for (auto it = nonstationary_symbols_map.crbegin(); - it != nonstationary_symbols_map.crend(); ++it) + for (auto it = nonstationary_symbols_map.crbegin(); it != nonstationary_symbols_map.crend(); ++it) { - for (auto &equation : equations) + for (auto& equation : equations) { - equation = dynamic_cast(equation->detrend(it->first, it->second.first, it->second.second)); + equation = dynamic_cast( + equation->detrend(it->first, it->second.first, it->second.second)); assert(equation); } - for (auto &equation : static_only_equations) + for (auto& equation : static_only_equations) { - equation = dynamic_cast(equation->detrend(it->first, it->second.first, it->second.second)); + equation = dynamic_cast( + equation->detrend(it->first, it->second.first, it->second.second)); assert(equation); } } - for (auto &equation : equations) + for (auto& equation : equations) { - equation = dynamic_cast(equation->removeTrendLeadLag(trend_symbols_map)); + equation = dynamic_cast(equation->removeTrendLeadLag(trend_symbols_map)); assert(equation); } - for (auto &equation : static_only_equations) + for (auto& equation : static_only_equations) { - equation = dynamic_cast(equation->removeTrendLeadLag(trend_symbols_map)); + equation = dynamic_cast(equation->removeTrendLeadLag(trend_symbols_map)); assert(equation); } } @@ -3381,67 +3516,67 @@ DynamicModel::detrendEquations() void DynamicModel::removeTrendVariableFromEquations() { - for (auto &equation : equations) + for (auto& equation : equations) { - equation = dynamic_cast(equation->replaceTrendVar()); + equation = dynamic_cast(equation->replaceTrendVar()); assert(equation); } - for (auto &equation : static_only_equations) + for (auto& equation : static_only_equations) { - equation = dynamic_cast(equation->replaceTrendVar()); + equation = dynamic_cast(equation->replaceTrendVar()); assert(equation); } } void -DynamicModel::differentiateForwardVars(const vector &subset) +DynamicModel::differentiateForwardVars(const vector& subset) { substituteLeadLagInternal(AuxVarType::diffForward, true, subset); } void -DynamicModel::fillEvalContext(eval_context_t &eval_context) const +DynamicModel::fillEvalContext(eval_context_t& eval_context) const { // First, auxiliary variables for (auto aux_equation : aux_equations) { assert(aux_equation->op_code == BinaryOpcode::equal); - auto auxvar = dynamic_cast(aux_equation->arg1); + auto auxvar = dynamic_cast(aux_equation->arg1); assert(auxvar); try { double val = aux_equation->arg2->eval(eval_context); eval_context[auxvar->symb_id] = val; } - catch (ExprNode::EvalException &e) + catch (ExprNode::EvalException& e) { // Do nothing } } // Second, model local variables - for (auto &[symb_id, expression] : local_variables_table) + for (auto& [symb_id, expression] : local_variables_table) { try { double val = expression->eval(eval_context); eval_context[symb_id] = val; } - catch (ExprNode::EvalException &e) + catch (ExprNode::EvalException& e) { // Do nothing } } - //Third, trend variables + // Third, trend variables for (int trendVar : symbol_table.getTrendVarIds()) - eval_context[trendVar] = 2; //not <= 0 bc of log, not 1 bc of powers + eval_context[trendVar] = 2; // not <= 0 bc of log, not 1 bc of powers } void DynamicModel::addStaticOnlyEquation(expr_t eq, optional lineno, map eq_tags) { - auto beq = dynamic_cast(eq); + auto beq = dynamic_cast(eq); assert(beq && beq->op_code == BinaryOpcode::equal); static_only_equations_equation_tags.add(static_only_equations.size(), move(eq_tags)); @@ -3462,30 +3597,32 @@ DynamicModel::dynamicOnlyEquationsNbr() const } void -DynamicModel::addOccbinEquation(expr_t eq, optional lineno, map eq_tags, const vector ®imes_bind, const vector ®imes_relax) +DynamicModel::addOccbinEquation(expr_t eq, optional lineno, map eq_tags, + const vector& regimes_bind, + const vector& regimes_relax) { - auto beq = dynamic_cast(eq); + auto beq = dynamic_cast(eq); assert(beq && beq->op_code == BinaryOpcode::equal); // Construct the term to be added to the corresponding equation expr_t basic_term = AddMinus(beq->arg1, beq->arg2); expr_t term = basic_term; - for (auto ®ime : regimes_bind) + for (auto& regime : regimes_bind) { int param_id = symbol_table.getID(ParsingDriver::buildOccbinBindParamName(regime)); term = AddTimes(term, AddVariable(param_id)); } - for (auto ®ime : regimes_relax) + for (auto& regime : regimes_relax) { int param_id = symbol_table.getID(ParsingDriver::buildOccbinBindParamName(regime)); term = AddTimes(term, AddMinus(One, AddVariable(param_id))); } // Create or update the dynamic equation - optional eqn { equation_tags.getEqnByTag("name", eq_tags.at("name")) }; + optional eqn {equation_tags.getEqnByTag("name", eq_tags.at("name"))}; if (eqn) { - BinaryOpNode *orig_eq { equations[*eqn] }; + BinaryOpNode* orig_eq {equations[*eqn]}; /* In the following, we could have kept only orig_eq->arg1, but the following adds a (somewhat bizarre) support for equation snippets without “bind” nor “relax” */ @@ -3506,11 +3643,13 @@ DynamicModel::addOccbinEquation(expr_t eq, optional lineno, map eqn_static { static_only_equations_equation_tags.getEqnByTag("name", eq_tags.at("name")) }; + optional eqn_static { + static_only_equations_equation_tags.getEqnByTag("name", eq_tags.at("name"))}; if (eqn_static) { - BinaryOpNode *orig_eq { static_only_equations[*eqn_static] }; - static_only_equations[*eqn_static] = AddEqual(AddPlus(AddMinus(orig_eq->arg1, orig_eq->arg2), basic_term), Zero); + BinaryOpNode* orig_eq {static_only_equations[*eqn_static]}; + static_only_equations[*eqn_static] + = AddEqual(AddPlus(AddMinus(orig_eq->arg1, orig_eq->arg2), basic_term), Zero); // It’s unclear how to update lineno and tags, so don’t do it } else @@ -3522,30 +3661,29 @@ DynamicModel::addOccbinEquation(expr_t eq, optional lineno, map(temporary_terms_derivatives[0], - temp_term_union, temporary_terms_idxs, - buffer, tef_terms); + writeTemporaryTerms(temporary_terms_derivatives[0], temp_term_union, + temporary_terms_idxs, buffer, tef_terms); writeModelEquations(buffer, temp_term_union); - size_t result = hash{}(buffer.str()); + size_t result = hash {}(buffer.str()); // check whether basename directory exist. If not, create it. // If it does, read old checksum if it exists, return if equal to result fstream checksum_file; - auto filename = filesystem::path{basename} / "checksum"; + auto filename = filesystem::path {basename} / "checksum"; if (!filesystem::create_directory(basename)) { checksum_file.open(filename, ios::in | ios::binary); @@ -3572,7 +3710,7 @@ DynamicModel::isChecksumMatching(const string &basename) const } void -DynamicModel::writeJsonOutput(ostream &output) const +DynamicModel::writeJsonOutput(ostream& output) const { deriv_node_temp_terms_t tef_terms; writeJsonModelLocalVariables(output, false, tef_terms); @@ -3585,8 +3723,7 @@ DynamicModel::writeJsonOutput(ostream &output) const output << ", "; writeJsonVariableMapping(output); output << R"(, "dynamic_tmp_nbr": [)"; - for (bool printed_something {false}; - const auto &tts : temporary_terms_derivatives) + for (bool printed_something {false}; const auto& tts : temporary_terms_derivatives) { if (exchange(printed_something, true)) output << ", "; @@ -3597,7 +3734,7 @@ DynamicModel::writeJsonOutput(ostream &output) const } void -DynamicModel::writeJsonAST(ostream &output) const +DynamicModel::writeJsonAST(ostream& output) const { vector> eqtags; output << R"("abstract_syntax_tree":[)" << endl; @@ -3620,19 +3757,16 @@ DynamicModel::writeJsonAST(ostream &output) const } void -DynamicModel::writeJsonVariableMapping(ostream &output) const +DynamicModel::writeJsonVariableMapping(ostream& output) const { output << R"("variable_mapping":[)" << endl; - for (bool printed_something{false}; - const auto &[var, eqs] : variableMapping) + for (bool printed_something {false}; const auto& [var, eqs] : variableMapping) { if (exchange(printed_something, true)) output << ", "; output << R"({"name": ")" << symbol_table.getName(var) << R"(", "equations":[)"; - for (bool printed_something2{false}; - int it2 : eqs) - if (auto tmp = equation_tags.getTagValueByEqnAndKey(it2, "name"); - tmp) + for (bool printed_something2 {false}; int it2 : eqs) + if (auto tmp = equation_tags.getTagValueByEqnAndKey(it2, "name"); tmp) { if (exchange(printed_something2, true)) output << ", "; @@ -3644,18 +3778,16 @@ DynamicModel::writeJsonVariableMapping(ostream &output) const } void -DynamicModel::writeJsonXrefsHelper(ostream &output, const map, set> &xrefmap) const +DynamicModel::writeJsonXrefsHelper(ostream& output, + const map, set>& xrefmap) const { - for (bool printed_something{false}; - const auto &[symb_lag, eqs] : xrefmap) + for (bool printed_something {false}; const auto& [symb_lag, eqs] : xrefmap) { if (exchange(printed_something, true)) output << ", "; output << R"({"name": ")" << symbol_table.getName(symb_lag.first) << R"(")" - << R"(, "shift": )" << symb_lag.second - << R"(, "equations": [)"; - for (bool printed_something2{false}; - int eq : eqs) + << R"(, "shift": )" << symb_lag.second << R"(, "equations": [)"; + for (bool printed_something2 {false}; int eq : eqs) { if (exchange(printed_something2, true)) output << ", "; @@ -3666,7 +3798,7 @@ DynamicModel::writeJsonXrefsHelper(ostream &output, const map, se } void -DynamicModel::writeJsonXrefs(ostream &output) const +DynamicModel::writeJsonXrefs(ostream& output) const { output << R"("xrefs": {)" << R"("parameters": [)"; @@ -3684,7 +3816,7 @@ DynamicModel::writeJsonXrefs(ostream &output) const } void -DynamicModel::writeJsonOriginalModelOutput(ostream &output) const +DynamicModel::writeJsonOriginalModelOutput(ostream& output) const { writeJsonModelEquations(output, false); output << ", "; @@ -3692,24 +3824,18 @@ DynamicModel::writeJsonOriginalModelOutput(ostream &output) const } void -DynamicModel::writeJsonDynamicModelInfo(ostream &output) const +DynamicModel::writeJsonDynamicModelInfo(ostream& output) const { output << R"("model_info": {)" << R"("lead_lag_incidence": [)"; // Loop on endogenous variables - int nstatic = 0, - nfwrd = 0, - npred = 0, - nboth = 0; + int nstatic = 0, nfwrd = 0, npred = 0, nboth = 0; for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++) { if (endoID != 0) output << ","; output << "["; - int sstatic = 1, - sfwrd = 0, - spred = 0, - sboth = 0; + int sstatic = 1, sfwrd = 0, spred = 0, sboth = 0; // Loop on periods for (int lag = -max_endo_lag; lag <= max_endo_lead; lag++) { @@ -3739,7 +3865,7 @@ DynamicModel::writeJsonDynamicModelInfo(ostream &output) const } } } - catch (UnknownDerivIDException &e) + catch (UnknownDerivIDException& e) { output << " 0"; } @@ -3755,9 +3881,9 @@ DynamicModel::writeJsonDynamicModelInfo(ostream &output) const << R"("nfwrd": )" << nfwrd << ", " << endl << R"("npred": )" << npred << ", " << endl << R"("nboth": )" << nboth << ", " << endl - << R"("nsfwrd": )" << nfwrd+nboth << ", " << endl - << R"("nspred": )" << npred+nboth << ", " << endl - << R"("ndynamic": )" << npred+nboth+nfwrd << ", " << endl + << R"("nsfwrd": )" << nfwrd + nboth << ", " << endl + << R"("nspred": )" << npred + nboth << ", " << endl + << R"("ndynamic": )" << npred + nboth + nfwrd << ", " << endl << R"("maximum_endo_lag": )" << max_endo_lag << ", " << endl << R"("maximum_endo_lead": )" << max_endo_lead << ", " << endl << R"("maximum_exo_lag": )" << max_exo_lag << ", " << endl @@ -3774,63 +3900,56 @@ DynamicModel::writeJsonDynamicModelInfo(ostream &output) const << R"("orig_maximum_exo_det_lead": )" << max_exo_det_lead_orig << "," << endl << R"("orig_maximum_lag": )" << max_lag_orig << "," << endl << R"("orig_maximum_lead": )" << max_lead_orig << "," << endl - << R"("orig_maximum_lag_with_diffs_expanded": )" << max_lag_with_diffs_expanded_orig - << "," <(NNZDerivatives.size()); i++) { output << (i > computed_derivs_order ? -1 : NNZDerivatives[i]); if (i < static_cast(NNZDerivatives.size()) - 1) - output << ", "; + output << ", "; } - output << "]}" - << endl; + output << "]}" << endl; } void -DynamicModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) const +DynamicModel::writeJsonComputingPassOutput(ostream& output, bool writeDetails) const { - auto [mlv_output, d_output] { writeJsonComputingPassOutputHelper(writeDetails) }; + auto [mlv_output, d_output] {writeJsonComputingPassOutputHelper(writeDetails)}; if (writeDetails) output << R"("dynamic_model": {)"; else output << R"("dynamic_model_simple": {)"; output << mlv_output.str(); - for (const auto &it : d_output) + for (const auto& it : d_output) output << ", " << it.str(); output << "}"; } void -DynamicModel::writeJsonParamsDerivatives(ostream &output, bool writeDetails) const +DynamicModel::writeJsonParamsDerivatives(ostream& output, bool writeDetails) const { if (!params_derivatives.size()) return; - auto [mlv_output, tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output, g3p_output] - { writeJsonParamsDerivativesHelper(writeDetails) }; + auto [mlv_output, tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output, + g3p_output] {writeJsonParamsDerivativesHelper(writeDetails)}; if (writeDetails) output << R"("dynamic_model_params_derivative": {)"; else output << R"("dynamic_model_params_derivatives_simple": {)"; - output << mlv_output.str() - << ", " << tt_output.str() - << ", " << rp_output.str() - << ", " << gp_output.str() - << ", " << rpp_output.str() - << ", " << gpp_output.str() - << ", " << hp_output.str() - << ", " << g3p_output.str() - << "}"; + output << mlv_output.str() << ", " << tt_output.str() << ", " << rp_output.str() << ", " + << gp_output.str() << ", " << rpp_output.str() << ", " << gpp_output.str() << ", " + << hp_output.str() << ", " << g3p_output.str() << "}"; } void -DynamicModel::substituteVarExpectation(const map &subst_table) +DynamicModel::substituteVarExpectation(const map& subst_table) { - for (auto &equation : equations) - equation = dynamic_cast(equation->substituteVarExpectation(subst_table)); + for (auto& equation : equations) + equation = dynamic_cast(equation->substituteVarExpectation(subst_table)); } void @@ -3839,7 +3958,8 @@ DynamicModel::checkNoRemainingPacExpectation() const for (size_t eq = 0; eq < equations.size(); eq++) if (equations[eq]->containsPacExpectation()) { - cerr << "ERROR: in equation " << equation_tags.getTagValueByEqnAndKey(eq, "name").value_or(to_string(eq+1)) + cerr << "ERROR: in equation " + << equation_tags.getTagValueByEqnAndKey(eq, "name").value_or(to_string(eq + 1)) << ", the pac_expectation operator references an unknown pac_model" << endl; exit(EXIT_FAILURE); } @@ -3849,18 +3969,18 @@ void DynamicModel::simplifyEquations() { size_t last_subst_table_size = 0; - map subst_table; + map subst_table; // Equations with “mcp” tag are excluded, see dynare#1697 findConstantEquationsWithoutMcpTag(subst_table); while (subst_table.size() != last_subst_table_size) { last_subst_table_size = subst_table.size(); - for (auto &[id, definition] : local_variables_table) + for (auto& [id, definition] : local_variables_table) definition = definition->replaceVarsInEquation(subst_table); - for (auto &equation : equations) - equation = dynamic_cast(equation->replaceVarsInEquation(subst_table)); - for (auto &equation : static_only_equations) - equation = dynamic_cast(equation->replaceVarsInEquation(subst_table)); + for (auto& equation : equations) + equation = dynamic_cast(equation->replaceVarsInEquation(subst_table)); + for (auto& equation : static_only_equations) + equation = dynamic_cast(equation->replaceVarsInEquation(subst_table)); subst_table.clear(); findConstantEquationsWithoutMcpTag(subst_table); } @@ -3872,8 +3992,11 @@ DynamicModel::checkNoRemainingPacTargetNonstationary() const for (size_t eq = 0; eq < equations.size(); eq++) if (equations[eq]->containsPacTargetNonstationary()) { - cerr << "ERROR: in equation " << equation_tags.getTagValueByEqnAndKey(eq, "name").value_or(to_string(eq+1)) - << ", the pac_target_nonstationary operator does not match a corresponding 'pac_target_info' block" << endl; + cerr << "ERROR: in equation " + << equation_tags.getTagValueByEqnAndKey(eq, "name").value_or(to_string(eq + 1)) + << ", the pac_target_nonstationary operator does not match a corresponding " + "'pac_target_info' block" + << endl; exit(EXIT_FAILURE); } } @@ -3883,13 +4006,13 @@ DynamicModel::checkIsLinear() const { if (!nonzero_hessian_eqs.empty()) { - cerr << "ERROR: If the model is declared linear the second derivatives must be equal to zero." << endl + cerr << "ERROR: If the model is declared linear the second derivatives must be equal to zero." + << endl << " The following equations have non-zero second derivatives:" << endl; for (auto it : nonzero_hessian_eqs) { - cerr << " * Eq # " << it+1; - if (optional eqname { equation_tags.getTagValueByEqnAndKey(it, "name") }; - eqname) + cerr << " * Eq # " << it + 1; + if (optional eqname {equation_tags.getTagValueByEqnAndKey(it, "name")}; eqname) cerr << " [" << *eqname << "]"; cerr << endl; } diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh index 636ee605..0dd374cc 100644 --- a/src/DynamicModel.hh +++ b/src/DynamicModel.hh @@ -20,11 +20,11 @@ #ifndef _DYNAMICMODEL_HH #define _DYNAMICMODEL_HH -#include #include +#include -#include "StaticModel.hh" #include "Bytecode.hh" +#include "StaticModel.hh" using namespace std; @@ -34,23 +34,24 @@ class DynamicModel : public ModelTree friend class StaticModel; // For reading static_mfs from converting constructor public: //! A reference to the trend component model table - TrendComponentModelTable &trend_component_model_table; + TrendComponentModelTable& trend_component_model_table; //! A reference to the VAR model table - VarModelTable &var_model_table; + VarModelTable& var_model_table; /* Used in the balanced growth test, for determining whether the cross-derivative of a given equation, w.r.t. an endogenous and a trend variable is zero. Controlled by option “balanced_growth_test_tol” of the “model” block. The default should not be too small (see dynare#1389). */ - double balanced_growth_test_tol{1e-6}; + double balanced_growth_test_tol {1e-6}; + private: /* Used in the balanced growth test, for skipping equations where the test cannot be performed (i.e. when LHS=RHS at the initial values). Should not be too large, otherwise the test becomes less powerful. */ - constexpr static double zero_band{1e-8}; + constexpr static double zero_band {1e-8}; //! Stores equations declared as [static] /*! They will be used in the conversion to StaticModel to replace equations marked as [dynamic] */ - vector static_only_equations; + vector static_only_equations; //! Stores line numbers of equations declared as [static] vector> static_only_equations_lineno; @@ -73,24 +74,25 @@ private: //! Maximum lag and lead over all types of variables (positive values) /*! Set by computeDerivIDs() */ - int max_lag{0}, max_lead{0}; + int max_lag {0}, max_lead {0}; //! Maximum lag and lead over endogenous variables (positive values) /*! Set by computeDerivIDs() */ - int max_endo_lag{0}, max_endo_lead{0}; + int max_endo_lag {0}, max_endo_lead {0}; //! Maximum lag and lead over exogenous variables (positive values) /*! Set by computeDerivIDs() */ - int max_exo_lag{0}, max_exo_lead{0}; + int max_exo_lag {0}, max_exo_lead {0}; //! Maximum lag and lead over deterministic exogenous variables (positive values) /*! Set by computeDerivIDs() */ - int max_exo_det_lag{0}, max_exo_det_lead{0}; + int max_exo_det_lag {0}, max_exo_det_lead {0}; //! Maximum lag and lead over all types of variables (positive values) of original model - int max_lag_orig{0}, max_lead_orig{0}, max_lag_with_diffs_expanded_orig{0}; + int max_lag_orig {0}, max_lead_orig {0}, max_lag_with_diffs_expanded_orig {0}; //! Maximum lag and lead over endogenous variables (positive values) of original model - int max_endo_lag_orig{0}, max_endo_lead_orig{0}; + int max_endo_lag_orig {0}, max_endo_lead_orig {0}; //! Maximum lag and lead over exogenous variables (positive values) of original model - int max_exo_lag_orig{0}, max_exo_lead_orig{0}; - //! Maximum lag and lead over deterministic exogenous variables (positive values) of original model - int max_exo_det_lag_orig{0}, max_exo_det_lead_orig{0}; + int max_exo_lag_orig {0}, max_exo_lead_orig {0}; + //! Maximum lag and lead over deterministic exogenous variables (positive values) of original + //! model + int max_exo_det_lag_orig {0}, max_exo_det_lead_orig {0}; // Cross reference information: eq → set of (symb_id, lag) for each symbol type map xrefs; @@ -111,30 +113,30 @@ private: map> var_expectation_functions_to_write; // Value of the “mfs” option of “model” block (or ”model_options” command) - int mfs{1}; + int mfs {1}; /* Value of the “static_mfs” option of “model” block (or the “model_options” command). Only used when converting to StaticModel class. */ - int static_mfs{0}; + int static_mfs {0}; // Writes dynamic model file (MATLAB/Octave version, legacy representation) - void writeDynamicMFile(const string &basename) const; + void writeDynamicMFile(const string& basename) const; //! Writes the code of the block-decomposed model in virtual machine bytecode - void writeDynamicBlockBytecode(const string &basename) const; + void writeDynamicBlockBytecode(const string& basename) const; //! Writes the code of the model in virtual machine bytecode - void writeDynamicBytecode(const string &basename) const; + void writeDynamicBytecode(const string& basename) const; // Write the block structure of the model in the driver file - void writeBlockDriverOutput(ostream &output) const; + void writeBlockDriverOutput(ostream& output) const; // Used by determineBlockDerivativesType() enum class BlockDerivativeType - { - standard, - chainRule, - normalizedChainRule - }; + { + standard, + chainRule, + normalizedChainRule + }; /* For each tuple (lag, eq, var) within the given block, determine the type of the derivative to be computed. Indices are within the block (i.e. @@ -143,7 +145,7 @@ private: void computeChainRuleJacobian() override; - string reform(const string &name) const; + string reform(const string& name) const; SymbolType getTypeByDerivID(int deriv_id) const noexcept(false) override; int getLagByDerivID(int deriv_id) const noexcept(false) override; @@ -153,10 +155,11 @@ private: //! Compute the column indices of the dynamic Jacobian void computeDynJacobianCols(); //! Computes derivatives of the Jacobian w.r. to trend vars and tests that they are equal to zero - void testTrendDerivativesEqualToZero(const eval_context_t &eval_context); + void testTrendDerivativesEqualToZero(const eval_context_t& eval_context); //! Allocates the derivation IDs for all dynamic variables of the model - /*! Also computes max_{endo,exo}_{lead_lag}, and initializes dynJacobianColsNbr to the number of dynamic endos */ + /*! Also computes max_{endo,exo}_{lead_lag}, and initializes dynJacobianColsNbr to the number of + * dynamic endos */ void computeDerivIDs(); /* Compute the Jacobian column indices in the block decomposition case @@ -167,37 +170,39 @@ private: //! Factorized code for substitutions of leads/lags /*! \param[in] type determines which type of variables is concerned - \param[in] deterministic_model whether we are in a deterministic model (only for exogenous leads/lags) - \param[in] subset variables to which to apply the transformation (only for diff of forward vars) + \param[in] deterministic_model whether we are in a deterministic model (only for exogenous + leads/lags) \param[in] subset variables to which to apply the transformation (only for diff of + forward vars) */ - void substituteLeadLagInternal(AuxVarType type, bool deterministic_model, const vector &subset); + void substituteLeadLagInternal(AuxVarType type, bool deterministic_model, + const vector& subset); //! Help computeXrefs to compute the reverse references (i.e. param->eqs, endo->eqs, etc) - void computeRevXref(map, set> &xrefset, const set> &eiref, int eqn); + void computeRevXref(map, set>& xrefset, const set>& eiref, + int eqn); //! Write reverse cross references - void writeRevXrefs(ostream &output, const map, set> &xrefmap, const string &type) const; + void writeRevXrefs(ostream& output, const map, set>& xrefmap, + const string& type) const; /* Writes MATLAB/Octave wrapper function for computing residuals and derivatives at the same time (legacy representation) */ - void writeDynamicMWrapperFunction(const string &name, const string &ending) const; + void writeDynamicMWrapperFunction(const string& name, const string& ending) const; /* Helper for writing MATLAB/Octave functions for residuals/derivatives and their temporary terms (legacy representation) */ - void writeDynamicMFileHelper(const string &basename, - const string &name, const string &retvalname, - const string &name_tt, size_t ttlen, - const string &previous_tt_name, - const ostringstream &init_s, const ostringstream &end_s, - const ostringstream &s, const ostringstream &s_tt) const; + void writeDynamicMFileHelper(const string& basename, const string& name, const string& retvalname, + const string& name_tt, size_t ttlen, const string& previous_tt_name, + const ostringstream& init_s, const ostringstream& end_s, + const ostringstream& s, const ostringstream& s_tt) const; /* Create the compatibility dynamic.m file for MATLAB/Octave not yet using the temporary terms array interface (legacy representation) */ - void writeDynamicMCompatFile(const string &basename) const; + void writeDynamicMCompatFile(const string& basename) const; //! Internal helper for the copy constructor and assignment operator /*! Copies all the structures that contain ExprNode*, by the converting the pointers into their equivalent in the new tree */ - void copyHelper(const DynamicModel &m); + void copyHelper(const DynamicModel& m); /* Handles parsing of argument passed to exclude_eqs/include_eqs. @@ -221,7 +226,8 @@ private: Returns a set of pairs (tag name, tag value) corresponding to the set of equations to be included or excluded. */ - static vector> parseIncludeExcludeEquations(const string &inc_exc_option_value, bool exclude_eqs); + static vector> + parseIncludeExcludeEquations(const string& inc_exc_option_value, bool exclude_eqs); /* Helper for the removeEquations() method. listed_eqs_by_tag describes a list of equations to remove (identified by @@ -240,12 +246,11 @@ private: Returns a list of excluded variables (empty if excluded_vars_change_type=false) */ - vector removeEquationsHelper(set> &listed_eqs_by_tag, - bool exclude_eqs, bool excluded_vars_change_type, - vector &all_equations, - vector> &all_equations_lineno, - EquationTags &all_equation_tags, - bool static_equations) const; + vector removeEquationsHelper(set>& listed_eqs_by_tag, bool exclude_eqs, + bool excluded_vars_change_type, + vector& all_equations, + vector>& all_equations_lineno, + EquationTags& all_equation_tags, bool static_equations) const; //! Compute autoregressive matrices of trend component models /* The algorithm uses matching rules over expression trees. It cannot handle @@ -254,7 +259,8 @@ private: //! Compute error component matrices of trend component_models /*! Returns a pair (A0r, A0starr) */ - pair, expr_t>>, map, expr_t>>> computeErrorComponentMatrices(const ExprNode::subst_table_t &diff_subst_table) const; + pair, expr_t>>, map, expr_t>>> + computeErrorComponentMatrices(const ExprNode::subst_table_t& diff_subst_table) const; /* For a VAR model, given the symbol ID of a LHS variable, and a (negative) lag, returns all the corresponding deriv_ids (by properly dealing with two @@ -267,7 +273,7 @@ private: int getBlockJacobianEndoCol(int blk, int var, int lag) const override { - return blocks_jacob_cols_endo[blk].at({ var, lag }); + return blocks_jacob_cols_endo[blk].at({var, lag}); } protected: @@ -278,60 +284,60 @@ protected: } public: - DynamicModel(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg, - TrendComponentModelTable &trend_component_model_table_arg, - VarModelTable &var_model_table_arg); + DynamicModel(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg, + TrendComponentModelTable& trend_component_model_table_arg, + VarModelTable& var_model_table_arg); - DynamicModel(const DynamicModel &m); - DynamicModel &operator=(const DynamicModel &m); + DynamicModel(const DynamicModel& m); + DynamicModel& operator=(const DynamicModel& m); //! Compute cross references void computeXrefs(); //! Write cross references - void writeXrefs(ostream &output) const; + void writeXrefs(ostream& output) const; //! Execute computations (variable sorting + derivation + block decomposition) /*! - \param derivsOrder order of derivatives w.r. to exo, exo_det and endo should be computed (implies jacobianExo = true when order >= 2) - \param paramsDerivsOrder order of derivatives w.r. to a pair (endo/exo/exo_det, parameter) to be computed (>0 implies jacobianExo = true) - \param eval_context evaluation context for normalization - \param no_tmp_terms if true, no temporary terms will be computed in the dynamic files + \param derivsOrder order of derivatives w.r. to exo, exo_det and endo should be computed + (implies jacobianExo = true when order >= 2) \param paramsDerivsOrder order of derivatives w.r. + to a pair (endo/exo/exo_det, parameter) to be computed (>0 implies jacobianExo = true) \param + eval_context evaluation context for normalization \param no_tmp_terms if true, no temporary + terms will be computed in the dynamic files */ - void computingPass(int derivsOrder, int paramsDerivsOrder, const eval_context_t &eval_context, + void computingPass(int derivsOrder, int paramsDerivsOrder, const eval_context_t& eval_context, bool no_tmp_terms, bool block, bool use_dll); //! Writes information about the dynamic model to the driver file - void writeDriverOutput(ostream &output, bool compute_xrefs) const; + void writeDriverOutput(ostream& output, bool compute_xrefs) const; //! Write JSON AST - void writeJsonAST(ostream &output) const; + void writeJsonAST(ostream& output) const; //! Write JSON variable mapping - void writeJsonVariableMapping(ostream &output) const; + void writeJsonVariableMapping(ostream& output) const; //! Write JSON Output - void writeJsonOutput(ostream &output) const; + void writeJsonOutput(ostream& output) const; //! Write JSON Output representation of original dynamic model - void writeJsonOriginalModelOutput(ostream &output) const; + void writeJsonOriginalModelOutput(ostream& output) const; //! Write JSON Output representation of model info (useful stuff from M_) - void writeJsonDynamicModelInfo(ostream &output) const; + void writeJsonDynamicModelInfo(ostream& output) const; //! Write JSON Output representation of dynamic model after computing pass - void writeJsonComputingPassOutput(ostream &output, bool writeDetails) const; + void writeJsonComputingPassOutput(ostream& output, bool writeDetails) const; //! Write JSON params derivatives - void writeJsonParamsDerivatives(ostream &output, bool writeDetails) const; + void writeJsonParamsDerivatives(ostream& output, bool writeDetails) const; //! Write cross reference output if the xref maps have been filed - void writeJsonXrefs(ostream &output) const; - void writeJsonXrefsHelper(ostream &output, const map, set> &xrefmap) const; + void writeJsonXrefs(ostream& output) const; + void writeJsonXrefsHelper(ostream& output, const map, set>& xrefmap) const; //! Print equations that have non-zero second derivatives - void printNonZeroHessianEquations(ostream &output) const; + void printNonZeroHessianEquations(ostream& output) const; //! Tells whether Hessian has been computed /*! This is needed to know whether no non-zero equation in Hessian means a @@ -357,7 +363,7 @@ public: components, available from the transformed model. Needs to be called after fillTrendComponentModelTableFromOrigModel() has been called on the original model */ - void fillTrendComponentModelTableAREC(const ExprNode::subst_table_t &diff_subst_table) const; + void fillTrendComponentModelTableAREC(const ExprNode::subst_table_t& diff_subst_table) const; //! Fill the VAR model table with information available from the transformed model // NB: Does not fill the AR and A0 matrices @@ -374,16 +380,18 @@ public: void updateVarAndTrendModel() const; //! Writes dynamic model file (+ bytecode) - void writeDynamicFile(const string &basename, bool use_dll, const string &mexext, const filesystem::path &matlabroot, bool julia) const; + void writeDynamicFile(const string& basename, bool use_dll, const string& mexext, + const filesystem::path& matlabroot, bool julia) const; //! Writes file containing parameters derivatives template - void writeParamsDerivativesFile(const string &basename) const; + void writeParamsDerivativesFile(const string& basename) const; //! Creates mapping for variables and equations they are present in void createVariableMapping(); - //! Expands equation tags with default equation names (available "name" tag or LHS variable or equation ID) + //! Expands equation tags with default equation names (available "name" tag or LHS variable or + //! equation ID) void expandEqTags(); //! Find endogenous variables not used in model @@ -395,14 +403,14 @@ public: void setLeadsLagsOrig(); //! Implements the include_eqs/exclude_eqs options - void includeExcludeEquations(const string &inc_exc_option_value, bool exclude_eqs); + void includeExcludeEquations(const string& inc_exc_option_value, bool exclude_eqs); /* Removes equations from the model (identified by one or more tags; if multiple tags are present for a single equation, they are understood as a conjunction). Used for include_eqs/exclude_eqs options and for model_remove and model_replace blocks */ - void removeEquations(const vector> &listed_eqs_by_tag, bool exclude_eqs, + void removeEquations(const vector>& listed_eqs_by_tag, bool exclude_eqs, bool excluded_vars_change_type); /* Replaces model equations with derivatives of Lagrangian w.r.t. endogenous. @@ -411,13 +419,13 @@ public: Returns the number of optimality FOCs, which is by construction equal to the number of endogenous before adding the Lagrange multipliers (internally called ramsey_endo_nbr). */ - int computeRamseyPolicyFOCs(const StaticModel &static_model); + int computeRamseyPolicyFOCs(const StaticModel& static_model); //! Clears all equations void clearEquations(); //! Replaces the model equations in dynamic_model with those in this model - void replaceMyEquations(DynamicModel &dynamic_model) const; + void replaceMyEquations(DynamicModel& dynamic_model) const; //! Adds an equation marked as [static] void addStaticOnlyEquation(expr_t eq, optional lineno, map eq_tags); @@ -433,13 +441,14 @@ 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 lineno, map eq_tags, const vector ®imes_bind, const vector ®imes_relax); + void addOccbinEquation(expr_t eq, optional lineno, map eq_tags, + const vector& regimes_bind, const vector& regimes_relax); //! Writes LaTeX file with the equations of the dynamic model - void writeLatexFile(const string &basename, bool write_equation_tags) const; + void writeLatexFile(const string& basename, bool write_equation_tags) const; //! Writes LaTeX file with the equations of the dynamic model (for the original model) - void writeLatexOriginalFile(const string &basename, bool write_equation_tags) const; + void writeLatexOriginalFile(const string& basename, bool write_equation_tags) const; int getDerivID(int symb_id, int lag) const noexcept(false) override; @@ -454,25 +463,24 @@ public: if (type == SymbolType::endogenous) { assert(lag >= -1 && lag <= 1); - return tsid+(lag+1)*symbol_table.endo_nbr(); + return tsid + (lag + 1) * symbol_table.endo_nbr(); } else if (type == SymbolType::exogenous) { assert(lag == 0); - return tsid+3*symbol_table.endo_nbr(); + return tsid + 3 * symbol_table.endo_nbr(); } else if (type == SymbolType::exogenousDet) { assert(lag == 0); - return tsid+3*symbol_table.endo_nbr()+symbol_table.exo_nbr(); + return tsid + 3 * symbol_table.endo_nbr() + symbol_table.exo_nbr(); } else throw UnknownDerivIDException(); } else { - if (auto it = dyn_jacobian_cols_table.find(deriv_id); - it == dyn_jacobian_cols_table.end()) + if (auto it = dyn_jacobian_cols_table.find(deriv_id); it == dyn_jacobian_cols_table.end()) throw UnknownDerivIDException(); else return it->second; @@ -481,12 +489,12 @@ public: int getJacobianColsNbr(bool sparse) const override { - return sparse ? - 3*symbol_table.endo_nbr() + symbol_table.exo_nbr() + symbol_table.exo_det_nbr() : - dyn_jacobian_ncols; + return sparse + ? 3 * symbol_table.endo_nbr() + symbol_table.exo_nbr() + symbol_table.exo_det_nbr() + : dyn_jacobian_ncols; } - void addAllParamDerivId(set &deriv_id_set) override; + void addAllParamDerivId(set& deriv_id_set) override; //! Returns true indicating that this is a dynamic model bool @@ -496,7 +504,7 @@ public: }; //! Drive test of detrended equations - void runTrendTest(const eval_context_t &eval_context); + void runTrendTest(const eval_context_t& eval_context); //! Transforms the model by removing all leads greater or equal than 2 on endos /*! Note that this can create new lags on endos and exos */ @@ -515,25 +523,26 @@ public: //! Transforms the model by removing all UnaryOpcode::expectation void substituteExpectation(bool partial_information_model); - //! Transforms the model by decreasing the lead/lag of predetermined variables in model equations by one + //! Transforms the model by decreasing the lead/lag of predetermined variables in model equations + //! by one void transformPredeterminedVariables(); // Performs the transformations associated to variables declared with “var(log)” void substituteLogTransform(); // Check that no variable was declared with “var(log)” in the given equations - void checkNoWithLogTransform(const set &eqnumbers); + void checkNoWithLogTransform(const set& eqnumbers); //! Transforms the model by removing trends specified by the user void detrendEquations(); - const nonstationary_symbols_map_t & + const nonstationary_symbols_map_t& getNonstationarySymbolsMap() const { return nonstationary_symbols_map; } - const map & + const map& getTrendSymbolsMap() const { return trend_symbols_map; @@ -548,20 +557,28 @@ public: /* Creates aux vars for all unary operators in all equations. Also makes the substitution in growth terms of pac_model/pac_target_info and in expressions of var_expectation_model. */ - pair substituteUnaryOps(VarExpectationModelTable &var_expectation_model_table, PacModelTable &pac_model_table); + pair + substituteUnaryOps(VarExpectationModelTable& var_expectation_model_table, + PacModelTable& pac_model_table); /* Creates aux vars for all unary operators in specified equations. Also makes the substitution in growth terms of pac_model/pac_target_info and in expressions of var_expectation_model. */ - pair substituteUnaryOps(const set &eqnumbers, VarExpectationModelTable &var_expectation_model_table, PacModelTable &pac_model_table); + pair + substituteUnaryOps(const set& eqnumbers, + VarExpectationModelTable& var_expectation_model_table, + PacModelTable& pac_model_table); //! Substitutes diff operator - pair substituteDiff(VarExpectationModelTable &var_expectation_model_table, PacModelTable &pac_model_table); + pair + substituteDiff(VarExpectationModelTable& var_expectation_model_table, + PacModelTable& pac_model_table); //! Substitute VarExpectation operators - void substituteVarExpectation(const map &subst_table); + void substituteVarExpectation(const map& subst_table); - void analyzePacEquationStructure(const string &name, map &pac_eq_name, PacModelTable::equation_info_t &pac_equation_info); + void analyzePacEquationStructure(const string& name, map& pac_eq_name, + PacModelTable::equation_info_t& pac_equation_info); // Exception thrown by getPacTargetSymbId() struct PacTargetNotIdentifiedException @@ -570,7 +587,7 @@ public: }; //! Return target of the pac equation - int getPacTargetSymbId(const string &pac_model_name) const; + int getPacTargetSymbId(const string& pac_model_name) const; /* For a PAC MCE model, fill pac_expectation_substitution with the expression that will be substituted for the pac_expectation operator. @@ -578,29 +595,22 @@ public: The symbol IDs of the new endogenous are added to pac_aux_var_symb_ids, and the new auxiliary parameters to pac_mce_alpha_symb_ids. */ - void computePacModelConsistentExpectationSubstitution(const string &name, - int discount_symb_id, int pac_eq_max_lag, - expr_t growth_correction_term, - string auxname, - ExprNode::subst_table_t &diff_subst_table, - map &pac_aux_var_symb_ids, - map> &pac_aux_param_symb_ids, - map &pac_expectation_substitution); - + void computePacModelConsistentExpectationSubstitution( + const string& name, int discount_symb_id, int pac_eq_max_lag, expr_t growth_correction_term, + string auxname, ExprNode::subst_table_t& diff_subst_table, + map& pac_aux_var_symb_ids, map>& pac_aux_param_symb_ids, + map& pac_expectation_substitution); /* For a PAC backward model, fill pac_expectation_substitution with the expression that will be substituted for the pac_expectation operator. The symbol IDs of the new parameters are also added to pac_aux_param_symb_ids. The symbol ID of the new auxiliary variable is added to pac_aux_var_symb_ids. */ - void computePacBackwardExpectationSubstitution(const string &name, - const vector &lhs, - int max_lag, - const string &aux_model_type, - expr_t growth_correction_term, - string auxname, - map &pac_aux_var_symb_ids, - map> &pac_aux_param_symb_ids, - map &pac_expectation_substitution); + void computePacBackwardExpectationSubstitution(const string& name, const vector& lhs, + int max_lag, const string& aux_model_type, + expr_t growth_correction_term, string auxname, + map& pac_aux_var_symb_ids, + map>& pac_aux_param_symb_ids, + map& pac_expectation_substitution); /* Same as above, but for PAC models which have an associated pac_target_info. @@ -610,23 +620,21 @@ public: in target_components. The routine also creates the auxiliary variables for the components, and adds the corresponding equations. */ - void computePacBackwardExpectationSubstitutionWithComponents(const string &name, - const vector &lhs, - int max_lag, - const string &aux_model_type, - vector &pac_target_components, - map &pac_expectation_substitution); + void computePacBackwardExpectationSubstitutionWithComponents( + const string& name, const vector& lhs, int max_lag, const string& aux_model_type, + vector& pac_target_components, + map& pac_expectation_substitution); //! Substitutes pac_expectation operator with expectation based on auxiliary model - void substitutePacExpectation(const map &pac_expectation_substitution, - const map &pac_eq_name); + void substitutePacExpectation(const map& pac_expectation_substitution, + const map& pac_eq_name); //! Substitutes the pac_target_nonstationary operator of a given pac_model - void substitutePacTargetNonstationary(const string &pac_model_name, expr_t substexpr); + void substitutePacTargetNonstationary(const string& pac_model_name, expr_t substexpr); //! Table to undiff LHS variables for pac vector z - vector getUndiffLHSForPac(const string &aux_model_name, - const ExprNode::subst_table_t &diff_subst_table) const; + vector getUndiffLHSForPac(const string& aux_model_name, + const ExprNode::subst_table_t& diff_subst_table) const; //! Transforms the model by replacing trend variables with a 1 void removeTrendVariableFromEquations(); @@ -634,10 +642,10 @@ public: //! Transforms the model by creating aux vars for the diff of forward vars /*! If subset is empty, does the transformation for all fwrd vars; otherwise restrict it to the vars in subset */ - void differentiateForwardVars(const vector &subset); + void differentiateForwardVars(const vector& subset); //! Fills eval context with values of model local variables and auxiliary variables - void fillEvalContext(eval_context_t &eval_context) const; + void fillEvalContext(eval_context_t& eval_context) const; /*! Checks that all pac_expectation operators have been substituted, error out otherwise */ @@ -650,20 +658,22 @@ public: auto getStaticOnlyEquationsInfo() const { - return tuple{static_only_equations, static_only_equations_lineno, static_only_equations_equation_tags}; + return tuple {static_only_equations, static_only_equations_lineno, + static_only_equations_equation_tags}; }; //! Returns true if a parameter was used in the model block with a lead or lag bool ParamUsedWithLeadLag() const; - bool isChecksumMatching(const string &basename) const; + bool isChecksumMatching(const string& basename) const; - //! Simplify model equations: if a variable is equal to a constant, replace that variable elsewhere in the model + //! Simplify model equations: if a variable is equal to a constant, replace that variable + //! elsewhere in the model /*! Equations with MCP tags are excluded, see dynare#1697 */ void simplifyEquations(); // Converts a set of equation tags into the corresponding set of equation numbers - set getEquationNumbersFromTags(const set &eqtags) const; + set getEquationNumbersFromTags(const set& eqtags) const; // Returns the set of equations (as numbers) which have a pac_expectation operator set findPacExpectationEquationNumbers() const; @@ -689,17 +699,18 @@ public: template void -DynamicModel::writeParamsDerivativesFile(const string &basename) const +DynamicModel::writeParamsDerivativesFile(const string& basename) const { if (!params_derivatives.size()) return; - constexpr ExprNodeOutputType output_type { julia ? ExprNodeOutputType::juliaDynamicModel : ExprNodeOutputType::matlabDynamicModel }; + constexpr ExprNodeOutputType output_type {julia ? ExprNodeOutputType::juliaDynamicModel + : ExprNodeOutputType::matlabDynamicModel}; - auto [tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output, g3p_output] - { writeParamsDerivativesFileHelper() }; + auto [tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output, + g3p_output] {writeParamsDerivativesFileHelper()}; - if constexpr(!julia) + if constexpr (!julia) { filesystem::path filename {packageDir(basename) / "dynamic_params_derivs.m"}; ofstream paramsDerivsFile {filename, ios::out | ios::binary}; @@ -708,80 +719,160 @@ DynamicModel::writeParamsDerivativesFile(const string &basename) const cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; exit(EXIT_FAILURE); } - paramsDerivsFile << "function [rp, gp, rpp, gpp, hp, g3p] = dynamic_params_derivs(y, x, params, steady_state, it_, ss_param_deriv, ss_param_2nd_deriv)" << endl - << "%" << endl - << "% Compute the derivatives of the dynamic model with respect to the parameters" << endl - << "% Inputs :" << endl - << "% y [#dynamic variables by 1] double vector of endogenous variables in the order stored" << endl - << "% in M_.lead_lag_incidence; see the Manual" << endl - << "% x [nperiods by M_.exo_nbr] double matrix of exogenous variables (in declaration order)" << endl - << "% for all simulation periods" << endl - << "% params [M_.param_nbr by 1] double vector of parameter values in declaration order" << endl - << "% steady_state [M_.endo_nbr by 1] double vector of steady state values" << endl - << "% it_ scalar double time period for exogenous variables for which to evaluate the model" << endl - << "% ss_param_deriv [M_.eq_nbr by #params] Jacobian matrix of the steady states values with respect to the parameters" << endl - << "% ss_param_2nd_deriv [M_.eq_nbr by #params by #params] Hessian matrix of the steady states values with respect to the parameters" << endl - << "%" << endl - << "% Outputs:" << endl - << "% rp [M_.eq_nbr by #params] double Jacobian matrix of dynamic model equations with respect to parameters " << endl - << "% Dynare may prepend or append auxiliary equations, see M_.aux_vars" << endl - << "% gp [M_.endo_nbr by #dynamic variables by #params] double Derivative of the Jacobian matrix of the dynamic model equations with respect to the parameters" << endl - << "% rows: equations in order of declaration" << endl - << "% columns: variables in order stored in M_.lead_lag_incidence" << endl - << "% rpp [#second_order_residual_terms by 4] double Hessian matrix of second derivatives of residuals with respect to parameters;" << endl - << "% rows: respective derivative term" << endl - << "% 1st column: equation number of the term appearing" << endl - << "% 2nd column: number of the first parameter in derivative" << endl - << "% 3rd column: number of the second parameter in derivative" << endl - << "% 4th column: value of the Hessian term" << endl - << "% gpp [#second_order_Jacobian_terms by 5] double Hessian matrix of second derivatives of the Jacobian with respect to the parameters;" << endl - << "% rows: respective derivative term" << endl - << "% 1st column: equation number of the term appearing" << endl - << "% 2nd column: column number of variable in Jacobian of the dynamic model" << endl - << "% 3rd column: number of the first parameter in derivative" << endl - << "% 4th column: number of the second parameter in derivative" << endl - << "% 5th column: value of the Hessian term" << endl - << "% hp [#first_order_Hessian_terms by 5] double Jacobian matrix of derivatives of the dynamic Hessian with respect to the parameters;" << endl - << "% rows: respective derivative term" << endl - << "% 1st column: equation number of the term appearing" << endl - << "% 2nd column: column number of first variable in Hessian of the dynamic model" << endl - << "% 3rd column: column number of second variable in Hessian of the dynamic model" << endl - << "% 4th column: number of the parameter in derivative" << endl - << "% 5th column: value of the Hessian term" << endl - << "% g3p [#first_order_g3_terms by 6] double Jacobian matrix of derivatives of g3 (dynamic 3rd derivs) with respect to the parameters;" << endl - << "% rows: respective derivative term" << endl - << "% 1st column: equation number of the term appearing" << endl - << "% 2nd column: column number of first variable in g3 of the dynamic model" << endl - << "% 3rd column: column number of second variable in g3 of the dynamic model" << endl - << "% 4th column: column number of third variable in g3 of the dynamic model" << endl - << "% 5th column: number of the parameter in derivative" << endl - << "% 6th column: value of the Hessian term" << endl - << "%" << endl - << "%" << endl - << "% Warning : this file is generated automatically by Dynare" << endl - << "% from model file (.mod)" << endl << endl - << "T = NaN(" << params_derivs_temporary_terms_idxs.size() << ",1);" << endl - << tt_output.str() - << "rp = zeros(" << equations.size() << ", " - << symbol_table.param_nbr() << ");" << endl - << rp_output.str() - << "gp = zeros(" << equations.size() << ", " << getJacobianColsNbr(false) << ", " << symbol_table.param_nbr() << ");" << endl - << gp_output.str() - << "if nargout >= 3" << endl - << "rpp = zeros(" << params_derivatives.at({ 0, 2 }).size() << ",4);" << endl - << rpp_output.str() - << "gpp = zeros(" << params_derivatives.at({ 1, 2 }).size() << ",5);" << endl - << gpp_output.str() - << "end" << endl - << "if nargout >= 5" << endl - << "hp = zeros(" << params_derivatives.at({ 2, 1 }).size() << ",5);" << endl - << hp_output.str() - << "end" << endl - << "if nargout >= 6" << endl - << "g3p = zeros(" << params_derivatives.at({ 3, 1 }).size() << ",6);" << endl - << g3p_output.str() - << "end" << endl - << "end" << endl; + paramsDerivsFile + << "function [rp, gp, rpp, gpp, hp, g3p] = dynamic_params_derivs(y, x, params, " + "steady_state, it_, ss_param_deriv, ss_param_2nd_deriv)" + << endl + << "%" << endl + << "% Compute the derivatives of the dynamic model with respect to the parameters" << endl + << "% Inputs :" << endl + << "% y [#dynamic variables by 1] double vector of endogenous variables in " + "the order stored" + << endl + << "% in M_.lead_lag_incidence; see the " + "Manual" + << endl + << "% x [nperiods by M_.exo_nbr] double matrix of exogenous variables (in " + "declaration order)" + << endl + << "% for all simulation periods" << endl + << "% params [M_.param_nbr by 1] double vector of parameter values in " + "declaration order" + << endl + << "% steady_state [M_.endo_nbr by 1] double vector of steady state values" + << endl + << "% it_ scalar double time period for exogenous " + "variables for which to evaluate the model" + << endl + << "% ss_param_deriv [M_.eq_nbr by #params] Jacobian matrix of the steady " + "states values with respect to the parameters" + << endl + << "% ss_param_2nd_deriv [M_.eq_nbr by #params by #params] Hessian matrix of the " + "steady states values with respect to the parameters" + << endl + << "%" << endl + << "% Outputs:" << endl + << "% rp [M_.eq_nbr by #params] double Jacobian matrix of dynamic model " + "equations with respect to parameters " + << endl + << "% Dynare may prepend or append " + "auxiliary equations, see M_.aux_vars" + << endl + << "% gp [M_.endo_nbr by #dynamic variables by #params] double Derivative of " + "the Jacobian matrix of the dynamic model equations with respect to the parameters" + << endl + << "% rows: equations in order " + "of declaration" + << endl + << "% columns: variables in " + "order stored in M_.lead_lag_incidence" + << endl + << "% rpp [#second_order_residual_terms by 4] double Hessian matrix of second " + "derivatives of residuals with respect to parameters;" + << endl + << "% rows: respective " + "derivative term" + << endl + << "% 1st column: equation " + "number of the term appearing" + << endl + << "% 2nd column: number of " + "the first parameter in derivative" + << endl + << "% 3rd column: number of " + "the second parameter in derivative" + << endl + << "% 4th column: value of " + "the Hessian term" + << endl + << "% gpp [#second_order_Jacobian_terms by 5] double Hessian matrix of second " + "derivatives of the Jacobian with respect to the parameters;" + << endl + << "% rows: respective " + "derivative term" + << endl + << "% 1st column: equation " + "number of the term appearing" + << endl + << "% 2nd column: column " + "number of variable in Jacobian of the dynamic model" + << endl + << "% 3rd column: number of " + "the first parameter in derivative" + << endl + << "% 4th column: number of " + "the second parameter in derivative" + << endl + << "% 5th column: value of " + "the Hessian term" + << endl + << "% hp [#first_order_Hessian_terms by 5] double Jacobian matrix of " + "derivatives of the dynamic Hessian with respect to the parameters;" + << endl + << "% rows: respective " + "derivative term" + << endl + << "% 1st column: equation " + "number of the term appearing" + << endl + << "% 2nd column: column " + "number of first variable in Hessian of the dynamic model" + << endl + << "% 3rd column: column " + "number of second variable in Hessian of the dynamic model" + << endl + << "% 4th column: number of " + "the parameter in derivative" + << endl + << "% 5th column: value of " + "the Hessian term" + << endl + << "% g3p [#first_order_g3_terms by 6] double Jacobian matrix of derivatives of " + "g3 (dynamic 3rd derivs) with respect to the parameters;" + << endl + << "% rows: respective " + "derivative term" + << endl + << "% 1st column: equation " + "number of the term appearing" + << endl + << "% 2nd column: column " + "number of first variable in g3 of the dynamic model" + << endl + << "% 3rd column: column " + "number of second variable in g3 of the dynamic model" + << endl + << "% 4th column: column " + "number of third variable in g3 of the dynamic model" + << endl + << "% 5th column: number of " + "the parameter in derivative" + << endl + << "% 6th column: value of " + "the Hessian term" + << endl + << "%" << endl + << "%" << endl + << "% Warning : this file is generated automatically by Dynare" << endl + << "% from model file (.mod)" << endl + << endl + << "T = NaN(" << params_derivs_temporary_terms_idxs.size() << ",1);" << endl + << tt_output.str() << "rp = zeros(" << equations.size() << ", " + << symbol_table.param_nbr() << ");" << endl + << rp_output.str() << "gp = zeros(" << equations.size() << ", " + << getJacobianColsNbr(false) << ", " << symbol_table.param_nbr() << ");" << endl + << gp_output.str() << "if nargout >= 3" << endl + << "rpp = zeros(" << params_derivatives.at({0, 2}).size() << ",4);" << endl + << rpp_output.str() << "gpp = zeros(" << params_derivatives.at({1, 2}).size() << ",5);" + << endl + << gpp_output.str() << "end" << endl + << "if nargout >= 5" << endl + << "hp = zeros(" << params_derivatives.at({2, 1}).size() << ",5);" << endl + << hp_output.str() << "end" << endl + << "if nargout >= 6" << endl + << "g3p = zeros(" << params_derivatives.at({3, 1}).size() << ",6);" << endl + << g3p_output.str() << "end" << endl + << "end" << endl; paramsDerivsFile.close(); } else @@ -793,25 +884,24 @@ DynamicModel::writeParamsDerivativesFile(const string &basename) const << "function dynamic_params_derivs(y, x, params, steady_state, it_," << "ss_param_deriv, ss_param_2nd_deriv)" << endl << "@inbounds begin" << endl - << tt_output.str() - << "rp = zeros(" << equations.size() << ", " + << tt_output.str() << "rp = zeros(" << equations.size() << ", " << symbol_table.param_nbr() << ");" << endl - << rp_output.str() - << "gp = zeros(" << equations.size() << ", " << getJacobianColsNbr(false) << ", " << symbol_table.param_nbr() << ");" << endl - << gp_output.str() - << "rpp = zeros(" << params_derivatives.at({ 0, 2 }).size() << ",4);" << endl - << rpp_output.str() - << "gpp = zeros(" << params_derivatives.at({ 1, 2 }).size() << ",5);" << endl - << gpp_output.str() - << "hp = zeros(" << params_derivatives.at({ 2, 1 }).size() << ",5);" << endl - << hp_output.str() - << "g3p = zeros(" << params_derivatives.at({ 3, 1 }).size() << ",6);" << endl - << g3p_output.str() - << "end" << endl + << rp_output.str() << "gp = zeros(" << equations.size() << ", " + << getJacobianColsNbr(false) << ", " << symbol_table.param_nbr() << ");" << endl + << gp_output.str() << "rpp = zeros(" << params_derivatives.at({0, 2}).size() << ",4);" + << endl + << rpp_output.str() << "gpp = zeros(" << params_derivatives.at({1, 2}).size() << ",5);" + << endl + << gpp_output.str() << "hp = zeros(" << params_derivatives.at({2, 1}).size() << ",5);" + << endl + << hp_output.str() << "g3p = zeros(" << params_derivatives.at({3, 1}).size() << ",6);" + << endl + << g3p_output.str() << "end" << endl << "return (rp, gp, rpp, gpp, hp, g3p)" << endl << "end" << endl; - writeToFileIfModified(output, filesystem::path{basename} / "model" / "julia" / "DynamicParamsDerivs.jl"); + writeToFileIfModified(output, filesystem::path {basename} / "model" / "julia" + / "DynamicParamsDerivs.jl"); } } diff --git a/src/DynareMain.cc b/src/DynareMain.cc index e16c7697..67aefdb9 100644 --- a/src/DynareMain.cc +++ b/src/DynareMain.cc @@ -17,24 +17,24 @@ * along with Dynare. If not, see . */ -#include -#include -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include +#include +#include #include #include -#include "ParsingDriver.hh" -#include "ExtendedPreprocessorTypes.hh" #include "ConfigFile.hh" +#include "ExtendedPreprocessorTypes.hh" #include "ModFile.hh" +#include "ParsingDriver.hh" /* Prototype for the function that handles the macro-expansion of the .mod file Splitting this out was necessary because ParsingDriver.hh and macro/Driver.hh can't be @@ -42,21 +42,27 @@ Function can be found in: MacroExpandModFile.cc */ -stringstream -macroExpandModFile(const filesystem::path &filename, const istream &modfile, - bool debug, bool save_macro, filesystem::path save_macro_file, bool line_macro, - const vector> &defines, - vector paths); +stringstream macroExpandModFile(const filesystem::path& filename, const istream& modfile, + bool debug, bool save_macro, filesystem::path save_macro_file, + bool line_macro, const vector>& defines, + vector paths); void 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] [parallel_test] [parallel_use_psexec=true|false]" - << " [-D[=]] [-I/path] [nostrict] [stochastic] [fast] [minimal_workspace] [compute_xrefs] [output=second|third] [language=matlab|julia]" - << " [params_derivs_order=0|1|2] [transform_unary_ops] [exclude_eqs=] [include_eqs=]" - << " [json=parse|check|transform|compute] [jsonstdout] [onlyjson] [jsonderivsimple] [nopathchange] [nopreprocessoroutput]" - << " [mexext=] [matlabroot=] [onlymodel] [notime] [use_dll] [nocommutativity]" + 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] " + "[parallel_test] [parallel_use_psexec=true|false]" + << " [-D[=]] [-I/path] [nostrict] [stochastic] [fast] [minimal_workspace] " + "[compute_xrefs] [output=second|third] [language=matlab|julia]" + << " [params_derivs_order=0|1|2] [transform_unary_ops] " + "[exclude_eqs=] [include_eqs=]" + << " [json=parse|check|transform|compute] [jsonstdout] [onlyjson] [jsonderivsimple] " + "[nopathchange] [nopreprocessoroutput]" + << " [mexext=] [matlabroot=] [onlymodel] [notime] [use_dll] " + "[nocommutativity]" << endl; exit(EXIT_FAILURE); } @@ -65,23 +71,22 @@ usage() the input stream afterwards). This function should be kept in sync with the one with the same name in matlab/dynare.m */ vector -parse_options_line(istream &modfile) +parse_options_line(istream& modfile) { vector options; string first_nonempty_line; - regex pat{R"(^\s*//\s*--\+\s*options:([^\+]*)\+--)"}; + regex pat {R"(^\s*//\s*--\+\s*options:([^\+]*)\+--)"}; smatch matches; while (getline(modfile, first_nonempty_line)) if (!first_nonempty_line.empty()) { - if (regex_search(first_nonempty_line, matches, pat) - && matches.size() > 1 && matches[1].matched) + if (regex_search(first_nonempty_line, matches, pat) && matches.size() > 1 + && matches[1].matched) { - regex pat2{R"([^,\s]+)"}; - string s{matches[1]}; - for (sregex_iterator p(s.begin(), s.end(), pat2); - p != sregex_iterator{}; ++p) + regex pat2 {R"([^,\s]+)"}; + string s {matches[1]}; + for (sregex_iterator p(s.begin(), s.end(), pat2); p != sregex_iterator {}; ++p) options.push_back(p->str()); } break; @@ -93,7 +98,7 @@ parse_options_line(istream &modfile) } int -main(int argc, char **argv) +main(int argc, char** argv) { /* Redirect stderr to stdout. @@ -140,7 +145,8 @@ main(int argc, char **argv) filesystem::path parallel_config_file; bool parallel = false; string cluster_name; - bool parallel_follower_open_mode = false; // Must be the same default as in matlab/default_option_values.m + bool parallel_follower_open_mode + = false; // Must be the same default as in matlab/default_option_values.m bool parallel_test = false; bool parallel_use_psexec = true; // Must be the same default as in matlab/default_option_values.m bool nostrict = false; @@ -153,12 +159,12 @@ main(int argc, char **argv) string exclude_eqs, include_eqs; vector> defines; vector paths; - OutputType output_mode{OutputType::standard}; - JsonOutputPointType json{JsonOutputPointType::nojson}; - JsonFileOutputType json_output_mode{JsonFileOutputType::file}; + OutputType output_mode {OutputType::standard}; + JsonOutputPointType json {JsonOutputPointType::nojson}; + JsonFileOutputType json_output_mode {JsonFileOutputType::file}; bool onlyjson = false; bool jsonderivsimple = false; - LanguageOutputType language{LanguageOutputType::matlab}; + LanguageOutputType language {LanguageOutputType::matlab}; string mexext; filesystem::path matlabroot; bool onlymodel = false; @@ -289,9 +295,8 @@ main(int argc, char **argv) usage(); } - if (auto equal_index = s.find('='); - equal_index != string::npos) - defines.emplace_back(s.substr(2, equal_index-2), s.substr(equal_index+1)); + if (auto equal_index = s.find('='); equal_index != string::npos) + defines.emplace_back(s.substr(2, equal_index - 2), s.substr(equal_index + 1)); else defines.emplace_back(s.substr(2), "true"); } @@ -411,7 +416,7 @@ main(int argc, char **argv) cerr << "Incorrect syntax for matlabroot option" << endl; usage(); } - matlabroot = filesystem::path{s.substr(11)}; + matlabroot = filesystem::path {s.substr(11)}; } else if (s == "onlymodel") onlymodel = true; @@ -431,7 +436,7 @@ main(int argc, char **argv) cout << "Starting preprocessing of the model file ..." << endl; // Determine root of Dynare installation - const filesystem::path argv0{argv[0]}; + const filesystem::path argv0 {argv[0]}; // Normal case: binary is in preprocessor/dynare-preprocessor(.exe)? filesystem::path dynareroot = argv0.parent_path().parent_path(); if (argv0.filename().stem() == "dynare_m") @@ -445,7 +450,7 @@ main(int argc, char **argv) const string basename {filename.stem().string()}; // Forbid some basenames, since they will cause trouble (see preprocessor#62) - set forbidden_basenames = { "T", "y", "x", "params", "steady_state", "it_", "true" }; + set forbidden_basenames = {"T", "y", "x", "params", "steady_state", "it_", "true"}; if (forbidden_basenames.contains(basename)) { cerr << "ERROR: Please use another name for your .mod file. The one you have chosen (" @@ -456,22 +461,23 @@ 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); + 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(); // 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_file.getIncludePaths()) paths.emplace_back(it); /* * Macro-expand MOD file */ - stringstream macro_output = - macroExpandModFile(filename, modfile, debug, save_macro, move(save_macro_file), line_macro, - defines, move(paths)); + stringstream macro_output + = macroExpandModFile(filename, modfile, debug, save_macro, move(save_macro_file), line_macro, + defines, move(paths)); if (only_macro) return EXIT_SUCCESS; @@ -503,8 +509,8 @@ main(int argc, char **argv) } if (mod_file->use_dll) - ModelTree::initializeMEXCompilationWorkers(max(jthread::hardware_concurrency(), 1U), - dynareroot, mexext); + ModelTree::initializeMEXCompilationWorkers(max(jthread::hardware_concurrency(), 1U), dynareroot, + mexext); if (json == JsonOutputPointType::parsing) mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson); @@ -515,7 +521,8 @@ main(int argc, char **argv) mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson); // Perform transformations on the model (creation of auxiliary vars and equations) - mod_file->transformPass(nostrict, stochastic, compute_xrefs || json == JsonOutputPointType::transformpass, + mod_file->transformPass(nostrict, stochastic, + compute_xrefs || json == JsonOutputPointType::transformpass, transform_unary_ops, exclude_eqs, include_eqs); if (json == JsonOutputPointType::transformpass) mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson); @@ -533,8 +540,8 @@ 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, compute_xrefs, - mexext, matlabroot, onlymodel, gui, notime); + nointeractive, config_file, check_model_changes, minimal_workspace, + compute_xrefs, mexext, matlabroot, onlymodel, gui, notime); /* Ensures that workers are not destroyed before they finish compiling. Also ensures that the preprocessor final message is printed after the end of diff --git a/src/EquationTags.cc b/src/EquationTags.cc index f980d438..db8e1c2e 100644 --- a/src/EquationTags.cc +++ b/src/EquationTags.cc @@ -19,63 +19,62 @@ #include "EquationTags.hh" -#include #include +#include #include set -EquationTags::getEqnsByKey(const string &key) const +EquationTags::getEqnsByKey(const string& key) const { set retval; - for (const auto & [eqn, tags] : eqn_tags) + for (const auto& [eqn, tags] : eqn_tags) if (tags.contains(key)) retval.insert(eqn); return retval; } set -EquationTags::getEqnsByTag(const string &key, const string &value) const +EquationTags::getEqnsByTag(const string& key, const string& value) const { set retval; - for (const auto & [eqn, tags] : eqn_tags) + for (const auto& [eqn, tags] : eqn_tags) if (auto tmp = tags.find(key); tmp != tags.end() && tmp->second == value) retval.insert(eqn); return retval; } optional -EquationTags::getEqnByTag(const string &key, const string &value) const +EquationTags::getEqnByTag(const string& key, const string& value) const { - for (const auto & [eqn, tags] : eqn_tags) + for (const auto& [eqn, tags] : eqn_tags) if (auto tmp = tags.find(key); tmp != tags.end() && tmp->second == value) return eqn; return nullopt; } set -EquationTags::getEqnsByTags(const map &tags_selected) const +EquationTags::getEqnsByTags(const map& tags_selected) const { set retval; - for (const auto &[eqn, tags] : eqn_tags) + for (const auto& [eqn, tags] : eqn_tags) { - for (const auto &[key, value] : tags_selected) + for (const auto& [key, value] : tags_selected) if (auto tmp = tags.find(key); tmp == tags.end() || tmp->second != value) goto next_eq; retval.insert(eqn); - next_eq: - ; + next_eq:; } return retval; } void -EquationTags::erase(const set &eqns, const map &old_eqn_num_2_new) +EquationTags::erase(const set& eqns, const map& old_eqn_num_2_new) { for (int eqn : eqns) eqn_tags.erase(eqn); - for (const auto & [oldeqn, neweqn] : old_eqn_num_2_new) - for (auto & [eqn, tags] : eqn_tags) + for (const auto& [oldeqn, neweqn] : old_eqn_num_2_new) + for (auto& [eqn, tags] : eqn_tags) if (eqn == oldeqn) { auto tmp = eqn_tags.extract(eqn); @@ -85,38 +84,35 @@ EquationTags::erase(const set &eqns, const map &old_eqn_num_2_new } void -EquationTags::writeCheckSumInfo(ostream &output) const +EquationTags::writeCheckSumInfo(ostream& output) const { - for (const auto & [eqn, tags] : eqn_tags) - for (const auto & [key, value] : tags) - output << " " << eqn + 1 - << key << " " << value << endl; + for (const auto& [eqn, tags] : eqn_tags) + for (const auto& [key, value] : tags) + output << " " << eqn + 1 << key << " " << value << endl; } void -EquationTags::writeOutput(ostream &output) const +EquationTags::writeOutput(ostream& output) const { output << "M_.equations_tags = {" << endl; - for (const auto & [eqn, tags] : eqn_tags) - for (const auto & [key, value] : tags) - output << " " << eqn + 1 << " , '" - << key << "' , '" << value << "' ;" << endl; + for (const auto& [eqn, tags] : eqn_tags) + for (const auto& [key, value] : tags) + output << " " << eqn + 1 << " , '" << key << "' , '" << value << "' ;" << endl; output << "};" << endl; } void -EquationTags::writeLatexOutput(ostream &output, int eqn) const +EquationTags::writeLatexOutput(ostream& output, int eqn) const { if (!eqn_tags.contains(eqn)) return; - auto escape_special_latex_symbols = [](string str) - { - const regex special_latex_chars (R"([&%$#_{}])"); - const regex backslash (R"(\\)"); - const regex tilde (R"(~)"); - const regex carrot (R"(\^)"); - const regex textbackslash (R"(\\textbackslash)"); + auto escape_special_latex_symbols = [](string str) { + const regex special_latex_chars(R"([&%$#_{}])"); + const regex backslash(R"(\\)"); + const regex tilde(R"(~)"); + const regex carrot(R"(\^)"); + const regex textbackslash(R"(\\textbackslash)"); str = regex_replace(str, backslash, R"(\textbackslash)"); str = regex_replace(str, special_latex_chars, R"(\$&)"); str = regex_replace(str, carrot, R"(\^{})"); @@ -125,8 +121,7 @@ EquationTags::writeLatexOutput(ostream &output, int eqn) const }; output << R"(\noindent[)"; - for (bool wrote_eq_tag {false}; - const auto & [key, value] : eqn_tags.at(eqn)) + for (bool wrote_eq_tag {false}; const auto& [key, value] : eqn_tags.at(eqn)) { if (exchange(wrote_eq_tag, true)) output << ", "; @@ -139,14 +134,13 @@ EquationTags::writeLatexOutput(ostream &output, int eqn) const } void -EquationTags::writeJsonAST(ostream &output, int eqn) const +EquationTags::writeJsonAST(ostream& output, int eqn) const { if (!eqn_tags.contains(eqn)) return; output << R"(, "tags": {)"; - for (bool wroteFirst {false}; - const auto &[key, value] : eqn_tags.at(eqn)) + for (bool wroteFirst {false}; const auto& [key, value] : eqn_tags.at(eqn)) { if (exchange(wroteFirst, true)) output << ", "; diff --git a/src/EquationTags.hh b/src/EquationTags.hh index 75321d96..7025146c 100644 --- a/src/EquationTags.hh +++ b/src/EquationTags.hh @@ -21,9 +21,9 @@ #define _EQUATION_TAGS_HH #include +#include #include #include -#include using namespace std; @@ -31,13 +31,14 @@ class EquationTags { private: map> eqn_tags; + public: // Add multiple equation tags for the given equation void add(int eqn, map tags) { if (eqn_tags.contains(eqn)) - eqn_tags[eqn].insert(move_iterator{tags.begin()}, move_iterator{tags.end()}); + eqn_tags[eqn].insert(move_iterator {tags.begin()}, move_iterator {tags.end()}); else eqn_tags[eqn] = move(tags); } @@ -58,7 +59,7 @@ public: //! Erase tags for given equations, using old_eqn_num_2_new as the mapping //! to use for the remaining equation numbers - void erase(const set &eqns, const map &old_eqn_num_2_new); + void erase(const set& eqns, const map& old_eqn_num_2_new); //! Various functions to get info from equation tags //! Get equation tags for a given equation @@ -71,20 +72,20 @@ public: } //! Get equations that have the given key - set getEqnsByKey(const string &key) const; + set getEqnsByKey(const string& key) const; //! Get equations that have the given key and value - set getEqnsByTag(const string &key, const string &value) const; + set getEqnsByTag(const string& key, const string& value) const; //! Get the first equation that has the given key and value - optional getEqnByTag(const string &key, const string &value) const; + optional getEqnByTag(const string& key, const string& value) const; // Get equations that have all the given keys and values (seen as a conjunction) - set getEqnsByTags(const map &tags_selected) const; + set getEqnsByTags(const map& tags_selected) const; //! Get the tag value given the equation number and key optional - getTagValueByEqnAndKey(int eqn, const string &key) const + getTagValueByEqnAndKey(int eqn, const string& key) const { if (auto it = eqn_tags.find(eqn); it != eqn_tags.end()) if (auto it2 = it->second.find(key); it2 != it->second.end()) @@ -101,24 +102,24 @@ public: //! Returns true if equation tag with key and value exists bool - exists(const string &key, const string &value) const + exists(const string& key, const string& value) const { return getEqnByTag(key, value).has_value(); } //! Returns true if equation tag with key exists for a given equation bool - exists(int eqn, const string &key) const + exists(int eqn, const string& key) const { auto it = eqn_tags.find(eqn); return it != eqn_tags.end() && it->second.contains(key); } //! Various functions to write equation tags - void writeCheckSumInfo(ostream &output) const; - void writeOutput(ostream &output) const; - void writeLatexOutput(ostream &output, int eqn) const; - void writeJsonAST(ostream &output, int eq) const; + void writeCheckSumInfo(ostream& output) const; + void writeOutput(ostream& output) const; + void writeLatexOutput(ostream& output, int eqn) const; + void writeJsonAST(ostream& output, int eq) const; }; #endif diff --git a/src/ExprNode.cc b/src/ExprNode.cc index c3e80d94..de8309d9 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -17,20 +17,20 @@ * along with Dynare. If not, see . */ -#include #include #include #include -#include +#include #include -#include #include +#include +#include -#include "ExprNode.hh" #include "DataTree.hh" +#include "ExprNode.hh" #include "ModFile.hh" -ExprNode::ExprNode(DataTree &datatree_arg, int idx_arg) : datatree{datatree_arg}, idx{idx_arg} +ExprNode::ExprNode(DataTree& datatree_arg, int idx_arg) : datatree {datatree_arg}, idx {idx_arg} { } @@ -56,9 +56,9 @@ ExprNode::getDerivative(int deriv_id) } expr_t -ExprNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables, - unordered_map> &non_null_chain_rule_derivatives, - unordered_map> &cache) +ExprNode::getChainRuleDerivative(int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) { if (!non_null_chain_rule_derivatives.contains(this)) prepareForChainRuleDerivation(recursive_variables, non_null_chain_rule_derivatives); @@ -68,10 +68,8 @@ ExprNode::getChainRuleDerivative(int deriv_id, const map &r return datatree.Zero; // If derivative is in the cache, return that value - if (auto it = cache.find(this); - it != cache.end()) - if (auto it2 = it->second.find(deriv_id); - it2 != it->second.end()) + if (auto it = cache.find(this); it != cache.end()) + if (auto it2 = it->second.find(deriv_id); it2 != it->second.end()) return it2->second; auto r = computeChainRuleDerivative(deriv_id, recursive_variables, @@ -84,14 +82,14 @@ ExprNode::getChainRuleDerivative(int deriv_id, const map &r int ExprNode::precedence([[maybe_unused]] ExprNodeOutputType output_type, - [[maybe_unused]] const temporary_terms_t &temporary_terms) const + [[maybe_unused]] const temporary_terms_t& temporary_terms) const { // For a constant, a variable, or a unary op, the precedence is maximal return 100; } int -ExprNode::precedenceJson([[maybe_unused]] const temporary_terms_t &temporary_terms) const +ExprNode::precedenceJson([[maybe_unused]] const temporary_terms_t& temporary_terms) const { // For a constant, a variable, or a unary op, the precedence is maximal return 100; @@ -105,7 +103,7 @@ ExprNode::cost([[maybe_unused]] int cost, [[maybe_unused]] bool is_matlab) const } int -ExprNode::cost([[maybe_unused]] const vector>> &blocks_temporary_terms, +ExprNode::cost([[maybe_unused]] const vector>>& blocks_temporary_terms, [[maybe_unused]] bool is_matlab) const { // For a terminal node, the cost is null @@ -113,7 +111,7 @@ ExprNode::cost([[maybe_unused]] const vector>> &blo } int -ExprNode::cost([[maybe_unused]] const map, unordered_set> &temp_terms_map, +ExprNode::cost([[maybe_unused]] const map, unordered_set>& temp_terms_map, [[maybe_unused]] bool is_matlab) const { // For a terminal node, the cost is null @@ -121,11 +119,11 @@ ExprNode::cost([[maybe_unused]] const map, unordered_set> } bool -ExprNode::checkIfTemporaryTermThenWrite(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs) const +ExprNode::checkIfTemporaryTermThenWrite(ostream& output, ExprNodeOutputType output_type, + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs) const { - if (!temporary_terms.contains(const_cast(this))) + if (!temporary_terms.contains(const_cast(this))) return false; /* If we are inside a steady_state() operator, the temporary terms do not @@ -135,26 +133,25 @@ ExprNode::checkIfTemporaryTermThenWrite(ostream &output, ExprNodeOutputType outp if (isSteadyStateOperatorOutput(output_type)) return false; - auto it2 = temporary_terms_idxs.find(const_cast(this)); + auto it2 = temporary_terms_idxs.find(const_cast(this)); // It is the responsibility of the caller to ensure that all temporary terms have their index assert(it2 != temporary_terms_idxs.end()); output << "T" << LEFT_ARRAY_SUBSCRIPT(output_type) - << it2->second + ARRAY_SUBSCRIPT_OFFSET(output_type) - << RIGHT_ARRAY_SUBSCRIPT(output_type); + << it2->second + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type); return true; } bool -ExprNode::checkIfTemporaryTermThenWriteBytecode(BytecodeWriter &code_file, - ExprNodeBytecodeOutputType output_type, - const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs) const +ExprNode::checkIfTemporaryTermThenWriteBytecode( + BytecodeWriter& code_file, ExprNodeBytecodeOutputType output_type, + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs) const { - if (!temporary_terms.contains(const_cast(this))) + if (!temporary_terms.contains(const_cast(this))) return false; - auto it2 = temporary_terms_idxs.find(const_cast(this)); + auto it2 = temporary_terms_idxs.find(const_cast(this)); // It is the responsibility of the caller to ensure that all temporary terms have their index assert(it2 != temporary_terms_idxs.end()); @@ -166,21 +163,21 @@ ExprNode::checkIfTemporaryTermThenWriteBytecode(BytecodeWriter &code_file, was initially not called with steady_dynamic=true). */ return false; case ExprNodeBytecodeOutputType::dynamicModel: - code_file << FLDT_{it2->second}; + code_file << FLDT_ {it2->second}; break; case ExprNodeBytecodeOutputType::staticModel: - code_file << FLDST_{it2->second}; + code_file << FLDST_ {it2->second}; break; case ExprNodeBytecodeOutputType::dynamicAssignmentLHS: case ExprNodeBytecodeOutputType::staticAssignmentLHS: - cerr << "ExprNode::checkIfTemporaryTermThenWriteBytecode: can't assign a temporary term" << endl; + cerr << "ExprNode::checkIfTemporaryTermThenWriteBytecode: can't assign a temporary term" + << endl; exit(EXIT_FAILURE); } return true; } - pair ExprNode::getLagEquivalenceClass() const { @@ -189,11 +186,11 @@ ExprNode::getLagEquivalenceClass() const if (index == numeric_limits::min()) index = 0; // If no variable in the expression, the equivalence class has size 1 - return { decreaseLeadsLags(index), index }; + return {decreaseLeadsLags(index), index}; } void -ExprNode::collectVariables(SymbolType type, set &result) const +ExprNode::collectVariables(SymbolType type, set& result) const { set> symbs_lags; collectDynamicVariables(type, symbs_lags); @@ -202,93 +199,99 @@ ExprNode::collectVariables(SymbolType type, set &result) const } void -ExprNode::collectEndogenous(set> &result) const +ExprNode::collectEndogenous(set>& result) const { set> symb_ids_and_lags; collectDynamicVariables(SymbolType::endogenous, symb_ids_and_lags); - for (const auto &[symb_id, lag] : symb_ids_and_lags) + for (const auto& [symb_id, lag] : symb_ids_and_lags) result.emplace(datatree.symbol_table.getTypeSpecificID(symb_id), lag); } void -ExprNode::computeTemporaryTerms([[maybe_unused]] const pair &derivOrder, - [[maybe_unused]] map, unordered_set> &temp_terms_map, - [[maybe_unused]] unordered_map>> &reference_count, - [[maybe_unused]] bool is_matlab) const +ExprNode::computeTemporaryTerms( + [[maybe_unused]] const pair& derivOrder, + [[maybe_unused]] map, unordered_set>& temp_terms_map, + [[maybe_unused]] unordered_map>>& reference_count, + [[maybe_unused]] bool is_matlab) const { // Nothing to do for a terminal node } void -ExprNode::computeBlockTemporaryTerms([[maybe_unused]] int blk, [[maybe_unused]] int eq, - [[maybe_unused]] vector>> &blocks_temporary_terms, - [[maybe_unused]] unordered_map> &reference_count) const +ExprNode::computeBlockTemporaryTerms( + [[maybe_unused]] int blk, [[maybe_unused]] int eq, + [[maybe_unused]] vector>>& blocks_temporary_terms, + [[maybe_unused]] unordered_map>& reference_count) const { // Nothing to do for a terminal node } void -ExprNode::writeOutput(ostream &output) const +ExprNode::writeOutput(ostream& output) const { writeOutput(output, ExprNodeOutputType::matlabOutsideModel, {}, {}); } void -ExprNode::writeOutput(ostream &output, ExprNodeOutputType output_type) const +ExprNode::writeOutput(ostream& output, ExprNodeOutputType output_type) const { writeOutput(output, output_type, {}, {}); } void -ExprNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs) const +ExprNode::writeOutput(ostream& output, ExprNodeOutputType output_type, + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs) const { writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, {}); } void -ExprNode::writeExternalFunctionOutput([[maybe_unused]] ostream &output, - [[maybe_unused]] ExprNodeOutputType output_type, - [[maybe_unused]] const temporary_terms_t &temporary_terms, - [[maybe_unused]] const temporary_terms_idxs_t &temporary_terms_idxs, - [[maybe_unused]] deriv_node_temp_terms_t &tef_terms) const +ExprNode::writeExternalFunctionOutput( + [[maybe_unused]] ostream& output, [[maybe_unused]] ExprNodeOutputType output_type, + [[maybe_unused]] const temporary_terms_t& temporary_terms, + [[maybe_unused]] const temporary_terms_idxs_t& temporary_terms_idxs, + [[maybe_unused]] deriv_node_temp_terms_t& tef_terms) const { // Nothing to do } void -ExprNode::writeJsonExternalFunctionOutput([[maybe_unused]] vector &efout, - [[maybe_unused]] const temporary_terms_t &temporary_terms, - [[maybe_unused]] deriv_node_temp_terms_t &tef_terms, +ExprNode::writeJsonExternalFunctionOutput([[maybe_unused]] vector& efout, + [[maybe_unused]] const temporary_terms_t& temporary_terms, + [[maybe_unused]] deriv_node_temp_terms_t& tef_terms, [[maybe_unused]] bool isdynamic) const { // Nothing to do } void -ExprNode::writeBytecodeExternalFunctionOutput([[maybe_unused]] BytecodeWriter &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, - [[maybe_unused]] deriv_node_temp_terms_t &tef_terms) const +ExprNode::writeBytecodeExternalFunctionOutput( + [[maybe_unused]] BytecodeWriter& 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, + [[maybe_unused]] deriv_node_temp_terms_t& tef_terms) const { // Nothing to do } -VariableNode * -ExprNode::createEndoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector &neweqs) const +VariableNode* +ExprNode::createEndoLeadAuxiliaryVarForMyself(subst_table_t& subst_table, + vector& neweqs) const { int n = maxEndoLead(); assert(n >= 2); - if (auto it = subst_table.find(this); - it != subst_table.end()) - return const_cast(it->second); + if (auto it = subst_table.find(this); it != subst_table.end()) + return const_cast(it->second); - expr_t substexpr = decreaseLeadsLags(n-1); - int lag = n-2; + expr_t substexpr = decreaseLeadsLags(n - 1); + int lag = n - 2; // Each iteration tries to create an auxvar such that auxvar(+1)=expr(-lag) - // At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an auxvar) equivalent to expr(-lag-1) (resp. expr(-lag)) + // At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an auxvar) + // equivalent to expr(-lag-1) (resp. expr(-lag)) while (lag >= 0) { expr_t orig_expr = decreaseLeadsLags(lag); @@ -297,33 +300,34 @@ ExprNode::createEndoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector int symb_id = datatree.symbol_table.addEndoLeadAuxiliaryVar(orig_expr->idx, substexpr); neweqs.push_back(datatree.AddEqual(datatree.AddVariable(symb_id, 0), substexpr)); substexpr = datatree.AddVariable(symb_id, +1); - assert(dynamic_cast(substexpr)); - subst_table[orig_expr] = dynamic_cast(substexpr); + assert(dynamic_cast(substexpr)); + subst_table[orig_expr] = dynamic_cast(substexpr); } else - substexpr = const_cast(it->second); + substexpr = const_cast(it->second); lag--; } - return dynamic_cast(substexpr); + return dynamic_cast(substexpr); } -VariableNode * -ExprNode::createExoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector &neweqs) const +VariableNode* +ExprNode::createExoLeadAuxiliaryVarForMyself(subst_table_t& subst_table, + vector& neweqs) const { int n = maxExoLead(); assert(n >= 1); - if (auto it = subst_table.find(this); - it != subst_table.end()) - return const_cast(it->second); + if (auto it = subst_table.find(this); it != subst_table.end()) + return const_cast(it->second); expr_t substexpr = decreaseLeadsLags(n); - int lag = n-1; + int lag = n - 1; // Each iteration tries to create an auxvar such that auxvar(+1)=expr(-lag) - // At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an auxvar) equivalent to expr(-lag-1) (resp. expr(-lag)) + // At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an auxvar) + // equivalent to expr(-lag-1) (resp. expr(-lag)) while (lag >= 0) { expr_t orig_expr = decreaseLeadsLags(lag); @@ -332,16 +336,16 @@ ExprNode::createExoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector< int symb_id = datatree.symbol_table.addExoLeadAuxiliaryVar(orig_expr->idx, substexpr); neweqs.push_back(datatree.AddEqual(datatree.AddVariable(symb_id, 0), substexpr)); substexpr = datatree.AddVariable(symb_id, +1); - assert(dynamic_cast(substexpr)); - subst_table[orig_expr] = dynamic_cast(substexpr); + assert(dynamic_cast(substexpr)); + subst_table[orig_expr] = dynamic_cast(substexpr); } else - substexpr = const_cast(it->second); + substexpr = const_cast(it->second); lag--; } - return dynamic_cast(substexpr); + return dynamic_cast(substexpr); } bool @@ -351,33 +355,33 @@ ExprNode::isNumConstNodeEqualTo([[maybe_unused]] double value) const } bool -ExprNode::isVariableNodeEqualTo([[maybe_unused]] SymbolType type_arg, [[maybe_unused]] int variable_id, +ExprNode::isVariableNodeEqualTo([[maybe_unused]] SymbolType type_arg, + [[maybe_unused]] int variable_id, [[maybe_unused]] int lag_arg) const { return false; } void -ExprNode::fillErrorCorrectionRow(int eqn, - const vector &nontarget_lhs, - const vector &target_lhs, - map, expr_t> &A0, - map, expr_t> &A0star) const +ExprNode::fillErrorCorrectionRow(int eqn, const vector& nontarget_lhs, + const vector& target_lhs, map, expr_t>& A0, + map, expr_t>& A0star) const { vector> terms; decomposeAdditiveTerms(terms, 1); - for (const auto &[term, sign] : terms) + for (const auto& [term, sign] : terms) { int speed_of_adjustment_param; vector, double>> error_linear_combination; try { - tie(speed_of_adjustment_param, error_linear_combination) = term->matchParamTimesLinearCombinationOfVariables(); - for (auto &[var_id, lag, param_id, constant] : error_linear_combination) + tie(speed_of_adjustment_param, error_linear_combination) + = term->matchParamTimesLinearCombinationOfVariables(); + for (auto& [var_id, lag, param_id, constant] : error_linear_combination) constant *= sign; // Update sign of constants } - catch (MatchFailureException &e) + catch (MatchFailureException& e) { /* FIXME: we should not just skip them, but rather verify that they are autoregressive terms or residuals (probably by merging the two "fill" procedures) */ @@ -387,37 +391,46 @@ ExprNode::fillErrorCorrectionRow(int eqn, /* Verify that all variables belong to the error-correction term. FIXME: same remark as above about skipping terms. */ bool not_ec = false; - for (const auto &[var_id, lag, param_id, constant] : error_linear_combination) + for (const auto& [var_id, lag, param_id, constant] : error_linear_combination) { auto [orig_var_id, orig_lag] = datatree.symbol_table.unrollDiffLeadLagChain(var_id, lag); - not_ec = not_ec || (find(target_lhs.begin(), target_lhs.end(), orig_var_id) == target_lhs.end() - && find(nontarget_lhs.begin(), nontarget_lhs.end(), orig_var_id) == nontarget_lhs.end()); + not_ec = not_ec + || (find(target_lhs.begin(), target_lhs.end(), orig_var_id) == target_lhs.end() + && find(nontarget_lhs.begin(), nontarget_lhs.end(), orig_var_id) + == nontarget_lhs.end()); } if (not_ec) continue; // Now fill the matrices - for (const auto &[var_id, lag, param_id, constant] : error_linear_combination) + for (const auto& [var_id, lag, param_id, constant] : error_linear_combination) if (auto [orig_vid, orig_lag] = datatree.symbol_table.unrollDiffLeadLagChain(var_id, lag); find(target_lhs.begin(), target_lhs.end(), orig_vid) == target_lhs.end()) { if (orig_lag != -1) { - cerr << "ERROR in trend component model: variables in the error correction term should appear with a lag of -1" << endl; + cerr << "ERROR in trend component model: variables in the error correction term " + "should appear with a lag of -1" + << endl; exit(EXIT_FAILURE); } // This an LHS variable, so fill A0 if (constant != 1) { - cerr << "ERROR in trend component model: LHS variable should not appear with a multiplicative constant in error correction term" << endl; + cerr << "ERROR in trend component model: LHS variable should not appear with a " + "multiplicative constant in error correction term" + << endl; exit(EXIT_FAILURE); } if (*param_id) { - cerr << "ERROR in trend component model: spurious parameter in error correction term" << endl; + cerr + << "ERROR in trend component model: spurious parameter in error correction term" + << endl; exit(EXIT_FAILURE); } - int colidx = static_cast(distance(nontarget_lhs.begin(), find(nontarget_lhs.begin(), nontarget_lhs.end(), orig_vid))); + int colidx = static_cast(distance( + nontarget_lhs.begin(), find(nontarget_lhs.begin(), nontarget_lhs.end(), orig_vid))); if (A0.contains({eqn, colidx})) { cerr << "ExprNode::fillErrorCorrection: Error filling A0 matrix: " @@ -429,12 +442,13 @@ ExprNode::fillErrorCorrectionRow(int eqn, else { // This is a target, so fill A0star - int colidx = static_cast(distance(target_lhs.begin(), find(target_lhs.begin(), target_lhs.end(), orig_vid))); + int colidx = static_cast( + distance(target_lhs.begin(), find(target_lhs.begin(), target_lhs.end(), orig_vid))); expr_t e = datatree.AddTimes(datatree.AddVariable(speed_of_adjustment_param), datatree.AddPossiblyNegativeConstant(-constant)); if (param_id) e = datatree.AddTimes(e, datatree.AddVariable(*param_id)); - if (pair coor{eqn, colidx}; A0star.contains(coor)) + if (pair coor {eqn, colidx}; A0star.contains(coor)) A0star[coor] = datatree.AddPlus(e, A0star[coor]); else A0star[coor] = e; @@ -443,11 +457,11 @@ ExprNode::fillErrorCorrectionRow(int eqn, } void -ExprNode::matchMatchedMoment([[maybe_unused]] vector &symb_ids, - [[maybe_unused]] vector &lags, - [[maybe_unused]] vector &powers) const +ExprNode::matchMatchedMoment([[maybe_unused]] vector& symb_ids, + [[maybe_unused]] vector& lags, + [[maybe_unused]] vector& powers) const { - throw MatchFailureException{"Unsupported expression"}; + throw MatchFailureException {"Unsupported expression"}; } bool @@ -469,10 +483,8 @@ ExprNode::hasExogenous() const return !symbs_lags.empty(); } - -NumConstNode::NumConstNode(DataTree &datatree_arg, int idx_arg, int id_arg) : - ExprNode{datatree_arg, idx_arg}, - id{id_arg} +NumConstNode::NumConstNode(DataTree& datatree_arg, int idx_arg, int id_arg) : + ExprNode {datatree_arg, idx_arg}, id {id_arg} { } @@ -490,10 +502,11 @@ NumConstNode::prepareForDerivation() } void -NumConstNode::prepareForChainRuleDerivation([[maybe_unused]] const map &recursive_variables, - unordered_map> &non_null_chain_rule_derivatives) const +NumConstNode::prepareForChainRuleDerivation( + [[maybe_unused]] const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const { - non_null_chain_rule_derivatives.try_emplace(const_cast(this)); + non_null_chain_rule_derivatives.try_emplace(const_cast(this)); } expr_t @@ -503,29 +516,28 @@ NumConstNode::computeDerivative([[maybe_unused]] int deriv_id) } void -NumConstNode::writeOutput(ostream &output, ExprNodeOutputType 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 +NumConstNode::writeOutput(ostream& output, ExprNodeOutputType 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 { if (!checkIfTemporaryTermThenWrite(output, output_type, temporary_terms, temporary_terms_idxs)) output << datatree.num_constants.get(id); } void -NumConstNode::writeJsonAST(ostream &output) const +NumConstNode::writeJsonAST(ostream& output) const { output << R"({"node_type" : "NumConstNode", "value" : )"; output << std::stof(datatree.num_constants.get(id)) << "}"; } void -NumConstNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - [[maybe_unused]] const deriv_node_temp_terms_t &tef_terms, +NumConstNode::writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms, + [[maybe_unused]] const deriv_node_temp_terms_t& tef_terms, [[maybe_unused]] bool isdynamic) const { - if (temporary_terms.contains(const_cast(this))) + if (temporary_terms.contains(const_cast(this))) output << "T" << idx; else output << datatree.num_constants.get(id); @@ -538,24 +550,25 @@ NumConstNode::containsExternalFunction() const } double -NumConstNode::eval([[maybe_unused]] const eval_context_t &eval_context) const noexcept(false) +NumConstNode::eval([[maybe_unused]] const eval_context_t& eval_context) const noexcept(false) { return datatree.num_constants.getDouble(id); } void -NumConstNode::writeBytecodeOutput(BytecodeWriter &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 +NumConstNode::writeBytecodeOutput(BytecodeWriter& 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 { assert(!isAssignmentLHSBytecodeOutput(output_type)); - if (!checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) - code_file << FLDC_{datatree.num_constants.getDouble(id)}; + if (!checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, + temporary_terms_idxs)) + code_file << FLDC_ {datatree.num_constants.getDouble(id)}; } void -NumConstNode::collectVARLHSVariable([[maybe_unused]] set &result) const +NumConstNode::collectVARLHSVariable([[maybe_unused]] set& result) const { cerr << "ERROR: you can only have variables or unary ops on LHS of VAR" << endl; exit(EXIT_FAILURE); @@ -563,18 +576,19 @@ NumConstNode::collectVARLHSVariable([[maybe_unused]] set &result) const void NumConstNode::collectDynamicVariables([[maybe_unused]] SymbolType type_arg, - [[maybe_unused]] set> &result) const + [[maybe_unused]] set>& result) const { } void -NumConstNode::computeSubExprContainingVariable([[maybe_unused]] int symb_id, [[maybe_unused]] int lag, - [[maybe_unused]] set &contain_var) const +NumConstNode::computeSubExprContainingVariable([[maybe_unused]] int symb_id, + [[maybe_unused]] int lag, + [[maybe_unused]] set& contain_var) const { } -BinaryOpNode * -NumConstNode::normalizeEquationHelper([[maybe_unused]] const set &contain_var, +BinaryOpNode* +NumConstNode::normalizeEquationHelper([[maybe_unused]] const set& contain_var, [[maybe_unused]] expr_t rhs) const { cerr << "NumConstNode::normalizeEquationHelper: this should not happen" << endl; @@ -582,27 +596,28 @@ NumConstNode::normalizeEquationHelper([[maybe_unused]] const set &contai } expr_t -NumConstNode::computeChainRuleDerivative([[maybe_unused]] int deriv_id, - [[maybe_unused]] const map &recursive_variables, - [[maybe_unused]] unordered_map> &non_null_chain_rule_derivatives, - [[maybe_unused]] unordered_map> &cache) +NumConstNode::computeChainRuleDerivative( + [[maybe_unused]] int deriv_id, + [[maybe_unused]] const map& recursive_variables, + [[maybe_unused]] unordered_map>& non_null_chain_rule_derivatives, + [[maybe_unused]] unordered_map>& cache) { return datatree.Zero; } expr_t -NumConstNode::toStatic(DataTree &static_datatree) const +NumConstNode::toStatic(DataTree& static_datatree) const { return static_datatree.AddNonNegativeConstant(datatree.num_constants.get(id)); } void -NumConstNode::computeXrefs([[maybe_unused]] EquationInfo &ei) const +NumConstNode::computeXrefs([[maybe_unused]] EquationInfo& ei) const { } expr_t -NumConstNode::clone(DataTree &alt_datatree) const +NumConstNode::clone(DataTree& alt_datatree) const { return alt_datatree.AddNonNegativeConstant(datatree.num_constants.get(id)); } @@ -652,11 +667,11 @@ NumConstNode::maxLagWithDiffsExpanded() const expr_t NumConstNode::undiff() const { - return const_cast(this); + return const_cast(this); } int -NumConstNode::VarMaxLag([[maybe_unused]] const set &lhs_lag_equiv) const +NumConstNode::VarMaxLag([[maybe_unused]] const set& lhs_lag_equiv) const { return 0; } @@ -664,78 +679,80 @@ NumConstNode::VarMaxLag([[maybe_unused]] const set &lhs_lag_equiv) const expr_t NumConstNode::decreaseLeadsLags([[maybe_unused]] int n) const { - return const_cast(this); + return const_cast(this); } expr_t NumConstNode::decreaseLeadsLagsPredeterminedVariables() const { - return const_cast(this); + return const_cast(this); } expr_t -NumConstNode::substituteEndoLeadGreaterThanTwo([[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs, +NumConstNode::substituteEndoLeadGreaterThanTwo([[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs, [[maybe_unused]] bool deterministic_model) const { - return const_cast(this); + return const_cast(this); } expr_t -NumConstNode::substituteEndoLagGreaterThanTwo([[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs) const +NumConstNode::substituteEndoLagGreaterThanTwo([[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs) const { - return const_cast(this); + return const_cast(this); } expr_t -NumConstNode::substituteExoLead([[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs, +NumConstNode::substituteExoLead([[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs, [[maybe_unused]] bool deterministic_model) const { - return const_cast(this); + return const_cast(this); } expr_t -NumConstNode::substituteExoLag([[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs) const +NumConstNode::substituteExoLag([[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs) const { - return const_cast(this); + return const_cast(this); } expr_t -NumConstNode::substituteExpectation([[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs, +NumConstNode::substituteExpectation([[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs, [[maybe_unused]] bool partial_information_model) const { - return const_cast(this); + return const_cast(this); } expr_t NumConstNode::substituteAdl() const { - return const_cast(this); + return const_cast(this); } expr_t NumConstNode::substituteModelLocalVariables() const { - return const_cast(this); + return const_cast(this); } expr_t -NumConstNode::substituteVarExpectation([[maybe_unused]] const map &subst_table) const +NumConstNode::substituteVarExpectation( + [[maybe_unused]] const map& subst_table) const { - return const_cast(this); + return const_cast(this); } void -NumConstNode::findDiffNodes([[maybe_unused]] lag_equivalence_table_t &nodes) const +NumConstNode::findDiffNodes([[maybe_unused]] lag_equivalence_table_t& nodes) const { } void -NumConstNode::findUnaryOpNodesForAuxVarCreation([[maybe_unused]] lag_equivalence_table_t &nodes) const +NumConstNode::findUnaryOpNodesForAuxVarCreation( + [[maybe_unused]] lag_equivalence_table_t& nodes) const { } @@ -746,41 +763,41 @@ NumConstNode::findTargetVariable([[maybe_unused]] int lhs_symb_id) const } expr_t -NumConstNode::substituteDiff([[maybe_unused]] const lag_equivalence_table_t &nodes, - [[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs) const +NumConstNode::substituteDiff([[maybe_unused]] const lag_equivalence_table_t& nodes, + [[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs) const { - return const_cast(this); + return const_cast(this); } expr_t -NumConstNode::substituteUnaryOpNodes([[maybe_unused]] const lag_equivalence_table_t &nodes, - [[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs) const +NumConstNode::substituteUnaryOpNodes([[maybe_unused]] const lag_equivalence_table_t& nodes, + [[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs) const { - return const_cast(this); + return const_cast(this); } expr_t -NumConstNode::substitutePacExpectation([[maybe_unused]] const string &name, +NumConstNode::substitutePacExpectation([[maybe_unused]] const string& name, [[maybe_unused]] expr_t subexpr) { - return const_cast(this); + return const_cast(this); } expr_t -NumConstNode::substitutePacTargetNonstationary([[maybe_unused]] const string &name, +NumConstNode::substitutePacTargetNonstationary([[maybe_unused]] const string& name, [[maybe_unused]] expr_t subexpr) { - return const_cast(this); + return const_cast(this); } expr_t -NumConstNode::differentiateForwardVars([[maybe_unused]] const vector &subset, - [[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs) const +NumConstNode::differentiateForwardVars([[maybe_unused]] const vector& subset, + [[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs) const { - return const_cast(this); + return const_cast(this); } bool @@ -801,13 +818,13 @@ NumConstNode::isVariableNodeEqualTo([[maybe_unused]] SymbolType type_arg, } bool -NumConstNode::containsPacExpectation([[maybe_unused]] const string &pac_model_name) const +NumConstNode::containsPacExpectation([[maybe_unused]] const string& pac_model_name) const { return false; } bool -NumConstNode::containsPacTargetNonstationary([[maybe_unused]] const string &pac_model_name) const +NumConstNode::containsPacTargetNonstationary([[maybe_unused]] const string& pac_model_name) const { return false; } @@ -815,20 +832,20 @@ NumConstNode::containsPacTargetNonstationary([[maybe_unused]] const string &pac_ expr_t NumConstNode::replaceTrendVar() const { - return const_cast(this); + return const_cast(this); } expr_t NumConstNode::detrend([[maybe_unused]] int symb_id, [[maybe_unused]] bool log_trend, [[maybe_unused]] expr_t trend) const { - return const_cast(this); + return const_cast(this); } expr_t -NumConstNode::removeTrendLeadLag([[maybe_unused]] const map &trend_symbols_map) const +NumConstNode::removeTrendLeadLag([[maybe_unused]] const map& trend_symbols_map) const { - return const_cast(this); + return const_cast(this); } bool @@ -844,26 +861,27 @@ NumConstNode::isParamTimesEndogExpr() const } expr_t -NumConstNode::replaceVarsInEquation([[maybe_unused]] map &table) const +NumConstNode::replaceVarsInEquation([[maybe_unused]] map& table) const { - return const_cast(this); + return const_cast(this); } expr_t NumConstNode::substituteLogTransform([[maybe_unused]] int orig_symb_id, [[maybe_unused]] int aux_symb_id) const { - return const_cast(this); + return const_cast(this); } -VariableNode::VariableNode(DataTree &datatree_arg, int idx_arg, int symb_id_arg, int lag_arg) : - ExprNode{datatree_arg, idx_arg}, - symb_id{symb_id_arg}, - lag{lag_arg} +VariableNode::VariableNode(DataTree& datatree_arg, int idx_arg, int symb_id_arg, int lag_arg) : + ExprNode {datatree_arg, idx_arg}, symb_id {symb_id_arg}, lag {lag_arg} { - // It makes sense to allow a lead/lag on parameters: during steady state calibration, endogenous and parameters can be swapped + // It makes sense to allow a lead/lag on parameters: during steady state calibration, endogenous + // and parameters can be swapped assert(get_type() != SymbolType::externalFunction - && (lag == 0 || (get_type() != SymbolType::modelLocalVariable && get_type() != SymbolType::modFileLocalVariable))); + && (lag == 0 + || (get_type() != SymbolType::modelLocalVariable + && get_type() != SymbolType::modFileLocalVariable))); } void @@ -905,29 +923,31 @@ VariableNode::prepareForDerivation() exit(EXIT_FAILURE); case SymbolType::excludedVariable: cerr << "VariableNode::prepareForDerivation: impossible case: " - << "You are trying to derive a variable that has been excluded via model_remove/var_remove/include_eqs/exclude_eqs: " + << "You are trying to derive a variable that has been excluded via " + "model_remove/var_remove/include_eqs/exclude_eqs: " << datatree.symbol_table.getName(symb_id) << endl; exit(EXIT_FAILURE); } } void -VariableNode::prepareForChainRuleDerivation(const map &recursive_variables, - unordered_map> &non_null_chain_rule_derivatives) const +VariableNode::prepareForChainRuleDerivation( + const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const { - if (non_null_chain_rule_derivatives.contains(const_cast(this))) + if (non_null_chain_rule_derivatives.contains(const_cast(this))) return; switch (get_type()) { case SymbolType::endogenous: { - set &nnd { non_null_chain_rule_derivatives[const_cast(this)] }; + set& nnd {non_null_chain_rule_derivatives[const_cast(this)]}; int my_deriv_id {datatree.getDerivID(symb_id, lag)}; - if (auto it = recursive_variables.find(my_deriv_id); - it != recursive_variables.end()) + if (auto it = recursive_variables.find(my_deriv_id); it != recursive_variables.end()) { - it->second->arg2->prepareForChainRuleDerivation(recursive_variables, non_null_chain_rule_derivatives); + it->second->arg2->prepareForChainRuleDerivation(recursive_variables, + non_null_chain_rule_derivatives); nnd = non_null_chain_rule_derivatives.at(it->second->arg2); } nnd.insert(my_deriv_id); @@ -942,14 +962,14 @@ VariableNode::prepareForChainRuleDerivation(const map &recu case SymbolType::statementDeclaredVariable: case SymbolType::unusedEndogenous: // Those variables are never derived using chain rule - non_null_chain_rule_derivatives.try_emplace(const_cast(this)); + non_null_chain_rule_derivatives.try_emplace(const_cast(this)); break; case SymbolType::modelLocalVariable: { - expr_t def { datatree.getLocalVariable(symb_id) }; + expr_t def {datatree.getLocalVariable(symb_id)}; // Non null derivatives are those of the value of the model local variable def->prepareForChainRuleDerivation(recursive_variables, non_null_chain_rule_derivatives); - non_null_chain_rule_derivatives.emplace(const_cast(this), + non_null_chain_rule_derivatives.emplace(const_cast(this), non_null_chain_rule_derivatives.at(def)); } break; @@ -1010,7 +1030,7 @@ VariableNode::containsExternalFunction() const } void -VariableNode::writeJsonAST(ostream &output) const +VariableNode::writeJsonAST(ostream& output) const { output << R"({"node_type" : "VariableNode", )" << R"("name" : ")" << datatree.symbol_table.getName(symb_id) << R"(", "type" : ")"; @@ -1060,12 +1080,11 @@ VariableNode::writeJsonAST(ostream &output) const } void -VariableNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - [[maybe_unused]] const deriv_node_temp_terms_t &tef_terms, +VariableNode::writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms, + [[maybe_unused]] const deriv_node_temp_terms_t& tef_terms, bool isdynamic) const { - if (temporary_terms.contains(const_cast(this))) + if (temporary_terms.contains(const_cast(this))) { output << "T" << idx; return; @@ -1077,10 +1096,10 @@ VariableNode::writeJsonOutput(ostream &output, } void -VariableNode::writeOutput(ostream &output, ExprNodeOutputType 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 +VariableNode::writeOutput(ostream& output, ExprNodeOutputType 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 { auto type = get_type(); if (checkIfTemporaryTermThenWrite(output, output_type, temporary_terms, temporary_terms_idxs)) @@ -1092,7 +1111,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output << R"(\bar)"; output << "{" << datatree.symbol_table.getTeXName(symb_id) << "}"; if (output_type == ExprNodeOutputType::latexDynamicModel - && (type == SymbolType::endogenous || type == SymbolType::exogenous || type == SymbolType::exogenousDet || type == SymbolType::trend || type == SymbolType::logTrend)) + && (type == SymbolType::endogenous || type == SymbolType::exogenous + || type == SymbolType::exogenousDet || type == SymbolType::trend + || type == SymbolType::logTrend)) { output << "_{t"; if (lag != 0) @@ -1106,8 +1127,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, return; } - auto juliaTimeDataFrameHelper = [&] - { + auto juliaTimeDataFrameHelper = [&] { if (lag != 0) output << "lag("; output << "ds." << datatree.symbol_table.getName(symb_id); @@ -1125,9 +1145,11 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case SymbolType::parameter: if (int tsid = datatree.symbol_table.getTypeSpecificID(symb_id); output_type == ExprNodeOutputType::matlabOutsideModel) - output << "M_.params" << "(" << tsid + 1 << ")"; + output << "M_.params" + << "(" << tsid + 1 << ")"; else - output << "params" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << "params" << LEFT_ARRAY_SUBSCRIPT(output_type) + << tsid + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case SymbolType::modelLocalVariable: @@ -1135,7 +1157,8 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, || output_type == ExprNodeOutputType::CDynamicSteadyStateOperator) { output << "("; - datatree.getLocalVariable(symb_id)->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + datatree.getLocalVariable(symb_id)->writeOutput(output, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); output << ")"; } else @@ -1149,8 +1172,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, break; case SymbolType::endogenous: - switch (int tsid = datatree.symbol_table.getTypeSpecificID(symb_id); - output_type) + switch (int tsid = datatree.symbol_table.getTypeSpecificID(symb_id); output_type) { case ExprNodeOutputType::juliaDynamicModel: case ExprNodeOutputType::juliaSparseDynamicModel: @@ -1158,8 +1180,11 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case ExprNodeOutputType::matlabSparseDynamicModel: case ExprNodeOutputType::CDynamicModel: case ExprNodeOutputType::CSparseDynamicModel: - i = datatree.getJacobianCol(datatree.getDerivID(symb_id, lag), isSparseModelOutput(output_type)) + ARRAY_SUBSCRIPT_OFFSET(output_type); - output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); + i = datatree.getJacobianCol(datatree.getDerivID(symb_id, lag), + isSparseModelOutput(output_type)) + + ARRAY_SUBSCRIPT_OFFSET(output_type); + output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i + << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case ExprNodeOutputType::CStaticModel: case ExprNodeOutputType::CSparseStaticModel: @@ -1168,26 +1193,30 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case ExprNodeOutputType::matlabStaticModel: case ExprNodeOutputType::matlabSparseStaticModel: i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type); - output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i + << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case ExprNodeOutputType::matlabOutsideModel: output << "oo_.steady_state(" << tsid + 1 << ")"; break; case ExprNodeOutputType::juliaDynamicSteadyStateOperator: case ExprNodeOutputType::matlabDynamicSteadyStateOperator: - output << "steady_state" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + 1 << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << "steady_state" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + 1 + << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case ExprNodeOutputType::CDynamicSteadyStateOperator: output << "steady_state[" << tsid << "]"; break; case ExprNodeOutputType::juliaSteadyStateFile: case ExprNodeOutputType::steadyStateFile: - output << "ys_" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + 1 << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << "ys_" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + 1 + << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case ExprNodeOutputType::matlabDseries: output << "ds." << datatree.symbol_table.getName(symb_id); if (lag != 0) - output << LEFT_ARRAY_SUBSCRIPT(output_type) << lag << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << LEFT_ARRAY_SUBSCRIPT(output_type) << lag + << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case ExprNodeOutputType::juliaTimeDataFrame: juliaTimeDataFrameHelper(); @@ -1215,22 +1244,22 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case ExprNodeOutputType::juliaDynamicModel: case ExprNodeOutputType::matlabDynamicModel: if (lag > 0) - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_+" << lag << ", " << i + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_+" << lag << ", " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); else if (lag < 0) - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_" << lag << ", " << i + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_" << lag << ", " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); else - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_, " << i + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_, " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case ExprNodeOutputType::CDynamicModel: if (lag == 0) - output << "x[it_+" << i << "*nb_row_x]"; + output << "x[it_+" << i << "*nb_row_x]"; else if (lag > 0) - output << "x[it_+" << lag << "+" << i << "*nb_row_x]"; + output << "x[it_+" << lag << "+" << i << "*nb_row_x]"; else - output << "x[it_" << lag << "+" << i << "*nb_row_x]"; + output << "x[it_" << lag << "+" << i << "*nb_row_x]"; break; case ExprNodeOutputType::juliaSparseDynamicModel: case ExprNodeOutputType::matlabSparseDynamicModel: @@ -1243,23 +1272,26 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case ExprNodeOutputType::juliaSparseStaticModel: case ExprNodeOutputType::matlabStaticModel: case ExprNodeOutputType::matlabSparseStaticModel: - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i + << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case ExprNodeOutputType::matlabOutsideModel: assert(lag == 0); - output << "oo_.exo_steady_state(" << i << ")"; + output << "oo_.exo_steady_state(" << i << ")"; break; case ExprNodeOutputType::matlabDynamicSteadyStateOperator: - output << "oo_.exo_steady_state(" << i << ")"; + output << "oo_.exo_steady_state(" << i << ")"; break; case ExprNodeOutputType::juliaSteadyStateFile: case ExprNodeOutputType::steadyStateFile: - output << "exo_" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << "exo_" << LEFT_ARRAY_SUBSCRIPT(output_type) << i + << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case ExprNodeOutputType::matlabDseries: output << "ds." << datatree.symbol_table.getName(symb_id); if (lag != 0) - output << LEFT_ARRAY_SUBSCRIPT(output_type) << lag << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << LEFT_ARRAY_SUBSCRIPT(output_type) << lag + << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case ExprNodeOutputType::juliaTimeDataFrame: juliaTimeDataFrameHelper(); @@ -1278,28 +1310,29 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, break; case SymbolType::exogenousDet: - i = datatree.symbol_table.getTypeSpecificID(symb_id) + datatree.symbol_table.exo_nbr() + ARRAY_SUBSCRIPT_OFFSET(output_type); + i = datatree.symbol_table.getTypeSpecificID(symb_id) + datatree.symbol_table.exo_nbr() + + ARRAY_SUBSCRIPT_OFFSET(output_type); switch (output_type) { case ExprNodeOutputType::juliaDynamicModel: case ExprNodeOutputType::matlabDynamicModel: if (lag > 0) - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_+" << lag << ", " << i + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_+" << lag << ", " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); else if (lag < 0) - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_" << lag << ", " << i + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_" << lag << ", " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); else - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_, " << i + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_, " << i << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case ExprNodeOutputType::CDynamicModel: if (lag == 0) - output << "x[it_+" << i << "*nb_row_x]"; + output << "x[it_+" << i << "*nb_row_x]"; else if (lag > 0) - output << "x[it_+" << lag << "+" << i << "*nb_row_x]"; + output << "x[it_+" << lag << "+" << i << "*nb_row_x]"; else - output << "x[it_" << lag << "+" << i << "*nb_row_x]"; + output << "x[it_" << lag << "+" << i << "*nb_row_x]"; break; case ExprNodeOutputType::juliaSparseDynamicModel: case ExprNodeOutputType::matlabSparseDynamicModel: @@ -1312,23 +1345,28 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case ExprNodeOutputType::juliaSparseStaticModel: case ExprNodeOutputType::matlabStaticModel: case ExprNodeOutputType::matlabSparseStaticModel: - output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << "x" << LEFT_ARRAY_SUBSCRIPT(output_type) << i + << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case ExprNodeOutputType::matlabOutsideModel: assert(lag == 0); - output << "oo_.exo_det_steady_state(" << datatree.symbol_table.getTypeSpecificID(symb_id) + 1 << ")"; + output << "oo_.exo_det_steady_state(" + << datatree.symbol_table.getTypeSpecificID(symb_id) + 1 << ")"; break; case ExprNodeOutputType::matlabDynamicSteadyStateOperator: - output << "oo_.exo_det_steady_state(" << datatree.symbol_table.getTypeSpecificID(symb_id) + 1 << ")"; + output << "oo_.exo_det_steady_state(" + << datatree.symbol_table.getTypeSpecificID(symb_id) + 1 << ")"; break; case ExprNodeOutputType::juliaSteadyStateFile: case ExprNodeOutputType::steadyStateFile: - output << "exo_" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << "exo_" << LEFT_ARRAY_SUBSCRIPT(output_type) << i + << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case ExprNodeOutputType::matlabDseries: output << "ds." << datatree.symbol_table.getName(symb_id); if (lag != 0) - output << LEFT_ARRAY_SUBSCRIPT(output_type) << lag << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << LEFT_ARRAY_SUBSCRIPT(output_type) << lag + << RIGHT_ARRAY_SUBSCRIPT(output_type); break; case ExprNodeOutputType::juliaTimeDataFrame: juliaTimeDataFrameHelper(); @@ -1365,7 +1403,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, } break; case SymbolType::unusedEndogenous: - cerr << "ERROR: You cannot use an endogenous variable in an expression if that variable has not been used in the model block." << endl; + cerr << "ERROR: You cannot use an endogenous variable in an expression if that variable has " + "not been used in the model block." + << endl; exit(EXIT_FAILURE); case SymbolType::externalFunction: case SymbolType::trend: @@ -1378,7 +1418,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, } double -VariableNode::eval(const eval_context_t &eval_context) const noexcept(false) +VariableNode::eval(const eval_context_t& eval_context) const noexcept(false) { if (get_type() == SymbolType::modelLocalVariable) return datatree.getLocalVariable(symb_id)->eval(eval_context); @@ -1391,46 +1431,48 @@ VariableNode::eval(const eval_context_t &eval_context) const noexcept(false) } void -VariableNode::writeBytecodeOutput(BytecodeWriter &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 +VariableNode::writeBytecodeOutput(BytecodeWriter& 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 { - if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, + temporary_terms_idxs)) return; auto type = get_type(); if (type == SymbolType::modelLocalVariable || type == SymbolType::modFileLocalVariable) - datatree.getLocalVariable(symb_id)->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + datatree.getLocalVariable(symb_id)->writeBytecodeOutput(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); else { int tsid = datatree.symbol_table.getTypeSpecificID(symb_id); switch (output_type) { case ExprNodeBytecodeOutputType::dynamicModel: - code_file << FLDV_{type, tsid, lag}; + code_file << FLDV_ {type, tsid, lag}; break; case ExprNodeBytecodeOutputType::staticModel: - code_file << FLDSV_{type, tsid}; + code_file << FLDSV_ {type, tsid}; break; case ExprNodeBytecodeOutputType::dynamicSteadyStateOperator: - code_file << FLDVS_{type, tsid}; + code_file << FLDVS_ {type, tsid}; break; case ExprNodeBytecodeOutputType::dynamicAssignmentLHS: - code_file << FSTPV_{type, tsid, lag}; + code_file << FSTPV_ {type, tsid, lag}; break; case ExprNodeBytecodeOutputType::staticAssignmentLHS: - code_file << FSTPSV_{type, tsid}; + code_file << FSTPSV_ {type, tsid}; break; } } } void -VariableNode::collectVARLHSVariable(set &result) const +VariableNode::collectVARLHSVariable(set& result) const { if (get_type() == SymbolType::endogenous && lag == 0) - result.insert(const_cast(this)); + result.insert(const_cast(this)); else { cerr << "ERROR: you can only have endogenous variables or unary ops on LHS of VAR" << endl; @@ -1439,7 +1481,7 @@ VariableNode::collectVARLHSVariable(set &result) const } void -VariableNode::collectDynamicVariables(SymbolType type_arg, set> &result) const +VariableNode::collectDynamicVariables(SymbolType type_arg, set>& result) const { if (get_type() == type_arg) result.emplace(symb_id, lag); @@ -1448,31 +1490,33 @@ VariableNode::collectDynamicVariables(SymbolType type_arg, set> & } void -VariableNode::computeSubExprContainingVariable(int symb_id_arg, int lag_arg, set &contain_var) const +VariableNode::computeSubExprContainingVariable(int symb_id_arg, int lag_arg, + set& contain_var) const { if (symb_id == symb_id_arg && lag == lag_arg) contain_var.insert(const_cast(this)); if (get_type() == SymbolType::modelLocalVariable) - datatree.getLocalVariable(symb_id)->computeSubExprContainingVariable(symb_id_arg, lag_arg, contain_var); + datatree.getLocalVariable(symb_id)->computeSubExprContainingVariable(symb_id_arg, lag_arg, + contain_var); } -BinaryOpNode * -VariableNode::normalizeEquationHelper(const set &contain_var, expr_t rhs) const +BinaryOpNode* +VariableNode::normalizeEquationHelper(const set& contain_var, expr_t rhs) const { - assert(contain_var.contains(const_cast(this))); + assert(contain_var.contains(const_cast(this))); if (get_type() == SymbolType::modelLocalVariable) return datatree.getLocalVariable(symb_id)->normalizeEquationHelper(contain_var, rhs); // This the LHS variable: we have finished the normalization - return datatree.AddEqual(const_cast(this), rhs); + return datatree.AddEqual(const_cast(this), rhs); } expr_t -VariableNode::computeChainRuleDerivative(int deriv_id, - const map &recursive_variables, - unordered_map> &non_null_chain_rule_derivatives, - unordered_map> &cache) +VariableNode::computeChainRuleDerivative( + int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) { switch (get_type()) { @@ -1486,18 +1530,18 @@ VariableNode::computeChainRuleDerivative(int deriv_id, [[fallthrough]]; case SymbolType::endogenous: case SymbolType::parameter: - if (int my_deriv_id {datatree.getDerivID(symb_id, lag)}; - deriv_id == my_deriv_id) + if (int my_deriv_id {datatree.getDerivID(symb_id, lag)}; deriv_id == my_deriv_id) return datatree.One; // If there is in the equation a recursive variable we could use a chaine rule derivation - else if (auto it = recursive_variables.find(my_deriv_id); - it != recursive_variables.end()) - return it->second->arg2->getChainRuleDerivative(deriv_id, recursive_variables, non_null_chain_rule_derivatives, cache); + else if (auto it = recursive_variables.find(my_deriv_id); it != recursive_variables.end()) + return it->second->arg2->getChainRuleDerivative(deriv_id, recursive_variables, + non_null_chain_rule_derivatives, cache); else return datatree.Zero; case SymbolType::modelLocalVariable: - return datatree.getLocalVariable(symb_id)->getChainRuleDerivative(deriv_id, recursive_variables, non_null_chain_rule_derivatives, cache); + return datatree.getLocalVariable(symb_id)->getChainRuleDerivative( + deriv_id, recursive_variables, non_null_chain_rule_derivatives, cache); case SymbolType::modFileLocalVariable: cerr << "modFileLocalVariable is not derivable" << endl; exit(EXIT_FAILURE); @@ -1517,13 +1561,13 @@ VariableNode::computeChainRuleDerivative(int deriv_id, } expr_t -VariableNode::toStatic(DataTree &static_datatree) const +VariableNode::toStatic(DataTree& static_datatree) const { return static_datatree.AddVariable(symb_id); } void -VariableNode::computeXrefs(EquationInfo &ei) const +VariableNode::computeXrefs(EquationInfo& ei) const { switch (get_type()) { @@ -1561,7 +1605,7 @@ VariableNode::get_type() const } expr_t -VariableNode::clone(DataTree &alt_datatree) const +VariableNode::clone(DataTree& alt_datatree) const { return alt_datatree.AddVariable(symb_id, lag); } @@ -1674,11 +1718,11 @@ VariableNode::maxLagWithDiffsExpanded() const expr_t VariableNode::undiff() const { - return const_cast(this); + return const_cast(this); } int -VariableNode::VarMaxLag(const set &lhs_lag_equiv) const +VariableNode::VarMaxLag(const set& lhs_lag_equiv) const { auto [lag_equiv_repr, index] = getLagEquivalenceClass(); if (lhs_lag_equiv.contains(lag_equiv_repr)) @@ -1692,7 +1736,7 @@ VariableNode::substituteAdl() const { /* Do not recurse into model-local variables definition, rather do it at the DynamicModel method level (see the comment there) */ - return const_cast(this); + return const_cast(this); } expr_t @@ -1701,27 +1745,27 @@ VariableNode::substituteModelLocalVariables() const if (get_type() == SymbolType::modelLocalVariable) return datatree.getLocalVariable(symb_id); - return const_cast(this); + return const_cast(this); } expr_t -VariableNode::substituteVarExpectation(const map &subst_table) const +VariableNode::substituteVarExpectation(const map& subst_table) const { if (get_type() == SymbolType::modelLocalVariable) return datatree.getLocalVariable(symb_id)->substituteVarExpectation(subst_table); - return const_cast(this); + return const_cast(this); } void -VariableNode::findDiffNodes(lag_equivalence_table_t &nodes) const +VariableNode::findDiffNodes(lag_equivalence_table_t& nodes) const { if (get_type() == SymbolType::modelLocalVariable) datatree.getLocalVariable(symb_id)->findDiffNodes(nodes); } void -VariableNode::findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const +VariableNode::findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t& nodes) const { if (get_type() == SymbolType::modelLocalVariable) datatree.getLocalVariable(symb_id)->findUnaryOpNodesForAuxVarCreation(nodes); @@ -1737,40 +1781,42 @@ VariableNode::findTargetVariable(int lhs_symb_id) const } expr_t -VariableNode::substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, - vector &neweqs) const +VariableNode::substituteDiff(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const { if (get_type() == SymbolType::modelLocalVariable) return datatree.getLocalVariable(symb_id)->substituteDiff(nodes, subst_table, neweqs); - return const_cast(this); + return const_cast(this); } expr_t -VariableNode::substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const +VariableNode::substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, + subst_table_t& subst_table, + vector& neweqs) const { if (get_type() == SymbolType::modelLocalVariable) return datatree.getLocalVariable(symb_id)->substituteUnaryOpNodes(nodes, subst_table, neweqs); - return const_cast(this); + return const_cast(this); } expr_t -VariableNode::substitutePacExpectation(const string &name, expr_t subexpr) +VariableNode::substitutePacExpectation(const string& name, expr_t subexpr) { if (get_type() == SymbolType::modelLocalVariable) return datatree.getLocalVariable(symb_id)->substitutePacExpectation(name, subexpr); - return const_cast(this); + return const_cast(this); } expr_t -VariableNode::substitutePacTargetNonstationary(const string &name, expr_t subexpr) +VariableNode::substitutePacTargetNonstationary(const string& name, expr_t subexpr) { if (get_type() == SymbolType::modelLocalVariable) return datatree.getLocalVariable(symb_id)->substitutePacTargetNonstationary(name, subexpr); - return const_cast(this); + return const_cast(this); } expr_t @@ -1783,11 +1829,11 @@ VariableNode::decreaseLeadsLags(int n) const case SymbolType::exogenousDet: case SymbolType::trend: case SymbolType::logTrend: - return datatree.AddVariable(symb_id, lag-n); + return datatree.AddVariable(symb_id, lag - n); case SymbolType::modelLocalVariable: return datatree.getLocalVariable(symb_id)->decreaseLeadsLags(n); default: - return const_cast(this); + return const_cast(this); } } @@ -1800,60 +1846,65 @@ VariableNode::decreaseLeadsLagsPredeterminedVariables() const if (datatree.symbol_table.isPredetermined(symb_id)) return decreaseLeadsLags(1); else - return const_cast(this); + return const_cast(this); } expr_t -VariableNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +VariableNode::substituteEndoLeadGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs, + bool deterministic_model) const { switch (get_type()) { case SymbolType::endogenous: if (lag <= 1) - return const_cast(this); + return const_cast(this); else return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs); case SymbolType::modelLocalVariable: if (expr_t value = datatree.getLocalVariable(symb_id); value->maxEndoLead() <= 1) - return const_cast(this); + return const_cast(this); else return value->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); default: - return const_cast(this); + return const_cast(this); } } expr_t -VariableNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const +VariableNode::substituteEndoLagGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs) const { - VariableNode *substexpr; + VariableNode* substexpr; int cur_lag; switch (get_type()) { case SymbolType::endogenous: if (lag >= -1) - return const_cast(this); + return const_cast(this); if (auto it = subst_table.find(this); it != subst_table.end()) - return const_cast(it->second); + return const_cast(it->second); substexpr = datatree.AddVariable(symb_id, -1); cur_lag = -2; // Each iteration tries to create an auxvar such that auxvar(-1)=curvar(cur_lag) - // At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an auxvar) equivalent to curvar(cur_lag+1) (resp. curvar(cur_lag)) + // At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an + // auxvar) equivalent to curvar(cur_lag+1) (resp. curvar(cur_lag)) while (cur_lag >= lag) { - VariableNode *orig_expr = datatree.AddVariable(symb_id, cur_lag); + VariableNode* orig_expr = datatree.AddVariable(symb_id, cur_lag); if (auto it = subst_table.find(orig_expr); it == subst_table.end()) { - int aux_symb_id = datatree.symbol_table.addEndoLagAuxiliaryVar(symb_id, cur_lag+1, substexpr); + int aux_symb_id + = datatree.symbol_table.addEndoLagAuxiliaryVar(symb_id, cur_lag + 1, substexpr); neweqs.push_back(datatree.AddEqual(datatree.AddVariable(aux_symb_id, 0), substexpr)); substexpr = datatree.AddVariable(aux_symb_id, -1); subst_table[orig_expr] = substexpr; } else - substexpr = const_cast(it->second); + substexpr = const_cast(it->second); cur_lag--; } @@ -1861,65 +1912,68 @@ VariableNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector case SymbolType::modelLocalVariable: if (expr_t value = datatree.getLocalVariable(symb_id); value->maxEndoLag() <= 1) - return const_cast(this); + return const_cast(this); else return value->substituteEndoLagGreaterThanTwo(subst_table, neweqs); default: - return const_cast(this); + return const_cast(this); } } expr_t -VariableNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +VariableNode::substituteExoLead(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const { switch (get_type()) { case SymbolType::exogenous: if (lag <= 0) - return const_cast(this); + return const_cast(this); else return createExoLeadAuxiliaryVarForMyself(subst_table, neweqs); case SymbolType::modelLocalVariable: if (expr_t value = datatree.getLocalVariable(symb_id); value->maxExoLead() == 0) - return const_cast(this); + return const_cast(this); else return value->substituteExoLead(subst_table, neweqs, deterministic_model); default: - return const_cast(this); + return const_cast(this); } } expr_t -VariableNode::substituteExoLag(subst_table_t &subst_table, vector &neweqs) const +VariableNode::substituteExoLag(subst_table_t& subst_table, vector& neweqs) const { - VariableNode *substexpr; + VariableNode* substexpr; int cur_lag; switch (get_type()) { case SymbolType::exogenous: if (lag >= 0) - return const_cast(this); + return const_cast(this); if (auto it = subst_table.find(this); it != subst_table.end()) - return const_cast(it->second); + return const_cast(it->second); substexpr = datatree.AddVariable(symb_id, 0); cur_lag = -1; // Each iteration tries to create an auxvar such that auxvar(-1)=curvar(cur_lag) - // At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an auxvar) equivalent to curvar(cur_lag+1) (resp. curvar(cur_lag)) + // At the beginning (resp. end) of each iteration, substexpr is an expression (possibly an + // auxvar) equivalent to curvar(cur_lag+1) (resp. curvar(cur_lag)) while (cur_lag >= lag) { - VariableNode *orig_expr = datatree.AddVariable(symb_id, cur_lag); + VariableNode* orig_expr = datatree.AddVariable(symb_id, cur_lag); if (auto it = subst_table.find(orig_expr); it == subst_table.end()) { - int aux_symb_id = datatree.symbol_table.addExoLagAuxiliaryVar(symb_id, cur_lag+1, substexpr); + int aux_symb_id + = datatree.symbol_table.addExoLagAuxiliaryVar(symb_id, cur_lag + 1, substexpr); neweqs.push_back(datatree.AddEqual(datatree.AddVariable(aux_symb_id, 0), substexpr)); substexpr = datatree.AddVariable(aux_symb_id, -1); subst_table[orig_expr] = substexpr; } else - substexpr = const_cast(it->second); + substexpr = const_cast(it->second); cur_lag--; } @@ -1927,25 +1981,28 @@ VariableNode::substituteExoLag(subst_table_t &subst_table, vectormaxExoLag() == 0) - return const_cast(this); + return const_cast(this); else return value->substituteExoLag(subst_table, neweqs); default: - return const_cast(this); + return const_cast(this); } } expr_t -VariableNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const +VariableNode::substituteExpectation(subst_table_t& subst_table, vector& neweqs, + bool partial_information_model) const { if (get_type() == SymbolType::modelLocalVariable) - return datatree.getLocalVariable(symb_id)->substituteExpectation(subst_table, neweqs, partial_information_model); + return datatree.getLocalVariable(symb_id)->substituteExpectation(subst_table, neweqs, + partial_information_model); - return const_cast(this); + return const_cast(this); } expr_t -VariableNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const +VariableNode::differentiateForwardVars(const vector& subset, subst_table_t& subst_table, + vector& neweqs) const { switch (get_type()) { @@ -1953,18 +2010,20 @@ VariableNode::differentiateForwardVars(const vector &subset, subst_table assert(lag <= 1); if (lag <= 0 || (subset.size() > 0 - && find(subset.begin(), subset.end(), datatree.symbol_table.getName(symb_id)) == subset.end())) - return const_cast(this); + && find(subset.begin(), subset.end(), datatree.symbol_table.getName(symb_id)) + == subset.end())) + return const_cast(this); else { - VariableNode *diffvar; + VariableNode* diffvar; if (auto it = subst_table.find(this); it != subst_table.end()) - diffvar = const_cast(it->second); + diffvar = const_cast(it->second); else { expr_t substexpr = datatree.AddMinus(datatree.AddVariable(symb_id, 0), datatree.AddVariable(symb_id, -1)); - int aux_symb_id = datatree.symbol_table.addDiffForwardAuxiliaryVar(symb_id, 0, substexpr); + int aux_symb_id + = datatree.symbol_table.addDiffForwardAuxiliaryVar(symb_id, 0, substexpr); neweqs.push_back(datatree.AddEqual(datatree.AddVariable(aux_symb_id, 0), substexpr)); diffvar = datatree.AddVariable(aux_symb_id, 1); subst_table[this] = diffvar; @@ -1973,11 +2032,11 @@ VariableNode::differentiateForwardVars(const vector &subset, subst_table } case SymbolType::modelLocalVariable: if (expr_t value = datatree.getLocalVariable(symb_id); value->maxEndoLead() <= 0) - return const_cast(this); + return const_cast(this); else return value->differentiateForwardVars(subset, subst_table, neweqs); default: - return const_cast(this); + return const_cast(this); } } @@ -1990,14 +2049,15 @@ VariableNode::isNumConstNodeEqualTo([[maybe_unused]] double value) const bool VariableNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const { - if (get_type() == type_arg && datatree.symbol_table.getTypeSpecificID(symb_id) == variable_id && lag == lag_arg) + if (get_type() == type_arg && datatree.symbol_table.getTypeSpecificID(symb_id) == variable_id + && lag == lag_arg) return true; else return false; } bool -VariableNode::containsPacExpectation(const string &pac_model_name) const +VariableNode::containsPacExpectation(const string& pac_model_name) const { if (get_type() == SymbolType::modelLocalVariable) return datatree.getLocalVariable(symb_id)->containsPacExpectation(pac_model_name); @@ -2006,7 +2066,7 @@ VariableNode::containsPacExpectation(const string &pac_model_name) const } bool -VariableNode::containsPacTargetNonstationary(const string &pac_model_name) const +VariableNode::containsPacTargetNonstationary(const string& pac_model_name) const { if (get_type() == SymbolType::modelLocalVariable) return datatree.getLocalVariable(symb_id)->containsPacTargetNonstationary(pac_model_name); @@ -2025,7 +2085,7 @@ VariableNode::replaceTrendVar() const else if (get_type() == SymbolType::logTrend) return datatree.Zero; else - return const_cast(this); + return const_cast(this); } expr_t @@ -2035,21 +2095,21 @@ VariableNode::detrend(int symb_id, bool log_trend, expr_t trend) const return datatree.getLocalVariable(symb_id)->detrend(symb_id, log_trend, trend); if (this->symb_id != symb_id) - return const_cast(this); + return const_cast(this); if (log_trend) { if (lag == 0) - return datatree.AddPlus(const_cast(this), trend); + return datatree.AddPlus(const_cast(this), trend); else - return datatree.AddPlus(const_cast(this), trend->decreaseLeadsLags(-lag)); + return datatree.AddPlus(const_cast(this), trend->decreaseLeadsLags(-lag)); } else { if (lag == 0) - return datatree.AddTimes(const_cast(this), trend); + return datatree.AddTimes(const_cast(this), trend); else - return datatree.AddTimes(const_cast(this), trend->decreaseLeadsLags(-lag)); + return datatree.AddTimes(const_cast(this), trend->decreaseLeadsLags(-lag)); } } @@ -2063,13 +2123,13 @@ VariableNode::countDiffs() const } expr_t -VariableNode::removeTrendLeadLag(const map &trend_symbols_map) const +VariableNode::removeTrendLeadLag(const map& trend_symbols_map) const { if (get_type() == SymbolType::modelLocalVariable) return datatree.getLocalVariable(symb_id)->removeTrendLeadLag(trend_symbols_map); if ((get_type() != SymbolType::trend && get_type() != SymbolType::logTrend) || lag == 0) - return const_cast(this); + return const_cast(this); auto it = trend_symbols_map.find(symb_id); expr_t noTrendLeadLagNode = datatree.AddVariable(it->first); @@ -2082,29 +2142,33 @@ VariableNode::removeTrendLeadLag(const map &trend_symbols_map) cons if (log_trend) { for (int i = 1; i < lag; i++) - growthFactorSequence = datatree.AddPlus(growthFactorSequence, trend->decreaseLeadsLags(-1*(i+1))); + growthFactorSequence + = datatree.AddPlus(growthFactorSequence, trend->decreaseLeadsLags(-1 * (i + 1))); return datatree.AddPlus(noTrendLeadLagNode, growthFactorSequence); } else { for (int i = 1; i < lag; i++) - growthFactorSequence = datatree.AddTimes(growthFactorSequence, trend->decreaseLeadsLags(-1*(i+1))); + growthFactorSequence + = datatree.AddTimes(growthFactorSequence, trend->decreaseLeadsLags(-1 * (i + 1))); return datatree.AddTimes(noTrendLeadLagNode, growthFactorSequence); } } - else //get_lag < 0 + else // get_lag < 0 { expr_t growthFactorSequence = trend; if (log_trend) { for (int i = 1; i < abs(lag); i++) - growthFactorSequence = datatree.AddPlus(growthFactorSequence, trend->decreaseLeadsLags(i)); + growthFactorSequence + = datatree.AddPlus(growthFactorSequence, trend->decreaseLeadsLags(i)); return datatree.AddMinus(noTrendLeadLagNode, growthFactorSequence); } else { for (int i = 1; i < abs(lag); i++) - growthFactorSequence = datatree.AddTimes(growthFactorSequence, trend->decreaseLeadsLags(i)); + growthFactorSequence + = datatree.AddTimes(growthFactorSequence, trend->decreaseLeadsLags(i)); return datatree.AddDivide(noTrendLeadLagNode, growthFactorSequence); } } @@ -2129,25 +2193,27 @@ VariableNode::isParamTimesEndogExpr() const } expr_t -VariableNode::replaceVarsInEquation(map &table) const +VariableNode::replaceVarsInEquation(map& table) const { /* Do not recurse into model-local variables definitions, since MLVs are already handled by DynamicModel::simplifyEquations(). This is also necessary because of #65. */ - for (auto &it : table) + for (auto& it : table) if (it.first->symb_id == symb_id) return it.second; - return const_cast(this); + return const_cast(this); } void -VariableNode::matchMatchedMoment(vector &symb_ids, vector &lags, vector &powers) const +VariableNode::matchMatchedMoment(vector& symb_ids, vector& lags, + vector& powers) const { /* Used for simple expression outside model block, so no need to special-case model local variables */ if (get_type() != SymbolType::endogenous) - throw MatchFailureException{"Variable " + datatree.symbol_table.getName(symb_id) + " is not an endogenous"}; + throw MatchFailureException {"Variable " + datatree.symbol_table.getName(symb_id) + + " is not an endogenous"}; symb_ids.push_back(symb_id); lags.push_back(lag); @@ -2163,18 +2229,21 @@ VariableNode::substituteLogTransform(int orig_symb_id, int aux_symb_id) const if (symb_id == orig_symb_id) return datatree.AddExp(datatree.AddVariable(aux_symb_id, lag)); else - return const_cast(this); + return const_cast(this); } -UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, int idx_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, string adl_param_name_arg, vector adl_lags_arg) : - ExprNode{datatree_arg, idx_arg}, - arg{arg_arg}, - expectation_information_set{expectation_information_set_arg}, - param1_symb_id{param1_symb_id_arg}, - param2_symb_id{param2_symb_id_arg}, - op_code{op_code_arg}, - adl_param_name{move(adl_param_name_arg)}, - adl_lags{move(adl_lags_arg)} +UnaryOpNode::UnaryOpNode(DataTree& datatree_arg, int idx_arg, UnaryOpcode op_code_arg, + const expr_t arg_arg, int expectation_information_set_arg, + int param1_symb_id_arg, int param2_symb_id_arg, string adl_param_name_arg, + vector adl_lags_arg) : + ExprNode {datatree_arg, idx_arg}, + arg {arg_arg}, + expectation_information_set {expectation_information_set_arg}, + param1_symb_id {param1_symb_id_arg}, + param2_symb_id {param2_symb_id_arg}, + op_code {op_code_arg}, + adl_param_name {move(adl_param_name_arg)}, + adl_lags {move(adl_lags_arg)} { } @@ -2201,16 +2270,17 @@ UnaryOpNode::prepareForDerivation() } void -UnaryOpNode::prepareForChainRuleDerivation(const map &recursive_variables, - unordered_map> &non_null_chain_rule_derivatives) const +UnaryOpNode::prepareForChainRuleDerivation( + const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const { - if (non_null_chain_rule_derivatives.contains(const_cast(this))) + if (non_null_chain_rule_derivatives.contains(const_cast(this))) return; /* Non-null derivatives are those of the argument (except for STEADY_STATE in a dynamic context, in which case the potentially non-null derivatives are all the parameters) */ - set &nnd { non_null_chain_rule_derivatives[const_cast(this)] }; + set& nnd {non_null_chain_rule_derivatives[const_cast(this)]}; if ((op_code == UnaryOpcode::steadyState || op_code == UnaryOpcode::steadyStateParamDeriv || op_code == UnaryOpcode::steadyStateParam2ndDeriv) && datatree.isDynamic()) @@ -2299,15 +2369,18 @@ UnaryOpNode::composeDerivatives(expr_t darg, int deriv_id) { if (datatree.getTypeByDerivID(deriv_id) == SymbolType::parameter) { - auto varg = dynamic_cast(arg); + auto varg = dynamic_cast(arg); if (!varg) { cerr << "UnaryOpNode::composeDerivatives: STEADY_STATE() should only be used on " - << "standalone variables (like STEADY_STATE(y)) to be derivable w.r.t. parameters" << endl; + << "standalone variables (like STEADY_STATE(y)) to be derivable w.r.t. " + "parameters" + << endl; exit(EXIT_FAILURE); } if (datatree.symbol_table.getType(varg->symb_id) == SymbolType::endogenous) - return datatree.AddSteadyStateParamDeriv(arg, datatree.getSymbIDByDerivID(deriv_id)); + return datatree.AddSteadyStateParamDeriv(arg, + datatree.getSymbIDByDerivID(deriv_id)); else return datatree.Zero; } @@ -2320,10 +2393,11 @@ UnaryOpNode::composeDerivatives(expr_t darg, int deriv_id) assert(datatree.isDynamic()); if (datatree.getTypeByDerivID(deriv_id) == SymbolType::parameter) { - auto varg = dynamic_cast(arg); + auto varg = dynamic_cast(arg); assert(varg); assert(datatree.symbol_table.getType(varg->symb_id) == SymbolType::endogenous); - return datatree.AddSteadyStateParam2ndDeriv(arg, param1_symb_id, datatree.getSymbIDByDerivID(deriv_id)); + return datatree.AddSteadyStateParam2ndDeriv(arg, param1_symb_id, + datatree.getSymbIDByDerivID(deriv_id)); } else return datatree.Zero; @@ -2331,13 +2405,15 @@ UnaryOpNode::composeDerivatives(expr_t darg, int deriv_id) assert(datatree.isDynamic()); if (datatree.getTypeByDerivID(deriv_id) == SymbolType::parameter) { - cerr << "3rd derivative of STEADY_STATE node w.r.t. three parameters not implemented" << endl; + cerr << "3rd derivative of STEADY_STATE node w.r.t. three parameters not implemented" + << endl; exit(EXIT_FAILURE); } else return datatree.Zero; case UnaryOpcode::expectation: - cerr << "UnaryOpNode::composeDerivatives: not implemented on UnaryOpcode::expectation" << endl; + cerr << "UnaryOpNode::composeDerivatives: not implemented on UnaryOpcode::expectation" + << endl; exit(EXIT_FAILURE); case UnaryOpcode::erf: case UnaryOpcode::erfc: @@ -2375,23 +2451,25 @@ UnaryOpNode::computeDerivative(int deriv_id) } int -UnaryOpNode::cost(const map, unordered_set> &temp_terms_map, bool is_matlab) const +UnaryOpNode::cost(const map, unordered_set>& temp_terms_map, + bool is_matlab) const { // For a temporary term, the cost is null - for (const auto &it : temp_terms_map) - if (it.second.contains(const_cast(this))) + for (const auto& it : temp_terms_map) + if (it.second.contains(const_cast(this))) return 0; return cost(arg->cost(temp_terms_map, is_matlab), is_matlab); } int -UnaryOpNode::cost(const vector>> &blocks_temporary_terms, bool is_matlab) const +UnaryOpNode::cost(const vector>>& blocks_temporary_terms, + bool is_matlab) const { // For a temporary term, the cost is null - for (const auto &blk_tt : blocks_temporary_terms) - for (const auto &eq_tt : blk_tt) - if (eq_tt.contains(const_cast(this))) + for (const auto& blk_tt : blocks_temporary_terms) + for (const auto& eq_tt : blk_tt) + if (eq_tt.contains(const_cast(this))) return 0; return cost(arg->cost(blocks_temporary_terms, is_matlab), is_matlab); @@ -2400,7 +2478,7 @@ UnaryOpNode::cost(const vector>> &blocks_temporary_ int UnaryOpNode::cost(int cost, bool is_matlab) const { - if (op_code == UnaryOpcode::uminus && dynamic_cast(arg)) + if (op_code == UnaryOpcode::uminus && dynamic_cast(arg)) return 0; // Cost is zero for a negative constant, as for a positive one if (is_matlab) @@ -2510,22 +2588,21 @@ UnaryOpNode::cost(int cost, bool is_matlab) const } void -UnaryOpNode::computeTemporaryTerms(const pair &derivOrder, - map, unordered_set> &temp_terms_map, - unordered_map>> &reference_count, - bool is_matlab) const +UnaryOpNode::computeTemporaryTerms( + const pair& derivOrder, map, unordered_set>& temp_terms_map, + unordered_map>>& reference_count, bool is_matlab) const { - expr_t this2 = const_cast(this); - if (auto it = reference_count.find(this2); - it == reference_count.end()) + expr_t this2 = const_cast(this); + if (auto it = reference_count.find(this2); it == reference_count.end()) { - reference_count[this2] = { 1, derivOrder }; - if (op_code != UnaryOpcode::steadyState) // See comment in checkIfTemporaryTermThenWrite{,Bytecode}() + reference_count[this2] = {1, derivOrder}; + if (op_code + != UnaryOpcode::steadyState) // See comment in checkIfTemporaryTermThenWrite{,Bytecode}() arg->computeTemporaryTerms(derivOrder, temp_terms_map, reference_count, is_matlab); } else { - auto &[nref, min_order] = it->second; + auto& [nref, min_order] = it->second; nref++; if (nref * cost(temp_terms_map, is_matlab) > min_cost(is_matlab)) temp_terms_map[min_order].insert(this2); @@ -2533,20 +2610,21 @@ UnaryOpNode::computeTemporaryTerms(const pair &derivOrder, } void -UnaryOpNode::computeBlockTemporaryTerms(int blk, int eq, vector>> &blocks_temporary_terms, - unordered_map> &reference_count) const +UnaryOpNode::computeBlockTemporaryTerms( + int blk, int eq, vector>>& blocks_temporary_terms, + unordered_map>& reference_count) const { - expr_t this2 = const_cast(this); - if (auto it = reference_count.find(this2); - it == reference_count.end()) + expr_t this2 = const_cast(this); + if (auto it = reference_count.find(this2); it == reference_count.end()) { - reference_count[this2] = { 1, blk, eq }; - if (op_code != UnaryOpcode::steadyState) // See comment in checkIfTemporaryTermThenWrite{,Bytecode}() + reference_count[this2] = {1, blk, eq}; + if (op_code + != UnaryOpcode::steadyState) // See comment in checkIfTemporaryTermThenWrite{,Bytecode}() arg->computeBlockTemporaryTerms(blk, eq, blocks_temporary_terms, reference_count); } else { - auto &[nref, first_blk, first_eq] = it->second; + auto& [nref, first_blk, first_eq] = it->second; nref++; if (nref * cost(blocks_temporary_terms, false) > min_cost_c) blocks_temporary_terms[first_blk][first_eq].insert(this2); @@ -2560,7 +2638,7 @@ UnaryOpNode::containsExternalFunction() const } void -UnaryOpNode::writeJsonAST(ostream &output) const +UnaryOpNode::writeJsonAST(ostream& output) const { output << R"({"node_type" : "UnaryOpNode", "op" : ")"; switch (op_code) @@ -2657,8 +2735,7 @@ UnaryOpNode::writeJsonAST(ostream &output) const case UnaryOpcode::adl: output << R"(, "adl_param_name" : ")" << adl_param_name << R"(")" << R"(, "lags" : [)"; - for (bool printed_something{false}; - int lag : adl_lags) + for (bool printed_something {false}; int lag : adl_lags) { if (exchange(printed_something, true)) output << ", "; @@ -2673,12 +2750,10 @@ UnaryOpNode::writeJsonAST(ostream &output) const } void -UnaryOpNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - const deriv_node_temp_terms_t &tef_terms, - bool isdynamic) const +UnaryOpNode::writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms, + const deriv_node_temp_terms_t& tef_terms, bool isdynamic) const { - if (temporary_terms.contains(const_cast(this))) + if (temporary_terms.contains(const_cast(this))) { output << "T" << idx; return; @@ -2757,8 +2832,7 @@ UnaryOpNode::writeJsonOutput(ostream &output, output << "adl("; arg->writeJsonOutput(output, temporary_terms, tef_terms); output << ", '" << adl_param_name << "', ["; - for (bool printed_something{false}; - int lag : adl_lags) + for (bool printed_something {false}; int lag : adl_lags) { if (exchange(printed_something, true)) output << ", "; @@ -2773,18 +2847,18 @@ UnaryOpNode::writeJsonOutput(ostream &output, return; case UnaryOpcode::steadyStateParamDeriv: { - auto varg = dynamic_cast(arg); + auto varg = dynamic_cast(arg); assert(varg); assert(datatree.symbol_table.getType(varg->symb_id) == SymbolType::endogenous); assert(datatree.symbol_table.getType(param1_symb_id) == SymbolType::parameter); int tsid_endo = datatree.symbol_table.getTypeSpecificID(varg->symb_id); int tsid_param = datatree.symbol_table.getTypeSpecificID(param1_symb_id); - output << "ss_param_deriv(" << tsid_endo+1 << "," << tsid_param+1 << ")"; + output << "ss_param_deriv(" << tsid_endo + 1 << "," << tsid_param + 1 << ")"; } return; case UnaryOpcode::steadyStateParam2ndDeriv: { - auto varg = dynamic_cast(arg); + auto varg = dynamic_cast(arg); assert(varg); assert(datatree.symbol_table.getType(varg->symb_id) == SymbolType::endogenous); assert(datatree.symbol_table.getType(param1_symb_id) == SymbolType::parameter); @@ -2792,8 +2866,8 @@ UnaryOpNode::writeJsonOutput(ostream &output, int tsid_endo = datatree.symbol_table.getTypeSpecificID(varg->symb_id); int tsid_param1 = datatree.symbol_table.getTypeSpecificID(param1_symb_id); int tsid_param2 = datatree.symbol_table.getTypeSpecificID(param2_symb_id); - output << "ss_param_2nd_deriv(" << tsid_endo+1 << "," << tsid_param1+1 - << "," << tsid_param2+1 << ")"; + output << "ss_param_2nd_deriv(" << tsid_endo + 1 << "," << tsid_param1 + 1 << "," + << tsid_param2 + 1 << ")"; } return; case UnaryOpcode::expectation: @@ -2833,10 +2907,10 @@ UnaryOpNode::writeJsonOutput(ostream &output, } void -UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType 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 +UnaryOpNode::writeOutput(ostream& output, ExprNodeOutputType 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 { if (checkIfTemporaryTermThenWrite(output, output_type, temporary_terms, temporary_terms_idxs)) return; @@ -2983,19 +3057,19 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, return; case UnaryOpcode::steadyStateParamDeriv: { - auto varg = dynamic_cast(arg); + auto varg = dynamic_cast(arg); assert(varg); assert(datatree.symbol_table.getType(varg->symb_id) == SymbolType::endogenous); assert(datatree.symbol_table.getType(param1_symb_id) == SymbolType::parameter); int tsid_endo = datatree.symbol_table.getTypeSpecificID(varg->symb_id); int tsid_param = datatree.symbol_table.getTypeSpecificID(param1_symb_id); assert(isMatlabOutput(output_type)); - output << "ss_param_deriv(" << tsid_endo+1 << "," << tsid_param+1 << ")"; + output << "ss_param_deriv(" << tsid_endo + 1 << "," << tsid_param + 1 << ")"; } return; case UnaryOpcode::steadyStateParam2ndDeriv: { - auto varg = dynamic_cast(arg); + auto varg = dynamic_cast(arg); assert(varg); assert(datatree.symbol_table.getType(varg->symb_id) == SymbolType::endogenous); assert(datatree.symbol_table.getType(param1_symb_id) == SymbolType::parameter); @@ -3004,8 +3078,8 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, int tsid_param1 = datatree.symbol_table.getTypeSpecificID(param1_symb_id); int tsid_param2 = datatree.symbol_table.getTypeSpecificID(param2_symb_id); assert(isMatlabOutput(output_type)); - output << "ss_param_2nd_deriv(" << tsid_endo+1 << "," << tsid_param1+1 - << "," << tsid_param2+1 << ")"; + output << "ss_param_2nd_deriv(" << tsid_endo + 1 << "," << tsid_param1 + 1 << "," + << tsid_param2 + 1 << ")"; } return; case UnaryOpcode::expectation: @@ -3037,8 +3111,7 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, break; } - if (output_type == ExprNodeOutputType::juliaTimeDataFrame - && op_code != UnaryOpcode::uminus) + if (output_type == ExprNodeOutputType::juliaTimeDataFrame && op_code != UnaryOpcode::uminus) output << "."; // Use vectorized form of the function bool close_parenthesis = false; @@ -3049,7 +3122,8 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, */ if (op_code != UnaryOpcode::uminus || (op_code == UnaryOpcode::uminus - && arg->precedence(output_type, temporary_terms) < precedence(output_type, temporary_terms))) + && arg->precedence(output_type, temporary_terms) + < precedence(output_type, temporary_terms))) { output << LEFT_PAR(output_type); close_parenthesis = true; @@ -3067,29 +3141,30 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, } void -UnaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, - deriv_node_temp_terms_t &tef_terms) const +UnaryOpNode::writeExternalFunctionOutput(ostream& output, ExprNodeOutputType output_type, + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + deriv_node_temp_terms_t& tef_terms) const { - arg->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + arg->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); } void -UnaryOpNode::writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, +UnaryOpNode::writeJsonExternalFunctionOutput(vector& efout, + const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, bool isdynamic) const { arg->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms, isdynamic); } void -UnaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, +UnaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter& 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 + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + deriv_node_temp_terms_t& tef_terms) const { arg->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); @@ -3143,10 +3218,12 @@ UnaryOpNode::eval_opcode(UnaryOpcode op_code, double v) noexcept(false) case UnaryOpcode::steadyState: return v; case UnaryOpcode::steadyStateParamDeriv: - cerr << "UnaryOpNode::eval_opcode: not implemented on UnaryOpcode::steadyStateParamDeriv" << endl; + cerr << "UnaryOpNode::eval_opcode: not implemented on UnaryOpcode::steadyStateParamDeriv" + << endl; exit(EXIT_FAILURE); case UnaryOpcode::steadyStateParam2ndDeriv: - cerr << "UnaryOpNode::eval_opcode: not implemented on UnaryOpcode::steadyStateParam2ndDeriv" << endl; + cerr << "UnaryOpNode::eval_opcode: not implemented on UnaryOpcode::steadyStateParam2ndDeriv" + << endl; exit(EXIT_FAILURE); case UnaryOpcode::expectation: cerr << "UnaryOpNode::eval_opcode: not implemented on UnaryOpcode::expectation" << endl; @@ -3166,25 +3243,26 @@ UnaryOpNode::eval_opcode(UnaryOpcode op_code, double v) noexcept(false) } double -UnaryOpNode::eval(const eval_context_t &eval_context) const noexcept(false) +UnaryOpNode::eval(const eval_context_t& eval_context) const noexcept(false) { double v = arg->eval(eval_context); return eval_opcode(op_code, v); } void -UnaryOpNode::writeBytecodeOutput(BytecodeWriter &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 +UnaryOpNode::writeBytecodeOutput(BytecodeWriter& 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 { assert(!isAssignmentLHSBytecodeOutput(output_type)); - if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, + temporary_terms_idxs)) return; if (op_code == UnaryOpcode::steadyState) { - ExprNodeBytecodeOutputType new_output_type{output_type}; + ExprNodeBytecodeOutputType new_output_type {output_type}; switch (output_type) { case ExprNodeBytecodeOutputType::dynamicModel: @@ -3198,32 +3276,34 @@ UnaryOpNode::writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutp cerr << "UnaryOpNode::writeBytecodeOutput: impossible case" << endl; exit(EXIT_FAILURE); } - arg->writeBytecodeOutput(code_file, new_output_type, temporary_terms, temporary_terms_idxs, tef_terms); + arg->writeBytecodeOutput(code_file, new_output_type, temporary_terms, temporary_terms_idxs, + tef_terms); } else { - arg->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); - code_file << FUNARY_{op_code}; + arg->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); + code_file << FUNARY_ {op_code}; } } void -UnaryOpNode::collectVARLHSVariable(set &result) const +UnaryOpNode::collectVARLHSVariable(set& result) const { if (op_code == UnaryOpcode::diff) - result.insert(const_cast(this)); + result.insert(const_cast(this)); else arg->collectVARLHSVariable(result); } void -UnaryOpNode::collectDynamicVariables(SymbolType type_arg, set> &result) const +UnaryOpNode::collectDynamicVariables(SymbolType type_arg, set>& result) const { arg->collectDynamicVariables(type_arg, result); } void -UnaryOpNode::computeSubExprContainingVariable(int symb_id, int lag, set &contain_var) const +UnaryOpNode::computeSubExprContainingVariable(int symb_id, int lag, set& contain_var) const { if (op_code == UnaryOpcode::diff) { @@ -3231,20 +3311,20 @@ UnaryOpNode::computeSubExprContainingVariable(int symb_id, int lag, set expr_t substitute {datatree.AddMinus(arg, lagged_arg)}; substitute->computeSubExprContainingVariable(symb_id, lag, contain_var); if (contain_var.contains(arg) || contain_var.contains(lagged_arg)) - contain_var.insert(const_cast(this)); + contain_var.insert(const_cast(this)); } else { arg->computeSubExprContainingVariable(symb_id, lag, contain_var); if (contain_var.contains(arg)) - contain_var.insert(const_cast(this)); + contain_var.insert(const_cast(this)); } } -BinaryOpNode * -UnaryOpNode::normalizeEquationHelper(const set &contain_var, expr_t rhs) const +BinaryOpNode* +UnaryOpNode::normalizeEquationHelper(const set& contain_var, expr_t rhs) const { - assert(contain_var.contains(const_cast(this))); + assert(contain_var.contains(const_cast(this))); switch (op_code) { @@ -3327,7 +3407,8 @@ UnaryOpNode::normalizeEquationHelper(const set &contain_var, expr_t rhs) — var in arg but not arg(-1); — var in arg(-1) but not arg; — var in both arg and arg(-1). */ - return datatree.AddMinus(arg, arg->decreaseLeadsLags(1))->normalizeEquationHelper(contain_var, rhs); + return datatree.AddMinus(arg, arg->decreaseLeadsLags(1)) + ->normalizeEquationHelper(contain_var, rhs); default: throw NormalizationFailed(); } @@ -3336,17 +3417,18 @@ UnaryOpNode::normalizeEquationHelper(const set &contain_var, expr_t rhs) } expr_t -UnaryOpNode::computeChainRuleDerivative(int deriv_id, - const map &recursive_variables, - unordered_map> &non_null_chain_rule_derivatives, - unordered_map> &cache) +UnaryOpNode::computeChainRuleDerivative( + int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) { - expr_t darg = arg->getChainRuleDerivative(deriv_id, recursive_variables, non_null_chain_rule_derivatives, cache); + expr_t darg = arg->getChainRuleDerivative(deriv_id, recursive_variables, + non_null_chain_rule_derivatives, cache); return composeDerivatives(darg, deriv_id); } expr_t -UnaryOpNode::buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) const +UnaryOpNode::buildSimilarUnaryOpNode(expr_t alt_arg, DataTree& alt_datatree) const { switch (op_code) { @@ -3393,10 +3475,14 @@ UnaryOpNode::buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) con case UnaryOpcode::steadyState: return alt_datatree.AddSteadyState(alt_arg); case UnaryOpcode::steadyStateParamDeriv: - cerr << "UnaryOpNode::buildSimilarUnaryOpNode: UnaryOpcode::steadyStateParamDeriv can't be translated" << endl; + cerr << "UnaryOpNode::buildSimilarUnaryOpNode: UnaryOpcode::steadyStateParamDeriv can't be " + "translated" + << endl; exit(EXIT_FAILURE); case UnaryOpcode::steadyStateParam2ndDeriv: - cerr << "UnaryOpNode::buildSimilarUnaryOpNode: UnaryOpcode::steadyStateParam2ndDeriv can't be translated" << endl; + cerr << "UnaryOpNode::buildSimilarUnaryOpNode: UnaryOpcode::steadyStateParam2ndDeriv can't " + "be translated" + << endl; exit(EXIT_FAILURE); case UnaryOpcode::expectation: return alt_datatree.AddExpectation(expectation_information_set, alt_arg); @@ -3413,20 +3499,20 @@ UnaryOpNode::buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) con } expr_t -UnaryOpNode::toStatic(DataTree &static_datatree) const +UnaryOpNode::toStatic(DataTree& static_datatree) const { expr_t sarg = arg->toStatic(static_datatree); return buildSimilarUnaryOpNode(sarg, static_datatree); } void -UnaryOpNode::computeXrefs(EquationInfo &ei) const +UnaryOpNode::computeXrefs(EquationInfo& ei) const { arg->computeXrefs(ei); } expr_t -UnaryOpNode::clone(DataTree &alt_datatree) const +UnaryOpNode::clone(DataTree& alt_datatree) const { expr_t substarg = arg->clone(alt_datatree); return buildSimilarUnaryOpNode(substarg, alt_datatree); @@ -3485,7 +3571,7 @@ UnaryOpNode::undiff() const } int -UnaryOpNode::VarMaxLag(const set &lhs_lag_equiv) const +UnaryOpNode::VarMaxLag(const set& lhs_lag_equiv) const { auto [lag_equiv_repr, index] = getLagEquivalenceClass(); if (lhs_lag_equiv.contains(lag_equiv_repr)) @@ -3502,12 +3588,15 @@ UnaryOpNode::substituteAdl() const expr_t arg1subst = arg->substituteAdl(); - return transform_reduce(adl_lags.begin(), adl_lags.end(), static_cast(datatree.Zero), - [&](expr_t e1, expr_t e2) { return datatree.AddPlus(e1, e2); }, - [&](int lag) { - return datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + to_string(lag)), 0), - arg1subst->decreaseLeadsLags(lag)); - }); + return transform_reduce( + adl_lags.begin(), adl_lags.end(), static_cast(datatree.Zero), + [&](expr_t e1, expr_t e2) { return datatree.AddPlus(e1, e2); }, + [&](int lag) { + return datatree.AddTimes( + datatree.AddVariable( + datatree.symbol_table.getID(adl_param_name + "_lag_" + to_string(lag)), 0), + arg1subst->decreaseLeadsLags(lag)); + }); } expr_t @@ -3517,7 +3606,7 @@ UnaryOpNode::substituteModelLocalVariables() const } expr_t -UnaryOpNode::substituteVarExpectation(const map &subst_table) const +UnaryOpNode::substituteVarExpectation(const map& subst_table) const { return recurseTransform(&ExprNode::substituteVarExpectation, subst_table); } @@ -3563,7 +3652,7 @@ UnaryOpNode::createAuxVarForUnaryOpNode() const } void -UnaryOpNode::findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const +UnaryOpNode::findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t& nodes) const { arg->findUnaryOpNodesForAuxVarCreation(nodes); @@ -3571,11 +3660,11 @@ UnaryOpNode::findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) c return; auto [lag_equiv_repr, index] = getLagEquivalenceClass(); - nodes[lag_equiv_repr][index] = const_cast(this); + nodes[lag_equiv_repr][index] = const_cast(this); } void -UnaryOpNode::findDiffNodes(lag_equivalence_table_t &nodes) const +UnaryOpNode::findDiffNodes(lag_equivalence_table_t& nodes) const { arg->findDiffNodes(nodes); @@ -3583,7 +3672,7 @@ UnaryOpNode::findDiffNodes(lag_equivalence_table_t &nodes) const return; auto [lag_equiv_repr, index] = getLagEquivalenceClass(); - nodes[lag_equiv_repr][index] = const_cast(this); + nodes[lag_equiv_repr][index] = const_cast(this); } optional @@ -3593,17 +3682,16 @@ UnaryOpNode::findTargetVariable(int lhs_symb_id) const } expr_t -UnaryOpNode::substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, - vector &neweqs) const +UnaryOpNode::substituteDiff(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const { // If this is not a diff node, then substitute recursively and return expr_t argsubst = arg->substituteDiff(nodes, subst_table, neweqs); if (op_code != UnaryOpcode::diff) return buildSimilarUnaryOpNode(argsubst, datatree); - if (auto sit = subst_table.find(this); - sit != subst_table.end()) - return const_cast(sit->second); + if (auto sit = subst_table.find(this); sit != subst_table.end()) + return const_cast(sit->second); auto [lag_equiv_repr, index] = getLagEquivalenceClass(); auto it = nodes.find(lag_equiv_repr); @@ -3613,13 +3701,13 @@ UnaryOpNode::substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t /* diff does not appear in VAR equations, so simply create aux var and return. Once the comparison of expression nodes works, come back and remove this part, folding into the next loop. */ - int symb_id = datatree.symbol_table.addDiffAuxiliaryVar(argsubst->idx, const_cast(this)); - VariableNode *aux_var = datatree.AddVariable(symb_id, 0); - neweqs.push_back(datatree.AddEqual(aux_var, - datatree.AddMinus(argsubst, - argsubst->decreaseLeadsLags(1)))); - subst_table[this] = dynamic_cast(aux_var); - return const_cast(subst_table[this]); + int symb_id = datatree.symbol_table.addDiffAuxiliaryVar(argsubst->idx, + const_cast(this)); + VariableNode* aux_var = datatree.AddVariable(symb_id, 0); + neweqs.push_back( + datatree.AddEqual(aux_var, datatree.AddMinus(argsubst, argsubst->decreaseLeadsLags(1)))); + subst_table[this] = dynamic_cast(aux_var); + return const_cast(subst_table[this]); } /* At this point, we know that this node (and its lagged/leaded brothers) @@ -3627,60 +3715,59 @@ UnaryOpNode::substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t substitution table for all those similar nodes, in an iteration going from leads to lags. */ int last_index = 0; - VariableNode *last_aux_var = nullptr; + VariableNode* last_aux_var = nullptr; for (auto rit = it->second.rbegin(); rit != it->second.rend(); ++rit) { - expr_t argsubst = dynamic_cast(rit->second)-> - arg->substituteDiff(nodes, subst_table, neweqs); - auto vn = dynamic_cast(argsubst); + expr_t argsubst = dynamic_cast(rit->second) + ->arg->substituteDiff(nodes, subst_table, neweqs); + auto vn = dynamic_cast(argsubst); int symb_id; if (rit == it->second.rbegin()) { if (vn) - symb_id = datatree.symbol_table.addDiffAuxiliaryVar(argsubst->idx, rit->second, vn->symb_id, vn->lag); + symb_id = datatree.symbol_table.addDiffAuxiliaryVar(argsubst->idx, rit->second, + vn->symb_id, vn->lag); else symb_id = datatree.symbol_table.addDiffAuxiliaryVar(argsubst->idx, rit->second); // make originating aux var & equation last_index = rit->first; last_aux_var = datatree.AddVariable(symb_id, 0); - //ORIG_AUX_DIFF = argsubst - argsubst(-1) - neweqs.push_back(datatree.AddEqual(last_aux_var, - datatree.AddMinus(argsubst, - argsubst->decreaseLeadsLags(1)))); - subst_table[rit->second] = dynamic_cast(last_aux_var); + // ORIG_AUX_DIFF = argsubst - argsubst(-1) + neweqs.push_back(datatree.AddEqual( + last_aux_var, datatree.AddMinus(argsubst, argsubst->decreaseLeadsLags(1)))); + subst_table[rit->second] = dynamic_cast(last_aux_var); } else { // just add equation of form: AUX_DIFF = LAST_AUX_VAR(-1) - VariableNode *new_aux_var = nullptr; + VariableNode* new_aux_var = nullptr; for (int i = last_index; i > rit->first; i--) { if (i == last_index) symb_id = datatree.symbol_table.addDiffLagAuxiliaryVar(argsubst->idx, rit->second, last_aux_var->symb_id, -1); else - symb_id = datatree.symbol_table.addDiffLagAuxiliaryVar(new_aux_var->idx, rit->second, - last_aux_var->symb_id, -1); + symb_id = datatree.symbol_table.addDiffLagAuxiliaryVar( + new_aux_var->idx, rit->second, last_aux_var->symb_id, -1); new_aux_var = datatree.AddVariable(symb_id, 0); - neweqs.push_back(datatree.AddEqual(new_aux_var, - last_aux_var->decreaseLeadsLags(1))); + neweqs.push_back(datatree.AddEqual(new_aux_var, last_aux_var->decreaseLeadsLags(1))); last_aux_var = new_aux_var; } - subst_table[rit->second] = dynamic_cast(new_aux_var); + subst_table[rit->second] = dynamic_cast(new_aux_var); last_index = rit->first; } } - return const_cast(subst_table[this]); + return const_cast(subst_table[this]); } expr_t -UnaryOpNode::substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const +UnaryOpNode::substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, + subst_table_t& subst_table, vector& neweqs) const { - if (auto sit = subst_table.find(this); - sit != subst_table.end()) - return const_cast(sit->second); + if (auto sit = subst_table.find(this); sit != subst_table.end()) + return const_cast(sit->second); /* If the equivalence class of this node is not marked for substitution, then substitute recursively and return. */ @@ -3769,7 +3856,7 @@ UnaryOpNode::substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_ // index of the node that will // be used as the definition for // the aux var. - VariableNode *aux_var = nullptr; + VariableNode* aux_var = nullptr; for (auto rit = it->second.rbegin(); rit != it->second.rend(); ++rit) if (rit == it->second.rbegin()) { @@ -3786,31 +3873,32 @@ UnaryOpNode::substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_ auto argsubst_shifted = argsubst->decreaseLeadsLags(index - base_index); auto aux_def = buildSimilarUnaryOpNode(argsubst_shifted, datatree); int symb_id; - if (auto vn = dynamic_cast(argsubst_shifted); !vn) + if (auto vn = dynamic_cast(argsubst_shifted); !vn) symb_id = datatree.symbol_table.addUnaryOpAuxiliaryVar(this->idx, aux_def, unary_op); else symb_id = datatree.symbol_table.addUnaryOpAuxiliaryVar(this->idx, aux_def, unary_op, vn->symb_id, vn->lag); aux_var = datatree.AddVariable(symb_id, 0); neweqs.push_back(datatree.AddEqual(aux_var, aux_def)); - subst_table[rit->second] = dynamic_cast(aux_var); + subst_table[rit->second] = dynamic_cast(aux_var); } else - subst_table[rit->second] = dynamic_cast(aux_var->decreaseLeadsLags(base_index - rit->first)); + subst_table[rit->second] + = dynamic_cast(aux_var->decreaseLeadsLags(base_index - rit->first)); assert(subst_table.contains(this)); - return const_cast(subst_table.at(this)); + return const_cast(subst_table.at(this)); } expr_t -UnaryOpNode::substitutePacExpectation(const string &name, expr_t subexpr) +UnaryOpNode::substitutePacExpectation(const string& name, expr_t subexpr) { return recurseTransform(&ExprNode::substitutePacExpectation, name, subexpr); } expr_t -UnaryOpNode::substitutePacTargetNonstationary(const string &name, expr_t subexpr) +UnaryOpNode::substitutePacTargetNonstationary(const string& name, expr_t subexpr) { return recurseTransform(&ExprNode::substitutePacTargetNonstationary, name, subexpr); } @@ -3828,7 +3916,9 @@ UnaryOpNode::decreaseLeadsLagsPredeterminedVariables() const } expr_t -UnaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +UnaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs, + bool deterministic_model) const { if (op_code == UnaryOpcode::uminus || deterministic_model) return recurseTransform(&ExprNode::substituteEndoLeadGreaterThanTwo, subst_table, neweqs, @@ -3838,18 +3928,20 @@ UnaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector if (maxEndoLead() >= 2) return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs); else - return const_cast(this); + return const_cast(this); } } expr_t -UnaryOpNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const +UnaryOpNode::substituteEndoLagGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::substituteEndoLagGreaterThanTwo, subst_table, neweqs); } expr_t -UnaryOpNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +UnaryOpNode::substituteExoLead(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const { if (op_code == UnaryOpcode::uminus || deterministic_model) return recurseTransform(&ExprNode::substituteExoLead, subst_table, neweqs, deterministic_model); @@ -3858,55 +3950,63 @@ UnaryOpNode::substituteExoLead(subst_table_t &subst_table, vector= 1) return createExoLeadAuxiliaryVarForMyself(subst_table, neweqs); else - return const_cast(this); + return const_cast(this); } } expr_t -UnaryOpNode::substituteExoLag(subst_table_t &subst_table, vector &neweqs) const +UnaryOpNode::substituteExoLag(subst_table_t& subst_table, vector& neweqs) const { return recurseTransform(&ExprNode::substituteExoLag, subst_table, neweqs); } expr_t -UnaryOpNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const +UnaryOpNode::substituteExpectation(subst_table_t& subst_table, vector& neweqs, + bool partial_information_model) const { if (op_code == UnaryOpcode::expectation) { - if (auto it = subst_table.find(const_cast(this)); it != subst_table.end()) - return const_cast(it->second); + if (auto it = subst_table.find(const_cast(this)); it != subst_table.end()) + return const_cast(it->second); - //Arriving here, we need to create an auxiliary variable for this Expectation Operator: - //AUX_EXPECT_(LEAD/LAG)_(period)_(arg.idx) OR - //AUX_EXPECT_(info_set_name)_(arg.idx) - int symb_id = datatree.symbol_table.addExpectationAuxiliaryVar(expectation_information_set, arg->idx, const_cast(this)); + // Arriving here, we need to create an auxiliary variable for this Expectation Operator: + // AUX_EXPECT_(LEAD/LAG)_(period)_(arg.idx) OR + // AUX_EXPECT_(info_set_name)_(arg.idx) + int symb_id = datatree.symbol_table.addExpectationAuxiliaryVar( + expectation_information_set, arg->idx, const_cast(this)); expr_t newAuxE = datatree.AddVariable(symb_id, 0); if (partial_information_model && expectation_information_set == 0) - if (!dynamic_cast(arg)) + if (!dynamic_cast(arg)) { cerr << "ERROR: In Partial Information models, EXPECTATION(0)(X) " << "can only be used when X is a single variable." << endl; exit(EXIT_FAILURE); } - //take care of any nested expectation operators by calling arg->substituteExpectation(.), then decreaseLeadsLags for this UnaryOpcode::expectation operator - //arg(lag-period) (holds entire subtree of arg(lag-period) - expr_t substexpr = (arg->substituteExpectation(subst_table, neweqs, partial_information_model))->decreaseLeadsLags(expectation_information_set); + // take care of any nested expectation operators by calling arg->substituteExpectation(.), + // then decreaseLeadsLags for this UnaryOpcode::expectation operator arg(lag-period) (holds + // entire subtree of arg(lag-period) + expr_t substexpr + = (arg->substituteExpectation(subst_table, neweqs, partial_information_model)) + ->decreaseLeadsLags(expectation_information_set); assert(substexpr); - neweqs.push_back(datatree.AddEqual(newAuxE, substexpr)); //AUXE_period_arg.idx = arg(lag-period) + neweqs.push_back( + datatree.AddEqual(newAuxE, substexpr)); // AUXE_period_arg.idx = arg(lag-period) newAuxE = datatree.AddVariable(symb_id, expectation_information_set); - assert(dynamic_cast(newAuxE)); - subst_table[this] = dynamic_cast(newAuxE); + assert(dynamic_cast(newAuxE)); + subst_table[this] = dynamic_cast(newAuxE); return newAuxE; } else - return recurseTransform(&ExprNode::substituteExpectation, subst_table, neweqs, partial_information_model); + return recurseTransform(&ExprNode::substituteExpectation, subst_table, neweqs, + partial_information_model); } expr_t -UnaryOpNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const +UnaryOpNode::differentiateForwardVars(const vector& subset, subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::differentiateForwardVars, subset, subst_table, neweqs); } @@ -3926,13 +4026,13 @@ UnaryOpNode::isVariableNodeEqualTo([[maybe_unused]] SymbolType type_arg, } bool -UnaryOpNode::containsPacExpectation(const string &pac_model_name) const +UnaryOpNode::containsPacExpectation(const string& pac_model_name) const { return arg->containsPacExpectation(pac_model_name); } bool -UnaryOpNode::containsPacTargetNonstationary(const string &pac_model_name) const +UnaryOpNode::containsPacTargetNonstationary(const string& pac_model_name) const { return arg->containsPacTargetNonstationary(pac_model_name); } @@ -3950,7 +4050,7 @@ UnaryOpNode::detrend(int symb_id, bool log_trend, expr_t trend) const } expr_t -UnaryOpNode::removeTrendLeadLag(const map &trend_symbols_map) const +UnaryOpNode::removeTrendLeadLag(const map& trend_symbols_map) const { return recurseTransform(&ExprNode::removeTrendLeadLag, trend_symbols_map); } @@ -3959,8 +4059,7 @@ bool UnaryOpNode::isInStaticForm() const { if (op_code == UnaryOpcode::steadyState || op_code == UnaryOpcode::steadyStateParamDeriv - || op_code == UnaryOpcode::steadyStateParam2ndDeriv - || op_code == UnaryOpcode::expectation) + || op_code == UnaryOpcode::steadyStateParam2ndDeriv || op_code == UnaryOpcode::expectation) return false; else return arg->isInStaticForm(); @@ -3973,7 +4072,7 @@ UnaryOpNode::isParamTimesEndogExpr() const } expr_t -UnaryOpNode::replaceVarsInEquation(map &table) const +UnaryOpNode::replaceVarsInEquation(map& table) const { return recurseTransform(&ExprNode::replaceVarsInEquation, table); } @@ -3984,13 +4083,14 @@ UnaryOpNode::substituteLogTransform(int orig_symb_id, int aux_symb_id) const return recurseTransform(&ExprNode::substituteLogTransform, orig_symb_id, aux_symb_id); } -BinaryOpNode::BinaryOpNode(DataTree &datatree_arg, int idx_arg, const expr_t arg1_arg, - BinaryOpcode op_code_arg, const expr_t arg2_arg, int powerDerivOrder_arg) : - ExprNode{datatree_arg, idx_arg}, - arg1{arg1_arg}, - arg2{arg2_arg}, - op_code{op_code_arg}, - powerDerivOrder{powerDerivOrder_arg} +BinaryOpNode::BinaryOpNode(DataTree& datatree_arg, int idx_arg, const expr_t arg1_arg, + BinaryOpcode op_code_arg, const expr_t arg2_arg, + int powerDerivOrder_arg) : + ExprNode {datatree_arg, idx_arg}, + arg1 {arg1_arg}, + arg2 {arg2_arg}, + op_code {op_code_arg}, + powerDerivOrder {powerDerivOrder_arg} { assert(powerDerivOrder >= 0); } @@ -4008,29 +4108,27 @@ BinaryOpNode::prepareForDerivation() // Non-null derivatives are the union of those of the arguments // Compute set union of arg1->non_null_derivatives and arg2->non_null_derivatives - set_union(arg1->non_null_derivatives.begin(), - arg1->non_null_derivatives.end(), - arg2->non_null_derivatives.begin(), - arg2->non_null_derivatives.end(), + set_union(arg1->non_null_derivatives.begin(), arg1->non_null_derivatives.end(), + arg2->non_null_derivatives.begin(), arg2->non_null_derivatives.end(), inserter(non_null_derivatives, non_null_derivatives.begin())); } void -BinaryOpNode::prepareForChainRuleDerivation(const map &recursive_variables, - unordered_map> &non_null_chain_rule_derivatives) const +BinaryOpNode::prepareForChainRuleDerivation( + const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const { - if (non_null_chain_rule_derivatives.contains(const_cast(this))) + if (non_null_chain_rule_derivatives.contains(const_cast(this))) return; arg1->prepareForChainRuleDerivation(recursive_variables, non_null_chain_rule_derivatives); arg2->prepareForChainRuleDerivation(recursive_variables, non_null_chain_rule_derivatives); - set &nnd { non_null_chain_rule_derivatives[const_cast(this)] }; + set& nnd {non_null_chain_rule_derivatives[const_cast(this)]}; set_union(non_null_chain_rule_derivatives.at(arg1).begin(), non_null_chain_rule_derivatives.at(arg1).end(), non_null_chain_rule_derivatives.at(arg2).begin(), - non_null_chain_rule_derivatives.at(arg2).end(), - inserter(nnd, nnd.begin())); + non_null_chain_rule_derivatives.at(arg2).end(), inserter(nnd, nnd.begin())); } expr_t @@ -4080,16 +4178,15 @@ BinaryOpNode::composeDerivatives(expr_t darg1, expr_t darg2) if (darg2 == datatree.Zero) if (darg1 == datatree.Zero) return datatree.Zero; + else if (dynamic_cast(arg2)) + { + t11 = datatree.AddMinus(arg2, datatree.One); + t12 = datatree.AddPower(arg1, t11); + t13 = datatree.AddTimes(arg2, t12); + return datatree.AddTimes(darg1, t13); + } else - if (dynamic_cast(arg2)) - { - t11 = datatree.AddMinus(arg2, datatree.One); - t12 = datatree.AddPower(arg1, t11); - t13 = datatree.AddTimes(arg2, t12); - return datatree.AddTimes(darg1, t13); - } - else - return datatree.AddTimes(darg1, datatree.AddPowerDeriv(arg1, arg2, powerDerivOrder + 1)); + return datatree.AddTimes(darg1, datatree.AddPowerDeriv(arg1, arg2, powerDerivOrder + 1)); else { t11 = datatree.AddLog(arg1); @@ -4113,7 +4210,8 @@ BinaryOpNode::composeDerivatives(expr_t darg1, expr_t darg2) expr_t first_part = datatree.AddTimes(f, t15); for (int i = 0; i < powerDerivOrder; i++) - first_part = datatree.AddTimes(first_part, datatree.AddMinus(arg2, datatree.AddPossiblyNegativeConstant(i))); + first_part = datatree.AddTimes( + first_part, datatree.AddMinus(arg2, datatree.AddPossiblyNegativeConstant(i))); t13 = datatree.Zero; for (int i = 0; i < powerDerivOrder; i++) @@ -4151,16 +4249,14 @@ expr_t BinaryOpNode::unpackPowerDeriv() const { if (op_code != BinaryOpcode::powerDeriv) - return const_cast(this); + return const_cast(this); expr_t front = datatree.One; for (int i = 0; i < powerDerivOrder; i++) front = datatree.AddTimes(front, - datatree.AddMinus(arg2, - datatree.AddPossiblyNegativeConstant(i))); - expr_t tmp = datatree.AddPower(arg1, - datatree.AddMinus(arg2, - datatree.AddPossiblyNegativeConstant(powerDerivOrder))); + datatree.AddMinus(arg2, datatree.AddPossiblyNegativeConstant(i))); + expr_t tmp = datatree.AddPower( + arg1, datatree.AddMinus(arg2, datatree.AddPossiblyNegativeConstant(powerDerivOrder))); return datatree.AddTimes(front, tmp); } @@ -4173,10 +4269,11 @@ BinaryOpNode::computeDerivative(int deriv_id) } int -BinaryOpNode::precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const +BinaryOpNode::precedence(ExprNodeOutputType output_type, + const temporary_terms_t& temporary_terms) const { // A temporary term behaves as a variable - if (temporary_terms.contains(const_cast(this))) + if (temporary_terms.contains(const_cast(this))) return 100; switch (op_code) @@ -4212,10 +4309,10 @@ BinaryOpNode::precedence(ExprNodeOutputType output_type, const temporary_terms_t } int -BinaryOpNode::precedenceJson(const temporary_terms_t &temporary_terms) const +BinaryOpNode::precedenceJson(const temporary_terms_t& temporary_terms) const { // A temporary term behaves as a variable - if (temporary_terms.contains(const_cast(this))) + if (temporary_terms.contains(const_cast(this))) return 100; switch (op_code) @@ -4247,11 +4344,12 @@ BinaryOpNode::precedenceJson(const temporary_terms_t &temporary_terms) const } int -BinaryOpNode::cost(const map, unordered_set> &temp_terms_map, bool is_matlab) const +BinaryOpNode::cost(const map, unordered_set>& temp_terms_map, + bool is_matlab) const { // For a temporary term, the cost is null - for (const auto &it : temp_terms_map) - if (it.second.contains(const_cast(this))) + for (const auto& it : temp_terms_map) + if (it.second.contains(const_cast(this))) return 0; int arg_cost = arg1->cost(temp_terms_map, is_matlab) + arg2->cost(temp_terms_map, is_matlab); @@ -4260,15 +4358,17 @@ BinaryOpNode::cost(const map, unordered_set> &temp_terms_ } int -BinaryOpNode::cost(const vector>> &blocks_temporary_terms, bool is_matlab) const +BinaryOpNode::cost(const vector>>& blocks_temporary_terms, + bool is_matlab) const { // For a temporary term, the cost is null - for (const auto &blk_tt : blocks_temporary_terms) - for (const auto &eq_tt : blk_tt) - if (eq_tt.contains(const_cast(this))) + for (const auto& blk_tt : blocks_temporary_terms) + for (const auto& eq_tt : blk_tt) + if (eq_tt.contains(const_cast(this))) return 0; - int arg_cost = arg1->cost(blocks_temporary_terms, is_matlab) + arg2->cost(blocks_temporary_terms, is_matlab); + int arg_cost = arg1->cost(blocks_temporary_terms, is_matlab) + + arg2->cost(blocks_temporary_terms, is_matlab); return cost(arg_cost, is_matlab); } @@ -4298,7 +4398,7 @@ BinaryOpNode::cost(int cost, bool is_matlab) const return cost + 990; case BinaryOpcode::power: case BinaryOpcode::powerDeriv: - return cost + (min_cost_matlab/2+1); + return cost + (min_cost_matlab / 2 + 1); case BinaryOpcode::equal: return cost; } @@ -4325,7 +4425,7 @@ BinaryOpNode::cost(int cost, bool is_matlab) const case BinaryOpcode::power: return cost + 520; case BinaryOpcode::powerDeriv: - return cost + (min_cost_c/2+1); + return cost + (min_cost_c / 2 + 1); case BinaryOpcode::equal: return cost; } @@ -4333,18 +4433,16 @@ BinaryOpNode::cost(int cost, bool is_matlab) const } void -BinaryOpNode::computeTemporaryTerms(const pair &derivOrder, - map, unordered_set> &temp_terms_map, - unordered_map>> &reference_count, - bool is_matlab) const +BinaryOpNode::computeTemporaryTerms( + const pair& derivOrder, map, unordered_set>& temp_terms_map, + unordered_map>>& reference_count, bool is_matlab) const { - expr_t this2 = const_cast(this); - if (auto it = reference_count.find(this2); - it == reference_count.end()) + expr_t this2 = const_cast(this); + if (auto it = reference_count.find(this2); it == reference_count.end()) { // If this node has never been encountered, set its ref count to one, // and travel through its children - reference_count[this2] = { 1, derivOrder }; + reference_count[this2] = {1, derivOrder}; arg1->computeTemporaryTerms(derivOrder, temp_terms_map, reference_count, is_matlab); arg2->computeTemporaryTerms(derivOrder, temp_terms_map, reference_count, is_matlab); } @@ -4353,7 +4451,7 @@ BinaryOpNode::computeTemporaryTerms(const pair &derivOrder, /* If the node has already been encountered, increment its ref count and declare it as a temporary term if it is too costly (except if it is an equal node: we don't want them as temporary terms) */ - auto &[nref, min_order] = it->second; + auto& [nref, min_order] = it->second; nref++; if (nref * cost(temp_terms_map, is_matlab) > min_cost(is_matlab) && op_code != BinaryOpcode::equal) @@ -4362,29 +4460,29 @@ BinaryOpNode::computeTemporaryTerms(const pair &derivOrder, } void -BinaryOpNode::computeBlockTemporaryTerms(int blk, int eq, vector>> &blocks_temporary_terms, - unordered_map> &reference_count) const +BinaryOpNode::computeBlockTemporaryTerms( + int blk, int eq, vector>>& blocks_temporary_terms, + unordered_map>& reference_count) const { - expr_t this2 = const_cast(this); - if (auto it = reference_count.find(this2); - it == reference_count.end()) + expr_t this2 = const_cast(this); + if (auto it = reference_count.find(this2); it == reference_count.end()) { - reference_count[this2] = { 1, blk, eq }; + reference_count[this2] = {1, blk, eq}; arg1->computeBlockTemporaryTerms(blk, eq, blocks_temporary_terms, reference_count); arg2->computeBlockTemporaryTerms(blk, eq, blocks_temporary_terms, reference_count); } else { - auto &[nref, first_blk, first_eq] = it->second; + auto& [nref, first_blk, first_eq] = it->second; nref++; - if (nref * cost(blocks_temporary_terms, false) > min_cost_c - && op_code != BinaryOpcode::equal) + if (nref * cost(blocks_temporary_terms, false) > min_cost_c && op_code != BinaryOpcode::equal) blocks_temporary_terms[first_blk][first_eq].insert(this2); } } double -BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2, int derivOrder) noexcept(false) +BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2, + int derivOrder) noexcept(false) { switch (op_code) { @@ -4399,13 +4497,12 @@ BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2, int derivO case BinaryOpcode::power: return pow(v1, v2); case BinaryOpcode::powerDeriv: - if (fabs(v1) < power_deriv_near_zero && v2 > 0 - && derivOrder > v2 - && fabs(v2-nearbyint(v2)) < power_deriv_near_zero) + if (fabs(v1) < power_deriv_near_zero && v2 > 0 && derivOrder > v2 + && fabs(v2 - nearbyint(v2)) < power_deriv_near_zero) return 0.0; else { - double dxp = pow(v1, v2-derivOrder); + double dxp = pow(v1, v2 - derivOrder); for (int i = 0; i < derivOrder; i++) dxp *= v2--; return dxp; @@ -4439,7 +4536,7 @@ BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2, int derivO } double -BinaryOpNode::eval(const eval_context_t &eval_context) const noexcept(false) +BinaryOpNode::eval(const eval_context_t& eval_context) const noexcept(false) { double v1 = arg1->eval(eval_context); double v2 = arg2->eval(eval_context); @@ -4447,31 +4544,33 @@ BinaryOpNode::eval(const eval_context_t &eval_context) const noexcept(false) } void -BinaryOpNode::writeBytecodeOutput(BytecodeWriter &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 +BinaryOpNode::writeBytecodeOutput(BytecodeWriter& 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 { assert(!isAssignmentLHSBytecodeOutput(output_type)); - if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, + temporary_terms_idxs)) return; if (op_code == BinaryOpcode::powerDeriv) - code_file << FLDC_{static_cast(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 << FLDC_ {static_cast(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}; } bool BinaryOpNode::containsExternalFunction() const { - return arg1->containsExternalFunction() - || arg2->containsExternalFunction(); + return arg1->containsExternalFunction() || arg2->containsExternalFunction(); } void -BinaryOpNode::writeJsonAST(ostream &output) const +BinaryOpNode::writeJsonAST(ostream& output) const { output << R"({"node_type" : "BinaryOpNode",)" << R"( "op" : ")"; @@ -4531,13 +4630,11 @@ BinaryOpNode::writeJsonAST(ostream &output) const } void -BinaryOpNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - const deriv_node_temp_terms_t &tef_terms, - bool isdynamic) const +BinaryOpNode::writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms, + const deriv_node_temp_terms_t& tef_terms, bool isdynamic) const { // If current node is a temporary term - if (temporary_terms.contains(const_cast(this))) + if (temporary_terms.contains(const_cast(this))) { output << "T" << idx; return; @@ -4553,8 +4650,7 @@ BinaryOpNode::writeJsonOutput(ostream &output, case BinaryOpcode::min: output << "min("; break; - default: - ; + default:; } arg1->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); output << ","; @@ -4577,9 +4673,9 @@ BinaryOpNode::writeJsonOutput(ostream &output, bool close_parenthesis = false; - // If left argument has a lower precedence, or if current and left argument are both power operators, - // add parenthesis around left argument - if (auto barg1 = dynamic_cast(arg1); + // If left argument has a lower precedence, or if current and left argument are both power + // operators, add parenthesis around left argument + if (auto barg1 = dynamic_cast(arg1); arg1->precedenceJson(temporary_terms) < prec || (op_code == BinaryOpcode::power && barg1 && barg1->op_code == BinaryOpcode::power)) { @@ -4632,8 +4728,7 @@ BinaryOpNode::writeJsonOutput(ostream &output, case BinaryOpcode::equal: output << "="; break; - default: - ; + default:; } close_parenthesis = false; @@ -4643,8 +4738,9 @@ BinaryOpNode::writeJsonOutput(ostream &output, - it is a power operator and current operator is also a power operator - it has same precedence as current operator and current operator is either a minus or a divide */ - auto barg2 = dynamic_cast(arg2); - if (int arg2_prec = arg2->precedenceJson(temporary_terms); arg2_prec < prec + auto barg2 = dynamic_cast(arg2); + if (int arg2_prec = arg2->precedenceJson(temporary_terms); + arg2_prec < prec || (op_code == BinaryOpcode::power && barg2 && barg2->op_code == BinaryOpcode::power) || (op_code == BinaryOpcode::minus && arg2_prec == prec) || (op_code == BinaryOpcode::divide && arg2_prec == prec)) @@ -4661,10 +4757,10 @@ BinaryOpNode::writeJsonOutput(ostream &output, } void -BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType 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 +BinaryOpNode::writeOutput(ostream& output, ExprNodeOutputType 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 { if (checkIfTemporaryTermThenWrite(output, output_type, temporary_terms, temporary_terms_idxs)) return; @@ -4673,7 +4769,8 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, if (op_code == BinaryOpcode::powerDeriv) { if (isLatexOutput(output_type)) - unpackPowerDeriv()->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + unpackPowerDeriv()->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); else { if (isJuliaOutput(output_type)) @@ -4689,7 +4786,8 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, } // Treat special case of power operator in C, and case of max and min operators - if ((op_code == BinaryOpcode::power && isCOutput(output_type)) || op_code == BinaryOpcode::max || op_code == BinaryOpcode::min) + if ((op_code == BinaryOpcode::power && isCOutput(output_type)) || op_code == BinaryOpcode::max + || op_code == BinaryOpcode::min) { switch (op_code) { @@ -4708,8 +4806,7 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, else output << "min("; break; - default: - ; + default:; } arg1->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); output << ","; @@ -4726,10 +4823,12 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output << R"(\frac{)"; else { - // If left argument has a lower precedence, or if current and left argument are both power operators, add parenthesis around left argument - auto barg1 = dynamic_cast(arg1); + // If left argument has a lower precedence, or if current and left argument are both power + // operators, add parenthesis around left argument + auto barg1 = dynamic_cast(arg1); if (arg1->precedence(output_type, temporary_terms) < prec - || (op_code == BinaryOpcode::power && barg1 != nullptr && barg1->op_code == BinaryOpcode::power)) + || (op_code == BinaryOpcode::power && barg1 != nullptr + && barg1->op_code == BinaryOpcode::power)) { output << LEFT_PAR(output_type); close_parenthesis = true; @@ -4765,7 +4864,8 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case BinaryOpcode::times: if (isLatexOutput(output_type)) output << R"(\, )"; - else if (output_type == ExprNodeOutputType::occbinDifferenceFile // This file operates on vectors, see dynare#1826 + else if (output_type == ExprNodeOutputType::occbinDifferenceFile // This file operates on + // vectors, see dynare#1826 || output_type == ExprNodeOutputType::juliaTimeDataFrame) output << " .*"; else @@ -4774,15 +4874,17 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case BinaryOpcode::divide: if (!isLatexOutput(output_type)) { - if (output_type == ExprNodeOutputType::occbinDifferenceFile // This file operates on vectors, see dynare#1826 - || output_type == ExprNodeOutputType::juliaTimeDataFrame) + if (output_type == ExprNodeOutputType::occbinDifferenceFile // This file operates on + // vectors, see dynare#1826 + || output_type == ExprNodeOutputType::juliaTimeDataFrame) output << " ./"; else output << "/"; } break; case BinaryOpcode::power: - if (output_type == ExprNodeOutputType::occbinDifferenceFile // This file operates on vectors, see dynare#1826 + if (output_type == ExprNodeOutputType::occbinDifferenceFile // This file operates on vectors, + // see dynare#1826 || output_type == ExprNodeOutputType::juliaTimeDataFrame) output << " .^"; else @@ -4841,13 +4943,13 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, else output << "="; break; - default: - ; + default:; } close_parenthesis = false; - if (isLatexOutput(output_type) && (op_code == BinaryOpcode::power || op_code == BinaryOpcode::divide)) + if (isLatexOutput(output_type) + && (op_code == BinaryOpcode::power || op_code == BinaryOpcode::divide)) output << "{"; else { @@ -4856,9 +4958,11 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - it is a power operator and current operator is also a power operator - it has same precedence as current operator and current operator is either a minus or a divide */ - auto barg2 = dynamic_cast(arg2); - if (int arg2_prec = arg2->precedence(output_type, temporary_terms); arg2_prec < prec - || (op_code == BinaryOpcode::power && barg2 && barg2->op_code == BinaryOpcode::power && !isLatexOutput(output_type)) + auto barg2 = dynamic_cast(arg2); + if (int arg2_prec = arg2->precedence(output_type, temporary_terms); + arg2_prec < prec + || (op_code == BinaryOpcode::power && barg2 && barg2->op_code == BinaryOpcode::power + && !isLatexOutput(output_type)) || (op_code == BinaryOpcode::minus && arg2_prec == prec) || (op_code == BinaryOpcode::divide && arg2_prec == prec && !isLatexOutput(output_type))) { @@ -4870,7 +4974,8 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, // Write right argument arg2->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); - if (isLatexOutput(output_type) && (op_code == BinaryOpcode::power || op_code == BinaryOpcode::divide)) + if (isLatexOutput(output_type) + && (op_code == BinaryOpcode::power || op_code == BinaryOpcode::divide)) output << "}"; if (close_parenthesis) @@ -4878,19 +4983,21 @@ BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, } void -BinaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, - deriv_node_temp_terms_t &tef_terms) const +BinaryOpNode::writeExternalFunctionOutput(ostream& output, ExprNodeOutputType output_type, + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + deriv_node_temp_terms_t& tef_terms) const { - arg1->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); - arg2->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + arg1->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); + arg2->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); } void -BinaryOpNode::writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, +BinaryOpNode::writeJsonExternalFunctionOutput(vector& efout, + const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, bool isdynamic) const { arg1->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms, isdynamic); @@ -4898,11 +5005,10 @@ BinaryOpNode::writeJsonExternalFunctionOutput(vector &efout, } void -BinaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &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 +BinaryOpNode::writeBytecodeExternalFunctionOutput( + BytecodeWriter& 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 { arg1->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); @@ -4911,21 +5017,20 @@ BinaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, } int -BinaryOpNode::VarMaxLag(const set &lhs_lag_equiv) const +BinaryOpNode::VarMaxLag(const set& lhs_lag_equiv) const { - return max(arg1->VarMaxLag(lhs_lag_equiv), - arg2->VarMaxLag(lhs_lag_equiv)); + return max(arg1->VarMaxLag(lhs_lag_equiv), arg2->VarMaxLag(lhs_lag_equiv)); } void -BinaryOpNode::collectVARLHSVariable([[maybe_unused]] set &result) const +BinaryOpNode::collectVARLHSVariable([[maybe_unused]] set& result) const { cerr << "ERROR: you can only have variables or unary ops on LHS of VAR" << endl; exit(EXIT_FAILURE); } void -BinaryOpNode::collectDynamicVariables(SymbolType type_arg, set> &result) const +BinaryOpNode::collectDynamicVariables(SymbolType type_arg, set>& result) const { arg1->collectDynamicVariables(type_arg, result); arg2->collectDynamicVariables(type_arg, result); @@ -4975,18 +5080,18 @@ BinaryOpNode::Compute_RHS(expr_t arg1, expr_t arg2, int op, int op_type) const } void -BinaryOpNode::computeSubExprContainingVariable(int symb_id, int lag, set &contain_var) const +BinaryOpNode::computeSubExprContainingVariable(int symb_id, int lag, set& contain_var) const { arg1->computeSubExprContainingVariable(symb_id, lag, contain_var); arg2->computeSubExprContainingVariable(symb_id, lag, contain_var); if (contain_var.contains(arg1) || contain_var.contains(arg2)) - contain_var.insert(const_cast(this)); + contain_var.insert(const_cast(this)); } -BinaryOpNode * -BinaryOpNode::normalizeEquationHelper(const set &contain_var, expr_t rhs) const +BinaryOpNode* +BinaryOpNode::normalizeEquationHelper(const set& contain_var, expr_t rhs) const { - assert(contain_var.contains(const_cast(this))); + assert(contain_var.contains(const_cast(this))); bool arg1_contains_var = contain_var.contains(arg1); bool arg2_contains_var = contain_var.contains(arg2); @@ -5028,7 +5133,7 @@ BinaryOpNode::normalizeEquationHelper(const set &contain_var, expr_t rhs } catch (DataTree::DivisionByZeroException) { - throw NormalizationFailed{}; + throw NormalizationFailed {}; } break; case BinaryOpcode::divide: @@ -5044,7 +5149,7 @@ BinaryOpNode::normalizeEquationHelper(const set &contain_var, expr_t rhs } catch (DataTree::DivisionByZeroException) { - throw NormalizationFailed{}; + throw NormalizationFailed {}; } break; case BinaryOpcode::power: @@ -5063,7 +5168,7 @@ BinaryOpNode::normalizeEquationHelper(const set &contain_var, expr_t rhs } catch (DataTree::DivisionByZeroException) { - throw NormalizationFailed{}; + throw NormalizationFailed {}; } break; case BinaryOpcode::equal: @@ -5079,7 +5184,7 @@ BinaryOpNode::normalizeEquationHelper(const set &contain_var, expr_t rhs return arg2->normalizeEquationHelper(contain_var, rhs); } -BinaryOpNode * +BinaryOpNode* BinaryOpNode::normalizeEquation(int symb_id, int lag) const { assert(op_code == BinaryOpcode::equal); @@ -5095,22 +5200,25 @@ BinaryOpNode::normalizeEquation(int symb_id, int lag) const throw NormalizationFailed(); return arg1_contains_var ? arg1->normalizeEquationHelper(contain_var, arg2) - : arg2->normalizeEquationHelper(contain_var, arg1); + : arg2->normalizeEquationHelper(contain_var, arg1); } expr_t -BinaryOpNode::computeChainRuleDerivative(int deriv_id, - const map &recursive_variables, - unordered_map> &non_null_chain_rule_derivatives, - unordered_map> &cache) +BinaryOpNode::computeChainRuleDerivative( + int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) { - expr_t darg1 = arg1->getChainRuleDerivative(deriv_id, recursive_variables, non_null_chain_rule_derivatives, cache); - expr_t darg2 = arg2->getChainRuleDerivative(deriv_id, recursive_variables, non_null_chain_rule_derivatives, cache); + expr_t darg1 = arg1->getChainRuleDerivative(deriv_id, recursive_variables, + non_null_chain_rule_derivatives, cache); + expr_t darg2 = arg2->getChainRuleDerivative(deriv_id, recursive_variables, + non_null_chain_rule_derivatives, cache); return composeDerivatives(darg1, darg2); } expr_t -BinaryOpNode::buildSimilarBinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, DataTree &alt_datatree) const +BinaryOpNode::buildSimilarBinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, + DataTree& alt_datatree) const { switch (op_code) { @@ -5149,7 +5257,7 @@ BinaryOpNode::buildSimilarBinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, DataTre } expr_t -BinaryOpNode::toStatic(DataTree &static_datatree) const +BinaryOpNode::toStatic(DataTree& static_datatree) const { expr_t sarg1 = arg1->toStatic(static_datatree); expr_t sarg2 = arg2->toStatic(static_datatree); @@ -5157,14 +5265,14 @@ BinaryOpNode::toStatic(DataTree &static_datatree) const } void -BinaryOpNode::computeXrefs(EquationInfo &ei) const +BinaryOpNode::computeXrefs(EquationInfo& ei) const { arg1->computeXrefs(ei); arg2->computeXrefs(ei); } expr_t -BinaryOpNode::clone(DataTree &alt_datatree) const +BinaryOpNode::clone(DataTree& alt_datatree) const { expr_t substarg1 = arg1->clone(alt_datatree); expr_t substarg2 = arg2->clone(alt_datatree); @@ -5232,17 +5340,23 @@ BinaryOpNode::decreaseLeadsLagsPredeterminedVariables() const } expr_t -BinaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +BinaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs, + bool deterministic_model) const { expr_t arg1subst, arg2subst; int maxendolead1 = arg1->maxEndoLead(), maxendolead2 = arg2->maxEndoLead(); if (maxendolead1 < 2 && maxendolead2 < 2) - return const_cast(this); + return const_cast(this); if (deterministic_model) { - arg1subst = maxendolead1 >= 2 ? arg1->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model) : arg1; - arg2subst = maxendolead2 >= 2 ? arg2->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model) : arg2; + arg1subst = maxendolead1 >= 2 ? arg1->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, + deterministic_model) + : arg1; + arg2subst = maxendolead2 >= 2 ? arg2->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, + deterministic_model) + : arg2; return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); } else @@ -5251,20 +5365,26 @@ BinaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vecto case BinaryOpcode::plus: case BinaryOpcode::minus: case BinaryOpcode::equal: - arg1subst = maxendolead1 >= 2 ? arg1->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model) : arg1; - arg2subst = maxendolead2 >= 2 ? arg2->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model) : arg2; + arg1subst = maxendolead1 >= 2 ? arg1->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, + deterministic_model) + : arg1; + arg2subst = maxendolead2 >= 2 ? arg2->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, + deterministic_model) + : arg2; return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); case BinaryOpcode::times: case BinaryOpcode::divide: if (maxendolead1 >= 2 && maxendolead2 == 0 && arg2->maxExoLead() == 0) { - arg1subst = arg1->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); + arg1subst + = arg1->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); return buildSimilarBinaryOpNode(arg1subst, arg2, datatree); } - if (maxendolead1 == 0 && arg1->maxExoLead() == 0 - && maxendolead2 >= 2 && op_code == BinaryOpcode::times) + if (maxendolead1 == 0 && arg1->maxExoLead() == 0 && maxendolead2 >= 2 + && op_code == BinaryOpcode::times) { - arg2subst = arg2->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); + arg2subst + = arg2->substituteEndoLeadGreaterThanTwo(subst_table, neweqs, deterministic_model); return buildSimilarBinaryOpNode(arg1, arg2subst, datatree); } return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs); @@ -5274,23 +5394,29 @@ BinaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vecto } expr_t -BinaryOpNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const +BinaryOpNode::substituteEndoLagGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::substituteEndoLagGreaterThanTwo, subst_table, neweqs); } expr_t -BinaryOpNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +BinaryOpNode::substituteExoLead(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const { expr_t arg1subst, arg2subst; int maxexolead1 = arg1->maxExoLead(), maxexolead2 = arg2->maxExoLead(); if (maxexolead1 < 1 && maxexolead2 < 1) - return const_cast(this); + return const_cast(this); if (deterministic_model) { - arg1subst = maxexolead1 >= 1 ? arg1->substituteExoLead(subst_table, neweqs, deterministic_model) : arg1; - arg2subst = maxexolead2 >= 1 ? arg2->substituteExoLead(subst_table, neweqs, deterministic_model) : arg2; + arg1subst = maxexolead1 >= 1 + ? arg1->substituteExoLead(subst_table, neweqs, deterministic_model) + : arg1; + arg2subst = maxexolead2 >= 1 + ? arg2->substituteExoLead(subst_table, neweqs, deterministic_model) + : arg2; return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); } else @@ -5299,8 +5425,12 @@ BinaryOpNode::substituteExoLead(subst_table_t &subst_table, vector= 1 ? arg1->substituteExoLead(subst_table, neweqs, deterministic_model) : arg1; - arg2subst = maxexolead2 >= 1 ? arg2->substituteExoLead(subst_table, neweqs, deterministic_model) : arg2; + arg1subst = maxexolead1 >= 1 + ? arg1->substituteExoLead(subst_table, neweqs, deterministic_model) + : arg1; + arg2subst = maxexolead2 >= 1 + ? arg2->substituteExoLead(subst_table, neweqs, deterministic_model) + : arg2; return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree); case BinaryOpcode::times: case BinaryOpcode::divide: @@ -5309,8 +5439,8 @@ BinaryOpNode::substituteExoLead(subst_table_t &subst_table, vectorsubstituteExoLead(subst_table, neweqs, deterministic_model); return buildSimilarBinaryOpNode(arg1subst, arg2, datatree); } - if (maxexolead1 == 0 && arg1->maxEndoLead() == 0 - && maxexolead2 >= 1 && op_code == BinaryOpcode::times) + if (maxexolead1 == 0 && arg1->maxEndoLead() == 0 && maxexolead2 >= 1 + && op_code == BinaryOpcode::times) { arg2subst = arg2->substituteExoLead(subst_table, neweqs, deterministic_model); return buildSimilarBinaryOpNode(arg1, arg2subst, datatree); @@ -5322,15 +5452,17 @@ BinaryOpNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs) const +BinaryOpNode::substituteExoLag(subst_table_t& subst_table, vector& neweqs) const { return recurseTransform(&ExprNode::substituteExoLag, subst_table, neweqs); } expr_t -BinaryOpNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const +BinaryOpNode::substituteExpectation(subst_table_t& subst_table, vector& neweqs, + bool partial_information_model) const { - return recurseTransform(&ExprNode::substituteExpectation, subst_table, neweqs, partial_information_model); + return recurseTransform(&ExprNode::substituteExpectation, subst_table, neweqs, + partial_information_model); } expr_t @@ -5346,34 +5478,36 @@ BinaryOpNode::substituteModelLocalVariables() const } expr_t -BinaryOpNode::substituteVarExpectation(const map &subst_table) const +BinaryOpNode::substituteVarExpectation(const map& subst_table) const { return recurseTransform(&ExprNode::substituteVarExpectation, subst_table); } void -BinaryOpNode::findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const +BinaryOpNode::findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t& nodes) const { arg1->findUnaryOpNodesForAuxVarCreation(nodes); arg2->findUnaryOpNodesForAuxVarCreation(nodes); } void -BinaryOpNode::findDiffNodes(lag_equivalence_table_t &nodes) const +BinaryOpNode::findDiffNodes(lag_equivalence_table_t& nodes) const { arg1->findDiffNodes(nodes); arg2->findDiffNodes(nodes); } expr_t -BinaryOpNode::substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, - vector &neweqs) const +BinaryOpNode::substituteDiff(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::substituteDiff, nodes, subst_table, neweqs); } expr_t -BinaryOpNode::substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const +BinaryOpNode::substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, + subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::substituteUnaryOpNodes, nodes, subst_table, neweqs); } @@ -5385,19 +5519,20 @@ BinaryOpNode::countDiffs() const } expr_t -BinaryOpNode::substitutePacExpectation(const string &name, expr_t subexpr) +BinaryOpNode::substitutePacExpectation(const string& name, expr_t subexpr) { return recurseTransform(&ExprNode::substitutePacExpectation, name, subexpr); } expr_t -BinaryOpNode::substitutePacTargetNonstationary(const string &name, expr_t subexpr) +BinaryOpNode::substitutePacTargetNonstationary(const string& name, expr_t subexpr) { return recurseTransform(&ExprNode::substitutePacTargetNonstationary, name, subexpr); } expr_t -BinaryOpNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const +BinaryOpNode::differentiateForwardVars(const vector& subset, subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::differentiateForwardVars, subset, subst_table, neweqs); } @@ -5407,7 +5542,8 @@ BinaryOpNode::addMultipliersToConstraints(int i) { int symb_id = datatree.symbol_table.addMultiplierAuxiliaryVar(i); expr_t newAuxLM = datatree.AddVariable(symb_id, 0); - return datatree.AddEqual(datatree.AddTimes(newAuxLM, datatree.AddMinus(arg1, arg2)), datatree.Zero); + return datatree.AddEqual(datatree.AddTimes(newAuxLM, datatree.AddMinus(arg1, arg2)), + datatree.Zero); } bool @@ -5425,15 +5561,17 @@ BinaryOpNode::isVariableNodeEqualTo([[maybe_unused]] SymbolType type_arg, } bool -BinaryOpNode::containsPacExpectation(const string &pac_model_name) const +BinaryOpNode::containsPacExpectation(const string& pac_model_name) const { - return arg1->containsPacExpectation(pac_model_name) || arg2->containsPacExpectation(pac_model_name); + return arg1->containsPacExpectation(pac_model_name) + || arg2->containsPacExpectation(pac_model_name); } bool -BinaryOpNode::containsPacTargetNonstationary(const string &pac_model_name) const +BinaryOpNode::containsPacTargetNonstationary(const string& pac_model_name) const { - return arg1->containsPacTargetNonstationary(pac_model_name) || arg2->containsPacTargetNonstationary(pac_model_name); + return arg1->containsPacTargetNonstationary(pac_model_name) + || arg2->containsPacTargetNonstationary(pac_model_name); } expr_t @@ -5449,7 +5587,7 @@ BinaryOpNode::detrend(int symb_id, bool log_trend, expr_t trend) const } expr_t -BinaryOpNode::removeTrendLeadLag(const map &trend_symbols_map) const +BinaryOpNode::removeTrendLeadLag(const map& trend_symbols_map) const { return recurseTransform(&ExprNode::removeTrendLeadLag, trend_symbols_map); } @@ -5479,8 +5617,7 @@ BinaryOpNode::findTargetVariableHelper1(int lhs_symb_id, int rhs_symb_id) const } optional -BinaryOpNode::findTargetVariableHelper(const expr_t arg1, const expr_t arg2, - int lhs_symb_id) const +BinaryOpNode::findTargetVariableHelper(const expr_t arg1, const expr_t arg2, int lhs_symb_id) const { set params; arg1->collectVariables(SymbolType::parameter, params); @@ -5489,10 +5626,9 @@ BinaryOpNode::findTargetVariableHelper(const expr_t arg1, const expr_t arg2, set> endogs; arg2->collectDynamicVariables(SymbolType::endogenous, endogs); - if (auto testarg2 = dynamic_cast(arg2); + if (auto testarg2 = dynamic_cast(arg2); endogs.size() == 2 && testarg2 && testarg2->op_code == BinaryOpcode::minus - && dynamic_cast(testarg2->arg1) - && dynamic_cast(testarg2->arg2)) + && dynamic_cast(testarg2->arg1) && dynamic_cast(testarg2->arg2)) { if (findTargetVariableHelper1(lhs_symb_id, endogs.begin()->first)) return endogs.rbegin()->first; @@ -5516,26 +5652,27 @@ BinaryOpNode::findTargetVariable(int lhs_symb_id) const } void -BinaryOpNode::getPacAREC(int lhs_symb_id, int lhs_orig_symb_id, - pair>> &ec_params_and_vars, - vector, optional, int>> &ar_params_and_vars, - vector, double>> &additive_vars_params_and_constants) const +BinaryOpNode::getPacAREC( + int lhs_symb_id, int lhs_orig_symb_id, + pair>>& ec_params_and_vars, + vector, optional, int>>& ar_params_and_vars, + vector, double>>& additive_vars_params_and_constants) const { ec_params_and_vars.first = -1; vector> terms; decomposeAdditiveTerms(terms, 1); for (auto it = terms.begin(); it != terms.end(); ++it) - if (auto bopn = dynamic_cast(it->first); bopn) + if (auto bopn = dynamic_cast(it->first); bopn) { try { auto [param_id, target_id] = bopn->matchParamTimesTargetMinusVariable(lhs_orig_symb_id); - ec_params_and_vars = { param_id, { { target_id, true, 1 }, { lhs_orig_symb_id, false, -1 }}}; + ec_params_and_vars = {param_id, {{target_id, true, 1}, {lhs_orig_symb_id, false, -1}}}; terms.erase(it); break; } - catch (MatchFailureException &e) + catch (MatchFailureException& e) { } } @@ -5546,9 +5683,9 @@ BinaryOpNode::getPacAREC(int lhs_symb_id, int lhs_orig_symb_id, exit(EXIT_FAILURE); } - for (const auto &[term, sign] : terms) + for (const auto& [term, sign] : terms) { - if (dynamic_cast(term)) + if (dynamic_cast(term)) continue; optional pid; @@ -5558,23 +5695,23 @@ BinaryOpNode::getPacAREC(int lhs_symb_id, int lhs_orig_symb_id, auto [vid, lag, pid, constant] = term->matchVariableTimesConstantTimesParam(true); linear_combination.emplace_back(vid.value(), lag, move(pid), constant); } - catch (MatchFailureException &e) + catch (MatchFailureException& e) { try { tie(pid, linear_combination) = term->matchParamTimesLinearCombinationOfVariables(); } - catch (MatchFailureException &e) + catch (MatchFailureException& e) { cerr << "Unsupported expression in PAC equation" << endl; exit(EXIT_FAILURE); } } - for (auto &[vid, vlag, pidtmp, constant] : linear_combination) + for (auto& [vid, vlag, pidtmp, constant] : linear_combination) constant *= sign; // Update sign of constants - for (const auto &[vid, vlag, pidtmp, constant] : linear_combination) + for (const auto& [vid, vlag, pidtmp, constant] : linear_combination) { if (!pid) pid = pidtmp; @@ -5590,12 +5727,14 @@ BinaryOpNode::getPacAREC(int lhs_symb_id, int lhs_orig_symb_id, // This is an autoregressive term if (constant != 1 || !pid || !datatree.symbol_table.isDiffAuxiliaryVariable(vid)) { - cerr << "BinaryOpNode::getPacAREC: autoregressive terms must be of the form 'parameter*diff_lagged_variable" << endl; + cerr << "BinaryOpNode::getPacAREC: autoregressive terms must be of the form " + "'parameter*diff_lagged_variable" + << endl; exit(EXIT_FAILURE); } if (static_cast(ar_params_and_vars.size()) < -vlagorig) - ar_params_and_vars.resize(-vlagorig, { nullopt, nullopt, 0 }); - ar_params_and_vars[-vlagorig-1] = { pid, vid, vlag }; + ar_params_and_vars.resize(-vlagorig, {nullopt, nullopt, 0}); + ar_params_and_vars[-vlagorig - 1] = {pid, vid, vlag}; } else // This is a residual additive term @@ -5610,8 +5749,8 @@ BinaryOpNode::isParamTimesEndogExpr() const if (op_code == BinaryOpcode::times) { set params; - auto test_arg1 = dynamic_cast(arg1); - auto test_arg2 = dynamic_cast(arg2); + auto test_arg1 = dynamic_cast(arg1); + auto test_arg2 = dynamic_cast(arg2); if (test_arg1) arg1->collectVariables(SymbolType::parameter, params); else if (test_arg2) @@ -5656,11 +5795,11 @@ BinaryOpNode::getPacNonOptimizingPart(int optim_share_symb_id) const expr_t one_minus_optim_share = nullptr; for (auto [factor, exponent] : factors) { - auto bopn = dynamic_cast(factor); + auto bopn = dynamic_cast(factor); if (exponent != 1 || !bopn || bopn->op_code != BinaryOpcode::minus) continue; - auto arg1 = dynamic_cast(bopn->arg1); - auto arg2 = dynamic_cast(bopn->arg2); + auto arg1 = dynamic_cast(bopn->arg1); + auto arg2 = dynamic_cast(bopn->arg2); if (arg1 && arg2 && arg1->eval({}) == 1 && arg2->symb_id == optim_share_symb_id) { one_minus_optim_share = factor; @@ -5717,21 +5856,21 @@ BinaryOpNode::getPacOptimizingShareAndExprNodes(int lhs_orig_symb_id) const { vector> terms; decomposeAdditiveTerms(terms, 1); - for (auto &it : terms) - if (dynamic_cast(it.first)) + for (auto& it : terms) + if (dynamic_cast(it.first)) // if the pac_expectation operator is additive in the expression // there are no optimizing shares - return { nullopt, nullptr, nullptr, nullptr }; + return {nullopt, nullptr, nullptr, nullptr}; optional optim_share; expr_t optim_part, non_optim_part, additive_part; optim_part = non_optim_part = additive_part = nullptr; for (auto it = terms.begin(); it != terms.end(); ++it) - if (auto bopn = dynamic_cast(it->first); bopn) + if (auto bopn = dynamic_cast(it->first); bopn) { tie(optim_share, optim_part) - = bopn->getPacOptimizingShareAndExprNodesHelper(lhs_orig_symb_id); + = bopn->getPacOptimizingShareAndExprNodesHelper(lhs_orig_symb_id); if (optim_share && optim_part) { terms.erase(it); @@ -5740,10 +5879,10 @@ BinaryOpNode::getPacOptimizingShareAndExprNodes(int lhs_orig_symb_id) const } if (!optim_part) - return { nullopt, nullptr, nullptr, nullptr }; + return {nullopt, nullptr, nullptr, nullptr}; for (auto it = terms.begin(); it != terms.end(); ++it) - if (auto bopn = dynamic_cast(it->first); bopn) + if (auto bopn = dynamic_cast(it->first); bopn) { non_optim_part = bopn->getPacNonOptimizingPart(optim_share.value()); if (non_optim_part) @@ -5754,7 +5893,7 @@ BinaryOpNode::getPacOptimizingShareAndExprNodes(int lhs_orig_symb_id) const } if (!non_optim_part) - return { nullopt, nullptr, nullptr, nullptr }; + return {nullopt, nullptr, nullptr, nullptr}; else { additive_part = datatree.Zero; @@ -5764,15 +5903,16 @@ BinaryOpNode::getPacOptimizingShareAndExprNodes(int lhs_orig_symb_id) const additive_part = nullptr; } - return { optim_share, optim_part, non_optim_part, additive_part }; + return {optim_share, optim_part, non_optim_part, additive_part}; } void -BinaryOpNode::fillAutoregressiveRow(int eqn, const vector &lhs, map, expr_t> &AR) const +BinaryOpNode::fillAutoregressiveRow(int eqn, const vector& lhs, + map, expr_t>& AR) const { vector> terms; decomposeAdditiveTerms(terms, 1); - for (const auto &it : terms) + for (const auto& it : terms) { optional vid, param_id; int lag; @@ -5782,7 +5922,7 @@ BinaryOpNode::fillAutoregressiveRow(int eqn, const vector &lhs, mapmatchVariableTimesConstantTimesParam(true); constant *= it.second; } - catch (MatchFailureException &e) + catch (MatchFailureException& e) { continue; } @@ -5800,7 +5940,9 @@ BinaryOpNode::fillAutoregressiveRow(int eqn, const vector &lhs, map &lhs, map &table) const +BinaryOpNode::findConstantEquations(map& table) const { if (op_code == BinaryOpcode::equal) { // The variable must be contemporaneous (see #83) - if (auto varg1 = dynamic_cast(arg1); - varg1 && varg1->lag == 0 && dynamic_cast(arg2)) - table[varg1] = dynamic_cast(arg2); - else if (auto varg2 = dynamic_cast(arg2); - varg2 && varg2->lag == 0 && dynamic_cast(arg1)) - table[varg2] = dynamic_cast(arg1); + if (auto varg1 = dynamic_cast(arg1); + varg1 && varg1->lag == 0 && dynamic_cast(arg2)) + table[varg1] = dynamic_cast(arg2); + else if (auto varg2 = dynamic_cast(arg2); + varg2 && varg2->lag == 0 && dynamic_cast(arg1)) + table[varg2] = dynamic_cast(arg1); } } expr_t -BinaryOpNode::replaceVarsInEquation(map &table) const +BinaryOpNode::replaceVarsInEquation(map& table) const { if (op_code == BinaryOpcode::equal) - for (auto &it : table) + for (auto& it : table) if ((it.first == arg1 && it.second == arg2) || (it.first == arg2 && it.second == arg1)) - return const_cast(this); + return const_cast(this); return recurseTransform(&ExprNode::replaceVarsInEquation, table); } void -BinaryOpNode::matchMatchedMoment(vector &symb_ids, vector &lags, vector &powers) const +BinaryOpNode::matchMatchedMoment(vector& symb_ids, vector& lags, + vector& powers) const { if (op_code == BinaryOpcode::times) { @@ -5842,19 +5985,21 @@ BinaryOpNode::matchMatchedMoment(vector &symb_ids, vector &lags, vecto } else if (op_code == BinaryOpcode::power) { - if (!dynamic_cast(arg1)) - throw MatchFailureException{"First argument of power expression must be a variable"}; - auto ncn = dynamic_cast(arg2); + if (!dynamic_cast(arg1)) + throw MatchFailureException {"First argument of power expression must be a variable"}; + auto ncn = dynamic_cast(arg2); if (!ncn) - throw MatchFailureException{"Second argument of power expression must be a positive integer"}; + throw MatchFailureException { + "Second argument of power expression must be a positive integer"}; double c = datatree.num_constants.getDouble(ncn->id); if (c <= 0 || round(c) != c) - throw MatchFailureException{"Second argument of power expression must be a positive integer"}; + throw MatchFailureException { + "Second argument of power expression must be a positive integer"}; arg1->matchMatchedMoment(symb_ids, lags, powers); powers.back() = static_cast(c); } else - throw MatchFailureException{"Unsupported binary operator"}; + throw MatchFailureException {"Unsupported binary operator"}; } expr_t @@ -5863,13 +6008,14 @@ BinaryOpNode::substituteLogTransform(int orig_symb_id, int aux_symb_id) const return recurseTransform(&ExprNode::substituteLogTransform, orig_symb_id, aux_symb_id); } -TrinaryOpNode::TrinaryOpNode(DataTree &datatree_arg, int idx_arg, const expr_t arg1_arg, - TrinaryOpcode op_code_arg, const expr_t arg2_arg, const expr_t arg3_arg) : - ExprNode{datatree_arg, idx_arg}, - arg1{arg1_arg}, - arg2{arg2_arg}, - arg3{arg3_arg}, - op_code{op_code_arg} +TrinaryOpNode::TrinaryOpNode(DataTree& datatree_arg, int idx_arg, const expr_t arg1_arg, + TrinaryOpcode op_code_arg, const expr_t arg2_arg, + const expr_t arg3_arg) : + ExprNode {datatree_arg, idx_arg}, + arg1 {arg1_arg}, + arg2 {arg2_arg}, + arg3 {arg3_arg}, + op_code {op_code_arg} { } @@ -5888,40 +6034,34 @@ TrinaryOpNode::prepareForDerivation() // Non-null derivatives are the union of those of the arguments // Compute set union of arg{1,2,3}->non_null_derivatives set non_null_derivatives_tmp; - set_union(arg1->non_null_derivatives.begin(), - arg1->non_null_derivatives.end(), - arg2->non_null_derivatives.begin(), - arg2->non_null_derivatives.end(), + set_union(arg1->non_null_derivatives.begin(), arg1->non_null_derivatives.end(), + arg2->non_null_derivatives.begin(), arg2->non_null_derivatives.end(), inserter(non_null_derivatives_tmp, non_null_derivatives_tmp.begin())); - set_union(non_null_derivatives_tmp.begin(), - non_null_derivatives_tmp.end(), - arg3->non_null_derivatives.begin(), - arg3->non_null_derivatives.end(), + set_union(non_null_derivatives_tmp.begin(), non_null_derivatives_tmp.end(), + arg3->non_null_derivatives.begin(), arg3->non_null_derivatives.end(), inserter(non_null_derivatives, non_null_derivatives.begin())); } void -TrinaryOpNode::prepareForChainRuleDerivation(const map &recursive_variables, - unordered_map> &non_null_chain_rule_derivatives) const +TrinaryOpNode::prepareForChainRuleDerivation( + const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const { - if (non_null_chain_rule_derivatives.contains(const_cast(this))) + if (non_null_chain_rule_derivatives.contains(const_cast(this))) return; arg1->prepareForChainRuleDerivation(recursive_variables, non_null_chain_rule_derivatives); arg2->prepareForChainRuleDerivation(recursive_variables, non_null_chain_rule_derivatives); arg3->prepareForChainRuleDerivation(recursive_variables, non_null_chain_rule_derivatives); - set &nnd { non_null_chain_rule_derivatives[const_cast(this)] }; + set& nnd {non_null_chain_rule_derivatives[const_cast(this)]}; set nnd_tmp; set_union(non_null_chain_rule_derivatives.at(arg1).begin(), non_null_chain_rule_derivatives.at(arg1).end(), non_null_chain_rule_derivatives.at(arg2).begin(), - non_null_chain_rule_derivatives.at(arg2).end(), - inserter(nnd_tmp, nnd_tmp.begin())); - set_union(nnd_tmp.begin(), nnd_tmp.end(), - non_null_chain_rule_derivatives.at(arg3).begin(), - non_null_chain_rule_derivatives.at(arg3).end(), - inserter(nnd, nnd.begin())); + non_null_chain_rule_derivatives.at(arg2).end(), inserter(nnd_tmp, nnd_tmp.begin())); + set_union(nnd_tmp.begin(), nnd_tmp.end(), non_null_chain_rule_derivatives.at(arg3).begin(), + non_null_chain_rule_derivatives.at(arg3).end(), inserter(nnd, nnd.begin())); } expr_t @@ -5961,7 +6101,7 @@ TrinaryOpNode::composeDerivatives(expr_t darg1, expr_t darg2, expr_t darg3) // derivatives thru sigma t11 = datatree.AddDivide(y, arg3); t12 = datatree.AddTimes(t11, darg3); - //intermediary sum + // intermediary sum t11 = datatree.AddMinus(t14, t12); // total derivative: // (darg1/sigma - darg2/sigma - darg3*(x-mu)/sigma^2) * t15 @@ -6002,10 +6142,10 @@ TrinaryOpNode::computeDerivative(int deriv_id) int TrinaryOpNode::precedence([[maybe_unused]] ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms) const + const temporary_terms_t& temporary_terms) const { // A temporary term behaves as a variable - if (temporary_terms.contains(const_cast(this))) + if (temporary_terms.contains(const_cast(this))) return 100; switch (op_code) @@ -6018,32 +6158,33 @@ TrinaryOpNode::precedence([[maybe_unused]] ExprNodeOutputType output_type, } int -TrinaryOpNode::cost(const map, unordered_set> &temp_terms_map, bool is_matlab) const +TrinaryOpNode::cost(const map, unordered_set>& temp_terms_map, + bool is_matlab) const { // For a temporary term, the cost is null - for (const auto &it : temp_terms_map) - if (it.second.contains(const_cast(this))) + for (const auto& it : temp_terms_map) + if (it.second.contains(const_cast(this))) return 0; - int arg_cost = arg1->cost(temp_terms_map, is_matlab) - + arg2->cost(temp_terms_map, is_matlab) - + arg3->cost(temp_terms_map, is_matlab); + int arg_cost = arg1->cost(temp_terms_map, is_matlab) + arg2->cost(temp_terms_map, is_matlab) + + arg3->cost(temp_terms_map, is_matlab); return cost(arg_cost, is_matlab); } int -TrinaryOpNode::cost(const vector>> &blocks_temporary_terms, bool is_matlab) const +TrinaryOpNode::cost(const vector>>& blocks_temporary_terms, + bool is_matlab) const { // For a temporary term, the cost is null - for (const auto &blk_tt : blocks_temporary_terms) - for (const auto &eq_tt : blk_tt) - if (eq_tt.contains(const_cast(this))) + for (const auto& blk_tt : blocks_temporary_terms) + for (const auto& eq_tt : blk_tt) + if (eq_tt.contains(const_cast(this))) return 0; int arg_cost = arg1->cost(blocks_temporary_terms, is_matlab) - + arg2->cost(blocks_temporary_terms, is_matlab) - + arg3->cost(blocks_temporary_terms, is_matlab); + + arg2->cost(blocks_temporary_terms, is_matlab) + + arg3->cost(blocks_temporary_terms, is_matlab); return cost(arg_cost, is_matlab); } @@ -6057,7 +6198,7 @@ TrinaryOpNode::cost(int cost, bool is_matlab) const { case TrinaryOpcode::normcdf: case TrinaryOpcode::normpdf: - return cost+1000; + return cost + 1000; } else // Cost for C files @@ -6065,24 +6206,22 @@ TrinaryOpNode::cost(int cost, bool is_matlab) const { case TrinaryOpcode::normcdf: case TrinaryOpcode::normpdf: - return cost+1000; + return cost + 1000; } __builtin_unreachable(); // Silence GCC warning } void -TrinaryOpNode::computeTemporaryTerms(const pair &derivOrder, - map, unordered_set> &temp_terms_map, - unordered_map>> &reference_count, - bool is_matlab) const +TrinaryOpNode::computeTemporaryTerms( + const pair& derivOrder, map, unordered_set>& temp_terms_map, + unordered_map>>& reference_count, bool is_matlab) const { - expr_t this2 = const_cast(this); - if (auto it = reference_count.find(this2); - it == reference_count.end()) + expr_t this2 = const_cast(this); + if (auto it = reference_count.find(this2); it == reference_count.end()) { // If this node has never been encountered, set its ref count to one, // and travel through its children - reference_count[this2] = { 1, derivOrder }; + reference_count[this2] = {1, derivOrder}; arg1->computeTemporaryTerms(derivOrder, temp_terms_map, reference_count, is_matlab); arg2->computeTemporaryTerms(derivOrder, temp_terms_map, reference_count, is_matlab); arg3->computeTemporaryTerms(derivOrder, temp_terms_map, reference_count, is_matlab); @@ -6091,7 +6230,7 @@ TrinaryOpNode::computeTemporaryTerms(const pair &derivOrder, { // If the node has already been encountered, increment its ref count // and declare it as a temporary term if it is too costly - auto &[nref, min_order] = it->second; + auto& [nref, min_order] = it->second; nref++; if (nref * cost(temp_terms_map, is_matlab) > min_cost(is_matlab)) temp_terms_map[min_order].insert(this2); @@ -6099,21 +6238,21 @@ TrinaryOpNode::computeTemporaryTerms(const pair &derivOrder, } void -TrinaryOpNode::computeBlockTemporaryTerms(int blk, int eq, vector>> &blocks_temporary_terms, - unordered_map> &reference_count) const +TrinaryOpNode::computeBlockTemporaryTerms( + int blk, int eq, vector>>& blocks_temporary_terms, + unordered_map>& reference_count) const { - expr_t this2 = const_cast(this); - if (auto it = reference_count.find(this2); - it == reference_count.end()) + expr_t this2 = const_cast(this); + if (auto it = reference_count.find(this2); it == reference_count.end()) { - reference_count[this2] = { 1, blk, eq }; + reference_count[this2] = {1, blk, eq}; arg1->computeBlockTemporaryTerms(blk, eq, blocks_temporary_terms, reference_count); arg2->computeBlockTemporaryTerms(blk, eq, blocks_temporary_terms, reference_count); arg3->computeBlockTemporaryTerms(blk, eq, blocks_temporary_terms, reference_count); } else { - auto &[nref, first_blk, first_eq] = it->second; + auto& [nref, first_blk, first_eq] = it->second; nref++; if (nref * cost(blocks_temporary_terms, false) > min_cost_c) blocks_temporary_terms[first_blk][first_eq].insert(this2); @@ -6126,15 +6265,15 @@ TrinaryOpNode::eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v switch (op_code) { case TrinaryOpcode::normcdf: - return (0.5*(1+erf((v1-v2)/v3/numbers::sqrt2))); + return (0.5 * (1 + erf((v1 - v2) / v3 / numbers::sqrt2))); case TrinaryOpcode::normpdf: - return (1/(v3*sqrt(2*numbers::pi)*exp(pow((v1-v2)/v3, 2)/2))); + return (1 / (v3 * sqrt(2 * numbers::pi) * exp(pow((v1 - v2) / v3, 2) / 2))); } __builtin_unreachable(); // Silence GCC warning } double -TrinaryOpNode::eval(const eval_context_t &eval_context) const noexcept(false) +TrinaryOpNode::eval(const eval_context_t& eval_context) const noexcept(false) { double v1 = arg1->eval(eval_context); double v2 = arg2->eval(eval_context); @@ -6144,31 +6283,35 @@ TrinaryOpNode::eval(const eval_context_t &eval_context) const noexcept(false) } void -TrinaryOpNode::writeBytecodeOutput(BytecodeWriter &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 +TrinaryOpNode::writeBytecodeOutput(BytecodeWriter& 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 { assert(!isAssignmentLHSBytecodeOutput(output_type)); - if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, + temporary_terms_idxs)) return; - 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); - arg3->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); - code_file << FTRINARY_{op_code}; + 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); + arg3->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); + code_file << FTRINARY_ {op_code}; } bool TrinaryOpNode::containsExternalFunction() const { - return arg1->containsExternalFunction() - || arg2->containsExternalFunction() - || arg3->containsExternalFunction(); + return arg1->containsExternalFunction() || arg2->containsExternalFunction() + || arg3->containsExternalFunction(); } void -TrinaryOpNode::writeJsonAST(ostream &output) const +TrinaryOpNode::writeJsonAST(ostream& output) const { output << R"({"node_type" : "TrinaryOpNode", )" << R"("op" : ")"; @@ -6191,13 +6334,11 @@ TrinaryOpNode::writeJsonAST(ostream &output) const } void -TrinaryOpNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - const deriv_node_temp_terms_t &tef_terms, - bool isdynamic) const +TrinaryOpNode::writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms, + const deriv_node_temp_terms_t& tef_terms, bool isdynamic) const { // If current node is a temporary term - if (temporary_terms.contains(const_cast(this))) + if (temporary_terms.contains(const_cast(this))) { output << "T" << idx; return; @@ -6222,10 +6363,10 @@ TrinaryOpNode::writeJsonOutput(ostream &output, } void -TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType 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 +TrinaryOpNode::writeOutput(ostream& output, ExprNodeOutputType 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 { if (checkIfTemporaryTermThenWrite(output, output_type, temporary_terms, temporary_terms_idxs)) return; @@ -6245,8 +6386,8 @@ TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output << ")/M_SQRT2)))"; } else if (isJuliaOutput(output_type)) - { - // Julia API is normcdf(mu, sigma, x) ! + { + // Julia API is normcdf(mu, sigma, x) ! output << "normcdf"; if (output_type == ExprNodeOutputType::juliaTimeDataFrame) output << "."; @@ -6284,8 +6425,8 @@ TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output << ",2)/2)))"; } else if (isJuliaOutput(output_type)) - { - // Julia API is normpdf(mu, sigma, x) ! + { + // Julia API is normpdf(mu, sigma, x) ! output << "normpdf("; arg2->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); output << ","; @@ -6312,20 +6453,23 @@ TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, } void -TrinaryOpNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, - deriv_node_temp_terms_t &tef_terms) const +TrinaryOpNode::writeExternalFunctionOutput(ostream& output, ExprNodeOutputType output_type, + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + deriv_node_temp_terms_t& tef_terms) const { - arg1->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); - arg2->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); - arg3->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + arg1->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); + arg2->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); + arg3->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); } void -TrinaryOpNode::writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, +TrinaryOpNode::writeJsonExternalFunctionOutput(vector& efout, + const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, bool isdynamic) const { arg1->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms, isdynamic); @@ -6334,11 +6478,10 @@ TrinaryOpNode::writeJsonExternalFunctionOutput(vector &efout, } void -TrinaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &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 +TrinaryOpNode::writeBytecodeExternalFunctionOutput( + BytecodeWriter& 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 { arg1->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); @@ -6349,14 +6492,14 @@ TrinaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, } void -TrinaryOpNode::collectVARLHSVariable([[maybe_unused]] set &result) const +TrinaryOpNode::collectVARLHSVariable([[maybe_unused]] set& result) const { cerr << "ERROR: you can only have variables or unary ops on LHS of VAR" << endl; exit(EXIT_FAILURE); } void -TrinaryOpNode::collectDynamicVariables(SymbolType type_arg, set> &result) const +TrinaryOpNode::collectDynamicVariables(SymbolType type_arg, set>& result) const { arg1->collectDynamicVariables(type_arg, result); arg2->collectDynamicVariables(type_arg, result); @@ -6364,36 +6507,41 @@ TrinaryOpNode::collectDynamicVariables(SymbolType type_arg, set> } void -TrinaryOpNode::computeSubExprContainingVariable(int symb_id, int lag, set &contain_var) const +TrinaryOpNode::computeSubExprContainingVariable(int symb_id, int lag, + set& contain_var) const { arg1->computeSubExprContainingVariable(symb_id, lag, contain_var); arg2->computeSubExprContainingVariable(symb_id, lag, contain_var); arg3->computeSubExprContainingVariable(symb_id, lag, contain_var); if (contain_var.contains(arg1) || contain_var.contains(arg2) || contain_var.contains(arg3)) - contain_var.insert(const_cast(this)); + contain_var.insert(const_cast(this)); } -BinaryOpNode * -TrinaryOpNode::normalizeEquationHelper([[maybe_unused]] const set &contain_var, +BinaryOpNode* +TrinaryOpNode::normalizeEquationHelper([[maybe_unused]] const set& contain_var, [[maybe_unused]] expr_t rhs) const { throw NormalizationFailed(); } expr_t -TrinaryOpNode::computeChainRuleDerivative(int deriv_id, - const map &recursive_variables, - unordered_map> &non_null_chain_rule_derivatives, - unordered_map> &cache) +TrinaryOpNode::computeChainRuleDerivative( + int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) { - expr_t darg1 = arg1->getChainRuleDerivative(deriv_id, recursive_variables, non_null_chain_rule_derivatives, cache); - expr_t darg2 = arg2->getChainRuleDerivative(deriv_id, recursive_variables, non_null_chain_rule_derivatives, cache); - expr_t darg3 = arg3->getChainRuleDerivative(deriv_id, recursive_variables, non_null_chain_rule_derivatives, cache); + expr_t darg1 = arg1->getChainRuleDerivative(deriv_id, recursive_variables, + non_null_chain_rule_derivatives, cache); + expr_t darg2 = arg2->getChainRuleDerivative(deriv_id, recursive_variables, + non_null_chain_rule_derivatives, cache); + expr_t darg3 = arg3->getChainRuleDerivative(deriv_id, recursive_variables, + non_null_chain_rule_derivatives, cache); return composeDerivatives(darg1, darg2, darg3); } expr_t -TrinaryOpNode::buildSimilarTrinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, expr_t alt_arg3, DataTree &alt_datatree) const +TrinaryOpNode::buildSimilarTrinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, expr_t alt_arg3, + DataTree& alt_datatree) const { switch (op_code) { @@ -6406,7 +6554,7 @@ TrinaryOpNode::buildSimilarTrinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, expr_ } expr_t -TrinaryOpNode::toStatic(DataTree &static_datatree) const +TrinaryOpNode::toStatic(DataTree& static_datatree) const { expr_t sarg1 = arg1->toStatic(static_datatree); expr_t sarg2 = arg2->toStatic(static_datatree); @@ -6415,7 +6563,7 @@ TrinaryOpNode::toStatic(DataTree &static_datatree) const } void -TrinaryOpNode::computeXrefs(EquationInfo &ei) const +TrinaryOpNode::computeXrefs(EquationInfo& ei) const { arg1->computeXrefs(ei); arg2->computeXrefs(ei); @@ -6423,7 +6571,7 @@ TrinaryOpNode::computeXrefs(EquationInfo &ei) const } expr_t -TrinaryOpNode::clone(DataTree &alt_datatree) const +TrinaryOpNode::clone(DataTree& alt_datatree) const { expr_t substarg1 = arg1->clone(alt_datatree); expr_t substarg2 = arg2->clone(alt_datatree); @@ -6481,11 +6629,10 @@ TrinaryOpNode::undiff() const } int -TrinaryOpNode::VarMaxLag(const set &lhs_lag_equiv) const +TrinaryOpNode::VarMaxLag(const set& lhs_lag_equiv) const { return max(arg1->VarMaxLag(lhs_lag_equiv), - max(arg2->VarMaxLag(lhs_lag_equiv), - arg3->VarMaxLag(lhs_lag_equiv))); + max(arg2->VarMaxLag(lhs_lag_equiv), arg3->VarMaxLag(lhs_lag_equiv))); } expr_t @@ -6501,27 +6648,32 @@ TrinaryOpNode::decreaseLeadsLagsPredeterminedVariables() const } expr_t -TrinaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +TrinaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs, + bool deterministic_model) const { if (maxEndoLead() < 2) - return const_cast(this); + return const_cast(this); else if (deterministic_model) - return recurseTransform(&ExprNode::substituteEndoLeadGreaterThanTwo, subst_table, neweqs, deterministic_model); + return recurseTransform(&ExprNode::substituteEndoLeadGreaterThanTwo, subst_table, neweqs, + deterministic_model); else return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs); } expr_t -TrinaryOpNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const +TrinaryOpNode::substituteEndoLagGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::substituteEndoLagGreaterThanTwo, subst_table, neweqs); } expr_t -TrinaryOpNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +TrinaryOpNode::substituteExoLead(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const { if (maxExoLead() == 0) - return const_cast(this); + return const_cast(this); else if (deterministic_model) return recurseTransform(&ExprNode::substituteExoLead, subst_table, neweqs, deterministic_model); else @@ -6529,15 +6681,17 @@ TrinaryOpNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs) const +TrinaryOpNode::substituteExoLag(subst_table_t& subst_table, vector& neweqs) const { return recurseTransform(&ExprNode::substituteExoLag, subst_table, neweqs); } expr_t -TrinaryOpNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const +TrinaryOpNode::substituteExpectation(subst_table_t& subst_table, vector& neweqs, + bool partial_information_model) const { - return recurseTransform(&ExprNode::substituteExpectation, subst_table, neweqs, partial_information_model); + return recurseTransform(&ExprNode::substituteExpectation, subst_table, neweqs, + partial_information_model); } expr_t @@ -6553,13 +6707,13 @@ TrinaryOpNode::substituteModelLocalVariables() const } expr_t -TrinaryOpNode::substituteVarExpectation(const map &subst_table) const +TrinaryOpNode::substituteVarExpectation(const map& subst_table) const { return recurseTransform(&ExprNode::substituteVarExpectation, subst_table); } void -TrinaryOpNode::findDiffNodes(lag_equivalence_table_t &nodes) const +TrinaryOpNode::findDiffNodes(lag_equivalence_table_t& nodes) const { arg1->findDiffNodes(nodes); arg2->findDiffNodes(nodes); @@ -6567,7 +6721,7 @@ TrinaryOpNode::findDiffNodes(lag_equivalence_table_t &nodes) const } void -TrinaryOpNode::findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const +TrinaryOpNode::findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t& nodes) const { arg1->findUnaryOpNodesForAuxVarCreation(nodes); arg2->findUnaryOpNodesForAuxVarCreation(nodes); @@ -6586,14 +6740,16 @@ TrinaryOpNode::findTargetVariable(int lhs_symb_id) const } expr_t -TrinaryOpNode::substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, - vector &neweqs) const +TrinaryOpNode::substituteDiff(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::substituteDiff, nodes, subst_table, neweqs); } expr_t -TrinaryOpNode::substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const +TrinaryOpNode::substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, + subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::substituteUnaryOpNodes, nodes, subst_table, neweqs); } @@ -6605,19 +6761,20 @@ TrinaryOpNode::countDiffs() const } expr_t -TrinaryOpNode::substitutePacExpectation(const string &name, expr_t subexpr) +TrinaryOpNode::substitutePacExpectation(const string& name, expr_t subexpr) { return recurseTransform(&ExprNode::substitutePacExpectation, name, subexpr); } expr_t -TrinaryOpNode::substitutePacTargetNonstationary(const string &name, expr_t subexpr) +TrinaryOpNode::substitutePacTargetNonstationary(const string& name, expr_t subexpr) { return recurseTransform(&ExprNode::substitutePacTargetNonstationary, name, subexpr); } expr_t -TrinaryOpNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const +TrinaryOpNode::differentiateForwardVars(const vector& subset, subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::differentiateForwardVars, subset, subst_table, neweqs); } @@ -6637,17 +6794,19 @@ TrinaryOpNode::isVariableNodeEqualTo([[maybe_unused]] SymbolType type_arg, } bool -TrinaryOpNode::containsPacExpectation(const string &pac_model_name) const +TrinaryOpNode::containsPacExpectation(const string& pac_model_name) const { - return (arg1->containsPacExpectation(pac_model_name) || arg2->containsPacExpectation(pac_model_name) || arg3->containsPacExpectation(pac_model_name)); + return (arg1->containsPacExpectation(pac_model_name) + || arg2->containsPacExpectation(pac_model_name) + || arg3->containsPacExpectation(pac_model_name)); } bool -TrinaryOpNode::containsPacTargetNonstationary(const string &pac_model_name) const +TrinaryOpNode::containsPacTargetNonstationary(const string& pac_model_name) const { return arg1->containsPacTargetNonstationary(pac_model_name) - || arg2->containsPacTargetNonstationary(pac_model_name) - || arg3->containsPacTargetNonstationary(pac_model_name); + || arg2->containsPacTargetNonstationary(pac_model_name) + || arg3->containsPacTargetNonstationary(pac_model_name); } expr_t @@ -6663,7 +6822,7 @@ TrinaryOpNode::detrend(int symb_id, bool log_trend, expr_t trend) const } expr_t -TrinaryOpNode::removeTrendLeadLag(const map &trend_symbols_map) const +TrinaryOpNode::removeTrendLeadLag(const map& trend_symbols_map) const { return recurseTransform(&ExprNode::removeTrendLeadLag, trend_symbols_map); } @@ -6677,13 +6836,12 @@ TrinaryOpNode::isInStaticForm() const bool TrinaryOpNode::isParamTimesEndogExpr() const { - return arg1->isParamTimesEndogExpr() - || arg2->isParamTimesEndogExpr() - || arg3->isParamTimesEndogExpr(); + return arg1->isParamTimesEndogExpr() || arg2->isParamTimesEndogExpr() + || arg3->isParamTimesEndogExpr(); } expr_t -TrinaryOpNode::replaceVarsInEquation(map &table) const +TrinaryOpNode::replaceVarsInEquation(map& table) const { return recurseTransform(&ExprNode::replaceVarsInEquation, table); } @@ -6694,13 +6852,10 @@ TrinaryOpNode::substituteLogTransform(int orig_symb_id, int aux_symb_id) const return recurseTransform(&ExprNode::substituteLogTransform, orig_symb_id, aux_symb_id); } -AbstractExternalFunctionNode::AbstractExternalFunctionNode(DataTree &datatree_arg, - int idx_arg, +AbstractExternalFunctionNode::AbstractExternalFunctionNode(DataTree& datatree_arg, int idx_arg, int symb_id_arg, vector arguments_arg) : - ExprNode{datatree_arg, idx_arg}, - symb_id{symb_id_arg}, - arguments{move(arguments_arg)} + ExprNode {datatree_arg, idx_arg}, symb_id {symb_id_arg}, arguments {move(arguments_arg)} { } @@ -6717,8 +6872,7 @@ AbstractExternalFunctionNode::prepareForDerivation() for (int i = 1; i < static_cast(arguments.size()); i++) { set non_null_derivatives_tmp; - set_union(non_null_derivatives.begin(), - non_null_derivatives.end(), + set_union(non_null_derivatives.begin(), non_null_derivatives.end(), arguments.at(i)->non_null_derivatives.begin(), arguments.at(i)->non_null_derivatives.end(), inserter(non_null_derivatives_tmp, non_null_derivatives_tmp.begin())); @@ -6729,23 +6883,24 @@ AbstractExternalFunctionNode::prepareForDerivation() } void -AbstractExternalFunctionNode::prepareForChainRuleDerivation(const map &recursive_variables, - unordered_map> &non_null_chain_rule_derivatives) const +AbstractExternalFunctionNode::prepareForChainRuleDerivation( + const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const { - if (non_null_chain_rule_derivatives.contains(const_cast(this))) + if (non_null_chain_rule_derivatives.contains(const_cast(this))) return; for (auto argument : arguments) argument->prepareForChainRuleDerivation(recursive_variables, non_null_chain_rule_derivatives); - non_null_chain_rule_derivatives.emplace(const_cast(this), + non_null_chain_rule_derivatives.emplace(const_cast(this), non_null_chain_rule_derivatives.at(arguments.at(0))); - set &nnd { non_null_chain_rule_derivatives.at(const_cast(this)) }; + set& nnd { + non_null_chain_rule_derivatives.at(const_cast(this))}; for (int i {1}; i < static_cast(arguments.size()); i++) { set nnd_tmp; - set_union(nnd.begin(), nnd.end(), - non_null_chain_rule_derivatives.at(arguments.at(i)).begin(), + set_union(nnd.begin(), nnd.end(), non_null_chain_rule_derivatives.at(arguments.at(i)).begin(), non_null_chain_rule_derivatives.at(arguments.at(i)).end(), inserter(nnd_tmp, nnd_tmp.begin())); nnd = move(nnd_tmp); @@ -6763,55 +6918,57 @@ AbstractExternalFunctionNode::computeDerivative(int deriv_id) } expr_t -AbstractExternalFunctionNode::computeChainRuleDerivative(int deriv_id, - const map &recursive_variables, - unordered_map> &non_null_chain_rule_derivatives, - unordered_map> &cache) +AbstractExternalFunctionNode::computeChainRuleDerivative( + int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) { assert(datatree.external_functions_table.getNargs(symb_id) > 0); vector dargs; for (auto argument : arguments) - dargs.push_back(argument->getChainRuleDerivative(deriv_id, recursive_variables, non_null_chain_rule_derivatives, cache)); + dargs.push_back(argument->getChainRuleDerivative(deriv_id, recursive_variables, + non_null_chain_rule_derivatives, cache)); return composeDerivatives(dargs); } void -AbstractExternalFunctionNode::writeBytecodeExternalFunctionArguments(BytecodeWriter &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 +AbstractExternalFunctionNode::writeBytecodeExternalFunctionArguments( + BytecodeWriter& 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 { for (auto argument : arguments) - argument->writeBytecodeOutput(code_file, output_type, temporary_terms, - temporary_terms_idxs, tef_terms); + argument->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); } void -AbstractExternalFunctionNode::collectVARLHSVariable([[maybe_unused]] set &result) const +AbstractExternalFunctionNode::collectVARLHSVariable([[maybe_unused]] set& result) const { cerr << "ERROR: you can only have variables or unary ops on LHS of VAR" << endl; exit(EXIT_FAILURE); } void -AbstractExternalFunctionNode::collectDynamicVariables(SymbolType type_arg, set> &result) const +AbstractExternalFunctionNode::collectDynamicVariables(SymbolType type_arg, + set>& result) const { for (auto argument : arguments) argument->collectDynamicVariables(type_arg, result); } double -AbstractExternalFunctionNode::eval([[maybe_unused]] const eval_context_t &eval_context) const noexcept(false) +AbstractExternalFunctionNode::eval([[maybe_unused]] const eval_context_t& eval_context) const + noexcept(false) { throw EvalExternalFunctionException(); } int -AbstractExternalFunctionNode::maxHelper(const function &f) const +AbstractExternalFunctionNode::maxHelper(const function& f) const { - return transform_reduce(arguments.begin(), arguments.end(), 0, - [](int a, int b) { return max(a, b); }, f); + return transform_reduce( + arguments.begin(), arguments.end(), 0, [](int a, int b) { return max(a, b); }, f); } int @@ -6863,7 +7020,7 @@ AbstractExternalFunctionNode::undiff() const } int -AbstractExternalFunctionNode::VarMaxLag(const set &lhs_lag_equiv) const +AbstractExternalFunctionNode::VarMaxLag(const set& lhs_lag_equiv) const { return maxHelper([&](expr_t e) { return e->VarMaxLag(lhs_lag_equiv); }); } @@ -6881,27 +7038,33 @@ AbstractExternalFunctionNode::decreaseLeadsLagsPredeterminedVariables() const } expr_t -AbstractExternalFunctionNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +AbstractExternalFunctionNode::substituteEndoLeadGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs, + bool deterministic_model) const { if (maxEndoLead() < 2) - return const_cast(this); + return const_cast(this); else if (deterministic_model) - return recurseTransform(&ExprNode::substituteEndoLeadGreaterThanTwo, subst_table, neweqs, deterministic_model); + return recurseTransform(&ExprNode::substituteEndoLeadGreaterThanTwo, subst_table, neweqs, + deterministic_model); else return createEndoLeadAuxiliaryVarForMyself(subst_table, neweqs); } expr_t -AbstractExternalFunctionNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const +AbstractExternalFunctionNode::substituteEndoLagGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::substituteEndoLagGreaterThanTwo, subst_table, neweqs); } expr_t -AbstractExternalFunctionNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +AbstractExternalFunctionNode::substituteExoLead(subst_table_t& subst_table, + vector& neweqs, + bool deterministic_model) const { if (maxExoLead() == 0) - return const_cast(this); + return const_cast(this); else if (deterministic_model) return recurseTransform(&ExprNode::substituteExoLead, subst_table, neweqs, deterministic_model); else @@ -6909,15 +7072,19 @@ AbstractExternalFunctionNode::substituteExoLead(subst_table_t &subst_table, vect } expr_t -AbstractExternalFunctionNode::substituteExoLag(subst_table_t &subst_table, vector &neweqs) const +AbstractExternalFunctionNode::substituteExoLag(subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::substituteExoLag, subst_table, neweqs); } expr_t -AbstractExternalFunctionNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const +AbstractExternalFunctionNode::substituteExpectation(subst_table_t& subst_table, + vector& neweqs, + bool partial_information_model) const { - return recurseTransform(&ExprNode::substituteExpectation, subst_table, neweqs, partial_information_model); + return recurseTransform(&ExprNode::substituteExpectation, subst_table, neweqs, + partial_information_model); } expr_t @@ -6933,20 +7100,21 @@ AbstractExternalFunctionNode::substituteModelLocalVariables() const } expr_t -AbstractExternalFunctionNode::substituteVarExpectation(const map &subst_table) const +AbstractExternalFunctionNode::substituteVarExpectation(const map& subst_table) const { return recurseTransform(&ExprNode::substituteVarExpectation, subst_table); } void -AbstractExternalFunctionNode::findDiffNodes(lag_equivalence_table_t &nodes) const +AbstractExternalFunctionNode::findDiffNodes(lag_equivalence_table_t& nodes) const { for (auto argument : arguments) argument->findDiffNodes(nodes); } void -AbstractExternalFunctionNode::findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const +AbstractExternalFunctionNode::findUnaryOpNodesForAuxVarCreation( + lag_equivalence_table_t& nodes) const { for (auto argument : arguments) argument->findUnaryOpNodesForAuxVarCreation(nodes); @@ -6956,21 +7124,23 @@ optional AbstractExternalFunctionNode::findTargetVariable(int lhs_symb_id) const { for (auto argument : arguments) - if (optional retval = argument->findTargetVariable(lhs_symb_id); - retval) + if (optional retval = argument->findTargetVariable(lhs_symb_id); retval) return retval; return nullopt; } expr_t -AbstractExternalFunctionNode::substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, - vector &neweqs) const +AbstractExternalFunctionNode::substituteDiff(const lag_equivalence_table_t& nodes, + subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::substituteDiff, nodes, subst_table, neweqs); } expr_t -AbstractExternalFunctionNode::substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const +AbstractExternalFunctionNode::substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, + subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::substituteUnaryOpNodes, nodes, subst_table, neweqs); } @@ -6982,43 +7152,47 @@ AbstractExternalFunctionNode::countDiffs() const } expr_t -AbstractExternalFunctionNode::substitutePacExpectation(const string &name, expr_t subexpr) +AbstractExternalFunctionNode::substitutePacExpectation(const string& name, expr_t subexpr) { return recurseTransform(&ExprNode::substitutePacExpectation, name, subexpr); } expr_t -AbstractExternalFunctionNode::substitutePacTargetNonstationary(const string &name, expr_t subexpr) +AbstractExternalFunctionNode::substitutePacTargetNonstationary(const string& name, expr_t subexpr) { return recurseTransform(&ExprNode::substitutePacTargetNonstationary, name, subexpr); } expr_t -AbstractExternalFunctionNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const +AbstractExternalFunctionNode::differentiateForwardVars(const vector& subset, + subst_table_t& subst_table, + vector& neweqs) const { return recurseTransform(&ExprNode::differentiateForwardVars, subset, subst_table, neweqs); } bool -AbstractExternalFunctionNode::alreadyWrittenAsTefTerm(int the_symb_id, const deriv_node_temp_terms_t &tef_terms) const +AbstractExternalFunctionNode::alreadyWrittenAsTefTerm( + int the_symb_id, const deriv_node_temp_terms_t& tef_terms) const { - return tef_terms.contains({ the_symb_id, arguments }); + return tef_terms.contains({the_symb_id, arguments}); } int -AbstractExternalFunctionNode::getIndxInTefTerms(int the_symb_id, const deriv_node_temp_terms_t &tef_terms) const noexcept(false) +AbstractExternalFunctionNode::getIndxInTefTerms(int the_symb_id, + const deriv_node_temp_terms_t& tef_terms) const + noexcept(false) { - if (auto it = tef_terms.find({ the_symb_id, arguments }); - it != tef_terms.end()) + if (auto it = tef_terms.find({the_symb_id, arguments}); it != tef_terms.end()) return it->second; throw UnknownFunctionNameAndArgs(); } void -AbstractExternalFunctionNode::computeTemporaryTerms(const pair &derivOrder, - map, unordered_set> &temp_terms_map, - [[maybe_unused]] unordered_map>> &reference_count, - [[maybe_unused]] bool is_matlab) const +AbstractExternalFunctionNode::computeTemporaryTerms( + const pair& derivOrder, map, unordered_set>& temp_terms_map, + [[maybe_unused]] unordered_map>>& reference_count, + [[maybe_unused]] bool is_matlab) const { /* All external function nodes are declared as temporary terms. @@ -7031,8 +7205,8 @@ AbstractExternalFunctionNode::computeTemporaryTerms(const pair &derivO corresponding to the same external function call is present in that previous level. */ - expr_t this2 = const_cast(this); - for (auto &tt : temp_terms_map) + expr_t this2 = const_cast(this); + for (auto& tt : temp_terms_map) if (find_if(tt.second.cbegin(), tt.second.cend(), sameTefTermPredicate()) != tt.second.cend()) { tt.second.insert(this2); @@ -7043,13 +7217,14 @@ AbstractExternalFunctionNode::computeTemporaryTerms(const pair &derivO } void -AbstractExternalFunctionNode::computeBlockTemporaryTerms(int blk, int eq, vector>> &blocks_temporary_terms, - [[maybe_unused]] unordered_map> &reference_count) const +AbstractExternalFunctionNode::computeBlockTemporaryTerms( + int blk, int eq, vector>>& blocks_temporary_terms, + [[maybe_unused]] unordered_map>& reference_count) const { // See comments in computeTemporaryTerms() for the logic - expr_t this2 = const_cast(this); - for (auto &btt : blocks_temporary_terms) - for (auto &tt : btt) + expr_t this2 = const_cast(this); + for (auto& btt : blocks_temporary_terms) + for (auto& tt : btt) if (find_if(tt.cbegin(), tt.cend(), sameTefTermPredicate()) != tt.cend()) { tt.insert(this2); @@ -7074,14 +7249,14 @@ AbstractExternalFunctionNode::isVariableNodeEqualTo([[maybe_unused]] SymbolType } bool -AbstractExternalFunctionNode::containsPacExpectation(const string &pac_model_name) const +AbstractExternalFunctionNode::containsPacExpectation(const string& pac_model_name) const { return any_of(arguments.begin(), arguments.end(), [&](expr_t e) { return e->containsPacExpectation(pac_model_name); }); } bool -AbstractExternalFunctionNode::containsPacTargetNonstationary(const string &pac_model_name) const +AbstractExternalFunctionNode::containsPacTargetNonstationary(const string& pac_model_name) const { return any_of(arguments.begin(), arguments.end(), [&](expr_t e) { return e->containsPacTargetNonstationary(pac_model_name); }); @@ -7100,7 +7275,7 @@ AbstractExternalFunctionNode::detrend(int symb_id, bool log_trend, expr_t trend) } expr_t -AbstractExternalFunctionNode::removeTrendLeadLag(const map &trend_symbols_map) const +AbstractExternalFunctionNode::removeTrendLeadLag(const map& trend_symbols_map) const { return recurseTransform(&ExprNode::removeTrendLeadLag, trend_symbols_map); } @@ -7108,8 +7283,7 @@ AbstractExternalFunctionNode::removeTrendLeadLag(const map &trend_s bool AbstractExternalFunctionNode::isInStaticForm() const { - return all_of(arguments.begin(), arguments.end(), - [](expr_t e) { return e->isInStaticForm(); }); + return all_of(arguments.begin(), arguments.end(), [](expr_t e) { return e->isInStaticForm(); }); } bool @@ -7119,7 +7293,8 @@ AbstractExternalFunctionNode::isParamTimesEndogExpr() const } void -AbstractExternalFunctionNode::computeSubExprContainingVariable(int symb_id, int lag, set &contain_var) const +AbstractExternalFunctionNode::computeSubExprContainingVariable(int symb_id, int lag, + set& contain_var) const { bool var_present = false; for (auto arg : arguments) @@ -7128,24 +7303,23 @@ AbstractExternalFunctionNode::computeSubExprContainingVariable(int symb_id, int var_present = var_present || contain_var.contains(arg); } if (var_present) - contain_var.insert(const_cast(this)); + contain_var.insert(const_cast(this)); } -BinaryOpNode * -AbstractExternalFunctionNode::normalizeEquationHelper([[maybe_unused]] const set &contain_var, - [[maybe_unused]] expr_t rhs) const +BinaryOpNode* +AbstractExternalFunctionNode::normalizeEquationHelper( + [[maybe_unused]] const set& contain_var, [[maybe_unused]] expr_t rhs) const { throw NormalizationFailed(); } void -AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOutputType 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 +AbstractExternalFunctionNode::writeExternalFunctionArguments( + ostream& output, ExprNodeOutputType 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 { - for (bool printed_something{false}; - auto arg : arguments) + for (bool printed_something {false}; auto arg : arguments) { if (exchange(printed_something, true)) output << ","; @@ -7155,11 +7329,10 @@ AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, Ex } void -AbstractExternalFunctionNode::writeJsonASTExternalFunctionArguments(ostream &output) const +AbstractExternalFunctionNode::writeJsonASTExternalFunctionArguments(ostream& output) const { output << "{"; - for (int i{0}; - auto arg : arguments) + for (int i {0}; auto arg : arguments) { if (i != 0) output << ","; @@ -7171,13 +7344,11 @@ AbstractExternalFunctionNode::writeJsonASTExternalFunctionArguments(ostream &out } void -AbstractExternalFunctionNode::writeJsonExternalFunctionArguments(ostream &output, - const temporary_terms_t &temporary_terms, - const deriv_node_temp_terms_t &tef_terms, - bool isdynamic) const +AbstractExternalFunctionNode::writeJsonExternalFunctionArguments( + ostream& output, const temporary_terms_t& temporary_terms, + const deriv_node_temp_terms_t& tef_terms, bool isdynamic) const { - for (bool printed_something{false}; - auto arg : arguments) + for (bool printed_something {false}; auto arg : arguments) { if (exchange(printed_something, true)) output << ","; @@ -7187,15 +7358,15 @@ AbstractExternalFunctionNode::writeJsonExternalFunctionArguments(ostream &output } void -AbstractExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType 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 +AbstractExternalFunctionNode::writePrhs(ostream& output, ExprNodeOutputType 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 { - for (int i{0}; - auto argument : arguments) + for (int i {0}; auto argument : arguments) { - output << " prhs[" << i++ << "] = mxCreateDoubleScalar("; // All external_function arguments are scalars + output << " prhs[" << i++ + << "] = mxCreateDoubleScalar("; // All external_function arguments are scalars argument->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); output << ");" << endl; } @@ -7208,16 +7379,14 @@ AbstractExternalFunctionNode::containsExternalFunction() const } expr_t -AbstractExternalFunctionNode::replaceVarsInEquation(map &table) const +AbstractExternalFunctionNode::replaceVarsInEquation(map& table) const { return recurseTransform(&ExprNode::replaceVarsInEquation, table); } -ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg, - int idx_arg, - int symb_id_arg, - const vector &arguments_arg) : - AbstractExternalFunctionNode{datatree_arg, idx_arg, symb_id_arg, arguments_arg} +ExternalFunctionNode::ExternalFunctionNode(DataTree& datatree_arg, int idx_arg, int symb_id_arg, + const vector& arguments_arg) : + AbstractExternalFunctionNode {datatree_arg, idx_arg, symb_id_arg, arguments_arg} { } @@ -7228,7 +7397,7 @@ AbstractExternalFunctionNode::substituteLogTransform(int orig_symb_id, int aux_s } expr_t -AbstractExternalFunctionNode::toStatic(DataTree &static_datatree) const +AbstractExternalFunctionNode::toStatic(DataTree& static_datatree) const { vector static_arguments; for (auto argument : arguments) @@ -7237,7 +7406,7 @@ AbstractExternalFunctionNode::toStatic(DataTree &static_datatree) const } expr_t -AbstractExternalFunctionNode::clone(DataTree &alt_datatree) const +AbstractExternalFunctionNode::clone(DataTree& alt_datatree) const { vector dynamic_arguments; for (auto argument : arguments) @@ -7246,45 +7415,47 @@ AbstractExternalFunctionNode::clone(DataTree &alt_datatree) const } expr_t -ExternalFunctionNode::composeDerivatives(const vector &dargs) +ExternalFunctionNode::composeDerivatives(const vector& dargs) { vector dNodes; for (int i = 0; i < static_cast(dargs.size()); i++) - dNodes.push_back(datatree.AddTimes(dargs.at(i), - datatree.AddFirstDerivExternalFunction(symb_id, arguments, i+1))); + dNodes.push_back(datatree.AddTimes( + dargs.at(i), datatree.AddFirstDerivExternalFunction(symb_id, arguments, i + 1))); return accumulate(dNodes.begin(), dNodes.end(), static_cast(datatree.Zero), [&](expr_t e1, expr_t e2) { return datatree.AddPlus(e1, e2); }); } void -ExternalFunctionNode::writeBytecodeOutput(BytecodeWriter &code_file, +ExternalFunctionNode::writeBytecodeOutput(BytecodeWriter& 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 + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + const deriv_node_temp_terms_t& tef_terms) const { if (output_type == ExprNodeBytecodeOutputType::dynamicSteadyStateOperator) { - cerr << "ERROR: The expression inside a steady_state operator cannot contain external functions" << endl; + cerr << "ERROR: The expression inside a steady_state operator cannot contain external " + "functions" + << endl; exit(EXIT_FAILURE); } - if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, + temporary_terms_idxs)) return; if (!isAssignmentLHSBytecodeOutput(output_type)) - code_file << FLDTEF_{getIndxInTefTerms(symb_id, tef_terms)}; + code_file << FLDTEF_ {getIndxInTefTerms(symb_id, tef_terms)}; else - code_file << FSTPTEF_{getIndxInTefTerms(symb_id, tef_terms)}; + code_file << FSTPTEF_ {getIndxInTefTerms(symb_id, tef_terms)}; } void -ExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &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 +ExternalFunctionNode::writeBytecodeExternalFunctionOutput( + BytecodeWriter& 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 { int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); assert(first_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); @@ -7295,7 +7466,7 @@ ExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_f if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) { - tef_terms[{ symb_id, arguments }] = static_cast(tef_terms.size()); + tef_terms[{symb_id, arguments}] = static_cast(tef_terms.size()); int indx = getIndxInTefTerms(symb_id, tef_terms); int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); assert(second_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); @@ -7305,8 +7476,7 @@ ExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_f int nb_output_arguments; ExternalFunctionCallType call_type; - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) + if (symb_id == first_deriv_symb_id && symb_id == second_deriv_symb_id) { nb_output_arguments = 3; call_type = ExternalFunctionCallType::levelWithFirstAndSecondDerivative; @@ -7322,13 +7492,14 @@ ExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_f call_type = ExternalFunctionCallType::levelWithoutDerivative; } - code_file << FCALL_{nb_output_arguments, static_cast(arguments.size()), datatree.symbol_table.getName(symb_id), indx, call_type} - << FSTPTEF_{indx}; + code_file << FCALL_ {nb_output_arguments, static_cast(arguments.size()), + datatree.symbol_table.getName(symb_id), indx, call_type} + << FSTPTEF_ {indx}; } } void -ExternalFunctionNode::writeJsonAST(ostream &output) const +ExternalFunctionNode::writeJsonAST(ostream& output) const { output << R"({"node_type" : "ExternalFunctionNode", )" << R"("name" : ")" << datatree.symbol_table.getName(symb_id) << R"(", "args" : [)"; @@ -7337,12 +7508,11 @@ ExternalFunctionNode::writeJsonAST(ostream &output) const } void -ExternalFunctionNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - const deriv_node_temp_terms_t &tef_terms, +ExternalFunctionNode::writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms, + const deriv_node_temp_terms_t& tef_terms, bool isdynamic) const { - if (temporary_terms.contains(const_cast(this))) + if (temporary_terms.contains(const_cast(this))) { output << "T" << idx; return; @@ -7353,7 +7523,7 @@ ExternalFunctionNode::writeJsonOutput(ostream &output, int tef_idx = getIndxInTefTerms(symb_id, tef_terms); output << "TEF_" << tef_idx; } - catch (UnknownFunctionNameAndArgs &) + catch (UnknownFunctionNameAndArgs&) { // When writing the JSON output at parsing pass, we don’t use TEF terms output << datatree.symbol_table.getName(symb_id) << "("; @@ -7363,28 +7533,31 @@ ExternalFunctionNode::writeJsonOutput(ostream &output, } void -ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType 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 +ExternalFunctionNode::writeOutput(ostream& output, ExprNodeOutputType 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 { - if (output_type == ExprNodeOutputType::matlabOutsideModel || output_type == ExprNodeOutputType::steadyStateFile + if (output_type == ExprNodeOutputType::matlabOutsideModel + || output_type == ExprNodeOutputType::steadyStateFile || output_type == ExprNodeOutputType::juliaSteadyStateFile || output_type == ExprNodeOutputType::epilogueFile - || output_type == ExprNodeOutputType::occbinDifferenceFile - || isLatexOutput(output_type)) + || output_type == ExprNodeOutputType::occbinDifferenceFile || isLatexOutput(output_type)) { string name = isLatexOutput(output_type) ? datatree.symbol_table.getTeXName(symb_id) - : datatree.symbol_table.getName(symb_id); + : datatree.symbol_table.getName(symb_id); output << name << "("; - writeExternalFunctionArguments(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + writeExternalFunctionArguments(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); output << ")"; return; } if (isSteadyStateOperatorOutput(output_type)) { - cerr << "ERROR: The expression inside a steady_state operator cannot contain external functions" << endl; + cerr << "ERROR: The expression inside a steady_state operator cannot contain external " + "functions" + << endl; exit(EXIT_FAILURE); } @@ -7397,17 +7570,17 @@ ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_typ } void -ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, - deriv_node_temp_terms_t &tef_terms) const +ExternalFunctionNode::writeExternalFunctionOutput( + ostream& output, ExprNodeOutputType output_type, const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, deriv_node_temp_terms_t& tef_terms) const { for (auto argument : arguments) - argument->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + argument->writeExternalFunctionOutput(output, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) { - tef_terms[{ symb_id, arguments }] = static_cast(tef_terms.size()); + tef_terms[{symb_id, arguments}] = static_cast(tef_terms.size()); int indx = getIndxInTefTerms(symb_id, tef_terms); int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); assert(first_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); @@ -7426,16 +7599,16 @@ ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutpu if (symb_id == first_deriv_symb_id && symb_id == second_deriv_symb_id) output << "int TEFDD_" << indx << "_nrows;" << endl; - int nlhs = - symb_id == first_deriv_symb_id && symb_id == second_deriv_symb_id ? 3 - : symb_id == first_deriv_symb_id ? 2 : 1; + int nlhs = symb_id == first_deriv_symb_id && symb_id == second_deriv_symb_id ? 3 + : symb_id == first_deriv_symb_id ? 2 + : 1; output << "{" << endl << " mxArray *plhs[" << nlhs << "], *prhs[" << arguments.size() << "];" << endl; writePrhs(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); - output << " mexCallMATLAB(" << nlhs << ", plhs, " << arguments.size() << ", prhs, " << R"(")" - << datatree.symbol_table.getName(symb_id) << R"(");)" << endl; + output << " mexCallMATLAB(" << nlhs << ", plhs, " << arguments.size() << ", prhs, " + << R"(")" << datatree.symbol_table.getName(symb_id) << R"(");)" << endl; output << " TEF_" << indx << " = mxGetPr(plhs[0]);" << endl; if (symb_id == first_deriv_symb_id) @@ -7449,25 +7622,25 @@ ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutpu } else { - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) - output << "[TEF_" << indx << ", TEFD_"<< indx << ", TEFDD_"<< indx << "] = "; + if (symb_id == first_deriv_symb_id && symb_id == second_deriv_symb_id) + output << "[TEF_" << indx << ", TEFD_" << indx << ", TEFDD_" << indx << "] = "; else if (symb_id == first_deriv_symb_id) - output << "[TEF_" << indx << ", TEFD_"<< indx << "] = "; + output << "[TEF_" << indx << ", TEFD_" << indx << "] = "; else output << "TEF_" << indx << " = "; output << datatree.symbol_table.getName(symb_id) << "("; - writeExternalFunctionArguments(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + writeExternalFunctionArguments(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); output << ");" << endl; } } } void -ExternalFunctionNode::writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, +ExternalFunctionNode::writeJsonExternalFunctionOutput(vector& efout, + const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, bool isdynamic) const { int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); @@ -7478,7 +7651,7 @@ ExternalFunctionNode::writeJsonExternalFunctionOutput(vector &efout, if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) { - tef_terms[{ symb_id, arguments }] = static_cast(tef_terms.size()); + tef_terms[{symb_id, arguments}] = static_cast(tef_terms.size()); int indx = getIndxInTefTerms(symb_id, tef_terms); int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); assert(second_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); @@ -7501,7 +7674,7 @@ ExternalFunctionNode::writeJsonExternalFunctionOutput(vector &efout, } void -ExternalFunctionNode::computeXrefs(EquationInfo &ei) const +ExternalFunctionNode::computeXrefs(EquationInfo& ei) const { vector dynamic_arguments; for (auto argument : arguments) @@ -7509,43 +7682,43 @@ ExternalFunctionNode::computeXrefs(EquationInfo &ei) const } expr_t -ExternalFunctionNode::buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const +ExternalFunctionNode::buildSimilarExternalFunctionNode(vector& alt_args, + DataTree& alt_datatree) const { return alt_datatree.AddExternalFunction(symb_id, alt_args); } -function +function ExternalFunctionNode::sameTefTermPredicate() const { return [this](expr_t e) { - auto e2 = dynamic_cast(e); - return (e2 != nullptr && e2->symb_id == symb_id && e2->arguments == arguments); - }; + auto e2 = dynamic_cast(e); + return (e2 != nullptr && e2->symb_id == symb_id && e2->arguments == arguments); + }; } -FirstDerivExternalFunctionNode::FirstDerivExternalFunctionNode(DataTree &datatree_arg, - int idx_arg, +FirstDerivExternalFunctionNode::FirstDerivExternalFunctionNode(DataTree& datatree_arg, int idx_arg, int top_level_symb_id_arg, - const vector &arguments_arg, + const vector& arguments_arg, int inputIndex_arg) : - AbstractExternalFunctionNode{datatree_arg, idx_arg, top_level_symb_id_arg, arguments_arg}, - inputIndex{inputIndex_arg} + AbstractExternalFunctionNode {datatree_arg, idx_arg, top_level_symb_id_arg, arguments_arg}, + inputIndex {inputIndex_arg} { } expr_t -FirstDerivExternalFunctionNode::composeDerivatives(const vector &dargs) +FirstDerivExternalFunctionNode::composeDerivatives(const vector& dargs) { vector dNodes; for (int i = 0; i < static_cast(dargs.size()); i++) - dNodes.push_back(datatree.AddTimes(dargs.at(i), - datatree.AddSecondDerivExternalFunction(symb_id, arguments, inputIndex, i+1))); + dNodes.push_back(datatree.AddTimes(dargs.at(i), datatree.AddSecondDerivExternalFunction( + symb_id, arguments, inputIndex, i + 1))); return accumulate(dNodes.begin(), dNodes.end(), static_cast(datatree.Zero), [&](expr_t e1, expr_t e2) { return datatree.AddPlus(e1, e2); }); } void -FirstDerivExternalFunctionNode::writeJsonAST(ostream &output) const +FirstDerivExternalFunctionNode::writeJsonAST(ostream& output) const { output << R"({"node_type" : "FirstDerivExternalFunctionNode", )" << R"("name" : ")" << datatree.symbol_table.getName(symb_id) << R"(", "args" : [)"; @@ -7554,13 +7727,13 @@ FirstDerivExternalFunctionNode::writeJsonAST(ostream &output) const } void -FirstDerivExternalFunctionNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - const deriv_node_temp_terms_t &tef_terms, +FirstDerivExternalFunctionNode::writeJsonOutput(ostream& output, + const temporary_terms_t& temporary_terms, + const deriv_node_temp_terms_t& tef_terms, [[maybe_unused]] bool isdynamic) const { // If current node is a temporary term - if (temporary_terms.contains(const_cast(this))) + if (temporary_terms.contains(const_cast(this))) { output << "T" << idx; return; @@ -7572,20 +7745,19 @@ FirstDerivExternalFunctionNode::writeJsonOutput(ostream &output, const int tmpIndx = inputIndex - 1; if (first_deriv_symb_id == symb_id) - output << "TEFD_" << getIndxInTefTerms(symb_id, tef_terms) - << "[" << tmpIndx << "]"; + output << "TEFD_" << getIndxInTefTerms(symb_id, tef_terms) << "[" << tmpIndx << "]"; else if (first_deriv_symb_id == ExternalFunctionsTable::IDNotSet) output << "TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex; else - output << "TEFD_def_" << getIndxInTefTerms(first_deriv_symb_id, tef_terms) - << "[" << tmpIndx << "]"; + output << "TEFD_def_" << getIndxInTefTerms(first_deriv_symb_id, tef_terms) << "[" << tmpIndx + << "]"; } void -FirstDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType 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 +FirstDerivExternalFunctionNode::writeOutput(ostream& output, ExprNodeOutputType 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 { assert(output_type != ExprNodeOutputType::matlabOutsideModel && output_type != ExprNodeOutputType::occbinDifferenceFile); @@ -7594,14 +7766,17 @@ FirstDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType { output << R"(\frac{\partial )" << datatree.symbol_table.getTeXName(symb_id) << R"(}{\partial )" << inputIndex << "}("; - writeExternalFunctionArguments(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + writeExternalFunctionArguments(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); output << ")"; return; } if (isSteadyStateOperatorOutput(output_type)) { - cerr << "ERROR: The expression inside a steady_state operator cannot contain external functions" << endl; + cerr << "ERROR: The expression inside a steady_state operator cannot contain external " + "functions" + << endl; exit(EXIT_FAILURE); } @@ -7614,8 +7789,8 @@ FirstDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType const int tmpIndx = inputIndex - 1 + ARRAY_SUBSCRIPT_OFFSET(output_type); if (first_deriv_symb_id == symb_id) - output << "TEFD_" << getIndxInTefTerms(symb_id, tef_terms) - << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndx << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << "TEFD_" << getIndxInTefTerms(symb_id, tef_terms) << LEFT_ARRAY_SUBSCRIPT(output_type) + << tmpIndx << RIGHT_ARRAY_SUBSCRIPT(output_type); else if (first_deriv_symb_id == ExternalFunctionsTable::IDNotSet) { if (isCOutput(output_type)) @@ -7628,35 +7803,36 @@ FirstDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType } void -FirstDerivExternalFunctionNode::writeBytecodeOutput(BytecodeWriter &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 +FirstDerivExternalFunctionNode::writeBytecodeOutput( + BytecodeWriter& 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 { if (output_type == ExprNodeBytecodeOutputType::dynamicSteadyStateOperator) { - cerr << "ERROR: The expression inside a steady_state operator cannot contain external functions" << endl; + cerr << "ERROR: The expression inside a steady_state operator cannot contain external " + "functions" + << endl; exit(EXIT_FAILURE); } - if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, + temporary_terms_idxs)) return; int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); assert(first_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); if (!isAssignmentLHSBytecodeOutput(output_type)) - code_file << FLDTEFD_{getIndxInTefTerms(symb_id, tef_terms), inputIndex}; + code_file << FLDTEFD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex}; else - code_file << FSTPTEFD_{getIndxInTefTerms(symb_id, tef_terms), inputIndex}; + code_file << FSTPTEFD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex}; } void -FirstDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, - deriv_node_temp_terms_t &tef_terms) const +FirstDerivExternalFunctionNode::writeExternalFunctionOutput( + ostream& output, ExprNodeOutputType output_type, const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, deriv_node_temp_terms_t& tef_terms) const { assert(output_type != ExprNodeOutputType::matlabOutsideModel); int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); @@ -7667,8 +7843,8 @@ FirstDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Exp if (first_deriv_symb_id == symb_id) { expr_t parent = datatree.AddExternalFunction(symb_id, arguments); - parent->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, - tef_terms); + parent->writeExternalFunctionOutput(output, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); return; } @@ -7678,31 +7854,34 @@ FirstDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Exp if (isCOutput(output_type)) if (first_deriv_symb_id == ExternalFunctionsTable::IDNotSet) { - output << "double *TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex << ";" << endl + output << "double *TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex + << ";" << endl << "{" << endl << " const mwSize dims[2] = {1, " << arguments.size() << "};" << endl << " mxArray *plhs[1], *prhs[3];" << endl - << R"( prhs[0] = mxCreateString(")" << datatree.symbol_table.getName(symb_id) << R"(");)" << endl - << " prhs[1] = mxCreateDoubleScalar(" << inputIndex << ");"<< endl - << " prhs[2] = mxCreateCellArray(2, dims);"<< endl; + << R"( prhs[0] = mxCreateString(")" << datatree.symbol_table.getName(symb_id) + << R"(");)" << endl + << " prhs[1] = mxCreateDoubleScalar(" << inputIndex << ");" << endl + << " prhs[2] = mxCreateCellArray(2, dims);" << endl; - for (int i{0}; - auto argument : arguments) + for (int i {0}; auto argument : arguments) { output << " mxSetCell(prhs[2], " << i++ << ", " << "mxCreateDoubleScalar("; // All external_function arguments are scalars - argument->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + argument->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); output << "));" << endl; } - output << " mexCallMATLAB(1, plhs, 3, prhs," << R"("jacob_element");)" << endl - << " TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex + output << " mexCallMATLAB(1, plhs, 3, prhs," + << R"("jacob_element");)" << endl + << " TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex << " = mxGetPr(plhs[0]);" << endl << "}" << endl; } else { - tef_terms[{ first_deriv_symb_id, arguments }] = static_cast(tef_terms.size()); + tef_terms[{first_deriv_symb_id, arguments}] = static_cast(tef_terms.size()); int indx = getIndxInTefTerms(first_deriv_symb_id, tef_terms); output << "double *TEFD_def_" << indx << ";" << endl << "{" << endl @@ -7710,24 +7889,26 @@ FirstDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Exp writePrhs(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); - output << " mexCallMATLAB(1, plhs, " << arguments.size() << ", prhs," << R"(")" - << datatree.symbol_table.getName(first_deriv_symb_id) << R"(");)" << endl + output << " mexCallMATLAB(1, plhs, " << arguments.size() << ", prhs," + << R"(")" << datatree.symbol_table.getName(first_deriv_symb_id) << R"(");)" << endl << " TEFD_def_" << indx << " = mxGetPr(plhs[0]);" << endl << "}" << endl; } else { if (first_deriv_symb_id == ExternalFunctionsTable::IDNotSet) - output << "TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex << " = jacob_element('" - << datatree.symbol_table.getName(symb_id) << "'," << inputIndex << ",{"; + output << "TEFD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex + << " = jacob_element('" << datatree.symbol_table.getName(symb_id) << "'," + << inputIndex << ",{"; else { - tef_terms[{ first_deriv_symb_id, arguments }] = static_cast(tef_terms.size()); - output << "TEFD_def_" << getIndxInTefTerms(first_deriv_symb_id, tef_terms) - << " = " << datatree.symbol_table.getName(first_deriv_symb_id) << "("; + tef_terms[{first_deriv_symb_id, arguments}] = static_cast(tef_terms.size()); + output << "TEFD_def_" << getIndxInTefTerms(first_deriv_symb_id, tef_terms) << " = " + << datatree.symbol_table.getName(first_deriv_symb_id) << "("; } - writeExternalFunctionArguments(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + writeExternalFunctionArguments(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); if (first_deriv_symb_id == ExternalFunctionsTable::IDNotSet) output << "}"; @@ -7736,10 +7917,9 @@ FirstDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Exp } void -FirstDerivExternalFunctionNode::writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - bool isdynamic) const +FirstDerivExternalFunctionNode::writeJsonExternalFunctionOutput( + vector& efout, const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, bool isdynamic) const { int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); assert(first_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); @@ -7759,15 +7939,17 @@ FirstDerivExternalFunctionNode::writeJsonExternalFunctionOutput(vector & stringstream ef; if (first_deriv_symb_id == ExternalFunctionsTable::IDNotSet) ef << R"({"first_deriv_external_function": {)" - << R"("external_function_term": "TEFD_fdd_)" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex << R"(")" + << R"("external_function_term": "TEFD_fdd_)" << getIndxInTefTerms(symb_id, tef_terms) << "_" + << inputIndex << R"(")" << R"(, "analytic_derivative": false)" - << R"(, "wrt": )" << inputIndex - << R"(, "value": ")" << datatree.symbol_table.getName(symb_id) << "("; + << R"(, "wrt": )" << inputIndex << R"(, "value": ")" + << datatree.symbol_table.getName(symb_id) << "("; else { - tef_terms[{ first_deriv_symb_id, arguments }] = static_cast(tef_terms.size()); + tef_terms[{first_deriv_symb_id, arguments}] = static_cast(tef_terms.size()); ef << R"({"first_deriv_external_function": {)" - << R"("external_function_term": "TEFD_def_)" << getIndxInTefTerms(first_deriv_symb_id, tef_terms) << R"(")" + << R"("external_function_term": "TEFD_def_)" + << getIndxInTefTerms(first_deriv_symb_id, tef_terms) << R"(")" << R"(, "analytic_derivative": true)" << R"(, "value": ")" << datatree.symbol_table.getName(first_deriv_symb_id) << "("; } @@ -7778,11 +7960,10 @@ FirstDerivExternalFunctionNode::writeJsonExternalFunctionOutput(vector & } void -FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &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 +FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput( + BytecodeWriter& 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 { int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); assert(first_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); @@ -7806,79 +7987,79 @@ FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWrit if (int indx = getIndxInTefTerms(symb_id, tef_terms); first_deriv_symb_id == ExternalFunctionsTable::IDNotSet) { - int nb_input_arguments{0}; - int nb_output_arguments{1}; - FCALL_ fcall{nb_output_arguments, nb_input_arguments, "jacob_element", indx, - ExternalFunctionCallType::numericalFirstDerivative}; + int nb_input_arguments {0}; + int nb_output_arguments {1}; + FCALL_ fcall {nb_output_arguments, nb_input_arguments, "jacob_element", indx, + 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(arguments.size())); - code_file << fcall << FSTPTEFD_{indx, inputIndex}; + code_file << fcall << FSTPTEFD_ {indx, inputIndex}; } else { - tef_terms[{ first_deriv_symb_id, arguments }] = static_cast(tef_terms.size()); + tef_terms[{first_deriv_symb_id, arguments}] = static_cast(tef_terms.size()); int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); assert(second_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); - int nb_output_arguments{1}; + int nb_output_arguments {1}; - code_file << FCALL_{nb_output_arguments, static_cast(arguments.size()), datatree.symbol_table.getName(first_deriv_symb_id), indx, ExternalFunctionCallType::separatelyProvidedFirstDerivative} - << FSTPTEFD_{indx, inputIndex}; + code_file << FCALL_ {nb_output_arguments, static_cast(arguments.size()), + datatree.symbol_table.getName(first_deriv_symb_id), indx, + ExternalFunctionCallType::separatelyProvidedFirstDerivative} + << FSTPTEFD_ {indx, inputIndex}; } } expr_t -FirstDerivExternalFunctionNode::buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const +FirstDerivExternalFunctionNode::buildSimilarExternalFunctionNode(vector& alt_args, + DataTree& alt_datatree) const { return alt_datatree.AddFirstDerivExternalFunction(symb_id, alt_args, inputIndex); } void -FirstDerivExternalFunctionNode::computeXrefs(EquationInfo &ei) const +FirstDerivExternalFunctionNode::computeXrefs(EquationInfo& ei) const { vector dynamic_arguments; for (auto argument : arguments) argument->computeXrefs(ei); } -function +function FirstDerivExternalFunctionNode::sameTefTermPredicate() const { int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); if (first_deriv_symb_id == symb_id) return [this](expr_t e) { - auto e2 = dynamic_cast(e); + auto e2 = dynamic_cast(e); return (e2 && e2->symb_id == symb_id && e2->arguments == arguments); }; else return [this](expr_t e) { - auto e2 = dynamic_cast(e); + auto e2 = dynamic_cast(e); return (e2 && e2->symb_id == symb_id && e2->arguments == arguments); }; } -SecondDerivExternalFunctionNode::SecondDerivExternalFunctionNode(DataTree &datatree_arg, - int idx_arg, - int top_level_symb_id_arg, - const vector &arguments_arg, - int inputIndex1_arg, - int inputIndex2_arg) : - AbstractExternalFunctionNode{datatree_arg, idx_arg, top_level_symb_id_arg, arguments_arg}, - inputIndex1{inputIndex1_arg}, - inputIndex2{inputIndex2_arg} +SecondDerivExternalFunctionNode::SecondDerivExternalFunctionNode( + DataTree& datatree_arg, int idx_arg, int top_level_symb_id_arg, + const vector& arguments_arg, int inputIndex1_arg, int inputIndex2_arg) : + AbstractExternalFunctionNode {datatree_arg, idx_arg, top_level_symb_id_arg, arguments_arg}, + inputIndex1 {inputIndex1_arg}, + inputIndex2 {inputIndex2_arg} { } expr_t -SecondDerivExternalFunctionNode::composeDerivatives([[maybe_unused]] const vector &dargs) +SecondDerivExternalFunctionNode::composeDerivatives([[maybe_unused]] const vector& dargs) { cerr << "ERROR: third order derivatives of external functions are not implemented" << endl; exit(EXIT_FAILURE); } void -SecondDerivExternalFunctionNode::writeJsonAST(ostream &output) const +SecondDerivExternalFunctionNode::writeJsonAST(ostream& output) const { output << R"({"node_type" : "SecondDerivExternalFunctionNode", )" << R"("name" : ")" << datatree.symbol_table.getName(symb_id) << R"(", "args" : [)"; @@ -7887,13 +8068,13 @@ SecondDerivExternalFunctionNode::writeJsonAST(ostream &output) const } void -SecondDerivExternalFunctionNode::writeJsonOutput(ostream &output, - const temporary_terms_t &temporary_terms, - const deriv_node_temp_terms_t &tef_terms, +SecondDerivExternalFunctionNode::writeJsonOutput(ostream& output, + const temporary_terms_t& temporary_terms, + const deriv_node_temp_terms_t& tef_terms, [[maybe_unused]] bool isdynamic) const { // If current node is a temporary term - if (temporary_terms.contains(const_cast(this))) + if (temporary_terms.contains(const_cast(this))) { output << "T" << idx; return; @@ -7906,20 +8087,21 @@ SecondDerivExternalFunctionNode::writeJsonOutput(ostream &output, const int tmpIndex2 = inputIndex2 - 1; if (second_deriv_symb_id == symb_id) - output << "TEFDD_" << getIndxInTefTerms(symb_id, tef_terms) - << "[" << tmpIndex1 << "," << tmpIndex2 << "]"; + output << "TEFDD_" << getIndxInTefTerms(symb_id, tef_terms) << "[" << tmpIndex1 << "," + << tmpIndex2 << "]"; else if (second_deriv_symb_id == ExternalFunctionsTable::IDNotSet) - output << "TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2; + output << "TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" + << inputIndex2; else - output << "TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) - << "[" << tmpIndex1 << "," << tmpIndex2 << "]"; + output << "TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) << "[" << tmpIndex1 + << "," << tmpIndex2 << "]"; } void -SecondDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType 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 +SecondDerivExternalFunctionNode::writeOutput(ostream& output, ExprNodeOutputType 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 { assert(output_type != ExprNodeOutputType::matlabOutsideModel && output_type != ExprNodeOutputType::occbinDifferenceFile); @@ -7928,14 +8110,17 @@ SecondDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType { output << R"(\frac{\partial^2 )" << datatree.symbol_table.getTeXName(symb_id) << R"(}{\partial )" << inputIndex1 << R"(\partial )" << inputIndex2 << "}("; - writeExternalFunctionArguments(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + writeExternalFunctionArguments(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); output << ")"; return; } if (isSteadyStateOperatorOutput(output_type)) { - cerr << "ERROR: The expression inside a steady_state operator cannot contain external functions" << endl; + cerr << "ERROR: The expression inside a steady_state operator cannot contain external " + "functions" + << endl; exit(EXIT_FAILURE); } @@ -7951,33 +8136,33 @@ SecondDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType int indx = getIndxInTefTerms(symb_id, tef_terms); if (second_deriv_symb_id == symb_id) if (isCOutput(output_type)) - output << "TEFDD_" << indx - << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndex1 << " * TEFDD_" << indx << "_nrows + " - << tmpIndex2 << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << "TEFDD_" << indx << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndex1 << " * TEFDD_" + << indx << "_nrows + " << tmpIndex2 << RIGHT_ARRAY_SUBSCRIPT(output_type); else output << "TEFDD_" << getIndxInTefTerms(symb_id, tef_terms) - << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndex1 << "," << tmpIndex2 << RIGHT_ARRAY_SUBSCRIPT(output_type); + << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndex1 << "," << tmpIndex2 + << RIGHT_ARRAY_SUBSCRIPT(output_type); else if (second_deriv_symb_id == ExternalFunctionsTable::IDNotSet) { if (isCOutput(output_type)) output << "*"; - output << "TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2; + output << "TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" + << inputIndex2; } + else if (isCOutput(output_type)) + output << "TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) + << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndex1 << " * PROBLEM_" << indx << "_nrows" + << tmpIndex2 << RIGHT_ARRAY_SUBSCRIPT(output_type); else - if (isCOutput(output_type)) - output << "TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) - << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndex1 << " * PROBLEM_" << indx << "_nrows" - << tmpIndex2 << RIGHT_ARRAY_SUBSCRIPT(output_type); - else - output << "TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) - << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndex1 << "," << tmpIndex2 << RIGHT_ARRAY_SUBSCRIPT(output_type); + output << "TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) + << LEFT_ARRAY_SUBSCRIPT(output_type) << tmpIndex1 << "," << tmpIndex2 + << RIGHT_ARRAY_SUBSCRIPT(output_type); } void -SecondDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, - deriv_node_temp_terms_t &tef_terms) const +SecondDerivExternalFunctionNode::writeExternalFunctionOutput( + ostream& output, ExprNodeOutputType output_type, const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, deriv_node_temp_terms_t& tef_terms) const { assert(output_type != ExprNodeOutputType::matlabOutsideModel); int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); @@ -7988,8 +8173,8 @@ SecondDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Ex if (second_deriv_symb_id == symb_id) { expr_t parent = datatree.AddExternalFunction(symb_id, arguments); - parent->writeExternalFunctionOutput(output, output_type, temporary_terms, temporary_terms_idxs, - tef_terms); + parent->writeExternalFunctionOutput(output, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); return; } @@ -8000,32 +8185,35 @@ SecondDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Ex if (second_deriv_symb_id == ExternalFunctionsTable::IDNotSet) { stringstream ending; - output << "double *TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2 << ";" << endl + output << "double *TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" + << inputIndex1 << "_" << inputIndex2 << ";" << endl << "{" << endl << " const mwSize dims[2]= {1, " << arguments.size() << "};" << endl << " mxArray *plhs[1], *prhs[4];" << endl - << R"( prhs[0] = mxCreateString(")" << datatree.symbol_table.getName(symb_id) << R"(");)" << endl - << " prhs[1] = mxCreateDoubleScalar(" << inputIndex1 << ");"<< endl - << " prhs[2] = mxCreateDoubleScalar(" << inputIndex2 << ");"<< endl - << " prhs[3] = mxCreateCellArray(2, dims);"<< endl; + << R"( prhs[0] = mxCreateString(")" << datatree.symbol_table.getName(symb_id) + << R"(");)" << endl + << " prhs[1] = mxCreateDoubleScalar(" << inputIndex1 << ");" << endl + << " prhs[2] = mxCreateDoubleScalar(" << inputIndex2 << ");" << endl + << " prhs[3] = mxCreateCellArray(2, dims);" << endl; - for (int i{0}; - auto argument : arguments) + for (int i {0}; auto argument : arguments) { output << " mxSetCell(prhs[3], " << i++ << ", " << " mxCreateDoubleScalar("; // All external_function arguments are scalars - argument->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + argument->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); output << "));" << endl; } - output << " mexCallMATLAB(1, plhs, 4, prhs, " << R"("hess_element");)" << endl - << " TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2 - << " = mxGetPr(plhs[0]);" << endl + output << " mexCallMATLAB(1, plhs, 4, prhs, " + << R"("hess_element");)" << endl + << " TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 + << "_" << inputIndex2 << " = mxGetPr(plhs[0]);" << endl << "}" << endl; } else { - tef_terms[{ second_deriv_symb_id, arguments }] = static_cast(tef_terms.size()); + tef_terms[{second_deriv_symb_id, arguments}] = static_cast(tef_terms.size()); int indx = getIndxInTefTerms(second_deriv_symb_id, tef_terms); output << "double *TEFDD_def_" << indx << ";" << endl << "{" << endl @@ -8033,25 +8221,26 @@ SecondDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Ex writePrhs(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); - output << " mexCallMATLAB(1, plhs, " << arguments.size() << ", prhs, " << R"(")" - << datatree.symbol_table.getName(second_deriv_symb_id) << R"(");)" << endl + output << " mexCallMATLAB(1, plhs, " << arguments.size() << ", prhs, " + << R"(")" << datatree.symbol_table.getName(second_deriv_symb_id) << R"(");)" << endl << " TEFDD_def_" << indx << " = mxGetPr(plhs[0]);" << endl << "}" << endl; } else { if (second_deriv_symb_id == ExternalFunctionsTable::IDNotSet) - output << "TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2 - << " = hess_element('" << datatree.symbol_table.getName(symb_id) << "'," - << inputIndex1 << "," << inputIndex2 << ",{"; + output << "TEFDD_fdd_" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" + << inputIndex2 << " = hess_element('" << datatree.symbol_table.getName(symb_id) + << "'," << inputIndex1 << "," << inputIndex2 << ",{"; else { - tef_terms[{ second_deriv_symb_id, arguments }] = static_cast(tef_terms.size()); - output << "TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) - << " = " << datatree.symbol_table.getName(second_deriv_symb_id) << "("; + tef_terms[{second_deriv_symb_id, arguments}] = static_cast(tef_terms.size()); + output << "TEFDD_def_" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) << " = " + << datatree.symbol_table.getName(second_deriv_symb_id) << "("; } - writeExternalFunctionArguments(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + writeExternalFunctionArguments(output, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); if (second_deriv_symb_id == ExternalFunctionsTable::IDNotSet) output << "}"; @@ -8060,10 +8249,9 @@ SecondDerivExternalFunctionNode::writeExternalFunctionOutput(ostream &output, Ex } void -SecondDerivExternalFunctionNode::writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - bool isdynamic) const +SecondDerivExternalFunctionNode::writeJsonExternalFunctionOutput( + vector& efout, const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, bool isdynamic) const { int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); assert(second_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); @@ -8083,16 +8271,17 @@ SecondDerivExternalFunctionNode::writeJsonExternalFunctionOutput(vector stringstream ef; if (second_deriv_symb_id == ExternalFunctionsTable::IDNotSet) ef << R"({"second_deriv_external_function": {)" - << R"("external_function_term": "TEFDD_fdd_)" << getIndxInTefTerms(symb_id, tef_terms) << "_" << inputIndex1 << "_" << inputIndex2 << R"(")" + << R"("external_function_term": "TEFDD_fdd_)" << getIndxInTefTerms(symb_id, tef_terms) << "_" + << inputIndex1 << "_" << inputIndex2 << R"(")" << R"(, "analytic_derivative": false)" - << R"(, "wrt1": )" << inputIndex1 - << R"(, "wrt2": )" << inputIndex2 - << R"(, "value": ")" << datatree.symbol_table.getName(symb_id) << "("; + << R"(, "wrt1": )" << inputIndex1 << R"(, "wrt2": )" << inputIndex2 << R"(, "value": ")" + << datatree.symbol_table.getName(symb_id) << "("; else { - tef_terms[{ second_deriv_symb_id, arguments }] = static_cast(tef_terms.size()); + tef_terms[{second_deriv_symb_id, arguments}] = static_cast(tef_terms.size()); ef << R"({"second_deriv_external_function": {)" - << R"("external_function_term": "TEFDD_def_)" << getIndxInTefTerms(second_deriv_symb_id, tef_terms) << R"(")" + << R"("external_function_term": "TEFDD_def_)" + << getIndxInTefTerms(second_deriv_symb_id, tef_terms) << R"(")" << R"(, "analytic_derivative": true)" << R"(, "value": ")" << datatree.symbol_table.getName(second_deriv_symb_id) << "("; } @@ -8103,13 +8292,14 @@ SecondDerivExternalFunctionNode::writeJsonExternalFunctionOutput(vector } expr_t -SecondDerivExternalFunctionNode::buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const +SecondDerivExternalFunctionNode::buildSimilarExternalFunctionNode(vector& alt_args, + DataTree& alt_datatree) const { return alt_datatree.AddSecondDerivExternalFunction(symb_id, alt_args, inputIndex1, inputIndex2); } void -SecondDerivExternalFunctionNode::computeXrefs(EquationInfo &ei) const +SecondDerivExternalFunctionNode::computeXrefs(EquationInfo& ei) const { vector dynamic_arguments; for (auto argument : arguments) @@ -8117,36 +8307,37 @@ SecondDerivExternalFunctionNode::computeXrefs(EquationInfo &ei) const } void -SecondDerivExternalFunctionNode::writeBytecodeOutput(BytecodeWriter &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 +SecondDerivExternalFunctionNode::writeBytecodeOutput( + BytecodeWriter& 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 { if (output_type == ExprNodeBytecodeOutputType::dynamicSteadyStateOperator) { - cerr << "ERROR: The expression inside a steady_state operator cannot contain external functions" << endl; + cerr << "ERROR: The expression inside a steady_state operator cannot contain external " + "functions" + << endl; exit(EXIT_FAILURE); } - if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, + temporary_terms_idxs)) return; int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); assert(second_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); if (!isAssignmentLHSBytecodeOutput(output_type)) - code_file << FLDTEFDD_{getIndxInTefTerms(symb_id, tef_terms), inputIndex1, inputIndex2}; + code_file << FLDTEFDD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex1, inputIndex2}; else - code_file << FSTPTEFDD_{getIndxInTefTerms(symb_id, tef_terms), inputIndex1, inputIndex2}; + code_file << FSTPTEFDD_ {getIndxInTefTerms(symb_id, tef_terms), inputIndex1, inputIndex2}; } void -SecondDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &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 +SecondDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput( + BytecodeWriter& 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 { int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); assert(second_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); @@ -8170,67 +8361,69 @@ SecondDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWri if (int indx = getIndxInTefTerms(symb_id, tef_terms); second_deriv_symb_id == ExternalFunctionsTable::IDNotSet) { - FCALL_ fcall{1, 0, "hess_element", indx, ExternalFunctionCallType::numericalSecondDerivative}; + FCALL_ fcall {1, 0, "hess_element", indx, + 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(arguments.size())); - code_file << fcall << FSTPTEFDD_{indx, inputIndex1, inputIndex2}; + code_file << fcall << FSTPTEFDD_ {indx, inputIndex1, inputIndex2}; } else { - tef_terms[{ second_deriv_symb_id, arguments }] = static_cast(tef_terms.size()); + tef_terms[{second_deriv_symb_id, arguments}] = static_cast(tef_terms.size()); - code_file << FCALL_{1, static_cast(arguments.size()), datatree.symbol_table.getName(second_deriv_symb_id), indx, ExternalFunctionCallType::separatelyProvidedSecondDerivative} - << FSTPTEFDD_{indx, inputIndex1, inputIndex2}; + code_file << FCALL_ {1, static_cast(arguments.size()), + datatree.symbol_table.getName(second_deriv_symb_id), indx, + ExternalFunctionCallType::separatelyProvidedSecondDerivative} + << FSTPTEFDD_ {indx, inputIndex1, inputIndex2}; } } -function +function SecondDerivExternalFunctionNode::sameTefTermPredicate() const { int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); if (second_deriv_symb_id == symb_id) return [this](expr_t e) { - auto e2 = dynamic_cast(e); + auto e2 = dynamic_cast(e); return (e2 && e2->symb_id == symb_id && e2->arguments == arguments); }; else return [this](expr_t e) { - auto e2 = dynamic_cast(e); + auto e2 = dynamic_cast(e); return (e2 && e2->symb_id == symb_id && e2->arguments == arguments); }; } -SubModelNode::SubModelNode(DataTree &datatree_arg, - int idx_arg, - string model_name_arg) : - ExprNode{datatree_arg, idx_arg}, - model_name{move(model_name_arg)} +SubModelNode::SubModelNode(DataTree& datatree_arg, int idx_arg, string model_name_arg) : + ExprNode {datatree_arg, idx_arg}, model_name {move(model_name_arg)} { } void -SubModelNode::computeTemporaryTerms([[maybe_unused]] const pair &derivOrder, - [[maybe_unused]] map, unordered_set> &temp_terms_map, - [[maybe_unused]] unordered_map>> &reference_count, - [[maybe_unused]] bool is_matlab) const +SubModelNode::computeTemporaryTerms( + [[maybe_unused]] const pair& derivOrder, + [[maybe_unused]] map, unordered_set>& temp_terms_map, + [[maybe_unused]] unordered_map>>& reference_count, + [[maybe_unused]] bool is_matlab) const { cerr << "SubModelNode::computeTemporaryTerms not implemented." << endl; exit(EXIT_FAILURE); } void -SubModelNode::computeBlockTemporaryTerms([[maybe_unused]] int blk, [[maybe_unused]] int eq, - [[maybe_unused]] vector>> &blocks_temporary_terms, - [[maybe_unused]] unordered_map> &reference_count) const +SubModelNode::computeBlockTemporaryTerms( + [[maybe_unused]] int blk, [[maybe_unused]] int eq, + [[maybe_unused]] vector>>& blocks_temporary_terms, + [[maybe_unused]] unordered_map>& reference_count) const { cerr << "SubModelNode::computeBlocksTemporaryTerms not implemented." << endl; exit(EXIT_FAILURE); } expr_t -SubModelNode::toStatic([[maybe_unused]] DataTree &static_datatree) const +SubModelNode::toStatic([[maybe_unused]] DataTree& static_datatree) const { cerr << "SubModelNode::toStatic not implemented." << endl; exit(EXIT_FAILURE); @@ -8244,8 +8437,9 @@ SubModelNode::prepareForDerivation() } void -SubModelNode::prepareForChainRuleDerivation([[maybe_unused]] const map &recursive_variables, - [[maybe_unused]] unordered_map> &non_null_chain_rule_derivatives) const +SubModelNode::prepareForChainRuleDerivation( + [[maybe_unused]] const map& recursive_variables, + [[maybe_unused]] unordered_map>& non_null_chain_rule_derivatives) const { cerr << "SubModelNode::prepareForChainRuleDerivation not implemented." << endl; exit(EXIT_FAILURE); @@ -8259,10 +8453,11 @@ SubModelNode::computeDerivative([[maybe_unused]] int deriv_id) } expr_t -SubModelNode::computeChainRuleDerivative([[maybe_unused]] int deriv_id, - [[maybe_unused]] const map &recursive_variables, - [[maybe_unused]] unordered_map> &non_null_chain_rule_derivatives, - [[maybe_unused]] unordered_map> &cache) +SubModelNode::computeChainRuleDerivative( + [[maybe_unused]] int deriv_id, + [[maybe_unused]] const map& recursive_variables, + [[maybe_unused]] unordered_map>& non_null_chain_rule_derivatives, + [[maybe_unused]] unordered_map>& cache) { cerr << "SubModelNode::computeChainRuleDerivative not implemented." << endl; exit(EXIT_FAILURE); @@ -8318,7 +8513,7 @@ SubModelNode::undiff() const } int -SubModelNode::VarMaxLag([[maybe_unused]] const set &lhs_lag_equiv) const +SubModelNode::VarMaxLag([[maybe_unused]] const set& lhs_lag_equiv) const { cerr << "SubModelNode::VarMaxLag not implemented." << endl; exit(EXIT_FAILURE); @@ -8338,10 +8533,9 @@ SubModelNode::countDiffs() const exit(EXIT_FAILURE); } - expr_t -SubModelNode::substituteEndoLeadGreaterThanTwo([[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs, +SubModelNode::substituteEndoLeadGreaterThanTwo([[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs, [[maybe_unused]] bool deterministic_model) const { cerr << "SubModelNode::substituteEndoLeadGreaterThanTwo not implemented." << endl; @@ -8349,16 +8543,16 @@ SubModelNode::substituteEndoLeadGreaterThanTwo([[maybe_unused]] subst_table_t &s } expr_t -SubModelNode::substituteEndoLagGreaterThanTwo([[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs) const +SubModelNode::substituteEndoLagGreaterThanTwo([[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs) const { cerr << "SubModelNode::substituteEndoLagGreaterThanTwo not implemented." << endl; exit(EXIT_FAILURE); } expr_t -SubModelNode::substituteExoLead([[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs, +SubModelNode::substituteExoLead([[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs, [[maybe_unused]] bool deterministic_model) const { cerr << "SubModelNode::substituteExoLead not implemented." << endl; @@ -8366,8 +8560,8 @@ SubModelNode::substituteExoLead([[maybe_unused]] subst_table_t &subst_table, } expr_t -SubModelNode::substituteExoLag([[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs) const +SubModelNode::substituteExoLag([[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs) const { cerr << "SubModelNode::substituteExoLag not implemented." << endl; exit(EXIT_FAILURE); @@ -8380,18 +8574,18 @@ SubModelNode::containsExternalFunction() const } double -SubModelNode::eval([[maybe_unused]] const eval_context_t &eval_context) const noexcept(false) +SubModelNode::eval([[maybe_unused]] const eval_context_t& eval_context) const noexcept(false) { throw EvalException(); } void -SubModelNode::computeXrefs([[maybe_unused]] EquationInfo &ei) const +SubModelNode::computeXrefs([[maybe_unused]] EquationInfo& ei) const { } void -SubModelNode::collectVARLHSVariable([[maybe_unused]] set &result) const +SubModelNode::collectVARLHSVariable([[maybe_unused]] set& result) const { cerr << "ERROR: you can only have variables or unary ops on LHS of VAR" << endl; exit(EXIT_FAILURE); @@ -8399,16 +8593,17 @@ SubModelNode::collectVARLHSVariable([[maybe_unused]] set &result) const void SubModelNode::collectDynamicVariables([[maybe_unused]] SymbolType type_arg, - [[maybe_unused]] set> &result) const + [[maybe_unused]] set>& result) const { } void -SubModelNode::writeBytecodeOutput([[maybe_unused]] BytecodeWriter &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, - [[maybe_unused]] const deriv_node_temp_terms_t &tef_terms) const +SubModelNode::writeBytecodeOutput( + [[maybe_unused]] BytecodeWriter& 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, + [[maybe_unused]] const deriv_node_temp_terms_t& tef_terms) const { cerr << "SubModelNode::compile not implemented." << endl; exit(EXIT_FAILURE); @@ -8417,44 +8612,45 @@ SubModelNode::writeBytecodeOutput([[maybe_unused]] BytecodeWriter &code_file, void SubModelNode::computeSubExprContainingVariable([[maybe_unused]] int symb_id, [[maybe_unused]] int lag, - [[maybe_unused]] set &contain_var) const + [[maybe_unused]] set& contain_var) const { } -BinaryOpNode * -SubModelNode::normalizeEquationHelper([[maybe_unused]] const set &contain_var, +BinaryOpNode* +SubModelNode::normalizeEquationHelper([[maybe_unused]] const set& contain_var, [[maybe_unused]] expr_t rhs) const { throw NormalizationFailed(); } expr_t -SubModelNode::substituteExpectation([[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs, +SubModelNode::substituteExpectation([[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs, [[maybe_unused]] bool partial_information_model) const { - return const_cast(this); + return const_cast(this); } expr_t SubModelNode::substituteAdl() const { - return const_cast(this); + return const_cast(this); } expr_t SubModelNode::substituteModelLocalVariables() const { - return const_cast(this); + return const_cast(this); } void -SubModelNode::findDiffNodes([[maybe_unused]] lag_equivalence_table_t &nodes) const +SubModelNode::findDiffNodes([[maybe_unused]] lag_equivalence_table_t& nodes) const { } void -SubModelNode::findUnaryOpNodesForAuxVarCreation([[maybe_unused]] lag_equivalence_table_t &nodes) const +SubModelNode::findUnaryOpNodesForAuxVarCreation( + [[maybe_unused]] lag_equivalence_table_t& nodes) const { } @@ -8465,19 +8661,19 @@ SubModelNode::findTargetVariable([[maybe_unused]] int lhs_symb_id) const } expr_t -SubModelNode::substituteDiff([[maybe_unused]] const lag_equivalence_table_t &nodes, - [[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs) const +SubModelNode::substituteDiff([[maybe_unused]] const lag_equivalence_table_t& nodes, + [[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs) const { - return const_cast(this); + return const_cast(this); } expr_t -SubModelNode::substituteUnaryOpNodes([[maybe_unused]] const lag_equivalence_table_t &nodes, - [[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs) const +SubModelNode::substituteUnaryOpNodes([[maybe_unused]] const lag_equivalence_table_t& nodes, + [[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs) const { - return const_cast(this); + return const_cast(this); } bool @@ -8507,15 +8703,15 @@ SubModelNode::isParamTimesEndogExpr() const } expr_t -SubModelNode::replaceVarsInEquation([[maybe_unused]] map &table) const +SubModelNode::replaceVarsInEquation([[maybe_unused]] map& table) const { - return const_cast(this); + return const_cast(this); } expr_t -SubModelNode::differentiateForwardVars([[maybe_unused]] const vector &subset, - [[maybe_unused]] subst_table_t &subst_table, - [[maybe_unused]] vector &neweqs) const +SubModelNode::differentiateForwardVars([[maybe_unused]] const vector& subset, + [[maybe_unused]] subst_table_t& subst_table, + [[maybe_unused]] vector& neweqs) const { cerr << "SubModelNode::differentiateForwardVars not implemented." << endl; exit(EXIT_FAILURE); @@ -8544,7 +8740,7 @@ SubModelNode::detrend([[maybe_unused]] int symb_id, [[maybe_unused]] bool log_tr } expr_t -SubModelNode::removeTrendLeadLag([[maybe_unused]] const map &trend_symbols_map) const +SubModelNode::removeTrendLeadLag([[maybe_unused]] const map& trend_symbols_map) const { cerr << "SubModelNode::removeTrendLeadLag not implemented." << endl; exit(EXIT_FAILURE); @@ -8554,23 +8750,20 @@ expr_t SubModelNode::substituteLogTransform([[maybe_unused]] int orig_symb_id, [[maybe_unused]] int aux_symb_id) const { - return const_cast(this); + return const_cast(this); } -VarExpectationNode::VarExpectationNode(DataTree &datatree_arg, - int idx_arg, - string model_name_arg) : - SubModelNode{datatree_arg, idx_arg, move(model_name_arg)} +VarExpectationNode::VarExpectationNode(DataTree& datatree_arg, int idx_arg, string model_name_arg) : + SubModelNode {datatree_arg, idx_arg, move(model_name_arg)} { } expr_t -VarExpectationNode::clone(DataTree &alt_datatree) const +VarExpectationNode::clone(DataTree& alt_datatree) const { return alt_datatree.AddVarExpectation(model_name); } - int VarExpectationNode::maxLagWithDiffsExpanded() const { @@ -8585,10 +8778,10 @@ VarExpectationNode::maxLagWithDiffsExpanded() const } void -VarExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - [[maybe_unused]] const temporary_terms_t &temporary_terms, - [[maybe_unused]] const temporary_terms_idxs_t &temporary_terms_idxs, - [[maybe_unused]] const deriv_node_temp_terms_t &tef_terms) const +VarExpectationNode::writeOutput(ostream& output, ExprNodeOutputType output_type, + [[maybe_unused]] const temporary_terms_t& temporary_terms, + [[maybe_unused]] const temporary_terms_idxs_t& temporary_terms_idxs, + [[maybe_unused]] const deriv_node_temp_terms_t& tef_terms) const { assert(output_type != ExprNodeOutputType::matlabOutsideModel); @@ -8603,79 +8796,78 @@ VarExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, } expr_t -VarExpectationNode::substituteVarExpectation(const map &subst_table) const +VarExpectationNode::substituteVarExpectation(const map& subst_table) const { auto it = subst_table.find(model_name); if (it == subst_table.end()) { - cerr << "ERROR: unknown model '" << model_name << "' used in var_expectation expression" << endl; + cerr << "ERROR: unknown model '" << model_name << "' used in var_expectation expression" + << endl; exit(EXIT_FAILURE); } return it->second; } expr_t -VarExpectationNode::substitutePacExpectation([[maybe_unused]] const string &name, +VarExpectationNode::substitutePacExpectation([[maybe_unused]] const string& name, [[maybe_unused]] expr_t subexpr) { - return const_cast(this); + return const_cast(this); } expr_t -VarExpectationNode::substitutePacTargetNonstationary([[maybe_unused]] const string &name, +VarExpectationNode::substitutePacTargetNonstationary([[maybe_unused]] const string& name, [[maybe_unused]] expr_t subexpr) { - return const_cast(this); + return const_cast(this); } bool -VarExpectationNode::containsPacExpectation([[maybe_unused]] const string &pac_model_name) const +VarExpectationNode::containsPacExpectation([[maybe_unused]] const string& pac_model_name) const { return false; } bool -VarExpectationNode::containsPacTargetNonstationary([[maybe_unused]] const string &pac_model_name) const +VarExpectationNode::containsPacTargetNonstationary( + [[maybe_unused]] const string& pac_model_name) const { return false; } void -VarExpectationNode::writeJsonAST(ostream &output) const +VarExpectationNode::writeJsonAST(ostream& output) const { output << R"({"node_type" : "VarExpectationNode", )" << R"("name" : ")" << model_name << R"("})"; } void -VarExpectationNode::writeJsonOutput(ostream &output, - [[maybe_unused]] const temporary_terms_t &temporary_terms, - [[maybe_unused]] const deriv_node_temp_terms_t &tef_terms, +VarExpectationNode::writeJsonOutput(ostream& output, + [[maybe_unused]] const temporary_terms_t& temporary_terms, + [[maybe_unused]] const deriv_node_temp_terms_t& tef_terms, [[maybe_unused]] bool isdynamic) const { output << "var_expectation(" - << "model_name = " << model_name - << ")"; + << "model_name = " << model_name << ")"; } -PacExpectationNode::PacExpectationNode(DataTree &datatree_arg, - int idx_arg, - string model_name_arg) : - SubModelNode{datatree_arg, idx_arg, move(model_name_arg)} +PacExpectationNode::PacExpectationNode(DataTree& datatree_arg, int idx_arg, string model_name_arg) : + SubModelNode {datatree_arg, idx_arg, move(model_name_arg)} { } expr_t -PacExpectationNode::clone(DataTree &alt_datatree) const +PacExpectationNode::clone(DataTree& alt_datatree) const { return alt_datatree.AddPacExpectation(model_name); } void -PacExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - [[maybe_unused]] const temporary_terms_t &temporary_terms, - [[maybe_unused]] const temporary_terms_idxs_t &temporary_terms_idxs, - [[maybe_unused]] const deriv_node_temp_terms_t &tef_terms) const +PacExpectationNode::writeOutput(ostream& output, ExprNodeOutputType output_type, + [[maybe_unused]] const temporary_terms_t& temporary_terms, + [[maybe_unused]] const temporary_terms_idxs_t& temporary_terms_idxs, + [[maybe_unused]] const deriv_node_temp_terms_t& tef_terms) const { assert(output_type != ExprNodeOutputType::matlabOutsideModel); if (isLatexOutput(output_type)) @@ -8696,13 +8888,14 @@ PacExpectationNode::maxLagWithDiffsExpanded() const } expr_t -PacExpectationNode::substituteVarExpectation([[maybe_unused]] const map &subst_table) const +PacExpectationNode::substituteVarExpectation( + [[maybe_unused]] const map& subst_table) const { - return const_cast(this); + return const_cast(this); } bool -PacExpectationNode::containsPacExpectation(const string &pac_model_name) const +PacExpectationNode::containsPacExpectation(const string& pac_model_name) const { if (pac_model_name.empty()) return true; @@ -8711,67 +8904,68 @@ PacExpectationNode::containsPacExpectation(const string &pac_model_name) const } bool -PacExpectationNode::containsPacTargetNonstationary([[maybe_unused]] const string &pac_model_name) const +PacExpectationNode::containsPacTargetNonstationary( + [[maybe_unused]] const string& pac_model_name) const { return false; } void -PacExpectationNode::writeJsonAST(ostream &output) const +PacExpectationNode::writeJsonAST(ostream& output) const { output << R"({"node_type" : "PacExpectationNode", )" << R"("name" : ")" << model_name << R"("})"; } void -PacExpectationNode::writeJsonOutput(ostream &output, - [[maybe_unused]] const temporary_terms_t &temporary_terms, - [[maybe_unused]] const deriv_node_temp_terms_t &tef_terms, +PacExpectationNode::writeJsonOutput(ostream& output, + [[maybe_unused]] const temporary_terms_t& temporary_terms, + [[maybe_unused]] const deriv_node_temp_terms_t& tef_terms, [[maybe_unused]] bool isdynamic) const { output << "pac_expectation(" - << "model_name = " << model_name - << ")"; + << "model_name = " << model_name << ")"; } expr_t -PacExpectationNode::substitutePacExpectation(const string &name, expr_t subexpr) +PacExpectationNode::substitutePacExpectation(const string& name, expr_t subexpr) { if (model_name != name) - return const_cast(this); + return const_cast(this); return subexpr; } expr_t -PacExpectationNode::substitutePacTargetNonstationary([[maybe_unused]] const string &name, +PacExpectationNode::substitutePacTargetNonstationary([[maybe_unused]] const string& name, [[maybe_unused]] expr_t subexpr) { - return const_cast(this); + return const_cast(this); } -PacTargetNonstationaryNode::PacTargetNonstationaryNode(DataTree &datatree_arg, - int idx_arg, +PacTargetNonstationaryNode::PacTargetNonstationaryNode(DataTree& datatree_arg, int idx_arg, string model_name_arg) : - SubModelNode{datatree_arg, idx_arg, move(model_name_arg)} + SubModelNode {datatree_arg, idx_arg, move(model_name_arg)} { } expr_t -PacTargetNonstationaryNode::clone(DataTree &alt_datatree) const +PacTargetNonstationaryNode::clone(DataTree& alt_datatree) const { return alt_datatree.AddPacTargetNonstationary(model_name); } void -PacTargetNonstationaryNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - [[maybe_unused]] const temporary_terms_t &temporary_terms, - [[maybe_unused]] const temporary_terms_idxs_t &temporary_terms_idxs, - [[maybe_unused]] const deriv_node_temp_terms_t &tef_terms) const +PacTargetNonstationaryNode::writeOutput( + ostream& output, ExprNodeOutputType output_type, + [[maybe_unused]] const temporary_terms_t& temporary_terms, + [[maybe_unused]] const temporary_terms_idxs_t& temporary_terms_idxs, + [[maybe_unused]] const deriv_node_temp_terms_t& tef_terms) const { assert(output_type != ExprNodeOutputType::matlabOutsideModel); if (isLatexOutput(output_type)) { - output << "PAC_TARGET_NONSTATIONARY" << LEFT_PAR(output_type) << model_name << RIGHT_PAR(output_type); + output << "PAC_TARGET_NONSTATIONARY" << LEFT_PAR(output_type) << model_name + << RIGHT_PAR(output_type); return; } @@ -8787,19 +8981,21 @@ PacTargetNonstationaryNode::maxLagWithDiffsExpanded() const } expr_t -PacTargetNonstationaryNode::substituteVarExpectation([[maybe_unused]] const map &subst_table) const +PacTargetNonstationaryNode::substituteVarExpectation( + [[maybe_unused]] const map& subst_table) const { - return const_cast(this); + return const_cast(this); } bool -PacTargetNonstationaryNode::containsPacExpectation([[maybe_unused]] const string &pac_model_name) const +PacTargetNonstationaryNode::containsPacExpectation( + [[maybe_unused]] const string& pac_model_name) const { return false; } bool -PacTargetNonstationaryNode::containsPacTargetNonstationary(const string &pac_model_name) const +PacTargetNonstationaryNode::containsPacTargetNonstationary(const string& pac_model_name) const { if (pac_model_name.empty()) return true; @@ -8808,46 +9004,45 @@ PacTargetNonstationaryNode::containsPacTargetNonstationary(const string &pac_mod } void -PacTargetNonstationaryNode::writeJsonAST(ostream &output) const +PacTargetNonstationaryNode::writeJsonAST(ostream& output) const { output << R"({"node_type" : "PacTargetNonstationaryNode", )" << R"("name" : ")" << model_name << R"("})"; } void -PacTargetNonstationaryNode::writeJsonOutput(ostream &output, - [[maybe_unused]] const temporary_terms_t &temporary_terms, - [[maybe_unused]] const deriv_node_temp_terms_t &tef_terms, - [[maybe_unused]] bool isdynamic) const +PacTargetNonstationaryNode::writeJsonOutput( + ostream& output, [[maybe_unused]] const temporary_terms_t& temporary_terms, + [[maybe_unused]] const deriv_node_temp_terms_t& tef_terms, + [[maybe_unused]] bool isdynamic) const { output << "pac_target_nonstationary(" - << "model_name = " << model_name - << ")"; + << "model_name = " << model_name << ")"; } expr_t -PacTargetNonstationaryNode::substitutePacExpectation([[maybe_unused]] const string &name, +PacTargetNonstationaryNode::substitutePacExpectation([[maybe_unused]] const string& name, [[maybe_unused]] expr_t subexpr) { - return const_cast(this); + return const_cast(this); } expr_t -PacTargetNonstationaryNode::substitutePacTargetNonstationary(const string &name, expr_t subexpr) +PacTargetNonstationaryNode::substitutePacTargetNonstationary(const string& name, expr_t subexpr) { if (model_name != name) - return const_cast(this); + return const_cast(this); return subexpr; } void -ExprNode::decomposeAdditiveTerms(vector> &terms, int current_sign) const +ExprNode::decomposeAdditiveTerms(vector>& terms, int current_sign) const { - terms.emplace_back(const_cast(this), current_sign); + terms.emplace_back(const_cast(this), current_sign); } void -UnaryOpNode::decomposeAdditiveTerms(vector> &terms, int current_sign) const +UnaryOpNode::decomposeAdditiveTerms(vector>& terms, int current_sign) const { if (op_code == UnaryOpcode::uminus) arg->decomposeAdditiveTerms(terms, -current_sign); @@ -8856,7 +9051,7 @@ UnaryOpNode::decomposeAdditiveTerms(vector> &terms, int curren } void -BinaryOpNode::decomposeAdditiveTerms(vector> &terms, int current_sign) const +BinaryOpNode::decomposeAdditiveTerms(vector>& terms, int current_sign) const { if (op_code == BinaryOpcode::plus || op_code == BinaryOpcode::minus) { @@ -8871,13 +9066,15 @@ BinaryOpNode::decomposeAdditiveTerms(vector> &terms, int curre } void -ExprNode::decomposeMultiplicativeFactors(vector> &factors, int current_exponent) const +ExprNode::decomposeMultiplicativeFactors(vector>& factors, + int current_exponent) const { - factors.emplace_back(const_cast(this), current_exponent); + factors.emplace_back(const_cast(this), current_exponent); } void -BinaryOpNode::decomposeMultiplicativeFactors(vector> &factors, int current_exponent) const +BinaryOpNode::decomposeMultiplicativeFactors(vector>& factors, + int current_exponent) const { if (op_code == BinaryOpcode::times || op_code == BinaryOpcode::divide) { @@ -8899,21 +9096,22 @@ ExprNode::matchVariableTimesConstantTimesParam(bool variable_obligatory) const double constant = 1.0; 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}; + throw MatchFailureException {"No variable in this expression"}; + return {move(variable_id), lag, move(param_id), constant}; } void -ExprNode::matchVTCTPHelper([[maybe_unused]] optional &var_id, [[maybe_unused]] int &lag, - [[maybe_unused]] optional ¶m_id, [[maybe_unused]] double &constant, +ExprNode::matchVTCTPHelper([[maybe_unused]] optional& var_id, [[maybe_unused]] int& lag, + [[maybe_unused]] optional& param_id, + [[maybe_unused]] double& constant, [[maybe_unused]] bool at_denominator) const { - throw MatchFailureException{"Expression not allowed in linear combination of variables"}; + throw MatchFailureException {"Expression not allowed in linear combination of variables"}; } void -NumConstNode::matchVTCTPHelper([[maybe_unused]] optional &var_id, [[maybe_unused]] int &lag, - [[maybe_unused]] optional ¶m_id, double &constant, +NumConstNode::matchVTCTPHelper([[maybe_unused]] optional& var_id, [[maybe_unused]] int& lag, + [[maybe_unused]] optional& param_id, double& constant, bool at_denominator) const { double myvalue = eval({}); @@ -8924,32 +9122,34 @@ NumConstNode::matchVTCTPHelper([[maybe_unused]] optional &var_id, [[maybe_u } void -VariableNode::matchVTCTPHelper(optional &var_id, int &lag, optional ¶m_id, - [[maybe_unused]] double &constant, bool at_denominator) const +VariableNode::matchVTCTPHelper(optional& var_id, int& lag, optional& param_id, + [[maybe_unused]] double& constant, bool at_denominator) const { if (at_denominator) - throw MatchFailureException{"A variable or parameter cannot appear at denominator"}; + throw MatchFailureException {"A variable or parameter cannot appear at denominator"}; SymbolType type = get_type(); if (type == SymbolType::endogenous || type == SymbolType::exogenous) { if (var_id) - throw MatchFailureException{"More than one variable in this expression"}; + throw MatchFailureException {"More than one variable in this expression"}; var_id = symb_id; lag = this->lag; } else if (type == SymbolType::parameter) { if (param_id) - throw MatchFailureException{"More than one parameter in this expression"}; + throw MatchFailureException {"More than one parameter in this expression"}; param_id = symb_id; } else - throw MatchFailureException{"Symbol " + datatree.symbol_table.getName(symb_id) + " not allowed here"}; + throw MatchFailureException {"Symbol " + datatree.symbol_table.getName(symb_id) + + " not allowed here"}; } void -UnaryOpNode::matchVTCTPHelper(optional &var_id, int &lag, optional ¶m_id, double &constant, bool at_denominator) const +UnaryOpNode::matchVTCTPHelper(optional& var_id, int& lag, optional& param_id, + double& constant, bool at_denominator) const { if (op_code == UnaryOpcode::uminus) { @@ -8957,11 +9157,12 @@ UnaryOpNode::matchVTCTPHelper(optional &var_id, int &lag, optional &pa arg->matchVTCTPHelper(var_id, lag, param_id, constant, at_denominator); } else - throw MatchFailureException{"Operator not allowed in this expression"}; + throw MatchFailureException {"Operator not allowed in this expression"}; } void -BinaryOpNode::matchVTCTPHelper(optional &var_id, int &lag, optional ¶m_id, double &constant, bool at_denominator) const +BinaryOpNode::matchVTCTPHelper(optional& var_id, int& lag, optional& param_id, + double& constant, bool at_denominator) const { if (op_code == BinaryOpcode::times || op_code == BinaryOpcode::divide) { @@ -8972,7 +9173,7 @@ BinaryOpNode::matchVTCTPHelper(optional &var_id, int &lag, optional &p arg2->matchVTCTPHelper(var_id, lag, param_id, constant, !at_denominator); } else - throw MatchFailureException{"Operator not allowed in this expression"}; + throw MatchFailureException {"Operator not allowed in this expression"}; } vector, double>> @@ -8985,7 +9186,8 @@ ExprNode::matchLinearCombinationOfVariables() const for (auto [term, sign] : terms) { - auto [variable_id, lag, param_id, constant] = term->matchVariableTimesConstantTimesParam(true); + auto [variable_id, lag, param_id, constant] + = term->matchVariableTimesConstantTimesParam(true); constant *= sign; result.emplace_back(variable_id.value(), lag, move(param_id), constant); } @@ -9012,94 +9214,92 @@ ExprNode::matchLinearCombinationOfVariablesPlusConstant() const pair, double>>> ExprNode::matchParamTimesLinearCombinationOfVariables() const { - auto bopn = dynamic_cast(this); + auto bopn = dynamic_cast(this); if (!bopn || bopn->op_code != BinaryOpcode::times) - throw MatchFailureException{"Not a multiplicative expression"}; + throw MatchFailureException {"Not a multiplicative expression"}; expr_t param = bopn->arg1, lincomb = bopn->arg2; auto is_param = [](expr_t e) { - auto vn = dynamic_cast(e); - return vn && vn->get_type() == SymbolType::parameter; - }; + auto vn = dynamic_cast(e); + return vn && vn->get_type() == SymbolType::parameter; + }; if (!is_param(param)) { swap(param, lincomb); if (!is_param(param)) - throw MatchFailureException{"No parameter on either side of the multiplication"}; + throw MatchFailureException {"No parameter on either side of the multiplication"}; } - return { dynamic_cast(param)->symb_id, lincomb->matchLinearCombinationOfVariables() }; + return {dynamic_cast(param)->symb_id, + lincomb->matchLinearCombinationOfVariables()}; } pair ExprNode::matchParamTimesTargetMinusVariable(int symb_id) const { - auto bopn = dynamic_cast(this); + auto bopn = dynamic_cast(this); if (!bopn || bopn->op_code != BinaryOpcode::times) - throw MatchFailureException{"Not a multiplicative expression"}; + throw MatchFailureException {"Not a multiplicative expression"}; expr_t param = bopn->arg1, minus = bopn->arg2; auto is_param = [](expr_t e) { - auto vn = dynamic_cast(e); - return vn && vn->get_type() == SymbolType::parameter; - }; + auto vn = dynamic_cast(e); + return vn && vn->get_type() == SymbolType::parameter; + }; if (!is_param(param)) { swap(param, minus); if (!is_param(param)) - throw MatchFailureException{"No parameter on either side of the multiplication"}; + throw MatchFailureException {"No parameter on either side of the multiplication"}; } - auto bminus = dynamic_cast(minus); + auto bminus = dynamic_cast(minus); if (!bminus || bminus->op_code != BinaryOpcode::minus) - throw MatchFailureException{"Neither factor is a minus operator"}; + throw MatchFailureException {"Neither factor is a minus operator"}; - auto lhs_level = dynamic_cast(bminus->arg2); - auto target = dynamic_cast(bminus->arg1); + auto lhs_level = dynamic_cast(bminus->arg2); + auto target = dynamic_cast(bminus->arg1); - auto check_target = [&] - { - if (target->get_type() != SymbolType::endogenous - && target->get_type() != SymbolType::exogenous) - return false; - if (datatree.symbol_table.isAuxiliaryVariable(target->symb_id)) - { - auto &avi = datatree.symbol_table.getAuxVarInfo(target->symb_id); - if (avi.type == AuxVarType::pacTargetNonstationary && target->lag == -1) - return true; - return (avi.type == AuxVarType::unaryOp - && avi.unary_op == "log" - && avi.orig_symb_id - && !datatree.symbol_table.isAuxiliaryVariable(*avi.orig_symb_id) - && target->lag + avi.orig_lead_lag.value() == -1); - } - else - return target->lag == -1; - }; + auto check_target = [&] { + if (target->get_type() != SymbolType::endogenous && target->get_type() != SymbolType::exogenous) + return false; + if (datatree.symbol_table.isAuxiliaryVariable(target->symb_id)) + { + auto& avi = datatree.symbol_table.getAuxVarInfo(target->symb_id); + if (avi.type == AuxVarType::pacTargetNonstationary && target->lag == -1) + return true; + return (avi.type == AuxVarType::unaryOp && avi.unary_op == "log" && avi.orig_symb_id + && !datatree.symbol_table.isAuxiliaryVariable(*avi.orig_symb_id) + && target->lag + avi.orig_lead_lag.value() == -1); + } + else + return target->lag == -1; + }; if (lhs_level && lhs_level->symb_id == symb_id && target && check_target()) - return { dynamic_cast(param)->symb_id, target->symb_id }; + return {dynamic_cast(param)->symb_id, target->symb_id}; else - throw MatchFailureException{"Neither factor is of the form (target-variable) where target is endo or exo (possibly logged), and has one lag"}; + throw MatchFailureException {"Neither factor is of the form (target-variable) where target is " + "endo or exo (possibly logged), and has one lag"}; } pair ExprNode::matchEndogenousTimesConstant() const { - throw MatchFailureException{"This expression is not of the form endogenous*constant"}; + throw MatchFailureException {"This expression is not of the form endogenous*constant"}; } pair VariableNode::matchEndogenousTimesConstant() const { if (get_type() == SymbolType::endogenous) - return { symb_id, datatree.One }; + return {symb_id, datatree.One}; else - throw MatchFailureException{"This expression is not of the form endogenous*constant"}; + throw MatchFailureException {"This expression is not of the form endogenous*constant"}; } pair @@ -9107,14 +9307,14 @@ BinaryOpNode::matchEndogenousTimesConstant() const { if (op_code == BinaryOpcode::times) { - if (auto varg1 = dynamic_cast(arg1); + if (auto varg1 = dynamic_cast(arg1); varg1 && varg1->get_type() == SymbolType::endogenous && arg2->isConstant()) - return { varg1->symb_id, arg2 }; - if (auto varg2 = dynamic_cast(arg2); + return {varg1->symb_id, arg2}; + if (auto varg2 = dynamic_cast(arg2); varg2 && varg2->get_type() == SymbolType::endogenous && arg1->isConstant()) - return { varg2->symb_id, arg1 }; + return {varg2->symb_id, arg1}; } - throw MatchFailureException{"This expression is not of the form endogenous*constant"}; + throw MatchFailureException {"This expression is not of the form endogenous*constant"}; } pair>, expr_t> @@ -9140,7 +9340,7 @@ ExprNode::matchLinearCombinationOfEndogenousWithConstant() const constant = datatree.AddUMinus(constant); endo_terms.emplace_back(endo_id, constant); } - return { endo_terms, intercept }; + return {endo_terms, intercept}; } string diff --git a/src/ExprNode.hh b/src/ExprNode.hh index 83339ea9..b7c860ba 100644 --- a/src/ExprNode.hh +++ b/src/ExprNode.hh @@ -20,21 +20,21 @@ #ifndef _EXPR_NODE_HH #define _EXPR_NODE_HH -#include -#include -#include -#include #include +#include #include -#include +#include +#include #include #include +#include +#include using namespace std; +#include "Bytecode.hh" #include "CommonEnums.hh" #include "ExternalFunctionsTable.hh" -#include "Bytecode.hh" class DataTree; class NumConstNode; @@ -43,7 +43,7 @@ class UnaryOpNode; class BinaryOpNode; class PacExpectationNode; -using expr_t = class ExprNode *; +using expr_t = class ExprNode*; struct ExprNodeLess; @@ -58,7 +58,8 @@ using temporary_terms_idxs_t = unordered_map; /*! The key is a symbol id. Lags are assumed to be null */ using eval_context_t = map; -//! Type for tracking first/second derivative functions that have already been written as temporary terms +//! Type for tracking first/second derivative functions that have already been written as temporary +//! terms using deriv_node_temp_terms_t = map>, int>; //! Type for the substitution map used for creating aux. vars for diff and unary_ops @@ -85,114 +86,114 @@ using lag_equivalence_table_t = map>; //! Possible types of output when writing ExprNode(s) (not used for bytecode) enum class ExprNodeOutputType - { - matlabStaticModel, //!< Matlab code, static model, legacy representation - matlabDynamicModel, //!< Matlab code, dynamic model, legacy representation - matlabSparseStaticModel, //!< Matlab code, static model, sparse representation - matlabSparseDynamicModel, //!< Matlab code, dynamic model, sparse representation - CDynamicModel, //!< C code, dynamic model, legacy representation - CStaticModel, //!< C code, static model, legacy representation - CSparseDynamicModel, //!< C code, dynamic model, sparse representation - CSparseStaticModel, //!< C code, static model, sparse representation - juliaStaticModel, //!< Julia code, static model, legacy representation - juliaDynamicModel, //!< Julia code, dynamic model, legacy representation - juliaSparseStaticModel, //!< Julia code, static model, sparse representation - juliaSparseDynamicModel, //!< Julia code, dynamic model, sparse representation - matlabOutsideModel, //!< Matlab code, outside model block (for example in initval) - latexStaticModel, //!< LaTeX code, static model - latexDynamicModel, //!< LaTeX code, dynamic model - latexDynamicSteadyStateOperator, //!< LaTeX code, dynamic model, inside a steady state operator - matlabDynamicSteadyStateOperator, //!< Matlab code, dynamic model, inside a steady state operator - CDynamicSteadyStateOperator, //!< C code, dynamic model, inside a steady state operator - juliaDynamicSteadyStateOperator, //!< Julia code, dynamic model, inside a steady state operator - steadyStateFile, //!< Matlab code, in the generated steady state file - juliaSteadyStateFile, //!< Julia code, in the generated steady state file - matlabDseries, //!< Matlab code for dseries - juliaTimeDataFrame, //!< Julia code for TimeDataFrame objects - epilogueFile, //!< Matlab code, in the generated epilogue file - occbinDifferenceFile //!< MATLAB, in the generated occbin_difference file - }; +{ + matlabStaticModel, //!< Matlab code, static model, legacy representation + matlabDynamicModel, //!< Matlab code, dynamic model, legacy representation + matlabSparseStaticModel, //!< Matlab code, static model, sparse representation + matlabSparseDynamicModel, //!< Matlab code, dynamic model, sparse representation + CDynamicModel, //!< C code, dynamic model, legacy representation + CStaticModel, //!< C code, static model, legacy representation + CSparseDynamicModel, //!< C code, dynamic model, sparse representation + CSparseStaticModel, //!< C code, static model, sparse representation + juliaStaticModel, //!< Julia code, static model, legacy representation + juliaDynamicModel, //!< Julia code, dynamic model, legacy representation + juliaSparseStaticModel, //!< Julia code, static model, sparse representation + juliaSparseDynamicModel, //!< Julia code, dynamic model, sparse representation + matlabOutsideModel, //!< Matlab code, outside model block (for example in initval) + latexStaticModel, //!< LaTeX code, static model + latexDynamicModel, //!< LaTeX code, dynamic model + latexDynamicSteadyStateOperator, //!< LaTeX code, dynamic model, inside a steady state operator + matlabDynamicSteadyStateOperator, //!< Matlab code, dynamic model, inside a steady state operator + CDynamicSteadyStateOperator, //!< C code, dynamic model, inside a steady state operator + juliaDynamicSteadyStateOperator, //!< Julia code, dynamic model, inside a steady state operator + steadyStateFile, //!< Matlab code, in the generated steady state file + juliaSteadyStateFile, //!< Julia code, in the generated steady state file + matlabDseries, //!< Matlab code for dseries + juliaTimeDataFrame, //!< Julia code for TimeDataFrame objects + epilogueFile, //!< Matlab code, in the generated epilogue file + occbinDifferenceFile //!< MATLAB, in the generated occbin_difference file +}; // Possible types of output when writing ExprNode(s) in bytecode enum class ExprNodeBytecodeOutputType - { - dynamicModel, - staticModel, - dynamicSteadyStateOperator, // Inside a steady_state operator - dynamicAssignmentLHS, // Assignment of a dynamic variable on the LHS of a (recursive) equation - staticAssignmentLHS // Assignment of a static variable on the LHS of a (recursive) equation - }; +{ + dynamicModel, + staticModel, + dynamicSteadyStateOperator, // Inside a steady_state operator + dynamicAssignmentLHS, // Assignment of a dynamic variable on the LHS of a (recursive) equation + staticAssignmentLHS // Assignment of a static variable on the LHS of a (recursive) equation +}; constexpr bool isMatlabOutput(ExprNodeOutputType output_type) { return output_type == ExprNodeOutputType::matlabStaticModel - || output_type == ExprNodeOutputType::matlabDynamicModel - || output_type == ExprNodeOutputType::matlabSparseStaticModel - || output_type == ExprNodeOutputType::matlabSparseDynamicModel - || output_type == ExprNodeOutputType::matlabOutsideModel - || output_type == ExprNodeOutputType::matlabDynamicSteadyStateOperator - || output_type == ExprNodeOutputType::steadyStateFile - || output_type == ExprNodeOutputType::matlabDseries - || output_type == ExprNodeOutputType::epilogueFile - || output_type == ExprNodeOutputType::occbinDifferenceFile; + || output_type == ExprNodeOutputType::matlabDynamicModel + || output_type == ExprNodeOutputType::matlabSparseStaticModel + || output_type == ExprNodeOutputType::matlabSparseDynamicModel + || output_type == ExprNodeOutputType::matlabOutsideModel + || output_type == ExprNodeOutputType::matlabDynamicSteadyStateOperator + || output_type == ExprNodeOutputType::steadyStateFile + || output_type == ExprNodeOutputType::matlabDseries + || output_type == ExprNodeOutputType::epilogueFile + || output_type == ExprNodeOutputType::occbinDifferenceFile; } constexpr bool isJuliaOutput(ExprNodeOutputType output_type) { return output_type == ExprNodeOutputType::juliaStaticModel - || output_type == ExprNodeOutputType::juliaDynamicModel - || output_type == ExprNodeOutputType::juliaSparseStaticModel - || output_type == ExprNodeOutputType::juliaSparseDynamicModel - || output_type == ExprNodeOutputType::juliaDynamicSteadyStateOperator - || output_type == ExprNodeOutputType::juliaSteadyStateFile - || output_type == ExprNodeOutputType::juliaTimeDataFrame; + || output_type == ExprNodeOutputType::juliaDynamicModel + || output_type == ExprNodeOutputType::juliaSparseStaticModel + || output_type == ExprNodeOutputType::juliaSparseDynamicModel + || output_type == ExprNodeOutputType::juliaDynamicSteadyStateOperator + || output_type == ExprNodeOutputType::juliaSteadyStateFile + || output_type == ExprNodeOutputType::juliaTimeDataFrame; } constexpr bool isCOutput(ExprNodeOutputType output_type) { return output_type == ExprNodeOutputType::CDynamicModel - || output_type == ExprNodeOutputType::CStaticModel - || output_type == ExprNodeOutputType::CSparseDynamicModel - || output_type == ExprNodeOutputType::CSparseStaticModel - || output_type == ExprNodeOutputType::CDynamicSteadyStateOperator; + || output_type == ExprNodeOutputType::CStaticModel + || output_type == ExprNodeOutputType::CSparseDynamicModel + || output_type == ExprNodeOutputType::CSparseStaticModel + || output_type == ExprNodeOutputType::CDynamicSteadyStateOperator; } constexpr bool isLatexOutput(ExprNodeOutputType output_type) { return output_type == ExprNodeOutputType::latexStaticModel - || output_type == ExprNodeOutputType::latexDynamicModel - || output_type == ExprNodeOutputType::latexDynamicSteadyStateOperator; + || output_type == ExprNodeOutputType::latexDynamicModel + || output_type == ExprNodeOutputType::latexDynamicSteadyStateOperator; } constexpr bool isSteadyStateOperatorOutput(ExprNodeOutputType output_type) { return output_type == ExprNodeOutputType::latexDynamicSteadyStateOperator - || output_type == ExprNodeOutputType::matlabDynamicSteadyStateOperator - || output_type == ExprNodeOutputType::CDynamicSteadyStateOperator - || output_type == ExprNodeOutputType::juliaDynamicSteadyStateOperator; + || output_type == ExprNodeOutputType::matlabDynamicSteadyStateOperator + || output_type == ExprNodeOutputType::CDynamicSteadyStateOperator + || output_type == ExprNodeOutputType::juliaDynamicSteadyStateOperator; } constexpr bool isSparseModelOutput(ExprNodeOutputType output_type) { return output_type == ExprNodeOutputType::matlabSparseStaticModel - || output_type == ExprNodeOutputType::matlabSparseDynamicModel - || output_type == ExprNodeOutputType::juliaSparseStaticModel - || output_type == ExprNodeOutputType::juliaSparseDynamicModel - || output_type == ExprNodeOutputType::CSparseDynamicModel - || output_type == ExprNodeOutputType::CSparseStaticModel; + || output_type == ExprNodeOutputType::matlabSparseDynamicModel + || output_type == ExprNodeOutputType::juliaSparseStaticModel + || output_type == ExprNodeOutputType::juliaSparseDynamicModel + || output_type == ExprNodeOutputType::CSparseDynamicModel + || output_type == ExprNodeOutputType::CSparseStaticModel; } constexpr bool isAssignmentLHSBytecodeOutput(ExprNodeBytecodeOutputType output_type) { return output_type == ExprNodeBytecodeOutputType::staticAssignmentLHS - || output_type == ExprNodeBytecodeOutputType::dynamicAssignmentLHS; + || output_type == ExprNodeBytecodeOutputType::dynamicAssignmentLHS; } /* Equal to 1 for Matlab langage or Julia, or to 0 for C language. Not defined for LaTeX. @@ -245,6 +246,7 @@ class ExprNode friend class AbstractExternalFunctionNode; friend class VarExpectationNode; friend class PacExpectationNode; + private: //! Computes derivative w.r. to a derivation ID (but doesn't store it in derivatives map) /*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */ @@ -252,17 +254,21 @@ private: /* Internal helper for getChainRuleDerivative(), that does the computation but assumes that the caching of this is handled elsewhere */ - virtual expr_t computeChainRuleDerivative(int deriv_id, const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives, unordered_map> &cache) = 0; + virtual expr_t + computeChainRuleDerivative(int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) + = 0; protected: //! Reference to the enclosing DataTree - DataTree &datatree; + DataTree& datatree; //! Index number const int idx; //! Is the data member non_null_derivatives initialized ? - bool preparedForDerivation{false}; + bool preparedForDerivation {false}; //! Set of derivation IDs with respect to which the derivative is potentially non-null set non_null_derivatives; @@ -270,8 +276,8 @@ protected: //! Used for caching of first order derivatives (when non-null) map derivatives; - constexpr static int min_cost_matlab{40*90}; - constexpr static int min_cost_c{40*4}; + constexpr static int min_cost_matlab {40 * 90}; + constexpr static int min_cost_c {40 * 4}; constexpr static int min_cost(bool is_matlab) { @@ -287,13 +293,18 @@ protected: “recursive_variables”. Note that all non-endogenous variables are automatically considered to have a zero derivative (since they’re never used in a chain rule context) */ - virtual void prepareForChainRuleDerivation(const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives) const = 0; + virtual void prepareForChainRuleDerivation( + const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const + = 0; //! Cost of computing current node /*! Nodes included in temporary_terms are considered having a null cost */ virtual int cost(int cost, bool is_matlab) const; - virtual int cost(const vector>> &blocks_temporary_terms, bool is_matlab) const; - virtual int cost(const map, unordered_set> &temp_terms_map, bool is_matlab) const; + virtual int cost(const vector>>& blocks_temporary_terms, + bool is_matlab) const; + virtual int cost(const map, unordered_set>& temp_terms_map, + bool is_matlab) const; //! For creating equation cross references struct EquationInfo @@ -304,18 +315,20 @@ protected: //! If this node is a temporary term, writes its temporary term representation /*! Returns true if node is a temporary term and has therefore been written to output*/ - bool checkIfTemporaryTermThenWrite(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs) const; + bool checkIfTemporaryTermThenWrite(ostream& output, ExprNodeOutputType output_type, + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs) const; // Same as above, for the bytecode case - bool checkIfTemporaryTermThenWriteBytecode(BytecodeWriter &code_file, - ExprNodeBytecodeOutputType output_type, - const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs) const; + bool + checkIfTemporaryTermThenWriteBytecode(BytecodeWriter& code_file, + ExprNodeBytecodeOutputType output_type, + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs) const; // Internal helper for matchVariableTimesConstantTimesParam() - virtual void matchVTCTPHelper(optional &var_id, int &lag, optional ¶m_id, double &constant, bool at_denominator) const; + virtual void matchVTCTPHelper(optional& var_id, int& lag, optional& param_id, + double& constant, bool at_denominator) const; /* Computes the representative element and the index under the lag-equivalence relationship. See the comment above @@ -328,18 +341,21 @@ protected: - diff(expr) will be added to the output set if either expr or expr(-1) contains the variable; - the method will be called recursively on expr-expr(-1) */ - virtual void computeSubExprContainingVariable(int symb_id, int lag, set &contain_var) const = 0; + virtual void computeSubExprContainingVariable(int symb_id, int lag, + set& contain_var) const + = 0; public: - ExprNode(DataTree &datatree_arg, int idx_arg); + ExprNode(DataTree& datatree_arg, int idx_arg); virtual ~ExprNode() = default; - ExprNode(const ExprNode &) = delete; - ExprNode &operator=(const ExprNode &) = delete; + ExprNode(const ExprNode&) = delete; + ExprNode& operator=(const ExprNode&) = delete; //! Returns derivative w.r. to derivation ID - /*! Uses a symbolic a priori to pre-detect null derivatives, and caches the result for other derivatives (to avoid computing it several times) - For an equal node, returns the derivative of lhs minus rhs */ + /*! Uses a symbolic a priori to pre-detect null derivatives, and caches the result for other + derivatives (to avoid computing it several times) For an equal node, returns the derivative of + lhs minus rhs */ expr_t getDerivative(int deriv_id); /* Computes derivatives by applying the chain rule for some variables. @@ -359,11 +375,14 @@ public: NB 3: the use of std::unordered_map instead of std::map for caching purposes improves performance on very very large models (tens of thousands of equations) */ - expr_t getChainRuleDerivative(int deriv_id, const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives, unordered_map> &cache); + expr_t getChainRuleDerivative(int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache); //! Returns precedence of node /*! Equals 100 for constants, variables, unary ops, and temporary terms */ - virtual int precedence(ExprNodeOutputType output_t, const temporary_terms_t &temporary_terms) const; + virtual int precedence(ExprNodeOutputType output_t, + const temporary_terms_t& temporary_terms) const; //! Compute temporary terms in this expression /*! @@ -384,10 +403,9 @@ public: NB: the use of std::unordered_map instead of std::map for caching purposes improves performance on very large models (⩾5000 equations) */ - virtual void computeTemporaryTerms(const pair &derivOrder, - map, unordered_set> &temp_terms_map, - unordered_map>> &reference_count, - bool is_matlab) const; + virtual void computeTemporaryTerms( + const pair& derivOrder, map, unordered_set>& temp_terms_map, + unordered_map>>& reference_count, bool is_matlab) const; //! Compute temporary terms in this expression for block decomposed model /*! @@ -405,11 +423,13 @@ public: NB: the use of std::unordered_{set,map} instead of std::{set,map} for caching and output improves performance on very large models (⩾5000 equations) */ - virtual void computeBlockTemporaryTerms(int blk, int eq, - vector>> &blocks_temporary_terms, - unordered_map> &reference_count) const; + virtual void + computeBlockTemporaryTerms(int blk, int eq, + vector>>& blocks_temporary_terms, + unordered_map>& reference_count) const; - //! Writes output of node, using a Txxx notation for nodes in temporary_terms, and specifiying the set of already written external functions + //! Writes output of node, using a Txxx notation for nodes in temporary_terms, and specifiying the + //! set of already written external functions /*! \param[in] output the output stream \param[in] output_type the type of output (MATLAB, C, LaTeX...) @@ -419,73 +439,84 @@ public: when writing MATLAB with block decomposition) \param[in] tef_terms the set of already written external function nodes */ - virtual void writeOutput(ostream &output, ExprNodeOutputType 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 = 0; + virtual void writeOutput(ostream& output, ExprNodeOutputType 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 + = 0; //! returns true if the expr node contains an external function virtual bool containsExternalFunction() const = 0; //! Writes output of node (with no temporary terms and with "outside model" output type) - void writeOutput(ostream &output) const; + void writeOutput(ostream& output) const; //! Writes output of node (with no temporary terms) - void writeOutput(ostream &output, ExprNodeOutputType output_type) const; + void writeOutput(ostream& output, ExprNodeOutputType output_type) const; //! Writes output of node, using a Txxx notation for nodes in temporary_terms - void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs) const; + void writeOutput(ostream& output, ExprNodeOutputType output_type, + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs) const; //! Writes output of node in JSON syntax - virtual void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic = true) const = 0; + virtual void writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms, + const deriv_node_temp_terms_t& tef_terms, + bool isdynamic = true) const + = 0; // Returns a string representation of the expression, used by the GDB pretty printer string toString() const; //! Writes the Abstract Syntax Tree in JSON - virtual void writeJsonAST(ostream &output) const = 0; + virtual void writeJsonAST(ostream& output) const = 0; - virtual int precedenceJson(const temporary_terms_t &temporary_terms) const; + virtual int precedenceJson(const temporary_terms_t& temporary_terms) const; - //! Writes the output for an external function, ensuring that the external function is called as few times as possible using temporary terms - virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, - deriv_node_temp_terms_t &tef_terms) const; + //! Writes the output for an external function, ensuring that the external function is called as + //! few times as possible using temporary terms + virtual void writeExternalFunctionOutput(ostream& output, ExprNodeOutputType output_type, + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + deriv_node_temp_terms_t& tef_terms) const; //! Write the JSON output of an external function in a string vector //! Allows the insertion of commas if necessary - virtual void writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, + virtual void writeJsonExternalFunctionOutput(vector& efout, + const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, bool isdynamic = true) const; - virtual void writeBytecodeExternalFunctionOutput(BytecodeWriter &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; + virtual void writeBytecodeExternalFunctionOutput( + BytecodeWriter& 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; - //! Computes the set of all variables of a given symbol type in the expression (with information on lags) + //! Computes the set of all variables of a given symbol type in the expression (with information + //! on lags) /*! Variables are stored as integer pairs of the form (symb_id, lag). They are added to the set given in argument. Note that model local variables are substituted by their expression in the computation (and added if type_arg = ModelLocalVariable). */ - virtual void collectDynamicVariables(SymbolType type_arg, set> &result) const = 0; + virtual void collectDynamicVariables(SymbolType type_arg, set>& result) const = 0; //! Find the maximum lag in a VAR: handles case where LHS is diff - virtual int VarMaxLag(const set &lhs_lag_equiv) const = 0; + virtual int VarMaxLag(const set& lhs_lag_equiv) const = 0; //! Finds LHS variable in a VAR equation - virtual void collectVARLHSVariable(set &result) const = 0; + virtual void collectVARLHSVariable(set& result) const = 0; - //! Computes the set of all variables of a given symbol type in the expression (without information on lags) + //! Computes the set of all variables of a given symbol type in the expression (without + //! information on lags) /*! Variables are stored as symb_id. They are added to the set given in argument. Note that model local variables are substituted by their expression in the computation (and added if type_arg = ModelLocalVariable). */ - void collectVariables(SymbolType type_arg, set &result) const; + void collectVariables(SymbolType type_arg, set& result) const; //! Computes the set of endogenous variables in the expression /*! @@ -493,7 +524,7 @@ public: They are added to the set given in argument. Note that model local variables are substituted by their expression in the computation. */ - void collectEndogenous(set> &result) const; + void collectEndogenous(set>& result) const; class EvalException { @@ -503,23 +534,30 @@ public: { }; - virtual double eval(const eval_context_t &eval_context) const noexcept(false) = 0; + virtual double eval(const eval_context_t& eval_context) const noexcept(false) = 0; // Write output to bytecode file - virtual void writeBytecodeOutput(BytecodeWriter &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 = 0; + virtual void writeBytecodeOutput(BytecodeWriter& 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 + = 0; //! Creates a static version of this node /*! - This method duplicates the current node by creating a similar node from which all leads/lags have been stripped, - adds the result in the static_datatree argument (and not in the original datatree), and returns it. + This method duplicates the current node by creating a similar node from which all leads/lags + have been stripped, adds the result in the static_datatree argument (and not in the original + datatree), and returns it. */ - virtual expr_t toStatic(DataTree &static_datatree) const = 0; + virtual expr_t toStatic(DataTree& static_datatree) const = 0; /*! Compute cross references for equations */ - // virtual void computeXrefs(set ¶m, set &endo, set &exo, set &exo_det) const = 0; - virtual void computeXrefs(EquationInfo &ei) const = 0; + // virtual void computeXrefs(set ¶m, set &endo, set &exo, set &exo_det) + // const = 0; + virtual void computeXrefs(EquationInfo& ei) const = 0; //! Helper for normalization of equations /*! Normalize the equation this = rhs. @@ -527,8 +565,11 @@ public: Returns an equal node of the form: LHS variable = new RHS. Must be given the set of all subexpressions that contain the desired LHS variable. Throws a NormallizationFailed() exception if normalization is not possible. */ - virtual BinaryOpNode *normalizeEquationHelper(const set &contain_var, expr_t rhs) const = 0; - class NormalizationFailed {}; + virtual BinaryOpNode* normalizeEquationHelper(const set& contain_var, expr_t rhs) const + = 0; + class NormalizationFailed + { + }; //! Returns the maximum lead of endogenous in this expression /*! Always returns a non-negative value */ @@ -566,7 +607,8 @@ public: virtual expr_t undiff() const = 0; - //! Returns a new expression where all the leads/lags have been shifted backwards by the same amount + //! Returns a new expression where all the leads/lags have been shifted backwards by the same + //! amount /*! Only acts on endogenous, exogenous, exogenous det \param[in] n The number of lags by which to shift @@ -575,83 +617,119 @@ public: virtual expr_t decreaseLeadsLags(int n) const = 0; //! Type for the substitution map used in the process of creating auxiliary vars - using subst_table_t = map; + using subst_table_t = map; //! Type for the substitution map used in the process of substituting adl expressions - using subst_table_adl_t = map; + using subst_table_adl_t = map; //! Creates auxiliary endo lead variables corresponding to this expression /*! - If maximum endogenous lead >= 3, this method will also create intermediary auxiliary var, and will add the equations of the form aux1 = aux2(+1) to the substitution table. - \pre This expression is assumed to have maximum endogenous lead >= 2 - \param[in,out] subst_table The table to which new auxiliary variables and their correspondance will be added - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. - \return The new variable node corresponding to the current expression + If maximum endogenous lead >= 3, this method will also create intermediary auxiliary var, and + will add the equations of the form aux1 = aux2(+1) to the substitution table. \pre This + expression is assumed to have maximum endogenous lead >= 2 \param[in,out] subst_table The table + to which new auxiliary variables and their correspondance will be added \param[out] neweqs + Equations to be added to the model to match the creation of auxiliary variables. \return The new + variable node corresponding to the current expression */ - VariableNode *createEndoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector &neweqs) const; + VariableNode* createEndoLeadAuxiliaryVarForMyself(subst_table_t& subst_table, + vector& neweqs) const; //! Creates auxiliary exo lead variables corresponding to this expression /*! - If maximum exogenous lead >= 2, this method will also create intermediary auxiliary var, and will add the equations of the form aux1 = aux2(+1) to the substitution table. - \pre This expression is assumed to have maximum exogenous lead >= 1 - \param[in,out] subst_table The table to which new auxiliary variables and their correspondance will be added - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. - \return The new variable node corresponding to the current expression + If maximum exogenous lead >= 2, this method will also create intermediary auxiliary var, and + will add the equations of the form aux1 = aux2(+1) to the substitution table. \pre This + expression is assumed to have maximum exogenous lead >= 1 \param[in,out] subst_table The table + to which new auxiliary variables and their correspondance will be added \param[out] neweqs + Equations to be added to the model to match the creation of auxiliary variables. \return The new + variable node corresponding to the current expression */ - VariableNode *createExoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector &neweqs) const; + VariableNode* createExoLeadAuxiliaryVarForMyself(subst_table_t& subst_table, + vector& neweqs) const; - //! Constructs a new expression where sub-expressions with max endo lead >= 2 have been replaced by auxiliary variables + //! Constructs a new expression where sub-expressions with max endo lead >= 2 have been replaced + //! by auxiliary variables /*! - \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr. - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. + \param[in,out] subst_table Map used to store expressions that have already be substituted and + their corresponding variable, in order to avoid creating two auxiliary variables for the same + sub-expr. \param[out] neweqs Equations to be added to the model to match the creation of + auxiliary variables. If the method detects a sub-expr which needs to be substituted, two cases are possible: - - if this expr is in the table, then it will use the corresponding variable and return the substituted expression - - if this expr is not in the table, then it will create an auxiliary endogenous variable, add the substitution in the table and return the substituted expression + - if this expr is in the table, then it will use the corresponding variable and return the + substituted expression + - if this expr is not in the table, then it will create an auxiliary endogenous variable, add + the substitution in the table and return the substituted expression - \return A new equivalent expression where sub-expressions with max endo lead >= 2 have been replaced by auxiliary variables + \return A new equivalent expression where sub-expressions with max endo lead >= 2 have been + replaced by auxiliary variables */ - virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const = 0; + virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs, + bool deterministic_model) const + = 0; - //! Constructs a new expression where endo variables with max endo lag >= 2 have been replaced by auxiliary variables + //! Constructs a new expression where endo variables with max endo lag >= 2 have been replaced by + //! auxiliary variables /*! - \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr. - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. + \param[in,out] subst_table Map used to store expressions that have already be substituted and + their corresponding variable, in order to avoid creating two auxiliary variables for the same + sub-expr. \param[out] neweqs Equations to be added to the model to match the creation of + auxiliary variables. */ - virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const = 0; + virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs) const + = 0; - //! Constructs a new expression where exogenous variables with a lead have been replaced by auxiliary variables + //! Constructs a new expression where exogenous variables with a lead have been replaced by + //! auxiliary variables /*! - \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr. - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. + \param[in,out] subst_table Map used to store expressions that have already be substituted and + their corresponding variable, in order to avoid creating two auxiliary variables for the same + sub-expr. \param[out] neweqs Equations to be added to the model to match the creation of + auxiliary variables. */ - virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const = 0; - //! Constructs a new expression where exogenous variables with a lag have been replaced by auxiliary variables + virtual expr_t substituteExoLead(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const + = 0; + //! Constructs a new expression where exogenous variables with a lag have been replaced by + //! auxiliary variables /*! - \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr. - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. + \param[in,out] subst_table Map used to store expressions that have already be substituted and + their corresponding variable, in order to avoid creating two auxiliary variables for the same + sub-expr. \param[out] neweqs Equations to be added to the model to match the creation of + auxiliary variables. */ - virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const = 0; + virtual expr_t substituteExoLag(subst_table_t& subst_table, vector& neweqs) const + = 0; - //! Constructs a new expression where the expectation operator has been replaced by auxiliary variables + //! Constructs a new expression where the expectation operator has been replaced by auxiliary + //! variables /*! - \param[in,out] subst_table Map used to store expressions that have already be substituted and their corresponding variable, in order to avoid creating two auxiliary variables for the same sub-expr. - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. - \param[in] partial_information_model Are we substituting in a partial information model? + \param[in,out] subst_table Map used to store expressions that have already be substituted and + their corresponding variable, in order to avoid creating two auxiliary variables for the same + sub-expr. \param[out] neweqs Equations to be added to the model to match the creation of + auxiliary variables. \param[in] partial_information_model Are we substituting in a partial + information model? */ - virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const = 0; + virtual expr_t substituteExpectation(subst_table_t& subst_table, vector& neweqs, + bool partial_information_model) const + = 0; virtual expr_t decreaseLeadsLagsPredeterminedVariables() const = 0; - //! Constructs a new expression where forward variables (supposed to be at most in t+1) have been replaced by themselves at t, plus a new aux var representing their (time) differentiate + //! Constructs a new expression where forward variables (supposed to be at most in t+1) have been + //! replaced by themselves at t, plus a new aux var representing their (time) differentiate /*! \param[in] subset variables to which to limit the transformation; transform all fwrd vars if empty \param[in,out] subst_table Map used to store mapping between a given forward variable and the aux var that contains its differentiate - \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables. + \param[out] neweqs Equations to be added to the model to match the creation of auxiliary + variables. */ - virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const = 0; + virtual expr_t differentiateForwardVars(const vector& subset, subst_table_t& subst_table, + vector& neweqs) const + = 0; //! Return true if the nodeID is a numerical constant equal to value and false otherwise /*! @@ -663,7 +741,8 @@ public: //! Returns the maximum number of nested diffs in the expression virtual int countDiffs() const = 0; - //! Return true if the nodeID is a variable withe a type equal to type_arg, a specific variable id aqual to varfiable_id and a lag equal to lag_arg and false otherwise + //! Return true if the nodeID is a variable withe a type equal to type_arg, a specific variable id + //! aqual to varfiable_id and a lag equal to lag_arg and false otherwise /*! \param[in] the type (type_arg), specifique variable id (variable_id and the lag (lag_arg) \param[out] the boolean equal to true if NodeId is the variable @@ -689,42 +768,49 @@ public: virtual expr_t substituteModelLocalVariables() const = 0; //! Substitute VarExpectation nodes - virtual expr_t substituteVarExpectation(const map &subst_table) const = 0; + virtual expr_t substituteVarExpectation(const map& subst_table) const = 0; //! Mark diff nodes to be substituted /*! The various nodes that are equivalent up to a shift of leads/lags are grouped together in the “nodes” table. See the comment above lag_equivalence_table_t for more details. */ - virtual void findDiffNodes(lag_equivalence_table_t &nodes) const = 0; + virtual void findDiffNodes(lag_equivalence_table_t& nodes) const = 0; //! Substitute diff operator - virtual expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const = 0; + virtual expr_t substituteDiff(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const + = 0; //! Mark unary ops nodes to be substituted /*! The various nodes that are equivalent up to a shift of leads/lags are grouped together in the “nodes” table. See the comment above lag_equivalence_table_t for more details. */ - virtual void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const = 0; + virtual void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t& nodes) const = 0; //! Substitute unary ops nodes - virtual expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const = 0; + virtual expr_t substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, + subst_table_t& subst_table, + vector& neweqs) const + = 0; //! Substitute pac_expectation operator - virtual expr_t substitutePacExpectation(const string &name, expr_t subexpr) = 0; + virtual expr_t substitutePacExpectation(const string& name, expr_t subexpr) = 0; //! Substitute pac_target_nonstationary operator - virtual expr_t substitutePacTargetNonstationary(const string &name, expr_t subexpr) = 0; + virtual expr_t substitutePacTargetNonstationary(const string& name, expr_t subexpr) = 0; virtual optional findTargetVariable(int lhs_symb_id) const = 0; //! Add ExprNodes to the provided datatree - virtual expr_t clone(DataTree &alt_datatree) const = 0; + virtual expr_t clone(DataTree& alt_datatree) const = 0; //! Move a trend variable with lag/lead to time t by dividing/multiplying by its growth factor - virtual expr_t removeTrendLeadLag(const map &trend_symbols_map) const = 0; + virtual expr_t removeTrendLeadLag(const map& trend_symbols_map) const = 0; - //! Returns true if the expression is in static form (no lead, no lag, no expectation, no STEADY_STATE) + //! Returns true if the expression is in static form (no lead, no lag, no expectation, no + //! STEADY_STATE) virtual bool isInStaticForm() const = 0; - //! Matches a linear combination of variables (endo or exo), where scalars can be constant*parameter + //! Matches a linear combination of variables (endo or exo), where scalars can be + //! constant*parameter /*! Returns a list of (variable_id, lag, param_id, constant) corresponding to the terms in the expression. When there is no parameter in a term, param_id is nullopt. @@ -741,14 +827,16 @@ public: no variable), then variable_id is nullopt. Can throw a MatchFailureException. */ - vector, int, optional, double>> matchLinearCombinationOfVariablesPlusConstant() const; + vector, int, optional, double>> + matchLinearCombinationOfVariablesPlusConstant() const; /* Matches a parameter, times a linear combination of variables (endo or exo), where scalars can be constant*parameters. The first output argument is the symbol ID of the parameter. The second output argument is the linear combination, in the same format as the output of matchLinearCombinationOfVariables(). */ - pair, double>>> matchParamTimesLinearCombinationOfVariables() const; + pair, double>>> + matchParamTimesLinearCombinationOfVariables() const; /* Matches a linear combination of endogenous, where scalars can be any constant expression (i.e. containing no endogenous, no exogenous and no @@ -772,32 +860,33 @@ public: virtual bool isParamTimesEndogExpr() const = 0; //! Fills the EC matrix structure - void fillErrorCorrectionRow(int eqn, const vector &nontarget_lhs, const vector &target_lhs, - map, expr_t> &A0, - map, expr_t> &A0star) const; + void fillErrorCorrectionRow(int eqn, const vector& nontarget_lhs, + const vector& target_lhs, map, expr_t>& A0, + map, expr_t>& A0star) const; //! Replaces variables found in BinaryOpNode::findConstantEquations() with their constant values - virtual expr_t replaceVarsInEquation(map &table) const = 0; + virtual expr_t replaceVarsInEquation(map& table) const = 0; //! Returns true if PacExpectationNode encountered - virtual bool containsPacExpectation(const string &pac_model_name = "") const = 0; + virtual bool containsPacExpectation(const string& pac_model_name = "") const = 0; //! Returns true if PacTargetNonstationaryNode encountered - virtual bool containsPacTargetNonstationary(const string &pac_model_name = "") const = 0; + virtual bool containsPacTargetNonstationary(const string& pac_model_name = "") const = 0; //! Decompose an expression into its additive terms /*! Returns a list of terms, with their sign (either 1 or -1, depending on whether the terms appears with a plus or a minus). The current_sign argument should normally be left to 1. If current_sign == -1, then all signs are inverted */ - virtual void decomposeAdditiveTerms(vector> &terms, int current_sign = 1) const; + virtual void decomposeAdditiveTerms(vector>& terms, int current_sign = 1) const; //! Decompose an expression into its multiplicative factors /*! Returns a list of factors, with their exponents (either 1 or -1, depending on whether the factors appear at the numerator or the denominator). The current_exponent argument should normally be left to 1. If current_exponent == -1, then all exponents are inverted */ - virtual void decomposeMultiplicativeFactors(vector> &factors, int current_exponent = 1) const; + virtual void decomposeMultiplicativeFactors(vector>& factors, + int current_exponent = 1) const; // Matches an expression of the form variable*constant*parameter /* Returns a tuple (variable_id, lag, param_id, constant). @@ -811,7 +900,8 @@ public: If the expression is not of the expected form, throws a MatchFailureException */ - tuple, int, optional, double> matchVariableTimesConstantTimesParam(bool variable_obligatory) const; + tuple, int, optional, double> + matchVariableTimesConstantTimesParam(bool variable_obligatory) const; /* Matches an expression of the form endogenous*constant where constant is an expression containing no endogenous, no exogenous and no exogenous deterministic. @@ -831,7 +921,8 @@ public: For each factor, adds an integer in the 3 vectors in argument (symb_id in the first, lag in the second, exponent in the third). Throws a MatchFailureException if not of the right form. */ - virtual void matchMatchedMoment(vector &symb_ids, vector &lags, vector &powers) const; + virtual void matchMatchedMoment(vector& symb_ids, vector& lags, + vector& powers) const; /* Returns true if the expression contains no endogenous, no exogenous and no exogenous deterministic */ @@ -858,33 +949,51 @@ struct ExprNodeLess }; //! Numerical constant node -/*! The constant is necessarily non-negative (this is enforced at the NumericalConstants class level) */ +/*! The constant is necessarily non-negative (this is enforced at the NumericalConstants class + * level) */ class NumConstNode : public ExprNode { public: //! Id from numerical constants table const int id; + private: expr_t computeDerivative(int deriv_id) override; - expr_t computeChainRuleDerivative(int deriv_id, const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives, unordered_map> &cache) override; + expr_t + computeChainRuleDerivative(int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) override; + protected: void prepareForDerivation() override; - void prepareForChainRuleDerivation(const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives) const override; - void matchVTCTPHelper(optional &var_id, int &lag, optional ¶m_id, double &constant, bool at_denominator) const override; - void computeSubExprContainingVariable(int symb_id, int lag, set &contain_var) const override; + void prepareForChainRuleDerivation( + const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const override; + void matchVTCTPHelper(optional& var_id, int& lag, optional& param_id, double& constant, + bool at_denominator) const override; + void computeSubExprContainingVariable(int symb_id, int lag, + set& contain_var) const override; + public: - NumConstNode(DataTree &datatree_arg, int idx_arg, int id_arg); - void writeOutput(ostream &output, ExprNodeOutputType 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; - 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; + NumConstNode(DataTree& datatree_arg, int idx_arg, int id_arg); + void writeOutput(ostream& output, ExprNodeOutputType 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; + 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; bool containsExternalFunction() const override; - void collectVARLHSVariable(set &result) const override; - void collectDynamicVariables(SymbolType type_arg, set> &result) const override; - double eval(const eval_context_t &eval_context) const noexcept(false) override; - void writeBytecodeOutput(BytecodeWriter &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; - expr_t toStatic(DataTree &static_datatree) const override; - void computeXrefs(EquationInfo &ei) const override; - BinaryOpNode *normalizeEquationHelper(const set &contain_var, expr_t rhs) const override; + void collectVARLHSVariable(set& result) const override; + void collectDynamicVariables(SymbolType type_arg, set>& result) const override; + double eval(const eval_context_t& eval_context) const noexcept(false) override; + void writeBytecodeOutput(BytecodeWriter& 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; + expr_t toStatic(DataTree& static_datatree) const override; + void computeXrefs(EquationInfo& ei) const override; + BinaryOpNode* normalizeEquationHelper(const set& contain_var, expr_t rhs) const override; int maxEndoLead() const override; int maxExoLead() const override; int maxEndoLag() const override; @@ -892,37 +1001,44 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMaxLag(const set &lhs_lag_equiv) const override; + int VarMaxLag(const set& lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; - expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const override; + expr_t substituteEndoLeadGreaterThanTwo(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + expr_t substituteEndoLagGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteExoLead(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + expr_t substituteExoLag(subst_table_t& subst_table, vector& neweqs) const override; + expr_t substituteExpectation(subst_table_t& subst_table, vector& neweqs, + bool partial_information_model) const override; expr_t substituteAdl() const override; expr_t substituteModelLocalVariables() const override; - expr_t substituteVarExpectation(const map &subst_table) const override; - void findDiffNodes(lag_equivalence_table_t &nodes) const override; - void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override; + expr_t substituteVarExpectation(const map& subst_table) const override; + void findDiffNodes(lag_equivalence_table_t& nodes) const override; + void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t& nodes) const override; optional findTargetVariable(int lhs_symb_id) const override; - expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - expr_t substitutePacExpectation(const string &name, expr_t subexpr) override; - expr_t substitutePacTargetNonstationary(const string &name, expr_t subexpr) override; + expr_t substituteDiff(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substitutePacExpectation(const string& name, expr_t subexpr) override; + expr_t substitutePacTargetNonstationary(const string& name, expr_t subexpr) override; expr_t decreaseLeadsLagsPredeterminedVariables() const override; - expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const override; + expr_t differentiateForwardVars(const vector& subset, subst_table_t& subst_table, + vector& neweqs) const override; bool isNumConstNodeEqualTo(double value) const override; int countDiffs() const override; bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override; expr_t replaceTrendVar() const override; expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override; - expr_t clone(DataTree &alt_datatree) const override; - expr_t removeTrendLeadLag(const map &trend_symbols_map) const override; + expr_t clone(DataTree& alt_datatree) const override; + expr_t removeTrendLeadLag(const map& trend_symbols_map) const override; bool isInStaticForm() const override; - expr_t replaceVarsInEquation(map &table) const override; - bool containsPacExpectation(const string &pac_model_name = "") const override; - bool containsPacTargetNonstationary(const string &pac_model_name = "") const override; + expr_t replaceVarsInEquation(map& table) const override; + bool containsPacExpectation(const string& pac_model_name = "") const override; + bool containsPacTargetNonstationary(const string& pac_model_name = "") const override; bool isParamTimesEndogExpr() const override; expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override; }; @@ -931,33 +1047,51 @@ public: class VariableNode : public ExprNode { friend class UnaryOpNode; + public: //! Id from the symbol table const int symb_id; //! A positive value is a lead, a negative is a lag const int lag; + private: expr_t computeDerivative(int deriv_id) override; - expr_t computeChainRuleDerivative(int deriv_id, const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives, unordered_map> &cache) override; + expr_t + computeChainRuleDerivative(int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) override; + protected: void prepareForDerivation() override; - void prepareForChainRuleDerivation(const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives) const override; - void matchVTCTPHelper(optional &var_id, int &lag, optional ¶m_id, double &constant, bool at_denominator) const override; - void computeSubExprContainingVariable(int symb_id, int lag, set &contain_var) const override; + void prepareForChainRuleDerivation( + const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const override; + void matchVTCTPHelper(optional& var_id, int& lag, optional& param_id, double& constant, + bool at_denominator) const override; + void computeSubExprContainingVariable(int symb_id, int lag, + set& contain_var) const override; + public: - VariableNode(DataTree &datatree_arg, int idx_arg, int symb_id_arg, int lag_arg); - void writeOutput(ostream &output, ExprNodeOutputType 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; - 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; + VariableNode(DataTree& datatree_arg, int idx_arg, int symb_id_arg, int lag_arg); + void writeOutput(ostream& output, ExprNodeOutputType 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; + 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; bool containsExternalFunction() const override; - void collectVARLHSVariable(set &result) const override; - void collectDynamicVariables(SymbolType type_arg, set> &result) const override; - double eval(const eval_context_t &eval_context) const noexcept(false) override; - void writeBytecodeOutput(BytecodeWriter &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; - expr_t toStatic(DataTree &static_datatree) const override; - void computeXrefs(EquationInfo &ei) const override; + void collectVARLHSVariable(set& result) const override; + void collectDynamicVariables(SymbolType type_arg, set>& result) const override; + double eval(const eval_context_t& eval_context) const noexcept(false) override; + void writeBytecodeOutput(BytecodeWriter& 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; + expr_t toStatic(DataTree& static_datatree) const override; + void computeXrefs(EquationInfo& ei) const override; SymbolType get_type() const; - BinaryOpNode *normalizeEquationHelper(const set &contain_var, expr_t rhs) const override; + BinaryOpNode* normalizeEquationHelper(const set& contain_var, expr_t rhs) const override; int maxEndoLead() const override; int maxExoLead() const override; int maxEndoLag() const override; @@ -965,39 +1099,47 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMaxLag(const set &lhs_lag_equiv) const override; + int VarMaxLag(const set& lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; - expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const override; + expr_t substituteEndoLeadGreaterThanTwo(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + expr_t substituteEndoLagGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteExoLead(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + expr_t substituteExoLag(subst_table_t& subst_table, vector& neweqs) const override; + expr_t substituteExpectation(subst_table_t& subst_table, vector& neweqs, + bool partial_information_model) const override; expr_t substituteAdl() const override; expr_t substituteModelLocalVariables() const override; - expr_t substituteVarExpectation(const map &subst_table) const override; - void findDiffNodes(lag_equivalence_table_t &nodes) const override; - void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override; + expr_t substituteVarExpectation(const map& subst_table) const override; + void findDiffNodes(lag_equivalence_table_t& nodes) const override; + void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t& nodes) const override; optional findTargetVariable(int lhs_symb_id) const override; - expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - expr_t substitutePacExpectation(const string &name, expr_t subexpr) override; - expr_t substitutePacTargetNonstationary(const string &name, expr_t subexpr) override; + expr_t substituteDiff(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substitutePacExpectation(const string& name, expr_t subexpr) override; + expr_t substitutePacTargetNonstationary(const string& name, expr_t subexpr) override; expr_t decreaseLeadsLagsPredeterminedVariables() const override; - expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const override; + expr_t differentiateForwardVars(const vector& subset, subst_table_t& subst_table, + vector& neweqs) const override; bool isNumConstNodeEqualTo(double value) const override; int countDiffs() const override; bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override; expr_t replaceTrendVar() const override; expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override; - expr_t clone(DataTree &alt_datatree) const override; - expr_t removeTrendLeadLag(const map &trend_symbols_map) const override; + expr_t clone(DataTree& alt_datatree) const override; + expr_t removeTrendLeadLag(const map& trend_symbols_map) const override; bool isInStaticForm() const override; - expr_t replaceVarsInEquation(map &table) const override; - bool containsPacExpectation(const string &pac_model_name = "") const override; - bool containsPacTargetNonstationary(const string &pac_model_name = "") const override; + expr_t replaceVarsInEquation(map& table) const override; + bool containsPacExpectation(const string& pac_model_name = "") const override; + bool containsPacTargetNonstationary(const string& pac_model_name = "") const override; bool isParamTimesEndogExpr() const override; - void matchMatchedMoment(vector &symb_ids, vector &lags, vector &powers) const override; + void matchMatchedMoment(vector& symb_ids, vector& lags, + vector& powers) const override; pair matchEndogenousTimesConstant() const override; expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override; }; @@ -1007,17 +1149,23 @@ class UnaryOpNode : public ExprNode { protected: void prepareForDerivation() override; - void prepareForChainRuleDerivation(const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives) const override; - void matchVTCTPHelper(optional &var_id, int &lag, optional ¶m_id, double &constant, bool at_denominator) const override; - void computeSubExprContainingVariable(int symb_id, int lag, set &contain_var) const override; - // Returns the node obtained by applying a transformation recursively on the argument (in same datatree) + void prepareForChainRuleDerivation( + const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const override; + void matchVTCTPHelper(optional& var_id, int& lag, optional& param_id, double& constant, + bool at_denominator) const override; + void computeSubExprContainingVariable(int symb_id, int lag, + set& contain_var) const override; + // Returns the node obtained by applying a transformation recursively on the argument (in same + // datatree) template expr_t recurseTransform(Callable&& op, Args&&... args) const { - expr_t substarg { invoke(forward(op), arg, forward(args)...) }; + expr_t substarg {invoke(forward(op), arg, forward(args)...)}; return buildSimilarUnaryOpNode(substarg, datatree); } + public: const expr_t arg; //! Stores the information set. Only used for expectation operator @@ -1027,47 +1175,64 @@ public: const UnaryOpcode op_code; const string adl_param_name; const vector adl_lags; + private: expr_t computeDerivative(int deriv_id) override; - expr_t computeChainRuleDerivative(int deriv_id, const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives, unordered_map> &cache) override; + expr_t + computeChainRuleDerivative(int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) override; int cost(int cost, bool is_matlab) const override; - int cost(const vector>> &blocks_temporary_terms, bool is_matlab) const override; - int cost(const map, unordered_set> &temp_terms_map, bool is_matlab) const override; + int cost(const vector>>& blocks_temporary_terms, + bool is_matlab) const override; + int cost(const map, unordered_set>& temp_terms_map, + bool is_matlab) const override; //! Returns the derivative of this node if darg is the derivative of the argument expr_t composeDerivatives(expr_t darg, int deriv_id); + public: - UnaryOpNode(DataTree &datatree_arg, int idx_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, string adl_param_name_arg, vector adl_lags_arg); - void computeTemporaryTerms(const pair &derivOrder, - map, unordered_set> &temp_terms_map, - unordered_map>> &reference_count, + UnaryOpNode(DataTree& datatree_arg, int idx_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, + int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, + string adl_param_name_arg, vector adl_lags_arg); + void computeTemporaryTerms(const pair& derivOrder, + map, unordered_set>& temp_terms_map, + unordered_map>>& reference_count, bool is_matlab) const override; - void computeBlockTemporaryTerms(int blk, int eq, vector>> &blocks_temporary_terms, - unordered_map> &reference_count) const override; - void writeOutput(ostream &output, ExprNodeOutputType 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; - 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 computeBlockTemporaryTerms( + int blk, int eq, vector>>& blocks_temporary_terms, + unordered_map>& reference_count) const override; + void writeOutput(ostream& output, ExprNodeOutputType 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; + 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; bool containsExternalFunction() const override; - void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType 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 writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, + void writeExternalFunctionOutput(ostream& output, ExprNodeOutputType 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 writeJsonExternalFunctionOutput(vector& efout, + const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, bool isdynamic) const override; - void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, + void writeBytecodeExternalFunctionOutput(BytecodeWriter& 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 collectVARLHSVariable(set &result) const override; - void collectDynamicVariables(SymbolType type_arg, set> &result) const override; + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + deriv_node_temp_terms_t& tef_terms) const override; + void collectVARLHSVariable(set& result) const override; + void collectDynamicVariables(SymbolType type_arg, set>& result) const override; static double eval_opcode(UnaryOpcode op_code, double v) noexcept(false); - double eval(const eval_context_t &eval_context) const noexcept(false) override; - void writeBytecodeOutput(BytecodeWriter &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; - expr_t toStatic(DataTree &static_datatree) const override; - void computeXrefs(EquationInfo &ei) const override; - BinaryOpNode *normalizeEquationHelper(const set &contain_var, expr_t rhs) const override; + double eval(const eval_context_t& eval_context) const noexcept(false) override; + void writeBytecodeOutput(BytecodeWriter& 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; + expr_t toStatic(DataTree& static_datatree) const override; + void computeXrefs(EquationInfo& ei) const override; + BinaryOpNode* normalizeEquationHelper(const set& contain_var, expr_t rhs) const override; int maxEndoLead() const override; int maxExoLead() const override; int maxEndoLag() const override; @@ -1075,42 +1240,50 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMaxLag(const set &lhs_lag_equiv) const override; + int VarMaxLag(const set& lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; - expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - //! Creates another UnaryOpNode with the same opcode, but with a possibly different datatree and argument - expr_t buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) const; - expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const override; + expr_t substituteEndoLeadGreaterThanTwo(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + //! Creates another UnaryOpNode with the same opcode, but with a possibly different datatree and + //! argument + expr_t buildSimilarUnaryOpNode(expr_t alt_arg, DataTree& alt_datatree) const; + expr_t substituteEndoLagGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteExoLead(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + expr_t substituteExoLag(subst_table_t& subst_table, vector& neweqs) const override; + expr_t substituteExpectation(subst_table_t& subst_table, vector& neweqs, + bool partial_information_model) const override; expr_t substituteAdl() const override; expr_t substituteModelLocalVariables() const override; - expr_t substituteVarExpectation(const map &subst_table) const override; - void findDiffNodes(lag_equivalence_table_t &nodes) const override; + expr_t substituteVarExpectation(const map& subst_table) const override; + void findDiffNodes(lag_equivalence_table_t& nodes) const override; bool createAuxVarForUnaryOpNode() const; - void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override; + void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t& nodes) const override; optional findTargetVariable(int lhs_symb_id) const override; - expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - expr_t substitutePacExpectation(const string &name, expr_t subexpr) override; - expr_t substitutePacTargetNonstationary(const string &name, expr_t subexpr) override; + expr_t substituteDiff(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substitutePacExpectation(const string& name, expr_t subexpr) override; + expr_t substitutePacTargetNonstationary(const string& name, expr_t subexpr) override; expr_t decreaseLeadsLagsPredeterminedVariables() const override; - expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const override; + expr_t differentiateForwardVars(const vector& subset, subst_table_t& subst_table, + vector& neweqs) const override; bool isNumConstNodeEqualTo(double value) const override; int countDiffs() const override; bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override; expr_t replaceTrendVar() const override; expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override; - expr_t clone(DataTree &alt_datatree) const override; - expr_t removeTrendLeadLag(const map &trend_symbols_map) const override; + expr_t clone(DataTree& alt_datatree) const override; + expr_t removeTrendLeadLag(const map& trend_symbols_map) const override; bool isInStaticForm() const override; - expr_t replaceVarsInEquation(map &table) const override; - bool containsPacExpectation(const string &pac_model_name = "") const override; - bool containsPacTargetNonstationary(const string &pac_model_name = "") const override; + expr_t replaceVarsInEquation(map& table) const override; + bool containsPacExpectation(const string& pac_model_name = "") const override; + bool containsPacTargetNonstationary(const string& pac_model_name = "") const override; bool isParamTimesEndogExpr() const override; - void decomposeAdditiveTerms(vector> &terms, int current_sign) const override; + void decomposeAdditiveTerms(vector>& terms, int current_sign) const override; expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override; }; @@ -1119,71 +1292,94 @@ class BinaryOpNode : public ExprNode { protected: void prepareForDerivation() override; - void prepareForChainRuleDerivation(const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives) const override; - void matchVTCTPHelper(optional &var_id, int &lag, optional ¶m_id, double &constant, bool at_denominator) const override; - void computeSubExprContainingVariable(int symb_id, int lag, set &contain_var) const override; + void prepareForChainRuleDerivation( + const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const override; + void matchVTCTPHelper(optional& var_id, int& lag, optional& param_id, double& constant, + bool at_denominator) const override; + void computeSubExprContainingVariable(int symb_id, int lag, + set& contain_var) const override; + public: const expr_t arg1, arg2; const BinaryOpcode op_code; const int powerDerivOrder; const string adlparam; + private: expr_t computeDerivative(int deriv_id) override; - expr_t computeChainRuleDerivative(int deriv_id, const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives, unordered_map> &cache) override; + expr_t + computeChainRuleDerivative(int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) override; int cost(int cost, bool is_matlab) const override; - int cost(const vector>> &blocks_temporary_terms, bool is_matlab) const override; - int cost(const map, unordered_set> &temp_terms_map, bool is_matlab) const override; + int cost(const vector>>& blocks_temporary_terms, + bool is_matlab) const override; + int cost(const map, unordered_set>& temp_terms_map, + bool is_matlab) const override; //! Returns the derivative of this node if darg1 and darg2 are the derivatives of the arguments expr_t composeDerivatives(expr_t darg1, expr_t darg2); - // Returns the node obtained by applying a transformation recursively on the arguments (in same datatree) + // Returns the node obtained by applying a transformation recursively on the arguments (in same + // datatree) template expr_t recurseTransform(Callable&& op, Args&&... args) const { - expr_t substarg1 { invoke(forward(op), arg1, forward(args)...) }; - expr_t substarg2 { invoke(forward(op), arg2, forward(args)...) }; + expr_t substarg1 {invoke(forward(op), arg1, forward(args)...)}; + expr_t substarg2 {invoke(forward(op), arg2, forward(args)...)}; return buildSimilarBinaryOpNode(substarg1, substarg2, datatree); } + public: - BinaryOpNode(DataTree &datatree_arg, int idx_arg, const expr_t arg1_arg, - BinaryOpcode op_code_arg, const expr_t arg2_arg, int powerDerivOrder); - int precedenceJson(const temporary_terms_t &temporary_terms) const override; - int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const override; - void computeTemporaryTerms(const pair &derivOrder, - map, unordered_set> &temp_terms_map, - unordered_map>> &reference_count, + BinaryOpNode(DataTree& datatree_arg, int idx_arg, const expr_t arg1_arg, BinaryOpcode op_code_arg, + const expr_t arg2_arg, int powerDerivOrder); + int precedenceJson(const temporary_terms_t& temporary_terms) const override; + int precedence(ExprNodeOutputType output_type, + const temporary_terms_t& temporary_terms) const override; + void computeTemporaryTerms(const pair& derivOrder, + map, unordered_set>& temp_terms_map, + unordered_map>>& reference_count, bool is_matlab) const override; - void computeBlockTemporaryTerms(int blk, int eq, vector>> &blocks_temporary_terms, - unordered_map> &reference_count) const override; - void writeOutput(ostream &output, ExprNodeOutputType 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; - 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 computeBlockTemporaryTerms( + int blk, int eq, vector>>& blocks_temporary_terms, + unordered_map>& reference_count) const override; + void writeOutput(ostream& output, ExprNodeOutputType 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; + 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; bool containsExternalFunction() const override; - void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType 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 writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, + void writeExternalFunctionOutput(ostream& output, ExprNodeOutputType 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 writeJsonExternalFunctionOutput(vector& efout, + const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, bool isdynamic) const override; - void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, + void writeBytecodeExternalFunctionOutput(BytecodeWriter& 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 collectVARLHSVariable(set &result) const override; - void collectDynamicVariables(SymbolType type_arg, set> &result) const override; - static double eval_opcode(double v1, BinaryOpcode op_code, double v2, int derivOrder) noexcept(false); - double eval(const eval_context_t &eval_context) const noexcept(false) override; - void writeBytecodeOutput(BytecodeWriter &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; + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + deriv_node_temp_terms_t& tef_terms) const override; + void collectVARLHSVariable(set& result) const override; + void collectDynamicVariables(SymbolType type_arg, set>& result) const override; + static double eval_opcode(double v1, BinaryOpcode op_code, double v2, + int derivOrder) noexcept(false); + double eval(const eval_context_t& eval_context) const noexcept(false) override; + void writeBytecodeOutput(BytecodeWriter& 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; expr_t Compute_RHS(expr_t arg1, expr_t arg2, int op, int op_type) const; - expr_t toStatic(DataTree &static_datatree) const override; - void computeXrefs(EquationInfo &ei) const override; - BinaryOpNode *normalizeEquationHelper(const set &contain_var, expr_t rhs) const override; + expr_t toStatic(DataTree& static_datatree) const override; + void computeXrefs(EquationInfo& ei) const override; + BinaryOpNode* normalizeEquationHelper(const set& contain_var, expr_t rhs) const override; //! Try to normalize an equation with respect to a given dynamic variable. /*! Should only be called on Equal nodes. The variable must appear in the equation. */ - BinaryOpNode *normalizeEquation(int symb_id, int lag) const; + BinaryOpNode* normalizeEquation(int symb_id, int lag) const; int maxEndoLead() const override; int maxExoLead() const override; int maxEndoLag() const override; @@ -1191,50 +1387,61 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMaxLag(const set &lhs_lag_equiv) const override; + int VarMaxLag(const set& lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; - expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - //! Creates another BinaryOpNode with the same opcode, but with a possibly different datatree and arguments - expr_t buildSimilarBinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, DataTree &alt_datatree) const; - expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const override; + expr_t substituteEndoLeadGreaterThanTwo(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + //! Creates another BinaryOpNode with the same opcode, but with a possibly different datatree and + //! arguments + expr_t buildSimilarBinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, DataTree& alt_datatree) const; + expr_t substituteEndoLagGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteExoLead(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + expr_t substituteExoLag(subst_table_t& subst_table, vector& neweqs) const override; + expr_t substituteExpectation(subst_table_t& subst_table, vector& neweqs, + bool partial_information_model) const override; expr_t substituteAdl() const override; expr_t substituteModelLocalVariables() const override; - expr_t substituteVarExpectation(const map &subst_table) const override; - void findDiffNodes(lag_equivalence_table_t &nodes) const override; - void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override; + expr_t substituteVarExpectation(const map& subst_table) const override; + void findDiffNodes(lag_equivalence_table_t& nodes) const override; + void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t& nodes) const override; bool findTargetVariableHelper1(int lhs_symb_id, int rhs_symb_id) const; - optional findTargetVariableHelper(const expr_t arg1, const expr_t arg2, int lhs_symb_id) const; + optional findTargetVariableHelper(const expr_t arg1, const expr_t arg2, + int lhs_symb_id) const; optional findTargetVariable(int lhs_symb_id) const override; - expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - expr_t substitutePacExpectation(const string &name, expr_t subexpr) override; - expr_t substitutePacTargetNonstationary(const string &name, expr_t subexpr) override; + expr_t substituteDiff(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substitutePacExpectation(const string& name, expr_t subexpr) override; + expr_t substitutePacTargetNonstationary(const string& name, expr_t subexpr) override; expr_t decreaseLeadsLagsPredeterminedVariables() const override; - expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const override; + expr_t differentiateForwardVars(const vector& subset, subst_table_t& subst_table, + vector& neweqs) const override; bool isNumConstNodeEqualTo(double value) const override; int countDiffs() const override; bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override; expr_t replaceTrendVar() const override; expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override; - expr_t clone(DataTree &alt_datatree) const override; - expr_t removeTrendLeadLag(const map &trend_symbols_map) const override; - //! Function to write out the oPowerNode in expr_t terms as opposed to writing out the function itself + expr_t clone(DataTree& alt_datatree) const override; + expr_t removeTrendLeadLag(const map& trend_symbols_map) const override; + //! Function to write out the oPowerNode in expr_t terms as opposed to writing out the function + //! itself expr_t unpackPowerDeriv() const; //! Returns MULT_i*(lhs-rhs) = 0, creating multiplier MULT_i expr_t addMultipliersToConstraints(int i); //! Returns the non-zero hand-side of an equation (that must have a hand side equal to zero) expr_t getNonZeroPartofEquation() const; bool isInStaticForm() const override; - void fillAutoregressiveRow(int eqn, const vector &lhs, map, expr_t> &AR) const; + void fillAutoregressiveRow(int eqn, const vector& lhs, + map, expr_t>& AR) const; //! Finds equations where a variable is equal to a constant - void findConstantEquations(map &table) const; - expr_t replaceVarsInEquation(map &table) const override; - bool containsPacExpectation(const string &pac_model_name = "") const override; - bool containsPacTargetNonstationary(const string &pac_model_name = "") const override; + void findConstantEquations(map& table) const; + expr_t replaceVarsInEquation(map& table) const override; + bool containsPacExpectation(const string& pac_model_name = "") const override; + bool containsPacTargetNonstationary(const string& pac_model_name = "") const override; /* ec_params_and_vars: - 1st element = feedback force parameter @@ -1247,21 +1454,25 @@ public: variable_lag is *not* the lag order in the AR (because variable is an AUX_DIFF_LAG) */ - void getPacAREC(int lhs_symb_id, int lhs_orig_symb_id, - pair>> &ec_params_and_vars, - vector, optional, int>> &ar_params_and_vars, - vector, double>> &additive_vars_params_and_constants) const; + void getPacAREC( + int lhs_symb_id, int lhs_orig_symb_id, + pair>>& ec_params_and_vars, + vector, optional, int>>& ar_params_and_vars, + vector, double>>& additive_vars_params_and_constants) const; //! Finds the share of optimizing agents in the PAC equation, //! the expr node associated with it, //! and the expr node associated with the non-optimizing part - tuple, expr_t, expr_t, expr_t> getPacOptimizingShareAndExprNodes(int lhs_orig_symb_id) const; + tuple, expr_t, expr_t, expr_t> + getPacOptimizingShareAndExprNodes(int lhs_orig_symb_id) const; pair, expr_t> getPacOptimizingShareAndExprNodesHelper(int lhs_orig_symb_id) const; expr_t getPacNonOptimizingPart(int optim_share_symb_id) const; bool isParamTimesEndogExpr() const override; - void decomposeAdditiveTerms(vector> &terms, int current_sign) const override; - void decomposeMultiplicativeFactors(vector> &factors, int current_exponent = 1) const override; - void matchMatchedMoment(vector &symb_ids, vector &lags, vector &powers) const override; + void decomposeAdditiveTerms(vector>& terms, int current_sign) const override; + void decomposeMultiplicativeFactors(vector>& factors, + int current_exponent = 1) const override; + void matchMatchedMoment(vector& symb_ids, vector& lags, + vector& powers) const override; pair matchEndogenousTimesConstant() const override; expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override; }; @@ -1270,66 +1481,89 @@ public: class TrinaryOpNode : public ExprNode { friend class ModelTree; + public: const expr_t arg1, arg2, arg3; const TrinaryOpcode op_code; + protected: void prepareForDerivation() override; - void prepareForChainRuleDerivation(const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives) const override; - void computeSubExprContainingVariable(int symb_id, int lag, set &contain_var) const override; + void prepareForChainRuleDerivation( + const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const override; + void computeSubExprContainingVariable(int symb_id, int lag, + set& contain_var) const override; + private: expr_t computeDerivative(int deriv_id) override; - expr_t computeChainRuleDerivative(int deriv_id, const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives, unordered_map> &cache) override; + expr_t + computeChainRuleDerivative(int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) override; int cost(int cost, bool is_matlab) const override; - int cost(const vector>> &blocks_temporary_terms, bool is_matlab) const override; - int cost(const map, unordered_set> &temp_terms_map, bool is_matlab) const override; - //! Returns the derivative of this node if darg1, darg2 and darg3 are the derivatives of the arguments + int cost(const vector>>& blocks_temporary_terms, + bool is_matlab) const override; + int cost(const map, unordered_set>& temp_terms_map, + bool is_matlab) const override; + //! Returns the derivative of this node if darg1, darg2 and darg3 are the derivatives of the + //! arguments expr_t composeDerivatives(expr_t darg1, expr_t darg2, expr_t darg3); - // Returns the node obtained by applying a transformation recursively on the arguments (in same datatree) + // Returns the node obtained by applying a transformation recursively on the arguments (in same + // datatree) template expr_t recurseTransform(Callable&& op, Args&&... args) const { - expr_t substarg1 { invoke(forward(op), arg1, forward(args)...) }; - expr_t substarg2 { invoke(forward(op), arg2, forward(args)...) }; - expr_t substarg3 { invoke(forward(op), arg3, forward(args)...) }; + expr_t substarg1 {invoke(forward(op), arg1, forward(args)...)}; + expr_t substarg2 {invoke(forward(op), arg2, forward(args)...)}; + expr_t substarg3 {invoke(forward(op), arg3, forward(args)...)}; return buildSimilarTrinaryOpNode(substarg1, substarg2, substarg3, datatree); } + public: - TrinaryOpNode(DataTree &datatree_arg, int idx_arg, const expr_t arg1_arg, + TrinaryOpNode(DataTree& datatree_arg, int idx_arg, const expr_t arg1_arg, TrinaryOpcode op_code_arg, const expr_t arg2_arg, const expr_t arg3_arg); - int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const override; - void computeTemporaryTerms(const pair &derivOrder, - map, unordered_set> &temp_terms_map, - unordered_map>> &reference_count, + int precedence(ExprNodeOutputType output_type, + const temporary_terms_t& temporary_terms) const override; + void computeTemporaryTerms(const pair& derivOrder, + map, unordered_set>& temp_terms_map, + unordered_map>>& reference_count, bool is_matlab) const override; - void computeBlockTemporaryTerms(int blk, int eq, vector>> &blocks_temporary_terms, - unordered_map> &reference_count) const override; - void writeOutput(ostream &output, ExprNodeOutputType 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; - 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 computeBlockTemporaryTerms( + int blk, int eq, vector>>& blocks_temporary_terms, + unordered_map>& reference_count) const override; + void writeOutput(ostream& output, ExprNodeOutputType 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; + 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; bool containsExternalFunction() const override; - void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType 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 writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, + void writeExternalFunctionOutput(ostream& output, ExprNodeOutputType 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 writeJsonExternalFunctionOutput(vector& efout, + const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, bool isdynamic) const override; - void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, + void writeBytecodeExternalFunctionOutput(BytecodeWriter& 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 collectVARLHSVariable(set &result) const override; - void collectDynamicVariables(SymbolType type_arg, set> &result) const override; + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + deriv_node_temp_terms_t& tef_terms) const override; + void collectVARLHSVariable(set& result) const override; + void collectDynamicVariables(SymbolType type_arg, set>& result) const override; static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) noexcept(false); - double eval(const eval_context_t &eval_context) const noexcept(false) override; - void writeBytecodeOutput(BytecodeWriter &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; - expr_t toStatic(DataTree &static_datatree) const override; - void computeXrefs(EquationInfo &ei) const override; - BinaryOpNode *normalizeEquationHelper(const set &contain_var, expr_t rhs) const override; + double eval(const eval_context_t& eval_context) const noexcept(false) override; + void writeBytecodeOutput(BytecodeWriter& 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; + expr_t toStatic(DataTree& static_datatree) const override; + void computeXrefs(EquationInfo& ei) const override; + BinaryOpNode* normalizeEquationHelper(const set& contain_var, expr_t rhs) const override; int maxEndoLead() const override; int maxExoLead() const override; int maxEndoLag() const override; @@ -1337,39 +1571,48 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMaxLag(const set &lhs_lag_equiv) const override; + int VarMaxLag(const set& lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; - expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - //! Creates another TrinaryOpNode with the same opcode, but with a possibly different datatree and arguments - expr_t buildSimilarTrinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, expr_t alt_arg3, DataTree &alt_datatree) const; - expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const override; + expr_t substituteEndoLeadGreaterThanTwo(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + //! Creates another TrinaryOpNode with the same opcode, but with a possibly different datatree and + //! arguments + expr_t buildSimilarTrinaryOpNode(expr_t alt_arg1, expr_t alt_arg2, expr_t alt_arg3, + DataTree& alt_datatree) const; + expr_t substituteEndoLagGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteExoLead(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + expr_t substituteExoLag(subst_table_t& subst_table, vector& neweqs) const override; + expr_t substituteExpectation(subst_table_t& subst_table, vector& neweqs, + bool partial_information_model) const override; expr_t substituteAdl() const override; expr_t substituteModelLocalVariables() const override; - expr_t substituteVarExpectation(const map &subst_table) const override; - void findDiffNodes(lag_equivalence_table_t &nodes) const override; - void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override; + expr_t substituteVarExpectation(const map& subst_table) const override; + void findDiffNodes(lag_equivalence_table_t& nodes) const override; + void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t& nodes) const override; optional findTargetVariable(int lhs_symb_id) const override; - expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - expr_t substitutePacExpectation(const string &name, expr_t subexpr) override; - expr_t substitutePacTargetNonstationary(const string &name, expr_t subexpr) override; + expr_t substituteDiff(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substitutePacExpectation(const string& name, expr_t subexpr) override; + expr_t substitutePacTargetNonstationary(const string& name, expr_t subexpr) override; expr_t decreaseLeadsLagsPredeterminedVariables() const override; - expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const override; + expr_t differentiateForwardVars(const vector& subset, subst_table_t& subst_table, + vector& neweqs) const override; bool isNumConstNodeEqualTo(double value) const override; int countDiffs() const override; bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override; expr_t replaceTrendVar() const override; expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override; - expr_t clone(DataTree &alt_datatree) const override; - expr_t removeTrendLeadLag(const map &trend_symbols_map) const override; + expr_t clone(DataTree& alt_datatree) const override; + expr_t removeTrendLeadLag(const map& trend_symbols_map) const override; bool isInStaticForm() const override; - expr_t replaceVarsInEquation(map &table) const override; - bool containsPacExpectation(const string &pac_model_name = "") const override; - bool containsPacTargetNonstationary(const string &pac_model_name = "") const override; + expr_t replaceVarsInEquation(map& table) const override; + bool containsPacExpectation(const string& pac_model_name = "") const override; + bool containsPacTargetNonstationary(const string& pac_model_name = "") const override; bool isParamTimesEndogExpr() const override; expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override; }; @@ -1380,13 +1623,18 @@ class AbstractExternalFunctionNode : public ExprNode public: const int symb_id; const vector arguments; + private: expr_t computeDerivative(int deriv_id) override; - expr_t computeChainRuleDerivative(int deriv_id, const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives, unordered_map> &cache) override; - virtual expr_t composeDerivatives(const vector &dargs) = 0; + expr_t + computeChainRuleDerivative(int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) override; + virtual expr_t composeDerivatives(const vector& dargs) = 0; // Computes the maximum of f applied to all arguments (result will always be non-negative) - int maxHelper(const function &f) const; - // Returns the node obtained by applying a transformation recursively on the arguments (in same datatree) + int maxHelper(const function& f) const; + // Returns the node obtained by applying a transformation recursively on the arguments (in same + // datatree) template expr_t recurseTransform(Callable&& op, Args&&... args) const @@ -1396,64 +1644,90 @@ private: arguments_subst.push_back(invoke(forward(op), argument, forward(args)...)); return buildSimilarExternalFunctionNode(arguments_subst, datatree); } + protected: //! Thrown when trying to access an unknown entry in external_function_node_map class UnknownFunctionNameAndArgs { }; void prepareForDerivation() override; - void prepareForChainRuleDerivation(const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives) const override; + void prepareForChainRuleDerivation( + const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const override; //! Returns true if the given external function has been written as a temporary term - bool alreadyWrittenAsTefTerm(int the_symb_id, const deriv_node_temp_terms_t &tef_terms) const; + bool alreadyWrittenAsTefTerm(int the_symb_id, const deriv_node_temp_terms_t& tef_terms) const; //! Returns the index in the tef_terms map of this external function - int getIndxInTefTerms(int the_symb_id, const deriv_node_temp_terms_t &tef_terms) const noexcept(false); + int getIndxInTefTerms(int the_symb_id, const deriv_node_temp_terms_t& tef_terms) const + noexcept(false); //! Helper function to write output arguments of any given external function - void writeExternalFunctionArguments(ostream &output, ExprNodeOutputType 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; - void writeJsonASTExternalFunctionArguments(ostream &output) const; - 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 writeExternalFunctionArguments(ostream& output, ExprNodeOutputType 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; + void writeJsonASTExternalFunctionArguments(ostream& output) const; + 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, 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; + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + const deriv_node_temp_terms_t& tef_terms) const; /*! Returns a predicate that tests whether an other ExprNode is an external function which is computed by the same external function call (i.e. it has the same so-called "Tef" index) */ - virtual function sameTefTermPredicate() const = 0; - void computeSubExprContainingVariable(int symb_id, int lag, set &contain_var) const override; + virtual function sameTefTermPredicate() const = 0; + void computeSubExprContainingVariable(int symb_id, int lag, + set& contain_var) const override; + public: - AbstractExternalFunctionNode(DataTree &datatree_arg, int idx_arg, int symb_id_arg, + AbstractExternalFunctionNode(DataTree& datatree_arg, int idx_arg, int symb_id_arg, vector arguments_arg); - void computeTemporaryTerms(const pair &derivOrder, - map, unordered_set> &temp_terms_map, - unordered_map>> &reference_count, + void computeTemporaryTerms(const pair& derivOrder, + map, unordered_set>& temp_terms_map, + unordered_map>>& reference_count, bool is_matlab) const override; - void computeBlockTemporaryTerms(int blk, int eq, vector>> &blocks_temporary_terms, - unordered_map> &reference_count) const override; - void writeOutput(ostream &output, ExprNodeOutputType 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 = 0; - void writeJsonAST(ostream &output) const override = 0; - void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic = true) const override = 0; + void computeBlockTemporaryTerms( + int blk, int eq, vector>>& blocks_temporary_terms, + unordered_map>& reference_count) const override; + void writeOutput(ostream& output, ExprNodeOutputType 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 + = 0; + void writeJsonAST(ostream& output) const override = 0; + void writeJsonOutput(ostream& output, const temporary_terms_t& temporary_terms, + const deriv_node_temp_terms_t& tef_terms, + bool isdynamic = true) const override + = 0; bool containsExternalFunction() const override; - void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType 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 = 0; - void writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, - bool isdynamic = true) const override = 0; - void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, + void writeExternalFunctionOutput(ostream& output, ExprNodeOutputType 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 + = 0; + void writeJsonExternalFunctionOutput(vector& efout, + const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, + bool isdynamic = true) const override + = 0; + void writeBytecodeExternalFunctionOutput(BytecodeWriter& 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 = 0; - void collectVARLHSVariable(set &result) const override; - void collectDynamicVariables(SymbolType type_arg, set> &result) const override; - double eval(const eval_context_t &eval_context) const noexcept(false) override; - void writeBytecodeOutput(BytecodeWriter &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 = 0; - expr_t toStatic(DataTree &static_datatree) const override; - void computeXrefs(EquationInfo &ei) const override = 0; - BinaryOpNode *normalizeEquationHelper(const set &contain_var, expr_t rhs) const override; + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + deriv_node_temp_terms_t& tef_terms) const override + = 0; + void collectVARLHSVariable(set& result) const override; + void collectDynamicVariables(SymbolType type_arg, set>& result) const override; + double eval(const eval_context_t& eval_context) const noexcept(false) override; + void writeBytecodeOutput(BytecodeWriter& 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 + = 0; + expr_t toStatic(DataTree& static_datatree) const override; + void computeXrefs(EquationInfo& ei) const override = 0; + BinaryOpNode* normalizeEquationHelper(const set& contain_var, expr_t rhs) const override; int maxEndoLead() const override; int maxExoLead() const override; int maxEndoLag() const override; @@ -1461,39 +1735,51 @@ public: int maxLead() const override; int maxLag() const override; int maxLagWithDiffsExpanded() const override; - int VarMaxLag(const set &lhs_lag_equiv) const override; + int VarMaxLag(const set& lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; - expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const override; + expr_t substituteEndoLeadGreaterThanTwo(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + expr_t substituteEndoLagGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteExoLead(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + expr_t substituteExoLag(subst_table_t& subst_table, vector& neweqs) const override; + expr_t substituteExpectation(subst_table_t& subst_table, vector& neweqs, + bool partial_information_model) const override; expr_t substituteAdl() const override; expr_t substituteModelLocalVariables() const override; - expr_t substituteVarExpectation(const map &subst_table) const override; - void findDiffNodes(lag_equivalence_table_t &nodes) const override; - void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override; + expr_t substituteVarExpectation(const map& subst_table) const override; + void findDiffNodes(lag_equivalence_table_t& nodes) const override; + void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t& nodes) const override; optional findTargetVariable(int lhs_symb_id) const override; - expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - expr_t substitutePacExpectation(const string &name, expr_t subexpr) override; - expr_t substitutePacTargetNonstationary(const string &name, expr_t subexpr) override; - virtual expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const = 0; + expr_t substituteDiff(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substitutePacExpectation(const string& name, expr_t subexpr) override; + expr_t substitutePacTargetNonstationary(const string& name, expr_t subexpr) override; + virtual expr_t buildSimilarExternalFunctionNode(vector& alt_args, + DataTree& alt_datatree) const + = 0; expr_t decreaseLeadsLagsPredeterminedVariables() const override; - expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const override; + expr_t differentiateForwardVars(const vector& subset, subst_table_t& subst_table, + vector& neweqs) const override; bool isNumConstNodeEqualTo(double value) const override; int countDiffs() const override; bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override; - void writePrhs(ostream &output, ExprNodeOutputType 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; + void writePrhs(ostream& output, ExprNodeOutputType 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; expr_t replaceTrendVar() const override; expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override; - expr_t clone(DataTree &alt_datatree) const override; - expr_t removeTrendLeadLag(const map &trend_symbols_map) const override; + expr_t clone(DataTree& alt_datatree) const override; + expr_t removeTrendLeadLag(const map& trend_symbols_map) const override; bool isInStaticForm() const override; - expr_t replaceVarsInEquation(map &table) const override; - bool containsPacExpectation(const string &pac_model_name = "") const override; - bool containsPacTargetNonstationary(const string &pac_model_name = "") const override; + expr_t replaceVarsInEquation(map& table) const override; + bool containsPacExpectation(const string& pac_model_name = "") const override; + bool containsPacTargetNonstationary(const string& pac_model_name = "") const override; bool isParamTimesEndogExpr() const override; expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override; }; @@ -1502,69 +1788,86 @@ class ExternalFunctionNode : public AbstractExternalFunctionNode { friend class FirstDerivExternalFunctionNode; friend class SecondDerivExternalFunctionNode; + private: - expr_t composeDerivatives(const vector &dargs) override; + expr_t composeDerivatives(const vector& dargs) override; + protected: - function sameTefTermPredicate() const override; + function sameTefTermPredicate() const override; + public: - ExternalFunctionNode(DataTree &datatree_arg, int idx_arg, int symb_id_arg, - const vector &arguments_arg); - void writeOutput(ostream &output, ExprNodeOutputType 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; - 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 writeExternalFunctionOutput(ostream &output, ExprNodeOutputType 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 writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, + ExternalFunctionNode(DataTree& datatree_arg, int idx_arg, int symb_id_arg, + const vector& arguments_arg); + void writeOutput(ostream& output, ExprNodeOutputType 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; + 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 writeExternalFunctionOutput(ostream& output, ExprNodeOutputType 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 writeJsonExternalFunctionOutput(vector& efout, + const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, bool isdynamic) const override; - void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, + void writeBytecodeExternalFunctionOutput(BytecodeWriter& 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, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; - void computeXrefs(EquationInfo &ei) const override; - expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const override; + 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, + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + const deriv_node_temp_terms_t& tef_terms) const override; + void computeXrefs(EquationInfo& ei) const override; + expr_t buildSimilarExternalFunctionNode(vector& alt_args, + DataTree& alt_datatree) const override; }; class FirstDerivExternalFunctionNode : public AbstractExternalFunctionNode { public: const int inputIndex; + private: - expr_t composeDerivatives(const vector &dargs) override; + expr_t composeDerivatives(const vector& dargs) override; + protected: - function sameTefTermPredicate() const override; + function sameTefTermPredicate() const override; + public: - FirstDerivExternalFunctionNode(DataTree &datatree_arg, int idx_arg, - int top_level_symb_id_arg, - const vector &arguments_arg, - int inputIndex_arg); - void writeOutput(ostream &output, ExprNodeOutputType 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; - 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, - const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, - const deriv_node_temp_terms_t &tef_terms) const override; - void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType 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 writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, + FirstDerivExternalFunctionNode(DataTree& datatree_arg, int idx_arg, int top_level_symb_id_arg, + const vector& arguments_arg, int inputIndex_arg); + void writeOutput(ostream& output, ExprNodeOutputType 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; + 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, + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + const deriv_node_temp_terms_t& tef_terms) const override; + void writeExternalFunctionOutput(ostream& output, ExprNodeOutputType 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 writeJsonExternalFunctionOutput(vector& efout, + const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, bool isdynamic) const override; - void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, + void writeBytecodeExternalFunctionOutput(BytecodeWriter& 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 computeXrefs(EquationInfo &ei) const override; - expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const override; + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + deriv_node_temp_terms_t& tef_terms) const override; + void computeXrefs(EquationInfo& ei) const override; + expr_t buildSimilarExternalFunctionNode(vector& alt_args, + DataTree& alt_datatree) const override; }; class SecondDerivExternalFunctionNode : public AbstractExternalFunctionNode @@ -1572,38 +1875,44 @@ class SecondDerivExternalFunctionNode : public AbstractExternalFunctionNode public: const int inputIndex1; const int inputIndex2; + private: - expr_t composeDerivatives(const vector &dargs) override; + expr_t composeDerivatives(const vector& dargs) override; + protected: - function sameTefTermPredicate() const override; + function sameTefTermPredicate() const override; + public: - SecondDerivExternalFunctionNode(DataTree &datatree_arg, int idx_arg, - int top_level_symb_id_arg, - const vector &arguments_arg, - int inputIndex1_arg, + SecondDerivExternalFunctionNode(DataTree& datatree_arg, int idx_arg, int top_level_symb_id_arg, + const vector& arguments_arg, int inputIndex1_arg, int inputIndex2_arg); - void writeOutput(ostream &output, ExprNodeOutputType 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; - 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, - const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, - const deriv_node_temp_terms_t &tef_terms) const override; - void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType 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 writeJsonExternalFunctionOutput(vector &efout, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, + void writeOutput(ostream& output, ExprNodeOutputType 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; + 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, + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + const deriv_node_temp_terms_t& tef_terms) const override; + void writeExternalFunctionOutput(ostream& output, ExprNodeOutputType 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 writeJsonExternalFunctionOutput(vector& efout, + const temporary_terms_t& temporary_terms, + deriv_node_temp_terms_t& tef_terms, bool isdynamic) const override; - void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, + void writeBytecodeExternalFunctionOutput(BytecodeWriter& 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 computeXrefs(EquationInfo &ei) const override; - expr_t buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const override; + const temporary_terms_t& temporary_terms, + const temporary_terms_idxs_t& temporary_terms_idxs, + deriv_node_temp_terms_t& tef_terms) const override; + void computeXrefs(EquationInfo& ei) const override; + expr_t buildSimilarExternalFunctionNode(vector& alt_args, + DataTree& alt_datatree) const override; }; /* Common superclass for nodes that have the following two characteristics: @@ -1614,14 +1923,15 @@ class SubModelNode : public ExprNode { public: const string model_name; - SubModelNode(DataTree &datatree_arg, int idx_arg, string model_name_arg); - void computeTemporaryTerms(const pair &derivOrder, - map, unordered_set> &temp_terms_map, - unordered_map>> &reference_count, + SubModelNode(DataTree& datatree_arg, int idx_arg, string model_name_arg); + void computeTemporaryTerms(const pair& derivOrder, + map, unordered_set>& temp_terms_map, + unordered_map>>& reference_count, bool is_matlab) const override; - void computeBlockTemporaryTerms(int blk, int eq, vector>> &blocks_temporary_terms, - unordered_map> &reference_count) const override; - expr_t toStatic(DataTree &static_datatree) const override; + void computeBlockTemporaryTerms( + int blk, int eq, vector>>& blocks_temporary_terms, + unordered_map>& reference_count) const override; + expr_t toStatic(DataTree& static_datatree) const override; expr_t computeDerivative(int deriv_id) override; int maxEndoLead() const override; int maxExoLead() const override; @@ -1629,97 +1939,124 @@ public: int maxExoLag() const override; int maxLead() const override; int maxLag() const override; - int VarMaxLag(const set &lhs_lag_equiv) const override; + int VarMaxLag(const set& lhs_lag_equiv) const override; expr_t undiff() const override; expr_t decreaseLeadsLags(int n) const override; int countDiffs() const override; - expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const override; - expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const override; + expr_t substituteEndoLeadGreaterThanTwo(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + expr_t substituteEndoLagGreaterThanTwo(subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteExoLead(subst_table_t& subst_table, vector& neweqs, + bool deterministic_model) const override; + expr_t substituteExoLag(subst_table_t& subst_table, vector& neweqs) const override; bool containsExternalFunction() const override; - double eval(const eval_context_t &eval_context) const noexcept(false) override; - void computeXrefs(EquationInfo &ei) const override; - expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const override; + double eval(const eval_context_t& eval_context) const noexcept(false) override; + void computeXrefs(EquationInfo& ei) const override; + expr_t substituteExpectation(subst_table_t& subst_table, vector& neweqs, + bool partial_information_model) const override; expr_t substituteAdl() const override; expr_t substituteModelLocalVariables() const override; - void findDiffNodes(lag_equivalence_table_t &nodes) const override; - void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t &nodes) const override; + void findDiffNodes(lag_equivalence_table_t& nodes) const override; + void findUnaryOpNodesForAuxVarCreation(lag_equivalence_table_t& nodes) const override; optional findTargetVariable(int lhs_symb_id) const override; - expr_t substituteDiff(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector &neweqs) const override; - BinaryOpNode *normalizeEquationHelper(const set &contain_var, expr_t rhs) const override; - void writeBytecodeOutput(BytecodeWriter &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; - void collectVARLHSVariable(set &result) const override; - void collectDynamicVariables(SymbolType type_arg, set> &result) const override; + expr_t substituteDiff(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + expr_t substituteUnaryOpNodes(const lag_equivalence_table_t& nodes, subst_table_t& subst_table, + vector& neweqs) const override; + BinaryOpNode* normalizeEquationHelper(const set& contain_var, expr_t rhs) const override; + void writeBytecodeOutput(BytecodeWriter& 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; + void collectVARLHSVariable(set& result) const override; + void collectDynamicVariables(SymbolType type_arg, set>& result) const override; bool isNumConstNodeEqualTo(double value) const override; bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const override; bool isInStaticForm() const override; - expr_t replaceVarsInEquation(map &table) const override; + expr_t replaceVarsInEquation(map& table) const override; bool isParamTimesEndogExpr() const override; - expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const override; + expr_t differentiateForwardVars(const vector& subset, subst_table_t& subst_table, + vector& neweqs) const override; expr_t decreaseLeadsLagsPredeterminedVariables() const override; expr_t replaceTrendVar() const override; expr_t detrend(int symb_id, bool log_trend, expr_t trend) const override; - expr_t removeTrendLeadLag(const map &trend_symbols_map) const override; + expr_t removeTrendLeadLag(const map& trend_symbols_map) const override; expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override; + protected: void prepareForDerivation() override; - void prepareForChainRuleDerivation(const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives) const override; - void computeSubExprContainingVariable(int symb_id, int lag, set &contain_var) const override; + void prepareForChainRuleDerivation( + const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives) const override; + void computeSubExprContainingVariable(int symb_id, int lag, + set& contain_var) const override; + private: - expr_t computeChainRuleDerivative(int deriv_id, const map &recursive_variables, unordered_map> &non_null_chain_rule_derivatives, unordered_map> &cache) override; + expr_t + computeChainRuleDerivative(int deriv_id, const map& recursive_variables, + unordered_map>& non_null_chain_rule_derivatives, + unordered_map>& cache) override; }; class VarExpectationNode : public SubModelNode { public: - VarExpectationNode(DataTree &datatree_arg, int idx_arg, string model_name_arg); - void writeOutput(ostream &output, ExprNodeOutputType 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; - expr_t clone(DataTree &alt_datatree) const override; + VarExpectationNode(DataTree& datatree_arg, int idx_arg, string model_name_arg); + void writeOutput(ostream& output, ExprNodeOutputType 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; + expr_t clone(DataTree& alt_datatree) const override; int maxLagWithDiffsExpanded() const override; - expr_t substituteVarExpectation(const map &subst_table) const override; - expr_t substitutePacExpectation(const string &name, expr_t subexpr) override; - expr_t substitutePacTargetNonstationary(const string &name, expr_t subexpr) override; - bool containsPacExpectation(const string &pac_model_name = "") const override; - bool containsPacTargetNonstationary(const string &pac_model_name = "") const override; - 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; + expr_t substituteVarExpectation(const map& subst_table) const override; + expr_t substitutePacExpectation(const string& name, expr_t subexpr) override; + expr_t substitutePacTargetNonstationary(const string& name, expr_t subexpr) override; + bool containsPacExpectation(const string& pac_model_name = "") const override; + bool containsPacTargetNonstationary(const string& pac_model_name = "") const override; + 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; }; class PacExpectationNode : public SubModelNode { public: - PacExpectationNode(DataTree &datatree_arg, int idx_arg, string model_name); - void writeOutput(ostream &output, ExprNodeOutputType 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; - expr_t clone(DataTree &alt_datatree) const override; + PacExpectationNode(DataTree& datatree_arg, int idx_arg, string model_name); + void writeOutput(ostream& output, ExprNodeOutputType 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; + expr_t clone(DataTree& alt_datatree) const override; int maxLagWithDiffsExpanded() const override; - expr_t substituteVarExpectation(const map &subst_table) const override; - expr_t substitutePacExpectation(const string &name, expr_t subexpr) override; - expr_t substitutePacTargetNonstationary(const string &name, expr_t subexpr) override; - bool containsPacExpectation(const string &pac_model_name = "") const override; - bool containsPacTargetNonstationary(const string &pac_model_name = "") const override; - 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; + expr_t substituteVarExpectation(const map& subst_table) const override; + expr_t substitutePacExpectation(const string& name, expr_t subexpr) override; + expr_t substitutePacTargetNonstationary(const string& name, expr_t subexpr) override; + bool containsPacExpectation(const string& pac_model_name = "") const override; + bool containsPacTargetNonstationary(const string& pac_model_name = "") const override; + 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; }; class PacTargetNonstationaryNode : public SubModelNode { public: - PacTargetNonstationaryNode(DataTree &datatree_arg, int idx_arg, string model_name); - void writeOutput(ostream &output, ExprNodeOutputType 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; - expr_t clone(DataTree &alt_datatree) const override; + PacTargetNonstationaryNode(DataTree& datatree_arg, int idx_arg, string model_name); + void writeOutput(ostream& output, ExprNodeOutputType 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; + expr_t clone(DataTree& alt_datatree) const override; int maxLagWithDiffsExpanded() const override; - expr_t substituteVarExpectation(const map &subst_table) const override; - expr_t substitutePacExpectation(const string &name, expr_t subexpr) override; - expr_t substitutePacTargetNonstationary(const string &name, expr_t subexpr) override; - bool containsPacExpectation(const string &pac_model_name = "") const override; - bool containsPacTargetNonstationary(const string &pac_model_name = "") const override; - 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; + expr_t substituteVarExpectation(const map& subst_table) const override; + expr_t substitutePacExpectation(const string& name, expr_t subexpr) override; + expr_t substitutePacTargetNonstationary(const string& name, expr_t subexpr) override; + bool containsPacExpectation(const string& pac_model_name = "") const override; + bool containsPacTargetNonstationary(const string& pac_model_name = "") const override; + 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; }; #endif diff --git a/src/ExtendedPreprocessorTypes.hh b/src/ExtendedPreprocessorTypes.hh index d4d70a7d..64da1cc9 100644 --- a/src/ExtendedPreprocessorTypes.hh +++ b/src/ExtendedPreprocessorTypes.hh @@ -22,33 +22,33 @@ // Values for the “output” option enum class OutputType - { - standard, // Default value, infer the derivation order from .mod file only - second, // Output at least 2nd dynamic derivatives - third, // Output at least 3rd dynamic derivatives - }; +{ + standard, // Default value, infer the derivation order from .mod file only + second, // Output at least 2nd dynamic derivatives + third, // Output at least 3rd dynamic derivatives +}; // Values for the “language” option enum class LanguageOutputType - { - matlab, // outputs files for MATLAB/Octave processing - julia, // outputs files for Julia - }; +{ + matlab, // outputs files for MATLAB/Octave processing + julia, // outputs files for Julia +}; enum class JsonFileOutputType - { - file, // output JSON files to file - standardout, // output JSON files to stdout - }; +{ + file, // output JSON files to file + standardout, // output JSON files to stdout +}; // Values for the “json” option enum class JsonOutputPointType - { - nojson, // don't output JSON - parsing, // output JSON after the parsing step - checkpass, // output JSON after the check pass - transformpass, // output JSON after the transform pass - computingpass // output JSON after the computing pass - }; +{ + nojson, // don't output JSON + parsing, // output JSON after the parsing step + checkpass, // output JSON after the check pass + transformpass, // output JSON after the transform pass + computingpass // output JSON after the computing pass +}; #endif diff --git a/src/ExternalFunctionsTable.cc b/src/ExternalFunctionsTable.cc index 3147f3e7..791725d9 100644 --- a/src/ExternalFunctionsTable.cc +++ b/src/ExternalFunctionsTable.cc @@ -17,16 +17,17 @@ * along with Dynare. If not, see . */ -#include #include #include +#include #include #include "ExternalFunctionsTable.hh" #include "SymbolTable.hh" void -ExternalFunctionsTable::addExternalFunction(int symb_id, const external_function_options &external_function_options_arg, bool track_nargs) +ExternalFunctionsTable::addExternalFunction( + int symb_id, const external_function_options& external_function_options_arg, bool track_nargs) { assert(symb_id >= 0); assert(external_function_options_arg.nargs > 0); @@ -63,11 +64,14 @@ ExternalFunctionsTable::addExternalFunction(int symb_id, const external_function if (external_function_options_chng.secondDerivSymbID != IDNotSet && external_function_options_chng.firstDerivSymbID == IDNotSet) { - cerr << "ERROR: If the second derivative is provided, the first derivative must also be provided." << endl; + cerr << "ERROR: If the second derivative is provided, the first derivative must also be " + "provided." + << endl; exit(EXIT_FAILURE); } - if (external_function_options_chng.secondDerivSymbID == external_function_options_chng.firstDerivSymbID + if (external_function_options_chng.secondDerivSymbID + == external_function_options_chng.firstDerivSymbID && external_function_options_chng.firstDerivSymbID != symb_id && external_function_options_chng.firstDerivSymbID != IDNotSet) { @@ -80,29 +84,40 @@ ExternalFunctionsTable::addExternalFunction(int symb_id, const external_function if (exists(symb_id)) { bool ok_to_overwrite = false; - if (getNargs(symb_id) == IDNotSet) // implies that the information stored about this function is not important + if (getNargs(symb_id) + == IDNotSet) // implies that the information stored about this function is not important ok_to_overwrite = true; - if (!ok_to_overwrite) // prevents multiple non-compatible calls to external_function(name=funcname) + if (!ok_to_overwrite) // prevents multiple non-compatible calls to + // external_function(name=funcname) { // e.g. e_f(name=a,nargs=1,fd,sd) and e_f(name=a,nargs=2,fd=b,sd=c) should cause an error if (external_function_options_chng.nargs != getNargs(symb_id)) { - cerr << "ERROR: The number of arguments passed to the external_function() statement do not " - << "match the number of arguments passed to a previous call or declaration of the top-level function."<< endl; + cerr << "ERROR: The number of arguments passed to the external_function() statement " + "do not " + << "match the number of arguments passed to a previous call or declaration of " + "the top-level function." + << endl; exit(EXIT_FAILURE); } if (external_function_options_chng.firstDerivSymbID != getFirstDerivSymbID(symb_id)) { - cerr << "ERROR: The first derivative function passed to the external_function() statement does not " - << "match the first derivative function passed to a previous call or declaration of the top-level function."<< endl; + cerr << "ERROR: The first derivative function passed to the external_function() " + "statement does not " + << "match the first derivative function passed to a previous call or " + "declaration of the top-level function." + << endl; exit(EXIT_FAILURE); } if (external_function_options_chng.secondDerivSymbID != getSecondDerivSymbID(symb_id)) { - cerr << "ERROR: The second derivative function passed to the external_function() statement does not " - << "match the second derivative function passed to a previous call or declaration of the top-level function."<< endl; + cerr << "ERROR: The second derivative function passed to the external_function() " + "statement does not " + << "match the second derivative function passed to a previous call or " + "declaration of the top-level function." + << endl; exit(EXIT_FAILURE); } } diff --git a/src/ExternalFunctionsTable.hh b/src/ExternalFunctionsTable.hh index 16009289..d38c4dd8 100644 --- a/src/ExternalFunctionsTable.hh +++ b/src/ExternalFunctionsTable.hh @@ -20,11 +20,11 @@ #ifndef _EXTERNALFUNCTIONSTABLE_HH #define _EXTERNALFUNCTIONSTABLE_HH +#include #include +#include #include #include -#include -#include using namespace std; @@ -55,12 +55,16 @@ public: constexpr static int IDSetButNoNameProvided = -2; //! Default number of arguments when nargs is not specified constexpr static int defaultNargs = 1; + private: //! Map containing options provided to external_functions() external_function_table_type externalFunctionTable; + public: //! Adds an external function to the table as well as its derivative functions - void addExternalFunction(int symb_id, const external_function_options &external_function_options_arg, bool track_nargs); + void addExternalFunction(int symb_id, + const external_function_options& external_function_options_arg, + bool track_nargs); //! See if the function exists in the External Functions Table inline bool exists(int symb_id) const; //! Get the number of arguments for a given external function @@ -80,31 +84,28 @@ ExternalFunctionsTable::exists(int symb_id) const inline int ExternalFunctionsTable::getNargs(int symb_id) const noexcept(false) { - if (auto it = externalFunctionTable.find(symb_id); - it != externalFunctionTable.end()) + if (auto it = externalFunctionTable.find(symb_id); it != externalFunctionTable.end()) return it->second.nargs; else - throw UnknownExternalFunctionSymbolIDException{symb_id}; + throw UnknownExternalFunctionSymbolIDException {symb_id}; } inline int ExternalFunctionsTable::getFirstDerivSymbID(int symb_id) const noexcept(false) { - if (auto it = externalFunctionTable.find(symb_id); - it != externalFunctionTable.end()) + if (auto it = externalFunctionTable.find(symb_id); it != externalFunctionTable.end()) return it->second.firstDerivSymbID; else - throw UnknownExternalFunctionSymbolIDException{symb_id}; + throw UnknownExternalFunctionSymbolIDException {symb_id}; } inline int ExternalFunctionsTable::getSecondDerivSymbID(int symb_id) const noexcept(false) { - if (auto it = externalFunctionTable.find(symb_id); - it != externalFunctionTable.end()) + if (auto it = externalFunctionTable.find(symb_id); it != externalFunctionTable.end()) return it->second.secondDerivSymbID; else - throw UnknownExternalFunctionSymbolIDException{symb_id}; + throw UnknownExternalFunctionSymbolIDException {symb_id}; } #endif diff --git a/src/MacroExpandModFile.cc b/src/MacroExpandModFile.cc index d12e104c..6251ae25 100644 --- a/src/MacroExpandModFile.cc +++ b/src/MacroExpandModFile.cc @@ -17,19 +17,18 @@ * along with Dynare. If not, see . */ +#include +#include +#include #include #include -#include -#include -#include #include "macro/Driver.hh" stringstream -macroExpandModFile(const filesystem::path &filename, const istream &modfile, - bool debug, bool save_macro, filesystem::path save_macro_file, bool line_macro, - const vector> &defines, - vector paths) +macroExpandModFile(const filesystem::path& filename, const istream& modfile, bool debug, + bool save_macro, filesystem::path save_macro_file, bool line_macro, + const vector>& defines, vector paths) { // Do macro processing stringstream macro_output; @@ -43,7 +42,7 @@ macroExpandModFile(const filesystem::path &filename, const istream &modfile, { if (save_macro_file.empty()) save_macro_file = filename.stem().string() + "-macroexp.mod"; - ofstream macro_output_file{save_macro_file}; + ofstream macro_output_file {save_macro_file}; if (macro_output_file.fail()) { cerr << "Cannot open " << save_macro_file.string() << " for macro output" << endl; diff --git a/src/ModFile.cc b/src/ModFile.cc index a083f770..a63bc673 100644 --- a/src/ModFile.cc +++ b/src/ModFile.cc @@ -17,39 +17,39 @@ * along with Dynare. If not, see . */ -#include -#include -#include -#include #include +#include +#include +#include #include +#include #include -#include "ModFile.hh" -#include "ConfigFile.hh" #include "ComputingTasks.hh" +#include "ConfigFile.hh" +#include "ModFile.hh" #include "Shocks.hh" -ModFile::ModFile(WarningConsolidation &warnings_arg) - : var_model_table{symbol_table}, - trend_component_model_table{symbol_table}, - var_expectation_model_table{symbol_table}, - pac_model_table{symbol_table}, - expressions_tree{symbol_table, num_constants, external_functions_table}, - original_model{symbol_table, num_constants, external_functions_table, +ModFile::ModFile(WarningConsolidation& warnings_arg) : + var_model_table {symbol_table}, + trend_component_model_table {symbol_table}, + var_expectation_model_table {symbol_table}, + pac_model_table {symbol_table}, + expressions_tree {symbol_table, num_constants, external_functions_table}, + original_model {symbol_table, num_constants, external_functions_table, + trend_component_model_table, var_model_table}, + dynamic_model {symbol_table, num_constants, external_functions_table, trend_component_model_table, var_model_table}, - dynamic_model{symbol_table, num_constants, external_functions_table, - trend_component_model_table, var_model_table}, - trend_dynamic_model{symbol_table, num_constants, external_functions_table, - trend_component_model_table, var_model_table}, - orig_ramsey_dynamic_model{symbol_table, num_constants, external_functions_table, - trend_component_model_table, var_model_table}, - epilogue{symbol_table, num_constants, external_functions_table, - trend_component_model_table, var_model_table}, - static_model{symbol_table, num_constants, external_functions_table}, - steady_state_model{symbol_table, num_constants, external_functions_table, static_model}, - warnings{warnings_arg} + trend_dynamic_model {symbol_table, num_constants, external_functions_table, + trend_component_model_table, var_model_table}, + orig_ramsey_dynamic_model {symbol_table, num_constants, external_functions_table, + trend_component_model_table, var_model_table}, + epilogue {symbol_table, num_constants, external_functions_table, trend_component_model_table, + var_model_table}, + static_model {symbol_table, num_constants, external_functions_table}, + steady_state_model {symbol_table, num_constants, external_functions_table, static_model}, + warnings {warnings_arg} { } @@ -59,15 +59,15 @@ ModFile::evalAllExpressions(bool warn_uninit) cout << "Evaluating expressions..." << endl; // Loop over all statements, and fill global eval context if relevant - for (auto &st : statements) + for (auto& st : statements) { - if (auto ips = dynamic_cast(st.get()); ips) + if (auto ips = dynamic_cast(st.get()); ips) ips->fillEvalContext(global_eval_context); - if (auto ies = dynamic_cast(st.get()); ies) + if (auto ies = dynamic_cast(st.get()); ies) ies->fillEvalContext(global_eval_context); - if (auto lpass = dynamic_cast(st.get()); lpass) + if (auto lpass = dynamic_cast(st.get()); lpass) lpass->fillEvalContext(global_eval_context); } @@ -77,13 +77,14 @@ ModFile::evalAllExpressions(bool warn_uninit) // Check if some symbols are not initialized, and give them a zero value then for (int id = 0; id <= symbol_table.maxID(); id++) if (auto type = symbol_table.getType(id); - (type == SymbolType::endogenous || type == SymbolType::exogenous || type == SymbolType::exogenousDet - || type == SymbolType::parameter || type == SymbolType::modelLocalVariable) + (type == SymbolType::endogenous || type == SymbolType::exogenous + || type == SymbolType::exogenousDet || type == SymbolType::parameter + || type == SymbolType::modelLocalVariable) && !global_eval_context.contains(id)) { if (warn_uninit) - warnings << "WARNING: Can't find a numeric initial value for " - << symbol_table.getName(id) << ", using zero" << endl; + warnings << "WARNING: Can't find a numeric initial value for " << symbol_table.getName(id) + << ", using zero" << endl; global_eval_context[id] = 0; } } @@ -103,7 +104,7 @@ ModFile::addStatementAtFront(unique_ptr st) void ModFile::checkPass(bool nostrict, bool stochastic) { - for (auto &statement : statements) + for (auto& statement : statements) statement->checkPass(mod_file_struct, warnings); // Check the steady state block @@ -117,7 +118,9 @@ ModFile::checkPass(bool nostrict, bool stochastic) if (mod_file_struct.write_latex_steady_state_model_present && !mod_file_struct.steady_state_model_present) { - cerr << "ERROR: You cannot have a write_latex_steady_state_model statement without a steady_state_model block." << endl; + cerr << "ERROR: You cannot have a write_latex_steady_state_model statement without a " + "steady_state_model block." + << endl; exit(EXIT_FAILURE); } @@ -129,20 +132,16 @@ ModFile::checkPass(bool nostrict, bool stochastic) if (param_used_with_lead_lag) warnings << "WARNING: A parameter was used with a lead or a lag in the model block" << endl; - bool stochastic_statement_present = mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present - || mod_file_struct.osr_present - || mod_file_struct.discretionary_policy_present - || mod_file_struct.calib_smoother_present - || mod_file_struct.identification_present - || mod_file_struct.mom_estimation_present - || mod_file_struct.sensitivity_present - || stochastic; + bool stochastic_statement_present + = mod_file_struct.stoch_simul_present || mod_file_struct.estimation_present + || mod_file_struct.osr_present || mod_file_struct.discretionary_policy_present + || mod_file_struct.calib_smoother_present || mod_file_struct.identification_present + || mod_file_struct.mom_estimation_present || mod_file_struct.sensitivity_present + || stochastic; // Allow empty model only when doing a standalone BVAR estimation if (dynamic_model.equation_number() == 0 - && (mod_file_struct.check_present - || mod_file_struct.perfect_foresight_solver_present + && (mod_file_struct.check_present || mod_file_struct.perfect_foresight_solver_present || mod_file_struct.perfect_foresight_with_expectation_errors_solver_present || stochastic_statement_present)) { @@ -152,7 +151,9 @@ ModFile::checkPass(bool nostrict, bool stochastic) if (mod_file_struct.ramsey_model_present && mod_file_struct.discretionary_policy_present) { - cerr << "ERROR: You cannot use the discretionary_policy command when you use either ramsey_model or ramsey_policy and vice versa" << endl; + cerr << "ERROR: You cannot use the discretionary_policy command when you use either " + "ramsey_model or ramsey_policy and vice versa" + << endl; exit(EXIT_FAILURE); } @@ -161,28 +162,40 @@ ModFile::checkPass(bool nostrict, bool stochastic) || (!(mod_file_struct.ramsey_model_present || mod_file_struct.discretionary_policy_present) && mod_file_struct.planner_objective_present)) { - cerr << "ERROR: A planner_objective statement must be used with a ramsey_model, a ramsey_policy or a discretionary_policy statement and vice versa." << endl; + cerr << "ERROR: A planner_objective statement must be used with a ramsey_model, a " + "ramsey_policy or a discretionary_policy statement and vice versa." + << endl; exit(EXIT_FAILURE); } if (mod_file_struct.ramsey_constraints_present && !mod_file_struct.ramsey_model_present) { - cerr << "ERROR: A ramsey_constraints block requires the presence of a ramsey_model or ramsey_policy statement" << endl; + cerr << "ERROR: A ramsey_constraints block requires the presence of a ramsey_model or " + "ramsey_policy statement" + << endl; exit(EXIT_FAILURE); } - if ((mod_file_struct.osr_present && (!mod_file_struct.osr_params_present || !mod_file_struct.optim_weights_present)) - || ((!mod_file_struct.osr_present || !mod_file_struct.osr_params_present) && mod_file_struct.optim_weights_present) - || ((!mod_file_struct.osr_present || !mod_file_struct.optim_weights_present) && mod_file_struct.osr_params_present)) + if ((mod_file_struct.osr_present + && (!mod_file_struct.osr_params_present || !mod_file_struct.optim_weights_present)) + || ((!mod_file_struct.osr_present || !mod_file_struct.osr_params_present) + && mod_file_struct.optim_weights_present) + || ((!mod_file_struct.osr_present || !mod_file_struct.optim_weights_present) + && mod_file_struct.osr_params_present)) { cerr << "ERROR: The osr statement must be used with osr_params and optim_weights." << endl; exit(EXIT_FAILURE); } - if ((mod_file_struct.perfect_foresight_solver_present || mod_file_struct.perfect_foresight_with_expectation_errors_solver_present) + if ((mod_file_struct.perfect_foresight_solver_present + || mod_file_struct.perfect_foresight_with_expectation_errors_solver_present) && stochastic_statement_present) { - cerr << "ERROR: A .mod file cannot contain both one of {perfect_foresight_solver, simul, perfect_foresight_with_expectation_errors_solver} and one of {stoch_simul, estimation, osr, ramsey_policy, discretionary_policy}. This is not possible: one cannot mix perfect foresight context with stochastic context in the same file." << endl; + cerr << "ERROR: A .mod file cannot contain both one of {perfect_foresight_solver, simul, " + "perfect_foresight_with_expectation_errors_solver} and one of {stoch_simul, " + "estimation, osr, ramsey_policy, discretionary_policy}. This is not possible: one " + "cannot mix perfect foresight context with stochastic context in the same file." + << endl; exit(EXIT_FAILURE); } @@ -192,15 +205,20 @@ ModFile::checkPass(bool nostrict, bool stochastic) exit(EXIT_FAILURE); } - if ((stochastic_statement_present || mod_file_struct.check_present || mod_file_struct.steady_present) && no_static) + if ((stochastic_statement_present || mod_file_struct.check_present + || mod_file_struct.steady_present) + && no_static) { - cerr << "ERROR: no_static option is incompatible with stoch_simul, estimation, osr, ramsey_policy, discretionary_policy, steady and check commands" << endl; + cerr << "ERROR: no_static option is incompatible with stoch_simul, estimation, osr, " + "ramsey_policy, discretionary_policy, steady and check commands" + << endl; exit(EXIT_FAILURE); } if (mod_file_struct.dsge_var_estimated && !mod_file_struct.dsge_prior_weight_in_estimated_params) { - cerr << "ERROR: When estimating a DSGE-VAR model and estimating the weight of the prior, dsge_prior_weight must " + cerr << "ERROR: When estimating a DSGE-VAR model and estimating the weight of the prior, " + "dsge_prior_weight must " << "be referenced in the estimated_params block." << endl; exit(EXIT_FAILURE); } @@ -219,19 +237,23 @@ ModFile::checkPass(bool nostrict, bool stochastic) if (mod_file_struct.dsge_var_estimated || !mod_file_struct.dsge_var_calibrated.empty()) { - cerr << "ERROR: dsge_prior_weight can either be declared as a parameter (deprecated) or via the dsge_var option " + cerr << "ERROR: dsge_prior_weight can either be declared as a parameter (deprecated) or " + "via the dsge_var option " << "to the estimation statement (preferred), but not both." << endl; exit(EXIT_FAILURE); } - if (!mod_file_struct.dsge_prior_weight_initialized && !mod_file_struct.dsge_prior_weight_in_estimated_params) + if (!mod_file_struct.dsge_prior_weight_initialized + && !mod_file_struct.dsge_prior_weight_in_estimated_params) { - cerr << "ERROR: If dsge_prior_weight is declared as a parameter, it must either be initialized or placed in the " + cerr << "ERROR: If dsge_prior_weight is declared as a parameter, it must either be " + "initialized or placed in the " << "estimated_params block." << endl; exit(EXIT_FAILURE); } - if (mod_file_struct.dsge_prior_weight_initialized && mod_file_struct.dsge_prior_weight_in_estimated_params) + if (mod_file_struct.dsge_prior_weight_initialized + && mod_file_struct.dsge_prior_weight_in_estimated_params) { cerr << "ERROR: dsge_prior_weight cannot be both initialized and estimated." << endl; exit(EXIT_FAILURE); @@ -242,28 +264,36 @@ ModFile::checkPass(bool nostrict, bool stochastic) { if (!mod_file_struct.dsge_var_estimated && !mod_file_struct.dsge_var_calibrated.empty()) { - cerr << "ERROR: If dsge_prior_weight is in the estimated_params block, the prior weight cannot be calibrated " + cerr << "ERROR: If dsge_prior_weight is in the estimated_params block, the prior weight " + "cannot be calibrated " << "via the dsge_var option in the estimation statement." << endl; exit(EXIT_FAILURE); } else if (!mod_file_struct.dsge_var_estimated && !symbol_table.exists("dsge_prior_weight")) { - cerr << "ERROR: If dsge_prior_weight is in the estimated_params block, it must either be declared as a parameter " - << "(deprecated) or the dsge_var option must be passed to the estimation statement (preferred)." << endl; + cerr << "ERROR: If dsge_prior_weight is in the estimated_params block, it must either be " + "declared as a parameter " + << "(deprecated) or the dsge_var option must be passed to the estimation statement " + "(preferred)." + << endl; exit(EXIT_FAILURE); } } if (dynamic_model.staticOnlyEquationsNbr() != dynamic_model.dynamicOnlyEquationsNbr()) { - cerr << "ERROR: the number of equations marked [static] must be equal to the number of equations marked [dynamic]" << endl; + cerr << "ERROR: the number of equations marked [static] must be equal to the number of " + "equations marked [dynamic]" + << endl; exit(EXIT_FAILURE); } if (dynamic_model.staticOnlyEquationsNbr() > 0 && (mod_file_struct.ramsey_model_present || mod_file_struct.discretionary_policy_present)) { - cerr << "ERROR: marking equations as [static] or [dynamic] is not possible with ramsey_model, ramsey_policy or discretionary_policy" << endl; + cerr << "ERROR: marking equations as [static] or [dynamic] is not possible with " + "ramsey_model, ramsey_policy or discretionary_policy" + << endl; exit(EXIT_FAILURE); } @@ -278,7 +308,9 @@ ModFile::checkPass(bool nostrict, bool stochastic) || dynamic_model.isBinaryOpUsed(BinaryOpcode::lessEqual) || dynamic_model.isBinaryOpUsed(BinaryOpcode::equalEqual) || dynamic_model.isBinaryOpUsed(BinaryOpcode::different))) - warnings << R"(WARNING: you are using a function (max, min, abs, sign) or an operator (<, >, <=, >=, ==, !=) which is unsuitable for a stochastic context; see the reference manual, section about "Expressions", for more details.)" << endl; + warnings + << R"(WARNING: you are using a function (max, min, abs, sign) or an operator (<, >, <=, >=, ==, !=) which is unsuitable for a stochastic context; see the reference manual, section about "Expressions", for more details.)" + << endl; if (linear && (dynamic_model.isUnaryOpUsedOnType(SymbolType::endogenous, UnaryOpcode::sign) @@ -298,8 +330,7 @@ ModFile::checkPass(bool nostrict, bool stochastic) exit(EXIT_FAILURE); } - if (linear - && !mod_file_struct.perfect_foresight_solver_present + if (linear && !mod_file_struct.perfect_foresight_solver_present && !mod_file_struct.perfect_foresight_with_expectation_errors_solver_present && (dynamic_model.isUnaryOpUsedOnType(SymbolType::exogenous, UnaryOpcode::sign) || dynamic_model.isUnaryOpUsedOnType(SymbolType::exogenous, UnaryOpcode::abs) @@ -329,23 +360,23 @@ ModFile::checkPass(bool nostrict, bool stochastic) if (parameters_intersect.size() > 0) { cerr << "ERROR: some estimated parameters ("; - for (bool printed_something{false}; - int symb_id : parameters_intersect) + for (bool printed_something {false}; int symb_id : parameters_intersect) { if (exchange(printed_something, true)) cerr << ", "; cerr << symbol_table.getName(symb_id); } - cerr << ") also appear in the expressions defining the variance/covariance matrix of shocks; this is not allowed." << endl; + cerr << ") also appear in the expressions defining the variance/covariance matrix of shocks; " + "this is not allowed." + << endl; exit(EXIT_FAILURE); } // Check if some exogenous is not used in the model block, Issue #841 set unusedExo0 = dynamic_model.findUnusedExogenous(); set unusedExo; - set_difference(unusedExo0.begin(), unusedExo0.end(), - mod_file_struct.pac_params.begin(), mod_file_struct.pac_params.end(), - inserter(unusedExo, unusedExo.begin())); + set_difference(unusedExo0.begin(), unusedExo0.end(), mod_file_struct.pac_params.begin(), + mod_file_struct.pac_params.end(), inserter(unusedExo, unusedExo.begin())); if (unusedExo.size() > 0) { ostringstream unused_exos; @@ -357,7 +388,10 @@ ModFile::checkPass(bool nostrict, bool stochastic) << "not used in model block, removed by nostrict command-line option" << endl; else { - cerr << "ERROR: " << unused_exos.str() << "not used in model block. To bypass this error, use the `nostrict` option. This may lead to crashes or unexpected behavior." << endl; + cerr << "ERROR: " << unused_exos.str() + << "not used in model block. To bypass this error, use the `nostrict` option. This " + "may lead to crashes or unexpected behavior." + << endl; exit(EXIT_FAILURE); } } @@ -365,7 +399,7 @@ ModFile::checkPass(bool nostrict, bool stochastic) void ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool transform_unary_ops, - const string &exclude_eqs, const string &include_eqs) + const string& exclude_eqs, const string& include_eqs) { /* Save the original model (must be done before any model transformations by preprocessor) — except predetermined variables (which must be handled before the call to @@ -401,7 +435,8 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool << "' not used in model block, removed by nostrict command-line option" << endl; } else if (unusedEndogsIsErr) - cerr << "Error: " << symbol_table.getName(unusedEndog) << " not used in the model block"<< endl; + cerr << "Error: " << symbol_table.getName(unusedEndog) << " not used in the model block" + << endl; if (unusedEndogsIsErr) exit(EXIT_FAILURE); @@ -410,11 +445,11 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool – equations which are part of VARs and Trend Component Models – PAC equations (those with a pac_expectation operator) */ set var_tcm_eqtags; - for (const auto &[name, tags] : trend_component_model_table.getEqTags()) - for (auto &tag : tags) + for (const auto& [name, tags] : trend_component_model_table.getEqTags()) + for (auto& tag : tags) var_tcm_eqtags.insert(tag); - for (const auto &[name, tags] : var_model_table.getEqTags()) - for (auto &tag : tags) + for (const auto& [name, tags] : var_model_table.getEqTags()) + for (auto& tag : tags) var_tcm_eqtags.insert(tag); set unary_ops_eqs = dynamic_model.getEquationNumbersFromTags(var_tcm_eqtags); @@ -427,13 +462,16 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool lag_equivalence_table_t unary_ops_nodes; ExprNode::subst_table_t unary_ops_subst_table; if (transform_unary_ops) - tie(unary_ops_nodes, unary_ops_subst_table) = dynamic_model.substituteUnaryOps(var_expectation_model_table, pac_model_table); + tie(unary_ops_nodes, unary_ops_subst_table) + = dynamic_model.substituteUnaryOps(var_expectation_model_table, pac_model_table); else // substitute only those unary ops that appear in VAR, TCM and PAC model equations - tie(unary_ops_nodes, unary_ops_subst_table) = dynamic_model.substituteUnaryOps(unary_ops_eqs, var_expectation_model_table, pac_model_table); + tie(unary_ops_nodes, unary_ops_subst_table) = dynamic_model.substituteUnaryOps( + unary_ops_eqs, var_expectation_model_table, pac_model_table); // Create auxiliary variable and equations for Diff operators - auto [diff_nodes, diff_subst_table] = dynamic_model.substituteDiff(var_expectation_model_table, pac_model_table); + auto [diff_nodes, diff_subst_table] + = dynamic_model.substituteDiff(var_expectation_model_table, pac_model_table); // Fill trend component and VAR model tables dynamic_model.fillTrendComponentModelTable(); @@ -447,9 +485,8 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool trend_component_model_table); // PAC model - pac_model_table.transformPass(unary_ops_nodes, unary_ops_subst_table, - diff_nodes, diff_subst_table, - dynamic_model, var_model_table, + pac_model_table.transformPass(unary_ops_nodes, unary_ops_subst_table, diff_nodes, + diff_subst_table, dynamic_model, var_model_table, trend_component_model_table); // Create auxiliary vars for Expectation operator @@ -460,8 +497,8 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool dynamic_model.detrendEquations(); trend_dynamic_model = dynamic_model; dynamic_model.removeTrendVariableFromEquations(); - const auto &trend_symbols = dynamic_model.getTrendSymbolsMap(); - const auto &nonstationary_symbols = dynamic_model.getNonstationarySymbolsMap(); + const auto& trend_symbols = dynamic_model.getTrendSymbolsMap(); + const auto& nonstationary_symbols = dynamic_model.getNonstationarySymbolsMap(); epilogue.detrend(trend_symbols, nonstationary_symbols); } @@ -470,9 +507,9 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool if (mod_file_struct.ramsey_model_present) { mod_file_struct.ramsey_orig_eq_nbr = dynamic_model.equation_number(); - PlannerObjectiveStatement *pos = nullptr; - for (auto &statement : statements) - if (auto pos2 = dynamic_cast(statement.get()); pos2) + PlannerObjectiveStatement* pos = nullptr; + for (auto& statement : statements) + if (auto pos2 = dynamic_cast(statement.get()); pos2) { if (pos) { @@ -483,7 +520,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool pos = pos2; } assert(pos); - const PlannerObjective &planner_objective = pos->getPlannerObjective(); + const PlannerObjective& planner_objective = pos->getPlannerObjective(); /* clone the model then clone the new equations back to the original because @@ -491,9 +528,12 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool */ if (linear) orig_ramsey_dynamic_model = dynamic_model; - DynamicModel ramsey_FOC_equations_dynamic_model {symbol_table, num_constants, external_functions_table, trend_component_model_table, var_model_table}; + DynamicModel ramsey_FOC_equations_dynamic_model { + symbol_table, num_constants, external_functions_table, trend_component_model_table, + var_model_table}; ramsey_FOC_equations_dynamic_model = dynamic_model; - mod_file_struct.ramsey_orig_endo_nbr = ramsey_FOC_equations_dynamic_model.computeRamseyPolicyFOCs(planner_objective); + mod_file_struct.ramsey_orig_endo_nbr + = ramsey_FOC_equations_dynamic_model.computeRamseyPolicyFOCs(planner_objective); ramsey_FOC_equations_dynamic_model.replaceMyEquations(dynamic_model); } @@ -506,15 +546,12 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool exos. The transformation is not exactly the same on stochastic and deterministic models, because there is no need to take into account the Jensen inequality on the latter. */ - bool deterministic_model = !(mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present - || mod_file_struct.osr_present - || mod_file_struct.discretionary_policy_present - || mod_file_struct.calib_smoother_present - || mod_file_struct.identification_present - || mod_file_struct.mom_estimation_present - || mod_file_struct.sensitivity_present - || stochastic); + bool deterministic_model + = !(mod_file_struct.stoch_simul_present || mod_file_struct.estimation_present + || mod_file_struct.osr_present || mod_file_struct.discretionary_policy_present + || mod_file_struct.calib_smoother_present || mod_file_struct.identification_present + || mod_file_struct.mom_estimation_present || mod_file_struct.sensitivity_present + || stochastic); dynamic_model.substituteEndoLeadGreaterThanTwo(deterministic_model); dynamic_model.substituteExoLead(deterministic_model); dynamic_model.substituteEndoLagGreaterThanTwo(deterministic_model); @@ -530,11 +567,11 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool { int sid = symbol_table.addSymbol("dsge_prior_weight", SymbolType::parameter); if (!mod_file_struct.dsge_var_calibrated.empty()) - addStatementAtFront(make_unique(sid, - expressions_tree.AddNonNegativeConstant(mod_file_struct.dsge_var_calibrated), - symbol_table)); + addStatementAtFront(make_unique( + sid, expressions_tree.AddNonNegativeConstant(mod_file_struct.dsge_var_calibrated), + symbol_table)); } - catch (SymbolTable::AlreadyDeclaredException &e) + catch (SymbolTable::AlreadyDeclaredException& e) { cerr << "ERROR: dsge_prior_weight should not be declared as a model variable / parameter " << "when the dsge_var option is passed to the estimation statement." << endl; @@ -559,54 +596,72 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool && !(mod_file_struct.bvar_present && dynamic_model.equation_number() == 0) && (dynamic_model.equation_number() != symbol_table.endo_nbr())) { - cerr << "ERROR: There are " << dynamic_model.equation_number() << " equations but " << symbol_table.endo_nbr() << " endogenous variables!" << endl; + cerr << "ERROR: There are " << dynamic_model.equation_number() << " equations but " + << symbol_table.endo_nbr() << " endogenous variables!" << endl; exit(EXIT_FAILURE); } if (symbol_table.exo_det_nbr() > 0 - && (mod_file_struct.perfect_foresight_solver_present || mod_file_struct.perfect_foresight_with_expectation_errors_solver_present)) + && (mod_file_struct.perfect_foresight_solver_present + || mod_file_struct.perfect_foresight_with_expectation_errors_solver_present)) { - cerr << "ERROR: A .mod file cannot contain both one of {perfect_foresight_solver, simul, perfect_foresight_with_expectation_errors_solver} and varexo_det declaration (all exogenous variables are deterministic in this case)" << endl; + cerr << "ERROR: A .mod file cannot contain both one of {perfect_foresight_solver, simul, " + "perfect_foresight_with_expectation_errors_solver} and varexo_det declaration (all " + "exogenous variables are deterministic in this case)" + << endl; exit(EXIT_FAILURE); } if (mod_file_struct.ramsey_model_present && symbol_table.exo_det_nbr() > 0) { - cerr << "ERROR: ramsey_model and ramsey_policy are incompatible with deterministic exogenous variables" << endl; + cerr << "ERROR: ramsey_model and ramsey_policy are incompatible with deterministic exogenous " + "variables" + << endl; exit(EXIT_FAILURE); } if (mod_file_struct.identification_present && symbol_table.exo_det_nbr() > 0) { - cerr << "ERROR: identification is incompatible with deterministic exogenous variables" << endl; + cerr << "ERROR: identification is incompatible with deterministic exogenous variables" + << endl; exit(EXIT_FAILURE); } if (mod_file_struct.occbin_constraints_present && (mod_file_struct.osr_present || mod_file_struct.mom_estimation_present - || mod_file_struct.ramsey_model_present - || mod_file_struct.discretionary_policy_present || mod_file_struct.extended_path_present - || mod_file_struct.identification_present || mod_file_struct.sensitivity_present)) + || mod_file_struct.ramsey_model_present || mod_file_struct.discretionary_policy_present + || mod_file_struct.extended_path_present || mod_file_struct.identification_present + || mod_file_struct.sensitivity_present)) { - cerr << "ERROR: the 'occbin_constraints' block is not compatible with commands other than 'estimation', 'stoch_simul', and 'calib_smoother'." << endl; + cerr << "ERROR: the 'occbin_constraints' block is not compatible with commands other than " + "'estimation', 'stoch_simul', and 'calib_smoother'." + << endl; exit(EXIT_FAILURE); } if (mod_file_struct.shocks_surprise_present && !mod_file_struct.occbin_constraints_present) { - cerr << "ERROR: the 'shocks(surprise)' block can only be used in conjunction with the 'occbin_constraints' block." << endl; + cerr << "ERROR: the 'shocks(surprise)' block can only be used in conjunction with the " + "'occbin_constraints' block." + << endl; exit(EXIT_FAILURE); } - if (mod_file_struct.shocks_learnt_in_present && !mod_file_struct.perfect_foresight_with_expectation_errors_solver_present) + if (mod_file_struct.shocks_learnt_in_present + && !mod_file_struct.perfect_foresight_with_expectation_errors_solver_present) { - cerr << "ERROR: the 'shocks(learnt_in=…)' block can only be used in conjunction with the 'perfect_foresight_with_expectation_errors_solver' command." << endl; + cerr << "ERROR: the 'shocks(learnt_in=…)' block can only be used in conjunction with the " + "'perfect_foresight_with_expectation_errors_solver' command." + << endl; exit(EXIT_FAILURE); } - if (mod_file_struct.endval_learnt_in_present && !mod_file_struct.perfect_foresight_with_expectation_errors_solver_present) + if (mod_file_struct.endval_learnt_in_present + && !mod_file_struct.perfect_foresight_with_expectation_errors_solver_present) { - cerr << "ERROR: the 'endval(learnt_in=…)' block can only be used in conjunction with the 'perfect_foresight_with_expectation_errors_solver' command." << endl; + cerr << "ERROR: the 'endval(learnt_in=…)' block can only be used in conjunction with the " + "'perfect_foresight_with_expectation_errors_solver' command." + << endl; exit(EXIT_FAILURE); } @@ -614,8 +669,9 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool cout << "Found " << dynamic_model.equation_number() << " equation(s)." << endl; else { - cout << "Found " << mod_file_struct.ramsey_orig_eq_nbr << " equation(s)." << endl; - cout << "Found " << dynamic_model.equation_number() << " FOC equation(s) for Ramsey Problem." << endl; + cout << "Found " << mod_file_struct.ramsey_orig_eq_nbr << " equation(s)." << endl; + cout << "Found " << dynamic_model.equation_number() << " FOC equation(s) for Ramsey Problem." + << endl; } if (symbol_table.exists("dsge_prior_weight")) @@ -624,8 +680,10 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool { if (symbol_table.exo_nbr() != symbol_table.observedVariablesNbr()) { - cerr << "ERROR: When estimating a DSGE-Var and the bayesian_irf option is passed to the estimation " - << "statement, the number of shocks must equal the number of observed variables." << endl; + cerr << "ERROR: When estimating a DSGE-Var and the bayesian_irf option is passed to " + "the estimation " + << "statement, the number of shocks must equal the number of observed variables." + << endl; exit(EXIT_FAILURE); } } @@ -651,24 +709,28 @@ ModFile::computingPass(bool no_tmp_terms, OutputType output, int params_derivs_o static_model = static_cast(dynamic_model); if (!no_static) { - if (mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present || mod_file_struct.osr_present - || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present - || mod_file_struct.calib_smoother_present || mod_file_struct.mom_estimation_present) + if (mod_file_struct.stoch_simul_present || mod_file_struct.estimation_present + || mod_file_struct.osr_present || mod_file_struct.ramsey_model_present + || mod_file_struct.identification_present || mod_file_struct.calib_smoother_present + || mod_file_struct.mom_estimation_present) static_model.set_cutoff_to_zero(); int derivsOrder = 1; int paramsDerivsOrder = 0; - if (mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation) + if (mod_file_struct.identification_present + || mod_file_struct.estimation_analytic_derivation) derivsOrder = 2; - if (mod_file_struct.identification_present + if (mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation || mod_file_struct.osr_analytic_derivation - || (mod_file_struct.GMM_present && (mod_file_struct.analytic_standard_errors_present || mod_file_struct.analytic_jacobian_present))) + || (mod_file_struct.GMM_present + && (mod_file_struct.analytic_standard_errors_present + || mod_file_struct.analytic_jacobian_present))) paramsDerivsOrder = params_derivs_order; - static_model.computingPass(derivsOrder, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll); + static_model.computingPass(derivsOrder, paramsDerivsOrder, global_eval_context, + no_tmp_terms, block, use_dll); if (mod_file_struct.ramsey_model_present) static_model.computeRamseyMultipliersDerivatives(mod_file_struct.ramsey_orig_endo_nbr, !use_dll, no_tmp_terms); @@ -676,8 +738,7 @@ ModFile::computingPass(bool no_tmp_terms, OutputType output, int params_derivs_o // Set things to compute for dynamic model if (mod_file_struct.perfect_foresight_solver_present || mod_file_struct.perfect_foresight_with_expectation_errors_solver_present - || mod_file_struct.check_present - || mod_file_struct.stoch_simul_present + || mod_file_struct.check_present || mod_file_struct.stoch_simul_present || mod_file_struct.estimation_present || mod_file_struct.osr_present || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present || mod_file_struct.calib_smoother_present || mod_file_struct.mom_estimation_present) @@ -688,41 +749,54 @@ ModFile::computingPass(bool no_tmp_terms, OutputType output, int params_derivs_o int derivsOrder = 1; if (output == OutputType::second) derivsOrder = 2; - else if (output == OutputType::third) + else if (output == OutputType::third) derivsOrder = 3; - dynamic_model.computingPass(derivsOrder, 0, global_eval_context, no_tmp_terms, block, use_dll); + dynamic_model.computingPass(derivsOrder, 0, global_eval_context, no_tmp_terms, block, + use_dll); } else { - if (mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present || mod_file_struct.osr_present - || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present - || mod_file_struct.calib_smoother_present || mod_file_struct.mom_estimation_present) + if (mod_file_struct.stoch_simul_present || mod_file_struct.estimation_present + || mod_file_struct.osr_present || mod_file_struct.ramsey_model_present + || mod_file_struct.identification_present + || mod_file_struct.calib_smoother_present + || mod_file_struct.mom_estimation_present) dynamic_model.set_cutoff_to_zero(); if (mod_file_struct.order_option < 1) { cerr << "ERROR: Incorrect order option..." << endl; exit(EXIT_FAILURE); } - int derivsOrder = max(mod_file_struct.order_option,mod_file_struct.identification_order + 1); // See preprocessor#40 - if (mod_file_struct.GMM_present - && (mod_file_struct.analytic_standard_errors_present || mod_file_struct.analytic_jacobian_present)) //analytic_standard_errors or analytic_jacobian require one order more - derivsOrder = max(mod_file_struct.order_option, - max(mod_file_struct.identification_order,mod_file_struct.mom_order) + 1); // See preprocessor#40 + int derivsOrder + = max(mod_file_struct.order_option, + mod_file_struct.identification_order + 1); // See preprocessor#40 + if (mod_file_struct.GMM_present + && (mod_file_struct.analytic_standard_errors_present + || mod_file_struct.analytic_jacobian_present)) // analytic_standard_errors or + // analytic_jacobian require + // one order more + derivsOrder + = max(mod_file_struct.order_option, + max(mod_file_struct.identification_order, mod_file_struct.mom_order) + + 1); // See preprocessor#40 if (mod_file_struct.sensitivity_present || linear || output == OutputType::second) derivsOrder = max(derivsOrder, 2); if (mod_file_struct.estimation_analytic_derivation || output == OutputType::third) derivsOrder = max(derivsOrder, 3); int paramsDerivsOrder = 0; - if (mod_file_struct.identification_present + if (mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation || mod_file_struct.osr_analytic_derivation - || (mod_file_struct.GMM_present && (mod_file_struct.analytic_standard_errors_present || mod_file_struct.analytic_jacobian_present))) + || (mod_file_struct.GMM_present + && (mod_file_struct.analytic_standard_errors_present + || mod_file_struct.analytic_jacobian_present))) paramsDerivsOrder = params_derivs_order; - dynamic_model.computingPass(derivsOrder, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll); + dynamic_model.computingPass(derivsOrder, paramsDerivsOrder, global_eval_context, + no_tmp_terms, block, use_dll); if (linear && mod_file_struct.ramsey_model_present) - orig_ramsey_dynamic_model.computingPass(2, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll); + orig_ramsey_dynamic_model.computingPass(2, paramsDerivsOrder, global_eval_context, + no_tmp_terms, block, use_dll); } } else // No computing task requested, compute derivatives up to 2nd order by default @@ -740,25 +814,25 @@ ModFile::computingPass(bool no_tmp_terms, OutputType output, int params_derivs_o // Those matrices can only be filled here, because we use derivatives dynamic_model.fillVarModelTableMatrices(); - for (auto &statement : statements) + for (auto& statement : statements) statement->computingPass(mod_file_struct); // Compute epilogue derivatives (but silence standard output) - streambuf *oldcout = cout.rdbuf(); + streambuf* oldcout = cout.rdbuf(); cout.rdbuf(nullptr); epilogue.computingPass(2, 0, global_eval_context, true, false, false); cout.rdbuf(oldcout); } void -ModFile::remove_directory_with_matlab_lock(const filesystem::path &dir) +ModFile::remove_directory_with_matlab_lock(const filesystem::path& dir) { auto dirStatus {status(dir)}; if (!exists(dirStatus)) return; if (is_directory(dirStatus)) - for (const auto &e : filesystem::directory_iterator{dir}) + for (const auto& e : filesystem::directory_iterator {dir}) if (e.is_directory()) remove_directory_with_matlab_lock(e); @@ -768,11 +842,11 @@ 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, +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 check_model_changes, bool minimal_workspace, bool compute_xrefs, - const string &mexext, - const filesystem::path &matlabroot, bool onlymodel, bool gui, bool notime) const + const string& mexext, const filesystem::path& matlabroot, bool onlymodel, + bool gui, bool notime) const { if (basename.empty()) { @@ -795,12 +869,13 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, filesystem::remove_all(basename + "/model/src"); filesystem::remove_all(basename + "/model/bytecode"); - // Do not remove basename/model/julia/, otherwise it would break calls to writeToFileIfModified() + // Do not remove basename/model/julia/, otherwise it would break calls to + // writeToFileIfModified() } create_directory(plusfolder); filesystem::path fname {plusfolder / "driver.m"}; - ofstream mOutputFile{fname, ios::out | ios::binary}; + ofstream mOutputFile {fname, ios::out | ios::binary}; if (!mOutputFile.is_open()) { cerr << "ERROR: Can't open file " << fname.string() << " for writing" << endl; @@ -811,7 +886,8 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, << "% Status : main Dynare file" << endl << "%" << endl << "% Warning : this file is generated automatically by Dynare" << endl - << "% from model file (.mod)" << endl << endl; + << "% from model file (.mod)" << endl + << endl; if (no_warn) mOutputFile << "warning off" << endl; // This will be executed *after* function warning_config() @@ -820,21 +896,25 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, mOutputFile << "clearvars -global" << endl << "clear_persistent_variables(fileparts(which('dynare')), false)" << endl; else if (clear_global) - mOutputFile << "clear M_ options_ oo_ estim_params_ bayestopt_ dataset_ dataset_info estimation_info;" << endl; + mOutputFile + << "clear M_ options_ oo_ estim_params_ bayestopt_ dataset_ dataset_info estimation_info;" + << endl; if (!notime) mOutputFile << "tic0 = tic;" << endl; - mOutputFile << "% Define global variables." << endl - << "global M_ options_ oo_ estim_params_ bayestopt_ dataset_ dataset_info estimation_info" << endl - << "options_ = [];" << endl - << "M_.fname = '" << basename << "';" << endl - << "M_.dynare_version = '" << PACKAGE_VERSION << "';" << endl - << "oo_.dynare_version = '" << PACKAGE_VERSION << "';" << endl - << "options_.dynare_version = '" << PACKAGE_VERSION << "';" << endl - << "%" << endl - << "% Some global variables initialization" << endl - << "%" << endl; + mOutputFile + << "% Define global variables." << endl + << "global M_ options_ oo_ estim_params_ bayestopt_ dataset_ dataset_info estimation_info" + << endl + << "options_ = [];" << endl + << "M_.fname = '" << basename << "';" << endl + << "M_.dynare_version = '" << PACKAGE_VERSION << "';" << endl + << "oo_.dynare_version = '" << PACKAGE_VERSION << "';" << endl + << "options_.dynare_version = '" << PACKAGE_VERSION << "';" << endl + << "%" << endl + << "% Some global variables initialization" << endl + << "%" << endl; if (!onlymodel) config_file.writeHooks(mOutputFile); mOutputFile << "global_initialization;" << endl; @@ -843,8 +923,7 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, mOutputFile << "options_.minimal_workspace = true;" << endl; if (console) - mOutputFile << "options_.console_mode = true;" << endl - << "options_.nodisplay = true;" << endl; + mOutputFile << "options_.console_mode = true;" << endl << "options_.nodisplay = true;" << endl; if (nograph) mOutputFile << "options_.nograph = true;" << endl; @@ -862,8 +941,8 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, pac_model_table.writeOutput(mOutputFile); // Initialize M_.Sigma_e, M_.Correlation_matrix, M_.H, and M_.Correlation_matrix_ME - mOutputFile << "M_.Sigma_e = zeros(" << symbol_table.exo_nbr() << ", " - << symbol_table.exo_nbr() << ");" << endl + mOutputFile << "M_.Sigma_e = zeros(" << symbol_table.exo_nbr() << ", " << symbol_table.exo_nbr() + << ");" << endl << "M_.Correlation_matrix = eye(" << symbol_table.exo_nbr() << ", " << symbol_table.exo_nbr() << ");" << endl; @@ -873,13 +952,13 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, << "M_.Correlation_matrix_ME = eye(" << symbol_table.observedVariablesNbr() << ", " << symbol_table.observedVariablesNbr() << ");" << endl; else - mOutputFile << "M_.H = 0;" << endl - << "M_.Correlation_matrix_ME = 1;" << endl; + mOutputFile << "M_.H = 0;" << endl << "M_.Correlation_matrix_ME = 1;" << endl; // 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 M_.det_shocks, M_.surprise_shocks, M_.learnt_shocks, M_.learnt_endval and + // M_.heteroskedastic_shocks mOutputFile << "M_.det_shocks = [];" << endl << "M_.surprise_shocks = [];" << endl << "M_.learnt_shocks = [];" << endl @@ -888,28 +967,29 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, << "M_.heteroskedastic_shocks.Qscale_orig = [];" << endl; // NB: options_.{ramsey,discretionary}_policy should rather be fields of M_ - mOutputFile << boolalpha - << "options_.linear = " << linear << ";" << endl + mOutputFile << boolalpha << "options_.linear = " << linear << ";" << endl << "options_.block = " << block << ";" << endl << "options_.bytecode = " << bytecode << ";" << endl << "options_.use_dll = " << use_dll << ";" << endl << "options_.ramsey_policy = " << mod_file_struct.ramsey_model_present << ";" << endl - << "options_.discretionary_policy = " << mod_file_struct.discretionary_policy_present << ";" << endl; + << "options_.discretionary_policy = " << mod_file_struct.discretionary_policy_present + << ";" << endl; if (mod_file_struct.discretionary_policy_present) - mOutputFile << "M_.discretionary_orig_eq_nbr = " << original_model.equation_number() << ";" << endl; + mOutputFile << "M_.discretionary_orig_eq_nbr = " << original_model.equation_number() << ";" + << endl; if (parallel_local_files.size() > 0) { mOutputFile << "options_.parallel_info.local_files = {" << endl; - for (const auto ¶llel_local_file : parallel_local_files) + for (const auto& parallel_local_file : parallel_local_files) { size_t j = parallel_local_file.find_last_of(R"(/\)"); if (j == string::npos) mOutputFile << "'', '" << parallel_local_file << "';" << endl; else - mOutputFile << "'" << parallel_local_file.substr(0, j+1) << "', '" - << parallel_local_file.substr(j+1) << "';" << endl; + mOutputFile << "'" << parallel_local_file.substr(0, j + 1) << "', '" + << parallel_local_file.substr(j + 1) << "';" << endl; } mOutputFile << "};" << endl; } @@ -918,8 +998,7 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, { mOutputFile << "M_.nonzero_hessian_eqs = "; dynamic_model.printNonZeroHessianEquations(mOutputFile); - mOutputFile << ";" << endl - << "M_.hessian_eq_zero = isempty(M_.nonzero_hessian_eqs);" << endl; + mOutputFile << ";" << endl << "M_.hessian_eq_zero = isempty(M_.nonzero_hessian_eqs);" << endl; } if (!onlymodel) @@ -927,13 +1006,17 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, if (bytecode) mOutputFile << "if exist('bytecode') ~= 3" << endl - << " error('DYNARE: Can''t find bytecode DLL. Please compile it or remove the ''bytecode'' option.')" << endl + << " error('DYNARE: Can''t find bytecode DLL. Please compile it or remove the " + "''bytecode'' option.')" + << endl << "end" << endl; mOutputFile << "M_.eq_nbr = " << dynamic_model.equation_number() << ";" << endl << "M_.ramsey_orig_eq_nbr = " << mod_file_struct.ramsey_orig_eq_nbr << ";" << endl << "M_.ramsey_orig_endo_nbr = " << mod_file_struct.ramsey_orig_endo_nbr << ";" << endl - << "M_.set_auxiliary_variables = exist(['./+' M_.fname '/set_auxiliary_variables.m'], 'file') == 2;" << endl; + << "M_.set_auxiliary_variables = exist(['./+' M_.fname " + "'/set_auxiliary_variables.m'], 'file') == 2;" + << endl; epilogue.writeOutput(mOutputFile); @@ -949,11 +1032,11 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, } if (onlymodel || gui) - for (const auto &statement : statements) + for (const auto& statement : statements) { /* Special treatment for initval block: insert initial values for the auxiliary variables and initialize exo det */ - if (auto ivs = dynamic_cast(statement.get()); ivs) + if (auto ivs = dynamic_cast(statement.get()); ivs) { ivs->writeOutput(mOutputFile, basename, minimal_workspace); static_model.writeAuxVarInitval(mOutputFile, ExprNodeOutputType::matlabOutsideModel); @@ -961,81 +1044,100 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, } // Special treatment for endval block: insert initial values for the auxiliary variables - if (auto evs = dynamic_cast(statement.get()); evs) + if (auto evs = dynamic_cast(statement.get()); evs) { evs->writeOutput(mOutputFile, basename, minimal_workspace); static_model.writeAuxVarInitval(mOutputFile, ExprNodeOutputType::matlabOutsideModel); } - if (auto ips = dynamic_cast(statement.get()); ips) + if (auto ips = dynamic_cast(statement.get()); ips) ips->writeOutput(mOutputFile, basename, minimal_workspace); - if (auto ss = dynamic_cast(statement.get()); ss) + if (auto ss = dynamic_cast(statement.get()); ss) ss->writeOutput(mOutputFile, basename, minimal_workspace); - if (auto eps = dynamic_cast(statement.get()); eps) + if (auto eps = dynamic_cast(statement.get()); eps) eps->writeOutput(mOutputFile, basename, minimal_workspace); - if (auto sgs = dynamic_cast(statement.get()); sgs) + if (auto sgs = dynamic_cast(statement.get()); sgs) sgs->writeOutput(mOutputFile, basename, minimal_workspace); if (gui) - if (auto it = dynamic_cast(statement.get()); it) + if (auto it = dynamic_cast(statement.get()); it) it->writeOutput(mOutputFile, basename, minimal_workspace); } else { - for (const auto &statement : statements) + for (const auto& statement : statements) { statement->writeOutput(mOutputFile, basename, minimal_workspace); /* Special treatment for initval block: insert initial values for the auxiliary variables and initialize exo det */ - if (auto ivs = dynamic_cast(statement.get()); ivs) + if (auto ivs = dynamic_cast(statement.get()); ivs) { static_model.writeAuxVarInitval(mOutputFile, ExprNodeOutputType::matlabOutsideModel); ivs->writeOutputPostInit(mOutputFile); } // Special treatment for endval block: insert initial values for the auxiliary variables - if (auto evs = dynamic_cast(statement.get()); evs) + if (auto evs = dynamic_cast(statement.get()); evs) static_model.writeAuxVarInitval(mOutputFile, ExprNodeOutputType::matlabOutsideModel); - // Special treatment for load params and steady state statement: insert initial values for the auxiliary variables - if (auto lpass = dynamic_cast(statement.get()); lpass && !no_static) + // Special treatment for load params and steady state statement: insert initial values for + // the auxiliary variables + if (auto lpass = dynamic_cast(statement.get()); + lpass && !no_static) static_model.writeAuxVarInitval(mOutputFile, ExprNodeOutputType::matlabOutsideModel); } if (!notime) - mOutputFile << endl << endl - << "oo_.time = toc(tic0);" << endl - << "disp(['Total computing time : ' dynsec2hms(oo_.time) ]);" << endl; + mOutputFile << endl + << endl + << "oo_.time = toc(tic0);" << endl + << "disp(['Total computing time : ' dynsec2hms(oo_.time) ]);" << endl; mOutputFile << "if ~exist([M_.dname filesep 'Output'],'dir')" << endl << " mkdir(M_.dname,'Output');" << endl << "end" << endl - << "save([M_.dname filesep 'Output' filesep '" << basename << "_results.mat'], 'oo_', 'M_', 'options_');" << endl + << "save([M_.dname filesep 'Output' filesep '" << basename + << "_results.mat'], 'oo_', 'M_', 'options_');" << endl << "if exist('estim_params_', 'var') == 1" << endl - << " save([M_.dname filesep 'Output' filesep '" << basename << "_results.mat'], 'estim_params_', '-append');" << endl << "end" << endl + << " save([M_.dname filesep 'Output' filesep '" << basename + << "_results.mat'], 'estim_params_', '-append');" << endl + << "end" << endl << "if exist('bayestopt_', 'var') == 1" << endl - << " save([M_.dname filesep 'Output' filesep '" << basename << "_results.mat'], 'bayestopt_', '-append');" << endl << "end" << endl + << " save([M_.dname filesep 'Output' filesep '" << basename + << "_results.mat'], 'bayestopt_', '-append');" << endl + << "end" << endl << "if exist('dataset_', 'var') == 1" << endl - << " save([M_.dname filesep 'Output' filesep '" << basename << "_results.mat'], 'dataset_', '-append');" << endl << "end" << endl + << " save([M_.dname filesep 'Output' filesep '" << basename + << "_results.mat'], 'dataset_', '-append');" << endl + << "end" << endl << "if exist('estimation_info', 'var') == 1" << endl - << " save([M_.dname filesep 'Output' filesep '" << basename << "_results.mat'], 'estimation_info', '-append');" << endl << "end" << endl + << " save([M_.dname filesep 'Output' filesep '" << basename + << "_results.mat'], 'estimation_info', '-append');" << endl + << "end" << endl << "if exist('dataset_info', 'var') == 1" << endl - << " save([M_.dname filesep 'Output' filesep '" << basename << "_results.mat'], 'dataset_info', '-append');" << endl << "end" << endl + << " save([M_.dname filesep 'Output' filesep '" << basename + << "_results.mat'], 'dataset_info', '-append');" << endl + << "end" << endl << "if exist('oo_recursive_', 'var') == 1" << endl - << " save([M_.dname filesep 'Output' filesep '" << basename << "_results.mat'], 'oo_recursive_', '-append');" << endl << "end" << endl + << " save([M_.dname filesep 'Output' filesep '" << basename + << "_results.mat'], 'oo_recursive_', '-append');" << endl + << "end" << endl << "if exist('options_mom_', 'var') == 1" << endl - << " save([M_.dname filesep 'Output' filesep '" << basename << "_results.mat'], 'options_mom_', '-append');" << endl << "end" << endl; + << " save([M_.dname filesep 'Output' filesep '" << basename + << "_results.mat'], 'options_mom_', '-append');" << endl + << "end" << endl; config_file.writeEndParallel(mOutputFile); if (!no_warn) { if (warnings.countWarnings() > 0) - mOutputFile << "disp('Note: " << warnings.countWarnings() << " warning(s) encountered in the preprocessor')" << endl; + mOutputFile << "disp('Note: " << warnings.countWarnings() + << " warning(s) encountered in the preprocessor')" << endl; mOutputFile << "if ~isempty(lastwarn)" << endl << " disp('Note: warning(s) encountered in MATLAB/Octave code')" << endl @@ -1057,9 +1159,11 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, if (mod_file_struct.ramsey_model_present) { if (use_dll) - static_model.writeRamseyMultipliersDerivativesCFile(basename, mexext, matlabroot, mod_file_struct.ramsey_orig_endo_nbr); + static_model.writeRamseyMultipliersDerivativesCFile( + basename, mexext, matlabroot, mod_file_struct.ramsey_orig_endo_nbr); else - static_model.writeRamseyMultipliersDerivativesMFile(basename, mod_file_struct.ramsey_orig_endo_nbr); + static_model.writeRamseyMultipliersDerivativesMFile( + basename, mod_file_struct.ramsey_orig_endo_nbr); } } @@ -1079,7 +1183,7 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, } void -ModFile::writeJuliaOutput(const string &basename) const +ModFile::writeJuliaOutput(const string& basename) const { if (dynamic_model.equation_number() > 0) { @@ -1095,7 +1199,8 @@ ModFile::writeJuliaOutput(const string &basename) const } void -ModFile::writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple) +ModFile::writeJsonOutput(const string& basename, JsonOutputPointType json, + JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple) { if (json == JsonOutputPointType::nojson) return; @@ -1104,10 +1209,11 @@ ModFile::writeJsonOutput(const string &basename, JsonOutputPointType json, JsonF symbol_table.freeze(); if (json_output_mode == JsonFileOutputType::standardout) - cout << "//-- BEGIN JSON --// " << endl - << "{" << endl; + cout << "//-- BEGIN JSON --// " << endl << "{" << endl; - writeJsonOutputParsingCheck(basename, json_output_mode, json == JsonOutputPointType::transformpass, json == JsonOutputPointType::computingpass); + writeJsonOutputParsingCheck(basename, json_output_mode, + json == JsonOutputPointType::transformpass, + json == JsonOutputPointType::computingpass); if (json == JsonOutputPointType::parsing || json == JsonOutputPointType::checkpass) symbol_table.unfreeze(); @@ -1116,8 +1222,7 @@ ModFile::writeJsonOutput(const string &basename, JsonOutputPointType json, JsonF writeJsonComputingPassOutput(basename, json_output_mode, jsonderivsimple); if (json_output_mode == JsonFileOutputType::standardout) - cout << "}" << endl - << "//-- END JSON --// " << endl; + cout << "}" << endl << "//-- END JSON --// " << endl; switch (json) { @@ -1143,7 +1248,8 @@ ModFile::writeJsonOutput(const string &basename, JsonOutputPointType json, JsonF } void -ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType json_output_mode, bool transformpass, bool computingpass) const +ModFile::writeJsonOutputParsingCheck(const string& basename, JsonFileOutputType json_output_mode, + bool transformpass, bool computingpass) const { ostringstream output; output << "{" << endl; @@ -1154,9 +1260,7 @@ ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType output << ", "; static_model.writeJsonOutput(output); - if (!statements.empty() - || !var_model_table.empty() - || !trend_component_model_table.empty()) + if (!statements.empty() || !var_model_table.empty() || !trend_component_model_table.empty()) { output << R"(, "statements": [)"; if (!var_model_table.empty()) @@ -1183,8 +1287,7 @@ ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType output << ", "; } - for (bool printed_something{false}; - auto &it : statements) + for (bool printed_something {false}; auto& it : statements) { if (exchange(printed_something, true)) output << ", " << endl; @@ -1224,8 +1327,7 @@ ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType pac_model_table.writeJsonOutput(original_model_output); original_model_output << ", "; } - for (bool printed_something{false}; - const auto &it : statements) + for (bool printed_something {false}; const auto& it : statements) { original_model_output << (exchange(printed_something, true) ? "," : "") << endl; it->writeJsonOutput(original_model_output); @@ -1263,7 +1365,7 @@ ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType filesystem::create_directories(basename + "/model/json"); const filesystem::path fname {basename + "/model/json/modfile.json"}; - ofstream jsonOutputFile{fname, ios::out | ios::binary}; + ofstream jsonOutputFile {fname, ios::out | ios::binary}; if (!jsonOutputFile.is_open()) { cerr << "ERROR: Can't open file " << fname.string() << " for writing" << endl; @@ -1319,7 +1421,8 @@ ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType } void -ModFile::writeJsonComputingPassOutput(const string &basename, JsonFileOutputType json_output_mode, bool jsonderivsimple) const +ModFile::writeJsonComputingPassOutput(const string& basename, JsonFileOutputType json_output_mode, + bool jsonderivsimple) const { if (basename.empty() && json_output_mode != JsonFileOutputType::standardout) { @@ -1327,7 +1430,8 @@ ModFile::writeJsonComputingPassOutput(const string &basename, JsonFileOutputType exit(EXIT_FAILURE); } - ostringstream tmp_out, static_output, dynamic_output, static_paramsd_output, dynamic_paramsd_output; + ostringstream tmp_out, static_output, dynamic_output, static_paramsd_output, + dynamic_paramsd_output; static_output << "{"; static_model.writeJsonComputingPassOutput(static_output, !jsonderivsimple); @@ -1365,7 +1469,8 @@ ModFile::writeJsonComputingPassOutput(const string &basename, JsonFileOutputType writeJsonFileHelper(basename + "/model/json/dynamic.json", dynamic_output); if (!static_paramsd_output.str().empty()) - writeJsonFileHelper(basename + "/model/json/static_params_derivs.json", static_paramsd_output); + writeJsonFileHelper(basename + "/model/json/static_params_derivs.json", + static_paramsd_output); if (!dynamic_paramsd_output.str().empty()) writeJsonFileHelper(basename + "/model/json/params_derivs.json", dynamic_paramsd_output); @@ -1373,9 +1478,9 @@ ModFile::writeJsonComputingPassOutput(const string &basename, JsonFileOutputType } void -ModFile::writeJsonFileHelper(const filesystem::path &fname, ostringstream &output) const +ModFile::writeJsonFileHelper(const filesystem::path& fname, ostringstream& output) const { - ofstream jsonOutput{fname, ios::out | ios::binary}; + ofstream jsonOutput {fname, ios::out | ios::binary}; if (!jsonOutput.is_open()) { cerr << "ERROR: Can't open file " << fname.string() << " for writing" << endl; @@ -1392,12 +1497,12 @@ ModFile::unique_path() string possible_characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; random_device rd; mt19937 generator(rd()); - uniform_int_distribution distribution{0, static_cast(possible_characters.size())-1}; + uniform_int_distribution distribution {0, static_cast(possible_characters.size()) - 1}; do { constexpr int rand_length = 10; string rand_str(rand_length, '\0'); - for (auto &dis : rand_str) + for (auto& dis : rand_str) dis = possible_characters[distribution(generator)]; path = rand_str; } diff --git a/src/ModFile.hh b/src/ModFile.hh index 5e141d50..a2779525 100644 --- a/src/ModFile.hh +++ b/src/ModFile.hh @@ -20,24 +20,24 @@ #ifndef _MOD_FILE_HH #define _MOD_FILE_HH -#include #include -#include -#include #include +#include +#include +#include -#include "SymbolTable.hh" +#include "ConfigFile.hh" +#include "DynamicModel.hh" +#include "ExtendedPreprocessorTypes.hh" +#include "ExternalFunctionsTable.hh" +#include "ModelEquationBlock.hh" #include "NumericalConstants.hh" #include "NumericalInitialization.hh" -#include "StaticModel.hh" -#include "DynamicModel.hh" -#include "ModelEquationBlock.hh" #include "Statement.hh" -#include "ExternalFunctionsTable.hh" -#include "ConfigFile.hh" -#include "WarningConsolidation.hh" -#include "ExtendedPreprocessorTypes.hh" +#include "StaticModel.hh" #include "SubModel.hh" +#include "SymbolTable.hh" +#include "WarningConsolidation.hh" using namespace std; @@ -45,7 +45,7 @@ using namespace std; class ModFile { public: - explicit ModFile(WarningConsolidation &warnings_arg); + explicit ModFile(WarningConsolidation& warnings_arg); //! Symbol table SymbolTable symbol_table; //! External Functions table @@ -78,23 +78,24 @@ public: SteadyStateModel steady_state_model; //! Option linear - bool linear{false}; + bool linear {false}; //! Was the “block” option passed to the “model” block? - bool block{false}; + bool block {false}; //! Is the model stored in bytecode format (bytecode=true) or in a M-file (bytecode=false) - bool bytecode{false}; + bool bytecode {false}; /*! Is the model stored in a MEX file ? (option “use_dll”, either in the “model” block or on the preprocessor command line) */ - bool use_dll{false}; + bool use_dll {false}; - //! Is the static model have to computed (no_static=false) or not (no_static=true). Option of 'model' - bool no_static{false}; + //! Is the static model have to computed (no_static=false) or not (no_static=true). Option of + //! 'model' + bool no_static {false}; //! Is the 'differentiate_forward_vars' option used? - bool differentiate_forward_vars{false}; + bool differentiate_forward_vars {false}; /*! If the 'differentiate_forward_vars' option is used, contains the set of endogenous with respect to which to do the transformation; @@ -103,14 +104,14 @@ public: vector differentiate_forward_vars_subset; //! Are nonstationary variables present ? - bool nonstationary_variables{false}; + bool nonstationary_variables {false}; //! Global evaluation context /*! Filled using initval blocks and parameters initializations */ eval_context_t global_eval_context; //! Parameter used with lead/lag - bool param_used_with_lead_lag{false}; + bool param_used_with_lead_lag {false}; //! Stores the list of extra files to be transefered during a parallel run /*! (i.e. option parallel_local_files of model block) */ @@ -122,11 +123,13 @@ private: //! Structure of the mod file ModFileStructure mod_file_struct; //! Warnings Encountered - WarningConsolidation &warnings; + WarningConsolidation& warnings; //! Functions used in writing of JSON outut. See writeJsonOutput - void writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType json_output_mode, bool transformpass, bool computingpass) const; - void writeJsonComputingPassOutput(const string &basename, JsonFileOutputType json_output_mode, bool jsonderivsimple) const; - void writeJsonFileHelper(const filesystem::path &fname, ostringstream &output) const; + void writeJsonOutputParsingCheck(const string& basename, JsonFileOutputType json_output_mode, + bool transformpass, bool computingpass) const; + void writeJsonComputingPassOutput(const string& basename, JsonFileOutputType json_output_mode, + bool jsonderivsimple) const; + void writeJsonFileHelper(const filesystem::path& fname, ostringstream& output) const; /* Generate a random temporary path, in the current directory. Equivalent to boost::filesystem::unique_path(). Both are insecure, but currently there is no better portable solution. Maybe in a later C++ standard? */ @@ -137,14 +140,16 @@ private: same directory, otherwise it may fail if the destination is not on the same filesystem. This technique is applied recursively to subdirectories. Works even if the argument does not exist or is not a directory. */ - static void remove_directory_with_matlab_lock(const filesystem::path &dir); + static void remove_directory_with_matlab_lock(const filesystem::path& dir); + public: //! Add a statement void addStatement(unique_ptr st); //! Add a statement at the front of the statements vector void addStatementAtFront(unique_ptr st); //! Evaluate all the statements - /*! \param warn_uninit Should a warning be displayed for uninitialized endogenous/exogenous/parameters ? */ + /*! \param warn_uninit Should a warning be displayed for uninitialized + * endogenous/exogenous/parameters ? */ void evalAllExpressions(bool warn_uninit); //! Do some checking and fills mod_file_struct /*! \todo add check for number of equations and endogenous if ramsey_policy is present */ @@ -152,15 +157,16 @@ public: //! Perform some transformations on the model (creation of auxiliary vars and equations) /*! \param compute_xrefs if true, equation cross references will be computed */ void transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool transform_unary_ops, - const string &exclude_eqs, const string &include_eqs); + const string& exclude_eqs, const string& include_eqs); //! Execute computations - /*! \param no_tmp_terms if true, no temporary terms will be computed in the static and dynamic files */ + /*! \param no_tmp_terms if true, no temporary terms will be computed in the static and dynamic + * files */ /*! \param params_derivs_order compute this order of derivs wrt parameters */ void computingPass(bool no_tmp_terms, OutputType output, int params_derivs_order); //! Writes Matlab/Octave output files /*! - \param basename The base name used for writing output files. Should be the name of the mod file without its extension - \param clear_all Should a "clear all" instruction be written to output ? + \param basename The base name used for writing output files. Should be the name of the mod file + without its extension \param clear_all Should a "clear all" instruction be written to output ? \param console Are we in console mode ? \param nograph Should we build the figures? \param nointeractive Should Dynare request user input? @@ -169,20 +175,23 @@ public: \param mingw Should the MEX command of use_dll be adapted for MinGW? \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, + 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 check_model_changes, bool minimal_workspace, bool compute_xrefs, - const string &mexext, const filesystem::path &matlabroot, - bool onlymodel, bool gui, bool notime) const; + const string& mexext, const filesystem::path& matlabroot, bool onlymodel, + bool gui, bool notime) const; - void writeJuliaOutput(const string &basename) const; + void writeJuliaOutput(const string& basename) const; void computeChecksum(); //! Write JSON representation of ModFile object //! Initially created to enable Julia to work with .mod files - //! Potentially outputs ModFile after the various parts of processing (parsing, checkPass, transformPass, computingPass) - //! Allows user of other host language platforms (python, fortran, etc) to provide support for dynare .mod files - void writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple = false); + //! Potentially outputs ModFile after the various parts of processing (parsing, checkPass, + //! transformPass, computingPass) Allows user of other host language platforms (python, fortran, + //! etc) to provide support for dynare .mod files + void writeJsonOutput(const string& basename, JsonOutputPointType json, + JsonFileOutputType json_output_mode, bool onlyjson, + bool jsonderivsimple = false); }; #endif // ! MOD_FILE_HH diff --git a/src/ModelEquationBlock.cc b/src/ModelEquationBlock.cc index d2a0c1d8..a2f7a7ba 100644 --- a/src/ModelEquationBlock.cc +++ b/src/ModelEquationBlock.cc @@ -17,69 +17,67 @@ * along with Dynare. If not, see . */ -#include #include +#include #include #include "ModelEquationBlock.hh" -PlannerObjective::PlannerObjective(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg) : - StaticModel {symbol_table_arg, num_constants_arg, external_functions_table_arg} +PlannerObjective::PlannerObjective(SymbolTable& symbol_table_arg, + NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg) : + StaticModel {symbol_table_arg, num_constants_arg, external_functions_table_arg} { } void -PlannerObjective::computingPassBlock([[maybe_unused]] const eval_context_t &eval_context, +PlannerObjective::computingPassBlock([[maybe_unused]] const eval_context_t& eval_context, [[maybe_unused]] bool no_tmp_terms) { // Disable block decomposition on planner objective } -OrigRamseyDynamicModel::OrigRamseyDynamicModel(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg, - TrendComponentModelTable &trend_component_model_table_arg, - VarModelTable &var_model_table_arg) : - DynamicModel {symbol_table_arg, num_constants_arg, external_functions_table_arg, - trend_component_model_table_arg, var_model_table_arg} +OrigRamseyDynamicModel::OrigRamseyDynamicModel( + SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg, + TrendComponentModelTable& trend_component_model_table_arg, VarModelTable& var_model_table_arg) : + DynamicModel {symbol_table_arg, num_constants_arg, external_functions_table_arg, + trend_component_model_table_arg, var_model_table_arg} { } -OrigRamseyDynamicModel & -OrigRamseyDynamicModel::operator=(const DynamicModel &m) +OrigRamseyDynamicModel& +OrigRamseyDynamicModel::operator=(const DynamicModel& m) { DynamicModel::operator=(m); return *this; } -SteadyStateModel::SteadyStateModel(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg, - const StaticModel &static_model_arg) : - DataTree{symbol_table_arg, num_constants_arg, external_functions_table_arg}, - static_model{static_model_arg} +SteadyStateModel::SteadyStateModel(SymbolTable& symbol_table_arg, + NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg, + const StaticModel& static_model_arg) : + DataTree {symbol_table_arg, num_constants_arg, external_functions_table_arg}, + static_model {static_model_arg} { } -SteadyStateModel::SteadyStateModel(const SteadyStateModel &m) : - DataTree{m}, - static_model{m.static_model} +SteadyStateModel::SteadyStateModel(const SteadyStateModel& m) : + DataTree {m}, static_model {m.static_model} { - for (const auto &it : m.def_table) + for (const auto& it : m.def_table) def_table.emplace_back(it.first, it.second->clone(*this)); } -SteadyStateModel & -SteadyStateModel::operator=(const SteadyStateModel &m) +SteadyStateModel& +SteadyStateModel::operator=(const SteadyStateModel& m) { DataTree::operator=(m); assert(&static_model == &m.static_model); def_table.clear(); - for (const auto &it : m.def_table) + for (const auto& it : m.def_table) def_table.emplace_back(it.first, it.second->clone(*this)); return *this; @@ -95,12 +93,12 @@ SteadyStateModel::addDefinition(int symb_id, expr_t expr) || symbol_table.getType(symb_id) == SymbolType::parameter); // Add the variable - vector v{symb_id}; + vector v {symb_id}; def_table.emplace_back(v, expr); } void -SteadyStateModel::addMultipleDefinitions(const vector &symb_ids, expr_t expr) +SteadyStateModel::addMultipleDefinitions(const vector& symb_ids, expr_t expr) { for (int symb_id : symb_ids) { @@ -113,7 +111,7 @@ SteadyStateModel::addMultipleDefinitions(const vector &symb_ids, expr_t exp } void -SteadyStateModel::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) const +SteadyStateModel::checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) const { if (def_table.size() == 0) return; @@ -121,12 +119,13 @@ SteadyStateModel::checkPass(ModFileStructure &mod_file_struct, WarningConsolidat mod_file_struct.steady_state_model_present = true; set so_far_defined; - for (const auto &[symb_ids, expr] : def_table) + for (const auto& [symb_ids, expr] : def_table) { // Check that symbols are not already defined for (int symb_id : symb_ids) if (so_far_defined.contains(symb_id)) - warnings << "WARNING: in the 'steady_state_model' block, variable '" << symbol_table.getName(symb_id) << "' is declared twice" << endl; + warnings << "WARNING: in the 'steady_state_model' block, variable '" + << symbol_table.getName(symb_id) << "' is declared twice" << endl; // Check that expression has no undefined symbol if (!mod_file_struct.ramsey_model_present) @@ -137,8 +136,10 @@ SteadyStateModel::checkPass(ModFileStructure &mod_file_struct, WarningConsolidat for (int used_symbol : used_symbols) if (!so_far_defined.contains(used_symbol)) { - cerr << "ERROR: in the 'steady_state_model' block, variable '" << symbol_table.getName(used_symbol) - << "' is undefined in the declaration of variable '" << symbol_table.getName(symb_ids[0]) << "'" << endl; + cerr << "ERROR: in the 'steady_state_model' block, variable '" + << symbol_table.getName(used_symbol) + << "' is undefined in the declaration of variable '" + << symbol_table.getName(symb_ids[0]) << "'" << endl; exit(EXIT_FAILURE); } } @@ -151,29 +152,30 @@ SteadyStateModel::checkPass(ModFileStructure &mod_file_struct, WarningConsolidat *conditional* to those instruments) */ set should_be_defined = symbol_table.getOrigEndogenous(); if (mod_file_struct.ramsey_model_present) - for (const auto &s : mod_file_struct.instruments.getSymbols()) + for (const auto& s : mod_file_struct.instruments.getSymbols()) should_be_defined.erase(symbol_table.getID(s)); for (int v : should_be_defined) if (!so_far_defined.contains(v)) - warnings << "WARNING: in the 'steady_state_model' block, variable '" << symbol_table.getName(v) << "' is not assigned a value" << endl; + warnings << "WARNING: in the 'steady_state_model' block, variable '" + << symbol_table.getName(v) << "' is not assigned a value" << endl; } void -SteadyStateModel::writeLatexSteadyStateFile(const string &basename) const +SteadyStateModel::writeLatexSteadyStateFile(const string& basename) const { filesystem::create_directories(basename + "/latex"); const filesystem::path filename {basename + "/latex/steady_state.tex"}, - content_filename {basename + "/latex/steady_state_content.tex"}; + content_filename {basename + "/latex/steady_state_content.tex"}; - ofstream output{filename, ios::out | ios::binary}; + ofstream output {filename, ios::out | ios::binary}; if (!output.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; exit(EXIT_FAILURE); } - ofstream content_output{content_filename, ios::out | ios::binary}; + ofstream content_output {content_filename, ios::out | ios::binary}; if (!content_output.is_open()) { cerr << "ERROR: Can't open file " << content_filename.string() << " for writing" << endl; @@ -188,31 +190,30 @@ SteadyStateModel::writeLatexSteadyStateFile(const string &basename) const << "\\begin{document}" << endl << "\\footnotesize" << endl; - for (const auto & [ids, value] : def_table) + for (const auto& [ids, value] : def_table) for (int id : ids) { - content_output << "\\begin{dmath}" << endl - << symbol_table.getTeXName(id) << " = "; + content_output << "\\begin{dmath}" << endl << symbol_table.getTeXName(id) << " = "; value->writeOutput(content_output, ExprNodeOutputType::latexStaticModel); content_output << endl << "\\end{dmath}" << endl; } static_model.writeLatexAuxVarRecursiveDefinitions(content_output); - output << "\\include{steady_state_content.tex}" << endl - << "\\end{document}" << endl; + output << "\\include{steady_state_content.tex}" << endl << "\\end{document}" << endl; output.close(); content_output.close(); } void -SteadyStateModel::writeSteadyStateFile(const string &basename, bool julia) const +SteadyStateModel::writeSteadyStateFile(const string& basename, bool julia) const { if (def_table.size() == 0) return; - ExprNodeOutputType output_type = (julia ? ExprNodeOutputType::juliaSteadyStateFile : ExprNodeOutputType::steadyStateFile); + ExprNodeOutputType output_type + = (julia ? ExprNodeOutputType::juliaSteadyStateFile : ExprNodeOutputType::steadyStateFile); stringstream output; if (!julia) @@ -226,9 +227,9 @@ SteadyStateModel::writeSteadyStateFile(const string &basename, bool julia) const << "#" << endl << "function steady_state!(ys_::Vector{<: Real}, exo_::Vector{<: Real}, " << "params::Vector{<: Real})" << endl - << "@inbounds begin" << endl; + << "@inbounds begin" << endl; - for (const auto & [symb_ids, value] : def_table) + for (const auto& [symb_ids, value] : def_table) { output << " "; if (symb_ids.size() > 1) @@ -236,7 +237,7 @@ SteadyStateModel::writeSteadyStateFile(const string &basename, bool julia) const for (size_t j = 0; j < symb_ids.size(); j++) { getVariable(symb_ids[j])->ExprNode::writeOutput(output, output_type); - if (j < symb_ids.size()-1) + if (j < symb_ids.size() - 1) output << ","; } if (symb_ids.size() > 1) @@ -257,13 +258,14 @@ SteadyStateModel::writeSteadyStateFile(const string &basename, bool julia) const output << "end" << endl; if (julia) - writeToFileIfModified(output, filesystem::path{basename} / "model" / "julia" / "SteadyState2.jl"); + writeToFileIfModified(output, + filesystem::path {basename} / "model" / "julia" / "SteadyState2.jl"); else { /* Calling writeToFileIfModified() is useless here since we write inside a subdirectory deleted at each preprocessor run. */ filesystem::path filename {packageDir(basename) / "steadystate.m"}; - ofstream output_file{filename, ios::out | ios::binary}; + ofstream output_file {filename, ios::out | ios::binary}; if (!output_file.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; @@ -275,7 +277,7 @@ SteadyStateModel::writeSteadyStateFile(const string &basename, bool julia) const } void -SteadyStateModel::writeJsonSteadyStateFile(ostream &output, bool transformComputingPass) const +SteadyStateModel::writeJsonSteadyStateFile(ostream& output, bool transformComputingPass) const { if (def_table.size() == 0) return; @@ -284,16 +286,14 @@ SteadyStateModel::writeJsonSteadyStateFile(ostream &output, bool transformComput output << "{\"steady_state_model\": ["; - for (bool printed_something{false}; - const auto &[symb_ids, value] : def_table) + for (bool printed_something {false}; const auto& [symb_ids, value] : def_table) { if (exchange(printed_something, true)) output << ","; output << "{\"lhs\": "; if (symb_ids.size() > 1) output << "["; - for (bool printed_something2{false}; - int symb_id : symb_ids) + for (bool printed_something2 {false}; int symb_id : symb_ids) { if (exchange(printed_something2, true)) output << ","; @@ -314,30 +314,28 @@ SteadyStateModel::writeJsonSteadyStateFile(ostream &output, bool transformComput output << "]}"; } -Epilogue::Epilogue(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg, - TrendComponentModelTable &trend_component_model_table_arg, - VarModelTable &var_model_table_arg) : - DynamicModel{symbol_table_arg, num_constants_arg, external_functions_table_arg, - trend_component_model_table_arg, var_model_table_arg} +Epilogue::Epilogue(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg, + TrendComponentModelTable& trend_component_model_table_arg, + VarModelTable& var_model_table_arg) : + DynamicModel {symbol_table_arg, num_constants_arg, external_functions_table_arg, + trend_component_model_table_arg, var_model_table_arg} { } -Epilogue::Epilogue(const Epilogue &m) : - DynamicModel{m} +Epilogue::Epilogue(const Epilogue& m) : DynamicModel {m} { - for (const auto &it : m.dynamic_def_table) + for (const auto& it : m.dynamic_def_table) dynamic_def_table.emplace_back(it.first, it.second->clone(*this)); } -Epilogue & -Epilogue::operator=(const Epilogue &m) +Epilogue& +Epilogue::operator=(const Epilogue& m) { DynamicModel::operator=(m); dynamic_def_table.clear(); - for (const auto &it : m.dynamic_def_table) + for (const auto& it : m.dynamic_def_table) dynamic_def_table.emplace_back(it.first, it.second->clone(*this)); return *this; @@ -350,20 +348,22 @@ Epilogue::addDefinition(int symb_id, expr_t expr) } void -Epilogue::checkPass(ModFileStructure &mod_file_struct) const +Epilogue::checkPass(ModFileStructure& mod_file_struct) const { if (dynamic_def_table.size() == 0) { if (mod_file_struct.with_epilogue_option) { - cerr << "ERROR: the 'with_epilogue' option cannot be specified when there is no 'epilogue' block" << endl; + cerr << "ERROR: the 'with_epilogue' option cannot be specified when there is no " + "'epilogue' block" + << endl; exit(EXIT_FAILURE); } return; } set so_far_defined; - for (const auto &[symb_id, expr] : dynamic_def_table) + for (const auto& [symb_id, expr] : dynamic_def_table) if (so_far_defined.contains(symb_id)) { cerr << "WARNING: in the 'epilogue' block, variable '" << symbol_table.getName(symb_id) @@ -377,29 +377,28 @@ Epilogue::checkPass(ModFileStructure &mod_file_struct) const void Epilogue::toStatic() { - for (const auto & [symb_id, expr] : dynamic_def_table) + for (const auto& [symb_id, expr] : dynamic_def_table) static_def_table.emplace_back(symb_id, expr->toStatic(*this)); } void -Epilogue::detrend(const map &trend_symbols_map, - const nonstationary_symbols_map_t &nonstationary_symbols_map) +Epilogue::detrend(const map& trend_symbols_map, + const nonstationary_symbols_map_t& nonstationary_symbols_map) { - for (auto it = nonstationary_symbols_map.crbegin(); - it != nonstationary_symbols_map.crend(); ++it) - for (auto & [symb_id, expr] : dynamic_def_table) + for (auto it = nonstationary_symbols_map.crbegin(); it != nonstationary_symbols_map.crend(); ++it) + for (auto& [symb_id, expr] : dynamic_def_table) { expr = expr->detrend(it->first, it->second.first, it->second.second); assert(expr); } - for (auto & [symb_id, expr] : dynamic_def_table) + for (auto& [symb_id, expr] : dynamic_def_table) { expr = expr->removeTrendLeadLag(trend_symbols_map); assert(expr); } - for (auto & [symb_id, expr] : dynamic_def_table) + for (auto& [symb_id, expr] : dynamic_def_table) { expr = expr->replaceTrendVar(); assert(expr); @@ -407,7 +406,7 @@ Epilogue::detrend(const map &trend_symbols_map, } void -Epilogue::writeEpilogueFile(const string &basename) const +Epilogue::writeEpilogueFile(const string& basename) const { if (dynamic_def_table.empty()) return; @@ -417,10 +416,10 @@ Epilogue::writeEpilogueFile(const string &basename) const } void -Epilogue::writeStaticEpilogueFile(const string &basename) const +Epilogue::writeStaticEpilogueFile(const string& basename) const { filesystem::path filename {packageDir(basename) / "epilogue_static.m"}; - ofstream output{filename, ios::out | ios::binary}; + ofstream output {filename, ios::out | ios::binary}; if (!output.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; @@ -431,23 +430,27 @@ Epilogue::writeStaticEpilogueFile(const string &basename) const << "% function ds = epilogue_static(params, ds)" << endl << "% Epilogue file generated by Dynare preprocessor" << endl; - for (const auto & [symb_id, expr] : static_def_table) + for (const auto& [symb_id, expr] : static_def_table) { - // Rewrite external function TEF term for every equation as argument values could have been changed - // in between two calls to the same function; + // Rewrite external function TEF term for every equation as argument values could have been + // changed in between two calls to the same function; deriv_node_temp_terms_t tef_terms; temporary_terms_t temporary_terms; temporary_terms_idxs_t temporary_terms_idxs; output << endl; if (expr->containsExternalFunction()) - expr->writeExternalFunctionOutput(output, ExprNodeOutputType::matlabDseries, temporary_terms, temporary_terms_idxs, tef_terms); + expr->writeExternalFunctionOutput(output, ExprNodeOutputType::matlabDseries, + temporary_terms, temporary_terms_idxs, tef_terms); output << "epilogue_static_tmp_term = "; - expr->writeOutput(output, ExprNodeOutputType::matlabDseries, temporary_terms, temporary_terms_idxs, tef_terms); + expr->writeOutput(output, ExprNodeOutputType::matlabDseries, temporary_terms, + temporary_terms_idxs, tef_terms); output << ";" << endl << "if isdseries(epilogue_static_tmp_term)" << endl << " ds." << symbol_table.getName(symb_id) << " = epilogue_static_tmp_term;" << endl << "else" << endl - << " ds." << symbol_table.getName(symb_id) << " = dseries(ones(ds.nobs,1)*epilogue_static_tmp_term, ds.firstdate, '" << symbol_table.getName(symb_id) << "');" << endl + << " ds." << symbol_table.getName(symb_id) + << " = dseries(ones(ds.nobs,1)*epilogue_static_tmp_term, ds.firstdate, '" + << symbol_table.getName(symb_id) << "');" << endl << "end" << endl; } output << "end" << endl; @@ -455,10 +458,10 @@ Epilogue::writeStaticEpilogueFile(const string &basename) const } void -Epilogue::writeDynamicEpilogueFile(const string &basename) const +Epilogue::writeDynamicEpilogueFile(const string& basename) const { filesystem::path filename {packageDir(basename) / "epilogue_dynamic.m"}; - ofstream output{filename, ios::out | ios::binary}; + ofstream output {filename, ios::out | ios::binary}; if (!output.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; @@ -467,13 +470,14 @@ Epilogue::writeDynamicEpilogueFile(const string &basename) const output << "function ds = epilogue_dynamic(params, ds)" << endl << "% function ds = epilogue_dynamic(params, ds)" << endl - << "% Epilogue file generated by Dynare preprocessor" << endl << endl + << "% Epilogue file generated by Dynare preprocessor" << endl + << endl << "simul_end_date = lastdate(ds);" << endl; deriv_node_temp_terms_t tef_terms; temporary_terms_t temporary_terms; temporary_terms_idxs_t temporary_terms_idxs; - for (const auto & [symb_id, expr] : dynamic_def_table) + for (const auto& [symb_id, expr] : dynamic_def_table) { int max_lag = expr->maxLagWithDiffsExpanded(); set used_symbols; @@ -483,12 +487,12 @@ Epilogue::writeDynamicEpilogueFile(const string &basename) const output << endl << "if ~ds.exist('" << symbol_table.getName(symb_id) << "')" << endl - << " ds = [ds dseries(NaN(ds.nobs,1), ds.firstdate, '" << symbol_table.getName(symb_id)<< "')];" << endl + << " ds = [ds dseries(NaN(ds.nobs,1), ds.firstdate, '" + << symbol_table.getName(symb_id) << "')];" << endl << "end" << endl << "try" << endl << " simul_begin_date = firstobservedperiod(ds{"; - for (bool printed_something{false}; - int symb_id : used_symbols) + for (bool printed_something {false}; int symb_id : used_symbols) { if (exchange(printed_something, true)) output << ", "; @@ -497,43 +501,40 @@ Epilogue::writeDynamicEpilogueFile(const string &basename) const output << "}) + " << max_lag << ";" << endl << " from simul_begin_date to simul_end_date do " << "ds." << symbol_table.getName(symb_id) << "(t) = "; - expr->writeOutput(output, ExprNodeOutputType::epilogueFile, temporary_terms, temporary_terms_idxs, tef_terms); - output << ";" << endl - << "catch" << endl - << "end" << endl; + expr->writeOutput(output, ExprNodeOutputType::epilogueFile, temporary_terms, + temporary_terms_idxs, tef_terms); + output << ";" << endl << "catch" << endl << "end" << endl; } output << "end" << endl; output.close(); } void -Epilogue::writeOutput(ostream &output) const +Epilogue::writeOutput(ostream& output) const { if (dynamic_def_table.empty()) { - output << "M_.epilogue_names = {};" << endl - << "M_.epilogue_var_list_ = {};" << endl; + output << "M_.epilogue_names = {};" << endl << "M_.epilogue_var_list_ = {};" << endl; return; } output << "M_.epilogue_names = cell(" << dynamic_def_table.size() << ",1);" << endl; - for (int idx{1}; - const auto &[symb_id, expr] : dynamic_def_table) - output << "M_.epilogue_names{" << idx++ << "} = '" - << symbol_table.getName(symb_id) << "';" << endl; + for (int idx {1}; const auto& [symb_id, expr] : dynamic_def_table) + output << "M_.epilogue_names{" << idx++ << "} = '" << symbol_table.getName(symb_id) << "';" + << endl; set endogs; - for (const auto & [symb_id, expr] : dynamic_def_table) + for (const auto& [symb_id, expr] : dynamic_def_table) expr->collectVariables(SymbolType::endogenous, endogs); vector symbol_list; for (auto symb_id : endogs) symbol_list.push_back(symbol_table.getName(symb_id)); - SymbolList{move(symbol_list)}.writeOutput("M_.epilogue_var_list_", output); + SymbolList {move(symbol_list)}.writeOutput("M_.epilogue_var_list_", output); } void -Epilogue::computingPassBlock([[maybe_unused]] const eval_context_t &eval_context, +Epilogue::computingPassBlock([[maybe_unused]] const eval_context_t& eval_context, [[maybe_unused]] bool no_tmp_terms) { // Disable block decomposition on epilogue blocks diff --git a/src/ModelEquationBlock.hh b/src/ModelEquationBlock.hh index 8efe6aaf..d7931aae 100644 --- a/src/ModelEquationBlock.hh +++ b/src/ModelEquationBlock.hh @@ -21,17 +21,17 @@ #define _MODEL_EQUATION_BLOCK_HH #include "DataTree.hh" +#include "DynamicModel.hh" #include "Statement.hh" #include "StaticModel.hh" -#include "DynamicModel.hh" #include "WarningConsolidation.hh" class PlannerObjective : public StaticModel { public: - PlannerObjective(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg); + PlannerObjective(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg); + protected: string modelClassName() const override @@ -40,18 +40,17 @@ protected: } private: - void computingPassBlock(const eval_context_t &eval_context, bool no_tmp_terms) override; + void computingPassBlock(const eval_context_t& eval_context, bool no_tmp_terms) override; }; class OrigRamseyDynamicModel : public DynamicModel { public: - OrigRamseyDynamicModel(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg, - TrendComponentModelTable &trend_component_model_table_arg, - VarModelTable &var_model_table_arg); - OrigRamseyDynamicModel &operator=(const DynamicModel &m); + OrigRamseyDynamicModel(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg, + TrendComponentModelTable& trend_component_model_table_arg, + VarModelTable& var_model_table_arg); + OrigRamseyDynamicModel& operator=(const DynamicModel& m); protected: string @@ -64,71 +63,73 @@ protected: class SteadyStateModel : public DataTree { private: - //! Associates a set of symbol IDs (the variable(s) assigned in a given statement) to an expression (their assigned value) + //! Associates a set of symbol IDs (the variable(s) assigned in a given statement) to an + //! expression (their assigned value) vector, expr_t>> def_table; //! Reference to static model (for writing auxiliary equations) - const StaticModel &static_model; + const StaticModel& static_model; public: - SteadyStateModel(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg, - const StaticModel &static_model_arg); + SteadyStateModel(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg, + const StaticModel& static_model_arg); - SteadyStateModel(const SteadyStateModel &m); - SteadyStateModel &operator=(const SteadyStateModel &m); + SteadyStateModel(const SteadyStateModel& m); + SteadyStateModel& operator=(const SteadyStateModel& m); //! Add an expression of the form "var = expr;" void addDefinition(int symb_id, expr_t expr); //! Add an expression of the form "[ var1, var2, ... ] = expr;" - void addMultipleDefinitions(const vector &symb_ids, expr_t expr); + void addMultipleDefinitions(const vector& symb_ids, expr_t expr); //! Checks that definitions are in a recursive order, and that no variable is declared twice /*! - \param[in] ramsey_model Is there a Ramsey model in the MOD file? If yes, then disable the check on the recursivity of the declarations + \param[in] ramsey_model Is there a Ramsey model in the MOD file? If yes, then disable the check + on the recursivity of the declarations */ - void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) const; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) const; //! Write the steady state file - void writeSteadyStateFile(const string &basename, bool julia) const; + void writeSteadyStateFile(const string& basename, bool julia) const; //! Writes LaTeX file with the equations of the dynamic model (for the steady state model) - void writeLatexSteadyStateFile(const string &basename) const; + void writeLatexSteadyStateFile(const string& basename) const; //! Writes JSON output - void writeJsonSteadyStateFile(ostream &output, bool transformComputingPass) const; + void writeJsonSteadyStateFile(ostream& output, bool transformComputingPass) const; }; class Epilogue : public DynamicModel { private: - //! Associates a symbol ID (the variable assigned in a given statement) to an expression (its assigned value) + //! Associates a symbol ID (the variable assigned in a given statement) to an expression (its + //! assigned value) vector> dynamic_def_table, static_def_table; -public: - Epilogue(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg, - TrendComponentModelTable &trend_component_model_table_arg, - VarModelTable &var_model_table_arg); - Epilogue(const Epilogue &m); - Epilogue &operator=(const Epilogue &m); +public: + Epilogue(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg, + TrendComponentModelTable& trend_component_model_table_arg, + VarModelTable& var_model_table_arg); + + Epilogue(const Epilogue& m); + Epilogue& operator=(const Epilogue& m); //! Add an expression of the form "var = expr;" void addDefinition(int symb_id, expr_t expr); //! Checks that no variable is declared twice, and that “with_epilogue” is not misused - void checkPass(ModFileStructure &mod_file_struct) const; + void checkPass(ModFileStructure& mod_file_struct) const; //! Creates static epilogue equations void toStatic(); //! Deal with trend variables in the epilogue block - void detrend(const map &trend_symbols_map, - const nonstationary_symbols_map_t &nonstationary_symbols_map); + void detrend(const map& trend_symbols_map, + const nonstationary_symbols_map_t& nonstationary_symbols_map); //! Write the steady state file - void writeEpilogueFile(const string &basename) const; + void writeEpilogueFile(const string& basename) const; //! Write Output - void writeOutput(ostream &output) const; + void writeOutput(ostream& output) const; protected: string @@ -139,9 +140,9 @@ protected: private: //! Helper for public writeEpilogueFile - void writeStaticEpilogueFile(const string &basename) const; - void writeDynamicEpilogueFile(const string &basename) const; - void computingPassBlock(const eval_context_t &eval_context, bool no_tmp_terms) override; + void writeStaticEpilogueFile(const string& basename) const; + void writeDynamicEpilogueFile(const string& basename) const; + void computingPassBlock(const eval_context_t& eval_context, bool no_tmp_terms) override; }; #endif diff --git a/src/ModelTree.cc b/src/ModelTree.cc index d02438a8..6710c2bc 100644 --- a/src/ModelTree.cc +++ b/src/ModelTree.cc @@ -33,9 +33,9 @@ # include #endif +#include #include #include -#include /* NB: The workers must be listed *after* all the other static variables related to MEX compilation, so that when the preprocessor exits, the workers @@ -44,141 +44,139 @@ condition_variable_any ModelTree::mex_compilation_cv; mutex ModelTree::mex_compilation_mut; vector, string>> ModelTree::mex_compilation_queue; -set ModelTree::mex_compilation_ongoing, ModelTree::mex_compilation_done, ModelTree::mex_compilation_failed; +set ModelTree::mex_compilation_ongoing, ModelTree::mex_compilation_done, + ModelTree::mex_compilation_failed; vector ModelTree::mex_compilation_workers; void -ModelTree::copyHelper(const ModelTree &m) +ModelTree::copyHelper(const ModelTree& m) { auto f = [this](expr_t e) { return e->clone(*this); }; // Equations - for (const auto &it : m.equations) - equations.push_back(dynamic_cast(f(it))); - for (const auto &it : m.aux_equations) - aux_equations.push_back(dynamic_cast(f(it))); + for (const auto& it : m.equations) + equations.push_back(dynamic_cast(f(it))); + for (const auto& it : m.aux_equations) + aux_equations.push_back(dynamic_cast(f(it))); - auto convert_deriv_map = [f](const map, expr_t> &dm) - { - map, expr_t> dm2; - for (const auto &it : dm) - dm2.emplace(it.first, f(it.second)); - return dm2; - }; + auto convert_deriv_map = [f](const map, expr_t>& dm) { + map, expr_t> dm2; + for (const auto& it : dm) + dm2.emplace(it.first, f(it.second)); + return dm2; + }; // Derivatives - for (const auto &it : m.derivatives) + for (const auto& it : m.derivatives) derivatives.push_back(convert_deriv_map(it)); - for (const auto &it : m.params_derivatives) + for (const auto& it : m.params_derivatives) params_derivatives.emplace(it.first, convert_deriv_map(it.second)); - for (const auto &it : m.jacobian_sparse_column_major_order) + for (const auto& it : m.jacobian_sparse_column_major_order) jacobian_sparse_column_major_order.emplace(it.first, f(it.second)); - auto convert_temporary_terms_t = [f](const temporary_terms_t &tt) - { - temporary_terms_t tt2; - for (const auto &it : tt) - tt2.insert(f(it)); - return tt2; - }; + auto convert_temporary_terms_t = [f](const temporary_terms_t& tt) { + temporary_terms_t tt2; + for (const auto& it : tt) + tt2.insert(f(it)); + return tt2; + }; // Temporary terms - for (const auto &it : m.temporary_terms_derivatives) + for (const auto& it : m.temporary_terms_derivatives) temporary_terms_derivatives.push_back(convert_temporary_terms_t(it)); - for (const auto &it : m.temporary_terms_idxs) + for (const auto& it : m.temporary_terms_idxs) temporary_terms_idxs.emplace(f(it.first), it.second); - for (const auto &it : m.params_derivs_temporary_terms) + for (const auto& it : m.params_derivs_temporary_terms) params_derivs_temporary_terms.emplace(it.first, convert_temporary_terms_t(it.second)); - for (const auto &it : m.params_derivs_temporary_terms_idxs) + for (const auto& it : m.params_derivs_temporary_terms_idxs) params_derivs_temporary_terms_idxs.emplace(f(it.first), it.second); // Other stuff - for (const auto &it : m.trend_symbols_map) + for (const auto& it : m.trend_symbols_map) trend_symbols_map.emplace(it.first, f(it.second)); - for (const auto &it : m.nonstationary_symbols_map) - nonstationary_symbols_map.emplace(it.first, pair{it.second.first, f(it.second.second)}); + for (const auto& it : m.nonstationary_symbols_map) + nonstationary_symbols_map.emplace(it.first, pair {it.second.first, f(it.second.second)}); - for (const auto &it : m.equation_type_and_normalized_equation) - equation_type_and_normalized_equation.emplace_back(it.first, dynamic_cast(f(it.second))); + for (const auto& it : m.equation_type_and_normalized_equation) + equation_type_and_normalized_equation.emplace_back(it.first, + dynamic_cast(f(it.second))); - for (const auto &it : m.blocks_derivatives) + for (const auto& it : m.blocks_derivatives) { map, expr_t> v; - for (const auto &it2 : it) + for (const auto& it2 : it) v.emplace(it2.first, f(it2.second)); blocks_derivatives.push_back(v); } - auto convert_vector_tt = [f](vector vtt) - { - vector vtt2; - for (const auto &tt : vtt) - { - temporary_terms_t tt2; - for (const auto &it : tt) - tt2.insert(f(it)); - vtt2.push_back(tt2); - } - return vtt2; - }; - for (const auto &it : m.blocks_temporary_terms) + auto convert_vector_tt = [f](vector vtt) { + vector vtt2; + for (const auto& tt : vtt) + { + temporary_terms_t tt2; + for (const auto& it : tt) + tt2.insert(f(it)); + vtt2.push_back(tt2); + } + return vtt2; + }; + for (const auto& it : m.blocks_temporary_terms) blocks_temporary_terms.push_back(convert_vector_tt(it)); - for (const auto &it : m.blocks_temporary_terms_idxs) + for (const auto& it : m.blocks_temporary_terms_idxs) blocks_temporary_terms_idxs.emplace(f(it.first), it.second); - for (const auto &it : m.blocks_jacobian_sparse_column_major_order) + for (const auto& it : m.blocks_jacobian_sparse_column_major_order) { map, expr_t, columnMajorOrderLess> v; - for (const auto &it2 : it) + for (const auto& it2 : it) v.emplace(it2.first, f(it2.second)); blocks_jacobian_sparse_column_major_order.push_back(v); } } -ModelTree::ModelTree(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg, - bool is_dynamic_arg) : - DataTree{symbol_table_arg, num_constants_arg, external_functions_table_arg, is_dynamic_arg}, - derivatives(4), - NNZDerivatives(4, 0), - temporary_terms_derivatives(4) +ModelTree::ModelTree(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg, bool is_dynamic_arg) : + DataTree {symbol_table_arg, num_constants_arg, external_functions_table_arg, is_dynamic_arg}, + derivatives(4), + NNZDerivatives(4, 0), + temporary_terms_derivatives(4) { // Ensure that elements accessed by writeParamsDerivativesFileHelper() exist - for (const auto &ord : {pair{0, 1}, pair{1, 1}, pair{0, 2}, pair{1, 2}, pair{2, 1}, pair{3, 1}}) + for (const auto& ord : + {pair {0, 1}, pair {1, 1}, pair {0, 2}, pair {1, 2}, pair {2, 1}, pair {3, 1}}) params_derivatives.try_emplace(ord); } -ModelTree::ModelTree(const ModelTree &m) : - DataTree{m}, - user_set_add_flags{m.user_set_add_flags}, - user_set_subst_flags{m.user_set_subst_flags}, - user_set_add_libs{m.user_set_add_libs}, - user_set_subst_libs{m.user_set_subst_libs}, - user_set_compiler{m.user_set_compiler}, - equations_lineno{m.equations_lineno}, - equation_tags{m.equation_tags}, - computed_derivs_order{m.computed_derivs_order}, - NNZDerivatives{m.NNZDerivatives}, - jacobian_sparse_colptr{m.jacobian_sparse_colptr}, - eq_idx_block2orig{m.eq_idx_block2orig}, - endo_idx_block2orig{m.endo_idx_block2orig}, - eq_idx_orig2block{m.eq_idx_orig2block}, - endo_idx_orig2block{m.endo_idx_orig2block}, - block_decomposed{m.block_decomposed}, - time_recursive_block_decomposition{m.time_recursive_block_decomposition}, - blocks{m.blocks}, - endo2block{m.endo2block}, - eq2block{m.eq2block}, - blocks_jacobian_sparse_colptr{m.blocks_jacobian_sparse_colptr}, - endo2eq{m.endo2eq}, - cutoff{m.cutoff} +ModelTree::ModelTree(const ModelTree& m) : + DataTree {m}, + user_set_add_flags {m.user_set_add_flags}, + user_set_subst_flags {m.user_set_subst_flags}, + user_set_add_libs {m.user_set_add_libs}, + user_set_subst_libs {m.user_set_subst_libs}, + user_set_compiler {m.user_set_compiler}, + equations_lineno {m.equations_lineno}, + equation_tags {m.equation_tags}, + computed_derivs_order {m.computed_derivs_order}, + NNZDerivatives {m.NNZDerivatives}, + jacobian_sparse_colptr {m.jacobian_sparse_colptr}, + eq_idx_block2orig {m.eq_idx_block2orig}, + endo_idx_block2orig {m.endo_idx_block2orig}, + eq_idx_orig2block {m.eq_idx_orig2block}, + endo_idx_orig2block {m.endo_idx_orig2block}, + block_decomposed {m.block_decomposed}, + time_recursive_block_decomposition {m.time_recursive_block_decomposition}, + blocks {m.blocks}, + endo2block {m.endo2block}, + eq2block {m.eq2block}, + blocks_jacobian_sparse_colptr {m.blocks_jacobian_sparse_colptr}, + endo2eq {m.endo2eq}, + cutoff {m.cutoff} { copyHelper(m); } -ModelTree & -ModelTree::operator=(const ModelTree &m) +ModelTree& +ModelTree::operator=(const ModelTree& m) { DataTree::operator=(m); @@ -233,7 +231,7 @@ ModelTree::operator=(const ModelTree &m) } void -ModelTree::computeNormalization(const jacob_map_t &contemporaneous_jacobian) +ModelTree::computeNormalization(const jacob_map_t& contemporaneous_jacobian) { const int n {static_cast(equations.size())}; @@ -249,25 +247,29 @@ ModelTree::computeNormalization(const jacob_map_t &contemporaneous_jacobian) BipartiteGraph g(2 * n); // Fill in the graph - for (const auto &[eq_and_endo, val] : contemporaneous_jacobian) + for (const auto& [eq_and_endo, val] : contemporaneous_jacobian) add_edge(eq_and_endo.first + n, eq_and_endo.second, g); // Compute maximum cardinality matching - vector mate_map(2*n); + vector mate_map(2 * n); edmonds_maximum_cardinality_matching(g, &mate_map[0]); // Check if all variables are normalized - if (auto it = find(mate_map.begin(), mate_map.begin() + n, boost::graph_traits::null_vertex()); + if (auto it = find(mate_map.begin(), mate_map.begin() + n, + boost::graph_traits::null_vertex()); it != mate_map.begin() + n) - throw ModelNormalizationFailed {symbol_table.getName(symbol_table.getID(SymbolType::endogenous, it - mate_map.begin())) }; + throw ModelNormalizationFailed { + symbol_table.getName(symbol_table.getID(SymbolType::endogenous, it - mate_map.begin()))}; - // Create the resulting map, by copying the n first elements of mate_map, and substracting n to them + // Create the resulting map, by copying the n first elements of mate_map, and substracting n to + // them endo2eq.resize(equations.size()); - transform(mate_map.begin(), mate_map.begin() + n, endo2eq.begin(), [=](vertex_descriptor_t i) { return i-n; }); + transform(mate_map.begin(), mate_map.begin() + n, endo2eq.begin(), + [=](vertex_descriptor_t i) { return i - n; }); } bool -ModelTree::computeNonSingularNormalization(const eval_context_t &eval_context) +ModelTree::computeNonSingularNormalization(const eval_context_t& eval_context) { const int n {static_cast(equations.size())}; @@ -275,7 +277,9 @@ ModelTree::computeNonSingularNormalization(const eval_context_t &eval_context) not have as many equations as variables. */ if (n != symbol_table.endo_nbr()) { - cout << "The " << modelClassName() << " cannot be normalized, since it does not have as many equations as variables." << endl; + cout << "The " << modelClassName() + << " cannot be normalized, since it does not have as many equations as variables." + << endl; return false; } @@ -287,16 +291,21 @@ ModelTree::computeNonSingularNormalization(const eval_context_t &eval_context) matched with the endogenous on the LHS. */ if (time_recursive_block_decomposition) { - auto [normalize_by_lhs, lhs_symbolic_jacobian] { computeLeftHandSideSymbolicJacobian() }; + auto [normalize_by_lhs, lhs_symbolic_jacobian] {computeLeftHandSideSymbolicJacobian()}; if (normalize_by_lhs) try { computeNormalization(lhs_symbolic_jacobian); return true; } - catch (ModelNormalizationFailed &e) + catch (ModelNormalizationFailed& e) { - cerr << "WARNING: All equations are written so that a single contemporaneous endogenous variable appears on the left-hand side. This suggests a natural normalization of the model. However, variable " << e.unmatched_endo << " could not be matched with an equation. Check whether this is desired." << endl; + cerr << "WARNING: All equations are written so that a single contemporaneous " + "endogenous variable appears on the left-hand side. This suggests a natural " + "normalization of the model. However, variable " + << e.unmatched_endo + << " could not be matched with an equation. Check whether this is desired." + << endl; } } @@ -304,12 +313,12 @@ ModelTree::computeNonSingularNormalization(const eval_context_t &eval_context) // Compute the maximum value of each row of the contemporaneous Jacobian matrix vector max_val(n, 0.0); - for (const auto &[eq_and_endo, val] : contemporaneous_jacobian) + for (const auto& [eq_and_endo, val] : contemporaneous_jacobian) max_val[eq_and_endo.first] = max(max_val[eq_and_endo.first], fabs(val)); // Compute normalized contemporaneous Jacobian jacob_map_t normalized_contemporaneous_jacobian(contemporaneous_jacobian); - for (auto &[eq_and_endo, val] : normalized_contemporaneous_jacobian) + for (auto& [eq_and_endo, val] : normalized_contemporaneous_jacobian) val /= max_val[eq_and_endo.first]; // We start with the highest value of the cutoff and try to normalize the model @@ -322,7 +331,7 @@ ModelTree::computeNonSingularNormalization(const eval_context_t &eval_context) // Drop elements below cutoff from normalized contemporaneous Jacobian jacob_map_t normalized_contemporaneous_jacobian_above_cutoff; int suppressed = 0; - for (const auto &[eq_and_endo, val] : normalized_contemporaneous_jacobian) + for (const auto& [eq_and_endo, val] : normalized_contemporaneous_jacobian) if (fabs(val) > max(current_cutoff, cutoff)) normalized_contemporaneous_jacobian_above_cutoff[eq_and_endo] = val; else @@ -334,7 +343,7 @@ ModelTree::computeNonSingularNormalization(const eval_context_t &eval_context) computeNormalization(normalized_contemporaneous_jacobian_above_cutoff); return true; } - catch (ModelNormalizationFailed &e) + catch (ModelNormalizationFailed& e) { } last_suppressed = suppressed; @@ -347,56 +356,55 @@ ModelTree::computeNonSingularNormalization(const eval_context_t &eval_context) computeNormalization(normalized_contemporaneous_jacobian); return true; } - catch (ModelNormalizationFailed &e) + catch (ModelNormalizationFailed& e) { } cout << "Normalization failed with cutoff, trying symbolic normalization..." << endl; /* If no non-singular normalization can be found, try to find a normalization even with a potential singularity. */ - auto symbolic_jacobian { computeSymbolicJacobian(true) }; + auto symbolic_jacobian {computeSymbolicJacobian(true)}; try { computeNormalization(symbolic_jacobian); return true; } - catch (ModelNormalizationFailed &e) + catch (ModelNormalizationFailed& e) { - cerr << "Could not normalize the " << modelClassName() << ". Variable " - << e.unmatched_endo << " is not in the maximum cardinality matching." << endl; + cerr << "Could not normalize the " << modelClassName() << ". Variable " << e.unmatched_endo + << " is not in the maximum cardinality matching." << endl; } return false; } ModelTree::jacob_map_t -ModelTree::evaluateAndReduceJacobian(const eval_context_t &eval_context) const +ModelTree::evaluateAndReduceJacobian(const eval_context_t& eval_context) const { jacob_map_t contemporaneous_jacobian; - for (const auto &[indices, d1] : derivatives[1]) + for (const auto& [indices, d1] : derivatives[1]) { int deriv_id = indices[1]; if (getTypeByDerivID(deriv_id) == SymbolType::endogenous) { int eq = indices[0]; - int var { getTypeSpecificIDByDerivID(deriv_id) }; + int var {getTypeSpecificIDByDerivID(deriv_id)}; int lag = getLagByDerivID(deriv_id); - double val { [&] - { + double val {[&] { try { return d1->eval(eval_context); } - catch (ExprNode::EvalExternalFunctionException &e) + catch (ExprNode::EvalExternalFunctionException& e) { return 1.0; } /* Other types of EvalException should not happen (all symbols should have a value; we don’t evaluate an equal sign) */ - }() }; + }()}; if ((isnan(val) || fabs(val) >= cutoff) && lag == 0) - contemporaneous_jacobian[{ eq, var }] = val; + contemporaneous_jacobian[{eq, var}] = val; } } @@ -422,7 +430,7 @@ ModelTree::computePrologueAndEpilogue() (resp. column) indices are to be interpreted according to “eq_idx_block2orig” (resp. “endo_idx_block2orig”). Stored in row-major order. */ - vector IM(n*n, false); + vector IM(n * n, false); for (int i = 0; i < n; i++) { set> endos_and_lags; @@ -468,7 +476,7 @@ ModelTree::computePrologueAndEpilogue() prologue = new_prologue; } while (something_has_been_done); - + // Find the epilogue equations int epilogue = 0; do @@ -505,11 +513,12 @@ ModelTree::computePrologueAndEpilogue() updateReverseVariableEquationOrderings(); - return { prologue, epilogue }; + return {prologue, epilogue}; } void -ModelTree::equationTypeDetermination(const map, expr_t> &first_order_endo_derivatives) +ModelTree::equationTypeDetermination( + const map, expr_t>& first_order_endo_derivatives) { equation_type_and_normalized_equation.clear(); equation_type_and_normalized_equation.resize(equations.size()); @@ -519,8 +528,8 @@ ModelTree::equationTypeDetermination(const map, expr_t> &fi int var = endo_idx_block2orig[i]; expr_t lhs = equations[eq]->arg1; EquationType Equation_Simulation_Type = EquationType::solve; - BinaryOpNode *normalized_eq = nullptr; - if (auto it = first_order_endo_derivatives.find({ eq, var, 0 }); + BinaryOpNode* normalized_eq = nullptr; + if (auto it = first_order_endo_derivatives.find({eq, var, 0}); it != first_order_endo_derivatives.end()) { expr_t derivative = it->second; @@ -532,27 +541,28 @@ ModelTree::equationTypeDetermination(const map, expr_t> &fi { set> result; derivative->collectEndogenous(result); - bool variable_not_in_derivative = !result.contains({ var, 0 }); + bool variable_not_in_derivative = !result.contains({var, 0}); try { - normalized_eq = equations[eq]->normalizeEquation(symbol_table.getID(SymbolType::endogenous, var), 0); + normalized_eq = equations[eq]->normalizeEquation( + symbol_table.getID(SymbolType::endogenous, var), 0); if ((getMFS() == 2 && variable_not_in_derivative) || getMFS() == 3) Equation_Simulation_Type = EquationType::evaluateRenormalized; } - catch (ExprNode::NormalizationFailed &e) + catch (ExprNode::NormalizationFailed& e) { } } } - equation_type_and_normalized_equation[eq] = { Equation_Simulation_Type, normalized_eq }; + equation_type_and_normalized_equation[eq] = {Equation_Simulation_Type, normalized_eq}; } } void ModelTree::computeDynamicStructureOfBlock(int blk) { - vector max_endo_lag_lead(blocks[blk].size, pair{0, 0}); + vector max_endo_lag_lead(blocks[blk].size, pair {0, 0}); blocks[blk].max_endo_lag = blocks[blk].max_endo_lead = 0; for (int eq = 0; eq < blocks[blk].size; eq++) { @@ -567,7 +577,8 @@ ModelTree::computeDynamicStructureOfBlock(int blk) { blocks[blk].max_endo_lag = max(blocks[blk].max_endo_lag, -lag); blocks[blk].max_endo_lead = max(blocks[blk].max_endo_lead, lag); - auto &[max_endo_lag, max_endo_lead] = max_endo_lag_lead[getBlockInitialVariableID(blk, endo)]; + auto& [max_endo_lag, max_endo_lead] + = max_endo_lag_lead[getBlockInitialVariableID(blk, endo)]; max_endo_lag = max(max_endo_lag, -lag); max_endo_lead = max(max_endo_lead, lag); } @@ -577,7 +588,7 @@ ModelTree::computeDynamicStructureOfBlock(int blk) void ModelTree::computeSimulationTypeOfBlock(int blk) { - auto &type = blocks[blk].simulation_type; + auto& type = blocks[blk].simulation_type; if (blocks[blk].max_endo_lag > 0 && blocks[blk].max_endo_lead > 0) { if (blocks[blk].size == 1) @@ -597,11 +608,11 @@ ModelTree::computeSimulationTypeOfBlock(int blk) bool can_eval = (getBlockEquationType(blk, 0) == EquationType::evaluate || getBlockEquationType(blk, 0) == EquationType::evaluateRenormalized); if (blocks[blk].max_endo_lead > 0) - type = can_eval ? BlockSimulationType::evaluateBackward : - BlockSimulationType::solveBackwardSimple; + type = can_eval ? BlockSimulationType::evaluateBackward + : BlockSimulationType::solveBackwardSimple; else - type = can_eval ? BlockSimulationType::evaluateForward : - BlockSimulationType::solveForwardSimple; + type = can_eval ? BlockSimulationType::evaluateForward + : BlockSimulationType::solveForwardSimple; } } @@ -610,7 +621,7 @@ ModelTree::getVariableLeadLagByBlock() const { int nb_endo = symbol_table.endo_nbr(); - lag_lead_vector_t variable_lag_lead(nb_endo, { 0, 0 }), equation_lag_lead(nb_endo, { 0, 0 }); + lag_lead_vector_t variable_lag_lead(nb_endo, {0, 0}), equation_lag_lead(nb_endo, {0, 0}); for (int eq = 0; eq < nb_endo; eq++) { set> endos_and_lags; @@ -624,7 +635,7 @@ ModelTree::getVariableLeadLagByBlock() const equation_lag_lead[eq].second = max(equation_lag_lead[eq].second, lag); } } - return { equation_lag_lead, variable_lag_lead }; + return {equation_lag_lead, variable_lag_lead}; } void @@ -639,23 +650,21 @@ ModelTree::computeBlockDecomposition(int prologue, int epilogue) For detecting dependencies between variables, use the symbolic adjacency matrix */ VariableDependencyGraph G(nb_simvars); - for (const auto &[key, value] : computeSymbolicJacobian(time_recursive_block_decomposition)) + for (const auto& [key, value] : computeSymbolicJacobian(time_recursive_block_decomposition)) { auto [eq, endo] = key; - if (eq_idx_orig2block[eq] >= prologue - && eq_idx_orig2block[eq] < nb_var - epilogue - && endo_idx_orig2block[endo] >= prologue - && endo_idx_orig2block[endo] < nb_var - epilogue + if (eq_idx_orig2block[eq] >= prologue && eq_idx_orig2block[eq] < nb_var - epilogue + && endo_idx_orig2block[endo] >= prologue && endo_idx_orig2block[endo] < nb_var - epilogue && eq != endo2eq[endo]) - add_edge(vertex(eq_idx_orig2block[endo2eq[endo]]-prologue, G), - vertex(eq_idx_orig2block[eq]-prologue, G), G); + add_edge(vertex(eq_idx_orig2block[endo2eq[endo]] - prologue, G), + vertex(eq_idx_orig2block[eq] - prologue, G), G); } /* Identify the simultaneous blocks. Each simultaneous block is given an index, starting from 0, in recursive order */ auto [num_simblocks, simvar2simblock] = G.sortedStronglyConnectedComponents(); - int num_blocks = prologue+num_simblocks+epilogue; + int num_blocks = prologue + num_simblocks + epilogue; blocks.clear(); blocks.resize(num_blocks); @@ -664,9 +673,9 @@ ModelTree::computeBlockDecomposition(int prologue, int epilogue) // Initialize size and mfs_size for prologue and epilogue, plus eq/endo→block mappings for (int blk = 0; blk < num_blocks; blk++) - if (blk < prologue || blk >= num_blocks-epilogue) + if (blk < prologue || blk >= num_blocks - epilogue) { - int var_eq = (blk < prologue ? blk : blk-num_simblocks+nb_simvars); + int var_eq = (blk < prologue ? blk : blk - num_simblocks + nb_simvars); blocks[blk].size = 1; blocks[blk].mfs_size = 1; blocks[blk].first_equation = var_eq; @@ -679,10 +688,10 @@ ModelTree::computeBlockDecomposition(int prologue, int epilogue) for (int i = 0; i < static_cast(simvar2simblock.size()); i++) { simblock2simvars[simvar2simblock[i]].push_back(i); - int blk = prologue+simvar2simblock[i]; + int blk = prologue + simvar2simblock[i]; blocks[blk].size++; - endo2block[endo_idx_block2orig[prologue+i]] = blk; - eq2block[eq_idx_block2orig[prologue+i]] = blk; + endo2block[endo_idx_block2orig[prologue + i]] = blk; + eq2block[eq_idx_block2orig[prologue + i]] = blk; } // Determine the dynamic structure of each block @@ -698,21 +707,24 @@ ModelTree::computeBlockDecomposition(int prologue, int epilogue) related to lead/lag variables. This forces those vertices to belong to the feedback set */ for (int i = 0; i < nb_simvars; i++) - if (equation_type_and_normalized_equation[eq_idx_block2orig[i+prologue]].first == EquationType::solve - || (!time_recursive_block_decomposition && - (variable_lag_lead[endo_idx_block2orig[i+prologue]].first > 0 - || variable_lag_lead[endo_idx_block2orig[i+prologue]].second > 0 - || equation_lag_lead[eq_idx_block2orig[i+prologue]].first > 0 - || equation_lag_lead[eq_idx_block2orig[i+prologue]].second > 0)) + if (equation_type_and_normalized_equation[eq_idx_block2orig[i + prologue]].first + == EquationType::solve + || (!time_recursive_block_decomposition + && (variable_lag_lead[endo_idx_block2orig[i + prologue]].first > 0 + || variable_lag_lead[endo_idx_block2orig[i + prologue]].second > 0 + || equation_lag_lead[eq_idx_block2orig[i + prologue]].first > 0 + || equation_lag_lead[eq_idx_block2orig[i + prologue]].second > 0)) || getMFS() == 0) add_edge(vertex(i, G), vertex(i, G), G); - const vector old_eq_idx_block2orig(eq_idx_block2orig), old_endo_idx_block2orig(endo_idx_block2orig); + const vector old_eq_idx_block2orig(eq_idx_block2orig), + old_endo_idx_block2orig(endo_idx_block2orig); int ordidx = prologue; - for (int blk = prologue; blk < prologue+num_simblocks; blk++) + for (int blk = prologue; blk < prologue + num_simblocks; blk++) { - blocks[blk].first_equation = (blk == 0 ? 0 : blocks[blk-1].first_equation + blocks[blk-1].size); - auto subG = G.extractSubgraph(simblock2simvars[blk-prologue]); + blocks[blk].first_equation + = (blk == 0 ? 0 : blocks[blk - 1].first_equation + blocks[blk - 1].size); + auto subG = G.extractSubgraph(simblock2simvars[blk - prologue]); auto feed_back_vertices = subG.minimalSetOfFeedbackVertices(); blocks[blk].mfs_size = feed_back_vertices.size(); auto recursive_vertices = subG.reorderRecursiveVariables(feed_back_vertices); @@ -722,20 +734,20 @@ ModelTree::computeBlockDecomposition(int prologue, int epilogue) recursive order */ for (int vtx : recursive_vertices) { - int simvar { v_index1[vertex(vtx, subG)] }; - eq_idx_block2orig[ordidx] = old_eq_idx_block2orig[simvar+prologue]; - endo_idx_block2orig[ordidx] = old_endo_idx_block2orig[simvar+prologue]; + int simvar {v_index1[vertex(vtx, subG)]}; + eq_idx_block2orig[ordidx] = old_eq_idx_block2orig[simvar + prologue]; + endo_idx_block2orig[ordidx] = old_endo_idx_block2orig[simvar + prologue]; ordidx++; } // Then the feedback variables, reordered by dynamic status - for (auto max_lag_lead : { pair{0, 0}, pair{1, 0}, pair{1, 1}, pair{0, 1} }) + for (auto max_lag_lead : {pair {0, 0}, pair {1, 0}, pair {1, 1}, pair {0, 1}}) for (int vtx : feed_back_vertices) if (int simvar = v_index1[vertex(vtx, subG)]; - variable_lag_lead[old_endo_idx_block2orig[simvar+prologue]] == max_lag_lead) + variable_lag_lead[old_endo_idx_block2orig[simvar + prologue]] == max_lag_lead) { - eq_idx_block2orig[ordidx] = old_eq_idx_block2orig[simvar+prologue]; - endo_idx_block2orig[ordidx] = old_endo_idx_block2orig[simvar+prologue]; + eq_idx_block2orig[ordidx] = old_eq_idx_block2orig[simvar + prologue]; + endo_idx_block2orig[ordidx] = old_endo_idx_block2orig[simvar + prologue]; ordidx++; } } @@ -761,8 +773,7 @@ ModelTree::printBlockDecomposition() const || simulation_type == BlockSimulationType::solveTwoBoundariesComplete) { Nb_SimulBlocks++; - if (int size = blocks[block].size; - size > largest_block) + if (int size = blocks[block].size; size > largest_block) { largest_block = size; Nb_feedback_variable = blocks[block].mfs_size; @@ -771,9 +782,11 @@ ModelTree::printBlockDecomposition() const int Nb_RecursBlocks = Nb_TotalBlocks - Nb_SimulBlocks; cout << Nb_TotalBlocks << " block(s) found:" << endl - << " " << Nb_RecursBlocks << " recursive block(s) and " << Nb_SimulBlocks << " simultaneous block(s)." << endl + << " " << Nb_RecursBlocks << " recursive block(s) and " << Nb_SimulBlocks + << " simultaneous block(s)." << endl << " the largest simultaneous block has " << largest_block << " equation(s)" << endl - << " and " << Nb_feedback_variable << " feedback variable(s)." << endl; + << " and " << Nb_feedback_variable + << " feedback variable(s)." << endl; } void @@ -789,28 +802,26 @@ ModelTree::reduceBlockDecomposition() set> endos_and_lags; getBlockEquationExpr(blk, 0)->collectEndogenous(endos_and_lags); bool is_lead = false, is_lag = false; - for (int var = 0; var < blocks[blk-1].size; var++) + for (int var = 0; var < blocks[blk - 1].size; var++) { - is_lag = is_lag || endos_and_lags.contains({ getBlockVariableID(blk-1, var), -1 }); - is_lead = is_lead || endos_and_lags.contains({ getBlockVariableID(blk-1, var), 1 }); + is_lag = is_lag || endos_and_lags.contains({getBlockVariableID(blk - 1, var), -1}); + is_lead = is_lead || endos_and_lags.contains({getBlockVariableID(blk - 1, var), 1}); } - if ((blocks[blk-1].simulation_type == BlockSimulationType::evaluateForward - && blocks[blk].simulation_type == BlockSimulationType::evaluateForward - && !is_lead) - || (blocks[blk-1].simulation_type == BlockSimulationType::evaluateBackward - && blocks[blk].simulation_type == BlockSimulationType::evaluateBackward - && !is_lag)) + if ((blocks[blk - 1].simulation_type == BlockSimulationType::evaluateForward + && blocks[blk].simulation_type == BlockSimulationType::evaluateForward && !is_lead) + || (blocks[blk - 1].simulation_type == BlockSimulationType::evaluateBackward + && blocks[blk].simulation_type == BlockSimulationType::evaluateBackward && !is_lag)) { // Merge the current block into the previous one - blocks[blk-1].size++; - blocks[blk-1].mfs_size = blocks[blk-1].size; - computeDynamicStructureOfBlock(blk-1); - blocks.erase(blocks.begin()+blk); - for (auto &b : endo2block) + blocks[blk - 1].size++; + blocks[blk - 1].mfs_size = blocks[blk - 1].size; + computeDynamicStructureOfBlock(blk - 1); + blocks.erase(blocks.begin() + blk); + for (auto& b : endo2block) if (b >= blk) b--; - for (auto &b : eq2block) + for (auto& b : eq2block) if (b >= blk) b--; blk--; @@ -830,7 +841,7 @@ ModelTree::determineLinearBlocks() case BlockSimulationType::solveBackwardComplete: case BlockSimulationType::solveForwardSimple: case BlockSimulationType::solveForwardComplete: - for (const auto &[indices, d1] : blocks_derivatives[blk]) + for (const auto& [indices, d1] : blocks_derivatives[blk]) { int lag = get<2>(indices); if (lag == 0) @@ -838,7 +849,7 @@ ModelTree::determineLinearBlocks() set> endogenous; d1->collectEndogenous(endogenous); for (int l = 0; l < blocks[blk].size; l++) - if (endogenous.contains({ endo_idx_block2orig[blocks[blk].first_equation+l], 0 })) + if (endogenous.contains({endo_idx_block2orig[blocks[blk].first_equation + l], 0})) { blocks[blk].linear = false; goto the_end; @@ -849,13 +860,13 @@ ModelTree::determineLinearBlocks() break; case BlockSimulationType::solveTwoBoundariesComplete: case BlockSimulationType::solveTwoBoundariesSimple: - for (const auto &[indices, d1] : blocks_derivatives[blk]) + for (const auto& [indices, d1] : blocks_derivatives[blk]) { int lag = get<2>(indices); set> endogenous; d1->collectEndogenous(endogenous); for (int l = 0; l < blocks[blk].size; l++) - if (endogenous.contains({ endo_idx_block2orig[blocks[blk].first_equation+l], lag })) + if (endogenous.contains({endo_idx_block2orig[blocks[blk].first_equation + l], lag})) { blocks[blk].linear = false; goto the_end2; @@ -875,15 +886,15 @@ ModelTree::equation_number() const } void -ModelTree::computeDerivatives(int order, const set &vars) +ModelTree::computeDerivatives(int order, const set& vars) { assert(order >= 1); computed_derivs_order = order; // Do not shrink the vectors, since they have a minimal size of 4 (see constructor) - derivatives.resize(max(static_cast(order+1), derivatives.size())); - NNZDerivatives.resize(max(static_cast(order+1), NNZDerivatives.size()), 0); + derivatives.resize(max(static_cast(order + 1), derivatives.size())); + NNZDerivatives.resize(max(static_cast(order + 1), NNZDerivatives.size()), 0); // First-order derivatives for (int var : vars) @@ -892,18 +903,20 @@ ModelTree::computeDerivatives(int order, const set &vars) expr_t d1 = equations[eq]->getDerivative(var); if (d1 == Zero) continue; - derivatives[1][{ eq, var }] = d1; + derivatives[1][{eq, var}] = d1; ++NNZDerivatives[1]; } // Compute the sparse representation of the Jacobian - for (const auto &[indices, d1] : derivatives[1]) - jacobian_sparse_column_major_order.try_emplace({indices[0], getJacobianCol(indices[1], true)}, d1); - jacobian_sparse_colptr = computeCSCColPtr(jacobian_sparse_column_major_order, getJacobianColsNbr(true)); + for (const auto& [indices, d1] : derivatives[1]) + jacobian_sparse_column_major_order.try_emplace({indices[0], getJacobianCol(indices[1], true)}, + d1); + jacobian_sparse_colptr + = computeCSCColPtr(jacobian_sparse_column_major_order, getJacobianColsNbr(true)); // Higher-order derivatives for (int o = 2; o <= order; o++) - for (const auto &[lower_indices, lower_d] : derivatives[o-1]) + for (const auto& [lower_indices, lower_d] : derivatives[o - 1]) for (int var : vars) { if (lower_indices.back() > var) @@ -913,7 +926,7 @@ ModelTree::computeDerivatives(int order, const set &vars) if (d == Zero) continue; - vector indices{lower_indices}; + vector indices {lower_indices}; indices.push_back(var); // At this point, indices of endogenous variables are sorted in non-decreasing order derivatives[o][indices] = d; @@ -930,10 +943,9 @@ ModelTree::computeTemporaryTerms(bool is_matlab, bool no_tmp_terms) { /* Ensure that we don’t have any model-local variable in the model at this point (we used to treat them as temporary terms) */ - assert([&] - { + assert([&] { set used_local_vars; - for (auto &equation : equations) + for (auto& equation : equations) equation->collectVariables(SymbolType::modelLocalVariable, used_local_vars); return used_local_vars.empty(); }()); @@ -942,33 +954,27 @@ ModelTree::computeTemporaryTerms(bool is_matlab, bool no_tmp_terms) map, unordered_set> temp_terms_map; unordered_map>> reference_count; - for (auto &equation : equations) - equation->computeTemporaryTerms({ 0, 0 }, - temp_terms_map, - reference_count, - is_matlab); + for (auto& equation : equations) + equation->computeTemporaryTerms({0, 0}, temp_terms_map, reference_count, is_matlab); for (int order = 1; order < static_cast(derivatives.size()); order++) - for (const auto &it : derivatives[order]) - it.second->computeTemporaryTerms({ order, 0 }, - temp_terms_map, - reference_count, - is_matlab); + for (const auto& it : derivatives[order]) + it.second->computeTemporaryTerms({order, 0}, temp_terms_map, reference_count, is_matlab); /* If the user has specified the notmpterms option, clear all temporary terms, except those that correspond to external functions (since they are not optional) */ if (no_tmp_terms) - for (auto &it : temp_terms_map) - erase_if(it.second, - [](expr_t e) { return !dynamic_cast(e); }); + for (auto& it : temp_terms_map) + erase_if(it.second, [](expr_t e) { return !dynamic_cast(e); }); // Fill the structures temporary_terms_derivatives.clear(); temporary_terms_derivatives.resize(derivatives.size()); for (int order = 0; order < static_cast(derivatives.size()); order++) - copy(temp_terms_map[{ order, 0 }].begin(), temp_terms_map[{ order, 0 }].end(), - inserter(temporary_terms_derivatives.at(order), temporary_terms_derivatives.at(order).begin())); + copy(temp_terms_map[{order, 0}].begin(), temp_terms_map[{order, 0}].end(), + inserter(temporary_terms_derivatives.at(order), + temporary_terms_derivatives.at(order).begin())); // Compute indices in MATLAB/Julia vector for (int order {0}, idx {0}; order < static_cast(derivatives.size()); order++) @@ -998,11 +1004,13 @@ ModelTree::computeBlockTemporaryTerms(bool no_tmp_terms) || blocks[blk].simulation_type == BlockSimulationType::evaluateForward || eq < blocks[blk].getRecursiveSize()) && isBlockEquationRenormalized(blk, eq)) - getBlockEquationRenormalizedExpr(blk, eq)->computeBlockTemporaryTerms(blk, eq, temp_terms, reference_count); + getBlockEquationRenormalizedExpr(blk, eq)->computeBlockTemporaryTerms( + blk, eq, temp_terms, reference_count); else - getBlockEquationExpr(blk, eq)->computeBlockTemporaryTerms(blk, eq, temp_terms, reference_count); + getBlockEquationExpr(blk, eq)->computeBlockTemporaryTerms(blk, eq, temp_terms, + reference_count); } - for (const auto &[ignore, d] : blocks_derivatives[blk]) + for (const auto& [ignore, d] : blocks_derivatives[blk]) d->computeBlockTemporaryTerms(blk, blocks[blk].size, temp_terms, reference_count); } @@ -1010,48 +1018,46 @@ ModelTree::computeBlockTemporaryTerms(bool no_tmp_terms) terms, except those that correspond to external functions (since they are not optional) */ if (no_tmp_terms) - for (auto &it : temp_terms) - for (auto &it2 : it) - erase_if(it2, [](expr_t e) { return !dynamic_cast(e); }); + for (auto& it : temp_terms) + for (auto& it2 : it) + erase_if(it2, [](expr_t e) { return !dynamic_cast(e); }); blocks_temporary_terms.resize(nb_blocks); for (int blk {0}; blk < nb_blocks; blk++) { blocks_temporary_terms.at(blk).resize(temp_terms.at(blk).size()); for (size_t i {0}; i < temp_terms.at(blk).size(); i++) - copy(temp_terms.at(blk).at(i).begin(), temp_terms.at(blk).at(i).end(), inserter(blocks_temporary_terms.at(blk).at(i), blocks_temporary_terms.at(blk).at(i).begin())); + copy(temp_terms.at(blk).at(i).begin(), temp_terms.at(blk).at(i).end(), + inserter(blocks_temporary_terms.at(blk).at(i), + blocks_temporary_terms.at(blk).at(i).begin())); } // Compute indices in the temporary terms vector blocks_temporary_terms_idxs.clear(); - for (int idx{0}; - auto &blk_tt : blocks_temporary_terms) - for (auto &eq_tt : blk_tt) + for (int idx {0}; auto& blk_tt : blocks_temporary_terms) + for (auto& eq_tt : blk_tt) for (auto tt : eq_tt) blocks_temporary_terms_idxs[tt] = idx++; } void -ModelTree::writeJsonTemporaryTerms(const temporary_terms_t &tt, - temporary_terms_t &temp_term_union, - ostream &output, - deriv_node_temp_terms_t &tef_terms, const string &concat) const +ModelTree::writeJsonTemporaryTerms(const temporary_terms_t& tt, temporary_terms_t& temp_term_union, + ostream& output, deriv_node_temp_terms_t& tef_terms, + const string& concat) const { // Local var used to keep track of temp nodes already written temporary_terms_t tt2 = temp_term_union; output << R"("external_functions_temporary_terms_)" << concat << R"(": [)"; - for (bool printed_term{false}; - auto it : tt) + for (bool printed_term {false}; auto it : tt) { - if (dynamic_cast(it)) + if (dynamic_cast(it)) { if (exchange(printed_term, true)) output << ", "; vector efout; it->writeJsonExternalFunctionOutput(efout, tt2, tef_terms); - for (bool printed_efout{false}; - auto &it : efout) + for (bool printed_efout {false}; auto& it : efout) { if (exchange(printed_efout, true)) output << ", "; @@ -1063,8 +1069,7 @@ ModelTree::writeJsonTemporaryTerms(const temporary_terms_t &tt, output << "]" << R"(, "temporary_terms_)" << concat << R"(": [)"; - for (bool printed_term{false}; - const auto &it : tt) + for (bool printed_term {false}; const auto& it : tt) { if (exchange(printed_term, true)) output << ", "; @@ -1081,7 +1086,8 @@ ModelTree::writeJsonTemporaryTerms(const temporary_terms_t &tt, } void -ModelTree::fixNestedParenthesis(ostringstream &output, map &tmp_paren_vars, bool &message_printed) const +ModelTree::fixNestedParenthesis(ostringstream& output, map& tmp_paren_vars, + bool& message_printed) const { string str = output.str(); if (!testNestedParenthesis(str)) @@ -1112,11 +1118,23 @@ ModelTree::fixNestedParenthesis(ostringstream &output, map &tmp_ { if (!message_printed) { - cerr << "Warning: A .m file created by Dynare will have more than 32 nested parenthesis. MATLAB cannot support this. " << endl - << " We are going to modify, albeit inefficiently, this output to have fewer than 32 nested parenthesis. " << endl - << " It would hence behoove you to use the use_dll option of the model block to circumnavigate this problem." << endl - << " If you have not yet set up a compiler on your system, see the MATLAB documentation for doing so." << endl - << " For Windows, see: https://www.mathworks.com/help/matlab/matlab_external/install-mingw-support-package.html" << endl << endl; + cerr << "Warning: A .m file created by Dynare will have more than 32 nested " + "parenthesis. MATLAB cannot support this. " + << endl + << " We are going to modify, albeit inefficiently, this output to have " + "fewer than 32 nested parenthesis. " + << endl + << " It would hence behoove you to use the use_dll option of the model " + "block to circumnavigate this problem." + << endl + << " If you have not yet set up a compiler on your system, see the " + "MATLAB documentation for doing so." + << endl + << " For Windows, see: " + "https://www.mathworks.com/help/matlab/matlab_external/" + "install-mingw-support-package.html" + << endl + << endl; message_printed = true; } string str1 = str.substr(first_open_paren, matching_paren - first_open_paren + 1); @@ -1146,9 +1164,9 @@ ModelTree::fixNestedParenthesis(ostringstream &output, map &tmp_ if (open_paren_idx != string::npos && match_paren_idx != string::npos) { - string val = str1.substr(open_paren_idx, match_paren_idx - open_paren_idx + 1); - if (auto it = tmp_paren_vars.find(val); - it == tmp_paren_vars.end()) + string val + = str1.substr(open_paren_idx, match_paren_idx - open_paren_idx + 1); + 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"; @@ -1161,8 +1179,7 @@ ModelTree::fixNestedParenthesis(ostringstream &output, map &tmp_ } } } - if (auto it = tmp_paren_vars.find(str1); - it == tmp_paren_vars.end()) + 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"; @@ -1181,10 +1198,9 @@ ModelTree::fixNestedParenthesis(ostringstream &output, map &tmp_ } bool -ModelTree::testNestedParenthesis(const string &str) const +ModelTree::testNestedParenthesis(const string& str) const { - for (int open{0}; - char i : str) + for (int open {0}; char i : str) { if (i == '(') open++; @@ -1197,7 +1213,8 @@ ModelTree::testNestedParenthesis(const string &str) const } void -ModelTree::writeJsonModelLocalVariables(ostream &output, bool write_tef_terms, deriv_node_temp_terms_t &tef_terms) const +ModelTree::writeJsonModelLocalVariables(ostream& output, bool write_tef_terms, + deriv_node_temp_terms_t& tef_terms) const { /* Collect all model local variables appearing in equations, and print only them. Printing unused model local variables can lead to a crash (see @@ -1208,8 +1225,7 @@ ModelTree::writeJsonModelLocalVariables(ostream &output, bool write_tef_terms, d equation->collectVariables(SymbolType::modelLocalVariable, used_local_vars); output << R"("model_local_variables": [)"; - for (bool printed_something{false}; - int id : local_variables_vector) + for (bool printed_something {false}; int id : local_variables_vector) if (used_local_vars.contains(id)) { if (exchange(printed_something, true)) @@ -1220,8 +1236,7 @@ ModelTree::writeJsonModelLocalVariables(ostream &output, bool write_tef_terms, d { vector efout; value->writeJsonExternalFunctionOutput(efout, {}, tef_terms); - for (bool printed_efout{false}; - auto &it : efout) + for (bool printed_efout {false}; auto& it : efout) { if (exchange(printed_efout, true)) output << ", "; @@ -1232,8 +1247,7 @@ ModelTree::writeJsonModelLocalVariables(ostream &output, bool write_tef_terms, d output << ", "; } - output << R"({"variable": ")" << symbol_table.getName(id) - << R"(", "value": ")"; + output << R"({"variable": ")" << symbol_table.getName(id) << R"(", "value": ")"; value->writeJsonOutput(output, {}, tef_terms); output << R"("})" << endl; } @@ -1241,42 +1255,41 @@ ModelTree::writeJsonModelLocalVariables(ostream &output, bool write_tef_terms, d } int -ModelTree::writeBytecodeBinFile(const filesystem::path &filename, bool is_two_boundaries) const +ModelTree::writeBytecodeBinFile(const filesystem::path& filename, bool is_two_boundaries) const { - ofstream SaveCode { filename, ios::out | ios::binary }; + ofstream SaveCode {filename, ios::out | ios::binary}; if (!SaveCode.is_open()) { cerr << R"(Error : Can't open file ")" << filename.string() << R"(" for writing)" << endl; exit(EXIT_FAILURE); } int u_count {0}; - for (const auto &[indices, d1] : derivatives[1]) - if (int deriv_id {indices[1]}; - getTypeByDerivID(deriv_id) == SymbolType::endogenous) + for (const auto& [indices, d1] : derivatives[1]) + if (int deriv_id {indices[1]}; getTypeByDerivID(deriv_id) == SymbolType::endogenous) { int eq {indices[0]}; - SaveCode.write(reinterpret_cast(&eq), sizeof eq); + SaveCode.write(reinterpret_cast(&eq), sizeof eq); int tsid {getTypeSpecificIDByDerivID(deriv_id)}; int lag {getLagByDerivID(deriv_id)}; int varr {tsid + lag * symbol_table.endo_nbr()}; - SaveCode.write(reinterpret_cast(&varr), sizeof varr); - SaveCode.write(reinterpret_cast(&lag), sizeof lag); + SaveCode.write(reinterpret_cast(&varr), sizeof varr); + SaveCode.write(reinterpret_cast(&lag), sizeof lag); int u {u_count + symbol_table.endo_nbr()}; - SaveCode.write(reinterpret_cast(&u), sizeof u); + SaveCode.write(reinterpret_cast(&u), sizeof u); u_count++; } if (is_two_boundaries) u_count += symbol_table.endo_nbr(); for (int j {0}; j < symbol_table.endo_nbr(); j++) - SaveCode.write(reinterpret_cast(&j), sizeof j); + SaveCode.write(reinterpret_cast(&j), sizeof j); for (int j {0}; j < symbol_table.endo_nbr(); j++) - SaveCode.write(reinterpret_cast(&j), sizeof j); + SaveCode.write(reinterpret_cast(&j), sizeof j); SaveCode.close(); return u_count; } int -ModelTree::writeBlockBytecodeBinFile(ofstream &bin_file, int block) const +ModelTree::writeBlockBytecodeBinFile(ofstream& bin_file, int block) const { int u_count {0}; int block_size {blocks[block].size}; @@ -1285,20 +1298,20 @@ ModelTree::writeBlockBytecodeBinFile(ofstream &bin_file, int block) const BlockSimulationType simulation_type {blocks[block].simulation_type}; bool is_two_boundaries {simulation_type == BlockSimulationType::solveTwoBoundariesComplete || simulation_type == BlockSimulationType::solveTwoBoundariesSimple}; - for (const auto &[indices, ignore] : blocks_derivatives[block]) + for (const auto& [indices, ignore] : blocks_derivatives[block]) { - const auto &[eq, var, lag] {indices}; + const auto& [eq, var, lag] {indices}; if (lag != 0 && !is_two_boundaries) continue; if (eq >= block_recursive && var >= block_recursive) { int v {eq - block_recursive}; - bin_file.write(reinterpret_cast(&v), sizeof v); + bin_file.write(reinterpret_cast(&v), sizeof v); int varr {var - block_recursive + lag * block_mfs}; - bin_file.write(reinterpret_cast(&varr), sizeof varr); - bin_file.write(reinterpret_cast(&lag), sizeof lag); + bin_file.write(reinterpret_cast(&varr), sizeof varr); + bin_file.write(reinterpret_cast(&lag), sizeof lag); int u {u_count + block_mfs}; - bin_file.write(reinterpret_cast(&u), sizeof u); + bin_file.write(reinterpret_cast(&u), sizeof u); u_count++; } } @@ -1308,31 +1321,32 @@ ModelTree::writeBlockBytecodeBinFile(ofstream &bin_file, int block) const for (int j {block_recursive}; j < block_size; j++) { int varr {getBlockVariableID(block, j)}; - bin_file.write(reinterpret_cast(&varr), sizeof varr); + bin_file.write(reinterpret_cast(&varr), sizeof varr); } for (int j {block_recursive}; j < block_size; j++) { int eqr {getBlockEquationID(block, j)}; - bin_file.write(reinterpret_cast(&eqr), sizeof eqr); + bin_file.write(reinterpret_cast(&eqr), sizeof eqr); } return u_count; } void -ModelTree::writeLatexModelFile(const string &mod_basename, const string &latex_basename, ExprNodeOutputType output_type, bool write_equation_tags) const +ModelTree::writeLatexModelFile(const string& mod_basename, const string& latex_basename, + ExprNodeOutputType output_type, bool write_equation_tags) const { filesystem::create_directories(mod_basename + "/latex"); const filesystem::path filename {mod_basename + "/latex/" + latex_basename + ".tex"}, - content_filename {mod_basename + "/latex/" + latex_basename + "_content" + ".tex"}; - ofstream output{filename, ios::out | ios::binary}; + content_filename {mod_basename + "/latex/" + latex_basename + "_content" + ".tex"}; + ofstream output {filename, ios::out | ios::binary}; if (!output.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; exit(EXIT_FAILURE); } - ofstream content_output{content_filename, ios::out | ios::binary}; + ofstream content_output {content_filename, ios::out | ios::binary}; if (!content_output.is_open()) { cerr << "ERROR: Can't open file " << content_filename.string() << " for writing" << endl; @@ -1352,8 +1366,7 @@ ModelTree::writeLatexModelFile(const string &mod_basename, const string &latex_b { expr_t value = local_variables_table.at(id); - content_output << R"(\begin{dmath*})" << endl - << symbol_table.getTeXName(id) << " = "; + content_output << R"(\begin{dmath*})" << endl << symbol_table.getTeXName(id) << " = "; // Use an empty set for the temporary terms value->writeOutput(content_output, output_type); content_output << endl << R"(\end{dmath*})" << endl; @@ -1366,12 +1379,14 @@ ModelTree::writeLatexModelFile(const string &mod_basename, const string &latex_b equation_tags.writeLatexOutput(content_output, eq); content_output << R"(\begin{dmath})" << endl; - // Here it is necessary to cast to superclass ExprNode, otherwise the overloaded writeOutput() method is not found - dynamic_cast(equations[eq])->writeOutput(content_output, output_type); + // Here it is necessary to cast to superclass ExprNode, otherwise the overloaded writeOutput() + // method is not found + dynamic_cast(equations[eq])->writeOutput(content_output, output_type); content_output << endl << R"(\end{dmath})" << endl; } - output << R"(\include{)" << latex_basename + "_content" << "}" << endl + output << R"(\include{)" << latex_basename + "_content" + << "}" << endl << R"(\end{document})" << endl; output.close(); @@ -1381,7 +1396,7 @@ ModelTree::writeLatexModelFile(const string &mod_basename, const string &latex_b void ModelTree::addEquation(expr_t eq, optional lineno) { - auto beq = dynamic_cast(eq); + auto beq = dynamic_cast(eq); assert(beq && beq->op_code == BinaryOpcode::equal); equations.push_back(beq); @@ -1389,7 +1404,7 @@ ModelTree::addEquation(expr_t eq, optional lineno) } void -ModelTree::findConstantEquationsWithoutMcpTag(map &subst_table) const +ModelTree::findConstantEquationsWithoutMcpTag(map& subst_table) const { for (size_t i = 0; i < equations.size(); i++) if (!equation_tags.exists(i, "mcp")) @@ -1406,30 +1421,31 @@ ModelTree::addEquation(expr_t eq, optional lineno, map eq_t void ModelTree::addAuxEquation(expr_t eq) { - auto beq = dynamic_cast(eq); + auto beq = dynamic_cast(eq); assert(beq && beq->op_code == BinaryOpcode::equal); aux_equations.push_back(beq); } void -ModelTree::addTrendVariables(const vector &trend_vars, expr_t growth_factor) noexcept(false) +ModelTree::addTrendVariables(const vector& trend_vars, expr_t growth_factor) noexcept(false) { for (int id : trend_vars) if (trend_symbols_map.contains(id)) - throw TrendException{symbol_table.getName(id)}; + throw TrendException {symbol_table.getName(id)}; else trend_symbols_map[id] = growth_factor; } void -ModelTree::addNonstationaryVariables(const vector &nonstationary_vars, bool log_deflator, expr_t deflator) noexcept(false) +ModelTree::addNonstationaryVariables(const vector& nonstationary_vars, bool log_deflator, + expr_t deflator) noexcept(false) { for (int id : nonstationary_vars) if (nonstationary_symbols_map.contains(id)) - throw TrendException{symbol_table.getName(id)}; + throw TrendException {symbol_table.getName(id)}; else - nonstationary_symbols_map[id] = { log_deflator, deflator }; + nonstationary_symbols_map[id] = {log_deflator, deflator}; } void @@ -1464,25 +1480,25 @@ ModelTree::computeParamsDerivatives(int paramsDerivsOrder) expr_t d = equations[eq]->getDerivative(param); if (d == Zero) continue; - params_derivatives[{ 0, 1 }][{ eq, param }] = d; + params_derivatives[{0, 1}][{eq, param}] = d; } for (int endoOrd = 1; endoOrd < static_cast(derivatives.size()); endoOrd++) - for (const auto &[lower_indices, lower_d] : derivatives[endoOrd]) + for (const auto& [lower_indices, lower_d] : derivatives[endoOrd]) { expr_t d = lower_d->getDerivative(param); if (d == Zero) continue; - vector indices{lower_indices}; + vector indices {lower_indices}; indices.push_back(param); - params_derivatives[{ endoOrd, 1 }][indices] = d; + params_derivatives[{endoOrd, 1}][indices] = d; } } // Higher-order derivatives w.r.t. parameters for (int endoOrd = 0; endoOrd < static_cast(derivatives.size()); endoOrd++) for (int paramOrd = 2; paramOrd <= paramsDerivsOrder; paramOrd++) - for (const auto &[lower_indices, lower_d] : params_derivatives[{ endoOrd, paramOrd-1 }]) + for (const auto& [lower_indices, lower_d] : params_derivatives[{endoOrd, paramOrd - 1}]) for (int param : deriv_id_set) { if (lower_indices.back() > param) @@ -1491,10 +1507,11 @@ ModelTree::computeParamsDerivatives(int paramsDerivsOrder) expr_t d = lower_d->getDerivative(param); if (d == Zero) continue; - vector indices{lower_indices}; + vector indices {lower_indices}; indices.push_back(param); - // At this point, indices of both endogenous and parameters are sorted in non-decreasing order - params_derivatives[{ endoOrd, paramOrd }][indices] = d; + // At this point, indices of both endogenous and parameters are sorted in non-decreasing + // order + params_derivatives[{endoOrd, paramOrd}][indices] = d; } } @@ -1506,17 +1523,17 @@ ModelTree::computeParamsDerivativesTemporaryTerms() /* The temp terms should be constructed in the same order as the for loops in {Static,Dynamic}Model::write{Json,}ParamsDerivativesFile() */ map, unordered_set> temp_terms_map; - for (const auto &[order, derivs] : params_derivatives) - for (const auto &[indices, d] : derivs) + for (const auto& [order, derivs] : params_derivatives) + for (const auto& [indices, d] : derivs) d->computeTemporaryTerms(order, temp_terms_map, reference_count, true); - for (const auto &[order, tts] : temp_terms_map) + for (const auto& [order, tts] : temp_terms_map) copy(temp_terms_map[order].begin(), temp_terms_map[order].end(), - inserter(params_derivs_temporary_terms[order], params_derivs_temporary_terms[order].begin())); + inserter(params_derivs_temporary_terms[order], + params_derivs_temporary_terms[order].begin())); - for (int idx {0}; - const auto &[order, tts] : params_derivs_temporary_terms) - for (const auto &tt : tts) + for (int idx {0}; const auto& [order, tts] : params_derivs_temporary_terms) + for (const auto& tt : tts) params_derivs_temporary_terms_idxs[tt] = idx++; } @@ -1527,7 +1544,7 @@ ModelTree::isNonstationary(int symb_id) const } void -ModelTree::writeJsonModelEquations(ostream &output, bool residuals) const +ModelTree::writeJsonModelEquations(ostream& output, bool residuals) const { if (residuals) output << endl << R"("residuals":[)" << endl; @@ -1538,7 +1555,7 @@ ModelTree::writeJsonModelEquations(ostream &output, bool residuals) const if (eq > 0) output << ", "; - BinaryOpNode *eq_node = equations[eq]; + BinaryOpNode* eq_node = equations[eq]; expr_t lhs = eq_node->arg1; expr_t rhs = eq_node->arg2; @@ -1563,12 +1580,10 @@ ModelTree::writeJsonModelEquations(ostream &output, bool residuals) const if (equations_lineno[eq]) output << R"(, "line": )" << *equations_lineno[eq]; - if (auto eqtags = equation_tags.getTagsByEqn(eq); - !eqtags.empty()) + if (auto eqtags = equation_tags.getTagsByEqn(eq); !eqtags.empty()) { output << R"(, "tags": {)"; - for (bool printed_something{false}; - const auto &[name, value] : eqtags) + for (bool printed_something {false}; const auto& [name, value] : eqtags) { if (exchange(printed_something, true)) output << ", "; @@ -1584,7 +1599,7 @@ ModelTree::writeJsonModelEquations(ostream &output, bool residuals) const } string -ModelTree::matlab_arch(const string &mexext) +ModelTree::matlab_arch(const string& mexext) { if (mexext == "mexglx") return "glnx86"; @@ -1605,7 +1620,8 @@ ModelTree::matlab_arch(const string &mexext) return "maca64"; else { - cerr << "ERROR: 'mexext' option to preprocessor incorrectly set, needed with 'use_dll'" << endl; + cerr << "ERROR: 'mexext' option to preprocessor incorrectly set, needed with 'use_dll'" + << endl; exit(EXIT_FAILURE); } } @@ -1613,7 +1629,7 @@ ModelTree::matlab_arch(const string &mexext) #ifdef __APPLE__ pair -ModelTree::findCompilerOnMacos(const string &mexext) +ModelTree::findCompilerOnMacos(const string& mexext) { /* Try to find gcc, otherwise use Apple’s clang compiler. Homebrew binaries are located in /usr/local/bin/ on x86_64 systems and in @@ -1625,12 +1641,12 @@ ModelTree::findCompilerOnMacos(const string &mexext) if (filesystem::path global_gcc_path {"/usr/local/bin/gcc-" + macos_gcc_version}; exists(global_gcc_path) && mexext == "mexmaci64") - return { global_gcc_path, false }; + return {global_gcc_path, false}; else if (filesystem::path global_gcc_path {"/opt/homebrew/bin/gcc-" + macos_gcc_version}; exists(global_gcc_path) && mexext == "mexmaca64") - return { global_gcc_path, false }; + return {global_gcc_path, false}; else if (filesystem::path global_clang_path {"/usr/bin/clang"}; exists(global_clang_path)) - return { global_clang_path, true }; + return {global_clang_path, true}; else { cerr << "ERROR: You must install gcc-" << macos_gcc_version @@ -1647,12 +1663,18 @@ ModelTree::findCompilerOnMacos(const string &mexext) #endif filesystem::path -ModelTree::compileMEX(const filesystem::path &output_dir, const string &output_basename, const string &mexext, const vector &input_files, const filesystem::path &matlabroot, bool link) const +ModelTree::compileMEX(const filesystem::path& output_dir, const string& output_basename, + const string& mexext, const vector& input_files, + const filesystem::path& matlabroot, bool link) const { assert(!mex_compilation_workers.empty()); - const string gcc_opt_flags { "-O3 -g0 --param ira-max-conflict-table-size=1 -fno-forward-propagate -fno-gcse -fno-dce -fno-dse -fno-tree-fre -fno-tree-pre -fno-tree-cselim -fno-tree-dse -fno-tree-dce -fno-tree-pta -fno-gcse-after-reload" }; - const string clang_opt_flags { "-O3 -g0 --param ira-max-conflict-table-size=1 -Wno-unused-command-line-argument" }; + const string gcc_opt_flags { + "-O3 -g0 --param ira-max-conflict-table-size=1 -fno-forward-propagate -fno-gcse -fno-dce " + "-fno-dse -fno-tree-fre -fno-tree-pre -fno-tree-cselim -fno-tree-dse -fno-tree-dce " + "-fno-tree-pta -fno-gcse-after-reload"}; + const string clang_opt_flags { + "-O3 -g0 --param ira-max-conflict-table-size=1 -Wno-unused-command-line-argument"}; filesystem::path compiler; ostringstream flags; @@ -1661,7 +1683,8 @@ ModelTree::compileMEX(const filesystem::path &output_dir, const string &output_b if (matlabroot.empty()) { - cerr << "ERROR: 'matlabroot' option to preprocessor is not set, needed with 'use_dll'" << endl; + cerr << "ERROR: 'matlabroot' option to preprocessor is not set, needed with 'use_dll'" + << endl; exit(EXIT_FAILURE); } @@ -1719,14 +1742,14 @@ ModelTree::compileMEX(const filesystem::path &output_dir, const string &output_b if (user_set_compiler.empty()) cmd << compiler << " "; + else if (!filesystem::exists(user_set_compiler)) + { + cerr << "Error: The specified compiler '" << user_set_compiler + << "' cannot be found on your system" << endl; + exit(EXIT_FAILURE); + } else - if (!filesystem::exists(user_set_compiler)) - { - cerr << "Error: The specified compiler '" << user_set_compiler << "' cannot be found on your system" << endl; - exit(EXIT_FAILURE); - } - else - cmd << user_set_compiler << " "; + cmd << user_set_compiler << " "; if (user_set_subst_flags.empty()) cmd << (is_clang ? clang_opt_flags : gcc_opt_flags) << " " << flags.str() << " "; @@ -1736,7 +1759,7 @@ ModelTree::compileMEX(const filesystem::path &output_dir, const string &output_b if (!user_set_add_flags.empty()) cmd << user_set_add_flags << " "; - for (auto &f : input_files) + for (auto& f : input_files) cmd << f << " "; cmd << "-o " << output_filename << " "; @@ -1760,11 +1783,8 @@ ModelTree::compileMEX(const filesystem::path &output_dir, const string &output_b // The prerequisites are the object files among the input files set prerequisites; - copy_if(input_files.begin(), input_files.end(), - inserter(prerequisites, prerequisites.end()), [](const auto &p) - { - return p.extension() == ".o"; - }); + copy_if(input_files.begin(), input_files.end(), inserter(prerequisites, prerequisites.end()), + [](const auto& p) { return p.extension() == ".o"; }); unique_lock lk {mex_compilation_mut}; mex_compilation_queue.emplace_back(output_filename, prerequisites, cmd.str()); @@ -1784,7 +1804,7 @@ ModelTree::reorderAuxiliaryEquations() map auxEndoToEq; for (int i = 0; i < n; i++) { - auto varexpr = dynamic_cast(aux_equations[i]->arg1); + auto varexpr = dynamic_cast(aux_equations[i]->arg1); assert(varexpr && symbol_table.getType(varexpr->symb_id) == SymbolType::endogenous); auxEndoToEq[varexpr->symb_id] = i; } @@ -1799,8 +1819,7 @@ ModelTree::reorderAuxiliaryEquations() set endos; aux_equations[i]->collectVariables(SymbolType::endogenous, endos); for (int endo : endos) - if (auto it = auxEndoToEq.find(endo); - it != auxEndoToEq.end() && it->second != i) + if (auto it = auxEndoToEq.find(endo); it != auxEndoToEq.end() && it->second != i) add_edge(i, it->second, g); } @@ -1820,13 +1839,13 @@ map, expr_t> ModelTree::collectFirstOrderDerivativesEndogenous() { map, expr_t> endo_derivatives; - for (auto &[indices, d1] : derivatives[1]) + for (auto& [indices, d1] : derivatives[1]) if (getTypeByDerivID(indices[1]) == SymbolType::endogenous) { int eq = indices[0]; - int var { getTypeSpecificIDByDerivID(indices[1]) }; + int var {getTypeSpecificIDByDerivID(indices[1])}; int lag = getLagByDerivID(indices[1]); - endo_derivatives[{ eq, var, lag }] = d1; + endo_derivatives[{eq, var, lag}] = d1; } return endo_derivatives; } @@ -1839,9 +1858,9 @@ ModelTree::computeSymbolicJacobian(bool contemporaneous_only) const { set> endos_and_lags; equations[i]->collectEndogenous(endos_and_lags); - for (const auto &[endo, lag] : endos_and_lags) + for (const auto& [endo, lag] : endos_and_lags) if (!contemporaneous_only || lag == 0) - symbolic_jacobian.try_emplace({ i, endo }, 1); + symbolic_jacobian.try_emplace({i, endo}, 1); } return symbolic_jacobian; } @@ -1850,29 +1869,30 @@ pair ModelTree::computeLeftHandSideSymbolicJacobian() const { jacob_map_t lhs_symbolic_jacobian; - auto not_contemporaneous = [](const pair &p) { return p.second != 0; }; + auto not_contemporaneous = [](const pair& p) { return p.second != 0; }; for (int eq {0}; eq < static_cast(equations.size()); eq++) - if (equations_lineno[eq]) // Hand-written equation: test whether LHS has single contemporaneous endo + if (equations_lineno[eq]) // Hand-written equation: test whether LHS has single contemporaneous + // endo { set> endos_and_lags; equations[eq]->arg1->collectEndogenous(endos_and_lags); erase_if(endos_and_lags, not_contemporaneous); if (endos_and_lags.size() == 1) - lhs_symbolic_jacobian.try_emplace({ eq, endos_and_lags.begin()->first }, 1); + lhs_symbolic_jacobian.try_emplace({eq, endos_and_lags.begin()->first}, 1); else - return { false, {} }; + return {false, {}}; } else // Generated equation: keep all endos on both LHS and RHS { set> endos_and_lags; equations[eq]->collectEndogenous(endos_and_lags); erase_if(endos_and_lags, not_contemporaneous); - for (const auto &[endo, lag] : endos_and_lags) - lhs_symbolic_jacobian.try_emplace({ eq, endo }, 1); + for (const auto& [endo, lag] : endos_and_lags) + lhs_symbolic_jacobian.try_emplace({eq, endo}, 1); } - return { true, lhs_symbolic_jacobian }; + return {true, lhs_symbolic_jacobian}; } void @@ -1894,12 +1914,12 @@ ModelTree::getRHSFromLHS(expr_t lhs) const for (auto eq : equations) if (eq->arg1 == lhs) return eq->arg2; - throw ExprNode::MatchFailureException{"Cannot find an equation with the requested LHS"}; + throw ExprNode::MatchFailureException {"Cannot find an equation with the requested LHS"}; } void -ModelTree::initializeMEXCompilationWorkers(int numworkers, const filesystem::path &dynareroot, - const string &mexext) +ModelTree::initializeMEXCompilationWorkers(int numworkers, const filesystem::path& dynareroot, + const string& mexext) { assert(numworkers > 0); assert(mex_compilation_workers.empty()); @@ -1907,8 +1927,7 @@ 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) - { + mex_compilation_workers.emplace_back([](stop_token stoken) { unique_lock lk {mex_compilation_mut}; filesystem::path output; string cmd; @@ -1916,10 +1935,9 @@ ModelTree::initializeMEXCompilationWorkers(int numworkers, const filesystem::pat /* Look for an object to compile, whose prerequisites are already compiled. If found, remove it from the queue, save the output path and the compilation command, and return true. Must be run under the lock. */ - auto pick_job = [&cmd, &output] - { + auto pick_job = [&cmd, &output] { for (auto it {mex_compilation_queue.begin()}; it != mex_compilation_queue.end(); ++it) - if (const auto &prerequisites {get<1>(*it)}; // Will become dangling after erase + if (const auto& prerequisites {get<1>(*it)}; // Will become dangling after erase includes(mex_compilation_done.begin(), mex_compilation_done.end(), prerequisites.begin(), prerequisites.end())) { @@ -1936,7 +1954,7 @@ ModelTree::initializeMEXCompilationWorkers(int numworkers, const filesystem::pat if (mex_compilation_cv.wait(lk, stoken, pick_job)) { lk.unlock(); - int r { system(cmd.c_str()) }; + int r {system(cmd.c_str())}; lk.lock(); mex_compilation_ongoing.erase(output); if (r) @@ -1963,7 +1981,7 @@ ModelTree::initializeMEXCompilationWorkers(int numworkers, const filesystem::pat /* We can’t use setenv() since it is not available on MinGW. Note that putenv() seems to make an internal copy of the string on MinGW, contrary to what is done on GNU/Linux and macOS. */ - if (putenv(const_cast(newpath.c_str())) != 0) + if (putenv(const_cast(newpath.c_str())) != 0) { cerr << "Can't set PATH" << endl; exit(EXIT_FAILURE); @@ -1975,7 +1993,7 @@ ModelTree::initializeMEXCompilationWorkers(int numworkers, const filesystem::pat /* On macOS, with Octave, enforce our compiler. In particular this is necessary if we’ve selected GCC; otherwise Clang will be used, and it does not accept the same optimization flags (see dynare#1797) */ - auto [compiler_path, is_clang] { findCompilerOnMacos(mexext) }; + auto [compiler_path, is_clang] {findCompilerOnMacos(mexext)}; if (setenv("CC", compiler_path.c_str(), 1) != 0) { cerr << "Can't set CC environment variable" << endl; @@ -1997,11 +2015,12 @@ ModelTree::waitForMEXCompilationWorkers() unique_lock lk {mex_compilation_mut}; mex_compilation_cv.wait(lk, [] { return (mex_compilation_queue.empty() && mex_compilation_ongoing.empty()) - || !mex_compilation_failed.empty(); }); + || !mex_compilation_failed.empty(); + }); if (!mex_compilation_failed.empty()) { cerr << "Compilation failed for: "; - for (const auto &p : mex_compilation_failed) + for (const auto& p : mex_compilation_failed) cerr << p.string() << " "; cerr << endl; lk.unlock(); // So that threads can process their stoken @@ -2010,7 +2029,7 @@ ModelTree::waitForMEXCompilationWorkers() } void -ModelTree::computingPassBlock(const eval_context_t &eval_context, bool no_tmp_terms) +ModelTree::computingPassBlock(const eval_context_t& eval_context, bool no_tmp_terms) { if (!computeNonSingularNormalization(eval_context)) return; @@ -2028,11 +2047,10 @@ ModelTree::computingPassBlock(const eval_context_t &eval_context, bool no_tmp_te } vector -ModelTree::computeCSCColPtr(const SparseColumnMajorOrderMatrix &matrix, int ncols) +ModelTree::computeCSCColPtr(const SparseColumnMajorOrderMatrix& matrix, int ncols) { - vector colptr(ncols+1, matrix.size()); - for (int k {0}, current_col {0}; - const auto &[indices, d1] : matrix) + vector colptr(ncols + 1, matrix.size()); + for (int k {0}, current_col {0}; const auto& [indices, d1] : matrix) { while (indices.second >= current_col) colptr[current_col++] = k; @@ -2042,7 +2060,7 @@ ModelTree::computeCSCColPtr(const SparseColumnMajorOrderMatrix &matrix, int ncol } void -ModelTree::writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const +ModelTree::writeAuxVarRecursiveDefinitions(ostream& output, ExprNodeOutputType output_type) const { deriv_node_temp_terms_t tef_terms; for (auto aux_equation : aux_equations) diff --git a/src/ModelTree.hh b/src/ModelTree.hh index 88a2b114..0ff060e4 100644 --- a/src/ModelTree.hh +++ b/src/ModelTree.hh @@ -18,45 +18,46 @@ */ #ifndef _MODELTREE_HH -#define _MODELTREE_HH +# define _MODELTREE_HH -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include -#include "DataTree.hh" -#include "EquationTags.hh" -#include "ExtendedPreprocessorTypes.hh" -#include "Bytecode.hh" +# include "Bytecode.hh" +# include "DataTree.hh" +# include "EquationTags.hh" +# include "ExtendedPreprocessorTypes.hh" using namespace std; // Helper to convert a vector into a tuple template auto -vectorToTupleHelper(const vector &v, index_sequence) +vectorToTupleHelper(const vector& v, index_sequence) { - return tuple{v[Indices]...}; + return tuple {v[Indices]...}; } template auto -vectorToTuple(const vector &v) +vectorToTuple(const vector& v) { assert(v.size() >= N); return vectorToTupleHelper(v, make_index_sequence()); } -//! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a expr_t on the new normalized equation -using equation_type_and_normalized_equation_t = vector>; +//! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a +//! expr_t on the new normalized equation +using equation_type_and_normalized_equation_t = vector>; //! Vector describing variables: max_lag in the block, max_lead in the block using lag_lead_vector_t = vector>; @@ -66,9 +67,12 @@ class ModelTree : public DataTree { friend class DynamicModel; friend class StaticModel; + public: // Set via the `compiler` command - string user_set_add_flags, user_set_subst_flags, user_set_add_libs, user_set_subst_libs, user_set_compiler; + string user_set_add_flags, user_set_subst_flags, user_set_add_libs, user_set_subst_libs, + user_set_compiler; + protected: /* * ************** BEGIN ************** @@ -81,7 +85,7 @@ protected: * that's a place to update future structures. */ //! Stores declared and generated auxiliary equations - vector equations; + vector equations; /* Stores line numbers of declared equations; undefined in some cases (e.g. auxiliary equations) */ vector> equations_lineno; @@ -101,10 +105,10 @@ protected: For example, such a divergence appears when there is an expectation operator in a ramsey model, see tests/optimal_policy/nk_ramsey_expectation.mod */ - vector aux_equations; + vector aux_equations; //! Maximum order at which (endogenous) derivatives have been computed - int computed_derivs_order{0}; + int computed_derivs_order {0}; //! Stores derivatives /*! Index 0 is not used, index 1 contains first derivatives, ... @@ -123,7 +127,7 @@ protected: struct columnMajorOrderLess { bool - operator()(const pair &p1, const pair &p2) const + operator()(const pair& p1, const pair& p2) const { return p1.second < p2.second || (p1.second == p2.second && p1.first < p2.first); } @@ -144,7 +148,7 @@ protected: In inner maps, the vector of integers consists of: the equation index, then the derivation IDs of endogenous (in non-decreasing order), then the IDs of parameters (in non-decreasing order)*/ - map, map, expr_t>> params_derivatives; + map, map, expr_t>> params_derivatives; //! Temporary terms for residuals and derivatives /*! Index 0 is temp. terms of residuals, index 1 for first derivatives, ... */ @@ -179,7 +183,8 @@ protected: Set by updateReverseVariableEquationOrderings() */ vector eq_idx_orig2block, endo_idx_orig2block; - //! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a expr_t on the new normalized equation + //! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a + //! expr_t on the new normalized equation equation_type_and_normalized_equation_t equation_type_and_normalized_equation; /* Stores derivatives of each block w.r.t. endogenous that belong to it. @@ -192,10 +197,12 @@ protected: public: BlockSimulationType simulation_type; int first_equation; // Stores a block-ordered equation ID - int size{0}; - int mfs_size{0}; // Size of the minimal feedback set - bool linear{true}; // Whether the block is linear in endogenous variable - int max_endo_lag{0}, max_endo_lead{0}; // Maximum lag/lead on endos that appear in and *that belong to* the block + int size {0}; + int mfs_size {0}; // Size of the minimal feedback set + bool linear {true}; // Whether the block is linear in endogenous variable + int max_endo_lag {0}, + max_endo_lead { + 0}; // Maximum lag/lead on endos that appear in and *that belong to* the block int getRecursiveSize() const @@ -267,7 +274,7 @@ protected: //! Computes derivatives /*! \param order the derivation order \param vars the derivation IDs w.r.t. which compute the derivatives */ - void computeDerivatives(int order, const set &vars); + void computeDerivatives(int order, const set& vars); //! Computes derivatives of the Jacobian and Hessian w.r. to parameters void computeParamsDerivatives(int paramsDerivsOrder); //! Computes temporary terms (for all equations and derivatives) @@ -279,29 +286,33 @@ protected: void computeParamsDerivativesTemporaryTerms(); //! Writes temporary terms template - void writeTemporaryTerms(const temporary_terms_t &tt, temporary_terms_t &temp_term_union, const temporary_terms_idxs_t &tt_idxs, ostream &output, deriv_node_temp_terms_t &tef_terms) const; - void writeJsonTemporaryTerms(const temporary_terms_t &tt, temporary_terms_t &temp_term_union, ostream &output, deriv_node_temp_terms_t &tef_terms, const string &concat) const; + void writeTemporaryTerms(const temporary_terms_t& tt, temporary_terms_t& temp_term_union, + const temporary_terms_idxs_t& tt_idxs, ostream& output, + deriv_node_temp_terms_t& tef_terms) const; + void writeJsonTemporaryTerms(const temporary_terms_t& tt, temporary_terms_t& temp_term_union, + ostream& output, deriv_node_temp_terms_t& tef_terms, + const string& concat) const; //! Writes temporary terms in bytecode template - 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, + BytecodeWriter& 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 */ - int writeBytecodeBinFile(const filesystem::path &filename, bool is_two_boundaries) const; + int writeBytecodeBinFile(const filesystem::path& filename, bool is_two_boundaries) const; //! Adds per-block information for bytecode simulation in a separate .bin file - int writeBlockBytecodeBinFile(ofstream &bin_file, int block) const; + int writeBlockBytecodeBinFile(ofstream& bin_file, int block) const; //! Fixes output when there are more than 32 nested parens, Issue #1201 - void fixNestedParenthesis(ostringstream &output, map &tmp_paren_vars, bool &message_printed) const; + void fixNestedParenthesis(ostringstream& output, map& tmp_paren_vars, + bool& message_printed) const; //! Tests if string contains more than 32 nested parens, Issue #1201 - bool testNestedParenthesis(const string &str) const; + bool testNestedParenthesis(const string& str) const; //! Writes model equations template - void writeModelEquations(ostream &output, const temporary_terms_t &temporary_terms) const; + void writeModelEquations(ostream& output, const temporary_terms_t& temporary_terms) const; // Returns outputs for derivatives and temporary terms at each derivation order template @@ -309,83 +320,94 @@ protected: // Writes and compiles dynamic/static file (C version, legacy representation) template - void writeModelCFile(const string &basename, const string &mexext, const filesystem::path &matlabroot) const; + void writeModelCFile(const string& basename, const string& mexext, + const filesystem::path& matlabroot) const; // Writes per-block residuals and temporary terms (incl. for derivatives) template - void writePerBlockHelper(int blk, ostream &output, temporary_terms_t &temporary_terms) const; + void writePerBlockHelper(int blk, ostream& output, temporary_terms_t& temporary_terms) const; // Writes per-block Jacobian (sparse representation) // Assumes temporary terms for derivatives are already set. template - void writeSparsePerBlockJacobianHelper(int blk, ostream &output, temporary_terms_t &temporary_terms) const; + void writeSparsePerBlockJacobianHelper(int blk, ostream& output, + temporary_terms_t& temporary_terms) const; /* Helper for writing derivatives w.r.t. parameters. Returns { tt, rp, gp, rpp, gpp, hp, g3p }. g3p is empty if requesting a static output type. */ template - tuple writeParamsDerivativesFileHelper() const; + tuple + writeParamsDerivativesFileHelper() const; // Helper for writing bytecode (without block decomposition) template - void writeBytecodeHelper(BytecodeWriter &code_file) const; + void writeBytecodeHelper(BytecodeWriter& code_file) const; // Helper for writing blocks in bytecode template - void writeBlockBytecodeHelper(BytecodeWriter &code_file, int block, temporary_terms_t &temporary_terms_union) const; + void writeBlockBytecodeHelper(BytecodeWriter& code_file, int block, + temporary_terms_t& temporary_terms_union) const; // Helper for writing sparse derivatives indices in MATLAB/Octave driver file template - void writeDriverSparseIndicesHelper(ostream &output) const; + void writeDriverSparseIndicesHelper(ostream& output) const; // Helper for writing sparse derivatives indices in JSON template - void writeJsonSparseIndicesHelper(ostream &output) const; + void writeJsonSparseIndicesHelper(ostream& output) const; // Helper for writing sparse block derivatives indices in MATLAB/Octave driver file template - void writeBlockDriverSparseIndicesHelper(ostream &output) const; + void writeBlockDriverSparseIndicesHelper(ostream& output) const; /* Helper for writing JSON output for residuals and derivatives. Returns mlv and derivatives output at each derivation order. */ template - pair> writeJsonComputingPassOutputHelper(bool writeDetails) const; + pair> + writeJsonComputingPassOutputHelper(bool writeDetails) const; /* Helper for writing JSON derivatives w.r.t. parameters. Returns { mlv, tt, rp, gp, rpp, gpp, hp, g3p }. g3p is empty if requesting a static output type. */ template - tuple writeJsonParamsDerivativesHelper(bool writeDetails) const; + tuple + writeJsonParamsDerivativesHelper(bool writeDetails) const; //! Writes JSON model equations //! if residuals = true, we are writing the dynamic/static model. //! Otherwise, just the model equations (with line numbers, no tmp terms) - void writeJsonModelEquations(ostream &output, bool residuals) const; + void writeJsonModelEquations(ostream& output, bool residuals) const; /* Writes JSON model local variables. Optionally put the external function variable calls into TEF terms */ - void writeJsonModelLocalVariables(ostream &output, bool write_tef_terms, deriv_node_temp_terms_t &tef_terms) const; + void writeJsonModelLocalVariables(ostream& output, bool write_tef_terms, + deriv_node_temp_terms_t& tef_terms) const; //! Writes model equations in bytecode template - void writeBytecodeModelEquations(BytecodeWriter &code_file, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms) const; + void writeBytecodeModelEquations(BytecodeWriter& code_file, + const temporary_terms_t& temporary_terms, + const deriv_node_temp_terms_t& tef_terms) const; // Writes the sparse representation of the model in MATLAB/Octave template - void writeSparseModelMFiles(const string &basename) const; + void writeSparseModelMFiles(const string& basename) const; // Writes and compiles the sparse representation of the model in C template - void writeSparseModelCFiles(const string &basename, const string &mexext, const filesystem::path &matlabroot) const; + void writeSparseModelCFiles(const string& basename, const string& mexext, + const filesystem::path& matlabroot) const; // Writes the sparse representation of the model in Julia // Assumes that the directory /model/julia/ already exists template - void writeSparseModelJuliaFiles(const string &basename) const; + void writeSparseModelJuliaFiles(const string& basename) const; //! Writes LaTeX model file - void writeLatexModelFile(const string &mod_basename, const string &latex_basename, ExprNodeOutputType output_type, bool write_equation_tags) const; + void writeLatexModelFile(const string& mod_basename, const string& latex_basename, + ExprNodeOutputType output_type, bool write_equation_tags) const; /* Write files for helping a user to debug their model (MATLAB/Octave, sparse representation). @@ -394,11 +416,11 @@ protected: They are not optimized for performance (hence in particular the absence of a C version, or the non-reuse of temporary terms). */ template - void writeDebugModelMFiles(const string &basename) const; + void writeDebugModelMFiles(const string& basename) const; // Write the file that sets auxiliary variables given the original variables template - void writeSetAuxiliaryVariablesFile(const string &basename, bool julia) const; + void writeSetAuxiliaryVariablesFile(const string& basename, bool julia) const; private: //! Sparse matrix of double to store the values of the static Jacobian @@ -452,33 +474,37 @@ private: string unmatched_endo; // Name of endogenous not in maximum cardinality matching }; - //! Compute the matching between endogenous and variable using the jacobian contemporaneous_jacobian + //! Compute the matching between endogenous and variable using the jacobian + //! contemporaneous_jacobian /*! - \param contemporaneous_jacobian Jacobian used as an incidence matrix: all elements declared in the map (even if they are zero), are used as vertices of the incidence matrix - \return True if a complete normalization has been achieved + \param contemporaneous_jacobian Jacobian used as an incidence matrix: all elements declared in + the map (even if they are zero), are used as vertices of the incidence matrix \return True if a + complete normalization has been achieved */ - void computeNormalization(const jacob_map_t &contemporaneous_jacobian); + void computeNormalization(const jacob_map_t& contemporaneous_jacobian); //! Try to compute the matching between endogenous and variable using a decreasing cutoff /*! Applied to the jacobian contemporaneous_jacobian and stop when a matching is found. - If no matching is found using a strictly positive cutoff, then a zero cutoff is applied (i.e. use a symbolic normalization); in that case, the method adds zeros in the jacobian matrices to reflect all the edges in the symbolic incidence matrix. - If no matching is found with a zero cutoff, an error message is printed. - The resulting normalization is stored in endo2eq. - Returns a boolean indicating success. + If no matching is found using a strictly positive cutoff, then a zero cutoff is applied (i.e. + use a symbolic normalization); in that case, the method adds zeros in the jacobian matrices to + reflect all the edges in the symbolic incidence matrix. If no matching is found with a zero + cutoff, an error message is printed. The resulting normalization is stored in endo2eq. Returns a + boolean indicating success. */ - bool computeNonSingularNormalization(const eval_context_t &eval_context); + bool computeNonSingularNormalization(const eval_context_t& eval_context); //! Evaluate the jacobian (w.r.t. endogenous) and suppress all the elements below the cutoff /*! Returns the contemporaneous_jacobian. Elements below the cutoff are discarded. External functions are evaluated to 1. */ - jacob_map_t evaluateAndReduceJacobian(const eval_context_t &eval_context) const; + jacob_map_t evaluateAndReduceJacobian(const eval_context_t& eval_context) const; /* Search the equations and variables belonging to the prologue and the epilogue of the model. Initializes “eq_idx_block2orig” and “endo_idx_block2orig”. Returns the sizes of the prologue and epilogue. */ pair computePrologueAndEpilogue(); //! Determine the type of each equation of model and try to normalize the unnormalized equation - void equationTypeDetermination(const map, expr_t> &first_order_endo_derivatives); + void + equationTypeDetermination(const map, expr_t>& first_order_endo_derivatives); /* Fills the max lags/leads and n_{static,mixed,forward,backward} fields of a given block. Needs the fields size and first_equation. */ @@ -512,25 +538,29 @@ protected: EquationType getBlockEquationType(int blk, int eq) const { - return equation_type_and_normalized_equation[eq_idx_block2orig[blocks[blk].first_equation+eq]].first; + return equation_type_and_normalized_equation[eq_idx_block2orig[blocks[blk].first_equation + eq]] + .first; }; //! Return true if the equation has been normalized bool isBlockEquationRenormalized(int blk, int eq) const { - return equation_type_and_normalized_equation[eq_idx_block2orig[blocks[blk].first_equation + eq]].first == EquationType::evaluateRenormalized; + return equation_type_and_normalized_equation[eq_idx_block2orig[blocks[blk].first_equation + eq]] + .first + == EquationType::evaluateRenormalized; }; //! Return the expr_t of equation belonging to the block - BinaryOpNode * + BinaryOpNode* getBlockEquationExpr(int blk, int eq) const { return equations[eq_idx_block2orig[blocks[blk].first_equation + eq]]; }; //! Return the expr_t of renormalized equation belonging to the block - BinaryOpNode * + BinaryOpNode* getBlockEquationRenormalizedExpr(int blk, int eq) const { - return equation_type_and_normalized_equation[eq_idx_block2orig[blocks[blk].first_equation + eq]].second; + return equation_type_and_normalized_equation[eq_idx_block2orig[blocks[blk].first_equation + eq]] + .second; }; //! Return the original number of equation belonging to the block int @@ -573,7 +603,7 @@ protected: be overriden in derived classes which don’t support block decomposition (currently Epilogue and PlannerObjective). Sets “block_decomposed” to true in case of success. */ - virtual void computingPassBlock(const eval_context_t &eval_context, bool no_tmp_terms); + virtual void computingPassBlock(const eval_context_t& eval_context, bool no_tmp_terms); /* Get column number within Jacobian of a given block. “var” is the block-specific endogenous variable index. */ @@ -584,61 +614,64 @@ protected: /* Given a sparse matrix in column major order, returns the colptr pointer for the CSC storage */ - static vector computeCSCColPtr(const SparseColumnMajorOrderMatrix &matrix, int ncols); + static vector computeCSCColPtr(const SparseColumnMajorOrderMatrix& matrix, int ncols); private: //! Internal helper for the copy constructor and assignment operator /*! Copies all the structures that contain ExprNode*, by the converting the pointers into their equivalent in the new tree */ - void copyHelper(const ModelTree &m); + void copyHelper(const ModelTree& m); //! Returns the name of the MATLAB architecture given the extension used for MEX files - static string matlab_arch(const string &mexext); -#ifdef __APPLE__ + static string matlab_arch(const string& mexext); +# ifdef __APPLE__ /* Finds a suitable compiler on macOS. The boolean is false if this is GCC and true if this is Clang */ - static pair findCompilerOnMacos(const string &mexext); -#endif + static pair findCompilerOnMacos(const string& mexext); +# endif /* Compiles a MEX file (if link=true) or an object file to be linked later into a MEX file (if link=false). The compilation is done in separate worker threads working in parallel, so the call to this function is not blocking. The dependency of a linked MEX file upon intermediary objects is nicely handled. Returns the name of the output file (to be reused later as input file if link=false). */ - filesystem::path compileMEX(const filesystem::path &output_dir, const string &output_basename, const string &mexext, const vector &input_files, const filesystem::path &matlabroot, bool link = true) const; + filesystem::path compileMEX(const filesystem::path& output_dir, const string& output_basename, + const string& mexext, const vector& input_files, + const filesystem::path& matlabroot, bool link = true) const; public: - ModelTree(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg, - bool is_dynamic_arg = false); + ModelTree(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg, bool is_dynamic_arg = false); protected: - ModelTree(const ModelTree &m); - ModelTree &operator=(const ModelTree &m); + ModelTree(const ModelTree& m); + ModelTree& operator=(const ModelTree& m); public: //! Absolute value under which a number is considered to be zero - double cutoff{1e-15}; + double cutoff {1e-15}; //! Declare a node as an equation of the model; also give its line number void addEquation(expr_t eq, optional lineno); //! Declare a node as an equation of the model, also giving its tags void addEquation(expr_t eq, optional lineno, map eq_tags); - //! Declare a node as an auxiliary equation of the model, adding it at the end of the list of auxiliary equations + //! 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); //! Returns the number of equations in the model int equation_number() const; //! Adds a trend variable with its growth factor - void addTrendVariables(const vector &trend_vars, expr_t growth_factor) noexcept(false); + void addTrendVariables(const vector& trend_vars, expr_t growth_factor) noexcept(false); //! Adds a nonstationary variables with their (common) deflator - void addNonstationaryVariables(const vector &nonstationary_vars, bool log_deflator, expr_t deflator) noexcept(false); + void addNonstationaryVariables(const vector& nonstationary_vars, bool log_deflator, + expr_t deflator) noexcept(false); //! Is a given variable non-stationary? bool isNonstationary(int symb_id) const; void set_cutoff_to_zero(); /*! Reorder auxiliary variables so that they appear in recursive order in set_auxiliary_variables.m and dynamic_set_auxiliary_series.m */ void reorderAuxiliaryEquations(); - //! Find equations of the form “variable=constant”, excluding equations with “mcp” tag (see dynare#1697) - void findConstantEquationsWithoutMcpTag(map &subst_table) const; + //! Find equations of the form “variable=constant”, excluding equations with “mcp” tag (see + //! dynare#1697) + void findConstantEquationsWithoutMcpTag(map& subst_table) const; /* Given an expression, searches for the first equation that has exactly this expression on the LHS, and returns the RHS of that equation. If no such equation can be found, throws an ExprNode::MatchFailureExpression */ @@ -646,30 +679,30 @@ public: /* Initialize the MEX compilation workers (and some environment variables needed for finding GCC) */ - static void initializeMEXCompilationWorkers(int numworkers, const filesystem::path &dynareroot, - const string &mexext); + static void initializeMEXCompilationWorkers(int numworkers, const filesystem::path& dynareroot, + const string& mexext); // Waits until the MEX compilation queue is empty static void waitForMEXCompilationWorkers(); // Write the definitions of the auxiliary variables (assumed to be in recursive order) - void writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const; + void writeAuxVarRecursiveDefinitions(ostream& output, ExprNodeOutputType output_type) const; //! Returns the vector of non-zero derivative counts - const vector & + const vector& getNNZDerivatives() const { return NNZDerivatives; } //! Returns the vector of temporary terms derivatives - const vector & + const vector& getTemporaryTermsDerivatives() const { return temporary_terms_derivatives; } - //!Returns the maximum order of computed derivatives + //! Returns the maximum order of computed derivatives int getComputedDerivsOrder() const { @@ -709,21 +742,20 @@ public: template void -ModelTree::writeTemporaryTerms(const temporary_terms_t &tt, - temporary_terms_t &temp_term_union, - const temporary_terms_idxs_t &tt_idxs, - ostream &output, deriv_node_temp_terms_t &tef_terms) const +ModelTree::writeTemporaryTerms(const temporary_terms_t& tt, temporary_terms_t& temp_term_union, + const temporary_terms_idxs_t& tt_idxs, ostream& output, + deriv_node_temp_terms_t& tef_terms) const { for (auto it : tt) { - if (dynamic_cast(it)) + if (dynamic_cast(it)) it->writeExternalFunctionOutput(output, output_type, temp_term_union, tt_idxs, tef_terms); it->writeOutput(output, output_type, tt, tt_idxs, tef_terms); output << " = "; it->writeOutput(output, output_type, temp_term_union, tt_idxs, tef_terms); - if constexpr(isCOutput(output_type) || isMatlabOutput(output_type)) + if constexpr (isCOutput(output_type) || isMatlabOutput(output_type)) output << ";"; output << endl; @@ -733,12 +765,12 @@ ModelTree::writeTemporaryTerms(const temporary_terms_t &tt, template void -ModelTree::writeModelEquations(ostream &output, const temporary_terms_t &temporary_terms) const +ModelTree::writeModelEquations(ostream& output, const temporary_terms_t& temporary_terms) const { for (int eq {0}; eq < static_cast(equations.size()); eq++) { - BinaryOpNode *eq_node { equations[eq] }; - expr_t lhs { eq_node->arg1 }, rhs { eq_node->arg2 }; + BinaryOpNode* eq_node {equations[eq]}; + expr_t lhs {eq_node->arg1}, rhs {eq_node->arg2}; // Test if the right hand side of the equation is empty. double vrhs {1.0}; @@ -746,15 +778,14 @@ ModelTree::writeModelEquations(ostream &output, const temporary_terms_t &tempora { vrhs = rhs->eval({}); } - catch (ExprNode::EvalException &e) + catch (ExprNode::EvalException& e) { } if (vrhs != 0) // The right hand side of the equation is not empty ==> residual=lhs-rhs; { output << " residual" << LEFT_ARRAY_SUBSCRIPT(output_type) - << eq + ARRAY_SUBSCRIPT_OFFSET(output_type) - << RIGHT_ARRAY_SUBSCRIPT(output_type) + << eq + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type) << " = ("; lhs->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs); output << ") - ("; @@ -764,8 +795,7 @@ ModelTree::writeModelEquations(ostream &output, const temporary_terms_t &tempora else // The right hand side of the equation is empty ==> residual=lhs; { output << "residual" << LEFT_ARRAY_SUBSCRIPT(output_type) - << eq + ARRAY_SUBSCRIPT_OFFSET(output_type) - << RIGHT_ARRAY_SUBSCRIPT(output_type) + << eq + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type) << " = "; lhs->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs); output << ";" << endl; @@ -779,7 +809,8 @@ ModelTree::writeModelFileHelper() const { constexpr bool sparse {isSparseModelOutput(output_type)}; - vector d_output(derivatives.size()); // Derivatives output (at all orders, including 0=residual) + vector d_output( + derivatives.size()); // Derivatives output (at all orders, including 0=residual) vector tt_output(derivatives.size()); // Temp terms output (at all orders) deriv_node_temp_terms_t tef_terms; @@ -796,35 +827,36 @@ ModelTree::writeModelFileHelper() const writeTemporaryTerms(temporary_terms_derivatives[1], temp_term_union, temporary_terms_idxs, tt_output[1], tef_terms); - if constexpr(sparse) + if constexpr (sparse) { // NB: we iterate over the Jacobian reordered in column-major order - // Indices of rows and columns are output in M_ and the JSON file (since they are constant) - for (int k {0}; - const auto &[row_col, d1] : jacobian_sparse_column_major_order) + // Indices of rows and columns are output in M_ and the JSON file (since they are + // constant) + for (int k {0}; const auto& [row_col, d1] : jacobian_sparse_column_major_order) { d_output[1] << "g1_v" << LEFT_ARRAY_SUBSCRIPT(output_type) << k + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d1->writeOutput(d_output[1], output_type, temp_term_union, temporary_terms_idxs, tef_terms); + d1->writeOutput(d_output[1], output_type, temp_term_union, temporary_terms_idxs, + tef_terms); d_output[1] << ";" << endl; k++; } } else // Legacy representation (dense matrix) { - for (const auto &[indices, d1] : derivatives[1]) + for (const auto& [indices, d1] : derivatives[1]) { auto [eq, var] = vectorToTuple<2>(indices); d_output[1] << "g1" << LEFT_ARRAY_SUBSCRIPT(output_type); - if constexpr(isMatlabOutput(output_type) || isJuliaOutput(output_type)) + if constexpr (isMatlabOutput(output_type) || isJuliaOutput(output_type)) d_output[1] << eq + 1 << "," << getJacobianCol(var, sparse) + 1; else - d_output[1] << eq + getJacobianCol(var, sparse)*equations.size(); + d_output[1] << eq + getJacobianCol(var, sparse) * equations.size(); d_output[1] << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d1->writeOutput(d_output[1], output_type, - temp_term_union, temporary_terms_idxs, tef_terms); + d1->writeOutput(d_output[1], output_type, temp_term_union, temporary_terms_idxs, + tef_terms); d_output[1] << ";" << endl; } } @@ -837,18 +869,18 @@ ModelTree::writeModelFileHelper() const writeTemporaryTerms(temporary_terms_derivatives[i], temp_term_union, temporary_terms_idxs, tt_output[i], tef_terms); - if constexpr(sparse) + if constexpr (sparse) { /* List non-zero elements of the tensor in row-major order (this is suitable for the k-order solver according to Normann). */ // Tensor indices are output in M_ and the JSON file (since they are constant) - for (int k {0}; - const auto &[vidx, d] : derivatives[i]) + for (int k {0}; const auto& [vidx, d] : derivatives[i]) { d_output[i] << "g" << i << "_v" << LEFT_ARRAY_SUBSCRIPT(output_type) << k + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d->writeOutput(d_output[i], output_type, temp_term_union, temporary_terms_idxs, tef_terms); + d->writeOutput(d_output[i], output_type, temp_term_union, temporary_terms_idxs, + tef_terms); d_output[i] << ";" << endl; k++; } @@ -862,38 +894,39 @@ ModelTree::writeModelFileHelper() const accesses and expression reusage. */ ostringstream i_output, j_output, v_output; - for (int k{0}; // Current line index in the 3-column matrix - const auto &[vidx, d] : derivatives[i]) + for (int k {0}; // Current line index in the 3-column matrix + const auto& [vidx, d] : derivatives[i]) { - int eq{vidx[0]}; + int eq {vidx[0]}; - int col_idx{0}; + int col_idx {0}; for (size_t j = 1; j < vidx.size(); j++) { col_idx *= getJacobianColsNbr(sparse); col_idx += getJacobianCol(vidx[j], sparse); } - if constexpr(isJuliaOutput(output_type)) + if constexpr (isJuliaOutput(output_type)) { d_output[i] << " g" << i << "[" << eq + 1 << "," << col_idx + 1 << "] = "; - d->writeOutput(d_output[i], output_type, temp_term_union, temporary_terms_idxs, tef_terms); + d->writeOutput(d_output[i], output_type, temp_term_union, temporary_terms_idxs, + tef_terms); d_output[i] << endl; } else { i_output << "g" << i << "_i" << LEFT_ARRAY_SUBSCRIPT(output_type) << k + ARRAY_SUBSCRIPT_OFFSET(output_type) - << RIGHT_ARRAY_SUBSCRIPT(output_type) - << "=" << eq + 1 << ";" << endl; + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq + 1 << ";" << endl; j_output << "g" << i << "_j" << LEFT_ARRAY_SUBSCRIPT(output_type) << k + ARRAY_SUBSCRIPT_OFFSET(output_type) - << RIGHT_ARRAY_SUBSCRIPT(output_type) - << "=" << col_idx + 1 << ";" << endl; + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << col_idx + 1 << ";" + << endl; v_output << "g" << i << "_v" << LEFT_ARRAY_SUBSCRIPT(output_type) << k + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d->writeOutput(v_output, output_type, temp_term_union, temporary_terms_idxs, tef_terms); + d->writeOutput(v_output, output_type, temp_term_union, temporary_terms_idxs, + tef_terms); v_output << ";" << endl; k++; @@ -902,59 +935,60 @@ ModelTree::writeModelFileHelper() const // Output symetric elements at order 2 if (i == 2 && vidx[1] != vidx[2]) { - int col_idx_sym{getJacobianCol(vidx[2], sparse) * getJacobianColsNbr(sparse) + getJacobianCol(vidx[1], sparse)}; + int col_idx_sym {getJacobianCol(vidx[2], sparse) * getJacobianColsNbr(sparse) + + getJacobianCol(vidx[1], sparse)}; - if constexpr(isJuliaOutput(output_type)) + if constexpr (isJuliaOutput(output_type)) d_output[2] << " g2[" << eq + 1 << "," << col_idx_sym + 1 << "] = " << "g2[" << eq + 1 << "," << col_idx + 1 << "]" << endl; else { i_output << "g" << i << "_i" << LEFT_ARRAY_SUBSCRIPT(output_type) << k + ARRAY_SUBSCRIPT_OFFSET(output_type) - << RIGHT_ARRAY_SUBSCRIPT(output_type) - << "=" << eq + 1 << ";" << endl; + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq + 1 << ";" + << endl; j_output << "g" << i << "_j" << LEFT_ARRAY_SUBSCRIPT(output_type) << k + ARRAY_SUBSCRIPT_OFFSET(output_type) - << RIGHT_ARRAY_SUBSCRIPT(output_type) - << "=" << col_idx_sym + 1 << ";" << endl; + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << col_idx_sym + 1 + << ";" << endl; v_output << "g" << i << "_v" << LEFT_ARRAY_SUBSCRIPT(output_type) << k + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << "g" << i << "_v" << LEFT_ARRAY_SUBSCRIPT(output_type) - << k-1 + ARRAY_SUBSCRIPT_OFFSET(output_type) + << k - 1 + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type) << ";" << endl; k++; } } } - if constexpr(!isJuliaOutput(output_type)) + if constexpr (!isJuliaOutput(output_type)) d_output[i] << i_output.str() << j_output.str() << v_output.str(); } } - if constexpr(isMatlabOutput(output_type)) + if constexpr (isMatlabOutput(output_type)) { - // Check that we don't have more than 32 nested parenthesis because MATLAB does not suppor this. See Issue #1201 + // Check that we don't have more than 32 nested parenthesis because MATLAB does not suppor + // this. See Issue #1201 map tmp_paren_vars; bool message_printed {false}; - for (auto &it : tt_output) + for (auto& it : tt_output) fixNestedParenthesis(it, tmp_paren_vars, message_printed); - for (auto &it : d_output) + for (auto& it : d_output) fixNestedParenthesis(it, tmp_paren_vars, message_printed); } - return { move(d_output), move(tt_output) }; + return {move(d_output), move(tt_output)}; } template void -ModelTree::writeModelCFile(const string &basename, const string &mexext, - const filesystem::path &matlabroot) const +ModelTree::writeModelCFile(const string& basename, const string& mexext, + const filesystem::path& matlabroot) const { ofstream output; - auto open_file = [&output](const filesystem::path &p) - { + auto open_file = [&output](const filesystem::path& p) { output.open(p, ios::out | ios::binary); if (!output.is_open()) { @@ -963,31 +997,36 @@ ModelTree::writeModelCFile(const string &basename, const string &mexext, } }; - const filesystem::path model_src_dir { filesystem::path{basename} / "model" / "src" }; + const filesystem::path model_src_dir {filesystem::path {basename} / "model" / "src"}; - auto [d_output, tt_output] = writeModelFileHelper(); + auto [d_output, tt_output] = writeModelFileHelper < dynamic + ? ExprNodeOutputType::CDynamicModel + : ExprNodeOutputType::CStaticModel > (); vector header_files, object_files; // TODO: when C++20 support is complete, mark the following strings constexpr - const string prefix { dynamic ? "dynamic_" : "static_" }; - const string ss_it_argin { dynamic ? ", const double *restrict steady_state, int it_" : "" }; - const string ss_it_argout { dynamic ? ", steady_state, it_" : "" }; - const string nb_row_x_argin { dynamic ? ", int nb_row_x" : "" }; - const string nb_row_x_argout { dynamic ? ", nb_row_x" : "" }; + const string prefix {dynamic ? "dynamic_" : "static_"}; + const string ss_it_argin {dynamic ? ", const double *restrict steady_state, int it_" : ""}; + const string ss_it_argout {dynamic ? ", steady_state, it_" : ""}; + const string nb_row_x_argin {dynamic ? ", int nb_row_x" : ""}; + const string nb_row_x_argout {dynamic ? ", nb_row_x" : ""}; for (size_t i {0}; i < d_output.size(); i++) { - const string funcname { prefix + (i == 0 ? "resid" : "g" + to_string(i))}; + const string funcname {prefix + (i == 0 ? "resid" : "g" + to_string(i))}; - const string prototype_tt { "void " + funcname + "_tt(const double *restrict y, const double *restrict x" + nb_row_x_argin + ", const double *restrict params" + ss_it_argin + ", double *restrict T)" }; + const string prototype_tt {"void " + funcname + + "_tt(const double *restrict y, const double *restrict x" + + nb_row_x_argin + ", const double *restrict params" + ss_it_argin + + ", double *restrict T)"}; - const filesystem::path header_tt { model_src_dir / (funcname + "_tt.h") }; + const filesystem::path header_tt {model_src_dir / (funcname + "_tt.h")}; open_file(header_tt); output << prototype_tt << ";" << endl; output.close(); header_files.push_back(header_tt); - const filesystem::path source_tt { model_src_dir / (funcname + "_tt.c") }; + const filesystem::path source_tt {model_src_dir / (funcname + "_tt.c")}; open_file(source_tt); output << "#include " << endl << R"(#include "mex.h")" << endl // Needed for calls to external functions @@ -996,58 +1035,57 @@ ModelTree::writeModelCFile(const string &basename, const string &mexext, output << endl << prototype_tt << endl << "{" << endl - << tt_output[i].str() - << "}" << endl + << tt_output[i].str() << "}" << endl << endl; output.close(); - object_files.push_back(compileMEX(model_src_dir, funcname + "_tt" , mexext, { source_tt }, - matlabroot, false)); + object_files.push_back( + compileMEX(model_src_dir, funcname + "_tt", mexext, {source_tt}, matlabroot, false)); - const string prototype_main - { - [&funcname, &ss_it_argin, &nb_row_x_argin, i] - { - string p = "void " + funcname + "(const double *restrict y, const double *restrict x" + nb_row_x_argin + ", const double *restrict params" + ss_it_argin + ", const double *restrict T, "; - if (i == 0) - p += "double *restrict residual"; - else if (i == 1) - p += "double *restrict g1"; - else - p += "double *restrict g" + to_string(i) + "_i, double *restrict g" + - to_string(i) + "_j, double *restrict g" + to_string(i) + "_v"; - p += ")"; - return p; - }() - }; + const string prototype_main {[&funcname, &ss_it_argin, &nb_row_x_argin, i] { + string p = "void " + funcname + "(const double *restrict y, const double *restrict x" + + nb_row_x_argin + ", const double *restrict params" + ss_it_argin + + ", const double *restrict T, "; + if (i == 0) + p += "double *restrict residual"; + else if (i == 1) + p += "double *restrict g1"; + else + p += "double *restrict g" + to_string(i) + "_i, double *restrict g" + to_string(i) + + "_j, double *restrict g" + to_string(i) + "_v"; + p += ")"; + return p; + }()}; - const filesystem::path header_main { model_src_dir / (funcname + ".h") }; + const filesystem::path header_main {model_src_dir / (funcname + ".h")}; open_file(header_main); output << prototype_main << ";" << endl; output.close(); header_files.push_back(header_main); - const filesystem::path source_main { model_src_dir / (funcname + ".c") }; + const filesystem::path source_main {model_src_dir / (funcname + ".c")}; open_file(source_main); output << "#include " << endl << R"(#include "mex.h")" << endl // Needed for calls to external functions << endl; writeCHelpersDefinition(output); if (i == 0) - writeCHelpersDeclaration(output); // Provide external definition of helpers in resid main file + writeCHelpersDeclaration( + output); // Provide external definition of helpers in resid main file output << endl << prototype_main << endl << "{" << endl - << d_output[i].str() - << "}" << endl + << d_output[i].str() << "}" << endl << endl; output.close(); - object_files.push_back(compileMEX(model_src_dir, funcname, mexext, { source_main }, - matlabroot, false)); + object_files.push_back( + compileMEX(model_src_dir, funcname, mexext, {source_main}, matlabroot, false)); } - const filesystem::path filename { model_src_dir / (dynamic ? "dynamic.c" : "static.c") }; + const filesystem::path filename {model_src_dir / (dynamic ? "dynamic.c" : "static.c")}; - const int ntt { static_cast(temporary_terms_derivatives[0].size() + temporary_terms_derivatives[1].size() + temporary_terms_derivatives[2].size() + temporary_terms_derivatives[3].size()) }; + const int ntt {static_cast( + temporary_terms_derivatives[0].size() + temporary_terms_derivatives[1].size() + + temporary_terms_derivatives[2].size() + temporary_terms_derivatives[3].size())}; open_file(filename); output << "/*" << endl @@ -1057,19 +1095,21 @@ ModelTree::writeModelCFile(const string &basename, const string &mexext, << " * from model file (.mod)" << endl << " */" << endl << endl - << "#include " << endl // Needed for getPowerDeriv() + << "#include " << endl // Needed for getPowerDeriv() << "#include " << endl // Needed for malloc() and free() << R"(#include "mex.h")" << endl; - for (const auto &it : header_files) + for (const auto& it : header_files) output << "#include " << it.filename() << endl; output << endl << "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl << "{" << endl; - if constexpr(dynamic) - output << " if (nlhs > " << min(computed_derivs_order + 1, 4) << ")" << endl - << R"( mexErrMsgTxt("Derivatives of higher order than computed have been requested");)" << endl - << " if (nrhs != 5)" << endl - << R"( mexErrMsgTxt("Requires exactly 5 input arguments");)" << endl; + if constexpr (dynamic) + output + << " if (nlhs > " << min(computed_derivs_order + 1, 4) << ")" << endl + << R"( mexErrMsgTxt("Derivatives of higher order than computed have been requested");)" + << endl + << " if (nrhs != 5)" << endl + << R"( mexErrMsgTxt("Requires exactly 5 input arguments");)" << endl; else output << " if (nrhs > 3)" << endl << R"( mexErrMsgTxt("Accepts at most 3 output arguments");)" << endl @@ -1079,7 +1119,7 @@ ModelTree::writeModelCFile(const string &basename, const string &mexext, << " double *y = mxGetPr(prhs[0]);" << endl << " double *x = mxGetPr(prhs[1]);" << endl << " double *params = mxGetPr(prhs[2]);" << endl; - if constexpr(dynamic) + if constexpr (dynamic) output << " double *steady_state = mxGetPr(prhs[3]);" << endl << " int it_ = (int) mxGetScalar(prhs[4]) - 1;" << endl << " int nb_row_x = mxGetM(prhs[1]);" << endl; @@ -1090,27 +1130,38 @@ ModelTree::writeModelCFile(const string &basename, const string &mexext, << " {" << endl << " plhs[0] = mxCreateDoubleMatrix(" << equations.size() << ",1, mxREAL);" << endl << " double *residual = mxGetPr(plhs[0]);" << endl - << " " << prefix << "resid_tt(y, x" << nb_row_x_argout << ", params" << ss_it_argout << ", T);" << endl - << " " << prefix << "resid(y, x" << nb_row_x_argout << ", params" << ss_it_argout << ", T, residual);" << endl + << " " << prefix << "resid_tt(y, x" << nb_row_x_argout << ", params" << ss_it_argout + << ", T);" << endl + << " " << prefix << "resid(y, x" << nb_row_x_argout << ", params" << ss_it_argout + << ", T, residual);" << endl << " }" << endl << endl << " if (nlhs >= 2)" << endl << " {" << endl - << " plhs[1] = mxCreateDoubleMatrix(" << equations.size() << ", " << getJacobianColsNbr(false) << ", mxREAL);" << endl + << " plhs[1] = mxCreateDoubleMatrix(" << equations.size() << ", " + << getJacobianColsNbr(false) << ", mxREAL);" << endl << " double *g1 = mxGetPr(plhs[1]);" << endl - << " " << prefix << "g1_tt(y, x" << nb_row_x_argout << ", params" << ss_it_argout << ", T);" << endl - << " " << prefix << "g1(y, x" << nb_row_x_argout << ", params" << ss_it_argout << ", T, g1);" << endl + << " " << prefix << "g1_tt(y, x" << nb_row_x_argout << ", params" << ss_it_argout + << ", T);" << endl + << " " << prefix << "g1(y, x" << nb_row_x_argout << ", params" << ss_it_argout + << ", T, g1);" << endl << " }" << endl << endl << " if (nlhs >= 3)" << endl << " {" << endl - << " mxArray *g2_i = mxCreateDoubleMatrix(" << NNZDerivatives[2] << ", " << 1 << ", mxREAL);" << endl - << " mxArray *g2_j = mxCreateDoubleMatrix(" << NNZDerivatives[2] << ", " << 1 << ", mxREAL);" << endl - << " mxArray *g2_v = mxCreateDoubleMatrix(" << NNZDerivatives[2] << ", " << 1 << ", mxREAL);" << endl - << " " << prefix << "g2_tt(y, x" << nb_row_x_argout << ", params" << ss_it_argout << ", T);" << endl - << " " << prefix << "g2(y, x" << nb_row_x_argout << ", params" << ss_it_argout << ", T, mxGetPr(g2_i), mxGetPr(g2_j), mxGetPr(g2_v));" << endl + << " mxArray *g2_i = mxCreateDoubleMatrix(" << NNZDerivatives[2] << ", " << 1 + << ", mxREAL);" << endl + << " mxArray *g2_j = mxCreateDoubleMatrix(" << NNZDerivatives[2] << ", " << 1 + << ", mxREAL);" << endl + << " mxArray *g2_v = mxCreateDoubleMatrix(" << NNZDerivatives[2] << ", " << 1 + << ", mxREAL);" << endl + << " " << prefix << "g2_tt(y, x" << nb_row_x_argout << ", params" << ss_it_argout + << ", T);" << endl + << " " << prefix << "g2(y, x" << nb_row_x_argout << ", params" << ss_it_argout + << ", T, mxGetPr(g2_i), mxGetPr(g2_j), mxGetPr(g2_v));" << endl << " mxArray *m = mxCreateDoubleScalar(" << equations.size() << ");" << endl - << " mxArray *n = mxCreateDoubleScalar(" << getJacobianColsNbr(false)*getJacobianColsNbr(false) << ");" << endl + << " mxArray *n = mxCreateDoubleScalar(" + << getJacobianColsNbr(false) * getJacobianColsNbr(false) << ");" << endl << " mxArray *plhs_sparse[1], *prhs_sparse[5] = { g2_i, g2_j, g2_v, m, n };" << endl << R"( mexCallMATLAB(1, plhs_sparse, 5, prhs_sparse, "sparse");)" << endl << " plhs[2] = plhs_sparse[0];" << endl @@ -1121,16 +1172,23 @@ ModelTree::writeModelCFile(const string &basename, const string &mexext, << " mxDestroyArray(n);" << endl << " }" << endl << endl; - if constexpr(dynamic) + if constexpr (dynamic) output << " if (nlhs >= 4)" << endl << " {" << endl - << " mxArray *g3_i = mxCreateDoubleMatrix(" << NNZDerivatives[3] << ", " << 1 << ", mxREAL);" << endl - << " mxArray *g3_j = mxCreateDoubleMatrix(" << NNZDerivatives[3] << ", " << 1 << ", mxREAL);" << endl - << " mxArray *g3_v = mxCreateDoubleMatrix(" << NNZDerivatives[3] << ", " << 1 << ", mxREAL);" << endl - << " " << prefix << "g3_tt(y, x" << nb_row_x_argout << ", params" << ss_it_argout << ", T);" << endl - << " " << prefix << "g3(y, x" << nb_row_x_argout << ", params" << ss_it_argout << ", T, mxGetPr(g3_i), mxGetPr(g3_j), mxGetPr(g3_v));" << endl + << " mxArray *g3_i = mxCreateDoubleMatrix(" << NNZDerivatives[3] << ", " << 1 + << ", mxREAL);" << endl + << " mxArray *g3_j = mxCreateDoubleMatrix(" << NNZDerivatives[3] << ", " << 1 + << ", mxREAL);" << endl + << " mxArray *g3_v = mxCreateDoubleMatrix(" << NNZDerivatives[3] << ", " << 1 + << ", mxREAL);" << endl + << " " << prefix << "g3_tt(y, x" << nb_row_x_argout << ", params" << ss_it_argout + << ", T);" << endl + << " " << prefix << "g3(y, x" << nb_row_x_argout << ", params" << ss_it_argout + << ", T, mxGetPr(g3_i), mxGetPr(g3_j), mxGetPr(g3_v));" << endl << " mxArray *m = mxCreateDoubleScalar(" << equations.size() << ");" << endl - << " mxArray *n = mxCreateDoubleScalar(" << getJacobianColsNbr(false)*getJacobianColsNbr(false)*getJacobianColsNbr(false) << ");" << endl + << " mxArray *n = mxCreateDoubleScalar(" + << getJacobianColsNbr(false) * getJacobianColsNbr(false) * getJacobianColsNbr(false) + << ");" << endl << " mxArray *plhs_sparse[1], *prhs_sparse[5] = { g3_i, g3_j, g3_v, m, n };" << endl << R"( mexCallMATLAB(1, plhs_sparse, 5, prhs_sparse, "sparse");)" << endl << " plhs[3] = plhs_sparse[0];" << endl @@ -1142,51 +1200,53 @@ ModelTree::writeModelCFile(const string &basename, const string &mexext, << " }" << endl << endl; - output << " free(T);" << endl - << "}" << endl; + output << " free(T);" << endl << "}" << endl; output.close(); object_files.push_back(filename); - compileMEX(packageDir(basename), dynamic ? "dynamic" : "static", mexext, object_files, matlabroot); + compileMEX(packageDir(basename), dynamic ? "dynamic" : "static", mexext, object_files, + matlabroot); } template void -ModelTree::writePerBlockHelper(int blk, ostream &output, temporary_terms_t &temporary_terms) const +ModelTree::writePerBlockHelper(int blk, ostream& output, temporary_terms_t& temporary_terms) const { - int block_recursive_size { blocks[blk].getRecursiveSize() }; + int block_recursive_size {blocks[blk].getRecursiveSize()}; // The equations deriv_node_temp_terms_t tef_terms; - auto write_eq_tt = [&](int eq) - { - for (auto it : blocks_temporary_terms[blk][eq]) - { - if (dynamic_cast(it)) - it->writeExternalFunctionOutput(output, output_type, temporary_terms, blocks_temporary_terms_idxs, tef_terms); + auto write_eq_tt = [&](int eq) { + for (auto it : blocks_temporary_terms[blk][eq]) + { + if (dynamic_cast(it)) + it->writeExternalFunctionOutput(output, output_type, temporary_terms, + blocks_temporary_terms_idxs, tef_terms); - output << " "; - it->writeOutput(output, output_type, blocks_temporary_terms[blk][eq], blocks_temporary_terms_idxs, tef_terms); - output << '='; - it->writeOutput(output, output_type, temporary_terms, blocks_temporary_terms_idxs, tef_terms); - temporary_terms.insert(it); - output << ';' << endl; - } - }; + output << " "; + it->writeOutput(output, output_type, blocks_temporary_terms[blk][eq], + blocks_temporary_terms_idxs, tef_terms); + output << '='; + it->writeOutput(output, output_type, temporary_terms, blocks_temporary_terms_idxs, + tef_terms); + temporary_terms.insert(it); + output << ';' << endl; + } + }; for (int eq {0}; eq < blocks[blk].size; eq++) { write_eq_tt(eq); - EquationType equ_type { getBlockEquationType(blk, eq) }; - BinaryOpNode *e { getBlockEquationExpr(blk, eq) }; - expr_t lhs { e->arg1 }, rhs { e->arg2 }; + EquationType equ_type {getBlockEquationType(blk, eq)}; + BinaryOpNode* e {getBlockEquationExpr(blk, eq)}; + expr_t lhs {e->arg1}, rhs {e->arg2}; switch (blocks[blk].simulation_type) { case BlockSimulationType::evaluateBackward: case BlockSimulationType::evaluateForward: - evaluation: + evaluation: if (equ_type == EquationType::evaluateRenormalized) { e = getBlockEquationRenormalizedExpr(blk, eq); @@ -1211,7 +1271,7 @@ ModelTree::writePerBlockHelper(int blk, ostream &output, temporary_terms_t &temp case BlockSimulationType::solveBackwardSimple: case BlockSimulationType::solveForwardSimple: output << " residual" << LEFT_ARRAY_SUBSCRIPT(output_type) - << eq-block_recursive_size+ARRAY_SUBSCRIPT_OFFSET(output_type) + << eq - block_recursive_size + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=("; lhs->writeOutput(output, output_type, temporary_terms, blocks_temporary_terms_idxs); output << ")-("; @@ -1229,71 +1289,74 @@ ModelTree::writePerBlockHelper(int blk, ostream &output, temporary_terms_t &temp } template -tuple +tuple ModelTree::writeParamsDerivativesFileHelper() const { static_assert(!isCOutput(output_type), "C output is not implemented"); constexpr bool sparse {isSparseModelOutput(output_type)}; - ostringstream tt_output; // Used for storing model temp vars and equations - ostringstream rp_output; // 1st deriv. of residuals w.r.t. parameters - ostringstream gp_output; // 1st deriv. of Jacobian w.r.t. parameters + ostringstream tt_output; // Used for storing model temp vars and equations + ostringstream rp_output; // 1st deriv. of residuals w.r.t. parameters + ostringstream gp_output; // 1st deriv. of Jacobian w.r.t. parameters ostringstream rpp_output; // 2nd deriv of residuals w.r.t. parameters ostringstream gpp_output; // 2nd deriv of Jacobian w.r.t. parameters - ostringstream hp_output; // 1st deriv. of Hessian w.r.t. parameters - ostringstream g3p_output; // 1st deriv. of 3rd deriv. matrix w.r.t. parameters (only in dynamic case) + ostringstream hp_output; // 1st deriv. of Hessian w.r.t. parameters + ostringstream + g3p_output; // 1st deriv. of 3rd deriv. matrix w.r.t. parameters (only in dynamic case) temporary_terms_t temp_term_union; deriv_node_temp_terms_t tef_terms; - for (const auto &[order, tts] : params_derivs_temporary_terms) + for (const auto& [order, tts] : params_derivs_temporary_terms) writeTemporaryTerms(tts, temp_term_union, params_derivs_temporary_terms_idxs, tt_output, tef_terms); - for (const auto &[indices, d1] : params_derivatives.at({ 0, 1 })) + for (const auto& [indices, d1] : params_derivatives.at({0, 1})) { - auto [eq, param] { vectorToTuple<2>(indices) }; + auto [eq, param] {vectorToTuple<2>(indices)}; - int param_col { getTypeSpecificIDByDerivID(param) + 1 }; + int param_col {getTypeSpecificIDByDerivID(param) + 1}; - rp_output << "rp" << LEFT_ARRAY_SUBSCRIPT(output_type) << eq+1 << ", " << param_col + rp_output << "rp" << LEFT_ARRAY_SUBSCRIPT(output_type) << eq + 1 << ", " << param_col << RIGHT_ARRAY_SUBSCRIPT(output_type) << " = "; - d1->writeOutput(rp_output, output_type, temp_term_union, params_derivs_temporary_terms_idxs, tef_terms); + d1->writeOutput(rp_output, output_type, temp_term_union, params_derivs_temporary_terms_idxs, + tef_terms); rp_output << ";" << endl; } - for (const auto &[indices, d2] : params_derivatives.at({ 1, 1 })) + for (const auto& [indices, d2] : params_derivatives.at({1, 1})) { - auto [eq, var, param] { vectorToTuple<3>(indices) }; + auto [eq, var, param] {vectorToTuple<3>(indices)}; - int var_col { getJacobianCol(var, sparse) + 1 }; - int param_col { getTypeSpecificIDByDerivID(param) + 1 }; + int var_col {getJacobianCol(var, sparse) + 1}; + int param_col {getTypeSpecificIDByDerivID(param) + 1}; - gp_output << "gp" << LEFT_ARRAY_SUBSCRIPT(output_type) << eq+1 << ", " << var_col - << ", " << param_col << RIGHT_ARRAY_SUBSCRIPT(output_type) << " = "; - d2->writeOutput(gp_output, output_type, temp_term_union, params_derivs_temporary_terms_idxs, tef_terms); + gp_output << "gp" << LEFT_ARRAY_SUBSCRIPT(output_type) << eq + 1 << ", " << var_col << ", " + << param_col << RIGHT_ARRAY_SUBSCRIPT(output_type) << " = "; + d2->writeOutput(gp_output, output_type, temp_term_union, params_derivs_temporary_terms_idxs, + tef_terms); gp_output << ";" << endl; } - for (int i {1}; - const auto &[indices, d2] : params_derivatives.at({ 0, 2 })) + for (int i {1}; const auto& [indices, d2] : params_derivatives.at({0, 2})) { - auto [eq, param1, param2] { vectorToTuple<3>(indices) }; + auto [eq, param1, param2] {vectorToTuple<3>(indices)}; - int param1_col { getTypeSpecificIDByDerivID(param1) + 1 }; - int param2_col { getTypeSpecificIDByDerivID(param2) + 1 }; + int param1_col {getTypeSpecificIDByDerivID(param1) + 1}; + int param2_col {getTypeSpecificIDByDerivID(param2) + 1}; rpp_output << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq + 1 << ";" << endl << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d2->writeOutput(rpp_output, output_type, temp_term_union, params_derivs_temporary_terms_idxs, tef_terms); + d2->writeOutput(rpp_output, output_type, temp_term_union, params_derivs_temporary_terms_idxs, + tef_terms); rpp_output << ";" << endl; i++; @@ -1302,30 +1365,29 @@ ModelTree::writeParamsDerivativesFileHelper() const { // Treat symmetric elements rpp_output << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq + 1 << ";" << endl << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl << "rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4" - << RIGHT_ARRAY_SUBSCRIPT(output_type) - << "=rpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i-1 << ",4" + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=rpp" + << LEFT_ARRAY_SUBSCRIPT(output_type) << i - 1 << ",4" << RIGHT_ARRAY_SUBSCRIPT(output_type) << ";" << endl; i++; } } - for (int i {1}; - const auto &[indices, d2] : params_derivatives.at({ 1, 2 })) + for (int i {1}; const auto& [indices, d2] : params_derivatives.at({1, 2})) { - auto [eq, var, param1, param2] { vectorToTuple<4>(indices) }; + auto [eq, var, param1, param2] {vectorToTuple<4>(indices)}; - int var_col { getJacobianCol(var, sparse) + 1 }; - int param1_col { getTypeSpecificIDByDerivID(param1) + 1 }; - int param2_col { getTypeSpecificIDByDerivID(param2) + 1 }; + int var_col {getJacobianCol(var, sparse) + 1}; + int param1_col {getTypeSpecificIDByDerivID(param1) + 1}; + int param2_col {getTypeSpecificIDByDerivID(param2) + 1}; gpp_output << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq + 1 << ";" << endl << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var_col << ";" << endl << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3" @@ -1334,7 +1396,8 @@ ModelTree::writeParamsDerivativesFileHelper() const << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param2_col << ";" << endl << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d2->writeOutput(gpp_output, output_type, temp_term_union, params_derivs_temporary_terms_idxs, tef_terms); + d2->writeOutput(gpp_output, output_type, temp_term_union, params_derivs_temporary_terms_idxs, + tef_terms); gpp_output << ";" << endl; i++; @@ -1343,7 +1406,7 @@ ModelTree::writeParamsDerivativesFileHelper() const { // Treat symmetric elements gpp_output << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq + 1 << ";" << endl << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var_col << ";" << endl << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3" @@ -1351,24 +1414,23 @@ ModelTree::writeParamsDerivativesFileHelper() const << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param1_col << ";" << endl << "gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5" - << RIGHT_ARRAY_SUBSCRIPT(output_type) - << "=gpp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i-1 << ",5" + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=gpp" + << LEFT_ARRAY_SUBSCRIPT(output_type) << i - 1 << ",5" << RIGHT_ARRAY_SUBSCRIPT(output_type) << ";" << endl; i++; } } - for (int i {1}; - const auto &[indices, d2] : params_derivatives.at({ 2, 1 })) + for (int i {1}; const auto& [indices, d2] : params_derivatives.at({2, 1})) { - auto [eq, var1, var2, param] { vectorToTuple<4>(indices) }; + auto [eq, var1, var2, param] {vectorToTuple<4>(indices)}; - int var1_col { getJacobianCol(var1, sparse) + 1 }; - int var2_col { getJacobianCol(var2, sparse) + 1 }; - int param_col { getTypeSpecificIDByDerivID(param) + 1 }; + int var1_col {getJacobianCol(var1, sparse) + 1}; + int var2_col {getJacobianCol(var2, sparse) + 1}; + int param_col {getTypeSpecificIDByDerivID(param) + 1}; hp_output << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq + 1 << ";" << endl << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var1_col << ";" << endl << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3" @@ -1377,7 +1439,8 @@ ModelTree::writeParamsDerivativesFileHelper() const << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param_col << ";" << endl << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d2->writeOutput(hp_output, output_type, temp_term_union, params_derivs_temporary_terms_idxs, tef_terms); + d2->writeOutput(hp_output, output_type, temp_term_union, params_derivs_temporary_terms_idxs, + tef_terms); hp_output << ";" << endl; i++; @@ -1386,7 +1449,7 @@ ModelTree::writeParamsDerivativesFileHelper() const { // Treat symmetric elements hp_output << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq + 1 << ";" << endl << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var2_col << ";" << endl << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3" @@ -1394,27 +1457,26 @@ ModelTree::writeParamsDerivativesFileHelper() const << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",4" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param_col << ";" << endl << "hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",5" - << RIGHT_ARRAY_SUBSCRIPT(output_type) - << "=hp" << LEFT_ARRAY_SUBSCRIPT(output_type) << i-1 << ",5" + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=hp" + << LEFT_ARRAY_SUBSCRIPT(output_type) << i - 1 << ",5" << RIGHT_ARRAY_SUBSCRIPT(output_type) << ";" << endl; i++; } } - if constexpr(output_type == ExprNodeOutputType::matlabDynamicModel - || output_type == ExprNodeOutputType::juliaDynamicModel) - for (int i {1}; - const auto &[indices, d2] : params_derivatives.at({ 3, 1 })) + if constexpr (output_type == ExprNodeOutputType::matlabDynamicModel + || output_type == ExprNodeOutputType::juliaDynamicModel) + for (int i {1}; const auto& [indices, d2] : params_derivatives.at({3, 1})) { - auto [eq, var1, var2, var3, param] { vectorToTuple<5>(indices) }; + auto [eq, var1, var2, var3, param] {vectorToTuple<5>(indices)}; - int var1_col { getJacobianCol(var1, sparse) + 1 }; - int var2_col { getJacobianCol(var2, sparse) + 1 }; - int var3_col { getJacobianCol(var3, sparse) + 1 }; - int param_col { getTypeSpecificIDByDerivID(param) + 1 }; + int var1_col {getJacobianCol(var1, sparse) + 1}; + int var2_col {getJacobianCol(var2, sparse) + 1}; + int var3_col {getJacobianCol(var3, sparse) + 1}; + int param_col {getTypeSpecificIDByDerivID(param) + 1}; g3p_output << "g3p" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",1" - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq+1 << ";" << endl + << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << eq + 1 << ";" << endl << "g3p" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",2" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << var1_col << ";" << endl << "g3p" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",3" @@ -1425,15 +1487,17 @@ ModelTree::writeParamsDerivativesFileHelper() const << RIGHT_ARRAY_SUBSCRIPT(output_type) << "=" << param_col << ";" << endl << "g3p" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << ",6" << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; - d2->writeOutput(g3p_output, output_type, temp_term_union, params_derivs_temporary_terms_idxs, tef_terms); + d2->writeOutput(g3p_output, output_type, temp_term_union, + params_derivs_temporary_terms_idxs, tef_terms); g3p_output << ";" << endl; i++; } - if constexpr(isMatlabOutput(output_type)) + if constexpr (isMatlabOutput(output_type)) { - // Check that we don't have more than 32 nested parenthesis because MATLAB does not support this. See Issue #1201 + // Check that we don't have more than 32 nested parenthesis because MATLAB does not support + // this. See Issue #1201 map tmp_paren_vars; bool message_printed {false}; fixNestedParenthesis(tt_output, tmp_paren_vars, message_printed); @@ -1445,32 +1509,34 @@ ModelTree::writeParamsDerivativesFileHelper() const fixNestedParenthesis(g3p_output, tmp_paren_vars, message_printed); } - return { move(tt_output), move(rp_output), move(gp_output), - move(rpp_output), move(gpp_output), move(hp_output), move(g3p_output) }; + return {move(tt_output), move(rp_output), move(gp_output), move(rpp_output), + move(gpp_output), move(hp_output), move(g3p_output)}; } template void -ModelTree::writeBytecodeTemporaryTerms(const temporary_terms_t &tt, - temporary_terms_t &temporary_terms_union, - BytecodeWriter &code_file, - deriv_node_temp_terms_t &tef_terms) const +ModelTree::writeBytecodeTemporaryTerms(const temporary_terms_t& tt, + temporary_terms_t& temporary_terms_union, + BytecodeWriter& code_file, + deriv_node_temp_terms_t& tef_terms) const { for (auto it : tt) { - if (dynamic_cast(it)) - it->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs, tef_terms); + if (dynamic_cast(it)) + it->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms_union, + temporary_terms_idxs, tef_terms); int idx {temporary_terms_idxs.at(it)}; - code_file << FNUMEXPR_{ExpressionType::TemporaryTerm, idx}; - it->writeBytecodeOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs, tef_terms); + code_file << FNUMEXPR_ {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}; + if constexpr (output_type == ExprNodeBytecodeOutputType::dynamicModel) + code_file << FSTPT_ {idx}; else - code_file << FSTPST_{idx}; + code_file << FSTPST_ {idx}; temporary_terms_union.insert(it); } @@ -1478,123 +1544,132 @@ ModelTree::writeBytecodeTemporaryTerms(const temporary_terms_t &tt, template void -ModelTree::writeBytecodeModelEquations(BytecodeWriter &code_file, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms) const +ModelTree::writeBytecodeModelEquations(BytecodeWriter& code_file, + const temporary_terms_t& temporary_terms, + const deriv_node_temp_terms_t& tef_terms) const { for (int eq {0}; eq < static_cast(equations.size()); eq++) { - BinaryOpNode *eq_node {equations[eq]}; + BinaryOpNode* eq_node {equations[eq]}; expr_t lhs {eq_node->arg1}, rhs {eq_node->arg2}; - code_file << FNUMEXPR_{ExpressionType::ModelEquation, eq}; + code_file << FNUMEXPR_ {ExpressionType::ModelEquation, eq}; // Test if the right hand side of the equation is empty. double vrhs {1.0}; try { vrhs = rhs->eval({}); } - catch (ExprNode::EvalException &e) + catch (ExprNode::EvalException& e) { } if (vrhs != 0) // The right hand side of the equation is not empty ⇒ residual=lhs-rhs { - lhs->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); - rhs->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + lhs->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); + rhs->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); - code_file << FBINARY_{BinaryOpcode::minus} << FSTPR_{eq}; + code_file << FBINARY_ {BinaryOpcode::minus} << 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}; + lhs->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, + tef_terms); + code_file << FSTPR_ {eq}; } } } template void -ModelTree::writeBytecodeHelper(BytecodeWriter &code_file) const +ModelTree::writeBytecodeHelper(BytecodeWriter& code_file) const { - constexpr ExprNodeBytecodeOutputType output_type { dynamic ? ExprNodeBytecodeOutputType::dynamicModel : ExprNodeBytecodeOutputType::staticModel }; + constexpr ExprNodeBytecodeOutputType output_type { + dynamic ? ExprNodeBytecodeOutputType::dynamicModel : ExprNodeBytecodeOutputType::staticModel}; temporary_terms_t temporary_terms_union; deriv_node_temp_terms_t tef_terms; - writeBytecodeTemporaryTerms(temporary_terms_derivatives[0], temporary_terms_union, code_file, tef_terms); + writeBytecodeTemporaryTerms(temporary_terms_derivatives[0], temporary_terms_union, + code_file, tef_terms); writeBytecodeModelEquations(code_file, temporary_terms_union, tef_terms); - code_file << FENDEQU_{}; + code_file << FENDEQU_ {}; // Temporary terms for the Jacobian - writeBytecodeTemporaryTerms(temporary_terms_derivatives[1], temporary_terms_union, code_file, tef_terms); + writeBytecodeTemporaryTerms(temporary_terms_derivatives[1], temporary_terms_union, + code_file, tef_terms); // 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 << FJMPIFEVAL_ {0}; // Use 0 as jump offset for the time being // The Jacobian in “simulate” mode - vector>> my_derivatives(symbol_table.endo_nbr());; + vector>> my_derivatives(symbol_table.endo_nbr()); + ; int count_u {symbol_table.endo_nbr()}; - for (const auto &[indices, d1] : derivatives[1]) + for (const auto& [indices, d1] : derivatives[1]) { auto [eq, deriv_id] {vectorToTuple<2>(indices)}; if (getTypeByDerivID(deriv_id) == SymbolType::endogenous) { int tsid {getTypeSpecificIDByDerivID(deriv_id)}; int lag {getLagByDerivID(deriv_id)}; - if constexpr(dynamic) - code_file << FNUMEXPR_{ExpressionType::FirstEndoDerivative, eq, tsid, lag}; + if constexpr (dynamic) + code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eq, tsid, lag}; else - code_file << FNUMEXPR_{ExpressionType::FirstEndoDerivative, eq, tsid}; + code_file << FNUMEXPR_ {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}; + d1->writeBytecodeOutput(code_file, output_type, temporary_terms_union, + temporary_terms_idxs, tef_terms); + if constexpr (dynamic) + code_file << FSTPU_ {count_u}; else - code_file << FSTPSU_{count_u}; + code_file << FSTPSU_ {count_u}; count_u++; } } for (int i {0}; i < symbol_table.endo_nbr(); i++) { - code_file << FLDR_{i}; + code_file << FLDR_ {i}; if (my_derivatives[i].size()) { - for (bool first_term {true}; - const auto &[tsid, lag, uidx] : my_derivatives[i]) + 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}; + if constexpr (dynamic) + code_file << FLDU_ {uidx} << FLDV_ {SymbolType::endogenous, tsid, lag}; else - code_file << FLDSU_{uidx} << FLDSV_{SymbolType::endogenous, tsid}; - code_file << FBINARY_{BinaryOpcode::times}; + code_file << FLDSU_ {uidx} << FLDSV_ {SymbolType::endogenous, tsid}; + code_file << FBINARY_ {BinaryOpcode::times}; if (!exchange(first_term, false)) - code_file << FBINARY_{BinaryOpcode::plus}; + code_file << FBINARY_ {BinaryOpcode::plus}; } - code_file << FBINARY_{BinaryOpcode::minus}; + code_file << FBINARY_ {BinaryOpcode::minus}; } - if constexpr(dynamic) - code_file << FSTPU_{i}; + if constexpr (dynamic) + code_file << FSTPU_ {i}; else - code_file << FSTPSU_{i}; + code_file << 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 << 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, FJMPIFEVAL_ {pos_jmp - pos_jmpifeval}); // The Jacobian in “evaluate” mode - for (const auto &[indices, d1] : derivatives[1]) + for (const auto& [indices, d1] : derivatives[1]) { auto [eq, deriv_id] {vectorToTuple<2>(indices)}; int tsid {getTypeSpecificIDByDerivID(deriv_id)}; int lag {getLagByDerivID(deriv_id)}; SymbolType type {getTypeByDerivID(deriv_id)}; - if constexpr(dynamic) + if constexpr (dynamic) { ExpressionType expr_type; switch (type) @@ -1612,40 +1687,43 @@ ModelTree::writeBytecodeHelper(BytecodeWriter &code_file) const assert(false); break; } - code_file << FNUMEXPR_{expr_type, eq, tsid, lag}; + code_file << FNUMEXPR_ {expr_type, eq, tsid, lag}; } else { assert(type == SymbolType::endogenous); - code_file << FNUMEXPR_{ExpressionType::FirstEndoDerivative, eq, tsid}; + code_file << FNUMEXPR_ {ExpressionType::FirstEndoDerivative, eq, tsid}; } - d1->writeBytecodeOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs, tef_terms); - if constexpr(dynamic) - { - // 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}; - } + d1->writeBytecodeOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs, + tef_terms); + if constexpr (dynamic) + { + // 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}; + } else - code_file << FSTPG2_{eq, tsid}; + code_file << 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, FJMP_ {pos_end_block - pos_jmp - 1}); - code_file << FENDBLOCK_{} << FEND_{}; + code_file << FENDBLOCK_ {} << FEND_ {}; } template void -ModelTree::writeBlockBytecodeHelper(BytecodeWriter &code_file, int block, temporary_terms_t &temporary_terms_union) const +ModelTree::writeBlockBytecodeHelper(BytecodeWriter& code_file, int block, + temporary_terms_t& temporary_terms_union) const { - constexpr ExprNodeBytecodeOutputType output_type - { dynamic ? ExprNodeBytecodeOutputType::dynamicModel : ExprNodeBytecodeOutputType::staticModel }; - constexpr ExprNodeBytecodeOutputType assignment_lhs_output_type - { dynamic ? ExprNodeBytecodeOutputType::dynamicAssignmentLHS : ExprNodeBytecodeOutputType::staticAssignmentLHS }; + constexpr ExprNodeBytecodeOutputType output_type { + dynamic ? ExprNodeBytecodeOutputType::dynamicModel : ExprNodeBytecodeOutputType::staticModel}; + constexpr ExprNodeBytecodeOutputType assignment_lhs_output_type { + dynamic ? ExprNodeBytecodeOutputType::dynamicAssignmentLHS + : ExprNodeBytecodeOutputType::staticAssignmentLHS}; const BlockSimulationType simulation_type {blocks[block].simulation_type}; const int block_size {blocks[block].size}; @@ -1654,19 +1732,20 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter &code_file, int block, tempor deriv_node_temp_terms_t tef_terms; - auto write_eq_tt = [&](int eq) - { + auto write_eq_tt = [&](int eq) { for (auto it : blocks_temporary_terms[block][eq]) { - if (dynamic_cast(it)) - it->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); + if (dynamic_cast(it)) + 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)}; - 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 << FNUMEXPR_ {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)}; else - code_file << FSTPST_{blocks_temporary_terms_idxs.at(it)}; + code_file << FSTPST_ {blocks_temporary_terms_idxs.at(it)}; temporary_terms_union.insert(it); } }; @@ -1676,14 +1755,14 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter &code_file, int block, tempor { write_eq_tt(i); - EquationType equ_type { getBlockEquationType(block, i) }; - BinaryOpNode *e { getBlockEquationExpr(block, i) }; - expr_t lhs { e->arg1 }, rhs { e->arg2 }; + EquationType equ_type {getBlockEquationType(block, i)}; + BinaryOpNode* e {getBlockEquationExpr(block, i)}; + expr_t lhs {e->arg1}, rhs {e->arg2}; switch (simulation_type) { case BlockSimulationType::evaluateBackward: case BlockSimulationType::evaluateForward: - evaluation: + evaluation: if (equ_type == EquationType::evaluateRenormalized) { e = getBlockEquationRenormalizedExpr(block, i); @@ -1692,9 +1771,11 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter &code_file, int block, tempor } else assert(equ_type == EquationType::evaluate); - code_file << FNUMEXPR_{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, blocks_temporary_terms_idxs, tef_terms); + code_file << FNUMEXPR_ {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, + blocks_temporary_terms_idxs, tef_terms); break; case BlockSimulationType::solveBackwardComplete: case BlockSimulationType::solveForwardComplete: @@ -1705,10 +1786,12 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter &code_file, int block, tempor [[fallthrough]]; case BlockSimulationType::solveBackwardSimple: case BlockSimulationType::solveForwardSimple: - code_file << FNUMEXPR_{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 << FNUMEXPR_ {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}; break; } } @@ -1723,11 +1806,11 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter &code_file, int block, tempor be needed in subsequent blocks. */ write_eq_tt(blocks[block].size); - code_file << FENDEQU_{}; + code_file << 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 << 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”) */ @@ -1741,14 +1824,15 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter &code_file, int block, tempor { int eqr {getBlockEquationID(block, 0)}; int varr {getBlockVariableID(block, 0)}; - code_file << FNUMEXPR_{ExpressionType::FirstEndoDerivative, eqr, varr, 0}; + code_file << FNUMEXPR_ {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 }) }; + 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); + 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 << FLDZ_ {}; + code_file << FSTPG_ {0}; } break; @@ -1760,26 +1844,26 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter &code_file, int block, tempor // For each equation, stores a list of tuples (index_u, var, lag) vector>> Uf(symbol_table.endo_nbr()); - for (int count_u {block_mfs}; - const auto &[indices, d1] : blocks_derivatives[block]) + for (int count_u {block_mfs}; const auto& [indices, d1] : blocks_derivatives[block]) { - const auto &[eq, var, lag] {indices}; + const auto& [eq, var, lag] {indices}; int eqr {getBlockEquationID(block, eq)}; int varr {getBlockVariableID(block, var)}; assert(eq >= block_recursive); if (var >= block_recursive) { - if constexpr(dynamic) + if constexpr (dynamic) if (lag != 0 && (simulation_type == BlockSimulationType::solveForwardComplete || simulation_type == BlockSimulationType::solveBackwardComplete)) continue; - code_file << FNUMEXPR_{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 << FNUMEXPR_ {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}; else - code_file << FSTPSU_{count_u}; + code_file << FSTPSU_ {count_u}; Uf[eqr].emplace_back(count_u, varr, lag); count_u++; } @@ -1787,25 +1871,22 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter &code_file, int block, tempor for (int i {0}; i < block_size; i++) if (i >= block_recursive) { - code_file << FLDR_{i-block_recursive} << FLDZ_{}; + code_file << FLDR_ {i - block_recursive} << FLDZ_ {}; int eqr {getBlockEquationID(block, i)}; - for (const auto &[index_u, var, lag] : Uf[eqr]) + for (const auto& [index_u, var, lag] : Uf[eqr]) { - if constexpr(dynamic) - code_file << FLDU_{index_u} - << FLDV_{SymbolType::endogenous, var, lag}; + if constexpr (dynamic) + code_file << FLDU_ {index_u} << 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 << FLDSU_ {index_u} << FLDSV_ {SymbolType::endogenous, var}; + code_file << FBINARY_ {BinaryOpcode::times} << FBINARY_ {BinaryOpcode::plus}; } - code_file << FBINARY_{BinaryOpcode::minus}; - if constexpr(dynamic) - code_file << FSTPU_{i - block_recursive}; + code_file << FBINARY_ {BinaryOpcode::minus}; + if constexpr (dynamic) + code_file << FSTPU_ {i - block_recursive}; else - code_file << FSTPSU_{i - block_recursive}; + code_file << FSTPSU_ {i - block_recursive}; } } break; @@ -1816,30 +1897,32 @@ ModelTree::writeBlockBytecodeHelper(BytecodeWriter &code_file, int block, tempor // 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 << 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, FJMPIFEVAL_ {pos_jmp - pos_jmpifeval}); // Write the derivatives for the “evaluate” mode - for (const auto &[indices, d] : blocks_derivatives[block]) + for (const auto& [indices, d] : blocks_derivatives[block]) { - const auto &[eq, var, lag] {indices}; + const auto& [eq, var, lag] {indices}; int eqr {getBlockEquationID(block, eq)}; int varr {getBlockVariableID(block, var)}; - code_file << FNUMEXPR_{ExpressionType::FirstEndoDerivative, eqr, varr, lag}; - d->writeBytecodeOutput(code_file, output_type, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); + code_file << FNUMEXPR_ {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)}; + if constexpr (dynamic) + code_file << FSTPG3_ {eq - block_recursive, var, lag, + getBlockJacobianEndoCol(block, var, lag)}; else - code_file << FSTPG2_{eq-block_recursive, getBlockJacobianEndoCol(block, var, lag)}; + code_file << 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, FJMP_ {pos_end_block - pos_jmp - 1}); - code_file << FENDBLOCK_{}; + code_file << FENDBLOCK_ {}; } template @@ -1847,35 +1930,40 @@ pair> ModelTree::writeJsonComputingPassOutputHelper(bool writeDetails) const { ostringstream mlv_output; // Used for storing model local vars - vector d_output(derivatives.size()); // Derivatives output (at all orders, including 0=residual) + vector d_output( + derivatives.size()); // Derivatives output (at all orders, including 0=residual) deriv_node_temp_terms_t tef_terms; temporary_terms_t temp_term_union; writeJsonModelLocalVariables(mlv_output, true, tef_terms); - writeJsonTemporaryTerms(temporary_terms_derivatives[0], temp_term_union, d_output[0], tef_terms, ""); + writeJsonTemporaryTerms(temporary_terms_derivatives[0], temp_term_union, d_output[0], tef_terms, + ""); d_output[0] << ", "; writeJsonModelEquations(d_output[0], true); - int ncols { getJacobianColsNbr(false) }; + int ncols {getJacobianColsNbr(false)}; for (size_t i {1}; i < derivatives.size(); i++) { - string matrix_name { i == 1 ? "jacobian" : i == 2 ? "hessian" : i == 3 ? "third_derivative" : to_string(i) + "th_derivative"}; - writeJsonTemporaryTerms(temporary_terms_derivatives[i], temp_term_union, d_output[i], tef_terms, matrix_name); - temp_term_union.insert(temporary_terms_derivatives[i].begin(), temporary_terms_derivatives[i].end()); - d_output[i] << R"(, ")" << matrix_name << R"(": {)" - << R"( "nrows": )" << equations.size() - << R"(, "ncols": )" << ncols + string matrix_name {i == 1 ? "jacobian" + : i == 2 ? "hessian" + : i == 3 ? "third_derivative" + : to_string(i) + "th_derivative"}; + writeJsonTemporaryTerms(temporary_terms_derivatives[i], temp_term_union, d_output[i], + tef_terms, matrix_name); + temp_term_union.insert(temporary_terms_derivatives[i].begin(), + temporary_terms_derivatives[i].end()); + d_output[i] << R"(, ")" << matrix_name << R"(": {)" + << R"( "nrows": )" << equations.size() << R"(, "ncols": )" << ncols << R"(, "entries": [)"; - for (bool printed_something {false}; - const auto &[vidx, d] : derivatives[i]) + for (bool printed_something {false}; const auto& [vidx, d] : derivatives[i]) { if (exchange(printed_something, true)) d_output[i] << ", "; - int eq { vidx[0] }; + int eq {vidx[0]}; int col_idx {0}; for (size_t j {1}; j < vidx.size(); j++) @@ -1893,7 +1981,8 @@ ModelTree::writeJsonComputingPassOutputHelper(bool writeDetails) const if (i == 2 && vidx[1] != vidx[2]) // Symmetric elements in hessian { - int col_idx_sym { getJacobianCol(vidx[2], false) * getJacobianColsNbr(false) + getJacobianCol(vidx[1], false)}; + int col_idx_sym {getJacobianCol(vidx[2], false) * getJacobianColsNbr(false) + + getJacobianCol(vidx[1], false)}; d_output[i] << ", " << col_idx_sym + 1; } if (i > 1) @@ -1902,9 +1991,11 @@ ModelTree::writeJsonComputingPassOutputHelper(bool writeDetails) const if (writeDetails) for (size_t j = 1; j < vidx.size(); j++) { - d_output[i] << R"(, "var)" << (i > 1 ? to_string(j) : "") << R"(": ")" << getNameByDerivID(vidx[j]) << R"(")"; - if constexpr(dynamic) - d_output[i] << R"(, "shift)" << (i > 1 ? to_string(j) : "") << R"(": )" << getLagByDerivID(vidx[j]); + d_output[i] << R"(, "var)" << (i > 1 ? to_string(j) : "") << R"(": ")" + << getNameByDerivID(vidx[j]) << R"(")"; + if constexpr (dynamic) + d_output[i] << R"(, "shift)" << (i > 1 ? to_string(j) : "") << R"(": )" + << getLagByDerivID(vidx[j]); } d_output[i] << R"(, "val": ")"; @@ -1916,43 +2007,41 @@ ModelTree::writeJsonComputingPassOutputHelper(bool writeDetails) const ncols *= getJacobianColsNbr(false); } - return { move(mlv_output), move(d_output) }; + return {move(mlv_output), move(d_output)}; } template -tuple +tuple ModelTree::writeJsonParamsDerivativesHelper(bool writeDetails) const { ostringstream mlv_output; // Used for storing model local vars - ostringstream tt_output; // Used for storing model temp vars and equations - ostringstream rp_output; // 1st deriv. of residuals w.r.t. parameters - ostringstream gp_output; // 1st deriv. of Jacobian w.r.t. parameters + ostringstream tt_output; // Used for storing model temp vars and equations + ostringstream rp_output; // 1st deriv. of residuals w.r.t. parameters + ostringstream gp_output; // 1st deriv. of Jacobian w.r.t. parameters ostringstream rpp_output; // 2nd deriv of residuals w.r.t. parameters ostringstream gpp_output; // 2nd deriv of Jacobian w.r.t. parameters - ostringstream hp_output; // 1st deriv. of Hessian w.r.t. parameters + ostringstream hp_output; // 1st deriv. of Hessian w.r.t. parameters ostringstream g3p_output; // 1st deriv. of 3rd deriv. matrix w.r.t. parameters deriv_node_temp_terms_t tef_terms; writeJsonModelLocalVariables(mlv_output, true, tef_terms); temporary_terms_t temp_term_union; - for (const auto &[order, tts] : params_derivs_temporary_terms) + for (const auto& [order, tts] : params_derivs_temporary_terms) writeJsonTemporaryTerms(tts, temp_term_union, tt_output, tef_terms, "all"); rp_output << R"("deriv_wrt_params": {)" - << R"( "neqs": )" << equations.size() - << R"(, "nparamcols": )" << symbol_table.param_nbr() - << R"(, "entries": [)"; - for (bool printed_something {false}; - const auto &[vidx, d] : params_derivatives.at({ 0, 1 })) + << R"( "neqs": )" << equations.size() << R"(, "nparamcols": )" + << symbol_table.param_nbr() << R"(, "entries": [)"; + for (bool printed_something {false}; const auto& [vidx, d] : params_derivatives.at({0, 1})) { if (exchange(printed_something, true)) rp_output << ", "; - auto [eq, param] { vectorToTuple<2>(vidx) }; + auto [eq, param] {vectorToTuple<2>(vidx)}; - int param_col { getTypeSpecificIDByDerivID(param) + 1 }; + int param_col {getTypeSpecificIDByDerivID(param) + 1}; if (writeDetails) rp_output << R"({"eq": )" << eq + 1; @@ -1971,33 +2060,30 @@ ModelTree::writeJsonParamsDerivativesHelper(bool writeDetails) const rp_output << "]}"; gp_output << R"("deriv_jacobian_wrt_params": {)" - << R"( "neqs": )" << equations.size() - << R"(, "nvarcols": )" << getJacobianColsNbr(false) - << R"(, "nparamcols": )" << symbol_table.param_nbr() + << R"( "neqs": )" << equations.size() << R"(, "nvarcols": )" + << getJacobianColsNbr(false) << R"(, "nparamcols": )" << symbol_table.param_nbr() << R"(, "entries": [)"; - for (bool printed_something {false}; - const auto &[vidx, d] : params_derivatives.at({ 1, 1 })) + for (bool printed_something {false}; const auto& [vidx, d] : params_derivatives.at({1, 1})) { if (exchange(printed_something, true)) gp_output << ", "; - auto [eq, var, param] { vectorToTuple<3>(vidx) }; + auto [eq, var, param] {vectorToTuple<3>(vidx)}; - int var_col { getJacobianCol(var, false) + 1 }; - int param_col { getTypeSpecificIDByDerivID(param) + 1 }; + int var_col {getJacobianCol(var, false) + 1}; + int param_col {getTypeSpecificIDByDerivID(param) + 1}; if (writeDetails) gp_output << R"({"eq": )" << eq + 1; else gp_output << R"({"row": )" << eq + 1; - gp_output << R"(, "var_col": )" << var_col - << R"(, "param_col": )" << param_col; + gp_output << R"(, "var_col": )" << var_col << R"(, "param_col": )" << param_col; if (writeDetails) { gp_output << R"(, "var": ")" << getNameByDerivID(var) << R"(")"; - if constexpr(dynamic) + if constexpr (dynamic) gp_output << R"(, "lag": )" << getLagByDerivID(var); gp_output << R"(, "param": ")" << getNameByDerivID(param) << R"(")"; } @@ -2009,27 +2095,24 @@ ModelTree::writeJsonParamsDerivativesHelper(bool writeDetails) const gp_output << "]}"; rpp_output << R"("second_deriv_residuals_wrt_params": {)" - << R"( "nrows": )" << equations.size() - << R"(, "nparam1cols": )" << symbol_table.param_nbr() - << R"(, "nparam2cols": )" << symbol_table.param_nbr() + << R"( "nrows": )" << equations.size() << R"(, "nparam1cols": )" + << symbol_table.param_nbr() << R"(, "nparam2cols": )" << symbol_table.param_nbr() << R"(, "entries": [)"; - for (bool printed_something {false}; - const auto &[vidx, d] : params_derivatives.at({ 0, 2 })) + for (bool printed_something {false}; const auto& [vidx, d] : params_derivatives.at({0, 2})) { if (exchange(printed_something, true)) rpp_output << ", "; - auto [eq, param1, param2] { vectorToTuple<3>(vidx) }; + auto [eq, param1, param2] {vectorToTuple<3>(vidx)}; - int param1_col { getTypeSpecificIDByDerivID(param1) + 1 }; - int param2_col { getTypeSpecificIDByDerivID(param2) + 1 }; + int param1_col {getTypeSpecificIDByDerivID(param1) + 1}; + int param2_col {getTypeSpecificIDByDerivID(param2) + 1}; if (writeDetails) rpp_output << R"({"eq": )" << eq + 1; else rpp_output << R"({"row": )" << eq + 1; - rpp_output << R"(, "param1_col": )" << param1_col - << R"(, "param2_col": )" << param2_col; + rpp_output << R"(, "param1_col": )" << param1_col << R"(, "param2_col": )" << param2_col; if (writeDetails) rpp_output << R"(, "param1": ")" << getNameByDerivID(param1) << R"(")" @@ -2042,36 +2125,32 @@ ModelTree::writeJsonParamsDerivativesHelper(bool writeDetails) const rpp_output << "]}"; gpp_output << R"("second_deriv_jacobian_wrt_params": {)" - << R"( "neqs": )" << equations.size() - << R"(, "nvarcols": )" << getJacobianColsNbr(false) - << R"(, "nparam1cols": )" << symbol_table.param_nbr() - << R"(, "nparam2cols": )" << symbol_table.param_nbr() - << R"(, "entries": [)"; - for (bool printed_something {false}; - const auto &[vidx, d] : params_derivatives.at({ 1, 2 })) + << R"( "neqs": )" << equations.size() << R"(, "nvarcols": )" + << getJacobianColsNbr(false) << R"(, "nparam1cols": )" << symbol_table.param_nbr() + << R"(, "nparam2cols": )" << symbol_table.param_nbr() << R"(, "entries": [)"; + for (bool printed_something {false}; const auto& [vidx, d] : params_derivatives.at({1, 2})) { if (exchange(printed_something, true)) gpp_output << ", "; - auto [eq, var, param1, param2] { vectorToTuple<4>(vidx) }; + auto [eq, var, param1, param2] {vectorToTuple<4>(vidx)}; - int var_col { getJacobianCol(var, false) + 1 }; - int param1_col { getTypeSpecificIDByDerivID(param1) + 1 }; - int param2_col { getTypeSpecificIDByDerivID(param2) + 1 }; + int var_col {getJacobianCol(var, false) + 1}; + int param1_col {getTypeSpecificIDByDerivID(param1) + 1}; + int param2_col {getTypeSpecificIDByDerivID(param2) + 1}; if (writeDetails) gpp_output << R"({"eq": )" << eq + 1; else gpp_output << R"({"row": )" << eq + 1; - gpp_output << R"(, "var_col": )" << var_col - << R"(, "param1_col": )" << param1_col + gpp_output << R"(, "var_col": )" << var_col << R"(, "param1_col": )" << param1_col << R"(, "param2_col": )" << param2_col; if (writeDetails) { gpp_output << R"(, "var": ")" << getNameByDerivID(var) << R"(")"; - if constexpr(dynamic) + if constexpr (dynamic) gpp_output << R"(, "lag": )" << getLagByDerivID(var); gpp_output << R"(, "param1": ")" << getNameByDerivID(param1) << R"(")" << R"(, "param2": ")" << getNameByDerivID(param2) << R"(")"; @@ -2084,39 +2163,35 @@ ModelTree::writeJsonParamsDerivativesHelper(bool writeDetails) const gpp_output << "]}" << endl; hp_output << R"("derivative_hessian_wrt_params": {)" - << R"( "neqs": )" << equations.size() - << R"(, "nvar1cols": )" << getJacobianColsNbr(false) - << R"(, "nvar2cols": )" << getJacobianColsNbr(false) - << R"(, "nparamcols": )" << symbol_table.param_nbr() - << R"(, "entries": [)"; - for (bool printed_something {false}; - const auto &[vidx, d] : params_derivatives.at({ 2, 1 })) + << R"( "neqs": )" << equations.size() << R"(, "nvar1cols": )" + << getJacobianColsNbr(false) << R"(, "nvar2cols": )" << getJacobianColsNbr(false) + << R"(, "nparamcols": )" << symbol_table.param_nbr() << R"(, "entries": [)"; + for (bool printed_something {false}; const auto& [vidx, d] : params_derivatives.at({2, 1})) { if (exchange(printed_something, true)) hp_output << ", "; - auto [eq, var1, var2, param] { vectorToTuple<4>(vidx) }; + auto [eq, var1, var2, param] {vectorToTuple<4>(vidx)}; - int var1_col { getJacobianCol(var1, false) + 1 }; - int var2_col { getJacobianCol(var2, false) + 1 }; - int param_col { getTypeSpecificIDByDerivID(param) + 1 }; + int var1_col {getJacobianCol(var1, false) + 1}; + int var2_col {getJacobianCol(var2, false) + 1}; + int param_col {getTypeSpecificIDByDerivID(param) + 1}; if (writeDetails) hp_output << R"({"eq": )" << eq + 1; else hp_output << R"({"row": )" << eq + 1; - hp_output << R"(, "var1_col": )" << var1_col - << R"(, "var2_col": )" << var2_col + hp_output << R"(, "var1_col": )" << var1_col << R"(, "var2_col": )" << var2_col << R"(, "param_col": )" << param_col; if (writeDetails) { hp_output << R"(, "var1": ")" << getNameByDerivID(var1) << R"(")"; - if constexpr(dynamic) + if constexpr (dynamic) hp_output << R"(, "lag1": )" << getLagByDerivID(var1); hp_output << R"(, "var2": ")" << getNameByDerivID(var2) << R"(")"; - if constexpr(dynamic) + if constexpr (dynamic) hp_output << R"(, "lag2": )" << getLagByDerivID(var2); hp_output << R"(, "param": ")" << getNameByDerivID(param) << R"(")"; } @@ -2127,46 +2202,42 @@ ModelTree::writeJsonParamsDerivativesHelper(bool writeDetails) const } hp_output << "]}" << endl; - if constexpr(dynamic) + if constexpr (dynamic) { g3p_output << R"("derivative_g3_wrt_params": {)" - << R"( "neqs": )" << equations.size() - << R"(, "nvar1cols": )" << getJacobianColsNbr(false) - << R"(, "nvar2cols": )" << getJacobianColsNbr(false) - << R"(, "nvar3cols": )" << getJacobianColsNbr(false) - << R"(, "nparamcols": )" << symbol_table.param_nbr() - << R"(, "entries": [)"; - for (bool printed_something {false}; - const auto &[vidx, d] : params_derivatives.at({ 3, 1 })) + << R"( "neqs": )" << equations.size() << R"(, "nvar1cols": )" + << getJacobianColsNbr(false) << R"(, "nvar2cols": )" << getJacobianColsNbr(false) + << R"(, "nvar3cols": )" << getJacobianColsNbr(false) << R"(, "nparamcols": )" + << symbol_table.param_nbr() << R"(, "entries": [)"; + for (bool printed_something {false}; const auto& [vidx, d] : params_derivatives.at({3, 1})) { if (exchange(printed_something, true)) g3p_output << ", "; - auto [eq, var1, var2, var3, param] { vectorToTuple<5>(vidx) }; + auto [eq, var1, var2, var3, param] {vectorToTuple<5>(vidx)}; - int var1_col { getJacobianCol(var1, false) + 1 }; - int var2_col { getJacobianCol(var2, false) + 1 }; - int var3_col { getJacobianCol(var3, false) + 1 }; - int param_col { getTypeSpecificIDByDerivID(param) + 1 }; + int var1_col {getJacobianCol(var1, false) + 1}; + int var2_col {getJacobianCol(var2, false) + 1}; + int var3_col {getJacobianCol(var3, false) + 1}; + int param_col {getTypeSpecificIDByDerivID(param) + 1}; if (writeDetails) g3p_output << R"({"eq": )" << eq + 1; else g3p_output << R"({"row": )" << eq + 1; - g3p_output << R"(, "var1_col": )" << var1_col + 1 - << R"(, "var2_col": )" << var2_col + 1 - << R"(, "var3_col": )" << var3_col + 1 - << R"(, "param_col": )" << param_col + 1; + g3p_output << R"(, "var1_col": )" << var1_col + 1 << R"(, "var2_col": )" << var2_col + 1 + << R"(, "var3_col": )" << var3_col + 1 << R"(, "param_col": )" + << param_col + 1; if (writeDetails) g3p_output << R"(, "var1": ")" << getNameByDerivID(var1) << R"(")" - << R"(, "lag1": )" << getLagByDerivID(var1) - << R"(, "var2": ")" << getNameByDerivID(var2) << R"(")" - << R"(, "lag2": )" << getLagByDerivID(var2) - << R"(, "var3": ")" << getNameByDerivID(var3) << R"(")" - << R"(, "lag3": )" << getLagByDerivID(var3) - << R"(, "param": ")" << getNameByDerivID(param) << R"(")"; + << R"(, "lag1": )" << getLagByDerivID(var1) << R"(, "var2": ")" + << getNameByDerivID(var2) << R"(")" + << R"(, "lag2": )" << getLagByDerivID(var2) << R"(, "var3": ")" + << getNameByDerivID(var3) << R"(")" + << R"(, "lag3": )" << getLagByDerivID(var3) << R"(, "param": ")" + << getNameByDerivID(param) << R"(")"; g3p_output << R"(, "val": ")"; d->writeJsonOutput(g3p_output, temp_term_union, tef_terms); @@ -2175,40 +2246,38 @@ ModelTree::writeJsonParamsDerivativesHelper(bool writeDetails) const g3p_output << "]}" << endl; } - return { move(mlv_output), move(tt_output), move(rp_output), move(gp_output), - move(rpp_output), move(gpp_output), move(hp_output), move(g3p_output) }; + return {move(mlv_output), move(tt_output), move(rp_output), move(gp_output), + move(rpp_output), move(gpp_output), move(hp_output), move(g3p_output)}; } template void -ModelTree::writeDriverSparseIndicesHelper(ostream &output) const +ModelTree::writeDriverSparseIndicesHelper(ostream& output) const { // TODO: when C++20 support is complete, mark this constexpr const string model_name {dynamic ? "dynamic" : "static"}; // Write indices for the sparse Jacobian (both naive and CSC storage) output << "M_." << model_name << "_g1_sparse_rowval = int32(["; - for (const auto &[indices, d1] : jacobian_sparse_column_major_order) - output << indices.first+1 << ' '; - output << "]);" << endl - << "M_." << model_name << "_g1_sparse_colval = int32(["; - for (const auto &[indices, d1] : jacobian_sparse_column_major_order) - output << indices.second+1 << ' '; - output << "]);" << endl - << "M_." << model_name << "_g1_sparse_colptr = int32(["; + for (const auto& [indices, d1] : jacobian_sparse_column_major_order) + output << indices.first + 1 << ' '; + output << "]);" << endl << "M_." << model_name << "_g1_sparse_colval = int32(["; + for (const auto& [indices, d1] : jacobian_sparse_column_major_order) + output << indices.second + 1 << ' '; + output << "]);" << endl << "M_." << model_name << "_g1_sparse_colptr = int32(["; for (int it : jacobian_sparse_colptr) - output << it+1 << ' '; + output << it + 1 << ' '; output << "]);" << endl; // Write indices for the sparse higher-order derivatives for (int i {2}; i <= computed_derivs_order; i++) { output << "M_." << model_name << "_g" << i << "_sparse_indices = int32(["; - for (const auto &[vidx, d] : derivatives[i]) + for (const auto& [vidx, d] : derivatives[i]) { for (bool row_number {true}; // First element of vidx is row number int it : vidx) - output << (exchange(row_number, false) ? it : getJacobianCol(it, true))+1 << ' '; + output << (exchange(row_number, false) ? it : getJacobianCol(it, true)) + 1 << ' '; output << ';' << endl; } output << "]);" << endl; @@ -2217,7 +2286,7 @@ ModelTree::writeDriverSparseIndicesHelper(ostream &output) const template void -ModelTree::writeJsonSparseIndicesHelper(ostream &output) const +ModelTree::writeJsonSparseIndicesHelper(ostream& output) const { // TODO: when C++20 support is complete, mark this constexpr const string model_name {dynamic ? "dynamic" : "static"}; @@ -2225,29 +2294,26 @@ ModelTree::writeJsonSparseIndicesHelper(ostream &output) const // Write indices for the sparse Jacobian (both naive and CSC storage) output << '"' << model_name << R"(_g1_sparse_rowval": [)"; for (bool printed_something {false}; - const auto &[indices, d1] : jacobian_sparse_column_major_order) + const auto& [indices, d1] : jacobian_sparse_column_major_order) { if (exchange(printed_something, true)) output << ", "; - output << indices.first+1; + output << indices.first + 1; } - output << "], " << endl - << '"' << model_name << R"(_g1_sparse_colval": [)"; + output << "], " << endl << '"' << model_name << R"(_g1_sparse_colval": [)"; for (bool printed_something {false}; - const auto &[indices, d1] : jacobian_sparse_column_major_order) + const auto& [indices, d1] : jacobian_sparse_column_major_order) { if (exchange(printed_something, true)) output << ", "; - output << indices.second+1; + output << indices.second + 1; } - output << "], " << endl - << '"' << model_name << R"(_g1_sparse_colptr": [)"; - for (bool printed_something {false}; - int it : jacobian_sparse_colptr) + output << "], " << endl << '"' << model_name << R"(_g1_sparse_colptr": [)"; + for (bool printed_something {false}; int it : jacobian_sparse_colptr) { if (exchange(printed_something, true)) output << ", "; - output << it+1; + output << it + 1; } output << ']' << endl; @@ -2255,19 +2321,17 @@ ModelTree::writeJsonSparseIndicesHelper(ostream &output) const for (int i {2}; i <= computed_derivs_order; i++) { output << R"(, ")" << model_name << "_g" << i << R"(_sparse_indices": [)"; - for (bool printed_something {false}; - const auto &[vidx, d] : derivatives[i]) + for (bool printed_something {false}; const auto& [vidx, d] : derivatives[i]) { if (exchange(printed_something, true)) output << ", "; output << '['; - for (bool printed_something2 {false}; - int it : vidx) + for (bool printed_something2 {false}; int it : vidx) { if (printed_something2) output << ", "; // First element of vidx is row number - output << (exchange(printed_something2, true) ? getJacobianCol(it, true) : it)+1; + output << (exchange(printed_something2, true) ? getJacobianCol(it, true) : it) + 1; } output << ']' << endl; } @@ -2277,31 +2341,31 @@ ModelTree::writeJsonSparseIndicesHelper(ostream &output) const template void -ModelTree::writeBlockDriverSparseIndicesHelper(ostream &output) const +ModelTree::writeBlockDriverSparseIndicesHelper(ostream& output) const { for (int blk {0}; blk < static_cast(blocks.size()); blk++) { - const string struct_name { "M_.block_structure"s + (dynamic ? "" : "_stat") + ".block(" + to_string(blk+1) + ")." }; + const string struct_name {"M_.block_structure"s + (dynamic ? "" : "_stat") + ".block(" + + to_string(blk + 1) + ")."}; // Write indices for the sparse Jacobian (both naive and CSC storage) output << struct_name << "g1_sparse_rowval = int32(["; - for (const auto &[indices, d1] : blocks_jacobian_sparse_column_major_order.at(blk)) - output << indices.first+1 << ' '; - output << "]);" << endl - << struct_name << "g1_sparse_colval = int32(["; - for (const auto &[indices, d1] : blocks_jacobian_sparse_column_major_order.at(blk)) - output << indices.second+1 << ' '; - output << "]);" << endl - << struct_name << "g1_sparse_colptr = int32(["; + for (const auto& [indices, d1] : blocks_jacobian_sparse_column_major_order.at(blk)) + output << indices.first + 1 << ' '; + output << "]);" << endl << struct_name << "g1_sparse_colval = int32(["; + for (const auto& [indices, d1] : blocks_jacobian_sparse_column_major_order.at(blk)) + output << indices.second + 1 << ' '; + output << "]);" << endl << struct_name << "g1_sparse_colptr = int32(["; for (int it : blocks_jacobian_sparse_colptr.at(blk)) - output << it+1 << ' '; + output << it + 1 << ' '; output << "]);" << endl; } } template void -ModelTree::writeSparsePerBlockJacobianHelper(int blk, ostream &output, temporary_terms_t &temporary_terms) const +ModelTree::writeSparsePerBlockJacobianHelper(int blk, ostream& output, + temporary_terms_t& temporary_terms) const { static_assert(isSparseModelOutput(output_type)); @@ -2314,11 +2378,11 @@ ModelTree::writeSparsePerBlockJacobianHelper(int blk, ostream &output, temporary && blocks[blk].simulation_type != BlockSimulationType::evaluateBackward); int k {0}; - for (const auto &[row_col, d1] : blocks_jacobian_sparse_column_major_order[blk]) + for (const auto& [row_col, d1] : blocks_jacobian_sparse_column_major_order[blk]) { output << "g1_v" << LEFT_ARRAY_SUBSCRIPT(output_type) - << k + ARRAY_SUBSCRIPT_OFFSET(output_type) - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; + << k + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type) + << "="; d1->writeOutput(output, output_type, temporary_terms, blocks_temporary_terms_idxs); output << ";" << endl; k++; @@ -2327,17 +2391,19 @@ ModelTree::writeSparsePerBlockJacobianHelper(int blk, ostream &output, temporary template void -ModelTree::writeSparseModelJuliaFiles(const string &basename) const +ModelTree::writeSparseModelJuliaFiles(const string& basename) const { - auto [d_sparse_output, tt_sparse_output] = writeModelFileHelper(); + auto [d_sparse_output, tt_sparse_output] = writeModelFileHelper < dynamic + ? ExprNodeOutputType::juliaSparseDynamicModel + : ExprNodeOutputType::juliaSparseStaticModel > (); - filesystem::path julia_dir {filesystem::path{basename} / "model" / "julia"}; + filesystem::path julia_dir {filesystem::path {basename} / "model" / "julia"}; // TODO: when C++20 support is complete, mark the following strings constexpr - const string prefix { dynamic ? "SparseDynamic" : "SparseStatic" }; - const string ss_argin { dynamic ? ", steady_state::Vector{<: Real}" : "" }; - const string ss_argout { dynamic ? ", steady_state" : "" }; - const int ylen {(dynamic ? 3 : 1)*symbol_table.endo_nbr()}; - const int xlen {symbol_table.exo_nbr()+symbol_table.exo_det_nbr()}; + const string prefix {dynamic ? "SparseDynamic" : "SparseStatic"}; + const string ss_argin {dynamic ? ", steady_state::Vector{<: Real}" : ""}; + const string ss_argout {dynamic ? ", steady_state" : ""}; + const int ylen {(dynamic ? 3 : 1) * symbol_table.endo_nbr()}; + const int xlen {symbol_table.exo_nbr() + symbol_table.exo_det_nbr()}; size_t ttlen {0}; @@ -2345,31 +2411,30 @@ ModelTree::writeSparseModelJuliaFiles(const string &basename) const // ResidTT! output << "function " << prefix << "ResidTT!(T::Vector{<: Real}, " - << "y::Vector{<: Real}, x::Vector{<: Real}, params::Vector{<: Real}" - << ss_argin << ")" << endl + << "y::Vector{<: Real}, x::Vector{<: Real}, params::Vector{<: Real}" << ss_argin << ")" + << endl << "@inbounds begin" << endl - << tt_sparse_output[0].str() - << "end" << endl + << tt_sparse_output[0].str() << "end" << endl << " return nothing" << endl - << "end" << endl << endl; + << "end" << endl + << endl; writeToFileIfModified(output, julia_dir / (prefix + "ResidTT!.jl")); ttlen += temporary_terms_derivatives[0].size(); // Resid! output.str(""); - output << "function " << prefix << "Resid!(T::Vector{<: Real}, residual::AbstractVector{<: Real}, " - << "y::Vector{<: Real}, x::Vector{<: Real}, params::Vector{<: Real}" - << ss_argin << ")" << endl + output << "function " << prefix + << "Resid!(T::Vector{<: Real}, residual::AbstractVector{<: Real}, " + << "y::Vector{<: Real}, x::Vector{<: Real}, params::Vector{<: Real}" << ss_argin << ")" + << endl << " @assert length(T) >= " << ttlen << endl << " @assert length(residual) == " << equations.size() << endl << " @assert length(y) == " << ylen << endl << " @assert length(x) == " << xlen << endl << " @assert length(params) == " << symbol_table.param_nbr() << endl << "@inbounds begin" << endl - << d_sparse_output[0].str() - << "end" << endl; - output << " return nothing" << endl - << "end" << endl << endl; + << d_sparse_output[0].str() << "end" << endl; + output << " return nothing" << endl << "end" << endl << endl; writeToFileIfModified(output, julia_dir / (prefix + "Resid!.jl")); // G1TT! @@ -2378,28 +2443,26 @@ ModelTree::writeSparseModelJuliaFiles(const string &basename) const << "x::Vector{<: Real}, params::Vector{<: Real}" << ss_argin << ")" << endl << " " << prefix << "ResidTT!(T, y, x, params" << ss_argout << ")" << endl << "@inbounds begin" << endl - << tt_sparse_output[1].str() - << "end" << endl + << tt_sparse_output[1].str() << "end" << endl << " return nothing" << endl - << "end" << endl << endl; + << "end" << endl + << endl; writeToFileIfModified(output, julia_dir / (prefix + "G1TT!.jl")); ttlen += temporary_terms_derivatives[1].size(); // G1! output.str(""); output << "function " << prefix << "G1!(T::Vector{<: Real}, g1_v::Vector{<: Real}, " - << "y::Vector{<: Real}, x::Vector{<: Real}, params::Vector{<: Real}" - << ss_argin << ")" << endl + << "y::Vector{<: Real}, x::Vector{<: Real}, params::Vector{<: Real}" << ss_argin << ")" + << endl << " @assert length(T) >= " << ttlen << endl << " @assert length(g1_v) == " << derivatives[1].size() << endl << " @assert length(y) == " << ylen << endl << " @assert length(x) == " << xlen << endl << " @assert length(params) == " << symbol_table.param_nbr() << endl << "@inbounds begin" << endl - << d_sparse_output[1].str() - << "end" << endl; - output << " return nothing" << endl - << "end" << endl << endl; + << d_sparse_output[1].str() << "end" << endl; + output << " return nothing" << endl << "end" << endl << endl; writeToFileIfModified(output, julia_dir / (prefix + "G1!.jl")); for (int i {2}; i <= computed_derivs_order; i++) @@ -2408,30 +2471,32 @@ ModelTree::writeSparseModelJuliaFiles(const string &basename) const output.str(""); output << "function " << prefix << "G" << i << "TT!(T::Vector{<: Real}, y::Vector{<: Real}, " << "x::Vector{<: Real}, params::Vector{<: Real}" << ss_argin << ")" << endl - << " " << prefix << "G" << to_string(i-1) << "TT!(T, y, x, params" << ss_argout << ")" << endl + << " " << prefix << "G" << to_string(i - 1) << "TT!(T, y, x, params" << ss_argout + << ")" << endl << "@inbounds begin" << endl - << tt_sparse_output[i].str() - << "end" << endl + << tt_sparse_output[i].str() << "end" << endl << " return nothing" << endl - << "end" << endl << endl; + << "end" << endl + << endl; writeToFileIfModified(output, julia_dir / (prefix + "G" + to_string(i) + "TT!.jl")); ttlen += temporary_terms_derivatives[i].size(); // G! output.str(""); - output << "function " << prefix << "G" << i << "!(T::Vector{<: Real}, g" << i << "_v::Vector{<: Real}, " - << "y::Vector{<: Real}, x::Vector{<: Real}, params::Vector{<: Real}" - << ss_argin << ")" << endl + output << "function " << prefix << "G" << i << "!(T::Vector{<: Real}, g" << i + << "_v::Vector{<: Real}, " + << "y::Vector{<: Real}, x::Vector{<: Real}, params::Vector{<: Real}" << ss_argin << ")" + << endl << " @assert length(T) >= " << ttlen << endl << " @assert length(g" << i << "_v) == " << derivatives[i].size() << endl << " @assert length(y) == " << ylen << endl << " @assert length(x) == " << xlen << endl << " @assert length(params) == " << symbol_table.param_nbr() << endl << "@inbounds begin" << endl - << d_sparse_output[i].str() - << "end" << endl + << d_sparse_output[i].str() << "end" << endl << " return nothing" << endl - << "end" << endl << endl; + << "end" << endl + << endl; writeToFileIfModified(output, julia_dir / (prefix + "G" + to_string(i) + "!.jl")); } } @@ -2439,22 +2504,22 @@ ModelTree::writeSparseModelJuliaFiles(const string &basename) const template void -ModelTree::writeSparseModelMFiles(const string &basename) const +ModelTree::writeSparseModelMFiles(const string& basename) const { - constexpr ExprNodeOutputType output_type {dynamic ? ExprNodeOutputType::matlabSparseDynamicModel : ExprNodeOutputType::matlabSparseStaticModel}; + constexpr ExprNodeOutputType output_type {dynamic ? ExprNodeOutputType::matlabSparseDynamicModel + : ExprNodeOutputType::matlabSparseStaticModel}; auto [d_sparse_output, tt_sparse_output] = writeModelFileHelper(); const filesystem::path m_dir {packageDir(basename) / "+sparse"}; // TODO: when C++20 support is complete, mark the following strings constexpr - const string prefix { dynamic ? "dynamic_" : "static_" }; - const string full_prefix { basename + ".sparse." + prefix }; - const string ss_arg { dynamic ? ", steady_state" : "" }; + const string prefix {dynamic ? "dynamic_" : "static_"}; + const string full_prefix {basename + ".sparse." + prefix}; + const string ss_arg {dynamic ? ", steady_state" : ""}; size_t ttlen {temporary_terms_derivatives[0].size()}; ofstream output; - auto open_file = [&output](const filesystem::path &p) - { + auto open_file = [&output](const filesystem::path& p) { output.open(p, ios::out | ios::binary); if (!output.is_open()) { @@ -2465,7 +2530,8 @@ ModelTree::writeSparseModelMFiles(const string &basename) const // Residuals (non-block) open_file(m_dir / (prefix + "resid_tt.m")); - output << "function [T_order, T] = " << prefix << "resid_tt(y, x, params" << ss_arg << ", T_order, T)" << endl + output << "function [T_order, T] = " << prefix << "resid_tt(y, x, params" << ss_arg + << ", T_order, T)" << endl << "if T_order >= 0" << endl << " return" << endl << "end" << endl @@ -2473,17 +2539,18 @@ ModelTree::writeSparseModelMFiles(const string &basename) const << "if size(T, 1) < " << ttlen << endl << " T = [T; NaN(" << ttlen << " - size(T, 1), 1)];" << endl << "end" << endl - << tt_sparse_output[0].str() - << "end" << endl; + << tt_sparse_output[0].str() << "end" << endl; output.close(); open_file(m_dir / (prefix + "resid.m")); - output << "function [residual, T_order, T] = " << prefix << "resid(y, x, params" << ss_arg << ", T_order, T)" << endl - << "if nargin < " << 5+static_cast(dynamic) << endl + output << "function [residual, T_order, T] = " << prefix << "resid(y, x, params" << ss_arg + << ", T_order, T)" << endl + << "if nargin < " << 5 + static_cast(dynamic) << endl << " T_order = -1;" << endl << " T = NaN(" << ttlen << ", 1);" << endl << "end" << endl - << "[T_order, T] = " << full_prefix << "resid_tt(y, x, params" << ss_arg << ", T_order, T);" << endl + << "[T_order, T] = " << full_prefix << "resid_tt(y, x, params" << ss_arg + << ", T_order, T);" << endl << "residual = NaN(" << equations.size() << ", 1);" << endl << d_sparse_output[0].str(); output << "end" << endl; @@ -2493,27 +2560,30 @@ ModelTree::writeSparseModelMFiles(const string &basename) const ttlen += temporary_terms_derivatives[1].size(); open_file(m_dir / (prefix + "g1_tt.m")); - output << "function [T_order, T] = " << prefix << "g1_tt(y, x, params" << ss_arg << ", T_order, T)" << endl + output << "function [T_order, T] = " << prefix << "g1_tt(y, x, params" << ss_arg + << ", T_order, T)" << endl << "if T_order >= 1" << endl << " return" << endl << "end" << endl - << "[T_order, T] = " << full_prefix << "resid_tt(y, x, params" << ss_arg << ", T_order, T);" << endl + << "[T_order, T] = " << full_prefix << "resid_tt(y, x, params" << ss_arg + << ", T_order, T);" << endl << "T_order = 1;" << endl << "if size(T, 1) < " << ttlen << endl << " T = [T; NaN(" << ttlen << " - size(T, 1), 1)];" << endl << "end" << endl - << tt_sparse_output[1].str() - << "end" << endl; + << tt_sparse_output[1].str() << "end" << endl; output.close(); open_file(m_dir / (prefix + "g1.m")); // NB: At first order, sparse indices are passed as extra arguments - output << "function [g1, T_order, T] = " << prefix << "g1(y, x, params" << ss_arg << ", sparse_rowval, sparse_colval, sparse_colptr, T_order, T)" << endl - << "if nargin < " << 8+static_cast(dynamic) << endl + output << "function [g1, T_order, T] = " << prefix << "g1(y, x, params" << ss_arg + << ", sparse_rowval, sparse_colval, sparse_colptr, T_order, T)" << endl + << "if nargin < " << 8 + static_cast(dynamic) << endl << " T_order = -1;" << endl << " T = NaN(" << ttlen << ", 1);" << endl << "end" << endl - << "[T_order, T] = " << full_prefix << "g1_tt(y, x, params" << ss_arg << ", T_order, T);" << endl + << "[T_order, T] = " << full_prefix << "g1_tt(y, x, params" << ss_arg << ", T_order, T);" + << endl << "g1_v = NaN(" << jacobian_sparse_column_major_order.size() << ", 1);" << endl << d_sparse_output[1].str(); // On MATLAB < R2020a, sparse() does not accept int32 indices @@ -2521,7 +2591,8 @@ ModelTree::writeSparseModelMFiles(const string &basename) const << " sparse_rowval = double(sparse_rowval);" << endl << " sparse_colval = double(sparse_colval);" << endl << "end" << endl - << "g1 = sparse(sparse_rowval, sparse_colval, g1_v, " << equations.size() << ", " << getJacobianColsNbr(true) << ");" << endl + << "g1 = sparse(sparse_rowval, sparse_colval, g1_v, " << equations.size() << ", " + << getJacobianColsNbr(true) << ");" << endl << "end" << endl; output.close(); @@ -2535,25 +2606,26 @@ ModelTree::writeSparseModelMFiles(const string &basename) const << "if T_order >= " << i << endl << " return" << endl << "end" << endl - << "[T_order, T] = " << full_prefix << "g" << i-1 << "_tt(y, x, params" << ss_arg << ", T_order, T);" << endl + << "[T_order, T] = " << full_prefix << "g" << i - 1 << "_tt(y, x, params" << ss_arg + << ", T_order, T);" << endl << "T_order = " << i << ";" << endl << "if size(T, 1) < " << ttlen << endl << " T = [T; NaN(" << ttlen << " - size(T, 1), 1)];" << endl << "end" << endl - << tt_sparse_output[i].str() - << "end" << endl; + << tt_sparse_output[i].str() << "end" << endl; output.close(); open_file(m_dir / (prefix + "g" + to_string(i) + ".m")); - output << "function [g" << i << "_v, T_order, T] = " << prefix << "g" << i << "(y, x, params" << ss_arg << ", T_order, T)" << endl - << "if nargin < " << 5+static_cast(dynamic) << endl + output << "function [g" << i << "_v, T_order, T] = " << prefix << "g" << i << "(y, x, params" + << ss_arg << ", T_order, T)" << endl + << "if nargin < " << 5 + static_cast(dynamic) << endl << " T_order = -1;" << endl << " T = NaN(" << ttlen << ", 1);" << endl << "end" << endl - << "[T_order, T] = " << full_prefix << "g" << i << "_tt(y, x, params" << ss_arg << ", T_order, T);" << endl + << "[T_order, T] = " << full_prefix << "g" << i << "_tt(y, x, params" << ss_arg + << ", T_order, T);" << endl << "g" << i << "_v = NaN(" << derivatives[i].size() << ", 1);" << endl - << d_sparse_output[i].str() - << "end" << endl; + << d_sparse_output[i].str() << "end" << endl; output.close(); } @@ -2564,13 +2636,14 @@ ModelTree::writeSparseModelMFiles(const string &basename) const temporary_terms_t temporary_terms_written; for (int blk {0}; blk < static_cast(blocks.size()); blk++) { - const string funcname {prefix + to_string(blk+1)}; + const string funcname {prefix + to_string(blk + 1)}; const BlockSimulationType simulation_type {blocks[blk].simulation_type}; const bool evaluate {simulation_type == BlockSimulationType::evaluateForward || simulation_type == BlockSimulationType::evaluateBackward}; const string resid_g1_arg {evaluate ? "" : ", residual, g1"}; open_file(block_dir / (funcname + ".m")); - output << "function [y, T" << resid_g1_arg << "] = " << funcname << "(y, x, params" << ss_arg << ", sparse_rowval, sparse_colval, sparse_colptr, T)" << endl; + output << "function [y, T" << resid_g1_arg << "] = " << funcname << "(y, x, params" + << ss_arg << ", sparse_rowval, sparse_colval, sparse_colptr, T)" << endl; if (!evaluate) output << "residual=NaN(" << blocks[blk].mfs_size << ", 1);" << endl; @@ -2580,20 +2653,23 @@ ModelTree::writeSparseModelMFiles(const string &basename) const // Write Jacobian if (!evaluate) { - const bool one_boundary {simulation_type == BlockSimulationType::solveBackwardSimple - || simulation_type == BlockSimulationType::solveForwardSimple - || simulation_type == BlockSimulationType::solveBackwardComplete - || simulation_type == BlockSimulationType::solveForwardComplete}; + const bool one_boundary { + simulation_type == BlockSimulationType::solveBackwardSimple + || simulation_type == BlockSimulationType::solveForwardSimple + || simulation_type == BlockSimulationType::solveBackwardComplete + || simulation_type == BlockSimulationType::solveForwardComplete}; output << "if nargout > 3" << endl - << " g1_v = NaN(" << blocks_jacobian_sparse_column_major_order[blk].size() << ", 1);" << endl; + << " g1_v = NaN(" << blocks_jacobian_sparse_column_major_order[blk].size() + << ", 1);" << endl; writeSparsePerBlockJacobianHelper(blk, output, temporary_terms_written); // On MATLAB < R2020a, sparse() does not accept int32 indices output << " if ~isoctave && matlab_ver_less_than('9.8')" << endl << " sparse_rowval = double(sparse_rowval);" << endl << " sparse_colval = double(sparse_colval);" << endl << " end" << endl - << " g1 = sparse(sparse_rowval, sparse_colval, g1_v, " << blocks[blk].mfs_size << ", " - << (one_boundary ? 1 : 3)*blocks[blk].mfs_size << ");" << endl + << " g1 = sparse(sparse_rowval, sparse_colval, g1_v, " + << blocks[blk].mfs_size << ", " + << (one_boundary ? 1 : 3) * blocks[blk].mfs_size << ");" << endl << "end" << endl; } output << "end" << endl; @@ -2604,26 +2680,26 @@ ModelTree::writeSparseModelMFiles(const string &basename) const template void -ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext, - const filesystem::path &matlabroot) const +ModelTree::writeSparseModelCFiles(const string& basename, const string& mexext, + const filesystem::path& matlabroot) const { - constexpr ExprNodeOutputType output_type {dynamic ? ExprNodeOutputType::CSparseDynamicModel : ExprNodeOutputType::CSparseStaticModel}; + constexpr ExprNodeOutputType output_type {dynamic ? ExprNodeOutputType::CSparseDynamicModel + : ExprNodeOutputType::CSparseStaticModel}; auto [d_sparse_output, tt_sparse_output] = writeModelFileHelper(); const filesystem::path mex_dir {packageDir(basename) / "+sparse"}; - const filesystem::path model_src_dir {filesystem::path{basename} / "model" / "src" / "sparse"}; + const filesystem::path model_src_dir {filesystem::path {basename} / "model" / "src" / "sparse"}; // TODO: when C++20 support is complete, mark the following strings constexpr - const string prefix { dynamic ? "dynamic_" : "static_" }; - const string ss_argin { dynamic ? ", const double *restrict steady_state" : "" }; - const string ss_argout { dynamic ? ", steady_state" : "" }; - const int ylen {(dynamic ? 3 : 1)*symbol_table.endo_nbr()}; - const int xlen {symbol_table.exo_nbr()+symbol_table.exo_det_nbr()}; + const string prefix {dynamic ? "dynamic_" : "static_"}; + const string ss_argin {dynamic ? ", const double *restrict steady_state" : ""}; + const string ss_argout {dynamic ? ", steady_state" : ""}; + const int ylen {(dynamic ? 3 : 1) * symbol_table.endo_nbr()}; + const int xlen {symbol_table.exo_nbr() + symbol_table.exo_det_nbr()}; vector tt_object_files; ofstream output; - auto open_file = [&output](const filesystem::path &p) - { + auto open_file = [&output](const filesystem::path& p) { output.open(p, ios::out | ios::binary); if (!output.is_open()) { @@ -2635,66 +2711,88 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext, size_t ttlen {0}; // Helper for dealing with y, x, params and steady_state inputs (shared with block case) - auto y_x_params_ss_inputs = [&](bool assign_y) - { - output << " if (!(mxIsDouble(prhs[0]) && !mxIsComplex(prhs[0]) && !mxIsSparse(prhs[0]) && mxGetNumberOfElements(prhs[0]) == " << ylen << "))" << endl - << R"( mexErrMsgTxt("y must be a real dense numeric array with )" << ylen << R"( elements");)" << endl; + auto y_x_params_ss_inputs = [&](bool assign_y) { + output << " if (!(mxIsDouble(prhs[0]) && !mxIsComplex(prhs[0]) && !mxIsSparse(prhs[0]) && " + "mxGetNumberOfElements(prhs[0]) == " + << ylen << "))" << endl + << R"( mexErrMsgTxt("y must be a real dense numeric array with )" << ylen + << R"( elements");)" << endl; if (assign_y) output << " const double *restrict y = mxGetPr(prhs[0]);" << endl; - output << " if (!(mxIsDouble(prhs[1]) && !mxIsComplex(prhs[1]) && !mxIsSparse(prhs[1]) && mxGetNumberOfElements(prhs[1]) == " << xlen << "))" << endl - << R"( mexErrMsgTxt("x must be a real dense numeric array with )" << xlen << R"( elements");)" << endl + output << " if (!(mxIsDouble(prhs[1]) && !mxIsComplex(prhs[1]) && !mxIsSparse(prhs[1]) && " + "mxGetNumberOfElements(prhs[1]) == " + << xlen << "))" << endl + << R"( mexErrMsgTxt("x must be a real dense numeric array with )" << xlen + << R"( elements");)" << endl << " const double *restrict x = mxGetPr(prhs[1]);" << endl - << " if (!(mxIsDouble(prhs[2]) && !mxIsComplex(prhs[2]) && !mxIsSparse(prhs[2]) && mxGetNumberOfElements(prhs[2]) == " << symbol_table.param_nbr() << "))" << endl - << R"( mexErrMsgTxt("params must be a real dense numeric array with )" << symbol_table.param_nbr() << R"( elements");)" << endl + << " if (!(mxIsDouble(prhs[2]) && !mxIsComplex(prhs[2]) && !mxIsSparse(prhs[2]) && " + "mxGetNumberOfElements(prhs[2]) == " + << symbol_table.param_nbr() << "))" << endl + << R"( mexErrMsgTxt("params must be a real dense numeric array with )" + << symbol_table.param_nbr() << R"( elements");)" << endl << " const double *restrict params = mxGetPr(prhs[2]);" << endl; - if constexpr(dynamic) - output << " if (!(mxIsDouble(prhs[3]) && !mxIsComplex(prhs[3]) && !mxIsSparse(prhs[3]) && mxGetNumberOfElements(prhs[3]) == " << symbol_table.endo_nbr() << "))" << endl - << R"( mexErrMsgTxt("steady_state must be a real dense numeric array with )" << symbol_table.endo_nbr() << R"( elements");)" << endl + if constexpr (dynamic) + output << " if (!(mxIsDouble(prhs[3]) && !mxIsComplex(prhs[3]) && !mxIsSparse(prhs[3]) && " + "mxGetNumberOfElements(prhs[3]) == " + << symbol_table.endo_nbr() << "))" << endl + << R"( mexErrMsgTxt("steady_state must be a real dense numeric array with )" + << symbol_table.endo_nbr() << R"( elements");)" << endl << " const double *restrict steady_state = mxGetPr(prhs[3]);" << endl; }; // Helper for dealing with sparse_rowval and sparse_colptr inputs (shared with block case) - auto sparse_indices_inputs = [&](int ncols, int nzval) - { + auto sparse_indices_inputs = [&](int ncols, int nzval) { // We use sparse_rowval and sparse_colptr (sparse_colval is unused) - const int row_idx {3+static_cast(dynamic)}, col_idx {row_idx+2}; - output << " if (!(mxIsInt32(prhs[" << row_idx << "]) && mxGetNumberOfElements(prhs[" << row_idx << "]) == " << nzval << "))" << endl - << R"( mexErrMsgTxt("sparse_rowval must be an int32 array with )" << nzval << R"( elements");)" << endl - << " if (!(mxIsInt32(prhs[" << col_idx << "]) && mxGetNumberOfElements(prhs[" << col_idx << "]) == " << ncols+1 << "))" << endl - << R"( mexErrMsgTxt("sparse_colptr must be an int32 array with )" << ncols+1 << R"( elements");)" << endl + const int row_idx {3 + static_cast(dynamic)}, col_idx {row_idx + 2}; + output << " if (!(mxIsInt32(prhs[" << row_idx << "]) && mxGetNumberOfElements(prhs[" << row_idx + << "]) == " << nzval << "))" << endl + << R"( mexErrMsgTxt("sparse_rowval must be an int32 array with )" << nzval + << R"( elements");)" << endl + << " if (!(mxIsInt32(prhs[" << col_idx << "]) && mxGetNumberOfElements(prhs[" << col_idx + << "]) == " << ncols + 1 << "))" << endl + << R"( mexErrMsgTxt("sparse_colptr must be an int32 array with )" << ncols + 1 + << R"( elements");)" << endl << "#if MX_HAS_INTERLEAVED_COMPLEX" << endl - << " const int32_T *restrict sparse_rowval = mxGetInt32s(prhs[" << row_idx << "]);" << endl - << " const int32_T *restrict sparse_colptr = mxGetInt32s(prhs[" << col_idx << "]);" << endl + << " const int32_T *restrict sparse_rowval = mxGetInt32s(prhs[" << row_idx << "]);" + << endl + << " const int32_T *restrict sparse_colptr = mxGetInt32s(prhs[" << col_idx << "]);" + << endl << "#else" << endl - << " const int32_T *restrict sparse_rowval = (int32_T *) mxGetData(prhs[" << row_idx << "]);" << endl - << " const int32_T *restrict sparse_colptr = (int32_T *) mxGetData(prhs[" << col_idx << "]);" << endl + << " const int32_T *restrict sparse_rowval = (int32_T *) mxGetData(prhs[" << row_idx + << "]);" << endl + << " const int32_T *restrict sparse_colptr = (int32_T *) mxGetData(prhs[" << col_idx + << "]);" << endl << "#endif" << endl; }; // Helper for creating sparse Jacobian (shared with block case) - auto sparse_jacobian_create = [&](int argidx, int nrows, int ncols, int nzval) - { - output << " plhs[" << argidx << "] = mxCreateSparse(" << nrows << ", " << ncols << ", " << nzval << ", mxREAL);" << endl - << " mwIndex *restrict ir = mxGetIr(plhs[" << argidx << "]), *restrict jc = mxGetJc(plhs[" << argidx << "]);" << endl + auto sparse_jacobian_create = [&](int argidx, int nrows, int ncols, int nzval) { + output << " plhs[" << argidx << "] = mxCreateSparse(" << nrows << ", " << ncols << ", " + << nzval << ", mxREAL);" << endl + << " mwIndex *restrict ir = mxGetIr(plhs[" << argidx + << "]), *restrict jc = mxGetJc(plhs[" << argidx << "]);" << endl << " for (mwSize i = 0; i < " << nzval << "; i++)" << endl << " *ir++ = *sparse_rowval++ - 1;" << endl - << " for (mwSize i = 0; i < " << ncols+1 << "; i++)" << endl + << " for (mwSize i = 0; i < " << ncols + 1 << "; i++)" << endl << " *jc++ = *sparse_colptr++ - 1;" << endl; }; for (int i {0}; i <= computed_derivs_order; i++) { - const string funcname { prefix + (i == 0 ? "resid" : "g" + to_string(i))}; + const string funcname {prefix + (i == 0 ? "resid" : "g" + to_string(i))}; ttlen += temporary_terms_derivatives[i].size(); - const string prototype_tt { "void " + funcname + "_tt(const double *restrict y, const double *restrict x, const double *restrict params" + ss_argin + ", double *restrict T)" }; + const string prototype_tt { + "void " + funcname + + "_tt(const double *restrict y, const double *restrict x, const double *restrict params" + + ss_argin + ", double *restrict T)"}; - const filesystem::path header_tt { model_src_dir / (funcname + "_tt.h") }; + const filesystem::path header_tt {model_src_dir / (funcname + "_tt.h")}; open_file(header_tt); output << prototype_tt << ";" << endl; output.close(); - const filesystem::path source_tt { model_src_dir / (funcname + "_tt.c") }; + const filesystem::path source_tt {model_src_dir / (funcname + "_tt.c")}; open_file(source_tt); output << "#include " << endl << R"(#include "mex.h")" << endl // Needed for calls to external functions @@ -2703,21 +2801,24 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext, output << endl << prototype_tt << endl << "{" << endl - << tt_sparse_output[i].str() - << "}" << endl + << tt_sparse_output[i].str() << "}" << endl << endl; output.close(); - tt_object_files.push_back(compileMEX(model_src_dir, funcname + "_tt", mexext, { source_tt }, - matlabroot, false)); + tt_object_files.push_back( + compileMEX(model_src_dir, funcname + "_tt", mexext, {source_tt}, matlabroot, false)); - const string prototype_main {"void " + funcname + "(const double *restrict y, const double *restrict x, const double *restrict params" + ss_argin + ", const double *restrict T, double *restrict " + (i == 0 ? "residual" : "g" + to_string(i) + "_v") + ")"}; + const string prototype_main { + "void " + funcname + + "(const double *restrict y, const double *restrict x, const double *restrict params" + + ss_argin + ", const double *restrict T, double *restrict " + + (i == 0 ? "residual" : "g" + to_string(i) + "_v") + ")"}; - const filesystem::path header_main { model_src_dir / (funcname + ".h") }; + const filesystem::path header_main {model_src_dir / (funcname + ".h")}; open_file(header_main); output << prototype_main << ";" << endl; output.close(); - const filesystem::path source_main { model_src_dir / (funcname + ".c") }; + const filesystem::path source_main {model_src_dir / (funcname + ".c")}; open_file(source_main); output << "#include " << endl << R"(#include "mex.h")" << endl // Needed for calls to external functions @@ -2727,28 +2828,30 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext, output << endl << prototype_main << endl << "{" << endl - << d_sparse_output[i].str() - << "}" << endl + << d_sparse_output[i].str() << "}" << endl << endl; output.close(); - auto main_object_file {compileMEX(model_src_dir, funcname, mexext, { source_main }, - matlabroot, false)}; + auto main_object_file { + compileMEX(model_src_dir, funcname, mexext, {source_main}, matlabroot, false)}; - const filesystem::path source_mex { model_src_dir / (funcname + "_mex.c")}; - int nargin {5+static_cast(dynamic)+3*static_cast(i == 1)}; + const filesystem::path source_mex {model_src_dir / (funcname + "_mex.c")}; + int nargin {5 + static_cast(dynamic) + 3 * static_cast(i == 1)}; open_file(source_mex); output << "#include " << endl // For memcpy() << R"(#include "mex.h")" << endl << R"(#include ")" << funcname << R"(.h")" << endl; for (int j {0}; j <= i; j++) - output << R"(#include ")" << prefix << (j == 0 ? "resid" : "g" + to_string(j)) << R"(_tt.h")" << endl; + output << R"(#include ")" << prefix << (j == 0 ? "resid" : "g" + to_string(j)) + << R"(_tt.h")" << endl; output << endl << "#define max(a, b) ((a > b) ? (a) : (b))" << endl << endl - << "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl + << "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" + << endl << "{" << endl - << " if (nrhs != " << nargin-2 << " && nrhs != " << nargin << ")" << endl - << R"( mexErrMsgTxt("Accepts exactly )" << nargin-2 << " or " << nargin << R"( input arguments");)" << endl + << " if (nrhs != " << nargin - 2 << " && nrhs != " << nargin << ")" << endl + << R"( mexErrMsgTxt("Accepts exactly )" << nargin - 2 << " or " << nargin + << R"( input arguments");)" << endl << " if (nlhs != 1 && nlhs != 3)" << endl << R"( mexErrMsgTxt("Accepts exactly 1 or 3 output arguments");)" << endl; @@ -2757,53 +2860,60 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext, if (i == 1) sparse_indices_inputs(getJacobianColsNbr(true), jacobian_sparse_column_major_order.size()); - output << " mxArray *T_mx, *T_order_mx;" << endl - << " int T_order_on_input;" << endl - << " if (nrhs > " << nargin-2 << ")" << endl - << " {" << endl - << " T_order_mx = (mxArray *) prhs[" << nargin-2 << "];" << endl - << " T_mx = (mxArray *) prhs[" << nargin-1 << "];" << endl - << " if (!(mxIsScalar(T_order_mx) && mxIsNumeric(T_order_mx)))" << endl - << R"( mexErrMsgTxt("T_order should be a numeric scalar");)" << endl - << " if (!(mxIsDouble(T_mx) && !mxIsComplex(T_mx) && !mxIsSparse(T_mx) && mxGetN(T_mx) == 1))" << endl - << R"( mexErrMsgTxt("T_mx should be a real dense column vector");)" << endl - << " T_order_on_input = mxGetScalar(T_order_mx);" << endl - << " if (T_order_on_input < " << i << ")" << endl - << " {" << endl - << " T_order_mx = mxCreateDoubleScalar(" << i << ");" << endl - << " const mxArray *T_old_mx = T_mx;" << endl - << " T_mx = mxCreateDoubleMatrix(max(" << ttlen << ", mxGetM(T_old_mx)), 1, mxREAL);" << endl - << " memcpy(mxGetPr(T_mx), mxGetPr(T_old_mx), mxGetM(T_old_mx)*sizeof(double));" << endl - << " }" << endl - << " else if (mxGetM(T_mx) < " << ttlen << ")" << endl - << R"( mexErrMsgTxt("T_mx should have at least )" << ttlen << R"( elements");)" << endl - << " }" << endl - << " else" << endl - << " {" << endl - << " T_order_mx = mxCreateDoubleScalar(" << i << ");" << endl - << " T_mx = mxCreateDoubleMatrix(" << ttlen << ", 1, mxREAL);" << endl - << " T_order_on_input = -1;" << endl - << " }" << endl - << " double *restrict T = mxGetPr(T_mx);" << endl - << " if (T_order_on_input < " << i << ")" << endl - << " switch (T_order_on_input)" << endl - << " {" << endl; + output + << " mxArray *T_mx, *T_order_mx;" << endl + << " int T_order_on_input;" << endl + << " if (nrhs > " << nargin - 2 << ")" << endl + << " {" << endl + << " T_order_mx = (mxArray *) prhs[" << nargin - 2 << "];" << endl + << " T_mx = (mxArray *) prhs[" << nargin - 1 << "];" << endl + << " if (!(mxIsScalar(T_order_mx) && mxIsNumeric(T_order_mx)))" << endl + << R"( mexErrMsgTxt("T_order should be a numeric scalar");)" << endl + << " if (!(mxIsDouble(T_mx) && !mxIsComplex(T_mx) && !mxIsSparse(T_mx) && " + "mxGetN(T_mx) == 1))" + << endl + << R"( mexErrMsgTxt("T_mx should be a real dense column vector");)" << endl + << " T_order_on_input = mxGetScalar(T_order_mx);" << endl + << " if (T_order_on_input < " << i << ")" << endl + << " {" << endl + << " T_order_mx = mxCreateDoubleScalar(" << i << ");" << endl + << " const mxArray *T_old_mx = T_mx;" << endl + << " T_mx = mxCreateDoubleMatrix(max(" << ttlen + << ", mxGetM(T_old_mx)), 1, mxREAL);" << endl + << " memcpy(mxGetPr(T_mx), mxGetPr(T_old_mx), mxGetM(T_old_mx)*sizeof(double));" + << endl + << " }" << endl + << " else if (mxGetM(T_mx) < " << ttlen << ")" << endl + << R"( mexErrMsgTxt("T_mx should have at least )" << ttlen << R"( elements");)" + << endl + << " }" << endl + << " else" << endl + << " {" << endl + << " T_order_mx = mxCreateDoubleScalar(" << i << ");" << endl + << " T_mx = mxCreateDoubleMatrix(" << ttlen << ", 1, mxREAL);" << endl + << " T_order_on_input = -1;" << endl + << " }" << endl + << " double *restrict T = mxGetPr(T_mx);" << endl + << " if (T_order_on_input < " << i << ")" << endl + << " switch (T_order_on_input)" << endl + << " {" << endl; for (int j {0}; j <= i; j++) { if (j == 0) - output << " default:" << endl - << " " << prefix << "resid"; + output << " default:" << endl << " " << prefix << "resid"; else - output << " case " << j-1 << ":" << endl - << " " << prefix << "g" << j; + output << " case " << j - 1 << ":" << endl << " " << prefix << "g" << j; output << "_tt(y, x, params" << ss_argout << ", T);" << endl; } output << " }" << endl; if (i == 1) - sparse_jacobian_create(0, equations.size(), getJacobianColsNbr(true), jacobian_sparse_column_major_order.size()); + sparse_jacobian_create(0, equations.size(), getJacobianColsNbr(true), + jacobian_sparse_column_major_order.size()); else - output << " plhs[0] = mxCreateDoubleMatrix(" << (i == 0 ? equations.size() : derivatives[i].size()) << ", 1, mxREAL);" << endl; - output << " " << prefix << (i == 0 ? "resid" : "g" + to_string(i)) << "(y, x, params" << ss_argout << ", T, mxGetPr(plhs[0]));" << endl + output << " plhs[0] = mxCreateDoubleMatrix(" + << (i == 0 ? equations.size() : derivatives[i].size()) << ", 1, mxREAL);" << endl; + output << " " << prefix << (i == 0 ? "resid" : "g" + to_string(i)) << "(y, x, params" + << ss_argout << ", T, mxGetPr(plhs[0]));" << endl << " if (nlhs == 3)" << endl << " {" << endl << " plhs[1] = T_order_mx;" << endl @@ -2812,7 +2922,7 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext, << "}" << endl; output.close(); - vector mex_input_files { main_object_file, source_mex }; + vector mex_input_files {main_object_file, source_mex}; for (int j {0}; j <= i; j++) mex_input_files.push_back(tt_object_files[j]); compileMEX(mex_dir, funcname, mexext, mex_input_files, matlabroot); @@ -2825,9 +2935,9 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext, size_t total_blk_ttlen {0}; // Temporary terms of all blocks up to the present one for (int blk {0}; blk < static_cast(blocks.size()); blk++) { - const string funcname {prefix + to_string(blk+1)}; + const string funcname {prefix + to_string(blk + 1)}; const filesystem::path source_mex {model_src_dir / "block" / (funcname + ".c")}; - int nargin {7+static_cast(dynamic)}; + int nargin {7 + static_cast(dynamic)}; const BlockSimulationType simulation_type {blocks[blk].simulation_type}; const bool evaluate {simulation_type == BlockSimulationType::evaluateForward || simulation_type == BlockSimulationType::evaluateBackward}; @@ -2836,21 +2946,21 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext, || simulation_type == BlockSimulationType::solveBackwardComplete || simulation_type == BlockSimulationType::solveForwardComplete}; // The following two variables are not used for “evaluate” blocks - int g1_ncols {(one_boundary ? 1 : 3)*blocks[blk].mfs_size}; + int g1_ncols {(one_boundary ? 1 : 3) * blocks[blk].mfs_size}; open_file(source_mex); - output << "#include " << endl - << R"(#include "mex.h")" << endl - << endl; + output << "#include " << endl << R"(#include "mex.h")" << endl << endl; writeCHelpersDefinition(output); writeCHelpersDeclaration(output); // Provide external definition of helpers output << endl - << "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl + << "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" + << endl << "{" << endl << " if (nrhs != " << nargin << ")" << endl - << R"( mexErrMsgTxt("Accepts exactly )" << nargin << R"( input arguments");)" << endl; + << R"( mexErrMsgTxt("Accepts exactly )" << nargin << R"( input arguments");)" + << endl; if (evaluate) output << " if (nlhs != 2)" << endl - << R"( mexErrMsgTxt("Accepts exactly 2 output arguments");)" << endl; + << R"( mexErrMsgTxt("Accepts exactly 2 output arguments");)" << endl; else /* Only two output arguments make sense if one only wants to evaluate the recursive variables. */ @@ -2867,26 +2977,34 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext, Octave and older MATLAB (and also C++ does not have the “restrict” qualifier, so it may not be a net gain). See: https://fr.mathworks.com/matlabcentral/answers/77048-return-large-unchange-mxarray-from-mex - https://fr.mathworks.com/matlabcentral/answers/422751-how-to-output-a-mexfunction-input-without-copy */ + https://fr.mathworks.com/matlabcentral/answers/422751-how-to-output-a-mexfunction-input-without-copy + */ output << " plhs[0] = mxDuplicateArray(prhs[0]);" << endl << " double *restrict y = mxGetPr(plhs[0]);" << endl; - // NB: For “evaluate” blocks, sparse_{rowval,colval,colptr} arguments are present but ignored + // NB: For “evaluate” blocks, sparse_{rowval,colval,colptr} arguments are present but + // ignored if (!evaluate) sparse_indices_inputs(g1_ncols, blocks_jacobian_sparse_column_major_order[blk].size()); - for (const auto &it : blocks_temporary_terms[blk]) + for (const auto& it : blocks_temporary_terms[blk]) total_blk_ttlen += it.size(); - output << " if (!(mxIsDouble(prhs[" << nargin-1 << "]) && !mxIsComplex(prhs[" << nargin-1 << "]) && !mxIsSparse(prhs[" << nargin-1 << "]) && mxGetNumberOfElements(prhs[" << nargin-1 << "]) >= " << total_blk_ttlen << "))" << endl - << R"( mexErrMsgTxt("T must be a real dense numeric array with at least )" << total_blk_ttlen << R"( elements");)" << endl - /* We’d like to avoid copying T when the block has no temporary - terms, but the same remark as above applies. */ - << " plhs[1] = mxDuplicateArray(prhs[" << nargin-1 <<"]);" << endl + output << " if (!(mxIsDouble(prhs[" << nargin - 1 << "]) && !mxIsComplex(prhs[" + << nargin - 1 << "]) && !mxIsSparse(prhs[" << nargin - 1 + << "]) && mxGetNumberOfElements(prhs[" << nargin - 1 << "]) >= " << total_blk_ttlen + << "))" << endl + << R"( mexErrMsgTxt("T must be a real dense numeric array with at least )" + << total_blk_ttlen << R"( elements");)" + << endl + /* We’d like to avoid copying T when the block has no temporary + terms, but the same remark as above applies. */ + << " plhs[1] = mxDuplicateArray(prhs[" << nargin - 1 << "]);" << endl << " double *restrict T = mxGetPr(plhs[1]);" << endl; if (!evaluate) - output << " mxArray *residual_mx = mxCreateDoubleMatrix(" << blocks[blk].mfs_size << ", 1, mxREAL);" << endl + output << " mxArray *residual_mx = mxCreateDoubleMatrix(" << blocks[blk].mfs_size + << ", 1, mxREAL);" << endl << " double *restrict residual = mxGetPr(residual_mx);" << endl << " if (nlhs > 2)" << endl << " plhs[2] = residual_mx;" << endl; @@ -2897,30 +3015,31 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext, if (!evaluate) { // Write Jacobian - output << " if (nlhs > 3)" << endl - << " {" << endl; - sparse_jacobian_create(3, blocks[blk].mfs_size, g1_ncols, blocks_jacobian_sparse_column_major_order[blk].size()); + output << " if (nlhs > 3)" << endl << " {" << endl; + sparse_jacobian_create(3, blocks[blk].mfs_size, g1_ncols, + blocks_jacobian_sparse_column_major_order[blk].size()); output << " double *restrict g1_v = mxGetPr(plhs[3]);" << endl; writeSparsePerBlockJacobianHelper(blk, output, temporary_terms_written); output << " }" << endl; } output << "}" << endl; output.close(); - compileMEX(block_dir, funcname, mexext, { source_mex }, matlabroot); + compileMEX(block_dir, funcname, mexext, {source_mex}, matlabroot); } } } template void -ModelTree::writeDebugModelMFiles(const string &basename) const +ModelTree::writeDebugModelMFiles(const string& basename) const { - constexpr ExprNodeOutputType output_type {dynamic ? ExprNodeOutputType::matlabSparseDynamicModel : ExprNodeOutputType::matlabSparseStaticModel}; + constexpr ExprNodeOutputType output_type {dynamic ? ExprNodeOutputType::matlabSparseDynamicModel + : ExprNodeOutputType::matlabSparseStaticModel}; const filesystem::path m_dir {packageDir(basename) / "+debug"}; // TODO: when C++20 support is complete, mark the following strings constexpr - const string prefix { dynamic ? "dynamic_" : "static_" }; - const string ss_arg { dynamic ? ", steady_state" : "" }; + const string prefix {dynamic ? "dynamic_" : "static_"}; + const string ss_arg {dynamic ? ", steady_state" : ""}; const filesystem::path resid_filename {m_dir / (prefix + "resid.m")}; ofstream output {resid_filename, ios::out | ios::binary}; @@ -2941,13 +3060,13 @@ ModelTree::writeDebugModelMFiles(const string &basename) const for (size_t eq {0}; eq < equations.size(); eq++) { output << "lhs" << LEFT_ARRAY_SUBSCRIPT(output_type) - << eq + ARRAY_SUBSCRIPT_OFFSET(output_type) - << RIGHT_ARRAY_SUBSCRIPT(output_type) << " = "; + << eq + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type) + << " = "; equations[eq]->arg1->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs); output << ";" << endl << "rhs" << LEFT_ARRAY_SUBSCRIPT(output_type) - << eq + ARRAY_SUBSCRIPT_OFFSET(output_type) - << RIGHT_ARRAY_SUBSCRIPT(output_type) << " = "; + << eq + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type) + << " = "; equations[eq]->arg2->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs); output << ";" << endl; } @@ -2959,10 +3078,12 @@ ModelTree::writeDebugModelMFiles(const string &basename) const template void -ModelTree::writeSetAuxiliaryVariablesFile(const string &basename, bool julia) const +ModelTree::writeSetAuxiliaryVariablesFile(const string& basename, bool julia) const { - const auto output_type { julia ? (dynamic ? ExprNodeOutputType::juliaTimeDataFrame : ExprNodeOutputType::juliaStaticModel) - : (dynamic ? ExprNodeOutputType::matlabDseries : ExprNodeOutputType::matlabStaticModel) }; + const auto output_type {julia ? (dynamic ? ExprNodeOutputType::juliaTimeDataFrame + : ExprNodeOutputType::juliaStaticModel) + : (dynamic ? ExprNodeOutputType::matlabDseries + : ExprNodeOutputType::matlabStaticModel)}; ostringstream output_func_body; writeAuxVarRecursiveDefinitions(output_func_body, output_type); @@ -2970,7 +3091,7 @@ ModelTree::writeSetAuxiliaryVariablesFile(const string &basename, bool julia) co if (output_func_body.str().empty()) return; - string func_name { dynamic ? "dynamic_set_auxiliary_series" : "set_auxiliary_variables" }; + string func_name {dynamic ? "dynamic_set_auxiliary_series" : "set_auxiliary_variables"}; if (julia) func_name.push_back('!'); const char comment {julia ? '#' : '%'}; @@ -2979,13 +3100,13 @@ ModelTree::writeSetAuxiliaryVariablesFile(const string &basename, bool julia) co output << "function "; if (!julia) { - if constexpr(dynamic) + if constexpr (dynamic) output << "ds = "; else output << "y = "; } output << func_name + "("; - if constexpr(dynamic) + if constexpr (dynamic) output << "ds"; else output << "y, x"; @@ -2995,19 +3116,20 @@ ModelTree::writeSetAuxiliaryVariablesFile(const string &basename, bool julia) co << comment << endl; if (julia) output << "@inbounds begin" << endl; - output << output_func_body.str() - << "end" << endl; + output << output_func_body.str() << "end" << endl; if (julia) output << "end" << endl; if (julia) - writeToFileIfModified(output, filesystem::path{basename} / "model" / "julia" / (dynamic ? "DynamicSetAuxiliarySeries.jl" : "SetAuxiliaryVariables.jl")); + writeToFileIfModified( + output, filesystem::path {basename} / "model" / "julia" + / (dynamic ? "DynamicSetAuxiliarySeries.jl" : "SetAuxiliaryVariables.jl")); else { /* Calling writeToFileIfModified() is useless here since we write inside a subdirectory deleted at each preprocessor run. */ filesystem::path filename {packageDir(basename) / (func_name + ".m")}; - ofstream output_file{filename, ios::out | ios::binary}; + ofstream output_file {filename, ios::out | ios::binary}; if (!output_file.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; diff --git a/src/NumericalConstants.cc b/src/NumericalConstants.cc index 04251eb4..3cfee6de 100644 --- a/src/NumericalConstants.cc +++ b/src/NumericalConstants.cc @@ -17,17 +17,16 @@ * along with Dynare. If not, see . */ -#include #include #include +#include #include "NumericalConstants.hh" int -NumericalConstants::AddNonNegativeConstant(const string &iConst) +NumericalConstants::AddNonNegativeConstant(const string& iConst) { - if (auto iter = numConstantsIndex.find(iConst); - iter != numConstantsIndex.end()) + if (auto iter = numConstantsIndex.find(iConst); iter != numConstantsIndex.end()) return iter->second; auto id = static_cast(mNumericalConstants.size()); diff --git a/src/NumericalConstants.hh b/src/NumericalConstants.hh index f8355011..ba20587f 100644 --- a/src/NumericalConstants.hh +++ b/src/NumericalConstants.hh @@ -20,9 +20,9 @@ #ifndef _NUMERICALCONSTANTS_HH #define _NUMERICALCONSTANTS_HH +#include #include #include -#include using namespace std; @@ -36,9 +36,10 @@ private: vector double_vals; //! Map matching constants to their id map numConstantsIndex; + public: //! Adds a non-negative constant (possibly Inf or NaN) and returns its ID - int AddNonNegativeConstant(const string &iConst); + int AddNonNegativeConstant(const string& iConst); //! Get a constant in string form string get(int ID) const; //! Get a constant in double form diff --git a/src/NumericalInitialization.cc b/src/NumericalInitialization.cc index 84f48893..74a86199 100644 --- a/src/NumericalInitialization.cc +++ b/src/NumericalInitialization.cc @@ -17,36 +17,36 @@ * along with Dynare. If not, see . */ -#include -#include -#include #include +#include +#include +#include #include #include "NumericalInitialization.hh" -InitParamStatement::InitParamStatement(int symb_id_arg, - const expr_t param_value_arg, - const SymbolTable &symbol_table_arg) : - symb_id{symb_id_arg}, - param_value{param_value_arg}, - symbol_table{symbol_table_arg} +InitParamStatement::InitParamStatement(int symb_id_arg, const expr_t param_value_arg, + const SymbolTable& symbol_table_arg) : + symb_id {symb_id_arg}, param_value {param_value_arg}, symbol_table {symbol_table_arg} { } void -InitParamStatement::checkPass(ModFileStructure &mod_file_struct, [[maybe_unused]] WarningConsolidation &warnings) +InitParamStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { if (symbol_table.getName(symb_id) == "dsge_prior_weight") mod_file_struct.dsge_prior_weight_initialized = true; // Needed for the workaround discussed in dynare#1173 if (symbol_table.getName(symb_id) == "optimal_policy_discount_factor") - param_value->collectVariables(SymbolType::parameter, mod_file_struct.parameters_in_planner_discount); + param_value->collectVariables(SymbolType::parameter, + mod_file_struct.parameters_in_planner_discount); } void -InitParamStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, bool minimal_workspace) const +InitParamStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, + bool minimal_workspace) const { int id = symbol_table.getTypeSpecificID(symb_id) + 1; output << "M_.params(" << id << ") = "; @@ -57,44 +57,46 @@ InitParamStatement::writeOutput(ostream &output, [[maybe_unused]] const string & } void -InitParamStatement::writeJsonOutput(ostream &output) const +InitParamStatement::writeJsonOutput(ostream& output) const { - output << R"({"statementName": "param_init", "name": ")" << symbol_table.getName(symb_id) << R"(", )" << R"("value": ")"; + output << R"({"statementName": "param_init", "name": ")" << symbol_table.getName(symb_id) + << R"(", )" + << R"("value": ")"; param_value->writeJsonOutput(output, {}, {}); output << R"("})"; } void -InitParamStatement::fillEvalContext(eval_context_t &eval_context) const +InitParamStatement::fillEvalContext(eval_context_t& eval_context) const { try { eval_context[symb_id] = param_value->eval(eval_context); } - catch (ExprNode::EvalException &e) + catch (ExprNode::EvalException& e) { // Do nothing } } InitOrEndValStatement::InitOrEndValStatement(init_values_t init_values_arg, - const SymbolTable &symbol_table_arg, + const SymbolTable& symbol_table_arg, bool all_values_required_arg) : - init_values{move(init_values_arg)}, - symbol_table{symbol_table_arg}, - all_values_required{all_values_required_arg} + init_values {move(init_values_arg)}, + symbol_table {symbol_table_arg}, + all_values_required {all_values_required_arg} { } void -InitOrEndValStatement::fillEvalContext(eval_context_t &eval_context) const +InitOrEndValStatement::fillEvalContext(eval_context_t& eval_context) const { for (auto [symb_id, value] : init_values) try { eval_context[symb_id] = value->eval(eval_context); } - catch (ExprNode::EvalException &e) + catch (ExprNode::EvalException& e) { // Do nothing } @@ -124,7 +126,7 @@ InitOrEndValStatement::getUninitializedVariables(SymbolType type) } void -InitOrEndValStatement::writeInitValues(ostream &output) const +InitOrEndValStatement::writeInitValues(ostream& output) const { for (auto [symb_id, value] : init_values) { @@ -161,31 +163,31 @@ InitOrEndValStatement::writeInitValues(ostream &output) const } void -InitOrEndValStatement::writeJsonInitValues(ostream &output) const +InitOrEndValStatement::writeJsonInitValues(ostream& output) const { - for (bool printed_something{false}; - auto &[symb_id, value] : init_values) + for (bool printed_something {false}; auto& [symb_id, value] : init_values) { if (symbol_table.getType(symb_id) == SymbolType::unusedEndogenous) // See #82 continue; if (exchange(printed_something, true)) output << ", "; - output << R"({"name": ")" << symbol_table.getName(symb_id) << R"(", )" << R"("value": ")"; + output << R"({"name": ")" << symbol_table.getName(symb_id) << R"(", )" + << R"("value": ")"; value->writeJsonOutput(output, {}, {}); output << R"("})"; } } InitValStatement::InitValStatement(init_values_t init_values_arg, - const SymbolTable &symbol_table_arg, + const SymbolTable& symbol_table_arg, bool all_values_required_arg) : - InitOrEndValStatement{move(init_values_arg), symbol_table_arg, all_values_required_arg} + InitOrEndValStatement {move(init_values_arg), symbol_table_arg, all_values_required_arg} { } void -InitValStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +InitValStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { if (mod_file_struct.endval_present) { @@ -217,12 +219,10 @@ InitValStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, } void -InitValStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +InitValStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { - output << "%" << endl - << "% INITVAL instructions" << endl - << "%" << endl; + output << "%" << endl << "% INITVAL instructions" << endl << "%" << endl; // Writing initval block to set initial values for variables output << "options_.initval_file = false;" << endl; @@ -230,7 +230,7 @@ InitValStatement::writeOutput(ostream &output, [[maybe_unused]] const string &ba } void -InitValStatement::writeJsonOutput(ostream &output) const +InitValStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "initval", "vals": [)"; writeJsonInitValues(output); @@ -238,26 +238,25 @@ InitValStatement::writeJsonOutput(ostream &output) const } void -InitValStatement::writeOutputPostInit(ostream &output) const +InitValStatement::writeOutputPostInit(ostream& output) const { output << "if M_.exo_nbr > 0" << endl << "\too_.exo_simul = ones(M_.maximum_lag,1)*oo_.exo_steady_state';" << endl - <<"end" << endl + << "end" << endl << "if M_.exo_det_nbr > 0" << endl << "\too_.exo_det_simul = ones(M_.maximum_lag,1)*oo_.exo_det_steady_state';" << endl - <<"end" << endl; + << "end" << endl; } -EndValStatement::EndValStatement(init_values_t init_values_arg, - const SymbolTable &symbol_table_arg, +EndValStatement::EndValStatement(init_values_t init_values_arg, const SymbolTable& symbol_table_arg, bool all_values_required_arg) : - InitOrEndValStatement{move(init_values_arg), symbol_table_arg, all_values_required_arg} + InitOrEndValStatement {move(init_values_arg), symbol_table_arg, all_values_required_arg} { } void -EndValStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +EndValStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.endval_present = true; @@ -285,12 +284,10 @@ EndValStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, } void -EndValStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +EndValStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { - output << "%" << endl - << "% ENDVAL instructions" << endl - << "%" << endl; + output << "%" << endl << "% ENDVAL instructions" << endl << "%" << endl; // Writing endval block to set terminal values for variables output << "oo_.initial_steady_state = oo_.steady_state;" << endl << "oo_.initial_exo_steady_state = oo_.exo_steady_state;" << endl; @@ -299,7 +296,7 @@ EndValStatement::writeOutput(ostream &output, [[maybe_unused]] const string &bas } void -EndValStatement::writeJsonOutput(ostream &output) const +EndValStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "endval", "vals": [)"; writeJsonInitValues(output); @@ -308,16 +305,16 @@ EndValStatement::writeJsonOutput(ostream &output) const EndValLearntInStatement::EndValLearntInStatement(int learnt_in_period_arg, learnt_end_values_t learnt_end_values_arg, - const SymbolTable &symbol_table_arg) : - learnt_in_period{learnt_in_period_arg}, - learnt_end_values{move(learnt_end_values_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + learnt_in_period {learnt_in_period_arg}, + learnt_end_values {move(learnt_end_values_arg)}, + symbol_table {symbol_table_arg} { } void -EndValLearntInStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +EndValLearntInStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.endval_learnt_in_present = true; } @@ -338,7 +335,7 @@ EndValLearntInStatement::typeToString(LearntEndValType type) } void -EndValLearntInStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +EndValLearntInStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "M_.learnt_endval = [ M_.learnt_endval;" << endl; @@ -346,9 +343,9 @@ EndValLearntInStatement::writeOutput(ostream &output, [[maybe_unused]] const str { if (symbol_table.getType(symb_id) == SymbolType::unusedEndogenous) // See #82 continue; - output << "struct('learnt_in'," << learnt_in_period - << ",'exo_id'," << symbol_table.getTypeSpecificID(symb_id)+1 - << ",'type','" << typeToString(type) << "'" + output << "struct('learnt_in'," << learnt_in_period << ",'exo_id'," + << symbol_table.getTypeSpecificID(symb_id) + 1 << ",'type','" << typeToString(type) + << "'" << ",'value',"; value->writeOutput(output); output << ");" << endl; @@ -357,12 +354,10 @@ EndValLearntInStatement::writeOutput(ostream &output, [[maybe_unused]] const str } void -EndValLearntInStatement::writeJsonOutput(ostream &output) const +EndValLearntInStatement::writeJsonOutput(ostream& output) const { - output << R"({"statementName": "endval", "learnt_in": )" - << learnt_in_period << R"(, "vals": [)"; - for (bool printed_something{false}; - auto &[type, symb_id, value] : learnt_end_values) + output << R"({"statementName": "endval", "learnt_in": )" << learnt_in_period << R"(, "vals": [)"; + for (bool printed_something {false}; auto& [type, symb_id, value] : learnt_end_values) { if (symbol_table.getType(symb_id) == SymbolType::unusedEndogenous) // See #82 continue; @@ -378,24 +373,24 @@ EndValLearntInStatement::writeJsonOutput(ostream &output) const } HistValStatement::HistValStatement(hist_values_t hist_values_arg, - const SymbolTable &symbol_table_arg, + const SymbolTable& symbol_table_arg, bool all_values_required_arg) : - hist_values{move(hist_values_arg)}, - symbol_table{symbol_table_arg}, - all_values_required{all_values_required_arg} + hist_values {move(hist_values_arg)}, + symbol_table {symbol_table_arg}, + all_values_required {all_values_required_arg} { } void -HistValStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +HistValStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { if (all_values_required) { set unused_endo = symbol_table.getEndogenous(); set unused_exo = symbol_table.getExogenous(); - for (const auto &[key, value] : hist_values) + for (const auto& [key, value] : hist_values) { int symb_id = key.first; unused_endo.erase(symb_id); @@ -424,60 +419,71 @@ HistValStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, } void -HistValStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +HistValStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "%" << endl << "% HISTVAL instructions" << endl << "%" << endl - << "M_.histval_dseries = dseries(zeros(M_.orig_maximum_lag_with_diffs_expanded, M_.orig_endo_nbr" + << "M_.histval_dseries = dseries(zeros(M_.orig_maximum_lag_with_diffs_expanded, " + "M_.orig_endo_nbr" << (symbol_table.AuxVarsSize() > 0 ? "+sum([M_.aux_vars.type]==6)" : "") << (symbol_table.exo_nbr() > 0 ? "+M_.exo_nbr" : "") << (symbol_table.exo_det_nbr() > 0 ? "+M_.exo_det_nbr" : "") - << "), dates(sprintf('%dY', -M_.orig_maximum_lag_with_diffs_expanded+1)), [ M_.endo_names(1:M_.orig_endo_nbr); " - << (symbol_table.AuxVarsSize() > 0 ? "M_.endo_names([M_.aux_vars(find([M_.aux_vars.type]==6)).endo_index]); " : "") + << "), dates(sprintf('%dY', -M_.orig_maximum_lag_with_diffs_expanded+1)), [ " + "M_.endo_names(1:M_.orig_endo_nbr); " + << (symbol_table.AuxVarsSize() > 0 + ? "M_.endo_names([M_.aux_vars(find([M_.aux_vars.type]==6)).endo_index]); " + : "") << (symbol_table.exo_nbr() > 0 ? "M_.exo_names; " : "") - << (symbol_table.exo_det_nbr() > 0 ? "M_.exo_det_names; " : "") - << "]);" << endl; + << (symbol_table.exo_det_nbr() > 0 ? "M_.exo_det_names; " : "") << "]);" << endl; - for (const auto &[key, value] : hist_values) + for (const auto& [key, value] : hist_values) { auto [symb_id, lag] = key; if (symbol_table.getType(symb_id) == SymbolType::unusedEndogenous) // See #82 continue; - output << "M_.histval_dseries{'" << symbol_table.getName(symb_id) << "'}(dates('" << lag << "Y'))="; + output << "M_.histval_dseries{'" << symbol_table.getName(symb_id) << "'}(dates('" << lag + << "Y'))="; value->writeOutput(output); output << ";" << endl; } output << "if exist(['+' M_.fname '/dynamic_set_auxiliary_series.m'])" << endl - << " eval(['M_.histval_dseries = ' M_.fname '.dynamic_set_auxiliary_series(M_.histval_dseries, M_.params);']);" << endl + << " eval(['M_.histval_dseries = ' M_.fname " + "'.dynamic_set_auxiliary_series(M_.histval_dseries, M_.params);']);" + << endl << "end" << endl - << "M_.endo_histval = M_.histval_dseries{M_.endo_names{:}}(dates(sprintf('%dY', 1-M_.maximum_lag)):dates('0Y')).data';" << endl - << "M_.endo_histval(isnan(M_.endo_histval)) = 0;" << endl; // Ensure that lead aux variables do not have a NaN + << "M_.endo_histval = M_.histval_dseries{M_.endo_names{:}}(dates(sprintf('%dY', " + "1-M_.maximum_lag)):dates('0Y')).data';" + << endl + << "M_.endo_histval(isnan(M_.endo_histval)) = 0;" + << endl; // Ensure that lead aux variables do not have a NaN if (symbol_table.exo_nbr() > 0) - output << "M_.exo_histval = M_.histval_dseries{M_.exo_names{:}}(dates(sprintf('%dY', 1-M_.maximum_lag)):dates('0Y')).data';" << endl; + output << "M_.exo_histval = M_.histval_dseries{M_.exo_names{:}}(dates(sprintf('%dY', " + "1-M_.maximum_lag)):dates('0Y')).data';" + << endl; if (symbol_table.exo_det_nbr() > 0) - output << "M_.exo_det_histval = M_.histval_dseries{M_.exo_det_names{:}}(dates(sprintf('%dY', 1-M_.maximum_lag)):dates('0Y')).data';" << endl; + output << "M_.exo_det_histval = M_.histval_dseries{M_.exo_det_names{:}}(dates(sprintf('%dY', " + "1-M_.maximum_lag)):dates('0Y')).data';" + << endl; } void -HistValStatement::writeJsonOutput(ostream &output) const +HistValStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "histval", "vals": [)"; - for (bool printed_something{false}; - const auto &[key, value] : hist_values) + for (bool printed_something {false}; const auto& [key, value] : hist_values) { - auto &[symb_id, lag] = key; + auto& [symb_id, lag] = key; if (symbol_table.getType(symb_id) == SymbolType::unusedEndogenous) // See #82 continue; if (exchange(printed_something, true)) output << ", "; output << R"({ "name": ")" << symbol_table.getName(symb_id) << R"(")" - << R"(, "lag": )" << lag - << R"(, "value": ")"; + << R"(, "lag": )" << lag << R"(, "value": ")"; value->writeJsonOutput(output, {}, {}); output << R"("})"; } @@ -485,12 +491,12 @@ HistValStatement::writeJsonOutput(ostream &output) const } InitvalFileStatement::InitvalFileStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -InitvalFileStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +InitvalFileStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "%" << endl @@ -498,11 +504,13 @@ InitvalFileStatement::writeOutput(ostream &output, [[maybe_unused]] const string << "%" << endl << "options_.initval_file = true;" << endl; options_list.writeOutput(output, "options_initvalf"); - output << "[oo_.initval_series, options_.periods] = histvalf_initvalf('INITVALF', M_, options_initvalf);" << endl; + output << "[oo_.initval_series, options_.periods] = histvalf_initvalf('INITVALF', M_, " + "options_initvalf);" + << endl; } void -InitvalFileStatement::writeJsonOutput(ostream &output) const +InitvalFileStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "initval_file")"; if (!options_list.empty()) @@ -514,12 +522,12 @@ InitvalFileStatement::writeJsonOutput(ostream &output) const } HistvalFileStatement::HistvalFileStatement(OptionsList options_list_arg) : - options_list{move(options_list_arg)} + options_list {move(options_list_arg)} { } void -HistvalFileStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +HistvalFileStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "%" << endl @@ -527,11 +535,13 @@ HistvalFileStatement::writeOutput(ostream &output, [[maybe_unused]] const string << "%" << endl << "options_.histval_file = true;" << endl; options_list.writeOutput(output, "options_histvalf"); - output << "[M_.endo_histval, M_.exo_histval, M_.exo_det_histval] = histvalf(M_, options_histvalf);" << endl; + output + << "[M_.endo_histval, M_.exo_histval, M_.exo_det_histval] = histvalf(M_, options_histvalf);" + << endl; } void -HistvalFileStatement::writeJsonOutput(ostream &output) const +HistvalFileStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "histval_file")"; if (!options_list.empty()) @@ -544,21 +554,22 @@ HistvalFileStatement::writeJsonOutput(ostream &output) const HomotopySetupStatement::HomotopySetupStatement(bool from_initval_to_endval_arg, homotopy_values_t homotopy_values_arg, - const SymbolTable &symbol_table_arg) : - from_initval_to_endval{from_initval_to_endval_arg}, - homotopy_values{move(homotopy_values_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + from_initval_to_endval {from_initval_to_endval_arg}, + homotopy_values {move(homotopy_values_arg)}, + symbol_table {symbol_table_arg} { } void -HomotopySetupStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +HomotopySetupStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "%" << endl << "% HOMOTOPY_SETUP instructions" << endl << "%" << endl - << "options_.homotopy_from_initval_to_endval = " << boolalpha << from_initval_to_endval << ';' << endl + << "options_.homotopy_from_initval_to_endval = " << boolalpha << from_initval_to_endval + << ';' << endl << "options_.homotopy_values = zeros(0, 4);" << endl; for (auto [symb_id, expression1, expression2] : homotopy_values) @@ -566,7 +577,8 @@ HomotopySetupStatement::writeOutput(ostream &output, [[maybe_unused]] const stri const SymbolType type = symbol_table.getType(symb_id); const int tsid = symbol_table.getTypeSpecificID(symb_id) + 1; - output << "options_.homotopy_values = vertcat(options_.homotopy_values, [ " << static_cast(type) << ", " << tsid << ", "; + output << "options_.homotopy_values = vertcat(options_.homotopy_values, [ " + << static_cast(type) << ", " << tsid << ", "; if (expression1) expression1->writeOutput(output); else @@ -578,12 +590,12 @@ HomotopySetupStatement::writeOutput(ostream &output, [[maybe_unused]] const stri } void -HomotopySetupStatement::writeJsonOutput(ostream &output) const +HomotopySetupStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "homotopy", )" << R"("values": [)"; - for (bool printed_something{false}; - const auto &[symb_id, expression1, expression2] : homotopy_values) + for (bool printed_something {false}; + const auto& [symb_id, expression1, expression2] : homotopy_values) { if (exchange(printed_something, true)) output << ", "; @@ -603,29 +615,30 @@ HomotopySetupStatement::writeJsonOutput(ostream &output) const } SaveParamsAndSteadyStateStatement::SaveParamsAndSteadyStateStatement(string filename_arg) : - filename{move(filename_arg)} + filename {move(filename_arg)} { } void -SaveParamsAndSteadyStateStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +SaveParamsAndSteadyStateStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "save_params_and_steady_state('" << filename << "');" << endl; } void -SaveParamsAndSteadyStateStatement::writeJsonOutput(ostream &output) const +SaveParamsAndSteadyStateStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "save_params_and_steady_state")" << R"(, "filename": ")" << filename << R"(")" << "}"; } -LoadParamsAndSteadyStateStatement::LoadParamsAndSteadyStateStatement(const filesystem::path &filename, - const SymbolTable &symbol_table_arg, - WarningConsolidation &warnings) : - symbol_table{symbol_table_arg} +LoadParamsAndSteadyStateStatement::LoadParamsAndSteadyStateStatement( + const filesystem::path& filename, const SymbolTable& symbol_table_arg, + WarningConsolidation& warnings) : + symbol_table {symbol_table_arg} { cout << "Reading " << filename.string() << "." << endl; @@ -649,19 +662,21 @@ LoadParamsAndSteadyStateStatement::LoadParamsAndSteadyStateStatement(const files int symb_id = symbol_table.getID(symb_name); content[symb_id] = value; } - catch (SymbolTable::UnknownSymbolNameException &e) + catch (SymbolTable::UnknownSymbolNameException& e) { - warnings << "WARNING: Unknown symbol " << symb_name << " in " << filename.string() << endl; + warnings << "WARNING: Unknown symbol " << symb_name << " in " << filename.string() + << endl; } } f.close(); } void -LoadParamsAndSteadyStateStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +LoadParamsAndSteadyStateStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { - for (const auto &[id, value] : content) + for (const auto& [id, value] : content) { switch (symbol_table.getType(id)) { @@ -678,7 +693,8 @@ LoadParamsAndSteadyStateStatement::writeOutput(ostream &output, [[maybe_unused]] output << "oo_.exo_det_steady_state"; break; default: - cerr << "ERROR: Unsupported variable type for " << symbol_table.getName(id) << " in load_params_and_steady_state" << endl; + cerr << "ERROR: Unsupported variable type for " << symbol_table.getName(id) + << " in load_params_and_steady_state" << endl; exit(EXIT_FAILURE); } @@ -688,12 +704,11 @@ LoadParamsAndSteadyStateStatement::writeOutput(ostream &output, [[maybe_unused]] } void -LoadParamsAndSteadyStateStatement::writeJsonOutput(ostream &output) const +LoadParamsAndSteadyStateStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "load_params_and_steady_state",)" << R"("values": [)"; - for (bool printed_something{false}; - const auto &[id, value] : content) + for (bool printed_something {false}; const auto& [id, value] : content) { if (exchange(printed_something, true)) output << ", "; @@ -705,9 +720,9 @@ LoadParamsAndSteadyStateStatement::writeJsonOutput(ostream &output) const } void -LoadParamsAndSteadyStateStatement::fillEvalContext(eval_context_t &eval_context) const +LoadParamsAndSteadyStateStatement::fillEvalContext(eval_context_t& eval_context) const { - for (const auto & [id, value] : content) + for (const auto& [id, value] : content) /* We use strtod() instead of stod() because we want underflows and overflows to respectively yield 0 and ±Inf. See also the comment in NumericalConstants.cc */ diff --git a/src/NumericalInitialization.hh b/src/NumericalInitialization.hh index f368696e..0c87a0df 100644 --- a/src/NumericalInitialization.hh +++ b/src/NumericalInitialization.hh @@ -20,14 +20,14 @@ #ifndef _NUMERICALINITIALIZATION_HH #define _NUMERICALINITIALIZATION_HH +#include +#include #include #include -#include -#include -#include "SymbolTable.hh" #include "ExprNode.hh" #include "Statement.hh" +#include "SymbolTable.hh" using namespace std; @@ -36,15 +36,16 @@ class InitParamStatement : public Statement private: const int symb_id; const expr_t param_value; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: InitParamStatement(int symb_id_arg, const expr_t param_value_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; //! Fill eval context with parameter value - void fillEvalContext(eval_context_t &eval_context) const; + void fillEvalContext(eval_context_t& eval_context) const; }; class InitOrEndValStatement : public Statement @@ -55,46 +56,46 @@ public: an initialization can depend on a previously initialized variable inside the block */ using init_values_t = vector>; + protected: const init_values_t init_values; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; const bool all_values_required; + public: - InitOrEndValStatement(init_values_t init_values_arg, - const SymbolTable &symbol_table_arg, + InitOrEndValStatement(init_values_t init_values_arg, const SymbolTable& symbol_table_arg, bool all_values_required_arg); //! Return set of unused variables by type set getUninitializedVariables(SymbolType type); //! Fill eval context with variables values - void fillEvalContext(eval_context_t &eval_context) const; + void fillEvalContext(eval_context_t& eval_context) const; + protected: - void writeInitValues(ostream &output) const; - void writeJsonInitValues(ostream &output) const; + void writeInitValues(ostream& output) const; + void writeJsonInitValues(ostream& output) const; }; class InitValStatement : public InitOrEndValStatement { public: - InitValStatement(init_values_t init_values_arg, - const SymbolTable &symbol_table_arg, + InitValStatement(init_values_t init_values_arg, const SymbolTable& symbol_table_arg, bool all_values_required_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; + 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; //! Writes initializations for oo_.exo_simul and oo_.exo_det_simul - void writeOutputPostInit(ostream &output) const; + void writeOutputPostInit(ostream& output) const; }; class EndValStatement : public InitOrEndValStatement { public: - EndValStatement(init_values_t init_values_arg, - const SymbolTable &symbol_table_arg, + EndValStatement(init_values_t init_values_arg, const SymbolTable& symbol_table_arg, bool all_values_required_arg); //! Workaround for trac ticket #35 - 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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class EndValLearntInStatement : public Statement @@ -102,24 +103,25 @@ class EndValLearntInStatement : public Statement public: const int learnt_in_period; enum class LearntEndValType - { - level, - add, - multiply - }; + { + level, + add, + multiply + }; // The tuple is (type, symb_id, value) using learnt_end_values_t = vector>; const learnt_end_values_t learnt_end_values; + private: - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; static string typeToString(LearntEndValType type); + public: - EndValLearntInStatement(int learnt_in_period_arg, - learnt_end_values_t learnt_end_values_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; - void writeJsonOutput(ostream &output) const override; + EndValLearntInStatement(int learnt_in_period_arg, learnt_end_values_t learnt_end_values_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; + void writeJsonOutput(ostream& output) const override; }; class HistValStatement : public Statement @@ -131,38 +133,41 @@ public: Maps pairs (symbol_id, lag) to expr_t */ using hist_values_t = map, expr_t>; + private: const hist_values_t hist_values; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; const bool all_values_required; + public: - HistValStatement(hist_values_t hist_values_arg, - const SymbolTable &symbol_table_arg, + HistValStatement(hist_values_t hist_values_arg, const SymbolTable& symbol_table_arg, bool all_values_required_arg); //! Workaround for trac ticket #157 - 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; + void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class InitvalFileStatement : public Statement { private: const OptionsList options_list; + public: explicit InitvalFileStatement(OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class HistvalFileStatement : public Statement { private: const OptionsList options_list; + public: explicit HistvalFileStatement(OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class HomotopySetupStatement : public Statement @@ -171,42 +176,46 @@ public: //! Stores the declarations of homotopy_setup /*! Order matter so we use a vector. First expr_t can be NULL if no initial value given. */ using homotopy_values_t = vector>; + private: const bool from_initval_to_endval; // Whether the from_initval_to_endval option was passed const homotopy_values_t homotopy_values; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: HomotopySetupStatement(bool from_initval_to_endval_arg, homotopy_values_t homotopy_values_arg, - const SymbolTable &symbol_table_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + const SymbolTable& symbol_table_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class SaveParamsAndSteadyStateStatement : public Statement { private: const string filename; + public: explicit SaveParamsAndSteadyStateStatement(string filename_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class LoadParamsAndSteadyStateStatement : public Statement { private: - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; //! Content of the file /*! Maps symbol ID to numeric value (stored as string) */ map content; + public: - LoadParamsAndSteadyStateStatement(const filesystem::path &filename, - const SymbolTable &symbol_table_arg, - WarningConsolidation &warnings); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; + LoadParamsAndSteadyStateStatement(const filesystem::path& filename, + const SymbolTable& symbol_table_arg, + WarningConsolidation& warnings); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; //! Fill eval context with parameters/variables values - void fillEvalContext(eval_context_t &eval_context) const; - void writeJsonOutput(ostream &output) const override; + void fillEvalContext(eval_context_t& eval_context) const; + void writeJsonOutput(ostream& output) const override; }; #endif diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc index a91f5030..99153cea 100644 --- a/src/ParsingDriver.cc +++ b/src/ParsingDriver.cc @@ -17,20 +17,20 @@ * along with Dynare. If not, see . */ +#include +#include #include #include -#include -#include -#include #include +#include +#include "ExprNode.hh" #include "ParsingDriver.hh" #include "Statement.hh" -#include "ExprNode.hh" #include "WarningConsolidation.hh" bool -ParsingDriver::symbol_exists_and_is_not_modfile_local_or_external_function(const string &s) +ParsingDriver::symbol_exists_and_is_not_modfile_local_or_external_function(const string& s) { if (!mod_file->symbol_table.exists(s)) return false; @@ -41,21 +41,23 @@ ParsingDriver::symbol_exists_and_is_not_modfile_local_or_external_function(const } void -ParsingDriver::check_symbol_existence_in_model_block(const string &name) +ParsingDriver::check_symbol_existence_in_model_block(const string& name) { if (!mod_file->symbol_table.exists(name) || undeclared_model_vars.contains(name)) undeclared_model_variable_error("Unknown symbol: " + name, name); } void -ParsingDriver::check_symbol_existence(const string &name) +ParsingDriver::check_symbol_existence(const string& name) { if (!mod_file->symbol_table.exists(name)) - error("Unknown symbol: " + name + ".\nIf referenced from the 'initval', 'endval', 'histval', or 'shocks' block, you can pass the 'nostrict' option to dynare to have this line ignored."); + error("Unknown symbol: " + name + + ".\nIf referenced from the 'initval', 'endval', 'histval', or 'shocks' block, you can " + "pass the 'nostrict' option to dynare to have this line ignored."); } void -ParsingDriver::check_symbol_is_parameter(const string &name) +ParsingDriver::check_symbol_is_parameter(const string& name) { check_symbol_existence(name); int symb_id = mod_file->symbol_table.getID(name); @@ -64,11 +66,11 @@ ParsingDriver::check_symbol_is_parameter(const string &name) } void -ParsingDriver::set_current_data_tree(DataTree *data_tree_arg) +ParsingDriver::set_current_data_tree(DataTree* data_tree_arg) { data_tree = data_tree_arg; - model_tree = dynamic_cast(data_tree_arg); - dynamic_model = dynamic_cast(data_tree_arg); + model_tree = dynamic_cast(data_tree_arg); + dynamic_model = dynamic_cast(data_tree_arg); } void @@ -87,7 +89,7 @@ ParsingDriver::reset_current_external_function_options() } unique_ptr -ParsingDriver::parse(istream &in, bool debug) +ParsingDriver::parse(istream& in, bool debug) { mod_file = make_unique(warnings); @@ -107,20 +109,21 @@ ParsingDriver::parse(istream &in, bool debug) } void -ParsingDriver::error(const Dynare::parser::location_type &l, const string &m) +ParsingDriver::error(const Dynare::parser::location_type& l, const string& m) { create_error_string(l, m, cerr); exit(EXIT_FAILURE); } void -ParsingDriver::error(const string &m) +ParsingDriver::error(const string& m) { error(location, m); } void -ParsingDriver::create_error_string(const Dynare::parser::location_type &l, const string &m, ostream &stream) +ParsingDriver::create_error_string(const Dynare::parser::location_type& l, const string& m, + ostream& stream) { stream << "ERROR: " << *l.begin.filename << ": line " << l.begin.line; if (l.begin.line == l.end.line) @@ -135,7 +138,8 @@ ParsingDriver::create_error_string(const Dynare::parser::location_type &l, const } void -ParsingDriver::create_error_string(const Dynare::parser::location_type &l, const string &m, const string &var) +ParsingDriver::create_error_string(const Dynare::parser::location_type& l, const string& m, + const string& var) { ostringstream stream; create_error_string(l, m, stream); @@ -143,13 +147,13 @@ ParsingDriver::create_error_string(const Dynare::parser::location_type &l, const } void -ParsingDriver::model_error(const string &m, const string &var) +ParsingDriver::model_error(const string& m, const string& var) { create_error_string(location, m, var); } void -ParsingDriver::undeclared_model_variable_error(const string &m, const string &var) +ParsingDriver::undeclared_model_variable_error(const string& m, const string& var) { ostringstream stream; if (!nostrict) @@ -172,20 +176,21 @@ ParsingDriver::undeclared_model_variable_error(const string &m, const string &va } void -ParsingDriver::warning(const string &m) +ParsingDriver::warning(const string& m) { warnings << "WARNING: " << location << ": " << m << endl; } int -ParsingDriver::declare_symbol(const string &name, SymbolType type, const string &tex_name, const vector> &partition_value) +ParsingDriver::declare_symbol(const string& name, SymbolType type, const string& tex_name, + const vector>& partition_value) { int symb_id; try { symb_id = mod_file->symbol_table.addSymbol(name, type, tex_name, partition_value); } - catch (SymbolTable::AlreadyDeclaredException &e) + catch (SymbolTable::AlreadyDeclaredException& e) { if (e.same_type) { @@ -199,16 +204,17 @@ ParsingDriver::declare_symbol(const string &name, SymbolType type, const string } int -ParsingDriver::declare_endogenous(const string &name, const string &tex_name, const vector> &partition_value) +ParsingDriver::declare_endogenous(const string& name, const string& tex_name, + const vector>& partition_value) { return declare_symbol(name, SymbolType::endogenous, tex_name, partition_value); } void -ParsingDriver::var(const vector>>> &symbol_list, +ParsingDriver::var(const vector>>>& symbol_list, bool log_option) { - for (auto &[name, tex_name, partition] : symbol_list) + for (auto& [name, tex_name, partition] : symbol_list) { int symb_id = declare_endogenous(name, tex_name, partition); if (log_option) @@ -217,44 +223,49 @@ ParsingDriver::var(const vector> &partition_value) +ParsingDriver::declare_exogenous(const string& name, const string& tex_name, + const vector>& partition_value) { return declare_symbol(name, SymbolType::exogenous, tex_name, partition_value); } void -ParsingDriver::varexo(const vector>>> &symbol_list) +ParsingDriver::varexo( + const vector>>>& symbol_list) { - for (auto &[name, tex_name, partition] : symbol_list) + for (auto& [name, tex_name, partition] : symbol_list) declare_exogenous(name, tex_name, partition); } void -ParsingDriver::varexo_det(const vector>>> &symbol_list) +ParsingDriver::varexo_det( + const vector>>>& symbol_list) { - for (auto &[name, tex_name, partition] : symbol_list) + for (auto& [name, tex_name, partition] : symbol_list) declare_symbol(name, SymbolType::exogenousDet, tex_name, partition); } int -ParsingDriver::declare_parameter(const string &name, const string &tex_name, const vector> &partition_value) +ParsingDriver::declare_parameter(const string& name, const string& tex_name, + const vector>& partition_value) { return declare_symbol(name, SymbolType::parameter, tex_name, partition_value); } void -ParsingDriver::parameters(const vector>>> &symbol_list) +ParsingDriver::parameters( + const vector>>>& symbol_list) { - for (auto &[name, tex_name, partition] : symbol_list) + for (auto& [name, tex_name, partition] : symbol_list) declare_parameter(name, tex_name, partition); } void -ParsingDriver::declare_statement_local_variable(const string &name) +ParsingDriver::declare_statement_local_variable(const string& name) { if (mod_file->symbol_table.exists(name)) error("Symbol " + name + " cannot be assigned within a statement " - +"while being assigned elsewhere in the modfile"); + + "while being assigned elsewhere in the modfile"); declare_symbol(name, SymbolType::statementDeclaredVariable, "", {}); } @@ -271,16 +282,18 @@ ParsingDriver::set_planner_discount_latex_name(string tex_name) } void -ParsingDriver::end_trend_var(bool log_trend, expr_t growth_factor, const vector> &symbol_list) +ParsingDriver::end_trend_var(bool log_trend, expr_t growth_factor, + const vector>& symbol_list) { /* Run detrending engine if trend variables are present, even if unused in a var(deflator=…) statement (see #113). */ mod_file->nonstationary_variables = true; vector declared_trend_vars; - for (auto &[name, tex_name] : symbol_list) + for (auto& [name, tex_name] : symbol_list) { - int symb_id = declare_symbol(name, log_trend ? SymbolType::logTrend : SymbolType::trend, tex_name, {}); + int symb_id = declare_symbol(name, log_trend ? SymbolType::logTrend : SymbolType::trend, + tex_name, {}); declared_trend_vars.push_back(symb_id); } @@ -288,7 +301,7 @@ ParsingDriver::end_trend_var(bool log_trend, expr_t growth_factor, const vector< { dynamic_model->addTrendVariables(declared_trend_vars, growth_factor); } - catch (DataTree::TrendException &e) + catch (DataTree::TrendException& e) { error("Trend variable " + e.name + " was declared twice."); } @@ -297,9 +310,9 @@ ParsingDriver::end_trend_var(bool log_trend, expr_t growth_factor, const vector< } void -ParsingDriver::predetermined_variables(const vector &symbol_list) +ParsingDriver::predetermined_variables(const vector& symbol_list) { - for (auto &name : symbol_list) + for (auto& name : symbol_list) { check_symbol_is_endogenous(name); int symb_id = mod_file->symbol_table.getID(name); @@ -308,7 +321,7 @@ ParsingDriver::predetermined_variables(const vector &symbol_list) } expr_t -ParsingDriver::add_non_negative_constant(const string &constant) +ParsingDriver::add_non_negative_constant(const string& constant) { return data_tree->AddNonNegativeConstant(constant); } @@ -326,7 +339,7 @@ ParsingDriver::add_inf_constant() } expr_t -ParsingDriver::add_model_variable(const string &name) +ParsingDriver::add_model_variable(const string& name) { if (name.find(".") != string::npos) error(name + " treated as a variable, but it contains a '.'"); @@ -337,9 +350,11 @@ ParsingDriver::add_model_variable(const string &name) { symb_id = mod_file->symbol_table.getID(name); if (mod_file->symbol_table.getType(symb_id) == SymbolType::excludedVariable) - error("Variable '" + name + "' can no longer be used since it has been excluded by a previous 'model_remove' or 'var_remove' statement"); + error("Variable '" + name + + "' can no longer be used since it has been excluded by a previous 'model_remove' " + "or 'var_remove' statement"); } - catch (SymbolTable::UnknownSymbolNameException &e) + catch (SymbolTable::UnknownSymbolNameException& e) { /* Declare variable as exogenous to continue parsing. Processing will end at end of model block (or planner_objective statement) if nostrict @@ -351,7 +366,7 @@ ParsingDriver::add_model_variable(const string &name) } expr_t -ParsingDriver::declare_or_change_type(SymbolType new_type, const string &name) +ParsingDriver::declare_or_change_type(SymbolType new_type, const string& name) { int symb_id; try @@ -361,10 +376,9 @@ ParsingDriver::declare_or_change_type(SymbolType new_type, const string &name) // remove error messages undeclared_model_vars.erase(name); - erase_if(undeclared_model_variable_errors, - [&name](auto &v) { return v.first == name; }); + erase_if(undeclared_model_variable_errors, [&name](auto& v) { return v.first == name; }); } - catch (SymbolTable::UnknownSymbolNameException &e) + catch (SymbolTable::UnknownSymbolNameException& e) { switch (new_type) { @@ -382,7 +396,6 @@ ParsingDriver::declare_or_change_type(SymbolType new_type, const string &name) } } return add_model_variable(symb_id, 0); - } expr_t @@ -393,18 +406,21 @@ ParsingDriver::add_model_variable(int symb_id, int lag) if (type == SymbolType::modFileLocalVariable) error("Variable " + mod_file->symbol_table.getName(symb_id) - +" not allowed inside model declaration. Its scope is only outside model."); + + " not allowed inside model declaration. Its scope is only outside model."); if (type == SymbolType::externalFunction) error("Symbol " + mod_file->symbol_table.getName(symb_id) - +" is a function name external to Dynare. It cannot be used like a variable without input argument inside model."); + + " is a function name external to Dynare. It cannot be used like a variable without " + "input argument inside model."); // See dynare#1765 if (type == SymbolType::exogenousDet && lag != 0) - error("Exogenous deterministic variable " + mod_file->symbol_table.getName(symb_id) + " cannot be given a lead or a lag."); + error("Exogenous deterministic variable " + mod_file->symbol_table.getName(symb_id) + + " cannot be given a lead or a lag."); if (type == SymbolType::modelLocalVariable && lag != 0) - error("Model local variable " + mod_file->symbol_table.getName(symb_id) + " cannot be given a lead or a lag."); + error("Model local variable " + mod_file->symbol_table.getName(symb_id) + + " cannot be given a lead or a lag."); if (data_tree == planner_objective.get()) { @@ -412,28 +428,33 @@ ParsingDriver::add_model_variable(int symb_id, int lag) error("Leads and lags on variables are forbidden in 'planner_objective'."); if (type == SymbolType::modelLocalVariable) - error("Model local variable " + mod_file->symbol_table.getName(symb_id) + " cannot be used in 'planner_objective'."); + error("Model local variable " + mod_file->symbol_table.getName(symb_id) + + " cannot be used in 'planner_objective'."); } if (data_tree == occbin_constraints_tree.get()) { if (lag != 0) - error("Leads and lags on variables are forbidden in 'occbin_constraints'. Note that you can achieve the same effect by introducing an auxiliary variable in the model."); + error("Leads and lags on variables are forbidden in 'occbin_constraints'. Note that you " + "can achieve the same effect by introducing an auxiliary variable in the model."); if (type == SymbolType::modelLocalVariable) - error("Model local variable " + mod_file->symbol_table.getName(symb_id) + " cannot be used in 'occbin_constraints'."); + error("Model local variable " + mod_file->symbol_table.getName(symb_id) + + " cannot be used in 'occbin_constraints'."); if (type == SymbolType::exogenous || type == SymbolType::exogenousDet) - error("Exogenous variable " + mod_file->symbol_table.getName(symb_id) + " cannot be used in 'occbin_constraints'."); + error("Exogenous variable " + mod_file->symbol_table.getName(symb_id) + + " cannot be used in 'occbin_constraints'."); } - // It makes sense to allow a lead/lag on parameters: during steady state calibration, endogenous and parameters can be swapped - // NB: we use data_tree here, to avoid a crash in the occbin_constraints case + // It makes sense to allow a lead/lag on parameters: during steady state calibration, endogenous + // and parameters can be swapped NB: we use data_tree here, to avoid a crash in the + // occbin_constraints case return data_tree->AddVariable(symb_id, lag); } expr_t -ParsingDriver::add_expression_variable(const string &name) +ParsingDriver::add_expression_variable(const string& name) { if (name.find(".") != string::npos) error(name + " treated as a variable, but it contains a '.'"); @@ -447,26 +468,31 @@ ParsingDriver::add_expression_variable(const string &name) // This check must come after the previous one! if (mod_file->symbol_table.getType(name) == SymbolType::modelLocalVariable) - error("Variable " + name + " not allowed outside model declaration. Its scope is only inside model."); + error("Variable " + name + + " not allowed outside model declaration. Its scope is only inside model."); if (mod_file->symbol_table.getType(name) == SymbolType::trend || mod_file->symbol_table.getType(name) == SymbolType::logTrend) - error("Variable " + name + " not allowed outside model declaration, because it is a trend variable."); + error("Variable " + name + + " not allowed outside model declaration, because it is a trend variable."); if (mod_file->symbol_table.getType(name) == SymbolType::externalFunction) - error("Symbol '" + name + "' is the name of a MATLAB/Octave function, and cannot be used as a variable."); + error("Symbol '" + name + + "' is the name of a MATLAB/Octave function, and cannot be used as a variable."); int symb_id = mod_file->symbol_table.getID(name); return data_tree->AddVariable(symb_id); } void -ParsingDriver::end_nonstationary_var(bool log_deflator, expr_t deflator, const vector>>> &symbol_list, bool log_option) +ParsingDriver::end_nonstationary_var( + bool log_deflator, expr_t deflator, + const vector>>>& symbol_list, bool log_option) { mod_file->nonstationary_variables = true; vector declared_nonstationary_vars; - for (auto &[name, tex_name, partition] : symbol_list) + for (auto& [name, tex_name, partition] : symbol_list) { int symb_id = declare_endogenous(name, tex_name, partition); declared_nonstationary_vars.push_back(symb_id); @@ -478,7 +504,7 @@ ParsingDriver::end_nonstationary_var(bool log_deflator, expr_t deflator, const v { dynamic_model->addNonstationaryVariables(declared_nonstationary_vars, log_deflator, deflator); } - catch (DataTree::TrendException &e) + catch (DataTree::TrendException& e) { error("Variable " + e.name + " was listed more than once as following a trend."); } @@ -487,21 +513,22 @@ ParsingDriver::end_nonstationary_var(bool log_deflator, expr_t deflator, const v deflator->collectVariables(SymbolType::endogenous, r); for (int it : r) if (dynamic_model->isNonstationary(it)) - error("The deflator contains a non-stationary endogenous variable. This is not allowed. Please use only stationary endogenous and/or {log_}trend_vars."); + error("The deflator contains a non-stationary endogenous variable. This is not allowed. " + "Please use only stationary endogenous and/or {log_}trend_vars."); declared_nonstationary_vars.clear(); reset_data_tree(); } void -ParsingDriver::dsample(const string &arg1) +ParsingDriver::dsample(const string& arg1) { int arg1_val = stoi(arg1); mod_file->addStatement(make_unique(arg1_val)); } void -ParsingDriver::dsample(const string &arg1, const string &arg2) +ParsingDriver::dsample(const string& arg1, const string& arg2) { int arg1_val = stoi(arg1); int arg2_val = stoi(arg2); @@ -509,7 +536,7 @@ ParsingDriver::dsample(const string &arg1, const string &arg2) } void -ParsingDriver::init_param(const string &name, expr_t rhs) +ParsingDriver::init_param(const string& name, expr_t rhs) { check_symbol_is_parameter(name); int symb_id = mod_file->symbol_table.getID(name); @@ -517,7 +544,7 @@ ParsingDriver::init_param(const string &name, expr_t rhs) } void -ParsingDriver::init_val(const string &name, expr_t rhs) +ParsingDriver::init_val(const string& name, expr_t rhs) { if (nostrict && !mod_file->symbol_table.exists(name)) { @@ -534,11 +561,12 @@ void ParsingDriver::initval_file() { mod_file->addStatement(make_unique(move(options_list))); - options_list.clear(); + options_list.clear(); } void -ParsingDriver::end_val(EndValLearntInStatement::LearntEndValType type, const string &name, expr_t rhs) +ParsingDriver::end_val(EndValLearntInStatement::LearntEndValType type, const string& name, + expr_t rhs) { if (nostrict && !mod_file->symbol_table.exists(name)) { @@ -552,7 +580,7 @@ ParsingDriver::end_val(EndValLearntInStatement::LearntEndValType type, const str } void -ParsingDriver::hist_val(const string &name, const string &lag, expr_t rhs) +ParsingDriver::hist_val(const string& name, const string& lag, expr_t rhs) { if (nostrict && !mod_file->symbol_table.exists(name)) { @@ -567,7 +595,7 @@ ParsingDriver::hist_val(const string &name, const string &lag, expr_t rhs) if (ilag > 0) error("histval: the lag on " + name + " should be less than or equal to 0"); - pair key{symb_id, ilag}; + pair key {symb_id, ilag}; if (hist_values.contains(key)) error("hist_val: (" + name + ", " + lag + ") declared twice"); @@ -576,14 +604,13 @@ ParsingDriver::hist_val(const string &name, const string &lag, expr_t rhs) } void -ParsingDriver::homotopy_val(const string &name, expr_t val1, expr_t val2) +ParsingDriver::homotopy_val(const string& name, expr_t val1, expr_t val2) { check_symbol_existence(name); int symb_id = mod_file->symbol_table.getID(name); SymbolType type = mod_file->symbol_table.getType(symb_id); - if (type != SymbolType::parameter - && type != SymbolType::exogenous + if (type != SymbolType::parameter && type != SymbolType::exogenous && type != SymbolType::exogenousDet) error("homotopy_val: " + name + " should be a parameter or exogenous variable"); @@ -593,9 +620,8 @@ ParsingDriver::homotopy_val(const string &name, expr_t val1, expr_t val2) void ParsingDriver::end_generate_irfs() { - mod_file->addStatement(make_unique(move(options_list), - move(generate_irf_names), - move(generate_irf_elements))); + mod_file->addStatement(make_unique( + move(options_list), move(generate_irf_names), move(generate_irf_elements))); generate_irf_elements.clear(); generate_irf_names.clear(); @@ -605,10 +631,10 @@ ParsingDriver::end_generate_irfs() void ParsingDriver::add_generate_irfs_element(string name) { - for (const auto &it : generate_irf_names) + for (const auto& it : generate_irf_names) if (it == name) - error("Names in the generate_irfs block must be unique but you entered '" - + name + "' more than once."); + error("Names in the generate_irfs block must be unique but you entered '" + name + + "' more than once."); generate_irf_names.push_back(move(name)); generate_irf_elements.push_back(generate_irf_exos); @@ -617,7 +643,7 @@ ParsingDriver::add_generate_irfs_element(string name) } void -ParsingDriver::add_generate_irfs_exog_element(string exo, const string &value) +ParsingDriver::add_generate_irfs_exog_element(string exo, const string& value) { check_symbol_is_exogenous(exo, false); if (generate_irf_exos.contains(exo)) @@ -669,63 +695,63 @@ ParsingDriver::differentiate_forward_vars_some(vector symbol_list) { mod_file->differentiate_forward_vars = true; mod_file->differentiate_forward_vars_subset = move(symbol_list); - for (auto &it : mod_file->differentiate_forward_vars_subset) + for (auto& it : mod_file->differentiate_forward_vars_subset) check_symbol_is_endogenous(it); } void -ParsingDriver::cutoff(const string &value) +ParsingDriver::cutoff(const string& value) { double val = stod(value); mod_file->dynamic_model.cutoff = val; } void -ParsingDriver::mfs(const string &value) +ParsingDriver::mfs(const string& value) { int val = stoi(value); mod_file->dynamic_model.setMFS(val); } void -ParsingDriver::static_mfs(const string &value) +ParsingDriver::static_mfs(const string& value) { int val = stoi(value); mod_file->dynamic_model.setStaticMFS(val); } void -ParsingDriver::compilation_setup_substitute_flags(const string &flags) +ParsingDriver::compilation_setup_substitute_flags(const string& flags) { mod_file->dynamic_model.user_set_subst_flags = flags; } void -ParsingDriver::compilation_setup_add_flags(const string &flags) +ParsingDriver::compilation_setup_add_flags(const string& flags) { mod_file->dynamic_model.user_set_add_flags = flags; } void -ParsingDriver::compilation_setup_substitute_libs(const string &libs) +ParsingDriver::compilation_setup_substitute_libs(const string& libs) { mod_file->dynamic_model.user_set_subst_libs = libs; } void -ParsingDriver::compilation_setup_add_libs(const string &libs) +ParsingDriver::compilation_setup_add_libs(const string& libs) { mod_file->dynamic_model.user_set_add_libs = libs; } void -ParsingDriver::compilation_setup_compiler(const string &compiler) +ParsingDriver::compilation_setup_compiler(const string& compiler) { mod_file->dynamic_model.user_set_compiler = compiler; } void -ParsingDriver::balanced_growth_test_tol(const string &value) +ParsingDriver::balanced_growth_test_tol(const string& value) { mod_file->dynamic_model.balanced_growth_test_tol = stod(value); } @@ -749,9 +775,11 @@ ParsingDriver::end_endval(bool all_values_required) end_values_new.emplace_back(symb_id, value); break; case EndValLearntInStatement::LearntEndValType::add: - error("endval: '" + mod_file->symbol_table.getName(symb_id) + " += ...' line not allowed unless 'learnt_in' option with value >1 is passed"); + error("endval: '" + mod_file->symbol_table.getName(symb_id) + + " += ...' line not allowed unless 'learnt_in' option with value >1 is passed"); case EndValLearntInStatement::LearntEndValType::multiply: - error("endval: '" + mod_file->symbol_table.getName(symb_id) + " *= ...' line not allowed unless 'learnt_in' option with value >1 is passed"); + error("endval: '" + mod_file->symbol_table.getName(symb_id) + + " *= ...' line not allowed unless 'learnt_in' option with value >1 is passed"); } mod_file->addStatement(make_unique(move(end_values_new), mod_file->symbol_table, @@ -760,7 +788,7 @@ ParsingDriver::end_endval(bool all_values_required) } void -ParsingDriver::end_endval_learnt_in(const string &learnt_in_period) +ParsingDriver::end_endval_learnt_in(const string& learnt_in_period) { int learnt_in_period_int = stoi(learnt_in_period); if (learnt_in_period_int < 1) @@ -772,9 +800,10 @@ ParsingDriver::end_endval_learnt_in(const string &learnt_in_period) } for (auto [type, symb_id, value] : end_values) if (mod_file->symbol_table.getType(symb_id) != SymbolType::exogenous) - error("endval(learnt_in=...): " + mod_file->symbol_table.getName(symb_id) + " is not an exogenous variable"); - mod_file->addStatement(make_unique(learnt_in_period_int, move(end_values), - mod_file->symbol_table)); + error("endval(learnt_in=...): " + mod_file->symbol_table.getName(symb_id) + + " is not an exogenous variable"); + mod_file->addStatement(make_unique( + learnt_in_period_int, move(end_values), mod_file->symbol_table)); end_values.clear(); } @@ -789,7 +818,8 @@ ParsingDriver::end_histval(bool all_values_required) void ParsingDriver::end_homotopy(bool from_initval_to_endval) { - mod_file->addStatement(make_unique(from_initval_to_endval, move(homotopy_values), mod_file->symbol_table)); + mod_file->addStatement(make_unique( + from_initval_to_endval, move(homotopy_values), mod_file->symbol_table)); homotopy_values.clear(); } @@ -808,13 +838,13 @@ ParsingDriver::end_epilogue() } void -ParsingDriver::add_epilogue_variable(const string &name) +ParsingDriver::add_epilogue_variable(const string& name) { declare_symbol(name, SymbolType::epilogue, "", {}); } void -ParsingDriver::add_epilogue_equal(const string &name, expr_t expr) +ParsingDriver::add_epilogue_equal(const string& name, expr_t expr) { mod_file->epilogue.addDefinition(mod_file->symbol_table.getID(name), expr); } @@ -830,7 +860,7 @@ ParsingDriver::end_model() { bool exit_after_write = false; if (model_errors.size() > 0) - for (auto &it : model_errors) + for (auto& it : model_errors) { if (it.first.empty()) exit_after_write = true; @@ -838,7 +868,7 @@ ParsingDriver::end_model() } if (undeclared_model_variable_errors.size() > 0) - for (auto &it : undeclared_model_variable_errors) + for (auto& it : undeclared_model_variable_errors) { if (nostrict) warning(it.second); @@ -866,7 +896,8 @@ ParsingDriver::end_shocks(bool overwrite) if (!learnt_shocks_add.empty()) error("shocks: 'add' keyword not allowed unless 'learnt_in' option with value >1 is passed"); if (!learnt_shocks_multiply.empty()) - error("shocks: 'multiply' keyword not allowed unless 'learnt_in' option with value >1 is passed"); + error( + "shocks: 'multiply' keyword not allowed unless 'learnt_in' option with value >1 is passed"); var_shocks.clear(); std_shocks.clear(); covar_shocks.clear(); @@ -877,8 +908,7 @@ void ParsingDriver::end_mshocks(bool overwrite, bool relative_to_initval) { mod_file->addStatement(make_unique(overwrite, relative_to_initval, - move(det_shocks), - mod_file->symbol_table)); + move(det_shocks), mod_file->symbol_table)); det_shocks.clear(); if (!learnt_shocks_add.empty()) error("mshocks: 'add' keyword not allowed"); @@ -889,8 +919,8 @@ ParsingDriver::end_mshocks(bool overwrite, bool relative_to_initval) void ParsingDriver::end_shocks_surprise(bool overwrite) { - mod_file->addStatement(make_unique(overwrite, move(det_shocks), - mod_file->symbol_table)); + mod_file->addStatement( + make_unique(overwrite, move(det_shocks), mod_file->symbol_table)); det_shocks.clear(); if (!learnt_shocks_add.empty()) error("shocks(surprise): 'add' keyword not allowed"); @@ -899,7 +929,7 @@ ParsingDriver::end_shocks_surprise(bool overwrite) } void -ParsingDriver::end_shocks_learnt_in(const string &learnt_in_period, bool overwrite) +ParsingDriver::end_shocks_learnt_in(const string& learnt_in_period, bool overwrite) { int learnt_in_period_int = stoi(learnt_in_period); if (learnt_in_period_int < 1) @@ -909,46 +939,50 @@ ParsingDriver::end_shocks_learnt_in(const string &learnt_in_period, bool overwri end_shocks(overwrite); return; } - for (auto &storage : { det_shocks, learnt_shocks_add, learnt_shocks_multiply } ) - for (auto &[symb_id, vals] : storage) + for (auto& storage : {det_shocks, learnt_shocks_add, learnt_shocks_multiply}) + for (auto& [symb_id, vals] : storage) for (auto [period1, period2, expr] : vals) if (period1 < learnt_in_period_int) - error("shocks: for variable " + mod_file->symbol_table.getName(symb_id) + ", shock period (" + to_string(period1) + ") is earlier than the period in which the shock is learnt (" + learnt_in_period + ")"); + error("shocks: for variable " + mod_file->symbol_table.getName(symb_id) + + ", shock period (" + to_string(period1) + + ") is earlier than the period in which the shock is learnt (" + learnt_in_period + + ")"); // Aggregate the three types of shocks ShocksLearntInStatement::learnt_shocks_t learnt_shocks; - for (const auto &[id, v] : det_shocks) + for (const auto& [id, v] : det_shocks) { vector> v2; for (auto [period1, period2, value] : v) v2.emplace_back(ShocksLearntInStatement::LearntShockType::level, period1, period2, value); learnt_shocks[id] = v2; } - for (const auto &[id, v] : learnt_shocks_add) + for (const auto& [id, v] : learnt_shocks_add) { vector> v2; for (auto [period1, period2, value] : v) v2.emplace_back(ShocksLearntInStatement::LearntShockType::add, period1, period2, value); learnt_shocks[id] = v2; } - for (const auto &[id, v] : learnt_shocks_multiply) + for (const auto& [id, v] : learnt_shocks_multiply) { vector> v2; for (auto [period1, period2, value] : v) - v2.emplace_back(ShocksLearntInStatement::LearntShockType::multiply, period1, period2, value); + v2.emplace_back(ShocksLearntInStatement::LearntShockType::multiply, period1, period2, + value); learnt_shocks[id] = v2; } - mod_file->addStatement(make_unique(learnt_in_period_int, overwrite, - move(learnt_shocks), - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + learnt_in_period_int, overwrite, move(learnt_shocks), mod_file->symbol_table)); det_shocks.clear(); learnt_shocks_add.clear(); learnt_shocks_multiply.clear(); } void -ParsingDriver::end_mshocks_learnt_in(const string &learnt_in_period, bool overwrite, bool relative_to_initval) +ParsingDriver::end_mshocks_learnt_in(const string& learnt_in_period, bool overwrite, + bool relative_to_initval) { int learnt_in_period_int = stoi(learnt_in_period); if (learnt_in_period_int < 1) @@ -959,16 +993,19 @@ ParsingDriver::end_mshocks_learnt_in(const string &learnt_in_period, bool overwr return; } - for (auto &[symb_id, vals] : det_shocks) + for (auto& [symb_id, vals] : det_shocks) for (auto [period1, period2, expr] : vals) if (period1 < learnt_in_period_int) - error("mshocks: for variable " + mod_file->symbol_table.getName(symb_id) + ", shock period (" + to_string(period1) + ") is earlier than the period in which the shock is learnt (" + learnt_in_period + ")"); + error("mshocks: for variable " + mod_file->symbol_table.getName(symb_id) + + ", shock period (" + to_string(period1) + + ") is earlier than the period in which the shock is learnt (" + learnt_in_period + + ")"); ShocksLearntInStatement::learnt_shocks_t learnt_shocks; - const auto type { relative_to_initval ? - ShocksLearntInStatement::LearntShockType::multiplyInitialSteadyState : - ShocksLearntInStatement::LearntShockType::multiplySteadyState }; - for (const auto &[id, v] : det_shocks) + const auto type {relative_to_initval + ? ShocksLearntInStatement::LearntShockType::multiplyInitialSteadyState + : ShocksLearntInStatement::LearntShockType::multiplySteadyState}; + for (const auto& [id, v] : det_shocks) { vector> v2; for (auto [period1, period2, value] : v) @@ -976,9 +1013,8 @@ ParsingDriver::end_mshocks_learnt_in(const string &learnt_in_period, bool overwr learnt_shocks[id] = v2; } - mod_file->addStatement(make_unique(learnt_in_period_int, overwrite, - move(learnt_shocks), - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + learnt_in_period_int, overwrite, move(learnt_shocks), mod_file->symbol_table)); det_shocks.clear(); if (!learnt_shocks_add.empty()) error("mshocks: 'add' keyword not allowed"); @@ -989,16 +1025,16 @@ ParsingDriver::end_mshocks_learnt_in(const string &learnt_in_period, bool overwr void ParsingDriver::end_heteroskedastic_shocks(bool overwrite) { - mod_file->addStatement(make_unique(overwrite, - move(heteroskedastic_shocks_values), - move(heteroskedastic_shocks_scales), - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + overwrite, move(heteroskedastic_shocks_values), move(heteroskedastic_shocks_scales), + mod_file->symbol_table)); heteroskedastic_shocks_values.clear(); heteroskedastic_shocks_scales.clear(); } void -ParsingDriver::add_det_shock(const string &var, const vector> &periods, const vector &values, DetShockType type) +ParsingDriver::add_det_shock(const string& var, const vector>& periods, + const vector& values, DetShockType type) { switch (type) { @@ -1006,7 +1042,7 @@ ParsingDriver::add_det_shock(const string &var, const vector> &pe check_symbol_is_endogenous(var); break; case DetShockType::standard: - // Allow exo_det, for stochastic context + // Allow exo_det, for stochastic context check_symbol_is_exogenous(var, true); break; case DetShockType::add: @@ -1022,7 +1058,8 @@ ParsingDriver::add_det_shock(const string &var, const vector> &pe error("shocks/conditional_forecast_paths: variable " + var + " declared twice"); if (periods.size() != values.size()) - error("shocks/conditional_forecast_paths: variable " + var + ": number of periods is different from number of shock values"); + error("shocks/conditional_forecast_paths: variable " + var + + ": number of periods is different from number of shock values"); vector> v; @@ -1045,7 +1082,8 @@ ParsingDriver::add_det_shock(const string &var, const vector> &pe } void -ParsingDriver::add_heteroskedastic_shock(const string &var, const vector> &periods, const vector &values, bool scales) +ParsingDriver::add_heteroskedastic_shock(const string& var, const vector>& periods, + const vector& values, bool scales) { check_symbol_is_exogenous(var, false); @@ -1056,7 +1094,8 @@ ParsingDriver::add_heteroskedastic_shock(const string &var, const vector> v; for (size_t i = 0; i < periods.size(); i++) @@ -1069,11 +1108,12 @@ ParsingDriver::add_heteroskedastic_shock(const string &var, const vectorsymbol_table.exists(var)) { - warning("discarding shocks block declaration of the standard error of '" + var + "' as it was not declared"); + warning("discarding shocks block declaration of the standard error of '" + var + + "' as it was not declared"); return; } @@ -1087,11 +1127,12 @@ ParsingDriver::add_stderr_shock(const string &var, expr_t value) } void -ParsingDriver::add_var_shock(const string &var, expr_t value) +ParsingDriver::add_var_shock(const string& var, expr_t value) { if (nostrict && !mod_file->symbol_table.exists(var)) { - warning("discarding shocks block declaration of the variance of '" + var + "' as it was not declared"); + warning("discarding shocks block declaration of the variance of '" + var + + "' as it was not declared"); return; } @@ -1105,12 +1146,12 @@ ParsingDriver::add_var_shock(const string &var, expr_t value) } void -ParsingDriver::add_covar_shock(const string &var1, const string &var2, expr_t value) +ParsingDriver::add_covar_shock(const string& var1, const string& var2, expr_t value) { - if (nostrict && - (!mod_file->symbol_table.exists(var1) || !mod_file->symbol_table.exists(var2))) + if (nostrict && (!mod_file->symbol_table.exists(var1) || !mod_file->symbol_table.exists(var2))) { - warning("discarding shocks block declaration of the covariance of '" + var1 + "' and '" + var2 + "' as at least one was not declared"); + warning("discarding shocks block declaration of the covariance of '" + var1 + "' and '" + var2 + + "' as at least one was not declared"); return; } @@ -1119,23 +1160,23 @@ ParsingDriver::add_covar_shock(const string &var1, const string &var2, expr_t va int symb_id1 = mod_file->symbol_table.getID(var1); int symb_id2 = mod_file->symbol_table.getID(var2); - pair key{symb_id1, symb_id2}, key_inv{symb_id2, symb_id1}; + pair key {symb_id1, symb_id2}, key_inv {symb_id2, symb_id1}; - if (covar_shocks.contains(key) || covar_shocks.contains(key_inv) - || corr_shocks.contains(key) || corr_shocks.contains(key_inv)) - error("shocks: covariance or correlation shock on variable pair (" + var1 + ", " - + var2 + ") declared twice"); + if (covar_shocks.contains(key) || covar_shocks.contains(key_inv) || corr_shocks.contains(key) + || corr_shocks.contains(key_inv)) + error("shocks: covariance or correlation shock on variable pair (" + var1 + ", " + var2 + + ") declared twice"); covar_shocks[key] = value; } void -ParsingDriver::add_correl_shock(const string &var1, const string &var2, expr_t value) +ParsingDriver::add_correl_shock(const string& var1, const string& var2, expr_t value) { - if (nostrict && - (!mod_file->symbol_table.exists(var1) || !mod_file->symbol_table.exists(var2))) + if (nostrict && (!mod_file->symbol_table.exists(var1) || !mod_file->symbol_table.exists(var2))) { - warning("discarding shocks block declaration of the correlation of '" + var1 + "' and '" + var2 + "' as at least one was not declared"); + warning("discarding shocks block declaration of the correlation of '" + var1 + "' and '" + + var2 + "' as at least one was not declared"); return; } @@ -1144,12 +1185,12 @@ ParsingDriver::add_correl_shock(const string &var1, const string &var2, expr_t v int symb_id1 = mod_file->symbol_table.getID(var1); int symb_id2 = mod_file->symbol_table.getID(var2); - pair key{symb_id1, symb_id2}, key_inv{symb_id2, symb_id1}; + pair key {symb_id1, symb_id2}, key_inv {symb_id2, symb_id1}; - if (covar_shocks.contains(key) || covar_shocks.contains(key_inv) - || corr_shocks.contains(key) || corr_shocks.contains(key_inv)) - error("shocks: covariance or correlation shock on variable pair (" + var1 + ", " - + var2 + ") declared twice"); + if (covar_shocks.contains(key) || covar_shocks.contains(key_inv) || corr_shocks.contains(key) + || corr_shocks.contains(key_inv)) + error("shocks: covariance or correlation shock on variable pair (" + var1 + ", " + var2 + + ") declared twice"); corr_shocks[key] = value; } @@ -1165,11 +1206,9 @@ ParsingDriver::begin_svar_identification() void ParsingDriver::end_svar_identification() { - mod_file->addStatement(make_unique(move(svar_ident_restrictions), - svar_upper_cholesky, - svar_lower_cholesky, - svar_constants_exclusion, - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + move(svar_ident_restrictions), svar_upper_cholesky, svar_lower_cholesky, + svar_constants_exclusion, mod_file->symbol_table)); svar_equation_restrictions.clear(); svar_ident_restrictions.clear(); svar_Qi_restriction_nbr.clear(); @@ -1177,15 +1216,15 @@ ParsingDriver::end_svar_identification() } void -ParsingDriver::combine_lag_and_restriction(const string &lag) +ParsingDriver::combine_lag_and_restriction(const string& lag) { int current_lag = stoi(lag); - for (const auto &it : svar_ident_restrictions) + for (const auto& it : svar_ident_restrictions) if (it.lag == current_lag) error("lag " + lag + " used more than once."); - for (const auto &it : svar_equation_restrictions) + for (const auto& it : svar_equation_restrictions) for (auto it1 : it.second) { SvarIdentificationStatement::svar_identification_restriction new_restriction; @@ -1206,7 +1245,8 @@ ParsingDriver::combine_lag_and_restriction(const string &lag) } void -ParsingDriver::add_restriction_in_equation(const string &equation, const vector &symbol_list) +ParsingDriver::add_restriction_in_equation(const string& equation, + const vector& symbol_list) { int eqn = stoi(equation); if (eqn < 1) @@ -1216,12 +1256,12 @@ ParsingDriver::add_restriction_in_equation(const string &equation, const vector< error("equation number " + equation + " referenced more than once under a single lag."); vector svar_restriction_symbols; - for (auto &name : symbol_list) + for (auto& name : symbol_list) { check_symbol_existence(name); int symb_id = mod_file->symbol_table.getID(name); - for (const auto &viit : svar_restriction_symbols) + for (const auto& viit : svar_restriction_symbols) if (symb_id == viit) error(name + " restriction added twice."); @@ -1231,7 +1271,7 @@ ParsingDriver::add_restriction_in_equation(const string &equation, const vector< } void -ParsingDriver::add_restriction_equation_nbr(const string &eq_nbr) +ParsingDriver::add_restriction_equation_nbr(const string& eq_nbr) { svar_equation_nbr = stoi(eq_nbr); svar_left_handside = true; @@ -1249,7 +1289,8 @@ ParsingDriver::add_restriction_equal() } void -ParsingDriver::add_positive_restriction_element(expr_t value, const string &variable, const string &lag) +ParsingDriver::add_positive_restriction_element(expr_t value, const string& variable, + const string& lag) { // if the expression is not on the left handside, change its sign if (!svar_left_handside) @@ -1259,7 +1300,7 @@ ParsingDriver::add_positive_restriction_element(expr_t value, const string &vari } void -ParsingDriver::add_positive_restriction_element(const string &variable, const string &lag) +ParsingDriver::add_positive_restriction_element(const string& variable, const string& lag) { expr_t value(data_tree->One); @@ -1271,7 +1312,8 @@ ParsingDriver::add_positive_restriction_element(const string &variable, const st } void -ParsingDriver::add_negative_restriction_element(expr_t value, const string &variable, const string &lag) +ParsingDriver::add_negative_restriction_element(expr_t value, const string& variable, + const string& lag) { // if the expression is on the left handside, change its sign if (svar_left_handside) @@ -1281,7 +1323,7 @@ ParsingDriver::add_negative_restriction_element(expr_t value, const string &vari } void -ParsingDriver::add_negative_restriction_element(const string &variable, const string &lag) +ParsingDriver::add_negative_restriction_element(const string& variable, const string& lag) { expr_t value(data_tree->One); @@ -1293,7 +1335,7 @@ ParsingDriver::add_negative_restriction_element(const string &variable, const st } void -ParsingDriver::add_restriction_element(expr_t value, const string &variable, const string &lag) +ParsingDriver::add_restriction_element(expr_t value, const string& variable, const string& lag) { check_symbol_existence(variable); int symb_id = mod_file->symbol_table.getID(variable); @@ -1316,7 +1358,8 @@ ParsingDriver::add_restriction_element(expr_t value, const string &variable, con { if ((svar_restriction_type == SvarRestrictionType::Qi_TYPE && current_lag > 0) || (svar_restriction_type == SvarRestrictionType::Ri_TYPE && current_lag == 0)) - error("SVAR_IDENTIFICATION: a single restrictions must affect either Qi or Ri, but not both"); + error( + "SVAR_IDENTIFICATION: a single restrictions must affect either Qi or Ri, but not both"); } SvarIdentificationStatement::svar_identification_restriction new_restriction; new_restriction.equation = svar_equation_nbr; @@ -1375,7 +1418,7 @@ ParsingDriver::option_num(string name_option, string opt1, string opt2) if (options_list.contains(name_option)) error("option " + name_option + " declared twice"); - options_list.set(move(name_option), pair{move(opt1), move(opt2)}); + options_list.set(move(name_option), pair {move(opt1), move(opt2)}); } void @@ -1384,7 +1427,7 @@ ParsingDriver::option_num(string name_option, string opt) if (options_list.contains(name_option)) error("option " + name_option + " declared twice"); - options_list.set(move(name_option), OptionsList::NumVal{move(opt)}); + options_list.set(move(name_option), OptionsList::NumVal {move(opt)}); } void @@ -1393,7 +1436,7 @@ ParsingDriver::option_str(string name_option, string opt) if (options_list.contains(name_option)) error("option " + name_option + " declared twice"); - options_list.set(move(name_option), OptionsList::StringVal{move(opt)}); + options_list.set(move(name_option), OptionsList::StringVal {move(opt)}); } void @@ -1402,7 +1445,7 @@ ParsingDriver::option_date(string name_option, string opt) if (options_list.contains(name_option)) error("option " + name_option + " declared twice"); - options_list.set(move(name_option), OptionsList::DateVal{move(opt)}); + options_list.set(move(name_option), OptionsList::DateVal {move(opt)}); } void @@ -1412,7 +1455,7 @@ ParsingDriver::option_symbol_list(string name_option, vector symbol_list error("option " + name_option + " declared twice"); if (name_option == "irf_shocks") - for (auto &shock : symbol_list) + for (auto& shock : symbol_list) { if (!mod_file->symbol_table.exists(shock)) error("Unknown symbol: " + shock); @@ -1421,11 +1464,13 @@ ParsingDriver::option_symbol_list(string name_option, vector symbol_list } if (name_option == "ms.parameters") - for (auto &it : symbol_list) + for (auto& it : symbol_list) if (mod_file->symbol_table.getType(it) != SymbolType::parameter) - error("Variables passed to the parameters option of the markov_switching statement must be parameters. Caused by: " + it); + error("Variables passed to the parameters option of the markov_switching statement must be " + "parameters. Caused by: " + + it); - options_list.set(move(name_option), OptionsList::SymbolListVal{move(symbol_list)}); + options_list.set(move(name_option), OptionsList::SymbolListVal {move(symbol_list)}); } void @@ -1449,7 +1494,7 @@ ParsingDriver::option_vec_str(string name_option, vector opt) if (opt.empty()) error("option " + name_option + " was passed an empty vector."); - options_list.set(move(name_option), OptionsList::VecStrVal{move(opt)}); + options_list.set(move(name_option), OptionsList::VecStrVal {move(opt)}); } void @@ -1461,7 +1506,7 @@ ParsingDriver::option_vec_cellstr(string name_option, vector opt) if (opt.empty()) error("option " + name_option + " was passed an empty vector."); - options_list.set(move(name_option), OptionsList::VecCellStrVal{move(opt)}); + options_list.set(move(name_option), OptionsList::VecCellStrVal {move(opt)}); } void @@ -1473,7 +1518,7 @@ ParsingDriver::option_vec_value(string name_option, vector opt) if (opt.empty()) error("option " + name_option + " was passed an empty vector."); - options_list.set(move(name_option), OptionsList::VecValueVal{move(opt)}); + options_list.set(move(name_option), OptionsList::VecValueVal {move(opt)}); } void @@ -1503,9 +1548,9 @@ ParsingDriver::rplot(vector symbol_list) void ParsingDriver::stoch_simul(SymbolList symbol_list) { - //make sure default order is known to preprocessor, see #49 + // make sure default order is known to preprocessor, see #49 if (!options_list.contains("order")) - options_list.set("order", OptionsList::NumVal{"2"}); + options_list.set("order", OptionsList::NumVal {"2"}); symbol_list.removeDuplicates("stoch_simul", warnings); @@ -1519,11 +1564,12 @@ ParsingDriver::trend_component_model() { try { - mod_file->trend_component_model_table.addTrendComponentModel(options_list.get("trend_component.name"), - options_list.get("trend_component.eqtags"), - options_list.get("trend_component.targets")); + mod_file->trend_component_model_table.addTrendComponentModel( + options_list.get("trend_component.name"), + options_list.get("trend_component.eqtags"), + options_list.get("trend_component.targets")); } - catch (OptionsList::UnknownOptionException &e) + catch (OptionsList::UnknownOptionException& e) { string name {e.name.substr(16)}; if (name == "name") @@ -1539,11 +1585,14 @@ ParsingDriver::var_model() { try { - mod_file->var_model_table.addVarModel(options_list.get("var.model_name"), - options_list.get_if("var.structural").value_or(OptionsList::NumVal{"false"}) == "true", - options_list.get("var.eqtags")); + mod_file->var_model_table.addVarModel( + options_list.get("var.model_name"), + options_list.get_if("var.structural") + .value_or(OptionsList::NumVal {"false"}) + == "true", + options_list.get("var.eqtags")); } - catch (OptionsList::UnknownOptionException &e) + catch (OptionsList::UnknownOptionException& e) { error("You must pass the '" + e.name.substr(4) + "' option to the 'var_model' statement."); } @@ -1553,7 +1602,8 @@ ParsingDriver::var_model() void ParsingDriver::simul() { - warning("The 'simul' statement is deprecated. Please use 'perfect_foresight_setup' and 'perfect_foresight_solver' instead."); + warning("The 'simul' statement is deprecated. Please use 'perfect_foresight_setup' and " + "'perfect_foresight_solver' instead."); mod_file->addStatement(make_unique(move(options_list))); options_list.clear(); } @@ -1592,7 +1642,8 @@ ParsingDriver::add_estimated_params_element() check_symbol_existence(estim_params.name2); SymbolType type2 = mod_file->symbol_table.getType(estim_params.name2); if ((type != SymbolType::endogenous && type != SymbolType::exogenous) || type != type2) - error(estim_params.name + " and " + estim_params.name2 + " must either be both endogenous variables or both exogenous"); + error(estim_params.name + " and " + estim_params.name2 + + " must either be both endogenous variables or both exogenous"); break; } } @@ -1611,25 +1662,24 @@ ParsingDriver::estimated_params(bool overwrite) void ParsingDriver::estimated_params_init(bool use_calibration) { - mod_file->addStatement(make_unique(move(estim_params_list), - mod_file->symbol_table, - use_calibration)); + mod_file->addStatement(make_unique( + move(estim_params_list), mod_file->symbol_table, use_calibration)); estim_params_list.clear(); } void ParsingDriver::estimated_params_bounds() { - mod_file->addStatement(make_unique(move(estim_params_list), - mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(estim_params_list), mod_file->symbol_table)); estim_params_list.clear(); } void ParsingDriver::estimated_params_remove() { - mod_file->addStatement(make_unique(move(estim_params_list), - mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(estim_params_list), mod_file->symbol_table)); estim_params_list.clear(); } @@ -1655,11 +1705,12 @@ void ParsingDriver::set_unit_root_vars() { mod_file->addStatement(make_unique()); - warning("''unit_root_vars'' is now obsolete; use the ''diffuse_filter'' option of ''estimation'' instead"); + warning("''unit_root_vars'' is now obsolete; use the ''diffuse_filter'' option of ''estimation'' " + "instead"); } void -ParsingDriver::set_time(const string &arg) +ParsingDriver::set_time(const string& arg) { option_date("initial_period", arg); mod_file->addStatement(make_unique(move(options_list))); @@ -1682,12 +1733,13 @@ ParsingDriver::set_subsamples(string name1, string name2) mod_file->addStatement(make_unique(name1, name2, subsample_declaration_map, mod_file->symbol_table)); - subsample_declarations[{ move(name1), move(name2) }] = move(subsample_declaration_map); + subsample_declarations[{move(name1), move(name2)}] = move(subsample_declaration_map); subsample_declaration_map.clear(); } void -ParsingDriver::copy_subsamples(string to_name1, string to_name2, string from_name1, string from_name2) +ParsingDriver::copy_subsamples(string to_name1, string to_name2, string from_name1, + string from_name2) { check_symbol_existence(to_name1); check_symbol_existence(from_name1); @@ -1696,23 +1748,23 @@ ParsingDriver::copy_subsamples(string to_name1, string to_name2, string from_nam if (!from_name2.empty()) check_symbol_existence(from_name2); - if (!subsample_declarations.contains({ from_name1, from_name2 })) + if (!subsample_declarations.contains({from_name1, from_name2})) { - string err{from_name1}; + string err {from_name1}; if (!from_name2.empty()) err.append(",").append(from_name2); error(err + " does not have an associated subsample statement."); } - mod_file->addStatement(make_unique(to_name1, to_name2, from_name1, from_name2, - mod_file->symbol_table)); + mod_file->addStatement(make_unique(to_name1, to_name2, from_name1, + from_name2, mod_file->symbol_table)); - subsample_declarations[{ move(to_name1), move(to_name2) }] - = subsample_declarations[{ move(from_name1), move(from_name2) }]; + subsample_declarations[{move(to_name1), move(to_name2)}] + = subsample_declarations[{move(from_name1), move(from_name2)}]; } void -ParsingDriver::check_symbol_is_statement_variable(const string &name) +ParsingDriver::check_symbol_is_statement_variable(const string& name) { check_symbol_existence(name); int symb_id = mod_file->symbol_table.getID(name); @@ -1725,11 +1777,11 @@ ParsingDriver::set_subsample_name_equal_to_date_range(string name, string date1, { if (subsample_declaration_map.contains(name)) error("Symbol " + name + " may only be assigned once in a SUBSAMPLE statement"); - subsample_declaration_map[move(name)] = { move(date1), move(date2) }; + subsample_declaration_map[move(name)] = {move(date1), move(date2)}; } void -ParsingDriver::check_subsample_declaration_exists(const string &name1, const string &subsample_name) +ParsingDriver::check_subsample_declaration_exists(const string& name1, const string& subsample_name) { if (subsample_name.empty()) return; @@ -1738,7 +1790,8 @@ ParsingDriver::check_subsample_declaration_exists(const string &name1, const str } void -ParsingDriver::check_subsample_declaration_exists(const string &name1, const string &name2, const string &subsample_name) +ParsingDriver::check_subsample_declaration_exists(const string& name1, const string& name2, + const string& subsample_name) { if (subsample_name.empty()) return; @@ -1747,13 +1800,13 @@ ParsingDriver::check_subsample_declaration_exists(const string &name1, const str if (!name2.empty()) check_symbol_existence(name2); - auto it = subsample_declarations.find({ name1, name2 }); + auto it = subsample_declarations.find({name1, name2}); if (it == subsample_declarations.end()) { - it = subsample_declarations.find({ name2, name1 }); + it = subsample_declarations.find({name2, name1}); if (it == subsample_declarations.end()) { - string err{name1}; + string err {name1}; if (!name2.empty()) err.append(",").append(name2); error("A subsample statement has not been issued for " + err); @@ -1762,7 +1815,8 @@ ParsingDriver::check_subsample_declaration_exists(const string &name1, const str auto tmp_map = it->second; if (!tmp_map.contains(subsample_name)) - error("The subsample name " + subsample_name + " was not previously declared in a subsample statement."); + error("The subsample name " + subsample_name + + " was not previously declared in a subsample statement."); } void @@ -1778,12 +1832,12 @@ ParsingDriver::set_prior(string name, string subsample_name) } void -ParsingDriver::set_joint_prior(const vector &symbol_vec) +ParsingDriver::set_joint_prior(const vector& symbol_vec) { - for (auto &it : symbol_vec) + for (auto& it : symbol_vec) add_joint_parameter(it); - mod_file->addStatement(make_unique(move(joint_parameters), prior_shape, - move(options_list))); + mod_file->addStatement( + make_unique(move(joint_parameters), prior_shape, move(options_list))); joint_parameters.clear(); options_list.clear(); prior_shape = PriorDistributions::noShape; @@ -1803,9 +1857,8 @@ ParsingDriver::set_prior_variance(expr_t variance) } void -ParsingDriver::copy_prior(string to_declaration_type, string to_name1, - string to_name2, string to_subsample_name, - string from_declaration_type, string from_name1, +ParsingDriver::copy_prior(string to_declaration_type, string to_name1, string to_name2, + string to_subsample_name, string from_declaration_type, string from_name1, string from_name2, string from_subsample_name) { if (to_declaration_type == "par") @@ -1826,11 +1879,10 @@ ParsingDriver::copy_prior(string to_declaration_type, string to_name1, check_symbol_is_endogenous_or_exogenous(from_name2, false); } - mod_file->addStatement(make_unique(move(to_declaration_type), move(to_name1), - move(to_name2), move(to_subsample_name), - move(from_declaration_type), move(from_name1), - move(from_name2), move(from_subsample_name), - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + move(to_declaration_type), move(to_name1), move(to_name2), move(to_subsample_name), + move(from_declaration_type), move(from_name1), move(from_name2), move(from_subsample_name), + mod_file->symbol_table)); } void @@ -1838,16 +1890,15 @@ ParsingDriver::set_options(string name, string subsample_name) { check_symbol_is_parameter(name); check_subsample_declaration_exists(name, subsample_name); - mod_file->addStatement(make_unique(move(name), move(subsample_name), - move(options_list))); + mod_file->addStatement( + make_unique(move(name), move(subsample_name), move(options_list))); options_list.clear(); } void -ParsingDriver::copy_options(string to_declaration_type, string to_name1, - string to_name2, string to_subsample_name, - string from_declaration_type, string from_name1, - string from_name2, string from_subsample_name) +ParsingDriver::copy_options(string to_declaration_type, string to_name1, string to_name2, + string to_subsample_name, string from_declaration_type, + string from_name1, string from_name2, string from_subsample_name) { if (to_declaration_type == "par") check_symbol_is_parameter(to_name1); @@ -1867,15 +1918,14 @@ ParsingDriver::copy_options(string to_declaration_type, string to_name1, check_symbol_is_endogenous_or_exogenous(from_name2, false); } - mod_file->addStatement(make_unique(move(to_declaration_type), move(to_name1), - move(to_name2), move(to_subsample_name), - move(from_declaration_type), move(from_name1), - move(from_name2), move(from_subsample_name), - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + move(to_declaration_type), move(to_name1), move(to_name2), move(to_subsample_name), + move(from_declaration_type), move(from_name1), move(from_name2), move(from_subsample_name), + mod_file->symbol_table)); } void -ParsingDriver::check_symbol_is_endogenous_or_exogenous(const string &name, bool allow_det) +ParsingDriver::check_symbol_is_endogenous_or_exogenous(const string& name, bool allow_det) { check_symbol_existence(name); switch (mod_file->symbol_table.getType(name)) @@ -1893,7 +1943,7 @@ ParsingDriver::check_symbol_is_endogenous_or_exogenous(const string &name, bool } void -ParsingDriver::check_symbol_is_endogenous(const string &name) +ParsingDriver::check_symbol_is_endogenous(const string& name) { check_symbol_existence(name); if (mod_file->symbol_table.getType(name) != SymbolType::endogenous) @@ -1901,7 +1951,7 @@ ParsingDriver::check_symbol_is_endogenous(const string &name) } void -ParsingDriver::check_symbol_is_exogenous(const string &name, bool allow_exo_det) +ParsingDriver::check_symbol_is_exogenous(const string& name, bool allow_exo_det) { check_symbol_existence(name); switch (mod_file->symbol_table.getType(name)) @@ -1922,9 +1972,9 @@ ParsingDriver::set_std_prior(string name, string subsample_name) { check_symbol_is_endogenous_or_exogenous(name, false); check_subsample_declaration_exists(name, subsample_name); - mod_file->addStatement(make_unique(move(name), move(subsample_name), - prior_shape, prior_variance, - move(options_list), mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(name), move(subsample_name), prior_shape, prior_variance, + move(options_list), mod_file->symbol_table)); options_list.clear(); set_prior_variance(); prior_shape = PriorDistributions::noShape; @@ -1935,8 +1985,8 @@ ParsingDriver::set_std_options(string name, string subsample_name) { check_symbol_is_endogenous_or_exogenous(name, false); check_subsample_declaration_exists(name, subsample_name); - mod_file->addStatement(make_unique(move(name), move(subsample_name), - move(options_list), mod_file->symbol_table)); + mod_file->addStatement(make_unique( + move(name), move(subsample_name), move(options_list), mod_file->symbol_table)); options_list.clear(); } @@ -1946,9 +1996,9 @@ ParsingDriver::set_corr_prior(string name1, string name2, string subsample_name) check_symbol_is_endogenous_or_exogenous(name1, false); check_symbol_is_endogenous_or_exogenous(name2, false); check_subsample_declaration_exists(name1, name2, subsample_name); - mod_file->addStatement(make_unique(move(name1), move(name2), - move(subsample_name), prior_shape, prior_variance, - move(options_list), mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(name1), move(name2), move(subsample_name), prior_shape, + prior_variance, move(options_list), mod_file->symbol_table)); options_list.clear(); set_prior_variance(); prior_shape = PriorDistributions::noShape; @@ -1960,9 +2010,8 @@ ParsingDriver::set_corr_options(string name1, string name2, string subsample_nam check_symbol_is_endogenous_or_exogenous(name1, false); check_symbol_is_endogenous_or_exogenous(name2, false); check_subsample_declaration_exists(name1, name2, subsample_name); - mod_file->addStatement(make_unique(move(name1), move(name2), - move(subsample_name), move(options_list), - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + move(name1), move(name2), move(subsample_name), move(options_list), mod_file->symbol_table)); options_list.clear(); } @@ -1989,7 +2038,7 @@ ParsingDriver::check_varobs() } void -ParsingDriver::add_varobs(const string &name) +ParsingDriver::add_varobs(const string& name) { check_symbol_is_endogenous(name); int symb_id = mod_file->symbol_table.getID(name); @@ -2004,7 +2053,7 @@ ParsingDriver::check_varexobs() } void -ParsingDriver::add_varexobs(const string &name) +ParsingDriver::add_varexobs(const string& name) { check_symbol_existence(name); int symb_id = mod_file->symbol_table.getID(name); @@ -2016,16 +2065,16 @@ ParsingDriver::add_varexobs(const string &name) void ParsingDriver::set_trends() { - mod_file->addStatement(make_unique(move(trend_elements), - mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(trend_elements), mod_file->symbol_table)); trend_elements.clear(); } void ParsingDriver::set_deterministic_trends() { - mod_file->addStatement(make_unique(move(trend_elements), - mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(trend_elements), mod_file->symbol_table)); trend_elements.clear(); } @@ -2041,34 +2090,35 @@ ParsingDriver::set_trend_element(string arg1, expr_t arg2) void ParsingDriver::set_filter_initial_state() { - mod_file->addStatement(make_unique(move(filter_initial_state_elements), - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + move(filter_initial_state_elements), mod_file->symbol_table)); filter_initial_state_elements.clear(); } void -ParsingDriver::set_filter_initial_state_element(const string &name, const string &lag, expr_t rhs) +ParsingDriver::set_filter_initial_state_element(const string& name, const string& lag, expr_t rhs) { check_symbol_existence(name); int symb_id = mod_file->symbol_table.getID(name); SymbolType type = mod_file->symbol_table.getType(symb_id); int ilag = stoi(lag); - if (type != SymbolType::endogenous - && type != SymbolType::exogenous + if (type != SymbolType::endogenous && type != SymbolType::exogenous && type != SymbolType::exogenousDet) error("filter_initial_state: " + name + " should be an endogenous or exogenous variable"); if ((type == SymbolType::exogenous || type == SymbolType::exogenousDet) && ilag == 0) error("filter_initial_state: exogenous variable " + name + " must be provided with a lag"); - if (filter_initial_state_elements.contains({ symb_id, ilag })) + if (filter_initial_state_elements.contains({symb_id, ilag})) error("filter_initial_state: (" + name + ", " + lag + ") declared twice"); if (mod_file->dynamic_model.minLagForSymbol(symb_id) > ilag - 1) - error("filter_initial_state: variable " + name + " does not appear in the model with the lag " + to_string(ilag-1) + " (see the reference manual for the timing convention in 'filter_initial_state')"); + error("filter_initial_state: variable " + name + " does not appear in the model with the lag " + + to_string(ilag - 1) + + " (see the reference manual for the timing convention in 'filter_initial_state')"); - filter_initial_state_elements[{ symb_id, ilag }] = rhs; + filter_initial_state_elements[{symb_id, ilag}] = rhs; } void @@ -2081,16 +2131,15 @@ ParsingDriver::set_optim_weights(string name, expr_t value) } void -ParsingDriver::set_optim_weights(const string &name1, const string &name2, expr_t value) +ParsingDriver::set_optim_weights(const string& name1, const string& name2, expr_t value) { check_symbol_is_endogenous(name1); check_symbol_is_endogenous(name2); - pair covar_key{name1, name2}; + pair covar_key {name1, name2}; if (covar_weights.contains(covar_key)) - error("optim_weights: pair of variables (" + name1 + ", " + name2 - + ") declared twice"); + error("optim_weights: pair of variables (" + name1 + ", " + name2 + ") declared twice"); covar_weights[covar_key] = value; } @@ -2107,35 +2156,37 @@ ParsingDriver::optim_weights() void ParsingDriver::set_osr_params(vector symbol_list) { - mod_file->addStatement(make_unique(move(symbol_list), mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(symbol_list), mod_file->symbol_table)); } void ParsingDriver::run_osr(vector symbol_list) { - mod_file->addStatement(make_unique(move(symbol_list), move(options_list), - mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(symbol_list), move(options_list), mod_file->symbol_table)); options_list.clear(); } void ParsingDriver::run_dynatype(string filename, vector symbol_list) { - mod_file->addStatement(make_unique(move(symbol_list), move(filename), - mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(symbol_list), move(filename), mod_file->symbol_table)); } void ParsingDriver::run_dynasave(string filename, vector symbol_list) { - mod_file->addStatement(make_unique(move(symbol_list), move(filename), - mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(symbol_list), move(filename), mod_file->symbol_table)); } void -ParsingDriver::run_load_params_and_steady_state(const string &filename) +ParsingDriver::run_load_params_and_steady_state(const string& filename) { - mod_file->addStatement(make_unique(filename, mod_file->symbol_table, warnings)); + mod_file->addStatement( + make_unique(filename, mod_file->symbol_table, warnings)); } void @@ -2154,7 +2205,7 @@ ParsingDriver::run_identification() void ParsingDriver::add_mc_filename(string filename, string prior) { - for (auto &it : filename_list) + for (auto& it : filename_list) if (it.first == filename) error("model_comparison: filename " + filename + " declared twice"); filename_list.emplace_back(move(filename), move(prior)); @@ -2163,8 +2214,8 @@ ParsingDriver::add_mc_filename(string filename, string prior) void ParsingDriver::run_model_comparison() { - mod_file->addStatement(make_unique(move(filename_list), - move(options_list))); + mod_file->addStatement( + make_unique(move(filename_list), move(options_list))); filename_list.clear(); options_list.clear(); } @@ -2172,8 +2223,7 @@ ParsingDriver::run_model_comparison() void ParsingDriver::begin_planner_objective() { - planner_objective = make_unique(mod_file->symbol_table, - mod_file->num_constants, + planner_objective = make_unique(mod_file->symbol_table, mod_file->num_constants, mod_file->external_functions_table); set_current_data_tree(planner_objective.get()); } @@ -2190,7 +2240,7 @@ ParsingDriver::end_planner_objective(expr_t expr) // Handle undeclared variables (see #81) bool exit_after_write = false; if (undeclared_model_variable_errors.size() > 0) - for (auto &it : undeclared_model_variable_errors) + for (auto& it : undeclared_model_variable_errors) { if (nostrict) warning(it.second); @@ -2225,11 +2275,12 @@ ParsingDriver::ramsey_model() init_param("optimal_policy_discount_factor", planner_discount); } else if (planner_discount) - error("ramsey_model: the 'planner_discount' option cannot be used when the 'optimal_policy_discount_factor' parameter is explicitly declared."); + error("ramsey_model: the 'planner_discount' option cannot be used when the " + "'optimal_policy_discount_factor' parameter is explicitly declared."); // Check that instruments are declared endogenous (#72) if (options_list.contains("instruments")) - for (const auto &s : options_list.get("instruments").getSymbols()) + for (const auto& s : options_list.get("instruments").getSymbols()) check_symbol_is_endogenous(s); mod_file->addStatement(make_unique(move(options_list))); @@ -2241,7 +2292,8 @@ ParsingDriver::ramsey_model() void ParsingDriver::ramsey_policy(vector symbol_list) { - warning("The 'ramsey_policy' statement is deprecated. Please use 'ramsey_model', 'stoch_simul', and 'evaluate_planner_objective' instead."); + warning("The 'ramsey_policy' statement is deprecated. Please use 'ramsey_model', 'stoch_simul', " + "and 'evaluate_planner_objective' instead."); // Some checks to ensure correct error messages (see #90) if (ramsey_model_seen) @@ -2258,11 +2310,12 @@ ParsingDriver::ramsey_policy(vector symbol_list) init_param("optimal_policy_discount_factor", planner_discount); } else if (planner_discount) - error("ramsey_policy: the 'planner_discount' option cannot be used when the 'optimal_policy_discount_factor' parameter is explicitly declared."); + error("ramsey_policy: the 'planner_discount' option cannot be used when the " + "'optimal_policy_discount_factor' parameter is explicitly declared."); // Check that instruments are declared endogenous (#72) if (options_list.contains("instruments")) - for (const auto &s : options_list.get("instruments").getSymbols()) + for (const auto& s : options_list.get("instruments").getSymbols()) check_symbol_is_endogenous(s); mod_file->addStatement(make_unique(move(symbol_list), move(options_list), @@ -2321,12 +2374,11 @@ ParsingDriver::discretionary_policy(vector symbol_list) // Check that instruments are declared endogenous (#72) if (options_list.contains("instruments")) - for (const auto &s : options_list.get("instruments").getSymbols()) + for (const auto& s : options_list.get("instruments").getSymbols()) check_symbol_is_endogenous(s); - mod_file->addStatement(make_unique(move(symbol_list), - move(options_list), - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + move(symbol_list), move(options_list), mod_file->symbol_table)); options_list.clear(); planner_discount = nullptr; } @@ -2334,43 +2386,47 @@ ParsingDriver::discretionary_policy(vector symbol_list) void ParsingDriver::write_latex_dynamic_model(bool write_equation_tags) { - mod_file->addStatement(make_unique(mod_file->dynamic_model, write_equation_tags)); + mod_file->addStatement( + make_unique(mod_file->dynamic_model, write_equation_tags)); } void ParsingDriver::write_latex_static_model(bool write_equation_tags) { - mod_file->addStatement(make_unique(mod_file->static_model, write_equation_tags)); + mod_file->addStatement( + make_unique(mod_file->static_model, write_equation_tags)); } void ParsingDriver::write_latex_original_model(bool write_equation_tags) { - mod_file->addStatement(make_unique(mod_file->original_model, write_equation_tags)); + mod_file->addStatement( + make_unique(mod_file->original_model, write_equation_tags)); } void ParsingDriver::write_latex_steady_state_model() { - mod_file->addStatement(make_unique(mod_file->steady_state_model)); + mod_file->addStatement( + make_unique(mod_file->steady_state_model)); } void -ParsingDriver::bvar_density(const string &maxnlags) +ParsingDriver::bvar_density(const string& maxnlags) { mod_file->addStatement(make_unique(stoi(maxnlags), move(options_list))); options_list.clear(); } void -ParsingDriver::bvar_forecast(const string &nlags) +ParsingDriver::bvar_forecast(const string& nlags) { mod_file->addStatement(make_unique(stoi(nlags), move(options_list))); options_list.clear(); } void -ParsingDriver::bvar_irf(const string &nirf, string identificationname) +ParsingDriver::bvar_irf(const string& nirf, string identificationname) { mod_file->addStatement(make_unique(stoi(nirf), move(identificationname))); } @@ -2436,8 +2492,8 @@ void ParsingDriver::svar() { bool has_coefficients = options_list.contains("ms.coefficients"), - has_variances = options_list.contains("ms.variances"), - has_constants = options_list.contains("ms.constants"); + has_variances = options_list.contains("ms.variances"), + has_constants = options_list.contains("ms.constants"); if (!has_coefficients && !has_variances && !has_constants) error("You must pass one of 'coefficients', 'variances', or 'constants'."); @@ -2450,7 +2506,7 @@ ParsingDriver::svar() if (stoi(options_list.get("ms.chain")) <= 0) error("The value passed to the 'chain' option must be greater than zero."); } - catch (OptionsList::UnknownOptionException &) + catch (OptionsList::UnknownOptionException&) { error("A 'chain' option must be passed to the 'svar' statement."); } @@ -2475,9 +2531,10 @@ ParsingDriver::markov_switching() error("The value passed to the number_of_regimes option must be greater than zero."); options_list.get("ms.duration"); // Just check its presence } - catch (OptionsList::UnknownOptionException &e) + catch (OptionsList::UnknownOptionException& e) { - error("A '" + e.name.substr(3) + "' option must be passed to the 'markov_switching' statement."); + error("A '" + e.name.substr(3) + + "' option must be passed to the 'markov_switching' statement."); } mod_file->addStatement(make_unique(move(options_list))); @@ -2487,44 +2544,40 @@ ParsingDriver::markov_switching() void ParsingDriver::shock_decomposition(vector symbol_list) { - mod_file->addStatement(make_unique(move(symbol_list), - move(options_list), - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + move(symbol_list), move(options_list), mod_file->symbol_table)); options_list.clear(); } void ParsingDriver::realtime_shock_decomposition(vector symbol_list) { - mod_file->addStatement(make_unique(move(symbol_list), - move(options_list), - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + move(symbol_list), move(options_list), mod_file->symbol_table)); options_list.clear(); } void ParsingDriver::plot_shock_decomposition(vector symbol_list) { - mod_file->addStatement(make_unique(move(symbol_list), - move(options_list), - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + move(symbol_list), move(options_list), mod_file->symbol_table)); options_list.clear(); } void ParsingDriver::initial_condition_decomposition(vector symbol_list) { - mod_file->addStatement(make_unique(move(symbol_list), - move(options_list), - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + move(symbol_list), move(options_list), mod_file->symbol_table)); options_list.clear(); } void ParsingDriver::squeeze_shock_decomposition(vector symbol_list) { - mod_file->addStatement(make_unique(move(symbol_list), - mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(symbol_list), mod_file->symbol_table)); } void @@ -2535,20 +2588,21 @@ ParsingDriver::conditional_forecast() } void -ParsingDriver::plot_conditional_forecast(const optional &periods, vector symbol_list) +ParsingDriver::plot_conditional_forecast(const optional& periods, + vector symbol_list) { optional iperiods; if (periods) iperiods = stoi(*periods); - mod_file->addStatement(make_unique(move(iperiods), move(symbol_list), - mod_file->symbol_table)); + mod_file->addStatement(make_unique( + move(iperiods), move(symbol_list), mod_file->symbol_table)); } void ParsingDriver::conditional_forecast_paths() { - mod_file->addStatement(make_unique(move(det_shocks), - mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(det_shocks), mod_file->symbol_table)); det_shocks.clear(); if (!learnt_shocks_add.empty()) error("conditional_forecast_paths: 'add' keyword not allowed"); @@ -2576,7 +2630,7 @@ ParsingDriver::add_model_equal(expr_t arg1, expr_t arg2, map eq_ { expr_t id = model_tree->AddEqual(arg1, arg2); - for (const auto &[key, value] : eq_tags) + for (const auto& [key, value] : eq_tags) if (key == "endogenous") declare_or_change_type(SymbolType::endogenous, value); @@ -2584,7 +2638,8 @@ ParsingDriver::add_model_equal(expr_t arg1, expr_t arg2, map eq_ { // If the equation is tagged [static] if (!id->isInStaticForm()) - error("An equation tagged [static] cannot contain leads, lags, expectations or STEADY_STATE operators"); + error("An equation tagged [static] cannot contain leads, lags, expectations or " + "STEADY_STATE operators"); dynamic_model->addStaticOnlyEquation(id, location.begin.line, eq_tags); } @@ -2596,27 +2651,33 @@ ParsingDriver::add_model_equal(expr_t arg1, expr_t arg2, map eq_ auto regimes_bind = DataTree::strsplit(eq_tags["bind"], ','); auto regimes_relax = DataTree::strsplit(eq_tags["relax"], ','); auto regimes_all = regimes_bind; - regimes_all.insert(regimes_all.end(), regimes_relax.begin(), regimes_relax.end()); // Concatenate the two vectors - for (const auto ®ime : regimes_all) + regimes_all.insert(regimes_all.end(), regimes_relax.begin(), + regimes_relax.end()); // Concatenate the two vectors + for (const auto& regime : regimes_all) { if (!isSymbolIdentifier(regime)) - error("The string '" + regime + "' is not a valid Occbin regime name (contains unauthorized characters)"); + error("The string '" + regime + + "' is not a valid Occbin regime name (contains unauthorized characters)"); string param_name = buildOccbinBindParamName(regime); try { if (mod_file->symbol_table.getType(param_name) != SymbolType::parameter) - error("The name '" + param_name + "' is already used. Please use another name for Occbin regime '" + regime + "'"); + error("The name '" + param_name + + "' is already used. Please use another name for Occbin regime '" + regime + + "'"); } - catch (SymbolTable::UnknownSymbolNameException &e) + catch (SymbolTable::UnknownSymbolNameException& e) { // Declare and initialize the new parameter int symb_id = mod_file->symbol_table.addSymbol(param_name, SymbolType::parameter); - mod_file->addStatement(make_unique(symb_id, dynamic_model->Zero, mod_file->symbol_table)); + mod_file->addStatement(make_unique(symb_id, dynamic_model->Zero, + mod_file->symbol_table)); } } eq_tags.erase("bind"); eq_tags.erase("relax"); - dynamic_model->addOccbinEquation(id, location.begin.line, move(eq_tags), regimes_bind, regimes_relax); + dynamic_model->addOccbinEquation(id, location.begin.line, move(eq_tags), regimes_bind, + regimes_relax); } else // General case model_tree->addEquation(id, location.begin.line, move(eq_tags)); @@ -2631,59 +2692,61 @@ ParsingDriver::add_model_equal_with_zero_rhs(expr_t arg, map eq_ } void -ParsingDriver::model_local_variable(const vector> &symbol_list) +ParsingDriver::model_local_variable(const vector>& symbol_list) { - for (auto &[name, tex_name] : symbol_list) + for (auto& [name, tex_name] : symbol_list) declare_symbol(name, SymbolType::modelLocalVariable, tex_name, {}); } void -ParsingDriver::declare_and_init_model_local_variable(const string &name, expr_t rhs) +ParsingDriver::declare_and_init_model_local_variable(const string& name, expr_t rhs) { int symb_id; try { symb_id = mod_file->symbol_table.addSymbol(name, SymbolType::modelLocalVariable); } - catch (SymbolTable::AlreadyDeclaredException &e) + catch (SymbolTable::AlreadyDeclaredException& e) { /* It can have already been declared in a steady_state_model block or model_local_variable statement, check that it is indeed a ModelLocalVariable */ symb_id = mod_file->symbol_table.getID(name); if (mod_file->symbol_table.getType(symb_id) != SymbolType::modelLocalVariable) - error(name + " has wrong type or was already used on the right-hand side. You cannot use it on the left-hand side of a pound ('#') expression"); + error(name + + " has wrong type or was already used on the right-hand side. You cannot use it on " + "the left-hand side of a pound ('#') expression"); } try { model_tree->AddLocalVariable(symb_id, rhs); } - catch (DataTree::LocalVariableException &e) + catch (DataTree::LocalVariableException& e) { error("Local model variable " + name + " declared twice."); } } void -ParsingDriver::change_type(SymbolType new_type, const vector &symbol_list) +ParsingDriver::change_type(SymbolType new_type, const vector& symbol_list) { - for (auto &it : symbol_list) + for (auto& it : symbol_list) { int id; try { id = mod_file->symbol_table.getID(it); } - catch (SymbolTable::UnknownSymbolNameException &e) + catch (SymbolTable::UnknownSymbolNameException& e) { error("Unknown variable " + it); } // Check if symbol already used in a VariableNode - if (mod_file->expressions_tree.isSymbolUsed(id) - || mod_file->dynamic_model.isSymbolUsed(id)) - error("You cannot modify the type of symbol " + it + " after having used it in an expression"); + if (mod_file->expressions_tree.isSymbolUsed(id) || mod_file->dynamic_model.isSymbolUsed(id)) + error("You cannot modify the type of symbol " + it + + " after having used it in an expression"); mod_file->symbol_table.changeType(id, new_type); } @@ -2769,7 +2832,7 @@ ParsingDriver::add_power(expr_t arg1, expr_t arg2) } expr_t -ParsingDriver::add_expectation(const string &arg1, expr_t arg2) +ParsingDriver::add_expectation(const string& arg1, expr_t arg2) { if (data_tree == occbin_constraints_tree.get()) error("The 'expectation' operator is forbidden in 'occbin_constraints'."); @@ -2778,7 +2841,7 @@ ParsingDriver::add_expectation(const string &arg1, expr_t arg2) } expr_t -ParsingDriver::add_var_expectation(const string &model_name) +ParsingDriver::add_var_expectation(const string& model_name) { if (data_tree == occbin_constraints_tree.get()) error("The 'var_expectation' operator is forbidden in 'occbin_constraints'."); @@ -2787,7 +2850,7 @@ ParsingDriver::add_var_expectation(const string &model_name) } expr_t -ParsingDriver::add_pac_expectation(const string &model_name) +ParsingDriver::add_pac_expectation(const string& model_name) { if (data_tree == occbin_constraints_tree.get()) error("The 'pac_expectation' operator is forbidden in 'occbin_constraints'."); @@ -2796,7 +2859,7 @@ ParsingDriver::add_pac_expectation(const string &model_name) } expr_t -ParsingDriver::add_pac_target_nonstationary(const string &model_name) +ParsingDriver::add_pac_target_nonstationary(const string& model_name) { if (data_tree == occbin_constraints_tree.get()) error("The 'pac_target_nonstationary' operator is forbidden in 'occbin_constraints'."); @@ -2820,12 +2883,13 @@ ParsingDriver::pac_model() { auto discount {options_list.get("pac.discount")}; check_symbol_is_parameter(discount); - mod_file->pac_model_table.addPacModel(options_list.get("pac.model_name"), - options_list.get_if("pac.aux_model_name").value_or(OptionsList::StringVal{}), - move(discount), pac_growth, - pac_auxname, pac_kind); + mod_file->pac_model_table.addPacModel( + options_list.get("pac.model_name"), + options_list.get_if("pac.aux_model_name") + .value_or(OptionsList::StringVal {}), + move(discount), pac_growth, pac_auxname, pac_kind); } - catch (OptionsList::UnknownOptionException &e) + catch (OptionsList::UnknownOptionException& e) { error("You must pass the '" + e.name.substr(4) + "' option to the 'pac_model' statement."); } @@ -2866,7 +2930,7 @@ ParsingDriver::add_diff(expr_t arg1) } expr_t -ParsingDriver::add_adl(expr_t arg1, const string &name, const string &lag) +ParsingDriver::add_adl(expr_t arg1, const string& name, const string& lag) { vector lags(stoi(lag)); iota(lags.begin(), lags.end(), 1); @@ -2874,7 +2938,7 @@ ParsingDriver::add_adl(expr_t arg1, const string &name, const string &lag) } expr_t -ParsingDriver::add_adl(expr_t arg1, const string &name, const vector &lags) +ParsingDriver::add_adl(expr_t arg1, const string& name, const vector& lags) { expr_t id = data_tree->AddAdl(arg1, name, lags); @@ -3052,19 +3116,21 @@ ParsingDriver::add_steady_state(expr_t arg1) } void -ParsingDriver::external_function_option(const string &name_option, const string &opt) +ParsingDriver::external_function_option(const string& name_option, const string& opt) { if (name_option == "name") { if (opt.empty()) - error("An argument must be passed to the 'name' option of the external_function() statement."); + error("An argument must be passed to the 'name' option of the external_function() " + "statement."); declare_symbol(opt, SymbolType::externalFunction, "", {}); current_external_function_id = mod_file->symbol_table.getID(opt); } else if (name_option == "first_deriv_provided") { if (opt.empty()) - current_external_function_options.firstDerivSymbID = ExternalFunctionsTable::IDSetButNoNameProvided; + current_external_function_options.firstDerivSymbID + = ExternalFunctionsTable::IDSetButNoNameProvided; else { int symb_id = declare_symbol(opt, SymbolType::externalFunction, "", {}); @@ -3074,7 +3140,8 @@ ParsingDriver::external_function_option(const string &name_option, const string else if (name_option == "second_deriv_provided") { if (opt.empty()) - current_external_function_options.secondDerivSymbID = ExternalFunctionsTable::IDSetButNoNameProvided; + current_external_function_options.secondDerivSymbID + = ExternalFunctionsTable::IDSetButNoNameProvided; else { int symb_id = declare_symbol(opt, SymbolType::externalFunction, "", {}); @@ -3084,7 +3151,8 @@ ParsingDriver::external_function_option(const string &name_option, const string else if (name_option == "nargs") current_external_function_options.nargs = stoi(opt); else - error("Unexpected error in ParsingDriver::external_function_option(): Please inform Dynare Team."); + error("Unexpected error in ParsingDriver::external_function_option(): Please inform Dynare " + "Team."); } void @@ -3095,13 +3163,18 @@ ParsingDriver::external_function() if (current_external_function_options.secondDerivSymbID >= 0 && current_external_function_options.firstDerivSymbID == ExternalFunctionsTable::IDNotSet) - error("If the second derivative is provided to the external_function command, the first derivative must also be provided."); + error("If the second derivative is provided to the external_function command, the first " + "derivative must also be provided."); - if (current_external_function_options.secondDerivSymbID == ExternalFunctionsTable::IDSetButNoNameProvided - && current_external_function_options.firstDerivSymbID != ExternalFunctionsTable::IDSetButNoNameProvided) - error("If the second derivative is provided in the top-level function, the first derivative must also be provided in that function."); + if (current_external_function_options.secondDerivSymbID + == ExternalFunctionsTable::IDSetButNoNameProvided + && current_external_function_options.firstDerivSymbID + != ExternalFunctionsTable::IDSetButNoNameProvided) + error("If the second derivative is provided in the top-level function, the first derivative " + "must also be provided in that function."); - mod_file->external_functions_table.addExternalFunction(current_external_function_id, current_external_function_options, true); + mod_file->external_functions_table.addExternalFunction(current_external_function_id, + current_external_function_options, true); reset_current_external_function_options(); } @@ -3123,8 +3196,8 @@ ParsingDriver::is_there_one_integer_argument() const if (stack_external_function_args.top().size() != 1) return nullopt; - auto numNode = dynamic_cast(stack_external_function_args.top().front()); - auto unaryNode = dynamic_cast(stack_external_function_args.top().front()); + auto numNode = dynamic_cast(stack_external_function_args.top().front()); + auto unaryNode = dynamic_cast(stack_external_function_args.top().front()); if (!numNode && !unaryNode) return nullopt; @@ -3137,25 +3210,24 @@ ParsingDriver::is_there_one_integer_argument() const { model_var_arg = numNode->eval(ectmp); } - catch (ExprNode::EvalException &e) + catch (ExprNode::EvalException& e) { return nullopt; } } + else if (unaryNode->op_code != UnaryOpcode::uminus) + return nullopt; else - if (unaryNode->op_code != UnaryOpcode::uminus) - return nullopt; - else - { - try - { - model_var_arg = unaryNode->eval(ectmp); - } - catch (ExprNode::EvalException &e) - { - return nullopt; - } - } + { + try + { + model_var_arg = unaryNode->eval(ectmp); + } + catch (ExprNode::EvalException& e) + { + return nullopt; + } + } if (model_var_arg != floor(model_var_arg)) return nullopt; @@ -3163,7 +3235,7 @@ ParsingDriver::is_there_one_integer_argument() const } expr_t -ParsingDriver::add_model_var_or_external_function(const string &function_name, bool in_model_block) +ParsingDriver::add_model_var_or_external_function(const string& function_name, bool in_model_block) { expr_t nid; if (mod_file->symbol_table.exists(function_name)) @@ -3180,34 +3252,42 @@ ParsingDriver::add_model_var_or_external_function(const string &function_name, b if (undeclared_model_vars.contains(function_name)) undeclared_model_variable_error("Unknown symbol: " + function_name, function_name); - optional rv{is_there_one_integer_argument()}; + optional rv {is_there_one_integer_argument()}; if (!rv) model_error("Symbol " + function_name - +" is being treated as if it were a function (i.e., takes an argument that is not an integer).", ""); + + " is being treated as if it were a function (i.e., takes an argument " + "that is not an integer).", + ""); nid = add_model_variable(mod_file->symbol_table.getID(function_name), *rv); stack_external_function_args.pop(); return nid; } else - { // e.g. this function has already been referenced (either ad hoc or through the external_function() statement + { // e.g. this function has already been referenced (either ad hoc or through the + // external_function() statement // => check that the information matches previously declared info int symb_id = mod_file->symbol_table.getID(function_name); if (!mod_file->external_functions_table.exists(symb_id)) - error("Using a derivative of an external function (" + function_name + ") in the model block is currently not allowed."); + error("Using a derivative of an external function (" + function_name + + ") in the model block is currently not allowed."); if (in_model_block || parsing_epilogue) { - if (mod_file->external_functions_table.getNargs(symb_id) == ExternalFunctionsTable::IDNotSet) + if (mod_file->external_functions_table.getNargs(symb_id) + == ExternalFunctionsTable::IDNotSet) error("Before using " + function_name - +"() in the model block, you must first declare it via the external_function() statement"); - else if (static_cast(stack_external_function_args.top().size()) != mod_file->external_functions_table.getNargs(symb_id)) - error("The number of arguments passed to " + function_name - +"() does not match those of a previous call or declaration of this function."); + + "() in the model block, you must first declare it via the " + "external_function() statement"); + else if (static_cast(stack_external_function_args.top().size()) + != mod_file->external_functions_table.getNargs(symb_id)) + error( + "The number of arguments passed to " + function_name + + "() does not match those of a previous call or declaration of this function."); } } else - { //First time encountering this external function i.e., not previously declared or encountered + { // First time encountering this external function i.e., not previously declared or encountered if (parsing_epilogue) error("Variable " + function_name + " used in the epilogue block but was not declared."); @@ -3218,7 +3298,7 @@ ParsingDriver::add_model_var_or_external_function(const string &function_name, b undeclared_model_vars.insert(function_name); undeclared_model_variable_error("Unknown symbol: " + function_name, function_name); - optionalrv{is_there_one_integer_argument()}; + optional rv {is_there_one_integer_argument()}; if (rv) { // assume it's a lead/lagged variable @@ -3227,16 +3307,18 @@ ParsingDriver::add_model_var_or_external_function(const string &function_name, b } else error("To use an external function (" + function_name - +") within the model block, you must first declare it via the external_function() statement."); + + ") within the model block, you must first declare it via the " + "external_function() statement."); } int symb_id = declare_symbol(function_name, SymbolType::externalFunction, "", {}); current_external_function_options.nargs = stack_external_function_args.top().size(); - mod_file->external_functions_table.addExternalFunction(symb_id, - current_external_function_options, in_model_block); + mod_file->external_functions_table.addExternalFunction( + symb_id, current_external_function_options, in_model_block); reset_current_external_function_options(); } - //By this point, we're sure that this function exists in the External Functions Table and is not a mod var + // By this point, we're sure that this function exists in the External Functions Table and is not + // a mod var int symb_id = mod_file->symbol_table.getID(function_name); nid = data_tree->AddExternalFunction(symb_id, stack_external_function_args.top()); stack_external_function_args.pop(); @@ -3254,7 +3336,7 @@ ParsingDriver::add_native_remove_charset(string_view str, string_view token) { size_t found = str.find(token); assert(found != string_view::npos); - add_native(string{str.substr(0, found)}); + add_native(string {str.substr(0, found)}); } void @@ -3268,7 +3350,7 @@ ParsingDriver::add_verbatim_remove_charset(string_view str, string_view token) { size_t found = str.find(token); assert(found != string_view::npos); - add_verbatim(string{str.substr(0, found)}); + add_verbatim(string {str.substr(0, found)}); } void @@ -3278,45 +3360,47 @@ ParsingDriver::begin_steady_state_model() } void -ParsingDriver::add_steady_state_model_equal(const string &varname, expr_t expr) +ParsingDriver::add_steady_state_model_equal(const string& varname, expr_t expr) { int id; try { id = mod_file->symbol_table.getID(varname); } - catch (SymbolTable::UnknownSymbolNameException &e) + catch (SymbolTable::UnknownSymbolNameException& e) { // Unknown symbol, declare it as a ModFileLocalVariable id = mod_file->symbol_table.addSymbol(varname, SymbolType::modFileLocalVariable); } if (SymbolType type = mod_file->symbol_table.getType(id); - type != SymbolType::endogenous && type != SymbolType::modFileLocalVariable && type != SymbolType::parameter) + type != SymbolType::endogenous && type != SymbolType::modFileLocalVariable + && type != SymbolType::parameter) error(varname + " has incorrect type"); mod_file->steady_state_model.addDefinition(id, expr); } void -ParsingDriver::add_steady_state_model_equal_multiple(const vector &symbol_list, expr_t expr) +ParsingDriver::add_steady_state_model_equal_multiple(const vector& symbol_list, expr_t expr) { vector ids; - for (const auto &symb : symbol_list) + for (const auto& symb : symbol_list) { int id; try { id = mod_file->symbol_table.getID(symb); } - catch (SymbolTable::UnknownSymbolNameException &e) + catch (SymbolTable::UnknownSymbolNameException& e) { // Unknown symbol, declare it as a ModFileLocalVariable id = mod_file->symbol_table.addSymbol(symb, SymbolType::modFileLocalVariable); } if (SymbolType type = mod_file->symbol_table.getType(id); - type != SymbolType::endogenous && type != SymbolType::modFileLocalVariable && type != SymbolType::parameter) + type != SymbolType::endogenous && type != SymbolType::modFileLocalVariable + && type != SymbolType::parameter) error(symb + " has incorrect type"); ids.push_back(id); } @@ -3333,21 +3417,23 @@ ParsingDriver::add_graph_format(string name) void ParsingDriver::process_graph_format_option() { - options_list.set("graph_format", OptionsList::SymbolListVal{move(graph_formats)}); + options_list.set("graph_format", OptionsList::SymbolListVal {move(graph_formats)}); graph_formats.clear(); } void ParsingDriver::initial_condition_decomp_process_graph_format_option() { - options_list.set("initial_condition_decomp.graph_format", OptionsList::SymbolListVal{move(graph_formats)}); + options_list.set("initial_condition_decomp.graph_format", + OptionsList::SymbolListVal {move(graph_formats)}); graph_formats.clear(); } void ParsingDriver::plot_shock_decomp_process_graph_format_option() { - options_list.set("plot_shock_decomp.graph_format", OptionsList::SymbolListVal{move(graph_formats)}); + options_list.set("plot_shock_decomp.graph_format", + OptionsList::SymbolListVal {move(graph_formats)}); graph_formats.clear(); } @@ -3364,7 +3450,8 @@ ParsingDriver::add_parallel_local_file(string filename) } void -ParsingDriver::add_moment_calibration_item(const string &endo1, const string &endo2, string lags, const pair &range) +ParsingDriver::add_moment_calibration_item(const string& endo1, const string& endo2, string lags, + const pair& range) { MomentCalibration::Constraint c; @@ -3385,13 +3472,14 @@ ParsingDriver::add_moment_calibration_item(const string &endo1, const string &en void ParsingDriver::end_moment_calibration() { - mod_file->addStatement(make_unique(move(moment_calibration_constraints), - mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(moment_calibration_constraints), mod_file->symbol_table)); moment_calibration_constraints.clear(); } void -ParsingDriver::add_irf_calibration_item(const string &endo, string periods, const string &exo, const pair &range) +ParsingDriver::add_irf_calibration_item(const string& endo, string periods, const string& exo, + const pair& range) { IrfCalibration::Constraint c; @@ -3415,8 +3503,7 @@ void ParsingDriver::end_irf_calibration() { mod_file->addStatement(make_unique(move(irf_calibration_constraints), - mod_file->symbol_table, - move(options_list))); + mod_file->symbol_table, move(options_list))); irf_calibration_constraints.clear(); options_list.clear(); } @@ -3452,14 +3539,16 @@ ParsingDriver::perfect_foresight_solver() void ParsingDriver::perfect_foresight_with_expectation_errors_setup() { - mod_file->addStatement(make_unique(move(options_list))); + mod_file->addStatement( + make_unique(move(options_list))); options_list.clear(); } void ParsingDriver::perfect_foresight_with_expectation_errors_solver() { - mod_file->addStatement(make_unique(move(options_list))); + mod_file->addStatement( + make_unique(move(options_list))); options_list.clear(); } @@ -3481,37 +3570,37 @@ ParsingDriver::prior_posterior_function(bool prior_func) void ParsingDriver::add_ramsey_constraints_statement() { - mod_file->addStatement(make_unique(mod_file->symbol_table, - move(ramsey_constraints))); + mod_file->addStatement( + make_unique(mod_file->symbol_table, move(ramsey_constraints))); ramsey_constraints.clear(); } void -ParsingDriver::ramsey_constraint_add_less(const string &name, const expr_t rhs) +ParsingDriver::ramsey_constraint_add_less(const string& name, const expr_t rhs) { add_ramsey_constraint(name, BinaryOpcode::less, rhs); } void -ParsingDriver::ramsey_constraint_add_greater(const string &name, const expr_t rhs) +ParsingDriver::ramsey_constraint_add_greater(const string& name, const expr_t rhs) { add_ramsey_constraint(name, BinaryOpcode::greater, rhs); } void -ParsingDriver::ramsey_constraint_add_less_equal(const string &name, const expr_t rhs) +ParsingDriver::ramsey_constraint_add_less_equal(const string& name, const expr_t rhs) { add_ramsey_constraint(name, BinaryOpcode::lessEqual, rhs); } void -ParsingDriver::ramsey_constraint_add_greater_equal(const string &name, const expr_t rhs) +ParsingDriver::ramsey_constraint_add_greater_equal(const string& name, const expr_t rhs) { add_ramsey_constraint(name, BinaryOpcode::greaterEqual, rhs); } void -ParsingDriver::add_ramsey_constraint(const string &name, BinaryOpcode op_code, const expr_t rhs) +ParsingDriver::add_ramsey_constraint(const string& name, BinaryOpcode op_code, const expr_t rhs) { check_symbol_is_endogenous(name); int symb_id = mod_file->symbol_table.getID(name); @@ -3554,7 +3643,7 @@ ParsingDriver::end_shock_groups(string name) } void -ParsingDriver::add_init2shocks(const string &endo_name, const string &exo_name) +ParsingDriver::add_init2shocks(const string& endo_name, const string& exo_name) { check_symbol_existence(endo_name); check_symbol_existence(exo_name); @@ -3572,8 +3661,8 @@ ParsingDriver::add_init2shocks(const string &endo_name, const string &exo_name) void ParsingDriver::end_init2shocks(string name) { - mod_file->addStatement(make_unique(move(init2shocks), move(name), - mod_file->symbol_table)); + mod_file->addStatement( + make_unique(move(init2shocks), move(name), mod_file->symbol_table)); init2shocks.clear(); } @@ -3584,40 +3673,42 @@ ParsingDriver::var_expectation_model() { string v {options_list.get("variable")}; if (var_expectation_model_expression) - error("You can't pass both the 'variable' or the 'expression' options to the var_expectation_model statement."); + error("You can't pass both the 'variable' or the 'expression' options to the " + "var_expectation_model statement."); var_expectation_model_expression = data_tree->AddVariable(mod_file->symbol_table.getID(v)); } - catch (OptionsList::UnknownOptionException &) + catch (OptionsList::UnknownOptionException&) { if (!var_expectation_model_expression) - error("You must pass either the 'variable' or the 'expression' option to the var_expectation_model statement."); + error("You must pass either the 'variable' or the 'expression' option to the " + "var_expectation_model statement."); } if (var_expectation_model_discount) { - VariableNode *var; - if (!dynamic_cast(var_expectation_model_discount) - && !((var = dynamic_cast(var_expectation_model_discount)) + VariableNode* var; + if (!dynamic_cast(var_expectation_model_discount) + && !((var = dynamic_cast(var_expectation_model_discount)) && var->get_type() == SymbolType::parameter)) error("The discount factor must be a constant expression or a parameter"); } else var_expectation_model_discount = data_tree->One; - int time_shift { stoi(options_list.get_if("time_shift").value_or(OptionsList::NumVal{"0"})) }; + int time_shift {stoi( + options_list.get_if("time_shift").value_or(OptionsList::NumVal {"0"}))}; if (time_shift > 0) error("The 'time_shift' option must be a non-positive integer"); try { - mod_file->var_expectation_model_table.addVarExpectationModel(options_list.get("model_name"), - var_expectation_model_expression, - options_list.get("auxiliary_model_name"), - options_list.get("horizon"), - var_expectation_model_discount, - time_shift); + mod_file->var_expectation_model_table.addVarExpectationModel( + options_list.get("model_name"), var_expectation_model_expression, + options_list.get("auxiliary_model_name"), + options_list.get("horizon"), var_expectation_model_discount, + time_shift); } - catch (OptionsList::UnknownOptionException &e) + catch (OptionsList::UnknownOptionException& e) { error("You must pass the '" + e.name + "' option to the 'var_expectation_model' statement."); } @@ -3634,7 +3725,7 @@ ParsingDriver::begin_matched_moments() } void -ParsingDriver::end_matched_moments(const vector &moments) +ParsingDriver::end_matched_moments(const vector& moments) { vector, vector, vector>> parsed_moments; for (auto m : moments) @@ -3644,12 +3735,12 @@ ParsingDriver::end_matched_moments(const vector &moments) m->matchMatchedMoment(symb_ids, lags, powers); parsed_moments.emplace_back(move(symb_ids), move(lags), move(powers)); } - catch (ExprNode::MatchFailureException &e) + catch (ExprNode::MatchFailureException& e) { error("Matched moment expression has incorrect format: " + e.message); } - mod_file->addStatement(make_unique(mod_file->symbol_table, - move(parsed_moments))); + mod_file->addStatement( + make_unique(mod_file->symbol_table, move(parsed_moments))); reset_data_tree(); } @@ -3661,18 +3752,17 @@ ParsingDriver::begin_occbin_constraints() and those would trigger the non-linearity warning in a stochastic context if added to the main DynamicModel tree. It also simplifies the enforcement of various constraints at parsing time. */ - occbin_constraints_tree = make_unique(mod_file->symbol_table, - mod_file->num_constants, - mod_file->external_functions_table, - false); + occbin_constraints_tree = make_unique(mod_file->symbol_table, mod_file->num_constants, + mod_file->external_functions_table, false); set_current_data_tree(occbin_constraints_tree.get()); } void -ParsingDriver::end_occbin_constraints(vector> constraints) +ParsingDriver::end_occbin_constraints( + vector> constraints) { // Perform a few checks - for (const auto &[name, bind, relax, error_bind, error_relax] : constraints) + for (const auto& [name, bind, relax, error_bind, error_relax] : constraints) { string param_name = buildOccbinBindParamName(name); if (!mod_file->symbol_table.exists(param_name)) @@ -3681,8 +3771,8 @@ ParsingDriver::end_occbin_constraints(vectoraddStatement(make_unique(*occbin_constraints_tree, - move(constraints))); + mod_file->addStatement( + make_unique(*occbin_constraints_tree, move(constraints))); reset_data_tree(); } @@ -3716,7 +3806,8 @@ void ParsingDriver::add_pac_target_info_component(expr_t component_expr) { get<0>(pac_target_info_component) = component_expr; - mod_file->pac_model_table.addTargetComponent(pac_target_info_name, exchange(pac_target_info_component, {})); + mod_file->pac_model_table.addTargetComponent(pac_target_info_name, + exchange(pac_target_info_component, {})); } void @@ -3738,12 +3829,11 @@ ParsingDriver::set_pac_target_info_component_kind(PacTargetKind kind) } bool -ParsingDriver::isSymbolIdentifier(const string &str) +ParsingDriver::isSymbolIdentifier(const string& str) { if (str.empty()) return false; - auto myisalpha = [](char ch) - { + auto myisalpha = [](char ch) { // We cannot use std::isalpha(), because it is locale-dependent return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); }; @@ -3756,22 +3846,22 @@ ParsingDriver::isSymbolIdentifier(const string &str) } void -ParsingDriver::model_remove(const vector> &listed_eqs_by_tags) +ParsingDriver::model_remove(const vector>& listed_eqs_by_tags) { mod_file->dynamic_model.removeEquations(listed_eqs_by_tags, true, true); } void -ParsingDriver::begin_model_replace(const vector> &listed_eqs_by_tags) +ParsingDriver::begin_model_replace(const vector>& listed_eqs_by_tags) { mod_file->dynamic_model.removeEquations(listed_eqs_by_tags, true, false); set_current_data_tree(&mod_file->dynamic_model); } void -ParsingDriver::var_remove(const vector &symbol_list) +ParsingDriver::var_remove(const vector& symbol_list) { - for (const auto &name : symbol_list) + for (const auto& name : symbol_list) { check_symbol_existence(name); int symb_id = mod_file->symbol_table.getID(name); diff --git a/src/ParsingDriver.hh b/src/ParsingDriver.hh index b945b0d4..3ded45b8 100644 --- a/src/ParsingDriver.hh +++ b/src/ParsingDriver.hh @@ -24,24 +24,24 @@ # error Impossible to include both ParsingDriver.hh and macro/Driver.hh #endif -#include -#include #include -#include #include +#include +#include #include +#include #include "ModFile.hh" #include "SymbolList.hh" class ParsingDriver; -#include "ExprNode.hh" #include "DynareBison.hh" +#include "ExprNode.hh" #include "ComputingTasks.hh" -#include "Shocks.hh" -#include "NumericalInitialization.hh" #include "DynamicModel.hh" +#include "NumericalInitialization.hh" +#include "Shocks.hh" using namespace std; @@ -59,22 +59,21 @@ using namespace std; class DynareFlex : public DynareFlexLexer { public: - DynareFlex(istream *in = nullptr, ostream *out = nullptr); + DynareFlex(istream* in = nullptr, ostream* out = nullptr); - DynareFlex(const DynareFlex &) = delete; - DynareFlex &operator=(const DynareFlex &) = delete; + DynareFlex(const DynareFlex&) = delete; + DynareFlex& operator=(const DynareFlex&) = delete; //! The main lexing function - Dynare::parser::token_type lex(Dynare::parser::semantic_type *yylval, - Dynare::parser::location_type *yylloc, - ParsingDriver &driver); + Dynare::parser::token_type lex(Dynare::parser::semantic_type* yylval, + Dynare::parser::location_type* yylloc, ParsingDriver& driver); //! The filename being parsed /*! The bison parser locations (begin and end) contain a pointer to that string */ string filename; //! Increment the location counter given a token - static void location_increment(Dynare::parser::location_type *yylloc, const char *yytext); + static void location_increment(Dynare::parser::location_type* yylloc, const char* yytext); //! Count parens in dates statement int dates_parens_nb; @@ -86,29 +85,34 @@ class ParsingDriver { private: //! Checks that a given symbol exists, and stops with an error message if it doesn't - void check_symbol_existence(const string &name); + void check_symbol_existence(const string& name); - //! Checks that a given symbol exists and is a parameter, and stops with an error message if it isn't - void check_symbol_is_parameter(const string &name); + //! Checks that a given symbol exists and is a parameter, and stops with an error message if it + //! isn't + void check_symbol_is_parameter(const string& name); //! Checks that a given symbol was assigned within a Statement - void check_symbol_is_statement_variable(const string &name); + void check_symbol_is_statement_variable(const string& name); - //! Checks that a given symbol exists and is a endogenous or exogenous, and stops with an error message if it isn't - void check_symbol_is_endogenous_or_exogenous(const string &name, bool allow_exo_det); + //! Checks that a given symbol exists and is a endogenous or exogenous, and stops with an error + //! message if it isn't + void check_symbol_is_endogenous_or_exogenous(const string& name, bool allow_exo_det); - //! 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); + //! 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); - //! Checks that a given symbol exists and is a exogenous, and stops with an error message if it isn't - void check_symbol_is_exogenous(const string &name, bool allow_exo_det); + //! Checks that a given symbol exists and is a exogenous, and stops with an error message if it + //! isn't + void check_symbol_is_exogenous(const string& name, bool allow_exo_det); - //! 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); + //! 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); //! Helper to add a symbol declaration (returns its symbol ID) - int declare_symbol(const string &name, SymbolType type, const string &tex_name, const vector> &partition_value); + int declare_symbol(const string& name, SymbolType type, const string& tex_name, + const vector>& partition_value); //! Temporary store for the planner objective unique_ptr planner_objective; @@ -119,18 +123,20 @@ private: //! The data tree in which to add expressions currently parsed /*! The object pointed to is not owned by the parsing driver. It is essentially a reference. */ - DataTree *data_tree; + DataTree* data_tree; //! The model tree in which to add expressions currently parsed - /*! It is only a dynamic cast of data_tree pointer, and is therefore null if data_tree is not a ModelTree instance */ - ModelTree *model_tree; + /*! It is only a dynamic cast of data_tree pointer, and is therefore null if data_tree is not a + * ModelTree instance */ + ModelTree* model_tree; //! The dynamic model tree in which to add expressions currently parsed - /*! It is only a dynamic cast of data_tree pointer, and is therefore null if data_tree is not a DynamicModel instance */ - DynamicModel *dynamic_model; + /*! It is only a dynamic cast of data_tree pointer, and is therefore null if data_tree is not a + * DynamicModel instance */ + DynamicModel* dynamic_model; //! Sets data_tree and model_tree pointers - void set_current_data_tree(DataTree *data_tree_arg); + void set_current_data_tree(DataTree* data_tree_arg); //! Stores options lists OptionsList options_list; @@ -163,7 +169,8 @@ private: //! Temporary storage for correlations of shocks ShocksStatement::covar_and_corr_shocks_t corr_shocks; //! Temporary storage for values and scales of heteroskedastic_shocks - HeteroskedasticShocksStatement::heteroskedastic_shocks_t heteroskedastic_shocks_values, heteroskedastic_shocks_scales; + HeteroskedasticShocksStatement::heteroskedastic_shocks_t heteroskedastic_shocks_values, + heteroskedastic_shocks_scales; //! Temporary storage for initval blocks InitOrEndValStatement::init_values_t init_values; /* Temporary storage for endval blocks. Uses a type that encompasses both @@ -181,7 +188,8 @@ private: RamseyConstraintsStatement::constraints_t ramsey_constraints; //! Temporary storage for svar_identification blocks SvarIdentificationStatement::svar_identification_restrictions_t svar_ident_restrictions; - //! Temporary storage for mapping the equation number to the restrictions within an svar_identification block + //! Temporary storage for mapping the equation number to the restrictions within an + //! svar_identification block map> svar_equation_restrictions; //! Temporary storage for constants exculsion within an svar_identification bool svar_constants_exclusion; @@ -191,7 +199,8 @@ private: bool svar_lower_cholesky; //! Temporary storage for equation number for a restriction within an svar_identification block int svar_equation_nbr; - //! Temporary storage for left/right handside of a restriction equation within an svar_identificaton block + //! Temporary storage for left/right handside of a restriction equation within an + //! svar_identificaton block bool svar_left_handside; //! Temporary storage for current restriction number in svar_identification block map svar_Qi_restriction_nbr; @@ -200,11 +209,11 @@ private: set undeclared_model_vars; //! Temporary storage for restriction type enum class SvarRestrictionType - { - NOT_SET, - Qi_TYPE, - Ri_TYPE - }; + { + NOT_SET, + Qi_TYPE, + Ri_TYPE + }; SvarRestrictionType svar_restriction_type; //! Temporary storage for generate_irfs vector generate_irf_names; @@ -214,15 +223,18 @@ private: stack> stack_external_function_args; //! Temporary storage for parameters in joint prior statement vector joint_parameters; - //! Temporary storage for the symb_id associated with the "name" symbol of the current external_function statement + //! Temporary storage for the symb_id associated with the "name" symbol of the current + //! external_function statement int current_external_function_id; //! Temporary storage for option list provided to external_function() ExternalFunctionsTable::external_function_options current_external_function_options; //! Temporary storage for a variance declared in the prior statement expr_t prior_variance; SubsamplesStatement::subsample_declaration_map_t subsample_declaration_map; - //! Temporary storage for subsample statement: map>, subsample_declaration_map > - using subsample_declarations_t = map, SubsamplesStatement::subsample_declaration_map_t >; + //! Temporary storage for subsample statement: map>, + //! subsample_declaration_map > + using subsample_declarations_t + = map, SubsamplesStatement::subsample_declaration_map_t>; subsample_declarations_t subsample_declarations; //! Temporary storage for shock_groups vector shock_group; @@ -231,7 +243,7 @@ private: vector> init2shocks; /* Temporary storage for planner_discount and planner_discount_latex_name options of ramsey_model and ramsey_policy */ - expr_t planner_discount{nullptr}; + expr_t planner_discount {nullptr}; string planner_discount_latex_name; //! reset the values for temporary storage void reset_current_external_function_options(); @@ -246,7 +258,7 @@ private: //! The mod file representation constructed by this ParsingDriver unique_ptr mod_file; - WarningConsolidation &warnings; + WarningConsolidation& warnings; //! Temporary storage for several options of pac_model expr_t pac_growth; @@ -259,27 +271,27 @@ private: vector> undeclared_model_variable_errors; //! True when parsing the epilogue block - bool parsing_epilogue{false}; + bool parsing_epilogue {false}; //! True when parsing pac_model statement - bool parsing_pac_model{false}; + bool parsing_pac_model {false}; //! True if a ramsey_model statement has already been seen - bool ramsey_model_seen{false}; + bool ramsey_model_seen {false}; //! True if a ramsey_policy statement has already been seen - bool ramsey_policy_seen{false}; + bool ramsey_policy_seen {false}; public: - ParsingDriver(WarningConsolidation &warnings_arg, bool nostrict_arg) : - warnings{warnings_arg}, nostrict{nostrict_arg} + ParsingDriver(WarningConsolidation& warnings_arg, bool nostrict_arg) : + warnings {warnings_arg}, nostrict {nostrict_arg} { - }; + } - ParsingDriver(const ParsingDriver &) = delete; - ParsingDriver &operator=(const ParsingDriver &) = delete; + ParsingDriver(const ParsingDriver&) = delete; + ParsingDriver& operator=(const ParsingDriver&) = delete; //! Starts parsing, and constructs the MOD file representation - unique_ptr parse(istream &in, bool debug); + unique_ptr parse(istream& in, bool debug); //! Reference to the lexer unique_ptr lexer; @@ -297,27 +309,30 @@ public: PriorDistributions prior_shape; //! Temporary storage for "expression" option of VAR_EXPECTATION_MODEL - expr_t var_expectation_model_expression{nullptr}; + expr_t var_expectation_model_expression {nullptr}; //! Temporary storage for discount option of VAR_EXPECTATION_MODEL - expr_t var_expectation_model_discount{nullptr}; + expr_t var_expectation_model_discount {nullptr}; //! Error handler with explicit location - void error(const Dynare::parser::location_type &l, const string &m) __attribute__ ((noreturn)); + void error(const Dynare::parser::location_type& l, const string& m) __attribute__((noreturn)); //! Error handler using saved location - void error(const string &m) __attribute__ ((noreturn)); + void error(const string& m) __attribute__((noreturn)); //! Warning handler using saved location - void warning(const string &m); + void warning(const string& m); - //! Error handler with explicit location (used in model block, accumulating error messages to be printed later) - void model_error(const string &m, const string &var); - void undeclared_model_variable_error(const string &m, const string &var); + //! Error handler with explicit location (used in model block, accumulating error messages to be + //! printed later) + void model_error(const string& m, const string& var); + void undeclared_model_variable_error(const string& m, const string& var); //! Code shared between model_error() and error() - void create_error_string(const Dynare::parser::location_type &l, const string &m, const string &var); - void create_error_string(const Dynare::parser::location_type &l, const string &m, ostream &stream); + void create_error_string(const Dynare::parser::location_type& l, const string& m, + const string& var); + void create_error_string(const Dynare::parser::location_type& l, const string& m, + ostream& stream); //! Check if a given symbol exists in the parsing context, and is not a mod file local variable - bool symbol_exists_and_is_not_modfile_local_or_external_function(const string &s); + bool symbol_exists_and_is_not_modfile_local_or_external_function(const string& s); //! Sets mode of ModelTree class to use C output void use_dll(); //! the modelis block decomposed @@ -332,50 +347,55 @@ public: //! the differentiate_forward_vars option is enabled (for a subset of vars) void differentiate_forward_vars_some(vector symbol_list); //! cutoff option of model block - void cutoff(const string &value); + void cutoff(const string& value); //! mfs option of model block - void mfs(const string &value); + void mfs(const string& value); //! static_mfs option of model block - void static_mfs(const string &value); + void static_mfs(const string& value); //! the flags to substitute for the default compiler flags used by `use_dll` - void compilation_setup_substitute_flags(const string &flags); + void compilation_setup_substitute_flags(const string& flags); //! the flags to add to the default compiler flags used by `use_dll` - void compilation_setup_add_flags(const string &flags); + void compilation_setup_add_flags(const string& flags); //! the libs to substitute for the default compiler libs used by `use_dll` - void compilation_setup_substitute_libs(const string &libs); + void compilation_setup_substitute_libs(const string& libs); //! the libs to add to the default compiler libs used by `use_dll` - void compilation_setup_add_libs(const string &libs); + void compilation_setup_add_libs(const string& libs); //! the compiler to replace the default compiler used by `use_dll` - void compilation_setup_compiler(const string &path); + void compilation_setup_compiler(const string& path); //! balanced_growth_test_tol option of model block - void balanced_growth_test_tol(const string &value); + void balanced_growth_test_tol(const string& value); //! Sets the FILENAME for the initial value in initval void initval_file(); //! Declares an endogenous variable (and returns its symbol ID) - int declare_endogenous(const string &name, const string &tex_name = "", const vector> &partition_value = {}); + int declare_endogenous(const string& name, const string& tex_name = "", + const vector>& partition_value = {}); // Handles a “var” or “var(log)” statement (without “deflator” or “log_deflator” options) - void var(const vector>>> &symbol_list, bool log_option); + void var(const vector>>>& symbol_list, + bool log_option); //! Declares an exogenous variable (and returns its symbol ID) - int declare_exogenous(const string &name, const string &tex_name = "", const vector> &partition_value = {}); + int declare_exogenous(const string& name, const string& tex_name = "", + const vector>& partition_value = {}); // Handles a “varexo” statement - void varexo(const vector>>> &symbol_list); + void varexo(const vector>>>& symbol_list); // Handles a “varexo_det” statement - void varexo_det(const vector>>> &symbol_list); + void varexo_det(const vector>>>& symbol_list); //! Declares a parameter (and returns its symbol ID) - int declare_parameter(const string &name, const string &tex_name = "", const vector> &partition_value = {}); + int declare_parameter(const string& name, const string& tex_name = "", + const vector>& partition_value = {}); // Handles a “parameters” statement - void parameters(const vector>>> &symbol_list); + void parameters(const vector>>>& symbol_list); // Handles a “model_local_variable” statement - void model_local_variable(const vector> &symbol_list); + void model_local_variable(const vector>& symbol_list); //! Declares a statement local variable - void declare_statement_local_variable(const string &name); + void declare_statement_local_variable(const string& name); //! Completes a subsample statement void set_subsamples(string name1, string name2); //! Declares a subsample, assigning the value to name void set_subsample_name_equal_to_date_range(string name, string date1, string date2); //! Checks that a subsample statement (and given name) were provided for the pair name1 & name2 - void check_subsample_declaration_exists(const string &name1, const string &subsample_name); - void check_subsample_declaration_exists(const string &name1, const string &name2, const string &subsample_name); + void check_subsample_declaration_exists(const string& name1, const string& subsample_name); + void check_subsample_declaration_exists(const string& name1, const string& name2, + const string& subsample_name); //! Copies the set of subsamples from_name to_name void copy_subsamples(string to_name1, string to_name2, string from_name1, string from_name2); //! Sets the value of the planner_discount option of ramsey_{model,policy} @@ -383,45 +403,45 @@ public: //! Sets the value of the planner_discount_latex_name option of ramsey_model void set_planner_discount_latex_name(string tex_name); //! Handles a “predetermined_variables” statement - void predetermined_variables(const vector &symbol_list); + void predetermined_variables(const vector& symbol_list); //! Declares and initializes a local parameter - void declare_and_init_model_local_variable(const string &name, expr_t rhs); + void declare_and_init_model_local_variable(const string& name, expr_t rhs); //! Changes type of a symbol - void change_type(SymbolType new_type, const vector &symbol_list); + void change_type(SymbolType new_type, const vector& symbol_list); //! Adds a non-negative constant to DataTree - expr_t add_non_negative_constant(const string &constant); + expr_t add_non_negative_constant(const string& constant); //! Adds a NaN constant to DataTree expr_t add_nan_constant(); //! Adds an Inf constant to DataTree expr_t add_inf_constant(); //! Adds a model variable to ModelTree and VariableTable - expr_t add_model_variable(const string &name); + expr_t add_model_variable(const string& name); //! Declares a variable of type new_type OR changes a variable in the equations to type new_type //! and removes any error messages that may have been issued in model_errors - expr_t declare_or_change_type(SymbolType new_type, const string &name); + expr_t declare_or_change_type(SymbolType new_type, const string& name); //! Adds an Expression's variable - expr_t add_expression_variable(const string &name); + expr_t add_expression_variable(const string& name); //! Adds a "dsample" statement - void dsample(const string &arg1); + void dsample(const string& arg1); //! Adds a "dsample" statement - void dsample(const string &arg1, const string &arg2); + void dsample(const string& arg1, const string& arg2); //! Writes parameter intitialisation expression - void init_param(const string &name, expr_t rhs); + void init_param(const string& name, expr_t rhs); //! Add a line inside an initval block - void init_val(const string &name, expr_t rhs); + void init_val(const string& name, expr_t rhs); //! Add a line inside an endval block - void end_val(EndValLearntInStatement::LearntEndValType type, const string &name, expr_t rhs); + void end_val(EndValLearntInStatement::LearntEndValType type, const string& name, expr_t rhs); //! Add a line inside a histval block - void hist_val(const string &name, const string &lag, expr_t rhs); + void hist_val(const string& name, const string& lag, expr_t rhs); //! Adds an entry in a homotopy_setup block /*! Second argument "val1" can be NULL if no initial value provided */ - void homotopy_val(const string &name, expr_t val1, expr_t val2); + void homotopy_val(const string& name, expr_t val1, expr_t val2); //! Writes end of an initval block void end_initval(bool all_values_required); //! Writes end of an endval block void end_endval(bool all_values_required); //! Writes end of an endval(learnt_in=…) block - void end_endval_learnt_in(const string &learnt_in_period); + void end_endval_learnt_in(const string& learnt_in_period); //! Writes end of an histval block void end_histval(bool all_values_required); //! Writes end of an homotopy_setup block @@ -431,9 +451,9 @@ public: //! End epilogue block void end_epilogue(); //! Add epilogue variable - void add_epilogue_variable(const string &varname); + void add_epilogue_variable(const string& varname); //! Add equation in epilogue block - void add_epilogue_equal(const string &varname, expr_t expr); + void add_epilogue_equal(const string& varname, expr_t expr); /* Begin a model or model_replace block, or an expression as an option value of some statement. Must be followed by a call to reset_data_tree(). */ @@ -447,40 +467,43 @@ public: //! Writes a shocks(surprise) statement void end_shocks_surprise(bool overwrite); //! Writes a shocks(learnt_in=…) block - void end_shocks_learnt_in(const string &learnt_in_period, bool overwrite); + void end_shocks_learnt_in(const string& learnt_in_period, bool overwrite); //! Writes a mshocks(learnt_in=…) block - void end_mshocks_learnt_in(const string &learnt_in_period, bool overwrite, bool relative_to_initval); + void end_mshocks_learnt_in(const string& learnt_in_period, bool overwrite, + bool relative_to_initval); //! Writes a heteroskedastic_shocks statement void end_heteroskedastic_shocks(bool overwrite); /* Adds a deterministic shock, a path element inside a conditional_forecast_paths block, or a surprise shock */ enum class DetShockType - { - standard, - add, // for “add” in “shocks(learnt_in)” - multiply, // for “multiply” in “shocks(learnt_in)” - conditional_forecast - }; - void add_det_shock(const string &var, const vector> &periods, const vector &values, DetShockType type); + { + standard, + add, // for “add” in “shocks(learnt_in)” + multiply, // for “multiply” in “shocks(learnt_in)” + conditional_forecast + }; + void add_det_shock(const string& var, const vector>& periods, + const vector& values, DetShockType type); //! Adds a heteroskedastic shock (either values or scales) - void add_heteroskedastic_shock(const string &var, const vector> &periods, const vector &values, bool scales); + void add_heteroskedastic_shock(const string& var, const vector>& periods, + const vector& values, bool scales); //! Adds a std error shock - void add_stderr_shock(const string &var, expr_t value); + void add_stderr_shock(const string& var, expr_t value); //! Adds a variance shock - void add_var_shock(const string &var, expr_t value); + void add_var_shock(const string& var, expr_t value); //! Adds a covariance shock - void add_covar_shock(const string &var1, const string &var2, expr_t value); + void add_covar_shock(const string& var1, const string& var2, expr_t value); //! Adds a correlated shock - void add_correl_shock(const string &var1, const string &var2, expr_t value); + void add_correl_shock(const string& var1, const string& var2, expr_t value); //! Adds a shock period range - void add_period(const string &p1, const string &p2); + void add_period(const string& p1, const string& p2); //! Adds a shock period - void add_period(const string &p1); + void add_period(const string& p1); //! Adds a deterministic shock value void add_value(expr_t value); //! Adds a deterministic shock value /*! \param v a string containing a (possibly negative) numeric constant */ - void add_value(const string &v); + void add_value(const string& v); //! Write a steady command void steady(); //! Sets an option to a numerical value @@ -530,7 +553,7 @@ public: //! Adds a declaration for a user-defined external function void external_function(); //! Sets an external_function option to a string value - void external_function_option(const string &name_option, const string &opt); + void external_function_option(const string& name_option, const string& opt); //! Add a line in an estimated params block void add_estimated_params_element(); //! Writes osr params bounds command @@ -538,25 +561,27 @@ public: //! Add a line in an osr params block void add_osr_params_element(); //! Sets the frequency of the data - void set_time(const string &arg); + void set_time(const string& arg); //! Estimation Data void estimation_data(); //! Sets the prior for a parameter void set_prior(string name, string subsample_name); //! Sets the joint prior for a set of parameters - void set_joint_prior(const vector &symbol_vec); + void set_joint_prior(const vector& symbol_vec); //! Adds a parameters to the list of joint parameters void add_joint_parameter(string name); //! Adds the variance option to its temporary holding place void set_prior_variance(expr_t variance = nullptr); //! Copies the prior from_name to_name - void copy_prior(string to_declaration_type, string to_name1, string to_name2, string to_subsample_name, - string from_declaration_type, string from_name1, string from_name2, string from_subsample_name); + void copy_prior(string to_declaration_type, string to_name1, string to_name2, + string to_subsample_name, string from_declaration_type, string from_name1, + string from_name2, string from_subsample_name); //! Sets the options for a parameter void set_options(string name, string subsample_name); //! Copies the options from_name to_name - void copy_options(string to_declaration_type, string to_name1, string to_name2, string to_subsample_name, - string from_declaration_type, string from_name1, string from_name2, string from_subsample_name); + void copy_options(string to_declaration_type, string to_name1, string to_name2, + string to_subsample_name, string from_declaration_type, string from_name1, + string from_name2, string from_subsample_name); //! Sets the prior for estimated std dev void set_std_prior(string name, string subsample_name); //! Sets the options for estimated std dev @@ -572,34 +597,34 @@ public: //! Check that no observed variable has yet be defined void check_varobs(); //! Add a new observed variable - void add_varobs(const string &name); + void add_varobs(const string& name); //! Check that no observed exogenous variable has yet be defined void check_varexobs(); //! Add a new observed exogenous variable - void add_varexobs(const string &name); + void add_varexobs(const string& name); //! Svar_Identification Statement void begin_svar_identification(); void end_svar_identification(); //! Svar_Identification Statement: match list of restrictions and equation number with lag - void combine_lag_and_restriction(const string &lag); + void combine_lag_and_restriction(const string& lag); //! Svar_Identification Statement: match list of restrictions with equation number - void add_restriction_in_equation(const string &equation, const vector &symbol_list); + void add_restriction_in_equation(const string& equation, const vector& symbol_list); //! Svar_Identification Statement: add exclusions of constants void add_constants_exclusion(); //! Svar_Identification Statement: add equation number for following restriction equations - void add_restriction_equation_nbr(const string &eq_nbr); + void add_restriction_equation_nbr(const string& eq_nbr); //! Svar_Identification Statement: record presence of equal sign void add_restriction_equal(); //! Svar_Idenditification Statement: add coefficient of a linear restriction (positive value) - void add_positive_restriction_element(expr_t value, const string &variable, const string &lag); + void add_positive_restriction_element(expr_t value, const string& variable, const string& lag); //! Svar_Idenditification Statement: add unit coefficient of a linear restriction - void add_positive_restriction_element(const string &variable, const string &lag); + void add_positive_restriction_element(const string& variable, const string& lag); //! Svar_Idenditification Statement: add coefficient of a linear restriction (negative value) - void add_negative_restriction_element(expr_t value, const string &variable, const string &lag); + void add_negative_restriction_element(expr_t value, const string& variable, const string& lag); //! Svar_Idenditification Statement: add negative unit coefficient of a linear restriction - void add_negative_restriction_element(const string &variable, const string &lag); + void add_negative_restriction_element(const string& variable, const string& lag); //! Svar_Idenditification Statement: add restriction element - void add_restriction_element(expr_t value, const string &variable, const string &lag); + void add_restriction_element(expr_t value, const string& variable, const string& lag); //! Svar_Identification Statement: check that restriction is homogenous void check_restriction_expression_constant(expr_t value); //! Svar_Identification Statement: restriction of form upper cholesky @@ -611,7 +636,7 @@ public: //! generate_irfs Block void end_generate_irfs(); void add_generate_irfs_element(string name); - void add_generate_irfs_exog_element(string exo, const string &value); + void add_generate_irfs_exog_element(string exo, const string& value); //! Forecast Statement void forecast(vector symbol_list); void set_trends(); @@ -620,16 +645,16 @@ public: //! filter_initial_state block void set_filter_initial_state(); //! element for filter_initial_state block - void set_filter_initial_state_element(const string &name, const string &lag, expr_t rhs); + void set_filter_initial_state_element(const string& name, const string& lag, expr_t rhs); void set_unit_root_vars(); void optim_weights(); void set_optim_weights(string name, expr_t value); - void set_optim_weights(const string &name1, const string &name2, expr_t value); + void set_optim_weights(const string& name1, const string& name2, expr_t value); void set_osr_params(vector symbol_list); void run_osr(vector symbol_list); void run_dynasave(string filename, vector symbol_list); void run_dynatype(string filename, vector symbol_list); - void run_load_params_and_steady_state(const string &filename); + void run_load_params_and_steady_state(const string& filename); void run_save_params_and_steady_state(string filename); void run_identification(); void add_mc_filename(string filename, string prior = "1"); @@ -643,15 +668,15 @@ public: //! Ramsey constraints statement void add_ramsey_constraints_statement(); //! Ramsey less constraint - void ramsey_constraint_add_less(const string &name, const expr_t rhs); + void ramsey_constraint_add_less(const string& name, const expr_t rhs); //! Ramsey greater constraint - void ramsey_constraint_add_greater(const string &name, const expr_t rhs); + void ramsey_constraint_add_greater(const string& name, const expr_t rhs); //! Ramsey less or equal constraint - void ramsey_constraint_add_less_equal(const string &name, const expr_t rhs); + void ramsey_constraint_add_less_equal(const string& name, const expr_t rhs); //! Ramsey greater or equal constraint - void ramsey_constraint_add_greater_equal(const string &name, const expr_t rhs); + void ramsey_constraint_add_greater_equal(const string& name, const expr_t rhs); //! Ramsey constraint helper function - void add_ramsey_constraint(const string &name, BinaryOpcode op_code, const expr_t rhs); + void add_ramsey_constraint(const string& name, BinaryOpcode op_code, const expr_t rhs); //! Ramsey policy statement void ramsey_policy(vector symbol_list); //! Evaluate Planner Objective @@ -675,11 +700,11 @@ public: //! Adds a write_latex_steady_state_model statement void write_latex_steady_state_model(); //! BVAR marginal density - void bvar_density(const string &maxnlags); + void bvar_density(const string& maxnlags); //! BVAR forecast - void bvar_forecast(const string &nlags); + void bvar_forecast(const string& nlags); //! BVAR IRF - void bvar_irf(const string &nirf, string identificationname); + void bvar_irf(const string& nirf, string identificationname); //! SBVAR statement void sbvar(); //! Markov Switching Statement: Estimation @@ -715,7 +740,7 @@ public: //! Conditional forecast paths block void conditional_forecast_paths(); //! Plot conditional forecast statement - void plot_conditional_forecast(const optional &periods, vector symbol_list); + void plot_conditional_forecast(const optional& periods, vector symbol_list); //! Smoother on calibrated models void calib_smoother(vector symbol_list); //! Extended path @@ -749,13 +774,13 @@ public: //! Writes token "arg1^arg2" to model tree expr_t add_power(expr_t arg1, expr_t arg2); //! Writes token "E(arg1)(arg2)" to model tree - expr_t add_expectation(const string &arg1, expr_t arg2); + expr_t add_expectation(const string& arg1, expr_t arg2); //! Writes token "VAR_EXPECTATION(model_name)" to model tree - expr_t add_var_expectation(const string &model_name); + expr_t add_var_expectation(const string& model_name); //! Writes token "PAC_EXPECTATION(model_name, discount, growth)" to model tree - expr_t add_pac_expectation(const string &model_name); + expr_t add_pac_expectation(const string& model_name); //! Adds a pac_target_nonstationary(model_name, discount, growth) node to model tree - expr_t add_pac_target_nonstationary(const string &model_name); + expr_t add_pac_target_nonstationary(const string& model_name); //! Creates pac_model statement void begin_pac_model(); void pac_model(); @@ -768,8 +793,8 @@ public: //! Writes token "diff(arg1)" to model tree expr_t add_diff(expr_t arg1); //! Writes token "adl(arg1, lag)" to model tree - expr_t add_adl(expr_t arg1, const string &name, const string &lag); - expr_t add_adl(expr_t arg1, const string &name, const vector &lags); + expr_t add_adl(expr_t arg1, const string& name, const string& lag); + expr_t add_adl(expr_t arg1, const string& name, const vector& lags); //! Writes token "exp(arg1)" to model tree expr_t add_exp(expr_t arg1); //! Writes token "log(arg1)" to model tree @@ -833,32 +858,39 @@ public: //! Test to see if model/external function has exactly one integer argument optional is_there_one_integer_argument() const; //! Adds an external function call node - expr_t add_model_var_or_external_function(const string &function_name, bool in_model_block); + expr_t add_model_var_or_external_function(const string& function_name, bool in_model_block); //! Adds a native statement void add_native(string s); - //! Adds a native statement, first removing the set of characters passed in token (and everything after) + //! Adds a native statement, first removing the set of characters passed in token (and everything + //! after) void add_native_remove_charset(string_view str, string_view token); //! Adds a verbatim statement void add_verbatim(string s); - //! Adds a verbatim statement, first removing the set of characters passed in token (and everything after) + //! Adds a verbatim statement, first removing the set of characters passed in token (and + //! everything after) void add_verbatim_remove_charset(string_view str, string_view token); //! Resets data_tree and model_tree pointers to default (i.e. mod_file->expressions_tree) void reset_data_tree(); //! Begin a steady_state_model block void begin_steady_state_model(); //! Add an assignment equation in steady_state_model block - void add_steady_state_model_equal(const string &varname, expr_t expr); + void add_steady_state_model_equal(const string& varname, expr_t expr); //! Add a multiple assignment equation in steady_state_model block - void add_steady_state_model_equal_multiple(const vector &symbol_list, expr_t expr); + void add_steady_state_model_equal_multiple(const vector& symbol_list, expr_t expr); //! Ends declaration of trend variable - void end_trend_var(bool log_trend, expr_t growth_factor, const vector> &symbol_list); + void end_trend_var(bool log_trend, expr_t growth_factor, + const vector>& symbol_list); //! Handles a “var(deflator=…)”, “var(log, deflator=…)” or “var(log_deflator=…)” statement - void end_nonstationary_var(bool log_deflator, expr_t deflator, const vector>>> &symbol_list, bool log_option); + void end_nonstationary_var( + bool log_deflator, expr_t deflator, + const vector>>>& symbol_list, + bool log_option); //! Add a graph format to the list of formats requested void add_graph_format(string name); //! Add the graph_format option to the OptionsList structure void process_graph_format_option(); - //! Add the graph_format option to the initial_condition_decomp substructure of the OptionsList structure + //! Add the graph_format option to the initial_condition_decomp substructure of the OptionsList + //! structure void initial_condition_decomp_process_graph_format_option(); //! Add the graph_format option to the plot_shock_decomp substructure of the OptionsList structure void plot_shock_decomp_process_graph_format_option(); @@ -867,11 +899,13 @@ public: //! Processing the parallel_local_files option void add_parallel_local_file(string filename); //! Add an item of a moment_calibration statement - void add_moment_calibration_item(const string &endo1, const string &endo2, string lags, const pair &range); + void add_moment_calibration_item(const string& endo1, const string& endo2, string lags, + const pair& range); //! End a moment_calibration statement void end_moment_calibration(); //! Add an item of an irf_calibration statement - void add_irf_calibration_item(const string &endo, string periods, const string &exo, const pair &range); + void add_irf_calibration_item(const string& endo, string periods, const string& exo, + const pair& range); //! End a moment_calibration statement void end_irf_calibration(); //! Add a shock to a group @@ -881,7 +915,7 @@ public: //! End shock groups declaration void end_shock_groups(string name); //! Add a set of init2shocks - void add_init2shocks(const string &endo_name, const string &exo_name); + void add_init2shocks(const string& endo_name, const string& exo_name); //! End init2shocks declaration void end_init2shocks(string name); void smoother2histval(); @@ -898,17 +932,18 @@ public: //! Start parsing a matched_moments block void begin_matched_moments(); //! Add a matched_moments block - void end_matched_moments(const vector &moments); + void end_matched_moments(const vector& moments); //! Start parsing an occbin_constraints block void begin_occbin_constraints(); //! Add an occbin_constraints block - void end_occbin_constraints(vector> constraints); + void end_occbin_constraints( + vector> constraints); // Process a model_remove statement - void model_remove(const vector> &listed_eqs_by_tags); + void model_remove(const vector>& listed_eqs_by_tags); // Begin a model_replace statement - void begin_model_replace(const vector> &listed_eqs_by_tags); + void begin_model_replace(const vector>& listed_eqs_by_tags); // Add a var_remove statement - void var_remove(const vector &symbol_list); + void var_remove(const vector& symbol_list); void begin_pac_target_info(string name); void end_pac_target_info(); void set_pac_target_info_target(expr_t target); @@ -920,9 +955,10 @@ public: // Add a resid statement void resid(); // Returns true iff the string is a legal symbol identifier (see NAME token in lexer) - static bool isSymbolIdentifier(const string &str); + static bool isSymbolIdentifier(const string& str); // Given an Occbin regime name, returns the corresponding auxiliary parameter - static string buildOccbinBindParamName(const string ®ime) + static string + buildOccbinBindParamName(const string& regime) { return "occbin_" + regime + "_bind"; } diff --git a/src/Shocks.cc b/src/Shocks.cc index c0c2b95e..1b7f54db 100644 --- a/src/Shocks.cc +++ b/src/Shocks.cc @@ -26,30 +26,27 @@ AbstractShocksStatement::AbstractShocksStatement(bool overwrite_arg, ShockType type_arg, det_shocks_t det_shocks_arg, - const SymbolTable &symbol_table_arg) : - overwrite{overwrite_arg}, - type{type_arg}, - det_shocks{move(det_shocks_arg)}, - symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + overwrite {overwrite_arg}, + type {type_arg}, + det_shocks {move(det_shocks_arg)}, + symbol_table {symbol_table_arg} { } void -AbstractShocksStatement::writeDetShocks(ostream &output) const +AbstractShocksStatement::writeDetShocks(ostream& output) const { int exo_det_length = 0; - for (const auto & [id, shock_vec] : det_shocks) + for (const auto& [id, shock_vec] : det_shocks) for (bool exo_det = (symbol_table.getType(id) == SymbolType::exogenousDet); - const auto &[period1, period2, value] : shock_vec) + const auto& [period1, period2, value] : shock_vec) { output << "M_.det_shocks = [ M_.det_shocks;" << endl - << boolalpha - << "struct('exo_det'," << exo_det - << ",'exo_id'," << symbol_table.getTypeSpecificID(id)+1 - << ",'type','" << typeToString(type) << "'" - << ",'periods'," << period1 << ":" << period2 - << ",'value',"; + << boolalpha << "struct('exo_det'," << exo_det << ",'exo_id'," + << symbol_table.getTypeSpecificID(id) + 1 << ",'type','" << typeToString(type) << "'" + << ",'periods'," << period1 << ":" << period2 << ",'value',"; value->writeOutput(output); output << ") ];" << endl; @@ -60,18 +57,16 @@ AbstractShocksStatement::writeDetShocks(ostream &output) const } void -AbstractShocksStatement::writeJsonDetShocks(ostream &output) const +AbstractShocksStatement::writeJsonDetShocks(ostream& output) const { output << R"("deterministic_shocks": [)"; - for (bool printed_something{false}; - const auto &[id, shock_vec] : det_shocks) + for (bool printed_something {false}; const auto& [id, shock_vec] : det_shocks) { if (exchange(printed_something, true)) output << ", "; output << R"({"var": ")" << symbol_table.getName(id) << R"(", )" << R"("values": [)"; - for (bool printed_something2{false}; - const auto &[period1, period2, value] : shock_vec) + for (bool printed_something2 {false}; const auto& [period1, period2, value] : shock_vec) { if (exchange(printed_something2, true)) output << ", "; @@ -101,35 +96,33 @@ AbstractShocksStatement::typeToString(ShockType type) __builtin_unreachable(); // Silence GCC warning } -ShocksStatement::ShocksStatement(bool overwrite_arg, - det_shocks_t det_shocks_arg, +ShocksStatement::ShocksStatement(bool overwrite_arg, det_shocks_t det_shocks_arg, var_and_std_shocks_t var_shocks_arg, var_and_std_shocks_t std_shocks_arg, covar_and_corr_shocks_t covar_shocks_arg, covar_and_corr_shocks_t corr_shocks_arg, - const SymbolTable &symbol_table_arg) : - AbstractShocksStatement{overwrite_arg, ShockType::level, move(det_shocks_arg), symbol_table_arg}, - var_shocks{move(var_shocks_arg)}, - std_shocks{move(std_shocks_arg)}, - covar_shocks{move(covar_shocks_arg)}, - corr_shocks{move(corr_shocks_arg)} + const SymbolTable& symbol_table_arg) : + AbstractShocksStatement {overwrite_arg, ShockType::level, move(det_shocks_arg), + symbol_table_arg}, + var_shocks {move(var_shocks_arg)}, + std_shocks {move(std_shocks_arg)}, + covar_shocks {move(covar_shocks_arg)}, + corr_shocks {move(corr_shocks_arg)} { } void -ShocksStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +ShocksStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { - output << "%" << endl - << "% SHOCKS instructions" << endl - << "%" << endl; + output << "%" << endl << "% SHOCKS instructions" << endl << "%" << endl; if (overwrite) { output << "M_.det_shocks = [];" << endl; - output << "M_.Sigma_e = zeros(" << symbol_table.exo_nbr() << ", " - << symbol_table.exo_nbr() << ");" << endl + output << "M_.Sigma_e = zeros(" << symbol_table.exo_nbr() << ", " << symbol_table.exo_nbr() + << ");" << endl << "M_.Correlation_matrix = eye(" << symbol_table.exo_nbr() << ", " << symbol_table.exo_nbr() << ");" << endl; @@ -139,9 +132,7 @@ ShocksStatement::writeOutput(ostream &output, [[maybe_unused]] const string &bas << "M_.Correlation_matrix_ME = eye(" << symbol_table.observedVariablesNbr() << ", " << symbol_table.observedVariablesNbr() << ");" << endl; else - output << "M_.H = 0;" << endl - << "M_.Correlation_matrix_ME = 1;" << endl; - + output << "M_.H = 0;" << endl << "M_.Correlation_matrix_ME = 1;" << endl; } writeDetShocks(output); @@ -152,14 +143,14 @@ ShocksStatement::writeOutput(ostream &output, [[maybe_unused]] const string &bas If there are no off-diagonal elements, and we are not in overwrite mode, then we don't reset it to 1, since there might be previous shocks blocks with off-diagonal elements. */ - if (covar_shocks.size()+corr_shocks.size() > 0) + if (covar_shocks.size() + corr_shocks.size() > 0) output << "M_.sigma_e_is_diagonal = 0;" << endl; else if (overwrite) output << "M_.sigma_e_is_diagonal = 1;" << endl; } void -ShocksStatement::writeJsonOutput(ostream &output) const +ShocksStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "shocks")" << R"(, "overwrite": )" << boolalpha << overwrite; @@ -168,9 +159,8 @@ ShocksStatement::writeJsonOutput(ostream &output) const output << ", "; writeJsonDetShocks(output); } - output<< R"(, "variance": [)"; - for (bool printed_something{false}; - auto &[id, value] : var_shocks) + output << R"(, "variance": [)"; + for (bool printed_something {false}; auto& [id, value] : var_shocks) { if (exchange(printed_something, true)) output << ", "; @@ -181,8 +171,7 @@ ShocksStatement::writeJsonOutput(ostream &output) const } output << "]" << R"(, "stderr": [)"; - for (bool printed_something{false}; - auto &[id, value] : std_shocks) + for (bool printed_something {false}; auto& [id, value] : std_shocks) { if (exchange(printed_something, true)) output << ", "; @@ -193,8 +182,7 @@ ShocksStatement::writeJsonOutput(ostream &output) const } output << "]" << R"(, "covariance": [)"; - for (bool printed_something{false}; - auto &[ids, value] : covar_shocks) + for (bool printed_something {false}; auto& [ids, value] : covar_shocks) { if (exchange(printed_something, true)) output << ", "; @@ -207,8 +195,7 @@ ShocksStatement::writeJsonOutput(ostream &output) const } output << "]" << R"(, "correlation": [)"; - for (bool printed_something{false}; - auto &[ids, value] : corr_shocks) + for (bool printed_something {false}; auto& [ids, value] : corr_shocks) { if (exchange(printed_something, true)) output << ", "; @@ -224,8 +211,7 @@ ShocksStatement::writeJsonOutput(ostream &output) const } void -ShocksStatement::writeVarOrStdShock(ostream &output, const pair &it, - bool stddev) const +ShocksStatement::writeVarOrStdShock(ostream& output, const pair& it, bool stddev) const { SymbolType type = symbol_table.getType(it.first); assert(type == SymbolType::exogenous || symbol_table.isObservedVariable(it.first)); @@ -252,23 +238,24 @@ ShocksStatement::writeVarOrStdShock(ostream &output, const pair &it } void -ShocksStatement::writeVarAndStdShocks(ostream &output) const +ShocksStatement::writeVarAndStdShocks(ostream& output) const { - for (const auto &it : var_shocks) + for (const auto& it : var_shocks) writeVarOrStdShock(output, it, false); - for (const auto &it : std_shocks) + for (const auto& it : std_shocks) writeVarOrStdShock(output, it, true); } void -ShocksStatement::writeCovarOrCorrShock(ostream &output, const pair, expr_t> &it, +ShocksStatement::writeCovarOrCorrShock(ostream& output, const pair, expr_t>& it, bool corr) const { SymbolType type1 = symbol_table.getType(it.first.first); SymbolType type2 = symbol_table.getType(it.first.second); assert((type1 == SymbolType::exogenous && type2 == SymbolType::exogenous) - || (symbol_table.isObservedVariable(it.first.first) && symbol_table.isObservedVariable(it.first.second))); + || (symbol_table.isObservedVariable(it.first.first) + && symbol_table.isObservedVariable(it.first.second))); string matrix, corr_matrix; int id1, id2; if (type1 == SymbolType::exogenous) @@ -289,89 +276,95 @@ ShocksStatement::writeCovarOrCorrShock(ostream &output, const paircollectVariables(SymbolType::parameter, mod_file_struct.parameters_within_shocks_values); for (auto [id, val] : std_shocks) val->collectVariables(SymbolType::parameter, mod_file_struct.parameters_within_shocks_values); - for (const auto &[ids, val] : covar_shocks) + for (const auto& [ids, val] : covar_shocks) val->collectVariables(SymbolType::parameter, mod_file_struct.parameters_within_shocks_values); - for (const auto &[ids, val] : corr_shocks) + for (const auto& [ids, val] : corr_shocks) val->collectVariables(SymbolType::parameter, mod_file_struct.parameters_within_shocks_values); } @@ -401,14 +394,12 @@ ShocksStatement::has_calibrated_measurement_errors() const if (symbol_table.isObservedVariable(id)) return true; - for (const auto & [ids, val] : covar_shocks) - if (symbol_table.isObservedVariable(ids.first) - || symbol_table.isObservedVariable(ids.second)) + for (const auto& [ids, val] : covar_shocks) + if (symbol_table.isObservedVariable(ids.first) || symbol_table.isObservedVariable(ids.second)) return true; - for (const auto & [ids, val] : corr_shocks) - if (symbol_table.isObservedVariable(ids.first) - || symbol_table.isObservedVariable(ids.second)) + for (const auto& [ids, val] : corr_shocks) + if (symbol_table.isObservedVariable(ids.first) || symbol_table.isObservedVariable(ids.second)) return true; return false; @@ -416,21 +407,20 @@ ShocksStatement::has_calibrated_measurement_errors() const MShocksStatement::MShocksStatement(bool overwrite_arg, bool relative_to_initval_arg, det_shocks_t det_shocks_arg, - const SymbolTable &symbol_table_arg) : - AbstractShocksStatement{overwrite_arg, - relative_to_initval_arg ? ShockType::multiplyInitialSteadyState : ShockType::multiplySteadyState, - move(det_shocks_arg), symbol_table_arg}, - relative_to_initval{relative_to_initval_arg} + const SymbolTable& symbol_table_arg) : + AbstractShocksStatement {overwrite_arg, + relative_to_initval_arg ? ShockType::multiplyInitialSteadyState + : ShockType::multiplySteadyState, + move(det_shocks_arg), symbol_table_arg}, + relative_to_initval {relative_to_initval_arg} { } void -MShocksStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +MShocksStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { - output << "%" << endl - << "% MSHOCKS instructions" << endl - << "%" << endl; + output << "%" << endl << "% MSHOCKS instructions" << endl << "%" << endl; if (overwrite) output << "M_.det_shocks = [];" << endl; @@ -439,11 +429,11 @@ MShocksStatement::writeOutput(ostream &output, [[maybe_unused]] const string &ba } void -MShocksStatement::writeJsonOutput(ostream &output) const +MShocksStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "mshocks")" - << R"(, "overwrite": )" << boolalpha << overwrite - << R"(, "relative_to_initval": )" << boolalpha << relative_to_initval; + << R"(, "overwrite": )" << boolalpha << overwrite << R"(, "relative_to_initval": )" + << boolalpha << relative_to_initval; if (!det_shocks.empty()) { output << ", "; @@ -452,35 +442,35 @@ MShocksStatement::writeJsonOutput(ostream &output) const output << "}"; } -ShocksSurpriseStatement::ShocksSurpriseStatement(bool overwrite_arg, - AbstractShocksStatement::det_shocks_t surprise_shocks_arg, - const SymbolTable &symbol_table_arg) : - overwrite{overwrite_arg}, surprise_shocks{move(surprise_shocks_arg)}, - symbol_table{symbol_table_arg} +ShocksSurpriseStatement::ShocksSurpriseStatement( + bool overwrite_arg, AbstractShocksStatement::det_shocks_t surprise_shocks_arg, + const SymbolTable& symbol_table_arg) : + overwrite {overwrite_arg}, + surprise_shocks {move(surprise_shocks_arg)}, + symbol_table {symbol_table_arg} { } void -ShocksSurpriseStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +ShocksSurpriseStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.shocks_surprise_present = true; } void -ShocksSurpriseStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +ShocksSurpriseStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { if (overwrite) output << "M_.surprise_shocks = [" << endl; else output << "M_.surprise_shocks = [ M_.surprise_shocks;" << endl; - for (const auto &[id, shock_vec] : surprise_shocks) - for (const auto &[period1, period2, value] : shock_vec) + for (const auto& [id, shock_vec] : surprise_shocks) + for (const auto& [period1, period2, value] : shock_vec) { - output << "struct('exo_id'," << symbol_table.getTypeSpecificID(id)+1 - << ",'periods'," << period1 << ":" << period2 - << ",'value',"; + output << "struct('exo_id'," << symbol_table.getTypeSpecificID(id) + 1 << ",'periods'," + << period1 << ":" << period2 << ",'value',"; value->writeOutput(output); output << ");" << endl; } @@ -488,20 +478,18 @@ ShocksSurpriseStatement::writeOutput(ostream &output, [[maybe_unused]] const str } void -ShocksSurpriseStatement::writeJsonOutput(ostream &output) const +ShocksSurpriseStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "shocks")" << R"(, "surprise": true)" << R"(, "surprise_shocks": [)"; - for (bool printed_something{false}; - const auto &[id, shock_vec] : surprise_shocks) + for (bool printed_something {false}; const auto& [id, shock_vec] : surprise_shocks) { if (exchange(printed_something, true)) output << ", "; output << R"({"var": ")" << symbol_table.getName(id) << R"(", )" << R"("values": [)"; - for (bool printed_something2{false}; - const auto &[period1, period2, value] : shock_vec) + for (bool printed_something2 {false}; const auto& [period1, period2, value] : shock_vec) { if (exchange(printed_something2, true)) output << ", "; @@ -518,15 +506,17 @@ ShocksSurpriseStatement::writeJsonOutput(ostream &output) const ShocksLearntInStatement::ShocksLearntInStatement(int learnt_in_period_arg, bool overwrite_arg, learnt_shocks_t learnt_shocks_arg, - const SymbolTable &symbol_table_arg) : - learnt_in_period{learnt_in_period_arg}, overwrite{overwrite_arg}, - learnt_shocks{move(learnt_shocks_arg)}, symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + learnt_in_period {learnt_in_period_arg}, + overwrite {overwrite_arg}, + learnt_shocks {move(learnt_shocks_arg)}, + symbol_table {symbol_table_arg} { } void -ShocksLearntInStatement::checkPass(ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +ShocksLearntInStatement::checkPass(ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { mod_file_struct.shocks_learnt_in_present = true; } @@ -551,22 +541,22 @@ ShocksLearntInStatement::typeToString(LearntShockType type) } void -ShocksLearntInStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +ShocksLearntInStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { if (overwrite) output << "if ~isempty(M_.learnt_shocks)" << endl - << " M_.learnt_shocks = M_.learnt_shocks([M_.learnt_shocks.learnt_in] ~= " << learnt_in_period << ");" << endl + << " M_.learnt_shocks = M_.learnt_shocks([M_.learnt_shocks.learnt_in] ~= " + << learnt_in_period << ");" << endl << "end" << endl; output << "M_.learnt_shocks = [ M_.learnt_shocks;" << endl; - for (const auto &[id, shock_vec] : learnt_shocks) - for (const auto &[type, period1, period2, value] : shock_vec) + for (const auto& [id, shock_vec] : learnt_shocks) + for (const auto& [type, period1, period2, value] : shock_vec) { - output << "struct('learnt_in'," << learnt_in_period - << ",'exo_id'," << symbol_table.getTypeSpecificID(id)+1 - << ",'periods'," << period1 << ":" << period2 - << ",'type','" << typeToString(type) << "'" + output << "struct('learnt_in'," << learnt_in_period << ",'exo_id'," + << symbol_table.getTypeSpecificID(id) + 1 << ",'periods'," << period1 << ":" + << period2 << ",'type','" << typeToString(type) << "'" << ",'value',"; value->writeOutput(output); output << ");" << endl; @@ -575,21 +565,18 @@ ShocksLearntInStatement::writeOutput(ostream &output, [[maybe_unused]] const str } void -ShocksLearntInStatement::writeJsonOutput(ostream &output) const +ShocksLearntInStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "shocks")" - << R"(, "learnt_in": )" << learnt_in_period - << R"(, "overwrite": )" << boolalpha << overwrite - << R"(, "learnt_shocks": [)"; - for (bool printed_something{false}; - const auto &[id, shock_vec] : learnt_shocks) + << R"(, "learnt_in": )" << learnt_in_period << R"(, "overwrite": )" << boolalpha + << overwrite << R"(, "learnt_shocks": [)"; + for (bool printed_something {false}; const auto& [id, shock_vec] : learnt_shocks) { if (exchange(printed_something, true)) output << ", "; output << R"({"var": ")" << symbol_table.getName(id) << R"(", )" << R"("values": [)"; - for (bool printed_something2{false}; - const auto &[type, period1, period2, value] : shock_vec) + for (bool printed_something2 {false}; const auto& [type, period1, period2, value] : shock_vec) { if (exchange(printed_something2, true)) output << ", "; @@ -605,42 +592,41 @@ ShocksLearntInStatement::writeJsonOutput(ostream &output) const output << "]}"; } -ConditionalForecastPathsStatement::ConditionalForecastPathsStatement(AbstractShocksStatement::det_shocks_t paths_arg, - const SymbolTable &symbol_table_arg) : - paths{move(paths_arg)}, - symbol_table{symbol_table_arg}, - path_length{computePathLength(paths)} +ConditionalForecastPathsStatement::ConditionalForecastPathsStatement( + AbstractShocksStatement::det_shocks_t paths_arg, const SymbolTable& symbol_table_arg) : + paths {move(paths_arg)}, symbol_table {symbol_table_arg}, path_length {computePathLength(paths)} { } int -ConditionalForecastPathsStatement::computePathLength(const AbstractShocksStatement::det_shocks_t &paths) +ConditionalForecastPathsStatement::computePathLength( + const AbstractShocksStatement::det_shocks_t& paths) { - int length{0}; - for (const auto &[ignore, elems] : paths) - for (auto &[period1, period2, value] : elems) + int length {0}; + for (const auto& [ignore, elems] : paths) + for (auto& [period1, period2, value] : elems) // Period1 < Period2, as enforced in ParsingDriver::add_period() length = max(length, period2); return length; } void -ConditionalForecastPathsStatement::writeOutput(ostream &output, - [[maybe_unused]] const string &basename, +ConditionalForecastPathsStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { assert(path_length > 0); output << "constrained_vars_ = [];" << endl << "constrained_paths_ = NaN(" << paths.size() << ", " << path_length << ");" << endl; - for (int k{1}; - const auto &[id, elems] : paths) + for (int k {1}; const auto& [id, elems] : paths) { if (k == 1) output << "constrained_vars_ = " << symbol_table.getTypeSpecificID(id) + 1 << ";" << endl; else - output << "constrained_vars_ = [constrained_vars_; " << symbol_table.getTypeSpecificID(id) + 1 << "];" << endl; - for (const auto &[period1, period2, value] : elems) + output << "constrained_vars_ = [constrained_vars_; " + << symbol_table.getTypeSpecificID(id) + 1 << "];" << endl; + for (const auto& [period1, period2, value] : elems) for (int j = period1; j <= period2; j++) { output << "constrained_paths_(" << k << "," << j << ")="; @@ -652,19 +638,17 @@ ConditionalForecastPathsStatement::writeOutput(ostream &output, } void -ConditionalForecastPathsStatement::writeJsonOutput(ostream &output) const +ConditionalForecastPathsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "conditional_forecast_paths")" << R"(, "paths": [)"; - for (bool printed_something{false}; - const auto &[id, elems] : paths) + for (bool printed_something {false}; const auto& [id, elems] : paths) { if (exchange(printed_something, true)) output << ", "; output << R"({"var": ")" << symbol_table.getName(id) << R"(", )" << R"("values": [)"; - for (bool printed_something2{false}; - const auto &[period1, period2, value] : elems) + for (bool printed_something2 {false}; const auto& [period1, period2, value] : elems) { if (exchange(printed_something2, true)) output << ", "; @@ -680,38 +664,35 @@ ConditionalForecastPathsStatement::writeJsonOutput(ostream &output) const } MomentCalibration::MomentCalibration(constraints_t constraints_arg, - const SymbolTable &symbol_table_arg) - : constraints{move(constraints_arg)}, symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + constraints {move(constraints_arg)}, symbol_table {symbol_table_arg} { } void -MomentCalibration::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +MomentCalibration::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "options_.endogenous_prior_restrictions.moment = {" << endl; - for (const auto &c : constraints) + for (const auto& c : constraints) { output << "'" << symbol_table.getName(c.endo1) << "', " - << "'" << symbol_table.getName(c.endo2) << "', " - << c.lags << ", " + << "'" << symbol_table.getName(c.endo2) << "', " << c.lags << ", " << "[ "; c.lower_bound->writeOutput(output); output << ", "; c.upper_bound->writeOutput(output); - output << " ];" - << endl; + output << " ];" << endl; } output << "};" << endl; } void -MomentCalibration::writeJsonOutput(ostream &output) const +MomentCalibration::writeJsonOutput(ostream& output) const { output << R"({"statementName": "moment_calibration")" << R"(, "moment_calibration_criteria": [)"; - for (bool printed_something{false}; - const auto &c : constraints) + for (bool printed_something {false}; const auto& c : constraints) { if (exchange(printed_something, true)) output << ", "; @@ -730,37 +711,36 @@ MomentCalibration::writeJsonOutput(ostream &output) const << "}"; } -IrfCalibration::IrfCalibration(constraints_t constraints_arg, - const SymbolTable &symbol_table_arg, - OptionsList options_list_arg) - : constraints{move(constraints_arg)}, symbol_table{symbol_table_arg}, options_list{move(options_list_arg)} +IrfCalibration::IrfCalibration(constraints_t constraints_arg, const SymbolTable& symbol_table_arg, + OptionsList options_list_arg) : + constraints {move(constraints_arg)}, + symbol_table {symbol_table_arg}, + options_list {move(options_list_arg)} { } void -IrfCalibration::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +IrfCalibration::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { options_list.writeOutput(output); output << "options_.endogenous_prior_restrictions.irf = {" << endl; - for (const auto &c : constraints) + for (const auto& c : constraints) { output << "'" << symbol_table.getName(c.endo) << "', " - << "'" << symbol_table.getName(c.exo) << "', " - << c.periods << ", " + << "'" << symbol_table.getName(c.exo) << "', " << c.periods << ", " << "[ "; c.lower_bound->writeOutput(output); output << ", "; c.upper_bound->writeOutput(output); - output << " ];" - << endl; + output << " ];" << endl; } output << "};" << endl; } void -IrfCalibration::writeJsonOutput(ostream &output) const +IrfCalibration::writeJsonOutput(ostream& output) const { output << R"({"statementName": "irf_calibration")"; if (!options_list.empty()) @@ -770,8 +750,7 @@ IrfCalibration::writeJsonOutput(ostream &output) const } output << R"(, "irf_restrictions": [)"; - for (bool printed_something{false}; - const auto &c : constraints) + for (bool printed_something {false}; const auto& c : constraints) { if (exchange(printed_something, true)) output << ", "; @@ -790,20 +769,20 @@ IrfCalibration::writeJsonOutput(ostream &output) const << "}"; } -ShockGroupsStatement::ShockGroupsStatement(group_t shock_groups_arg, string name_arg) - : shock_groups{move(shock_groups_arg)}, name{move(name_arg)} +ShockGroupsStatement::ShockGroupsStatement(group_t shock_groups_arg, string name_arg) : + shock_groups {move(shock_groups_arg)}, name {move(name_arg)} { } void -ShockGroupsStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +ShockGroupsStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { int i = 1; for (auto it = shock_groups.begin(); it != shock_groups.end(); ++it) { - bool unique_label{true}; - for (auto it1 = it+1; it1 != shock_groups.end(); ++it1) + bool unique_label {true}; + for (auto it1 = it + 1; it1 != shock_groups.end(); ++it1) if (it->name == it1->name) { unique_label = false; @@ -814,11 +793,10 @@ ShockGroupsStatement::writeOutput(ostream &output, [[maybe_unused]] const string if (unique_label) { - output << "M_.shock_groups." << name - << ".group" << i << ".label = '" << it->name << "';" << endl - << "M_.shock_groups." << name - << ".group" << i << ".shocks = {"; - for (const auto &it1 : it->list) + output << "M_.shock_groups." << name << ".group" << i << ".label = '" << it->name << "';" + << endl + << "M_.shock_groups." << name << ".group" << i << ".shocks = {"; + for (const auto& it1 : it->list) output << " '" << it1 << "'"; output << "};" << endl; i++; @@ -827,14 +805,14 @@ ShockGroupsStatement::writeOutput(ostream &output, [[maybe_unused]] const string } void -ShockGroupsStatement::writeJsonOutput(ostream &output) const +ShockGroupsStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "shock_groups", "name": ")" << name << R"(", "groups": [)"; - bool printed_something{false}; + bool printed_something {false}; for (auto it = shock_groups.begin(); it != shock_groups.end(); ++it) { - bool unique_label{true}; - for (auto it1 = it+1; it1 != shock_groups.end(); ++it1) + bool unique_label {true}; + for (auto it1 = it + 1; it1 != shock_groups.end(); ++it1) if (it->name == it1->name) { unique_label = false; @@ -847,8 +825,7 @@ ShockGroupsStatement::writeJsonOutput(ostream &output) const output << ", "; output << R"({"group_name": ")" << it->name << R"(",)" << R"("shocks": [)"; - for (bool printed_something2{false}; - const auto &it1 : it->list) + for (bool printed_something2 {false}; const auto& it1 : it->list) { if (exchange(printed_something2, true)) output << ", "; @@ -861,14 +838,14 @@ ShockGroupsStatement::writeJsonOutput(ostream &output) const } Init2shocksStatement::Init2shocksStatement(vector> init2shocks_arg, string name_arg, - const SymbolTable &symbol_table_arg) - : init2shocks{move(init2shocks_arg)}, name{move(name_arg)}, symbol_table{symbol_table_arg} + const SymbolTable& symbol_table_arg) : + init2shocks {move(init2shocks_arg)}, name {move(name_arg)}, symbol_table {symbol_table_arg} { } void -Init2shocksStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +Init2shocksStatement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { for (size_t i = 0; i < init2shocks.size(); i++) for (size_t j = i + 1; j < init2shocks.size(); j++) @@ -882,21 +859,21 @@ Init2shocksStatement::checkPass([[maybe_unused]] ModFileStructure &mod_file_stru } void -Init2shocksStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +Init2shocksStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << "M_.init2shocks." << name << " = {" << endl; - for (const auto &[id1, id2] : init2shocks) - output << "{'" << symbol_table.getName(id1) << "', '" << symbol_table.getName(id2) << "'};" << endl; + for (const auto& [id1, id2] : init2shocks) + output << "{'" << symbol_table.getName(id1) << "', '" << symbol_table.getName(id2) << "'};" + << endl; output << "};" << endl; } void -Init2shocksStatement::writeJsonOutput(ostream &output) const +Init2shocksStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "init2shocks", "name": ")" << name << R"(", "groups": [)"; - for (bool printed_something{false}; - const auto &[id1, id2] : init2shocks) + for (bool printed_something {false}; const auto& [id1, id2] : init2shocks) { if (exchange(printed_something, true)) output << ","; @@ -906,17 +883,19 @@ Init2shocksStatement::writeJsonOutput(ostream &output) const output << "]}"; } -HeteroskedasticShocksStatement::HeteroskedasticShocksStatement(bool overwrite_arg, - heteroskedastic_shocks_t values_arg, - heteroskedastic_shocks_t scales_arg, - const SymbolTable &symbol_table_arg) - : overwrite{overwrite_arg}, values{move(values_arg)}, scales{move(scales_arg)}, - symbol_table{symbol_table_arg} +HeteroskedasticShocksStatement::HeteroskedasticShocksStatement( + bool overwrite_arg, heteroskedastic_shocks_t values_arg, heteroskedastic_shocks_t scales_arg, + const SymbolTable& symbol_table_arg) : + overwrite {overwrite_arg}, + values {move(values_arg)}, + scales {move(scales_arg)}, + symbol_table {symbol_table_arg} { } void -HeteroskedasticShocksStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +HeteroskedasticShocksStatement::writeOutput(ostream& output, + [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { // NB: The first initialization of the fields is done in ModFile::writeMOutput() @@ -924,43 +903,40 @@ HeteroskedasticShocksStatement::writeOutput(ostream &output, [[maybe_unused]] co output << "M_.heteroskedastic_shocks.Qvalue_orig = [];" << endl << "M_.heteroskedastic_shocks.Qscale_orig = [];" << endl; - for (const auto &[symb_id, vec] : values) + for (const auto& [symb_id, vec] : values) for (int tsid = symbol_table.getTypeSpecificID(symb_id); - const auto &[period1, period2, value] : vec) + const auto& [period1, period2, value] : vec) { - output << "M_.heteroskedastic_shocks.Qvalue_orig = [M_.heteroskedastic_shocks.Qvalue_orig; struct('exo_id', " - << tsid+1 << ",'periods'," - << period1 << ":" << period2 << ",'value',"; + output << "M_.heteroskedastic_shocks.Qvalue_orig = [M_.heteroskedastic_shocks.Qvalue_orig; " + "struct('exo_id', " + << tsid + 1 << ",'periods'," << period1 << ":" << period2 << ",'value',"; value->writeOutput(output); output << ")];" << endl; } - for (const auto &[symb_id, vec] : scales) + for (const auto& [symb_id, vec] : scales) for (int tsid = symbol_table.getTypeSpecificID(symb_id); - const auto &[period1, period2, scale] : vec) + const auto& [period1, period2, scale] : vec) { - output << "M_.heteroskedastic_shocks.Qscale_orig = [M_.heteroskedastic_shocks.Qscale_orig; struct('exo_id', " - << tsid+1 << ",'periods'," - << period1 << ":" << period2 << ",'scale',"; + output << "M_.heteroskedastic_shocks.Qscale_orig = [M_.heteroskedastic_shocks.Qscale_orig; " + "struct('exo_id', " + << tsid + 1 << ",'periods'," << period1 << ":" << period2 << ",'scale',"; scale->writeOutput(output); output << ")];" << endl; } } void -HeteroskedasticShocksStatement::writeJsonOutput(ostream &output) const +HeteroskedasticShocksStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "heteroskedastic_shocks")" - << R"(, "overwrite": )" << boolalpha << overwrite - << R"(, "shocks_values": [)"; - for (bool printed_something{false}; - const auto &[symb_id, vec] : values) + << R"(, "overwrite": )" << boolalpha << overwrite << R"(, "shocks_values": [)"; + for (bool printed_something {false}; const auto& [symb_id, vec] : values) { if (exchange(printed_something, true)) output << ", "; output << R"({"var": ")" << symbol_table.getName(symb_id) << R"(", )" << R"("values": [)"; - for (bool printed_something2{false}; - const auto &[period1, period2, value] : vec) + for (bool printed_something2 {false}; const auto& [period1, period2, value] : vec) { if (exchange(printed_something2, true)) output << ", "; @@ -973,15 +949,13 @@ HeteroskedasticShocksStatement::writeJsonOutput(ostream &output) const output << "]}"; } output << R"(], "shocks_scales": [)"; - for (bool printed_something{false}; - const auto &[symb_id, vec] : scales) + for (bool printed_something {false}; const auto& [symb_id, vec] : scales) { if (exchange(printed_something, true)) output << ", "; output << R"({"var": ")" << symbol_table.getName(symb_id) << R"(", )" << R"("scales": [)"; - for (bool printed_something2{false}; - const auto &[period1, period2, value] : vec) + for (bool printed_something2 {false}; const auto& [period1, period2, value] : vec) { if (exchange(printed_something2, true)) output << ", "; diff --git a/src/Shocks.hh b/src/Shocks.hh index 43573760..7c4e71bb 100644 --- a/src/Shocks.hh +++ b/src/Shocks.hh @@ -20,13 +20,13 @@ #ifndef _SHOCKS_HH #define _SHOCKS_HH +#include #include #include -#include +#include "ExprNode.hh" #include "Statement.hh" #include "SymbolTable.hh" -#include "ExprNode.hh" using namespace std; @@ -36,24 +36,26 @@ public: // The tuple is (period1, period2, value) using det_shocks_t = map>>; enum class ShockType - { - level, // The value is the level of the exogenous (“values” statement in “shocks”) - multiplySteadyState, // The value is the ratio of the exogenous over its (terminal) steady state (“values” statement in “mshocks”) - multiplyInitialSteadyState // The value is the ratio of the exogenous over its initial steady state (“values” statement in “mshocks(relative_to_initval)”) - }; + { + level, // The value is the level of the exogenous (“values” statement in “shocks”) + multiplySteadyState, // The value is the ratio of the exogenous over its (terminal) steady state + // (“values” statement in “mshocks”) + multiplyInitialSteadyState // The value is the ratio of the exogenous over its initial steady + // state (“values” statement in “mshocks(relative_to_initval)”) + }; + protected: //! Does this "shocks" statement replace the previous ones? const bool overwrite; const ShockType type; // Type of shocks represented by this block const det_shocks_t det_shocks; - const SymbolTable &symbol_table; - void writeDetShocks(ostream &output) const; - void writeJsonDetShocks(ostream &output) const; + const SymbolTable& symbol_table; + void writeDetShocks(ostream& output) const; + void writeJsonDetShocks(ostream& output) const; static string typeToString(ShockType type); - AbstractShocksStatement(bool overwrite_arg, ShockType type_arg, - det_shocks_t det_shocks_arg, - const SymbolTable &symbol_table_arg); + AbstractShocksStatement(bool overwrite_arg, ShockType type_arg, det_shocks_t det_shocks_arg, + const SymbolTable& symbol_table_arg); }; class ShocksStatement : public AbstractShocksStatement @@ -61,36 +63,35 @@ class ShocksStatement : public AbstractShocksStatement public: using var_and_std_shocks_t = map; using covar_and_corr_shocks_t = map, expr_t>; + private: const var_and_std_shocks_t var_shocks, std_shocks; const covar_and_corr_shocks_t covar_shocks, corr_shocks; - void writeVarOrStdShock(ostream &output, const pair &it, bool stddev) const; - void writeVarAndStdShocks(ostream &output) const; - void writeCovarOrCorrShock(ostream &output, const pair, expr_t> &it, bool corr) const; - void writeCovarAndCorrShocks(ostream &output) const; + void writeVarOrStdShock(ostream& output, const pair& it, bool stddev) const; + void writeVarAndStdShocks(ostream& output) const; + void writeCovarOrCorrShock(ostream& output, const pair, expr_t>& it, + bool corr) const; + void writeCovarAndCorrShocks(ostream& output) const; bool has_calibrated_measurement_errors() const; + public: - ShocksStatement(bool overwrite_arg, - det_shocks_t det_shocks_arg, - var_and_std_shocks_t var_shocks_arg, - var_and_std_shocks_t std_shocks_arg, - covar_and_corr_shocks_t covar_shocks_arg, - covar_and_corr_shocks_t corr_shocks_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; - void writeJsonOutput(ostream &output) const override; + ShocksStatement(bool overwrite_arg, det_shocks_t det_shocks_arg, + var_and_std_shocks_t var_shocks_arg, var_and_std_shocks_t std_shocks_arg, + covar_and_corr_shocks_t covar_shocks_arg, covar_and_corr_shocks_t corr_shocks_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; + void writeJsonOutput(ostream& output) const override; }; class MShocksStatement : public AbstractShocksStatement { public: const bool relative_to_initval; - MShocksStatement(bool overwrite_arg, bool relative_to_initval_arg, - det_shocks_t det_shocks_arg, - const SymbolTable &symbol_table_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + MShocksStatement(bool overwrite_arg, bool relative_to_initval_arg, det_shocks_t det_shocks_arg, + const SymbolTable& symbol_table_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; /* Represents a shocks(surprise) block. @@ -102,15 +103,17 @@ public: //! Does this "shocks(surprise)" statement replace the previous ones? const bool overwrite; const AbstractShocksStatement::det_shocks_t surprise_shocks; + private: - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: ShocksSurpriseStatement(bool overwrite_arg, AbstractShocksStatement::det_shocks_t surprise_shocks_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; - void writeJsonOutput(ostream &output) const override; + 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; + void writeJsonOutput(ostream& output) const override; }; /* Represents a shocks(learnt_in=…) or mshocks(learnt_in=…) block. @@ -123,40 +126,48 @@ public: //! Does this “shocks(learnt_in=…)” or “mshocks(learnt_in=…)” block replace the previous ones? const bool overwrite; enum class LearntShockType - { - level, // The value is the level of the exogenous (“values” statement in “shocks(learnt_in=…)”) - add, // The value is the additive change of the exogenous compared to previous information period (“add” statement in “shocks(learnt_in=…)”) - multiply, // The value is the multiplicative change of the exogenous compared to previous information period (“multiply” statement in “shocks(learnt_in=…)”) - multiplySteadyState, // The value is the ratio of the exogenous over its (terminal) steady state as anticipated in the same informational period (“values” statement in “mshocks(learnt_in=…)”) - multiplyInitialSteadyState // The value is the ratio of the exogenous over its initial steady state as anticipated in the same informational period (“values” statement in “mshocks(learnt_in=…, relative_to_initval)”) - }; + { + level, // The value is the level of the exogenous (“values” statement in “shocks(learnt_in=…)”) + add, // The value is the additive change of the exogenous compared to previous information + // period (“add” statement in “shocks(learnt_in=…)”) + multiply, // The value is the multiplicative change of the exogenous compared to previous + // information period (“multiply” statement in “shocks(learnt_in=…)”) + multiplySteadyState, // The value is the ratio of the exogenous over its (terminal) steady state + // as anticipated in the same informational period (“values” statement in + // “mshocks(learnt_in=…)”) + multiplyInitialSteadyState // The value is the ratio of the exogenous over its initial steady + // state as anticipated in the same informational period (“values” + // statement in “mshocks(learnt_in=…, relative_to_initval)”) + }; // The tuple is (type, period1, period2, value) using learnt_shocks_t = map>>; const learnt_shocks_t learnt_shocks; + private: - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; static string typeToString(LearntShockType type); + public: ShocksLearntInStatement(int learnt_in_period_arg, bool overwrite_arg, - learnt_shocks_t learnt_shocks_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; - void writeJsonOutput(ostream &output) const override; + learnt_shocks_t learnt_shocks_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; + void writeJsonOutput(ostream& output) const override; }; class ConditionalForecastPathsStatement : public Statement { private: const AbstractShocksStatement::det_shocks_t paths; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; const int path_length; + public: ConditionalForecastPathsStatement(AbstractShocksStatement::det_shocks_t paths_arg, - const SymbolTable &symbol_table_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; - static int computePathLength(const AbstractShocksStatement::det_shocks_t &paths); + const SymbolTable& symbol_table_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; + static int computePathLength(const AbstractShocksStatement::det_shocks_t& paths); }; class MomentCalibration : public Statement @@ -169,14 +180,15 @@ public: expr_t lower_bound, upper_bound; }; using constraints_t = vector; + private: constraints_t constraints; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: - MomentCalibration(constraints_t constraints_arg, - const SymbolTable &symbol_table_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + MomentCalibration(constraints_t constraints_arg, const SymbolTable& symbol_table_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class IrfCalibration : public Statement @@ -190,16 +202,17 @@ public: expr_t lower_bound, upper_bound; }; using constraints_t = vector; + private: constraints_t constraints; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; const OptionsList options_list; + public: - IrfCalibration(constraints_t constraints_arg, - const SymbolTable &symbol_table_arg, + IrfCalibration(constraints_t constraints_arg, const SymbolTable& symbol_table_arg, OptionsList options_list_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class ShockGroupsStatement : public Statement @@ -211,13 +224,15 @@ public: vector list; }; using group_t = vector; + private: group_t shock_groups; string name; + public: ShockGroupsStatement(group_t shock_groups_arg, string name_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class Init2shocksStatement : public Statement @@ -225,12 +240,14 @@ class Init2shocksStatement : public Statement private: const vector> init2shocks; const string name; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: - Init2shocksStatement(vector> init2shocks_arg, string name_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; - void writeJsonOutput(ostream &output) const override; + Init2shocksStatement(vector> init2shocks_arg, string name_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; + void writeJsonOutput(ostream& output) const override; }; class HeteroskedasticShocksStatement : public Statement @@ -238,16 +255,18 @@ class HeteroskedasticShocksStatement : public Statement public: // Maps exo symb_id to list of tuples (period1, period2, value/scale) using heteroskedastic_shocks_t = map>>; + private: const bool overwrite; const heteroskedastic_shocks_t values, scales; - const SymbolTable &symbol_table; + const SymbolTable& symbol_table; + public: HeteroskedasticShocksStatement(bool overwrite_arg, heteroskedastic_shocks_t values_arg, heteroskedastic_shocks_t scales_arg, - const SymbolTable &symbol_table_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + const SymbolTable& symbol_table_arg); + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; #endif diff --git a/src/Statement.cc b/src/Statement.cc index b4c357f4..dc86196e 100644 --- a/src/Statement.cc +++ b/src/Statement.cc @@ -25,23 +25,23 @@ #include void -Statement::checkPass([[maybe_unused]] ModFileStructure &mod_file_struct, - [[maybe_unused]] WarningConsolidation &warnings) +Statement::checkPass([[maybe_unused]] ModFileStructure& mod_file_struct, + [[maybe_unused]] WarningConsolidation& warnings) { } void -Statement::computingPass([[maybe_unused]] const ModFileStructure &mod_file_struct) +Statement::computingPass([[maybe_unused]] const ModFileStructure& mod_file_struct) { } NativeStatement::NativeStatement(string native_statement_arg) : - native_statement{move(native_statement_arg)} + native_statement {move(native_statement_arg)} { } void -NativeStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +NativeStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { using namespace boost::xpressive; @@ -50,12 +50,12 @@ NativeStatement::writeOutput(ostream &output, [[maybe_unused]] const string &bas sregex regex_dollar = sregex::compile(R"((\$))" + date_regex); string ns = regex_replace(native_statement, regex_lookbehind, "dates('$&')"); - ns = regex_replace(ns, regex_dollar, "$2"); //replace $DATE with DATE + ns = regex_replace(ns, regex_dollar, "$2"); // replace $DATE with DATE output << ns << endl; } void -NativeStatement::writeJsonOutput(ostream &output) const +NativeStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "native")" << R"(, "string": ")"; @@ -65,55 +65,55 @@ NativeStatement::writeJsonOutput(ostream &output) const switch (ch) { case '\b': - output << R"(\b)"; - break; + output << R"(\b)"; + break; case '\f': - output << R"(\f)"; - break; + output << R"(\f)"; + break; case '\n': - output << R"(\n)"; - break; + output << R"(\n)"; + break; case '\r': - output << R"(\r)"; - break; + output << R"(\r)"; + break; case '\t': - output << R"(\t)"; - break; + output << R"(\t)"; + break; case '"': - output << R"(\")"; - break; + output << R"(\")"; + break; case '\\': - output << R"(\\)"; + output << R"(\\)"; break; default: - output << ch; - break; + output << ch; + break; } output << R"("})"; } VerbatimStatement::VerbatimStatement(string verbatim_statement_arg) : - verbatim_statement{move(verbatim_statement_arg)} + verbatim_statement {move(verbatim_statement_arg)} { } void -VerbatimStatement::writeOutput(ostream &output, [[maybe_unused]] const string &basename, +VerbatimStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, [[maybe_unused]] bool minimal_workspace) const { output << verbatim_statement << endl; } void -VerbatimStatement::writeJsonOutput(ostream &output) const +VerbatimStatement::writeJsonOutput(ostream& output) const { output << R"({"statementName": "verbatim")" << R"(, "string": ")"; @@ -123,55 +123,55 @@ VerbatimStatement::writeJsonOutput(ostream &output) const switch (ch) { case '\b': - output << R"(\b)"; - break; + output << R"(\b)"; + break; case '\f': - output << R"(\f)"; - break; + output << R"(\f)"; + break; case '\n': - output << R"(\n)"; - break; + output << R"(\n)"; + break; case '\r': - output << R"(\r)"; - break; + output << R"(\r)"; + break; case '\t': - output << R"(\t)"; - break; + output << R"(\t)"; + break; case '"': - output << R"(\")"; - break; + output << R"(\")"; + break; case '\\': - output << R"(\\)"; + output << R"(\\)"; break; default: - output << ch; - break; + output << ch; + break; } output << R"("})"; } void -OptionsList::writeOutput(ostream &output) const +OptionsList::writeOutput(ostream& output) const { writeOutputCommon(output, "options_"); } void -OptionsList::writeOutput(ostream &output, const string &option_group) const +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; + output << "if ~isfield(" << option_group.substr(0, idx) << ",'" + << option_group.substr(idx + 1) << "')" << endl; output << " " << option_group << " = struct();" << endl; output << "end" << endl; } @@ -182,146 +182,145 @@ OptionsList::writeOutput(ostream &output, const string &option_group) const } void -OptionsList::writeOutputCommon(ostream &output, const string &option_group) const +OptionsList::writeOutputCommon(ostream& output, const string& option_group) const { - for (const auto &[name, val] : options) - std::visit([&](const T &v) - { - if constexpr(is_same_v) - v.writeOutput(option_group + "." + name, output); - else - { - output << option_group << "." << name << " = "; - if constexpr(is_same_v || is_same_v) - output << v; - else if constexpr(is_same_v>) - output << '[' << v.first << "; " << v.second << ']'; - else if constexpr(is_same_v) - output << "'" << v << "'"; - else if constexpr(is_same_v>) + for (const auto& [name, val] : options) + std::visit( + [&](const T& v) { + if constexpr (is_same_v) + v.writeOutput(option_group + "." + name, output); + else { - if (v.size() > 1) + output << option_group << "." << name << " = "; + if constexpr (is_same_v || is_same_v) + output << v; + else if constexpr (is_same_v>) + output << '[' << v.first << "; " << v.second << ']'; + else if constexpr (is_same_v) + output << "'" << v << "'"; + else if constexpr (is_same_v>) { - output << '['; - for (int it : v) - output << it << ";"; - output << ']'; + if (v.size() > 1) + { + output << '['; + for (int it : v) + output << it << ";"; + output << ']'; + } + else + output << v.front(); } - else - output << v.front(); - } - else if constexpr(is_same_v) - { - if (v.size() > 1) + else if constexpr (is_same_v) { + if (v.size() > 1) + { + output << '{'; + for (const auto& it : v) + output << "'" << it << "';"; + output << '}'; + } + else + output << v.front(); + } + else if constexpr (is_same_v) + { + /* VecCellStrVal should ideally be merged into VecStrVal. + only difference is treatment of v.size==1, where VecStrVal + does not add quotes and curly brackets, i.e. allows for type conversion of + '2' into the number 2 */ output << '{'; - for (const auto &it : v) + for (const auto& it : v) output << "'" << it << "';"; output << '}'; } - else - output << v.front(); - } - else if constexpr(is_same_v) - { - /* VecCellStrVal should ideally be merged into VecStrVal. - only difference is treatment of v.size==1, where VecStrVal - does not add quotes and curly brackets, i.e. allows for type conversion of - '2' into the number 2 */ - output << '{'; - for (const auto &it : v) - output << "'" << it << "';"; - output << '}'; - } - else if constexpr(is_same_v) - { - /* For historical reason, those vectors are output as row vectors (contrary - to vectors of integers which are output as column vectors) */ - output << '['; - for (const auto &it : v) - output << it << ','; - output << ']'; - } - else if constexpr(is_same_v>>) - { - // Same remark as for VecValueVal - output << '{'; - for (const auto &v2 : v) + else if constexpr (is_same_v) { + /* For historical reason, those vectors are output as row vectors (contrary + to vectors of integers which are output as column vectors) */ output << '['; - for (const auto &it : v2) + for (const auto& it : v) output << it << ','; - output << "], "; + output << ']'; } - output << '}'; + else if constexpr (is_same_v>>) + { + // Same remark as for VecValueVal + output << '{'; + for (const auto& v2 : v) + { + output << '['; + for (const auto& it : v2) + output << it << ','; + output << "], "; + } + output << '}'; + } + else + static_assert(always_false_v, "Non-exhaustive visitor!"); + output << ";" << endl; } - else - static_assert(always_false_v, "Non-exhaustive visitor!"); - output << ";" << endl; - } - }, val); + }, + val); } void -OptionsList::writeJsonOutput(ostream &output) const +OptionsList::writeJsonOutput(ostream& output) const { if (empty()) return; output << R"("options": {)"; - for (bool opt_written {false}; - const auto &[name, val] : options) + for (bool opt_written {false}; const auto& [name, val] : options) { if (exchange(opt_written, true)) output << ", "; output << R"(")" << name << R"(": )"; - std::visit([&](const T &v) - { - if constexpr(is_same_v) - output << v; - else if constexpr(is_same_v>) - output << '[' << v.first << ", " << v.second << ']'; - else if constexpr(is_same_v || is_same_v) - output << '"' << v << '"'; - else if constexpr(is_same_v) - { - output << '{'; - v.writeJsonOutput(output); - output << '}'; - } - else if constexpr(is_same_v> || is_same_v - || is_same_v || is_same_v - || is_same_v>>) - { - output << '['; - for (bool printed_something{false}; - const auto &it : v) + std::visit( + [&](const T& v) { + if constexpr (is_same_v) + output << v; + else if constexpr (is_same_v>) + output << '[' << v.first << ", " << v.second << ']'; + else if constexpr (is_same_v || is_same_v) + output << '"' << v << '"'; + else if constexpr (is_same_v) { - if (exchange(printed_something, true)) - output << ", "; - if constexpr(is_same_v> || is_same_v) - output << it; - else if constexpr(is_same_v || is_same_v) - output << '"' << it << '"'; - else // vector> - { - output << '['; - for (bool printed_something2{false}; - const auto &it2 : it) - { - if (exchange(printed_something2, true)) - output << ", "; - output << it2; - } - output << ']'; - } + output << '{'; + v.writeJsonOutput(output); + output << '}'; } - output << ']'; - } - else - static_assert(always_false_v, "Non-exhaustive visitor!"); - }, val); + else if constexpr (is_same_v> || is_same_v + || is_same_v || is_same_v + || is_same_v>>) + { + output << '['; + for (bool printed_something {false}; const auto& it : v) + { + if (exchange(printed_something, true)) + output << ", "; + if constexpr (is_same_v> || is_same_v) + output << it; + else if constexpr (is_same_v || is_same_v) + output << '"' << it << '"'; + else // vector> + { + output << '['; + for (bool printed_something2 {false}; const auto& it2 : it) + { + if (exchange(printed_something2, true)) + output << ", "; + output << it2; + } + output << ']'; + } + } + output << ']'; + } + else + static_assert(always_false_v, "Non-exhaustive visitor!"); + }, + val); } output << "}"; @@ -334,13 +333,13 @@ OptionsList::clear() } bool -OptionsList::contains(const string &name) const +OptionsList::contains(const string& name) const { return options.contains(name); } void -OptionsList::erase(const string &name) +OptionsList::erase(const string& name) { options.erase(name); } diff --git a/src/Statement.hh b/src/Statement.hh index 3fba9395..2206aec4 100644 --- a/src/Statement.hh +++ b/src/Statement.hh @@ -20,11 +20,11 @@ #ifndef _STATEMENT_HH #define _STATEMENT_HH -#include -#include #include -#include #include +#include +#include +#include #include #include "SymbolList.hh" @@ -33,102 +33,104 @@ struct ModFileStructure { //! Whether check is present - bool check_present{false}; + bool check_present {false}; //! Whether steady is present - bool steady_present{false}; + bool steady_present {false}; //! Whether a perfect_foresight_solver/simul statement is present - bool perfect_foresight_solver_present{false}; + bool perfect_foresight_solver_present {false}; //! Whether a perfect_foresight_with_expectation_errors_solver statement is present - bool perfect_foresight_with_expectation_errors_solver_present{false}; + bool perfect_foresight_with_expectation_errors_solver_present {false}; //! Whether a stoch_simul statement is present - bool stoch_simul_present{false}; + bool stoch_simul_present {false}; //! Whether an estimation statement is present - bool estimation_present{false}; + bool estimation_present {false}; //! Whether an osr statement is present - bool osr_present{false}; + bool osr_present {false}; //! Whether an osr params statement is present - bool osr_params_present{false}; + bool osr_params_present {false}; //! Whether an optim weight statement is present - bool optim_weights_present{false}; + bool optim_weights_present {false}; //! Whether a ramsey_model statement is present - bool ramsey_model_present{false}; + bool ramsey_model_present {false}; //! Whether a discretionary_objective statement is present - bool discretionary_policy_present{false}; + bool discretionary_policy_present {false}; //! Whether a planner_objective statement is present - bool planner_objective_present{false}; + bool planner_objective_present {false}; //! Whether an extended_path statement is present - bool extended_path_present{false}; + bool extended_path_present {false}; //! The value of the "order" option of stoch_simul, estimation, osr, ramsey_policy //! Derivation order - /*! First initialized to zero. If user sets order option somewhere in the MOD file, it will be equal to the maximum of order options. Otherwise will default to 2 */ - int order_option{0}; + /*! First initialized to zero. If user sets order option somewhere in the MOD file, it will be + * equal to the maximum of order options. Otherwise will default to 2 */ + int order_option {0}; //! Whether a bvar_density, bvar_forecast, sbvar, ms_sbvar statement is present - bool bvar_present{false}; + bool bvar_present {false}; //! Whether an svar_identification statement is present - bool svar_identification_present{false}; - //! Whether an identification statement is present or the identification option of dynare_sensitivity statement is equal to one - bool identification_present{false}; + bool svar_identification_present {false}; + //! Whether an identification statement is present or the identification option of + //! dynare_sensitivity statement is equal to one + bool identification_present {false}; //! The maximum of the “order” option in identification statements - int identification_order{0}; + int identification_order {0}; //! Whether a sensitivity statement is present - bool sensitivity_present{false}; + bool sensitivity_present {false}; //! Whether the option analytic_derivation is given to estimation - bool estimation_analytic_derivation{false}; + bool estimation_analytic_derivation {false}; //! Whether the option analytic_derivation is given to osr - bool osr_analytic_derivation{false}; + bool osr_analytic_derivation {false}; //! Whether the option partial_information is given to stoch_simul/estimation/osr/ramsey_policy - bool partial_information{false}; + bool partial_information {false}; //! Whether the "k_order_solver" option is used (explictly, or implicitly if order >= 3) - bool k_order_solver{false}; + bool k_order_solver {false}; //! Whether an method_of_moments statement is present - bool mom_estimation_present{false}; + bool mom_estimation_present {false}; //! Whether an GMM-option is present - bool GMM_present{false}; + bool GMM_present {false}; //! Whether an analytic_standard_errors-option is present - bool analytic_standard_errors_present{false}; + bool analytic_standard_errors_present {false}; //! Whether an analytic_jacobian-option is present - bool analytic_jacobian_present{false}; + bool analytic_jacobian_present {false}; //! The maximum of the “order” option in method_of_moments statements - int mom_order{0}; + int mom_order {0}; //! Whether there is a calibrated measurement error - bool calibrated_measurement_errors{false}; + bool calibrated_measurement_errors {false}; //! Whether dsge_prior_weight was initialized as a parameter bool dsge_prior_weight_initialized; //! Whether dsge_prior_weight is in the estimated_params block - bool dsge_prior_weight_in_estimated_params{false}; + bool dsge_prior_weight_in_estimated_params {false}; //! Whether there is a dsge_var, with calibrated prior weight string dsge_var_calibrated; //! Whether there is a dsge_var, with prior weight that must be estimated - bool dsge_var_estimated{false}; + bool dsge_var_estimated {false}; //! Whether there is a bayesian_irf option passed to the estimation statement - bool bayesian_irf_present{false}; + bool bayesian_irf_present {false}; //! Whether there is a data statement present - bool estimation_data_statement_present{false}; + bool estimation_data_statement_present {false}; //! Last chain number for Markov Switching statement2 - int last_markov_switching_chain{0}; + int last_markov_switching_chain {0}; //! Whether a calib_smoother statement is present - bool calib_smoother_present{false}; + bool calib_smoother_present {false}; //! Whether there is an estimated_params_init with use_calibration - bool estim_params_use_calib{false}; + bool estim_params_use_calib {false}; //! Set of parameters used within shocks blocks, inside the expressions //! defining the values of covariances (stored as symbol ids) set parameters_within_shocks_values; //! Set of estimated parameters (stored as symbol ids) set estimated_parameters; //! Whether there is a prior statement present - bool prior_statement_present{false}; + bool prior_statement_present {false}; //! Whether there is a std prior statement present - bool std_prior_statement_present{false}; + bool std_prior_statement_present {false}; //! Whether there is a corr prior statement present - bool corr_prior_statement_present{false}; + bool corr_prior_statement_present {false}; //! Whether there is a options statement present - bool options_statement_present{false}; + bool options_statement_present {false}; //! Whether there is a std options statement present - bool std_options_statement_present{false}; + bool std_options_statement_present {false}; //! Whether there is a corr options statement present - bool corr_options_statement_present{false}; + bool corr_options_statement_present {false}; //! Whether a Markov Switching DSGE is present - bool ms_dsge_present{false}; + bool ms_dsge_present {false}; /* The number of equations in the model present just before adding the Lagrange multipliers and computing the Ramsey FOC; it is by construction equal to the number of Lagrange multipliers that will be added by the @@ -144,31 +146,31 @@ struct ModFileStructure already been added. */ int ramsey_orig_endo_nbr {0}; //! Whether there was a steady_state_model block - bool steady_state_model_present{false}; + bool steady_state_model_present {false}; //! Whether there is a write_latex_steady_state_model statement present - bool write_latex_steady_state_model_present{false}; + bool write_latex_steady_state_model_present {false}; //! Pac growth and discount set pac_params; //! Instruments if ramsey_model, ramsey_policy or discretionary_policy is present SymbolList instruments; /* Whether any of shock_decomposition, realtime_shock_decomposition and initial_condition_decomposition has the “with_epilogue” option */ - bool with_epilogue_option{false}; + bool with_epilogue_option {false}; /* Lists symbol IDs of parameters that appear in a “planner_discount” option. See dynare#1173 for more details. */ set parameters_in_planner_discount; // Whether an endval block (without the learnt_it=… option) appears - bool endval_present{false}; + bool endval_present {false}; // Whether a shocks(surprise) block appears - bool shocks_surprise_present{false}; + bool shocks_surprise_present {false}; // Whether a shocks(learnt_in=…) block appears - bool shocks_learnt_in_present{false}; + bool shocks_learnt_in_present {false}; // Whether an endval(learnt_in=…) block appears - bool endval_learnt_in_present{false}; + bool endval_learnt_in_present {false}; // Whether an occbin_constraints block appears - bool occbin_constraints_present{false}; + bool occbin_constraints_present {false}; // Whether a ramsey_constraints block appears - bool ramsey_constraints_present{false}; + bool ramsey_constraints_present {false}; }; class Statement @@ -177,43 +179,47 @@ public: Statement() = default; virtual ~Statement() = default; - Statement(const Statement &) = delete; - Statement &operator=(const Statement &) = delete; + Statement(const Statement&) = delete; + Statement& operator=(const Statement&) = delete; //! Do some internal check, and fill the ModFileStructure class /*! Don't forget to update ComputingTasks.hh, Shocks.hh and NumericalInitialization.hh if you modify the signature of this method. Otherwise the default implementation (i.e. a no-op) will apply and some checks won't be run. */ - virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); - virtual void computingPass(const ModFileStructure &mod_file_struct); + virtual void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings); + virtual void computingPass(const ModFileStructure& mod_file_struct); //! Write Matlab output code /*! \param output is the output stream of the main matlab file - \param basename is the name of the modfile (without extension) which can be used to build auxiliary files + \param basename is the name of the modfile (without extension) which can be used to build + auxiliary files */ - virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const = 0; - virtual void writeJsonOutput(ostream &output) const = 0; + virtual void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const + = 0; + virtual void writeJsonOutput(ostream& output) const = 0; }; class NativeStatement : public Statement { private: const string native_statement; + public: explicit NativeStatement(string native_statement_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; class VerbatimStatement : public Statement { private: const string verbatim_statement; + public: explicit VerbatimStatement(string verbatim_statement_arg); - void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; - void writeJsonOutput(ostream &output) const override; + void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; + void writeJsonOutput(ostream& output) const override; }; /* Stores a list of named options with their values. @@ -251,15 +257,15 @@ public: bool empty() const; void clear(); // Whether there is an option with that name that has been given a value - bool contains(const string &name) const; + bool contains(const string& name) const; // Erase the option with that name - void erase(const string &name); + void erase(const string& name); /* Declares an option with a name and value. Overwrite any previous value for that name. */ template void - set(string name, T &&val) + set(string name, T&& val) { options.insert_or_assign(move(name), forward(val)); } @@ -267,7 +273,7 @@ public: struct UnknownOptionException { const string name; - UnknownOptionException(string name_arg) : name{move(name_arg)} + UnknownOptionException(string name_arg) : name {move(name_arg)} { } }; @@ -277,13 +283,13 @@ public: Throws bad_variant_access if the option has a value of a different type. */ template T - get(const string &name) const + get(const string& name) const { auto it = options.find(name); if (it != options.end()) return std::get(it->second); else - throw UnknownOptionException{name}; + throw UnknownOptionException {name}; } /* Retrieves the value of the option with that name. @@ -291,7 +297,7 @@ public: Throws bad_variant_access if the option has a value of a different type. */ template optional - get_if(const string &name) const + get_if(const string& name) const { auto it = options.find(name); if (it != options.end()) @@ -304,27 +310,29 @@ public: Throws UnknownOptionException if there is no option with that name. */ template decltype(auto) - visit(const string &name, Visitor &&vis) const + visit(const string& name, Visitor&& vis) const { auto it = options.find(name); if (it != options.end()) return std::visit(forward(vis), it->second); else - throw UnknownOptionException{name}; + throw UnknownOptionException {name}; } - void writeOutput(ostream &output) const; - void writeOutput(ostream &output, const string &option_group) const; - void writeJsonOutput(ostream &output) const; + void writeOutput(ostream& output) const; + void writeOutput(ostream& output, const string& option_group) const; + void writeJsonOutput(ostream& output) const; private: // pair corresponds to a pair of numerical values // vector> corresponds to a vector of vectors of numerical values map, StringVal, DateVal, SymbolListVal, vector, - VecStrVal, VecCellStrVal, VecValueVal, vector>>> options; - void writeOutputCommon(ostream &output, const string &option_group) const; + VecStrVal, VecCellStrVal, VecValueVal, vector>>> + options; + void writeOutputCommon(ostream& output, const string& option_group) const; // Helper constant for visitors - template static constexpr bool always_false_v {false}; + template + static constexpr bool always_false_v {false}; }; #endif // ! _STATEMENT_HH diff --git a/src/StaticModel.cc b/src/StaticModel.cc index 10332fad..5ce83bbd 100644 --- a/src/StaticModel.cc +++ b/src/StaticModel.cc @@ -17,47 +17,46 @@ * along with Dynare. If not, see . */ -#include +#include +#include #include #include -#include -#include -#include +#include #include +#include #include -#include "StaticModel.hh" #include "DynamicModel.hh" +#include "StaticModel.hh" -StaticModel::StaticModel(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants_arg, - ExternalFunctionsTable &external_functions_table_arg) : - ModelTree{symbol_table_arg, num_constants_arg, external_functions_table_arg} +StaticModel::StaticModel(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg, + ExternalFunctionsTable& external_functions_table_arg) : + ModelTree {symbol_table_arg, num_constants_arg, external_functions_table_arg} { } void -StaticModel::copyHelper(const StaticModel &m) +StaticModel::copyHelper(const StaticModel& m) { - auto f = [this](const ExprNode *e) { return e->clone(*this); }; + auto f = [this](const ExprNode* e) { return e->clone(*this); }; - for (const auto &it : m.ramsey_multipliers_derivatives_temporary_terms) + for (const auto& it : m.ramsey_multipliers_derivatives_temporary_terms) ramsey_multipliers_derivatives_temporary_terms.insert(f(it)); - for (const auto &it : m.ramsey_multipliers_derivatives_temporary_terms_idxs) + for (const auto& it : m.ramsey_multipliers_derivatives_temporary_terms_idxs) ramsey_multipliers_derivatives_temporary_terms_idxs.emplace(f(it.first), it.second); } -StaticModel::StaticModel(const StaticModel &m) : - ModelTree{m}, - ramsey_multipliers_derivatives{m.ramsey_multipliers_derivatives}, - ramsey_multipliers_derivatives_sparse_colptr{m.ramsey_multipliers_derivatives_sparse_colptr}, - static_mfs{m.static_mfs} +StaticModel::StaticModel(const StaticModel& m) : + ModelTree {m}, + ramsey_multipliers_derivatives {m.ramsey_multipliers_derivatives}, + ramsey_multipliers_derivatives_sparse_colptr {m.ramsey_multipliers_derivatives_sparse_colptr}, + static_mfs {m.static_mfs} { copyHelper(m); } -StaticModel & -StaticModel::operator=(const StaticModel &m) +StaticModel& +StaticModel::operator=(const StaticModel& m) { ModelTree::operator=(m); @@ -71,8 +70,8 @@ StaticModel::operator=(const StaticModel &m) return *this; } -StaticModel::StaticModel(const DynamicModel &m) : - ModelTree{m.symbol_table, m.num_constants, m.external_functions_table} +StaticModel::StaticModel(const DynamicModel& m) : + ModelTree {m.symbol_table, m.num_constants, m.external_functions_table} { // Convert model local variables (need to be done first) for (int it : m.local_variables_vector) @@ -87,9 +86,9 @@ StaticModel::StaticModel(const DynamicModel &m) : // If equation is dynamic, replace it by an equation marked [static] if (dynamic_equations.contains(i)) { - auto [static_only_equations, - static_only_equations_lineno, - static_only_equations_equation_tags] = m.getStaticOnlyEquationsInfo(); + auto [static_only_equations, static_only_equations_lineno, + static_only_equations_equation_tags] + = m.getStaticOnlyEquationsInfo(); addEquation(static_only_equations[static_only_index]->toStatic(*this), static_only_equations_lineno[static_only_index], @@ -97,13 +96,13 @@ StaticModel::StaticModel(const DynamicModel &m) : static_only_index++; } else - addEquation(m.equations[i]->toStatic(*this), - m.equations_lineno[i], + addEquation(m.equations[i]->toStatic(*this), m.equations_lineno[i], m.equation_tags.getTagsByEqn(i)); } catch (DataTree::DivisionByZeroException) { - cerr << "...division by zero error encountered when converting equation " << i << " to static" << endl; + cerr << "...division by zero error encountered when converting equation " << i + << " to static" << endl; exit(EXIT_FAILURE); } @@ -123,14 +122,14 @@ StaticModel::StaticModel(const DynamicModel &m) : } void -StaticModel::writeStaticBytecode(const string &basename) const +StaticModel::writeStaticBytecode(const string& basename) const { /* Bytecode only works when there are with as many endogenous as equations. (e.g. the constructor of FBEGINBLOCK_ makes this assumption) */ assert(static_cast(equations.size()) == symbol_table.endo_nbr()); // First write the .bin file - int u_count_int { writeBytecodeBinFile(basename + "/model/bytecode/static.bin", false) }; + int u_count_int {writeBytecodeBinFile(basename + "/model/bytecode/static.bin", false)}; BytecodeWriter code_file {basename + "/model/bytecode/static.cod"}; vector eq_idx(equations.size()); @@ -139,23 +138,23 @@ StaticModel::writeStaticBytecode(const string &basename) const iota(endo_idx.begin(), endo_idx.end(), 0); // Declare temporary terms and the (single) block - code_file << FDIMST_{static_cast(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 << FDIMST_ {static_cast(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()}; writeBytecodeHelper(code_file); } void -StaticModel::writeStaticBlockBytecode(const string &basename) const +StaticModel::writeStaticBlockBytecode(const string& basename) const { BytecodeWriter code_file {basename + "/model/bytecode/block/static.cod"}; @@ -168,7 +167,7 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const } // Temporary variables declaration - code_file << FDIMST_{static_cast(blocks_temporary_terms_idxs.size())}; + code_file << FDIMST_ {static_cast(blocks_temporary_terms_idxs.size())}; temporary_terms_t temporary_terms_written; @@ -178,27 +177,29 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const const int block_size {blocks[block].size}; const int u_count {simulation_type == BlockSimulationType::solveBackwardComplete - || simulation_type == BlockSimulationType::solveForwardComplete - ? writeBlockBytecodeBinFile(bin_file, block) - : 0}; + || simulation_type == BlockSimulationType::solveForwardComplete + ? 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 << 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(code_file, block, temporary_terms_written); } - code_file << FEND_{}; + code_file << FEND_ {}; } void -StaticModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll) +StaticModel::computingPass(int derivsOrder, int paramsDerivsOrder, + const eval_context_t& eval_context, bool no_tmp_terms, bool block, + bool use_dll) { initializeVariablesAndEquations(); @@ -209,9 +210,10 @@ StaticModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_co is not needed for parameter derivatives, since tensors for those are not stored as matrices. This check is implemented at this place for symmetry with DynamicModel::computingPass(). */ - if (log2(symbol_table.endo_nbr())*derivsOrder >= numeric_limits::digits) + if (log2(symbol_table.endo_nbr()) * derivsOrder >= numeric_limits::digits) { - cerr << "ERROR: The derivatives matrix of the " << modelClassName() << " is too large. Please decrease the approximation order." << endl; + cerr << "ERROR: The derivatives matrix of the " << modelClassName() + << " is too large. Please decrease the approximation order." << endl; exit(EXIT_FAILURE); } @@ -230,7 +232,8 @@ StaticModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_co if (paramsDerivsOrder > 0) { - cout << "Computing " << modelClassName() << " derivatives w.r.t. parameters (order " << paramsDerivsOrder << ")." << endl; + cout << "Computing " << modelClassName() << " derivatives w.r.t. parameters (order " + << paramsDerivsOrder << ")." << endl; computeParamsDerivatives(paramsDerivsOrder); } @@ -242,42 +245,43 @@ StaticModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_co computingPassBlock(eval_context, no_tmp_terms); if (!block_decomposed && block) { - cerr << "ERROR: Block decomposition requested but failed. If your model does not have a steady state, you may want to try the 'no_static' option of the 'model' block." << endl; + cerr << "ERROR: Block decomposition requested but failed. If your model does not have a " + "steady state, you may want to try the 'no_static' option of the 'model' block." + << endl; exit(EXIT_FAILURE); } } void -StaticModel::writeStaticMFile(const string &basename) const +StaticModel::writeStaticMFile(const string& basename) const { auto [d_output, tt_output] = writeModelFileHelper(); ostringstream init_output, end_output; init_output << "residual = zeros(" << equations.size() << ", 1);"; writeStaticMFileHelper(basename, "static_resid", "residual", "static_resid_tt", - temporary_terms_derivatives[0].size(), - "", init_output, end_output, + temporary_terms_derivatives[0].size(), "", init_output, end_output, d_output[0], tt_output[0]); init_output.str(""); end_output.str(""); init_output << "g1 = zeros(" << equations.size() << ", " << symbol_table.endo_nbr() << ");"; writeStaticMFileHelper(basename, "static_g1", "g1", "static_g1_tt", - temporary_terms_derivatives[0].size() + temporary_terms_derivatives[1].size(), - "static_resid_tt", - init_output, end_output, - d_output[1], tt_output[1]); + temporary_terms_derivatives[0].size() + + temporary_terms_derivatives[1].size(), + "static_resid_tt", init_output, end_output, d_output[1], tt_output[1]); writeStaticMWrapperFunction(basename, "g1"); // For order ≥ 2 - int ncols{symbol_table.endo_nbr()}; - int ntt { static_cast(temporary_terms_derivatives[0].size() + temporary_terms_derivatives[1].size()) }; - for (size_t i{2}; i < derivatives.size(); i++) + int ncols {symbol_table.endo_nbr()}; + int ntt {static_cast(temporary_terms_derivatives[0].size() + + temporary_terms_derivatives[1].size())}; + for (size_t i {2}; i < derivatives.size(); i++) { ncols *= symbol_table.endo_nbr(); ntt += temporary_terms_derivatives[i].size(); - string gname{"g" + to_string(i)}; - string gprevname{"g" + to_string(i-1)}; + string gname {"g" + to_string(i)}; + string gprevname {"g" + to_string(i - 1)}; init_output.str(""); end_output.str(""); @@ -286,18 +290,14 @@ StaticModel::writeStaticMFile(const string &basename) const init_output << gname << "_i = zeros(" << NNZDerivatives[i] << ",1);" << endl << gname << "_j = zeros(" << NNZDerivatives[i] << ",1);" << endl << gname << "_v = zeros(" << NNZDerivatives[i] << ",1);" << endl; - end_output << gname << " = sparse(" - << gname << "_i," << gname << "_j," << gname << "_v," + end_output << gname << " = sparse(" << gname << "_i," << gname << "_j," << gname << "_v," << equations.size() << "," << ncols << ");"; } else init_output << gname << " = sparse([],[],[]," << equations.size() << "," << ncols << ");"; - writeStaticMFileHelper(basename, "static_" + gname, gname, - "static_" + gname + "_tt", - ntt, - "static_" + gprevname + "_tt", - init_output, end_output, - d_output[i], tt_output[i]); + writeStaticMFileHelper(basename, "static_" + gname, gname, "static_" + gname + "_tt", ntt, + "static_" + gprevname + "_tt", init_output, end_output, d_output[i], + tt_output[i]); if (i <= 3) writeStaticMWrapperFunction(basename, gname); } @@ -306,7 +306,7 @@ StaticModel::writeStaticMFile(const string &basename) const } void -StaticModel::writeStaticMWrapperFunction(const string &basename, const string &ending) const +StaticModel::writeStaticMWrapperFunction(const string& basename, const string& ending) const { string name; if (ending == "g1") @@ -317,7 +317,7 @@ StaticModel::writeStaticMWrapperFunction(const string &basename, const string &e name = "static_resid_g1_g2_g3"; filesystem::path filename {packageDir(basename) / (name + ".m")}; - ofstream output{filename, ios::out | ios::binary}; + ofstream output {filename, ios::out | ios::binary}; if (!output.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; @@ -346,10 +346,12 @@ StaticModel::writeStaticMWrapperFunction(const string &basename, const string &e output << " residual = " << basename << ".static_resid(T, y, x, params, false);" << endl << " g1 = " << basename << ".static_g1(T, y, x, params, false);" << endl; else if (ending == "g2") - output << " [residual, g1] = " << basename << ".static_resid_g1(T, y, x, params, false);" << endl + output << " [residual, g1] = " << basename << ".static_resid_g1(T, y, x, params, false);" + << endl << " g2 = " << basename << ".static_g2(T, y, x, params, false);" << endl; else if (ending == "g3") - output << " [residual, g1, g2] = " << basename << ".static_resid_g1_g2(T, y, x, params, false);" << endl + output << " [residual, g1, g2] = " << basename + << ".static_resid_g1_g2(T, y, x, params, false);" << endl << " g3 = " << basename << ".static_g3(T, y, x, params, false);" << endl; output << endl << "end" << endl; @@ -357,15 +359,14 @@ StaticModel::writeStaticMWrapperFunction(const string &basename, const string &e } void -StaticModel::writeStaticMFileHelper(const string &basename, - const string &name, const string &retvalname, - const string &name_tt, size_t ttlen, - const string &previous_tt_name, - const ostringstream &init_s, const ostringstream &end_s, - const ostringstream &s, const ostringstream &s_tt) const +StaticModel::writeStaticMFileHelper(const string& basename, const string& name, + const string& retvalname, const string& name_tt, size_t ttlen, + const string& previous_tt_name, const ostringstream& init_s, + const ostringstream& end_s, const ostringstream& s, + const ostringstream& s_tt) const { filesystem::path filename {packageDir(basename) / (name_tt + ".m")}; - ofstream output{filename, ios::out | ios::binary}; + ofstream output {filename, ios::out | ios::binary}; if (!output.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; @@ -378,22 +379,30 @@ StaticModel::writeStaticMFileHelper(const string &basename, << "% File created by Dynare Preprocessor from .mod file" << endl << "%" << endl << "% Inputs:" << endl - << "% T [#temp variables by 1] double vector of temporary terms to be filled by function" << endl - << "% y [M_.endo_nbr by 1] double vector of endogenous variables in declaration order" << endl - << "% x [M_.exo_nbr by 1] double vector of exogenous variables in declaration order" << endl - << "% params [M_.param_nbr by 1] double vector of parameter values in declaration order" << endl + << "% T [#temp variables by 1] double vector of temporary terms to be filled " + "by function" + << endl + << "% y [M_.endo_nbr by 1] double vector of endogenous variables in " + "declaration order" + << endl + << "% x [M_.exo_nbr by 1] double vector of exogenous variables in " + "declaration order" + << endl + << "% params [M_.param_nbr by 1] double vector of parameter values in " + "declaration order" + << endl << "%" << endl << "% Output:" << endl << "% T [#temp variables by 1] double vector of temporary terms" << endl - << "%" << endl << endl + << "%" << endl + << endl << "assert(length(T) >= " << ttlen << ");" << endl << endl; if (!previous_tt_name.empty()) output << "T = " << basename << "." << previous_tt_name << "(T, y, x, params);" << endl << endl; - output << s_tt.str() << endl - << "end" << endl; + output << s_tt.str() << endl << "end" << endl; output.close(); filename = packageDir(basename) / (name + ".m"); @@ -410,51 +419,64 @@ StaticModel::writeStaticMFileHelper(const string &basename, << "% File created by Dynare Preprocessor from .mod file" << endl << "%" << endl << "% Inputs:" << endl - << "% T [#temp variables by 1] double vector of temporary terms to be filled by function" << endl - << "% y [M_.endo_nbr by 1] double vector of endogenous variables in declaration order" << endl - << "% x [M_.exo_nbr by 1] double vector of exogenous variables in declaration order" << endl - << "% params [M_.param_nbr by 1] double vector of parameter values in declaration order" << endl + << "% T [#temp variables by 1] double vector of temporary terms to be filled " + "by function" + << endl + << "% y [M_.endo_nbr by 1] double vector of endogenous variables in " + "declaration order" + << endl + << "% x [M_.exo_nbr by 1] double vector of exogenous variables in " + "declaration order" + << endl + << "% params [M_.param_nbr by 1] double vector of parameter values in " + "declaration order" + << endl << "% to evaluate the model" << endl - << "% T_flag boolean boolean flag saying whether or not to calculate temporary terms" << endl + << "% T_flag boolean boolean flag saying whether or not to " + "calculate temporary terms" + << endl << "%" << endl << "% Output:" << endl << "% " << retvalname << endl - << "%" << endl << endl; + << "%" << endl + << endl; if (!name_tt.empty()) output << "if T_flag" << endl - << " T = " << basename << "." << name_tt << "(T, y, x, params);" << endl + << " T = " << basename << "." << name_tt << "(T, y, x, params);" << endl << "end" << endl; - output << init_s.str() << endl - << s.str() - << end_s.str() << endl - << "end" << endl; + output << init_s.str() << endl << s.str() << end_s.str() << endl << "end" << endl; output.close(); } void -StaticModel::writeStaticMCompatFile(const string &basename) const +StaticModel::writeStaticMCompatFile(const string& basename) const { filesystem::path filename {packageDir(basename) / "static.m"}; - ofstream output{filename, ios::out | ios::binary}; + ofstream output {filename, ios::out | ios::binary}; if (!output.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; exit(EXIT_FAILURE); } - int ntt { static_cast(temporary_terms_derivatives[0].size() + temporary_terms_derivatives[1].size() + temporary_terms_derivatives[2].size() + temporary_terms_derivatives[3].size()) }; + int ntt {static_cast( + temporary_terms_derivatives[0].size() + temporary_terms_derivatives[1].size() + + temporary_terms_derivatives[2].size() + temporary_terms_derivatives[3].size())}; output << "function [residual, g1, g2, g3] = static(y, x, params)" << endl << " T = NaN(" << ntt << ", 1);" << endl << " if nargout <= 1" << endl << " residual = " << basename << ".static_resid(T, y, x, params, true);" << endl << " elseif nargout == 2" << endl - << " [residual, g1] = " << basename << ".static_resid_g1(T, y, x, params, true);" << endl + << " [residual, g1] = " << basename << ".static_resid_g1(T, y, x, params, true);" + << endl << " elseif nargout == 3" << endl - << " [residual, g1, g2] = " << basename << ".static_resid_g1_g2(T, y, x, params, true);" << endl + << " [residual, g1, g2] = " << basename + << ".static_resid_g1_g2(T, y, x, params, true);" << endl << " else" << endl - << " [residual, g1, g2, g3] = " << basename << ".static_resid_g1_g2_g3(T, y, x, params, true);" << endl + << " [residual, g1, g2, g3] = " << basename + << ".static_resid_g1_g2_g3(T, y, x, params, true);" << endl << " end" << endl << "end" << endl; @@ -462,9 +484,10 @@ StaticModel::writeStaticMCompatFile(const string &basename) const } void -StaticModel::writeStaticFile(const string &basename, bool use_dll, const string &mexext, const filesystem::path &matlabroot, bool julia) const +StaticModel::writeStaticFile(const string& basename, bool use_dll, const string& mexext, + const filesystem::path& matlabroot, bool julia) const { - filesystem::path model_dir{basename}; + filesystem::path model_dir {basename}; model_dir /= "model"; if (use_dll) { @@ -531,10 +554,10 @@ StaticModel::exoPresentInEqs() const } void -StaticModel::writeDriverOutput(ostream &output) const +StaticModel::writeDriverOutput(ostream& output) const { output << "M_.static_tmp_nbr = ["; - for (const auto &temporary_terms_derivative : temporary_terms_derivatives) + for (const auto& temporary_terms_derivative : temporary_terms_derivatives) output << temporary_terms_derivative.size() << "; "; output << "];" << endl; @@ -545,46 +568,47 @@ StaticModel::writeDriverOutput(ostream &output) const } void -StaticModel::writeBlockDriverOutput(ostream &output) const +StaticModel::writeBlockDriverOutput(ostream& output) const { for (int blk = 0; blk < static_cast(blocks.size()); blk++) { - output << "M_.block_structure_stat.block(" << blk+1 << ").Simulation_Type = " << static_cast(blocks[blk].simulation_type) << ";" << endl - << "M_.block_structure_stat.block(" << blk+1 << ").endo_nbr = " << blocks[blk].size << ";" << endl - << "M_.block_structure_stat.block(" << blk+1 << ").mfs = " << blocks[blk].mfs_size << ";" << endl - << "M_.block_structure_stat.block(" << blk+1 << ").equation = ["; + output << "M_.block_structure_stat.block(" << blk + 1 + << ").Simulation_Type = " << static_cast(blocks[blk].simulation_type) << ";" + << endl + << "M_.block_structure_stat.block(" << blk + 1 << ").endo_nbr = " << blocks[blk].size + << ";" << endl + << "M_.block_structure_stat.block(" << blk + 1 << ").mfs = " << blocks[blk].mfs_size + << ";" << endl + << "M_.block_structure_stat.block(" << blk + 1 << ").equation = ["; for (int eq = 0; eq < blocks[blk].size; eq++) - output << " " << getBlockEquationID(blk, eq)+1; - output << "];" << endl - << "M_.block_structure_stat.block(" << blk+1 << ").variable = ["; + output << " " << getBlockEquationID(blk, eq) + 1; + output << "];" << endl << "M_.block_structure_stat.block(" << blk + 1 << ").variable = ["; for (int var = 0; var < blocks[blk].size; var++) - output << " " << getBlockVariableID(blk, var)+1; + output << " " << getBlockVariableID(blk, var) + 1; output << "];" << endl; } output << "M_.block_structure_stat.variable_reordered = ["; for (int i = 0; i < symbol_table.endo_nbr(); i++) - output << " " << endo_idx_block2orig[i]+1; - output << "];" << endl - << "M_.block_structure_stat.equation_reordered = ["; + output << " " << endo_idx_block2orig[i] + 1; + output << "];" << endl << "M_.block_structure_stat.equation_reordered = ["; for (int i = 0; i < symbol_table.endo_nbr(); i++) - output << " " << eq_idx_block2orig[i]+1; + output << " " << eq_idx_block2orig[i] + 1; output << "];" << endl; set> row_incidence; - for (const auto &[indices, d1] : derivatives[1]) - if (int deriv_id = indices[1]; - getTypeByDerivID(deriv_id) == SymbolType::endogenous) + for (const auto& [indices, d1] : derivatives[1]) + if (int deriv_id = indices[1]; getTypeByDerivID(deriv_id) == SymbolType::endogenous) { int eq = indices[0]; - int var { getTypeSpecificIDByDerivID(deriv_id) }; + int var {getTypeSpecificIDByDerivID(deriv_id)}; row_incidence.emplace(eq, var); } output << "M_.block_structure_stat.incidence.sparse_IM = [" << endl; for (auto [eq, var] : row_incidence) - output << " " << eq+1 << " " << var+1 << ";" << endl; + output << " " << eq + 1 << " " << var + 1 << ";" << endl; output << "];" << endl - << "M_.block_structure_stat.tmp_nbr = " << blocks_temporary_terms_idxs.size() - << ";" << endl; + << "M_.block_structure_stat.tmp_nbr = " << blocks_temporary_terms_idxs.size() << ";" + << endl; writeBlockDriverSparseIndicesHelper(output); } @@ -638,11 +662,11 @@ StaticModel::getDerivID(int symb_id, [[maybe_unused]] int lag) const noexcept(fa else /* See the special treatment in VariableNode::prepareForDerivation(), VariableNode::computeDerivative() and VariableNode::getChainRuleDerivative() */ - throw UnknownDerivIDException{}; + throw UnknownDerivIDException {}; } void -StaticModel::addAllParamDerivId(set &deriv_id_set) +StaticModel::addAllParamDerivId(set& deriv_id_set) { for (int i = 0; i < symbol_table.param_nbr(); i++) deriv_id_set.insert(i + symbol_table.endo_nbr()); @@ -660,12 +684,13 @@ StaticModel::computeChainRuleJacobian() for (int blk = 0; blk < nb_blocks; blk++) { int nb_recursives = blocks[blk].getRecursiveSize(); - BlockSimulationType simulation_type { blocks[blk].simulation_type }; + BlockSimulationType simulation_type {blocks[blk].simulation_type}; - map recursive_vars; + map recursive_vars; for (int i = 0; i < nb_recursives; i++) { - int deriv_id = getDerivID(symbol_table.getID(SymbolType::endogenous, getBlockVariableID(blk, i)), 0); + int deriv_id = getDerivID( + symbol_table.getID(SymbolType::endogenous, getBlockVariableID(blk, i)), 0); if (getBlockEquationType(blk, i) == EquationType::evaluateRenormalized) recursive_vars[deriv_id] = getBlockEquationRenormalizedExpr(blk, i); else @@ -684,9 +709,11 @@ StaticModel::computeChainRuleJacobian() for (int var = nb_recursives; var < size; var++) { int var_orig = getBlockVariableID(blk, var); - expr_t d1 = equations[eq_orig]->getChainRuleDerivative(getDerivID(symbol_table.getID(SymbolType::endogenous, var_orig), 0), recursive_vars, non_null_chain_rule_derivatives, chain_rule_deriv_cache); + expr_t d1 = equations[eq_orig]->getChainRuleDerivative( + getDerivID(symbol_table.getID(SymbolType::endogenous, var_orig), 0), + recursive_vars, non_null_chain_rule_derivatives, chain_rule_deriv_cache); if (d1 != Zero) - blocks_derivatives[blk][{ eq, var, 0 }] = d1; + blocks_derivatives[blk][{eq, var, 0}] = d1; } } @@ -694,35 +721,38 @@ StaticModel::computeChainRuleJacobian() if (simulation_type != BlockSimulationType::evaluateForward && simulation_type != BlockSimulationType::evaluateBackward) { - for (const auto &[indices, d1] : blocks_derivatives[blk]) + for (const auto& [indices, d1] : blocks_derivatives[blk]) { - auto &[eq, var, lag] { indices }; + auto& [eq, var, lag] {indices}; assert(eq >= nb_recursives && var >= nb_recursives && lag == 0); - blocks_jacobian_sparse_column_major_order[blk].try_emplace({eq-nb_recursives, var-nb_recursives}, d1); + blocks_jacobian_sparse_column_major_order[blk].try_emplace( + {eq - nb_recursives, var - nb_recursives}, d1); } - blocks_jacobian_sparse_colptr[blk] = computeCSCColPtr(blocks_jacobian_sparse_column_major_order[blk], blocks[blk].mfs_size); + blocks_jacobian_sparse_colptr[blk] = computeCSCColPtr( + blocks_jacobian_sparse_column_major_order[blk], blocks[blk].mfs_size); } } } void -StaticModel::writeLatexFile(const string &basename, bool write_equation_tags) const +StaticModel::writeLatexFile(const string& basename, bool write_equation_tags) const { - writeLatexModelFile(basename, "static", ExprNodeOutputType::latexStaticModel, write_equation_tags); + writeLatexModelFile(basename, "static", ExprNodeOutputType::latexStaticModel, + write_equation_tags); } void -StaticModel::writeAuxVarInitval(ostream &output, ExprNodeOutputType output_type) const +StaticModel::writeAuxVarInitval(ostream& output, ExprNodeOutputType output_type) const { for (auto aux_equation : aux_equations) { - dynamic_cast(aux_equation)->writeOutput(output, output_type); + dynamic_cast(aux_equation)->writeOutput(output, output_type); output << ";" << endl; } } void -StaticModel::writeLatexAuxVarRecursiveDefinitions(ostream &output) const +StaticModel::writeLatexAuxVarRecursiveDefinitions(ostream& output) const { deriv_node_temp_terms_t tef_terms; temporary_terms_t temporary_terms; @@ -734,13 +764,14 @@ StaticModel::writeLatexAuxVarRecursiveDefinitions(ostream &output) const for (auto aux_equation : aux_equations) { output << R"(\begin{dmath})" << endl; - dynamic_cast(aux_equation)->writeOutput(output, ExprNodeOutputType::latexStaticModel); + dynamic_cast(aux_equation) + ->writeOutput(output, ExprNodeOutputType::latexStaticModel); output << endl << R"(\end{dmath})" << endl; } } void -StaticModel::writeJsonAuxVarRecursiveDefinitions(ostream &output) const +StaticModel::writeJsonAuxVarRecursiveDefinitions(ostream& output) const { deriv_node_temp_terms_t tef_terms; temporary_terms_t temporary_terms; @@ -750,8 +781,7 @@ StaticModel::writeJsonAuxVarRecursiveDefinitions(ostream &output) const { vector efout; aux_equation->writeJsonExternalFunctionOutput(efout, temporary_terms, tef_terms, false); - for (bool printed_something{false}; - const auto &it : efout) + for (bool printed_something {false}; const auto& it : efout) { if (exchange(printed_something, true)) output << ", "; @@ -770,11 +800,10 @@ StaticModel::writeJsonAuxVarRecursiveDefinitions(ostream &output) const } void -StaticModel::writeJsonOutput(ostream &output) const +StaticModel::writeJsonOutput(ostream& output) const { output << R"("static_tmp_nbr": [)"; - for (bool printed_something {false}; - const auto &tts : temporary_terms_derivatives) + for (bool printed_something {false}; const auto& tts : temporary_terms_derivatives) { if (exchange(printed_something, true)) output << ", "; @@ -785,42 +814,37 @@ StaticModel::writeJsonOutput(ostream &output) const } void -StaticModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) const +StaticModel::writeJsonComputingPassOutput(ostream& output, bool writeDetails) const { - auto [mlv_output, d_output] { writeJsonComputingPassOutputHelper(writeDetails) }; + auto [mlv_output, d_output] {writeJsonComputingPassOutputHelper(writeDetails)}; if (writeDetails) output << R"("static_model": {)"; else output << R"("static_model_simple": {)"; output << mlv_output.str(); - for (const auto &it : d_output) + for (const auto& it : d_output) output << ", " << it.str(); output << "}"; } void -StaticModel::writeJsonParamsDerivatives(ostream &output, bool writeDetails) const +StaticModel::writeJsonParamsDerivatives(ostream& output, bool writeDetails) const { if (!params_derivatives.size()) return; - auto [mlv_output, tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output, g3p_output] - { writeJsonParamsDerivativesHelper(writeDetails) }; + auto [mlv_output, tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output, + g3p_output] {writeJsonParamsDerivativesHelper(writeDetails)}; // g3p_output is ignored if (writeDetails) output << R"("static_model_params_derivative": {)"; else output << R"("static_model_params_derivatives_simple": {)"; - output << mlv_output.str() - << ", " << tt_output.str() - << ", " << rp_output.str() - << ", " << gp_output.str() - << ", " << rpp_output.str() - << ", " << gpp_output.str() - << ", " << hp_output.str() - << "}"; + output << mlv_output.str() << ", " << tt_output.str() << ", " << rp_output.str() << ", " + << gp_output.str() << ", " << rpp_output.str() << ", " << gpp_output.str() << ", " + << hp_output.str() << "}"; } void @@ -828,16 +852,16 @@ StaticModel::computeRamseyMultipliersDerivatives(int ramsey_orig_endo_nbr, bool bool no_tmp_terms) { // Compute derivation IDs of Lagrange multipliers - set mult_symb_ids { symbol_table.getLagrangeMultipliers() }; + set mult_symb_ids {symbol_table.getLagrangeMultipliers()}; vector mult_deriv_ids; for (int symb_id : mult_symb_ids) mult_deriv_ids.push_back(getDerivID(symb_id, 0)); // Compute the list of aux vars for which to apply the chain rule derivation - map recursive_variables; + map recursive_variables; for (auto aux_eq : aux_equations) { - auto varexpr { dynamic_cast(aux_eq->arg1) }; + auto varexpr {dynamic_cast(aux_eq->arg1)}; assert(varexpr && symbol_table.isAuxiliaryVariable(varexpr->symb_id)); /* Determine whether the auxiliary variable has been added after the last Lagrange multiplier. We use the guarantee given by SymbolTable that @@ -851,64 +875,64 @@ StaticModel::computeRamseyMultipliersDerivatives(int ramsey_orig_endo_nbr, bool unordered_map> cache; for (int eq {0}; eq < ramsey_orig_endo_nbr; eq++) for (int mult {0}; mult < static_cast(mult_deriv_ids.size()); mult++) - if (expr_t d { equations[eq]->getChainRuleDerivative(mult_deriv_ids[mult], recursive_variables, - non_null_chain_rule_derivatives, cache) }; + if (expr_t d {equations[eq]->getChainRuleDerivative(mult_deriv_ids[mult], recursive_variables, + non_null_chain_rule_derivatives, cache)}; d != Zero) - ramsey_multipliers_derivatives.try_emplace({ eq, mult }, d); + ramsey_multipliers_derivatives.try_emplace({eq, mult}, d); // Compute the temporary terms map, unordered_set> temp_terms_map; unordered_map>> reference_count; - for (const auto &[row_col, d] : ramsey_multipliers_derivatives) - d->computeTemporaryTerms({ 1, 0 }, temp_terms_map, reference_count, is_matlab); + for (const auto& [row_col, d] : ramsey_multipliers_derivatives) + d->computeTemporaryTerms({1, 0}, temp_terms_map, reference_count, is_matlab); /* If the user has specified the notmpterms option, clear all temporary terms, except those that correspond to external functions (since they are not optional) */ if (no_tmp_terms) - for (auto &it : temp_terms_map) - erase_if(it.second, - [](expr_t e) { return !dynamic_cast(e); }); + for (auto& it : temp_terms_map) + erase_if(it.second, [](expr_t e) { return !dynamic_cast(e); }); copy(temp_terms_map[{1, 0}].begin(), temp_terms_map[{1, 0}].end(), - inserter(ramsey_multipliers_derivatives_temporary_terms, ramsey_multipliers_derivatives_temporary_terms.begin())); - for (int idx {0}; - auto it : ramsey_multipliers_derivatives_temporary_terms) + inserter(ramsey_multipliers_derivatives_temporary_terms, + ramsey_multipliers_derivatives_temporary_terms.begin())); + for (int idx {0}; auto it : ramsey_multipliers_derivatives_temporary_terms) ramsey_multipliers_derivatives_temporary_terms_idxs[it] = idx++; // Compute the CSC format - ramsey_multipliers_derivatives_sparse_colptr = computeCSCColPtr(ramsey_multipliers_derivatives, - mult_deriv_ids.size()); + ramsey_multipliers_derivatives_sparse_colptr + = computeCSCColPtr(ramsey_multipliers_derivatives, mult_deriv_ids.size()); } void -StaticModel::writeDriverRamseyMultipliersDerivativesSparseIndices(ostream &output) const +StaticModel::writeDriverRamseyMultipliersDerivativesSparseIndices(ostream& output) const { output << "M_.ramsey_multipliers_static_g1_sparse_rowval = int32(["; - for (auto &[row_col, d] : ramsey_multipliers_derivatives) - output << row_col.first+1 << ' '; - output << "]);" << endl - << "M_.ramsey_multipliers_static_g1_sparse_colval = int32(["; - for (auto &[row_col, d] : ramsey_multipliers_derivatives) - output << row_col.second+1 << ' '; - output << "]);" << endl - << "M_.ramsey_multipliers_static_g1_sparse_colptr = int32(["; + for (auto& [row_col, d] : ramsey_multipliers_derivatives) + output << row_col.first + 1 << ' '; + output << "]);" << endl << "M_.ramsey_multipliers_static_g1_sparse_colval = int32(["; + for (auto& [row_col, d] : ramsey_multipliers_derivatives) + output << row_col.second + 1 << ' '; + output << "]);" << endl << "M_.ramsey_multipliers_static_g1_sparse_colptr = int32(["; for (int it : ramsey_multipliers_derivatives_sparse_colptr) - output << it+1 << ' '; + output << it + 1 << ' '; output << "]);" << endl; } void -StaticModel::writeRamseyMultipliersDerivativesMFile(const string &basename, int ramsey_orig_endo_nbr) const +StaticModel::writeRamseyMultipliersDerivativesMFile(const string& basename, + int ramsey_orig_endo_nbr) const { - constexpr auto output_type { ExprNodeOutputType::matlabStaticModel }; + constexpr auto output_type {ExprNodeOutputType::matlabStaticModel}; filesystem::path filename {packageDir(basename) / "ramsey_multipliers_static_g1.m"}; - ofstream output_file{filename, ios::out | ios::binary}; + ofstream output_file {filename, ios::out | ios::binary}; if (!output_file.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; exit(EXIT_FAILURE); } - output_file << "function g1m = ramsey_multipliers_static_g1(y, x, params, sparse_rowval, sparse_colval, sparse_colptr)" << endl + output_file << "function g1m = ramsey_multipliers_static_g1(y, x, params, sparse_rowval, " + "sparse_colval, sparse_colptr)" + << endl << "g1m_v=NaN(" << ramsey_multipliers_derivatives.size() << ",1);" << endl; writeRamseyMultipliersDerivativesHelper(output_file); @@ -918,36 +942,42 @@ StaticModel::writeRamseyMultipliersDerivativesMFile(const string &basename, int << " sparse_rowval = double(sparse_rowval);" << endl << " sparse_colval = double(sparse_colval);" << endl << "end" << endl - << "g1m = sparse(sparse_rowval, sparse_colval, g1m_v, " << ramsey_orig_endo_nbr << ", " << symbol_table.getLagrangeMultipliers().size() << ");" << endl + << "g1m = sparse(sparse_rowval, sparse_colval, g1m_v, " << ramsey_orig_endo_nbr + << ", " << symbol_table.getLagrangeMultipliers().size() << ");" << endl << "end" << endl; output_file.close(); } void -StaticModel::writeRamseyMultipliersDerivativesCFile(const string &basename, const string &mexext, const filesystem::path &matlabroot, int ramsey_orig_endo_nbr) const +StaticModel::writeRamseyMultipliersDerivativesCFile(const string& basename, const string& mexext, + const filesystem::path& matlabroot, + int ramsey_orig_endo_nbr) const { - constexpr auto output_type { ExprNodeOutputType::CStaticModel }; - const filesystem::path model_src_dir {filesystem::path{basename} / "model" / "src"}; + constexpr auto output_type {ExprNodeOutputType::CStaticModel}; + const filesystem::path model_src_dir {filesystem::path {basename} / "model" / "src"}; - const int xlen { symbol_table.exo_nbr()+symbol_table.exo_det_nbr() }; - const int nzval { static_cast(ramsey_multipliers_derivatives.size()) }; - const int ncols { static_cast(symbol_table.getLagrangeMultipliers().size()) }; + const int xlen {symbol_table.exo_nbr() + symbol_table.exo_det_nbr()}; + const int nzval {static_cast(ramsey_multipliers_derivatives.size())}; + const int ncols {static_cast(symbol_table.getLagrangeMultipliers().size())}; const filesystem::path p {model_src_dir / "ramsey_multipliers_static_g1.c"}; - ofstream output{p, ios::out | ios::binary}; + ofstream output {p, ios::out | ios::binary}; if (!output.is_open()) { cerr << "ERROR: Can't open file " << p.string() << " for writing" << endl; exit(EXIT_FAILURE); } - output << "#include " << endl << endl + output << "#include " << endl + << endl << R"(#include "mex.h")" << endl // Needed for calls to external functions << endl; writeCHelpersDefinition(output); writeCHelpersDeclaration(output); // Provide external definition of helpers output << endl - << "void ramsey_multipliers_static_g1(const double *restrict y, const double *restrict x, const double *restrict params, double *restrict T, double *restrict g1m_v)" << endl + << "void ramsey_multipliers_static_g1(const double *restrict y, const double *restrict x, " + "const double *restrict params, double *restrict T, double *restrict g1m_v)" + << endl << "{" << endl; writeRamseyMultipliersDerivativesHelper(output); output << "}" << endl @@ -958,19 +988,32 @@ StaticModel::writeRamseyMultipliersDerivativesCFile(const string &basename, cons << R"( mexErrMsgTxt("Accepts exactly 6 input arguments");)" << endl << " if (nlhs != 1)" << endl << R"( mexErrMsgTxt("Accepts exactly 1 output argument");)" << endl - << " if (!(mxIsDouble(prhs[0]) && !mxIsComplex(prhs[0]) && !mxIsSparse(prhs[0]) && mxGetNumberOfElements(prhs[0]) == " << symbol_table.endo_nbr() << "))" << endl - << R"( mexErrMsgTxt("y must be a real dense numeric array with )" << symbol_table.endo_nbr() << R"( elements");)" << endl + << " if (!(mxIsDouble(prhs[0]) && !mxIsComplex(prhs[0]) && !mxIsSparse(prhs[0]) && " + "mxGetNumberOfElements(prhs[0]) == " + << symbol_table.endo_nbr() << "))" << endl + << R"( mexErrMsgTxt("y must be a real dense numeric array with )" + << symbol_table.endo_nbr() << R"( elements");)" << endl << " const double *restrict y = mxGetPr(prhs[0]);" << endl - << " if (!(mxIsDouble(prhs[1]) && !mxIsComplex(prhs[1]) && !mxIsSparse(prhs[1]) && mxGetNumberOfElements(prhs[1]) == " << xlen << "))" << endl - << R"( mexErrMsgTxt("x must be a real dense numeric array with )" << xlen << R"( elements");)" << endl + << " if (!(mxIsDouble(prhs[1]) && !mxIsComplex(prhs[1]) && !mxIsSparse(prhs[1]) && " + "mxGetNumberOfElements(prhs[1]) == " + << xlen << "))" << endl + << R"( mexErrMsgTxt("x must be a real dense numeric array with )" << xlen + << R"( elements");)" << endl << " const double *restrict x = mxGetPr(prhs[1]);" << endl - << " if (!(mxIsDouble(prhs[2]) && !mxIsComplex(prhs[2]) && !mxIsSparse(prhs[2]) && mxGetNumberOfElements(prhs[2]) == " << symbol_table.param_nbr() << "))" << endl - << R"( mexErrMsgTxt("params must be a real dense numeric array with )" << symbol_table.param_nbr() << R"( elements");)" << endl + << " if (!(mxIsDouble(prhs[2]) && !mxIsComplex(prhs[2]) && !mxIsSparse(prhs[2]) && " + "mxGetNumberOfElements(prhs[2]) == " + << symbol_table.param_nbr() << "))" << endl + << R"( mexErrMsgTxt("params must be a real dense numeric array with )" + << symbol_table.param_nbr() << R"( elements");)" << endl << " const double *restrict params = mxGetPr(prhs[2]);" << endl - << " if (!(mxIsInt32(prhs[3]) && mxGetNumberOfElements(prhs[3]) == " << nzval << "))" << endl - << R"( mexErrMsgTxt("sparse_rowval must be an int32 array with )" << nzval << R"( elements");)" << endl - << " if (!(mxIsInt32(prhs[5]) && mxGetNumberOfElements(prhs[5]) == " << ncols+1 << "))" << endl - << R"( mexErrMsgTxt("sparse_colptr must be an int32 array with )" << ncols+1 << R"( elements");)" << endl + << " if (!(mxIsInt32(prhs[3]) && mxGetNumberOfElements(prhs[3]) == " << nzval << "))" + << endl + << R"( mexErrMsgTxt("sparse_rowval must be an int32 array with )" << nzval + << R"( elements");)" << endl + << " if (!(mxIsInt32(prhs[5]) && mxGetNumberOfElements(prhs[5]) == " << ncols + 1 << "))" + << endl + << R"( mexErrMsgTxt("sparse_colptr must be an int32 array with )" << ncols + 1 + << R"( elements");)" << endl << "#if MX_HAS_INTERLEAVED_COMPLEX" << endl << " const int32_T *restrict sparse_rowval = mxGetInt32s(prhs[3]);" << endl << " const int32_T *restrict sparse_colptr = mxGetInt32s(prhs[5]);" << endl @@ -978,18 +1021,20 @@ StaticModel::writeRamseyMultipliersDerivativesCFile(const string &basename, cons << " const int32_T *restrict sparse_rowval = (int32_T *) mxGetData(prhs[3]);" << endl << " const int32_T *restrict sparse_colptr = (int32_T *) mxGetData(prhs[5]);" << endl << "#endif" << endl - << " plhs[0] = mxCreateSparse(" << ramsey_orig_endo_nbr << ", " << ncols << ", " << nzval << ", mxREAL);" << endl + << " plhs[0] = mxCreateSparse(" << ramsey_orig_endo_nbr << ", " << ncols << ", " << nzval + << ", mxREAL);" << endl << " mwIndex *restrict ir = mxGetIr(plhs[0]), *restrict jc = mxGetJc(plhs[0]);" << endl << " for (mwSize i = 0; i < " << nzval << "; i++)" << endl << " *ir++ = *sparse_rowval++ - 1;" << endl - << " for (mwSize i = 0; i < " << ncols+1 << "; i++)" << endl + << " for (mwSize i = 0; i < " << ncols + 1 << "; i++)" << endl << " *jc++ = *sparse_colptr++ - 1;" << endl - << " mxArray *T_mx = mxCreateDoubleMatrix(" << ramsey_multipliers_derivatives_temporary_terms.size() << ", 1, mxREAL);" << endl + << " mxArray *T_mx = mxCreateDoubleMatrix(" + << ramsey_multipliers_derivatives_temporary_terms.size() << ", 1, mxREAL);" << endl << " ramsey_multipliers_static_g1(y, x, params, mxGetPr(T_mx), mxGetPr(plhs[0]));" << endl << " mxDestroyArray(T_mx);" << endl << "}" << endl; output.close(); - compileMEX(packageDir(basename), "ramsey_multipliers_static_g1", mexext, { p }, matlabroot); + compileMEX(packageDir(basename), "ramsey_multipliers_static_g1", mexext, {p}, matlabroot); } diff --git a/src/StaticModel.hh b/src/StaticModel.hh index f605c258..30491f74 100644 --- a/src/StaticModel.hh +++ b/src/StaticModel.hh @@ -20,11 +20,11 @@ #ifndef _STATIC_MODEL_HH #define _STATIC_MODEL_HH -#include #include +#include -#include "ModelTree.hh" #include "Bytecode.hh" +#include "ModelTree.hh" using namespace std; @@ -58,23 +58,24 @@ private: NB: the default value defined here is not used when converting from DynamicModel class, and in particular it does not affect the main “model” block. See the DynamicModel class for the default value in that case. */ - int static_mfs{0}; + int static_mfs {0}; // Writes static model file (MATLAB/Octave version, legacy representation) - void writeStaticMFile(const string &basename) const; + void writeStaticMFile(const string& basename) const; //! Writes the code of the block-decomposed model in virtual machine bytecode - void writeStaticBlockBytecode(const string &basename) const; + void writeStaticBlockBytecode(const string& basename) const; //! Writes the code of the model in virtual machine bytecode - void writeStaticBytecode(const string &basename) const; + void writeStaticBytecode(const string& basename) const; //! Computes jacobian and prepares for equation normalization /*! Using values from initval/endval blocks and parameter initializations: - computes the jacobian for the model w.r. to contemporaneous variables - - removes edges of the incidence matrix when derivative w.r. to the corresponding variable is too close to zero (below the cutoff) + - removes edges of the incidence matrix when derivative w.r. to the corresponding variable is + too close to zero (below the cutoff) */ - void evaluateJacobian(const eval_context_t &eval_context, jacob_map_t *j_m, bool dynamic); + void evaluateJacobian(const eval_context_t& eval_context, jacob_map_t* j_m, bool dynamic); SymbolType getTypeByDerivID(int deriv_id) const noexcept(false) override; int getLagByDerivID(int deriv_id) const noexcept(false) override; @@ -96,38 +97,37 @@ private: /* Helper for writing MATLAB/Octave functions for residuals/derivatives and their temporary terms (legacy representation) */ - void writeStaticMFileHelper(const string &basename, - const string &name, const string &retvalname, - const string &name_tt, size_t ttlen, - const string &previous_tt_name, - const ostringstream &init_s, const ostringstream &end_s, - const ostringstream &s, const ostringstream &s_tt) const; + void writeStaticMFileHelper(const string& basename, const string& name, const string& retvalname, + const string& name_tt, size_t ttlen, const string& previous_tt_name, + const ostringstream& init_s, const ostringstream& end_s, + const ostringstream& s, const ostringstream& s_tt) const; /* Writes MATLAB/Octave wrapper function for computing residuals and derivatives at the same time (legacy representation) */ - void writeStaticMWrapperFunction(const string &basename, const string &ending) const; + void writeStaticMWrapperFunction(const string& basename, const string& ending) const; /* Create the compatibility static.m file for MATLAB/Octave not yet using the temporary terms array interface (legacy representation) */ - void writeStaticMCompatFile(const string &name) const; + void writeStaticMCompatFile(const string& name) const; int - getBlockJacobianEndoCol([[maybe_unused]] int blk, int var, [[maybe_unused]] int lag) const override + getBlockJacobianEndoCol([[maybe_unused]] int blk, int var, + [[maybe_unused]] int lag) const override { assert(var >= blocks[blk].getRecursiveSize()); return var - blocks[blk].getRecursiveSize(); } // Write the block structure of the model in the driver file - void writeBlockDriverOutput(ostream &output) const; + void writeBlockDriverOutput(ostream& output) const; // Helper for writing ramsey_multipliers_derivatives template - void writeRamseyMultipliersDerivativesHelper(ostream &output) const; + void writeRamseyMultipliersDerivativesHelper(ostream& output) const; //! Internal helper for the copy constructor and assignment operator /*! Copies all the structures that contain ExprNode*, by the converting the pointers into their equivalent in the new tree */ - void copyHelper(const StaticModel &m); + void copyHelper(const StaticModel& m); protected: string @@ -137,71 +137,77 @@ protected: } public: - StaticModel(SymbolTable &symbol_table_arg, - NumericalConstants &num_constants, - ExternalFunctionsTable &external_functions_table_arg); + StaticModel(SymbolTable& symbol_table_arg, NumericalConstants& num_constants, + ExternalFunctionsTable& external_functions_table_arg); - StaticModel(const StaticModel &m); - StaticModel &operator=(const StaticModel &m); + StaticModel(const StaticModel& m); + StaticModel& operator=(const StaticModel& m); //! Creates the static version of a dynamic model - explicit StaticModel(const DynamicModel &m); + explicit StaticModel(const DynamicModel& m); //! Writes information about the static model to the driver file - void writeDriverOutput(ostream &output) const; + void writeDriverOutput(ostream& output) const; //! Execute computations (variable sorting + derivation + block decomposition) /*! \param eval_context evaluation context for normalization \param no_tmp_terms if true, no temporary terms will be computed in the static files \param derivsOrder order of derivation with respect to endogenous - \param paramsDerivsOrder order of derivatives w.r. to a pair (endogenous, parameter) to be computed + \param paramsDerivsOrder order of derivatives w.r. to a pair (endogenous, parameter) to be + computed */ - void computingPass(int derivsOrder, int paramsDerivsOrder, const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll); + void computingPass(int derivsOrder, int paramsDerivsOrder, const eval_context_t& eval_context, + bool no_tmp_terms, bool block, bool use_dll); //! Writes static model file (+ bytecode) - void writeStaticFile(const string &basename, bool use_dll, const string &mexext, const filesystem::path &matlabroot, bool julia) const; + void writeStaticFile(const string& basename, bool use_dll, const string& mexext, + const filesystem::path& matlabroot, bool julia) const; //! Write JSON Output (used by PlannerObjectiveStatement) - void writeJsonOutput(ostream &output) const; + void writeJsonOutput(ostream& output) const; //! Write JSON representation of static model - void writeJsonComputingPassOutput(ostream &output, bool writeDetails) const; + void writeJsonComputingPassOutput(ostream& output, bool writeDetails) const; //! Write JSON params derivatives - void writeJsonParamsDerivatives(ostream &output, bool writeDetails) const; + void writeJsonParamsDerivatives(ostream& output, bool writeDetails) const; //! Writes file containing static parameters derivatives template - void writeParamsDerivativesFile(const string &basename) const; + void writeParamsDerivativesFile(const string& basename) const; //! Writes LaTeX file with the equations of the static model - void writeLatexFile(const string &basename, bool write_equation_tags) const; + void writeLatexFile(const string& basename, bool write_equation_tags) const; //! Writes initializations in oo_.steady_state or steady state file for the auxiliary variables - void writeAuxVarInitval(ostream &output, ExprNodeOutputType output_type) const; + void writeAuxVarInitval(ostream& output, ExprNodeOutputType output_type) const; - void writeLatexAuxVarRecursiveDefinitions(ostream &output) const; - void writeJsonAuxVarRecursiveDefinitions(ostream &output) const; + void writeLatexAuxVarRecursiveDefinitions(ostream& output) const; + void writeJsonAuxVarRecursiveDefinitions(ostream& output) const; //! To ensure that no exogenous is present in the planner objective //! See #1264 bool exoPresentInEqs() const; int getDerivID(int symb_id, int lag) const noexcept(false) override; - void addAllParamDerivId(set &deriv_id_set) override; + void addAllParamDerivId(set& deriv_id_set) override; // Fills the ramsey_multipliers_derivatives structure (see the comment there) - void computeRamseyMultipliersDerivatives(int ramsey_orig_endo_nbr, bool is_matlab, bool no_tmp_terms); + void computeRamseyMultipliersDerivatives(int ramsey_orig_endo_nbr, bool is_matlab, + bool no_tmp_terms); // Writes the sparse indices of ramsey_multipliers_derivatives to the driver file - void writeDriverRamseyMultipliersDerivativesSparseIndices(ostream &output) const; + void writeDriverRamseyMultipliersDerivativesSparseIndices(ostream& output) const; // Writes ramsey_multipliers_derivatives (MATLAB/Octave version) - void writeRamseyMultipliersDerivativesMFile(const string &basename, int ramsey_orig_endo_nbr) const; + void writeRamseyMultipliersDerivativesMFile(const string& basename, + int ramsey_orig_endo_nbr) const; // Writes ramsey_multipliers_derivatives (C version) - void writeRamseyMultipliersDerivativesCFile(const string &basename, const string &mexext, const filesystem::path &matlabroot, int ramsey_orig_endo_nbr) const; + void writeRamseyMultipliersDerivativesCFile(const string& basename, const string& mexext, + const filesystem::path& matlabroot, + int ramsey_orig_endo_nbr) const; int getMFS() const override @@ -212,18 +218,19 @@ public: template void -StaticModel::writeParamsDerivativesFile(const string &basename) const +StaticModel::writeParamsDerivativesFile(const string& basename) const { if (!params_derivatives.size()) return; - constexpr ExprNodeOutputType output_type { julia ? ExprNodeOutputType::juliaStaticModel : ExprNodeOutputType::matlabStaticModel }; + constexpr ExprNodeOutputType output_type {julia ? ExprNodeOutputType::juliaStaticModel + : ExprNodeOutputType::matlabStaticModel}; - auto [tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output, g3p_output] - { writeParamsDerivativesFileHelper() }; + auto [tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output, + g3p_output] {writeParamsDerivativesFileHelper()}; // g3p_output is ignored - if constexpr(!julia) + if constexpr (!julia) { filesystem::path filename {packageDir(basename) / "static_params_derivs.m"}; ofstream paramsDerivsFile {filename, ios::out | ios::binary}; @@ -232,57 +239,97 @@ StaticModel::writeParamsDerivativesFile(const string &basename) const cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; exit(EXIT_FAILURE); } - paramsDerivsFile << "function [rp, gp, rpp, gpp, hp] = static_params_derivs(y, x, params)" << endl - << "%" << endl - << "% Status : Computes derivatives of the static model with respect to the parameters" << endl - << "%" << endl - << "% Inputs : " << endl - << "% y [M_.endo_nbr by 1] double vector of endogenous variables in declaration order" << endl - << "% x [M_.exo_nbr by 1] double vector of exogenous variables in declaration order" << endl - << "% params [M_.param_nbr by 1] double vector of parameter values in declaration order" << endl - << "%" << endl - << "% Outputs:" << endl - << "% rp [M_.eq_nbr by #params] double Jacobian matrix of static model equations with respect to parameters " << endl - << "% Dynare may prepend or append auxiliary equations, see M_.aux_vars" << endl - << "% gp [M_.endo_nbr by M_.endo_nbr by #params] double Derivative of the Jacobian matrix of the static model equations with respect to the parameters" << endl - << "% rows: variables in declaration order" << endl - << "% rows: equations in order of declaration" << endl - << "% rpp [#second_order_residual_terms by 4] double Hessian matrix of second derivatives of residuals with respect to parameters;" << endl - << "% rows: respective derivative term" << endl - << "% 1st column: equation number of the term appearing" << endl - << "% 2nd column: number of the first parameter in derivative" << endl - << "% 3rd column: number of the second parameter in derivative" << endl - << "% 4th column: value of the Hessian term" << endl - << "% gpp [#second_order_Jacobian_terms by 5] double Hessian matrix of second derivatives of the Jacobian with respect to the parameters;" << endl - << "% rows: respective derivative term" << endl - << "% 1st column: equation number of the term appearing" << endl - << "% 2nd column: column number of variable in Jacobian of the static model" << endl - << "% 3rd column: number of the first parameter in derivative" << endl - << "% 4th column: number of the second parameter in derivative" << endl - << "% 5th column: value of the Hessian term" << endl - << "%" << endl - << "%" << endl - << "% Warning : this file is generated automatically by Dynare" << endl - << "% from model file (.mod)" << endl << endl - << "T = NaN(" << params_derivs_temporary_terms_idxs.size() << ",1);" << endl - << tt_output.str() - << "rp = zeros(" << equations.size() << ", " - << symbol_table.param_nbr() << ");" << endl - << rp_output.str() - << "gp = zeros(" << equations.size() << ", " << symbol_table.endo_nbr() << ", " - << symbol_table.param_nbr() << ");" << endl - << gp_output.str() - << "if nargout >= 3" << endl - << "rpp = zeros(" << params_derivatives.at({ 0, 2 }).size() << ",4);" << endl - << rpp_output.str() - << "gpp = zeros(" << params_derivatives.at({ 1, 2 }).size() << ",5);" << endl - << gpp_output.str() - << "end" << endl - << "if nargout >= 5" << endl - << "hp = zeros(" << params_derivatives.at({ 2, 1 }).size() << ",5);" << endl - << hp_output.str() - << "end" << endl - << "end" << endl; + paramsDerivsFile + << "function [rp, gp, rpp, gpp, hp] = static_params_derivs(y, x, params)" << endl + << "%" << endl + << "% Status : Computes derivatives of the static model with respect to the parameters" + << endl + << "%" << endl + << "% Inputs : " << endl + << "% y [M_.endo_nbr by 1] double vector of endogenous variables in " + "declaration order" + << endl + << "% x [M_.exo_nbr by 1] double vector of exogenous variables in " + "declaration order" + << endl + << "% params [M_.param_nbr by 1] double vector of parameter values in declaration " + "order" + << endl + << "%" << endl + << "% Outputs:" << endl + << "% rp [M_.eq_nbr by #params] double Jacobian matrix of static model " + "equations with respect to parameters " + << endl + << "% Dynare may prepend or append " + "auxiliary equations, see M_.aux_vars" + << endl + << "% gp [M_.endo_nbr by M_.endo_nbr by #params] double Derivative of the " + "Jacobian matrix of the static model equations with respect to the parameters" + << endl + << "% rows: variables in " + "declaration order" + << endl + << "% rows: equations in order " + "of declaration" + << endl + << "% rpp [#second_order_residual_terms by 4] double Hessian matrix of second " + "derivatives of residuals with respect to parameters;" + << endl + << "% rows: respective " + "derivative term" + << endl + << "% 1st column: equation " + "number of the term appearing" + << endl + << "% 2nd column: number of " + "the first parameter in derivative" + << endl + << "% 3rd column: number of " + "the second parameter in derivative" + << endl + << "% 4th column: value of " + "the Hessian term" + << endl + << "% gpp [#second_order_Jacobian_terms by 5] double Hessian matrix of second " + "derivatives of the Jacobian with respect to the parameters;" + << endl + << "% rows: respective " + "derivative term" + << endl + << "% 1st column: equation " + "number of the term appearing" + << endl + << "% 2nd column: column " + "number of variable in Jacobian of the static model" + << endl + << "% 3rd column: number of " + "the first parameter in derivative" + << endl + << "% 4th column: number of " + "the second parameter in derivative" + << endl + << "% 5th column: value of " + "the Hessian term" + << endl + << "%" << endl + << "%" << endl + << "% Warning : this file is generated automatically by Dynare" << endl + << "% from model file (.mod)" << endl + << endl + << "T = NaN(" << params_derivs_temporary_terms_idxs.size() << ",1);" << endl + << tt_output.str() << "rp = zeros(" << equations.size() << ", " + << symbol_table.param_nbr() << ");" << endl + << rp_output.str() << "gp = zeros(" << equations.size() << ", " << symbol_table.endo_nbr() + << ", " << symbol_table.param_nbr() << ");" << endl + << gp_output.str() << "if nargout >= 3" << endl + << "rpp = zeros(" << params_derivatives.at({0, 2}).size() << ",4);" << endl + << rpp_output.str() << "gpp = zeros(" << params_derivatives.at({1, 2}).size() << ",5);" + << endl + << gpp_output.str() << "end" << endl + << "if nargout >= 5" << endl + << "hp = zeros(" << params_derivatives.at({2, 1}).size() << ",5);" << endl + << hp_output.str() << "end" << endl + << "end" << endl; paramsDerivsFile.close(); } else @@ -293,46 +340,42 @@ StaticModel::writeParamsDerivativesFile(const string &basename) const << "#" << endl << "function static_params_derivs(y, x, params)" << endl << "@inbounds begin" << endl - << tt_output.str() - << "rp = zeros(" << equations.size() << ", " + << tt_output.str() << "rp = zeros(" << equations.size() << ", " << symbol_table.param_nbr() << ");" << endl - << rp_output.str() - << "gp = zeros(" << equations.size() << ", " << symbol_table.endo_nbr() << ", " - << symbol_table.param_nbr() << ");" << endl - << gp_output.str() - << "rpp = zeros(" << params_derivatives.at({ 0, 2 }).size() << ",4);" << endl - << rpp_output.str() - << "gpp = zeros(" << params_derivatives.at({ 1, 2 }).size() << ",5);" << endl - << gpp_output.str() - << "hp = zeros(" << params_derivatives.at({ 2, 1 }).size() << ",5);" << endl - << hp_output.str() - << "end" << endl + << rp_output.str() << "gp = zeros(" << equations.size() << ", " + << symbol_table.endo_nbr() << ", " << symbol_table.param_nbr() << ");" << endl + << gp_output.str() << "rpp = zeros(" << params_derivatives.at({0, 2}).size() << ",4);" + << endl + << rpp_output.str() << "gpp = zeros(" << params_derivatives.at({1, 2}).size() << ",5);" + << endl + << gpp_output.str() << "hp = zeros(" << params_derivatives.at({2, 1}).size() << ",5);" + << endl + << hp_output.str() << "end" << endl << "return (rp, gp, rpp, gpp, hp)" << endl << "end" << endl; - writeToFileIfModified(output, filesystem::path{basename} / "model" / "julia" / "StaticParamsDerivs.jl"); + writeToFileIfModified(output, filesystem::path {basename} / "model" / "julia" + / "StaticParamsDerivs.jl"); } } template void -StaticModel::writeRamseyMultipliersDerivativesHelper(ostream &output) const +StaticModel::writeRamseyMultipliersDerivativesHelper(ostream& output) const { // Write temporary terms (which includes external function stuff) deriv_node_temp_terms_t tef_terms; temporary_terms_t unused_tt_copy; - writeTemporaryTerms(ramsey_multipliers_derivatives_temporary_terms, - unused_tt_copy, - ramsey_multipliers_derivatives_temporary_terms_idxs, - output, tef_terms); + writeTemporaryTerms(ramsey_multipliers_derivatives_temporary_terms, unused_tt_copy, + ramsey_multipliers_derivatives_temporary_terms_idxs, output, + tef_terms); // Write chain rule derivatives - for (int k {0}; - auto &[row_col, d] : ramsey_multipliers_derivatives) + for (int k {0}; auto& [row_col, d] : ramsey_multipliers_derivatives) { output << "g1m_v" << LEFT_ARRAY_SUBSCRIPT(output_type) - << k + ARRAY_SUBSCRIPT_OFFSET(output_type) - << RIGHT_ARRAY_SUBSCRIPT(output_type) << "="; + << k + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type) + << "="; d->writeOutput(output, output_type, ramsey_multipliers_derivatives_temporary_terms, ramsey_multipliers_derivatives_temporary_terms_idxs, tef_terms); output << ";" << endl; diff --git a/src/SubModel.cc b/src/SubModel.cc index ef4d1383..87844043 100644 --- a/src/SubModel.cc +++ b/src/SubModel.cc @@ -21,17 +21,16 @@ #include #include -#include "SubModel.hh" #include "DynamicModel.hh" +#include "SubModel.hh" -TrendComponentModelTable::TrendComponentModelTable(SymbolTable &symbol_table_arg) : - symbol_table{symbol_table_arg} +TrendComponentModelTable::TrendComponentModelTable(SymbolTable& symbol_table_arg) : + symbol_table {symbol_table_arg} { } void -TrendComponentModelTable::addTrendComponentModel(string name_arg, - vector eqtags_arg, +TrendComponentModelTable::addTrendComponentModel(string name_arg, vector eqtags_arg, vector target_eqtags_arg) { if (isExistingTrendComponentModelName(name_arg)) @@ -45,34 +44,39 @@ TrendComponentModelTable::addTrendComponentModel(string name_arg, } void -TrendComponentModelTable::setVals(map> eqnums_arg, map> target_eqnums_arg, - map> lhs_arg, map> lhs_expr_t_arg) +TrendComponentModelTable::setVals(map> eqnums_arg, + map> target_eqnums_arg, + map> lhs_arg, + map> lhs_expr_t_arg) { eqnums = move(eqnums_arg); target_eqnums = move(target_eqnums_arg); lhs = move(lhs_arg); lhs_expr_t = move(lhs_expr_t_arg); - for (const auto &it : eqnums) + for (const auto& it : eqnums) { vector nontrend_vec; for (auto eq : it.second) - if (find(target_eqnums[it.first].begin(), target_eqnums[it.first].end(), eq) == target_eqnums[it.first].end()) + if (find(target_eqnums[it.first].begin(), target_eqnums[it.first].end(), eq) + == target_eqnums[it.first].end()) nontrend_vec.push_back(eq); nontarget_eqnums[it.first] = nontrend_vec; } - for (const auto &name : names) + for (const auto& name : names) { vector nontarget_lhs_vec, target_lhs_vec; vector lhsv = getLhs(name); vector eqnumsv = getEqNums(name); for (int nontrend_it : getNonTargetEqNums(name)) - nontarget_lhs_vec.push_back(lhsv.at(distance(eqnumsv.begin(), find(eqnumsv.begin(), eqnumsv.end(), nontrend_it)))); + nontarget_lhs_vec.push_back( + lhsv.at(distance(eqnumsv.begin(), find(eqnumsv.begin(), eqnumsv.end(), nontrend_it)))); nontarget_lhs[name] = nontarget_lhs_vec; for (int trend_it : getTargetEqNums(name)) - target_lhs_vec.push_back(lhsv.at(distance(eqnumsv.begin(), find(eqnumsv.begin(), eqnumsv.end(), trend_it)))); + target_lhs_vec.push_back( + lhsv.at(distance(eqnumsv.begin(), find(eqnumsv.begin(), eqnumsv.end(), trend_it)))); target_lhs[name] = target_lhs_vec; } } @@ -121,112 +125,112 @@ TrendComponentModelTable::setA0(map, expr_t>> A0_arg A0star = move(A0star_arg); } -const map> & +const map>& TrendComponentModelTable::getEqTags() const { return eqtags; } -const vector & -TrendComponentModelTable::getEqTags(const string &name_arg) const +const vector& +TrendComponentModelTable::getEqTags(const string& name_arg) const { checkModelName(name_arg); return eqtags.at(name_arg); } void -TrendComponentModelTable::checkModelName(const string &name_arg) const +TrendComponentModelTable::checkModelName(const string& name_arg) const { if (!isExistingTrendComponentModelName(name_arg)) { - cerr << name_arg - << " is not a recognized equation tag of a trend component model equation" << endl; + cerr << name_arg << " is not a recognized equation tag of a trend component model equation" + << endl; exit(EXIT_FAILURE); } } -const vector & -TrendComponentModelTable::getNonTargetLhs(const string &name_arg) const +const vector& +TrendComponentModelTable::getNonTargetLhs(const string& name_arg) const { checkModelName(name_arg); return nontarget_lhs.at(name_arg); } -const vector & -TrendComponentModelTable::getTargetLhs(const string &name_arg) const +const vector& +TrendComponentModelTable::getTargetLhs(const string& name_arg) const { checkModelName(name_arg); return target_lhs.at(name_arg); } -const vector & -TrendComponentModelTable::getLhs(const string &name_arg) const +const vector& +TrendComponentModelTable::getLhs(const string& name_arg) const { checkModelName(name_arg); return lhs.at(name_arg); } -const vector & -TrendComponentModelTable::getLhsExprT(const string &name_arg) const +const vector& +TrendComponentModelTable::getLhsExprT(const string& name_arg) const { checkModelName(name_arg); return lhs_expr_t.at(name_arg); } -const map> & +const map>& TrendComponentModelTable::getTargetEqTags() const { return target_eqtags; } -const map> & +const map>& TrendComponentModelTable::getEqNums() const { return eqnums; } -const map> & +const map>& TrendComponentModelTable::getTargetEqNums() const { return target_eqnums; } -const vector & -TrendComponentModelTable::getTargetEqNums(const string &name_arg) const +const vector& +TrendComponentModelTable::getTargetEqNums(const string& name_arg) const { checkModelName(name_arg); return target_eqnums.at(name_arg); } -const map> & +const map>& TrendComponentModelTable::getNonTargetEqNums() const { return nontarget_eqnums; } -const vector & -TrendComponentModelTable::getNonTargetEqNums(const string &name_arg) const +const vector& +TrendComponentModelTable::getNonTargetEqNums(const string& name_arg) const { checkModelName(name_arg); return nontarget_eqnums.at(name_arg); } -const vector & -TrendComponentModelTable::getEqNums(const string &name_arg) const +const vector& +TrendComponentModelTable::getEqNums(const string& name_arg) const { checkModelName(name_arg); return eqnums.at(name_arg); } -const vector & -TrendComponentModelTable::getMaxLags(const string &name_arg) const +const vector& +TrendComponentModelTable::getMaxLags(const string& name_arg) const { checkModelName(name_arg); return max_lags.at(name_arg); } int -TrendComponentModelTable::getMaxLag(const string &name_arg) const +TrendComponentModelTable::getMaxLag(const string& name_arg) const { int max_lag_int = 0; for (auto it : getMaxLags(name_arg)) @@ -234,21 +238,21 @@ TrendComponentModelTable::getMaxLag(const string &name_arg) const return max_lag_int; } -const vector & -TrendComponentModelTable::getDiff(const string &name_arg) const +const vector& +TrendComponentModelTable::getDiff(const string& name_arg) const { checkModelName(name_arg); return diff.at(name_arg); } void -TrendComponentModelTable::writeOutput(const string &basename, ostream &output) const +TrendComponentModelTable::writeOutput(const string& basename, ostream& output) const { if (names.empty()) return; const filesystem::path filename {DataTree::packageDir(basename) / "trend_component_ar_a0.m"}; - ofstream ar_ec_output{filename, ios::out | ios::binary}; + ofstream ar_ec_output {filename, ios::out | ios::binary}; if (!ar_ec_output.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; @@ -256,49 +260,42 @@ TrendComponentModelTable::writeOutput(const string &basename, ostream &output) c } ar_ec_output << "function [AR, A0, A0star] = trend_component_ar_a0(model_name, params)" << endl << "%function [AR, A0, A0star] = trend_component_ar_a0(model_name, params)" << endl - << "% File automatically generated by the Dynare preprocessor" << endl << endl; + << "% File automatically generated by the Dynare preprocessor" << endl + << endl; - for (const auto &name : names) + for (const auto& name : names) { output << "M_.trend_component." << name << ".model_name = '" << name << "';" << endl << "M_.trend_component." << name << ".eqtags = {"; - for (const auto &it : eqtags.at(name)) + for (const auto& it : eqtags.at(name)) output << "'" << it << "'; "; - output << "};" << endl - << "M_.trend_component." << name << ".eqn = ["; + output << "};" << endl << "M_.trend_component." << name << ".eqn = ["; for (auto it : eqnums.at(name)) output << it + 1 << " "; - output << "];" << endl - << "M_.trend_component." << name << ".targets = ["; + output << "];" << endl << "M_.trend_component." << name << ".targets = ["; for (auto it : eqnums.at(name)) if (find(target_eqnums.at(name).begin(), target_eqnums.at(name).end(), it) == target_eqnums.at(name).end()) output << "false "; else output << "true "; - output << "];" << endl - << "M_.trend_component." << name << ".lhs = ["; + output << "];" << endl << "M_.trend_component." << name << ".lhs = ["; for (auto it : lhs.at(name)) output << symbol_table.getTypeSpecificID(it) + 1 << " "; - output << "];" << endl - << "M_.trend_component." << name << ".max_lag = ["; + output << "];" << endl << "M_.trend_component." << name << ".max_lag = ["; for (auto it : max_lags.at(name)) output << it << " "; - output << "];" << endl - << "M_.trend_component." << name << ".diff = ["; + output << "];" << endl << "M_.trend_component." << name << ".diff = ["; for (bool it : diff.at(name)) output << boolalpha << it << " "; - output << "];" << endl - << "M_.trend_component." << name << ".orig_diff_var = ["; - for (const auto &it : orig_diff_var.at(name)) + output << "];" << endl << "M_.trend_component." << name << ".orig_diff_var = ["; + for (const auto& it : orig_diff_var.at(name)) output << (it ? symbol_table.getTypeSpecificID(*it) + 1 : -1) << " "; - output << "];" << endl - << "M_.trend_component." << name << ".nonstationary = ["; + output << "];" << endl << "M_.trend_component." << name << ".nonstationary = ["; for (size_t i = 0; i < diff.at(name).size(); i++) output << "true "; output << "];" << endl; - for (int i{1}; - const auto &it : rhs.at(name)) + for (int i {1}; const auto& it : rhs.at(name)) { output << "M_.trend_component." << name << ".rhs.vars_at_eq{" << i << "}.var = ["; for (auto [var, lag] : it) @@ -312,7 +309,7 @@ TrendComponentModelTable::writeOutput(const string &basename, ostream &output) c i++; } output << "M_.trend_component." << name << ".target_vars = ["; - for (const optional &it : target_vars.at(name)) + for (const optional& it : target_vars.at(name)) output << (it ? symbol_table.getTypeSpecificID(*it) + 1 : -1) << " "; output << "];" << endl; @@ -325,7 +322,8 @@ TrendComponentModelTable::writeOutput(const string &basename, ostream &output) c vector eqtags_vec = eqtags.at(name); output << "M_.trend_component." << name << ".target_eqn = ["; for (auto it : target_eqtags_vec) - output << distance(eqtags_vec.begin(), find(eqtags_vec.begin(), eqtags_vec.end(), it)) + 1 << " "; + output << distance(eqtags_vec.begin(), find(eqtags_vec.begin(), eqtags_vec.end(), it)) + 1 + << " "; output << "];" << endl; vector target_lhs_vec = getTargetLhs(name); @@ -333,11 +331,14 @@ TrendComponentModelTable::writeOutput(const string &basename, ostream &output) c ar_ec_output << "if strcmp(model_name, '" << name << "')" << endl << " % AR" << endl - << " AR = zeros(" << nontarget_lhs_vec.size() << ", " << nontarget_lhs_vec.size() << ", " << getMaxLag(name) << ");" << endl; - for (const auto &[key, expr] : AR.at(name)) + << " AR = zeros(" << nontarget_lhs_vec.size() << ", " + << nontarget_lhs_vec.size() << ", " << getMaxLag(name) << ");" << endl; + for (const auto& [key, expr] : AR.at(name)) { auto [eqn, lag, lhs_symb_id] = key; - int colidx = static_cast(distance(nontarget_lhs_vec.begin(), find(nontarget_lhs_vec.begin(), nontarget_lhs_vec.end(), lhs_symb_id))); + int colidx = static_cast( + distance(nontarget_lhs_vec.begin(), + find(nontarget_lhs_vec.begin(), nontarget_lhs_vec.end(), lhs_symb_id))); ar_ec_output << " AR(" << eqn + 1 << ", " << colidx + 1 << ", " << lag << ") = "; expr->writeOutput(ar_ec_output, ExprNodeOutputType::matlabDynamicModel); ar_ec_output << ";" << endl; @@ -345,8 +346,9 @@ TrendComponentModelTable::writeOutput(const string &basename, ostream &output) c ar_ec_output << endl << " % A0" << endl - << " A0 = zeros(" << nontarget_lhs_vec.size() << ", " << nontarget_lhs_vec.size() << ");" << endl; - for (const auto &[key, expr] : A0.at(name)) + << " A0 = zeros(" << nontarget_lhs_vec.size() << ", " + << nontarget_lhs_vec.size() << ");" << endl; + for (const auto& [key, expr] : A0.at(name)) { auto [eqn, colidx] = key; ar_ec_output << " A0(" << eqn + 1 << ", " << colidx + 1 << ") = "; @@ -356,8 +358,9 @@ TrendComponentModelTable::writeOutput(const string &basename, ostream &output) c ar_ec_output << endl << " % A0star" << endl - << " A0star = zeros(" << nontarget_lhs_vec.size() << ", " << target_lhs_vec.size() << ");" << endl; - for (const auto &[key, expr] : A0star.at(name)) + << " A0star = zeros(" << nontarget_lhs_vec.size() << ", " + << target_lhs_vec.size() << ");" << endl; + for (const auto& [key, expr] : A0star.at(name)) { auto [eqn, colidx] = key; ar_ec_output << " A0star(" << eqn + 1 << ", " << colidx + 1 << ") = "; @@ -365,8 +368,7 @@ TrendComponentModelTable::writeOutput(const string &basename, ostream &output) c ar_ec_output << ";" << endl; } - ar_ec_output << " return" << endl - << "end" << endl << endl; + ar_ec_output << " return" << endl << "end" << endl << endl; } ar_ec_output << "error([model_name ' is not a valid trend_component_model name'])" << endl << "end" << endl; @@ -374,26 +376,23 @@ TrendComponentModelTable::writeOutput(const string &basename, ostream &output) c } void -TrendComponentModelTable::writeJsonOutput(ostream &output) const +TrendComponentModelTable::writeJsonOutput(ostream& output) const { - for (bool printed_something{false}; - const auto &name : names) + for (bool printed_something {false}; const auto& name : names) { if (exchange(printed_something, true)) output << ", "; output << R"({"statementName": "trend_component_model",)" << R"("model_name": ")" << name << R"(",)" << R"("eqtags": [)"; - for (bool printed_something2{false}; - const auto &it : eqtags.at(name)) + for (bool printed_something2 {false}; const auto& it : eqtags.at(name)) { if (exchange(printed_something2, true)) output << ", "; output << R"(")" << it << R"(")"; } output << R"(], "target_eqtags": [)"; - for (bool printed_something2{false}; - const auto &it : target_eqtags.at(name)) + for (bool printed_something2 {false}; const auto& it : target_eqtags.at(name)) { if (exchange(printed_something2, true)) output << ", "; @@ -403,8 +402,7 @@ TrendComponentModelTable::writeJsonOutput(ostream &output) const } } -VarModelTable::VarModelTable(SymbolTable &symbol_table_arg) : - symbol_table{symbol_table_arg} +VarModelTable::VarModelTable(SymbolTable& symbol_table_arg) : symbol_table {symbol_table_arg} { } @@ -423,61 +421,58 @@ VarModelTable::addVarModel(string name_arg, bool structural_arg, vector } void -VarModelTable::writeOutput(const string &basename, ostream &output) const +VarModelTable::writeOutput(const string& basename, ostream& output) const { if (names.empty()) return; const filesystem::path filename {DataTree::packageDir(basename) / "varmatrices.m"}; - ofstream ar_output{filename, ios::out | ios::binary}; + ofstream ar_output {filename, ios::out | ios::binary}; if (!ar_output.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; exit(EXIT_FAILURE); } ar_output << "function [ar, a0, constants] = varmatrices(model_name, params, reducedform)" << endl - << "% File automatically generated by the Dynare preprocessor" << endl << endl + << "% File automatically generated by the Dynare preprocessor" << endl + << endl << "if nargin<3" << endl << " reducedform = false;" << endl - << "end" << endl << endl; + << "end" << endl + << endl; - for (const auto &name : names) + for (const auto& name : names) { output << "M_.var." << name << ".model_name = '" << name << "';" << endl - << "M_.var." << name << ".structural = " << boolalpha << structural.at(name) << ";" << endl + << "M_.var." << name << ".structural = " << boolalpha << structural.at(name) << ";" + << endl << "M_.var." << name << ".eqtags = {"; - for (const auto &it : eqtags.at(name)) + for (const auto& it : eqtags.at(name)) output << "'" << it << "'; "; - output << "};" << endl - << "M_.var." << name << ".eqn = ["; + output << "};" << endl << "M_.var." << name << ".eqn = ["; for (auto it : eqnums.at(name)) output << it + 1 << " "; - output << "];" << endl - << "M_.var." << name << ".lhs = ["; + output << "];" << endl << "M_.var." << name << ".lhs = ["; for (auto it : lhs.at(name)) output << symbol_table.getTypeSpecificID(it) + 1 << " "; - output << "];" << endl - << "M_.var." << name << ".max_lag = ["; + output << "];" << endl << "M_.var." << name << ".max_lag = ["; for (auto it : max_lags.at(name)) output << it << " "; - output << "];" << endl - << "M_.var." << name << ".diff = ["; + output << "];" << endl << "M_.var." << name << ".diff = ["; for (bool it : diff.at(name)) output << boolalpha << it << " "; output << "];" << endl << "M_.var." << name << ".nonstationary = M_.var." << name << ".diff;" << endl << "M_.var." << name << ".orig_diff_var = ["; - for (const auto &it : orig_diff_var.at(name)) + for (const auto& it : orig_diff_var.at(name)) output << (it ? symbol_table.getTypeSpecificID(*it) + 1 : -1) << " "; output << "];" << endl; - for (int i{1}; - const auto &it : rhs.at(name)) + for (int i {1}; const auto& it : rhs.at(name)) { output << "M_.var." << name << ".rhs.vars_at_eq{" << i << "}.var = ["; for (auto [var, lag] : it) output << symbol_table.getTypeSpecificID(var) + 1 << " "; - output << "];" << endl - << "M_.var." << name << ".rhs.vars_at_eq{" << i << "}.lag = ["; + output << "];" << endl << "M_.var." << name << ".rhs.vars_at_eq{" << i << "}.lag = ["; for (auto [var, lag] : it) output << lag << " "; output << "];" << endl; @@ -487,22 +482,24 @@ VarModelTable::writeOutput(const string &basename, ostream &output) const vector lhs = getLhsOrigIds(name); ar_output << "if strcmp(model_name, '" << name << "')" << endl - << " ar = zeros(" << lhs.size() << ", " << lhs.size() << ", " << getMaxLag(name) << ");" << endl; - for (const auto &[key, expr] : AR.at(name)) + << " ar = zeros(" << lhs.size() << ", " << lhs.size() << ", " << getMaxLag(name) + << ");" << endl; + for (const auto& [key, expr] : AR.at(name)) { auto [eqn, lag, lhs_symb_id] = key; - int colidx = static_cast(distance(lhs.begin(), find(lhs.begin(), lhs.end(), lhs_symb_id))); + int colidx + = static_cast(distance(lhs.begin(), find(lhs.begin(), lhs.end(), lhs_symb_id))); ar_output << " ar(" << eqn + 1 << "," << colidx + 1 << "," << lag << ") = "; expr->writeOutput(ar_output, ExprNodeOutputType::matlabDynamicModel); ar_output << ";" << endl; } - ar_output << " if nargout>1" << endl - << " a0 = eye(" << lhs.size() << ");" << endl; - for (const auto &[key, expr] : A0.at(name)) + ar_output << " if nargout>1" << endl << " a0 = eye(" << lhs.size() << ");" << endl; + for (const auto& [key, expr] : A0.at(name)) { auto [eqn, lhs_symb_id] = key; - int colidx = static_cast(distance(lhs.begin(), find(lhs.begin(), lhs.end(), lhs_symb_id))); - if (eqn!=colidx) + int colidx + = static_cast(distance(lhs.begin(), find(lhs.begin(), lhs.end(), lhs_symb_id))); + if (eqn != colidx) { ar_output << " a0(" << eqn + 1 << "," << colidx + 1 << ") = "; expr->writeOutput(ar_output, ExprNodeOutputType::matlabDynamicModel); @@ -532,25 +529,24 @@ VarModelTable::writeOutput(const string &basename, ostream &output) const << " end" << endl << " end" << endl << " return" << endl - << "end" << endl << endl; + << "end" << endl + << endl; } ar_output << "error('%s is not a valid var_model name', model_name)" << endl; ar_output.close(); } void -VarModelTable::writeJsonOutput(ostream &output) const +VarModelTable::writeJsonOutput(ostream& output) const { - for (bool printed_something{false}; - const auto &name : names) + for (bool printed_something {false}; const auto& name : names) { if (exchange(printed_something, true)) output << ", "; output << R"({"statementName": "var_model",)" << R"("model_name": ")" << name << R"(",)" << R"("eqtags": [)"; - for (bool printed_something2{false}; - const auto &it : eqtags.at(name)) + for (bool printed_something2 {false}; const auto& it : eqtags.at(name)) { if (exchange(printed_something2, true)) output << ", "; @@ -560,32 +556,31 @@ VarModelTable::writeJsonOutput(ostream &output) const } } -const map & +const map& VarModelTable::getStructural() const { return structural; } -const map> & +const map>& VarModelTable::getEqTags() const { return eqtags; } -const vector & -VarModelTable::getEqTags(const string &name_arg) const +const vector& +VarModelTable::getEqTags(const string& name_arg) const { checkModelName(name_arg); return eqtags.at(name_arg); } void -VarModelTable::checkModelName(const string &name_arg) const +VarModelTable::checkModelName(const string& name_arg) const { if (!isExistingVarModelName(name_arg)) { - cerr << name_arg - << " is not a recognized equation tag of a VAR model equation" << endl; + cerr << name_arg << " is not a recognized equation tag of a VAR model equation" << endl; exit(EXIT_FAILURE); } } @@ -634,21 +629,21 @@ VarModelTable::setLhsExprT(map> lhs_expr_t_arg) lhs_expr_t = move(lhs_expr_t_arg); } -const map> & +const map>& VarModelTable::getEqNums() const { return eqnums; } -const vector & -VarModelTable::getDiff(const string &name_arg) const +const vector& +VarModelTable::getDiff(const string& name_arg) const { checkModelName(name_arg); return diff.at(name_arg); } -const vector & -VarModelTable::getEqNums(const string &name_arg) const +const vector& +VarModelTable::getEqNums(const string& name_arg) const { checkModelName(name_arg); return eqnums.at(name_arg); @@ -690,56 +685,57 @@ VarModelTable::setConstants(map> constants_arg) constants = move(constants_arg); } -const vector & -VarModelTable::getMaxLags(const string &name_arg) const +const vector& +VarModelTable::getMaxLags(const string& name_arg) const { checkModelName(name_arg); return max_lags.at(name_arg); } int -VarModelTable::getMaxLag(const string &name_arg) const +VarModelTable::getMaxLag(const string& name_arg) const { - vector maxlags { getMaxLags(name_arg) }; + vector maxlags {getMaxLags(name_arg)}; return reduce(maxlags.begin(), maxlags.end(), 0, [](int a, int b) { return max(a, b); }); } -const vector & -VarModelTable::getLhs(const string &name_arg) const +const vector& +VarModelTable::getLhs(const string& name_arg) const { checkModelName(name_arg); return lhs.at(name_arg); } -const vector & -VarModelTable::getLhsOrigIds(const string &name_arg) const +const vector& +VarModelTable::getLhsOrigIds(const string& name_arg) const { checkModelName(name_arg); return lhs_orig_symb_ids.at(name_arg); } -const vector>> & -VarModelTable::getRhs(const string &name_arg) const +const vector>>& +VarModelTable::getRhs(const string& name_arg) const { checkModelName(name_arg); return rhs.at(name_arg); } -const vector & -VarModelTable::getLhsExprT(const string &name_arg) const +const vector& +VarModelTable::getLhsExprT(const string& name_arg) const { checkModelName(name_arg); return lhs_expr_t.at(name_arg); } - -VarExpectationModelTable::VarExpectationModelTable(SymbolTable &symbol_table_arg) : - symbol_table{symbol_table_arg} +VarExpectationModelTable::VarExpectationModelTable(SymbolTable& symbol_table_arg) : + symbol_table {symbol_table_arg} { } void -VarExpectationModelTable::addVarExpectationModel(string name_arg, expr_t expression_arg, string aux_model_name_arg, string horizon_arg, expr_t discount_arg, int time_shift_arg) +VarExpectationModelTable::addVarExpectationModel(string name_arg, expr_t expression_arg, + string aux_model_name_arg, string horizon_arg, + expr_t discount_arg, int time_shift_arg) { if (isExistingVarExpectationModelName(name_arg)) { @@ -756,7 +752,7 @@ VarExpectationModelTable::addVarExpectationModel(string name_arg, expr_t express } bool -VarExpectationModelTable::isExistingVarExpectationModelName(const string &name_arg) const +VarExpectationModelTable::isExistingVarExpectationModelName(const string& name_arg) const { return names.contains(name_arg); } @@ -768,25 +764,26 @@ VarExpectationModelTable::empty() const } void -VarExpectationModelTable::writeOutput(ostream &output) const +VarExpectationModelTable::writeOutput(ostream& output) const { - for (const auto &name : names) + for (const auto& name : names) { string mstruct = "M_.var_expectation." + name; output << mstruct << ".auxiliary_model_name = '" << aux_model_name.at(name) << "';" << endl << mstruct << ".horizon = " << horizon.at(name) << ';' << endl << mstruct << ".time_shift = " << time_shift.at(name) << ';' << endl; - auto &vpc = vars_params_constants.at(name); + auto& vpc = vars_params_constants.at(name); if (!vpc.size()) { - cerr << "ERROR: VarExpectationModelStatement::writeOutput: matchExpression() has not been called" << endl; + cerr << "ERROR: VarExpectationModelStatement::writeOutput: matchExpression() has not " + "been called" + << endl; exit(EXIT_FAILURE); } ostringstream vars_list, params_list, constants_list; - for (bool printed_something{false}; - const auto &[variable_id, param_id, constant] : vpc) + for (bool printed_something {false}; const auto& [variable_id, param_id, constant] : vpc) { if (exchange(printed_something, true)) { @@ -794,9 +791,9 @@ VarExpectationModelTable::writeOutput(ostream &output) const params_list << ", "; constants_list << ", "; } - vars_list << symbol_table.getTypeSpecificID(variable_id)+1; + vars_list << symbol_table.getTypeSpecificID(variable_id) + 1; if (param_id) - params_list << symbol_table.getTypeSpecificID(*param_id)+1; + params_list << symbol_table.getTypeSpecificID(*param_id) + 1; else params_list << "NaN"; constants_list << constant; @@ -805,9 +802,10 @@ VarExpectationModelTable::writeOutput(ostream &output) const << mstruct << ".expr.params = [ " << params_list.str() << " ];" << endl << mstruct << ".expr.constants = [ " << constants_list.str() << " ];" << endl; - if (auto disc_var = dynamic_cast(discount.at(name)); - disc_var) - output << mstruct << ".discount_index = " << symbol_table.getTypeSpecificID(disc_var->symb_id) + 1 << ';' << endl; + if (auto disc_var = dynamic_cast(discount.at(name)); disc_var) + output << mstruct + << ".discount_index = " << symbol_table.getTypeSpecificID(disc_var->symb_id) + 1 + << ';' << endl; else { output << mstruct << ".discount_value = "; @@ -816,33 +814,38 @@ VarExpectationModelTable::writeOutput(ostream &output) const } output << mstruct << ".param_indices = [ "; for (int param_id : aux_param_symb_ids.at(name)) - output << symbol_table.getTypeSpecificID(param_id)+1 << ' '; + output << symbol_table.getTypeSpecificID(param_id) + 1 << ' '; output << "];" << endl; } } void -VarExpectationModelTable::substituteUnaryOpsInExpression(const lag_equivalence_table_t &nodes, ExprNode::subst_table_t &subst_table, vector &neweqs) +VarExpectationModelTable::substituteUnaryOpsInExpression(const lag_equivalence_table_t& nodes, + ExprNode::subst_table_t& subst_table, + vector& neweqs) { - for (const auto &name : names) + for (const auto& name : names) expression[name] = expression[name]->substituteUnaryOpNodes(nodes, subst_table, neweqs); } void -VarExpectationModelTable::substituteDiffNodesInExpression(const lag_equivalence_table_t &nodes, ExprNode::subst_table_t &subst_table, vector &neweqs) +VarExpectationModelTable::substituteDiffNodesInExpression(const lag_equivalence_table_t& nodes, + ExprNode::subst_table_t& subst_table, + vector& neweqs) { - for (const auto &name : names) + for (const auto& name : names) expression[name] = expression[name]->substituteDiff(nodes, subst_table, neweqs); } void -VarExpectationModelTable::transformPass(ExprNode::subst_table_t &diff_subst_table, - DynamicModel &dynamic_model, const VarModelTable &var_model_table, - const TrendComponentModelTable &trend_component_model_table) +VarExpectationModelTable::transformPass(ExprNode::subst_table_t& diff_subst_table, + DynamicModel& dynamic_model, + const VarModelTable& var_model_table, + const TrendComponentModelTable& trend_component_model_table) { map var_expectation_subst_table; - for (const auto &name : names) + for (const auto& name : names) { // Collect information about the auxiliary model @@ -869,18 +872,19 @@ VarExpectationModelTable::transformPass(ExprNode::subst_table_t &diff_subst_tabl try { auto vpc = expression[name]->matchLinearCombinationOfVariables(); - for (const auto &[variable_id, lag, param_id, constant] : vpc) + for (const auto& [variable_id, lag, param_id, constant] : vpc) { if (lag != 0) - throw ExprNode::MatchFailureException{"lead/lags are not allowed"}; + throw ExprNode::MatchFailureException {"lead/lags are not allowed"}; if (symbol_table.getType(variable_id) != SymbolType::endogenous) - throw ExprNode::MatchFailureException{"Variable is not an endogenous"}; + throw ExprNode::MatchFailureException {"Variable is not an endogenous"}; vars_params_constants[name].emplace_back(variable_id, param_id, constant); } } - catch (ExprNode::MatchFailureException &e) + catch (ExprNode::MatchFailureException& e) { - cerr << "ERROR: expression in var_expectation_model " << name << " is not of the expected form: " << e.message << endl; + cerr << "ERROR: expression in var_expectation_model " << name + << " is not of the expected form: " << e.message << endl; exit(EXIT_FAILURE); } @@ -892,25 +896,30 @@ VarExpectationModelTable::transformPass(ExprNode::subst_table_t &diff_subst_tabl /* If the auxiliary model is a VAR, add a parameter corresponding to the constant. */ string constant_param_name = "var_expectation_model_" + name + "_constant"; - int constant_param_id = symbol_table.addSymbol(constant_param_name, SymbolType::parameter); + int constant_param_id + = symbol_table.addSymbol(constant_param_name, SymbolType::parameter); aux_param_symb_ids[name].push_back(constant_param_id); - subst_expr = dynamic_model.AddPlus(subst_expr, dynamic_model.AddVariable(constant_param_id)); + subst_expr + = dynamic_model.AddPlus(subst_expr, dynamic_model.AddVariable(constant_param_id)); } for (int lag = 0; lag < max_lag; lag++) for (auto variable : lhs) { - string param_name = "var_expectation_model_" + name + '_' + symbol_table.getName(variable) + '_' + to_string(lag); + string param_name = "var_expectation_model_" + name + '_' + + symbol_table.getName(variable) + '_' + to_string(lag); int new_param_id = symbol_table.addSymbol(param_name, SymbolType::parameter); aux_param_symb_ids[name].push_back(new_param_id); - subst_expr = dynamic_model.AddPlus(subst_expr, - dynamic_model.AddTimes(dynamic_model.AddVariable(new_param_id), - dynamic_model.AddVariable(variable, -lag + time_shift[name]))); + subst_expr = dynamic_model.AddPlus( + subst_expr, dynamic_model.AddTimes( + dynamic_model.AddVariable(new_param_id), + dynamic_model.AddVariable(variable, -lag + time_shift[name]))); } if (var_expectation_subst_table.contains(name)) { - cerr << "ERROR: model name '" << name << "' is used by several var_expectation_model statements" << endl; + cerr << "ERROR: model name '" << name + << "' is used by several var_expectation_model statements" << endl; exit(EXIT_FAILURE); } var_expectation_subst_table[name] = subst_expr; @@ -924,10 +933,9 @@ VarExpectationModelTable::transformPass(ExprNode::subst_table_t &diff_subst_tabl } void -VarExpectationModelTable::writeJsonOutput(ostream &output) const +VarExpectationModelTable::writeJsonOutput(ostream& output) const { - for (bool printed_something{false}; - const auto &name : names) + for (bool printed_something {false}; const auto& name : names) { if (exchange(printed_something, true)) output << ", "; @@ -941,19 +949,17 @@ VarExpectationModelTable::writeJsonOutput(ostream &output) const << R"("discount": ")"; discount.at(name)->writeOutput(output); output << R"(", )" - << R"("time_shift": )" << time_shift.at(name) - << R"(})"; + << R"("time_shift": )" << time_shift.at(name) << R"(})"; } } - -PacModelTable::PacModelTable(SymbolTable &symbol_table_arg) : - symbol_table{symbol_table_arg} +PacModelTable::PacModelTable(SymbolTable& symbol_table_arg) : symbol_table {symbol_table_arg} { } void -PacModelTable::addPacModel(string name_arg, string aux_model_name_arg, string discount_arg, expr_t growth_arg, string auxname_arg, PacTargetKind kind_arg) +PacModelTable::addPacModel(string name_arg, string aux_model_name_arg, string discount_arg, + expr_t growth_arg, string auxname_arg, PacTargetKind kind_arg) { if (isExistingPacModelName(name_arg)) { @@ -971,7 +977,7 @@ PacModelTable::addPacModel(string name_arg, string aux_model_name_arg, string di } bool -PacModelTable::isExistingPacModelName(const string &name_arg) const +PacModelTable::isExistingPacModelName(const string& name_arg) const { return names.contains(name_arg); } @@ -983,75 +989,96 @@ PacModelTable::empty() const } void -PacModelTable::checkPass(ModFileStructure &mod_file_struct) +PacModelTable::checkPass(ModFileStructure& mod_file_struct) { - for (auto &[name, gv] : growth) + for (auto& [name, gv] : growth) if (gv) { if (target_info.contains(name)) { - cerr << "ERROR: for PAC model '" << name << "', it is not possible to declare a 'growth' option in the 'pac_model' command when there is also a 'pac_target_info' block" << endl; + cerr << "ERROR: for PAC model '" << name + << "', it is not possible to declare a 'growth' option in the 'pac_model' command " + "when there is also a 'pac_target_info' block" + << endl; exit(EXIT_FAILURE); } gv->collectVariables(SymbolType::exogenous, mod_file_struct.pac_params); } - for (auto &[name, auxn] : auxname) + for (auto& [name, auxn] : auxname) if (!auxn.empty() && target_info.contains(name)) { - cerr << "ERROR: for PAC model '" << name << "', it is not possible to declare an 'auxname' option in the 'pac_model' command when there is also a 'pac_target_info' block" << endl; + cerr << "ERROR: for PAC model '" << name + << "', it is not possible to declare an 'auxname' option in the 'pac_model' command " + "when there is also a 'pac_target_info' block" + << endl; exit(EXIT_FAILURE); } - for (auto &[name, k] : kind) + for (auto& [name, k] : kind) if (k != PacTargetKind::unspecified) { if (target_info.contains(name)) { - cerr << "ERROR: for PAC model '" << name << "', it is not possible to declare a 'kind' option in the 'pac_model' command when there is also a 'pac_target_info' block" << endl; + cerr << "ERROR: for PAC model '" << name + << "', it is not possible to declare a 'kind' option in the 'pac_model' command " + "when there is also a 'pac_target_info' block" + << endl; exit(EXIT_FAILURE); } if (aux_model_name[name].empty()) { - cerr << "ERROR: for PAC model '" << name << "', it is not possible to declare a 'kind' option in the 'pac_model' command since this is a MCE model" << endl; + cerr << "ERROR: for PAC model '" << name + << "', it is not possible to declare a 'kind' option in the 'pac_model' command " + "since this is a MCE model" + << endl; exit(EXIT_FAILURE); } } - for (const auto &[name, ti] : target_info) - for (auto &[expr, gv, auxname, kind, coeff, growth_neutrality_param, h_indices, original_gv, gv_info] : get<2>(ti)) + for (const auto& [name, ti] : target_info) + for (auto& [expr, gv, auxname, kind, coeff, growth_neutrality_param, h_indices, original_gv, + gv_info] : get<2>(ti)) if (gv) gv->collectVariables(SymbolType::exogenous, mod_file_struct.pac_params); - for (const auto &[name, ti] : target_info) + for (const auto& [name, ti] : target_info) { - auto &[target, auxname_target_nonstationary, components] = ti; + auto& [target, auxname_target_nonstationary, components] = ti; if (!target) { - cerr << "ERROR: the block 'pac_target_info(" << name << ")' is missing the 'target' statement" << endl; + cerr << "ERROR: the block 'pac_target_info(" << name + << ")' is missing the 'target' statement" << endl; exit(EXIT_FAILURE); } if (auxname_target_nonstationary.empty()) { - cerr << "ERROR: the block 'pac_target_info(" << name << ")' is missing the 'auxname_target_nonstationary' statement" << endl; + cerr << "ERROR: the block 'pac_target_info(" << name + << ")' is missing the 'auxname_target_nonstationary' statement" << endl; exit(EXIT_FAILURE); } int nonstationary_nb = 0; - for (auto &[component, growth_component, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth_component, growth_component_info] : components) + for (auto& [component, growth_component, auxname, kind, coeff, growth_neutrality_param, + h_indices, original_growth_component, growth_component_info] : components) { if (auxname.empty()) { - cerr << "ERROR: the block 'pac_target_info(" << name << ")' is missing the 'auxname' statement in some 'component'" << endl; + cerr << "ERROR: the block 'pac_target_info(" << name + << ")' is missing the 'auxname' statement in some 'component'" << endl; exit(EXIT_FAILURE); } if (kind == PacTargetKind::unspecified) { - cerr << "ERROR: the block 'pac_target_info(" << name << ")' is missing the 'kind' statement in some 'component'" << endl; + cerr << "ERROR: the block 'pac_target_info(" << name + << ")' is missing the 'kind' statement in some 'component'" << endl; exit(EXIT_FAILURE); } if (kind == PacTargetKind::ll && growth_component) { - cerr << "ERROR: in the block 'pac_target_info(" << name << ")', a component of 'kind ll' (i.e. stationary) has a 'growth' option. This is not permitted." << endl; + cerr << "ERROR: in the block 'pac_target_info(" << name + << ")', a component of 'kind ll' (i.e. stationary) has a 'growth' option. This " + "is not permitted." + << endl; exit(EXIT_FAILURE); } if (kind == PacTargetKind::dd || kind == PacTargetKind::dl) @@ -1059,63 +1086,73 @@ PacModelTable::checkPass(ModFileStructure &mod_file_struct) } if (!nonstationary_nb) { - cerr << "ERROR: the block 'pac_target_info(" << name << ")' must contain at least one nonstationary component (i.e. of 'kind' equal to either 'dd' or 'dl')." << endl; + cerr << "ERROR: the block 'pac_target_info(" << name + << ")' must contain at least one nonstationary component (i.e. of 'kind' equal to " + "either 'dd' or 'dl')." + << endl; exit(EXIT_FAILURE); } } } void -PacModelTable::substituteUnaryOpsInGrowth(const lag_equivalence_table_t &nodes, ExprNode::subst_table_t &subst_table, vector &neweqs) +PacModelTable::substituteUnaryOpsInGrowth(const lag_equivalence_table_t& nodes, + ExprNode::subst_table_t& subst_table, + vector& neweqs) { - for (auto &[name, gv] : growth) + for (auto& [name, gv] : growth) if (gv) gv = gv->substituteUnaryOpNodes(nodes, subst_table, neweqs); - for (auto &[name, ti] : target_info) - for (auto &[expr, gv, auxname, kind, coeff, growth_neutrality_param, h_indices, original_gv, gv_info] : get<2>(ti)) + for (auto& [name, ti] : target_info) + for (auto& [expr, gv, auxname, kind, coeff, growth_neutrality_param, h_indices, original_gv, + gv_info] : get<2>(ti)) if (gv) gv = gv->substituteUnaryOpNodes(nodes, subst_table, neweqs); } void -PacModelTable::findDiffNodesInGrowth(lag_equivalence_table_t &diff_nodes) const +PacModelTable::findDiffNodesInGrowth(lag_equivalence_table_t& diff_nodes) const { - for (auto &[name, gv] : growth) + for (auto& [name, gv] : growth) if (gv) gv->findDiffNodes(diff_nodes); - for (const auto &[name, ti] : target_info) - for (auto &[expr, gv, auxname, kind, coeff, growth_neutrality_param, h_indices, original_gv, gv_info] : get<2>(ti)) + for (const auto& [name, ti] : target_info) + for (auto& [expr, gv, auxname, kind, coeff, growth_neutrality_param, h_indices, original_gv, + gv_info] : get<2>(ti)) if (gv) gv->findDiffNodes(diff_nodes); } void -PacModelTable::substituteDiffNodesInGrowth(const lag_equivalence_table_t &diff_nodes, ExprNode::subst_table_t &diff_subst_table, vector &neweqs) +PacModelTable::substituteDiffNodesInGrowth(const lag_equivalence_table_t& diff_nodes, + ExprNode::subst_table_t& diff_subst_table, + vector& neweqs) { - for (auto &[name, gv] : growth) + for (auto& [name, gv] : growth) if (gv) gv = gv->substituteDiff(diff_nodes, diff_subst_table, neweqs); - for (auto &[name, ti] : target_info) - for (auto &[expr, gv, auxname, kind, coeff, growth_neutrality_param, h_indices, original_gv, gv_info] : get<2>(ti)) + for (auto& [name, ti] : target_info) + for (auto& [expr, gv, auxname, kind, coeff, growth_neutrality_param, h_indices, original_gv, + gv_info] : get<2>(ti)) if (gv) gv = gv->substituteDiff(diff_nodes, diff_subst_table, neweqs); } void -PacModelTable::transformPass(const lag_equivalence_table_t &unary_ops_nodes, - ExprNode::subst_table_t &unary_ops_subst_table, - const lag_equivalence_table_t &diff_nodes, - ExprNode::subst_table_t &diff_subst_table, - DynamicModel &dynamic_model, const VarModelTable &var_model_table, - const TrendComponentModelTable &trend_component_model_table) +PacModelTable::transformPass(const lag_equivalence_table_t& unary_ops_nodes, + ExprNode::subst_table_t& unary_ops_subst_table, + const lag_equivalence_table_t& diff_nodes, + ExprNode::subst_table_t& diff_subst_table, DynamicModel& dynamic_model, + const VarModelTable& var_model_table, + const TrendComponentModelTable& trend_component_model_table) { // model name → expression for pac_expectation map pac_expectation_substitution; - for (const auto &name : names) + for (const auto& name : names) { /* Fill the growth_info structure. Cannot be done in an earlier pass since growth terms can be @@ -1125,7 +1162,7 @@ PacModelTable::transformPass(const lag_equivalence_table_t &unary_ops_nodes, { growth_info[name] = growth[name]->matchLinearCombinationOfVariablesPlusConstant(); } - catch (ExprNode::MatchFailureException &e) + catch (ExprNode::MatchFailureException& e) { cerr << "ERROR: PAC growth must be a linear combination of variables" << endl; exit(EXIT_FAILURE); @@ -1135,35 +1172,45 @@ PacModelTable::transformPass(const lag_equivalence_table_t &unary_ops_nodes, if (target_info.contains(name)) { // Substitute unary ops and diffs in the target… - expr_t &target = get<0>(target_info[name]); - vector neweqs; + expr_t& target = get<0>(target_info[name]); + vector neweqs; target = target->substituteUnaryOpNodes(unary_ops_nodes, unary_ops_subst_table, neweqs); if (neweqs.size() > 0) { - cerr << "ERROR: the 'target' expression of 'pac_target_info(" << name << ")' contains a variable with a unary operator that is not present in the model" << endl; + cerr + << "ERROR: the 'target' expression of 'pac_target_info(" << name + << ")' contains a variable with a unary operator that is not present in the model" + << endl; exit(EXIT_FAILURE); } target = target->substituteDiff(diff_nodes, diff_subst_table, neweqs); if (neweqs.size() > 0) { - cerr << "ERROR: the 'target' expression of 'pac_target_info(" << name << ")' contains a diff'd variable that is not present in the model" << endl; + cerr << "ERROR: the 'target' expression of 'pac_target_info(" << name + << ")' contains a diff'd variable that is not present in the model" << endl; exit(EXIT_FAILURE); } // …and in component expressions - auto &components = get<2>(target_info[name]); - for (auto &[component, growth_component, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth_component, growth_component_info] : components) + auto& components = get<2>(target_info[name]); + for (auto& [component, growth_component, auxname, kind, coeff, growth_neutrality_param, + h_indices, original_growth_component, growth_component_info] : components) { - component = component->substituteUnaryOpNodes(unary_ops_nodes, unary_ops_subst_table, neweqs); + component = component->substituteUnaryOpNodes(unary_ops_nodes, unary_ops_subst_table, + neweqs); if (neweqs.size() > 0) { - cerr << "ERROR: a 'component' expression of 'pac_target_info(" << name << ")' contains a variable with a unary operator that is not present in the model" << endl; + cerr << "ERROR: a 'component' expression of 'pac_target_info(" << name + << ")' contains a variable with a unary operator that is not present in the " + "model" + << endl; exit(EXIT_FAILURE); } component = component->substituteDiff(diff_nodes, diff_subst_table, neweqs); if (neweqs.size() > 0) { - cerr << "ERROR: a 'component' expression of 'pac_target_info(" << name << ")' contains a diff'd variable that is not present in the model" << endl; + cerr << "ERROR: a 'component' expression of 'pac_target_info(" << name + << ")' contains a diff'd variable that is not present in the model" << endl; exit(EXIT_FAILURE); } } @@ -1171,14 +1218,16 @@ PacModelTable::transformPass(const lag_equivalence_table_t &unary_ops_nodes, /* Fill the growth_info structure. Cannot be done in an earlier pass since growth terms can be transformed by DynamicModel::substituteDiff(). */ - for (auto &[component, growth_component, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth_component, growth_component_info] : components) + for (auto& [component, growth_component, auxname, kind, coeff, growth_neutrality_param, + h_indices, original_growth_component, growth_component_info] : components) { if (growth_component) try { - growth_component_info = growth_component->matchLinearCombinationOfVariablesPlusConstant(); + growth_component_info + = growth_component->matchLinearCombinationOfVariablesPlusConstant(); } - catch (ExprNode::MatchFailureException &e) + catch (ExprNode::MatchFailureException& e) { cerr << "ERROR: PAC growth must be a linear combination of variables" << endl; exit(EXIT_FAILURE); @@ -1193,21 +1242,28 @@ PacModelTable::transformPass(const lag_equivalence_table_t &unary_ops_nodes, } catch (ExprNode::MatchFailureException) { - cerr << "ERROR: there is no equation whose LHS is equal to the 'target' of 'pac_target_info(" << name << ")'" << endl; + cerr << "ERROR: there is no equation whose LHS is equal to the 'target' of " + "'pac_target_info(" + << name << ")'" << endl; exit(EXIT_FAILURE); } // Substitute unary ops and diffs in that equation, before parsing (see dynare#1837) - target_expr = target_expr->substituteUnaryOpNodes(unary_ops_nodes, unary_ops_subst_table, neweqs); + target_expr + = target_expr->substituteUnaryOpNodes(unary_ops_nodes, unary_ops_subst_table, neweqs); if (neweqs.size() > 0) { - cerr << "ERROR: the equation defining the target of 'pac_target_info(" << name << ")' contains a variable with a unary operator that is not present in the model" << endl; + cerr + << "ERROR: the equation defining the target of 'pac_target_info(" << name + << ")' contains a variable with a unary operator that is not present in the model" + << endl; exit(EXIT_FAILURE); } target_expr = target_expr->substituteDiff(diff_nodes, diff_subst_table, neweqs); if (neweqs.size() > 0) { - cerr << "ERROR: the equation defining the target of 'pac_target_info(" << name << ")' contains a diff'd variable that is not present in the model" << endl; + cerr << "ERROR: the equation defining the target of 'pac_target_info(" << name + << ")' contains a diff'd variable that is not present in the model" << endl; exit(EXIT_FAILURE); } @@ -1220,38 +1276,51 @@ PacModelTable::transformPass(const lag_equivalence_table_t &unary_ops_nodes, } catch (ExprNode::MatchFailureException) { - cerr << "ERROR: the model equation defining the 'target' of 'pac_target_info(" << name << ")' is not of the right form (should be a linear combination of endogenous variables)" << endl; + cerr << "ERROR: the model equation defining the 'target' of 'pac_target_info(" << name + << ")' is not of the right form (should be a linear combination of endogenous " + "variables)" + << endl; exit(EXIT_FAILURE); } // Associate the coefficients of the linear combination with the right components for (auto [var, coeff] : terms) - if (auto it = find_if(components.begin(), components.end(), - [&](const auto &v) { return get<0>(v) == dynamic_model.AddVariable(var); }); + if (auto it = find_if( + components.begin(), components.end(), + [&](const auto& v) { return get<0>(v) == dynamic_model.AddVariable(var); }); it != components.end()) get<4>(*it) = coeff; else { - cerr << "ERROR: the model equation defining the 'target' of 'pac_target_info(" << name << ")' contains a variable (" << symbol_table.getName(var) << ") that is not declared as a 'component'" << endl; + cerr << "ERROR: the model equation defining the 'target' of 'pac_target_info(" + << name << ")' contains a variable (" << symbol_table.getName(var) + << ") that is not declared as a 'component'" << endl; exit(EXIT_FAILURE); } // Verify that all declared components appear in that equation - for (const auto &[component, growth_component, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth_component, growth_component_info] : components) + for (const auto& [component, growth_component, auxname, kind, coeff, + growth_neutrality_param, h_indices, original_growth_component, + growth_component_info] : components) if (!coeff) { - cerr << "ERROR: a 'component' of 'pac_target_info(" << name << ")' does not appear in the model equation defining the 'target'" << endl; + cerr << "ERROR: a 'component' of 'pac_target_info(" << name + << ")' does not appear in the model equation defining the 'target'" << endl; exit(EXIT_FAILURE); } /* Add the variable and equation defining the stationary part of the target. Note that it includes the constant. */ expr_t yns = constant; - for (const auto &[component, growth_component, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth_component, growth_component_info] : components) + for (const auto& [component, growth_component, auxname, kind, coeff, + growth_neutrality_param, h_indices, original_growth_component, + growth_component_info] : components) if (kind != PacTargetKind::ll) yns = dynamic_model.AddPlus(yns, dynamic_model.AddTimes(coeff, component)); - int target_nonstationary_id = symbol_table.addPacTargetNonstationaryAuxiliaryVar(get<1>(target_info[name]), yns); - expr_t neweq = dynamic_model.AddEqual(dynamic_model.AddVariable(target_nonstationary_id), yns); + int target_nonstationary_id + = symbol_table.addPacTargetNonstationaryAuxiliaryVar(get<1>(target_info[name]), yns); + expr_t neweq + = dynamic_model.AddEqual(dynamic_model.AddVariable(target_nonstationary_id), yns); dynamic_model.addEquation(neweq, nullopt); dynamic_model.addAuxEquation(neweq); @@ -1259,7 +1328,8 @@ PacModelTable::transformPass(const lag_equivalence_table_t &unary_ops_nodes, This needs to be done here, otherwise DynamicModel::analyzePacEquationStructure() will not be able to identify the error-correction part */ - dynamic_model.substitutePacTargetNonstationary(name, dynamic_model.AddVariable(target_nonstationary_id, -1)); + dynamic_model.substitutePacTargetNonstationary( + name, dynamic_model.AddVariable(target_nonstationary_id, -1)); } // Collect some information about PAC models @@ -1280,7 +1350,8 @@ PacModelTable::transformPass(const lag_equivalence_table_t &unary_ops_nodes, max_lag = 0; else { - cerr << "Error: aux_model_name not recognized as VAR model or Trend Component model" << endl; + cerr << "Error: aux_model_name not recognized as VAR model or Trend Component model" + << endl; exit(EXIT_FAILURE); } dynamic_model.analyzePacEquationStructure(name, eq_name, equation_info); @@ -1296,7 +1367,10 @@ PacModelTable::transformPass(const lag_equivalence_table_t &unary_ops_nodes, } catch (SymbolTable::AlreadyDeclaredException) { - cerr << "The variable/parameter '" << param_name << "' conflicts with the auxiliary parameter that will be generated for the growth neutrality correction of the '" << name << "' PAC model. Please rename that parameter." << endl; + cerr << "The variable/parameter '" << param_name + << "' conflicts with the auxiliary parameter that will be generated for the " + "growth neutrality correction of the '" + << name << "' PAC model. Please rename that parameter." << endl; exit(EXIT_FAILURE); } } @@ -1304,44 +1378,37 @@ PacModelTable::transformPass(const lag_equivalence_table_t &unary_ops_nodes, // Compute the expressions that will be substituted for the pac_expectation operators expr_t growth_correction_term = dynamic_model.Zero; if (growth[name]) - growth_correction_term = dynamic_model.AddTimes(growth[name], dynamic_model.AddVariable(growth_neutrality_params[name])); + growth_correction_term = dynamic_model.AddTimes( + growth[name], dynamic_model.AddVariable(growth_neutrality_params[name])); if (aux_model_name[name].empty()) { if (target_info.contains(name)) { - cerr << "ERROR: the block 'pac_target_info(" << name << ")' is not supported in the context of a PAC model with model-consistent expectations (MCE)." << endl; + cerr << "ERROR: the block 'pac_target_info(" << name + << ")' is not supported in the context of a PAC model with model-consistent " + "expectations (MCE)." + << endl; exit(EXIT_FAILURE); } else - dynamic_model.computePacModelConsistentExpectationSubstitution(name, - symbol_table.getID(discount[name]), - pacEquationMaxLag(name), - growth_correction_term, - auxname[name], - diff_subst_table, - aux_var_symb_ids, - aux_param_symb_ids, - pac_expectation_substitution); + dynamic_model.computePacModelConsistentExpectationSubstitution( + name, symbol_table.getID(discount[name]), pacEquationMaxLag(name), + growth_correction_term, auxname[name], diff_subst_table, aux_var_symb_ids, + aux_param_symb_ids, pac_expectation_substitution); } else { if (target_info.contains(name)) { assert(growth_correction_term == dynamic_model.Zero); - dynamic_model.computePacBackwardExpectationSubstitutionWithComponents(name, lhs[name], - max_lag, - aux_model_type[name], - get<2>(target_info[name]), - pac_expectation_substitution); + dynamic_model.computePacBackwardExpectationSubstitutionWithComponents( + name, lhs[name], max_lag, aux_model_type[name], get<2>(target_info[name]), + pac_expectation_substitution); } else - dynamic_model.computePacBackwardExpectationSubstitution(name, lhs[name], max_lag, - aux_model_type[name], - growth_correction_term, - auxname[name], - aux_var_symb_ids, - aux_param_symb_ids, - pac_expectation_substitution); + dynamic_model.computePacBackwardExpectationSubstitution( + name, lhs[name], max_lag, aux_model_type[name], growth_correction_term, + auxname[name], aux_var_symb_ids, aux_param_symb_ids, pac_expectation_substitution); } } @@ -1354,13 +1421,11 @@ PacModelTable::transformPass(const lag_equivalence_table_t &unary_ops_nodes, } void -PacModelTable::writeOutput(ostream &output) const +PacModelTable::writeOutput(ostream& output) const { // Helper to print the “growth_info” structure (linear decomposition of growth) - auto growth_info_helper = [&](const string &fieldname, const growth_info_t &gi) - { - for (int i{1}; - auto [growth_symb_id, growth_lag, param_id, constant] : gi) + auto growth_info_helper = [&](const string& fieldname, const growth_info_t& gi) { + for (int i {1}; auto [growth_symb_id, growth_lag, param_id, constant] : gi) { string structname = fieldname + "(" + to_string(i++) + ")."; if (growth_symb_id) @@ -1377,7 +1442,8 @@ PacModelTable::writeOutput(ostream &output) const { // case when this is not the highest lag of the growth variable int aux_symb_id = symbol_table.searchAuxiliaryVars(*growth_symb_id, growth_lag); - output << structname << var_field << " = " << symbol_table.getTypeSpecificID(aux_symb_id) + 1 << ";" << endl + output << structname << var_field << " = " + << symbol_table.getTypeSpecificID(aux_symb_id) + 1 << ";" << endl << structname << "lag = 0;" << endl; } catch (...) @@ -1386,14 +1452,17 @@ PacModelTable::writeOutput(ostream &output) const { // case when this is the highest lag of the growth variable int tmp_growth_lag = growth_lag + 1; - int aux_symb_id = symbol_table.searchAuxiliaryVars(*growth_symb_id, tmp_growth_lag); - output << structname << var_field << " = " << symbol_table.getTypeSpecificID(aux_symb_id) + 1 << ";" << endl + int aux_symb_id + = symbol_table.searchAuxiliaryVars(*growth_symb_id, tmp_growth_lag); + output << structname << var_field << " = " + << symbol_table.getTypeSpecificID(aux_symb_id) + 1 << ";" << endl << structname << "lag = -1;" << endl; } catch (...) { // case when there is no aux var for the variable - output << structname << var_field << " = "<< symbol_table.getTypeSpecificID(*growth_symb_id) + 1 << ";" << endl + output << structname << var_field << " = " + << symbol_table.getTypeSpecificID(*growth_symb_id) + 1 << ";" << endl << structname << "lag = " << growth_lag << ";" << endl; } } @@ -1402,16 +1471,20 @@ PacModelTable::writeOutput(ostream &output) const output << structname << "endo_id = 0;" << endl << structname << "exo_id = 0;" << endl << structname << "lag = 0;" << endl; - output << structname << "param_id = " - << (param_id ? symbol_table.getTypeSpecificID(*param_id) + 1 : 0) << ";" << endl + output << structname + << "param_id = " << (param_id ? symbol_table.getTypeSpecificID(*param_id) + 1 : 0) + << ";" << endl << structname << "constant = " << constant << ";" << endl; } }; - for (const auto &name : names) + for (const auto& name : names) { - output << "M_.pac." << name << ".auxiliary_model_name = '" << aux_model_name.at(name) << "';" << endl - << "M_.pac." << name << ".discount_index = " << symbol_table.getTypeSpecificID(discount.at(name)) + 1 << ";" << endl; + output << "M_.pac." << name << ".auxiliary_model_name = '" << aux_model_name.at(name) << "';" + << endl + << "M_.pac." << name + << ".discount_index = " << symbol_table.getTypeSpecificID(discount.at(name)) + 1 << ";" + << endl; if (growth.at(name)) { @@ -1423,61 +1496,64 @@ PacModelTable::writeOutput(ostream &output) const } // Write the auxiliary parameter IDs created for the pac_expectation operator - for (auto &[name, ids] : aux_param_symb_ids) + for (auto& [name, ids] : aux_param_symb_ids) { - output << "M_.pac." << name << "." << (aux_model_name.at(name).empty() ? "mce.alpha" : "h_param_indices") << " = ["; + output << "M_.pac." << name << "." + << (aux_model_name.at(name).empty() ? "mce.alpha" : "h_param_indices") << " = ["; for (auto id : ids) output << symbol_table.getTypeSpecificID(id) + 1 << " "; output << "];" << endl; } // Write the auxiliary variable IDs created for the pac_expectation operator - for (auto &[name, id] : aux_var_symb_ids) + for (auto& [name, id] : aux_var_symb_ids) output << "M_.pac." << name << "." << (aux_model_name.at(name).empty() ? "mce.z1" : "aux_id") << " = " << symbol_table.getTypeSpecificID(id) + 1 << ";" << endl; // Write PAC equation name info - for (auto &[name, eq] : eq_name) + for (auto& [name, eq] : eq_name) output << "M_.pac." << name << ".eq_name = '" << eq << "';" << endl; - for (auto &[model, growth_neutrality_param_index] : growth_neutrality_params) + for (auto& [model, growth_neutrality_param_index] : growth_neutrality_params) output << "M_.pac." << model << ".growth_neutrality_param_index = " << symbol_table.getTypeSpecificID(growth_neutrality_param_index) + 1 << ";" << endl; - for (auto &[model, type] : aux_model_type) - output << "M_.pac." << model << ".auxiliary_model_type = '" << type << "';" << endl; + for (auto& [model, type] : aux_model_type) + output << "M_.pac." << model << ".auxiliary_model_type = '" << type << "';" << endl; - for (auto &[name, k] : kind) + for (auto& [name, k] : kind) if (!aux_model_name.empty()) output << "M_.pac." << name << ".kind = '" << (k == PacTargetKind::unspecified ? "" : kindToString(k)) << "';" << endl; - for (auto &[name, val] : equation_info) + for (auto& [name, val] : equation_info) { - auto &[lhs_pac_var, optim_share_index, ar_params_and_vars, ec_params_and_vars, non_optim_vars_params_and_constants, additive_vars_params_and_constants, optim_additive_vars_params_and_constants] = val; - output << "M_.pac." << name << ".lhs_var = " - << symbol_table.getTypeSpecificID(lhs_pac_var.first) + 1 << ";" << endl; + auto& [lhs_pac_var, optim_share_index, ar_params_and_vars, ec_params_and_vars, + non_optim_vars_params_and_constants, additive_vars_params_and_constants, + optim_additive_vars_params_and_constants] + = val; + output << "M_.pac." << name + << ".lhs_var = " << symbol_table.getTypeSpecificID(lhs_pac_var.first) + 1 << ";" + << endl; if (optim_share_index) output << "M_.pac." << name << ".share_of_optimizing_agents_index = " << symbol_table.getTypeSpecificID(*optim_share_index) + 1 << ";" << endl; - output << "M_.pac." << name << ".ec.params = " - << symbol_table.getTypeSpecificID(ec_params_and_vars.first) + 1 << ";" << endl + output << "M_.pac." << name + << ".ec.params = " << symbol_table.getTypeSpecificID(ec_params_and_vars.first) + 1 + << ";" << endl << "M_.pac." << name << ".ec.vars = ["; - for (auto &it : ec_params_and_vars.second) + for (auto& it : ec_params_and_vars.second) output << symbol_table.getTypeSpecificID(get<0>(it)) + 1 << " "; - output << "];" << endl - << "M_.pac." << name << ".ec.istarget = ["; - for (auto &it : ec_params_and_vars.second) + output << "];" << endl << "M_.pac." << name << ".ec.istarget = ["; + for (auto& it : ec_params_and_vars.second) output << boolalpha << get<1>(it) << " "; - output << "];" << endl - << "M_.pac." << name << ".ec.scale = ["; - for (auto &it : ec_params_and_vars.second) + output << "];" << endl << "M_.pac." << name << ".ec.scale = ["; + for (auto& it : ec_params_and_vars.second) output << get<2>(it) << " "; - output << "];" << endl - << "M_.pac." << name << ".ec.isendo = ["; - for (auto &it : ec_params_and_vars.second) + output << "];" << endl << "M_.pac." << name << ".ec.isendo = ["; + for (auto& it : ec_params_and_vars.second) switch (symbol_table.getType(get<0>(it))) { case SymbolType::endogenous: @@ -1490,35 +1566,30 @@ PacModelTable::writeOutput(ostream &output) const cerr << "expecting endogenous or exogenous" << endl; exit(EXIT_FAILURE); } - output << "];" << endl - << "M_.pac." << name << ".ar.params = ["; - for (auto &[pid, vid, vlag] : ar_params_and_vars) + output << "];" << endl << "M_.pac." << name << ".ar.params = ["; + for (auto& [pid, vid, vlag] : ar_params_and_vars) output << (pid ? symbol_table.getTypeSpecificID(*pid) + 1 : -1) << " "; - output << "];" << endl - << "M_.pac." << name << ".ar.vars = ["; - for (auto &[pid, vid, vlag] : ar_params_and_vars) + output << "];" << endl << "M_.pac." << name << ".ar.vars = ["; + for (auto& [pid, vid, vlag] : ar_params_and_vars) output << (vid ? symbol_table.getTypeSpecificID(*vid) + 1 : -1) << " "; - output << "];" << endl - << "M_.pac." << name << ".ar.lags = ["; - for (auto &[pid, vid, vlag] : ar_params_and_vars) + output << "];" << endl << "M_.pac." << name << ".ar.lags = ["; + for (auto& [pid, vid, vlag] : ar_params_and_vars) output << vlag << " "; output << "];" << endl << "M_.pac." << name << ".max_lag = " << pacEquationMaxLag(name) << ";" << endl; if (!non_optim_vars_params_and_constants.empty()) { output << "M_.pac." << name << ".non_optimizing_behaviour.params = ["; - for (auto &it : non_optim_vars_params_and_constants) + for (auto& it : non_optim_vars_params_and_constants) if (get<2>(it)) output << symbol_table.getTypeSpecificID(*get<2>(it)) + 1 << " "; else output << "NaN "; - output << "];" << endl - << "M_.pac." << name << ".non_optimizing_behaviour.vars = ["; - for (auto &it : non_optim_vars_params_and_constants) + output << "];" << endl << "M_.pac." << name << ".non_optimizing_behaviour.vars = ["; + for (auto& it : non_optim_vars_params_and_constants) output << symbol_table.getTypeSpecificID(get<0>(it)) + 1 << " "; - output << "];" << endl - << "M_.pac." << name << ".non_optimizing_behaviour.isendo = ["; - for (auto &it : non_optim_vars_params_and_constants) + output << "];" << endl << "M_.pac." << name << ".non_optimizing_behaviour.isendo = ["; + for (auto& it : non_optim_vars_params_and_constants) switch (symbol_table.getType(get<0>(it))) { case SymbolType::endogenous: @@ -1531,31 +1602,28 @@ PacModelTable::writeOutput(ostream &output) const cerr << "expecting endogenous or exogenous" << endl; exit(EXIT_FAILURE); } - output << "];" << endl - << "M_.pac." << name << ".non_optimizing_behaviour.lags = ["; - for (auto &it : non_optim_vars_params_and_constants) + output << "];" << endl << "M_.pac." << name << ".non_optimizing_behaviour.lags = ["; + for (auto& it : non_optim_vars_params_and_constants) output << get<1>(it) << " "; output << "];" << endl << "M_.pac." << name << ".non_optimizing_behaviour.scaling_factor = ["; - for (auto &it : non_optim_vars_params_and_constants) + for (auto& it : non_optim_vars_params_and_constants) output << get<3>(it) << " "; output << "];" << endl; } if (!additive_vars_params_and_constants.empty()) { output << "M_.pac." << name << ".additive.params = ["; - for (auto &it : additive_vars_params_and_constants) + for (auto& it : additive_vars_params_and_constants) if (get<2>(it)) output << symbol_table.getTypeSpecificID(*get<2>(it)) + 1 << " "; else output << "NaN "; - output << "];" << endl - << "M_.pac." << name << ".additive.vars = ["; - for (auto &it : additive_vars_params_and_constants) + output << "];" << endl << "M_.pac." << name << ".additive.vars = ["; + for (auto& it : additive_vars_params_and_constants) output << symbol_table.getTypeSpecificID(get<0>(it)) + 1 << " "; - output << "];" << endl - << "M_.pac." << name << ".additive.isendo = ["; - for (auto &it : additive_vars_params_and_constants) + output << "];" << endl << "M_.pac." << name << ".additive.isendo = ["; + for (auto& it : additive_vars_params_and_constants) switch (symbol_table.getType(get<0>(it))) { case SymbolType::endogenous: @@ -1568,31 +1636,27 @@ PacModelTable::writeOutput(ostream &output) const cerr << "expecting endogenous or exogenous" << endl; exit(EXIT_FAILURE); } - output << "];" << endl - << "M_.pac." << name << ".additive.lags = ["; - for (auto &it : additive_vars_params_and_constants) + output << "];" << endl << "M_.pac." << name << ".additive.lags = ["; + for (auto& it : additive_vars_params_and_constants) output << get<1>(it) << " "; - output << "];" << endl - << "M_.pac." << name << ".additive.scaling_factor = ["; - for (auto &it : additive_vars_params_and_constants) + output << "];" << endl << "M_.pac." << name << ".additive.scaling_factor = ["; + for (auto& it : additive_vars_params_and_constants) output << get<3>(it) << " "; output << "];" << endl; } if (!optim_additive_vars_params_and_constants.empty()) { output << "M_.pac." << name << ".optim_additive.params = ["; - for (auto &it : optim_additive_vars_params_and_constants) + for (auto& it : optim_additive_vars_params_and_constants) if (get<2>(it)) output << symbol_table.getTypeSpecificID(*get<2>(it)) + 1 << " "; else output << "NaN "; - output << "];" << endl - << "M_.pac." << name << ".optim_additive.vars = ["; - for (auto &it : optim_additive_vars_params_and_constants) + output << "];" << endl << "M_.pac." << name << ".optim_additive.vars = ["; + for (auto& it : optim_additive_vars_params_and_constants) output << symbol_table.getTypeSpecificID(get<0>(it)) + 1 << " "; - output << "];" << endl - << "M_.pac." << name << ".optim_additive.isendo = ["; - for (auto &it : optim_additive_vars_params_and_constants) + output << "];" << endl << "M_.pac." << name << ".optim_additive.isendo = ["; + for (auto& it : optim_additive_vars_params_and_constants) switch (symbol_table.getType(get<0>(it))) { case SymbolType::endogenous: @@ -1605,36 +1669,39 @@ PacModelTable::writeOutput(ostream &output) const cerr << "expecting endogenous or exogenous" << endl; exit(EXIT_FAILURE); } - output << "];" << endl - << "M_.pac." << name << ".optim_additive.lags = ["; - for (auto &it : optim_additive_vars_params_and_constants) + output << "];" << endl << "M_.pac." << name << ".optim_additive.lags = ["; + for (auto& it : optim_additive_vars_params_and_constants) output << get<1>(it) << " "; - output << "];" << endl - << "M_.pac." << name << ".optim_additive.scaling_factor = ["; - for (auto &it : optim_additive_vars_params_and_constants) + output << "];" << endl << "M_.pac." << name << ".optim_additive.scaling_factor = ["; + for (auto& it : optim_additive_vars_params_and_constants) output << get<3>(it) << " "; output << "];" << endl; } } - for (auto &[name, val] : target_info) - for (int component_idx{1}; - auto &[component, growth_component, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth_component, growth_component_info] : get<2>(val)) + for (auto& [name, val] : target_info) + for (int component_idx {1}; + auto& [component, growth_component, auxname, kind, coeff, growth_neutrality_param, + h_indices, original_growth_component, growth_component_info] : get<2>(val)) { string fieldname = "M_.pac." + name + ".components(" + to_string(component_idx) + ")"; - output << fieldname << ".aux_id = " << symbol_table.getTypeSpecificID(auxname) + 1 << ";" << endl - << fieldname << ".endo_var = " << symbol_table.getTypeSpecificID(dynamic_cast(component)->symb_id) + 1 << ";" << endl + output << fieldname << ".aux_id = " << symbol_table.getTypeSpecificID(auxname) + 1 << ";" + << endl + << fieldname << ".endo_var = " + << symbol_table.getTypeSpecificID(dynamic_cast(component)->symb_id) + + 1 + << ";" << endl << fieldname << ".kind = '" << kindToString(kind) << "';" << endl << fieldname << ".h_param_indices = ["; for (int id : h_indices) output << symbol_table.getTypeSpecificID(id) + 1 << " "; - output << "];" << endl - << fieldname << ".coeff_str = '"; + output << "];" << endl << fieldname << ".coeff_str = '"; coeff->writeJsonOutput(output, {}, {}, true); output << "';" << endl; if (growth_component) { - output << fieldname << ".growth_neutrality_param_index = " << symbol_table.getTypeSpecificID(growth_neutrality_param) + 1 << ";" << endl + output << fieldname << ".growth_neutrality_param_index = " + << symbol_table.getTypeSpecificID(growth_neutrality_param) + 1 << ";" << endl << fieldname << ".growth_str = '"; original_growth_component->writeJsonOutput(output, {}, {}, true); output << "';" << endl; @@ -1645,10 +1712,9 @@ PacModelTable::writeOutput(ostream &output) const } void -PacModelTable::writeJsonOutput(ostream &output) const +PacModelTable::writeJsonOutput(ostream& output) const { - for (bool printed_something{false}; - const auto &name : names) + for (bool printed_something {false}; const auto& name : names) { /* The calling method has already added a comma, so don’t output one for the first statement */ @@ -1667,21 +1733,20 @@ PacModelTable::writeJsonOutput(ostream &output) const output << "}" << endl; } - for (auto &[name, val] : target_info) + for (auto& [name, val] : target_info) { output << R"(, {"statementName": "pac_target_info", "model_name": ")" << name << R"(", "target": ")"; get<0>(val)->writeJsonOutput(output, {}, {}, true); - output << R"(", "auxname_target_nonstationary": ")" << get<1>(val) - << R"(", "components": [)"; - for (auto &[component, growth_component, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth_component, growth_component_info] : get<2>(val)) + output << R"(", "auxname_target_nonstationary": ")" << get<1>(val) << R"(", "components": [)"; + for (auto& [component, growth_component, auxname, kind, coeff, growth_neutrality_param, + h_indices, original_growth_component, growth_component_info] : get<2>(val)) { if (component != get<0>(get<2>(val).front())) output << ", "; output << R"({"component": ")"; component->writeJsonOutput(output, {}, {}, true); - output << R"(", "auxname": ")" << auxname - << R"(", "kind": ")" << kindToString(kind); + output << R"(", "auxname": ")" << auxname << R"(", "kind": ")" << kindToString(kind); if (growth_component) { output << R"(", "growth_str": ")"; @@ -1694,7 +1759,7 @@ PacModelTable::writeJsonOutput(ostream &output) const } int -PacModelTable::pacEquationMaxLag(const string &name_arg) const +PacModelTable::pacEquationMaxLag(const string& name_arg) const { return get<2>(equation_info.at(name_arg)).size(); } @@ -1718,53 +1783,52 @@ PacModelTable::kindToString(PacTargetKind kind) } void -PacModelTable::setTargetExpr(const string &name_arg, expr_t target) +PacModelTable::setTargetExpr(const string& name_arg, expr_t target) { get<0>(target_info[name_arg]) = target; } void -PacModelTable::setTargetAuxnameNonstationary(const string &name_arg, string auxname) +PacModelTable::setTargetAuxnameNonstationary(const string& name_arg, string auxname) { get<1>(target_info[name_arg]) = move(auxname); } void -PacModelTable::addTargetComponent(const string &name_arg, target_component_t component) +PacModelTable::addTargetComponent(const string& name_arg, target_component_t component) { get<7>(component) = get<1>(component); // original_growth = growth get<2>(target_info[name_arg]).emplace_back(move(component)); } void -PacModelTable::writeTargetCoefficientsFile(const string &basename) const +PacModelTable::writeTargetCoefficientsFile(const string& basename) const { if (target_info.empty()) return; filesystem::path filename {DataTree::packageDir(basename) / "pac_target_coefficients.m"}; - ofstream output{filename, ios::out | ios::binary}; + ofstream output {filename, ios::out | ios::binary}; if (!output.is_open()) { cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl; exit(EXIT_FAILURE); } output << "function coeffs = pac_target_coefficients(model_name, params)" << endl; - for (auto &[model_name, val] : target_info) + for (auto& [model_name, val] : target_info) { output << " if strcmp(model_name, '" << model_name << "')" << endl << " coeffs = NaN(" << get<2>(val).size() << ",1);" << endl; - for (int i{1}; - auto &[component, growth_component, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth_component, growth_component_info] : get<2>(val)) + for (int i {1}; + auto& [component, growth_component, auxname, kind, coeff, growth_neutrality_param, + h_indices, original_growth_component, growth_component_info] : get<2>(val)) { output << " coeffs(" << i++ << ") = "; coeff->writeOutput(output, ExprNodeOutputType::matlabDynamicModel); output << ";" << endl; } - output << " return" << endl - << " end" << endl; + output << " return" << endl << " end" << endl; } - output << " error([ 'Unknown PAC model: ' model_name ])" << endl - << "end" << endl; + output << " error([ 'Unknown PAC model: ' model_name ])" << endl << "end" << endl; output.close(); } diff --git a/src/SubModel.hh b/src/SubModel.hh index 583720c7..7285dc18 100644 --- a/src/SubModel.hh +++ b/src/SubModel.hh @@ -20,16 +20,16 @@ #ifndef _SUBMODEL_HH #define _SUBMODEL_HH -#include -#include -#include #include +#include #include +#include +#include #include "ExprNode.hh" -#include "SymbolTable.hh" -#include "SymbolList.hh" #include "Statement.hh" +#include "SymbolList.hh" +#include "SymbolTable.hh" // DynamicModel.hh can’t be included here, otherwise it would be a circular dependency class DynamicModel; @@ -43,10 +43,11 @@ using namespace std; class TrendComponentModelTable { private: - SymbolTable &symbol_table; + SymbolTable& symbol_table; set names; map> eqtags, target_eqtags; - map> eqnums, target_eqnums, nontarget_eqnums, max_lags, lhs, target_lhs, nontarget_lhs; + map> eqnums, target_eqnums, nontarget_eqnums, max_lags, lhs, target_lhs, + nontarget_lhs; map>> orig_diff_var; map>>> rhs; map> diff; @@ -57,35 +58,34 @@ private: in the structural VAR context. */ map, expr_t>> A0, A0star; // name -> (eqn, col) -> expr_t public: - explicit TrendComponentModelTable(SymbolTable &symbol_table_arg); + explicit TrendComponentModelTable(SymbolTable& symbol_table_arg); //! Add a trend component model void addTrendComponentModel(string name_arg, vector eqtags_arg, vector target_eqtags_arg); - inline bool isExistingTrendComponentModelName(const string &name_arg) const; + inline bool isExistingTrendComponentModelName(const string& name_arg) const; inline bool empty() const; - const map> &getEqTags() const; - const vector &getEqTags(const string &name_arg) const; - const map> &getTargetEqTags() const; - const map> &getEqNums() const; - const map> &getTargetEqNums() const; - const vector &getTargetEqNums(const string &name_arg) const; - const vector &getEqNums(const string &name_arg) const; - const vector &getMaxLags(const string &name_arg) const; - int getMaxLag(const string &name_arg) const; - const vector &getLhs(const string &name_arg) const; - const vector &getLhsExprT(const string &name_arg) const; - const vector &getDiff(const string &name_arg) const; - const map> &getNonTargetEqNums() const; - const vector &getNonTargetEqNums(const string &name_arg) const; - const vector &getNonTargetLhs(const string &name_arg) const; - const vector &getTargetLhs(const string &name_arg) const; + const map>& getEqTags() const; + const vector& getEqTags(const string& name_arg) const; + const map>& getTargetEqTags() const; + const map>& getEqNums() const; + const map>& getTargetEqNums() const; + const vector& getTargetEqNums(const string& name_arg) const; + const vector& getEqNums(const string& name_arg) const; + const vector& getMaxLags(const string& name_arg) const; + int getMaxLag(const string& name_arg) const; + const vector& getLhs(const string& name_arg) const; + const vector& getLhsExprT(const string& name_arg) const; + const vector& getDiff(const string& name_arg) const; + const map>& getNonTargetEqNums() const; + const vector& getNonTargetEqNums(const string& name_arg) const; + const vector& getNonTargetLhs(const string& name_arg) const; + const vector& getTargetLhs(const string& name_arg) const; void setVals(map> eqnums_arg, map> target_eqnums_arg, - map> lhs_arg, - map> lhs_expr_t_arg); + map> lhs_arg, map> lhs_expr_t_arg); void setRhs(map>>> rhs_arg); void setMaxLags(map> max_lags_arg); void setDiff(map> diff_arg); @@ -96,18 +96,18 @@ public: map, expr_t>> A0star_arg); //! Write output of this class - void writeOutput(const string &basename, ostream &output) const; + void writeOutput(const string& basename, ostream& output) const; //! Write JSON Output - void writeJsonOutput(ostream &output) const; + void writeJsonOutput(ostream& output) const; private: - void checkModelName(const string &name_arg) const; + void checkModelName(const string& name_arg) const; void setNonTargetEqnums(); }; inline bool -TrendComponentModelTable::isExistingTrendComponentModelName(const string &name_arg) const +TrendComponentModelTable::isExistingTrendComponentModelName(const string& name_arg) const { return names.contains(name_arg); } @@ -121,43 +121,45 @@ TrendComponentModelTable::empty() const class VarModelTable { private: - SymbolTable &symbol_table; + SymbolTable& symbol_table; set names; map structural; // Whether VARs are structural or reduced-form map> eqtags; map> eqnums, max_lags, lhs, lhs_orig_symb_ids; map>> orig_diff_var; - map>>> rhs; // name -> for each equation: set of pairs (var, lag) + map>>> + rhs; // name -> for each equation: set of pairs (var, lag) map> diff; map> lhs_expr_t; - map, expr_t>> AR; // name -> (eqn, lag, lhs_symb_id) -> param_expr_t + map, expr_t>> + AR; // name -> (eqn, lag, lhs_symb_id) -> param_expr_t /* The A0 matrix is mainly for structural VARs. For reduced-form VARs, it will be equal to the identity matrix. Also note that A0 in the structural VAR context is not the same thing as in the trend-component model context. */ map, expr_t>> A0; // name -> (eqn, lhs_symb_id) -> param_expr_t - map> constants; // name -> eqn -> constant + map> constants; // name -> eqn -> constant public: - explicit VarModelTable(SymbolTable &symbol_table_arg); + explicit VarModelTable(SymbolTable& symbol_table_arg); //! Add a VAR model void addVarModel(string name, bool structural_arg, vector eqtags); - inline bool isExistingVarModelName(const string &name_arg) const; + inline bool isExistingVarModelName(const string& name_arg) const; inline bool empty() const; - const map &getStructural() const; - const map> &getEqTags() const; - const vector &getEqTags(const string &name_arg) const; - const map> &getEqNums() const; - const vector &getDiff(const string &name_arg) const; - const vector &getEqNums(const string &name_arg) const; - const vector &getMaxLags(const string &name_arg) const; - int getMaxLag(const string &name_arg) const; - const vector &getLhs(const string &name_arg) const; - const vector &getLhsOrigIds(const string &name_arg) const; - const vector>> &getRhs(const string &name_arg) const; - const vector &getLhsExprT(const string &name_arg) const; + const map& getStructural() const; + const map>& getEqTags() const; + const vector& getEqTags(const string& name_arg) const; + const map>& getEqNums() const; + const vector& getDiff(const string& name_arg) const; + const vector& getEqNums(const string& name_arg) const; + const vector& getMaxLags(const string& name_arg) const; + int getMaxLag(const string& name_arg) const; + const vector& getLhs(const string& name_arg) const; + const vector& getLhsOrigIds(const string& name_arg) const; + const vector>>& getRhs(const string& name_arg) const; + const vector& getLhsExprT(const string& name_arg) const; void setEqNums(map> eqnums_arg); void setLhs(map> lhs_arg); @@ -171,17 +173,17 @@ public: void setConstants(map> constants_arg); //! Write output of this class - void writeOutput(const string &basename, ostream &output) const; + void writeOutput(const string& basename, ostream& output) const; //! Write JSON Output - void writeJsonOutput(ostream &output) const; + void writeJsonOutput(ostream& output) const; private: - void checkModelName(const string &name_arg) const; + void checkModelName(const string& name_arg) const; }; inline bool -VarModelTable::isExistingVarModelName(const string &name_arg) const +VarModelTable::isExistingVarModelName(const string& name_arg) const { return names.contains(name_arg); } @@ -195,7 +197,7 @@ VarModelTable::empty() const class VarExpectationModelTable { private: - SymbolTable &symbol_table; + SymbolTable& symbol_table; set names; map expression; map aux_model_name; @@ -206,26 +208,31 @@ private: map> aux_param_symb_ids; // Decomposition of the expression map, double>>> vars_params_constants; + public: - explicit VarExpectationModelTable(SymbolTable &symbol_table_arg); + explicit VarExpectationModelTable(SymbolTable& symbol_table_arg); void addVarExpectationModel(string name_arg, expr_t expression_arg, string aux_model_name_arg, string horizon_arg, expr_t discount_arg, int time_shift_arg); - bool isExistingVarExpectationModelName(const string &name_arg) const; + bool isExistingVarExpectationModelName(const string& name_arg) const; bool empty() const; - void substituteUnaryOpsInExpression(const lag_equivalence_table_t &nodes, ExprNode::subst_table_t &subst_table, vector &neweqs); + void substituteUnaryOpsInExpression(const lag_equivalence_table_t& nodes, + ExprNode::subst_table_t& subst_table, + vector& neweqs); // Called by DynamicModel::substituteDiff() - void substituteDiffNodesInExpression(const lag_equivalence_table_t &diff_nodes, ExprNode::subst_table_t &diff_subst_table, vector &neweqs); - void transformPass(ExprNode::subst_table_t &diff_subst_table, - DynamicModel &dynamic_model, const VarModelTable &var_model_table, - const TrendComponentModelTable &trend_component_model_table); - void writeOutput(ostream &output) const; - void writeJsonOutput(ostream &output) const; + void substituteDiffNodesInExpression(const lag_equivalence_table_t& diff_nodes, + ExprNode::subst_table_t& diff_subst_table, + vector& neweqs); + void transformPass(ExprNode::subst_table_t& diff_subst_table, DynamicModel& dynamic_model, + const VarModelTable& var_model_table, + const TrendComponentModelTable& trend_component_model_table); + void writeOutput(ostream& output) const; + void writeJsonOutput(ostream& output) const; }; class PacModelTable { private: - SymbolTable &symbol_table; + SymbolTable& symbol_table; set names; map aux_model_name; map discount; @@ -280,10 +287,18 @@ private: public: /* Stores info about PAC equations pac_model_name → - (lhs, optim_share_index, ar_params_and_vars, ec_params_and_vars, non_optim_vars_params_and_constants, additive_vars_params_and_constants, optim_additive_vars_params_and_constants) + (lhs, optim_share_index, ar_params_and_vars, ec_params_and_vars, + non_optim_vars_params_and_constants, additive_vars_params_and_constants, + optim_additive_vars_params_and_constants) */ - using equation_info_t = map, optional, vector, optional, int>>, pair>>, vector, double>>, vector, double>>, vector, double>>>>; + using equation_info_t + = map, optional, vector, optional, int>>, + pair>>, + vector, double>>, + vector, double>>, + vector, double>>>>; + private: equation_info_t equation_info; @@ -291,44 +306,49 @@ public: /* (component variable/expr, growth, auxname, kind, coeff. in the linear combination, growth_param ID (unused if growth is nullptr), vector of h parameters, original_growth, growth_info) */ - using target_component_t = tuple, expr_t, growth_info_t>; + using target_component_t = tuple, + expr_t, growth_info_t>; private: // pac_model_name → (target variable/expr, auxname_target_nonstationary, target components) map>> target_info; - int pacEquationMaxLag(const string &name_arg) const; + int pacEquationMaxLag(const string& name_arg) const; // Return a text representation of a kind (but fails on “unspecified” kind value) static string kindToString(PacTargetKind kind); public: - explicit PacModelTable(SymbolTable &symbol_table_arg); - void addPacModel(string name_arg, string aux_model_name_arg, string discount_arg, expr_t growth_arg, string auxname_arg, PacTargetKind kind_arg); - bool isExistingPacModelName(const string &name_arg) const; + explicit PacModelTable(SymbolTable& symbol_table_arg); + void addPacModel(string name_arg, string aux_model_name_arg, string discount_arg, + expr_t growth_arg, string auxname_arg, PacTargetKind kind_arg); + bool isExistingPacModelName(const string& name_arg) const; bool empty() const; - void checkPass(ModFileStructure &mod_file_struct); + void checkPass(ModFileStructure& mod_file_struct); // Called by DynamicModel::substituteUnaryOps() - void substituteUnaryOpsInGrowth(const lag_equivalence_table_t &nodes, ExprNode::subst_table_t &subst_table, vector &neweqs); - void findDiffNodesInGrowth(lag_equivalence_table_t &diff_nodes) const; + void substituteUnaryOpsInGrowth(const lag_equivalence_table_t& nodes, + ExprNode::subst_table_t& subst_table, + vector& neweqs); + void findDiffNodesInGrowth(lag_equivalence_table_t& diff_nodes) const; // Called by DynamicModel::substituteDiff() - void substituteDiffNodesInGrowth(const lag_equivalence_table_t &diff_nodes, ExprNode::subst_table_t &diff_subst_table, vector &neweqs); + void substituteDiffNodesInGrowth(const lag_equivalence_table_t& diff_nodes, + ExprNode::subst_table_t& diff_subst_table, + vector& neweqs); // Must be called after substituteDiffNodesInGrowth() and substituteUnaryOpsInGrowth() - void transformPass(const lag_equivalence_table_t &unary_ops_nodes, - ExprNode::subst_table_t &unary_ops_subst_table, - const lag_equivalence_table_t &diff_nodes, - ExprNode::subst_table_t &diff_subst_table, - DynamicModel &dynamic_model, const VarModelTable &var_model_table, - const TrendComponentModelTable &trend_component_model_table); - void writeOutput(ostream &output) const; - void writeJsonOutput(ostream &output) const; - void setTargetExpr(const string &name_arg, expr_t target); - void setTargetAuxnameNonstationary(const string &name_arg, string auxname); + void transformPass(const lag_equivalence_table_t& unary_ops_nodes, + ExprNode::subst_table_t& unary_ops_subst_table, + const lag_equivalence_table_t& diff_nodes, + ExprNode::subst_table_t& diff_subst_table, DynamicModel& dynamic_model, + const VarModelTable& var_model_table, + const TrendComponentModelTable& trend_component_model_table); + void writeOutput(ostream& output) const; + void writeJsonOutput(ostream& output) const; + void setTargetExpr(const string& name_arg, expr_t target); + void setTargetAuxnameNonstationary(const string& name_arg, string auxname); /* Only the first four elements of the tuple are expected to be set by the caller. The other ones will be filled by this class. */ - void addTargetComponent(const string &name_arg, target_component_t component); - void writeTargetCoefficientsFile(const string &basename) const; + void addTargetComponent(const string& name_arg, target_component_t component); + void writeTargetCoefficientsFile(const string& basename) const; }; - #endif diff --git a/src/SymbolList.cc b/src/SymbolList.cc index 7362c8b1..f06c854c 100644 --- a/src/SymbolList.cc +++ b/src/SymbolList.cc @@ -21,14 +21,13 @@ #include "SymbolList.hh" -SymbolList::SymbolList(vector symbols_arg) : - symbols{move(symbols_arg)} +SymbolList::SymbolList(vector symbols_arg) : symbols {move(symbols_arg)} { } void -SymbolList::checkPass(WarningConsolidation &warnings, const vector &types, - const SymbolTable &symbol_table) const noexcept(false) +SymbolList::checkPass(WarningConsolidation& warnings, const vector& types, + const SymbolTable& symbol_table) const noexcept(false) { if (types.empty()) return; @@ -41,20 +40,21 @@ SymbolList::checkPass(WarningConsolidation &warnings, const vector & regex_str += "|AUX_ENDO_|LOG_"; break; } - regex re("^(" + regex_str +")"); - for (const auto &symbol : symbols) + regex re("^(" + regex_str + ")"); + for (const auto& symbol : symbols) { if (!symbol_table.exists(symbol)) { if (regex_search(symbol, m, re)) { - warnings << "WARNING: symbol_list variable " << symbol << " has not yet been declared. " - << "This is being ignored because the variable name corresponds to a possible " - << "auxiliary variable name." << endl; + warnings + << "WARNING: symbol_list variable " << symbol << " has not yet been declared. " + << "This is being ignored because the variable name corresponds to a possible " + << "auxiliary variable name." << endl; return; } else - throw SymbolListException{"Variable " + symbol + " was not declared."}; + throw SymbolListException {"Variable " + symbol + " was not declared."}; } if (none_of(types.begin(), types.end(), @@ -62,7 +62,7 @@ SymbolList::checkPass(WarningConsolidation &warnings, const vector & { string valid_types; for (auto type : types) - switch(type) + switch (type) { case SymbolType::endogenous: valid_types += "endogenous, "; @@ -104,18 +104,17 @@ SymbolList::checkPass(WarningConsolidation &warnings, const vector & valid_types += "excludedVariable, "; break; } - valid_types = valid_types.erase(valid_types.size()-2, 2); - throw SymbolListException{"Variable " + symbol + " is not one of {" + valid_types + "}"}; + valid_types = valid_types.erase(valid_types.size() - 2, 2); + throw SymbolListException {"Variable " + symbol + " is not one of {" + valid_types + "}"}; } } } void -SymbolList::writeOutput(const string &varname, ostream &output) const +SymbolList::writeOutput(const string& varname, ostream& output) const { output << varname << " = {"; - for (bool printed_something{false}; - const auto &name : symbols) + for (bool printed_something {false}; const auto& name : symbols) { if (exchange(printed_something, true)) output << ";"; @@ -125,11 +124,10 @@ SymbolList::writeOutput(const string &varname, ostream &output) const } void -SymbolList::writeJsonOutput(ostream &output) const +SymbolList::writeJsonOutput(ostream& output) const { output << R"("symbol_list": [)"; - for (bool printed_something{false}; - const auto &name : symbols) + for (bool printed_something {false}; const auto& name : symbols) { if (exchange(printed_something, true)) output << ","; @@ -145,14 +143,15 @@ SymbolList::getSymbols() const } void -SymbolList::removeDuplicates(const string &dynare_command, WarningConsolidation &warnings) +SymbolList::removeDuplicates(const string& dynare_command, WarningConsolidation& warnings) { vector unique_symbols; - for (const auto &it : symbols) + for (const auto& it : symbols) if (find(unique_symbols.begin(), unique_symbols.end(), it) == unique_symbols.end()) unique_symbols.push_back(it); else warnings << "WARNING: In " << dynare_command << ": " << it - << " found more than once in symbol list. Removing all but first occurrence." << endl; + << " found more than once in symbol list. Removing all but first occurrence." + << endl; symbols = unique_symbols; } diff --git a/src/SymbolList.hh b/src/SymbolList.hh index f8db55db..fec24a77 100644 --- a/src/SymbolList.hh +++ b/src/SymbolList.hh @@ -20,13 +20,13 @@ #ifndef _SYMBOL_LIST_HH #define _SYMBOL_LIST_HH +#include +#include #include #include -#include -#include -#include "WarningConsolidation.hh" #include "SymbolTable.hh" +#include "WarningConsolidation.hh" using namespace std; @@ -36,6 +36,7 @@ class SymbolList { private: vector symbols; + public: SymbolList() = default; // This constructor is deliberately not marked explicit, to allow implicit conversion @@ -46,16 +47,17 @@ public: const string message; }; //! Remove duplicate symbols - void removeDuplicates(const string &dynare_command, WarningConsolidation &warnings); + void removeDuplicates(const string& dynare_command, WarningConsolidation& warnings); //! Check symbols to ensure variables have been declared and are endogenous - void checkPass(WarningConsolidation &warnings, const vector &types, const SymbolTable &symbol_table) const noexcept(false); + void checkPass(WarningConsolidation& warnings, const vector& types, + const SymbolTable& symbol_table) const noexcept(false); //! Output content in Matlab format /*! Creates a string array for Matlab, stored in variable "varname" */ - void writeOutput(const string &varname, ostream &output) const; + void writeOutput(const string& varname, ostream& output) const; //! Output content in Matlab format without preceding varname of writeOutput - void write(ostream &output) const; + void write(ostream& output) const; //! Write JSON output - void writeJsonOutput(ostream &output) const; + void writeJsonOutput(ostream& output) const; //! Is Empty bool empty() const diff --git a/src/SymbolTable.cc b/src/SymbolTable.cc index 463532e6..43e22c88 100644 --- a/src/SymbolTable.cc +++ b/src/SymbolTable.cc @@ -18,9 +18,9 @@ */ #include -#include -#include #include +#include +#include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #include @@ -30,7 +30,8 @@ #include "SymbolTable.hh" int -SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_name, const vector> &partition_value) noexcept(false) +SymbolTable::addSymbol(const string& name, SymbolType type, const string& tex_name, + const vector>& partition_value) noexcept(false) { if (frozen) throw FrozenException(); @@ -38,9 +39,9 @@ SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_na if (exists(name)) { if (type_table[getID(name)] == type) - throw AlreadyDeclaredException{name, true}; + throw AlreadyDeclaredException {name, true}; else - throw AlreadyDeclaredException{name, false}; + throw AlreadyDeclaredException {name, false}; } string final_tex_name = tex_name; @@ -57,7 +58,7 @@ SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_na string final_long_name = name; bool non_long_name_partition_exists = false; - for (const auto &it : partition_value) + for (const auto& it : partition_value) if (it.first == "long_name") final_long_name = it.second; else @@ -73,7 +74,7 @@ SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_na if (non_long_name_partition_exists) { map pmv; - for (const auto &it : partition_value) + for (const auto& it : partition_value) pmv[it.first] = it.second; partition_value_map[id] = pmv; } @@ -81,7 +82,7 @@ SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_na } int -SymbolTable::addSymbol(const string &name, SymbolType type) noexcept(false) +SymbolTable::addSymbol(const string& name, SymbolType type) noexcept(false) { return addSymbol(name, type, "", {}); } @@ -154,26 +155,26 @@ SymbolTable::getID(SymbolType type, int tsid) const noexcept(false) { case SymbolType::endogenous: if (tsid < 0 || tsid >= static_cast(endo_ids.size())) - throw UnknownTypeSpecificIDException{tsid, type}; + throw UnknownTypeSpecificIDException {tsid, type}; else return endo_ids[tsid]; case SymbolType::exogenous: if (tsid < 0 || tsid >= static_cast(exo_ids.size())) - throw UnknownTypeSpecificIDException{tsid, type}; + throw UnknownTypeSpecificIDException {tsid, type}; else return exo_ids[tsid]; case SymbolType::exogenousDet: if (tsid < 0 || tsid >= static_cast(exo_det_ids.size())) - throw UnknownTypeSpecificIDException{tsid, type}; + throw UnknownTypeSpecificIDException {tsid, type}; else return exo_det_ids[tsid]; case SymbolType::parameter: if (tsid < 0 || tsid >= static_cast(param_ids.size())) - throw UnknownTypeSpecificIDException{tsid, type}; + throw UnknownTypeSpecificIDException {tsid, type}; else return param_ids[tsid]; default: - throw UnknownTypeSpecificIDException{tsid, type}; + throw UnknownTypeSpecificIDException {tsid, type}; } } @@ -181,15 +182,15 @@ map> SymbolTable::getPartitionsForType(SymbolType st) const noexcept(false) { map> partitions; - for (const auto &it : partition_value_map) + for (const auto& it : partition_value_map) if (getType(it.first) == st) - for (const auto &it1 : it.second) + for (const auto& it1 : it.second) partitions[it1.first][it.first] = it1.second; return partitions; } void -SymbolTable::writeOutput(ostream &output) const noexcept(false) +SymbolTable::writeOutput(ostream& output) const noexcept(false) { if (!frozen) throw NotYetFrozenException(); @@ -200,18 +201,19 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false) output << "M_.exo_names_tex = cell(" << exo_nbr() << ",1);" << endl; output << "M_.exo_names_long = cell(" << exo_nbr() << ",1);" << endl; for (int id = 0; id < exo_nbr(); id++) - output << "M_.exo_names(" << id+1 << ") = {'" << getName(exo_ids[id]) << "'};" << endl - << "M_.exo_names_tex(" << id+1 << ") = {'" << getTeXName(exo_ids[id]) << "'};" << endl - << "M_.exo_names_long(" << id+1 << ") = {'" << getLongName(exo_ids[id]) << "'};" << endl; - for (auto &partition : getPartitionsForType(SymbolType::exogenous)) + output << "M_.exo_names(" << id + 1 << ") = {'" << getName(exo_ids[id]) << "'};" << endl + << "M_.exo_names_tex(" << id + 1 << ") = {'" << getTeXName(exo_ids[id]) << "'};" + << endl + << "M_.exo_names_long(" << id + 1 << ") = {'" << getLongName(exo_ids[id]) << "'};" + << endl; + for (auto& partition : getPartitionsForType(SymbolType::exogenous)) if (partition.first != "long_name") { output << "M_.exo_partitions." << partition.first << " = { "; for (int id = 0; id < exo_nbr(); id++) { output << "'"; - if (auto it1 = partition.second.find(exo_ids[id]); - it1 != partition.second.end()) + if (auto it1 = partition.second.find(exo_ids[id]); it1 != partition.second.end()) output << it1->second; output << "' "; } @@ -235,11 +237,14 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false) output << "M_.exo_det_names_tex = cell(" << exo_det_nbr() << ",1);" << endl; output << "M_.exo_det_names_long = cell(" << exo_det_nbr() << ",1);" << endl; for (int id = 0; id < exo_det_nbr(); id++) - output << "M_.exo_det_names(" << id+1 << ") = {'" << getName(exo_det_ids[id]) << "'};" << endl - << "M_.exo_det_names_tex(" << id+1 << ") = {'" << getTeXName(exo_det_ids[id]) << "'};" << endl - << "M_.exo_det_names_long(" << id+1 << ") = {'" << getLongName(exo_det_ids[id]) << "'};" << endl; + output << "M_.exo_det_names(" << id + 1 << ") = {'" << getName(exo_det_ids[id]) << "'};" + << endl + << "M_.exo_det_names_tex(" << id + 1 << ") = {'" << getTeXName(exo_det_ids[id]) + << "'};" << endl + << "M_.exo_det_names_long(" << id + 1 << ") = {'" << getLongName(exo_det_ids[id]) + << "'};" << endl; output << "M_.exo_det_partitions = struct();" << endl; - for (auto &partition : getPartitionsForType(SymbolType::exogenousDet)) + for (auto& partition : getPartitionsForType(SymbolType::exogenousDet)) if (partition.first != "long_name") { output << "M_.exo_det_partitions." << partition.first << " = { "; @@ -261,19 +266,20 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false) output << "M_.endo_names_tex = cell(" << endo_nbr() << ",1);" << endl; output << "M_.endo_names_long = cell(" << endo_nbr() << ",1);" << endl; for (int id = 0; id < endo_nbr(); id++) - output << "M_.endo_names(" << id+1 << ") = {'" << getName(endo_ids[id]) << "'};" << endl - << "M_.endo_names_tex(" << id+1 << ") = {'" << getTeXName(endo_ids[id]) << "'};" << endl - << "M_.endo_names_long(" << id+1 << ") = {'" << getLongName(endo_ids[id]) << "'};" << endl; + output << "M_.endo_names(" << id + 1 << ") = {'" << getName(endo_ids[id]) << "'};" << endl + << "M_.endo_names_tex(" << id + 1 << ") = {'" << getTeXName(endo_ids[id]) << "'};" + << endl + << "M_.endo_names_long(" << id + 1 << ") = {'" << getLongName(endo_ids[id]) << "'};" + << endl; output << "M_.endo_partitions = struct();" << endl; - for (auto &partition : getPartitionsForType(SymbolType::endogenous)) + for (auto& partition : getPartitionsForType(SymbolType::endogenous)) if (partition.first != "long_name") { output << "M_.endo_partitions." << partition.first << " = { "; for (int id = 0; id < endo_nbr(); id++) { output << "'"; - if (auto it1 = partition.second.find(endo_ids[id]); - it1 != partition.second.end()) + if (auto it1 = partition.second.find(endo_ids[id]); it1 != partition.second.end()) output << it1->second; output << "' "; } @@ -288,22 +294,24 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false) output << "M_.param_names_long = cell(" << param_nbr() << ",1);" << endl; for (int id = 0; id < param_nbr(); id++) { - output << "M_.param_names(" << id+1 << ") = {'" << getName(param_ids[id]) << "'};" << endl - << "M_.param_names_tex(" << id+1 << ") = {'" << getTeXName(param_ids[id]) << "'};" << endl - << "M_.param_names_long(" << id+1 << ") = {'" << getLongName(param_ids[id]) << "'};" << endl; + output << "M_.param_names(" << id + 1 << ") = {'" << getName(param_ids[id]) << "'};" + << endl + << "M_.param_names_tex(" << id + 1 << ") = {'" << getTeXName(param_ids[id]) + << "'};" << endl + << "M_.param_names_long(" << id + 1 << ") = {'" << getLongName(param_ids[id]) + << "'};" << endl; if (getName(param_ids[id]) == "dsge_prior_weight") output << "options_.dsge_var = 1;" << endl; } output << "M_.param_partitions = struct();" << endl; - for (auto &partition : getPartitionsForType(SymbolType::parameter)) + for (auto& partition : getPartitionsForType(SymbolType::parameter)) if (partition.first != "long_name") { output << "M_.param_partitions." << partition.first << " = { "; for (int id = 0; id < param_nbr(); id++) { output << "'"; - if (auto it1 = partition.second.find(param_ids[id]); - it1 != partition.second.end()) + if (auto it1 = partition.second.find(param_ids[id]); it1 != partition.second.end()) output << it1->second; output << "' "; } @@ -329,8 +337,10 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false) else for (int i = 0; i < static_cast(aux_vars.size()); i++) { - output << "M_.aux_vars(" << i+1 << ").endo_index = " << getTypeSpecificID(aux_vars[i].symb_id)+1 << ";" << endl - << "M_.aux_vars(" << i+1 << ").type = " << aux_vars[i].get_type_id() << ";" << endl; + output << "M_.aux_vars(" << i + 1 + << ").endo_index = " << getTypeSpecificID(aux_vars[i].symb_id) + 1 << ";" << endl + << "M_.aux_vars(" << i + 1 << ").type = " << aux_vars[i].get_type_id() << ";" + << endl; switch (aux_vars[i].type) { case AuxVarType::endoLead: @@ -345,26 +355,34 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false) case AuxVarType::diffLag: case AuxVarType::diffLead: case AuxVarType::diffForward: - output << "M_.aux_vars(" << i+1 << ").orig_index = " << getTypeSpecificID(aux_vars[i].orig_symb_id.value())+1 << ";" << endl - << "M_.aux_vars(" << i+1 << ").orig_lead_lag = " << aux_vars[i].orig_lead_lag.value() << ";" << endl; + output << "M_.aux_vars(" << i + 1 + << ").orig_index = " << getTypeSpecificID(aux_vars[i].orig_symb_id.value()) + 1 + << ";" << endl + << "M_.aux_vars(" << i + 1 + << ").orig_lead_lag = " << aux_vars[i].orig_lead_lag.value() << ";" << endl; break; case AuxVarType::unaryOp: - output << "M_.aux_vars(" << i+1 << ").unary_op = '" << aux_vars[i].unary_op << "';" << endl; + output << "M_.aux_vars(" << i + 1 << ").unary_op = '" << aux_vars[i].unary_op << "';" + << endl; [[fallthrough]]; case AuxVarType::diff: if (aux_vars[i].orig_symb_id) - output << "M_.aux_vars(" << i+1 << ").orig_index = " << getTypeSpecificID(*aux_vars[i].orig_symb_id)+1 << ";" << endl - << "M_.aux_vars(" << i+1 << ").orig_lead_lag = " << aux_vars[i].orig_lead_lag.value() << ";" << endl; + output << "M_.aux_vars(" << i + 1 + << ").orig_index = " << getTypeSpecificID(*aux_vars[i].orig_symb_id) + 1 << ";" + << endl + << "M_.aux_vars(" << i + 1 + << ").orig_lead_lag = " << aux_vars[i].orig_lead_lag.value() << ";" << endl; break; case AuxVarType::multiplier: - output << "M_.aux_vars(" << i+1 << ").eq_nbr = " << aux_vars[i].equation_number_for_multiplier + 1 << ";" << endl; + output << "M_.aux_vars(" << i + 1 + << ").eq_nbr = " << aux_vars[i].equation_number_for_multiplier + 1 << ";" + << endl; break; } - if (expr_t orig_expr = aux_vars[i].expr_node; - orig_expr) + if (expr_t orig_expr = aux_vars[i].expr_node; orig_expr) { - output << "M_.aux_vars(" << i+1 << ").orig_expr = '"; + output << "M_.aux_vars(" << i + 1 << ").orig_expr = '"; orig_expr->writeJsonOutput(output, {}, {}); output << "';" << endl; } @@ -374,73 +392,77 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false) { output << "M_.predetermined_variables = [ "; for (int predetermined_variable : predetermined_variables) - output << getTypeSpecificID(predetermined_variable)+1 << " "; + output << getTypeSpecificID(predetermined_variable) + 1 << " "; output << "];" << endl; } if (observedVariablesNbr() > 0) { output << "options_.varobs = cell(" << observedVariablesNbr() << ", 1);" << endl; - for (int ic{1}; - int it : varobs) + for (int ic {1}; int it : varobs) output << "options_.varobs(" << ic++ << ") = {'" << getName(it) << "'};" << endl; output << "options_.varobs_id = [ "; for (int varob : varobs) - output << getTypeSpecificID(varob)+1 << " "; - output << " ];" << endl; + output << getTypeSpecificID(varob) + 1 << " "; + output << " ];" << endl; } if (observedExogenousVariablesNbr() > 0) { output << "options_.varexobs = cell(1);" << endl; - for (int ic{1}; - int it : varexobs) + for (int ic {1}; int it : varexobs) output << "options_.varexobs(" << ic++ << ") = {'" << getName(it) << "'};" << endl; output << "options_.varexobs_id = [ "; for (int varexob : varexobs) - output << getTypeSpecificID(varexob)+1 << " "; - output << " ];" << endl; + output << getTypeSpecificID(varexob) + 1 << " "; + output << " ];" << endl; } } int SymbolTable::addLeadAuxiliaryVarInternal(bool endo, int index, expr_t expr_arg) noexcept(false) { - string varname{(endo ? "AUX_ENDO_LEAD_" : "AUX_EXO_LEAD_") + to_string(index)}; + string varname {(endo ? "AUX_ENDO_LEAD_" : "AUX_EXO_LEAD_") + to_string(index)}; int symb_id; try { symb_id = addSymbol(varname, SymbolType::endogenous); } - catch (AlreadyDeclaredException &e) + catch (AlreadyDeclaredException& e) { - cerr << "ERROR: you should rename your variable called " << varname << ", this name is internally used by Dynare" << endl; + cerr << "ERROR: you should rename your variable called " << varname + << ", this name is internally used by Dynare" << endl; exit(EXIT_FAILURE); } - aux_vars.emplace_back(symb_id, (endo ? AuxVarType::endoLead : AuxVarType::exoLead), 0, 0, 0, 0, expr_arg, ""); + aux_vars.emplace_back(symb_id, (endo ? AuxVarType::endoLead : AuxVarType::exoLead), 0, 0, 0, 0, + expr_arg, ""); return symb_id; } int -SymbolTable::addLagAuxiliaryVarInternal(bool endo, int orig_symb_id, int orig_lead_lag, expr_t expr_arg) noexcept(false) +SymbolTable::addLagAuxiliaryVarInternal(bool endo, int orig_symb_id, int orig_lead_lag, + expr_t expr_arg) noexcept(false) { - string varname{(endo ? "AUX_ENDO_LAG_" : "AUX_EXO_LAG_") + to_string(orig_symb_id) + "_" + to_string(-orig_lead_lag)}; + string varname {(endo ? "AUX_ENDO_LAG_" : "AUX_EXO_LAG_") + to_string(orig_symb_id) + "_" + + to_string(-orig_lead_lag)}; int symb_id; try { symb_id = addSymbol(varname, SymbolType::endogenous); } - catch (AlreadyDeclaredException &e) + catch (AlreadyDeclaredException& e) { - cerr << "ERROR: you should rename your variable called " << varname << ", this name is internally used by Dynare" << endl; + cerr << "ERROR: you should rename your variable called " << varname + << ", this name is internally used by Dynare" << endl; exit(EXIT_FAILURE); } - aux_vars.emplace_back(symb_id, (endo ? AuxVarType::endoLag : AuxVarType::exoLag), orig_symb_id, orig_lead_lag, 0, 0, expr_arg, ""); + aux_vars.emplace_back(symb_id, (endo ? AuxVarType::endoLag : AuxVarType::exoLag), orig_symb_id, + orig_lead_lag, 0, 0, expr_arg, ""); return symb_id; } @@ -452,7 +474,8 @@ SymbolTable::addEndoLeadAuxiliaryVar(int index, expr_t expr_arg) noexcept(false) } int -SymbolTable::addEndoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) noexcept(false) +SymbolTable::addEndoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, + expr_t expr_arg) noexcept(false) { return addLagAuxiliaryVarInternal(true, orig_symb_id, orig_lead_lag, expr_arg); } @@ -464,24 +487,27 @@ SymbolTable::addExoLeadAuxiliaryVar(int index, expr_t expr_arg) noexcept(false) } int -SymbolTable::addExoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) noexcept(false) +SymbolTable::addExoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, + expr_t expr_arg) noexcept(false) { return addLagAuxiliaryVarInternal(false, orig_symb_id, orig_lead_lag, expr_arg); } int -SymbolTable::addExpectationAuxiliaryVar(int information_set, int index, expr_t expr_arg) noexcept(false) +SymbolTable::addExpectationAuxiliaryVar(int information_set, int index, + expr_t expr_arg) noexcept(false) { - string varname{"AUX_EXPECT_"s + (information_set < 0 ? "LAG" : "LEAD") + "_" - + to_string(abs(information_set)) + "_" + to_string(index)}; + string varname {"AUX_EXPECT_"s + (information_set < 0 ? "LAG" : "LEAD") + "_" + + to_string(abs(information_set)) + "_" + to_string(index)}; int symb_id; try { symb_id = addSymbol(varname, SymbolType::endogenous); } - catch (AlreadyDeclaredException &e) + catch (AlreadyDeclaredException& e) { - cerr << "ERROR: you should rename your variable called " << varname << ", this name is internally used by Dynare" << endl; + cerr << "ERROR: you should rename your variable called " << varname + << ", this name is internally used by Dynare" << endl; exit(EXIT_FAILURE); } @@ -491,7 +517,8 @@ SymbolTable::addExpectationAuxiliaryVar(int information_set, int index, expr_t e } int -SymbolTable::addLogTransformAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) noexcept(false) +SymbolTable::addLogTransformAuxiliaryVar(int orig_symb_id, int orig_lead_lag, + expr_t expr_arg) noexcept(false) { string varname = "LOG_" + getName(orig_symb_id); int symb_id; @@ -499,29 +526,34 @@ SymbolTable::addLogTransformAuxiliaryVar(int orig_symb_id, int orig_lead_lag, ex { symb_id = addSymbol(varname, SymbolType::endogenous); } - catch (AlreadyDeclaredException &e) + catch (AlreadyDeclaredException& e) { - cerr << "ERROR: you should rename your variable called " << varname << ", it conflicts with the auxiliary variable created for representing the log of " << getName(orig_symb_id) << endl; + cerr << "ERROR: you should rename your variable called " << varname + << ", it conflicts with the auxiliary variable created for representing the log of " + << getName(orig_symb_id) << endl; exit(EXIT_FAILURE); } - aux_vars.emplace_back(symb_id, AuxVarType::logTransform, orig_symb_id, orig_lead_lag, 0, 0, expr_arg, ""); + aux_vars.emplace_back(symb_id, AuxVarType::logTransform, orig_symb_id, orig_lead_lag, 0, 0, + expr_arg, ""); return symb_id; } int -SymbolTable::addDiffLagAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id, int orig_lag) noexcept(false) +SymbolTable::addDiffLagAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id, + int orig_lag) noexcept(false) { - string varname{"AUX_DIFF_LAG_" + to_string(index)}; + string varname {"AUX_DIFF_LAG_" + to_string(index)}; int symb_id; try { symb_id = addSymbol(varname, SymbolType::endogenous); } - catch (AlreadyDeclaredException &e) + catch (AlreadyDeclaredException& e) { - cerr << "ERROR: you should rename your variable called " << varname << ", this name is internally used by Dynare" << endl; + cerr << "ERROR: you should rename your variable called " << varname + << ", this name is internally used by Dynare" << endl; exit(EXIT_FAILURE); } @@ -531,17 +563,19 @@ SymbolTable::addDiffLagAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id } int -SymbolTable::addDiffLeadAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id, int orig_lead) noexcept(false) +SymbolTable::addDiffLeadAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id, + int orig_lead) noexcept(false) { - string varname{"AUX_DIFF_LEAD_" + to_string(index)}; + string varname {"AUX_DIFF_LEAD_" + to_string(index)}; int symb_id; try { symb_id = addSymbol(varname, SymbolType::endogenous); } - catch (AlreadyDeclaredException &e) + catch (AlreadyDeclaredException& e) { - cerr << "ERROR: you should rename your variable called " << varname << ", this name is internally used by Dynare" << endl; + cerr << "ERROR: you should rename your variable called " << varname + << ", this name is internally used by Dynare" << endl; exit(EXIT_FAILURE); } @@ -551,41 +585,48 @@ SymbolTable::addDiffLeadAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_i } int -SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg, optional orig_symb_id, optional orig_lag) noexcept(false) +SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg, optional orig_symb_id, + optional orig_lag) noexcept(false) { - string varname{"AUX_DIFF_" + to_string(index)}; + string varname {"AUX_DIFF_" + to_string(index)}; int symb_id; try { symb_id = addSymbol(varname, SymbolType::endogenous); } - catch (AlreadyDeclaredException &e) + catch (AlreadyDeclaredException& e) { - cerr << "ERROR: you should rename your variable called " << varname << ", this name is internally used by Dynare" << endl; + cerr << "ERROR: you should rename your variable called " << varname + << ", this name is internally used by Dynare" << endl; 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, move(orig_symb_id), move(orig_lag), 0, 0, + expr_arg, ""); return symb_id; } int -SymbolTable::addUnaryOpAuxiliaryVar(int index, expr_t expr_arg, string unary_op, optional orig_symb_id, optional orig_lag) noexcept(false) +SymbolTable::addUnaryOpAuxiliaryVar(int index, expr_t expr_arg, string unary_op, + optional orig_symb_id, + optional orig_lag) noexcept(false) { - string varname{"AUX_UOP_" + to_string(index)}; + string varname {"AUX_UOP_" + to_string(index)}; int symb_id; try { symb_id = addSymbol(varname, SymbolType::endogenous); } - catch (AlreadyDeclaredException &e) + catch (AlreadyDeclaredException& e) { - cerr << "ERROR: you should rename your variable called " << varname << ", this name is internally used by Dynare" << endl; + cerr << "ERROR: you should rename your variable called " << varname + << ", this name is internally used by Dynare" << endl; 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, move(orig_symb_id), move(orig_lag), 0, 0, + expr_arg, unary_op); return symb_id; } @@ -593,15 +634,16 @@ SymbolTable::addUnaryOpAuxiliaryVar(int index, expr_t expr_arg, string unary_op, int SymbolTable::addMultiplierAuxiliaryVar(int index) noexcept(false) { - string varname{"MULT_" + to_string(index+1)}; + string varname {"MULT_" + to_string(index + 1)}; int symb_id; try { symb_id = addSymbol(varname, SymbolType::endogenous); } - catch (AlreadyDeclaredException &e) + catch (AlreadyDeclaredException& e) { - cerr << "ERROR: you should rename your variable called " << varname << ", this name is internally used by Dynare" << endl; + cerr << "ERROR: you should rename your variable called " << varname + << ", this name is internally used by Dynare" << endl; exit(EXIT_FAILURE); } @@ -610,35 +652,41 @@ SymbolTable::addMultiplierAuxiliaryVar(int index) noexcept(false) } int -SymbolTable::addDiffForwardAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) noexcept(false) +SymbolTable::addDiffForwardAuxiliaryVar(int orig_symb_id, int orig_lead_lag, + expr_t expr_arg) noexcept(false) { - string varname{"AUX_DIFF_FWRD_" + to_string(orig_symb_id+1)}; + string varname {"AUX_DIFF_FWRD_" + to_string(orig_symb_id + 1)}; int symb_id; try { symb_id = addSymbol(varname, SymbolType::endogenous); } - catch (AlreadyDeclaredException &e) + catch (AlreadyDeclaredException& e) { - cerr << "ERROR: you should rename your variable called " << varname << ", this name is internally used by Dynare" << endl; + cerr << "ERROR: you should rename your variable called " << varname + << ", this name is internally used by Dynare" << endl; exit(EXIT_FAILURE); } - aux_vars.emplace_back(symb_id, AuxVarType::diffForward, orig_symb_id, orig_lead_lag, 0, 0, expr_arg, ""); + aux_vars.emplace_back(symb_id, AuxVarType::diffForward, orig_symb_id, orig_lead_lag, 0, 0, + expr_arg, ""); return symb_id; } int -SymbolTable::addPacExpectationAuxiliaryVar(const string &name, expr_t expr_arg) +SymbolTable::addPacExpectationAuxiliaryVar(const string& name, expr_t expr_arg) { int symb_id; try { symb_id = addSymbol(name, SymbolType::endogenous); } - catch (AlreadyDeclaredException &e) + catch (AlreadyDeclaredException& e) { - cerr << "ERROR: the variable/parameter '" << name << "' conflicts with a variable that will be generated for a 'pac_expectation' expression. Please rename it." << endl; + cerr << "ERROR: the variable/parameter '" << name + << "' conflicts with a variable that will be generated for a 'pac_expectation' " + "expression. Please rename it." + << endl; exit(EXIT_FAILURE); } @@ -647,16 +695,19 @@ SymbolTable::addPacExpectationAuxiliaryVar(const string &name, expr_t expr_arg) } int -SymbolTable::addPacTargetNonstationaryAuxiliaryVar(const string &name, expr_t expr_arg) +SymbolTable::addPacTargetNonstationaryAuxiliaryVar(const string& name, expr_t expr_arg) { int symb_id; try { symb_id = addSymbol(name, SymbolType::endogenous); } - catch (AlreadyDeclaredException &e) + catch (AlreadyDeclaredException& e) { - cerr << "ERROR: the variable/parameter '" << name << "' conflicts with a variable that will be generated for a 'pac_target_nonstationary' expression. Please rename it." << endl; + cerr << "ERROR: the variable/parameter '" << name + << "' conflicts with a variable that will be generated for a 'pac_target_nonstationary' " + "expression. Please rename it." + << endl; exit(EXIT_FAILURE); } @@ -667,45 +718,43 @@ SymbolTable::addPacTargetNonstationaryAuxiliaryVar(const string &name, expr_t ex int SymbolTable::searchAuxiliaryVars(int orig_symb_id, int orig_lead_lag) const noexcept(false) { - for (const auto &aux_var : aux_vars) + for (const auto& aux_var : aux_vars) if ((aux_var.type == AuxVarType::endoLag || aux_var.type == AuxVarType::exoLag) && aux_var.orig_symb_id == orig_symb_id && aux_var.orig_lead_lag == orig_lead_lag) return aux_var.symb_id; - throw SearchFailedException{orig_symb_id, orig_lead_lag}; + throw SearchFailedException {orig_symb_id, orig_lead_lag}; } int SymbolTable::getOrigSymbIdForAuxVar(int aux_var_symb_id_arg) const noexcept(false) { - for (const auto &aux_var : aux_vars) - if ((aux_var.type == AuxVarType::endoLag - || aux_var.type == AuxVarType::exoLag - || aux_var.type == AuxVarType::diff - || aux_var.type == AuxVarType::diffLag - || aux_var.type == AuxVarType::diffLead - || aux_var.type == AuxVarType::diffForward + for (const auto& aux_var : aux_vars) + if ((aux_var.type == AuxVarType::endoLag || aux_var.type == AuxVarType::exoLag + || aux_var.type == AuxVarType::diff || aux_var.type == AuxVarType::diffLag + || aux_var.type == AuxVarType::diffLead || aux_var.type == AuxVarType::diffForward || aux_var.type == AuxVarType::unaryOp) && aux_var.symb_id == aux_var_symb_id_arg) { if (optional r = aux_var.orig_symb_id; r) return *r; else - throw UnknownSymbolIDException{aux_var_symb_id_arg}; // Some diff and unaryOp auxvars have orig_symb_id unset + throw UnknownSymbolIDException { + aux_var_symb_id_arg}; // Some diff and unaryOp auxvars have orig_symb_id unset } - throw UnknownSymbolIDException{aux_var_symb_id_arg}; + throw UnknownSymbolIDException {aux_var_symb_id_arg}; } pair SymbolTable::unrollDiffLeadLagChain(int symb_id, int lag) const noexcept(false) { - for (const auto &aux_var : aux_vars) + for (const auto& aux_var : aux_vars) if (aux_var.symb_id == symb_id) if (aux_var.type == AuxVarType::diffLag || aux_var.type == AuxVarType::diffLead) { auto [orig_symb_id, orig_lag] = unrollDiffLeadLagChain(aux_var.orig_symb_id.value(), lag); - return { orig_symb_id, orig_lag + aux_var.orig_lead_lag.value() }; + return {orig_symb_id, orig_lag + aux_var.orig_lead_lag.value()}; } - return { symb_id, lag }; + return {symb_id, lag}; } void @@ -803,11 +852,11 @@ SymbolTable::getObservedExogenousVariableIndex(int symb_id) const return static_cast(it - varexobs.begin()); } -vector +vector SymbolTable::getTrendVarIds() const { - vector trendVars; - for (const auto &it : symbol_table) + vector trendVars; + for (const auto& it : symbol_table) if (getType(it.second) == SymbolType::trend || getType(it.second) == SymbolType::logTrend) trendVars.push_back(it.second); return trendVars; @@ -816,8 +865,8 @@ SymbolTable::getTrendVarIds() const set SymbolTable::getExogenous() const { - set exogs; - for (const auto &it : symbol_table) + set exogs; + for (const auto& it : symbol_table) if (getType(it.second) == SymbolType::exogenous) exogs.insert(it.second); return exogs; @@ -826,8 +875,8 @@ SymbolTable::getExogenous() const set SymbolTable::getObservedExogenous() const { - set oexogs; - for (const auto &it : symbol_table) + set oexogs; + for (const auto& it : symbol_table) if (getType(it.second) == SymbolType::exogenous) if (isObservedExogenousVariable(it.second)) oexogs.insert(it.second); @@ -837,8 +886,8 @@ SymbolTable::getObservedExogenous() const set SymbolTable::getEndogenous() const { - set endogs; - for (const auto &it : symbol_table) + set endogs; + for (const auto& it : symbol_table) if (getType(it.second) == SymbolType::endogenous) endogs.insert(it.second); return endogs; @@ -847,31 +896,32 @@ SymbolTable::getEndogenous() const bool SymbolTable::isAuxiliaryVariable(int symb_id) const { - return any_of(aux_vars.begin(), aux_vars.end(), [=](const auto &av) { return av.symb_id == symb_id; }); + return any_of(aux_vars.begin(), aux_vars.end(), + [=](const auto& av) { return av.symb_id == symb_id; }); } bool SymbolTable::isDiffAuxiliaryVariable(int symb_id) const { - return any_of(aux_vars.begin(), aux_vars.end(), - [=](const auto &av) { return av.symb_id == symb_id - && (av.type == AuxVarType::diff - || av.type == AuxVarType::diffLag - || av.type == AuxVarType::diffLead); }); + return any_of(aux_vars.begin(), aux_vars.end(), [=](const auto& av) { + return av.symb_id == symb_id + && (av.type == AuxVarType::diff || av.type == AuxVarType::diffLag + || av.type == AuxVarType::diffLead); + }); } set SymbolTable::getOrigEndogenous() const { - set origendogs; - for (const auto &it : symbol_table) + set origendogs; + for (const auto& it : symbol_table) if (getType(it.second) == SymbolType::endogenous && !isAuxiliaryVariable(it.second)) origendogs.insert(it.second); return origendogs; } void -SymbolTable::writeJsonOutput(ostream &output) const +SymbolTable::writeJsonOutput(ostream& output) const { output << R"("endogenous": )"; writeJsonVarVector(output, endo_ids); @@ -889,20 +939,20 @@ SymbolTable::writeJsonOutput(ostream &output) const { output << R"(, "varobs": [)"; for (size_t i = 0; i < varobs.size(); i++) - { - if (i != 0) - output << ", "; - output << R"(")" << getName(varobs[i]) << R"(")"; - } + { + if (i != 0) + output << ", "; + output << R"(")" << getName(varobs[i]) << R"(")"; + } output << "]" << endl; - + output << R"(, "varobs_ids": [)"; for (size_t i = 0; i < varobs.size(); i++) - { - if (i != 0) - output << ", "; - output << getTypeSpecificID(varobs[i])+1; - } + { + if (i != 0) + output << ", "; + output << getTypeSpecificID(varobs[i]) + 1; + } output << "]" << endl; } @@ -910,20 +960,20 @@ SymbolTable::writeJsonOutput(ostream &output) const { output << R"(, "varexobs": [)"; for (size_t i = 0; i < varexobs.size(); i++) - { - if (i != 0) - output << ", "; - output << R"(")" << getName(varexobs[i]) << R"(")"; - } + { + if (i != 0) + output << ", "; + output << R"(")" << getName(varexobs[i]) << R"(")"; + } output << "]" << endl; - + output << R"(, "varexobs_ids": [)"; for (size_t i = 0; i < varexobs.size(); i++) - { - if (i != 0) - output << ", "; - output << getTypeSpecificID(varexobs[i])+1; - } + { + if (i != 0) + output << ", "; + output << getTypeSpecificID(varexobs[i]) + 1; + } output << "]" << endl; } // Write the auxiliary variable table @@ -934,56 +984,56 @@ SymbolTable::writeJsonOutput(ostream &output) const { output << R"(, "aux_vars": [)" << endl; for (int i = 0; i < static_cast(aux_vars.size()); i++) - { - if (i != 0) - output << ", "; - output << R"({"endo_index": )" << getTypeSpecificID(aux_vars[i].symb_id)+1 - << R"(, "type": )" << aux_vars[i].get_type_id(); - switch (aux_vars[i].type) - { - case AuxVarType::endoLead: - case AuxVarType::exoLead: - case AuxVarType::expectation: - case AuxVarType::pacExpectation: + { + if (i != 0) + output << ", "; + output << R"({"endo_index": )" << getTypeSpecificID(aux_vars[i].symb_id) + 1 + << R"(, "type": )" << aux_vars[i].get_type_id(); + switch (aux_vars[i].type) + { + case AuxVarType::endoLead: + case AuxVarType::exoLead: + case AuxVarType::expectation: + case AuxVarType::pacExpectation: case AuxVarType::pacTargetNonstationary: - break; - case AuxVarType::endoLag: - case AuxVarType::exoLag: + break; + case AuxVarType::endoLag: + case AuxVarType::exoLag: case AuxVarType::logTransform: - case AuxVarType::diffLag: - case AuxVarType::diffLead: - case AuxVarType::diffForward: - output << R"(, "orig_index": )" << getTypeSpecificID(aux_vars[i].orig_symb_id.value())+1 - << R"(, "orig_lead_lag": )" << aux_vars[i].orig_lead_lag.value(); - break; - case AuxVarType::unaryOp: + case AuxVarType::diffLag: + case AuxVarType::diffLead: + case AuxVarType::diffForward: + output << R"(, "orig_index": )" + << getTypeSpecificID(aux_vars[i].orig_symb_id.value()) + 1 + << R"(, "orig_lead_lag": )" << aux_vars[i].orig_lead_lag.value(); + break; + case AuxVarType::unaryOp: output << R"(, "unary_op": ")" << aux_vars[i].unary_op << R"(")"; [[fallthrough]]; case AuxVarType::diff: - if (aux_vars[i].orig_symb_id) - output << R"(, "orig_index": )" << getTypeSpecificID(*aux_vars[i].orig_symb_id)+1 - << R"(, "orig_lead_lag": )" << aux_vars[i].orig_lead_lag.value(); - break; - case AuxVarType::multiplier: - output << R"(, "eq_nbr": )" << aux_vars[i].equation_number_for_multiplier + 1; - break; - } + if (aux_vars[i].orig_symb_id) + output << R"(, "orig_index": )" << getTypeSpecificID(*aux_vars[i].orig_symb_id) + 1 + << R"(, "orig_lead_lag": )" << aux_vars[i].orig_lead_lag.value(); + break; + case AuxVarType::multiplier: + output << R"(, "eq_nbr": )" << aux_vars[i].equation_number_for_multiplier + 1; + break; + } - if (expr_t orig_expr = aux_vars[i].expr_node; - orig_expr) - { - output << R"(, "orig_expr": ")"; - orig_expr->writeJsonOutput(output, {}, {}); - output << R"(")"; - } - output << '}' << endl; - } + if (expr_t orig_expr = aux_vars[i].expr_node; orig_expr) + { + output << R"(, "orig_expr": ")"; + orig_expr->writeJsonOutput(output, {}, {}); + output << R"(")"; + } + output << '}' << endl; + } output << "]" << endl; } } void -SymbolTable::writeJsonVarVector(ostream &output, const vector &varvec) const +SymbolTable::writeJsonVarVector(ostream& output, const vector& varvec) const { output << "["; for (size_t i = 0; i < varvec.size(); i++) @@ -992,9 +1042,10 @@ SymbolTable::writeJsonVarVector(ostream &output, const vector &varvec) cons output << ", "; output << "{" << R"("name":")" << getName(varvec[i]) << R"(", )" - << R"("texName":")" << boost::replace_all_copy(getTeXName(varvec[i]), R"(\)", R"(\\)") << R"(", )" - << R"("longName":")" << boost::replace_all_copy(getLongName(varvec[i]), R"(\)", R"(\\)") << R"("})" - << endl; + << R"("texName":")" << boost::replace_all_copy(getTeXName(varvec[i]), R"(\)", R"(\\)") + << R"(", )" + << R"("longName":")" + << boost::replace_all_copy(getLongName(varvec[i]), R"(\)", R"(\\)") << R"("})" << endl; } output << "]" << endl; } @@ -1007,7 +1058,7 @@ SymbolTable::getUltimateOrigSymbID(int symb_id) const { symb_id = getOrigSymbIdForAuxVar(symb_id); } - catch (UnknownSymbolIDException &) + catch (UnknownSymbolIDException&) { break; } @@ -1017,13 +1068,13 @@ SymbolTable::getUltimateOrigSymbID(int symb_id) const optional SymbolTable::getEquationNumberForMultiplier(int symb_id) const { - for (const auto &aux_var : aux_vars) + for (const auto& aux_var : aux_vars) if (aux_var.symb_id == symb_id && aux_var.type == AuxVarType::multiplier) return aux_var.equation_number_for_multiplier; return nullopt; } -const set & +const set& SymbolTable::getVariablesWithLogTransform() const { return with_log_transform; @@ -1033,7 +1084,7 @@ set SymbolTable::getLagrangeMultipliers() const { set r; - for (const auto &aux_var : aux_vars) + for (const auto& aux_var : aux_vars) if (aux_var.type == AuxVarType::multiplier) r.insert(aux_var.symb_id); return r; diff --git a/src/SymbolTable.hh b/src/SymbolTable.hh index da9b234c..f7e005fe 100644 --- a/src/SymbolTable.hh +++ b/src/SymbolTable.hh @@ -21,53 +21,55 @@ #define _SYMBOLTABLE_HH #include +#include +#include +#include #include #include #include -#include -#include -#include #include "CommonEnums.hh" #include "ExprNode.hh" using namespace std; -using expr_t = class ExprNode *; +using expr_t = class ExprNode*; //! Types of auxiliary variables enum class AuxVarType - { - endoLead = 0, //!< Substitute for endo leads >= 2 - endoLag = 1, //!< Substitute for endo lags >= 2 - exoLead = 2, //!< Substitute for exo leads >= 1 - exoLag = 3, //!< Substitute for exo lags >= 1 - expectation = 4, //!< Substitute for Expectation Operator - diffForward = 5, /* Substitute for the differentiate of a forward variable, +{ + endoLead = 0, //!< Substitute for endo leads >= 2 + endoLag = 1, //!< Substitute for endo lags >= 2 + exoLead = 2, //!< Substitute for exo leads >= 1 + exoLag = 3, //!< Substitute for exo lags >= 1 + expectation = 4, //!< Substitute for Expectation Operator + diffForward = 5, /* Substitute for the differentiate of a forward variable, for the differentiate_forward_vars option. N.B.: nothing to do with the diff() operator! */ - multiplier = 6, //!< Multipliers for FOC of Ramsey Problem - logTransform = 7, //!< Log-transformation of a variable declared with “var(log)” - diff = 8, //!< Variable for Diff operator - diffLag = 9, //!< Variable for timing between Diff operators (lag) - unaryOp = 10, //!< Variable for allowing the undiff operator to work when diff was taken of unary op, eg diff(log(x)) - diffLead = 11, //!< Variable for timing between Diff operators (lead) - pacExpectation = 12, //!< Variable created for the substitution of the pac_expectation operator - pacTargetNonstationary = 13 //!< Variable created for the substitution of the pac_target_nonstationary operator - }; + multiplier = 6, //!< Multipliers for FOC of Ramsey Problem + logTransform = 7, //!< Log-transformation of a variable declared with “var(log)” + diff = 8, //!< Variable for Diff operator + diffLag = 9, //!< Variable for timing between Diff operators (lag) + unaryOp = 10, //!< Variable for allowing the undiff operator to work when diff was taken of unary + //!< op, eg diff(log(x)) + diffLead = 11, //!< Variable for timing between Diff operators (lead) + pacExpectation = 12, //!< Variable created for the substitution of the pac_expectation operator + pacTargetNonstationary + = 13 //!< Variable created for the substitution of the pac_target_nonstationary operator +}; //! Information on some auxiliary variables struct AuxVarInfo { - const int symb_id; // Symbol ID of the auxiliary variable - const AuxVarType type; // Its type - const optional orig_symb_id; /* Symbol ID of the (only) endo that appears on the RHS of - the definition of this auxvar. - Used by endoLag, exoLag, diffForward, logTransform, diff, - diffLag, diffLead and unaryOp. - For diff and unaryOp, if the argument expression is more complex - than than a simple variable, this value is unset - (hence the need for std::optional). */ + const int symb_id; // Symbol ID of the auxiliary variable + const AuxVarType type; // Its type + const optional orig_symb_id; /* Symbol ID of the (only) endo that appears on the RHS of + the definition of this auxvar. + Used by endoLag, exoLag, diffForward, logTransform, diff, + diffLag, diffLead and unaryOp. + For diff and unaryOp, if the argument expression is more + complex than than a simple variable, this value is unset + (hence the need for std::optional). */ const optional orig_lead_lag; /* Lead/lag of the (only) endo as it appears on the RHS of the definition of this auxvar. Only set if orig_symb_id is set (in particular, for diff and unaryOp, unset @@ -79,8 +81,8 @@ struct AuxVarInfo associated with this aux var. Only used for avMultiplier. */ const int information_set; // Argument of expectation operator. Only used for avExpectation. - const expr_t expr_node; // Auxiliary variable definition - const string unary_op; // Used with AuxUnaryOp + const expr_t expr_node; // Auxiliary variable definition + const string unary_op; // Used with AuxUnaryOp int get_type_id() const @@ -107,7 +109,7 @@ class SymbolTable { private: //! Has method freeze() been called? - bool frozen{false}; + bool frozen {false}; using symbol_table_type = map; //! Maps strings to symbol IDs @@ -196,31 +198,34 @@ public: { public: int orig_symb_id, orig_lead_lag, symb_id; - SearchFailedException(int orig_symb_id_arg, int orig_lead_lag_arg) : orig_symb_id{orig_symb_id_arg}, - orig_lead_lag{orig_lead_lag_arg} + SearchFailedException(int orig_symb_id_arg, int orig_lead_lag_arg) : + orig_symb_id {orig_symb_id_arg}, orig_lead_lag {orig_lead_lag_arg} { } - explicit SearchFailedException(int symb_id_arg) : symb_id{symb_id_arg} + explicit SearchFailedException(int symb_id_arg) : symb_id {symb_id_arg} { } }; private: //! Factorized code for adding aux lag variables - int addLagAuxiliaryVarInternal(bool endo, int orig_symb_id, int orig_lead_lag, expr_t arg) noexcept(false); + int addLagAuxiliaryVarInternal(bool endo, int orig_symb_id, int orig_lead_lag, + expr_t arg) noexcept(false); //! Factorized code for adding aux lead variables int addLeadAuxiliaryVarInternal(bool endo, int index, expr_t arg) noexcept(false); //! Factorized code for Json writing - void writeJsonVarVector(ostream &output, const vector &varvec) const; + void writeJsonVarVector(ostream& output, const vector& varvec) const; //! Factorized code for asserting that 0 <= symb_id <= symbol_table.size() inline void validateSymbID(int symb_id) const noexcept(false); + public: //! Add a symbol /*! Returns the symbol ID */ - int addSymbol(const string &name, SymbolType type, const string &tex_name, const vector> &partition_value) noexcept(false); + int addSymbol(const string& name, SymbolType type, const string& tex_name, + const vector>& partition_value) noexcept(false); //! Add a symbol without its TeX name (will be equal to its name) /*! Returns the symbol ID */ - int addSymbol(const string &name, SymbolType type) noexcept(false); + int addSymbol(const string& name, SymbolType type) noexcept(false); //! Adds an auxiliary variable for endogenous with lead >= 2 /*! \param[in] index Used to construct the variable name @@ -228,9 +233,9 @@ public: int addEndoLeadAuxiliaryVar(int index, expr_t arg) noexcept(false); //! Adds an auxiliary variable for endogenous with lag >= 2 /*! - \param[in] orig_symb_id symbol ID of the endogenous declared by the user that this new variable will represent - \param[in] orig_lead_lag lag value such that this new variable will be equivalent to orig_symb_id(orig_lead_lag) - \return the symbol ID of the new symbol */ + \param[in] orig_symb_id symbol ID of the endogenous declared by the user that this new variable + will represent \param[in] orig_lead_lag lag value such that this new variable will be equivalent + to orig_symb_id(orig_lead_lag) \return the symbol ID of the new symbol */ int addEndoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t arg) noexcept(false); //! Adds an auxiliary variable for endogenous with lead >= 1 /*! @@ -239,9 +244,9 @@ public: int addExoLeadAuxiliaryVar(int index, expr_t arg) noexcept(false); //! Adds an auxiliary variable for exogenous with lag >= 1 /*! - \param[in] orig_symb_id symbol ID of the exogenous declared by the user that this new variable will represent - \param[in] orig_lead_lag lag value such that this new variable will be equivalent to orig_symb_id(orig_lead_lag) - \return the symbol ID of the new symbol */ + \param[in] orig_symb_id symbol ID of the exogenous declared by the user that this new variable + will represent \param[in] orig_lead_lag lag value such that this new variable will be equivalent + to orig_symb_id(orig_lead_lag) \return the symbol ID of the new symbol */ int addExoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t arg) noexcept(false); //! Adds an auxiliary variable for the expectation operator /*! @@ -262,7 +267,8 @@ public: – orig_lead_lag is typically 0 – expr_arg is typically log(orig_symb_id) */ - int addLogTransformAuxiliaryVar(int orig_symb_id, int orig_lead_lag, expr_t expr_arg) noexcept(false); + int addLogTransformAuxiliaryVar(int orig_symb_id, int orig_lead_lag, + expr_t expr_arg) noexcept(false); //! Adds an auxiliary variable for the (time) differentiate of a forward var /*! \param[in] orig_symb_id The symb_id of the forward variable @@ -296,17 +302,22 @@ public: diffLead increases it). */ pair 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 orig_symb_id = nullopt, optional orig_lag = nullopt) noexcept(false); + int addDiffAuxiliaryVar(int index, expr_t expr_arg, optional orig_symb_id = nullopt, + optional 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); + int addDiffLagAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id, + int orig_lag) noexcept(false); //! Takes care of timing between diff statements - int addDiffLeadAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id, int orig_lead) noexcept(false); + int addDiffLeadAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id, + int orig_lead) noexcept(false); //! An Auxiliary variable for a unary op - int addUnaryOpAuxiliaryVar(int index, expr_t expr_arg, string unary_op, optional orig_symb_id = nullopt, optional orig_lag = nullopt) noexcept(false); + int addUnaryOpAuxiliaryVar(int index, expr_t expr_arg, string unary_op, + optional orig_symb_id = nullopt, + optional orig_lag = nullopt) noexcept(false); //! An auxiliary variable for a pac_expectation operator - int addPacExpectationAuxiliaryVar(const string &name, expr_t expr_arg); + int addPacExpectationAuxiliaryVar(const string& name, expr_t expr_arg); //! An auxiliary variable for a pac_target_nonstationary operator - int addPacTargetNonstationaryAuxiliaryVar(const string &name, expr_t expr_arg); + int addPacTargetNonstationaryAuxiliaryVar(const string& name, expr_t expr_arg); //! Returns the number of auxiliary variables int AuxVarsSize() const @@ -314,23 +325,24 @@ public: return aux_vars.size(); }; //! Tests if symbol already exists - inline bool exists(const string &name) const; + inline bool exists(const string& name) const; //! Get symbol name (by ID) inline string getName(int id) const noexcept(false); //! Get TeX name inline string getTeXName(int id) const noexcept(false); //! Get long name inline string getLongName(int id) const noexcept(false); - //! Returns true if the partition name is the first encountered for the type of variable represented by id + //! Returns true if the partition name is the first encountered for the type of variable + //! represented by id bool isFirstOfPartitionForType(int id) const noexcept(false); //! Returns a list of partitions and symbols that belong to that partition map> getPartitionsForType(SymbolType st) const noexcept(false); //! Get type (by ID) inline SymbolType getType(int id) const noexcept(false); //! Get type (by name) - inline SymbolType getType(const string &name) const noexcept(false); + inline SymbolType getType(const string& name) const noexcept(false); //! Get ID (by name) - inline int getID(const string &name) const noexcept(false); + inline int getID(const string& name) const noexcept(false); //! Get ID (by type specific ID) int getID(SymbolType type, int tsid) const noexcept(false); //! Freeze symbol table @@ -343,7 +355,7 @@ public: //! Get type specific ID (by symbol ID) inline int getTypeSpecificID(int id) const noexcept(false); //! Get type specific ID (by symbol name) - inline int getTypeSpecificID(const string &name) const noexcept(false); + inline int getTypeSpecificID(const string& name) const noexcept(false); //! Get number of endogenous variables inline int endo_nbr() const noexcept(false); //! Get number of exogenous variables @@ -357,9 +369,9 @@ public: //! Get number of user-declared endogenous variables (without the auxiliary variables) inline int orig_endo_nbr() const noexcept(false); //! Write output of this class - void writeOutput(ostream &output) const noexcept(false); + void writeOutput(ostream& output) const noexcept(false); //! Write JSON Output - void writeJsonOutput(ostream &output) const; + void writeJsonOutput(ostream& output) const; //! Mark a symbol as predetermined variable void markPredetermined(int symb_id) noexcept(false); //! Mark an endogenous as having been declared with “var(log)” @@ -382,21 +394,22 @@ public: int observedExogenousVariablesNbr() const; //! Is a given symbol in the set of observed exogenous variables bool isObservedExogenousVariable(int symb_id) const; - //! Return the index of a given observed exogenous variable in the vector of all observed variables + //! Return the index of a given observed exogenous variable in the vector of all observed + //! variables int getObservedExogenousVariableIndex(int symb_id) const; - vector getTrendVarIds() const; + vector getTrendVarIds() const; //! Get list of exogenous variables - set getExogenous() const; + set getExogenous() const; //! Get list of exogenous variables - set getObservedExogenous() const; + set getObservedExogenous() const; //! Get list of endogenous variables - set getEndogenous() const; + set getEndogenous() const; //! Is a given symbol an auxiliary variable bool isAuxiliaryVariable(int symb_id) const; //! Is a given symbol a diff, diff lead, or diff lag auxiliary variable bool isDiffAuxiliaryVariable(int symb_id) const; //! Get list of endogenous variables without aux vars - set getOrigEndogenous() const; + set getOrigEndogenous() const; //! Returns the original symbol corresponding to this variable /* If symb_id has no original variable, returns symb_id. Otherwise, repeatedly call getOrigSymbIDForAuxVar() until an original variable is @@ -404,13 +417,14 @@ public: no original variable (e.g. aux var for lead, Lagrange Multiplier or diff associated to a complex expression). */ int getUltimateOrigSymbID(int symb_id) const; - //! If this is a Lagrange multiplier, return its associated equation number; otherwise return nullopt + //! If this is a Lagrange multiplier, return its associated equation number; otherwise return + //! nullopt optional getEquationNumberForMultiplier(int symb_id) const; /* Return all the information about a given auxiliary variable. Throws UnknownSymbolIDException if it is not an aux var */ - const AuxVarInfo &getAuxVarInfo(int symb_id) const; + const AuxVarInfo& getAuxVarInfo(int symb_id) const; // Returns the set of all endogenous declared with “var(log)” - const set &getVariablesWithLogTransform() const; + const set& getVariablesWithLogTransform() const; // Returns all Lagrange multipliers set getLagrangeMultipliers() const; }; @@ -419,11 +433,11 @@ inline void SymbolTable::validateSymbID(int symb_id) const noexcept(false) { if (symb_id < 0 || symb_id > static_cast(symbol_table.size())) - throw UnknownSymbolIDException{symb_id}; + throw UnknownSymbolIDException {symb_id}; } inline bool -SymbolTable::exists(const string &name) const +SymbolTable::exists(const string& name) const { return symbol_table.contains(name); } @@ -457,19 +471,18 @@ SymbolTable::getType(int id) const noexcept(false) } inline SymbolType -SymbolTable::getType(const string &name) const noexcept(false) +SymbolTable::getType(const string& name) const noexcept(false) { return getType(getID(name)); } inline int -SymbolTable::getID(const string &name) const noexcept(false) +SymbolTable::getID(const string& name) const noexcept(false) { - if (auto iter = symbol_table.find(name); - iter != symbol_table.end()) + if (auto iter = symbol_table.find(name); iter != symbol_table.end()) return iter->second; else - throw UnknownSymbolNameException{name}; + throw UnknownSymbolNameException {name}; } inline int @@ -480,15 +493,14 @@ SymbolTable::getTypeSpecificID(int id) const noexcept(false) validateSymbID(id); - if (auto it = type_specific_ids.find(id); - it != type_specific_ids.end()) + if (auto it = type_specific_ids.find(id); it != type_specific_ids.end()) return it->second; else - throw NoTypeSpecificIDException{id}; + throw NoTypeSpecificIDException {id}; } inline int -SymbolTable::getTypeSpecificID(const string &name) const noexcept(false) +SymbolTable::getTypeSpecificID(const string& name) const noexcept(false) { return getTypeSpecificID(getID(name)); } @@ -541,13 +553,13 @@ SymbolTable::orig_endo_nbr() const noexcept(false) return endo_nbr() - aux_vars.size(); } -inline const AuxVarInfo & +inline const AuxVarInfo& SymbolTable::getAuxVarInfo(int symb_id) const { - for (const auto &aux_var : aux_vars) + for (const auto& aux_var : aux_vars) if (aux_var.symb_id == symb_id) return aux_var; - throw UnknownSymbolIDException{symb_id}; + throw UnknownSymbolIDException {symb_id}; } #endif diff --git a/src/VariableDependencyGraph.cc b/src/VariableDependencyGraph.cc index eea2e151..d176417a 100644 --- a/src/VariableDependencyGraph.cc +++ b/src/VariableDependencyGraph.cc @@ -17,8 +17,8 @@ * along with Dynare. If not, see . */ -#include #include +#include #include "VariableDependencyGraph.hh" @@ -59,16 +59,17 @@ VariableDependencyGraph::eliminate(vertex_descriptor vertex_to_eliminate) { if (in_degree(vertex_to_eliminate, *this) > 0 && out_degree(vertex_to_eliminate, *this) > 0) for (auto [it_in, in_end] = in_edges(vertex_to_eliminate, *this); it_in != in_end; ++it_in) - for (auto [it_out, out_end] = out_edges(vertex_to_eliminate, *this); it_out != out_end; ++it_out) - if (auto [ed, exist] = edge(source(*it_in, *this), target(*it_out, *this), *this); - !exist) + for (auto [it_out, out_end] = out_edges(vertex_to_eliminate, *this); it_out != out_end; + ++it_out) + if (auto [ed, exist] = edge(source(*it_in, *this), target(*it_out, *this), *this); !exist) add_edge(source(*it_in, *this), target(*it_out, *this), *this); suppress(vertex_to_eliminate); } bool -VariableDependencyGraph::hasCycleDFS(vertex_descriptor u, color_t &color, vector &circuit_stack) const +VariableDependencyGraph::hasCycleDFS(vertex_descriptor u, color_t& color, + vector& circuit_stack) const { auto v_index = get(vertex_index, *this); color[u] = gray_color; @@ -126,13 +127,13 @@ VariableDependencyGraph::print() const } VariableDependencyGraph -VariableDependencyGraph::extractSubgraph(const vector &select_index) const +VariableDependencyGraph::extractSubgraph(const vector& select_index) const { int n = select_index.size(); VariableDependencyGraph G(n); auto v_index = get(vertex_index, *this); auto v_index1_G = get(vertex_index1, G); // Maps new vertices to original indices - map reverse_index; // Maps orig indices to new ones + map reverse_index; // Maps orig indices to new ones for (int i = 0; i < n; i++) { reverse_index[select_index[i]] = i; @@ -159,7 +160,7 @@ VariableDependencyGraph::vertexBelongsToAClique(vertex_descriptor vertex) const while (it_in != in_end && it_out != out_end && agree) { agree = (source(*it_in, *this) == target(*it_out, *this) - && source(*it_in, *this) != target(*it_in, *this)); //not a loop + && source(*it_in, *this) != target(*it_in, *this)); // not a loop liste.push_back(source(*it_in, *this)); ++it_in; ++it_out; @@ -199,7 +200,8 @@ VariableDependencyGraph::eliminationOfVerticesWithOneOrLessIndegreeOrOutdegree() if (in_degree_n <= 1 || out_degree_n <= 1) { not_a_loop = true; - if (in_degree_n >= 1 && out_degree_n >= 1) // Do not eliminate a vertex if it loops on itself! + if (in_degree_n >= 1 + && out_degree_n >= 1) // Do not eliminate a vertex if it loops on itself! for (auto [it_in, in_end] = in_edges(*it, *this); it_in != in_end; ++it_in) if (source(*it_in, *this) == target(*it_in, *this)) not_a_loop = false; @@ -247,7 +249,7 @@ VariableDependencyGraph::eliminationOfVerticesBelongingToAClique() } bool -VariableDependencyGraph::suppressionOfVerticesWithLoop(set &feed_back_vertices) +VariableDependencyGraph::suppressionOfVerticesWithLoop(set& feed_back_vertices) { bool something_has_been_done = false; vertex_iterator ita; @@ -285,8 +287,10 @@ VariableDependencyGraph::minimalSetOfFeedbackVertices() const while (something_has_been_done && num_vertices(G) > 0) { something_has_been_done = G.eliminationOfVerticesWithOneOrLessIndegreeOrOutdegree(); - something_has_been_done = G.eliminationOfVerticesBelongingToAClique() || something_has_been_done; - something_has_been_done = G.suppressionOfVerticesWithLoop(feed_back_vertices) || something_has_been_done; + something_has_been_done + = G.eliminationOfVerticesBelongingToAClique() || something_has_been_done; + something_has_been_done + = G.suppressionOfVerticesWithLoop(feed_back_vertices) || something_has_been_done; } if (!G.hasCycle()) @@ -314,7 +318,7 @@ VariableDependencyGraph::minimalSetOfFeedbackVertices() const } vector -VariableDependencyGraph::reorderRecursiveVariables(const set &feedback_vertices) const +VariableDependencyGraph::reorderRecursiveVariables(const set& feedback_vertices) const { vector reordered_vertices; VariableDependencyGraph G(*this); @@ -362,7 +366,8 @@ VariableDependencyGraph::sortedStronglyConnectedComponents() const auto v_index = get(vertex_index, *this); // Compute SCCs and create mapping from vertices to unordered SCCs - int num_scc = strong_components(static_cast(*this), make_iterator_property_map(vertex2scc.begin(), v_index)); + int num_scc = strong_components(static_cast(*this), + make_iterator_property_map(vertex2scc.begin(), v_index)); // Create directed acyclic graph (DAG) associated to the SCCs adjacency_list dag(num_scc); @@ -384,11 +389,11 @@ VariableDependencyGraph::sortedStronglyConnectedComponents() const // Construct mapping from unordered SCC to ordered SCC vector unordered2ordered(num_scc); for (int j = 0; j < num_scc; j++) - unordered2ordered[reverseOrdered2unordered[num_scc-j-1]] = j; + unordered2ordered[reverseOrdered2unordered[num_scc - j - 1]] = j; // Update the mapping of vertices to (now sorted) SCCs for (int i = 0; i < static_cast(num_vertices(*this)); i++) vertex2scc[i] = unordered2ordered[vertex2scc[i]]; - return { num_scc, vertex2scc }; + return {num_scc, vertex2scc}; } diff --git a/src/VariableDependencyGraph.hh b/src/VariableDependencyGraph.hh index b6b4897a..b43b5ebf 100644 --- a/src/VariableDependencyGraph.hh +++ b/src/VariableDependencyGraph.hh @@ -30,20 +30,25 @@ using namespace std; -using VertexProperty_t = boost::property>>>>; +using VertexProperty_t = boost::property< + boost::vertex_index_t, int, + boost::property< + boost::vertex_index1_t, int, + boost::property>>>>; /* Class used to store a graph representing dependencies between variables. Used in the block decomposition. */ -class VariableDependencyGraph - : public boost::adjacency_list +class VariableDependencyGraph : + public boost::adjacency_list { public: - using color_t = map::vertex_descriptor, boost::default_color_type>; - using base = boost::adjacency_list; + using color_t = map::vertex_descriptor, + boost::default_color_type>; + using base + = boost::adjacency_list; VariableDependencyGraph(int n); //! Extracts a subgraph @@ -54,12 +59,13 @@ public: The property vertex_index1 of the subgraph contains indices of the original graph. */ - VariableDependencyGraph extractSubgraph(const vector &select_index) const; + VariableDependencyGraph extractSubgraph(const vector& select_index) const; //! Return the feedback set set minimalSetOfFeedbackVertices() const; //! Reorder the recursive variables - /*! They appear first in a quasi triangular form and they are followed by the feedback variables */ - vector reorderRecursiveVariables(const set &feedback_vertices) const; + /*! They appear first in a quasi triangular form and they are followed by the feedback variables + */ + vector reorderRecursiveVariables(const set& feedback_vertices) const; /* Computes the strongly connected components (SCCs) of the graph, and sort them topologically. Returns the number of SCCs, and a mapping of vertex indices to sorted SCC @@ -67,6 +73,7 @@ public: pair> sortedStronglyConnectedComponents() const; // Print on stdout a description of the graph void print() const; + private: // Remove a vertex (including all edges to and from it); takes a vertex descriptor void suppress(vertex_descriptor vertex_to_eliminate); @@ -77,14 +84,14 @@ private: through the vertex to be removed) */ void eliminate(vertex_descriptor vertex_to_eliminate); // Internal helper for hasCycle() - bool hasCycleDFS(vertex_descriptor u, color_t &color, vector &circuit_stack) const; + bool hasCycleDFS(vertex_descriptor u, color_t& color, vector& circuit_stack) const; // Determine whether the graph has a cycle bool hasCycle() const; bool vertexBelongsToAClique(vertex_descriptor vertex) const; bool eliminationOfVerticesWithOneOrLessIndegreeOrOutdegree(); bool eliminationOfVerticesBelongingToAClique(); // The suppressed vertices are stored in feedback set - bool suppressionOfVerticesWithLoop(set &feed_back_vertices); + bool suppressionOfVerticesWithLoop(set& feed_back_vertices); }; #endif // _VARIABLEDEPENDENCYGRAPH_HH diff --git a/src/WarningConsolidation.cc b/src/WarningConsolidation.cc index 447b2473..4f584df7 100644 --- a/src/WarningConsolidation.cc +++ b/src/WarningConsolidation.cc @@ -20,8 +20,8 @@ #include "WarningConsolidation.hh" #include -WarningConsolidation & -operator<<(WarningConsolidation &wcc, const string &warning) +WarningConsolidation& +operator<<(WarningConsolidation& wcc, const string& warning) { if (wcc.no_warn) return wcc; @@ -31,8 +31,8 @@ operator<<(WarningConsolidation &wcc, const string &warning) return wcc; }; -WarningConsolidation & -operator<<(WarningConsolidation &wcc, const Dynare::location &loc) +WarningConsolidation& +operator<<(WarningConsolidation& wcc, const Dynare::location& loc) { if (wcc.no_warn) return wcc; @@ -40,12 +40,10 @@ operator<<(WarningConsolidation &wcc, const Dynare::location &loc) stringstream ostr; Dynare::position last = loc.end - 1; ostr << loc.begin; - if (last.filename - && (!loc.begin.filename - || *loc.begin.filename != *last.filename)) + if (last.filename && (!loc.begin.filename || *loc.begin.filename != *last.filename)) ostr << '-' << last; else if (loc.begin.line != last.line) - ostr << '-' << last.line << '.' << last.column; + ostr << '-' << last.line << '.' << last.column; else if (loc.begin.column != last.column) ostr << '-' << last.column; @@ -54,8 +52,8 @@ operator<<(WarningConsolidation &wcc, const Dynare::location &loc) return wcc; }; -WarningConsolidation & -operator<<(WarningConsolidation &wcc, ostream &(*pf)(ostream &)) +WarningConsolidation& +operator<<(WarningConsolidation& wcc, ostream& (*pf)(ostream&)) { if (wcc.no_warn) return wcc; @@ -66,7 +64,7 @@ operator<<(WarningConsolidation &wcc, ostream &(*pf)(ostream &)) } void -WarningConsolidation::writeOutput(ostream &output) const +WarningConsolidation::writeOutput(ostream& output) const { if (warnings.str().empty()) return; @@ -88,7 +86,7 @@ WarningConsolidation::writeOutput(ostream &output) const else { output << "');" << endl; - if (i+1 < warningsstr.length()) + if (i + 1 < warningsstr.length()) writedisp = true; } } diff --git a/src/WarningConsolidation.hh b/src/WarningConsolidation.hh index b24ad83e..b1e99c34 100644 --- a/src/WarningConsolidation.hh +++ b/src/WarningConsolidation.hh @@ -20,9 +20,9 @@ #ifndef _WARNINGCONSOLIDATION_HH #define _WARNINGCONSOLIDATION_HH +#include "DynareBisonLocation.hh" #include #include -#include "DynareBisonLocation.hh" using namespace std; @@ -34,28 +34,28 @@ private: bool no_warn; public: - explicit WarningConsolidation(bool no_warn_arg) : no_warn{no_warn_arg} + explicit WarningConsolidation(bool no_warn_arg) : no_warn {no_warn_arg} { - }; + } //! Add A Warning to the StringStream - friend WarningConsolidation &operator<<(WarningConsolidation &wcc, const string &warning); - friend WarningConsolidation &operator<<(WarningConsolidation &wcc, const Dynare::location &loc); - friend WarningConsolidation &operator<<(WarningConsolidation &wcc, ostream &(*pf)(ostream &)); + friend WarningConsolidation& operator<<(WarningConsolidation& wcc, const string& warning); + friend WarningConsolidation& operator<<(WarningConsolidation& wcc, const Dynare::location& loc); + friend WarningConsolidation& operator<<(WarningConsolidation& wcc, ostream& (*pf)(ostream&)); void - addWarning(const string &w) + addWarning(const string& w) { warnings << w; }; void - addWarning(ostream &(*pf)(ostream &)) + addWarning(ostream& (*pf)(ostream&)) { warnings << pf; }; //! Write Warnings to m file - void writeOutput(ostream &output) const; + void writeOutput(ostream& output) const; //! Count warnings /*! This is done in a very lousy way, by counting newlines in the stringstream... */ diff --git a/src/macro/Directives.cc b/src/macro/Directives.cc index 5d160a34..a1bd74ad 100644 --- a/src/macro/Directives.cc +++ b/src/macro/Directives.cc @@ -26,25 +26,25 @@ using namespace macro; void -Eval::interpret(ostream &output, Environment &env, [[maybe_unused]] vector &paths) +Eval::interpret(ostream& output, Environment& env, [[maybe_unused]] vector& paths) { try { output << expr->eval(env)->to_string(); } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("Evaluation", location); error(ex); } - catch (exception &e) + catch (exception& e) { error(StackTrace("Evaluation", e.what(), location)); } } void -Include::interpret(ostream &output, Environment &env, vector &paths) +Include::interpret(ostream& output, Environment& env, vector& paths) { using namespace filesystem; try @@ -56,7 +56,7 @@ Include::interpret(ostream &output, Environment &env, vector & ifstream incfile(filename, ios::binary); if (incfile.fail()) { - for (const auto &dir : paths) + for (const auto& dir : paths) { incfile = ifstream(dir / filename, ios::binary); if (incfile.good()) @@ -66,10 +66,12 @@ Include::interpret(ostream &output, Environment &env, vector & { ostringstream errmsg; errmsg << " * " << current_path().string() << endl; - for (const auto &dir : paths) + for (const auto& dir : paths) errmsg << " * " << absolute(dir).string() << endl; - error(StackTrace("@#include", "Could not open " + filename.string() - +". The following directories were searched:\n" + errmsg.str(), location)); + error(StackTrace("@#include", + "Could not open " + filename.string() + + ". The following directories were searched:\n" + errmsg.str(), + location)); } } Driver m; @@ -79,12 +81,12 @@ Include::interpret(ostream &output, Environment &env, vector & https://en.cppreference.com/w/cpp/filesystem/path/native. */ m.parse(filename.string(), incfile, false, {}, env, paths, output); } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("@#include", location); error(ex); } - catch (exception &e) + catch (exception& e) { error(StackTrace("@#include", e.what(), location)); } @@ -92,7 +94,8 @@ Include::interpret(ostream &output, Environment &env, vector & } void -IncludePath::interpret([[maybe_unused]] ostream &output, Environment &env, vector &paths) +IncludePath::interpret([[maybe_unused]] ostream& output, Environment& env, + vector& paths) { using namespace filesystem; try @@ -110,7 +113,7 @@ IncludePath::interpret([[maybe_unused]] ostream &output, Environment &env, vecto string ipstr = static_cast(*msp); while (ipstr.size() > 1 && (ipstr.back() == '/' || ipstr.back() == '\\')) ipstr.pop_back(); - path ip{ipstr}; + path ip {ipstr}; #else path ip = static_cast(*msp); #endif @@ -120,12 +123,12 @@ IncludePath::interpret([[maybe_unused]] ostream &output, Environment &env, vecto warning(StackTrace("@#includepath", ip.string() + " does not exist", location)); paths.emplace_back(ip); } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("@#includepath", location); error(ex); } - catch (exception &e) + catch (exception& e) { error(StackTrace("@#includepath", e.what(), location)); } @@ -133,7 +136,8 @@ IncludePath::interpret([[maybe_unused]] ostream &output, Environment &env, vecto } void -Define::interpret([[maybe_unused]] ostream &output, Environment &env, [[maybe_unused]] vector &paths) +Define::interpret([[maybe_unused]] ostream& output, Environment& env, + [[maybe_unused]] vector& paths) { try { @@ -144,12 +148,12 @@ Define::interpret([[maybe_unused]] ostream &output, Environment &env, [[maybe_un else throw StackTrace("LHS of can be either a variable or a function"); } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("@#define", location); error(ex); } - catch (exception &e) + catch (exception& e) { error(StackTrace("@#define", e.what(), location)); } @@ -157,18 +161,18 @@ Define::interpret([[maybe_unused]] ostream &output, Environment &env, [[maybe_un } void -Echo::interpret(ostream &output, Environment &env, [[maybe_unused]] vector &paths) +Echo::interpret(ostream& output, Environment& env, [[maybe_unused]] vector& paths) { try { cout << "@#echo (" << getLocation() << "): " << expr->eval(env)->to_string() << endl; } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("@#echo", location); error(ex); } - catch (exception &e) + catch (exception& e) { error(StackTrace("@#echo", e.what(), location)); } @@ -176,25 +180,27 @@ Echo::interpret(ostream &output, Environment &env, [[maybe_unused]] vector &paths) +Error::interpret([[maybe_unused]] ostream& output, Environment& env, + [[maybe_unused]] vector& paths) { try { throw StackTrace(expr->eval(env)->to_string()); } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("@#error", location); error(ex); } - catch (exception &e) + catch (exception& e) { error(StackTrace("@#error", e.what(), location)); } } void -EchoMacroVars::interpret(ostream &output, Environment &env, [[maybe_unused]] vector &paths) +EchoMacroVars::interpret(ostream& output, Environment& env, + [[maybe_unused]] vector& paths) { if (save) env.print(output, vars, location.begin.line, true); @@ -204,7 +210,7 @@ EchoMacroVars::interpret(ostream &output, Environment &env, [[maybe_unused]] vec } void -For::interpret(ostream &output, Environment &env, vector &paths) +For::interpret(ostream& output, Environment& env, vector& paths) { ArrayPtr ap; try @@ -213,12 +219,12 @@ For::interpret(ostream &output, Environment &env, vector &path if (!ap) throw StackTrace("The index must loop through an array"); } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("@#for", location); error(ex); } - catch (exception &e) + catch (exception& e) { error(StackTrace("@#for", e.what(), location)); } @@ -237,8 +243,11 @@ For::interpret(ostream &output, Environment &env, vector &path { TuplePtr mtp = dynamic_pointer_cast(btp); if (index_vec.size() != mtp->size()) - error(StackTrace("@#for", "Encountered tuple of size " + to_string(mtp->size()) - + " but only have " + to_string(index_vec.size()) + " index variables", location)); + error(StackTrace("@#for", + "Encountered tuple of size " + to_string(mtp->size()) + + " but only have " + to_string(index_vec.size()) + + " index variables", + location)); else for (size_t j = 0; j < index_vec.size(); j++) env.define(index_vec.at(j), mtp->at(j)); @@ -246,7 +255,7 @@ For::interpret(ostream &output, Environment &env, vector &path } bool printLine = true; - for (const auto &statement : statements) + for (const auto& statement : statements) { if (printLine) { @@ -260,10 +269,9 @@ For::interpret(ostream &output, Environment &env, vector &path } void -If::interpret(ostream &output, Environment &env, vector &paths) +If::interpret(ostream& output, Environment& env, vector& paths) { - for (bool first_clause{true}; - const auto &[expr, body] : expr_and_body) + for (bool first_clause {true}; const auto& [expr, body] : expr_and_body) try { if ((ifdef || ifndef) && exchange(first_clause, false)) @@ -285,8 +293,8 @@ If::interpret(ostream &output, Environment &env, vector &paths RealPtr dp = dynamic_pointer_cast(tmp); BoolPtr bp = dynamic_pointer_cast(tmp); if (!bp && !dp) - error(StackTrace("@#if", - "The condition must evaluate to a boolean or a double", location)); + error(StackTrace("@#if", "The condition must evaluate to a boolean or a double", + location)); if ((bp && *bp) || (dp && *dp)) { interpretBody(body, output, env, paths); @@ -294,12 +302,12 @@ If::interpret(ostream &output, Environment &env, vector &paths } } } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("@#if", location); error(ex); } - catch (exception &e) + catch (exception& e) { error(StackTrace("@#if", e.what(), location)); } @@ -307,10 +315,10 @@ If::interpret(ostream &output, Environment &env, vector &paths } void -If::interpretBody(const vector &body, ostream &output, Environment &env, vector &paths) +If::interpretBody(const vector& body, ostream& output, Environment& env, + vector& paths) { - for (bool printLine{true}; - const auto &statement : body) + for (bool printLine {true}; const auto& statement : body) { if (exchange(printLine, false)) statement->printLineInfo(output); diff --git a/src/macro/Directives.hh b/src/macro/Directives.hh index 89f93347..6d564e76 100644 --- a/src/macro/Directives.hh +++ b/src/macro/Directives.hh @@ -26,187 +26,210 @@ namespace macro { - class Directive : public Node +class Directive : public Node +{ + // A Parent class just for clarity +public: + explicit Directive(Tokenizer::location location_arg) : Node(move(location_arg)) { - // A Parent class just for clarity - public: - explicit Directive(Tokenizer::location location_arg) : - Node(move(location_arg)) { } - // Directives can be interpreted - virtual void interpret(ostream &output, Environment &env, vector &paths) = 0; - }; + } + // Directives can be interpreted + virtual void interpret(ostream& output, Environment& env, vector& paths) = 0; +}; +class TextNode : public Directive +{ + // Class for text not interpreted by macroprocessor + // Not a real directive node + // Treated as such as the output is only to be interpreted +private: + const string text; - class TextNode : public Directive +public: + TextNode(string text_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), text {move(text_arg)} { - // Class for text not interpreted by macroprocessor - // Not a real directive node - // Treated as such as the output is only to be interpreted - private: - const string text; - public: - TextNode(string text_arg, Tokenizer::location location_arg) : - Directive(move(location_arg)), text{move(text_arg)} { } - void - interpret(ostream &output, [[maybe_unused]] Environment &env, [[maybe_unused]] vector &paths) override - { - output << text; - } - }; - - - class Eval : public Directive + } + void + interpret(ostream& output, [[maybe_unused]] Environment& env, + [[maybe_unused]] vector& paths) override { - // Class for @{} statements - // Not a real directive node - // Treated as such as the output is only to be interpreted - private: - const ExpressionPtr expr; - public: - Eval(ExpressionPtr expr_arg, Tokenizer::location location_arg) : - Directive(move(location_arg)), expr{move(expr_arg)} { } - void interpret(ostream &output, Environment &env, vector &paths) override; - }; + output << text; + } +}; +class Eval : public Directive +{ + // Class for @{} statements + // Not a real directive node + // Treated as such as the output is only to be interpreted +private: + const ExpressionPtr expr; - class Include : public Directive +public: + Eval(ExpressionPtr expr_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), expr {move(expr_arg)} { - private: - const ExpressionPtr expr; - public: - Include(ExpressionPtr expr_arg, Tokenizer::location location_arg) : - Directive(move(location_arg)), expr{move(expr_arg)} { } - void interpret(ostream &output, Environment &env, vector &paths) override; - }; + } + void interpret(ostream& output, Environment& env, vector& paths) override; +}; +class Include : public Directive +{ +private: + const ExpressionPtr expr; - class IncludePath : public Directive +public: + Include(ExpressionPtr expr_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), expr {move(expr_arg)} { - private: - const ExpressionPtr expr; - public: - IncludePath(ExpressionPtr expr_arg, Tokenizer::location location_arg) : - Directive(move(location_arg)), expr{move(expr_arg)} { } - void interpret(ostream &output, Environment &env, vector &paths) override; - }; + } + void interpret(ostream& output, Environment& env, vector& paths) override; +}; +class IncludePath : public Directive +{ +private: + const ExpressionPtr expr; - class Define : public Directive +public: + IncludePath(ExpressionPtr expr_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), expr {move(expr_arg)} { - private: - const VariablePtr var; - const FunctionPtr func; - const ExpressionPtr value; - public: - Define(VariablePtr var_arg, - ExpressionPtr value_arg, - Tokenizer::location location_arg) : - Directive(move(location_arg)), var{move(var_arg)}, value{move(value_arg)} { } - Define(FunctionPtr func_arg, - ExpressionPtr value_arg, - Tokenizer::location location_arg) : - Directive(move(location_arg)), func{move(func_arg)}, value{move(value_arg)} { } - void interpret(ostream &output, Environment &env, vector &paths) override; - }; + } + void interpret(ostream& output, Environment& env, vector& paths) override; +}; +class Define : public Directive +{ +private: + const VariablePtr var; + const FunctionPtr func; + const ExpressionPtr value; - class Echo : public Directive +public: + Define(VariablePtr var_arg, ExpressionPtr value_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), var {move(var_arg)}, value {move(value_arg)} { - private: - const ExpressionPtr expr; - public: - Echo(ExpressionPtr expr_arg, - Tokenizer::location location_arg) : - Directive(move(location_arg)), expr{move(expr_arg)} { } - void interpret(ostream &output, Environment &env, vector &paths) override; - }; - - - class Error : public Directive + } + Define(FunctionPtr func_arg, ExpressionPtr value_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), func {move(func_arg)}, value {move(value_arg)} { - private: - const ExpressionPtr expr; - public: - Error(ExpressionPtr expr_arg, - Tokenizer::location location_arg) : - Directive(move(location_arg)), expr{move(expr_arg)} { } - void interpret(ostream &output, Environment &env, vector &paths) override; - }; + } + void interpret(ostream& output, Environment& env, vector& paths) override; +}; +class Echo : public Directive +{ +private: + const ExpressionPtr expr; - class EchoMacroVars : public Directive +public: + Echo(ExpressionPtr expr_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), expr {move(expr_arg)} { - private: - const bool save; - const vector vars; - public: - EchoMacroVars(bool save_arg, - Tokenizer::location location_arg) : - Directive(move(location_arg)), save{save_arg} { } - EchoMacroVars(bool save_arg, vector vars_arg, - Tokenizer::location location_arg) : - Directive(move(location_arg)), save{save_arg}, vars{move(vars_arg)} { } - void interpret(ostream &output, Environment &env, vector &paths) override; - }; + } + void interpret(ostream& output, Environment& env, vector& paths) override; +}; +class Error : public Directive +{ +private: + const ExpressionPtr expr; - class For : public Directive +public: + Error(ExpressionPtr expr_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), expr {move(expr_arg)} { - private: - const vector index_vec; - const ExpressionPtr index_vals; - const vector statements; - public: - For(vector index_vec_arg, - ExpressionPtr index_vals_arg, - vector statements_arg, + } + void interpret(ostream& output, Environment& env, vector& paths) override; +}; + +class EchoMacroVars : public Directive +{ +private: + const bool save; + const vector vars; + +public: + EchoMacroVars(bool save_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), save {save_arg} + { + } + EchoMacroVars(bool save_arg, vector vars_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), save {save_arg}, vars {move(vars_arg)} + { + } + void interpret(ostream& output, Environment& env, vector& paths) override; +}; + +class For : public Directive +{ +private: + const vector index_vec; + const ExpressionPtr index_vals; + const vector statements; + +public: + For(vector index_vec_arg, ExpressionPtr index_vals_arg, + vector statements_arg, Tokenizer::location location_arg) : + Directive(move(location_arg)), + index_vec {move(index_vec_arg)}, + index_vals {move(index_vals_arg)}, + statements {move(statements_arg)} + { + } + void interpret(ostream& output, Environment& env, vector& paths) override; +}; + +class If : public Directive +{ +protected: + /* Every if statement and the associated body to execute are stored in a + * pair>, where the ExpressionPtr is the condition + * and vector is the series of statements to execute if the condition evaluates + * to true. + * The `if` statement is the first element in the vector + * If there exist any `elseif` statements, they follow + * If there is an `else` statement it is the last element in the vector. Its condition is true. + */ + const vector>> expr_and_body; + const bool ifdef, ifndef; + +public: + If(vector>> expr_and_body_arg, + Tokenizer::location location_arg, bool ifdef_arg = false, bool ifndef_arg = false) : + Directive(move(location_arg)), + expr_and_body {move(expr_and_body_arg)}, + ifdef {ifdef_arg}, + ifndef {ifndef_arg} + { + } + void interpret(ostream& output, Environment& env, vector& paths) override; + +protected: + void interpretBody(const vector& body, ostream& output, Environment& env, + vector& paths); +}; + +class Ifdef : public If +{ +public: + Ifdef(vector>> expr_and_body_arg, Tokenizer::location location_arg) : - Directive(move(location_arg)), index_vec{move(index_vec_arg)}, - index_vals{move(index_vals_arg)}, statements{move(statements_arg)} { } - void interpret(ostream &output, Environment &env, vector &paths) override; - }; - - - class If : public Directive + If(move(expr_and_body_arg), move(location_arg), true, false) { - protected: - /* Every if statement and the associated body to execute are stored in a - * pair>, where the ExpressionPtr is the condition - * and vector is the series of statements to execute if the condition evaluates - * to true. - * The `if` statement is the first element in the vector - * If there exist any `elseif` statements, they follow - * If there is an `else` statement it is the last element in the vector. Its condition is true. - */ - const vector>> expr_and_body; - const bool ifdef, ifndef; - public: - If(vector>> expr_and_body_arg, - Tokenizer::location location_arg, - bool ifdef_arg = false, bool ifndef_arg = false) : - Directive(move(location_arg)), expr_and_body{move(expr_and_body_arg)}, - ifdef{ifdef_arg}, ifndef{ifndef_arg} { } - void interpret(ostream &output, Environment &env, vector &paths) override; - protected: - void interpretBody(const vector &body, ostream &output, - Environment &env, vector &paths); - }; + } +}; - class Ifdef : public If +class Ifndef : public If +{ +public: + Ifndef(vector>> expr_and_body_arg, + Tokenizer::location location_arg) : + If(move(expr_and_body_arg), move(location_arg), false, true) { - public: - Ifdef(vector>> expr_and_body_arg, - Tokenizer::location location_arg) : - If(move(expr_and_body_arg), move(location_arg), true, false) { } - }; - - - class Ifndef : public If - { - public: - Ifndef(vector>> expr_and_body_arg, - Tokenizer::location location_arg) : - If(move(expr_and_body_arg), move(location_arg), false, true) { } - }; + } +}; } #endif diff --git a/src/macro/Driver.cc b/src/macro/Driver.cc index cffdd0c1..401e213d 100644 --- a/src/macro/Driver.cc +++ b/src/macro/Driver.cc @@ -25,16 +25,16 @@ using namespace macro; void -Driver::parse(const string &file_arg, const istream &modfile, - bool debug, const vector> &defines, - Environment &env, vector &paths, ostream &output) +Driver::parse(const string& file_arg, const istream& modfile, bool debug, + const vector>& defines, Environment& env, + vector& paths, ostream& output) { file = file_arg; if (!defines.empty()) { stringstream command_line_defines_with_endl; - for (const auto & [var, val] : defines) + for (const auto& [var, val] : defines) command_line_defines_with_endl << "@#define " << var << " = " << val << endl; Driver m; istream is(command_line_defines_with_endl.rdbuf()); @@ -54,8 +54,7 @@ Driver::parse(const string &file_arg, const istream &modfile, parser.parse(); // Interpret parsed statements - for (bool printLine{true}; - const auto &statement : statements) + for (bool printLine {true}; const auto& statement : statements) { if (exchange(printLine, false)) statement->printLineInfo(output); @@ -64,7 +63,7 @@ Driver::parse(const string &file_arg, const istream &modfile, } void -Driver::error(const Tokenizer::parser::location_type &location, const string &message) const +Driver::error(const Tokenizer::parser::location_type& location, const string& message) const { cerr << "ERROR in macro-processor: " << location << ": " << message << endl; exit(EXIT_FAILURE); diff --git a/src/macro/Driver.hh b/src/macro/Driver.hh index ad287cc8..a28999d9 100644 --- a/src/macro/Driver.hh +++ b/src/macro/Driver.hh @@ -24,9 +24,9 @@ # error Impossible to include both ../ParsingDriver.hh and Driver.hh #endif -#include "Parser.hh" #include "Environment.hh" #include "Expressions.hh" +#include "Parser.hh" #include @@ -39,87 +39,90 @@ namespace macro { - /* The lexer class - * It was necessary to subclass the TokenizerFlexLexer class generated by Flex, - * since the prototype for TokenizerFlexLexer::yylex() was not convenient. - */ - class TokenizerFlex : public TokenizerFlexLexer +/* The lexer class + * It was necessary to subclass the TokenizerFlexLexer class generated by Flex, + * since the prototype for TokenizerFlexLexer::yylex() was not convenient. + */ +class TokenizerFlex : public TokenizerFlexLexer +{ +public: + TokenizerFlex(istream* in) : TokenizerFlexLexer {in} { - public: - TokenizerFlex(istream *in) : TokenizerFlexLexer{in} { } - TokenizerFlex(const TokenizerFlex &) = delete; - TokenizerFlex &operator=(const TokenizerFlex &) = delete; + } + TokenizerFlex(const TokenizerFlex&) = delete; + TokenizerFlex& operator=(const TokenizerFlex&) = delete; - //! The main lexing function - Tokenizer::parser::token_type lex(Tokenizer::parser::semantic_type *yylval, - Tokenizer::parser::location_type *yylloc, - macro::Driver &driver); - static void location_increment(Tokenizer::parser::location_type *yylloc, const char *yytext); + //! The main lexing function + Tokenizer::parser::token_type lex(Tokenizer::parser::semantic_type* yylval, + Tokenizer::parser::location_type* yylloc, + macro::Driver& driver); + static void location_increment(Tokenizer::parser::location_type* yylloc, const char* yytext); +}; + +//! Implements the macro expansion using a Flex scanner and a Bison parser +class Driver +{ +private: + vector statements; + stack> directive_stack; + +public: + Driver() = default; + Driver(const Driver&) = delete; + Driver& operator=(const Driver&) = delete; + + //! Exception thrown when value of an unknown variable is requested + struct UnknownVariable + { + const string name; }; - //! Implements the macro expansion using a Flex scanner and a Bison parser - class Driver + //! Starts parsing a file, modifies `env`, `paths` and `output` + //! as they are modified by various macro directives + void parse(const string& file, const istream& modfile, bool debug, + const vector>& defines, Environment& env, + vector& paths, ostream& output); + + //! Name of main file being parsed (for error reporting purposes) + string file; + + //! Reference to the lexer + unique_ptr lexer; + + //! Error handler + void error(const Tokenizer::parser::location_type& location, const string& message) const; + + bool + inContext() const { - private: - vector statements; - stack> directive_stack; - public: - Driver() = default; - Driver(const Driver &) = delete; - Driver &operator=(const Driver &) = delete; + return !directive_stack.empty(); + } - //! Exception thrown when value of an unknown variable is requested - struct UnknownVariable - { - const string name; - }; + void + pushContext() + { + directive_stack.emplace(vector()); + } - //! Starts parsing a file, modifies `env`, `paths` and `output` - //! as they are modified by various macro directives - void parse(const string &file, const istream &modfile, - bool debug, const vector> &defines, - Environment &env, vector &paths, ostream &output); + void + pushContextTop(DirectivePtr statement) + { + directive_stack.top().emplace_back(move(statement)); + } - //! Name of main file being parsed (for error reporting purposes) - string file; + void + pushStatements(DirectivePtr statement) + { + statements.emplace_back(move(statement)); + } - //! Reference to the lexer - unique_ptr lexer; - - //! Error handler - void error(const Tokenizer::parser::location_type &location, const string &message) const; - - bool - inContext() const - { - return !directive_stack.empty(); - } - - void - pushContext() - { - directive_stack.emplace(vector()); - } - - void - pushContextTop(DirectivePtr statement) - { - directive_stack.top().emplace_back(move(statement)); - } - - void - pushStatements(DirectivePtr statement) - { - statements.emplace_back(move(statement)); - } - - vector - popContext() - { - auto top = move(directive_stack.top()); - directive_stack.pop(); - return top; - } - }; + vector + popContext() + { + auto top = move(directive_stack.top()); + directive_stack.pop(); + return top; + } +}; } #endif diff --git a/src/macro/Environment.cc b/src/macro/Environment.cc index a9b56658..8ee8bdd9 100644 --- a/src/macro/Environment.cc +++ b/src/macro/Environment.cc @@ -43,7 +43,7 @@ Environment::define(FunctionPtr func, ExpressionPtr value) } ExpressionPtr -Environment::getVariable(const string &name) const +Environment::getVariable(const string& name) const { if (auto it = variables.find(name); it != variables.end()) return it->second; @@ -55,7 +55,7 @@ Environment::getVariable(const string &name) const } tuple -Environment::getFunction(const string &name) const +Environment::getFunction(const string& name) const { if (auto it = functions.find(name); it != functions.end()) return it->second; @@ -67,50 +67,51 @@ Environment::getFunction(const string &name) const } codes::BaseType -Environment::getType(const string &name) const +Environment::getType(const string& name) const { - return getVariable(name)->eval(const_cast(*this))->getType(); + return getVariable(name)->eval(const_cast(*this))->getType(); } bool -Environment::isVariableDefined(const string &name) const noexcept +Environment::isVariableDefined(const string& name) const noexcept { try { getVariable(name); return true; } - catch (StackTrace &ex) + catch (StackTrace& ex) { return false; } } bool -Environment::isFunctionDefined(const string &name) const noexcept +Environment::isFunctionDefined(const string& name) const noexcept { try { getFunction(name); return true; } - catch (StackTrace &ex) + catch (StackTrace& ex) { return false; } } void -Environment::print(ostream &output, const vector &vars, const optional &line, bool save) const +Environment::print(ostream& output, const vector& vars, const optional& line, + bool save) const { if (!save && !variables.empty()) output << "Macro Variables:" << endl; if (vars.empty()) - for (const auto &it : variables) + for (const auto& it : variables) printVariable(output, it.first, line, save); else - for (const auto &it : vars) + for (const auto& it : vars) if (isVariableDefined(it)) printVariable(output, it, line, save); @@ -118,10 +119,10 @@ Environment::print(ostream &output, const vector &vars, const optional &vars, const optional &line, bool save) const +Environment::printVariable(ostream& output, const string& name, const optional& line, + bool save) const { assert(!save || line); - output << (save ? "options_.macrovars_line_" + to_string(*line) + "." : " ") - << name << " = "; - getVariable(name)->eval(const_cast(*this))->print(output, save); + output << (save ? "options_.macrovars_line_" + to_string(*line) + "." : " ") << name << " = "; + getVariable(name)->eval(const_cast(*this))->print(output, save); if (save) output << ";"; output << endl; } void -Environment::printFunction(ostream &output, const tuple &function, const optional &line, bool save) const +Environment::printFunction(ostream& output, const tuple& function, + const optional& line, bool save) const { assert(!save || line); output << (save ? "options_.macrovars_line_" + to_string(*line) + ".function." : " "); diff --git a/src/macro/Environment.hh b/src/macro/Environment.hh index 91a488d1..49545ba5 100644 --- a/src/macro/Environment.hh +++ b/src/macro/Environment.hh @@ -23,44 +23,51 @@ #include "ForwardDeclarationsAndEnums.hh" #include -#include #include +#include namespace macro { - class Environment +class Environment +{ +private: + const Environment* parent {nullptr}; + map variables; + map> functions; + +public: + Environment() = default; + Environment(const Environment* parent_arg) : parent {parent_arg} { - private: - const Environment *parent{nullptr}; - map variables; - map> functions; - public: - Environment() = default; - Environment(const Environment *parent_arg) : parent{parent_arg} { } - void define(VariablePtr var, ExpressionPtr value); - void define(FunctionPtr func, ExpressionPtr value); - ExpressionPtr getVariable(const string &name) const; - tuple getFunction(const string &name) const; - codes::BaseType getType(const string &name) const; - bool isVariableDefined(const string &name) const noexcept; - bool isFunctionDefined(const string &name) const noexcept; - bool isSymbolDefined(const string &name) const noexcept - { - return isVariableDefined(name) || isFunctionDefined(name); - } - void print(ostream &output, const vector &vars, const optional &line = nullopt, bool save = false) const; - void printVariable(ostream &output, const string &name, const optional &line, bool save) const; - void printFunction(ostream &output, const tuple &function, const optional &line, bool save) const; - size_t - size() const noexcept - { - return variables.size() + functions.size(); - } - const Environment * - getGlobalEnv() const noexcept - { - return parent == nullptr ? this : parent->getGlobalEnv(); - } - }; + } + void define(VariablePtr var, ExpressionPtr value); + void define(FunctionPtr func, ExpressionPtr value); + ExpressionPtr getVariable(const string& name) const; + tuple getFunction(const string& name) const; + codes::BaseType getType(const string& name) const; + bool isVariableDefined(const string& name) const noexcept; + bool isFunctionDefined(const string& name) const noexcept; + bool + isSymbolDefined(const string& name) const noexcept + { + return isVariableDefined(name) || isFunctionDefined(name); + } + void print(ostream& output, const vector& vars, const optional& line = nullopt, + bool save = false) const; + void printVariable(ostream& output, const string& name, const optional& line, + bool save) const; + void printFunction(ostream& output, const tuple& function, + const optional& line, bool save) const; + size_t + size() const noexcept + { + return variables.size() + functions.size(); + } + const Environment* + getGlobalEnv() const noexcept + { + return parent == nullptr ? this : parent->getGlobalEnv(); + } +}; } #endif diff --git a/src/macro/Expressions.cc b/src/macro/Expressions.cc index 83fd7b3a..13009c4a 100644 --- a/src/macro/Expressions.cc +++ b/src/macro/Expressions.cc @@ -17,15 +17,15 @@ * along with Dynare. If not, see . */ -#include #include +#include #include "Expressions.hh" using namespace macro; BoolPtr -BaseType::is_different(const BaseTypePtr &btp) const +BaseType::is_different(const BaseTypePtr& btp) const { if (*(this->is_equal(btp))) return make_shared(false); @@ -33,7 +33,7 @@ BaseType::is_different(const BaseTypePtr &btp) const } BoolPtr -Bool::is_equal(const BaseTypePtr &btp) const +Bool::is_equal(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -42,7 +42,7 @@ Bool::is_equal(const BaseTypePtr &btp) const } BoolPtr -Bool::logical_and(const ExpressionPtr &ep, Environment &env) const +Bool::logical_and(const ExpressionPtr& ep, Environment& env) const { if (!value) return make_shared(false); @@ -58,7 +58,7 @@ Bool::logical_and(const ExpressionPtr &ep, Environment &env) const } BoolPtr -Bool::logical_or(const ExpressionPtr &ep, Environment &env) const +Bool::logical_or(const ExpressionPtr& ep, Environment& env) const { if (value) return make_shared(true); @@ -80,7 +80,7 @@ Bool::logical_not() const } BaseTypePtr -Real::plus(const BaseTypePtr &btp) const +Real::plus(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -89,7 +89,7 @@ Real::plus(const BaseTypePtr &btp) const } BaseTypePtr -Real::minus(const BaseTypePtr &btp) const +Real::minus(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -98,7 +98,7 @@ Real::minus(const BaseTypePtr &btp) const } BaseTypePtr -Real::times(const BaseTypePtr &btp) const +Real::times(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -107,7 +107,7 @@ Real::times(const BaseTypePtr &btp) const } BaseTypePtr -Real::divide(const BaseTypePtr &btp) const +Real::divide(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -116,7 +116,7 @@ Real::divide(const BaseTypePtr &btp) const } BaseTypePtr -Real::power(const BaseTypePtr &btp) const +Real::power(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -125,7 +125,7 @@ Real::power(const BaseTypePtr &btp) const } BoolPtr -Real::is_less(const BaseTypePtr &btp) const +Real::is_less(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -134,7 +134,7 @@ Real::is_less(const BaseTypePtr &btp) const } BoolPtr -Real::is_greater(const BaseTypePtr &btp) const +Real::is_greater(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -143,7 +143,7 @@ Real::is_greater(const BaseTypePtr &btp) const } BoolPtr -Real::is_less_equal(const BaseTypePtr &btp) const +Real::is_less_equal(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -152,7 +152,7 @@ Real::is_less_equal(const BaseTypePtr &btp) const } BoolPtr -Real::is_greater_equal(const BaseTypePtr &btp) const +Real::is_greater_equal(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -161,7 +161,7 @@ Real::is_greater_equal(const BaseTypePtr &btp) const } BoolPtr -Real::is_equal(const BaseTypePtr &btp) const +Real::is_equal(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -170,7 +170,7 @@ Real::is_equal(const BaseTypePtr &btp) const } BoolPtr -Real::logical_and(const ExpressionPtr &ep, Environment &env) const +Real::logical_and(const ExpressionPtr& ep, Environment& env) const { if (!value) return make_shared(false); @@ -186,7 +186,7 @@ Real::logical_and(const ExpressionPtr &ep, Environment &env) const } BoolPtr -Real::logical_or(const ExpressionPtr &ep, Environment &env) const +Real::logical_or(const ExpressionPtr& ep, Environment& env) const { if (value) return make_shared(true); @@ -208,7 +208,7 @@ Real::logical_not() const } RealPtr -Real::max(const BaseTypePtr &btp) const +Real::max(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -217,7 +217,7 @@ Real::max(const BaseTypePtr &btp) const } RealPtr -Real::min(const BaseTypePtr &btp) const +Real::min(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -226,7 +226,7 @@ Real::min(const BaseTypePtr &btp) const } RealPtr -Real::mod(const BaseTypePtr &btp) const +Real::mod(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -235,27 +235,30 @@ Real::mod(const BaseTypePtr &btp) const } RealPtr -Real::normpdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const +Real::normpdf(const BaseTypePtr& btp1, const BaseTypePtr& btp2) const { auto btp12 = dynamic_pointer_cast(btp1); auto btp22 = dynamic_pointer_cast(btp2); if (!btp12 || !btp22) throw StackTrace("Type mismatch for operands of `normpdf` operator"); - return make_shared((1/(btp22->value*std::sqrt(2*numbers::pi)*std::exp(pow((value-btp12->value)/btp22->value, 2)/2)))); + return make_shared((1 + / (btp22->value * std::sqrt(2 * numbers::pi) + * std::exp(pow((value - btp12->value) / btp22->value, 2) / 2)))); } RealPtr -Real::normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const +Real::normcdf(const BaseTypePtr& btp1, const BaseTypePtr& btp2) const { auto btp12 = dynamic_pointer_cast(btp1); auto btp22 = dynamic_pointer_cast(btp2); if (!btp12 || !btp22) throw StackTrace("Type mismatch for operands of `normpdf` operator"); - return make_shared((0.5*(1+std::erf((value-btp12->value)/btp22->value/numbers::sqrt2)))); + return make_shared( + (0.5 * (1 + std::erf((value - btp12->value) / btp22->value / numbers::sqrt2)))); } BaseTypePtr -String::plus(const BaseTypePtr &btp) const +String::plus(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -264,7 +267,7 @@ String::plus(const BaseTypePtr &btp) const } BoolPtr -String::is_less(const BaseTypePtr &btp) const +String::is_less(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -273,7 +276,7 @@ String::is_less(const BaseTypePtr &btp) const } BoolPtr -String::is_greater(const BaseTypePtr &btp) const +String::is_greater(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -282,7 +285,7 @@ String::is_greater(const BaseTypePtr &btp) const } BoolPtr -String::is_less_equal(const BaseTypePtr &btp) const +String::is_less_equal(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -291,7 +294,7 @@ String::is_less_equal(const BaseTypePtr &btp) const } BoolPtr -String::is_greater_equal(const BaseTypePtr &btp) const +String::is_greater_equal(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -300,7 +303,7 @@ String::is_greater_equal(const BaseTypePtr &btp) const } BoolPtr -String::is_equal(const BaseTypePtr &btp) const +String::is_equal(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -309,9 +312,9 @@ String::is_equal(const BaseTypePtr &btp) const } BoolPtr -String::cast_bool([[maybe_unused]] Environment &env) const +String::cast_bool([[maybe_unused]] Environment& env) const { - auto f = [](const char &a, const char &b) { return (tolower(a) == tolower(b)); }; + auto f = [](const char& a, const char& b) { return (tolower(a) == tolower(b)); }; if (string tf = "true"; equal(value.begin(), value.end(), tf.begin(), tf.end(), f)) return make_shared(true); @@ -334,7 +337,7 @@ String::cast_bool([[maybe_unused]] Environment &env) const } RealPtr -String::cast_real([[maybe_unused]] Environment &env) const +String::cast_real([[maybe_unused]] Environment& env) const { try { @@ -351,19 +354,19 @@ String::cast_real([[maybe_unused]] Environment &env) const } BaseTypePtr -Array::plus(const BaseTypePtr &btp) const +Array::plus(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) throw StackTrace("Type mismatch for operands of + operator"); - vector arr_copy{arr}; + vector arr_copy {arr}; arr_copy.insert(arr_copy.end(), btp2->arr.begin(), btp2->arr.end()); return make_shared(arr_copy); } BaseTypePtr -Array::minus(const BaseTypePtr &btp) const +Array::minus(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -372,7 +375,7 @@ Array::minus(const BaseTypePtr &btp) const /* Highly inefficient algorithm for computing set difference (but vector is not suited for that...) */ vector arr_copy; - for (const auto &it : arr) + for (const auto& it : arr) { auto itbtp = dynamic_pointer_cast(it); auto it2 = btp2->arr.cbegin(); @@ -386,15 +389,15 @@ Array::minus(const BaseTypePtr &btp) const } BaseTypePtr -Array::times(const BaseTypePtr &btp) const +Array::times(const BaseTypePtr& btp) const { vector values; auto btp2 = dynamic_pointer_cast(btp); if (!btp2) throw StackTrace("Type mismatch for operands of * operator"); - for (const auto &itl : arr) - for (const auto &itr : btp2->getValue()) + for (const auto& itl : arr) + for (const auto& itr : btp2->getValue()) { vector new_tuple; if (dynamic_pointer_cast(itl) || dynamic_pointer_cast(itl)) @@ -407,7 +410,7 @@ Array::times(const BaseTypePtr &btp) const if (dynamic_pointer_cast(itr) || dynamic_pointer_cast(itr)) new_tuple.push_back(itr); else if (dynamic_pointer_cast(itr)) - for (const auto &tit : dynamic_pointer_cast(itr)->getValue()) + for (const auto& tit : dynamic_pointer_cast(itr)->getValue()) new_tuple.push_back(tit); else throw StackTrace("Array::times: unsupported type on rhs"); @@ -419,7 +422,7 @@ Array::times(const BaseTypePtr &btp) const } BaseTypePtr -Array::power(const BaseTypePtr &btp) const +Array::power(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2 || !*(btp2->isinteger())) @@ -435,7 +438,7 @@ Array::power(const BaseTypePtr &btp) const } BoolPtr -Array::is_equal(const BaseTypePtr &btp) const +Array::is_equal(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -455,20 +458,20 @@ Array::is_equal(const BaseTypePtr &btp) const } ArrayPtr -Array::set_union(const BaseTypePtr &btp) const +Array::set_union(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) throw StackTrace("Arguments of the union operator (|) must be sets"); vector new_values = arr; - for (const auto &it : btp2->arr) + for (const auto& it : btp2->arr) { bool found = false; auto it2 = dynamic_pointer_cast(it); if (!it2) throw StackTrace("Type mismatch for operands of in operator"); - for (const auto &nvit : new_values) + for (const auto& nvit : new_values) { auto v2 = dynamic_pointer_cast(nvit); if (!v2) @@ -486,19 +489,19 @@ Array::set_union(const BaseTypePtr &btp) const } ArrayPtr -Array::set_intersection(const BaseTypePtr &btp) const +Array::set_intersection(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) throw StackTrace("Arguments of the intersection operator (|) must be sets"); vector new_values; - for (const auto &it : btp2->arr) + for (const auto& it : btp2->arr) { auto it2 = dynamic_pointer_cast(it); if (!it2) throw StackTrace("Type mismatch for operands of in operator"); - for (const auto &nvit : arr) + for (const auto& nvit : arr) { auto v2 = dynamic_pointer_cast(nvit); if (!v2) @@ -514,9 +517,9 @@ Array::set_intersection(const BaseTypePtr &btp) const } BoolPtr -Array::contains(const BaseTypePtr &btp) const +Array::contains(const BaseTypePtr& btp) const { - for (const auto &v : arr) + for (const auto& v : arr) { auto v2 = dynamic_pointer_cast(v); if (!v2) @@ -531,7 +534,7 @@ RealPtr Array::sum() const { double retval = 0; - for (const auto &v : arr) + for (const auto& v : arr) { auto v2 = dynamic_pointer_cast(v); if (!v2) @@ -542,7 +545,7 @@ Array::sum() const } BoolPtr -Array::cast_bool(Environment &env) const +Array::cast_bool(Environment& env) const { if (arr.size() != 1) throw StackTrace("Array must be of size 1 to be cast to a boolean"); @@ -550,7 +553,7 @@ Array::cast_bool(Environment &env) const } RealPtr -Array::cast_real(Environment &env) const +Array::cast_real(Environment& env) const { if (arr.size() != 1) throw StackTrace("Array must be of size 1 to be cast to a real"); @@ -558,7 +561,7 @@ Array::cast_real(Environment &env) const } BoolPtr -Tuple::is_equal(const BaseTypePtr &btp) const +Tuple::is_equal(const BaseTypePtr& btp) const { auto btp2 = dynamic_pointer_cast(btp); if (!btp2) @@ -578,9 +581,9 @@ Tuple::is_equal(const BaseTypePtr &btp) const } BoolPtr -Tuple::contains(const BaseTypePtr &btp) const +Tuple::contains(const BaseTypePtr& btp) const { - for (const auto &v : tup) + for (const auto& v : tup) { auto v2 = dynamic_pointer_cast(v); if (!v2) @@ -592,7 +595,7 @@ Tuple::contains(const BaseTypePtr &btp) const } BoolPtr -Tuple::cast_bool(Environment &env) const +Tuple::cast_bool(Environment& env) const { if (tup.size() != 1) throw StackTrace("Tuple must be of size 1 to be cast to a boolean"); @@ -600,7 +603,7 @@ Tuple::cast_bool(Environment &env) const } RealPtr -Tuple::cast_real(Environment &env) const +Tuple::cast_real(Environment& env) const { if (tup.size() != 1) throw StackTrace("Tuple must be of size 1 to be cast to a real"); @@ -608,7 +611,7 @@ Tuple::cast_real(Environment &env) const } BaseTypePtr -Range::eval(Environment &env) const +Range::eval(Environment& env) const { RealPtr incdbl = make_shared(1); if (inc) @@ -631,55 +634,64 @@ Range::eval(Environment &env) const } BaseTypePtr -Array::eval(Environment &env) const +Array::eval(Environment& env) const { vector retval; - for (const auto &it : arr) + for (const auto& it : arr) retval.emplace_back(it->eval(env)); return make_shared(retval); } BaseTypePtr -Tuple::eval(Environment &env) const +Tuple::eval(Environment& env) const { vector retval; - for (const auto &it : tup) + for (const auto& it : tup) retval.emplace_back(it->eval(env)); return make_shared(retval); } BaseTypePtr -Variable::eval(Environment &env) const +Variable::eval(Environment& env) const { if (indices && !indices->empty()) { ArrayPtr map = dynamic_pointer_cast(indices->eval(env)); vector ind; - for (const auto &it : map->getValue()) + for (const auto& it : map->getValue()) // Necessary to handle indexes like: y[1:2,2] - // In general this evaluates to [[1:2],2] but when subscripting we want to expand it to [1,2,2] + // In general this evaluates to [[1:2],2] but when subscripting we want to expand it to + // [1,2,2] if (auto db = dynamic_pointer_cast(it); db) { if (!*(db->isinteger())) - throw StackTrace("variable", "When indexing a variable you must pass " - "an int or an int array", location); + throw StackTrace("variable", + "When indexing a variable you must pass " + "an int or an int array", + location); ind.emplace_back(*db); } else if (dynamic_pointer_cast(it)) - for (const auto &it1 : dynamic_pointer_cast(it)->getValue()) + for (const auto& it1 : dynamic_pointer_cast(it)->getValue()) if (db = dynamic_pointer_cast(it1); db) { if (!*(db->isinteger())) - throw StackTrace("variable", "When indexing a variable you must pass " - "an int or an int array", location); + throw StackTrace("variable", + "When indexing a variable you must pass " + "an int or an int array", + location); ind.emplace_back(*db); } else - throw StackTrace("variable", "You cannot index a variable with a " - "nested array", location); + throw StackTrace("variable", + "You cannot index a variable with a " + "nested array", + location); else - throw StackTrace("variable", "You can only index a variable with an int or " - "an int array", location); + throw StackTrace("variable", + "You can only index a variable with an int or " + "an int array", + location); switch (env.getType(name)) { @@ -693,15 +705,14 @@ Variable::eval(Environment &env) const throw StackTrace("variable", "Internal Error: Range: should not arrive here", location); case codes::BaseType::String: { - string orig_string - = dynamic_pointer_cast(env.getVariable(name))->to_string(); + string orig_string = dynamic_pointer_cast(env.getVariable(name))->to_string(); string retvals; for (auto it : ind) try { retvals += orig_string.substr(it - 1, 1); } - catch (const out_of_range &ex) + catch (const out_of_range& ex) { throw StackTrace("variable", "Index out of range", location); } @@ -716,7 +727,7 @@ Variable::eval(Environment &env) const { retval.emplace_back(ap->at(it - 1)->eval(env)); } - catch (const out_of_range &ex) + catch (const out_of_range& ex) { throw StackTrace("variable", "Index out of range", location); } @@ -732,7 +743,7 @@ Variable::eval(Environment &env) const } BaseTypePtr -Function::eval(Environment &env) const +Function::eval(Environment& env) const { FunctionPtr func; ExpressionPtr body; @@ -742,15 +753,17 @@ Function::eval(Environment &env) const { tie(func, body) = env.getFunction(name); } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("Function", location); throw; } if (func->args.size() != args.size()) - throw StackTrace("Function", "The number of arguments used to call " + name - +" does not match the number used in its definition", location); + throw StackTrace("Function", + "The number of arguments used to call " + name + + " does not match the number used in its definition", + location); try { @@ -763,7 +776,7 @@ Function::eval(Environment &env) const env = env_orig; return retval; } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("Function", location); throw; @@ -771,7 +784,7 @@ Function::eval(Environment &env) const } BaseTypePtr -UnaryOp::eval(Environment &env) const +UnaryOp::eval(Environment& env) const { try { @@ -857,12 +870,12 @@ UnaryOp::eval(Environment &env) const return arg->eval(env)->defined(env); } } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("unary operation", location); throw; } - catch (exception &e) + catch (exception& e) { throw StackTrace("unary operation", e.what(), location); } @@ -871,7 +884,7 @@ UnaryOp::eval(Environment &env) const } BaseTypePtr -BinaryOp::eval(Environment &env) const +BinaryOp::eval(Environment& env) const { try { @@ -917,12 +930,12 @@ BinaryOp::eval(Environment &env) const return arg1->eval(env)->mod(arg2->eval(env)); } } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("binary operation", location); throw; } - catch (exception &e) + catch (exception& e) { throw StackTrace("binary operation", e.what(), location); } @@ -931,7 +944,7 @@ BinaryOp::eval(Environment &env) const } BaseTypePtr -TrinaryOp::eval(Environment &env) const +TrinaryOp::eval(Environment& env) const { try { @@ -943,12 +956,12 @@ TrinaryOp::eval(Environment &env) const return arg1->eval(env)->normcdf(arg2->eval(env), arg3->eval(env)); } } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("trinary operation", location); throw; } - catch (exception &e) + catch (exception& e) { throw StackTrace("trinary operation", e.what(), location); } @@ -957,7 +970,7 @@ TrinaryOp::eval(Environment &env) const } BaseTypePtr -Comprehension::eval(Environment &env) const +Comprehension::eval(Environment& env) const { ArrayPtr input_set; VariablePtr vp; @@ -970,10 +983,12 @@ Comprehension::eval(Environment &env) const vp = dynamic_pointer_cast(c_vars); mt = dynamic_pointer_cast(c_vars); if ((!vp && !mt) || (vp && mt)) - throw StackTrace("Comprehension", "the loop variables must be either " - "a tuple or a variable", location); + throw StackTrace("Comprehension", + "the loop variables must be either " + "a tuple or a variable", + location); } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("Comprehension: ", location); throw; @@ -985,27 +1000,32 @@ Comprehension::eval(Environment &env) const auto btp = dynamic_pointer_cast(input_set->at(i)); if (vp) env.define(vp, btp); - else - if (btp->getType() == codes::BaseType::Tuple) - { - auto mt2 = dynamic_pointer_cast(btp); - if (mt->size() != mt2->size()) - throw StackTrace("Comprehension", "The number of elements in the input " - " set tuple are not the same as the number of elements in " - "the output expression tuple", location); + else if (btp->getType() == codes::BaseType::Tuple) + { + auto mt2 = dynamic_pointer_cast(btp); + if (mt->size() != mt2->size()) + throw StackTrace("Comprehension", + "The number of elements in the input " + " set tuple are not the same as the number of elements in " + "the output expression tuple", + location); - for (size_t j = 0; j < mt->size(); j++) - { - auto vp2 = dynamic_pointer_cast(mt->at(j)); - if (!vp2) - throw StackTrace("Comprehension", "Output expression tuple must be " - "comprised of variable names", location); - env.define(vp2, mt2->at(j)); - } - } - else - throw StackTrace("Comprehension", "assigning to tuple in output expression " - "but input expression does not contain tuples", location); + for (size_t j = 0; j < mt->size(); j++) + { + auto vp2 = dynamic_pointer_cast(mt->at(j)); + if (!vp2) + throw StackTrace("Comprehension", + "Output expression tuple must be " + "comprised of variable names", + location); + env.define(vp2, mt2->at(j)); + } + } + else + throw StackTrace("Comprehension", + "assigning to tuple in output expression " + "but input expression does not contain tuples", + location); if (!c_when) if (!c_expr) @@ -1024,7 +1044,7 @@ Comprehension::eval(Environment &env) const if (!bp && !dp) throw StackTrace("The condition must evaluate to a boolean or a real"); } - catch (StackTrace &ex) + catch (StackTrace& ex) { ex.push("Comprehension", location); throw; @@ -1047,27 +1067,27 @@ Array::to_string() const noexcept if (arr.empty()) return "[]"; string retval = "["; - for (const auto &it : arr) + for (const auto& it : arr) retval += it->to_string() + ", "; - return retval.substr(0, retval.size()-2) + "]"; + return retval.substr(0, retval.size() - 2) + "]"; } string Tuple::to_string() const noexcept { string retval = "("; - for (const auto &it : tup) + for (const auto& it : tup) retval += it->to_string() + ", "; - return retval.substr(0, retval.size()-2) + ")"; + return retval.substr(0, retval.size() - 2) + ")"; } string Function::to_string() const noexcept { string retval = name + "("; - for (const auto &it : args) + for (const auto& it : args) retval += it->to_string() + ", "; - return retval.substr(0, retval.size()-2) + ")"; + return retval.substr(0, retval.size() - 2) + ")"; } string @@ -1227,9 +1247,11 @@ TrinaryOp::to_string() const noexcept switch (op_code) { case codes::TrinaryOp::normpdf: - return "normpdf(" + arg1->to_string() + ", " + arg2->to_string() + ", " + arg3->to_string() + ")"; + return "normpdf(" + arg1->to_string() + ", " + arg2->to_string() + ", " + arg3->to_string() + + ")"; case codes::TrinaryOp::normcdf: - return "normcdf(" + arg1->to_string() + ", " + arg2->to_string() + ", " + arg3->to_string() + ")"; + return "normcdf(" + arg1->to_string() + ", " + arg2->to_string() + ", " + arg3->to_string() + + ")"; } // Suppress GCC warning exit(EXIT_FAILURE); @@ -1248,19 +1270,16 @@ Comprehension::to_string() const noexcept } void -String::print(ostream &output, bool matlab_output) const noexcept +String::print(ostream& output, bool matlab_output) const noexcept { - output << (matlab_output ? "'" : R"(")") - << value - << (matlab_output ? "'" : R"(")"); + output << (matlab_output ? "'" : R"(")") << value << (matlab_output ? "'" : R"(")"); } void -Array::print(ostream &output, bool matlab_output) const noexcept +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}; auto e : arr) { if (exchange(printed_something, true)) output << ", "; @@ -1270,11 +1289,10 @@ Array::print(ostream &output, bool matlab_output) const noexcept } void -Tuple::print(ostream &output, bool matlab_output) const noexcept +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}; auto e : tup) { if (exchange(printed_something, true)) output << ", "; @@ -1284,11 +1302,10 @@ Tuple::print(ostream &output, bool matlab_output) const noexcept } void -Function::printArgs(ostream &output) const noexcept +Function::printArgs(ostream& output) const noexcept { output << "("; - for (bool printed_something{false}; - auto e : args) + for (bool printed_something {false}; auto e : args) { if (exchange(printed_something, true)) output << ", "; @@ -1298,7 +1315,7 @@ Function::printArgs(ostream &output) const noexcept } void -UnaryOp::print(ostream &output, bool matlab_output) const noexcept +UnaryOp::print(ostream& output, bool matlab_output) const noexcept { switch (op_code) { @@ -1423,24 +1440,18 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept arg->print(output, matlab_output); - if (op_code != codes::UnaryOp::cast_bool - && op_code != codes::UnaryOp::cast_real - && op_code != codes::UnaryOp::cast_string - && op_code != codes::UnaryOp::cast_tuple - && op_code != codes::UnaryOp::cast_array - && op_code != codes::UnaryOp::logical_not - && op_code != codes::UnaryOp::unary_plus - && op_code != codes::UnaryOp::unary_minus) + if (op_code != codes::UnaryOp::cast_bool && op_code != codes::UnaryOp::cast_real + && op_code != codes::UnaryOp::cast_string && op_code != codes::UnaryOp::cast_tuple + && op_code != codes::UnaryOp::cast_array && op_code != codes::UnaryOp::logical_not + && op_code != codes::UnaryOp::unary_plus && op_code != codes::UnaryOp::unary_minus) output << ")"; } void -BinaryOp::print(ostream &output, bool matlab_output) const noexcept +BinaryOp::print(ostream& output, bool matlab_output) const noexcept { - if (op_code == codes::BinaryOp::set_union - || op_code == codes::BinaryOp::set_intersection - || op_code == codes::BinaryOp::max - || op_code == codes::BinaryOp::min + if (op_code == codes::BinaryOp::set_union || op_code == codes::BinaryOp::set_intersection + || op_code == codes::BinaryOp::max || op_code == codes::BinaryOp::min || op_code == codes::BinaryOp::mod) { switch (op_code) @@ -1529,7 +1540,7 @@ BinaryOp::print(ostream &output, bool matlab_output) const noexcept } void -TrinaryOp::print(ostream &output, bool matlab_output) const noexcept +TrinaryOp::print(ostream& output, bool matlab_output) const noexcept { switch (op_code) { @@ -1549,7 +1560,7 @@ TrinaryOp::print(ostream &output, bool matlab_output) const noexcept } void -Comprehension::print(ostream &output, bool matlab_output) const noexcept +Comprehension::print(ostream& output, bool matlab_output) const noexcept { output << "["; if (c_expr) diff --git a/src/macro/Expressions.hh b/src/macro/Expressions.hh index 31ade4e9..427c442e 100644 --- a/src/macro/Expressions.hh +++ b/src/macro/Expressions.hh @@ -20,601 +20,1212 @@ #ifndef _EXPRESSIONS_HH #define _EXPRESSIONS_HH -#include "ForwardDeclarationsAndEnums.hh" #include "Environment.hh" +#include "ForwardDeclarationsAndEnums.hh" #include "ParserLocation.hh" #include -#include -#include #include +#include +#include namespace macro { - class StackTrace final : public exception +class StackTrace final : public exception +{ +private: + vector message; + +public: + StackTrace(string message_arg) : message {move(message_arg)} { - private: - vector message; - public: - StackTrace (string message_arg) : message{move(message_arg)} { } - StackTrace (const string &prefix, const char *standard_exception_message, const Tokenizer::location &location) - { - stringstream ss; - ss << prefix << ": " << location << " " << standard_exception_message; - message = {ss.str()}; - } - StackTrace (const string &prefix, const string &msg, const Tokenizer::location &location) - { - stringstream ss; - ss << prefix << ": " << location << " " << msg; - message = {ss.str()}; - } - void push(const string &prefix, const Tokenizer::location &location) - { - stringstream ss; - auto end_col = 0 < location.end.column ? location.end.column - 1 : 0; - - ss << prefix << ": " - << R"(")" << *location.begin.filename << R"(" line )" << location.begin.line - << ", col " << location.begin.column; - if (location.end.filename - && (!location.begin.filename - || *location.begin.filename != *location.end.filename)) - ss << R"( to ")" << location.end.filename << R"(")" << " line " << location.end.line - << ", col " << end_col; - else if (location.begin.line < location.end.line) - ss << " to line " << location.end.line << ", col " << end_col; - else if (location.begin.column < end_col) - ss << "-" << end_col; - message.emplace_back(ss.str()); - } - string trace() const - { - stringstream ss; - for (auto &msg : message) - ss << "- " << msg << endl; - return ss.str(); - } - }; - - - class Node + } + StackTrace(const string& prefix, const char* standard_exception_message, + const Tokenizer::location& location) { - protected: - const Tokenizer::location location; - public: - explicit Node(Tokenizer::location location_arg) : - location{move(location_arg)} { } - virtual ~Node() = default; - public: - Tokenizer::location getLocation() const noexcept { return location; } - void - error(const StackTrace &e) const noexcept - { - cerr << endl << "Macro-processing error: backtrace..." << endl << e.trace(); - exit(EXIT_FAILURE); - } - void - warning(const StackTrace &e) const noexcept - { - cerr << endl << "Macro-processing warning: backtrace..." << endl << e.trace(); - } - void - printLineInfo(ostream &output) const noexcept - { - output << R"(@#line ")" << *(location.begin.filename) << R"(" )" << location.begin.line << endl; - } - void - printEndLineInfo(ostream &output) const noexcept - { - // Add one to end line because we want to print the line number of the line *following* the end statement - output << R"(@#line ")" << *(location.begin.filename) << R"(" )" << location.end.line + 1 << endl; - } - }; - - - class Expression : public Node + stringstream ss; + ss << prefix << ": " << location << " " << standard_exception_message; + message = {ss.str()}; + } + StackTrace(const string& prefix, const string& msg, const Tokenizer::location& location) { - public: - explicit Expression(Tokenizer::location location_arg) : - Node(move(location_arg)) { } - virtual string to_string() const noexcept = 0; - virtual void print(ostream &output, bool matlab_output = false) const noexcept = 0; - virtual BaseTypePtr eval(Environment &env) const = 0; - }; - - - class BaseType : public Expression, public enable_shared_from_this + stringstream ss; + ss << prefix << ": " << location << " " << msg; + message = {ss.str()}; + } + void + push(const string& prefix, const Tokenizer::location& location) { - public: - explicit BaseType(Tokenizer::location location_arg = Tokenizer::location()) : - Expression(move(location_arg)) { } - virtual codes::BaseType getType() const noexcept = 0; - BaseTypePtr eval([[maybe_unused]] Environment &env) const override { return const_pointer_cast(shared_from_this()); } - public: - virtual BaseTypePtr plus([[maybe_unused]] const BaseTypePtr &bt) const { throw StackTrace("Operator + does not exist for this type"); } - virtual BaseTypePtr unary_plus() const { throw StackTrace("Unary operator + does not exist for this type"); } - virtual BaseTypePtr minus([[maybe_unused]] const BaseTypePtr &bt) const { throw StackTrace("Operator - does not exist for this type"); } - virtual BaseTypePtr unary_minus() const { throw StackTrace("Unary operator - does not exist for this type"); } - virtual BaseTypePtr times([[maybe_unused]] const BaseTypePtr &bt) const { throw StackTrace("Operator * does not exist for this type"); } - virtual BaseTypePtr divide([[maybe_unused]] const BaseTypePtr &bt) const { throw StackTrace("Operator / does not exist for this type"); } - virtual BaseTypePtr power([[maybe_unused]] const BaseTypePtr &btp) const { throw StackTrace("Operator ^ does not exist for this type"); } - virtual BoolPtr is_less([[maybe_unused]] const BaseTypePtr &btp) const { throw StackTrace("Operator < does not exist for this type"); } - virtual BoolPtr is_greater([[maybe_unused]] const BaseTypePtr &btp) const { throw StackTrace("Operator > does not exist for this type"); } - virtual BoolPtr is_less_equal([[maybe_unused]] const BaseTypePtr &btp) const { throw StackTrace("Operator <= does not exist for this type"); } - virtual BoolPtr is_greater_equal([[maybe_unused]] const BaseTypePtr &btp) const { throw StackTrace("Operator >= does not exist for this type"); } - virtual BoolPtr is_equal(const BaseTypePtr &btp) const = 0; - virtual BoolPtr is_different(const BaseTypePtr &btp) const final; - virtual BoolPtr logical_and([[maybe_unused]] const ExpressionPtr &ep, [[maybe_unused]] Environment &env) const { throw StackTrace("Operator && does not exist for this type"); } - virtual BoolPtr logical_or([[maybe_unused]] const ExpressionPtr &ep, [[maybe_unused]] Environment &env) const { throw StackTrace("Operator || does not exist for this type"); } - virtual BoolPtr logical_not() const { throw StackTrace("Operator ! does not exist for this type"); } - virtual ArrayPtr set_union([[maybe_unused]] const BaseTypePtr &btp) const { throw StackTrace("Operator | does not exist for this type"); } - virtual ArrayPtr set_intersection([[maybe_unused]] const BaseTypePtr &btp) const { throw StackTrace("Operator & does not exist for this type"); } - virtual BoolPtr contains([[maybe_unused]] const BaseTypePtr &btp) const { throw StackTrace("Second argument of `in` operator must be an array"); } - virtual RealPtr length() const { throw StackTrace("Operator `length` does not exist for this type"); } - virtual BoolPtr isempty() const { throw StackTrace("Operator `isempty` does not exist for this type"); } - virtual BoolPtr isboolean() const noexcept { return make_shared(false, location); } - virtual BoolPtr isreal() const noexcept { return make_shared(false, location); } - virtual BoolPtr isinteger() const noexcept { return make_shared(false, location); } - virtual BoolPtr isstring() const noexcept { return make_shared(false, location); } - virtual BoolPtr istuple() const noexcept { return make_shared(false, location); } - virtual BoolPtr isarray() const noexcept { return make_shared(false, location); } - virtual RealPtr max([[maybe_unused]] const BaseTypePtr &btp) const { throw StackTrace("Operator `max` does not exist for this type"); } - virtual RealPtr min([[maybe_unused]] const BaseTypePtr &btp) const { throw StackTrace("Operator `min` does not exist for this type"); } - virtual RealPtr mod([[maybe_unused]] const BaseTypePtr &btp) const { throw StackTrace("Operator `mod` does not exist for this type"); } - virtual RealPtr exp() const { throw StackTrace("Operator `exp` does not exist for this type"); } - virtual RealPtr ln() const { throw StackTrace("Operator `ln` does not exist for this type"); } - virtual RealPtr log10() const { throw StackTrace("Operator `log10` does not exist for this type"); } - virtual BoolPtr isinf() const { throw StackTrace("Operator `isinf` does not exist for this type"); } - virtual BoolPtr isnan() const { throw StackTrace("Operator `isnan` does not exist for this type"); } - virtual BoolPtr isfinite() const { throw StackTrace("Operator `isfinite` does not exist for this type"); } - virtual BoolPtr isnormal() const { throw StackTrace("Operator `isnormal` does not exist for this type"); } - virtual RealPtr sin() const { throw StackTrace("Operator `sin` does not exist for this type"); } - virtual RealPtr cos() const { throw StackTrace("Operator `cos` does not exist for this type"); } - virtual RealPtr tan() const { throw StackTrace("Operator `tan` does not exist for this type"); } - virtual RealPtr asin() const { throw StackTrace("Operator `asin` does not exist for this type"); } - virtual RealPtr acos() const { throw StackTrace("Operator `acos` does not exist for this type"); } - virtual RealPtr atan() const { throw StackTrace("Operator `atan` does not exist for this type"); } - virtual RealPtr sqrt() const { throw StackTrace("Operator `sqrt` does not exist for this type"); } - virtual RealPtr cbrt() const { throw StackTrace("Operator `cbrt` does not exist for this type"); } - virtual RealPtr sign() const { throw StackTrace("Operator `sign` does not exist for this type"); } - virtual RealPtr floor() const { throw StackTrace("Operator `floor` does not exist for this type"); } - virtual RealPtr ceil() const { throw StackTrace("Operator `ceil` does not exist for this type"); } - virtual RealPtr trunc() const { throw StackTrace("Operator `trunc` does not exist for this type"); } - virtual RealPtr sum() const { throw StackTrace("Operator `sum` does not exist for this type"); } - virtual RealPtr erf() const { throw StackTrace("Operator `erf` does not exist for this type"); } - virtual RealPtr erfc() const { throw StackTrace("Operator `erfc` does not exist for this type"); } - virtual RealPtr gamma() const { throw StackTrace("Operator `gamma` does not exist for this type"); } - virtual RealPtr lgamma() const { throw StackTrace("Operator `lgamma` does not exist for this type"); } - virtual RealPtr round() const { throw StackTrace("Operator `round` does not exist for this type"); } - virtual RealPtr normpdf() const { throw StackTrace("Operator `normpdf` does not exist for this type"); } - virtual RealPtr normpdf([[maybe_unused]] const BaseTypePtr &btp1, [[maybe_unused]] const BaseTypePtr &btp2) const { throw StackTrace("Operator `normpdf` does not exist for this type"); } - virtual RealPtr normcdf() const { throw StackTrace("Operator `normcdf` does not exist for this type"); } - virtual RealPtr normcdf([[maybe_unused]] const BaseTypePtr &btp1, [[maybe_unused]] const BaseTypePtr &btp2) const { throw StackTrace("Operator `normcdf` does not exist for this type"); } - virtual BoolPtr cast_bool([[maybe_unused]] Environment &env) const { throw StackTrace("This type cannot be cast to a boolean"); } - virtual RealPtr cast_real([[maybe_unused]] Environment &env) const { throw StackTrace("This type cannot be cast to a real"); } - virtual StringPtr cast_string() const { throw StackTrace("This type cannot be cast to a string"); } - virtual TuplePtr cast_tuple() const { throw StackTrace("This type cannot be cast to a tuple"); } - virtual ArrayPtr cast_array() const { throw StackTrace("This type cannot be cast to an array"); } - virtual BoolPtr defined([[maybe_unused]] const Environment &env) const { throw StackTrace("Operator `defined` does not exist for this type"); } - }; + stringstream ss; + auto end_col = 0 < location.end.column ? location.end.column - 1 : 0; - - class Bool final : public BaseType + ss << prefix << ": " + << R"(")" << *location.begin.filename << R"(" line )" << location.begin.line << ", col " + << location.begin.column; + if (location.end.filename + && (!location.begin.filename || *location.begin.filename != *location.end.filename)) + ss << R"( to ")" << location.end.filename << R"(")" + << " line " << location.end.line << ", col " << end_col; + else if (location.begin.line < location.end.line) + ss << " to line " << location.end.line << ", col " << end_col; + else if (location.begin.column < end_col) + ss << "-" << end_col; + message.emplace_back(ss.str()); + } + string + trace() const { - private: - const bool value; - public: - Bool(bool value_arg, - Tokenizer::location location_arg = Tokenizer::location()) : + stringstream ss; + for (auto& msg : message) + ss << "- " << msg << endl; + return ss.str(); + } +}; + +class Node +{ +protected: + const Tokenizer::location location; + +public: + explicit Node(Tokenizer::location location_arg) : location {move(location_arg)} + { + } + virtual ~Node() = default; + +public: + Tokenizer::location + getLocation() const noexcept + { + return location; + } + void + error(const StackTrace& e) const noexcept + { + cerr << endl << "Macro-processing error: backtrace..." << endl << e.trace(); + exit(EXIT_FAILURE); + } + void + warning(const StackTrace& e) const noexcept + { + cerr << endl << "Macro-processing warning: backtrace..." << endl << e.trace(); + } + void + printLineInfo(ostream& output) const noexcept + { + output << R"(@#line ")" << *(location.begin.filename) << R"(" )" << location.begin.line << endl; + } + void + printEndLineInfo(ostream& output) const noexcept + { + // Add one to end line because we want to print the line number of the line *following* the end + // statement + output << R"(@#line ")" << *(location.begin.filename) << R"(" )" << location.end.line + 1 + << endl; + } +}; + +class Expression : public Node +{ +public: + explicit Expression(Tokenizer::location location_arg) : Node(move(location_arg)) + { + } + virtual string to_string() const noexcept = 0; + virtual void print(ostream& output, bool matlab_output = false) const noexcept = 0; + virtual BaseTypePtr eval(Environment& env) const = 0; +}; + +class BaseType : public Expression, public enable_shared_from_this +{ +public: + explicit BaseType(Tokenizer::location location_arg = Tokenizer::location()) : + Expression(move(location_arg)) + { + } + virtual codes::BaseType getType() const noexcept = 0; + BaseTypePtr + eval([[maybe_unused]] Environment& env) const override + { + return const_pointer_cast(shared_from_this()); + } + +public: + virtual BaseTypePtr + plus([[maybe_unused]] const BaseTypePtr& bt) const + { + throw StackTrace("Operator + does not exist for this type"); + } + virtual BaseTypePtr + unary_plus() const + { + throw StackTrace("Unary operator + does not exist for this type"); + } + virtual BaseTypePtr + minus([[maybe_unused]] const BaseTypePtr& bt) const + { + throw StackTrace("Operator - does not exist for this type"); + } + virtual BaseTypePtr + unary_minus() const + { + throw StackTrace("Unary operator - does not exist for this type"); + } + virtual BaseTypePtr + times([[maybe_unused]] const BaseTypePtr& bt) const + { + throw StackTrace("Operator * does not exist for this type"); + } + virtual BaseTypePtr + divide([[maybe_unused]] const BaseTypePtr& bt) const + { + throw StackTrace("Operator / does not exist for this type"); + } + virtual BaseTypePtr + power([[maybe_unused]] const BaseTypePtr& btp) const + { + throw StackTrace("Operator ^ does not exist for this type"); + } + virtual BoolPtr + is_less([[maybe_unused]] const BaseTypePtr& btp) const + { + throw StackTrace("Operator < does not exist for this type"); + } + virtual BoolPtr + is_greater([[maybe_unused]] const BaseTypePtr& btp) const + { + throw StackTrace("Operator > does not exist for this type"); + } + virtual BoolPtr + is_less_equal([[maybe_unused]] const BaseTypePtr& btp) const + { + throw StackTrace("Operator <= does not exist for this type"); + } + virtual BoolPtr + is_greater_equal([[maybe_unused]] const BaseTypePtr& btp) const + { + throw StackTrace("Operator >= does not exist for this type"); + } + virtual BoolPtr is_equal(const BaseTypePtr& btp) const = 0; + virtual BoolPtr is_different(const BaseTypePtr& btp) const final; + virtual BoolPtr + logical_and([[maybe_unused]] const ExpressionPtr& ep, [[maybe_unused]] Environment& env) const + { + throw StackTrace("Operator && does not exist for this type"); + } + virtual BoolPtr + logical_or([[maybe_unused]] const ExpressionPtr& ep, [[maybe_unused]] Environment& env) const + { + throw StackTrace("Operator || does not exist for this type"); + } + virtual BoolPtr + logical_not() const + { + throw StackTrace("Operator ! does not exist for this type"); + } + virtual ArrayPtr + set_union([[maybe_unused]] const BaseTypePtr& btp) const + { + throw StackTrace("Operator | does not exist for this type"); + } + virtual ArrayPtr + set_intersection([[maybe_unused]] const BaseTypePtr& btp) const + { + throw StackTrace("Operator & does not exist for this type"); + } + virtual BoolPtr + contains([[maybe_unused]] const BaseTypePtr& btp) const + { + throw StackTrace("Second argument of `in` operator must be an array"); + } + virtual RealPtr + length() const + { + throw StackTrace("Operator `length` does not exist for this type"); + } + virtual BoolPtr + isempty() const + { + throw StackTrace("Operator `isempty` does not exist for this type"); + } + virtual BoolPtr + isboolean() const noexcept + { + return make_shared(false, location); + } + virtual BoolPtr + isreal() const noexcept + { + return make_shared(false, location); + } + virtual BoolPtr + isinteger() const noexcept + { + return make_shared(false, location); + } + virtual BoolPtr + isstring() const noexcept + { + return make_shared(false, location); + } + virtual BoolPtr + istuple() const noexcept + { + return make_shared(false, location); + } + virtual BoolPtr + isarray() const noexcept + { + return make_shared(false, location); + } + virtual RealPtr + max([[maybe_unused]] const BaseTypePtr& btp) const + { + throw StackTrace("Operator `max` does not exist for this type"); + } + virtual RealPtr + min([[maybe_unused]] const BaseTypePtr& btp) const + { + throw StackTrace("Operator `min` does not exist for this type"); + } + virtual RealPtr + mod([[maybe_unused]] const BaseTypePtr& btp) const + { + throw StackTrace("Operator `mod` does not exist for this type"); + } + virtual RealPtr + exp() const + { + throw StackTrace("Operator `exp` does not exist for this type"); + } + virtual RealPtr + ln() const + { + throw StackTrace("Operator `ln` does not exist for this type"); + } + virtual RealPtr + log10() const + { + throw StackTrace("Operator `log10` does not exist for this type"); + } + virtual BoolPtr + isinf() const + { + throw StackTrace("Operator `isinf` does not exist for this type"); + } + virtual BoolPtr + isnan() const + { + throw StackTrace("Operator `isnan` does not exist for this type"); + } + virtual BoolPtr + isfinite() const + { + throw StackTrace("Operator `isfinite` does not exist for this type"); + } + virtual BoolPtr + isnormal() const + { + throw StackTrace("Operator `isnormal` does not exist for this type"); + } + virtual RealPtr + sin() const + { + throw StackTrace("Operator `sin` does not exist for this type"); + } + virtual RealPtr + cos() const + { + throw StackTrace("Operator `cos` does not exist for this type"); + } + virtual RealPtr + tan() const + { + throw StackTrace("Operator `tan` does not exist for this type"); + } + virtual RealPtr + asin() const + { + throw StackTrace("Operator `asin` does not exist for this type"); + } + virtual RealPtr + acos() const + { + throw StackTrace("Operator `acos` does not exist for this type"); + } + virtual RealPtr + atan() const + { + throw StackTrace("Operator `atan` does not exist for this type"); + } + virtual RealPtr + sqrt() const + { + throw StackTrace("Operator `sqrt` does not exist for this type"); + } + virtual RealPtr + cbrt() const + { + throw StackTrace("Operator `cbrt` does not exist for this type"); + } + virtual RealPtr + sign() const + { + throw StackTrace("Operator `sign` does not exist for this type"); + } + virtual RealPtr + floor() const + { + throw StackTrace("Operator `floor` does not exist for this type"); + } + virtual RealPtr + ceil() const + { + throw StackTrace("Operator `ceil` does not exist for this type"); + } + virtual RealPtr + trunc() const + { + throw StackTrace("Operator `trunc` does not exist for this type"); + } + virtual RealPtr + sum() const + { + throw StackTrace("Operator `sum` does not exist for this type"); + } + virtual RealPtr + erf() const + { + throw StackTrace("Operator `erf` does not exist for this type"); + } + virtual RealPtr + erfc() const + { + throw StackTrace("Operator `erfc` does not exist for this type"); + } + virtual RealPtr + gamma() const + { + throw StackTrace("Operator `gamma` does not exist for this type"); + } + virtual RealPtr + lgamma() const + { + throw StackTrace("Operator `lgamma` does not exist for this type"); + } + virtual RealPtr + round() const + { + throw StackTrace("Operator `round` does not exist for this type"); + } + virtual RealPtr + normpdf() const + { + throw StackTrace("Operator `normpdf` does not exist for this type"); + } + virtual RealPtr + normpdf([[maybe_unused]] const BaseTypePtr& btp1, [[maybe_unused]] const BaseTypePtr& btp2) const + { + throw StackTrace("Operator `normpdf` does not exist for this type"); + } + virtual RealPtr + normcdf() const + { + throw StackTrace("Operator `normcdf` does not exist for this type"); + } + virtual RealPtr + normcdf([[maybe_unused]] const BaseTypePtr& btp1, [[maybe_unused]] const BaseTypePtr& btp2) const + { + throw StackTrace("Operator `normcdf` does not exist for this type"); + } + virtual BoolPtr + cast_bool([[maybe_unused]] Environment& env) const + { + throw StackTrace("This type cannot be cast to a boolean"); + } + virtual RealPtr + cast_real([[maybe_unused]] Environment& env) const + { + throw StackTrace("This type cannot be cast to a real"); + } + virtual StringPtr + cast_string() const + { + throw StackTrace("This type cannot be cast to a string"); + } + virtual TuplePtr + cast_tuple() const + { + throw StackTrace("This type cannot be cast to a tuple"); + } + virtual ArrayPtr + cast_array() const + { + throw StackTrace("This type cannot be cast to an array"); + } + virtual BoolPtr + defined([[maybe_unused]] const Environment& env) const + { + throw StackTrace("Operator `defined` does not exist for this type"); + } +}; + +class Bool final : public BaseType +{ +private: + const bool value; + +public: + Bool(bool value_arg, Tokenizer::location location_arg = Tokenizer::location()) : + BaseType(move(location_arg)), value {value_arg} + { + } + codes::BaseType + getType() const noexcept override + { + return codes::BaseType::Bool; + } + string + to_string() const noexcept override + { + return value ? "true" : "false"; + } + void + print(ostream& output, [[maybe_unused]] bool matlab_output = false) const noexcept override + { + output << to_string(); + } + +public: + operator bool() const + { + return value; + } + BoolPtr is_equal(const BaseTypePtr& btp) const override; + BoolPtr logical_and(const ExpressionPtr& ep, Environment& env) const override; + BoolPtr logical_or(const ExpressionPtr& ep, Environment& env) const override; + BoolPtr logical_not() const override; + BoolPtr + isboolean() const noexcept override + { + return make_shared(true, location); + } + BoolPtr + cast_bool([[maybe_unused]] Environment& env) const override + { + return make_shared(value); + } + RealPtr + cast_real([[maybe_unused]] Environment& env) const override + { + return value ? make_shared(1) : make_shared(0); + } + StringPtr + cast_string() const override + { + return make_shared(this->to_string()); + } + TuplePtr + cast_tuple() const override + { + return make_shared(vector {make_shared(value)}); + } + ArrayPtr + cast_array() const override + { + return make_shared(vector {make_shared(value)}); + } +}; + +class Real final : public BaseType +{ +private: + const double value; + +public: + // Use strtod to handle extreme cases (e.g. 1e500, 1e-500), nan, inf + // See Note in NumericalConstants::AddNonNegativeConstant + Real(const string& value_arg, Tokenizer::location location_arg = Tokenizer::location()) : + BaseType(move(location_arg)), value {strtod(value_arg.c_str(), nullptr)} + { + } + Real(double value_arg, Tokenizer::location location_arg = Tokenizer::location()) : + BaseType(move(location_arg)), value {value_arg} + { + } + codes::BaseType + getType() const noexcept override + { + return codes::BaseType::Real; + } + string + to_string() const noexcept override + { + ostringstream strs; + strs << setprecision(15) << value; + return strs.str(); + } + void + print(ostream& output, [[maybe_unused]] bool matlab_output = false) const noexcept override + { + output << to_string(); + } + +public: + operator double() const + { + return value; + } + BaseTypePtr plus(const BaseTypePtr& bt) const override; + BaseTypePtr + unary_plus() const override + { + return make_shared(value); + } + BaseTypePtr minus(const BaseTypePtr& bt) const override; + BaseTypePtr + unary_minus() const override + { + return make_shared(-value); + } + BaseTypePtr times(const BaseTypePtr& bt) const override; + BaseTypePtr divide(const BaseTypePtr& bt) const override; + BaseTypePtr power(const BaseTypePtr& btp) const override; + BoolPtr is_less(const BaseTypePtr& btp) const override; + BoolPtr is_greater(const BaseTypePtr& btp) const override; + BoolPtr is_less_equal(const BaseTypePtr& btp) const override; + BoolPtr is_greater_equal(const BaseTypePtr& btp) const override; + BoolPtr is_equal(const BaseTypePtr& btp) const override; + BoolPtr + isreal() const noexcept override + { + return make_shared(true, location); + } + BoolPtr + isinteger() const noexcept override + { + double intpart; + return make_shared(modf(value, &intpart) == 0.0, location); + } + BoolPtr logical_and(const ExpressionPtr& ep, Environment& env) const override; + BoolPtr logical_or(const ExpressionPtr& ep, Environment& env) const override; + BoolPtr logical_not() const override; + RealPtr max(const BaseTypePtr& btp) const override; + RealPtr min(const BaseTypePtr& btp) const override; + RealPtr mod(const BaseTypePtr& btp) const override; + RealPtr + exp() const override + { + return make_shared(std::exp(value)); + } + RealPtr + ln() const override + { + return make_shared(std::log(value)); + } + RealPtr + log10() const override + { + return make_shared(std::log10(value)); + } + BoolPtr + isinf() const override + { + return make_shared(std::isinf(value)); + } + BoolPtr + isnan() const override + { + return make_shared(std::isnan(value)); + } + BoolPtr + isfinite() const override + { + return make_shared(std::isfinite(value)); + } + BoolPtr + isnormal() const override + { + return make_shared(std::isnormal(value)); + } + RealPtr + sin() const override + { + return make_shared(std::sin(value)); + } + RealPtr + cos() const override + { + return make_shared(std::cos(value)); + } + RealPtr + tan() const override + { + return make_shared(std::tan(value)); + } + RealPtr + asin() const override + { + return make_shared(std::asin(value)); + } + RealPtr + acos() const override + { + return make_shared(std::acos(value)); + } + RealPtr + atan() const override + { + return make_shared(std::atan(value)); + } + RealPtr + sqrt() const override + { + return make_shared(std::sqrt(value)); + } + RealPtr + cbrt() const override + { + return make_shared(std::cbrt(value)); + } + RealPtr + sign() const override + { + return make_shared((value > 0) ? 1. : ((value < 0) ? -1. : 0.)); + } + RealPtr + floor() const override + { + return make_shared(std::floor(value)); + } + RealPtr + ceil() const override + { + return make_shared(std::ceil(value)); + } + RealPtr + trunc() const override + { + return make_shared(std::trunc(value)); + } + RealPtr + erf() const override + { + return make_shared(std::erf(value)); + } + RealPtr + erfc() const override + { + return make_shared(std::erfc(value)); + } + RealPtr + gamma() const override + { + return make_shared(std::tgamma(value)); + } + RealPtr + lgamma() const override + { + return make_shared(std::lgamma(value)); + } + RealPtr + round() const override + { + return make_shared(std::round(value)); + } + RealPtr + normpdf() const override + { + return normpdf(make_shared(0), make_shared(1)); + } + RealPtr normpdf(const BaseTypePtr& btp1, const BaseTypePtr& btp2) const override; + RealPtr + normcdf() const override + { + return normcdf(make_shared(0), make_shared(1)); + } + RealPtr normcdf(const BaseTypePtr& btp1, const BaseTypePtr& btp2) const override; + BoolPtr + cast_bool([[maybe_unused]] Environment& env) const override + { + return make_shared(static_cast(value)); + } + RealPtr + cast_real([[maybe_unused]] Environment& env) const override + { + return make_shared(value); + } + StringPtr + cast_string() const override + { + return make_shared(this->to_string()); + } + TuplePtr + cast_tuple() const override + { + return make_shared(vector {make_shared(value)}); + } + ArrayPtr + cast_array() const override + { + return make_shared(vector {make_shared(value)}); + } +}; + +class String final : public BaseType +{ +private: + const string value; + +public: + String(string value_arg, Tokenizer::location location_arg = Tokenizer::location()) : + BaseType(move(location_arg)), value {move(value_arg)} + { + } + codes::BaseType + getType() const noexcept override + { + return codes::BaseType::String; + } + string + to_string() const noexcept override + { + return value; + } + void print(ostream& output, bool matlab_output = false) const noexcept override; + +public: + operator string() const + { + return value; + } + BaseTypePtr plus(const BaseTypePtr& bt) const override; + BoolPtr is_less(const BaseTypePtr& btp) const override; + BoolPtr is_greater(const BaseTypePtr& btp) const override; + BoolPtr is_less_equal(const BaseTypePtr& btp) const override; + BoolPtr is_greater_equal(const BaseTypePtr& btp) const override; + BoolPtr is_equal(const BaseTypePtr& btp) const override; + BoolPtr + isstring() const noexcept override + { + return make_shared(true, location); + } + RealPtr + length() const override + { + return make_shared(value.size()); + } + BoolPtr + isempty() const override + { + return make_shared(value.empty()); + } + BoolPtr cast_bool(Environment& env) const override; + RealPtr cast_real(Environment& env) const override; + StringPtr + cast_string() const override + { + return make_shared(value); + } + TuplePtr + cast_tuple() const override + { + return make_shared(vector {make_shared(value)}); + } + ArrayPtr + cast_array() const override + { + return make_shared(vector {make_shared(value)}); + } + BoolPtr + defined(const Environment& env) const override + { + return make_shared(env.isSymbolDefined(value)); + } +}; + +class Tuple final : public BaseType +{ +private: + const vector tup; + +public: + Tuple(vector tup_arg, Tokenizer::location location_arg = Tokenizer::location()) : + BaseType(move(location_arg)), tup {move(tup_arg)} + { + } + codes::BaseType + getType() const noexcept override + { + return codes::BaseType::Tuple; + } + string to_string() const noexcept override; + void print(ostream& output, bool matlab_output = false) const noexcept override; + BaseTypePtr eval(Environment& env) const override; + +public: + size_t + size() const + { + return tup.size(); + } + bool + empty() const + { + return tup.empty(); + } + const vector& + getValue() const + { + return tup; + } + const ExpressionPtr& + at(int i) const + { + return tup.at(i); + } + BoolPtr is_equal(const BaseTypePtr& btp) const override; + BoolPtr + istuple() const noexcept override + { + return make_shared(true, location); + } + BoolPtr contains(const BaseTypePtr& btp) const override; + RealPtr + length() const override + { + return make_shared(tup.size()); + } + BoolPtr + isempty() const override + { + return make_shared(empty()); + } + BoolPtr cast_bool(Environment& env) const override; + RealPtr cast_real(Environment& env) const override; + StringPtr + cast_string() const override + { + return make_shared(this->to_string()); + } + TuplePtr + cast_tuple() const override + { + return make_shared(tup); + } + ArrayPtr + cast_array() const override + { + return make_shared(tup); + } +}; + +class Array final : public BaseType +{ +private: + const vector arr; + +public: + Array(vector arr_arg, Tokenizer::location location_arg = Tokenizer::location()) : + BaseType(move(location_arg)), arr {move(arr_arg)} + { + } + codes::BaseType + getType() const noexcept override + { + return codes::BaseType::Array; + } + string to_string() const noexcept override; + void print(ostream& output, bool matlab_output = false) const noexcept override; + BaseTypePtr eval(Environment& env) const override; + +public: + size_t + size() const + { + return arr.size(); + } + const vector& + getValue() const + { + return arr; + } + const ExpressionPtr& + at(int i) const + { + return arr.at(i); + } + bool + empty() const + { + return arr.empty(); + } + BaseTypePtr plus(const BaseTypePtr& bt) const override; + BaseTypePtr minus(const BaseTypePtr& bt) const override; + BaseTypePtr times(const BaseTypePtr& bt) const override; + BaseTypePtr power(const BaseTypePtr& btp) const override; + BoolPtr is_equal(const BaseTypePtr& btp) const override; + BoolPtr + isarray() const noexcept override + { + return make_shared(true, location); + } + ArrayPtr set_union(const BaseTypePtr& btp) const override; + ArrayPtr set_intersection(const BaseTypePtr& btp) const override; + BoolPtr contains(const BaseTypePtr& btp) const override; + RealPtr + length() const override + { + return make_shared(arr.size()); + } + BoolPtr + isempty() const override + { + return make_shared(empty()); + } + RealPtr sum() const override; + BoolPtr cast_bool(Environment& env) const override; + RealPtr cast_real(Environment& env) const override; + StringPtr + cast_string() const override + { + return make_shared(this->to_string()); + } + TuplePtr + cast_tuple() const override + { + return make_shared(arr); + } + ArrayPtr + cast_array() const override + { + return make_shared(arr); + } +}; + +class Range final : public BaseType +{ +private: + const ExpressionPtr start, inc, end; + +public: + Range(ExpressionPtr start_arg, ExpressionPtr end_arg, Tokenizer::location location_arg) : + BaseType(move(location_arg)), start {move(start_arg)}, end {move(end_arg)} + { + } + Range(ExpressionPtr start_arg, ExpressionPtr inc_arg, ExpressionPtr end_arg, + Tokenizer::location location_arg) : BaseType(move(location_arg)), - value{value_arg} { } - codes::BaseType getType() const noexcept override { return codes::BaseType::Bool; } - string to_string() const noexcept override { return value ? "true" : "false"; } - void print(ostream &output, [[maybe_unused]] bool matlab_output = false) const noexcept override { output << to_string(); } - public: - operator bool() const { return value; } - BoolPtr is_equal(const BaseTypePtr &btp) const override; - BoolPtr logical_and(const ExpressionPtr &ep, Environment &env) const override; - BoolPtr logical_or(const ExpressionPtr &ep, Environment &env) const override; - BoolPtr logical_not() const override; - BoolPtr isboolean() const noexcept override { return make_shared(true, location); } - BoolPtr cast_bool([[maybe_unused]] Environment &env) const override { return make_shared(value); } - RealPtr cast_real([[maybe_unused]] Environment &env) const override { return value ? make_shared(1) : make_shared(0); } - StringPtr cast_string() const override { return make_shared(this->to_string()); } - TuplePtr - cast_tuple() const override - { - return make_shared(vector{make_shared(value)}); - } - ArrayPtr - cast_array() const override - { - return make_shared(vector{make_shared(value)}); - } - }; - - - class Real final : public BaseType + start {move(start_arg)}, + inc {move(inc_arg)}, + end {move(end_arg)} { - private: - const double value; - public: - // Use strtod to handle extreme cases (e.g. 1e500, 1e-500), nan, inf - // See Note in NumericalConstants::AddNonNegativeConstant - Real(const string &value_arg, - Tokenizer::location location_arg = Tokenizer::location()) : - BaseType(move(location_arg)), - value{strtod(value_arg.c_str(), nullptr)} { } - Real(double value_arg, - Tokenizer::location location_arg = Tokenizer::location()) : - BaseType(move(location_arg)), - value{value_arg} { } - codes::BaseType getType() const noexcept override { return codes::BaseType::Real; } - string - to_string() const noexcept override - { - ostringstream strs; - strs << setprecision(15) << value; - return strs.str(); - } - void print(ostream &output, [[maybe_unused]] bool matlab_output = false) const noexcept override { output << to_string(); } - public: - operator double() const { return value; } - BaseTypePtr plus(const BaseTypePtr &bt) const override; - BaseTypePtr unary_plus() const override { return make_shared(value); } - BaseTypePtr minus(const BaseTypePtr &bt) const override; - BaseTypePtr unary_minus() const override { return make_shared(-value); } - BaseTypePtr times(const BaseTypePtr &bt) const override; - BaseTypePtr divide(const BaseTypePtr &bt) const override; - BaseTypePtr power(const BaseTypePtr &btp) const override; - BoolPtr is_less(const BaseTypePtr &btp) const override; - BoolPtr is_greater(const BaseTypePtr &btp) const override; - BoolPtr is_less_equal(const BaseTypePtr &btp) const override; - BoolPtr is_greater_equal(const BaseTypePtr &btp) const override; - BoolPtr is_equal(const BaseTypePtr &btp) const override; - BoolPtr isreal() const noexcept override { return make_shared(true, location); } - BoolPtr isinteger() const noexcept override - { - double intpart; - return make_shared(modf(value, &intpart) == 0.0, location); - } - BoolPtr logical_and(const ExpressionPtr &ep, Environment &env) const override; - BoolPtr logical_or(const ExpressionPtr &ep, Environment &env) const override; - BoolPtr logical_not() const override; - RealPtr max(const BaseTypePtr &btp) const override; - RealPtr min(const BaseTypePtr &btp) const override; - RealPtr mod(const BaseTypePtr &btp) const override; - RealPtr exp() const override { return make_shared(std::exp(value)); } - RealPtr ln() const override { return make_shared(std::log(value)); } - RealPtr log10() const override { return make_shared(std::log10(value)); } - BoolPtr isinf() const override { return make_shared(std::isinf(value)); } - BoolPtr isnan() const override { return make_shared(std::isnan(value)); } - BoolPtr isfinite() const override { return make_shared(std::isfinite(value)); } - BoolPtr isnormal() const override { return make_shared(std::isnormal(value)); } - RealPtr sin() const override { return make_shared(std::sin(value)); } - RealPtr cos() const override { return make_shared(std::cos(value)); } - RealPtr tan() const override { return make_shared(std::tan(value)); } - RealPtr asin() const override { return make_shared(std::asin(value)); } - RealPtr acos() const override { return make_shared(std::acos(value)); } - RealPtr atan() const override { return make_shared(std::atan(value)); } - RealPtr sqrt() const override { return make_shared(std::sqrt(value)); } - RealPtr cbrt() const override { return make_shared(std::cbrt(value)); } - RealPtr - sign() const override - { - return make_shared((value > 0) ? 1. : ((value < 0) ? -1. : 0.)); - } - RealPtr floor() const override { return make_shared(std::floor(value)); } - RealPtr ceil() const override { return make_shared(std::ceil(value)); } - RealPtr trunc() const override { return make_shared(std::trunc(value)); } - RealPtr erf() const override { return make_shared(std::erf(value)); } - RealPtr erfc() const override { return make_shared(std::erfc(value)); } - RealPtr gamma() const override { return make_shared(std::tgamma(value)); } - RealPtr lgamma() const override { return make_shared(std::lgamma(value)); } - RealPtr round() const override { return make_shared(std::round(value)); } - RealPtr - normpdf() const override - { - return normpdf(make_shared(0), make_shared(1)); - } - RealPtr normpdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const override; - RealPtr - normcdf() const override - { - return normcdf(make_shared(0), make_shared(1)); - } - RealPtr normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const override; - BoolPtr cast_bool([[maybe_unused]] Environment &env) const override { return make_shared(static_cast(value)); } - RealPtr cast_real([[maybe_unused]] Environment &env) const override { return make_shared(value); } - StringPtr cast_string() const override { return make_shared(this->to_string()); } - TuplePtr - cast_tuple() const override - { - return make_shared(vector{make_shared(value)}); - } - ArrayPtr - cast_array() const override - { - return make_shared(vector{make_shared(value)}); - } - }; - - class String final : public BaseType + } + codes::BaseType + getType() const noexcept override { - private: - const string value; - public: - String(string value_arg, - Tokenizer::location location_arg = Tokenizer::location()) : - BaseType(move(location_arg)), - value{move(value_arg)} { } - codes::BaseType getType() const noexcept override { return codes::BaseType::String; } - string to_string() const noexcept override { return value; } - void print(ostream &output, bool matlab_output = false) const noexcept override; - public: - operator string() const { return value; } - BaseTypePtr plus(const BaseTypePtr &bt) const override; - BoolPtr is_less(const BaseTypePtr &btp) const override; - BoolPtr is_greater(const BaseTypePtr &btp) const override; - BoolPtr is_less_equal(const BaseTypePtr &btp) const override; - BoolPtr is_greater_equal(const BaseTypePtr &btp) const override; - BoolPtr is_equal(const BaseTypePtr &btp) const override; - BoolPtr isstring() const noexcept override { return make_shared(true, location); } - RealPtr length() const override { return make_shared(value.size()); } - BoolPtr isempty() const override { return make_shared(value.empty()); } - BoolPtr cast_bool(Environment &env) const override; - RealPtr cast_real(Environment &env) const override; - StringPtr cast_string() const override { return make_shared(value); } - TuplePtr - cast_tuple() const override - { - return make_shared(vector{make_shared(value)}); - } - ArrayPtr - cast_array() const override - { - return make_shared(vector{make_shared(value)}); - } - BoolPtr - defined(const Environment &env) const override - { - return make_shared(env.isSymbolDefined(value)); - } - }; - - - class Tuple final : public BaseType + return codes::BaseType::Range; + } + string + to_string() const noexcept override { - private: - const vector tup; - public: - Tuple(vector tup_arg, - Tokenizer::location location_arg = Tokenizer::location()) : - BaseType(move(location_arg)), - tup{move(tup_arg)} { } - codes::BaseType getType() const noexcept override { return codes::BaseType::Tuple; } - string to_string() const noexcept override; - void print(ostream &output, bool matlab_output = false) const noexcept override; - BaseTypePtr eval(Environment &env) const override; - public: - size_t size() const { return tup.size(); } - bool empty() const { return tup.empty(); } - const vector &getValue() const { return tup; } - const ExpressionPtr &at(int i) const { return tup.at(i); } - BoolPtr is_equal(const BaseTypePtr &btp) const override; - BoolPtr istuple() const noexcept override { return make_shared(true, location); } - BoolPtr contains(const BaseTypePtr &btp) const override; - RealPtr length() const override { return make_shared(tup.size()); } - BoolPtr isempty() const override { return make_shared(empty()); } - BoolPtr cast_bool(Environment &env) const override; - RealPtr cast_real(Environment &env) const override; - StringPtr cast_string() const override { return make_shared(this->to_string()); } - TuplePtr cast_tuple() const override { return make_shared(tup); } - ArrayPtr cast_array() const override { return make_shared(tup); } - }; - - - class Array final : public BaseType + string retval = "[" + start->to_string() + ":"; + if (inc) + retval += inc->to_string() + ":"; + return retval + end->to_string() + "]"; + } + void + print(ostream& output, [[maybe_unused]] bool matlab_output = false) const noexcept override { - private: - const vector arr; - public: - Array(vector arr_arg, - Tokenizer::location location_arg = Tokenizer::location()) : - BaseType(move(location_arg)), arr{move(arr_arg)} { } - codes::BaseType getType() const noexcept override { return codes::BaseType::Array; } - string to_string() const noexcept override; - void print(ostream &output, bool matlab_output = false) const noexcept override; - BaseTypePtr eval(Environment &env) const override; - public: - size_t size() const { return arr.size(); } - const vector &getValue() const { return arr; } - const ExpressionPtr &at(int i) const { return arr.at(i); } - bool empty() const { return arr.empty(); } - BaseTypePtr plus(const BaseTypePtr &bt) const override; - BaseTypePtr minus(const BaseTypePtr &bt) const override; - BaseTypePtr times(const BaseTypePtr &bt) const override; - BaseTypePtr power(const BaseTypePtr &btp) const override; - BoolPtr is_equal(const BaseTypePtr &btp) const override; - BoolPtr isarray() const noexcept override { return make_shared(true, location); } - ArrayPtr set_union(const BaseTypePtr &btp) const override; - ArrayPtr set_intersection(const BaseTypePtr &btp) const override; - BoolPtr contains(const BaseTypePtr &btp) const override; - RealPtr length() const override { return make_shared(arr.size()); } - BoolPtr isempty() const override { return make_shared(empty()); } - RealPtr sum() const override; - BoolPtr cast_bool(Environment &env) const override; - RealPtr cast_real(Environment &env) const override; - StringPtr cast_string() const override { return make_shared(this->to_string()); } - TuplePtr cast_tuple() const override { return make_shared(arr); } - ArrayPtr cast_array() const override { return make_shared(arr); } - }; + output << to_string(); + } + BaseTypePtr eval(Environment& env) const override; - - class Range final : public BaseType +public: + BoolPtr + is_equal([[maybe_unused]] const BaseTypePtr& btp) const override { - private: - const ExpressionPtr start, inc, end; - public: - Range(ExpressionPtr start_arg, ExpressionPtr end_arg, - Tokenizer::location location_arg) : - BaseType(move(location_arg)), start{move(start_arg)}, end{move(end_arg)} { } - Range(ExpressionPtr start_arg, ExpressionPtr inc_arg, ExpressionPtr end_arg, - Tokenizer::location location_arg) : - BaseType(move(location_arg)), - start{move(start_arg)}, inc{move(inc_arg)}, end{move(end_arg)} { } - codes::BaseType getType() const noexcept override { return codes::BaseType::Range; } - string - to_string() const noexcept override - { - string retval = "[" + start->to_string() + ":"; - if (inc) - retval += inc->to_string() + ":"; - return retval + end->to_string() + "]"; - } - void print(ostream &output, [[maybe_unused]] bool matlab_output = false) const noexcept override { output << to_string(); } - BaseTypePtr eval(Environment &env) const override; - public: - BoolPtr - is_equal([[maybe_unused]] const BaseTypePtr &btp) const override - { - throw StackTrace("Internal error: Range: Should not arrive here: is_equal"); - } - }; + throw StackTrace("Internal error: Range: Should not arrive here: is_equal"); + } +}; - - class Variable final : public Expression +class Variable final : public Expression +{ +private: + const string name; + const ArrayPtr indices; // for indexing strings/arrays +public: + Variable(string name_arg, Tokenizer::location location_arg) : + Expression(move(location_arg)), name {move(name_arg)} { - private: - const string name; - const ArrayPtr indices; // for indexing strings/arrays - public: - Variable(string name_arg, - Tokenizer::location location_arg) : - Expression(move(location_arg)), name{move(name_arg)} { } - Variable(string name_arg, ArrayPtr indices_arg, - Tokenizer::location location_arg) : - Expression(move(location_arg)), name{move(name_arg)}, indices{move(indices_arg)} { } - string to_string() const noexcept override { return name; } - void print(ostream &output, [[maybe_unused]] bool matlab_output = false) const noexcept override { output << name; } - BaseTypePtr eval(Environment &env) const override; - public: - const string &getName() const noexcept { return name; } - codes::BaseType getType(const Environment &env) const { return env.getType(name); } - }; - - - class Function final : public Expression + } + Variable(string name_arg, ArrayPtr indices_arg, Tokenizer::location location_arg) : + Expression(move(location_arg)), name {move(name_arg)}, indices {move(indices_arg)} { - private: - const string name; - const vector args; - public: - Function(string name_arg, - vector args_arg, - Tokenizer::location location_arg) : - Expression(move(location_arg)), name{move(name_arg)}, args{move(args_arg)} { } - string to_string() const noexcept override; - void - print(ostream &output, [[maybe_unused]] bool matlab_output = false) const noexcept override - { - printName(output); printArgs(output); - } - BaseTypePtr eval(Environment &env) const override; - public: - void printName(ostream &output) const noexcept { output << name; } - void printArgs(ostream &output) const noexcept; - const string &getName() const { return name; } - const vector &getArgs() const { return args; } - }; - - - class UnaryOp final : public Expression + } + string + to_string() const noexcept override { - private: - const codes::UnaryOp op_code; - const ExpressionPtr arg; - 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)} { } - string to_string() const noexcept override; - void print(ostream &output, bool matlab_output = false) const noexcept override; - BaseTypePtr eval(Environment &env) const override; - }; - - - class BinaryOp final : public Expression + return name; + } + void + print(ostream& output, [[maybe_unused]] bool matlab_output = false) const noexcept override { - private: - const codes::BinaryOp op_code; - const ExpressionPtr arg1, arg2; - public: - BinaryOp(codes::BinaryOp op_code_arg, - ExpressionPtr arg1_arg, ExpressionPtr arg2_arg, - Tokenizer::location location_arg) : - Expression(move(location_arg)), op_code{op_code_arg}, - arg1{move(arg1_arg)}, arg2{move(arg2_arg)} { } - public: - string to_string() const noexcept override; - void print(ostream &output, bool matlab_output = false) const noexcept override; - BaseTypePtr eval(Environment &env) const override; - }; + output << name; + } + BaseTypePtr eval(Environment& env) const override; - - class TrinaryOp final : public Expression +public: + const string& + getName() const noexcept { - private: - const codes::TrinaryOp op_code; - const ExpressionPtr arg1, arg2, arg3; - public: - TrinaryOp(codes::TrinaryOp op_code_arg, - ExpressionPtr arg1_arg, ExpressionPtr arg2_arg, ExpressionPtr arg3_arg, - Tokenizer::location location_arg) : - Expression(move(location_arg)), op_code{op_code_arg}, - arg1{move(arg1_arg)}, arg2{move(arg2_arg)}, arg3{move(arg3_arg)} { } - string to_string() const noexcept override; - void print(ostream &output, bool matlab_output = false) const noexcept override; - BaseTypePtr eval(Environment &env) const override; - }; - - - class Comprehension final : public Expression + return name; + } + codes::BaseType + getType(const Environment& env) const { - /* - * Filter: [c_vars IN c_set WHEN c_when] => c_expr == nullptr - * Map: [c_expr FOR c_vars IN c_set] => c_when == nullptr - * Filter + Map: [c_expr FOR c_vars IN c_set WHEN c_when] => all members assigned - */ - private: - const ExpressionPtr c_expr, c_vars, c_set, c_when; - public: - Comprehension(ExpressionPtr c_expr_arg, - ExpressionPtr c_vars_arg, - ExpressionPtr c_set_arg, - ExpressionPtr c_when_arg, - Tokenizer::location location_arg) : + return env.getType(name); + } +}; + +class Function final : public Expression +{ +private: + const string name; + const vector args; + +public: + Function(string name_arg, vector args_arg, Tokenizer::location location_arg) : + Expression(move(location_arg)), name {move(name_arg)}, args {move(args_arg)} + { + } + string to_string() const noexcept override; + void + print(ostream& output, [[maybe_unused]] bool matlab_output = false) const noexcept override + { + printName(output); + printArgs(output); + } + BaseTypePtr eval(Environment& env) const override; + +public: + void + printName(ostream& output) const noexcept + { + output << name; + } + void printArgs(ostream& output) const noexcept; + const string& + getName() const + { + return name; + } + const vector& + getArgs() const + { + return args; + } +}; + +class UnaryOp final : public Expression +{ +private: + const codes::UnaryOp op_code; + const ExpressionPtr arg; + +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)} + { + } + string to_string() const noexcept override; + void print(ostream& output, bool matlab_output = false) const noexcept override; + BaseTypePtr eval(Environment& env) const override; +}; + +class BinaryOp final : public Expression +{ +private: + const codes::BinaryOp op_code; + const ExpressionPtr arg1, arg2; + +public: + BinaryOp(codes::BinaryOp op_code_arg, ExpressionPtr arg1_arg, ExpressionPtr arg2_arg, + Tokenizer::location location_arg) : Expression(move(location_arg)), - c_expr{move(c_expr_arg)}, c_vars{move(c_vars_arg)}, - c_set{move(c_set_arg)}, c_when{move(c_when_arg)} { } - Comprehension(ExpressionPtr c_expr_arg, - ExpressionPtr c_vars_arg, - ExpressionPtr c_set_arg, - Tokenizer::location location_arg) : + op_code {op_code_arg}, + arg1 {move(arg1_arg)}, + arg2 {move(arg2_arg)} + { + } + +public: + string to_string() const noexcept override; + void print(ostream& output, bool matlab_output = false) const noexcept override; + BaseTypePtr eval(Environment& env) const override; +}; + +class TrinaryOp final : public Expression +{ +private: + const codes::TrinaryOp op_code; + const ExpressionPtr arg1, arg2, arg3; + +public: + TrinaryOp(codes::TrinaryOp op_code_arg, ExpressionPtr arg1_arg, ExpressionPtr arg2_arg, + ExpressionPtr arg3_arg, Tokenizer::location location_arg) : Expression(move(location_arg)), - c_expr{move(c_expr_arg)}, c_vars{move(c_vars_arg)}, c_set{move(c_set_arg)} { } - Comprehension([[maybe_unused]] bool filter_only_arg, - ExpressionPtr c_vars_arg, - ExpressionPtr c_set_arg, - ExpressionPtr c_when_arg, - Tokenizer::location location_arg) : + op_code {op_code_arg}, + arg1 {move(arg1_arg)}, + arg2 {move(arg2_arg)}, + arg3 {move(arg3_arg)} + { + } + string to_string() const noexcept override; + void print(ostream& output, bool matlab_output = false) const noexcept override; + BaseTypePtr eval(Environment& env) const override; +}; + +class Comprehension final : public Expression +{ + /* + * Filter: [c_vars IN c_set WHEN c_when] => c_expr == nullptr + * Map: [c_expr FOR c_vars IN c_set] => c_when == nullptr + * Filter + Map: [c_expr FOR c_vars IN c_set WHEN c_when] => all members assigned + */ +private: + const ExpressionPtr c_expr, c_vars, c_set, c_when; + +public: + Comprehension(ExpressionPtr c_expr_arg, ExpressionPtr c_vars_arg, ExpressionPtr c_set_arg, + ExpressionPtr c_when_arg, Tokenizer::location location_arg) : Expression(move(location_arg)), - c_vars{move(c_vars_arg)}, c_set{move(c_set_arg)}, c_when{move(c_when_arg)} { } - string to_string() const noexcept override; - void print(ostream &output, bool matlab_output = false) const noexcept override; - BaseTypePtr eval(Environment &env) const override; - }; + c_expr {move(c_expr_arg)}, + c_vars {move(c_vars_arg)}, + c_set {move(c_set_arg)}, + c_when {move(c_when_arg)} + { + } + Comprehension(ExpressionPtr c_expr_arg, ExpressionPtr c_vars_arg, ExpressionPtr c_set_arg, + Tokenizer::location location_arg) : + Expression(move(location_arg)), + c_expr {move(c_expr_arg)}, + c_vars {move(c_vars_arg)}, + c_set {move(c_set_arg)} + { + } + Comprehension([[maybe_unused]] bool filter_only_arg, ExpressionPtr c_vars_arg, + ExpressionPtr c_set_arg, ExpressionPtr c_when_arg, + Tokenizer::location location_arg) : + Expression(move(location_arg)), + c_vars {move(c_vars_arg)}, + c_set {move(c_set_arg)}, + c_when {move(c_when_arg)} + { + } + string to_string() const noexcept override; + void print(ostream& output, bool matlab_output = false) const noexcept override; + BaseTypePtr eval(Environment& env) const override; +}; } #endif diff --git a/src/macro/ForwardDeclarationsAndEnums.hh b/src/macro/ForwardDeclarationsAndEnums.hh index 18f0c13e..28425393 100644 --- a/src/macro/ForwardDeclarationsAndEnums.hh +++ b/src/macro/ForwardDeclarationsAndEnums.hh @@ -26,123 +26,123 @@ using namespace std; namespace macro { - // For Expressions.hh - class BaseType; - using BaseTypePtr = shared_ptr; - class Bool; - using BoolPtr = shared_ptr; - class Real; - using RealPtr = shared_ptr; - class String; - using StringPtr = shared_ptr; - class Tuple; - using TuplePtr = shared_ptr; - class Array; - using ArrayPtr = shared_ptr; - class Range; - using RangePtr = shared_ptr; +// For Expressions.hh +class BaseType; +using BaseTypePtr = shared_ptr; +class Bool; +using BoolPtr = shared_ptr; +class Real; +using RealPtr = shared_ptr; +class String; +using StringPtr = shared_ptr; +class Tuple; +using TuplePtr = shared_ptr; +class Array; +using ArrayPtr = shared_ptr; +class Range; +using RangePtr = shared_ptr; - // For Environment.hh - class Expression; - using ExpressionPtr = shared_ptr; - class Variable; - using VariablePtr = shared_ptr; - class Function; - using FunctionPtr = shared_ptr; +// For Environment.hh +class Expression; +using ExpressionPtr = shared_ptr; +class Variable; +using VariablePtr = shared_ptr; +class Function; +using FunctionPtr = shared_ptr; - // For Parser.yy - class Directive; - using DirectivePtr = shared_ptr; - class Eval; - using EvalPtr = shared_ptr; +// For Parser.yy +class Directive; +using DirectivePtr = shared_ptr; +class Eval; +using EvalPtr = shared_ptr; - // For Directives.cc - class Driver; +// For Directives.cc +class Driver; - namespace codes - { - enum class BaseType - { - Bool, - Real, - String, - Array, - Range, - Tuple - }; +namespace codes +{ +enum class BaseType +{ + Bool, + Real, + String, + Array, + Range, + Tuple +}; - enum class UnaryOp - { - cast_bool, - cast_real, - cast_string, - cast_tuple, - cast_array, - logical_not, - unary_minus, - unary_plus, - length, - isempty, - isboolean, - isreal, - isstring, - istuple, - isarray, - exp, - ln, - log10, - sin, - cos, - tan, - asin, - acos, - atan, - sqrt, - cbrt, - sign, - floor, - ceil, - trunc, - sum, - erf, - erfc, - gamma, - lgamma, - round, - normpdf, - normcdf, - defined - }; +enum class UnaryOp +{ + cast_bool, + cast_real, + cast_string, + cast_tuple, + cast_array, + logical_not, + unary_minus, + unary_plus, + length, + isempty, + isboolean, + isreal, + isstring, + istuple, + isarray, + exp, + ln, + log10, + sin, + cos, + tan, + asin, + acos, + atan, + sqrt, + cbrt, + sign, + floor, + ceil, + trunc, + sum, + erf, + erfc, + gamma, + lgamma, + round, + normpdf, + normcdf, + defined +}; - enum class BinaryOp - { - plus, - minus, - times, - divide, - power, - equal_equal, - not_equal, - less, - greater, - less_equal, - greater_equal, - logical_and, - logical_or, - in, - set_union, - set_intersection, - max, - min, - mod - }; +enum class BinaryOp +{ + plus, + minus, + times, + divide, + power, + equal_equal, + not_equal, + less, + greater, + less_equal, + greater_equal, + logical_and, + logical_or, + in, + set_union, + set_intersection, + max, + min, + mod +}; - enum class TrinaryOp - { - normpdf, - normcdf - }; - } +enum class TrinaryOp +{ + normpdf, + normcdf +}; +} } #endif