Reformat C++ source code using clang-format 15
parent
529ec50337
commit
d463607e90
|
@ -17,10 +17,10 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <ios>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
|
||||
#include "Bytecode.hh"
|
||||
|
||||
|
@ -40,8 +40,7 @@ operator<<(BytecodeWriter &code_file, const FCALL_ &instr)
|
|||
{
|
||||
code_file.instructions_positions.push_back(code_file.tellp());
|
||||
|
||||
auto write_member = [&code_file](const auto &member)
|
||||
{
|
||||
auto write_member = [&code_file](const auto& member) {
|
||||
code_file.write(reinterpret_cast<const char*>(&member), sizeof member);
|
||||
};
|
||||
|
||||
|
@ -71,8 +70,7 @@ operator<<(BytecodeWriter &code_file, const FBEGINBLOCK_ &instr)
|
|||
{
|
||||
code_file.instructions_positions.push_back(code_file.tellp());
|
||||
|
||||
auto write_member = [&code_file](const auto &member)
|
||||
{
|
||||
auto write_member = [&code_file](const auto& member) {
|
||||
code_file.write(reinterpret_cast<const char*>(&member), sizeof member);
|
||||
};
|
||||
|
||||
|
|
246
src/Bytecode.hh
246
src/Bytecode.hh
|
@ -20,12 +20,12 @@
|
|||
#ifndef _BYTECODE_HH
|
||||
#define _BYTECODE_HH
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <ios>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "CommonEnums.hh"
|
||||
|
||||
|
@ -38,22 +38,35 @@ enum class Tags
|
|||
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)
|
||||
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)
|
||||
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
|
||||
|
@ -71,7 +84,8 @@ enum class Tags
|
|||
|
||||
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
|
||||
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
|
||||
|
@ -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}
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
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}
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -200,7 +225,7 @@ class FLDZ_ final : public BytecodeInstruction
|
|||
public:
|
||||
FLDZ_() : BytecodeInstruction {Tags::FLDZ}
|
||||
{
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class FEND_ final : public BytecodeInstruction
|
||||
|
@ -208,7 +233,7 @@ class FEND_ final : public BytecodeInstruction
|
|||
public:
|
||||
FEND_() : BytecodeInstruction {Tags::FEND}
|
||||
{
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class FENDBLOCK_ final : public BytecodeInstruction
|
||||
|
@ -216,7 +241,7 @@ class FENDBLOCK_ final : public BytecodeInstruction
|
|||
public:
|
||||
FENDBLOCK_() : BytecodeInstruction {Tags::FENDBLOCK}
|
||||
{
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class FENDEQU_ final : public BytecodeInstruction
|
||||
|
@ -224,7 +249,7 @@ class FENDEQU_ final : public BytecodeInstruction
|
|||
public:
|
||||
FENDEQU_() : BytecodeInstruction {Tags::FENDEQU}
|
||||
{
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class FDIMT_ final : public TagWithOneArgument<int>
|
||||
|
@ -232,7 +257,7 @@ class FDIMT_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FDIMT_(int size_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FDIMT, size_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_size()
|
||||
{
|
||||
|
@ -245,7 +270,7 @@ class FDIMST_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FDIMST_(int size_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FDIMST, size_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_size()
|
||||
{
|
||||
|
@ -258,7 +283,7 @@ class FLDC_ final : public TagWithOneArgument<double>
|
|||
public:
|
||||
explicit FLDC_(double value_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FLDC, value_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
double
|
||||
get_value()
|
||||
{
|
||||
|
@ -271,7 +296,7 @@ class FLDU_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FLDU_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FLDU, pos_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_pos()
|
||||
{
|
||||
|
@ -284,7 +309,7 @@ class FLDSU_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FLDSU_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FLDSU, pos_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_pos()
|
||||
{
|
||||
|
@ -297,7 +322,7 @@ class FLDR_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FLDR_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FLDR, pos_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_pos()
|
||||
{
|
||||
|
@ -310,7 +335,7 @@ class FLDT_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FLDT_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FLDT, pos_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_pos()
|
||||
{
|
||||
|
@ -323,7 +348,7 @@ class FLDST_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FLDST_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FLDST, pos_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_pos()
|
||||
{
|
||||
|
@ -336,7 +361,7 @@ class FSTPT_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FSTPT_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPT, pos_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_pos()
|
||||
{
|
||||
|
@ -349,7 +374,7 @@ class FSTPST_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FSTPST_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPST, pos_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_pos()
|
||||
{
|
||||
|
@ -362,7 +387,7 @@ class FSTPR_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FSTPR_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPR, pos_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_pos()
|
||||
{
|
||||
|
@ -375,7 +400,7 @@ class FSTPU_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FSTPU_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPU, pos_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_pos()
|
||||
{
|
||||
|
@ -388,7 +413,7 @@ class FSTPSU_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FSTPSU_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPSU, pos_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_pos()
|
||||
{
|
||||
|
@ -401,7 +426,7 @@ class FSTPG_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FSTPG_(int pos_arg) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPG, pos_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_pos()
|
||||
{
|
||||
|
@ -412,9 +437,10 @@ public:
|
|||
class FSTPG2_ final : public TagWithTwoArguments<int, int>
|
||||
{
|
||||
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<int, int, int, int>
|
||||
{
|
||||
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<UnaryOpcode>
|
||||
{
|
||||
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<BinaryOpcode>
|
||||
{
|
||||
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<TrinaryOpcode>
|
||||
{
|
||||
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<int>
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
@ -512,7 +544,7 @@ class FJMP_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FJMP_(int arg_pos) : TagWithOneArgument::TagWithOneArgument {Tags::FJMP, arg_pos}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_pos()
|
||||
{
|
||||
|
@ -525,7 +557,7 @@ class FLDTEF_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FLDTEF_(int number) : TagWithOneArgument::TagWithOneArgument {Tags::FLDTEF, number}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_number()
|
||||
{
|
||||
|
@ -538,7 +570,7 @@ class FSTPTEF_ final : public TagWithOneArgument<int>
|
|||
public:
|
||||
explicit FSTPTEF_(int number) : TagWithOneArgument::TagWithOneArgument {Tags::FSTPTEF, number}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_number()
|
||||
{
|
||||
|
@ -551,7 +583,7 @@ class FLDTEFD_ final : public TagWithTwoArguments<int, int>
|
|||
public:
|
||||
FLDTEFD_(int indx, int row) : TagWithTwoArguments::TagWithTwoArguments {Tags::FLDTEFD, indx, row}
|
||||
{
|
||||
};
|
||||
}
|
||||
int
|
||||
get_indx()
|
||||
{
|
||||
|
@ -567,9 +599,10 @@ public:
|
|||
class FSTPTEFD_ final : public TagWithTwoArguments<int, int>
|
||||
{
|
||||
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<int, int, int>
|
||||
{
|
||||
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<int, int, int>
|
||||
{
|
||||
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<SymbolType, int>
|
||||
{
|
||||
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<SymbolType, int>
|
||||
{
|
||||
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<SymbolType, int>
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
@ -688,7 +726,7 @@ public:
|
|||
FLDV_(SymbolType type_arg, int pos_arg, int lead_lag_arg) :
|
||||
TagWithThreeArguments::TagWithThreeArguments {Tags::FLDV, type_arg, pos_arg, lead_lag_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
SymbolType
|
||||
get_type()
|
||||
{
|
||||
|
@ -712,7 +750,7 @@ public:
|
|||
FSTPV_(SymbolType type_arg, int pos_arg, int lead_lag_arg) :
|
||||
TagWithThreeArguments::TagWithThreeArguments {Tags::FSTPV, type_arg, pos_arg, lead_lag_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
SymbolType
|
||||
get_type()
|
||||
{
|
||||
|
@ -734,14 +772,17 @@ class FCALL_ final : public BytecodeInstruction
|
|||
{
|
||||
template<typename B>
|
||||
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};
|
||||
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) :
|
||||
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},
|
||||
|
@ -749,16 +790,14 @@ public:
|
|||
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<add_pointer_t<decltype(member)>>(code);
|
||||
code += sizeof member;
|
||||
};
|
||||
|
@ -853,7 +892,8 @@ 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
|
||||
public:
|
||||
|
@ -864,7 +904,7 @@ public:
|
|||
dvariable1 {0},
|
||||
lag1 {0}
|
||||
{
|
||||
};
|
||||
}
|
||||
FNUMEXPR_(const ExpressionType expression_type_arg, int equation_arg, int dvariable1_arg) :
|
||||
BytecodeInstruction {Tags::FNUMEXPR},
|
||||
expression_type {expression_type_arg},
|
||||
|
@ -872,15 +912,16 @@ public:
|
|||
dvariable1 {dvariable1_arg},
|
||||
lag1 {0}
|
||||
{
|
||||
};
|
||||
FNUMEXPR_(const ExpressionType expression_type_arg, int equation_arg, int dvariable1_arg, int 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()
|
||||
{
|
||||
|
@ -907,6 +948,7 @@ class FBEGINBLOCK_ final : public BytecodeInstruction
|
|||
{
|
||||
template<typename B>
|
||||
friend BytecodeWriter& operator<<(BytecodeWriter& code_file, const B& instr);
|
||||
|
||||
private:
|
||||
int size {0};
|
||||
BlockSimulationType type;
|
||||
|
@ -919,20 +961,22 @@ private:
|
|||
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<int> &variable_arg, const vector<int> &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<int>& variable_arg, const vector<int>& 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<int> det_exogenous_arg, vector<int> 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)},
|
||||
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},
|
||||
|
@ -944,13 +988,15 @@ public:
|
|||
}
|
||||
// Constructor when derivatives w.r.t. exogenous are absent
|
||||
FBEGINBLOCK_(int size_arg, BlockSimulationType type_arg, int first_element, int block_size,
|
||||
const vector<int> &variable_arg, const vector<int> &equation_arg,
|
||||
bool is_linear_arg, int u_count_int_arg, int nb_col_jacob_arg) :
|
||||
const vector<int>& variable_arg, const vector<int>& 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)},
|
||||
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},
|
||||
|
@ -960,13 +1006,11 @@ public:
|
|||
}
|
||||
/* 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<add_pointer_t<decltype(member)>>(code);
|
||||
code += sizeof member;
|
||||
};
|
||||
|
@ -1063,9 +1107,11 @@ class BytecodeWriter : private ofstream
|
|||
{
|
||||
template<typename B>
|
||||
friend BytecodeWriter& operator<<(BytecodeWriter& code_file, const B& instr);
|
||||
|
||||
private:
|
||||
// Stores the positions of all instructions in the byte stream
|
||||
vector<pos_type> instructions_positions;
|
||||
|
||||
public:
|
||||
BytecodeWriter(const filesystem::path& filename);
|
||||
// Returns the number of the next instruction to be written
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
#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
|
||||
|
@ -32,9 +33,11 @@ enum class SymbolType
|
|||
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)
|
||||
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
|
||||
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)
|
||||
|
||||
|
@ -66,7 +69,8 @@ enum class UnaryOpcode
|
|||
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
|
||||
steadyStateParam2ndDeriv, // for the 2nd derivative of the STEADY_STATE operator w.r.t. to a
|
||||
// parameter
|
||||
expectation,
|
||||
erf,
|
||||
erfc,
|
||||
|
@ -119,8 +123,10 @@ enum class PriorDistributions
|
|||
|
||||
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)
|
||||
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
|
||||
};
|
||||
|
||||
|
@ -133,7 +139,8 @@ enum class BlockSimulationType
|
|||
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
|
||||
solveTwoBoundariesComplete //!< Block of several equations, Newton solver needed, forward and
|
||||
//!< backwar
|
||||
};
|
||||
|
||||
enum class PacTargetKind
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,20 +20,21 @@
|
|||
#ifndef _COMPUTINGTASKS_HH
|
||||
#define _COMPUTINGTASKS_HH
|
||||
|
||||
#include <ostream>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
|
||||
#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;
|
||||
|
@ -45,6 +46,7 @@ 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;
|
||||
|
@ -56,6 +58,7 @@ 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;
|
||||
|
@ -67,6 +70,7 @@ 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;
|
||||
|
@ -77,6 +81,7 @@ 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;
|
||||
|
@ -88,6 +93,7 @@ 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;
|
||||
|
@ -98,6 +104,7 @@ 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;
|
||||
|
@ -110,6 +117,7 @@ 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;
|
||||
|
@ -121,6 +129,7 @@ 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;
|
||||
|
@ -133,6 +142,7 @@ private:
|
|||
const SymbolList symbol_list;
|
||||
const OptionsList options_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
StochSimulStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -147,6 +157,7 @@ private:
|
|||
const SymbolList symbol_list;
|
||||
const OptionsList options_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
ForecastStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -159,6 +170,7 @@ 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;
|
||||
|
@ -176,9 +188,11 @@ public:
|
|||
expr_t expression;
|
||||
};
|
||||
using constraints_t = vector<Constraint>;
|
||||
|
||||
private:
|
||||
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;
|
||||
|
@ -192,6 +206,7 @@ private:
|
|||
const SymbolList symbol_list;
|
||||
const OptionsList options_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
RamseyPolicyStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -204,6 +219,7 @@ 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;
|
||||
|
@ -214,6 +230,7 @@ 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;
|
||||
|
@ -224,6 +241,7 @@ 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;
|
||||
|
@ -234,6 +252,7 @@ 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;
|
||||
|
@ -245,9 +264,9 @@ class OccbinGraphStatement : public Statement
|
|||
private:
|
||||
const SymbolList symbol_list;
|
||||
const OptionsList options_list;
|
||||
|
||||
public:
|
||||
OccbinGraphStatement(SymbolList symbol_list_arg,
|
||||
OptionsList options_list_arg);
|
||||
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;
|
||||
};
|
||||
|
@ -258,6 +277,7 @@ private:
|
|||
const SymbolList symbol_list;
|
||||
const OptionsList options_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
DiscretionaryPolicyStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -271,6 +291,7 @@ class RplotStatement : public Statement
|
|||
private:
|
||||
const SymbolList symbol_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
RplotStatement(SymbolList symbol_list_arg, const SymbolTable& symbol_table_arg);
|
||||
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
|
||||
|
@ -289,6 +310,7 @@ class DsampleStatement : public Statement
|
|||
{
|
||||
private:
|
||||
const int val1, val2;
|
||||
|
||||
public:
|
||||
explicit DsampleStatement(int val1_arg);
|
||||
DsampleStatement(int val1_arg, int val2_arg);
|
||||
|
@ -302,9 +324,9 @@ private:
|
|||
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;
|
||||
|
@ -315,6 +337,7 @@ 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;
|
||||
|
@ -326,9 +349,11 @@ class ObservationTrendsStatement : public Statement
|
|||
{
|
||||
public:
|
||||
using trend_elements_t = map<string, expr_t>;
|
||||
|
||||
private:
|
||||
const trend_elements_t trend_elements;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
ObservationTrendsStatement(trend_elements_t trend_elements_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -340,9 +365,11 @@ class DeterministicTrendsStatement : public Statement
|
|||
{
|
||||
public:
|
||||
using trend_elements_t = map<string, expr_t>;
|
||||
|
||||
private:
|
||||
const trend_elements_t trend_elements;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
DeterministicTrendsStatement(trend_elements_t trend_elements_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -354,9 +381,11 @@ class FilterInitialStateStatement : public Statement
|
|||
{
|
||||
public:
|
||||
using filter_initial_state_elements_t = map<pair<int, int>, expr_t>;
|
||||
|
||||
private:
|
||||
const filter_initial_state_elements_t filter_initial_state_elements;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
FilterInitialStateStatement(filter_initial_state_elements_t filter_initial_state_elements_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -369,6 +398,7 @@ class OsrParamsStatement : public Statement
|
|||
private:
|
||||
const SymbolList symbol_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
OsrParamsStatement(SymbolList symbol_list_arg, const SymbolTable& symbol_table_arg);
|
||||
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
|
||||
|
@ -382,6 +412,7 @@ private:
|
|||
const SymbolList symbol_list;
|
||||
const OptionsList options_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
OsrStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -410,6 +441,7 @@ class OsrParamsBoundsStatement : public Statement
|
|||
{
|
||||
private:
|
||||
const vector<OsrParams> osr_params_list;
|
||||
|
||||
public:
|
||||
explicit OsrParamsBoundsStatement(vector<OsrParams> osr_params_list_arg);
|
||||
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
|
||||
|
@ -423,6 +455,7 @@ private:
|
|||
const SymbolList symbol_list;
|
||||
const string filename;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
DynaTypeStatement(SymbolList symbol_list_arg, string filename_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -437,6 +470,7 @@ private:
|
|||
const SymbolList symbol_list;
|
||||
const string filename;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
DynaSaveStatement(SymbolList symbol_list_arg, string filename_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -449,12 +483,13 @@ class ModelComparisonStatement : public Statement
|
|||
{
|
||||
public:
|
||||
using filename_list_t = vector<pair<string, string>>;
|
||||
|
||||
private:
|
||||
filename_list_t filename_list;
|
||||
OptionsList options_list;
|
||||
|
||||
public:
|
||||
ModelComparisonStatement(filename_list_t filename_list_arg,
|
||||
OptionsList options_list_arg);
|
||||
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;
|
||||
};
|
||||
|
@ -502,11 +537,15 @@ class EstimatedParamsStatement : public AbstractEstimatedParamsStatement
|
|||
{
|
||||
private:
|
||||
const bool overwrite;
|
||||
|
||||
public:
|
||||
EstimatedParamsStatement(vector<EstimationParams> estim_params_list_arg,
|
||||
const SymbolTable &symbol_table_arg,
|
||||
bool overwrite_arg);
|
||||
string blockName() const override { return "estimated_params"; };
|
||||
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;
|
||||
|
@ -516,11 +555,15 @@ class EstimatedParamsInitStatement : public AbstractEstimatedParamsStatement
|
|||
{
|
||||
private:
|
||||
const bool use_calibration;
|
||||
|
||||
public:
|
||||
EstimatedParamsInitStatement(vector<EstimationParams> estim_params_list_arg,
|
||||
const SymbolTable &symbol_table_arg,
|
||||
const bool use_calibration_arg);
|
||||
string blockName() const override { return "estimated_params_init"; };
|
||||
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;
|
||||
|
@ -531,7 +574,11 @@ class EstimatedParamsBoundsStatement : public AbstractEstimatedParamsStatement
|
|||
public:
|
||||
EstimatedParamsBoundsStatement(vector<EstimationParams> estim_params_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
string blockName() const override { return "estimated_params_bounds"; };
|
||||
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;
|
||||
|
@ -554,13 +601,14 @@ class OptimWeightsStatement : public Statement
|
|||
public:
|
||||
using var_weights_t = map<string, expr_t>;
|
||||
using covar_weights_t = map<pair<string, string>, expr_t>;
|
||||
|
||||
private:
|
||||
const var_weights_t var_weights;
|
||||
const covar_weights_t covar_weights;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
OptimWeightsStatement(var_weights_t var_weights_arg,
|
||||
covar_weights_t covar_weights_arg,
|
||||
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;
|
||||
|
@ -572,6 +620,7 @@ class PlannerObjectiveStatement : public Statement
|
|||
private:
|
||||
PlannerObjective model_tree;
|
||||
bool computing_pass_called {false};
|
||||
|
||||
public:
|
||||
explicit PlannerObjectiveStatement(const PlannerObjective& model_tree_arg);
|
||||
/*! \todo check there are only endogenous variables at the current period in the objective
|
||||
|
@ -590,6 +639,7 @@ 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;
|
||||
|
@ -602,6 +652,7 @@ 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;
|
||||
|
@ -614,6 +665,7 @@ 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;
|
||||
|
@ -625,6 +677,7 @@ 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;
|
||||
|
@ -636,6 +689,7 @@ 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;
|
||||
|
@ -647,6 +701,7 @@ 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;
|
||||
|
@ -658,6 +713,7 @@ 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;
|
||||
|
@ -669,6 +725,7 @@ 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;
|
||||
|
@ -682,6 +739,7 @@ private:
|
|||
const SymbolList symbol_list;
|
||||
const OptionsList options_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
MSSBVARIrfStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -694,6 +752,7 @@ 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;
|
||||
|
@ -705,6 +764,7 @@ 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;
|
||||
|
@ -716,6 +776,7 @@ class IdentificationStatement : public Statement
|
|||
{
|
||||
private:
|
||||
OptionsList options_list;
|
||||
|
||||
public:
|
||||
explicit IdentificationStatement(OptionsList options_list_arg);
|
||||
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
|
||||
|
@ -728,8 +789,10 @@ class WriteLatexDynamicModelStatement : public Statement
|
|||
private:
|
||||
const DynamicModel& dynamic_model;
|
||||
const bool write_equation_tags;
|
||||
|
||||
public:
|
||||
WriteLatexDynamicModelStatement(const DynamicModel &dynamic_model_arg, bool write_equation_tags_arg);
|
||||
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;
|
||||
};
|
||||
|
@ -739,6 +802,7 @@ class WriteLatexStaticModelStatement : public Statement
|
|||
private:
|
||||
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;
|
||||
|
@ -750,8 +814,10 @@ class WriteLatexOriginalModelStatement : public Statement
|
|||
private:
|
||||
const DynamicModel& original_model;
|
||||
const bool write_equation_tags;
|
||||
|
||||
public:
|
||||
WriteLatexOriginalModelStatement(const DynamicModel &original_model_arg, bool write_equation_tags_arg);
|
||||
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;
|
||||
};
|
||||
|
@ -760,6 +826,7 @@ class WriteLatexSteadyStateModelStatement : public Statement
|
|||
{
|
||||
private:
|
||||
const SteadyStateModel& steady_state_model;
|
||||
|
||||
public:
|
||||
explicit WriteLatexSteadyStateModelStatement(const SteadyStateModel& steady_state_model_arg);
|
||||
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
|
||||
|
@ -773,6 +840,7 @@ private:
|
|||
const SymbolList symbol_list;
|
||||
const OptionsList options_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
ShockDecompositionStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -787,6 +855,7 @@ private:
|
|||
const SymbolList symbol_list;
|
||||
const OptionsList options_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
RealtimeShockDecompositionStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -801,6 +870,7 @@ private:
|
|||
const SymbolList symbol_list;
|
||||
const OptionsList options_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
PlotShockDecompositionStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -815,6 +885,7 @@ private:
|
|||
const SymbolList symbol_list;
|
||||
const OptionsList options_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
InitialConditionDecompositionStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -828,6 +899,7 @@ class SqueezeShockDecompositionStatement : public Statement
|
|||
private:
|
||||
const SymbolList symbol_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
SqueezeShockDecompositionStatement(SymbolList symbol_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -840,6 +912,7 @@ 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;
|
||||
|
@ -853,6 +926,7 @@ private:
|
|||
const optional<int> periods; // The user is allowed not to declare periods
|
||||
const SymbolList symbol_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
PlotConditionalForecastStatement(optional<int> periods_arg, SymbolList symbol_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -867,6 +941,7 @@ private:
|
|||
const SymbolList symbol_list;
|
||||
const OptionsList options_list;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
CalibSmootherStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -879,6 +954,7 @@ 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;
|
||||
|
@ -900,15 +976,16 @@ public:
|
|||
};
|
||||
|
||||
using svar_identification_restrictions_t = vector<svar_identification_restriction>;
|
||||
|
||||
private:
|
||||
const svar_identification_restrictions_t restrictions;
|
||||
const bool upper_cholesky_present, lower_cholesky_present, constants_exclusion_present;
|
||||
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;
|
||||
|
@ -921,6 +998,7 @@ class MarkovSwitchingStatement : public Statement
|
|||
private:
|
||||
const OptionsList options_list;
|
||||
map<pair<int, int>, double> restriction_map;
|
||||
|
||||
public:
|
||||
explicit MarkovSwitchingStatement(OptionsList options_list_arg);
|
||||
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
|
||||
|
@ -932,6 +1010,7 @@ 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;
|
||||
|
@ -950,6 +1029,7 @@ 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;
|
||||
|
@ -960,6 +1040,7 @@ 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;
|
||||
|
@ -972,13 +1053,14 @@ class SubsamplesStatement : public Statement
|
|||
public:
|
||||
//! Storage for declaring subsamples: map<subsample_name, <date1, date2 >
|
||||
using subsample_declaration_map_t = map<string, pair<string, string>>;
|
||||
|
||||
private:
|
||||
const string name1, name2;
|
||||
const subsample_declaration_map_t subsample_declaration_map;
|
||||
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;
|
||||
|
@ -990,12 +1072,10 @@ class SubsamplesEqualStatement : public Statement
|
|||
private:
|
||||
const string to_name1, to_name2, from_name1, from_name2;
|
||||
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);
|
||||
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;
|
||||
};
|
||||
|
@ -1007,9 +1087,9 @@ private:
|
|||
const PriorDistributions prior_shape;
|
||||
const OptionsList options_list;
|
||||
void writeOutputHelper(ostream& output, const string& field, const string& lhs_field) const;
|
||||
|
||||
public:
|
||||
JointPriorStatement(vector<string> joint_parameters_arg,
|
||||
PriorDistributions prior_shape_arg,
|
||||
JointPriorStatement(vector<string> 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;
|
||||
|
@ -1023,10 +1103,8 @@ 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;
|
||||
|
@ -1045,11 +1123,8 @@ protected:
|
|||
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);
|
||||
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;
|
||||
};
|
||||
|
@ -1058,12 +1133,10 @@ class StdPriorStatement : public BasicPriorStatement
|
|||
{
|
||||
private:
|
||||
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,
|
||||
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;
|
||||
|
@ -1074,14 +1147,11 @@ class CorrPriorStatement : public BasicPriorStatement
|
|||
private:
|
||||
const string name1;
|
||||
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);
|
||||
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;
|
||||
|
@ -1093,15 +1163,11 @@ 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;
|
||||
|
||||
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,
|
||||
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;
|
||||
|
@ -1114,9 +1180,7 @@ 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);
|
||||
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;
|
||||
|
@ -1139,10 +1203,9 @@ class StdOptionsStatement : public BasicOptionsStatement
|
|||
{
|
||||
private:
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
StdOptionsStatement(string name_arg,
|
||||
string subsample_name_arg,
|
||||
OptionsList options_list_arg,
|
||||
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;
|
||||
|
@ -1153,11 +1216,10 @@ class CorrOptionsStatement : public BasicOptionsStatement
|
|||
private:
|
||||
const string name1;
|
||||
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);
|
||||
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;
|
||||
|
@ -1169,16 +1231,12 @@ 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;
|
||||
|
||||
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);
|
||||
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;
|
||||
|
@ -1196,6 +1254,7 @@ 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;
|
||||
|
@ -1206,6 +1265,7 @@ class MethodOfMomentsStatement : public Statement
|
|||
{
|
||||
private:
|
||||
const OptionsList options_list;
|
||||
|
||||
public:
|
||||
explicit MethodOfMomentsStatement(OptionsList options_list_arg);
|
||||
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
|
||||
|
@ -1220,9 +1280,9 @@ private:
|
|||
const OptionsList options_list;
|
||||
const vector<string> generate_irf_names;
|
||||
const vector<map<string, double>> generate_irf_elements;
|
||||
|
||||
public:
|
||||
GenerateIRFsStatement(OptionsList options_list_arg,
|
||||
vector<string> generate_irf_names_arg,
|
||||
GenerateIRFsStatement(OptionsList options_list_arg, vector<string> generate_irf_names_arg,
|
||||
vector<map<string, double>> generate_irf_elements_arg);
|
||||
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
|
||||
void writeJsonOutput(ostream& output) const override;
|
||||
|
@ -1232,6 +1292,7 @@ class MatchedMomentsStatement : public Statement
|
|||
{
|
||||
private:
|
||||
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 */
|
||||
|
@ -1246,10 +1307,13 @@ 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)
|
||||
// The tuple is (name, bind, relax, error_bind, error_relax) (where relax and error_{bind,relax}
|
||||
// can be nullptr)
|
||||
const vector<tuple<string, BinaryOpNode*, BinaryOpNode*, expr_t, expr_t>> constraints;
|
||||
OccbinConstraintsStatement(const DataTree &data_tree_arg,
|
||||
OccbinConstraintsStatement(
|
||||
const DataTree& data_tree_arg,
|
||||
vector<tuple<string, BinaryOpNode*, BinaryOpNode*, expr_t, expr_t>> constraints_arg);
|
||||
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
|
||||
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
|
||||
|
@ -1260,6 +1324,7 @@ 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;
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
@ -26,8 +26,8 @@
|
|||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
@ -53,9 +53,11 @@ Path::Path(vector<string> includepath_arg)
|
|||
paths["include"] = move(includepath_arg);
|
||||
}
|
||||
|
||||
FollowerNode::FollowerNode(string computerName_arg, string port_arg, int minCpuNbr_arg, int maxCpuNbr_arg, string userName_arg,
|
||||
string password_arg, string remoteDrive_arg, string remoteDirectory_arg,
|
||||
string programPath_arg, string programConfig_arg, string matlabOctavePath_arg, bool singleCompThread_arg,
|
||||
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)},
|
||||
|
@ -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,7 +101,8 @@ 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 {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)}
|
||||
|
@ -117,8 +120,7 @@ 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)
|
||||
if (auto appdata = getenv("APPDATA"); appdata)
|
||||
defaultConfigFile = filesystem::path {appdata} / "dynare.ini";
|
||||
else
|
||||
{
|
||||
|
@ -132,8 +134,7 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file)
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#else
|
||||
if (auto home = getenv("HOME");
|
||||
home)
|
||||
if (auto home = getenv("HOME"); home)
|
||||
defaultConfigFile = filesystem::path {home} / ".dynare";
|
||||
else
|
||||
{
|
||||
|
@ -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,14 +165,14 @@ 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<string> includepath;
|
||||
int minCpuNbr {0}, maxCpuNbr {0};
|
||||
int numberOfThreadsPerJob {1};
|
||||
|
@ -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)
|
||||
|
@ -286,16 +288,17 @@ 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")
|
||||
else if (tokenizedLine.front() == "Name")
|
||||
name = tokenizedLine.back();
|
||||
else if (tokenizedLine.front() == "CPUnbr")
|
||||
{
|
||||
|
@ -308,8 +311,7 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file)
|
|||
minCpuNbr = 1;
|
||||
maxCpuNbr = stoi(tokenizedCpuNbr.front());
|
||||
}
|
||||
else if (tokenizedCpuNbr.size() == 2
|
||||
&& tokenizedCpuNbr[0].at(0) == '['
|
||||
else if (tokenizedCpuNbr.size() == 2 && tokenizedCpuNbr[0].at(0) == '['
|
||||
&& tokenizedCpuNbr[1].at(tokenizedCpuNbr[1].size() - 1) == ']')
|
||||
{
|
||||
tokenizedCpuNbr[0].erase(0, 1);
|
||||
|
@ -354,8 +356,7 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file)
|
|||
remoteDrive = tokenizedLine.back();
|
||||
else if (tokenizedLine.front() == "RemoteDirectory")
|
||||
remoteDirectory = tokenizedLine.back();
|
||||
else if (tokenizedLine.front() == "DynarePath"
|
||||
|| tokenizedLine.front() == "ProgramPath")
|
||||
else if (tokenizedLine.front() == "DynarePath" || tokenizedLine.front() == "ProgramPath")
|
||||
programPath = tokenizedLine.back();
|
||||
else if (tokenizedLine.front() == "ProgramConfig")
|
||||
programConfig = tokenizedLine.back();
|
||||
|
@ -370,7 +371,9 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file)
|
|||
singleCompThread = false;
|
||||
else
|
||||
{
|
||||
cerr << "ERROR (in config file): The value passed to SingleCompThread may only be 'true' or 'false'." << endl;
|
||||
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")
|
||||
|
@ -380,8 +383,7 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file)
|
|||
char_separator sep(" ,;", "()", drop_empty_tokens);
|
||||
tokenizer tokens(tokenizedLine.back(), sep);
|
||||
string node_name;
|
||||
for (bool begin_weight{false};
|
||||
const auto &token : tokens)
|
||||
for (bool begin_weight {false}; const auto& token : tokens)
|
||||
{
|
||||
if (token == "(")
|
||||
{
|
||||
|
@ -401,7 +403,9 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file)
|
|||
{
|
||||
if (member_nodes.contains(node_name))
|
||||
{
|
||||
cerr << "ERROR (in config file): Node entered twice in specification of cluster." << endl;
|
||||
cerr << "ERROR (in config file): Node entered twice in specification "
|
||||
"of cluster."
|
||||
<< endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else
|
||||
|
@ -415,14 +419,18 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file)
|
|||
auto weight = stod(token);
|
||||
if (weight <= 0)
|
||||
{
|
||||
cerr << "ERROR (in config file): Misspecification of weights passed to Members option." << endl;
|
||||
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;
|
||||
cerr << "ERROR (in config file): Misspecification of weights passed to "
|
||||
"Members option."
|
||||
<< endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
@ -432,14 +440,17 @@ ConfigFile::getConfigFileInfo(const filesystem::path &config_file)
|
|||
member_nodes[node_name] = 1.0;
|
||||
else
|
||||
{
|
||||
cerr << "ERROR (in config file): Node entered twice in specification of cluster." << endl;
|
||||
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;
|
||||
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,11 +495,14 @@ ConfigFile::addPathsConfFileElement(vector<string> includepath)
|
|||
}
|
||||
|
||||
void
|
||||
ConfigFile::addParallelConfFileElement(bool inNode, bool inCluster, const member_nodes_t &member_nodes, const string &name,
|
||||
const string &computerName, const string &port, int minCpuNbr, int maxCpuNbr,
|
||||
const string &userName, const string &password, const string &remoteDrive,
|
||||
const string &remoteDirectory, const string &programPath, const string &programConfig,
|
||||
const string &matlabOctavePath, bool singleCompThread, int numberOfThreadsPerJob,
|
||||
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
|
||||
|
@ -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))
|
||||
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,
|
||||
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);
|
||||
|
@ -537,8 +549,7 @@ ConfigFile::addParallelConfFileElement(bool inNode, bool inCluster, const member
|
|||
void
|
||||
ConfigFile::checkPass([[maybe_unused]] WarningConsolidation& warnings) const
|
||||
{
|
||||
for (bool global_init_file_declared{false};
|
||||
const auto &hook : 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))
|
||||
|
@ -573,19 +584,22 @@ ConfigFile::checkPass([[maybe_unused]] WarningConsolidation &warnings) const
|
|||
}
|
||||
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,7 +669,8 @@ 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);
|
||||
}
|
||||
|
||||
|
@ -649,7 +678,8 @@ ConfigFile::checkPass([[maybe_unused]] WarningConsolidation &warnings) const
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
@ -670,7 +700,8 @@ 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)
|
||||
|
@ -705,10 +736,10 @@ 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)
|
||||
|
@ -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 << "', "
|
||||
<< "'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,8 +794,12 @@ 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
|
||||
output
|
||||
<< "ErrorCode = AnalyseComputationalEnvironment(options_.parallel, options_.parallel_info);"
|
||||
<< endl
|
||||
<< "disp(['AnalyseComputationalEnvironment returned with Error Code: ' "
|
||||
"num2str(ErrorCode)]);"
|
||||
<< endl
|
||||
<< "diary off;" << endl
|
||||
<< "return;" << endl;
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
#ifndef _CONFIG_FILE_HH
|
||||
#define _CONFIG_FILE_HH
|
||||
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
|
||||
#include "WarningConsolidation.hh"
|
||||
|
||||
|
@ -34,8 +34,10 @@ class Hook
|
|||
{
|
||||
public:
|
||||
explicit Hook(string global_init_file_arg);
|
||||
|
||||
private:
|
||||
map<string, string> hooks;
|
||||
|
||||
public:
|
||||
map<string, string>
|
||||
get_hooks() const
|
||||
|
@ -48,8 +50,10 @@ class Path
|
|||
{
|
||||
public:
|
||||
explicit Path(vector<string> includepath_arg);
|
||||
|
||||
private:
|
||||
map<string, vector<string>> paths;
|
||||
|
||||
public:
|
||||
map<string, vector<string>>
|
||||
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,12 +119,15 @@ private:
|
|||
//! Add Paths
|
||||
void addPathsConfFileElement(vector<string> 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& parallel_config_file);
|
||||
|
|
|
@ -17,13 +17,13 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
#include "DataTree.hh"
|
||||
|
||||
|
@ -46,10 +46,8 @@ 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) :
|
||||
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},
|
||||
|
@ -125,8 +123,7 @@ 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<NumConstNode>(*this, node_list.size(), id);
|
||||
|
@ -145,8 +142,7 @@ 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<VariableNode>(*this, node_list.size(), symb_id, lag);
|
||||
|
@ -162,7 +158,8 @@ DataTree::getVariable(int symb_id, int lag) const
|
|||
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;
|
||||
|
@ -250,8 +247,7 @@ DataTree::AddUMinus(expr_t iArg1)
|
|||
return Zero;
|
||||
|
||||
// Simplify -(-x) in x
|
||||
if (auto uarg = dynamic_cast<UnaryOpNode *>(iArg1);
|
||||
uarg && uarg->op_code == UnaryOpcode::uminus)
|
||||
if (auto uarg = dynamic_cast<UnaryOpNode*>(iArg1); uarg && uarg->op_code == UnaryOpcode::uminus)
|
||||
return uarg->arg;
|
||||
|
||||
return AddUnaryOp(UnaryOpcode::uminus, iArg1);
|
||||
|
@ -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
|
||||
|
@ -680,8 +677,7 @@ DataTree::AddExpectation(int iArg1, expr_t iArg2)
|
|||
expr_t
|
||||
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<VarExpectationNode>(*this, node_list.size(), model_name);
|
||||
|
@ -694,8 +690,7 @@ DataTree::AddVarExpectation(const string &model_name)
|
|||
expr_t
|
||||
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<PacExpectationNode>(*this, node_list.size(), model_name);
|
||||
|
@ -757,35 +752,42 @@ DataTree::AddExternalFunction(int symb_id, const vector<expr_t> &arguments)
|
|||
}
|
||||
|
||||
expr_t
|
||||
DataTree::AddFirstDerivExternalFunction(int top_level_symb_id, const vector<expr_t> &arguments, int input_index)
|
||||
DataTree::AddFirstDerivExternalFunction(int top_level_symb_id, const vector<expr_t>& 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<FirstDerivExternalFunctionNode>(*this, node_list.size(), top_level_symb_id, arguments, input_index);
|
||||
auto sp = make_unique<FirstDerivExternalFunctionNode>(*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<expr_t> &arguments, int input_index1, int input_index2)
|
||||
DataTree::AddSecondDerivExternalFunction(int top_level_symb_id, const vector<expr_t>& 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 });
|
||||
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<SecondDerivExternalFunctionNode>(*this, node_list.size(), top_level_symb_id, arguments, input_index1, input_index2);
|
||||
auto sp = make_unique<SecondDerivExternalFunctionNode>(*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;
|
||||
}
|
||||
|
||||
|
@ -897,7 +899,9 @@ DataTree::writeCHelpersDefinition(ostream &output) const
|
|||
<< "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
|
||||
|
@ -932,8 +936,7 @@ 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;
|
||||
|
|
|
@ -20,22 +20,22 @@
|
|||
#ifndef _DATATREE_HH
|
||||
#define _DATATREE_HH
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <filesystem>
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#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;
|
||||
|
||||
|
@ -60,8 +60,10 @@ private:
|
|||
using variable_node_map_t = map<pair<int, int>, 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<tuple<expr_t, UnaryOpcode, int, int, int, string, vector<int>>, 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<tuple<expr_t, UnaryOpcode, int, int, int, string, vector<int>>, UnaryOpNode*>;
|
||||
unary_op_node_map_t unary_op_node_map;
|
||||
|
||||
//! ( arg1, arg2, opCode, order of Power Derivative) -> BinaryOpNode
|
||||
|
@ -89,11 +91,13 @@ private:
|
|||
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<tuple<vector<expr_t>, int, int>, FirstDerivExternalFunctionNode *>;
|
||||
using first_deriv_external_function_node_map_t
|
||||
= map<tuple<vector<expr_t>, 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<tuple<vector<expr_t>, int, int, int>, SecondDerivExternalFunctionNode *>;
|
||||
using second_deriv_external_function_node_map_t
|
||||
= map<tuple<vector<expr_t>, 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<int, expr_t> 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<int> local_variables_vector;
|
||||
|
||||
//! Internal implementation of ParamUsedWithLeadLag()
|
||||
|
@ -119,18 +124,20 @@ private:
|
|||
//! The list of nodes
|
||||
vector<unique_ptr<ExprNode>> 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<int> &adl_lags = vector<int>());
|
||||
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<int>& adl_lags = vector<int>());
|
||||
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;
|
||||
|
||||
|
@ -261,9 +268,11 @@ public:
|
|||
//! Adds an external function node
|
||||
expr_t AddExternalFunction(int symb_id, const vector<expr_t>& arguments);
|
||||
//! Adds an external function node for the first derivative of an external function
|
||||
expr_t AddFirstDerivExternalFunction(int top_level_symb_id, const vector<expr_t> &arguments, int input_index);
|
||||
expr_t AddFirstDerivExternalFunction(int top_level_symb_id, const vector<expr_t>& 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<expr_t> &arguments, int input_index1, int input_index2);
|
||||
expr_t AddSecondDerivExternalFunction(int top_level_symb_id, const vector<expr_t>& 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,7 +283,8 @@ 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
|
||||
|
@ -335,7 +345,8 @@ public:
|
|||
//! Adds to the set all the deriv IDs corresponding to parameters
|
||||
virtual void addAllParamDerivId(set<int>& 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
|
||||
{
|
||||
|
@ -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<int> &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<int>& 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<NumConstNode *>(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<NumConstNode*>(arg); op_code != UnaryOpcode::uminus || !carg)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -427,10 +440,13 @@ DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int
|
|||
}
|
||||
}
|
||||
|
||||
auto sp = make_unique<UnaryOpNode>(*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<UnaryOpNode>(*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;
|
||||
}
|
||||
|
||||
|
@ -453,7 +469,8 @@ DataTree::AddBinaryOp(expr_t arg1, BinaryOpcode op_code, expr_t arg2, int powerD
|
|||
{
|
||||
}
|
||||
|
||||
auto sp = make_unique<BinaryOpNode>(*this, node_list.size(), arg1, op_code, arg2, powerDerivOrder);
|
||||
auto sp
|
||||
= make_unique<BinaryOpNode>(*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);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,11 +20,11 @@
|
|||
#ifndef _DYNAMICMODEL_HH
|
||||
#define _DYNAMICMODEL_HH
|
||||
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
#include "StaticModel.hh"
|
||||
#include "Bytecode.hh"
|
||||
#include "StaticModel.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -42,6 +42,7 @@ public:
|
|||
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};
|
||||
|
||||
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
|
||||
|
@ -89,7 +90,8 @@ private:
|
|||
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
|
||||
//! 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
|
||||
|
@ -156,7 +158,8 @@ private:
|
|||
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,26 +170,28 @@ 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<string> &subset);
|
||||
void substituteLeadLagInternal(AuxVarType type, bool deterministic_model,
|
||||
const vector<string>& subset);
|
||||
|
||||
//! Help computeXrefs to compute the reverse references (i.e. param->eqs, endo->eqs, etc)
|
||||
void computeRevXref(map<pair<int, int>, set<int>> &xrefset, const set<pair<int, int>> &eiref, int eqn);
|
||||
void computeRevXref(map<pair<int, int>, set<int>>& xrefset, const set<pair<int, int>>& eiref,
|
||||
int eqn);
|
||||
|
||||
//! Write reverse cross references
|
||||
void writeRevXrefs(ostream &output, const map<pair<int, int>, set<int>> &xrefmap, const string &type) const;
|
||||
void writeRevXrefs(ostream& output, const map<pair<int, int>, set<int>>& 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;
|
||||
/* 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,
|
||||
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;
|
||||
|
||||
|
@ -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<map<string, string>> parseIncludeExcludeEquations(const string &inc_exc_option_value, bool exclude_eqs);
|
||||
static vector<map<string, string>>
|
||||
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<int> removeEquationsHelper(set<map<string, string>> &listed_eqs_by_tag,
|
||||
bool exclude_eqs, bool excluded_vars_change_type,
|
||||
vector<int> removeEquationsHelper(set<map<string, string>>& listed_eqs_by_tag, bool exclude_eqs,
|
||||
bool excluded_vars_change_type,
|
||||
vector<BinaryOpNode*>& all_equations,
|
||||
vector<optional<int>>& all_equations_lineno,
|
||||
EquationTags &all_equation_tags,
|
||||
bool static_equations) const;
|
||||
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<map<string, map<tuple<int, int>, expr_t>>, map<string, map<tuple<int, int>, expr_t>>> computeErrorComponentMatrices(const ExprNode::subst_table_t &diff_subst_table) const;
|
||||
pair<map<string, map<tuple<int, int>, expr_t>>, map<string, map<tuple<int, int>, 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
|
||||
|
@ -278,8 +284,7 @@ protected:
|
|||
}
|
||||
|
||||
public:
|
||||
DynamicModel(SymbolTable &symbol_table_arg,
|
||||
NumericalConstants &num_constants_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);
|
||||
|
@ -295,10 +300,11 @@ public:
|
|||
|
||||
//! 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,
|
||||
bool no_tmp_terms, bool block, bool use_dll);
|
||||
|
@ -374,7 +380,8 @@ 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<bool julia>
|
||||
|
@ -383,7 +390,8 @@ public:
|
|||
//! 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
|
||||
|
@ -433,7 +441,8 @@ public:
|
|||
auxiliary parameters have already been added to the symbol table.
|
||||
It also assumes that the “bind” and “relax” tags have been cleared from
|
||||
eq_tags. */
|
||||
void addOccbinEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags, const vector<string> ®imes_bind, const vector<string> ®imes_relax);
|
||||
void addOccbinEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags,
|
||||
const vector<string>& regimes_bind, const vector<string>& regimes_relax);
|
||||
|
||||
//! Writes LaTeX file with the equations of the dynamic model
|
||||
void writeLatexFile(const string& basename, bool write_equation_tags) const;
|
||||
|
@ -471,8 +480,7 @@ public:
|
|||
}
|
||||
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,9 +489,9 @@ 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<int>& deriv_id_set) override;
|
||||
|
@ -515,7 +523,8 @@ 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)”
|
||||
|
@ -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<lag_equivalence_table_t, ExprNode::subst_table_t> substituteUnaryOps(VarExpectationModelTable &var_expectation_model_table, PacModelTable &pac_model_table);
|
||||
pair<lag_equivalence_table_t, ExprNode::subst_table_t>
|
||||
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<lag_equivalence_table_t, ExprNode::subst_table_t> substituteUnaryOps(const set<int> &eqnumbers, VarExpectationModelTable &var_expectation_model_table, PacModelTable &pac_model_table);
|
||||
pair<lag_equivalence_table_t, ExprNode::subst_table_t>
|
||||
substituteUnaryOps(const set<int>& eqnumbers,
|
||||
VarExpectationModelTable& var_expectation_model_table,
|
||||
PacModelTable& pac_model_table);
|
||||
|
||||
//! Substitutes diff operator
|
||||
pair<lag_equivalence_table_t, ExprNode::subst_table_t> substituteDiff(VarExpectationModelTable &var_expectation_model_table, PacModelTable &pac_model_table);
|
||||
pair<lag_equivalence_table_t, ExprNode::subst_table_t>
|
||||
substituteDiff(VarExpectationModelTable& var_expectation_model_table,
|
||||
PacModelTable& pac_model_table);
|
||||
|
||||
//! Substitute VarExpectation operators
|
||||
void substituteVarExpectation(const map<string, expr_t>& subst_table);
|
||||
|
||||
void analyzePacEquationStructure(const string &name, map<string, string> &pac_eq_name, PacModelTable::equation_info_t &pac_equation_info);
|
||||
void analyzePacEquationStructure(const string& name, map<string, string>& pac_eq_name,
|
||||
PacModelTable::equation_info_t& pac_equation_info);
|
||||
|
||||
// Exception thrown by getPacTargetSymbId()
|
||||
struct PacTargetNotIdentifiedException
|
||||
|
@ -578,26 +595,19 @@ 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<string, int> &pac_aux_var_symb_ids,
|
||||
map<string, vector<int>> &pac_aux_param_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<string, int>& pac_aux_var_symb_ids, map<string, vector<int>>& pac_aux_param_symb_ids,
|
||||
map<string, expr_t>& 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<int> &lhs,
|
||||
int max_lag,
|
||||
const string &aux_model_type,
|
||||
expr_t growth_correction_term,
|
||||
string auxname,
|
||||
void computePacBackwardExpectationSubstitution(const string& name, const vector<int>& lhs,
|
||||
int max_lag, const string& aux_model_type,
|
||||
expr_t growth_correction_term, string auxname,
|
||||
map<string, int>& pac_aux_var_symb_ids,
|
||||
map<string, vector<int>>& pac_aux_param_symb_ids,
|
||||
map<string, expr_t>& pac_expectation_substitution);
|
||||
|
@ -610,10 +620,8 @@ 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<int> &lhs,
|
||||
int max_lag,
|
||||
const string &aux_model_type,
|
||||
void computePacBackwardExpectationSubstitutionWithComponents(
|
||||
const string& name, const vector<int>& lhs, int max_lag, const string& aux_model_type,
|
||||
vector<PacModelTable::target_component_t>& pac_target_components,
|
||||
map<string, expr_t>& pac_expectation_substitution);
|
||||
|
||||
|
@ -650,7 +658,8 @@ 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
|
||||
|
@ -658,7 +667,8 @@ public:
|
|||
|
||||
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();
|
||||
|
||||
|
@ -694,10 +704,11 @@ 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<output_type>() };
|
||||
auto [tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output,
|
||||
g3p_output] {writeParamsDerivativesFileHelper<output_type>()};
|
||||
|
||||
if constexpr (!julia)
|
||||
{
|
||||
|
@ -708,79 +719,159 @@ 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
|
||||
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
|
||||
<< "% 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
|
||||
<< "% 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
|
||||
<< "% 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
|
||||
<< "% from model file (.mod)" << endl
|
||||
<< endl
|
||||
<< "T = NaN(" << params_derivs_temporary_terms_idxs.size() << ",1);" << 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()
|
||||
<< "if nargout >= 3" << 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
|
||||
<< 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
|
||||
<< hp_output.str() << "end" << endl
|
||||
<< "if nargout >= 6" << endl
|
||||
<< "g3p = zeros(" << params_derivatives.at({3, 1}).size() << ",6);" << endl
|
||||
<< g3p_output.str()
|
||||
<< "end" << endl
|
||||
<< g3p_output.str() << "end" << endl
|
||||
<< "end" << endl;
|
||||
paramsDerivsFile.close();
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,24 +17,24 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <regex>
|
||||
#include <thread>
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#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<pair<string, string>> &defines,
|
||||
stringstream macroExpandModFile(const filesystem::path& filename, const istream& modfile,
|
||||
bool debug, bool save_macro, filesystem::path save_macro_file,
|
||||
bool line_macro, const vector<pair<string, string>>& defines,
|
||||
vector<filesystem::path> 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<variable>[=<value>]] [-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=<equation_tag_list_or_file>] [include_eqs=<equation_tag_list_or_file>]"
|
||||
<< " [json=parse|check|transform|compute] [jsonstdout] [onlyjson] [jsonderivsimple] [nopathchange] [nopreprocessoroutput]"
|
||||
<< " [mexext=<extension>] [matlabroot=<path>] [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<variable>[=<value>]] [-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=<equation_tag_list_or_file>] [include_eqs=<equation_tag_list_or_file>]"
|
||||
<< " [json=parse|check|transform|compute] [jsonstdout] [onlyjson] [jsonderivsimple] "
|
||||
"[nopathchange] [nopreprocessoroutput]"
|
||||
<< " [mexext=<extension>] [matlabroot=<path>] [onlymodel] [notime] [use_dll] "
|
||||
"[nocommutativity]"
|
||||
<< endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -75,13 +81,12 @@ parse_options_line(istream &modfile)
|
|||
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)
|
||||
for (sregex_iterator p(s.begin(), s.end(), pat2); p != sregex_iterator {}; ++p)
|
||||
options.push_back(p->str());
|
||||
}
|
||||
break;
|
||||
|
@ -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;
|
||||
|
@ -289,8 +295,7 @@ main(int argc, char **argv)
|
|||
usage();
|
||||
}
|
||||
|
||||
if (auto equal_index = s.find('=');
|
||||
equal_index != string::npos)
|
||||
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");
|
||||
|
@ -456,7 +461,8 @@ 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();
|
||||
|
@ -469,8 +475,8 @@ main(int argc, char **argv)
|
|||
/*
|
||||
* Macro-expand MOD file
|
||||
*/
|
||||
stringstream macro_output =
|
||||
macroExpandModFile(filename, modfile, debug, save_macro, move(save_macro_file), line_macro,
|
||||
stringstream macro_output
|
||||
= macroExpandModFile(filename, modfile, debug, save_macro, move(save_macro_file), line_macro,
|
||||
defines, move(paths));
|
||||
|
||||
if (only_macro)
|
||||
|
@ -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
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
#include "EquationTags.hh"
|
||||
|
||||
#include <regex>
|
||||
#include <ostream>
|
||||
#include <regex>
|
||||
#include <utility>
|
||||
|
||||
set<int>
|
||||
|
@ -62,8 +62,7 @@ EquationTags::getEqnsByTags(const map<string, string> &tags_selected) const
|
|||
if (auto tmp = tags.find(key); tmp == tags.end() || tmp->second != value)
|
||||
goto next_eq;
|
||||
retval.insert(eqn);
|
||||
next_eq:
|
||||
;
|
||||
next_eq:;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
@ -89,8 +88,7 @@ EquationTags::writeCheckSumInfo(ostream &output) const
|
|||
{
|
||||
for (const auto& [eqn, tags] : eqn_tags)
|
||||
for (const auto& [key, value] : tags)
|
||||
output << " " << eqn + 1
|
||||
<< key << " " << value << endl;
|
||||
output << " " << eqn + 1 << key << " " << value << endl;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -99,8 +97,7 @@ 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;
|
||||
output << " " << eqn + 1 << " , '" << key << "' , '" << value << "' ;" << endl;
|
||||
output << "};" << endl;
|
||||
}
|
||||
|
||||
|
@ -110,8 +107,7 @@ EquationTags::writeLatexOutput(ostream &output, int eqn) const
|
|||
if (!eqn_tags.contains(eqn))
|
||||
return;
|
||||
|
||||
auto escape_special_latex_symbols = [](string str)
|
||||
{
|
||||
auto escape_special_latex_symbols = [](string str) {
|
||||
const regex special_latex_chars(R"([&%$#_{}])");
|
||||
const regex backslash(R"(\\)");
|
||||
const regex tilde(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 << ", ";
|
||||
|
@ -145,8 +140,7 @@ EquationTags::writeJsonAST(ostream &output, int eqn) const
|
|||
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 << ", ";
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
#define _EQUATION_TAGS_HH
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -31,6 +31,7 @@ class EquationTags
|
|||
{
|
||||
private:
|
||||
map<int, map<string, string>> eqn_tags;
|
||||
|
||||
public:
|
||||
// Add multiple equation tags for the given equation
|
||||
void
|
||||
|
|
1500
src/ExprNode.cc
1500
src/ExprNode.cc
File diff suppressed because it is too large
Load Diff
839
src/ExprNode.hh
839
src/ExprNode.hh
File diff suppressed because it is too large
Load Diff
|
@ -17,16 +17,17 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
#ifndef _EXTERNALFUNCTIONSTABLE_HH
|
||||
#define _EXTERNALFUNCTIONSTABLE_HH
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
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,8 +84,7 @@ 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};
|
||||
|
@ -90,8 +93,7 @@ ExternalFunctionsTable::getNargs(int symb_id) const noexcept(false)
|
|||
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};
|
||||
|
@ -100,8 +102,7 @@ ExternalFunctionsTable::getFirstDerivSymbID(int symb_id) const noexcept(false)
|
|||
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};
|
||||
|
|
|
@ -17,19 +17,18 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <algorithm>
|
||||
|
||||
#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<pair<string, string>> &defines,
|
||||
vector<filesystem::path> paths)
|
||||
macroExpandModFile(const filesystem::path& filename, const istream& modfile, bool debug,
|
||||
bool save_macro, filesystem::path save_macro_file, bool line_macro,
|
||||
const vector<pair<string, string>>& defines, vector<filesystem::path> paths)
|
||||
{
|
||||
// Do macro processing
|
||||
stringstream macro_output;
|
||||
|
|
435
src/ModFile.cc
435
src/ModFile.cc
|
@ -17,22 +17,22 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <typeinfo>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#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},
|
||||
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},
|
||||
|
@ -45,8 +45,8 @@ ModFile::ModFile(WarningConsolidation &warnings_arg)
|
|||
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},
|
||||
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}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
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<int> unusedExo0 = dynamic_model.findUnusedExogenous();
|
||||
set<int> 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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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,14 +546,11 @@ 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
|
||||
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);
|
||||
|
@ -530,8 +567,8 @@ 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<InitParamStatement>(sid,
|
||||
expressions_tree.AddNonNegativeConstant(mod_file_struct.dsge_var_calibrated),
|
||||
addStatementAtFront(make_unique<InitParamStatement>(
|
||||
sid, expressions_tree.AddNonNegativeConstant(mod_file_struct.dsge_var_calibrated),
|
||||
symbol_table));
|
||||
}
|
||||
catch (SymbolTable::AlreadyDeclaredException& e)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -615,7 +670,8 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool
|
|||
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 " << 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<StaticModel>(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
|
||||
|| 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)
|
||||
|
@ -690,25 +751,34 @@ ModFile::computingPass(bool no_tmp_terms, OutputType output, int params_derivs_o
|
|||
derivsOrder = 2;
|
||||
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
|
||||
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
|
||||
&& (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);
|
||||
|
@ -718,11 +788,15 @@ ModFile::computingPass(bool no_tmp_terms, OutputType output, int params_derivs_o
|
|||
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
|
||||
|
@ -771,8 +845,8 @@ void
|
|||
ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global, bool no_warn,
|
||||
bool console, bool nograph, bool nointeractive, const ConfigFile& config_file,
|
||||
bool 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,7 +869,8 @@ 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);
|
||||
|
@ -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,13 +896,17 @@ 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
|
||||
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
|
||||
|
@ -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,16 +967,17 @@ 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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -1001,41 +1084,60 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global,
|
|||
if (auto evs = dynamic_cast<EndValStatement*>(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<LoadParamsAndSteadyStateStatement *>(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<LoadParamsAndSteadyStateStatement*>(statement.get());
|
||||
lpass && !no_static)
|
||||
static_model.writeAuxVarInitval(mOutputFile, ExprNodeOutputType::matlabOutsideModel);
|
||||
}
|
||||
|
||||
if (!notime)
|
||||
mOutputFile << endl << 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
|
|
@ -20,24 +20,24 @@
|
|||
#ifndef _MOD_FILE_HH
|
||||
#define _MOD_FILE_HH
|
||||
|
||||
#include <ostream>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
#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;
|
||||
|
||||
|
@ -90,7 +90,8 @@ public:
|
|||
“model” block or on the preprocessor command line) */
|
||||
bool use_dll {false};
|
||||
|
||||
//! Is the static model have to computed (no_static=false) or not (no_static=true). Option of 'model'
|
||||
//! 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?
|
||||
|
@ -124,8 +125,10 @@ private:
|
|||
//! Warnings Encountered
|
||||
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 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
|
||||
|
@ -138,13 +141,15 @@ private:
|
|||
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);
|
||||
|
||||
public:
|
||||
//! Add a statement
|
||||
void addStatement(unique_ptr<Statement> st);
|
||||
//! Add a statement at the front of the statements vector
|
||||
void addStatementAtFront(unique_ptr<Statement> 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 */
|
||||
|
@ -154,13 +159,14 @@ public:
|
|||
void transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool transform_unary_ops,
|
||||
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?
|
||||
|
@ -172,17 +178,20 @@ public:
|
|||
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 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
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
||||
#include "ModelEquationBlock.hh"
|
||||
|
@ -37,11 +37,10 @@ PlannerObjective::computingPassBlock([[maybe_unused]] const eval_context_t &eval
|
|||
// Disable block decomposition on planner objective
|
||||
}
|
||||
|
||||
OrigRamseyDynamicModel::OrigRamseyDynamicModel(SymbolTable &symbol_table_arg,
|
||||
NumericalConstants &num_constants_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) :
|
||||
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}
|
||||
{
|
||||
|
@ -64,8 +63,7 @@ SteadyStateModel::SteadyStateModel(SymbolTable &symbol_table_arg,
|
|||
}
|
||||
|
||||
SteadyStateModel::SteadyStateModel(const SteadyStateModel& m) :
|
||||
DataTree{m},
|
||||
static_model{m.static_model}
|
||||
DataTree {m}, static_model {m.static_model}
|
||||
{
|
||||
for (const auto& it : m.def_table)
|
||||
def_table.emplace_back(it.first, it.second->clone(*this));
|
||||
|
@ -126,7 +124,8 @@ SteadyStateModel::checkPass(ModFileStructure &mod_file_struct, WarningConsolidat
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +156,8 @@ SteadyStateModel::checkPass(ModFileStructure &mod_file_struct, WarningConsolidat
|
|||
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
|
||||
|
@ -191,16 +193,14 @@ SteadyStateModel::writeLatexSteadyStateFile(const string &basename) const
|
|||
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();
|
||||
|
@ -212,7 +212,8 @@ 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)
|
||||
|
@ -257,7 +258,8 @@ 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
|
||||
|
@ -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,8 +314,7 @@ SteadyStateModel::writeJsonSteadyStateFile(ostream &output, bool transformComput
|
|||
output << "]}";
|
||||
}
|
||||
|
||||
Epilogue::Epilogue(SymbolTable &symbol_table_arg,
|
||||
NumericalConstants &num_constants_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) :
|
||||
|
@ -324,8 +323,7 @@ Epilogue::Epilogue(SymbolTable &symbol_table_arg,
|
|||
{
|
||||
}
|
||||
|
||||
Epilogue::Epilogue(const Epilogue &m) :
|
||||
DynamicModel{m}
|
||||
Epilogue::Epilogue(const Epilogue& m) : DynamicModel {m}
|
||||
{
|
||||
for (const auto& it : m.dynamic_def_table)
|
||||
dynamic_def_table.emplace_back(it.first, it.second->clone(*this));
|
||||
|
@ -356,7 +354,9 @@ Epilogue::checkPass(ModFileStructure &mod_file_struct) const
|
|||
{
|
||||
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;
|
||||
|
@ -385,8 +385,7 @@ void
|
|||
Epilogue::detrend(const map<int, expr_t>& 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 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);
|
||||
|
@ -433,21 +432,25 @@ Epilogue::writeStaticEpilogueFile(const string &basename) const
|
|||
|
||||
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;
|
||||
|
@ -467,7 +470,8 @@ 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;
|
||||
|
@ -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,10 +501,9 @@ 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();
|
||||
|
@ -511,16 +514,14 @@ 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<int> endogs;
|
||||
for (const auto& [symb_id, expr] : dynamic_def_table)
|
||||
|
|
|
@ -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,
|
||||
PlannerObjective(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg,
|
||||
ExternalFunctionsTable& external_functions_table_arg);
|
||||
|
||||
protected:
|
||||
string
|
||||
modelClassName() const override
|
||||
|
@ -46,8 +46,7 @@ private:
|
|||
class OrigRamseyDynamicModel : public DynamicModel
|
||||
{
|
||||
public:
|
||||
OrigRamseyDynamicModel(SymbolTable &symbol_table_arg,
|
||||
NumericalConstants &num_constants_arg,
|
||||
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);
|
||||
|
@ -64,15 +63,15 @@ 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<pair<vector<int>, expr_t>> def_table;
|
||||
|
||||
//! Reference to static model (for writing auxiliary equations)
|
||||
const StaticModel& static_model;
|
||||
|
||||
public:
|
||||
SteadyStateModel(SymbolTable &symbol_table_arg,
|
||||
NumericalConstants &num_constants_arg,
|
||||
SteadyStateModel(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg,
|
||||
ExternalFunctionsTable& external_functions_table_arg,
|
||||
const StaticModel& static_model_arg);
|
||||
|
||||
|
@ -85,7 +84,8 @@ public:
|
|||
void addMultipleDefinitions(const vector<int>& 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;
|
||||
//! Write the steady state file
|
||||
|
@ -99,11 +99,12 @@ public:
|
|||
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<pair<int, expr_t>> dynamic_def_table, static_def_table;
|
||||
|
||||
public:
|
||||
Epilogue(SymbolTable &symbol_table_arg,
|
||||
NumericalConstants &num_constants_arg,
|
||||
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);
|
||||
|
|
292
src/ModelTree.cc
292
src/ModelTree.cc
|
@ -33,9 +33,9 @@
|
|||
# include <mach-o/dyld.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <regex>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
|
||||
/* 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,7 +44,8 @@
|
|||
condition_variable_any ModelTree::mex_compilation_cv;
|
||||
mutex ModelTree::mex_compilation_mut;
|
||||
vector<tuple<filesystem::path, set<filesystem::path>, string>> ModelTree::mex_compilation_queue;
|
||||
set<filesystem::path> ModelTree::mex_compilation_ongoing, ModelTree::mex_compilation_done, ModelTree::mex_compilation_failed;
|
||||
set<filesystem::path> ModelTree::mex_compilation_ongoing, ModelTree::mex_compilation_done,
|
||||
ModelTree::mex_compilation_failed;
|
||||
vector<jthread> ModelTree::mex_compilation_workers;
|
||||
|
||||
void
|
||||
|
@ -58,8 +59,7 @@ ModelTree::copyHelper(const ModelTree &m)
|
|||
for (const auto& it : m.aux_equations)
|
||||
aux_equations.push_back(dynamic_cast<BinaryOpNode*>(f(it)));
|
||||
|
||||
auto convert_deriv_map = [f](const map<vector<int>, expr_t> &dm)
|
||||
{
|
||||
auto convert_deriv_map = [f](const map<vector<int>, expr_t>& dm) {
|
||||
map<vector<int>, expr_t> dm2;
|
||||
for (const auto& it : dm)
|
||||
dm2.emplace(it.first, f(it.second));
|
||||
|
@ -74,8 +74,7 @@ ModelTree::copyHelper(const ModelTree &m)
|
|||
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)
|
||||
{
|
||||
auto convert_temporary_terms_t = [f](const temporary_terms_t& tt) {
|
||||
temporary_terms_t tt2;
|
||||
for (const auto& it : tt)
|
||||
tt2.insert(f(it));
|
||||
|
@ -99,7 +98,8 @@ ModelTree::copyHelper(const ModelTree &m)
|
|||
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<BinaryOpNode *>(f(it.second)));
|
||||
equation_type_and_normalized_equation.emplace_back(it.first,
|
||||
dynamic_cast<BinaryOpNode*>(f(it.second)));
|
||||
|
||||
for (const auto& it : m.blocks_derivatives)
|
||||
{
|
||||
|
@ -109,8 +109,7 @@ ModelTree::copyHelper(const ModelTree &m)
|
|||
blocks_derivatives.push_back(v);
|
||||
}
|
||||
|
||||
auto convert_vector_tt = [f](vector<temporary_terms_t> vtt)
|
||||
{
|
||||
auto convert_vector_tt = [f](vector<temporary_terms_t> vtt) {
|
||||
vector<temporary_terms_t> vtt2;
|
||||
for (const auto& tt : vtt)
|
||||
{
|
||||
|
@ -135,17 +134,16 @@ ModelTree::copyHelper(const ModelTree &m)
|
|||
}
|
||||
}
|
||||
|
||||
ModelTree::ModelTree(SymbolTable &symbol_table_arg,
|
||||
NumericalConstants &num_constants_arg,
|
||||
ExternalFunctionsTable &external_functions_table_arg,
|
||||
bool is_dynamic_arg) :
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -257,13 +255,17 @@ ModelTree::computeNormalization(const jacob_map_t &contemporaneous_jacobian)
|
|||
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<BipartiteGraph>::null_vertex());
|
||||
if (auto it = find(mate_map.begin(), mate_map.begin() + n,
|
||||
boost::graph_traits<BipartiteGraph>::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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -296,7 +300,12 @@ ModelTree::computeNonSingularNormalization(const eval_context_t &eval_context)
|
|||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,8 +371,8 @@ ModelTree::computeNonSingularNormalization(const eval_context_t &eval_context)
|
|||
}
|
||||
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;
|
||||
|
@ -381,8 +390,7 @@ ModelTree::evaluateAndReduceJacobian(const eval_context_t &eval_context) const
|
|||
int eq = indices[0];
|
||||
int var {getTypeSpecificIDByDerivID(deriv_id)};
|
||||
int lag = getLagByDerivID(deriv_id);
|
||||
double val { [&]
|
||||
{
|
||||
double val {[&] {
|
||||
try
|
||||
{
|
||||
return d1->eval(eval_context);
|
||||
|
@ -509,7 +517,8 @@ ModelTree::computePrologueAndEpilogue()
|
|||
}
|
||||
|
||||
void
|
||||
ModelTree::equationTypeDetermination(const map<tuple<int, int, int>, expr_t> &first_order_endo_derivatives)
|
||||
ModelTree::equationTypeDetermination(
|
||||
const map<tuple<int, int, int>, expr_t>& first_order_endo_derivatives)
|
||||
{
|
||||
equation_type_and_normalized_equation.clear();
|
||||
equation_type_and_normalized_equation.resize(equations.size());
|
||||
|
@ -536,7 +545,8 @@ ModelTree::equationTypeDetermination(const map<tuple<int, int, int>, expr_t> &fi
|
|||
|
||||
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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -642,10 +653,8 @@ ModelTree::computeBlockDecomposition(int prologue, int epilogue)
|
|||
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);
|
||||
|
@ -698,20 +707,23 @@ 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
|
||||
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<int> old_eq_idx_block2orig(eq_idx_block2orig), old_endo_idx_block2orig(endo_idx_block2orig);
|
||||
const vector<int> 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++)
|
||||
{
|
||||
blocks[blk].first_equation = (blk == 0 ? 0 : blocks[blk-1].first_equation + blocks[blk-1].size);
|
||||
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();
|
||||
|
@ -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
|
||||
|
@ -796,11 +809,9 @@ ModelTree::reduceBlockDecomposition()
|
|||
}
|
||||
|
||||
if ((blocks[blk - 1].simulation_type == BlockSimulationType::evaluateForward
|
||||
&& blocks[blk].simulation_type == BlockSimulationType::evaluateForward
|
||||
&& !is_lead)
|
||||
&& blocks[blk].simulation_type == BlockSimulationType::evaluateForward && !is_lead)
|
||||
|| (blocks[blk - 1].simulation_type == BlockSimulationType::evaluateBackward
|
||||
&& blocks[blk].simulation_type == BlockSimulationType::evaluateBackward
|
||||
&& !is_lag))
|
||||
&& blocks[blk].simulation_type == BlockSimulationType::evaluateBackward && !is_lag))
|
||||
{
|
||||
// Merge the current block into the previous one
|
||||
blocks[blk - 1].size++;
|
||||
|
@ -898,8 +909,10 @@ ModelTree::computeDerivatives(int order, const set<int> &vars)
|
|||
|
||||
// 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));
|
||||
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++)
|
||||
|
@ -930,8 +943,7 @@ 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<int> used_local_vars;
|
||||
for (auto& equation : equations)
|
||||
equation->collectVariables(SymbolType::modelLocalVariable, used_local_vars);
|
||||
|
@ -943,32 +955,26 @@ ModelTree::computeTemporaryTerms(bool is_matlab, bool no_tmp_terms)
|
|||
unordered_map<expr_t, pair<int, pair<int, int>>> reference_count;
|
||||
|
||||
for (auto& equation : equations)
|
||||
equation->computeTemporaryTerms({ 0, 0 },
|
||||
temp_terms_map,
|
||||
reference_count,
|
||||
is_matlab);
|
||||
equation->computeTemporaryTerms({0, 0}, temp_terms_map, reference_count, is_matlab);
|
||||
|
||||
for (int order = 1; order < static_cast<int>(derivatives.size()); order++)
|
||||
for (const auto& it : derivatives[order])
|
||||
it.second->computeTemporaryTerms({ order, 0 },
|
||||
temp_terms_map,
|
||||
reference_count,
|
||||
is_matlab);
|
||||
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<AbstractExternalFunctionNode *>(e); });
|
||||
erase_if(it.second, [](expr_t e) { return !dynamic_cast<AbstractExternalFunctionNode*>(e); });
|
||||
|
||||
// Fill the structures
|
||||
temporary_terms_derivatives.clear();
|
||||
temporary_terms_derivatives.resize(derivatives.size());
|
||||
for (int order = 0; order < static_cast<int>(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()));
|
||||
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<int>(derivatives.size()); order++)
|
||||
|
@ -998,9 +1004,11 @@ 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])
|
||||
d->computeBlockTemporaryTerms(blk, blocks[blk].size, temp_terms, reference_count);
|
||||
|
@ -1019,30 +1027,29 @@ ModelTree::computeBlockTemporaryTerms(bool no_tmp_terms)
|
|||
{
|
||||
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 (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<AbstractExternalFunctionNode*>(it))
|
||||
{
|
||||
|
@ -1050,8 +1057,7 @@ ModelTree::writeJsonTemporaryTerms(const temporary_terms_t &tt,
|
|||
output << ", ";
|
||||
vector<string> 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<string, string> &tmp_paren_vars, bool &message_printed) const
|
||||
ModelTree::fixNestedParenthesis(ostringstream& output, map<string, string>& tmp_paren_vars,
|
||||
bool& message_printed) const
|
||||
{
|
||||
string str = output.str();
|
||||
if (!testNestedParenthesis(str))
|
||||
|
@ -1112,11 +1118,23 @@ ModelTree::fixNestedParenthesis(ostringstream &output, map<string, string> &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<string, string> &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<string, string> &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";
|
||||
|
@ -1183,8 +1200,7 @@ ModelTree::fixNestedParenthesis(ostringstream &output, map<string, string> &tmp_
|
|||
bool
|
||||
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<string> 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;
|
||||
}
|
||||
|
@ -1251,8 +1265,7 @@ ModelTree::writeBytecodeBinFile(const filesystem::path &filename, bool is_two_bo
|
|||
}
|
||||
int u_count {0};
|
||||
for (const auto& [indices, d1] : derivatives[1])
|
||||
if (int deriv_id {indices[1]};
|
||||
getTypeByDerivID(deriv_id) == SymbolType::endogenous)
|
||||
if (int deriv_id {indices[1]}; getTypeByDerivID(deriv_id) == SymbolType::endogenous)
|
||||
{
|
||||
int eq {indices[0]};
|
||||
SaveCode.write(reinterpret_cast<char*>(&eq), sizeof eq);
|
||||
|
@ -1319,7 +1332,8 @@ ModelTree::writeBlockBytecodeBinFile(ofstream &bin_file, int block) const
|
|||
}
|
||||
|
||||
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");
|
||||
|
||||
|
@ -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
|
||||
// Here it is necessary to cast to superclass ExprNode, otherwise the overloaded writeOutput()
|
||||
// method is not found
|
||||
dynamic_cast<ExprNode*>(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();
|
||||
|
@ -1423,7 +1438,8 @@ ModelTree::addTrendVariables(const vector<int> &trend_vars, expr_t growth_factor
|
|||
}
|
||||
|
||||
void
|
||||
ModelTree::addNonstationaryVariables(const vector<int> &nonstationary_vars, bool log_deflator, expr_t deflator) noexcept(false)
|
||||
ModelTree::addNonstationaryVariables(const vector<int>& nonstationary_vars, bool log_deflator,
|
||||
expr_t deflator) noexcept(false)
|
||||
{
|
||||
for (int id : nonstationary_vars)
|
||||
if (nonstationary_symbols_map.contains(id))
|
||||
|
@ -1493,7 +1509,8 @@ ModelTree::computeParamsDerivatives(int paramsDerivsOrder)
|
|||
continue;
|
||||
vector<int> indices {lower_indices};
|
||||
indices.push_back(param);
|
||||
// At this point, indices of both endogenous and parameters are sorted in non-decreasing order
|
||||
// At this point, indices of both endogenous and parameters are sorted in non-decreasing
|
||||
// order
|
||||
params_derivatives[{endoOrd, paramOrd}][indices] = d;
|
||||
}
|
||||
}
|
||||
|
@ -1512,10 +1529,10 @@ ModelTree::computeParamsDerivativesTemporaryTerms()
|
|||
|
||||
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 (int idx {0}; const auto& [order, tts] : params_derivs_temporary_terms)
|
||||
for (const auto& tt : tts)
|
||||
params_derivs_temporary_terms_idxs[tt] = idx++;
|
||||
}
|
||||
|
@ -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 << ", ";
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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<filesystem::path> &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<filesystem::path>& 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,10 +1742,10 @@ 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))
|
||||
else if (!filesystem::exists(user_set_compiler))
|
||||
{
|
||||
cerr << "Error: The specified compiler '" << user_set_compiler << "' cannot be found on your system" << endl;
|
||||
cerr << "Error: The specified compiler '" << user_set_compiler
|
||||
<< "' cannot be found on your system" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else
|
||||
|
@ -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<filesystem::path> 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<mutex> lk {mex_compilation_mut};
|
||||
mex_compilation_queue.emplace_back(output_filename, prerequisites, cmd.str());
|
||||
|
@ -1799,8 +1819,7 @@ ModelTree::reorderAuxiliaryEquations()
|
|||
set<int> 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);
|
||||
}
|
||||
|
||||
|
@ -1853,7 +1872,8 @@ ModelTree::computeLeftHandSideSymbolicJacobian() const
|
|||
auto not_contemporaneous = [](const pair<int, int>& p) { return p.second != 0; };
|
||||
|
||||
for (int eq {0}; eq < static_cast<int>(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<pair<int, int>> endos_and_lags;
|
||||
equations[eq]->arg1->collectEndogenous(endos_and_lags);
|
||||
|
@ -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<mutex> lk {mex_compilation_mut};
|
||||
filesystem::path output;
|
||||
string cmd;
|
||||
|
@ -1916,8 +1935,7 @@ 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
|
||||
includes(mex_compilation_done.begin(), mex_compilation_done.end(),
|
||||
|
@ -1997,7 +2015,8 @@ ModelTree::waitForMEXCompilationWorkers()
|
|||
unique_lock<mutex> 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: ";
|
||||
|
@ -2031,8 +2050,7 @@ vector<int>
|
|||
ModelTree::computeCSCColPtr(const SparseColumnMajorOrderMatrix& matrix, int ncols)
|
||||
{
|
||||
vector<int> colptr(ncols + 1, matrix.size());
|
||||
for (int k {0}, current_col {0};
|
||||
const auto &[indices, d1] : matrix)
|
||||
for (int k {0}, current_col {0}; const auto& [indices, d1] : matrix)
|
||||
{
|
||||
while (indices.second >= current_col)
|
||||
colptr[current_col++] = k;
|
||||
|
|
968
src/ModelTree.hh
968
src/ModelTree.hh
File diff suppressed because it is too large
Load Diff
|
@ -17,17 +17,16 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "NumericalConstants.hh"
|
||||
|
||||
int
|
||||
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<int>(mNumericalConstants.size());
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
#ifndef _NUMERICALCONSTANTS_HH
|
||||
#define _NUMERICALCONSTANTS_HH
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -36,6 +36,7 @@ private:
|
|||
vector<double> double_vals;
|
||||
//! Map matching constants to their id
|
||||
map<string, int> numConstantsIndex;
|
||||
|
||||
public:
|
||||
//! Adds a non-negative constant (possibly Inf or NaN) and returns its ID
|
||||
int AddNonNegativeConstant(const string& iConst);
|
||||
|
|
|
@ -17,36 +17,36 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#include "NumericalInitialization.hh"
|
||||
|
||||
InitParamStatement::InitParamStatement(int symb_id_arg,
|
||||
const expr_t param_value_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}
|
||||
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 << ") = ";
|
||||
|
@ -59,7 +59,9 @@ InitParamStatement::writeOutput(ostream &output, [[maybe_unused]] const string &
|
|||
void
|
||||
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"("})";
|
||||
}
|
||||
|
@ -163,14 +165,14 @@ InitOrEndValStatement::writeInitValues(ostream &output) const
|
|||
void
|
||||
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"("})";
|
||||
}
|
||||
|
@ -220,9 +222,7 @@ void
|
|||
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;
|
||||
|
||||
|
@ -248,8 +248,7 @@ InitValStatement::writeOutputPostInit(ostream &output) const
|
|||
<< "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}
|
||||
{
|
||||
|
@ -288,9 +287,7 @@ void
|
|||
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;
|
||||
|
@ -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;
|
||||
|
@ -359,10 +356,8 @@ EndValLearntInStatement::writeOutput(ostream &output, [[maybe_unused]] const str
|
|||
void
|
||||
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;
|
||||
|
@ -430,15 +425,18 @@ HistValStatement::writeOutput(ostream &output, [[maybe_unused]] const string &ba
|
|||
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)
|
||||
{
|
||||
|
@ -446,29 +444,38 @@ HistValStatement::writeOutput(ostream &output, [[maybe_unused]] const string &ba
|
|||
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
|
||||
{
|
||||
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;
|
||||
if (symbol_table.getType(symb_id) == SymbolType::unusedEndogenous) // See #82
|
||||
|
@ -476,8 +483,7 @@ HistValStatement::writeJsonOutput(ostream &output) const
|
|||
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"("})";
|
||||
}
|
||||
|
@ -498,7 +504,9 @@ 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
|
||||
|
@ -527,7 +535,9 @@ 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
|
||||
|
@ -558,7 +568,8 @@ HomotopySetupStatement::writeOutput(ostream &output, [[maybe_unused]] const stri
|
|||
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<int>(type) << ", " << tsid << ", ";
|
||||
output << "options_.homotopy_values = vertcat(options_.homotopy_values, [ "
|
||||
<< static_cast<int>(type) << ", " << tsid << ", ";
|
||||
if (expression1)
|
||||
expression1->writeOutput(output);
|
||||
else
|
||||
|
@ -608,7 +620,8 @@ SaveParamsAndSteadyStateStatement::SaveParamsAndSteadyStateStatement(string file
|
|||
}
|
||||
|
||||
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;
|
||||
|
@ -622,8 +635,8 @@ SaveParamsAndSteadyStateStatement::writeJsonOutput(ostream &output) const
|
|||
<< "}";
|
||||
}
|
||||
|
||||
LoadParamsAndSteadyStateStatement::LoadParamsAndSteadyStateStatement(const filesystem::path &filename,
|
||||
const SymbolTable &symbol_table_arg,
|
||||
LoadParamsAndSteadyStateStatement::LoadParamsAndSteadyStateStatement(
|
||||
const filesystem::path& filename, const SymbolTable& symbol_table_arg,
|
||||
WarningConsolidation& warnings) :
|
||||
symbol_table {symbol_table_arg}
|
||||
{
|
||||
|
@ -651,14 +664,16 @@ LoadParamsAndSteadyStateStatement::LoadParamsAndSteadyStateStatement(const files
|
|||
}
|
||||
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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -692,8 +708,7 @@ 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 << ", ";
|
||||
|
|
|
@ -20,14 +20,14 @@
|
|||
#ifndef _NUMERICALINITIALIZATION_HH
|
||||
#define _NUMERICALINITIALIZATION_HH
|
||||
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <filesystem>
|
||||
|
||||
#include "SymbolTable.hh"
|
||||
#include "ExprNode.hh"
|
||||
#include "Statement.hh"
|
||||
#include "SymbolTable.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -37,6 +37,7 @@ private:
|
|||
const int symb_id;
|
||||
const expr_t param_value;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
InitParamStatement(int symb_id_arg, const expr_t param_value_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -55,18 +56,20 @@ public:
|
|||
an initialization can depend on a previously initialized variable inside the block
|
||||
*/
|
||||
using init_values_t = vector<pair<int, expr_t>>;
|
||||
|
||||
protected:
|
||||
const init_values_t init_values;
|
||||
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<int> getUninitializedVariables(SymbolType type);
|
||||
//! Fill eval context with variables values
|
||||
void fillEvalContext(eval_context_t& eval_context) const;
|
||||
|
||||
protected:
|
||||
void writeInitValues(ostream& output) const;
|
||||
void writeJsonInitValues(ostream& output) const;
|
||||
|
@ -75,8 +78,7 @@ protected:
|
|||
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;
|
||||
|
@ -88,8 +90,7 @@ public:
|
|||
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;
|
||||
|
@ -110,12 +111,13 @@ public:
|
|||
// The tuple is (type, symb_id, value)
|
||||
using learnt_end_values_t = vector<tuple<LearntEndValType, int, expr_t>>;
|
||||
const learnt_end_values_t learnt_end_values;
|
||||
|
||||
private:
|
||||
const SymbolTable& symbol_table;
|
||||
static string typeToString(LearntEndValType type);
|
||||
|
||||
public:
|
||||
EndValLearntInStatement(int learnt_in_period_arg,
|
||||
learnt_end_values_t learnt_end_values_arg,
|
||||
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;
|
||||
|
@ -131,13 +133,14 @@ public:
|
|||
Maps pairs (symbol_id, lag) to expr_t
|
||||
*/
|
||||
using hist_values_t = map<pair<int, int>, expr_t>;
|
||||
|
||||
private:
|
||||
const hist_values_t hist_values;
|
||||
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;
|
||||
|
@ -149,6 +152,7 @@ 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;
|
||||
|
@ -159,6 +163,7 @@ 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;
|
||||
|
@ -171,10 +176,12 @@ 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<tuple<int, expr_t, expr_t>>;
|
||||
|
||||
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;
|
||||
|
||||
public:
|
||||
HomotopySetupStatement(bool from_initval_to_endval_arg, homotopy_values_t homotopy_values_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -186,6 +193,7 @@ 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;
|
||||
|
@ -199,6 +207,7 @@ private:
|
|||
//! Content of the file
|
||||
/*! Maps symbol ID to numeric value (stored as string) */
|
||||
map<int, string> content;
|
||||
|
||||
public:
|
||||
LoadParamsAndSteadyStateStatement(const filesystem::path& filename,
|
||||
const SymbolTable& symbol_table_arg,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -24,24 +24,24 @@
|
|||
# error Impossible to include both ParsingDriver.hh and macro/Driver.hh
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <istream>
|
||||
#include <stack>
|
||||
#include <optional>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#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;
|
||||
|
||||
|
@ -66,8 +66,7 @@ public:
|
|||
|
||||
//! The main lexing function
|
||||
Dynare::parser::token_type lex(Dynare::parser::semantic_type* yylval,
|
||||
Dynare::parser::location_type *yylloc,
|
||||
ParsingDriver &driver);
|
||||
Dynare::parser::location_type* yylloc, ParsingDriver& driver);
|
||||
|
||||
//! The filename being parsed
|
||||
/*! The bison parser locations (begin and end) contain a pointer to that string */
|
||||
|
@ -88,27 +87,32 @@ private:
|
|||
//! Checks that a given symbol exists, and stops with an error message if it doesn't
|
||||
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
|
||||
//! 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);
|
||||
|
||||
//! Checks that a given symbol exists and is a endogenous or exogenous, and stops with an error message if it isn't
|
||||
//! 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
|
||||
//! 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
|
||||
//! 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
|
||||
//! 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<pair<string, string>> &partition_value);
|
||||
int declare_symbol(const string& name, SymbolType type, const string& tex_name,
|
||||
const vector<pair<string, string>>& partition_value);
|
||||
|
||||
//! Temporary store for the planner objective
|
||||
unique_ptr<PlannerObjective> planner_objective;
|
||||
|
@ -122,11 +126,13 @@ private:
|
|||
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 */
|
||||
/*! 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 */
|
||||
/*! 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
|
||||
|
@ -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<int, vector<int>> 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<int, int> svar_Qi_restriction_nbr;
|
||||
|
@ -214,15 +223,18 @@ private:
|
|||
stack<vector<expr_t>> stack_external_function_args;
|
||||
//! Temporary storage for parameters in joint prior statement
|
||||
vector<string> 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<pair<var_name1, var_name2>>, subsample_declaration_map >
|
||||
using subsample_declarations_t = map<pair<string, string >, SubsamplesStatement::subsample_declaration_map_t >;
|
||||
//! Temporary storage for subsample statement: map<pair<var_name1, var_name2>>,
|
||||
//! subsample_declaration_map >
|
||||
using subsample_declarations_t
|
||||
= map<pair<string, string>, SubsamplesStatement::subsample_declaration_map_t>;
|
||||
subsample_declarations_t subsample_declarations;
|
||||
//! Temporary storage for shock_groups
|
||||
vector<string> shock_group;
|
||||
|
@ -273,7 +285,7 @@ public:
|
|||
ParsingDriver(WarningConsolidation& warnings_arg, bool nostrict_arg) :
|
||||
warnings {warnings_arg}, nostrict {nostrict_arg}
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
ParsingDriver(const ParsingDriver&) = delete;
|
||||
ParsingDriver& operator=(const ParsingDriver&) = delete;
|
||||
|
@ -308,13 +320,16 @@ public:
|
|||
//! Warning handler using saved location
|
||||
void warning(const string& m);
|
||||
|
||||
//! Error handler with explicit location (used in model block, accumulating error messages to be printed later)
|
||||
//! 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);
|
||||
|
@ -352,17 +367,21 @@ public:
|
|||
//! 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<pair<string, string>> &partition_value = {});
|
||||
int declare_endogenous(const string& name, const string& tex_name = "",
|
||||
const vector<pair<string, string>>& partition_value = {});
|
||||
// Handles a “var” or “var(log)” statement (without “deflator” or “log_deflator” options)
|
||||
void var(const vector<tuple<string, string, vector<pair<string, string>>>> &symbol_list, bool log_option);
|
||||
void var(const vector<tuple<string, string, vector<pair<string, string>>>>& 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<pair<string, string>> &partition_value = {});
|
||||
int declare_exogenous(const string& name, const string& tex_name = "",
|
||||
const vector<pair<string, string>>& partition_value = {});
|
||||
// Handles a “varexo” statement
|
||||
void varexo(const vector<tuple<string, string, vector<pair<string, string>>>>& symbol_list);
|
||||
// Handles a “varexo_det” statement
|
||||
void varexo_det(const vector<tuple<string, string, vector<pair<string, string>>>>& symbol_list);
|
||||
//! Declares a parameter (and returns its symbol ID)
|
||||
int declare_parameter(const string &name, const string &tex_name = "", const vector<pair<string, string>> &partition_value = {});
|
||||
int declare_parameter(const string& name, const string& tex_name = "",
|
||||
const vector<pair<string, string>>& partition_value = {});
|
||||
// Handles a “parameters” statement
|
||||
void parameters(const vector<tuple<string, string, vector<pair<string, string>>>>& symbol_list);
|
||||
// Handles a “model_local_variable” statement
|
||||
|
@ -375,7 +394,8 @@ public:
|
|||
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& 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}
|
||||
|
@ -449,7 +469,8 @@ public:
|
|||
//! Writes a shocks(learnt_in=…) block
|
||||
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
|
||||
|
@ -461,9 +482,11 @@ public:
|
|||
multiply, // for “multiply” in “shocks(learnt_in)”
|
||||
conditional_forecast
|
||||
};
|
||||
void add_det_shock(const string &var, const vector<pair<int, int>> &periods, const vector<expr_t> &values, DetShockType type);
|
||||
void add_det_shock(const string& var, const vector<pair<int, int>>& periods,
|
||||
const vector<expr_t>& values, DetShockType type);
|
||||
//! Adds a heteroskedastic shock (either values or scales)
|
||||
void add_heteroskedastic_shock(const string &var, const vector<pair<int, int>> &periods, const vector<expr_t> &values, bool scales);
|
||||
void add_heteroskedastic_shock(const string& var, const vector<pair<int, int>>& periods,
|
||||
const vector<expr_t>& values, bool scales);
|
||||
//! Adds a std error shock
|
||||
void add_stderr_shock(const string& var, expr_t value);
|
||||
//! Adds a variance shock
|
||||
|
@ -550,13 +573,15 @@ public:
|
|||
//! 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
|
||||
|
@ -836,11 +861,13 @@ public:
|
|||
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();
|
||||
|
@ -851,14 +878,19 @@ public:
|
|||
//! Add a multiple assignment equation in steady_state_model block
|
||||
void add_steady_state_model_equal_multiple(const vector<string>& symbol_list, expr_t expr);
|
||||
//! Ends declaration of trend variable
|
||||
void end_trend_var(bool log_trend, expr_t growth_factor, const vector<pair<string, string>> &symbol_list);
|
||||
void end_trend_var(bool log_trend, expr_t growth_factor,
|
||||
const vector<pair<string, string>>& 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<tuple<string, string, vector<pair<string, string>>>> &symbol_list, bool log_option);
|
||||
void end_nonstationary_var(
|
||||
bool log_deflator, expr_t deflator,
|
||||
const vector<tuple<string, string, vector<pair<string, string>>>>& 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<expr_t, expr_t> &range);
|
||||
void add_moment_calibration_item(const string& endo1, const string& endo2, string lags,
|
||||
const pair<expr_t, expr_t>& 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<expr_t, expr_t> &range);
|
||||
void add_irf_calibration_item(const string& endo, string periods, const string& exo,
|
||||
const pair<expr_t, expr_t>& range);
|
||||
//! End a moment_calibration statement
|
||||
void end_irf_calibration();
|
||||
//! Add a shock to a group
|
||||
|
@ -902,7 +936,8 @@ public:
|
|||
//! Start parsing an occbin_constraints block
|
||||
void begin_occbin_constraints();
|
||||
//! Add an occbin_constraints block
|
||||
void end_occbin_constraints(vector<tuple<string, BinaryOpNode *, BinaryOpNode *, expr_t, expr_t>> constraints);
|
||||
void end_occbin_constraints(
|
||||
vector<tuple<string, BinaryOpNode*, BinaryOpNode*, expr_t, expr_t>> constraints);
|
||||
// Process a model_remove statement
|
||||
void model_remove(const vector<map<string, string>>& listed_eqs_by_tags);
|
||||
// Begin a model_replace statement
|
||||
|
@ -922,7 +957,8 @@ public:
|
|||
// Returns true iff the string is a legal symbol identifier (see NAME token in lexer)
|
||||
static bool isSymbolIdentifier(const string& str);
|
||||
// Given an Occbin regime name, returns the corresponding auxiliary parameter
|
||||
static string buildOccbinBindParamName(const string ®ime)
|
||||
static string
|
||||
buildOccbinBindParamName(const string& regime)
|
||||
{
|
||||
return "occbin_" + regime + "_bind";
|
||||
}
|
||||
|
|
278
src/Shocks.cc
278
src/Shocks.cc
|
@ -44,12 +44,9 @@ AbstractShocksStatement::writeDetShocks(ostream &output) const
|
|||
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;
|
||||
|
||||
|
@ -63,15 +60,13 @@ void
|
|||
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,14 +96,14 @@ 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},
|
||||
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)},
|
||||
|
@ -120,16 +115,14 @@ void
|
|||
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);
|
||||
|
@ -169,8 +160,7 @@ ShocksStatement::writeJsonOutput(ostream &output) const
|
|||
writeJsonDetShocks(output);
|
||||
}
|
||||
output << R"(, "variance": [)";
|
||||
for (bool printed_something{false};
|
||||
auto &[id, value] : var_shocks)
|
||||
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<int, expr_t> &it,
|
||||
bool stddev) const
|
||||
ShocksStatement::writeVarOrStdShock(ostream& output, const pair<int, expr_t>& it, bool stddev) const
|
||||
{
|
||||
SymbolType type = symbol_table.getType(it.first);
|
||||
assert(type == SymbolType::exogenous || symbol_table.isObservedVariable(it.first));
|
||||
|
@ -268,7 +254,8 @@ ShocksStatement::writeCovarOrCorrShock(ostream &output, const pair<pair<int, int
|
|||
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,19 +276,19 @@ ShocksStatement::writeCovarOrCorrShock(ostream &output, const pair<pair<int, int
|
|||
output << matrix << "(" << id1 << ", " << id2 << ") = ";
|
||||
it.second->writeOutput(output);
|
||||
if (corr)
|
||||
output << "*sqrt(" << matrix << "(" << id1 << ", " << id1 << ")*"
|
||||
<< matrix << "(" << id2 << ", " << id2 << "))";
|
||||
output << "*sqrt(" << matrix << "(" << id1 << ", " << id1 << ")*" << matrix << "(" << id2
|
||||
<< ", " << id2 << "))";
|
||||
output << ";" << endl
|
||||
<< matrix << "(" << id2 << ", " << id1 << ") = "
|
||||
<< matrix << "(" << id1 << ", " << id2 << ");" << endl;
|
||||
<< matrix << "(" << id2 << ", " << id1 << ") = " << matrix << "(" << id1 << ", " << id2
|
||||
<< ");" << endl;
|
||||
|
||||
if (corr)
|
||||
{
|
||||
output << corr_matrix << "(" << id1 << ", " << id2 << ") = ";
|
||||
it.second->writeOutput(output);
|
||||
output << ";" << endl
|
||||
<< corr_matrix << "(" << id2 << ", " << id1 << ") = "
|
||||
<< corr_matrix << "(" << id1 << ", " << id2 << ");" << endl;
|
||||
<< corr_matrix << "(" << id2 << ", " << id1 << ") = " << corr_matrix << "(" << id1
|
||||
<< ", " << id2 << ");" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,22 +311,24 @@ ShocksStatement::checkPass(ModFileStructure &mod_file_struct,
|
|||
Also Determine if there is a calibrated measurement error */
|
||||
for (auto [id, val] : var_shocks)
|
||||
{
|
||||
if (symbol_table.getType(id) != SymbolType::exogenous
|
||||
&& !symbol_table.isObservedVariable(id))
|
||||
if (symbol_table.getType(id) != SymbolType::exogenous && !symbol_table.isObservedVariable(id))
|
||||
{
|
||||
cerr << "shocks: setting a variance on '"
|
||||
<< symbol_table.getName(id) << "' is not allowed, because it is neither an exogenous variable nor an observed endogenous variable" << endl;
|
||||
cerr << "shocks: setting a variance on '" << symbol_table.getName(id)
|
||||
<< "' is not allowed, because it is neither an exogenous variable nor an observed "
|
||||
"endogenous variable"
|
||||
<< endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto [id, val] : std_shocks)
|
||||
{
|
||||
if (symbol_table.getType(id) != SymbolType::exogenous
|
||||
&& !symbol_table.isObservedVariable(id))
|
||||
if (symbol_table.getType(id) != SymbolType::exogenous && !symbol_table.isObservedVariable(id))
|
||||
{
|
||||
cerr << "shocks: setting a standard error on '"
|
||||
<< symbol_table.getName(id) << "' is not allowed, because it is neither an exogenous variable nor an observed endogenous variable" << endl;
|
||||
cerr << "shocks: setting a standard error on '" << symbol_table.getName(id)
|
||||
<< "' is not allowed, because it is neither an exogenous variable nor an observed "
|
||||
"endogenous variable"
|
||||
<< endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
@ -353,9 +342,11 @@ ShocksStatement::checkPass(ModFileStructure &mod_file_struct,
|
|||
|| (symbol_table.isObservedVariable(symb_id1)
|
||||
&& symbol_table.isObservedVariable(symb_id2))))
|
||||
{
|
||||
cerr << "shocks: setting a covariance between '"
|
||||
<< symbol_table.getName(symb_id1) << "' and '"
|
||||
<< symbol_table.getName(symb_id2) << "'is not allowed; covariances can only be specified for exogenous or observed endogenous variables of same type" << endl;
|
||||
cerr << "shocks: setting a covariance between '" << symbol_table.getName(symb_id1)
|
||||
<< "' and '" << symbol_table.getName(symb_id2)
|
||||
<< "'is not allowed; covariances can only be specified for exogenous or observed "
|
||||
"endogenous variables of same type"
|
||||
<< endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
@ -369,9 +360,11 @@ ShocksStatement::checkPass(ModFileStructure &mod_file_struct,
|
|||
|| (symbol_table.isObservedVariable(symb_id1)
|
||||
&& symbol_table.isObservedVariable(symb_id2))))
|
||||
{
|
||||
cerr << "shocks: setting a correlation between '"
|
||||
<< symbol_table.getName(symb_id1) << "' and '"
|
||||
<< symbol_table.getName(symb_id2) << "'is not allowed; correlations can only be specified for exogenous or observed endogenous variables of same type" << endl;
|
||||
cerr << "shocks: setting a correlation between '" << symbol_table.getName(symb_id1)
|
||||
<< "' and '" << symbol_table.getName(symb_id2)
|
||||
<< "'is not allowed; correlations can only be specified for exogenous or observed "
|
||||
"endogenous variables of same type"
|
||||
<< endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
@ -402,13 +395,11 @@ ShocksStatement::has_calibrated_measurement_errors() const
|
|||
return true;
|
||||
|
||||
for (const auto& [ids, val] : covar_shocks)
|
||||
if (symbol_table.isObservedVariable(ids.first)
|
||||
|| symbol_table.isObservedVariable(ids.second))
|
||||
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))
|
||||
if (symbol_table.isObservedVariable(ids.first) || symbol_table.isObservedVariable(ids.second))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -418,7 +409,8 @@ MShocksStatement::MShocksStatement(bool overwrite_arg, bool relative_to_initval_
|
|||
det_shocks_t det_shocks_arg,
|
||||
const SymbolTable& symbol_table_arg) :
|
||||
AbstractShocksStatement {overwrite_arg,
|
||||
relative_to_initval_arg ? ShockType::multiplyInitialSteadyState : ShockType::multiplySteadyState,
|
||||
relative_to_initval_arg ? ShockType::multiplyInitialSteadyState
|
||||
: ShockType::multiplySteadyState,
|
||||
move(det_shocks_arg), symbol_table_arg},
|
||||
relative_to_initval {relative_to_initval_arg}
|
||||
{
|
||||
|
@ -428,9 +420,7 @@ void
|
|||
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;
|
||||
|
@ -442,8 +432,8 @@ void
|
|||
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,10 +442,11 @@ MShocksStatement::writeJsonOutput(ostream &output) const
|
|||
output << "}";
|
||||
}
|
||||
|
||||
ShocksSurpriseStatement::ShocksSurpriseStatement(bool overwrite_arg,
|
||||
AbstractShocksStatement::det_shocks_t surprise_shocks_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)},
|
||||
overwrite {overwrite_arg},
|
||||
surprise_shocks {move(surprise_shocks_arg)},
|
||||
symbol_table {symbol_table_arg}
|
||||
{
|
||||
}
|
||||
|
@ -478,9 +469,8 @@ ShocksSurpriseStatement::writeOutput(ostream &output, [[maybe_unused]] const str
|
|||
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;
|
||||
}
|
||||
|
@ -493,15 +483,13 @@ 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 << ", ";
|
||||
|
@ -519,8 +507,10 @@ 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}
|
||||
learnt_in_period {learnt_in_period_arg},
|
||||
overwrite {overwrite_arg},
|
||||
learnt_shocks {move(learnt_shocks_arg)},
|
||||
symbol_table {symbol_table_arg}
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -556,17 +546,17 @@ ShocksLearntInStatement::writeOutput(ostream &output, [[maybe_unused]] const str
|
|||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
@ -578,18 +568,15 @@ void
|
|||
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,16 +592,15 @@ 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)
|
||||
|
@ -633,13 +619,13 @@ ConditionalForecastPathsStatement::writeOutput(ostream &output,
|
|||
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;
|
||||
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++)
|
||||
{
|
||||
|
@ -656,15 +642,13 @@ 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,8 +664,8 @@ 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}
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -693,14 +677,12 @@ MomentCalibration::writeOutput(ostream &output, [[maybe_unused]] const string &b
|
|||
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;
|
||||
}
|
||||
|
@ -710,8 +692,7 @@ 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,10 +711,11 @@ 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)}
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -747,14 +729,12 @@ IrfCalibration::writeOutput(ostream &output, [[maybe_unused]] const string &base
|
|||
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;
|
||||
}
|
||||
|
@ -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,8 +769,8 @@ 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)}
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -814,10 +793,9 @@ 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 = {";
|
||||
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;
|
||||
|
@ -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,8 +838,8 @@ ShockGroupsStatement::writeJsonOutput(ostream &output) const
|
|||
}
|
||||
|
||||
Init2shocksStatement::Init2shocksStatement(vector<pair<int, int>> 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}
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -887,7 +864,8 @@ Init2shocksStatement::writeOutput(ostream &output, [[maybe_unused]] const string
|
|||
{
|
||||
output << "M_.init2shocks." << name << " = {" << endl;
|
||||
for (const auto& [id1, id2] : init2shocks)
|
||||
output << "{'" << symbol_table.getName(id1) << "', '" << symbol_table.getName(id2) << "'};" << endl;
|
||||
output << "{'" << symbol_table.getName(id1) << "', '" << symbol_table.getName(id2) << "'};"
|
||||
<< endl;
|
||||
output << "};" << endl;
|
||||
}
|
||||
|
||||
|
@ -895,8 +873,7 @@ void
|
|||
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)},
|
||||
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()
|
||||
|
@ -928,9 +907,9 @@ HeteroskedasticShocksStatement::writeOutput(ostream &output, [[maybe_unused]] co
|
|||
for (int tsid = symbol_table.getTypeSpecificID(symb_id);
|
||||
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;
|
||||
}
|
||||
|
@ -938,9 +917,9 @@ HeteroskedasticShocksStatement::writeOutput(ostream &output, [[maybe_unused]] co
|
|||
for (int tsid = symbol_table.getTypeSpecificID(symb_id);
|
||||
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;
|
||||
}
|
||||
|
@ -950,17 +929,14 @@ void
|
|||
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 << ", ";
|
||||
|
|
|
@ -20,13 +20,13 @@
|
|||
#ifndef _SHOCKS_HH
|
||||
#define _SHOCKS_HH
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "ExprNode.hh"
|
||||
#include "Statement.hh"
|
||||
#include "SymbolTable.hh"
|
||||
#include "ExprNode.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -38,9 +38,12 @@ public:
|
|||
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)”)
|
||||
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;
|
||||
|
@ -51,8 +54,7 @@ protected:
|
|||
void writeJsonDetShocks(ostream& output) const;
|
||||
static string typeToString(ShockType type);
|
||||
|
||||
AbstractShocksStatement(bool overwrite_arg, ShockType type_arg,
|
||||
det_shocks_t det_shocks_arg,
|
||||
AbstractShocksStatement(bool overwrite_arg, ShockType type_arg, det_shocks_t det_shocks_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
};
|
||||
|
||||
|
@ -61,21 +63,21 @@ class ShocksStatement : public AbstractShocksStatement
|
|||
public:
|
||||
using var_and_std_shocks_t = map<int, expr_t>;
|
||||
using covar_and_corr_shocks_t = map<pair<int, int>, 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<int, expr_t>& it, bool stddev) const;
|
||||
void writeVarAndStdShocks(ostream& output) const;
|
||||
void writeCovarOrCorrShock(ostream &output, const pair<pair<int, int>, expr_t> &it, bool corr) const;
|
||||
void writeCovarOrCorrShock(ostream& output, const pair<pair<int, int>, 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,
|
||||
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;
|
||||
|
@ -86,8 +88,7 @@ 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,
|
||||
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;
|
||||
|
@ -102,8 +103,10 @@ 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;
|
||||
|
||||
public:
|
||||
ShocksSurpriseStatement(bool overwrite_arg,
|
||||
AbstractShocksStatement::det_shocks_t surprise_shocks_arg,
|
||||
|
@ -125,21 +128,28 @@ public:
|
|||
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)”)
|
||||
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<int, vector<tuple<LearntShockType, int, int, expr_t>>>;
|
||||
const learnt_shocks_t learnt_shocks;
|
||||
|
||||
private:
|
||||
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);
|
||||
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;
|
||||
|
@ -151,6 +161,7 @@ private:
|
|||
const AbstractShocksStatement::det_shocks_t paths;
|
||||
const SymbolTable& symbol_table;
|
||||
const int path_length;
|
||||
|
||||
public:
|
||||
ConditionalForecastPathsStatement(AbstractShocksStatement::det_shocks_t paths_arg,
|
||||
const SymbolTable& symbol_table_arg);
|
||||
|
@ -169,12 +180,13 @@ public:
|
|||
expr_t lower_bound, upper_bound;
|
||||
};
|
||||
using constraints_t = vector<Constraint>;
|
||||
|
||||
private:
|
||||
constraints_t constraints;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
MomentCalibration(constraints_t constraints_arg,
|
||||
const SymbolTable &symbol_table_arg);
|
||||
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;
|
||||
};
|
||||
|
@ -190,13 +202,14 @@ public:
|
|||
expr_t lower_bound, upper_bound;
|
||||
};
|
||||
using constraints_t = vector<Constraint>;
|
||||
|
||||
private:
|
||||
constraints_t constraints;
|
||||
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;
|
||||
|
@ -211,9 +224,11 @@ public:
|
|||
vector<string> list;
|
||||
};
|
||||
using group_t = vector<Group>;
|
||||
|
||||
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;
|
||||
|
@ -226,8 +241,10 @@ private:
|
|||
const vector<pair<int, int>> init2shocks;
|
||||
const string name;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
Init2shocksStatement(vector<pair<int, int>> init2shocks_arg, string name_arg, const SymbolTable &symbol_table_arg);
|
||||
Init2shocksStatement(vector<pair<int, int>> 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;
|
||||
|
@ -238,10 +255,12 @@ class HeteroskedasticShocksStatement : public Statement
|
|||
public:
|
||||
// Maps exo symb_id to list of tuples (period1, period2, value/scale)
|
||||
using heteroskedastic_shocks_t = map<int, vector<tuple<int, int, expr_t>>>;
|
||||
|
||||
private:
|
||||
const bool overwrite;
|
||||
const heteroskedastic_shocks_t values, scales;
|
||||
const SymbolTable& symbol_table;
|
||||
|
||||
public:
|
||||
HeteroskedasticShocksStatement(bool overwrite_arg, heteroskedastic_shocks_t values_arg,
|
||||
heteroskedastic_shocks_t scales_arg,
|
||||
|
|
|
@ -168,10 +168,10 @@ void
|
|||
OptionsList::writeOutput(ostream& output, const string& option_group) const
|
||||
{
|
||||
// Initialize option_group as an empty struct iff the field does not exist!
|
||||
if (size_t idx = option_group.find_last_of(".");
|
||||
idx != string::npos)
|
||||
if (size_t idx = option_group.find_last_of("."); idx != string::npos)
|
||||
{
|
||||
output << "if ~isfield(" << option_group.substr(0, idx) << ",'" << option_group.substr(idx+1) << "')" << endl;
|
||||
output << "if ~isfield(" << option_group.substr(0, idx) << ",'"
|
||||
<< option_group.substr(idx + 1) << "')" << endl;
|
||||
output << " " << option_group << " = struct();" << endl;
|
||||
output << "end" << endl;
|
||||
}
|
||||
|
@ -185,8 +185,8 @@ void
|
|||
OptionsList::writeOutputCommon(ostream& output, const string& option_group) const
|
||||
{
|
||||
for (const auto& [name, val] : options)
|
||||
std::visit([&]<class T>(const T &v)
|
||||
{
|
||||
std::visit(
|
||||
[&]<class T>(const T& v) {
|
||||
if constexpr (is_same_v<T, SymbolListVal>)
|
||||
v.writeOutput(option_group + "." + name, output);
|
||||
else
|
||||
|
@ -259,7 +259,8 @@ OptionsList::writeOutputCommon(ostream &output, const string &option_group) cons
|
|||
static_assert(always_false_v<T>, "Non-exhaustive visitor!");
|
||||
output << ";" << endl;
|
||||
}
|
||||
}, val);
|
||||
},
|
||||
val);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -270,14 +271,13 @@ OptionsList::writeJsonOutput(ostream &output) const
|
|||
|
||||
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([&]<class T>(const T &v)
|
||||
{
|
||||
std::visit(
|
||||
[&]<class T>(const T& v) {
|
||||
if constexpr (is_same_v<T, NumVal>)
|
||||
output << v;
|
||||
else if constexpr (is_same_v<T, pair<string, string>>)
|
||||
|
@ -295,8 +295,7 @@ OptionsList::writeJsonOutput(ostream &output) const
|
|||
|| is_same_v<T, vector<vector<string>>>)
|
||||
{
|
||||
output << '[';
|
||||
for (bool printed_something{false};
|
||||
const auto &it : v)
|
||||
for (bool printed_something {false}; const auto& it : v)
|
||||
{
|
||||
if (exchange(printed_something, true))
|
||||
output << ", ";
|
||||
|
@ -307,8 +306,7 @@ OptionsList::writeJsonOutput(ostream &output) const
|
|||
else // vector<vector<string>>
|
||||
{
|
||||
output << '[';
|
||||
for (bool printed_something2{false};
|
||||
const auto &it2 : it)
|
||||
for (bool printed_something2 {false}; const auto& it2 : it)
|
||||
{
|
||||
if (exchange(printed_something2, true))
|
||||
output << ", ";
|
||||
|
@ -321,7 +319,8 @@ OptionsList::writeJsonOutput(ostream &output) const
|
|||
}
|
||||
else
|
||||
static_assert(always_false_v<T>, "Non-exhaustive visitor!");
|
||||
}, val);
|
||||
},
|
||||
val);
|
||||
}
|
||||
|
||||
output << "}";
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
#ifndef _STATEMENT_HH
|
||||
#define _STATEMENT_HH
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
#include "SymbolList.hh"
|
||||
|
@ -60,13 +60,15 @@ struct ModFileStructure
|
|||
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 */
|
||||
/*! 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};
|
||||
//! 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
|
||||
//! 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};
|
||||
|
@ -190,9 +192,11 @@ public:
|
|||
//! 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 writeOutput(ostream& output, const string& basename, bool minimal_workspace) const
|
||||
= 0;
|
||||
virtual void writeJsonOutput(ostream& output) const = 0;
|
||||
};
|
||||
|
||||
|
@ -200,6 +204,7 @@ 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;
|
||||
|
@ -210,6 +215,7 @@ 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;
|
||||
|
@ -321,10 +327,12 @@ private:
|
|||
// pair<string, string> corresponds to a pair of numerical values
|
||||
// vector<vector<string>> corresponds to a vector of vectors of numerical values
|
||||
map<string, variant<NumVal, pair<string, string>, StringVal, DateVal, SymbolListVal, vector<int>,
|
||||
VecStrVal, VecCellStrVal, VecValueVal, vector<vector<string>>>> options;
|
||||
VecStrVal, VecCellStrVal, VecValueVal, vector<vector<string>>>>
|
||||
options;
|
||||
void writeOutputCommon(ostream& output, const string& option_group) const;
|
||||
// Helper constant for visitors
|
||||
template<class> static constexpr bool always_false_v {false};
|
||||
template<class>
|
||||
static constexpr bool always_false_v {false};
|
||||
};
|
||||
|
||||
#endif // ! _STATEMENT_HH
|
||||
|
|
|
@ -17,20 +17,19 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "StaticModel.hh"
|
||||
#include "DynamicModel.hh"
|
||||
#include "StaticModel.hh"
|
||||
|
||||
StaticModel::StaticModel(SymbolTable &symbol_table_arg,
|
||||
NumericalConstants &num_constants_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}
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -198,7 +197,9 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const
|
|||
}
|
||||
|
||||
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();
|
||||
|
||||
|
@ -211,7 +212,8 @@ StaticModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_co
|
|||
with DynamicModel::computingPass(). */
|
||||
if (log2(symbol_table.endo_nbr()) * derivsOrder >= numeric_limits<int>::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,7 +245,9 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -255,23 +260,22 @@ StaticModel::writeStaticMFile(const string &basename) const
|
|||
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<int>(temporary_terms_derivatives[0].size() + temporary_terms_derivatives[1].size()) };
|
||||
int ntt {static_cast<int>(temporary_terms_derivatives[0].size()
|
||||
+ temporary_terms_derivatives[1].size())};
|
||||
for (size_t i {2}; i < derivatives.size(); i++)
|
||||
{
|
||||
ncols *= symbol_table.endo_nbr();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,12 +359,11 @@ 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};
|
||||
|
@ -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,26 +419,34 @@ 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
|
||||
<< "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();
|
||||
}
|
||||
|
||||
|
@ -443,18 +460,23 @@ StaticModel::writeStaticMCompatFile(const string &basename) const
|
|||
cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
int ntt { static_cast<int>(temporary_terms_derivatives[0].size() + temporary_terms_derivatives[1].size() + temporary_terms_derivatives[2].size() + temporary_terms_derivatives[3].size()) };
|
||||
int ntt {static_cast<int>(
|
||||
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,7 +484,8 @@ 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};
|
||||
model_dir /= "model";
|
||||
|
@ -549,14 +572,17 @@ StaticModel::writeBlockDriverOutput(ostream &output) const
|
|||
{
|
||||
for (int blk = 0; blk < static_cast<int>(blocks.size()); blk++)
|
||||
{
|
||||
output << "M_.block_structure_stat.block(" << blk+1 << ").Simulation_Type = " << static_cast<int>(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
|
||||
output << "M_.block_structure_stat.block(" << blk + 1
|
||||
<< ").Simulation_Type = " << static_cast<int>(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 << "];" << endl << "M_.block_structure_stat.block(" << blk + 1 << ").variable = [";
|
||||
for (int var = 0; var < blocks[blk].size; var++)
|
||||
output << " " << getBlockVariableID(blk, var) + 1;
|
||||
output << "];" << endl;
|
||||
|
@ -564,16 +590,14 @@ StaticModel::writeBlockDriverOutput(ostream &output) const
|
|||
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 << "];" << endl << "M_.block_structure_stat.equation_reordered = [";
|
||||
for (int i = 0; i < symbol_table.endo_nbr(); i++)
|
||||
output << " " << eq_idx_block2orig[i] + 1;
|
||||
output << "];" << endl;
|
||||
|
||||
set<pair<int, int>> row_incidence;
|
||||
for (const auto& [indices, d1] : derivatives[1])
|
||||
if (int deriv_id = indices[1];
|
||||
getTypeByDerivID(deriv_id) == SymbolType::endogenous)
|
||||
if (int deriv_id = indices[1]; getTypeByDerivID(deriv_id) == SymbolType::endogenous)
|
||||
{
|
||||
int eq = indices[0];
|
||||
int var {getTypeSpecificIDByDerivID(deriv_id)};
|
||||
|
@ -583,8 +607,8 @@ StaticModel::writeBlockDriverOutput(ostream &output) const
|
|||
for (auto [eq, var] : row_incidence)
|
||||
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<false>(output);
|
||||
}
|
||||
|
@ -665,7 +689,8 @@ StaticModel::computeChainRuleJacobian()
|
|||
map<int, BinaryOpNode*> 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,7 +709,9 @@ 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;
|
||||
}
|
||||
|
@ -698,9 +725,11 @@ StaticModel::computeChainRuleJacobian()
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -708,7 +737,8 @@ StaticModel::computeChainRuleJacobian()
|
|||
void
|
||||
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
|
||||
|
@ -734,7 +764,8 @@ StaticModel::writeLatexAuxVarRecursiveDefinitions(ostream &output) const
|
|||
for (auto aux_equation : aux_equations)
|
||||
{
|
||||
output << R"(\begin{dmath})" << endl;
|
||||
dynamic_cast<ExprNode *>(aux_equation)->writeOutput(output, ExprNodeOutputType::latexStaticModel);
|
||||
dynamic_cast<ExprNode*>(aux_equation)
|
||||
->writeOutput(output, ExprNodeOutputType::latexStaticModel);
|
||||
output << endl << R"(\end{dmath})" << endl;
|
||||
}
|
||||
}
|
||||
|
@ -750,8 +781,7 @@ StaticModel::writeJsonAuxVarRecursiveDefinitions(ostream &output) const
|
|||
{
|
||||
vector<string> 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 << ", ";
|
||||
|
@ -773,8 +803,7 @@ void
|
|||
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 << ", ";
|
||||
|
@ -805,22 +834,17 @@ StaticModel::writeJsonParamsDerivatives(ostream &output, bool writeDetails) cons
|
|||
if (!params_derivatives.size())
|
||||
return;
|
||||
|
||||
auto [mlv_output, tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output, g3p_output]
|
||||
{ writeJsonParamsDerivativesHelper<false>(writeDetails) };
|
||||
auto [mlv_output, tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output,
|
||||
g3p_output] {writeJsonParamsDerivativesHelper<false>(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
|
||||
|
@ -866,17 +890,16 @@ StaticModel::computeRamseyMultipliersDerivatives(int ramsey_orig_endo_nbr, bool
|
|||
not optional) */
|
||||
if (no_tmp_terms)
|
||||
for (auto& it : temp_terms_map)
|
||||
erase_if(it.second,
|
||||
[](expr_t e) { return !dynamic_cast<AbstractExternalFunctionNode *>(e); });
|
||||
erase_if(it.second, [](expr_t e) { return !dynamic_cast<AbstractExternalFunctionNode*>(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
|
||||
|
@ -885,19 +908,18 @@ StaticModel::writeDriverRamseyMultipliersDerivativesSparseIndices(ostream &outpu
|
|||
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([";
|
||||
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([";
|
||||
output << "]);" << endl << "M_.ramsey_multipliers_static_g1_sparse_colptr = int32([";
|
||||
for (int it : ramsey_multipliers_derivatives_sparse_colptr)
|
||||
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};
|
||||
filesystem::path filename {packageDir(basename) / "ramsey_multipliers_static_g1.m"};
|
||||
|
@ -908,7 +930,9 @@ StaticModel::writeRamseyMultipliersDerivativesMFile(const string &basename, int
|
|||
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_type>(output_file);
|
||||
|
@ -918,13 +942,16 @@ 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"};
|
||||
|
@ -941,13 +968,16 @@ StaticModel::writeRamseyMultipliersDerivativesCFile(const string &basename, cons
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
output << "#include <math.h>" << endl << endl
|
||||
output << "#include <math.h>" << 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_type>(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,13 +1021,15 @@ 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
|
||||
<< " *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;
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
#ifndef _STATIC_MODEL_HH
|
||||
#define _STATIC_MODEL_HH
|
||||
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
#include "ModelTree.hh"
|
||||
#include "Bytecode.hh"
|
||||
#include "ModelTree.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -72,7 +72,8 @@ private:
|
|||
//! 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);
|
||||
|
||||
|
@ -96,10 +97,8 @@ 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,
|
||||
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
|
||||
|
@ -111,7 +110,8 @@ private:
|
|||
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();
|
||||
|
@ -137,8 +137,7 @@ protected:
|
|||
}
|
||||
|
||||
public:
|
||||
StaticModel(SymbolTable &symbol_table_arg,
|
||||
NumericalConstants &num_constants,
|
||||
StaticModel(SymbolTable& symbol_table_arg, NumericalConstants& num_constants,
|
||||
ExternalFunctionsTable& external_functions_table_arg);
|
||||
|
||||
StaticModel(const StaticModel& m);
|
||||
|
@ -155,12 +154,15 @@ public:
|
|||
\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;
|
||||
|
@ -192,16 +194,20 @@ public:
|
|||
void addAllParamDerivId(set<int>& 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;
|
||||
|
||||
// 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
|
||||
|
@ -217,10 +223,11 @@ 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<output_type>() };
|
||||
auto [tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output,
|
||||
g3p_output] {writeParamsDerivativesFileHelper<output_type>()};
|
||||
// g3p_output is ignored
|
||||
|
||||
if constexpr (!julia)
|
||||
|
@ -232,56 +239,96 @@ 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
|
||||
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
|
||||
<< "% 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
|
||||
<< "% 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
|
||||
<< "% 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
|
||||
<< "% from model file (.mod)" << endl
|
||||
<< endl
|
||||
<< "T = NaN(" << params_derivs_temporary_terms_idxs.size() << ",1);" << 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()
|
||||
<< "if nargout >= 3" << 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
|
||||
<< 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
|
||||
<< hp_output.str() << "end" << endl
|
||||
<< "end" << endl;
|
||||
paramsDerivsFile.close();
|
||||
}
|
||||
|
@ -293,24 +340,22 @@ 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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,18 +366,16 @@ 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<output_type>(ramsey_multipliers_derivatives_temporary_terms,
|
||||
unused_tt_copy,
|
||||
ramsey_multipliers_derivatives_temporary_terms_idxs,
|
||||
output, tef_terms);
|
||||
writeTemporaryTerms<output_type>(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;
|
||||
|
|
522
src/SubModel.cc
522
src/SubModel.cc
File diff suppressed because it is too large
Load Diff
|
@ -20,16 +20,16 @@
|
|||
#ifndef _SUBMODEL_HH
|
||||
#define _SUBMODEL_HH
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#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;
|
||||
|
@ -46,7 +46,8 @@ private:
|
|||
SymbolTable& symbol_table;
|
||||
set<string> names;
|
||||
map<string, vector<string>> eqtags, target_eqtags;
|
||||
map<string, vector<int>> eqnums, target_eqnums, nontarget_eqnums, max_lags, lhs, target_lhs, nontarget_lhs;
|
||||
map<string, vector<int>> eqnums, target_eqnums, nontarget_eqnums, max_lags, lhs, target_lhs,
|
||||
nontarget_lhs;
|
||||
map<string, vector<optional<int>>> orig_diff_var;
|
||||
map<string, vector<set<pair<int, int>>>> rhs;
|
||||
map<string, vector<bool>> diff;
|
||||
|
@ -84,8 +85,7 @@ public:
|
|||
const vector<int>& getTargetLhs(const string& name_arg) const;
|
||||
|
||||
void setVals(map<string, vector<int>> eqnums_arg, map<string, vector<int>> target_eqnums_arg,
|
||||
map<string, vector<int>> lhs_arg,
|
||||
map<string, vector<expr_t>> lhs_expr_t_arg);
|
||||
map<string, vector<int>> lhs_arg, map<string, vector<expr_t>> lhs_expr_t_arg);
|
||||
void setRhs(map<string, vector<set<pair<int, int>>>> rhs_arg);
|
||||
void setMaxLags(map<string, vector<int>> max_lags_arg);
|
||||
void setDiff(map<string, vector<bool>> diff_arg);
|
||||
|
@ -127,10 +127,12 @@ private:
|
|||
map<string, vector<string>> eqtags;
|
||||
map<string, vector<int>> eqnums, max_lags, lhs, lhs_orig_symb_ids;
|
||||
map<string, vector<optional<int>>> orig_diff_var;
|
||||
map<string, vector<set<pair<int, int>>>> rhs; // name -> for each equation: set of pairs (var, lag)
|
||||
map<string, vector<set<pair<int, int>>>>
|
||||
rhs; // name -> for each equation: set of pairs (var, lag)
|
||||
map<string, vector<bool>> diff;
|
||||
map<string, vector<expr_t>> lhs_expr_t;
|
||||
map<string, map<tuple<int, int, int>, expr_t>> AR; // name -> (eqn, lag, lhs_symb_id) -> param_expr_t
|
||||
map<string, map<tuple<int, int, int>, 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
|
||||
|
@ -206,17 +208,22 @@ private:
|
|||
map<string, vector<int>> aux_param_symb_ids;
|
||||
// Decomposition of the expression
|
||||
map<string, vector<tuple<int, optional<int>, double>>> vars_params_constants;
|
||||
|
||||
public:
|
||||
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 empty() const;
|
||||
void substituteUnaryOpsInExpression(const lag_equivalence_table_t &nodes, ExprNode::subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs);
|
||||
void substituteUnaryOpsInExpression(const lag_equivalence_table_t& nodes,
|
||||
ExprNode::subst_table_t& subst_table,
|
||||
vector<BinaryOpNode*>& neweqs);
|
||||
// Called by DynamicModel::substituteDiff()
|
||||
void substituteDiffNodesInExpression(const lag_equivalence_table_t &diff_nodes, ExprNode::subst_table_t &diff_subst_table, vector<BinaryOpNode *> &neweqs);
|
||||
void transformPass(ExprNode::subst_table_t &diff_subst_table,
|
||||
DynamicModel &dynamic_model, const VarModelTable &var_model_table,
|
||||
void substituteDiffNodesInExpression(const lag_equivalence_table_t& diff_nodes,
|
||||
ExprNode::subst_table_t& diff_subst_table,
|
||||
vector<BinaryOpNode*>& 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;
|
||||
|
@ -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<string,
|
||||
tuple<pair<int, int>, optional<int>, vector<tuple<optional<int>, optional<int>, int>>, pair<int, vector<tuple<int, bool, int>>>, vector<tuple<int, int, optional<int>, double>>, vector<tuple<int, int, optional<int>, double>>, vector<tuple<int, int, optional<int>, double>>>>;
|
||||
using equation_info_t
|
||||
= map<string,
|
||||
tuple<pair<int, int>, optional<int>, vector<tuple<optional<int>, optional<int>, int>>,
|
||||
pair<int, vector<tuple<int, bool, int>>>,
|
||||
vector<tuple<int, int, optional<int>, double>>,
|
||||
vector<tuple<int, int, optional<int>, double>>,
|
||||
vector<tuple<int, int, optional<int>, double>>>>;
|
||||
|
||||
private:
|
||||
equation_info_t equation_info;
|
||||
|
||||
|
@ -291,7 +306,8 @@ 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, expr_t, string, PacTargetKind, expr_t, int, vector<int>, expr_t, growth_info_t>;
|
||||
using target_component_t = tuple<expr_t, expr_t, string, PacTargetKind, expr_t, int, vector<int>,
|
||||
expr_t, growth_info_t>;
|
||||
|
||||
private:
|
||||
// pac_model_name → (target variable/expr, auxname_target_nonstationary, target components)
|
||||
|
@ -304,21 +320,26 @@ private:
|
|||
|
||||
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);
|
||||
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);
|
||||
// Called by DynamicModel::substituteUnaryOps()
|
||||
void substituteUnaryOpsInGrowth(const lag_equivalence_table_t &nodes, ExprNode::subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs);
|
||||
void substituteUnaryOpsInGrowth(const lag_equivalence_table_t& nodes,
|
||||
ExprNode::subst_table_t& subst_table,
|
||||
vector<BinaryOpNode*>& 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<BinaryOpNode *> &neweqs);
|
||||
void substituteDiffNodesInGrowth(const lag_equivalence_table_t& diff_nodes,
|
||||
ExprNode::subst_table_t& diff_subst_table,
|
||||
vector<BinaryOpNode*>& 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,
|
||||
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;
|
||||
|
@ -330,5 +351,4 @@ public:
|
|||
void writeTargetCoefficientsFile(const string& basename) const;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,8 +21,7 @@
|
|||
|
||||
#include "SymbolList.hh"
|
||||
|
||||
SymbolList::SymbolList(vector<string> symbols_arg) :
|
||||
symbols{move(symbols_arg)}
|
||||
SymbolList::SymbolList(vector<string> symbols_arg) : symbols {move(symbols_arg)}
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -48,7 +47,8 @@ SymbolList::checkPass(WarningConsolidation &warnings, const vector<SymbolType> &
|
|||
{
|
||||
if (regex_search(symbol, m, re))
|
||||
{
|
||||
warnings << "WARNING: symbol_list variable " << symbol << " has not yet been declared. "
|
||||
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;
|
||||
|
@ -114,8 +114,7 @@ void
|
|||
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 << ";";
|
||||
|
@ -128,8 +127,7 @@ void
|
|||
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 << ",";
|
||||
|
@ -153,6 +151,7 @@ SymbolList::removeDuplicates(const string &dynare_command, WarningConsolidation
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -20,13 +20,13 @@
|
|||
#ifndef _SYMBOL_LIST_HH
|
||||
#define _SYMBOL_LIST_HH
|
||||
|
||||
#include <algorithm>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "WarningConsolidation.hh"
|
||||
#include "SymbolTable.hh"
|
||||
#include "WarningConsolidation.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -36,6 +36,7 @@ class SymbolList
|
|||
{
|
||||
private:
|
||||
vector<string> symbols;
|
||||
|
||||
public:
|
||||
SymbolList() = default;
|
||||
// This constructor is deliberately not marked explicit, to allow implicit conversion
|
||||
|
@ -48,7 +49,8 @@ public:
|
|||
//! Remove duplicate symbols
|
||||
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<SymbolType> &types, const SymbolTable &symbol_table) const noexcept(false);
|
||||
void checkPass(WarningConsolidation& warnings, const vector<SymbolType>& 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;
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
@ -30,7 +30,8 @@
|
|||
#include "SymbolTable.hh"
|
||||
|
||||
int
|
||||
SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_name, const vector<pair<string, string>> &partition_value) noexcept(false)
|
||||
SymbolTable::addSymbol(const string& name, SymbolType type, const string& tex_name,
|
||||
const vector<pair<string, string>>& partition_value) noexcept(false)
|
||||
{
|
||||
if (frozen)
|
||||
throw FrozenException();
|
||||
|
@ -201,8 +202,10 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false)
|
|||
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;
|
||||
<< "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")
|
||||
{
|
||||
|
@ -210,8 +213,7 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false)
|
|||
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,9 +237,12 @@ 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))
|
||||
if (partition.first != "long_name")
|
||||
|
@ -262,8 +267,10 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false)
|
|||
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;
|
||||
<< "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))
|
||||
if (partition.first != "long_name")
|
||||
|
@ -272,8 +279,7 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false)
|
|||
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,9 +294,12 @@ 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;
|
||||
}
|
||||
|
@ -302,8 +311,7 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false)
|
|||
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<int>(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,24 +355,32 @@ 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 = '";
|
||||
orig_expr->writeJsonOutput(output, {}, {});
|
||||
|
@ -381,8 +399,7 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false)
|
|||
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 = [ ";
|
||||
|
@ -394,8 +411,7 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false)
|
|||
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 = [ ";
|
||||
|
@ -416,19 +432,23 @@ SymbolTable::addLeadAuxiliaryVarInternal(bool endo, int index, expr_t expr_arg)
|
|||
}
|
||||
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
|
||||
{
|
||||
|
@ -436,11 +456,13 @@ SymbolTable::addLagAuxiliaryVarInternal(bool endo, int orig_symb_id, int orig_le
|
|||
}
|
||||
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,13 +487,15 @@ 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)};
|
||||
|
@ -481,7 +506,8 @@ SymbolTable::addExpectationAuxiliaryVar(int information_set, int index, expr_t 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;
|
||||
|
@ -501,17 +528,21 @@ SymbolTable::addLogTransformAuxiliaryVar(int orig_symb_id, int orig_lead_lag, ex
|
|||
}
|
||||
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)};
|
||||
int symb_id;
|
||||
|
@ -521,7 +552,8 @@ SymbolTable::addDiffLagAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id
|
|||
}
|
||||
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,7 +563,8 @@ 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)};
|
||||
int symb_id;
|
||||
|
@ -541,7 +574,8 @@ SymbolTable::addDiffLeadAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_i
|
|||
}
|
||||
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,7 +585,8 @@ SymbolTable::addDiffLeadAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_i
|
|||
}
|
||||
|
||||
int
|
||||
SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg, optional<int> orig_symb_id, optional<int> orig_lag) noexcept(false)
|
||||
SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg, optional<int> orig_symb_id,
|
||||
optional<int> orig_lag) noexcept(false)
|
||||
{
|
||||
string varname {"AUX_DIFF_" + to_string(index)};
|
||||
int symb_id;
|
||||
|
@ -561,17 +596,21 @@ SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg, optional<int> orig_
|
|||
}
|
||||
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<int> orig_symb_id, optional<int> orig_lag) noexcept(false)
|
||||
SymbolTable::addUnaryOpAuxiliaryVar(int index, expr_t expr_arg, string unary_op,
|
||||
optional<int> orig_symb_id,
|
||||
optional<int> orig_lag) noexcept(false)
|
||||
{
|
||||
string varname {"AUX_UOP_" + to_string(index)};
|
||||
int symb_id;
|
||||
|
@ -581,11 +620,13 @@ SymbolTable::addUnaryOpAuxiliaryVar(int index, expr_t expr_arg, string unary_op,
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
@ -601,7 +642,8 @@ SymbolTable::addMultiplierAuxiliaryVar(int index) noexcept(false)
|
|||
}
|
||||
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,7 +652,8 @@ 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)};
|
||||
int symb_id;
|
||||
|
@ -620,11 +663,13 @@ SymbolTable::addDiffForwardAuxiliaryVar(int orig_symb_id, int orig_lead_lag, exp
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -638,7 +683,10 @@ SymbolTable::addPacExpectationAuxiliaryVar(const string &name, expr_t expr_arg)
|
|||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -656,7 +704,10 @@ SymbolTable::addPacTargetNonstationaryAuxiliaryVar(const string &name, expr_t ex
|
|||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -678,19 +729,17 @@ 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
|
||||
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<int> 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};
|
||||
}
|
||||
|
@ -847,17 +896,18 @@ 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<int>
|
||||
|
@ -953,7 +1003,8 @@ SymbolTable::writeJsonOutput(ostream &output) const
|
|||
case AuxVarType::diffLag:
|
||||
case AuxVarType::diffLead:
|
||||
case AuxVarType::diffForward:
|
||||
output << R"(, "orig_index": )" << getTypeSpecificID(aux_vars[i].orig_symb_id.value())+1
|
||||
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:
|
||||
|
@ -969,8 +1020,7 @@ SymbolTable::writeJsonOutput(ostream &output) const
|
|||
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 << R"(, "orig_expr": ")";
|
||||
orig_expr->writeJsonOutput(output, {}, {});
|
||||
|
@ -992,9 +1042,10 @@ SymbolTable::writeJsonVarVector(ostream &output, const vector<int> &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;
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
#define _SYMBOLTABLE_HH
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <ostream>
|
||||
#include <optional>
|
||||
|
||||
#include "CommonEnums.hh"
|
||||
#include "ExprNode.hh"
|
||||
|
@ -50,10 +50,12 @@ enum class AuxVarType
|
|||
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))
|
||||
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
|
||||
pacTargetNonstationary
|
||||
= 13 //!< Variable created for the substitution of the pac_target_nonstationary operator
|
||||
};
|
||||
|
||||
//! Information on some auxiliary variables
|
||||
|
@ -65,8 +67,8 @@ struct AuxVarInfo
|
|||
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
|
||||
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<int> 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
|
||||
|
@ -196,8 +198,8 @@ 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}
|
||||
|
@ -207,17 +209,20 @@ public:
|
|||
|
||||
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<int>& 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<pair<string, string>> &partition_value) noexcept(false);
|
||||
int addSymbol(const string& name, SymbolType type, const string& tex_name,
|
||||
const vector<pair<string, string>>& 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);
|
||||
|
@ -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,13 +302,18 @@ public:
|
|||
diffLead increases it). */
|
||||
pair<int, int> unrollDiffLeadLagChain(int symb_id, int lag) const noexcept(false);
|
||||
//! Adds an auxiliary variable when the diff operator is encountered
|
||||
int addDiffAuxiliaryVar(int index, expr_t expr_arg, optional<int> orig_symb_id = nullopt, optional<int> orig_lag = nullopt) noexcept(false);
|
||||
int addDiffAuxiliaryVar(int index, expr_t expr_arg, optional<int> orig_symb_id = nullopt,
|
||||
optional<int> orig_lag = nullopt) noexcept(false);
|
||||
//! Takes care of timing between diff statements
|
||||
int addDiffLagAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id, int orig_lag) noexcept(false);
|
||||
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<int> orig_symb_id = nullopt, optional<int> orig_lag = nullopt) noexcept(false);
|
||||
int addUnaryOpAuxiliaryVar(int index, expr_t expr_arg, string unary_op,
|
||||
optional<int> orig_symb_id = nullopt,
|
||||
optional<int> orig_lag = nullopt) noexcept(false);
|
||||
//! An auxiliary variable for a pac_expectation operator
|
||||
int addPacExpectationAuxiliaryVar(const string& name, expr_t expr_arg);
|
||||
//! An auxiliary variable for a pac_target_nonstationary operator
|
||||
|
@ -321,7 +332,8 @@ public:
|
|||
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<string, map<int, string>> getPartitionsForType(SymbolType st) const noexcept(false);
|
||||
|
@ -382,7 +394,8 @@ 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<int> getTrendVarIds() const;
|
||||
//! Get list of exogenous variables
|
||||
|
@ -404,7 +417,8 @@ 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<int> getEquationNumberForMultiplier(int symb_id) const;
|
||||
/* Return all the information about a given auxiliary variable. Throws
|
||||
UnknownSymbolIDException if it is not an aux var */
|
||||
|
@ -465,8 +479,7 @@ SymbolTable::getType(const string &name) const noexcept(false)
|
|||
inline int
|
||||
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};
|
||||
|
@ -480,8 +493,7 @@ 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};
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#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<int> &circuit_stack) const
|
||||
VariableDependencyGraph::hasCycleDFS(vertex_descriptor u, color_t& color,
|
||||
vector<int>& circuit_stack) const
|
||||
{
|
||||
auto v_index = get(vertex_index, *this);
|
||||
color[u] = gray_color;
|
||||
|
@ -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;
|
||||
|
@ -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())
|
||||
|
@ -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<base>(*this), make_iterator_property_map(vertex2scc.begin(), v_index));
|
||||
int num_scc = strong_components(static_cast<base>(*this),
|
||||
make_iterator_property_map(vertex2scc.begin(), v_index));
|
||||
|
||||
// Create directed acyclic graph (DAG) associated to the SCCs
|
||||
adjacency_list<vecS, vecS, directedS> dag(num_scc);
|
||||
|
|
|
@ -30,20 +30,25 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
using VertexProperty_t = boost::property<boost::vertex_index_t, int,
|
||||
boost::property<boost::vertex_index1_t, int,
|
||||
using VertexProperty_t = boost::property<
|
||||
boost::vertex_index_t, int,
|
||||
boost::property<
|
||||
boost::vertex_index1_t, int,
|
||||
boost::property<boost::vertex_degree_t, int,
|
||||
boost::property<boost::vertex_in_degree_t, int,
|
||||
boost::property<boost::vertex_out_degree_t, int>>>>>;
|
||||
|
||||
/* Class used to store a graph representing dependencies between variables.
|
||||
Used in the block decomposition. */
|
||||
class VariableDependencyGraph
|
||||
: public boost::adjacency_list<boost::listS, boost::listS, boost::bidirectionalS, VertexProperty_t>
|
||||
class VariableDependencyGraph :
|
||||
public boost::adjacency_list<boost::listS, boost::listS, boost::bidirectionalS,
|
||||
VertexProperty_t>
|
||||
{
|
||||
public:
|
||||
using color_t = map<boost::graph_traits<VariableDependencyGraph>::vertex_descriptor, boost::default_color_type>;
|
||||
using base = boost::adjacency_list<boost::listS, boost::listS, boost::bidirectionalS, VertexProperty_t>;
|
||||
using color_t = map<boost::graph_traits<VariableDependencyGraph>::vertex_descriptor,
|
||||
boost::default_color_type>;
|
||||
using base
|
||||
= boost::adjacency_list<boost::listS, boost::listS, boost::bidirectionalS, VertexProperty_t>;
|
||||
|
||||
VariableDependencyGraph(int n);
|
||||
//! Extracts a subgraph
|
||||
|
@ -58,7 +63,8 @@ public:
|
|||
//! Return the feedback set
|
||||
set<int> minimalSetOfFeedbackVertices() const;
|
||||
//! Reorder the recursive variables
|
||||
/*! They appear first in a quasi triangular form and they are followed by the feedback variables */
|
||||
/*! They appear first in a quasi triangular form and they are followed by the feedback variables
|
||||
*/
|
||||
vector<int> reorderRecursiveVariables(const set<int>& feedback_vertices) const;
|
||||
/* Computes the strongly connected components (SCCs) of the graph, and sort them
|
||||
topologically.
|
||||
|
@ -67,6 +73,7 @@ public:
|
|||
pair<int, vector<int>> 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);
|
||||
|
|
|
@ -40,9 +40,7 @@ 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;
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
#ifndef _WARNINGCONSOLIDATION_HH
|
||||
#define _WARNINGCONSOLIDATION_HH
|
||||
|
||||
#include "DynareBisonLocation.hh"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "DynareBisonLocation.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -36,7 +36,7 @@ private:
|
|||
public:
|
||||
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);
|
||||
|
|
|
@ -68,8 +68,10 @@ Include::interpret(ostream &output, Environment &env, vector<filesystem::path> &
|
|||
errmsg << " * " << current_path().string() << endl;
|
||||
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;
|
||||
|
@ -92,7 +94,8 @@ Include::interpret(ostream &output, Environment &env, vector<filesystem::path> &
|
|||
}
|
||||
|
||||
void
|
||||
IncludePath::interpret([[maybe_unused]] ostream &output, Environment &env, vector<filesystem::path> &paths)
|
||||
IncludePath::interpret([[maybe_unused]] ostream& output, Environment& env,
|
||||
vector<filesystem::path>& paths)
|
||||
{
|
||||
using namespace filesystem;
|
||||
try
|
||||
|
@ -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<filesystem::path> &paths)
|
||||
Define::interpret([[maybe_unused]] ostream& output, Environment& env,
|
||||
[[maybe_unused]] vector<filesystem::path>& paths)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -176,7 +180,8 @@ Echo::interpret(ostream &output, Environment &env, [[maybe_unused]] vector<files
|
|||
}
|
||||
|
||||
void
|
||||
Error::interpret([[maybe_unused]] ostream &output, Environment &env, [[maybe_unused]] vector<filesystem::path> &paths)
|
||||
Error::interpret([[maybe_unused]] ostream& output, Environment& env,
|
||||
[[maybe_unused]] vector<filesystem::path>& paths)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -194,7 +199,8 @@ Error::interpret([[maybe_unused]] ostream &output, Environment &env, [[maybe_unu
|
|||
}
|
||||
|
||||
void
|
||||
EchoMacroVars::interpret(ostream &output, Environment &env, [[maybe_unused]] vector<filesystem::path> &paths)
|
||||
EchoMacroVars::interpret(ostream& output, Environment& env,
|
||||
[[maybe_unused]] vector<filesystem::path>& paths)
|
||||
{
|
||||
if (save)
|
||||
env.print(output, vars, location.begin.line, true);
|
||||
|
@ -237,8 +243,11 @@ For::interpret(ostream &output, Environment &env, vector<filesystem::path> &path
|
|||
{
|
||||
TuplePtr mtp = dynamic_pointer_cast<Tuple>(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));
|
||||
|
@ -262,8 +271,7 @@ For::interpret(ostream &output, Environment &env, vector<filesystem::path> &path
|
|||
void
|
||||
If::interpret(ostream& output, Environment& env, vector<filesystem::path>& 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<filesystem::path> &paths
|
|||
RealPtr dp = dynamic_pointer_cast<Real>(tmp);
|
||||
BoolPtr bp = dynamic_pointer_cast<Bool>(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);
|
||||
|
@ -307,10 +315,10 @@ If::interpret(ostream &output, Environment &env, vector<filesystem::path> &paths
|
|||
}
|
||||
|
||||
void
|
||||
If::interpretBody(const vector<DirectivePtr> &body, ostream &output, Environment &env, vector<filesystem::path> &paths)
|
||||
If::interpretBody(const vector<DirectivePtr>& body, ostream& output, Environment& env,
|
||||
vector<filesystem::path>& paths)
|
||||
{
|
||||
for (bool printLine{true};
|
||||
const auto &statement : body)
|
||||
for (bool printLine {true}; const auto& statement : body)
|
||||
{
|
||||
if (exchange(printLine, false))
|
||||
statement->printLineInfo(output);
|
||||
|
|
|
@ -30,13 +30,13 @@ namespace macro
|
|||
{
|
||||
// A Parent class just for clarity
|
||||
public:
|
||||
explicit Directive(Tokenizer::location location_arg) :
|
||||
Node(move(location_arg)) { }
|
||||
explicit Directive(Tokenizer::location location_arg) : Node(move(location_arg))
|
||||
{
|
||||
}
|
||||
// Directives can be interpreted
|
||||
virtual void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) = 0;
|
||||
};
|
||||
|
||||
|
||||
class TextNode : public Directive
|
||||
{
|
||||
// Class for text not interpreted by macroprocessor
|
||||
|
@ -44,17 +44,20 @@ namespace macro
|
|||
// 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)} { }
|
||||
Directive(move(location_arg)), text {move(text_arg)}
|
||||
{
|
||||
}
|
||||
void
|
||||
interpret(ostream &output, [[maybe_unused]] Environment &env, [[maybe_unused]] vector<filesystem::path> &paths) override
|
||||
interpret(ostream& output, [[maybe_unused]] Environment& env,
|
||||
[[maybe_unused]] vector<filesystem::path>& paths) override
|
||||
{
|
||||
output << text;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Eval : public Directive
|
||||
{
|
||||
// Class for @{} statements
|
||||
|
@ -62,111 +65,123 @@ namespace macro
|
|||
// 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)} { }
|
||||
Directive(move(location_arg)), expr {move(expr_arg)}
|
||||
{
|
||||
}
|
||||
void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
|
||||
};
|
||||
|
||||
|
||||
class Include : public Directive
|
||||
{
|
||||
private:
|
||||
const ExpressionPtr expr;
|
||||
|
||||
public:
|
||||
Include(ExpressionPtr expr_arg, Tokenizer::location location_arg) :
|
||||
Directive(move(location_arg)), expr{move(expr_arg)} { }
|
||||
Directive(move(location_arg)), expr {move(expr_arg)}
|
||||
{
|
||||
}
|
||||
void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
|
||||
};
|
||||
|
||||
|
||||
class IncludePath : public Directive
|
||||
{
|
||||
private:
|
||||
const ExpressionPtr expr;
|
||||
|
||||
public:
|
||||
IncludePath(ExpressionPtr expr_arg, Tokenizer::location location_arg) :
|
||||
Directive(move(location_arg)), expr{move(expr_arg)} { }
|
||||
Directive(move(location_arg)), expr {move(expr_arg)}
|
||||
{
|
||||
}
|
||||
void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
|
||||
};
|
||||
|
||||
|
||||
class Define : public Directive
|
||||
{
|
||||
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)} { }
|
||||
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<filesystem::path>& paths) override;
|
||||
};
|
||||
|
||||
|
||||
class Echo : public Directive
|
||||
{
|
||||
private:
|
||||
const ExpressionPtr expr;
|
||||
|
||||
public:
|
||||
Echo(ExpressionPtr expr_arg,
|
||||
Tokenizer::location location_arg) :
|
||||
Directive(move(location_arg)), expr{move(expr_arg)} { }
|
||||
Echo(ExpressionPtr expr_arg, Tokenizer::location location_arg) :
|
||||
Directive(move(location_arg)), expr {move(expr_arg)}
|
||||
{
|
||||
}
|
||||
void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
|
||||
};
|
||||
|
||||
|
||||
class Error : public Directive
|
||||
{
|
||||
private:
|
||||
const ExpressionPtr expr;
|
||||
|
||||
public:
|
||||
Error(ExpressionPtr expr_arg,
|
||||
Tokenizer::location location_arg) :
|
||||
Directive(move(location_arg)), expr{move(expr_arg)} { }
|
||||
Error(ExpressionPtr expr_arg, Tokenizer::location location_arg) :
|
||||
Directive(move(location_arg)), expr {move(expr_arg)}
|
||||
{
|
||||
}
|
||||
void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
|
||||
};
|
||||
|
||||
|
||||
class EchoMacroVars : public Directive
|
||||
{
|
||||
private:
|
||||
const bool save;
|
||||
const vector<string> vars;
|
||||
|
||||
public:
|
||||
EchoMacroVars(bool save_arg,
|
||||
Tokenizer::location location_arg) :
|
||||
Directive(move(location_arg)), save{save_arg} { }
|
||||
EchoMacroVars(bool save_arg, vector<string> vars_arg,
|
||||
Tokenizer::location location_arg) :
|
||||
Directive(move(location_arg)), save{save_arg}, vars{move(vars_arg)} { }
|
||||
EchoMacroVars(bool save_arg, Tokenizer::location location_arg) :
|
||||
Directive(move(location_arg)), save {save_arg}
|
||||
{
|
||||
}
|
||||
EchoMacroVars(bool save_arg, vector<string> vars_arg, Tokenizer::location location_arg) :
|
||||
Directive(move(location_arg)), save {save_arg}, vars {move(vars_arg)}
|
||||
{
|
||||
}
|
||||
void interpret(ostream& output, Environment& env, vector<filesystem::path>& paths) override;
|
||||
};
|
||||
|
||||
|
||||
class For : public Directive
|
||||
{
|
||||
private:
|
||||
const vector<VariablePtr> index_vec;
|
||||
const ExpressionPtr index_vals;
|
||||
const vector<DirectivePtr> statements;
|
||||
|
||||
public:
|
||||
For(vector<VariablePtr> index_vec_arg,
|
||||
ExpressionPtr index_vals_arg,
|
||||
vector<DirectivePtr> 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)} { }
|
||||
For(vector<VariablePtr> index_vec_arg, ExpressionPtr index_vals_arg,
|
||||
vector<DirectivePtr> 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<filesystem::path>& paths) override;
|
||||
};
|
||||
|
||||
|
||||
class If : public Directive
|
||||
{
|
||||
protected:
|
||||
|
@ -180,16 +195,21 @@ namespace macro
|
|||
*/
|
||||
const vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body;
|
||||
const bool ifdef, ifndef;
|
||||
|
||||
public:
|
||||
If(vector<pair<ExpressionPtr, vector<DirectivePtr>>> 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} { }
|
||||
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<filesystem::path>& paths) override;
|
||||
|
||||
protected:
|
||||
void interpretBody(const vector<DirectivePtr> &body, ostream &output,
|
||||
Environment &env, vector<filesystem::path> &paths);
|
||||
void interpretBody(const vector<DirectivePtr>& body, ostream& output, Environment& env,
|
||||
vector<filesystem::path>& paths);
|
||||
};
|
||||
|
||||
class Ifdef : public If
|
||||
|
@ -197,16 +217,19 @@ namespace macro
|
|||
public:
|
||||
Ifdef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
|
||||
Tokenizer::location location_arg) :
|
||||
If(move(expr_and_body_arg), move(location_arg), true, false) { }
|
||||
If(move(expr_and_body_arg), move(location_arg), true, false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Ifndef : public If
|
||||
{
|
||||
public:
|
||||
Ifndef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
|
||||
Tokenizer::location location_arg) :
|
||||
If(move(expr_and_body_arg), move(location_arg), false, true) { }
|
||||
If(move(expr_and_body_arg), move(location_arg), false, true)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
using namespace macro;
|
||||
|
||||
void
|
||||
Driver::parse(const string &file_arg, const istream &modfile,
|
||||
bool debug, const vector<pair<string, string>> &defines,
|
||||
Environment &env, vector<filesystem::path> &paths, ostream &output)
|
||||
Driver::parse(const string& file_arg, const istream& modfile, bool debug,
|
||||
const vector<pair<string, string>>& defines, Environment& env,
|
||||
vector<filesystem::path>& paths, ostream& output)
|
||||
{
|
||||
file = file_arg;
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -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 <stack>
|
||||
|
||||
|
@ -46,7 +46,9 @@ namespace macro
|
|||
class TokenizerFlex : public TokenizerFlexLexer
|
||||
{
|
||||
public:
|
||||
TokenizerFlex(istream *in) : TokenizerFlexLexer{in} { }
|
||||
TokenizerFlex(istream* in) : TokenizerFlexLexer {in}
|
||||
{
|
||||
}
|
||||
TokenizerFlex(const TokenizerFlex&) = delete;
|
||||
TokenizerFlex& operator=(const TokenizerFlex&) = delete;
|
||||
|
||||
|
@ -63,6 +65,7 @@ namespace macro
|
|||
private:
|
||||
vector<DirectivePtr> statements;
|
||||
stack<vector<DirectivePtr>> directive_stack;
|
||||
|
||||
public:
|
||||
Driver() = default;
|
||||
Driver(const Driver&) = delete;
|
||||
|
@ -76,9 +79,9 @@ namespace macro
|
|||
|
||||
//! 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<pair<string, string>> &defines,
|
||||
Environment &env, vector<filesystem::path> &paths, ostream &output);
|
||||
void parse(const string& file, const istream& modfile, bool debug,
|
||||
const vector<pair<string, string>>& defines, Environment& env,
|
||||
vector<filesystem::path>& paths, ostream& output);
|
||||
|
||||
//! Name of main file being parsed (for error reporting purposes)
|
||||
string file;
|
||||
|
|
|
@ -101,7 +101,8 @@ Environment::isFunctionDefined(const string &name) const noexcept
|
|||
}
|
||||
|
||||
void
|
||||
Environment::print(ostream &output, const vector<string> &vars, const optional<int> &line, bool save) const
|
||||
Environment::print(ostream& output, const vector<string>& vars, const optional<int>& line,
|
||||
bool save) const
|
||||
{
|
||||
if (!save && !variables.empty())
|
||||
output << "Macro Variables:" << endl;
|
||||
|
@ -130,11 +131,11 @@ Environment::print(ostream &output, const vector<string> &vars, const optional<i
|
|||
}
|
||||
|
||||
void
|
||||
Environment::printVariable(ostream &output, const string &name, const optional<int> &line, bool save) const
|
||||
Environment::printVariable(ostream& output, const string& name, const optional<int>& line,
|
||||
bool save) const
|
||||
{
|
||||
assert(!save || line);
|
||||
output << (save ? "options_.macrovars_line_" + to_string(*line) + "." : " ")
|
||||
<< name << " = ";
|
||||
output << (save ? "options_.macrovars_line_" + to_string(*line) + "." : " ") << name << " = ";
|
||||
getVariable(name)->eval(const_cast<Environment&>(*this))->print(output, save);
|
||||
if (save)
|
||||
output << ";";
|
||||
|
@ -142,7 +143,8 @@ Environment::printVariable(ostream &output, const string &name, const optional<i
|
|||
}
|
||||
|
||||
void
|
||||
Environment::printFunction(ostream &output, const tuple<FunctionPtr, ExpressionPtr> &function, const optional<int> &line, bool save) const
|
||||
Environment::printFunction(ostream& output, const tuple<FunctionPtr, ExpressionPtr>& function,
|
||||
const optional<int>& line, bool save) const
|
||||
{
|
||||
assert(!save || line);
|
||||
output << (save ? "options_.macrovars_line_" + to_string(*line) + ".function." : " ");
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
#include "ForwardDeclarationsAndEnums.hh"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace macro
|
||||
{
|
||||
|
@ -34,9 +34,12 @@ namespace macro
|
|||
const Environment* parent {nullptr};
|
||||
map<string, ExpressionPtr> variables;
|
||||
map<string, tuple<FunctionPtr, ExpressionPtr>> functions;
|
||||
|
||||
public:
|
||||
Environment() = default;
|
||||
Environment(const Environment *parent_arg) : parent{parent_arg} { }
|
||||
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;
|
||||
|
@ -44,13 +47,17 @@ namespace macro
|
|||
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
|
||||
bool
|
||||
isSymbolDefined(const string& name) const noexcept
|
||||
{
|
||||
return isVariableDefined(name) || isFunctionDefined(name);
|
||||
}
|
||||
void print(ostream &output, const vector<string> &vars, const optional<int> &line = nullopt, bool save = false) const;
|
||||
void printVariable(ostream &output, const string &name, const optional<int> &line, bool save) const;
|
||||
void printFunction(ostream &output, const tuple<FunctionPtr, ExpressionPtr> &function, const optional<int> &line, bool save) const;
|
||||
void print(ostream& output, const vector<string>& vars, const optional<int>& line = nullopt,
|
||||
bool save = false) const;
|
||||
void printVariable(ostream& output, const string& name, const optional<int>& line,
|
||||
bool save) const;
|
||||
void printFunction(ostream& output, const tuple<FunctionPtr, ExpressionPtr>& function,
|
||||
const optional<int>& line, bool save) const;
|
||||
size_t
|
||||
size() const noexcept
|
||||
{
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <utility>
|
||||
#include <numbers>
|
||||
#include <utility>
|
||||
|
||||
#include "Expressions.hh"
|
||||
|
||||
|
@ -241,7 +241,9 @@ Real::normpdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const
|
|||
auto btp22 = dynamic_pointer_cast<Real>(btp2);
|
||||
if (!btp12 || !btp22)
|
||||
throw StackTrace("Type mismatch for operands of `normpdf` operator");
|
||||
return make_shared<Real>((1/(btp22->value*std::sqrt(2*numbers::pi)*std::exp(pow((value-btp12->value)/btp22->value, 2)/2))));
|
||||
return make_shared<Real>((1
|
||||
/ (btp22->value * std::sqrt(2 * numbers::pi)
|
||||
* std::exp(pow((value - btp12->value) / btp22->value, 2) / 2))));
|
||||
}
|
||||
|
||||
RealPtr
|
||||
|
@ -251,7 +253,8 @@ Real::normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const
|
|||
auto btp22 = dynamic_pointer_cast<Real>(btp2);
|
||||
if (!btp12 || !btp22)
|
||||
throw StackTrace("Type mismatch for operands of `normpdf` operator");
|
||||
return make_shared<Real>((0.5*(1+std::erf((value-btp12->value)/btp22->value/numbers::sqrt2))));
|
||||
return make_shared<Real>(
|
||||
(0.5 * (1 + std::erf((value - btp12->value) / btp22->value / numbers::sqrt2))));
|
||||
}
|
||||
|
||||
BaseTypePtr
|
||||
|
@ -657,12 +660,15 @@ Variable::eval(Environment &env) const
|
|||
vector<int> ind;
|
||||
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<Real>(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<Array>(it))
|
||||
|
@ -670,16 +676,22 @@ Variable::eval(Environment &env) const
|
|||
if (db = dynamic_pointer_cast<Real>(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,8 +705,7 @@ 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<String>(env.getVariable(name))->to_string();
|
||||
string orig_string = dynamic_pointer_cast<String>(env.getVariable(name))->to_string();
|
||||
string retvals;
|
||||
for (auto it : ind)
|
||||
try
|
||||
|
@ -749,8 +760,10 @@ Function::eval(Environment &env) const
|
|||
}
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -970,8 +983,10 @@ Comprehension::eval(Environment &env) const
|
|||
vp = dynamic_pointer_cast<Variable>(c_vars);
|
||||
mt = dynamic_pointer_cast<Tuple>(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)
|
||||
{
|
||||
|
@ -985,27 +1000,32 @@ Comprehension::eval(Environment &env) const
|
|||
auto btp = dynamic_pointer_cast<BaseType>(input_set->at(i));
|
||||
if (vp)
|
||||
env.define(vp, btp);
|
||||
else
|
||||
if (btp->getType() == codes::BaseType::Tuple)
|
||||
else if (btp->getType() == codes::BaseType::Tuple)
|
||||
{
|
||||
auto mt2 = dynamic_pointer_cast<Tuple>(btp);
|
||||
if (mt->size() != mt2->size())
|
||||
throw StackTrace("Comprehension", "The number of elements in the input "
|
||||
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);
|
||||
"the output expression tuple",
|
||||
location);
|
||||
|
||||
for (size_t j = 0; j < mt->size(); j++)
|
||||
{
|
||||
auto vp2 = dynamic_pointer_cast<Variable>(mt->at(j));
|
||||
if (!vp2)
|
||||
throw StackTrace("Comprehension", "Output expression tuple must be "
|
||||
"comprised of variable names", location);
|
||||
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);
|
||||
throw StackTrace("Comprehension",
|
||||
"assigning to tuple in output expression "
|
||||
"but input expression does not contain tuples",
|
||||
location);
|
||||
|
||||
if (!c_when)
|
||||
if (!c_expr)
|
||||
|
@ -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);
|
||||
|
@ -1250,17 +1272,14 @@ Comprehension::to_string() const noexcept
|
|||
void
|
||||
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
|
||||
{
|
||||
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 << ", ";
|
||||
|
@ -1273,8 +1292,7 @@ void
|
|||
Tuple::print(ostream& output, bool matlab_output) const noexcept
|
||||
{
|
||||
output << (matlab_output ? "{" : "(");
|
||||
for (bool printed_something{false};
|
||||
auto e : tup)
|
||||
for (bool printed_something {false}; auto e : tup)
|
||||
{
|
||||
if (exchange(printed_something, true))
|
||||
output << ", ";
|
||||
|
@ -1287,8 +1305,7 @@ void
|
|||
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 << ", ";
|
||||
|
@ -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
|
||||
{
|
||||
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)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue