Skip to content
Snippets Groups Projects

Compare revisions

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

Source

Select target project
No results found
Select Git revision
  • 4.6
  • 5.x
  • 6.x
  • aux_vars_fix
  • julia
  • llvm-15
  • master
  • python-codegen
  • rework_pac
  • uop
  • julia-6.2.0
  • julia-6.3.0
  • julia-6.4.0
  • julia-7.0.0
14 results

Target

Select target project
  • normann/preprocessor
  • Dynare/preprocessor
  • FerhatMihoubi/preprocessor
  • MichelJuillard/preprocessor
  • sebastien/preprocessor
  • lnsongxf/preprocessor
  • albop/preprocessor
  • DoraK/preprocessor
  • amg/preprocessor
  • wmutschl/preprocessor
  • JohannesPfeifer/preprocessor
11 results
Select Git revision
  • master
  • created_preprocessor_repo
2 results
Show changes
Showing
with 13706 additions and 13226 deletions
# Meson native file for compiling under Homebrew / x86-64
[binaries]
cpp = '/usr/local/bin/g++-15'
flex = '/usr/local/opt/flex/bin/flex'
bison = '/usr/local/opt/bison/bin/bison'
[built-in options]
# XCode 15 (on Ventura and Sonoma) has a linker issue, see https://github.com/mesonbuild/meson/issues/12282, workaround is to use ld_classic
cpp_link_args = [ '-Wl,-ld_classic' ]
\ No newline at end of file
# Meson cross file for targeting Linux arm64
[binaries]
cpp = 'aarch64-linux-gnu-g++'
strip = 'aarch64-linux-gnu-strip'
[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'
# Meson cross file for creating a WebAssembly version of the preprocessor.
#
# Requires emscripten to be installed.
# Was successfully tested with emscripten 3.1.69 installed through emsdk
# tool, as described on: https://emscripten.org/docs/getting_started/downloads.html
# Don’t forget to source script snippet in current shell before running meson.
#
# Compilation creates a .wasm and .js wrapper under <builddir>/src/
#
# Can be run locally with node.js using:
# node dynare-preprocessor.js file.mod
# NB: a version of node.js is shipped with emscripten (under the node/
# subdirectory), but another version should also work.
[binaries]
cpp = 'em++'
[host_machine]
system = 'emscripten'
# Could be changed to wasm64 if 4GB memory constraint is hit
# Some background: https://v8.dev/blog/4gb-wasm-memory
cpu_family = 'wasm32'
cpu = 'wasm32'
endian = 'little'
[built-in options]
# Never do a debug build, because otherwise the lack of optimisations can
# overflow the memory capacities.
buildtype = 'release'
# The -fexceptions flag (for both compilation and linking) is needed for an
# unknown reason (C++ compilers are supposed to always add exception support).
# The -Wno-unqualified-std-cast-call flag removes many warnings about “move”
# not being qualified with “std::” namespace.
# The -fexperimental-library flag is needed to get std::jthread support (it was
# supposed to no longer be necessary for LLVM 20, but for some reason we still
# need it).
cpp_args = [ '-fexceptions', '-Wno-unqualified-std-cast-call', '-fexperimental-library' ]
# NODERAWFS=1 is needed for accessing the local filesystem
cpp_link_args = [ '-s', 'NODERAWFS=1', '-fexceptions' ]
[properties]
# It’s necessary to use a different copy of Boost than the one under
# /usr/include, because otherwise GCC headers confuse Clang
boost_root = '/tmp/boost_1_86_0'
# Meson cross file for targeting Windows from Linux
# NB: The boost_root property must be set, possibly through a second cross file
[binaries]
cpp = 'x86_64-w64-mingw32-g++-posix'
strip = 'x86_64-w64-mingw32-strip'
[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'
[built-in options]
prefer_static = true
# See the comments in the main Dynare Meson cross-file
cpp_args = [ '-fstack-protector', '-march=nocona', '-msahf', '-mtune=generic' ]
cpp_link_args = [ '-fstack-protector' ]
#[properties]
#boost_root = '/home/sebastien/dynare/unstable/preprocessor/deps/mingw64/'
/*
* Copyright © 2022-2024 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <cstdlib>
#include <ios>
#include <iostream>
#include "Bytecode.hh"
namespace Bytecode
{
Writer::Writer(const filesystem::path& filename)
{
open(filename, ios::out | ios::binary);
if (!is_open())
{
cerr << R"(Error : Can't open file ")" << filename.string() << R"(" for writing)" << endl;
exit(EXIT_FAILURE);
}
}
template<>
Writer&
operator<<(Writer& code_file, const FCALL& instr)
{
code_file.instructions_positions.push_back(code_file.tellp());
auto write_member = [&code_file](const auto& member) {
code_file.write(reinterpret_cast<const char*>(&member), sizeof member);
};
write_member(instr.tag);
write_member(instr.nb_output_arguments);
write_member(instr.nb_input_arguments);
write_member(instr.indx);
write_member(instr.add_input_arguments);
write_member(instr.row);
write_member(instr.col);
write_member(instr.call_type);
int size = static_cast<int>(instr.func_name.size());
write_member(size);
code_file.write(instr.func_name.c_str(), size + 1);
size = static_cast<int>(instr.arg_func_name.size());
write_member(size);
code_file.write(instr.arg_func_name.c_str(), size + 1);
return code_file;
}
template<>
Writer&
operator<<(Writer& code_file, const FBEGINBLOCK& instr)
{
code_file.instructions_positions.push_back(code_file.tellp());
auto write_member = [&code_file](const auto& member) {
code_file.write(reinterpret_cast<const char*>(&member), sizeof member);
};
write_member(instr.tag);
write_member(instr.size);
write_member(instr.type);
for (int i = 0; i < instr.size; i++)
{
write_member(instr.variables[i]);
write_member(instr.equations[i]);
}
if (instr.type == BlockSimulationType::solveTwoBoundariesSimple
|| instr.type == BlockSimulationType::solveTwoBoundariesComplete
|| instr.type == BlockSimulationType::solveBackwardComplete
|| instr.type == BlockSimulationType::solveForwardComplete)
{
write_member(instr.is_linear);
write_member(instr.u_count_int);
}
write_member(instr.nb_col_jacob);
write_member(instr.det_exo_size);
write_member(instr.exo_size);
ranges::for_each_n(instr.det_exogenous.begin(), instr.det_exo_size, write_member);
ranges::for_each_n(instr.exogenous.begin(), instr.exo_size, write_member);
return code_file;
}
}
/*
* Copyright © 2007-2024 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef BYTECODE_HH
#define BYTECODE_HH
#include <concepts>
#include <filesystem>
#include <fstream>
#include <ios>
#include <type_traits>
#include <utility>
#include <vector>
#include "CommonEnums.hh"
using namespace std;
namespace Bytecode
{
// The different tags encoding a bytecode instruction
enum class Tag
{
FLDZ, // Loads a zero onto the stack
FLDC, // Loads a constant term onto the stack
FDIMT, // Defines the number of temporary terms - dynamic context (the period has to be indicated)
FDIMST, // Defines the number of temporary terms - static context (the period hasn’t to be
// indicated)
FLDT, // Loads a temporary term onto the stack - dynamic context (the period has to be indicated)
FLDST, // Loads a temporary term onto the stack - static context (the period hasn’t to be
// indicated)
FSTPT, // Stores a temporary term from the stack - dynamic context (the period has to be
// indicated)
FSTPST, // Stores a temporary term from the stack - static context (the period hasn’t to be
// indicated)
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)
FLDR, // Loads a residual onto the stack
FSTPR, // Stores a residual from the stack
FSTPG, // Stores the derivative of a simple (single-equation) block in simulate mode
FSTPG2, // Stores the derivative matrix of a block in evaluate mode
FUNARY, // A unary operator
FBINARY, // A binary operator
FTRINARY, // A trinary operator
FJMPIFEVAL, // Jump if evaluate = true
FJMP, // Jump
FBEGINBLOCK, // Marks the beginning of a model block
FENDBLOCK, // Marks the end of a model block
FENDEQU, // Marks the last equation of the block; for a block that has to be solved, the
// derivatives appear just after this flag
FEND, // Marks the end of the model code
FNUMEXPR, // Stores the expression type and references
FCALL, // Call an external function
FLDTEF, // Loads the result of an external function onto the stack
FSTPTEF, // Stores the result of an external function from the stack
FLDTEFD, // Loads the result of the 1st derivative of an external function onto the stack
FSTPTEFD, // Stores the result of the 1st derivative of an external function from the stack
FLDTEFDD, // Loads the result of the 2nd derivative of an external function onto the stack
FSTPTEFDD // Stores the result of the 2nd derivative of an external function from the stack
};
enum class ExpressionType
{
TemporaryTerm,
ModelEquation,
FirstEndoDerivative,
FirstExoDerivative,
FirstExodetDerivative,
};
enum class ExternalFunctionCallType
{
levelWithoutDerivative,
levelWithFirstDerivative,
levelWithFirstAndSecondDerivative,
separatelyProvidedFirstDerivative,
numericalFirstDerivative,
separatelyProvidedSecondDerivative,
numericalSecondDerivative
};
class Writer;
struct Instruction
{
const Tag tag;
explicit Instruction(Tag tag_arg) : tag {tag_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
would no longer be POD; its memory representation would also include
runtime type information, and our crude serialization technique (copying the
whole object from memory) would thus not work. */
~Instruction() = default;
};
template<typename T>
concept IsInstruction = derived_from<T, Instruction>;
struct FLDZ final : public Instruction
{
FLDZ() : Instruction {Tag::FLDZ}
{
}
};
struct FEND final : public Instruction
{
FEND() : Instruction {Tag::FEND}
{
}
};
struct FENDBLOCK final : public Instruction
{
FENDBLOCK() : Instruction {Tag::FENDBLOCK}
{
}
};
struct FENDEQU final : public Instruction
{
FENDEQU() : Instruction {Tag::FENDEQU}
{
}
};
struct FDIMT final : public Instruction
{
const int size;
explicit FDIMT(int size_arg) : Instruction {Tag::FDIMT}, size {size_arg}
{
}
};
struct FDIMST final : public Instruction
{
const int size;
explicit FDIMST(int size_arg) : Instruction {Tag::FDIMST}, size {size_arg}
{
}
};
struct FLDC final : public Instruction
{
const double value;
explicit FLDC(double value_arg) : Instruction {Tag::FLDC}, value {value_arg}
{
}
};
struct FLDU final : public Instruction
{
const int pos;
explicit FLDU(int pos_arg) : Instruction {Tag::FLDU}, pos {pos_arg}
{
}
};
struct FLDSU final : public Instruction
{
const int pos;
explicit FLDSU(int pos_arg) : Instruction {Tag::FLDSU}, pos {pos_arg}
{
}
};
struct FLDR final : public Instruction
{
const int pos;
explicit FLDR(int pos_arg) : Instruction {Tag::FLDR}, pos {pos_arg}
{
}
};
struct FLDT final : public Instruction
{
const int pos;
explicit FLDT(int pos_arg) : Instruction {Tag::FLDT}, pos {pos_arg}
{
}
};
struct FLDST final : public Instruction
{
const int pos;
explicit FLDST(int pos_arg) : Instruction {Tag::FLDST}, pos {pos_arg}
{
}
};
struct FSTPT final : public Instruction
{
const int pos;
explicit FSTPT(int pos_arg) : Instruction {Tag::FSTPT}, pos {pos_arg}
{
}
};
struct FSTPST final : public Instruction
{
const int pos;
explicit FSTPST(int pos_arg) : Instruction {Tag::FSTPST}, pos {pos_arg}
{
}
};
struct FSTPR final : public Instruction
{
const int pos;
explicit FSTPR(int pos_arg) : Instruction {Tag::FSTPR}, pos {pos_arg}
{
}
};
struct FSTPU final : public Instruction
{
const int pos;
explicit FSTPU(int pos_arg) : Instruction {Tag::FSTPU}, pos {pos_arg}
{
}
};
struct FSTPSU final : public Instruction
{
const int pos;
explicit FSTPSU(int pos_arg) : Instruction {Tag::FSTPSU}, pos {pos_arg}
{
}
};
struct FSTPG final : public Instruction
{
explicit FSTPG() : Instruction {Tag::FSTPG}
{
}
};
struct FSTPG2 final : public Instruction
{
const int row, col;
FSTPG2(int row_arg, int col_arg) : Instruction {Tag::FSTPG2}, row {row_arg}, col {col_arg}
{
}
};
struct FUNARY final : public Instruction
{
const UnaryOpcode op_code;
explicit FUNARY(UnaryOpcode op_code_arg) : Instruction {Tag::FUNARY}, op_code {op_code_arg}
{
}
};
struct FBINARY final : public Instruction
{
const BinaryOpcode op_code;
explicit FBINARY(BinaryOpcode op_code_arg) : Instruction {Tag::FBINARY}, op_code {op_code_arg}
{
}
};
struct FTRINARY final : public Instruction
{
const TrinaryOpcode op_code;
explicit FTRINARY(TrinaryOpcode op_code_arg) : Instruction {Tag::FTRINARY}, op_code {op_code_arg}
{
}
};
struct FJMPIFEVAL final : public Instruction
{
const int pos;
explicit FJMPIFEVAL(int pos_arg) : Instruction {Tag::FJMPIFEVAL}, pos {pos_arg}
{
}
};
struct FJMP final : public Instruction
{
const int pos;
explicit FJMP(int pos_arg) : Instruction {Tag::FJMP}, pos {pos_arg}
{
}
};
struct FLDTEF final : public Instruction
{
const int number;
explicit FLDTEF(int number_arg) : Instruction {Tag::FLDTEF}, number {number_arg}
{
}
};
struct FSTPTEF final : public Instruction
{
const int number;
explicit FSTPTEF(int number_arg) : Instruction {Tag::FSTPTEF}, number {number_arg}
{
}
};
struct FLDTEFD final : public Instruction
{
const int indx, row;
FLDTEFD(int indx_arg, int row_arg) : Instruction {Tag::FLDTEFD}, indx {indx_arg}, row {row_arg}
{
}
};
struct FSTPTEFD final : public Instruction
{
const int indx, row;
FSTPTEFD(int indx_arg, int row_arg) : Instruction {Tag::FSTPTEFD}, indx {indx_arg}, row {row_arg}
{
}
};
struct FLDTEFDD final : public Instruction
{
const int indx, row, col;
FLDTEFDD(int indx_arg, int row_arg, int col_arg) :
Instruction {Tag::FLDTEFDD}, indx {indx_arg}, row {row_arg}, col {col_arg}
{
}
};
struct FSTPTEFDD final : public Instruction
{
const int indx, row, col;
FSTPTEFDD(int indx_arg, int row_arg, int col_arg) :
Instruction {Tag::FSTPTEF}, indx {indx_arg}, row {row_arg}, col {col_arg}
{
}
};
struct FLDVS final : public Instruction
{
const SymbolType type;
const int pos;
FLDVS(SymbolType type_arg, int pos_arg) : Instruction {Tag::FLDVS}, type {type_arg}, pos {pos_arg}
{
}
};
struct FLDSV final : public Instruction
{
const SymbolType type;
const int pos;
FLDSV(SymbolType type_arg, int pos_arg) : Instruction {Tag::FLDSV}, type {type_arg}, pos {pos_arg}
{
}
};
struct FSTPSV final : public Instruction
{
const SymbolType type;
const int pos;
FSTPSV(SymbolType type_arg, int pos_arg) :
Instruction {Tag::FSTPSV}, type {type_arg}, pos {pos_arg}
{
}
};
struct FLDV final : public Instruction
{
const SymbolType type;
const int pos, lead_lag;
FLDV(SymbolType type_arg, int pos_arg, int lead_lag_arg) :
Instruction {Tag::FLDV}, type {type_arg}, pos {pos_arg}, lead_lag {lead_lag_arg}
{
}
};
struct FSTPV final : public Instruction
{
const SymbolType type;
const int pos, lead_lag;
FSTPV(SymbolType type_arg, int pos_arg, int lead_lag_arg) :
Instruction {Tag::FSTPV}, type {type_arg}, pos {pos_arg}, lead_lag {lead_lag_arg}
{
}
};
class FCALL final : public Instruction
{
template<IsInstruction B>
friend Writer& operator<<(Writer& 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) :
Instruction {Tag::FCALL},
nb_output_arguments {nb_output_arguments_arg},
nb_input_arguments {nb_input_arguments_arg},
indx {indx_arg},
func_name {move(func_name_arg)},
call_type {call_type_arg}
{
}
/* Deserializing constructor.
Updates the code pointer to point beyond the bytes read. */
FCALL(char*& code) : Instruction {Tag::FCALL}
{
code += sizeof(tag);
auto read_member = [&code](auto& member) {
member = *reinterpret_cast<add_pointer_t<decltype(member)>>(code);
code += sizeof member;
};
read_member(nb_output_arguments);
read_member(nb_input_arguments);
read_member(indx);
read_member(add_input_arguments);
read_member(row);
read_member(col);
read_member(call_type);
int size;
read_member(size);
func_name = code;
code += size + 1;
read_member(size);
arg_func_name = code;
code += size + 1;
}
string
get_function_name()
{
// printf("get_function_name => func_name=%s\n",func_name.c_str());fflush(stdout);
return func_name;
}
int
get_nb_output_arguments()
{
return nb_output_arguments;
}
int
get_nb_input_arguments()
{
return nb_input_arguments;
}
int
get_indx()
{
return indx;
}
void
set_arg_func_name(string arg_arg_func_name)
{
arg_func_name = move(arg_arg_func_name);
}
string
get_arg_func_name()
{
return arg_func_name;
}
void
set_nb_add_input_arguments(int arg_add_input_arguments)
{
add_input_arguments = arg_add_input_arguments;
}
int
get_nb_add_input_arguments()
{
return add_input_arguments;
}
void
set_row(int arg_row)
{
row = arg_row;
}
int
get_row()
{
return row;
}
void
set_col(int arg_col)
{
col = arg_col;
}
int
get_col()
{
return col;
}
ExternalFunctionCallType
get_call_type()
{
return call_type;
}
};
class FNUMEXPR final : public Instruction
{
private:
ExpressionType expression_type;
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:
FNUMEXPR(const ExpressionType expression_type_arg, int equation_arg) :
Instruction {Tag::FNUMEXPR},
expression_type {expression_type_arg},
equation {equation_arg},
dvariable1 {0},
lag1 {0}
{
}
FNUMEXPR(const ExpressionType expression_type_arg, int equation_arg, int dvariable1_arg) :
Instruction {Tag::FNUMEXPR},
expression_type {expression_type_arg},
equation {equation_arg},
dvariable1 {dvariable1_arg},
lag1 {0}
{
}
FNUMEXPR(const ExpressionType expression_type_arg, int equation_arg, int dvariable1_arg,
int lag1_arg) :
Instruction {Tag::FNUMEXPR},
expression_type {expression_type_arg},
equation {equation_arg},
dvariable1 {dvariable1_arg},
lag1 {lag1_arg}
{
}
ExpressionType
get_expression_type()
{
return expression_type;
}
int
get_equation()
{
return equation;
}
int
get_dvariable1()
{
return dvariable1;
}
int
get_lag1()
{
return lag1;
}
};
class FBEGINBLOCK final : public Instruction
{
template<IsInstruction B>
friend Writer& operator<<(Writer& code_file, const B& instr);
private:
int size {0};
BlockSimulationType type;
vector<int> variables;
vector<int> equations;
vector<int> exogenous;
vector<int> det_exogenous;
bool is_linear {false};
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>& variables_arg, const vector<int>& equations_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) :
Instruction {Tag::FBEGINBLOCK},
size {size_arg},
type {type_arg},
variables {variables_arg.begin() + first_element,
variables_arg.begin() + (first_element + block_size)},
equations {equations_arg.begin() + first_element,
equations_arg.begin() + (first_element + block_size)},
exogenous {move(exogenous_arg)},
det_exogenous {move(det_exogenous_arg)},
is_linear {is_linear_arg},
u_count_int {u_count_int_arg},
nb_col_jacob {nb_col_jacob_arg},
det_exo_size {det_exo_size_arg},
exo_size {exo_size_arg}
{
}
// Constructor when derivatives w.r.t. exogenous are absent
FBEGINBLOCK(int size_arg, BlockSimulationType type_arg, int first_element, int block_size,
const vector<int>& variables_arg, const vector<int>& equations_arg,
bool is_linear_arg, int u_count_int_arg, int nb_col_jacob_arg) :
Instruction {Tag::FBEGINBLOCK},
size {size_arg},
type {type_arg},
variables {variables_arg.begin() + first_element,
variables_arg.begin() + (first_element + block_size)},
equations {equations_arg.begin() + first_element,
equations_arg.begin() + (first_element + block_size)},
is_linear {is_linear_arg},
u_count_int {u_count_int_arg},
nb_col_jacob {nb_col_jacob_arg},
det_exo_size {0},
exo_size {0}
{
}
/* Deserializing constructor.
Updates the code pointer to point beyond the bytes read. */
FBEGINBLOCK(char*& code) : Instruction {Tag::FBEGINBLOCK}
{
code += sizeof(tag);
auto read_member = [&code](auto& member) {
member = *reinterpret_cast<add_pointer_t<decltype(member)>>(code);
code += sizeof member;
};
read_member(size);
read_member(type);
variables.resize(size);
equations.resize(size);
for (int i {0}; i < size; i++)
{
read_member(variables[i]);
read_member(equations[i]);
}
if (type == BlockSimulationType::solveTwoBoundariesSimple
|| type == BlockSimulationType::solveTwoBoundariesComplete
|| type == BlockSimulationType::solveBackwardComplete
|| type == BlockSimulationType::solveForwardComplete)
{
read_member(is_linear);
read_member(u_count_int);
}
read_member(nb_col_jacob);
read_member(det_exo_size);
read_member(exo_size);
for (int i {0}; i < det_exo_size; i++)
{
int tmp_i;
read_member(tmp_i);
det_exogenous.push_back(tmp_i);
}
for (int i {0}; i < exo_size; i++)
{
int tmp_i;
read_member(tmp_i);
exogenous.push_back(tmp_i);
}
}
int
get_size()
{
return size;
}
BlockSimulationType
get_type()
{
return type;
}
bool
get_is_linear()
{
return is_linear;
}
int
get_u_count_int()
{
return u_count_int;
}
vector<int>
get_variables()
{
return variables;
}
vector<int>
get_equations()
{
return equations;
}
int
get_nb_col_jacob()
{
return nb_col_jacob;
}
int
get_exo_size()
{
return exo_size;
}
int
get_det_exo_size()
{
return det_exo_size;
}
vector<int>
get_exogenous()
{
return exogenous;
}
};
// Superclass of std::ofstream for writing a sequence of bytecode instructions
class Writer : private ofstream
{
template<IsInstruction B>
friend Writer& operator<<(Writer& code_file, const B& instr);
private:
// Stores the positions of all instructions in the byte stream
vector<pos_type> instructions_positions;
public:
Writer(const filesystem::path& filename);
// Returns the number of the next instruction to be written
int
getInstructionCounter() const
{
return static_cast<int>(instructions_positions.size());
}
/* Overwrites an existing instruction, given its number.
It is the responsibility of the caller to ensure that the new instruction
occupies exactly as many bytes as the former one. */
void
overwriteInstruction(int instruction_number, const IsInstruction auto& new_instruction)
{
seekp(instructions_positions.at(instruction_number));
*this << new_instruction;
instructions_positions.pop_back();
seekp(0, ios_base::end);
}
};
// Overloads of operator<< for writing bytecode instructions
template<IsInstruction B>
Writer&
operator<<(Writer& code_file, const B& instr)
{
code_file.instructions_positions.push_back(code_file.tellp());
code_file.write(reinterpret_cast<const char*>(&instr), sizeof(B));
return code_file;
}
template<>
Writer& operator<<(Writer& code_file, const FCALL& instr);
template<>
Writer& operator<<(Writer& code_file, const FBEGINBLOCK& instr);
}
#endif
/*
* Copyright (C) 2007-2017 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CODEINTERPRETER_HH
#define _CODEINTERPRETER_HH
//#define DEBUGL
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <fstream>
#include <cstring>
#include <vector>
#ifdef LINBCG
# include "linbcg.hh"
#endif
#ifdef BYTE_CODE
# ifndef DEBUG_EX
# include "mex.h"
# else
# include "mex_interface.hh"
# endif
#endif
#include <stdint.h>
#define NEAR_ZERO (1e-12)
using namespace std;
/**
* \enum Tags
* \brief The differents flags of the bytecode
*/
enum Tags
{
FLDZ, //!< Stores zero in the stack - 0 (0)
FLDC, //!< Stores a constant term in the stack - 1 (1)
FDIMT, //!< Defines the number of temporary terms - dynamic context (the period has to be indicated) - 2 (2)
FDIMST, //!< Defines the number of temporary terms - static context (the period hasn't to be indicated) - 3 (3)
FLDT, //!< Stores a temporary term in the stack - dynamic context (the period has to be indicated) - 4 (4)
FLDST, //!< Stores a temporary term in the stack - static context (the period hasn't to be indicated) - 5 (5)
FSTPT, //!< Loads a temporary term from the stack - dynamic context (the period has to be indicated) - 6 (6)
FSTPST, //!< Loads a temporary term from the stack - static context (the period hasn't to be indicated) - 7 (7)
FLDU, //!< Stores an element of the vector U in the stack - dynamic context (the period has to be indicated) - 8 (8)
FLDSU, //!< Stores an element of the vector U in the stack - static context (the period hasn't to be indicated) - 9 (9)
FSTPU, //!< Loads an element of the vector U from the stack - dynamic context (the period has to be indicated) - A (10)
FSTPSU, //!< Loads an element of the vector U from the stack - static context (the period hasn't to be indicated) - B (11)
FLDV, //!< Stores a variable (described in SymbolType) in the stack - dynamic context (the period has to be indicated) - C (12)
FLDSV, //!< Stores a variable (described in SymbolType) in the stack - static context (the period hasn't to be indicated) - D (13)
FLDVS, //!< Stores a variable (described in SymbolType) in the stack - dynamic context but inside the STEADYSTATE function (the period hasn't to be indicated) - E (14)
FSTPV, //!< Loads a variable (described in SymbolType) from the stack - dynamic context (the period has to be indicated) - F (15)
FSTPSV, //!< Loads a variable (described in SymbolType) from the stack - static context (the period hasn't to be indicated) - 10 (16)
FLDR, //!< Stores a residual in the stack - 11 (17)
FSTPR, //!< Loads a residual from the stack - 12 (18)
FSTPG, //!< Loads a derivative from the stack - 13 (19)
FSTPG2, //!< Loads a derivative matrix for static model from the stack - 14 (20)
FSTPG3, //!< Loads a derivative matrix for a dynamic model from the stack - 15 (21)
FSTPG4, //!< Loads a second order derivative matrix for a dynamic model from the stack - 16 (22)
FUNARY, //!< A Unary operator - 17 (23)
FBINARY, //!< A binary operator - 18 (24)
FTRINARY, //!< A trinary operator - 19 (25)
FCUML, //!< Cumulates the result - 1A (26)
FJMPIFEVAL, //!< Jump if evaluate = true - 1B (27)
FJMP, //!< Jump - 1C (28)
FBEGINBLOCK, //!< Defines the begining of a model block - 1D (29)
FENDBLOCK, //!< Defines the end of a model block - 1E (30)
FENDEQU, //!< Defines the last equation of the block. For block that has to be solved, the derivatives appear just after this flag - 1F (31)
FEND, //!< Defines the end of the model code - 20 (32)
FOK, //!< Used for debugging purpose - 21 (33)
FNUMEXPR, //!< Store the expression type and references - 22 (34)
FCALL, //!< Call an external function - 23 (35)
FPUSH, //!< Push a double in the stack - 24 (36)
FPOP, //!< Pop a double from the stack - 25 (37)
FLDTEF, //!< Stores the result of an external function in the stack - 26 (38)
FSTPTEF, //!< Loads the result of an external function from the stack- 27 (39)
FLDTEFD, //!< Stores the result of an external function in the stack - 28 (40)
FSTPTEFD, //!< Loads the result of an external function from the stack- 29 (41)
FLDTEFDD, //!< Stores the result of an external function in the stack - 28 (42)
FSTPTEFDD //!< Loads the result of an external function from the stack- 29 (43)
};
enum BlockType
{
SIMULTANS, //!< Simultaneous time separable block
PROLOGUE, //!< Prologue block (one equation at the beginning, later merged)
EPILOGUE, //!< Epilogue block (one equation at the beginning, later merged)
SIMULTAN //!< Simultaneous time unseparable block
};
enum EquationType
{
E_UNKNOWN, //!< Unknown equation type
E_EVALUATE, //!< Simple evaluation, normalized variable on left-hand side
E_EVALUATE_S, //!< Simple evaluation, normalize using the first order derivative
E_SOLVE //!< No simple evaluation of the equation, it has to be solved
};
enum BlockSimulationType
{
UNKNOWN, //!< Unknown simulation type
EVALUATE_FORWARD, //!< Simple evaluation, normalized variable on left-hand side, forward
EVALUATE_BACKWARD, //!< Simple evaluation, normalized variable on left-hand side, backward
SOLVE_FORWARD_SIMPLE, //!< Block of one equation, newton solver needed, forward
SOLVE_BACKWARD_SIMPLE, //!< Block of one equation, newton solver needed, backward
SOLVE_TWO_BOUNDARIES_SIMPLE, //!< Block of one equation, newton solver needed, forward & ackward
SOLVE_FORWARD_COMPLETE, //!< Block of several equations, newton solver needed, forward
SOLVE_BACKWARD_COMPLETE, //!< Block of several equations, newton solver needed, backward
SOLVE_TWO_BOUNDARIES_COMPLETE //!< Block of several equations, newton solver needed, forward and backwar
};
//! Enumeration of possible symbol types
/*! Warning: do not to change existing values for 0 to 4: the values matter for homotopy_setup command */
enum SymbolType
{
eEndogenous = 0, //!< Endogenous
eExogenous = 1, //!< Exogenous
eExogenousDet = 2, //!< Exogenous deterministic
eParameter = 4, //!< Parameter
eModelLocalVariable = 10, //!< Local variable whose scope is model (pound expression)
eModFileLocalVariable = 11, //!< Local variable whose scope is mod file (model excluded)
eExternalFunction = 12, //!< External (user-defined) function
eTrend = 13, //!< Trend variable
eStatementDeclaredVariable = 14, //!< Local variable assigned within a Statement (see subsample statement for example)
eLogTrend = 15, //!< Log-trend variable
eUnusedEndogenous = 16
};
enum ExpressionType
{
TemporaryTerm,
ModelEquation,
FirstEndoDerivative,
FirstOtherEndoDerivative,
FirstExoDerivative,
FirstExodetDerivative,
FirstParamDerivative,
SecondEndoDerivative,
SecondExoDerivative,
SecondExodetDerivative,
SecondParamDerivative,
ThirdEndoDerivative,
ThirdExoDerivative,
ThirdExodetDerivative,
ThirdParamDerivative
};
enum UnaryOpcode
{
oUminus,
oExp,
oLog,
oLog10,
oCos,
oSin,
oTan,
oAcos,
oAsin,
oAtan,
oCosh,
oSinh,
oTanh,
oAcosh,
oAsinh,
oAtanh,
oSqrt,
oAbs,
oSign,
oSteadyState,
oSteadyStateParamDeriv, // for the derivative of the STEADY_STATE operator w.r.t. to a parameter
oSteadyStateParam2ndDeriv, // for the 2nd derivative of the STEADY_STATE operator w.r.t. to a parameter
oExpectation,
oErf
};
enum BinaryOpcode
{
oPlus,
oMinus,
oTimes,
oDivide,
oPower,
oPowerDeriv, // for the derivative of the power function (see trac ticket #78)
oEqual,
oMax,
oMin,
oLess,
oGreater,
oLessEqual,
oGreaterEqual,
oEqualEqual,
oDifferent
};
enum TrinaryOpcode
{
oNormcdf,
oNormpdf
};
enum external_function_type
{
ExternalFunctionWithoutDerivative,
ExternalFunctionWithFirstDerivative,
ExternalFunctionWithFirstandSecondDerivative,
ExternalFunctionNumericalFirstDerivative,
ExternalFunctionFirstDerivative,
ExternalFunctionNumericalSecondDerivative,
ExternalFunctionSecondDerivative
};
enum PriorDistributions
{
eNoShape = 0,
eBeta = 1,
eGamma = 2,
eNormal = 3,
eInvGamma = 4,
eInvGamma1 = 4,
eUniform = 5,
eInvGamma2 = 6,
eDirichlet = 7,
eWeibull = 8
};
enum NodeTreeReference
{
eResiduals = 0,
eFirstDeriv = 1,
eSecondDeriv = 2,
eThirdDeriv = 3,
eResidualsParamsDeriv = 4,
eJacobianParamsDeriv = 5,
eResidualsParamsSecondDeriv = 6,
eJacobianParamsSecondDeriv = 7,
eHessianParamsDeriv = 8
};
struct Block_contain_type
{
int Equation, Variable, Own_Derivative;
};
#pragma pack(push, 1)
class TagWithoutArgument
{
protected:
uint8_t op_code;
public:
inline
TagWithoutArgument(uint8_t op_code_arg) : op_code(op_code_arg)
{
};
inline void
write(ostream &CompileCode, unsigned int &instruction_number)
{
CompileCode.write(reinterpret_cast<char *>(this), sizeof(*this));
instruction_number++;
};
};
template < class T1 >
class TagWithOneArgument
{
protected:
uint8_t op_code;
T1 arg1;
public:
inline
TagWithOneArgument(uint8_t op_code_arg) : op_code(op_code_arg)
{
};
inline
TagWithOneArgument(uint8_t op_code_arg, T1 arg_arg1) : op_code(op_code_arg), arg1(arg_arg1)
{
};
inline void
write(ostream &CompileCode, unsigned int &instruction_number)
{
CompileCode.write(reinterpret_cast<char *>(this), sizeof(TagWithOneArgument));
instruction_number++;
};
};
template < class T1, class T2 >
class TagWithTwoArguments
{
protected:
uint8_t op_code;
T1 arg1;
T2 arg2;
public:
inline
TagWithTwoArguments(uint8_t op_code_arg) : op_code(op_code_arg)
{
};
inline
TagWithTwoArguments(uint8_t op_code_arg, T1 arg_arg1, T2 arg_arg2) : op_code(op_code_arg), arg1(arg_arg1), arg2(arg_arg2)
{
};
inline void
write(ostream &CompileCode, unsigned int &instruction_number)
{
CompileCode.write(reinterpret_cast<char *>(this), sizeof(*this));
instruction_number++;
};
};
template < class T1, class T2, class T3 >
class TagWithThreeArguments
{
protected:
uint8_t op_code;
T1 arg1;
T2 arg2;
T3 arg3;
public:
inline
TagWithThreeArguments(uint8_t op_code_arg) : op_code(op_code_arg)
{
};
inline
TagWithThreeArguments(uint8_t op_code_arg, T1 arg_arg1, T2 arg_arg2, T3 arg_arg3) : op_code(op_code_arg), arg1(arg_arg1), arg2(arg_arg2), arg3(arg_arg3)
{
};
inline void
write(ostream &CompileCode, unsigned int &instruction_number)
{
CompileCode.write(reinterpret_cast<char *>(this), sizeof(*this));
instruction_number++;
};
};
template < class T1, class T2, class T3, class T4 >
class TagWithFourArguments
{
protected:
uint8_t op_code;
T1 arg1;
T2 arg2;
T3 arg3;
T4 arg4;
public:
inline
TagWithFourArguments(uint8_t op_code_arg) : op_code(op_code_arg)
{
};
inline
TagWithFourArguments(uint8_t op_code_arg, T1 arg_arg1, T2 arg_arg2, T3 arg_arg3, T4 arg_arg4) : op_code(op_code_arg), arg1(arg_arg1), arg2(arg_arg2), arg3(arg_arg3), arg4(arg_arg4)
{
};
inline void
write(ostream &CompileCode, unsigned int &instruction_number)
{
CompileCode.write(reinterpret_cast<char *>(this), sizeof(*this));
instruction_number++;
};
};
class FLDZ_ : public TagWithoutArgument
{
public:
inline
FLDZ_() : TagWithoutArgument(FLDZ)
{
};
};
class FEND_ : public TagWithoutArgument
{
public:
inline
FEND_() : TagWithoutArgument(FEND)
{
};
};
class FENDBLOCK_ : public TagWithoutArgument
{
public:
inline
FENDBLOCK_() : TagWithoutArgument(FENDBLOCK)
{
};
};
class FENDEQU_ : public TagWithoutArgument
{
public:
inline
FENDEQU_() : TagWithoutArgument(FENDEQU)
{
};
};
class FCUML_ : public TagWithoutArgument
{
public:
inline
FCUML_() : TagWithoutArgument(FCUML)
{
};
};
class FPUSH_ : public TagWithoutArgument
{
public:
inline
FPUSH_() : TagWithoutArgument(FPUSH)
{
};
};
class FPOP_ : public TagWithoutArgument
{
public:
inline
FPOP_() : TagWithoutArgument(FPOP)
{
};
};
class FDIMT_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FDIMT_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FDIMT)
{
};
inline
FDIMT_(unsigned int size_arg) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FDIMT, size_arg)
{
};
inline unsigned int
get_size()
{
return arg1;
};
};
class FDIMST_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FDIMST_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FDIMST)
{
};
inline
FDIMST_(const unsigned int size_arg) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FDIMST, size_arg)
{
};
inline unsigned int
get_size()
{
return arg1;
};
};
class FLDC_ : public TagWithOneArgument<double>
{
public:
inline
FLDC_() : TagWithOneArgument<double>::TagWithOneArgument(FLDC)
{
};
inline
FLDC_(const double value_arg) : TagWithOneArgument<double>::TagWithOneArgument(FLDC, value_arg)
{
};
inline double
get_value()
{
return arg1;
};
};
class FLDU_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FLDU_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDU)
{
};
inline
FLDU_(const unsigned int pos_arg) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDU, pos_arg)
{
};
inline unsigned int
get_pos()
{
return arg1;
};
};
class FLDSU_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FLDSU_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDSU)
{
};
inline
FLDSU_(const unsigned int pos_arg) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDSU, pos_arg)
{
};
inline unsigned int
get_pos()
{
return arg1;
};
};
class FLDR_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FLDR_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDR)
{
};
inline
FLDR_(const unsigned int pos_arg) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDR, pos_arg)
{
};
inline unsigned int
get_pos()
{
return arg1;
};
};
class FLDT_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FLDT_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDT)
{
};
inline
FLDT_(const unsigned int pos_arg) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDT, pos_arg)
{
};
inline unsigned int
get_pos()
{
return arg1;
};
};
class FLDST_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FLDST_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDST)
{
};
inline
FLDST_(const unsigned int pos_arg) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDST, pos_arg)
{
};
inline unsigned int
get_pos()
{
return arg1;
};
};
class FSTPT_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FSTPT_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPT)
{
};
inline
FSTPT_(const unsigned int pos_arg) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPT, pos_arg)
{
};
inline unsigned int
get_pos()
{
return arg1;
};
};
class FSTPST_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FSTPST_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPST)
{
};
inline
FSTPST_(const unsigned int pos_arg) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPST, pos_arg)
{
};
inline unsigned int
get_pos()
{
return arg1;
};
};
class FSTPR_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FSTPR_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPR)
{
};
inline
FSTPR_(const unsigned int pos_arg) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPR, pos_arg)
{
};
inline unsigned int
get_pos()
{
return arg1;
};
};
class FSTPU_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FSTPU_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPU)
{
};
inline
FSTPU_(const unsigned int pos_arg) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPU, pos_arg)
{
};
inline unsigned int
get_pos()
{
return arg1;
};
};
class FSTPSU_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FSTPSU_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPSU)
{
};
inline
FSTPSU_(const unsigned int pos_arg) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPSU, pos_arg)
{
};
inline unsigned int
get_pos()
{
return arg1;
};
};
class FSTPG_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FSTPG_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPG, 0)
{
};
inline
FSTPG_(const unsigned int pos_arg) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPG, pos_arg)
{
};
inline unsigned int
get_pos()
{
return arg1;
};
};
class FSTPG2_ : public TagWithTwoArguments<unsigned int, unsigned int>
{
public:
inline
FSTPG2_() : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FSTPG2, 0, 0)
{
};
inline
FSTPG2_(const unsigned int pos_arg1, const unsigned int pos_arg2) : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FSTPG2, pos_arg1, pos_arg2)
{
};
inline unsigned int
get_row()
{
return arg1;
};
inline unsigned int
get_col()
{
return arg2;
};
};
class FSTPG3_ : public TagWithFourArguments<unsigned int, unsigned int, int, unsigned int>
{
public:
inline
FSTPG3_() : TagWithFourArguments<unsigned int, unsigned int, int, unsigned int>::TagWithFourArguments(FSTPG3, 0, 0, 0, 0)
{
};
inline
FSTPG3_(const unsigned int pos_arg1, const unsigned int pos_arg2, const int pos_arg3, const unsigned int pos_arg4) : TagWithFourArguments<unsigned int, unsigned int, int, unsigned int>::TagWithFourArguments(FSTPG3, pos_arg1, pos_arg2, pos_arg3, pos_arg4)
{
};
inline unsigned int
get_row()
{
return arg1;
};
inline unsigned int
get_col()
{
return arg2;
};
inline int
get_lag()
{
return arg2;
};
inline unsigned int
get_col_pos()
{
return arg4;
};
};
class FUNARY_ : public TagWithOneArgument<uint8_t>
{
public:
inline
FUNARY_() : TagWithOneArgument<uint8_t>::TagWithOneArgument(FUNARY)
{
};
inline
FUNARY_(uint8_t op_type_arg) : TagWithOneArgument<uint8_t>::TagWithOneArgument(FUNARY, op_type_arg)
{
};
inline uint8_t
get_op_type()
{
return arg1;
};
};
class FBINARY_ : public TagWithOneArgument<uint8_t>
{
public:
inline
FBINARY_() : TagWithOneArgument<uint8_t>::TagWithOneArgument(FBINARY)
{
};
inline
FBINARY_(const int op_type_arg) : TagWithOneArgument<uint8_t>::TagWithOneArgument(FBINARY, op_type_arg)
{
};
inline uint8_t
get_op_type()
{
return arg1;
};
};
class FTRINARY_ : public TagWithOneArgument<uint8_t>
{
public:
inline
FTRINARY_() : TagWithOneArgument<uint8_t>::TagWithOneArgument(FTRINARY)
{
};
inline
FTRINARY_(const int op_type_arg) : TagWithOneArgument<uint8_t>::TagWithOneArgument(FTRINARY, op_type_arg)
{
};
inline uint8_t
get_op_type()
{
return arg1;
};
};
class FOK_ : public TagWithOneArgument<int>
{
public:
inline
FOK_() : TagWithOneArgument<int>::TagWithOneArgument(FOK)
{
};
inline
FOK_(const int arg_arg) : TagWithOneArgument<int>::TagWithOneArgument(FOK, arg_arg)
{
};
inline int
get_arg()
{
return arg1;
};
};
class FJMPIFEVAL_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FJMPIFEVAL_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FJMPIFEVAL)
{
};
inline
FJMPIFEVAL_(unsigned int arg_pos) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FJMPIFEVAL, arg_pos)
{
};
inline unsigned int
get_pos()
{
return arg1;
}
};
class FJMP_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FJMP_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FJMP)
{
};
inline
FJMP_(unsigned int arg_pos) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FJMP, arg_pos)
{
};
inline unsigned int
get_pos()
{
return arg1;
}
};
class FLDTEF_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FLDTEF_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDTEF)
{
};
inline
FLDTEF_(unsigned int number) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FLDTEF, number)
{
};
inline unsigned int
get_number()
{
return arg1;
}
};
class FSTPTEF_ : public TagWithOneArgument<unsigned int>
{
public:
inline
FSTPTEF_() : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPTEF)
{
};
inline
FSTPTEF_(unsigned int number) : TagWithOneArgument<unsigned int>::TagWithOneArgument(FSTPTEF, number)
{
};
inline unsigned int
get_number()
{
return arg1;
}
};
class FLDTEFD_ : public TagWithTwoArguments<unsigned int, unsigned int>
{
public:
inline
FLDTEFD_() : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FLDTEFD)
{
};
inline
FLDTEFD_(unsigned int indx, unsigned int row) : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FLDTEFD, indx, row)
{
};
inline unsigned int
get_indx()
{
return arg1;
};
inline unsigned int
get_row()
{
return arg2;
};
};
class FSTPTEFD_ : public TagWithTwoArguments<unsigned int, unsigned int>
{
public:
inline
FSTPTEFD_() : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FSTPTEFD)
{
};
inline
FSTPTEFD_(unsigned int indx, unsigned int row) : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FSTPTEFD, indx, row)
{
};
inline unsigned int
get_indx()
{
return arg1;
};
inline unsigned int
get_row()
{
return arg2;
};
};
class FLDTEFDD_ : public TagWithThreeArguments<unsigned int, unsigned int, unsigned int>
{
public:
inline
FLDTEFDD_() : TagWithThreeArguments<unsigned int, unsigned int, unsigned int>::TagWithThreeArguments(FLDTEFDD)
{
};
inline
FLDTEFDD_(unsigned int indx, unsigned int row, unsigned int col) : TagWithThreeArguments<unsigned int, unsigned int, unsigned int>::TagWithThreeArguments(FLDTEFDD, indx, row, col)
{
};
inline unsigned int
get_indx()
{
return arg1;
};
inline unsigned int
get_row()
{
return arg2;
};
inline unsigned int
get_col()
{
return arg3;
};
};
class FSTPTEFDD_ : public TagWithThreeArguments<unsigned int, unsigned int, unsigned int>
{
public:
inline
FSTPTEFDD_() : TagWithThreeArguments<unsigned int, unsigned int, unsigned int>::TagWithThreeArguments(FSTPTEFDD)
{
};
inline
FSTPTEFDD_(unsigned int indx, unsigned int row, unsigned int col) : TagWithThreeArguments<unsigned int, unsigned int, unsigned int>::TagWithThreeArguments(FSTPTEF, indx, row, col)
{
};
inline unsigned int
get_indx()
{
return arg1;
};
inline unsigned int
get_row()
{
return arg2;
};
inline unsigned int
get_col()
{
return arg3;
};
};
class FLDVS_ : public TagWithTwoArguments<uint8_t, unsigned int>
{
public:
inline
FLDVS_() : TagWithTwoArguments<uint8_t, unsigned int>::TagWithTwoArguments(FLDVS)
{
};
inline
FLDVS_(uint8_t type_arg, const unsigned int pos_arg) : TagWithTwoArguments<uint8_t, unsigned int>::TagWithTwoArguments(FLDVS, type_arg, pos_arg)
{
};
inline uint8_t
get_type()
{
return arg1;
};
inline unsigned int
get_pos()
{
return arg2;
};
};
class FLDSV_ : public TagWithTwoArguments<uint8_t, unsigned int>
{
public:
inline
FLDSV_() : TagWithTwoArguments<uint8_t, unsigned int>::TagWithTwoArguments(FLDSV)
{
};
inline
FLDSV_(const uint8_t type_arg, const unsigned int pos_arg) :
TagWithTwoArguments<uint8_t, unsigned int>::TagWithTwoArguments(FLDSV, type_arg, pos_arg)
{
};
inline uint8_t
get_type()
{
return arg1;
};
inline unsigned int
get_pos()
{
return arg2;
};
};
class FSTPSV_ : public TagWithTwoArguments<uint8_t, unsigned int>
{
public:
inline
FSTPSV_() : TagWithTwoArguments<uint8_t, unsigned int>::TagWithTwoArguments(FSTPSV)
{
};
inline
FSTPSV_(const uint8_t type_arg, const unsigned int pos_arg) :
TagWithTwoArguments<uint8_t, unsigned int>::TagWithTwoArguments(FSTPSV, type_arg, pos_arg)
{
};
inline uint8_t
get_type()
{
return arg1;
};
inline unsigned int
get_pos()
{
return arg2;
};
};
class FLDV_ : public TagWithThreeArguments<uint8_t, unsigned int, int>
{
public:
inline
FLDV_() : TagWithThreeArguments<uint8_t, unsigned int, int>::TagWithThreeArguments(FLDV)
{
};
inline
FLDV_(const int type_arg, const unsigned int pos_arg) :
TagWithThreeArguments<uint8_t, unsigned int, int>::TagWithThreeArguments(FLDV, type_arg, pos_arg, 0)
{
};
inline
FLDV_(const int type_arg, const unsigned int pos_arg, const int lead_lag_arg) :
TagWithThreeArguments<uint8_t, unsigned int, int>::TagWithThreeArguments(FLDV, type_arg, pos_arg, lead_lag_arg)
{
};
inline uint8_t
get_type()
{
return arg1;
};
inline unsigned int
get_pos()
{
return arg2;
};
inline int
get_lead_lag()
{
return arg3;
};
};
class FSTPV_ : public TagWithThreeArguments<uint8_t, unsigned int, int>
{
public:
inline
FSTPV_() : TagWithThreeArguments<uint8_t, unsigned int, int>::TagWithThreeArguments(FSTPV)
{
};
inline
FSTPV_(const int type_arg, const unsigned int pos_arg) :
TagWithThreeArguments<uint8_t, unsigned int, int>::TagWithThreeArguments(FSTPV, type_arg, pos_arg, 0)
{
};
inline
FSTPV_(const int type_arg, const unsigned int pos_arg, const int lead_lag_arg) :
TagWithThreeArguments<uint8_t, unsigned int, int>::TagWithThreeArguments(FSTPV, type_arg, pos_arg, lead_lag_arg)
{
};
inline uint8_t
get_type()
{
return arg1;
};
inline unsigned int
get_pos()
{
return arg2;
};
inline int
get_lead_lag()
{
return arg3;
};
};
class FCALL_ : public TagWithFourArguments<unsigned int, unsigned int, string, unsigned int>
{
string func_name;
string arg_func_name;
unsigned int add_input_arguments, row, col;
external_function_type function_type;
public:
inline
FCALL_() : TagWithFourArguments<unsigned int, unsigned int, string, unsigned int>::TagWithFourArguments(FCALL)
{
arg_func_name = "";
add_input_arguments = 0;
row = 0;
col = 0;
function_type = ExternalFunctionWithoutDerivative;
};
inline
FCALL_(unsigned int nb_output_arguments, unsigned int nb_input_arguments, string f_name, unsigned int indx) :
TagWithFourArguments<unsigned int, unsigned int, string, unsigned int>::TagWithFourArguments(FCALL, nb_output_arguments, nb_input_arguments, f_name, indx)
{
arg_func_name = "";
add_input_arguments = 0;
row = 0;
col = 0;
function_type = ExternalFunctionWithoutDerivative;
func_name = f_name;
};
inline string
get_function_name()
{
//printf("get_function_name => func_name=%s\n",func_name.c_str());fflush(stdout);
return func_name;
};
inline unsigned int
get_nb_output_arguments()
{
return arg1;
};
inline unsigned int
get_nb_input_arguments()
{
return arg2;
};
inline unsigned int
get_indx()
{
return arg4;
};
inline void
set_arg_func_name(string arg_arg_func_name)
{
arg_func_name = arg_arg_func_name;
};
inline string
get_arg_func_name()
{
return arg_func_name;
};
inline void
set_nb_add_input_arguments(unsigned int arg_add_input_arguments)
{
add_input_arguments = arg_add_input_arguments;
};
inline unsigned int
get_nb_add_input_arguments()
{
return add_input_arguments;
};
inline void
set_row(unsigned int arg_row)
{
row = arg_row;
};
inline unsigned int
get_row()
{
return row;
}
inline void
set_col(unsigned int arg_col)
{
col = arg_col;
};
inline unsigned int
get_col()
{
return col;
};
inline void
set_function_type(external_function_type arg_function_type)
{
function_type = arg_function_type;
};
inline external_function_type
get_function_type()
{
return (function_type);
}
inline void
write(ostream &CompileCode, unsigned int &instruction_number)
{
CompileCode.write(reinterpret_cast<char *>(&op_code), sizeof(op_code));
CompileCode.write(reinterpret_cast<char *>(&arg1), sizeof(arg1));
CompileCode.write(reinterpret_cast<char *>(&arg2), sizeof(arg2));
CompileCode.write(reinterpret_cast<char *>(&arg4), sizeof(arg4));
CompileCode.write(reinterpret_cast<char *>(&add_input_arguments), sizeof(add_input_arguments));
CompileCode.write(reinterpret_cast<char *>(&row), sizeof(row));
CompileCode.write(reinterpret_cast<char *>(&col), sizeof(col));
CompileCode.write(reinterpret_cast<char *>(&function_type), sizeof(function_type));
size_t size = func_name.size();
CompileCode.write(reinterpret_cast<char *>(&size), sizeof(int));
const char *name = func_name.c_str();
CompileCode.write(reinterpret_cast<const char *>(name), func_name.size());
size = arg_func_name.size();
CompileCode.write(reinterpret_cast<char *>(&size), sizeof(int));
name = arg_func_name.c_str();
CompileCode.write(reinterpret_cast<const char *>(name), arg_func_name.size());
instruction_number++;
};
#ifdef BYTE_CODE
inline uint8_t *
load(uint8_t *code)
{
op_code = FCALL; code += sizeof(op_code);
memcpy(&arg1, code, sizeof(arg1)); code += sizeof(arg1);
memcpy(&arg2, code, sizeof(arg2)); code += sizeof(arg2);
memcpy(&arg4, code, sizeof(arg4)); code += sizeof(arg4);
memcpy(&add_input_arguments, code, sizeof(add_input_arguments)); code += sizeof(add_input_arguments);
memcpy(&row, code, sizeof(row)); code += sizeof(row);
memcpy(&col, code, sizeof(col)); code += sizeof(col);
memcpy(&function_type, code, sizeof(function_type)); code += sizeof(function_type);
int size;
memcpy(&size, code, sizeof(size)); code += sizeof(size);
char *name = (char *) mxMalloc((size+1)*sizeof(char));
memcpy(name, code, size); code += size;
name[size] = 0;
func_name = name;
mxFree(name);
memcpy(&size, code, sizeof(size)); code += sizeof(size);
name = (char *) mxMalloc((size+1)*sizeof(char));
memcpy(name, code, size); code += size;
name[size] = 0;
arg_func_name = name;
mxFree(name);
return code;
}
#endif
};
class FNUMEXPR_ : public TagWithOneArgument<ExpressionType>
{
private:
unsigned int equation;
uint16_t dvariable1, dvariable2, dvariable3;
int8_t lag1, lag2, lag3;
public:
inline
FNUMEXPR_() : TagWithOneArgument<ExpressionType>::TagWithOneArgument(FNUMEXPR)
{
};
inline
FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg) : TagWithOneArgument<ExpressionType>::TagWithOneArgument(FNUMEXPR, expression_type),
dvariable1(0), dvariable2(0), dvariable3(0), lag1(0), lag2(0), lag3(0)
{
equation = equation_arg;
};
inline
FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg, unsigned int dvariable1_arg) : TagWithOneArgument<ExpressionType>::TagWithOneArgument(FNUMEXPR, expression_type),
dvariable2(0), dvariable3(0), lag1(0), lag2(0), lag3(0)
{
equation = equation_arg;
dvariable1 = dvariable1_arg;
};
inline
FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg, unsigned int dvariable1_arg, int lag1_arg) : TagWithOneArgument<ExpressionType>::TagWithOneArgument(FNUMEXPR, expression_type),
dvariable2(0), dvariable3(0), lag2(0), lag3(0)
{
equation = equation_arg;
dvariable1 = dvariable1_arg;
lag1 = lag1_arg;
};
inline
FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg, unsigned int dvariable1_arg, unsigned int dvariable2_arg) : TagWithOneArgument<ExpressionType>::TagWithOneArgument(FNUMEXPR, expression_type),
dvariable3(0), lag1(0), lag2(0), lag3(0)
{
equation = equation_arg;
dvariable1 = dvariable1_arg;
dvariable2 = dvariable2_arg;
};
inline
FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg, unsigned int dvariable1_arg, int lag1_arg, unsigned int dvariable2_arg, int lag2_arg) : TagWithOneArgument<ExpressionType>::TagWithOneArgument(FNUMEXPR, expression_type),
dvariable3(0), lag3(0)
{
equation = equation_arg;
dvariable1 = dvariable1_arg;
lag1 = lag1_arg;
dvariable2 = dvariable2_arg;
lag2 = lag2_arg;
};
inline
FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg, unsigned int dvariable1_arg, unsigned int dvariable2_arg, unsigned int dvariable3_arg) : TagWithOneArgument<ExpressionType>::TagWithOneArgument(FNUMEXPR, expression_type),
lag1(0), lag2(0), lag3(0)
{
equation = equation_arg;
dvariable1 = dvariable1_arg;
dvariable2 = dvariable2_arg;
dvariable3 = dvariable3_arg;
};
inline
FNUMEXPR_(const ExpressionType expression_type, unsigned int equation_arg, unsigned int dvariable1_arg, int lag1_arg, unsigned int dvariable2_arg, int lag2_arg, unsigned int dvariable3_arg, int lag3_arg) : TagWithOneArgument<ExpressionType>::TagWithOneArgument(FNUMEXPR, expression_type)
{
equation = equation_arg;
dvariable1 = dvariable1_arg;
lag1 = lag1_arg;
dvariable2 = dvariable2_arg;
lag2 = lag2_arg;
dvariable3 = dvariable3_arg;
lag3 = lag3_arg;
};
inline ExpressionType
get_expression_type()
{
return arg1;
}
inline unsigned int
get_equation()
{
return equation;
};
inline unsigned int
get_dvariable1()
{
return dvariable1;
};
inline int
get_lag1()
{
return lag1;
};
inline unsigned int
get_dvariable2()
{
return dvariable2;
};
inline int
get_lag2()
{
return lag2;
};
inline unsigned int
get_dvariable3()
{
return dvariable3;
};
inline int
get_lag3()
{
return lag3;
};
inline void
write(ostream &CompileCode, unsigned int &instruction_number)
{
CompileCode.write(reinterpret_cast<char *>(this), sizeof(FNUMEXPR_));
instruction_number++;
};
};
class FBEGINBLOCK_
{
private:
uint8_t op_code;
int size;
uint8_t type;
vector<int> variable;
vector<int> equation;
vector<unsigned int> other_endogenous;
vector<unsigned int> exogenous;
vector<unsigned int> det_exogenous;
bool is_linear;
vector<Block_contain_type> Block_Contain_;
int endo_nbr;
int Max_Lag;
int Max_Lead;
int u_count_int;
int nb_col_jacob;
unsigned int det_exo_size, exo_size, other_endo_size;
unsigned int nb_col_det_exo_jacob, nb_col_exo_jacob, nb_col_other_endo_jacob;
public:
inline
FBEGINBLOCK_()
{
op_code = FBEGINBLOCK; size = 0; type = UNKNOWN; /*variable = NULL; equation = NULL;*/
is_linear = false; endo_nbr = 0; Max_Lag = 0; Max_Lead = 0; u_count_int = 0; nb_col_jacob = 0;
};
inline
FBEGINBLOCK_(unsigned int size_arg, BlockSimulationType type_arg, int unsigned first_element, int unsigned block_size,
const vector<int> &variable_arg, const vector<int> &equation_arg,
bool is_linear_arg, int endo_nbr_arg, int Max_Lag_arg, int Max_Lead_arg, int &u_count_int_arg, int nb_col_jacob_arg,
unsigned int det_exo_size_arg, unsigned int nb_col_det_exo_jacob_arg, unsigned int exo_size_arg, unsigned int nb_col_exo_jacob_arg, unsigned int other_endo_size_arg, unsigned int nb_col_other_endo_jacob_arg,
const vector<unsigned int> &det_exogenous_arg, const vector<unsigned int> &exogenous_arg, const vector<unsigned int> &other_endogenous_arg)
{
op_code = FBEGINBLOCK; size = size_arg; type = type_arg;
variable = vector<int>(variable_arg.begin()+first_element, variable_arg.begin()+(first_element+block_size));
equation = vector<int>(equation_arg.begin()+first_element, equation_arg.begin()+(first_element+block_size));
det_exogenous = vector<unsigned int>(det_exogenous_arg);
exogenous = vector<unsigned int>(exogenous_arg);
other_endogenous = vector<unsigned int>(other_endogenous_arg);
is_linear = is_linear_arg; endo_nbr = endo_nbr_arg; Max_Lag = Max_Lag_arg; Max_Lead = Max_Lead_arg; u_count_int = u_count_int_arg;
nb_col_jacob = nb_col_jacob_arg;
det_exo_size = det_exo_size_arg; nb_col_det_exo_jacob = nb_col_det_exo_jacob_arg;
exo_size = exo_size_arg; nb_col_exo_jacob = nb_col_exo_jacob_arg;
other_endo_size = other_endo_size_arg; nb_col_other_endo_jacob = nb_col_other_endo_jacob_arg;
};
inline
FBEGINBLOCK_(unsigned int size_arg, BlockSimulationType type_arg, int unsigned first_element, int unsigned block_size,
const vector<int> &variable_arg, const vector<int> &equation_arg,
bool is_linear_arg, int endo_nbr_arg, int Max_Lag_arg, int Max_Lead_arg, int &u_count_int_arg, int nb_col_jacob_arg)
{
op_code = FBEGINBLOCK; size = size_arg; type = type_arg;
variable = vector<int>(variable_arg.begin()+first_element, variable_arg.begin()+(first_element+block_size));
equation = vector<int>(equation_arg.begin()+first_element, equation_arg.begin()+(first_element+block_size));
is_linear = is_linear_arg; endo_nbr = endo_nbr_arg; Max_Lag = Max_Lag_arg; Max_Lead = Max_Lead_arg; u_count_int = u_count_int_arg;
nb_col_jacob = nb_col_jacob_arg;
det_exo_size = 0; exo_size = 0; other_endo_size = 0;
nb_col_det_exo_jacob = 0; nb_col_exo_jacob = 0; nb_col_other_endo_jacob = 0;
}
inline unsigned int
get_size()
{
return size;
};
inline uint8_t
get_type()
{
return type;
};
inline bool
get_is_linear()
{
return is_linear;
};
inline int
get_endo_nbr()
{
return endo_nbr;
};
inline int
get_Max_Lag()
{
return Max_Lag;
};
inline int
get_Max_Lead()
{
return Max_Lead;
};
inline int
get_u_count_int()
{
return u_count_int;
};
inline vector<Block_contain_type>
get_Block_Contain()
{
return Block_Contain_;
};
inline int
get_nb_col_jacob()
{
return nb_col_jacob;
};
inline unsigned int
get_exo_size()
{
return exo_size;
};
inline unsigned int
get_nb_col_exo_jacob()
{
return nb_col_exo_jacob;
};
inline unsigned int
get_det_exo_size()
{
return det_exo_size;
};
inline unsigned int
get_nb_col_det_exo_jacob()
{
return nb_col_det_exo_jacob;
};
inline unsigned int
get_other_endo_size()
{
return other_endo_size;
};
inline unsigned int
get_nb_col_other_endo_jacob()
{
return nb_col_other_endo_jacob;
};
inline vector<int>
get_endogenous()
{
return variable;
}
inline vector<unsigned int>
get_exogenous()
{
return exogenous;
}
inline void
write(ostream &CompileCode, unsigned int &instruction_number)
{
CompileCode.write(reinterpret_cast<char *>(&op_code), sizeof(op_code));
CompileCode.write(reinterpret_cast<char *>(&size), sizeof(size));
CompileCode.write(reinterpret_cast<char *>(&type), sizeof(type));
for (int i = 0; i < size; i++)
{
CompileCode.write(reinterpret_cast<char *>(&variable[i]), sizeof(variable[0]));
CompileCode.write(reinterpret_cast<char *>(&equation[i]), sizeof(equation[0]));
}
if (type == SOLVE_TWO_BOUNDARIES_SIMPLE || type == SOLVE_TWO_BOUNDARIES_COMPLETE
|| type == SOLVE_BACKWARD_COMPLETE || type == SOLVE_FORWARD_COMPLETE)
{
CompileCode.write(reinterpret_cast<char *>(&is_linear), sizeof(is_linear));
CompileCode.write(reinterpret_cast<char *>(&endo_nbr), sizeof(endo_nbr));
CompileCode.write(reinterpret_cast<char *>(&Max_Lag), sizeof(Max_Lag));
CompileCode.write(reinterpret_cast<char *>(&Max_Lead), sizeof(Max_Lead));
CompileCode.write(reinterpret_cast<char *>(&u_count_int), sizeof(u_count_int));
}
CompileCode.write(reinterpret_cast<char *>(&nb_col_jacob), sizeof(nb_col_jacob));
CompileCode.write(reinterpret_cast<char *>(&det_exo_size), sizeof(det_exo_size));
CompileCode.write(reinterpret_cast<char *>(&nb_col_det_exo_jacob), sizeof(nb_col_det_exo_jacob));
CompileCode.write(reinterpret_cast<char *>(&exo_size), sizeof(exo_size));
CompileCode.write(reinterpret_cast<char *>(&nb_col_exo_jacob), sizeof(nb_col_exo_jacob));
CompileCode.write(reinterpret_cast<char *>(&other_endo_size), sizeof(other_endo_size));
CompileCode.write(reinterpret_cast<char *>(&nb_col_other_endo_jacob), sizeof(nb_col_other_endo_jacob));
for (unsigned int i = 0; i < det_exo_size; i++)
CompileCode.write(reinterpret_cast<char *>(&det_exogenous[i]), sizeof(det_exogenous[0]));
for (unsigned int i = 0; i < exo_size; i++)
CompileCode.write(reinterpret_cast<char *>(&exogenous[i]), sizeof(exogenous[0]));
for (unsigned int i = 0; i < other_endo_size; i++)
CompileCode.write(reinterpret_cast<char *>(&other_endogenous[i]), sizeof(other_endogenous[0]));
instruction_number++;
};
#ifdef BYTE_CODE
inline uint8_t *
load(uint8_t *code)
{
op_code = FBEGINBLOCK; code += sizeof(op_code);
memcpy(&size, code, sizeof(size)); code += sizeof(size);
memcpy(&type, code, sizeof(type)); code += sizeof(type);
for (int i = 0; i < size; i++)
{
Block_contain_type bc;
memcpy(&bc.Variable, code, sizeof(bc.Variable)); code += sizeof(bc.Variable);
memcpy(&bc.Equation, code, sizeof(bc.Equation)); code += sizeof(bc.Equation);
Block_Contain_.push_back(bc);
}
if (type == SOLVE_TWO_BOUNDARIES_SIMPLE || type == SOLVE_TWO_BOUNDARIES_COMPLETE
|| type == SOLVE_BACKWARD_COMPLETE || type == SOLVE_FORWARD_COMPLETE)
{
memcpy(&is_linear, code, sizeof(is_linear)); code += sizeof(is_linear);
memcpy(&endo_nbr, code, sizeof(endo_nbr)); code += sizeof(endo_nbr);
memcpy(&Max_Lag, code, sizeof(Max_Lag)); code += sizeof(Max_Lag);
memcpy(&Max_Lead, code, sizeof(Max_Lead)); code += sizeof(Max_Lead);
memcpy(&u_count_int, code, sizeof(u_count_int)); code += sizeof(u_count_int);
}
memcpy(&nb_col_jacob, code, sizeof(nb_col_jacob)); code += sizeof(nb_col_jacob);
memcpy(&det_exo_size, code, sizeof(det_exo_size)); code += sizeof(det_exo_size);
memcpy(&nb_col_det_exo_jacob, code, sizeof(nb_col_det_exo_jacob)); code += sizeof(nb_col_det_exo_jacob);
memcpy(&exo_size, code, sizeof(exo_size)); code += sizeof(exo_size);
memcpy(&nb_col_exo_jacob, code, sizeof(nb_col_exo_jacob)); code += sizeof(nb_col_exo_jacob);
memcpy(&other_endo_size, code, sizeof(other_endo_size)); code += sizeof(other_endo_size);
memcpy(&nb_col_other_endo_jacob, code, sizeof(nb_col_other_endo_jacob)); code += sizeof(nb_col_other_endo_jacob);
for (unsigned int i = 0; i < det_exo_size; i++)
{
unsigned int tmp_i;
memcpy(&tmp_i, code, sizeof(tmp_i)); code += sizeof(tmp_i);
det_exogenous.push_back(tmp_i);
}
for (unsigned int i = 0; i < exo_size; i++)
{
unsigned int tmp_i;
memcpy(&tmp_i, code, sizeof(tmp_i)); code += sizeof(tmp_i);
exogenous.push_back(tmp_i);
}
for (unsigned int i = 0; i < other_endo_size; i++)
{
unsigned int tmp_i;
memcpy(&tmp_i, code, sizeof(tmp_i)); code += sizeof(tmp_i);
other_endogenous.push_back(tmp_i);
}
return code;
};
#endif
};
#ifdef BYTE_CODE
typedef vector<pair<Tags, void * > > tags_liste_t;
class CodeLoad
{
private:
uint8_t *code;
unsigned int nb_blocks;
vector<size_t> begin_block;
public:
inline unsigned int
get_block_number()
{
return nb_blocks;
};
size_t inline
get_begin_block(int block)
{
return begin_block[block];
}
inline void *
get_current_code()
{
return code;
};
inline tags_liste_t
get_op_code(string file_name)
{
tags_liste_t tags_liste;
ifstream CompiledCode;
streamoff Code_Size;
CompiledCode.open((file_name + ".cod").c_str(), std::ios::in | std::ios::binary| std::ios::ate);
if (!CompiledCode.is_open())
{
return tags_liste;
}
Code_Size = CompiledCode.tellg();
CompiledCode.seekg(std::ios::beg);
code = (uint8_t *) mxMalloc(Code_Size);
CompiledCode.seekg(0);
CompiledCode.read(reinterpret_cast<char *>(code), Code_Size);
CompiledCode.close();
nb_blocks = 0;
bool done = false;
int instruction = 0;
while (!done)
{
switch (*code)
{
case FLDZ:
# ifdef DEBUGL
mexPrintf("FLDZ = %d size = %d\n", FLDZ, sizeof(FLDZ_));
# endif
tags_liste.push_back(make_pair(FLDZ, code));
code += sizeof(FLDZ_);
break;
case FEND:
# ifdef DEBUGL
mexPrintf("FEND\n");
# endif
tags_liste.push_back(make_pair(FEND, code));
code += sizeof(FEND_);
done = true;
break;
case FENDBLOCK:
# ifdef DEBUGL
mexPrintf("FENDBLOCK\n");
# endif
tags_liste.push_back(make_pair(FENDBLOCK, code));
code += sizeof(FENDBLOCK_);
break;
case FENDEQU:
# ifdef DEBUGL
mexPrintf("FENDEQU\n");
# endif
tags_liste.push_back(make_pair(FENDEQU, code));
code += sizeof(FENDEQU_);
break;
case FCUML:
# ifdef DEBUGL
mexPrintf("FCUML\n");
# endif
tags_liste.push_back(make_pair(FCUML, code));
code += sizeof(FCUML_);
break;
case FDIMT:
# ifdef DEBUGL
mexPrintf("FDIMT = %d size = %d\n", FDIMT, sizeof(FDIMT_));
# endif
tags_liste.push_back(make_pair(FDIMT, code));
code += sizeof(FDIMT_);
break;
case FDIMST:
# ifdef DEBUGL
mexPrintf("FDIMST\n");
# endif
tags_liste.push_back(make_pair(FDIMST, code));
code += sizeof(FDIMST_);
break;
case FNUMEXPR:
# ifdef DEBUGL
mexPrintf("FNUMEXPR\n");
# endif
tags_liste.push_back(make_pair(FNUMEXPR, code));
code += sizeof(FNUMEXPR_);
break;
case FLDC:
# ifdef DEBUGL
mexPrintf("FLDC\n");
# endif
tags_liste.push_back(make_pair(FLDC, code));
code += sizeof(FLDC_);
break;
case FLDU:
# ifdef DEBUGL
mexPrintf("FLDU\n");
# endif
tags_liste.push_back(make_pair(FLDU, code));
code += sizeof(FLDU_);
break;
case FLDSU:
# ifdef DEBUGL
mexPrintf("FLDSU\n");
# endif
tags_liste.push_back(make_pair(FLDSU, code));
code += sizeof(FLDSU_);
break;
case FLDR:
# ifdef DEBUGL
mexPrintf("FLDR\n");
# endif
tags_liste.push_back(make_pair(FLDR, code));
code += sizeof(FLDR_);
break;
case FLDT:
# ifdef DEBUGL
mexPrintf("FLDT\n");
# endif
tags_liste.push_back(make_pair(FLDT, code));
code += sizeof(FLDT_);
break;
case FLDST:
# ifdef DEBUGL
mexPrintf("FLDST\n");
# endif
tags_liste.push_back(make_pair(FLDST, code));
code += sizeof(FLDST_);
break;
case FSTPT:
# ifdef DEBUGL
mexPrintf("FSTPT = %d size = %d\n", FSTPT, sizeof(FSTPT_));
# endif
tags_liste.push_back(make_pair(FSTPT, code));
code += sizeof(FSTPT_);
break;
case FSTPST:
# ifdef DEBUGL
mexPrintf("FSTPST\n");
# endif
tags_liste.push_back(make_pair(FSTPST, code));
code += sizeof(FSTPST_);
break;
case FSTPR:
# ifdef DEBUGL
mexPrintf("FSTPR\n");
# endif
tags_liste.push_back(make_pair(FSTPR, code));
code += sizeof(FSTPR_);
break;
case FSTPU:
# ifdef DEBUGL
mexPrintf("FSTPU\n");
# endif
tags_liste.push_back(make_pair(FSTPU, code));
code += sizeof(FSTPU_);
break;
case FSTPSU:
# ifdef DEBUGL
mexPrintf("FSTPSU\n");
# endif
tags_liste.push_back(make_pair(FSTPSU, code));
code += sizeof(FSTPSU_);
break;
case FSTPG:
# ifdef DEBUGL
mexPrintf("FSTPG\n");
# endif
tags_liste.push_back(make_pair(FSTPG, code));
code += sizeof(FSTPG_);
break;
case FSTPG2:
# ifdef DEBUGL
mexPrintf("FSTPG2\n");
# endif
tags_liste.push_back(make_pair(FSTPG2, code));
code += sizeof(FSTPG2_);
break;
case FSTPG3:
# ifdef DEBUGL
mexPrintf("FSTPG3\n");
# endif
tags_liste.push_back(make_pair(FSTPG3, code));
code += sizeof(FSTPG3_);
break;
case FUNARY:
# ifdef DEBUGL
mexPrintf("FUNARY\n");
# endif
tags_liste.push_back(make_pair(FUNARY, code));
code += sizeof(FUNARY_);
break;
case FBINARY:
# ifdef DEBUGL
mexPrintf("FBINARY\n");
# endif
tags_liste.push_back(make_pair(FBINARY, code));
code += sizeof(FBINARY_);
break;
case FTRINARY:
# ifdef DEBUGL
mexPrintf("FTRINARY\n");
# endif
tags_liste.push_back(make_pair(FTRINARY, code));
code += sizeof(FTRINARY_);
break;
case FOK:
# ifdef DEBUGL
mexPrintf("FOK\n");
# endif
tags_liste.push_back(make_pair(FOK, code));
code += sizeof(FOK_);
break;
case FLDVS:
# ifdef DEBUGL
mexPrintf("FLDVS\n");
# endif
tags_liste.push_back(make_pair(FLDVS, code));
code += sizeof(FLDVS_);
break;
case FLDSV:
# ifdef DEBUGL
mexPrintf("FLDSV\n");
# endif
tags_liste.push_back(make_pair(FLDSV, code));
code += sizeof(FLDSV_);
break;
case FSTPSV:
# ifdef DEBUGL
mexPrintf("FSTPSV\n");
# endif
tags_liste.push_back(make_pair(FSTPSV, code));
code += sizeof(FSTPSV_);
break;
case FLDV:
# ifdef DEBUGL
mexPrintf("FLDV\n");
# endif
tags_liste.push_back(make_pair(FLDV, code));
code += sizeof(FLDV_);
break;
case FSTPV:
# ifdef DEBUGL
mexPrintf("FSTPV\n");
# endif
tags_liste.push_back(make_pair(FSTPV, code));
code += sizeof(FSTPV_);
break;
case FBEGINBLOCK:
# ifdef DEBUGL
mexPrintf("FBEGINBLOCK\n");
# endif
{
FBEGINBLOCK_ *fbegin_block = new FBEGINBLOCK_;
code = fbegin_block->load(code);
begin_block.push_back(tags_liste.size());
tags_liste.push_back(make_pair(FBEGINBLOCK, fbegin_block));
nb_blocks++;
}
break;
case FJMPIFEVAL:
# ifdef DEBUGL
mexPrintf("FJMPIFEVAL\n");
# endif
tags_liste.push_back(make_pair(FJMPIFEVAL, code));
code += sizeof(FJMPIFEVAL_);
break;
case FJMP:
# ifdef DEBUGL
mexPrintf("FJMP\n");
# endif
tags_liste.push_back(make_pair(FJMP, code));
code += sizeof(FJMP_);
break;
case FCALL:
{
# ifdef DEBUGL
mexPrintf("FCALL\n");
# endif
FCALL_ *fcall = new FCALL_;
code = fcall->load(code);
tags_liste.push_back(make_pair(FCALL, fcall));
# ifdef DEBUGL
mexPrintf("FCALL finish\n"); mexEvalString("drawnow;");
mexPrintf("-- *code=%d\n", *code); mexEvalString("drawnow;");
# endif
}
break;
case FPUSH:
# ifdef DEBUGL
mexPrintf("FPUSH\n");
# endif
tags_liste.push_back(make_pair(FPUSH, code));
code += sizeof(FPUSH_);
break;
case FPOP:
# ifdef DEBUGL
mexPrintf("FPOP\n");
# endif
tags_liste.push_back(make_pair(FPOP, code));
code += sizeof(FPOP_);
break;
case FLDTEF:
# ifdef DEBUGL
mexPrintf("FLDTEF\n");
# endif
tags_liste.push_back(make_pair(FLDTEF, code));
code += sizeof(FLDTEF_);
break;
case FSTPTEF:
# ifdef DEBUGL
mexPrintf("FSTPTEF\n");
# endif
tags_liste.push_back(make_pair(FSTPTEF, code));
code += sizeof(FSTPTEF_);
break;
case FLDTEFD:
# ifdef DEBUGL
mexPrintf("FLDTEFD\n");
# endif
tags_liste.push_back(make_pair(FLDTEFD, code));
code += sizeof(FLDTEFD_);
break;
case FSTPTEFD:
# ifdef DEBUGL
mexPrintf("FSTPTEFD\n");
# endif
tags_liste.push_back(make_pair(FSTPTEFD, code));
code += sizeof(FSTPTEFD_);
break;
case FLDTEFDD:
# ifdef DEBUGL
mexPrintf("FLDTEFDD\n");
# endif
tags_liste.push_back(make_pair(FLDTEFDD, code));
code += sizeof(FLDTEFDD_);
break;
case FSTPTEFDD:
# ifdef DEBUGL
mexPrintf("FSTPTEFDD\n");
# endif
tags_liste.push_back(make_pair(FSTPTEFDD, code));
code += sizeof(FSTPTEFDD_);
break;
default:
mexPrintf("Unknown Tag value=%d code=%x\n", *code, code);
done = true;
}
instruction++;
}
return tags_liste;
};
};
#endif
#pragma pack(pop)
#endif
/*
* Copyright © 2007-2024 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef COMMON_ENUMS_HH
#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 */
enum class SymbolType
{
endogenous = 0, // Endogenous (non-heterogeneous)
exogenous = 1, // Exogenous (non-heterogeneous)
exogenousDet = 2, // Exogenous deterministic (non-heterogeneous)
parameter = 4, // Parameter (non-heterogeneous)
heterogeneousEndogenous = 5, // Endogenous that is heterogeneous across some dimension
heterogeneousExogenous = 6, // Exogenous that is heterogeneous across some dimension
heterogeneousParameter = 7, // Parameter that is heterogeneous across some dimension
modelLocalVariable = 10, // Local variable whose scope is model (pound expression)
modFileLocalVariable = 11, // Local variable whose scope is mod file (model excluded)
externalFunction = 12, // External (user-defined) function
trend = 13, // Trend variable
statementDeclaredVariable
= 14, //!< Local variable assigned within a Statement (see subsample statement for example)
logTrend = 15, //!< Log-trend variable
unusedEndogenous
= 16, //!< Type to mark unused endogenous variables when `nostrict` option is passed
// Value 17 is unused for the time being (but could be reused)
epilogue = 18, //!< Variables created in epilogue block
excludedVariable = 19 //!< Variable excluded via model_remove/var_remove/include_eqs/exclude_eqs
};
constexpr bool
isHeterogeneous(SymbolType type)
{
return type == SymbolType::heterogeneousEndogenous || type == SymbolType::heterogeneousExogenous
|| type == SymbolType::heterogeneousParameter;
}
enum class UnaryOpcode
{
uminus,
exp,
log,
log10,
cos,
sin,
tan,
acos,
asin,
atan,
cosh,
sinh,
tanh,
acosh,
asinh,
atanh,
sqrt,
cbrt,
abs,
sign,
steadyState,
steadyStateParamDeriv, // for the derivative of the STEADY_STATE operator w.r.t. to a parameter
steadyStateParam2ndDeriv, // for the 2nd derivative of the STEADY_STATE operator w.r.t. to a
// parameter
expectation,
erf,
erfc,
diff,
adl,
sum
};
enum class BinaryOpcode
{
plus,
minus,
times,
divide,
power,
powerDeriv, // for the derivative of the power function (see trac ticket #78)
equal,
max,
min,
less,
greater,
lessEqual,
greaterEqual,
equalEqual,
different
};
// Small number value used when evaluating powerDeriv opcodes.
// Put here instead of inside BinaryOpNode class, because needed by bytecode MEX.
constexpr double power_deriv_near_zero {1e-12};
enum class TrinaryOpcode
{
normcdf,
normpdf
};
enum class PriorDistributions
{
noShape = 0,
beta = 1,
gamma = 2,
normal = 3,
invGamma = 4,
invGamma1 = 4,
uniform = 5,
invGamma2 = 6,
dirichlet = 7,
weibull = 8
};
enum class EquationType
{
evaluate, //!< Simple evaluation, normalized variable on left-hand side (written as such by the
//!< user)
evaluateRenormalized, //!< Simple evaluation, normalized variable on left-hand side (normalization
//!< computed by the preprocessor)
solve //!< No simple evaluation of the equation, it has to be solved
};
enum class BlockSimulationType
{
evaluateForward = 1, //!< Simple evaluation, normalized variable on left-hand side, forward
evaluateBackward, //!< Simple evaluation, normalized variable on left-hand side, backward
solveForwardSimple, //!< Block of one equation, newton solver needed, forward
solveBackwardSimple, //!< Block of one equation, newton solver needed, backward
solveTwoBoundariesSimple, //!< Block of one equation, Newton solver needed, forward and backward
solveForwardComplete, //!< Block of several equations, Newton solver needed, forward
solveBackwardComplete, //!< Block of several equations, Newton solver needed, backward
solveTwoBoundariesComplete //!< Block of several equations, Newton solver needed, forward and
//!< backwar
};
enum class PacTargetKind
{
unspecified, // Must be the first one, because it’s the default initializer
ll,
dl,
dd
};
#endif
Source diff could not be displayed: it is too large. Options to address this: view the blob.
/* /*
* Copyright (C) 2003-2017 Dynare Team * Copyright © 2003-2024 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -14,73 +14,103 @@ ...@@ -14,73 +14,103 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>. * along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef _COMPUTINGTASKS_HH #ifndef COMPUTING_TASKS_HH
#define _COMPUTINGTASKS_HH #define COMPUTING_TASKS_HH
#include <memory>
#include <optional>
#include <ostream> #include <ostream>
#include "SymbolList.hh" #include "DynamicModel.hh"
#include "SymbolTable.hh" #include "ModelEquationBlock.hh"
#include "Statement.hh" #include "Statement.hh"
#include "StaticModel.hh" #include "StaticModel.hh"
#include "DynamicModel.hh" #include "SymbolList.hh"
#include "SteadyStateModel.hh" #include "SymbolTable.hh"
class SteadyStatement : public Statement class SteadyStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
SteadyStatement(const OptionsList &options_list_arg); explicit SteadyStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class CheckStatement : public Statement class CheckStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
CheckStatement(const OptionsList &options_list_arg); explicit CheckStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class SimulStatement : public Statement class SimulStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
SimulStatement(const OptionsList &options_list_arg); explicit SimulStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class PerfectForesightSetupStatement : public Statement class PerfectForesightSetupStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
PerfectForesightSetupStatement(const OptionsList &options_list_arg); explicit PerfectForesightSetupStatement(OptionsList options_list_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class PerfectForesightSolverStatement : public Statement class PerfectForesightSolverStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public:
explicit PerfectForesightSolverStatement(OptionsList options_list_arg);
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
};
class PerfectForesightWithExpectationErrorsSetupStatement : public Statement
{
private:
const OptionsList options_list;
public: public:
PerfectForesightSolverStatement(const OptionsList &options_list_arg); explicit PerfectForesightWithExpectationErrorsSetupStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeJsonOutput(ostream& output) const override;
virtual void writeJsonOutput(ostream &output) const; };
class PerfectForesightWithExpectationErrorsSolverStatement : public Statement
{
private:
const OptionsList options_list;
public:
explicit PerfectForesightWithExpectationErrorsSolverStatement(OptionsList options_list_arg);
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class PriorPosteriorFunctionStatement : public Statement class PriorPosteriorFunctionStatement : public Statement
...@@ -88,22 +118,23 @@ class PriorPosteriorFunctionStatement : public Statement ...@@ -88,22 +118,23 @@ class PriorPosteriorFunctionStatement : public Statement
private: private:
const bool prior_func; const bool prior_func;
const OptionsList options_list; const OptionsList options_list;
public: public:
PriorPosteriorFunctionStatement(const bool prior_func_arg, const OptionsList &options_list_arg); PriorPosteriorFunctionStatement(const bool prior_func_arg, OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class ModelInfoStatement : public Statement class ModelInfoStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
ModelInfoStatement(const OptionsList &options_list_arg); explicit ModelInfoStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeJsonOutput(ostream& output) const override;
virtual void writeJsonOutput(ostream &output) const;
}; };
class StochSimulStatement : public Statement class StochSimulStatement : public Statement
...@@ -111,12 +142,14 @@ class StochSimulStatement : public Statement ...@@ -111,12 +142,14 @@ class StochSimulStatement : public Statement
private: private:
const SymbolList symbol_list; const SymbolList symbol_list;
const OptionsList options_list; const OptionsList options_list;
const SymbolTable& symbol_table;
public: public:
StochSimulStatement(const SymbolList &symbol_list_arg, StochSimulStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
const OptionsList &options_list_arg); const SymbolTable& symbol_table_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class ForecastStatement : public Statement class ForecastStatement : public Statement
...@@ -124,148 +157,219 @@ class ForecastStatement : public Statement ...@@ -124,148 +157,219 @@ class ForecastStatement : public Statement
private: private:
const SymbolList symbol_list; const SymbolList symbol_list;
const OptionsList options_list; const OptionsList options_list;
const SymbolTable& symbol_table;
public: public:
ForecastStatement(const SymbolList &symbol_list_arg, ForecastStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
const OptionsList &options_list_arg); const SymbolTable& symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeJsonOutput(ostream &output) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class RamseyModelStatement : public Statement class RamseyModelStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
RamseyModelStatement(const OptionsList &options_list_arg); explicit RamseyModelStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class RamseyConstraintsStatement : public Statement class RamseyPolicyStatement : public Statement
{ {
private:
const SymbolList symbol_list;
const OptionsList options_list;
const SymbolTable& symbol_table;
public: public:
struct Constraint RamseyPolicyStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
const SymbolTable& symbol_table_arg);
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
};
class EvaluatePlannerObjectiveStatement : public Statement
{ {
int endo; private:
BinaryOpcode code; const OptionsList options_list;
expr_t expression;
public:
explicit EvaluatePlannerObjectiveStatement(OptionsList options_list_arg);
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
typedef vector<Constraint> constraints_t;
class OccbinSetupStatement : public Statement
{
private: private:
const SymbolTable &symbol_table; const OptionsList options_list;
const constraints_t constraints;
public: public:
RamseyConstraintsStatement(const SymbolTable &symbol_table_arg, const constraints_t &constraints_arg); explicit OccbinSetupStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeJsonOutput(ostream& output) const override;
virtual void writeJsonOutput(ostream &output) const;
}; };
class RamseyPolicyStatement : public Statement class OccbinSolverStatement : public Statement
{ {
private: private:
const SymbolTable &symbol_table;
const vector<string> ramsey_policy_list;
const OptionsList options_list; const OptionsList options_list;
public: public:
RamseyPolicyStatement(const SymbolTable &symbol_table_arg, explicit OccbinSolverStatement(OptionsList options_list_arg);
const vector<string> &ramsey_policy_list_arg, void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
const OptionsList &options_list_arg); void writeJsonOutput(ostream& output) const override;
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
void checkRamseyPolicyList();
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
virtual void writeJsonOutput(ostream &output) const;
}; };
class DiscretionaryPolicyStatement : public Statement class OccbinWriteRegimesStatement : public Statement
{ {
private: private:
const SymbolList symbol_list;
const OptionsList options_list; const OptionsList options_list;
public: public:
DiscretionaryPolicyStatement(const SymbolList &symbol_list_arg, explicit OccbinWriteRegimesStatement(OptionsList options_list_arg);
const OptionsList &options_list_arg); void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void writeJsonOutput(ostream& output) const override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
virtual void writeJsonOutput(ostream &output) const;
}; };
class RplotStatement : public Statement class OccbinGraphStatement : public Statement
{ {
private: private:
const SymbolList symbol_list; const SymbolList symbol_list;
const OptionsList options_list;
public: public:
RplotStatement(const SymbolList &symbol_list_arg); OccbinGraphStatement(SymbolList symbol_list_arg, OptionsList options_list_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class UnitRootVarsStatement : public Statement class DiscretionaryPolicyStatement : public Statement
{ {
private:
const SymbolList symbol_list;
const OptionsList options_list;
const SymbolTable& symbol_table;
public: public:
UnitRootVarsStatement(void); DiscretionaryPolicyStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; const SymbolTable& symbol_table_arg);
virtual void writeJsonOutput(ostream &output) const; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class PeriodsStatement : public Statement class RplotStatement : public Statement
{ {
private: private:
const int periods; 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;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
};
class UnitRootVarsStatement : public Statement
{
public: public:
PeriodsStatement(int periods_arg); void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeJsonOutput(ostream& output) const override;
virtual void writeJsonOutput(ostream &output) const;
}; };
class DsampleStatement : public Statement class DsampleStatement : public Statement
{ {
private: private:
const int val1, val2; const int val1, val2;
public: public:
DsampleStatement(int val1_arg); explicit DsampleStatement(int val1_arg);
DsampleStatement(int val1_arg, int val2_arg); DsampleStatement(int val1_arg, int val2_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class EstimationStatement : public Statement class EstimationStatement : public Statement
{ {
private: private:
const SymbolTable& symbol_table;
const SymbolList symbol_list; const SymbolList symbol_list;
const OptionsList options_list; const OptionsList options_list;
public: public:
EstimationStatement(const SymbolList &symbol_list_arg, EstimationStatement(const SymbolTable& symbol_table_arg, SymbolList symbol_list_arg,
const OptionsList &options_list_arg); OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class DynareSensitivityStatement : public Statement class SensitivityStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
DynareSensitivityStatement(const OptionsList &options_list_arg); explicit SensitivityStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class ObservationTrendsStatement : public Statement class ObservationTrendsStatement : public Statement
{ {
public: public:
typedef map<string, expr_t> trend_elements_t; 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);
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
};
class DeterministicTrendsStatement : public Statement
{
public:
using trend_elements_t = map<string, expr_t>;
private: private:
const trend_elements_t trend_elements; const trend_elements_t trend_elements;
const SymbolTable& symbol_table; const SymbolTable& symbol_table;
public:
DeterministicTrendsStatement(trend_elements_t trend_elements_arg,
const SymbolTable& symbol_table_arg);
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
};
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: public:
ObservationTrendsStatement(const trend_elements_t &trend_elements_arg, FilterInitialStateStatement(filter_initial_state_elements_t filter_initial_state_elements_arg,
const SymbolTable& symbol_table_arg); const SymbolTable& symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class OsrParamsStatement : public Statement class OsrParamsStatement : public Statement
...@@ -273,11 +377,12 @@ class OsrParamsStatement : public Statement ...@@ -273,11 +377,12 @@ class OsrParamsStatement : public Statement
private: private:
const SymbolList symbol_list; const SymbolList symbol_list;
const SymbolTable& symbol_table; const SymbolTable& symbol_table;
public: public:
OsrParamsStatement(const SymbolList &symbol_list_arg, const SymbolTable &symbol_table_arg); OsrParamsStatement(SymbolList symbol_list_arg, const SymbolTable& symbol_table_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class OsrStatement : public Statement class OsrStatement : public Statement
...@@ -285,12 +390,14 @@ class OsrStatement : public Statement ...@@ -285,12 +390,14 @@ class OsrStatement : public Statement
private: private:
const SymbolList symbol_list; const SymbolList symbol_list;
const OptionsList options_list; const OptionsList options_list;
const SymbolTable& symbol_table;
public: public:
OsrStatement(const SymbolList &symbol_list_arg, OsrStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
const OptionsList &options_list_arg); const SymbolTable& symbol_table_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
//! Temporary structure used when parsing estimation_params* statements //! Temporary structure used when parsing estimation_params* statements
...@@ -313,11 +420,12 @@ class OsrParamsBoundsStatement : public Statement ...@@ -313,11 +420,12 @@ class OsrParamsBoundsStatement : public Statement
{ {
private: private:
const vector<OsrParams> osr_params_list; const vector<OsrParams> osr_params_list;
public: public:
OsrParamsBoundsStatement(const vector<OsrParams> &osr_params_list_arg); explicit OsrParamsBoundsStatement(vector<OsrParams> osr_params_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class DynaTypeStatement : public Statement class DynaTypeStatement : public Statement
...@@ -325,11 +433,14 @@ class DynaTypeStatement : public Statement ...@@ -325,11 +433,14 @@ class DynaTypeStatement : public Statement
private: private:
const SymbolList symbol_list; const SymbolList symbol_list;
const string filename; const string filename;
const SymbolTable& symbol_table;
public: public:
DynaTypeStatement(const SymbolList &symbol_list_arg, DynaTypeStatement(SymbolList symbol_list_arg, string filename_arg,
const string &filename_arg); const SymbolTable& symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeJsonOutput(ostream &output) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class DynaSaveStatement : public Statement class DynaSaveStatement : public Statement
...@@ -337,25 +448,29 @@ class DynaSaveStatement : public Statement ...@@ -337,25 +448,29 @@ class DynaSaveStatement : public Statement
private: private:
const SymbolList symbol_list; const SymbolList symbol_list;
const string filename; const string filename;
const SymbolTable& symbol_table;
public: public:
DynaSaveStatement(const SymbolList &symbol_list_arg, DynaSaveStatement(SymbolList symbol_list_arg, string filename_arg,
const string &filename_arg); const SymbolTable& symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeJsonOutput(ostream &output) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class ModelComparisonStatement : public Statement class ModelComparisonStatement : public Statement
{ {
public: public:
typedef vector<pair<string, string> > filename_list_t; using filename_list_t = vector<pair<string, string>>;
private: private:
filename_list_t filename_list; filename_list_t filename_list;
OptionsList options_list; OptionsList options_list;
public: public:
ModelComparisonStatement(const filename_list_t &filename_list_arg, ModelComparisonStatement(filename_list_t filename_list_arg, OptionsList options_list_arg);
const OptionsList &options_list_arg); void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeJsonOutput(ostream& output) const override;
virtual void writeJsonOutput(ostream &output) const;
}; };
//! Temporary structure used when parsing estimation_params* statements //! Temporary structure used when parsing estimation_params* statements
...@@ -373,7 +488,7 @@ public: ...@@ -373,7 +488,7 @@ public:
type = 0; type = 0;
name = ""; name = "";
name2 = ""; name2 = "";
prior = eNoShape; prior = PriorDistributions::noShape;
init_val = datatree.NaN; init_val = datatree.NaN;
low_bound = datatree.MinusInfinity; low_bound = datatree.MinusInfinity;
up_bound = datatree.Infinity; up_bound = datatree.Infinity;
...@@ -385,86 +500,117 @@ public: ...@@ -385,86 +500,117 @@ public:
} }
}; };
class EstimatedParamsStatement : public Statement class AbstractEstimatedParamsStatement : public Statement
{ {
private: protected:
const vector<EstimationParams> estim_params_list; const vector<EstimationParams> estim_params_list;
const SymbolTable& symbol_table; const SymbolTable& symbol_table;
public: AbstractEstimatedParamsStatement(vector<EstimationParams> estim_params_list_arg,
EstimatedParamsStatement(const vector<EstimationParams> &estim_params_list_arg,
const SymbolTable& symbol_table_arg); const SymbolTable& symbol_table_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); [[nodiscard]] virtual string blockName() const = 0;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; // Part of the check pass that is common to the three estimated_params{,_init,bounds} blocks
virtual void writeJsonOutput(ostream &output) const; void commonCheckPass() const;
}; };
class EstimatedParamsInitStatement : public Statement class EstimatedParamsStatement : public AbstractEstimatedParamsStatement
{ {
private: private:
const vector<EstimationParams> estim_params_list; const bool overwrite;
const SymbolTable &symbol_table;
const bool use_calibration;
public: public:
EstimatedParamsInitStatement(const vector<EstimationParams> &estim_params_list_arg, EstimatedParamsStatement(vector<EstimationParams> estim_params_list_arg,
const SymbolTable &symbol_table_arg, const SymbolTable& symbol_table_arg, bool overwrite_arg);
const bool use_calibration_arg); [[nodiscard]] string
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); blockName() const override
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; {
virtual void writeJsonOutput(ostream &output) const; return "estimated_params";
}
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class EstimatedParamsBoundsStatement : public Statement class EstimatedParamsInitStatement : public AbstractEstimatedParamsStatement
{ {
private: private:
const bool use_calibration;
public:
EstimatedParamsInitStatement(vector<EstimationParams> estim_params_list_arg,
const SymbolTable& symbol_table_arg, const bool use_calibration_arg);
[[nodiscard]] string
blockName() const override
{
return "estimated_params_init";
}
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
};
class EstimatedParamsBoundsStatement : public AbstractEstimatedParamsStatement
{
public:
EstimatedParamsBoundsStatement(vector<EstimationParams> estim_params_list_arg,
const SymbolTable& symbol_table_arg);
[[nodiscard]] string
blockName() const override
{
return "estimated_params_bounds";
}
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
};
class EstimatedParamsRemoveStatement : public Statement
{
public:
// Only the type, name and name2 fields of EstimationParams are used
const vector<EstimationParams> estim_params_list; const vector<EstimationParams> estim_params_list;
const SymbolTable& symbol_table; const SymbolTable& symbol_table;
public: EstimatedParamsRemoveStatement(vector<EstimationParams> estim_params_list_arg,
EstimatedParamsBoundsStatement(const vector<EstimationParams> &estim_params_list_arg,
const SymbolTable& symbol_table_arg); const SymbolTable& symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class OptimWeightsStatement : public Statement class OptimWeightsStatement : public Statement
{ {
public: public:
typedef map<string, expr_t> var_weights_t; using var_weights_t = map<string, expr_t>;
typedef map<pair<string, string>, expr_t> covar_weights_t; using covar_weights_t = map<pair<string, string>, expr_t>;
private: private:
const var_weights_t var_weights; const var_weights_t var_weights;
const covar_weights_t covar_weights; const covar_weights_t covar_weights;
const SymbolTable& symbol_table; const SymbolTable& symbol_table;
public: public:
OptimWeightsStatement(const var_weights_t &var_weights_arg, OptimWeightsStatement(var_weights_t var_weights_arg, covar_weights_t covar_weights_arg,
const covar_weights_t &covar_weights_arg,
const SymbolTable& symbol_table_arg); const SymbolTable& symbol_table_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
/*! \todo Make model_tree a member instead of a pointer */
class PlannerObjectiveStatement : public Statement class PlannerObjectiveStatement : public Statement
{ {
private: private:
StaticModel *model_tree; unique_ptr<PlannerObjective> model_tree;
bool computing_pass_called; bool computing_pass_called {false};
public: public:
//! Constructor explicit PlannerObjectiveStatement(unique_ptr<PlannerObjective> model_tree_arg);
/*! \param model_tree_arg the model tree used to store the objective function.
It is owned by the PlannerObjectiveStatement, and will be deleted by its destructor */
PlannerObjectiveStatement(StaticModel *model_tree_arg);
virtual
~PlannerObjectiveStatement();
/*! \todo check there are only endogenous variables at the current period in the objective /*! \todo check there are only endogenous variables at the current period in the objective
(no exogenous, no lead/lag) */ (no exogenous, no lead/lag) */
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
/*! \todo allow for the possibility of disabling temporary terms */ /*! \todo allow for the possibility of disabling temporary terms */
virtual void computingPass(); void computingPass(const ModFileStructure& mod_file_struct) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
//! Return the Planner Objective //! Return a reference the Planner Objective model tree
StaticModel *getPlannerObjective() const; [[nodiscard]] const PlannerObjective& getPlannerObjective() const;
}; };
class BVARDensityStatement : public Statement class BVARDensityStatement : public Statement
...@@ -472,11 +618,12 @@ class BVARDensityStatement : public Statement ...@@ -472,11 +618,12 @@ class BVARDensityStatement : public Statement
private: private:
const int maxnlags; const int maxnlags;
const OptionsList options_list; const OptionsList options_list;
public: public:
BVARDensityStatement(int maxnlags_arg, const OptionsList &options_list_arg); BVARDensityStatement(int maxnlags_arg, OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class BVARForecastStatement : public Statement class BVARForecastStatement : public Statement
...@@ -484,66 +631,85 @@ class BVARForecastStatement : public Statement ...@@ -484,66 +631,85 @@ class BVARForecastStatement : public Statement
private: private:
const int nlags; const int nlags;
const OptionsList options_list; const OptionsList options_list;
public:
BVARForecastStatement(int nlags_arg, OptionsList options_list_arg);
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
};
class BVARIRFStatement : public Statement
{
private:
const int nirf;
const string identificationname;
public: public:
BVARForecastStatement(int nlags_arg, const OptionsList &options_list_arg); BVARIRFStatement(int nirf_arg, string identificationname_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class SBVARStatement : public Statement class SBVARStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
SBVARStatement(const OptionsList &options_list_arg); explicit SBVARStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class MSSBVAREstimationStatement : public Statement class MSSBVAREstimationStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
MSSBVAREstimationStatement(const OptionsList &options_list_arg); explicit MSSBVAREstimationStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class MSSBVARSimulationStatement : public Statement class MSSBVARSimulationStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
MSSBVARSimulationStatement(const OptionsList &options_list_arg); explicit MSSBVARSimulationStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class MSSBVARComputeMDDStatement : public Statement class MSSBVARComputeMDDStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
MSSBVARComputeMDDStatement(const OptionsList &options_list_arg); explicit MSSBVARComputeMDDStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class MSSBVARComputeProbabilitiesStatement : public Statement class MSSBVARComputeProbabilitiesStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
MSSBVARComputeProbabilitiesStatement(const OptionsList &options_list_arg); explicit MSSBVARComputeProbabilitiesStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class MSSBVARIrfStatement : public Statement class MSSBVARIrfStatement : public Statement
...@@ -551,45 +717,50 @@ class MSSBVARIrfStatement : public Statement ...@@ -551,45 +717,50 @@ class MSSBVARIrfStatement : public Statement
private: private:
const SymbolList symbol_list; const SymbolList symbol_list;
const OptionsList options_list; const OptionsList options_list;
const SymbolTable& symbol_table;
public: public:
MSSBVARIrfStatement(const SymbolList &symbol_list_arg, MSSBVARIrfStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
const OptionsList &options_list_arg); const SymbolTable& symbol_table_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class MSSBVARForecastStatement : public Statement class MSSBVARForecastStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
MSSBVARForecastStatement(const OptionsList &options_list_arg); explicit MSSBVARForecastStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class MSSBVARVarianceDecompositionStatement : public Statement class MSSBVARVarianceDecompositionStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
MSSBVARVarianceDecompositionStatement(const OptionsList &options_list_arg); explicit MSSBVARVarianceDecompositionStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class IdentificationStatement : public Statement class IdentificationStatement : public Statement
{ {
private: private:
OptionsList options_list; OptionsList options_list;
public: public:
IdentificationStatement(const OptionsList &options_list_arg); explicit IdentificationStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class WriteLatexDynamicModelStatement : public Statement class WriteLatexDynamicModelStatement : public Statement
...@@ -597,10 +768,12 @@ class WriteLatexDynamicModelStatement : public Statement ...@@ -597,10 +768,12 @@ class WriteLatexDynamicModelStatement : public Statement
private: private:
const DynamicModel& dynamic_model; const DynamicModel& dynamic_model;
const bool write_equation_tags; const bool write_equation_tags;
public: public:
WriteLatexDynamicModelStatement(const DynamicModel &dynamic_model_arg, bool write_equation_tags_arg); WriteLatexDynamicModelStatement(const DynamicModel& dynamic_model_arg,
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; bool write_equation_tags_arg);
virtual void writeJsonOutput(ostream &output) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class WriteLatexStaticModelStatement : public Statement class WriteLatexStaticModelStatement : public Statement
...@@ -608,10 +781,11 @@ class WriteLatexStaticModelStatement : public Statement ...@@ -608,10 +781,11 @@ class WriteLatexStaticModelStatement : public Statement
private: private:
const StaticModel& static_model; const StaticModel& static_model;
const bool write_equation_tags; const bool write_equation_tags;
public: public:
WriteLatexStaticModelStatement(const StaticModel& static_model_arg, bool write_equation_tags_arg); WriteLatexStaticModelStatement(const StaticModel& static_model_arg, bool write_equation_tags_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class WriteLatexOriginalModelStatement : public Statement class WriteLatexOriginalModelStatement : public Statement
...@@ -619,21 +793,24 @@ class WriteLatexOriginalModelStatement : public Statement ...@@ -619,21 +793,24 @@ class WriteLatexOriginalModelStatement : public Statement
private: private:
const DynamicModel& original_model; const DynamicModel& original_model;
const bool write_equation_tags; const bool write_equation_tags;
public: public:
WriteLatexOriginalModelStatement(const DynamicModel &original_model_arg, bool write_equation_tags_arg); WriteLatexOriginalModelStatement(const DynamicModel& original_model_arg,
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; bool write_equation_tags_arg);
virtual void writeJsonOutput(ostream &output) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class WriteLatexSteadyStateModelStatement : public Statement class WriteLatexSteadyStateModelStatement : public Statement
{ {
private: private:
const SteadyStateModel& steady_state_model; const SteadyStateModel& steady_state_model;
public: public:
WriteLatexSteadyStateModelStatement(const SteadyStateModel &steady_state_model_arg); explicit WriteLatexSteadyStateModelStatement(const SteadyStateModel& steady_state_model_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class ShockDecompositionStatement : public Statement class ShockDecompositionStatement : public Statement
...@@ -641,11 +818,14 @@ class ShockDecompositionStatement : public Statement ...@@ -641,11 +818,14 @@ class ShockDecompositionStatement : public Statement
private: private:
const SymbolList symbol_list; const SymbolList symbol_list;
const OptionsList options_list; const OptionsList options_list;
const SymbolTable& symbol_table;
public: public:
ShockDecompositionStatement(const SymbolList &symbol_list_arg, ShockDecompositionStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
const OptionsList &options_list_arg); const SymbolTable& symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeJsonOutput(ostream &output) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class RealtimeShockDecompositionStatement : public Statement class RealtimeShockDecompositionStatement : public Statement
...@@ -653,10 +833,14 @@ class RealtimeShockDecompositionStatement : public Statement ...@@ -653,10 +833,14 @@ class RealtimeShockDecompositionStatement : public Statement
private: private:
const SymbolList symbol_list; const SymbolList symbol_list;
const OptionsList options_list; const OptionsList options_list;
const SymbolTable& symbol_table;
public: public:
RealtimeShockDecompositionStatement(const SymbolList &symbol_list_arg, RealtimeShockDecompositionStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
const OptionsList &options_list_arg); const SymbolTable& symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class PlotShockDecompositionStatement : public Statement class PlotShockDecompositionStatement : public Statement
...@@ -664,10 +848,14 @@ class PlotShockDecompositionStatement : public Statement ...@@ -664,10 +848,14 @@ class PlotShockDecompositionStatement : public Statement
private: private:
const SymbolList symbol_list; const SymbolList symbol_list;
const OptionsList options_list; const OptionsList options_list;
const SymbolTable& symbol_table;
public: public:
PlotShockDecompositionStatement(const SymbolList &symbol_list_arg, PlotShockDecompositionStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
const OptionsList &options_list_arg); const SymbolTable& symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class InitialConditionDecompositionStatement : public Statement class InitialConditionDecompositionStatement : public Statement
...@@ -675,32 +863,55 @@ class InitialConditionDecompositionStatement : public Statement ...@@ -675,32 +863,55 @@ class InitialConditionDecompositionStatement : public Statement
private: private:
const SymbolList symbol_list; const SymbolList symbol_list;
const OptionsList options_list; const OptionsList options_list;
const SymbolTable& symbol_table;
public:
InitialConditionDecompositionStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
const SymbolTable& symbol_table_arg);
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
};
class SqueezeShockDecompositionStatement : public Statement
{
private:
const SymbolList symbol_list;
const SymbolTable& symbol_table;
public: public:
InitialConditionDecompositionStatement(const SymbolList &symbol_list_arg, SqueezeShockDecompositionStatement(SymbolList symbol_list_arg,
const OptionsList &options_list_arg); const SymbolTable& symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class ConditionalForecastStatement : public Statement class ConditionalForecastStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
ConditionalForecastStatement(const OptionsList &options_list_arg); explicit ConditionalForecastStatement(OptionsList options_list_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeJsonOutput(ostream &output) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class PlotConditionalForecastStatement : public Statement class PlotConditionalForecastStatement : public Statement
{ {
private: private:
//! A value of -1 indicates that the user didn't specify a value const optional<int> periods; // The user is allowed not to declare periods
const int periods;
const SymbolList symbol_list; const SymbolList symbol_list;
const SymbolTable& symbol_table;
public: public:
PlotConditionalForecastStatement(int periods_arg, const SymbolList &symbol_list_arg); PlotConditionalForecastStatement(const optional<int>& periods_arg, SymbolList symbol_list_arg,
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; const SymbolTable& symbol_table_arg);
virtual void writeJsonOutput(ostream &output) const; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class CalibSmootherStatement : public Statement class CalibSmootherStatement : public Statement
...@@ -708,29 +919,32 @@ class CalibSmootherStatement : public Statement ...@@ -708,29 +919,32 @@ class CalibSmootherStatement : public Statement
private: private:
const SymbolList symbol_list; const SymbolList symbol_list;
const OptionsList options_list; const OptionsList options_list;
const SymbolTable& symbol_table;
public: public:
CalibSmootherStatement(const SymbolList &symbol_list_arg, CalibSmootherStatement(SymbolList symbol_list_arg, OptionsList options_list_arg,
const OptionsList &options_list_arg); const SymbolTable& symbol_table_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class ExtendedPathStatement : public Statement class ExtendedPathStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
ExtendedPathStatement(const OptionsList &options_list_arg); explicit ExtendedPathStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class SvarIdentificationStatement : public Statement class SvarIdentificationStatement : public Statement
{ {
public: public:
// typedef map<pair<int, int>, vector<int> > svar_identification_exclusion_t; // using svar_identification_exclusion_t = map<pair<int, int>, vector<int>>;
struct svar_identification_restriction struct svar_identification_restriction
{ {
int equation; int equation;
...@@ -740,23 +954,22 @@ public: ...@@ -740,23 +954,22 @@ public:
expr_t value; expr_t value;
}; };
typedef vector< svar_identification_restriction > svar_identification_restrictions_t; using svar_identification_restrictions_t = vector<svar_identification_restriction>;
private: private:
const svar_identification_restrictions_t restrictions; const svar_identification_restrictions_t restrictions;
const bool upper_cholesky_present; const bool upper_cholesky_present, lower_cholesky_present, constants_exclusion_present;
const bool lower_cholesky_present;
const bool constants_exclusion_present;
const SymbolTable& symbol_table; const SymbolTable& symbol_table;
int getMaxLag() const; [[nodiscard]] int getMaxLag() const;
public: public:
SvarIdentificationStatement(const svar_identification_restrictions_t &restrictions_arg, SvarIdentificationStatement(svar_identification_restrictions_t restrictions_arg,
const bool &upper_cholesky_present_arg, bool upper_cholesky_present_arg, bool lower_cholesky_present_arg,
const bool &lower_cholesky_present_arg, bool constants_exclusion_present_arg,
const bool &constants_exclusion_present_arg,
const SymbolTable& symbol_table_arg); const SymbolTable& symbol_table_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class MarkovSwitchingStatement : public Statement class MarkovSwitchingStatement : public Statement
...@@ -764,90 +977,86 @@ class MarkovSwitchingStatement : public Statement ...@@ -764,90 +977,86 @@ class MarkovSwitchingStatement : public Statement
private: private:
const OptionsList options_list; const OptionsList options_list;
map<pair<int, int>, double> restriction_map; map<pair<int, int>, double> restriction_map;
public: public:
MarkovSwitchingStatement(const OptionsList &options_list_arg); explicit MarkovSwitchingStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeCOutput(ostream &output, const string &basename); void writeJsonOutput(ostream& output) const override;
virtual void writeJsonOutput(ostream &output) const;
}; };
class SvarStatement : public Statement class SvarStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
SvarStatement(const OptionsList &options_list_arg); explicit SvarStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class SvarGlobalIdentificationCheckStatement : public Statement class SvarGlobalIdentificationCheckStatement : public Statement
{ {
public: public:
SvarGlobalIdentificationCheckStatement(); void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeJsonOutput(ostream& output) const override;
virtual void writeJsonOutput(ostream &output) const;
}; };
class SetTimeStatement : public Statement class SetTimeStatement : public Statement
{ {
private: private:
const OptionsList options_list; const string period;
public: public:
SetTimeStatement(const OptionsList &options_list_arg); explicit SetTimeStatement(string period_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class EstimationDataStatement : public Statement class EstimationDataStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
EstimationDataStatement(const OptionsList &options_list_arg); explicit EstimationDataStatement(OptionsList options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class SubsamplesStatement : public Statement class SubsamplesStatement : public Statement
{ {
public: public:
//! Storage for declaring subsamples: map<subsample_name, <date1, date2 > //! Storage for declaring subsamples: map<subsample_name, <date1, date2 >
typedef map<string, pair<string, string> > subsample_declaration_map_t; using subsample_declaration_map_t = map<string, pair<string, string>>;
private: private:
const string name1; const string name1, name2;
const string name2;
const subsample_declaration_map_t subsample_declaration_map; const subsample_declaration_map_t subsample_declaration_map;
const SymbolTable symbol_table; const SymbolTable& symbol_table;
public: public:
SubsamplesStatement(const string &name1_arg, SubsamplesStatement(string name1_arg, string name2_arg,
const string &name2_arg, subsample_declaration_map_t subsample_declaration_map_arg,
const subsample_declaration_map_t subsample_declaration_map_arg,
const SymbolTable& symbol_table_arg); const SymbolTable& symbol_table_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeJsonOutput(ostream& output) const override;
virtual void writeJsonOutput(ostream &output) const;
}; };
class SubsamplesEqualStatement : public Statement class SubsamplesEqualStatement : public Statement
{ {
private: private:
const string to_name1; const string to_name1, to_name2, from_name1, from_name2;
const string to_name2; const SymbolTable& symbol_table;
const string from_name1;
const string from_name2;
const SymbolTable symbol_table;
public: public:
SubsamplesEqualStatement(const string &to_name1_arg, SubsamplesEqualStatement(string to_name1_arg, string to_name2_arg, string from_name1_arg,
const string &to_name2_arg, string from_name2_arg, const SymbolTable& symbol_table_arg);
const string &from_name1_arg, void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
const string &from_name2_arg, void writeJsonOutput(ostream& output) const override;
const SymbolTable &symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
virtual void writeJsonOutput(ostream &output) const;
}; };
class JointPriorStatement : public Statement class JointPriorStatement : public Statement
...@@ -856,46 +1065,36 @@ private: ...@@ -856,46 +1065,36 @@ private:
const vector<string> joint_parameters; const vector<string> joint_parameters;
const PriorDistributions prior_shape; const PriorDistributions prior_shape;
const OptionsList options_list; const OptionsList options_list;
public:
JointPriorStatement(const vector<string> joint_parameters_arg,
const PriorDistributions &prior_shape_arg,
const OptionsList &options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
void writeOutputHelper(ostream& output, const string& field, const string& lhs_field) const; void writeOutputHelper(ostream& output, const string& field, const string& lhs_field) const;
virtual void writeJsonOutput(ostream &output) const;
public:
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;
void writeJsonOutput(ostream& output) const override;
}; };
class BasicPriorStatement : public Statement class BasicPriorStatement : public Statement
{ {
public:
virtual
~BasicPriorStatement();
protected: protected:
const string name; const string name, subsample_name;
const string subsample_name;
const PriorDistributions prior_shape; const PriorDistributions prior_shape;
const expr_t variance; const expr_t variance;
const OptionsList options_list; const OptionsList options_list;
BasicPriorStatement(const string &name_arg, BasicPriorStatement(string name_arg, string subsample_name_arg,
const string &subsample_name_arg, PriorDistributions prior_shape_arg, expr_t variance_arg,
const PriorDistributions &prior_shape_arg, OptionsList options_list_arg);
const expr_t &variance_arg, void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
const OptionsList &options_list_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
void get_base_name(const SymbolType symb_type, string& lhs_field) const; void get_base_name(const SymbolType symb_type, string& lhs_field) const;
void writeCommonOutput(ostream& output, const string& lhs_field) const; void writeCommonOutput(ostream& output, const string& lhs_field) const;
void writeCommonOutputHelper(ostream& output, const string& field, const string& lhs_field) const; void writeCommonOutputHelper(ostream& output, const string& field, const string& lhs_field) const;
void writePriorOutput(ostream& output, string& lhs_field, const string& name2) const; void writePriorOutput(ostream& output, string& lhs_field, const string& name2) const;
bool is_structural_innovation(const SymbolType symb_type) const; [[nodiscard]] bool is_structural_innovation(const SymbolType symb_type) const;
void writePriorIndex(ostream& output, const string& lhs_field) const; void writePriorIndex(ostream& output, const string& lhs_field) const;
void writeVarianceOption(ostream& output, const string& lhs_field) const; void writeVarianceOption(ostream& output, const string& lhs_field) const;
void writeOutputHelper(ostream& output, const string& field, const string& lhs_field) const; void writeOutputHelper(ostream& output, const string& field, const string& lhs_field) const;
void writeShape(ostream& output, const string& lhs_field) const; void writeShape(ostream& output, const string& lhs_field) const;
void writeCOutputHelper(ostream &output, const string &field) const;
void writeCShape(ostream &output) const;
void writeCVarianceOption(ostream &output) const;
void writeCDomain(ostream &output) const;
void writeJsonShape(ostream& output) const; void writeJsonShape(ostream& output) const;
void writeJsonPriorOutput(ostream& output) const; void writeJsonPriorOutput(ostream& output) const;
}; };
...@@ -903,223 +1102,241 @@ protected: ...@@ -903,223 +1102,241 @@ protected:
class PriorStatement : public BasicPriorStatement class PriorStatement : public BasicPriorStatement
{ {
public: public:
PriorStatement(const string &name_arg, PriorStatement(string name_arg, string subsample_name_arg, PriorDistributions prior_shape_arg,
const string &subsample_name_arg, expr_t variance_arg, OptionsList options_list_arg);
const PriorDistributions &prior_shape_arg, void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
const expr_t &variance_arg, void writeJsonOutput(ostream& output) const override;
const OptionsList &options_list_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
virtual void writeCOutput(ostream &output, const string &basename);
virtual void writeJsonOutput(ostream &output) const;
}; };
class StdPriorStatement : public BasicPriorStatement class StdPriorStatement : public BasicPriorStatement
{ {
private: private:
const SymbolTable symbol_table; const SymbolTable& symbol_table;
public: public:
StdPriorStatement(const string &name_arg, StdPriorStatement(string name_arg, string subsample_name_arg, PriorDistributions prior_shape_arg,
const string &subsample_name_arg, expr_t variance_arg, OptionsList options_list_arg,
const PriorDistributions &prior_shape_arg,
const expr_t &variance_arg,
const OptionsList &options_list_arg,
const SymbolTable& symbol_table_arg); const SymbolTable& symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeCOutput(ostream &output, const string &basename); void writeJsonOutput(ostream& output) const override;
virtual void writeJsonOutput(ostream &output) const;
}; };
class CorrPriorStatement : public BasicPriorStatement class CorrPriorStatement : public BasicPriorStatement
{ {
private: private:
const string name1; const string name1;
const SymbolTable symbol_table; const SymbolTable& symbol_table;
public:
CorrPriorStatement(const string &name_arg1, public:
const string &name_arg2, CorrPriorStatement(string name_arg1, string name_arg2, string subsample_name_arg,
const string &subsample_name_arg, PriorDistributions prior_shape_arg, expr_t variance_arg,
const PriorDistributions &prior_shape_arg, OptionsList options_list_arg, const SymbolTable& symbol_table_arg);
const expr_t &variance_arg, void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
const OptionsList &options_list_arg, void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
const SymbolTable &symbol_table_arg); void writeJsonOutput(ostream& output) const override;
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
virtual void writeCOutput(ostream &output, const string &basename);
virtual void writeJsonOutput(ostream &output) const;
}; };
class PriorEqualStatement : public Statement class PriorEqualStatement : public Statement
{ {
private: private:
const string to_declaration_type; const string to_declaration_type, to_name1, to_name2, to_subsample_name;
const string to_name1; const string from_declaration_type, from_name1, from_name2, from_subsample_name;
const string to_name2; const SymbolTable& symbol_table;
const string to_subsample_name;
const string from_declaration_type; public:
const string from_name1; PriorEqualStatement(string to_declaration_type_arg, string to_name1_arg, string to_name2_arg,
const string from_name2; string to_subsample_name_arg, string from_declaration_type_arg,
const string from_subsample_name; string from_name1_arg, string from_name2_arg, string from_subsample_name_arg,
const SymbolTable symbol_table;
public:
PriorEqualStatement(const string &to_declaration_type_arg,
const string &to_name1_arg,
const string &to_name2_arg,
const string &to_subsample_name_arg,
const string &from_declaration_type_arg,
const string &from_name1_arg,
const string &from_name2_arg,
const string &from_subsample_name_arg,
const SymbolTable& symbol_table_arg); const SymbolTable& symbol_table_arg);
void get_base_name(const SymbolType symb_type, string& lhs_field) const; void get_base_name(const SymbolType symb_type, string& lhs_field) const;
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class BasicOptionsStatement : public Statement class BasicOptionsStatement : public Statement
{ {
public:
virtual
~BasicOptionsStatement();
protected: protected:
const string name; const string name, subsample_name;
const string subsample_name;
const OptionsList options_list; const OptionsList options_list;
BasicOptionsStatement(const string &name_arg, BasicOptionsStatement(string name_arg, string subsample_name_arg, OptionsList options_list_arg);
const string &subsample_name_arg,
const OptionsList &options_list_arg);
void get_base_name(const SymbolType symb_type, string& lhs_field) const; void get_base_name(const SymbolType symb_type, string& lhs_field) const;
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
void writeOptionsOutput(ostream& output, string& lhs_field, const string& name2) const; void writeOptionsOutput(ostream& output, string& lhs_field, const string& name2) const;
void writeCommonOutput(ostream& output, const string& lhs_field) const; void writeCommonOutput(ostream& output, const string& lhs_field) const;
void writeCommonOutputHelper(ostream& output, const string& field, const string& lhs_field) const; void writeCommonOutputHelper(ostream& output, const string& field, const string& lhs_field) const;
bool is_structural_innovation(const SymbolType symb_type) const; [[nodiscard]] bool is_structural_innovation(const SymbolType symb_type) const;
void writeOptionsIndex(ostream& output, const string& lhs_field) const; void writeOptionsIndex(ostream& output, const string& lhs_field) const;
void writeOutputHelper(ostream& output, const string& field, const string& lhs_field) const; void writeOutputHelper(ostream& output, const string& field, const string& lhs_field) const;
void writeCOutputHelper(ostream &output, const string &field) const;
void writeJsonOptionsOutput(ostream& output) const; void writeJsonOptionsOutput(ostream& output) const;
}; };
class OptionsStatement : public BasicOptionsStatement class OptionsStatement : public BasicOptionsStatement
{ {
public: public:
OptionsStatement(const string &name_arg, const string &subsample_name_arg, const OptionsList &options_list_arg); OptionsStatement(string name_arg, string subsample_name_arg, OptionsList options_list_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeCOutput(ostream &output, const string &basename); void writeJsonOutput(ostream& output) const override;
virtual void writeJsonOutput(ostream &output) const;
}; };
class StdOptionsStatement : public BasicOptionsStatement class StdOptionsStatement : public BasicOptionsStatement
{ {
private: private:
const SymbolTable symbol_table; const SymbolTable& symbol_table;
public: public:
StdOptionsStatement(const string &name_arg, StdOptionsStatement(string name_arg, string subsample_name_arg, OptionsList options_list_arg,
const string &subsample_name_arg,
const OptionsList &options_list_arg,
const SymbolTable& symbol_table_arg); const SymbolTable& symbol_table_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeCOutput(ostream &output, const string &basename); void writeJsonOutput(ostream& output) const override;
virtual void writeJsonOutput(ostream &output) const;
}; };
class CorrOptionsStatement : public BasicOptionsStatement class CorrOptionsStatement : public BasicOptionsStatement
{ {
private: private:
const string name1; const string name1;
const SymbolTable symbol_table; const SymbolTable& symbol_table;
public: public:
CorrOptionsStatement(const string &name_arg1, const string &name_arg2, CorrOptionsStatement(string name_arg1, string name_arg2, string subsample_name_arg,
const string &subsample_name_arg, OptionsList options_list_arg, const SymbolTable& symbol_table_arg);
const OptionsList &options_list_arg, void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
const SymbolTable &symbol_table_arg); void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void writeJsonOutput(ostream& output) const override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
virtual void writeCOutput(ostream &output, const string &basename);
virtual void writeJsonOutput(ostream &output) const;
}; };
class OptionsEqualStatement : public Statement class OptionsEqualStatement : public Statement
{ {
private: private:
const string to_declaration_type; const string to_declaration_type, to_name1, to_name2, to_subsample_name;
const string to_name1; const string from_declaration_type, from_name1, from_name2, from_subsample_name;
const string to_name2; const SymbolTable& symbol_table;
const string to_subsample_name;
const string from_declaration_type; public:
const string from_name1; OptionsEqualStatement(string to_declaration_type_arg, string to_name1_arg, string to_name2_arg,
const string from_name2; string to_subsample_name_arg, string from_declaration_type_arg,
const string from_subsample_name; string from_name1_arg, string from_name2_arg,
const SymbolTable symbol_table; string from_subsample_name_arg, const SymbolTable& symbol_table_arg);
public:
OptionsEqualStatement(const string &to_declaration_type_arg,
const string &to_name1_arg,
const string &to_name2_arg,
const string &to_subsample_name_arg,
const string &from_declaration_type_arg,
const string &from_name1_arg,
const string &from_name2_arg,
const string &from_subsample_name_arg,
const SymbolTable &symbol_table_arg);
void get_base_name(const SymbolType symb_type, string& lhs_field) const; void get_base_name(const SymbolType symb_type, string& lhs_field) const;
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class ModelDiagnosticsStatement : public Statement class ModelDiagnosticsStatement : public Statement
{ {
public: public:
ModelDiagnosticsStatement(); void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeJsonOutput(ostream& output) const override;
virtual void writeJsonOutput(ostream &output) const;
}; };
class Smoother2histvalStatement : public Statement class Smoother2histvalStatement : public Statement
{ {
private: private:
const OptionsList options_list; const OptionsList options_list;
public: public:
Smoother2histvalStatement(const OptionsList &options_list_arg); explicit Smoother2histvalStatement(OptionsList options_list_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
}; };
class GMMEstimationStatement : public Statement class MethodOfMomentsStatement : public Statement
{ {
private: private:
const SymbolList symbol_list;
const OptionsList options_list; const OptionsList options_list;
public: public:
GMMEstimationStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg); explicit MethodOfMomentsStatement(OptionsList options_list_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
virtual void writeJsonOutput(ostream &output) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class SMMEstimationStatement : public Statement class GenerateIRFsStatement : public Statement
{ {
public:
private: private:
const SymbolList symbol_list;
const OptionsList options_list; const OptionsList options_list;
const vector<string> generate_irf_names;
const vector<map<string, double>> generate_irf_elements;
public: public:
SMMEstimationStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg); GenerateIRFsStatement(OptionsList options_list_arg, vector<string> generate_irf_names_arg,
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; vector<map<string, double>> generate_irf_elements_arg);
virtual void writeJsonOutput(ostream &output) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
}; };
class GenerateIRFsStatement : public Statement 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 */
const vector<tuple<vector<int>, vector<int>, vector<int>>> moments;
MatchedMomentsStatement(const SymbolTable& symbol_table_arg,
vector<tuple<vector<int>, vector<int>, vector<int>>> moments_arg);
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
};
class OccbinConstraintsStatement : public Statement
{
private:
DataTree data_tree;
public: public:
// 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,
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;
void writeJsonOutput(ostream& output) const override;
};
class ResidStatement : public Statement
{
private: private:
const OptionsList options_list; const OptionsList options_list;
const vector<string> generate_irf_names;
const vector<map<string, double> > generate_irf_elements; public:
explicit ResidStatement(OptionsList options_list_arg);
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
};
class MatchedIrfsStatement : public Statement
{
public: public:
GenerateIRFsStatement(const OptionsList &options_list_arg, // (endo name, exo name) → vector of (period start, period end, value, weight)
const vector<string> &generate_irf_names_arg, using matched_irfs_t = map<pair<string, string>, vector<tuple<int, int, expr_t, expr_t>>>;
const vector<map<string, double> > &generate_irf_elements_arg); MatchedIrfsStatement(matched_irfs_t values_weights_arg, bool overwrite_arg);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
virtual void writeJsonOutput(ostream &output) const; void writeJsonOutput(ostream& output) const override;
private:
const matched_irfs_t values_weights;
const bool overwrite;
};
class MatchedIrfsWeightsStatement : public Statement
{
public:
/* (endo1 name, period index or range for endo1, exo1 name, endo2 name, period index or range for
endo2, exo2 name) → weight */
using matched_irfs_weights_t = map<tuple<string, string, string, string, string, string>, expr_t>;
MatchedIrfsWeightsStatement(matched_irfs_weights_t weights_arg, bool overwrite_arg);
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override;
private:
const matched_irfs_weights_t weights;
const bool overwrite;
}; };
#endif #endif
/*
* Copyright (C) 2010-2017 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include "ConfigFile.hh"
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
using namespace std;
Hook::Hook(string &global_init_file_arg)
{
if (global_init_file_arg.empty())
{
cerr << "ERROR: The Hook must have a Global Initialization File argument." << endl;
exit(EXIT_FAILURE);
}
hooks["global_init_file"] = global_init_file_arg;
}
Path::Path(vector<string> &includepath_arg)
{
if (includepath_arg.empty())
{
cerr << "ERROR: The Path must have an Include argument." << endl;
exit(EXIT_FAILURE);
}
paths["include"] = includepath_arg;
}
SlaveNode::SlaveNode(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 &dynarePath_arg, string &matlabOctavePath_arg, bool singleCompThread_arg, int numberOfThreadsPerJob_arg,
string &operatingSystem_arg) :
computerName(computerName_arg), port(port_arg), minCpuNbr(minCpuNbr_arg), maxCpuNbr(maxCpuNbr_arg), userName(userName_arg),
password(password_arg), remoteDrive(remoteDrive_arg), remoteDirectory(remoteDirectory_arg), dynarePath(dynarePath_arg),
matlabOctavePath(matlabOctavePath_arg), singleCompThread(singleCompThread_arg), numberOfThreadsPerJob(numberOfThreadsPerJob_arg),
operatingSystem(operatingSystem_arg)
{
if (computerName.empty())
{
cerr << "ERROR: The node must have a ComputerName." << endl;
exit(EXIT_FAILURE);
}
if (!operatingSystem.empty())
if (operatingSystem.compare("windows") != 0 && operatingSystem.compare("unix") != 0)
{
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(member_nodes_arg)
{
if (member_nodes.empty())
{
cerr << "ERROR: The cluster must have at least one member node." << endl;
exit(EXIT_FAILURE);
}
}
ConfigFile::ConfigFile(bool parallel_arg, bool parallel_test_arg,
bool parallel_slave_open_mode_arg, const string &cluster_name_arg) :
parallel(parallel_arg), parallel_test(parallel_test_arg),
parallel_slave_open_mode(parallel_slave_open_mode_arg), cluster_name(cluster_name_arg)
{
}
ConfigFile::~ConfigFile()
{
}
void
ConfigFile::getConfigFileInfo(const string &config_file)
{
using namespace boost;
ifstream *configFile;
if (config_file.empty())
{
string defaultConfigFile("");
// Test OS and try to open default file
#if defined(_WIN32) || defined(__CYGWIN32__)
if (getenv("APPDATA") == NULL)
{
if (parallel || parallel_test)
cerr << "ERROR: ";
else
cerr << "WARNING: ";
cerr << "APPDATA environment variable not found." << endl;
if (parallel || parallel_test)
exit(EXIT_FAILURE);
}
else
{
defaultConfigFile += getenv("APPDATA");
defaultConfigFile += "\\dynare.ini";
}
#else
if (getenv("HOME") == NULL)
{
if (parallel || parallel_test)
cerr << "ERROR: ";
else
cerr << "WARNING: ";
cerr << "HOME environment variable not found." << endl;
if (parallel || parallel_test)
exit(EXIT_FAILURE);
}
else
{
defaultConfigFile += getenv("HOME");
defaultConfigFile += "/.dynare";
}
#endif
configFile = new ifstream(defaultConfigFile.c_str(), fstream::in);
if (!configFile->is_open())
if (parallel || parallel_test)
{
cerr << "ERROR: Could not open the default config file (" << defaultConfigFile << ")" << endl;
exit(EXIT_FAILURE);
}
else
return;
}
else
{
configFile = new ifstream(config_file.c_str(), fstream::in);
if (!configFile->is_open())
{
cerr << "ERROR: Couldn't open file " << config_file << endl;;
exit(EXIT_FAILURE);
}
}
string name, computerName, port, userName, password, remoteDrive,
remoteDirectory, dynarePath, matlabOctavePath, operatingSystem,
global_init_file;
vector<string> includepath;
int minCpuNbr = 0, maxCpuNbr = 0;
int numberOfThreadsPerJob = 1;
bool singleCompThread = false;
member_nodes_t member_nodes;
bool inHooks = false;
bool inNode = false;
bool inCluster = false;
bool inPaths = false;
while (configFile->good())
{
string line;
getline(*configFile, line);
trim(line);
if (line.empty() || !line.compare(0, 1, "#"))
continue;
if (!line.compare("[node]")
|| !line.compare("[cluster]")
|| !line.compare("[hooks]")
|| !line.compare("[paths]"))
{
if (!global_init_file.empty())
// we were just in [hooks]
addHooksConfFileElement(global_init_file);
else if (!includepath.empty())
// we were just in [paths]
addPathsConfFileElement(includepath);
else
// we were just in [node] or [cluster]
addParallelConfFileElement(inNode, inCluster, member_nodes, name,
computerName, port, minCpuNbr, maxCpuNbr, userName,
password, remoteDrive, remoteDirectory,
dynarePath, matlabOctavePath, singleCompThread, numberOfThreadsPerJob,
operatingSystem);
//! Reset communication vars / option defaults
if (!line.compare("[hooks]"))
{
inHooks = true;
inNode = false;
inCluster = false;
inPaths = false;
}
else if (!line.compare("[node]"))
{
inHooks = false;
inNode = true;
inCluster = false;
inPaths = false;
}
else if (!line.compare("[paths]"))
{
inHooks = false;
inNode = false;
inCluster = false;
inPaths = true;
}
else
{
inHooks = false;
inNode = false;
inCluster = true;
inPaths = false;
}
name = userName = computerName = port = password = remoteDrive
= remoteDirectory = dynarePath = matlabOctavePath
= operatingSystem = global_init_file = "";
includepath.clear();
minCpuNbr = maxCpuNbr = 0;
numberOfThreadsPerJob = 1;
singleCompThread = false;
member_nodes.clear();
}
else
{
vector<string> tokenizedLine;
split(tokenizedLine, line, is_any_of("="));
if (tokenizedLine.size() != 2)
{
cerr << "ERROR (in config file): Options should be formatted as 'option = value'." << endl;
exit(EXIT_FAILURE);
}
trim(tokenizedLine.front());
trim(tokenizedLine.back());
if (inHooks)
if (!tokenizedLine.front().compare("GlobalInitFile"))
if (global_init_file.empty())
global_init_file = tokenizedLine.back();
else
{
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;
exit(EXIT_FAILURE);
}
else if (inPaths)
if (!tokenizedLine.front().compare("Include"))
if (includepath.empty())
{
vector<string> tokenizedPath;
split(tokenizedPath, tokenizedLine.back(), is_any_of(":"), token_compress_on);
for (vector<string>::iterator it = tokenizedPath.begin();
it != tokenizedPath.end(); it++)
if (!it->empty())
{
trim(*it);
includepath.push_back(*it);
}
}
else
{
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;
exit(EXIT_FAILURE);
}
else
if (!tokenizedLine.front().compare("Name"))
name = tokenizedLine.back();
else if (!tokenizedLine.front().compare("CPUnbr"))
{
vector<string> tokenizedCpuNbr;
split(tokenizedCpuNbr, tokenizedLine.back(), is_any_of(":"));
try
{
if (tokenizedCpuNbr.size() == 1)
{
minCpuNbr = 1;
maxCpuNbr = lexical_cast< int >(tokenizedCpuNbr.front());
}
else if (tokenizedCpuNbr.size() == 2
&& tokenizedCpuNbr[0].at(0) == '['
&& tokenizedCpuNbr[1].at(tokenizedCpuNbr[1].size()-1) == ']')
{
tokenizedCpuNbr[0].erase(0, 1);
tokenizedCpuNbr[1].erase(tokenizedCpuNbr[1].size()-1, 1);
minCpuNbr = lexical_cast< int >(tokenizedCpuNbr[0]);
maxCpuNbr = lexical_cast< int >(tokenizedCpuNbr[1]);
}
}
catch (const bad_lexical_cast &)
{
cerr << "ERROR: Could not convert value to integer for CPUnbr." << endl;
exit(EXIT_FAILURE);
}
if (minCpuNbr <= 0 || maxCpuNbr <= 0)
{
cerr << "ERROR: Syntax for the CPUnbr option is as follows:" << endl
<< " 1) CPUnbr = <int>" << endl
<< " or 2) CPUnbr = [<int>:<int>]" << endl
<< " where <int> is an Integer > 0." << endl;
exit(EXIT_FAILURE);
}
minCpuNbr--;
maxCpuNbr--;
if (minCpuNbr > maxCpuNbr)
{
int tmp = maxCpuNbr;
maxCpuNbr = minCpuNbr;
minCpuNbr = tmp;
}
}
else if (!tokenizedLine.front().compare("Port"))
port = tokenizedLine.back();
else if (!tokenizedLine.front().compare("ComputerName"))
computerName = tokenizedLine.back();
else if (!tokenizedLine.front().compare("UserName"))
userName = tokenizedLine.back();
else if (!tokenizedLine.front().compare("Password"))
password = tokenizedLine.back();
else if (!tokenizedLine.front().compare("RemoteDrive"))
remoteDrive = tokenizedLine.back();
else if (!tokenizedLine.front().compare("RemoteDirectory"))
remoteDirectory = tokenizedLine.back();
else if (!tokenizedLine.front().compare("DynarePath"))
dynarePath = tokenizedLine.back();
else if (!tokenizedLine.front().compare("MatlabOctavePath"))
matlabOctavePath = tokenizedLine.back();
else if (!tokenizedLine.front().compare("NumberOfThreadsPerJob"))
numberOfThreadsPerJob = atoi(tokenizedLine.back().c_str());
else if (!tokenizedLine.front().compare("SingleCompThread"))
if (tokenizedLine.back().compare("true") == 0)
singleCompThread = true;
else if (tokenizedLine.back().compare("false") == 0)
singleCompThread = false;
else
{
cerr << "ERROR (in config file): The value passed to SingleCompThread may only be 'true' or 'false'." << endl;
exit(EXIT_FAILURE);
}
else if (!tokenizedLine.front().compare("OperatingSystem"))
operatingSystem = tokenizedLine.back();
else if (!tokenizedLine.front().compare("Members"))
{
char_separator<char> sep(" ,;", "()", drop_empty_tokens);
tokenizer<char_separator<char> > tokens(tokenizedLine.back(), sep);
bool begin_weight = false;
string node_name;
for (tokenizer<char_separator<char> >::iterator it = tokens.begin();
it != tokens.end(); it++)
{
string token(*it);
if (token.compare("(") == 0)
{
begin_weight = true;
continue;
}
else if (token.compare(")") == 0)
{
node_name.clear();
begin_weight = false;
continue;
}
if (!begin_weight)
{
if (!node_name.empty())
if (member_nodes.find(node_name) != member_nodes.end())
{
cerr << "ERROR (in config file): Node entered twice in specification of cluster." << endl;
exit(EXIT_FAILURE);
}
else
member_nodes[node_name] = 1.0;
node_name = token;
}
else
try
{
double weight = lexical_cast<double>(token.c_str());
if (weight <= 0)
{
cerr << "ERROR (in config file): Misspecification of weights passed to Members option." << endl;
exit(EXIT_FAILURE);
}
member_nodes[node_name] = weight;
}
catch (bad_lexical_cast &)
{
cerr << "ERROR (in config file): Misspecification of weights passed to Members option." << endl;
exit(EXIT_FAILURE);
}
}
if (!node_name.empty())
if (member_nodes.find(node_name) == member_nodes.end())
member_nodes[node_name] = 1.0;
else
{
cerr << "ERROR (in config file): Node entered twice in specification of cluster." << endl;
exit(EXIT_FAILURE);
}
}
else
{
cerr << "ERROR (in config file): Option " << tokenizedLine.front() << " is invalid." << endl;
exit(EXIT_FAILURE);
}
}
}
if (!global_init_file.empty())
addHooksConfFileElement(global_init_file);
else if (!includepath.empty())
addPathsConfFileElement(includepath);
else
addParallelConfFileElement(inNode, inCluster, member_nodes, name,
computerName, port, minCpuNbr, maxCpuNbr, userName,
password, remoteDrive, remoteDirectory,
dynarePath, matlabOctavePath, singleCompThread, numberOfThreadsPerJob,
operatingSystem);
configFile->close();
delete configFile;
}
void
ConfigFile::addHooksConfFileElement(string &global_init_file)
{
if (global_init_file.empty())
{
cerr << "ERROR: The global initialization file must be passed to the GlobalInitFile option." << endl;
exit(EXIT_FAILURE);
}
else
hooks.push_back(new Hook(global_init_file));
}
void
ConfigFile::addPathsConfFileElement(vector<string> &includepath)
{
if (includepath.empty())
{
cerr << "ERROR: The path to be included must be passed to the Include option." << endl;
exit(EXIT_FAILURE);
}
else
paths.push_back(new Path(includepath));
}
void
ConfigFile::addParallelConfFileElement(bool inNode, bool inCluster, member_nodes_t member_nodes,
string &name, string &computerName, string port, int minCpuNbr, int maxCpuNbr, string &userName,
string &password, string &remoteDrive, string &remoteDirectory,
string &dynarePath, string &matlabOctavePath, bool singleCompThread, int numberOfThreadsPerJob,
string &operatingSystem)
{
//! ADD NODE
if (inNode)
if (!member_nodes.empty())
{
cerr << "Invalid option passed to [node]." << endl;
exit(EXIT_FAILURE);
}
else
if (name.empty() || slave_nodes.find(name) != slave_nodes.end())
{
cerr << "ERROR: Every node must be assigned a unique name." << endl;
exit(EXIT_FAILURE);
}
else
slave_nodes[name] = new SlaveNode(computerName, port, minCpuNbr, maxCpuNbr, userName,
password, remoteDrive, remoteDirectory, dynarePath,
matlabOctavePath, singleCompThread, numberOfThreadsPerJob,
operatingSystem);
//! ADD CLUSTER
else if (inCluster)
if (minCpuNbr > 0 || maxCpuNbr > 0 || !userName.empty()
|| !password.empty() || !remoteDrive.empty() || !remoteDirectory.empty()
|| !dynarePath.empty() || !matlabOctavePath.empty() || !operatingSystem.empty())
{
cerr << "Invalid option passed to [cluster]." << endl;
exit(EXIT_FAILURE);
}
else
if (name.empty() || clusters.find(name) != clusters.end())
{
cerr << "ERROR: The cluster must be assigned a unique name." << endl;
exit(EXIT_FAILURE);
}
else
{
if (clusters.empty())
firstClusterName = name;
clusters[name] = new Cluster(member_nodes);
}
}
void
ConfigFile::checkPass(WarningConsolidation &warnings) const
{
bool global_init_file_declared = false;
for (vector<Hook *>::const_iterator it = hooks.begin(); it != hooks.end(); it++)
{
const map <string, string> hookmap = (*it)->get_hooks();
for (map <string, string>::const_iterator mapit = hookmap.begin(); mapit != hookmap.end(); mapit++)
if (mapit->first.compare("global_init_file") == 0)
if (global_init_file_declared == true)
{
cerr << "ERROR: Only one global initialization file may be provided." << endl;
exit(EXIT_FAILURE);
}
else
global_init_file_declared = true;
}
if (!parallel && !parallel_test)
return;
//! Check Slave Nodes
if (slave_nodes.empty())
{
cerr << "ERROR: At least one node must be defined in the config file." << endl;
exit(EXIT_FAILURE);
}
for (map<string, SlaveNode *>::const_iterator it = slave_nodes.begin();
it != slave_nodes.end(); it++)
{
#if !defined(_WIN32) && !defined(__CYGWIN32__)
//For Linux/Mac, check that cpuNbr starts at 0
if (it->second->minCpuNbr != 0)
warnings << "WARNING: On Unix-based operating systems, you cannot specify the CPU that is "
<< "used in parallel processing. This will be adjusted for you such that the "
<< "same number of CPUs are used." << endl;
#endif
if (!it->second->port.empty())
try
{
boost::lexical_cast< int >(it->second->port);
}
catch (const boost::bad_lexical_cast &)
{
cerr << "ERROR (node " << it->first << "): the port must be an integer." << endl;
exit(EXIT_FAILURE);
}
if (!it->second->computerName.compare("localhost")) // We are working locally
{
if (!it->second->remoteDrive.empty())
{
cerr << "ERROR (node " << it->first << "): the RemoteDrive option may not be passed for a local node." << endl;
exit(EXIT_FAILURE);
}
if (!it->second->remoteDirectory.empty())
{
cerr << "ERROR (node " << it->first << "): the RemoteDirectory option may not be passed for a local node." << endl;
exit(EXIT_FAILURE);
}
}
else
{
if (it->second->userName.empty())
{
cerr << "ERROR (node " << it->first << "): the UserName option must be passed for every remote node." << endl;
exit(EXIT_FAILURE);
}
if (it->second->operatingSystem.compare("windows") == 0)
{
if (it->second->password.empty())
{
cerr << "ERROR (node " << it->first << "): the Password option must be passed under Windows for every remote node." << endl;
exit(EXIT_FAILURE);
}
if (it->second->remoteDrive.empty())
{
cerr << "ERROR (node " << it->first << "): the RemoteDrive option must be passed under Windows for every remote node." << endl;
exit(EXIT_FAILURE);
}
}
#if defined(_WIN32) || defined(__CYGWIN32__)
if (it->second->operatingSystem.empty())
{
if (it->second->password.empty())
{
cerr << "ERROR (node " << it->first << "): the Password option must be passed under Windows for every remote node." << endl;
exit(EXIT_FAILURE);
}
if (it->second->remoteDrive.empty())
{
cerr << "ERROR (node " << it->first << "): the RemoteDrive option must be passed under Windows for every remote node." << endl;
exit(EXIT_FAILURE);
}
}
#endif
if (it->second->remoteDirectory.empty())
{
cerr << "ERROR (node " << it->first << "): the RemoteDirectory must be specified for every remote node." << endl;
exit(EXIT_FAILURE);
}
}
}
//! Check Clusters
if (clusters.empty())
{
cerr << "ERROR: At least one cluster must be defined in the config file." << endl;
exit(EXIT_FAILURE);
}
if (!cluster_name.empty() && clusters.find(cluster_name) == clusters.end())
{
cerr << "ERROR: Cluster Name " << cluster_name << " was not found in the config file." << endl;
exit(EXIT_FAILURE);
}
for (map<string, Cluster *>::const_iterator it = clusters.begin();
it != clusters.end(); it++)
for (member_nodes_t::const_iterator itmn = it->second->member_nodes.begin();
itmn != it->second->member_nodes.end(); itmn++)
if (slave_nodes.find(itmn->first) == slave_nodes.end())
{
cerr << "Error: node " << itmn->first << " specified in cluster " << it->first << " was not found" << endl;
exit(EXIT_FAILURE);
}
}
void
ConfigFile::transformPass()
{
if (!parallel && !parallel_test)
return;
#if !defined(_WIN32) && !defined(__CYGWIN32__)
//For Linux/Mac, check that cpuNbr starts at 0
for (map<string, SlaveNode *>::const_iterator it = slave_nodes.begin();
it != slave_nodes.end(); it++)
if (it->second->minCpuNbr != 0)
{
it->second->maxCpuNbr = it->second->maxCpuNbr - it->second->minCpuNbr;
it->second->minCpuNbr = 0;
}
#endif
map<string, Cluster *>::const_iterator cluster_it;
if (cluster_name.empty())
cluster_it = clusters.find(firstClusterName);
else
cluster_it = clusters.find(cluster_name);
double weight_denominator = 0.0;
for (member_nodes_t::const_iterator it = cluster_it->second->member_nodes.begin();
it != cluster_it->second->member_nodes.end(); it++)
weight_denominator += it->second;
for (member_nodes_t::iterator it = cluster_it->second->member_nodes.begin();
it != cluster_it->second->member_nodes.end(); it++)
it->second /= weight_denominator;
}
vector<string>
ConfigFile::getIncludePaths() const
{
vector<string> include_paths;
for (vector<Path *>::const_iterator it = paths.begin(); it != paths.end(); it++)
{
map <string, vector<string> > pathmap = (*it)->get_paths();
for (map <string, vector<string> >::const_iterator mapit = pathmap.begin(); mapit != pathmap.end(); mapit++)
for (vector<string>::const_iterator vecit = mapit->second.begin(); vecit != mapit->second.end(); vecit++)
include_paths.push_back(*vecit);
}
return include_paths;
}
void
ConfigFile::writeHooks(ostream &output) const
{
for (vector<Hook *>::const_iterator it = hooks.begin(); it != hooks.end(); it++)
{
map <string, string> hookmap = (*it)->get_hooks();
for (map <string, string>::const_iterator mapit = hookmap.begin(); mapit != hookmap.end(); mapit++)
output << "options_." << mapit->first << " = '" << mapit->second << "';" << endl;
}
}
void
ConfigFile::writeCluster(ostream &output) const
{
if (!parallel && !parallel_test)
return;
map<string, Cluster *>::const_iterator cluster_it;
if (cluster_name.empty())
cluster_it = clusters.find(firstClusterName);
else
cluster_it = clusters.find(cluster_name);
int i = 1;
for (map<string, SlaveNode *>::const_iterator it = slave_nodes.begin();
it != slave_nodes.end(); it++)
{
bool slave_node_in_member_nodes = false;
for (member_nodes_t::const_iterator itmn = cluster_it->second->member_nodes.begin();
itmn != cluster_it->second->member_nodes.end(); itmn++)
if (!it->first.compare(itmn->first))
slave_node_in_member_nodes = true;
if (!slave_node_in_member_nodes)
continue;
output << "options_.parallel";
if (i > 1)
output << "(" << i << ")";
i++;
output << " = struct('Local', ";
if (it->second->computerName.compare("localhost"))
output << "0, ";
else
output << "1, ";
output << "'ComputerName', '" << it->second->computerName << "', "
<< "'Port', '" << it->second->port << "', "
<< "'CPUnbr', [" << it->second->minCpuNbr << ":" << it->second->maxCpuNbr << "], "
<< "'UserName', '" << it->second->userName << "', "
<< "'Password', '" << it->second->password << "', "
<< "'RemoteDrive', '" << it->second->remoteDrive << "', "
<< "'RemoteDirectory', '" << it->second->remoteDirectory << "', "
<< "'DynarePath', '" << it->second->dynarePath << "', "
<< "'MatlabOctavePath', '" << it->second->matlabOctavePath << "', "
<< "'OperatingSystem', '" << it->second->operatingSystem << "', "
<< "'NodeWeight', '" << (cluster_it->second->member_nodes.find(it->first))->second << "', "
<< "'NumberOfThreadsPerJob', " << it->second->numberOfThreadsPerJob << ", ";
if (it->second->singleCompThread)
output << "'SingleCompThread', 'true');" << endl;
else
output << "'SingleCompThread', 'false');" << endl;
}
if (parallel_slave_open_mode)
output << "options_.parallel_info.leaveSlaveOpen = 1;" << endl;
output << "InitializeComputationalEnvironment();" << endl;
if (parallel_test)
output << "ErrorCode = AnalyseComputationalEnvironment(options_.parallel, options_.parallel_info);" << endl
<< "disp(['AnalyseComputationalEnvironment returned with Error Code: ' num2str(ErrorCode)]);" << endl
<< "diary off;" << endl
<< "return;" << endl;
}
void
ConfigFile::writeEndParallel(ostream &output) const
{
if ((!parallel && !parallel_test) || !parallel_slave_open_mode)
return;
output << "if options_.parallel_info.leaveSlaveOpen == 1" << endl
<< " closeSlave(options_.parallel,options_.parallel_info.RemoteTmpFolder);" << endl
<< "end" << endl;
}
/*
* Copyright (C) 2010-2017 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_FILE_HH
#define _CONFIG_FILE_HH
#include <map>
#include <vector>
#include "WarningConsolidation.hh"
using namespace std;
typedef map<string, double> member_nodes_t;
class Hook
{
public:
Hook(string &global_init_file_arg);
~Hook();
private:
map<string, string> hooks;
public:
inline map<string, string>
get_hooks()
{
return hooks;
};
};
class Path
{
public:
Path(vector<string> &includepath_arg);
~Path();
private:
map<string, vector<string> > paths;
public:
inline map<string, vector<string> >
get_paths()
{
return paths;
};
};
class SlaveNode
{
friend class ConfigFile;
public:
SlaveNode(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 &dynarePath_arg, string &matlabOctavePath_arg, bool singleCompThread_arg, int numberOfThreadsPerJob_arg,
string &operatingSystem_arg);
~SlaveNode();
protected:
const string computerName;
const string port;
int minCpuNbr;
int maxCpuNbr;
const string userName;
const string password;
const string remoteDrive;
const string remoteDirectory;
const string dynarePath;
const string matlabOctavePath;
const bool singleCompThread;
const int numberOfThreadsPerJob;
const string operatingSystem;
};
class Cluster
{
friend class ConfigFile;
public:
Cluster(member_nodes_t member_nodes_arg);
~Cluster();
protected:
member_nodes_t member_nodes;
};
//! The abstract representation of a "config" file
class ConfigFile
{
public:
ConfigFile(bool parallel_arg, bool parallel_test_arg, bool parallel_slave_open_mode_arg, const string &cluster_name);
~ConfigFile();
private:
const bool parallel;
const bool parallel_test;
const bool parallel_slave_open_mode;
const string cluster_name;
string firstClusterName;
//! Hooks
vector<Hook *> hooks;
//! Paths
vector<Path *> paths;
//! Cluster Table
map<string, Cluster *> clusters;
//! Node Map
map<string, SlaveNode *> slave_nodes;
//! Add Hooks
void addHooksConfFileElement(string &global_init_file);
//! Add Paths
void addPathsConfFileElement(vector<string> &includepath);
//! Add a SlaveNode or a Cluster object
void addParallelConfFileElement(bool inNode, bool inCluster, member_nodes_t member_nodes, string &name,
string &computerName, string port, int minCpuNbr, int maxCpuNbr, string &userName,
string &password, string &remoteDrive, string &remoteDirectory,
string &dynarePath, string &matlabOctavePath, bool singleCompThread, int numberOfThreadsPerJob,
string &operatingSystem);
public:
//! Parse config file
void getConfigFileInfo(const string &parallel_config_file);
//! Check Pass
void checkPass(WarningConsolidation &warnings) const;
//! Check Pass
void transformPass();
//! Get Path Info
vector<string> getIncludePaths() const;
//! Write any hooks
void writeHooks(ostream &output) const;
//! Create options_.parallel structure, write options
void writeCluster(ostream &output) const;
//! Close slave nodes if needed
void writeEndParallel(ostream &output) const;
};
#endif // ! CONFIG_FILE_HH
/*
* Copyright © 2010-2024 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/
#include <fstream>
#include <iostream>
#include <utility>
#ifdef _WIN32
# include <shlobj.h>
#endif
#include "Configuration.hh"
#include "DataTree.hh" // For strsplit()
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/tokenizer.hpp>
#pragma GCC diagnostic pop
Configuration::Path::Path(vector<string> includepath_arg)
{
if (includepath_arg.empty())
{
cerr << "ERROR: The Path must have an Include argument." << endl;
exit(EXIT_FAILURE);
}
paths["include"] = move(includepath_arg);
}
Configuration::FollowerNode::FollowerNode(string computerName_arg, string port_arg,
int minCpuNbr_arg, int maxCpuNbr_arg, string userName_arg,
string password_arg, string remoteDrive_arg,
string remoteDirectory_arg, string programPath_arg,
string programConfig_arg, string matlabOctavePath_arg,
bool singleCompThread_arg, int numberOfThreadsPerJob_arg,
string operatingSystem_arg) :
computerName {move(computerName_arg)},
port {move(port_arg)},
minCpuNbr {minCpuNbr_arg},
maxCpuNbr {maxCpuNbr_arg},
userName {move(userName_arg)},
password {move(password_arg)},
remoteDrive {move(remoteDrive_arg)},
remoteDirectory {move(remoteDirectory_arg)},
programPath {move(programPath_arg)},
programConfig {move(programConfig_arg)},
matlabOctavePath {move(matlabOctavePath_arg)},
singleCompThread {singleCompThread_arg},
numberOfThreadsPerJob {numberOfThreadsPerJob_arg},
operatingSystem {move(operatingSystem_arg)}
{
if (computerName.empty())
{
cerr << "ERROR: The node must have a ComputerName." << endl;
exit(EXIT_FAILURE);
}
if (!operatingSystem.empty())
if (operatingSystem != "windows" && operatingSystem != "unix")
{
cerr << "ERROR: The OperatingSystem must be either 'unix' or 'windows' (Case Sensitive)."
<< endl;
exit(EXIT_FAILURE);
}
}
Configuration::Cluster::Cluster(member_nodes_t member_nodes_arg) :
member_nodes {move(member_nodes_arg)}
{
if (member_nodes.empty())
{
cerr << "ERROR: The cluster must have at least one member node." << endl;
exit(EXIT_FAILURE);
}
}
Configuration::Configuration(bool parallel_arg, bool parallel_test_arg,
bool parallel_follower_open_mode_arg, bool parallel_use_psexec_arg,
string cluster_name_arg) :
parallel {parallel_arg},
parallel_test {parallel_test_arg},
parallel_follower_open_mode {parallel_follower_open_mode_arg},
parallel_use_psexec {parallel_use_psexec_arg},
cluster_name {move(cluster_name_arg)}
{
}
void
Configuration::getConfigFileInfo(const filesystem::path& conffile_option,
WarningConsolidation& warnings)
{
using namespace boost;
filesystem::path config_file {conffile_option};
if (config_file.empty())
{
config_file = findConfigFile("dynare.ini");
if (config_file.empty()) // Try old default location (Dynare ⩽ 5) for backward compatibility
{
filesystem::path old_default_config_file;
#ifdef _WIN32
array<wchar_t, MAX_PATH + 1> appdata;
if (SHGetFolderPathW(nullptr, CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY, nullptr,
SHGFP_TYPE_CURRENT, appdata.data())
== S_OK)
old_default_config_file = filesystem::path {appdata.data()} / "dynare.ini";
#else
if (auto home = getenv("HOME"); home)
old_default_config_file = filesystem::path {home} / ".dynare";
#endif
if (!old_default_config_file.empty() && exists(old_default_config_file))
{
warnings << "WARNING: the location " << old_default_config_file.string()
<< " for the configuration file is obsolete; please see the reference"
<< " manual for the new location." << endl;
config_file = old_default_config_file;
}
}
}
if (config_file.empty())
{
if (parallel || parallel_test)
{
cerr << "ERROR: the parallel or parallel_test option was passed but no configuration "
<< "file was found" << endl;
exit(EXIT_FAILURE);
}
else
return;
}
ifstream configFile;
configFile.open(config_file, fstream::in);
if (!configFile.is_open())
{
cerr << "ERROR: Couldn't open configuration file " << config_file.string() << endl;
exit(EXIT_FAILURE);
}
string name, computerName, port, userName, password, remoteDrive, remoteDirectory, programPath,
programConfig, matlabOctavePath, operatingSystem;
vector<string> includepath;
int minCpuNbr {0}, maxCpuNbr {0};
int numberOfThreadsPerJob {1};
bool singleCompThread {false};
member_nodes_t member_nodes;
bool inHooks {false}, inNode {false}, inCluster {false}, inPaths {false};
while (configFile.good())
{
string line;
getline(configFile, line);
trim(line);
if (line.empty() || !line.compare(0, 1, "#"))
continue;
if (line == "[node]" || line == "[cluster]" || line == "[hooks]" || line == "[paths]")
{
if (!includepath.empty())
// we were just in [paths]
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);
//! Reset communication vars / option defaults
if (line == "[hooks]")
{
inHooks = true;
inNode = false;
inCluster = false;
inPaths = false;
}
else if (line == "[node]")
{
inHooks = false;
inNode = true;
inCluster = false;
inPaths = false;
}
else if (line == "[paths]")
{
inHooks = false;
inNode = false;
inCluster = false;
inPaths = true;
}
else
{
inHooks = false;
inNode = false;
inCluster = true;
inPaths = false;
}
name = userName = computerName = port = password = remoteDrive = remoteDirectory
= programPath = programConfig = matlabOctavePath = operatingSystem = "";
includepath.clear();
minCpuNbr = maxCpuNbr = 0;
numberOfThreadsPerJob = 1;
singleCompThread = false;
member_nodes.clear();
}
else
{
vector<string> tokenizedLine;
split(tokenizedLine, line, is_any_of("="));
if (tokenizedLine.size() != 2)
{
cerr << "ERROR (in config file): Options should be formatted as 'option = value'."
<< endl;
exit(EXIT_FAILURE);
}
trim(tokenizedLine.front());
trim(tokenizedLine.back());
if (inHooks)
if (tokenizedLine.front() == "GlobalInitFile")
if (global_init_file.empty())
global_init_file = tokenizedLine.back();
else
{
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;
exit(EXIT_FAILURE);
}
else if (inPaths)
if (tokenizedLine.front() == "Include")
if (includepath.empty())
{
vector<string> tokenizedPath;
split(tokenizedPath, tokenizedLine.back(), is_any_of(":"), token_compress_on);
for (auto& it : tokenizedPath)
if (!it.empty())
{
trim(it);
includepath.push_back(it);
}
}
else
{
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;
exit(EXIT_FAILURE);
}
else if (tokenizedLine.front() == "Name")
name = tokenizedLine.back();
else if (tokenizedLine.front() == "CPUnbr")
{
vector<string> tokenizedCpuNbr;
split(tokenizedCpuNbr, tokenizedLine.back(), is_any_of(":"));
try
{
if (tokenizedCpuNbr.size() == 1)
{
minCpuNbr = 1;
maxCpuNbr = stoi(tokenizedCpuNbr.front());
}
else if (tokenizedCpuNbr.size() == 2 && tokenizedCpuNbr[0].at(0) == '['
&& tokenizedCpuNbr[1].at(tokenizedCpuNbr[1].size() - 1) == ']')
{
tokenizedCpuNbr[0].erase(0, 1);
tokenizedCpuNbr[1].erase(tokenizedCpuNbr[1].size() - 1, 1);
minCpuNbr = stoi(tokenizedCpuNbr[0]);
maxCpuNbr = stoi(tokenizedCpuNbr[1]);
}
}
catch (const invalid_argument&)
{
cerr << "ERROR: Could not convert value to integer for CPUnbr." << endl;
exit(EXIT_FAILURE);
}
if (minCpuNbr <= 0 || maxCpuNbr <= 0)
{
cerr << "ERROR: Syntax for the CPUnbr option is as follows:" << endl
<< " 1) CPUnbr = <int>" << endl
<< " or 2) CPUnbr = [<int>:<int>]" << endl
<< " where <int> is an Integer > 0." << endl;
exit(EXIT_FAILURE);
}
minCpuNbr--;
maxCpuNbr--;
if (minCpuNbr > maxCpuNbr)
{
int tmp = maxCpuNbr;
maxCpuNbr = minCpuNbr;
minCpuNbr = tmp;
}
}
else if (tokenizedLine.front() == "Port")
port = tokenizedLine.back();
else if (tokenizedLine.front() == "ComputerName")
computerName = tokenizedLine.back();
else if (tokenizedLine.front() == "UserName")
userName = tokenizedLine.back();
else if (tokenizedLine.front() == "Password")
password = tokenizedLine.back();
else if (tokenizedLine.front() == "RemoteDrive")
remoteDrive = tokenizedLine.back();
else if (tokenizedLine.front() == "RemoteDirectory")
remoteDirectory = tokenizedLine.back();
else if (tokenizedLine.front() == "DynarePath" || tokenizedLine.front() == "ProgramPath")
programPath = tokenizedLine.back();
else if (tokenizedLine.front() == "ProgramConfig")
programConfig = tokenizedLine.back();
else if (tokenizedLine.front() == "MatlabOctavePath")
matlabOctavePath = tokenizedLine.back();
else if (tokenizedLine.front() == "NumberOfThreadsPerJob")
numberOfThreadsPerJob = stoi(tokenizedLine.back());
else if (tokenizedLine.front() == "SingleCompThread")
if (tokenizedLine.back() == "true")
singleCompThread = true;
else if (tokenizedLine.back() == "false")
singleCompThread = false;
else
{
cerr << "ERROR (in config file): The value passed to SingleCompThread may only be "
"'true' or 'false'."
<< endl;
exit(EXIT_FAILURE);
}
else if (tokenizedLine.front() == "OperatingSystem")
operatingSystem = tokenizedLine.back();
else if (tokenizedLine.front() == "Members")
{
char_separator sep(" ,;", "()", drop_empty_tokens);
tokenizer tokens(tokenizedLine.back(), sep);
string node_name;
for (bool begin_weight {false}; const auto& token : tokens)
{
if (token == "(")
{
begin_weight = true;
continue;
}
else if (token == ")")
{
node_name.clear();
begin_weight = false;
continue;
}
if (!begin_weight)
{
if (!node_name.empty())
{
if (member_nodes.contains(node_name))
{
cerr << "ERROR (in config file): Node entered twice in specification "
"of cluster."
<< endl;
exit(EXIT_FAILURE);
}
else
member_nodes[node_name] = 1.0;
}
node_name = token;
}
else
try
{
auto weight = stod(token);
if (weight <= 0)
{
cerr << "ERROR (in config file): Misspecification of weights passed to "
"Members option."
<< endl;
exit(EXIT_FAILURE);
}
member_nodes[node_name] = weight;
}
catch (const invalid_argument&)
{
cerr << "ERROR (in config file): Misspecification of weights passed to "
"Members option."
<< endl;
exit(EXIT_FAILURE);
}
}
if (!node_name.empty())
{
if (!member_nodes.contains(node_name))
member_nodes[node_name] = 1.0;
else
{
cerr << "ERROR (in config file): Node entered twice in specification of "
"cluster."
<< endl;
exit(EXIT_FAILURE);
}
}
}
else
{
cerr << "ERROR (in config file): Option " << tokenizedLine.front() << " is invalid."
<< endl;
exit(EXIT_FAILURE);
}
}
}
if (!includepath.empty())
addPathsConfFileElement(includepath);
else
addParallelConfFileElement(inNode, inCluster, member_nodes, name, computerName, port, minCpuNbr,
maxCpuNbr, userName, password, remoteDrive, remoteDirectory,
programPath, programConfig, matlabOctavePath, singleCompThread,
numberOfThreadsPerJob, operatingSystem);
configFile.close();
}
void
Configuration::addPathsConfFileElement(vector<string> includepath)
{
if (includepath.empty())
{
cerr << "ERROR: The path to be included must be passed to the Include option." << endl;
exit(EXIT_FAILURE);
}
else
paths.emplace_back(move(includepath));
}
void
Configuration::addParallelConfFileElement(bool inNode, bool inCluster,
const member_nodes_t& member_nodes, const string& name,
const string& computerName, const string& port,
int minCpuNbr, int maxCpuNbr, const string& userName,
const string& password, const string& remoteDrive,
const string& remoteDirectory, const string& programPath,
const string& programConfig,
const string& matlabOctavePath, bool singleCompThread,
int numberOfThreadsPerJob, const string& operatingSystem)
{
//! ADD NODE
if (inNode)
if (!member_nodes.empty())
{
cerr << "Invalid option passed to [node]." << endl;
exit(EXIT_FAILURE);
}
else if (name.empty() || follower_nodes.contains(name))
{
cerr << "ERROR: Every node must be assigned a unique name." << endl;
exit(EXIT_FAILURE);
}
else
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())
{
cerr << "Invalid option passed to [cluster]." << endl;
exit(EXIT_FAILURE);
}
else if (name.empty() || clusters.contains(name))
{
cerr << "ERROR: The cluster must be assigned a unique name." << endl;
exit(EXIT_FAILURE);
}
else
{
if (clusters.empty())
firstClusterName = name;
clusters.emplace(name, member_nodes);
}
}
}
void
Configuration::checkPass([[maybe_unused]] WarningConsolidation& warnings) const
{
if (!parallel && !parallel_test)
return;
//! Check Follower Nodes
if (follower_nodes.empty())
{
cerr << "ERROR: At least one node must be defined in the config file." << endl;
exit(EXIT_FAILURE);
}
for (const auto& follower_node : follower_nodes)
{
#if !defined(_WIN32) && !defined(__CYGWIN32__)
// For Linux/Mac, check that cpuNbr starts at 0
if (follower_node.second.minCpuNbr != 0)
warnings << "WARNING: On Unix-based operating systems, you cannot specify the CPU that is "
<< "used in parallel processing. This will be adjusted for you such that the "
<< "same number of CPUs are used." << endl;
#endif
if (!follower_node.second.port.empty())
try
{
stoi(follower_node.second.port);
}
catch (const invalid_argument&)
{
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;
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;
exit(EXIT_FAILURE);
}
}
else
{
if (follower_node.second.userName.empty())
{
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;
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;
exit(EXIT_FAILURE);
}
}
#if defined(_WIN32) || defined(__CYGWIN32__)
if (follower_node.second.operatingSystem.empty())
{
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;
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;
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;
exit(EXIT_FAILURE);
}
}
}
//! Check Clusters
if (clusters.empty())
{
cerr << "ERROR: At least one cluster must be defined in the config file." << endl;
exit(EXIT_FAILURE);
}
if (!cluster_name.empty() && !clusters.contains(cluster_name))
{
cerr << "ERROR: Cluster Name " << cluster_name << " was not found in the config file."
<< endl;
exit(EXIT_FAILURE);
}
for (const auto& cluster : clusters)
for (const auto& itmn : cluster.second.member_nodes)
if (!follower_nodes.contains(itmn.first))
{
cerr << "Error: node " << itmn.first << " specified in cluster " << cluster.first
<< " was not found" << endl;
exit(EXIT_FAILURE);
}
}
void
Configuration::transformPass()
{
/* If the user did not specify the GlobalInitFile option, use global_init.m in configuration
directory if it exists */
if (auto default_global_init_file = findConfigFile("global_init.m");
global_init_file.empty() && !default_global_init_file.empty())
global_init_file = default_global_init_file.string();
if (!parallel && !parallel_test)
return;
#if !defined(_WIN32) && !defined(__CYGWIN32__)
// For Linux/Mac, check that cpuNbr starts at 0
for (auto& it : follower_nodes)
if (it.second.minCpuNbr != 0)
{
it.second.maxCpuNbr = it.second.maxCpuNbr - it.second.minCpuNbr;
it.second.minCpuNbr = 0;
}
#endif
auto& cluster = cluster_name.empty() ? clusters.at(firstClusterName) : clusters.at(cluster_name);
double weight_denominator {0.0};
for (const auto& [name, weight] : cluster.member_nodes)
weight_denominator += weight;
for (auto& [name, weight] : cluster.member_nodes)
weight /= weight_denominator;
}
vector<filesystem::path>
Configuration::getIncludePaths() const
{
vector<filesystem::path> include_paths;
for (const auto& path : paths)
for (const auto& mapit : path.get_paths())
for (const auto& vecit : mapit.second)
include_paths.emplace_back(vecit);
return include_paths;
}
void
Configuration::writeHooks(ostream& output) const
{
if (!global_init_file.empty())
output << "options_.global_init_file = '" << global_init_file << "';" << endl;
}
void
Configuration::writeCluster(ostream& output) const
{
if (!parallel && !parallel_test)
return;
const auto& cluster
= cluster_name.empty() ? clusters.at(firstClusterName) : clusters.at(cluster_name);
for (int i {1}; const auto& [name, node] : follower_nodes)
{
if (!cluster.member_nodes.contains(name))
continue; // Skip nodes not in the selected cluster
output << "options_.parallel";
if (i > 1)
output << "(" << i << ")";
i++;
output << " = struct('Local', " << noboolalpha << (node.computerName == "localhost") << ", "
<< "'ComputerName', '" << node.computerName << "', "
<< "'Port', '" << node.port << "', "
<< "'CPUnbr', [" << node.minCpuNbr << ":" << node.maxCpuNbr << "], "
<< "'UserName', '" << node.userName << "', "
<< "'Password', '" << node.password << "', "
<< "'RemoteDrive', '" << node.remoteDrive << "', "
<< "'RemoteDirectory', '" << node.remoteDirectory
<< "', "
// The following should be switched back to “ProgramPath” once we move to Dragonfly
<< "'DynarePath', '" << node.programPath << "', "
<< "'ProgramConfig', '" << node.programConfig << "', "
<< "'MatlabOctavePath', '" << node.matlabOctavePath << "', "
<< "'OperatingSystem', '" << node.operatingSystem << "', "
<< "'NodeWeight', '" << cluster.member_nodes.at(name) << "', "
<< "'NumberOfThreadsPerJob', " << node.numberOfThreadsPerJob << ", "
<< "'SingleCompThread', '" << boolalpha << node.singleCompThread << "');" << endl;
}
// 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)
output << "options_.parallel_info.use_psexec = false;" << endl;
output << "options_.parallel_info.console_mode= isoctave;" << endl;
output << "InitializeComputationalEnvironment();" << endl;
if (parallel_test)
output
<< "ErrorCode = AnalyseComputationalEnvironment(options_.parallel, options_.parallel_info);"
<< endl
<< "disp(['AnalyseComputationalEnvironment returned with Error Code: ' "
"num2str(ErrorCode)]);"
<< endl
<< "diary off;" << endl
<< "return;" << endl;
}
void
Configuration::writeEndParallel(ostream& output) const
{
if ((!parallel && !parallel_test) || !parallel_follower_open_mode)
return;
output << "if options_.parallel_info.leaveSlaveOpen == 1" << endl
<< " closeSlave(options_.parallel,options_.parallel_info.RemoteTmpFolder);" << endl
<< "end" << endl;
}
filesystem::path
Configuration::findConfigFile(const string& filename)
{
#ifdef _WIN32
array<wchar_t, MAX_PATH + 1> appdata;
if (SHGetFolderPathW(nullptr, CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY, nullptr, SHGFP_TYPE_CURRENT,
appdata.data())
== S_OK)
{
filesystem::path candidate {filesystem::path {appdata.data()} / "dynare" / filename};
if (exists(candidate))
return candidate;
}
#else
filesystem::path xdg_config_home;
if (auto xdg_config_home_env = getenv("XDG_CONFIG_HOME"); xdg_config_home_env)
xdg_config_home = xdg_config_home_env;
if (auto home = getenv("HOME"); xdg_config_home.empty() && home)
xdg_config_home = filesystem::path {home} / ".config";
if (!xdg_config_home.empty())
{
filesystem::path candidate {xdg_config_home / "dynare" / filename};
if (exists(candidate))
return candidate;
}
string xdg_config_dirs;
if (auto xdg_config_dirs_env = getenv("XDG_CONFIG_DIRS"); xdg_config_dirs_env)
xdg_config_dirs = xdg_config_dirs_env;
if (xdg_config_dirs.empty())
xdg_config_dirs = "/etc/xdg";
for (const auto& dir : DataTree::strsplit(xdg_config_dirs, ':'))
{
filesystem::path candidate {filesystem::path {dir} / "dynare" / filename};
if (exists(candidate))
return candidate;
}
#endif
return {};
}
/*
* Copyright © 2010-2023 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef CONFIGURATION_HH
#define CONFIGURATION_HH
#include <filesystem>
#include <map>
#include <vector>
#include "WarningConsolidation.hh"
using namespace std;
/* The abstract representation of the configuration.
Merges information from the command-line and from the configuration file. */
class Configuration
{
public:
Configuration(bool parallel_arg, bool parallel_test_arg, bool parallel_follower_open_mode_arg,
bool parallel_use_psexec_arg, string cluster_name);
private:
using member_nodes_t = map<string, double>;
class Path
{
public:
explicit Path(vector<string> includepath_arg);
[[nodiscard]] map<string, vector<string>>
get_paths() const
{
return paths;
}
private:
map<string, vector<string>> paths;
};
struct 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);
const string computerName, port;
int minCpuNbr, maxCpuNbr;
const string userName, password;
const string remoteDrive, remoteDirectory;
const string programPath, programConfig, matlabOctavePath;
const bool singleCompThread;
const int numberOfThreadsPerJob;
const string operatingSystem;
};
struct Cluster
{
explicit Cluster(member_nodes_t member_nodes_arg);
member_nodes_t member_nodes;
};
const bool parallel, parallel_test, parallel_follower_open_mode, parallel_use_psexec;
const string cluster_name;
string firstClusterName;
//! Hooks
string global_init_file;
//! Paths
vector<Path> paths;
//! Cluster Table
map<string, Cluster> clusters;
//! Node Map
map<string, FollowerNode> follower_nodes;
//! 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);
/* Given a filename (e.g. dynare.ini), looks for it in the configuration directory:
– if under Linux or macOS, look into the “dynare” subdirectory of the XDG
configuration directories (following the default values and the precedence order specified in
the XDG specification)
– if under Windows, look into %APPDATA%\dynare\
The returned path will be empty if the file is not found. */
[[nodiscard]] static filesystem::path findConfigFile(const string& filename);
public:
//! Parse config file
void getConfigFileInfo(const filesystem::path& conffile_option, WarningConsolidation& warnings);
//! Check Pass
void checkPass(WarningConsolidation& warnings) const;
//! Check Pass
void transformPass();
//! Get Path Info
[[nodiscard]] vector<filesystem::path> getIncludePaths() const;
//! Write any hooks
void writeHooks(ostream& output) const;
//! Create options_.parallel structure, write options
void writeCluster(ostream& output) const;
//! Close follower nodes if needed
void writeEndParallel(ostream& output) const;
};
#endif
/* /*
* Copyright (C) 2003-2016 Dynare Team * Copyright © 2003-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -14,26 +14,29 @@ ...@@ -14,26 +14,29 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>. * along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include <cstdlib> #include <algorithm>
#include <cassert> #include <cassert>
#include <cstdlib>
#include <filesystem>
#include <fstream>
#include <iostream> #include <iostream>
#include <iterator>
#include <ranges>
#include "DataTree.hh" #include "DataTree.hh"
DataTree::DataTree(SymbolTable &symbol_table_arg, bool DataTree::no_commutativity = false;
NumericalConstants &num_constants_arg,
ExternalFunctionsTable &external_functions_table_arg) : void
symbol_table(symbol_table_arg), DataTree::initConstants()
num_constants(num_constants_arg),
external_functions_table(external_functions_table_arg),
node_counter(0)
{ {
Zero = AddNonNegativeConstant("0"); Zero = AddNonNegativeConstant("0");
One = AddNonNegativeConstant("1"); One = AddNonNegativeConstant("1");
Two = AddNonNegativeConstant("2"); Two = AddNonNegativeConstant("2");
Three = AddNonNegativeConstant("3");
MinusOne = AddUMinus(One); MinusOne = AddUMinus(One);
...@@ -44,77 +47,173 @@ DataTree::DataTree(SymbolTable &symbol_table_arg, ...@@ -44,77 +47,173 @@ DataTree::DataTree(SymbolTable &symbol_table_arg,
Pi = AddNonNegativeConstant("3.141592653589793"); Pi = AddNonNegativeConstant("3.141592653589793");
} }
DataTree::~DataTree() DataTree::DataTree(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg,
ExternalFunctionsTable& external_functions_table_arg,
HeterogeneityTable& heterogeneity_table_arg, bool is_dynamic_arg) :
symbol_table {symbol_table_arg},
num_constants {num_constants_arg},
external_functions_table {external_functions_table_arg},
heterogeneity_table {heterogeneity_table_arg},
is_dynamic {is_dynamic_arg}
{ {
for (node_list_t::iterator it = node_list.begin(); it != node_list.end(); it++) initConstants();
delete *it;
} }
expr_t DataTree::DataTree(const DataTree& d) :
symbol_table {d.symbol_table},
num_constants {d.num_constants},
external_functions_table {d.external_functions_table},
heterogeneity_table {d.heterogeneity_table},
is_dynamic {d.is_dynamic},
local_variables_vector {d.local_variables_vector}
{
// Constants must be initialized first because they are used in some Add* methods
initConstants();
// See commment in DataTree::operator=() for the rationale
for (int symb_id : d.local_variables_vector)
local_variables_table[symb_id] = d.local_variables_table.at(symb_id)->clone(*this);
for (const auto& it : d.node_list)
it->clone(*this);
assert(node_list.size() == d.node_list.size());
}
DataTree&
DataTree::operator=(const DataTree& d)
{
assert(&symbol_table == &d.symbol_table);
assert(&num_constants == &d.num_constants);
assert(&external_functions_table == &d.external_functions_table);
assert(&heterogeneity_table == &d.heterogeneity_table);
assert(is_dynamic == d.is_dynamic);
num_const_node_map.clear();
variable_node_map.clear();
unary_op_node_map.clear();
binary_op_node_map.clear();
trinary_op_node_map.clear();
external_function_node_map.clear();
var_expectation_node_map.clear();
pac_expectation_node_map.clear();
pac_target_nonstationary_node_map.clear();
first_deriv_external_function_node_map.clear();
second_deriv_external_function_node_map.clear();
node_list.clear();
// Constants must be initialized first because they are used in some Add* methods
initConstants();
/* Model local variables must be next, because they can be evaluated in Add*
methods when the model equations are added. They need to be cloned in
order of appearance in the model block (hence with
local_variables_vector), because if there is a model_local_variable statement
the symbol IDs ordering may not be the right one (see dynare#1782) */
for (int symb_id : d.local_variables_vector)
local_variables_table[symb_id] = d.local_variables_table.at(symb_id)->clone(*this);
for (const auto& it : d.node_list)
it->clone(*this);
assert(node_list.size() == d.node_list.size());
local_variables_vector = d.local_variables_vector;
return *this;
}
NumConstNode*
DataTree::AddNonNegativeConstant(const string& value) DataTree::AddNonNegativeConstant(const string& value)
{ {
int id = num_constants.AddNonNegativeConstant(value); int id = num_constants.AddNonNegativeConstant(value);
num_const_node_map_t::iterator it = num_const_node_map.find(id); if (auto it = num_const_node_map.find(id); it != num_const_node_map.end())
if (it != num_const_node_map.end())
return it->second; return it->second;
else
return new NumConstNode(*this, id); auto sp = make_unique<NumConstNode>(*this, node_list.size(), id);
auto p = sp.get();
node_list.push_back(move(sp));
num_const_node_map.emplace(id, p);
return p;
} }
VariableNode* VariableNode*
DataTree::AddVariableInternal(int symb_id, int lag) DataTree::AddVariable(int symb_id, int lag)
{ {
variable_node_map_t::iterator it = variable_node_map.find(make_pair(symb_id, lag)); if (lag != 0 && !is_dynamic)
if (it != variable_node_map.end()) {
cerr << "Leads/lags not authorized in this DataTree" << endl;
exit(EXIT_FAILURE);
}
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);
auto p = sp.get();
node_list.push_back(move(sp));
variable_node_map.try_emplace({symb_id, lag}, p);
return p;
}
VariableNode*
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;
exit(EXIT_FAILURE);
}
return it->second; return it->second;
else
return new VariableNode(*this, symb_id, lag);
} }
bool bool
DataTree::ParamUsedWithLeadLagInternal() const DataTree::ParamUsedWithLeadLagInternal() const
{ {
for (variable_node_map_t::const_iterator it = variable_node_map.begin(); for (const auto& [symb_lag, expr] : variable_node_map)
it != variable_node_map.end(); it++) if (symbol_table.getType(symb_lag.first) == SymbolType::parameter && symb_lag.second != 0)
if (symbol_table.getType(it->first.first) == eParameter && it->first.second != 0)
return true; return true;
return false; return false;
} }
VariableNode *
DataTree::AddVariable(int symb_id, int lag)
{
assert(lag == 0);
return AddVariableInternal(symb_id, lag);
}
expr_t expr_t
DataTree::AddPlus(expr_t iArg1, expr_t iArg2) DataTree::AddPlus(expr_t iArg1, expr_t iArg2)
{ {
if (iArg1 != Zero && iArg2 != Zero) if (iArg2 == Zero)
{ return iArg1;
if (iArg1 == Zero)
return iArg2;
// Simplify x+(-y) in x-y // Simplify x+(-y) in x-y
UnaryOpNode *uarg2 = dynamic_cast<UnaryOpNode *>(iArg2); if (auto uarg2 = dynamic_cast<UnaryOpNode*>(iArg2);
if (uarg2 != NULL && uarg2->get_op_code() == oUminus) uarg2 && uarg2->op_code == UnaryOpcode::uminus)
return AddMinus(iArg1, uarg2->get_arg()); return AddMinus(iArg1, uarg2->arg);
// Simplify (-x)+y in y-x
if (auto uarg1 = dynamic_cast<UnaryOpNode*>(iArg1);
uarg1 && uarg1->op_code == UnaryOpcode::uminus)
return AddMinus(iArg2, uarg1->arg);
// Simplify (x-y)+y in x
if (auto barg1 = dynamic_cast<BinaryOpNode*>(iArg1);
barg1 && barg1->op_code == BinaryOpcode::minus && barg1->arg2 == iArg2)
return barg1->arg1;
// Simplify y+(x-y) in x
if (auto barg2 = dynamic_cast<BinaryOpNode*>(iArg2);
barg2 && barg2->op_code == BinaryOpcode::minus && barg2->arg2 == iArg1)
return barg2->arg1;
// To treat commutativity of "+" // To treat commutativity of "+"
// Nodes iArg1 and iArg2 are sorted by index // Nodes iArg1 and iArg2 are sorted by index
if (iArg1->idx > iArg2->idx) if (iArg1->idx > iArg2->idx && !no_commutativity) // NOLINT(clang-analyzer-core.NullDereference)
{ swap(iArg1, iArg2);
expr_t tmp = iArg1; return AddBinaryOp(iArg1, BinaryOpcode::plus, iArg2);
iArg1 = iArg2;
iArg2 = tmp;
}
return AddBinaryOp(iArg1, oPlus, iArg2);
}
else if (iArg1 != Zero)
return iArg1;
else if (iArg2 != Zero)
return iArg2;
else
return Zero;
} }
expr_t expr_t
...@@ -129,56 +228,74 @@ DataTree::AddMinus(expr_t iArg1, expr_t iArg2) ...@@ -129,56 +228,74 @@ DataTree::AddMinus(expr_t iArg1, expr_t iArg2)
if (iArg1 == iArg2) if (iArg1 == iArg2)
return Zero; return Zero;
return AddBinaryOp(iArg1, oMinus, iArg2); // Simplify x-(-y) in x+y
if (auto uarg2 = dynamic_cast<UnaryOpNode*>(iArg2);
uarg2 && uarg2->op_code == UnaryOpcode::uminus)
return AddPlus(iArg1, uarg2->arg);
// Simplify (x+y)-y and (y+x)-y in x
if (auto barg1 = dynamic_cast<BinaryOpNode*>(iArg1);
barg1 && barg1->op_code == BinaryOpcode::plus)
{
if (barg1->arg2 == iArg2)
return barg1->arg1;
if (barg1->arg1 == iArg2)
return barg1->arg2;
}
return AddBinaryOp(iArg1, BinaryOpcode::minus, iArg2);
} }
expr_t expr_t
DataTree::AddUMinus(expr_t iArg1) DataTree::AddUMinus(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
{ return Zero;
// Simplify -(-x) in x // Simplify -(-x) in x
UnaryOpNode *uarg = dynamic_cast<UnaryOpNode *>(iArg1); if (auto uarg = dynamic_cast<UnaryOpNode*>(iArg1); uarg && uarg->op_code == UnaryOpcode::uminus)
if (uarg != NULL && uarg->get_op_code() == oUminus) return uarg->arg;
return uarg->get_arg();
return AddUnaryOp(oUminus, iArg1); return AddUnaryOp(UnaryOpcode::uminus, iArg1);
}
else
return Zero;
} }
expr_t expr_t
DataTree::AddTimes(expr_t iArg1, expr_t iArg2) DataTree::AddTimes(expr_t iArg1, expr_t iArg2)
{ {
if (iArg1 == Zero || iArg2 == Zero)
return Zero;
if (iArg1 == One)
return iArg2;
if (iArg2 == One)
return iArg1;
if (iArg1 == MinusOne) if (iArg1 == MinusOne)
return AddUMinus(iArg2); return AddUMinus(iArg2);
else if (iArg2 == MinusOne)
if (iArg2 == MinusOne)
return AddUMinus(iArg1); return AddUMinus(iArg1);
else if (iArg1 != Zero && iArg1 != One && iArg2 != Zero && iArg2 != One)
{ // Simplify (x/y)*y in x
if (auto barg1 = dynamic_cast<BinaryOpNode*>(iArg1);
barg1 && barg1->op_code == BinaryOpcode::divide && barg1->arg2 == iArg2)
return barg1->arg1;
// Simplify y*(x/y) in x
if (auto barg2 = dynamic_cast<BinaryOpNode*>(iArg2);
barg2 && barg2->op_code == BinaryOpcode::divide && barg2->arg2 == iArg1)
return barg2->arg1;
// To treat commutativity of "*" // To treat commutativity of "*"
// Nodes iArg1 and iArg2 are sorted by index // Nodes iArg1 and iArg2 are sorted by index
if (iArg1->idx > iArg2->idx) if (iArg1->idx > iArg2->idx && !no_commutativity) // NOLINT(clang-analyzer-core.NullDereference)
{ swap(iArg1, iArg2);
expr_t tmp = iArg1; return AddBinaryOp(iArg1, BinaryOpcode::times, iArg2);
iArg1 = iArg2;
iArg2 = tmp;
}
return AddBinaryOp(iArg1, oTimes, iArg2);
}
else if (iArg1 != Zero && iArg1 != One && iArg2 == One)
return iArg1;
else if (iArg2 != Zero && iArg2 != One && iArg1 == One)
return iArg2;
else if (iArg2 == One && iArg1 == One)
return One;
else
return Zero;
} }
expr_t expr_t
DataTree::AddDivide(expr_t iArg1, expr_t iArg2) throw (DivisionByZeroException) DataTree::AddDivide(expr_t iArg1, expr_t iArg2) noexcept(false)
{ {
if (iArg2 == One) if (iArg2 == One)
return iArg1; return iArg1;
...@@ -196,219 +313,280 @@ DataTree::AddDivide(expr_t iArg1, expr_t iArg2) throw (DivisionByZeroException) ...@@ -196,219 +313,280 @@ DataTree::AddDivide(expr_t iArg1, expr_t iArg2) throw (DivisionByZeroException)
if (iArg1 == iArg2) if (iArg1 == iArg2)
return One; return One;
return AddBinaryOp(iArg1, oDivide, iArg2); // Simplify x/(1/y) in x*y
if (auto barg2 = dynamic_cast<BinaryOpNode*>(iArg2);
barg2 && barg2->op_code == BinaryOpcode::divide && barg2->arg1 == One)
return AddTimes(iArg1, barg2->arg2);
// Simplify (x*y)/y and (y*x)/y in x
if (auto barg1 = dynamic_cast<BinaryOpNode*>(iArg1);
barg1 && barg1->op_code == BinaryOpcode::times)
{
if (barg1->arg2 == iArg2)
return barg1->arg1;
if (barg1->arg1 == iArg2)
return barg1->arg2;
}
return AddBinaryOp(iArg1, BinaryOpcode::divide, iArg2);
} }
expr_t expr_t
DataTree::AddLess(expr_t iArg1, expr_t iArg2) DataTree::AddLess(expr_t iArg1, expr_t iArg2)
{ {
return AddBinaryOp(iArg1, oLess, iArg2); return AddBinaryOp(iArg1, BinaryOpcode::less, iArg2);
} }
expr_t expr_t
DataTree::AddGreater(expr_t iArg1, expr_t iArg2) DataTree::AddGreater(expr_t iArg1, expr_t iArg2)
{ {
return AddBinaryOp(iArg1, oGreater, iArg2); return AddBinaryOp(iArg1, BinaryOpcode::greater, iArg2);
} }
expr_t expr_t
DataTree::AddLessEqual(expr_t iArg1, expr_t iArg2) DataTree::AddLessEqual(expr_t iArg1, expr_t iArg2)
{ {
return AddBinaryOp(iArg1, oLessEqual, iArg2); return AddBinaryOp(iArg1, BinaryOpcode::lessEqual, iArg2);
} }
expr_t expr_t
DataTree::AddGreaterEqual(expr_t iArg1, expr_t iArg2) DataTree::AddGreaterEqual(expr_t iArg1, expr_t iArg2)
{ {
return AddBinaryOp(iArg1, oGreaterEqual, iArg2); return AddBinaryOp(iArg1, BinaryOpcode::greaterEqual, iArg2);
} }
expr_t expr_t
DataTree::AddEqualEqual(expr_t iArg1, expr_t iArg2) DataTree::AddEqualEqual(expr_t iArg1, expr_t iArg2)
{ {
return AddBinaryOp(iArg1, oEqualEqual, iArg2); return AddBinaryOp(iArg1, BinaryOpcode::equalEqual, iArg2);
} }
expr_t expr_t
DataTree::AddDifferent(expr_t iArg1, expr_t iArg2) DataTree::AddDifferent(expr_t iArg1, expr_t iArg2)
{ {
return AddBinaryOp(iArg1, oDifferent, iArg2); return AddBinaryOp(iArg1, BinaryOpcode::different, iArg2);
} }
expr_t expr_t
DataTree::AddPower(expr_t iArg1, expr_t iArg2) DataTree::AddPower(expr_t iArg1, expr_t iArg2)
{ {
if (iArg1 != Zero && iArg2 != Zero && iArg1 != One && iArg2 != One) // This one comes first, because 0⁰=1
return AddBinaryOp(iArg1, oPower, iArg2); if (iArg2 == Zero)
else if (iArg1 == One)
return One;
else if (iArg2 == One)
return iArg1;
else if (iArg2 == Zero)
return One; return One;
else
if (iArg1 == Zero)
return Zero; return Zero;
if (iArg1 == One)
return One;
if (iArg2 == One)
return iArg1;
return AddBinaryOp(iArg1, BinaryOpcode::power, iArg2);
} }
expr_t expr_t
DataTree::AddPowerDeriv(expr_t iArg1, expr_t iArg2, int powerDerivOrder) DataTree::AddPowerDeriv(expr_t iArg1, expr_t iArg2, int powerDerivOrder)
{ {
assert(powerDerivOrder > 0); assert(powerDerivOrder > 0);
return AddBinaryOp(iArg1, oPowerDeriv, iArg2, powerDerivOrder); return AddBinaryOp(iArg1, BinaryOpcode::powerDeriv, iArg2, powerDerivOrder);
}
expr_t
DataTree::AddDiff(expr_t iArg1)
{
if (iArg1->maxLead() > 0)
// Issue preprocessor#21: always expand diffs with leads
return AddMinus(iArg1, iArg1->decreaseLeadsLags(1));
return AddUnaryOp(UnaryOpcode::diff, iArg1);
}
expr_t
DataTree::AddAdl(expr_t iArg1, const string& name, const vector<int>& lags)
{
return AddUnaryOp(UnaryOpcode::adl, iArg1, 0, 0, 0, name, lags);
} }
expr_t expr_t
DataTree::AddExp(expr_t iArg1) DataTree::AddExp(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
return AddUnaryOp(oExp, iArg1);
else
return One; return One;
return AddUnaryOp(UnaryOpcode::exp, iArg1);
} }
expr_t expr_t
DataTree::AddLog(expr_t iArg1) DataTree::AddLog(expr_t iArg1)
{ {
if (iArg1 != Zero && iArg1 != One) if (iArg1 == One)
return AddUnaryOp(oLog, iArg1);
else if (iArg1 == One)
return Zero; return Zero;
else
if (iArg1 == Zero)
{ {
cerr << "ERROR: log(0) not defined!" << endl; cerr << "ERROR: log(0) not defined!" << endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Simplify log(1/x) in −log(x)
if (auto barg1 = dynamic_cast<BinaryOpNode*>(iArg1);
barg1 && barg1->op_code == BinaryOpcode::divide && barg1->arg1 == One)
return AddUMinus(AddLog(barg1->arg2));
return AddUnaryOp(UnaryOpcode::log, iArg1);
} }
expr_t expr_t
DataTree::AddLog10(expr_t iArg1) DataTree::AddLog10(expr_t iArg1)
{ {
if (iArg1 != Zero && iArg1 != One) if (iArg1 == One)
return AddUnaryOp(oLog10, iArg1);
else if (iArg1 == One)
return Zero; return Zero;
else
if (iArg1 == Zero)
{ {
cerr << "ERROR: log10(0) not defined!" << endl; cerr << "ERROR: log10(0) not defined!" << endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Simplify log₁₀(1/x) in −log₁₀(x)
if (auto barg1 = dynamic_cast<BinaryOpNode*>(iArg1);
barg1 && barg1->op_code == BinaryOpcode::divide && barg1->arg1 == One)
return AddUMinus(AddLog10(barg1->arg2));
return AddUnaryOp(UnaryOpcode::log10, iArg1);
} }
expr_t expr_t
DataTree::AddCos(expr_t iArg1) DataTree::AddCos(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
return AddUnaryOp(oCos, iArg1);
else
return One; return One;
return AddUnaryOp(UnaryOpcode::cos, iArg1);
} }
expr_t expr_t
DataTree::AddSin(expr_t iArg1) DataTree::AddSin(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
return AddUnaryOp(oSin, iArg1);
else
return Zero; return Zero;
return AddUnaryOp(UnaryOpcode::sin, iArg1);
} }
expr_t expr_t
DataTree::AddTan(expr_t iArg1) DataTree::AddTan(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
return AddUnaryOp(oTan, iArg1);
else
return Zero; return Zero;
return AddUnaryOp(UnaryOpcode::tan, iArg1);
} }
expr_t expr_t
DataTree::AddAcos(expr_t iArg1) DataTree::AddAcos(expr_t iArg1)
{ {
if (iArg1 != One) if (iArg1 == One)
return AddUnaryOp(oAcos, iArg1);
else
return Zero; return Zero;
return AddUnaryOp(UnaryOpcode::acos, iArg1);
} }
expr_t expr_t
DataTree::AddAsin(expr_t iArg1) DataTree::AddAsin(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
return AddUnaryOp(oAsin, iArg1);
else
return Zero; return Zero;
return AddUnaryOp(UnaryOpcode::asin, iArg1);
} }
expr_t expr_t
DataTree::AddAtan(expr_t iArg1) DataTree::AddAtan(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
return AddUnaryOp(oAtan, iArg1);
else
return Zero; return Zero;
return AddUnaryOp(UnaryOpcode::atan, iArg1);
} }
expr_t expr_t
DataTree::AddCosh(expr_t iArg1) DataTree::AddCosh(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
return AddUnaryOp(oCosh, iArg1);
else
return One; return One;
return AddUnaryOp(UnaryOpcode::cosh, iArg1);
} }
expr_t expr_t
DataTree::AddSinh(expr_t iArg1) DataTree::AddSinh(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
return AddUnaryOp(oSinh, iArg1);
else
return Zero; return Zero;
return AddUnaryOp(UnaryOpcode::sinh, iArg1);
} }
expr_t expr_t
DataTree::AddTanh(expr_t iArg1) DataTree::AddTanh(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
return AddUnaryOp(oTanh, iArg1);
else
return Zero; return Zero;
return AddUnaryOp(UnaryOpcode::tanh, iArg1);
} }
expr_t expr_t
DataTree::AddAcosh(expr_t iArg1) DataTree::AddAcosh(expr_t iArg1)
{ {
if (iArg1 != One) if (iArg1 == One)
return AddUnaryOp(oAcosh, iArg1);
else
return Zero; return Zero;
return AddUnaryOp(UnaryOpcode::acosh, iArg1);
} }
expr_t expr_t
DataTree::AddAsinh(expr_t iArg1) DataTree::AddAsinh(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
return AddUnaryOp(oAsinh, iArg1);
else
return Zero; return Zero;
return AddUnaryOp(UnaryOpcode::asinh, iArg1);
} }
expr_t expr_t
DataTree::AddAtanh(expr_t iArg1) DataTree::AddAtanh(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
return AddUnaryOp(oAtanh, iArg1);
else
return Zero; return Zero;
return AddUnaryOp(UnaryOpcode::atanh, iArg1);
} }
expr_t expr_t
DataTree::AddSqrt(expr_t iArg1) DataTree::AddSqrt(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
return AddUnaryOp(oSqrt, iArg1);
else
return Zero; return Zero;
if (iArg1 == One)
return One;
return AddUnaryOp(UnaryOpcode::sqrt, iArg1);
}
expr_t
DataTree::AddCbrt(expr_t iArg1)
{
if (iArg1 == Zero)
return Zero;
if (iArg1 == One)
return One;
return AddUnaryOp(UnaryOpcode::cbrt, iArg1);
} }
expr_t expr_t
...@@ -416,10 +594,11 @@ DataTree::AddAbs(expr_t iArg1) ...@@ -416,10 +594,11 @@ DataTree::AddAbs(expr_t iArg1)
{ {
if (iArg1 == Zero) if (iArg1 == Zero)
return Zero; return Zero;
if (iArg1 == One) if (iArg1 == One)
return One; return One;
else
return AddUnaryOp(oAbs, iArg1); return AddUnaryOp(UnaryOpcode::abs, iArg1);
} }
expr_t expr_t
...@@ -427,242 +606,290 @@ DataTree::AddSign(expr_t iArg1) ...@@ -427,242 +606,290 @@ DataTree::AddSign(expr_t iArg1)
{ {
if (iArg1 == Zero) if (iArg1 == Zero)
return Zero; return Zero;
if (iArg1 == One) if (iArg1 == One)
return One; return One;
else
return AddUnaryOp(oSign, iArg1); return AddUnaryOp(UnaryOpcode::sign, iArg1);
} }
expr_t expr_t
DataTree::AddErf(expr_t iArg1) DataTree::AddErf(expr_t iArg1)
{ {
if (iArg1 != Zero) if (iArg1 == Zero)
return AddUnaryOp(oErf, iArg1);
else
return Zero; return Zero;
return AddUnaryOp(UnaryOpcode::erf, iArg1);
}
expr_t
DataTree::AddErfc(expr_t iArg1)
{
if (iArg1 == Zero)
return One;
return AddUnaryOp(UnaryOpcode::erfc, iArg1);
} }
expr_t expr_t
DataTree::AddMax(expr_t iArg1, expr_t iArg2) DataTree::AddMax(expr_t iArg1, expr_t iArg2)
{ {
return AddBinaryOp(iArg1, oMax, iArg2); return AddBinaryOp(iArg1, BinaryOpcode::max, iArg2);
} }
expr_t expr_t
DataTree::AddMin(expr_t iArg1, expr_t iArg2) DataTree::AddMin(expr_t iArg1, expr_t iArg2)
{ {
return AddBinaryOp(iArg1, oMin, iArg2); return AddBinaryOp(iArg1, BinaryOpcode::min, iArg2);
} }
expr_t expr_t
DataTree::AddNormcdf(expr_t iArg1, expr_t iArg2, expr_t iArg3) DataTree::AddNormcdf(expr_t iArg1, expr_t iArg2, expr_t iArg3)
{ {
return AddTrinaryOp(iArg1, oNormcdf, iArg2, iArg3); return AddTrinaryOp(iArg1, TrinaryOpcode::normcdf, iArg2, iArg3);
} }
expr_t expr_t
DataTree::AddNormpdf(expr_t iArg1, expr_t iArg2, expr_t iArg3) DataTree::AddNormpdf(expr_t iArg1, expr_t iArg2, expr_t iArg3)
{ {
return AddTrinaryOp(iArg1, oNormpdf, iArg2, iArg3); return AddTrinaryOp(iArg1, TrinaryOpcode::normpdf, iArg2, iArg3);
} }
expr_t expr_t
DataTree::AddSteadyState(expr_t iArg1) DataTree::AddSteadyState(expr_t iArg1)
{ {
return AddUnaryOp(oSteadyState, iArg1); return AddUnaryOp(UnaryOpcode::steadyState, iArg1);
} }
expr_t expr_t
DataTree::AddSteadyStateParamDeriv(expr_t iArg1, int param_symb_id) DataTree::AddSteadyStateParamDeriv(expr_t iArg1, int param_symb_id)
{ {
return AddUnaryOp(oSteadyStateParamDeriv, iArg1, 0, param_symb_id); return AddUnaryOp(UnaryOpcode::steadyStateParamDeriv, iArg1, 0, param_symb_id);
} }
expr_t expr_t
DataTree::AddSteadyStateParam2ndDeriv(expr_t iArg1, int param1_symb_id, int param2_symb_id) DataTree::AddSteadyStateParam2ndDeriv(expr_t iArg1, int param1_symb_id, int param2_symb_id)
{ {
return AddUnaryOp(oSteadyStateParam2ndDeriv, iArg1, 0, param1_symb_id, param2_symb_id); return AddUnaryOp(UnaryOpcode::steadyStateParam2ndDeriv, iArg1, 0, param1_symb_id,
param2_symb_id);
} }
expr_t expr_t
DataTree::AddExpectation(int iArg1, expr_t iArg2) DataTree::AddExpectation(int iArg1, expr_t iArg2)
{ {
return AddUnaryOp(oExpectation, iArg2, iArg1); return AddUnaryOp(UnaryOpcode::expectation, iArg2, iArg1);
}
expr_t
DataTree::AddVarExpectation(const string& model_name)
{
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);
auto p = sp.get();
node_list.push_back(move(sp));
var_expectation_node_map.emplace(model_name, p);
return p;
}
expr_t
DataTree::AddPacExpectation(const string& model_name)
{
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);
auto p = sp.get();
node_list.push_back(move(sp));
pac_expectation_node_map.emplace(model_name, p);
return p;
} }
expr_t expr_t
DataTree::AddPacTargetNonstationary(const string& model_name)
{
if (auto it = pac_target_nonstationary_node_map.find(model_name);
it != pac_target_nonstationary_node_map.end())
return it->second;
auto sp = make_unique<PacTargetNonstationaryNode>(*this, node_list.size(), model_name);
auto p = sp.get();
node_list.push_back(move(sp));
pac_target_nonstationary_node_map.emplace(model_name, p);
return p;
}
BinaryOpNode*
DataTree::AddEqual(expr_t iArg1, expr_t iArg2) DataTree::AddEqual(expr_t iArg1, expr_t iArg2)
{ {
return AddBinaryOp(iArg1, oEqual, iArg2); /* We know that we can safely cast to BinaryOpNode because
BinaryOpCode::equal can never be reduced to a constant. */
return dynamic_cast<BinaryOpNode*>(AddBinaryOp(iArg1, BinaryOpcode::equal, iArg2));
} }
void void
DataTree::AddLocalVariable(int symb_id, expr_t value) throw (LocalVariableException) DataTree::AddLocalVariable(int symb_id, expr_t value) noexcept(false)
{ {
assert(symbol_table.getType(symb_id) == eModelLocalVariable); assert(symbol_table.getType(symb_id) == SymbolType::modelLocalVariable);
// Throw an exception if symbol already declared // Throw an exception if symbol already declared
map<int, expr_t>::iterator it = local_variables_table.find(symb_id); if (local_variables_table.contains(symb_id))
if (it != local_variables_table.end()) throw LocalVariableException {symbol_table.getName(symb_id)};
throw LocalVariableException(symbol_table.getName(symb_id));
local_variables_table[symb_id] = value; local_variables_table.emplace(symb_id, value);
local_variables_vector.push_back(symb_id); local_variables_vector.push_back(symb_id);
} }
expr_t expr_t
DataTree::AddExternalFunction(int symb_id, const vector<expr_t>& arguments) DataTree::AddExternalFunction(int symb_id, const vector<expr_t>& arguments)
{ {
assert(symbol_table.getType(symb_id) == eExternalFunction); assert(symbol_table.getType(symb_id) == SymbolType::externalFunction);
external_function_node_map_t::iterator it = external_function_node_map.find(make_pair(arguments, symb_id)); if (auto it = external_function_node_map.find({arguments, symb_id});
if (it != external_function_node_map.end()) it != external_function_node_map.end())
return it->second; return it->second;
return new ExternalFunctionNode(*this, symb_id, arguments); auto sp = make_unique<ExternalFunctionNode>(*this, node_list.size(), symb_id, arguments);
auto p = sp.get();
node_list.push_back(move(sp));
external_function_node_map.try_emplace({arguments, symb_id}, p);
return p;
} }
expr_t 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) == eExternalFunction); assert(symbol_table.getType(top_level_symb_id) == SymbolType::externalFunction);
first_deriv_external_function_node_map_t::iterator it if (auto it
= first_deriv_external_function_node_map.find(make_pair(make_pair(arguments, input_index), = first_deriv_external_function_node_map.find({arguments, input_index, top_level_symb_id});
top_level_symb_id)); it != first_deriv_external_function_node_map.end())
if (it != first_deriv_external_function_node_map.end())
return it->second; return it->second;
return new FirstDerivExternalFunctionNode(*this, 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);
return p;
} }
expr_t 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) == eExternalFunction); assert(symbol_table.getType(top_level_symb_id) == SymbolType::externalFunction);
second_deriv_external_function_node_map_t::iterator it if (auto it = second_deriv_external_function_node_map.find(
= second_deriv_external_function_node_map.find(make_pair(make_pair(arguments, {arguments, input_index1, input_index2, top_level_symb_id});
make_pair(input_index1, input_index2)), it != second_deriv_external_function_node_map.end())
top_level_symb_id));
if (it != second_deriv_external_function_node_map.end())
return it->second; return it->second;
return new SecondDerivExternalFunctionNode(*this, 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);
return p;
}
expr_t
DataTree::AddSum(expr_t arg)
{
return AddUnaryOp(UnaryOpcode::sum, arg);
} }
bool bool
DataTree::isSymbolUsed(int symb_id) const DataTree::isSymbolUsed(int symb_id) const
{ {
for (variable_node_map_t::const_iterator it = variable_node_map.begin(); if (ranges::any_of(views::keys(variable_node_map),
it != variable_node_map.end(); it++) [=](const auto& symb_lag) { return symb_lag.first == symb_id; }))
if (it->first.first == symb_id)
return true; return true;
if (local_variables_table.find(symb_id) != local_variables_table.end()) if (local_variables_table.contains(symb_id))
return true; return true;
return false; return false;
} }
int int
DataTree::getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException) DataTree::getDerivID([[maybe_unused]] int symb_id, [[maybe_unused]] int lag) const noexcept(false)
{ {
throw UnknownDerivIDException(); throw UnknownDerivIDException();
} }
SymbolType SymbolType
DataTree::getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException) DataTree::getTypeByDerivID([[maybe_unused]] int deriv_id) const noexcept(false)
{ {
throw UnknownDerivIDException(); throw UnknownDerivIDException();
} }
int int
DataTree::getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException) DataTree::getLagByDerivID([[maybe_unused]] int deriv_id) const noexcept(false)
{ {
throw UnknownDerivIDException(); throw UnknownDerivIDException();
} }
int int
DataTree::getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException) DataTree::getSymbIDByDerivID([[maybe_unused]] int deriv_id) const noexcept(false)
{ {
throw UnknownDerivIDException(); throw UnknownDerivIDException();
} }
void
DataTree::addAllParamDerivId(set<int> &deriv_id_set)
{
}
int int
DataTree::getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException) DataTree::getTypeSpecificIDByDerivID([[maybe_unused]] int deriv_id) const
{ {
throw UnknownDerivIDException(); throw UnknownDerivIDException();
} }
bool void
DataTree::isUnaryOpUsed(UnaryOpcode opcode) const DataTree::addAllParamDerivId([[maybe_unused]] set<int>& deriv_id_set)
{ {
for (unary_op_node_map_t::const_iterator it = unary_op_node_map.begin();
it != unary_op_node_map.end(); it++)
if (it->first.first.second == opcode)
return true;
return false;
} }
bool bool
DataTree::isBinaryOpUsed(BinaryOpcode opcode) const DataTree::isUnaryOpUsed(UnaryOpcode opcode) const
{ {
for (binary_op_node_map_t::const_iterator it = binary_op_node_map.begin(); return ranges::any_of(views::keys(unary_op_node_map),
it != binary_op_node_map.end(); it++) [=](const auto& key) { return get<1>(key) == opcode; });
if (it->first.second == opcode)
return true;
return false;
} }
bool bool
DataTree::isTrinaryOpUsed(TrinaryOpcode opcode) const DataTree::isUnaryOpUsedOnType(SymbolType type, UnaryOpcode opcode) const
{ {
for (trinary_op_node_map_t::const_iterator it = trinary_op_node_map.begin(); set<int> var;
it != trinary_op_node_map.end(); it++) for (const auto& [key, value] : unary_op_node_map)
if (it->first.second == opcode) if (get<1>(key) == opcode)
return true;
return false;
}
bool
DataTree::isExternalFunctionUsed(int symb_id) const
{ {
for (external_function_node_map_t::const_iterator it = external_function_node_map.begin(); value->collectVariables(type, var);
it != external_function_node_map.end(); it++) if (!var.empty())
if (it->first.second == symb_id)
return true; return true;
}
return false; return false;
} }
bool bool
DataTree::isFirstDerivExternalFunctionUsed(int symb_id) const DataTree::isBinaryOpUsed(BinaryOpcode opcode) const
{ {
for (first_deriv_external_function_node_map_t::const_iterator it = first_deriv_external_function_node_map.begin(); return ranges::any_of(views::keys(binary_op_node_map),
it != first_deriv_external_function_node_map.end(); it++) [=](const auto& key) { return get<2>(key) == opcode; });
if (it->first.second == symb_id)
return true;
return false;
} }
bool bool
DataTree::isSecondDerivExternalFunctionUsed(int symb_id) const DataTree::isBinaryOpUsedOnType(SymbolType type, BinaryOpcode opcode) const
{
set<int> var;
for (const auto& [key, value] : binary_op_node_map)
if (get<2>(key) == opcode)
{ {
for (second_deriv_external_function_node_map_t::const_iterator it = second_deriv_external_function_node_map.begin(); value->collectVariables(type, var);
it != second_deriv_external_function_node_map.end(); it++) if (!var.empty())
if (it->first.second == symb_id)
return true; return true;
}
return false; return false;
} }
...@@ -670,86 +897,94 @@ int ...@@ -670,86 +897,94 @@ int
DataTree::minLagForSymbol(int symb_id) const DataTree::minLagForSymbol(int symb_id) const
{ {
int r = 0; int r = 0;
for (variable_node_map_t::const_iterator it = variable_node_map.begin(); for (const auto& [symb_lag, expr] : variable_node_map)
it != variable_node_map.end(); ++it) if (symb_lag.first == symb_id)
if (it->first.first == symb_id && it->first.second < r) r = min(r, symb_lag.second);
r = it->first.second;
return r; return r;
} }
void void
DataTree::writePowerDerivCHeader(ostream &output) const DataTree::writeCHelpersDefinition(ostream& output) const
{ {
if (isBinaryOpUsed(oPowerDeriv)) if (isBinaryOpUsed(BinaryOpcode::powerDeriv))
output << "double getPowerDeriv(double, double, int);" << endl; output << "// The k-th derivative of x^p" << endl
} << "inline double" << endl
<< "getPowerDeriv(double x, double p, int k)" << endl
void
DataTree::writePowerDeriv(ostream &output) const
{
if (isBinaryOpUsed(oPowerDeriv))
output << "/*" << endl
<< " * The k-th derivative of x^p" << endl
<< " */" << endl
<< "double getPowerDeriv(double x, double p, int k)" << endl
<< "{" << endl << "{" << endl
<< "#ifdef _MSC_VER" << endl << " if (fabs(x) < " << power_deriv_near_zero
<< "# define nearbyint(x) (fabs((x)-floor(x)) < fabs((x)-ceil(x)) ? floor(x) : ceil(x))" << endl << " && p >= 0 && k > p && fabs(p-nearbyint(p)) < " << power_deriv_near_zero << ')'
<< "#endif" << endl << endl
<< " if ( fabs(x) < " << NEAR_ZERO << " && p > 0 && k > p && fabs(p-nearbyint(p)) < " << NEAR_ZERO << " )" << endl
<< " return 0.0;" << endl << " return 0.0;" << endl
<< " else" << endl << " else" << endl
<< " {" << endl << " {" << endl
<< " int i = 0;" << endl
<< " double dxp = pow(x, p-k);" << endl << " double dxp = pow(x, p-k);" << endl
<< " for (; i<k; i++)" << endl << " for (int i = 0; i<k; i++)" << endl
<< " dxp *= p--;" << endl << " dxp *= p--;" << endl
<< " return dxp;" << endl << " return dxp;" << endl
<< " }" << endl << " }" << endl
<< "}" << endl; << "}" << endl;
if (isUnaryOpUsed(UnaryOpcode::sign))
output << "inline double" << endl
<< "sign(double x)" << endl
<< "{" << endl
<< " return (x > 0) ? 1 : ((x < 0) ? -1 : 0);" << endl
<< "}" << endl;
} }
void void
DataTree::writeNormcdfCHeader(ostream &output) const DataTree::writeCHelpersDeclaration(ostream& output) const
{ {
#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) if (isBinaryOpUsed(BinaryOpcode::powerDeriv))
if (isTrinaryOpUsed(oNormcdf)) output << "extern inline double getPowerDeriv(double x, double p, int k);" << endl;
output << "#ifdef _MSC_VER" << endl if (isUnaryOpUsed(UnaryOpcode::sign))
<< "double normcdf(double);" << endl output << "extern inline double sign(double x);" << endl;
<< "#endif" << endl; }
#endif
vector<string>
DataTree::strsplit(string_view str, char delim)
{
vector<string> result;
while (true)
{
size_t idx {str.find(delim)};
if (auto sub {str.substr(0, idx)}; !sub.empty())
result.emplace_back(sub);
if (idx == string_view::npos)
break;
str.remove_prefix(idx + 1);
}
return result;
}
filesystem::path
DataTree::packageDir(const string_view& package)
{
filesystem::path d;
for (const auto& it : strsplit(package, '.'))
d /= "+" + it;
return d;
} }
void void
DataTree::writeNormcdf(ostream &output) const DataTree::writeToFileIfModified(stringstream& new_contents, const filesystem::path& filename)
{ {
#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__) ifstream old_file {filename, ios::in | ios::binary};
if (isTrinaryOpUsed(oNormcdf)) if (old_file.is_open()
output << endl && ranges::equal(istreambuf_iterator<char> {old_file}, istreambuf_iterator<char> {},
<< "#ifdef _MSC_VER" << endl istreambuf_iterator<char> {new_contents}, istreambuf_iterator<char> {}))
<< "/*" << endl return;
<< " * Define normcdf for MSVC compiler" << endl old_file.close();
<< " */" << endl
<< "double normcdf(double x)" << endl new_contents.seekg(0);
<< "{" << endl
<< "#if _MSC_VER >= 1700" << endl ofstream new_file {filename, ios::out | ios::binary};
<< " return 0.5 * erfc(-x * M_SQRT1_2);" << endl if (!new_file.is_open())
<< "#else" << endl {
<< " // From http://www.johndcook.com/blog/cpp_phi" << endl cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl;
<< " double a1 = 0.254829592;" << endl exit(EXIT_FAILURE);
<< " double a2 = -0.284496736;" << endl }
<< " double a3 = 1.421413741;" << endl ranges::copy(istreambuf_iterator<char> {new_contents}, istreambuf_iterator<char> {},
<< " double a4 = -1.453152027;" << endl ostreambuf_iterator<char> {new_file});
<< " double a5 = 1.061405429;" << endl new_file.close();
<< " double p = 0.3275911;" << endl
<< " int sign = (x < 0) ? -1 : 1;" << endl
<< " x = fabs(x)/sqrt(2.0);" << endl
<< " // From the Handbook of Mathematical Functions by Abramowitz and Stegun, formula 7.1.26" << endl
<< " double t = 1.0/(1.0 + p*x);" << endl
<< " double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x);" << endl
<< " return 0.5*(1.0 + sign*y);" << endl
<< "#endif" << endl
<< "}" << endl
<< "#endif" << endl;
#endif
} }
/* /*
* Copyright (C) 2003-2017 Dynare Team * Copyright © 2003-2024 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -14,123 +14,165 @@ ...@@ -14,123 +14,165 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>. * along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef _DATATREE_HH #ifndef DATA_TREE_HH
#define _DATATREE_HH #define DATA_TREE_HH
using namespace std; #include <cmath>
#include <filesystem>
#include <string> #include <iomanip>
#include <map> #include <map>
#include <list> #include <memory>
#include <sstream> #include <sstream>
#include <iomanip> #include <string>
#include <cmath> #include <string_view>
#include <utility>
#include <vector>
#include "SymbolTable.hh"
#include "NumericalConstants.hh"
#include "ExternalFunctionsTable.hh"
#include "ExprNode.hh" #include "ExprNode.hh"
#include "ExternalFunctionsTable.hh"
#include "HeterogeneityTable.hh"
#include "NumericalConstants.hh"
#include "SubModel.hh"
#include "SymbolTable.hh"
#define CONSTANTS_PRECISION 16 using namespace std;
class DataTree class DataTree
{ {
friend class ExprNode; public:
friend class NumConstNode;
friend class VariableNode;
friend class UnaryOpNode;
friend class BinaryOpNode;
friend class TrinaryOpNode;
friend class AbstractExternalFunctionNode;
friend class ExternalFunctionNode;
friend class FirstDerivExternalFunctionNode;
friend class SecondDerivExternalFunctionNode;
protected:
//! A reference to the symbol table //! A reference to the symbol table
SymbolTable& symbol_table; SymbolTable& symbol_table;
//! Reference to numerical constants table //! Reference to numerical constants table
NumericalConstants& num_constants; NumericalConstants& num_constants;
//! A reference to the external functions table //! A reference to the external functions table
ExternalFunctionsTable& external_functions_table; ExternalFunctionsTable& external_functions_table;
// A reference to the heterogeneity table
HeterogeneityTable& heterogeneity_table;
//! Is it possible to use leads/lags on variable nodes?
/* NB: This data member cannot be replaced by a virtual method, because this information is needed
in AddVariable(), which itself can be called from the copy constructor. */
const bool is_dynamic;
typedef map<int, NumConstNode *> num_const_node_map_t; private:
//! num_constant_id -> NumConstNode
using num_const_node_map_t = map<int, NumConstNode*>;
num_const_node_map_t num_const_node_map; num_const_node_map_t num_const_node_map;
//! Pair (symbol_id, lag) used as key
typedef map<pair<int, int>, VariableNode *> variable_node_map_t; //! (symbol_id, lag) -> VariableNode
using variable_node_map_t = map<pair<int, int>, VariableNode*>;
variable_node_map_t variable_node_map; variable_node_map_t variable_node_map;
//! Pair( Pair(arg1, UnaryOpCode), Pair( Expectation Info Set, Pair(param1_symb_id, param2_symb_id)) ))
typedef map<pair<pair<expr_t, UnaryOpcode>, pair<int, pair<int, int> > >, UnaryOpNode *> unary_op_node_map_t; //! (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; unary_op_node_map_t unary_op_node_map;
//! Pair( Pair( Pair(arg1, arg2), order of Power Derivative), opCode)
typedef map<pair<pair<pair<expr_t, expr_t>, int>, BinaryOpcode>, BinaryOpNode *> binary_op_node_map_t; //! ( arg1, arg2, opCode, order of Power Derivative) -> BinaryOpNode
using binary_op_node_map_t = map<tuple<expr_t, expr_t, BinaryOpcode, int>, BinaryOpNode*>;
binary_op_node_map_t binary_op_node_map; binary_op_node_map_t binary_op_node_map;
typedef map<pair<pair<pair<expr_t, expr_t>, expr_t>, TrinaryOpcode>, TrinaryOpNode *> trinary_op_node_map_t;
//! ( arg1, arg2, arg3, opCode) -> TrinaryOpNode
using trinary_op_node_map_t = map<tuple<expr_t, expr_t, expr_t, TrinaryOpcode>, TrinaryOpNode*>;
trinary_op_node_map_t trinary_op_node_map; trinary_op_node_map_t trinary_op_node_map;
// (arguments, symb_id) -> ExternalFunctionNode // (arguments, symb_id) -> ExternalFunctionNode
typedef map<pair<vector<expr_t>, int>, ExternalFunctionNode *> external_function_node_map_t; using external_function_node_map_t = map<pair<vector<expr_t>, int>, ExternalFunctionNode*>;
external_function_node_map_t external_function_node_map; external_function_node_map_t external_function_node_map;
// ((arguments, deriv_idx), symb_id) -> FirstDerivExternalFunctionNode // (model_name, symb_id, forecast_horizon) -> VarExpectationNode
typedef map<pair<pair<vector<expr_t>, int>, int>, FirstDerivExternalFunctionNode *> first_deriv_external_function_node_map_t; using var_expectation_node_map_t = map<string, VarExpectationNode*>;
var_expectation_node_map_t var_expectation_node_map;
// model_name -> PacExpectationNode
using pac_expectation_node_map_t = map<string, PacExpectationNode*>;
pac_expectation_node_map_t pac_expectation_node_map;
// model_name -> PacTargetNonstationaryNode
using pac_target_nonstationary_node_map_t = map<string, PacTargetNonstationaryNode*>;
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*>;
first_deriv_external_function_node_map_t first_deriv_external_function_node_map; first_deriv_external_function_node_map_t first_deriv_external_function_node_map;
// ((arguments, (deriv_idx1, deriv_idx2)), symb_id) -> SecondDerivExternalFunctionNode // (arguments, deriv_idx1, deriv_idx2, symb_id) -> SecondDerivExternalFunctionNode
typedef map<pair<pair<vector<expr_t>, pair<int, int> >, int>, SecondDerivExternalFunctionNode *> second_deriv_external_function_node_map_t; 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; second_deriv_external_function_node_map_t second_deriv_external_function_node_map;
// Flag to disable simplifications related to commutativity of addition and multiplication
static bool no_commutativity;
protected:
//! Stores local variables value (maps symbol ID to corresponding node) //! Stores local variables value (maps symbol ID to corresponding node)
map<int, expr_t> local_variables_table; 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; vector<int> local_variables_vector;
//! Internal implementation of AddVariable(), without the check on the lag
VariableNode *AddVariableInternal(int symb_id, int lag);
//! Internal implementation of ParamUsedWithLeadLag() //! Internal implementation of ParamUsedWithLeadLag()
bool ParamUsedWithLeadLagInternal() const; [[nodiscard]] bool ParamUsedWithLeadLagInternal() const;
/* Writes the contents of “new_contents” to the file “filename”. However, if
the file already exists and would not be modified by this operation, then do
nothing. */
static void writeToFileIfModified(stringstream& new_contents, const filesystem::path& filename);
private: private:
typedef list<expr_t> node_list_t; constexpr static int constants_precision {16};
//! The list of nodes
node_list_t node_list;
//! A counter for filling ExprNode's idx field
int node_counter;
inline expr_t AddPossiblyNegativeConstant(double val); //! The list of nodes
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); vector<unique_ptr<ExprNode>> node_list;
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); 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: public:
DataTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_arg); DataTree(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg,
virtual ExternalFunctionsTable& external_functions_table_arg,
~DataTree(); HeterogeneityTable& heterogeneity_table_arg, bool is_dynamic_arg = false);
virtual ~DataTree() = default;
DataTree(const DataTree& d);
DataTree& operator=(const DataTree& d);
//! Some predefined constants //! Some predefined constants
expr_t Zero, One, Two, MinusOne, NaN, Infinity, MinusInfinity, Pi; NumConstNode *Zero, *One, *Two, *Three, *NaN, *Infinity, *Pi;
expr_t MinusOne, MinusInfinity;
//! Raised when a local parameter is declared twice //! Raised when a local parameter is declared twice
class LocalVariableException struct LocalVariableException
{ {
public:
string name; string name;
LocalVariableException(const string &name_arg) : name(name_arg)
{
}
}; };
class DivisionByZeroException class DivisionByZeroException
{ {
}; };
inline expr_t AddPossiblyNegativeConstant(double val);
//! Adds a non-negative numerical constant (possibly Inf or NaN) //! Adds a non-negative numerical constant (possibly Inf or NaN)
expr_t AddNonNegativeConstant(const string &value); NumConstNode* AddNonNegativeConstant(const string& value);
//! Adds a variable //! Adds a variable
/*! The default implementation of the method refuses any lag != 0 */ VariableNode* AddVariable(int symb_id, int lag = 0);
virtual VariableNode *AddVariable(int symb_id, int lag = 0); //! Gets a variable
/*! Same as AddVariable, except that it fails if the variable node has not
already been created */
[[nodiscard]] VariableNode* getVariable(int symb_id, int lag = 0) const;
//! Adds "arg1+arg2" to model tree //! Adds "arg1+arg2" to model tree
expr_t AddPlus(expr_t iArg1, expr_t iArg2); expr_t AddPlus(expr_t iArg1, expr_t iArg2);
//! Adds "arg1-arg2" to model tree //! Adds "arg1-arg2" to model tree
...@@ -140,7 +182,7 @@ public: ...@@ -140,7 +182,7 @@ public:
//! Adds "arg1*arg2" to model tree //! Adds "arg1*arg2" to model tree
expr_t AddTimes(expr_t iArg1, expr_t iArg2); expr_t AddTimes(expr_t iArg1, expr_t iArg2);
//! Adds "arg1/arg2" to model tree //! Adds "arg1/arg2" to model tree
expr_t AddDivide(expr_t iArg1, expr_t iArg2) throw (DivisionByZeroException); expr_t AddDivide(expr_t iArg1, expr_t iArg2) noexcept(false);
//! Adds "arg1<arg2" to model tree //! Adds "arg1<arg2" to model tree
expr_t AddLess(expr_t iArg1, expr_t iArg2); expr_t AddLess(expr_t iArg1, expr_t iArg2);
//! Adds "arg1>arg2" to model tree //! Adds "arg1>arg2" to model tree
...@@ -159,6 +201,10 @@ public: ...@@ -159,6 +201,10 @@ public:
expr_t AddPowerDeriv(expr_t iArg1, expr_t iArg2, int powerDerivOrder); expr_t AddPowerDeriv(expr_t iArg1, expr_t iArg2, int powerDerivOrder);
//! Adds "E(arg1)(arg2)" to model tree //! Adds "E(arg1)(arg2)" to model tree
expr_t AddExpectation(int iArg1, expr_t iArg2); expr_t AddExpectation(int iArg1, expr_t iArg2);
//! Adds "diff(arg)" to model tree
expr_t AddDiff(expr_t iArg1);
//! Adds "adl(arg1, name, lag/lags)" to model tree
expr_t AddAdl(expr_t iArg1, const string& name, const vector<int>& lags);
//! Adds "exp(arg)" to model tree //! Adds "exp(arg)" to model tree
expr_t AddExp(expr_t iArg1); expr_t AddExp(expr_t iArg1);
//! Adds "log(arg)" to model tree //! Adds "log(arg)" to model tree
...@@ -191,12 +237,16 @@ public: ...@@ -191,12 +237,16 @@ public:
expr_t AddAtanh(expr_t iArg1); expr_t AddAtanh(expr_t iArg1);
//! Adds "sqrt(arg)" to model tree //! Adds "sqrt(arg)" to model tree
expr_t AddSqrt(expr_t iArg1); expr_t AddSqrt(expr_t iArg1);
//! Adds "cbrt(arg)" to model tree
expr_t AddCbrt(expr_t iArg1);
//! Adds "abs(arg)" to model tree //! Adds "abs(arg)" to model tree
expr_t AddAbs(expr_t iArg1); expr_t AddAbs(expr_t iArg1);
//! Adds "sign(arg)" to model tree //! Adds "sign(arg)" to model tree
expr_t AddSign(expr_t iArg1); expr_t AddSign(expr_t iArg1);
//! Adds "erf(arg)" to model tree //! Adds "erf(arg)" to model tree
expr_t AddErf(expr_t iArg1); expr_t AddErf(expr_t iArg1);
//! Adds "erfc(arg)" to model tree
expr_t AddErfc(expr_t iArg1);
//! Adds "max(arg1,arg2)" to model tree //! Adds "max(arg1,arg2)" to model tree
expr_t AddMax(expr_t iArg1, expr_t iArg2); expr_t AddMax(expr_t iArg1, expr_t iArg2);
//! Adds "min(arg1,arg2)" to model tree //! Adds "min(arg1,arg2)" to model tree
...@@ -212,71 +262,136 @@ public: ...@@ -212,71 +262,136 @@ public:
//! Add 2nd derivative of steady state w.r.t. parameter to model tree //! Add 2nd derivative of steady state w.r.t. parameter to model tree
expr_t AddSteadyStateParam2ndDeriv(expr_t iArg1, int param1_symb_id, int param2_symb_id); expr_t AddSteadyStateParam2ndDeriv(expr_t iArg1, int param1_symb_id, int param2_symb_id);
//! Adds "arg1=arg2" to model tree //! Adds "arg1=arg2" to model tree
expr_t AddEqual(expr_t iArg1, expr_t iArg2); BinaryOpNode* AddEqual(expr_t iArg1, expr_t iArg2);
//! Adds "var_expectation(model_name)" to model tree
expr_t AddVarExpectation(const string& model_name);
//! Adds pac_expectation command to model tree
expr_t AddPacExpectation(const string& model_name);
//! Adds a pac_target_nonstationary node to model tree
expr_t AddPacTargetNonstationary(const string& model_name);
//! Adds a model local variable with its value //! Adds a model local variable with its value
void AddLocalVariable(int symb_id, expr_t value) throw (LocalVariableException); void AddLocalVariable(int symb_id, expr_t value) noexcept(false);
//! Adds an external function node //! Adds an external function node
expr_t AddExternalFunction(int symb_id, const vector<expr_t>& arguments); expr_t AddExternalFunction(int symb_id, const vector<expr_t>& arguments);
//! Adds an external function node for the first derivative of an external function //! 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 //! 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);
// Adds "SUM(arg)" to model tree
expr_t AddSum(expr_t arg);
//! Checks if a given symbol is used somewhere in the data tree //! Checks if a given symbol is used somewhere in the data tree
bool isSymbolUsed(int symb_id) const; [[nodiscard]] bool isSymbolUsed(int symb_id) const;
//! Checks if a given unary op is used somewhere in the data tree //! Checks if a given unary op is used somewhere in the data tree
bool isUnaryOpUsed(UnaryOpcode opcode) const; [[nodiscard]] bool isUnaryOpUsed(UnaryOpcode opcode) const;
//! Checks if a given unary op is used somewhere in the data tree on an endogenous variable
[[nodiscard]] bool isUnaryOpUsedOnType(SymbolType type, UnaryOpcode opcode) const;
//! Checks if a given binary op is used somewhere in the data tree //! Checks if a given binary op is used somewhere in the data tree
bool isBinaryOpUsed(BinaryOpcode opcode) const; [[nodiscard]] bool isBinaryOpUsed(BinaryOpcode opcode) const;
//! Checks if a given trinary op is used somewhere in the data tree //! Checks if a given binary op is used somewhere in the data tree on an endogenous variable
bool isTrinaryOpUsed(TrinaryOpcode opcode) const; [[nodiscard]] bool isBinaryOpUsedOnType(SymbolType type, BinaryOpcode opcode) const;
//! Checks if a given external function is used somewhere in the data tree //! Returns the minimum lag (as a negative number) of the given symbol in the whole data tree (and
bool isExternalFunctionUsed(int symb_id) const; //! not only in the equations !!)
//! Checks if a given first derivative external function is used somewhere in the data tree
bool isFirstDerivExternalFunctionUsed(int symb_id) const;
//! Checks if a given second derivative external function is used somewhere in the data tree
bool isSecondDerivExternalFunctionUsed(int symb_id) 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 0 if the symbol is not used */ /*! Returns 0 if the symbol is not used */
int minLagForSymbol(int symb_id) const; [[nodiscard]] int minLagForSymbol(int symb_id) const;
//! Write the C Header for getPowerDeriv when use_dll is used /* Writes definitions of C function helpers (getPowerDeriv(), sign()) as
void writePowerDerivCHeader(ostream &output) const; inline functions */
//! Write getPowerDeriv in C void writeCHelpersDefinition(ostream& output) const;
void writePowerDeriv(ostream &output) const; /* Writes declarations of C function helpers (getPowerDeriv(), sign()) as
//! Write the C Header for normcdf when use_dll is used extern inline (external definition). Those need to be included in exactly
void writeNormcdfCHeader(ostream &output) const; one translation unit. That external definition will be used or not,
//! Write normcdf in C depending on the optimization decision by the compiler.
void writeNormcdf(ostream &output) const; See https://en.cppreference.com/w/c/language/inline */
void writeCHelpersDeclaration(ostream& output) const;
//! Thrown when trying to access an unknown variable by deriv_id //! Thrown when trying to access an unknown variable by deriv_id
class UnknownDerivIDException class UnknownDerivIDException
{ {
}; };
//! Raised when a trend is declared twice //! Raised when a trend is declared twice
class TrendException struct TrendException
{ {
public:
string name; string name;
TrendException(const string &name_arg) : name(name_arg) };
// Returns the derivation ID, or throws an exception if the derivation ID does not exist
[[nodiscard]] virtual int getDerivID(int symb_id, int lag) const noexcept(false);
// Get the type corresponding to a derivation ID
[[nodiscard]] virtual SymbolType getTypeByDerivID(int deriv_id) const noexcept(false);
// Get the lag corresponding to a derivation ID
[[nodiscard]] virtual int getLagByDerivID(int deriv_id) const noexcept(false);
// Get the symbol ID corresponding to a derivation ID
[[nodiscard]] virtual int getSymbIDByDerivID(int deriv_id) const noexcept(false);
// Get the type-specific ID corresponding to a derivation ID
[[nodiscard]] virtual int getTypeSpecificIDByDerivID(int deriv_id) const;
// Get the symbol name corresponding to a derivation ID
[[nodiscard]] string
getNameByDerivID(int deriv_id) const
{ {
return symbol_table.getName(getSymbIDByDerivID(deriv_id));
}
/* Returns the column of the Jacobian associated to a derivation ID.
The “sparse” argument selects between the legacy representation and the
sparse representation. */
[[nodiscard]] virtual int
getJacobianCol([[maybe_unused]] int deriv_id, [[maybe_unused]] bool sparse) const
{
throw UnknownDerivIDException();
}
/* Returns the number of columns of the Jacobian
The “sparse” argument selects between the legacy representation and the
sparse representation. */
[[nodiscard]] virtual int
getJacobianColsNbr([[maybe_unused]] bool sparse) const
{
throw UnknownDerivIDException();
} }
};
//! Returns the derivation ID, or throws an exception if the derivation ID does not exist
virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException);
virtual SymbolType getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException);
virtual int getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException);
virtual int getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException);
//! Returns the column of the dynamic Jacobian associated to a derivation ID
virtual int getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException);
//! Adds to the set all the deriv IDs corresponding to parameters //! Adds to the set all the deriv IDs corresponding to parameters
virtual void addAllParamDerivId(set<int>& deriv_id_set); virtual void addAllParamDerivId(set<int>& deriv_id_set);
//! Returns bool indicating whether DataTree represents a Dynamic Model (returns true in DynamicModel.hh) struct UnknownLocalVariableException
virtual bool
isDynamic() const
{ {
return false; //! Symbol ID
int id;
}; };
[[nodiscard]] expr_t
getLocalVariable(int symb_id, int lead_lag) const
{
auto it = local_variables_table.find(symb_id);
if (it == local_variables_table.end())
throw UnknownLocalVariableException {symb_id};
/* In the following, the case without lead/lag is optimized. It makes a difference on models
with many nested model-local variables, see e.g.
https://forum.dynare.org/t/pre-processing-takes-very-long/26865 */
if (lead_lag == 0)
return it->second;
else
return it->second->decreaseLeadsLags(-lead_lag);
}
static void
setNoCommutativity()
{
no_commutativity = true;
}
/* Equivalent of MATLAB/Octave’s strsplit, except that it ignores empty
substring components (MATLAB/Octave adds them to the output); in
particular, returns an empty vector given an empty string. */
static vector<string> strsplit(string_view str, char delim);
/*! Takes a MATLAB/Octave package name (possibly with several levels nested using dots),
and returns the path to the corresponding filesystem directory.
In practice the package nesting is used for the planner_objective (stored
inside +objective subdir). */
static filesystem::path packageDir(const string_view& package);
}; };
inline expr_t inline expr_t
...@@ -287,7 +402,7 @@ DataTree::AddPossiblyNegativeConstant(double v) ...@@ -287,7 +402,7 @@ DataTree::AddPossiblyNegativeConstant(double v)
if (isnan(v)) if (isnan(v))
return NaN; return NaN;
if (isinf(v)) if (isinf(v))
return (v < 0 ? MinusInfinity : Infinity); return v < 0 ? MinusInfinity : Infinity;
bool neg = false; bool neg = false;
if (v < 0) if (v < 0)
...@@ -296,7 +411,7 @@ DataTree::AddPossiblyNegativeConstant(double v) ...@@ -296,7 +411,7 @@ DataTree::AddPossiblyNegativeConstant(double v)
neg = true; neg = true;
} }
ostringstream ost; ostringstream ost;
ost << setprecision(CONSTANTS_PRECISION) << v; ost << setprecision(constants_precision) << v;
expr_t cnode = AddNonNegativeConstant(ost.str()); expr_t cnode = AddNonNegativeConstant(ost.str());
...@@ -307,21 +422,23 @@ DataTree::AddPossiblyNegativeConstant(double v) ...@@ -307,21 +422,23 @@ DataTree::AddPossiblyNegativeConstant(double v)
} }
inline expr_t inline expr_t
DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int param1_symb_id, int param2_symb_id) 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 the node already exists in tree, share it
unary_op_node_map_t::iterator it = unary_op_node_map.find(make_pair(make_pair(arg, op_code), make_pair(arg_exp_info_set, make_pair(param1_symb_id, param2_symb_id)))); if (auto it = unary_op_node_map.find({arg, op_code, arg_exp_info_set, param1_symb_id,
if (it != unary_op_node_map.end()) param2_symb_id, adl_param_name, adl_lags});
it != unary_op_node_map.end())
return it->second; return it->second;
// Try to reduce to a constant // Try to reduce to a constant
// Case where arg is a constant and op_code == oUminus (i.e. we're adding a negative constant) is skipped // Case where arg is a constant and op_code == UnaryOpcode::uminus (i.e. we're adding a negative
NumConstNode *carg = dynamic_cast<NumConstNode *>(arg); // constant) is skipped
if (op_code != oUminus || carg == NULL) if (auto carg = dynamic_cast<NumConstNode*>(arg); op_code != UnaryOpcode::uminus || !carg)
{ {
try try
{ {
double argval = arg->eval(eval_context_t()); double argval = arg->eval({}); // NOLINT(clang-analyzer-core.CallAndMessage)
double val = UnaryOpNode::eval_opcode(op_code, argval); double val = UnaryOpNode::eval_opcode(op_code, argval);
return AddPossiblyNegativeConstant(val); return AddPossiblyNegativeConstant(val);
} }
...@@ -329,50 +446,69 @@ DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int ...@@ -329,50 +446,69 @@ DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int
{ {
} }
} }
return new UnaryOpNode(*this, op_code, arg, arg_exp_info_set, param1_symb_id, param2_symb_id);
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);
return p;
} }
inline expr_t inline expr_t
DataTree::AddBinaryOp(expr_t arg1, BinaryOpcode op_code, expr_t arg2, int powerDerivOrder) DataTree::AddBinaryOp(expr_t arg1, BinaryOpcode op_code, expr_t arg2, int powerDerivOrder)
{ {
binary_op_node_map_t::iterator it = binary_op_node_map.find(make_pair(make_pair(make_pair(arg1, arg2), powerDerivOrder), op_code)); if (auto it = binary_op_node_map.find({arg1, arg2, op_code, powerDerivOrder});
if (it != binary_op_node_map.end()) it != binary_op_node_map.end())
return it->second; return it->second;
// Try to reduce to a constant // Try to reduce to a constant
try try
{ {
double argval1 = arg1->eval(eval_context_t()); double argval1 = arg1->eval({}); // NOLINT(clang-analyzer-core.CallAndMessage)
double argval2 = arg2->eval(eval_context_t()); double argval2 = arg2->eval({}); // NOLINT(clang-analyzer-core.CallAndMessage)
double val = BinaryOpNode::eval_opcode(argval1, op_code, argval2, powerDerivOrder); double val = BinaryOpNode::eval_opcode(argval1, op_code, argval2, powerDerivOrder);
return AddPossiblyNegativeConstant(val); return AddPossiblyNegativeConstant(val);
} }
catch (ExprNode::EvalException& e) catch (ExprNode::EvalException& e)
{ {
} }
return new BinaryOpNode(*this, 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);
return p;
} }
inline expr_t inline expr_t
DataTree::AddTrinaryOp(expr_t arg1, TrinaryOpcode op_code, expr_t arg2, expr_t arg3) DataTree::AddTrinaryOp(expr_t arg1, TrinaryOpcode op_code, expr_t arg2, expr_t arg3)
{ {
trinary_op_node_map_t::iterator it = trinary_op_node_map.find(make_pair(make_pair(make_pair(arg1, arg2), arg3), op_code)); if (auto it = trinary_op_node_map.find({arg1, arg2, arg3, op_code});
if (it != trinary_op_node_map.end()) it != trinary_op_node_map.end())
return it->second; return it->second;
// Try to reduce to a constant // Try to reduce to a constant
try try
{ {
double argval1 = arg1->eval(eval_context_t()); double argval1 = arg1->eval({});
double argval2 = arg2->eval(eval_context_t()); double argval2 = arg2->eval({});
double argval3 = arg3->eval(eval_context_t()); double argval3 = arg3->eval({});
double val = TrinaryOpNode::eval_opcode(argval1, op_code, argval2, argval3); double val = TrinaryOpNode::eval_opcode(argval1, op_code, argval2, argval3);
return AddPossiblyNegativeConstant(val); return AddPossiblyNegativeConstant(val);
} }
catch (ExprNode::EvalException& e) catch (ExprNode::EvalException& e)
{ {
} }
return new TrinaryOpNode(*this, arg1, op_code, arg2, arg3);
auto sp = make_unique<TrinaryOpNode>(*this, node_list.size(), arg1, op_code, arg2, arg3);
auto p = sp.get();
node_list.push_back(move(sp));
trinary_op_node_map.try_emplace({arg1, arg2, arg3, op_code}, p);
return p;
} }
#endif #endif
Source diff could not be displayed: it is too large. Options to address this: view the blob.
/* /*
* Copyright (C) 2003-2018 Dynare Team * Copyright © 2003-2024 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -14,221 +14,324 @@ ...@@ -14,221 +14,324 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>. * along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef _DYNAMICMODEL_HH #ifndef DYNAMIC_MODEL_HH
#define _DYNAMICMODEL_HH #define DYNAMIC_MODEL_HH
using namespace std;
#define ZERO_BAND 1e-8
#include <filesystem>
#include <fstream> #include <fstream>
#include <boost/crc.hpp>
#include "Bytecode.hh"
#include "StaticModel.hh" #include "StaticModel.hh"
using namespace std;
//! Stores a dynamic model //! Stores a dynamic model
class DynamicModel : public ModelTree class DynamicModel : public ModelTree
{
friend class StaticModel; // For reading static_mfs from converting constructor
public:
//! A reference to the trend component model table
TrendComponentModelTable& trend_component_model_table;
//! A reference to the VAR model table
VarModelTable& var_model_table;
/* Used in the balanced growth test, for determining whether the
cross-derivative of a given equation, w.r.t. an endogenous and a trend
variable is zero. Controlled by option “balanced_growth_test_tol” of the
“model” block. The default should not be too small (see dynare#1389). */
double balanced_growth_test_tol {1e-6};
/* For a given equation, tracks all the regimes and the declared alternatives with combinations of
bind and relax tags */
class OccbinRegimeTracker
{ {
private: private:
// The list of constraints used for this equation
vector<string> constraints;
/* The list of regimes present for this equation; each regime is a vector of boolean, of same
length as “constraints”; each boolean represents a constraint (in the order of
“constraints”): false for relax, true for bind */
set<vector<bool>> regimes_present;
public:
struct ConstraintInBothBindAndRelaxException
{
const string constraint;
};
struct RegimeAlreadyPresentException
{
const vector<string> constraints_bind, constraints_relax;
};
void addRegime(const vector<string>& constraints_bind,
const vector<string>& constraints_relax) noexcept(false);
struct MissingRegimeException
{
const vector<string> constraints_bind, constraints_relax;
};
void checkAllRegimesPresent() const noexcept(false);
private:
[[nodiscard]] pair<vector<string>, vector<string>>
convertBitVectorToRegimes(const vector<bool>& r) const;
};
private:
/* Used in the balanced growth test, for skipping equations where the test
cannot be performed (i.e. when LHS=RHS at the initial values). Should not
be too large, otherwise the test becomes less powerful. */
constexpr static double zero_band {1e-8};
//! Stores equations declared as [static] //! Stores equations declared as [static]
/*! They will be used in toStatic() to replace equations marked as [dynamic] */ /*! They will be used in the conversion to StaticModel to replace equations marked as [dynamic] */
vector<BinaryOpNode*> static_only_equations; vector<BinaryOpNode*> static_only_equations;
//! Stores line numbers of equations declared as [static] //! Stores line numbers of equations declared as [static]
vector<int> static_only_equations_lineno; vector<optional<int>> static_only_equations_lineno;
//! Stores the equation tags of equations declared as [static] //! Stores the equation tags of equations declared as [static]
vector<vector<pair<string, string> > > static_only_equations_equation_tags; EquationTags static_only_equations_equation_tags;
// Complementarity conditions of equations declared as [static]
vector<optional<tuple<int, expr_t, expr_t>>> static_only_complementarity_conditions;
typedef map<pair<int, int>, int> deriv_id_table_t; using deriv_id_table_t = map<pair<int, int>, int>;
//! Maps a pair (symbol_id, lag) to a deriv ID //! Maps a pair (symbol_id, lag) to a deriv ID
deriv_id_table_t deriv_id_table; deriv_id_table_t deriv_id_table;
//! Maps a deriv ID to a pair (symbol_id, lag) //! Maps a deriv ID to a pair (symbol_id, lag)
vector<pair<int, int>> inv_deriv_id_table; vector<pair<int, int>> inv_deriv_id_table;
//! Maps a deriv_id to the column index of the dynamic Jacobian /* Maps a deriv_id to the column index of the dynamic Jacobian, in the legacy
/*! Contains only endogenous, exogenous and exogenous deterministic */ representation.
Contains only endogenous, exogenous and exogenous deterministic */
map<int, int> dyn_jacobian_cols_table; map<int, int> dyn_jacobian_cols_table;
// Number of columns of the dynamic Jacobian (legacy representation)
int dyn_jacobian_ncols;
//! Maximum lag and lead over all types of variables (positive values) //! Maximum lag and lead over all types of variables (positive values)
/*! Set by computeDerivIDs() */ /*! Set by computeDerivIDs() */
int max_lag, max_lead; int max_lag {0}, max_lead {0};
//! Maximum lag and lead over endogenous variables (positive values) //! Maximum lag and lead over endogenous variables (positive values)
/*! Set by computeDerivIDs() */ /*! Set by computeDerivIDs() */
int max_endo_lag, max_endo_lead; int max_endo_lag {0}, max_endo_lead {0};
//! Maximum lag and lead over exogenous variables (positive values) //! Maximum lag and lead over exogenous variables (positive values)
/*! Set by computeDerivIDs() */ /*! Set by computeDerivIDs() */
int max_exo_lag, max_exo_lead; int max_exo_lag {0}, max_exo_lead {0};
//! Maximum lag and lead over deterministic exogenous variables (positive values) //! Maximum lag and lead over deterministic exogenous variables (positive values)
/*! Set by computeDerivIDs() */ /*! Set by computeDerivIDs() */
int max_exo_det_lag, max_exo_det_lead; int max_exo_det_lag {0}, max_exo_det_lead {0};
//! Maximum lag and lead over all types of variables (positive values) of original model //! Maximum lag and lead over all types of variables (positive values) of original model
int max_lag_orig, max_lead_orig; int max_lag_orig {0}, max_lead_orig {0}, max_lag_with_diffs_expanded_orig {0};
//! Maximum lag and lead over endogenous variables (positive values) of original model //! Maximum lag and lead over endogenous variables (positive values) of original model
int max_endo_lag_orig, max_endo_lead_orig; int max_endo_lag_orig {0}, max_endo_lead_orig {0};
//! Maximum lag and lead over exogenous variables (positive values) of original model //! Maximum lag and lead over exogenous variables (positive values) of original model
int max_exo_lag_orig, max_exo_lead_orig; 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
int max_exo_det_lag_orig, max_exo_det_lead_orig; //! model
int max_exo_det_lag_orig {0}, max_exo_det_lead_orig {0};
//! Cross reference information // Cross reference information: eq → set of (symb_id, lag) for each symbol type
map<int, ExprNode::EquationInfo> xrefs; map<int, ExprNode::EquationInfo> xrefs;
map<pair<int, int>, set<int> > xref_param; // Reverse cross reference information: (symb_id, lag) → eqs
map<pair<int, int>, set<int> > xref_endo; map<pair<int, int>, set<int>> xref_param, xref_endo, xref_exo, xref_exo_det;
map<pair<int, int>, set<int> > xref_exo;
map<pair<int, int>, set<int> > xref_exo_det;
//! Nonzero equations in the Hessian //! Nonzero equations in the Hessian
map<int, string> nonzero_hessian_eqs; set<int> nonzero_hessian_eqs;
//! Number of columns of dynamic jacobian
/*! Set by computeDerivID()s and computeDynJacobianCols() */
int dynJacobianColsNbr;
//! Temporary terms for block decomposed models
vector< vector<temporary_terms_t> > v_temporary_terms;
vector<temporary_terms_inuse_t> v_temporary_terms_inuse;
//! Store the derivatives or the chainrule derivatives:map<pair< equation, pair< variable, lead_lag >, expr_t>
typedef map< pair< int, pair< int, int> >, expr_t> first_chain_rule_derivatives_t;
first_chain_rule_derivatives_t first_chain_rule_derivatives;
//! Writes dynamic model file (Matlab version)
void writeDynamicMFile(const string &dynamic_basename) const;
//! Writes dynamic model file (Julia version)
void writeDynamicJuliaFile(const string &dynamic_basename) const;
//! Writes dynamic model file (C version)
/*! \todo add third derivatives handling */
void writeDynamicCFile(const string &dynamic_basename, const int order) const;
//! Writes dynamic model file when SparseDLL option is on
void writeSparseDynamicMFile(const string &dynamic_basename, const string &basename) const;
//! Writes the dynamic model equations and its derivatives
/*! \todo add third derivatives handling in C output */
void writeDynamicModel(ostream &DynamicOutput, bool use_dll, bool julia) const;
//! Writes the Block reordred structure of the model in M output
void writeModelEquationsOrdered_M(const string &dynamic_basename) const;
//! Writes the code of the Block reordred structure of the model in virtual machine bytecode
void writeModelEquationsCode_Block(string &file_name, const string &bin_basename, const map_idx_t &map_idx) const;
//! Writes the code of the model in virtual machine bytecode
void writeModelEquationsCode(string &file_name, const string &bin_basename, const map_idx_t &map_idx) const;
//! Computes jacobian and prepares for equation normalization
/*! Using values from initval/endval blocks and parameter initializations:
- computes the jacobian for the model w.r. to contemporaneous variables
- removes edges of the incidence matrix when derivative w.r. to the corresponding variable is too close to zero (below the cutoff)
*/
//void evaluateJacobian(const eval_context_t &eval_context, jacob_map *j_m, bool dynamic);
//! return a map on the block jacobian
map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> get_Derivatives(int block);
//! Computes chain rule derivatives of the Jacobian w.r. to endogenous variables
void computeChainRuleJacobian(blocks_derivatives_t &blocks_derivatives);
string reform(string name) const;
map_idx_t map_idx;
//! sorts the temporary terms in the blocks order
void computeTemporaryTermsOrdered();
//! creates a mapping from the index of temporary terms to a natural index
void computeTemporaryTermsMapping();
//! Write derivative code of an equation w.r. to a variable
void compileDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int symb_id, int lag, const map_idx_t &map_idx) const;
//! Write chain rule derivative code of an equation w.r. to a variable
void compileChainRuleDerivative(ofstream &code_file, unsigned int &instruction_number, int eq, int var, int lag, const map_idx_t &map_idx) const;
//! Get the type corresponding to a derivation ID
virtual SymbolType getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException);
//! Get the lag corresponding to a derivation ID
virtual int getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException);
//! Get the symbol ID corresponding to a derivation ID
virtual int getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException);
//! Compute the column indices of the dynamic Jacobian
void computeDynJacobianCols(bool jacobianExo);
//! Computes derivatives of the Jacobian w.r. to trend vars and tests that they are equal to zero
void testTrendDerivativesEqualToZero(const eval_context_t &eval_context);
//! Collect only the first derivatives
map<pair<int, pair<int, int> >, expr_t> collect_first_order_derivatives_endogenous();
//! Allocates the derivation IDs for all dynamic variables of the model //! Creates mapping for variables and equations they are present in
/*! Also computes max_{endo,exo}_{lead_lag}, and initializes dynJacobianColsNbr to the number of dynamic endos */ map<int, set<int>> variableMapping;
void computeDerivIDs();
//! Write chain rule derivative of a recursive equation w.r. to a variable /* For each block, and for each variable type, maps (variable ID, lag) to
void writeChainRuleDerivative(ostream &output, int eq, int var, int lag, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; Jacobian column. The variable ID is the index within the block. */
vector<map<pair<int, int>, int>> blocks_jacob_cols_endo;
//! Collecte the derivatives w.r. to endogenous of the block, to endogenous of previouys blocks and to exogenous //! Used for var_expectation and var_model
void collect_block_first_order_derivatives(); map<string, set<int>> var_expectation_functions_to_write;
//! Collecte the informations about exogenous, deterministic exogenous and endogenous from the previous block for each block // Value of the “mfs” option of “model” block (or ”model_options” command)
void collectBlockVariables(); int mfs {1};
//! Factorized code for substitutions of leads/lags /* Value of the “static_mfs” option of “model” block (or the “model_options”
/*! \param[in] type determines which type of variables is concerned command).
\param[in] deterministic_model whether we are in a deterministic model (only for exogenous leads/lags) Only used when converting to StaticModel class. */
\param[in] subset variables to which to apply the transformation (only for diff of forward vars) int static_mfs {0};
*/
void substituteLeadLagInternal(aux_var_t type, bool deterministic_model, const vector<string> &subset);
private: // Writes dynamic model file (MATLAB/Octave version, legacy representation)
//! Indicate if the temporary terms are computed for the overall model (true) or not (false). Default value true void writeDynamicMFile(const string& basename) const;
bool global_temporary_terms; //! Writes the code of the block-decomposed model in virtual machine bytecode
void writeDynamicBlockBytecode(const string& basename) const;
//! Writes the code of the model in virtual machine bytecode
void writeDynamicBytecode(const string& basename) const;
//! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a expr_t on the new normalized equation // Write the block structure of the model in the driver file
equation_type_and_normalized_equation_t equation_type_and_normalized_equation; void writeBlockDriverOutput(ostream& output) const;
//! for each block contains pair< Simulation_Type, pair < Block_Size, Recursive_part_Size > > // Used by determineBlockDerivativesType()
block_type_firstequation_size_mfs_t block_type_firstequation_size_mfs; enum class BlockDerivativeType
{
standard,
chainRule,
normalizedChainRule
};
//! for all blocks derivatives description /* For each tuple (lag, eq, var) within the given block, determine the type
blocks_derivatives_t blocks_derivatives; of the derivative to be computed. Indices are within the block (i.e.
between 0 and blocks[blk].size-1). */
map<tuple<int, int, int>, BlockDerivativeType> determineBlockDerivativesType(int blk);
//! The jacobian without the elements below the cutoff void computeChainRuleJacobian() override;
dynamic_jacob_map_t dynamic_jacobian;
//! Vector indicating if the block is linear in endogenous variable (true) or not (false) string reform(const string& name) const;
vector<bool> blocks_linear;
//! Map the derivatives for a block pair<lag, make_pair(make_pair(eq, var)), expr_t> SymbolType getTypeByDerivID(int deriv_id) const noexcept(false) override;
typedef map<pair< int, pair<int, int> >, expr_t> derivative_t; int getLagByDerivID(int deriv_id) const noexcept(false) override;
//! Vector of derivative for each blocks int getSymbIDByDerivID(int deriv_id) const noexcept(false) override;
vector<derivative_t> derivative_endo, derivative_other_endo, derivative_exo, derivative_exo_det; int getTypeSpecificIDByDerivID(int deriv_id) const override;
//!List for each block and for each lag-lead all the other endogenous variables and exogenous variables //! Compute the column indices of the dynamic Jacobian
typedef set<int> var_t; void computeDynJacobianCols();
typedef map<int, var_t> lag_var_t; //! Computes derivatives of the Jacobian w.r. to trend vars and tests that they are equal to zero
vector<lag_var_t> other_endo_block, exo_block, exo_det_block; void testTrendDerivativesEqualToZero(const eval_context_t& eval_context);
//!List for each block the exogenous variables //! Allocates the derivation IDs for all dynamic variables of the model
vector<pair<var_t, int> > block_var_exo; /*! Also computes max_{endo,exo}_{lead_lag}, and initializes dynJacobianColsNbr to the number of
* dynamic endos */
void computeDerivIDs();
map< int, map<int, int> > block_exo_index, block_det_exo_index, block_other_endo_index; /* Compute the Jacobian column indices in the block decomposition case
(stored in blocks_jacob_cols_*).
Also fills auxiliary structures related to “other” endogenous and
exogenous: blocks{,_derivatives}_{other_endo,exo_exo_det} */
void computeBlockDynJacobianCols();
//! for each block described the number of static, forward, backward and mixed variables in the block //! Factorized code for substitutions of leads/lags
/*! pair< pair<static, forward>, pair<backward,mixed> > */ /*! \param[in] type determines which type of variables is concerned
vector<pair< pair<int, int>, pair<int, int> > > block_col_type; \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);
//! Help computeXrefs to compute the reverse references (i.e. param->eqs, endo->eqs, etc) //! 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 //! 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,
const ostringstream& init_s, const ostringstream& end_s,
const ostringstream& s, const ostringstream& s_tt) const;
/* Create the compatibility dynamic.m file for MATLAB/Octave not yet using
the temporary terms array interface (legacy representation) */
void writeDynamicMCompatFile(const string& basename) const;
//! Internal helper for the copy constructor and assignment operator
/*! Copies all the structures that contain ExprNode*, by the converting the
pointers into their equivalent in the new tree */
void copyHelper(const DynamicModel& m);
/* Handles parsing of argument passed to exclude_eqs/include_eqs.
The argument inc_exc_option_value should be of one of the following forms:
* filename.txt
* eq1
* ['eq 1', 'eq 2']
* [tagname='eq 1']
* [tagname=('eq 1', 'eq 2')]
If argument is a filename, the file should be formatted as:
eq 1
eq 2
OR
tagname=
X
Y
The boolean exclude_eqs should be true if we are in the exclude_eqs case,
false in the include_eqs case (this only affects error messages).
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);
/* Helper for the removeEquations() method.
listed_eqs_by_tag describes a list of equations to remove (identified by
one or more tags; if multiple tags are present for a single equation, they
are understood as a conjunction), exclude_eqs is a boolean indicating whether we’re
excluding or including, and excluded_vars_change_type is a boolean
indicating whether to compute variables to be excluded.
The all_equations* arguments will be modified by the routine by excluding
equations. They are either the main structures for storing equations in
ModelTree, or their counterpart for static-only equations. The
static_equations boolean indicates when we are in the latter case.
The listed_eqs_by_tag structure will be updated by removing the tags
matched with equations in the all_equations* argument*.
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<BinaryOpNode*>& all_equations, vector<optional<int>>& all_equations_lineno,
vector<optional<tuple<int, expr_t, expr_t>>>& all_complementarity_conditions,
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
arbitrarily-written expressions. */
map<string, map<tuple<int, int, int>, expr_t>> computeAutoregressiveMatrices() const;
//! 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;
/* 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
types of auxiliary variables: endo lags and diff lags). It returns a
vector because in some cases there may be sereval corresponding deriv_ids
(for example, in the deriv_id table, AUX_DIFF_nn(-1) may appear as itself
(with a lag), and also as a contemporaneous diff lag auxvar). */
vector<int> getVARDerivIDs(int lhs_symb_id, int lead_lag) const;
int
getBlockJacobianEndoCol(int blk, int var, int lag) const override
{
return blocks_jacob_cols_endo[blk].at({var, lag});
}
//! List for each variable its block number and its maximum lag and lead inside the block // Used to check consistency of bind/relax tags; the keys are equation names
vector<pair<int, pair<int, int> > > variable_block_lead_lag; map<string, OccbinRegimeTracker> occbin_regime_trackers;
//! List for each equation its block number
vector<int> equation_block;
//!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous protected:
vector<pair<int, int> > endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block; string
modelClassName() const override
{
return "dynamic model";
}
public: public:
DynamicModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg, ExternalFunctionsTable &external_functions_table_argx); DynamicModel(SymbolTable& symbol_table_arg, NumericalConstants& num_constants_arg,
//! Adds a variable node ExternalFunctionsTable& external_functions_table_arg,
/*! This implementation allows for non-zero lag */ HeterogeneityTable& heterogeneity_table_arg,
virtual VariableNode *AddVariable(int symb_id, int lag = 0); TrendComponentModelTable& trend_component_model_table_arg,
VarModelTable& var_model_table_arg);
DynamicModel(const DynamicModel& m);
DynamicModel& operator=(const DynamicModel& m);
//! Compute cross references //! Compute cross references
void computeXrefs(); void computeXrefs();
...@@ -236,19 +339,24 @@ public: ...@@ -236,19 +339,24 @@ public:
//! Write cross references //! Write cross references
void writeXrefs(ostream& output) const; void writeXrefs(ostream& output) const;
//! Execute computations (variable sorting + derivation) //! Execute computations (variable sorting + derivation + block decomposition)
/*! /*!
\param jacobianExo whether derivatives w.r. to exo and exo_det should be in the Jacobian (derivatives w.r. to endo are always computed) \param derivsOrder order of derivatives w.r. to exo, exo_det and endo should be computed
\param hessian whether 2nd derivatives w.r. to exo, exo_det and endo should be computed (implies jacobianExo = true) (implies jacobianExo = true when order >= 2) \param paramsDerivsOrder order of derivatives w.r.
\param thirdDerivatives whether 3rd derivatives w.r. to endo/exo/exo_det should be computed (implies jacobianExo = true) to a pair (endo/exo/exo_det, parameter) to be computed (>0 implies jacobianExo = true) \param
\param paramsDerivsOrder order of derivatives w.r. to a pair (endo/exo/exo_det, parameter) to be computed (>0 implies jacobianExo = true) eval_context evaluation context for normalization \param no_tmp_terms if true, no temporary
\param eval_context evaluation context for normalization terms will be computed in the dynamic files
\param no_tmp_terms if true, no temporary terms will be computed in the dynamic files
*/ */
void computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, int paramsDerivsOrder, void computingPass(int derivsOrder, int paramsDerivsOrder, const eval_context_t& eval_context,
const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode, const bool nopreprocessoroutput); bool no_tmp_terms, bool block, bool use_dll);
//! Writes model initialization and lead/lag incidence matrix to output //! Writes information about the dynamic model to the driver file
void writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll, int order, bool estimation_present, bool compute_xrefs, bool julia) const; void writeDriverOutput(ostream& output, bool compute_xrefs) const;
//! Write JSON AST
void writeJsonAST(ostream& output) const;
//! Write JSON variable mapping
void writeJsonVariableMapping(ostream& output) const;
//! Write JSON Output //! Write JSON Output
void writeJsonOutput(ostream& output) const; void writeJsonOutput(ostream& output) const;
...@@ -262,30 +370,70 @@ public: ...@@ -262,30 +370,70 @@ public:
//! Write JSON Output representation of dynamic model after computing pass //! Write JSON Output representation of dynamic model after computing pass
void writeJsonComputingPassOutput(ostream& output, bool writeDetails) const; void writeJsonComputingPassOutput(ostream& output, bool writeDetails) const;
//! Write JSON prams derivatives file //! Write JSON params derivatives
void writeJsonParamsDerivativesFile(ostream &output, bool writeDetails) const; void writeJsonParamsDerivatives(ostream& output, bool writeDetails) const;
//! Write cross reference output if the xref maps have been filed //! Write cross reference output if the xref maps have been filed
void writeJsonXrefs(ostream& output) const; void writeJsonXrefs(ostream& output) const;
void writeJsonXrefsHelper(ostream &output, const map<pair<int, int>, set<int> > &xrefs) const; void writeJsonXrefsHelper(ostream& output, const map<pair<int, int>, set<int>>& xrefmap) const;
//! Print equations that have non-zero second derivatives //! Print equations that have non-zero second derivatives
void printNonZeroHessianEquations(ostream& output) const; void printNonZeroHessianEquations(ostream& output) const;
//! Set the equations that have non-zero second derivatives //! Tells whether Hessian has been computed
void setNonZeroHessianEquations(map<int, string> &eqs); /*! This is needed to know whether no non-zero equation in Hessian means a
zero Hessian or Hessian not computed */
bool
isHessianComputed() const
{
return computed_derivs_order >= 2;
}
/* Check whether the model is linear, by verifying that the hessian is zero,
and error out otherwise.
Must be called after computingPass().
FIXME: this check always passes if derivsOrder = 1, i.e. for a perfect
foresight model, because the Hessian is not computed in that case. */
void checkIsLinear() const;
//! Fill the trend component model table with information available from the transformed model
void fillTrendComponentModelTable() const;
//! Fill the trend component model table with information available from the original model
void fillTrendComponentModelTableFromOrigModel() const;
/* Fill the trend component model table with information about AR/EC
components, available from the transformed model. Needs to be called after
fillTrendComponentModelTableFromOrigModel() has been called on the
original model */
void fillTrendComponentModelTableAREC(const ExprNode::subst_table_t& diff_subst_table) const;
//! Fill the VAR model table with information available from the transformed model
// NB: Does not fill the AR and A0 matrices
void fillVarModelTable() const;
//! Fill the VAR model table with information available from the original model
void fillVarModelTableFromOrigModel() const;
//! Fill the AR and A0 matrices of the VAR model table
// Uses derivatives, hence must be called after computingPass()
void fillVarModelTableMatrices();
//! Update the rhs references in the var model and trend component tables
//! after substitution of auxiliary variables and find the trend variables
//! in the trend_component model
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;
//! Adds informations for simulation in a binary file
void Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename,
const int &num, int &u_count_int, bool &file_open, bool is_two_boundaries) const;
//! Writes dynamic model file
void writeDynamicFile(const string &basename, bool block, bool bytecode, bool use_dll, int order, bool julia) const;
//! Writes file containing parameters derivatives //! Writes file containing parameters derivatives
void writeParamsDerivativesFile(const string &basename, bool julia) const; template<bool julia>
void writeParamsDerivativesFile(const string& basename) const;
//! Converts to static model (only the equations) //! Creates mapping for variables and equations they are present in
/*! It assumes that the static model given in argument has just been allocated */ void createVariableMapping();
void toStatic(StaticModel &static_model) const;
//! 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 //! Find endogenous variables not used in model
set<int> findUnusedEndogenous(); set<int> findUnusedEndogenous();
...@@ -295,17 +443,36 @@ public: ...@@ -295,17 +443,36 @@ public:
//! Set the max leads/lags of the original model //! Set the max leads/lags of the original model
void setLeadsLagsOrig(); void setLeadsLagsOrig();
//! Copies a dynamic model (only the equations) //! Implements the include_eqs/exclude_eqs options
/*! It assumes that the dynamic model given in argument has just been allocated */ void includeExcludeEquations(const string& inc_exc_option_value, bool exclude_eqs);
void cloneDynamic(DynamicModel &dynamic_model) const;
/* Removes equations from the model (identified by one or more tags; if
multiple tags are present for a single equation, they are understood as a
conjunction).
Used for include_eqs/exclude_eqs options and for model_remove and
model_replace blocks */
void removeEquations(const vector<map<string, string>>& listed_eqs_by_tag, bool exclude_eqs,
bool excluded_vars_change_type);
/* Replaces model equations with derivatives of Lagrangian w.r.t. endogenous.
The optimality FOCs (derivatives w.r.t. ordinary endogenous) will appear
first, followed by the constraints (derivatives w.r.t. multipliers).
Returns the number of optimality FOCs, which is by construction equal to
the number of endogenous before adding the Lagrange multipliers
(internally called ramsey_endo_nbr). */
int computeRamseyPolicyFOCs(const StaticModel& planner_objective,
map<int, pair<expr_t, expr_t>> cloned_ramsey_constraints);
//! Clears all equations
void clearEquations();
//! Replaces model equations with derivatives of Lagrangian w.r.t. endogenous
void computeRamseyPolicyFOCs(const StaticModel &static_model, const bool nopreprocessoroutput);
//! Replaces the model equations in dynamic_model with those in this model //! Replaces the model equations in dynamic_model with those in this model
void replaceMyEquations(DynamicModel& dynamic_model) const; void replaceMyEquations(DynamicModel& dynamic_model) const;
//! Adds an equation marked as [static] //! Adds an equation marked as [static]
void addStaticOnlyEquation(expr_t eq, int lineno, const vector<pair<string, string> > &eq_tags); void addStaticOnlyEquation(expr_t eq, const optional<int>& lineno,
optional<tuple<int, expr_t, expr_t>> complementarity_condition,
map<string, string> eq_tags);
//! Returns number of static only equations //! Returns number of static only equations
size_t staticOnlyEquationsNbr() const; size_t staticOnlyEquationsNbr() const;
...@@ -313,22 +480,66 @@ public: ...@@ -313,22 +480,66 @@ public:
//! Returns number of dynamic only equations //! Returns number of dynamic only equations
size_t dynamicOnlyEquationsNbr() const; size_t dynamicOnlyEquationsNbr() const;
// Adds an occbin equation (with “bind” and/or “relax” tag)
/* This function assumes that there is a “name” tag, and that the relevant
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, const optional<int>& lineno, map<string, string> eq_tags,
const vector<string>& constraints_bind,
const vector<string>& constraints_relax);
//! Writes LaTeX file with the equations of the dynamic model //! Writes LaTeX file with the equations of the dynamic model
void writeLatexFile(const string &basename, const bool write_equation_tags) const; void writeLatexFile(const string& basename, bool write_equation_tags) const;
//! Writes LaTeX file with the equations of the dynamic model (for the original model) //! Writes LaTeX file with the equations of the dynamic model (for the original model)
void writeLatexOriginalFile(const string &basename, const bool write_equation_tags) const; void writeLatexOriginalFile(const string& basename, bool write_equation_tags) const;
virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException); int getDerivID(int symb_id, int lag) const noexcept(false) override;
virtual int getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException);
virtual void addAllParamDerivId(set<int> &deriv_id_set);
//! Returns true indicating that this is a dynamic model int
virtual bool getJacobianCol(int deriv_id, bool sparse) const override
isDynamic() const
{ {
return true; if (sparse)
}; {
SymbolType type {getTypeByDerivID(deriv_id)};
int tsid {getTypeSpecificIDByDerivID(deriv_id)};
int lag {getLagByDerivID(deriv_id)};
if (type == SymbolType::endogenous)
{
assert(lag >= -1 && lag <= 1);
return tsid + (lag + 1) * symbol_table.endo_nbr();
}
else if (type == SymbolType::exogenous)
{
assert(lag == 0);
return tsid + 3 * symbol_table.endo_nbr();
}
else if (type == SymbolType::exogenousDet)
{
assert(lag == 0);
return tsid + 3 * symbol_table.endo_nbr() + symbol_table.exo_nbr();
}
else
throw UnknownDerivIDException();
}
else
{
if (auto it = dyn_jacobian_cols_table.find(deriv_id); it == dyn_jacobian_cols_table.end())
throw UnknownDerivIDException();
else
return it->second;
}
}
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;
}
void addAllParamDerivId(set<int>& deriv_id_set) override;
//! Drive test of detrended equations //! Drive test of detrended equations
void runTrendTest(const eval_context_t& eval_context); void runTrendTest(const eval_context_t& eval_context);
...@@ -347,15 +558,138 @@ public: ...@@ -347,15 +558,138 @@ public:
//! Transforms the model by removing all lags on exos //! Transforms the model by removing all lags on exos
void substituteExoLag(bool deterministic_model); void substituteExoLag(bool deterministic_model);
//! Transforms the model by removing all oExpectation //! Transforms the model by removing all UnaryOpcode::expectation
void substituteExpectation(bool partial_information_model); 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(); void transformPredeterminedVariables();
// Performs the transformations associated to variables declared with “var(log)”
void substituteLogTransform();
/* Performs the transformations associated to aggregation operators in heterogeneous models, such
as SUM(…) */
void substituteAggregationOperators();
// Check that no variable was declared with “var(log)” in the given equations
void checkNoWithLogTransform(const set<int>& eqnumbers);
//! Transforms the model by removing trends specified by the user //! Transforms the model by removing trends specified by the user
void detrendEquations(); void detrendEquations();
const nonstationary_symbols_map_t&
getNonstationarySymbolsMap() const
{
return nonstationary_symbols_map;
}
const map<int, expr_t>&
getTrendSymbolsMap() const
{
return trend_symbols_map;
}
//! Substitutes adl operator
void substituteAdl();
//! Substitutes out all model-local variables
void substituteModelLocalVariables();
/* 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);
/* 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);
//! Substitutes diff operator
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);
// Exception thrown by getPacTargetSymbId()
struct PacTargetNotIdentifiedException
{
const string model_name, message;
};
//! Return target of the pac equation
int getPacTargetSymbId(const string& pac_model_name) const;
/* For a PAC MCE model, fill pac_expectation_substitution with the
expression that will be substituted for the pac_expectation operator.
In the process, add the variable and the equation defining Z₁.
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,
map<string, expr_t>& pac_expectation_substitution);
/* For a PAC MCE model with an associated pac_target_info, fill pac_expectation_substitution with
the expression that will be substituted for the pac_expectation operator. In the process, add
the variables and the equations defining Z₁ and Z₀ for each component. The new auxiliary
parameters are added to pac_mce_alpha_symb_ids. The routine also creates the auxiliary
variables for the components, and adds the corresponding equations.
*/
void computePacModelConsistentExpectationSubstitutionWithComponents(
const string& name, int discount_symb_id, int pac_eq_max_lag,
ExprNode::subst_table_t& diff_subst_table, map<string, vector<int>>& pac_aux_param_symb_ids,
vector<PacModelTable::target_component_t>& pac_target_components,
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,
map<string, int>& pac_aux_var_symb_ids,
map<string, vector<int>>& pac_aux_param_symb_ids,
map<string, expr_t>& pac_expectation_substitution);
/* Same as above, but for PAC models which have an associated
pac_target_info.
Contrary to the above routine, this one will create the growth correction
parameters as needed.
Those parameter IDs, as well as the IDs for the h parameters, are stored
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,
vector<PacModelTable::target_component_t>& pac_target_components,
map<string, expr_t>& pac_expectation_substitution);
//! Substitutes pac_expectation operator with expectation based on auxiliary model
void substitutePacExpectation(const map<string, expr_t>& pac_expectation_substitution,
const map<string, string>& pac_eq_name);
//! Substitutes the pac_target_nonstationary operator of a given pac_model
void substitutePacTargetNonstationary(const string& pac_model_name, expr_t substexpr);
//! Table to undiff LHS variables for pac vector z
vector<int> getUndiffLHSForPac(const string& aux_model_name,
const ExprNode::subst_table_t& diff_subst_table) const;
//! Transforms the model by replacing trend variables with a 1 //! Transforms the model by replacing trend variables with a 1
void removeTrendVariableFromEquations(); void removeTrendVariableFromEquations();
...@@ -367,213 +701,265 @@ public: ...@@ -367,213 +701,265 @@ public:
//! Fills eval context with values of model local variables and auxiliary variables //! Fills eval context with values of model local variables and auxiliary variables
void fillEvalContext(eval_context_t& eval_context) const; void fillEvalContext(eval_context_t& eval_context) const;
//! Return the number of blocks /*! Checks that all pac_expectation operators have been substituted, error
virtual unsigned int out otherwise */
getNbBlocks() const void checkNoRemainingPacExpectation() const;
{
return (block_type_firstequation_size_mfs.size()); /*! Checks that all pac_target_nonstationary operators have been substituted, error
}; out otherwise */
//! Determine the simulation type of each block void checkNoRemainingPacTargetNonstationary() const;
virtual BlockSimulationType
getBlockSimulationType(int block_number) const auto
{ getStaticOnlyEquationsInfo() const
return (block_type_firstequation_size_mfs[block_number].first.first);
};
//! Return the first equation number of a block
virtual unsigned int
getBlockFirstEquation(int block_number) const
{
return (block_type_firstequation_size_mfs[block_number].first.second);
};
//! Return the size of the block block_number
virtual unsigned int
getBlockSize(int block_number) const
{
return (block_type_firstequation_size_mfs[block_number].second.first);
};
//! Return the number of exogenous variable in the block block_number
virtual unsigned int
getBlockExoSize(int block_number) const
{
return (block_var_exo[block_number].first.size());
};
//! Return the number of colums in the jacobian matrix for exogenous variable in the block block_number
virtual unsigned int
getBlockExoColSize(int block_number) const
{
return (block_var_exo[block_number].second);
};
//! Return the number of feedback variable of the block block_number
virtual unsigned int
getBlockMfs(int block_number) const
{
return (block_type_firstequation_size_mfs[block_number].second.second);
};
//! Return the maximum lag in a block
virtual unsigned int
getBlockMaxLag(int block_number) const
{
return (block_lag_lead[block_number].first);
};
//! Return the maximum lead in a block
virtual unsigned int
getBlockMaxLead(int block_number) const
{
return (block_lag_lead[block_number].second);
};
//! Return the type of equation (equation_number) belonging to the block block_number
virtual EquationType
getBlockEquationType(int block_number, int equation_number) const
{
return (equation_type_and_normalized_equation[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]].first);
};
//! Return true if the equation has been normalized
virtual bool
isBlockEquationRenormalized(int block_number, int equation_number) const
{
return (equation_type_and_normalized_equation[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]].first == E_EVALUATE_S);
};
//! Return the expr_t of the equation equation_number belonging to the block block_number
virtual expr_t
getBlockEquationExpr(int block_number, int equation_number) const
{
return (equations[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]]);
};
//! Return the expr_t of the renormalized equation equation_number belonging to the block block_number
virtual expr_t
getBlockEquationRenormalizedExpr(int block_number, int equation_number) const
{
return (equation_type_and_normalized_equation[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]].second);
};
//! Return the original number of equation equation_number belonging to the block block_number
virtual int
getBlockEquationID(int block_number, int equation_number) const
{
return (equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]);
};
//! Return the original number of variable variable_number belonging to the block block_number
virtual int
getBlockVariableID(int block_number, int variable_number) const
{
return (variable_reordered[block_type_firstequation_size_mfs[block_number].first.second+variable_number]);
};
//! Return the original number of the exogenous variable varexo_number belonging to the block block_number
virtual int
getBlockVariableExoID(int block_number, int variable_number) const
{
map<int, var_t>::const_iterator it = exo_block[block_number].find(variable_number);
return (it->first);
};
//! Return the position of equation_number in the block number belonging to the block block_number
virtual int
getBlockInitialEquationID(int block_number, int equation_number) const
{
return ((int) inv_equation_reordered[equation_number] - (int) block_type_firstequation_size_mfs[block_number].first.second);
};
//! Return the position of variable_number in the block number belonging to the block block_number
virtual int
getBlockInitialVariableID(int block_number, int variable_number) const
{ {
return ((int) inv_variable_reordered[variable_number] - (int) block_type_firstequation_size_mfs[block_number].first.second); return tuple {static_only_equations, static_only_equations_lineno,
}; static_only_complementarity_conditions, static_only_equations_equation_tags};
//! Return the block number containing the endogenous variable variable_number }
//! Returns true if a parameter was used in the model block with a lead or lag
bool ParamUsedWithLeadLag() const;
bool isChecksumMatching(const string& basename) const;
//! Simplify model equations: if a variable is equal to a constant, replace that variable
//! elsewhere in the model
/*! Equations with MCP tags are excluded, see dynare#1697 */
void simplifyEquations();
// Converts a set of equation tags into the corresponding set of equation numbers
set<int> getEquationNumbersFromTags(const set<string>& eqtags) const;
// Returns the set of equations (as numbers) which have a pac_expectation operator
set<int> findPacExpectationEquationNumbers() const;
int int
getBlockVariableID(int variable_number) const getMFS() const override
{ {
return (variable_block_lead_lag[variable_number].first); return mfs;
};
//! Return the position of the exogenous variable_number in the block number belonging to the block block_number
virtual int
getBlockInitialExogenousID(int block_number, int variable_number) const
{
map< int, map<int, int> >::const_iterator it = block_exo_index.find(block_number);
if (it != block_exo_index.end())
{
map<int, int>::const_iterator it1 = it->second.find(variable_number);
if (it1 != it->second.end())
return it1->second;
else
return -1;
} }
else
return (-1); void
}; setMFS(int mfs_arg)
//! Return the position of the deterministic exogenous variable_number in the block number belonging to the block block_number
virtual int
getBlockInitialDetExogenousID(int block_number, int variable_number) const
{
map< int, map<int, int> >::const_iterator it = block_det_exo_index.find(block_number);
if (it != block_det_exo_index.end())
{ {
map<int, int>::const_iterator it1 = it->second.find(variable_number); mfs = mfs_arg;
if (it1 != it->second.end())
return it1->second;
else
return -1;
} }
else
return (-1); void
}; setStaticMFS(int static_mfs_arg)
//! Return the position of the other endogenous variable_number in the block number belonging to the block block_number
virtual int
getBlockInitialOtherEndogenousID(int block_number, int variable_number) const
{
map< int, map<int, int> >::const_iterator it = block_other_endo_index.find(block_number);
if (it != block_other_endo_index.end())
{ {
map<int, int>::const_iterator it1 = it->second.find(variable_number); static_mfs = static_mfs_arg;
if (it1 != it->second.end())
return it1->second;
else
return -1;
} }
else
return (-1); // Checks that all alternatives are declared for all Occbin regimes in all equations
void checkOccbinRegimes() const;
}; };
bool isModelLocalVariableUsed() const;
//! Returns true if a parameter was used in the model block with a lead or lag template<bool julia>
bool ParamUsedWithLeadLag() const; void
DynamicModel::writeParamsDerivativesFile(const string& basename) const
{
if (!params_derivatives.size())
return;
//! Writes model initialization and lead/lag incidence matrix to C output constexpr ExprNodeOutputType output_type {julia ? ExprNodeOutputType::juliaDynamicModel
void writeCOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll, int order, bool estimation_present) const; : ExprNodeOutputType::matlabDynamicModel};
//! Writes model initialization and lead/lag incidence matrix to Cpp output
void writeCCOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll, int order, bool estimation_present) const;
//! Writes C file containing residuals
void writeResidualsC(const string &basename, bool cuda) const;
//! Writes C file containing first order derivatives of model evaluated at steady state
void writeFirstDerivativesC(const string &basename, bool cuda) const;
//! Writes C file containing first order derivatives of model evaluated at steady state (conpressed sparse column)
void writeFirstDerivativesC_csr(const string &basename, bool cuda) const;
//! Writes C file containing second order derivatives of model evaluated at steady state (compressed sparse column)
void writeSecondDerivativesC_csr(const string &basename, bool cuda) const;
//! Writes C file containing third order derivatives of model evaluated at steady state (compressed sparse column)
void writeThirdDerivativesC_csr(const string &basename, bool cuda) const;
bool isChecksumMatching(const string &basename) const; auto [tt_output, rp_output, gp_output, rpp_output, gpp_output, hp_output,
}; g3p_output] {writeParamsDerivativesFileHelper<output_type>()};
//! Classes to re-order derivatives for various sparse storage formats if constexpr (!julia)
class derivative
{ {
public: filesystem::path filename {packageDir(basename) / "dynamic_params_derivs.m"};
long unsigned int linear_address; ofstream paramsDerivsFile {filename, ios::out | ios::binary};
long unsigned int col_nbr; if (!paramsDerivsFile.is_open())
unsigned int row_nbr;
expr_t value;
derivative(long unsigned int arg1, long unsigned int arg2, int arg3, expr_t arg4) :
linear_address(arg1), col_nbr(arg2), row_nbr(arg3), value(arg4)
{ {
}; cerr << "ERROR: Can't open file " << filename.string() << " for writing" << endl;
}; exit(EXIT_FAILURE);
}
class derivative_less_than paramsDerivsFile
{ << "function [rp, gp, rpp, gpp, hp, g3p] = dynamic_params_derivs(y, x, params, "
public: "steady_state, it_, ss_param_deriv, ss_param_2nd_deriv)"
bool << endl
operator()(const derivative &d1, const derivative &d2) const << "%" << endl
<< "% Compute the derivatives of the dynamic model with respect to the parameters" << endl
<< "% Inputs :" << endl
<< "% y [#dynamic variables by 1] double vector of endogenous variables in "
"the order stored"
<< endl
<< "% in M_.lead_lag_incidence; see the "
"Manual"
<< endl
<< "% x [nperiods by M_.exo_nbr] double matrix of exogenous variables (in "
"declaration order)"
<< endl
<< "% for all simulation periods" << endl
<< "% params [M_.param_nbr by 1] double vector of parameter values in "
"declaration order"
<< endl
<< "% steady_state [M_.endo_nbr by 1] double vector of steady state values"
<< endl
<< "% it_ scalar double time period for exogenous "
"variables for which to evaluate the model"
<< endl
<< "% ss_param_deriv [M_.eq_nbr by #params] Jacobian matrix of the steady "
"states values with respect to the parameters"
<< endl
<< "% ss_param_2nd_deriv [M_.eq_nbr by #params by #params] Hessian matrix of the "
"steady states values with respect to the parameters"
<< endl
<< "%" << endl
<< "% Outputs:" << endl
<< "% rp [M_.eq_nbr by #params] double Jacobian matrix of dynamic model "
"equations with respect to parameters "
<< endl
<< "% Dynare may prepend or append "
"auxiliary equations, see M_.aux_vars"
<< endl
<< "% gp [M_.endo_nbr by #dynamic variables by #params] double Derivative of "
"the Jacobian matrix of the dynamic model equations with respect to the parameters"
<< endl
<< "% rows: equations in order "
"of declaration"
<< endl
<< "% columns: variables in "
"order stored in M_.lead_lag_incidence"
<< endl
<< "% rpp [#second_order_residual_terms by 4] double Hessian matrix of second "
"derivatives of residuals with respect to parameters;"
<< endl
<< "% rows: respective "
"derivative term"
<< endl
<< "% 1st column: equation "
"number of the term appearing"
<< endl
<< "% 2nd column: number of "
"the first parameter in derivative"
<< endl
<< "% 3rd column: number of "
"the second parameter in derivative"
<< endl
<< "% 4th column: value of "
"the Hessian term"
<< endl
<< "% gpp [#second_order_Jacobian_terms by 5] double Hessian matrix of second "
"derivatives of the Jacobian with respect to the parameters;"
<< endl
<< "% rows: respective "
"derivative term"
<< endl
<< "% 1st column: equation "
"number of the term appearing"
<< endl
<< "% 2nd column: column "
"number of variable in Jacobian of the dynamic model"
<< endl
<< "% 3rd column: number of "
"the first parameter in derivative"
<< endl
<< "% 4th column: number of "
"the second parameter in derivative"
<< endl
<< "% 5th column: value of "
"the Hessian term"
<< endl
<< "% hp [#first_order_Hessian_terms by 5] double Jacobian matrix of "
"derivatives of the dynamic Hessian with respect to the parameters;"
<< endl
<< "% rows: respective "
"derivative term"
<< endl
<< "% 1st column: equation "
"number of the term appearing"
<< endl
<< "% 2nd column: column "
"number of first variable in Hessian of the dynamic model"
<< endl
<< "% 3rd column: column "
"number of second variable in Hessian of the dynamic model"
<< endl
<< "% 4th column: number of "
"the parameter in derivative"
<< endl
<< "% 5th column: value of "
"the Hessian term"
<< endl
<< "% g3p [#first_order_g3_terms by 6] double Jacobian matrix of derivatives of "
"g3 (dynamic 3rd derivs) with respect to the parameters;"
<< endl
<< "% rows: respective "
"derivative term"
<< endl
<< "% 1st column: equation "
"number of the term appearing"
<< endl
<< "% 2nd column: column "
"number of first variable in g3 of the dynamic model"
<< endl
<< "% 3rd column: column "
"number of second variable in g3 of the dynamic model"
<< endl
<< "% 4th column: column "
"number of third variable in g3 of the dynamic model"
<< endl
<< "% 5th column: number of "
"the parameter in derivative"
<< endl
<< "% 6th column: value of "
"the Hessian term"
<< endl
<< "%" << endl
<< "%" << endl
<< "% Warning : this file is generated automatically by Dynare" << endl
<< "% from model file (.mod)" << endl
<< endl
<< "T = NaN(" << params_derivs_temporary_terms_idxs.size() << ",1);" << endl
<< tt_output.str() << "rp = zeros(" << equations.size() << ", "
<< symbol_table.param_nbr() << ");" << endl
<< rp_output.str() << "gp = zeros(" << equations.size() << ", "
<< getJacobianColsNbr(false) << ", " << symbol_table.param_nbr() << ");" << endl
<< gp_output.str() << "if nargout >= 3" << endl
<< "rpp = zeros(" << params_derivatives.at({0, 2}).size() << ",4);" << endl
<< rpp_output.str() << "gpp = zeros(" << params_derivatives.at({1, 2}).size() << ",5);"
<< endl
<< gpp_output.str() << "end" << endl
<< "if nargout >= 5" << endl
<< "hp = zeros(" << params_derivatives.at({2, 1}).size() << ",5);" << endl
<< hp_output.str() << "end" << endl
<< "if nargout >= 6" << endl
<< "g3p = zeros(" << params_derivatives.at({3, 1}).size() << ",6);" << endl
<< g3p_output.str() << "end" << endl
<< "end" << endl;
paramsDerivsFile.close();
}
else
{ {
return d1.linear_address < d2.linear_address; stringstream output;
output << "# NB: this file was automatically generated by Dynare" << endl
<< "# from " << basename << ".mod" << endl
<< "#" << endl
<< "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() << ", "
<< 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
<< "return (rp, gp, rpp, gpp, hp, g3p)" << endl
<< "end" << endl;
writeToFileIfModified(output, filesystem::path {basename} / "model" / "julia"
/ "DynamicParamsDerivs.jl");
} }
}; }
#endif #endif
Source diff could not be displayed: it is too large. Options to address this: view the blob.
/* -*- C++ -*- */
/* /*
* Copyright (C) 2003-2017 Dynare Team * Copyright © 2003-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -14,16 +15,15 @@ ...@@ -14,16 +15,15 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>. * along with Dynare. If not, see <https://www.gnu.org/licenses/>.
*/ */
%{ %{
using namespace std;
#include <cstring>
#include "ParsingDriver.hh" #include "ParsingDriver.hh"
using namespace std;
// Announce to Flex the prototype we want for lexing function // Announce to Flex the prototype we want for lexing function
#define YY_DECL \ #define YY_DECL \
Dynare::parser::token_type \ Dynare::parser::token_type \
...@@ -32,7 +32,7 @@ using namespace std; ...@@ -32,7 +32,7 @@ using namespace std;
ParsingDriver& driver) ParsingDriver& driver)
// Shortcut to access tokens defined by Bison // Shortcut to access tokens defined by Bison
typedef Dynare::parser::token token; using token = Dynare::parser::token;
/* By default yylex returns int, we use token_type. /* By default yylex returns int, we use token_type.
Unfortunately yyterminate by default returns 0, which is Unfortunately yyterminate by default returns 0, which is
...@@ -40,18 +40,17 @@ typedef Dynare::parser::token token; ...@@ -40,18 +40,17 @@ typedef Dynare::parser::token token;
#define yyterminate() return Dynare::parser::token_type(0); #define yyterminate() return Dynare::parser::token_type(0);
int comment_caller, line_caller; int comment_caller, line_caller;
/* Particular value : when sigma_e command is found
this flag is set to 1, when command finished it is set to 0
*/
int sigma_e = 0;
string eofbuff; string eofbuff;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
%} %}
%option c++ %option c++
%option prefix="Dynare" %option prefix="Dynare"
%option case-insensitive noyywrap nounput batch debug never-interactive %option case-insensitive noyywrap batch debug never-interactive
/* NB: if new start conditions are defined, add them in the line for <<EOF>> */ /* NB: if new start conditions are defined, add them in the line for <<EOF>> */
%x COMMENT %x COMMENT
...@@ -60,7 +59,6 @@ string eofbuff; ...@@ -60,7 +59,6 @@ string eofbuff;
%x VERBATIM_BLOCK %x VERBATIM_BLOCK
%x NATIVE %x NATIVE
%x NATIVE_COMMENT %x NATIVE_COMMENT
%x DATES_STATEMENT
%x LINE1 %x LINE1
%x LINE2 %x LINE2
%x LINE3 %x LINE3
...@@ -70,7 +68,9 @@ string eofbuff; ...@@ -70,7 +68,9 @@ string eofbuff;
#define YY_USER_ACTION location_increment(yylloc, yytext); #define YY_USER_ACTION location_increment(yylloc, yytext);
%} %}
DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2])) NAME [a-z_][a-z0-9_]*
FLOAT_NUMBER ((([0-9]*\.[0-9]+)|([0-9]+\.))([ed][-+]?[0-9]+)?)|([0-9]+[ed][-+]?[0-9]+)
DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]|[sh][12])
%% %%
/* Code put at the beginning of yylex() */ /* Code put at the beginning of yylex() */
...@@ -82,7 +82,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -82,7 +82,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
/* Rules for matching $line directives */ /* Rules for matching $line directives */
<*>^@#line\ \" { line_caller = YYSTATE; BEGIN(LINE1); } <*>^@#line\ \" { line_caller = YYSTATE; BEGIN(LINE1); }
<LINE1>[^\"]* { <LINE1>[^\"]* {
filename = string(yytext); filename = yytext;
BEGIN(LINE2); BEGIN(LINE2);
} }
<LINE2>\" BEGIN(LINE3); <LINE2>\" BEGIN(LINE3);
...@@ -92,13 +92,12 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -92,13 +92,12 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
} }
/* spaces, tabs and carriage returns are ignored */ /* spaces, tabs and carriage returns are ignored */
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,COMMENT,DATES_STATEMENT,LINE1,LINE2,LINE3>[ \t\r\f]+ { yylloc->step(); } <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,COMMENT,LINE1,LINE2,LINE3>[[:space:]]+ { yylloc->step(); }
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,COMMENT,DATES_STATEMENT,LINE1,LINE2,LINE3>[\n]+ { yylloc->step(); }
/* Comments */ /* Comments */
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,DATES_STATEMENT>["%"].* <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK>%.*
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,DATES_STATEMENT>["/"]["/"].* <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK>"//".*
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,DATES_STATEMENT>"/*" {comment_caller = YY_START; BEGIN COMMENT;} <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK>"/*" {comment_caller = YY_START; BEGIN COMMENT;}
<COMMENT>"*/" {BEGIN comment_caller;} <COMMENT>"*/" {BEGIN comment_caller;}
<COMMENT>. <COMMENT>.
...@@ -112,12 +111,13 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -112,12 +111,13 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<INITIAL>predetermined_variables {BEGIN DYNARE_STATEMENT; return token::PREDETERMINED_VARIABLES;} <INITIAL>predetermined_variables {BEGIN DYNARE_STATEMENT; return token::PREDETERMINED_VARIABLES;}
<INITIAL>parameters {BEGIN DYNARE_STATEMENT; return token::PARAMETERS;} <INITIAL>parameters {BEGIN DYNARE_STATEMENT; return token::PARAMETERS;}
<INITIAL>model_local_variable {BEGIN DYNARE_STATEMENT; return token::MODEL_LOCAL_VARIABLE;} <INITIAL>model_local_variable {BEGIN DYNARE_STATEMENT; return token::MODEL_LOCAL_VARIABLE;}
<INITIAL>periods {BEGIN DYNARE_STATEMENT; return token::PERIODS;} <INITIAL>heterogeneity_dimension {BEGIN DYNARE_STATEMENT; return token::HETEROGENEITY_DIMENSION;}
<INITIAL>model_info {BEGIN DYNARE_STATEMENT; return token::MODEL_INFO;} <INITIAL>model_info {BEGIN DYNARE_STATEMENT; return token::MODEL_INFO;}
<INITIAL>estimation {BEGIN DYNARE_STATEMENT; return token::ESTIMATION;} <INITIAL>estimation {BEGIN DYNARE_STATEMENT; return token::ESTIMATION;}
<INITIAL>set_time {BEGIN DYNARE_STATEMENT; return token::SET_TIME;} <INITIAL>set_time {BEGIN DYNARE_STATEMENT; return token::SET_TIME;}
<INITIAL>data {BEGIN DYNARE_STATEMENT; return token::DATA;} <INITIAL>data {BEGIN DYNARE_STATEMENT; return token::DATA;}
<INITIAL>varobs {BEGIN DYNARE_STATEMENT; return token::VAROBS;} <INITIAL>varobs {BEGIN DYNARE_STATEMENT; return token::VAROBS;}
<INITIAL>varexobs {BEGIN DYNARE_STATEMENT; return token::VAREXOBS;}
<INITIAL>unit_root_vars {BEGIN DYNARE_STATEMENT; return token::UNIT_ROOT_VARS;} <INITIAL>unit_root_vars {BEGIN DYNARE_STATEMENT; return token::UNIT_ROOT_VARS;}
<INITIAL>rplot {BEGIN DYNARE_STATEMENT; return token::RPLOT;} <INITIAL>rplot {BEGIN DYNARE_STATEMENT; return token::RPLOT;}
<INITIAL>osr_params {BEGIN DYNARE_STATEMENT; return token::OSR_PARAMS;} <INITIAL>osr_params {BEGIN DYNARE_STATEMENT; return token::OSR_PARAMS;}
...@@ -137,17 +137,27 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -137,17 +137,27 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<INITIAL>check {BEGIN DYNARE_STATEMENT; return token::CHECK;} <INITIAL>check {BEGIN DYNARE_STATEMENT; return token::CHECK;}
<INITIAL>simul {BEGIN DYNARE_STATEMENT; return token::SIMUL;} <INITIAL>simul {BEGIN DYNARE_STATEMENT; return token::SIMUL;}
<INITIAL>stoch_simul {BEGIN DYNARE_STATEMENT; return token::STOCH_SIMUL;} <INITIAL>stoch_simul {BEGIN DYNARE_STATEMENT; return token::STOCH_SIMUL;}
<INITIAL>var_model {BEGIN DYNARE_STATEMENT; return token::VAR_MODEL;}
<INITIAL>trend_component_model {BEGIN DYNARE_STATEMENT; return token::TREND_COMPONENT_MODEL;}
<INITIAL>var_expectation_model {BEGIN DYNARE_STATEMENT; return token::VAR_EXPECTATION_MODEL;}
<INITIAL>pac_model {BEGIN DYNARE_STATEMENT; return token::PAC_MODEL;}
<INITIAL>dsample {BEGIN DYNARE_STATEMENT; return token::DSAMPLE;} <INITIAL>dsample {BEGIN DYNARE_STATEMENT; return token::DSAMPLE;}
<INITIAL>Sigma_e {BEGIN DYNARE_STATEMENT; sigma_e = 1; return token::SIGMA_E;}
<INITIAL>planner_objective {BEGIN DYNARE_STATEMENT; return token::PLANNER_OBJECTIVE;} <INITIAL>planner_objective {BEGIN DYNARE_STATEMENT; return token::PLANNER_OBJECTIVE;}
<INITIAL>ramsey_model {BEGIN DYNARE_STATEMENT; return token::RAMSEY_MODEL;} <INITIAL>ramsey_model {BEGIN DYNARE_STATEMENT; return token::RAMSEY_MODEL;}
<INITIAL>ramsey_policy {BEGIN DYNARE_STATEMENT; return token::RAMSEY_POLICY;} <INITIAL>ramsey_policy {BEGIN DYNARE_STATEMENT; return token::RAMSEY_POLICY;}
<INITIAL>evaluate_planner_objective {BEGIN DYNARE_STATEMENT; return token::EVALUATE_PLANNER_OBJECTIVE;}
<INITIAL>occbin_setup {BEGIN DYNARE_STATEMENT; return token::OCCBIN_SETUP;}
<INITIAL>occbin_solver {BEGIN DYNARE_STATEMENT; return token::OCCBIN_SOLVER;}
<INITIAL>occbin_write_regimes {BEGIN DYNARE_STATEMENT; return token::OCCBIN_WRITE_REGIMES;}
<INITIAL>occbin_graph {BEGIN DYNARE_STATEMENT; return token::OCCBIN_GRAPH;}
<INITIAL>discretionary_policy {BEGIN DYNARE_STATEMENT; return token::DISCRETIONARY_POLICY;} <INITIAL>discretionary_policy {BEGIN DYNARE_STATEMENT; return token::DISCRETIONARY_POLICY;}
<INITIAL>identification {BEGIN DYNARE_STATEMENT; return token::IDENTIFICATION;} <INITIAL>identification {BEGIN DYNARE_STATEMENT; return token::IDENTIFICATION;}
<INITIAL>bvar_density {BEGIN DYNARE_STATEMENT; return token::BVAR_DENSITY; } <INITIAL>bvar_density {BEGIN DYNARE_STATEMENT; return token::BVAR_DENSITY; }
<INITIAL>bvar_forecast {BEGIN DYNARE_STATEMENT; return token::BVAR_FORECAST; } <INITIAL>bvar_forecast {BEGIN DYNARE_STATEMENT; return token::BVAR_FORECAST; }
<INITIAL>dynare_sensitivity {BEGIN DYNARE_STATEMENT; return token::DYNARE_SENSITIVITY;} <INITIAL>bvar_irf {BEGIN DYNARE_STATEMENT; return token::BVAR_IRF; }
<INITIAL>sensitivity {BEGIN DYNARE_STATEMENT; return token::SENSITIVITY;}
<INITIAL>dynare_sensitivity {BEGIN DYNARE_STATEMENT; return token::DYNARE_SENSITIVITY;} // Deprecated
<INITIAL>initval_file {BEGIN DYNARE_STATEMENT; return token::INITVAL_FILE;} <INITIAL>initval_file {BEGIN DYNARE_STATEMENT; return token::INITVAL_FILE;}
<INITIAL>histval_file {BEGIN DYNARE_STATEMENT; return token::HISTVAL_FILE;} <INITIAL>histval_file {BEGIN DYNARE_STATEMENT; return token::HISTVAL_FILE;}
<INITIAL>forecast {BEGIN DYNARE_STATEMENT; return token::FORECAST;} <INITIAL>forecast {BEGIN DYNARE_STATEMENT; return token::FORECAST;}
...@@ -155,6 +165,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -155,6 +165,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<INITIAL>realtime_shock_decomposition {BEGIN DYNARE_STATEMENT; return token::REALTIME_SHOCK_DECOMPOSITION;} <INITIAL>realtime_shock_decomposition {BEGIN DYNARE_STATEMENT; return token::REALTIME_SHOCK_DECOMPOSITION;}
<INITIAL>plot_shock_decomposition {BEGIN DYNARE_STATEMENT; return token::PLOT_SHOCK_DECOMPOSITION;} <INITIAL>plot_shock_decomposition {BEGIN DYNARE_STATEMENT; return token::PLOT_SHOCK_DECOMPOSITION;}
<INITIAL>initial_condition_decomposition {BEGIN DYNARE_STATEMENT; return token::INITIAL_CONDITION_DECOMPOSITION;} <INITIAL>initial_condition_decomposition {BEGIN DYNARE_STATEMENT; return token::INITIAL_CONDITION_DECOMPOSITION;}
<INITIAL>squeeze_shock_decomposition {BEGIN DYNARE_STATEMENT; return token::SQUEEZE_SHOCK_DECOMPOSITION;}
<INITIAL>sbvar {BEGIN DYNARE_STATEMENT; return token::SBVAR;} <INITIAL>sbvar {BEGIN DYNARE_STATEMENT; return token::SBVAR;}
<INITIAL>ms_estimation {BEGIN DYNARE_STATEMENT; return token::MS_ESTIMATION;} <INITIAL>ms_estimation {BEGIN DYNARE_STATEMENT; return token::MS_ESTIMATION;}
<INITIAL>ms_simulation {BEGIN DYNARE_STATEMENT; return token::MS_SIMULATION;} <INITIAL>ms_simulation {BEGIN DYNARE_STATEMENT; return token::MS_SIMULATION;}
...@@ -165,8 +176,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -165,8 +176,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<INITIAL>ms_variance_decomposition {BEGIN DYNARE_STATEMENT; return token::MS_VARIANCE_DECOMPOSITION;} <INITIAL>ms_variance_decomposition {BEGIN DYNARE_STATEMENT; return token::MS_VARIANCE_DECOMPOSITION;}
<INITIAL>conditional_forecast {BEGIN DYNARE_STATEMENT; return token::CONDITIONAL_FORECAST;} <INITIAL>conditional_forecast {BEGIN DYNARE_STATEMENT; return token::CONDITIONAL_FORECAST;}
<INITIAL>plot_conditional_forecast {BEGIN DYNARE_STATEMENT; return token::PLOT_CONDITIONAL_FORECAST;} <INITIAL>plot_conditional_forecast {BEGIN DYNARE_STATEMENT; return token::PLOT_CONDITIONAL_FORECAST;}
<INITIAL>gmm_estimation {BEGIN DYNARE_STATEMENT; return token::GMM_ESTIMATION;} <INITIAL>method_of_moments {BEGIN DYNARE_STATEMENT; return token::METHOD_OF_MOMENTS;}
<INITIAL>smm_estimation {BEGIN DYNARE_STATEMENT; return token::SMM_ESTIMATION;}
<INITIAL>markov_switching {BEGIN DYNARE_STATEMENT; return token::MARKOV_SWITCHING;} <INITIAL>markov_switching {BEGIN DYNARE_STATEMENT; return token::MARKOV_SWITCHING;}
<INITIAL>svar {BEGIN DYNARE_STATEMENT; return token::SVAR;} <INITIAL>svar {BEGIN DYNARE_STATEMENT; return token::SVAR;}
...@@ -179,12 +189,15 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -179,12 +189,15 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<INITIAL>smoother2histval {BEGIN DYNARE_STATEMENT; return token::SMOOTHER2HISTVAL;} <INITIAL>smoother2histval {BEGIN DYNARE_STATEMENT; return token::SMOOTHER2HISTVAL;}
<INITIAL>perfect_foresight_setup {BEGIN DYNARE_STATEMENT; return token::PERFECT_FORESIGHT_SETUP;} <INITIAL>perfect_foresight_setup {BEGIN DYNARE_STATEMENT; return token::PERFECT_FORESIGHT_SETUP;}
<INITIAL>perfect_foresight_solver {BEGIN DYNARE_STATEMENT; return token::PERFECT_FORESIGHT_SOLVER;} <INITIAL>perfect_foresight_solver {BEGIN DYNARE_STATEMENT; return token::PERFECT_FORESIGHT_SOLVER;}
<INITIAL>perfect_foresight_with_expectation_errors_setup {BEGIN DYNARE_STATEMENT; return token::PERFECT_FORESIGHT_WITH_EXPECTATION_ERRORS_SETUP;}
<INITIAL>perfect_foresight_with_expectation_errors_solver {BEGIN DYNARE_STATEMENT; return token::PERFECT_FORESIGHT_WITH_EXPECTATION_ERRORS_SOLVER;}
<INITIAL>compilation_setup {BEGIN DYNARE_STATEMENT; return token::COMPILATION_SETUP;}
<INITIAL>model_remove {BEGIN DYNARE_STATEMENT; return token::MODEL_REMOVE;}
<INITIAL>model_options {BEGIN DYNARE_STATEMENT; return token::MODEL_OPTIONS;}
<INITIAL>var_remove {BEGIN DYNARE_STATEMENT; return token::VAR_REMOVE;}
<INITIAL>resid {BEGIN DYNARE_STATEMENT; return token::RESID;}
<DYNARE_STATEMENT>; { <DYNARE_STATEMENT>; {BEGIN INITIAL; return Dynare::parser::token_type (yytext[0]);}
if (!sigma_e)
BEGIN INITIAL;
return Dynare::parser::token_type (yytext[0]);
}
/* Begin of a Dynare block */ /* Begin of a Dynare block */
...@@ -193,16 +206,22 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -193,16 +206,22 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<INITIAL>initval {BEGIN DYNARE_BLOCK; return token::INITVAL;} <INITIAL>initval {BEGIN DYNARE_BLOCK; return token::INITVAL;}
<INITIAL>endval {BEGIN DYNARE_BLOCK; return token::ENDVAL;} <INITIAL>endval {BEGIN DYNARE_BLOCK; return token::ENDVAL;}
<INITIAL>histval {BEGIN DYNARE_BLOCK; return token::HISTVAL;} <INITIAL>histval {BEGIN DYNARE_BLOCK; return token::HISTVAL;}
<INITIAL>filter_initial_state {BEGIN DYNARE_BLOCK; return token::FILTER_INITIAL_STATE;}
<INITIAL>shocks {BEGIN DYNARE_BLOCK; return token::SHOCKS;} <INITIAL>shocks {BEGIN DYNARE_BLOCK; return token::SHOCKS;}
<INITIAL>heteroskedastic_shocks {BEGIN DYNARE_BLOCK; return token::HETEROSKEDASTIC_SHOCKS;}
<INITIAL>shock_groups {BEGIN DYNARE_BLOCK; return token::SHOCK_GROUPS;} <INITIAL>shock_groups {BEGIN DYNARE_BLOCK; return token::SHOCK_GROUPS;}
<INITIAL>init2shocks {BEGIN DYNARE_BLOCK; return token::INIT2SHOCKS;}
<INITIAL>mshocks {BEGIN DYNARE_BLOCK; return token::MSHOCKS;} <INITIAL>mshocks {BEGIN DYNARE_BLOCK; return token::MSHOCKS;}
<INITIAL>estimated_params {BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS;} <INITIAL>estimated_params {BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS;}
<INITIAL>epilogue {BEGIN DYNARE_BLOCK; return token::EPILOGUE;}
/* priors is an alias for estimated_params */ /* priors is an alias for estimated_params */
<INITIAL>priors {BEGIN DYNARE_BLOCK;return token::ESTIMATED_PARAMS;} <INITIAL>priors {BEGIN DYNARE_BLOCK;return token::ESTIMATED_PARAMS;}
<INITIAL>estimated_params_init {BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS_INIT;} <INITIAL>estimated_params_init {BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS_INIT;}
<INITIAL>estimated_params_bounds {BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS_BOUNDS;} <INITIAL>estimated_params_bounds {BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS_BOUNDS;}
<INITIAL>estimated_params_remove {BEGIN DYNARE_BLOCK; return token::ESTIMATED_PARAMS_REMOVE;}
<INITIAL>osr_params_bounds {BEGIN DYNARE_BLOCK; return token::OSR_PARAMS_BOUNDS;} <INITIAL>osr_params_bounds {BEGIN DYNARE_BLOCK; return token::OSR_PARAMS_BOUNDS;}
<INITIAL>observation_trends {BEGIN DYNARE_BLOCK; return token::OBSERVATION_TRENDS;} <INITIAL>observation_trends {BEGIN DYNARE_BLOCK; return token::OBSERVATION_TRENDS;}
<INITIAL>deterministic_trends {BEGIN DYNARE_BLOCK; return token::DETERMINISTIC_TRENDS;}
<INITIAL>optim_weights {BEGIN DYNARE_BLOCK; return token::OPTIM_WEIGHTS;} <INITIAL>optim_weights {BEGIN DYNARE_BLOCK; return token::OPTIM_WEIGHTS;}
<INITIAL>homotopy_setup {BEGIN DYNARE_BLOCK; return token::HOMOTOPY_SETUP;} <INITIAL>homotopy_setup {BEGIN DYNARE_BLOCK; return token::HOMOTOPY_SETUP;}
<INITIAL>conditional_forecast_paths {BEGIN DYNARE_BLOCK; return token::CONDITIONAL_FORECAST_PATHS;} <INITIAL>conditional_forecast_paths {BEGIN DYNARE_BLOCK; return token::CONDITIONAL_FORECAST_PATHS;}
...@@ -211,6 +230,13 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -211,6 +230,13 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<INITIAL>irf_calibration {BEGIN DYNARE_BLOCK; return token::IRF_CALIBRATION;} <INITIAL>irf_calibration {BEGIN DYNARE_BLOCK; return token::IRF_CALIBRATION;}
<INITIAL>ramsey_constraints {BEGIN DYNARE_BLOCK; return token::RAMSEY_CONSTRAINTS;} <INITIAL>ramsey_constraints {BEGIN DYNARE_BLOCK; return token::RAMSEY_CONSTRAINTS;}
<INITIAL>generate_irfs {BEGIN DYNARE_BLOCK; return token::GENERATE_IRFS;} <INITIAL>generate_irfs {BEGIN DYNARE_BLOCK; return token::GENERATE_IRFS;}
<INITIAL>matched_moments {BEGIN DYNARE_BLOCK; return token::MATCHED_MOMENTS;}
<INITIAL>occbin_constraints {BEGIN DYNARE_BLOCK; return token::OCCBIN_CONSTRAINTS;}
<INITIAL>model_replace {BEGIN DYNARE_BLOCK; return token::MODEL_REPLACE;}
<INITIAL>pac_target_info {BEGIN DYNARE_BLOCK; return token::PAC_TARGET_INFO;}
<INITIAL>matched_irfs {BEGIN DYNARE_BLOCK; return token::MATCHED_IRFS;}
<INITIAL>matched_irfs_weights {BEGIN DYNARE_BLOCK; return token::MATCHED_IRFS_WEIGHTS;}
<INITIAL>perfect_foresight_controlled_paths {BEGIN DYNARE_BLOCK; return token::PERFECT_FORESIGHT_CONTROLLED_PATHS;}
/* For the semicolon after an "end" keyword */ /* For the semicolon after an "end" keyword */
<INITIAL>; {return Dynare::parser::token_type (yytext[0]);} <INITIAL>; {return Dynare::parser::token_type (yytext[0]);}
...@@ -221,7 +247,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -221,7 +247,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>subsamples {return token::SUBSAMPLES;} <DYNARE_STATEMENT>subsamples {return token::SUBSAMPLES;}
<DYNARE_STATEMENT>options {return token::OPTIONS;} <DYNARE_STATEMENT>options {return token::OPTIONS;}
<DYNARE_STATEMENT>prior { <DYNARE_STATEMENT>prior {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::PRIOR; return token::PRIOR;
} }
<INITIAL>std {BEGIN DYNARE_STATEMENT; return token::STD;} <INITIAL>std {BEGIN DYNARE_STATEMENT; return token::STD;}
...@@ -231,31 +257,12 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -231,31 +257,12 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<INITIAL>prior_function {BEGIN DYNARE_STATEMENT; return token::PRIOR_FUNCTION;} <INITIAL>prior_function {BEGIN DYNARE_STATEMENT; return token::PRIOR_FUNCTION;}
<INITIAL>posterior_function {BEGIN DYNARE_STATEMENT; return token::POSTERIOR_FUNCTION;} <INITIAL>posterior_function {BEGIN DYNARE_STATEMENT; return token::POSTERIOR_FUNCTION;}
/* Inside of a Dynare statement */ <DYNARE_STATEMENT,DYNARE_BLOCK>{DATE} {
<DYNARE_STATEMENT>{DATE} { yylval->emplace<string>(yytext);
char *yycopy = strdup(yytext); return token::DATE;
char *uput = yycopy + yyleng;
unput(')');
unput('\'');
while (uput > yycopy)
unput(*--uput);
unput('\'');
unput('(');
unput('s');
unput('e');
unput('t');
unput('a');
unput('d');
free( yycopy );
} }
<DYNARE_STATEMENT>${DATE} { yylloc->step();
#if (YY_FLEX_MAJOR_VERSION > 2) || (YY_FLEX_MAJOR_VERSION == 2 && YY_FLEX_MINOR_VERSION >= 6) /* Inside a Dynare statement */
yyout << yytext + 1;
#else
*yyout << yytext + 1;
#endif
}
<DYNARE_STATEMENT>dates {dates_parens_nb=0; BEGIN DATES_STATEMENT; yylval->string_val = new string("dates");}
<DYNARE_STATEMENT>file {return token::FILE;} <DYNARE_STATEMENT>file {return token::FILE;}
<DYNARE_STATEMENT>datafile {return token::DATAFILE;} <DYNARE_STATEMENT>datafile {return token::DATAFILE;}
<DYNARE_STATEMENT>dirname {return token::DIRNAME;} <DYNARE_STATEMENT>dirname {return token::DIRNAME;}
...@@ -265,7 +272,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -265,7 +272,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>mean {return token::MEAN;} <DYNARE_STATEMENT>mean {return token::MEAN;}
<DYNARE_STATEMENT>stdev {return token::STDEV;} <DYNARE_STATEMENT>stdev {return token::STDEV;}
<DYNARE_STATEMENT>truncate {return token::TRUNCATE;} <DYNARE_STATEMENT>truncate {return token::TRUNCATE;}
<DYNARE_STATEMENT>domain {return token::DOMAINN;} <DYNARE_STATEMENT>domain {return token::DOMAINN;} // Use altered token name to avoid identifier collision on Windows and macOS
<DYNARE_STATEMENT>variance {return token::VARIANCE;} <DYNARE_STATEMENT>variance {return token::VARIANCE;}
<DYNARE_STATEMENT>mode {return token::MODE;} <DYNARE_STATEMENT>mode {return token::MODE;}
<DYNARE_STATEMENT>interval {return token::INTERVAL;} <DYNARE_STATEMENT>interval {return token::INTERVAL;}
...@@ -276,22 +283,22 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -276,22 +283,22 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>jscale {return token::JSCALE;} <DYNARE_STATEMENT>jscale {return token::JSCALE;}
<DYNARE_STATEMENT>prefilter {return token::PREFILTER;} <DYNARE_STATEMENT>prefilter {return token::PREFILTER;}
<DYNARE_STATEMENT>presample {return token::PRESAMPLE;} <DYNARE_STATEMENT>presample {return token::PRESAMPLE;}
<DYNARE_STATEMENT>lik_algo {return token::LIK_ALGO;}
<DYNARE_STATEMENT>lik_init {return token::LIK_INIT;} <DYNARE_STATEMENT>lik_init {return token::LIK_INIT;}
<DYNARE_STATEMENT>taper_steps {return token::TAPER_STEPS;} <DYNARE_STATEMENT>taper_steps {return token::TAPER_STEPS;}
<DYNARE_STATEMENT>geweke_interval {return token::GEWEKE_INTERVAL;} <DYNARE_STATEMENT>geweke_interval {return token::GEWEKE_INTERVAL;}
<DYNARE_STATEMENT>raftery_lewis_qrs {return token::RAFTERY_LEWIS_QRS;} <DYNARE_STATEMENT>raftery_lewis_qrs {return token::RAFTERY_LEWIS_QRS;}
<DYNARE_STATEMENT>raftery_lewis_diagnostics {return token::RAFTERY_LEWIS_DIAGNOSTICS;} <DYNARE_STATEMENT>raftery_lewis_diagnostics {return token::RAFTERY_LEWIS_DIAGNOSTICS;}
<DYNARE_STATEMENT>brooks_gelman_plotrows {return token::BROOKS_GELMAN_PLOTROWS;}
<DYNARE_STATEMENT>graph {return token::GRAPH;} <DYNARE_STATEMENT>graph {return token::GRAPH;}
<DYNARE_STATEMENT>nograph {return token::NOGRAPH;} <DYNARE_STATEMENT>nograph {return token::NOGRAPH;}
<DYNARE_STATEMENT>posterior_graph {return token::POSTERIOR_GRAPH;} <DYNARE_STATEMENT>posterior_graph {return token::POSTERIOR_GRAPH;}
<DYNARE_STATEMENT>posterior_nograph {return token::POSTERIOR_NOGRAPH;} <DYNARE_STATEMENT>posterior_nograph {return token::POSTERIOR_NOGRAPH;}
<DYNARE_STATEMENT>nodisplay {return token::NODISPLAY;} <DYNARE_STATEMENT>nodisplay {return token::NODISPLAY;}
<DYNARE_STATEMENT>graph_format {return token::GRAPH_FORMAT;} <DYNARE_STATEMENT>graph_format {return token::GRAPH_FORMAT;}
<DYNARE_STATEMENT>eps {yylval->string_val = new string(yytext); return token::EPS;} <DYNARE_STATEMENT>eps {yylval->emplace<string>(yytext); return token::EPS;}
<DYNARE_STATEMENT>pdf {yylval->string_val = new string(yytext); return token::PDF;} <DYNARE_STATEMENT>pdf {yylval->emplace<string>(yytext); return token::PDF;}
<DYNARE_STATEMENT>fig {yylval->string_val = new string(yytext); return token::FIG;} <DYNARE_STATEMENT>fig {yylval->emplace<string>(yytext); return token::FIG;}
<DYNARE_STATEMENT>none {yylval->string_val = new string(yytext); return token::NONE;} <DYNARE_STATEMENT>none {yylval->emplace<string>(yytext); return token::NONE;}
<DYNARE_STATEMENT>print {return token::PRINT;} <DYNARE_STATEMENT>print {return token::PRINT;}
<DYNARE_STATEMENT>noprint {return token::NOPRINT;} <DYNARE_STATEMENT>noprint {return token::NOPRINT;}
<DYNARE_STATEMENT>conf_sig {return token::CONF_SIG;} <DYNARE_STATEMENT>conf_sig {return token::CONF_SIG;}
...@@ -300,6 +307,9 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -300,6 +307,9 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>mh_drop {return token::MH_DROP;} <DYNARE_STATEMENT>mh_drop {return token::MH_DROP;}
<DYNARE_STATEMENT>mh_jscale {return token::MH_JSCALE;} <DYNARE_STATEMENT>mh_jscale {return token::MH_JSCALE;}
<DYNARE_STATEMENT>mh_init_scale {return token::MH_INIT_SCALE;} <DYNARE_STATEMENT>mh_init_scale {return token::MH_INIT_SCALE;}
<DYNARE_STATEMENT>mh_init_scale_factor {return token::MH_INIT_SCALE_FACTOR;}
<DYNARE_STATEMENT>mh_tune_jscale {return token::MH_TUNE_JSCALE;}
<DYNARE_STATEMENT>mh_tune_guess {return token::MH_TUNE_GUESS;}
<DYNARE_STATEMENT>mode_file {return token::MODE_FILE;} <DYNARE_STATEMENT>mode_file {return token::MODE_FILE;}
<DYNARE_STATEMENT>mode_compute {return token::MODE_COMPUTE;} <DYNARE_STATEMENT>mode_compute {return token::MODE_COMPUTE;}
<DYNARE_STATEMENT>mode_check {return token::MODE_CHECK;} <DYNARE_STATEMENT>mode_check {return token::MODE_CHECK;}
...@@ -307,7 +317,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -307,7 +317,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>mode_check_symmetric_plots {return token::MODE_CHECK_SYMMETRIC_PLOTS;} <DYNARE_STATEMENT>mode_check_symmetric_plots {return token::MODE_CHECK_SYMMETRIC_PLOTS;}
<DYNARE_STATEMENT>mode_check_number_of_points {return token::MODE_CHECK_NUMBER_OF_POINTS;} <DYNARE_STATEMENT>mode_check_number_of_points {return token::MODE_CHECK_NUMBER_OF_POINTS;}
<DYNARE_STATEMENT>prior_trunc {return token::PRIOR_TRUNC;} <DYNARE_STATEMENT>prior_trunc {return token::PRIOR_TRUNC;}
<DYNARE_STATEMENT>mh_mode {return token::MH_MODE;} <DYNARE_STATEMENT>mh_posterior_mode_estimation {return token::MH_POSTERIOR_MODE_ESTIMATION;}
<DYNARE_STATEMENT>mh_nblocks {return token::MH_NBLOCKS;} <DYNARE_STATEMENT>mh_nblocks {return token::MH_NBLOCKS;}
<DYNARE_STATEMENT>load_mh_file {return token::LOAD_MH_FILE;} <DYNARE_STATEMENT>load_mh_file {return token::LOAD_MH_FILE;}
<DYNARE_STATEMENT>load_results_after_load_mh {return token::LOAD_RESULTS_AFTER_LOAD_MH;} <DYNARE_STATEMENT>load_results_after_load_mh {return token::LOAD_RESULTS_AFTER_LOAD_MH;}
...@@ -318,6 +328,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -318,6 +328,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>kalman_algo {return token::KALMAN_ALGO;} <DYNARE_STATEMENT>kalman_algo {return token::KALMAN_ALGO;}
<DYNARE_STATEMENT>fast_kalman_filter {return token::FAST_KALMAN_FILTER;} <DYNARE_STATEMENT>fast_kalman_filter {return token::FAST_KALMAN_FILTER;}
<DYNARE_STATEMENT>kalman_tol {return token::KALMAN_TOL;} <DYNARE_STATEMENT>kalman_tol {return token::KALMAN_TOL;}
<DYNARE_STATEMENT>schur_vec_tol {return token::SCHUR_VEC_TOL;}
<DYNARE_STATEMENT>diffuse_kalman_tol {return token::DIFFUSE_KALMAN_TOL;} <DYNARE_STATEMENT>diffuse_kalman_tol {return token::DIFFUSE_KALMAN_TOL;}
<DYNARE_STATEMENT>forecast {return token::FORECAST;} <DYNARE_STATEMENT>forecast {return token::FORECAST;}
<DYNARE_STATEMENT>smoother {return token::SMOOTHER;} <DYNARE_STATEMENT>smoother {return token::SMOOTHER;}
...@@ -332,11 +343,16 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -332,11 +343,16 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT,DYNARE_BLOCK>relative_irf {return token::RELATIVE_IRF;} <DYNARE_STATEMENT,DYNARE_BLOCK>relative_irf {return token::RELATIVE_IRF;}
<DYNARE_STATEMENT>tex {return token::TEX;} <DYNARE_STATEMENT>tex {return token::TEX;}
<DYNARE_STATEMENT>nomoments {return token::NOMOMENTS;} <DYNARE_STATEMENT>nomoments {return token::NOMOMENTS;}
<DYNARE_STATEMENT>nomodelsummary {return token::NOMODELSUMMARY;}
<DYNARE_STATEMENT>std {return token::STD;} <DYNARE_STATEMENT>std {return token::STD;}
<DYNARE_STATEMENT>corr {return token::CORR;} <DYNARE_STATEMENT>corr {return token::CORR;}
<DYNARE_STATEMENT>nocorr {return token::NOCORR;} <DYNARE_STATEMENT>nocorr {return token::NOCORR;}
<DYNARE_STATEMENT>optim {return token::OPTIM;} <DYNARE_STATEMENT>optim {return token::OPTIM;}
<DYNARE_STATEMENT>periods {return token::PERIODS;} <DYNARE_STATEMENT>periods {return token::PERIODS;}
<DYNARE_BLOCK>from_initval_to_endval {return token::FROM_INITVAL_TO_ENDVAL;}
<DYNARE_STATEMENT>endval_steady {return token::ENDVAL_STEADY;}
<DYNARE_STATEMENT,DYNARE_BLOCK>model_name {return token::MODEL_NAME;}
<DYNARE_STATEMENT>auxiliary_model_name {return token::AUXILIARY_MODEL_NAME;}
<DYNARE_STATEMENT>endogenous_terminal_period {return token::ENDOGENOUS_TERMINAL_PERIOD;} <DYNARE_STATEMENT>endogenous_terminal_period {return token::ENDOGENOUS_TERMINAL_PERIOD;}
<DYNARE_STATEMENT>sub_draws {return token::SUB_DRAWS;} <DYNARE_STATEMENT>sub_draws {return token::SUB_DRAWS;}
<DYNARE_STATEMENT>minimal_solving_periods {return token::MINIMAL_SOLVING_PERIODS;} <DYNARE_STATEMENT>minimal_solving_periods {return token::MINIMAL_SOLVING_PERIODS;}
...@@ -346,8 +362,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -346,8 +362,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>modifiedharmonicmean {return token::MODIFIEDHARMONICMEAN;} <DYNARE_STATEMENT>modifiedharmonicmean {return token::MODIFIEDHARMONICMEAN;}
<DYNARE_STATEMENT>constant {return token::CONSTANT;} <DYNARE_STATEMENT>constant {return token::CONSTANT;}
<DYNARE_STATEMENT>noconstant {return token::NOCONSTANT;} <DYNARE_STATEMENT>noconstant {return token::NOCONSTANT;}
<DYNARE_STATEMENT>covar {return token::COVAR;}
<DYNARE_STATEMENT>filename {return token::FILENAME;} <DYNARE_STATEMENT>filename {return token::FILENAME;}
<DYNARE_STATEMENT>conditional_likelihood {return token::CONDITIONAL_LIKELIHOOD;}
<DYNARE_STATEMENT>diffuse_filter {return token::DIFFUSE_FILTER;} <DYNARE_STATEMENT>diffuse_filter {return token::DIFFUSE_FILTER;}
<DYNARE_STATEMENT>plot_priors {return token::PLOT_PRIORS;} <DYNARE_STATEMENT>plot_priors {return token::PLOT_PRIORS;}
<DYNARE_STATEMENT>aim_solver {return token::AIM_SOLVER;} <DYNARE_STATEMENT>aim_solver {return token::AIM_SOLVER;}
...@@ -371,6 +387,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -371,6 +387,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>restriction_fname {return token::RESTRICTION_FNAME;} <DYNARE_STATEMENT>restriction_fname {return token::RESTRICTION_FNAME;}
<DYNARE_STATEMENT>nlags {return token::NLAGS;} <DYNARE_STATEMENT>nlags {return token::NLAGS;}
<DYNARE_STATEMENT>restrictions {return token::RESTRICTIONS;} <DYNARE_STATEMENT>restrictions {return token::RESTRICTIONS;}
<DYNARE_BLOCK>adl {return token::ADL;}
<DYNARE_STATEMENT,DYNARE_BLOCK>diff {return token::DIFF;}
<DYNARE_STATEMENT>cross_restrictions {return token::CROSS_RESTRICTIONS;} <DYNARE_STATEMENT>cross_restrictions {return token::CROSS_RESTRICTIONS;}
<DYNARE_STATEMENT>contemp_reduced_form {return token::CONTEMP_REDUCED_FORM;} <DYNARE_STATEMENT>contemp_reduced_form {return token::CONTEMP_REDUCED_FORM;}
<DYNARE_STATEMENT>real_pseudo_forecast {return token::REAL_PSEUDO_FORECAST;} <DYNARE_STATEMENT>real_pseudo_forecast {return token::REAL_PSEUDO_FORECAST;}
...@@ -388,7 +406,9 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -388,7 +406,9 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>logarithmic_reduction {return token::LOGARITHMIC_REDUCTION;} <DYNARE_STATEMENT>logarithmic_reduction {return token::LOGARITHMIC_REDUCTION;}
<DYNARE_STATEMENT>use_univariate_filters_if_singularity_is_detected {return token::USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED;} <DYNARE_STATEMENT>use_univariate_filters_if_singularity_is_detected {return token::USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED;}
<DYNARE_STATEMENT>hybrid {return token::HYBRID;} <DYNARE_STATEMENT>hybrid {return token::HYBRID;}
<DYNARE_STATEMENT>use_first_order_solution {return token::USE_FIRST_ORDER_SOLUTION;}
<DYNARE_STATEMENT>default {return token::DEFAULT;} <DYNARE_STATEMENT>default {return token::DEFAULT;}
<DYNARE_STATEMENT>init2shocks {return token::INIT2SHOCKS;}
<DYNARE_STATEMENT>number_of_particles {return token::NUMBER_OF_PARTICLES;} <DYNARE_STATEMENT>number_of_particles {return token::NUMBER_OF_PARTICLES;}
<DYNARE_STATEMENT>resampling {return token::RESAMPLING;} <DYNARE_STATEMENT>resampling {return token::RESAMPLING;}
...@@ -399,6 +419,11 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -399,6 +419,11 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>kitagawa {return token::KITAGAWA;} <DYNARE_STATEMENT>kitagawa {return token::KITAGAWA;}
<DYNARE_STATEMENT>smooth {return token::SMOOTH;} <DYNARE_STATEMENT>smooth {return token::SMOOTH;}
<DYNARE_STATEMENT>stratified {return token::STRATIFIED;} <DYNARE_STATEMENT>stratified {return token::STRATIFIED;}
<DYNARE_STATEMENT>residual {
yylval->emplace<string>(yytext);
return token::RESIDUAL;
}
<DYNARE_STATEMENT>multinomial {return token::MULTINOMIAL;}
<DYNARE_STATEMENT>cpf_weights {return token::CPF_WEIGHTS;} <DYNARE_STATEMENT>cpf_weights {return token::CPF_WEIGHTS;}
<DYNARE_STATEMENT>amisanotristani {return token::AMISANOTRISTANI;} <DYNARE_STATEMENT>amisanotristani {return token::AMISANOTRISTANI;}
<DYNARE_STATEMENT>murrayjonesparslow {return token::MURRAYJONESPARSLOW;} <DYNARE_STATEMENT>murrayjonesparslow {return token::MURRAYJONESPARSLOW;}
...@@ -413,45 +438,47 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -413,45 +438,47 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>no_posterior_kernel_density {return token::NO_POSTERIOR_KERNEL_DENSITY;} <DYNARE_STATEMENT>no_posterior_kernel_density {return token::NO_POSTERIOR_KERNEL_DENSITY;}
<DYNARE_STATEMENT>rescale_prediction_error_covariance {return token::RESCALE_PREDICTION_ERROR_COVARIANCE;} <DYNARE_STATEMENT>rescale_prediction_error_covariance {return token::RESCALE_PREDICTION_ERROR_COVARIANCE;}
<DYNARE_STATEMENT>use_penalized_objective_for_hessian {return token::USE_PENALIZED_OBJECTIVE_FOR_HESSIAN;} <DYNARE_STATEMENT>use_penalized_objective_for_hessian {return token::USE_PENALIZED_OBJECTIVE_FOR_HESSIAN;}
<DYNARE_STATEMENT>expression {return token::EXPRESSION;}
<DYNARE_STATEMENT>first_simulation_period {return token::FIRST_SIMULATION_PERIOD;}
<DYNARE_STATEMENT>last_simulation_period {return token::LAST_SIMULATION_PERIOD;}
<DYNARE_STATEMENT>no_init_estimation_check_first_obs {return token::NO_INIT_ESTIMATION_CHECK_FIRST_OBS;}
<DYNARE_STATEMENT>fsolve_options {return token::FSOLVE_OPTIONS;}
<DYNARE_STATEMENT>alpha { <DYNARE_STATEMENT>alpha {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::ALPHA; return token::ALPHA;
} }
<DYNARE_STATEMENT>beta { <DYNARE_STATEMENT>beta {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::BETA; return token::BETA;
} }
<DYNARE_STATEMENT>gamma { <DYNARE_STATEMENT>gamma {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::GAMMA; return token::GAMMA;
} }
<DYNARE_STATEMENT>inv_gamma { <DYNARE_STATEMENT>inv_gamma {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::INV_GAMMA; return token::INV_GAMMA;
} }
<DYNARE_STATEMENT>inv_gamma1 { <DYNARE_STATEMENT>inv_gamma1 {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::INV_GAMMA1; return token::INV_GAMMA1;
} }
<DYNARE_STATEMENT>inv_gamma2 { <DYNARE_STATEMENT>inv_gamma2 {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::INV_GAMMA2; return token::INV_GAMMA2;
} }
<DYNARE_STATEMENT>dirichlet { <DYNARE_STATEMENT>dirichlet {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::DIRICHLET; return token::DIRICHLET;
} }
<DYNARE_STATEMENT>weibull { <DYNARE_STATEMENT>weibull {return token::WEIBULL;}
yylval->string_val = new string(yytext);
return token::WEIBULL;
}
<DYNARE_STATEMENT>normal { <DYNARE_STATEMENT>normal {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::NORMAL; return token::NORMAL;
} }
<DYNARE_STATEMENT>uniform { <DYNARE_STATEMENT>uniform {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::UNIFORM; return token::UNIFORM;
} }
<DYNARE_STATEMENT>gsig2_lmdm {return token::GSIG2_LMDM;} <DYNARE_STATEMENT>gsig2_lmdm {return token::GSIG2_LMDM;}
...@@ -462,20 +489,21 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -462,20 +489,21 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>ncsk {return token::NCSK;} <DYNARE_STATEMENT>ncsk {return token::NCSK;}
<DYNARE_STATEMENT>nstd {return token::NSTD;} <DYNARE_STATEMENT>nstd {return token::NSTD;}
<DYNARE_STATEMENT>ninv { <DYNARE_STATEMENT>ninv {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::NINV; return token::NINV;
} }
<DYNARE_STATEMENT>indxparr {return token::INDXPARR;} <DYNARE_STATEMENT>indxparr {return token::INDXPARR;}
<DYNARE_STATEMENT>indxovr {return token::INDXOVR;} <DYNARE_STATEMENT>indxovr {return token::INDXOVR;}
<DYNARE_STATEMENT>aband { <DYNARE_STATEMENT>aband {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::ABAND; return token::ABAND;
} }
<DYNARE_STATEMENT>write_equation_tags {return token::WRITE_EQUATION_TAGS;} <DYNARE_STATEMENT>write_equation_tags {return token::WRITE_EQUATION_TAGS;}
<DYNARE_STATEMENT>eqtags {return token::EQTAGS;}
<DYNARE_STATEMENT>targets {return token::TARGETS;}
<DYNARE_STATEMENT>indxap {return token::INDXAP;} <DYNARE_STATEMENT>indxap {return token::INDXAP;}
<DYNARE_STATEMENT>apband {return token::APBAND;} <DYNARE_STATEMENT>apband {return token::APBAND;}
<DYNARE_STATEMENT>indximf {return token::INDXIMF;} <DYNARE_STATEMENT>indximf {return token::INDXIMF;}
<DYNARE_STATEMENT>imfband {return token::IMFBAND;}
<DYNARE_STATEMENT>indxfore {return token::INDXFORE;} <DYNARE_STATEMENT>indxfore {return token::INDXFORE;}
<DYNARE_STATEMENT>foreband {return token::FOREBAND;} <DYNARE_STATEMENT>foreband {return token::FOREBAND;}
<DYNARE_STATEMENT>indxgforehat {return token::INDXGFOREHAT;} <DYNARE_STATEMENT>indxgforehat {return token::INDXGFOREHAT;}
...@@ -484,22 +512,21 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -484,22 +512,21 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>indxgdls {return token::INDXGDLS;} <DYNARE_STATEMENT>indxgdls {return token::INDXGDLS;}
<DYNARE_STATEMENT>eq_ms {return token::EQ_MS;} <DYNARE_STATEMENT>eq_ms {return token::EQ_MS;}
<DYNARE_STATEMENT>cms { <DYNARE_STATEMENT>cms {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::CMS; return token::CMS;
} }
<DYNARE_STATEMENT>ncms { <DYNARE_STATEMENT>ncms {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::NCMS; return token::NCMS;
} }
<DYNARE_STATEMENT>eq_cms {return token::EQ_CMS;} <DYNARE_STATEMENT>eq_cms {return token::EQ_CMS;}
<DYNARE_STATEMENT>tlindx {return token::TLINDX;} <DYNARE_STATEMENT>tlindx {return token::TLINDX;}
<DYNARE_STATEMENT>tlnumber {return token::TLNUMBER;} <DYNARE_STATEMENT>tlnumber {return token::TLNUMBER;}
<DYNARE_STATEMENT>cnum { <DYNARE_STATEMENT>cnum {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::CNUM; return token::CNUM;
} }
<DYNARE_STATEMENT>nodecomposition {return token::NODECOMPOSITION;}; <DYNARE_STATEMENT>nodecomposition {return token::NODECOMPOSITION;};
<DYNARE_STATEMENT>banact {return token::BANACT;}
<DYNARE_BLOCK>use_calibration {return token::USE_CALIBRATION;} <DYNARE_BLOCK>use_calibration {return token::USE_CALIBRATION;}
<DYNARE_STATEMENT>output_file_tag {return token::OUTPUT_FILE_TAG;} <DYNARE_STATEMENT>output_file_tag {return token::OUTPUT_FILE_TAG;}
<DYNARE_STATEMENT>file_tag {return token::FILE_TAG;}; <DYNARE_STATEMENT>file_tag {return token::FILE_TAG;};
...@@ -534,6 +561,33 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -534,6 +561,33 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>max_block_iterations {return token::MAX_BLOCK_ITERATIONS;} <DYNARE_STATEMENT>max_block_iterations {return token::MAX_BLOCK_ITERATIONS;}
<DYNARE_STATEMENT>max_repeated_optimization_runs {return token::MAX_REPEATED_OPTIMIZATION_RUNS;} <DYNARE_STATEMENT>max_repeated_optimization_runs {return token::MAX_REPEATED_OPTIMIZATION_RUNS;}
<DYNARE_STATEMENT>maxit {return token::MAXIT;} <DYNARE_STATEMENT>maxit {return token::MAXIT;}
<DYNARE_STATEMENT>simul_maxit {return token::SIMUL_MAXIT;}
<DYNARE_STATEMENT>likelihood_maxit {return token::LIKELIHOOD_MAXIT;}
<DYNARE_STATEMENT>smoother_maxit {return token::SMOOTHER_MAXIT;}
<DYNARE_STATEMENT>simul_periods {return token::SIMUL_PERIODS;}
<DYNARE_STATEMENT>likelihood_periods {return token::LIKELIHOOD_PERIODS;}
<DYNARE_STATEMENT>smoother_periods {return token::SMOOTHER_PERIODS;}
<DYNARE_STATEMENT>simul_curb_retrench {return token::SIMUL_CURB_RETRENCH;}
<DYNARE_STATEMENT>likelihood_curb_retrench {return token::LIKELIHOOD_CURB_RETRENCH;}
<DYNARE_STATEMENT>smoother_curb_retrench {return token::SMOOTHER_CURB_RETRENCH;}
<DYNARE_STATEMENT>simul_check_ahead_periods {return token::SIMUL_CHECK_AHEAD_PERIODS;}
<DYNARE_STATEMENT>simul_max_check_ahead_periods {return token::SIMUL_MAX_CHECK_AHEAD_PERIODS;}
<DYNARE_STATEMENT>simul_reset_check_ahead_periods {return token::SIMUL_RESET_CHECK_AHEAD_PERIODS;}
<DYNARE_STATEMENT>likelihood_check_ahead_periods {return token::LIKELIHOOD_CHECK_AHEAD_PERIODS;}
<DYNARE_STATEMENT>likelihood_max_check_ahead_periods {return token::LIKELIHOOD_MAX_CHECK_AHEAD_PERIODS;}
<DYNARE_STATEMENT>smoother_check_ahead_periods {return token::SMOOTHER_CHECK_AHEAD_PERIODS;}
<DYNARE_STATEMENT>smoother_max_check_ahead_periods {return token::SMOOTHER_MAX_CHECK_AHEAD_PERIODS;}
<DYNARE_STATEMENT>simul_debug {return token::SIMUL_DEBUG;}
<DYNARE_STATEMENT>smoother_debug {return token::SMOOTHER_DEBUG;}
<DYNARE_STATEMENT>simul_periodic_solution {return token::SIMUL_PERIODIC_SOLUTION;}
<DYNARE_STATEMENT>likelihood_periodic_solution {return token::LIKELIHOOD_PERIODIC_SOLUTION;}
<DYNARE_STATEMENT>smoother_periodic_solution {return token::SMOOTHER_PERIODIC_SOLUTION;}
<DYNARE_STATEMENT>likelihood_inversion_filter {return token::LIKELIHOOD_INVERSION_FILTER;}
<DYNARE_STATEMENT>likelihood_piecewise_kalman_filter {return token::LIKELIHOOD_PIECEWISE_KALMAN_FILTER;}
<DYNARE_STATEMENT>likelihood_max_kalman_iterations {return token::LIKELIHOOD_MAX_KALMAN_ITERATIONS;}
<DYNARE_STATEMENT>smoother_inversion_filter {return token::SMOOTHER_INVERSION_FILTER;}
<DYNARE_STATEMENT>smoother_piecewise_kalman_filter {return token::SMOOTHER_PIECEWISE_KALMAN_FILTER;}
<DYNARE_STATEMENT>filter_use_relaxation {return token::FILTER_USE_RELEXATION;}
<DYNARE_STATEMENT>function_convergence_criterion {return token::FUNCTION_CONVERGENCE_CRITERION;} <DYNARE_STATEMENT>function_convergence_criterion {return token::FUNCTION_CONVERGENCE_CRITERION;}
<DYNARE_STATEMENT>parameter_convergence_criterion {return token::PARAMETER_CONVERGENCE_CRITERION;} <DYNARE_STATEMENT>parameter_convergence_criterion {return token::PARAMETER_CONVERGENCE_CRITERION;}
<DYNARE_STATEMENT>number_of_large_perturbations {return token::NUMBER_OF_LARGE_PERTURBATIONS;} <DYNARE_STATEMENT>number_of_large_perturbations {return token::NUMBER_OF_LARGE_PERTURBATIONS;}
...@@ -545,19 +599,15 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -545,19 +599,15 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>tolf {return token::TOLF;} <DYNARE_STATEMENT>tolf {return token::TOLF;}
<DYNARE_STATEMENT>tolx {return token::TOLX;} <DYNARE_STATEMENT>tolx {return token::TOLX;}
<DYNARE_STATEMENT>opt_algo {return token::OPT_ALGO;} <DYNARE_STATEMENT>opt_algo {return token::OPT_ALGO;}
<DYNARE_STATEMENT>add_flags {return token::ADD_FLAGS;}
<DYNARE_STATEMENT>substitute_flags {return token::SUBSTITUTE_FLAGS;}
<DYNARE_STATEMENT>add_libs {return token::ADD_LIBS;}
<DYNARE_STATEMENT>substitute_libs {return token::SUBSTITUTE_LIBS;}
<DYNARE_STATEMENT>compiler {return token::COMPILER;}
<DYNARE_STATEMENT>instruments {return token::INSTRUMENTS;} <DYNARE_STATEMENT>instruments {return token::INSTRUMENTS;}
<DYNARE_STATEMENT>hessian { <DYNARE_STATEMENT>hessian {return token::HESSIAN;}
yylval->string_val = new string(yytext); <DYNARE_STATEMENT>prior_variance {return token::PRIOR_VARIANCE;}
return token::HESSIAN; <DYNARE_STATEMENT>identity_matrix {return token::IDENTITY_MATRIX;}
}
<DYNARE_STATEMENT>prior_variance {
yylval->string_val = new string(yytext);
return token::PRIOR_VARIANCE;
}
<DYNARE_STATEMENT>identity_matrix {
yylval->string_val = new string(yytext);
return token::IDENTITY_MATRIX;
}
<DYNARE_STATEMENT>mcmc_jumping_covariance {return token::MCMC_JUMPING_COVARIANCE;} <DYNARE_STATEMENT>mcmc_jumping_covariance {return token::MCMC_JUMPING_COVARIANCE;}
/* These four (var, varexo, varexo_det, parameters) are for change_type */ /* These four (var, varexo, varexo_det, parameters) are for change_type */
...@@ -579,14 +629,28 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -579,14 +629,28 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>homotopy_mode {return token::HOMOTOPY_MODE; } <DYNARE_STATEMENT>homotopy_mode {return token::HOMOTOPY_MODE; }
<DYNARE_STATEMENT>homotopy_steps {return token::HOMOTOPY_STEPS; } <DYNARE_STATEMENT>homotopy_steps {return token::HOMOTOPY_STEPS; }
<DYNARE_STATEMENT>homotopy_force_continue {return token::HOMOTOPY_FORCE_CONTINUE;} <DYNARE_STATEMENT>homotopy_force_continue {return token::HOMOTOPY_FORCE_CONTINUE;}
<DYNARE_STATEMENT>homotopy_max_completion_share {return token::HOMOTOPY_MAX_COMPLETION_SHARE;}
<DYNARE_STATEMENT>homotopy_min_step_size {return token::HOMOTOPY_MIN_STEP_SIZE;}
<DYNARE_STATEMENT>homotopy_initial_step_size {return token::HOMOTOPY_INITIAL_STEP_SIZE;}
<DYNARE_STATEMENT>homotopy_step_size_increase_success_count {return token::HOMOTOPY_STEP_SIZE_INCREASE_SUCCESS_COUNT;}
<DYNARE_STATEMENT>homotopy_linearization_fallback {return token::HOMOTOPY_LINEARIZATION_FALLBACK;}
<DYNARE_STATEMENT>homotopy_marginal_linearization_fallback {return token::HOMOTOPY_MARGINAL_LINEARIZATION_FALLBACK;}
<DYNARE_STATEMENT>homotopy_exclude_varexo {return token::HOMOTOPY_EXCLUDE_VAREXO;}
<DYNARE_STATEMENT>nocheck {return token::NOCHECK; } <DYNARE_STATEMENT>nocheck {return token::NOCHECK; }
<DYNARE_STATEMENT>steady_solve_algo {return token::STEADY_SOLVE_ALGO;}
<DYNARE_STATEMENT>steady_maxit {return token::STEADY_MAXIT;}
<DYNARE_STATEMENT>steady_tolf {return token::STEADY_TOLF;}
<DYNARE_STATEMENT>steady_tolx {return token::STEADY_TOLX;}
<DYNARE_STATEMENT>steady_markowitz {return token::STEADY_MARKOWITZ;}
<DYNARE_STATEMENT>controlled_varexo {return token::CONTROLLED_VAREXO; } <DYNARE_STATEMENT>controlled_varexo {return token::CONTROLLED_VAREXO; }
<DYNARE_STATEMENT>parameter_set {return token::PARAMETER_SET; } <DYNARE_STATEMENT>parameter_set {return token::PARAMETER_SET; }
<DYNARE_STATEMENT>init_state {return token::INIT_STATE; } <DYNARE_STATEMENT>init_state {return token::INIT_STATE; }
<DYNARE_STATEMENT>fast_realtime {return token::FAST_REALTIME; } <DYNARE_STATEMENT>fast_realtime {return token::FAST_REALTIME; }
<DYNARE_STATEMENT>save_realtime {return token::SAVE_REALTIME;} <DYNARE_STATEMENT>save_realtime {return token::SAVE_REALTIME;}
<DYNARE_STATEMENT>detail_plot {return token::DETAIL_PLOT;} <DYNARE_STATEMENT>detail_plot {return token::DETAIL_PLOT;}
<DYNARE_STATEMENT>flip {return token::FLIP;}
<DYNARE_STATEMENT>interactive {return token::INTERACTIVE;} <DYNARE_STATEMENT>interactive {return token::INTERACTIVE;}
<DYNARE_STATEMENT>screen_shocks {return token::SCREEN_SHOCKS;} <DYNARE_STATEMENT>screen_shocks {return token::SCREEN_SHOCKS;}
<DYNARE_STATEMENT>steadystate {return token::STEADYSTATE;} <DYNARE_STATEMENT>steadystate {return token::STEADYSTATE;}
...@@ -594,6 +658,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -594,6 +658,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>qoq {return token::QOQ; } <DYNARE_STATEMENT>qoq {return token::QOQ; }
<DYNARE_STATEMENT>yoy {return token::YOY; } <DYNARE_STATEMENT>yoy {return token::YOY; }
<DYNARE_STATEMENT>aoa {return token::AOA; } <DYNARE_STATEMENT>aoa {return token::AOA; }
<DYNARE_STATEMENT>unconditional {return token::UNCONDITIONAL; }
<DYNARE_STATEMENT>conditional {return token::CONDITIONAL; }
<DYNARE_STATEMENT>fig_name {return token::FIG_NAME;} <DYNARE_STATEMENT>fig_name {return token::FIG_NAME;}
<DYNARE_STATEMENT>write_xls {return token::WRITE_XLS;} <DYNARE_STATEMENT>write_xls {return token::WRITE_XLS;}
<DYNARE_STATEMENT>realtime {return token::REALTIME;} <DYNARE_STATEMENT>realtime {return token::REALTIME;}
...@@ -606,15 +672,19 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -606,15 +672,19 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>mle_mode {return token::MLE_MODE; } <DYNARE_STATEMENT>mle_mode {return token::MLE_MODE; }
<DYNARE_STATEMENT>k_order_solver {return token::K_ORDER_SOLVER; } <DYNARE_STATEMENT>k_order_solver {return token::K_ORDER_SOLVER; }
<DYNARE_STATEMENT>filter_covariance {return token::FILTER_COVARIANCE; } <DYNARE_STATEMENT>filter_covariance {return token::FILTER_COVARIANCE; }
<DYNARE_STATEMENT>updated_covariance {return token::UPDATED_COVARIANCE; }
<DYNARE_STATEMENT>filter_decomposition {return token::FILTER_DECOMPOSITION; } <DYNARE_STATEMENT>filter_decomposition {return token::FILTER_DECOMPOSITION; }
<DYNARE_STATEMENT>smoothed_state_uncertainty {return token::SMOOTHED_STATE_UNCERTAINTY; } <DYNARE_STATEMENT>smoothed_state_uncertainty {return token::SMOOTHED_STATE_UNCERTAINTY; }
<DYNARE_STATEMENT>smoother_redux {return token::SMOOTHER_REDUX; }
<DYNARE_STATEMENT>selected_variables_only {return token::SELECTED_VARIABLES_ONLY; } <DYNARE_STATEMENT>selected_variables_only {return token::SELECTED_VARIABLES_ONLY; }
<DYNARE_STATEMENT>pruning {return token::PRUNING; } <DYNARE_STATEMENT>pruning {return token::PRUNING; }
<DYNARE_STATEMENT>save_draws {return token::SAVE_DRAWS; } <DYNARE_STATEMENT>save_draws {return token::SAVE_DRAWS; }
<DYNARE_STATEMENT>deflator {return token::DEFLATOR;} <DYNARE_STATEMENT>deflator {return token::DEFLATOR;}
<DYNARE_STATEMENT>log_deflator {return token::LOG_DEFLATOR;} <DYNARE_STATEMENT>log_deflator {return token::LOG_DEFLATOR;}
<DYNARE_STATEMENT>epilogue {return token::EPILOGUE;}
<DYNARE_STATEMENT>growth_factor {return token::GROWTH_FACTOR;} <DYNARE_STATEMENT>growth_factor {return token::GROWTH_FACTOR;}
<DYNARE_STATEMENT>log_growth_factor {return token::LOG_GROWTH_FACTOR;} <DYNARE_STATEMENT>log_growth_factor {return token::LOG_GROWTH_FACTOR;}
<DYNARE_STATEMENT,DYNARE_BLOCK>growth {return token::GROWTH;}
<DYNARE_STATEMENT>cova_compute {return token::COVA_COMPUTE;} <DYNARE_STATEMENT>cova_compute {return token::COVA_COMPUTE;}
<DYNARE_STATEMENT>discretionary_tol {return token::DISCRETIONARY_TOL;} <DYNARE_STATEMENT>discretionary_tol {return token::DISCRETIONARY_TOL;}
<DYNARE_STATEMENT>analytic_derivation {return token::ANALYTIC_DERIVATION;} <DYNARE_STATEMENT>analytic_derivation {return token::ANALYTIC_DERIVATION;}
...@@ -622,6 +692,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -622,6 +692,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>solver_periods {return token::SOLVER_PERIODS;} <DYNARE_STATEMENT>solver_periods {return token::SOLVER_PERIODS;}
<DYNARE_STATEMENT>endogenous_prior {return token::ENDOGENOUS_PRIOR;} <DYNARE_STATEMENT>endogenous_prior {return token::ENDOGENOUS_PRIOR;}
<DYNARE_STATEMENT>consider_all_endogenous {return token::CONSIDER_ALL_ENDOGENOUS;} <DYNARE_STATEMENT>consider_all_endogenous {return token::CONSIDER_ALL_ENDOGENOUS;}
<DYNARE_STATEMENT>consider_all_endogenous_and_auxiliary {return token::CONSIDER_ALL_ENDOGENOUS_AND_AUXILIARY;}
<DYNARE_STATEMENT>consider_only_observed {return token::CONSIDER_ONLY_OBSERVED;} <DYNARE_STATEMENT>consider_only_observed {return token::CONSIDER_ONLY_OBSERVED;}
<DYNARE_STATEMENT>infile {return token::INFILE;} <DYNARE_STATEMENT>infile {return token::INFILE;}
<DYNARE_STATEMENT>invars {return token::INVARS;} <DYNARE_STATEMENT>invars {return token::INVARS;}
...@@ -634,46 +705,93 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -634,46 +705,93 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>posterior_sampler_options {return token::POSTERIOR_SAMPLER_OPTIONS;} <DYNARE_STATEMENT>posterior_sampler_options {return token::POSTERIOR_SAMPLER_OPTIONS;}
<DYNARE_STATEMENT>silent_optimizer {return token::SILENT_OPTIMIZER;} <DYNARE_STATEMENT>silent_optimizer {return token::SILENT_OPTIMIZER;}
<DYNARE_STATEMENT>lmmcp {return token::LMMCP;} <DYNARE_STATEMENT>lmmcp {return token::LMMCP;}
<DYNARE_STATEMENT>occbin {return token::OCCBIN;} <DYNARE_STATEMENT>additional_optimizer_steps {return token::ADDITIONAL_OPTIMIZER_STEPS;}
<DYNARE_STATEMENT>centered_moments {return token::CENTERED_MOMENTS; }
<DYNARE_STATEMENT>autolag {return token::AUTOLAG; }
<DYNARE_STATEMENT>recursive_order_estimation {return token::RECURSIVE_ORDER_ESTIMATION; }
<DYNARE_STATEMENT>bartlett_kernel_lag {return token::BARTLETT_KERNEL_LAG; } <DYNARE_STATEMENT>bartlett_kernel_lag {return token::BARTLETT_KERNEL_LAG; }
<DYNARE_STATEMENT>optimal { <DYNARE_STATEMENT>gmm {return token::GMM;}
yylval->string_val = new string(yytext); <DYNARE_STATEMENT>smm {return token::SMM;}
return token::OPTIMAL; <DYNARE_STATEMENT>irf_matching {return token::IRF_MATCHING;}
} <DYNARE_STATEMENT>stoch_simul {return token::STOCH_SIMUL;}
<DYNARE_STATEMENT>diagonal {
yylval->string_val = new string(yytext);
return token::DIAGONAL;
}
<DYNARE_STATEMENT>weighting_matrix {return token::WEIGHTING_MATRIX; } <DYNARE_STATEMENT>weighting_matrix {return token::WEIGHTING_MATRIX; }
<DYNARE_STATEMENT>weighting_matrix_scaling_factor {return token::WEIGHTING_MATRIX_SCALING_FACTOR; }
<DYNARE_STATEMENT>analytic_standard_errors {return token::ANALYTIC_STANDARD_ERRORS; }
<DYNARE_STATEMENT>analytic_jacobian {return token::ANALYTIC_JACOBIAN; }
<DYNARE_STATEMENT>mom_method {return token::MOM_METHOD; }
<DYNARE_STATEMENT>simulation_method {return token::SIMULATION_METHOD; }
<DYNARE_STATEMENT>penalized_estimator {return token::PENALIZED_ESTIMATOR; } <DYNARE_STATEMENT>penalized_estimator {return token::PENALIZED_ESTIMATOR; }
<DYNARE_STATEMENT>verbose {return token::VERBOSE; } <DYNARE_STATEMENT>verbose {return token::VERBOSE; }
<DYNARE_STATEMENT>simulation_multiple {return token::SIMULATION_MULTIPLE; } <DYNARE_STATEMENT>simulation_multiple {return token::SIMULATION_MULTIPLE; }
<DYNARE_STATEMENT>burnin {return token::BURNIN; }
<DYNARE_STATEMENT>seed {return token::SEED; } <DYNARE_STATEMENT>seed {return token::SEED; }
<DYNARE_STATEMENT>se_tolx {return token::SE_TOLX;}
<DYNARE_STATEMENT>bounded_shock_support {return token::BOUNDED_SHOCK_SUPPORT; } <DYNARE_STATEMENT>bounded_shock_support {return token::BOUNDED_SHOCK_SUPPORT; }
<DYNARE_STATEMENT>irf_matching_file {return token::IRF_MATCHING_FILE;}
<DYNARE_STATEMENT>add_tiny_number_to_cholesky {return token::ADD_TINY_NUMBER_TO_CHOLESKY; }
<DYNARE_STATEMENT>analytical_girf {return token::ANALYTICAL_GIRF; } <DYNARE_STATEMENT>analytical_girf {return token::ANALYTICAL_GIRF; }
<DYNARE_STATEMENT>irf_in_percent {return token::IRF_IN_PERCENT; } <DYNARE_STATEMENT>irf_in_percent {return token::IRF_IN_PERCENT; }
<DYNARE_STATEMENT>emas_girf {return token::EMAS_GIRF; } <DYNARE_STATEMENT>emas_girf {return token::EMAS_GIRF; }
<DYNARE_STATEMENT>emas_drop {return token::EMAS_DROP; } <DYNARE_STATEMENT>emas_drop {return token::EMAS_DROP; }
<DYNARE_STATEMENT>emas_tolf {return token::EMAS_TOLF; } <DYNARE_STATEMENT>emas_tolf {return token::EMAS_TOLF; }
<DYNARE_STATEMENT>emas_max_iter {return token::EMAS_MAX_ITER; } <DYNARE_STATEMENT>emas_max_iter {return token::EMAS_MAX_ITER; }
<DYNARE_STATEMENT>variable {return token::VARIABLE;}
<DYNARE_STATEMENT>[\$][^$]*[\$] { <DYNARE_STATEMENT>no_identification_strength {return token::NO_IDENTIFICATION_STRENGTH;}
strtok(yytext+1, "$"); <DYNARE_STATEMENT>no_identification_reducedform {return token::NO_IDENTIFICATION_REDUCEDFORM;}
yylval->string_val = new string(yytext + 1); <DYNARE_STATEMENT>no_identification_moments {return token::NO_IDENTIFICATION_MOMENTS;}
<DYNARE_STATEMENT>no_identification_minimal {return token::NO_IDENTIFICATION_MINIMAL;}
<DYNARE_STATEMENT>no_identification_spectrum {return token::NO_IDENTIFICATION_SPECTRUM;}
<DYNARE_STATEMENT>normalize_jacobians {return token::NORMALIZE_JACOBIANS;}
<DYNARE_STATEMENT>grid_nbr {return token::GRID_NBR;}
<DYNARE_STATEMENT>tol_rank {return token::TOL_RANK;}
<DYNARE_STATEMENT>tol_deriv {return token::TOL_DERIV;}
<DYNARE_STATEMENT>tol_sv {return token::TOL_SV;}
<DYNARE_STATEMENT>checks_via_subsets {return token::CHECKS_VIA_SUBSETS;}
<DYNARE_STATEMENT>max_dim_subsets_groups {return token::MAX_DIM_SUBSETS_GROUPS;}
<DYNARE_STATEMENT>max_nrows {return token::MAX_NROWS;}
<DYNARE_STATEMENT>with_epilogue {return token::WITH_EPILOGUE;}
<DYNARE_STATEMENT>heteroskedastic_filter {return token::HETEROSKEDASTIC_FILTER;}
<DYNARE_STATEMENT>non_zero {return token::NON_ZERO;}
<DYNARE_STATEMENT>preconditioner {return token::PRECONDITIONER;}
<DYNARE_STATEMENT>umfiter {return token::UMFITER;}
<DYNARE_STATEMENT>iterstack {return token::ITERSTACK;}
<DYNARE_STATEMENT>ilu {return token::ILU;}
<DYNARE_STATEMENT>iter_tol {return token::ITER_TOL;}
<DYNARE_STATEMENT>iter_maxit {return token::ITER_MAXIT;}
<DYNARE_STATEMENT>gmres_restart {return token::GMRES_RESTART;}
<DYNARE_STATEMENT>iterstack_maxlu {return token::ITERSTACK_MAXLU;}
<DYNARE_STATEMENT>iterstack_nperiods {return token::ITERSTACK_NPERIODS;}
<DYNARE_STATEMENT>iterstack_nlu {return token::ITERSTACK_NLU;}
<DYNARE_STATEMENT>iterstack_relu {return token::ITERSTACK_RELU;}
<DYNARE_STATEMENT>check_jacobian_singularity {return token::CHECK_JACOBIAN_SINGULARITY;}
<DYNARE_STATEMENT>\$[^$]*\$ {
yylval->emplace<string>(yytext + 1).pop_back();
return token::TEX_NAME; return token::TEX_NAME;
} }
/* Inside a Dynare block */ /* Inside a Dynare block */
<DYNARE_BLOCK>var {return token::VAR;} <DYNARE_BLOCK>var {return token::VAR;}
<DYNARE_BLOCK>varexo {return token::VAREXO;}
<DYNARE_BLOCK>stderr {return token::STDERR;} <DYNARE_BLOCK>stderr {return token::STDERR;}
<DYNARE_BLOCK>values {return token::VALUES;} <DYNARE_BLOCK>values {return token::VALUES;}
<DYNARE_BLOCK>corr {return token::CORR;} <DYNARE_BLOCK>corr {return token::CORR;}
<DYNARE_BLOCK>periods {return token::PERIODS;} <DYNARE_BLOCK>periods {return token::PERIODS;}
<DYNARE_BLOCK>cutoff {return token::CUTOFF;} <DYNARE_BLOCK>scales {return token::SCALES;}
<DYNARE_BLOCK>mfs {return token::MFS;} <DYNARE_BLOCK>add {
yylval->emplace<string>(yytext);
return token::ADD;
}
<DYNARE_BLOCK>multiply {
yylval->emplace<string>(yytext);
return token::MULTIPLY;
}
<DYNARE_STATEMENT,DYNARE_BLOCK>cutoff {return token::CUTOFF;}
<DYNARE_STATEMENT,DYNARE_BLOCK>mfs {
yylval->emplace<string>(yytext);
return token::MFS;
}
<DYNARE_STATEMENT,DYNARE_BLOCK>static_mfs {return token::STATIC_MFS;}
<DYNARE_STATEMENT,DYNARE_BLOCK>balanced_growth_test_tol {return token::BALANCED_GROWTH_TEST_TOL;}
<DYNARE_STATEMENT,DYNARE_BLOCK>heterogeneity {return token::HETEROGENEITY;}
<DYNARE_BLOCK>gamma_pdf {return token::GAMMA_PDF;} <DYNARE_BLOCK>gamma_pdf {return token::GAMMA_PDF;}
<DYNARE_BLOCK>beta_pdf {return token::BETA_PDF;} <DYNARE_BLOCK>beta_pdf {return token::BETA_PDF;}
<DYNARE_BLOCK>normal_pdf {return token::NORMAL_PDF;} <DYNARE_BLOCK>normal_pdf {return token::NORMAL_PDF;}
...@@ -683,12 +801,52 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -683,12 +801,52 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_BLOCK>uniform_pdf {return token::UNIFORM_PDF;} <DYNARE_BLOCK>uniform_pdf {return token::UNIFORM_PDF;}
<DYNARE_BLOCK>weibull_pdf {return token::WEIBULL_PDF;} <DYNARE_BLOCK>weibull_pdf {return token::WEIBULL_PDF;}
<DYNARE_BLOCK>dsge_prior_weight {return token::DSGE_PRIOR_WEIGHT;} <DYNARE_BLOCK>dsge_prior_weight {return token::DSGE_PRIOR_WEIGHT;}
<DYNARE_BLOCK>surprise {return token::SURPRISE;}
<DYNARE_BLOCK>bind {
yylval->emplace<string>(yytext);
return token::BIND;
}
<DYNARE_BLOCK>relax {
yylval->emplace<string>(yytext);
return token::RELAX;
}
<DYNARE_BLOCK>error_bind {
yylval->emplace<string>(yytext);
return token::ERROR_BIND;
}
<DYNARE_BLOCK>error_relax {
yylval->emplace<string>(yytext);
return token::ERROR_RELAX;
}
<DYNARE_BLOCK>relative_to_initval {return token::RELATIVE_TO_INITVAL;}
<DYNARE_BLOCK>; {return Dynare::parser::token_type (yytext[0]);} <DYNARE_BLOCK>; {return Dynare::parser::token_type (yytext[0]);}
<DYNARE_BLOCK># {return Dynare::parser::token_type (yytext[0]);} <DYNARE_BLOCK># {return Dynare::parser::token_type (yytext[0]);}
<DYNARE_BLOCK>autocorr {return token::AUTOCORR;}
<DYNARE_BLOCK>restriction {return token::RESTRICTION;} <DYNARE_BLOCK>restriction {return token::RESTRICTION;}
<DYNARE_BLOCK>component {return token::COMPONENT;}
<DYNARE_BLOCK>target {return token::TARGET;}
<DYNARE_BLOCK,DYNARE_STATEMENT>auxname {return token::AUXNAME;}
<DYNARE_BLOCK>auxname_target_nonstationary {return token::AUXNAME_TARGET_NONSTATIONARY;}
<DYNARE_BLOCK,DYNARE_STATEMENT>kind {
yylval->emplace<string>(yytext);
return token::KIND;
}
<DYNARE_BLOCK,DYNARE_STATEMENT>ll {
yylval->emplace<string>(yytext);
return token::LL;
}
<DYNARE_BLOCK,DYNARE_STATEMENT>dl {
yylval->emplace<string>(yytext);
return token::DL;
}
<DYNARE_BLOCK,DYNARE_STATEMENT>dd {
yylval->emplace<string>(yytext);
return token::DD;
}
<DYNARE_BLOCK>weights {return token::WEIGHTS;}
<DYNARE_BLOCK>exogenize {return token::EXOGENIZE;}
<DYNARE_BLOCK>endogenize {return token::ENDOGENIZE;}
/* Inside Dynare statement */ /* Inside Dynare statement */
<DYNARE_STATEMENT>solve_algo {return token::SOLVE_ALGO;} <DYNARE_STATEMENT>solve_algo {return token::SOLVE_ALGO;}
...@@ -698,16 +856,16 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -698,16 +856,16 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>robust_lin_solve {return token::ROBUST_LIN_SOLVE;} <DYNARE_STATEMENT>robust_lin_solve {return token::ROBUST_LIN_SOLVE;}
<DYNARE_STATEMENT>drop {return token::DROP;} <DYNARE_STATEMENT>drop {return token::DROP;}
<DYNARE_STATEMENT>order {return token::ORDER;} <DYNARE_STATEMENT>order {return token::ORDER;}
<DYNARE_STATEMENT>sylvester {return token::SYLVESTER;}
<DYNARE_STATEMENT>lyapunov {return token::LYAPUNOV;} <DYNARE_STATEMENT>lyapunov {return token::LYAPUNOV;}
<DYNARE_STATEMENT>dr { <DYNARE_STATEMENT>dr {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::DR; return token::DR;
} }
<DYNARE_STATEMENT>sylvester_fixed_point_tol {return token::SYLVESTER_FIXED_POINT_TOL;} <DYNARE_STATEMENT>lyapunov_complex_threshold {return token::LYAPUNOV_COMPLEX_THRESHOLD;}
<DYNARE_STATEMENT>lyapunov_fixed_point_tol {return token::LYAPUNOV_FIXED_POINT_TOL;} <DYNARE_STATEMENT>lyapunov_fixed_point_tol {return token::LYAPUNOV_FIXED_POINT_TOL;}
<DYNARE_STATEMENT>lyapunov_doubling_tol {return token::LYAPUNOV_DOUBLING_TOL;} <DYNARE_STATEMENT>lyapunov_doubling_tol {return token::LYAPUNOV_DOUBLING_TOL;}
<DYNARE_STATEMENT>dr_cycle_reduction_tol {return token::DR_CYCLE_REDUCTION_TOL;} <DYNARE_STATEMENT>dr_cycle_reduction_tol {return token::DR_CYCLE_REDUCTION_TOL;}
<DYNARE_STATEMENT>dr_cycle_reduction_maxiter {return token::DR_CYCLE_REDUCTION_MAXITER;}
<DYNARE_STATEMENT>dr_logarithmic_reduction_tol {return token::DR_LOGARITHMIC_REDUCTION_TOL;} <DYNARE_STATEMENT>dr_logarithmic_reduction_tol {return token::DR_LOGARITHMIC_REDUCTION_TOL;}
<DYNARE_STATEMENT>dr_logarithmic_reduction_maxiter {return token::DR_LOGARITHMIC_REDUCTION_MAXITER;} <DYNARE_STATEMENT>dr_logarithmic_reduction_maxiter {return token::DR_LOGARITHMIC_REDUCTION_MAXITER;}
<DYNARE_STATEMENT>replic {return token::REPLIC;} <DYNARE_STATEMENT>replic {return token::REPLIC;}
...@@ -719,6 +877,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -719,6 +877,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>one_sided_hp_filter {return token::ONE_SIDED_HP_FILTER;} <DYNARE_STATEMENT>one_sided_hp_filter {return token::ONE_SIDED_HP_FILTER;}
<DYNARE_STATEMENT>bandpass_filter {return token::BANDPASS_FILTER;} <DYNARE_STATEMENT>bandpass_filter {return token::BANDPASS_FILTER;}
<DYNARE_STATEMENT>hp_ngrid {return token::HP_NGRID;} <DYNARE_STATEMENT>hp_ngrid {return token::HP_NGRID;}
<DYNARE_STATEMENT>filtered_theoretical_moments_grid {return token::FILTERED_THEORETICAL_MOMENTS_GRID;}
<DYNARE_STATEMENT>simul_seed {return token::SIMUL_SEED;} <DYNARE_STATEMENT>simul_seed {return token::SIMUL_SEED;}
<DYNARE_STATEMENT>qz_criterium {return token::QZ_CRITERIUM;} <DYNARE_STATEMENT>qz_criterium {return token::QZ_CRITERIUM;}
<DYNARE_STATEMENT>qz_zero_threshold {return token::QZ_ZERO_THRESHOLD;} <DYNARE_STATEMENT>qz_zero_threshold {return token::QZ_ZERO_THRESHOLD;}
...@@ -728,10 +887,20 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -728,10 +887,20 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>xls_range {return token::XLS_RANGE;} <DYNARE_STATEMENT>xls_range {return token::XLS_RANGE;}
<DYNARE_STATEMENT>series {return token::SERIES;} <DYNARE_STATEMENT>series {return token::SERIES;}
<DYNARE_STATEMENT>mh_recover {return token::MH_RECOVER;} <DYNARE_STATEMENT>mh_recover {return token::MH_RECOVER;}
<DYNARE_STATEMENT>mh_initialize_from_previous_mcmc {return token::MH_INITIALIZE_FROM_PREVIOUS_MCMC;}
<DYNARE_STATEMENT>mh_initialize_from_previous_mcmc_directory {return token::MH_INITIALIZE_FROM_PREVIOUS_MCMC_DIRECTORY;}
<DYNARE_STATEMENT>mh_initialize_from_previous_mcmc_record {return token::MH_INITIALIZE_FROM_PREVIOUS_MCMC_RECORD;}
<DYNARE_STATEMENT>mh_initialize_from_previous_mcmc_prior {return token::MH_INITIALIZE_FROM_PREVIOUS_MCMC_PRIOR;}
<DYNARE_STATEMENT>planner_discount {return token::PLANNER_DISCOUNT;} <DYNARE_STATEMENT>planner_discount {return token::PLANNER_DISCOUNT;}
<DYNARE_STATEMENT>planner_discount_latex_name {return token::PLANNER_DISCOUNT_LATEX_NAME;}
<DYNARE_STATEMENT>calibration {return token::CALIBRATION;} <DYNARE_STATEMENT>calibration {return token::CALIBRATION;}
<DYNARE_STATEMENT>irf_plot_threshold {return token::IRF_PLOT_THRESHOLD;} <DYNARE_STATEMENT>irf_plot_threshold {return token::IRF_PLOT_THRESHOLD;}
<DYNARE_STATEMENT>no_homotopy {return token::NO_HOMOTOPY;} <DYNARE_STATEMENT>no_homotopy {return token::NO_HOMOTOPY;}
<DYNARE_STATEMENT>particle_filter_options {return token::PARTICLE_FILTER_OPTIONS;}
<DYNARE_STATEMENT>constant_simulation_length {return token::CONSTANT_SIMULATION_LENGTH;}
<DYNARE_STATEMENT>block_static { return token::BLOCK_STATIC; }
<DYNARE_STATEMENT>block_dynamic { return token::BLOCK_DYNAMIC; }
<DYNARE_STATEMENT>incidence { return token::INCIDENCE; }
<DYNARE_BLOCK>stderr_multiples {return token::STDERR_MULTIPLES;} <DYNARE_BLOCK>stderr_multiples {return token::STDERR_MULTIPLES;}
<DYNARE_BLOCK>diagonal_only {return token::DIAGONAL_ONLY;} <DYNARE_BLOCK>diagonal_only {return token::DIAGONAL_ONLY;}
...@@ -740,6 +909,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -740,6 +909,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_BLOCK>lag {return token::LAG;} <DYNARE_BLOCK>lag {return token::LAG;}
<DYNARE_BLOCK>coeff {return token::COEFF;} <DYNARE_BLOCK>coeff {return token::COEFF;}
<DYNARE_BLOCK>overwrite {return token::OVERWRITE;} <DYNARE_BLOCK>overwrite {return token::OVERWRITE;}
<DYNARE_BLOCK>learnt_in {return token::LEARNT_IN;}
<DYNARE_STATEMENT,DYNARE_BLOCK>upper_cholesky {return token::UPPER_CHOLESKY;} <DYNARE_STATEMENT,DYNARE_BLOCK>upper_cholesky {return token::UPPER_CHOLESKY;}
<DYNARE_STATEMENT,DYNARE_BLOCK>lower_cholesky {return token::LOWER_CHOLESKY;} <DYNARE_STATEMENT,DYNARE_BLOCK>lower_cholesky {return token::LOWER_CHOLESKY;}
<DYNARE_STATEMENT>chain {return token::CHAIN;} <DYNARE_STATEMENT>chain {return token::CHAIN;}
...@@ -749,42 +919,50 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -749,42 +919,50 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>coefficients {return token::COEFFICIENTS;} <DYNARE_STATEMENT>coefficients {return token::COEFFICIENTS;}
<DYNARE_STATEMENT>variances {return token::VARIANCES;} <DYNARE_STATEMENT>variances {return token::VARIANCES;}
<DYNARE_STATEMENT>equations {return token::EQUATIONS;} <DYNARE_STATEMENT>equations {return token::EQUATIONS;}
<DYNARE_STATEMENT>time_shift {return token::TIME_SHIFT;}
<DYNARE_STATEMENT>structural {return token::STRUCTURAL;}
<DYNARE_STATEMENT>true {
yylval->emplace<string>(yytext);
return token::TRUE;
}
<DYNARE_STATEMENT>false {
yylval->emplace<string>(yytext);
return token::FALSE;
}
<DYNARE_STATEMENT>[\.] {return Dynare::parser::token_type (yytext[0]);} <DYNARE_STATEMENT,DYNARE_BLOCK>\. {return Dynare::parser::token_type (yytext[0]);}
<DYNARE_STATEMENT>[\\] {return Dynare::parser::token_type (yytext[0]);} <DYNARE_STATEMENT>\\ {return Dynare::parser::token_type (yytext[0]);}
<DYNARE_STATEMENT>[\'] {return Dynare::parser::token_type (yytext[0]);} <DYNARE_STATEMENT>\' {return Dynare::parser::token_type (yytext[0]);}
<DYNARE_BLOCK>use_dll {return token::USE_DLL;} <DYNARE_STATEMENT,DYNARE_BLOCK>use_dll {return token::USE_DLL;}
<DYNARE_BLOCK>block {return token::BLOCK;} <DYNARE_STATEMENT,DYNARE_BLOCK>block {return token::BLOCK;}
<DYNARE_BLOCK>bytecode {return token::BYTECODE;} <DYNARE_STATEMENT,DYNARE_BLOCK>bytecode {return token::BYTECODE;}
<DYNARE_BLOCK>all_values_required {return token::ALL_VALUES_REQUIRED;} <DYNARE_BLOCK>all_values_required {return token::ALL_VALUES_REQUIRED;}
<DYNARE_BLOCK>no_static {return token::NO_STATIC;} <DYNARE_STATEMENT,DYNARE_BLOCK>no_static {return token::NO_STATIC;}
<DYNARE_BLOCK>differentiate_forward_vars {return token::DIFFERENTIATE_FORWARD_VARS;} <DYNARE_STATEMENT,DYNARE_BLOCK>differentiate_forward_vars {return token::DIFFERENTIATE_FORWARD_VARS;}
<DYNARE_BLOCK>parallel_local_files {return token::PARALLEL_LOCAL_FILES;} <DYNARE_STATEMENT,DYNARE_BLOCK>parallel_local_files {return token::PARALLEL_LOCAL_FILES;}
<DYNARE_STATEMENT,DYNARE_BLOCK>linear {return token::LINEAR;} <DYNARE_STATEMENT,DYNARE_BLOCK>linear {return token::LINEAR;}
<DYNARE_STATEMENT,DYNARE_BLOCK>[,] {return token::COMMA;} <DYNARE_STATEMENT,DYNARE_BLOCK>, {return token::COMMA;}
<DYNARE_STATEMENT,DYNARE_BLOCK>[:] {return Dynare::parser::token_type (yytext[0]);} <DYNARE_STATEMENT,DYNARE_BLOCK>: {return Dynare::parser::token_type (yytext[0]);}
<DYNARE_STATEMENT,DYNARE_BLOCK>[\(\)] {return Dynare::parser::token_type (yytext[0]);} <DYNARE_STATEMENT,DYNARE_BLOCK>[\(\)] {return Dynare::parser::token_type (yytext[0]);}
<DYNARE_STATEMENT,DYNARE_BLOCK>[\[] {return Dynare::parser::token_type (yytext[0]);} <DYNARE_STATEMENT,DYNARE_BLOCK>\[ {return Dynare::parser::token_type (yytext[0]);}
<DYNARE_STATEMENT,DYNARE_BLOCK>[\]] { <DYNARE_STATEMENT,DYNARE_BLOCK>\] {return Dynare::parser::token_type (yytext[0]);}
if (sigma_e) <DYNARE_STATEMENT,DYNARE_BLOCK>\+ {return token::PLUS;}
sigma_e = 0; <DYNARE_STATEMENT,DYNARE_BLOCK>- {return token::MINUS;}
return Dynare::parser::token_type (yytext[0]); <DYNARE_STATEMENT,DYNARE_BLOCK>\* {return token::TIMES;}
} <DYNARE_STATEMENT,DYNARE_BLOCK>\/ {return token::DIVIDE;}
<DYNARE_STATEMENT,DYNARE_BLOCK>[+] {return token::PLUS;} <DYNARE_STATEMENT,DYNARE_BLOCK>= {return token::EQUAL;}
<DYNARE_STATEMENT,DYNARE_BLOCK>[-] {return token::MINUS;} <DYNARE_STATEMENT,DYNARE_BLOCK>< {return token::LESS;}
<DYNARE_STATEMENT,DYNARE_BLOCK>[*] {return token::TIMES;} <DYNARE_STATEMENT,DYNARE_BLOCK>> {return token::GREATER;}
<DYNARE_STATEMENT,DYNARE_BLOCK>[/] {return token::DIVIDE;} <DYNARE_STATEMENT,DYNARE_BLOCK>>= {return token::GREATER_EQUAL;}
<DYNARE_STATEMENT,DYNARE_BLOCK>[=] {return token::EQUAL;} <DYNARE_STATEMENT,DYNARE_BLOCK><= {return token::LESS_EQUAL;}
<DYNARE_STATEMENT,DYNARE_BLOCK>[<] {return token::LESS;} <DYNARE_STATEMENT,DYNARE_BLOCK>== {return token::EQUAL_EQUAL;}
<DYNARE_STATEMENT,DYNARE_BLOCK>[>] {return token::GREATER;} <DYNARE_STATEMENT,DYNARE_BLOCK>!= {return token::EXCLAMATION_EQUAL;}
<DYNARE_STATEMENT,DYNARE_BLOCK>">=" {return token::GREATER_EQUAL;} <DYNARE_BLOCK>\+= {return token::PLUS_EQUAL;}
<DYNARE_STATEMENT,DYNARE_BLOCK>"<=" {return token::LESS_EQUAL;} <DYNARE_BLOCK>\*= {return token::TIMES_EQUAL;}
<DYNARE_STATEMENT,DYNARE_BLOCK>"==" {return token::EQUAL_EQUAL;} <DYNARE_STATEMENT,DYNARE_BLOCK>\^ {return token::POWER;}
<DYNARE_STATEMENT,DYNARE_BLOCK>"!=" {return token::EXCLAMATION_EQUAL;}
<DYNARE_STATEMENT,DYNARE_BLOCK>[\^] {return token::POWER;}
<DYNARE_STATEMENT,DYNARE_BLOCK>exp {return token::EXP;} <DYNARE_STATEMENT,DYNARE_BLOCK>exp {return token::EXP;}
<DYNARE_STATEMENT,DYNARE_BLOCK>log {return token::LOG;} <DYNARE_STATEMENT,DYNARE_BLOCK>log {return token::LOG;}
<DYNARE_STATEMENT,DYNARE_BLOCK>log10 {return token::LOG10;} <DYNARE_STATEMENT,DYNARE_BLOCK>log10 {return token::LOG10;}
...@@ -802,6 +980,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -802,6 +980,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT,DYNARE_BLOCK>acosh {return token::ACOSH;} <DYNARE_STATEMENT,DYNARE_BLOCK>acosh {return token::ACOSH;}
<DYNARE_STATEMENT,DYNARE_BLOCK>atanh {return token::ATANH;} <DYNARE_STATEMENT,DYNARE_BLOCK>atanh {return token::ATANH;}
<DYNARE_STATEMENT,DYNARE_BLOCK>sqrt {return token::SQRT;} <DYNARE_STATEMENT,DYNARE_BLOCK>sqrt {return token::SQRT;}
<DYNARE_STATEMENT,DYNARE_BLOCK>cbrt {return token::CBRT;}
<DYNARE_STATEMENT,DYNARE_BLOCK>max {return token::MAX;} <DYNARE_STATEMENT,DYNARE_BLOCK>max {return token::MAX;}
<DYNARE_STATEMENT,DYNARE_BLOCK>min {return token::MIN;} <DYNARE_STATEMENT,DYNARE_BLOCK>min {return token::MIN;}
<DYNARE_STATEMENT,DYNARE_BLOCK>abs {return token::ABS;} <DYNARE_STATEMENT,DYNARE_BLOCK>abs {return token::ABS;}
...@@ -809,13 +988,21 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -809,13 +988,21 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT,DYNARE_BLOCK>normcdf {return token::NORMCDF;} <DYNARE_STATEMENT,DYNARE_BLOCK>normcdf {return token::NORMCDF;}
<DYNARE_STATEMENT,DYNARE_BLOCK>normpdf {return token::NORMPDF;} <DYNARE_STATEMENT,DYNARE_BLOCK>normpdf {return token::NORMPDF;}
<DYNARE_STATEMENT,DYNARE_BLOCK>erf {return token::ERF;} <DYNARE_STATEMENT,DYNARE_BLOCK>erf {return token::ERF;}
<DYNARE_STATEMENT,DYNARE_BLOCK>erfc {return token::ERFC;}
<DYNARE_STATEMENT,DYNARE_BLOCK>steady_state {return token::STEADY_STATE;} <DYNARE_STATEMENT,DYNARE_BLOCK>steady_state {return token::STEADY_STATE;}
<DYNARE_STATEMENT,DYNARE_BLOCK>expectation {return token::EXPECTATION;} <DYNARE_STATEMENT,DYNARE_BLOCK>expectation {return token::EXPECTATION;}
<DYNARE_BLOCK>var_expectation {return token::VAR_EXPECTATION;}
<DYNARE_BLOCK>pac_expectation {return token::PAC_EXPECTATION;}
<DYNARE_BLOCK>pac_target_nonstationary {return token::PAC_TARGET_NONSTATIONARY;}
<DYNARE_BLOCK>sum {return token::SUM;}
<DYNARE_STATEMENT>discount {return token::DISCOUNT;}
<DYNARE_STATEMENT,DYNARE_BLOCK>varobs {return token::VAROBS;} <DYNARE_STATEMENT,DYNARE_BLOCK>varobs {return token::VAROBS;}
<DYNARE_STATEMENT,DYNARE_BLOCK>full {return token::FULL;} <DYNARE_STATEMENT,DYNARE_BLOCK>varexobs {return token::VAREXOBS;}
<DYNARE_STATEMENT,DYNARE_BLOCK>nan {return token::NAN_CONSTANT;} <DYNARE_STATEMENT,DYNARE_BLOCK>nan {return token::NAN_CONSTANT;}
<DYNARE_STATEMENT,DYNARE_BLOCK>inf {return token::INF_CONSTANT;} <DYNARE_STATEMENT,DYNARE_BLOCK>inf {return token::INF_CONSTANT;}
<DYNARE_STATEMENT,DYNARE_BLOCK>constants {return token::CONSTANTS;} <DYNARE_STATEMENT,DYNARE_BLOCK>constants {return token::CONSTANTS;}
<DYNARE_BLOCK>⟂ {return token::PERPENDICULAR;}
<DYNARE_BLOCK>_\|_ {return token::PERPENDICULAR;}
/* options for GSA module by Marco Ratto */ /* options for GSA module by Marco Ratto */
<DYNARE_STATEMENT>identification {return token::IDENTIFICATION;} <DYNARE_STATEMENT>identification {return token::IDENTIFICATION;}
...@@ -863,35 +1050,27 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -863,35 +1050,27 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<DYNARE_STATEMENT>use_shock_groups {return token::USE_SHOCK_GROUPS;} <DYNARE_STATEMENT>use_shock_groups {return token::USE_SHOCK_GROUPS;}
<DYNARE_STATEMENT>colormap {return token::COLORMAP;} <DYNARE_STATEMENT>colormap {return token::COLORMAP;}
<DYNARE_STATEMENT,DYNARE_BLOCK>[A-Za-z_][A-Za-z0-9_]* { <DYNARE_STATEMENT,DYNARE_BLOCK>{NAME} {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::NAME; return token::NAME;
} }
<DYNARE_STATEMENT,DYNARE_BLOCK>((([0-9]*\.[0-9]+)|([0-9]+\.))([edED][-+]?[0-9]+)?)|([0-9]+[edED][-+]?[0-9]+) { <DYNARE_STATEMENT,DYNARE_BLOCK>{FLOAT_NUMBER} {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::FLOAT_NUMBER; return token::FLOAT_NUMBER;
} }
<DYNARE_STATEMENT,DYNARE_BLOCK>[0-9]+ { <DYNARE_STATEMENT,DYNARE_BLOCK>[0-9]+ {
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::INT_NUMBER; return token::INT_NUMBER;
} }
<DATES_STATEMENT>\( { yylval->string_val->append(yytext); dates_parens_nb++; } <DYNARE_BLOCK>\|e { return token::PIPE_E; }
<DATES_STATEMENT>\) { <DYNARE_BLOCK>\|x { return token::PIPE_X; }
yylval->string_val->append(yytext); <DYNARE_BLOCK>\|p { return token::PIPE_P; }
if (--dates_parens_nb == 0)
{
BEGIN DYNARE_STATEMENT;
return token::DATES;
}
}
<DATES_STATEMENT>. { yylval->string_val->append(yytext); }
<DYNARE_STATEMENT,DYNARE_BLOCK>\'[^\']+\' { <DYNARE_STATEMENT,DYNARE_BLOCK>\'[^\']*\' {
yylval->string_val = new string(yytext + 1); yylval->emplace<string>(yytext + 1).pop_back();
yylval->string_val->resize(yylval->string_val->length() - 1);
return token::QUOTED_STRING; return token::QUOTED_STRING;
} }
...@@ -899,11 +1078,9 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -899,11 +1078,9 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
/* Verbatim Block */ /* Verbatim Block */
<INITIAL>verbatim[[:space:]]*; { <INITIAL>verbatim[[:space:]]*; {
BEGIN VERBATIM_BLOCK; BEGIN VERBATIM_BLOCK;
yylval->string_val = new string();
} }
<VERBATIM_BLOCK>end[[:space:]]*; { <VERBATIM_BLOCK>end[[:space:]]*; {
BEGIN INITIAL; BEGIN INITIAL;
yylval->string_val = new string();
} }
<VERBATIM_BLOCK>\n { <VERBATIM_BLOCK>\n {
if (strlen(yytext) > 1) if (strlen(yytext) > 1)
...@@ -925,11 +1102,11 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -925,11 +1102,11 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
element in initval (in which case Dynare recognizes the matrix name as an external element in initval (in which case Dynare recognizes the matrix name as an external
function symbol), and may want to modify the matrix later with Matlab statements. function symbol), and may want to modify the matrix later with Matlab statements.
*/ */
<INITIAL>[A-Za-z_][A-Za-z0-9_]* { <INITIAL>{NAME} {
if (driver.symbol_exists_and_is_not_modfile_local_or_external_function(yytext)) if (driver.symbol_exists_and_is_not_modfile_local_or_external_function(yytext))
{ {
BEGIN DYNARE_STATEMENT; BEGIN DYNARE_STATEMENT;
yylval->string_val = new string(yytext); yylval->emplace<string>(yytext);
return token::NAME; return token::NAME;
} }
else else
...@@ -940,29 +1117,32 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -940,29 +1117,32 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
} }
} }
/* For joint prior statement, match [symbol, symbol, ...] /*
For joint prior statement, match [symbol, symbol, ...]
If no match, begin native and push everything back on stack If no match, begin native and push everything back on stack
We produce SYMBOL_VEC in Flex (instead of matching `'[' symbol_list ']'`
in Bison because the pattern also matches potential native statements
(e.g. function returns from a MATLAB/Octave function). Hence, we need to
be able to back out of the statement if we realize it's a native statement
and move to the NATIVE context
*/ */
<INITIAL>\[([[:space:]]*[A-Za-z_][A-Za-z0-9_]*[[:space:]]*,{1}[[:space:]]*)*([[:space:]]*[A-Za-z_][A-Za-z0-9_]*[[:space:]]*){1}\] { <INITIAL>\[([[:space:]]*{NAME}[[:space:]]*,{1}[[:space:]]*)*([[:space:]]*{NAME}[[:space:]]*){1}\] {
string yytextcpy = string(yytext); string yytextcpy{yytext};
yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), '['), yytextcpy.end()); yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), '['), yytextcpy.end());
yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), ']'), yytextcpy.end()); yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), ']'), yytextcpy.end());
yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), ' '), yytextcpy.end()); yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), ' '), yytextcpy.end());
istringstream ss(yytextcpy); istringstream ss(yytextcpy);
string token; string token;
yylval->vector_string_val = new vector<string *>; vector<string> val;
bool dynare_statement = true; bool dynare_statement = true;
while (getline(ss, token, ',')) while (getline(ss, token, ','))
if (driver.symbol_exists_and_is_not_modfile_local_or_external_function(token.c_str())) if (driver.symbol_exists_and_is_not_modfile_local_or_external_function(token))
yylval->vector_string_val->push_back(new string(token)); val.push_back(token);
else else
{ {
for (vector<string *>::iterator it=yylval->vector_string_val->begin();
it != yylval->vector_string_val->end(); it++)
delete *it;
delete yylval->vector_string_val;
BEGIN NATIVE; BEGIN NATIVE;
yyless(0); yyless(0);
dynare_statement = false; dynare_statement = false;
...@@ -971,6 +1151,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -971,6 +1151,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
if (dynare_statement) if (dynare_statement)
{ {
BEGIN DYNARE_STATEMENT; BEGIN DYNARE_STATEMENT;
yylval->emplace<vector<string>>(val);
return token::SYMBOL_VEC; return token::SYMBOL_VEC;
} }
} }
...@@ -985,8 +1166,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -985,8 +1166,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
\'[^\'\n]*\' | \'[^\'\n]*\' |
\"[^\"\n]*\" | \"[^\"\n]*\" |
\.{1,2} | \.{1,2} |
"*" | \* |
"/" { yymore(); eofbuff = string(yytext); } \/ { yymore(); eofbuff = yytext; }
\.{3,}[[:space:]]*\n { driver.add_native_remove_charset(yytext, "\n"); } \.{3,}[[:space:]]*\n { driver.add_native_remove_charset(yytext, "\n"); }
\n { \n {
if (strlen(yytext) > 1) if (strlen(yytext) > 1)
...@@ -997,8 +1178,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -997,8 +1178,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
driver.add_native(eofbuff); driver.add_native(eofbuff);
yyterminate(); yyterminate();
} }
\.{3,}[[:space:]]*"%".*\n | \.{3,}[[:space:]]*%.*\n |
"%"[^\n]* { driver.add_native_remove_charset(yytext, "%"); } %[^\n]* { driver.add_native_remove_charset(yytext, "%"); }
\.{3,}[[:space:]]*"//".*\n | \.{3,}[[:space:]]*"//".*\n |
"//"[^\n]* { driver.add_native_remove_charset(yytext, "//"); } "//"[^\n]* { driver.add_native_remove_charset(yytext, "//"); }
\.{3,}[[:space:]]*"/*" { \.{3,}[[:space:]]*"/*" {
...@@ -1015,13 +1196,15 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 ...@@ -1015,13 +1196,15 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
<NATIVE_COMMENT>"*/"[[:space:]]*\n { BEGIN NATIVE; } <NATIVE_COMMENT>"*/"[[:space:]]*\n { BEGIN NATIVE; }
<NATIVE_COMMENT>. <NATIVE_COMMENT>.
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,COMMENT,DATES_STATEMENT,LINE1,LINE2,LINE3,NATIVE_COMMENT><<EOF>> { yyterminate(); } <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,COMMENT,LINE1,LINE2,LINE3,NATIVE_COMMENT><<EOF>> { yyterminate(); }
<*>. { driver.error(*yylloc, "character unrecognized by lexer"); } <*>. { driver.error(*yylloc, "character unrecognized by lexer"); }
%% %%
#pragma GCC diagnostic pop
DynareFlex::DynareFlex(istream* in, ostream* out) DynareFlex::DynareFlex(istream* in, ostream* out)
: DynareFlexLexer(in, out) : DynareFlexLexer{in, out}
{ {
} }
......